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"
29 DEFAULT_DEBUG_CHANNEL(x11drv
);
31 static USER_DRIVER user_driver
=
34 X11DRV_EVENT_Synchronize
,
35 X11DRV_EVENT_CheckFocus
,
36 X11DRV_EVENT_UserRepaintDisable
,
37 /* keyboard functions */
39 X11DRV_KEYBOARD_VkKeyScan
,
40 X11DRV_KEYBOARD_MapVirtualKey
,
41 X11DRV_KEYBOARD_GetKeyNameText
,
42 X11DRV_KEYBOARD_ToAscii
,
43 X11DRV_KEYBOARD_GetBeepActive
,
44 X11DRV_KEYBOARD_SetBeepActive
,
46 X11DRV_KEYBOARD_GetDIState
,
47 X11DRV_KEYBOARD_GetDIData
,
48 X11DRV_KEYBOARD_GetKeyboardConfig
,
49 X11DRV_KEYBOARD_SetKeyboardConfig
,
52 X11DRV_MOUSE_SetCursor
,
53 X11DRV_MOUSE_MoveCursor
,
54 X11DRV_MOUSE_EnableWarpPointer
,
55 /* screen saver functions */
56 X11DRV_GetScreenSaveActive
,
57 X11DRV_SetScreenSaveActive
,
58 X11DRV_GetScreenSaveTimeout
,
59 X11DRV_SetScreenSaveTimeout
,
60 /* windowing functions */
64 static XKeyboardState keyboard_state
;
72 /***********************************************************************
75 static int error_handler(Display
*display
, XErrorEvent
*error_evt
)
77 DebugBreak(); /* force an entry in the debugger */
82 /***********************************************************************
85 * Setup the x11drv options.
87 static void setup_options(void)
93 if (RegCreateKeyExA( HKEY_LOCAL_MACHINE
, "Software\\Wine\\Wine\\Config\\x11drv", 0, NULL
,
94 REG_OPTION_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &hkey
, NULL
))
96 ERR("Cannot create config registry key\n" );
100 /* --display option */
102 count
= sizeof(buffer
);
103 if (!RegQueryValueExA( hkey
, "display", 0, &type
, buffer
, &count
))
107 if (strcmp( buffer
, Options
.display
))
108 MESSAGE( "%s: warning: --display option ignored, using '%s'\n", argv0
, buffer
);
110 else if ((Options
.display
= getenv( "DISPLAY" )))
112 if (strcmp( buffer
, Options
.display
))
113 MESSAGE( "%s: warning: $DISPLAY variable ignored, using '%s'\n", argv0
, buffer
);
115 Options
.display
= strdup(buffer
);
119 if (!Options
.display
&& !(Options
.display
= getenv( "DISPLAY" )))
121 MESSAGE( "%s: no display specified\n", argv0
);
124 RegSetValueExA( hkey
, "display", 0, REG_SZ
, Options
.display
, strlen(Options
.display
)+1 );
127 /* --managed option */
129 if (!Options
.managed
)
131 count
= sizeof(buffer
);
132 if (!RegQueryValueExA( hkey
, "managed", 0, &type
, buffer
, &count
))
133 Options
.managed
= IS_OPTION_TRUE( buffer
[0] );
135 else RegSetValueExA( hkey
, "managed", 0, REG_SZ
, "y", 2 );
141 /***********************************************************************
144 * Create the desktop window for the --desktop mode.
146 static void create_desktop( const char *geometry
)
148 int x
= 0, y
= 0, flags
;
149 unsigned int width
= 640, height
= 480; /* Default size = 640x480 */
150 char *name
= "Wine desktop";
151 XSizeHints
*size_hints
;
153 XClassHint
*class_hints
;
154 XSetWindowAttributes win_attr
;
155 XTextProperty window_name
;
156 Atom XA_WM_DELETE_WINDOW
;
157 /* Used to create the desktop window with a good visual */
158 XVisualInfo
*vi
= NULL
;
162 /* Get in wine.ini if the desktop window should have a double-buffered visual or not */
163 dblbuf_visual
= PROFILE_GetWineIniBool( "x11drv", "DesktopDoubleBuffered", 0 );
165 int dblBuf
[]={GLX_RGBA
,GLX_DEPTH_SIZE
,16,GLX_DOUBLEBUFFER
,None
};
168 vi
= glXChooseVisual(display
, DefaultScreen(display
), dblBuf
);
169 win_attr
.colormap
= XCreateColormap(display
, RootWindow(display
,vi
->screen
),
170 vi
->visual
, AllocNone
);
173 #endif /* HAVE_OPENGL */
175 flags
= TSXParseGeometry( geometry
, &x
, &y
, &width
, &height
);
176 MONITOR_PrimaryMonitor
.rect
.right
= width
;
177 MONITOR_PrimaryMonitor
.rect
.bottom
= height
;
180 win_attr
.background_pixel
= BlackPixel(display
, 0);
181 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
182 PointerMotionMask
| ButtonPressMask
|
183 ButtonReleaseMask
| EnterWindowMask
;
184 win_attr
.cursor
= TSXCreateFontCursor( display
, XC_top_left_arrow
);
188 screen
= ScreenOfDisplay(display
, vi
->screen
);
189 screen_depth
= vi
->depth
;
191 root_window
= TSXCreateWindow( display
,
192 (vi
== NULL
? DefaultRootWindow(display
) : RootWindow(display
, vi
->screen
)),
193 x
, y
, width
, height
, 0,
194 (vi
== NULL
? CopyFromParent
: vi
->depth
),
196 (vi
== NULL
? CopyFromParent
: vi
->visual
),
197 CWBackPixel
| CWEventMask
| CWCursor
| (vi
== NULL
? 0 : CWColormap
),
200 /* Set window manager properties */
201 size_hints
= TSXAllocSizeHints();
202 wm_hints
= TSXAllocWMHints();
203 class_hints
= TSXAllocClassHint();
204 if (!size_hints
|| !wm_hints
|| !class_hints
)
206 MESSAGE("Not enough memory for window manager hints.\n" );
209 size_hints
->min_width
= size_hints
->max_width
= width
;
210 size_hints
->min_height
= size_hints
->max_height
= height
;
211 size_hints
->flags
= PMinSize
| PMaxSize
;
212 if (flags
& (XValue
| YValue
)) size_hints
->flags
|= USPosition
;
213 if (flags
& (WidthValue
| HeightValue
)) size_hints
->flags
|= USSize
;
214 else size_hints
->flags
|= PSize
;
216 wm_hints
->flags
= InputHint
| StateHint
;
217 wm_hints
->input
= True
;
218 wm_hints
->initial_state
= NormalState
;
219 class_hints
->res_name
= (char *)argv0
;
220 class_hints
->res_class
= "Wine";
222 TSXStringListToTextProperty( &name
, 1, &window_name
);
223 TSXSetWMProperties( display
, root_window
, &window_name
, &window_name
,
224 NULL
, 0, size_hints
, wm_hints
, class_hints
);
225 XA_WM_DELETE_WINDOW
= TSXInternAtom( display
, "WM_DELETE_WINDOW", False
);
226 TSXSetWMProtocols( display
, root_window
, &XA_WM_DELETE_WINDOW
, 1 );
227 TSXFree( size_hints
);
229 TSXFree( class_hints
);
232 TSXMapWindow( display
, root_window
);
235 /* Created so that XOpenIM can be called using the 'large stack' */
236 static void XOpenIM_large_stack(void)
238 TSXOpenIM(display
,NULL
,NULL
,NULL
);
241 /***********************************************************************
242 * X11DRV process initialisation routine
244 static void process_attach(void)
246 USER_Driver
= &user_driver
;
247 CLIPBOARD_Driver
= &X11DRV_CLIPBOARD_Driver
;
248 WND_Driver
= &X11DRV_WND_Driver
;
254 if (!(display
= TSXOpenDisplay( Options
.display
)))
256 MESSAGE( "%s: Can't open display: %s\n", argv0
, Options
.display
);
259 fcntl( ConnectionNumber(display
), F_SETFD
, 1 ); /* set close on exec flag */
260 screen
= DefaultScreenOfDisplay( display
);
261 visual
= DefaultVisual( display
, DefaultScreen(display
) );
262 root_window
= DefaultRootWindow( display
);
264 /* Initialize screen depth */
266 screen_depth
= PROFILE_GetWineIniInt( "x11drv", "ScreenDepth", 0 );
267 if (screen_depth
) /* depth specified */
270 int *depth_list
= TSXListDepths(display
, DefaultScreen(display
), &depth_count
);
271 for (i
= 0; i
< depth_count
; i
++)
272 if (depth_list
[i
] == screen_depth
) break;
273 TSXFree( depth_list
);
274 if (i
>= depth_count
)
276 MESSAGE( "%s: Depth %d not supported on this screen.\n", argv0
, screen_depth
);
280 else screen_depth
= DefaultDepthOfScreen( screen
);
282 /* tell the libX11 that we will do input method handling ourselves
283 * that keep libX11 from doing anything whith dead keys, allowing Wine
284 * to have total control over dead keys, that is this line allows
285 * them to work in Wine, even whith a libX11 including the dead key
286 * patches from Th.Quinot (http://Web.FdN.FR/~tquinot/dead-keys.en.html)
288 CALL_LARGE_STACK( XOpenIM_large_stack
, NULL
);
290 if (Options
.synchronous
) XSetErrorHandler( error_handler
);
292 MONITOR_PrimaryMonitor
.rect
.left
= 0;
293 MONITOR_PrimaryMonitor
.rect
.top
= 0;
294 MONITOR_PrimaryMonitor
.rect
.right
= WidthOfScreen( screen
);
295 MONITOR_PrimaryMonitor
.rect
.bottom
= HeightOfScreen( screen
);
296 MONITOR_PrimaryMonitor
.depth
= screen_depth
;
298 if (Options
.desktopGeometry
)
300 Options
.managed
= FALSE
;
301 create_desktop( Options
.desktopGeometry
);
305 X11DRV_GDI_Initialize();
307 /* save keyboard setup */
308 TSXGetKeyboardControl(display
, &keyboard_state
);
310 /* initialize event handling */
315 /***********************************************************************
316 * X11DRV process termination routine
318 static void process_detach(void)
320 /* restore keyboard setup */
321 XKeyboardControl keyboard_value
;
323 keyboard_value
.key_click_percent
= keyboard_state
.key_click_percent
;
324 keyboard_value
.bell_percent
= keyboard_state
.bell_percent
;
325 keyboard_value
.bell_pitch
= keyboard_state
.bell_pitch
;
326 keyboard_value
.bell_duration
= keyboard_state
.bell_duration
;
327 keyboard_value
.auto_repeat_mode
= keyboard_state
.global_auto_repeat
;
329 XChangeKeyboardControl(display
, KBKeyClickPercent
| KBBellPercent
|
330 KBBellPitch
| KBBellDuration
| KBAutoRepeatMode
, &keyboard_value
);
333 X11DRV_GDI_Finalize();
337 /* close the display */
338 XCloseDisplay( display
);
342 CLIPBOARD_Driver
= NULL
;
348 /***********************************************************************
349 * X11DRV initialisation routine
351 BOOL WINAPI
X11DRV_Init( HINSTANCE hinst
, DWORD reason
, LPVOID reserved
)
353 static int process_count
;
357 case DLL_PROCESS_ATTACH
:
358 if (!process_count
++) process_attach();
360 case DLL_PROCESS_DETACH
:
361 if (!--process_count
) process_detach();
367 /***********************************************************************
368 * X11DRV_GetScreenSaveActive
370 * Returns the active status of the screen saver
372 BOOL
X11DRV_GetScreenSaveActive(void)
375 TSXGetScreenSaver(display
, &timeout
, &temp
, &temp
, &temp
);
379 /***********************************************************************
380 * X11DRV_SetScreenSaveActive
382 * Activate/Deactivate the screen saver
384 void X11DRV_SetScreenSaveActive(BOOL bActivate
)
387 TSXActivateScreenSaver(display
);
389 TSXResetScreenSaver(display
);
392 /***********************************************************************
393 * X11DRV_GetScreenSaveTimeout
395 * Return the screen saver timeout
397 int X11DRV_GetScreenSaveTimeout(void)
400 TSXGetScreenSaver(display
, &timeout
, &temp
, &temp
, &temp
);
404 /***********************************************************************
405 * X11DRV_SetScreenSaveTimeout
407 * Set the screen saver timeout
409 void X11DRV_SetScreenSaveTimeout(int nTimeout
)
411 TSXSetScreenSaver(display
, nTimeout
, 60, DefaultBlanking
, DefaultExposures
);
414 /***********************************************************************
415 * X11DRV_IsSingleWindow
417 BOOL
X11DRV_IsSingleWindow(void)
419 return (root_window
!= DefaultRootWindow(display
));