winex11: Use the default anti-aliasing parameters from gdi32.
[wine.git] / dlls / winex11.drv / x11drv_main.c
blob3ff42335ab35084ef907a97a89f8b6d1762fb6e1
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_width;
64 unsigned int screen_height;
65 unsigned int screen_bpp;
66 RECT virtual_screen_rect;
67 Window root_window;
68 int usexvidmode = 1;
69 int usexrandr = 1;
70 int usexcomposite = 1;
71 int use_xkb = 1;
72 int use_take_focus = 1;
73 int use_primary_selection = 0;
74 int use_system_cursors = 1;
75 int show_systray = 1;
76 int grab_pointer = 1;
77 int grab_fullscreen = 0;
78 int managed_mode = 1;
79 int decorated_mode = 1;
80 int private_color_map = 0;
81 int primary_monitor = 0;
82 int client_side_graphics = 1;
83 int client_side_with_render = 1;
84 int copy_default_colors = 128;
85 int alloc_system_colors = 256;
86 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
87 int xrender_error_base = 0;
88 HMODULE x11drv_module = 0;
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 int use_xim = 1;
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 "UTF8_STRING",
117 "RAW_ASCENT",
118 "RAW_DESCENT",
119 "RAW_CAP_HEIGHT",
120 "Rel X",
121 "Rel Y",
122 "WM_PROTOCOLS",
123 "WM_DELETE_WINDOW",
124 "WM_STATE",
125 "WM_TAKE_FOCUS",
126 "DndProtocol",
127 "DndSelection",
128 "_ICC_PROFILE",
129 "_MOTIF_WM_HINTS",
130 "_NET_STARTUP_INFO_BEGIN",
131 "_NET_STARTUP_INFO",
132 "_NET_SUPPORTED",
133 "_NET_SYSTEM_TRAY_OPCODE",
134 "_NET_SYSTEM_TRAY_S0",
135 "_NET_SYSTEM_TRAY_VISUAL",
136 "_NET_WM_ICON",
137 "_NET_WM_MOVERESIZE",
138 "_NET_WM_NAME",
139 "_NET_WM_PID",
140 "_NET_WM_PING",
141 "_NET_WM_STATE",
142 "_NET_WM_STATE_ABOVE",
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 "XdndTarget",
172 "XdndTypeList",
173 "HTML Format",
174 "WCF_BITMAP",
175 "WCF_DIB",
176 "WCF_DIBV5",
177 "WCF_DIF",
178 "WCF_DSPBITMAP",
179 "WCF_DSPENHMETAFILE",
180 "WCF_DSPMETAFILEPICT",
181 "WCF_DSPTEXT",
182 "WCF_ENHMETAFILE",
183 "WCF_HDROP",
184 "WCF_LOCALE",
185 "WCF_METAFILEPICT",
186 "WCF_OEMTEXT",
187 "WCF_OWNERDISPLAY",
188 "WCF_PALETTE",
189 "WCF_PENDATA",
190 "WCF_RIFF",
191 "WCF_SYLK",
192 "WCF_TIFF",
193 "WCF_WAVE",
194 "image/bmp",
195 "image/gif",
196 "image/jpeg",
197 "image/png",
198 "text/html",
199 "text/plain",
200 "text/rtf",
201 "text/richtext",
202 "text/uri-list"
205 /***********************************************************************
206 * ignore_error
208 * Check if the X error is one we can ignore.
210 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
212 if ((event->request_code == X_SetInputFocus || event->request_code == X_ChangeWindowAttributes) &&
213 (event->error_code == BadMatch || event->error_code == BadWindow)) return TRUE;
215 /* ignore a number of errors on gdi display caused by creating/destroying windows */
216 if (display == gdi_display)
218 if (event->error_code == BadDrawable ||
219 event->error_code == BadGC ||
220 event->error_code == BadWindow)
221 return TRUE;
222 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
223 if (xrender_error_base) /* check for XRender errors */
225 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
227 #endif
229 return FALSE;
233 /***********************************************************************
234 * X11DRV_expect_error
236 * Setup a callback function that will be called on an X error. The
237 * callback must return non-zero if the error is the one it expected.
239 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
241 err_callback = callback;
242 err_callback_display = display;
243 err_callback_arg = arg;
244 err_callback_result = 0;
245 err_serial = NextRequest(display);
249 /***********************************************************************
250 * X11DRV_check_error
252 * Check if an expected X11 error occurred; return non-zero if yes.
253 * The caller is responsible for calling XSync first if necessary.
255 int X11DRV_check_error(void)
257 err_callback = NULL;
258 return err_callback_result;
262 /***********************************************************************
263 * error_handler
265 static int error_handler( Display *display, XErrorEvent *error_evt )
267 if (err_callback && display == err_callback_display &&
268 (long)(error_evt->serial - err_serial) >= 0)
270 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
272 TRACE( "got expected error %d req %d\n",
273 error_evt->error_code, error_evt->request_code );
274 return 0;
277 if (ignore_error( display, error_evt ))
279 TRACE( "got ignored error %d req %d\n",
280 error_evt->error_code, error_evt->request_code );
281 return 0;
283 if (TRACE_ON(synchronous))
285 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
286 error_evt->serial, error_evt->request_code );
287 DebugBreak(); /* force an entry in the debugger */
289 old_error_handler( display, error_evt );
290 return 0;
293 /***********************************************************************
294 * init_pixmap_formats
296 static void init_pixmap_formats( Display *display )
298 int i, count, max = 32;
299 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
301 for (i = 0; i < count; i++)
303 TRACE( "depth %u, bpp %u, pad %u\n",
304 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
305 if (formats[i].depth > max) max = formats[i].depth;
307 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
308 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
312 /***********************************************************************
313 * get_config_key
315 * Get a config key from either the app-specific or the default config
317 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
318 char *buffer, DWORD size )
320 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
321 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
322 return ERROR_FILE_NOT_FOUND;
326 /***********************************************************************
327 * setup_options
329 * Setup the x11drv options.
331 static void setup_options(void)
333 char buffer[MAX_PATH+16];
334 HKEY hkey, appkey = 0;
335 DWORD len;
337 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
338 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
340 /* open the app-specific key */
342 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
343 if (len && len < MAX_PATH)
345 HKEY tmpkey;
346 char *p, *appname = buffer;
347 if ((p = strrchr( appname, '/' ))) appname = p + 1;
348 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
349 strcat( appname, "\\X11 Driver" );
350 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
351 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
353 if (RegOpenKeyA( 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, "PrivateColorMap", buffer, sizeof(buffer) ))
401 private_color_map = IS_OPTION_TRUE( buffer[0] );
403 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
404 primary_monitor = atoi( buffer );
406 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
407 copy_default_colors = atoi(buffer);
409 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
410 alloc_system_colors = atoi(buffer);
412 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
414 if (appkey) RegCloseKey( appkey );
415 if (hkey) RegCloseKey( hkey );
418 #ifdef SONAME_LIBXCOMPOSITE
420 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
421 MAKE_FUNCPTR(XCompositeQueryExtension)
422 MAKE_FUNCPTR(XCompositeQueryVersion)
423 MAKE_FUNCPTR(XCompositeVersion)
424 MAKE_FUNCPTR(XCompositeRedirectWindow)
425 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
426 MAKE_FUNCPTR(XCompositeUnredirectWindow)
427 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
428 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
429 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
430 #undef MAKE_FUNCPTR
432 static int xcomp_event_base;
433 static int xcomp_error_base;
435 static void X11DRV_XComposite_Init(void)
437 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
438 if (!xcomposite_handle)
440 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
441 usexcomposite = 0;
442 return;
445 #define LOAD_FUNCPTR(f) \
446 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
447 goto sym_not_found;
448 LOAD_FUNCPTR(XCompositeQueryExtension)
449 LOAD_FUNCPTR(XCompositeQueryVersion)
450 LOAD_FUNCPTR(XCompositeVersion)
451 LOAD_FUNCPTR(XCompositeRedirectWindow)
452 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
453 LOAD_FUNCPTR(XCompositeUnredirectWindow)
454 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
455 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
456 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
457 #undef LOAD_FUNCPTR
459 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
460 &xcomp_error_base)) {
461 TRACE("XComposite extension could not be queried; disabled\n");
462 wine_dlclose(xcomposite_handle, NULL, 0);
463 xcomposite_handle = NULL;
464 usexcomposite = 0;
465 return;
467 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
468 return;
470 sym_not_found:
471 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
472 wine_dlclose(xcomposite_handle, NULL, 0);
473 xcomposite_handle = NULL;
474 usexcomposite = 0;
476 #endif /* defined(SONAME_LIBXCOMPOSITE) */
478 static void init_visuals( Display *display, int screen )
480 int count;
481 XVisualInfo *info;
483 default_visual.screen = screen;
484 if (default_visual.depth) /* depth specified */
486 info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask, &default_visual, &count );
487 if (info)
489 default_visual = *info;
490 XFree( info );
492 else WARN( "no visual found for depth %d\n", default_visual.depth );
495 if (!default_visual.visual)
497 default_visual.depth = DefaultDepth( display, screen );
498 default_visual.visual = DefaultVisual( display, screen );
499 default_visual.visualid = default_visual.visual->visualid;
500 default_visual.class = default_visual.visual->class;
501 default_visual.red_mask = default_visual.visual->red_mask;
502 default_visual.green_mask = default_visual.visual->green_mask;
503 default_visual.blue_mask = default_visual.visual->blue_mask;
504 default_visual.colormap_size = default_visual.visual->map_entries;
505 default_visual.bits_per_rgb = default_visual.visual->bits_per_rgb;
507 default_colormap = XCreateColormap( display, root_window, default_visual.visual, AllocNone );
509 argb_visual.screen = screen;
510 argb_visual.class = TrueColor;
511 argb_visual.depth = 32;
512 argb_visual.red_mask = 0xff0000;
513 argb_visual.green_mask = 0x00ff00;
514 argb_visual.blue_mask = 0x0000ff;
516 if ((info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask | VisualClassMask |
517 VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
518 &argb_visual, &count )))
520 argb_visual = *info;
521 XFree( info );
523 TRACE( "default visual %lx class %u argb %lx\n",
524 default_visual.visualid, default_visual.class, argb_visual.visualid );
527 /***********************************************************************
528 * X11DRV process initialisation routine
530 static BOOL process_attach(void)
532 char error[1024];
533 Display *display;
534 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
536 if (!libx11)
538 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
539 return FALSE;
541 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
542 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
543 #ifdef SONAME_LIBXEXT
544 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
545 #endif
547 setup_options();
549 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
551 /* Open display */
553 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
554 if (!(display = XOpenDisplay( NULL ))) return FALSE;
556 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
557 root_window = DefaultRootWindow( display );
558 gdi_display = display;
559 old_error_handler = XSetErrorHandler( error_handler );
561 init_pixmap_formats( display );
562 init_visuals( display, DefaultScreen( display ));
563 screen_bpp = pixmap_formats[default_visual.depth]->bits_per_pixel;
565 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
567 winContext = XUniqueContext();
568 win_data_context = XUniqueContext();
569 cursor_context = XUniqueContext();
571 if (TRACE_ON(synchronous)) XSynchronize( display, True );
573 xinerama_init( DisplayWidth( display, default_visual.screen ),
574 DisplayHeight( display, default_visual.screen ));
575 X11DRV_Settings_Init();
577 /* initialize XVidMode */
578 X11DRV_XF86VM_Init();
579 /* initialize XRandR */
580 X11DRV_XRandR_Init();
581 #ifdef SONAME_LIBXCOMPOSITE
582 X11DRV_XComposite_Init();
583 #endif
584 X11DRV_XInput2_Init();
586 #ifdef HAVE_XKB
587 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
588 #endif
589 X11DRV_InitKeyboard( gdi_display );
590 X11DRV_InitClipboard();
591 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
593 return TRUE;
597 /***********************************************************************
598 * X11DRV thread termination routine
600 static void thread_detach(void)
602 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
604 if (data)
606 X11DRV_ResetSelectionOwner();
607 if (data->xim) XCloseIM( data->xim );
608 if (data->font_set) XFreeFontSet( data->display, data->font_set );
609 XCloseDisplay( data->display );
610 HeapFree( GetProcessHeap(), 0, data );
615 /* store the display fd into the message queue */
616 static void set_queue_display_fd( Display *display )
618 HANDLE handle;
619 int ret;
621 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
623 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
624 ExitProcess(1);
626 SERVER_START_REQ( set_queue_fd )
628 req->handle = wine_server_obj_handle( handle );
629 ret = wine_server_call( req );
631 SERVER_END_REQ;
632 if (ret)
634 MESSAGE( "x11drv: Can't store handle for display fd\n" );
635 ExitProcess(1);
637 CloseHandle( handle );
641 /***********************************************************************
642 * X11DRV thread initialisation routine
644 struct x11drv_thread_data *x11drv_init_thread_data(void)
646 struct x11drv_thread_data *data = x11drv_thread_data();
648 if (data) return data;
650 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
652 ERR( "could not create data\n" );
653 ExitProcess(1);
655 if (!(data->display = XOpenDisplay(NULL)))
657 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));
658 ExitProcess(1);
661 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
663 #ifdef HAVE_XKB
664 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
665 XkbSetDetectableAutoRepeat( data->display, True, NULL );
666 #endif
668 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
670 set_queue_display_fd( data->display );
671 TlsSetValue( thread_data_tls_index, data );
673 if (use_xim) X11DRV_SetupXIM();
675 return data;
679 /***********************************************************************
680 * X11DRV initialisation routine
682 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
684 BOOL ret = TRUE;
686 switch(reason)
688 case DLL_PROCESS_ATTACH:
689 x11drv_module = hinst;
690 ret = process_attach();
691 break;
692 case DLL_THREAD_DETACH:
693 thread_detach();
694 break;
696 return ret;
699 /***********************************************************************
700 * GetScreenSaveActive (X11DRV.@)
702 * Returns the active status of the screen saver
704 BOOL CDECL X11DRV_GetScreenSaveActive(void)
706 int timeout, temp;
707 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
708 return timeout != 0;
711 /***********************************************************************
712 * SetScreenSaveActive (X11DRV.@)
714 * Activate/Deactivate the screen saver
716 void CDECL X11DRV_SetScreenSaveActive(BOOL bActivate)
718 int timeout, interval, prefer_blanking, allow_exposures;
719 static int last_timeout = 15 * 60;
721 XLockDisplay( gdi_display );
722 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
723 &allow_exposures);
724 if (timeout) last_timeout = timeout;
726 timeout = bActivate ? last_timeout : 0;
727 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
728 allow_exposures);
729 XUnlockDisplay( gdi_display );