Index: xorg/composite/compalloc.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/composite/compalloc.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -b -B -r1.8 -r1.9 --- xorg/composite/compalloc.c 12 Jan 2006 22:14:55 -0000 1.8 +++ xorg/composite/compalloc.c 13 Mar 2006 21:59:55 -0000 1.9 @@ -1,6 +1,26 @@ /* * $Id: compalloc.c,v 1.7 2005/07/03 07:37:34 daniels Exp $ * + * Copyright © 2006 Sun Microsystems + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sun Microsystems not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * * Copyright © 2003 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -58,6 +78,11 @@ CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw; Bool wasMapped = pWin->mapped; + CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); + + if (pWin == cs->pOverlayWin) { + return Success; + } /* * Only one Manual update is allowed Index: xorg/composite/compext.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/composite/compext.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -b -B -r1.5 -r1.6 --- xorg/composite/compext.c 3 Jul 2005 07:37:34 -0000 1.5 +++ xorg/composite/compext.c 13 Mar 2006 21:59:55 -0000 1.6 @@ -1,5 +1,26 @@ /* - * $Id: compext.c,v 1.4 2005/07/03 07:01:17 daniels Exp $ + * $Id: compext.c,v 1.5 2005/07/03 07:37:34 daniels Exp $ + * + * + * Copyright © 2006 Sun Microsystems + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sun Microsystems not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * * Copyright © 2003 Keith Packard * @@ -32,6 +53,10 @@ int CompositeClientPrivateIndex; RESTYPE CompositeClientWindowType; RESTYPE CompositeClientSubwindowsType; +RESTYPE CompositeClientOverlayType; + +static void deleteCompOverlayClient (CompOverlayClientPtr pOcToDel, + ScreenPtr pScreen); typedef struct _CompositeClient { int major_version; @@ -77,6 +102,26 @@ } static int +FreeCompositeClientOverlay (pointer value, XID ccwid) +{ + CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; + ScreenPtr pScreen = pOc->pScreen; + CompScreenPtr cs; + + deleteCompOverlayClient(pOc, pScreen); + + /* Unmap overlay window when there are no more clients using it */ + cs = GetCompScreen(pScreen); + if (cs->pOverlayClients == NULL) { + if (cs->pOverlayWin != NULL) { + UnmapWindow(cs->pOverlayWin, FALSE); + } + } + + return Success; +} + +static int ProcCompositeQueryVersion (ClientPtr client) { CompositeClientPtr pCompositeClient = GetCompositeClient (client); @@ -243,6 +288,229 @@ return(client->noClientException); } + +/* + * Routines for manipulating the per-screen overlay clients list. + * This list indicates which clients have called GetOverlayWindow + * for this screen. + */ + +/* Return the screen's overlay client list element for the given client */ +static CompOverlayClientPtr +findCompOverlayClient (ClientPtr pClient, ScreenPtr pScreen) +{ + CompScreenPtr cs = GetCompScreen(pScreen); + CompOverlayClientPtr pOc; + + for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext) { + if (pOc->pClient == pClient) { + return pOc; + } + } + + return NULL; +} + +static int +createCompOverlayClient (ClientPtr pClient, ScreenPtr pScreen) +{ + CompScreenPtr cs = GetCompScreen(pScreen); + CompOverlayClientPtr pOc; + + pOc = (CompOverlayClientPtr) xalloc(sizeof(CompOverlayClientRec)); + if (pOc == NULL) { + return BadAlloc; + } + pOc->pClient = pClient; + pOc->pScreen = pScreen; + pOc->resource = FakeClientID(pClient->index); + pOc->pNext = cs->pOverlayClients; + cs->pOverlayClients = pOc; + + /* + * Create a resource for this element so it can be deleted + * when the client goes away. + */ + if (!AddResource (pOc->resource, CompositeClientOverlayType, + (pointer) pOc)) { + xfree(pOc); + return BadAlloc; + } + + return Success; +} + +/* + * Delete the given overlay client list element from its screen list. + */ +static void +deleteCompOverlayClient (CompOverlayClientPtr pOcToDel, ScreenPtr pScreen) +{ + CompScreenPtr cs = GetCompScreen(pScreen); + CompOverlayClientPtr pOc, pNext; + CompOverlayClientPtr pOcLast = NULL; + + pOc = cs->pOverlayClients; + while (pOc != NULL) { + pNext = pOc->pNext; + if (pOc == pOcToDel) { + xfree(pOc); + if (pOcLast == NULL) { + cs->pOverlayClients = pNext; + } else { + pOcLast->pNext = pNext; + } + break; + } + pOcLast = pOc; + pOc = pNext; + } +} + +/* + * Delete all the hide-counts list elements for this screen. + */ +void +deleteCompOverlayClientsForScreen (ScreenPtr pScreen) +{ + CompScreenPtr cs = GetCompScreen(pScreen); + CompOverlayClientPtr pOc, pTmp; + + pOc = cs->pOverlayClients; + while (pOc != NULL) { + pTmp = pOc->pNext; + FreeResource(pOc->resource, 0); + pOc = pTmp; + } + cs->pOverlayClients = NULL; +} + +/* +** If necessary, create the overlay window. And map it +** Note: I found it excessively difficult to destroy this window +** during compCloseScreen; DeleteWindow can't be called because +** the input devices are already shut down. So we are going to +** just allocate an overlay window once per screen per X server +** invocation. +*/ + +static WindowPtr +createOverlayWindow (ScreenPtr pScreen) +{ + int wid = FakeClientID(0); + WindowPtr pWin; + XID overrideRedirect = TRUE; + int result; + + pWin = CreateWindow ( + wid, WindowTable[pScreen->myNum], + 0, 0, pScreen->width, pScreen->height, 0, + InputOutput, CWOverrideRedirect, &overrideRedirect, + WindowTable[pScreen->myNum]->drawable.depth, + serverClient, pScreen->rootVisual, &result); + if (pWin == NULL) { + return NULL; + } + + if (!AddResource(wid, RT_WINDOW, (pointer)pWin)) { + DeleteWindow(pWin, None); + return NULL; + } + + return pWin; +} + +int +ProcCompositeGetOverlayWindow (ClientPtr client) +{ + REQUEST(xCompositeGetOverlayWindowReq); + xCompositeGetOverlayWindowReply rep; + WindowPtr pWin; + ScreenPtr pScreen; + CompScreenPtr cs; + CompOverlayClientPtr pOc; + + REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); + pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); + if (!pWin) + { + client->errorValue = stuff->window; + return BadWindow; + } + pScreen = pWin->drawable.pScreen; + + cs = GetCompScreen(pScreen); + if (cs->pOverlayWin == NULL) { + cs->pOverlayWin = createOverlayWindow(pScreen); + if (cs->pOverlayWin == NULL) { + return BadAlloc; + } + } + MapWindow(cs->pOverlayWin, serverClient); + + /* Record that client is using this overlay window */ + pOc = findCompOverlayClient(client, pScreen); + if (pOc == NULL) { + int ret = createCompOverlayClient(client, pScreen); + if (ret != Success) { + return ret; + } + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.overlayWin = cs->pOverlayWin->drawable.id; + + if (client->swapped) + { + int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.overlayWin, n); + } + (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep); + + return client->noClientException; +} + +int +ProcCompositeReleaseOverlayWindow (ClientPtr client) +{ + REQUEST(xCompositeReleaseOverlayWindowReq); + WindowPtr pWin; + ScreenPtr pScreen; + CompOverlayClientPtr pOc; + CompScreenPtr cs; + + REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); + pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); + if (!pWin) + { + client->errorValue = stuff->window; + return BadWindow; + } + pScreen = pWin->drawable.pScreen; + + /* + * Has client queried a reference to the overlay window + * on this screen? If not, generate an error. + */ + pOc = findCompOverlayClient(client, pWin->drawable.pScreen); + if (pOc == NULL) { + return BadMatch; + } + + deleteCompOverlayClient(pOc, pOc->pScreen); + + cs = GetCompScreen(pScreen); + if (cs->pOverlayClients == NULL) { + UnmapWindow(cs->pOverlayWin, FALSE); + } + + return client->noClientException; +} + int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { ProcCompositeQueryVersion, ProcCompositeRedirectWindow, @@ -251,6 +519,8 @@ ProcCompositeUnredirectSubwindows, ProcCompositeCreateRegionFromBorderClip, ProcCompositeNameWindowPixmap, + ProcCompositeGetOverlayWindow, + ProcCompositeReleaseOverlayWindow, }; static int @@ -351,6 +621,30 @@ return (*ProcCompositeVector[stuff->compositeReqType]) (client); } +int +SProcCompositeGetOverlayWindow (ClientPtr client) +{ + int n; + REQUEST(xCompositeGetOverlayWindowReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); + swapl(&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + +int +SProcCompositeReleaseOverlayWindow (ClientPtr client) +{ + int n; + REQUEST(xCompositeReleaseOverlayWindowReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); + swapl(&stuff->window, n); + return (*ProcCompositeVector[stuff->compositeReqType]) (client); +} + int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { SProcCompositeQueryVersion, SProcCompositeRedirectWindow, @@ -359,6 +653,8 @@ SProcCompositeUnredirectSubwindows, SProcCompositeCreateRegionFromBorderClip, SProcCompositeNameWindowPixmap, + SProcCompositeGetOverlayWindow, + SProcCompositeReleaseOverlayWindow, }; static int @@ -386,6 +682,10 @@ if (!CompositeClientSubwindowsType) return; + CompositeClientOverlayType = CreateNewResourceType (FreeCompositeClientOverlay); + if (!CompositeClientOverlayType) + return; + CompositeClientPrivateIndex = AllocateClientPrivateIndex (); if (!AllocateClientPrivate (CompositeClientPrivateIndex, sizeof (CompositeClientRec))) @@ -400,7 +700,6 @@ return; CompositeReqCode = (CARD8) extEntry->base; - for (s = 0; s < screenInfo.numScreens; s++) if (!compScreenInit (screenInfo.screens[s])) return; Index: xorg/composite/compinit.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/composite/compinit.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -b -B -r1.9 -r1.10 --- xorg/composite/compinit.c 3 Jul 2005 07:37:34 -0000 1.9 +++ xorg/composite/compinit.c 13 Mar 2006 21:59:55 -0000 1.10 @@ -1,5 +1,25 @@ /* - * $Id: compinit.c,v 1.8 2005/07/03 07:01:17 daniels Exp $ + * $Id: compinit.c,v 1.9 2005/07/03 07:37:34 daniels Exp $ + * + * Copyright © 2006 Sun Microsystems + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sun Microsystems not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * * Copyright © 2003 Keith Packard * @@ -55,6 +76,15 @@ pScreen->CreateWindow = cs->CreateWindow; pScreen->CopyWindow = cs->CopyWindow; pScreen->PositionWindow = cs->PositionWindow; + + deleteCompOverlayClientsForScreen(pScreen); + + /* + ** Note: no need to call DeleteWindow; the server has + ** already destroyed it. + */ + cs->pOverlayWin = NULL; + xfree (cs); pScreen->devPrivates[CompScreenPrivateIndex].ptr = 0; ret = (*pScreen->CloseScreen) (index, pScreen); @@ -333,6 +363,8 @@ return FALSE; cs->damaged = FALSE; + cs->pOverlayWin = NULL; + cs->pOverlayClients = NULL; if (!compAddAlternateVisuals (pScreen, cs)) { Index: xorg/composite/compint.h =================================================================== RCS file: /cvs/xorg/xserver/xorg/composite/compint.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -b -B -r1.8 -r1.9 --- xorg/composite/compint.h 3 Jul 2005 08:53:37 -0000 1.8 +++ xorg/composite/compint.h 13 Mar 2006 21:59:55 -0000 1.9 @@ -1,6 +1,26 @@ /* * $Id: compint.h,v 1.7 2005/07/03 07:01:17 daniels Exp $ * + * Copyright © 2006 Sun Microsystems + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sun Microsystems not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * * Copyright © 2003 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -95,6 +115,15 @@ #define NUM_COMP_ALTERNATE_VISUALS 1 #endif +typedef struct _CompOverlayClientRec *CompOverlayClientPtr; + +typedef struct _CompOverlayClientRec { + CompOverlayClientPtr pNext; + ClientPtr pClient; + ScreenPtr pScreen; + XID resource; +} CompOverlayClientRec; + typedef struct _CompScreen { PositionWindowProcPtr PositionWindow; CopyWindowProcPtr CopyWindow; @@ -126,6 +155,10 @@ CloseScreenProcPtr CloseScreen; Bool damaged; XID alternateVisuals[NUM_COMP_ALTERNATE_VISUALS]; + + WindowPtr pOverlayWin; + CompOverlayClientPtr pOverlayClients; + } CompScreenRec, *CompScreenPtr; extern int CompScreenPrivateIndex; @@ -257,4 +290,25 @@ void compWindowUpdate (WindowPtr pWin); +void +deleteCompOverlayClientsForScreen (ScreenPtr pScreen); + +int +ProcCompositeGetOverlayWindow (ClientPtr client); + +int +ProcCompositeReleaseOverlayWindow (ClientPtr client); + +int +SProcCompositeGetOverlayWindow (ClientPtr client); + +int +SProcCompositeReleaseOverlayWindow (ClientPtr client); + +WindowPtr +CompositeRealChildHead (WindowPtr pWin); + +int +DeleteWindowNoInputDevices(pointer value, XID wid); + #endif /* _COMPINT_H_ */ Index: xorg/composite/compwindow.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/composite/compwindow.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -b -B -r1.11 -r1.12 --- xorg/composite/compwindow.c 3 Jul 2005 07:37:34 -0000 1.11 +++ xorg/composite/compwindow.c 13 Mar 2006 21:59:55 -0000 1.12 @@ -1,5 +1,25 @@ /* - * $Id: compwindow.c,v 1.10 2005/07/03 07:01:17 daniels Exp $ + * $Id: compwindow.c,v 1.11 2005/07/03 07:37:34 daniels Exp $ + * + * Copyright © 2006 Sun Microsystems + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sun Microsystems not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * * Copyright © 2003 Keith Packard * @@ -753,3 +773,34 @@ } } } + +WindowPtr +CompositeRealChildHead (WindowPtr pWin) +{ + WindowPtr pChild, pChildBefore; + CompScreenPtr cs; + + if (!pWin->parent && + (screenIsSaved == SCREEN_SAVER_ON) && + (HasSaverWindow (pWin->drawable.pScreen->myNum))) { + + /* First child is the screen saver; see if next child is the overlay */ + pChildBefore = pWin->firstChild; + pChild = pChildBefore->nextSib; + + } else { + pChildBefore = NullWindow; + pChild = pWin->firstChild; + } + + if (!pChild) { + return NullWindow; + } + + cs = GetCompScreen(pWin->drawable.pScreen); + if (pChild == cs->pOverlayWin) { + return pChild; + } else { + return pChildBefore; + } +} Index: xorg/xfixes/cursor.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/xfixes/cursor.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -b -B -r1.6 -r1.7 --- xorg/xfixes/cursor.c 3 Jul 2005 07:37:35 -0000 1.6 +++ xorg/xfixes/cursor.c 13 Mar 2006 21:59:55 -0000 1.7 @@ -1,6 +1,26 @@ /* * $Id: cursor.c,v 1.5 2005/07/03 07:02:08 daniels Exp $ * + * Copyright © 2006 Sun Microsystems + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sun Microsystems not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * * Copyright © 2002 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -35,10 +55,14 @@ #include "windowstr.h" static RESTYPE CursorClientType; +static RESTYPE CursorHideCountType; static RESTYPE CursorWindowType; static int CursorScreenPrivateIndex = -1; static int CursorGeneration; static CursorPtr CursorCurrent; +static CursorPtr pInvisibleCursor = NULL; + +static void deleteCursorHideCountsForScreen (ScreenPtr pScreen); #define VERIFY_CURSOR(pCursor, cursor, client, access) { \ pCursor = (CursorPtr)SecurityLookupIDByType((client), (cursor), \ @@ -66,12 +90,29 @@ static CursorEventPtr cursorEvents; /* + * Each screen has a list of clients which have requested + * that the cursor be hid, and the number of times each + * client has requested. +*/ + +typedef struct _CursorHideCountRec *CursorHideCountPtr; + +typedef struct _CursorHideCountRec { + CursorHideCountPtr pNext; + ClientPtr pClient; + ScreenPtr pScreen; + int hideCount; + XID resource; +} CursorHideCountRec; + +/* * Wrap DisplayCursor to catch cursor change events */ typedef struct _CursorScreen { DisplayCursorProcPtr DisplayCursor; CloseScreenProcPtr CloseScreen; + CursorHideCountPtr pCursorHideCounts; } CursorScreenRec, *CursorScreenPtr; #define GetCursorScreen(s) ((CursorScreenPtr) ((s)->devPrivates[CursorScreenPrivateIndex].ptr)) @@ -88,7 +129,13 @@ Bool ret; Unwrap (cs, pScreen, DisplayCursor); + + if (cs->pCursorHideCounts != NULL) { + ret = (*pScreen->DisplayCursor) (pScreen, pInvisibleCursor); + } else { ret = (*pScreen->DisplayCursor) (pScreen, pCursor); + } + if (pCursor != CursorCurrent) { CursorEventPtr e; @@ -122,6 +169,7 @@ Unwrap (cs, pScreen, CloseScreen); Unwrap (cs, pScreen, DisplayCursor); + deleteCursorHideCountsForScreen(pScreen); ret = (*pScreen->CloseScreen) (index, pScreen); xfree (cs); if (index == 0) @@ -430,7 +478,7 @@ SProcXFixesGetCursorName (ClientPtr client) { int n; - REQUEST(xXFixesSetCursorNameReq); + REQUEST(xXFixesGetCursorNameReq); swaps (&stuff->length, n); REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq); @@ -687,6 +735,199 @@ return (*ProcXFixesVector[stuff->xfixesReqType]) (client); } +/* + * Routines for manipulating the per-screen hide counts list. + * This list indicates which clients have requested cursor hiding + * for that screen. + */ + +/* Return the screen's hide-counts list element for the given client */ +static CursorHideCountPtr +findCursorHideCount (ClientPtr pClient, ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + CursorHideCountPtr pChc; + + for (pChc = cs->pCursorHideCounts; pChc != NULL; pChc = pChc->pNext) { + if (pChc->pClient == pClient) { + return pChc; + } + } + + return NULL; +} + +static int +createCursorHideCount (ClientPtr pClient, ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + CursorHideCountPtr pChc; + + pChc = (CursorHideCountPtr) xalloc(sizeof(CursorHideCountRec)); + if (pChc == NULL) { + return BadAlloc; + } + pChc->pClient = pClient; + pChc->pScreen = pScreen; + pChc->hideCount = 1; + pChc->resource = FakeClientID(pClient->index); + pChc->pNext = cs->pCursorHideCounts; + cs->pCursorHideCounts = pChc; + + /* + * Create a resource for this element so it can be deleted + * when the client goes away. + */ + if (!AddResource (pChc->resource, CursorHideCountType, + (pointer) pChc)) { + xfree(pChc); + return BadAlloc; + } + + return Success; +} + +/* + * Delete the given hide-counts list element from its screen list. + */ +static void +deleteCursorHideCount (CursorHideCountPtr pChcToDel, ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + CursorHideCountPtr pChc, pNext; + CursorHideCountPtr pChcLast = NULL; + + pChc = cs->pCursorHideCounts; + while (pChc != NULL) { + pNext = pChc->pNext; + if (pChc == pChcToDel) { + xfree(pChc); + if (pChcLast == NULL) { + cs->pCursorHideCounts = pNext; + } else { + pChcLast->pNext = pNext; + } + return; + } + pChcLast = pChc; + pChc = pNext; + } +} + +/* + * Delete all the hide-counts list elements for this screen. + */ +static void +deleteCursorHideCountsForScreen (ScreenPtr pScreen) +{ + CursorScreenPtr cs = GetCursorScreen(pScreen); + CursorHideCountPtr pChc, pTmp; + + pChc = cs->pCursorHideCounts; + while (pChc != NULL) { + pTmp = pChc->pNext; + FreeResource(pChc->resource, 0); + pChc = pTmp; + } + cs->pCursorHideCounts = NULL; +} + +int +ProcXFixesHideCursor (ClientPtr client) +{ + WindowPtr pWin; + CursorHideCountPtr pChc; + REQUEST(xXFixesHideCursorReq); + int ret; + + REQUEST_SIZE_MATCH (xXFixesHideCursorReq); + + pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); + if (!pWin) { + client->errorValue = stuff->window; + return BadWindow; + } + + /* + * Has client hidden the cursor before on this screen? + * If so, just increment the count. + */ + + pChc = findCursorHideCount(client, pWin->drawable.pScreen); + if (pChc != NULL) { + pChc->hideCount++; + return client->noClientException; + } + + /* + * This is the first time this client has hid the cursor + * for this screen. + */ + ret = createCursorHideCount(client, pWin->drawable.pScreen); + + if (ret == Success) { + (void) CursorDisplayCursor(pWin->drawable.pScreen, CursorCurrent); + } + + return ret; +} + +int +SProcXFixesHideCursor (ClientPtr client) +{ + int n; + REQUEST(xXFixesHideCursorReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesHideCursorReq); + swapl (&stuff->window, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesShowCursor (ClientPtr client) +{ + WindowPtr pWin; + CursorHideCountPtr pChc; + REQUEST(xXFixesShowCursorReq); + + REQUEST_SIZE_MATCH (xXFixesShowCursorReq); + + pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); + if (!pWin) { + client->errorValue = stuff->window; + return BadWindow; + } + + /* + * Has client hidden the cursor on this screen? + * If not, generate an error. + */ + pChc = findCursorHideCount(client, pWin->drawable.pScreen); + if (pChc == NULL) { + return BadMatch; + } + + pChc->hideCount--; + if (pChc->hideCount <= 0) { + FreeResource(pChc->resource, 0); + } + + return (client->noClientException); +} + +int +SProcXFixesShowCursor (ClientPtr client) +{ + int n; + REQUEST(xXFixesShowCursorReq); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXFixesShowCursorReq); + swapl (&stuff->window, n); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + static int CursorFreeClient (pointer data, XID id) { @@ -706,6 +947,18 @@ } static int +CursorFreeHideCount (pointer data, XID id) +{ + CursorHideCountPtr pChc = (CursorHideCountPtr) data; + ScreenPtr pScreen = pChc->pScreen; + + deleteCursorHideCount(pChc, pChc->pScreen); + (void) CursorDisplayCursor(pScreen, CursorCurrent); + + return 1; +} + +static int CursorFreeWindow (pointer data, XID id) { WindowPtr pWindow = (WindowPtr) data; @@ -722,6 +975,36 @@ return 1; } +static CursorPtr +createInvisibleCursor (void) +{ + CursorPtr pCursor; + static unsigned int *psrcbits, *pmaskbits; + CursorMetricRec cm; + + psrcbits = (unsigned int *) xalloc(4); + pmaskbits = (unsigned int *) xalloc(4); + if (psrcbits == NULL || pmaskbits == NULL) { + return NULL; + } + *psrcbits = 0; + *pmaskbits = 0; + + cm.width = 1; + cm.height = 1; + cm.xhot = 0; + cm.yhot = 0; + + pCursor = AllocCursor( + (unsigned char *)psrcbits, + (unsigned char *)pmaskbits, + &cm, + 0, 0, 0, + 0, 0, 0); + + return pCursor; +} + Bool XFixesCursorInit (void) { @@ -744,10 +1027,20 @@ return FALSE; Wrap (cs, pScreen, CloseScreen, CursorCloseScreen); Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor); + cs->pCursorHideCounts = NULL; SetCursorScreen (pScreen, cs); } CursorClientType = CreateNewResourceType(CursorFreeClient); + CursorHideCountType = CreateNewResourceType(CursorFreeHideCount); CursorWindowType = CreateNewResourceType(CursorFreeWindow); + + if (pInvisibleCursor == NULL) { + pInvisibleCursor = createInvisibleCursor(); + if (pInvisibleCursor == NULL) { + return BadAlloc; + } + } + return CursorClientType && CursorWindowType; } Index: xorg/xfixes/xfixes.c =================================================================== RCS file: /cvs/xorg/xserver/xorg/xfixes/xfixes.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -b -B -r1.7 -r1.8 --- xorg/xfixes/xfixes.c 3 Jul 2005 07:37:35 -0000 1.7 +++ xorg/xfixes/xfixes.c 13 Mar 2006 21:59:55 -0000 1.8 @@ -1,5 +1,25 @@ /* - * $Id: xfixes.c,v 1.6 2005/07/03 07:02:08 daniels Exp $ + * $Id: xfixes.c,v 1.7 2005/07/03 07:37:35 daniels Exp $ + * + * Copyright © 2006 Sun Microsystems + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sun Microsystems not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * * Copyright © 2002 Keith Packard * @@ -74,6 +94,7 @@ X_XFixesGetCursorImage, /* Version 1 */ X_XFixesChangeCursorByName, /* Version 2 */ X_XFixesExpandRegion, /* Version 3 */ + X_XFixesShowCursor, /* Version 4 */ }; #define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0])) @@ -111,6 +132,9 @@ ProcXFixesChangeCursorByName, /*************** Version 3 ******************/ ProcXFixesExpandRegion, +/*************** Version 4 ****************/ + ProcXFixesHideCursor, + ProcXFixesShowCursor, }; static int @@ -171,6 +195,9 @@ SProcXFixesChangeCursorByName, /*************** Version 3 ******************/ SProcXFixesExpandRegion, +/*************** Version 4 ****************/ + SProcXFixesHideCursor, + SProcXFixesShowCursor, }; static int Index: xorg/xfixes/xfixesint.h =================================================================== RCS file: /cvs/xorg/xserver/xorg/xfixes/xfixesint.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -b -B -r1.7 -r1.8 --- xorg/xfixes/xfixesint.h 3 Jul 2005 08:53:54 -0000 1.7 +++ xorg/xfixes/xfixesint.h 13 Mar 2006 21:59:55 -0000 1.8 @@ -1,5 +1,25 @@ /* - * $Id: xfixesint.h,v 1.6 2005/07/03 07:02:08 daniels Exp $ + * $Id: xfixesint.h,v 1.7 2005/07/03 08:53:54 daniels Exp $ + * + * Copyright © 2006 Sun Microsystems + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Sun Microsystems not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * * Copyright © 2002 Keith Packard * @@ -240,4 +260,18 @@ int SProcXFixesExpandRegion (ClientPtr client); +/* Cursor Visibility (Version 4) */ + +int +ProcXFixesHideCursor (ClientPtr client); + +int +SProcXFixesHideCursor (ClientPtr client); + +int +ProcXFixesShowCursor (ClientPtr client); + +int +SProcXFixesShowCursor (ClientPtr client); + #endif /* _XFIXESINT_H_ */