|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
Copyright 1989, 1998 The Open Group
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
Permission to use, copy, modify, distribute, and sell this software and its
|
|
Packit Service |
2b1f13 |
documentation for any purpose is hereby granted without fee, provided that
|
|
Packit Service |
2b1f13 |
the above copyright notice appear in all copies and that both that
|
|
Packit Service |
2b1f13 |
copyright notice and this permission notice appear in supporting
|
|
Packit Service |
2b1f13 |
documentation.
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
The above copyright notice and this permission notice shall be included in
|
|
Packit Service |
2b1f13 |
all copies or substantial portions of the Software.
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
Packit Service |
2b1f13 |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
Packit Service |
2b1f13 |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
Packit Service |
2b1f13 |
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
Packit Service |
2b1f13 |
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit Service |
2b1f13 |
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
Except as contained in this notice, the name of The Open Group shall not be
|
|
Packit Service |
2b1f13 |
used in advertising or otherwise to promote the sale, use or other dealings
|
|
Packit Service |
2b1f13 |
in this Software without prior written authorization from The Open Group.
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* CloseDisplayHook package - provide callback on XCloseDisplay
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* *
|
|
Packit Service |
2b1f13 |
* Author: Jim Fulton, MIT X Consortium
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* Public Entry Points
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* CloseHook XmuAddCloseDisplayHook (dpy, func, arg)
|
|
Packit Service |
2b1f13 |
* Display *dpy;
|
|
Packit Service |
2b1f13 |
* XmuCloseHookProc func;
|
|
Packit Service |
2b1f13 |
* XPointer arg;
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* Bool XmuRemoveCloseDisplayHook (dpy, hook, func, arg)
|
|
Packit Service |
2b1f13 |
* Display *dpy;
|
|
Packit Service |
2b1f13 |
* CloseHook hook;
|
|
Packit Service |
2b1f13 |
* XmuCloseHookProc func;
|
|
Packit Service |
2b1f13 |
* XPointer arg;
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* Bool XmuLookupCloseDisplayHook (dpy, hook, func, arg)
|
|
Packit Service |
2b1f13 |
* Display *dpy;
|
|
Packit Service |
2b1f13 |
* CloseHook hook;
|
|
Packit Service |
2b1f13 |
* XmuCloseHookProc func;
|
|
Packit Service |
2b1f13 |
* XPointer arg;
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
2b1f13 |
#include <config.h>
|
|
Packit Service |
2b1f13 |
#endif
|
|
Packit Service |
2b1f13 |
#include <stdio.h> /* for NULL */
|
|
Packit Service |
2b1f13 |
#include <X11/Xos.h>
|
|
Packit Service |
2b1f13 |
#include <X11/Xlib.h>
|
|
Packit Service |
2b1f13 |
#include <X11/Xmu/CloseHook.h>
|
|
Packit Service |
2b1f13 |
#include <stdlib.h>
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* Private data
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* This is a list of display entries, each of which contains a list of callback
|
|
Packit Service |
2b1f13 |
* records.
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
typedef struct _CallbackRec {
|
|
Packit Service |
2b1f13 |
struct _CallbackRec *next; /* next link in chain */
|
|
Packit Service |
2b1f13 |
XmuCloseHookProc func; /* function to call */
|
|
Packit Service |
2b1f13 |
XPointer arg; /* argument to pass with function */
|
|
Packit Service |
2b1f13 |
} CallbackRec;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
typedef struct _DisplayEntry {
|
|
Packit Service |
2b1f13 |
struct _DisplayEntry *next; /* next link in chain */
|
|
Packit Service |
2b1f13 |
Display *dpy; /* the display this represents */
|
|
Packit Service |
2b1f13 |
int extension; /* from XAddExtension */
|
|
Packit Service |
2b1f13 |
struct _CallbackRec *start, *end; /* linked list of callbacks */
|
|
Packit Service |
2b1f13 |
struct _CallbackRec *calling; /* currently being called back */
|
|
Packit Service |
2b1f13 |
} DisplayEntry;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* Prototypes
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
static DisplayEntry *_FindDisplayEntry(Display*, DisplayEntry**);
|
|
Packit Service |
2b1f13 |
static Bool _MakeExtension(Display*, int*);
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
static DisplayEntry *elist = NULL;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
*****************************************************************************
|
|
Packit Service |
2b1f13 |
* Public Entry Points *
|
|
Packit Service |
2b1f13 |
*****************************************************************************
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* Add - add a callback for the given display. When the display is closed,
|
|
Packit Service |
2b1f13 |
* the given function will be called as:
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* (*func) (dpy, arg)
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* This function is declared to return an int even though the value is ignored
|
|
Packit Service |
2b1f13 |
* because some compilers have problems with functions returning void.
|
|
Packit Service |
2b1f13 |
*
|
|
Packit Service |
2b1f13 |
* This routine returns NULL if it was unable to add the callback, otherwise
|
|
Packit Service |
2b1f13 |
* it returns an untyped pointer that can be used with Remove or Lookup, but
|
|
Packit Service |
2b1f13 |
* not dereferenced.
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
CloseHook
|
|
Packit Service |
2b1f13 |
XmuAddCloseDisplayHook(Display *dpy, XmuCloseHookProc func, XPointer arg)
|
|
Packit Service |
2b1f13 |
{
|
|
Packit Service |
2b1f13 |
DisplayEntry *de;
|
|
Packit Service |
2b1f13 |
CallbackRec *cb;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/* allocate ahead of time so that we can fail atomically */
|
|
Packit Service |
2b1f13 |
cb = (CallbackRec *) malloc (sizeof (CallbackRec));
|
|
Packit Service |
2b1f13 |
if (!cb) return ((XPointer) NULL);
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
de = _FindDisplayEntry (dpy, NULL);
|
|
Packit Service |
2b1f13 |
if (!de) {
|
|
Packit Service |
2b1f13 |
if ((de = (DisplayEntry *) malloc (sizeof (DisplayEntry))) == NULL ||
|
|
Packit Service |
2b1f13 |
!_MakeExtension (dpy, &de->extension)) {
|
|
Packit Service |
2b1f13 |
free ((char *) cb);
|
|
Packit Service |
2b1f13 |
if (de) free ((char *) de);
|
|
Packit Service |
2b1f13 |
return ((CloseHook) NULL);
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
de->dpy = dpy;
|
|
Packit Service |
2b1f13 |
de->start = de->end = NULL;
|
|
Packit Service |
2b1f13 |
de->calling = NULL;
|
|
Packit Service |
2b1f13 |
de->next = elist;
|
|
Packit Service |
2b1f13 |
elist = de;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/* add to end of list of callback recordss */
|
|
Packit Service |
2b1f13 |
cb->func = func;
|
|
Packit Service |
2b1f13 |
cb->arg = arg;
|
|
Packit Service |
2b1f13 |
cb->next = NULL;
|
|
Packit Service |
2b1f13 |
if (de->end) {
|
|
Packit Service |
2b1f13 |
de->end->next = cb;
|
|
Packit Service |
2b1f13 |
} else {
|
|
Packit Service |
2b1f13 |
de->start = cb;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
de->end = cb;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
return ((CloseHook) cb);
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* Remove - get rid of a callback. If handle is non-null, use that to compare
|
|
Packit Service |
2b1f13 |
* entries. Otherwise, remove first instance of the function/argument pair.
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
Bool
|
|
Packit Service |
2b1f13 |
XmuRemoveCloseDisplayHook(Display *dpy, CloseHook handle,
|
|
Packit Service |
2b1f13 |
XmuCloseHookProc func, XPointer arg)
|
|
Packit Service |
2b1f13 |
{
|
|
Packit Service |
2b1f13 |
DisplayEntry *de = _FindDisplayEntry (dpy, NULL);
|
|
Packit Service |
2b1f13 |
register CallbackRec *h, *prev;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
if (!de) return False;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/* look for handle or function/argument pair */
|
|
Packit Service |
2b1f13 |
for (h = de->start, prev = NULL; h; h = h->next) {
|
|
Packit Service |
2b1f13 |
if (handle) {
|
|
Packit Service |
2b1f13 |
if (h == (CallbackRec *) handle) break;
|
|
Packit Service |
2b1f13 |
} else {
|
|
Packit Service |
2b1f13 |
if (h->func == func && h->arg == arg) break;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
prev = h;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
if (!h) return False;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/* remove from list, watch head and tail */
|
|
Packit Service |
2b1f13 |
if (de->start == h) {
|
|
Packit Service |
2b1f13 |
de->start = h->next;
|
|
Packit Service |
2b1f13 |
} else {
|
|
Packit Service |
2b1f13 |
prev->next = h->next;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
if (de->end == h) de->end = prev;
|
|
Packit Service |
2b1f13 |
if (de->calling != h) free ((char *) h);
|
|
Packit Service |
2b1f13 |
return True;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* Lookup - see whether or not a handle has been installed. If handle is
|
|
Packit Service |
2b1f13 |
* non-NULL, look for an entry that matches it; otherwise look for an entry
|
|
Packit Service |
2b1f13 |
* with the same function/argument pair.
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
Bool
|
|
Packit Service |
2b1f13 |
XmuLookupCloseDisplayHook(Display *dpy, CloseHook handle,
|
|
Packit Service |
2b1f13 |
XmuCloseHookProc func, XPointer arg)
|
|
Packit Service |
2b1f13 |
{
|
|
Packit Service |
2b1f13 |
DisplayEntry *de = _FindDisplayEntry (dpy, NULL);
|
|
Packit Service |
2b1f13 |
register CallbackRec *h;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
if (!de) return False;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
for (h = de->start; h; h = h->next) {
|
|
Packit Service |
2b1f13 |
if (handle) {
|
|
Packit Service |
2b1f13 |
if (h == (CallbackRec *) handle) break;
|
|
Packit Service |
2b1f13 |
} else {
|
|
Packit Service |
2b1f13 |
if (h->func == func && h->arg == arg) break;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
return (h ? True : False);
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
*****************************************************************************
|
|
Packit Service |
2b1f13 |
* internal routines *
|
|
Packit Service |
2b1f13 |
*****************************************************************************
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* Find the specified display on the linked list of displays. Also return
|
|
Packit Service |
2b1f13 |
* the preceeding link so that the display can be unlinked without having
|
|
Packit Service |
2b1f13 |
* back pointers.
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
static DisplayEntry *
|
|
Packit Service |
2b1f13 |
_FindDisplayEntry(register Display *dpy, DisplayEntry **prevp)
|
|
Packit Service |
2b1f13 |
{
|
|
Packit Service |
2b1f13 |
register DisplayEntry *d, *prev;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
for (d = elist, prev = NULL; d; d = d->next) {
|
|
Packit Service |
2b1f13 |
if (d->dpy == dpy) {
|
|
Packit Service |
2b1f13 |
if (prevp) *prevp = prev;
|
|
Packit Service |
2b1f13 |
return d;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
prev = d;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
return NULL;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* _DoCallbacks - process all of the callbacks for this display and free
|
|
Packit Service |
2b1f13 |
* the associated callback data (callback records and display entries).
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
/* ARGSUSED */
|
|
Packit Service |
2b1f13 |
static int
|
|
Packit Service |
2b1f13 |
_DoCallbacks(Display *dpy, XExtCodes *codes)
|
|
Packit Service |
2b1f13 |
{
|
|
Packit Service |
2b1f13 |
register CallbackRec *h;
|
|
Packit Service |
2b1f13 |
DisplayEntry *prev;
|
|
Packit Service |
2b1f13 |
DisplayEntry *de = _FindDisplayEntry (dpy, &prev;;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
if (!de) return 0;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/* walk the list doing the callbacks and freeing callback record */
|
|
Packit Service |
2b1f13 |
for (h = de->start; h;) {
|
|
Packit Service |
2b1f13 |
register CallbackRec *nexth = h->next;
|
|
Packit Service |
2b1f13 |
de->calling = h; /* let remove know we'll free it */
|
|
Packit Service |
2b1f13 |
(*(h->func)) (dpy, h->arg);
|
|
Packit Service |
2b1f13 |
de->calling = NULL;
|
|
Packit Service |
2b1f13 |
free ((char *) h);
|
|
Packit Service |
2b1f13 |
h = nexth;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/* unlink this display from chain */
|
|
Packit Service |
2b1f13 |
if (elist == de) {
|
|
Packit Service |
2b1f13 |
elist = de->next;
|
|
Packit Service |
2b1f13 |
} else {
|
|
Packit Service |
2b1f13 |
prev->next = de->next;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
free ((char *) de);
|
|
Packit Service |
2b1f13 |
return 1;
|
|
Packit Service |
2b1f13 |
}
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
/*
|
|
Packit Service |
2b1f13 |
* _MakeExtension - create an extension for this display; done once per display
|
|
Packit Service |
2b1f13 |
*/
|
|
Packit Service |
2b1f13 |
static Bool
|
|
Packit Service |
2b1f13 |
_MakeExtension(Display *dpy, int *extensionp)
|
|
Packit Service |
2b1f13 |
{
|
|
Packit Service |
2b1f13 |
XExtCodes *codes;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
codes = XAddExtension (dpy);
|
|
Packit Service |
2b1f13 |
if (!codes) return False;
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
(void) XESetCloseDisplay (dpy, codes->extension, _DoCallbacks);
|
|
Packit Service |
2b1f13 |
|
|
Packit Service |
2b1f13 |
*extensionp = codes->extension;
|
|
Packit Service |
2b1f13 |
return True;
|
|
Packit Service |
2b1f13 |
}
|