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 wndPtr
->expose_event
= NULL
;
83 X11DRV_WND_RegisterWindow( wndPtr
);
88 /**********************************************************************
89 * X11DRV_WND_CreateWindow
91 BOOL32
X11DRV_WND_CreateWindow(WND
*wndPtr
, CLASS
*classPtr
, CREATESTRUCT32A
*cs
, BOOL32 bUnicode
)
93 /* Create the X window (only for top-level windows, and then only */
94 /* when there's no desktop window) */
96 if (!(cs
->style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
98 XSetWindowAttributes win_attr
;
100 if (Options
.managed
&& ((cs
->style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
101 (cs
->dwExStyle
& WS_EX_DLGMODALFRAME
)))
103 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
104 KeyReleaseMask
| PointerMotionMask
|
105 ButtonPressMask
| ButtonReleaseMask
|
106 FocusChangeMask
| StructureNotifyMask
;
107 win_attr
.override_redirect
= FALSE
;
108 wndPtr
->flags
|= WIN_MANAGED
;
112 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
113 KeyReleaseMask
| PointerMotionMask
|
114 ButtonPressMask
| ButtonReleaseMask
|
116 win_attr
.override_redirect
= TRUE
;
118 win_attr
.colormap
= COLOR_GetColormap();
119 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
120 win_attr
.save_under
= ((classPtr
->style
& CS_SAVEBITS
) != 0);
121 win_attr
.cursor
= DISPLAY_XCursor
;
122 wndPtr
->window
= TSXCreateWindow( display
, rootWindow
, cs
->x
, cs
->y
,
123 cs
->cx
, cs
->cy
, 0, CopyFromParent
,
124 InputOutput
, CopyFromParent
,
125 CWEventMask
| CWOverrideRedirect
|
126 CWColormap
| CWCursor
| CWSaveUnder
|
127 CWBackingStore
, &win_attr
);
132 if ((wndPtr
->flags
& WIN_MANAGED
) &&
133 (cs
->dwExStyle
& WS_EX_DLGMODALFRAME
))
135 XSizeHints
* size_hints
= TSXAllocSizeHints();
139 size_hints
->min_width
= size_hints
->max_width
= cs
->cx
;
140 size_hints
->min_height
= size_hints
->max_height
= cs
->cy
;
141 size_hints
->flags
= (PSize
| PMinSize
| PMaxSize
);
142 TSXSetWMSizeHints( display
, wndPtr
->window
, size_hints
,
143 XA_WM_NORMAL_HINTS
);
148 if (cs
->hwndParent
) /* Get window owner */
150 Window win
= X11DRV_WND_GetXWindow( cs
->hwndParent
);
151 if (win
) TSXSetTransientForHint( display
, wndPtr
->window
, win
);
153 X11DRV_WND_RegisterWindow( wndPtr
);
158 /***********************************************************************
159 * X11DRV_WND_DestroyWindow
161 BOOL32
X11DRV_WND_DestroyWindow(WND
*pWnd
)
163 if (pWnd
->expose_event
)
165 free( pWnd
->expose_event
);
166 pWnd
->expose_event
= NULL
;
172 TSXDeleteContext( display
, pWnd
->window
, winContext
);
173 TSXDestroyWindow( display
, pWnd
->window
);
174 while( TSXCheckWindowEvent(display
, pWnd
->window
, NoEventMask
, &xe
) );
181 /*****************************************************************
182 * X11DRV_WND_SetParent
184 WND
*X11DRV_WND_SetParent(WND
*wndPtr
, WND
*pWndParent
)
186 if( wndPtr
&& pWndParent
&& (wndPtr
!= WIN_GetDesktop()) )
188 WND
* pWndPrev
= wndPtr
->parent
;
190 if( pWndParent
!= pWndPrev
)
192 BOOL32 bFixupDCE
= IsWindowVisible32(wndPtr
->hwndSelf
);
194 if ( wndPtr
->window
)
196 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
198 TSXDestroyWindow( display
, wndPtr
->window
);
199 wndPtr
->window
= None
;
202 DCE_InvalidateDCE( wndPtr
, &wndPtr
->rectWindow
);
204 WIN_UnlinkWindow(wndPtr
->hwndSelf
);
205 wndPtr
->parent
= pWndParent
;
207 /* FIXME: Create an X counterpart for reparented top-level windows
208 * when not in the desktop mode. */
210 if ( pWndParent
!= WIN_GetDesktop() ) wndPtr
->dwStyle
|= WS_CHILD
;
211 WIN_LinkWindow(wndPtr
->hwndSelf
, HWND_BOTTOM
);
215 DCE_InvalidateDCE( wndPtr
, &wndPtr
->rectWindow
);
216 UpdateWindow32(wndPtr
->hwndSelf
);
224 /***********************************************************************
225 * X11DRV_WND_ForceWindowRaise
227 * Raise a window on top of the X stacking order, while preserving
228 * the correct Windows Z order.
230 void X11DRV_WND_ForceWindowRaise(WND
*pWnd
)
232 XWindowChanges winChanges
;
235 if( !pWnd
|| !pWnd
->window
|| (pWnd
->flags
& WIN_MANAGED
) )
238 /* Raise all windows up to pWnd according to their Z order.
239 * (it would be easier with sibling-related Below but it doesn't
240 * work very well with SGI mwm for instance)
242 winChanges
.stack_mode
= Above
;
245 if (pWnd
->window
) TSXReconfigureWMWindow( display
, pWnd
->window
, 0,
246 CWStackMode
, &winChanges
);
247 wndPrev
= WIN_GetDesktop()->child
;
248 if (wndPrev
== pWnd
) break;
249 while (wndPrev
&& (wndPrev
->next
!= pWnd
)) wndPrev
= wndPrev
->next
;
254 /***********************************************************************
255 * X11DRV_WND_FindDesktopXWindow [Internal]
257 * Find the actual X window which needs be restacked.
258 * Used by X11DRV_SetWindowPos().
260 static Window
X11DRV_WND_FindDesktopXWindow( WND
*wndPtr
)
262 if (!(wndPtr
->flags
& WIN_MANAGED
))
263 return wndPtr
->window
;
266 Window window
, root
, parent
, *children
;
268 window
= wndPtr
->window
;
271 TSXQueryTree( display
, window
, &root
, &parent
,
272 &children
, &nchildren
);
281 /***********************************************************************
282 * WINPOS_SetXWindowPos
284 * SetWindowPos() for an X window. Used by the real SetWindowPos().
286 void X11DRV_WND_SetWindowPos(WND
*wndPtr
, const WINDOWPOS32
*winpos
, BOOL32 bSMC_SETXPOS
)
288 XWindowChanges winChanges
;
290 WND
*winposPtr
= WIN_FindWndPtr( winpos
->hwnd
);
292 if (!(winpos
->flags
& SWP_SHOWWINDOW
) && (winpos
->flags
& SWP_HIDEWINDOW
))
294 if(wndPtr
&& wndPtr
->window
) TSXUnmapWindow( display
, wndPtr
->window
);
299 if ( !(winpos
->flags
& SWP_NOSIZE
))
301 winChanges
.width
= winpos
->cx
;
302 winChanges
.height
= winpos
->cy
;
303 changeMask
|= CWWidth
| CWHeight
;
305 /* Tweak dialog window size hints */
307 if ((winposPtr
->flags
& WIN_MANAGED
) &&
308 (winposPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
310 XSizeHints
*size_hints
= TSXAllocSizeHints();
314 long supplied_return
;
316 TSXGetWMSizeHints( display
, winposPtr
->window
, size_hints
,
317 &supplied_return
, XA_WM_NORMAL_HINTS
);
318 size_hints
->min_width
= size_hints
->max_width
= winpos
->cx
;
319 size_hints
->min_height
= size_hints
->max_height
= winpos
->cy
;
320 TSXSetWMSizeHints( display
, winposPtr
->window
, size_hints
,
321 XA_WM_NORMAL_HINTS
);
326 if (!(winpos
->flags
& SWP_NOMOVE
))
328 winChanges
.x
= winpos
->x
;
329 winChanges
.y
= winpos
->y
;
330 changeMask
|= CWX
| CWY
;
332 if (!(winpos
->flags
& SWP_NOZORDER
))
334 winChanges
.stack_mode
= Below
;
335 changeMask
|= CWStackMode
;
337 if (winpos
->hwndInsertAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
338 else if (winpos
->hwndInsertAfter
!= HWND_BOTTOM
)
340 WND
* insertPtr
= WIN_FindWndPtr( winpos
->hwndInsertAfter
);
343 stack
[0] = X11DRV_WND_FindDesktopXWindow( insertPtr
);
344 stack
[1] = X11DRV_WND_FindDesktopXWindow( winposPtr
);
346 /* for stupid window managers (i.e. all of them) */
348 TSXRestackWindows(display
, stack
, 2);
349 changeMask
&= ~CWStackMode
;
354 TSXReconfigureWMWindow( display
, winposPtr
->window
, 0, changeMask
, &winChanges
);
358 if ( winpos
->flags
& SWP_SHOWWINDOW
)
360 if(wndPtr
&& wndPtr
->window
) TSXMapWindow( display
, wndPtr
->window
);
364 /*****************************************************************
367 void X11DRV_WND_SetText(WND
*wndPtr
, LPCSTR text
)
372 TSXStoreName( display
, wndPtr
->window
, text
);
373 TSXSetIconName( display
, wndPtr
->window
, text
);
376 /*****************************************************************
377 * X11DRV_WND_SetFocus
380 * Explicit colormap management seems to work only with OLVWM.
382 void X11DRV_WND_SetFocus(WND
*wndPtr
)
384 HWND32 hwnd
= wndPtr
->hwndSelf
;
385 XWindowAttributes win_attr
;
387 /* Only mess with the X focus if there's */
388 /* no desktop window and no window manager. */
389 if ((rootWindow
!= DefaultRootWindow(display
)) || Options
.managed
) return;
391 if (!hwnd
) /* If setting the focus to 0, uninstall the colormap */
393 if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE
)
394 TSXUninstallColormap( display
, COLOR_GetColormap() );
398 /* Set X focus and install colormap */
400 if (!wndPtr
->window
) return;
402 if (!TSXGetWindowAttributes( display
, wndPtr
->window
, &win_attr
) ||
403 (win_attr
.map_state
!= IsViewable
))
404 return; /* If window is not viewable, don't change anything */
406 TSXSetInputFocus( display
,wndPtr
->window
, RevertToParent
, CurrentTime
);
407 if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE
)
408 TSXInstallColormap( display
, COLOR_GetColormap() );
413 /*****************************************************************
414 * X11DRV_WND_PreSizeMove
416 void X11DRV_WND_PreSizeMove(WND
*wndPtr
)
418 if (!(wndPtr
->dwStyle
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
419 TSXGrabServer( display
);
422 /*****************************************************************
423 * X11DRV_WND_PostSizeMove
425 void X11DRV_WND_PostSizeMove(WND
*wndPtr
)
427 if (!(wndPtr
->dwStyle
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
428 TSXUngrabServer( display
);
431 #endif /* !defined(X_DISPLAY_MISSING) */