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