winetest: Include language settings in OS info.
[wine/multimedia.git] / dlls / winex11.drv / x11drv_main.c
blob8e2082d008cebce5bcf624a62781660019479117
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 "xvidmode.h"
51 #include "xrandr.h"
52 #include "xcomposite.h"
53 #include "wine/server.h"
54 #include "wine/debug.h"
55 #include "wine/library.h"
57 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
58 WINE_DECLARE_DEBUG_CHANNEL(synchronous);
59 WINE_DECLARE_DEBUG_CHANNEL(winediag);
61 static CRITICAL_SECTION X11DRV_CritSection;
62 static CRITICAL_SECTION_DEBUG critsect_debug =
64 0, 0, &X11DRV_CritSection,
65 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
66 0, 0, { (DWORD_PTR)(__FILE__ ": X11DRV_CritSection") }
68 static CRITICAL_SECTION X11DRV_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };
70 static Screen *screen;
71 Visual *visual;
72 XPixmapFormatValues **pixmap_formats;
73 unsigned int screen_width;
74 unsigned int screen_height;
75 unsigned int screen_bpp;
76 unsigned int screen_depth;
77 RECT virtual_screen_rect;
78 Window root_window;
79 int usexvidmode = 1;
80 int usexrandr = 1;
81 int usexcomposite = 1;
82 int use_xkb = 1;
83 int use_take_focus = 1;
84 int use_primary_selection = 0;
85 int use_system_cursors = 1;
86 int show_systray = 1;
87 int grab_pointer = 1;
88 int grab_fullscreen = 0;
89 int managed_mode = 1;
90 int decorated_mode = 1;
91 int private_color_map = 0;
92 int primary_monitor = 0;
93 int client_side_with_core = 1;
94 int client_side_with_render = 1;
95 int client_side_antialias_with_core = 1;
96 int client_side_antialias_with_render = 1;
97 int copy_default_colors = 128;
98 int alloc_system_colors = 256;
99 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
100 int xrender_error_base = 0;
101 HMODULE x11drv_module = 0;
103 static x11drv_error_callback err_callback; /* current callback for error */
104 static Display *err_callback_display; /* display callback is set for */
105 static void *err_callback_arg; /* error callback argument */
106 static int err_callback_result; /* error callback result */
107 static unsigned long err_serial; /* serial number of first request */
108 static int (*old_error_handler)( Display *, XErrorEvent * );
109 static int use_xim = 1;
110 static char input_style[20];
112 #define IS_OPTION_TRUE(ch) \
113 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
114 #define IS_OPTION_FALSE(ch) \
115 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
117 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
119 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
121 "CLIPBOARD",
122 "COMPOUND_TEXT",
123 "INCR",
124 "MANAGER",
125 "MULTIPLE",
126 "SELECTION_DATA",
127 "TARGETS",
128 "TEXT",
129 "UTF8_STRING",
130 "RAW_ASCENT",
131 "RAW_DESCENT",
132 "RAW_CAP_HEIGHT",
133 "WM_PROTOCOLS",
134 "WM_DELETE_WINDOW",
135 "WM_STATE",
136 "WM_TAKE_FOCUS",
137 "DndProtocol",
138 "DndSelection",
139 "_ICC_PROFILE",
140 "_MOTIF_WM_HINTS",
141 "_NET_STARTUP_INFO_BEGIN",
142 "_NET_STARTUP_INFO",
143 "_NET_SUPPORTED",
144 "_NET_SYSTEM_TRAY_OPCODE",
145 "_NET_SYSTEM_TRAY_S0",
146 "_NET_WM_ICON",
147 "_NET_WM_MOVERESIZE",
148 "_NET_WM_NAME",
149 "_NET_WM_PID",
150 "_NET_WM_PING",
151 "_NET_WM_STATE",
152 "_NET_WM_STATE_ABOVE",
153 "_NET_WM_STATE_FULLSCREEN",
154 "_NET_WM_STATE_MAXIMIZED_HORZ",
155 "_NET_WM_STATE_MAXIMIZED_VERT",
156 "_NET_WM_STATE_SKIP_PAGER",
157 "_NET_WM_STATE_SKIP_TASKBAR",
158 "_NET_WM_USER_TIME",
159 "_NET_WM_USER_TIME_WINDOW",
160 "_NET_WM_WINDOW_OPACITY",
161 "_NET_WM_WINDOW_TYPE",
162 "_NET_WM_WINDOW_TYPE_DIALOG",
163 "_NET_WM_WINDOW_TYPE_NORMAL",
164 "_NET_WM_WINDOW_TYPE_UTILITY",
165 "_NET_WORKAREA",
166 "_XEMBED",
167 "_XEMBED_INFO",
168 "XdndAware",
169 "XdndEnter",
170 "XdndPosition",
171 "XdndStatus",
172 "XdndLeave",
173 "XdndFinished",
174 "XdndDrop",
175 "XdndActionCopy",
176 "XdndActionMove",
177 "XdndActionLink",
178 "XdndActionAsk",
179 "XdndActionPrivate",
180 "XdndSelection",
181 "XdndTarget",
182 "XdndTypeList",
183 "HTML Format",
184 "WCF_BITMAP",
185 "WCF_DIB",
186 "WCF_DIBV5",
187 "WCF_DIF",
188 "WCF_DSPBITMAP",
189 "WCF_DSPENHMETAFILE",
190 "WCF_DSPMETAFILEPICT",
191 "WCF_DSPTEXT",
192 "WCF_ENHMETAFILE",
193 "WCF_HDROP",
194 "WCF_LOCALE",
195 "WCF_METAFILEPICT",
196 "WCF_OEMTEXT",
197 "WCF_OWNERDISPLAY",
198 "WCF_PALETTE",
199 "WCF_PENDATA",
200 "WCF_RIFF",
201 "WCF_SYLK",
202 "WCF_TIFF",
203 "WCF_WAVE",
204 "image/bmp",
205 "image/gif",
206 "image/jpeg",
207 "image/png",
208 "text/html",
209 "text/plain",
210 "text/rtf",
211 "text/richtext",
212 "text/uri-list"
215 /***********************************************************************
216 * ignore_error
218 * Check if the X error is one we can ignore.
220 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
222 if ((event->request_code == X_SetInputFocus || event->request_code == X_ChangeWindowAttributes) &&
223 (event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE;
225 /* ignore a number of errors on gdi display caused by creating/destroying windows */
226 if (display == gdi_display)
228 if (event->error_code == BadDrawable ||
229 event->error_code == BadGC ||
230 event->error_code == BadWindow)
231 return TRUE;
232 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
233 if (xrender_error_base) /* check for XRender errors */
235 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
237 #endif
239 return FALSE;
243 /***********************************************************************
244 * X11DRV_expect_error
246 * Setup a callback function that will be called on an X error. The
247 * callback must return non-zero if the error is the one it expected.
248 * This function acquires the x11 lock; X11DRV_check_error must be
249 * called in all cases to release it.
251 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
253 wine_tsx11_lock();
254 err_callback = callback;
255 err_callback_display = display;
256 err_callback_arg = arg;
257 err_callback_result = 0;
258 err_serial = NextRequest(display);
262 /***********************************************************************
263 * X11DRV_check_error
265 * Check if an expected X11 error occurred; return non-zero if yes.
266 * Also release the x11 lock obtained in X11DRV_expect_error.
267 * The caller is responsible for calling XSync first if necessary.
269 int X11DRV_check_error(void)
271 int ret;
272 err_callback = NULL;
273 ret = err_callback_result;
274 wine_tsx11_unlock();
275 return ret;
279 /***********************************************************************
280 * error_handler
282 static int error_handler( Display *display, XErrorEvent *error_evt )
284 if (err_callback && display == err_callback_display &&
285 (long)(error_evt->serial - err_serial) >= 0)
287 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
289 TRACE( "got expected error %d req %d\n",
290 error_evt->error_code, error_evt->request_code );
291 return 0;
294 if (ignore_error( display, error_evt ))
296 TRACE( "got ignored error %d req %d\n",
297 error_evt->error_code, error_evt->request_code );
298 return 0;
300 if (TRACE_ON(synchronous))
302 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
303 error_evt->serial, error_evt->request_code );
304 DebugBreak(); /* force an entry in the debugger */
306 old_error_handler( display, error_evt );
307 return 0;
310 /***********************************************************************
311 * wine_tsx11_lock (X11DRV.@)
313 void CDECL wine_tsx11_lock(void)
315 EnterCriticalSection( &X11DRV_CritSection );
318 /***********************************************************************
319 * wine_tsx11_unlock (X11DRV.@)
321 void CDECL wine_tsx11_unlock(void)
323 LeaveCriticalSection( &X11DRV_CritSection );
327 /***********************************************************************
328 * init_pixmap_formats
330 static void init_pixmap_formats( Display *display )
332 int i, count, max = 32;
333 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
335 for (i = 0; i < count; i++)
337 TRACE( "depth %u, bpp %u, pad %u\n",
338 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
339 if (formats[i].depth > max) max = formats[i].depth;
341 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
342 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
346 /***********************************************************************
347 * get_config_key
349 * Get a config key from either the app-specific or the default config
351 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
352 char *buffer, DWORD size )
354 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
355 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
356 return ERROR_FILE_NOT_FOUND;
360 /***********************************************************************
361 * setup_options
363 * Setup the x11drv options.
365 static void setup_options(void)
367 char buffer[MAX_PATH+16];
368 HKEY hkey, appkey = 0;
369 DWORD len;
371 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
372 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
374 /* open the app-specific key */
376 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
377 if (len && len < MAX_PATH)
379 HKEY tmpkey;
380 char *p, *appname = buffer;
381 if ((p = strrchr( appname, '/' ))) appname = p + 1;
382 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
383 strcat( appname, "\\X11 Driver" );
384 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
385 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
387 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
388 RegCloseKey( tmpkey );
392 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
393 managed_mode = IS_OPTION_TRUE( buffer[0] );
395 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
396 decorated_mode = IS_OPTION_TRUE( buffer[0] );
398 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
399 usexvidmode = IS_OPTION_TRUE( buffer[0] );
401 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
402 usexrandr = IS_OPTION_TRUE( buffer[0] );
404 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
405 use_take_focus = IS_OPTION_TRUE( buffer[0] );
407 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
408 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
410 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
411 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
413 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
414 show_systray = IS_OPTION_TRUE( buffer[0] );
416 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
417 grab_pointer = IS_OPTION_TRUE( buffer[0] );
419 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
420 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
422 screen_depth = 0;
423 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
424 screen_depth = atoi(buffer);
426 if (!get_config_key( hkey, appkey, "ClientSideWithCore", buffer, sizeof(buffer) ))
427 client_side_with_core = IS_OPTION_TRUE( buffer[0] );
429 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
430 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
432 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithCore", buffer, sizeof(buffer) ))
433 client_side_antialias_with_core = IS_OPTION_TRUE( buffer[0] );
435 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithRender", buffer, sizeof(buffer) ))
436 client_side_antialias_with_render = IS_OPTION_TRUE( buffer[0] );
438 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
439 use_xim = IS_OPTION_TRUE( buffer[0] );
441 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
442 private_color_map = IS_OPTION_TRUE( buffer[0] );
444 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
445 primary_monitor = atoi( buffer );
447 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
448 copy_default_colors = atoi(buffer);
450 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
451 alloc_system_colors = atoi(buffer);
453 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
455 if (appkey) RegCloseKey( appkey );
456 if (hkey) RegCloseKey( hkey );
459 #ifdef SONAME_LIBXCOMPOSITE
461 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
462 MAKE_FUNCPTR(XCompositeQueryExtension)
463 MAKE_FUNCPTR(XCompositeQueryVersion)
464 MAKE_FUNCPTR(XCompositeVersion)
465 MAKE_FUNCPTR(XCompositeRedirectWindow)
466 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
467 MAKE_FUNCPTR(XCompositeUnredirectWindow)
468 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
469 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
470 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
471 #undef MAKE_FUNCPTR
473 static int xcomp_event_base;
474 static int xcomp_error_base;
476 static void X11DRV_XComposite_Init(void)
478 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
479 if (!xcomposite_handle)
481 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
482 usexcomposite = 0;
483 return;
486 #define LOAD_FUNCPTR(f) \
487 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
488 goto sym_not_found;
489 LOAD_FUNCPTR(XCompositeQueryExtension)
490 LOAD_FUNCPTR(XCompositeQueryVersion)
491 LOAD_FUNCPTR(XCompositeVersion)
492 LOAD_FUNCPTR(XCompositeRedirectWindow)
493 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
494 LOAD_FUNCPTR(XCompositeUnredirectWindow)
495 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
496 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
497 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
498 #undef LOAD_FUNCPTR
500 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
501 &xcomp_error_base)) {
502 TRACE("XComposite extension could not be queried; disabled\n");
503 wine_dlclose(xcomposite_handle, NULL, 0);
504 xcomposite_handle = NULL;
505 usexcomposite = 0;
506 return;
508 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
509 return;
511 sym_not_found:
512 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
513 wine_dlclose(xcomposite_handle, NULL, 0);
514 xcomposite_handle = NULL;
515 usexcomposite = 0;
517 #endif /* defined(SONAME_LIBXCOMPOSITE) */
520 /***********************************************************************
521 * X11DRV process initialisation routine
523 static BOOL process_attach(void)
525 char error[1024];
526 Display *display;
527 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
529 if (!libx11)
531 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
532 return FALSE;
534 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
535 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
536 #ifdef SONAME_LIBXEXT
537 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
538 #endif
540 setup_options();
542 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
544 /* Open display */
546 if (!(display = XOpenDisplay( NULL ))) return FALSE;
548 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
549 screen = DefaultScreenOfDisplay( display );
550 visual = DefaultVisual( display, DefaultScreen(display) );
551 root_window = DefaultRootWindow( display );
552 gdi_display = display;
553 old_error_handler = XSetErrorHandler( error_handler );
555 /* Initialize screen depth */
557 if (screen_depth) /* depth specified */
559 int depth_count, i;
560 int *depth_list = XListDepths(display, DefaultScreen(display), &depth_count);
561 for (i = 0; i < depth_count; i++)
562 if (depth_list[i] == screen_depth) break;
563 XFree( depth_list );
564 if (i >= depth_count)
566 WARN( "invalid depth %d, using default\n", screen_depth );
567 screen_depth = 0;
570 if (!screen_depth) screen_depth = DefaultDepthOfScreen( screen );
571 init_pixmap_formats( display );
572 screen_bpp = pixmap_formats[screen_depth]->bits_per_pixel;
574 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
576 if (TRACE_ON(synchronous)) XSynchronize( display, True );
578 xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
579 X11DRV_Settings_Init();
581 #ifdef SONAME_LIBXXF86VM
582 /* initialize XVidMode */
583 X11DRV_XF86VM_Init();
584 #endif
585 #ifdef SONAME_LIBXRANDR
586 /* initialize XRandR */
587 X11DRV_XRandR_Init();
588 #endif
589 #ifdef SONAME_LIBXCOMPOSITE
590 X11DRV_XComposite_Init();
591 #endif
592 X11DRV_XInput2_Init();
594 #ifdef HAVE_XKB
595 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
596 #endif
597 X11DRV_InitKeyboard( gdi_display );
598 X11DRV_InitClipboard();
599 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
601 return TRUE;
605 /***********************************************************************
606 * X11DRV thread termination routine
608 static void thread_detach(void)
610 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
612 if (data)
614 X11DRV_ResetSelectionOwner();
615 wine_tsx11_lock();
616 if (data->xim) XCloseIM( data->xim );
617 if (data->font_set) XFreeFontSet( data->display, data->font_set );
618 XCloseDisplay( data->display );
619 wine_tsx11_unlock();
620 HeapFree( GetProcessHeap(), 0, data );
625 /***********************************************************************
626 * X11DRV process termination routine
628 static void process_detach(void)
630 X11DRV_Clipboard_Cleanup();
631 #ifdef SONAME_LIBXXF86VM
632 /* cleanup XVidMode */
633 X11DRV_XF86VM_Cleanup();
634 #endif
635 if(using_client_side_fonts)
636 X11DRV_XRender_Finalize();
638 /* cleanup GDI */
639 X11DRV_GDI_Finalize();
640 X11DRV_OpenGL_Cleanup();
642 IME_UnregisterClasses();
643 DeleteCriticalSection( &X11DRV_CritSection );
644 TlsFree( thread_data_tls_index );
648 /* store the display fd into the message queue */
649 static void set_queue_display_fd( Display *display )
651 HANDLE handle;
652 int ret;
654 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
656 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
657 ExitProcess(1);
659 SERVER_START_REQ( set_queue_fd )
661 req->handle = wine_server_obj_handle( handle );
662 ret = wine_server_call( req );
664 SERVER_END_REQ;
665 if (ret)
667 MESSAGE( "x11drv: Can't store handle for display fd\n" );
668 ExitProcess(1);
670 CloseHandle( handle );
674 /***********************************************************************
675 * X11DRV thread initialisation routine
677 struct x11drv_thread_data *x11drv_init_thread_data(void)
679 struct x11drv_thread_data *data = x11drv_thread_data();
681 if (data) return data;
683 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
685 ERR( "could not create data\n" );
686 ExitProcess(1);
688 wine_tsx11_lock();
689 if (!(data->display = XOpenDisplay(NULL)))
691 wine_tsx11_unlock();
692 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));
693 ExitProcess(1);
696 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
698 #ifdef HAVE_XKB
699 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
700 XkbSetDetectableAutoRepeat( data->display, True, NULL );
701 #endif
703 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
704 wine_tsx11_unlock();
706 set_queue_display_fd( data->display );
707 TlsSetValue( thread_data_tls_index, data );
709 if (use_xim) X11DRV_SetupXIM();
711 return data;
715 /***********************************************************************
716 * X11DRV initialisation routine
718 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
720 BOOL ret = TRUE;
722 switch(reason)
724 case DLL_PROCESS_ATTACH:
725 x11drv_module = hinst;
726 ret = process_attach();
727 break;
728 case DLL_THREAD_DETACH:
729 thread_detach();
730 break;
731 case DLL_PROCESS_DETACH:
732 process_detach();
733 break;
735 return ret;
738 /***********************************************************************
739 * GetScreenSaveActive (X11DRV.@)
741 * Returns the active status of the screen saver
743 BOOL CDECL X11DRV_GetScreenSaveActive(void)
745 int timeout, temp;
746 wine_tsx11_lock();
747 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
748 wine_tsx11_unlock();
749 return timeout != 0;
752 /***********************************************************************
753 * SetScreenSaveActive (X11DRV.@)
755 * Activate/Deactivate the screen saver
757 void CDECL X11DRV_SetScreenSaveActive(BOOL bActivate)
759 int timeout, interval, prefer_blanking, allow_exposures;
760 static int last_timeout = 15 * 60;
762 wine_tsx11_lock();
763 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
764 &allow_exposures);
765 if (timeout) last_timeout = timeout;
767 timeout = bActivate ? last_timeout : 0;
768 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
769 allow_exposures);
770 wine_tsx11_unlock();