Part 3 of 3 (Other parts are in proto and lib) Composite Version 0.3:

CompositeGetOverlayWindow, CompositeReleaseOverlayWindow Xfixes Version
    4.0: XFixesHideCursor, XFixesShowCursor
This commit is contained in:
Deron Johnson 2006-03-13 21:59:55 +00:00
parent e5956f49b2
commit 450018f48b
8 changed files with 819 additions and 3 deletions

View File

@ -1,6 +1,26 @@
/*
* $Id$
*
* 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 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
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

View File

@ -1,6 +1,27 @@
/*
* $Id$
*
*
* 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
@ -32,6 +53,10 @@ static CARD8 CompositeReqCode;
int CompositeClientPrivateIndex;
RESTYPE CompositeClientWindowType;
RESTYPE CompositeClientSubwindowsType;
RESTYPE CompositeClientOverlayType;
static void deleteCompOverlayClient (CompOverlayClientPtr pOcToDel,
ScreenPtr pScreen);
typedef struct _CompositeClient {
int major_version;
@ -76,6 +101,26 @@ FreeCompositeClientSubwindows (pointer value, XID ccwid)
return Success;
}
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)
{
@ -243,6 +288,229 @@ ProcCompositeNameWindowPixmap (ClientPtr client)
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 @@ int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
ProcCompositeUnredirectSubwindows,
ProcCompositeCreateRegionFromBorderClip,
ProcCompositeNameWindowPixmap,
ProcCompositeGetOverlayWindow,
ProcCompositeReleaseOverlayWindow,
};
static int
@ -351,6 +621,30 @@ SProcCompositeNameWindowPixmap (ClientPtr client)
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 @@ int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
SProcCompositeUnredirectSubwindows,
SProcCompositeCreateRegionFromBorderClip,
SProcCompositeNameWindowPixmap,
SProcCompositeGetOverlayWindow,
SProcCompositeReleaseOverlayWindow,
};
static int
@ -386,6 +682,10 @@ CompositeExtensionInit (void)
if (!CompositeClientSubwindowsType)
return;
CompositeClientOverlayType = CreateNewResourceType (FreeCompositeClientOverlay);
if (!CompositeClientOverlayType)
return;
CompositeClientPrivateIndex = AllocateClientPrivateIndex ();
if (!AllocateClientPrivate (CompositeClientPrivateIndex,
sizeof (CompositeClientRec)))
@ -400,7 +700,6 @@ CompositeExtensionInit (void)
return;
CompositeReqCode = (CARD8) extEntry->base;
for (s = 0; s < screenInfo.numScreens; s++)
if (!compScreenInit (screenInfo.screens[s]))
return;

View File

@ -1,6 +1,26 @@
/*
* $Id$
*
* 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
@ -33,6 +53,7 @@ int CompWindowPrivateIndex;
int CompSubwindowsPrivateIndex;
int CompGeneration;
static Bool
compCloseScreen (int index, ScreenPtr pScreen)
{
@ -55,6 +76,15 @@ compCloseScreen (int index, ScreenPtr pScreen)
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 @@ compScreenInit (ScreenPtr pScreen)
return FALSE;
cs->damaged = FALSE;
cs->pOverlayWin = NULL;
cs->pOverlayClients = NULL;
if (!compAddAlternateVisuals (pScreen, cs))
{
@ -386,5 +418,6 @@ compScreenInit (ScreenPtr pScreen)
pScreen->CloseScreen = compCloseScreen;
pScreen->devPrivates[CompScreenPrivateIndex].ptr = (pointer) cs;
return TRUE;
}

View File

@ -1,6 +1,26 @@
/*
* $Id$
*
* 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 @@ typedef struct _CompSubwindows {
#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 @@ typedef struct _CompScreen {
CloseScreenProcPtr CloseScreen;
Bool damaged;
XID alternateVisuals[NUM_COMP_ALTERNATE_VISUALS];
WindowPtr pOverlayWin;
CompOverlayClientPtr pOverlayClients;
} CompScreenRec, *CompScreenPtr;
extern int CompScreenPrivateIndex;
@ -257,4 +290,25 @@ compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
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_ */

View File

@ -1,6 +1,26 @@
/*
* $Id$
*
* 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
@ -753,3 +773,34 @@ compWindowUpdate (WindowPtr pWin)
}
}
}
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;
}
}

View File

@ -1,6 +1,26 @@
/*
* $Id$
*
* 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), \
@ -65,6 +89,22 @@ typedef struct _CursorEvent {
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
*/
@ -72,6 +112,7 @@ static CursorEventPtr cursorEvents;
typedef struct _CursorScreen {
DisplayCursorProcPtr DisplayCursor;
CloseScreenProcPtr CloseScreen;
CursorHideCountPtr pCursorHideCounts;
} CursorScreenRec, *CursorScreenPtr;
#define GetCursorScreen(s) ((CursorScreenPtr) ((s)->devPrivates[CursorScreenPrivateIndex].ptr))
@ -88,7 +129,13 @@ CursorDisplayCursor (ScreenPtr pScreen,
Bool ret;
Unwrap (cs, pScreen, DisplayCursor);
ret = (*pScreen->DisplayCursor) (pScreen, pCursor);
if (cs->pCursorHideCounts != NULL) {
ret = (*pScreen->DisplayCursor) (pScreen, pInvisibleCursor);
} else {
ret = (*pScreen->DisplayCursor) (pScreen, pCursor);
}
if (pCursor != CursorCurrent)
{
CursorEventPtr e;
@ -122,6 +169,7 @@ CursorCloseScreen (int index, ScreenPtr pScreen)
Unwrap (cs, pScreen, CloseScreen);
Unwrap (cs, pScreen, DisplayCursor);
deleteCursorHideCountsForScreen(pScreen);
ret = (*pScreen->CloseScreen) (index, pScreen);
xfree (cs);
if (index == 0)
@ -430,7 +478,7 @@ int
SProcXFixesGetCursorName (ClientPtr client)
{
int n;
REQUEST(xXFixesSetCursorNameReq);
REQUEST(xXFixesGetCursorNameReq);
swaps (&stuff->length, n);
REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
@ -687,6 +735,199 @@ SProcXFixesChangeCursorByName (ClientPtr client)
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)
{
@ -705,6 +946,18 @@ CursorFreeClient (pointer data, XID id)
return 1;
}
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)
{
@ -722,6 +975,36 @@ CursorFreeWindow (pointer data, XID id)
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 @@ XFixesCursorInit (void)
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;
}

View File

@ -1,6 +1,26 @@
/*
* $Id$
*
* 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
@ -74,6 +94,7 @@ static const int version_requests[] = {
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 @@ int (*ProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
ProcXFixesChangeCursorByName,
/*************** Version 3 ******************/
ProcXFixesExpandRegion,
/*************** Version 4 ****************/
ProcXFixesHideCursor,
ProcXFixesShowCursor,
};
static int
@ -171,6 +195,9 @@ int (*SProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
SProcXFixesChangeCursorByName,
/*************** Version 3 ******************/
SProcXFixesExpandRegion,
/*************** Version 4 ****************/
SProcXFixesHideCursor,
SProcXFixesShowCursor,
};
static int

View File

@ -1,6 +1,26 @@
/*
* $Id$
*
* 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
@ -240,4 +260,18 @@ ProcXFixesExpandRegion (ClientPtr client);
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_ */