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.
23 #include <X11/Xproto.h>
24 #include <X11/Xutil.h>
25 #include <X11/keysym.h>
26 #include <X11/Xatom.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"
50 #include <X11/extensions/XShm.h>
52 #include <X11/extensions/shape.h>
55 #ifdef CONFIG_XINERAMA
56 #include <X11/extensions/Xinerama.h>
60 #include <X11/extensions/xf86vmode.h>
71 unsigned long functions
;
72 unsigned long decorations
;
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.
90 MotifWmHints wsMotifWmHints
;
91 Atom wsTextProperlyAtom
= None
;
94 int wsDepthOnScreen
= 0;
99 int wsNonNativeOrder
= 0;
104 wsTWindow
* wsWindowList
[wsWLCount
] = { NULL
,NULL
,NULL
,NULL
,NULL
};
106 unsigned long wsKeyTable
[512];
111 inline int wsSearch( Window win
);
115 #define PACK_RGB16(r,g,b,pixel) pixel=(b>>3);\
121 #define PACK_RGB15(r,g,b,pixel) pixel=(b>>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
); }
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
;
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" );
189 int wsErrorHandler( Display
* dpy
,XErrorEvent
* Event
)
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)" );
201 void wsXInit( void* mDisplay
)
209 char * DisplayName
= ":0.0";
210 if ( getenv( "DISPLAY" ) ) DisplayName
=getenv( "DISPLAY" );
211 wsDisplay
=XOpenDisplay( DisplayName
);
214 mp_msg( MSGT_GPLAYER
,MSGL_FATAL
,MSGTR_WS_CouldNotOpenDisplay
);
219 /* enable DND atoms */
222 { /* on remote display XShm will be disabled - LGB */
223 char *dispname
=DisplayString(wsDisplay
);
225 if (dispname
&&*dispname
!=':') {
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
);
239 if ( !XShapeQueryExtension( wsDisplay
,&eventbase
,&errorbase
) )
241 mp_msg( MSGT_GPLAYER
,MSGL_ERR
,MSGTR_WS_NoXshape
);
248 XSynchronize( wsDisplay
,True
);
250 wsScreen
=DefaultScreen( wsDisplay
);
251 wsRootWin
=RootWindow( wsDisplay
,wsScreen
);
255 XF86VidModeModeLine modeline
;
257 XF86VidModeGetModeLine( wsDisplay
,wsScreen
,&clock
,&modeline
);
258 wsMaxX
=modeline
.hdisplay
;
259 wsMaxY
=modeline
.vdisplay
;
265 wsMaxX
=DisplayWidth( wsDisplay
,wsScreen
);
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();
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
);
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
);
289 XShmQueryVersion( wsDisplay
,&major
,&minor
,&shp
);
290 mp_msg( MSGT_GPLAYER
,MSGL_DBG2
,"[ws] XShm version is %d.%d\n",major
,minor
);
295 XShapeQueryVersion( wsDisplay
,&major
,&minor
);
296 mp_msg( MSGT_GPLAYER
,MSGL_DBG2
,"[ws] XShape version is %d.%d\n",major
,minor
);
301 wsOutMask
=wsGetOutMask();
302 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"[ws] Initialized converter: " );
303 sws_rgb2rgb_init(get_sws_cpuflags());
307 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"rgb32 to rgb32\n" );
308 wsConvFunc
=rgb32torgb32
;
311 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"rgb32 to bgr32\n" );
312 wsConvFunc
=rgb32tobgr32
;
315 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"rgb32 to rgb24\n" );
316 wsConvFunc
=rgb32to24
;
319 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"rgb32 to bgr24\n" );
320 wsConvFunc
=rgb32tobgr24
;
323 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"rgb32 to rgb16\n" );
324 wsConvFunc
=rgb32to16
;
327 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"rgb32 to bgr16\n" );
328 wsConvFunc
=rgb32tobgr16
;
331 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"rgb32 to rgb15\n" );
332 wsConvFunc
=rgb32to15
;
335 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"rgb32 to bgr15\n" );
336 wsConvFunc
=rgb32tobgr15
;
339 XSetErrorHandler( wsErrorHandler
);
342 // ----------------------------------------------------------------------------------------------
344 // X,Y : window position
345 // wX,wY : size of window
347 // cV : visible mouse cursor on window
348 // D : visible frame, title, etc.
350 // ----------------------------------------------------------------------------------------------
352 XClassHint wsClassHint
;
353 XTextProperty wsTextProperty
;
356 void wsCreateWindow( wsTWindow
* win
,int X
,int Y
,int wX
,int hY
,int bW
,int cV
,unsigned char D
,char * label
)
361 if ( D
& wsShowFrame
) win
->Decorations
=1;
362 wsHGC
=DefaultGC( wsDisplay
,wsScreen
);
363 // The window position and size.
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;
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;
380 win
->OldWidth
=win
->Width
;
381 win
->OldHeight
=win
->Height
;
383 // Border size for window.
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
);
395 mp_msg( MSGT_GPLAYER
,MSGL_FATAL
,MSGTR_WS_ColorDepthTooLow
);
398 XMatchVisualInfo( wsDisplay
,wsScreen
,depth
,TrueColor
,&win
->VisualInfo
);
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
;
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
|
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
,
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
;
452 win
->SizeHint
.flags
|=PMinSize
;
453 win
->SizeHint
.min_width
=win
->Width
;
454 win
->SizeHint
.min_height
=win
->Height
;
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
,
499 if ( D
& wsShowWindow
) XMapWindow( wsDisplay
,win
->WindowID
);
501 wsCreateImage( win
,win
->Width
,win
->Height
);
502 // --- End of creating --------------------------------------------------------------------------
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 ); }
514 XSync( wsDisplay
,False
);
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
)
527 l
=wsSearch( win
->WindowID
);
528 wsWindowList
[l
]=NULL
;
529 if ( win
->wsCursor
!= None
)
531 XFreeCursor( wsDisplay
,win
->wsCursor
);
534 XFreeGC( wsDisplay
,win
->wGC
);
535 XUnmapWindow( wsDisplay
,win
->WindowID
);
536 wsDestroyImage( win
);
537 XDestroyWindow( wsDisplay
,win
->WindowID
);
542 win
->MouseHandler
=NULL
;
543 win
->KeyHandler
=NULL
;
551 // ----------------------------------------------------------------------------------------------
553 // ----------------------------------------------------------------------------------------------
555 inline int wsSearch( Window win
)
558 for ( i
=0;i
<wsWLCount
;i
++ ) if ( wsWindowList
[i
] && wsWindowList
[i
]->WindowID
== win
) return i
;
562 Bool
wsEvents( Display
* display
,XEvent
* Event
,XPointer arg
)
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
)
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" ); }
584 /* try to process DND events */
585 wsXDNDProcessClientMessage(wsWindowList
[l
],&Event
->xclient
);
589 case MapNotify
: i
=wsWindowMapped
; wsWindowList
[l
]->Mapped
=wsMapped
; goto expose
;
590 case UnmapNotify
: i
=wsWindowUnmapped
; wsWindowList
[l
]->Mapped
=wsNone
; goto expose
;
592 if ( wsWindowList
[l
]->Focused
== wsFocused
) break;
594 wsWindowList
[l
]->Focused
=wsFocused
;
597 if ( wsWindowList
[l
]->Focused
== wsNone
) break;
599 wsWindowList
[l
]->Focused
=wsNone
;
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
;
609 wsWindowList
[l
]->State
=i
;
610 if ( wsWindowList
[l
]->ReDraw
) wsWindowList
[l
]->ReDraw();
614 wsWindowList
[l
]->State
=wsWindowExpose
;
615 if ( ( wsWindowList
[l
]->ReDraw
)&&( !Event
->xexpose
.count
) ) wsWindowList
[l
]->ReDraw();
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
; }
633 case KeyPress
: i
=wsKeyPressed
; goto keypressed
;
634 case KeyRelease
: i
=wsKeyReleased
;
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;
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
);
663 static XComposeStatus stat
;
665 XLookupString( &Event
->xkey
,buf
,sizeof(buf
),&keySym
,&stat
);
666 key
=( (keySym
&0xff00) != 0?( (keySym
&0x00ff) + 256 ):( keySym
) );
668 if ( wsWindowList
[l
]->KeyHandler
) wsWindowList
[l
]->KeyHandler( Event
->xkey
.keycode
,i
,key
);
676 /* pump all motion events from the display queue:
677 this way it works faster when moving the window */
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? */
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
;
695 if ( wsWindowList
[l
]->MouseHandler
)
696 wsWindowList
[l
]->MouseHandler( i
,Event
->xbutton
.x
,Event
->xbutton
.y
,Event
->xmotion
.x_root
,Event
->xmotion
.y_root
);
699 case SelectionNotify
:
701 wsXDNDProcessSelection(wsWindowList
[l
],Event
);
705 XSync( wsDisplay
,False
);
709 Bool
wsDummyEvents( Display
* display
,XEvent
* Event
,XPointer arg
)
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 )
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 );
732 // handle pending events
733 while ( XPending(wsDisplay
) ){
734 XNextEvent( wsDisplay
,&wsEvent
);
735 wsEvents( wsDisplay
,&wsEvent
,NULL
);
738 usleep(delay
*1000); // FIXME!
739 if(delay
<10*20) delay
+=20; // pump up delay up to 0.2 sec (low activity)
746 XIfEvent( wsDisplay
,&wsEvent
,wsDummyEvents
,NULL
);
747 wsEvents( wsDisplay
,&wsEvent
,NULL
);
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
)
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
779 win
->Width
=win
->OldWidth
;
780 win
->Height
=win
->OldHeight
;
781 decoration
=win
->Decorations
;
785 wsScreenSaverOn( wsDisplay
);
788 win
->isFullScreen
=False
;
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
;
809 wsScreenSaverOff( wsDisplay
);
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
);
837 // ----------------------------------------------------------------------------------------------
839 // ----------------------------------------------------------------------------------------------
840 void wsPostRedisplay( wsTWindow
* win
)
844 win
->State
=wsWindowExpose
;
850 // ----------------------------------------------------------------------------------------------
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
)
863 wsConvFunc( Image
,win
->ImageData
,win
->xImage
->width
* win
->xImage
->height
* 4 );
864 if (!wsNonNativeOrder
) return;
865 switch (win
->xImage
->bits_per_pixel
) {
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
]);
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
]);
884 void wsPutImage( wsTWindow
* win
)
888 XShmPutImage( wsDisplay
,win
->WindowID
,win
->wGC
,win
->xImage
,
890 ( win
->Width
- win
->xImage
->width
) / 2,( win
->Height
- win
->xImage
->height
) / 2,
891 win
->xImage
->width
,win
->xImage
->height
,0 );
895 XPutImage( wsDisplay
,win
->WindowID
,win
->wGC
,win
->xImage
,
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
)
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;
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
)
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 // ----------------------------------------------------------------------------------------------
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
)
1001 case wsRGB24
: color
=( r
<< 16 ) + ( g
<< 8 ) + b
; break;
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
)
1015 switch ( wsOutMask
)
1018 case wsRGB24
: color
=( r
<< 16 ) + ( g
<< 8 ) + b
; break;
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
)
1055 case wsShowMouseCursor
:
1056 if ( win
->wsCursor
!= None
)
1058 XFreeCursor( wsDisplay
,win
->wsCursor
);
1061 XDefineCursor( wsDisplay
,win
->WindowID
,0 );
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
);
1068 XFlush( wsDisplay
);
1071 int wsGetDepthOnScreen( void )
1077 if( (depth
= vo_find_depth_from_visuals( wsDisplay
,wsScreen
,&visual
)) > 0 )
1079 mXImage
= XCreateImage( wsDisplay
,visual
,depth
,ZPixmap
,0,NULL
,
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
;
1088 wsNonNativeOrder
= mXImage
->byte_order
== MSBFirst
;
1090 XDestroyImage( mXImage
);
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
);
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
)
1123 case wsShowWindow
: XMapRaised( wsDisplay
,win
->WindowID
); break;
1124 case wsHideWindow
: XUnmapWindow( wsDisplay
,win
->WindowID
); break;
1126 XFlush( wsDisplay
);
1129 void wsDestroyImage( wsTWindow
* win
)
1133 XDestroyImage( win
->xImage
);
1136 XShmDetach( wsDisplay
,&win
->Shminfo
);
1137 shmdt( win
->Shminfo
.shmaddr
);
1143 void wsCreateImage( wsTWindow
* win
,int Width
,int Height
)
1145 int CompletionType
= -1;
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
);
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
);
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
);
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 );
1179 win
->xImage
=XCreateImage( wsDisplay
,win
->VisualInfo
.visual
,win
->VisualInfo
.depth
,
1180 ZPixmap
,0,0,Width
,Height
,
1181 (wsDepthOnScreen
== 3) ? 32 : wsDepthOnScreen
,
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
);
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
;
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
); }
1217 static int dpms_disabled
=0;
1218 static int timeout_save
=0;
1220 void wsScreenSaverOn( Display
*mDisplay
)
1224 if ( dpms_disabled
)
1226 if ( DPMSQueryExtension( mDisplay
,¬hing
,¬hing
) )
1228 if ( !DPMSEnable( mDisplay
) ) mp_msg( MSGT_GPLAYER
,MSGL_ERR
,MSGTR_WS_DpmsUnavailable
); // restoring power saving settings
1231 // DPMS does not seem to be enabled unless we call DPMSInfo
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
);
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
;
1254 if ( DPMSQueryExtension( mDisplay
,¬hing
,¬hing
) )
1258 DPMSInfo( mDisplay
,&state
,&onoff
);
1262 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"Disabling DPMS.\n" );
1264 stat
=DPMSDisable( mDisplay
); // monitor powersave off
1265 mp_dbg( MSGT_GPLAYER
,MSGL_DBG2
,"stat: %d.\n",stat
);
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
1274 void wsSetShape( wsTWindow
* win
,char * data
)
1276 #ifdef CONFIG_XSHAPE
1277 if ( !wsUseXShape
) return;
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
);
1288 void wsSetIcon( Display
* dsp
,Window win
,Pixmap icon
,Pixmap mask
)
1294 wm
=XGetWMHints( dsp
,win
);
1295 if ( !wm
) wm
=XAllocWMHints();
1297 wm
->icon_pixmap
=icon
;
1299 wm
->flags
|=IconPixmapHint
| IconMaskHint
;
1301 XSetWMHints( dsp
,win
,wm
);
1305 iconatom
=XInternAtom( dsp
,"KWM_WIN_ICON",0 );
1306 XChangeProperty( dsp
,win
,iconatom
,iconatom
,32,PropModeReplace
,(unsigned char *)data
,2 );
1311 #include "wsmkeys.h"