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