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 * Harold L Hunt II 30 */ 31 32#ifdef HAVE_XWIN_CONFIG_H 33#include <xwin-config.h> 34#endif 35 36#include "win.h" 37 38/* 39 * winSetShapeMultiWindow - See Porting Layer Definition - p. 42 40 */ 41 42void 43winSetShapeMultiWindow(WindowPtr pWin, int kind) 44{ 45 ScreenPtr pScreen = pWin->drawable.pScreen; 46 47 winScreenPriv(pScreen); 48 49#if CYGMULTIWINDOW_DEBUG 50 ErrorF("winSetShapeMultiWindow - pWin: %p kind: %i\n", pWin, kind); 51#endif 52 53 WIN_UNWRAP(SetShape); 54 (*pScreen->SetShape) (pWin, kind); 55 WIN_WRAP(SetShape, winSetShapeMultiWindow); 56 57 /* Update the Windows window's shape */ 58 winReshapeMultiWindow(pWin); 59 winUpdateRgnMultiWindow(pWin); 60 61 return; 62} 63 64/* 65 * winUpdateRgnMultiWindow - Local function to update a Windows window region 66 */ 67 68void 69winUpdateRgnMultiWindow(WindowPtr pWin) 70{ 71 SetWindowRgn(winGetWindowPriv(pWin)->hWnd, 72 winGetWindowPriv(pWin)->hRgn, TRUE); 73 74 /* The system now owns the region specified by the region handle and will delete it when it is no longer needed. */ 75 winGetWindowPriv(pWin)->hRgn = NULL; 76} 77 78/* 79 * winReshapeMultiWindow - Computes the composite clipping region for a window 80 */ 81 82void 83winReshapeMultiWindow(WindowPtr pWin) 84{ 85 int nRects; 86 RegionRec rrNewShape; 87 BoxPtr pShape, pRects, pEnd; 88 HRGN hRgn, hRgnRect; 89 90 winWindowPriv(pWin); 91 92#if CYGDEBUG 93 winDebug("winReshape ()\n"); 94#endif 95 96 /* Bail if the window is the root window */ 97 if (pWin->parent == NULL) 98 return; 99 100 /* Bail if the window is not top level */ 101 if (pWin->parent->parent != NULL) 102 return; 103 104 /* Bail if Windows window handle is invalid */ 105 if (pWinPriv->hWnd == NULL) 106 return; 107 108 /* Free any existing window region stored in the window privates */ 109 if (pWinPriv->hRgn != NULL) { 110 DeleteObject(pWinPriv->hRgn); 111 pWinPriv->hRgn = NULL; 112 } 113 114 /* Bail if the window has no bounding region defined */ 115 if (!wBoundingShape(pWin)) 116 return; 117 118 RegionNull(&rrNewShape); 119 RegionCopy(&rrNewShape, wBoundingShape(pWin)); 120 RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth); 121 122 nRects = RegionNumRects(&rrNewShape); 123 pShape = RegionRects(&rrNewShape); 124 125 /* Don't do anything if there are no rectangles in the region */ 126 if (nRects > 0) { 127 RECT rcClient; 128 RECT rcWindow; 129 int iOffsetX, iOffsetY; 130 131 /* Get client rectangle */ 132 if (!GetClientRect(pWinPriv->hWnd, &rcClient)) { 133 ErrorF("winReshape - GetClientRect failed, bailing: %d\n", 134 (int) GetLastError()); 135 return; 136 } 137 138 /* Translate client rectangle coords to screen coords */ 139 /* NOTE: Only transforms top and left members */ 140 ClientToScreen(pWinPriv->hWnd, (LPPOINT) &rcClient); 141 142 /* Get window rectangle */ 143 if (!GetWindowRect(pWinPriv->hWnd, &rcWindow)) { 144 ErrorF("winReshape - GetWindowRect failed, bailing: %d\n", 145 (int) GetLastError()); 146 return; 147 } 148 149 /* Calculate offset from window upper-left to client upper-left */ 150 iOffsetX = rcClient.left - rcWindow.left; 151 iOffsetY = rcClient.top - rcWindow.top; 152 153 /* Create initial Windows region for title bar */ 154 /* FIXME: Mean, nasty, ugly hack!!! */ 155 hRgn = CreateRectRgn(0, 0, rcWindow.right, iOffsetY); 156 if (hRgn == NULL) { 157 ErrorF("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " 158 "failed: %d\n", 159 0, 0, (int) rcWindow.right, iOffsetY, (int) GetLastError()); 160 } 161 162 /* Loop through all rectangles in the X region */ 163 for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) { 164 /* Create a Windows region for the X rectangle */ 165 hRgnRect = CreateRectRgn(pRects->x1 + iOffsetX, 166 pRects->y1 + iOffsetY, 167 pRects->x2 + iOffsetX, 168 pRects->y2 + iOffsetY); 169 if (hRgnRect == NULL) { 170 ErrorF("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " 171 "failed: %d\n" 172 "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", 173 pRects->x1 + iOffsetX, 174 pRects->y1 + iOffsetY, 175 pRects->x2 + iOffsetX, 176 pRects->y2 + iOffsetY, 177 (int) GetLastError(), 178 pRects->x1, pRects->x2, iOffsetX, 179 pRects->y1, pRects->y2, iOffsetY); 180 } 181 182 /* Merge the Windows region with the accumulated region */ 183 if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) { 184 ErrorF("winReshape - CombineRgn () failed: %d\n", 185 (int) GetLastError()); 186 } 187 188 /* Delete the temporary Windows region */ 189 DeleteObject(hRgnRect); 190 } 191 192 /* Save a handle to the composite region in the window privates */ 193 pWinPriv->hRgn = hRgn; 194 } 195 196 RegionUninit(&rrNewShape); 197 198 return; 199} 200