A few simplifications and optimizations in the x11 driver.
[wine] / dlls / x11drv / x11drv_main.c
1 /*
2  * X11DRV initialization code
3  *
4  * Copyright 1998 Patrik Stridvall
5  * Copyright 2000 Alexandre Julliard
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "ts_xlib.h"
11
12 #include "winbase.h"
13
14 #include "clipboard.h"
15 #include "debugtools.h"
16 #include "gdi.h"
17 #include "monitor.h"
18 #include "options.h"
19 #include "user.h"
20 #include "win.h"
21 #include "x11drv.h"
22
23
24 static USER_DRIVER user_driver =
25 {
26     /* event functions */
27     X11DRV_EVENT_Synchronize,
28     X11DRV_EVENT_CheckFocus,
29     X11DRV_EVENT_UserRepaintDisable,
30     /* keyboard functions */
31     X11DRV_KEYBOARD_Init,
32     X11DRV_KEYBOARD_VkKeyScan,
33     X11DRV_KEYBOARD_MapVirtualKey,
34     X11DRV_KEYBOARD_GetKeyNameText,
35     X11DRV_KEYBOARD_ToAscii,
36     X11DRV_KEYBOARD_GetBeepActive,
37     X11DRV_KEYBOARD_SetBeepActive,
38     X11DRV_KEYBOARD_Beep,
39     X11DRV_KEYBOARD_GetDIState,
40     X11DRV_KEYBOARD_GetDIData,
41     X11DRV_KEYBOARD_GetKeyboardConfig,
42     X11DRV_KEYBOARD_SetKeyboardConfig,
43     /* mouse functions */
44     X11DRV_MOUSE_Init,
45     X11DRV_MOUSE_SetCursor,
46     X11DRV_MOUSE_MoveCursor,
47     X11DRV_MOUSE_EnableWarpPointer
48 };
49
50 static XKeyboardState keyboard_state;
51
52 Display *display;
53 Screen *screen;
54 Visual *visual;
55 int screen_depth;
56 Window root_window;
57
58 /***********************************************************************
59  *              error_handler
60  */
61 static int error_handler(Display *display, XErrorEvent *error_evt)
62 {
63     DebugBreak();  /* force an entry in the debugger */
64     return 0;
65 }
66
67
68 /***********************************************************************
69  *           X11DRV process initialisation routine
70  */
71 static void process_attach(void)
72 {
73     USER_Driver      = &user_driver;
74     CLIPBOARD_Driver = &X11DRV_CLIPBOARD_Driver;
75     MONITOR_Driver   = &X11DRV_MONITOR_Driver;
76     WND_Driver       = &X11DRV_WND_Driver;
77
78     /* We need this before calling any Xlib function */
79     InitializeCriticalSection( &X11DRV_CritSection );
80     MakeCriticalSectionGlobal( &X11DRV_CritSection );
81   
82     putenv("XKB_DISABLE="); /* Disable XKB extension if present. */
83
84     /* Open display */
85   
86     if (!(display = TSXOpenDisplay( Options.display )))
87     {
88         MESSAGE( "%s: Can't open display: %s\n",
89                  argv0, Options.display ? Options.display : "(none specified)" );
90         ExitProcess(1);
91     }
92     screen = DefaultScreenOfDisplay( display );
93     visual = DefaultVisual( display, DefaultScreen(display) );
94     root_window = DefaultRootWindow( display );
95
96     /* Initialize screen depth */
97
98     screen_depth = PROFILE_GetWineIniInt( "x11drv", "ScreenDepth", 0 );
99     if (screen_depth)  /* depth specified */
100     {
101         int depth_count, i;
102         int *depth_list = TSXListDepths(display, DefaultScreen(display), &depth_count);
103         for (i = 0; i < depth_count; i++)
104             if (depth_list[i] == screen_depth) break;
105         TSXFree( depth_list );
106         if (i >= depth_count)
107         {
108             MESSAGE( "%s: Depth %d not supported on this screen.\n", argv0, screen_depth );
109             ExitProcess(1);
110         }
111     }
112     else screen_depth = DefaultDepthOfScreen( screen );
113
114     /* tell the libX11 that we will do input method handling ourselves
115      * that keep libX11 from doing anything whith dead keys, allowing Wine
116      * to have total control over dead keys, that is this line allows
117      * them to work in Wine, even whith a libX11 including the dead key
118      * patches from Th.Quinot (http://Web.FdN.FR/~tquinot/dead-keys.en.html)
119      */
120     TSXOpenIM(display,NULL,NULL,NULL);
121
122     if (Options.synchronous) XSetErrorHandler( error_handler );
123     if (Options.desktopGeometry && Options.managed) Options.managed = FALSE;
124
125     /* initialize monitor */
126     X11DRV_MONITOR_Initialize( &MONITOR_PrimaryMonitor );
127
128     /* initialize GDI */
129     X11DRV_GDI_Initialize();
130
131     /* save keyboard setup */
132     TSXGetKeyboardControl(display, &keyboard_state);
133
134     /* initialize event handling */
135     X11DRV_EVENT_Init();
136 }
137
138
139 /***********************************************************************
140  *           X11DRV process termination routine
141  */
142 static void process_detach(void)
143 {
144     /* restore keyboard setup */
145     XKeyboardControl keyboard_value;
146   
147     keyboard_value.key_click_percent = keyboard_state.key_click_percent;
148     keyboard_value.bell_percent      = keyboard_state.bell_percent;
149     keyboard_value.bell_pitch        = keyboard_state.bell_pitch;
150     keyboard_value.bell_duration     = keyboard_state.bell_duration;
151     keyboard_value.auto_repeat_mode  = keyboard_state.global_auto_repeat;
152   
153     XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent | 
154                            KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
155
156     /* cleanup GDI */
157     X11DRV_GDI_Finalize();
158
159 #if 0  /* FIXME */
160
161     /* cleanup monitor */
162     X11DRV_MONITOR_Finalize( &MONITOR_PrimaryMonitor );
163
164     /* close the display */
165     XCloseDisplay( display );
166     display = NULL;
167
168     USER_Driver      = NULL;
169     CLIPBOARD_Driver = NULL;
170     MONITOR_Driver   = NULL;
171     WND_Driver       = NULL;
172 #endif
173 }
174
175
176 /***********************************************************************
177  *           X11DRV initialisation routine
178  */
179 BOOL WINAPI X11DRV_Init( HINSTANCE hinst, DWORD reason, LPVOID reserved )
180 {
181     static int process_count;
182
183     switch(reason)
184     {
185     case DLL_PROCESS_ATTACH:
186         if (!process_count++) process_attach();
187         break;
188     case DLL_PROCESS_DETACH:
189         if (!--process_count) process_detach();
190         break;
191     }
192     return TRUE;
193 }