#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
XExtensionInfo *XextCreateExtension (void)
{
register XExtensionInfo *info =
(XExtensionInfo *) Xmalloc (sizeof (XExtensionInfo));
if (info) {
info->head = NULL;
info->cur = NULL;
info->ndisplays = 0;
}
return info;
}
void XextDestroyExtension (XExtensionInfo *info)
{
info->head = NULL;
info->cur = NULL;
info->ndisplays = 0;
XFree ((char *) info);
}
XExtDisplayInfo *XextAddDisplay (
XExtensionInfo *extinfo,
Display *dpy,
char *ext_name,
XExtensionHooks *hooks,
int nevents,
XPointer data)
{
XExtDisplayInfo *dpyinfo;
dpyinfo = (XExtDisplayInfo *) Xmalloc (sizeof (XExtDisplayInfo));
if (!dpyinfo) return NULL;
dpyinfo->display = dpy;
dpyinfo->data = data;
dpyinfo->codes = XInitExtension (dpy, ext_name);
if (dpyinfo->codes) {
int i, j;
for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) {
XESetWireToEvent (dpy, j, hooks->wire_to_event);
XESetEventToWire (dpy, j, hooks->event_to_wire);
}
if (hooks->create_gc)
XESetCreateGC (dpy, dpyinfo->codes->extension, hooks->create_gc);
if (hooks->copy_gc)
XESetCopyGC (dpy, dpyinfo->codes->extension, hooks->copy_gc);
if (hooks->flush_gc)
XESetFlushGC (dpy, dpyinfo->codes->extension, hooks->flush_gc);
if (hooks->free_gc)
XESetFreeGC (dpy, dpyinfo->codes->extension, hooks->free_gc);
if (hooks->create_font)
XESetCreateFont (dpy, dpyinfo->codes->extension, hooks->create_font);
if (hooks->free_font)
XESetFreeFont (dpy, dpyinfo->codes->extension, hooks->free_font);
if (hooks->close_display)
XESetCloseDisplay (dpy, dpyinfo->codes->extension,
hooks->close_display);
if (hooks->error)
XESetError (dpy, dpyinfo->codes->extension, hooks->error);
if (hooks->error_string)
XESetErrorString (dpy, dpyinfo->codes->extension,
hooks->error_string);
} else if (hooks->close_display) {
XExtCodes *codes = XAddExtension(dpy);
if (!codes) {
XFree(dpyinfo);
return NULL;
}
XESetCloseDisplay (dpy, codes->extension, hooks->close_display);
}
_XLockMutex(_Xglobal_lock);
dpyinfo->next = extinfo->head;
extinfo->head = dpyinfo;
extinfo->cur = dpyinfo;
extinfo->ndisplays++;
_XUnlockMutex(_Xglobal_lock);
return dpyinfo;
}
int XextRemoveDisplay (XExtensionInfo *extinfo, Display *dpy)
{
XExtDisplayInfo *dpyinfo, *prev;
_XLockMutex(_Xglobal_lock);
prev = NULL;
for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) {
if (dpyinfo->display == dpy) break;
prev = dpyinfo;
}
if (!dpyinfo) {
_XUnlockMutex(_Xglobal_lock);
return 0;
}
if (prev)
prev->next = dpyinfo->next;
else
extinfo->head = dpyinfo->next;
extinfo->ndisplays--;
if (dpyinfo == extinfo->cur) extinfo->cur = NULL;
_XUnlockMutex(_Xglobal_lock);
Xfree ((char *) dpyinfo);
return 1;
}
XExtDisplayInfo *XextFindDisplay (XExtensionInfo *extinfo, Display *dpy)
{
register XExtDisplayInfo *dpyinfo;
if ((dpyinfo = extinfo->cur)&& dpyinfo->display == dpy) return dpyinfo;
_XLockMutex(_Xglobal_lock);
for (dpyinfo = extinfo->head; dpyinfo; dpyinfo = dpyinfo->next) {
if (dpyinfo->display == dpy) {
extinfo->cur = dpyinfo;
_XUnlockMutex(_Xglobal_lock);
return dpyinfo;
}
}
_XUnlockMutex(_Xglobal_lock);
return NULL;
}
static int _default_exterror (Display *dpy, char *ext_name, char *reason)
{
fprintf (stderr, "Xlib: extension \"%s\" %s on display \"%s\".\n",
ext_name, reason, DisplayString(dpy));
return 0;
}
extern int (*_XExtensionErrorFunction)();
int (*XSetExtensionErrorHandler(int (*handler)(Display*, char *, char * )))()
{
int (*oldhandler)() = _XExtensionErrorFunction;
_XExtensionErrorFunction = (handler ? handler :
_default_exterror);
return oldhandler;
}
int XMissingExtension (Display *dpy, _Xconst char *ext_name)
{
int (*func)() = (_XExtensionErrorFunction ?
_XExtensionErrorFunction : _default_exterror);
if (!ext_name) ext_name = X_EXTENSION_UNKNOWN;
return (*func) (dpy, ext_name, X_EXTENSION_MISSING);
}