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