wined3d: Use the texture dimension helpers in wined3d_texture_update_overlay().
[wine.git] / dlls / winex11.drv / x11drv_main.c
blobd4f5c84f9c73010e5914b35cac4d2a4ff35df524
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 "XdndTarget",
171 "XdndTypeList",
172 "HTML Format",
173 "WCF_BITMAP",
174 "WCF_DIB",
175 "WCF_DIBV5",
176 "WCF_DIF",
177 "WCF_DSPBITMAP",
178 "WCF_DSPENHMETAFILE",
179 "WCF_DSPMETAFILEPICT",
180 "WCF_DSPTEXT",
181 "WCF_ENHMETAFILE",
182 "WCF_HDROP",
183 "WCF_LOCALE",
184 "WCF_METAFILEPICT",
185 "WCF_OEMTEXT",
186 "WCF_OWNERDISPLAY",
187 "WCF_PALETTE",
188 "WCF_PENDATA",
189 "WCF_RIFF",
190 "WCF_SYLK",
191 "WCF_TIFF",
192 "WCF_WAVE",
193 "image/bmp",
194 "image/gif",
195 "image/jpeg",
196 "image/png",
197 "text/html",
198 "text/plain",
199 "text/rtf",
200 "text/richtext",
201 "text/uri-list"
204 /***********************************************************************
205 * ignore_error
207 * Check if the X error is one we can ignore.
209 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
211 if ((event->request_code == X_SetInputFocus || event->request_code == X_ChangeWindowAttributes) &&
212 (event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE;
214 /* ignore a number of errors on gdi display caused by creating/destroying windows */
215 if (display == gdi_display)
217 if (event->error_code == BadDrawable ||
218 event->error_code == BadGC ||
219 event->error_code == BadWindow)
220 return TRUE;
221 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
222 if (xrender_error_base) /* check for XRender errors */
224 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
226 #endif
228 return FALSE;
232 /***********************************************************************
233 * X11DRV_expect_error
235 * Setup a callback function that will be called on an X error. The
236 * callback must return non-zero if the error is the one it expected.
238 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
240 err_callback = callback;
241 err_callback_display = display;
242 err_callback_arg = arg;
243 err_callback_result = 0;
244 err_serial = NextRequest(display);
248 /***********************************************************************
249 * X11DRV_check_error
251 * Check if an expected X11 error occurred; return non-zero if yes.
252 * The caller is responsible for calling XSync first if necessary.
254 int X11DRV_check_error(void)
256 err_callback = NULL;
257 return err_callback_result;
261 /***********************************************************************
262 * error_handler
264 static int error_handler( Display *display, XErrorEvent *error_evt )
266 if (err_callback && display == err_callback_display &&
267 (long)(error_evt->serial - err_serial) >= 0)
269 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
271 TRACE( "got expected error %d req %d\n",
272 error_evt->error_code, error_evt->request_code );
273 return 0;
276 if (ignore_error( display, error_evt ))
278 TRACE( "got ignored error %d req %d\n",
279 error_evt->error_code, error_evt->request_code );
280 return 0;
282 if (TRACE_ON(synchronous))
284 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
285 error_evt->serial, error_evt->request_code );
286 DebugBreak(); /* force an entry in the debugger */
288 old_error_handler( display, error_evt );
289 return 0;
292 /***********************************************************************
293 * init_pixmap_formats
295 static void init_pixmap_formats( Display *display )
297 int i, count, max = 32;
298 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
300 for (i = 0; i < count; i++)
302 TRACE( "depth %u, bpp %u, pad %u\n",
303 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
304 if (formats[i].depth > max) max = formats[i].depth;
306 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
307 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
311 /***********************************************************************
312 * get_config_key
314 * Get a config key from either the app-specific or the default config
316 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
317 char *buffer, DWORD size )
319 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
320 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
321 return ERROR_FILE_NOT_FOUND;
325 /***********************************************************************
326 * setup_options
328 * Setup the x11drv options.
330 static void setup_options(void)
332 char buffer[MAX_PATH+16];
333 HKEY hkey, appkey = 0;
334 DWORD len;
336 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
337 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
339 /* open the app-specific key */
341 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
342 if (len && len < MAX_PATH)
344 HKEY tmpkey;
345 char *p, *appname = buffer;
346 if ((p = strrchr( appname, '/' ))) appname = p + 1;
347 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
348 strcat( appname, "\\X11 Driver" );
349 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
350 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
352 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
353 RegCloseKey( tmpkey );
357 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
358 managed_mode = IS_OPTION_TRUE( buffer[0] );
360 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
361 decorated_mode = IS_OPTION_TRUE( buffer[0] );
363 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
364 usexvidmode = IS_OPTION_TRUE( buffer[0] );
366 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
367 usexrandr = IS_OPTION_TRUE( buffer[0] );
369 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
370 use_take_focus = IS_OPTION_TRUE( buffer[0] );
372 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
373 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
375 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
376 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
378 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
379 show_systray = IS_OPTION_TRUE( buffer[0] );
381 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
382 grab_pointer = IS_OPTION_TRUE( buffer[0] );
384 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
385 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
387 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
388 default_visual.depth = atoi(buffer);
390 if (!get_config_key( hkey, appkey, "ClientSideGraphics", buffer, sizeof(buffer) ))
391 client_side_graphics = 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, "UseXIM", buffer, sizeof(buffer) ))
397 use_xim = IS_OPTION_TRUE( buffer[0] );
399 if (!get_config_key( hkey, appkey, "ShapeLayeredWindows", buffer, sizeof(buffer) ))
400 shape_layered_windows = IS_OPTION_TRUE( buffer[0] );
402 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
403 private_color_map = IS_OPTION_TRUE( buffer[0] );
405 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
406 primary_monitor = atoi( buffer );
408 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
409 copy_default_colors = atoi(buffer);
411 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
412 alloc_system_colors = atoi(buffer);
414 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
416 if (appkey) RegCloseKey( appkey );
417 if (hkey) RegCloseKey( hkey );
420 #ifdef SONAME_LIBXCOMPOSITE
422 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
423 MAKE_FUNCPTR(XCompositeQueryExtension)
424 MAKE_FUNCPTR(XCompositeQueryVersion)
425 MAKE_FUNCPTR(XCompositeVersion)
426 MAKE_FUNCPTR(XCompositeRedirectWindow)
427 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
428 MAKE_FUNCPTR(XCompositeUnredirectWindow)
429 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
430 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
431 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
432 #undef MAKE_FUNCPTR
434 static int xcomp_event_base;
435 static int xcomp_error_base;
437 static void X11DRV_XComposite_Init(void)
439 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
440 if (!xcomposite_handle)
442 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
443 usexcomposite = FALSE;
444 return;
447 #define LOAD_FUNCPTR(f) \
448 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
449 goto sym_not_found;
450 LOAD_FUNCPTR(XCompositeQueryExtension)
451 LOAD_FUNCPTR(XCompositeQueryVersion)
452 LOAD_FUNCPTR(XCompositeVersion)
453 LOAD_FUNCPTR(XCompositeRedirectWindow)
454 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
455 LOAD_FUNCPTR(XCompositeUnredirectWindow)
456 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
457 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
458 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
459 #undef LOAD_FUNCPTR
461 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
462 &xcomp_error_base)) {
463 TRACE("XComposite extension could not be queried; disabled\n");
464 wine_dlclose(xcomposite_handle, NULL, 0);
465 xcomposite_handle = NULL;
466 usexcomposite = FALSE;
467 return;
469 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
470 return;
472 sym_not_found:
473 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
474 wine_dlclose(xcomposite_handle, NULL, 0);
475 xcomposite_handle = NULL;
476 usexcomposite = FALSE;
478 #endif /* defined(SONAME_LIBXCOMPOSITE) */
480 static void init_visuals( Display *display, int screen )
482 int count;
483 XVisualInfo *info;
485 default_visual.screen = screen;
486 if (default_visual.depth) /* depth specified */
488 info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask, &default_visual, &count );
489 if (info)
491 default_visual = *info;
492 XFree( info );
494 else WARN( "no visual found for depth %d\n", default_visual.depth );
497 if (!default_visual.visual)
499 default_visual.depth = DefaultDepth( display, screen );
500 default_visual.visual = DefaultVisual( display, screen );
501 default_visual.visualid = default_visual.visual->visualid;
502 default_visual.class = default_visual.visual->class;
503 default_visual.red_mask = default_visual.visual->red_mask;
504 default_visual.green_mask = default_visual.visual->green_mask;
505 default_visual.blue_mask = default_visual.visual->blue_mask;
506 default_visual.colormap_size = default_visual.visual->map_entries;
507 default_visual.bits_per_rgb = default_visual.visual->bits_per_rgb;
509 default_colormap = XCreateColormap( display, root_window, default_visual.visual, AllocNone );
511 argb_visual.screen = screen;
512 argb_visual.class = TrueColor;
513 argb_visual.depth = 32;
514 argb_visual.red_mask = 0xff0000;
515 argb_visual.green_mask = 0x00ff00;
516 argb_visual.blue_mask = 0x0000ff;
518 if ((info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask | VisualClassMask |
519 VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
520 &argb_visual, &count )))
522 argb_visual = *info;
523 XFree( info );
525 TRACE( "default visual %lx class %u argb %lx\n",
526 default_visual.visualid, default_visual.class, argb_visual.visualid );
529 /***********************************************************************
530 * X11DRV process initialisation routine
532 static BOOL process_attach(void)
534 char error[1024];
535 Display *display;
536 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
538 if (!libx11)
540 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
541 return FALSE;
543 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
544 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
545 #ifdef SONAME_LIBXEXT
546 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
547 #endif
549 setup_options();
551 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
553 /* Open display */
555 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
556 if (!(display = XOpenDisplay( NULL ))) return FALSE;
558 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
559 root_window = DefaultRootWindow( display );
560 gdi_display = display;
561 old_error_handler = XSetErrorHandler( error_handler );
563 init_pixmap_formats( display );
564 init_visuals( display, DefaultScreen( display ));
565 screen_bpp = pixmap_formats[default_visual.depth]->bits_per_pixel;
567 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
569 winContext = XUniqueContext();
570 win_data_context = XUniqueContext();
571 cursor_context = XUniqueContext();
573 if (TRACE_ON(synchronous)) XSynchronize( display, True );
575 xinerama_init( DisplayWidth( display, default_visual.screen ),
576 DisplayHeight( display, default_visual.screen ));
577 X11DRV_Settings_Init();
579 /* initialize XVidMode */
580 X11DRV_XF86VM_Init();
581 /* initialize XRandR */
582 X11DRV_XRandR_Init();
583 #ifdef SONAME_LIBXCOMPOSITE
584 X11DRV_XComposite_Init();
585 #endif
586 X11DRV_XInput2_Init();
588 #ifdef HAVE_XKB
589 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
590 #endif
591 X11DRV_InitKeyboard( gdi_display );
592 X11DRV_InitClipboard();
593 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
595 return TRUE;
599 /***********************************************************************
600 * X11DRV thread termination routine
602 static void thread_detach(void)
604 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
606 if (data)
608 X11DRV_ResetSelectionOwner();
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 x11drv_module = hinst;
694 ret = process_attach();
695 break;
696 case DLL_THREAD_DETACH:
697 thread_detach();
698 break;
700 return ret;
704 /***********************************************************************
705 * SystemParametersInfo (X11DRV.@)
707 BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags )
709 switch (action)
711 case SPI_GETSCREENSAVEACTIVE:
712 if (ptr_param)
714 int timeout, temp;
715 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
716 *(BOOL *)ptr_param = timeout != 0;
717 return TRUE;
719 break;
720 case SPI_SETSCREENSAVEACTIVE:
722 int timeout, interval, prefer_blanking, allow_exposures;
723 static int last_timeout = 15 * 60;
725 XLockDisplay( gdi_display );
726 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
727 &allow_exposures);
728 if (timeout) last_timeout = timeout;
730 timeout = int_param ? last_timeout : 0;
731 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
732 allow_exposures);
733 XUnlockDisplay( gdi_display );
735 break;
737 return FALSE; /* let user32 handle it */