hal: Mark function that are only called from assembly as hidden.
[wine.git] / dlls / winex11.drv / x11drv_main.c
blob65ef59b0c1b8b2189e49438165b0a273f6d5c9e2
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/unicode.h"
53 #include "wine/debug.h"
54 #include "wine/library.h"
56 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
57 WINE_DECLARE_DEBUG_CHANNEL(synchronous);
58 WINE_DECLARE_DEBUG_CHANNEL(winediag);
60 XVisualInfo default_visual = { 0 };
61 XVisualInfo argb_visual = { 0 };
62 Colormap default_colormap = None;
63 XPixmapFormatValues **pixmap_formats;
64 unsigned int screen_bpp;
65 Window root_window;
66 BOOL usexvidmode = TRUE;
67 BOOL usexrandr = TRUE;
68 BOOL usexcomposite = TRUE;
69 BOOL use_xkb = TRUE;
70 BOOL use_take_focus = TRUE;
71 BOOL use_primary_selection = FALSE;
72 BOOL use_system_cursors = TRUE;
73 BOOL show_systray = TRUE;
74 BOOL grab_pointer = TRUE;
75 BOOL grab_fullscreen = FALSE;
76 BOOL managed_mode = TRUE;
77 BOOL decorated_mode = TRUE;
78 BOOL private_color_map = FALSE;
79 int primary_monitor = 0;
80 BOOL client_side_graphics = TRUE;
81 BOOL client_side_with_render = TRUE;
82 BOOL shape_layered_windows = TRUE;
83 int copy_default_colors = 128;
84 int alloc_system_colors = 256;
85 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
86 int xrender_error_base = 0;
87 HMODULE x11drv_module = 0;
88 char *process_name = NULL;
90 static x11drv_error_callback err_callback; /* current callback for error */
91 static Display *err_callback_display; /* display callback is set for */
92 static void *err_callback_arg; /* error callback argument */
93 static int err_callback_result; /* error callback result */
94 static unsigned long err_serial; /* serial number of first request */
95 static int (*old_error_handler)( Display *, XErrorEvent * );
96 static BOOL use_xim = TRUE;
97 static char input_style[20];
99 #define IS_OPTION_TRUE(ch) \
100 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
101 #define IS_OPTION_FALSE(ch) \
102 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
104 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
106 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
108 "CLIPBOARD",
109 "COMPOUND_TEXT",
110 "INCR",
111 "MANAGER",
112 "MULTIPLE",
113 "SELECTION_DATA",
114 "TARGETS",
115 "TEXT",
116 "TIMESTAMP",
117 "UTF8_STRING",
118 "RAW_ASCENT",
119 "RAW_DESCENT",
120 "RAW_CAP_HEIGHT",
121 "Rel X",
122 "Rel Y",
123 "WM_PROTOCOLS",
124 "WM_DELETE_WINDOW",
125 "WM_STATE",
126 "WM_TAKE_FOCUS",
127 "DndProtocol",
128 "DndSelection",
129 "_ICC_PROFILE",
130 "_MOTIF_WM_HINTS",
131 "_NET_STARTUP_INFO_BEGIN",
132 "_NET_STARTUP_INFO",
133 "_NET_SUPPORTED",
134 "_NET_SYSTEM_TRAY_OPCODE",
135 "_NET_SYSTEM_TRAY_S0",
136 "_NET_SYSTEM_TRAY_VISUAL",
137 "_NET_WM_ICON",
138 "_NET_WM_MOVERESIZE",
139 "_NET_WM_NAME",
140 "_NET_WM_PID",
141 "_NET_WM_PING",
142 "_NET_WM_STATE",
143 "_NET_WM_STATE_ABOVE",
144 "_NET_WM_STATE_DEMANDS_ATTENTION",
145 "_NET_WM_STATE_FULLSCREEN",
146 "_NET_WM_STATE_MAXIMIZED_HORZ",
147 "_NET_WM_STATE_MAXIMIZED_VERT",
148 "_NET_WM_STATE_SKIP_PAGER",
149 "_NET_WM_STATE_SKIP_TASKBAR",
150 "_NET_WM_USER_TIME",
151 "_NET_WM_USER_TIME_WINDOW",
152 "_NET_WM_WINDOW_OPACITY",
153 "_NET_WM_WINDOW_TYPE",
154 "_NET_WM_WINDOW_TYPE_DIALOG",
155 "_NET_WM_WINDOW_TYPE_NORMAL",
156 "_NET_WM_WINDOW_TYPE_UTILITY",
157 "_NET_WORKAREA",
158 "_XEMBED",
159 "_XEMBED_INFO",
160 "XdndAware",
161 "XdndEnter",
162 "XdndPosition",
163 "XdndStatus",
164 "XdndLeave",
165 "XdndFinished",
166 "XdndDrop",
167 "XdndActionCopy",
168 "XdndActionMove",
169 "XdndActionLink",
170 "XdndActionAsk",
171 "XdndActionPrivate",
172 "XdndSelection",
173 "XdndTypeList",
174 "HTML Format",
175 "WCF_DIF",
176 "WCF_ENHMETAFILE",
177 "WCF_HDROP",
178 "WCF_PENDATA",
179 "WCF_RIFF",
180 "WCF_SYLK",
181 "WCF_TIFF",
182 "WCF_WAVE",
183 "image/bmp",
184 "image/gif",
185 "image/jpeg",
186 "image/png",
187 "text/html",
188 "text/plain",
189 "text/rtf",
190 "text/richtext",
191 "text/uri-list"
194 /***********************************************************************
195 * ignore_error
197 * Check if the X error is one we can ignore.
199 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
201 if ((event->request_code == X_SetInputFocus ||
202 event->request_code == X_ChangeWindowAttributes ||
203 event->request_code == X_SendEvent) &&
204 (event->error_code == BadMatch ||
205 event->error_code == BadWindow)) return TRUE;
207 /* the clipboard display interacts with external windows, ignore all errors */
208 if (display == clipboard_display) return TRUE;
210 /* ignore a number of errors on gdi display caused by creating/destroying windows */
211 if (display == gdi_display)
213 if (event->error_code == BadDrawable ||
214 event->error_code == BadGC ||
215 event->error_code == BadWindow)
216 return TRUE;
217 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
218 if (xrender_error_base) /* check for XRender errors */
220 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
222 #endif
224 return FALSE;
228 /***********************************************************************
229 * X11DRV_expect_error
231 * Setup a callback function that will be called on an X error. The
232 * callback must return non-zero if the error is the one it expected.
234 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
236 err_callback = callback;
237 err_callback_display = display;
238 err_callback_arg = arg;
239 err_callback_result = 0;
240 err_serial = NextRequest(display);
244 /***********************************************************************
245 * X11DRV_check_error
247 * Check if an expected X11 error occurred; return non-zero if yes.
248 * The caller is responsible for calling XSync first if necessary.
250 int X11DRV_check_error(void)
252 err_callback = NULL;
253 return err_callback_result;
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 * init_pixmap_formats
291 static void init_pixmap_formats( Display *display )
293 int i, count, max = 32;
294 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
296 for (i = 0; i < count; i++)
298 TRACE( "depth %u, bpp %u, pad %u\n",
299 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
300 if (formats[i].depth > max) max = formats[i].depth;
302 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
303 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
307 /***********************************************************************
308 * get_config_key
310 * Get a config key from either the app-specific or the default config
312 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
313 char *buffer, DWORD size )
315 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
316 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
317 return ERROR_FILE_NOT_FOUND;
321 /***********************************************************************
322 * setup_options
324 * Setup the x11drv options.
326 static void setup_options(void)
328 static const WCHAR x11driverW[] = {'\\','X','1','1',' ','D','r','i','v','e','r',0};
329 char buffer[64];
330 WCHAR bufferW[MAX_PATH+16];
331 HKEY hkey, appkey = 0;
332 DWORD len;
334 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
335 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
337 /* open the app-specific key */
339 len = (GetModuleFileNameW( 0, bufferW, MAX_PATH ));
340 if (len && len < MAX_PATH)
342 HKEY tmpkey;
343 WCHAR *p, *appname = bufferW;
344 if ((p = strrchrW( appname, '/' ))) appname = p + 1;
345 if ((p = strrchrW( appname, '\\' ))) appname = p + 1;
346 len = WideCharToMultiByte( CP_UNIXCP, 0, appname, -1, NULL, 0, NULL, NULL );
347 if ((process_name = HeapAlloc( GetProcessHeap(), 0, len )))
348 WideCharToMultiByte( CP_UNIXCP, 0, appname, -1, process_name, len, NULL, NULL );
349 strcatW( appname, x11driverW );
350 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
351 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
353 if (RegOpenKeyW( tmpkey, appname, &appkey )) appkey = 0;
354 RegCloseKey( tmpkey );
358 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
359 managed_mode = IS_OPTION_TRUE( buffer[0] );
361 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
362 decorated_mode = IS_OPTION_TRUE( buffer[0] );
364 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
365 usexvidmode = IS_OPTION_TRUE( buffer[0] );
367 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
368 usexrandr = IS_OPTION_TRUE( buffer[0] );
370 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
371 use_take_focus = IS_OPTION_TRUE( buffer[0] );
373 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
374 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
376 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
377 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
379 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
380 show_systray = IS_OPTION_TRUE( buffer[0] );
382 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
383 grab_pointer = IS_OPTION_TRUE( buffer[0] );
385 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
386 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
388 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
389 default_visual.depth = atoi(buffer);
391 if (!get_config_key( hkey, appkey, "ClientSideGraphics", buffer, sizeof(buffer) ))
392 client_side_graphics = IS_OPTION_TRUE( buffer[0] );
394 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
395 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
397 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
398 use_xim = IS_OPTION_TRUE( buffer[0] );
400 if (!get_config_key( hkey, appkey, "ShapeLayeredWindows", buffer, sizeof(buffer) ))
401 shape_layered_windows = IS_OPTION_TRUE( buffer[0] );
403 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
404 private_color_map = IS_OPTION_TRUE( buffer[0] );
406 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
407 primary_monitor = atoi( buffer );
409 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
410 copy_default_colors = atoi(buffer);
412 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
413 alloc_system_colors = atoi(buffer);
415 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
417 if (appkey) RegCloseKey( appkey );
418 if (hkey) RegCloseKey( hkey );
421 #ifdef SONAME_LIBXCOMPOSITE
423 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
424 MAKE_FUNCPTR(XCompositeQueryExtension)
425 MAKE_FUNCPTR(XCompositeQueryVersion)
426 MAKE_FUNCPTR(XCompositeVersion)
427 MAKE_FUNCPTR(XCompositeRedirectWindow)
428 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
429 MAKE_FUNCPTR(XCompositeUnredirectWindow)
430 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
431 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
432 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
433 #undef MAKE_FUNCPTR
435 static int xcomp_event_base;
436 static int xcomp_error_base;
438 static void X11DRV_XComposite_Init(void)
440 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
441 if (!xcomposite_handle)
443 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
444 usexcomposite = FALSE;
445 return;
448 #define LOAD_FUNCPTR(f) \
449 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
450 goto sym_not_found;
451 LOAD_FUNCPTR(XCompositeQueryExtension)
452 LOAD_FUNCPTR(XCompositeQueryVersion)
453 LOAD_FUNCPTR(XCompositeVersion)
454 LOAD_FUNCPTR(XCompositeRedirectWindow)
455 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
456 LOAD_FUNCPTR(XCompositeUnredirectWindow)
457 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
458 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
459 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
460 #undef LOAD_FUNCPTR
462 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
463 &xcomp_error_base)) {
464 TRACE("XComposite extension could not be queried; disabled\n");
465 wine_dlclose(xcomposite_handle, NULL, 0);
466 xcomposite_handle = NULL;
467 usexcomposite = FALSE;
468 return;
470 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
471 return;
473 sym_not_found:
474 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
475 wine_dlclose(xcomposite_handle, NULL, 0);
476 xcomposite_handle = NULL;
477 usexcomposite = FALSE;
479 #endif /* defined(SONAME_LIBXCOMPOSITE) */
481 static void init_visuals( Display *display, int screen )
483 int count;
484 XVisualInfo *info;
486 default_visual.screen = screen;
487 if (default_visual.depth) /* depth specified */
489 info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask, &default_visual, &count );
490 if (info)
492 default_visual = *info;
493 XFree( info );
495 else WARN( "no visual found for depth %d\n", default_visual.depth );
498 if (!default_visual.visual)
500 default_visual.depth = DefaultDepth( display, screen );
501 default_visual.visual = DefaultVisual( display, screen );
502 default_visual.visualid = default_visual.visual->visualid;
503 default_visual.class = default_visual.visual->class;
504 default_visual.red_mask = default_visual.visual->red_mask;
505 default_visual.green_mask = default_visual.visual->green_mask;
506 default_visual.blue_mask = default_visual.visual->blue_mask;
507 default_visual.colormap_size = default_visual.visual->map_entries;
508 default_visual.bits_per_rgb = default_visual.visual->bits_per_rgb;
510 default_colormap = XCreateColormap( display, root_window, default_visual.visual, AllocNone );
512 argb_visual.screen = screen;
513 argb_visual.class = TrueColor;
514 argb_visual.depth = 32;
515 argb_visual.red_mask = 0xff0000;
516 argb_visual.green_mask = 0x00ff00;
517 argb_visual.blue_mask = 0x0000ff;
519 if ((info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask | VisualClassMask |
520 VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
521 &argb_visual, &count )))
523 argb_visual = *info;
524 XFree( info );
526 TRACE( "default visual %lx class %u argb %lx\n",
527 default_visual.visualid, default_visual.class, argb_visual.visualid );
530 /***********************************************************************
531 * X11DRV process initialisation routine
533 static BOOL process_attach(void)
535 char error[1024];
536 Display *display;
537 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
539 if (!libx11)
541 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
542 return FALSE;
544 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
545 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
546 #ifdef SONAME_LIBXEXT
547 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
548 #endif
550 setup_options();
552 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
554 /* Open display */
556 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
557 if (!(display = XOpenDisplay( NULL ))) return FALSE;
559 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
560 root_window = DefaultRootWindow( display );
561 gdi_display = display;
562 old_error_handler = XSetErrorHandler( error_handler );
564 init_pixmap_formats( display );
565 init_visuals( display, DefaultScreen( display ));
566 screen_bpp = pixmap_formats[default_visual.depth]->bits_per_pixel;
568 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
570 winContext = XUniqueContext();
571 win_data_context = XUniqueContext();
572 cursor_context = XUniqueContext();
574 if (TRACE_ON(synchronous)) XSynchronize( display, True );
576 xinerama_init( DisplayWidth( display, default_visual.screen ),
577 DisplayHeight( display, default_visual.screen ));
578 X11DRV_Settings_Init();
580 /* initialize XVidMode */
581 X11DRV_XF86VM_Init();
582 /* initialize XRandR */
583 X11DRV_XRandR_Init();
584 #ifdef SONAME_LIBXCOMPOSITE
585 X11DRV_XComposite_Init();
586 #endif
587 X11DRV_XInput2_Init();
589 #ifdef HAVE_XKB
590 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
591 #endif
592 X11DRV_InitKeyboard( gdi_display );
593 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
595 return TRUE;
599 /***********************************************************************
600 * ThreadDetach (X11DRV.@)
602 void CDECL X11DRV_ThreadDetach(void)
604 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
606 if (data)
608 if (data->xim) XCloseIM( data->xim );
609 if (data->font_set) XFreeFontSet( data->display, data->font_set );
610 XCloseDisplay( data->display );
611 HeapFree( GetProcessHeap(), 0, data );
612 /* clear data in case we get re-entered from user32 before the thread is truly dead */
613 TlsSetValue( thread_data_tls_index, NULL );
618 /* store the display fd into the message queue */
619 static void set_queue_display_fd( Display *display )
621 HANDLE handle;
622 int ret;
624 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
626 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
627 ExitProcess(1);
629 SERVER_START_REQ( set_queue_fd )
631 req->handle = wine_server_obj_handle( handle );
632 ret = wine_server_call( req );
634 SERVER_END_REQ;
635 if (ret)
637 MESSAGE( "x11drv: Can't store handle for display fd\n" );
638 ExitProcess(1);
640 CloseHandle( handle );
644 /***********************************************************************
645 * X11DRV thread initialisation routine
647 struct x11drv_thread_data *x11drv_init_thread_data(void)
649 struct x11drv_thread_data *data = x11drv_thread_data();
651 if (data) return data;
653 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
655 ERR( "could not create data\n" );
656 ExitProcess(1);
658 if (!(data->display = XOpenDisplay(NULL)))
660 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));
661 ExitProcess(1);
664 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
666 #ifdef HAVE_XKB
667 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
668 XkbSetDetectableAutoRepeat( data->display, True, NULL );
669 #endif
671 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
673 set_queue_display_fd( data->display );
674 TlsSetValue( thread_data_tls_index, data );
676 if (use_xim) X11DRV_SetupXIM();
678 return data;
682 /***********************************************************************
683 * X11DRV initialisation routine
685 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
687 BOOL ret = TRUE;
689 switch(reason)
691 case DLL_PROCESS_ATTACH:
692 DisableThreadLibraryCalls( hinst );
693 x11drv_module = hinst;
694 ret = process_attach();
695 break;
697 return ret;
701 /***********************************************************************
702 * SystemParametersInfo (X11DRV.@)
704 BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags )
706 switch (action)
708 case SPI_GETSCREENSAVEACTIVE:
709 if (ptr_param)
711 int timeout, temp;
712 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
713 *(BOOL *)ptr_param = timeout != 0;
714 return TRUE;
716 break;
717 case SPI_SETSCREENSAVEACTIVE:
719 int timeout, interval, prefer_blanking, allow_exposures;
720 static int last_timeout = 15 * 60;
722 XLockDisplay( gdi_display );
723 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
724 &allow_exposures);
725 if (timeout) last_timeout = timeout;
727 timeout = int_param ? last_timeout : 0;
728 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
729 allow_exposures);
730 XUnlockDisplay( gdi_display );
732 break;
734 return FALSE; /* let user32 handle it */