4 * Copyright 1993, 1994, 1995, 1996 Alexandre Julliard
6 * 1995, 1996 Alex Korobka
11 #ifndef X_DISPLAY_MISSING
13 #include <X11/Xatom.h>
21 #include "debugtools.h"
33 #include "wine/winuser16.h"
35 DEFAULT_DEBUG_CHANNEL(win
)
37 /* Some useful macros */
38 #define HAS_DLGFRAME(style,exStyle) \
39 ((!((style) & WS_THICKFRAME)) && (((style) & WS_DLGFRAME) || ((exStyle) & WS_EX_DLGMODALFRAME)))
41 /**********************************************************************/
43 extern Cursor X11DRV_MOUSE_XCursor
; /* Current X cursor */
44 extern BOOL
X11DRV_CreateBitmap( HBITMAP
);
45 extern Pixmap
X11DRV_BITMAP_Pixmap( HBITMAP
);
47 /**********************************************************************/
49 /* X context to associate a hwnd to an X window */
50 XContext winContext
= 0;
52 Atom wmProtocols
= None
;
53 Atom wmDeleteWindow
= None
;
54 Atom dndProtocol
= None
;
55 Atom dndSelection
= None
;
56 Atom wmChangeState
= None
;
58 Atom kwmDockWindow
= None
;
60 /***********************************************************************
61 * X11DRV_WND_GetXWindow
63 * Return the X window associated to a window.
65 Window
X11DRV_WND_GetXWindow(WND
*wndPtr
)
67 return wndPtr
&& wndPtr
->pDriverData
?
68 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
: 0;
71 /***********************************************************************
72 * X11DRV_WND_FindXWindow
74 * Return the the first X window associated to a window chain.
76 Window
X11DRV_WND_FindXWindow(WND
*wndPtr
)
79 !((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
)
80 wndPtr
= wndPtr
->parent
;
82 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
: 0;
85 /***********************************************************************
86 * X11DRV_WND_GetXScreen
88 * Return the X screen associated to the window.
90 Screen
*X11DRV_WND_GetXScreen(WND
*wndPtr
)
92 while(wndPtr
->parent
) wndPtr
= wndPtr
->parent
;
93 return X11DRV_DESKTOP_GetXScreen((struct tagDESKTOP
*) wndPtr
->wExtra
);
96 /***********************************************************************
97 * X11DRV_WND_GetXRootWindow
99 * Return the X display associated to the window.
101 Window
X11DRV_WND_GetXRootWindow(WND
*wndPtr
)
103 while(wndPtr
->parent
) wndPtr
= wndPtr
->parent
;
104 return X11DRV_DESKTOP_GetXRootWindow((struct tagDESKTOP
*) wndPtr
->wExtra
);
107 /***********************************************************************
108 * X11DRV_WND_RegisterWindow
110 * Associate an X window to a HWND.
112 static void X11DRV_WND_RegisterWindow(WND
*wndPtr
)
114 TSXSetWMProtocols( display
, X11DRV_WND_GetXWindow(wndPtr
), &wmDeleteWindow
, 1 );
116 if (!winContext
) winContext
= TSXUniqueContext();
117 TSXSaveContext( display
, X11DRV_WND_GetXWindow(wndPtr
),
118 winContext
, (char *) wndPtr
->hwndSelf
);
121 /**********************************************************************
122 * X11DRV_WND_Initialize
124 void X11DRV_WND_Initialize(WND
*wndPtr
)
126 X11DRV_WND_DATA
*pWndDriverData
=
127 (X11DRV_WND_DATA
*) HeapAlloc(SystemHeap
, 0, sizeof(X11DRV_WND_DATA
));
129 wndPtr
->pDriverData
= (void *) pWndDriverData
;
131 pWndDriverData
->window
= 0;
134 /**********************************************************************
135 * X11DRV_WND_Finalize
137 void X11DRV_WND_Finalize(WND
*wndPtr
)
139 X11DRV_WND_DATA
*pWndDriverData
=
140 (X11DRV_WND_DATA
*) wndPtr
->pDriverData
;
142 if (!wndPtr
->pDriverData
) {
143 ERR("Trying to destroy window again. Not good.\n");
146 if(pWndDriverData
->window
)
149 "WND destroyed without destroying "
150 "the associated X Window (%ld)\n",
151 pWndDriverData
->window
154 HeapFree(SystemHeap
, 0, wndPtr
->pDriverData
);
155 wndPtr
->pDriverData
= NULL
;
158 /**********************************************************************
159 * X11DRV_WND_CreateDesktopWindow
161 BOOL
X11DRV_WND_CreateDesktopWindow(WND
*wndPtr
, CLASS
*classPtr
, BOOL bUnicode
)
163 if (wmProtocols
== None
)
164 wmProtocols
= TSXInternAtom( display
, "WM_PROTOCOLS", True
);
165 if (wmDeleteWindow
== None
)
166 wmDeleteWindow
= TSXInternAtom( display
, "WM_DELETE_WINDOW", True
);
167 if( dndProtocol
== None
)
168 dndProtocol
= TSXInternAtom( display
, "DndProtocol" , False
);
169 if( dndSelection
== None
)
170 dndSelection
= TSXInternAtom( display
, "DndSelection" , False
);
171 if( wmChangeState
== None
)
172 wmChangeState
= TSXInternAtom (display
, "WM_CHANGE_STATE", False
);
173 if (kwmDockWindow
== None
)
174 kwmDockWindow
= TSXInternAtom( display
, "KWM_DOCKWINDOW", False
);
176 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
=
177 X11DRV_WND_GetXRootWindow( wndPtr
);
178 X11DRV_WND_RegisterWindow( wndPtr
);
184 /**********************************************************************
185 * X11DRV_WND_CreateWindow
187 BOOL
X11DRV_WND_CreateWindow(WND
*wndPtr
, CLASS
*classPtr
, CREATESTRUCTA
*cs
, BOOL bUnicode
)
189 /* Create the X window (only for top-level windows, and then only */
190 /* when there's no desktop window) */
192 if (!(cs
->style
& WS_CHILD
) &&
193 (X11DRV_WND_GetXRootWindow(wndPtr
) == DefaultRootWindow(display
)))
197 XSetWindowAttributes win_attr
;
199 /* Create "managed" windows only if a title bar or resizable */
200 /* frame is required. */
201 if (WIN_WindowNeedsWMBorder(cs
->style
, cs
->dwExStyle
)) {
202 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
203 KeyReleaseMask
| PointerMotionMask
|
204 ButtonPressMask
| ButtonReleaseMask
|
205 FocusChangeMask
| StructureNotifyMask
;
206 win_attr
.override_redirect
= FALSE
;
207 wndPtr
->flags
|= WIN_MANAGED
;
209 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
210 KeyReleaseMask
| PointerMotionMask
|
211 ButtonPressMask
| ButtonReleaseMask
|
213 win_attr
.override_redirect
= TRUE
;
215 wndPtr
->flags
|= WIN_NATIVE
;
217 win_attr
.bit_gravity
= (classPtr
->style
& (CS_VREDRAW
| CS_HREDRAW
)) ? BGForget
: BGNorthWest
;
218 win_attr
.colormap
= X11DRV_PALETTE_PaletteXColormap
;
219 win_attr
.backing_store
= NotUseful
;
220 win_attr
.save_under
= ((classPtr
->style
& CS_SAVEBITS
) != 0);
221 win_attr
.cursor
= X11DRV_MOUSE_XCursor
;
223 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
= 0;
224 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->bit_gravity
= win_attr
.bit_gravity
;
225 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
=
226 TSXCreateWindow( display
,
227 X11DRV_WND_GetXRootWindow(wndPtr
),
228 cs
->x
, cs
->y
, cs
->cx
, cs
->cy
,
230 InputOutput
, CopyFromParent
,
231 CWEventMask
| CWOverrideRedirect
|
232 CWColormap
| CWCursor
| CWSaveUnder
|
233 CWBackingStore
| CWBitGravity
,
236 if(!(wGroupLeader
= X11DRV_WND_GetXWindow(wndPtr
)))
239 /* If we are the systray, we need to be managed to be noticed by KWM */
241 if (wndPtr
->dwExStyle
& WS_EX_TRAYWINDOW
)
242 X11DRV_WND_DockWindow(wndPtr
);
244 if (wndPtr
->flags
& WIN_MANAGED
)
246 XClassHint
*class_hints
= TSXAllocClassHint();
247 XSizeHints
* size_hints
= TSXAllocSizeHints();
251 class_hints
->res_name
= "wineManaged";
252 class_hints
->res_class
= "Wine";
253 TSXSetClassHint( display
, ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
, class_hints
);
254 TSXFree (class_hints
);
259 size_hints
->win_gravity
= StaticGravity
;
260 size_hints
->flags
= PWinGravity
;
262 if (HAS_DLGFRAME(cs
->style
,cs
->dwExStyle
))
264 size_hints
->min_width
= size_hints
->max_width
= cs
->cx
;
265 size_hints
->min_height
= size_hints
->max_height
= cs
->cy
;
266 size_hints
->flags
|= PMinSize
| PMaxSize
;
269 TSXSetWMSizeHints( display
, X11DRV_WND_GetXWindow(wndPtr
),
270 size_hints
, XA_WM_NORMAL_HINTS
);
275 if (cs
->hwndParent
) /* Get window owner */
278 WND
*tmpWnd
= WIN_FindWndPtr(cs
->hwndParent
);
280 w
= X11DRV_WND_FindXWindow( tmpWnd
);
283 TSXSetTransientForHint( display
, X11DRV_WND_GetXWindow(wndPtr
), w
);
286 WIN_ReleaseWndPtr(tmpWnd
);
289 wm_hints
= TSXAllocWMHints();
291 wm_hints
->flags
= InputHint
| StateHint
| WindowGroupHint
;
292 wm_hints
->input
= True
;
294 if( wndPtr
->flags
& WIN_MANAGED
)
296 if( wndPtr
->class->hIcon
)
300 if( (ptr
= (CURSORICONINFO
*)GlobalLock16( wndPtr
->class->hIcon
)) )
302 /* This is not entirely correct, may need to create
303 * an icon window and set the pixmap as a background */
305 HBITMAP hBitmap
= CreateBitmap( ptr
->nWidth
, ptr
->nHeight
,
306 ptr
->bPlanes
, ptr
->bBitsPerPixel
, (char *)(ptr
+ 1) +
307 ptr
->nHeight
* BITMAP_GetWidthBytes(ptr
->nWidth
,1) );
311 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
= hBitmap
;
312 X11DRV_CreateBitmap( hBitmap
);
313 wm_hints
->flags
|= IconPixmapHint
;
314 wm_hints
->icon_pixmap
= X11DRV_BITMAP_Pixmap( hBitmap
);
318 wm_hints
->initial_state
= (wndPtr
->dwStyle
& WS_MINIMIZE
)
319 ? IconicState
: NormalState
;
322 wm_hints
->initial_state
= NormalState
;
323 wm_hints
->window_group
= wGroupLeader
;
325 TSXSetWMHints( display
, X11DRV_WND_GetXWindow(wndPtr
), wm_hints
);
328 X11DRV_WND_RegisterWindow( wndPtr
);
333 /***********************************************************************
334 * X11DRV_WND_DestroyWindow
336 BOOL
X11DRV_WND_DestroyWindow(WND
*wndPtr
)
339 if ((w
= X11DRV_WND_GetXWindow(wndPtr
)))
342 TSXDeleteContext( display
, w
, winContext
);
343 TSXDestroyWindow( display
, w
);
344 while( TSXCheckWindowEvent(display
, w
, NoEventMask
, &xe
) );
346 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
= None
;
347 if( ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
)
349 DeleteObject( ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
);
350 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
= 0;
357 /*****************************************************************
358 * X11DRV_WND_SetParent
360 WND
*X11DRV_WND_SetParent(WND
*wndPtr
, WND
*pWndParent
)
362 WND
*pDesktop
= WIN_GetDesktop();
364 if( wndPtr
&& pWndParent
&& (wndPtr
!= pDesktop
) )
366 WND
* pWndPrev
= wndPtr
->parent
;
368 if( pWndParent
!= pWndPrev
)
370 if ( X11DRV_WND_GetXWindow(wndPtr
) )
372 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
374 TSXDestroyWindow( display
, X11DRV_WND_GetXWindow(wndPtr
) );
375 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
= None
;
378 WIN_UnlinkWindow(wndPtr
->hwndSelf
);
379 wndPtr
->parent
= pWndParent
;
381 /* Create an X counterpart for reparented top-level windows
382 * when not in the desktop mode. */
384 if( pWndParent
== pDesktop
)
386 wndPtr
->dwStyle
&= ~WS_CHILD
;
388 if( X11DRV_WND_GetXRootWindow(wndPtr
) == DefaultRootWindow(display
) )
391 cs
.lpCreateParams
= NULL
;
392 cs
.hInstance
= 0; /* not used in following call */
393 cs
.hMenu
= 0; /* not used in following call */
394 cs
.hwndParent
= pWndParent
->hwndSelf
;
395 cs
.cy
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
398 cs
.cx
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
401 cs
.y
= wndPtr
->rectWindow
.top
;
402 cs
.x
= wndPtr
->rectWindow
.left
;
403 cs
.style
= wndPtr
->dwStyle
;
404 cs
.lpszName
= 0; /* not used in following call */
405 cs
.lpszClass
= 0; /*not used in following call */
406 cs
.dwExStyle
= wndPtr
->dwExStyle
;
407 X11DRV_WND_CreateWindow(wndPtr
, wndPtr
->class,
411 else /* a child window */
413 if( !( wndPtr
->dwStyle
& WS_CHILD
) )
415 wndPtr
->dwStyle
|= WS_CHILD
;
416 if( wndPtr
->wIDmenu
!= 0)
418 DestroyMenu( (HMENU
) wndPtr
->wIDmenu
);
423 WIN_LinkWindow(wndPtr
->hwndSelf
, HWND_TOP
);
425 WIN_ReleaseDesktop();
428 WIN_ReleaseDesktop();
432 /***********************************************************************
433 * X11DRV_WND_ForceWindowRaise
435 * Raise a window on top of the X stacking order, while preserving
436 * the correct Windows Z order.
438 void X11DRV_WND_ForceWindowRaise(WND
*wndPtr
)
440 XWindowChanges winChanges
;
441 WND
*wndPrev
,*pDesktop
= WIN_GetDesktop();
443 if( !wndPtr
|| !X11DRV_WND_GetXWindow(wndPtr
) || (wndPtr
->flags
& WIN_MANAGED
) )
445 WIN_ReleaseDesktop();
449 /* Raise all windows up to wndPtr according to their Z order.
450 * (it would be easier with sibling-related Below but it doesn't
451 * work very well with SGI mwm for instance)
453 winChanges
.stack_mode
= Above
;
456 if (X11DRV_WND_GetXWindow(wndPtr
))
457 TSXReconfigureWMWindow( display
, X11DRV_WND_GetXWindow(wndPtr
), 0,
458 CWStackMode
, &winChanges
);
459 wndPrev
= pDesktop
->child
;
460 if (wndPrev
== wndPtr
) break;
461 while (wndPrev
&& (wndPrev
->next
!= wndPtr
)) wndPrev
= wndPrev
->next
;
464 WIN_ReleaseDesktop();
467 /***********************************************************************
468 * X11DRV_WND_FindDesktopXWindow [Internal]
470 * Find the actual X window which needs be restacked.
471 * Used by X11DRV_WND_SetWindowPos().
473 static Window
X11DRV_WND_FindDesktopXWindow( WND
*wndPtr
)
475 if (!(wndPtr
->flags
& WIN_MANAGED
))
476 return X11DRV_WND_GetXWindow(wndPtr
);
479 Window window
, root
, parent
, *children
;
481 window
= X11DRV_WND_GetXWindow(wndPtr
);
484 TSXQueryTree( display
, window
, &root
, &parent
,
485 &children
, &nchildren
);
494 /***********************************************************************
495 * WINPOS_SetXWindowPos
497 * SetWindowPos() for an X window. Used by the real SetWindowPos().
499 void X11DRV_WND_SetWindowPos(WND
*wndPtr
, const WINDOWPOS
*winpos
, BOOL bChangePos
)
501 XWindowChanges winChanges
;
503 WND
*winposPtr
= WIN_FindWndPtr( winpos
->hwnd
);
504 if ( !winposPtr
) return;
506 if(!wndPtr
->hwndSelf
) wndPtr
= NULL
; /* FIXME: WND destroyed, shouldn't happen!!! */
508 if (!(winpos
->flags
& SWP_SHOWWINDOW
) && (winpos
->flags
& SWP_HIDEWINDOW
))
510 if(X11DRV_WND_GetXWindow(wndPtr
))
511 TSXUnmapWindow( display
, X11DRV_WND_GetXWindow(wndPtr
) );
516 if ( !(winpos
->flags
& SWP_NOSIZE
))
518 winChanges
.width
= (winpos
->cx
> 0 ) ? winpos
->cx
: 1;
519 winChanges
.height
= (winpos
->cy
> 0 ) ? winpos
->cy
: 1;
520 changeMask
|= CWWidth
| CWHeight
;
522 /* Tweak dialog window size hints */
524 if ((winposPtr
->flags
& WIN_MANAGED
) &&
525 HAS_DLGFRAME(winposPtr
->dwStyle
,winposPtr
->dwExStyle
))
527 XSizeHints
*size_hints
= TSXAllocSizeHints();
531 long supplied_return
;
533 TSXGetWMSizeHints( display
, X11DRV_WND_GetXWindow(winposPtr
), size_hints
,
534 &supplied_return
, XA_WM_NORMAL_HINTS
);
535 size_hints
->min_width
= size_hints
->max_width
= winpos
->cx
;
536 size_hints
->min_height
= size_hints
->max_height
= winpos
->cy
;
537 TSXSetWMSizeHints( display
, X11DRV_WND_GetXWindow(winposPtr
), size_hints
,
538 XA_WM_NORMAL_HINTS
);
543 if (!(winpos
->flags
& SWP_NOMOVE
))
545 winChanges
.x
= winpos
->x
;
546 winChanges
.y
= winpos
->y
;
547 changeMask
|= CWX
| CWY
;
549 if (!(winpos
->flags
& SWP_NOZORDER
))
551 winChanges
.stack_mode
= Below
;
552 changeMask
|= CWStackMode
;
554 if (winpos
->hwndInsertAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
555 else if (winpos
->hwndInsertAfter
!= HWND_BOTTOM
)
557 WND
* insertPtr
= WIN_FindWndPtr( winpos
->hwndInsertAfter
);
560 stack
[0] = X11DRV_WND_FindDesktopXWindow( insertPtr
);
561 stack
[1] = X11DRV_WND_FindDesktopXWindow( winposPtr
);
563 /* for stupid window managers (i.e. all of them) */
565 TSXRestackWindows(display
, stack
, 2);
566 changeMask
&= ~CWStackMode
;
568 WIN_ReleaseWndPtr(insertPtr
);
571 if (changeMask
&& X11DRV_WND_GetXWindow(winposPtr
))
573 TSXReconfigureWMWindow( display
, X11DRV_WND_GetXWindow(winposPtr
), 0, changeMask
, &winChanges
);
574 if( winposPtr
->class->style
& (CS_VREDRAW
| CS_HREDRAW
) )
575 X11DRV_WND_SetHostAttr( winposPtr
, HAK_BITGRAVITY
, BGForget
);
579 if ( winpos
->flags
& SWP_SHOWWINDOW
)
581 if(X11DRV_WND_GetXWindow(wndPtr
))
582 TSXMapWindow( display
, X11DRV_WND_GetXWindow(wndPtr
) );
584 WIN_ReleaseWndPtr(winposPtr
);
587 /*****************************************************************
590 void X11DRV_WND_SetText(WND
*wndPtr
, LPCSTR text
)
592 if (!X11DRV_WND_GetXWindow(wndPtr
))
595 TSXStoreName( display
, X11DRV_WND_GetXWindow(wndPtr
), text
);
596 TSXSetIconName( display
, X11DRV_WND_GetXWindow(wndPtr
), text
);
599 /*****************************************************************
600 * X11DRV_WND_SetFocus
603 * Explicit colormap management seems to work only with OLVWM.
605 void X11DRV_WND_SetFocus(WND
*wndPtr
)
607 HWND hwnd
= wndPtr
->hwndSelf
;
608 XWindowAttributes win_attr
;
611 /* Only mess with the X focus if there's */
612 /* no desktop window and if the window is not managed by the WM. */
613 if ((X11DRV_WND_GetXRootWindow(wndPtr
) != DefaultRootWindow(display
))
614 || (wndPtr
->flags
& WIN_MANAGED
)) return;
616 if (!hwnd
) /* If setting the focus to 0, uninstall the colormap */
618 if (X11DRV_PALETTE_PaletteFlags
& X11DRV_PALETTE_PRIVATE
)
619 TSXUninstallColormap( display
, X11DRV_PALETTE_PaletteXColormap
);
623 /* Set X focus and install colormap */
625 if (!(win
= X11DRV_WND_FindXWindow(wndPtr
))) return;
626 if (!TSXGetWindowAttributes( display
, win
, &win_attr
) ||
627 (win_attr
.map_state
!= IsViewable
))
628 return; /* If window is not viewable, don't change anything */
630 TSXSetInputFocus( display
, win
, RevertToParent
, CurrentTime
);
631 if (X11DRV_PALETTE_PaletteFlags
& X11DRV_PALETTE_PRIVATE
)
632 TSXInstallColormap( display
, X11DRV_PALETTE_PaletteXColormap
);
637 /*****************************************************************
638 * X11DRV_WND_PreSizeMove
640 void X11DRV_WND_PreSizeMove(WND
*wndPtr
)
642 if (!(wndPtr
->dwStyle
& WS_CHILD
) &&
643 (X11DRV_WND_GetXRootWindow(wndPtr
) == DefaultRootWindow(display
)))
644 TSXGrabServer( display
);
647 /*****************************************************************
648 * X11DRV_WND_PostSizeMove
650 void X11DRV_WND_PostSizeMove(WND
*wndPtr
)
652 if (!(wndPtr
->dwStyle
& WS_CHILD
) &&
653 (X11DRV_GetXRootWindow() == DefaultRootWindow(display
)))
654 TSXUngrabServer( display
);
657 /*****************************************************************
658 * X11DRV_WND_SurfaceCopy
660 * Copies rect to (rect.left + dx, rect.top + dy).
662 void X11DRV_WND_SurfaceCopy(WND
* wndPtr
, DC
*dcPtr
, INT dx
, INT dy
,
663 const RECT
*rect
, BOOL bUpdate
)
665 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dcPtr
->physDev
;
668 dst
.x
= (src
.x
= dcPtr
->w
.DCOrgX
+ rect
->left
) + dx
;
669 dst
.y
= (src
.y
= dcPtr
->w
.DCOrgY
+ rect
->top
) + dy
;
671 if (bUpdate
) /* handles non-Wine windows hanging over the copied area */
672 TSXSetGraphicsExposures( display
, physDev
->gc
, True
);
673 TSXSetFunction( display
, physDev
->gc
, GXcopy
);
674 TSXCopyArea( display
, physDev
->drawable
, physDev
->drawable
,
675 physDev
->gc
, src
.x
, src
.y
,
676 rect
->right
- rect
->left
,
677 rect
->bottom
- rect
->top
,
680 TSXSetGraphicsExposures( display
, physDev
->gc
, False
);
682 if (bUpdate
) /* Make sure exposure events have been processed */
686 /***********************************************************************
687 * X11DRV_WND_SetDrawable
689 * Set the drawable, origin and dimensions for the DC associated to
692 void X11DRV_WND_SetDrawable(WND
*wndPtr
, DC
*dc
, WORD flags
, BOOL bSetClipOrigin
)
694 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
695 INT dcOrgXCopy
= 0, dcOrgYCopy
= 0;
696 BOOL offsetClipRgn
= FALSE
;
698 if (!wndPtr
) /* Get a DC for the whole screen */
702 physDev
->drawable
= X11DRV_WND_GetXRootWindow(wndPtr
);
703 TSXSetSubwindowMode( display
, physDev
->gc
, IncludeInferiors
);
708 * This function change the coordinate system (DCOrgX,DCOrgY)
709 * values. When it moves the origin, other data like the current clipping
710 * region will not be moved to that new origin. In the case of DCs that are class
711 * or window DCs that clipping region might be a valid value from a previous use
712 * of the DC and changing the origin of the DC without moving the clip region
713 * results in a clip region that is not placed properly in the DC.
714 * This code will save the dc origin, let the SetDrawable
715 * modify the origin and reset the clipping. When the clipping is set,
716 * it is moved according to the new DC origin.
718 if ( (wndPtr
->class->style
& (CS_OWNDC
| CS_CLASSDC
)) && (dc
->w
.hClipRgn
> 0))
720 dcOrgXCopy
= dc
->w
.DCOrgX
;
721 dcOrgYCopy
= dc
->w
.DCOrgY
;
722 offsetClipRgn
= TRUE
;
725 if (flags
& DCX_WINDOW
)
727 dc
->w
.DCOrgX
= wndPtr
->rectWindow
.left
;
728 dc
->w
.DCOrgY
= wndPtr
->rectWindow
.top
;
732 dc
->w
.DCOrgX
= wndPtr
->rectClient
.left
;
733 dc
->w
.DCOrgY
= wndPtr
->rectClient
.top
;
735 while (!X11DRV_WND_GetXWindow(wndPtr
))
737 wndPtr
= wndPtr
->parent
;
738 dc
->w
.DCOrgX
+= wndPtr
->rectClient
.left
;
739 dc
->w
.DCOrgY
+= wndPtr
->rectClient
.top
;
741 dc
->w
.DCOrgX
-= wndPtr
->rectWindow
.left
;
742 dc
->w
.DCOrgY
-= wndPtr
->rectWindow
.top
;
744 /* reset the clip region, according to the new origin */
747 OffsetRgn(dc
->w
.hClipRgn
, dc
->w
.DCOrgX
- dcOrgXCopy
,dc
->w
.DCOrgY
- dcOrgYCopy
);
750 physDev
->drawable
= X11DRV_WND_GetXWindow(wndPtr
);
753 /* This is needed when we reuse a cached DC because
754 * SetDCState() called by ReleaseDC() screws up DC
755 * origins for child windows.
759 TSXSetClipOrigin( display
, physDev
->gc
, dc
->w
.DCOrgX
, dc
->w
.DCOrgY
);
764 /***********************************************************************
767 static BOOL
X11DRV_SetWMHint(Display
* display
, WND
* wndPtr
, int hint
, int val
)
769 XWMHints
* wm_hints
= TSXAllocWMHints();
771 wm_hints
->flags
= hint
;
775 wm_hints
->input
= val
;
779 wm_hints
->initial_state
= val
;
783 wm_hints
->icon_pixmap
= (Pixmap
)val
;
787 wm_hints
->icon_window
= (Window
)val
;
791 TSXSetWMHints( display
, X11DRV_WND_GetXWindow(wndPtr
), wm_hints
);
799 /***********************************************************************
800 * X11DRV_WND_SetHostAttr
802 * This function returns TRUE if the attribute is supported and the
803 * action was successful. Otherwise it should return FALSE and Wine will try
804 * to get by without the functionality provided by the host window system.
806 BOOL
X11DRV_WND_SetHostAttr(WND
* wnd
, INT ha
, INT value
)
810 if( (w
= X11DRV_WND_GetXWindow(wnd
)) )
812 XSetWindowAttributes win_attr
;
816 case HAK_ICONICSTATE
: /* called when a window is minimized/restored */
818 if( (wnd
->flags
& WIN_MANAGED
) )
822 if( wnd
->dwStyle
& WS_VISIBLE
)
824 XClientMessageEvent ev
;
826 /* FIXME: set proper icon */
828 ev
.type
= ClientMessage
;
829 ev
.display
= display
;
830 ev
.message_type
= wmChangeState
;
832 ev
.data
.l
[0] = IconicState
;
835 if( TSXSendEvent (display
,
836 RootWindow( display
, XScreenNumberOfScreen(X11DRV_WND_GetXScreen(wnd
)) ),
837 True
, (SubstructureRedirectMask
| SubstructureNotifyMask
), (XEvent
*)&ev
))
841 while( !TSXCheckTypedWindowEvent( display
, w
, UnmapNotify
, &xe
) );
847 X11DRV_SetWMHint( display
, wnd
, StateHint
, IconicState
);
851 if( !(wnd
->flags
& WS_VISIBLE
) )
852 X11DRV_SetWMHint( display
, wnd
, StateHint
, NormalState
);
856 TSXMapWindow(display
, w
);
857 while( !TSXCheckTypedWindowEvent( display
, w
, MapNotify
, &xe
) );
864 case HAK_BITGRAVITY
: /* called when a window is resized */
866 if( ((X11DRV_WND_DATA
*) wnd
->pDriverData
)->bit_gravity
!= value
)
868 win_attr
.bit_gravity
= value
;
869 ((X11DRV_WND_DATA
*) wnd
->pDriverData
)->bit_gravity
= value
;
870 TSXChangeWindowAttributes( display
, w
, CWBitGravity
, &win_attr
);
874 case HAK_ACCEPTFOCUS
: /* called when a window is disabled/enabled */
876 if( (wnd
->flags
& WIN_MANAGED
) )
877 return X11DRV_SetWMHint( display
, wnd
, InputHint
, value
);
883 /***********************************************************************
884 * X11DRV_WND_IsSelfClipping
886 BOOL
X11DRV_WND_IsSelfClipping(WND
*wndPtr
)
888 return X11DRV_WND_GetXWindow(wndPtr
) != None
;
891 /***********************************************************************
892 * X11DRV_WND_DockWindow
894 * Set the X Property of the window that tells the windowmanager we really
895 * want to be in the systray
897 * KDE: set "KWM_DOCKWINDOW", type "KWM_DOCKWINDOW" to 1 before a window is
900 * all others: to be added ;)
902 void X11DRV_WND_DockWindow(WND
*wndPtr
)
905 Window win
= X11DRV_WND_GetXWindow(wndPtr
);
906 if (kwmDockWindow
== None
)
907 return; /* no KDE running */
909 display
,win
,kwmDockWindow
,kwmDockWindow
,32,PropModeReplace
,(char*)&data
,1
912 #endif /* !defined(X_DISPLAY_MISSING) */