1 /*
2
3 Copyright 1987, 1998 The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
25 from The Open Group.
26
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 #include <X11/Xlibint.h>
33 #include <X11/Xos.h>
34 #include <stdio.h>
35
36 /*
37 * This routine is used to link a extension in so it will be called
38 * at appropriate times.
39 */
40
XInitExtension(Display * dpy,_Xconst char * name)41 XExtCodes *XInitExtension (
42 Display *dpy,
43 _Xconst char *name)
44 {
45 XExtCodes codes; /* temp. place for extension information. */
46 register _XExtension *ext;/* need a place to build it all */
47 if (!XQueryExtension(dpy, name,
48 &codes.major_opcode, &codes.first_event,
49 &codes.first_error)) return (NULL);
50
51 LockDisplay (dpy);
52 if (! (ext = Xcalloc (1, sizeof (_XExtension))) ||
53 ! (ext->name = strdup(name))) {
54 Xfree(ext);
55 UnlockDisplay(dpy);
56 return (XExtCodes *) NULL;
57 }
58 codes.extension = dpy->ext_number++;
59 ext->codes = codes;
60
61 /* chain it onto the display list */
62 ext->next = dpy->ext_procs;
63 dpy->ext_procs = ext;
64 UnlockDisplay (dpy);
65
66 return (&ext->codes); /* tell him which extension */
67 }
68
XAddExtension(Display * dpy)69 XExtCodes *XAddExtension (Display *dpy)
70 {
71 register _XExtension *ext;
72
73 LockDisplay (dpy);
74 if (! (ext = Xcalloc (1, sizeof (_XExtension)))) {
75 UnlockDisplay(dpy);
76 return (XExtCodes *) NULL;
77 }
78 ext->codes.extension = dpy->ext_number++;
79
80 /* chain it onto the display list */
81 ext->next = dpy->ext_procs;
82 dpy->ext_procs = ext;
83 UnlockDisplay (dpy);
84
85 return (&ext->codes); /* tell him which extension */
86 }
87
XLookupExtension(register Display * dpy,register int extension)88 static _XExtension *XLookupExtension (
89 register Display *dpy, /* display */
90 register int extension) /* extension number */
91 {
92 register _XExtension *ext;
93 for (ext = dpy->ext_procs; ext; ext = ext->next)
94 if (ext->codes.extension == extension) return (ext);
95 return (NULL);
96 }
97
XEHeadOfExtensionList(XEDataObject object)98 XExtData **XEHeadOfExtensionList(XEDataObject object)
99 {
100 return *(XExtData ***)&object;
101 }
102
103 int
XAddToExtensionList(XExtData ** structure,XExtData * ext_data)104 XAddToExtensionList(
105 XExtData **structure,
106 XExtData *ext_data)
107 {
108 ext_data->next = *structure;
109 *structure = ext_data;
110 return 1;
111 }
112
XFindOnExtensionList(XExtData ** structure,int number)113 XExtData *XFindOnExtensionList(
114 XExtData **structure,
115 int number)
116 {
117 XExtData *ext;
118
119 ext = *structure;
120 while (ext && (ext->number != number))
121 ext = ext->next;
122 return ext;
123 }
124
125 /*
126 * Routines to hang procs on the extension structure.
127 */
XESetCreateGC(Display * dpy,int extension,CreateGCType proc)128 CreateGCType XESetCreateGC(
129 Display *dpy, /* display */
130 int extension, /* extension number */
131 CreateGCType proc) /* routine to call when GC created */
132 {
133 register _XExtension *e; /* for lookup of extension */
134 register CreateGCType oldproc;
135 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
136 LockDisplay(dpy);
137 oldproc = e->create_GC;
138 e->create_GC = proc;
139 UnlockDisplay(dpy);
140 return (CreateGCType)oldproc;
141 }
142
XESetCopyGC(Display * dpy,int extension,CopyGCType proc)143 CopyGCType XESetCopyGC(
144 Display *dpy, /* display */
145 int extension, /* extension number */
146 CopyGCType proc) /* routine to call when GC copied */
147 {
148 register _XExtension *e; /* for lookup of extension */
149 register CopyGCType oldproc;
150 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
151 LockDisplay(dpy);
152 oldproc = e->copy_GC;
153 e->copy_GC = proc;
154 UnlockDisplay(dpy);
155 return (CopyGCType)oldproc;
156 }
157
XESetFlushGC(Display * dpy,int extension,FlushGCType proc)158 FlushGCType XESetFlushGC(
159 Display *dpy, /* display */
160 int extension, /* extension number */
161 FlushGCType proc) /* routine to call when GC copied */
162 {
163 register _XExtension *e; /* for lookup of extension */
164 register FlushGCType oldproc;
165 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
166 LockDisplay(dpy);
167 oldproc = e->flush_GC;
168 e->flush_GC = proc;
169 UnlockDisplay(dpy);
170 return (FlushGCType)oldproc;
171 }
172
XESetFreeGC(Display * dpy,int extension,FreeGCType proc)173 FreeGCType XESetFreeGC(
174 Display *dpy, /* display */
175 int extension, /* extension number */
176 FreeGCType proc) /* routine to call when GC freed */
177 {
178 register _XExtension *e; /* for lookup of extension */
179 register FreeGCType oldproc;
180 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
181 LockDisplay(dpy);
182 oldproc = e->free_GC;
183 e->free_GC = proc;
184 UnlockDisplay(dpy);
185 return (FreeGCType)oldproc;
186 }
187
XESetCreateFont(Display * dpy,int extension,CreateFontType proc)188 CreateFontType XESetCreateFont(
189 Display *dpy, /* display */
190 int extension, /* extension number */
191 CreateFontType proc) /* routine to call when font created */
192 {
193 register _XExtension *e; /* for lookup of extension */
194 register CreateFontType oldproc;
195 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
196 LockDisplay(dpy);
197 oldproc = e->create_Font;
198 e->create_Font = proc;
199 UnlockDisplay(dpy);
200 return (CreateFontType)oldproc;
201 }
202
XESetFreeFont(Display * dpy,int extension,FreeFontType proc)203 FreeFontType XESetFreeFont(
204 Display *dpy, /* display */
205 int extension, /* extension number */
206 FreeFontType proc) /* routine to call when font freed */
207 {
208 register _XExtension *e; /* for lookup of extension */
209 register FreeFontType oldproc;
210 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
211 LockDisplay(dpy);
212 oldproc = e->free_Font;
213 e->free_Font = proc;
214 UnlockDisplay(dpy);
215 return (FreeFontType)oldproc;
216 }
217
XESetCloseDisplay(Display * dpy,int extension,CloseDisplayType proc)218 CloseDisplayType XESetCloseDisplay(
219 Display *dpy, /* display */
220 int extension, /* extension number */
221 CloseDisplayType proc) /* routine to call when display closed */
222 {
223 register _XExtension *e; /* for lookup of extension */
224 register CloseDisplayType oldproc;
225 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
226 LockDisplay(dpy);
227 oldproc = e->close_display;
228 e->close_display = proc;
229 UnlockDisplay(dpy);
230 return (CloseDisplayType)oldproc;
231 }
232
233 typedef Bool (*WireToEventType) (
234 Display* /* display */,
235 XEvent* /* re */,
236 xEvent* /* event */
237 );
238
XESetWireToEvent(Display * dpy,int event_number,WireToEventType proc)239 WireToEventType XESetWireToEvent(
240 Display *dpy, /* display */
241 int event_number, /* event routine to replace */
242 WireToEventType proc) /* routine to call when converting event */
243 {
244 register WireToEventType oldproc;
245 if (proc == NULL) proc = (WireToEventType)_XUnknownWireEvent;
246 LockDisplay (dpy);
247 oldproc = dpy->event_vec[event_number];
248 dpy->event_vec[event_number] = proc;
249 UnlockDisplay (dpy);
250 return (WireToEventType)oldproc;
251 }
252
253 typedef Bool (*WireToEventCookieType) (
254 Display* /* display */,
255 XGenericEventCookie* /* re */,
256 xEvent* /* event */
257 );
258
XESetWireToEventCookie(Display * dpy,int extension,WireToEventCookieType proc)259 WireToEventCookieType XESetWireToEventCookie(
260 Display *dpy, /* display */
261 int extension, /* extension major opcode */
262 WireToEventCookieType proc /* routine to call for generic events */
263 )
264 {
265 WireToEventCookieType oldproc;
266 if (proc == NULL) proc = (WireToEventCookieType)_XUnknownWireEventCookie;
267 LockDisplay (dpy);
268 oldproc = dpy->generic_event_vec[extension & 0x7F];
269 dpy->generic_event_vec[extension & 0x7F] = proc;
270 UnlockDisplay (dpy);
271 return (WireToEventCookieType)oldproc;
272 }
273
274 typedef Bool (*CopyEventCookieType) (
275 Display* /* display */,
276 XGenericEventCookie* /* in */,
277 XGenericEventCookie* /* out */
278 );
279
XESetCopyEventCookie(Display * dpy,int extension,CopyEventCookieType proc)280 CopyEventCookieType XESetCopyEventCookie(
281 Display *dpy, /* display */
282 int extension, /* extension major opcode */
283 CopyEventCookieType proc /* routine to copy generic events */
284 )
285 {
286 CopyEventCookieType oldproc;
287 if (proc == NULL) proc = (CopyEventCookieType)_XUnknownCopyEventCookie;
288 LockDisplay (dpy);
289 oldproc = dpy->generic_event_copy_vec[extension & 0x7F];
290 dpy->generic_event_copy_vec[extension & 0x7F] = proc;
291 UnlockDisplay (dpy);
292 return (CopyEventCookieType)oldproc;
293 }
294
295
296 typedef Status (*EventToWireType) (
297 Display* /* display */,
298 XEvent* /* re */,
299 xEvent* /* event */
300 );
301
XESetEventToWire(Display * dpy,int event_number,EventToWireType proc)302 EventToWireType XESetEventToWire(
303 Display *dpy, /* display */
304 int event_number, /* event routine to replace */
305 EventToWireType proc) /* routine to call when converting event */
306 {
307 register EventToWireType oldproc;
308 if (proc == NULL) proc = (EventToWireType) _XUnknownNativeEvent;
309 LockDisplay (dpy);
310 oldproc = dpy->wire_vec[event_number];
311 dpy->wire_vec[event_number] = proc;
312 UnlockDisplay(dpy);
313 return (EventToWireType)oldproc;
314 }
315
316 typedef Bool (*WireToErrorType) (
317 Display* /* display */,
318 XErrorEvent* /* he */,
319 xError* /* we */
320 );
321
XESetWireToError(Display * dpy,int error_number,WireToErrorType proc)322 WireToErrorType XESetWireToError(
323 Display *dpy, /* display */
324 int error_number, /* error routine to replace */
325 WireToErrorType proc) /* routine to call when converting error */
326 {
327 register WireToErrorType oldproc = NULL;
328 if (proc == NULL) proc = (WireToErrorType)_XDefaultWireError;
329 LockDisplay (dpy);
330 if (!dpy->error_vec) {
331 int i;
332 dpy->error_vec = Xmalloc(256 * sizeof(oldproc));
333 for (i = 1; i < 256; i++)
334 dpy->error_vec[i] = _XDefaultWireError;
335 }
336 if (dpy->error_vec) {
337 oldproc = dpy->error_vec[error_number];
338 dpy->error_vec[error_number] = proc;
339 }
340 UnlockDisplay (dpy);
341 return (WireToErrorType)oldproc;
342 }
343
XESetError(Display * dpy,int extension,ErrorType proc)344 ErrorType XESetError(
345 Display *dpy, /* display */
346 int extension, /* extension number */
347 ErrorType proc) /* routine to call when X error happens */
348 {
349 register _XExtension *e; /* for lookup of extension */
350 register ErrorType oldproc;
351 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
352 LockDisplay(dpy);
353 oldproc = e->error;
354 e->error = proc;
355 UnlockDisplay(dpy);
356 return (ErrorType)oldproc;
357 }
358
XESetErrorString(Display * dpy,int extension,ErrorStringType proc)359 ErrorStringType XESetErrorString(
360 Display *dpy, /* display */
361 int extension, /* extension number */
362 ErrorStringType proc) /* routine to call when I/O error happens */
363 {
364 register _XExtension *e; /* for lookup of extension */
365 register ErrorStringType oldproc;
366 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
367 LockDisplay(dpy);
368 oldproc = e->error_string;
369 e->error_string = proc;
370 UnlockDisplay(dpy);
371 return (ErrorStringType)oldproc;
372 }
373
XESetPrintErrorValues(Display * dpy,int extension,PrintErrorType proc)374 PrintErrorType XESetPrintErrorValues(
375 Display *dpy, /* display */
376 int extension, /* extension number */
377 PrintErrorType proc) /* routine to call to print */
378 {
379 register _XExtension *e; /* for lookup of extension */
380 register PrintErrorType oldproc;
381 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
382 LockDisplay(dpy);
383 oldproc = e->error_values;
384 e->error_values = proc;
385 UnlockDisplay(dpy);
386 return (PrintErrorType)oldproc;
387 }
388
XESetBeforeFlush(Display * dpy,int extension,BeforeFlushType proc)389 BeforeFlushType XESetBeforeFlush(
390 Display *dpy, /* display */
391 int extension, /* extension number */
392 BeforeFlushType proc) /* routine to call on flush */
393 {
394 register _XExtension *e; /* for lookup of extension */
395 register BeforeFlushType oldproc;
396 register _XExtension *ext;
397 if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
398 LockDisplay(dpy);
399 oldproc = e->before_flush;
400 e->before_flush = proc;
401 for (ext = dpy->flushes; ext && ext != e; ext = ext->next)
402 ;
403 if (!ext) {
404 e->next_flush = dpy->flushes;
405 dpy->flushes = e;
406 }
407 UnlockDisplay(dpy);
408 return (BeforeFlushType)oldproc;
409 }
410