Fixed WIN_SendDestroyMsg.
[wine] / windows / x11drv / monitor.c
1 /*
2  * X11 monitor driver
3  *
4  * Copyright 1998 Patrik Stridvall
5  *
6  */
7
8 #include "config.h"
9
10 #ifndef X_DISPLAY_MISSING
11
12 #include <stdlib.h>
13 #include <X11/cursorfont.h>
14 #include "ts_xlib.h"
15 #include "ts_xutil.h"
16
17 #include "debug.h"
18 #include "heap.h"
19 #include "monitor.h"
20 #include "options.h"
21 #include "windef.h"
22 #include "x11drv.h"
23
24 /**********************************************************************/
25
26 extern Display *display;
27
28 /***********************************************************************
29  *              X11DRV_MONITOR_GetXScreen
30  *
31  * Return the X screen associated to the MONITOR.
32  */
33 Screen *X11DRV_MONITOR_GetXScreen(MONITOR *pMonitor)
34 {
35   X11DRV_MONITOR_DATA *pX11Monitor =
36     (X11DRV_MONITOR_DATA *) pMonitor->pDriverData;
37
38   return pX11Monitor->screen;
39 }
40
41 /***********************************************************************
42  *              X11DRV_MONITOR_GetXRootWindow
43  *
44  * Return the X screen associated to the MONITOR.
45  */
46 Window X11DRV_MONITOR_GetXRootWindow(MONITOR *pMonitor)
47 {
48   X11DRV_MONITOR_DATA *pX11Monitor =
49     (X11DRV_MONITOR_DATA *) pMonitor->pDriverData;
50
51   return pX11Monitor->rootWindow;
52 }
53
54 /***********************************************************************
55  *              X11DRV_MONITOR_CreateDesktop
56  * FIXME 
57  *   The desktop should create created in X11DRV_DESKTOP_Initialize
58  *   instead but it can't be yet because some code depends on that
59  *   the desktop always exists.
60  *
61  */
62 static void X11DRV_MONITOR_CreateDesktop(MONITOR *pMonitor)
63 {
64   X11DRV_MONITOR_DATA *pX11Monitor =
65     (X11DRV_MONITOR_DATA *) pMonitor->pDriverData;
66
67   int x, y, flags;
68   unsigned int width = 640, height = 480;  /* Default size = 640x480 */
69   char *name = "Wine desktop";
70   XSizeHints *size_hints;
71   XWMHints   *wm_hints;
72   XClassHint *class_hints;
73   XSetWindowAttributes win_attr;
74   XTextProperty window_name;
75   Atom XA_WM_DELETE_WINDOW;
76
77   flags = TSXParseGeometry( Options.desktopGeometry, &x, &y, &width, &height );
78   pX11Monitor->width  = width;
79   pX11Monitor->height = height;
80
81   /* Create window */
82   
83   win_attr.background_pixel = BlackPixel(display, 0);
84   win_attr.event_mask = 
85     ExposureMask | KeyPressMask | KeyReleaseMask |
86     PointerMotionMask | ButtonPressMask |
87     ButtonReleaseMask | EnterWindowMask;
88   win_attr.cursor = TSXCreateFontCursor( display, XC_top_left_arrow );
89
90   pX11Monitor->rootWindow =
91     TSXCreateWindow( display, 
92                      DefaultRootWindow(display),
93                      x, y, width, height, 0,
94                      CopyFromParent, InputOutput, CopyFromParent,
95                      CWBackPixel | CWEventMask | CWCursor, &win_attr);
96   
97   /* Set window manager properties */
98
99   size_hints  = TSXAllocSizeHints();
100   wm_hints    = TSXAllocWMHints();
101   class_hints = TSXAllocClassHint();
102   if (!size_hints || !wm_hints || !class_hints)
103     {
104       MSG("Not enough memory for window manager hints.\n" );
105       exit(1);
106     }
107   size_hints->min_width = size_hints->max_width = width;
108   size_hints->min_height = size_hints->max_height = height;
109   size_hints->flags = PMinSize | PMaxSize;
110   if (flags & (XValue | YValue)) size_hints->flags |= USPosition;
111   if (flags & (WidthValue | HeightValue)) size_hints->flags |= USSize;
112   else size_hints->flags |= PSize;
113
114   wm_hints->flags = InputHint | StateHint;
115   wm_hints->input = True;
116   wm_hints->initial_state = NormalState;
117   class_hints->res_name = Options.argv[0]; /* FIXME: Options.argv0 insteed? */
118   class_hints->res_class = "Wine";
119
120   TSXStringListToTextProperty( &name, 1, &window_name );
121   TSXSetWMProperties( display, pX11Monitor->rootWindow, &window_name, &window_name,
122                       Options.argv, *Options.argc, size_hints, wm_hints, class_hints );
123   XA_WM_DELETE_WINDOW = TSXInternAtom( display, "WM_DELETE_WINDOW", False );
124   TSXSetWMProtocols( display, pX11Monitor->rootWindow, &XA_WM_DELETE_WINDOW, 1 );
125   TSXFree( size_hints );
126   TSXFree( wm_hints );
127   TSXFree( class_hints );
128
129   /* Map window */
130
131   TSXMapWindow( display, pX11Monitor->rootWindow );
132 }
133
134 /***********************************************************************
135  *              X11DRV_MONITOR_Initialize
136  */
137 void X11DRV_MONITOR_Initialize(MONITOR *pMonitor)
138 {
139   X11DRV_MONITOR_DATA *pX11Monitor = (X11DRV_MONITOR_DATA *) 
140     HeapAlloc(SystemHeap, 0, sizeof(X11DRV_MONITOR_DATA));
141
142   int depth_count, i;
143   int *depth_list;
144
145   pMonitor->pDriverData = pX11Monitor;
146
147   pX11Monitor->screen  = DefaultScreenOfDisplay( display );
148
149   pX11Monitor->width   = WidthOfScreen( pX11Monitor->screen );
150   pX11Monitor->height  = HeightOfScreen( pX11Monitor->screen );
151
152   pX11Monitor->depth   = Options.screenDepth;
153   if (pX11Monitor->depth)  /* -depth option specified */
154     {
155       depth_list = TSXListDepths(display, DefaultScreen(display), &depth_count);
156       for (i = 0; i < depth_count; i++)
157         if (depth_list[i] == pX11Monitor->depth) break;
158       TSXFree( depth_list );
159       if (i >= depth_count)
160         {
161           MSG( "%s: Depth %d not supported on this screen.\n",
162                Options.programName, pX11Monitor->depth );
163           exit(1);
164         }
165     }
166   else
167     pX11Monitor->depth  = DefaultDepthOfScreen( pX11Monitor->screen );
168
169   if (Options.synchronous) TSXSynchronize( display, True );
170
171   if (Options.desktopGeometry)
172     X11DRV_MONITOR_CreateDesktop(pMonitor);
173   else 
174     pX11Monitor->rootWindow =
175       DefaultRootWindow( display );
176 }
177
178 /***********************************************************************
179  *              X11DRV_MONITOR_Finalize
180  */
181 void X11DRV_MONITOR_Finalize(MONITOR *pMonitor)
182 {
183   HeapFree(SystemHeap, 0, pMonitor->pDriverData);
184 }
185
186 /***********************************************************************
187  *              X11DRV_MONITOR_GetWidth
188  *
189  * Return the width of the monitor
190  */
191 int X11DRV_MONITOR_GetWidth(MONITOR *pMonitor)
192 {
193   X11DRV_MONITOR_DATA *pX11Monitor =
194     (X11DRV_MONITOR_DATA *) pMonitor->pDriverData;
195
196   return pX11Monitor->width;
197 }
198
199 /***********************************************************************
200  *              X11DRV_MONITOR_GetHeight
201  *
202  * Return the height of the monitor
203  */
204 int X11DRV_MONITOR_GetHeight(MONITOR *pMonitor)
205 {
206   X11DRV_MONITOR_DATA *pX11Monitor =
207     (X11DRV_MONITOR_DATA *) pMonitor->pDriverData;
208
209   return pX11Monitor->height;
210 }
211
212 /***********************************************************************
213  *              X11DRV_MONITOR_GetDepth
214  *
215  * Return the depth of the monitor
216  */
217 int X11DRV_MONITOR_GetDepth(MONITOR *pMonitor)
218 {
219   X11DRV_MONITOR_DATA *pX11Monitor =
220     (X11DRV_MONITOR_DATA *) pMonitor->pDriverData;
221
222   return pX11Monitor->depth;
223 }
224
225 #endif /* X_DISPLAY_MISSING */
226
227