19515ccd03da1b525f6feca1f84983d75cf0fbf1
[platform/upstream/libX11.git] / src / InitExt.c
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
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 = (_XExtension *) Xcalloc (1, sizeof (_XExtension))) ||
53             ! (ext->name = strdup(name))) {
54             if (ext) Xfree((char *) 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
69 XExtCodes *XAddExtension (Display *dpy)
70 {
71     register _XExtension *ext;
72
73     LockDisplay (dpy);
74     if (! (ext = (_XExtension *) 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
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
98 XExtData **XEHeadOfExtensionList(XEDataObject object)
99 {
100     return *(XExtData ***)&object;
101 }
102
103 int
104 XAddToExtensionList(
105     XExtData **structure,
106     XExtData *ext_data)
107 {
108     ext_data->next = *structure;
109     *structure = ext_data;
110     return 1;
111 }
112
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  */
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }