1/* 2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3 * 4 *Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 *"Software"), to deal in the Software without restriction, including 7 *without limitation the rights to use, copy, modify, merge, publish, 8 *distribute, sublicense, and/or sell copies of the Software, and to 9 *permit persons to whom the Software is furnished to do so, subject to 10 *the following conditions: 11 * 12 *The above copyright notice and this permission notice shall be 13 *included in all copies or substantial portions of the Software. 14 * 15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 *Except as contained in this notice, the name of the XFree86 Project 24 *shall not be used in advertising or otherwise to promote the sale, use 25 *or other dealings in this Software without prior written authorization 26 *from the XFree86 Project. 27 * 28 * Authors: Kensuke Matsuzaki 29 * Earle F. Philhower, III 30 * Harold L Hunt II 31 */ 32 33#ifdef HAVE_XWIN_CONFIG_H 34#include <xwin-config.h> 35#endif 36#include "win.h" 37#include "winprefs.h" 38 39#if 0 40/* 41 * winMWExtWMReorderWindows 42 */ 43 44void 45winMWExtWMReorderWindows (ScreenPtr pScreen) 46{ 47 winScreenPriv(pScreen); 48 HWND hwnd = NULL; 49 win32RootlessWindowPtr pRLWin = NULL; 50 win32RootlessWindowPtr pRLWinSib = NULL; 51 DWORD dwCurrentProcessID = GetCurrentProcessId (); 52 DWORD dwWindowProcessID = 0; 53 XID vlist[2]; 54 55#if CYGMULTIWINDOW_DEBUG && FALSE 56 winDebug ("winMWExtWMReorderWindows\n"); 57#endif 58 59 pScreenPriv->fRestacking = TRUE; 60 61 if (pScreenPriv->fWindowOrderChanged) 62 { 63#if CYGMULTIWINDOW_DEBUG 64 winDebug ("winMWExtWMReorderWindows - Need to restack\n"); 65#endif 66 hwnd = GetTopWindow (NULL); 67 68 while (hwnd) 69 { 70 GetWindowThreadProcessId (hwnd, &dwWindowProcessID); 71 72 if ((dwWindowProcessID == dwCurrentProcessID) 73 && GetProp (hwnd, WIN_WINDOW_PROP)) 74 { 75 pRLWinSib = pRLWin; 76 pRLWin = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP); 77 78 if (pRLWinSib) 79 { 80 vlist[0] = pRLWinSib->pFrame->win->drawable.id; 81 vlist[1] = Below; 82 83 ConfigureWindow (pRLWin->pFrame->win, CWSibling | CWStackMode, 84 vlist, wClient(pRLWin->pFrame->win)); 85 } 86 else 87 { 88 /* 1st window - raise to the top */ 89 vlist[0] = Above; 90 91 ConfigureWindow (pRLWin->pFrame->win, CWStackMode, 92 vlist, wClient(pRLWin->pFrame->win)); 93 } 94 } 95 hwnd = GetNextWindow (hwnd, GW_HWNDNEXT); 96 } 97 } 98 99 pScreenPriv->fRestacking = FALSE; 100 pScreenPriv->fWindowOrderChanged = FALSE; 101} 102#endif 103 104 105/* 106 * winMWExtWMMoveXWindow 107 */ 108 109void 110winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y) 111{ 112 CARD32 *vlist = malloc(sizeof(CARD32)*2); 113 114 vlist[0] = x; 115 vlist[1] = y; 116 ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); 117 free(vlist); 118} 119 120 121/* 122 * winMWExtWMResizeXWindow 123 */ 124 125void 126winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h) 127{ 128 CARD32 *vlist = malloc(sizeof(CARD32)*2); 129 130 vlist[0] = w; 131 vlist[1] = h; 132 ConfigureWindow (pWin, CWWidth | CWHeight, vlist, wClient(pWin)); 133 free(vlist); 134} 135 136 137/* 138 * winMWExtWMMoveResizeXWindow 139 */ 140 141void 142winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h) 143{ 144 CARD32 *vlist = malloc(sizeof(long)*4); 145 146 vlist[0] = x; 147 vlist[1] = y; 148 vlist[2] = w; 149 vlist[3] = h; 150 151 ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, vlist, wClient(pWin)); 152 free(vlist); 153} 154 155 156/* 157 * winMWExtWMUpdateIcon 158 * Change the Windows window icon 159 */ 160 161void 162winMWExtWMUpdateIcon (Window id) 163{ 164 WindowPtr pWin; 165 HICON hIcon, hiconOld; 166 167 dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); 168 hIcon = winOverrideIcon ((unsigned long)pWin); 169 170 if (!hIcon) 171 hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); 172 173 if (hIcon) 174 { 175 win32RootlessWindowPtr pRLWinPriv 176 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); 177 178 if (pRLWinPriv->hWnd) 179 { 180 181 hiconOld = (HICON) SendMessage (pRLWinPriv->hWnd, 182 WM_SETICON, ICON_BIG, (LPARAM) hIcon); 183 winDestroyIcon(hiconOld); 184 } 185 hIcon=NULL; 186 } 187} 188 189 190/* 191 * winMWExtWMDecorateWindow - Update window style. Called by EnumWindows. 192 */ 193 194wBOOL CALLBACK 195winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam) 196{ 197 win32RootlessWindowPtr pRLWinPriv = NULL; 198 ScreenPtr pScreen = NULL; 199 winPrivScreenPtr pScreenPriv = NULL; 200 winScreenInfo *pScreenInfo = NULL; 201 202 /* Check if the Windows window property for our X window pointer is valid */ 203 if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) 204 { 205 pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; 206 if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); 207 if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; 208 if (pRLWinPriv && pScreenInfo) winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo); 209 } 210 return TRUE; 211} 212 213 214/* 215 * winMWExtWMUpdateWindowDecoration - Update window style. 216 */ 217 218void 219winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv, 220 winScreenInfoPtr pScreenInfo) 221{ 222 Bool fDecorate = FALSE; 223 DWORD dwExStyle = 0; 224 DWORD dwStyle = 0; 225 WINDOWPLACEMENT wndPlace; 226 UINT showCmd = 0; 227 228 wndPlace.length = sizeof (WINDOWPLACEMENT); 229 230 /* Get current window placement */ 231 GetWindowPlacement (pRLWinPriv->hWnd, &wndPlace); 232 233 if (winIsInternalWMRunning(pScreenInfo)) 234 { 235 if (!pRLWinPriv->pFrame->win->overrideRedirect) 236 fDecorate = TRUE; 237 } 238#if 0 239 if (wndPlace.showCmd == SW_HIDE) 240 return;//showCmd = SWP_HIDEWINDOW; 241 else 242 showCmd = SWP_SHOWWINDOW; 243#else 244 if (wndPlace.showCmd == SW_HIDE) 245 return; 246 247 if (IsWindowVisible (pRLWinPriv->hWnd)) 248 showCmd = SWP_SHOWWINDOW; 249#endif 250 251 showCmd |= SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER; 252 253 winDebug ("winMWExtWMUpdateWindowDecoration %08x %s\n", 254 (int)pRLWinPriv, fDecorate?"Decorate":"Bare"); 255 256 /* Get the standard and extended window style information */ 257 dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); 258 dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); 259 260 if (fDecorate) 261 { 262 RECT rcNew; 263 int iDx, iDy; 264 winWMMessageRec wmMsg; 265 winScreenPriv(pScreenInfo->pScreen); 266 267 /* */ 268 if (!(dwExStyle & WS_EX_APPWINDOW)) 269 { 270 winDebug ("\tBare=>Decorate\n"); 271 /* Setup a rectangle with the X window position and size */ 272 SetRect (&rcNew, 273 pRLWinPriv->pFrame->x, 274 pRLWinPriv->pFrame->y, 275 pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width, 276 pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height); 277 278#ifdef CYGMULTIWINDOW_DEBUG 279 winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", 280 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, 281 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); 282#endif 283 /* */ 284 AdjustWindowRectEx (&rcNew, 285 WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, 286 FALSE, 287 WS_EX_APPWINDOW); 288 289#ifdef CYGMULTIWINDOW_DEBUG 290 winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", 291 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, 292 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); 293#endif 294 /* Calculate position deltas */ 295 iDx = pRLWinPriv->pFrame->x - rcNew.left; 296 iDy = pRLWinPriv->pFrame->y - rcNew.top; 297 298 /* Calculate new rectangle */ 299 rcNew.left += iDx; 300 rcNew.right += iDx; 301 rcNew.top += iDy; 302 rcNew.bottom += iDy; 303 304 /* Set the window extended style flags */ 305 SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW); 306 307 /* Set the window standard style flags */ 308 SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, 309 WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW); 310 311#ifdef CYGMULTIWINDOW_DEBUG 312 winDebug("\tWindowStyle: %08x %08x\n", 313 WS_POPUP | WS_SIZEBOX | WS_OVERLAPPEDWINDOW, 314 WS_EX_APPWINDOW); 315#endif 316 /* Position the Windows window */ 317#ifdef CYGMULTIWINDOW_DEBUG 318 winDebug("\tMoved {%d, %d, %d, %d}, {%d, %d}\n", 319 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, 320 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); 321#endif 322 SetWindowPos (pRLWinPriv->hWnd, NULL, 323 rcNew.left, rcNew.top, 324 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 325 showCmd); 326 327 328 wmMsg.hwndWindow = pRLWinPriv->hWnd; 329 wmMsg.iWindow = (Window)pRLWinPriv->pFrame->win->drawable.id; 330 wmMsg.msg = WM_WM_NAME_EVENT; 331 winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg); 332 333 winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv , 334 wBoundingShape(pRLWinPriv->pFrame->win)); 335 } 336 } 337 else 338 { 339 RECT rcNew; 340 341 /* */ 342 if (dwExStyle & WS_EX_APPWINDOW) 343 { 344 winDebug ("\tDecorate=>Bare\n"); 345 /* Setup a rectangle with the X window position and size */ 346 SetRect (&rcNew, 347 pRLWinPriv->pFrame->x, 348 pRLWinPriv->pFrame->y, 349 pRLWinPriv->pFrame->x + pRLWinPriv->pFrame->width, 350 pRLWinPriv->pFrame->y + pRLWinPriv->pFrame->height); 351#if 0 352 /* */ 353 AdjustWindowRectEx (&rcNew, 354 WS_POPUP | WS_CLIPCHILDREN, 355 FALSE, 356 WS_EX_TOOLWINDOW); 357 358 /* Calculate position deltas */ 359 iDx = pRLWinPriv->pFrame->x - rcNew.left; 360 iDy = pRLWinPriv->pFrame->y - rcNew.top; 361 362 /* Calculate new rectangle */ 363 rcNew.left += iDx; 364 rcNew.right += iDx; 365 rcNew.top += iDy; 366 rcNew.bottom += iDy; 367#endif 368 369 /* Hide window temporary to remove from taskbar. */ 370 ShowWindow( pRLWinPriv->hWnd, SW_HIDE ); 371 372 /* Set the window extended style flags */ 373 SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); 374 375 /* Set the window standard style flags */ 376 SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, 377 WS_POPUP | WS_CLIPCHILDREN); 378 379 /* Position the Windows window */ 380 SetWindowPos (pRLWinPriv->hWnd, NULL, 381 rcNew.left, rcNew.top, 382 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 383 showCmd); 384 385 winMWExtWMReshapeFrame ((RootlessFrameID)pRLWinPriv , 386 wBoundingShape(pRLWinPriv->pFrame->win)); 387 } 388 } 389} 390 391 392/* 393 * winIsInternalWMRunning (winScreenInfoPtr pScreenInfo) 394 */ 395Bool 396winIsInternalWMRunning (winScreenInfoPtr pScreenInfo) 397{ 398 return pScreenInfo->fInternalWM && !pScreenInfo->fAnotherWMRunning; 399} 400 401 402/* 403 * winMWExtWMRestackWindows 404 */ 405 406void 407winMWExtWMRestackWindows (ScreenPtr pScreen) 408{ 409 winScreenPriv(pScreen); 410 WindowPtr pRoot = pScreen->root; 411 WindowPtr pWin = NULL; 412 WindowPtr pWinPrev = NULL; 413 win32RootlessWindowPtr pRLWin = NULL; 414 win32RootlessWindowPtr pRLWinPrev = NULL; 415 int nWindow = 0; 416 HDWP hWinPosInfo = NULL; 417 418#if CYGMULTIWINDOW_DEBUG 419 winDebug ("winMWExtWMRestackWindows\n"); 420#endif 421 422 pScreenPriv->fRestacking = TRUE; 423 424 if (pRoot != NULL) 425 { 426 for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) 427 nWindow ++; 428 429 hWinPosInfo = BeginDeferWindowPos(nWindow); 430 431 for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) 432 { 433 if (pWin->realized) 434 { 435 UINT uFlags; 436 437 pRLWin = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); 438 if (pRLWin == NULL) continue; 439 440 if (pWinPrev) 441 pRLWinPrev = (win32RootlessWindowPtr) RootlessFrameForWindow (pWinPrev, FALSE); 442 443 uFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW; 444 if (pRLWinPrev != NULL) uFlags |= SWP_NOACTIVATE; 445 446#if CYGMULTIWINDOW_DEBUG 447 winDebug ("winMWExtWMRestackWindows - DeferWindowPos (%08x, %08x)\n", 448 pRLWin->hWnd, 449 pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP); 450#endif 451 hWinPosInfo = DeferWindowPos (hWinPosInfo, pRLWin->hWnd, 452 pRLWinPrev ? pRLWinPrev->hWnd : HWND_TOP, 453 0, 0, 0, 0, 454 uFlags); 455 if (hWinPosInfo == NULL) 456 { 457 ErrorF ("winMWExtWMRestackWindows - DeferWindowPos () failed: %d\n", 458 (int) GetLastError ()); 459 return; 460 } 461 pWinPrev = pWin; 462 } 463 } 464 if (!EndDeferWindowPos (hWinPosInfo)) 465 { 466 ErrorF ("winMWExtWMRestackWindows - EndDeferWindowPos () failed: %d\n", 467 (int) GetLastError ()); 468 return; 469 } 470 } 471 472#if CYGMULTIWINDOW_DEBUG 473 winDebug ("winMWExtWMRestackWindows - done\n"); 474#endif 475 pScreenPriv->fRestacking = FALSE; 476} 477