From c38dead3ea7e177728d90cd815cf4eead0c9f534 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 15 May 2010 16:28:11 +0000 Subject: xserver git update 15/5/2010 --- xorg-server/xfixes/select.c | 584 ++++++++++++++++++++++---------------------- 1 file changed, 292 insertions(+), 292 deletions(-) (limited to 'xorg-server/xfixes/select.c') diff --git a/xorg-server/xfixes/select.c b/xorg-server/xfixes/select.c index 5ba7896cb..044294ee1 100644 --- a/xorg-server/xfixes/select.c +++ b/xorg-server/xfixes/select.c @@ -1,292 +1,292 @@ -/* - * Copyright © 2002 Keith Packard - * - * 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. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "xfixesint.h" -#include "xace.h" - -static RESTYPE SelectionClientType, SelectionWindowType; -static Bool SelectionCallbackRegistered = FALSE; - -/* - * There is a global list of windows selecting for selection events - * on every selection. This should be plenty efficient for the - * expected usage, if it does become a problem, it should be easily - * replaced with a hash table of some kind keyed off the selection atom - */ - -typedef struct _SelectionEvent *SelectionEventPtr; - -typedef struct _SelectionEvent { - SelectionEventPtr next; - Atom selection; - CARD32 eventMask; - ClientPtr pClient; - WindowPtr pWindow; - XID clientResource; -} SelectionEventRec; - -static SelectionEventPtr selectionEvents; - -static void -XFixesSelectionCallback (CallbackListPtr *callbacks, pointer data, pointer args) -{ - SelectionEventPtr e; - SelectionInfoRec *info = (SelectionInfoRec *) args; - Selection *selection = info->selection; - int subtype; - CARD32 eventMask; - - switch (info->kind) { - case SelectionSetOwner: - subtype = XFixesSetSelectionOwnerNotify; - eventMask = XFixesSetSelectionOwnerNotifyMask; - break; - case SelectionWindowDestroy: - subtype = XFixesSelectionWindowDestroyNotify; - eventMask = XFixesSelectionWindowDestroyNotifyMask; - break; - case SelectionClientClose: - subtype = XFixesSelectionClientCloseNotify; - eventMask = XFixesSelectionClientCloseNotifyMask; - break; - default: - return; - } - for (e = selectionEvents; e; e = e->next) - { - if (e->selection == selection->selection && - (e->eventMask & eventMask) && - !e->pClient->clientGone) - { - xXFixesSelectionNotifyEvent ev; - - memset(&ev, 0, sizeof(xXFixesSelectionNotifyEvent)); - ev.type = XFixesEventBase + XFixesSelectionNotify; - ev.subtype = subtype; - ev.sequenceNumber = e->pClient->sequence; - ev.window = e->pWindow->drawable.id; - if (subtype == XFixesSetSelectionOwnerNotify) - ev.owner = selection->window; - else - ev.owner = 0; - ev.selection = e->selection; - ev.timestamp = currentTime.milliseconds; - ev.selectionTimestamp = selection->lastTimeChanged.milliseconds; - WriteEventsToClient (e->pClient, 1, (xEvent *) &ev); - } - } -} - -static Bool -CheckSelectionCallback (void) -{ - if (selectionEvents) - { - if (!SelectionCallbackRegistered) - { - if (!AddCallback (&SelectionCallback, XFixesSelectionCallback, NULL)) - return FALSE; - SelectionCallbackRegistered = TRUE; - } - } - else - { - if (SelectionCallbackRegistered) - { - DeleteCallback (&SelectionCallback, XFixesSelectionCallback, NULL); - SelectionCallbackRegistered = FALSE; - } - } - return TRUE; -} - -#define SelectionAllEvents (XFixesSetSelectionOwnerNotifyMask |\ - XFixesSelectionWindowDestroyNotifyMask |\ - XFixesSelectionClientCloseNotifyMask) - -static int -XFixesSelectSelectionInput (ClientPtr pClient, - Atom selection, - WindowPtr pWindow, - CARD32 eventMask) -{ - pointer val; - int rc; - SelectionEventPtr *prev, e; - - rc = XaceHook(XACE_SELECTION_ACCESS, pClient, selection, DixGetAttrAccess); - if (rc != Success) - return rc; - - for (prev = &selectionEvents; (e = *prev); prev = &e->next) - { - if (e->selection == selection && - e->pClient == pClient && - e->pWindow == pWindow) - { - break; - } - } - if (!eventMask) - { - if (e) - { - FreeResource (e->clientResource, 0); - } - return Success; - } - if (!e) - { - e = (SelectionEventPtr) xalloc (sizeof (SelectionEventRec)); - if (!e) - return BadAlloc; - - e->next = 0; - e->selection = selection; - e->pClient = pClient; - e->pWindow = pWindow; - e->clientResource = FakeClientID(pClient->index); - - /* - * Add a resource hanging from the window to - * catch window destroy - */ - rc = dixLookupResourceByType (&val, pWindow->drawable.id, - SelectionWindowType, serverClient, - DixGetAttrAccess); - if (rc != Success) - if (!AddResource (pWindow->drawable.id, SelectionWindowType, - (pointer) pWindow)) - { - xfree (e); - return BadAlloc; - } - - if (!AddResource (e->clientResource, SelectionClientType, (pointer) e)) - return BadAlloc; - - *prev = e; - if (!CheckSelectionCallback ()) - { - FreeResource (e->clientResource, 0); - return BadAlloc; - } - } - e->eventMask = eventMask; - return Success; -} - -int -ProcXFixesSelectSelectionInput (ClientPtr client) -{ - REQUEST (xXFixesSelectSelectionInputReq); - WindowPtr pWin; - int rc; - - REQUEST_SIZE_MATCH (xXFixesSelectSelectionInputReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - if (stuff->eventMask & ~SelectionAllEvents) - { - client->errorValue = stuff->eventMask; - return( BadValue ); - } - return XFixesSelectSelectionInput (client, stuff->selection, - pWin, stuff->eventMask); -} - -int -SProcXFixesSelectSelectionInput (ClientPtr client) -{ - register int n; - REQUEST(xXFixesSelectSelectionInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swapl(&stuff->selection, n); - swapl(&stuff->eventMask, n); - return (*ProcXFixesVector[stuff->xfixesReqType])(client); -} - -void -SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from, - xXFixesSelectionNotifyEvent *to) -{ - to->type = from->type; - cpswaps (from->sequenceNumber, to->sequenceNumber); - cpswapl (from->window, to->window); - cpswapl (from->owner, to->owner); - cpswapl (from->selection, to->selection); - cpswapl (from->timestamp, to->timestamp); - cpswapl (from->selectionTimestamp, to->selectionTimestamp); -} - -static int -SelectionFreeClient (pointer data, XID id) -{ - SelectionEventPtr old = (SelectionEventPtr) data; - SelectionEventPtr *prev, e; - - for (prev = &selectionEvents; (e = *prev); prev = &e->next) - { - if (e == old) - { - *prev = e->next; - xfree (e); - CheckSelectionCallback (); - break; - } - } - return 1; -} - -static int -SelectionFreeWindow (pointer data, XID id) -{ - WindowPtr pWindow = (WindowPtr) data; - SelectionEventPtr e, next; - - for (e = selectionEvents; e; e = next) - { - next = e->next; - if (e->pWindow == pWindow) - { - FreeResource (e->clientResource, 0); - } - } - return 1; -} - -Bool -XFixesSelectionInit (void) -{ - SelectionClientType = CreateNewResourceType(SelectionFreeClient, - "XFixesSelectionClient"); - SelectionWindowType = CreateNewResourceType(SelectionFreeWindow, - "XFixesSelectionWindow"); - return SelectionClientType && SelectionWindowType; -} +/* + * Copyright © 2002 Keith Packard + * + * 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "xfixesint.h" +#include "xace.h" + +static RESTYPE SelectionClientType, SelectionWindowType; +static Bool SelectionCallbackRegistered = FALSE; + +/* + * There is a global list of windows selecting for selection events + * on every selection. This should be plenty efficient for the + * expected usage, if it does become a problem, it should be easily + * replaced with a hash table of some kind keyed off the selection atom + */ + +typedef struct _SelectionEvent *SelectionEventPtr; + +typedef struct _SelectionEvent { + SelectionEventPtr next; + Atom selection; + CARD32 eventMask; + ClientPtr pClient; + WindowPtr pWindow; + XID clientResource; +} SelectionEventRec; + +static SelectionEventPtr selectionEvents; + +static void +XFixesSelectionCallback (CallbackListPtr *callbacks, pointer data, pointer args) +{ + SelectionEventPtr e; + SelectionInfoRec *info = (SelectionInfoRec *) args; + Selection *selection = info->selection; + int subtype; + CARD32 eventMask; + + switch (info->kind) { + case SelectionSetOwner: + subtype = XFixesSetSelectionOwnerNotify; + eventMask = XFixesSetSelectionOwnerNotifyMask; + break; + case SelectionWindowDestroy: + subtype = XFixesSelectionWindowDestroyNotify; + eventMask = XFixesSelectionWindowDestroyNotifyMask; + break; + case SelectionClientClose: + subtype = XFixesSelectionClientCloseNotify; + eventMask = XFixesSelectionClientCloseNotifyMask; + break; + default: + return; + } + for (e = selectionEvents; e; e = e->next) + { + if (e->selection == selection->selection && + (e->eventMask & eventMask) && + !e->pClient->clientGone) + { + xXFixesSelectionNotifyEvent ev; + + memset(&ev, 0, sizeof(xXFixesSelectionNotifyEvent)); + ev.type = XFixesEventBase + XFixesSelectionNotify; + ev.subtype = subtype; + ev.sequenceNumber = e->pClient->sequence; + ev.window = e->pWindow->drawable.id; + if (subtype == XFixesSetSelectionOwnerNotify) + ev.owner = selection->window; + else + ev.owner = 0; + ev.selection = e->selection; + ev.timestamp = currentTime.milliseconds; + ev.selectionTimestamp = selection->lastTimeChanged.milliseconds; + WriteEventsToClient (e->pClient, 1, (xEvent *) &ev); + } + } +} + +static Bool +CheckSelectionCallback (void) +{ + if (selectionEvents) + { + if (!SelectionCallbackRegistered) + { + if (!AddCallback (&SelectionCallback, XFixesSelectionCallback, NULL)) + return FALSE; + SelectionCallbackRegistered = TRUE; + } + } + else + { + if (SelectionCallbackRegistered) + { + DeleteCallback (&SelectionCallback, XFixesSelectionCallback, NULL); + SelectionCallbackRegistered = FALSE; + } + } + return TRUE; +} + +#define SelectionAllEvents (XFixesSetSelectionOwnerNotifyMask |\ + XFixesSelectionWindowDestroyNotifyMask |\ + XFixesSelectionClientCloseNotifyMask) + +static int +XFixesSelectSelectionInput (ClientPtr pClient, + Atom selection, + WindowPtr pWindow, + CARD32 eventMask) +{ + pointer val; + int rc; + SelectionEventPtr *prev, e; + + rc = XaceHook(XACE_SELECTION_ACCESS, pClient, selection, DixGetAttrAccess); + if (rc != Success) + return rc; + + for (prev = &selectionEvents; (e = *prev); prev = &e->next) + { + if (e->selection == selection && + e->pClient == pClient && + e->pWindow == pWindow) + { + break; + } + } + if (!eventMask) + { + if (e) + { + FreeResource (e->clientResource, 0); + } + return Success; + } + if (!e) + { + e = (SelectionEventPtr) malloc(sizeof (SelectionEventRec)); + if (!e) + return BadAlloc; + + e->next = 0; + e->selection = selection; + e->pClient = pClient; + e->pWindow = pWindow; + e->clientResource = FakeClientID(pClient->index); + + /* + * Add a resource hanging from the window to + * catch window destroy + */ + rc = dixLookupResourceByType (&val, pWindow->drawable.id, + SelectionWindowType, serverClient, + DixGetAttrAccess); + if (rc != Success) + if (!AddResource (pWindow->drawable.id, SelectionWindowType, + (pointer) pWindow)) + { + free(e); + return BadAlloc; + } + + if (!AddResource (e->clientResource, SelectionClientType, (pointer) e)) + return BadAlloc; + + *prev = e; + if (!CheckSelectionCallback ()) + { + FreeResource (e->clientResource, 0); + return BadAlloc; + } + } + e->eventMask = eventMask; + return Success; +} + +int +ProcXFixesSelectSelectionInput (ClientPtr client) +{ + REQUEST (xXFixesSelectSelectionInputReq); + WindowPtr pWin; + int rc; + + REQUEST_SIZE_MATCH (xXFixesSelectSelectionInputReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + if (stuff->eventMask & ~SelectionAllEvents) + { + client->errorValue = stuff->eventMask; + return( BadValue ); + } + return XFixesSelectSelectionInput (client, stuff->selection, + pWin, stuff->eventMask); +} + +int +SProcXFixesSelectSelectionInput (ClientPtr client) +{ + register int n; + REQUEST(xXFixesSelectSelectionInputReq); + + swaps(&stuff->length, n); + swapl(&stuff->window, n); + swapl(&stuff->selection, n); + swapl(&stuff->eventMask, n); + return (*ProcXFixesVector[stuff->xfixesReqType])(client); +} + +void +SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from, + xXFixesSelectionNotifyEvent *to) +{ + to->type = from->type; + cpswaps (from->sequenceNumber, to->sequenceNumber); + cpswapl (from->window, to->window); + cpswapl (from->owner, to->owner); + cpswapl (from->selection, to->selection); + cpswapl (from->timestamp, to->timestamp); + cpswapl (from->selectionTimestamp, to->selectionTimestamp); +} + +static int +SelectionFreeClient (pointer data, XID id) +{ + SelectionEventPtr old = (SelectionEventPtr) data; + SelectionEventPtr *prev, e; + + for (prev = &selectionEvents; (e = *prev); prev = &e->next) + { + if (e == old) + { + *prev = e->next; + free(e); + CheckSelectionCallback (); + break; + } + } + return 1; +} + +static int +SelectionFreeWindow (pointer data, XID id) +{ + WindowPtr pWindow = (WindowPtr) data; + SelectionEventPtr e, next; + + for (e = selectionEvents; e; e = next) + { + next = e->next; + if (e->pWindow == pWindow) + { + FreeResource (e->clientResource, 0); + } + } + return 1; +} + +Bool +XFixesSelectionInit (void) +{ + SelectionClientType = CreateNewResourceType(SelectionFreeClient, + "XFixesSelectionClient"); + SelectionWindowType = CreateNewResourceType(SelectionFreeWindow, + "XFixesSelectionWindow"); + return SelectionClientType && SelectionWindowType; +} -- cgit v1.2.3