shell32: Add explorer toolbar bitmaps.
[wine/hramrach.git] / dlls / winex11.drv / x11drv_main.c
blobfd8a41503e64638269cad77441ccf0880803f2b4
1 /*
2 * X11DRV initialization code
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2000 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library 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 GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
23 #include "wine/port.h"
25 #include <fcntl.h>
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #ifdef HAVE_SYS_TIME_H
31 # include <sys/time.h>
32 #endif
33 #ifdef HAVE_UNISTD_H
34 # include <unistd.h>
35 #endif
36 #include <X11/cursorfont.h>
37 #include <X11/Xlib.h>
38 #ifdef HAVE_XKB
39 #include <X11/XKBlib.h>
40 #endif
41 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
42 #include <X11/extensions/Xrender.h>
43 #endif
45 #include "windef.h"
46 #include "winbase.h"
47 #include "winreg.h"
49 #include "x11drv.h"
50 #include "xvidmode.h"
51 #include "xrandr.h"
52 #include "xcomposite.h"
53 #include "wine/server.h"
54 #include "wine/debug.h"
55 #include "wine/library.h"
57 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
58 WINE_DECLARE_DEBUG_CHANNEL(synchronous);
60 static CRITICAL_SECTION X11DRV_CritSection;
61 static CRITICAL_SECTION_DEBUG critsect_debug =
63 0, 0, &X11DRV_CritSection,
64 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
65 0, 0, { (DWORD_PTR)(__FILE__ ": X11DRV_CritSection") }
67 static CRITICAL_SECTION X11DRV_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };
69 Screen *screen;
70 Visual *visual;
71 unsigned int screen_width;
72 unsigned int screen_height;
73 unsigned int screen_bpp;
74 unsigned int screen_depth;
75 RECT virtual_screen_rect;
76 Window root_window;
77 int dxgrab = 0;
78 int usexvidmode = 1;
79 int usexrandr = 1;
80 int usexcomposite = 1;
81 int use_xkb = 1;
82 int use_take_focus = 1;
83 int use_primary_selection = 0;
84 int managed_mode = 1;
85 int decorated_mode = 1;
86 int private_color_map = 0;
87 int primary_monitor = 0;
88 int client_side_with_core = 1;
89 int client_side_with_render = 1;
90 int client_side_antialias_with_core = 1;
91 int client_side_antialias_with_render = 1;
92 int copy_default_colors = 128;
93 int alloc_system_colors = 256;
94 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
95 int xrender_error_base = 0;
96 HMODULE x11drv_module = 0;
98 static x11drv_error_callback err_callback; /* current callback for error */
99 static Display *err_callback_display; /* display callback is set for */
100 static void *err_callback_arg; /* error callback argument */
101 static int err_callback_result; /* error callback result */
102 static unsigned long err_serial; /* serial number of first request */
103 static int (*old_error_handler)( Display *, XErrorEvent * );
104 static int use_xim = 1;
105 static char input_style[20];
107 #define IS_OPTION_TRUE(ch) \
108 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
109 #define IS_OPTION_FALSE(ch) \
110 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
112 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
114 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
116 "CLIPBOARD",
117 "COMPOUND_TEXT",
118 "INCR",
119 "MULTIPLE",
120 "SELECTION_DATA",
121 "TARGETS",
122 "TEXT",
123 "UTF8_STRING",
124 "RAW_ASCENT",
125 "RAW_DESCENT",
126 "RAW_CAP_HEIGHT",
127 "WM_PROTOCOLS",
128 "WM_DELETE_WINDOW",
129 "WM_STATE",
130 "WM_TAKE_FOCUS",
131 "DndProtocol",
132 "DndSelection",
133 "_ICC_PROFILE",
134 "_MOTIF_WM_HINTS",
135 "_NET_SUPPORTED",
136 "_NET_SYSTEM_TRAY_OPCODE",
137 "_NET_SYSTEM_TRAY_S0",
138 "_NET_WM_MOVERESIZE",
139 "_NET_WM_NAME",
140 "_NET_WM_PID",
141 "_NET_WM_PING",
142 "_NET_WM_STATE",
143 "_NET_WM_STATE_ABOVE",
144 "_NET_WM_STATE_FULLSCREEN",
145 "_NET_WM_STATE_MAXIMIZED_HORZ",
146 "_NET_WM_STATE_MAXIMIZED_VERT",
147 "_NET_WM_STATE_SKIP_PAGER",
148 "_NET_WM_STATE_SKIP_TASKBAR",
149 "_NET_WM_WINDOW_OPACITY",
150 "_NET_WM_WINDOW_TYPE",
151 "_NET_WM_WINDOW_TYPE_DIALOG",
152 "_NET_WM_WINDOW_TYPE_NORMAL",
153 "_NET_WM_WINDOW_TYPE_UTILITY",
154 "_NET_WORKAREA",
155 "_XEMBED_INFO",
156 "XdndAware",
157 "XdndEnter",
158 "XdndPosition",
159 "XdndStatus",
160 "XdndLeave",
161 "XdndFinished",
162 "XdndDrop",
163 "XdndActionCopy",
164 "XdndActionMove",
165 "XdndActionLink",
166 "XdndActionAsk",
167 "XdndActionPrivate",
168 "XdndSelection",
169 "XdndTarget",
170 "XdndTypeList",
171 "WCF_DIB",
172 "image/gif",
173 "text/html",
174 "text/plain",
175 "text/rtf",
176 "text/richtext",
177 "text/uri-list"
180 /***********************************************************************
181 * ignore_error
183 * Check if the X error is one we can ignore.
185 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
187 if (event->request_code == X_SetInputFocus && event->error_code == BadMatch) return TRUE;
189 /* ignore a number of errors on gdi display caused by creating/destroying windows */
190 if (display == gdi_display)
192 if (event->error_code == BadDrawable || event->error_code == BadGC) return TRUE;
193 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
194 if (xrender_error_base) /* check for XRender errors */
196 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
198 #endif
200 return FALSE;
204 /***********************************************************************
205 * X11DRV_expect_error
207 * Setup a callback function that will be called on an X error. The
208 * callback must return non-zero if the error is the one it expected.
209 * This function acquires the x11 lock; X11DRV_check_error must be
210 * called in all cases to release it.
212 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
214 wine_tsx11_lock();
215 err_callback = callback;
216 err_callback_display = display;
217 err_callback_arg = arg;
218 err_callback_result = 0;
219 err_serial = NextRequest(display);
223 /***********************************************************************
224 * X11DRV_check_error
226 * Check if an expected X11 error occurred; return non-zero if yes.
227 * Also release the x11 lock obtained in X11DRV_expect_error.
228 * The caller is responsible for calling XSync first if necessary.
230 int X11DRV_check_error(void)
232 int ret;
233 err_callback = NULL;
234 ret = err_callback_result;
235 wine_tsx11_unlock();
236 return ret;
240 /***********************************************************************
241 * error_handler
243 static int error_handler( Display *display, XErrorEvent *error_evt )
245 if (err_callback && display == err_callback_display &&
246 (long)(error_evt->serial - err_serial) >= 0)
248 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
250 TRACE( "got expected error %d req %d\n",
251 error_evt->error_code, error_evt->request_code );
252 return 0;
255 if (ignore_error( display, error_evt ))
257 TRACE( "got ignored error %d req %d\n",
258 error_evt->error_code, error_evt->request_code );
259 return 0;
261 if (TRACE_ON(synchronous))
263 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
264 error_evt->serial, error_evt->request_code );
265 DebugBreak(); /* force an entry in the debugger */
267 old_error_handler( display, error_evt );
268 return 0;
271 /***********************************************************************
272 * wine_tsx11_lock (X11DRV.@)
274 void CDECL wine_tsx11_lock(void)
276 EnterCriticalSection( &X11DRV_CritSection );
279 /***********************************************************************
280 * wine_tsx11_unlock (X11DRV.@)
282 void CDECL wine_tsx11_unlock(void)
284 LeaveCriticalSection( &X11DRV_CritSection );
288 /***********************************************************************
289 * depth_to_bpp
291 * Convert X11-reported depth to the BPP value that Windows apps expect to see.
293 unsigned int depth_to_bpp( unsigned int depth )
295 switch (depth)
297 case 1:
298 case 8:
299 return depth;
300 case 15:
301 case 16:
302 return 16;
303 case 24:
304 /* This is not necessarily right. X11 always has 24 bits per pixel, but it can run
305 * with 24 bit framebuffers and 32 bit framebuffers. It doesn't make any difference
306 * for windowing, but gl applications can get visuals with alpha channels. So we
307 * should check the framebuffer and/or opengl formats available to find out what the
308 * framebuffer actually does
310 case 32:
311 return 32;
312 default:
313 FIXME( "Unexpected X11 depth %d bpp, what to report to app?\n", depth );
314 return depth;
319 /***********************************************************************
320 * get_config_key
322 * Get a config key from either the app-specific or the default config
324 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
325 char *buffer, DWORD size )
327 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
328 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
329 return ERROR_FILE_NOT_FOUND;
333 /***********************************************************************
334 * setup_options
336 * Setup the x11drv options.
338 static void setup_options(void)
340 char buffer[MAX_PATH+16];
341 HKEY hkey, appkey = 0;
342 DWORD len;
344 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
345 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
347 /* open the app-specific key */
349 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
350 if (len && len < MAX_PATH)
352 HKEY tmpkey;
353 char *p, *appname = buffer;
354 if ((p = strrchr( appname, '/' ))) appname = p + 1;
355 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
356 strcat( appname, "\\X11 Driver" );
357 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
358 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
360 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
361 RegCloseKey( tmpkey );
365 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
366 managed_mode = IS_OPTION_TRUE( buffer[0] );
368 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
369 decorated_mode = IS_OPTION_TRUE( buffer[0] );
371 if (!get_config_key( hkey, appkey, "DXGrab", buffer, sizeof(buffer) ))
372 dxgrab = IS_OPTION_TRUE( buffer[0] );
374 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
375 usexvidmode = IS_OPTION_TRUE( buffer[0] );
377 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
378 usexrandr = IS_OPTION_TRUE( buffer[0] );
380 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
381 use_take_focus = IS_OPTION_TRUE( buffer[0] );
383 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
384 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
386 screen_depth = 0;
387 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
388 screen_depth = atoi(buffer);
390 if (!get_config_key( hkey, appkey, "ClientSideWithCore", buffer, sizeof(buffer) ))
391 client_side_with_core = IS_OPTION_TRUE( buffer[0] );
393 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
394 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
396 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithCore", buffer, sizeof(buffer) ))
397 client_side_antialias_with_core = IS_OPTION_TRUE( buffer[0] );
399 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithRender", buffer, sizeof(buffer) ))
400 client_side_antialias_with_render = IS_OPTION_TRUE( buffer[0] );
402 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
403 use_xim = IS_OPTION_TRUE( buffer[0] );
405 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
406 private_color_map = IS_OPTION_TRUE( buffer[0] );
408 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
409 primary_monitor = atoi( buffer );
411 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
412 copy_default_colors = atoi(buffer);
414 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
415 alloc_system_colors = atoi(buffer);
417 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
419 if (appkey) RegCloseKey( appkey );
420 if (hkey) RegCloseKey( hkey );
423 #ifdef SONAME_LIBXCOMPOSITE
425 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
426 MAKE_FUNCPTR(XCompositeQueryExtension)
427 MAKE_FUNCPTR(XCompositeQueryVersion)
428 MAKE_FUNCPTR(XCompositeVersion)
429 MAKE_FUNCPTR(XCompositeRedirectWindow)
430 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
431 MAKE_FUNCPTR(XCompositeUnredirectWindow)
432 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
433 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
434 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
435 #undef MAKE_FUNCPTR
437 static int xcomp_event_base;
438 static int xcomp_error_base;
440 static void X11DRV_XComposite_Init(void)
442 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
443 if (!xcomposite_handle)
445 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
446 usexcomposite = 0;
447 return;
450 #define LOAD_FUNCPTR(f) \
451 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
452 goto sym_not_found;
453 LOAD_FUNCPTR(XCompositeQueryExtension)
454 LOAD_FUNCPTR(XCompositeQueryVersion)
455 LOAD_FUNCPTR(XCompositeVersion)
456 LOAD_FUNCPTR(XCompositeRedirectWindow)
457 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
458 LOAD_FUNCPTR(XCompositeUnredirectWindow)
459 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
460 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
461 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
462 #undef LOAD_FUNCPTR
464 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
465 &xcomp_error_base)) {
466 TRACE("XComposite extension could not be queried; disabled\n");
467 wine_dlclose(xcomposite_handle, NULL, 0);
468 xcomposite_handle = NULL;
469 usexcomposite = 0;
470 return;
472 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
473 return;
475 sym_not_found:
476 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
477 wine_dlclose(xcomposite_handle, NULL, 0);
478 xcomposite_handle = NULL;
479 usexcomposite = 0;
481 #endif /* defined(SONAME_LIBXCOMPOSITE) */
484 /***********************************************************************
485 * X11DRV process initialisation routine
487 static BOOL process_attach(void)
489 Display *display;
491 setup_options();
493 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
495 /* Open display */
497 if (!(display = XOpenDisplay( NULL ))) return FALSE;
499 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
500 screen = DefaultScreenOfDisplay( display );
501 visual = DefaultVisual( display, DefaultScreen(display) );
502 root_window = DefaultRootWindow( display );
503 gdi_display = display;
504 old_error_handler = XSetErrorHandler( error_handler );
506 /* Initialize screen depth */
508 if (screen_depth) /* depth specified */
510 int depth_count, i;
511 int *depth_list = XListDepths(display, DefaultScreen(display), &depth_count);
512 for (i = 0; i < depth_count; i++)
513 if (depth_list[i] == screen_depth) break;
514 XFree( depth_list );
515 if (i >= depth_count)
517 WARN( "invalid depth %d, using default\n", screen_depth );
518 screen_depth = 0;
521 if (!screen_depth) screen_depth = DefaultDepthOfScreen( screen );
522 screen_bpp = depth_to_bpp( screen_depth );
524 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
526 if (TRACE_ON(synchronous)) XSynchronize( display, True );
528 xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
529 X11DRV_Settings_Init();
531 #ifdef SONAME_LIBXXF86VM
532 /* initialize XVidMode */
533 X11DRV_XF86VM_Init();
534 #endif
535 #ifdef SONAME_LIBXRANDR
536 /* initialize XRandR */
537 X11DRV_XRandR_Init();
538 #endif
539 #ifdef SONAME_LIBXCOMPOSITE
540 X11DRV_XComposite_Init();
541 #endif
543 #ifdef HAVE_XKB
544 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
545 #endif
546 X11DRV_InitKeyboard( gdi_display );
547 X11DRV_InitClipboard();
548 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
550 return TRUE;
554 /***********************************************************************
555 * X11DRV thread termination routine
557 static void thread_detach(void)
559 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
561 if (data)
563 X11DRV_ResetSelectionOwner();
564 wine_tsx11_lock();
565 if (data->xim) XCloseIM( data->xim );
566 if (data->font_set) XFreeFontSet( data->display, data->font_set );
567 XCloseDisplay( data->display );
568 wine_tsx11_unlock();
569 HeapFree( GetProcessHeap(), 0, data );
574 /***********************************************************************
575 * X11DRV process termination routine
577 static void process_detach(void)
579 #ifdef SONAME_LIBXXF86VM
580 /* cleanup XVidMode */
581 X11DRV_XF86VM_Cleanup();
582 #endif
583 if(using_client_side_fonts)
584 X11DRV_XRender_Finalize();
586 /* cleanup GDI */
587 X11DRV_GDI_Finalize();
589 IME_UnregisterClasses();
590 DeleteCriticalSection( &X11DRV_CritSection );
591 TlsFree( thread_data_tls_index );
595 /* store the display fd into the message queue */
596 static void set_queue_display_fd( Display *display )
598 HANDLE handle;
599 int ret;
601 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
603 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
604 ExitProcess(1);
606 SERVER_START_REQ( set_queue_fd )
608 req->handle = wine_server_obj_handle( handle );
609 ret = wine_server_call( req );
611 SERVER_END_REQ;
612 if (ret)
614 MESSAGE( "x11drv: Can't store handle for display fd\n" );
615 ExitProcess(1);
617 CloseHandle( handle );
621 /***********************************************************************
622 * X11DRV thread initialisation routine
624 struct x11drv_thread_data *x11drv_init_thread_data(void)
626 struct x11drv_thread_data *data = x11drv_thread_data();
628 if (data) return data;
630 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
632 ERR( "could not create data\n" );
633 ExitProcess(1);
635 wine_tsx11_lock();
636 if (!(data->display = XOpenDisplay(NULL)))
638 wine_tsx11_unlock();
639 MESSAGE( "x11drv: Can't open display: %s\n", XDisplayName(NULL) );
640 MESSAGE( "Please ensure that your X server is running and that $DISPLAY is set correctly.\n" );
641 ExitProcess(1);
644 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
646 #ifdef HAVE_XKB
647 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
648 XkbSetDetectableAutoRepeat( data->display, True, NULL );
649 #endif
651 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
652 wine_tsx11_unlock();
654 set_queue_display_fd( data->display );
655 TlsSetValue( thread_data_tls_index, data );
657 if (use_xim) X11DRV_SetupXIM();
658 X11DRV_SetCursor( NULL );
660 return data;
664 /***********************************************************************
665 * X11DRV initialisation routine
667 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
669 BOOL ret = TRUE;
671 switch(reason)
673 case DLL_PROCESS_ATTACH:
674 x11drv_module = hinst;
675 ret = process_attach();
676 break;
677 case DLL_THREAD_DETACH:
678 thread_detach();
679 break;
680 case DLL_PROCESS_DETACH:
681 process_detach();
682 break;
684 return ret;
687 /***********************************************************************
688 * GetScreenSaveActive (X11DRV.@)
690 * Returns the active status of the screen saver
692 BOOL CDECL X11DRV_GetScreenSaveActive(void)
694 int timeout, temp;
695 wine_tsx11_lock();
696 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
697 wine_tsx11_unlock();
698 return timeout != 0;
701 /***********************************************************************
702 * SetScreenSaveActive (X11DRV.@)
704 * Activate/Deactivate the screen saver
706 void CDECL X11DRV_SetScreenSaveActive(BOOL bActivate)
708 int timeout, interval, prefer_blanking, allow_exposures;
709 static int last_timeout = 15 * 60;
711 wine_tsx11_lock();
712 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
713 &allow_exposures);
714 if (timeout) last_timeout = timeout;
716 timeout = bActivate ? last_timeout : 0;
717 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
718 allow_exposures);
719 wine_tsx11_unlock();