|
|
1.1 root 1: /* $Header: grabs.c,v 1.1 87/09/11 07:18:50 toddb Exp $ */
2: /************************************************************
3: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
4: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
5:
6: All Rights Reserved
7:
8: Permission to use, copy, modify, and distribute this software and its
9: documentation for any purpose and without fee is hereby granted,
10: provided that the above copyright notice appear in all copies and that
11: both that copyright notice and this permission notice appear in
12: supporting documentation, and that the names of Digital or MIT not be
13: used in advertising or publicity pertaining to distribution of the
14: software without specific, written prior permission.
15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19: WHETHER IN AN action OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21: SOFTWARE.
22:
23: ********************************************************/
24:
25: #include "X.h"
26: #include "misc.h"
27: #define NEED_EVENTS
28: #include "Xproto.h"
29: #include "windowstr.h"
30: #include "inputstr.h"
31:
32: #define BITMASK(i) (1 << ((i) & 31))
33: #define MASKIDX(i) ((i) >> 5)
34: #define MASKWORD(buf, i) buf[MASKIDX(i)]
35: #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
36: #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
37: #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
38:
39: static Mask *
40: CreateDetailMask()
41: {
42: Mask *pTempMask;
43: int i;
44:
45: pTempMask = (Mask *)Xalloc(sizeof(Mask) * MasksPerDetailMask);
46:
47: for ( i = 0; i < MasksPerDetailMask; i++)
48: pTempMask[i]= ~0;
49:
50: return pTempMask;
51:
52: }
53:
54: static void
55: DeleteDetailFromMask(ppDetailMask, detail)
56: Mask **ppDetailMask;
57: int detail;
58: {
59: if (*ppDetailMask == NULL)
60: *ppDetailMask = CreateDetailMask();
61:
62: BITCLEAR((*ppDetailMask), detail);
63: }
64:
65: static Mask *
66: CopyDetailMask(pOriginalDetailMask)
67: Mask *pOriginalDetailMask;
68: {
69: Mask *pTempMask;
70: int i;
71:
72: if (pOriginalDetailMask == NULL)
73: return NULL;
74:
75: pTempMask = (Mask *)Xalloc(sizeof(Mask) * MasksPerDetailMask);
76:
77: for ( i = 0; i < MasksPerDetailMask; i++)
78: pTempMask[i]= pOriginalDetailMask[i];
79:
80: return pTempMask;
81:
82: }
83:
84: extern void PassiveClientGone(); /* This is defined in events.c */
85:
86: void
87: AddPassiveGrabToWindowList(pGrab)
88: GrabPtr pGrab;
89: {
90: pGrab->resource = FakeClientID(pGrab->client->index);
91: pGrab->next = PASSIVEGRABS(pGrab->window);
92: pGrab->window->passiveGrabs = (pointer)pGrab;
93: AddResource(pGrab->resource, RT_FAKE, pGrab->window, PassiveClientGone, RC_CORE);
94: }
95:
96:
97: GrabPtr
98: CreateGrab(client, device, window, eventMask, ownerEvents, keyboardMode,
99: pointerMode, modifiers, key)
100: ClientPtr client;
101: DeviceIntPtr device;
102: WindowPtr window;
103: Mask eventMask;
104: BOOL ownerEvents, keyboardMode, pointerMode;
105: int modifiers, key;
106: {
107: GrabPtr grab;
108:
109: grab = (GrabPtr)Xalloc(sizeof(GrabRec));
110: grab->client = client;
111: grab->device = device;
112: grab->window = window;
113: grab->eventMask = eventMask;
114: grab->ownerEvents = ownerEvents;
115: grab->keyboardMode = keyboardMode;
116: grab->pointerMode = pointerMode;
117: grab->modifiersDetail.exact = modifiers;
118: grab->modifiersDetail.pMask = NULL;
119: grab->u.keybd.keyDetail.exact = key;
120: grab->u.keybd.keyDetail.pMask = NULL;
121: return grab;
122:
123: }
124:
125:
126:
127: void
128: DeleteGrab(pGrab)
129: GrabPtr pGrab;
130: {
131: if (pGrab->modifiersDetail.pMask != NULL)
132: Xfree(pGrab->modifiersDetail.pMask);
133:
134: if (pGrab->u.keybd.keyDetail.pMask != NULL)
135: Xfree(pGrab->u.keybd.keyDetail.pMask);
136:
137: Xfree(pGrab);
138:
139: }
140:
141:
142: static BOOL
143: IsInGrabMask(firstDetail, secondExact, exception)
144: DetailRec firstDetail;
145: int secondExact;
146: int exception;
147: {
148: if (firstDetail.exact == exception)
149: {
150: if (firstDetail.pMask == NULL)
151: return TRUE;
152:
153: if (GETBIT(firstDetail.pMask, secondExact))
154: return TRUE;
155: }
156:
157: return FALSE;
158: }
159:
160: static BOOL
161: IdenticalExactDetails(firstExact, secondExact, exception)
162: int firstExact, secondExact, exception;
163: {
164: if ((firstExact == exception) || (secondExact == exception))
165: return FALSE;
166:
167: if (firstExact == secondExact)
168: return TRUE;
169:
170: return FALSE;
171: }
172:
173: static BOOL
174: DetailSupersedesSecond(firstDetail, secondDetail, exception)
175: DetailRec firstDetail, secondDetail;
176: int exception;
177: {
178: if (IsInGrabMask(firstDetail, secondDetail.exact, exception))
179: return TRUE;
180:
181: if (IdenticalExactDetails(firstDetail.exact, secondDetail.exact, exception))
182: return TRUE;
183:
184: return FALSE;
185:
186: }
187:
188: BOOL
189: GrabSupersedesSecond(pFirstGrab, pSecondGrab)
190: GrabPtr pFirstGrab, pSecondGrab;
191: {
192: if (!DetailSupersedesSecond(pFirstGrab->modifiersDetail,
193: pSecondGrab->modifiersDetail,
194: AnyModifier))
195: return FALSE;
196:
197: if (DetailSupersedesSecond(pFirstGrab->u.keybd.keyDetail,
198: pSecondGrab->u.keybd.keyDetail, AnyKey))
199: return TRUE;
200:
201: return FALSE;
202: }
203:
204: BOOL
205: GrabMatchesSecond(pFirstGrab, pSecondGrab)
206: GrabPtr pFirstGrab, pSecondGrab;
207: {
208: if (pFirstGrab->device != pSecondGrab->device)
209: return FALSE;
210:
211: if (GrabSupersedesSecond(pFirstGrab, pSecondGrab))
212: return TRUE;
213:
214: if (GrabSupersedesSecond(pSecondGrab, pFirstGrab))
215: return TRUE;
216:
217: if (DetailSupersedesSecond(pSecondGrab->u.keybd.keyDetail,
218: pFirstGrab->u.keybd.keyDetail, AnyKey)
219: &&
220: DetailSupersedesSecond(pFirstGrab->modifiersDetail,
221: pSecondGrab->modifiersDetail, AnyModifier))
222: return TRUE;
223:
224: if (DetailSupersedesSecond(pFirstGrab->u.keybd.keyDetail,
225: pSecondGrab->u.keybd.keyDetail, AnyKey)
226: &&
227: DetailSupersedesSecond(pSecondGrab->modifiersDetail,
228: pFirstGrab->modifiersDetail, AnyModifier))
229: return TRUE;
230:
231: return FALSE;
232:
233: }
234:
235:
236:
237: void
238: DeletePassiveGrabFromList(pMinuendGrab)
239: GrabPtr pMinuendGrab;
240: {
241: register GrabPtr *next;
242: register GrabPtr grab;
243:
244: for (next = (GrabPtr *)&(pMinuendGrab->window->passiveGrabs); *next; )
245: {
246: grab = *next;
247:
248: if (GrabMatchesSecond(grab, pMinuendGrab) &&
249: (grab->client == pMinuendGrab->client))
250: {
251: if (GrabSupersedesSecond(pMinuendGrab, grab))
252: {
253: /* This is really sleazy and counts on FreeResource to update
254: *next ( notice the continue ). */
255:
256: FreeResource(grab->resource, RC_NONE);
257: continue;
258: }
259:
260: if ((grab->u.keybd.keyDetail.exact == AnyKey)
261: && (grab->modifiersDetail.exact != AnyModifier))
262: {
263: DeleteDetailFromMask(&(grab->u.keybd.keyDetail.pMask),
264: pMinuendGrab->u.keybd.keyDetail.exact);
265: }
266: else
267: {
268: if ((grab->modifiersDetail.exact == AnyModifier)
269: && (grab->u.keybd.keyDetail.exact != AnyKey))
270: {
271: DeleteDetailFromMask(&(grab->modifiersDetail.pMask),
272: pMinuendGrab->modifiersDetail.exact);
273: }
274: else
275: {
276: if ((pMinuendGrab->u.keybd.keyDetail.exact != AnyKey)
277: && (pMinuendGrab->modifiersDetail.exact != AnyModifier))
278: {
279: GrabPtr pNewGrab;
280:
281: DeleteDetailFromMask(&(grab->u.keybd.keyDetail.pMask),
282: pMinuendGrab->u.keybd.keyDetail.exact);
283:
284: pNewGrab = CreateGrab(grab->client, grab->device,
285: grab->window,
286: grab->eventMask, grab->ownerEvents,
287: grab->keyboardMode, grab->pointerMode, AnyModifier,
288: pMinuendGrab->u.keybd.keyDetail.exact);
289:
290: pNewGrab->modifiersDetail.pMask =
291: CopyDetailMask(grab->modifiersDetail.pMask);
292:
293: DeleteDetailFromMask(&(pNewGrab->modifiersDetail.pMask),
294: pMinuendGrab->modifiersDetail.exact);
295:
296: AddPassiveGrabToWindowList(pNewGrab);
297: }
298: else
299: {
300: if (pMinuendGrab->u.keybd.keyDetail.exact ==
301: AnyKey)
302: {
303: DeleteDetailFromMask(&(grab->modifiersDetail.pMask),
304: pMinuendGrab->modifiersDetail.exact);
305: }
306: else
307: {
308: DeleteDetailFromMask(
309: &(grab->u.keybd.keyDetail.pMask),
310: pMinuendGrab->u.keybd.keyDetail.exact);
311: }
312: }
313: }
314:
315: }
316: }
317: next = &((*next)->next);
318: }
319: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.