3 Copyright 1989, 1998 The Open Group
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
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 * Author: Jim Fulton, MIT X Consortium
28 * Xlib Extension-Writing Utilities
30 * This package contains utilities for writing the client API for various
31 * protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND
32 * ARE SUBJECT TO CHANGE!
36 * XextCreateExtension called once per extension
37 * XextDestroyExtension if no longer using extension
38 * XextAddDisplay add another display
39 * XextRemoveDisplay remove a display
40 * XextFindDisplay is a display open
42 * In addition, the following Xlib-style interfaces are provided:
44 * XSetExtensionErrorHandler establish an extension error handler
45 * XMissingExtension raise an error about missing ext
52 #include <X11/Xlibint.h>
53 #include <X11/extensions/Xext.h>
54 #include <X11/extensions/extutil.h>
55 #include <X11/extensions/ge.h>
57 /* defined in Xge.c */
59 xgeExtRegister(Display* dpy, int extension, XExtensionHooks* callbacks);
62 * XextCreateExtension - return an extension descriptor containing context
63 * information for this extension. This object is passed to all Xext
66 XExtensionInfo *XextCreateExtension (void)
68 register XExtensionInfo *info =
69 (XExtensionInfo *) Xmalloc (sizeof (XExtensionInfo));
81 * XextDestroyExtension - free memory the given extension descriptor
83 void XextDestroyExtension (XExtensionInfo *info)
85 info->head = NULL; /* to catch refs after this */
88 XFree ((char *) info);
94 * XextAddDisplay - add a display to this extension
96 XExtDisplayInfo *XextAddDisplay (
97 XExtensionInfo *extinfo,
100 XExtensionHooks *hooks,
104 XExtDisplayInfo *dpyinfo;
106 dpyinfo = (XExtDisplayInfo *) Xmalloc (sizeof (XExtDisplayInfo));
107 if (!dpyinfo) return NULL;
108 dpyinfo->display = dpy;
109 dpyinfo->data = data;
110 dpyinfo->codes = XInitExtension (dpy, ext_name);
113 * if the server has the extension, then we can initialize the
114 * appropriate function vectors
116 if (dpyinfo->codes) {
119 for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) {
120 XESetWireToEvent (dpy, j, hooks->wire_to_event);
121 XESetEventToWire (dpy, j, hooks->event_to_wire);
124 /* register extension for XGE */
125 if (strcmp(ext_name, GE_NAME))
126 xgeExtRegister(dpy, dpyinfo->codes->major_opcode, hooks);
128 if (hooks->create_gc)
129 XESetCreateGC (dpy, dpyinfo->codes->extension, hooks->create_gc);
131 XESetCopyGC (dpy, dpyinfo->codes->extension, hooks->copy_gc);
133 XESetFlushGC (dpy, dpyinfo->codes->extension, hooks->flush_gc);
135 XESetFreeGC (dpy, dpyinfo->codes->extension, hooks->free_gc);
136 if (hooks->create_font)
137 XESetCreateFont (dpy, dpyinfo->codes->extension, hooks->create_font);
138 if (hooks->free_font)
139 XESetFreeFont (dpy, dpyinfo->codes->extension, hooks->free_font);
140 if (hooks->close_display)
141 XESetCloseDisplay (dpy, dpyinfo->codes->extension,
142 hooks->close_display);
144 XESetError (dpy, dpyinfo->codes->extension, hooks->error);
145 if (hooks->error_string)
146 XESetErrorString (dpy, dpyinfo->codes->extension,
147 hooks->error_string);
148 } else if (hooks->close_display) {
149 /* The server doesn't have this extension.
150 * Use a private Xlib-internal extension to hang the close_display
151 * hook on so that the "cache" (extinfo->cur) is properly cleaned.
154 XExtCodes *codes = XAddExtension(dpy);
159 XESetCloseDisplay (dpy, codes->extension, hooks->close_display);
163 * now, chain it onto the list
165 _XLockMutex(_Xglobal_lock);
166 dpyinfo->next = extinfo->head;
167 extinfo->head = dpyinfo;
168 extinfo->cur = dpyinfo;
169 extinfo->ndisplays++;
170 _XUnlockMutex(_Xglobal_lock);
176 * XextRemoveDisplay - remove the indicated display from the extension object
178 int XextRemoveDisplay (XExtensionInfo *extinfo, Display *dpy)
180 XExtDisplayInfo *dpyinfo, *prev;
183 * locate this display and its back link so that it can be removed
185 _XLockMutex(_Xglobal_lock);
187 for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) {
188 if (dpyinfo->display == dpy) break;
192 _XUnlockMutex(_Xglobal_lock);
193 return 0; /* hmm, actually an error */
197 * remove the display from the list; handles going to zero
200 prev->next = dpyinfo->next;
202 extinfo->head = dpyinfo->next;
204 extinfo->ndisplays--;
205 if (dpyinfo == extinfo->cur) extinfo->cur = NULL; /* flush cache */
206 _XUnlockMutex(_Xglobal_lock);
208 Xfree ((char *) dpyinfo);
214 * XextFindDisplay - look for a display in this extension; keeps a cache
215 * of the most-recently used for efficiency.
217 XExtDisplayInfo *XextFindDisplay (XExtensionInfo *extinfo, Display *dpy)
219 register XExtDisplayInfo *dpyinfo;
222 * see if this was the most recently accessed display
224 if ((dpyinfo = extinfo->cur)&& dpyinfo->display == dpy) return dpyinfo;
228 * look for display in list
230 _XLockMutex(_Xglobal_lock);
231 for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) {
232 if (dpyinfo->display == dpy) {
233 extinfo->cur = dpyinfo; /* cache most recently used */
234 _XUnlockMutex(_Xglobal_lock);
238 _XUnlockMutex(_Xglobal_lock);
245 static int _default_exterror (Display *dpy, _Xconst char *ext_name, _Xconst char *reason)
247 fprintf (stderr, "Xlib: extension \"%s\" %s on display \"%s\".\n",
248 ext_name, reason, DisplayString(dpy));
254 * XSetExtensionErrorHandler - sets the handler that gets called when a
255 * requested extension is referenced. This should eventually move into Xlib.
258 extern XextErrorHandler _XExtensionErrorFunction;
260 XextErrorHandler XSetExtensionErrorHandler (XextErrorHandler handler)
262 XextErrorHandler oldhandler = _XExtensionErrorFunction;
264 _XExtensionErrorFunction = (handler ? handler :
271 * XMissingExtension - call the extension error handler
273 int XMissingExtension (Display *dpy, _Xconst char *ext_name)
275 XextErrorHandler func = (_XExtensionErrorFunction ?
276 _XExtensionErrorFunction : _default_exterror);
278 if (!ext_name) ext_name = X_EXTENSION_UNKNOWN;
279 return (*func) (dpy, ext_name, X_EXTENSION_MISSING);