2 * X11DRV initialization code
4 * Copyright 1998 Patrik Stridvall
5 * Copyright 2000 Alexandre Julliard
11 #include <X11/cursorfont.h>
19 #include "clipboard.h"
20 #include "debugtools.h"
28 DEFAULT_DEBUG_CHANNEL(x11drv
);
30 static USER_DRIVER user_driver
=
33 X11DRV_EVENT_Synchronize
,
34 X11DRV_EVENT_CheckFocus
,
35 X11DRV_EVENT_UserRepaintDisable
,
36 /* keyboard functions */
38 X11DRV_KEYBOARD_VkKeyScan
,
39 X11DRV_KEYBOARD_MapVirtualKey
,
40 X11DRV_KEYBOARD_GetKeyNameText
,
41 X11DRV_KEYBOARD_ToAscii
,
42 X11DRV_KEYBOARD_GetBeepActive
,
43 X11DRV_KEYBOARD_SetBeepActive
,
45 X11DRV_KEYBOARD_GetDIState
,
46 X11DRV_KEYBOARD_GetDIData
,
47 X11DRV_KEYBOARD_GetKeyboardConfig
,
48 X11DRV_KEYBOARD_SetKeyboardConfig
,
51 X11DRV_MOUSE_SetCursor
,
52 X11DRV_MOUSE_MoveCursor
,
53 X11DRV_MOUSE_EnableWarpPointer
,
54 /* screen saver functions */
55 X11DRV_GetScreenSaveActive
,
56 X11DRV_SetScreenSaveActive
,
57 X11DRV_GetScreenSaveTimeout
,
58 X11DRV_SetScreenSaveTimeout
,
59 /* windowing functions */
63 static XKeyboardState keyboard_state
;
71 /***********************************************************************
74 static int error_handler(Display
*display
, XErrorEvent
*error_evt
)
76 DebugBreak(); /* force an entry in the debugger */
81 /***********************************************************************
84 * Setup the x11drv options.
86 static void setup_options(void)
92 if (RegCreateKeyExA( HKEY_LOCAL_MACHINE
, "Software\\Wine\\Wine\\Config\\x11drv", 0, NULL
,
93 REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
))
95 ERR("Cannot create config registry key\n" );
99 /* --display option */
101 count
= sizeof(buffer
);
102 if (!RegQueryValueExA( hkey
, "display", 0, &type
, buffer
, &count
))
106 if (strcmp( buffer
, Options
.display
))
107 MESSAGE( "%s: warning: --display option ignored, using '%s'\n", argv0
, buffer
);
109 else if ((Options
.display
= getenv( "DISPLAY" )))
111 if (strcmp( buffer
, Options
.display
))
112 MESSAGE( "%s: warning: $DISPLAY variable ignored, using '%s'\n", argv0
, buffer
);
114 Options
.display
= strdup(buffer
);
118 if (!Options
.display
&& !(Options
.display
= getenv( "DISPLAY" )))
120 MESSAGE( "%s: no display specified\n", argv0
);
123 RegSetValueExA( hkey
, "display", 0, REG_SZ
, Options
.display
, strlen(Options
.display
)+1 );
126 /* --managed option */
128 if (!Options
.managed
)
130 count
= sizeof(buffer
);
131 if (!RegQueryValueExA( hkey
, "managed", 0, &type
, buffer
, &count
))
132 Options
.managed
= IS_OPTION_TRUE( buffer
[0] );
134 else RegSetValueExA( hkey
, "managed", 0, REG_SZ
, "y", 2 );
140 /***********************************************************************
143 * Create the desktop window for the --desktop mode.
145 static void create_desktop( const char *geometry
)
147 int x
= 0, y
= 0, flags
;
148 unsigned int width
= 640, height
= 480; /* Default size = 640x480 */
149 char *name
= "Wine desktop";
150 XSizeHints
*size_hints
;
152 XClassHint
*class_hints
;
153 XSetWindowAttributes win_attr
;
154 XTextProperty window_name
;
155 Atom XA_WM_DELETE_WINDOW
;
157 flags
= TSXParseGeometry( geometry
, &x
, &y
, &width
, &height
);
158 MONITOR_PrimaryMonitor
.rect
.right
= width
;
159 MONITOR_PrimaryMonitor
.rect
.bottom
= height
;
163 win_attr
.background_pixel
= BlackPixel(display
, 0);
164 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
165 PointerMotionMask
| ButtonPressMask
|
166 ButtonReleaseMask
| EnterWindowMask
;
167 win_attr
.cursor
= TSXCreateFontCursor( display
, XC_top_left_arrow
);
169 root_window
= TSXCreateWindow( display
, DefaultRootWindow(display
),
170 x
, y
, width
, height
, 0,
171 CopyFromParent
, InputOutput
, CopyFromParent
,
172 CWBackPixel
| CWEventMask
| CWCursor
, &win_attr
);
174 /* Set window manager properties */
176 size_hints
= TSXAllocSizeHints();
177 wm_hints
= TSXAllocWMHints();
178 class_hints
= TSXAllocClassHint();
179 if (!size_hints
|| !wm_hints
|| !class_hints
)
181 MESSAGE("Not enough memory for window manager hints.\n" );
184 size_hints
->min_width
= size_hints
->max_width
= width
;
185 size_hints
->min_height
= size_hints
->max_height
= height
;
186 size_hints
->flags
= PMinSize
| PMaxSize
;
187 if (flags
& (XValue
| YValue
)) size_hints
->flags
|= USPosition
;
188 if (flags
& (WidthValue
| HeightValue
)) size_hints
->flags
|= USSize
;
189 else size_hints
->flags
|= PSize
;
191 wm_hints
->flags
= InputHint
| StateHint
;
192 wm_hints
->input
= True
;
193 wm_hints
->initial_state
= NormalState
;
194 class_hints
->res_name
= (char *)argv0
;
195 class_hints
->res_class
= "Wine";
197 TSXStringListToTextProperty( &name
, 1, &window_name
);
198 TSXSetWMProperties( display
, root_window
, &window_name
, &window_name
,
199 NULL
, 0, size_hints
, wm_hints
, class_hints
);
200 XA_WM_DELETE_WINDOW
= TSXInternAtom( display
, "WM_DELETE_WINDOW", False
);
201 TSXSetWMProtocols( display
, root_window
, &XA_WM_DELETE_WINDOW
, 1 );
202 TSXFree( size_hints
);
204 TSXFree( class_hints
);
208 TSXMapWindow( display
, root_window
);
211 /* Created so that XOpenIM can be called using the 'large stack' */
212 static void XOpenIM_large_stack(void)
214 TSXOpenIM(display
,NULL
,NULL
,NULL
);
217 /***********************************************************************
218 * X11DRV process initialisation routine
220 static void process_attach(void)
222 USER_Driver
= &user_driver
;
223 CLIPBOARD_Driver
= &X11DRV_CLIPBOARD_Driver
;
224 WND_Driver
= &X11DRV_WND_Driver
;
230 if (!(display
= TSXOpenDisplay( Options
.display
)))
232 MESSAGE( "%s: Can't open display: %s\n", argv0
, Options
.display
);
235 fcntl( ConnectionNumber(display
), F_SETFD
, 1 ); /* set close on exec flag */
236 screen
= DefaultScreenOfDisplay( display
);
237 visual
= DefaultVisual( display
, DefaultScreen(display
) );
238 root_window
= DefaultRootWindow( display
);
240 /* Initialize screen depth */
242 screen_depth
= PROFILE_GetWineIniInt( "x11drv", "ScreenDepth", 0 );
243 if (screen_depth
) /* depth specified */
246 int *depth_list
= TSXListDepths(display
, DefaultScreen(display
), &depth_count
);
247 for (i
= 0; i
< depth_count
; i
++)
248 if (depth_list
[i
] == screen_depth
) break;
249 TSXFree( depth_list
);
250 if (i
>= depth_count
)
252 MESSAGE( "%s: Depth %d not supported on this screen.\n", argv0
, screen_depth
);
256 else screen_depth
= DefaultDepthOfScreen( screen
);
258 /* tell the libX11 that we will do input method handling ourselves
259 * that keep libX11 from doing anything whith dead keys, allowing Wine
260 * to have total control over dead keys, that is this line allows
261 * them to work in Wine, even whith a libX11 including the dead key
262 * patches from Th.Quinot (http://Web.FdN.FR/~tquinot/dead-keys.en.html)
264 CALL_LARGE_STACK( XOpenIM_large_stack
, NULL
);
266 if (Options
.synchronous
) XSetErrorHandler( error_handler
);
268 MONITOR_PrimaryMonitor
.rect
.left
= 0;
269 MONITOR_PrimaryMonitor
.rect
.top
= 0;
270 MONITOR_PrimaryMonitor
.rect
.right
= WidthOfScreen( screen
);
271 MONITOR_PrimaryMonitor
.rect
.bottom
= HeightOfScreen( screen
);
272 MONITOR_PrimaryMonitor
.depth
= screen_depth
;
274 if (Options
.desktopGeometry
)
276 Options
.managed
= FALSE
;
277 create_desktop( Options
.desktopGeometry
);
281 X11DRV_GDI_Initialize();
283 /* save keyboard setup */
284 TSXGetKeyboardControl(display
, &keyboard_state
);
286 /* initialize event handling */
291 /***********************************************************************
292 * X11DRV process termination routine
294 static void process_detach(void)
296 /* restore keyboard setup */
297 XKeyboardControl keyboard_value
;
299 keyboard_value
.key_click_percent
= keyboard_state
.key_click_percent
;
300 keyboard_value
.bell_percent
= keyboard_state
.bell_percent
;
301 keyboard_value
.bell_pitch
= keyboard_state
.bell_pitch
;
302 keyboard_value
.bell_duration
= keyboard_state
.bell_duration
;
303 keyboard_value
.auto_repeat_mode
= keyboard_state
.global_auto_repeat
;
305 XChangeKeyboardControl(display
, KBKeyClickPercent
| KBBellPercent
|
306 KBBellPitch
| KBBellDuration
| KBAutoRepeatMode
, &keyboard_value
);
309 X11DRV_GDI_Finalize();
313 /* close the display */
314 XCloseDisplay( display
);
318 CLIPBOARD_Driver
= NULL
;
324 /***********************************************************************
325 * X11DRV initialisation routine
327 BOOL WINAPI
X11DRV_Init( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
329 static int process_count
;
333 case DLL_PROCESS_ATTACH
:
334 if (!process_count
++) process_attach();
336 case DLL_PROCESS_DETACH
:
337 if (!--process_count
) process_detach();
343 /***********************************************************************
344 * X11DRV_GetScreenSaveActive
346 * Returns the active status of the screen saver
348 BOOL
X11DRV_GetScreenSaveActive(void)
351 TSXGetScreenSaver(display
, &timeout
, &temp
, &temp
, &temp
);
355 /***********************************************************************
356 * X11DRV_SetScreenSaveActive
358 * Activate/Deactivate the screen saver
360 void X11DRV_SetScreenSaveActive(BOOL bActivate
)
363 TSXActivateScreenSaver(display
);
365 TSXResetScreenSaver(display
);
368 /***********************************************************************
369 * X11DRV_GetScreenSaveTimeout
371 * Return the screen saver timeout
373 int X11DRV_GetScreenSaveTimeout(void)
376 TSXGetScreenSaver(display
, &timeout
, &temp
, &temp
, &temp
);
380 /***********************************************************************
381 * X11DRV_SetScreenSaveTimeout
383 * Set the screen saver timeout
385 void X11DRV_SetScreenSaveTimeout(int nTimeout
)
387 TSXSetScreenSaver(display
, nTimeout
, 60, DefaultBlanking
, DefaultExposures
);
390 /***********************************************************************
391 * X11DRV_IsSingleWindow
393 BOOL
X11DRV_IsSingleWindow(void)
395 return (root_window
!= DefaultRootWindow(display
));