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 + -
显示快捷键?