📄 ws.c
字号:
// --------------------------------------------------------------------------// AutoSpace Window System for Linux/Win32 v0.85// Writed by pontscho/fresh!mindworkz// --------------------------------------------------------------------------#include <X11/Xlib.h>#include <X11/Xproto.h>#include <X11/Xutil.h>#include <X11/keysym.h>#include <X11/Xatom.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <inttypes.h>#include "../config.h"#include "../libvo/x11_common.h"#include "../libvo/video_out.h"#include "ws.h"#include "wsxdnd.h"#include "../cpudetect.h"#include "../libswscale/swscale.h"#include "../libswscale/rgb2rgb.h"#include "../libmpcodecs/vf_scale.h"#include "../mp_msg.h"#include "../help_mp.h"#include "../mplayer.h"#include "../mpbswap.h"#include <X11/extensions/XShm.h>#ifdef HAVE_XSHAPE#include <X11/extensions/shape.h>#endif#ifdef HAVE_XINERAMA#include <X11/extensions/Xinerama.h>#endif#ifdef HAVE_XF86VM#include <X11/extensions/xf86vmode.h>#endif#include <sys/ipc.h>#include <sys/shm.h>#undef ENABLE_DPMS typedef struct{ unsigned long flags; unsigned long functions; unsigned long decorations; long input_mode; unsigned long status;} MotifWmHints;Atom wsMotifHints;int wsMaxX = 0; // Screen width.int wsMaxY = 0; // Screen height.int wsOrgX = 0; // Screen origin x.int wsOrgY = 0; // Screen origin y.Display * wsDisplay;int wsScreen;Window wsRootWin;XEvent wsEvent;int wsWindowDepth;GC wsHGC;MotifWmHints wsMotifWmHints;Atom wsTextProperlyAtom = None;int wsLayer = 0;int wsDepthOnScreen = 0;int wsRedMask = 0;int wsGreenMask = 0;int wsBlueMask = 0;int wsOutMask = 0;int wsNonNativeOrder = 0;int wsTrue = True;#define wsWLCount 5wsTWindow * wsWindowList[wsWLCount] = { NULL,NULL,NULL,NULL,NULL };unsigned long wsKeyTable[512];int wsUseXShm = 1;int wsUseXShape = 1;inline int wsSearch( Window win );// ---#define PACK_RGB16(r,g,b,pixel) pixel=(b>>3);\ pixel<<=6;\ pixel|=(g>>2);\ pixel<<=5;\ pixel|=(r>>3)#define PACK_RGB15(r,g,b,pixel) pixel=(b>>3);\ pixel<<=5;\ pixel|=(g>>3);\ pixel<<=5;\ pixel|=(r>>3)typedef void(*wsTConvFunc)( const unsigned char * in_pixels, unsigned char * out_pixels, unsigned num_pixels );wsTConvFunc wsConvFunc = NULL; void rgb32torgb32( const unsigned char * src, unsigned char * dst,unsigned int src_size ) { memcpy( dst,src,src_size ); }// ---#define MWM_HINTS_FUNCTIONS (1L << 0)#define MWM_HINTS_DECORATIONS (1L << 1)#define MWM_HINTS_INPUT_MODE (1L << 2)#define MWM_HINTS_STATUS (1L << 3)#define MWM_FUNC_ALL (1L << 0)#define MWM_FUNC_RESIZE (1L << 1)#define MWM_FUNC_MOVE (1L << 2)#define MWM_FUNC_MINIMIZE (1L << 3)#define MWM_FUNC_MAXIMIZE (1L << 4)#define MWM_FUNC_CLOSE (1L << 5)#define MWM_DECOR_ALL (1L << 0)#define MWM_DECOR_BORDER (1L << 1)#define MWM_DECOR_RESIZEH (1L << 2)#define MWM_DECOR_TITLE (1L << 3)#define MWM_DECOR_MENU (1L << 4)#define MWM_DECOR_MINIMIZE (1L << 5)#define MWM_DECOR_MAXIMIZE (1L << 6)#define MWM_INPUT_MODELESS 0#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1#define MWM_INPUT_SYSTEM_MODAL 2#define MWM_INPUT_FULL_APPLICATION_MODAL 3#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL#define MWM_TEAROFF_WINDOW (1L<<0)void wsWindowDecoration( wsTWindow * win,long d ){ wsMotifHints=XInternAtom( wsDisplay,"_MOTIF_WM_HINTS",0 ); if ( wsMotifHints == None ) return; memset( &wsMotifWmHints,0,sizeof( MotifWmHints ) ); wsMotifWmHints.flags=MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; if ( d ) { wsMotifWmHints.functions=MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE; wsMotifWmHints.decorations=MWM_DECOR_ALL; } XChangeProperty( wsDisplay,win->WindowID,wsMotifHints,wsMotifHints,32, PropModeReplace,(unsigned char *)&wsMotifWmHints,5 );}// ----------------------------------------------------------------------------------------------// Init X Window System.// ----------------------------------------------------------------------------------------------int wsIOErrorHandler( Display * dpy ){ fprintf( stderr,"[ws] IO error in display.\n" ); exit( 0 );}int wsErrorHandler( Display * dpy,XErrorEvent * Event ){ char type[128]; XGetErrorText( wsDisplay,Event->error_code,type,128 ); fprintf(stderr,"[ws] Error in display.\n"); fprintf(stderr,"[ws] Error code: %d ( %s )\n",Event->error_code,type ); fprintf(stderr,"[ws] Request code: %d\n",Event->request_code ); fprintf(stderr,"[ws] Minor code: %d\n",Event->minor_code ); fprintf(stderr,"[ws] Modules: %s\n",current_module?current_module:"(NULL)" ); exit( 0 );}void wsXInit( void* mDisplay ){ int eventbase; int errorbase;if(mDisplay){ wsDisplay=mDisplay;} else { char * DisplayName = ":0.0"; if ( getenv( "DISPLAY" ) ) DisplayName=getenv( "DISPLAY" ); wsDisplay=XOpenDisplay( DisplayName ); if ( !wsDisplay ) { mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_CouldNotOpenDisplay ); exit( 0 ); }}/* enable DND atoms */wsXDNDInitialize(); { /* on remote display XShm will be disabled - LGB */ char *dispname=DisplayString(wsDisplay); int localdisp=1; if (dispname&&*dispname!=':') { localdisp=0; wsUseXShm=0; } mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[ws] display name: %s => %s display.\n",dispname,localdisp?"local":"REMOTE"); if (!localdisp) mp_msg( MSGT_GPLAYER,MSGL_V,MSGTR_WS_RemoteDisplay );} if ( !XShmQueryExtension( wsDisplay ) ) { mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_WS_NoXshm ); wsUseXShm=0; }#ifdef HAVE_XSHAPE if ( !XShapeQueryExtension( wsDisplay,&eventbase,&errorbase ) ) { mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_WS_NoXshape ); wsUseXShape=0; }#else wsUseXShape=0;#endif XSynchronize( wsDisplay,True ); wsScreen=DefaultScreen( wsDisplay ); wsRootWin=RootWindow( wsDisplay,wsScreen );#ifdef HAVE_XF86VM { int clock; XF86VidModeModeLine modeline; XF86VidModeGetModeLine( wsDisplay,wsScreen,&clock ,&modeline ); wsMaxX=modeline.hdisplay; wsMaxY=modeline.vdisplay; }#endif { wsOrgX = wsOrgY = 0; if ( !wsMaxX ) wsMaxX=DisplayWidth( wsDisplay,wsScreen ); if ( !wsMaxY ) wsMaxY=DisplayHeight( wsDisplay,wsScreen ); } vo_screenwidth = wsMaxX; vo_screenheight = wsMaxY; xinerama_x = wsOrgX; xinerama_y = wsOrgY; update_xinerama_info(); wsMaxX = vo_screenwidth; wsMaxY = vo_screenheight; wsOrgX = xinerama_x; wsOrgY = xinerama_y; wsGetDepthOnScreen();#ifdef DEBUG { int minor,major,shp; mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] Screen depth: %d\n",wsDepthOnScreen ); mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] size: %dx%d\n",wsMaxX,wsMaxY );#ifdef HAVE_XINERAMA mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] origin: +%d+%d\n",wsOrgX,wsOrgY );#endif mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] red mask: 0x%x\n",wsRedMask ); mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] green mask: 0x%x\n",wsGreenMask ); mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] blue mask: 0x%x\n",wsBlueMask ); if ( wsUseXShm ) { XShmQueryVersion( wsDisplay,&major,&minor,&shp ); mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] XShm version is %d.%d\n",major,minor ); } #ifdef HAVE_XSHAPE if ( wsUseXShape ) { XShapeQueryVersion( wsDisplay,&major,&minor ); mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] XShape version is %d.%d\n",major,minor ); } #endif }#endif wsOutMask=wsGetOutMask(); mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[ws] Initialized converter: " ); sws_rgb2rgb_init(get_sws_cpuflags()); switch ( wsOutMask ) { case wsRGB32: mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb32\n" ); wsConvFunc=rgb32torgb32; break; case wsBGR32: mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr32\n" ); wsConvFunc=rgb32tobgr32; break; case wsRGB24: mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb24\n" ); wsConvFunc=rgb32to24; break; case wsBGR24: mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr24\n" ); wsConvFunc=rgb32tobgr24; break; case wsRGB16: mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb16\n" ); wsConvFunc=rgb32to16; break; case wsBGR16: mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr16\n" ); wsConvFunc=rgb32tobgr16; break; case wsRGB15: mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb15\n" ); wsConvFunc=rgb32to15; break; case wsBGR15: mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr15\n" ); wsConvFunc=rgb32tobgr15; break; } XSetErrorHandler( wsErrorHandler );}// ----------------------------------------------------------------------------------------------// Create window.// X,Y : window position// wX,wY : size of window// bW : border width// cV : visible mouse cursor on window// D : visible frame, title, etc.// sR : screen ratio// ----------------------------------------------------------------------------------------------XClassHint wsClassHint;XTextProperty wsTextProperty;Window LeaderWindow;void wsCreateWindow( wsTWindow * win,int X,int Y,int wX,int hY,int bW,int cV,unsigned char D,char * label ){ int depth; win->Property=D; if ( D & wsShowFrame ) win->Decorations=1; wsHGC=DefaultGC( wsDisplay,wsScreen );// The window position and size. switch ( X ) { case -1: win->X=( wsMaxX / 2 ) - ( wX / 2 ) + wsOrgX; break; case -2: win->X=wsMaxX - wX - 1 + wsOrgX; break; default: win->X=X; break; } switch ( Y ) { case -1: win->Y=( wsMaxY / 2 ) - ( hY / 2 ) + wsOrgY; break; case -2: win->Y=wsMaxY - hY - 1 + wsOrgY; break; default: win->Y=Y; break; } win->Width=wX; win->Height=hY; win->OldX=win->X; win->OldY=win->Y; win->OldWidth=win->Width; win->OldHeight=win->Height;// Border size for window. win->BorderWidth=bW;// Hide Mouse Cursor win->wsCursor=None; win->wsMouseEventType=cV; win->wsCursorData[0]=0; win->wsCursorPixmap=XCreateBitmapFromData( wsDisplay,wsRootWin,win->wsCursorData,1,1 ); if ( !(cV & wsShowMouseCursor) ) win->wsCursor=XCreatePixmapCursor( wsDisplay,win->wsCursorPixmap,win->wsCursorPixmap,&win->wsColor,&win->wsColor,0,0 ); depth = vo_find_depth_from_visuals( wsDisplay,wsScreen,NULL ); if ( depth < 15 ) { mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ColorDepthTooLow ); exit( 0 ); } XMatchVisualInfo( wsDisplay,wsScreen,depth,TrueColor,&win->VisualInfo );// --- win->AtomLeaderClient=XInternAtom( wsDisplay,"WM_CLIENT_LEADER",False ); win->AtomDeleteWindow=XInternAtom( wsDisplay,"WM_DELETE_WINDOW",False ); win->AtomTakeFocus=XInternAtom( wsDisplay,"WM_TAKE_FOCUS",False ); win->AtomRolle=XInternAtom( wsDisplay,"WM_WINDOW_ROLE",False ); win->AtomWMSizeHint=XInternAtom( wsDisplay,"WM_SIZE_HINT",False ); win->AtomWMNormalHint=XInternAtom( wsDisplay,"WM_NORMAL_HINT",False ); win->AtomProtocols=XInternAtom( wsDisplay,"WM_PROTOCOLS",False ); win->AtomsProtocols[0]=win->AtomDeleteWindow; win->AtomsProtocols[1]=win->AtomTakeFocus; win->AtomsProtocols[2]=win->AtomRolle;// --- win->WindowAttrib.background_pixel=BlackPixel( wsDisplay,wsScreen ); win->WindowAttrib.border_pixel=WhitePixel( wsDisplay,wsScreen ); win->WindowAttrib.colormap=XCreateColormap( wsDisplay,wsRootWin,win->VisualInfo.visual,AllocNone ); win->WindowAttrib.event_mask=StructureNotifyMask | FocusChangeMask | ExposureMask | PropertyChangeMask | EnterWindowMask | LeaveWindowMask | VisibilityChangeMask | KeyPressMask | KeyReleaseMask; if ( ( cV & wsHandleMouseButton ) ) win->WindowAttrib.event_mask|=ButtonPressMask | ButtonReleaseMask; if ( ( cV & wsHandleMouseMove ) ) win->WindowAttrib.event_mask|=PointerMotionMask; win->WindowAttrib.cursor=win->wsCursor; win->WindowAttrib.override_redirect=False; if ( D & wsOverredirect ) win->WindowAttrib.override_redirect=True; win->WindowMask=CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWCursor | CWOverrideRedirect; win->WindowID=XCreateWindow( wsDisplay, (win->Parent != 0?win->Parent:wsRootWin), win->X,win->Y,win->Width,win->Height,win->BorderWidth, win->VisualInfo.depth, InputOutput, win->VisualInfo.visual, win->WindowMask,&win->WindowAttrib ); wsClassHint.res_name="MPlayer"; wsClassHint.res_class="MPlayer"; XSetClassHint( wsDisplay,win->WindowID,&wsClassHint ); win->SizeHint.flags=PPosition | PSize | PResizeInc | PWinGravity;// | PBaseSize; win->SizeHint.x=win->X; win->SizeHint.y=win->Y; win->SizeHint.width=win->Width; win->SizeHint.height=win->Height;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -