2
* $Id: select.c,v 1.6 2005/07/03 07:37:35 daniels Exp $
4
* Copyright Ā© 2002 Keith Packard
6
* Permission to use, copy, modify, distribute, and sell this software and its
7
* documentation for any purpose is hereby granted without fee, provided that
8
* the above copyright notice appear in all copies and that both that
9
* copyright notice and this permission notice appear in supporting
10
* documentation, and that the name of Keith Packard not be used in
11
* advertising or publicity pertaining to distribution of the software without
12
* specific, written prior permission. Keith Packard makes no
13
* representations about the suitability of this software for any purpose. It
14
* is provided "as is" without express or implied warranty.
16
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
* PERFORMANCE OF THIS SOFTWARE.
25
#ifdef HAVE_DIX_CONFIG_H
26
#include <dix-config.h>
29
#include "xfixesint.h"
31
static RESTYPE SelectionClientType, SelectionWindowType;
32
static Bool SelectionCallbackRegistered = FALSE;
35
* There is a global list of windows selecting for selection events
36
* on every selection. This should be plenty efficient for the
37
* expected usage, if it does become a problem, it should be easily
38
* replaced with a hash table of some kind keyed off the selection atom
41
typedef struct _SelectionEvent *SelectionEventPtr;
43
typedef struct _SelectionEvent {
44
SelectionEventPtr next;
52
static SelectionEventPtr selectionEvents;
55
XFixesSelectionCallback (CallbackListPtr *callbacks, pointer data, pointer args)
58
SelectionInfoRec *info = (SelectionInfoRec *) args;
59
Selection *selection = info->selection;
64
case SelectionSetOwner:
65
subtype = XFixesSetSelectionOwnerNotify;
66
eventMask = XFixesSetSelectionOwnerNotifyMask;
68
case SelectionWindowDestroy:
69
subtype = XFixesSelectionWindowDestroyNotify;
70
eventMask = XFixesSelectionWindowDestroyNotifyMask;
72
case SelectionClientClose:
73
subtype = XFixesSelectionClientCloseNotify;
74
eventMask = XFixesSelectionClientCloseNotifyMask;
79
for (e = selectionEvents; e; e = e->next)
81
if (e->selection == selection->selection && (e->eventMask & eventMask))
83
xXFixesSelectionNotifyEvent ev;
85
ev.type = XFixesEventBase + XFixesSelectionNotify;
87
ev.sequenceNumber = e->pClient->sequence;
88
ev.window = e->pWindow->drawable.id;
89
if (subtype == XFixesSetSelectionOwnerNotify)
90
ev.owner = selection->window;
93
ev.selection = e->selection;
94
ev.timestamp = currentTime.milliseconds;
95
ev.selectionTimestamp = selection->lastTimeChanged.milliseconds;
96
WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
102
CheckSelectionCallback (void)
106
if (!SelectionCallbackRegistered)
108
if (!AddCallback (&SelectionCallback, XFixesSelectionCallback, NULL))
110
SelectionCallbackRegistered = TRUE;
115
if (SelectionCallbackRegistered)
117
DeleteCallback (&SelectionCallback, XFixesSelectionCallback, NULL);
118
SelectionCallbackRegistered = FALSE;
124
#define SelectionAllEvents (XFixesSetSelectionOwnerNotifyMask |\
125
XFixesSelectionWindowDestroyNotifyMask |\
126
XFixesSelectionClientCloseNotifyMask)
129
XFixesSelectSelectionInput (ClientPtr pClient,
134
SelectionEventPtr *prev, e;
136
for (prev = &selectionEvents; (e = *prev); prev = &e->next)
138
if (e->selection == selection &&
139
e->pClient == pClient &&
140
e->pWindow == pWindow)
149
FreeResource (e->clientResource, 0);
155
e = (SelectionEventPtr) xalloc (sizeof (SelectionEventRec));
160
e->selection = selection;
161
e->pClient = pClient;
162
e->pWindow = pWindow;
163
e->clientResource = FakeClientID(pClient->index);
166
* Add a resource hanging from the window to
167
* catch window destroy
169
if (!LookupIDByType(pWindow->drawable.id, SelectionWindowType))
170
if (!AddResource (pWindow->drawable.id, SelectionWindowType,
177
if (!AddResource (e->clientResource, SelectionClientType, (pointer) e))
181
if (!CheckSelectionCallback ())
183
FreeResource (e->clientResource, 0);
187
e->eventMask = eventMask;
192
ProcXFixesSelectSelectionInput (ClientPtr client)
194
REQUEST (xXFixesSelectSelectionInputReq);
197
REQUEST_SIZE_MATCH (xXFixesSelectSelectionInputReq);
198
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
202
if (stuff->eventMask & ~SelectionAllEvents)
204
client->errorValue = stuff->eventMask;
207
return XFixesSelectSelectionInput (client, stuff->selection,
208
pWin, stuff->eventMask);
212
SProcXFixesSelectSelectionInput (ClientPtr client)
215
REQUEST(xXFixesSelectSelectionInputReq);
217
swaps(&stuff->length, n);
218
swapl(&stuff->window, n);
219
swapl(&stuff->selection, n);
220
swapl(&stuff->eventMask, n);
221
return ProcXFixesSelectSelectionInput(client);
225
SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from,
226
xXFixesSelectionNotifyEvent *to)
228
to->type = from->type;
229
cpswaps (from->sequenceNumber, to->sequenceNumber);
230
cpswapl (from->window, to->window);
231
cpswapl (from->owner, to->owner);
232
cpswapl (from->selection, to->selection);
233
cpswapl (from->timestamp, to->timestamp);
234
cpswapl (from->selectionTimestamp, to->selectionTimestamp);
238
SelectionFreeClient (pointer data, XID id)
240
SelectionEventPtr old = (SelectionEventPtr) data;
241
SelectionEventPtr *prev, e;
243
for (prev = &selectionEvents; (e = *prev); prev = &e->next)
249
CheckSelectionCallback ();
257
SelectionFreeWindow (pointer data, XID id)
259
WindowPtr pWindow = (WindowPtr) data;
260
SelectionEventPtr e, next;
262
for (e = selectionEvents; e; e = next)
265
if (e->pWindow == pWindow)
267
FreeResource (e->clientResource, 0);
274
XFixesSelectionInit (void)
276
SelectionClientType = CreateNewResourceType(SelectionFreeClient);
277
SelectionWindowType = CreateNewResourceType(SelectionFreeWindow);
278
return SelectionClientType && SelectionWindowType;