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"
32 #include "wine/winuser16.h"
34 DEFAULT_DEBUG_CHANNEL(win
)
36 /* Some useful macros */
37 #define HAS_DLGFRAME(style,exStyle) \
38 ((!((style) & WS_THICKFRAME)) && (((style) & WS_DLGFRAME) || ((exStyle) & WS_EX_DLGMODALFRAME)))
40 /**********************************************************************/
42 extern Cursor X11DRV_MOUSE_XCursor
; /* Current X cursor */
43 extern BOOL
X11DRV_CreateBitmap( HBITMAP
);
44 extern Pixmap
X11DRV_BITMAP_Pixmap( HBITMAP
);
46 /**********************************************************************/
48 /* X context to associate a hwnd to an X window */
49 XContext winContext
= 0;
51 Atom wmProtocols
= None
;
52 Atom wmDeleteWindow
= None
;
53 Atom dndProtocol
= None
;
54 Atom dndSelection
= None
;
55 Atom wmChangeState
= None
;
57 Atom kwmDockWindow
= None
;
59 /***********************************************************************
60 * X11DRV_WND_GetXWindow
62 * Return the X window associated to a window.
64 Window
X11DRV_WND_GetXWindow(WND
*wndPtr
)
66 return wndPtr
&& wndPtr
->pDriverData
?
67 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
: 0;
70 /***********************************************************************
71 * X11DRV_WND_FindXWindow
73 * Return the the first X window associated to a window chain.
75 Window
X11DRV_WND_FindXWindow(WND
*wndPtr
)
78 !((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
)
79 wndPtr
= wndPtr
->parent
;
81 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
: 0;
84 /***********************************************************************
85 * X11DRV_WND_RegisterWindow
87 * Associate an X window to a HWND.
89 static void X11DRV_WND_RegisterWindow(WND
*wndPtr
)
91 TSXSetWMProtocols( display
, X11DRV_WND_GetXWindow(wndPtr
), &wmDeleteWindow
, 1 );
93 if (!winContext
) winContext
= TSXUniqueContext();
94 TSXSaveContext( display
, X11DRV_WND_GetXWindow(wndPtr
),
95 winContext
, (char *) wndPtr
->hwndSelf
);
98 /**********************************************************************
99 * X11DRV_WND_Initialize
101 void X11DRV_WND_Initialize(WND
*wndPtr
)
103 X11DRV_WND_DATA
*pWndDriverData
=
104 (X11DRV_WND_DATA
*) HeapAlloc(SystemHeap
, 0, sizeof(X11DRV_WND_DATA
));
106 wndPtr
->pDriverData
= (void *) pWndDriverData
;
108 pWndDriverData
->window
= 0;
111 /**********************************************************************
112 * X11DRV_WND_Finalize
114 void X11DRV_WND_Finalize(WND
*wndPtr
)
116 X11DRV_WND_DATA
*pWndDriverData
=
117 (X11DRV_WND_DATA
*) wndPtr
->pDriverData
;
119 if (!wndPtr
->pDriverData
) {
120 ERR("Trying to destroy window again. Not good.\n");
123 if(pWndDriverData
->window
)
126 "WND destroyed without destroying "
127 "the associated X Window (%ld)\n",
128 pWndDriverData
->window
131 HeapFree(SystemHeap
, 0, wndPtr
->pDriverData
);
132 wndPtr
->pDriverData
= NULL
;
135 /**********************************************************************
136 * X11DRV_WND_CreateDesktopWindow
138 BOOL
X11DRV_WND_CreateDesktopWindow(WND
*wndPtr
, CLASS
*classPtr
, BOOL bUnicode
)
140 if (wmProtocols
== None
)
141 wmProtocols
= TSXInternAtom( display
, "WM_PROTOCOLS", True
);
142 if (wmDeleteWindow
== None
)
143 wmDeleteWindow
= TSXInternAtom( display
, "WM_DELETE_WINDOW", True
);
144 if( dndProtocol
== None
)
145 dndProtocol
= TSXInternAtom( display
, "DndProtocol" , False
);
146 if( dndSelection
== None
)
147 dndSelection
= TSXInternAtom( display
, "DndSelection" , False
);
148 if( wmChangeState
== None
)
149 wmChangeState
= TSXInternAtom (display
, "WM_CHANGE_STATE", False
);
150 if (kwmDockWindow
== None
)
151 kwmDockWindow
= TSXInternAtom( display
, "KWM_DOCKWINDOW", False
);
153 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
= X11DRV_GetXRootWindow();
154 X11DRV_WND_RegisterWindow( wndPtr
);
160 /**********************************************************************
161 * X11DRV_WND_CreateWindow
163 BOOL
X11DRV_WND_CreateWindow(WND
*wndPtr
, CLASS
*classPtr
, CREATESTRUCTA
*cs
, BOOL bUnicode
)
165 /* Create the X window (only for top-level windows, and then only */
166 /* when there's no desktop window) */
168 if (!(cs
->style
& WS_CHILD
) && (X11DRV_GetXRootWindow() == DefaultRootWindow(display
)))
172 XSetWindowAttributes win_attr
;
174 /* Create "managed" windows only if a title bar or resizable */
175 /* frame is required. */
176 if (WIN_WindowNeedsWMBorder(cs
->style
, cs
->dwExStyle
)) {
177 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
178 KeyReleaseMask
| PointerMotionMask
|
179 ButtonPressMask
| ButtonReleaseMask
|
180 FocusChangeMask
| StructureNotifyMask
;
181 win_attr
.override_redirect
= FALSE
;
182 wndPtr
->flags
|= WIN_MANAGED
;
184 win_attr
.event_mask
= ExposureMask
| KeyPressMask
|
185 KeyReleaseMask
| PointerMotionMask
|
186 ButtonPressMask
| ButtonReleaseMask
|
188 win_attr
.override_redirect
= TRUE
;
190 wndPtr
->flags
|= WIN_NATIVE
;
192 win_attr
.bit_gravity
= (classPtr
->style
& (CS_VREDRAW
| CS_HREDRAW
)) ? BGForget
: BGNorthWest
;
193 win_attr
.colormap
= X11DRV_PALETTE_PaletteXColormap
;
194 win_attr
.backing_store
= NotUseful
;
195 win_attr
.save_under
= ((classPtr
->style
& CS_SAVEBITS
) != 0);
196 win_attr
.cursor
= X11DRV_MOUSE_XCursor
;
198 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
= 0;
199 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->bit_gravity
= win_attr
.bit_gravity
;
200 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
=
201 TSXCreateWindow( display
, X11DRV_GetXRootWindow(),
202 cs
->x
, cs
->y
, cs
->cx
, cs
->cy
,
204 InputOutput
, CopyFromParent
,
205 CWEventMask
| CWOverrideRedirect
|
206 CWColormap
| CWCursor
| CWSaveUnder
|
207 CWBackingStore
| CWBitGravity
,
210 if(!(wGroupLeader
= X11DRV_WND_GetXWindow(wndPtr
)))
213 /* If we are the systray, we need to be managed to be noticed by KWM */
215 if (wndPtr
->dwExStyle
& WS_EX_TRAYWINDOW
)
216 X11DRV_WND_DockWindow(wndPtr
);
218 if (wndPtr
->flags
& WIN_MANAGED
)
220 XClassHint
*class_hints
= TSXAllocClassHint();
221 XSizeHints
* size_hints
= TSXAllocSizeHints();
225 class_hints
->res_name
= "wineManaged";
226 class_hints
->res_class
= "Wine";
227 TSXSetClassHint( display
, ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
, class_hints
);
228 TSXFree (class_hints
);
233 size_hints
->win_gravity
= StaticGravity
;
234 size_hints
->flags
= PWinGravity
;
236 if (HAS_DLGFRAME(cs
->style
,cs
->dwExStyle
))
238 size_hints
->min_width
= size_hints
->max_width
= cs
->cx
;
239 size_hints
->min_height
= size_hints
->max_height
= cs
->cy
;
240 size_hints
->flags
|= PMinSize
| PMaxSize
;
243 TSXSetWMSizeHints( display
, X11DRV_WND_GetXWindow(wndPtr
),
244 size_hints
, XA_WM_NORMAL_HINTS
);
249 if (cs
->hwndParent
) /* Get window owner */
252 WND
*tmpWnd
= WIN_FindWndPtr(cs
->hwndParent
);
254 w
= X11DRV_WND_FindXWindow( tmpWnd
);
257 TSXSetTransientForHint( display
, X11DRV_WND_GetXWindow(wndPtr
), w
);
260 WIN_ReleaseWndPtr(tmpWnd
);
263 wm_hints
= TSXAllocWMHints();
265 wm_hints
->flags
= InputHint
| StateHint
| WindowGroupHint
;
266 wm_hints
->input
= True
;
268 if( wndPtr
->flags
& WIN_MANAGED
)
270 if( wndPtr
->class->hIcon
)
274 if( (ptr
= (CURSORICONINFO
*)GlobalLock16( wndPtr
->class->hIcon
)) )
276 /* This is not entirely correct, may need to create
277 * an icon window and set the pixmap as a background */
279 HBITMAP hBitmap
= CreateBitmap( ptr
->nWidth
, ptr
->nHeight
,
280 ptr
->bPlanes
, ptr
->bBitsPerPixel
, (char *)(ptr
+ 1) +
281 ptr
->nHeight
* BITMAP_GetWidthBytes(ptr
->nWidth
,1) );
285 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
= hBitmap
;
286 X11DRV_CreateBitmap( hBitmap
);
287 wm_hints
->flags
|= IconPixmapHint
;
288 wm_hints
->icon_pixmap
= X11DRV_BITMAP_Pixmap( hBitmap
);
292 wm_hints
->initial_state
= (wndPtr
->dwStyle
& WS_MINIMIZE
)
293 ? IconicState
: NormalState
;
296 wm_hints
->initial_state
= NormalState
;
297 wm_hints
->window_group
= wGroupLeader
;
299 TSXSetWMHints( display
, X11DRV_WND_GetXWindow(wndPtr
), wm_hints
);
302 X11DRV_WND_RegisterWindow( wndPtr
);
307 /***********************************************************************
308 * X11DRV_WND_DestroyWindow
310 BOOL
X11DRV_WND_DestroyWindow(WND
*wndPtr
)
313 if ((w
= X11DRV_WND_GetXWindow(wndPtr
)))
316 TSXDeleteContext( display
, w
, winContext
);
317 TSXDestroyWindow( display
, w
);
318 while( TSXCheckWindowEvent(display
, w
, NoEventMask
, &xe
) );
320 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
= None
;
321 if( ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
)
323 DeleteObject( ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
);
324 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->hWMIconBitmap
= 0;
331 /*****************************************************************
332 * X11DRV_WND_SetParent
334 WND
*X11DRV_WND_SetParent(WND
*wndPtr
, WND
*pWndParent
)
336 WND
*pDesktop
= WIN_GetDesktop();
338 if( wndPtr
&& pWndParent
&& (wndPtr
!= pDesktop
) )
340 WND
* pWndPrev
= wndPtr
->parent
;
342 if( pWndParent
!= pWndPrev
)
344 if ( X11DRV_WND_GetXWindow(wndPtr
) )
346 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
348 TSXDestroyWindow( display
, X11DRV_WND_GetXWindow(wndPtr
) );
349 ((X11DRV_WND_DATA
*) wndPtr
->pDriverData
)->window
= None
;
352 WIN_UnlinkWindow(wndPtr
->hwndSelf
);
353 wndPtr
->parent
= pWndParent
;
355 /* Create an X counterpart for reparented top-level windows
356 * when not in the desktop mode. */
358 if( pWndParent
== pDesktop
)
360 wndPtr
->dwStyle
&= ~WS_CHILD
;
362 if( X11DRV_GetXRootWindow() == DefaultRootWindow(display
) )
365 cs
.lpCreateParams
= NULL
;
366 cs
.hInstance
= 0; /* not used in following call */
367 cs
.hMenu
= 0; /* not used in following call */
368 cs
.hwndParent
= pWndParent
->hwndSelf
;
369 cs
.cy
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
372 cs
.cx
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
375 cs
.y
= wndPtr
->rectWindow
.top
;
376 cs
.x
= wndPtr
->rectWindow
.left
;
377 cs
.style
= wndPtr
->dwStyle
;
378 cs
.lpszName
= 0; /* not used in following call */
379 cs
.lpszClass
= 0; /*not used in following call */
380 cs
.dwExStyle
= wndPtr
->dwExStyle
;
381 X11DRV_WND_CreateWindow(wndPtr
, wndPtr
->class,
385 else /* a child window */
387 if( !( wndPtr
->dwStyle
& WS_CHILD
) )
389 wndPtr
->dwStyle
|= WS_CHILD
;
390 if( wndPtr
->wIDmenu
!= 0)
392 DestroyMenu( (HMENU
) wndPtr
->wIDmenu
);
397 WIN_LinkWindow(wndPtr
->hwndSelf
, HWND_TOP
);
399 WIN_ReleaseDesktop();
402 WIN_ReleaseDesktop();
406 /***********************************************************************
407 * X11DRV_WND_ForceWindowRaise
409 * Raise a window on top of the X stacking order, while preserving
410 * the correct Windows Z order.
412 void X11DRV_WND_ForceWindowRaise(WND
*wndPtr
)
414 XWindowChanges winChanges
;
415 WND
*wndPrev
,*pDesktop
= WIN_GetDesktop();
417 if( !wndPtr
|| !X11DRV_WND_GetXWindow(wndPtr
) || (wndPtr
->flags
& WIN_MANAGED
) )
419 WIN_ReleaseDesktop();
423 /* Raise all windows up to wndPtr according to their Z order.
424 * (it would be easier with sibling-related Below but it doesn't
425 * work very well with SGI mwm for instance)
427 winChanges
.stack_mode
= Above
;
430 if (X11DRV_WND_GetXWindow(wndPtr
))
431 TSXReconfigureWMWindow( display
, X11DRV_WND_GetXWindow(wndPtr
), 0,
432 CWStackMode
, &winChanges
);
433 wndPrev
= pDesktop
->child
;
434 if (wndPrev
== wndPtr
) break;
435 while (wndPrev
&& (wndPrev
->next
!= wndPtr
)) wndPrev
= wndPrev
->next
;
438 WIN_ReleaseDesktop();
441 /***********************************************************************
442 * X11DRV_WND_FindDesktopXWindow [Internal]
444 * Find the actual X window which needs be restacked.
445 * Used by X11DRV_WND_SetWindowPos().
447 static Window
X11DRV_WND_FindDesktopXWindow( WND
*wndPtr
)
449 if (!(wndPtr
->flags
& WIN_MANAGED
))
450 return X11DRV_WND_GetXWindow(wndPtr
);
453 Window window
, root
, parent
, *children
;
455 window
= X11DRV_WND_GetXWindow(wndPtr
);
458 TSXQueryTree( display
, window
, &root
, &parent
,
459 &children
, &nchildren
);
468 /***********************************************************************
469 * WINPOS_SetXWindowPos
471 * SetWindowPos() for an X window. Used by the real SetWindowPos().
473 void X11DRV_WND_SetWindowPos(WND
*wndPtr
, const WINDOWPOS
*winpos
, BOOL bChangePos
)
475 XWindowChanges winChanges
;
477 WND
*winposPtr
= WIN_FindWndPtr( winpos
->hwnd
);
478 if ( !winposPtr
) return;
480 if(!wndPtr
->hwndSelf
) wndPtr
= NULL
; /* FIXME: WND destroyed, shouldn't happen!!! */
482 if (!(winpos
->flags
& SWP_SHOWWINDOW
) && (winpos
->flags
& SWP_HIDEWINDOW
))
484 if(X11DRV_WND_GetXWindow(wndPtr
))
485 TSXUnmapWindow( display
, X11DRV_WND_GetXWindow(wndPtr
) );
490 if ( !(winpos
->flags
& SWP_NOSIZE
))
492 winChanges
.width
= (winpos
->cx
> 0 ) ? winpos
->cx
: 1;
493 winChanges
.height
= (winpos
->cy
> 0 ) ? winpos
->cy
: 1;
494 changeMask
|= CWWidth
| CWHeight
;
496 /* Tweak dialog window size hints */
498 if ((winposPtr
->flags
& WIN_MANAGED
) &&
499 HAS_DLGFRAME(winposPtr
->dwStyle
,winposPtr
->dwExStyle
))
501 XSizeHints
*size_hints
= TSXAllocSizeHints();
505 long supplied_return
;
507 TSXGetWMSizeHints( display
, X11DRV_WND_GetXWindow(winposPtr
), size_hints
,
508 &supplied_return
, XA_WM_NORMAL_HINTS
);
509 size_hints
->min_width
= size_hints
->max_width
= winpos
->cx
;
510 size_hints
->min_height
= size_hints
->max_height
= winpos
->cy
;
511 TSXSetWMSizeHints( display
, X11DRV_WND_GetXWindow(winposPtr
), size_hints
,
512 XA_WM_NORMAL_HINTS
);
517 if (!(winpos
->flags
& SWP_NOMOVE
))
519 winChanges
.x
= winpos
->x
;
520 winChanges
.y
= winpos
->y
;
521 changeMask
|= CWX
| CWY
;
523 if (!(winpos
->flags
& SWP_NOZORDER
))
525 winChanges
.stack_mode
= Below
;
526 changeMask
|= CWStackMode
;
528 if (winpos
->hwndInsertAfter
== HWND_TOP
) winChanges
.stack_mode
= Above
;
529 else if (winpos
->hwndInsertAfter
!= HWND_BOTTOM
)
531 WND
* insertPtr
= WIN_FindWndPtr( winpos
->hwndInsertAfter
);
534 stack
[0] = X11DRV_WND_FindDesktopXWindow( insertPtr
);
535 stack
[1] = X11DRV_WND_FindDesktopXWindow( winposPtr
);
537 /* for stupid window managers (i.e. all of them) */
539 TSXRestackWindows(display
, stack
, 2);
540 changeMask
&= ~CWStackMode
;
542 WIN_ReleaseWndPtr(insertPtr
);
545 if (changeMask
&& X11DRV_WND_GetXWindow(winposPtr
))
547 TSXReconfigureWMWindow( display
, X11DRV_WND_GetXWindow(winposPtr
), 0, changeMask
, &winChanges
);
548 if( winposPtr
->class->style
& (CS_VREDRAW
| CS_HREDRAW
) )
549 X11DRV_WND_SetHostAttr( winposPtr
, HAK_BITGRAVITY
, BGForget
);
553 if ( winpos
->flags
& SWP_SHOWWINDOW
)
555 if(X11DRV_WND_GetXWindow(wndPtr
))
556 TSXMapWindow( display
, X11DRV_WND_GetXWindow(wndPtr
) );
558 WIN_ReleaseWndPtr(winposPtr
);
561 /*****************************************************************
564 void X11DRV_WND_SetText(WND
*wndPtr
, LPCSTR text
)
566 if (!X11DRV_WND_GetXWindow(wndPtr
))
569 TSXStoreName( display
, X11DRV_WND_GetXWindow(wndPtr
), text
);
570 TSXSetIconName( display
, X11DRV_WND_GetXWindow(wndPtr
), text
);
573 /*****************************************************************
574 * X11DRV_WND_SetFocus
577 * Explicit colormap management seems to work only with OLVWM.
579 void X11DRV_WND_SetFocus(WND
*wndPtr
)
581 HWND hwnd
= wndPtr
->hwndSelf
;
582 XWindowAttributes win_attr
;
585 /* Only mess with the X focus if there's */
586 /* no desktop window and if the window is not managed by the WM. */
587 if ((X11DRV_GetXRootWindow() != DefaultRootWindow(display
))
588 || (wndPtr
->flags
& WIN_MANAGED
)) return;
590 if (!hwnd
) /* If setting the focus to 0, uninstall the colormap */
592 if (X11DRV_PALETTE_PaletteFlags
& X11DRV_PALETTE_PRIVATE
)
593 TSXUninstallColormap( display
, X11DRV_PALETTE_PaletteXColormap
);
597 /* Set X focus and install colormap */
599 if (!(win
= X11DRV_WND_FindXWindow(wndPtr
))) return;
600 if (!TSXGetWindowAttributes( display
, win
, &win_attr
) ||
601 (win_attr
.map_state
!= IsViewable
))
602 return; /* If window is not viewable, don't change anything */
604 TSXSetInputFocus( display
, win
, RevertToParent
, CurrentTime
);
605 if (X11DRV_PALETTE_PaletteFlags
& X11DRV_PALETTE_PRIVATE
)
606 TSXInstallColormap( display
, X11DRV_PALETTE_PaletteXColormap
);
611 /*****************************************************************
612 * X11DRV_WND_PreSizeMove
614 void X11DRV_WND_PreSizeMove(WND
*wndPtr
)
616 if (!(wndPtr
->dwStyle
& WS_CHILD
) && (X11DRV_GetXRootWindow() == DefaultRootWindow(display
)))
617 TSXGrabServer( display
);
620 /*****************************************************************
621 * X11DRV_WND_PostSizeMove
623 void X11DRV_WND_PostSizeMove(WND
*wndPtr
)
625 if (!(wndPtr
->dwStyle
& WS_CHILD
) &&
626 (X11DRV_GetXRootWindow() == DefaultRootWindow(display
)))
627 TSXUngrabServer( display
);
630 /*****************************************************************
631 * X11DRV_WND_SurfaceCopy
633 * Copies rect to (rect.left + dx, rect.top + dy).
635 void X11DRV_WND_SurfaceCopy(WND
* wndPtr
, DC
*dcPtr
, INT dx
, INT dy
,
636 const RECT
*rect
, BOOL bUpdate
)
638 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dcPtr
->physDev
;
641 dst
.x
= (src
.x
= dcPtr
->w
.DCOrgX
+ rect
->left
) + dx
;
642 dst
.y
= (src
.y
= dcPtr
->w
.DCOrgY
+ rect
->top
) + dy
;
644 if (bUpdate
) /* handles non-Wine windows hanging over the copied area */
645 TSXSetGraphicsExposures( display
, physDev
->gc
, True
);
646 TSXSetFunction( display
, physDev
->gc
, GXcopy
);
647 TSXCopyArea( display
, physDev
->drawable
, physDev
->drawable
,
648 physDev
->gc
, src
.x
, src
.y
,
649 rect
->right
- rect
->left
,
650 rect
->bottom
- rect
->top
,
653 TSXSetGraphicsExposures( display
, physDev
->gc
, False
);
655 if (bUpdate
) /* Make sure exposure events have been processed */
659 /***********************************************************************
660 * X11DRV_WND_SetDrawable
662 * Set the drawable, origin and dimensions for the DC associated to
665 void X11DRV_WND_SetDrawable(WND
*wndPtr
, DC
*dc
, WORD flags
, BOOL bSetClipOrigin
)
667 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
668 INT dcOrgXCopy
= 0, dcOrgYCopy
= 0;
669 BOOL offsetClipRgn
= FALSE
;
671 if (!wndPtr
) /* Get a DC for the whole screen */
675 physDev
->drawable
= X11DRV_GetXRootWindow();
676 TSXSetSubwindowMode( display
, physDev
->gc
, IncludeInferiors
);
681 * This function change the coordinate system (DCOrgX,DCOrgY)
682 * values. When it moves the origin, other data like the current clipping
683 * region will not be moved to that new origin. In the case of DCs that are class
684 * or window DCs that clipping region might be a valid value from a previous use
685 * of the DC and changing the origin of the DC without moving the clip region
686 * results in a clip region that is not placed properly in the DC.
687 * This code will save the dc origin, let the SetDrawable
688 * modify the origin and reset the clipping. When the clipping is set,
689 * it is moved according to the new DC origin.
691 if ( (wndPtr
->class->style
& (CS_OWNDC
| CS_CLASSDC
)) && (dc
->w
.hClipRgn
> 0))
693 dcOrgXCopy
= dc
->w
.DCOrgX
;
694 dcOrgYCopy
= dc
->w
.DCOrgY
;
695 offsetClipRgn
= TRUE
;
698 if (flags
& DCX_WINDOW
)
700 dc
->w
.DCOrgX
= wndPtr
->rectWindow
.left
;
701 dc
->w
.DCOrgY
= wndPtr
->rectWindow
.top
;
705 dc
->w
.DCOrgX
= wndPtr
->rectClient
.left
;
706 dc
->w
.DCOrgY
= wndPtr
->rectClient
.top
;
708 while (!X11DRV_WND_GetXWindow(wndPtr
))
710 wndPtr
= wndPtr
->parent
;
711 dc
->w
.DCOrgX
+= wndPtr
->rectClient
.left
;
712 dc
->w
.DCOrgY
+= wndPtr
->rectClient
.top
;
714 dc
->w
.DCOrgX
-= wndPtr
->rectWindow
.left
;
715 dc
->w
.DCOrgY
-= wndPtr
->rectWindow
.top
;
717 /* reset the clip region, according to the new origin */
720 OffsetRgn(dc
->w
.hClipRgn
, dc
->w
.DCOrgX
- dcOrgXCopy
,dc
->w
.DCOrgY
- dcOrgYCopy
);
723 physDev
->drawable
= X11DRV_WND_GetXWindow(wndPtr
);
726 /* This is needed when we reuse a cached DC because
727 * SetDCState() called by ReleaseDC() screws up DC
728 * origins for child windows.
732 TSXSetClipOrigin( display
, physDev
->gc
, dc
->w
.DCOrgX
, dc
->w
.DCOrgY
);
737 /***********************************************************************
740 static BOOL
X11DRV_SetWMHint(Display
* display
, WND
* wndPtr
, int hint
, int val
)
742 XWMHints
* wm_hints
= TSXAllocWMHints();
744 wm_hints
->flags
= hint
;
748 wm_hints
->input
= val
;
752 wm_hints
->initial_state
= val
;
756 wm_hints
->icon_pixmap
= (Pixmap
)val
;
760 wm_hints
->icon_window
= (Window
)val
;
764 TSXSetWMHints( display
, X11DRV_WND_GetXWindow(wndPtr
), wm_hints
);
772 /***********************************************************************
773 * X11DRV_WND_SetHostAttr
775 * This function returns TRUE if the attribute is supported and the
776 * action was successful. Otherwise it should return FALSE and Wine will try
777 * to get by without the functionality provided by the host window system.
779 BOOL
X11DRV_WND_SetHostAttr(WND
* wnd
, INT ha
, INT value
)
783 if( (w
= X11DRV_WND_GetXWindow(wnd
)) )
785 XSetWindowAttributes win_attr
;
789 case HAK_ICONICSTATE
: /* called when a window is minimized/restored */
791 if( (wnd
->flags
& WIN_MANAGED
) )
795 if( wnd
->dwStyle
& WS_VISIBLE
)
797 XClientMessageEvent ev
;
799 /* FIXME: set proper icon */
801 ev
.type
= ClientMessage
;
802 ev
.display
= display
;
803 ev
.message_type
= wmChangeState
;
805 ev
.data
.l
[0] = IconicState
;
808 if( TSXSendEvent (display
,
809 RootWindow( display
, XScreenNumberOfScreen(X11DRV_GetXScreen()) ),
810 True
, (SubstructureRedirectMask
| SubstructureNotifyMask
), (XEvent
*)&ev
))
814 while( !TSXCheckTypedWindowEvent( display
, w
, UnmapNotify
, &xe
) );
820 X11DRV_SetWMHint( display
, wnd
, StateHint
, IconicState
);
824 if( !(wnd
->flags
& WS_VISIBLE
) )
825 X11DRV_SetWMHint( display
, wnd
, StateHint
, NormalState
);
829 TSXMapWindow(display
, w
);
830 while( !TSXCheckTypedWindowEvent( display
, w
, MapNotify
, &xe
) );
837 case HAK_BITGRAVITY
: /* called when a window is resized */
839 if( ((X11DRV_WND_DATA
*) wnd
->pDriverData
)->bit_gravity
!= value
)
841 win_attr
.bit_gravity
= value
;
842 ((X11DRV_WND_DATA
*) wnd
->pDriverData
)->bit_gravity
= value
;
843 TSXChangeWindowAttributes( display
, w
, CWBitGravity
, &win_attr
);
847 case HAK_ACCEPTFOCUS
: /* called when a window is disabled/enabled */
849 if( (wnd
->flags
& WIN_MANAGED
) )
850 return X11DRV_SetWMHint( display
, wnd
, InputHint
, value
);
856 /***********************************************************************
857 * X11DRV_WND_IsSelfClipping
859 BOOL
X11DRV_WND_IsSelfClipping(WND
*wndPtr
)
861 return X11DRV_WND_GetXWindow(wndPtr
) != None
;
864 /***********************************************************************
865 * X11DRV_WND_DockWindow
867 * Set the X Property of the window that tells the windowmanager we really
868 * want to be in the systray
870 * KDE: set "KWM_DOCKWINDOW", type "KWM_DOCKWINDOW" to 1 before a window is
873 * all others: to be added ;)
875 void X11DRV_WND_DockWindow(WND
*wndPtr
)
878 Window win
= X11DRV_WND_GetXWindow(wndPtr
);
879 if (kwmDockWindow
== None
)
880 return; /* no KDE running */
882 display
,win
,kwmDockWindow
,kwmDockWindow
,32,PropModeReplace
,(char*)&data
,1
885 #endif /* !defined(X_DISPLAY_MISSING) */