InitExt.c revision b4ee4795
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 = (_XExtension *) Xcalloc (1, sizeof (_XExtension))) ||
53	    ! (ext->name = Xmalloc((unsigned) strlen(name) + 1))) {
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	(void) strcpy(ext->name, name);
61
62	/* chain it onto the display list */
63	ext->next = dpy->ext_procs;
64	dpy->ext_procs = ext;
65	UnlockDisplay (dpy);
66
67	return (&ext->codes);		/* tell him which extension */
68}
69
70XExtCodes *XAddExtension (Display *dpy)
71{
72    register _XExtension *ext;
73
74    LockDisplay (dpy);
75    if (! (ext = (_XExtension *) Xcalloc (1, sizeof (_XExtension)))) {
76	UnlockDisplay(dpy);
77	return (XExtCodes *) NULL;
78    }
79    ext->codes.extension = dpy->ext_number++;
80
81    /* chain it onto the display list */
82    ext->next = dpy->ext_procs;
83    dpy->ext_procs = ext;
84    UnlockDisplay (dpy);
85
86    return (&ext->codes);		/* tell him which extension */
87}
88
89static _XExtension *XLookupExtension (
90	register Display *dpy,	/* display */
91	register int extension)	/* extension number */
92{
93	register _XExtension *ext;
94	for (ext = dpy->ext_procs; ext; ext = ext->next)
95	    if (ext->codes.extension == extension) return (ext);
96	return (NULL);
97}
98
99XExtData **XEHeadOfExtensionList(XEDataObject object)
100{
101    return *(XExtData ***)&object;
102}
103
104int
105XAddToExtensionList(
106    XExtData **structure,
107    XExtData *ext_data)
108{
109    ext_data->next = *structure;
110    *structure = ext_data;
111    return 1;
112}
113
114XExtData *XFindOnExtensionList(
115    XExtData **structure,
116    int number)
117{
118    XExtData *ext;
119
120    ext = *structure;
121    while (ext && (ext->number != number))
122	ext = ext->next;
123    return ext;
124}
125
126/*
127 * Routines to hang procs on the extension structure.
128 */
129CreateGCType XESetCreateGC(
130	Display *dpy,		/* display */
131	int extension,		/* extension number */
132	CreateGCType proc)	/* routine to call when GC created */
133{
134	register _XExtension *e;	/* for lookup of extension */
135	register CreateGCType oldproc;
136	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
137	LockDisplay(dpy);
138	oldproc = e->create_GC;
139	e->create_GC = proc;
140	UnlockDisplay(dpy);
141	return (CreateGCType)oldproc;
142}
143
144CopyGCType XESetCopyGC(
145	Display *dpy,		/* display */
146	int extension,		/* extension number */
147	CopyGCType proc)	/* routine to call when GC copied */
148{
149	register _XExtension *e;	/* for lookup of extension */
150	register CopyGCType oldproc;
151	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
152	LockDisplay(dpy);
153	oldproc = e->copy_GC;
154	e->copy_GC = proc;
155	UnlockDisplay(dpy);
156	return (CopyGCType)oldproc;
157}
158
159FlushGCType XESetFlushGC(
160	Display *dpy,		/* display */
161	int extension,		/* extension number */
162	FlushGCType proc)	/* routine to call when GC copied */
163{
164	register _XExtension *e;	/* for lookup of extension */
165	register FlushGCType oldproc;
166	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
167	LockDisplay(dpy);
168	oldproc = e->flush_GC;
169	e->flush_GC = proc;
170	UnlockDisplay(dpy);
171	return (FlushGCType)oldproc;
172}
173
174FreeGCType XESetFreeGC(
175	Display *dpy,		/* display */
176	int extension,		/* extension number */
177	FreeGCType proc)	/* routine to call when GC freed */
178{
179	register _XExtension *e;	/* for lookup of extension */
180	register FreeGCType oldproc;
181	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
182	LockDisplay(dpy);
183	oldproc = e->free_GC;
184	e->free_GC = proc;
185	UnlockDisplay(dpy);
186	return (FreeGCType)oldproc;
187}
188
189CreateFontType XESetCreateFont(
190	Display *dpy,		/* display */
191	int extension,		/* extension number */
192	CreateFontType proc)	/* routine to call when font created */
193{
194	register _XExtension *e;	/* for lookup of extension */
195	register CreateFontType oldproc;
196	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
197	LockDisplay(dpy);
198	oldproc = e->create_Font;
199	e->create_Font = proc;
200	UnlockDisplay(dpy);
201	return (CreateFontType)oldproc;
202}
203
204FreeFontType XESetFreeFont(
205	Display *dpy,		/* display */
206	int extension,		/* extension number */
207	FreeFontType proc)	/* routine to call when font freed */
208{
209	register _XExtension *e;	/* for lookup of extension */
210	register FreeFontType oldproc;
211	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
212	LockDisplay(dpy);
213	oldproc = e->free_Font;
214	e->free_Font = proc;
215	UnlockDisplay(dpy);
216	return (FreeFontType)oldproc;
217}
218
219CloseDisplayType XESetCloseDisplay(
220	Display *dpy,		/* display */
221	int extension,		/* extension number */
222	CloseDisplayType proc)	/* routine to call when display closed */
223{
224	register _XExtension *e;	/* for lookup of extension */
225	register CloseDisplayType oldproc;
226	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
227	LockDisplay(dpy);
228	oldproc = e->close_display;
229	e->close_display = proc;
230	UnlockDisplay(dpy);
231	return (CloseDisplayType)oldproc;
232}
233
234typedef Bool (*WireToEventType) (
235    Display*	/* display */,
236    XEvent*	/* re */,
237    xEvent*	/* event */
238);
239
240WireToEventType XESetWireToEvent(
241	Display *dpy,		/* display */
242	int event_number,	/* event routine to replace */
243	WireToEventType proc)	/* routine to call when converting event */
244{
245	register WireToEventType oldproc;
246	if (proc == NULL) proc = (WireToEventType)_XUnknownWireEvent;
247	LockDisplay (dpy);
248	oldproc = dpy->event_vec[event_number];
249	dpy->event_vec[event_number] = proc;
250	UnlockDisplay (dpy);
251	return (WireToEventType)oldproc;
252}
253
254typedef Bool (*WireToEventCookieType) (
255    Display*	/* display */,
256    XGenericEventCookie*	/* re */,
257    xEvent*	/* event */
258);
259
260WireToEventCookieType XESetWireToEventCookie(
261    Display *dpy,       /* display */
262    int extension,      /* extension major opcode */
263    WireToEventCookieType proc /* routine to call for generic events */
264    )
265{
266	WireToEventCookieType oldproc;
267	if (proc == NULL) proc = (WireToEventCookieType)_XUnknownWireEventCookie;
268	LockDisplay (dpy);
269	oldproc = dpy->generic_event_vec[extension & 0x7F];
270	dpy->generic_event_vec[extension & 0x7F] = proc;
271	UnlockDisplay (dpy);
272	return (WireToEventCookieType)oldproc;
273}
274
275typedef Bool (*CopyEventCookieType) (
276    Display*	/* display */,
277    XGenericEventCookie*	/* in */,
278    XGenericEventCookie*	/* out */
279);
280
281CopyEventCookieType XESetCopyEventCookie(
282    Display *dpy,       /* display */
283    int extension,      /* extension major opcode */
284    CopyEventCookieType proc /* routine to copy generic events */
285    )
286{
287	CopyEventCookieType oldproc;
288	if (proc == NULL) proc = (CopyEventCookieType)_XUnknownCopyEventCookie;
289	LockDisplay (dpy);
290	oldproc = dpy->generic_event_copy_vec[extension & 0x7F];
291	dpy->generic_event_copy_vec[extension & 0x7F] = proc;
292	UnlockDisplay (dpy);
293	return (CopyEventCookieType)oldproc;
294}
295
296
297typedef Status (*EventToWireType) (
298    Display*	/* display */,
299    XEvent*	/* re */,
300    xEvent*	/* event */
301);
302
303EventToWireType XESetEventToWire(
304	Display *dpy,		/* display */
305	int event_number,	/* event routine to replace */
306	EventToWireType proc)	/* routine to call when converting event */
307{
308	register EventToWireType oldproc;
309	if (proc == NULL) proc = (EventToWireType) _XUnknownNativeEvent;
310	LockDisplay (dpy);
311	oldproc = dpy->wire_vec[event_number];
312	dpy->wire_vec[event_number] = proc;
313	UnlockDisplay(dpy);
314	return (EventToWireType)oldproc;
315}
316
317typedef Bool (*WireToErrorType) (
318    Display*	/* display */,
319    XErrorEvent* /* he */,
320    xError*	/* we */
321);
322
323WireToErrorType XESetWireToError(
324	Display *dpy,		/* display */
325	int error_number,	/* error routine to replace */
326	WireToErrorType proc)	/* routine to call when converting error */
327{
328	register WireToErrorType oldproc = NULL;
329	if (proc == NULL) proc = (WireToErrorType)_XDefaultWireError;
330	LockDisplay (dpy);
331	if (!dpy->error_vec) {
332	    int i;
333	    dpy->error_vec = Xmalloc(256 * sizeof(oldproc));
334	    for (i = 1; i < 256; i++)
335		dpy->error_vec[i] = _XDefaultWireError;
336	}
337	if (dpy->error_vec) {
338	    oldproc = dpy->error_vec[error_number];
339	    dpy->error_vec[error_number] = proc;
340	}
341	UnlockDisplay (dpy);
342	return (WireToErrorType)oldproc;
343}
344
345ErrorType XESetError(
346	Display *dpy,		/* display */
347	int extension,		/* extension number */
348	ErrorType proc)		/* routine to call when X error happens */
349{
350	register _XExtension *e;	/* for lookup of extension */
351	register ErrorType oldproc;
352	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
353	LockDisplay(dpy);
354	oldproc = e->error;
355	e->error = proc;
356	UnlockDisplay(dpy);
357	return (ErrorType)oldproc;
358}
359
360ErrorStringType XESetErrorString(
361	Display *dpy,		/* display */
362	int extension,		/* extension number */
363	ErrorStringType proc)	/* routine to call when I/O error happens */
364{
365	register _XExtension *e;	/* for lookup of extension */
366	register ErrorStringType oldproc;
367	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
368	LockDisplay(dpy);
369	oldproc = e->error_string;
370	e->error_string = proc;
371	UnlockDisplay(dpy);
372	return (ErrorStringType)oldproc;
373}
374
375PrintErrorType XESetPrintErrorValues(
376	Display *dpy,		/* display */
377	int extension,		/* extension number */
378	PrintErrorType proc)	/* routine to call to print */
379{
380	register _XExtension *e;	/* for lookup of extension */
381	register PrintErrorType oldproc;
382	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
383	LockDisplay(dpy);
384	oldproc = e->error_values;
385	e->error_values = proc;
386	UnlockDisplay(dpy);
387	return (PrintErrorType)oldproc;
388}
389
390BeforeFlushType XESetBeforeFlush(
391	Display *dpy,		/* display */
392	int extension,		/* extension number */
393	BeforeFlushType proc)	/* routine to call on flush */
394{
395	register _XExtension *e;	/* for lookup of extension */
396	register BeforeFlushType oldproc;
397	register _XExtension *ext;
398	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
399	LockDisplay(dpy);
400	oldproc = e->before_flush;
401	e->before_flush = proc;
402	for (ext = dpy->flushes; ext && ext != e; ext = ext->next)
403	    ;
404	if (!ext) {
405	    e->next_flush = dpy->flushes;
406	    dpy->flushes = e;
407	}
408	UnlockDisplay(dpy);
409	return (BeforeFlushType)oldproc;
410}
411