mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 04:20:27 +01:00
Rewrote idle and input handlers using WMBag to avoid a functional problem of
them, regarding removal of other input/idle handlers next to the called one, from the called handler.
This commit is contained in:
@@ -25,6 +25,10 @@ changes since wmaker 0.61.1:
|
|||||||
- fixed a bug in how input events were posted. Establishing 2 or more input
|
- fixed a bug in how input events were posted. Establishing 2 or more input
|
||||||
handlers for the same file descriptor, handling different (read/write/except)
|
handlers for the same file descriptor, handling different (read/write/except)
|
||||||
events, caused wrong handlers to be called.
|
events, caused wrong handlers to be called.
|
||||||
|
- Reimplemented the input and idle handlers with WMBag to avoid a functional
|
||||||
|
problem with them: inability to remove handlers next to the called one, from
|
||||||
|
the called handler itself. Trying to do this with the old version caused the
|
||||||
|
program to crash.
|
||||||
|
|
||||||
changes since wmaker 0.61.0:
|
changes since wmaker 0.61.0:
|
||||||
............................
|
............................
|
||||||
|
|||||||
231
WINGs/wevent.c
231
WINGs/wevent.c
@@ -44,7 +44,6 @@ typedef struct TimerHandler {
|
|||||||
typedef struct IdleHandler {
|
typedef struct IdleHandler {
|
||||||
WMCallback *callback;
|
WMCallback *callback;
|
||||||
void *clientData;
|
void *clientData;
|
||||||
struct IdleHandler *next;
|
|
||||||
} IdleHandler;
|
} IdleHandler;
|
||||||
|
|
||||||
|
|
||||||
@@ -53,7 +52,6 @@ typedef struct InputHandler {
|
|||||||
void *clientData;
|
void *clientData;
|
||||||
int fd;
|
int fd;
|
||||||
int mask;
|
int mask;
|
||||||
struct InputHandler *next;
|
|
||||||
} InputHandler;
|
} InputHandler;
|
||||||
|
|
||||||
|
|
||||||
@@ -104,9 +102,9 @@ static unsigned long eventMasks[] = {
|
|||||||
/* queue of timer event handlers */
|
/* queue of timer event handlers */
|
||||||
static TimerHandler *timerHandler=NULL;
|
static TimerHandler *timerHandler=NULL;
|
||||||
|
|
||||||
static IdleHandler *idleHandler=NULL;
|
static WMBag *idleHandler=NULL;
|
||||||
|
|
||||||
static InputHandler *inputHandler=NULL;
|
static WMBag *inputHandler=NULL;
|
||||||
|
|
||||||
/* hook for other toolkits or wmaker process their events */
|
/* hook for other toolkits or wmaker process their events */
|
||||||
static WMEventHook *extraEventHandler=NULL;
|
static WMEventHook *extraEventHandler=NULL;
|
||||||
@@ -225,25 +223,19 @@ WMDeleteTimerHandler(WMHandlerID handlerID)
|
|||||||
WMHandlerID
|
WMHandlerID
|
||||||
WMAddIdleHandler(WMCallback *callback, void *cdata)
|
WMAddIdleHandler(WMCallback *callback, void *cdata)
|
||||||
{
|
{
|
||||||
IdleHandler *handler, *tmp;
|
IdleHandler *handler;
|
||||||
|
|
||||||
handler = malloc(sizeof(IdleHandler));
|
handler = malloc(sizeof(IdleHandler));
|
||||||
if (!handler)
|
if (!handler)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
handler->callback = callback;
|
handler->callback = callback;
|
||||||
handler->clientData = cdata;
|
handler->clientData = cdata;
|
||||||
handler->next = NULL;
|
/* add handler at end of queue */
|
||||||
/* add callback at end of queue */
|
|
||||||
if (!idleHandler) {
|
if (!idleHandler) {
|
||||||
idleHandler = handler;
|
idleHandler = WMCreateBag(16);
|
||||||
} else {
|
|
||||||
tmp = idleHandler;
|
|
||||||
while (tmp->next) {
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
tmp->next = handler;
|
|
||||||
}
|
}
|
||||||
|
WMPutInBag(idleHandler, handler);
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
@@ -253,24 +245,16 @@ WMAddIdleHandler(WMCallback *callback, void *cdata)
|
|||||||
void
|
void
|
||||||
WMDeleteIdleHandler(WMHandlerID handlerID)
|
WMDeleteIdleHandler(WMHandlerID handlerID)
|
||||||
{
|
{
|
||||||
IdleHandler *tmp, *handler = (IdleHandler*)handlerID;
|
IdleHandler *handler = (IdleHandler*)handlerID;
|
||||||
|
int pos;
|
||||||
|
|
||||||
if (!handler || !idleHandler)
|
if (!handler || !idleHandler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmp = idleHandler;
|
pos = WMGetFirstInBag(idleHandler, handler);
|
||||||
if (tmp == handler) {
|
if (pos >= 0) {
|
||||||
idleHandler = handler->next;
|
wfree(handler);
|
||||||
wfree(handler);
|
WMDeleteFromBag(idleHandler, pos);
|
||||||
} else {
|
|
||||||
while (tmp->next) {
|
|
||||||
if (tmp->next == handler) {
|
|
||||||
tmp->next = handler->next;
|
|
||||||
wfree(handler);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,76 +264,75 @@ WMHandlerID
|
|||||||
WMAddInputHandler(int fd, int condition, WMInputProc *proc, void *clientData)
|
WMAddInputHandler(int fd, int condition, WMInputProc *proc, void *clientData)
|
||||||
{
|
{
|
||||||
InputHandler *handler;
|
InputHandler *handler;
|
||||||
|
|
||||||
handler = wmalloc(sizeof(InputHandler));
|
handler = wmalloc(sizeof(InputHandler));
|
||||||
|
|
||||||
handler->fd = fd;
|
handler->fd = fd;
|
||||||
handler->mask = condition;
|
handler->mask = condition;
|
||||||
handler->callback = proc;
|
handler->callback = proc;
|
||||||
handler->clientData = clientData;
|
handler->clientData = clientData;
|
||||||
|
|
||||||
handler->next = inputHandler;
|
if (!inputHandler)
|
||||||
|
inputHandler = WMCreateBag(16);
|
||||||
inputHandler = handler;
|
WMPutInBag(inputHandler, handler);
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WMDeleteInputHandler(WMHandlerID handlerID)
|
WMDeleteInputHandler(WMHandlerID handlerID)
|
||||||
{
|
{
|
||||||
InputHandler *tmp, *handler = (InputHandler*)handlerID;
|
InputHandler *handler = (InputHandler*)handlerID;
|
||||||
|
int pos;
|
||||||
|
|
||||||
if (!handler || !inputHandler)
|
if (!handler || !inputHandler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmp = inputHandler;
|
pos = WMGetFirstInBag(inputHandler, handler);
|
||||||
if (tmp == handler) {
|
if (pos >= 0) {
|
||||||
inputHandler = handler->next;
|
wfree(handler);
|
||||||
wfree(handler);
|
WMDeleteFromBag(inputHandler, pos);
|
||||||
} else {
|
}
|
||||||
while (tmp->next) {
|
|
||||||
if (tmp->next == handler) {
|
|
||||||
tmp->next = handler->next;
|
|
||||||
wfree(handler);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
checkIdleHandlers()
|
checkIdleHandlers()
|
||||||
{
|
{
|
||||||
IdleHandler *handler, *tmp;
|
IdleHandler *handler;
|
||||||
|
WMBag *handlerCopy;
|
||||||
|
int i, n;
|
||||||
|
|
||||||
if (!idleHandler) {
|
if (!idleHandler || WMGetBagItemCount(idleHandler)==0) {
|
||||||
W_FlushIdleNotificationQueue();
|
W_FlushIdleNotificationQueue();
|
||||||
/* make sure an observer in queue didn't added an idle handler */
|
/* make sure an observer in queue didn't added an idle handler */
|
||||||
return (idleHandler!=NULL);
|
return (idleHandler!=NULL && WMGetBagItemCount(idleHandler)>0);
|
||||||
}
|
}
|
||||||
|
|
||||||
handler = idleHandler;
|
|
||||||
|
|
||||||
/* we will process all idleHandlers so, empty the handler list */
|
|
||||||
idleHandler = NULL;
|
|
||||||
|
|
||||||
while (handler) {
|
n = WMGetBagItemCount(idleHandler);
|
||||||
tmp = handler->next;
|
handlerCopy = WMCreateBag(n);
|
||||||
|
for (i=0; i<n; i++)
|
||||||
|
WMPutInBag(handlerCopy, WMGetFromBag(idleHandler, i));
|
||||||
|
|
||||||
|
for (i=0; i<n; i++) {
|
||||||
|
handler = WMGetFromBag(handlerCopy, i);
|
||||||
|
/* check if the handler still exist or was removed by a callback */
|
||||||
|
if (WMGetFirstInBag(idleHandler, handler)<0)
|
||||||
|
continue;
|
||||||
|
|
||||||
(*handler->callback)(handler->clientData);
|
(*handler->callback)(handler->clientData);
|
||||||
/* remove the handler */
|
WMDeleteIdleHandler(handler);
|
||||||
wfree(handler);
|
|
||||||
|
|
||||||
handler = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WMFreeBag(handlerCopy);
|
||||||
|
|
||||||
W_FlushIdleNotificationQueue();
|
W_FlushIdleNotificationQueue();
|
||||||
|
|
||||||
/* this is not necesarrily False, because one handler can re-add itself */
|
/* this is not necesarrily False, because one handler can re-add itself */
|
||||||
return (idleHandler!=NULL);
|
return (WMGetBagItemCount(idleHandler)>0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -736,29 +719,31 @@ W_WaitForEvent(Display *dpy, unsigned long xeventmask)
|
|||||||
#if defined(HAVE_POLL) && defined(HAVE_POLL_H) && !defined(HAVE_SELECT)
|
#if defined(HAVE_POLL) && defined(HAVE_POLL_H) && !defined(HAVE_SELECT)
|
||||||
struct pollfd *fds;
|
struct pollfd *fds;
|
||||||
InputHandler *handler;
|
InputHandler *handler;
|
||||||
int count, timeout, nfds, k, retval;
|
int count, timeout, nfds, i, retval;
|
||||||
|
|
||||||
for (nfds = 1, handler = inputHandler;
|
if (inputHandler)
|
||||||
handler != 0; handler = handler->next) nfds++;
|
nfds = WMGetBagItemCount(inputHandler);
|
||||||
|
else
|
||||||
fds = wmalloc(nfds * sizeof(struct pollfd));
|
nfds = 0;
|
||||||
fds[0].fd = ConnectionNumber(dpy);
|
|
||||||
fds[0].events = POLLIN;
|
|
||||||
|
|
||||||
for (k = 1, handler = inputHandler;
|
fds = wmalloc(nfds+1 * sizeof(struct pollfd));
|
||||||
handler;
|
/* put this to the end of array to avoid using ranges from 1 to nfds+1 */
|
||||||
handler = handler->next, k++) {
|
fds[nfds].fd = ConnectionNumber(dpy);
|
||||||
fds[k].fd = handler->fd;
|
fds[nfds].events = POLLIN;
|
||||||
fds[k].events = 0;
|
|
||||||
if (handler->mask & WIReadMask)
|
|
||||||
fds[k].events |= POLLIN;
|
|
||||||
|
|
||||||
if (handler->mask & WIWriteMask)
|
for (i = 0; i<nfds; i++) {
|
||||||
fds[k].events |= POLLOUT;
|
handler = WMGetFromBag(inputHandler, i);
|
||||||
|
fds[i].fd = handler->fd;
|
||||||
|
fds[i].events = 0;
|
||||||
|
if (handler->mask & WIReadMask)
|
||||||
|
fds[i].events |= POLLIN;
|
||||||
|
|
||||||
|
if (handler->mask & WIWriteMask)
|
||||||
|
fds[i].events |= POLLOUT;
|
||||||
|
|
||||||
#if 0 /* FIXME */
|
#if 0 /* FIXME */
|
||||||
if (handler->mask & WIExceptMask)
|
if (handler->mask & WIExceptMask)
|
||||||
FD_SET(handler->fd, &eset);
|
FD_SET(handler->fd, &eset);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,40 +772,44 @@ W_WaitForEvent(Display *dpy, unsigned long xeventmask)
|
|||||||
|
|
||||||
count = poll(fds, nfds, timeout);
|
count = poll(fds, nfds, timeout);
|
||||||
|
|
||||||
if (count > 0) {
|
if (count>0 && nfds>0) {
|
||||||
handler = inputHandler;
|
WMBag *handlerCopy = WMCreateBag(nfds);
|
||||||
k = 1;
|
|
||||||
while (handler) {
|
for (i=0; i<nfds; i++)
|
||||||
|
WMPutInBag(handlerCopy, WMGetFromBag(inputHandler, i));
|
||||||
|
|
||||||
|
for (i=0; i<nfds; i++) {
|
||||||
int mask;
|
int mask;
|
||||||
InputHandler *next;
|
|
||||||
|
handler = WMGetFromBag(handlerCopy, i);
|
||||||
|
/* check if the handler still exist or was removed by a callback */
|
||||||
|
if (WMGetFirstInBag(inputHandler, handler)<0)
|
||||||
|
continue;
|
||||||
|
|
||||||
mask = 0;
|
mask = 0;
|
||||||
|
|
||||||
if ((handler->mask & WIReadMask) &&
|
if ((handler->mask & WIReadMask) &&
|
||||||
(fds[k].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI)))
|
(fds[i].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI)))
|
||||||
mask |= WIReadMask;
|
mask |= WIReadMask;
|
||||||
|
|
||||||
if ((handler->mask & WIWriteMask) &&
|
if ((handler->mask & WIWriteMask) &&
|
||||||
(fds[k].revents & (POLLOUT | POLLWRBAND)))
|
(fds[i].revents & (POLLOUT | POLLWRBAND)))
|
||||||
mask |= WIWriteMask;
|
mask |= WIWriteMask;
|
||||||
|
|
||||||
if ((handler->mask & WIExceptMask) &&
|
if ((handler->mask & WIExceptMask) &&
|
||||||
(fds[k].revents & (POLLHUP | POLLNVAL | POLLERR)))
|
(fds[i].revents & (POLLHUP | POLLNVAL | POLLERR)))
|
||||||
mask |= WIExceptMask;
|
mask |= WIExceptMask;
|
||||||
|
|
||||||
next = handler->next;
|
|
||||||
|
|
||||||
if (mask!=0 && handler->callback) {
|
if (mask!=0 && handler->callback) {
|
||||||
(*handler->callback)(handler->fd, mask,
|
(*handler->callback)(handler->fd, mask,
|
||||||
handler->clientData);
|
handler->clientData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handler = next;
|
WMFreeBag(handlerCopy);
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = fds[0].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI);
|
retval = fds[nfds].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI);
|
||||||
wfree(fds);
|
wfree(fds);
|
||||||
|
|
||||||
W_FlushASAPNotificationQueue();
|
W_FlushASAPNotificationQueue();
|
||||||
@@ -831,9 +820,9 @@ W_WaitForEvent(Display *dpy, unsigned long xeventmask)
|
|||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
struct timeval *timeoutPtr;
|
struct timeval *timeoutPtr;
|
||||||
fd_set rset, wset, eset;
|
fd_set rset, wset, eset;
|
||||||
int maxfd;
|
int maxfd, nfds, i;
|
||||||
int count;
|
int count;
|
||||||
InputHandler *handler = inputHandler;
|
InputHandler *handler;
|
||||||
|
|
||||||
FD_ZERO(&rset);
|
FD_ZERO(&rset);
|
||||||
FD_ZERO(&wset);
|
FD_ZERO(&wset);
|
||||||
@@ -842,7 +831,13 @@ W_WaitForEvent(Display *dpy, unsigned long xeventmask)
|
|||||||
FD_SET(ConnectionNumber(dpy), &rset);
|
FD_SET(ConnectionNumber(dpy), &rset);
|
||||||
maxfd = ConnectionNumber(dpy);
|
maxfd = ConnectionNumber(dpy);
|
||||||
|
|
||||||
while (handler) {
|
if (inputHandler)
|
||||||
|
nfds = WMGetBagItemCount(inputHandler);
|
||||||
|
else
|
||||||
|
nfds = 0;
|
||||||
|
|
||||||
|
for (i=0; i<nfds; i++) {
|
||||||
|
handler = WMGetFromBag(inputHandler, i);
|
||||||
if (handler->mask & WIReadMask)
|
if (handler->mask & WIReadMask)
|
||||||
FD_SET(handler->fd, &rset);
|
FD_SET(handler->fd, &rset);
|
||||||
|
|
||||||
@@ -854,8 +849,6 @@ W_WaitForEvent(Display *dpy, unsigned long xeventmask)
|
|||||||
|
|
||||||
if (maxfd < handler->fd)
|
if (maxfd < handler->fd)
|
||||||
maxfd = handler->fd;
|
maxfd = handler->fd;
|
||||||
|
|
||||||
handler = handler->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -881,37 +874,41 @@ W_WaitForEvent(Display *dpy, unsigned long xeventmask)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
count = select(1 + maxfd, &rset, &wset, &eset, timeoutPtr);
|
count = select(1 + maxfd, &rset, &wset, &eset, timeoutPtr);
|
||||||
|
|
||||||
if (count > 0) {
|
if (count>0 && nfds>0) {
|
||||||
handler = inputHandler;
|
WMBag *handlerCopy = WMCreateBag(nfds);
|
||||||
|
|
||||||
while (handler) {
|
for (i=0; i<nfds; i++)
|
||||||
|
WMPutInBag(handlerCopy, WMGetFromBag(inputHandler, i));
|
||||||
|
|
||||||
|
for (i=0; i<nfds; i++) {
|
||||||
int mask;
|
int mask;
|
||||||
InputHandler *next;
|
|
||||||
|
handler = WMGetFromBag(handlerCopy, i);
|
||||||
|
/* check if the handler still exist or was removed by a callback */
|
||||||
|
if (WMGetFirstInBag(inputHandler, handler)<0)
|
||||||
|
continue;
|
||||||
|
|
||||||
mask = 0;
|
mask = 0;
|
||||||
|
|
||||||
if ((handler->mask & WIReadMask) && FD_ISSET(handler->fd, &rset))
|
if ((handler->mask & WIReadMask) && FD_ISSET(handler->fd, &rset))
|
||||||
mask |= WIReadMask;
|
mask |= WIReadMask;
|
||||||
|
|
||||||
if ((handler->mask & WIWriteMask) && FD_ISSET(handler->fd, &wset))
|
if ((handler->mask & WIWriteMask) && FD_ISSET(handler->fd, &wset))
|
||||||
mask |= WIWriteMask;
|
mask |= WIWriteMask;
|
||||||
|
|
||||||
if ((handler->mask & WIExceptMask) && FD_ISSET(handler->fd, &eset))
|
if ((handler->mask & WIExceptMask) && FD_ISSET(handler->fd, &eset))
|
||||||
mask |= WIExceptMask;
|
mask |= WIExceptMask;
|
||||||
|
|
||||||
/* save it because the handler may remove itself! */
|
|
||||||
next = handler->next;
|
|
||||||
|
|
||||||
if (mask!=0 && handler->callback) {
|
if (mask!=0 && handler->callback) {
|
||||||
(*handler->callback)(handler->fd, mask,
|
(*handler->callback)(handler->fd, mask,
|
||||||
handler->clientData);
|
handler->clientData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handler = next;
|
WMFreeBag(handlerCopy);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
W_FlushASAPNotificationQueue();
|
W_FlushASAPNotificationQueue();
|
||||||
|
|||||||
@@ -856,7 +856,7 @@ familyClick(WMWidget *w, void *data)
|
|||||||
|
|
||||||
for (i = 0; i < WMGetBagItemCount(family->typefaces); i++) {
|
for (i = 0; i < WMGetBagItemCount(family->typefaces); i++) {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
int top;
|
int top=0;
|
||||||
WMListItem *fitem;
|
WMListItem *fitem;
|
||||||
|
|
||||||
face = WMGetFromBag(family->typefaces, i);
|
face = WMGetFromBag(family->typefaces, i);
|
||||||
|
|||||||
@@ -976,7 +976,7 @@ handleTextFieldKeyPress(TextField *tPtr, XEvent *event)
|
|||||||
char buffer[64];
|
char buffer[64];
|
||||||
KeySym ksym;
|
KeySym ksym;
|
||||||
char *textEvent = NULL;
|
char *textEvent = NULL;
|
||||||
void *data;
|
void *data = NULL;
|
||||||
int count, refresh = 0;
|
int count, refresh = 0;
|
||||||
int control_pressed = 0;
|
int control_pressed = 0;
|
||||||
int cancelSelection = 1;
|
int cancelSelection = 1;
|
||||||
|
|||||||
188
WINGs/wutil.c
188
WINGs/wutil.c
@@ -43,7 +43,6 @@ typedef struct TimerHandler {
|
|||||||
typedef struct IdleHandler {
|
typedef struct IdleHandler {
|
||||||
WMCallback *callback;
|
WMCallback *callback;
|
||||||
void *clientData;
|
void *clientData;
|
||||||
struct IdleHandler *next;
|
|
||||||
} IdleHandler;
|
} IdleHandler;
|
||||||
|
|
||||||
|
|
||||||
@@ -52,16 +51,15 @@ typedef struct InputHandler {
|
|||||||
void *clientData;
|
void *clientData;
|
||||||
int fd;
|
int fd;
|
||||||
int mask;
|
int mask;
|
||||||
struct InputHandler *next;
|
|
||||||
} InputHandler;
|
} InputHandler;
|
||||||
|
|
||||||
|
|
||||||
/* queue of timer event handlers */
|
/* queue of timer event handlers */
|
||||||
static TimerHandler *timerHandler=NULL;
|
static TimerHandler *timerHandler=NULL;
|
||||||
|
|
||||||
static IdleHandler *idleHandler=NULL;
|
static WMBag *idleHandler=NULL;
|
||||||
|
|
||||||
static InputHandler *inputHandler=NULL;
|
static WMBag *inputHandler=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -176,7 +174,7 @@ WMDeleteTimerHandler(WMHandlerID handlerID)
|
|||||||
WMHandlerID
|
WMHandlerID
|
||||||
WMAddIdleHandler(WMCallback *callback, void *cdata)
|
WMAddIdleHandler(WMCallback *callback, void *cdata)
|
||||||
{
|
{
|
||||||
IdleHandler *handler, *tmp;
|
IdleHandler *handler;
|
||||||
|
|
||||||
handler = malloc(sizeof(IdleHandler));
|
handler = malloc(sizeof(IdleHandler));
|
||||||
if (!handler)
|
if (!handler)
|
||||||
@@ -184,17 +182,11 @@ WMAddIdleHandler(WMCallback *callback, void *cdata)
|
|||||||
|
|
||||||
handler->callback = callback;
|
handler->callback = callback;
|
||||||
handler->clientData = cdata;
|
handler->clientData = cdata;
|
||||||
handler->next = NULL;
|
/* add handler at end of queue */
|
||||||
/* add callback at end of queue */
|
|
||||||
if (!idleHandler) {
|
if (!idleHandler) {
|
||||||
idleHandler = handler;
|
idleHandler = WMCreateBag(16);
|
||||||
} else {
|
|
||||||
tmp = idleHandler;
|
|
||||||
while (tmp->next) {
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
tmp->next = handler;
|
|
||||||
}
|
}
|
||||||
|
WMPutInBag(idleHandler, handler);
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
@@ -204,24 +196,16 @@ WMAddIdleHandler(WMCallback *callback, void *cdata)
|
|||||||
void
|
void
|
||||||
WMDeleteIdleHandler(WMHandlerID handlerID)
|
WMDeleteIdleHandler(WMHandlerID handlerID)
|
||||||
{
|
{
|
||||||
IdleHandler *tmp, *handler = (IdleHandler*)handlerID;
|
IdleHandler *handler = (IdleHandler*)handlerID;
|
||||||
|
int pos;
|
||||||
|
|
||||||
if (!handler || !idleHandler)
|
if (!handler || !idleHandler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmp = idleHandler;
|
pos = WMGetFirstInBag(idleHandler, handler);
|
||||||
if (tmp == handler) {
|
if (pos >= 0) {
|
||||||
idleHandler = handler->next;
|
wfree(handler);
|
||||||
wfree(handler);
|
WMDeleteFromBag(idleHandler, pos);
|
||||||
} else {
|
|
||||||
while (tmp->next) {
|
|
||||||
if (tmp->next == handler) {
|
|
||||||
tmp->next = handler->next;
|
|
||||||
wfree(handler);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,68 +223,68 @@ WMAddInputHandler(int fd, int condition, WMInputProc *proc, void *clientData)
|
|||||||
handler->callback = proc;
|
handler->callback = proc;
|
||||||
handler->clientData = clientData;
|
handler->clientData = clientData;
|
||||||
|
|
||||||
handler->next = inputHandler;
|
if (!inputHandler)
|
||||||
|
inputHandler = WMCreateBag(16);
|
||||||
inputHandler = handler;
|
WMPutInBag(inputHandler, handler);
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WMDeleteInputHandler(WMHandlerID handlerID)
|
WMDeleteInputHandler(WMHandlerID handlerID)
|
||||||
{
|
{
|
||||||
InputHandler *tmp, *handler = (InputHandler*)handlerID;
|
InputHandler *handler = (InputHandler*)handlerID;
|
||||||
|
int pos;
|
||||||
|
|
||||||
if (!handler || !inputHandler)
|
if (!handler || !inputHandler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tmp = inputHandler;
|
pos = WMGetFirstInBag(inputHandler, handler);
|
||||||
if (tmp == handler) {
|
if (pos >= 0) {
|
||||||
inputHandler = handler->next;
|
wfree(handler);
|
||||||
wfree(handler);
|
WMDeleteFromBag(inputHandler, pos);
|
||||||
} else {
|
|
||||||
while (tmp->next) {
|
|
||||||
if (tmp->next == handler) {
|
|
||||||
tmp->next = handler->next;
|
|
||||||
wfree(handler);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tmp = tmp->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
checkIdleHandlers()
|
checkIdleHandlers()
|
||||||
{
|
{
|
||||||
IdleHandler *handler, *tmp;
|
IdleHandler *handler;
|
||||||
|
WMBag *handlerCopy;
|
||||||
|
int i, n;
|
||||||
|
|
||||||
if (!idleHandler) {
|
if (!idleHandler || WMGetBagItemCount(idleHandler)==0) {
|
||||||
W_FlushIdleNotificationQueue();
|
W_FlushIdleNotificationQueue();
|
||||||
/* make sure an observer in queue didn't added an idle handler */
|
/* make sure an observer in queue didn't added an idle handler */
|
||||||
return (idleHandler!=NULL);
|
return (idleHandler!=NULL && WMGetBagItemCount(idleHandler)>0);
|
||||||
}
|
}
|
||||||
|
|
||||||
handler = idleHandler;
|
n = WMGetBagItemCount(idleHandler);
|
||||||
|
handlerCopy = WMCreateBag(n);
|
||||||
|
for (i=0; i<n; i++)
|
||||||
|
WMPutInBag(handlerCopy, WMGetFromBag(idleHandler, i));
|
||||||
|
|
||||||
/* we will process all idleHandlers so, empty the handler list */
|
for (i=0; i<n; i++) {
|
||||||
idleHandler = NULL;
|
handler = WMGetFromBag(handlerCopy, i);
|
||||||
|
/* check if the handler still exist or was removed by a callback */
|
||||||
|
if (WMGetFirstInBag(idleHandler, handler)<0)
|
||||||
|
continue;
|
||||||
|
|
||||||
while (handler) {
|
|
||||||
tmp = handler->next;
|
|
||||||
(*handler->callback)(handler->clientData);
|
(*handler->callback)(handler->clientData);
|
||||||
/* remove the handler */
|
WMDeleteIdleHandler(handler);
|
||||||
wfree(handler);
|
wfree(handler);
|
||||||
|
|
||||||
handler = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WMFreeBag(handlerCopy);
|
||||||
|
|
||||||
W_FlushIdleNotificationQueue();
|
W_FlushIdleNotificationQueue();
|
||||||
|
|
||||||
/* this is not necesarrily False, because one handler can re-add itself */
|
/* this is not necesarrily False, because one handler can re-add itself */
|
||||||
return (idleHandler!=NULL);
|
return (WMGetBagItemCount(idleHandler)>0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -387,28 +371,24 @@ handleInputEvents(Bool waitForInput)
|
|||||||
#if defined(HAVE_POLL) && defined(HAVE_POLL_H) && !defined(HAVE_SELECT)
|
#if defined(HAVE_POLL) && defined(HAVE_POLL_H) && !defined(HAVE_SELECT)
|
||||||
struct pollfd *fds;
|
struct pollfd *fds;
|
||||||
InputHandler *handler;
|
InputHandler *handler;
|
||||||
int count, timeout, nfds, k;
|
int count, timeout, nfds, i;
|
||||||
|
|
||||||
if (!inputHandler) {
|
if (!inputHandler || (nfds=WMGetBagItemCount(inputHandler))==0) {
|
||||||
W_FlushASAPNotificationQueue();
|
W_FlushASAPNotificationQueue();
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (nfds = 0, handler = inputHandler;
|
|
||||||
handler != 0; handler = handler->next) nfds++;
|
|
||||||
|
|
||||||
fds = wmalloc(nfds * sizeof(struct pollfd));
|
fds = wmalloc(nfds * sizeof(struct pollfd));
|
||||||
|
|
||||||
for (k = 0, handler = inputHandler;
|
for (i = 0; i<nfds; i++) {
|
||||||
handler;
|
handler = WMGetFromBag(inputHandler, i);
|
||||||
handler = handler->next, k++) {
|
fds[i].fd = handler->fd;
|
||||||
fds[k].fd = handler->fd;
|
fds[i].events = 0;
|
||||||
fds[k].events = 0;
|
|
||||||
if (handler->mask & WIReadMask)
|
if (handler->mask & WIReadMask)
|
||||||
fds[k].events |= POLLIN;
|
fds[i].events |= POLLIN;
|
||||||
|
|
||||||
if (handler->mask & WIWriteMask)
|
if (handler->mask & WIWriteMask)
|
||||||
fds[k].events |= POLLOUT;
|
fds[i].events |= POLLOUT;
|
||||||
|
|
||||||
#if 0 /* FIXME */
|
#if 0 /* FIXME */
|
||||||
if (handler->mask & WIExceptMask)
|
if (handler->mask & WIExceptMask)
|
||||||
@@ -434,36 +414,40 @@ handleInputEvents(Bool waitForInput)
|
|||||||
count = poll(fds, nfds, timeout);
|
count = poll(fds, nfds, timeout);
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
handler = inputHandler;
|
WMBag *handlerCopy = WMCreateBag(nfds);
|
||||||
k = 0;
|
|
||||||
while (handler) {
|
for (i=0; i<nfds, i++)
|
||||||
|
WMPutInBag(handlerCopy, WMGetFromBag(inputHandler, i));
|
||||||
|
|
||||||
|
for (i=0; i<nfds; i++) {
|
||||||
int mask;
|
int mask;
|
||||||
InputHandler *next;
|
|
||||||
|
handler = WMGetFromBag(handlerCopy, i);
|
||||||
|
/* check if the handler still exist or was removed by a callback */
|
||||||
|
if (WMGetFirstInBag(inputHandler, handler)<0)
|
||||||
|
continue;
|
||||||
|
|
||||||
mask = 0;
|
mask = 0;
|
||||||
|
|
||||||
if ((handler->mask & WIReadMask) &&
|
if ((handler->mask & WIReadMask) &&
|
||||||
(fds[k].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI)))
|
(fds[i].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI)))
|
||||||
mask |= WIReadMask;
|
mask |= WIReadMask;
|
||||||
|
|
||||||
if ((handler->mask & WIWriteMask) &&
|
if ((handler->mask & WIWriteMask) &&
|
||||||
(fds[k].revents & (POLLOUT | POLLWRBAND)))
|
(fds[i].revents & (POLLOUT | POLLWRBAND)))
|
||||||
mask |= WIWriteMask;
|
mask |= WIWriteMask;
|
||||||
|
|
||||||
if ((handler->mask & WIExceptMask) &&
|
if ((handler->mask & WIExceptMask) &&
|
||||||
(fds[k].revents & (POLLHUP | POLLNVAL | POLLERR)))
|
(fds[i].revents & (POLLHUP | POLLNVAL | POLLERR)))
|
||||||
mask |= WIExceptMask;
|
mask |= WIExceptMask;
|
||||||
|
|
||||||
next = handler->next;
|
|
||||||
|
|
||||||
if (mask!=0 && handler->callback) {
|
if (mask!=0 && handler->callback) {
|
||||||
(*handler->callback)(handler->fd, mask,
|
(*handler->callback)(handler->fd, mask,
|
||||||
handler->clientData);
|
handler->clientData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handler = next;
|
WMFreeBag(handlerCopy);
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wfree(fds);
|
wfree(fds);
|
||||||
@@ -476,11 +460,11 @@ handleInputEvents(Bool waitForInput)
|
|||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
struct timeval *timeoutPtr;
|
struct timeval *timeoutPtr;
|
||||||
fd_set rset, wset, eset;
|
fd_set rset, wset, eset;
|
||||||
int maxfd;
|
int maxfd, nfds, i;
|
||||||
int count;
|
int count;
|
||||||
InputHandler *handler = inputHandler;
|
InputHandler *handler;
|
||||||
|
|
||||||
if (!inputHandler) {
|
if (!inputHandler || (nfds=WMGetBagItemCount(inputHandler))==0) {
|
||||||
W_FlushASAPNotificationQueue();
|
W_FlushASAPNotificationQueue();
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
@@ -491,7 +475,8 @@ handleInputEvents(Bool waitForInput)
|
|||||||
|
|
||||||
maxfd = 0;
|
maxfd = 0;
|
||||||
|
|
||||||
while (handler) {
|
for (i=0; i<nfds; i++) {
|
||||||
|
handler = WMGetFromBag(inputHandler, i);
|
||||||
if (handler->mask & WIReadMask)
|
if (handler->mask & WIReadMask)
|
||||||
FD_SET(handler->fd, &rset);
|
FD_SET(handler->fd, &rset);
|
||||||
|
|
||||||
@@ -503,8 +488,6 @@ handleInputEvents(Bool waitForInput)
|
|||||||
|
|
||||||
if (maxfd < handler->fd)
|
if (maxfd < handler->fd)
|
||||||
maxfd = handler->fd;
|
maxfd = handler->fd;
|
||||||
|
|
||||||
handler = handler->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -526,11 +509,18 @@ handleInputEvents(Bool waitForInput)
|
|||||||
count = select(1 + maxfd, &rset, &wset, &eset, timeoutPtr);
|
count = select(1 + maxfd, &rset, &wset, &eset, timeoutPtr);
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
handler = inputHandler;
|
WMBag *handlerCopy = WMCreateBag(nfds);
|
||||||
|
|
||||||
while (handler) {
|
for (i=0; i<nfds; i++)
|
||||||
|
WMPutInBag(handlerCopy, WMGetFromBag(inputHandler, i));
|
||||||
|
|
||||||
|
for (i=0; i<nfds; i++) {
|
||||||
int mask;
|
int mask;
|
||||||
InputHandler *next;
|
|
||||||
|
handler = WMGetFromBag(handlerCopy, i);
|
||||||
|
/* check if the handler still exist or was removed by a callback */
|
||||||
|
if (WMGetFirstInBag(inputHandler, handler)<0)
|
||||||
|
continue;
|
||||||
|
|
||||||
mask = 0;
|
mask = 0;
|
||||||
|
|
||||||
@@ -543,16 +533,13 @@ handleInputEvents(Bool waitForInput)
|
|||||||
if ((handler->mask & WIExceptMask) && FD_ISSET(handler->fd, &eset))
|
if ((handler->mask & WIExceptMask) && FD_ISSET(handler->fd, &eset))
|
||||||
mask |= WIExceptMask;
|
mask |= WIExceptMask;
|
||||||
|
|
||||||
/* save it because the handler may remove itself! */
|
|
||||||
next = handler->next;
|
|
||||||
|
|
||||||
if (mask!=0 && handler->callback) {
|
if (mask!=0 && handler->callback) {
|
||||||
(*handler->callback)(handler->fd, mask,
|
(*handler->callback)(handler->fd, mask,
|
||||||
handler->clientData);
|
handler->clientData);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handler = next;
|
WMFreeBag(handlerCopy);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
W_FlushASAPNotificationQueue();
|
W_FlushASAPNotificationQueue();
|
||||||
@@ -575,11 +562,12 @@ WHandleEvents()
|
|||||||
* checkIdleHandlers() in a while loop, because else the while loop
|
* checkIdleHandlers() in a while loop, because else the while loop
|
||||||
* can run forever (if some idle handler reinitiates itself).
|
* can run forever (if some idle handler reinitiates itself).
|
||||||
*/
|
*/
|
||||||
if (inputHandler) {
|
if (inputHandler && WMGetBagItemCount(inputHandler)>0) {
|
||||||
/* Do idle and timer stuff while there are no input events */
|
/* Do idle and timer stuff while there are no input events */
|
||||||
/* We check InputHandler again because some idle handler could have
|
/* Check again if there are still input handlers, because some idle
|
||||||
* removed them */
|
* handler could have removed them */
|
||||||
while (checkIdleHandlers() && inputHandler && !handleInputEvents(False)) {
|
while (checkIdleHandlers() && WMGetBagItemCount(inputHandler)>0 &&
|
||||||
|
!handleInputEvents(False)) {
|
||||||
/* dispatch timer events */
|
/* dispatch timer events */
|
||||||
checkTimerHandlers();
|
checkTimerHandlers();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user