From 5cfbe97cd797d8f78ece208bb5114704b83d8aab Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 13 Jan 2012 16:54:57 +0100 Subject: libxtrans libXdmcp libxcb mesa xserver git update 13 jan 2012 --- xorg-server/Xext/xf86bigfont.c | 4 +- xorg-server/dix/dispatch.c | 12 +- xorg-server/dix/events.c | 5 +- xorg-server/hw/kdrive/ephyr/ephyrdriext.c | 4 +- xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c | 2 +- xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c | 6 +- xorg-server/hw/xfree86/dri/xf86dri.c | 4 +- xorg-server/hw/xfree86/dri2/dri2ext.c | 2 +- xorg-server/hw/xfree86/man/xorg.conf.man | 8 +- xorg-server/hw/xquartz/applewm.c | 4 +- xorg-server/hw/xquartz/xpr/appledri.c | 4 +- xorg-server/hw/xwin/winwindowswm.c | 4 +- xorg-server/include/dixstruct.h | 30 +- xorg-server/include/misc.h | 3 +- xorg-server/include/os.h | 2 + xorg-server/include/windowstr.h | 4 +- xorg-server/os/access.c | 9 +- xorg-server/os/backtrace.c | 8 +- xorg-server/os/connection.c | 14 +- xorg-server/os/io.c | 19 +- xorg-server/os/osdep.h | 19 +- xorg-server/render/animcur.c | 837 +++++++++++----------- 22 files changed, 507 insertions(+), 497 deletions(-) (limited to 'xorg-server') diff --git a/xorg-server/Xext/xf86bigfont.c b/xorg-server/Xext/xf86bigfont.c index 5053852a4..4b63a13a1 100644 --- a/xorg-server/Xext/xf86bigfont.c +++ b/xorg-server/Xext/xf86bigfont.c @@ -300,7 +300,7 @@ ProcXF86BigfontQueryVersion( #endif reply.capabilities = #ifdef HAS_SHM - (client->local && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0) + (LocalClient(client) && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0) #else 0 #endif @@ -367,7 +367,7 @@ ProcXF86BigfontQueryFont( #else switch (client->req_len) { case 2: /* client with version 1.0 libX11 */ - stuff_flags = (client->local && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0); + stuff_flags = (LocalClient(client) && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0); break; case 3: /* client with version 1.1 libX11 */ stuff_flags = stuff->flags; diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index b91b41f4a..44c24337a 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -3582,14 +3582,12 @@ ProcInitialConnection(ClientPtr client) REQUEST(xReq); xConnClientPrefix *prefix; int whichbyte = 1; - char order; prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); - order = prefix->byteOrder; - if (order != 'l' && order != 'B' && order != 'r' && order != 'R') + if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) return client->noClientException = -1; - if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || - (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) + if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || + (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) { client->swapped = TRUE; SwapConnClientPrefix(prefix); @@ -3601,10 +3599,6 @@ ProcInitialConnection(ClientPtr client) { swaps(&stuff->length); } - if (order == 'r' || order == 'R') - { - client->local = FALSE; - } ResetCurrentRequest(client); return Success; } diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index 536026716..04d7fb59b 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -1368,7 +1368,7 @@ ScreenRestructured (ScreenPtr pScreen) for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if (!DevHasCursor(pDev)) + if (!IsFloating(pDev) && !DevHasCursor(pDev)) continue; /* GrabDevice doesn't have a confineTo field, so we don't need to @@ -3723,7 +3723,8 @@ ActivatePassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event, } } - (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); + (*grabinfo->ActivateGrab)(device, grab, + ClientTimeToServerTime(event->any.time), TRUE); if (xE) { diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c index 85e38e058..0741a7294 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c @@ -586,7 +586,7 @@ ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client) } rep.isCapable = isCapable; - if (!client->local || client->swapped) + if (!LocalClient(client) || client->swapped) rep.isCapable = 0; if (client->swapped) { @@ -1253,7 +1253,7 @@ ProcXF86DRIDispatch (register ClientPtr client) } } - if (!client->local) + if (!LocalClient(client)) return DRIErrorBase + XF86DRIClientNotLocal; switch (stuff->data) diff --git a/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c b/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c index 4b17f152e..4bcf77efd 100644 --- a/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c +++ b/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c @@ -928,7 +928,7 @@ ProcXDGADispatch (ClientPtr client) { REQUEST(xReq); - if (!client->local) + if (!LocalClient(client)) return DGAErrorBase + XF86DGAClientNotLocal; #ifdef DGA_REQ_DEBUG diff --git a/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c b/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c index 6e5e3f94c..6d3d5fcbc 100644 --- a/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c +++ b/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c @@ -1527,7 +1527,7 @@ ProcXF86VidModeGetPermissions(ClientPtr client) rep.sequenceNumber = client->sequence; rep.permissions = XF86VM_READ_PERMISSION; if (xf86GetVidModeEnabled() && - (xf86GetVidModeAllowNonLocal() || client->local)) { + (xf86GetVidModeAllowNonLocal() || LocalClient (client))) { rep.permissions |= XF86VM_WRITE_PERMISSION; } if(client->swapped) { @@ -1597,7 +1597,7 @@ ProcXF86VidModeDispatch(ClientPtr client) default: if (!xf86GetVidModeEnabled()) return VidModeErrorBase + XF86VidModeExtensionDisabled; - if (xf86GetVidModeAllowNonLocal() || client->local) { + if (xf86GetVidModeAllowNonLocal() || LocalClient (client)) { switch (stuff->data) { case X_XF86VidModeAddModeLine: return ProcXF86VidModeAddModeLine(client); @@ -2017,7 +2017,7 @@ SProcXF86VidModeDispatch(ClientPtr client) default: if (!xf86GetVidModeEnabled()) return VidModeErrorBase + XF86VidModeExtensionDisabled; - if (xf86GetVidModeAllowNonLocal() || client->local) { + if (xf86GetVidModeAllowNonLocal() || LocalClient(client)) { switch (stuff->data) { case X_XF86VidModeAddModeLine: return SProcXF86VidModeAddModeLine(client); diff --git a/xorg-server/hw/xfree86/dri/xf86dri.c b/xorg-server/hw/xfree86/dri/xf86dri.c index 723e52622..c35ba2f94 100644 --- a/xorg-server/hw/xfree86/dri/xf86dri.c +++ b/xorg-server/hw/xfree86/dri/xf86dri.c @@ -130,7 +130,7 @@ ProcXF86DRIQueryDirectRenderingCapable( } rep.isCapable = isCapable; - if (!client->local || client->swapped) + if (!LocalClient(client) || client->swapped) rep.isCapable = 0; if (client->swapped) { @@ -557,7 +557,7 @@ ProcXF86DRIDispatch ( return ProcXF86DRIQueryDirectRenderingCapable(client); } - if (!client->local) + if (!LocalClient(client)) return DRIErrorBase + XF86DRIClientNotLocal; switch (stuff->data) diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c index 21331559f..73ef7f25e 100644 --- a/xorg-server/hw/xfree86/dri2/dri2ext.c +++ b/xorg-server/hw/xfree86/dri2/dri2ext.c @@ -547,7 +547,7 @@ ProcDRI2Dispatch (ClientPtr client) return ProcDRI2QueryVersion(client); } - if (!client->local) + if (!LocalClient(client)) return BadRequest; switch (stuff->data) { diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man index 57901853b..c1b3c4f2d 100644 --- a/xorg-server/hw/xfree86/man/xorg.conf.man +++ b/xorg-server/hw/xfree86/man/xorg.conf.man @@ -659,8 +659,8 @@ Allow modules built for a different, potentially incompatible version of the X server to load. Disabled by default. .TP 7 .BI "Option \*qAutoAddDevices\*q \*q" boolean \*q -If this option is disabled, then no devices will be added from HAL events. -Enabled by default. +If this option is disabled, then no devices will be added from the HAL or +udev backends. Enabled by default. .TP 7 .BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q If this option is disabled, then the devices will be added (and the @@ -802,8 +802,8 @@ Recent X servers employ HAL or udev backends for input device enumeration and input hotplugging. It is usually not necessary to provide .B InputDevice -sections in the xorg.conf if hotplugging is in use. If hotplugging is -enabled, +sections in the xorg.conf if hotplugging is in use (i.e. AutoAddDevices is +enabled). If hotplugging is enabled, .B InputDevice sections using the .B mouse, kbd diff --git a/xorg-server/hw/xquartz/applewm.c b/xorg-server/hw/xquartz/applewm.c index 7077a6c6a..55976c454 100644 --- a/xorg-server/hw/xquartz/applewm.c +++ b/xorg-server/hw/xquartz/applewm.c @@ -630,7 +630,7 @@ ProcAppleWMDispatch ( return ProcAppleWMQueryVersion(client); } - if (!client->local) + if (!LocalClient(client)) return WMErrorBase + AppleWMClientNotLocal; switch (stuff->data) @@ -693,7 +693,7 @@ SProcAppleWMDispatch ( REQUEST(xReq); /* It is bound to be non-local when there is byte swapping */ - if (!client->local) + if (!LocalClient(client)) return WMErrorBase + AppleWMClientNotLocal; /* only local clients are allowed WM access */ diff --git a/xorg-server/hw/xquartz/xpr/appledri.c b/xorg-server/hw/xquartz/xpr/appledri.c index 091145be3..44c132abc 100644 --- a/xorg-server/hw/xquartz/xpr/appledri.c +++ b/xorg-server/hw/xquartz/xpr/appledri.c @@ -133,7 +133,7 @@ ProcAppleDRIQueryDirectRenderingCapable( } rep.isCapable = isCapable; - if (!client->local) + if (!LocalClient(client)) rep.isCapable = 0; if (client->swapped) { @@ -365,7 +365,7 @@ ProcAppleDRIDispatch ( return ProcAppleDRIQueryDirectRenderingCapable(client); } - if (!client->local) + if (!LocalClient(client)) return DRIErrorBase + AppleDRIClientNotLocal; switch (stuff->data) diff --git a/xorg-server/hw/xwin/winwindowswm.c b/xorg-server/hw/xwin/winwindowswm.c index f43834d5e..577614db6 100644 --- a/xorg-server/hw/xwin/winwindowswm.c +++ b/xorg-server/hw/xwin/winwindowswm.c @@ -548,7 +548,7 @@ ProcWindowsWMDispatch (ClientPtr client) return ProcWindowsWMQueryVersion(client); } - if (!client->local) + if (!LocalClient(client)) return WMErrorBase + WindowsWMClientNotLocal; switch (stuff->data) @@ -598,7 +598,7 @@ SProcWindowsWMDispatch (ClientPtr client) REQUEST(xReq); /* It is bound to be non-local when there is byte swapping */ - if (!client->local) + if (!LocalClient(client)) return WMErrorBase + WindowsWMClientNotLocal; /* only local clients are allowed WM access */ diff --git a/xorg-server/include/dixstruct.h b/xorg-server/include/dixstruct.h index cb370519e..0a85f40b6 100644 --- a/xorg-server/include/dixstruct.h +++ b/xorg-server/include/dixstruct.h @@ -90,23 +90,23 @@ typedef struct _Client { Mask clientAsMask; pointer requestBuffer; pointer osPrivate; /* for OS layer, including scheduler */ - char swapped; - char local; - char big_requests; - char closeDownMode; - char clientGone; - char noClientException; /* this client died or needs to be - * killed */ - char clientState; + Bool swapped; ReplySwapPtr pSwapReplyFunc; XID errorValue; int sequence; + int closeDownMode; + int clientGone; + int noClientException; /* this client died or needs to be + * killed */ int ignoreCount; /* count for Attend/IgnoreClient */ - int numSaved; SaveSetElt *saveSet; - int (**requestVector) (ClientPtr /* pClient */); + int numSaved; + int (**requestVector) ( + ClientPtr /* pClient */); CARD32 req_len; /* length of current request */ + Bool big_requests; /* supports large requests */ int priority; + ClientState clientState; PrivateRec *devPrivates; unsigned short xkbClientFlags; unsigned short mapNotifyMask; @@ -114,16 +114,16 @@ typedef struct _Client { unsigned short vMajor,vMinor; KeyCode minKC,maxKC; - unsigned int replyBytesRemaining; + unsigned long replyBytesRemaining; int smart_priority; - int smart_start_tick; - int smart_stop_tick; - int smart_check_tick; + long smart_start_tick; + long smart_stop_tick; + long smart_check_tick; DeviceIntPtr clientPtr; ClientIdPtr clientIds; unsigned short majorOp, minorOp; -} ClientRec; +} ClientRec; /* * Scheduling interface diff --git a/xorg-server/include/misc.h b/xorg-server/include/misc.h index 3d08511ec..3f57f4b1a 100644 --- a/xorg-server/include/misc.h +++ b/xorg-server/include/misc.h @@ -364,7 +364,8 @@ extern _X_EXPORT unsigned long serverGeneration; /* Don't use this directly, use BUG_WARN or BUG_WARN_MSG instead */ #define __BUG_WARN_MSG(cond, with_msg, ...) \ do { if (cond) { \ - ErrorF("BUG: triggered 'if (" #cond ")'\nBUG: %s:%d in %s()\n", \ + ErrorF("BUG: triggered 'if (" #cond ")'\n"); \ + ErrorF("BUG: %s:%d in %s()\n", \ __FILE__, __LINE__, __func__); \ if (with_msg) ErrorF(__VA_ARGS__); \ xorg_backtrace(); \ diff --git a/xorg-server/include/os.h b/xorg-server/include/os.h index 84dedd5cb..48ce32962 100644 --- a/xorg-server/include/os.h +++ b/xorg-server/include/os.h @@ -353,6 +353,8 @@ typedef struct sockaddr * sockaddrPtr; extern _X_EXPORT int InvalidHost(sockaddrPtr /*saddr*/, int /*len*/, ClientPtr client); +extern _X_EXPORT int LocalClient(ClientPtr /* client */); + extern _X_EXPORT int LocalClientCred(ClientPtr, int *, int *); #define LCC_UID_SET (1 << 0) diff --git a/xorg-server/include/windowstr.h b/xorg-server/include/windowstr.h index 1124dfc4c..222de31dc 100644 --- a/xorg-server/include/windowstr.h +++ b/xorg-server/include/windowstr.h @@ -87,8 +87,8 @@ typedef struct _WindowOpt { struct _OtherClients *otherClients; /* default: NULL */ struct _GrabRec *passiveGrabs; /* default: NULL */ PropertyPtr userProps; /* default: NULL */ - CARD32 backingBitPlanes; /* default: ~0L */ - CARD32 backingPixel; /* default: 0 */ + unsigned long backingBitPlanes; /* default: ~0L */ + unsigned long backingPixel; /* default: 0 */ RegionPtr boundingShape; /* default: NULL */ RegionPtr clipShape; /* default: NULL */ RegionPtr inputShape; /* default: NULL */ diff --git a/xorg-server/os/access.c b/xorg-server/os/access.c index ed13d0a0d..b609442de 100644 --- a/xorg-server/os/access.c +++ b/xorg-server/os/access.c @@ -1045,6 +1045,13 @@ ComputeLocalClient(ClientPtr client) return FALSE; } +Bool LocalClient(ClientPtr client) +{ + if (!client->osPrivate) + return FALSE; + return ((OsCommPtr)client->osPrivate)->local_client; +} + /* * Return the uid and gid of a connected local client * @@ -1202,7 +1209,7 @@ AuthorizedClient(ClientPtr client) if (rc != Success) return rc; - return client->local ? Success : BadAccess; + return LocalClient(client) ? Success : BadAccess; } /* Add a host to the access control list. This is the external interface diff --git a/xorg-server/os/backtrace.c b/xorg-server/os/backtrace.c index 298bf1898..edaeb17c7 100644 --- a/xorg-server/os/backtrace.c +++ b/xorg-server/os/backtrace.c @@ -43,7 +43,8 @@ void xorg_backtrace(void) const char *mod; int size, i; Dl_info info; - ErrorF("\nBacktrace:\n"); + ErrorF("\n"); + ErrorF("Backtrace:\n"); size = backtrace(array, 64); for (i = 0; i < size; i++) { int rc = dladdr(array[i], &info); @@ -59,6 +60,7 @@ void xorg_backtrace(void) ErrorF("%d: %s (%p+0x%lx) [%p]\n", i, mod, info.dli_fbase, (long unsigned int)((char *) array[i] - (char *) info.dli_fbase), array[i]); } + ErrorF("\n"); } #else /* not glibc or glibc < 2.1 */ @@ -188,7 +190,8 @@ static int xorg_backtrace_pstack(void) { void xorg_backtrace(void) { - ErrorF("\nBacktrace:\n"); + ErrorF("\n"); + ErrorF("Backtrace:\n"); # ifdef HAVE_PSTACK /* First try fork/exec of pstack - otherwise fall back to walkcontext @@ -207,6 +210,7 @@ void xorg_backtrace(void) { # endif ErrorF("Failed to get backtrace info: %s\n", strerror(errno)); } + ErrorF("\n"); } # else diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c index 2c90d72a9..0e557a544 100644 --- a/xorg-server/os/connection.c +++ b/xorg-server/os/connection.c @@ -745,7 +745,7 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) free(oc); return NullClient; } - client->local = ComputeLocalClient(client); + oc->local_client = ComputeLocalClient(client); #if !defined(WIN32) ConnectionTranslation[fd] = client->index; #else @@ -882,7 +882,7 @@ ErrorConnMax(XtransConnInfo trans_conn) xConnSetupPrefix csp; char pad[3]; struct iovec iov[3]; - char order = 0; + char byteOrder = 0; int whichbyte = 1; struct timeval waittime; fd_set mask; @@ -895,16 +895,16 @@ ErrorConnMax(XtransConnInfo trans_conn) FD_SET(fd, &mask); (void)Select(fd + 1, &mask, NULL, NULL, &waittime); /* try to read the byte-order of the connection */ - (void)_XSERVTransRead(trans_conn, &order, 1); - if (order == 'l' || order == 'B' || order == 'r' || order == 'R') + (void)_XSERVTransRead(trans_conn, &byteOrder, 1); + if ((byteOrder == 'l') || (byteOrder == 'B')) { csp.success = xFalse; csp.lengthReason = sizeof(NOROOM) - 1; csp.length = (sizeof(NOROOM) + 2) >> 2; csp.majorVersion = X_PROTOCOL; csp.minorVersion = X_PROTOCOL_REVISION; - if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || - (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) + if (((*(char *) &whichbyte) && (byteOrder == 'B')) || + (!(*(char *) &whichbyte) && (byteOrder == 'l'))) { swaps(&csp.majorVersion); swaps(&csp.minorVersion); @@ -1032,7 +1032,7 @@ CloseDownConnection(ClientPtr client) if (FlushCallback) CallCallbacks(&FlushCallback, NULL); - if (oc->output) + if (oc->output && oc->output->count) FlushClient(client, oc, (char *)NULL, 0); #ifdef XDMCP XdmcpCloseDisplay(oc->fd); diff --git a/xorg-server/os/io.c b/xorg-server/os/io.c index 78b7260c7..f5013d774 100644 --- a/xorg-server/os/io.c +++ b/xorg-server/os/io.c @@ -84,23 +84,6 @@ SOFTWARE. CallbackListPtr ReplyCallback; CallbackListPtr FlushCallback; -typedef struct _connectionInput { - struct _connectionInput *next; - char *buffer; /* contains current client input */ - char *bufptr; /* pointer to current start of data */ - int bufcnt; /* count of bytes in buffer */ - int lenLastReq; - int size; - unsigned int ignoreBytes; /* bytes to ignore before the next request */ -} ConnectionInput, *ConnectionInputPtr; - -typedef struct _connectionOutput { - struct _connectionOutput *next; - unsigned char *buf; - int size; - int count; -} ConnectionOutput, *ConnectionOutputPtr; - static ConnectionInputPtr AllocateInputBuffer(void); static ConnectionOutputPtr AllocateOutputBuffer(void); @@ -908,7 +891,7 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) long notWritten; long todo; - if (!oco || !oco->count) + if (!oco) return 0; written = 0; padsize = padlength[extraCount & 3]; diff --git a/xorg-server/os/osdep.h b/xorg-server/os/osdep.h index c9add48ee..70e2a0726 100644 --- a/xorg-server/os/osdep.h +++ b/xorg-server/os/osdep.h @@ -108,8 +108,22 @@ typedef Bool (*AddAuthorFunc)(unsigned name_length, const char *name, unsigned data_length, char *data); #endif -typedef struct _connectionInput *ConnectionInputPtr; -typedef struct _connectionOutput *ConnectionOutputPtr; +typedef struct _connectionInput { + struct _connectionInput *next; + char *buffer; /* contains current client input */ + char *bufptr; /* pointer to current start of data */ + int bufcnt; /* count of bytes in buffer */ + int lenLastReq; + int size; + unsigned int ignoreBytes; /* bytes to ignore before the next request */ +} ConnectionInput, *ConnectionInputPtr; + +typedef struct _connectionOutput { + struct _connectionOutput *next; + int size; + unsigned char *buf; + int count; +} ConnectionOutput, *ConnectionOutputPtr; struct _osComm; @@ -148,6 +162,7 @@ typedef struct _osComm { XID auth_id; /* authorization id */ CARD32 conn_time; /* timestamp if not established, else 0 */ struct _XtransConnInfo *trans_conn; /* transport connection object */ + Bool local_client; } OsCommRec, *OsCommPtr; extern int FlushClient( diff --git a/xorg-server/render/animcur.c b/xorg-server/render/animcur.c index fddd9f81b..8d4a9c2ef 100644 --- a/xorg-server/render/animcur.c +++ b/xorg-server/render/animcur.c @@ -1,417 +1,420 @@ -/* - * - * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - */ - -/* - * Animated cursors for X. Not specific to Render in any way, but - * stuck there because Render has the other cool cursor extension. - * Besides, everyone has Render. - * - * Implemented as a simple layer over the core cursor code; it - * creates composite cursors out of a set of static cursors and - * delta times between each image. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include "servermd.h" -#include "scrnintstr.h" -#include "dixstruct.h" -#include "cursorstr.h" -#include "dixfontstr.h" -#include "opaque.h" -#include "picturestr.h" -#include "inputstr.h" -#include "xace.h" - -typedef struct _AnimCurElt { - CursorPtr pCursor; /* cursor to show */ - CARD32 delay; /* in ms */ -} AnimCurElt; - -typedef struct _AnimCur { - int nelt; /* number of elements in the elts array */ - AnimCurElt *elts; /* actually allocated right after the structure */ -} AnimCurRec, *AnimCurPtr; - -typedef struct _AnimScrPriv { - CloseScreenProcPtr CloseScreen; - - ScreenBlockHandlerProcPtr BlockHandler; - - CursorLimitsProcPtr CursorLimits; - DisplayCursorProcPtr DisplayCursor; - SetCursorPositionProcPtr SetCursorPosition; - RealizeCursorProcPtr RealizeCursor; - UnrealizeCursorProcPtr UnrealizeCursor; - RecolorCursorProcPtr RecolorCursor; -} AnimCurScreenRec, *AnimCurScreenPtr; - -static unsigned char empty[4]; - -static CursorBits animCursorBits = { - empty, empty, 2, 1, 1, 0, 0, 1 -}; - -static DevPrivateKeyRec AnimCurScreenPrivateKeyRec; -#define AnimCurScreenPrivateKey (&AnimCurScreenPrivateKeyRec) - -#define IsAnimCur(c) ((c) && ((c)->bits == &animCursorBits)) -#define GetAnimCur(c) ((AnimCurPtr) ((((char *)(c) + CURSOR_REC_SIZE)))) -#define GetAnimCurScreen(s) ((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey)) -#define SetAnimCurScreen(s,p) dixSetPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey, p) - -#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) -#define Unwrap(as,s,elt) ((s)->elt = (as)->elt) - - -static Bool -AnimCurCloseScreen (int index, ScreenPtr pScreen) -{ - AnimCurScreenPtr as = GetAnimCurScreen(pScreen); - Bool ret; - - Unwrap(as, pScreen, CloseScreen); - - Unwrap(as, pScreen, CursorLimits); - Unwrap(as, pScreen, DisplayCursor); - Unwrap(as, pScreen, SetCursorPosition); - Unwrap(as, pScreen, RealizeCursor); - Unwrap(as, pScreen, UnrealizeCursor); - Unwrap(as, pScreen, RecolorCursor); - SetAnimCurScreen(pScreen,0); - ret = (*pScreen->CloseScreen) (index, pScreen); - free(as); - return ret; -} - -static void -AnimCurCursorLimits (DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor, - BoxPtr pHotBox, - BoxPtr pTopLeftBox) -{ - AnimCurScreenPtr as = GetAnimCurScreen(pScreen); - - Unwrap (as, pScreen, CursorLimits); - if (IsAnimCur(pCursor)) - { - AnimCurPtr ac = GetAnimCur(pCursor); - - (*pScreen->CursorLimits) (pDev, pScreen, ac->elts[0].pCursor, - pHotBox, pTopLeftBox); - } - else - { - (*pScreen->CursorLimits) (pDev, pScreen, pCursor, - pHotBox, pTopLeftBox); - } - Wrap (as, pScreen, CursorLimits, AnimCurCursorLimits); -} - -/* - * This has to be a screen block handler instead of a generic - * block handler so that it is well ordered with respect to the DRI - * block handler responsible for releasing the hardware to DRI clients - */ - -static void -AnimCurScreenBlockHandler (int screenNum, - pointer blockData, - pointer pTimeout, - pointer pReadmask) -{ - ScreenPtr pScreen = screenInfo.screens[screenNum]; - AnimCurScreenPtr as = GetAnimCurScreen(pScreen); - DeviceIntPtr dev; - Bool activeDevice = FALSE; - CARD32 now = 0, - soonest = ~0; /* earliest time to wakeup again */ - - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) - { - if (!activeDevice) { - now = GetTimeInMillis (); - activeDevice = TRUE; - } - - if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) - { - AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor); - int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt; - DisplayCursorProcPtr DisplayCursor; - - /* - * Not a simple Unwrap/Wrap as this - * isn't called along the DisplayCursor - * wrapper chain. - */ - DisplayCursor = pScreen->DisplayCursor; - pScreen->DisplayCursor = as->DisplayCursor; - (void) (*pScreen->DisplayCursor) (dev, - pScreen, - ac->elts[elt].pCursor); - as->DisplayCursor = pScreen->DisplayCursor; - pScreen->DisplayCursor = DisplayCursor; - - dev->spriteInfo->anim.elt = elt; - dev->spriteInfo->anim.time = now + ac->elts[elt].delay; - } - - if (soonest > dev->spriteInfo->anim.time) - soonest = dev->spriteInfo->anim.time; - } - } - - if (activeDevice) - AdjustWaitForDelay (pTimeout, soonest - now); - - Unwrap (as, pScreen, BlockHandler); - (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask); - if (activeDevice) - Wrap (as, pScreen, BlockHandler, AnimCurScreenBlockHandler); - else - as->BlockHandler = NULL; -} - -static Bool -AnimCurDisplayCursor (DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor) -{ - AnimCurScreenPtr as = GetAnimCurScreen(pScreen); - Bool ret; - - Unwrap (as, pScreen, DisplayCursor); - if (IsAnimCur(pCursor)) - { - if (pCursor != pDev->spriteInfo->anim.pCursor) - { - AnimCurPtr ac = GetAnimCur(pCursor); - - ret = (*pScreen->DisplayCursor) - (pDev, pScreen, ac->elts[0].pCursor); - if (ret) - { - pDev->spriteInfo->anim.elt = 0; - pDev->spriteInfo->anim.time = GetTimeInMillis () + ac->elts[0].delay; - pDev->spriteInfo->anim.pCursor = pCursor; - pDev->spriteInfo->anim.pScreen = pScreen; - - if (!as->BlockHandler) - Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler); - } - } - else - ret = TRUE; - } - else - { - pDev->spriteInfo->anim.pCursor = 0; - pDev->spriteInfo->anim.pScreen = 0; - ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); - } - Wrap (as, pScreen, DisplayCursor, AnimCurDisplayCursor); - return ret; -} - -static Bool -AnimCurSetCursorPosition (DeviceIntPtr pDev, - ScreenPtr pScreen, - int x, - int y, - Bool generateEvent) -{ - AnimCurScreenPtr as = GetAnimCurScreen(pScreen); - Bool ret; - - Unwrap (as, pScreen, SetCursorPosition); - if (pDev->spriteInfo->anim.pCursor) { - pDev->spriteInfo->anim.pScreen = pScreen; - - if (!as->BlockHandler) - Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler); - } - ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent); - Wrap (as, pScreen, SetCursorPosition, AnimCurSetCursorPosition); - return ret; -} - -static Bool -AnimCurRealizeCursor (DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor) -{ - AnimCurScreenPtr as = GetAnimCurScreen(pScreen); - Bool ret; - - Unwrap (as, pScreen, RealizeCursor); - if (IsAnimCur(pCursor)) - ret = TRUE; - else - ret = (*pScreen->RealizeCursor) (pDev, pScreen, pCursor); - Wrap (as, pScreen, RealizeCursor, AnimCurRealizeCursor); - return ret; -} - -static Bool -AnimCurUnrealizeCursor (DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor) -{ - AnimCurScreenPtr as = GetAnimCurScreen(pScreen); - Bool ret; - - Unwrap (as, pScreen, UnrealizeCursor); - if (IsAnimCur(pCursor)) - { - AnimCurPtr ac = GetAnimCur(pCursor); - int i; - - if (pScreen->myNum == 0) - for (i = 0; i < ac->nelt; i++) - FreeCursor (ac->elts[i].pCursor, 0); - ret = TRUE; - } - else - ret = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor); - Wrap (as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); - return ret; -} - -static void -AnimCurRecolorCursor (DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor, - Bool displayed) -{ - AnimCurScreenPtr as = GetAnimCurScreen(pScreen); - - Unwrap (as, pScreen, RecolorCursor); - if (IsAnimCur(pCursor)) - { - AnimCurPtr ac = GetAnimCur(pCursor); - int i; - - for (i = 0; i < ac->nelt; i++) - (*pScreen->RecolorCursor) (pDev, pScreen, ac->elts[i].pCursor, - displayed && - pDev->spriteInfo->anim.elt == i); - } - else - (*pScreen->RecolorCursor) (pDev, pScreen, pCursor, displayed); - Wrap (as, pScreen, RecolorCursor, AnimCurRecolorCursor); -} - -Bool -AnimCurInit (ScreenPtr pScreen) -{ - AnimCurScreenPtr as; - - if (!dixRegisterPrivateKey(&AnimCurScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - - as = (AnimCurScreenPtr) malloc(sizeof (AnimCurScreenRec)); - if (!as) - return FALSE; - Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen); - - as->BlockHandler = NULL; - - Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits); - Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor); - Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition); - Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor); - Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); - Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor); - SetAnimCurScreen(pScreen,as); - return TRUE; -} - -int -AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor, ClientPtr client, XID cid) -{ - CursorPtr pCursor; - int rc, i; - AnimCurPtr ac; - - for (i = 0; i < screenInfo.numScreens; i++) - if (!GetAnimCurScreen (screenInfo.screens[i])) - return BadImplementation; - - for (i = 0; i < ncursor; i++) - if (IsAnimCur (cursors[i])) - return BadMatch; - - pCursor = (CursorPtr) calloc(CURSOR_REC_SIZE + - sizeof (AnimCurRec) + - ncursor * sizeof (AnimCurElt), 1); - if (!pCursor) - return BadAlloc; - dixInitPrivates(pCursor, pCursor + 1, PRIVATE_CURSOR); - pCursor->bits = &animCursorBits; - pCursor->refcnt = 1; - - pCursor->foreRed = cursors[0]->foreRed; - pCursor->foreGreen = cursors[0]->foreGreen; - pCursor->foreBlue = cursors[0]->foreBlue; - - pCursor->backRed = cursors[0]->backRed; - pCursor->backGreen = cursors[0]->backGreen; - pCursor->backBlue = cursors[0]->backBlue; - - pCursor->id = cid; - - /* security creation/labeling check */ - rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCursor, - RT_NONE, NULL, DixCreateAccess); - if (rc != Success) { - dixFiniPrivates(pCursor, PRIVATE_CURSOR); - free(pCursor); - return rc; - } - - /* - * Fill in the AnimCurRec - */ - animCursorBits.refcnt++; - ac = GetAnimCur (pCursor); - ac->nelt = ncursor; - ac->elts = (AnimCurElt *) (ac + 1); - - for (i = 0; i < ncursor; i++) - { - cursors[i]->refcnt++; - ac->elts[i].pCursor = cursors[i]; - ac->elts[i].delay = deltas[i]; - } - - *ppCursor = pCursor; - return Success; -} +/* + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * 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 Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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. + */ + +/* + * Animated cursors for X. Not specific to Render in any way, but + * stuck there because Render has the other cool cursor extension. + * Besides, everyone has Render. + * + * Implemented as a simple layer over the core cursor code; it + * creates composite cursors out of a set of static cursors and + * delta times between each image. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include "servermd.h" +#include "scrnintstr.h" +#include "dixstruct.h" +#include "cursorstr.h" +#include "dixfontstr.h" +#include "opaque.h" +#include "picturestr.h" +#include "inputstr.h" +#include "xace.h" + +typedef struct _AnimCurElt { + CursorPtr pCursor; /* cursor to show */ + CARD32 delay; /* in ms */ +} AnimCurElt; + +typedef struct _AnimCur { + int nelt; /* number of elements in the elts array */ + AnimCurElt *elts; /* actually allocated right after the structure */ +} AnimCurRec, *AnimCurPtr; + +typedef struct _AnimScrPriv { + CloseScreenProcPtr CloseScreen; + + ScreenBlockHandlerProcPtr BlockHandler; + + CursorLimitsProcPtr CursorLimits; + DisplayCursorProcPtr DisplayCursor; + SetCursorPositionProcPtr SetCursorPosition; + RealizeCursorProcPtr RealizeCursor; + UnrealizeCursorProcPtr UnrealizeCursor; + RecolorCursorProcPtr RecolorCursor; +} AnimCurScreenRec, *AnimCurScreenPtr; + +static unsigned char empty[4]; + +static CursorBits animCursorBits = { + empty, empty, 2, 1, 1, 0, 0, 1 +}; + +static DevPrivateKeyRec AnimCurScreenPrivateKeyRec; +#define AnimCurScreenPrivateKey (&AnimCurScreenPrivateKeyRec) + +#define IsAnimCur(c) ((c) && ((c)->bits == &animCursorBits)) +#define GetAnimCur(c) ((AnimCurPtr) ((((char *)(c) + CURSOR_REC_SIZE)))) +#define GetAnimCurScreen(s) ((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey)) +#define SetAnimCurScreen(s,p) dixSetPrivate(&(s)->devPrivates, AnimCurScreenPrivateKey, p) + +#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) +#define Unwrap(as,s,elt) ((s)->elt = (as)->elt) + + +static Bool +AnimCurCloseScreen (int index, ScreenPtr pScreen) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap(as, pScreen, CloseScreen); + + Unwrap(as, pScreen, CursorLimits); + Unwrap(as, pScreen, DisplayCursor); + Unwrap(as, pScreen, SetCursorPosition); + Unwrap(as, pScreen, RealizeCursor); + Unwrap(as, pScreen, UnrealizeCursor); + Unwrap(as, pScreen, RecolorCursor); + SetAnimCurScreen(pScreen,0); + ret = (*pScreen->CloseScreen) (index, pScreen); + free(as); + return ret; +} + +static void +AnimCurCursorLimits (DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor, + BoxPtr pHotBox, + BoxPtr pTopLeftBox) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + + Unwrap (as, pScreen, CursorLimits); + if (IsAnimCur(pCursor)) + { + AnimCurPtr ac = GetAnimCur(pCursor); + + (*pScreen->CursorLimits) (pDev, pScreen, ac->elts[0].pCursor, + pHotBox, pTopLeftBox); + } + else + { + (*pScreen->CursorLimits) (pDev, pScreen, pCursor, + pHotBox, pTopLeftBox); + } + Wrap (as, pScreen, CursorLimits, AnimCurCursorLimits); +} + +/* + * This has to be a screen block handler instead of a generic + * block handler so that it is well ordered with respect to the DRI + * block handler responsible for releasing the hardware to DRI clients + */ + +static void +AnimCurScreenBlockHandler (int screenNum, + pointer blockData, + pointer pTimeout, + pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[screenNum]; + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + DeviceIntPtr dev; + Bool activeDevice = FALSE; + CARD32 now = 0, + soonest = ~0; /* earliest time to wakeup again */ + + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) + { + if (!activeDevice) { + now = GetTimeInMillis (); + activeDevice = TRUE; + } + + if ((INT32) (now - dev->spriteInfo->anim.time) >= 0) + { + AnimCurPtr ac = GetAnimCur(dev->spriteInfo->anim.pCursor); + int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt; + DisplayCursorProcPtr DisplayCursor; + + /* + * Not a simple Unwrap/Wrap as this + * isn't called along the DisplayCursor + * wrapper chain. + */ + DisplayCursor = pScreen->DisplayCursor; + pScreen->DisplayCursor = as->DisplayCursor; + (void) (*pScreen->DisplayCursor) (dev, + pScreen, + ac->elts[elt].pCursor); + as->DisplayCursor = pScreen->DisplayCursor; + pScreen->DisplayCursor = DisplayCursor; + + dev->spriteInfo->anim.elt = elt; + dev->spriteInfo->anim.time = now + ac->elts[elt].delay; + } + + if (soonest > dev->spriteInfo->anim.time) + soonest = dev->spriteInfo->anim.time; + } + } + + if (activeDevice) + AdjustWaitForDelay (pTimeout, soonest - now); + + Unwrap (as, pScreen, BlockHandler); + (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask); + if (activeDevice) + Wrap (as, pScreen, BlockHandler, AnimCurScreenBlockHandler); + else + as->BlockHandler = NULL; +} + +static Bool +AnimCurDisplayCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + if (IsFloating(pDev)) + return FALSE; + + Unwrap (as, pScreen, DisplayCursor); + if (IsAnimCur(pCursor)) + { + if (pCursor != pDev->spriteInfo->anim.pCursor) + { + AnimCurPtr ac = GetAnimCur(pCursor); + + ret = (*pScreen->DisplayCursor) + (pDev, pScreen, ac->elts[0].pCursor); + if (ret) + { + pDev->spriteInfo->anim.elt = 0; + pDev->spriteInfo->anim.time = GetTimeInMillis () + ac->elts[0].delay; + pDev->spriteInfo->anim.pCursor = pCursor; + pDev->spriteInfo->anim.pScreen = pScreen; + + if (!as->BlockHandler) + Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler); + } + } + else + ret = TRUE; + } + else + { + pDev->spriteInfo->anim.pCursor = 0; + pDev->spriteInfo->anim.pScreen = 0; + ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); + } + Wrap (as, pScreen, DisplayCursor, AnimCurDisplayCursor); + return ret; +} + +static Bool +AnimCurSetCursorPosition (DeviceIntPtr pDev, + ScreenPtr pScreen, + int x, + int y, + Bool generateEvent) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap (as, pScreen, SetCursorPosition); + if (pDev->spriteInfo->anim.pCursor) { + pDev->spriteInfo->anim.pScreen = pScreen; + + if (!as->BlockHandler) + Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler); + } + ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent); + Wrap (as, pScreen, SetCursorPosition, AnimCurSetCursorPosition); + return ret; +} + +static Bool +AnimCurRealizeCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap (as, pScreen, RealizeCursor); + if (IsAnimCur(pCursor)) + ret = TRUE; + else + ret = (*pScreen->RealizeCursor) (pDev, pScreen, pCursor); + Wrap (as, pScreen, RealizeCursor, AnimCurRealizeCursor); + return ret; +} + +static Bool +AnimCurUnrealizeCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + Bool ret; + + Unwrap (as, pScreen, UnrealizeCursor); + if (IsAnimCur(pCursor)) + { + AnimCurPtr ac = GetAnimCur(pCursor); + int i; + + if (pScreen->myNum == 0) + for (i = 0; i < ac->nelt; i++) + FreeCursor (ac->elts[i].pCursor, 0); + ret = TRUE; + } + else + ret = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor); + Wrap (as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); + return ret; +} + +static void +AnimCurRecolorCursor (DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor, + Bool displayed) +{ + AnimCurScreenPtr as = GetAnimCurScreen(pScreen); + + Unwrap (as, pScreen, RecolorCursor); + if (IsAnimCur(pCursor)) + { + AnimCurPtr ac = GetAnimCur(pCursor); + int i; + + for (i = 0; i < ac->nelt; i++) + (*pScreen->RecolorCursor) (pDev, pScreen, ac->elts[i].pCursor, + displayed && + pDev->spriteInfo->anim.elt == i); + } + else + (*pScreen->RecolorCursor) (pDev, pScreen, pCursor, displayed); + Wrap (as, pScreen, RecolorCursor, AnimCurRecolorCursor); +} + +Bool +AnimCurInit (ScreenPtr pScreen) +{ + AnimCurScreenPtr as; + + if (!dixRegisterPrivateKey(&AnimCurScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + as = (AnimCurScreenPtr) malloc(sizeof (AnimCurScreenRec)); + if (!as) + return FALSE; + Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen); + + as->BlockHandler = NULL; + + Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits); + Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor); + Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition); + Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor); + Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor); + Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor); + SetAnimCurScreen(pScreen,as); + return TRUE; +} + +int +AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor, ClientPtr client, XID cid) +{ + CursorPtr pCursor; + int rc, i; + AnimCurPtr ac; + + for (i = 0; i < screenInfo.numScreens; i++) + if (!GetAnimCurScreen (screenInfo.screens[i])) + return BadImplementation; + + for (i = 0; i < ncursor; i++) + if (IsAnimCur (cursors[i])) + return BadMatch; + + pCursor = (CursorPtr) calloc(CURSOR_REC_SIZE + + sizeof (AnimCurRec) + + ncursor * sizeof (AnimCurElt), 1); + if (!pCursor) + return BadAlloc; + dixInitPrivates(pCursor, pCursor + 1, PRIVATE_CURSOR); + pCursor->bits = &animCursorBits; + pCursor->refcnt = 1; + + pCursor->foreRed = cursors[0]->foreRed; + pCursor->foreGreen = cursors[0]->foreGreen; + pCursor->foreBlue = cursors[0]->foreBlue; + + pCursor->backRed = cursors[0]->backRed; + pCursor->backGreen = cursors[0]->backGreen; + pCursor->backBlue = cursors[0]->backBlue; + + pCursor->id = cid; + + /* security creation/labeling check */ + rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCursor, + RT_NONE, NULL, DixCreateAccess); + if (rc != Success) { + dixFiniPrivates(pCursor, PRIVATE_CURSOR); + free(pCursor); + return rc; + } + + /* + * Fill in the AnimCurRec + */ + animCursorBits.refcnt++; + ac = GetAnimCur (pCursor); + ac->nelt = ncursor; + ac->elts = (AnimCurElt *) (ac + 1); + + for (i = 0; i < ncursor; i++) + { + cursors[i]->refcnt++; + ac->elts[i].pCursor = cursors[i]; + ac->elts[i].delay = deltas[i]; + } + + *ppCursor = pCursor; + return Success; +} -- cgit v1.2.3