d3dx9: Start effect state parsing.
[wine/multimedia.git] / dlls / winex11.drv / x11drv_main.c
blob9b01829feb5f2ed65c14b85d000be2aa9ed80163
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 unsigned int screen_width;
73 unsigned int screen_height;
74 unsigned int screen_bpp;
75 unsigned int screen_depth;
76 RECT virtual_screen_rect;
77 Window root_window;
78 int usexvidmode = 1;
79 int usexrandr = 1;
80 int usexcomposite = 1;
81 int use_xkb = 1;
82 int use_take_focus = 1;
83 int use_primary_selection = 0;
84 int use_system_cursors = 1;
85 int show_systray = 1;
86 int grab_pointer = 1;
87 int grab_fullscreen = 0;
88 int managed_mode = 1;
89 int decorated_mode = 1;
90 int private_color_map = 0;
91 int primary_monitor = 0;
92 int client_side_with_core = 1;
93 int client_side_with_render = 1;
94 int client_side_antialias_with_core = 1;
95 int client_side_antialias_with_render = 1;
96 int copy_default_colors = 128;
97 int alloc_system_colors = 256;
98 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
99 int xrender_error_base = 0;
100 HMODULE x11drv_module = 0;
102 static x11drv_error_callback err_callback; /* current callback for error */
103 static Display *err_callback_display; /* display callback is set for */
104 static void *err_callback_arg; /* error callback argument */
105 static int err_callback_result; /* error callback result */
106 static unsigned long err_serial; /* serial number of first request */
107 static int (*old_error_handler)( Display *, XErrorEvent * );
108 static int use_xim = 1;
109 static char input_style[20];
111 #define IS_OPTION_TRUE(ch) \
112 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
113 #define IS_OPTION_FALSE(ch) \
114 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
116 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
118 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
120 "CLIPBOARD",
121 "COMPOUND_TEXT",
122 "INCR",
123 "MANAGER",
124 "MULTIPLE",
125 "SELECTION_DATA",
126 "TARGETS",
127 "TEXT",
128 "UTF8_STRING",
129 "RAW_ASCENT",
130 "RAW_DESCENT",
131 "RAW_CAP_HEIGHT",
132 "WM_PROTOCOLS",
133 "WM_DELETE_WINDOW",
134 "WM_STATE",
135 "WM_TAKE_FOCUS",
136 "DndProtocol",
137 "DndSelection",
138 "_ICC_PROFILE",
139 "_MOTIF_WM_HINTS",
140 "_NET_STARTUP_INFO_BEGIN",
141 "_NET_STARTUP_INFO",
142 "_NET_SUPPORTED",
143 "_NET_SYSTEM_TRAY_OPCODE",
144 "_NET_SYSTEM_TRAY_S0",
145 "_NET_WM_ICON",
146 "_NET_WM_MOVERESIZE",
147 "_NET_WM_NAME",
148 "_NET_WM_PID",
149 "_NET_WM_PING",
150 "_NET_WM_STATE",
151 "_NET_WM_STATE_ABOVE",
152 "_NET_WM_STATE_FULLSCREEN",
153 "_NET_WM_STATE_MAXIMIZED_HORZ",
154 "_NET_WM_STATE_MAXIMIZED_VERT",
155 "_NET_WM_STATE_SKIP_PAGER",
156 "_NET_WM_STATE_SKIP_TASKBAR",
157 "_NET_WM_USER_TIME",
158 "_NET_WM_USER_TIME_WINDOW",
159 "_NET_WM_WINDOW_OPACITY",
160 "_NET_WM_WINDOW_TYPE",
161 "_NET_WM_WINDOW_TYPE_DIALOG",
162 "_NET_WM_WINDOW_TYPE_NORMAL",
163 "_NET_WM_WINDOW_TYPE_UTILITY",
164 "_NET_WORKAREA",
165 "_XEMBED",
166 "_XEMBED_INFO",
167 "XdndAware",
168 "XdndEnter",
169 "XdndPosition",
170 "XdndStatus",
171 "XdndLeave",
172 "XdndFinished",
173 "XdndDrop",
174 "XdndActionCopy",
175 "XdndActionMove",
176 "XdndActionLink",
177 "XdndActionAsk",
178 "XdndActionPrivate",
179 "XdndSelection",
180 "XdndTarget",
181 "XdndTypeList",
182 "HTML Format",
183 "WCF_BITMAP",
184 "WCF_DIB",
185 "WCF_DIBV5",
186 "WCF_DIF",
187 "WCF_DSPBITMAP",
188 "WCF_DSPENHMETAFILE",
189 "WCF_DSPMETAFILEPICT",
190 "WCF_DSPTEXT",
191 "WCF_ENHMETAFILE",
192 "WCF_HDROP",
193 "WCF_LOCALE",
194 "WCF_METAFILEPICT",
195 "WCF_OEMTEXT",
196 "WCF_OWNERDISPLAY",
197 "WCF_PALETTE",
198 "WCF_PENDATA",
199 "WCF_RIFF",
200 "WCF_SYLK",
201 "WCF_TIFF",
202 "WCF_WAVE",
203 "image/bmp",
204 "image/gif",
205 "image/jpeg",
206 "image/png",
207 "text/html",
208 "text/plain",
209 "text/rtf",
210 "text/richtext",
211 "text/uri-list"
214 /***********************************************************************
215 * ignore_error
217 * Check if the X error is one we can ignore.
219 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
221 if ((event->request_code == X_SetInputFocus || event->request_code == X_ChangeWindowAttributes) &&
222 (event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE;
224 /* ignore a number of errors on gdi display caused by creating/destroying windows */
225 if (display == gdi_display)
227 if (event->error_code == BadDrawable ||
228 event->error_code == BadGC ||
229 event->error_code == BadWindow)
230 return TRUE;
231 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
232 if (xrender_error_base) /* check for XRender errors */
234 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
236 #endif
238 return FALSE;
242 /***********************************************************************
243 * X11DRV_expect_error
245 * Setup a callback function that will be called on an X error. The
246 * callback must return non-zero if the error is the one it expected.
247 * This function acquires the x11 lock; X11DRV_check_error must be
248 * called in all cases to release it.
250 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
252 wine_tsx11_lock();
253 err_callback = callback;
254 err_callback_display = display;
255 err_callback_arg = arg;
256 err_callback_result = 0;
257 err_serial = NextRequest(display);
261 /***********************************************************************
262 * X11DRV_check_error
264 * Check if an expected X11 error occurred; return non-zero if yes.
265 * Also release the x11 lock obtained in X11DRV_expect_error.
266 * The caller is responsible for calling XSync first if necessary.
268 int X11DRV_check_error(void)
270 int ret;
271 err_callback = NULL;
272 ret = err_callback_result;
273 wine_tsx11_unlock();
274 return ret;
278 /***********************************************************************
279 * error_handler
281 static int error_handler( Display *display, XErrorEvent *error_evt )
283 if (err_callback && display == err_callback_display &&
284 (long)(error_evt->serial - err_serial) >= 0)
286 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
288 TRACE( "got expected error %d req %d\n",
289 error_evt->error_code, error_evt->request_code );
290 return 0;
293 if (ignore_error( display, error_evt ))
295 TRACE( "got ignored error %d req %d\n",
296 error_evt->error_code, error_evt->request_code );
297 return 0;
299 if (TRACE_ON(synchronous))
301 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
302 error_evt->serial, error_evt->request_code );
303 DebugBreak(); /* force an entry in the debugger */
305 old_error_handler( display, error_evt );
306 return 0;
309 /***********************************************************************
310 * wine_tsx11_lock (X11DRV.@)
312 void CDECL wine_tsx11_lock(void)
314 EnterCriticalSection( &X11DRV_CritSection );
317 /***********************************************************************
318 * wine_tsx11_unlock (X11DRV.@)
320 void CDECL wine_tsx11_unlock(void)
322 LeaveCriticalSection( &X11DRV_CritSection );
326 /***********************************************************************
327 * depth_to_bpp
329 * Convert X11-reported depth to the BPP value that Windows apps expect to see.
331 unsigned int depth_to_bpp( unsigned int depth )
333 switch (depth)
335 case 1:
336 case 8:
337 return depth;
338 case 15:
339 case 16:
340 return 16;
341 case 24:
342 /* This is not necessarily right. X11 always has 24 bits per pixel, but it can run
343 * with 24 bit framebuffers and 32 bit framebuffers. It doesn't make any difference
344 * for windowing, but gl applications can get visuals with alpha channels. So we
345 * should check the framebuffer and/or opengl formats available to find out what the
346 * framebuffer actually does
348 case 32:
349 return 32;
350 default:
351 FIXME( "Unexpected X11 depth %d bpp, what to report to app?\n", depth );
352 return depth;
357 /***********************************************************************
358 * get_config_key
360 * Get a config key from either the app-specific or the default config
362 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
363 char *buffer, DWORD size )
365 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
366 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
367 return ERROR_FILE_NOT_FOUND;
371 /***********************************************************************
372 * setup_options
374 * Setup the x11drv options.
376 static void setup_options(void)
378 char buffer[MAX_PATH+16];
379 HKEY hkey, appkey = 0;
380 DWORD len;
382 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
383 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
385 /* open the app-specific key */
387 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
388 if (len && len < MAX_PATH)
390 HKEY tmpkey;
391 char *p, *appname = buffer;
392 if ((p = strrchr( appname, '/' ))) appname = p + 1;
393 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
394 strcat( appname, "\\X11 Driver" );
395 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
396 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
398 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
399 RegCloseKey( tmpkey );
403 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
404 managed_mode = IS_OPTION_TRUE( buffer[0] );
406 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
407 decorated_mode = IS_OPTION_TRUE( buffer[0] );
409 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
410 usexvidmode = IS_OPTION_TRUE( buffer[0] );
412 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
413 usexrandr = IS_OPTION_TRUE( buffer[0] );
415 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
416 use_take_focus = IS_OPTION_TRUE( buffer[0] );
418 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
419 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
421 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
422 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
424 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
425 show_systray = IS_OPTION_TRUE( buffer[0] );
427 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
428 grab_pointer = IS_OPTION_TRUE( buffer[0] );
430 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
431 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
433 screen_depth = 0;
434 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
435 screen_depth = atoi(buffer);
437 if (!get_config_key( hkey, appkey, "ClientSideWithCore", buffer, sizeof(buffer) ))
438 client_side_with_core = IS_OPTION_TRUE( buffer[0] );
440 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
441 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
443 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithCore", buffer, sizeof(buffer) ))
444 client_side_antialias_with_core = IS_OPTION_TRUE( buffer[0] );
446 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithRender", buffer, sizeof(buffer) ))
447 client_side_antialias_with_render = IS_OPTION_TRUE( buffer[0] );
449 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
450 use_xim = IS_OPTION_TRUE( buffer[0] );
452 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
453 private_color_map = IS_OPTION_TRUE( buffer[0] );
455 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
456 primary_monitor = atoi( buffer );
458 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
459 copy_default_colors = atoi(buffer);
461 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
462 alloc_system_colors = atoi(buffer);
464 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
466 if (appkey) RegCloseKey( appkey );
467 if (hkey) RegCloseKey( hkey );
470 #ifdef SONAME_LIBXCOMPOSITE
472 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
473 MAKE_FUNCPTR(XCompositeQueryExtension)
474 MAKE_FUNCPTR(XCompositeQueryVersion)
475 MAKE_FUNCPTR(XCompositeVersion)
476 MAKE_FUNCPTR(XCompositeRedirectWindow)
477 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
478 MAKE_FUNCPTR(XCompositeUnredirectWindow)
479 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
480 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
481 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
482 #undef MAKE_FUNCPTR
484 static int xcomp_event_base;
485 static int xcomp_error_base;
487 static void X11DRV_XComposite_Init(void)
489 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
490 if (!xcomposite_handle)
492 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
493 usexcomposite = 0;
494 return;
497 #define LOAD_FUNCPTR(f) \
498 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
499 goto sym_not_found;
500 LOAD_FUNCPTR(XCompositeQueryExtension)
501 LOAD_FUNCPTR(XCompositeQueryVersion)
502 LOAD_FUNCPTR(XCompositeVersion)
503 LOAD_FUNCPTR(XCompositeRedirectWindow)
504 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
505 LOAD_FUNCPTR(XCompositeUnredirectWindow)
506 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
507 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
508 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
509 #undef LOAD_FUNCPTR
511 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
512 &xcomp_error_base)) {
513 TRACE("XComposite extension could not be queried; disabled\n");
514 wine_dlclose(xcomposite_handle, NULL, 0);
515 xcomposite_handle = NULL;
516 usexcomposite = 0;
517 return;
519 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
520 return;
522 sym_not_found:
523 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
524 wine_dlclose(xcomposite_handle, NULL, 0);
525 xcomposite_handle = NULL;
526 usexcomposite = 0;
528 #endif /* defined(SONAME_LIBXCOMPOSITE) */
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 (!(display = XOpenDisplay( NULL ))) return FALSE;
559 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
560 screen = DefaultScreenOfDisplay( display );
561 visual = DefaultVisual( display, DefaultScreen(display) );
562 root_window = DefaultRootWindow( display );
563 gdi_display = display;
564 old_error_handler = XSetErrorHandler( error_handler );
566 /* Initialize screen depth */
568 if (screen_depth) /* depth specified */
570 int depth_count, i;
571 int *depth_list = XListDepths(display, DefaultScreen(display), &depth_count);
572 for (i = 0; i < depth_count; i++)
573 if (depth_list[i] == screen_depth) break;
574 XFree( depth_list );
575 if (i >= depth_count)
577 WARN( "invalid depth %d, using default\n", screen_depth );
578 screen_depth = 0;
581 if (!screen_depth) screen_depth = DefaultDepthOfScreen( screen );
582 screen_bpp = depth_to_bpp( screen_depth );
584 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
586 if (TRACE_ON(synchronous)) XSynchronize( display, True );
588 xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
589 X11DRV_Settings_Init();
591 #ifdef SONAME_LIBXXF86VM
592 /* initialize XVidMode */
593 X11DRV_XF86VM_Init();
594 #endif
595 #ifdef SONAME_LIBXRANDR
596 /* initialize XRandR */
597 X11DRV_XRandR_Init();
598 #endif
599 #ifdef SONAME_LIBXCOMPOSITE
600 X11DRV_XComposite_Init();
601 #endif
602 X11DRV_XInput2_Init();
604 #ifdef HAVE_XKB
605 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
606 #endif
607 X11DRV_InitKeyboard( gdi_display );
608 X11DRV_InitClipboard();
609 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
611 return TRUE;
615 /***********************************************************************
616 * X11DRV thread termination routine
618 static void thread_detach(void)
620 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
622 if (data)
624 X11DRV_ResetSelectionOwner();
625 wine_tsx11_lock();
626 if (data->xim) XCloseIM( data->xim );
627 if (data->font_set) XFreeFontSet( data->display, data->font_set );
628 XCloseDisplay( data->display );
629 wine_tsx11_unlock();
630 HeapFree( GetProcessHeap(), 0, data );
635 /***********************************************************************
636 * X11DRV process termination routine
638 static void process_detach(void)
640 X11DRV_Clipboard_Cleanup();
641 #ifdef SONAME_LIBXXF86VM
642 /* cleanup XVidMode */
643 X11DRV_XF86VM_Cleanup();
644 #endif
645 if(using_client_side_fonts)
646 X11DRV_XRender_Finalize();
648 /* cleanup GDI */
649 X11DRV_GDI_Finalize();
650 X11DRV_OpenGL_Cleanup();
652 IME_UnregisterClasses();
653 DeleteCriticalSection( &X11DRV_CritSection );
654 TlsFree( thread_data_tls_index );
658 /* store the display fd into the message queue */
659 static void set_queue_display_fd( Display *display )
661 HANDLE handle;
662 int ret;
664 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
666 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
667 ExitProcess(1);
669 SERVER_START_REQ( set_queue_fd )
671 req->handle = wine_server_obj_handle( handle );
672 ret = wine_server_call( req );
674 SERVER_END_REQ;
675 if (ret)
677 MESSAGE( "x11drv: Can't store handle for display fd\n" );
678 ExitProcess(1);
680 CloseHandle( handle );
684 /***********************************************************************
685 * X11DRV thread initialisation routine
687 struct x11drv_thread_data *x11drv_init_thread_data(void)
689 struct x11drv_thread_data *data = x11drv_thread_data();
691 if (data) return data;
693 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
695 ERR( "could not create data\n" );
696 ExitProcess(1);
698 wine_tsx11_lock();
699 if (!(data->display = XOpenDisplay(NULL)))
701 wine_tsx11_unlock();
702 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));
703 ExitProcess(1);
706 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
708 #ifdef HAVE_XKB
709 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
710 XkbSetDetectableAutoRepeat( data->display, True, NULL );
711 #endif
713 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
714 wine_tsx11_unlock();
716 set_queue_display_fd( data->display );
717 TlsSetValue( thread_data_tls_index, data );
719 if (use_xim) X11DRV_SetupXIM();
721 return data;
725 /***********************************************************************
726 * X11DRV initialisation routine
728 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
730 BOOL ret = TRUE;
732 switch(reason)
734 case DLL_PROCESS_ATTACH:
735 x11drv_module = hinst;
736 ret = process_attach();
737 break;
738 case DLL_THREAD_DETACH:
739 thread_detach();
740 break;
741 case DLL_PROCESS_DETACH:
742 process_detach();
743 break;
745 return ret;
748 /***********************************************************************
749 * GetScreenSaveActive (X11DRV.@)
751 * Returns the active status of the screen saver
753 BOOL CDECL X11DRV_GetScreenSaveActive(void)
755 int timeout, temp;
756 wine_tsx11_lock();
757 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
758 wine_tsx11_unlock();
759 return timeout != 0;
762 /***********************************************************************
763 * SetScreenSaveActive (X11DRV.@)
765 * Activate/Deactivate the screen saver
767 void CDECL X11DRV_SetScreenSaveActive(BOOL bActivate)
769 int timeout, interval, prefer_blanking, allow_exposures;
770 static int last_timeout = 15 * 60;
772 wine_tsx11_lock();
773 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
774 &allow_exposures);
775 if (timeout) last_timeout = timeout;
777 timeout = bActivate ? last_timeout : 0;
778 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
779 allow_exposures);
780 wine_tsx11_unlock();