Add rules to install gmplayer manual pages.
[mplayer/glamo.git] / gui / wm / ws.c
blob65ec992d58f151f3ba26ebe5aa04926c58be4ab5
1 /*
2 * AutoSpace Window System for Linux/Win32 v0.85
3 * written by pontscho/fresh!mindworkz
5 * This file is part of MPlayer.
7 * MPlayer is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * MPlayer is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <X11/Xlib.h>
23 #include <X11/Xproto.h>
24 #include <X11/Xutil.h>
25 #include <X11/keysym.h>
26 #include <X11/Xatom.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <errno.h>
34 #include <inttypes.h>
36 #include "config.h"
37 #include "libvo/x11_common.h"
38 #include "libvo/video_out.h"
39 #include "cpudetect.h"
40 #include "libswscale/swscale.h"
41 #include "libswscale/rgb2rgb.h"
42 #include "libmpcodecs/vf_scale.h"
43 #include "mp_msg.h"
44 #include "help_mp.h"
45 #include "mplayer.h"
46 #include "mpbswap.h"
47 #include "ws.h"
48 #include "wsxdnd.h"
50 #include <X11/extensions/XShm.h>
51 #ifdef CONFIG_XSHAPE
52 #include <X11/extensions/shape.h>
53 #endif
55 #ifdef CONFIG_XINERAMA
56 #include <X11/extensions/Xinerama.h>
57 #endif
59 #ifdef CONFIG_XF86VM
60 #include <X11/extensions/xf86vmode.h>
61 #endif
63 #include <sys/ipc.h>
64 #include <sys/shm.h>
66 #undef ENABLE_DPMS
68 typedef struct
70 unsigned long flags;
71 unsigned long functions;
72 unsigned long decorations;
73 long input_mode;
74 unsigned long status;
75 } MotifWmHints;
77 Atom wsMotifHints;
79 int wsMaxX = 0; // Screen width.
80 int wsMaxY = 0; // Screen height.
81 int wsOrgX = 0; // Screen origin x.
82 int wsOrgY = 0; // Screen origin y.
84 Display * wsDisplay;
85 int wsScreen;
86 Window wsRootWin;
87 XEvent wsEvent;
88 int wsWindowDepth;
89 GC wsHGC;
90 MotifWmHints wsMotifWmHints;
91 Atom wsTextProperlyAtom = None;
92 int wsLayer = 0;
94 int wsDepthOnScreen = 0;
95 int wsRedMask = 0;
96 int wsGreenMask = 0;
97 int wsBlueMask = 0;
98 int wsOutMask = 0;
99 int wsNonNativeOrder = 0;
101 int wsTrue = True;
103 #define wsWLCount 5
104 wsTWindow * wsWindowList[wsWLCount] = { NULL,NULL,NULL,NULL,NULL };
106 unsigned long wsKeyTable[512];
108 int wsUseXShm = 1;
109 int wsUseXShape = 1;
111 inline int wsSearch( Window win );
113 // ---
115 #define PACK_RGB16(r,g,b,pixel) pixel=(b>>3);\
116 pixel<<=6;\
117 pixel|=(g>>2);\
118 pixel<<=5;\
119 pixel|=(r>>3)
121 #define PACK_RGB15(r,g,b,pixel) pixel=(b>>3);\
122 pixel<<=5;\
123 pixel|=(g>>3);\
124 pixel<<=5;\
125 pixel|=(r>>3)
127 typedef void(*wsTConvFunc)( const unsigned char * in_pixels, unsigned char * out_pixels, unsigned num_pixels );
128 wsTConvFunc wsConvFunc = NULL;
130 void rgb32torgb32( const unsigned char * src, unsigned char * dst,unsigned int src_size )
131 { memcpy( dst,src,src_size ); }
133 // ---
135 #define MWM_HINTS_FUNCTIONS (1L << 0)
136 #define MWM_HINTS_DECORATIONS (1L << 1)
137 #define MWM_HINTS_INPUT_MODE (1L << 2)
138 #define MWM_HINTS_STATUS (1L << 3)
140 #define MWM_FUNC_ALL (1L << 0)
141 #define MWM_FUNC_RESIZE (1L << 1)
142 #define MWM_FUNC_MOVE (1L << 2)
143 #define MWM_FUNC_MINIMIZE (1L << 3)
144 #define MWM_FUNC_MAXIMIZE (1L << 4)
145 #define MWM_FUNC_CLOSE (1L << 5)
147 #define MWM_DECOR_ALL (1L << 0)
148 #define MWM_DECOR_BORDER (1L << 1)
149 #define MWM_DECOR_RESIZEH (1L << 2)
150 #define MWM_DECOR_TITLE (1L << 3)
151 #define MWM_DECOR_MENU (1L << 4)
152 #define MWM_DECOR_MINIMIZE (1L << 5)
153 #define MWM_DECOR_MAXIMIZE (1L << 6)
155 #define MWM_INPUT_MODELESS 0
156 #define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
157 #define MWM_INPUT_SYSTEM_MODAL 2
158 #define MWM_INPUT_FULL_APPLICATION_MODAL 3
159 #define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
161 #define MWM_TEAROFF_WINDOW (1L<<0)
163 void wsWindowDecoration( wsTWindow * win,long d )
165 wsMotifHints=XInternAtom( wsDisplay,"_MOTIF_WM_HINTS",0 );
166 if ( wsMotifHints == None ) return;
168 memset( &wsMotifWmHints,0,sizeof( MotifWmHints ) );
169 wsMotifWmHints.flags=MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
170 if ( d )
172 wsMotifWmHints.functions=MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE;
173 wsMotifWmHints.decorations=MWM_DECOR_ALL;
175 XChangeProperty( wsDisplay,win->WindowID,wsMotifHints,wsMotifHints,32,
176 PropModeReplace,(unsigned char *)&wsMotifWmHints,5 );
179 // ----------------------------------------------------------------------------------------------
180 // Init X Window System.
181 // ----------------------------------------------------------------------------------------------
183 int wsIOErrorHandler( Display * dpy )
185 fprintf( stderr,"[ws] IO error in display.\n" );
186 exit( 0 );
189 int wsErrorHandler( Display * dpy,XErrorEvent * Event )
191 char type[128];
192 XGetErrorText( wsDisplay,Event->error_code,type,128 );
193 fprintf(stderr,"[ws] Error in display.\n");
194 fprintf(stderr,"[ws] Error code: %d ( %s )\n",Event->error_code,type );
195 fprintf(stderr,"[ws] Request code: %d\n",Event->request_code );
196 fprintf(stderr,"[ws] Minor code: %d\n",Event->minor_code );
197 fprintf(stderr,"[ws] Modules: %s\n",current_module?current_module:"(NULL)" );
198 exit( 0 );
201 void wsXInit( void* mDisplay )
203 int eventbase;
204 int errorbase;
206 if(mDisplay){
207 wsDisplay=mDisplay;
208 } else {
209 char * DisplayName = ":0.0";
210 if ( getenv( "DISPLAY" ) ) DisplayName=getenv( "DISPLAY" );
211 wsDisplay=XOpenDisplay( DisplayName );
212 if ( !wsDisplay )
214 mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_CouldNotOpenDisplay );
215 exit( 0 );
219 /* enable DND atoms */
220 wsXDNDInitialize();
222 { /* on remote display XShm will be disabled - LGB */
223 char *dispname=DisplayString(wsDisplay);
224 int localdisp=1;
225 if (dispname&&*dispname!=':') {
226 localdisp=0;
227 wsUseXShm=0;
229 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[ws] display name: %s => %s display.\n",dispname,localdisp?"local":"REMOTE");
230 if (!localdisp) mp_msg( MSGT_GPLAYER,MSGL_V,MSGTR_WS_RemoteDisplay );
233 if ( !XShmQueryExtension( wsDisplay ) )
235 mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_WS_NoXshm );
236 wsUseXShm=0;
238 #ifdef CONFIG_XSHAPE
239 if ( !XShapeQueryExtension( wsDisplay,&eventbase,&errorbase ) )
241 mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_WS_NoXshape );
242 wsUseXShape=0;
244 #else
245 wsUseXShape=0;
246 #endif
248 XSynchronize( wsDisplay,True );
250 wsScreen=DefaultScreen( wsDisplay );
251 wsRootWin=RootWindow( wsDisplay,wsScreen );
252 #ifdef CONFIG_XF86VM
254 int clock;
255 XF86VidModeModeLine modeline;
257 XF86VidModeGetModeLine( wsDisplay,wsScreen,&clock ,&modeline );
258 wsMaxX=modeline.hdisplay;
259 wsMaxY=modeline.vdisplay;
261 #endif
263 wsOrgX = wsOrgY = 0;
264 if ( !wsMaxX )
265 wsMaxX=DisplayWidth( wsDisplay,wsScreen );
266 if ( !wsMaxY )
267 wsMaxY=DisplayHeight( wsDisplay,wsScreen );
269 vo_screenwidth = wsMaxX; vo_screenheight = wsMaxY;
270 xinerama_x = wsOrgX; xinerama_y = wsOrgY;
271 update_xinerama_info();
272 wsMaxX = vo_screenwidth; wsMaxY = vo_screenheight;
273 wsOrgX = xinerama_x; wsOrgY = xinerama_y;
275 wsGetDepthOnScreen();
276 #ifdef DEBUG
278 int minor,major,shp;
279 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] Screen depth: %d\n",wsDepthOnScreen );
280 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] size: %dx%d\n",wsMaxX,wsMaxY );
281 #ifdef CONFIG_XINERAMA
282 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] origin: +%d+%d\n",wsOrgX,wsOrgY );
283 #endif
284 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] red mask: 0x%x\n",wsRedMask );
285 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] green mask: 0x%x\n",wsGreenMask );
286 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] blue mask: 0x%x\n",wsBlueMask );
287 if ( wsUseXShm )
289 XShmQueryVersion( wsDisplay,&major,&minor,&shp );
290 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] XShm version is %d.%d\n",major,minor );
292 #ifdef CONFIG_XSHAPE
293 if ( wsUseXShape )
295 XShapeQueryVersion( wsDisplay,&major,&minor );
296 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[ws] XShape version is %d.%d\n",major,minor );
298 #endif
300 #endif
301 wsOutMask=wsGetOutMask();
302 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[ws] Initialized converter: " );
303 sws_rgb2rgb_init(get_sws_cpuflags());
304 switch ( wsOutMask )
306 case wsRGB32:
307 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb32\n" );
308 wsConvFunc=rgb32torgb32;
309 break;
310 case wsBGR32:
311 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr32\n" );
312 wsConvFunc=rgb32tobgr32;
313 break;
314 case wsRGB24:
315 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb24\n" );
316 wsConvFunc=rgb32to24;
317 break;
318 case wsBGR24:
319 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr24\n" );
320 wsConvFunc=rgb32tobgr24;
321 break;
322 case wsRGB16:
323 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb16\n" );
324 wsConvFunc=rgb32to16;
325 break;
326 case wsBGR16:
327 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr16\n" );
328 wsConvFunc=rgb32tobgr16;
329 break;
330 case wsRGB15:
331 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb15\n" );
332 wsConvFunc=rgb32to15;
333 break;
334 case wsBGR15:
335 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr15\n" );
336 wsConvFunc=rgb32tobgr15;
337 break;
339 XSetErrorHandler( wsErrorHandler );
342 // ----------------------------------------------------------------------------------------------
343 // Create window.
344 // X,Y : window position
345 // wX,wY : size of window
346 // bW : border width
347 // cV : visible mouse cursor on window
348 // D : visible frame, title, etc.
349 // sR : screen ratio
350 // ----------------------------------------------------------------------------------------------
352 XClassHint wsClassHint;
353 XTextProperty wsTextProperty;
354 Window LeaderWindow;
356 void wsCreateWindow( wsTWindow * win,int X,int Y,int wX,int hY,int bW,int cV,unsigned char D,char * label )
358 int depth;
360 win->Property=D;
361 if ( D & wsShowFrame ) win->Decorations=1;
362 wsHGC=DefaultGC( wsDisplay,wsScreen );
363 // The window position and size.
364 switch ( X )
366 case -1: win->X=( wsMaxX / 2 ) - ( wX / 2 ) + wsOrgX; break;
367 case -2: win->X=wsMaxX - wX - 1 + wsOrgX; break;
368 default: win->X=X; break;
370 switch ( Y )
372 case -1: win->Y=( wsMaxY / 2 ) - ( hY / 2 ) + wsOrgY; break;
373 case -2: win->Y=wsMaxY - hY - 1 + wsOrgY; break;
374 default: win->Y=Y; break;
376 win->Width=wX;
377 win->Height=hY;
378 win->OldX=win->X;
379 win->OldY=win->Y;
380 win->OldWidth=win->Width;
381 win->OldHeight=win->Height;
383 // Border size for window.
384 win->BorderWidth=bW;
385 // Hide Mouse Cursor
386 win->wsCursor=None;
387 win->wsMouseEventType=cV;
388 win->wsCursorData[0]=0;
389 win->wsCursorPixmap=XCreateBitmapFromData( wsDisplay,wsRootWin,win->wsCursorData,1,1 );
390 if ( !(cV & wsShowMouseCursor) ) win->wsCursor=XCreatePixmapCursor( wsDisplay,win->wsCursorPixmap,win->wsCursorPixmap,&win->wsColor,&win->wsColor,0,0 );
392 depth = vo_find_depth_from_visuals( wsDisplay,wsScreen,NULL );
393 if ( depth < 15 )
395 mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ColorDepthTooLow );
396 exit( 0 );
398 XMatchVisualInfo( wsDisplay,wsScreen,depth,TrueColor,&win->VisualInfo );
400 // ---
401 win->AtomLeaderClient=XInternAtom( wsDisplay,"WM_CLIENT_LEADER",False );
402 win->AtomDeleteWindow=XInternAtom( wsDisplay,"WM_DELETE_WINDOW",False );
403 win->AtomTakeFocus=XInternAtom( wsDisplay,"WM_TAKE_FOCUS",False );
404 win->AtomRolle=XInternAtom( wsDisplay,"WM_WINDOW_ROLE",False );
405 win->AtomWMSizeHint=XInternAtom( wsDisplay,"WM_SIZE_HINT",False );
406 win->AtomWMNormalHint=XInternAtom( wsDisplay,"WM_NORMAL_HINT",False );
407 win->AtomProtocols=XInternAtom( wsDisplay,"WM_PROTOCOLS",False );
408 win->AtomsProtocols[0]=win->AtomDeleteWindow;
409 win->AtomsProtocols[1]=win->AtomTakeFocus;
410 win->AtomsProtocols[2]=win->AtomRolle;
411 // ---
413 win->WindowAttrib.background_pixel=BlackPixel( wsDisplay,wsScreen );
414 win->WindowAttrib.border_pixel=WhitePixel( wsDisplay,wsScreen );
415 win->WindowAttrib.colormap=XCreateColormap( wsDisplay,wsRootWin,win->VisualInfo.visual,AllocNone );
416 win->WindowAttrib.event_mask=StructureNotifyMask | FocusChangeMask |
417 ExposureMask | PropertyChangeMask |
418 EnterWindowMask | LeaveWindowMask |
419 VisibilityChangeMask |
420 KeyPressMask | KeyReleaseMask;
421 if ( ( cV & wsHandleMouseButton ) ) win->WindowAttrib.event_mask|=ButtonPressMask | ButtonReleaseMask;
422 if ( ( cV & wsHandleMouseMove ) ) win->WindowAttrib.event_mask|=PointerMotionMask;
423 win->WindowAttrib.cursor=win->wsCursor;
424 win->WindowAttrib.override_redirect=False;
425 if ( D & wsOverredirect ) win->WindowAttrib.override_redirect=True;
427 win->WindowMask=CWBackPixel | CWBorderPixel |
428 CWColormap | CWEventMask | CWCursor |
429 CWOverrideRedirect;
431 win->WindowID=XCreateWindow( wsDisplay,
432 (win->Parent != 0?win->Parent:wsRootWin),
433 win->X,win->Y,win->Width,win->Height,win->BorderWidth,
434 win->VisualInfo.depth,
435 InputOutput,
436 win->VisualInfo.visual,
437 win->WindowMask,&win->WindowAttrib );
439 wsClassHint.res_name="MPlayer";
441 wsClassHint.res_class="MPlayer";
442 XSetClassHint( wsDisplay,win->WindowID,&wsClassHint );
444 win->SizeHint.flags=PPosition | PSize | PResizeInc | PWinGravity;// | PBaseSize;
445 win->SizeHint.x=win->X;
446 win->SizeHint.y=win->Y;
447 win->SizeHint.width=win->Width;
448 win->SizeHint.height=win->Height;
450 if ( D & wsMinSize )
452 win->SizeHint.flags|=PMinSize;
453 win->SizeHint.min_width=win->Width;
454 win->SizeHint.min_height=win->Height;
456 if ( D & wsMaxSize )
458 win->SizeHint.flags|=PMaxSize;
459 win->SizeHint.max_width=win->Width;
460 win->SizeHint.max_height=win->Height;
463 win->SizeHint.height_inc=1;
464 win->SizeHint.width_inc=1;
465 win->SizeHint.base_width=win->Width;
466 win->SizeHint.base_height=win->Height;
467 win->SizeHint.win_gravity=StaticGravity;
468 XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint );
470 win->WMHints.flags=InputHint | StateHint;
471 win->WMHints.input=True;
472 win->WMHints.initial_state=NormalState;
473 XSetWMHints( wsDisplay,win->WindowID,&win->WMHints );
475 wsWindowDecoration( win,win->Decorations );
476 XStoreName( wsDisplay,win->WindowID,label );
477 XmbSetWMProperties( wsDisplay,win->WindowID,label,label,NULL,0,NULL,NULL,NULL );
479 XSetWMProtocols( wsDisplay,win->WindowID,win->AtomsProtocols,3 );
480 XChangeProperty( wsDisplay,win->WindowID,
481 win->AtomLeaderClient,
482 XA_WINDOW,32,PropModeReplace,
483 (unsigned char *)&LeaderWindow,1 );
485 wsTextProperty.value=label;
486 wsTextProperty.encoding=XA_STRING;
487 wsTextProperty.format=8;
488 wsTextProperty.nitems=strlen( label );
489 XSetWMIconName( wsDisplay,win->WindowID,&wsTextProperty );
491 win->wGC=XCreateGC( wsDisplay,win->WindowID,
492 GCForeground | GCBackground,
493 &win->wGCV );
495 win->Visible=0;
496 win->Focused=0;
497 win->Mapped=0;
498 win->Rolled=0;
499 if ( D & wsShowWindow ) XMapWindow( wsDisplay,win->WindowID );
501 wsCreateImage( win,win->Width,win->Height );
502 // --- End of creating --------------------------------------------------------------------------
505 int i;
506 for ( i=0;i < wsWLCount;i++ )
507 if ( wsWindowList[i] == NULL ) break;
508 if ( i == wsWLCount )
509 { mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_TooManyOpenWindows ); exit( 0 ); }
510 wsWindowList[i]=win;
513 XFlush( wsDisplay );
514 XSync( wsDisplay,False );
516 win->ReDraw=NULL;
517 win->ReSize=NULL;
518 win->Idle=NULL;
519 win->MouseHandler=NULL;
520 win->KeyHandler=NULL;
521 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"[ws] window is created. ( %s ).\n",label );
524 void wsDestroyWindow( wsTWindow * win )
526 int l;
527 l=wsSearch( win->WindowID );
528 wsWindowList[l]=NULL;
529 if ( win->wsCursor != None )
531 XFreeCursor( wsDisplay,win->wsCursor );
532 win->wsCursor=None;
534 XFreeGC( wsDisplay,win->wGC );
535 XUnmapWindow( wsDisplay,win->WindowID );
536 wsDestroyImage( win );
537 XDestroyWindow( wsDisplay,win->WindowID );
538 #if 0
539 win->ReDraw=NULL;
540 win->ReSize=NULL;
541 win->Idle=NULL;
542 win->MouseHandler=NULL;
543 win->KeyHandler=NULL;
544 win->Visible=0;
545 win->Focused=0;
546 win->Mapped=0;
547 win->Rolled=0;
548 #endif
551 // ----------------------------------------------------------------------------------------------
552 // Handle events.
553 // ----------------------------------------------------------------------------------------------
555 inline int wsSearch( Window win )
557 int i;
558 for ( i=0;i<wsWLCount;i++ ) if ( wsWindowList[i] && wsWindowList[i]->WindowID == win ) return i;
559 return -1;
562 Bool wsEvents( Display * display,XEvent * Event,XPointer arg )
564 unsigned long i = 0;
565 int l;
566 int x,y;
567 Window child_window = 0;
569 l=wsSearch( Event->xany.window );
570 if ( l == -1 ) return !wsTrue;
571 wsWindowList[l]->State=0;
572 switch( Event->type )
574 case ClientMessage:
575 if ( Event->xclient.message_type == wsWindowList[l]->AtomProtocols )
577 if ( (Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomDeleteWindow )
578 { i=wsWindowClosed; goto expose; }
579 if ( (Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomTakeFocus )
580 { i=wsWindowFocusIn; wsWindowList[l]->Focused=wsFocused; goto expose; }
581 if ( (Atom)Event->xclient.data.l[0] == wsWindowList[l]->AtomRolle )
582 { mp_msg( MSGT_GPLAYER,MSGL_V,"[ws] role set.\n" ); }
583 } else {
584 /* try to process DND events */
585 wsXDNDProcessClientMessage(wsWindowList[l],&Event->xclient);
587 break;
589 case MapNotify: i=wsWindowMapped; wsWindowList[l]->Mapped=wsMapped; goto expose;
590 case UnmapNotify: i=wsWindowUnmapped; wsWindowList[l]->Mapped=wsNone; goto expose;
591 case FocusIn:
592 if ( wsWindowList[l]->Focused == wsFocused ) break;
593 i=wsWindowFocusIn;
594 wsWindowList[l]->Focused=wsFocused;
595 goto expose;
596 case FocusOut:
597 if ( wsWindowList[l]->Focused == wsNone ) break;
598 i=wsWindowFocusOut;
599 wsWindowList[l]->Focused=wsNone;
600 goto expose;
601 case VisibilityNotify:
602 switch( Event->xvisibility.state )
604 case VisibilityUnobscured: i=wsWindowVisible; wsWindowList[l]->Visible=wsVisible; goto expose;
605 case VisibilityFullyObscured: i=wsWindowNotVisible; wsWindowList[l]->Visible=wsNotVisible; goto expose;
606 case VisibilityPartiallyObscured: i=wsWindowPartialVisible; wsWindowList[l]->Visible=wsPVisible; goto expose;
608 expose:
609 wsWindowList[l]->State=i;
610 if ( wsWindowList[l]->ReDraw ) wsWindowList[l]->ReDraw();
611 break;
613 case Expose:
614 wsWindowList[l]->State=wsWindowExpose;
615 if ( ( wsWindowList[l]->ReDraw )&&( !Event->xexpose.count ) ) wsWindowList[l]->ReDraw();
616 break;
618 case ConfigureNotify:
619 XTranslateCoordinates( wsDisplay,wsWindowList[l]->WindowID,wsRootWin,0,0,&x,&y,&child_window );
620 if ( ( wsWindowList[l]->X != x )||( wsWindowList[l]->Y != y )||( wsWindowList[l]->Width != Event->xconfigure.width )||( wsWindowList[l]->Height != Event->xconfigure.height ) )
622 wsWindowList[l]->X=x; wsWindowList[l]->Y=y;
623 wsWindowList[l]->Width=Event->xconfigure.width; wsWindowList[l]->Height=Event->xconfigure.height;
624 if ( wsWindowList[l]->ReSize ) wsWindowList[l]->ReSize( wsWindowList[l]->X,wsWindowList[l]->Y,wsWindowList[l]->Width,wsWindowList[l]->Height );
627 wsWindowList[l]->Rolled=wsNone;
628 if ( Event->xconfigure.y < 0 )
629 { i=wsWindowRolled; wsWindowList[l]->Rolled=wsRolled; goto expose; }
631 break;
633 case KeyPress: i=wsKeyPressed; goto keypressed;
634 case KeyRelease: i=wsKeyReleased;
635 keypressed:
636 wsWindowList[l]->Alt=0;
637 wsWindowList[l]->Shift=0;
638 wsWindowList[l]->NumLock=0;
639 wsWindowList[l]->Control=0;
640 wsWindowList[l]->CapsLock=0;
641 if ( Event->xkey.state & Mod1Mask ) wsWindowList[l]->Alt=1;
642 if ( Event->xkey.state & Mod2Mask ) wsWindowList[l]->NumLock=1;
643 if ( Event->xkey.state & ControlMask ) wsWindowList[l]->Control=1;
644 if ( Event->xkey.state & ShiftMask ) wsWindowList[l]->Shift=1;
645 if ( Event->xkey.state & LockMask ) wsWindowList[l]->CapsLock=1;
646 #if 0
648 KeySym keySym;
649 keySym=XKeycodeToKeysym( wsDisplay,Event->xkey.keycode,0 );
650 if ( keySym != NoSymbol )
652 keySym=( (keySym&0xff00) != 0?( (keySym&0x00ff) + 256 ):( keySym ) );
653 wsKeyTable[ keySym ]=i;
654 if ( wsWindowList[l]->KeyHandler )
655 wsWindowList[l]->KeyHandler( Event->xkey.state,i,keySym );
658 #else
660 int key;
661 char buf[100];
662 KeySym keySym;
663 static XComposeStatus stat;
665 XLookupString( &Event->xkey,buf,sizeof(buf),&keySym,&stat );
666 key=( (keySym&0xff00) != 0?( (keySym&0x00ff) + 256 ):( keySym ) );
667 wsKeyTable[ key ]=i;
668 if ( wsWindowList[l]->KeyHandler ) wsWindowList[l]->KeyHandler( Event->xkey.keycode,i,key );
670 #endif
671 break;
673 case MotionNotify:
674 i=wsMoveMouse;
676 /* pump all motion events from the display queue:
677 this way it works faster when moving the window */
678 static XEvent e;
679 if ( Event->xmotion.state )
681 while(XCheckTypedWindowEvent(display,Event->xany.window,MotionNotify,&e)){
682 /* FIXME: need to make sure we didn't release/press the button in between...*/
683 /* FIXME: do we need some timeout here to make sure we don't spend too much time
684 removing events from the queue? */
685 Event = &e;
689 goto buttonreleased;
690 case ButtonRelease: i=Event->xbutton.button + 128; goto buttonreleased;
691 case ButtonPress: i=Event->xbutton.button; goto buttonreleased;
692 case EnterNotify: i=wsEnterWindow; goto buttonreleased;
693 case LeaveNotify: i=wsLeaveWindow;
694 buttonreleased:
695 if ( wsWindowList[l]->MouseHandler )
696 wsWindowList[l]->MouseHandler( i,Event->xbutton.x,Event->xbutton.y,Event->xmotion.x_root,Event->xmotion.y_root );
697 break;
699 case SelectionNotify:
700 /* Handle DandD */
701 wsXDNDProcessSelection(wsWindowList[l],Event);
702 break;
704 XFlush( wsDisplay );
705 XSync( wsDisplay,False );
706 return !wsTrue;
709 Bool wsDummyEvents( Display * display,XEvent * Event,XPointer arg )
710 { return True; }
712 void wsHandleEvents( void ){
713 // handle pending events
714 while ( XPending(wsDisplay) ){
715 XNextEvent( wsDisplay,&wsEvent );
716 // printf("### X event: %d [%d]\n",wsEvent.type,delay);
717 wsEvents( wsDisplay,&wsEvent,NULL );
721 void wsMainLoop( void )
723 int delay=20;
724 mp_msg( MSGT_GPLAYER,MSGL_V,"[ws] init threads: %d\n",XInitThreads() );
725 XSynchronize( wsDisplay,False );
726 XLockDisplay( wsDisplay );
727 // XIfEvent( wsDisplay,&wsEvent,wsEvents,NULL );
729 #if 1
731 while(wsTrue){
732 // handle pending events
733 while ( XPending(wsDisplay) ){
734 XNextEvent( wsDisplay,&wsEvent );
735 wsEvents( wsDisplay,&wsEvent,NULL );
736 delay=0;
738 usleep(delay*1000); // FIXME!
739 if(delay<10*20) delay+=20; // pump up delay up to 0.2 sec (low activity)
742 #else
744 while( wsTrue )
746 XIfEvent( wsDisplay,&wsEvent,wsDummyEvents,NULL );
747 wsEvents( wsDisplay,&wsEvent,NULL );
749 #endif
751 XUnlockDisplay( wsDisplay );
754 // ----------------------------------------------------------------------------------------------
755 // Move window to selected layer
756 // ----------------------------------------------------------------------------------------------
758 #define WIN_LAYER_ONBOTTOM 2
759 #define WIN_LAYER_NORMAL 4
760 #define WIN_LAYER_ONTOP 10
762 void wsSetLayer( Display * wsDisplay, Window win, int layer )
763 { vo_x11_setlayer( wsDisplay,win,layer ); }
765 // ----------------------------------------------------------------------------------------------
766 // Switch to fullscreen.
767 // ----------------------------------------------------------------------------------------------
768 void wsFullScreen( wsTWindow * win )
770 int decoration = 0;
772 if ( win->isFullScreen )
774 vo_x11_ewmh_fullscreen( _NET_WM_STATE_REMOVE ); // removes fullscreen state if wm supports EWMH
775 if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // shouldn't be needed with EWMH fs
777 win->X=win->OldX;
778 win->Y=win->OldY;
779 win->Width=win->OldWidth;
780 win->Height=win->OldHeight;
781 decoration=win->Decorations;
784 #ifdef ENABLE_DPMS
785 wsScreenSaverOn( wsDisplay );
786 #endif
788 win->isFullScreen=False;
790 else
792 if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // shouldn't be needed with EWMH fs
794 win->OldX=win->X; win->OldY=win->Y;
795 win->OldWidth=win->Width; win->OldHeight=win->Height;
796 vo_dx = win->X; vo_dy = win->Y;
797 vo_dwidth = win->Width; vo_dheight = win->Height;
798 vo_screenwidth = wsMaxX; vo_screenheight = wsMaxY;
799 xinerama_x = wsOrgX; xinerama_y = wsOrgY;
800 update_xinerama_info();
801 wsMaxX = vo_screenwidth; wsMaxY = vo_screenheight;
802 wsOrgX = xinerama_x; wsOrgY = xinerama_y;
803 win->X=wsOrgX; win->Y=wsOrgY;
804 win->Width=wsMaxX; win->Height=wsMaxY;
807 win->isFullScreen=True;
808 #ifdef ENABLE_DPMS
809 wsScreenSaverOff( wsDisplay );
810 #endif
812 vo_x11_ewmh_fullscreen( _NET_WM_STATE_ADD ); // adds fullscreen state if wm supports EWMH
815 if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // shouldn't be needed with EWMH fs
817 vo_x11_decoration( wsDisplay,win->WindowID,decoration );
818 vo_x11_sizehint( win->X,win->Y,win->Width,win->Height,0 );
819 vo_x11_setlayer( wsDisplay,win->WindowID,win->isFullScreen );
821 if ((!(win->isFullScreen)) & vo_ontop) vo_x11_setlayer(wsDisplay, win->WindowID,1);
823 XMoveResizeWindow( wsDisplay,win->WindowID,win->X,win->Y,win->Width,win->Height );
826 if ( vo_wm_type == 0 && !(vo_fsmode&16) )
828 XWithdrawWindow( wsDisplay,win->WindowID,wsScreen );
832 XMapRaised( wsDisplay,win->WindowID );
833 XRaiseWindow( wsDisplay,win->WindowID );
834 XFlush( wsDisplay );
837 // ----------------------------------------------------------------------------------------------
838 // Redraw screen.
839 // ----------------------------------------------------------------------------------------------
840 void wsPostRedisplay( wsTWindow * win )
842 if ( win->ReDraw )
844 win->State=wsWindowExpose;
845 win->ReDraw();
846 XFlush( wsDisplay );
850 // ----------------------------------------------------------------------------------------------
851 // Do Exit.
852 // ----------------------------------------------------------------------------------------------
853 void wsDoExit( void )
854 { wsTrue=False; wsResizeWindow( wsWindowList[0],32,32 ); }
856 // ----------------------------------------------------------------------------------------------
857 // Put 'Image' to window.
858 // ----------------------------------------------------------------------------------------------
859 void wsConvert( wsTWindow * win,unsigned char * Image,unsigned int Size )
861 int i;
862 if ( wsConvFunc )
863 wsConvFunc( Image,win->ImageData,win->xImage->width * win->xImage->height * 4 );
864 if (!wsNonNativeOrder) return;
865 switch (win->xImage->bits_per_pixel) {
866 case 32:
868 uint32_t *d = win->ImageData;
869 for (i = 0; i < win->xImage->width * win->xImage->height; i++)
870 d[i] = bswap_32(d[i]);
871 break;
873 case 16:
874 case 15:
876 uint16_t *d = win->ImageData;
877 for (i = 0; i < win->xImage->width * win->xImage->height; i++)
878 d[i] = bswap_16(d[i]);
879 break;
884 void wsPutImage( wsTWindow * win )
886 if ( wsUseXShm )
888 XShmPutImage( wsDisplay,win->WindowID,win->wGC,win->xImage,
889 0,0,
890 ( win->Width - win->xImage->width ) / 2,( win->Height - win->xImage->height ) / 2,
891 win->xImage->width,win->xImage->height,0 );
893 else
895 XPutImage( wsDisplay,win->WindowID,win->wGC,win->xImage,
896 0,0,
897 ( win->Width - win->xImage->width ) / 2,( win->Height - win->xImage->height ) / 2,
898 win->xImage->width,win->xImage->height );
902 // ----------------------------------------------------------------------------------------------
903 // Move window to x, y.
904 // ----------------------------------------------------------------------------------------------
905 void wsMoveWindow( wsTWindow * win,int b,int x, int y )
907 if ( b )
909 switch ( x )
911 case -1: win->X=( wsMaxX / 2 ) - ( win->Width / 2 ) + wsOrgX; break;
912 case -2: win->X=wsMaxX - win->Width + wsOrgX; break;
913 default: win->X=x; break;
915 switch ( y )
917 case -1: win->Y=( wsMaxY / 2 ) - ( win->Height / 2 ) + wsOrgY; break;
918 case -2: win->Y=wsMaxY - win->Height + wsOrgY; break;
919 default: win->Y=y; break;
922 else { win->X=x; win->Y=y; }
924 win->SizeHint.flags=PPosition | PWinGravity;
925 win->SizeHint.x=win->X;
926 win->SizeHint.y=win->Y;
927 win->SizeHint.win_gravity=StaticGravity;
928 XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint );
930 XMoveWindow( wsDisplay,win->WindowID,win->X,win->Y );
931 if ( win->ReSize ) win->ReSize( win->X,win->Y,win->Width,win->Height );
934 // ----------------------------------------------------------------------------------------------
935 // Resize window to sx, sy.
936 // ----------------------------------------------------------------------------------------------
937 void wsResizeWindow( wsTWindow * win,int sx, int sy )
939 win->Width=sx;
940 win->Height=sy;
942 win->SizeHint.flags=PPosition | PSize | PWinGravity;// | PBaseSize;
943 win->SizeHint.x=win->X;
944 win->SizeHint.y=win->Y;
945 win->SizeHint.width=win->Width;
946 win->SizeHint.height=win->Height;
948 if ( win->Property & wsMinSize )
950 win->SizeHint.flags|=PMinSize;
951 win->SizeHint.min_width=win->Width;
952 win->SizeHint.min_height=win->Height;
954 if ( win->Property & wsMaxSize )
956 win->SizeHint.flags|=PMaxSize;
957 win->SizeHint.max_width=win->Width;
958 win->SizeHint.max_height=win->Height;
961 win->SizeHint.win_gravity=StaticGravity;
962 win->SizeHint.base_width=sx; win->SizeHint.base_height=sy;
964 if ( vo_wm_type == 0 ) XUnmapWindow( wsDisplay,win->WindowID );
966 XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint );
967 XResizeWindow( wsDisplay,win->WindowID,sx,sy );
968 XMapRaised( wsDisplay,win->WindowID );
969 if ( win->ReSize ) win->ReSize( win->X,win->Y,win->Width,win->Height );
972 // ----------------------------------------------------------------------------------------------
973 // Iconify window.
974 // ----------------------------------------------------------------------------------------------
975 void wsIconify( wsTWindow win )
976 { XIconifyWindow( wsDisplay,win.WindowID,0 ); }
978 // ----------------------------------------------------------------------------------------------
979 // Move top the window.
980 // ----------------------------------------------------------------------------------------------
981 void wsMoveTopWindow( Display * wsDisplay,Window win )
983 // XUnmapWindow( wsDisplay,win );
984 // XMapWindow( wsDisplay,win );
985 XMapRaised( wsDisplay,win );
986 XRaiseWindow( wsDisplay,win );
989 // ----------------------------------------------------------------------------------------------
990 // Set window background to 'color'.
991 // ----------------------------------------------------------------------------------------------
992 void wsSetBackground( wsTWindow * win,int color )
993 { XSetWindowBackground( wsDisplay,win->WindowID,color ); }
995 void wsSetBackgroundRGB( wsTWindow * win,int r,int g,int b )
997 int color = 0;
998 switch ( wsOutMask )
1000 case wsRGB32:
1001 case wsRGB24: color=( r << 16 ) + ( g << 8 ) + b; break;
1002 case wsBGR32:
1003 case wsBGR24: color=( b << 16 ) + ( g << 8 ) + r; break;
1004 case wsRGB16: PACK_RGB16( b,g,r,color ); break;
1005 case wsBGR16: PACK_RGB16( r,g,b,color ); break;
1006 case wsRGB15: PACK_RGB15( b,g,r,color ); break;
1007 case wsBGR15: PACK_RGB15( r,g,b,color ); break;
1009 XSetWindowBackground( wsDisplay,win->WindowID,color );
1012 void wsSetForegroundRGB( wsTWindow * win,int r,int g,int b )
1014 int color = 0;
1015 switch ( wsOutMask )
1017 case wsRGB32:
1018 case wsRGB24: color=( r << 16 ) + ( g << 8 ) + b; break;
1019 case wsBGR32:
1020 case wsBGR24: color=( b << 16 ) + ( g << 8 ) + r; break;
1021 case wsRGB16: PACK_RGB16( b,g,r,color ); break;
1022 case wsBGR16: PACK_RGB16( r,g,b,color ); break;
1023 case wsRGB15: PACK_RGB15( b,g,r,color ); break;
1024 case wsBGR15: PACK_RGB15( r,g,b,color ); break;
1026 XSetForeground( wsDisplay,win->wGC,color );
1029 // ----------------------------------------------------------------------------------------------
1030 // Draw string at x,y with fc ( foreground color ) and bc ( background color ).
1031 // ----------------------------------------------------------------------------------------------
1032 void wsDrawString( wsTWindow win,int x,int y,char * str,int fc,int bc )
1034 XSetForeground( wsDisplay,win.wGC,bc );
1035 XFillRectangle( wsDisplay,win.WindowID,win.wGC,x,y,
1036 XTextWidth( win.Font,str,strlen( str ) ) + 20,
1037 win.FontHeight + 2 );
1038 XSetForeground( wsDisplay,win.wGC,fc );
1039 XDrawString( wsDisplay,win.WindowID,win.wGC,x + 10,y + 13,str,strlen( str ) );
1042 // ----------------------------------------------------------------------------------------------
1043 // Calculation string width.
1044 // ----------------------------------------------------------------------------------------------
1045 int wsTextWidth( wsTWindow win,char * str )
1046 { return XTextWidth( win.Font,str,strlen( str ) ) + 20; }
1048 // ----------------------------------------------------------------------------------------------
1049 // Show / hide mouse cursor.
1050 // ----------------------------------------------------------------------------------------------
1051 void wsVisibleMouse( wsTWindow * win,int m )
1053 switch ( m )
1055 case wsShowMouseCursor:
1056 if ( win->wsCursor != None )
1058 XFreeCursor( wsDisplay,win->wsCursor );
1059 win->wsCursor=None;
1061 XDefineCursor( wsDisplay,win->WindowID,0 );
1062 break;
1063 case wsHideMouseCursor:
1064 win->wsCursor=XCreatePixmapCursor( wsDisplay,win->wsCursorPixmap,win->wsCursorPixmap,&win->wsColor,&win->wsColor,0,0 );
1065 XDefineCursor( wsDisplay,win->WindowID,win->wsCursor );
1066 break;
1068 XFlush( wsDisplay );
1071 int wsGetDepthOnScreen( void )
1073 int depth;
1074 XImage * mXImage;
1075 Visual * visual;
1077 if( (depth = vo_find_depth_from_visuals( wsDisplay,wsScreen,&visual )) > 0 )
1079 mXImage = XCreateImage( wsDisplay,visual,depth,ZPixmap,0,NULL,
1080 1,1,32,0 );
1081 wsDepthOnScreen = mXImage->bits_per_pixel;
1082 wsRedMask=mXImage->red_mask;
1083 wsGreenMask=mXImage->green_mask;
1084 wsBlueMask=mXImage->blue_mask;
1085 #ifdef WORDS_BIGENDIAN
1086 wsNonNativeOrder = mXImage->byte_order == LSBFirst;
1087 #else
1088 wsNonNativeOrder = mXImage->byte_order == MSBFirst;
1089 #endif
1090 XDestroyImage( mXImage );
1092 else
1094 int bpp,ibpp;
1095 XWindowAttributes attribs;
1097 mXImage=XGetImage( wsDisplay,wsRootWin,0,0,1,1,AllPlanes,ZPixmap );
1098 bpp=mXImage->bits_per_pixel;
1100 XGetWindowAttributes( wsDisplay,wsRootWin,&attribs );
1101 ibpp=attribs.depth;
1102 mXImage=XGetImage( wsDisplay,wsRootWin,0,0,1,1,AllPlanes,ZPixmap );
1103 bpp=mXImage->bits_per_pixel;
1104 if ( ( ibpp + 7 ) / 8 != ( bpp + 7 ) / 8 ) ibpp=bpp;
1105 wsDepthOnScreen=ibpp;
1106 wsRedMask=mXImage->red_mask;
1107 wsGreenMask=mXImage->green_mask;
1108 wsBlueMask=mXImage->blue_mask;
1109 XDestroyImage( mXImage );
1111 return wsDepthOnScreen;
1114 void wsXDone( void )
1116 XCloseDisplay( wsDisplay );
1119 void wsVisibleWindow( wsTWindow * win,int show )
1121 switch( show )
1123 case wsShowWindow: XMapRaised( wsDisplay,win->WindowID ); break;
1124 case wsHideWindow: XUnmapWindow( wsDisplay,win->WindowID ); break;
1126 XFlush( wsDisplay );
1129 void wsDestroyImage( wsTWindow * win )
1131 if ( win->xImage )
1133 XDestroyImage( win->xImage );
1134 if ( wsUseXShm )
1136 XShmDetach( wsDisplay,&win->Shminfo );
1137 shmdt( win->Shminfo.shmaddr );
1140 win->xImage=NULL;
1143 void wsCreateImage( wsTWindow * win,int Width,int Height )
1145 int CompletionType = -1;
1146 if ( wsUseXShm )
1148 CompletionType=XShmGetEventBase( wsDisplay ) + ShmCompletion;
1149 win->xImage=XShmCreateImage( wsDisplay,win->VisualInfo.visual,
1150 win->VisualInfo.depth,ZPixmap,NULL,&win->Shminfo,Width,Height );
1151 if ( win->xImage == NULL )
1153 mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError );
1154 exit( 0 );
1156 win->Shminfo.shmid=shmget( IPC_PRIVATE,win->xImage->bytes_per_line * win->xImage->height,IPC_CREAT|0777 );
1157 if ( win->Shminfo.shmid < 0 )
1159 XDestroyImage( win->xImage );
1160 mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError );
1161 exit( 0 );
1163 win->Shminfo.shmaddr=(char *)shmat( win->Shminfo.shmid,0,0 );
1165 if ( win->Shminfo.shmaddr == ((char *) -1) )
1167 XDestroyImage( win->xImage );
1168 if ( win->Shminfo.shmaddr != ((char *) -1) ) shmdt( win->Shminfo.shmaddr );
1169 mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_ShmError );
1170 exit( 0 );
1172 win->xImage->data=win->Shminfo.shmaddr;
1173 win->Shminfo.readOnly=0;
1174 XShmAttach( wsDisplay,&win->Shminfo );
1175 shmctl( win->Shminfo.shmid,IPC_RMID,0 );
1177 else
1179 win->xImage=XCreateImage( wsDisplay,win->VisualInfo.visual,win->VisualInfo.depth,
1180 ZPixmap,0,0,Width,Height,
1181 (wsDepthOnScreen == 3) ? 32 : wsDepthOnScreen,
1182 0 );
1183 if ( ( win->xImage->data=malloc( win->xImage->bytes_per_line * win->xImage->height ) ) == NULL )
1185 mp_msg( MSGT_GPLAYER,MSGL_FATAL,MSGTR_WS_NotEnoughMemoryDrawBuffer );
1186 exit( 0 );
1189 win->ImageData=(unsigned char *)win->xImage->data;
1190 win->ImageDataw=(unsigned short int *)win->xImage->data;
1191 win->ImageDatadw=(unsigned int *)win->xImage->data;
1194 void wsResizeImage( wsTWindow * win,int Width,int Height )
1195 { wsDestroyImage( win ); wsCreateImage( win,Width,Height ); }
1197 int wsGetOutMask( void )
1199 if ( ( wsDepthOnScreen == 32 )&&( wsRedMask == 0xff0000 )&&( wsGreenMask == 0x00ff00 )&&( wsBlueMask == 0x0000ff ) ) return wsRGB32;
1200 if ( ( wsDepthOnScreen == 32 )&&( wsRedMask == 0x0000ff )&&( wsGreenMask == 0x00ff00 )&&( wsBlueMask == 0xff0000 ) ) return wsBGR32;
1201 if ( ( wsDepthOnScreen == 24 )&&( wsRedMask == 0xff0000 )&&( wsGreenMask == 0x00ff00 )&&( wsBlueMask == 0x0000ff ) ) return wsRGB24;
1202 if ( ( wsDepthOnScreen == 24 )&&( wsRedMask == 0x0000ff )&&( wsGreenMask == 0x00ff00 )&&( wsBlueMask == 0xff0000 ) ) return wsBGR24;
1203 if ( ( wsDepthOnScreen == 16 )&&( wsRedMask == 0xf800 )&&( wsGreenMask == 0x7e0 )&&( wsBlueMask == 0x1f ) ) return wsRGB16;
1204 if ( ( wsDepthOnScreen == 16 )&&( wsRedMask == 0x1f )&&( wsGreenMask == 0x7e0 )&&( wsBlueMask == 0xf800 ) ) return wsBGR16;
1205 if ( ( wsDepthOnScreen == 15 )&&( wsRedMask == 0x7c00 )&&( wsGreenMask == 0x3e0 )&&( wsBlueMask == 0x1f ) ) return wsRGB15;
1206 if ( ( wsDepthOnScreen == 15 )&&( wsRedMask == 0x1f )&&( wsGreenMask == 0x3e0 )&&( wsBlueMask == 0x7c00 ) ) return wsBGR15;
1207 return 0;
1210 void wsSetTitle( wsTWindow * win,char * name )
1211 { XStoreName( wsDisplay,win->WindowID,name ); }
1213 void wsSetMousePosition( wsTWindow * win,int x, int y )
1214 { XWarpPointer( wsDisplay,wsRootWin,win->WindowID,0,0,0,0,x,y ); }
1216 #ifdef ENABLE_DPMS
1217 static int dpms_disabled=0;
1218 static int timeout_save=0;
1220 void wsScreenSaverOn( Display *mDisplay )
1222 int nothing;
1223 #ifdef CONFIG_XDPMS
1224 if ( dpms_disabled )
1226 if ( DPMSQueryExtension( mDisplay,&nothing,&nothing ) )
1228 if ( !DPMSEnable( mDisplay ) ) mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_WS_DpmsUnavailable ); // restoring power saving settings
1229 else
1231 // DPMS does not seem to be enabled unless we call DPMSInfo
1232 BOOL onoff;
1233 CARD16 state;
1234 DPMSInfo( mDisplay,&state,&onoff );
1235 if ( onoff ) mp_msg( MSGT_GPLAYER,MSGL_V,"Successfully enabled DPMS.\n" );
1236 else mp_msg( MSGT_GPLAYER,MSGL_STATUS,MSGTR_WS_DpmsNotEnabled );
1240 #endif
1241 if ( timeout_save )
1243 int dummy, interval, prefer_blank, allow_exp;
1244 XGetScreenSaver( mDisplay,&dummy,&interval,&prefer_blank,&allow_exp );
1245 XSetScreenSaver( mDisplay,timeout_save,interval,prefer_blank,allow_exp );
1246 XGetScreenSaver( mDisplay,&timeout_save,&interval,&prefer_blank,&allow_exp );
1250 void wsScreenSaverOff( Display * mDisplay )
1252 int interval,prefer_blank,allow_exp,nothing;
1253 #ifdef CONFIG_XDPMS
1254 if ( DPMSQueryExtension( mDisplay,&nothing,&nothing ) )
1256 BOOL onoff;
1257 CARD16 state;
1258 DPMSInfo( mDisplay,&state,&onoff );
1259 if ( onoff )
1261 Status stat;
1262 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"Disabling DPMS.\n" );
1263 dpms_disabled=1;
1264 stat=DPMSDisable( mDisplay ); // monitor powersave off
1265 mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"stat: %d.\n",stat );
1268 #endif
1269 XGetScreenSaver( mDisplay,&timeout_save,&interval,&prefer_blank,&allow_exp );
1270 if ( timeout_save ) XSetScreenSaver( mDisplay,0,interval,prefer_blank,allow_exp ); // turning off screensaver
1272 #endif
1274 void wsSetShape( wsTWindow * win,char * data )
1276 #ifdef CONFIG_XSHAPE
1277 if ( !wsUseXShape ) return;
1278 if ( data )
1280 win->Mask=XCreateBitmapFromData( wsDisplay,win->WindowID,data,win->Width,win->Height );
1281 XShapeCombineMask( wsDisplay,win->WindowID,ShapeBounding,0,0,win->Mask,ShapeSet );
1282 XFreePixmap( wsDisplay,win->Mask );
1284 else XShapeCombineMask( wsDisplay,win->WindowID,ShapeBounding,0,0,None,ShapeSet );
1285 #endif
1288 void wsSetIcon( Display * dsp,Window win,Pixmap icon,Pixmap mask )
1290 XWMHints * wm;
1291 long data[2];
1292 Atom iconatom;
1294 wm=XGetWMHints( dsp,win );
1295 if ( !wm ) wm=XAllocWMHints();
1297 wm->icon_pixmap=icon;
1298 wm->icon_mask=mask;
1299 wm->flags|=IconPixmapHint | IconMaskHint;
1301 XSetWMHints( dsp,win,wm );
1303 data[0]=icon;
1304 data[1]=mask;
1305 iconatom=XInternAtom( dsp,"KWM_WIN_ICON",0 );
1306 XChangeProperty( dsp,win,iconatom,iconatom,32,PropModeReplace,(unsigned char *)data,2 );
1308 XFree( wm );
1311 #include "wsmkeys.h"