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