x11_common.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 2,222 行 · 第 1/5 页
C
2,222 行
#include <mplaylib.h>#include <mplaylib.h>#include <math.h>#include <inttypes.h>#include "config.h"#include "mp_msg.h"#include "mp_fifo.h"#include "x11_common.h"#ifdef X11_FULLSCREEN#include <mplaylib.h>#include <mplaylib.h>#include <signal.h>#include <assert.h>#include "video_out.h"#include "aspect.h"#include "geometry.h"#include "help_mp.h"#include "osdep/timer.h"#include <X11/Xmd.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Xatom.h>#ifdef HAVE_XDPMS#include <X11/extensions/dpms.h>#endif#ifdef HAVE_XINERAMA#include <X11/extensions/Xinerama.h>#endif#ifdef HAVE_XF86VM#include <X11/extensions/xf86vmode.h>#endif#ifdef HAVE_XF86XK#include <X11/XF86keysym.h>#endif#ifdef HAVE_XV#include <X11/extensions/Xv.h>#include <X11/extensions/Xvlib.h>#include "subopt-helper.h"#endif#include "input/input.h"#include "input/mouse.h"#ifdef HAVE_NEW_GUI#include "gui/interface.h"#include "mplayer.h"#endif#define WIN_LAYER_ONBOTTOM 2#define WIN_LAYER_NORMAL 4#define WIN_LAYER_ONTOP 6#define WIN_LAYER_ABOVE_DOCK 10extern int enable_mouse_movements;int fs_layer = WIN_LAYER_ABOVE_DOCK;static int orig_layer = 0;static int old_gravity = NorthWestGravity;int stop_xscreensaver = 0;static int dpms_disabled = 0;static int timeout_save = 0;static int kdescreensaver_was_running = 0;char *mDisplayName = NULL;Display *mDisplay = NULL;Window mRootWin;int mScreen;int mLocalDisplay;/* output window id */int vo_mouse_autohide = 0;int vo_wm_type = 0;int vo_fs_type = 0; // needs to be accessible for GUI X11 codestatic int vo_fs_flip = 0;char **vo_fstype_list;/* 1 means that the WM is metacity (broken as hell) */int metacity_hack = 0;static Atom XA_NET_SUPPORTED;static Atom XA_NET_WM_STATE;static Atom XA_NET_WM_STATE_FULLSCREEN;static Atom XA_NET_WM_STATE_ABOVE;static Atom XA_NET_WM_STATE_STAYS_ON_TOP;static Atom XA_NET_WM_STATE_BELOW;static Atom XA_NET_WM_PID;static Atom XA_WIN_PROTOCOLS;static Atom XA_WIN_LAYER;static Atom XA_WIN_HINTS;static Atom XA_BLACKBOX_PID;static Atom XAWM_PROTOCOLS;static Atom XAWM_DELETE_WINDOW;#define XA_INIT(x) XA##x = XInternAtom(mDisplay, #x, False)static int vo_old_x = 0;static int vo_old_y = 0;static int vo_old_width = 0;static int vo_old_height = 0;#ifdef HAVE_XF86VMXF86VidModeModeInfo **vidmodes = NULL;XF86VidModeModeLine modeline;#endifstatic int vo_x11_get_fs_type(int supported);/* * Sends the EWMH fullscreen state event. * * action: could be one of _NET_WM_STATE_REMOVE -- remove state * _NET_WM_STATE_ADD -- add state * _NET_WM_STATE_TOGGLE -- toggle */void vo_x11_ewmh_fullscreen(int action){ assert(action == _NET_WM_STATE_REMOVE || action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); if (vo_fs_type & vo_wm_FULLSCREEN) { XEvent xev; /* init X event structure for _NET_WM_FULLSCREEN client message */ xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.message_type = XInternAtom(mDisplay, "_NET_WM_STATE", False); xev.xclient.window = vo_window; xev.xclient.format = 32; xev.xclient.data.l[0] = action; xev.xclient.data.l[1] = XInternAtom(mDisplay, "_NET_WM_STATE_FULLSCREEN", False); xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; /* finally send that damn thing */ if (!XSendEvent(mDisplay, DefaultRootWindow(mDisplay), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev)) { mp_msg(MSGT_VO, MSGL_ERR, MSGTR_EwmhFullscreenStateFailed); } }}void vo_hidecursor(Display * disp, Window win){ Cursor no_ptr; Pixmap bm_no; XColor black, dummy; Colormap colormap; static char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (WinID == 0) return; // do not hide if playing on the root window colormap = DefaultColormap(disp, DefaultScreen(disp)); if ( !XAllocNamedColor(disp, colormap, "black", &black, &dummy) ) { return; // color alloc failed, give up } bm_no = XCreateBitmapFromData(disp, win, bm_no_data, 8, 8); no_ptr = XCreatePixmapCursor(disp, bm_no, bm_no, &black, &black, 0, 0); XDefineCursor(disp, win, no_ptr); XFreeCursor(disp, no_ptr); if (bm_no != None) XFreePixmap(disp, bm_no); XFreeColors(disp,colormap,&black.pixel,1,0);}void vo_showcursor(Display * disp, Window win){ if (WinID == 0) return; XDefineCursor(disp, win, 0);}static int x11_errorhandler(Display * display, XErrorEvent * event){#define MSGLEN 60 char msg[MSGLEN]; XGetErrorText(display, event->error_code, (char *) &msg, MSGLEN); mp_msg(MSGT_VO, MSGL_ERR, "X11 error: %s\n", msg); mp_msg(MSGT_VO, MSGL_V, "Type: %x, display: %p, resourceid: %lx, serial: %lx\n", event->type, event->display, event->resourceid, event->serial); mp_msg(MSGT_VO, MSGL_V, "Error code: %x, request code: %x, minor code: %x\n", event->error_code, event->request_code, event->minor_code);// abort(); //exit_player("X11 error"); return 0;#undef MSGLEN}void fstype_help(void){ mp_msg(MSGT_VO, MSGL_INFO, MSGTR_AvailableFsType); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FULL_SCREEN_TYPES\n"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "none", "don't set fullscreen window layer"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "layer", "use _WIN_LAYER hint with default layer"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "layer=<0..15>", "use _WIN_LAYER hint with a given layer number"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "netwm", "force NETWM style"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "above", "use _NETWM_STATE_ABOVE hint if available"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "below", "use _NETWM_STATE_BELOW hint if available"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "fullscreen", "use _NETWM_STATE_FULLSCREEN hint if availale"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "stays_on_top", "use _NETWM_STATE_STAYS_ON_TOP hint if available"); mp_msg(MSGT_VO, MSGL_INFO, "You can also negate the settings with simply putting '-' in the beginning"); mp_msg(MSGT_VO, MSGL_INFO, "\n");}static void fstype_dump(int fstype){ if (fstype) { mp_msg(MSGT_VO, MSGL_V, "[x11] Current fstype setting honours"); if (fstype & vo_wm_LAYER) mp_msg(MSGT_VO, MSGL_V, " LAYER"); if (fstype & vo_wm_FULLSCREEN) mp_msg(MSGT_VO, MSGL_V, " FULLSCREEN"); if (fstype & vo_wm_STAYS_ON_TOP) mp_msg(MSGT_VO, MSGL_V, " STAYS_ON_TOP"); if (fstype & vo_wm_ABOVE) mp_msg(MSGT_VO, MSGL_V, " ABOVE"); if (fstype & vo_wm_BELOW) mp_msg(MSGT_VO, MSGL_V, " BELOW"); mp_msg(MSGT_VO, MSGL_V, " X atoms\n"); } else mp_msg(MSGT_VO, MSGL_V, "[x11] Current fstype setting doesn't honour any X atoms\n");}static int net_wm_support_state_test(Atom atom){#define NET_WM_STATE_TEST(x) { if (atom == XA_NET_WM_STATE_##x) { mp_msg( MSGT_VO,MSGL_V, "[x11] Detected wm supports " #x " state.\n" ); return vo_wm_##x; } } NET_WM_STATE_TEST(FULLSCREEN); NET_WM_STATE_TEST(ABOVE); NET_WM_STATE_TEST(STAYS_ON_TOP); NET_WM_STATE_TEST(BELOW); return 0;}static int x11_get_property(Atom type, Atom ** args, unsigned long *nitems){ int format; unsigned long bytesafter; return (Success == XGetWindowProperty(mDisplay, mRootWin, type, 0, 16384, False, AnyPropertyType, &type, &format, nitems, &bytesafter, (unsigned char **) args) && *nitems > 0);}static int vo_wm_detect(void){ int i; int wm = 0; unsigned long nitems; Atom *args = NULL; if (WinID >= 0) return 0;// -- supports layers if (x11_get_property(XA_WIN_PROTOCOLS, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports layers.\n"); for (i = 0; i < nitems; i++) { if (args[i] == XA_WIN_LAYER) { wm |= vo_wm_LAYER; metacity_hack |= 1; } else /* metacity is the only window manager I know which reports * supporting only the _WIN_LAYER hint in _WIN_PROTOCOLS. * (what's more support for it is broken) */ metacity_hack |= 2; } XFree(args); if (wm && (metacity_hack == 1)) { // metacity claims to support layers, but it is not the truth :-) wm ^= vo_wm_LAYER; mp_msg(MSGT_VO, MSGL_V, "[x11] Using workaround for Metacity bugs.\n"); } }// --- netwm if (x11_get_property(XA_NET_SUPPORTED, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports NetWM.\n"); for (i = 0; i < nitems; i++) wm |= net_wm_support_state_test(args[i]); XFree(args);#if 0 // ugly hack for broken OpenBox _NET_WM_STATE_FULLSCREEN support // (in their implementation it only changes internal window state, nothing more!!!) if (wm & vo_wm_FULLSCREEN) { if (x11_get_property(XA_BLACKBOX_PID, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm is a broken OpenBox.\n"); wm ^= vo_wm_FULLSCREEN; } XFree(args); }#endif } if (wm == 0) mp_msg(MSGT_VO, MSGL_V, "[x11] Unknown wm type...\n"); return wm;}static void init_atoms(void){ XA_INIT(_NET_SUPPORTED); XA_INIT(_NET_WM_STATE); XA_INIT(_NET_WM_STATE_FULLSCREEN); XA_INIT(_NET_WM_STATE_ABOVE); XA_INIT(_NET_WM_STATE_STAYS_ON_TOP); XA_INIT(_NET_WM_STATE_BELOW); XA_INIT(_NET_WM_PID); XA_INIT(_WIN_PROTOCOLS); XA_INIT(_WIN_LAYER); XA_INIT(_WIN_HINTS); XA_INIT(_BLACKBOX_PID); XA_INIT(WM_PROTOCOLS); XA_INIT(WM_DELETE_WINDOW);}void update_xinerama_info(void) { int screen = xinerama_screen; xinerama_x = xinerama_y = 0;#ifdef HAVE_XINERAMA if (screen >= -1 && XineramaIsActive(mDisplay)) { XineramaScreenInfo *screens; int num_screens; screens = XineramaQueryScreens(mDisplay, &num_screens); if (screen >= num_screens) screen = num_screens - 1; if (screen == -1) { int x = vo_dx + vo_dwidth / 2; int y = vo_dy + vo_dheight / 2; for (screen = num_screens - 1; screen > 0; screen--) { int left = screens[screen].x_org; int right = left + screens[screen].width; int top = screens[screen].y_org; int bottom = top + screens[screen].height; if (left <= x && x <= right && top <= y && y <= bottom) break; } } if (screen < 0) screen = 0; vo_screenwidth = screens[screen].width; vo_screenheight = screens[screen].height; xinerama_x = screens[screen].x_org; xinerama_y = screens[screen].y_org; XFree(screens); }#endif aspect_save_screenres(vo_screenwidth, vo_screenheight);}int vo_init(void){// int mScreen; int depth, bpp; unsigned int mask;// char * DisplayName = ":0.0";// Display * mDisplay; XImage *mXImage = NULL;// Window mRootWin; XWindowAttributes attribs; char *dispName; if (vo_rootwin) WinID = 0; // use root window if (vo_depthonscreen) { saver_off(mDisplay); return 1; // already called } XSetErrorHandler(x11_errorhandler);#if 0 if (!mDisplayName) if (!(mDisplayName = getenv("DISPLAY"))) mDisplayName = strdup(":0.0");#else dispName = XDisplayName(mDisplayName);#endif mp_msg(MSGT_VO, MSGL_V, "X11 opening display: %s\n", dispName); mDisplay = XOpenDisplay(dispName); if (!mDisplay) { mp_msg(MSGT_VO, MSGL_ERR, "vo: couldn't open the X11 display (%s)!\n", dispName); return 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?