extutil.c revision 6cda817a
1caade7ccSmrg/* 2caade7ccSmrg * $Xorg: extutil.c,v 1.4 2001/02/09 02:03:49 xorgcvs Exp $ 3caade7ccSmrg * 4caade7ccSmrgCopyright 1989, 1998 The Open Group 5caade7ccSmrg 6caade7ccSmrgPermission to use, copy, modify, distribute, and sell this software and its 7caade7ccSmrgdocumentation for any purpose is hereby granted without fee, provided that 8caade7ccSmrgthe above copyright notice appear in all copies and that both that 9caade7ccSmrgcopyright notice and this permission notice appear in supporting 10caade7ccSmrgdocumentation. 11caade7ccSmrg 12caade7ccSmrgThe above copyright notice and this permission notice shall be included in 13caade7ccSmrgall copies or substantial portions of the Software. 14caade7ccSmrg 15caade7ccSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16caade7ccSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17caade7ccSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18caade7ccSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19caade7ccSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20caade7ccSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21caade7ccSmrg 22caade7ccSmrgExcept as contained in this notice, the name of The Open Group shall not be 23caade7ccSmrgused in advertising or otherwise to promote the sale, use or other dealings 24caade7ccSmrgin this Software without prior written authorization from The Open Group. 25caade7ccSmrg * 26caade7ccSmrg * Author: Jim Fulton, MIT X Consortium 27caade7ccSmrg * 28caade7ccSmrg * 29caade7ccSmrg * Xlib Extension-Writing Utilities 30caade7ccSmrg * 31caade7ccSmrg * This package contains utilities for writing the client API for various 32caade7ccSmrg * protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND 33caade7ccSmrg * ARE SUBJECT TO CHANGE! 34caade7ccSmrg * 35caade7ccSmrg * Routines include: 36caade7ccSmrg * 37caade7ccSmrg * XextCreateExtension called once per extension 38caade7ccSmrg * XextDestroyExtension if no longer using extension 39caade7ccSmrg * XextAddDisplay add another display 40caade7ccSmrg * XextRemoveDisplay remove a display 41caade7ccSmrg * XextFindDisplay is a display open 42caade7ccSmrg * 43caade7ccSmrg * In addition, the following Xlib-style interfaces are provided: 44caade7ccSmrg * 45caade7ccSmrg * XSetExtensionErrorHandler establish an extension error handler 46caade7ccSmrg * XMissingExtension raise an error about missing ext 47caade7ccSmrg */ 48caade7ccSmrg/* $XFree86: xc/lib/Xext/extutil.c,v 1.5 2002/10/16 00:37:27 dawes Exp $ */ 49caade7ccSmrg 50caade7ccSmrg#ifdef HAVE_CONFIG_H 51caade7ccSmrg#include <config.h> 52caade7ccSmrg#endif 53caade7ccSmrg#include <stdio.h> 54caade7ccSmrg#include <X11/Xlibint.h> 55caade7ccSmrg#include <X11/extensions/Xext.h> 56caade7ccSmrg#include <X11/extensions/extutil.h> 57caade7ccSmrg 586cda817aSmrg/* defined in Xge.c */ 596cda817aSmrgextern _X_HIDDEN Bool 606cda817aSmrgxgeExtRegister(Display* dpy, int extension, XExtensionHooks* callbacks); 61caade7ccSmrg 62caade7ccSmrg/* 63caade7ccSmrg * XextCreateExtension - return an extension descriptor containing context 64caade7ccSmrg * information for this extension. This object is passed to all Xext 65caade7ccSmrg * routines. 66caade7ccSmrg */ 67caade7ccSmrgXExtensionInfo *XextCreateExtension (void) 68caade7ccSmrg{ 69caade7ccSmrg register XExtensionInfo *info = 70caade7ccSmrg (XExtensionInfo *) Xmalloc (sizeof (XExtensionInfo)); 71caade7ccSmrg 72caade7ccSmrg if (info) { 73caade7ccSmrg info->head = NULL; 74caade7ccSmrg info->cur = NULL; 75caade7ccSmrg info->ndisplays = 0; 76caade7ccSmrg } 77caade7ccSmrg return info; 78caade7ccSmrg} 79caade7ccSmrg 80caade7ccSmrg 81caade7ccSmrg/* 82caade7ccSmrg * XextDestroyExtension - free memory the given extension descriptor 83caade7ccSmrg */ 84caade7ccSmrgvoid XextDestroyExtension (XExtensionInfo *info) 85caade7ccSmrg{ 86caade7ccSmrg info->head = NULL; /* to catch refs after this */ 87caade7ccSmrg info->cur = NULL; 88caade7ccSmrg info->ndisplays = 0; 89caade7ccSmrg XFree ((char *) info); 90caade7ccSmrg} 91caade7ccSmrg 92caade7ccSmrg 93caade7ccSmrg 94caade7ccSmrg/* 95caade7ccSmrg * XextAddDisplay - add a display to this extension 96caade7ccSmrg */ 97caade7ccSmrgXExtDisplayInfo *XextAddDisplay ( 98caade7ccSmrg XExtensionInfo *extinfo, 99caade7ccSmrg Display *dpy, 100caade7ccSmrg char *ext_name, 101caade7ccSmrg XExtensionHooks *hooks, 102caade7ccSmrg int nevents, 103caade7ccSmrg XPointer data) 104caade7ccSmrg{ 105caade7ccSmrg XExtDisplayInfo *dpyinfo; 106caade7ccSmrg 107caade7ccSmrg dpyinfo = (XExtDisplayInfo *) Xmalloc (sizeof (XExtDisplayInfo)); 108caade7ccSmrg if (!dpyinfo) return NULL; 109caade7ccSmrg dpyinfo->display = dpy; 110caade7ccSmrg dpyinfo->data = data; 111caade7ccSmrg dpyinfo->codes = XInitExtension (dpy, ext_name); 112caade7ccSmrg 113caade7ccSmrg /* 114caade7ccSmrg * if the server has the extension, then we can initialize the 115caade7ccSmrg * appropriate function vectors 116caade7ccSmrg */ 117caade7ccSmrg if (dpyinfo->codes) { 118caade7ccSmrg int i, j; 119caade7ccSmrg 120caade7ccSmrg for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) { 121caade7ccSmrg XESetWireToEvent (dpy, j, hooks->wire_to_event); 122caade7ccSmrg XESetEventToWire (dpy, j, hooks->event_to_wire); 123caade7ccSmrg } 124caade7ccSmrg if (hooks->create_gc) 125caade7ccSmrg XESetCreateGC (dpy, dpyinfo->codes->extension, hooks->create_gc); 126caade7ccSmrg if (hooks->copy_gc) 127caade7ccSmrg XESetCopyGC (dpy, dpyinfo->codes->extension, hooks->copy_gc); 128caade7ccSmrg if (hooks->flush_gc) 129caade7ccSmrg XESetFlushGC (dpy, dpyinfo->codes->extension, hooks->flush_gc); 130caade7ccSmrg if (hooks->free_gc) 131caade7ccSmrg XESetFreeGC (dpy, dpyinfo->codes->extension, hooks->free_gc); 132caade7ccSmrg if (hooks->create_font) 133caade7ccSmrg XESetCreateFont (dpy, dpyinfo->codes->extension, hooks->create_font); 134caade7ccSmrg if (hooks->free_font) 135caade7ccSmrg XESetFreeFont (dpy, dpyinfo->codes->extension, hooks->free_font); 136caade7ccSmrg if (hooks->close_display) 137caade7ccSmrg XESetCloseDisplay (dpy, dpyinfo->codes->extension, 138caade7ccSmrg hooks->close_display); 139caade7ccSmrg if (hooks->error) 140caade7ccSmrg XESetError (dpy, dpyinfo->codes->extension, hooks->error); 141caade7ccSmrg if (hooks->error_string) 142caade7ccSmrg XESetErrorString (dpy, dpyinfo->codes->extension, 143caade7ccSmrg hooks->error_string); 144caade7ccSmrg } else if (hooks->close_display) { 145caade7ccSmrg /* The server doesn't have this extension. 146caade7ccSmrg * Use a private Xlib-internal extension to hang the close_display 147caade7ccSmrg * hook on so that the "cache" (extinfo->cur) is properly cleaned. 148caade7ccSmrg * (XBUG 7955) 149caade7ccSmrg */ 150caade7ccSmrg XExtCodes *codes = XAddExtension(dpy); 151caade7ccSmrg if (!codes) { 152caade7ccSmrg XFree(dpyinfo); 153caade7ccSmrg return NULL; 154caade7ccSmrg } 155caade7ccSmrg XESetCloseDisplay (dpy, codes->extension, hooks->close_display); 156caade7ccSmrg } 157caade7ccSmrg 158caade7ccSmrg /* 159caade7ccSmrg * now, chain it onto the list 160caade7ccSmrg */ 161caade7ccSmrg _XLockMutex(_Xglobal_lock); 162caade7ccSmrg dpyinfo->next = extinfo->head; 163caade7ccSmrg extinfo->head = dpyinfo; 164caade7ccSmrg extinfo->cur = dpyinfo; 165caade7ccSmrg extinfo->ndisplays++; 166caade7ccSmrg _XUnlockMutex(_Xglobal_lock); 167caade7ccSmrg return dpyinfo; 168caade7ccSmrg} 169caade7ccSmrg 170caade7ccSmrg 171caade7ccSmrg/* 172caade7ccSmrg * XextRemoveDisplay - remove the indicated display from the extension object 173caade7ccSmrg */ 174caade7ccSmrgint XextRemoveDisplay (XExtensionInfo *extinfo, Display *dpy) 175caade7ccSmrg{ 176caade7ccSmrg XExtDisplayInfo *dpyinfo, *prev; 177caade7ccSmrg 178caade7ccSmrg /* 179caade7ccSmrg * locate this display and its back link so that it can be removed 180caade7ccSmrg */ 181caade7ccSmrg _XLockMutex(_Xglobal_lock); 182caade7ccSmrg prev = NULL; 183caade7ccSmrg for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 184caade7ccSmrg if (dpyinfo->display == dpy) break; 185caade7ccSmrg prev = dpyinfo; 186caade7ccSmrg } 187caade7ccSmrg if (!dpyinfo) { 188caade7ccSmrg _XUnlockMutex(_Xglobal_lock); 189caade7ccSmrg return 0; /* hmm, actually an error */ 190caade7ccSmrg } 191caade7ccSmrg 192caade7ccSmrg /* 193caade7ccSmrg * remove the display from the list; handles going to zero 194caade7ccSmrg */ 195caade7ccSmrg if (prev) 196caade7ccSmrg prev->next = dpyinfo->next; 197caade7ccSmrg else 198caade7ccSmrg extinfo->head = dpyinfo->next; 199caade7ccSmrg 200caade7ccSmrg extinfo->ndisplays--; 201caade7ccSmrg if (dpyinfo == extinfo->cur) extinfo->cur = NULL; /* flush cache */ 202caade7ccSmrg _XUnlockMutex(_Xglobal_lock); 203caade7ccSmrg 204caade7ccSmrg Xfree ((char *) dpyinfo); 205caade7ccSmrg return 1; 206caade7ccSmrg} 207caade7ccSmrg 208caade7ccSmrg 209caade7ccSmrg/* 210caade7ccSmrg * XextFindDisplay - look for a display in this extension; keeps a cache 211caade7ccSmrg * of the most-recently used for efficiency. 212caade7ccSmrg */ 213caade7ccSmrgXExtDisplayInfo *XextFindDisplay (XExtensionInfo *extinfo, Display *dpy) 214caade7ccSmrg{ 215caade7ccSmrg register XExtDisplayInfo *dpyinfo; 216caade7ccSmrg 217caade7ccSmrg /* 218caade7ccSmrg * see if this was the most recently accessed display 219caade7ccSmrg */ 220caade7ccSmrg if ((dpyinfo = extinfo->cur)&& dpyinfo->display == dpy) return dpyinfo; 221caade7ccSmrg 222caade7ccSmrg 223caade7ccSmrg /* 224caade7ccSmrg * look for display in list 225caade7ccSmrg */ 226caade7ccSmrg _XLockMutex(_Xglobal_lock); 227caade7ccSmrg for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) { 228caade7ccSmrg if (dpyinfo->display == dpy) { 229caade7ccSmrg extinfo->cur = dpyinfo; /* cache most recently used */ 230caade7ccSmrg _XUnlockMutex(_Xglobal_lock); 231caade7ccSmrg return dpyinfo; 232caade7ccSmrg } 233caade7ccSmrg } 234caade7ccSmrg _XUnlockMutex(_Xglobal_lock); 235caade7ccSmrg 236caade7ccSmrg return NULL; 237caade7ccSmrg} 238caade7ccSmrg 239caade7ccSmrg 240caade7ccSmrg 241caade7ccSmrgstatic int _default_exterror (Display *dpy, char *ext_name, char *reason) 242caade7ccSmrg{ 243caade7ccSmrg fprintf (stderr, "Xlib: extension \"%s\" %s on display \"%s\".\n", 244caade7ccSmrg ext_name, reason, DisplayString(dpy)); 245caade7ccSmrg return 0; 246caade7ccSmrg} 247caade7ccSmrg 248caade7ccSmrg 249caade7ccSmrg/* 250caade7ccSmrg * XSetExtensionErrorHandler - sets the handler that gets called when a 251caade7ccSmrg * requested extension is referenced. This should eventually move into Xlib. 252caade7ccSmrg */ 253caade7ccSmrg 254c585b9bdSmrgextern XextErrorHandler _XExtensionErrorFunction; 255caade7ccSmrg 256c585b9bdSmrgXextErrorHandler XSetExtensionErrorHandler (XextErrorHandler handler) 257caade7ccSmrg{ 258c585b9bdSmrg XextErrorHandler oldhandler = _XExtensionErrorFunction; 259caade7ccSmrg 260caade7ccSmrg _XExtensionErrorFunction = (handler ? handler : 261caade7ccSmrg _default_exterror); 262caade7ccSmrg return oldhandler; 263caade7ccSmrg} 264caade7ccSmrg 265caade7ccSmrg 266caade7ccSmrg/* 267caade7ccSmrg * XMissingExtension - call the extension error handler 268caade7ccSmrg */ 269caade7ccSmrgint XMissingExtension (Display *dpy, _Xconst char *ext_name) 270caade7ccSmrg{ 271caade7ccSmrg int (*func)(Display*, char *, char *) = (_XExtensionErrorFunction ? 272caade7ccSmrg _XExtensionErrorFunction : _default_exterror); 273caade7ccSmrg 274caade7ccSmrg if (!ext_name) ext_name = X_EXTENSION_UNKNOWN; 275caade7ccSmrg return (*func) (dpy, ext_name, X_EXTENSION_MISSING); 276caade7ccSmrg} 277