winwin32rootless.c revision 706f2543
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 * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c 34 */ 35#ifdef HAVE_XWIN_CONFIG_H 36#include <xwin-config.h> 37#endif 38#include "win.h" 39#include <winuser.h> 40#define _WINDOWSWM_SERVER_ 41#include <X11/extensions/windowswmstr.h> 42#include "dixevents.h" 43#include "winmultiwindowclass.h" 44#include <X11/Xatom.h> 45 46 47/* 48 * Constant defines 49 */ 50 51#ifndef ULW_COLORKEY 52#define ULW_COLORKEY 0x00000001 53#endif 54#ifndef ULW_ALPHA 55#define ULW_ALPHA 0x00000002 56#endif 57#ifndef ULW_OPAQUE 58#define ULW_OPAQUE 0x00000004 59#endif 60#define AC_SRC_ALPHA 0x01 61 62/* 63 * Local function 64 */ 65 66DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND) 67static void 68winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame); 69 70/* 71 * Global variables 72 */ 73 74Bool g_fNoConfigureWindow = FALSE; 75 76/* 77 * Internal function to get the DIB format that is compatible with the screen 78 * Fixme: Share code with winshadgdi.c 79 */ 80 81static 82Bool 83winMWExtWMQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih) 84{ 85 HBITMAP hbmp; 86#if CYGMULTIWINDOW_DEBUG 87 LPDWORD pdw = NULL; 88#endif 89 90 /* Create a memory bitmap compatible with the screen */ 91 hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1); 92 if (hbmp == NULL) 93 { 94 ErrorF ("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n"); 95 return FALSE; 96 } 97 98 /* Initialize our bitmap info header */ 99 ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); 100 pbmih->biSize = sizeof (BITMAPINFOHEADER); 101 102 /* Get the biBitCount */ 103 if (!GetDIBits (pRLWinPriv->hdcScreen, 104 hbmp, 105 0, 1, 106 NULL, 107 (BITMAPINFO*) pbmih, 108 DIB_RGB_COLORS)) 109 { 110 ErrorF ("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n"); 111 DeleteObject (hbmp); 112 return FALSE; 113 } 114 115#if CYGMULTIWINDOW_DEBUG 116 /* Get a pointer to bitfields */ 117 pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); 118 119 winDebug ("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n", 120 (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); 121#endif 122 123 /* Get optimal color table, or the optimal bitfields */ 124 if (!GetDIBits (pRLWinPriv->hdcScreen, 125 hbmp, 126 0, 1, 127 NULL, 128 (BITMAPINFO*)pbmih, 129 DIB_RGB_COLORS)) 130 { 131 ErrorF ("winMWExtWMQueryDIBFormat - Second call to GetDIBits " 132 "failed\n"); 133 DeleteObject (hbmp); 134 return FALSE; 135 } 136 137 /* Free memory */ 138 DeleteObject (hbmp); 139 140 return TRUE; 141} 142 143static HRGN 144winMWExtWMCreateRgnFromRegion (RegionPtr pShape) 145{ 146 int nRects; 147 BoxPtr pRects, pEnd; 148 HRGN hRgn, hRgnRect; 149 150 if (pShape == NULL) return NULL; 151 152 nRects = RegionNumRects(pShape); 153 pRects = RegionRects(pShape); 154 155 hRgn = CreateRectRgn (0, 0, 0, 0); 156 if (hRgn == NULL) 157 { 158 ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " 159 "failed: %d\n", 160 0, 0, 0, 0, (int) GetLastError ()); 161 } 162 163 /* Loop through all rectangles in the X region */ 164 for (pEnd = pRects + nRects; pRects < pEnd; pRects++) 165 { 166 /* Create a Windows region for the X rectangle */ 167 hRgnRect = CreateRectRgn (pRects->x1, 168 pRects->y1, 169 pRects->x2, 170 pRects->y2); 171 if (hRgnRect == NULL) 172 { 173 ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " 174 "failed: %d\n", 175 pRects->x1, 176 pRects->y1, 177 pRects->x2, 178 pRects->y2, 179 (int) GetLastError ()); 180 } 181 182 /* Merge the Windows region with the accumulated region */ 183 if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) 184 { 185 ErrorF ("winReshape - CombineRgn () failed: %d\n", 186 (int) GetLastError ()); 187 } 188 189 /* Delete the temporary Windows region */ 190 DeleteObject (hRgnRect); 191 } 192 193 return hRgn; 194} 195 196static void 197InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv) 198{ 199 pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd); 200 pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen); 201 pRLWinPriv->hbmpShadow = NULL; 202 203 /* Allocate bitmap info header */ 204 pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) 205 + 256 * sizeof (RGBQUAD)); 206 if (pRLWinPriv->pbmihShadow == NULL) 207 { 208 ErrorF ("InitWin32RootlessEngine - malloc () failed\n"); 209 return; 210 } 211 212 /* Query the screen format */ 213 winMWExtWMQueryDIBFormat (pRLWinPriv, 214 pRLWinPriv->pbmihShadow); 215} 216 217Bool 218winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, 219 int newX, int newY, RegionPtr pShape) 220{ 221#define CLASS_NAME_LENGTH 512 222 Bool fResult = TRUE; 223 win32RootlessWindowPtr pRLWinPriv; 224 WNDCLASSEX wc; 225 char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; 226 HICON hIcon; 227 HICON hIconSmall; 228 char *res_name, *res_class, *res_role; 229 static int s_iWindowID = 0; 230 231#if CYGMULTIWINDOW_DEBUG 232 winDebug ("winMWExtWMCreateFrame %d %d - %d %d\n", 233 newX, newY, pFrame->width, pFrame->height); 234#endif 235 236 pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec)); 237 pRLWinPriv->pFrame = pFrame; 238 pRLWinPriv->pfb = NULL; 239 pRLWinPriv->hbmpShadow = NULL; 240 pRLWinPriv->hdcShadow = NULL; 241 pRLWinPriv->hdcScreen = NULL; 242 pRLWinPriv->pbmihShadow = NULL; 243 pRLWinPriv->fResized = TRUE; 244 pRLWinPriv->fClose = FALSE; 245 pRLWinPriv->fRestackingNow = FALSE; 246 pRLWinPriv->fDestroyed = FALSE; 247 pRLWinPriv->fMovingOrSizing = FALSE; 248 249 // Store the implementation private frame ID 250 pFrame->wid = (RootlessFrameID) pRLWinPriv; 251 252 winSelectIcons(pFrame->win, &hIcon, &hIconSmall); 253 254 /* Set standard class name prefix so we can identify window easily */ 255 strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass)); 256 257 if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class)) 258 { 259 strncat (pszClass, "-", 1); 260 strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); 261 strncat (pszClass, "-", 1); 262 strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); 263 264 /* Check if a window class is provided by the WM_WINDOW_ROLE property, 265 * if not use the WM_CLASS information. 266 * For further information see: 267 * http://tronche.com/gui/x/icccm/sec-5.html 268 */ 269 if (winMultiWindowGetWindowRole (pFrame->win, &res_role) ) 270 { 271 strcat (pszClass, "-"); 272 strcat (pszClass, res_role); 273 free (res_role); 274 } 275 276 free (res_name); 277 free (res_class); 278 } 279 280 /* Add incrementing window ID to make unique class name */ 281 snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++); 282 pszWindowID[sizeof(pszWindowID)-1] = 0; 283 strcat (pszClass, pszWindowID); 284 285#if CYGMULTIWINDOW_DEBUG 286 winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass); 287#endif 288 289 /* Setup our window class */ 290 wc.cbSize = sizeof(wc); 291 wc.style = CS_HREDRAW | CS_VREDRAW; 292 wc.lpfnWndProc = winMWExtWMWindowProc; 293 wc.cbClsExtra = 0; 294 wc.cbWndExtra = 0; 295 wc.hInstance = g_hInstance; 296 wc.hIcon = hIcon; 297 wc.hIconSm = hIconSmall; 298 wc.hCursor = 0; 299 wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); 300 wc.lpszMenuName = NULL; 301 wc.lpszClassName = pszClass; 302 RegisterClassEx (&wc); 303 304 /* Create the window */ 305 g_fNoConfigureWindow = TRUE; 306 pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ 307 pszClass, /* Class name */ 308 WINDOW_TITLE_X, /* Window name */ 309 WS_POPUP | WS_CLIPCHILDREN, 310 newX, /* Horizontal position */ 311 newY, /* Vertical position */ 312 pFrame->width, /* Right edge */ 313 pFrame->height, /* Bottom edge */ 314 (HWND) NULL, /* No parent or owner window */ 315 (HMENU) NULL, /* No menu */ 316 GetModuleHandle (NULL), /* Instance handle */ 317 pRLWinPriv); /* ScreenPrivates */ 318 if (pRLWinPriv->hWnd == NULL) 319 { 320 ErrorF ("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n", 321 (int) GetLastError ()); 322 fResult = FALSE; 323 } 324 325#if CYGMULTIWINDOW_DEBUG 326 winDebug ("winMWExtWMCreateFrame - ShowWindow\n"); 327#endif 328 329 //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); 330 g_fNoConfigureWindow = FALSE; 331 332 if (pShape != NULL) 333 { 334 winMWExtWMReshapeFrame (pFrame->wid, pShape); 335 } 336 337#if CYGMULTIWINDOW_DEBUG 338 winDebug ("winMWExtWMCreateFrame - (%08x) %08x\n", 339 (int) pFrame->wid, (int) pRLWinPriv->hWnd); 340#if 0 341 { 342 WindowPtr pWin2 = NULL; 343 win32RootlessWindowPtr pRLWinPriv2 = NULL; 344 345 /* Check if the Windows window property for our X window pointer is valid */ 346 if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) 347 { 348 pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); 349 } 350 winDebug ("winMWExtWMCreateFrame2 (%08x) %08x\n", 351 pRLWinPriv2, pRLWinPriv2->hWnd); 352 if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) 353 { 354 winDebug ("Error param missmatch\n"); 355 } 356 } 357#endif 358#endif 359 360 winMWExtWMSetNativeProperty (pFrame); 361 362 return fResult; 363} 364 365void 366winMWExtWMDestroyFrame (RootlessFrameID wid) 367{ 368 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 369 HICON hiconClass; 370 HICON hiconSmClass; 371 HMODULE hInstance; 372 int iReturn; 373 char pszClass[CLASS_NAME_LENGTH]; 374 375#if CYGMULTIWINDOW_DEBUG 376 winDebug ("winMWExtWMDestroyFrame (%08x) %08x\n", 377 (int) pRLWinPriv, (int) pRLWinPriv->hWnd); 378#if 0 379 { 380 WindowPtr pWin2 = NULL; 381 win32RootlessWindowPtr pRLWinPriv2 = NULL; 382 383 /* Check if the Windows window property for our X window pointer is valid */ 384 if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) 385 { 386 pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); 387 } 388 winDebug ("winMWExtWMDestroyFrame2 (%08x) %08x\n", 389 pRLWinPriv2, pRLWinPriv2->hWnd); 390 if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) 391 { 392 winDebug ("Error param missmatch\n"); 393 *(int*)0 = 1;//raise exseption 394 } 395 } 396#endif 397#endif 398 399 /* Store the info we need to destroy after this window is gone */ 400 hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HMODULE); 401 hiconClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICON); 402 hiconSmClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICONSM); 403 iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH); 404 405 pRLWinPriv->fClose = TRUE; 406 pRLWinPriv->fDestroyed = TRUE; 407 408 /* Destroy the Windows window */ 409 DestroyWindow (pRLWinPriv->hWnd); 410 411 /* Only if we were able to get the name */ 412 if (iReturn) 413 { 414#if CYGMULTIWINDOW_DEBUG 415 winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass); 416#endif 417 iReturn = UnregisterClass (pszClass, hInstance); 418 419#if CYGMULTIWINDOW_DEBUG 420 winDebug ("winMWExtWMDestroyFramew - %d Deleting Icon: ", iReturn); 421#endif 422 423 winDestroyIcon(hiconClass); 424 winDestroyIcon(hiconSmClass); 425 } 426 427#if CYGMULTIWINDOW_DEBUG 428 winDebug ("winMWExtWMDestroyFrame - done\n"); 429#endif 430} 431 432void 433winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY) 434{ 435 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 436 RECT rcNew; 437 DWORD dwExStyle; 438 DWORD dwStyle; 439 int iX, iY, iWidth, iHeight; 440 441#if CYGMULTIWINDOW_DEBUG 442 winDebug ("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY); 443#endif 444 445 /* Get the Windows window style and extended style */ 446 dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); 447 dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); 448 449 /* Get the X and Y location of the X window */ 450 iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); 451 iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); 452 453 /* Get the height and width of the X window */ 454 iWidth = pRLWinPriv->pFrame->width; 455 iHeight = pRLWinPriv->pFrame->height; 456 457 /* Store the origin, height, and width in a rectangle structure */ 458 SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); 459 460#ifdef CYGMULTIWINDOW_DEBUG 461 winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n", 462 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, 463 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); 464#endif 465 /* 466 * Calculate the required size of the Windows window rectangle, 467 * given the size of the Windows window client area. 468 */ 469 AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); 470 471#ifdef CYGMULTIWINDOW_DEBUG 472 winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", 473 rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, 474 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); 475#endif 476 g_fNoConfigureWindow = TRUE; 477 SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0, 478 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); 479 g_fNoConfigureWindow = FALSE; 480#if CYGMULTIWINDOW_DEBUG 481 winDebug ("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv); 482#endif 483} 484 485void 486winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, 487 int iNewX, int iNewY, 488 unsigned int uiNewWidth, unsigned int uiNewHeight, 489 unsigned int uiGravity) 490{ 491 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 492 RECT rcNew; 493 RECT rcOld; 494 DWORD dwExStyle; 495 DWORD dwStyle; 496 int iX, iY; 497 498#if CYGMULTIWINDOW_DEBUG 499 winDebug ("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n", 500 (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight); 501#endif 502 503 pRLWinPriv->fResized = TRUE; 504 505 /* Get the Windows window style and extended style */ 506 dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); 507 dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); 508 509 /* Get the X and Y location of the X window */ 510 iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); 511 iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); 512 513 /* Store the origin, height, and width in a rectangle structure */ 514 SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight); 515 516 /* 517 * Calculate the required size of the Windows window rectangle, 518 * given the size of the Windows window client area. 519 */ 520 AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); 521 522 /* Get a rectangle describing the old Windows window */ 523 GetWindowRect (pRLWinPriv->hWnd, &rcOld); 524 525 /* Check if the old rectangle and new rectangle are the same */ 526 if (!EqualRect (&rcNew, &rcOld)) 527 { 528 529 g_fNoConfigureWindow = TRUE; 530 MoveWindow (pRLWinPriv->hWnd, 531 rcNew.left, rcNew.top, 532 rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 533 TRUE); 534 g_fNoConfigureWindow = FALSE; 535 } 536} 537 538void 539winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid) 540{ 541 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 542 win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid; 543 winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen); 544 winScreenInfo *pScreenInfo = NULL; 545 DWORD dwCurrentProcessID = GetCurrentProcessId (); 546 DWORD dwWindowProcessID = 0; 547 HWND hWnd; 548 Bool fFirst = TRUE; 549 Bool fNeedRestack = TRUE; 550#if CYGMULTIWINDOW_DEBUG 551 winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv); 552#endif 553 554 if (pScreenPriv->fRestacking) return; 555 556 if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; 557 558 pRLWinPriv->fRestackingNow = TRUE; 559 560 /* Show window */ 561 if(!IsWindowVisible (pRLWinPriv->hWnd)) 562 ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); 563 564 if (pRLNextWinPriv == NULL) 565 { 566#if CYGMULTIWINDOW_DEBUG 567 winDebug ("Win %08x is top\n", pRLWinPriv); 568#endif 569 pScreenPriv->widTop = wid; 570 SetWindowPos (pRLWinPriv->hWnd, HWND_TOP, 571 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); 572 } 573 else if (winIsInternalWMRunning(pScreenInfo)) 574 { 575 /* using mulwinidow wm */ 576#if CYGMULTIWINDOW_DEBUG 577 winDebug ("Win %08x is not top\n", pRLWinPriv); 578#endif 579 for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV); 580 fNeedRestack && hWnd != NULL; 581 hWnd = GetNextWindow (hWnd, GW_HWNDPREV)) 582 { 583 GetWindowThreadProcessId (hWnd, &dwWindowProcessID); 584 585 if ((dwWindowProcessID == dwCurrentProcessID) 586 && GetProp (hWnd, WIN_WINDOW_PROP)) 587 { 588 if (hWnd == pRLNextWinPriv->hWnd) 589 { 590 /* Enable interleave X window and Windows window */ 591 if (!fFirst) 592 { 593#if CYGMULTIWINDOW_DEBUG 594 winDebug ("raise: Insert after Win %08x\n", pRLNextWinPriv); 595#endif 596 SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, 597 0, 0, 0, 0, 598 SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); 599 } 600 else 601 { 602#if CYGMULTIWINDOW_DEBUG 603 winDebug ("No change\n"); 604#endif 605 } 606 fNeedRestack = FALSE; 607 break; 608 } 609 if (fFirst) fFirst = FALSE; 610 } 611 } 612 613 for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDNEXT); 614 fNeedRestack && hWnd != NULL; 615 hWnd = GetNextWindow (hWnd, GW_HWNDNEXT)) 616 { 617 GetWindowThreadProcessId (hWnd, &dwWindowProcessID); 618 619 if ((dwWindowProcessID == dwCurrentProcessID) 620 && GetProp (hWnd, WIN_WINDOW_PROP)) 621 { 622 if (hWnd == pRLNextWinPriv->hWnd) 623 { 624#if CYGMULTIWINDOW_DEBUG 625 winDebug ("lower: Insert after Win %08x\n", pRLNextWinPriv); 626#endif 627 SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, 628 0, 0, 0, 0, 629 SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); 630 fNeedRestack = FALSE; 631 break; 632 } 633 } 634 } 635 } 636 else 637 { 638 /* using general wm like twm, wmaker etc. 639 Interleave X window and Windows window will cause problem. */ 640 SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, 641 0, 0, 0, 0, 642 SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); 643#if 0 644#endif 645 } 646#if CYGMULTIWINDOW_DEBUG 647 winDebug ("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv); 648#endif 649 650 pRLWinPriv->fRestackingNow = FALSE; 651} 652 653void 654winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape) 655{ 656 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 657 HRGN hRgn, hRgnWindow, hRgnClient; 658 RECT rcWindow, rcClient; 659#if CYGMULTIWINDOW_DEBUG 660 winDebug ("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv); 661#endif 662 663 hRgn = winMWExtWMCreateRgnFromRegion (pShape); 664 665 /* Create region for non-client area */ 666 GetWindowRect (pRLWinPriv->hWnd, &rcWindow); 667 GetClientRect (pRLWinPriv->hWnd, &rcClient); 668 MapWindowPoints (pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); 669 OffsetRgn (hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top); 670 OffsetRect (&rcClient, -rcWindow.left, -rcWindow.top); 671 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top); 672 hRgnWindow = CreateRectRgnIndirect (&rcWindow); 673 hRgnClient = CreateRectRgnIndirect (&rcClient); 674 CombineRgn (hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF); 675 CombineRgn (hRgn, hRgnWindow, hRgn, RGN_OR); 676 677 678 SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE); 679 680 DeleteObject (hRgnWindow); 681 DeleteObject (hRgnClient); 682} 683 684void 685winMWExtWMUnmapFrame (RootlessFrameID wid) 686{ 687 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 688#if CYGMULTIWINDOW_DEBUG 689 winDebug ("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv); 690#endif 691 692 g_fNoConfigureWindow = TRUE; 693 //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE); 694 ShowWindow (pRLWinPriv->hWnd, SW_HIDE); 695 g_fNoConfigureWindow = FALSE; 696} 697 698/* 699 * Fixme: Code sharing with winshadgdi.c and other engine support 700 */ 701void 702winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) 703{ 704 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 705 winPrivScreenPtr pScreenPriv = NULL; 706 winScreenInfo *pScreenInfo = NULL; 707 ScreenPtr pScreen = NULL; 708 DIBSECTION dibsection; 709 Bool fReturn = TRUE; 710 HDC hdcNew; 711 HBITMAP hbmpNew; 712#if CYGMULTIWINDOW_DEBUG 713 winDebug ("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed); 714#endif 715 716 if (!pRLWinPriv->fDestroyed) 717 { 718 pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; 719 if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); 720 if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; 721 722#if CYGMULTIWINDOW_DEBUG 723 winDebug ("\tpScreenPriv %08X\n", (int) pScreenPriv); 724 winDebug ("\tpScreenInfo %08X\n", (int) pScreenInfo); 725 winDebug ("\t(%d, %d)\n", (int)pRLWinPriv->pFrame->width, 726 (int) pRLWinPriv->pFrame->height); 727#endif 728 if (pRLWinPriv->hdcScreen == NULL) 729 { 730 InitWin32RootlessEngine (pRLWinPriv); 731 } 732 733 if (pRLWinPriv->fResized) 734 { 735 /* width * bpp must be multiple of 4 to match 32bit alignment */ 736 int stridesize; 737 int misalignment; 738 739 pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width; 740 pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height; 741 742 stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3); 743 misalignment = stridesize & 3; 744 if (misalignment != 0) 745 { 746 stridesize += 4 - misalignment; 747 pRLWinPriv->pbmihShadow->biWidth = stridesize / (pScreenInfo->dwBPP >> 3); 748 winDebug("\tresizing to %d (was %d)\n", 749 pRLWinPriv->pbmihShadow->biWidth, pRLWinPriv->pFrame->width); 750 } 751 752 hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen); 753 /* Create a DI shadow bitmap with a bit pointer */ 754 hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen, 755 (BITMAPINFO *) pRLWinPriv->pbmihShadow, 756 DIB_RGB_COLORS, 757 (VOID**) &pRLWinPriv->pfb, 758 NULL, 759 0); 760 if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) 761 { 762 ErrorF ("winMWExtWMStartDrawing - CreateDIBSection failed\n"); 763 //return FALSE; 764 } 765 else 766 { 767#if CYGMULTIWINDOW_DEBUG 768 winDebug ("winMWExtWMStartDrawing - Shadow buffer allocated\n"); 769#endif 770 } 771 772 /* Get information about the bitmap that was allocated */ 773 GetObject (hbmpNew, sizeof (dibsection), &dibsection); 774 775#if CYGMULTIWINDOW_DEBUG 776 /* Print information about bitmap allocated */ 777 winDebug ("winMWExtWMStartDrawing - Dibsection width: %d height: %d " 778 "depth: %d size image: %d\n", 779 (unsigned int)dibsection.dsBmih.biWidth, 780 (unsigned int)dibsection.dsBmih.biHeight, 781 (unsigned int)dibsection.dsBmih.biBitCount, 782 (unsigned int)dibsection.dsBmih.biSizeImage); 783#endif 784 785 /* Select the shadow bitmap into the shadow DC */ 786 SelectObject (hdcNew, hbmpNew); 787 788#if CYGMULTIWINDOW_DEBUG 789 winDebug ("winMWExtWMStartDrawing - Attempting a shadow blit\n"); 790#endif 791 792 /* Blit from the old shadow to the new shadow */ 793 fReturn = BitBlt (hdcNew, 794 0, 0, 795 pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height, 796 pRLWinPriv->hdcShadow, 797 0, 0, 798 SRCCOPY); 799 if (fReturn) 800 { 801#if CYGMULTIWINDOW_DEBUG 802 winDebug ("winMWExtWMStartDrawing - Shadow blit success\n"); 803#endif 804 } 805 else 806 { 807 ErrorF ("winMWExtWMStartDrawing - Shadow blit failure\n"); 808 } 809 810 /* Look for height weirdness */ 811 if (dibsection.dsBmih.biHeight < 0) 812 { 813 /* FIXME: Figure out why biHeight is sometimes negative */ 814 ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " 815 "biHeight still negative: %d\n", 816 (int) dibsection.dsBmih.biHeight); 817 ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " 818 "Flipping biHeight sign\n"); 819 dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; 820 } 821 822 pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes; 823 824#if CYGMULTIWINDOW_DEBUG 825 winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n", 826 (unsigned int)dibsection.dsBm.bmWidthBytes); 827#endif 828 829 /* Free the old shadow bitmap */ 830 DeleteObject (pRLWinPriv->hdcShadow); 831 DeleteObject (pRLWinPriv->hbmpShadow); 832 833 pRLWinPriv->hdcShadow = hdcNew; 834 pRLWinPriv->hbmpShadow = hbmpNew; 835 836 pRLWinPriv->fResized = FALSE; 837#if CYGMULTIWINDOW_DEBUG && FALSE 838 winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n", 839 (unsigned int)pRLWinPriv->pfb, 840 (unsigned int)dibsection.dsBm.bmWidthBytes); 841#endif 842 } 843 } 844 else 845 { 846 ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n"); 847 } 848#if CYGMULTIWINDOW_DEBUG 849 winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n", 850 (int) pRLWinPriv, 851 (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes); 852#endif 853 *pixelData = pRLWinPriv->pfb; 854 *bytesPerRow = pRLWinPriv->dwWidthBytes; 855} 856 857void 858winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush) 859{ 860#if 0 861 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 862 BLENDFUNCTION bfBlend; 863 SIZE szWin; 864 POINT ptSrc; 865#if CYGMULTIWINDOW_DEBUG || TRUE 866 winDebug ("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv); 867#endif 868 szWin.cx = pRLWinPriv->dwWidth; 869 szWin.cy = pRLWinPriv->dwHeight; 870 ptSrc.x = 0; 871 ptSrc.y = 0; 872 bfBlend.BlendOp = AC_SRC_OVER; 873 bfBlend.BlendFlags = 0; 874 bfBlend.SourceConstantAlpha = 255; 875 bfBlend.AlphaFormat = AC_SRC_ALPHA; 876 877 if (!UpdateLayeredWindow (pRLWinPriv->hWnd, 878 NULL, NULL, &szWin, 879 pRLWinPriv->hdcShadow, &ptSrc, 880 0, &bfBlend, ULW_ALPHA)) 881 { 882 ErrorF ("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n"); 883 } 884#endif 885} 886 887void 888winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage) 889{ 890 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 891#if 0 892 BLENDFUNCTION bfBlend; 893 SIZE szWin; 894 POINT ptSrc; 895#endif 896#if CYGMULTIWINDOW_DEBUG && 0 897 winDebug ("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv); 898#endif 899#if 0 900 szWin.cx = pRLWinPriv->dwWidth; 901 szWin.cy = pRLWinPriv->dwHeight; 902 ptSrc.x = 0; 903 ptSrc.y = 0; 904 bfBlend.BlendOp = AC_SRC_OVER; 905 bfBlend.BlendFlags = 0; 906 bfBlend.SourceConstantAlpha = 255; 907 bfBlend.AlphaFormat = AC_SRC_ALPHA; 908 909 if (!UpdateLayeredWindow (pRLWinPriv->hWnd, 910 NULL, NULL, &szWin, 911 pRLWinPriv->hdcShadow, &ptSrc, 912 0, &bfBlend, ULW_ALPHA)) 913 { 914 LPVOID lpMsgBuf; 915 916 /* Display a fancy error message */ 917 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | 918 FORMAT_MESSAGE_FROM_SYSTEM | 919 FORMAT_MESSAGE_IGNORE_INSERTS, 920 NULL, 921 GetLastError (), 922 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 923 (LPTSTR) &lpMsgBuf, 924 0, NULL); 925 926 ErrorF ("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n", 927 (LPSTR)lpMsgBuf); 928 LocalFree (lpMsgBuf); 929 } 930#endif 931 if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd); 932} 933 934void 935winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects, 936 int shift_x, int shift_y) 937{ 938 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 939 const BoxRec *pEnd; 940#if CYGMULTIWINDOW_DEBUG && 0 941 winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n", 942 pRLWinPriv, nCount, pRects, shift_x, shift_y); 943#endif 944 945 for (pEnd = pRects + nCount; pRects < pEnd; pRects++) { 946 RECT rcDmg; 947 rcDmg.left = pRects->x1 + shift_x; 948 rcDmg.top = pRects->y1 + shift_y; 949 rcDmg.right = pRects->x2 + shift_x; 950 rcDmg.bottom = pRects->y2 + shift_y; 951 952 InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); 953 } 954} 955 956void 957winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin) 958{ 959 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; 960#if CYGMULTIWINDOW_DEBUG 961 winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n", 962 (int) pRLWinPriv, (int) pRLWinPriv->hWnd); 963#endif 964 pRLWinPriv->pFrame = pFrame; 965 pRLWinPriv->fResized = TRUE; 966 967 /* Set the window extended style flags */ 968 SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); 969 970 /* Set the window standard style flags */ 971 SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, 972 WS_POPUP | WS_CLIPCHILDREN); 973 974 DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ()); 975 winMWExtWMSetNativeProperty (pFrame); 976#if CYGMULTIWINDOW_DEBUG 977#if 0 978 { 979 WindowPtr pWin2 = NULL; 980 win32RootlessWindowPtr pRLWinPriv2 = NULL; 981 982 /* Check if the Windows window property for our X window pointer is valid */ 983 if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) 984 { 985 pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); 986 } 987 winDebug ("winMWExtWMSwitchFrame2 (%08x) %08x\n", 988 pRLWinPriv2, pRLWinPriv2->hWnd); 989 if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) 990 { 991 winDebug ("Error param missmatch\n"); 992 } 993 } 994#endif 995#endif 996} 997 998void 999winMWExtWMCopyBytes (unsigned int width, unsigned int height, 1000 const void *src, unsigned int srcRowBytes, 1001 void *dst, unsigned int dstRowBytes) 1002{ 1003#if CYGMULTIWINDOW_DEBUG 1004 winDebug ("winMWExtWMCopyBytes - Not implemented\n"); 1005#endif 1006} 1007 1008void 1009winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects, 1010 int nDx, int nDy) 1011{ 1012 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; 1013 const BoxRec *pEnd; 1014 RECT rcDmg; 1015#if CYGMULTIWINDOW_DEBUG 1016 winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n", 1017 (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy); 1018#endif 1019 1020 for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) 1021 { 1022#if CYGMULTIWINDOW_DEBUG 1023 winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n", 1024 pDstRects->x1, pDstRects->y1, 1025 pDstRects->x2 - pDstRects->x1, 1026 pDstRects->y2 - pDstRects->y1, 1027 pDstRects->x1 + nDx, 1028 pDstRects->y1 + nDy); 1029#endif 1030 1031 if (!BitBlt (pRLWinPriv->hdcShadow, 1032 pDstRects->x1, pDstRects->y1, 1033 pDstRects->x2 - pDstRects->x1, 1034 pDstRects->y2 - pDstRects->y1, 1035 pRLWinPriv->hdcShadow, 1036 pDstRects->x1 + nDx, pDstRects->y1 + nDy, 1037 SRCCOPY)) 1038 { 1039 ErrorF ("winMWExtWMCopyWindow - BitBlt failed.\n"); 1040 } 1041 1042 rcDmg.left = pDstRects->x1; 1043 rcDmg.top = pDstRects->y1; 1044 rcDmg.right = pDstRects->x2; 1045 rcDmg.bottom = pDstRects->y2; 1046 1047 InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); 1048 } 1049#if CYGMULTIWINDOW_DEBUG 1050 winDebug ("winMWExtWMCopyWindow - done\n"); 1051#endif 1052} 1053 1054 1055/* 1056 * winMWExtWMSetNativeProperty 1057 */ 1058 1059static void 1060winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame) 1061{ 1062 win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; 1063 long lData; 1064 1065 /* FIXME: move this to WindowsWM extension */ 1066 1067 lData = (long) pRLWinPriv->hWnd; 1068 dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(), 1069 XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE); 1070} 1071