winwindow.c revision 35c4bbdf
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: Harold L Hunt II 29 * Kensuke Matsuzaki 30 */ 31 32#ifdef HAVE_XWIN_CONFIG_H 33#include <xwin-config.h> 34#endif 35#include "win.h" 36 37/* 38 * Prototypes for local functions 39 */ 40 41static int 42 winAddRgn(WindowPtr pWindow, void *data); 43 44static 45 void 46 winUpdateRgnRootless(WindowPtr pWindow); 47 48static 49 void 50 winReshapeRootless(WindowPtr pWin); 51 52/* See Porting Layer Definition - p. 37 */ 53/* See mfb/mfbwindow.c - mfbCreateWindow() */ 54 55Bool 56winCreateWindowRootless(WindowPtr pWin) 57{ 58 Bool fResult = FALSE; 59 ScreenPtr pScreen = pWin->drawable.pScreen; 60 61 winWindowPriv(pWin); 62 winScreenPriv(pScreen); 63 64#if CYGDEBUG 65 winTrace("winCreateWindowRootless (%p)\n", pWin); 66#endif 67 68 WIN_UNWRAP(CreateWindow); 69 fResult = (*pScreen->CreateWindow) (pWin); 70 WIN_WRAP(CreateWindow, winCreateWindowRootless); 71 72 pWinPriv->hRgn = NULL; 73 74 return fResult; 75} 76 77/* See Porting Layer Definition - p. 37 */ 78/* See mfb/mfbwindow.c - mfbDestroyWindow() */ 79 80Bool 81winDestroyWindowRootless(WindowPtr pWin) 82{ 83 Bool fResult = FALSE; 84 ScreenPtr pScreen = pWin->drawable.pScreen; 85 86 winWindowPriv(pWin); 87 winScreenPriv(pScreen); 88 89#if CYGDEBUG 90 winTrace("winDestroyWindowRootless (%p)\n", pWin); 91#endif 92 93 WIN_UNWRAP(DestroyWindow); 94 fResult = (*pScreen->DestroyWindow) (pWin); 95 WIN_WRAP(DestroyWindow, winDestroyWindowRootless); 96 97 if (pWinPriv->hRgn != NULL) { 98 DeleteObject(pWinPriv->hRgn); 99 pWinPriv->hRgn = NULL; 100 } 101 102 winUpdateRgnRootless(pWin); 103 104 return fResult; 105} 106 107/* See Porting Layer Definition - p. 37 */ 108/* See mfb/mfbwindow.c - mfbPositionWindow() */ 109 110Bool 111winPositionWindowRootless(WindowPtr pWin, int x, int y) 112{ 113 Bool fResult = FALSE; 114 ScreenPtr pScreen = pWin->drawable.pScreen; 115 116 winScreenPriv(pScreen); 117 118#if CYGDEBUG 119 winTrace("winPositionWindowRootless (%p)\n", pWin); 120#endif 121 122 WIN_UNWRAP(PositionWindow); 123 fResult = (*pScreen->PositionWindow) (pWin, x, y); 124 WIN_WRAP(PositionWindow, winPositionWindowRootless); 125 126 winUpdateRgnRootless(pWin); 127 128 return fResult; 129} 130 131/* See Porting Layer Definition - p. 37 */ 132/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */ 133 134Bool 135winChangeWindowAttributesRootless(WindowPtr pWin, unsigned long mask) 136{ 137 Bool fResult = FALSE; 138 ScreenPtr pScreen = pWin->drawable.pScreen; 139 140 winScreenPriv(pScreen); 141 142#if CYGDEBUG 143 winTrace("winChangeWindowAttributesRootless (%p)\n", pWin); 144#endif 145 146 WIN_UNWRAP(ChangeWindowAttributes); 147 fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask); 148 WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesRootless); 149 150 winUpdateRgnRootless(pWin); 151 152 return fResult; 153} 154 155/* See Porting Layer Definition - p. 37 156 * Also referred to as UnrealizeWindow 157 */ 158 159Bool 160winUnmapWindowRootless(WindowPtr pWin) 161{ 162 Bool fResult = FALSE; 163 ScreenPtr pScreen = pWin->drawable.pScreen; 164 165 winWindowPriv(pWin); 166 winScreenPriv(pScreen); 167 168#if CYGDEBUG 169 winTrace("winUnmapWindowRootless (%p)\n", pWin); 170#endif 171 172 WIN_UNWRAP(UnrealizeWindow); 173 fResult = (*pScreen->UnrealizeWindow) (pWin); 174 WIN_WRAP(UnrealizeWindow, winUnmapWindowRootless); 175 176 if (pWinPriv->hRgn != NULL) { 177 DeleteObject(pWinPriv->hRgn); 178 pWinPriv->hRgn = NULL; 179 } 180 181 winUpdateRgnRootless(pWin); 182 183 return fResult; 184} 185 186/* See Porting Layer Definition - p. 37 187 * Also referred to as RealizeWindow 188 */ 189 190Bool 191winMapWindowRootless(WindowPtr pWin) 192{ 193 Bool fResult = FALSE; 194 ScreenPtr pScreen = pWin->drawable.pScreen; 195 196 winScreenPriv(pScreen); 197 198#if CYGDEBUG 199 winTrace("winMapWindowRootless (%p)\n", pWin); 200#endif 201 202 WIN_UNWRAP(RealizeWindow); 203 fResult = (*pScreen->RealizeWindow) (pWin); 204 WIN_WRAP(RealizeWindow, winMapWindowRootless); 205 206 winReshapeRootless(pWin); 207 208 winUpdateRgnRootless(pWin); 209 210 return fResult; 211} 212 213void 214winSetShapeRootless(WindowPtr pWin, int kind) 215{ 216 ScreenPtr pScreen = pWin->drawable.pScreen; 217 218 winScreenPriv(pScreen); 219 220#if CYGDEBUG 221 winTrace("winSetShapeRootless (%p, %i)\n", pWin, kind); 222#endif 223 224 WIN_UNWRAP(SetShape); 225 (*pScreen->SetShape) (pWin, kind); 226 WIN_WRAP(SetShape, winSetShapeRootless); 227 228 winReshapeRootless(pWin); 229 winUpdateRgnRootless(pWin); 230 231 return; 232} 233 234/* 235 * Local function for adding a region to the Windows window region 236 */ 237 238static 239 int 240winAddRgn(WindowPtr pWin, void *data) 241{ 242 int iX, iY, iWidth, iHeight, iBorder; 243 HRGN hRgn = *(HRGN *) data; 244 HRGN hRgnWin; 245 246 winWindowPriv(pWin); 247 248 /* If pWin is not Root */ 249 if (pWin->parent != NULL) { 250#if CYGDEBUG 251 winDebug("winAddRgn ()\n"); 252#endif 253 if (pWin->mapped) { 254 iBorder = wBorderWidth(pWin); 255 256 iX = pWin->drawable.x - iBorder; 257 iY = pWin->drawable.y - iBorder; 258 259 iWidth = pWin->drawable.width + iBorder * 2; 260 iHeight = pWin->drawable.height + iBorder * 2; 261 262 hRgnWin = CreateRectRgn(0, 0, iWidth, iHeight); 263 264 if (hRgnWin == NULL) { 265 ErrorF("winAddRgn - CreateRectRgn () failed\n"); 266 ErrorF(" Rect %d %d %d %d\n", 267 iX, iY, iX + iWidth, iY + iHeight); 268 } 269 270 if (pWinPriv->hRgn) { 271 if (CombineRgn(hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND) 272 == ERROR) { 273 ErrorF("winAddRgn - CombineRgn () failed\n"); 274 } 275 } 276 277 OffsetRgn(hRgnWin, iX, iY); 278 279 if (CombineRgn(hRgn, hRgn, hRgnWin, RGN_OR) == ERROR) { 280 ErrorF("winAddRgn - CombineRgn () failed\n"); 281 } 282 283 DeleteObject(hRgnWin); 284 } 285 return WT_DONTWALKCHILDREN; 286 } 287 else { 288 return WT_WALKCHILDREN; 289 } 290} 291 292/* 293 * Local function to update the Windows window's region 294 */ 295 296static 297 void 298winUpdateRgnRootless(WindowPtr pWin) 299{ 300 HRGN hRgn = CreateRectRgn(0, 0, 0, 0); 301 302 if (hRgn != NULL) { 303 WalkTree(pWin->drawable.pScreen, winAddRgn, &hRgn); 304 SetWindowRgn(winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen, 305 hRgn, TRUE); 306 } 307 else { 308 ErrorF("winUpdateRgnRootless - CreateRectRgn failed.\n"); 309 } 310} 311 312static 313 void 314winReshapeRootless(WindowPtr pWin) 315{ 316 int nRects; 317 RegionRec rrNewShape; 318 BoxPtr pShape, pRects, pEnd; 319 HRGN hRgn, hRgnRect; 320 321 winWindowPriv(pWin); 322 323#if CYGDEBUG 324 winDebug("winReshapeRootless ()\n"); 325#endif 326 327 /* Bail if the window is the root window */ 328 if (pWin->parent == NULL) 329 return; 330 331 /* Bail if the window is not top level */ 332 if (pWin->parent->parent != NULL) 333 return; 334 335 /* Free any existing window region stored in the window privates */ 336 if (pWinPriv->hRgn != NULL) { 337 DeleteObject(pWinPriv->hRgn); 338 pWinPriv->hRgn = NULL; 339 } 340 341 /* Bail if the window has no bounding region defined */ 342 if (!wBoundingShape(pWin)) 343 return; 344 345 RegionNull(&rrNewShape); 346 RegionCopy(&rrNewShape, wBoundingShape(pWin)); 347 RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth); 348 349 nRects = RegionNumRects(&rrNewShape); 350 pShape = RegionRects(&rrNewShape); 351 352 if (nRects > 0) { 353 /* Create initial empty Windows region */ 354 hRgn = CreateRectRgn(0, 0, 0, 0); 355 356 /* Loop through all rectangles in the X region */ 357 for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) { 358 /* Create a Windows region for the X rectangle */ 359 hRgnRect = CreateRectRgn(pRects->x1, pRects->y1, 360 pRects->x2, pRects->y2); 361 if (hRgnRect == NULL) { 362 ErrorF("winReshapeRootless - CreateRectRgn() failed\n"); 363 } 364 365 /* Merge the Windows region with the accumulated region */ 366 if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) { 367 ErrorF("winReshapeRootless - CombineRgn() failed\n"); 368 } 369 370 /* Delete the temporary Windows region */ 371 DeleteObject(hRgnRect); 372 } 373 374 /* Save a handle to the composite region in the window privates */ 375 pWinPriv->hRgn = hRgn; 376 } 377 378 RegionUninit(&rrNewShape); 379 380 return; 381} 382