11ab64890Smrg/*
21ab64890Smrg
31ab64890SmrgCopyright 1987, 1998  The Open Group
41ab64890Smrg
51ab64890SmrgPermission to use, copy, modify, distribute, and sell this software and its
61ab64890Smrgdocumentation for any purpose is hereby granted without fee, provided that
71ab64890Smrgthe above copyright notice appear in all copies and that both that
81ab64890Smrgcopyright notice and this permission notice appear in supporting
91ab64890Smrgdocumentation.
101ab64890Smrg
111ab64890SmrgThe above copyright notice and this permission notice shall be included
121ab64890Smrgin all copies or substantial portions of the Software.
131ab64890Smrg
141ab64890SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
151ab64890SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
161ab64890SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
171ab64890SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
181ab64890SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
191ab64890SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
201ab64890SmrgOTHER DEALINGS IN THE SOFTWARE.
211ab64890Smrg
221ab64890SmrgExcept as contained in this notice, the name of The Open Group shall
231ab64890Smrgnot be used in advertising or otherwise to promote the sale, use or
241ab64890Smrgother dealings in this Software without prior written authorization
251ab64890Smrgfrom The Open Group.
261ab64890Smrg
271ab64890Smrg*/
281ab64890Smrg
291ab64890Smrg#ifdef HAVE_CONFIG_H
301ab64890Smrg#include <config.h>
311ab64890Smrg#endif
321ab64890Smrg#include <X11/Xlibint.h>
331ab64890Smrg#include <X11/Xos.h>
341ab64890Smrg#include <stdio.h>
351ab64890Smrg
367d2c738bSmrg/* The X11 protocol spec reserves events 64 through 127 for extensions */
377d2c738bSmrg#ifndef LastExtensionEvent
387d2c738bSmrg#define LastExtensionEvent 127
397d2c738bSmrg#endif
407d2c738bSmrg
417d2c738bSmrg/* The X11 protocol spec reserves requests 128 through 255 for extensions */
427d2c738bSmrg#ifndef LastExtensionRequest
437d2c738bSmrg#define FirstExtensionRequest 128
447d2c738bSmrg#define LastExtensionRequest 255
457d2c738bSmrg#endif
467d2c738bSmrg
477d2c738bSmrg
481ab64890Smrg/*
491ab64890Smrg * This routine is used to link a extension in so it will be called
501ab64890Smrg * at appropriate times.
511ab64890Smrg */
521ab64890Smrg
531ab64890SmrgXExtCodes *XInitExtension (
541ab64890Smrg	Display *dpy,
551ab64890Smrg	_Xconst char *name)
561ab64890Smrg{
571ab64890Smrg	XExtCodes codes;	/* temp. place for extension information. */
581ab64890Smrg	register _XExtension *ext;/* need a place to build it all */
5961b2299dSmrg	if (!XQueryExtension(dpy, name,
601ab64890Smrg		&codes.major_opcode, &codes.first_event,
611ab64890Smrg		&codes.first_error)) return (NULL);
621ab64890Smrg
631ab64890Smrg	LockDisplay (dpy);
64eb411b4bSmrg	if (! (ext = Xcalloc (1, sizeof (_XExtension))) ||
656cc2b21fSmrg	    ! (ext->name = strdup(name))) {
660f8248bfSmrg	    Xfree(ext);
671ab64890Smrg	    UnlockDisplay(dpy);
681ab64890Smrg	    return (XExtCodes *) NULL;
691ab64890Smrg	}
701ab64890Smrg	codes.extension = dpy->ext_number++;
711ab64890Smrg	ext->codes = codes;
721ab64890Smrg
7361b2299dSmrg	/* chain it onto the display list */
741ab64890Smrg	ext->next = dpy->ext_procs;
751ab64890Smrg	dpy->ext_procs = ext;
761ab64890Smrg	UnlockDisplay (dpy);
771ab64890Smrg
781ab64890Smrg	return (&ext->codes);		/* tell him which extension */
791ab64890Smrg}
801ab64890Smrg
811ab64890SmrgXExtCodes *XAddExtension (Display *dpy)
821ab64890Smrg{
831ab64890Smrg    register _XExtension *ext;
841ab64890Smrg
851ab64890Smrg    LockDisplay (dpy);
86eb411b4bSmrg    if (! (ext = Xcalloc (1, sizeof (_XExtension)))) {
871ab64890Smrg	UnlockDisplay(dpy);
881ab64890Smrg	return (XExtCodes *) NULL;
891ab64890Smrg    }
901ab64890Smrg    ext->codes.extension = dpy->ext_number++;
911ab64890Smrg
921ab64890Smrg    /* chain it onto the display list */
931ab64890Smrg    ext->next = dpy->ext_procs;
941ab64890Smrg    dpy->ext_procs = ext;
951ab64890Smrg    UnlockDisplay (dpy);
961ab64890Smrg
971ab64890Smrg    return (&ext->codes);		/* tell him which extension */
981ab64890Smrg}
991ab64890Smrg
1001ab64890Smrgstatic _XExtension *XLookupExtension (
1011ab64890Smrg	register Display *dpy,	/* display */
1021ab64890Smrg	register int extension)	/* extension number */
1031ab64890Smrg{
1041ab64890Smrg	register _XExtension *ext;
1051ab64890Smrg	for (ext = dpy->ext_procs; ext; ext = ext->next)
1061ab64890Smrg	    if (ext->codes.extension == extension) return (ext);
1071ab64890Smrg	return (NULL);
1081ab64890Smrg}
1091ab64890Smrg
1101ab64890SmrgXExtData **XEHeadOfExtensionList(XEDataObject object)
1111ab64890Smrg{
1121ab64890Smrg    return *(XExtData ***)&object;
1131ab64890Smrg}
1141ab64890Smrg
1151ab64890Smrgint
1161ab64890SmrgXAddToExtensionList(
1171ab64890Smrg    XExtData **structure,
1181ab64890Smrg    XExtData *ext_data)
1191ab64890Smrg{
1201ab64890Smrg    ext_data->next = *structure;
1211ab64890Smrg    *structure = ext_data;
1221ab64890Smrg    return 1;
1231ab64890Smrg}
1241ab64890Smrg
1251ab64890SmrgXExtData *XFindOnExtensionList(
1261ab64890Smrg    XExtData **structure,
1271ab64890Smrg    int number)
1281ab64890Smrg{
1291ab64890Smrg    XExtData *ext;
1301ab64890Smrg
1311ab64890Smrg    ext = *structure;
1321ab64890Smrg    while (ext && (ext->number != number))
1331ab64890Smrg	ext = ext->next;
1341ab64890Smrg    return ext;
1351ab64890Smrg}
1361ab64890Smrg
1371ab64890Smrg/*
1381ab64890Smrg * Routines to hang procs on the extension structure.
1391ab64890Smrg */
1401ab64890SmrgCreateGCType XESetCreateGC(
1411ab64890Smrg	Display *dpy,		/* display */
1421ab64890Smrg	int extension,		/* extension number */
1431ab64890Smrg	CreateGCType proc)	/* routine to call when GC created */
1441ab64890Smrg{
1451ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
1461ab64890Smrg	register CreateGCType oldproc;
1471ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
1481ab64890Smrg	LockDisplay(dpy);
1491ab64890Smrg	oldproc = e->create_GC;
1501ab64890Smrg	e->create_GC = proc;
1511ab64890Smrg	UnlockDisplay(dpy);
1521ab64890Smrg	return (CreateGCType)oldproc;
1531ab64890Smrg}
1541ab64890Smrg
1551ab64890SmrgCopyGCType XESetCopyGC(
1561ab64890Smrg	Display *dpy,		/* display */
1571ab64890Smrg	int extension,		/* extension number */
1581ab64890Smrg	CopyGCType proc)	/* routine to call when GC copied */
1591ab64890Smrg{
1601ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
1611ab64890Smrg	register CopyGCType oldproc;
1621ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
1631ab64890Smrg	LockDisplay(dpy);
1641ab64890Smrg	oldproc = e->copy_GC;
1651ab64890Smrg	e->copy_GC = proc;
1661ab64890Smrg	UnlockDisplay(dpy);
1671ab64890Smrg	return (CopyGCType)oldproc;
1681ab64890Smrg}
1691ab64890Smrg
1701ab64890SmrgFlushGCType XESetFlushGC(
1711ab64890Smrg	Display *dpy,		/* display */
1721ab64890Smrg	int extension,		/* extension number */
1731ab64890Smrg	FlushGCType proc)	/* routine to call when GC copied */
1741ab64890Smrg{
1751ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
1761ab64890Smrg	register FlushGCType oldproc;
1771ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
1781ab64890Smrg	LockDisplay(dpy);
1791ab64890Smrg	oldproc = e->flush_GC;
1801ab64890Smrg	e->flush_GC = proc;
1811ab64890Smrg	UnlockDisplay(dpy);
1821ab64890Smrg	return (FlushGCType)oldproc;
1831ab64890Smrg}
1841ab64890Smrg
1851ab64890SmrgFreeGCType XESetFreeGC(
1861ab64890Smrg	Display *dpy,		/* display */
1871ab64890Smrg	int extension,		/* extension number */
1881ab64890Smrg	FreeGCType proc)	/* routine to call when GC freed */
1891ab64890Smrg{
1901ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
1911ab64890Smrg	register FreeGCType oldproc;
1921ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
1931ab64890Smrg	LockDisplay(dpy);
1941ab64890Smrg	oldproc = e->free_GC;
1951ab64890Smrg	e->free_GC = proc;
1961ab64890Smrg	UnlockDisplay(dpy);
1971ab64890Smrg	return (FreeGCType)oldproc;
1981ab64890Smrg}
1991ab64890Smrg
2001ab64890SmrgCreateFontType XESetCreateFont(
2011ab64890Smrg	Display *dpy,		/* display */
2021ab64890Smrg	int extension,		/* extension number */
2031ab64890Smrg	CreateFontType proc)	/* routine to call when font created */
2041ab64890Smrg{
2051ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
2061ab64890Smrg	register CreateFontType oldproc;
2071ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
2081ab64890Smrg	LockDisplay(dpy);
2091ab64890Smrg	oldproc = e->create_Font;
2101ab64890Smrg	e->create_Font = proc;
2111ab64890Smrg	UnlockDisplay(dpy);
2121ab64890Smrg	return (CreateFontType)oldproc;
2131ab64890Smrg}
2141ab64890Smrg
2151ab64890SmrgFreeFontType XESetFreeFont(
2161ab64890Smrg	Display *dpy,		/* display */
2171ab64890Smrg	int extension,		/* extension number */
2181ab64890Smrg	FreeFontType proc)	/* routine to call when font freed */
2191ab64890Smrg{
2201ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
2211ab64890Smrg	register FreeFontType oldproc;
2221ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
2231ab64890Smrg	LockDisplay(dpy);
2241ab64890Smrg	oldproc = e->free_Font;
2251ab64890Smrg	e->free_Font = proc;
2261ab64890Smrg	UnlockDisplay(dpy);
2271ab64890Smrg	return (FreeFontType)oldproc;
2281ab64890Smrg}
2291ab64890Smrg
2301ab64890SmrgCloseDisplayType XESetCloseDisplay(
2311ab64890Smrg	Display *dpy,		/* display */
2321ab64890Smrg	int extension,		/* extension number */
2331ab64890Smrg	CloseDisplayType proc)	/* routine to call when display closed */
2341ab64890Smrg{
2351ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
2361ab64890Smrg	register CloseDisplayType oldproc;
2371ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
2381ab64890Smrg	LockDisplay(dpy);
2391ab64890Smrg	oldproc = e->close_display;
2401ab64890Smrg	e->close_display = proc;
2411ab64890Smrg	UnlockDisplay(dpy);
2421ab64890Smrg	return (CloseDisplayType)oldproc;
2431ab64890Smrg}
2441ab64890Smrg
2451ab64890Smrgtypedef Bool (*WireToEventType) (
2461ab64890Smrg    Display*	/* display */,
2471ab64890Smrg    XEvent*	/* re */,
2481ab64890Smrg    xEvent*	/* event */
2491ab64890Smrg);
2501ab64890Smrg
2511ab64890SmrgWireToEventType XESetWireToEvent(
2521ab64890Smrg	Display *dpy,		/* display */
2531ab64890Smrg	int event_number,	/* event routine to replace */
2541ab64890Smrg	WireToEventType proc)	/* routine to call when converting event */
2551ab64890Smrg{
2561ab64890Smrg	register WireToEventType oldproc;
2577d2c738bSmrg	if (event_number < 0 ||
2587d2c738bSmrg	    event_number > LastExtensionEvent) {
2597d2c738bSmrg	    fprintf(stderr, "Xlib: ignoring invalid extension event %d\n",
2607d2c738bSmrg		    event_number);
2617d2c738bSmrg	    return (WireToEventType)_XUnknownWireEvent;
2627d2c738bSmrg	}
2631ab64890Smrg	if (proc == NULL) proc = (WireToEventType)_XUnknownWireEvent;
2641ab64890Smrg	LockDisplay (dpy);
2651ab64890Smrg	oldproc = dpy->event_vec[event_number];
2661ab64890Smrg	dpy->event_vec[event_number] = proc;
2671ab64890Smrg	UnlockDisplay (dpy);
2681ab64890Smrg	return (WireToEventType)oldproc;
2691ab64890Smrg}
2701ab64890Smrg
271b4ee4795Smrgtypedef Bool (*WireToEventCookieType) (
272b4ee4795Smrg    Display*	/* display */,
273b4ee4795Smrg    XGenericEventCookie*	/* re */,
274b4ee4795Smrg    xEvent*	/* event */
275b4ee4795Smrg);
276b4ee4795Smrg
277b4ee4795SmrgWireToEventCookieType XESetWireToEventCookie(
278b4ee4795Smrg    Display *dpy,       /* display */
279b4ee4795Smrg    int extension,      /* extension major opcode */
280b4ee4795Smrg    WireToEventCookieType proc /* routine to call for generic events */
281b4ee4795Smrg    )
282b4ee4795Smrg{
283b4ee4795Smrg	WireToEventCookieType oldproc;
2847d2c738bSmrg	if (extension < FirstExtensionRequest ||
2857d2c738bSmrg	    extension > LastExtensionRequest) {
2867d2c738bSmrg	    fprintf(stderr, "Xlib: ignoring invalid extension opcode %d\n",
2877d2c738bSmrg		    extension);
2887d2c738bSmrg	    return (WireToEventCookieType)_XUnknownWireEventCookie;
2897d2c738bSmrg	}
290b4ee4795Smrg	if (proc == NULL) proc = (WireToEventCookieType)_XUnknownWireEventCookie;
291b4ee4795Smrg	LockDisplay (dpy);
292b4ee4795Smrg	oldproc = dpy->generic_event_vec[extension & 0x7F];
293b4ee4795Smrg	dpy->generic_event_vec[extension & 0x7F] = proc;
294b4ee4795Smrg	UnlockDisplay (dpy);
295b4ee4795Smrg	return (WireToEventCookieType)oldproc;
296b4ee4795Smrg}
297b4ee4795Smrg
298b4ee4795Smrgtypedef Bool (*CopyEventCookieType) (
299b4ee4795Smrg    Display*	/* display */,
300b4ee4795Smrg    XGenericEventCookie*	/* in */,
301b4ee4795Smrg    XGenericEventCookie*	/* out */
302b4ee4795Smrg);
303b4ee4795Smrg
304b4ee4795SmrgCopyEventCookieType XESetCopyEventCookie(
305b4ee4795Smrg    Display *dpy,       /* display */
306b4ee4795Smrg    int extension,      /* extension major opcode */
307b4ee4795Smrg    CopyEventCookieType proc /* routine to copy generic events */
308b4ee4795Smrg    )
309b4ee4795Smrg{
310b4ee4795Smrg	CopyEventCookieType oldproc;
3117d2c738bSmrg	if (extension < FirstExtensionRequest ||
3127d2c738bSmrg	    extension > LastExtensionRequest) {
3137d2c738bSmrg	    fprintf(stderr, "Xlib: ignoring invalid extension opcode %d\n",
3147d2c738bSmrg		    extension);
3157d2c738bSmrg	    return (CopyEventCookieType)_XUnknownCopyEventCookie;
3167d2c738bSmrg	}
317b4ee4795Smrg	if (proc == NULL) proc = (CopyEventCookieType)_XUnknownCopyEventCookie;
318b4ee4795Smrg	LockDisplay (dpy);
319b4ee4795Smrg	oldproc = dpy->generic_event_copy_vec[extension & 0x7F];
320b4ee4795Smrg	dpy->generic_event_copy_vec[extension & 0x7F] = proc;
321b4ee4795Smrg	UnlockDisplay (dpy);
322b4ee4795Smrg	return (CopyEventCookieType)oldproc;
323b4ee4795Smrg}
324b4ee4795Smrg
325b4ee4795Smrg
3261ab64890Smrgtypedef Status (*EventToWireType) (
3271ab64890Smrg    Display*	/* display */,
3281ab64890Smrg    XEvent*	/* re */,
3291ab64890Smrg    xEvent*	/* event */
3301ab64890Smrg);
3311ab64890Smrg
3321ab64890SmrgEventToWireType XESetEventToWire(
3331ab64890Smrg	Display *dpy,		/* display */
3341ab64890Smrg	int event_number,	/* event routine to replace */
3351ab64890Smrg	EventToWireType proc)	/* routine to call when converting event */
3361ab64890Smrg{
3371ab64890Smrg	register EventToWireType oldproc;
3387d2c738bSmrg	if (event_number < 0 ||
3397d2c738bSmrg	    event_number > LastExtensionEvent) {
3407d2c738bSmrg	    fprintf(stderr, "Xlib: ignoring invalid extension event %d\n",
3417d2c738bSmrg		    event_number);
3427d2c738bSmrg	    return (EventToWireType)_XUnknownNativeEvent;
3437d2c738bSmrg	}
3441ab64890Smrg	if (proc == NULL) proc = (EventToWireType) _XUnknownNativeEvent;
3451ab64890Smrg	LockDisplay (dpy);
3461ab64890Smrg	oldproc = dpy->wire_vec[event_number];
3471ab64890Smrg	dpy->wire_vec[event_number] = proc;
3481ab64890Smrg	UnlockDisplay(dpy);
3491ab64890Smrg	return (EventToWireType)oldproc;
3501ab64890Smrg}
3511ab64890Smrg
3521ab64890Smrgtypedef Bool (*WireToErrorType) (
3531ab64890Smrg    Display*	/* display */,
3541ab64890Smrg    XErrorEvent* /* he */,
3551ab64890Smrg    xError*	/* we */
3561ab64890Smrg);
3571ab64890Smrg
3581ab64890SmrgWireToErrorType XESetWireToError(
3591ab64890Smrg	Display *dpy,		/* display */
3601ab64890Smrg	int error_number,	/* error routine to replace */
3611ab64890Smrg	WireToErrorType proc)	/* routine to call when converting error */
3621ab64890Smrg{
3631ab64890Smrg	register WireToErrorType oldproc = NULL;
3647d2c738bSmrg	if (error_number < 0 ||
3657d2c738bSmrg	    error_number > LastExtensionError) {
3667d2c738bSmrg	   fprintf(stderr, "Xlib: ignoring invalid extension error %d\n",
3677d2c738bSmrg		    error_number);
3687d2c738bSmrg	   return (WireToErrorType)_XDefaultWireError;
3697d2c738bSmrg	}
3701ab64890Smrg	if (proc == NULL) proc = (WireToErrorType)_XDefaultWireError;
3711ab64890Smrg	LockDisplay (dpy);
3721ab64890Smrg	if (!dpy->error_vec) {
3731ab64890Smrg	    int i;
3741ab64890Smrg	    dpy->error_vec = Xmalloc(256 * sizeof(oldproc));
3751ab64890Smrg	    for (i = 1; i < 256; i++)
3761ab64890Smrg		dpy->error_vec[i] = _XDefaultWireError;
3771ab64890Smrg	}
3781ab64890Smrg	if (dpy->error_vec) {
3791ab64890Smrg	    oldproc = dpy->error_vec[error_number];
3801ab64890Smrg	    dpy->error_vec[error_number] = proc;
3811ab64890Smrg	}
3821ab64890Smrg	UnlockDisplay (dpy);
3831ab64890Smrg	return (WireToErrorType)oldproc;
3841ab64890Smrg}
3851ab64890Smrg
3861ab64890SmrgErrorType XESetError(
3871ab64890Smrg	Display *dpy,		/* display */
3881ab64890Smrg	int extension,		/* extension number */
3891ab64890Smrg	ErrorType proc)		/* routine to call when X error happens */
3901ab64890Smrg{
3911ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
3921ab64890Smrg	register ErrorType oldproc;
3931ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
3941ab64890Smrg	LockDisplay(dpy);
3951ab64890Smrg	oldproc = e->error;
3961ab64890Smrg	e->error = proc;
3971ab64890Smrg	UnlockDisplay(dpy);
3981ab64890Smrg	return (ErrorType)oldproc;
3991ab64890Smrg}
4001ab64890Smrg
4011ab64890SmrgErrorStringType XESetErrorString(
4021ab64890Smrg	Display *dpy,		/* display */
4031ab64890Smrg	int extension,		/* extension number */
4041ab64890Smrg	ErrorStringType proc)	/* routine to call when I/O error happens */
4051ab64890Smrg{
4061ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
4071ab64890Smrg	register ErrorStringType oldproc;
4081ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
4091ab64890Smrg	LockDisplay(dpy);
4101ab64890Smrg	oldproc = e->error_string;
4111ab64890Smrg	e->error_string = proc;
4121ab64890Smrg	UnlockDisplay(dpy);
4131ab64890Smrg	return (ErrorStringType)oldproc;
4141ab64890Smrg}
4151ab64890Smrg
4161ab64890SmrgPrintErrorType XESetPrintErrorValues(
4171ab64890Smrg	Display *dpy,		/* display */
4181ab64890Smrg	int extension,		/* extension number */
4191ab64890Smrg	PrintErrorType proc)	/* routine to call to print */
4201ab64890Smrg{
4211ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
4221ab64890Smrg	register PrintErrorType oldproc;
4231ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
4241ab64890Smrg	LockDisplay(dpy);
4251ab64890Smrg	oldproc = e->error_values;
4261ab64890Smrg	e->error_values = proc;
4271ab64890Smrg	UnlockDisplay(dpy);
4281ab64890Smrg	return (PrintErrorType)oldproc;
4291ab64890Smrg}
4301ab64890Smrg
4311ab64890SmrgBeforeFlushType XESetBeforeFlush(
4321ab64890Smrg	Display *dpy,		/* display */
4331ab64890Smrg	int extension,		/* extension number */
4341ab64890Smrg	BeforeFlushType proc)	/* routine to call on flush */
4351ab64890Smrg{
4361ab64890Smrg	register _XExtension *e;	/* for lookup of extension */
4371ab64890Smrg	register BeforeFlushType oldproc;
4381ab64890Smrg	register _XExtension *ext;
4391ab64890Smrg	if ((e = XLookupExtension (dpy, extension)) == NULL) return (NULL);
4401ab64890Smrg	LockDisplay(dpy);
4411ab64890Smrg	oldproc = e->before_flush;
4421ab64890Smrg	e->before_flush = proc;
4431ab64890Smrg	for (ext = dpy->flushes; ext && ext != e; ext = ext->next)
4441ab64890Smrg	    ;
4451ab64890Smrg	if (!ext) {
4461ab64890Smrg	    e->next_flush = dpy->flushes;
4471ab64890Smrg	    dpy->flushes = e;
44861b2299dSmrg	}
4491ab64890Smrg	UnlockDisplay(dpy);
4501ab64890Smrg	return (BeforeFlushType)oldproc;
4511ab64890Smrg}
452