InitExt.c revision eb411b4b
1/*
2
3Copyright 1987, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from 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
41XExtCodes *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	    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
69XExtCodes *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
88static _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
98XExtData **XEHeadOfExtensionList(XEDataObject object)
99{
100    return *(XExtData ***)&object;
101}
102
103int
104XAddToExtensionList(
105    XExtData **structure,
106    XExtData *ext_data)
107{
108    ext_data->next = *structure;
109    *structure = ext_data;
110    return 1;
111}
112
113XExtData *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 */
128CreateGCType 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
143CopyGCType 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
158FlushGCType 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
173FreeGCType 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
188CreateFontType 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
203FreeFontType 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
218CloseDisplayType 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
233typedef Bool (*WireToEventType) (
234    Display*	/* display */,
235    XEvent*	/* re */,
236    xEvent*	/* event */
237);
238
239WireToEventType 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
253typedef Bool (*WireToEventCookieType) (
254    Display*	/* display */,
255    XGenericEventCookie*	/* re */,
256    xEvent*	/* event */
257);
258
259WireToEventCookieType 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
274typedef Bool (*CopyEventCookieType) (
275    Display*	/* display */,
276    XGenericEventCookie*	/* in */,
277    XGenericEventCookie*	/* out */
278);
279
280CopyEventCookieType 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
296typedef Status (*EventToWireType) (
297    Display*	/* display */,
298    XEvent*	/* re */,
299    xEvent*	/* event */
300);
301
302EventToWireType 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
316typedef Bool (*WireToErrorType) (
317    Display*	/* display */,
318    XErrorEvent* /* he */,
319    xError*	/* we */
320);
321
322WireToErrorType 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
344ErrorType 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
359ErrorStringType 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
374PrintErrorType 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
389BeforeFlushType 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