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