Spelling fixes.
[wine/multimedia.git] / windows / x11drv / wnd.c
blobe6ab3707c905a6ff390f9646d984b40325dcf622
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 "windef.h"
32 #include "wingdi.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)
78 while (wndPtr &&
79 !((X11DRV_WND_DATA *) wndPtr->pDriverData)->window)
80 wndPtr = wndPtr->parent;
81 return wndPtr ?
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");
144 return;
146 if(pWndDriverData->window)
148 ERR(
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 );
180 return TRUE;
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)))
195 Window wGroupLeader;
196 XWMHints* wm_hints;
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;
208 } else {
209 win_attr.event_mask = ExposureMask | KeyPressMask |
210 KeyReleaseMask | PointerMotionMask |
211 ButtonPressMask | ButtonReleaseMask |
212 FocusChangeMask;
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,
229 0, CopyFromParent,
230 InputOutput, CopyFromParent,
231 CWEventMask | CWOverrideRedirect |
232 CWColormap | CWCursor | CWSaveUnder |
233 CWBackingStore | CWBitGravity,
234 &win_attr );
236 if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr)))
237 return FALSE;
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();
249 if (class_hints)
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);
257 if (size_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 );
271 TSXFree(size_hints);
275 if (cs->hwndParent) /* Get window owner */
277 Window w;
278 WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
280 w = X11DRV_WND_FindXWindow( tmpWnd );
281 if (w != None)
283 TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w );
284 wGroupLeader = 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 )
298 CURSORICONINFO *ptr;
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) );
309 if( hBitmap )
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;
321 else
322 wm_hints->initial_state = NormalState;
323 wm_hints->window_group = wGroupLeader;
325 TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
326 TSXFree(wm_hints);
328 X11DRV_WND_RegisterWindow( wndPtr );
330 return TRUE;
333 /***********************************************************************
334 * X11DRV_WND_DestroyWindow
336 BOOL X11DRV_WND_DestroyWindow(WND *wndPtr)
338 Window w;
339 if ((w = X11DRV_WND_GetXWindow(wndPtr)))
341 XEvent xe;
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;
354 return TRUE;
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;
387 wndPtr->wIDmenu = 0;
388 if( X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display) )
390 CREATESTRUCTA cs;
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;
396 if (!cs.cy)
397 cs.cy = 1;
398 cs.cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
399 if (!cs.cx)
400 cs.cx = 1;
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,
408 &cs, FALSE);
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 );
419 wndPtr->wIDmenu = 0;
423 WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
425 WIN_ReleaseDesktop();
426 return pWndPrev;
427 } /* failure */
428 WIN_ReleaseDesktop();
429 return 0;
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();
446 return;
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;
454 while (wndPtr)
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;
462 wndPtr = wndPrev;
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);
477 else
479 Window window, root, parent, *children;
480 int nchildren;
481 window = X11DRV_WND_GetXWindow(wndPtr);
482 for (;;)
484 TSXQueryTree( display, window, &root, &parent,
485 &children, &nchildren );
486 TSXFree( children );
487 if (parent == root)
488 return window;
489 window = parent;
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;
502 int changeMask = 0;
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) );
514 if(bChangePos)
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();
529 if (size_hints)
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 );
539 TSXFree(size_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 );
558 Window stack[2];
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 /*****************************************************************
588 * X11DRV_WND_SetText
590 void X11DRV_WND_SetText(WND *wndPtr, LPCSTR text)
592 if (!X11DRV_WND_GetXWindow(wndPtr))
593 return;
595 TSXStoreName( display, X11DRV_WND_GetXWindow(wndPtr), text );
596 TSXSetIconName( display, X11DRV_WND_GetXWindow(wndPtr), text );
599 /*****************************************************************
600 * X11DRV_WND_SetFocus
602 * Set the X focus.
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;
609 Window win;
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 );
620 return;
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 );
634 EVENT_Synchronize();
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;
666 POINT dst, src;
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,
678 dst.x, dst.y );
679 if (bUpdate)
680 TSXSetGraphicsExposures( display, physDev->gc, False );
682 if (bUpdate) /* Make sure exposure events have been processed */
683 EVENT_Synchronize();
686 /***********************************************************************
687 * X11DRV_WND_SetDrawable
689 * Set the drawable, origin and dimensions for the DC associated to
690 * a given window.
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 */
700 dc->w.DCOrgX = 0;
701 dc->w.DCOrgY = 0;
702 physDev->drawable = X11DRV_WND_GetXRootWindow(wndPtr);
703 TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors );
705 else
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;
730 else
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 */
745 if ( offsetClipRgn )
747 OffsetRgn(dc->w.hClipRgn, dc->w.DCOrgX - dcOrgXCopy,dc->w.DCOrgY - dcOrgYCopy);
750 physDev->drawable = X11DRV_WND_GetXWindow(wndPtr);
752 #if 0
753 /* This is needed when we reuse a cached DC because
754 * SetDCState() called by ReleaseDC() screws up DC
755 * origins for child windows.
758 if( bSetClipOrigin )
759 TSXSetClipOrigin( display, physDev->gc, dc->w.DCOrgX, dc->w.DCOrgY );
760 #endif
764 /***********************************************************************
765 * X11DRV_SetWMHint
767 static BOOL X11DRV_SetWMHint(Display* display, WND* wndPtr, int hint, int val)
769 XWMHints* wm_hints = TSXAllocWMHints();
771 wm_hints->flags = hint;
772 switch( hint )
774 case InputHint:
775 wm_hints->input = val;
776 break;
778 case StateHint:
779 wm_hints->initial_state = val;
780 break;
782 case IconPixmapHint:
783 wm_hints->icon_pixmap = (Pixmap)val;
784 break;
786 case IconWindowHint:
787 wm_hints->icon_window = (Window)val;
788 break;
791 TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints );
792 TSXFree(wm_hints);
793 return TRUE;
795 return FALSE;
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)
808 Window w;
810 if( (w = X11DRV_WND_GetXWindow(wnd)) )
812 XSetWindowAttributes win_attr;
814 switch( ha )
816 case HAK_ICONICSTATE: /* called when a window is minimized/restored */
818 if( (wnd->flags & WIN_MANAGED) )
820 if( value )
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;
831 ev.format = 32;
832 ev.data.l[0] = IconicState;
833 ev.window = w;
835 if( TSXSendEvent (display,
836 RootWindow( display, XScreenNumberOfScreen(X11DRV_WND_GetXScreen(wnd)) ),
837 True, (SubstructureRedirectMask | SubstructureNotifyMask), (XEvent*)&ev))
839 XEvent xe;
840 TSXFlush (display);
841 while( !TSXCheckTypedWindowEvent( display, w, UnmapNotify, &xe) );
843 else
844 break;
846 else
847 X11DRV_SetWMHint( display, wnd, StateHint, IconicState );
849 else
851 if( !(wnd->flags & WS_VISIBLE) )
852 X11DRV_SetWMHint( display, wnd, StateHint, NormalState );
853 else
855 XEvent xe;
856 TSXMapWindow(display, w );
857 while( !TSXCheckTypedWindowEvent( display, w, MapNotify, &xe) );
860 return TRUE;
862 break;
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 );
872 return TRUE;
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 );
880 return FALSE;
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
898 * mapped.
900 * all others: to be added ;)
902 void X11DRV_WND_DockWindow(WND *wndPtr)
904 int data = 1;
905 Window win = X11DRV_WND_GetXWindow(wndPtr);
906 if (kwmDockWindow == None)
907 return; /* no KDE running */
908 TSXChangeProperty(
909 display,win,kwmDockWindow,kwmDockWindow,32,PropModeReplace,(char*)&data,1
912 #endif /* !defined(X_DISPLAY_MISSING) */