winex11: Ignore X11 errors happening on the clipboard display connection.
[wine.git] / dlls / winex11.drv / x11drv_main.c
blob41097f4c1dbd0c565a025c1291df3b1a3c61bd1d
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 XVisualInfo default_visual = { 0 };
60 XVisualInfo argb_visual = { 0 };
61 Colormap default_colormap = None;
62 XPixmapFormatValues **pixmap_formats;
63 unsigned int screen_bpp;
64 Window root_window;
65 BOOL usexvidmode = TRUE;
66 BOOL usexrandr = TRUE;
67 BOOL usexcomposite = TRUE;
68 BOOL use_xkb = TRUE;
69 BOOL use_take_focus = TRUE;
70 BOOL use_primary_selection = FALSE;
71 BOOL use_system_cursors = TRUE;
72 BOOL show_systray = TRUE;
73 BOOL grab_pointer = TRUE;
74 BOOL grab_fullscreen = FALSE;
75 BOOL managed_mode = TRUE;
76 BOOL decorated_mode = TRUE;
77 BOOL private_color_map = FALSE;
78 int primary_monitor = 0;
79 BOOL client_side_graphics = TRUE;
80 BOOL client_side_with_render = TRUE;
81 BOOL shape_layered_windows = TRUE;
82 int copy_default_colors = 128;
83 int alloc_system_colors = 256;
84 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
85 int xrender_error_base = 0;
86 HMODULE x11drv_module = 0;
88 static x11drv_error_callback err_callback; /* current callback for error */
89 static Display *err_callback_display; /* display callback is set for */
90 static void *err_callback_arg; /* error callback argument */
91 static int err_callback_result; /* error callback result */
92 static unsigned long err_serial; /* serial number of first request */
93 static int (*old_error_handler)( Display *, XErrorEvent * );
94 static BOOL use_xim = TRUE;
95 static char input_style[20];
97 #define IS_OPTION_TRUE(ch) \
98 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
99 #define IS_OPTION_FALSE(ch) \
100 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
102 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
104 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
106 "CLIPBOARD",
107 "COMPOUND_TEXT",
108 "INCR",
109 "MANAGER",
110 "MULTIPLE",
111 "SELECTION_DATA",
112 "TARGETS",
113 "TEXT",
114 "UTF8_STRING",
115 "RAW_ASCENT",
116 "RAW_DESCENT",
117 "RAW_CAP_HEIGHT",
118 "Rel X",
119 "Rel Y",
120 "WM_PROTOCOLS",
121 "WM_DELETE_WINDOW",
122 "WM_STATE",
123 "WM_TAKE_FOCUS",
124 "DndProtocol",
125 "DndSelection",
126 "_ICC_PROFILE",
127 "_MOTIF_WM_HINTS",
128 "_NET_STARTUP_INFO_BEGIN",
129 "_NET_STARTUP_INFO",
130 "_NET_SUPPORTED",
131 "_NET_SYSTEM_TRAY_OPCODE",
132 "_NET_SYSTEM_TRAY_S0",
133 "_NET_SYSTEM_TRAY_VISUAL",
134 "_NET_WM_ICON",
135 "_NET_WM_MOVERESIZE",
136 "_NET_WM_NAME",
137 "_NET_WM_PID",
138 "_NET_WM_PING",
139 "_NET_WM_STATE",
140 "_NET_WM_STATE_ABOVE",
141 "_NET_WM_STATE_DEMANDS_ATTENTION",
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_USER_TIME",
148 "_NET_WM_USER_TIME_WINDOW",
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",
156 "_XEMBED_INFO",
157 "XdndAware",
158 "XdndEnter",
159 "XdndPosition",
160 "XdndStatus",
161 "XdndLeave",
162 "XdndFinished",
163 "XdndDrop",
164 "XdndActionCopy",
165 "XdndActionMove",
166 "XdndActionLink",
167 "XdndActionAsk",
168 "XdndActionPrivate",
169 "XdndSelection",
170 "XdndTypeList",
171 "HTML Format",
172 "WCF_BITMAP",
173 "WCF_DIB",
174 "WCF_DIBV5",
175 "WCF_DIF",
176 "WCF_DSPBITMAP",
177 "WCF_DSPENHMETAFILE",
178 "WCF_DSPMETAFILEPICT",
179 "WCF_DSPTEXT",
180 "WCF_ENHMETAFILE",
181 "WCF_HDROP",
182 "WCF_LOCALE",
183 "WCF_METAFILEPICT",
184 "WCF_OEMTEXT",
185 "WCF_OWNERDISPLAY",
186 "WCF_PALETTE",
187 "WCF_PENDATA",
188 "WCF_RIFF",
189 "WCF_SYLK",
190 "WCF_TIFF",
191 "WCF_WAVE",
192 "image/bmp",
193 "image/gif",
194 "image/jpeg",
195 "image/png",
196 "text/html",
197 "text/plain",
198 "text/rtf",
199 "text/richtext",
200 "text/uri-list"
203 /***********************************************************************
204 * ignore_error
206 * Check if the X error is one we can ignore.
208 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
210 if ((event->request_code == X_SetInputFocus || event->request_code == X_ChangeWindowAttributes) &&
211 (event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE;
213 /* the clipboard display interacts with external windows, ignore all errors */
214 if (display == clipboard_display) return TRUE;
216 /* ignore a number of errors on gdi display caused by creating/destroying windows */
217 if (display == gdi_display)
219 if (event->error_code == BadDrawable ||
220 event->error_code == BadGC ||
221 event->error_code == BadWindow)
222 return TRUE;
223 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
224 if (xrender_error_base) /* check for XRender errors */
226 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
228 #endif
230 return FALSE;
234 /***********************************************************************
235 * X11DRV_expect_error
237 * Setup a callback function that will be called on an X error. The
238 * callback must return non-zero if the error is the one it expected.
240 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
242 err_callback = callback;
243 err_callback_display = display;
244 err_callback_arg = arg;
245 err_callback_result = 0;
246 err_serial = NextRequest(display);
250 /***********************************************************************
251 * X11DRV_check_error
253 * Check if an expected X11 error occurred; return non-zero if yes.
254 * The caller is responsible for calling XSync first if necessary.
256 int X11DRV_check_error(void)
258 err_callback = NULL;
259 return err_callback_result;
263 /***********************************************************************
264 * error_handler
266 static int error_handler( Display *display, XErrorEvent *error_evt )
268 if (err_callback && display == err_callback_display &&
269 (long)(error_evt->serial - err_serial) >= 0)
271 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
273 TRACE( "got expected error %d req %d\n",
274 error_evt->error_code, error_evt->request_code );
275 return 0;
278 if (ignore_error( display, error_evt ))
280 TRACE( "got ignored error %d req %d\n",
281 error_evt->error_code, error_evt->request_code );
282 return 0;
284 if (TRACE_ON(synchronous))
286 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
287 error_evt->serial, error_evt->request_code );
288 DebugBreak(); /* force an entry in the debugger */
290 old_error_handler( display, error_evt );
291 return 0;
294 /***********************************************************************
295 * init_pixmap_formats
297 static void init_pixmap_formats( Display *display )
299 int i, count, max = 32;
300 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
302 for (i = 0; i < count; i++)
304 TRACE( "depth %u, bpp %u, pad %u\n",
305 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
306 if (formats[i].depth > max) max = formats[i].depth;
308 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
309 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
313 /***********************************************************************
314 * get_config_key
316 * Get a config key from either the app-specific or the default config
318 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
319 char *buffer, DWORD size )
321 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
322 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
323 return ERROR_FILE_NOT_FOUND;
327 /***********************************************************************
328 * setup_options
330 * Setup the x11drv options.
332 static void setup_options(void)
334 char buffer[MAX_PATH+16];
335 HKEY hkey, appkey = 0;
336 DWORD len;
338 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
339 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
341 /* open the app-specific key */
343 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
344 if (len && len < MAX_PATH)
346 HKEY tmpkey;
347 char *p, *appname = buffer;
348 if ((p = strrchr( appname, '/' ))) appname = p + 1;
349 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
350 strcat( appname, "\\X11 Driver" );
351 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
352 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
354 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
355 RegCloseKey( tmpkey );
359 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
360 managed_mode = IS_OPTION_TRUE( buffer[0] );
362 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
363 decorated_mode = IS_OPTION_TRUE( buffer[0] );
365 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
366 usexvidmode = IS_OPTION_TRUE( buffer[0] );
368 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
369 usexrandr = IS_OPTION_TRUE( buffer[0] );
371 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
372 use_take_focus = IS_OPTION_TRUE( buffer[0] );
374 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
375 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
377 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
378 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
380 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
381 show_systray = IS_OPTION_TRUE( buffer[0] );
383 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
384 grab_pointer = IS_OPTION_TRUE( buffer[0] );
386 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
387 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
389 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
390 default_visual.depth = atoi(buffer);
392 if (!get_config_key( hkey, appkey, "ClientSideGraphics", buffer, sizeof(buffer) ))
393 client_side_graphics = IS_OPTION_TRUE( buffer[0] );
395 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
396 client_side_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, "ShapeLayeredWindows", buffer, sizeof(buffer) ))
402 shape_layered_windows = IS_OPTION_TRUE( buffer[0] );
404 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
405 private_color_map = IS_OPTION_TRUE( buffer[0] );
407 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
408 primary_monitor = atoi( buffer );
410 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
411 copy_default_colors = atoi(buffer);
413 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
414 alloc_system_colors = atoi(buffer);
416 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
418 if (appkey) RegCloseKey( appkey );
419 if (hkey) RegCloseKey( hkey );
422 #ifdef SONAME_LIBXCOMPOSITE
424 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
425 MAKE_FUNCPTR(XCompositeQueryExtension)
426 MAKE_FUNCPTR(XCompositeQueryVersion)
427 MAKE_FUNCPTR(XCompositeVersion)
428 MAKE_FUNCPTR(XCompositeRedirectWindow)
429 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
430 MAKE_FUNCPTR(XCompositeUnredirectWindow)
431 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
432 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
433 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
434 #undef MAKE_FUNCPTR
436 static int xcomp_event_base;
437 static int xcomp_error_base;
439 static void X11DRV_XComposite_Init(void)
441 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
442 if (!xcomposite_handle)
444 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
445 usexcomposite = FALSE;
446 return;
449 #define LOAD_FUNCPTR(f) \
450 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
451 goto sym_not_found;
452 LOAD_FUNCPTR(XCompositeQueryExtension)
453 LOAD_FUNCPTR(XCompositeQueryVersion)
454 LOAD_FUNCPTR(XCompositeVersion)
455 LOAD_FUNCPTR(XCompositeRedirectWindow)
456 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
457 LOAD_FUNCPTR(XCompositeUnredirectWindow)
458 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
459 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
460 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
461 #undef LOAD_FUNCPTR
463 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
464 &xcomp_error_base)) {
465 TRACE("XComposite extension could not be queried; disabled\n");
466 wine_dlclose(xcomposite_handle, NULL, 0);
467 xcomposite_handle = NULL;
468 usexcomposite = FALSE;
469 return;
471 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
472 return;
474 sym_not_found:
475 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
476 wine_dlclose(xcomposite_handle, NULL, 0);
477 xcomposite_handle = NULL;
478 usexcomposite = FALSE;
480 #endif /* defined(SONAME_LIBXCOMPOSITE) */
482 static void init_visuals( Display *display, int screen )
484 int count;
485 XVisualInfo *info;
487 default_visual.screen = screen;
488 if (default_visual.depth) /* depth specified */
490 info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask, &default_visual, &count );
491 if (info)
493 default_visual = *info;
494 XFree( info );
496 else WARN( "no visual found for depth %d\n", default_visual.depth );
499 if (!default_visual.visual)
501 default_visual.depth = DefaultDepth( display, screen );
502 default_visual.visual = DefaultVisual( display, screen );
503 default_visual.visualid = default_visual.visual->visualid;
504 default_visual.class = default_visual.visual->class;
505 default_visual.red_mask = default_visual.visual->red_mask;
506 default_visual.green_mask = default_visual.visual->green_mask;
507 default_visual.blue_mask = default_visual.visual->blue_mask;
508 default_visual.colormap_size = default_visual.visual->map_entries;
509 default_visual.bits_per_rgb = default_visual.visual->bits_per_rgb;
511 default_colormap = XCreateColormap( display, root_window, default_visual.visual, AllocNone );
513 argb_visual.screen = screen;
514 argb_visual.class = TrueColor;
515 argb_visual.depth = 32;
516 argb_visual.red_mask = 0xff0000;
517 argb_visual.green_mask = 0x00ff00;
518 argb_visual.blue_mask = 0x0000ff;
520 if ((info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask | VisualClassMask |
521 VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
522 &argb_visual, &count )))
524 argb_visual = *info;
525 XFree( info );
527 TRACE( "default visual %lx class %u argb %lx\n",
528 default_visual.visualid, default_visual.class, argb_visual.visualid );
531 /***********************************************************************
532 * X11DRV process initialisation routine
534 static BOOL process_attach(void)
536 char error[1024];
537 Display *display;
538 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
540 if (!libx11)
542 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
543 return FALSE;
545 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
546 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
547 #ifdef SONAME_LIBXEXT
548 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
549 #endif
551 setup_options();
553 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
555 /* Open display */
557 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
558 if (!(display = XOpenDisplay( NULL ))) return FALSE;
560 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
561 root_window = DefaultRootWindow( display );
562 gdi_display = display;
563 old_error_handler = XSetErrorHandler( error_handler );
565 init_pixmap_formats( display );
566 init_visuals( display, DefaultScreen( display ));
567 screen_bpp = pixmap_formats[default_visual.depth]->bits_per_pixel;
569 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
571 winContext = XUniqueContext();
572 win_data_context = XUniqueContext();
573 cursor_context = XUniqueContext();
575 if (TRACE_ON(synchronous)) XSynchronize( display, True );
577 xinerama_init( DisplayWidth( display, default_visual.screen ),
578 DisplayHeight( display, default_visual.screen ));
579 X11DRV_Settings_Init();
581 /* initialize XVidMode */
582 X11DRV_XF86VM_Init();
583 /* initialize XRandR */
584 X11DRV_XRandR_Init();
585 #ifdef SONAME_LIBXCOMPOSITE
586 X11DRV_XComposite_Init();
587 #endif
588 X11DRV_XInput2_Init();
590 #ifdef HAVE_XKB
591 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
592 #endif
593 X11DRV_InitKeyboard( gdi_display );
594 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
596 return TRUE;
600 /***********************************************************************
601 * ThreadDetach (X11DRV.@)
603 void CDECL X11DRV_ThreadDetach(void)
605 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
607 if (data)
609 if (data->xim) XCloseIM( data->xim );
610 if (data->font_set) XFreeFontSet( data->display, data->font_set );
611 XCloseDisplay( data->display );
612 HeapFree( GetProcessHeap(), 0, data );
613 /* clear data in case we get re-entered from user32 before the thread is truly dead */
614 TlsSetValue( thread_data_tls_index, NULL );
619 /* store the display fd into the message queue */
620 static void set_queue_display_fd( Display *display )
622 HANDLE handle;
623 int ret;
625 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
627 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
628 ExitProcess(1);
630 SERVER_START_REQ( set_queue_fd )
632 req->handle = wine_server_obj_handle( handle );
633 ret = wine_server_call( req );
635 SERVER_END_REQ;
636 if (ret)
638 MESSAGE( "x11drv: Can't store handle for display fd\n" );
639 ExitProcess(1);
641 CloseHandle( handle );
645 /***********************************************************************
646 * X11DRV thread initialisation routine
648 struct x11drv_thread_data *x11drv_init_thread_data(void)
650 struct x11drv_thread_data *data = x11drv_thread_data();
652 if (data) return data;
654 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
656 ERR( "could not create data\n" );
657 ExitProcess(1);
659 if (!(data->display = XOpenDisplay(NULL)))
661 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));
662 ExitProcess(1);
665 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
667 #ifdef HAVE_XKB
668 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
669 XkbSetDetectableAutoRepeat( data->display, True, NULL );
670 #endif
672 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
674 set_queue_display_fd( data->display );
675 TlsSetValue( thread_data_tls_index, data );
677 if (use_xim) X11DRV_SetupXIM();
679 return data;
683 /***********************************************************************
684 * X11DRV initialisation routine
686 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
688 BOOL ret = TRUE;
690 switch(reason)
692 case DLL_PROCESS_ATTACH:
693 DisableThreadLibraryCalls( hinst );
694 x11drv_module = hinst;
695 ret = process_attach();
696 break;
698 return ret;
702 /***********************************************************************
703 * SystemParametersInfo (X11DRV.@)
705 BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags )
707 switch (action)
709 case SPI_GETSCREENSAVEACTIVE:
710 if (ptr_param)
712 int timeout, temp;
713 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
714 *(BOOL *)ptr_param = timeout != 0;
715 return TRUE;
717 break;
718 case SPI_SETSCREENSAVEACTIVE:
720 int timeout, interval, prefer_blanking, allow_exposures;
721 static int last_timeout = 15 * 60;
723 XLockDisplay( gdi_display );
724 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
725 &allow_exposures);
726 if (timeout) last_timeout = timeout;
728 timeout = int_param ? last_timeout : 0;
729 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
730 allow_exposures);
731 XUnlockDisplay( gdi_display );
733 break;
735 return FALSE; /* let user32 handle it */