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