|
|
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.