home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
evbl0627.zip
/
everblue_20010627.zip
/
x11
/
Xlib_NextEvent.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-02
|
10KB
|
369 lines
#include "Xlib_private.h"
extern long const _Xevent_to_mask[];
/*
* I don't think passing the pointers throught the pipe
* is a good idea, considering the code for peeking and
* putting back events, I am leaving the passing of
* pointers in but only as something to set off the fd
* flag, I am using the EventQueue linked list for all
* reads and writes to the event queue. Brian Smith
*/
int XNextEvent(Display *display, XEvent *event)
{
DBUG_ENTER("XNextEvent")
int rc = 0;
WinAttribData *attrib;
XEvent *ev;
Xlib_EventQueue *tmp;
#ifdef DEBUG
static char debuginfo[256];
#endif
XFlush(display);
DBUG_POINT("WinPeekMsg");
while (!EventQueue) {
QMSG qmsg;
if (WinPeekMsg(mainhab, &qmsg, NULLHANDLE, 0, 0, PM_REMOVE))
WinDispatchMsg(mainhab, &qmsg);
else
_sleep2(1);
}
/* For performance, assume pipe read/write is atomic */
DBUG_POINT("read");
rc = read(display->fd, (char *)&ev, sizeof(void *));
if (rc<0) {
DBUG_RETURN(False); /* broken by signal or alarm */
}
/* Something really went wrong if EventQueue is NULL */
if(EventQueue == NULL)
{
display->qlen = 0;
DBUG_RETURN(False);
}
pthread_mutex_lock(&evmutex);
memcpy(event, &(EventQueue->event), sizeof(XEvent));
/* Advance the Queue */
tmp = EventQueue;
EventQueue = EventQueue->next;
free(tmp);
display->qlen--;
DBUG_POINT("attrib");
attrib = WinQueryWindowPtr(event->xany.window,QWP_WINATTRIB);
if (attrib && attrib->lastexpose == ev) attrib->lastexpose = NULL;
if (attrib && attrib->lastconfigure == ev) attrib->lastconfigure = NULL;
pthread_mutex_unlock(&evmutex);
#ifdef DEBUG
sprintf(debuginfo, "Event type = %d", event->type);
DBUG_POINT(debuginfo);
#endif
DBUG_RETURN(True);
}
int XPending(Display *display)
{
DBUG_ENTER("XPending")
struct timeval tv = { 0, 0 };
fd_set readables;
/*FD_ZERO(&readables);
FD_SET(display->fd, &readables);
select(display->fd+1, &readables, NULL, NULL, &tv);
DBUG_RETURN(FD_ISSET(display->fd, &readables));*/
DBUG_RETURN(EventQueue?1:0);
}
int XPeekEvent(Display *display, XEvent *event_return)
{
DBUG_ENTER("XPeekEvent")
WinAttribData *attrib;
fd_set readables;
int ready = 0;
DBUG_POINT("XFlush()");
XFlush(display);
DBUG_POINT("spin!");
/* If we don't have an event waiting block until we have one */
while (!EventQueue) {
QMSG qmsg;
if (WinPeekMsg(mainhab, &qmsg, NULLHANDLE, 0, 0, PM_REMOVE))
WinDispatchMsg(mainhab, &qmsg);
else
_sleep2(1);
}
/* Return the tail end of the queue */
DBUG_POINT("pthread_mutex_lock()");
pthread_mutex_lock(&evmutex);
DBUG_POINT("memcpy()");
memcpy(event_return, &(EventQueue->event), sizeof(XEvent));
attrib = WinQueryWindowPtr(event_return->xany.window,QWP_WINATTRIB);
if (attrib && attrib->lastexpose == &(EventQueue->event)) attrib->lastexpose = NULL;
if (attrib && attrib->lastconfigure == &(EventQueue->event)) attrib->lastconfigure = NULL;
DBUG_POINT("pthread_mutex_unlock()");
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(True);
}
int XPutBackEvent(Display *display, XEvent *event)
{
DBUG_ENTER("XPutBackEvent")
Xlib_EventQueue *tmp;
pthread_mutex_lock(&evmutex);
/* Add the event to the top of the list */
tmp = malloc(sizeof(Xlib_EventQueue));
tmp->next = EventQueue;
EventQueue = tmp;
memcpy(&EventQueue->event, event, sizeof(XEvent));
display->qlen++;
write(pmout[1], (char *) &EventQueue->event, sizeof(void *));
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(True);
}
Bool XCheckWindowEvent(Display *display, Window w, long event_mask, XEvent *event_return)
{
DBUG_ENTER("XCheckWindowEvent")
Xlib_EventQueue *tmp, *prev = NULL;
pthread_mutex_lock(&evmutex);
tmp = EventQueue;
while(tmp != NULL)
{
if((tmp->event.xany.window == w) && (event_mask & _Xevent_to_mask[tmp->event.type]))
{
WinAttribData *attrib;
XEvent *ev;
int rc = 0;
memcpy(event_return, &tmp->event, sizeof(XEvent));
if(prev)
prev->next = tmp->next;
else
EventQueue = tmp->next;
free(tmp);
/* For performance, assume pipe read/write is atomic */
rc = read(display->fd, (char *)&ev, sizeof(void *));
if (rc<0) {
DBUG_RETURN(False); /* broken by signal or alarm */
}
attrib = WinQueryWindowPtr(event_return->xany.window,QWP_WINATTRIB);
if (attrib && attrib->lastexpose == &(tmp->event)) attrib->lastexpose = NULL;
if (attrib && attrib->lastconfigure == &(tmp->event)) attrib->lastconfigure = NULL;
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(True);
}
prev = tmp;
tmp = tmp->next;
}
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(False);
}
int XWindowEvent(Display *display, Window w, long event_mask, XEvent *event_return)
{
/* There is probably a better way of doing this but it
is eluding me at the moment. - Brian */
DBUG_ENTER("XWindowEvent")
while(!XCheckWindowEvent(display, w, event_mask, event_return))
DosSleep(1);
DBUG_RETURN(True);
}
Status XSendEvent(Display *display, Window w, Bool propagate,
long event_mask, XEvent *event_send)
{
DBUG_ENTER("XSendEvent")
Status result = Xlib_SendEvent(display, w, propagate, event_mask, event_send, TRUE);
DBUG_RETURN(result);
}
int XSelectInput(Display *display, Window w, long event_mask)
{
DBUG_ENTER("XSelectInput")
XWindowAttributes *winattrib = GetWinAttrib(w,NULL);
if (winattrib) {
winattrib->your_event_mask = event_mask;
DBUG_RETURN(True);
}
DBUG_RETURN(False);
}
/* Mode parameter appears to have no use on OS/2 since we cannot
* flush the connection and see if there are more events.
*/
int XEventsQueued(Display *display, int mode)
{
DBUG_ENTER("XEventsQueued")
int qlen;
XFlush(display);
pthread_mutex_lock(&evmutex);
qlen = display->qlen;
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(qlen);
}
int XIfEvent (display, event, predicate, arg)
register Display *display;
Bool (*predicate)(
#if NeedNestedPrototypes
Display* /* display */,
XEvent* /* event */,
char* /* arg */
#endif
); /* function to call */
register XEvent *event;
char *arg;
{
DBUG_ENTER("XIfEvent")
Xlib_EventQueue *tmp;
WinAttribData *attrib;
fd_set readables;
int ready = 0;
while(1)
{
pthread_mutex_lock(&evmutex);
tmp = EventQueue;
while(tmp != NULL)
{
if((*predicate)(display, &tmp->event, arg))
{
memcpy(event, &tmp->event, sizeof(XEvent));
attrib = WinQueryWindowPtr(tmp->event.xany.window,QWP_WINATTRIB);
if (attrib && attrib->lastexpose == &(tmp->event)) attrib->lastexpose = NULL;
if (attrib && attrib->lastconfigure == &(tmp->event)) attrib->lastconfigure = NULL;
Xlib_RemoveEvent(&tmp->event);
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(True);
}
tmp = tmp->next;
}
pthread_mutex_unlock(&evmutex);
/* If we don't have an event waiting block until we have one */
while (!EventQueue) {
QMSG qmsg;
if (WinPeekMsg(mainhab, &qmsg, NULLHANDLE, 0, 0, PM_REMOVE))
WinDispatchMsg(mainhab, &qmsg);
else
_sleep2(1);
}
}
DBUG_RETURN(False);
}
int XPeekIfEvent (display, event, predicate, arg)
register Display *display;
register XEvent *event;
Bool (*predicate)(
#if NeedNestedPrototypes
Display* /* display */,
XEvent* /* event */,
char* /* arg */
#endif
);
char *arg;
{
DBUG_ENTER("XPeekIfEvent")
WinAttribData *attrib;
Xlib_EventQueue *tmp;
fd_set readables;
int ready = 0;
while(1)
{
pthread_mutex_lock(&evmutex);
tmp = EventQueue;
while(tmp != NULL)
{
if((*predicate)(display, &tmp->event, arg))
{
memcpy(event, &tmp->event, sizeof(XEvent));
attrib = WinQueryWindowPtr(tmp->event.xany.window,QWP_WINATTRIB);
if (attrib && attrib->lastexpose == &(tmp->event)) attrib->lastexpose = NULL;
if (attrib && attrib->lastconfigure == &(tmp->event)) attrib->lastconfigure = NULL;
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(True);
}
tmp = tmp->next;
}
pthread_mutex_unlock(&evmutex);
/* If we don't have an event waiting block until we have one */
while (!EventQueue) {
QMSG qmsg;
if (WinPeekMsg(mainhab, &qmsg, NULLHANDLE, 0, 0, PM_REMOVE))
WinDispatchMsg(mainhab, &qmsg);
else
_sleep2(1);
}
}
DBUG_RETURN(False);
}
int XCheckIfEvent (display, event, predicate, arg)
register Display *display;
Bool (*predicate)(
#if NeedNestedPrototypes
Display* /* display */,
XEvent* /* event */,
char* /* arg */
#endif
); /* function to call */
register XEvent *event; /* XEvent to be filled in. */
char *arg;
{
DBUG_ENTER("XCheckIfEvent")
WinAttribData *attrib;
Xlib_EventQueue *tmp = EventQueue;
pthread_mutex_lock(&evmutex);
while(tmp != NULL)
{
if((*predicate)(display, &tmp->event, arg))
{
memcpy(event, &tmp->event, sizeof(XEvent));
attrib = WinQueryWindowPtr(tmp->event.xany.window,QWP_WINATTRIB);
if (attrib && attrib->lastexpose == &(tmp->event)) attrib->lastexpose = NULL;
if (attrib && attrib->lastconfigure == &(tmp->event)) attrib->lastconfigure = NULL;
Xlib_RemoveEvent(&tmp->event);
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(True);
}
tmp = tmp->next;
}
pthread_mutex_unlock(&evmutex);
DBUG_RETURN(False);
}