1706f2543Smrg/* 2706f2543Smrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3706f2543Smrg * 4706f2543Smrg *Permission is hereby granted, free of charge, to any person obtaining 5706f2543Smrg * a copy of this software and associated documentation files (the 6706f2543Smrg *"Software"), to deal in the Software without restriction, including 7706f2543Smrg *without limitation the rights to use, copy, modify, merge, publish, 8706f2543Smrg *distribute, sublicense, and/or sell copies of the Software, and to 9706f2543Smrg *permit persons to whom the Software is furnished to do so, subject to 10706f2543Smrg *the following conditions: 11706f2543Smrg * 12706f2543Smrg *The above copyright notice and this permission notice shall be 13706f2543Smrg *included in all copies or substantial portions of the Software. 14706f2543Smrg * 15706f2543Smrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16706f2543Smrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17706f2543Smrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18706f2543Smrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 19706f2543Smrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 20706f2543Smrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21706f2543Smrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22706f2543Smrg * 23706f2543Smrg *Except as contained in this notice, the name of the XFree86 Project 24706f2543Smrg *shall not be used in advertising or otherwise to promote the sale, use 25706f2543Smrg *or other dealings in this Software without prior written authorization 26706f2543Smrg *from the XFree86 Project. 27706f2543Smrg * 28706f2543Smrg * Authors: Kensuke Matsuzaki 29706f2543Smrg * Harold L Hunt II 30706f2543Smrg */ 31706f2543Smrg 32706f2543Smrg#ifdef HAVE_XWIN_CONFIG_H 33706f2543Smrg#include <xwin-config.h> 34706f2543Smrg#endif 35706f2543Smrg 36706f2543Smrg#include "win.h" 37706f2543Smrg 38706f2543Smrg 39706f2543Smrg/* 40706f2543Smrg * winSetShapeMultiWindow - See Porting Layer Definition - p. 42 41706f2543Smrg */ 42706f2543Smrg 43706f2543Smrgvoid 44706f2543SmrgwinSetShapeMultiWindow (WindowPtr pWin, int kind) 45706f2543Smrg{ 46706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 47706f2543Smrg winScreenPriv(pScreen); 48706f2543Smrg 49706f2543Smrg#if CYGMULTIWINDOW_DEBUG 50706f2543Smrg ErrorF ("winSetShapeMultiWindow - pWin: %08x kind: %i\n", pWin, kind); 51706f2543Smrg#endif 52706f2543Smrg 53706f2543Smrg WIN_UNWRAP(SetShape); 54706f2543Smrg (*pScreen->SetShape)(pWin, kind); 55706f2543Smrg WIN_WRAP(SetShape, winSetShapeMultiWindow); 56706f2543Smrg 57706f2543Smrg /* Update the Windows window's shape */ 58706f2543Smrg winReshapeMultiWindow (pWin); 59706f2543Smrg winUpdateRgnMultiWindow (pWin); 60706f2543Smrg 61706f2543Smrg return; 62706f2543Smrg} 63706f2543Smrg 64706f2543Smrg 65706f2543Smrg/* 66706f2543Smrg * winUpdateRgnMultiWindow - Local function to update a Windows window region 67706f2543Smrg */ 68706f2543Smrg 69706f2543Smrgvoid 70706f2543SmrgwinUpdateRgnMultiWindow (WindowPtr pWin) 71706f2543Smrg{ 72706f2543Smrg SetWindowRgn (winGetWindowPriv(pWin)->hWnd, 73706f2543Smrg winGetWindowPriv(pWin)->hRgn, TRUE); 74706f2543Smrg 75706f2543Smrg /* The system now owns the region specified by the region handle and will delete it when it is no longer needed. */ 76706f2543Smrg winGetWindowPriv(pWin)->hRgn = NULL; 77706f2543Smrg} 78706f2543Smrg 79706f2543Smrg 80706f2543Smrg/* 81706f2543Smrg * winReshapeMultiWindow - Computes the composite clipping region for a window 82706f2543Smrg */ 83706f2543Smrg 84706f2543Smrgvoid 85706f2543SmrgwinReshapeMultiWindow (WindowPtr pWin) 86706f2543Smrg{ 87706f2543Smrg int nRects; 88706f2543Smrg RegionRec rrNewShape; 89706f2543Smrg BoxPtr pShape, pRects, pEnd; 90706f2543Smrg HRGN hRgn, hRgnRect; 91706f2543Smrg winWindowPriv(pWin); 92706f2543Smrg 93706f2543Smrg#if CYGDEBUG 94706f2543Smrg winDebug ("winReshape ()\n"); 95706f2543Smrg#endif 96706f2543Smrg 97706f2543Smrg /* Bail if the window is the root window */ 98706f2543Smrg if (pWin->parent == NULL) 99706f2543Smrg return; 100706f2543Smrg 101706f2543Smrg /* Bail if the window is not top level */ 102706f2543Smrg if (pWin->parent->parent != NULL) 103706f2543Smrg return; 104706f2543Smrg 105706f2543Smrg /* Bail if Windows window handle is invalid */ 106706f2543Smrg if (pWinPriv->hWnd == NULL) 107706f2543Smrg return; 108706f2543Smrg 109706f2543Smrg /* Free any existing window region stored in the window privates */ 110706f2543Smrg if (pWinPriv->hRgn != NULL) 111706f2543Smrg { 112706f2543Smrg DeleteObject (pWinPriv->hRgn); 113706f2543Smrg pWinPriv->hRgn = NULL; 114706f2543Smrg } 115706f2543Smrg 116706f2543Smrg /* Bail if the window has no bounding region defined */ 117706f2543Smrg if (!wBoundingShape (pWin)) 118706f2543Smrg return; 119706f2543Smrg 120706f2543Smrg RegionNull(&rrNewShape); 121706f2543Smrg RegionCopy(&rrNewShape, wBoundingShape(pWin)); 122706f2543Smrg RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth); 123706f2543Smrg 124706f2543Smrg nRects = RegionNumRects(&rrNewShape); 125706f2543Smrg pShape = RegionRects(&rrNewShape); 126706f2543Smrg 127706f2543Smrg /* Don't do anything if there are no rectangles in the region */ 128706f2543Smrg if (nRects > 0) 129706f2543Smrg { 130706f2543Smrg RECT rcClient; 131706f2543Smrg RECT rcWindow; 132706f2543Smrg int iOffsetX, iOffsetY; 133706f2543Smrg 134706f2543Smrg /* Get client rectangle */ 135706f2543Smrg if (!GetClientRect (pWinPriv->hWnd, &rcClient)) 136706f2543Smrg { 137706f2543Smrg ErrorF ("winReshape - GetClientRect failed, bailing: %d\n", 138706f2543Smrg (int) GetLastError ()); 139706f2543Smrg return; 140706f2543Smrg } 141706f2543Smrg 142706f2543Smrg /* Translate client rectangle coords to screen coords */ 143706f2543Smrg /* NOTE: Only transforms top and left members */ 144706f2543Smrg ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient); 145706f2543Smrg 146706f2543Smrg /* Get window rectangle */ 147706f2543Smrg if (!GetWindowRect (pWinPriv->hWnd, &rcWindow)) 148706f2543Smrg { 149706f2543Smrg ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n", 150706f2543Smrg (int) GetLastError ()); 151706f2543Smrg return; 152706f2543Smrg } 153706f2543Smrg 154706f2543Smrg /* Calculate offset from window upper-left to client upper-left */ 155706f2543Smrg iOffsetX = rcClient.left - rcWindow.left; 156706f2543Smrg iOffsetY = rcClient.top - rcWindow.top; 157706f2543Smrg 158706f2543Smrg /* Create initial Windows region for title bar */ 159706f2543Smrg /* FIXME: Mean, nasty, ugly hack!!! */ 160706f2543Smrg hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY); 161706f2543Smrg if (hRgn == NULL) 162706f2543Smrg { 163706f2543Smrg ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " 164706f2543Smrg "failed: %d\n", 165706f2543Smrg 0, 0, (int) rcWindow.right, iOffsetY, (int) GetLastError ()); 166706f2543Smrg } 167706f2543Smrg 168706f2543Smrg /* Loop through all rectangles in the X region */ 169706f2543Smrg for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) 170706f2543Smrg { 171706f2543Smrg /* Create a Windows region for the X rectangle */ 172706f2543Smrg hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX, 173706f2543Smrg pRects->y1 + iOffsetY, 174706f2543Smrg pRects->x2 + iOffsetX, 175706f2543Smrg pRects->y2 + iOffsetY); 176706f2543Smrg if (hRgnRect == NULL) 177706f2543Smrg { 178706f2543Smrg ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " 179706f2543Smrg "failed: %d\n" 180706f2543Smrg "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", 181706f2543Smrg pRects->x1 + iOffsetX, 182706f2543Smrg pRects->y1 + iOffsetY, 183706f2543Smrg pRects->x2 + iOffsetX, 184706f2543Smrg pRects->y2 + iOffsetY, 185706f2543Smrg (int) GetLastError (), 186706f2543Smrg pRects->x1, pRects->x2, iOffsetX, 187706f2543Smrg pRects->y1, pRects->y2, iOffsetY); 188706f2543Smrg } 189706f2543Smrg 190706f2543Smrg /* Merge the Windows region with the accumulated region */ 191706f2543Smrg if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) 192706f2543Smrg { 193706f2543Smrg ErrorF ("winReshape - CombineRgn () failed: %d\n", 194706f2543Smrg (int) GetLastError ()); 195706f2543Smrg } 196706f2543Smrg 197706f2543Smrg /* Delete the temporary Windows region */ 198706f2543Smrg DeleteObject (hRgnRect); 199706f2543Smrg } 200706f2543Smrg 201706f2543Smrg /* Save a handle to the composite region in the window privates */ 202706f2543Smrg pWinPriv->hRgn = hRgn; 203706f2543Smrg } 204706f2543Smrg 205706f2543Smrg RegionUninit(&rrNewShape); 206706f2543Smrg 207706f2543Smrg return; 208706f2543Smrg} 209