Initial commit
[xorg_rtime.git] / libXext-1.0.2 / src / extutil.c
blobd96b17f3fc1b029718534a0ee2c30f1fdcedf1df
1 /*
2 * $Xorg: extutil.c,v 1.4 2001/02/09 02:03:49 xorgcvs Exp $
4 Copyright 1989, 1998 The Open Group
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
26 * Author: Jim Fulton, MIT X Consortium
29 * Xlib Extension-Writing Utilities
31 * This package contains utilities for writing the client API for various
32 * protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND
33 * ARE SUBJECT TO CHANGE!
35 * Routines include:
37 * XextCreateExtension called once per extension
38 * XextDestroyExtension if no longer using extension
39 * XextAddDisplay add another display
40 * XextRemoveDisplay remove a display
41 * XextFindDisplay is a display open
43 * In addition, the following Xlib-style interfaces are provided:
45 * XSetExtensionErrorHandler establish an extension error handler
46 * XMissingExtension raise an error about missing ext
48 /* $XFree86: xc/lib/Xext/extutil.c,v 1.5 2002/10/16 00:37:27 dawes Exp $ */
50 #ifdef HAVE_CONFIG_H
51 #include <config.h>
52 #endif
53 #include <stdio.h>
54 #include <X11/Xlibint.h>
55 #include <X11/extensions/Xext.h>
56 #include <X11/extensions/extutil.h>
60 * XextCreateExtension - return an extension descriptor containing context
61 * information for this extension. This object is passed to all Xext
62 * routines.
64 XExtensionInfo *XextCreateExtension (void)
66 register XExtensionInfo *info =
67 (XExtensionInfo *) Xmalloc (sizeof (XExtensionInfo));
69 if (info) {
70 info->head = NULL;
71 info->cur = NULL;
72 info->ndisplays = 0;
74 return info;
79 * XextDestroyExtension - free memory the given extension descriptor
81 void XextDestroyExtension (XExtensionInfo *info)
83 info->head = NULL; /* to catch refs after this */
84 info->cur = NULL;
85 info->ndisplays = 0;
86 XFree ((char *) info);
92 * XextAddDisplay - add a display to this extension
94 XExtDisplayInfo *XextAddDisplay (
95 XExtensionInfo *extinfo,
96 Display *dpy,
97 char *ext_name,
98 XExtensionHooks *hooks,
99 int nevents,
100 XPointer data)
102 XExtDisplayInfo *dpyinfo;
104 dpyinfo = (XExtDisplayInfo *) Xmalloc (sizeof (XExtDisplayInfo));
105 if (!dpyinfo) return NULL;
106 dpyinfo->display = dpy;
107 dpyinfo->data = data;
108 dpyinfo->codes = XInitExtension (dpy, ext_name);
111 * if the server has the extension, then we can initialize the
112 * appropriate function vectors
114 if (dpyinfo->codes) {
115 int i, j;
117 for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) {
118 XESetWireToEvent (dpy, j, hooks->wire_to_event);
119 XESetEventToWire (dpy, j, hooks->event_to_wire);
121 if (hooks->create_gc)
122 XESetCreateGC (dpy, dpyinfo->codes->extension, hooks->create_gc);
123 if (hooks->copy_gc)
124 XESetCopyGC (dpy, dpyinfo->codes->extension, hooks->copy_gc);
125 if (hooks->flush_gc)
126 XESetFlushGC (dpy, dpyinfo->codes->extension, hooks->flush_gc);
127 if (hooks->free_gc)
128 XESetFreeGC (dpy, dpyinfo->codes->extension, hooks->free_gc);
129 if (hooks->create_font)
130 XESetCreateFont (dpy, dpyinfo->codes->extension, hooks->create_font);
131 if (hooks->free_font)
132 XESetFreeFont (dpy, dpyinfo->codes->extension, hooks->free_font);
133 if (hooks->close_display)
134 XESetCloseDisplay (dpy, dpyinfo->codes->extension,
135 hooks->close_display);
136 if (hooks->error)
137 XESetError (dpy, dpyinfo->codes->extension, hooks->error);
138 if (hooks->error_string)
139 XESetErrorString (dpy, dpyinfo->codes->extension,
140 hooks->error_string);
141 } else if (hooks->close_display) {
142 /* The server doesn't have this extension.
143 * Use a private Xlib-internal extension to hang the close_display
144 * hook on so that the "cache" (extinfo->cur) is properly cleaned.
145 * (XBUG 7955)
147 XExtCodes *codes = XAddExtension(dpy);
148 if (!codes) {
149 XFree(dpyinfo);
150 return NULL;
152 XESetCloseDisplay (dpy, codes->extension, hooks->close_display);
156 * now, chain it onto the list
158 _XLockMutex(_Xglobal_lock);
159 dpyinfo->next = extinfo->head;
160 extinfo->head = dpyinfo;
161 extinfo->cur = dpyinfo;
162 extinfo->ndisplays++;
163 _XUnlockMutex(_Xglobal_lock);
164 return dpyinfo;
169 * XextRemoveDisplay - remove the indicated display from the extension object
171 int XextRemoveDisplay (XExtensionInfo *extinfo, Display *dpy)
173 XExtDisplayInfo *dpyinfo, *prev;
176 * locate this display and its back link so that it can be removed
178 _XLockMutex(_Xglobal_lock);
179 prev = NULL;
180 for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) {
181 if (dpyinfo->display == dpy) break;
182 prev = dpyinfo;
184 if (!dpyinfo) {
185 _XUnlockMutex(_Xglobal_lock);
186 return 0; /* hmm, actually an error */
190 * remove the display from the list; handles going to zero
192 if (prev)
193 prev->next = dpyinfo->next;
194 else
195 extinfo->head = dpyinfo->next;
197 extinfo->ndisplays--;
198 if (dpyinfo == extinfo->cur) extinfo->cur = NULL; /* flush cache */
199 _XUnlockMutex(_Xglobal_lock);
201 Xfree ((char *) dpyinfo);
202 return 1;
207 * XextFindDisplay - look for a display in this extension; keeps a cache
208 * of the most-recently used for efficiency.
210 XExtDisplayInfo *XextFindDisplay (XExtensionInfo *extinfo, Display *dpy)
212 register XExtDisplayInfo *dpyinfo;
215 * see if this was the most recently accessed display
217 if ((dpyinfo = extinfo->cur)&& dpyinfo->display == dpy) return dpyinfo;
221 * look for display in list
223 _XLockMutex(_Xglobal_lock);
224 for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) {
225 if (dpyinfo->display == dpy) {
226 extinfo->cur = dpyinfo; /* cache most recently used */
227 _XUnlockMutex(_Xglobal_lock);
228 return dpyinfo;
231 _XUnlockMutex(_Xglobal_lock);
233 return NULL;
238 static int _default_exterror (Display *dpy, char *ext_name, char *reason)
240 fprintf (stderr, "Xlib: extension \"%s\" %s on display \"%s\".\n",
241 ext_name, reason, DisplayString(dpy));
242 return 0;
247 * XSetExtensionErrorHandler - sets the handler that gets called when a
248 * requested extension is referenced. This should eventually move into Xlib.
251 extern int (*_XExtensionErrorFunction)();
253 int (*XSetExtensionErrorHandler(int (*handler)(Display*, char *, char * )))()
255 int (*oldhandler)() = _XExtensionErrorFunction;
257 _XExtensionErrorFunction = (handler ? handler :
258 _default_exterror);
259 return oldhandler;
264 * XMissingExtension - call the extension error handler
266 int XMissingExtension (Display *dpy, _Xconst char *ext_name)
268 int (*func)() = (_XExtensionErrorFunction ?
269 _XExtensionErrorFunction : _default_exterror);
271 if (!ext_name) ext_name = X_EXTENSION_UNKNOWN;
272 return (*func) (dpy, ext_name, X_EXTENSION_MISSING);