Added extra US keymap with the infamous phantom key.
[wine] / windows / x11drv / main.c
1 /*
2  * X11 main driver
3  *
4  * Copyright 1998 Patrik Stridvall
5  *
6  */
7
8 #include "config.h"
9
10 #ifndef X_DISPLAY_MISSING
11
12 #include <X11/Xlocale.h>
13 #include "ts_xlib.h"
14 #include "ts_xresource.h"
15 #include "ts_xutil.h"
16
17 #include <signal.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #include "clipboard.h"
23 #include "console.h"
24 #include "debugtools.h"
25 #include "desktop.h"
26 #include "keyboard.h"
27 #include "main.h"
28 #include "message.h"
29 #include "monitor.h"
30 #include "mouse.h"
31 #include "options.h"
32 #include "win.h"
33 #include "windef.h"
34 #include "x11drv.h"
35 #include "xmalloc.h"
36 #include "version.h"
37
38 /**********************************************************************/
39
40 void X11DRV_USER_ParseOptions(int *argc, char *argv[]);
41 void X11DRV_USER_Create(void);
42 void X11DRV_USER_SaveSetup(void);
43 void X11DRV_USER_RestoreSetup(void);
44
45 /**********************************************************************/
46
47 #define WINE_CLASS        "Wine"    /* Class name for resources */
48 #define WINE_APP_DEFAULTS "/usr/lib/X11/app-defaults/Wine"
49
50 static XrmOptionDescRec optionsTable[] =
51 {
52     { "-backingstore",  ".backingstore",    XrmoptionNoArg,  (caddr_t)"on" },
53     { "-desktop",       ".desktop",         XrmoptionSepArg, (caddr_t)NULL },
54     { "-depth",         ".depth",           XrmoptionSepArg, (caddr_t)NULL },
55     { "-display",       ".display",         XrmoptionSepArg, (caddr_t)NULL },
56     { "-iconic",        ".iconic",          XrmoptionNoArg,  (caddr_t)"on" },
57     { "-language",      ".language",        XrmoptionSepArg, (caddr_t)"En" },
58     { "-name",          ".name",            XrmoptionSepArg, (caddr_t)NULL },
59     { "-perfect",       ".perfect",         XrmoptionNoArg,  (caddr_t)"on" },
60     { "-privatemap",    ".privatemap",      XrmoptionNoArg,  (caddr_t)"on" },
61     { "-fixedmap",      ".fixedmap",        XrmoptionNoArg,  (caddr_t)"on" },
62     { "-synchronous",   ".synchronous",     XrmoptionNoArg,  (caddr_t)"on" },
63     { "-debug",         ".debug",           XrmoptionNoArg,  (caddr_t)"on" },
64     { "-debugmsg",      ".debugmsg",        XrmoptionSepArg, (caddr_t)NULL },
65     { "-dll",           ".dll",             XrmoptionSepArg, (caddr_t)NULL },
66     { "-failreadonly",  ".failreadonly",    XrmoptionNoArg,  (caddr_t)"on" },
67     { "-mode",          ".mode",            XrmoptionSepArg, (caddr_t)NULL },
68     { "-managed",       ".managed",         XrmoptionNoArg,  (caddr_t)"off"},
69     { "-winver",        ".winver",          XrmoptionSepArg, (caddr_t)NULL },
70     { "-config",        ".config",          XrmoptionSepArg, (caddr_t)NULL },
71     { "-nodga",         ".nodga",           XrmoptionNoArg,  (caddr_t)"off"},
72     { "-noxshm",        ".noxshm",          XrmoptionNoArg,  (caddr_t)"off"},
73     { "-console",       ".console",         XrmoptionSepArg, (caddr_t)NULL },
74     { "-dosver",        ".dosver",          XrmoptionSepArg, (caddr_t)NULL }
75 };
76
77 #define NB_OPTIONS  (sizeof(optionsTable) / sizeof(optionsTable[0]))
78
79 /**********************************************************************/
80
81 static XKeyboardState X11DRV_XKeyboardState;
82 Display *display;
83
84 /***********************************************************************
85  *              X11DRV_GetXScreen
86  *
87  * Return the X screen associated to the current desktop.
88  */
89 Screen *X11DRV_GetXScreen()
90 {
91   return X11DRV_MONITOR_GetXScreen(&MONITOR_PrimaryMonitor);
92 }
93
94 /***********************************************************************
95  *              X11DRV_GetXRootWindow
96  *
97  * Return the X display associated to the current desktop.
98  */
99 Window X11DRV_GetXRootWindow()
100 {
101   return X11DRV_MONITOR_GetXRootWindow(&MONITOR_PrimaryMonitor);
102 }
103
104 /***********************************************************************
105  *              X11DRV_USER_Initialize
106  */
107 BOOL X11DRV_USER_Initialize(void)
108 {
109   CLIPBOARD_Driver = &X11DRV_CLIPBOARD_Driver;
110   DESKTOP_Driver = &X11DRV_DESKTOP_Driver;
111   EVENT_Driver = &X11DRV_EVENT_Driver;
112   KEYBOARD_Driver = &X11DRV_KEYBOARD_Driver;
113   MONITOR_Driver = &X11DRV_MONITOR_Driver;
114   MOUSE_Driver = &X11DRV_MOUSE_Driver;
115   WND_Driver = &X11DRV_WND_Driver;
116
117   /* We need this before calling any Xlib function */
118   InitializeCriticalSection( &X11DRV_CritSection );
119   MakeCriticalSectionGlobal( &X11DRV_CritSection );
120   
121   TSXrmInitialize();
122   
123   putenv("XKB_DISABLE="); /* Disable XKB extension if present. */
124
125   X11DRV_USER_ParseOptions( Options.argc, Options.argv );
126   X11DRV_USER_Create();
127   X11DRV_USER_SaveSetup();
128
129   return TRUE;
130 }
131
132 /***********************************************************************
133  *              X11DRV_USER_Finalize
134  */
135 void X11DRV_USER_Finalize(void)
136 {
137   X11DRV_USER_RestoreSetup();
138 }
139
140 /**************************************************************************
141  *              X11DRV_USER_BeginDebugging
142  */
143 void X11DRV_USER_BeginDebugging(void)
144 {
145   TSXUngrabServer(display);
146   TSXFlush(display);
147 }
148
149 /**************************************************************************
150  *              X11DRV_USER_EndDebugging
151  */
152 void X11DRV_USER_EndDebugging(void)
153 {
154 }
155
156 /***********************************************************************
157  *               X11DRV_USER_GetResource
158  *
159  * Fetch the value of resource 'name' using the correct instance name.
160  * 'name' must begin with '.' or '*'
161  */
162 static int X11DRV_USER_GetResource( XrmDatabase db, char *name, XrmValue *value )
163 {
164   char *buff_instance, *buff_class;
165   char *dummy;
166   int retval;
167   
168   buff_instance = (char *)xmalloc(strlen(Options.programName)+strlen(name)+1);
169   buff_class    = (char *)xmalloc( strlen(WINE_CLASS) + strlen(name) + 1 );
170     
171   strcpy( buff_instance, Options.programName );
172   strcat( buff_instance, name );
173   strcpy( buff_class, WINE_CLASS );
174   strcat( buff_class, name );
175   retval = TSXrmGetResource( db, buff_instance, buff_class, &dummy, value );
176   free( buff_instance );
177   free( buff_class );
178   return retval;
179 }
180
181 /***********************************************************************
182  *              X11DRV_USER_ParseOptions
183  * Parse command line options and open display.
184  */
185 void X11DRV_USER_ParseOptions(int *argc, char *argv[])
186 {
187   int i;
188   char *display_name = NULL;
189   XrmValue value;
190   XrmDatabase db = TSXrmGetFileDatabase(WINE_APP_DEFAULTS);
191   char *xrm_string;
192
193   /* Get display name from command line */
194   for (i = 1; i < *argc; i++)
195     {
196       if (!strcmp( argv[i], "-display" )) display_name = argv[i+1];
197     }
198
199   /* Open display */
200   
201   if (display_name == NULL &&
202       X11DRV_USER_GetResource( db, ".display", &value )) display_name = value.addr;
203   
204   if (!(display = TSXOpenDisplay( display_name )))
205     {
206       MESSAGE( "%s: Can't open display: %s\n",
207            argv[0], display_name ? display_name : "(none specified)" );
208       exit(1);
209     }
210   
211   /* tell the libX11 that we will do input method handling ourselves
212    * that keep libX11 from doing anything whith dead keys, allowing Wine
213    * to have total control over dead keys, that is this line allows
214    * them to work in Wine, even whith a libX11 including the dead key
215    * patches from Th.Quinot (http://Web.FdN.FR/~tquinot/dead-keys.en.html)
216    */
217   TSXOpenIM(display,NULL,NULL,NULL);
218   
219   /* Merge file and screen databases */
220   if ((xrm_string = TSXResourceManagerString( display )) != NULL)
221     {
222       XrmDatabase display_db = TSXrmGetStringDatabase( xrm_string );
223       TSXrmMergeDatabases( display_db, &db );
224     }
225   
226   /* Parse command line */
227   TSXrmParseCommand( &db, optionsTable, NB_OPTIONS,
228                      Options.programName, argc, argv );
229   
230   /* Get all options */
231   if (X11DRV_USER_GetResource( db, ".iconic", &value ))
232     Options.cmdShow = SW_SHOWMINIMIZED;
233   if (X11DRV_USER_GetResource( db, ".privatemap", &value ))
234     Options.usePrivateMap = TRUE;
235   if (X11DRV_USER_GetResource( db, ".fixedmap", &value ))
236     Options.useFixedMap = TRUE;
237   if (X11DRV_USER_GetResource( db, ".synchronous", &value ))
238     Options.synchronous = TRUE;
239   if (X11DRV_USER_GetResource( db, ".backingstore", &value ))
240     Options.backingstore = TRUE;        
241   if (X11DRV_USER_GetResource( db, ".debug", &value ))
242     Options.debug = TRUE;
243   if (X11DRV_USER_GetResource( db, ".failreadonly", &value ))
244     Options.failReadOnly = TRUE;
245   if (X11DRV_USER_GetResource( db, ".perfect", &value ))
246     Options.perfectGraphics = TRUE;
247   if (X11DRV_USER_GetResource( db, ".depth", &value))
248     Options.screenDepth = atoi( value.addr );
249   if (X11DRV_USER_GetResource( db, ".desktop", &value))
250     Options.desktopGeometry = value.addr;
251   if (X11DRV_USER_GetResource( db, ".language", &value))
252     MAIN_ParseLanguageOption( (char *)value.addr );
253   if (X11DRV_USER_GetResource( db, ".managed", &value))
254     Options.managed = TRUE;
255   if (X11DRV_USER_GetResource( db, ".mode", &value))
256     MAIN_ParseModeOption( (char *)value.addr );
257   if (X11DRV_USER_GetResource( db, ".debugoptions", &value))
258     MAIN_ParseDebugOptions((char*)value.addr);
259   if (X11DRV_USER_GetResource( db, ".debugmsg", &value))
260     {
261 #ifndef DEBUG_RUNTIME
262       MESSAGE("%s: Option \"-debugmsg\" not implemented.\n" \
263           "    Recompile with DEBUG_RUNTIME in include/debugtools.h defined.\n",
264           argv[0]);
265       exit(1);
266 #else
267       MAIN_ParseDebugOptions((char*)value.addr);
268 #endif
269     }
270   
271   if (X11DRV_USER_GetResource( db, ".dll", &value))
272   {
273       if (Options.dllFlags)
274       {
275           /* don't overwrite previous value. Should we
276            * automatically add the ',' between multiple DLLs ?
277            */
278           MESSAGE("Only one -dll flag is allowed. Use ',' between multiple DLLs\n");
279       }
280       else Options.dllFlags = xstrdup((char *)value.addr);
281   }
282   
283   if (X11DRV_USER_GetResource( db, ".winver", &value))
284     VERSION_ParseWinVersion( (char*)value.addr );
285   if (X11DRV_USER_GetResource( db, ".dosver", &value))
286     VERSION_ParseDosVersion( (char*)value.addr );
287   if (X11DRV_USER_GetResource( db, ".config", &value))
288     Options.configFileName = xstrdup((char *)value.addr);
289   if (X11DRV_USER_GetResource( db, ".nodga", &value))
290     Options.noDGA = TRUE;
291   if (X11DRV_USER_GetResource( db, ".noxshm", &value))
292     Options.noXSHM = TRUE;
293   if (X11DRV_USER_GetResource( db, ".console", &value))
294       driver.driver_list = xstrdup((char *)value.addr);
295   else
296       driver.driver_list = CONSOLE_DEFAULT_DRIVER;
297 }
298
299 /***********************************************************************
300  *              X11DRV_USER_ErrorHandler
301  */
302 static int X11DRV_USER_ErrorHandler(Display *display, XErrorEvent *error_evt)
303 {
304     DebugBreak();  /* force an entry in the debugger */
305     return 0;
306 }
307
308 /***********************************************************************
309  *              X11DRV_USER_Create
310  */
311 void X11DRV_USER_Create()
312 {
313   if (Options.synchronous) XSetErrorHandler( X11DRV_USER_ErrorHandler );
314   
315   if (Options.desktopGeometry && Options.managed)
316     {
317 #if 0
318       MESSAGE( "%s: -managed and -desktop options cannot be used together\n",
319            Options.programName );
320       exit(1);
321 #else
322       Options.managed = FALSE;
323 #endif
324     }
325 }
326
327 /***********************************************************************
328  *           X11DRV_USER_SaveSetup
329  */
330 void X11DRV_USER_SaveSetup()
331 {
332   TSXGetKeyboardControl(display, &X11DRV_XKeyboardState);
333 }
334
335 /***********************************************************************
336  *           X11DRV_USER_RestoreSetup
337  */
338 void X11DRV_USER_RestoreSetup()
339 {
340   XKeyboardControl keyboard_value;
341   
342   keyboard_value.key_click_percent      = X11DRV_XKeyboardState.key_click_percent;
343   keyboard_value.bell_percent   = X11DRV_XKeyboardState.bell_percent;
344   keyboard_value.bell_pitch             = X11DRV_XKeyboardState.bell_pitch;
345   keyboard_value.bell_duration  = X11DRV_XKeyboardState.bell_duration;
346   keyboard_value.auto_repeat_mode       = X11DRV_XKeyboardState.global_auto_repeat;
347   
348   XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent | 
349                          KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
350 }
351
352 #endif /* X_DISPLAY_MISSING */