|
|
1.1 ! root 1: /*********************************************************** ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 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: /* $Header: extension.c,v 1.36 87/09/09 13:16:05 rws Exp $ */ ! 25: ! 26: #include "X.h" ! 27: #define NEED_REPLIES ! 28: #include "Xproto.h" ! 29: #include "misc.h" ! 30: #include "dixstruct.h" ! 31: #include "extnsionst.h" ! 32: #include "gcstruct.h" ! 33: #include "scrnintstr.h" ! 34: ! 35: #define EXTENSION_BASE 128 ! 36: #define EXTENSION_EVENT_BASE 64 ! 37: #define LAST_EVENT 128 ! 38: #define LAST_ERROR 255 ! 39: ! 40: ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS]; ! 41: ! 42: static ExtensionEntry **extensions = (ExtensionEntry **)NULL; ! 43: extern int (* ProcVector[]) (); ! 44: extern int (* SwappedProcVector[]) (); ! 45: extern int (* ReplySwapVector[256]) (); ! 46: ! 47: int lastEvent = EXTENSION_EVENT_BASE; ! 48: static int lastError = FirstExtensionError; ! 49: static int NumExtensions = 0; ! 50: ! 51: ExtensionEntry *AddExtension(name, NumEvents, NumErrors, MainProc, ! 52: SwappedMainProc, CloseDownProc) ! 53: char *name; ! 54: int NumEvents; ! 55: int NumErrors; ! 56: int (* MainProc)(); ! 57: int (* SwappedMainProc)(); ! 58: void (* CloseDownProc)(); ! 59: { ! 60: int i; ! 61: ! 62: if (!MainProc || !SwappedMainProc || !CloseDownProc) ! 63: return((ExtensionEntry *) NULL); ! 64: if ((lastEvent + NumEvents > LAST_EVENT) || ! 65: (unsigned)(lastError + NumErrors > LAST_ERROR)) ! 66: return((ExtensionEntry *) NULL); ! 67: ! 68: i = NumExtensions; ! 69: NumExtensions += 1; ! 70: extensions = (ExtensionEntry **) Xrealloc(extensions, ! 71: NumExtensions * sizeof(ExtensionEntry *)); ! 72: extensions[i] = (ExtensionEntry *) Xalloc(sizeof(ExtensionEntry)); ! 73: extensions[i]->name = (char *)Xalloc(strlen(name) + 1); ! 74: strcpy(extensions[i]->name, name); ! 75: extensions[i]->index = i; ! 76: extensions[i]->base = i + EXTENSION_BASE; ! 77: extensions[i]->CloseDown = CloseDownProc; ! 78: ProcVector[i + EXTENSION_BASE] = MainProc; ! 79: SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc; ! 80: if (NumEvents) ! 81: { ! 82: extensions[i]->eventBase = lastEvent; ! 83: extensions[i]->eventLast = lastEvent + NumEvents; ! 84: lastEvent += NumEvents; ! 85: } ! 86: else ! 87: { ! 88: extensions[i]->eventBase = 0; ! 89: extensions[i]->eventLast = 0; ! 90: } ! 91: if (NumErrors) ! 92: { ! 93: extensions[i]->errorBase = lastError; ! 94: extensions[i]->errorLast = lastError + NumErrors; ! 95: lastError += NumErrors; ! 96: } ! 97: else ! 98: { ! 99: extensions[i]->errorBase = 0; ! 100: extensions[i]->errorLast = 0; ! 101: } ! 102: return(extensions[i]); ! 103: } ! 104: ! 105: CloseDownExtensions() ! 106: { ! 107: register int i; ! 108: ! 109: for (i = 0; i < NumExtensions; i++) ! 110: { ! 111: (* extensions[i]->CloseDown)(extensions[i]); ! 112: Xfree(extensions[i]->name); ! 113: Xfree(extensions[i]); ! 114: } ! 115: Xfree(extensions); ! 116: NumExtensions = 0; ! 117: extensions = (ExtensionEntry **)NULL; ! 118: lastEvent = EXTENSION_EVENT_BASE; ! 119: lastError = FirstExtensionError; ! 120: } ! 121: ! 122: ! 123: ! 124: int ! 125: ProcQueryExtension(client) ! 126: ClientPtr client; ! 127: { ! 128: xQueryExtensionReply reply; ! 129: int i; ! 130: REQUEST(xQueryExtensionReq); ! 131: ! 132: REQUEST_AT_LEAST_SIZE(xQueryExtensionReq); ! 133: ! 134: reply.type = X_Reply; ! 135: reply.length = 0; ! 136: reply.major_opcode = 0; ! 137: reply.sequenceNumber = client->sequence; ! 138: ! 139: if ( ! NumExtensions ) ! 140: reply.present = xFalse; ! 141: else ! 142: { ! 143: for (i=0; i<NumExtensions; i++) ! 144: { ! 145: if ((strlen(extensions[i]->name) == stuff->nbytes) && ! 146: !strncmp(&stuff[1], extensions[i]->name, stuff->nbytes)) ! 147: break; ! 148: } ! 149: if (i == NumExtensions) ! 150: reply.present = xFalse; ! 151: else ! 152: { ! 153: reply.present = xTrue; ! 154: reply.major_opcode = extensions[i]->base; ! 155: reply.first_event = extensions[i]->eventBase; ! 156: reply.first_error = extensions[i]->errorBase; ! 157: } ! 158: } ! 159: WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply); ! 160: return(client->noClientException); ! 161: } ! 162: ! 163: int ! 164: ProcListExtensions(client) ! 165: ClientPtr client; ! 166: { ! 167: xListExtensionsReply reply; ! 168: char *bufptr, *buffer; ! 169: int total_length = 0; ! 170: ! 171: REQUEST(xReq); ! 172: REQUEST_SIZE_MATCH(xReq); ! 173: ! 174: reply.type = X_Reply; ! 175: reply.nExtensions = NumExtensions; ! 176: reply.length = 0; ! 177: reply.sequenceNumber = client->sequence; ! 178: buffer = NULL; ! 179: ! 180: if ( NumExtensions ) ! 181: { ! 182: register int i; ! 183: ! 184: for (i=0; i<NumExtensions; i++) ! 185: total_length += strlen(extensions[i]->name) + 1; ! 186: ! 187: reply.length = (total_length + 3) >> 2; ! 188: buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length); ! 189: for (i=0; i<NumExtensions; i++) ! 190: { ! 191: int len; ! 192: *bufptr++ = len = strlen(extensions[i]->name); ! 193: bcopy(extensions[i]->name, bufptr, len); ! 194: bufptr += len; ! 195: } ! 196: } ! 197: WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply); ! 198: if (reply.length) ! 199: { ! 200: WriteToClient(client, total_length, buffer); ! 201: DEALLOCATE_LOCAL(buffer); ! 202: } ! 203: return(client->noClientException); ! 204: } ! 205: ! 206: ! 207: ExtensionLookupProc ! 208: LookupProc(name, pGC) ! 209: char *name; ! 210: GCPtr pGC; ! 211: { ! 212: register int i; ! 213: ScreenProcEntry spentry; ! 214: spentry = AuxillaryScreenProcs[pGC->pScreen->myNum]; ! 215: if (spentry.num) ! 216: { ! 217: for (i = 0; i < spentry.num; i++) ! 218: if (strcmp(name, spentry.procList[i].name) == 0) ! 219: return(spentry.procList[i].proc); ! 220: } ! 221: return (ExtensionLookupProc)NULL; ! 222: } ! 223: ! 224: void ! 225: RegisterProc(name, pGC, proc) ! 226: char *name; ! 227: GC *pGC; ! 228: ExtensionLookupProc proc; ! 229: { ! 230: RegisterScreenProc(name, pGC->pScreen, proc); ! 231: } ! 232: ! 233: void ! 234: RegisterScreenProc(name, pScreen, proc) ! 235: char *name; ! 236: ScreenPtr pScreen; ! 237: ExtensionLookupProc proc; ! 238: { ! 239: ScreenProcEntry *spentry; ! 240: ProcEntryPtr procEntry = (ProcEntryPtr)NULL; ! 241: int i; ! 242: ! 243: spentry = &AuxillaryScreenProcs[pScreen->myNum]; ! 244: /* first replace duplicates */ ! 245: if (spentry->num) ! 246: { ! 247: for (i = 0; i < spentry->num; i++) ! 248: if (strcmp(name, spentry->procList[i].name) == 0) ! 249: { ! 250: procEntry = &spentry->procList[i]; ! 251: break; ! 252: } ! 253: } ! 254: if (procEntry) ! 255: procEntry->proc = proc; ! 256: else ! 257: { ! 258: if (spentry->num) ! 259: spentry->procList = (ProcEntryPtr) ! 260: Xrealloc(spentry->procList, ! 261: sizeof(ProcEntryRec) * (spentry->num+1)); ! 262: else ! 263: spentry->procList = (ProcEntryPtr) ! 264: Xalloc(sizeof(ProcEntryRec)); ! 265: procEntry = &spentry->procList[spentry->num]; ! 266: procEntry->name = (char *)Xalloc(strlen(name)+1); ! 267: strcpy(procEntry->name, name); ! 268: procEntry->proc = proc; ! 269: spentry->num++; ! 270: } ! 271: } ! 272: ! 273: ! 274: /***************** ! 275: * SendErrorToClient ! 276: * Send an Error back to the client. ! 277: *****************/ ! 278: ! 279: SendErrorToClient (client, reqCode, minorCode, resId, status) ! 280: ClientPtr client; ! 281: char reqCode, minorCode, status; ! 282: XID resId; ! 283: { ! 284: xError rep; ! 285: ! 286: rep.type = X_Error; ! 287: rep.sequenceNumber = client->sequence; ! 288: rep.errorCode = status; ! 289: rep.majorCode = reqCode; ! 290: rep.minorCode = minorCode; ! 291: rep.resourceID = resId; ! 292: ! 293: #ifdef notdef ! 294: ErrorF("SendErrorToClient %x\n", client->index); ! 295: ErrorF(" sequenceNumber = %d\n", rep.sequenceNumber); ! 296: ErrorF(" rep.errorCode= %d\n", rep.errorCode); ! 297: ErrorF(" rep.majorCode = %d\n", rep.majorCode); ! 298: ErrorF(" rep.resourceID = %x\n", rep.resourceID); ! 299: #endif ! 300: ! 301: WriteEventsToClient (client, 1, (pointer) &rep); ! 302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.