Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 1 | /* |
| 2 | * X11 windows driver |
| 3 | * |
| 4 | * Copyright 1993, 1994, 1995, 1996 Alexandre Julliard |
| 5 | * 1993 David Metcalfe |
| 6 | * 1995, 1996 Alex Korobka |
| 7 | */ |
| 8 | |
| 9 | #include "config.h" |
| 10 | |
| 11 | #ifndef X_DISPLAY_MISSING |
| 12 | |
| 13 | #include <X11/Xatom.h> |
| 14 | #include "ts_xlib.h" |
| 15 | #include "ts_xutil.h" |
| 16 | |
| 17 | #include <stdlib.h> |
| 18 | #include <string.h> |
| 19 | #include "color.h" |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 20 | #include "debug.h" |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 21 | #include "display.h" |
| 22 | #include "dce.h" |
| 23 | #include "options.h" |
| 24 | #include "message.h" |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 25 | #include "heap.h" |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 26 | #include "win.h" |
Jim Aston | 2e1cafa | 1999-03-14 16:35:05 +0000 | [diff] [blame] | 27 | #include "windef.h" |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 28 | #include "class.h" |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 29 | #include "x11drv.h" |
| 30 | |
| 31 | /**********************************************************************/ |
| 32 | |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 33 | extern Cursor X11DRV_MOUSE_XCursor; /* Current X cursor */ |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 34 | |
| 35 | /**********************************************************************/ |
| 36 | |
| 37 | /* X context to associate a hwnd to an X window */ |
| 38 | XContext winContext = 0; |
| 39 | |
| 40 | Atom wmProtocols = None; |
| 41 | Atom wmDeleteWindow = None; |
| 42 | Atom dndProtocol = None; |
| 43 | Atom dndSelection = None; |
| 44 | |
| 45 | /*********************************************************************** |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 46 | * X11DRV_WND_GetXWindow |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 47 | * |
| 48 | * Return the X window associated to a window. |
| 49 | */ |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 50 | Window X11DRV_WND_GetXWindow(WND *wndPtr) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 51 | { |
Ulrich Weigand | 4aaf65e | 1999-02-18 17:30:40 +0000 | [diff] [blame] | 52 | return wndPtr && wndPtr->pDriverData ? |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 53 | ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0; |
| 54 | } |
| 55 | |
| 56 | /*********************************************************************** |
| 57 | * X11DRV_WND_FindXWindow |
| 58 | * |
| 59 | * Return the the first X window associated to a window chain. |
| 60 | */ |
| 61 | Window X11DRV_WND_FindXWindow(WND *wndPtr) |
| 62 | { |
| 63 | while (wndPtr && |
| 64 | !((X11DRV_WND_DATA *) wndPtr->pDriverData)->window) |
| 65 | wndPtr = wndPtr->parent; |
| 66 | return wndPtr ? |
| 67 | ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window : 0; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | /*********************************************************************** |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 71 | * X11DRV_WND_GetXScreen |
| 72 | * |
| 73 | * Return the X screen associated to the window. |
| 74 | */ |
| 75 | Screen *X11DRV_WND_GetXScreen(WND *wndPtr) |
| 76 | { |
| 77 | while(wndPtr->parent) wndPtr = wndPtr->parent; |
| 78 | return X11DRV_DESKTOP_GetXScreen((struct tagDESKTOP *) wndPtr->wExtra); |
| 79 | } |
| 80 | |
| 81 | /*********************************************************************** |
| 82 | * X11DRV_WND_GetXRootWindow |
| 83 | * |
| 84 | * Return the X display associated to the window. |
| 85 | */ |
| 86 | Window X11DRV_WND_GetXRootWindow(WND *wndPtr) |
| 87 | { |
| 88 | while(wndPtr->parent) wndPtr = wndPtr->parent; |
| 89 | return X11DRV_DESKTOP_GetXRootWindow((struct tagDESKTOP *) wndPtr->wExtra); |
| 90 | } |
| 91 | |
| 92 | /*********************************************************************** |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 93 | * X11DRV_WND_RegisterWindow |
| 94 | * |
| 95 | * Associate an X window to a HWND. |
| 96 | */ |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 97 | static void X11DRV_WND_RegisterWindow(WND *wndPtr) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 98 | { |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 99 | TSXSetWMProtocols( display, X11DRV_WND_GetXWindow(wndPtr), &wmDeleteWindow, 1 ); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 100 | |
| 101 | if (!winContext) winContext = TSXUniqueContext(); |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 102 | TSXSaveContext( display, X11DRV_WND_GetXWindow(wndPtr), winContext, (char *) wndPtr ); |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 103 | } |
| 104 | |
| 105 | /********************************************************************** |
| 106 | * X11DRV_WND_Initialize |
| 107 | */ |
| 108 | void X11DRV_WND_Initialize(WND *wndPtr) |
| 109 | { |
| 110 | X11DRV_WND_DATA *pWndDriverData = |
| 111 | (X11DRV_WND_DATA *) HeapAlloc(SystemHeap, 0, sizeof(X11DRV_WND_DATA)); |
| 112 | |
| 113 | wndPtr->pDriverData = (void *) pWndDriverData; |
| 114 | |
| 115 | pWndDriverData->window = 0; |
| 116 | } |
| 117 | |
| 118 | /********************************************************************** |
| 119 | * X11DRV_WND_Finalize |
| 120 | */ |
| 121 | void X11DRV_WND_Finalize(WND *wndPtr) |
| 122 | { |
| 123 | X11DRV_WND_DATA *pWndDriverData = |
| 124 | (X11DRV_WND_DATA *) wndPtr->pDriverData; |
| 125 | |
Marcus Meissner | 308477b | 1999-01-23 14:03:11 +0000 | [diff] [blame] | 126 | if (!wndPtr->pDriverData) { |
| 127 | ERR(win,"Trying to destroy window again. Not good.\n"); |
| 128 | return; |
| 129 | } |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 130 | if(pWndDriverData->window) |
| 131 | { |
| 132 | ERR(win, |
| 133 | "WND destroyed without destroying " |
| 134 | "the associated X Window (%ld)\n", |
| 135 | pWndDriverData->window |
| 136 | ); |
| 137 | } |
| 138 | HeapFree(SystemHeap, 0, wndPtr->pDriverData); |
Marcus Meissner | bb7959b | 1999-01-24 18:55:48 +0000 | [diff] [blame] | 139 | wndPtr->pDriverData = NULL; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | /********************************************************************** |
| 143 | * X11DRV_WND_CreateDesktopWindow |
| 144 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 145 | BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 146 | { |
| 147 | if (wmProtocols == None) |
| 148 | wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True ); |
| 149 | if (wmDeleteWindow == None) |
| 150 | wmDeleteWindow = TSXInternAtom( display, "WM_DELETE_WINDOW", True ); |
| 151 | if( dndProtocol == None ) |
| 152 | dndProtocol = TSXInternAtom( display, "DndProtocol" , False ); |
| 153 | if( dndSelection == None ) |
| 154 | dndSelection = TSXInternAtom( display, "DndSelection" , False ); |
| 155 | |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 156 | ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = |
| 157 | X11DRV_WND_GetXRootWindow( wndPtr ); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 158 | X11DRV_WND_RegisterWindow( wndPtr ); |
| 159 | |
| 160 | return TRUE; |
| 161 | } |
| 162 | |
| 163 | /********************************************************************** |
| 164 | * X11DRV_WND_CreateWindow |
| 165 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 166 | BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BOOL bUnicode) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 167 | { |
| 168 | /* Create the X window (only for top-level windows, and then only */ |
| 169 | /* when there's no desktop window) */ |
| 170 | |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 171 | if (!(cs->style & WS_CHILD) && |
| 172 | (X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display))) |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 173 | { |
| 174 | Window wGroupLeader; |
| 175 | XWMHints* wm_hints; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 176 | XSetWindowAttributes win_attr; |
| 177 | |
| 178 | if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) || |
| 179 | (cs->dwExStyle & WS_EX_DLGMODALFRAME))) |
| 180 | { |
| 181 | win_attr.event_mask = ExposureMask | KeyPressMask | |
| 182 | KeyReleaseMask | PointerMotionMask | |
| 183 | ButtonPressMask | ButtonReleaseMask | |
| 184 | FocusChangeMask | StructureNotifyMask; |
| 185 | win_attr.override_redirect = FALSE; |
| 186 | wndPtr->flags |= WIN_MANAGED; |
| 187 | } |
| 188 | else |
| 189 | { |
| 190 | win_attr.event_mask = ExposureMask | KeyPressMask | |
| 191 | KeyReleaseMask | PointerMotionMask | |
| 192 | ButtonPressMask | ButtonReleaseMask | |
| 193 | FocusChangeMask; |
| 194 | win_attr.override_redirect = TRUE; |
| 195 | } |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 196 | wndPtr->flags |= WIN_NATIVE; |
| 197 | |
| 198 | win_attr.bit_gravity = BGNorthWest; |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame^] | 199 | win_attr.colormap = X11DRV_PALETTE_PaletteXColormap; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 200 | win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful; |
| 201 | win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0); |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 202 | win_attr.cursor = X11DRV_MOUSE_XCursor; |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 203 | |
| 204 | ((X11DRV_WND_DATA *) wndPtr->pDriverData)->bit_gravity = BGNorthWest; |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 205 | ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 206 | TSXCreateWindow( display, |
| 207 | X11DRV_WND_GetXRootWindow(wndPtr), |
| 208 | cs->x, cs->y, cs->cx, cs->cy, |
| 209 | 0, CopyFromParent, |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 210 | InputOutput, CopyFromParent, |
| 211 | CWEventMask | CWOverrideRedirect | |
| 212 | CWColormap | CWCursor | CWSaveUnder | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 213 | CWBackingStore | CWBitGravity, |
| 214 | &win_attr ); |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 215 | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 216 | if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr))) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 217 | return FALSE; |
| 218 | |
Dirk Thierbach | 9824ec4 | 1998-12-15 17:33:04 +0000 | [diff] [blame] | 219 | if (wndPtr->flags & WIN_MANAGED) { |
| 220 | XClassHint *class_hints = TSXAllocClassHint(); |
| 221 | |
| 222 | if (class_hints) { |
| 223 | class_hints->res_name = "wineManaged"; |
| 224 | class_hints->res_class = "Wine"; |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 225 | TSXSetClassHint( display, ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window, class_hints ); |
Dirk Thierbach | 9824ec4 | 1998-12-15 17:33:04 +0000 | [diff] [blame] | 226 | TSXFree (class_hints); |
| 227 | } |
| 228 | |
| 229 | if (cs->dwExStyle & WS_EX_DLGMODALFRAME) { |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 230 | XSizeHints* size_hints = TSXAllocSizeHints(); |
| 231 | |
Dirk Thierbach | 9824ec4 | 1998-12-15 17:33:04 +0000 | [diff] [blame] | 232 | if (size_hints) { |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 233 | size_hints->min_width = size_hints->max_width = cs->cx; |
| 234 | size_hints->min_height = size_hints->max_height = cs->cy; |
| 235 | size_hints->flags = (PSize | PMinSize | PMaxSize); |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 236 | TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(wndPtr), size_hints, |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 237 | XA_WM_NORMAL_HINTS ); |
| 238 | TSXFree(size_hints); |
| 239 | } |
| 240 | } |
Dirk Thierbach | 9824ec4 | 1998-12-15 17:33:04 +0000 | [diff] [blame] | 241 | } |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 242 | |
| 243 | if (cs->hwndParent) /* Get window owner */ |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 244 | { |
| 245 | Window w; |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 246 | WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent); |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 247 | |
| 248 | w = X11DRV_WND_FindXWindow( tmpWnd ); |
| 249 | if (w != None) |
| 250 | { |
| 251 | TSXSetTransientForHint( display, X11DRV_WND_GetXWindow(wndPtr), w ); |
| 252 | wGroupLeader = w; |
| 253 | } |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 254 | WIN_ReleaseWndPtr(tmpWnd); |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 255 | } |
| 256 | |
| 257 | wm_hints = TSXAllocWMHints(); |
| 258 | { |
| 259 | wm_hints->flags = InputHint | StateHint | WindowGroupHint; |
| 260 | wm_hints->input = True; |
| 261 | if( wndPtr->dwStyle & WS_VISIBLE ) |
| 262 | wm_hints->initial_state = (wndPtr->dwStyle & WS_MINIMIZE && |
| 263 | wndPtr->flags & WIN_MANAGED ) ? |
| 264 | IconicState : NormalState; |
| 265 | else |
| 266 | wm_hints->initial_state = WithdrawnState; |
| 267 | wm_hints->window_group = wGroupLeader; |
| 268 | |
| 269 | TSXSetWMHints( display, X11DRV_WND_GetXWindow(wndPtr), wm_hints ); |
| 270 | TSXFree(wm_hints); |
| 271 | } |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 272 | X11DRV_WND_RegisterWindow( wndPtr ); |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 273 | } |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 274 | return TRUE; |
| 275 | } |
| 276 | |
| 277 | /*********************************************************************** |
| 278 | * X11DRV_WND_DestroyWindow |
| 279 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 280 | BOOL X11DRV_WND_DestroyWindow(WND *wndPtr) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 281 | { |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 282 | if (X11DRV_WND_GetXWindow(wndPtr)) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 283 | { |
| 284 | XEvent xe; |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 285 | TSXDeleteContext( display, X11DRV_WND_GetXWindow(wndPtr), winContext ); |
| 286 | TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); |
| 287 | while( TSXCheckWindowEvent(display, X11DRV_WND_GetXWindow(wndPtr), NoEventMask, &xe) ); |
| 288 | ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 289 | } |
| 290 | |
| 291 | return TRUE; |
| 292 | } |
| 293 | |
| 294 | /***************************************************************** |
| 295 | * X11DRV_WND_SetParent |
| 296 | */ |
| 297 | WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent) |
| 298 | { |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 299 | WND *pDesktop = WIN_GetDesktop(); |
| 300 | |
| 301 | if( wndPtr && pWndParent && (wndPtr != pDesktop) ) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 302 | { |
| 303 | WND* pWndPrev = wndPtr->parent; |
| 304 | |
| 305 | if( pWndParent != pWndPrev ) |
| 306 | { |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 307 | if ( X11DRV_WND_GetXWindow(wndPtr) ) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 308 | { |
| 309 | /* Toplevel window needs to be reparented. Used by Tk 8.0 */ |
| 310 | |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 311 | TSXDestroyWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); |
| 312 | ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = None; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 313 | } |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 314 | |
| 315 | WIN_UnlinkWindow(wndPtr->hwndSelf); |
| 316 | wndPtr->parent = pWndParent; |
| 317 | |
NF Stevens | e00bb9d | 1999-01-31 10:01:41 +0000 | [diff] [blame] | 318 | /* Create an X counterpart for reparented top-level windows |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 319 | * when not in the desktop mode. */ |
NF Stevens | e00bb9d | 1999-01-31 10:01:41 +0000 | [diff] [blame] | 320 | |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 321 | if( pWndParent == pDesktop ) |
NF Stevens | e00bb9d | 1999-01-31 10:01:41 +0000 | [diff] [blame] | 322 | { |
| 323 | wndPtr->dwStyle &= ~WS_CHILD; |
| 324 | wndPtr->wIDmenu = 0; |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 325 | if( X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display) ) |
NF Stevens | e00bb9d | 1999-01-31 10:01:41 +0000 | [diff] [blame] | 326 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 327 | CREATESTRUCTA cs; |
NF Stevens | e00bb9d | 1999-01-31 10:01:41 +0000 | [diff] [blame] | 328 | cs.lpCreateParams = NULL; |
| 329 | cs.hInstance = 0; /* not used if following call */ |
| 330 | cs.hMenu = 0; /* not used in following call */ |
| 331 | cs.hwndParent = pWndParent->hwndSelf; |
| 332 | cs.cy = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; |
Pavel Roskin | a0fd289 | 1999-03-14 13:41:07 +0000 | [diff] [blame] | 333 | if (!cs.cy) |
| 334 | cs.cy = 1; |
NF Stevens | e00bb9d | 1999-01-31 10:01:41 +0000 | [diff] [blame] | 335 | cs.cx = wndPtr->rectWindow.right - wndPtr->rectWindow.left; |
Pavel Roskin | a0fd289 | 1999-03-14 13:41:07 +0000 | [diff] [blame] | 336 | if (!cs.cx) |
| 337 | cs.cx = 1; |
NF Stevens | e00bb9d | 1999-01-31 10:01:41 +0000 | [diff] [blame] | 338 | cs.y = wndPtr->rectWindow.top; |
| 339 | cs.x = wndPtr->rectWindow.left; |
| 340 | cs.style = wndPtr->dwStyle; |
| 341 | cs.lpszName = 0; /* not used in following call */ |
| 342 | cs.lpszClass = 0; /*not used in following call */ |
| 343 | cs.dwExStyle = wndPtr->dwExStyle; |
| 344 | X11DRV_WND_CreateWindow(wndPtr, wndPtr->class, |
| 345 | &cs, FALSE); |
| 346 | } |
| 347 | } |
| 348 | else /* a child window */ |
| 349 | { |
| 350 | if( !( wndPtr->dwStyle & WS_CHILD ) ) |
| 351 | { |
| 352 | wndPtr->dwStyle |= WS_CHILD; |
| 353 | if( wndPtr->wIDmenu != 0) |
| 354 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 355 | DestroyMenu( (HMENU) wndPtr->wIDmenu ); |
NF Stevens | e00bb9d | 1999-01-31 10:01:41 +0000 | [diff] [blame] | 356 | wndPtr->wIDmenu = 0; |
| 357 | } |
| 358 | } |
| 359 | } |
Bernd Herd | ec72112 | 1999-01-30 15:50:58 +0000 | [diff] [blame] | 360 | WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 361 | } |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 362 | WIN_ReleaseDesktop(); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 363 | return pWndPrev; |
| 364 | } /* failure */ |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 365 | WIN_ReleaseDesktop(); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 366 | return 0; |
| 367 | } |
| 368 | |
| 369 | /*********************************************************************** |
| 370 | * X11DRV_WND_ForceWindowRaise |
| 371 | * |
| 372 | * Raise a window on top of the X stacking order, while preserving |
| 373 | * the correct Windows Z order. |
| 374 | */ |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 375 | void X11DRV_WND_ForceWindowRaise(WND *wndPtr) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 376 | { |
| 377 | XWindowChanges winChanges; |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 378 | WND *wndPrev,*pDesktop = WIN_GetDesktop(); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 379 | |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 380 | if( !wndPtr || !X11DRV_WND_GetXWindow(wndPtr) || (wndPtr->flags & WIN_MANAGED) ) |
Francois Boisvert | 3a3cd9f | 1999-03-28 12:42:52 +0000 | [diff] [blame] | 381 | { |
| 382 | WIN_ReleaseDesktop(); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 383 | return; |
Francois Boisvert | 3a3cd9f | 1999-03-28 12:42:52 +0000 | [diff] [blame] | 384 | } |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 385 | |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 386 | /* Raise all windows up to wndPtr according to their Z order. |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 387 | * (it would be easier with sibling-related Below but it doesn't |
| 388 | * work very well with SGI mwm for instance) |
| 389 | */ |
| 390 | winChanges.stack_mode = Above; |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 391 | while (wndPtr) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 392 | { |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 393 | if (X11DRV_WND_GetXWindow(wndPtr)) |
| 394 | TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(wndPtr), 0, |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 395 | CWStackMode, &winChanges ); |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 396 | wndPrev = pDesktop->child; |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 397 | if (wndPrev == wndPtr) break; |
| 398 | while (wndPrev && (wndPrev->next != wndPtr)) wndPrev = wndPrev->next; |
| 399 | wndPtr = wndPrev; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 400 | } |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 401 | WIN_ReleaseDesktop(); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 402 | } |
| 403 | |
| 404 | /*********************************************************************** |
| 405 | * X11DRV_WND_FindDesktopXWindow [Internal] |
| 406 | * |
| 407 | * Find the actual X window which needs be restacked. |
| 408 | * Used by X11DRV_SetWindowPos(). |
| 409 | */ |
| 410 | static Window X11DRV_WND_FindDesktopXWindow( WND *wndPtr ) |
| 411 | { |
| 412 | if (!(wndPtr->flags & WIN_MANAGED)) |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 413 | return X11DRV_WND_GetXWindow(wndPtr); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 414 | else |
| 415 | { |
| 416 | Window window, root, parent, *children; |
| 417 | int nchildren; |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 418 | window = X11DRV_WND_GetXWindow(wndPtr); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 419 | for (;;) |
| 420 | { |
| 421 | TSXQueryTree( display, window, &root, &parent, |
| 422 | &children, &nchildren ); |
| 423 | TSXFree( children ); |
| 424 | if (parent == root) |
| 425 | return window; |
| 426 | window = parent; |
| 427 | } |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | /*********************************************************************** |
| 432 | * WINPOS_SetXWindowPos |
| 433 | * |
| 434 | * SetWindowPos() for an X window. Used by the real SetWindowPos(). |
| 435 | */ |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 436 | void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangePos) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 437 | { |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 438 | XWindowChanges winChanges; |
| 439 | int changeMask = 0; |
| 440 | WND *winposPtr = WIN_FindWndPtr( winpos->hwnd ); |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 441 | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 442 | if(!wndPtr->hwndSelf) wndPtr = NULL; /* FIXME: WND destroyed, shouldn't happend!!! */ |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 443 | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 444 | if (!(winpos->flags & SWP_SHOWWINDOW) && (winpos->flags & SWP_HIDEWINDOW)) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 445 | { |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 446 | if(X11DRV_WND_GetXWindow(wndPtr)) |
| 447 | TSXUnmapWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 448 | } |
| 449 | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 450 | if(bChangePos) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 451 | { |
| 452 | if ( !(winpos->flags & SWP_NOSIZE)) |
| 453 | { |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 454 | winChanges.width = (winpos->cx > 0 ) ? winpos->cx : 1; |
| 455 | winChanges.height = (winpos->cy > 0 ) ? winpos->cy : 1; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 456 | changeMask |= CWWidth | CWHeight; |
| 457 | |
| 458 | /* Tweak dialog window size hints */ |
| 459 | |
| 460 | if ((winposPtr->flags & WIN_MANAGED) && |
| 461 | (winposPtr->dwExStyle & WS_EX_DLGMODALFRAME)) |
| 462 | { |
| 463 | XSizeHints *size_hints = TSXAllocSizeHints(); |
| 464 | |
| 465 | if (size_hints) |
| 466 | { |
| 467 | long supplied_return; |
| 468 | |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 469 | TSXGetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints, |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 470 | &supplied_return, XA_WM_NORMAL_HINTS); |
| 471 | size_hints->min_width = size_hints->max_width = winpos->cx; |
| 472 | size_hints->min_height = size_hints->max_height = winpos->cy; |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 473 | TSXSetWMSizeHints( display, X11DRV_WND_GetXWindow(winposPtr), size_hints, |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 474 | XA_WM_NORMAL_HINTS ); |
| 475 | TSXFree(size_hints); |
| 476 | } |
| 477 | } |
| 478 | } |
| 479 | if (!(winpos->flags & SWP_NOMOVE)) |
| 480 | { |
| 481 | winChanges.x = winpos->x; |
| 482 | winChanges.y = winpos->y; |
| 483 | changeMask |= CWX | CWY; |
| 484 | } |
| 485 | if (!(winpos->flags & SWP_NOZORDER)) |
| 486 | { |
| 487 | winChanges.stack_mode = Below; |
| 488 | changeMask |= CWStackMode; |
| 489 | |
| 490 | if (winpos->hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above; |
| 491 | else if (winpos->hwndInsertAfter != HWND_BOTTOM) |
| 492 | { |
| 493 | WND* insertPtr = WIN_FindWndPtr( winpos->hwndInsertAfter ); |
| 494 | Window stack[2]; |
| 495 | |
| 496 | stack[0] = X11DRV_WND_FindDesktopXWindow( insertPtr ); |
| 497 | stack[1] = X11DRV_WND_FindDesktopXWindow( winposPtr ); |
| 498 | |
| 499 | /* for stupid window managers (i.e. all of them) */ |
| 500 | |
| 501 | TSXRestackWindows(display, stack, 2); |
| 502 | changeMask &= ~CWStackMode; |
Francois Boisvert | 6b1b41c | 1999-03-14 17:25:32 +0000 | [diff] [blame] | 503 | |
| 504 | WIN_ReleaseWndPtr(insertPtr); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 505 | } |
| 506 | } |
| 507 | if (changeMask) |
| 508 | { |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 509 | TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges ); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 510 | } |
| 511 | } |
| 512 | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 513 | if ( winpos->flags & SWP_SHOWWINDOW ) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 514 | { |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 515 | if(X11DRV_WND_GetXWindow(wndPtr)) TSXMapWindow( display, X11DRV_WND_GetXWindow(wndPtr) ); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 516 | } |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 517 | WIN_ReleaseWndPtr(winposPtr); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 518 | } |
| 519 | |
| 520 | /***************************************************************** |
| 521 | * X11DRV_WND_SetText |
| 522 | */ |
| 523 | void X11DRV_WND_SetText(WND *wndPtr, LPCSTR text) |
| 524 | { |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 525 | if (!X11DRV_WND_GetXWindow(wndPtr)) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 526 | return; |
| 527 | |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 528 | TSXStoreName( display, X11DRV_WND_GetXWindow(wndPtr), text ); |
| 529 | TSXSetIconName( display, X11DRV_WND_GetXWindow(wndPtr), text ); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 530 | } |
| 531 | |
| 532 | /***************************************************************** |
| 533 | * X11DRV_WND_SetFocus |
| 534 | * |
| 535 | * Set the X focus. |
| 536 | * Explicit colormap management seems to work only with OLVWM. |
| 537 | */ |
| 538 | void X11DRV_WND_SetFocus(WND *wndPtr) |
| 539 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 540 | HWND hwnd = wndPtr->hwndSelf; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 541 | XWindowAttributes win_attr; |
Alexandre Julliard | 6842064 | 1998-12-27 15:26:28 +0000 | [diff] [blame] | 542 | Window win; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 543 | |
| 544 | /* Only mess with the X focus if there's */ |
| 545 | /* no desktop window and no window manager. */ |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 546 | if ((X11DRV_WND_GetXRootWindow(wndPtr) != DefaultRootWindow(display)) |
| 547 | || Options.managed) return; |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 548 | |
| 549 | if (!hwnd) /* If setting the focus to 0, uninstall the colormap */ |
| 550 | { |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame^] | 551 | if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE) |
| 552 | TSXUninstallColormap( display, X11DRV_PALETTE_PaletteXColormap ); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 553 | return; |
| 554 | } |
| 555 | |
| 556 | /* Set X focus and install colormap */ |
| 557 | |
Alexandre Julliard | 6842064 | 1998-12-27 15:26:28 +0000 | [diff] [blame] | 558 | if (!(win = X11DRV_WND_FindXWindow(wndPtr))) return; |
| 559 | if (!TSXGetWindowAttributes( display, win, &win_attr ) || |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 560 | (win_attr.map_state != IsViewable)) |
| 561 | return; /* If window is not viewable, don't change anything */ |
| 562 | |
Alexandre Julliard | 6842064 | 1998-12-27 15:26:28 +0000 | [diff] [blame] | 563 | TSXSetInputFocus( display, win, RevertToParent, CurrentTime ); |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame^] | 564 | if (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_PRIVATE) |
| 565 | TSXInstallColormap( display, X11DRV_PALETTE_PaletteXColormap ); |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 566 | |
| 567 | EVENT_Synchronize(); |
| 568 | } |
| 569 | |
| 570 | /***************************************************************** |
| 571 | * X11DRV_WND_PreSizeMove |
| 572 | */ |
| 573 | void X11DRV_WND_PreSizeMove(WND *wndPtr) |
| 574 | { |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 575 | if (!(wndPtr->dwStyle & WS_CHILD) && |
| 576 | (X11DRV_WND_GetXRootWindow(wndPtr) == DefaultRootWindow(display))) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 577 | TSXGrabServer( display ); |
| 578 | } |
| 579 | |
| 580 | /***************************************************************** |
| 581 | * X11DRV_WND_PostSizeMove |
| 582 | */ |
| 583 | void X11DRV_WND_PostSizeMove(WND *wndPtr) |
| 584 | { |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 585 | if (!(wndPtr->dwStyle & WS_CHILD) && |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 586 | (X11DRV_GetXRootWindow() == DefaultRootWindow(display))) |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 587 | TSXUngrabServer( display ); |
| 588 | } |
| 589 | |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 590 | /***************************************************************** |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 591 | * X11DRV_WND_SurfaceCopy |
| 592 | * |
| 593 | * Copies rect to (rect.left + dx, rect.top + dy). |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 594 | */ |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 595 | void X11DRV_WND_SurfaceCopy(WND* wndPtr, DC *dcPtr, INT dx, INT dy, |
| 596 | const RECT *rect, BOOL bUpdate) |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 597 | { |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 598 | X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcPtr->physDev; |
| 599 | POINT dst, src; |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 600 | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 601 | dst.x = (src.x = dcPtr->w.DCOrgX + rect->left) + dx; |
| 602 | dst.y = (src.y = dcPtr->w.DCOrgY + rect->top) + dy; |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 603 | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 604 | if (bUpdate) /* handles non-Wine windows hanging over the copied area */ |
| 605 | TSXSetGraphicsExposures( display, physDev->gc, True ); |
| 606 | TSXSetFunction( display, physDev->gc, GXcopy ); |
| 607 | TSXCopyArea( display, physDev->drawable, physDev->drawable, |
| 608 | physDev->gc, src.x, src.y, |
| 609 | rect->right - rect->left, |
| 610 | rect->bottom - rect->top, |
| 611 | dst.x, dst.y ); |
| 612 | if (bUpdate) |
| 613 | TSXSetGraphicsExposures( display, physDev->gc, False ); |
Jerome Vouillon | 1da6dba | 1999-02-14 13:32:13 +0000 | [diff] [blame] | 614 | |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 615 | if (bUpdate) /* Make sure exposure events have been processed */ |
| 616 | EVENT_Synchronize(); |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 617 | } |
| 618 | |
| 619 | /*********************************************************************** |
| 620 | * X11DRV_WND_SetDrawable |
| 621 | * |
| 622 | * Set the drawable, origin and dimensions for the DC associated to |
| 623 | * a given window. |
| 624 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 625 | void X11DRV_WND_SetDrawable(WND *wndPtr, DC *dc, WORD flags, BOOL bSetClipOrigin) |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 626 | { |
| 627 | X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; |
| 628 | |
| 629 | if (!wndPtr) /* Get a DC for the whole screen */ |
| 630 | { |
| 631 | dc->w.DCOrgX = 0; |
| 632 | dc->w.DCOrgY = 0; |
Patrik Stridvall | ab121e7 | 1999-02-04 11:11:01 +0000 | [diff] [blame] | 633 | physDev->drawable = X11DRV_WND_GetXRootWindow(wndPtr); |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 634 | TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors ); |
| 635 | } |
| 636 | else |
| 637 | { |
| 638 | if (flags & DCX_WINDOW) |
| 639 | { |
| 640 | dc->w.DCOrgX = wndPtr->rectWindow.left; |
| 641 | dc->w.DCOrgY = wndPtr->rectWindow.top; |
| 642 | } |
| 643 | else |
| 644 | { |
| 645 | dc->w.DCOrgX = wndPtr->rectClient.left; |
| 646 | dc->w.DCOrgY = wndPtr->rectClient.top; |
| 647 | } |
| 648 | while (!X11DRV_WND_GetXWindow(wndPtr)) |
| 649 | { |
| 650 | wndPtr = wndPtr->parent; |
| 651 | dc->w.DCOrgX += wndPtr->rectClient.left; |
| 652 | dc->w.DCOrgY += wndPtr->rectClient.top; |
| 653 | } |
| 654 | dc->w.DCOrgX -= wndPtr->rectWindow.left; |
| 655 | dc->w.DCOrgY -= wndPtr->rectWindow.top; |
| 656 | physDev->drawable = X11DRV_WND_GetXWindow(wndPtr); |
| 657 | |
| 658 | #if 0 |
| 659 | /* This is needed when we reuse a cached DC because |
| 660 | * SetDCState() called by ReleaseDC() screws up DC |
| 661 | * origins for child windows. |
| 662 | */ |
| 663 | |
| 664 | if( bSetClipOrigin ) |
| 665 | TSXSetClipOrigin( display, physDev->gc, dc->w.DCOrgX, dc->w.DCOrgY ); |
| 666 | #endif |
| 667 | } |
| 668 | } |
| 669 | |
| 670 | /*********************************************************************** |
Alex Korobka | 4f1ac05 | 1999-03-28 09:37:57 +0000 | [diff] [blame] | 671 | * X11DRV_WND_SetHostAttr |
| 672 | */ |
| 673 | BOOL X11DRV_WND_SetHostAttr(WND* wnd, INT ha, INT value) |
| 674 | { |
| 675 | Window w; |
| 676 | |
| 677 | if( (w = X11DRV_WND_GetXWindow(wnd)) ) |
| 678 | { |
| 679 | XSetWindowAttributes win_attr; |
| 680 | |
| 681 | switch( ha ) |
| 682 | { |
| 683 | case HAK_BITGRAVITY: |
| 684 | |
| 685 | if( ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity != value ) |
| 686 | { |
| 687 | win_attr.bit_gravity = value; |
| 688 | ((X11DRV_WND_DATA *) wnd->pDriverData)->bit_gravity = value; |
| 689 | TSXChangeWindowAttributes( display, w, CWBitGravity, &win_attr ); |
| 690 | } |
| 691 | return TRUE; |
| 692 | |
| 693 | case HAK_ACCEPTFOCUS: |
| 694 | |
| 695 | if( (wnd->flags & WIN_MANAGED) ) |
| 696 | { |
| 697 | XWMHints* wm_hints = TSXAllocWMHints(); |
| 698 | |
| 699 | if( wm_hints ) |
| 700 | { |
| 701 | wm_hints->flags = InputHint; |
| 702 | wm_hints->input = value; |
| 703 | TSXSetWMHints( display, X11DRV_WND_GetXWindow(wnd), wm_hints ); |
| 704 | TSXFree( wm_hints ); |
| 705 | return TRUE; |
| 706 | } |
| 707 | } |
| 708 | break; |
| 709 | } |
| 710 | } |
| 711 | return FALSE; |
| 712 | } |
| 713 | |
| 714 | /*********************************************************************** |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 715 | * X11DRV_WND_IsSelfClipping |
| 716 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 717 | BOOL X11DRV_WND_IsSelfClipping(WND *wndPtr) |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 718 | { |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame^] | 719 | return X11DRV_WND_GetXWindow(wndPtr) != None; |
Patrik Stridvall | 151170c | 1998-12-26 12:00:43 +0000 | [diff] [blame] | 720 | } |
| 721 | |
Patrik Stridvall | e35d636 | 1998-12-07 09:13:40 +0000 | [diff] [blame] | 722 | #endif /* !defined(X_DISPLAY_MISSING) */ |