diff options
Diffstat (limited to 'Gui/wm')
-rw-r--r-- | Gui/wm/widget.h | 2 | ||||
-rw-r--r-- | Gui/wm/ws.c | 1077 | ||||
-rw-r--r-- | Gui/wm/ws.h | 239 | ||||
-rw-r--r-- | Gui/wm/wsconv.c | 204 | ||||
-rw-r--r-- | Gui/wm/wsconv.h | 39 | ||||
-rw-r--r-- | Gui/wm/wskeys.h | 140 | ||||
-rw-r--r-- | Gui/wm/wsmkeys.h | 52 |
7 files changed, 1753 insertions, 0 deletions
diff --git a/Gui/wm/widget.h b/Gui/wm/widget.h new file mode 100644 index 0000000000..b7751568ea --- /dev/null +++ b/Gui/wm/widget.h @@ -0,0 +1,2 @@ + +#define wgIsRect( X,Y,tX,tY,bX,bY ) ( ( X > tX )&&( Y > tY )&&( X < bX )&&( Y < bY ) )
\ No newline at end of file diff --git a/Gui/wm/ws.c b/Gui/wm/ws.c new file mode 100644 index 0000000000..49122e8500 --- /dev/null +++ b/Gui/wm/ws.c @@ -0,0 +1,1077 @@ + +// -------------------------------------------------------------------------- +// 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 <errno.h> +#include <stdlib.h> +#include <stdio.h> + +#include "ws.h" +#include "wsconv.h" +#include "../../config.h" + +#include <X11/extensions/xf86dga.h> +#include <X11/extensions/xf86dgastr.h> +#include <X11/extensions/XShm.h> +#include <X11/extensions/shape.h> +#include <sys/ipc.h> +#include <sys/shm.h> + +typedef struct +{ + long flags; + long functions; + long decorations; + long input_mode; + long status; +} MotifWmHints; + +Atom wsMotifHints; + +unsigned int wsMaxX = 0; // Screen width. +unsigned int wsMaxY = 0; // Screen height. + +Display * wsDisplay; +int wsScreen; +Window wsRootWin; +XEvent wsEvent; +int wsWindowDepth; +GC wsHGC; +MotifWmHints wsMotifWmHints; +Atom wsTextProperlyAtom = None; + +int wsDepthOnScreen = 0; +int wsRedMask = 0; +int wsGreenMask = 0; +int wsBlueMask = 0; +int wsOutMask = 0; + +int wsTrue = True; + +wsTWindow * wsWindowList[5] = { NULL,NULL,NULL,NULL,NULL }; +int wsWLCount = 0; + +unsigned long wsKeyTable[512]; + +int wsUseXShm = 1; +int wsUseDGA = 1; +int wsUseXShape = 1; + +int XShmGetEventBase( Display* ); +inline int wsSearch( Window win ); + +#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 ) + { + memset( &wsMotifWmHints,0,sizeof( MotifWmHints ) ); + wsMotifWmHints.flags=( d?0:MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS ); + wsMotifWmHints.functions=( d?0:MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE ); + wsMotifWmHints.decorations=( d?MWM_DECOR_ALL:0 ); + 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 ); + exit( 0 ); +} + +void wsXInit( void ) +{ + char * DisplayName = ":0.0"; + int eventbase; + int errorbase; + + if ( getenv( "DISPLAY" ) ) DisplayName=getenv( "DISPLAY" ); + wsDisplay=XOpenDisplay( DisplayName ); + if ( !wsDisplay ) + { + fprintf( stderr,"[ws] couldn't open the display !\n" ); + exit( 0 ); + } + + if ( !XShmQueryExtension( wsDisplay ) ) + { + fprintf( stderr,"[ws] sorry, your system is not supported X shared memory extension.\n" ); + wsUseXShm=0; + } +// if ( !XDGAQueryExtension( wsDisplay,&eventbase,&errorbase ) ) + { + fprintf( stderr,"[ws] sorry, your system is not supported DGA extension.\n" ); + wsUseDGA=0; + } + #ifdef HAVE_XSHAPE + if ( !XShapeQueryExtension( wsDisplay,&eventbase,&errorbase ) ) + { + fprintf( stderr,"[ws] sorry, your system is not supported XShape extension.\n" ); + wsUseXShape=0; + } + #else + wsUseXShape=0; + #endif + + XSynchronize( wsDisplay,True ); + + wsScreen=DefaultScreen( wsDisplay ); + wsRootWin=RootWindow( wsDisplay,wsScreen ); + wsMaxX=DisplayWidth( wsDisplay,wsScreen ); + wsMaxY=DisplayHeight( wsDisplay,wsScreen ); + + wsGetDepthOnScreen(); + #ifdef DEBUG + { + int minor,major,shp; + fprintf( stderr,"[ws] Screen depth: %d\n",wsDepthOnScreen ); + fprintf( stderr,"[ws] red mask: 0x%x\n",wsRedMask ); + fprintf( stderr,"[ws] green mask: 0x%x\n",wsGreenMask ); + fprintf( stderr,"[ws] blue mask: 0x%x\n",wsBlueMask ); + if ( wsUseXShm ) + { + XShmQueryVersion( wsDisplay,&major,&minor,&shp ); + fprintf( stderr,"[ws] XShm version is %d.%d\n",major,minor ); + } + if ( wsUseDGA ) + { +// XDGAQueryVersion( wsDisplay,&major,&minor ); +// fprintf( stderr,"[ws] DGA version is %d.%d\n",major,minor ); + } + #ifdef HAVE_XSHAPE + if ( wsUseXShape ) + { + XShapeQueryVersion( wsDisplay,&major,&minor ); + fprintf( stderr,"[ws] XShape version is %d.%d\n",major,minor ); + } + #endif + } + #endif + initConverter(); + wsOutMask=wsGetOutMask(); + switch ( wsOutMask ) + { + case wsRGB32: + wsConvFunc=BGR8880_to_RGB8880_c; + break; + case wsBGR32: + wsConvFunc=BGR8880_to_BGR8880_c; + break; + case wsRGB24: + #ifdef xHAVE_MMX + wsConvFunc=BGR8880_to_RGB888_mmx; + #else + wsConvFunc=BGR8880_to_RGB888_c; + #endif + break; + case wsBGR24: + wsConvFunc=BGR8880_to_BGR888_c; + break; + case wsRGB16: + wsConvFunc=BGR8880_to_RGB565_c; + break; + case wsBGR16: + wsConvFunc=BGR8880_to_BGR565_c; + break; + case wsRGB15: + wsConvFunc=BGR8880_to_RGB555_c; + break; + case wsBGR15: + wsConvFunc=BGR8880_to_BGR555_c; + break; + } + XSetIOErrorHandler( wsIOErrorHandler ); + 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 ) +{ + 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 ); break; + case -2: win->X=wsMaxX - wX - 1; break; + default: win->X=X; break; + } + switch ( Y ) + { + case -1: win->Y=( wsMaxY / 2 ) - ( hY / 2 ); break; + case -2: win->Y=wsMaxY - hY - 1; 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 ); + + XGetWindowAttributes( wsDisplay,wsRootWin,&win->Attribs ); + if ( win->Attribs.depth < 15 ) + { + fprintf( stderr,"[ws] sorry, this color depth is not enough.\n" ); + exit( 0 ); + } + XMatchVisualInfo( wsDisplay,wsScreen,win->Attribs.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->AtomProtocols=XInternAtom( wsDisplay,"WM_PROTOCOLS",False ); + { + char buf[32]; int i; + sprintf( buf,"_%s_REMOTE",label ); + for( i=0;i<strlen( buf );i++ ) + if ( ( buf[i] >= 'a' )&&( buf[i] <= 'z' ) ) buf[i]=buf[i] - 32; + for( i=0;i<strlen( buf );i++ ) + if ( buf[i] == ' ' ) buf[i]='_'; + fprintf( stderr,"[ws] atomname: %s\n",buf ); + win->AtomRemote=XInternAtom( wsDisplay,buf,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=BlackPixel( wsDisplay,wsScreen ); + 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 | + //SubstructureRedirectMask | + //SubstructureNotifyMask | + //ResizeRedirectMask | + //GCGraphicsExposures | + 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->WindowAttrib.save_under=True; +// win->WindowAttrib.do_not_propagate_mask = True; + + win->WindowMask=CWBackPixel | CWBorderPixel | + CWColormap | CWEventMask | CWCursor | + CWX | CWY | CWWidth | CWHeight | + 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=label; + wsClassHint.res_class="mPlayer"; + XSetClassHint( wsDisplay,win->WindowID,&wsClassHint ); + + win->SizeHint.flags=PPosition | PSize | PResizeInc; // | PBaseSize + win->SizeHint.x=win->X; + win->SizeHint.y=win->Y; + win->SizeHint.width=win->Width; + win->SizeHint.height=win->Height; + if ( D & wsMaxSize ) + { + win->SizeHint.flags|=PMaxSize; + win->SizeHint.min_width=win->Width; + win->SizeHint.min_height=win->Height; + } + if ( D & wsMinSize ) + { + win->SizeHint.flags|=PMinSize; + 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; + 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 ); + + XChangeProperty( wsDisplay,win->WindowID, + win->AtomRemote,XA_STRING, + 8,PropModeReplace, + "REALIZED",8 ); + +// win->Font=XLoadQueryFont( wsDisplay,"-adobe-helvetica-bold-r-normal--14-140-75-75-p-77-iso8859-1" ); +// -adobe-times-medium-r-normal--14-140-75-75-p-77-iso8859-1" ); +// -misc-fixed-bold-r-normal--13-120-75-75-C-80-iso8859-1" ); +// -misc-fixed-bold-r-normal--15-140-75-75-C-90-iso8859-1" ); +// -misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1" ); +// -adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1" ); +// -adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" ); +// -*-helvetica-bold-o-normal--14-*-*-*-p-*-iso8859-1" ); +// if ( !win->Font ) win->Font=XLoadQueryFont( wsDisplay,"fixed" ); +// if ( !win->Font ) +// { +// fprintf( stderr,"[main] could not load font.\n" ); +// exit( 0 ); +// } +// win->FontHeight=win->Font->ascent + win->Font->descent; +// +// #ifdef DEBUG +// fprintf( stderr,"[ws] font height: %d\n",win->FontHeight ); +// #endif + +// win->wGCV.font=win->Font->fid; +// win->wGCV.foreground=wsBlack; +// win->wGCV.background=wsBlack; + + win->wGC=XCreateGC( wsDisplay,win->WindowID, +// GCForeground | GCBackground, + 0, + &win->wGCV ); + + win->Visible=0; + win->Focused=0; + win->Mapped=0; + win->Rolled=0; + if ( D & wsShowWindow ) XMapWindow( wsDisplay,win->WindowID ); + + wsCreateImage( win ); +// --- End of creating -------------------------------------------------------------------------- + + wsWindowList[wsWLCount++]=win; + + XFlush( wsDisplay ); + XSync( wsDisplay,False ); + + win->ReDraw=NULL; + win->ReSize=NULL; + win->Idle=NULL; + win->MouseHandler=NULL; + win->KeyHandler=NULL; + #ifdef DEBUG + fprintf( stderr,"[ws] window is created. ( %s ).\n",label ); + #endif +} + +void wsDestroyWindow( wsTWindow * win ) +{ + int l; + l=wsSearch( win->WindowID ); + wsWindowList[l]=NULL; + if ( win->wsCursor != None ) + { + XFreeCursor( wsDisplay,win->wsCursor ); + win->wsCursor=None; + } + XUnmapWindow( wsDisplay,win->WindowID ); + wsDestroyImage( win ); + XDestroyWindow( wsDisplay,win->WindowID ); + 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; +} + +// ---------------------------------------------------------------------------------------------- +// Handle events. +// ---------------------------------------------------------------------------------------------- + +inline int wsSearch( Window win ) +{ + int i; + for ( i=0;i<wsWLCount;i++ ) if ( wsWindowList[i]->WindowID == win ) return i; + return -1; +} + +Bool wsEvents( Display * display,XEvent * Event,XPointer arg ) +{ + KeySym keySym; + unsigned long i = 0; + int l; + int x,y; + Window child_window = 0; + + l=wsSearch( Event->xany.window ); + if ( l == -1 ) return !wsTrue; + switch( Event->type ) + { + case ClientMessage: + if ( Event->xclient.message_type == wsWindowList[l]->AtomProtocols ) + { + if ( Event->xclient.data.l[0] == wsWindowList[l]->AtomDeleteWindow ) + { wsTrue=False; break; } + if ( Event->xclient.data.l[0] == wsWindowList[l]->AtomTakeFocus ) + { i=wsWindowFocusIn; wsWindowList[l]->Focused=wsFocused; goto expose; } + if ( Event->xclient.data.l[0] == wsWindowList[l]->AtomRolle ) + { fprintf( stderr,"[ws] rolled.\n" ); } + } + break; + +// case CirculateRequest:fprintf( stderr,"[ws,r] win: 0x%x\n",(int)Event->xcirculaterequest.window ); break; +// case CirculateNotify: fprintf( stderr,"[ws,c] win: 0x%x\n",(int)Event->xcirculate.window ); 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( wsDisplay,Event->xany.window ); + break; + + case Expose: + wsWindowList[l]->State=wsWindowExpose; + if ( ( wsWindowList[l]->ReDraw )&&( !Event->xexpose.count ) ) wsWindowList[l]->ReDraw( wsDisplay,Event->xany.window ); + 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; +// fprintf( stderr,"[ws] resize: %d,%d %dx%d\n",wsWindowList[l]->X,wsWindowList[l]->Y,Event->xconfigure.width,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; + 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 ); + } + break; + + case MotionNotify: i=wsMoveMouse; 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 PropertyNotify: +// fprintf(stderr,"[ws] PropertyNotify %s\n",XGetAtomName( wsDisplay,Event->xproperty.atom ) ); + if ( Event->xproperty.atom == wsWindowList[l]->AtomRemote ) + { + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char * args = NULL; + +// fprintf( stderr,"[ws] remote property notify.\n" ); + XGetWindowProperty( wsDisplay, + Event->xproperty.window, + Event->xproperty.atom, + 0,( 65536 / sizeof( long ) ), + False,XA_STRING, + &type,&format,&nitems,&bytesafter, + &args ); + if ( ( nitems )&&( wsWindowList[l]->RemoteHandler ) ) + { + args[strlen( args ) - 1]=0; + wsWindowList[l]->RemoteHandler( args ); + args[strlen( args ) - 1]=1; + XFree( args ); + } + } + break; + + } + XFlush( wsDisplay ); + XSync( wsDisplay,False ); + return !wsTrue; +// return True; +} + +Bool wsDummyEvents( Display * display,XEvent * Event,XPointer arg ) +{ return True; } + +void wsMainLoop( void ) +{ + fprintf( stderr,"[ws] init threads: %d\n",XInitThreads() ); + XSynchronize( wsDisplay,False ); + XLockDisplay( wsDisplay ); +// XIfEvent( wsDisplay,&wsEvent,wsEvents,NULL ); + while( wsTrue ) + { + XIfEvent( wsDisplay,&wsEvent,wsDummyEvents,NULL ); + wsEvents( wsDisplay,&wsEvent,NULL ); + } + XUnlockDisplay( wsDisplay ); +} + +// ---------------------------------------------------------------------------------------------- +// Switch to fullscreen. +// ---------------------------------------------------------------------------------------------- +void wsFullScreen( wsTWindow * win ) +{ + int decoration = 0; + XUnmapWindow( wsDisplay,win->WindowID ); + win->SizeHint.flags=0; + if ( win->isFullScreen ) + { + win->X=win->OldX; + win->Y=win->OldY; + win->Width=win->OldWidth; + win->Height=win->OldHeight; + win->isFullScreen=False; + if ( win->Property & wsMaxSize ) + { + win->SizeHint.flags|=PMaxSize; + win->SizeHint.max_width=win->Width; + win->SizeHint.max_height=win->Height; + } + if ( win->Property & wsMinSize ) + { + win->SizeHint.flags|=PMinSize; + win->SizeHint.min_width=win->Width; + win->SizeHint.min_height=win->Height; + } + decoration=win->Decorations; + wsScreenSaverOn( wsDisplay ); + } + else + { + win->OldX=win->X; win->OldY=win->Y; + win->OldWidth=win->Width; win->OldHeight=win->Height; + win->X=0; win->Y=0; + win->Width=wsMaxX; win->Height=wsMaxY; + win->isFullScreen=True; +// if ( win->Property & wsMaxSize ) +// { +// win->SizeHint.flags|=PMaxSize; +// win->SizeHint.min_width=0; +// win->SizeHint.min_height=0; +// } +// if ( win->Property & wsMinSize ) +// { +// win->SizeHint.flags|=PMinSize; +// win->SizeHint.max_width=4096; +// win->SizeHint.max_height=4096; +// } + wsScreenSaverOff( wsDisplay ); + } + + win->SizeHint.flags|=PPosition | PSize; + win->SizeHint.x=win->X; + win->SizeHint.y=win->Y; + win->SizeHint.width=win->Width; + win->SizeHint.height=win->Height; + XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint ); + + XMoveResizeWindow( wsDisplay,win->WindowID,win->X,win->Y,win->Width,win->Height ); + wsWindowDecoration( win,decoration ); + XRaiseWindow( wsDisplay,win->WindowID ); + XMapWindow( wsDisplay,win->WindowID ); +} + +// ---------------------------------------------------------------------------------------------- +// Redraw screen. +// ---------------------------------------------------------------------------------------------- +void wsPostRedisplay( wsTWindow * win ) +{ + if ( win->ReDraw ) + { + win->ReDraw( wsDisplay,win->WindowID ); + 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 ) +{ if ( wsConvFunc ) wsConvFunc( Image,win->ImageData,win->xImage->width * win->xImage->height ); } + +void wsPutImage( wsTWindow * win ) +{ + if ( wsUseXShm ) + { + XShmPutImage( wsDisplay,win->WindowID,win->wGC,win->xImage, + 0,0, + ( win->Width - win->xImage->width ) / 2,( win->Height - win->xImage->height ) / 2, + win->xImage->width,win->xImage->height,0 ); +// win->Width,win->Height,0 ); + } + else + { + XPutImage( wsDisplay,win->WindowID,win->wGC,win->xImage, + 0,0, + ( win->Width - win->xImage->width ) / 2,( win->Height - win->xImage->height ) / 2, + win->xImage->width,win->xImage->height ); + } +} + +// ---------------------------------------------------------------------------------------------- +// Move window to x, y. +// ---------------------------------------------------------------------------------------------- +void wsMoveWindow( wsTWindow * win,int x, int y ) +{ + switch ( x ) + { + case -1: win->X=( wsMaxX / 2 ) - ( win->Width / 2 ); break; + case -2: win->X=wsMaxX - win->Width; break; + default: win->X=x; break; + } + switch ( y ) + { + case -1: win->Y=( wsMaxY / 2 ) - ( win->Height / 2 ); break; + case -2: win->Y=wsMaxY - win->Height; break; + default: win->Y=y; break; + } + + win->SizeHint.flags=PPosition; + win->SizeHint.x=win->X; + win->SizeHint.y=win->Y; + XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint ); + + XMoveWindow( wsDisplay,win->WindowID,win->X,win->Y ); +} + +// ---------------------------------------------------------------------------------------------- +// Resize window to sx, sy. +// ---------------------------------------------------------------------------------------------- +void wsResizeWindow( wsTWindow * win,int sx, int sy ) +{ + win->Width=sx; + win->Height=sy; + + win->SizeHint.flags=PSize; + win->SizeHint.width=win->Width; + win->SizeHint.height=win->Height; + if ( win->Property & wsMinSize ) + { + win->SizeHint.flags|=PMinSize; + win->SizeHint.min_width=win->Width; + win->SizeHint.min_height=win->Height; + } + if ( win->Property & wsMaxSize ) + { + win->SizeHint.flags|=PMaxSize; + win->SizeHint.max_width=win->Width; + win->SizeHint.max_height=win->Height; + } + XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint ); + XResizeWindow( wsDisplay,win->WindowID,sx,sy ); +} + +// ---------------------------------------------------------------------------------------------- +// Iconify window. +// ---------------------------------------------------------------------------------------------- +void wsIconify( wsTWindow win ) +{ XIconifyWindow( wsDisplay,win.WindowID,0 ); } + +// ---------------------------------------------------------------------------------------------- +// Move top the window. +// ---------------------------------------------------------------------------------------------- +void wsMoveTopWindow( wsTWindow * win ) +{ XRaiseWindow( wsDisplay,win->WindowID ); } +//{ XUnmapWindow( wsDisplay,win.WindowID ); XMapWindow( wsDisplay,win.WindowID ); } + +// ---------------------------------------------------------------------------------------------- +// Set window background to 'color'. +// ---------------------------------------------------------------------------------------------- +void wsSetBackground( wsTWindow * win,int color ) +{ XSetWindowBackground( wsDisplay,win->WindowID,color ); } + +void wsSetBackgroundRGB( wsTWindow * win,int r,int g,int b ) +{ + int color = 0; + switch ( wsOutMask ) + { + case wsRGB32: + case wsRGB24: color=( r << 16 ) + ( g << 8 ) + b; break; + case wsBGR32: + case wsBGR24: color=( b << 16 ) + ( g << 8 ) + r; break; + case wsRGB16: PACK_RGB16( r,g,b,color ); break; + case wsBGR16: PACK_RGB16( b,g,r,color ); break; + case wsRGB15: PACK_RGB15( r,g,b,color ); break; + case wsBGR15: PACK_RGB15( b,g,r,color ); break; + } + XSetWindowBackground( wsDisplay,win->WindowID,color ); +} + + +// ---------------------------------------------------------------------------------------------- +// Draw string at x,y with fc ( foreground color ) and bc ( background color ). +// ---------------------------------------------------------------------------------------------- +void wsDrawString( wsTWindow win,int x,int y,char * str,int fc,int bc ) +{ + XSetForeground( wsDisplay,win.wGC,bc ); + XFillRectangle( wsDisplay,win.WindowID,win.wGC,x,y, + XTextWidth( win.Font,str,strlen( str ) ) + 20, + win.FontHeight + 2 ); + XSetForeground( wsDisplay,win.wGC,fc ); + XDrawString( wsDisplay,win.WindowID,win.wGC,x + 10,y + 13,str,strlen( str ) ); +} + +// ---------------------------------------------------------------------------------------------- +// Calculation string width. +// ---------------------------------------------------------------------------------------------- +int wsTextWidth( wsTWindow win,char * str ) +{ return XTextWidth( win.Font,str,strlen( str ) ) + 20; } + +// ---------------------------------------------------------------------------------------------- +// Show / hide mouse cursor. +// ---------------------------------------------------------------------------------------------- +void wsVisibleMouse( wsTWindow * win,int m ) +{ + switch ( m ) + { + case wsShowMouseCursor: + if ( win->wsCursor != None ) + { + XFreeCursor( wsDisplay,win->wsCursor ); + win->wsCursor=None; + } + XDefineCursor( wsDisplay,win->WindowID,0 ); + break; + case wsHideMouseCursor: + win->wsCursor=XCreatePixmapCursor( wsDisplay,win->wsCursorPixmap,win->wsCursorPixmap,&win->wsColor,&win->wsColor,0,0 ); + XDefineCursor( wsDisplay,win->WindowID,win->wsCursor ); + break; + } + XFlush( wsDisplay ); +} + +int wsGetDepthOnScreen( void ) +{ + int bpp,ibpp; + XImage * mXImage; + XWindowAttributes attribs; + + mXImage=XGetImage( wsDisplay,wsRootWin,0,0,1,1,AllPlanes,ZPixmap ); + bpp=mXImage->bits_per_pixel; + + XGetWindowAttributes( wsDisplay,wsRootWin,&attribs ); + ibpp=attribs.depth; + mXImage=XGetImage( wsDisplay,wsRootWin,0,0,1,1,AllPlanes,ZPixmap ); + bpp=mXImage->bits_per_pixel; + if ( ( ibpp + 7 ) / 8 != ( bpp + 7 ) / 8 ) ibpp=bpp; + wsDepthOnScreen=ibpp; + wsRedMask=mXImage->red_mask; + wsGreenMask=mXImage->green_mask; + wsBlueMask=mXImage->blue_mask; + XDestroyImage( mXImage ); + return ibpp; +} + +void wsXDone( void ) +{ +// if ( wsSwitchedAnotherVideoMode ) wsChangeVideoMode( wsOldXResolution,wsOldYResolution ); +// if ( wsUseDGA ) XF86DGADirectVideo( wsDisplay,wsScreen,0 ); + XCloseDisplay( wsDisplay ); +} + +void wsVisibleWindow( wsTWindow * win,int show ) +{ + switch( show ) + { + case wsShowWindow: XMapWindow( wsDisplay,win->WindowID ); break; + case wsHideWindow: XUnmapWindow( wsDisplay,win->WindowID ); break; + } + XFlush( wsDisplay ); +} + +void wsDestroyImage( wsTWindow * win ) |