Mercurial > kinput2.yaz
view lib/asyncerr.c @ 6:56c98768f86b
imported patch 08_kinput2-v3.1-fix-gcc-warning.patch
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 08 Mar 2010 20:07:06 +0900 |
parents | 92745d501b9a |
children |
line wrap: on
line source
#ifndef lint static char *rcsid = "$Id: asyncerr.c,v 1.6 1994/08/08 01:20:52 ishisone Exp $"; #endif /* * Copyright (C) 1992, 1994 Software Research Associates, Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Software Research Associates not be * used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. Software Research * Associates makes no representations about the suitability of this software * for any purpose. It is provided "as is" without express or implied * warranty. * * Author: Makoto Ishisone, Software Research Associates, Inc., Japan */ /* * X asyncronous error handler */ #include <X11/Xlib.h> #include <X11/Xfuncproto.h> #include "AsyncErr.h" #ifdef __STDC__ #include <stdlib.h> #else extern char *malloc(); #endif #ifndef NULL #define NULL 0 #endif #undef XSetErrorHandler typedef struct fe_errdesc_ { struct fe_errdesc_ *prev; struct fe_errdesc_ *next; Display *dpy; unsigned long from; /* range of the sequence numbers */ unsigned long to; /* which this handler covers */ int (*handler)(); /* async handler */ void (*destroy)(); XPointer client_data; } ErrDesc; static ErrDesc esentinel = { &esentinel, &esentinel, }; #define EHEAD (esentinel.next) #define ETAIL (esentinel.prev) #define EEND(p) ((p) == &esentinel) static int (*original_handler)(); /* * Some useful handlers */ /* ARGSUSED */ static int ignoreErrors(dpy, eev, cldata) Display *dpy; XErrorEvent *eev; XPointer cldata; { /* * Just ignore any errors. */ return 0; } /* ARGSUSED */ static int recordErrors(dpy, eev, cldata) Display *dpy; XErrorEvent *eev; XPointer cldata; { /* * Record the type of the error. * It assumes that the client data is a pointer to * an unsigned long int. If error occurs, it does: * + if the error code is less than 32, set the 'error code'th bit. * + otherwise (i.e. extension defined error) set the bit 0. */ unsigned long *errorbitsp = (unsigned long *)cldata; if (eev->error_code < 32) { *errorbitsp |= (1 << eev->error_code); } else { /* other errors */ *errorbitsp |= 1; } /* don't invoke global handler */ return 0; } static ErrDesc * newErrDesc() { return (ErrDesc *)malloc(sizeof(ErrDesc)); } static void eremove(edp) ErrDesc *edp; { edp->prev->next = edp->next; edp->next->prev = edp->prev; } static void eappend(edp) ErrDesc *edp; { edp->prev = esentinel.prev; edp->next = &esentinel; (esentinel.prev)->next = edp; esentinel.prev = edp; } static void removeHandler(edp) ErrDesc *edp; { if (edp->destroy != NULL) (*edp->destroy)(edp->dpy, edp->client_data); eremove(edp); (void)free((char *)edp); } static int callHandlers(dpy, eev) Display *dpy; XErrorEvent *eev; { ErrDesc *edp = EHEAD; int found = 0; int call_original = 0; while (!EEND(edp)) { if (edp->dpy == dpy && edp->from <= eev->serial && (eev->serial < edp->to || edp->from == edp->to)) { found = 1; if ((*edp->handler)(dpy, eev, edp->client_data)) call_original = 1; } edp = edp->next; } return !found || call_original; } static void removeHandlers(dpy) Display *dpy; { /* * Remove obsolete (out of date) handlers. */ ErrDesc *edp = EHEAD; unsigned long last = LastKnownRequestProcessed(dpy); while (!EEND(edp)) { ErrDesc *next = edp->next; if (edp->dpy == dpy && edp->to <= last && edp->from != edp->to) { removeHandler(edp); } edp = next; } } /* * public functions */ int XAEHandler(dpy, eev) Display *dpy; XErrorEvent *eev; { if (callHandlers(dpy, eev) && original_handler != NULL) { (void)original_handler(dpy, eev); } removeHandlers(dpy); return 0; /* for lint */ } void XAEInit() { int (*oldhandler)() = XSetErrorHandler(XAEHandler); if (oldhandler != XAEHandler) original_handler = oldhandler; } XErrorHandler XAESetErrorHandler(handler) XErrorHandler handler; { int (*oldhandler)(); oldhandler = original_handler; original_handler = handler; return oldhandler; } XAEHandle XAESet(dpy, handler, destroy, client_data) Display *dpy; int (*handler)(); void (*destroy)(); XPointer client_data; { ErrDesc *e; /* * First, remove out-of-date handlers. */ removeHandlers(dpy); /* * Allocate new ErrDesc structure. */ e = newErrDesc(); if (e == NULL) return NULL; e->dpy = dpy; e->from = NextRequest(dpy); e->to = e->from; e->handler = handler; e->destroy = destroy; e->client_data = client_data; eappend(e); return e; } void XAEUnset(handle) XAEHandle handle; { Display *dpy = handle->dpy; if (handle != NULL && handle->from == handle->to) { handle->to = NextRequest(dpy); if (handle->to <= handle->from) removeHandler(handle); } removeHandlers(dpy); } XAEHandle XAESetIgnoreErrors(dpy) Display *dpy; { return XAESet(dpy, ignoreErrors, (void (*)())NULL, (XPointer)NULL); } XAEHandle XAESetRecordErrors(dpy, errorbitsp) Display *dpy; unsigned long *errorbitsp; { *errorbitsp = 0L; /* clear all bits */ return XAESet(dpy, recordErrors, (void (*)())NULL, (XPointer)errorbitsp); }