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: Harold L Hunt II 2905b261ecSmrg * Kensuke Matsuzaki 3005b261ecSmrg */ 3105b261ecSmrg 3205b261ecSmrg#ifdef HAVE_XWIN_CONFIG_H 3305b261ecSmrg#include <xwin-config.h> 3405b261ecSmrg#endif 3505b261ecSmrg#include "win.h" 3605b261ecSmrg 3705b261ecSmrg/* 3805b261ecSmrg * Prototypes for local functions 3905b261ecSmrg */ 4005b261ecSmrg 4105b261ecSmrgstatic int 4235c4bbdfSmrg winAddRgn(WindowPtr pWindow, void *data); 4305b261ecSmrg 4405b261ecSmrgstatic 4535c4bbdfSmrg void 4635c4bbdfSmrg winUpdateRgnRootless(WindowPtr pWindow); 4705b261ecSmrg 4805b261ecSmrgstatic 4935c4bbdfSmrg void 5035c4bbdfSmrg winReshapeRootless(WindowPtr pWin); 5105b261ecSmrg 5205b261ecSmrg/* See Porting Layer Definition - p. 37 */ 5305b261ecSmrg/* See mfb/mfbwindow.c - mfbCreateWindow() */ 5405b261ecSmrg 5505b261ecSmrgBool 5635c4bbdfSmrgwinCreateWindowRootless(WindowPtr pWin) 5705b261ecSmrg{ 5835c4bbdfSmrg Bool fResult = FALSE; 5935c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 6035c4bbdfSmrg 6135c4bbdfSmrg winWindowPriv(pWin); 6235c4bbdfSmrg winScreenPriv(pScreen); 6305b261ecSmrg 6405b261ecSmrg#if CYGDEBUG 6535c4bbdfSmrg winTrace("winCreateWindowRootless (%p)\n", pWin); 6605b261ecSmrg#endif 6705b261ecSmrg 6835c4bbdfSmrg WIN_UNWRAP(CreateWindow); 6935c4bbdfSmrg fResult = (*pScreen->CreateWindow) (pWin); 7035c4bbdfSmrg WIN_WRAP(CreateWindow, winCreateWindowRootless); 7105b261ecSmrg 7235c4bbdfSmrg pWinPriv->hRgn = NULL; 7305b261ecSmrg 7435c4bbdfSmrg return fResult; 7535c4bbdfSmrg} 7605b261ecSmrg 7705b261ecSmrg/* See Porting Layer Definition - p. 37 */ 7805b261ecSmrg/* See mfb/mfbwindow.c - mfbDestroyWindow() */ 7905b261ecSmrg 8005b261ecSmrgBool 8135c4bbdfSmrgwinDestroyWindowRootless(WindowPtr pWin) 8205b261ecSmrg{ 8335c4bbdfSmrg Bool fResult = FALSE; 8435c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 8535c4bbdfSmrg 8635c4bbdfSmrg winWindowPriv(pWin); 8735c4bbdfSmrg winScreenPriv(pScreen); 8805b261ecSmrg 8905b261ecSmrg#if CYGDEBUG 9035c4bbdfSmrg winTrace("winDestroyWindowRootless (%p)\n", pWin); 9105b261ecSmrg#endif 9205b261ecSmrg 9335c4bbdfSmrg WIN_UNWRAP(DestroyWindow); 9435c4bbdfSmrg fResult = (*pScreen->DestroyWindow) (pWin); 9535c4bbdfSmrg WIN_WRAP(DestroyWindow, winDestroyWindowRootless); 9605b261ecSmrg 9735c4bbdfSmrg if (pWinPriv->hRgn != NULL) { 9835c4bbdfSmrg DeleteObject(pWinPriv->hRgn); 9935c4bbdfSmrg pWinPriv->hRgn = NULL; 10035c4bbdfSmrg } 10135c4bbdfSmrg 10235c4bbdfSmrg winUpdateRgnRootless(pWin); 10305b261ecSmrg 10435c4bbdfSmrg return fResult; 10535c4bbdfSmrg} 10605b261ecSmrg 10705b261ecSmrg/* See Porting Layer Definition - p. 37 */ 10805b261ecSmrg/* See mfb/mfbwindow.c - mfbPositionWindow() */ 10905b261ecSmrg 11005b261ecSmrgBool 11135c4bbdfSmrgwinPositionWindowRootless(WindowPtr pWin, int x, int y) 11205b261ecSmrg{ 11335c4bbdfSmrg Bool fResult = FALSE; 11435c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 11505b261ecSmrg 11635c4bbdfSmrg winScreenPriv(pScreen); 11705b261ecSmrg 11835c4bbdfSmrg#if CYGDEBUG 11935c4bbdfSmrg winTrace("winPositionWindowRootless (%p)\n", pWin); 12005b261ecSmrg#endif 12105b261ecSmrg 12235c4bbdfSmrg WIN_UNWRAP(PositionWindow); 12335c4bbdfSmrg fResult = (*pScreen->PositionWindow) (pWin, x, y); 12435c4bbdfSmrg WIN_WRAP(PositionWindow, winPositionWindowRootless); 12505b261ecSmrg 12635c4bbdfSmrg winUpdateRgnRootless(pWin); 12705b261ecSmrg 12835c4bbdfSmrg return fResult; 12905b261ecSmrg} 13005b261ecSmrg 13105b261ecSmrg/* See Porting Layer Definition - p. 37 */ 13205b261ecSmrg/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */ 13305b261ecSmrg 13405b261ecSmrgBool 13535c4bbdfSmrgwinChangeWindowAttributesRootless(WindowPtr pWin, unsigned long mask) 13605b261ecSmrg{ 13735c4bbdfSmrg Bool fResult = FALSE; 13835c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 13935c4bbdfSmrg 14035c4bbdfSmrg winScreenPriv(pScreen); 14105b261ecSmrg 14205b261ecSmrg#if CYGDEBUG 14335c4bbdfSmrg winTrace("winChangeWindowAttributesRootless (%p)\n", pWin); 14405b261ecSmrg#endif 14505b261ecSmrg 14635c4bbdfSmrg WIN_UNWRAP(ChangeWindowAttributes); 14735c4bbdfSmrg fResult = (*pScreen->ChangeWindowAttributes) (pWin, mask); 14835c4bbdfSmrg WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesRootless); 14935c4bbdfSmrg 15035c4bbdfSmrg winUpdateRgnRootless(pWin); 15135c4bbdfSmrg 15235c4bbdfSmrg return fResult; 15335c4bbdfSmrg} 15405b261ecSmrg 15505b261ecSmrg/* See Porting Layer Definition - p. 37 15605b261ecSmrg * Also referred to as UnrealizeWindow 15705b261ecSmrg */ 15805b261ecSmrg 15905b261ecSmrgBool 16035c4bbdfSmrgwinUnmapWindowRootless(WindowPtr pWin) 16105b261ecSmrg{ 16235c4bbdfSmrg Bool fResult = FALSE; 16335c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 16435c4bbdfSmrg 16535c4bbdfSmrg winWindowPriv(pWin); 16635c4bbdfSmrg winScreenPriv(pScreen); 16705b261ecSmrg 16805b261ecSmrg#if CYGDEBUG 16935c4bbdfSmrg winTrace("winUnmapWindowRootless (%p)\n", pWin); 17005b261ecSmrg#endif 17105b261ecSmrg 17235c4bbdfSmrg WIN_UNWRAP(UnrealizeWindow); 17335c4bbdfSmrg fResult = (*pScreen->UnrealizeWindow) (pWin); 17435c4bbdfSmrg WIN_WRAP(UnrealizeWindow, winUnmapWindowRootless); 17535c4bbdfSmrg 17635c4bbdfSmrg if (pWinPriv->hRgn != NULL) { 17735c4bbdfSmrg DeleteObject(pWinPriv->hRgn); 17835c4bbdfSmrg pWinPriv->hRgn = NULL; 17935c4bbdfSmrg } 18035c4bbdfSmrg 18135c4bbdfSmrg winUpdateRgnRootless(pWin); 18205b261ecSmrg 18335c4bbdfSmrg return fResult; 18435c4bbdfSmrg} 18505b261ecSmrg 18605b261ecSmrg/* See Porting Layer Definition - p. 37 18705b261ecSmrg * Also referred to as RealizeWindow 18805b261ecSmrg */ 18905b261ecSmrg 19005b261ecSmrgBool 19135c4bbdfSmrgwinMapWindowRootless(WindowPtr pWin) 19205b261ecSmrg{ 19335c4bbdfSmrg Bool fResult = FALSE; 19435c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 19505b261ecSmrg 19635c4bbdfSmrg winScreenPriv(pScreen); 19705b261ecSmrg 19805b261ecSmrg#if CYGDEBUG 19935c4bbdfSmrg winTrace("winMapWindowRootless (%p)\n", pWin); 20005b261ecSmrg#endif 20105b261ecSmrg 20235c4bbdfSmrg WIN_UNWRAP(RealizeWindow); 20335c4bbdfSmrg fResult = (*pScreen->RealizeWindow) (pWin); 20435c4bbdfSmrg WIN_WRAP(RealizeWindow, winMapWindowRootless); 20505b261ecSmrg 20635c4bbdfSmrg winReshapeRootless(pWin); 20705b261ecSmrg 20835c4bbdfSmrg winUpdateRgnRootless(pWin); 20905b261ecSmrg 21035c4bbdfSmrg return fResult; 21105b261ecSmrg} 21205b261ecSmrg 21335c4bbdfSmrgvoid 21435c4bbdfSmrgwinSetShapeRootless(WindowPtr pWin, int kind) 21505b261ecSmrg{ 21635c4bbdfSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 21705b261ecSmrg 21835c4bbdfSmrg winScreenPriv(pScreen); 21905b261ecSmrg 22005b261ecSmrg#if CYGDEBUG 22135c4bbdfSmrg winTrace("winSetShapeRootless (%p, %i)\n", pWin, kind); 22205b261ecSmrg#endif 22305b261ecSmrg 22435c4bbdfSmrg WIN_UNWRAP(SetShape); 22535c4bbdfSmrg (*pScreen->SetShape) (pWin, kind); 22635c4bbdfSmrg WIN_WRAP(SetShape, winSetShapeRootless); 22705b261ecSmrg 22835c4bbdfSmrg winReshapeRootless(pWin); 22935c4bbdfSmrg winUpdateRgnRootless(pWin); 23005b261ecSmrg 23135c4bbdfSmrg return; 23205b261ecSmrg} 23305b261ecSmrg 23435c4bbdfSmrg/* 23535c4bbdfSmrg * Local function for adding a region to the Windows window region 23605b261ecSmrg */ 23705b261ecSmrg 23835c4bbdfSmrgstatic 23935c4bbdfSmrg int 24035c4bbdfSmrgwinAddRgn(WindowPtr pWin, void *data) 24105b261ecSmrg{ 24235c4bbdfSmrg int iX, iY, iWidth, iHeight, iBorder; 24335c4bbdfSmrg HRGN hRgn = *(HRGN *) data; 24435c4bbdfSmrg HRGN hRgnWin; 24505b261ecSmrg 24635c4bbdfSmrg winWindowPriv(pWin); 24705b261ecSmrg 24835c4bbdfSmrg /* If pWin is not Root */ 24935c4bbdfSmrg if (pWin->parent != NULL) { 25005b261ecSmrg#if CYGDEBUG 25135c4bbdfSmrg winDebug("winAddRgn ()\n"); 25205b261ecSmrg#endif 25335c4bbdfSmrg if (pWin->mapped) { 25435c4bbdfSmrg iBorder = wBorderWidth(pWin); 25505b261ecSmrg 25635c4bbdfSmrg iX = pWin->drawable.x - iBorder; 25735c4bbdfSmrg iY = pWin->drawable.y - iBorder; 25805b261ecSmrg 25935c4bbdfSmrg iWidth = pWin->drawable.width + iBorder * 2; 26035c4bbdfSmrg iHeight = pWin->drawable.height + iBorder * 2; 26105b261ecSmrg 26235c4bbdfSmrg hRgnWin = CreateRectRgn(0, 0, iWidth, iHeight); 26305b261ecSmrg 26435c4bbdfSmrg if (hRgnWin == NULL) { 26535c4bbdfSmrg ErrorF("winAddRgn - CreateRectRgn () failed\n"); 26635c4bbdfSmrg ErrorF(" Rect %d %d %d %d\n", 26735c4bbdfSmrg iX, iY, iX + iWidth, iY + iHeight); 26835c4bbdfSmrg } 26905b261ecSmrg 27035c4bbdfSmrg if (pWinPriv->hRgn) { 27135c4bbdfSmrg if (CombineRgn(hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND) 27235c4bbdfSmrg == ERROR) { 27335c4bbdfSmrg ErrorF("winAddRgn - CombineRgn () failed\n"); 27435c4bbdfSmrg } 27535c4bbdfSmrg } 27605b261ecSmrg 27735c4bbdfSmrg OffsetRgn(hRgnWin, iX, iY); 27805b261ecSmrg 27935c4bbdfSmrg if (CombineRgn(hRgn, hRgn, hRgnWin, RGN_OR) == ERROR) { 28035c4bbdfSmrg ErrorF("winAddRgn - CombineRgn () failed\n"); 28135c4bbdfSmrg } 28205b261ecSmrg 28335c4bbdfSmrg DeleteObject(hRgnWin); 28435c4bbdfSmrg } 28535c4bbdfSmrg return WT_DONTWALKCHILDREN; 28605b261ecSmrg } 28735c4bbdfSmrg else { 28835c4bbdfSmrg return WT_WALKCHILDREN; 28905b261ecSmrg } 29005b261ecSmrg} 29105b261ecSmrg 29205b261ecSmrg/* 29305b261ecSmrg * Local function to update the Windows window's region 29405b261ecSmrg */ 29505b261ecSmrg 29605b261ecSmrgstatic 29735c4bbdfSmrg void 29835c4bbdfSmrgwinUpdateRgnRootless(WindowPtr pWin) 29905b261ecSmrg{ 30035c4bbdfSmrg HRGN hRgn = CreateRectRgn(0, 0, 0, 0); 30135c4bbdfSmrg 30235c4bbdfSmrg if (hRgn != NULL) { 30335c4bbdfSmrg WalkTree(pWin->drawable.pScreen, winAddRgn, &hRgn); 30435c4bbdfSmrg SetWindowRgn(winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen, 30535c4bbdfSmrg hRgn, TRUE); 30605b261ecSmrg } 30735c4bbdfSmrg else { 30835c4bbdfSmrg ErrorF("winUpdateRgnRootless - CreateRectRgn failed.\n"); 30905b261ecSmrg } 31005b261ecSmrg} 31105b261ecSmrg 31205b261ecSmrgstatic 31335c4bbdfSmrg void 31435c4bbdfSmrgwinReshapeRootless(WindowPtr pWin) 31505b261ecSmrg{ 31635c4bbdfSmrg int nRects; 31735c4bbdfSmrg RegionRec rrNewShape; 31835c4bbdfSmrg BoxPtr pShape, pRects, pEnd; 31935c4bbdfSmrg HRGN hRgn, hRgnRect; 32035c4bbdfSmrg 32135c4bbdfSmrg winWindowPriv(pWin); 32205b261ecSmrg 32305b261ecSmrg#if CYGDEBUG 32435c4bbdfSmrg winDebug("winReshapeRootless ()\n"); 32505b261ecSmrg#endif 32605b261ecSmrg 32735c4bbdfSmrg /* Bail if the window is the root window */ 32835c4bbdfSmrg if (pWin->parent == NULL) 32935c4bbdfSmrg return; 33005b261ecSmrg 33135c4bbdfSmrg /* Bail if the window is not top level */ 33235c4bbdfSmrg if (pWin->parent->parent != NULL) 33335c4bbdfSmrg return; 33405b261ecSmrg 33535c4bbdfSmrg /* Free any existing window region stored in the window privates */ 33635c4bbdfSmrg if (pWinPriv->hRgn != NULL) { 33735c4bbdfSmrg DeleteObject(pWinPriv->hRgn); 33835c4bbdfSmrg pWinPriv->hRgn = NULL; 33905b261ecSmrg } 34005b261ecSmrg 34135c4bbdfSmrg /* Bail if the window has no bounding region defined */ 34235c4bbdfSmrg if (!wBoundingShape(pWin)) 34335c4bbdfSmrg return; 34435c4bbdfSmrg 34535c4bbdfSmrg RegionNull(&rrNewShape); 34635c4bbdfSmrg RegionCopy(&rrNewShape, wBoundingShape(pWin)); 34735c4bbdfSmrg RegionTranslate(&rrNewShape, pWin->borderWidth, pWin->borderWidth); 34835c4bbdfSmrg 34935c4bbdfSmrg nRects = RegionNumRects(&rrNewShape); 35035c4bbdfSmrg pShape = RegionRects(&rrNewShape); 35135c4bbdfSmrg 35235c4bbdfSmrg if (nRects > 0) { 35335c4bbdfSmrg /* Create initial empty Windows region */ 35435c4bbdfSmrg hRgn = CreateRectRgn(0, 0, 0, 0); 35535c4bbdfSmrg 35635c4bbdfSmrg /* Loop through all rectangles in the X region */ 35735c4bbdfSmrg for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++) { 35835c4bbdfSmrg /* Create a Windows region for the X rectangle */ 35935c4bbdfSmrg hRgnRect = CreateRectRgn(pRects->x1, pRects->y1, 36035c4bbdfSmrg pRects->x2, pRects->y2); 36135c4bbdfSmrg if (hRgnRect == NULL) { 36235c4bbdfSmrg ErrorF("winReshapeRootless - CreateRectRgn() failed\n"); 36335c4bbdfSmrg } 36435c4bbdfSmrg 36535c4bbdfSmrg /* Merge the Windows region with the accumulated region */ 36635c4bbdfSmrg if (CombineRgn(hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) { 36735c4bbdfSmrg ErrorF("winReshapeRootless - CombineRgn() failed\n"); 36835c4bbdfSmrg } 36935c4bbdfSmrg 37035c4bbdfSmrg /* Delete the temporary Windows region */ 37135c4bbdfSmrg DeleteObject(hRgnRect); 37205b261ecSmrg } 37335c4bbdfSmrg 37435c4bbdfSmrg /* Save a handle to the composite region in the window privates */ 37535c4bbdfSmrg pWinPriv->hRgn = hRgn; 37605b261ecSmrg } 37705b261ecSmrg 37835c4bbdfSmrg RegionUninit(&rrNewShape); 37935c4bbdfSmrg 38035c4bbdfSmrg return; 38105b261ecSmrg} 382