wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / winex11.drv / x11drv_main.c
blob9ec4c7a98f64accf7c85fea8ce6e2168427adca0
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 "ntstatus.h"
46 #define WIN32_NO_STATUS
47 #include "windef.h"
48 #include "winbase.h"
49 #include "winreg.h"
51 #include "x11drv.h"
52 #include "xcomposite.h"
53 #include "wine/server.h"
54 #include "wine/unicode.h"
55 #include "wine/debug.h"
56 #include "wine/list.h"
57 #include "wine/heap.h"
59 WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
60 WINE_DECLARE_DEBUG_CHANNEL(synchronous);
61 WINE_DECLARE_DEBUG_CHANNEL(winediag);
63 XVisualInfo default_visual = { 0 };
64 XVisualInfo argb_visual = { 0 };
65 Colormap default_colormap = None;
66 XPixmapFormatValues **pixmap_formats;
67 unsigned int screen_bpp;
68 Window root_window;
69 BOOL usexvidmode = TRUE;
70 BOOL usexrandr = TRUE;
71 BOOL usexcomposite = TRUE;
72 BOOL use_xkb = TRUE;
73 BOOL use_take_focus = TRUE;
74 BOOL use_primary_selection = FALSE;
75 BOOL use_system_cursors = TRUE;
76 BOOL show_systray = TRUE;
77 BOOL grab_pointer = TRUE;
78 BOOL grab_fullscreen = FALSE;
79 BOOL managed_mode = TRUE;
80 BOOL decorated_mode = TRUE;
81 BOOL private_color_map = FALSE;
82 int primary_monitor = 0;
83 BOOL client_side_graphics = TRUE;
84 BOOL client_side_with_render = TRUE;
85 BOOL shape_layered_windows = TRUE;
86 int copy_default_colors = 128;
87 int alloc_system_colors = 256;
88 DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
89 int xrender_error_base = 0;
90 HMODULE x11drv_module = 0;
91 char *process_name = NULL;
93 static x11drv_error_callback err_callback; /* current callback for error */
94 static Display *err_callback_display; /* display callback is set for */
95 static void *err_callback_arg; /* error callback argument */
96 static int err_callback_result; /* error callback result */
97 static unsigned long err_serial; /* serial number of first request */
98 static int (*old_error_handler)( Display *, XErrorEvent * );
99 static BOOL use_xim = TRUE;
100 static char input_style[20];
102 static CRITICAL_SECTION x11drv_section;
103 static CRITICAL_SECTION_DEBUG critsect_debug =
105 0, 0, &x11drv_section,
106 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
107 0, 0, { (DWORD_PTR)(__FILE__ ": x11drv_section") }
109 static CRITICAL_SECTION x11drv_section = { &critsect_debug, -1, 0, 0, 0, 0 };
111 struct d3dkmt_vidpn_source
113 D3DKMT_VIDPNSOURCEOWNER_TYPE type; /* VidPN source owner type */
114 D3DDDI_VIDEO_PRESENT_SOURCE_ID id; /* VidPN present source id */
115 D3DKMT_HANDLE device; /* Kernel mode device context */
116 struct list entry; /* List entry */
119 static struct list d3dkmt_vidpn_sources = LIST_INIT( d3dkmt_vidpn_sources ); /* VidPN source information list */
121 #define IS_OPTION_TRUE(ch) \
122 ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
123 #define IS_OPTION_FALSE(ch) \
124 ((ch) == 'n' || (ch) == 'N' || (ch) == 'f' || (ch) == 'F' || (ch) == '0')
126 Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
128 static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
130 "CLIPBOARD",
131 "COMPOUND_TEXT",
132 "INCR",
133 "MANAGER",
134 "MULTIPLE",
135 "SELECTION_DATA",
136 "TARGETS",
137 "TEXT",
138 "TIMESTAMP",
139 "UTF8_STRING",
140 "RAW_ASCENT",
141 "RAW_DESCENT",
142 "RAW_CAP_HEIGHT",
143 "Rel X",
144 "Rel Y",
145 "WM_PROTOCOLS",
146 "WM_DELETE_WINDOW",
147 "WM_STATE",
148 "WM_TAKE_FOCUS",
149 "DndProtocol",
150 "DndSelection",
151 "_ICC_PROFILE",
152 "_MOTIF_WM_HINTS",
153 "_NET_STARTUP_INFO_BEGIN",
154 "_NET_STARTUP_INFO",
155 "_NET_SUPPORTED",
156 "_NET_SYSTEM_TRAY_OPCODE",
157 "_NET_SYSTEM_TRAY_S0",
158 "_NET_SYSTEM_TRAY_VISUAL",
159 "_NET_WM_ICON",
160 "_NET_WM_MOVERESIZE",
161 "_NET_WM_NAME",
162 "_NET_WM_PID",
163 "_NET_WM_PING",
164 "_NET_WM_STATE",
165 "_NET_WM_STATE_ABOVE",
166 "_NET_WM_STATE_DEMANDS_ATTENTION",
167 "_NET_WM_STATE_FULLSCREEN",
168 "_NET_WM_STATE_MAXIMIZED_HORZ",
169 "_NET_WM_STATE_MAXIMIZED_VERT",
170 "_NET_WM_STATE_SKIP_PAGER",
171 "_NET_WM_STATE_SKIP_TASKBAR",
172 "_NET_WM_USER_TIME",
173 "_NET_WM_USER_TIME_WINDOW",
174 "_NET_WM_WINDOW_OPACITY",
175 "_NET_WM_WINDOW_TYPE",
176 "_NET_WM_WINDOW_TYPE_DIALOG",
177 "_NET_WM_WINDOW_TYPE_NORMAL",
178 "_NET_WM_WINDOW_TYPE_UTILITY",
179 "_NET_WORKAREA",
180 "_GTK_WORKAREAS_D0",
181 "_XEMBED",
182 "_XEMBED_INFO",
183 "XdndAware",
184 "XdndEnter",
185 "XdndPosition",
186 "XdndStatus",
187 "XdndLeave",
188 "XdndFinished",
189 "XdndDrop",
190 "XdndActionCopy",
191 "XdndActionMove",
192 "XdndActionLink",
193 "XdndActionAsk",
194 "XdndActionPrivate",
195 "XdndSelection",
196 "XdndTypeList",
197 "HTML Format",
198 "WCF_DIF",
199 "WCF_ENHMETAFILE",
200 "WCF_HDROP",
201 "WCF_PENDATA",
202 "WCF_RIFF",
203 "WCF_SYLK",
204 "WCF_TIFF",
205 "WCF_WAVE",
206 "image/bmp",
207 "image/gif",
208 "image/jpeg",
209 "image/png",
210 "text/html",
211 "text/plain",
212 "text/rtf",
213 "text/richtext",
214 "text/uri-list"
217 /***********************************************************************
218 * ignore_error
220 * Check if the X error is one we can ignore.
222 static inline BOOL ignore_error( Display *display, XErrorEvent *event )
224 if ((event->request_code == X_SetInputFocus ||
225 event->request_code == X_ChangeWindowAttributes ||
226 event->request_code == X_SendEvent) &&
227 (event->error_code == BadMatch ||
228 event->error_code == BadWindow)) return TRUE;
230 /* the clipboard display interacts with external windows, ignore all errors */
231 if (display == clipboard_display) return TRUE;
233 /* ignore a number of errors on gdi display caused by creating/destroying windows */
234 if (display == gdi_display)
236 if (event->error_code == BadDrawable ||
237 event->error_code == BadGC ||
238 event->error_code == BadWindow)
239 return TRUE;
240 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
241 if (xrender_error_base) /* check for XRender errors */
243 if (event->error_code == xrender_error_base + BadPicture) return TRUE;
245 #endif
247 return FALSE;
251 /***********************************************************************
252 * X11DRV_expect_error
254 * Setup a callback function that will be called on an X error. The
255 * callback must return non-zero if the error is the one it expected.
257 void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg )
259 err_callback = callback;
260 err_callback_display = display;
261 err_callback_arg = arg;
262 err_callback_result = 0;
263 err_serial = NextRequest(display);
267 /***********************************************************************
268 * X11DRV_check_error
270 * Check if an expected X11 error occurred; return non-zero if yes.
271 * The caller is responsible for calling XSync first if necessary.
273 int X11DRV_check_error(void)
275 err_callback = NULL;
276 return err_callback_result;
280 /***********************************************************************
281 * error_handler
283 static int error_handler( Display *display, XErrorEvent *error_evt )
285 if (err_callback && display == err_callback_display &&
286 (long)(error_evt->serial - err_serial) >= 0)
288 if ((err_callback_result = err_callback( display, error_evt, err_callback_arg )))
290 TRACE( "got expected error %d req %d\n",
291 error_evt->error_code, error_evt->request_code );
292 return 0;
295 if (ignore_error( display, error_evt ))
297 TRACE( "got ignored error %d req %d\n",
298 error_evt->error_code, error_evt->request_code );
299 return 0;
301 if (TRACE_ON(synchronous))
303 ERR( "X protocol error: serial=%ld, request_code=%d - breaking into debugger\n",
304 error_evt->serial, error_evt->request_code );
305 DebugBreak(); /* force an entry in the debugger */
307 old_error_handler( display, error_evt );
308 return 0;
311 /***********************************************************************
312 * init_pixmap_formats
314 static void init_pixmap_formats( Display *display )
316 int i, count, max = 32;
317 XPixmapFormatValues *formats = XListPixmapFormats( display, &count );
319 for (i = 0; i < count; i++)
321 TRACE( "depth %u, bpp %u, pad %u\n",
322 formats[i].depth, formats[i].bits_per_pixel, formats[i].scanline_pad );
323 if (formats[i].depth > max) max = formats[i].depth;
325 pixmap_formats = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pixmap_formats) * (max + 1) );
326 for (i = 0; i < count; i++) pixmap_formats[formats[i].depth] = &formats[i];
330 /***********************************************************************
331 * get_config_key
333 * Get a config key from either the app-specific or the default config
335 static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
336 char *buffer, DWORD size )
338 if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
339 if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0;
340 return ERROR_FILE_NOT_FOUND;
344 /***********************************************************************
345 * setup_options
347 * Setup the x11drv options.
349 static void setup_options(void)
351 static const WCHAR x11driverW[] = {'\\','X','1','1',' ','D','r','i','v','e','r',0};
352 char buffer[64];
353 WCHAR bufferW[MAX_PATH+16];
354 HKEY hkey, appkey = 0;
355 DWORD len;
357 /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */
358 if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0;
360 /* open the app-specific key */
362 len = (GetModuleFileNameW( 0, bufferW, MAX_PATH ));
363 if (len && len < MAX_PATH)
365 HKEY tmpkey;
366 WCHAR *p, *appname = bufferW;
367 if ((p = strrchrW( appname, '/' ))) appname = p + 1;
368 if ((p = strrchrW( appname, '\\' ))) appname = p + 1;
369 CharLowerW(appname);
370 len = WideCharToMultiByte( CP_UNIXCP, 0, appname, -1, NULL, 0, NULL, NULL );
371 if ((process_name = HeapAlloc( GetProcessHeap(), 0, len )))
372 WideCharToMultiByte( CP_UNIXCP, 0, appname, -1, process_name, len, NULL, NULL );
373 strcatW( appname, x11driverW );
374 /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */
375 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey ))
377 if (RegOpenKeyW( tmpkey, appname, &appkey )) appkey = 0;
378 RegCloseKey( tmpkey );
382 if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) ))
383 managed_mode = IS_OPTION_TRUE( buffer[0] );
385 if (!get_config_key( hkey, appkey, "Decorated", buffer, sizeof(buffer) ))
386 decorated_mode = IS_OPTION_TRUE( buffer[0] );
388 if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) ))
389 usexvidmode = IS_OPTION_TRUE( buffer[0] );
391 if (!get_config_key( hkey, appkey, "UseXRandR", buffer, sizeof(buffer) ))
392 usexrandr = IS_OPTION_TRUE( buffer[0] );
394 if (!get_config_key( hkey, appkey, "UseTakeFocus", buffer, sizeof(buffer) ))
395 use_take_focus = IS_OPTION_TRUE( buffer[0] );
397 if (!get_config_key( hkey, appkey, "UsePrimarySelection", buffer, sizeof(buffer) ))
398 use_primary_selection = IS_OPTION_TRUE( buffer[0] );
400 if (!get_config_key( hkey, appkey, "UseSystemCursors", buffer, sizeof(buffer) ))
401 use_system_cursors = IS_OPTION_TRUE( buffer[0] );
403 if (!get_config_key( hkey, appkey, "ShowSystray", buffer, sizeof(buffer) ))
404 show_systray = IS_OPTION_TRUE( buffer[0] );
406 if (!get_config_key( hkey, appkey, "GrabPointer", buffer, sizeof(buffer) ))
407 grab_pointer = IS_OPTION_TRUE( buffer[0] );
409 if (!get_config_key( hkey, appkey, "GrabFullscreen", buffer, sizeof(buffer) ))
410 grab_fullscreen = IS_OPTION_TRUE( buffer[0] );
412 if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) ))
413 default_visual.depth = atoi(buffer);
415 if (!get_config_key( hkey, appkey, "ClientSideGraphics", buffer, sizeof(buffer) ))
416 client_side_graphics = IS_OPTION_TRUE( buffer[0] );
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, "UseXIM", buffer, sizeof(buffer) ))
422 use_xim = IS_OPTION_TRUE( buffer[0] );
424 if (!get_config_key( hkey, appkey, "ShapeLayeredWindows", buffer, sizeof(buffer) ))
425 shape_layered_windows = IS_OPTION_TRUE( buffer[0] );
427 if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
428 private_color_map = IS_OPTION_TRUE( buffer[0] );
430 if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
431 primary_monitor = atoi( buffer );
433 if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
434 copy_default_colors = atoi(buffer);
436 if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) ))
437 alloc_system_colors = atoi(buffer);
439 get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) );
441 if (appkey) RegCloseKey( appkey );
442 if (hkey) RegCloseKey( hkey );
445 #ifdef SONAME_LIBXCOMPOSITE
447 #define MAKE_FUNCPTR(f) typeof(f) * p##f;
448 MAKE_FUNCPTR(XCompositeQueryExtension)
449 MAKE_FUNCPTR(XCompositeQueryVersion)
450 MAKE_FUNCPTR(XCompositeVersion)
451 MAKE_FUNCPTR(XCompositeRedirectWindow)
452 MAKE_FUNCPTR(XCompositeRedirectSubwindows)
453 MAKE_FUNCPTR(XCompositeUnredirectWindow)
454 MAKE_FUNCPTR(XCompositeUnredirectSubwindows)
455 MAKE_FUNCPTR(XCompositeCreateRegionFromBorderClip)
456 MAKE_FUNCPTR(XCompositeNameWindowPixmap)
457 #undef MAKE_FUNCPTR
459 static int xcomp_event_base;
460 static int xcomp_error_base;
462 static void X11DRV_XComposite_Init(void)
464 void *xcomposite_handle = dlopen(SONAME_LIBXCOMPOSITE, RTLD_NOW);
465 if (!xcomposite_handle)
467 TRACE("Unable to open %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
468 usexcomposite = FALSE;
469 return;
472 #define LOAD_FUNCPTR(f) \
473 if((p##f = dlsym(xcomposite_handle, #f)) == NULL) goto sym_not_found
474 LOAD_FUNCPTR(XCompositeQueryExtension);
475 LOAD_FUNCPTR(XCompositeQueryVersion);
476 LOAD_FUNCPTR(XCompositeVersion);
477 LOAD_FUNCPTR(XCompositeRedirectWindow);
478 LOAD_FUNCPTR(XCompositeRedirectSubwindows);
479 LOAD_FUNCPTR(XCompositeUnredirectWindow);
480 LOAD_FUNCPTR(XCompositeUnredirectSubwindows);
481 LOAD_FUNCPTR(XCompositeCreateRegionFromBorderClip);
482 LOAD_FUNCPTR(XCompositeNameWindowPixmap);
483 #undef LOAD_FUNCPTR
485 if(!pXCompositeQueryExtension(gdi_display, &xcomp_event_base,
486 &xcomp_error_base)) {
487 TRACE("XComposite extension could not be queried; disabled\n");
488 dlclose(xcomposite_handle);
489 xcomposite_handle = NULL;
490 usexcomposite = FALSE;
491 return;
493 TRACE("XComposite is up and running error_base = %d\n", xcomp_error_base);
494 return;
496 sym_not_found:
497 TRACE("Unable to load function pointers from %s, XComposite disabled\n", SONAME_LIBXCOMPOSITE);
498 dlclose(xcomposite_handle);
499 xcomposite_handle = NULL;
500 usexcomposite = FALSE;
502 #endif /* defined(SONAME_LIBXCOMPOSITE) */
504 static void init_visuals( Display *display, int screen )
506 int count;
507 XVisualInfo *info;
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 );
524 default_visual.screen = screen;
525 if (default_visual.depth) /* depth specified */
527 if (default_visual.depth == 32 && argb_visual.visual)
529 default_visual = argb_visual;
531 else if ((info = XGetVisualInfo( display, VisualScreenMask | VisualDepthMask, &default_visual, &count )))
533 default_visual = *info;
534 XFree( info );
536 else WARN( "no visual found for depth %d\n", default_visual.depth );
539 if (!default_visual.visual)
541 default_visual.depth = DefaultDepth( display, screen );
542 default_visual.visual = DefaultVisual( display, screen );
543 default_visual.visualid = default_visual.visual->visualid;
544 default_visual.class = default_visual.visual->class;
545 default_visual.red_mask = default_visual.visual->red_mask;
546 default_visual.green_mask = default_visual.visual->green_mask;
547 default_visual.blue_mask = default_visual.visual->blue_mask;
548 default_visual.colormap_size = default_visual.visual->map_entries;
549 default_visual.bits_per_rgb = default_visual.visual->bits_per_rgb;
551 default_colormap = XCreateColormap( display, root_window, default_visual.visual, AllocNone );
553 TRACE( "default visual %lx class %u argb %lx\n",
554 default_visual.visualid, default_visual.class, argb_visual.visualid );
557 /***********************************************************************
558 * X11DRV process initialisation routine
560 static BOOL process_attach(void)
562 Display *display;
563 void *libx11 = dlopen( SONAME_LIBX11, RTLD_NOW|RTLD_GLOBAL );
565 if (!libx11)
567 ERR( "failed to load %s: %s\n", SONAME_LIBX11, dlerror() );
568 return FALSE;
570 pXGetEventData = dlsym( libx11, "XGetEventData" );
571 pXFreeEventData = dlsym( libx11, "XFreeEventData" );
572 #ifdef SONAME_LIBXEXT
573 dlopen( SONAME_LIBXEXT, RTLD_NOW|RTLD_GLOBAL );
574 #endif
576 setup_options();
578 if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
580 /* Open display */
582 if (!XInitThreads()) ERR( "XInitThreads failed, trouble ahead\n" );
583 if (!(display = XOpenDisplay( NULL ))) return FALSE;
585 fcntl( ConnectionNumber(display), F_SETFD, 1 ); /* set close on exec flag */
586 root_window = DefaultRootWindow( display );
587 gdi_display = display;
588 old_error_handler = XSetErrorHandler( error_handler );
590 init_pixmap_formats( display );
591 init_visuals( display, DefaultScreen( display ));
592 screen_bpp = pixmap_formats[default_visual.depth]->bits_per_pixel;
594 XInternAtoms( display, (char **)atom_names, NB_XATOMS - FIRST_XATOM, False, X11DRV_Atoms );
596 winContext = XUniqueContext();
597 win_data_context = XUniqueContext();
598 cursor_context = XUniqueContext();
600 if (TRACE_ON(synchronous)) XSynchronize( display, True );
602 xinerama_init( DisplayWidth( display, default_visual.screen ),
603 DisplayHeight( display, default_visual.screen ));
604 X11DRV_Settings_Init();
606 /* initialize XVidMode */
607 X11DRV_XF86VM_Init();
608 /* initialize XRandR */
609 X11DRV_XRandR_Init();
610 #ifdef SONAME_LIBXCOMPOSITE
611 X11DRV_XComposite_Init();
612 #endif
613 X11DRV_XInput2_Init();
615 #ifdef HAVE_XKB
616 if (use_xkb) use_xkb = XkbUseExtension( gdi_display, NULL, NULL );
617 #endif
618 X11DRV_InitKeyboard( gdi_display );
619 if (use_xim) use_xim = X11DRV_InitXIM( input_style );
621 X11DRV_DisplayDevices_Init(FALSE);
622 return TRUE;
626 /***********************************************************************
627 * ThreadDetach (X11DRV.@)
629 void CDECL X11DRV_ThreadDetach(void)
631 struct x11drv_thread_data *data = TlsGetValue( thread_data_tls_index );
633 if (data)
635 if (data->xim) XCloseIM( data->xim );
636 if (data->font_set) XFreeFontSet( data->display, data->font_set );
637 XCloseDisplay( data->display );
638 HeapFree( GetProcessHeap(), 0, data );
639 /* clear data in case we get re-entered from user32 before the thread is truly dead */
640 TlsSetValue( thread_data_tls_index, NULL );
645 /* store the display fd into the message queue */
646 static void set_queue_display_fd( Display *display )
648 HANDLE handle;
649 int ret;
651 if (wine_server_fd_to_handle( ConnectionNumber(display), GENERIC_READ | SYNCHRONIZE, 0, &handle ))
653 MESSAGE( "x11drv: Can't allocate handle for display fd\n" );
654 ExitProcess(1);
656 SERVER_START_REQ( set_queue_fd )
658 req->handle = wine_server_obj_handle( handle );
659 ret = wine_server_call( req );
661 SERVER_END_REQ;
662 if (ret)
664 MESSAGE( "x11drv: Can't store handle for display fd\n" );
665 ExitProcess(1);
667 CloseHandle( handle );
671 /***********************************************************************
672 * X11DRV thread initialisation routine
674 struct x11drv_thread_data *x11drv_init_thread_data(void)
676 struct x11drv_thread_data *data = x11drv_thread_data();
678 if (data) return data;
680 if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) )))
682 ERR( "could not create data\n" );
683 ExitProcess(1);
685 if (!(data->display = XOpenDisplay(NULL)))
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 );
700 set_queue_display_fd( data->display );
701 TlsSetValue( thread_data_tls_index, data );
703 if (use_xim) X11DRV_SetupXIM();
705 return data;
709 /***********************************************************************
710 * X11DRV initialisation routine
712 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
714 BOOL ret = TRUE;
716 switch(reason)
718 case DLL_PROCESS_ATTACH:
719 DisableThreadLibraryCalls( hinst );
720 x11drv_module = hinst;
721 ret = process_attach();
722 break;
724 return ret;
728 /***********************************************************************
729 * SystemParametersInfo (X11DRV.@)
731 BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_param, UINT flags )
733 switch (action)
735 case SPI_GETSCREENSAVEACTIVE:
736 if (ptr_param)
738 int timeout, temp;
739 XGetScreenSaver(gdi_display, &timeout, &temp, &temp, &temp);
740 *(BOOL *)ptr_param = timeout != 0;
741 return TRUE;
743 break;
744 case SPI_SETSCREENSAVEACTIVE:
746 int timeout, interval, prefer_blanking, allow_exposures;
747 static int last_timeout = 15 * 60;
749 XLockDisplay( gdi_display );
750 XGetScreenSaver(gdi_display, &timeout, &interval, &prefer_blanking,
751 &allow_exposures);
752 if (timeout) last_timeout = timeout;
754 timeout = int_param ? last_timeout : 0;
755 XSetScreenSaver(gdi_display, timeout, interval, prefer_blanking,
756 allow_exposures);
757 XUnlockDisplay( gdi_display );
759 break;
761 return FALSE; /* let user32 handle it */
764 /**********************************************************************
765 * X11DRV_D3DKMTSetVidPnSourceOwner
767 NTSTATUS CDECL X11DRV_D3DKMTSetVidPnSourceOwner( const D3DKMT_SETVIDPNSOURCEOWNER *desc )
769 struct d3dkmt_vidpn_source *source, *source2;
770 NTSTATUS status = STATUS_SUCCESS;
771 BOOL found;
772 UINT i;
774 TRACE("(%p)\n", desc);
776 EnterCriticalSection( &x11drv_section );
778 /* Check parameters */
779 for (i = 0; i < desc->VidPnSourceCount; ++i)
781 LIST_FOR_EACH_ENTRY( source, &d3dkmt_vidpn_sources, struct d3dkmt_vidpn_source, entry )
783 if (source->id == desc->pVidPnSourceId[i])
785 /* Same device */
786 if (source->device == desc->hDevice)
788 if ((source->type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
789 && (desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_SHARED
790 || desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EMULATED))
791 || (source->type == D3DKMT_VIDPNSOURCEOWNER_EMULATED
792 && desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE))
794 status = STATUS_INVALID_PARAMETER;
795 goto done;
798 /* Different devices */
799 else
801 if ((source->type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
802 || source->type == D3DKMT_VIDPNSOURCEOWNER_EMULATED)
803 && (desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE
804 || desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EMULATED))
806 status = STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE;
807 goto done;
813 /* On Windows, it seems that all video present sources are owned by DMM clients, so any attempt to set
814 * D3DKMT_VIDPNSOURCEOWNER_SHARED come back STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE */
815 if (desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_SHARED)
817 status = STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE;
818 goto done;
821 /* FIXME: D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVEGDI unsupported */
822 if (desc->pType[i] == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVEGDI || desc->pType[i] > D3DKMT_VIDPNSOURCEOWNER_EMULATED)
824 status = STATUS_INVALID_PARAMETER;
825 goto done;
829 /* Remove owner */
830 if (!desc->VidPnSourceCount && !desc->pType && !desc->pVidPnSourceId)
832 LIST_FOR_EACH_ENTRY_SAFE( source, source2, &d3dkmt_vidpn_sources, struct d3dkmt_vidpn_source, entry )
834 if (source->device == desc->hDevice)
836 list_remove( &source->entry );
837 heap_free( source );
840 goto done;
843 /* Add owner */
844 for (i = 0; i < desc->VidPnSourceCount; ++i)
846 found = FALSE;
847 LIST_FOR_EACH_ENTRY( source, &d3dkmt_vidpn_sources, struct d3dkmt_vidpn_source, entry )
849 if (source->device == desc->hDevice && source->id == desc->pVidPnSourceId[i])
851 found = TRUE;
852 break;
856 if (found)
857 source->type = desc->pType[i];
858 else
860 source = heap_alloc( sizeof( *source ) );
861 if (!source)
863 status = STATUS_NO_MEMORY;
864 goto done;
867 source->id = desc->pVidPnSourceId[i];
868 source->type = desc->pType[i];
869 source->device = desc->hDevice;
870 list_add_tail( &d3dkmt_vidpn_sources, &source->entry );
874 done:
875 LeaveCriticalSection( &x11drv_section );
876 return status;
879 /**********************************************************************
880 * X11DRV_D3DKMTCheckVidPnExclusiveOwnership
882 NTSTATUS CDECL X11DRV_D3DKMTCheckVidPnExclusiveOwnership( const D3DKMT_CHECKVIDPNEXCLUSIVEOWNERSHIP *desc )
884 struct d3dkmt_vidpn_source *source;
886 TRACE("(%p)\n", desc);
888 if (!desc || !desc->hAdapter)
889 return STATUS_INVALID_PARAMETER;
891 EnterCriticalSection( &x11drv_section );
892 LIST_FOR_EACH_ENTRY( source, &d3dkmt_vidpn_sources, struct d3dkmt_vidpn_source, entry )
894 if (source->id == desc->VidPnSourceId && source->type == D3DKMT_VIDPNSOURCEOWNER_EXCLUSIVE)
896 LeaveCriticalSection( &x11drv_section );
897 return STATUS_GRAPHICS_PRESENT_OCCLUDED;
900 LeaveCriticalSection( &x11drv_section );
901 return STATUS_SUCCESS;