2 * X11DRV initialization code
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2000 Alexandre Julliard
13 #include <X11/cursorfont.h>
18 #include "wine/winbase16.h"
22 #include "clipboard.h"
23 #include "debugtools.h"
32 DEFAULT_DEBUG_CHANNEL(x11drv
);
34 static USER_DRIVER user_driver
=
37 X11DRV_EVENT_Synchronize
,
38 X11DRV_EVENT_CheckFocus
,
39 X11DRV_EVENT_UserRepaintDisable
,
40 /* keyboard functions */
42 X11DRV_KEYBOARD_VkKeyScan
,
43 X11DRV_KEYBOARD_MapVirtualKey
,
44 X11DRV_KEYBOARD_GetKeyNameText
,
45 X11DRV_KEYBOARD_ToAscii
,
46 X11DRV_KEYBOARD_GetBeepActive
,
47 X11DRV_KEYBOARD_SetBeepActive
,
49 X11DRV_KEYBOARD_GetDIState
,
50 X11DRV_KEYBOARD_GetDIData
,
51 X11DRV_KEYBOARD_GetKeyboardConfig
,
52 X11DRV_KEYBOARD_SetKeyboardConfig
,
55 X11DRV_MOUSE_SetCursor
,
56 X11DRV_MOUSE_MoveCursor
,
57 /* screen saver functions */
58 X11DRV_GetScreenSaveActive
,
59 X11DRV_SetScreenSaveActive
,
60 X11DRV_GetScreenSaveTimeout
,
61 X11DRV_SetScreenSaveTimeout
,
62 /* windowing functions */
66 static XKeyboardState keyboard_state
;
74 /***********************************************************************
77 static int error_handler(Display
*display
, XErrorEvent
*error_evt
)
79 DebugBreak(); /* force an entry in the debugger */
84 /***********************************************************************
87 * Setup the x11drv options.
89 static void setup_options(void)
95 if (RegCreateKeyExA( HKEY_LOCAL_MACHINE
, "Software\\Wine\\Wine\\Config\\x11drv", 0, NULL
,
96 REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
))
98 ERR("Cannot create config registry key\n" );
102 /* --display option */
104 count
= sizeof(buffer
);
105 if (!RegQueryValueExA( hkey
, "display", 0, &type
, buffer
, &count
))
109 if (strcmp( buffer
, Options
.display
))
110 MESSAGE( "%s: warning: --display option ignored, using '%s'\n", argv0
, buffer
);
112 else if ((Options
.display
= getenv( "DISPLAY" )))
114 if (strcmp( buffer
, Options
.display
))
115 MESSAGE( "%s: warning: $DISPLAY variable ignored, using '%s'\n", argv0
, buffer
);
117 Options
.display
= strdup(buffer
);
121 if (!Options
.display
&& !(Options
.display
= getenv( "DISPLAY" )))
123 MESSAGE( "%s: no display specified\n", argv0
);
126 RegSetValueExA( hkey
, "display", 0, REG_SZ
, Options
.display
, strlen(Options
.display
)+1 );
129 /* --managed option */
131 if (!Options
.managed
)
133 count
= sizeof(buffer
);
134 if (!RegQueryValueExA( hkey
, "managed", 0, &type
, buffer
, &count
))
135 Options
.managed
= IS_OPTION_TRUE( buffer
[0] );
137 else RegSetValueExA( hkey
, "managed", 0, REG_SZ
, "y", 2 );
143 /***********************************************************************
146 * Create the desktop window for the --desktop mode.
148 static void create_desktop( const char *geometry
)
150 int x
= 0, y
= 0, flags
;
151 unsigned int width
= 640, height
= 480; /* Default size = 640x480 */
152 char *name
= "Wine desktop";
153 XSizeHints
*size_hints
;
155 XClassHint
*class_hints
;
156 XSetWindowAttributes win_attr
;
157 XTextProperty window_name
;
158 Atom XA_WM_DELETE_WINDOW
;
159 /* Used to create the desktop window with a good visual */
160 XVisualInfo
*vi
= NULL
;
164 /* Get in wine.ini if the desktop window should have a double-buffered visual or not */
165 dblbuf_visual
= PROFILE_GetWineIniBool( "x11drv", "DesktopDoubleBuffered", 0 );
167 int dblBuf
[]={GLX_RGBA
,GLX_DEPTH_SIZE
,16,GLX_DOUBLEBUFFER
,None
};
170 vi
= glXChooseVisual(display
, DefaultScreen(display
), dblBuf
);
171 win_attr
.colormap
= XCreateColormap(display
, RootWindow(display
,vi
->screen
),
172 vi
->visual
, AllocNone
);
175 #endif /* HAVE_OPENGL */
177 flags
= TSXParseGeometry( geometry
, &x
, &y
, &width
, &height
);
178 MONITOR_PrimaryMonitor
.rect
.right
= width
;
179 MONITOR_PrimaryMonitor
.rect
.bottom
= height
;
182 win_attr
.background_pixel
= BlackPixel(display
, 0);
183 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
184 PointerMotionMask
| ButtonPressMask
|
185 ButtonReleaseMask
| EnterWindowMask
;
186 win_attr
.cursor
= TSXCreateFontCursor( display
, XC_top_left_arrow
);
190 screen
= ScreenOfDisplay(display
, vi
->screen
);
191 screen_depth
= vi
->depth
;
193 root_window
= TSXCreateWindow( display
,
194 (vi
== NULL
? DefaultRootWindow(display
) : RootWindow(display
, vi
->screen
)),
195 x
, y
, width
, height
, 0,
196 (vi
== NULL
? CopyFromParent
: vi
->depth
),
198 (vi
== NULL
? CopyFromParent
: vi
->visual
),
199 CWBackPixel
| CWEventMask
| CWCursor
| (vi
== NULL
? 0 : CWColormap
),
202 /* Set window manager properties */
203 size_hints
= TSXAllocSizeHints();
204 wm_hints
= TSXAllocWMHints();
205 class_hints
= TSXAllocClassHint();
206 if (!size_hints
|| !wm_hints
|| !class_hints
)
208 MESSAGE("Not enough memory for window manager hints.\n" );
211 size_hints
->min_width
= size_hints
->max_width
= width
;
212 size_hints
->min_height
= size_hints
->max_height
= height
;
213 size_hints
->flags
= PMinSize
| PMaxSize
;
214 if (flags
& (XValue
| YValue
)) size_hints
->flags
|= USPosition
;
215 if (flags
& (WidthValue
| HeightValue
)) size_hints
->flags
|= USSize
;
216 else size_hints
->flags
|= PSize
;
218 wm_hints
->flags
= InputHint
| StateHint
;
219 wm_hints
->input
= True
;
220 wm_hints
->initial_state
= NormalState
;
221 class_hints
->res_name
= (char *)argv0
;
222 class_hints
->res_class
= "Wine";
224 TSXStringListToTextProperty( &name
, 1, &window_name
);
225 TSXSetWMProperties( display
, root_window
, &window_name
, &window_name
,
226 NULL
, 0, size_hints
, wm_hints
, class_hints
);
227 XA_WM_DELETE_WINDOW
= TSXInternAtom( display
, "WM_DELETE_WINDOW", False
);
228 TSXSetWMProtocols( display
, root_window
, &XA_WM_DELETE_WINDOW
, 1 );
229 TSXFree( size_hints
);
231 TSXFree( class_hints
);
234 TSXMapWindow( display
, root_window
);
237 /* Created so that XOpenIM can be called using the 'large stack' */
238 static void XOpenIM_large_stack(void)
240 TSXOpenIM(display
,NULL
,NULL
,NULL
);
243 /***********************************************************************
244 * X11DRV process initialisation routine
246 static void process_attach(void)
248 USER_Driver
= &user_driver
;
249 CLIPBOARD_Driver
= &X11DRV_CLIPBOARD_Driver
;
250 WND_Driver
= &X11DRV_WND_Driver
;
256 if (!(display
= TSXOpenDisplay( Options
.display
)))
258 MESSAGE( "%s: Can't open display: %s\n", argv0
, Options
.display
);
261 fcntl( ConnectionNumber(display
), F_SETFD
, 1 ); /* set close on exec flag */
262 screen
= DefaultScreenOfDisplay( display
);
263 visual
= DefaultVisual( display
, DefaultScreen(display
) );
264 root_window
= DefaultRootWindow( display
);
266 /* Initialize screen depth */
268 screen_depth
= PROFILE_GetWineIniInt( "x11drv", "ScreenDepth", 0 );
269 if (screen_depth
) /* depth specified */
272 int *depth_list
= TSXListDepths(display
, DefaultScreen(display
), &depth_count
);
273 for (i
= 0; i
< depth_count
; i
++)
274 if (depth_list
[i
] == screen_depth
) break;
275 TSXFree( depth_list
);
276 if (i
>= depth_count
)
278 MESSAGE( "%s: Depth %d not supported on this screen.\n", argv0
, screen_depth
);
282 else screen_depth
= DefaultDepthOfScreen( screen
);
284 /* tell the libX11 that we will do input method handling ourselves
285 * that keep libX11 from doing anything whith dead keys, allowing Wine
286 * to have total control over dead keys, that is this line allows
287 * them to work in Wine, even whith a libX11 including the dead key
288 * patches from Th.Quinot (http://Web.FdN.FR/~tquinot/dead-keys.en.html)
290 CALL_LARGE_STACK( XOpenIM_large_stack
, NULL
);
292 if (Options
.synchronous
) XSetErrorHandler( error_handler
);
294 MONITOR_PrimaryMonitor
.rect
.left
= 0;
295 MONITOR_PrimaryMonitor
.rect
.top
= 0;
296 MONITOR_PrimaryMonitor
.rect
.right
= WidthOfScreen( screen
);
297 MONITOR_PrimaryMonitor
.rect
.bottom
= HeightOfScreen( screen
);
298 MONITOR_PrimaryMonitor
.depth
= screen_depth
;
300 if (Options
.desktopGeometry
)
302 Options
.managed
= FALSE
;
303 create_desktop( Options
.desktopGeometry
);
307 X11DRV_GDI_Initialize();
309 /* save keyboard setup */
310 TSXGetKeyboardControl(display
, &keyboard_state
);
312 /* initialize event handling */
315 /* load display.dll */
316 LoadLibrary16( "display" );
320 /***********************************************************************
321 * X11DRV process termination routine
323 static void process_detach(void)
325 /* restore keyboard setup */
326 XKeyboardControl keyboard_value
;
328 keyboard_value
.key_click_percent
= keyboard_state
.key_click_percent
;
329 keyboard_value
.bell_percent
= keyboard_state
.bell_percent
;
330 keyboard_value
.bell_pitch
= keyboard_state
.bell_pitch
;
331 keyboard_value
.bell_duration
= keyboard_state
.bell_duration
;
332 keyboard_value
.auto_repeat_mode
= keyboard_state
.global_auto_repeat
;
334 XChangeKeyboardControl(display
, KBKeyClickPercent
| KBBellPercent
|
335 KBBellPitch
| KBBellDuration
| KBAutoRepeatMode
, &keyboard_value
);
338 X11DRV_GDI_Finalize();
342 /* close the display */
343 XCloseDisplay( display
);
347 CLIPBOARD_Driver
= NULL
;
353 /***********************************************************************
354 * X11DRV initialisation routine
356 BOOL WINAPI
X11DRV_Init( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
358 static int process_count
;
362 case DLL_PROCESS_ATTACH
:
363 if (!process_count
++) process_attach();
365 case DLL_PROCESS_DETACH
:
366 if (!--process_count
) process_detach();
372 /***********************************************************************
373 * X11DRV_GetScreenSaveActive
375 * Returns the active status of the screen saver
377 BOOL
X11DRV_GetScreenSaveActive(void)
380 TSXGetScreenSaver(display
, &timeout
, &temp
, &temp
, &temp
);
384 /***********************************************************************
385 * X11DRV_SetScreenSaveActive
387 * Activate/Deactivate the screen saver
389 void X11DRV_SetScreenSaveActive(BOOL bActivate
)
392 TSXActivateScreenSaver(display
);
394 TSXResetScreenSaver(display
);
397 /***********************************************************************
398 * X11DRV_GetScreenSaveTimeout
400 * Return the screen saver timeout
402 int X11DRV_GetScreenSaveTimeout(void)
405 TSXGetScreenSaver(display
, &timeout
, &temp
, &temp
, &temp
);
409 /***********************************************************************
410 * X11DRV_SetScreenSaveTimeout
412 * Set the screen saver timeout
414 void X11DRV_SetScreenSaveTimeout(int nTimeout
)
416 TSXSetScreenSaver(display
, nTimeout
, 60, DefaultBlanking
, DefaultExposures
);
419 /***********************************************************************
420 * X11DRV_IsSingleWindow
422 BOOL
X11DRV_IsSingleWindow(void)
424 return (root_window
!= DefaultRootWindow(display
));