winex11: Remove the remaining X11 locking calls.
[wine.git] / dlls / winex11.drv / x11drv_main.c
blobf3c9d3fa2967b40eaf634532938cb4a958ad3af1
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 static CRITICAL_SECTION X11DRV_CritSection;
60 static CRITICAL_SECTION_DEBUG critsect_debug =
62 0, 0, &X11DRV_CritSection,
63 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
64 0, 0, { (DWORD_PTR)(__FILE__ ": X11DRV_CritSection") }
66 static CRITICAL_SECTION X11DRV_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };
68 static Screen *screen;
69 Visual *visual;
70 XPixmapFormatValues **pixmap_formats;
71 unsigned int screen_width;
72 unsigned int screen_height;
73 unsigned int screen_bpp;
74 unsigned int screen_depth;
75 RECT virtual_screen_rect;
76 Window root_window;
77 int usexvidmode = 1;
78 int usexrandr = 1;
79 int usexcomposite = 1;
80 int use_xkb = 1;
81 int use_take_focus = 1;
82 int use_primary_selection = 0;
83 int use_system_cursors = 1;
84 int show_systray = 1;
85 int grab_pointer = 1;
86 int grab_fullscreen = 0;
87 int managed_mode = 1;
88 int decorated_mode = 1;
89 int private_color_map = 0;
90 int primary_monitor = 0;
91 int client_side_with_render = 1;
92 int client_side_antialias_with_core = 1;
93 int client_side_antialias_with_render = 1;
94 int copy_default_colors = 128;
95 int alloc_system_colors = 256;
96 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
97 int xrender_error_base = 0;
98 HMODULE x11drv_module = 0;
100 static x11drv_error_callback err_callback; /* current callback for error */
101 static Display *err_callback_display; /* display callback is set for */
102 static void *err_callback_arg; /* error callback argument */
103 static int err_callback_result; /* error callback result */
104 static unsigned long err_serial; /* serial number of first request */
105 static int (*old_error_handler)( Display *, XErrorEvent * );
106 static int use_xim = 1;
107 static char input_style[20];
109 #define IS_OPTION_TRUE(ch) \
110 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
111 #define IS_OPTION_FALSE(ch) \
112 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
114 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
116 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
118 "CLIPBOARD",
119 "COMPOUND_TEXT",
120 "INCR",
121 "MANAGER",
122 "MULTIPLE",
123 "SELECTION_DATA",
124 "TARGETS",
125 "TEXT",
126 "UTF8_STRING",
127 "RAW_ASCENT",
128 "RAW_DESCENT",
129 "RAW_CAP_HEIGHT",
130 "Rel X",
131 "Rel Y",
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.
248 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
250 err_callback = callback;
251 err_callback_display = display;
252 err_callback_arg = arg;
253 err_callback_result = 0;
254 err_serial = NextRequest(display);
258 /***********************************************************************
259 * X11DRV_check_error
261 * Check if an expected X11 error occurred; return non-zero if yes.
262 * The caller is responsible for calling XSync first if necessary.
264 int X11DRV_check_error(void)
266 err_callback = NULL;
267 return err_callback_result;
271 /***********************************************************************
272 * error_handler
274 static int error_handler( Display *display, XErrorEvent *error_evt )
276 if (err_callback && display == err_callback_display &&
277 (long)(error_evt->serial - err_serial) >= 0)
279 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
281 TRACE( "got expected error %d req %d\n",
282 error_evt->error_code, error_evt->request_code );
283 return 0;
286 if (ignore_error( display, error_evt ))
288 TRACE( "got ignored error %d req %d\n",
289 error_evt->error_code, error_evt->request_code );
290 return 0;
292 if (TRACE_ON(synchronous))
294 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
295 error_evt->serial, error_evt->request_code );
296 DebugBreak(); /* force an entry in the debugger */
298 old_error_handler( display, error_evt );
299 return 0;
302 /***********************************************************************
303 * wine_tsx11_lock (X11DRV.@)
305 void CDECL wine_tsx11_lock(void)
307 EnterCriticalSection( &X11DRV_CritSection );
310 /***********************************************************************
311 * wine_tsx11_unlock (X11DRV.@)
313 void CDECL wine_tsx11_unlock(void)
315 LeaveCriticalSection( &X11DRV_CritSection );
319 /***********************************************************************
320 * init_pixmap_formats
322 static void init_pixmap_formats( Display *display )
324 int i, count, max = 32;
325 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
327 for (i = 0; i < count; i++)
329 TRACE( "depth %u, bpp %u, pad %u\n",
330 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
331 if (formats[i].depth > max) max = formats[i].depth;
333 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
334 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
338 /***********************************************************************
339 * get_config_key
341 * Get a config key from either the app-specific or the default config
343 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
344 char *buffer, DWORD size )
346 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
347 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
348 return ERROR_FILE_NOT_FOUND;
352 /***********************************************************************
353 * setup_options
355 * Setup the x11drv options.
357 static void setup_options(void)
359 char buffer[MAX_PATH+16];
360 HKEY hkey, appkey = 0;
361 DWORD len;
363 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
364 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
366 /* open the app-specific key */
368 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
369 if (len && len < MAX_PATH)
371 HKEY tmpkey;
372 char *p, *appname = buffer;
373 if ((p = strrchr( appname, '/' ))) appname = p + 1;
374 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
375 strcat( appname, "\\X11 Driver" );
376 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
377 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
379 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
380 RegCloseKey( tmpkey );
384 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
385 managed_mode = IS_OPTION_TRUE( buffer[0] );
387 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
388 decorated_mode = IS_OPTION_TRUE( buffer[0] );
390 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
391 usexvidmode = IS_OPTION_TRUE( buffer[0] );
393 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
394 usexrandr = IS_OPTION_TRUE( buffer[0] );
396 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
397 use_take_focus = IS_OPTION_TRUE( buffer[0] );
399 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
400 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
402 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
403 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
405 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
406 show_systray = IS_OPTION_TRUE( buffer[0] );
408 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
409 grab_pointer = IS_OPTION_TRUE( buffer[0] );
411 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
412 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
414 screen_depth = 0;
415 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
416 screen_depth = atoi(buffer);
418 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
419 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
421 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithCore", buffer, sizeof(buffer) ))
422 client_side_antialias_with_core = IS_OPTION_TRUE( buffer[0] );
424 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithRender", buffer, sizeof(buffer) ))
425 client_side_antialias_with_render = IS_OPTION_TRUE( buffer[0] );
427 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
428 use_xim = IS_OPTION_TRUE( buffer[0] );
430 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
431 private_color_map = IS_OPTION_TRUE( buffer[0] );
433 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
434 primary_monitor = atoi( buffer );
436 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
437 copy_default_colors = atoi(buffer);
439 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
440 alloc_system_colors = atoi(buffer);
442 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
444 if (appkey) RegCloseKey( appkey );
445 if (hkey) RegCloseKey( hkey );
448 #ifdef SONAME_LIBXCOMPOSITE
450 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
451 MAKE_FUNCPTR(XCompositeQueryExtension)
452 MAKE_FUNCPTR(XCompositeQueryVersion)
453 MAKE_FUNCPTR(XCompositeVersion)
454 MAKE_FUNCPTR(XCompositeRedirectWindow)
455 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
456 MAKE_FUNCPTR(XCompositeUnredirectWindow)
457 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
458 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
459 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
460 #undef MAKE_FUNCPTR
462 static int xcomp_event_base;
463 static int xcomp_error_base;
465 static void X11DRV_XComposite_Init(void)
467 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
468 if (!xcomposite_handle)
470 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
471 usexcomposite = 0;
472 return;
475 #define LOAD_FUNCPTR(f) \
476 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
477 goto sym_not_found;
478 LOAD_FUNCPTR(XCompositeQueryExtension)
479 LOAD_FUNCPTR(XCompositeQueryVersion)
480 LOAD_FUNCPTR(XCompositeVersion)
481 LOAD_FUNCPTR(XCompositeRedirectWindow)
482 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
483 LOAD_FUNCPTR(XCompositeUnredirectWindow)
484 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
485 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
486 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
487 #undef LOAD_FUNCPTR
489 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
490 &xcomp_error_base)) {
491 TRACE("XComposite extension could not be queried; disabled\n");
492 wine_dlclose(xcomposite_handle, NULL, 0);
493 xcomposite_handle = NULL;
494 usexcomposite = 0;
495 return;
497 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
498 return;
500 sym_not_found:
501 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
502 wine_dlclose(xcomposite_handle, NULL, 0);
503 xcomposite_handle = NULL;
504 usexcomposite = 0;
506 #endif /* defined(SONAME_LIBXCOMPOSITE) */
509 /***********************************************************************
510 * X11DRV process initialisation routine
512 static BOOL process_attach(void)
514 char error[1024];
515 Display *display;
516 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
518 if (!libx11)
520 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
521 return FALSE;
523 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
524 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
525 #ifdef SONAME_LIBXEXT
526 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
527 #endif
529 setup_options();
531 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
533 /* Open display */
535 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
536 if (!(display = XOpenDisplay( NULL ))) return FALSE;
538 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
539 screen = DefaultScreenOfDisplay( display );
540 visual = DefaultVisual( display, DefaultScreen(display) );
541 root_window = DefaultRootWindow( display );
542 gdi_display = display;
543 old_error_handler = XSetErrorHandler( error_handler );
545 /* Initialize screen depth */
547 if (screen_depth) /* depth specified */
549 int depth_count, i;
550 int *depth_list = XListDepths(display, DefaultScreen(display), &depth_count);
551 for (i = 0; i < depth_count; i++)
552 if (depth_list[i] == screen_depth) break;
553 XFree( depth_list );
554 if (i >= depth_count)
556 WARN( "invalid depth %d, using default\n", screen_depth );
557 screen_depth = 0;
560 if (!screen_depth) screen_depth = DefaultDepthOfScreen( screen );
561 init_pixmap_formats( display );
562 screen_bpp = pixmap_formats[screen_depth]->bits_per_pixel;
564 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
566 winContext = XUniqueContext();
567 win_data_context = XUniqueContext();
568 cursor_context = XUniqueContext();
570 if (TRACE_ON(synchronous)) XSynchronize( display, True );
572 xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
573 X11DRV_Settings_Init();
575 /* initialize XVidMode */
576 X11DRV_XF86VM_Init();
577 /* initialize XRandR */
578 X11DRV_XRandR_Init();
579 #ifdef SONAME_LIBXCOMPOSITE
580 X11DRV_XComposite_Init();
581 #endif
582 X11DRV_XInput2_Init();
584 #ifdef HAVE_XKB
585 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
586 #endif
587 X11DRV_InitKeyboard( gdi_display );
588 X11DRV_InitClipboard();
589 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
591 return TRUE;
595 /***********************************************************************
596 * X11DRV thread termination routine
598 static void thread_detach(void)
600 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
602 if (data)
604 X11DRV_ResetSelectionOwner();
605 if (data->xim) XCloseIM( data->xim );
606 if (data->font_set) XFreeFontSet( data->display, data->font_set );
607 XCloseDisplay( data->display );
608 HeapFree( GetProcessHeap(), 0, data );
613 /* store the display fd into the message queue */
614 static void set_queue_display_fd( Display *display )
616 HANDLE handle;
617 int ret;
619 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
621 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
622 ExitProcess(1);
624 SERVER_START_REQ( set_queue_fd )
626 req->handle = wine_server_obj_handle( handle );
627 ret = wine_server_call( req );
629 SERVER_END_REQ;
630 if (ret)
632 MESSAGE( "x11drv: Can't store handle for display fd\n" );
633 ExitProcess(1);
635 CloseHandle( handle );
639 /***********************************************************************
640 * X11DRV thread initialisation routine
642 struct x11drv_thread_data *x11drv_init_thread_data(void)
644 struct x11drv_thread_data *data = x11drv_thread_data();
646 if (data) return data;
648 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
650 ERR( "could not create data\n" );
651 ExitProcess(1);
653 if (!(data->display = XOpenDisplay(NULL)))
655 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));
656 ExitProcess(1);
659 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
661 #ifdef HAVE_XKB
662 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
663 XkbSetDetectableAutoRepeat( data->display, True, NULL );
664 #endif
666 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
668 set_queue_display_fd( data->display );
669 TlsSetValue( thread_data_tls_index, data );
671 if (use_xim) X11DRV_SetupXIM();
673 return data;
677 /***********************************************************************
678 * X11DRV initialisation routine
680 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
682 BOOL ret = TRUE;
684 switch(reason)
686 case DLL_PROCESS_ATTACH:
687 x11drv_module = hinst;
688 ret = process_attach();
689 break;
690 case DLL_THREAD_DETACH:
691 thread_detach();
692 break;
694 return ret;
697 /***********************************************************************
698 * GetScreenSaveActive (X11DRV.@)
700 * Returns the active status of the screen saver
702 BOOL CDECL X11DRV_GetScreenSaveActive(void)
704 int timeout, temp;
705 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
706 return timeout != 0;
709 /***********************************************************************
710 * SetScreenSaveActive (X11DRV.@)
712 * Activate/Deactivate the screen saver
714 void CDECL X11DRV_SetScreenSaveActive(BOOL bActivate)
716 int timeout, interval, prefer_blanking, allow_exposures;
717 static int last_timeout = 15 * 60;
719 XLockDisplay( gdi_display );
720 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
721 &allow_exposures);
722 if (timeout) last_timeout = timeout;
724 timeout = bActivate ? last_timeout : 0;
725 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
726 allow_exposures);
727 XUnlockDisplay( gdi_display );