Revert last change in window activation on mouse click.
[wine/dcerpc.git] / windows / x11drv / wnd.c
blob96ed420d27278e70faded807959ab12a1341f656
1 /*
2 * X11 windows driver
4 * Copyright 1993, 1994, 1995, 1996 Alexandre Julliard
5 * 1993 David Metcalfe
6 * 1995, 1996 Alex Korobka
7 */
9 #include "config.h"
11 #ifndef X_DISPLAY_MISSING
13 #include <X11/Xatom.h>
14 #include "ts_xlib.h"
15 #include "ts_xutil.h"
17 #include <stdlib.h>
18 #include <string.h>
19 #include "bitmap.h"
20 #include "color.h"
21 #include "debugtools.h"
22 #include "display.h"
23 #include "dce.h"
24 #include "options.h"
25 #include "message.h"
26 #include "heap.h"
27 #include "win.h"
28 #include "windef.h"
29 #include "class.h"
30 #include "x11drv.h"
31 #include "wine/winuser16.h"
33 DEFAULT_DEBUG_CHANNEL(win)
35 /**********************************************************************/
37 extern Cursor X11DRV_MOUSE_XCursor; /* Current X cursor */
38 extern BOOL X11DRV_CreateBitmap( HBITMAP );
39 extern Pixmap X11DRV_BITMAP_Pixmap( HBITMAP );
41 /**********************************************************************/
43 /* X context to associate a hwnd to an X window */
44 XContext winContext = 0;
46 Atom wmProtocols = None;
47 Atom wmDeleteWindow = None;
48 Atom dndProtocol = None;
49 Atom dndSelection = None;
50 Atom wmChangeState = None;
52 /***********************************************************************
53 * X11DRV_WND_GetXWindow
55 * Return the X window associated to a window.
57 Window X11DRV_WND_GetXWindow(WND *wndPtr)
59 return wndPtr && wndPtr->pDriverData ?
60 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
63 /***********************************************************************
64 * X11DRV_WND_FindXWindow
66 * Return the the first X window associated to a window chain.
68 Window X11DRV_WND_FindXWindow(WND *wndPtr)
70 while (wndPtr &&
71 !((X11DRV_WND_DATA *) wndPtr->pDriverData)->window)
72 wndPtr = wndPtr->parent;
73 return wndPtr ?
74 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0;
77 /***********************************************************************
78 * X11DRV_WND_GetXScreen
80 * Return the X screen associated to the window.
82 Screen *X11DRV_WND_GetXScreen(WND *wndPtr)
84 while(wndPtr->parent) wndPtr = wndPtr->parent;
85 return X11DRV_DESKTOP_GetXScreen((struct tagDESKTOP *) wndPtr->wExtra);
88 /***********************************************************************
89 * X11DRV_WND_GetXRootWindow
91 * Return the X display associated to the window.
93 Window X11DRV_WND_GetXRootWindow(WND *wndPtr)
95 while(wndPtr->parent) wndPtr = wndPtr->parent;
96 return X11DRV_DESKTOP_GetXRootWindow((struct tagDESKTOP *) wndPtr->wExtra);
99 /***********************************************************************
100 * X11DRV_WND_RegisterWindow
102 * Associate an X window to a HWND.
104 static void X11DRV_WND_RegisterWindow(WND *wndPtr)
106 TSXSetWMProtocols( display, X11DRV_WND_GetXWindow(wndPtr), &wmDeleteWindow, 1 );
108 if (!winContext) winContext = TSXUniqueContext();
109 TSXSaveContext( display, X11DRV_WND_GetXWindow(wndPtr),
110 winContext, (char *) wndPtr->hwndSelf );
113 /**********************************************************************
114 * X11DRV_WND_Initialize
116 void X11DRV_WND_Initialize(WND *wndPtr)
118 X11DRV_WND_DATA *pWndDriverData =
119 (X11DRV_WND_DATA *) HeapAlloc(SystemHeap, 0, sizeof(X11DRV_WND_DATA));
121 wndPtr->pDriverData = (void *) pWndDriverData;
123 pWndDriverData->window = 0;
126 /**********************************************************************
127 * X11DRV_WND_Finalize
129 void X11DRV_WND_Finalize(WND *wndPtr)
131 X11DRV_WND_DATA *pWndDriverData =
132 (X11DRV_WND_DATA *) wndPtr->pDriverData;
134 if (!wndPtr->pDriverData) {
135 ERR("Trying to destroy window again. Not good.\n");
136 return;
138 if(pWndDriverData->window)
140 ERR(
141 "WND destroyed without destroying "
142 "the associated X Window (%ld)\n",
143 pWndDriverData->window
146 HeapFree(SystemHeap, 0, wndPtr->pDriverData);
147 wndPtr->pDriverData = NULL;
150 /**********************************************************************
151 * X11DRV_WND_CreateDesktopWindow
153 BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode)
155 if (wmProtocols == None)
156 wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True );
157 if (wmDeleteWindow == None)
158 wmDeleteWindow = TSXInternAtom( display, "WM_DELETE_WINDOW", True );
159 if( dndProtocol == None )
160 dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
161 if( dndSelection == None )
162 dndSelection = TSXInternAtom( display, "DndSelection" , False );
163 if( wmChangeState == None )
164 wmChangeState = TSXInternAtom (display, "WM_CHANGE_STATE", False);
166 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window =
167 X11DRV_WND_GetXRootWindow( wndPtr );
168 X11DRV_WND_RegisterWindow( wndPtr );
170 return TRUE;
174 /**********************************************************************
175 * X11DRV_WND_CreateWindow
177 BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BOOL bUnicode)
179 /* Create the X window (only for top-level windows, and then only */
180 /* when there's no desktop window) */
182 if (!(cs->style & WS_CHILD) &&
183 (X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display)))
185 Window wGroupLeader;
186 XWMHints* wm_hints;
187 XSetWindowAttributes win_attr;
189 /* Create "managed" windows only if a title bar or resizable */
190 /* frame is required. */
191 if (Options.managed && ( ((cs->style & WS_CAPTION) == WS_CAPTION) ||
192 (cs->style & WS_THICKFRAME) ||
193 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
195 win_attr.event_mask = ExposureMask | KeyPressMask |
196 KeyReleaseMask | PointerMotionMask |
197 ButtonPressMask | ButtonReleaseMask |
198 FocusChangeMask | StructureNotifyMask;
199 win_attr.override_redirect = FALSE;
200 wndPtr->flags |= WIN_MANAGED;
202 else
204 win_attr.event_mask = ExposureMask | KeyPressMask |
205 KeyReleaseMask | PointerMotionMask |
206 ButtonPressMask | ButtonReleaseMask |
207 FocusChangeMask;
208 win_attr.override_redirect = TRUE;
210 wndPtr->flags |= WIN_NATIVE;
212 win_attr.bit_gravity = (classPtr->style & (CS_VREDRAW | CS_HREDRAW)) ? BGForget : BGNorthWest;
213 win_attr.colormap = X11DRV_PALETTE_PaletteXColormap;
214 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
215 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
216 win_attr.cursor = X11DRV_MOUSE_XCursor;
218 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
219 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = win_attr.bit_gravity;
220 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window =
221 TSXCreateWindow( display,
222 X11DRV_WND_GetXRootWindow(wndPtr),
223 cs->x, cs->y, cs->cx, cs->cy,
224 0, CopyFromParent,
225 InputOutput, CopyFromParent,
226 CWEventMask | CWOverrideRedirect |
227 CWColormap | CWCursor | CWSaveUnder |
228 CWBackingStore | CWBitGravity,
229 &win_attr );
231 if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
232 return FALSE;
234 if (wndPtr->flags & WIN_MANAGED)
236 XClassHint *class_hints = TSXAllocClassHint();
237 XSizeHints* size_hints = TSXAllocSizeHints();
239 if (class_hints)
241 class_hints->res_name = "wineManaged";
242 class_hints->res_class = "Wine";
243 TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints );
244 TSXFree (class_hints);
247 if (size_hints)
249 size_hints->win_gravity = StaticGravity;
250 size_hints->flags = PWinGravity;
252 if (cs->dwExStyle & WS_EX_DLGMODALFRAME)
254 size_hints->min_width = size_hints->max_width = cs->cx;
255 size_hints->min_height = size_hints->max_height = cs->cy;
256 size_hints->flags |= PMinSize | PMaxSize;
259 TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr),
260 size_hints, XA_WM_NORMAL_HINTS );
261 TSXFree(size_hints);
265 if (cs->hwndParent) /* Get window owner */
267 Window w;
268 WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
270 w = X11DRV_WND_FindXWindow( tmpWnd );
271 if (w != None)
273 TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w );
274 wGroupLeader = w;
276 WIN_ReleaseWndPtr(tmpWnd);
279 wm_hints = TSXAllocWMHints();
281 wm_hints->flags = InputHint | StateHint | WindowGroupHint;
282 wm_hints->input = True;
284 if( wndPtr->flags & WIN_MANAGED )
286 if( wndPtr->class->hIcon )
288 CURSORICONINFO *ptr;
290 if( (ptr = (CURSORICONINFO *)GlobalLock16( wndPtr->class->hIcon )) )
292 /* This is not entirely correct, may need to create
293 * an icon window and set the pixmap as a background */
295 HBITMAP hBitmap = CreateBitmap( ptr->nWidth, ptr->nHeight,
296 ptr->bPlanes, ptr->bBitsPerPixel, (char *)(ptr + 1) +
297 ptr->nHeight * BITMAP_GetWidthBytes(ptr->nWidth,1) );
299 if( hBitmap )
301 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = hBitmap;
302 X11DRV_CreateBitmap( hBitmap );
303 wm_hints->flags |= IconPixmapHint;
304 wm_hints->icon_pixmap = X11DRV_BITMAP_Pixmap( hBitmap );
308 wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE)
309 ? IconicState : NormalState;
311 else
312 wm_hints->initial_state = NormalState;
313 wm_hints->window_group = wGroupLeader;
315 TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
316 TSXFree(wm_hints);
318 X11DRV_WND_RegisterWindow( wndPtr );
320 return TRUE;
323 /***********************************************************************
324 * X11DRV_WND_DestroyWindow
326 BOOL X11DRV_WND_DestroyWindow(WND *wndPtr)
328 Window w;
329 if ((w = X11DRV_WND_GetXWindow(wndPtr)))
331 XEvent xe;
332 TSXDeleteContext( display, w, winContext );
333 TSXDestroyWindow( display, w );
334 while( TSXCheckWindowEvent(display, w, NoEventMask, &xe) );
336 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
337 if( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap )
339 DeleteObject( ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap );
340 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0;
344 return TRUE;
347 /*****************************************************************
348 * X11DRV_WND_SetParent
350 WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent)
352 WND *pDesktop = WIN_GetDesktop();
354 if( wndPtr && pWndParent && (wndPtr != pDesktop) )
356 WND* pWndPrev = wndPtr->parent;
358 if( pWndParent != pWndPrev )
360 if ( X11DRV_WND_GetXWindow(wndPtr) )
362 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
364 TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
365 ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None;
368 WIN_UnlinkWindow(wndPtr->hwndSelf);
369 wndPtr->parent = pWndParent;
371 /* Create an X counterpart for reparented top-level windows
372 * when not in the desktop mode. */
374 if( pWndParent == pDesktop )
376 wndPtr->dwStyle &= ~WS_CHILD;
377 wndPtr->wIDmenu = 0;
378 if( X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display) )
380 CREATESTRUCTA cs;
381 cs.lpCreateParams = NULL;
382 cs.hInstance = 0; /* not used if following call */
383 cs.hMenu = 0; /* not used in following call */
384 cs.hwndParent = pWndParent->hwndSelf;
385 cs.cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
386 if (!cs.cy)
387 cs.cy = 1;
388 cs.cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
389 if (!cs.cx)
390 cs.cx = 1;
391 cs.y = wndPtr->rectWindow.top;
392 cs.x = wndPtr->rectWindow.left;
393 cs.style = wndPtr->dwStyle;
394 cs.lpszName = 0; /* not used in following call */
395 cs.lpszClass = 0; /*not used in following call */
396 cs.dwExStyle = wndPtr->dwExStyle;
397 X11DRV_WND_CreateWindow(wndPtr, wndPtr->class,
398 &cs, FALSE);
401 else /* a child window */
403 if( !( wndPtr->dwStyle & WS_CHILD ) )
405 wndPtr->dwStyle |= WS_CHILD;
406 if( wndPtr->wIDmenu != 0)
408 DestroyMenu( (HMENU) wndPtr->wIDmenu );
409 wndPtr->wIDmenu = 0;
413 WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
415 WIN_ReleaseDesktop();
416 return pWndPrev;
417 } /* failure */
418 WIN_ReleaseDesktop();
419 return 0;
422 /***********************************************************************
423 * X11DRV_WND_ForceWindowRaise
425 * Raise a window on top of the X stacking order, while preserving
426 * the correct Windows Z order.
428 void X11DRV_WND_ForceWindowRaise(WND *wndPtr)
430 XWindowChanges winChanges;
431 WND *wndPrev,*pDesktop = WIN_GetDesktop();
433 if( !wndPtr || !X11DRV_WND_GetXWindow(wndPtr) || (wndPtr->flags & WIN_MANAGED) )
435 WIN_ReleaseDesktop();
436 return;
439 /* Raise all windows up to wndPtr according to their Z order.
440 * (it would be easier with sibling-related Below but it doesn't
441 * work very well with SGI mwm for instance)
443 winChanges.stack_mode = Above;
444 while (wndPtr)
446 if (X11DRV_WND_GetXWindow(wndPtr))
447 TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(wndPtr), 0,
448 CWStackMode, &winChanges );
449 wndPrev = pDesktop->child;
450 if (wndPrev == wndPtr) break;
451 while (wndPrev && (wndPrev->next != wndPtr)) wndPrev = wndPrev->next;
452 wndPtr = wndPrev;
454 WIN_ReleaseDesktop();
457 /***********************************************************************
458 * X11DRV_WND_FindDesktopXWindow [Internal]
460 * Find the actual X window which needs be restacked.
461 * Used by X11DRV_SetWindowPos().
463 static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr )
465 if (!(wndPtr->flags & WIN_MANAGED))
466 return X11DRV_WND_GetXWindow(wndPtr);
467 else
469 Window window, root, parent, *children;
470 int nchildren;
471 window = X11DRV_WND_GetXWindow(wndPtr);
472 for (;;)
474 TSXQueryTree( display, window, &root, &parent,
475 &children, &nchildren );
476 TSXFree( children );
477 if (parent == root)
478 return window;
479 window = parent;
484 /***********************************************************************
485 * WINPOS_SetXWindowPos
487 * SetWindowPos() for an X window. Used by the real SetWindowPos().
489 void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangePos)
491 XWindowChanges winChanges;
492 int changeMask = 0;
493 WND *winposPtr = WIN_FindWndPtr( winpos->hwnd );
494 if ( !winposPtr ) return;
496 if(!wndPtr->hwndSelf) wndPtr = NULL; /* FIXME: WND destroyed, shouldn't happend!!! */
498 if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW))
500 if(X11DRV_WND_GetXWindow(wndPtr))
501 TSXUnmapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
504 if(bChangePos)
506 if ( !(winpos->flags & SWP_NOSIZE))
508 winChanges.width = (winpos->cx > 0 ) ? winpos->cx : 1;
509 winChanges.height = (winpos->cy > 0 ) ? winpos->cy : 1;
510 changeMask |= CWWidth | CWHeight;
512 /* Tweak dialog window size hints */
514 if ((winposPtr->flags & WIN_MANAGED) &&
515 (winposPtr->dwExStyle & WS_EX_DLGMODALFRAME))
517 XSizeHints *size_hints = TSXAllocSizeHints();
519 if (size_hints)
521 long supplied_return;
523 TSXGetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints,
524 &supplied_return, XA_WM_NORMAL_HINTS);
525 size_hints->min_width = size_hints->max_width = winpos->cx;
526 size_hints->min_height = size_hints->max_height = winpos->cy;
527 TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints,
528 XA_WM_NORMAL_HINTS );
529 TSXFree(size_hints);
533 if (!(winpos->flags & SWP_NOMOVE))
535 winChanges.x = winpos->x;
536 winChanges.y = winpos->y;
537 changeMask |= CWX | CWY;
539 if (!(winpos->flags & SWP_NOZORDER))
541 winChanges.stack_mode = Below;
542 changeMask |= CWStackMode;
544 if (winpos->hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
545 else if (winpos->hwndInsertAfter != HWND_BOTTOM)
547 WND* insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter );
548 Window stack[2];
550 stack[0] = X11DRV_WND_FindDesktopXWindow( insertPtr );
551 stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr );
553 /* for stupid window managers (i.e. all of them) */
555 TSXRestackWindows(display, stack, 2);
556 changeMask &= ~CWStackMode;
558 WIN_ReleaseWndPtr(insertPtr);
561 if (changeMask && X11DRV_WND_GetXWindow(winposPtr))
563 TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges );
564 if( winposPtr->class->style & (CS_VREDRAW | CS_HREDRAW) )
565 X11DRV_WND_SetHostAttr( winposPtr, HAK_BITGRAVITY, BGForget );
569 if ( winpos->flags & SWP_SHOWWINDOW )
571 if(X11DRV_WND_GetXWindow(wndPtr))
572 TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) );
574 WIN_ReleaseWndPtr(winposPtr);
577 /*****************************************************************
578 * X11DRV_WND_SetText
580 void X11DRV_WND_SetText(WND *wndPtr, LPCSTR text)
582 if (!X11DRV_WND_GetXWindow(wndPtr))
583 return;
585 TSXStoreName( display, X11DRV_WND_GetXWindow(wndPtr), text );
586 TSXSetIconName( display, X11DRV_WND_GetXWindow(wndPtr), text );
589 /*****************************************************************
590 * X11DRV_WND_SetFocus
592 * Set the X focus.
593 * Explicit colormap management seems to work only with OLVWM.
595 void X11DRV_WND_SetFocus(WND *wndPtr)
597 HWND hwnd = wndPtr->hwndSelf;
598 XWindowAttributes win_attr;
599 Window win;
601 /* Only mess with the X focus if there's */
602 /* no desktop window and no window manager. */
603 if ((X11DRV_WND_GetXRootWindow(wndPtr) != DefaultRootWindow(display))
604 || Options.managed) return;
606 if (!hwnd) /* If setting the focus to 0, uninstall the colormap */
608 if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
609 TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
610 return;
613 /* Set X focus and install colormap */
615 if (!(win = X11DRV_WND_FindXWindow(wndPtr))) return;
616 if (!TSXGetWindowAttributes( display, win, &win_attr ) ||
617 (win_attr.map_state != IsViewable))
618 return; /* If window is not viewable, don't change anything */
620 TSXSetInputFocus( display, win, RevertToParent, CurrentTime );
621 if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE)
622 TSXInstallColormap( display, X11DRV_PALETTE_PaletteXColormap );
624 EVENT_Synchronize();
627 /*****************************************************************
628 * X11DRV_WND_PreSizeMove
630 void X11DRV_WND_PreSizeMove(WND *wndPtr)
632 if (!(wndPtr->dwStyle & WS_CHILD) &&
633 (X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display)))
634 TSXGrabServer( display );
637 /*****************************************************************
638 * X11DRV_WND_PostSizeMove
640 void X11DRV_WND_PostSizeMove(WND *wndPtr)
642 if (!(wndPtr->dwStyle & WS_CHILD) &&
643 (X11DRV_GetXRootWindow() == DefaultRootWindow(display)))
644 TSXUngrabServer( display );
647 /*****************************************************************
648 * X11DRV_WND_SurfaceCopy
650 * Copies rect to (rect.left + dx, rect.top + dy).
652 void X11DRV_WND_SurfaceCopy(WND* wndPtr, DC *dcPtr, INT dx, INT dy,
653 const RECT *rect, BOOL bUpdate)
655 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcPtr->physDev;
656 POINT dst, src;
658 dst.x = (src.x = dcPtr->w.DCOrgX + rect->left) + dx;
659 dst.y = (src.y = dcPtr->w.DCOrgY + rect->top) + dy;
661 if (bUpdate) /* handles non-Wine windows hanging over the copied area */
662 TSXSetGraphicsExposures( display, physDev->gc, True );
663 TSXSetFunction( display, physDev->gc, GXcopy );
664 TSXCopyArea( display, physDev->drawable, physDev->drawable,
665 physDev->gc, src.x, src.y,
666 rect->right - rect->left,
667 rect->bottom - rect->top,
668 dst.x, dst.y );
669 if (bUpdate)
670 TSXSetGraphicsExposures( display, physDev->gc, False );
672 if (bUpdate) /* Make sure exposure events have been processed */
673 EVENT_Synchronize();
676 /***********************************************************************
677 * X11DRV_WND_SetDrawable
679 * Set the drawable, origin and dimensions for the DC associated to
680 * a given window.
682 void X11DRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL bSetClipOrigin)
684 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
686 if (!wndPtr) /* Get a DC for the whole screen */
688 dc->w.DCOrgX = 0;
689 dc->w.DCOrgY = 0;
690 physDev->drawable = X11DRV_WND_GetXRootWindow(wndPtr);
691 TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors );
693 else
695 if (flags & DCX_WINDOW)
697 dc->w.DCOrgX = wndPtr->rectWindow.left;
698 dc->w.DCOrgY = wndPtr->rectWindow.top;
700 else
702 dc->w.DCOrgX = wndPtr->rectClient.left;
703 dc->w.DCOrgY = wndPtr->rectClient.top;
705 while (!X11DRV_WND_GetXWindow(wndPtr))
707 wndPtr = wndPtr->parent;
708 dc->w.DCOrgX += wndPtr->rectClient.left;
709 dc->w.DCOrgY += wndPtr->rectClient.top;
711 dc->w.DCOrgX -= wndPtr->rectWindow.left;
712 dc->w.DCOrgY -= wndPtr->rectWindow.top;
713 physDev->drawable = X11DRV_WND_GetXWindow(wndPtr);
715 #if 0
716 /* This is needed when we reuse a cached DC because
717 * SetDCState() called by ReleaseDC() screws up DC
718 * origins for child windows.
721 if( bSetClipOrigin )
722 TSXSetClipOrigin( display, physDev->gc, dc->w.DCOrgX, dc->w.DCOrgY );
723 #endif
727 /***********************************************************************
728 * X11DRV_SetWMHint
730 static BOOL X11DRV_SetWMHint(Display* display, WND* wndPtr, int hint, int val)
732 XWMHints* wm_hints = TSXAllocWMHints();
734 wm_hints->flags = hint;
735 switch( hint )
737 case InputHint:
738 wm_hints->input = val;
739 break;
741 case StateHint:
742 wm_hints->initial_state = val;
743 break;
745 case IconPixmapHint:
746 wm_hints->icon_pixmap = (Pixmap)val;
747 break;
749 case IconWindowHint:
750 wm_hints->icon_window = (Window)val;
751 break;
754 TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
755 TSXFree(wm_hints);
756 return TRUE;
758 return FALSE;
762 /***********************************************************************
763 * X11DRV_WND_SetHostAttr
765 * This function returns TRUE if the attribute is supported and the
766 * action was successful. Otherwise it should return FALSE and Wine will try
767 * to get by without the functionality provided by the host window system.
769 BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value)
771 Window w;
773 if( (w = X11DRV_WND_GetXWindow(wnd)) )
775 XSetWindowAttributes win_attr;
777 switch( ha )
779 case HAK_ICONICSTATE: /* called when a window is minimized/restored */
781 if( (wnd->flags & WIN_MANAGED) )
783 if( value )
785 if( wnd->dwStyle & WS_VISIBLE )
787 XClientMessageEvent ev;
789 /* FIXME: set proper icon */
791 ev.type = ClientMessage;
792 ev.display = display;
793 ev.message_type = wmChangeState;
794 ev.format = 32;
795 ev.data.l[0] = IconicState;
796 ev.window = w;
798 if( TSXSendEvent (display,
799 RootWindow( display, XScreenNumberOfScreen(X11DRV_WND_GetXScreen(wnd)) ),
800 True, (SubstructureRedirectMask | SubstructureNotifyMask), (XEvent*)&ev))
802 XEvent xe;
803 TSXFlush (display);
804 while( !TSXCheckTypedWindowEvent( display, w, UnmapNotify, &xe) );
806 else
807 break;
809 else
810 X11DRV_SetWMHint( display, wnd, StateHint, IconicState );
812 else
814 if( !(wnd->flags & WS_VISIBLE) )
815 X11DRV_SetWMHint( display, wnd, StateHint, NormalState );
816 else
818 XEvent xe;
819 TSXMapWindow(display, w );
820 while( !TSXCheckTypedWindowEvent( display, w, MapNotify, &xe) );
823 return TRUE;
825 break;
827 case HAK_BITGRAVITY: /* called when a window is resized */
829 if( ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity != value )
831 win_attr.bit_gravity = value;
832 ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity = value;
833 TSXChangeWindowAttributes( display, w, CWBitGravity, &win_attr );
835 return TRUE;
837 case HAK_ACCEPTFOCUS: /* called when a window is disabled/enabled */
839 if( (wnd->flags & WIN_MANAGED) )
840 return X11DRV_SetWMHint( display, wnd, InputHint, value );
843 return FALSE;
846 /***********************************************************************
847 * X11DRV_WND_IsSelfClipping
849 BOOL X11DRV_WND_IsSelfClipping(WND *wndPtr)
851 return X11DRV_WND_GetXWindow(wndPtr) != None;
854 #endif /* !defined(X_DISPLAY_MISSING) */