1693
|
1
|
|
2 // --------------------------------------------------------------------------
|
|
3 // AutoSpace Window System for Linux/Win32 v0.85
|
|
4 // Writed by pontscho/fresh!mindworkz
|
|
5 // --------------------------------------------------------------------------
|
|
6
|
|
7 #include <X11/Xlib.h>
|
|
8 #include <X11/Xproto.h>
|
|
9 #include <X11/Xutil.h>
|
|
10 #include <X11/keysym.h>
|
|
11 #include <X11/Xatom.h>
|
|
12 #include <errno.h>
|
|
13 #include <stdlib.h>
|
|
14 #include <stdio.h>
|
|
15
|
|
16 #include "ws.h"
|
|
17 #include "wsconv.h"
|
|
18 #include "../../config.h"
|
|
19
|
|
20 #include <X11/extensions/xf86dga.h>
|
|
21 #include <X11/extensions/xf86dgastr.h>
|
|
22 #include <X11/extensions/XShm.h>
|
|
23 #include <X11/extensions/shape.h>
|
|
24 #include <sys/ipc.h>
|
|
25 #include <sys/shm.h>
|
|
26
|
|
27 typedef struct
|
|
28 {
|
|
29 long flags;
|
|
30 long functions;
|
|
31 long decorations;
|
|
32 long input_mode;
|
|
33 long status;
|
|
34 } MotifWmHints;
|
|
35
|
|
36 Atom wsMotifHints;
|
|
37
|
|
38 unsigned int wsMaxX = 0; // Screen width.
|
|
39 unsigned int wsMaxY = 0; // Screen height.
|
|
40
|
|
41 Display * wsDisplay;
|
|
42 int wsScreen;
|
|
43 Window wsRootWin;
|
|
44 XEvent wsEvent;
|
|
45 int wsWindowDepth;
|
|
46 GC wsHGC;
|
|
47 MotifWmHints wsMotifWmHints;
|
|
48 Atom wsTextProperlyAtom = None;
|
|
49
|
|
50 int wsDepthOnScreen = 0;
|
|
51 int wsRedMask = 0;
|
|
52 int wsGreenMask = 0;
|
|
53 int wsBlueMask = 0;
|
|
54 int wsOutMask = 0;
|
|
55
|
|
56 int wsTrue = True;
|
|
57
|
|
58 wsTWindow * wsWindowList[5] = { NULL,NULL,NULL,NULL,NULL };
|
|
59 int wsWLCount = 0;
|
|
60
|
|
61 unsigned long wsKeyTable[512];
|
|
62
|
|
63 int wsUseXShm = 1;
|
|
64 int wsUseDGA = 1;
|
|
65 int wsUseXShape = 1;
|
|
66
|
|
67 int XShmGetEventBase( Display* );
|
|
68 inline int wsSearch( Window win );
|
|
69
|
|
70 #define MWM_HINTS_FUNCTIONS (1L << 0)
|
|
71 #define MWM_HINTS_DECORATIONS (1L << 1)
|
|
72 #define MWM_HINTS_INPUT_MODE (1L << 2)
|
|
73 #define MWM_HINTS_STATUS (1L << 3)
|
|
74
|
|
75 #define MWM_FUNC_ALL (1L << 0)
|
|
76 #define MWM_FUNC_RESIZE (1L << 1)
|
|
77 #define MWM_FUNC_MOVE (1L << 2)
|
|
78 #define MWM_FUNC_MINIMIZE (1L << 3)
|
|
79 #define MWM_FUNC_MAXIMIZE (1L << 4)
|
|
80 #define MWM_FUNC_CLOSE (1L << 5)
|
|
81
|
|
82 #define MWM_DECOR_ALL (1L << 0)
|
|
83 #define MWM_DECOR_BORDER (1L << 1)
|
|
84 #define MWM_DECOR_RESIZEH (1L << 2)
|
|
85 #define MWM_DECOR_TITLE (1L << 3)
|
|
86 #define MWM_DECOR_MENU (1L << 4)
|
|
87 #define MWM_DECOR_MINIMIZE (1L << 5)
|
|
88 #define MWM_DECOR_MAXIMIZE (1L << 6)
|
|
89
|
|
90 #define MWM_INPUT_MODELESS 0
|
|
91 #define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
|
|
92 #define MWM_INPUT_SYSTEM_MODAL 2
|
|
93 #define MWM_INPUT_FULL_APPLICATION_MODAL 3
|
|
94 #define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
|
|
95
|
|
96 #define MWM_TEAROFF_WINDOW (1L<<0)
|
|
97
|
|
98 void wsWindowDecoration( wsTWindow * win,long d )
|
|
99 {
|
|
100 wsMotifHints=XInternAtom( wsDisplay,"_MOTIF_WM_HINTS",0 );
|
|
101 if ( wsMotifHints != None )
|
|
102 {
|
|
103 memset( &wsMotifWmHints,0,sizeof( MotifWmHints ) );
|
|
104 wsMotifWmHints.flags=( d?0:MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS );
|
|
105 wsMotifWmHints.functions=( d?0:MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE );
|
|
106 wsMotifWmHints.decorations=( d?MWM_DECOR_ALL:0 );
|
|
107 XChangeProperty( wsDisplay,win->WindowID,wsMotifHints,wsMotifHints,32,
|
|
108 PropModeReplace,(unsigned char *)&wsMotifWmHints,5 );
|
|
109 }
|
|
110 }
|
|
111
|
|
112 // ----------------------------------------------------------------------------------------------
|
|
113 // Init X Window System.
|
|
114 // ----------------------------------------------------------------------------------------------
|
|
115
|
|
116 int wsIOErrorHandler( Display * dpy )
|
|
117 {
|
|
118 fprintf( stderr,"[ws] io error in display.\n" );
|
|
119 exit( 0 );
|
|
120 }
|
|
121
|
|
122 int wsErrorHandler( Display * dpy,XErrorEvent * Event )
|
|
123 {
|
|
124 char type[128];
|
|
125 XGetErrorText( wsDisplay,Event->error_code,type,128 );
|
|
126 fprintf(stderr,"[ws] Error in display.\n");
|
|
127 fprintf(stderr,"[ws] Error code: %d ( %s )\n",Event->error_code,type );
|
|
128 fprintf(stderr,"[ws] Request code: %d\n",Event->request_code );
|
|
129 fprintf(stderr,"[ws] Minor code: %d\n",Event->minor_code );
|
|
130 exit( 0 );
|
|
131 }
|
|
132
|
|
133 void wsXInit( void )
|
|
134 {
|
|
135 char * DisplayName = ":0.0";
|
|
136 int eventbase;
|
|
137 int errorbase;
|
|
138
|
|
139 if ( getenv( "DISPLAY" ) ) DisplayName=getenv( "DISPLAY" );
|
|
140 wsDisplay=XOpenDisplay( DisplayName );
|
|
141 if ( !wsDisplay )
|
|
142 {
|
|
143 fprintf( stderr,"[ws] couldn't open the display !\n" );
|
|
144 exit( 0 );
|
|
145 }
|
|
146
|
|
147 if ( !XShmQueryExtension( wsDisplay ) )
|
|
148 {
|
|
149 fprintf( stderr,"[ws] sorry, your system is not supported X shared memory extension.\n" );
|
|
150 wsUseXShm=0;
|
|
151 }
|
1699
|
152 #ifdef HAVE_DGA2
|
|
153 if ( !XDGAQueryExtension( wsDisplay,&eventbase,&errorbase ) )
|
1693
|
154 {
|
|
155 fprintf( stderr,"[ws] sorry, your system is not supported DGA extension.\n" );
|
|
156 wsUseDGA=0;
|
|
157 }
|
1699
|
158 #else
|
|
159 wsUseDGA=0;
|
|
160 #endif
|
|
161 #ifdef HAVE_XSHAPE
|
1693
|
162 if ( !XShapeQueryExtension( wsDisplay,&eventbase,&errorbase ) )
|
|
163 {
|
|
164 fprintf( stderr,"[ws] sorry, your system is not supported XShape extension.\n" );
|
|
165 wsUseXShape=0;
|
|
166 }
|
1699
|
167 #else
|
1693
|
168 wsUseXShape=0;
|
1699
|
169 #endif
|
1693
|
170
|
|
171 XSynchronize( wsDisplay,True );
|
|
172
|
|
173 wsScreen=DefaultScreen( wsDisplay );
|
|
174 wsRootWin=RootWindow( wsDisplay,wsScreen );
|
|
175 wsMaxX=DisplayWidth( wsDisplay,wsScreen );
|
|
176 wsMaxY=DisplayHeight( wsDisplay,wsScreen );
|
|
177
|
|
178 wsGetDepthOnScreen();
|
1699
|
179 #ifdef DEBUG
|
1693
|
180 {
|
|
181 int minor,major,shp;
|
|
182 fprintf( stderr,"[ws] Screen depth: %d\n",wsDepthOnScreen );
|
|
183 fprintf( stderr,"[ws] red mask: 0x%x\n",wsRedMask );
|
|
184 fprintf( stderr,"[ws] green mask: 0x%x\n",wsGreenMask );
|
|
185 fprintf( stderr,"[ws] blue mask: 0x%x\n",wsBlueMask );
|
|
186 if ( wsUseXShm )
|
|
187 {
|
|
188 XShmQueryVersion( wsDisplay,&major,&minor,&shp );
|
|
189 fprintf( stderr,"[ws] XShm version is %d.%d\n",major,minor );
|
|
190 }
|
1699
|
191 // if ( wsUseDGA )
|
|
192 // {
|
1693
|
193 // XDGAQueryVersion( wsDisplay,&major,&minor );
|
|
194 // fprintf( stderr,"[ws] DGA version is %d.%d\n",major,minor );
|
1699
|
195 // }
|
1693
|
196 #ifdef HAVE_XSHAPE
|
|
197 if ( wsUseXShape )
|
|
198 {
|
|
199 XShapeQueryVersion( wsDisplay,&major,&minor );
|
|
200 fprintf( stderr,"[ws] XShape version is %d.%d\n",major,minor );
|
|
201 }
|
|
202 #endif
|
|
203 }
|
1699
|
204 #endif
|
1693
|
205 initConverter();
|
|
206 wsOutMask=wsGetOutMask();
|
|
207 switch ( wsOutMask )
|
|
208 {
|
|
209 case wsRGB32:
|
|
210 wsConvFunc=BGR8880_to_RGB8880_c;
|
|
211 break;
|
|
212 case wsBGR32:
|
|
213 wsConvFunc=BGR8880_to_BGR8880_c;
|
|
214 break;
|
|
215 case wsRGB24:
|
|
216 #ifdef xHAVE_MMX
|
|
217 wsConvFunc=BGR8880_to_RGB888_mmx;
|
|
218 #else
|
|
219 wsConvFunc=BGR8880_to_RGB888_c;
|
|
220 #endif
|
|
221 break;
|
|
222 case wsBGR24:
|
|
223 wsConvFunc=BGR8880_to_BGR888_c;
|
|
224 break;
|
|
225 case wsRGB16:
|
|
226 wsConvFunc=BGR8880_to_RGB565_c;
|
|
227 break;
|
|
228 case wsBGR16:
|
|
229 wsConvFunc=BGR8880_to_BGR565_c;
|
|
230 break;
|
|
231 case wsRGB15:
|
|
232 wsConvFunc=BGR8880_to_RGB555_c;
|
|
233 break;
|
|
234 case wsBGR15:
|
|
235 wsConvFunc=BGR8880_to_BGR555_c;
|
|
236 break;
|
|
237 }
|
|
238 XSetIOErrorHandler( wsIOErrorHandler );
|
|
239 XSetErrorHandler( wsErrorHandler );
|
|
240 }
|
|
241
|
|
242 // ----------------------------------------------------------------------------------------------
|
|
243 // Create window.
|
|
244 // X,Y : window position
|
|
245 // wX,wY : size of window
|
|
246 // bW : border width
|
|
247 // cV : visible mouse cursor on window
|
|
248 // D : visible frame, title, etc.
|
|
249 // sR : screen ratio
|
|
250 // ----------------------------------------------------------------------------------------------
|
|
251
|
|
252 XClassHint wsClassHint;
|
|
253 XTextProperty wsTextProperty;
|
|
254 Window LeaderWindow;
|
|
255
|
|
256 void wsCreateWindow( wsTWindow * win,int X,int Y,int wX,int hY,int bW,int cV,unsigned char D,char * label )
|
|
257 {
|
|
258 win->Property=D;
|
|
259 if ( D & wsShowFrame ) win->Decorations=1;
|
|
260 wsHGC=DefaultGC( wsDisplay,wsScreen );
|
|
261 // The window position and size.
|
|
262 switch ( X )
|
|
263 {
|
|
264 case -1: win->X=( wsMaxX / 2 ) - ( wX / 2 ); break;
|
|
265 case -2: win->X=wsMaxX - wX - 1; break;
|
|
266 default: win->X=X; break;
|
|
267 }
|
|
268 switch ( Y )
|
|
269 {
|
|
270 case -1: win->Y=( wsMaxY / 2 ) - ( hY / 2 ); break;
|
|
271 case -2: win->Y=wsMaxY - hY - 1; break;
|
|
272 default: win->Y=Y; break;
|
|
273 }
|
|
274 win->Width=wX;
|
|
275 win->Height=hY;
|
|
276 win->OldX=win->X;
|
|
277 win->OldY=win->Y;
|
|
278 win->OldWidth=win->Width;
|
|
279 win->OldHeight=win->Height;
|
|
280
|
|
281 // Border size for window.
|
|
282 win->BorderWidth=bW;
|
|
283 // Hide Mouse Cursor
|
|
284 win->wsCursor=None;
|
|
285 win->wsMouseEventType=cV;
|
|
286 win->wsCursorData[0]=0;
|
|
287 win->wsCursorPixmap=XCreateBitmapFromData( wsDisplay,wsRootWin,win->wsCursorData,1,1 );
|
|
288 if ( !(cV & wsShowMouseCursor) ) win->wsCursor=XCreatePixmapCursor( wsDisplay,win->wsCursorPixmap,win->wsCursorPixmap,&win->wsColor,&win->wsColor,0,0 );
|
|
289
|
|
290 XGetWindowAttributes( wsDisplay,wsRootWin,&win->Attribs );
|
|
291 if ( win->Attribs.depth < 15 )
|
|
292 {
|
|
293 fprintf( stderr,"[ws] sorry, this color depth is not enough.\n" );
|
|
294 exit( 0 );
|
|
295 }
|
|
296 XMatchVisualInfo( wsDisplay,wsScreen,win->Attribs.depth,TrueColor,&win->VisualInfo );
|
|
297
|
|
298 // ---
|
|
299 win->AtomLeaderClient=XInternAtom( wsDisplay,"WM_CLIENT_LEADER",False );
|
|
300 win->AtomDeleteWindow=XInternAtom( wsDisplay,"WM_DELETE_WINDOW",False );
|
|
301 win->AtomTakeFocus=XInternAtom( wsDisplay,"WM_TAKE_FOCUS",False );
|
|
302 win->AtomRolle=XInternAtom( wsDisplay,"WM_WINDOW_ROLE",False );
|
|
303 win->AtomProtocols=XInternAtom( wsDisplay,"WM_PROTOCOLS",False );
|
|
304 {
|
|
305 char buf[32]; int i;
|
|
306 sprintf( buf,"_%s_REMOTE",label );
|
|
307 for( i=0;i<strlen( buf );i++ )
|
|
308 if ( ( buf[i] >= 'a' )&&( buf[i] <= 'z' ) ) buf[i]=buf[i] - 32;
|
|
309 for( i=0;i<strlen( buf );i++ )
|
|
310 if ( buf[i] == ' ' ) buf[i]='_';
|
|
311 fprintf( stderr,"[ws] atomname: %s\n",buf );
|
|
312 win->AtomRemote=XInternAtom( wsDisplay,buf,False );
|
|
313 }
|
|
314 win->AtomsProtocols[0]=win->AtomDeleteWindow;
|
|
315 win->AtomsProtocols[1]=win->AtomTakeFocus;
|
|
316 win->AtomsProtocols[2]=win->AtomRolle;
|
|
317 // ---
|
|
318
|
|
319 // win->WindowAttrib.background_pixel=BlackPixel( wsDisplay,wsScreen );
|
|
320 // win->WindowAttrib.border_pixel=BlackPixel( wsDisplay,wsScreen );
|
|
321 win->WindowAttrib.background_pixel=BlackPixel( wsDisplay,wsScreen );
|
|
322 win->WindowAttrib.border_pixel=WhitePixel( wsDisplay,wsScreen );
|
|
323 win->WindowAttrib.colormap=XCreateColormap( wsDisplay,wsRootWin,win->VisualInfo.visual,AllocNone );
|
|
324 win->WindowAttrib.event_mask=StructureNotifyMask | FocusChangeMask |
|
|
325 //SubstructureRedirectMask |
|
|
326 //SubstructureNotifyMask |
|
|
327 //ResizeRedirectMask |
|
|
328 //GCGraphicsExposures |
|
|
329 ExposureMask | PropertyChangeMask |
|
|
330 EnterWindowMask | LeaveWindowMask |
|
|
331 VisibilityChangeMask |
|
|
332 KeyPressMask | KeyReleaseMask;
|
|
333 if ( ( cV & wsHandleMouseButton ) ) win->WindowAttrib.event_mask|=ButtonPressMask | ButtonReleaseMask;
|
|
334 if ( ( cV & wsHandleMouseMove ) ) win->WindowAttrib.event_mask|=PointerMotionMask;
|
|
335 win->WindowAttrib.cursor=win->wsCursor;
|
|
336 win->WindowAttrib.override_redirect=False;
|
|
337 if ( D & wsOverredirect ) win->WindowAttrib.override_redirect=True;
|
|
338
|
|
339 // win->WindowAttrib.save_under=True;
|
|
340 // win->WindowAttrib.do_not_propagate_mask = True;
|
|
341
|
|
342 win->WindowMask=CWBackPixel | CWBorderPixel |
|
|
343 CWColormap | CWEventMask | CWCursor |
|
|
344 CWX | CWY | CWWidth | CWHeight |
|
|
345 CWOverrideRedirect;
|
|
346
|
|
347 win->WindowID=XCreateWindow( wsDisplay,
|
|
348 (win->Parent != 0?win->Parent:wsRootWin),
|
|
349 win->X,win->Y,win->Width,win->Height,win->BorderWidth,
|
|
350 win->VisualInfo.depth,
|
|
351 InputOutput,
|
|
352 win->VisualInfo.visual,
|
|
353 win->WindowMask,&win->WindowAttrib );
|
|
354
|
|
355 wsClassHint.res_name=label;
|
|
356 wsClassHint.res_class="mPlayer";
|
|
357 XSetClassHint( wsDisplay,win->WindowID,&wsClassHint );
|
|
358
|
|
359 win->SizeHint.flags=PPosition | PSize | PResizeInc; // | PBaseSize
|
|
360 win->SizeHint.x=win->X;
|
|
361 win->SizeHint.y=win->Y;
|
|
362 win->SizeHint.width=win->Width;
|
|
363 win->SizeHint.height=win->Height;
|
|
364 if ( D & wsMaxSize )
|
|
365 {
|
|
366 win->SizeHint.flags|=PMaxSize;
|
|
367 win->SizeHint.min_width=win->Width;
|
|
368 win->SizeHint.min_height=win->Height;
|
|
369 }
|
|
370 if ( D & wsMinSize )
|
|
371 {
|
|
372 win->SizeHint.flags|=PMinSize;
|
|
373 win->SizeHint.max_width=win->Width;
|
|
374 win->SizeHint.max_height=win->Height;
|
|
375 }
|
|
376 win->SizeHint.height_inc=1;
|
|
377 win->SizeHint.width_inc=1;
|
|
378 // win->SizeHint.base_width=win->Width;
|
|
379 // win->SizeHint.base_height=win->Height;
|
|
380 XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint );
|
|
381
|
|
382 win->WMHints.flags=InputHint | StateHint;
|
|
383 win->WMHints.input=True;
|
|
384 win->WMHints.initial_state=NormalState;
|
|
385 XSetWMHints( wsDisplay,win->WindowID,&win->WMHints );
|
|
386
|
|
387 wsWindowDecoration( win,win->Decorations );
|
|
388 XStoreName( wsDisplay,win->WindowID,label );
|
|
389 XmbSetWMProperties( wsDisplay,win->WindowID,label,label,NULL,0,NULL,NULL,NULL );
|
|
390
|
|
391 XSetWMProtocols( wsDisplay,win->WindowID,win->AtomsProtocols,3 );
|
|
392 XChangeProperty( wsDisplay,win->WindowID,
|
|
393 win->AtomLeaderClient,
|
|
394 XA_WINDOW,32,PropModeReplace,
|
|
395 (unsigned char *)&LeaderWindow,1 );
|
|
396
|
|
397 wsTextProperty.value=label;
|
|
398 wsTextProperty.encoding=XA_STRING;
|
|
399 wsTextProperty.format=8;
|
|
400 wsTextProperty.nitems=strlen( label );
|
|
401 XSetWMIconName( wsDisplay,win->WindowID,&wsTextProperty );
|
|
402
|
|
403 XChangeProperty( wsDisplay,win->WindowID,
|
|
404 win->AtomRemote,XA_STRING,
|
|
405 8,PropModeReplace,
|
|
406 "REALIZED",8 );
|
|
407
|
|
408 // win->Font=XLoadQueryFont( wsDisplay,"-adobe-helvetica-bold-r-normal--14-140-75-75-p-77-iso8859-1" );
|
|
409 // -adobe-times-medium-r-normal--14-140-75-75-p-77-iso8859-1" );
|
|
410 // -misc-fixed-bold-r-normal--13-120-75-75-C-80-iso8859-1" );
|
|
411 // -misc-fixed-bold-r-normal--15-140-75-75-C-90-iso8859-1" );
|
|
412 // -misc-fixed-medium-r-normal--15-140-75-75-C-90-iso8859-1" );
|
|
413 // -adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1" );
|
|
414 // -adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1" );
|
|
415 // -*-helvetica-bold-o-normal--14-*-*-*-p-*-iso8859-1" );
|
|
416 // if ( !win->Font ) win->Font=XLoadQueryFont( wsDisplay,"fixed" );
|
|
417 // if ( !win->Font )
|
|
418 // {
|
|
419 // fprintf( stderr,"[main] could not load font.\n" );
|
|
420 // exit( 0 );
|
|
421 // }
|
|
422 // win->FontHeight=win->Font->ascent + win->Font->descent;
|
|
423 //
|
|
424 // #ifdef DEBUG
|
|
425 // fprintf( stderr,"[ws] font height: %d\n",win->FontHeight );
|
|
426 // #endif
|
|
427
|
|
428 // win->wGCV.font=win->Font->fid;
|
|
429 // win->wGCV.foreground=wsBlack;
|
|
430 // win->wGCV.background=wsBlack;
|
|
431
|
|
432 win->wGC=XCreateGC( wsDisplay,win->WindowID,
|
|
433 // GCForeground | GCBackground,
|
|
434 0,
|
|
435 &win->wGCV );
|
|
436
|
|
437 win->Visible=0;
|
|
438 win->Focused=0;
|
|
439 win->Mapped=0;
|
|
440 win->Rolled=0;
|
|
441 if ( D & wsShowWindow ) XMapWindow( wsDisplay,win->WindowID );
|
|
442
|
|
443 wsCreateImage( win );
|
|
444 // --- End of creating --------------------------------------------------------------------------
|
|
445
|
|
446 wsWindowList[wsWLCount++]=win;
|
|
447
|
|
448 XFlush( wsDisplay );
|
|
449 XSync( wsDisplay,False );
|
|
450
|
|
451 win->ReDraw=NULL;
|
|
452 win->ReSize=NULL;
|
|
453 win->Idle=NULL;
|
|
454 win->MouseHandler=NULL;
|
|
455 win->KeyHandler=NULL;
|
|
456 #ifdef DEBUG
|
|
457 fprintf( stderr,"[ws] window is created. ( %s ).\n",label );
|
|
458 #endif
|
|
459 }
|
|
460
|
|
461 void wsDestroyWindow( wsTWindow * win )
|
|
462 {
|
|
463 int l;
|
|
464 l=wsSearch( win->WindowID );
|
|
465 wsWindowList[l]=NULL;
|
|
466 if ( win->wsCursor != None )
|
|
467 {
|
|
468 XFreeCursor( wsDisplay,win->wsCursor );
|
|
469 win->wsCursor=None;
|
|
470 }
|
|
471 XUnmapWindow( wsDisplay,win->WindowID );
|
|
472 wsDestroyImage( win );
|
|
473 XDestroyWindow( wsDisplay,win->WindowID );
|
|
474 win->ReDraw=NULL;
|
|
475 win->ReSize=NULL;
|
|
476 win->Idle=NULL;
|
|
477 win->MouseHandler=NULL;
|
|
478 win->KeyHandler=NULL;
|
|
479 win->Visible=0;
|
|
480 win->Focused=0;
|
|
481 win->Mapped=0;
|
|
482 win->Rolled=0;
|
|
483 }
|
|
484
|
|
485 // ----------------------------------------------------------------------------------------------
|
|
486 // Handle events.
|
|
487 // ----------------------------------------------------------------------------------------------
|
|
488
|
|
489 inline int wsSearch( Window win )
|
|
490 {
|
|
491 int i;
|
|
492 for ( i=0;i<wsWLCount;i++ ) if ( wsWindowList[i]->WindowID == win ) return i;
|
|
493 return -1;
|
|
494 }
|
|
495
|
|
496 Bool wsEvents( Display * display,XEvent * Event,XPointer arg )
|
|
497 {
|
|
498 KeySym keySym;
|
|
499 unsigned long i = 0;
|
|
500 int l;
|
|
501 int x,y;
|
|
502 Window child_window = 0;
|
|
503
|
|
504 l=wsSearch( Event->xany.window );
|
|
505 if ( l == -1 ) return !wsTrue;
|
|
506 switch( Event->type )
|
|
507 {
|
|
508 case ClientMessage:
|
|
509 if ( Event->xclient.message_type == wsWindowList[l]->AtomProtocols )
|
|
510 {
|
|
511 if ( Event->xclient.data.l[0] == wsWindowList[l]->AtomDeleteWindow )
|
|
512 { wsTrue=False; break; }
|
|
513 if ( Event->xclient.data.l[0] == wsWindowList[l]->AtomTakeFocus )
|
|
514 { i=wsWindowFocusIn; wsWindowList[l]->Focused=wsFocused; goto expose; }
|
|
515 if ( Event->xclient.data.l[0] == wsWindowList[l]->AtomRolle )
|
|
516 { fprintf( stderr,"[ws] rolled.\n" ); }
|
|
517 }
|
|
518 break;
|
|
519
|
|
520 // case CirculateRequest:fprintf( stderr,"[ws,r] win: 0x%x\n",(int)Event->xcirculaterequest.window ); break;
|
|
521 // case CirculateNotify: fprintf( stderr,"[ws,c] win: 0x%x\n",(int)Event->xcirculate.window ); break;
|
|
522
|
|
523 case MapNotify: i=wsWindowMapped; wsWindowList[l]->Mapped=wsMapped; goto expose;
|
|
524 case UnmapNotify: i=wsWindowUnmapped; wsWindowList[l]->Mapped=wsNone; goto expose;
|
|
525 case FocusIn:
|
|
526 if ( wsWindowList[l]->Focused == wsFocused ) break;
|
|
527 i=wsWindowFocusIn; wsWindowList[l]->Focused=wsFocused; goto expose;
|
|
528 case FocusOut:
|
|
529 if ( wsWindowList[l]->Focused == wsNone ) break;
|
|
530 i=wsWindowFocusOut; wsWindowList[l]->Focused=wsNone; goto expose;
|
|
531 case VisibilityNotify:
|
|
532 switch( Event->xvisibility.state )
|
|
533 {
|
|
534 case VisibilityUnobscured: i=wsWindowVisible; wsWindowList[l]->Visible=wsVisible; goto expose;
|
|
535 case VisibilityFullyObscured: i=wsWindowNotVisible; wsWindowList[l]->Visible=wsNotVisible; goto expose;
|
|
536 case VisibilityPartiallyObscured: i=wsWindowPartialVisible; wsWindowList[l]->Visible=wsPVisible; goto expose;
|
|
537 }
|
|
538 expose:
|
|
539 wsWindowList[l]->State=i;
|
|
540 if ( wsWindowList[l]->ReDraw ) wsWindowList[l]->ReDraw( wsDisplay,Event->xany.window );
|
|
541 break;
|
|
542
|
|
543 case Expose:
|
|
544 wsWindowList[l]->State=wsWindowExpose;
|
|
545 if ( ( wsWindowList[l]->ReDraw )&&( !Event->xexpose.count ) ) wsWindowList[l]->ReDraw( wsDisplay,Event->xany.window );
|
|
546 break;
|
|
547
|
|
548 case ConfigureNotify:
|
|
549 XTranslateCoordinates( wsDisplay,wsWindowList[l]->WindowID,wsRootWin,0,0,&x,&y,&child_window );
|
|
550 if ( ( wsWindowList[l]->X != x )||( wsWindowList[l]->Y != y )||( wsWindowList[l]->Width != Event->xconfigure.width )||( wsWindowList[l]->Height != Event->xconfigure.height ) )
|
|
551 {
|
|
552 wsWindowList[l]->X=x; wsWindowList[l]->Y=y;
|
|
553 wsWindowList[l]->Width=Event->xconfigure.width; wsWindowList[l]->Height=Event->xconfigure.height;
|
|
554 // fprintf( stderr,"[ws] resize: %d,%d %dx%d\n",wsWindowList[l]->X,wsWindowList[l]->Y,Event->xconfigure.width,Event->xconfigure.height );
|
|
555 if ( wsWindowList[l]->ReSize ) wsWindowList[l]->ReSize( wsWindowList[l]->X,wsWindowList[l]->Y,wsWindowList[l]->Width,wsWindowList[l]->Height );
|
|
556 }
|
|
557
|
|
558 wsWindowList[l]->Rolled=wsNone;
|
|
559 if ( Event->xconfigure.y < 0 )
|
|
560 { i=wsWindowRolled; wsWindowList[l]->Rolled=wsRolled; goto expose; }
|
|
561
|
|
562 break;
|
|
563
|
|
564 case KeyPress: i=wsKeyPressed; goto keypressed;
|
|
565 case KeyRelease: i=wsKeyReleased;
|
|
566 keypressed:
|
|
567 wsWindowList[l]->Alt=0;
|
|
568 wsWindowList[l]->Shift=0;
|
|
569 wsWindowList[l]->NumLock=0;
|
|
570 wsWindowList[l]->Control=0;
|
|
571 wsWindowList[l]->CapsLock=0;
|
|
572 if ( Event->xkey.state & Mod1Mask ) wsWindowList[l]->Alt=1;
|
|
573 if ( Event->xkey.state & Mod2Mask ) wsWindowList[l]->NumLock=1;
|
|
574 if ( Event->xkey.state & ControlMask ) wsWindowList[l]->Control=1;
|
|
575 if ( Event->xkey.state & ShiftMask ) wsWindowList[l]->Shift=1;
|
|
576 if ( Event->xkey.state & LockMask ) wsWindowList[l]->CapsLock=1;
|
|
577 keySym=XKeycodeToKeysym( wsDisplay,Event->xkey.keycode,0 );
|
|
578 if ( keySym != NoSymbol )
|
|
579 {
|
|
580 keySym=( (keySym&0xff00) != 0?( (keySym&0x00ff) + 256 ):( keySym ) );
|
|
581 wsKeyTable[ keySym ]=i;
|
|
582 if ( wsWindowList[l]->KeyHandler )
|
|
583 wsWindowList[l]->KeyHandler( Event->xkey.state,i,keySym );
|
|
584 }
|
|
585 break;
|
|
586
|
|
587 case MotionNotify: i=wsMoveMouse; goto buttonreleased;
|
|
588 case ButtonRelease: i=Event->xbutton.button + 128; goto buttonreleased;
|
|
589 case ButtonPress: i=Event->xbutton.button; goto buttonreleased;
|
|
590 case EnterNotify: i=wsEnterWindow; goto buttonreleased;
|
|
591 case LeaveNotify: i=wsLeaveWindow;
|
|
592 buttonreleased:
|
|
593 if ( wsWindowList[l]->MouseHandler )
|
|
594 wsWindowList[l]->MouseHandler( i,Event->xbutton.x,Event->xbutton.y,Event->xmotion.x_root,Event->xmotion.y_root );
|
|
595 break;
|
|
596
|
|
597 case PropertyNotify:
|
|
598 // fprintf(stderr,"[ws] PropertyNotify %s\n",XGetAtomName( wsDisplay,Event->xproperty.atom ) );
|
|
599 if ( Event->xproperty.atom == wsWindowList[l]->AtomRemote )
|
|
600 {
|
|
601 Atom type;
|
|
602 int format;
|
|
603 unsigned long nitems, bytesafter;
|
|
604 unsigned char * args = NULL;
|
|
605
|
|
606 // fprintf( stderr,"[ws] remote property notify.\n" );
|
|
607 XGetWindowProperty( wsDisplay,
|
|
608 Event->xproperty.window,
|
|
609 Event->xproperty.atom,
|
|
610 0,( 65536 / sizeof( long ) ),
|
|
611 False,XA_STRING,
|
|
612 &type,&format,&nitems,&bytesafter,
|
|
613 &args );
|
|
614 if ( ( nitems )&&( wsWindowList[l]->RemoteHandler ) )
|
|
615 {
|
|
616 args[strlen( args ) - 1]=0;
|
|
617 wsWindowList[l]->RemoteHandler( args );
|
|
618 args[strlen( args ) - 1]=1;
|
|
619 XFree( args );
|
|
620 }
|
|
621 }
|
|
622 break;
|
|
623
|
|
624 }
|
|
625 XFlush( wsDisplay );
|
|
626 XSync( wsDisplay,False );
|
|
627 return !wsTrue;
|
|
628 // return True;
|
|
629 }
|
|
630
|
|
631 Bool wsDummyEvents( Display * display,XEvent * Event,XPointer arg )
|
|
632 { return True; }
|
|
633
|
1709
|
634 // mplTimerHandler(0); // handle timer event
|
|
635 void wsHandleEvents(){
|
|
636 // handle pending events
|
|
637 while ( XPending(wsDisplay) ){
|
|
638 XNextEvent( wsDisplay,&wsEvent );
|
|
639 // printf("### X event: %d [%d]\n",wsEvent.type,delay);
|
|
640 wsEvents( wsDisplay,&wsEvent,NULL );
|
|
641 }
|
|
642 }
|
|
643
|
1693
|
644 void wsMainLoop( void )
|
|
645 {
|
1699
|
646 int delay=20;
|
1693
|
647 fprintf( stderr,"[ws] init threads: %d\n",XInitThreads() );
|
|
648 XSynchronize( wsDisplay,False );
|
|
649 XLockDisplay( wsDisplay );
|
|
650 // XIfEvent( wsDisplay,&wsEvent,wsEvents,NULL );
|
1699
|
651
|
|
652 #if 1
|
|
653
|
|
654 while(wsTrue){
|
|
655 // handle pending events
|
|
656 while ( XPending(wsDisplay) ){
|
|
657 XNextEvent( wsDisplay,&wsEvent );
|
1701
|
658 // printf("### X event: %d [%d]\n",wsEvent.type,delay);
|
1699
|
659 wsEvents( wsDisplay,&wsEvent,NULL );
|
1701
|
660 delay=0;
|
1699
|
661 }
|
|
662 mplTimerHandler(0); // handle timer event
|
|
663 usleep(delay*1000); // FIXME!
|
1701
|
664 if(delay<10*20) delay+=20; // pump up delay up to 0.2 sec (low activity)
|
1699
|
665 }
|
|
666
|
|
667 #else
|
|
668
|
1693
|
669 while( wsTrue )
|
|
670 {
|
|
671 XIfEvent( wsDisplay,&wsEvent,wsDummyEvents,NULL );
|
|
672 wsEvents( wsDisplay,&wsEvent,NULL );
|
|
673 }
|
1699
|
674 #endif
|
|
675
|
1693
|
676 XUnlockDisplay( wsDisplay );
|
|
677 }
|
|
678
|
|
679 // ----------------------------------------------------------------------------------------------
|
|
680 // Switch to fullscreen.
|
|
681 // ----------------------------------------------------------------------------------------------
|
|
682 void wsFullScreen( wsTWindow * win )
|
|
683 {
|
|
684 int decoration = 0;
|
|
685 XUnmapWindow( wsDisplay,win->WindowID );
|
|
686 win->SizeHint.flags=0;
|
|
687 if ( win->isFullScreen )
|
|
688 {
|
|
689 win->X=win->OldX;
|
|
690 win->Y=win->OldY;
|
|
691 win->Width=win->OldWidth;
|
|
692 win->Height=win->OldHeight;
|
|
693 win->isFullScreen=False;
|
|
694 if ( win->Property & wsMaxSize )
|
|
695 {
|
|
696 win->SizeHint.flags|=PMaxSize;
|
|
697 win->SizeHint.max_width=win->Width;
|
|
698 win->SizeHint.max_height=win->Height;
|
|
699 }
|
|
700 if ( win->Property & wsMinSize )
|
|
701 {
|
|
702 win->SizeHint.flags|=PMinSize;
|
|
703 win->SizeHint.min_width=win->Width;
|
|
704 win->SizeHint.min_height=win->Height;
|
|
705 }
|
|
706 decoration=win->Decorations;
|
|
707 wsScreenSaverOn( wsDisplay );
|
|
708 }
|
|
709 else
|
|
710 {
|
|
711 win->OldX=win->X; win->OldY=win->Y;
|
|
712 win->OldWidth=win->Width; win->OldHeight=win->Height;
|
|
713 win->X=0; win->Y=0;
|
|
714 win->Width=wsMaxX; win->Height=wsMaxY;
|
|
715 win->isFullScreen=True;
|
|
716 // if ( win->Property & wsMaxSize )
|
|
717 // {
|
|
718 // win->SizeHint.flags|=PMaxSize;
|
|
719 // win->SizeHint.min_width=0;
|
|
720 // win->SizeHint.min_height=0;
|
|
721 // }
|
|
722 // if ( win->Property & wsMinSize )
|
|
723 // {
|
|
724 // win->SizeHint.flags|=PMinSize;
|
|
725 // win->SizeHint.max_width=4096;
|
|
726 // win->SizeHint.max_height=4096;
|
|
727 // }
|
|
728 wsScreenSaverOff( wsDisplay );
|
|
729 }
|
|
730
|
|
731 win->SizeHint.flags|=PPosition | PSize;
|
|
732 win->SizeHint.x=win->X;
|
|
733 win->SizeHint.y=win->Y;
|
|
734 win->SizeHint.width=win->Width;
|
|
735 win->SizeHint.height=win->Height;
|
|
736 XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint );
|
|
737
|
|
738 XMoveResizeWindow( wsDisplay,win->WindowID,win->X,win->Y,win->Width,win->Height );
|
|
739 wsWindowDecoration( win,decoration );
|
|
740 XRaiseWindow( wsDisplay,win->WindowID );
|
|
741 XMapWindow( wsDisplay,win->WindowID );
|
|
742 }
|
|
743
|
|
744 // ----------------------------------------------------------------------------------------------
|
|
745 // Redraw screen.
|
|
746 // ----------------------------------------------------------------------------------------------
|
|
747 void wsPostRedisplay( wsTWindow * win )
|
|
748 {
|
|
749 if ( win->ReDraw )
|
|
750 {
|
|
751 win->ReDraw( wsDisplay,win->WindowID );
|
|
752 XFlush( wsDisplay );
|
|
753 }
|
|
754 }
|
|
755
|
|
756 // ----------------------------------------------------------------------------------------------
|
|
757 // Do Exit.
|
|
758 // ----------------------------------------------------------------------------------------------
|
|
759 void wsDoExit( void )
|
|
760 { wsTrue=False; wsResizeWindow( wsWindowList[0],32,32 ); }
|
|
761
|
|
762 // ----------------------------------------------------------------------------------------------
|
|
763 // Put 'Image' to window.
|
|
764 // ----------------------------------------------------------------------------------------------
|
|
765 void wsConvert( wsTWindow * win,unsigned char * Image,unsigned int Size )
|
|
766 { if ( wsConvFunc ) wsConvFunc( Image,win->ImageData,win->xImage->width * win->xImage->height ); }
|
|
767
|
|
768 void wsPutImage( wsTWindow * win )
|
|
769 {
|
|
770 if ( wsUseXShm )
|
|
771 {
|
|
772 XShmPutImage( wsDisplay,win->WindowID,win->wGC,win->xImage,
|
|
773 0,0,
|
|
774 ( win->Width - win->xImage->width ) / 2,( win->Height - win->xImage->height ) / 2,
|
|
775 win->xImage->width,win->xImage->height,0 );
|
|
776 // win->Width,win->Height,0 );
|
|
777 }
|
|
778 else
|
|
779 {
|
|
780 XPutImage( wsDisplay,win->WindowID,win->wGC,win->xImage,
|
|
781 0,0,
|
|
782 ( win->Width - win->xImage->width ) / 2,( win->Height - win->xImage->height ) / 2,
|
|
783 win->xImage->width,win->xImage->height );
|
|
784 }
|
|
785 }
|
|
786
|
|
787 // ----------------------------------------------------------------------------------------------
|
|
788 // Move window to x, y.
|
|
789 // ----------------------------------------------------------------------------------------------
|
|
790 void wsMoveWindow( wsTWindow * win,int x, int y )
|
|
791 {
|
|
792 switch ( x )
|
|
793 {
|
|
794 case -1: win->X=( wsMaxX / 2 ) - ( win->Width / 2 ); break;
|
|
795 case -2: win->X=wsMaxX - win->Width; break;
|
|
796 default: win->X=x; break;
|
|
797 }
|
|
798 switch ( y )
|
|
799 {
|
|
800 case -1: win->Y=( wsMaxY / 2 ) - ( win->Height / 2 ); break;
|
|
801 case -2: win->Y=wsMaxY - win->Height; break;
|
|
802 default: win->Y=y; break;
|
|
803 }
|
|
804
|
|
805 win->SizeHint.flags=PPosition;
|
|
806 win->SizeHint.x=win->X;
|
|
807 win->SizeHint.y=win->Y;
|
|
808 XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint );
|
|
809
|
|
810 XMoveWindow( wsDisplay,win->WindowID,win->X,win->Y );
|
|
811 }
|
|
812
|
|
813 // ----------------------------------------------------------------------------------------------
|
|
814 // Resize window to sx, sy.
|
|
815 // ----------------------------------------------------------------------------------------------
|
|
816 void wsResizeWindow( wsTWindow * win,int sx, int sy )
|
|
817 {
|
|
818 win->Width=sx;
|
|
819 win->Height=sy;
|
|
820
|
|
821 win->SizeHint.flags=PSize;
|
|
822 win->SizeHint.width=win->Width;
|
|
823 win->SizeHint.height=win->Height;
|
|
824 if ( win->Property & wsMinSize )
|
|
825 {
|
|
826 win->SizeHint.flags|=PMinSize;
|
|
827 win->SizeHint.min_width=win->Width;
|
|
828 win->SizeHint.min_height=win->Height;
|
|
829 }
|
|
830 if ( win->Property & wsMaxSize )
|
|
831 {
|
|
832 win->SizeHint.flags|=PMaxSize;
|
|
833 win->SizeHint.max_width=win->Width;
|
|
834 win->SizeHint.max_height=win->Height;
|
|
835 }
|
|
836 XSetWMNormalHints( wsDisplay,win->WindowID,&win->SizeHint );
|
|
837 XResizeWindow( wsDisplay,win->WindowID,sx,sy );
|
|
838 }
|
|
839
|
|
840 // ----------------------------------------------------------------------------------------------
|
|
841 // Iconify window.
|
|
842 // ----------------------------------------------------------------------------------------------
|
|
843 void wsIconify( wsTWindow win )
|
|
844 { XIconifyWindow( wsDisplay,win.WindowID,0 ); }
|
|
845
|
|
846 // ----------------------------------------------------------------------------------------------
|
|
847 // Move top the window.
|
|
848 // ----------------------------------------------------------------------------------------------
|
|
849 void wsMoveTopWindow( wsTWindow * win )
|
|
850 { XRaiseWindow( wsDisplay,win->WindowID ); }
|
|
851 //{ XUnmapWindow( wsDisplay,win.WindowID ); XMapWindow( wsDisplay,win.WindowID ); }
|
|
852
|
|
853 // ----------------------------------------------------------------------------------------------
|
|
854 // Set window background to 'color'.
|
|
855 // ----------------------------------------------------------------------------------------------
|
|
856 void wsSetBackground( wsTWindow * win,int color )
|
|
857 { XSetWindowBackground( wsDisplay,win->WindowID,color ); }
|
|
858
|
|
859 void wsSetBackgroundRGB( wsTWindow * win,int r,int g,int b )
|
|
860 {
|
|
861 int color = 0;
|
|
862 switch ( wsOutMask )
|
|
863 {
|
|
864 case wsRGB32:
|
|
865 case wsRGB24: color=( r << 16 ) + ( g << 8 ) + b; break;
|
|
866 case wsBGR32:
|
|
867 case wsBGR24: color=( b << 16 ) + ( g << 8 ) + r; break;
|
|
868 case wsRGB16: PACK_RGB16( r,g,b,color ); break;
|
|
869 case wsBGR16: PACK_RGB16( b,g,r,color ); break;
|
|
870 case wsRGB15: PACK_RGB15( r,g,b,color ); break;
|
|
871 case wsBGR15: PACK_RGB15( b,g,r,color ); break;
|
|
872 }
|
|
873 XSetWindowBackground( wsDisplay,win->WindowID,color );
|
|
874 }
|
|
875
|
|
876
|
|
877 // ----------------------------------------------------------------------------------------------
|
|
878 // Draw string at x,y with fc ( foreground color ) and bc ( background color ).
|
|
879 // ----------------------------------------------------------------------------------------------
|
|
880 void wsDrawString( wsTWindow win,int x,int y,char * str,int fc,int bc )
|
|
881 {
|
|
882 XSetForeground( wsDisplay,win.wGC,bc );
|
|
883 XFillRectangle( wsDisplay,win.WindowID,win.wGC,x,y,
|
|
884 XTextWidth( win.Font,str,strlen( str ) ) + 20,
|
|
885 win.FontHeight + 2 );
|
|
886 XSetForeground( wsDisplay,win.wGC,fc );
|
|
887 XDrawString( wsDisplay,win.WindowID,win.wGC,x + 10,y + 13,str,strlen( str ) );
|
|
888 }
|
|
889
|
|
890 // ----------------------------------------------------------------------------------------------
|
|
891 // Calculation string width.
|
|
892 // ----------------------------------------------------------------------------------------------
|
|
893 int wsTextWidth( wsTWindow win,char * str )
|
|
894 { return XTextWidth( win.Font,str,strlen( str ) ) + 20; }
|
|
895
|
|
896 // ----------------------------------------------------------------------------------------------
|
|
897 // Show / hide mouse cursor.
|
|
898 // ----------------------------------------------------------------------------------------------
|
|
899 void wsVisibleMouse( wsTWindow * win,int m )
|
|
900 {
|
|
901 switch ( m )
|
|
902 {
|
|
903 case wsShowMouseCursor:
|
|
904 if ( win->wsCursor != None )
|
|
905 {
|
|
906 XFreeCursor( wsDisplay,win->wsCursor );
|
|
907 win->wsCursor=None;
|
|
908 }
|
|
909 XDefineCursor( wsDisplay,win->WindowID,0 );
|
|
910 break;
|
|
911 case wsHideMouseCursor:
|
|
912 win->wsCursor=XCreatePixmapCursor( wsDisplay,win->wsCursorPixmap,win->wsCursorPixmap,&win->wsColor,&win->wsColor,0,0 );
|
|
913 XDefineCursor( wsDisplay,win->WindowID,win->wsCursor );
|
|
914 break;
|
|
915 }
|
|
916 XFlush( wsDisplay );
|
|
917 }
|
|
918
|
|
919 int wsGetDepthOnScreen( void )
|
|
920 {
|
|
921 int bpp,ibpp;
|
|
922 XImage * mXImage;
|
|
923 XWindowAttributes attribs;
|
|
924
|
|
925 mXImage=XGetImage( wsDisplay,wsRootWin,0,0,1,1,AllPlanes,ZPixmap );
|
|
926 bpp=mXImage->bits_per_pixel;
|
|
927
|
|
928 XGetWindowAttributes( wsDisplay,wsRootWin,&attribs );
|
|
929 ibpp=attribs.depth;
|
|
930 mXImage=XGetImage( wsDisplay,wsRootWin,0,0,1,1,AllPlanes,ZPixmap );
|
|
931 bpp=mXImage->bits_per_pixel;
|
|
932 if ( ( ibpp + 7 ) / 8 != ( bpp + 7 ) / 8 ) ibpp=bpp;
|
|
933 wsDepthOnScreen=ibpp;
|
|
934 wsRedMask=mXImage->red_mask;
|
|
935 wsGreenMask=mXImage->green_mask;
|
|
936 wsBlueMask=mXImage->blue_mask;
|
|
937 XDestroyImage( mXImage );
|
|
938 return ibpp;
|
|
939 }
|
|
940
|
|
941 void wsXDone( void )
|
|
942 {
|
|
943 // if ( wsSwitchedAnotherVideoMode ) wsChangeVideoMode( wsOldXResolution,wsOldYResolution );
|
|
944 // if ( wsUseDGA ) XF86DGADirectVideo( wsDisplay,wsScreen,0 );
|
|
945 XCloseDisplay( wsDisplay );
|
|
946 }
|
|
947
|
|
948 void wsVisibleWindow( wsTWindow * win,int show )
|
|
949 {
|
|
950 switch( show )
|
|
951 {
|
|
952 case wsShowWindow: XMapWindow( wsDisplay,win->WindowID ); break;
|
|
953 case wsHideWindow: XUnmapWindow( wsDisplay,win->WindowID ); break;
|
|
954 }
|
|
955 XFlush( wsDisplay );
|
|
956 }
|
|
957
|
|
958 void wsDestroyImage( wsTWindow * win )
|
|
959 {
|
|
960 if ( win->xImage )
|
|
961 {
|
|
962 XDestroyImage( win->xImage );
|
|
963 if ( wsUseXShm )
|
|
964 {
|
|
965 XShmDetach( wsDisplay,&win->Shminfo );
|
|
966 shmdt( win->Shminfo.shmaddr );
|
|
967 }
|
|
968 }
|
|
969 win->xImage=NULL;
|
|
970 }
|
|
971
|
|
972 void wsCreateImage( wsTWindow * win )
|
|
973 {
|
|
974 int CompletionType = -1;
|
|
975 if ( wsUseXShm )
|
|
976 {
|
|
977 CompletionType=XShmGetEventBase( wsDisplay ) + ShmCompletion;
|
|
978 win->xImage=XShmCreateImage( wsDisplay,win->VisualInfo.visual,
|
|
979 win->Attribs.depth,ZPixmap,NULL,&win->Shminfo,win->Width,win->Height );
|
|
980 if ( win->xImage == NULL )
|
|
981 {
|
|
982 fprintf( stderr,"[ws] shared memory extension error.\n" );
|
|
983 exit( 0 );
|
|
984 }
|
|
985 // #ifdef DEBUG
|
|
986 // fprintf( stderr,"[ws] Screen depth: %d\n",win->xImage->bits_per_pixel );
|
|
987 // #endif
|
|
988 win->Shminfo.shmid=shmget( IPC_PRIVATE,win->xImage->bytes_per_line * win->xImage->height,IPC_CREAT|0777 );
|
|
989 if ( win->Shminfo.shmid < 0 )
|
|
990 {
|
|
991 XDestroyImage( win->xImage );
|
|
992 fprintf( stderr,"[ws] shared memory extension error.\n" );
|
|
993 exit( 0 );
|
|
994 }
|
|
995 win->Shminfo.shmaddr=(char *)shmat( win->Shminfo.shmid,0,0 );
|
|
996
|
|
997 if ( win->Shminfo.shmaddr == ((char *) -1) )
|
|
998 {
|
|
999 XDestroyImage( win->xImage );
|
|
1000 if ( win->Shminfo.shmaddr != ((char *) -1) ) shmdt( win->Shminfo.shmaddr );
|
|
1001 fprintf( stderr,"[ws] shared memory extension error.\n" );
|
|
1002 exit( 0 );
|
|
1003 }
|
|
1004 win->xImage->data=win->Shminfo.shmaddr;
|
|
1005 win->Shminfo.readOnly=0;
|
|
1006 XShmAttach( wsDisplay,&win->Shminfo );
|
|
1007 shmctl( win->Shminfo.shmid,IPC_RMID,0 );
|
|
1008 }
|
|
1009 else
|
|
1010 {
|
|
1011 win->xImage=XCreateImage( wsDisplay,win->VisualInfo.visual,win->Attribs.depth,
|
|
1012 ZPixmap,0,0,win->Width,win->Height,
|
|
1013 (wsDepthOnScreen == 3) ? 32 : wsDepthOnScreen,
|
|
1014 0 );
|
|
1015 if ( ( win->xImage->data=malloc( win->xImage->bytes_per_line * win->xImage->height ) ) == NULL )
|
|
1016 {
|
|
1017 fprintf( stderr,"[ws] sorry, not enough memory for draw buffer.\n" );
|
|
1018 exit( 0 );
|
|
1019 }
|
|
1020 }
|
|
1021 win->ImageData=(unsigned char *)win->xImage->data;
|
|
1022 win->ImageDataw=(unsigned short int *)win->xImage->data;
|
|
1023 win->ImageDatadw=(unsigned int *)win->xImage->data;
|
|
1024 }
|
|
1025
|
|
1026 void wsResizeImage( wsTWindow * win )
|
|
1027 { wsDestroyImage( win ); wsCreateImage( win ); }
|
|
1028
|
|
1029 int wsGetOutMask( void )
|
|
1030 {
|
|
1031 if ( ( wsDepthOnScreen == 32 )&&( wsRedMask == 0xff0000 )&&( wsGreenMask == 0x00ff00 )&&( wsBlueMask == 0x0000ff ) ) return wsRGB32;
|
|
1032 if ( ( wsDepthOnScreen == 32 )&&( wsRedMask == 0x0000ff )&&( wsGreenMask == 0x00ff00 )&&( wsBlueMask == 0xff0000 ) ) return wsBGR32;
|
|
1033 if ( ( wsDepthOnScreen == 24 )&&( wsRedMask == 0xff0000 )&&( wsGreenMask == 0x00ff00 )&&( wsBlueMask == 0x0000ff ) ) return wsRGB24;
|
|
1034 if ( ( wsDepthOnScreen == 24 )&&( wsRedMask == 0x0000ff )&&( wsGreenMask == 0x00ff00 )&&( wsBlueMask == 0xff0000 ) ) return wsBGR24;
|
|
1035 if ( ( wsDepthOnScreen == 16 )&&( wsRedMask == 0xf800 )&&( wsGreenMask == 0x7e0 )&&( wsBlueMask == 0x1f ) ) return wsRGB16;
|
|
1036 if ( ( wsDepthOnScreen == 16 )&&( wsRedMask == 0x1f )&&( wsGreenMask == 0x7e0 )&&( wsBlueMask == 0xf800 ) ) return wsBGR16;
|
|
1037 if ( ( wsDepthOnScreen == 15 )&&( wsRedMask == 0x7c00 )&&( wsGreenMask == 0x3e0 )&&( wsBlueMask == 0x1f ) ) return wsRGB15;
|
|
1038 if ( ( wsDepthOnScreen == 15 )&&( wsRedMask == 0x1f )&&( wsGreenMask == 0x3e0 )&&( wsBlueMask == 0x7c00 ) ) return wsBGR15;
|
|
1039 return 0;
|
|
1040 }
|
|
1041
|
|
1042 void wsSetTitle( wsTWindow * win,char * name )
|
|
1043 { XStoreName( wsDisplay,win->WindowID,name ); }
|
|
1044
|
|
1045 void wsSetMousePosition( wsTWindow * win,int x, int y )
|
|
1046 { XWarpPointer( wsDisplay,wsRootWin,win->WindowID,0,0,0,0,x,y ); }
|
|
1047
|
|
1048 static int dpms_disabled=0;
|
|
1049 static int timeout_save=0;
|
|
1050
|
|
1051 void wsScreenSaverOn( Display *mDisplay )
|
|
1052 {
|
|
1053 int nothing;
|
|
1054 if ( dpms_disabled )
|
|
1055 {
|
|
1056 if ( DPMSQueryExtension( mDisplay,¬hing,¬hing ) )
|
|
1057 {
|
|
1058 if ( !DPMSEnable( mDisplay ) ) fprintf( stderr,"DPMS not available ?\n" ); // restoring power saving settings
|
|
1059 else
|
|
1060 {
|
|
1061 // DPMS does not seem to be enabled unless we call DPMSInfo
|
|
1062 BOOL onoff;
|
|
1063 CARD16 state;
|
|
1064 DPMSInfo( mDisplay,&state,&onoff );
|
|
1065 if ( onoff ) fprintf( stderr,"Successfully enabled DPMS.\n" );
|
|
1066 else fprintf( stderr,"Could not enable DPMS.\n" );
|
|
1067 }
|
|
1068 }
|
|
1069 }
|
|
1070
|
|
1071 if ( timeout_save )
|
|
1072 {
|
|
1073 int dummy, interval, prefer_blank, allow_exp;
|
|
1074 XGetScreenSaver( mDisplay,&dummy,&interval,&prefer_blank,&allow_exp );
|
|
1075 XSetScreenSaver( mDisplay,timeout_save,interval,prefer_blank,allow_exp );
|
|
1076 XGetScreenSaver( mDisplay,&timeout_save,&interval,&prefer_blank,&allow_exp );
|
|
1077 }
|
|
1078 }
|
|
1079
|
|
1080 void wsScreenSaverOff( Display * mDisplay )
|
|
1081 {
|
|
1082 int interval,prefer_blank,allow_exp,nothing;
|
|
1083
|
|
1084 if ( DPMSQueryExtension( mDisplay,¬hing,¬hing ) )
|
|
1085 {
|
|
1086 BOOL onoff;
|
|
1087 CARD16 state;
|
|
1088 DPMSInfo( mDisplay,&state,&onoff );
|
|
1089 if ( onoff )
|
|
1090 {
|
|
1091 Status stat;
|
|
1092 fprintf( stderr,"Disabling DPMS.\n" );
|
|
1093 dpms_disabled=1;
|
|
1094 stat=DPMSDisable( mDisplay ); // monitor powersave off
|
|
1095 fprintf( stderr,"stat: %d.\n",stat );
|
|
1096 }
|
|
1097 }
|
|
1098 XGetScreenSaver( mDisplay,&timeout_save,&interval,&prefer_blank,&allow_exp );
|
|
1099 if ( timeout_save ) XSetScreenSaver( mDisplay,0,interval,prefer_blank,allow_exp ); // turning off screensaver
|
|
1100 }
|
|
1101
|
|
1102 void wsSetShape( wsTWindow * win,char * data )
|
|
1103 {
|
|
1104 #ifdef HAVE_XSHAPE
|
|
1105 if ( ( !wsUseXShape )||( !data ) ) return;
|
|
1106 win->Mask=XCreateBitmapFromData( wsDisplay,win->WindowID,data,win->Width,win->Height );
|
|
1107 XShapeCombineMask( wsDisplay,win->WindowID,ShapeBounding,0,0,win->Mask,ShapeSet );
|
|
1108 XFreePixmap( wsDisplay,win->Mask );
|
|
1109 #endif
|
|
1110 }
|
|
1111
|
|
1112 #include "wsmkeys.h"
|