webservices: Don't allocate an XML buffer until it is needed.
[wine.git] / dlls / winex11.drv / x11drv_main.c
blob2127df4324686043c7f84202e5b887c62f714201
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 "TIMESTAMP",
115 "UTF8_STRING",
116 "RAW_ASCENT",
117 "RAW_DESCENT",
118 "RAW_CAP_HEIGHT",
119 "Rel X",
120 "Rel Y",
121 "WM_PROTOCOLS",
122 "WM_DELETE_WINDOW",
123 "WM_STATE",
124 "WM_TAKE_FOCUS",
125 "DndProtocol",
126 "DndSelection",
127 "_ICC_PROFILE",
128 "_MOTIF_WM_HINTS",
129 "_NET_STARTUP_INFO_BEGIN",
130 "_NET_STARTUP_INFO",
131 "_NET_SUPPORTED",
132 "_NET_SYSTEM_TRAY_OPCODE",
133 "_NET_SYSTEM_TRAY_S0",
134 "_NET_SYSTEM_TRAY_VISUAL",
135 "_NET_WM_ICON",
136 "_NET_WM_MOVERESIZE",
137 "_NET_WM_NAME",
138 "_NET_WM_PID",
139 "_NET_WM_PING",
140 "_NET_WM_STATE",
141 "_NET_WM_STATE_ABOVE",
142 "_NET_WM_STATE_DEMANDS_ATTENTION",
143 "_NET_WM_STATE_FULLSCREEN",
144 "_NET_WM_STATE_MAXIMIZED_HORZ",
145 "_NET_WM_STATE_MAXIMIZED_VERT",
146 "_NET_WM_STATE_SKIP_PAGER",
147 "_NET_WM_STATE_SKIP_TASKBAR",
148 "_NET_WM_USER_TIME",
149 "_NET_WM_USER_TIME_WINDOW",
150 "_NET_WM_WINDOW_OPACITY",
151 "_NET_WM_WINDOW_TYPE",
152 "_NET_WM_WINDOW_TYPE_DIALOG",
153 "_NET_WM_WINDOW_TYPE_NORMAL",
154 "_NET_WM_WINDOW_TYPE_UTILITY",
155 "_NET_WORKAREA",
156 "_XEMBED",
157 "_XEMBED_INFO",
158 "XdndAware",
159 "XdndEnter",
160 "XdndPosition",
161 "XdndStatus",
162 "XdndLeave",
163 "XdndFinished",
164 "XdndDrop",
165 "XdndActionCopy",
166 "XdndActionMove",
167 "XdndActionLink",
168 "XdndActionAsk",
169 "XdndActionPrivate",
170 "XdndSelection",
171 "XdndTypeList",
172 "HTML Format",
173 "WCF_DIF",
174 "WCF_ENHMETAFILE",
175 "WCF_HDROP",
176 "WCF_PENDATA",
177 "WCF_RIFF",
178 "WCF_SYLK",
179 "WCF_TIFF",
180 "WCF_WAVE",
181 "image/bmp",
182 "image/gif",
183 "image/jpeg",
184 "image/png",
185 "text/html",
186 "text/plain",
187 "text/rtf",
188 "text/richtext",
189 "text/uri-list"
192 /***********************************************************************
193 * ignore_error
195 * Check if the X error is one we can ignore.
197 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
199 if ((event->request_code == X_SetInputFocus ||
200 event->request_code == X_ChangeWindowAttributes ||
201 event->request_code == X_SendEvent) &&
202 (event->error_code == BadMatch ||
203 event->error_code == BadWindow)) return TRUE;
205 /* the clipboard display interacts with external windows, ignore all errors */
206 if (display == clipboard_display) return TRUE;
208 /* ignore a number of errors on gdi display caused by creating/destroying windows */
209 if (display == gdi_display)
211 if (event->error_code == BadDrawable ||
212 event->error_code == BadGC ||
213 event->error_code == BadWindow)
214 return TRUE;
215 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
216 if (xrender_error_base) /* check for XRender errors */
218 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
220 #endif
222 return FALSE;
226 /***********************************************************************
227 * X11DRV_expect_error
229 * Setup a callback function that will be called on an X error. The
230 * callback must return non-zero if the error is the one it expected.
232 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
234 err_callback = callback;
235 err_callback_display = display;
236 err_callback_arg = arg;
237 err_callback_result = 0;
238 err_serial = NextRequest(display);
242 /***********************************************************************
243 * X11DRV_check_error
245 * Check if an expected X11 error occurred; return non-zero if yes.
246 * The caller is responsible for calling XSync first if necessary.
248 int X11DRV_check_error(void)
250 err_callback = NULL;
251 return err_callback_result;
255 /***********************************************************************
256 * error_handler
258 static int error_handler( Display *display, XErrorEvent *error_evt )
260 if (err_callback && display == err_callback_display &&
261 (long)(error_evt->serial - err_serial) >= 0)
263 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
265 TRACE( "got expected error %d req %d\n",
266 error_evt->error_code, error_evt->request_code );
267 return 0;
270 if (ignore_error( display, error_evt ))
272 TRACE( "got ignored error %d req %d\n",
273 error_evt->error_code, error_evt->request_code );
274 return 0;
276 if (TRACE_ON(synchronous))
278 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
279 error_evt->serial, error_evt->request_code );
280 DebugBreak(); /* force an entry in the debugger */
282 old_error_handler( display, error_evt );
283 return 0;
286 /***********************************************************************
287 * init_pixmap_formats
289 static void init_pixmap_formats( Display *display )
291 int i, count, max = 32;
292 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
294 for (i = 0; i < count; i++)
296 TRACE( "depth %u, bpp %u, pad %u\n",
297 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
298 if (formats[i].depth > max) max = formats[i].depth;
300 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
301 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
305 /***********************************************************************
306 * get_config_key
308 * Get a config key from either the app-specific or the default config
310 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
311 char *buffer, DWORD size )
313 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
314 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
315 return ERROR_FILE_NOT_FOUND;
319 /***********************************************************************
320 * setup_options
322 * Setup the x11drv options.
324 static void setup_options(void)
326 char buffer[MAX_PATH+16];
327 HKEY hkey, appkey = 0;
328 DWORD len;
330 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
331 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
333 /* open the app-specific key */
335 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
336 if (len && len < MAX_PATH)
338 HKEY tmpkey;
339 char *p, *appname = buffer;
340 if ((p = strrchr( appname, '/' ))) appname = p + 1;
341 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
342 strcat( appname, "\\X11 Driver" );
343 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
344 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
346 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
347 RegCloseKey( tmpkey );
351 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
352 managed_mode = IS_OPTION_TRUE( buffer[0] );
354 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
355 decorated_mode = IS_OPTION_TRUE( buffer[0] );
357 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
358 usexvidmode = IS_OPTION_TRUE( buffer[0] );
360 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
361 usexrandr = IS_OPTION_TRUE( buffer[0] );
363 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
364 use_take_focus = IS_OPTION_TRUE( buffer[0] );
366 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
367 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
369 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
370 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
372 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
373 show_systray = IS_OPTION_TRUE( buffer[0] );
375 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
376 grab_pointer = IS_OPTION_TRUE( buffer[0] );
378 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
379 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
381 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
382 default_visual.depth = atoi(buffer);
384 if (!get_config_key( hkey, appkey, "ClientSideGraphics", buffer, sizeof(buffer) ))
385 client_side_graphics = IS_OPTION_TRUE( buffer[0] );
387 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
388 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
390 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
391 use_xim = IS_OPTION_TRUE( buffer[0] );
393 if (!get_config_key( hkey, appkey, "ShapeLayeredWindows", buffer, sizeof(buffer) ))
394 shape_layered_windows = IS_OPTION_TRUE( buffer[0] );
396 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
397 private_color_map = IS_OPTION_TRUE( buffer[0] );
399 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
400 primary_monitor = atoi( buffer );
402 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
403 copy_default_colors = atoi(buffer);
405 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
406 alloc_system_colors = atoi(buffer);
408 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
410 if (appkey) RegCloseKey( appkey );
411 if (hkey) RegCloseKey( hkey );
414 #ifdef SONAME_LIBXCOMPOSITE
416 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
417 MAKE_FUNCPTR(XCompositeQueryExtension)
418 MAKE_FUNCPTR(XCompositeQueryVersion)
419 MAKE_FUNCPTR(XCompositeVersion)
420 MAKE_FUNCPTR(XCompositeRedirectWindow)
421 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
422 MAKE_FUNCPTR(XCompositeUnredirectWindow)
423 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
424 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
425 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
426 #undef MAKE_FUNCPTR
428 static int xcomp_event_base;
429 static int xcomp_error_base;
431 static void X11DRV_XComposite_Init(void)
433 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
434 if (!xcomposite_handle)
436 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
437 usexcomposite = FALSE;
438 return;
441 #define LOAD_FUNCPTR(f) \
442 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
443 goto sym_not_found;
444 LOAD_FUNCPTR(XCompositeQueryExtension)
445 LOAD_FUNCPTR(XCompositeQueryVersion)
446 LOAD_FUNCPTR(XCompositeVersion)
447 LOAD_FUNCPTR(XCompositeRedirectWindow)
448 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
449 LOAD_FUNCPTR(XCompositeUnredirectWindow)
450 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
451 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
452 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
453 #undef LOAD_FUNCPTR
455 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
456 &xcomp_error_base)) {
457 TRACE("XComposite extension could not be queried; disabled\n");
458 wine_dlclose(xcomposite_handle, NULL, 0);
459 xcomposite_handle = NULL;
460 usexcomposite = FALSE;
461 return;
463 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
464 return;
466 sym_not_found:
467 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
468 wine_dlclose(xcomposite_handle, NULL, 0);
469 xcomposite_handle = NULL;
470 usexcomposite = FALSE;
472 #endif /* defined(SONAME_LIBXCOMPOSITE) */
474 static void init_visuals( Display *display, int screen )
476 int count;
477 XVisualInfo *info;
479 default_visual.screen = screen;
480 if (default_visual.depth) /* depth specified */
482 info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask, &default_visual, &count );
483 if (info)
485 default_visual = *info;
486 XFree( info );
488 else WARN( "no visual found for depth %d\n", default_visual.depth );
491 if (!default_visual.visual)
493 default_visual.depth = DefaultDepth( display, screen );
494 default_visual.visual = DefaultVisual( display, screen );
495 default_visual.visualid = default_visual.visual->visualid;
496 default_visual.class = default_visual.visual->class;
497 default_visual.red_mask = default_visual.visual->red_mask;
498 default_visual.green_mask = default_visual.visual->green_mask;
499 default_visual.blue_mask = default_visual.visual->blue_mask;
500 default_visual.colormap_size = default_visual.visual->map_entries;
501 default_visual.bits_per_rgb = default_visual.visual->bits_per_rgb;
503 default_colormap = XCreateColormap( display, root_window, default_visual.visual, AllocNone );
505 argb_visual.screen = screen;
506 argb_visual.class = TrueColor;
507 argb_visual.depth = 32;
508 argb_visual.red_mask = 0xff0000;
509 argb_visual.green_mask = 0x00ff00;
510 argb_visual.blue_mask = 0x0000ff;
512 if ((info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask | VisualClassMask |
513 VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
514 &argb_visual, &count )))
516 argb_visual = *info;
517 XFree( info );
519 TRACE( "default visual %lx class %u argb %lx\n",
520 default_visual.visualid, default_visual.class, argb_visual.visualid );
523 /***********************************************************************
524 * X11DRV process initialisation routine
526 static BOOL process_attach(void)
528 char error[1024];
529 Display *display;
530 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
532 if (!libx11)
534 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
535 return FALSE;
537 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
538 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
539 #ifdef SONAME_LIBXEXT
540 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
541 #endif
543 setup_options();
545 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
547 /* Open display */
549 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
550 if (!(display = XOpenDisplay( NULL ))) return FALSE;
552 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
553 root_window = DefaultRootWindow( display );
554 gdi_display = display;
555 old_error_handler = XSetErrorHandler( error_handler );
557 init_pixmap_formats( display );
558 init_visuals( display, DefaultScreen( display ));
559 screen_bpp = pixmap_formats[default_visual.depth]->bits_per_pixel;
561 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
563 winContext = XUniqueContext();
564 win_data_context = XUniqueContext();
565 cursor_context = XUniqueContext();
567 if (TRACE_ON(synchronous)) XSynchronize( display, True );
569 xinerama_init( DisplayWidth( display, default_visual.screen ),
570 DisplayHeight( display, default_visual.screen ));
571 X11DRV_Settings_Init();
573 /* initialize XVidMode */
574 X11DRV_XF86VM_Init();
575 /* initialize XRandR */
576 X11DRV_XRandR_Init();
577 #ifdef SONAME_LIBXCOMPOSITE
578 X11DRV_XComposite_Init();
579 #endif
580 X11DRV_XInput2_Init();
582 #ifdef HAVE_XKB
583 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
584 #endif
585 X11DRV_InitKeyboard( gdi_display );
586 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
588 return TRUE;
592 /***********************************************************************
593 * ThreadDetach (X11DRV.@)
595 void CDECL X11DRV_ThreadDetach(void)
597 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
599 if (data)
601 if (data->xim) XCloseIM( data->xim );
602 if (data->font_set) XFreeFontSet( data->display, data->font_set );
603 XCloseDisplay( data->display );
604 HeapFree( GetProcessHeap(), 0, data );
605 /* clear data in case we get re-entered from user32 before the thread is truly dead */
606 TlsSetValue( thread_data_tls_index, NULL );
611 /* store the display fd into the message queue */
612 static void set_queue_display_fd( Display *display )
614 HANDLE handle;
615 int ret;
617 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
619 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
620 ExitProcess(1);
622 SERVER_START_REQ( set_queue_fd )
624 req->handle = wine_server_obj_handle( handle );
625 ret = wine_server_call( req );
627 SERVER_END_REQ;
628 if (ret)
630 MESSAGE( "x11drv: Can't store handle for display fd\n" );
631 ExitProcess(1);
633 CloseHandle( handle );
637 /***********************************************************************
638 * X11DRV thread initialisation routine
640 struct x11drv_thread_data *x11drv_init_thread_data(void)
642 struct x11drv_thread_data *data = x11drv_thread_data();
644 if (data) return data;
646 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
648 ERR( "could not create data\n" );
649 ExitProcess(1);
651 if (!(data->display = XOpenDisplay(NULL)))
653 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));
654 ExitProcess(1);
657 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
659 #ifdef HAVE_XKB
660 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
661 XkbSetDetectableAutoRepeat( data->display, True, NULL );
662 #endif
664 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
666 set_queue_display_fd( data->display );
667 TlsSetValue( thread_data_tls_index, data );
669 if (use_xim) X11DRV_SetupXIM();
671 return data;
675 /***********************************************************************
676 * X11DRV initialisation routine
678 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
680 BOOL ret = TRUE;
682 switch(reason)
684 case DLL_PROCESS_ATTACH:
685 DisableThreadLibraryCalls( hinst );
686 x11drv_module = hinst;
687 ret = process_attach();
688 break;
690 return ret;
694 /***********************************************************************
695 * SystemParametersInfo (X11DRV.@)
697 BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags )
699 switch (action)
701 case SPI_GETSCREENSAVEACTIVE:
702 if (ptr_param)
704 int timeout, temp;
705 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
706 *(BOOL *)ptr_param = timeout != 0;
707 return TRUE;
709 break;
710 case SPI_SETSCREENSAVEACTIVE:
712 int timeout, interval, prefer_blanking, allow_exposures;
713 static int last_timeout = 15 * 60;
715 XLockDisplay( gdi_display );
716 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
717 &allow_exposures);
718 if (timeout) last_timeout = timeout;
720 timeout = int_param ? last_timeout : 0;
721 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
722 allow_exposures);
723 XUnlockDisplay( gdi_display );
725 break;
727 return FALSE; /* let user32 handle it */