4 * Copyright 1993, 1994, 1995, 1996 Alexandre Julliard
6 * 1995, 1996 Alex Korobka
11 #ifndef X_DISPLAY_MISSING
13 #include <X11/Xatom.h>
28 /**********************************************************************/
30 extern Cursor DISPLAY_XCursor
; /* Current X cursor */
32 /**********************************************************************/
34 /* X context to associate a hwnd to an X window */
35 XContext winContext
= 0;
37 Atom wmProtocols
= None
;
38 Atom wmDeleteWindow
= None
;
39 Atom dndProtocol
= None
;
40 Atom dndSelection
= None
;
42 /***********************************************************************
43 * X11DRV_WND_GetXWindow
45 * Return the X window associated to a window.
47 Window
X11DRV_WND_GetXWindow(HWND32 hwnd
)
49 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
50 while (wndPtr
&& !wndPtr
->window
) wndPtr
= wndPtr
->parent
;
51 return wndPtr
? wndPtr
->window
: 0;
54 /***********************************************************************
55 * X11DRV_WND_RegisterWindow
57 * Associate an X window to a HWND.
59 static void X11DRV_WND_RegisterWindow(WND
*pWnd
)
61 TSXSetWMProtocols( display
, pWnd
->window
, &wmDeleteWindow
, 1 );
63 if (!winContext
) winContext
= TSXUniqueContext();
64 TSXSaveContext( display
, pWnd
->window
, winContext
, (char *)pWnd
);
67 /**********************************************************************
68 * X11DRV_WND_CreateDesktopWindow
70 BOOL32
X11DRV_WND_CreateDesktopWindow(WND
*wndPtr
, CLASS
*classPtr
, BOOL32 bUnicode
)
72 if (wmProtocols
== None
)
73 wmProtocols
= TSXInternAtom( display
, "WM_PROTOCOLS", True
);
74 if (wmDeleteWindow
== None
)
75 wmDeleteWindow
= TSXInternAtom( display
, "WM_DELETE_WINDOW", True
);
76 if( dndProtocol
== None
)
77 dndProtocol
= TSXInternAtom( display
, "DndProtocol" , False
);
78 if( dndSelection
== None
)
79 dndSelection
= TSXInternAtom( display
, "DndSelection" , False
);
81 wndPtr
->window
= rootWindow
;
82 X11DRV_WND_RegisterWindow( wndPtr
);
87 /**********************************************************************
88 * X11DRV_WND_CreateWindow
90 BOOL32
X11DRV_WND_CreateWindow(WND
*wndPtr
, CLASS
*classPtr
, CREATESTRUCT32A
*cs
, BOOL32 bUnicode
)
92 /* Create the X window (only for top-level windows, and then only */
93 /* when there's no desktop window) */
95 if (!(cs
->style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
97 XSetWindowAttributes win_attr
;
99 if (Options
.managed
&& ((cs
->style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
100 (cs
->dwExStyle
& WS_EX_DLGMODALFRAME
)))
102 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
103 KeyReleaseMask
| PointerMotionMask
|
104 ButtonPressMask
| ButtonReleaseMask
|
105 FocusChangeMask
| StructureNotifyMask
;
106 win_attr
.override_redirect
= FALSE
;
107 wndPtr
->flags
|= WIN_MANAGED
;
111 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
112 KeyReleaseMask
| PointerMotionMask
|
113 ButtonPressMask
| ButtonReleaseMask
|
115 win_attr
.override_redirect
= TRUE
;
117 win_attr
.colormap
= COLOR_GetColormap();
118 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
119 win_attr
.save_under
= ((classPtr
->style
& CS_SAVEBITS
) != 0);
120 win_attr
.cursor
= DISPLAY_XCursor
;
121 wndPtr
->window
= TSXCreateWindow( display
, rootWindow
, cs
->x
, cs
->y
,
122 cs
->cx
, cs
->cy
, 0, CopyFromParent
,
123 InputOutput
, CopyFromParent
,
124 CWEventMask
| CWOverrideRedirect
|
125 CWColormap
| CWCursor
| CWSaveUnder
|
126 CWBackingStore
, &win_attr
);
131 if (wndPtr
->flags
& WIN_MANAGED
) {
132 XClassHint
*class_hints
= TSXAllocClassHint();
135 class_hints
->res_name
= "wineManaged";
136 class_hints
->res_class
= "Wine";
137 TSXSetClassHint( display
, wndPtr
->window
, class_hints
);
138 TSXFree (class_hints
);
141 if (cs
->dwExStyle
& WS_EX_DLGMODALFRAME
) {
142 XSizeHints
* size_hints
= TSXAllocSizeHints();
145 size_hints
->min_width
= size_hints
->max_width
= cs
->cx
;
146 size_hints
->min_height
= size_hints
->max_height
= cs
->cy
;
147 size_hints
->flags
= (PSize
| PMinSize
| PMaxSize
);
148 TSXSetWMSizeHints( display
, wndPtr
->window
, size_hints
,
149 XA_WM_NORMAL_HINTS
);
155 if (cs
->hwndParent
) /* Get window owner */
157 Window win
= X11DRV_WND_GetXWindow( cs
->hwndParent
);
158 if (win
) TSXSetTransientForHint( display
, wndPtr
->window
, win
);
160 X11DRV_WND_RegisterWindow( wndPtr
);
165 /***********************************************************************
166 * X11DRV_WND_DestroyWindow
168 BOOL32
X11DRV_WND_DestroyWindow(WND
*pWnd
)
173 TSXDeleteContext( display
, pWnd
->window
, winContext
);
174 TSXDestroyWindow( display
, pWnd
->window
);
175 while( TSXCheckWindowEvent(display
, pWnd
->window
, NoEventMask
, &xe
) );
182 /*****************************************************************
183 * X11DRV_WND_SetParent
185 WND
*X11DRV_WND_SetParent(WND
*wndPtr
, WND
*pWndParent
)
187 if( wndPtr
&& pWndParent
&& (wndPtr
!= WIN_GetDesktop()) )
189 WND
* pWndPrev
= wndPtr
->parent
;
191 if( pWndParent
!= pWndPrev
)
193 BOOL32 bFixupDCE
= IsWindowVisible32(wndPtr
->hwndSelf
);
195 if ( wndPtr
->window
)
197 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
199 TSXDestroyWindow( display
, wndPtr
->window
);
200 wndPtr
->window
= None
;
203 DCE_InvalidateDCE( wndPtr
, &wndPtr
->rectWindow
);
205 WIN_UnlinkWindow(wndPtr
->hwndSelf
);
206 wndPtr
->parent
= pWndParent
;
208 /* FIXME: Create an X counterpart for reparented top-level windows
209 * when not in the desktop mode. */
211 if ( pWndParent
!= WIN_GetDesktop() ) wndPtr
->dwStyle
|= WS_CHILD
;
212 WIN_LinkWindow(wndPtr
->hwndSelf
, HWND_BOTTOM
);
216 DCE_InvalidateDCE( wndPtr
, &wndPtr
->rectWindow
);
217 UpdateWindow32(wndPtr
->hwndSelf
);
225 /***********************************************************************
226 * X11DRV_WND_ForceWindowRaise
228 * Raise a window on top of the X stacking order, while preserving
229 * the correct Windows Z order.
231 void X11DRV_WND_ForceWindowRaise(WND
*pWnd
)
233 XWindowChanges winChanges
;
236 if( !pWnd
|| !pWnd
->window
|| (pWnd
->flags
& WIN_MANAGED
) )
239 /* Raise all windows up to pWnd according to their Z order.
240 * (it would be easier with sibling-related Below but it doesn't
241 * work very well with SGI mwm for instance)
243 winChanges
.stack_mode
= Above
;
246 if (pWnd
->window
) TSXReconfigureWMWindow( display
, pWnd
->window
, 0,
247 CWStackMode
, &winChanges
);
248 wndPrev
= WIN_GetDesktop()->child
;
249 if (wndPrev
== pWnd
) break;
250 while (wndPrev
&& (wndPrev
->next
!= pWnd
)) wndPrev
= wndPrev
->next
;
255 /***********************************************************************
256 * X11DRV_WND_FindDesktopXWindow [Internal]
258 * Find the actual X window which needs be restacked.
259 * Used by X11DRV_SetWindowPos().
261 static Window
X11DRV_WND_FindDesktopXWindow( WND
*wndPtr
)
263 if (!(wndPtr
->flags
& WIN_MANAGED
))
264 return wndPtr
->window
;
267 Window window
, root
, parent
, *children
;
269 window
= wndPtr
->window
;
272 TSXQueryTree( display
, window
, &root
, &parent
,
273 &children
, &nchildren
);
282 /***********************************************************************
283 * WINPOS_SetXWindowPos
285 * SetWindowPos() for an X window. Used by the real SetWindowPos().
287 void X11DRV_WND_SetWindowPos(WND
*wndPtr
, const WINDOWPOS32
*winpos
, BOOL32 bSMC_SETXPOS
)
289 XWindowChanges winChanges
;
291 WND
*winposPtr
= WIN_FindWndPtr( winpos
->hwnd
);
293 if (!(winpos
->flags
& SWP_SHOWWINDOW
) && (winpos
->flags
& SWP_HIDEWINDOW
))
295 if(wndPtr
&& wndPtr
->window
) TSXUnmapWindow( display
, wndPtr
->window
);
300 if ( !(winpos
->flags
& SWP_NOSIZE
))
302 winChanges
.width
= winpos
->cx
;
303 winChanges
.height
= winpos
->cy
;
304 changeMask
|= CWWidth
| CWHeight
;
306 /* Tweak dialog window size hints */
308 if ((winposPtr
->flags
& WIN_MANAGED
) &&
309 (winposPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
311 XSizeHints
*size_hints
= TSXAllocSizeHints();
315 long supplied_return
;
317 TSXGetWMSizeHints( display
, winposPtr
->window
, size_hints
,
318 &supplied_return
, XA_WM_NORMAL_HINTS
);
319 size_hints
->min_width
= size_hints
->max_width
= winpos
->cx
;
320 size_hints
->min_height
= size_hints
->max_height
= winpos
->cy
;
321 TSXSetWMSizeHints( display
, winposPtr
->window
, size_hints
,
322 XA_WM_NORMAL_HINTS
);
327 if (!(winpos
->flags
& SWP_NOMOVE
))
329 winChanges
.x
= winpos
->x
;
330 winChanges
.y
= winpos
->y
;
331 changeMask
|= CWX
| CWY
;
333 if (!(winpos
->flags
& SWP_NOZORDER
))
335 winChanges
.stack_mode
= Below
;
336 changeMask
|= CWStackMode
;
338 if (winpos
->hwndInsertAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
339 else if (winpos
->hwndInsertAfter
!= HWND_BOTTOM
)
341 WND
* insertPtr
= WIN_FindWndPtr( winpos
->hwndInsertAfter
);
344 stack
[0] = X11DRV_WND_FindDesktopXWindow( insertPtr
);
345 stack
[1] = X11DRV_WND_FindDesktopXWindow( winposPtr
);
347 /* for stupid window managers (i.e. all of them) */
349 TSXRestackWindows(display
, stack
, 2);
350 changeMask
&= ~CWStackMode
;
355 TSXReconfigureWMWindow( display
, winposPtr
->window
, 0, changeMask
, &winChanges
);
359 if ( winpos
->flags
& SWP_SHOWWINDOW
)
361 if(wndPtr
&& wndPtr
->window
) TSXMapWindow( display
, wndPtr
->window
);
365 /*****************************************************************
368 void X11DRV_WND_SetText(WND
*wndPtr
, LPCSTR text
)
373 TSXStoreName( display
, wndPtr
->window
, text
);
374 TSXSetIconName( display
, wndPtr
->window
, text
);
377 /*****************************************************************
378 * X11DRV_WND_SetFocus
381 * Explicit colormap management seems to work only with OLVWM.
383 void X11DRV_WND_SetFocus(WND
*wndPtr
)
385 HWND32 hwnd
= wndPtr
->hwndSelf
;
386 XWindowAttributes win_attr
;
388 /* Only mess with the X focus if there's */
389 /* no desktop window and no window manager. */
390 if ((rootWindow
!= DefaultRootWindow(display
)) || Options
.managed
) return;
392 if (!hwnd
) /* If setting the focus to 0, uninstall the colormap */
394 if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE
)
395 TSXUninstallColormap( display
, COLOR_GetColormap() );
399 /* Set X focus and install colormap */
401 if (!wndPtr
->window
) return;
403 if (!TSXGetWindowAttributes( display
, wndPtr
->window
, &win_attr
) ||
404 (win_attr
.map_state
!= IsViewable
))
405 return; /* If window is not viewable, don't change anything */
407 TSXSetInputFocus( display
,wndPtr
->window
, RevertToParent
, CurrentTime
);
408 if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE
)
409 TSXInstallColormap( display
, COLOR_GetColormap() );
414 /*****************************************************************
415 * X11DRV_WND_PreSizeMove
417 void X11DRV_WND_PreSizeMove(WND
*wndPtr
)
419 if (!(wndPtr
->dwStyle
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
420 TSXGrabServer( display
);
423 /*****************************************************************
424 * X11DRV_WND_PostSizeMove
426 void X11DRV_WND_PostSizeMove(WND
*wndPtr
)
428 if (!(wndPtr
->dwStyle
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
429 TSXUngrabServer( display
);
432 #endif /* !defined(X_DISPLAY_MISSING) */