wined3d: Fix missing break inside switch in SetAutoGenFilterType.
[wine.git] / dlls / winex11.drv / x11drv_main.c
blob9d64a85dc4f808b2315c1238e745bc735aa9b640
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;
97 static x11drv_error_callback err_callback; /* current callback for error */
98 static Display *err_callback_display; /* display callback is set for */
99 static void *err_callback_arg; /* error callback argument */
100 static int err_callback_result; /* error callback result */
101 static unsigned long err_serial; /* serial number of first request */
102 static int (*old_error_handler)( Display *, XErrorEvent * );
103 static int use_xim = 1;
104 static char input_style[20];
106 #define IS_OPTION_TRUE(ch) \
107 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
108 #define IS_OPTION_FALSE(ch) \
109 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
111 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
113 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
115 "CLIPBOARD",
116 "COMPOUND_TEXT",
117 "MULTIPLE",
118 "SELECTION_DATA",
119 "TARGETS",
120 "TEXT",
121 "UTF8_STRING",
122 "RAW_ASCENT",
123 "RAW_DESCENT",
124 "RAW_CAP_HEIGHT",
125 "WM_PROTOCOLS",
126 "WM_DELETE_WINDOW",
127 "WM_STATE",
128 "WM_TAKE_FOCUS",
129 "DndProtocol",
130 "DndSelection",
131 "_ICC_PROFILE",
132 "_MOTIF_WM_HINTS",
133 "_NET_SUPPORTED",
134 "_NET_SYSTEM_TRAY_OPCODE",
135 "_NET_SYSTEM_TRAY_S0",
136 "_NET_WM_MOVERESIZE",
137 "_NET_WM_NAME",
138 "_NET_WM_PID",
139 "_NET_WM_PING",
140 "_NET_WM_STATE",
141 "_NET_WM_STATE_ABOVE",
142 "_NET_WM_STATE_FULLSCREEN",
143 "_NET_WM_STATE_MAXIMIZED_HORZ",
144 "_NET_WM_STATE_MAXIMIZED_VERT",
145 "_NET_WM_STATE_SKIP_PAGER",
146 "_NET_WM_STATE_SKIP_TASKBAR",
147 "_NET_WM_WINDOW_TYPE",
148 "_NET_WM_WINDOW_TYPE_DIALOG",
149 "_NET_WM_WINDOW_TYPE_NORMAL",
150 "_NET_WM_WINDOW_TYPE_UTILITY",
151 "_XEMBED_INFO",
152 "XdndAware",
153 "XdndEnter",
154 "XdndPosition",
155 "XdndStatus",
156 "XdndLeave",
157 "XdndFinished",
158 "XdndDrop",
159 "XdndActionCopy",
160 "XdndActionMove",
161 "XdndActionLink",
162 "XdndActionAsk",
163 "XdndActionPrivate",
164 "XdndSelection",
165 "XdndTarget",
166 "XdndTypeList",
167 "WCF_DIB",
168 "image/gif",
169 "text/html",
170 "text/plain",
171 "text/rtf",
172 "text/richtext",
173 "text/uri-list"
176 /***********************************************************************
177 * ignore_error
179 * Check if the X error is one we can ignore.
181 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
183 if (event->request_code == X_SetInputFocus && event->error_code == BadMatch) return TRUE;
185 /* ignore a number of errors on gdi display caused by creating/destroying windows */
186 if (display == gdi_display)
188 if (event->error_code == BadDrawable || event->error_code == BadGC) return TRUE;
189 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
190 if (xrender_error_base) /* check for XRender errors */
192 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
194 #endif
196 return FALSE;
200 /***********************************************************************
201 * X11DRV_expect_error
203 * Setup a callback function that will be called on an X error. The
204 * callback must return non-zero if the error is the one it expected.
205 * This function acquires the x11 lock; X11DRV_check_error must be
206 * called in all cases to release it.
208 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
210 wine_tsx11_lock();
211 err_callback = callback;
212 err_callback_display = display;
213 err_callback_arg = arg;
214 err_callback_result = 0;
215 err_serial = NextRequest(display);
219 /***********************************************************************
220 * X11DRV_check_error
222 * Check if an expected X11 error occurred; return non-zero if yes.
223 * Also release the x11 lock obtained in X11DRV_expect_error.
224 * The caller is responsible for calling XSync first if necessary.
226 int X11DRV_check_error(void)
228 int ret;
229 err_callback = NULL;
230 ret = err_callback_result;
231 wine_tsx11_unlock();
232 return ret;
236 /***********************************************************************
237 * error_handler
239 static int error_handler( Display *display, XErrorEvent *error_evt )
241 if (err_callback && display == err_callback_display &&
242 (long)(error_evt->serial - err_serial) >= 0)
244 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
246 TRACE( "got expected error %d req %d\n",
247 error_evt->error_code, error_evt->request_code );
248 return 0;
251 if (ignore_error( display, error_evt ))
253 TRACE( "got ignored error %d req %d\n",
254 error_evt->error_code, error_evt->request_code );
255 return 0;
257 if (TRACE_ON(synchronous))
259 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
260 error_evt->serial, error_evt->request_code );
261 DebugBreak(); /* force an entry in the debugger */
263 old_error_handler( display, error_evt );
264 return 0;
267 /***********************************************************************
268 * wine_tsx11_lock (X11DRV.@)
270 void wine_tsx11_lock(void)
272 EnterCriticalSection( &X11DRV_CritSection );
275 /***********************************************************************
276 * wine_tsx11_unlock (X11DRV.@)
278 void wine_tsx11_unlock(void)
280 LeaveCriticalSection( &X11DRV_CritSection );
284 /***********************************************************************
285 * depth_to_bpp
287 * Convert X11-reported depth to the BPP value that Windows apps expect to see.
289 unsigned int depth_to_bpp( unsigned int depth )
291 switch (depth)
293 case 1:
294 case 8:
295 return depth;
296 case 15:
297 case 16:
298 return 16;
299 case 24:
300 /* This is not necessarily right. X11 always has 24 bits per pixel, but it can run
301 * with 24 bit framebuffers and 32 bit framebuffers. It doesn't make any difference
302 * for windowing, but gl applications can get visuals with alpha channels. So we
303 * should check the framebuffer and/or opengl formats available to find out what the
304 * framebuffer actually does
306 case 32:
307 return 32;
308 default:
309 FIXME( "Unexpected X11 depth %d bpp, what to report to app?\n", depth );
310 return depth;
315 /***********************************************************************
316 * get_config_key
318 * Get a config key from either the app-specific or the default config
320 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
321 char *buffer, DWORD size )
323 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
324 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
325 return ERROR_FILE_NOT_FOUND;
329 /***********************************************************************
330 * setup_options
332 * Setup the x11drv options.
334 static void setup_options(void)
336 char buffer[MAX_PATH+16];
337 HKEY hkey, appkey = 0;
338 DWORD len;
340 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
341 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
343 /* open the app-specific key */
345 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
346 if (len && len < MAX_PATH)
348 HKEY tmpkey;
349 char *p, *appname = buffer;
350 if ((p = strrchr( appname, '/' ))) appname = p + 1;
351 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
352 strcat( appname, "\\X11 Driver" );
353 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
354 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
356 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
357 RegCloseKey( tmpkey );
361 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
362 managed_mode = IS_OPTION_TRUE( buffer[0] );
364 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
365 decorated_mode = IS_OPTION_TRUE( buffer[0] );
367 if (!get_config_key( hkey, appkey, "DXGrab", buffer, sizeof(buffer) ))
368 dxgrab = IS_OPTION_TRUE( buffer[0] );
370 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
371 usexvidmode = IS_OPTION_TRUE( buffer[0] );
373 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
374 usexrandr = IS_OPTION_TRUE( buffer[0] );
376 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
377 use_take_focus = IS_OPTION_TRUE( buffer[0] );
379 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
380 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
382 screen_depth = 0;
383 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
384 screen_depth = atoi(buffer);
386 if (!get_config_key( hkey, appkey, "ClientSideWithCore", buffer, sizeof(buffer) ))
387 client_side_with_core = IS_OPTION_TRUE( buffer[0] );
389 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
390 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
392 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithCore", buffer, sizeof(buffer) ))
393 client_side_antialias_with_core = IS_OPTION_TRUE( buffer[0] );
395 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithRender", buffer, sizeof(buffer) ))
396 client_side_antialias_with_render = IS_OPTION_TRUE( buffer[0] );
398 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
399 use_xim = IS_OPTION_TRUE( buffer[0] );
401 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
402 private_color_map = IS_OPTION_TRUE( buffer[0] );
404 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
405 primary_monitor = atoi( buffer );
407 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
408 copy_default_colors = atoi(buffer);
410 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
411 alloc_system_colors = atoi(buffer);
413 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
415 if (appkey) RegCloseKey( appkey );
416 if (hkey) RegCloseKey( hkey );
419 #ifdef SONAME_LIBXCOMPOSITE
421 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
422 MAKE_FUNCPTR(XCompositeQueryExtension)
423 MAKE_FUNCPTR(XCompositeQueryVersion)
424 MAKE_FUNCPTR(XCompositeVersion)
425 MAKE_FUNCPTR(XCompositeRedirectWindow)
426 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
427 MAKE_FUNCPTR(XCompositeUnredirectWindow)
428 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
429 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
430 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
431 #undef MAKE_FUNCPTR
433 static int xcomp_event_base;
434 static int xcomp_error_base;
436 static void X11DRV_XComposite_Init(void)
438 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
439 if (!xcomposite_handle)
441 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
442 usexcomposite = 0;
443 return;
446 #define LOAD_FUNCPTR(f) \
447 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
448 goto sym_not_found;
449 LOAD_FUNCPTR(XCompositeQueryExtension)
450 LOAD_FUNCPTR(XCompositeQueryVersion)
451 LOAD_FUNCPTR(XCompositeVersion)
452 LOAD_FUNCPTR(XCompositeRedirectWindow)
453 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
454 LOAD_FUNCPTR(XCompositeUnredirectWindow)
455 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
456 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
457 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
458 #undef LOAD_FUNCPTR
460 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
461 &xcomp_error_base)) {
462 TRACE("XComposite extension could not be queried; disabled\n");
463 wine_dlclose(xcomposite_handle, NULL, 0);
464 xcomposite_handle = NULL;
465 usexcomposite = 0;
466 return;
468 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
469 return;
471 sym_not_found:
472 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
473 wine_dlclose(xcomposite_handle, NULL, 0);
474 xcomposite_handle = NULL;
475 usexcomposite = 0;
477 #endif /* defined(SONAME_LIBXCOMPOSITE) */
480 /***********************************************************************
481 * X11DRV process initialisation routine
483 static BOOL process_attach(void)
485 Display *display;
486 const char *env;
488 setup_options();
490 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
492 /* Open display */
494 if (!(env = getenv("XMODIFIERS")) || !*env) /* try to avoid the Xlib XIM locking bug */
495 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
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 HAVE_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 X11DRV_InitKeyboard( gdi_display );
544 X11DRV_InitClipboard();
545 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
547 return TRUE;
551 /***********************************************************************
552 * X11DRV thread termination routine
554 static void thread_detach(void)
556 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
558 if (data)
560 X11DRV_ResetSelectionOwner();
561 wine_tsx11_lock();
562 if (data->xim) XCloseIM( data->xim );
563 XCloseDisplay( data->display );
564 wine_tsx11_unlock();
565 HeapFree( GetProcessHeap(), 0, data );
570 /***********************************************************************
571 * X11DRV process termination routine
573 static void process_detach(void)
575 #ifdef HAVE_LIBXXF86VM
576 /* cleanup XVidMode */
577 X11DRV_XF86VM_Cleanup();
578 #endif
579 if(using_client_side_fonts)
580 X11DRV_XRender_Finalize();
582 /* cleanup GDI */
583 X11DRV_GDI_Finalize();
585 DeleteCriticalSection( &X11DRV_CritSection );
586 TlsFree( thread_data_tls_index );
590 /* store the display fd into the message queue */
591 static void set_queue_display_fd( Display *display )
593 HANDLE handle;
594 int ret;
596 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
598 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
599 ExitProcess(1);
601 SERVER_START_REQ( set_queue_fd )
603 req->handle = handle;
604 ret = wine_server_call( req );
606 SERVER_END_REQ;
607 if (ret)
609 MESSAGE( "x11drv: Can't store handle for display fd\n" );
610 ExitProcess(1);
612 CloseHandle( handle );
616 /***********************************************************************
617 * X11DRV thread initialisation routine
619 struct x11drv_thread_data *x11drv_init_thread_data(void)
621 struct x11drv_thread_data *data;
623 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
625 ERR( "could not create data\n" );
626 ExitProcess(1);
628 wine_tsx11_lock();
629 if (!(data->display = XOpenDisplay(NULL)))
631 wine_tsx11_unlock();
632 MESSAGE( "x11drv: Can't open display: %s\n", XDisplayName(NULL) );
633 MESSAGE( "Please ensure that your X server is running and that $DISPLAY is set correctly.\n" );
634 ExitProcess(1);
637 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
639 #ifdef HAVE_XKB
640 if (use_xkb)
642 use_xkb = XkbUseExtension( data->display, NULL, NULL );
643 if (use_xkb)
645 /* Hack: dummy call to XkbKeysymToModifiers to force initialisation of Xkb internals */
646 /* This works around an Xlib bug where it tries to get the display lock */
647 /* twice during XFilterEvents if Xkb hasn't been initialised yet. */
648 XkbKeysymToModifiers( data->display, 'A' );
649 XkbSetDetectableAutoRepeat( data->display, True, NULL );
652 #endif
654 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
655 wine_tsx11_unlock();
657 set_queue_display_fd( data->display );
658 TlsSetValue( thread_data_tls_index, data );
660 if (use_xim) X11DRV_SetupXIM();
661 X11DRV_SetCursor( NULL );
663 return data;
667 /***********************************************************************
668 * X11DRV initialisation routine
670 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
672 BOOL ret = TRUE;
674 switch(reason)
676 case DLL_PROCESS_ATTACH:
677 ret = process_attach();
678 IME_RegisterClasses(hinst);
679 break;
680 case DLL_THREAD_DETACH:
681 thread_detach();
682 break;
683 case DLL_PROCESS_DETACH:
684 process_detach();
685 IME_UnregisterClasses(hinst);
686 break;
688 return ret;
691 /***********************************************************************
692 * GetScreenSaveActive (X11DRV.@)
694 * Returns the active status of the screen saver
696 BOOL X11DRV_GetScreenSaveActive(void)
698 int timeout, temp;
699 wine_tsx11_lock();
700 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
701 wine_tsx11_unlock();
702 return timeout != 0;
705 /***********************************************************************
706 * SetScreenSaveActive (X11DRV.@)
708 * Activate/Deactivate the screen saver
710 void X11DRV_SetScreenSaveActive(BOOL bActivate)
712 int timeout, interval, prefer_blanking, allow_exposures;
713 static int last_timeout = 15 * 60;
715 wine_tsx11_lock();
716 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
717 &allow_exposures);
718 if (timeout) last_timeout = timeout;
720 timeout = bActivate ? last_timeout : 0;
721 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
722 allow_exposures);
723 wine_tsx11_unlock();