📄 ws.c
字号:
if ( D & wsMinSize ) { win->SizeHint.flags|=PMinSize; win->SizeHint.min_width=win->Width; win->SizeHint.min_height=win->Height; } if ( D & wsMaxSize ) { win->SizeHint.flags|=PMaxSize; win->SizeHint.max_width=win->Width; win->SizeHint.max_height=win->Height; } win->SizeHint.height_inc=1; win->SizeHint.width_inc=1; win->SizeHint.base_width=win->Width; win->SizeHint.base_height=win->Height; win->SizeHint.win_gravity=StaticGravity; XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint ); win->WMHints.flags=InputHint | StateHint; win->WMHints.input=True; win->WMHints.initial_state=NormalState; XSetWMHints( wsDisplay,win->WindowID,&win->WMHints ); wsWindowDecoration( win,win->Decorations ); XStoreName( wsDisplay,win->WindowID,label ); XmbSetWMProperties( wsDisplay,win->WindowID,label,label,NULL,0,NULL,NULL,NULL ); XSetWMProtocols( wsDisplay,win->WindowID,win->AtomsProtocols,3 ); XChangeProperty( wsDisplay,win->WindowID, win->AtomLeaderClient, XA_WINDOW,32,PropModeReplace, (unsigned char *)&LeaderWindow,1 ); wsTextProperty.value=label; wsTextProperty.encoding=XA_STRING; wsTextProperty.format=8; wsTextProperty.nitems=strlen( label ); XSetWMIconName( wsDisplay,win->WindowID,&wsTextProperty ); win->wGC=XCreateGC( wsDisplay,win->WindowID, GCForeground | GCBackground, &win->wGCV ); win->Visible=0; win->Focused=0; win->Mapped=0; win->Rolled=0; if ( D & wsShowWindow ) XMapWindow( wsDisplay,win->WindowID ); wsCreateImage( win,win->Width,win->Height );// --- End of creating -------------------------------------------------------------------------- { int i; for ( i=0;i < wsWLCount;i++ ) if ( wsWindowList[i] == NULL ) break; if ( i == wsWLCount ) { mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_TooManyOpenWindows ); exit( 0 ); } wsWindowList[i]=win; } XFlush( wsDisplay ); XSync( wsDisplay,False ); win->ReDraw=NULL; win->ReSize=NULL; win->Idle=NULL; win->MouseHandler=NULL; win->KeyHandler=NULL; mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[ws] window is created. ( %s ).\n",label );}void wsDestroyWindow( wsTWindow * win ){ int l; l=wsSearch( win->WindowID ); wsWindowList[l]=NULL; if ( win->wsCursor != None ) { XFreeCursor( wsDisplay,win->wsCursor ); win->wsCursor=None; } XFreeGC( wsDisplay,win->wGC ); XUnmapWindow( wsDisplay,win->WindowID ); wsDestroyImage( win ); XDestroyWindow( wsDisplay,win->WindowID );#if 0 win->ReDraw=NULL; win->ReSize=NULL; win->Idle=NULL; win->MouseHandler=NULL; win->KeyHandler=NULL; win->Visible=0; win->Focused=0; win->Mapped=0; win->Rolled=0;#endif}// ----------------------------------------------------------------------------------------------// Handle events.// ----------------------------------------------------------------------------------------------inline int wsSearch( Window win ){ int i; for ( i=0;i<wsWLCount;i++ ) if ( wsWindowList[i] && wsWindowList[i]->WindowID == win ) return i; return -1;}Bool wsEvents( Display * display,XEvent * Event,XPointer arg ){ unsigned long i = 0; int l; int x,y; Window child_window = 0; l=wsSearch( Event->xany.window ); if ( l == -1 ) return !wsTrue; wsWindowList[l]->State=0; switch( Event->type ) { case ClientMessage: if ( Event->xclient.message_type == wsWindowList[l]->AtomProtocols ) { if ( (Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomDeleteWindow ) { i=wsWindowClosed; goto expose; } if ( (Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomTakeFocus ) { i=wsWindowFocusIn; wsWindowList[l]->Focused=wsFocused; goto expose; } if ( (Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomRolle ) { mp_msg( MSGT_GPLAYER,MSGL_V,"[ws] role set.\n" ); } } else { /* try to process DND events */ wsXDNDProcessClientMessage(wsWindowList[l],&Event->xclient); } break; case MapNotify: i=wsWindowMapped; wsWindowList[l]->Mapped=wsMapped; goto expose; case UnmapNotify: i=wsWindowUnmapped; wsWindowList[l]->Mapped=wsNone; goto expose; case FocusIn: if ( wsWindowList[l]->Focused == wsFocused ) break; i=wsWindowFocusIn; wsWindowList[l]->Focused=wsFocused; goto expose; case FocusOut: if ( wsWindowList[l]->Focused == wsNone ) break; i=wsWindowFocusOut; wsWindowList[l]->Focused=wsNone; goto expose; case VisibilityNotify: switch( Event->xvisibility.state ) { case VisibilityUnobscured: i=wsWindowVisible; wsWindowList[l]->Visible=wsVisible; goto expose; case VisibilityFullyObscured: i=wsWindowNotVisible; wsWindowList[l]->Visible=wsNotVisible; goto expose; case VisibilityPartiallyObscured: i=wsWindowPartialVisible; wsWindowList[l]->Visible=wsPVisible; goto expose; }expose: wsWindowList[l]->State=i; if ( wsWindowList[l]->ReDraw ) wsWindowList[l]->ReDraw(); break; case Expose: wsWindowList[l]->State=wsWindowExpose; if ( ( wsWindowList[l]->ReDraw )&&( !Event->xexpose.count ) ) wsWindowList[l]->ReDraw(); break; case ConfigureNotify: XTranslateCoordinates( wsDisplay,wsWindowList[l]->WindowID,wsRootWin,0,0,&x,&y,&child_window ); if ( ( wsWindowList[l]->X != x )||( wsWindowList[l]->Y != y )||( wsWindowList[l]->Width != Event->xconfigure.width )||( wsWindowList[l]->Height != Event->xconfigure.height ) ) { wsWindowList[l]->X=x; wsWindowList[l]->Y=y; wsWindowList[l]->Width=Event->xconfigure.width; wsWindowList[l]->Height=Event->xconfigure.height; if ( wsWindowList[l]->ReSize ) wsWindowList[l]->ReSize( wsWindowList[l]->X,wsWindowList[l]->Y,wsWindowList[l]->Width,wsWindowList[l]->Height ); } wsWindowList[l]->Rolled=wsNone; if ( Event->xconfigure.y < 0 ) { i=wsWindowRolled; wsWindowList[l]->Rolled=wsRolled; goto expose; } break; case KeyPress: i=wsKeyPressed; goto keypressed; case KeyRelease: i=wsKeyReleased;keypressed: wsWindowList[l]->Alt=0; wsWindowList[l]->Shift=0; wsWindowList[l]->NumLock=0; wsWindowList[l]->Control=0; wsWindowList[l]->CapsLock=0; if ( Event->xkey.state & Mod1Mask ) wsWindowList[l]->Alt=1; if ( Event->xkey.state & Mod2Mask ) wsWindowList[l]->NumLock=1; if ( Event->xkey.state & ControlMask ) wsWindowList[l]->Control=1; if ( Event->xkey.state & ShiftMask ) wsWindowList[l]->Shift=1; if ( Event->xkey.state & LockMask ) wsWindowList[l]->CapsLock=1;#if 0 { KeySym keySym; keySym=XKeycodeToKeysym( wsDisplay,Event->xkey.keycode,0 ); if ( keySym != NoSymbol ) { keySym=( (keySym&0xff00) != 0?( (keySym&0x00ff) + 256 ):( keySym ) ); wsKeyTable[ keySym ]=i; if ( wsWindowList[l]->KeyHandler ) wsWindowList[l]->KeyHandler( Event->xkey.state,i,keySym ); } }#else { int key; char buf[100]; KeySym keySym; static XComposeStatus stat; XLookupString( &Event->xkey,buf,sizeof(buf),&keySym,&stat ); key=( (keySym&0xff00) != 0?( (keySym&0x00ff) + 256 ):( keySym ) ); wsKeyTable[ key ]=i; if ( wsWindowList[l]->KeyHandler ) wsWindowList[l]->KeyHandler( Event->xkey.keycode,i,key ); }#endif break; case MotionNotify: i=wsMoveMouse; { /* pump all motion events from the display queue: this way it works faster when moving the window */ static XEvent e; if ( Event->xmotion.state ) { while(XCheckTypedWindowEvent(display,Event->xany.window,MotionNotify,&e)){ /* FIXME: need to make sure we didn't release/press the button in between...*/ /* FIXME: do we need some timeout here to make sure we don't spend too much time removing events from the queue? */ Event = &e; } } } goto buttonreleased; case ButtonRelease: i=Event->xbutton.button + 128; goto buttonreleased; case ButtonPress: i=Event->xbutton.button; goto buttonreleased; case EnterNotify: i=wsEnterWindow; goto buttonreleased; case LeaveNotify: i=wsLeaveWindow;buttonreleased: if ( wsWindowList[l]->MouseHandler ) wsWindowList[l]->MouseHandler( i,Event->xbutton.x,Event->xbutton.y,Event->xmotion.x_root,Event->xmotion.y_root ); break; case SelectionNotify: /* Handle DandD */ wsXDNDProcessSelection(wsWindowList[l],Event); break; } XFlush( wsDisplay ); XSync( wsDisplay,False ); return !wsTrue;}Bool wsDummyEvents( Display * display,XEvent * Event,XPointer arg ){ return True; }void wsHandleEvents( void ){ // handle pending events while ( XPending(wsDisplay) ){ XNextEvent( wsDisplay,&wsEvent );// printf("### X event: %d [%d]\n",wsEvent.type,delay); wsEvents( wsDisplay,&wsEvent,NULL ); }}void wsMainLoop( void ){ int delay=20; mp_msg( MSGT_GPLAYER,MSGL_V,"[ws] init threads: %d\n",XInitThreads() ); XSynchronize( wsDisplay,False ); XLockDisplay( wsDisplay );// XIfEvent( wsDisplay,&wsEvent,wsEvents,NULL );#if 1while(wsTrue){ // handle pending events while ( XPending(wsDisplay) ){ XNextEvent( wsDisplay,&wsEvent ); wsEvents( wsDisplay,&wsEvent,NULL ); delay=0; } usleep(delay*1000); // FIXME! if(delay<10*20) delay+=20; // pump up delay up to 0.2 sec (low activity)}#else while( wsTrue ) { XIfEvent( wsDisplay,&wsEvent,wsDummyEvents,NULL ); wsEvents( wsDisplay,&wsEvent,NULL ); }#endif XUnlockDisplay( wsDisplay );}// ----------------------------------------------------------------------------------------------// Move window to selected layer// ----------------------------------------------------------------------------------------------#define WIN_LAYER_ONBOTTOM 2#define WIN_LAYER_NORMAL 4#define WIN_LAYER_ONTOP 10void wsSetLayer( Display * wsDisplay, Window win, int layer ){ vo_x11_setlayer( wsDisplay,win,layer ); }// ----------------------------------------------------------------------------------------------// Switch to fullscreen.// ----------------------------------------------------------------------------------------------void wsFullScreen( wsTWindow * win ){ int decoration = 0; if ( win->isFullScreen ) { vo_x11_ewmh_fullscreen( _NET_WM_STATE_REMOVE ); // removes fullscreen state if wm supports EWMH if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // shouldn't be needed with EWMH fs { win->X=win->OldX; win->Y=win->OldY; win->Width=win->OldWidth; win->Height=win->OldHeight; decoration=win->Decorations; }#ifdef ENABLE_DPMS wsScreenSaverOn( wsDisplay );#endif win->isFullScreen=False; } else { if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // shouldn't be needed with EWMH fs { win->OldX=win->X; win->OldY=win->Y; win->OldWidth=win->Width; win->OldHeight=win->Height; vo_dx = win->X; vo_dy = win->Y; vo_dwidth = win->Width; vo_dheight = win->Height; 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; win->X=wsOrgX; win->Y=wsOrgY; win->Width=wsMaxX; win->Height=wsMaxY; } win->isFullScreen=True;#ifdef ENABLE_DPMS wsScreenSaverOff( wsDisplay );#endif vo_x11_ewmh_fullscreen( _NET_WM_STATE_ADD ); // adds fullscreen state if wm supports EWMH } if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // shouldn't be needed with EWMH fs { vo_x11_decoration( wsDisplay,win->WindowID,decoration ); vo_x11_sizehint( win->X,win->Y,win->Width,win->Height,0 ); vo_x11_setlayer( wsDisplay,win->WindowID,win->isFullScreen ); if ((!(win->isFullScreen)) & vo_ontop) vo_x11_setlayer(wsDisplay, win->WindowID,1); XMoveResizeWindow( wsDisplay,win->WindowID,win->X,win->Y,win->Width,win->Height ); } if ( vo_wm_type == 0 && !(vo_fsmode&16) ) { XWithdrawWindow( wsDisplay,win->WindowID,wsScreen ); } XMapRaised( wsDisplay,win->WindowID ); XRaiseWindow( wsDisplay,win->WindowID ); XFlush( wsDisplay );}// ----------------------------------------------------------------------------------------------// Redraw screen.// ----------------------------------------------------------------------------------------------void wsPostRedisplay( wsTWindow * win ){ if ( win->ReDraw ) { win->State=wsWindowExpose; win->ReDraw(); XFlush( wsDisplay ); }}// ----------------------------------------------------------------------------------------------// Do Exit.// ----------------------------------------------------------------------------------------------void wsDoExit( void ){ wsTrue=False; wsResizeWindow( wsWindowList[0],32,32 ); }// ----------------------------------------------------------------------------------------------// Put 'Image' to window.// ----------------------------------------------------------------------------------------------void wsConvert( wsTWindow * win,unsigned char * Image,unsigned int Size ){ int i; if ( wsConvFunc ) wsConvFunc( Image,win->ImageData,win->xImage->width * win->xImage->height * 4 ); if (!wsNonNativeOrder) return; switch (win->xImage->bits_per_pixel) { case 32: { uint32_t *d = win->ImageData; for (i = 0; i < win->xImage->width * win->xImage->height; i++) d[i] = bswap_32(d[i]); break; } case 16: case 15: { uint16_t *d = win->ImageData; for (i = 0; i < win->xImage->width * win->xImage->height; i++) d[i] = bswap_16(d[i]); break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -