gdi32: GetCharABCWidthsA should work for DBCS.
[wine/multimedia.git] / dlls / winex11.drv / x11drv_main.c
blob54f56b9009e3cf2ae7690325d3e5dfcdde4c1f4a
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);
59 WINE_DECLARE_DEBUG_CHANNEL(winediag);
61 static CRITICAL_SECTION X11DRV_CritSection;
62 static CRITICAL_SECTION_DEBUG critsect_debug =
64 0, 0, &X11DRV_CritSection,
65 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
66 0, 0, { (DWORD_PTR)(__FILE__ ": X11DRV_CritSection") }
68 static CRITICAL_SECTION X11DRV_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };
70 Screen *screen;
71 Visual *visual;
72 unsigned int screen_width;
73 unsigned int screen_height;
74 unsigned int screen_bpp;
75 unsigned int screen_depth;
76 RECT virtual_screen_rect;
77 Window root_window;
78 int dxgrab = 0;
79 int usexvidmode = 1;
80 int usexrandr = 1;
81 int usexcomposite = 1;
82 int use_xkb = 1;
83 int use_take_focus = 1;
84 int use_primary_selection = 0;
85 int use_system_cursors = 1;
86 int show_systray = 1;
87 int managed_mode = 1;
88 int decorated_mode = 1;
89 int private_color_map = 0;
90 int primary_monitor = 0;
91 int client_side_with_core = 1;
92 int client_side_with_render = 1;
93 int client_side_antialias_with_core = 1;
94 int client_side_antialias_with_render = 1;
95 int copy_default_colors = 128;
96 int alloc_system_colors = 256;
97 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
98 int xrender_error_base = 0;
99 HMODULE x11drv_module = 0;
101 static x11drv_error_callback err_callback; /* current callback for error */
102 static Display *err_callback_display; /* display callback is set for */
103 static void *err_callback_arg; /* error callback argument */
104 static int err_callback_result; /* error callback result */
105 static unsigned long err_serial; /* serial number of first request */
106 static int (*old_error_handler)( Display *, XErrorEvent * );
107 static int use_xim = 1;
108 static char input_style[20];
110 #define IS_OPTION_TRUE(ch) \
111 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
112 #define IS_OPTION_FALSE(ch) \
113 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
115 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
117 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
119 "CLIPBOARD",
120 "COMPOUND_TEXT",
121 "INCR",
122 "MANAGER",
123 "MULTIPLE",
124 "SELECTION_DATA",
125 "TARGETS",
126 "TEXT",
127 "UTF8_STRING",
128 "RAW_ASCENT",
129 "RAW_DESCENT",
130 "RAW_CAP_HEIGHT",
131 "WM_PROTOCOLS",
132 "WM_DELETE_WINDOW",
133 "WM_STATE",
134 "WM_TAKE_FOCUS",
135 "DndProtocol",
136 "DndSelection",
137 "_ICC_PROFILE",
138 "_MOTIF_WM_HINTS",
139 "_NET_STARTUP_INFO_BEGIN",
140 "_NET_STARTUP_INFO",
141 "_NET_SUPPORTED",
142 "_NET_SYSTEM_TRAY_OPCODE",
143 "_NET_SYSTEM_TRAY_S0",
144 "_NET_WM_ICON",
145 "_NET_WM_MOVERESIZE",
146 "_NET_WM_NAME",
147 "_NET_WM_PID",
148 "_NET_WM_PING",
149 "_NET_WM_STATE",
150 "_NET_WM_STATE_ABOVE",
151 "_NET_WM_STATE_FULLSCREEN",
152 "_NET_WM_STATE_MAXIMIZED_HORZ",
153 "_NET_WM_STATE_MAXIMIZED_VERT",
154 "_NET_WM_STATE_SKIP_PAGER",
155 "_NET_WM_STATE_SKIP_TASKBAR",
156 "_NET_WM_USER_TIME",
157 "_NET_WM_USER_TIME_WINDOW",
158 "_NET_WM_WINDOW_OPACITY",
159 "_NET_WM_WINDOW_TYPE",
160 "_NET_WM_WINDOW_TYPE_DIALOG",
161 "_NET_WM_WINDOW_TYPE_NORMAL",
162 "_NET_WM_WINDOW_TYPE_UTILITY",
163 "_NET_WORKAREA",
164 "_XEMBED",
165 "_XEMBED_INFO",
166 "XdndAware",
167 "XdndEnter",
168 "XdndPosition",
169 "XdndStatus",
170 "XdndLeave",
171 "XdndFinished",
172 "XdndDrop",
173 "XdndActionCopy",
174 "XdndActionMove",
175 "XdndActionLink",
176 "XdndActionAsk",
177 "XdndActionPrivate",
178 "XdndSelection",
179 "XdndTarget",
180 "XdndTypeList",
181 "HTML Format",
182 "WCF_DIB",
183 "image/gif",
184 "image/jpeg",
185 "image/png",
186 "text/html",
187 "text/plain",
188 "text/rtf",
189 "text/richtext",
190 "text/uri-list"
193 /***********************************************************************
194 * ignore_error
196 * Check if the X error is one we can ignore.
198 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
200 if ((event->request_code == X_SetInputFocus || event->request_code == X_ChangeWindowAttributes) &&
201 (event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE;
203 /* ignore a number of errors on gdi display caused by creating/destroying windows */
204 if (display == gdi_display)
206 if (event->error_code == BadDrawable ||
207 event->error_code == BadGC ||
208 event->error_code == BadWindow)
209 return TRUE;
210 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
211 if (xrender_error_base) /* check for XRender errors */
213 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
215 #endif
217 return FALSE;
221 /***********************************************************************
222 * X11DRV_expect_error
224 * Setup a callback function that will be called on an X error. The
225 * callback must return non-zero if the error is the one it expected.
226 * This function acquires the x11 lock; X11DRV_check_error must be
227 * called in all cases to release it.
229 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
231 wine_tsx11_lock();
232 err_callback = callback;
233 err_callback_display = display;
234 err_callback_arg = arg;
235 err_callback_result = 0;
236 err_serial = NextRequest(display);
240 /***********************************************************************
241 * X11DRV_check_error
243 * Check if an expected X11 error occurred; return non-zero if yes.
244 * Also release the x11 lock obtained in X11DRV_expect_error.
245 * The caller is responsible for calling XSync first if necessary.
247 int X11DRV_check_error(void)
249 int ret;
250 err_callback = NULL;
251 ret = err_callback_result;
252 wine_tsx11_unlock();
253 return ret;
257 /***********************************************************************
258 * error_handler
260 static int error_handler( Display *display, XErrorEvent *error_evt )
262 if (err_callback && display == err_callback_display &&
263 (long)(error_evt->serial - err_serial) >= 0)
265 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
267 TRACE( "got expected error %d req %d\n",
268 error_evt->error_code, error_evt->request_code );
269 return 0;
272 if (ignore_error( display, error_evt ))
274 TRACE( "got ignored error %d req %d\n",
275 error_evt->error_code, error_evt->request_code );
276 return 0;
278 if (TRACE_ON(synchronous))
280 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
281 error_evt->serial, error_evt->request_code );
282 DebugBreak(); /* force an entry in the debugger */
284 old_error_handler( display, error_evt );
285 return 0;
288 /***********************************************************************
289 * wine_tsx11_lock (X11DRV.@)
291 void CDECL wine_tsx11_lock(void)
293 EnterCriticalSection( &X11DRV_CritSection );
296 /***********************************************************************
297 * wine_tsx11_unlock (X11DRV.@)
299 void CDECL wine_tsx11_unlock(void)
301 LeaveCriticalSection( &X11DRV_CritSection );
305 /***********************************************************************
306 * depth_to_bpp
308 * Convert X11-reported depth to the BPP value that Windows apps expect to see.
310 unsigned int depth_to_bpp( unsigned int depth )
312 switch (depth)
314 case 1:
315 case 8:
316 return depth;
317 case 15:
318 case 16:
319 return 16;
320 case 24:
321 /* This is not necessarily right. X11 always has 24 bits per pixel, but it can run
322 * with 24 bit framebuffers and 32 bit framebuffers. It doesn't make any difference
323 * for windowing, but gl applications can get visuals with alpha channels. So we
324 * should check the framebuffer and/or opengl formats available to find out what the
325 * framebuffer actually does
327 case 32:
328 return 32;
329 default:
330 FIXME( "Unexpected X11 depth %d bpp, what to report to app?\n", depth );
331 return depth;
336 /***********************************************************************
337 * get_config_key
339 * Get a config key from either the app-specific or the default config
341 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
342 char *buffer, DWORD size )
344 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
345 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
346 return ERROR_FILE_NOT_FOUND;
350 /***********************************************************************
351 * setup_options
353 * Setup the x11drv options.
355 static void setup_options(void)
357 char buffer[MAX_PATH+16];
358 HKEY hkey, appkey = 0;
359 DWORD len;
361 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
362 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
364 /* open the app-specific key */
366 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
367 if (len && len < MAX_PATH)
369 HKEY tmpkey;
370 char *p, *appname = buffer;
371 if ((p = strrchr( appname, '/' ))) appname = p + 1;
372 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
373 strcat( appname, "\\X11 Driver" );
374 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
375 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
377 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
378 RegCloseKey( tmpkey );
382 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
383 managed_mode = IS_OPTION_TRUE( buffer[0] );
385 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
386 decorated_mode = IS_OPTION_TRUE( buffer[0] );
388 if (!get_config_key( hkey, appkey, "DXGrab", buffer, sizeof(buffer) ))
389 dxgrab = IS_OPTION_TRUE( buffer[0] );
391 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
392 usexvidmode = IS_OPTION_TRUE( buffer[0] );
394 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
395 usexrandr = IS_OPTION_TRUE( buffer[0] );
397 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
398 use_take_focus = IS_OPTION_TRUE( buffer[0] );
400 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
401 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
403 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
404 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
406 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
407 show_systray = IS_OPTION_TRUE( buffer[0] );
409 screen_depth = 0;
410 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
411 screen_depth = atoi(buffer);
413 if (!get_config_key( hkey, appkey, "ClientSideWithCore", buffer, sizeof(buffer) ))
414 client_side_with_core = IS_OPTION_TRUE( buffer[0] );
416 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
417 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
419 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithCore", buffer, sizeof(buffer) ))
420 client_side_antialias_with_core = IS_OPTION_TRUE( buffer[0] );
422 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithRender", buffer, sizeof(buffer) ))
423 client_side_antialias_with_render = IS_OPTION_TRUE( buffer[0] );
425 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
426 use_xim = IS_OPTION_TRUE( buffer[0] );
428 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
429 private_color_map = IS_OPTION_TRUE( buffer[0] );
431 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
432 primary_monitor = atoi( buffer );
434 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
435 copy_default_colors = atoi(buffer);
437 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
438 alloc_system_colors = atoi(buffer);
440 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
442 if (appkey) RegCloseKey( appkey );
443 if (hkey) RegCloseKey( hkey );
446 #ifdef SONAME_LIBXCOMPOSITE
448 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
449 MAKE_FUNCPTR(XCompositeQueryExtension)
450 MAKE_FUNCPTR(XCompositeQueryVersion)
451 MAKE_FUNCPTR(XCompositeVersion)
452 MAKE_FUNCPTR(XCompositeRedirectWindow)
453 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
454 MAKE_FUNCPTR(XCompositeUnredirectWindow)
455 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
456 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
457 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
458 #undef MAKE_FUNCPTR
460 static int xcomp_event_base;
461 static int xcomp_error_base;
463 static void X11DRV_XComposite_Init(void)
465 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
466 if (!xcomposite_handle)
468 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
469 usexcomposite = 0;
470 return;
473 #define LOAD_FUNCPTR(f) \
474 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
475 goto sym_not_found;
476 LOAD_FUNCPTR(XCompositeQueryExtension)
477 LOAD_FUNCPTR(XCompositeQueryVersion)
478 LOAD_FUNCPTR(XCompositeVersion)
479 LOAD_FUNCPTR(XCompositeRedirectWindow)
480 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
481 LOAD_FUNCPTR(XCompositeUnredirectWindow)
482 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
483 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
484 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
485 #undef LOAD_FUNCPTR
487 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
488 &xcomp_error_base)) {
489 TRACE("XComposite extension could not be queried; disabled\n");
490 wine_dlclose(xcomposite_handle, NULL, 0);
491 xcomposite_handle = NULL;
492 usexcomposite = 0;
493 return;
495 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
496 return;
498 sym_not_found:
499 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
500 wine_dlclose(xcomposite_handle, NULL, 0);
501 xcomposite_handle = NULL;
502 usexcomposite = 0;
504 #endif /* defined(SONAME_LIBXCOMPOSITE) */
507 /***********************************************************************
508 * X11DRV process initialisation routine
510 static BOOL process_attach(void)
512 Display *display;
514 setup_options();
516 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
518 /* Open display */
520 if (!(display = XOpenDisplay( NULL ))) return FALSE;
522 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
523 screen = DefaultScreenOfDisplay( display );
524 visual = DefaultVisual( display, DefaultScreen(display) );
525 root_window = DefaultRootWindow( display );
526 gdi_display = display;
527 old_error_handler = XSetErrorHandler( error_handler );
529 /* Initialize screen depth */
531 if (screen_depth) /* depth specified */
533 int depth_count, i;
534 int *depth_list = XListDepths(display, DefaultScreen(display), &depth_count);
535 for (i = 0; i < depth_count; i++)
536 if (depth_list[i] == screen_depth) break;
537 XFree( depth_list );
538 if (i >= depth_count)
540 WARN( "invalid depth %d, using default\n", screen_depth );
541 screen_depth = 0;
544 if (!screen_depth) screen_depth = DefaultDepthOfScreen( screen );
545 screen_bpp = depth_to_bpp( screen_depth );
547 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
549 if (TRACE_ON(synchronous)) XSynchronize( display, True );
551 xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
552 X11DRV_Settings_Init();
554 #ifdef SONAME_LIBXXF86VM
555 /* initialize XVidMode */
556 X11DRV_XF86VM_Init();
557 #endif
558 #ifdef SONAME_LIBXRANDR
559 /* initialize XRandR */
560 X11DRV_XRandR_Init();
561 #endif
562 #ifdef SONAME_LIBXCOMPOSITE
563 X11DRV_XComposite_Init();
564 #endif
566 #ifdef HAVE_XKB
567 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
568 #endif
569 X11DRV_InitKeyboard( gdi_display );
570 X11DRV_InitClipboard();
571 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
573 return TRUE;
577 /***********************************************************************
578 * X11DRV thread termination routine
580 static void thread_detach(void)
582 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
584 if (data)
586 X11DRV_ResetSelectionOwner();
587 wine_tsx11_lock();
588 if (data->xim) XCloseIM( data->xim );
589 if (data->font_set) XFreeFontSet( data->display, data->font_set );
590 XCloseDisplay( data->display );
591 wine_tsx11_unlock();
592 HeapFree( GetProcessHeap(), 0, data );
597 /***********************************************************************
598 * X11DRV process termination routine
600 static void process_detach(void)
602 X11DRV_Clipboard_Cleanup();
603 #ifdef SONAME_LIBXXF86VM
604 /* cleanup XVidMode */
605 X11DRV_XF86VM_Cleanup();
606 #endif
607 if(using_client_side_fonts)
608 X11DRV_XRender_Finalize();
610 /* cleanup GDI */
611 X11DRV_GDI_Finalize();
612 X11DRV_OpenGL_Cleanup();
614 IME_UnregisterClasses();
615 DeleteCriticalSection( &X11DRV_CritSection );
616 TlsFree( thread_data_tls_index );
620 /* store the display fd into the message queue */
621 static void set_queue_display_fd( Display *display )
623 HANDLE handle;
624 int ret;
626 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
628 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
629 ExitProcess(1);
631 SERVER_START_REQ( set_queue_fd )
633 req->handle = wine_server_obj_handle( handle );
634 ret = wine_server_call( req );
636 SERVER_END_REQ;
637 if (ret)
639 MESSAGE( "x11drv: Can't store handle for display fd\n" );
640 ExitProcess(1);
642 CloseHandle( handle );
646 /***********************************************************************
647 * X11DRV thread initialisation routine
649 struct x11drv_thread_data *x11drv_init_thread_data(void)
651 struct x11drv_thread_data *data = x11drv_thread_data();
653 if (data) return data;
655 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
657 ERR( "could not create data\n" );
658 ExitProcess(1);
660 wine_tsx11_lock();
661 if (!(data->display = XOpenDisplay(NULL)))
663 wine_tsx11_unlock();
664 ERR_(winediag)( "x11drv: Can't open display: %s. Please ensure that your X server is running and that $DISPLAY is set correctly.\n", XDisplayName(NULL));
665 ExitProcess(1);
668 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
670 #ifdef HAVE_XKB
671 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
672 XkbSetDetectableAutoRepeat( data->display, True, NULL );
673 #endif
675 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
676 wine_tsx11_unlock();
678 set_queue_display_fd( data->display );
679 TlsSetValue( thread_data_tls_index, data );
681 if (use_xim) X11DRV_SetupXIM();
683 return data;
687 /***********************************************************************
688 * X11DRV initialisation routine
690 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
692 BOOL ret = TRUE;
694 switch(reason)
696 case DLL_PROCESS_ATTACH:
697 x11drv_module = hinst;
698 ret = process_attach();
699 break;
700 case DLL_THREAD_DETACH:
701 thread_detach();
702 break;
703 case DLL_PROCESS_DETACH:
704 process_detach();
705 break;
707 return ret;
710 /***********************************************************************
711 * GetScreenSaveActive (X11DRV.@)
713 * Returns the active status of the screen saver
715 BOOL CDECL X11DRV_GetScreenSaveActive(void)
717 int timeout, temp;
718 wine_tsx11_lock();
719 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
720 wine_tsx11_unlock();
721 return timeout != 0;
724 /***********************************************************************
725 * SetScreenSaveActive (X11DRV.@)
727 * Activate/Deactivate the screen saver
729 void CDECL X11DRV_SetScreenSaveActive(BOOL bActivate)
731 int timeout, interval, prefer_blanking, allow_exposures;
732 static int last_timeout = 15 * 60;
734 wine_tsx11_lock();
735 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
736 &allow_exposures);
737 if (timeout) last_timeout = timeout;
739 timeout = bActivate ? last_timeout : 0;
740 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
741 allow_exposures);
742 wine_tsx11_unlock();