105b261ecSmrg/* 205b261ecSmrg *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 305b261ecSmrg * 405b261ecSmrg *Permission is hereby granted, free of charge, to any person obtaining 505b261ecSmrg * a copy of this software and associated documentation files (the 605b261ecSmrg *"Software"), to deal in the Software without restriction, including 705b261ecSmrg *without limitation the rights to use, copy, modify, merge, publish, 805b261ecSmrg *distribute, sublicense, and/or sell copies of the Software, and to 905b261ecSmrg *permit persons to whom the Software is furnished to do so, subject to 1005b261ecSmrg *the following conditions: 1105b261ecSmrg * 1205b261ecSmrg *The above copyright notice and this permission notice shall be 1305b261ecSmrg *included in all copies or substantial portions of the Software. 1405b261ecSmrg * 1505b261ecSmrg *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1605b261ecSmrg *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1705b261ecSmrg *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1805b261ecSmrg *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR 1905b261ecSmrg *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 2005b261ecSmrg *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2105b261ecSmrg *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg *Except as contained in this notice, the name of the XFree86 Project 2405b261ecSmrg *shall not be used in advertising or otherwise to promote the sale, use 2505b261ecSmrg *or other dealings in this Software without prior written authorization 2605b261ecSmrg *from the XFree86 Project. 2705b261ecSmrg * 2805b261ecSmrg * Authors: Kensuke Matsuzaki 2905b261ecSmrg * Harold L Hunt II 3005b261ecSmrg */ 3105b261ecSmrg 3205b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3305b261ecSmrg#include <xwin-config.h> 3405b261ecSmrg#endif 3505b261ecSmrg 3605b261ecSmrg#include "win.h" 3705b261ecSmrg 3805b261ecSmrg/* 3905b261ecSmrg * winSetShapeMultiWindow - See Porting Layer Definition - p. 42 4005b261ecSmrg */ 4105b261ecSmrg 4205b261ecSmrgvoid 4335c4bbdfSmrgwinSetShapeMultiWindow(WindowPtr pWin, int kind) 4405b261ecSmrg{ 4535c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 4635c4bbdfSmrg 4735c4bbdfSmrg winScreenPriv(pScreen); 4805b261ecSmrg 4905b261ecSmrg#if CYGMULTIWINDOW_DEBUG 5035c4bbdfSmrg ErrorF("winSetShapeMultiWindow - pWin: %p kind: %i\n", pWin, kind); 5105b261ecSmrg#endif 5205b261ecSmrg 5335c4bbdfSmrg WIN_UNWRAP(SetShape); 5435c4bbdfSmrg (*pScreen->SetShape) (pWin, kind); 5535c4bbdfSmrg WIN_WRAP(SetShape, winSetShapeMultiWindow); 5635c4bbdfSmrg 5735c4bbdfSmrg /* Update the Windows window's shape */ 5835c4bbdfSmrg winReshapeMultiWindow(pWin); 5935c4bbdfSmrg winUpdateRgnMultiWindow(pWin); 6035c4bbdfSmrg 6135c4bbdfSmrg return; 6235c4bbdfSmrg} 6305b261ecSmrg 6405b261ecSmrg/* 6505b261ecSmrg * winUpdateRgnMultiWindow - Local function to update a Windows window region 6605b261ecSmrg */ 6705b261ecSmrg 6805b261ecSmrgvoid 6935c4bbdfSmrgwinUpdateRgnMultiWindow(WindowPtr pWin) 7005b261ecSmrg{ 7135c4bbdfSmrg SetWindowRgn(winGetWindowPriv(pWin)->hWnd, 7235c4bbdfSmrg winGetWindowPriv(pWin)->hRgn, TRUE); 736747b715Smrg 7435c4bbdfSmrg /* The system now owns the region specified by the region handle and will delete it when it is no longer needed. */ 7535c4bbdfSmrg winGetWindowPriv(pWin)->hRgn = NULL; 7605b261ecSmrg} 7705b261ecSmrg 7805b261ecSmrg/* 7905b261ecSmrg * winReshapeMultiWindow - Computes the composite clipping region for a window 8005b261ecSmrg */ 8105b261ecSmrg 8205b261ecSmrgvoid 8335c4bbdfSmrgwinReshapeMultiWindow(WindowPtr pWin) 8405b261ecSmrg{ 8535c4bbdfSmrg int nRects; 8635c4bbdfSmrg RegionRec rrNewShape; 8735c4bbdfSmrg BoxPtr pShape, pRects, pEnd; 8835c4bbdfSmrg HRGN hRgn, hRgnRect; 8935c4bbdfSmrg 9035c4bbdfSmrg winWindowPriv(pWin); 9105b261ecSmrg 9205b261ecSmrg#if CYGDEBUG 9335c4bbdfSmrg winDebug("winReshape ()\n"); 9405b261ecSmrg#endif 9505b261ecSmrg 9635c4bbdfSmrg /* Bail if the window is the root window */ 9735c4bbdfSmrg if (pWin->parent == NULL) 9835c4bbdfSmrg return; 9905b261ecSmrg 10035c4bbdfSmrg /* Bail if the window is not top level */ 10135c4bbdfSmrg if (pWin->parent->parent != NULL) 10235c4bbdfSmrg return; 10335c4bbdfSmrg 10435c4bbdfSmrg /* Bail if Windows window handle is invalid */ 10535c4bbdfSmrg if (pWinPriv->hWnd == NULL) 10635c4bbdfSmrg return; 10735c4bbdfSmrg 10835c4bbdfSmrg /* Free any existing window region stored in the window privates */ 10935c4bbdfSmrg if (pWinPriv->hRgn != NULL) { 11035c4bbdfSmrg DeleteObject(pWinPriv->hRgn); 11135c4bbdfSmrg pWinPriv->hRgn = NULL; 11205b261ecSmrg } 11305b261ecSmrg 11435c4bbdfSmrg /* Bail if the window has no bounding region defined */ 11535c4bbdfSmrg if (!wBoundingShape(pWin)) 11635c4bbdfSmrg return; 11735c4bbdfSmrg 11835c4bbdfSmrg RegionNull(&rrNewShape); 11935c4bbdfSmrg RegionCopy(&rrNewShape, wBoundingShape(pWin)); 12035c4bbdfSmrg RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth); 12135c4bbdfSmrg 12235c4bbdfSmrg nRects = RegionNumRects(&rrNewShape); 12335c4bbdfSmrg pShape = RegionRects(&rrNewShape); 12435c4bbdfSmrg 12535c4bbdfSmrg /* Don't do anything if there are no rectangles in the region */ 12635c4bbdfSmrg if (nRects > 0) { 12735c4bbdfSmrg RECT rcClient; 12835c4bbdfSmrg RECT rcWindow; 12935c4bbdfSmrg int iOffsetX, iOffsetY; 13035c4bbdfSmrg 13135c4bbdfSmrg /* Get client rectangle */ 13235c4bbdfSmrg if (!GetClientRect(pWinPriv->hWnd, &rcClient)) { 13335c4bbdfSmrg ErrorF("winReshape - GetClientRect failed, bailing: %d\n", 13435c4bbdfSmrg (int) GetLastError()); 13535c4bbdfSmrg return; 13635c4bbdfSmrg } 13735c4bbdfSmrg 13835c4bbdfSmrg /* Translate client rectangle coords to screen coords */ 13935c4bbdfSmrg /* NOTE: Only transforms top and left members */ 14035c4bbdfSmrg ClientToScreen(pWinPriv->hWnd, (LPPOINT) &rcClient); 14135c4bbdfSmrg 14235c4bbdfSmrg /* Get window rectangle */ 14335c4bbdfSmrg if (!GetWindowRect(pWinPriv->hWnd, &rcWindow)) { 14435c4bbdfSmrg ErrorF("winReshape - GetWindowRect failed, bailing: %d\n", 14535c4bbdfSmrg (int) GetLastError()); 14635c4bbdfSmrg return; 14705b261ecSmrg } 14835c4bbdfSmrg 14935c4bbdfSmrg /* Calculate offset from window upper-left to client upper-left */ 15035c4bbdfSmrg iOffsetX = rcClient.left - rcWindow.left; 15135c4bbdfSmrg iOffsetY = rcClient.top - rcWindow.top; 15235c4bbdfSmrg 15335c4bbdfSmrg /* Create initial Windows region for title bar */ 15435c4bbdfSmrg /* FIXME: Mean, nasty, ugly hack!!! */ 15535c4bbdfSmrg hRgn = CreateRectRgn(0, 0, rcWindow.right, iOffsetY); 15635c4bbdfSmrg if (hRgn == NULL) { 15735c4bbdfSmrg ErrorF("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " 15835c4bbdfSmrg "failed: %d\n", 15935c4bbdfSmrg 0, 0, (int) rcWindow.right, iOffsetY, (int) GetLastError()); 16035c4bbdfSmrg } 16135c4bbdfSmrg 16235c4bbdfSmrg /* Loop through all rectangles in the X region */ 16335c4bbdfSmrg for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) { 16435c4bbdfSmrg /* Create a Windows region for the X rectangle */ 16535c4bbdfSmrg hRgnRect = CreateRectRgn(pRects->x1 + iOffsetX, 16635c4bbdfSmrg pRects->y1 + iOffsetY, 16735c4bbdfSmrg pRects->x2 + iOffsetX, 16835c4bbdfSmrg pRects->y2 + iOffsetY); 16935c4bbdfSmrg if (hRgnRect == NULL) { 17035c4bbdfSmrg ErrorF("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " 17135c4bbdfSmrg "failed: %d\n" 17235c4bbdfSmrg "\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n", 17335c4bbdfSmrg pRects->x1 + iOffsetX, 17435c4bbdfSmrg pRects->y1 + iOffsetY, 17535c4bbdfSmrg pRects->x2 + iOffsetX, 17635c4bbdfSmrg pRects->y2 + iOffsetY, 17735c4bbdfSmrg (int) GetLastError(), 17835c4bbdfSmrg pRects->x1, pRects->x2, iOffsetX, 17935c4bbdfSmrg pRects->y1, pRects->y2, iOffsetY); 18035c4bbdfSmrg } 18135c4bbdfSmrg 18235c4bbdfSmrg /* Merge the Windows region with the accumulated region */ 18335c4bbdfSmrg if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) { 18435c4bbdfSmrg ErrorF("winReshape - CombineRgn () failed: %d\n", 18535c4bbdfSmrg (int) GetLastError()); 18635c4bbdfSmrg } 18735c4bbdfSmrg 18835c4bbdfSmrg /* Delete the temporary Windows region */ 18935c4bbdfSmrg DeleteObject(hRgnRect); 19035c4bbdfSmrg } 19135c4bbdfSmrg 19235c4bbdfSmrg /* Save a handle to the composite region in the window privates */ 19335c4bbdfSmrg pWinPriv->hRgn = hRgn; 19405b261ecSmrg } 19505b261ecSmrg 19635c4bbdfSmrg RegionUninit(&rrNewShape); 19735c4bbdfSmrg 19835c4bbdfSmrg return; 19905b261ecSmrg} 200