#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <X11/Xlib.h>
#include <stdlib.h>
#include <X11/Xmu/DisplayQue.h>
static int _DQCloseDisplay(Display*, XPointer);
#define CallCloseCallback(q,e) (void) (*((q)->closefunc)) ((q), (e))
#define CallFreeCallback(q) (void) (*((q)->freefunc)) ((q))
XmuDisplayQueue *
XmuDQCreate(XmuCloseDisplayQueueProc closefunc,
XmuFreeDisplayQueueProc freefunc,
XPointer data)
{
XmuDisplayQueue *q = (XmuDisplayQueue *) malloc (sizeof (XmuDisplayQueue));
if (q) {
q->nentries = 0;
q->head = q->tail = NULL;
q->closefunc = closefunc;
q->freefunc = freefunc;
q->data = data;
}
return q;
}
Bool
XmuDQDestroy(XmuDisplayQueue *q, Bool docallbacks)
{
XmuDisplayQueueEntry *e = q->head;
while (e) {
XmuDisplayQueueEntry *nexte = e->next;
if (docallbacks && q->closefunc) CallCloseCallback (q, e);
free ((char *) e);
e = nexte;
}
free ((char *) q);
return True;
}
XmuDisplayQueueEntry *
XmuDQLookupDisplay(XmuDisplayQueue *q, Display *dpy)
{
XmuDisplayQueueEntry *e;
for (e = q->head; e; e = e->next) {
if (e->display == dpy) return e;
}
return NULL;
}
XmuDisplayQueueEntry *
XmuDQAddDisplay(XmuDisplayQueue *q, Display *dpy, XPointer data)
{
XmuDisplayQueueEntry *e;
if (!(e = (XmuDisplayQueueEntry *) malloc (sizeof (XmuDisplayQueueEntry)))) {
return NULL;
}
if (!(e->closehook = XmuAddCloseDisplayHook (dpy, _DQCloseDisplay,
(XPointer) q))) {
free ((char *) e);
return NULL;
}
e->display = dpy;
e->next = NULL;
e->data = data;
if (q->tail) {
q->tail->next = e;
e->prev = q->tail;
} else {
q->head = e;
e->prev = NULL;
}
q->tail = e;
q->nentries++;
return e;
}
Bool
XmuDQRemoveDisplay(XmuDisplayQueue *q, Display *dpy)
{
XmuDisplayQueueEntry *e;
for (e = q->head; e; e = e->next) {
if (e->display == dpy) {
if (q->head == e)
q->head = e->next;
else
e->prev->next = e->next;
if (q->tail == e)
q->tail = e->prev;
else
e->next->prev = e->prev;
(void) XmuRemoveCloseDisplayHook (dpy, e->closehook,
_DQCloseDisplay, (XPointer) q);
free ((char *) e);
q->nentries--;
return True;
}
}
return False;
}
static int
_DQCloseDisplay(Display *dpy, XPointer arg)
{
XmuDisplayQueue *q = (XmuDisplayQueue *) arg;
XmuDisplayQueueEntry *e;
for (e = q->head; e; e = e->next) {
if (e->display == dpy) {
if (q->closefunc) CallCloseCallback (q, e);
(void) XmuDQRemoveDisplay (q, dpy);
if (q->nentries == 0 && q->freefunc) CallFreeCallback (q);
return 1;
}
}
return 0;
}