xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

winmultiwindowwindow.c (36147B)


      1 /*
      2  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
      3  *Copyright (C) Colin Harrison 2005-2008
      4  *
      5  *Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  *"Software"), to deal in the Software without restriction, including
      8  *without limitation the rights to use, copy, modify, merge, publish,
      9  *distribute, sublicense, and/or sell copies of the Software, and to
     10  *permit persons to whom the Software is furnished to do so, subject to
     11  *the following conditions:
     12  *
     13  *The above copyright notice and this permission notice shall be
     14  *included in all copies or substantial portions of the Software.
     15  *
     16  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     17  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19  *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
     20  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
     21  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     22  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  *Except as contained in this notice, the name of the XFree86 Project
     25  *shall not be used in advertising or otherwise to promote the sale, use
     26  *or other dealings in this Software without prior written authorization
     27  *from the XFree86 Project.
     28  *
     29  * Authors:	Kensuke Matsuzaki
     30  *		Earle F. Philhower, III
     31  *		Harold L Hunt II
     32  *              Colin Harrison
     33  */
     34 
     35 #ifdef HAVE_XWIN_CONFIG_H
     36 #include <xwin-config.h>
     37 #endif
     38 
     39 #include "win.h"
     40 #include "dixevents.h"
     41 #include "winmultiwindowclass.h"
     42 #include "winmultiwindowicons.h"
     43 
     44 /*
     45  * Prototypes for local functions
     46  */
     47 
     48 void
     49  winCreateWindowsWindow(WindowPtr pWin);
     50 
     51 static void
     52  winDestroyWindowsWindow(WindowPtr pWin);
     53 
     54 static void
     55  winUpdateWindowsWindow(WindowPtr pWin);
     56 
     57 static void
     58  winFindWindow(void *value, XID id, void *cdata);
     59 
     60 static
     61     void
     62 winInitMultiWindowClass(void)
     63 {
     64     static wATOM atomXWinClass = 0;
     65     WNDCLASSEX wcx;
     66 
     67     if (atomXWinClass == 0) {
     68         HICON hIcon, hIconSmall;
     69 
     70         /* Load the default icons */
     71         winSelectIcons(&hIcon, &hIconSmall);
     72 
     73         /* Setup our window class */
     74         wcx.cbSize = sizeof(WNDCLASSEX);
     75         wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
     76         wcx.lpfnWndProc = winTopLevelWindowProc;
     77         wcx.cbClsExtra = 0;
     78         wcx.cbWndExtra = 0;
     79         wcx.hInstance = g_hInstance;
     80         wcx.hIcon = hIcon;
     81         wcx.hCursor = 0;
     82         wcx.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
     83         wcx.lpszMenuName = NULL;
     84         wcx.lpszClassName = WINDOW_CLASS_X;
     85         wcx.hIconSm = hIconSmall;
     86 
     87 #if CYGMULTIWINDOW_DEBUG
     88         ErrorF("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
     89 #endif
     90 
     91         atomXWinClass = RegisterClassEx(&wcx);
     92     }
     93 }
     94 
     95 /*
     96  * CreateWindow - See Porting Layer Definition - p. 37
     97  */
     98 
     99 Bool
    100 winCreateWindowMultiWindow(WindowPtr pWin)
    101 {
    102     Bool fResult = TRUE;
    103     ScreenPtr pScreen = pWin->drawable.pScreen;
    104 
    105     winWindowPriv(pWin);
    106     winScreenPriv(pScreen);
    107 
    108 #if CYGMULTIWINDOW_DEBUG
    109     winTrace("winCreateWindowMultiWindow - pWin: %p\n", pWin);
    110 #endif
    111 
    112     WIN_UNWRAP(CreateWindow);
    113     fResult = (*pScreen->CreateWindow) (pWin);
    114     WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
    115 
    116     /* Initialize some privates values */
    117     pWinPriv->hRgn = NULL;
    118     pWinPriv->hWnd = NULL;
    119     pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
    120     pWinPriv->fXKilled = FALSE;
    121 #ifdef XWIN_GLX_WINDOWS
    122     pWinPriv->fWglUsed = FALSE;
    123 #endif
    124 
    125     return fResult;
    126 }
    127 
    128 /*
    129  * DestroyWindow - See Porting Layer Definition - p. 37
    130  */
    131 
    132 Bool
    133 winDestroyWindowMultiWindow(WindowPtr pWin)
    134 {
    135     Bool fResult = TRUE;
    136     ScreenPtr pScreen = pWin->drawable.pScreen;
    137 
    138     winWindowPriv(pWin);
    139     winScreenPriv(pScreen);
    140 
    141 #if CYGMULTIWINDOW_DEBUG
    142     ErrorF("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
    143 #endif
    144 
    145     WIN_UNWRAP(DestroyWindow);
    146     fResult = (*pScreen->DestroyWindow) (pWin);
    147     WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
    148 
    149     /* Flag that the window has been destroyed */
    150     pWinPriv->fXKilled = TRUE;
    151 
    152     /* Kill the MS Windows window associated with this window */
    153     winDestroyWindowsWindow(pWin);
    154 
    155     return fResult;
    156 }
    157 
    158 /*
    159  * PositionWindow - See Porting Layer Definition - p. 37
    160  *
    161  * This function adjusts the position and size of Windows window
    162  * with respect to the underlying X window.  This is the inverse
    163  * of winAdjustXWindow, which adjusts X window to Windows window.
    164  */
    165 
    166 Bool
    167 winPositionWindowMultiWindow(WindowPtr pWin, int x, int y)
    168 {
    169     Bool fResult = TRUE;
    170     int iX, iY, iWidth, iHeight;
    171     ScreenPtr pScreen = pWin->drawable.pScreen;
    172 
    173     winWindowPriv(pWin);
    174     winScreenPriv(pScreen);
    175 
    176     HWND hWnd = pWinPriv->hWnd;
    177     RECT rcNew;
    178     RECT rcOld;
    179 
    180 #if CYGMULTIWINDOW_DEBUG
    181     RECT rcClient;
    182     RECT *lpRc;
    183 #endif
    184     DWORD dwExStyle;
    185     DWORD dwStyle;
    186 
    187 #if CYGMULTIWINDOW_DEBUG
    188     winTrace("winPositionWindowMultiWindow - pWin: %p\n", pWin);
    189 #endif
    190 
    191     WIN_UNWRAP(PositionWindow);
    192     fResult = (*pScreen->PositionWindow) (pWin, x, y);
    193     WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
    194 
    195 #if CYGWINDOWING_DEBUG
    196     ErrorF("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", x, y);
    197 #endif
    198 
    199     /* Bail out if the Windows window handle is bad */
    200     if (!hWnd) {
    201 #if CYGWINDOWING_DEBUG
    202         ErrorF("\timmediately return since hWnd is NULL\n");
    203 #endif
    204         return fResult;
    205     }
    206 
    207     /* Get the Windows window style and extended style */
    208     dwExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
    209     dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
    210 
    211     /* Get the X and Y location of the X window */
    212     iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
    213     iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
    214 
    215     /* Get the height and width of the X window */
    216     iWidth = pWin->drawable.width;
    217     iHeight = pWin->drawable.height;
    218 
    219     /* Store the origin, height, and width in a rectangle structure */
    220     SetRect(&rcNew, iX, iY, iX + iWidth, iY + iHeight);
    221 
    222 #if CYGMULTIWINDOW_DEBUG
    223     lpRc = &rcNew;
    224     ErrorF("winPositionWindowMultiWindow - drawable (%d, %d)-(%d, %d)\n",
    225            (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
    226 #endif
    227 
    228     /*
    229      * Calculate the required size of the Windows window rectangle,
    230      * given the size of the Windows window client area.
    231      */
    232     AdjustWindowRectEx(&rcNew, dwStyle, FALSE, dwExStyle);
    233 
    234     /* Get a rectangle describing the old Windows window */
    235     GetWindowRect(hWnd, &rcOld);
    236 
    237 #if CYGMULTIWINDOW_DEBUG
    238     /* Get a rectangle describing the Windows window client area */
    239     GetClientRect(hWnd, &rcClient);
    240 
    241     lpRc = &rcNew;
    242     ErrorF("winPositionWindowMultiWindow - rcNew (%d, %d)-(%d, %d)\n",
    243            (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
    244 
    245     lpRc = &rcOld;
    246     ErrorF("winPositionWindowMultiWindow - rcOld (%d, %d)-(%d, %d)\n",
    247            (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
    248 
    249     lpRc = &rcClient;
    250     ErrorF("rcClient (%d, %d)-(%d, %d)\n",
    251            (int)lpRc->left, (int)lpRc->top, (int)lpRc->right, (int)lpRc->bottom);
    252 #endif
    253 
    254     /* Check if the old rectangle and new rectangle are the same */
    255     if (!EqualRect(&rcNew, &rcOld)) {
    256 #if CYGMULTIWINDOW_DEBUG
    257         ErrorF("winPositionWindowMultiWindow - Need to move\n");
    258 #endif
    259 
    260 #if CYGWINDOWING_DEBUG
    261         ErrorF("\tMoveWindow to (%d, %d) - %dx%d\n", (int)rcNew.left, (int)rcNew.top,
    262                (int)(rcNew.right - rcNew.left), (int)(rcNew.bottom - rcNew.top));
    263 #endif
    264         /* Change the position and dimensions of the Windows window */
    265         MoveWindow(hWnd,
    266                    rcNew.left, rcNew.top,
    267                    rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, TRUE);
    268     }
    269     else {
    270 #if CYGMULTIWINDOW_DEBUG
    271         ErrorF("winPositionWindowMultiWindow - Not need to move\n");
    272 #endif
    273     }
    274 
    275     return fResult;
    276 }
    277 
    278 /*
    279  * ChangeWindowAttributes - See Porting Layer Definition - p. 37
    280  */
    281 
    282 Bool
    283 winChangeWindowAttributesMultiWindow(WindowPtr pWin, unsigned long mask)
    284 {
    285     Bool fResult = TRUE;
    286     ScreenPtr pScreen = pWin->drawable.pScreen;
    287 
    288     winScreenPriv(pScreen);
    289 
    290 #if CYGMULTIWINDOW_DEBUG
    291     ErrorF("winChangeWindowAttributesMultiWindow - pWin: %p\n", pWin);
    292 #endif
    293 
    294     WIN_UNWRAP(ChangeWindowAttributes);
    295     fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask);
    296     WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
    297 
    298     /*
    299      * NOTE: We do not currently need to do anything here.
    300      */
    301 
    302     return fResult;
    303 }
    304 
    305 /*
    306  * UnmapWindow - See Porting Layer Definition - p. 37
    307  * Also referred to as UnrealizeWindow
    308  */
    309 
    310 Bool
    311 winUnmapWindowMultiWindow(WindowPtr pWin)
    312 {
    313     Bool fResult = TRUE;
    314     ScreenPtr pScreen = pWin->drawable.pScreen;
    315 
    316     winWindowPriv(pWin);
    317     winScreenPriv(pScreen);
    318 
    319 #if CYGMULTIWINDOW_DEBUG
    320     ErrorF("winUnmapWindowMultiWindow - pWin: %p\n", pWin);
    321 #endif
    322 
    323     WIN_UNWRAP(UnrealizeWindow);
    324     fResult = (*pScreen->UnrealizeWindow) (pWin);
    325     WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
    326 
    327     /* Flag that the window has been killed */
    328     pWinPriv->fXKilled = TRUE;
    329 
    330     /* Destroy the Windows window associated with this X window */
    331     winDestroyWindowsWindow(pWin);
    332 
    333     return fResult;
    334 }
    335 
    336 /*
    337  * MapWindow - See Porting Layer Definition - p. 37
    338  * Also referred to as RealizeWindow
    339  */
    340 
    341 Bool
    342 winMapWindowMultiWindow(WindowPtr pWin)
    343 {
    344     Bool fResult = TRUE;
    345     ScreenPtr pScreen = pWin->drawable.pScreen;
    346 
    347     winWindowPriv(pWin);
    348     winScreenPriv(pScreen);
    349 
    350 #if CYGMULTIWINDOW_DEBUG
    351     ErrorF("winMapWindowMultiWindow - pWin: %p\n", pWin);
    352 #endif
    353 
    354     WIN_UNWRAP(RealizeWindow);
    355     fResult = (*pScreen->RealizeWindow) (pWin);
    356     WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
    357 
    358     /* Flag that this window has not been destroyed */
    359     pWinPriv->fXKilled = FALSE;
    360 
    361     /* Refresh/redisplay the Windows window associated with this X window */
    362     winUpdateWindowsWindow(pWin);
    363 
    364     /* Update the Windows window's shape */
    365     winReshapeMultiWindow(pWin);
    366     winUpdateRgnMultiWindow(pWin);
    367 
    368     return fResult;
    369 }
    370 
    371 /*
    372  * ReparentWindow - See Porting Layer Definition - p. 42
    373  */
    374 
    375 void
    376 winReparentWindowMultiWindow(WindowPtr pWin, WindowPtr pPriorParent)
    377 {
    378     ScreenPtr pScreen = pWin->drawable.pScreen;
    379 
    380     winScreenPriv(pScreen);
    381 
    382     winDebug
    383         ("winReparentMultiWindow - pWin:%p XID:0x%x, reparent from pWin:%p XID:0x%x to pWin:%p XID:0x%x\n",
    384          pWin, (unsigned int)pWin->drawable.id,
    385          pPriorParent, (unsigned int)pPriorParent->drawable.id,
    386          pWin->parent, (unsigned int)pWin->parent->drawable.id);
    387 
    388     WIN_UNWRAP(ReparentWindow);
    389     if (pScreen->ReparentWindow)
    390         (*pScreen->ReparentWindow) (pWin, pPriorParent);
    391     WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
    392 
    393     /* Update the Windows window associated with this X window */
    394     winUpdateWindowsWindow(pWin);
    395 }
    396 
    397 /*
    398  * RestackWindow - Shuffle the z-order of a window
    399  */
    400 
    401 void
    402 winRestackWindowMultiWindow(WindowPtr pWin, WindowPtr pOldNextSib)
    403 {
    404 #if 0
    405     WindowPtr pPrevWin;
    406     UINT uFlags;
    407     HWND hInsertAfter;
    408     HWND hWnd = NULL;
    409 #endif
    410     ScreenPtr pScreen = pWin->drawable.pScreen;
    411 
    412     winScreenPriv(pScreen);
    413 
    414 #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
    415     winTrace("winRestackMultiWindow - %p\n", pWin);
    416 #endif
    417 
    418     WIN_UNWRAP(RestackWindow);
    419     if (pScreen->RestackWindow)
    420         (*pScreen->RestackWindow) (pWin, pOldNextSib);
    421     WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
    422 
    423 #if 1
    424     /*
    425      * Calling winReorderWindowsMultiWindow here means our window manager
    426      * (i.e. Windows Explorer) has initiative to determine Z order.
    427      */
    428     if (pWin->nextSib != pOldNextSib)
    429         winReorderWindowsMultiWindow();
    430 #else
    431     /* Bail out if no window privates or window handle is invalid */
    432     if (!pWinPriv || !pWinPriv->hWnd)
    433         return;
    434 
    435     /* Get a pointer to our previous sibling window */
    436     pPrevWin = pWin->prevSib;
    437 
    438     /*
    439      * Look for a sibling window with
    440      * valid privates and window handle
    441      */
    442     while (pPrevWin && !winGetWindowPriv(pPrevWin)
    443            && !winGetWindowPriv(pPrevWin)->hWnd)
    444         pPrevWin = pPrevWin->prevSib;
    445 
    446     /* Check if we found a valid sibling */
    447     if (pPrevWin) {
    448         /* Valid sibling - get handle to insert window after */
    449         hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
    450         uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
    451 
    452         hWnd = GetNextWindow(pWinPriv->hWnd, GW_HWNDPREV);
    453 
    454         do {
    455             if (GetProp(hWnd, WIN_WINDOW_PROP)) {
    456                 if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) {
    457                     uFlags |= SWP_NOZORDER;
    458                 }
    459                 break;
    460             }
    461             hWnd = GetNextWindow(hWnd, GW_HWNDPREV);
    462         }
    463         while (hWnd);
    464     }
    465     else {
    466         /* No valid sibling - make this window the top window */
    467         hInsertAfter = HWND_TOP;
    468         uFlags = SWP_NOMOVE | SWP_NOSIZE;
    469     }
    470 
    471     /* Perform the restacking operation in Windows */
    472     SetWindowPos(pWinPriv->hWnd, hInsertAfter, 0, 0, 0, 0, uFlags);
    473 #endif
    474 }
    475 
    476 /*
    477  * winCreateWindowsWindow - Create a Windows window associated with an X window
    478  */
    479 
    480 void
    481 winCreateWindowsWindow(WindowPtr pWin)
    482 {
    483     int iX, iY;
    484     int iWidth;
    485     int iHeight;
    486     HWND hWnd;
    487     HWND hFore = NULL;
    488 
    489     winWindowPriv(pWin);
    490     WinXSizeHints hints;
    491     Window daddyId;
    492     DWORD dwStyle, dwExStyle;
    493     RECT rc;
    494 
    495     winInitMultiWindowClass();
    496 
    497     winDebug("winCreateWindowsTopLevelWindow - pWin:%p XID:0x%x \n", pWin,
    498              (unsigned int)pWin->drawable.id);
    499 
    500     iX = pWin->drawable.x + GetSystemMetrics(SM_XVIRTUALSCREEN);
    501     iY = pWin->drawable.y + GetSystemMetrics(SM_YVIRTUALSCREEN);
    502 
    503     iWidth = pWin->drawable.width;
    504     iHeight = pWin->drawable.height;
    505 
    506     /* If it's an InputOutput window, and so is going to end up being made visible,
    507        make sure the window actually ends up somewhere where it will be visible
    508 
    509        To handle arrangements of monitors which form a non-rectangular virtual
    510        desktop, check if the window will end up with its top-left corner on any
    511        monitor
    512     */
    513     if (pWin->drawable.class != InputOnly) {
    514         POINT pt = { iX, iY };
    515         if (MonitorFromPoint(pt, MONITOR_DEFAULTTONULL) == NULL)
    516             {
    517                 iX = CW_USEDEFAULT;
    518                 iY = CW_USEDEFAULT;
    519             }
    520     }
    521 
    522     winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
    523              iY);
    524 
    525     if (winMultiWindowGetTransientFor(pWin, &daddyId)) {
    526         if (daddyId) {
    527             WindowPtr pParent;
    528             int res = dixLookupWindow(&pParent, daddyId, serverClient, DixReadAccess);
    529             if (res == Success)
    530                 {
    531                     winPrivWinPtr pParentPriv = winGetWindowPriv(pParent);
    532                     hFore = pParentPriv->hWnd;
    533                 }
    534         }
    535     }
    536     else {
    537         /* Default positions if none specified */
    538         if (!winMultiWindowGetWMNormalHints(pWin, &hints))
    539             hints.flags = 0;
    540         if (!(hints.flags & (USPosition | PPosition)) &&
    541             !pWin->overrideRedirect) {
    542             iX = CW_USEDEFAULT;
    543             iY = CW_USEDEFAULT;
    544         }
    545     }
    546 
    547     /* Make it WS_OVERLAPPED in create call since WS_POPUP doesn't support */
    548     /* CW_USEDEFAULT, change back to popup after creation */
    549     dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
    550     dwExStyle = WS_EX_TOOLWINDOW;
    551 
    552     /*
    553        Calculate the window coordinates containing the requested client area,
    554        being careful to preserve CW_USEDEFAULT
    555      */
    556     rc.top = (iY != CW_USEDEFAULT) ? iY : 0;
    557     rc.left = (iX != CW_USEDEFAULT) ? iX : 0;
    558     rc.bottom = rc.top + iHeight;
    559     rc.right = rc.left + iWidth;
    560     AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
    561     if (iY != CW_USEDEFAULT)
    562         iY = rc.top;
    563     if (iX != CW_USEDEFAULT)
    564         iX = rc.left;
    565     iHeight = rc.bottom - rc.top;
    566     iWidth = rc.right - rc.left;
    567 
    568     winDebug("winCreateWindowsWindow - %dx%d @ %dx%d\n", iWidth, iHeight, iX,
    569              iY);
    570 
    571     /* Create the window */
    572     hWnd = CreateWindowExA(dwExStyle,   /* Extended styles */
    573                            WINDOW_CLASS_X,      /* Class name */
    574                            WINDOW_TITLE_X,      /* Window name */
    575                            dwStyle,     /* Styles */
    576                            iX,  /* Horizontal position */
    577                            iY,  /* Vertical position */
    578                            iWidth,      /* Right edge */
    579                            iHeight,     /* Bottom edge */
    580                            hFore,       /* Null or Parent window if transient */
    581                            (HMENU) NULL,        /* No menu */
    582                            GetModuleHandle(NULL),       /* Instance handle */
    583                            pWin);       /* ScreenPrivates */
    584     if (hWnd == NULL) {
    585         ErrorF("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
    586                (int) GetLastError());
    587     }
    588     pWinPriv->hWnd = hWnd;
    589 
    590     /* Change style back to popup, already placed... */
    591     SetWindowLongPtr(hWnd, GWL_STYLE,
    592                      WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
    593     SetWindowPos(hWnd, 0, 0, 0, 0, 0,
    594                  SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
    595                  SWP_NOACTIVATE);
    596 
    597     /* Adjust the X window to match the window placement we actually got... */
    598     winAdjustXWindow(pWin, hWnd);
    599 
    600     /* Make sure it gets the proper system menu for a WS_POPUP, too */
    601     GetSystemMenu(hWnd, TRUE);
    602 
    603     /* Cause any .XWinrc menus to be added in main WNDPROC */
    604     PostMessage(hWnd, WM_INIT_SYS_MENU, 0, 0);
    605 
    606     SetProp(hWnd, WIN_WID_PROP, (HANDLE) (INT_PTR) winGetWindowID(pWin));
    607 
    608     /* Flag that this Windows window handles its own activation */
    609     SetProp(hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
    610 }
    611 
    612 Bool winInDestroyWindowsWindow = FALSE;
    613 
    614 /*
    615  * winDestroyWindowsWindow - Destroy a Windows window associated
    616  * with an X window
    617  */
    618 static void
    619 winDestroyWindowsWindow(WindowPtr pWin)
    620 {
    621     MSG msg;
    622 
    623     winWindowPriv(pWin);
    624     BOOL oldstate = winInDestroyWindowsWindow;
    625     HICON hIcon;
    626     HICON hIconSm;
    627 
    628     winDebug("winDestroyWindowsWindow - pWin:%p XID:0x%x \n", pWin,
    629              (unsigned int)pWin->drawable.id);
    630 
    631     /* Bail out if the Windows window handle is invalid */
    632     if (pWinPriv->hWnd == NULL)
    633         return;
    634 
    635     winInDestroyWindowsWindow = TRUE;
    636 
    637     /* Store the info we need to destroy after this window is gone */
    638     hIcon = (HICON) SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_BIG, 0);
    639     hIconSm = (HICON) SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0);
    640 
    641     /* Destroy the Windows window */
    642     DestroyWindow(pWinPriv->hWnd);
    643 
    644     /* Null our handle to the Window so referencing it will cause an error */
    645     pWinPriv->hWnd = NULL;
    646 
    647     /* Destroy any icons we created for this window */
    648     winDestroyIcon(hIcon);
    649     winDestroyIcon(hIconSm);
    650 
    651 #ifdef XWIN_GLX_WINDOWS
    652     /* No longer note WGL used on this window */
    653     pWinPriv->fWglUsed = FALSE;
    654 #endif
    655 
    656     /* Process all messages on our queue */
    657     while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
    658         if (g_hDlgDepthChange == 0 || !IsDialogMessage(g_hDlgDepthChange, &msg)) {
    659             DispatchMessage(&msg);
    660         }
    661     }
    662 
    663     winInDestroyWindowsWindow = oldstate;
    664 
    665     winDebug("winDestroyWindowsWindow - done\n");
    666 }
    667 
    668 /*
    669  * winUpdateWindowsWindow - Redisplay/redraw a Windows window
    670  * associated with an X window
    671  */
    672 
    673 static void
    674 winUpdateWindowsWindow(WindowPtr pWin)
    675 {
    676     winWindowPriv(pWin);
    677     HWND hWnd = pWinPriv->hWnd;
    678 
    679 #if CYGMULTIWINDOW_DEBUG
    680     ErrorF("winUpdateWindowsWindow\n");
    681 #endif
    682 
    683     /* Check if the Windows window's parents have been destroyed */
    684     if (pWin->parent != NULL && pWin->parent->parent == NULL && pWin->mapped) {
    685         /* Create the Windows window if it has been destroyed */
    686         if (hWnd == NULL) {
    687             winCreateWindowsWindow(pWin);
    688             assert(pWinPriv->hWnd != NULL);
    689         }
    690 
    691         /* Display the window without activating it */
    692         if (pWin->drawable.class != InputOnly)
    693             ShowWindow(pWinPriv->hWnd, SW_SHOWNOACTIVATE);
    694 
    695         /* Send first paint message */
    696         UpdateWindow(pWinPriv->hWnd);
    697     }
    698     else if (hWnd != NULL) {
    699         /* Destroy the Windows window if its parents are destroyed */
    700         winDestroyWindowsWindow(pWin);
    701         assert(pWinPriv->hWnd == NULL);
    702     }
    703 
    704 #if CYGMULTIWINDOW_DEBUG
    705     ErrorF("-winUpdateWindowsWindow\n");
    706 #endif
    707 }
    708 
    709 /*
    710  * winGetWindowID -
    711  */
    712 
    713 XID
    714 winGetWindowID(WindowPtr pWin)
    715 {
    716     WindowIDPairRec wi = { pWin, 0 };
    717     ClientPtr c = wClient(pWin);
    718 
    719     /* */
    720     FindClientResourcesByType(c, RT_WINDOW, winFindWindow, &wi);
    721 
    722 #if CYGMULTIWINDOW_DEBUG
    723     ErrorF("winGetWindowID - Window ID: %u\n", (unsigned int)wi.id);
    724 #endif
    725 
    726     return wi.id;
    727 }
    728 
    729 /*
    730  * winFindWindow -
    731  */
    732 
    733 static void
    734 winFindWindow(void *value, XID id, void *cdata)
    735 {
    736     WindowIDPairPtr wi = (WindowIDPairPtr) cdata;
    737 
    738     if (value == wi->value) {
    739         wi->id = id;
    740     }
    741 }
    742 
    743 /*
    744  * winReorderWindowsMultiWindow -
    745  */
    746 
    747 void
    748 winReorderWindowsMultiWindow(void)
    749 {
    750     HWND hwnd = NULL;
    751     WindowPtr pWin = NULL;
    752     WindowPtr pWinSib = NULL;
    753     XID vlist[2];
    754     static Bool fRestacking = FALSE; /* Avoid recursive calls to this function */
    755     DWORD dwCurrentProcessID = GetCurrentProcessId();
    756     DWORD dwWindowProcessID = 0;
    757 
    758 #if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
    759     winTrace("winReorderWindowsMultiWindow\n");
    760 #endif
    761 
    762     if (fRestacking) {
    763         /* It is a recursive call so immediately exit */
    764 #if CYGWINDOWING_DEBUG
    765         ErrorF("winReorderWindowsMultiWindow - "
    766                "exit because fRestacking == TRUE\n");
    767 #endif
    768         return;
    769     }
    770     fRestacking = TRUE;
    771 
    772     /* Loop through top level Window windows, descending in Z order */
    773     for (hwnd = GetTopWindow(NULL);
    774          hwnd; hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)) {
    775         /* Don't take care of other Cygwin/X process's windows */
    776         GetWindowThreadProcessId(hwnd, &dwWindowProcessID);
    777 
    778         if (GetProp(hwnd, WIN_WINDOW_PROP)
    779             && (dwWindowProcessID == dwCurrentProcessID)
    780             && !IsIconic(hwnd)) {       /* ignore minimized windows */
    781             pWinSib = pWin;
    782             pWin = GetProp(hwnd, WIN_WINDOW_PROP);
    783 
    784             if (!pWinSib) {     /* 1st window - raise to the top */
    785                 vlist[0] = Above;
    786 
    787                 ConfigureWindow(pWin, CWStackMode, vlist, wClient(pWin));
    788             }
    789             else {              /* 2nd or deeper windows - just below the previous one */
    790                 vlist[0] = winGetWindowID(pWinSib);
    791                 vlist[1] = Below;
    792 
    793                 ConfigureWindow(pWin, CWSibling | CWStackMode,
    794                                 vlist, wClient(pWin));
    795             }
    796         }
    797     }
    798 
    799     fRestacking = FALSE;
    800 }
    801 
    802 /*
    803  * CopyWindow - See Porting Layer Definition - p. 39
    804  */
    805 void
    806 winCopyWindowMultiWindow(WindowPtr pWin, DDXPointRec oldpt, RegionPtr oldRegion)
    807 {
    808     ScreenPtr pScreen = pWin->drawable.pScreen;
    809 
    810     winScreenPriv(pScreen);
    811 
    812 #if CYGWINDOWING_DEBUG
    813     ErrorF("CopyWindowMultiWindow\n");
    814 #endif
    815     WIN_UNWRAP(CopyWindow);
    816     (*pScreen->CopyWindow) (pWin, oldpt, oldRegion);
    817     WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
    818 }
    819 
    820 /*
    821  * MoveWindow - See Porting Layer Definition - p. 42
    822  */
    823 void
    824 winMoveWindowMultiWindow(WindowPtr pWin, int x, int y,
    825                          WindowPtr pSib, VTKind kind)
    826 {
    827     ScreenPtr pScreen = pWin->drawable.pScreen;
    828 
    829     winScreenPriv(pScreen);
    830 
    831 #if CYGWINDOWING_DEBUG
    832     ErrorF("MoveWindowMultiWindow to (%d, %d)\n", x, y);
    833 #endif
    834 
    835     WIN_UNWRAP(MoveWindow);
    836     (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
    837     WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
    838 }
    839 
    840 /*
    841  * ResizeWindow - See Porting Layer Definition - p. 42
    842  */
    843 void
    844 winResizeWindowMultiWindow(WindowPtr pWin, int x, int y, unsigned int w,
    845                            unsigned int h, WindowPtr pSib)
    846 {
    847     ScreenPtr pScreen = pWin->drawable.pScreen;
    848 
    849     winScreenPriv(pScreen);
    850 
    851 #if CYGWINDOWING_DEBUG
    852     ErrorF("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
    853 #endif
    854     WIN_UNWRAP(ResizeWindow);
    855     (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
    856     WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
    857 }
    858 
    859 /*
    860  * winAdjustXWindow
    861  *
    862  * Move and resize X window with respect to corresponding Windows window.
    863  * This is called from WM_MOVE/WM_SIZE handlers when the user performs
    864  * any windowing operation (move, resize, minimize, maximize, restore).
    865  *
    866  * The functionality is the inverse of winPositionWindowMultiWindow, which
    867  * adjusts Windows window with respect to X window.
    868  */
    869 int
    870 winAdjustXWindow(WindowPtr pWin, HWND hwnd)
    871 {
    872     RECT rcDraw;                /* Rect made from pWin->drawable to be adjusted */
    873     RECT rcWin;                 /* The source: WindowRect from hwnd */
    874     DrawablePtr pDraw;
    875     XID vlist[4];
    876     LONG dX, dY, dW, dH, x, y;
    877     DWORD dwStyle, dwExStyle;
    878 
    879 #define WIDTH(rc) (rc.right - rc.left)
    880 #define HEIGHT(rc) (rc.bottom - rc.top)
    881 
    882 #if CYGWINDOWING_DEBUG
    883     ErrorF("winAdjustXWindow\n");
    884 #endif
    885 
    886     if (IsIconic(hwnd)) {
    887 #if CYGWINDOWING_DEBUG
    888         ErrorF("\timmediately return because the window is iconized\n");
    889 #endif
    890         /*
    891          * If the Windows window is minimized, its WindowRect has
    892          * meaningless values so we don't adjust X window to it.
    893          */
    894         vlist[0] = 0;
    895         vlist[1] = 0;
    896         return ConfigureWindow(pWin, CWX | CWY, vlist, wClient(pWin));
    897     }
    898 
    899     pDraw = &pWin->drawable;
    900 
    901     /* Calculate the window rect from the drawable */
    902     x = pDraw->x + GetSystemMetrics(SM_XVIRTUALSCREEN);
    903     y = pDraw->y + GetSystemMetrics(SM_YVIRTUALSCREEN);
    904     SetRect(&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
    905 #ifdef CYGMULTIWINDOW_DEBUG
    906     winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
    907              (int)rcDraw.left, (int)rcDraw.top, (int)rcDraw.right, (int)rcDraw.bottom,
    908              (int)(rcDraw.right - rcDraw.left), (int)(rcDraw.bottom - rcDraw.top));
    909 #endif
    910     dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
    911     dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
    912 #ifdef CYGMULTIWINDOW_DEBUG
    913     winDebug("\tWindowStyle: %08x %08x\n", (unsigned int)dwStyle, (unsigned int)dwExStyle);
    914 #endif
    915     AdjustWindowRectEx(&rcDraw, dwStyle, FALSE, dwExStyle);
    916 
    917     /* The source of adjust */
    918     GetWindowRect(hwnd, &rcWin);
    919 #ifdef CYGMULTIWINDOW_DEBUG
    920     winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
    921              (int)rcWin.left, (int)rcWin.top, (int)rcWin.right, (int)rcWin.bottom,
    922              (int)(rcWin.right - rcWin.left), (int)(rcWin.bottom - rcWin.top));
    923     winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
    924              (int)rcDraw.left, (int)rcDraw.top, (int)rcDraw.right, (int)rcDraw.bottom,
    925              (int)(rcDraw.right - rcDraw.left), (int)(rcDraw.bottom - rcDraw.top));
    926 #endif
    927 
    928     if (EqualRect(&rcDraw, &rcWin)) {
    929         /* Bail if no adjust is needed */
    930 #if CYGWINDOWING_DEBUG
    931         ErrorF("\treturn because already adjusted\n");
    932 #endif
    933         return 0;
    934     }
    935 
    936     /* Calculate delta values */
    937     dX = rcWin.left - rcDraw.left;
    938     dY = rcWin.top - rcDraw.top;
    939     dW = WIDTH(rcWin) - WIDTH(rcDraw);
    940     dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
    941 
    942     /*
    943      * Adjust.
    944      * We may only need to move (vlist[0] and [1]), or only resize
    945      * ([2] and [3]) but currently we set all the parameters and leave
    946      * the decision to ConfigureWindow.  The reason is code simplicity.
    947      */
    948     vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
    949     vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
    950     vlist[2] = pDraw->width + dW;
    951     vlist[3] = pDraw->height + dH;
    952 #if CYGWINDOWING_DEBUG
    953     ErrorF("\tConfigureWindow to (%u, %u) - %ux%u\n",
    954            (unsigned int)vlist[0], (unsigned int)vlist[1],
    955            (unsigned int)vlist[2], (unsigned int)vlist[3]);
    956 #endif
    957     return ConfigureWindow(pWin, CWX | CWY | CWWidth | CWHeight,
    958                            vlist, wClient(pWin));
    959 
    960 #undef WIDTH
    961 #undef HEIGHT
    962 }
    963 
    964 /*
    965   Helper function for creating a DIB to back a pixmap
    966  */
    967 static HBITMAP winCreateDIB(ScreenPtr pScreen, int width, int height, int bpp, void **ppvBits, BITMAPINFOHEADER **ppbmih)
    968 {
    969     winScreenPriv(pScreen);
    970     BITMAPV4HEADER *pbmih = NULL;
    971     HBITMAP hBitmap = NULL;
    972 
    973     /* Allocate bitmap info header */
    974     pbmih = malloc(sizeof(BITMAPV4HEADER) + 256 * sizeof(RGBQUAD));
    975     if (pbmih == NULL) {
    976         ErrorF("winCreateDIB: malloc() failed\n");
    977         return NULL;
    978     }
    979     memset(pbmih, 0, sizeof(BITMAPV4HEADER) + 256 * sizeof(RGBQUAD));
    980 
    981     /* Describe bitmap to be created */
    982     pbmih->bV4Size = sizeof(BITMAPV4HEADER);
    983     pbmih->bV4Width = width;
    984     pbmih->bV4Height = -height;  /* top-down bitmap */
    985     pbmih->bV4Planes = 1;
    986     pbmih->bV4BitCount = bpp;
    987     if (bpp == 1) {
    988         RGBQUAD *bmiColors = (RGBQUAD *)((char *)pbmih + sizeof(BITMAPV4HEADER));
    989         pbmih->bV4V4Compression = BI_RGB;
    990         bmiColors[1].rgbBlue = 255;
    991         bmiColors[1].rgbGreen = 255;
    992         bmiColors[1].rgbRed = 255;
    993     }
    994     else if (bpp == 8) {
    995         pbmih->bV4V4Compression = BI_RGB;
    996         pbmih->bV4ClrUsed = 0;
    997     }
    998     else if (bpp == 16) {
    999         pbmih->bV4V4Compression = BI_RGB;
   1000         pbmih->bV4ClrUsed = 0;
   1001     }
   1002     else if (bpp == 32) {
   1003         pbmih->bV4V4Compression = BI_BITFIELDS;
   1004         pbmih->bV4RedMask = pScreenPriv->dwRedMask;
   1005         pbmih->bV4GreenMask = pScreenPriv->dwGreenMask;
   1006         pbmih->bV4BlueMask = pScreenPriv->dwBlueMask;
   1007         pbmih->bV4AlphaMask = 0;
   1008     }
   1009     else {
   1010         ErrorF("winCreateDIB: %d bpp unhandled\n", bpp);
   1011     }
   1012 
   1013     /* Create a DIB with a bit pointer */
   1014     hBitmap = CreateDIBSection(NULL,
   1015                                (BITMAPINFO *) pbmih,
   1016                                DIB_RGB_COLORS, ppvBits, NULL, 0);
   1017     if (hBitmap == NULL) {
   1018         ErrorF("winCreateDIB: CreateDIBSection() failed\n");
   1019         return NULL;
   1020     }
   1021 
   1022     /* Store the address of the BMIH in the ppbmih parameter */
   1023     *ppbmih = (BITMAPINFOHEADER *)pbmih;
   1024 
   1025     winDebug("winCreateDIB: HBITMAP %p pBMIH %p pBits %p\n", hBitmap, pbmih, *ppvBits);
   1026 
   1027     return hBitmap;
   1028 }
   1029 
   1030 
   1031 /*
   1032  * CreatePixmap - See Porting Layer Definition
   1033  */
   1034 PixmapPtr
   1035 winCreatePixmapMultiwindow(ScreenPtr pScreen, int width, int height, int depth,
   1036                            unsigned usage_hint)
   1037 {
   1038     winPrivPixmapPtr pPixmapPriv = NULL;
   1039     PixmapPtr pPixmap = NULL;
   1040     int bpp, paddedwidth;
   1041 
   1042     /* allocate Pixmap header and privates */
   1043     pPixmap = AllocatePixmap(pScreen, 0);
   1044     if (!pPixmap)
   1045         return NullPixmap;
   1046 
   1047     bpp = BitsPerPixel(depth);
   1048     /*
   1049       DIBs have 4-byte aligned rows
   1050 
   1051       paddedwidth is the width in bytes, padded to align
   1052 
   1053       i.e. round up the number of bits used by a row so it is a multiple of 32,
   1054       then convert to bytes
   1055     */
   1056     paddedwidth = (((bpp * width) + 31) & ~31)/8;
   1057 
   1058     /* setup Pixmap header */
   1059     pPixmap->drawable.type = DRAWABLE_PIXMAP;
   1060     pPixmap->drawable.class = 0;
   1061     pPixmap->drawable.pScreen = pScreen;
   1062     pPixmap->drawable.depth = depth;
   1063     pPixmap->drawable.bitsPerPixel = bpp;
   1064     pPixmap->drawable.id = 0;
   1065     pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
   1066     pPixmap->drawable.x = 0;
   1067     pPixmap->drawable.y = 0;
   1068     pPixmap->drawable.width = width;
   1069     pPixmap->drawable.height = height;
   1070     pPixmap->devKind = paddedwidth;
   1071     pPixmap->refcnt = 1;
   1072     pPixmap->devPrivate.ptr = NULL; // later set to pbBits
   1073     pPixmap->primary_pixmap = NULL;
   1074 #ifdef COMPOSITE
   1075     pPixmap->screen_x = 0;
   1076     pPixmap->screen_y = 0;
   1077 #endif
   1078     pPixmap->usage_hint = usage_hint;
   1079 
   1080     /* Check for zero width or height pixmaps */
   1081     if (width == 0 || height == 0) {
   1082         /* DIBs with a dimension of 0 aren't permitted, so don't try to allocate
   1083            a DIB, just set fields and return */
   1084         return pPixmap;
   1085     }
   1086 
   1087     /* Initialize pixmap privates */
   1088     pPixmapPriv = winGetPixmapPriv(pPixmap);
   1089     pPixmapPriv->hBitmap = NULL;
   1090     pPixmapPriv->pbBits = NULL;
   1091     pPixmapPriv->pbmih = NULL;
   1092 
   1093     /* Create a DIB for the pixmap */
   1094     pPixmapPriv->hBitmap = winCreateDIB(pScreen, width, height, bpp, &pPixmapPriv->pbBits, &pPixmapPriv->pbmih);
   1095     pPixmapPriv->owned = TRUE;
   1096 
   1097     winDebug("winCreatePixmap: pPixmap %p HBITMAP %p pBMIH %p pBits %p\n", pPixmap, pPixmapPriv->hBitmap, pPixmapPriv->pbmih, pPixmapPriv->pbBits);
   1098     /* XXX: so why do we need this in privates ??? */
   1099     pPixmap->devPrivate.ptr = pPixmapPriv->pbBits;
   1100 
   1101     return pPixmap;
   1102 }
   1103 
   1104 /*
   1105  * DestroyPixmap - See Porting Layer Definition
   1106  */
   1107 Bool
   1108 winDestroyPixmapMultiwindow(PixmapPtr pPixmap)
   1109 {
   1110     winPrivPixmapPtr pPixmapPriv = NULL;
   1111 
   1112     /* Bail early if there is not a pixmap to destroy */
   1113     if (pPixmap == NULL) {
   1114         return TRUE;
   1115     }
   1116 
   1117     /* Decrement reference count, return if nonzero */
   1118     --pPixmap->refcnt;
   1119     if (pPixmap->refcnt != 0)
   1120         return TRUE;
   1121 
   1122     winDebug("winDestroyPixmap: pPixmap %p\n", pPixmap);
   1123 
   1124     /* Get a handle to the pixmap privates */
   1125     pPixmapPriv = winGetPixmapPriv(pPixmap);
   1126 
   1127     /* Nothing to do if we don't own the DIB */
   1128     if (!pPixmapPriv->owned)
   1129         return TRUE;
   1130 
   1131     /* Free GDI bitmap */
   1132     if (pPixmapPriv->hBitmap)
   1133         DeleteObject(pPixmapPriv->hBitmap);
   1134 
   1135     /* Free the bitmap info header memory */
   1136     free(pPixmapPriv->pbmih);
   1137     pPixmapPriv->pbmih = NULL;
   1138 
   1139     /* Free the pixmap memory */
   1140     free(pPixmap);
   1141     pPixmap = NULL;
   1142 
   1143     return TRUE;
   1144 }
   1145 
   1146 /*
   1147  * ModifyPixmapHeader - See Porting Layer Definition
   1148  */
   1149 Bool
   1150 winModifyPixmapHeaderMultiwindow(PixmapPtr pPixmap,
   1151                                  int width,
   1152                                  int height,
   1153                                  int depth,
   1154                                  int bitsPerPixel, int devKind, void *pPixData)
   1155 {
   1156     int i;
   1157     winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap);
   1158     Bool fResult;
   1159 
   1160     /* reinitialize everything */
   1161     pPixmap->drawable.depth = depth;
   1162     pPixmap->drawable.bitsPerPixel = bitsPerPixel;
   1163     pPixmap->drawable.id = 0;
   1164     pPixmap->drawable.x = 0;
   1165     pPixmap->drawable.y = 0;
   1166     pPixmap->drawable.width = width;
   1167     pPixmap->drawable.height = height;
   1168     pPixmap->devKind = devKind;
   1169     pPixmap->refcnt = 1;
   1170     pPixmap->devPrivate.ptr = pPixData;
   1171     pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
   1172 
   1173     /*
   1174       This can be used for some out-of-order initialization on the screen
   1175       pixmap, which is the only case we can properly support.
   1176     */
   1177 
   1178     /* Look for which screen this pixmap corresponds to */
   1179     for (i = 0; i < screenInfo.numScreens; i++) {
   1180         ScreenPtr pScreen = screenInfo.screens[i];
   1181         winScreenPriv(pScreen);
   1182         winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
   1183 
   1184         if (pScreenInfo->pfb == pPixData)
   1185             {
   1186                 /* and initialize pixmap privates from screen privates */
   1187                 pPixmapPriv->hBitmap = pScreenPriv->hbmpShadow;
   1188                 pPixmapPriv->pbBits = pScreenInfo->pfb;
   1189                 pPixmapPriv->pbmih = pScreenPriv->pbmih;
   1190 
   1191                 /* mark these not to get released by DestroyPixmap */
   1192                 pPixmapPriv->owned = FALSE;
   1193 
   1194                 return TRUE;
   1195             }
   1196     }
   1197 
   1198     /* Otherwise, since creating a DIBSection from arbitrary memory is not
   1199      * possible, fallback to normal.  If needed, we can create a DIBSection with
   1200      * a copy of the bits later (see comment about a potential slow-path in
   1201      * winBltExposedWindowRegionShadowGDI()). */
   1202     pPixmapPriv->hBitmap = 0;
   1203     pPixmapPriv->pbBits = 0;
   1204     pPixmapPriv->pbmih = 0;
   1205     pPixmapPriv->owned = FALSE;
   1206 
   1207     winDebug("winModifyPixmapHeaderMultiwindow: falling back\n");
   1208 
   1209     {
   1210         ScreenPtr pScreen = pPixmap->drawable.pScreen;
   1211         winScreenPriv(pScreen);
   1212         WIN_UNWRAP(ModifyPixmapHeader);
   1213         fResult = (*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData);
   1214         WIN_WRAP(ModifyPixmapHeader, winModifyPixmapHeaderMultiwindow);
   1215     }
   1216 
   1217     return fResult;
   1218 }