d3drm: Implement IDirect3DRMFrameX_AddTransform.
[wine/multimedia.git] / dlls / winex11.drv / x11drv_main.c
blob528715bf4aade497bc1b5cb8f786d3fc15e49e1c
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_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 * init_pixmap_formats
329 static void init_pixmap_formats( Display *display )
331 int i, count, max = 32;
332 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
334 for (i = 0; i < count; i++)
336 TRACE( "depth %u, bpp %u, pad %u\n",
337 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
338 if (formats[i].depth > max) max = formats[i].depth;
340 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
341 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
345 /***********************************************************************
346 * get_config_key
348 * Get a config key from either the app-specific or the default config
350 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
351 char *buffer, DWORD size )
353 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
354 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
355 return ERROR_FILE_NOT_FOUND;
359 /***********************************************************************
360 * setup_options
362 * Setup the x11drv options.
364 static void setup_options(void)
366 char buffer[MAX_PATH+16];
367 HKEY hkey, appkey = 0;
368 DWORD len;
370 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
371 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
373 /* open the app-specific key */
375 len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
376 if (len && len < MAX_PATH)
378 HKEY tmpkey;
379 char *p, *appname = buffer;
380 if ((p = strrchr( appname, '/' ))) appname = p + 1;
381 if ((p = strrchr( appname, '\\' ))) appname = p + 1;
382 strcat( appname, "\\X11 Driver" );
383 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
384 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
386 if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
387 RegCloseKey( tmpkey );
391 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
392 managed_mode = IS_OPTION_TRUE( buffer[0] );
394 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
395 decorated_mode = IS_OPTION_TRUE( buffer[0] );
397 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
398 usexvidmode = IS_OPTION_TRUE( buffer[0] );
400 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
401 usexrandr = IS_OPTION_TRUE( buffer[0] );
403 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
404 use_take_focus = IS_OPTION_TRUE( buffer[0] );
406 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
407 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
409 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
410 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
412 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
413 show_systray = IS_OPTION_TRUE( buffer[0] );
415 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
416 grab_pointer = IS_OPTION_TRUE( buffer[0] );
418 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
419 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
421 screen_depth = 0;
422 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
423 screen_depth = atoi(buffer);
425 if (!get_config_key( hkey, appkey, "ClientSideWithRender", buffer, sizeof(buffer) ))
426 client_side_with_render = IS_OPTION_TRUE( buffer[0] );
428 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithCore", buffer, sizeof(buffer) ))
429 client_side_antialias_with_core = IS_OPTION_TRUE( buffer[0] );
431 if (!get_config_key( hkey, appkey, "ClientSideAntiAliasWithRender", buffer, sizeof(buffer) ))
432 client_side_antialias_with_render = IS_OPTION_TRUE( buffer[0] );
434 if (!get_config_key( hkey, appkey, "UseXIM", buffer, sizeof(buffer) ))
435 use_xim = IS_OPTION_TRUE( buffer[0] );
437 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
438 private_color_map = IS_OPTION_TRUE( buffer[0] );
440 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
441 primary_monitor = atoi( buffer );
443 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
444 copy_default_colors = atoi(buffer);
446 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
447 alloc_system_colors = atoi(buffer);
449 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
451 if (appkey) RegCloseKey( appkey );
452 if (hkey) RegCloseKey( hkey );
455 #ifdef SONAME_LIBXCOMPOSITE
457 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
458 MAKE_FUNCPTR(XCompositeQueryExtension)
459 MAKE_FUNCPTR(XCompositeQueryVersion)
460 MAKE_FUNCPTR(XCompositeVersion)
461 MAKE_FUNCPTR(XCompositeRedirectWindow)
462 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
463 MAKE_FUNCPTR(XCompositeUnredirectWindow)
464 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
465 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
466 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
467 #undef MAKE_FUNCPTR
469 static int xcomp_event_base;
470 static int xcomp_error_base;
472 static void X11DRV_XComposite_Init(void)
474 void *xcomposite_handle = wine_dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW, NULL, 0);
475 if (!xcomposite_handle)
477 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
478 usexcomposite = 0;
479 return;
482 #define LOAD_FUNCPTR(f) \
483 if((p##f = wine_dlsym(xcomposite_handle, #f, NULL, 0)) == NULL) \
484 goto sym_not_found;
485 LOAD_FUNCPTR(XCompositeQueryExtension)
486 LOAD_FUNCPTR(XCompositeQueryVersion)
487 LOAD_FUNCPTR(XCompositeVersion)
488 LOAD_FUNCPTR(XCompositeRedirectWindow)
489 LOAD_FUNCPTR(XCompositeRedirectSubwindows)
490 LOAD_FUNCPTR(XCompositeUnredirectWindow)
491 LOAD_FUNCPTR(XCompositeUnredirectSubwindows)
492 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip)
493 LOAD_FUNCPTR(XCompositeNameWindowPixmap)
494 #undef LOAD_FUNCPTR
496 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
497 &xcomp_error_base)) {
498 TRACE("XComposite extension could not be queried; disabled\n");
499 wine_dlclose(xcomposite_handle, NULL, 0);
500 xcomposite_handle = NULL;
501 usexcomposite = 0;
502 return;
504 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
505 return;
507 sym_not_found:
508 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
509 wine_dlclose(xcomposite_handle, NULL, 0);
510 xcomposite_handle = NULL;
511 usexcomposite = 0;
513 #endif /* defined(SONAME_LIBXCOMPOSITE) */
516 /***********************************************************************
517 * X11DRV process initialisation routine
519 static BOOL process_attach(void)
521 char error[1024];
522 Display *display;
523 void *libx11 = wine_dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL, error, sizeof(error) );
525 if (!libx11)
527 ERR( "failed to load %s: %s\n", SONAME_LIBX11, error );
528 return FALSE;
530 pXGetEventData = wine_dlsym( libx11, "XGetEventData", NULL, 0 );
531 pXFreeEventData = wine_dlsym( libx11, "XFreeEventData", NULL, 0 );
532 #ifdef SONAME_LIBXEXT
533 wine_dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL, NULL, 0 );
534 #endif
536 setup_options();
538 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
540 /* Open display */
542 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
543 if (!(display = XOpenDisplay( NULL ))) return FALSE;
545 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
546 screen = DefaultScreenOfDisplay( display );
547 visual = DefaultVisual( display, DefaultScreen(display) );
548 root_window = DefaultRootWindow( display );
549 gdi_display = display;
550 old_error_handler = XSetErrorHandler( error_handler );
552 /* Initialize screen depth */
554 if (screen_depth) /* depth specified */
556 int depth_count, i;
557 int *depth_list = XListDepths(display, DefaultScreen(display), &depth_count);
558 for (i = 0; i < depth_count; i++)
559 if (depth_list[i] == screen_depth) break;
560 XFree( depth_list );
561 if (i >= depth_count)
563 WARN( "invalid depth %d, using default\n", screen_depth );
564 screen_depth = 0;
567 if (!screen_depth) screen_depth = DefaultDepthOfScreen( screen );
568 init_pixmap_formats( display );
569 screen_bpp = pixmap_formats[screen_depth]->bits_per_pixel;
571 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
573 if (TRACE_ON(synchronous)) XSynchronize( display, True );
575 xinerama_init( WidthOfScreen(screen), HeightOfScreen(screen) );
576 X11DRV_Settings_Init();
578 #ifdef SONAME_LIBXXF86VM
579 /* initialize XVidMode */
580 X11DRV_XF86VM_Init();
581 #endif
582 #ifdef SONAME_LIBXRANDR
583 /* initialize XRandR */
584 X11DRV_XRandR_Init();
585 #endif
586 #ifdef SONAME_LIBXCOMPOSITE
587 X11DRV_XComposite_Init();
588 #endif
589 X11DRV_XInput2_Init();
591 #ifdef HAVE_XKB
592 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
593 #endif
594 X11DRV_InitKeyboard( gdi_display );
595 X11DRV_InitClipboard();
596 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
598 return TRUE;
602 /***********************************************************************
603 * X11DRV thread termination routine
605 static void thread_detach(void)
607 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
609 if (data)
611 X11DRV_ResetSelectionOwner();
612 wine_tsx11_lock();
613 if (data->xim) XCloseIM( data->xim );
614 if (data->font_set) XFreeFontSet( data->display, data->font_set );
615 XCloseDisplay( data->display );
616 wine_tsx11_unlock();
617 HeapFree( GetProcessHeap(), 0, data );
622 /***********************************************************************
623 * X11DRV process termination routine
625 static void process_detach(void)
627 X11DRV_Clipboard_Cleanup();
628 #ifdef SONAME_LIBXXF86VM
629 /* cleanup XVidMode */
630 X11DRV_XF86VM_Cleanup();
631 #endif
632 X11DRV_XRender_Finalize();
634 /* cleanup GDI */
635 X11DRV_GDI_Finalize();
637 IME_UnregisterClasses();
638 DeleteCriticalSection( &X11DRV_CritSection );
639 TlsFree( thread_data_tls_index );
643 /* store the display fd into the message queue */
644 static void set_queue_display_fd( Display *display )
646 HANDLE handle;
647 int ret;
649 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
651 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
652 ExitProcess(1);
654 SERVER_START_REQ( set_queue_fd )
656 req->handle = wine_server_obj_handle( handle );
657 ret = wine_server_call( req );
659 SERVER_END_REQ;
660 if (ret)
662 MESSAGE( "x11drv: Can't store handle for display fd\n" );
663 ExitProcess(1);
665 CloseHandle( handle );
669 /***********************************************************************
670 * X11DRV thread initialisation routine
672 struct x11drv_thread_data *x11drv_init_thread_data(void)
674 struct x11drv_thread_data *data = x11drv_thread_data();
676 if (data) return data;
678 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
680 ERR( "could not create data\n" );
681 ExitProcess(1);
683 wine_tsx11_lock();
684 if (!(data->display = XOpenDisplay(NULL)))
686 wine_tsx11_unlock();
687 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));
688 ExitProcess(1);
691 fcntl( ConnectionNumber(data->display), F_SETFD, 1 ); /* set close on exec flag */
693 #ifdef HAVE_XKB
694 if (use_xkb && XkbUseExtension( data->display, NULL, NULL ))
695 XkbSetDetectableAutoRepeat( data->display, True, NULL );
696 #endif
698 if (TRACE_ON(synchronous)) XSynchronize( data->display, True );
699 wine_tsx11_unlock();
701 set_queue_display_fd( data->display );
702 TlsSetValue( thread_data_tls_index, data );
704 if (use_xim) X11DRV_SetupXIM();
706 return data;
710 /***********************************************************************
711 * X11DRV initialisation routine
713 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
715 BOOL ret = TRUE;
717 switch(reason)
719 case DLL_PROCESS_ATTACH:
720 x11drv_module = hinst;
721 ret = process_attach();
722 break;
723 case DLL_THREAD_DETACH:
724 thread_detach();
725 break;
726 case DLL_PROCESS_DETACH:
727 process_detach();
728 break;
730 return ret;
733 /***********************************************************************
734 * GetScreenSaveActive (X11DRV.@)
736 * Returns the active status of the screen saver
738 BOOL CDECL X11DRV_GetScreenSaveActive(void)
740 int timeout, temp;
741 wine_tsx11_lock();
742 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
743 wine_tsx11_unlock();
744 return timeout != 0;
747 /***********************************************************************
748 * SetScreenSaveActive (X11DRV.@)
750 * Activate/Deactivate the screen saver
752 void CDECL X11DRV_SetScreenSaveActive(BOOL bActivate)
754 int timeout, interval, prefer_blanking, allow_exposures;
755 static int last_timeout = 15 * 60;
757 wine_tsx11_lock();
758 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
759 &allow_exposures);
760 if (timeout) last_timeout = timeout;
762 timeout = bActivate ? last_timeout : 0;
763 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
764 allow_exposures);
765 wine_tsx11_unlock();