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 (cs
->dwExStyle
& WS_EX_DLGMODALFRAME
))
134 XSizeHints
* size_hints
= TSXAllocSizeHints();
138 size_hints
->min_width
= size_hints
->max_width
= cs
->cx
;
139 size_hints
->min_height
= size_hints
->max_height
= cs
->cy
;
140 size_hints
->flags
= (PSize
| PMinSize
| PMaxSize
);
141 TSXSetWMSizeHints( display
, wndPtr
->window
, size_hints
,
142 XA_WM_NORMAL_HINTS
);
147 if (cs
->hwndParent
) /* Get window owner */
149 Window win
= X11DRV_WND_GetXWindow( cs
->hwndParent
);
150 if (win
) TSXSetTransientForHint( display
, wndPtr
->window
, win
);
152 X11DRV_WND_RegisterWindow( wndPtr
);
157 /***********************************************************************
158 * X11DRV_WND_DestroyWindow
160 BOOL32
X11DRV_WND_DestroyWindow(WND
*pWnd
)
165 TSXDeleteContext( display
, pWnd
->window
, winContext
);
166 TSXDestroyWindow( display
, pWnd
->window
);
167 while( TSXCheckWindowEvent(display
, pWnd
->window
, NoEventMask
, &xe
) );
174 /*****************************************************************
175 * X11DRV_WND_SetParent
177 WND
*X11DRV_WND_SetParent(WND
*wndPtr
, WND
*pWndParent
)
179 if( wndPtr
&& pWndParent
&& (wndPtr
!= WIN_GetDesktop()) )
181 WND
* pWndPrev
= wndPtr
->parent
;
183 if( pWndParent
!= pWndPrev
)
185 BOOL32 bFixupDCE
= IsWindowVisible32(wndPtr
->hwndSelf
);
187 if ( wndPtr
->window
)
189 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
191 TSXDestroyWindow( display
, wndPtr
->window
);
192 wndPtr
->window
= None
;
195 DCE_InvalidateDCE( wndPtr
, &wndPtr
->rectWindow
);
197 WIN_UnlinkWindow(wndPtr
->hwndSelf
);
198 wndPtr
->parent
= pWndParent
;
200 /* FIXME: Create an X counterpart for reparented top-level windows
201 * when not in the desktop mode. */
203 if ( pWndParent
!= WIN_GetDesktop() ) wndPtr
->dwStyle
|= WS_CHILD
;
204 WIN_LinkWindow(wndPtr
->hwndSelf
, HWND_BOTTOM
);
208 DCE_InvalidateDCE( wndPtr
, &wndPtr
->rectWindow
);
209 UpdateWindow32(wndPtr
->hwndSelf
);
217 /***********************************************************************
218 * X11DRV_WND_ForceWindowRaise
220 * Raise a window on top of the X stacking order, while preserving
221 * the correct Windows Z order.
223 void X11DRV_WND_ForceWindowRaise(WND
*pWnd
)
225 XWindowChanges winChanges
;
228 if( !pWnd
|| !pWnd
->window
|| (pWnd
->flags
& WIN_MANAGED
) )
231 /* Raise all windows up to pWnd according to their Z order.
232 * (it would be easier with sibling-related Below but it doesn't
233 * work very well with SGI mwm for instance)
235 winChanges
.stack_mode
= Above
;
238 if (pWnd
->window
) TSXReconfigureWMWindow( display
, pWnd
->window
, 0,
239 CWStackMode
, &winChanges
);
240 wndPrev
= WIN_GetDesktop()->child
;
241 if (wndPrev
== pWnd
) break;
242 while (wndPrev
&& (wndPrev
->next
!= pWnd
)) wndPrev
= wndPrev
->next
;
247 /***********************************************************************
248 * X11DRV_WND_FindDesktopXWindow [Internal]
250 * Find the actual X window which needs be restacked.
251 * Used by X11DRV_SetWindowPos().
253 static Window
X11DRV_WND_FindDesktopXWindow( WND
*wndPtr
)
255 if (!(wndPtr
->flags
& WIN_MANAGED
))
256 return wndPtr
->window
;
259 Window window
, root
, parent
, *children
;
261 window
= wndPtr
->window
;
264 TSXQueryTree( display
, window
, &root
, &parent
,
265 &children
, &nchildren
);
274 /***********************************************************************
275 * WINPOS_SetXWindowPos
277 * SetWindowPos() for an X window. Used by the real SetWindowPos().
279 void X11DRV_WND_SetWindowPos(WND
*wndPtr
, const WINDOWPOS32
*winpos
, BOOL32 bSMC_SETXPOS
)
281 XWindowChanges winChanges
;
283 WND
*winposPtr
= WIN_FindWndPtr( winpos
->hwnd
);
285 if (!(winpos
->flags
& SWP_SHOWWINDOW
) && (winpos
->flags
& SWP_HIDEWINDOW
))
287 if(wndPtr
&& wndPtr
->window
) TSXUnmapWindow( display
, wndPtr
->window
);
292 if ( !(winpos
->flags
& SWP_NOSIZE
))
294 winChanges
.width
= winpos
->cx
;
295 winChanges
.height
= winpos
->cy
;
296 changeMask
|= CWWidth
| CWHeight
;
298 /* Tweak dialog window size hints */
300 if ((winposPtr
->flags
& WIN_MANAGED
) &&
301 (winposPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
303 XSizeHints
*size_hints
= TSXAllocSizeHints();
307 long supplied_return
;
309 TSXGetWMSizeHints( display
, winposPtr
->window
, size_hints
,
310 &supplied_return
, XA_WM_NORMAL_HINTS
);
311 size_hints
->min_width
= size_hints
->max_width
= winpos
->cx
;
312 size_hints
->min_height
= size_hints
->max_height
= winpos
->cy
;
313 TSXSetWMSizeHints( display
, winposPtr
->window
, size_hints
,
314 XA_WM_NORMAL_HINTS
);
319 if (!(winpos
->flags
& SWP_NOMOVE
))
321 winChanges
.x
= winpos
->x
;
322 winChanges
.y
= winpos
->y
;
323 changeMask
|= CWX
| CWY
;
325 if (!(winpos
->flags
& SWP_NOZORDER
))
327 winChanges
.stack_mode
= Below
;
328 changeMask
|= CWStackMode
;
330 if (winpos
->hwndInsertAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
331 else if (winpos
->hwndInsertAfter
!= HWND_BOTTOM
)
333 WND
* insertPtr
= WIN_FindWndPtr( winpos
->hwndInsertAfter
);
336 stack
[0] = X11DRV_WND_FindDesktopXWindow( insertPtr
);
337 stack
[1] = X11DRV_WND_FindDesktopXWindow( winposPtr
);
339 /* for stupid window managers (i.e. all of them) */
341 TSXRestackWindows(display
, stack
, 2);
342 changeMask
&= ~CWStackMode
;
347 TSXReconfigureWMWindow( display
, winposPtr
->window
, 0, changeMask
, &winChanges
);
351 if ( winpos
->flags
& SWP_SHOWWINDOW
)
353 if(wndPtr
&& wndPtr
->window
) TSXMapWindow( display
, wndPtr
->window
);
357 /*****************************************************************
360 void X11DRV_WND_SetText(WND
*wndPtr
, LPCSTR text
)
365 TSXStoreName( display
, wndPtr
->window
, text
);
366 TSXSetIconName( display
, wndPtr
->window
, text
);
369 /*****************************************************************
370 * X11DRV_WND_SetFocus
373 * Explicit colormap management seems to work only with OLVWM.
375 void X11DRV_WND_SetFocus(WND
*wndPtr
)
377 HWND32 hwnd
= wndPtr
->hwndSelf
;
378 XWindowAttributes win_attr
;
380 /* Only mess with the X focus if there's */
381 /* no desktop window and no window manager. */
382 if ((rootWindow
!= DefaultRootWindow(display
)) || Options
.managed
) return;
384 if (!hwnd
) /* If setting the focus to 0, uninstall the colormap */
386 if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE
)
387 TSXUninstallColormap( display
, COLOR_GetColormap() );
391 /* Set X focus and install colormap */
393 if (!wndPtr
->window
) return;
395 if (!TSXGetWindowAttributes( display
, wndPtr
->window
, &win_attr
) ||
396 (win_attr
.map_state
!= IsViewable
))
397 return; /* If window is not viewable, don't change anything */
399 TSXSetInputFocus( display
,wndPtr
->window
, RevertToParent
, CurrentTime
);
400 if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE
)
401 TSXInstallColormap( display
, COLOR_GetColormap() );
406 /*****************************************************************
407 * X11DRV_WND_PreSizeMove
409 void X11DRV_WND_PreSizeMove(WND
*wndPtr
)
411 if (!(wndPtr
->dwStyle
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
412 TSXGrabServer( display
);
415 /*****************************************************************
416 * X11DRV_WND_PostSizeMove
418 void X11DRV_WND_PostSizeMove(WND
*wndPtr
)
420 if (!(wndPtr
->dwStyle
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
421 TSXUngrabServer( display
);
424 #endif /* !defined(X_DISPLAY_MISSING) */