Add AppDefaults app selection to control panel
[wine/gsoc-2012-control.git] / dlls / winex11.drv / x11drv_main.c
blob8012df3f50fda9228215438e3f501408864dd4fb
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 "xcomposite.h"
51 #include "wine/server.h"
52 #include "wine/debug.h"
53 #include "wine/library.h"
55 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
56 WINE_DECLARE_DEBUG_CHANNEL(synchronous);
57 WINE_DECLARE_DEBUG_CHANNEL(winediag);
59 static CRITICAL_SECTION X11DRV_CritSection;
60 static CRITICAL_SECTION_DEBUG critsect_debug =
62 0, 0, &X11DRV_CritSection,
63 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
64 0, 0, { (DWORD_PTR)(__FILE__ ": X11DRV_CritSection") }
66 static CRITICAL_SECTION X11DRV_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };
68 static Screen *screen;
69 Visual *visual;
70 XPixmapFormatValues **pixmap_formats;
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 usexvidmode = 1;
78 int usexrandr = 1;
79 int usexcomposite = 1;
80 int use_xkb = 1;
81 int use_take_focus = 1;
82 int use_primary_selection = 0;
83 int use_system_cursors = 1;
84 int show_systray = 1;
85 int grab_pointer = 1;
86 int grab_fullscreen = 0;
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_render = 1;
92 int client_side_antialias_with_core = 1;
93 int client_side_antialias_with_render = 1;
94 int copy_default_colors = 128;
95 int alloc_system_colors = 256;
96 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
97 int xrender_error_base = 0;
98 HMODULE x11drv_module = 0;
100 static x11drv_error_callback err_callback; /* current callback for error */
101 static Display *err_callback_display; /* display callback is set for */
102 static void *err_callback_arg; /* error callback argument */
103 static int err_callback_result; /* error callback result */
104 static unsigned long err_serial; /* serial number of first request */
105 static int (*old_error_handler)( Display *, XErrorEvent * );
106 static int use_xim = 1;
107 static char input_style[20];
109 #define IS_OPTION_TRUE(ch) \
110 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
111 #define IS_OPTION_FALSE(ch) \
112 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
114 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
116 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
118 "CLIPBOARD",
119 "COMPOUND_TEXT",
120 "INCR",
121 "MANAGER",
122 "MULTIPLE",
123 "SELECTION_DATA",
124 "TARGETS",
125 "TEXT",
126 "UTF8_STRING",
127 "RAW_ASCENT",
128 "RAW_DESCENT",
129 "RAW_CAP_HEIGHT",
130 "WM_PROTOCOLS",
131 "WM_DELETE_WINDOW",
132 "WM_STATE",
133 "WM_TAKE_FOCUS",
134 "DndProtocol",
135 "DndSelection",
136 "_ICC_PROFILE",
137 "_MOTIF_WM_HINTS",
138 "_NET_STARTUP_INFO_BEGIN",
139 "_NET_STARTUP_INFO",
140 "_NET_SUPPORTED",
141 "_NET_SYSTEM_TRAY_OPCODE",
142 "_NET_SYSTEM_TRAY_S0",
143 "_NET_WM_ICON",
144 "_NET_WM_MOVERESIZE",
145 "_NET_WM_NAME",
146 "_NET_WM_PID",
147 "_NET_WM_PING",
148 "_NET_WM_STATE",
149 "_NET_WM_STATE_ABOVE",
150 "_NET_WM_STATE_FULLSCREEN",
151 "_NET_WM_STATE_MAXIMIZED_HORZ",
152 "_NET_WM_STATE_MAXIMIZED_VERT",
153 "_NET_WM_STATE_SKIP_PAGER",
154 "_NET_WM_STATE_SKIP_TASKBAR",
155 "_NET_WM_USER_TIME",
156 "_NET_WM_USER_TIME_WINDOW",
157 "_NET_WM_WINDOW_OPACITY",
158 "_NET_WM_WINDOW_TYPE",
159 "_NET_WM_WINDOW_TYPE_DIALOG",
160 "_NET_WM_WINDOW_TYPE_NORMAL",
161 "_NET_WM_WINDOW_TYPE_UTILITY",
162 "_NET_WORKAREA",
163 "_XEMBED",
164 "_XEMBED_INFO",
165 "XdndAware",
166 "XdndEnter",
167 "XdndPosition",
168 "XdndStatus",
169 "XdndLeave",
170 "XdndFinished",
171 "XdndDrop",
172 "XdndActionCopy",
173 "XdndActionMove",
174 "XdndActionLink",
175 "XdndActionAsk",
176 "XdndActionPrivate",
177 "XdndSelection",
178 "XdndTarget",
179 "XdndTypeList",
180 "HTML Format",
181 "WCF_BITMAP",
182 "WCF_DIB",
183 "WCF_DIBV5",
184 "WCF_DIF",
185 "WCF_DSPBITMAP",
186 "WCF_DSPENHMETAFILE",
187 "WCF_DSPMETAFILEPICT",
188 "WCF_DSPTEXT",
189 "WCF_ENHMETAFILE",
190 "WCF_HDROP",
191 "WCF_LOCALE",
192 "WCF_METAFILEPICT",
193 "WCF_OEMTEXT",
194 "WCF_OWNERDISPLAY",
195 "WCF_PALETTE",
196 "WCF_PENDATA",
197 "WCF_RIFF",
198 "WCF_SYLK",
199 "WCF_TIFF",
200 "WCF_WAVE",
201 "image/bmp",
202 "image/gif",
203 "image/jpeg",
204 "image/png",
205 "text/html",
206 "text/plain",
207 "text/rtf",
208 "text/richtext",
209 "text/uri-list"
212 /***********************************************************************
213 * ignore_error
215 * Check if the X error is one we can ignore.
217 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
219 if ((event->request_code == X_SetInputFocus || event->request_code == X_ChangeWindowAttributes) &&
220 (event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE;
222 /* ignore a number of errors on gdi display caused by creating/destroying windows */
223 if (display == gdi_display)
225 if (event->error_code == BadDrawable ||
226 event->error_code == BadGC ||
227 event->error_code == BadWindow)
228 return TRUE;
229 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
230 if (xrender_error_base) /* check for XRender errors */
232 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
234 #endif
236 return FALSE;
240 /***********************************************************************
241 * X11DRV_expect_error
243 * Setup a callback function that will be called on an X error. The
244 * callback must return non-zero if the error is the one it expected.
245 * This function acquires the x11 lock; X11DRV_check_error must be
246 * called in all cases to release it.
248 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
250 wine_tsx11_lock();
251 err_callback = callback;
252 err_callback_display = display;
253 err_callback_arg = arg;
254 err_callback_result = 0;
255 err_serial = NextRequest(display);
259 /***********************************************************************
260 * X11DRV_check_error
262 * Check if an expected X11 error occurred; return non-zero if yes.
263 * Also release the x11 lock obtained in X11DRV_expect_error.
264 * The caller is responsible for calling XSync first if necessary.
266 int X11DRV_check_error(void)
268 int ret;
269 err_callback = NULL;
270 ret = err_callback_result;
271 wine_tsx11_unlock();
272 return ret;
276 /***********************************************************************
277 * error_handler
279 static int error_handler( Display *display, XErrorEvent *error_evt )
281 if (err_callback && display == err_callback_display &&
282 (long)(error_evt->serial - err_serial) >= 0)
284 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
286 TRACE( "got expected error %d req %d\n",
287 error_evt->error_code, error_evt->request_code );
288 return 0;
291 if (ignore_error( display, error_evt ))
293 TRACE( "got ignored error %d req %d\n",
294 error_evt->error_code, error_evt->request_code );
295 return 0;
297 if (TRACE_ON(synchronous))
299 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
300 error_evt->serial, error_evt->request_code );
301 DebugBreak(); /* force an entry in the debugger */
303 old_error_handler( display, error_evt );
304 return 0;
307 /***********************************************************************
308 * wine_tsx11_lock (X11DRV.@)
310 void CDECL wine_tsx11_lock(void)
312 EnterCriticalSection( &X11DRV_CritSection );
315 /***********************************************************************
316 * wine_tsx11_unlock (X11DRV.@)
318 void CDECL wine_tsx11_unlock(void)
320 LeaveCriticalSection( &X11DRV_CritSection );
324 /***********************************************************************
325 * init_pixmap_formats
327 static void init_pixmap_formats( Display *display )
329 int i, count, max = 32;
330 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
332 for (i = 0; i < count; i++)
334 TRACE( "depth %u, bpp %u, pad %u\n",
335 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
336 if (formats[i].depth > max) max = formats[i].depth;
338 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
339 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
343 /***********************************************************************
344 * get_config_key
346 * Get a config key from either the app-specific or the default config
348 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
349 char *buffer, DWORD size )
351 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
352 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
353 return ERROR_FILE_NOT_FOUND;
357 /***********************************************************************
358 * setup_options
360 * Setup the x11drv options.
362 static void setup_options(void)
364 char buffer[MAX_PATH+16];
365 HKEY hkey, appkey = 0;
366 DWORD len;
368 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
369 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
371 /* open the app-specific key */
373 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
374 if (len && len < MAX_PATH)
376 HKEY tmpkey;
377 char *p, *appname = buffer;
378 if ((p = strrchr( appname, '/' ))) appname = p + 1;
379 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
380 strcat( appname, "\\X11 Driver" );
381 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
382 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
384 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
385 RegCloseKey( tmpkey );
389 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
390 managed_mode = IS_OPTION_TRUE( buffer[0] );
392 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
393 decorated_mode = IS_OPTION_TRUE( buffer[0] );
395 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
396 usexvidmode = IS_OPTION_TRUE( buffer[0] );
398 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
399 usexrandr = IS_OPTION_TRUE( buffer[0] );
401 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
402 use_take_focus = IS_OPTION_TRUE( buffer[0] );
404 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
405 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
407 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
408 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
410 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
411 show_systray = IS_OPTION_TRUE( buffer[0] );
413 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
414 grab_pointer = IS_OPTION_TRUE( buffer[0] );
416 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
417 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
419 screen_depth = 0;
420 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
421 screen_depth = atoi(buffer);
423 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
424 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
426 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithCore", buffer, sizeof(buffer) ))
427 client_side_antialias_with_core = IS_OPTION_TRUE( buffer[0] );
429 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithRender", buffer, sizeof(buffer) ))
430 client_side_antialias_with_render = IS_OPTION_TRUE( buffer[0] );
432 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
433 use_xim = IS_OPTION_TRUE( buffer[0] );
435 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
436 private_color_map = IS_OPTION_TRUE( buffer[0] );
438 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
439 primary_monitor = atoi( buffer );
441 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
442 copy_default_colors = atoi(buffer);
444 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
445 alloc_system_colors = atoi(buffer);
447 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
449 if (appkey) RegCloseKey( appkey );
450 if (hkey) RegCloseKey( hkey );
453 #ifdef SONAME_LIBXCOMPOSITE
455 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
456 MAKE_FUNCPTR(XCompositeQueryExtension)
457 MAKE_FUNCPTR(XCompositeQueryVersion)
458 MAKE_FUNCPTR(XCompositeVersion)
459 MAKE_FUNCPTR(XCompositeRedirectWindow)
460 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
461 MAKE_FUNCPTR(XCompositeUnredirectWindow)
462 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
463 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
464 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
465 #undef MAKE_FUNCPTR
467 static int xcomp_event_base;
468 static int xcomp_error_base;
470 static void X11DRV_XComposite_Init(void)
472 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
473 if (!xcomposite_handle)
475 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
476 usexcomposite = 0;
477 return;
480 #define LOAD_FUNCPTR(f) \
481 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
482 goto sym_not_found;
483 LOAD_FUNCPTR(XCompositeQueryExtension)
484 LOAD_FUNCPTR(XCompositeQueryVersion)
485 LOAD_FUNCPTR(XCompositeVersion)
486 LOAD_FUNCPTR(XCompositeRedirectWindow)
487 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
488 LOAD_FUNCPTR(XCompositeUnredirectWindow)
489 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
490 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
491 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
492 #undef LOAD_FUNCPTR
494 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
495 &xcomp_error_base)) {
496 TRACE("XComposite extension could not be queried; disabled\n");
497 wine_dlclose(xcomposite_handle, NULL, 0);
498 xcomposite_handle = NULL;
499 usexcomposite = 0;
500 return;
502 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
503 return;
505 sym_not_found:
506 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
507 wine_dlclose(xcomposite_handle, NULL, 0);
508 xcomposite_handle = NULL;
509 usexcomposite = 0;
511 #endif /* defined(SONAME_LIBXCOMPOSITE) */
514 /***********************************************************************
515 * X11DRV process initialisation routine
517 static BOOL process_attach(void)
519 char error[1024];
520 Display *display;
521 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
523 if (!libx11)
525 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
526 return FALSE;
528 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
529 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
530 #ifdef SONAME_LIBXEXT
531 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
532 #endif
534 setup_options();
536 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
538 /* Open display */
540 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
541 if (!(display = XOpenDisplay( NULL ))) return FALSE;
543 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
544 screen = DefaultScreenOfDisplay( display );
545 visual = DefaultVisual( display, DefaultScreen(display) );
546 root_window = DefaultRootWindow( display );
547 gdi_display = display;
548 old_error_handler = XSetErrorHandler( error_handler );
550 /* Initialize screen depth */
552 if (screen_depth) /* depth specified */
554 int depth_count, i;
555 int *depth_list = XListDepths(display, DefaultScreen(display), &depth_count);
556 for (i = 0; i < depth_count; i++)
557 if (depth_list[i] == screen_depth) break;
558 XFree( depth_list );
559 if (i >= depth_count)
561 WARN( "invalid depth %d, using default\n", screen_depth );
562 screen_depth = 0;
565 if (!screen_depth) screen_depth = DefaultDepthOfScreen( screen );
566 init_pixmap_formats( display );
567 screen_bpp = pixmap_formats[screen_depth]->bits_per_pixel;
569 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
571 if (TRACE_ON(synchronous)) XSynchronize( display, True );
573 xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
574 X11DRV_Settings_Init();
576 /* initialize XVidMode */
577 X11DRV_XF86VM_Init();
578 /* initialize XRandR */
579 X11DRV_XRandR_Init();
580 #ifdef SONAME_LIBXCOMPOSITE
581 X11DRV_XComposite_Init();
582 #endif
583 X11DRV_XInput2_Init();
585 #ifdef HAVE_XKB
586 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
587 #endif
588 X11DRV_InitKeyboard( gdi_display );
589 X11DRV_InitClipboard();
590 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
592 return TRUE;
596 /***********************************************************************
597 * X11DRV thread termination routine
599 static void thread_detach(void)
601 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
603 if (data)
605 X11DRV_ResetSelectionOwner();
606 wine_tsx11_lock();
607 if (data->xim) XCloseIM( data->xim );
608 if (data->font_set) XFreeFontSet( data->display, data->font_set );
609 XCloseDisplay( data->display );
610 wine_tsx11_unlock();
611 HeapFree( GetProcessHeap(), 0, data );
616 /***********************************************************************
617 * X11DRV process termination routine
619 static void process_detach(void)
621 X11DRV_Clipboard_Cleanup();
622 /* cleanup XVidMode */
623 X11DRV_XF86VM_Cleanup();
624 X11DRV_XRender_Finalize();
626 /* cleanup GDI */
627 X11DRV_GDI_Finalize();
629 IME_UnregisterClasses();
630 DeleteCriticalSection( &X11DRV_CritSection );
631 TlsFree( thread_data_tls_index );
635 /* store the display fd into the message queue */
636 static void set_queue_display_fd( Display *display )
638 HANDLE handle;
639 int ret;
641 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
643 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
644 ExitProcess(1);
646 SERVER_START_REQ( set_queue_fd )
648 req->handle = wine_server_obj_handle( handle );
649 ret = wine_server_call( req );
651 SERVER_END_REQ;
652 if (ret)
654 MESSAGE( "x11drv: Can't store handle for display fd\n" );
655 ExitProcess(1);
657 CloseHandle( handle );
661 /***********************************************************************
662 * X11DRV thread initialisation routine
664 struct x11drv_thread_data *x11drv_init_thread_data(void)
666 struct x11drv_thread_data *data = x11drv_thread_data();
668 if (data) return data;
670 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
672 ERR( "could not create data\n" );
673 ExitProcess(1);
675 wine_tsx11_lock();
676 if (!(data->display = XOpenDisplay(NULL)))
678 wine_tsx11_unlock();
679 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));
680 ExitProcess(1);
683 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
685 #ifdef HAVE_XKB
686 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
687 XkbSetDetectableAutoRepeat( data->display, True, NULL );
688 #endif
690 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
691 wine_tsx11_unlock();
693 set_queue_display_fd( data->display );
694 TlsSetValue( thread_data_tls_index, data );
696 if (use_xim) X11DRV_SetupXIM();
698 return data;
702 /***********************************************************************
703 * X11DRV initialisation routine
705 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
707 BOOL ret = TRUE;
709 switch(reason)
711 case DLL_PROCESS_ATTACH:
712 x11drv_module = hinst;
713 ret = process_attach();
714 break;
715 case DLL_THREAD_DETACH:
716 thread_detach();
717 break;
718 case DLL_PROCESS_DETACH:
719 process_detach();
720 break;
722 return ret;
725 /***********************************************************************
726 * GetScreenSaveActive (X11DRV.@)
728 * Returns the active status of the screen saver
730 BOOL CDECL X11DRV_GetScreenSaveActive(void)
732 int timeout, temp;
733 wine_tsx11_lock();
734 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
735 wine_tsx11_unlock();
736 return timeout != 0;
739 /***********************************************************************
740 * SetScreenSaveActive (X11DRV.@)
742 * Activate/Deactivate the screen saver
744 void CDECL X11DRV_SetScreenSaveActive(BOOL bActivate)
746 int timeout, interval, prefer_blanking, allow_exposures;
747 static int last_timeout = 15 * 60;
749 wine_tsx11_lock();
750 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
751 &allow_exposures);
752 if (timeout) last_timeout = timeout;
754 timeout = bActivate ? last_timeout : 0;
755 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
756 allow_exposures);
757 wine_tsx11_unlock();