Moved X11 mouse cursor handling to the DISPLAY driver.
[wine] / windows / x11drv / init.c
1 /*
2  * X11 windows driver
3  *
4  * Copyright 1993, 1994 Alexandre Julliard
5  * Copyright 1998 Patrik Stridvall
6  */
7
8 #include <string.h>
9 #include <X11/Xatom.h>
10 #include "ts_xlib.h"
11 #include "color.h"
12 #include "display.h"
13 #include "dce.h"
14 #include "options.h"
15 #include "message.h"
16 #include "win.h"
17 #include "windows.h"
18 #include "x11drv.h"
19
20 static BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs, BOOL32 bUnicode);
21 static WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent);
22
23 WND_DRIVER X11DRV_WND_Driver =
24 {
25     X11DRV_WND_CreateWindow,
26     X11DRV_WND_SetParent
27 };
28
29 extern Cursor DISPLAY_XCursor;  /* Current X cursor */
30
31 /**********************************************************************
32  *              X11DRV_WND_CreateWindow [Internal]
33  */
34 static BOOL32 X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCT32A *cs, BOOL32 bUnicode)
35 {
36   /* Create the X window (only for top-level windows, and then only */
37   /* when there's no desktop window) */
38   
39   if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
40     {
41       XSetWindowAttributes win_attr;
42       
43       if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
44                               (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
45         {
46           win_attr.event_mask = ExposureMask | KeyPressMask |
47             KeyReleaseMask | PointerMotionMask |
48             ButtonPressMask | ButtonReleaseMask |
49             FocusChangeMask | StructureNotifyMask;
50           win_attr.override_redirect = FALSE;
51           wndPtr->flags |= WIN_MANAGED;
52         }
53       else
54         {
55           win_attr.event_mask = ExposureMask | KeyPressMask |
56             KeyReleaseMask | PointerMotionMask |
57             ButtonPressMask | ButtonReleaseMask |
58             FocusChangeMask;
59           win_attr.override_redirect = TRUE;
60         }
61       win_attr.colormap      = COLOR_GetColormap();
62       win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
63       win_attr.save_under    = ((classPtr->style & CS_SAVEBITS) != 0);
64       win_attr.cursor        = DISPLAY_XCursor;
65       wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y,
66                                         cs->cx, cs->cy, 0, CopyFromParent,
67                                         InputOutput, CopyFromParent,
68                                         CWEventMask | CWOverrideRedirect |
69                                         CWColormap | CWCursor | CWSaveUnder |
70                                         CWBackingStore, &win_attr );
71
72       if ((wndPtr->flags & WIN_MANAGED) &&
73           (cs->dwExStyle & WS_EX_DLGMODALFRAME))
74         {
75           XSizeHints* size_hints = TSXAllocSizeHints();
76           
77           if (size_hints)
78             {
79               size_hints->min_width = size_hints->max_width = cs->cx;
80               size_hints->min_height = size_hints->max_height = cs->cy;
81                 size_hints->flags = (PSize | PMinSize | PMaxSize);
82                 TSXSetWMSizeHints( display, wndPtr->window, size_hints,
83                                    XA_WM_NORMAL_HINTS );
84                 TSXFree(size_hints);
85             }
86         }
87       
88       if (cs->hwndParent)  /* Get window owner */
89         {
90           Window win = WIN_GetXWindow( cs->hwndParent );
91           if (win) TSXSetTransientForHint( display, wndPtr->window, win );
92         }
93       EVENT_RegisterWindow( wndPtr );
94     }
95   return TRUE;
96 }
97
98 /*****************************************************************
99  *              X11DRV_WND_SetParent    [Internal]
100  */
101 static WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent)
102 {
103     if( wndPtr && pWndParent && (wndPtr != WIN_GetDesktop()) )
104     {
105         WND* pWndPrev = wndPtr->parent;
106
107         if( pWndParent != pWndPrev )
108         {
109             BOOL32 bFixupDCE = IsWindowVisible32(wndPtr->hwndSelf);
110
111             if ( wndPtr->window )
112             {
113                 /* Toplevel window needs to be reparented.  Used by Tk 8.0 */
114
115                 TSXDestroyWindow( display, wndPtr->window );
116                 wndPtr->window = None;
117             }
118             else if( bFixupDCE )
119                 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
120
121             WIN_UnlinkWindow(wndPtr->hwndSelf);
122             wndPtr->parent = pWndParent;
123
124             /* FIXME: Create an X counterpart for reparented top-level windows
125              * when not in the desktop mode. */
126      
127             if ( pWndParent != WIN_GetDesktop() ) wndPtr->dwStyle |= WS_CHILD;
128             WIN_LinkWindow(wndPtr->hwndSelf, HWND_BOTTOM);
129
130             if( bFixupDCE )
131             {
132                 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
133                 UpdateWindow32(wndPtr->hwndSelf);
134             }
135         }
136         return pWndPrev;
137     } /* failure */
138     return 0;
139 }