From d214a2ca9844df2353fb0abf370523e639968939 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 Sep 1999 13:46:59 +0000 Subject: [PATCH] Started to make modifications to support libWUtil --- WINGs/Makefile.am | 1 + WINGs/Makefile.in | 14 +- WINGs/WINGsP.h | 8 + WINGs/wapplication.c | 107 -------- WINGs/wappresource.c | 105 ++++++++ WINGs/wutil.c | 579 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 700 insertions(+), 114 deletions(-) create mode 100644 WINGs/wappresource.c create mode 100644 WINGs/wutil.c diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index ac849a1c..956c52c5 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -67,6 +67,7 @@ libWINGs_a_SOURCES = \ selection.c \ userdefaults.c \ wapplication.c \ + wappresource.c \ wballoon.c \ wbrowser.c \ wbutton.c \ diff --git a/WINGs/Makefile.in b/WINGs/Makefile.in index 37d5f2e7..4299b02c 100644 --- a/WINGs/Makefile.in +++ b/WINGs/Makefile.in @@ -143,7 +143,7 @@ wmquery_LDADD = libWINGs.a $(LIBLIST) EXTRA_DIST = logo.xpm BUGS # wbutton.c -libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c llist.h llist.c international.c notification.c selection.c userdefaults.c wapplication.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c hashtable.c memory.c usleep.c +libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c llist.h llist.c international.c notification.c selection.c userdefaults.c wapplication.c wappresource.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c hashtable.c memory.c usleep.c INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src -DRESOURCE_PATH=\"$(datadir)/WINGs\" @HEADER_SEARCH_PATH@ -DDEBUG @@ -163,12 +163,12 @@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ libWINGs_a_LIBADD = libWINGs_a_OBJECTS = configuration.o llist.o international.o \ -notification.o selection.o userdefaults.o wapplication.o wballoon.o \ -wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o wevent.o \ -wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o wlist.o \ -wmisc.o wpanel.o wpixmap.o wpopupbutton.o wscroller.o wscrollview.o \ -wslider.o wsplitview.o wtabview.o wtextfield.o wwindow.o wview.o \ -error.o findfile.o hashtable.o memory.o usleep.o +notification.o selection.o userdefaults.o wapplication.o wappresource.o \ +wballoon.o wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o \ +wevent.o wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o \ +wlist.o wmisc.o wpanel.o wpixmap.o wpopupbutton.o wscroller.o \ +wscrollview.o wslider.o wsplitview.o wtabview.o wtextfield.o wwindow.o \ +wview.o error.o findfile.o hashtable.o memory.o usleep.o AR = ar PROGRAMS = $(noinst_PROGRAMS) diff --git a/WINGs/WINGsP.h b/WINGs/WINGsP.h index c03cbb45..205aca9b 100644 --- a/WINGs/WINGsP.h +++ b/WINGs/WINGsP.h @@ -48,6 +48,14 @@ extern "C" { event.xclient.message_type=scrPtr->internalMessage; +typedef struct W_Application { + char *applicationName; + int argc; + char **argv; + char *resourcePath; +} W_Application; + + typedef struct W_Font { struct W_Screen *screen; diff --git a/WINGs/wapplication.c b/WINGs/wapplication.c index 5b979492..0ca7bd82 100644 --- a/WINGs/wapplication.c +++ b/WINGs/wapplication.c @@ -4,36 +4,10 @@ #include "WINGsP.h" -#include - -/* Xmd.h which is indirectly included by GNUstep.h defines BOOL, - * but libPropList also defines it. So we do this kluge to get rid of BOOL - * temporarily */ -#ifdef BOOL -# define WINGS_BOOL -# undef BOOL -#endif - -#include "GNUstep.h" - -#ifdef WINGS_BOOL -# define BOOL -# undef WINGS_BOOL -#endif - - extern void W_InitNotificationCenter(void); -typedef struct W_Application { - char *applicationName; - int argc; - char **argv; - char *resourcePath; -} W_Application; - - struct W_Application WMApplication; @@ -212,84 +186,3 @@ WMPathForResourceOfType(char *resource, char *ext) } -/********************* WMScreen related stuff ********************/ - - -void -WMSetApplicationIconImage(WMScreen *scr, WMPixmap *icon) -{ - if (scr->applicationIcon) - WMReleasePixmap(scr->applicationIcon); - - scr->applicationIcon = WMRetainPixmap(icon); - - if (scr->groupLeader) { - XWMHints *hints; - - hints = XGetWMHints(scr->display, scr->groupLeader); - hints->flags |= IconPixmapHint|IconMaskHint; - hints->icon_pixmap = icon->pixmap; - hints->icon_mask = icon->mask; - - XSetWMHints(scr->display, scr->groupLeader, hints); - XFree(hints); - } -} - - -WMPixmap* -WMGetApplicationIconImage(WMScreen *scr) -{ - return scr->applicationIcon; -} - - -void -WMSetApplicationHasAppIcon(WMScreen *scr, Bool flag) -{ - scr->aflags.hasAppIcon = flag; -} - - -void -W_InitApplication(WMScreen *scr) -{ - Window leader; - XClassHint *classHint; - XWMHints *hints; - - leader = XCreateSimpleWindow(scr->display, scr->rootWin, -1, -1, - 1, 1, 0, 0, 0); - - if (!scr->aflags.simpleApplication) { - classHint = XAllocClassHint(); - classHint->res_name = "groupLeader"; - classHint->res_class = WMApplication.applicationName; - XSetClassHint(scr->display, leader, classHint); - XFree(classHint); - - XSetCommand(scr->display, leader, WMApplication.argv, - WMApplication.argc); - - hints = XAllocWMHints(); - - hints->flags = WindowGroupHint; - hints->window_group = leader; - - if (scr->applicationIcon) { - hints->flags |= IconPixmapHint; - hints->icon_pixmap = scr->applicationIcon->pixmap; - if (scr->applicationIcon->mask) { - hints->flags |= IconMaskHint; - hints->icon_mask = scr->applicationIcon->mask; - } - } - - XSetWMHints(scr->display, leader, hints); - - XFree(hints); - } - scr->groupLeader = leader; -} - - diff --git a/WINGs/wappresource.c b/WINGs/wappresource.c new file mode 100644 index 00000000..244bb3fd --- /dev/null +++ b/WINGs/wappresource.c @@ -0,0 +1,105 @@ + + +#include + +#include "WINGsP.h" + +#include + +/* Xmd.h which is indirectly included by GNUstep.h defines BOOL, + * but libPropList also defines it. So we do this kluge to get rid of BOOL + * temporarily */ +#ifdef BOOL +# define WINGS_BOOL +# undef BOOL +#endif + +#include "GNUstep.h" + +#ifdef WINGS_BOOL +# define BOOL +# undef WINGS_BOOL +#endif + + +extern struct W_Application WMApplication; + + +void +WMSetApplicationIconImage(WMScreen *scr, WMPixmap *icon) +{ + if (scr->applicationIcon) + WMReleasePixmap(scr->applicationIcon); + + scr->applicationIcon = WMRetainPixmap(icon); + + if (scr->groupLeader) { + XWMHints *hints; + + hints = XGetWMHints(scr->display, scr->groupLeader); + hints->flags |= IconPixmapHint|IconMaskHint; + hints->icon_pixmap = icon->pixmap; + hints->icon_mask = icon->mask; + + XSetWMHints(scr->display, scr->groupLeader, hints); + XFree(hints); + } +} + + +WMPixmap* +WMGetApplicationIconImage(WMScreen *scr) +{ + return scr->applicationIcon; +} + + +void +WMSetApplicationHasAppIcon(WMScreen *scr, Bool flag) +{ + scr->aflags.hasAppIcon = flag; +} + + +void +W_InitApplication(WMScreen *scr) +{ + Window leader; + XClassHint *classHint; + XWMHints *hints; + + leader = XCreateSimpleWindow(scr->display, scr->rootWin, -1, -1, + 1, 1, 0, 0, 0); + + if (!scr->aflags.simpleApplication) { + classHint = XAllocClassHint(); + classHint->res_name = "groupLeader"; + classHint->res_class = WMApplication.applicationName; + XSetClassHint(scr->display, leader, classHint); + XFree(classHint); + + XSetCommand(scr->display, leader, WMApplication.argv, + WMApplication.argc); + + hints = XAllocWMHints(); + + hints->flags = WindowGroupHint; + hints->window_group = leader; + + if (scr->applicationIcon) { + hints->flags |= IconPixmapHint; + hints->icon_pixmap = scr->applicationIcon->pixmap; + if (scr->applicationIcon->mask) { + hints->flags |= IconMaskHint; + hints->icon_mask = scr->applicationIcon->mask; + } + } + + XSetWMHints(scr->display, leader, hints); + + XFree(hints); + } + scr->groupLeader = leader; +} + + diff --git a/WINGs/wutil.c b/WINGs/wutil.c new file mode 100644 index 00000000..e7d6f664 --- /dev/null +++ b/WINGs/wutil.c @@ -0,0 +1,579 @@ + + +/* + * This event handling stuff was based on Tk. + */ + +#include "WINGsP.h" + +#include "../src/config.h" + +#include +#include + +#ifdef HAVE_POLL_H +#include +#endif + + +//#include + +#ifdef HAVE_SYS_SELECT_H +# include +#endif + +#include + +#ifndef X_GETTIMEOFDAY +#define X_GETTIMEOFDAY(t) gettimeofday(t, (struct timezone*)0) +#endif + + + + +typedef struct TimerHandler { + WMCallback *callback; /* procedure to call */ + struct timeval when; /* when to call the callback */ + void *clientData; + struct TimerHandler *next; +} TimerHandler; + + +typedef struct IdleHandler { + WMCallback *callback; + void *clientData; + struct IdleHandler *next; +} IdleHandler; + + +typedef struct InputHandler { + WMInputProc *callback; + void *clientData; + int fd; + int mask; + struct InputHandler *next; +} InputHandler; + + +/* queue of timer event handlers */ +static TimerHandler *timerHandler=NULL; + +static IdleHandler *idleHandler=NULL; + +static InputHandler *inputHandler=NULL; + + + +#define timerPending() (timerHandler) + +#define idlePending() (idleHandler) + + +static void +rightNow(struct timeval *tv) { + X_GETTIMEOFDAY(tv); +} + +/* is t1 after t2 ? */ +#define IS_AFTER(t1, t2) (((t1).tv_sec > (t2).tv_sec) || \ + (((t1).tv_sec == (t2).tv_sec) \ + && ((t1).tv_usec > (t2).tv_usec))) + + +static void +addmillisecs(struct timeval *tv, int milliseconds) +{ + tv->tv_usec += milliseconds*1000; + + tv->tv_sec += tv->tv_usec/1000000; + tv->tv_usec = tv->tv_usec%1000000; +} + + +WMHandlerID +WMAddTimerHandler(int milliseconds, WMCallback *callback, void *cdata) +{ + TimerHandler *handler, *tmp; + + handler = malloc(sizeof(TimerHandler)); + if (!handler) + return NULL; + + rightNow(&handler->when); + addmillisecs(&handler->when, milliseconds); + handler->callback = callback; + handler->clientData = cdata; + /* insert callback in queue, sorted by time left */ + if (!timerHandler || !IS_AFTER(handler->when, timerHandler->when)) { + /* first in the queue */ + handler->next = timerHandler; + timerHandler = handler; + } else { + tmp = timerHandler; + while (tmp->next && IS_AFTER(handler->when, tmp->next->when)) { + tmp = tmp->next; + } + handler->next = tmp->next; + tmp->next = handler; + } + return handler; +} + + + +void +WMDeleteTimerWithClientData(void *cdata) +{ + TimerHandler *handler, *tmp; + + if (!cdata || !timerHandler) + return; + + tmp = timerHandler; + if (tmp->clientData==cdata) { + timerHandler = tmp->next; + free(tmp); + } else { + while (tmp->next) { + if (tmp->next->clientData==cdata) { + handler = tmp->next; + tmp->next = handler->next; + free(handler); + break; + } + tmp = tmp->next; + } + } +} + + + +void +WMDeleteTimerHandler(WMHandlerID handlerID) +{ + TimerHandler *tmp, *handler=(TimerHandler*)handlerID; + + if (!handler || !timerHandler) + return; + + tmp = timerHandler; + if (tmp==handler) { + timerHandler = handler->next; + free(handler); + } else { + while (tmp->next) { + if (tmp->next==handler) { + tmp->next=handler->next; + free(handler); + break; + } + tmp = tmp->next; + } + } +} + + + +WMHandlerID +WMAddIdleHandler(WMCallback *callback, void *cdata) +{ + IdleHandler *handler, *tmp; + + handler = malloc(sizeof(IdleHandler)); + if (!handler) + return NULL; + + handler->callback = callback; + handler->clientData = cdata; + handler->next = NULL; + /* add callback at end of queue */ + if (!idleHandler) { + idleHandler = handler; + } else { + tmp = idleHandler; + while (tmp->next) { + tmp = tmp->next; + } + tmp->next = handler; + } + + return handler; +} + + + +void +WMDeleteIdleHandler(WMHandlerID handlerID) +{ + IdleHandler *tmp, *handler = (IdleHandler*)handlerID; + + if (!handler || !idleHandler) + return; + + tmp = idleHandler; + if (tmp == handler) { + idleHandler = handler->next; + free(handler); + } else { + while (tmp->next) { + if (tmp->next == handler) { + tmp->next = handler->next; + free(handler); + break; + } + tmp = tmp->next; + } + } +} + + + +WMHandlerID +WMAddInputHandler(int fd, int condition, WMInputProc *proc, void *clientData) +{ + InputHandler *handler; + + handler = wmalloc(sizeof(InputHandler)); + + handler->fd = fd; + handler->mask = condition; + handler->callback = proc; + handler->clientData = clientData; + + handler->next = inputHandler; + + inputHandler = handler; + + return handler; +} + + +void +WMDeleteInputHandler(WMHandlerID handlerID) +{ + InputHandler *tmp, *handler = (InputHandler*)handlerID; + + if (!handler || !inputHandler) + return; + + tmp = inputHandler; + if (tmp == handler) { + inputHandler = handler->next; + free(handler); + } else { + while (tmp->next) { + if (tmp->next == handler) { + tmp->next = handler->next; + free(handler); + break; + } + tmp = tmp->next; + } + } +} + + +static void +checkIdleHandlers() +{ + IdleHandler *handler, *tmp; + + if (!idleHandler) { + W_FlushIdleNotificationQueue(); + return; + } + + handler = idleHandler; + + /* we will process all idleHandlers so, empty the handler list */ + idleHandler = NULL; + + while (handler) { + tmp = handler->next; + (*handler->callback)(handler->clientData); + /* remove the handler */ + free(handler); + + handler = tmp; + } + W_FlushIdleNotificationQueue(); +} + + + +static void +checkTimerHandlers() +{ + TimerHandler *handler; + struct timeval now; + + rightNow(&now); + + while (timerHandler && IS_AFTER(now, timerHandler->when)) { + handler = timerHandler; + timerHandler = timerHandler->next; + handler->next = NULL; + (*handler->callback)(handler->clientData); + free(handler); + } + + W_FlushASAPNotificationQueue(); +} + + + +static void +delayUntilNextTimerEvent(struct timeval *delay) +{ + struct timeval now; + + if (!timerHandler) { + /* The return value of this function is only valid if there _are_ + timers active. */ + delay->tv_sec = 0; + delay->tv_usec = 0; + return; + } + + rightNow(&now); + if (IS_AFTER(now, timerHandler->when)) { + delay->tv_sec = 0; + delay->tv_usec = 0; + } else { + delay->tv_sec = timerHandler->when.tv_sec - now.tv_sec; + delay->tv_usec = timerHandler->when.tv_usec - now.tv_usec; + if (delay->tv_usec < 0) { + delay->tv_usec += 1000000; + delay->tv_sec--; + } + } +} + + +Bool +W_WaitForEvent(Display *dpy, unsigned long xeventmask) +{ +#if defined(HAVE_POLL) && defined(HAVE_POLL_H) && !defined(HAVE_SELECT) + struct pollfd *fds; + InputHandler *handler; + int count, timeout, nfds, k, retval; + + for (nfds = 1, handler = inputHandler; + handler != 0; handler = handler->next) nfds++; + + fds = wmalloc(nfds * sizeof(struct pollfd)); + fds[0].fd = ConnectionNumber(dpy); + fds[0].events = POLLIN; + + for (k = 1, handler = inputHandler; + handler; + handler = handler->next, k++) { + fds[k].fd = handler->fd; + fds[k].events = 0; + if (handler->mask & WIReadMask) + fds[k].events |= POLLIN; + + if (handler->mask & WIWriteMask) + fds[k].events |= POLLOUT; + +#if 0 /* FIXME */ + if (handler->mask & WIExceptMask) + FD_SET(handler->fd, &eset); +#endif + } + + /* + * Setup the select() timeout to the estimated time until the + * next timer expires. + */ + if (timerPending()) { + struct timeval tv; + delayUntilNextTimerEvent(&tv); + timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000; + } else { + timeout = -1; + } + + if (xeventmask==0) { + if (XPending(dpy)) + return True; + } else { + XEvent ev; + if (XCheckMaskEvent(dpy, xeventmask, &ev)) { + XPutBackEvent(dpy, &ev); + return True; + } + } + + count = poll(fds, nfds, timeout); + + if (count > 0) { + handler = inputHandler; + k = 1; + while (handler) { + int mask; + InputHandler *next; + + mask = 0; + + if (fds[k].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI)) + mask |= WIReadMask; + + if (fds[k].revents & (POLLOUT | POLLWRBAND)) + mask |= WIWriteMask; + + if (fds[k].revents & (POLLHUP | POLLNVAL | POLLERR)) + mask |= WIExceptMask; + + next = handler->next; + + if (mask!=0 && handler->callback) { + (*handler->callback)(handler->fd, mask, + handler->clientData); + } + + handler = next; + k++; + } + } + + retval = fds[0].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI); + free(fds); + + W_FlushASAPNotificationQueue(); + + return retval; +#else /* not HAVE_POLL */ +#ifdef HAVE_SELECT + struct timeval timeout; + struct timeval *timeoutPtr; + fd_set rset, wset, eset; + int maxfd; + int count; + InputHandler *handler = inputHandler; + + FD_ZERO(&rset); + FD_ZERO(&wset); + FD_ZERO(&eset); + + FD_SET(ConnectionNumber(dpy), &rset); + maxfd = ConnectionNumber(dpy); + + while (handler) { + if (handler->mask & WIReadMask) + FD_SET(handler->fd, &rset); + + if (handler->mask & WIWriteMask) + FD_SET(handler->fd, &wset); + + if (handler->mask & WIExceptMask) + FD_SET(handler->fd, &eset); + + if (maxfd < handler->fd) + maxfd = handler->fd; + + handler = handler->next; + } + + + /* + * Setup the select() timeout to the estimated time until the + * next timer expires. + */ + if (timerPending()) { + delayUntilNextTimerEvent(&timeout); + timeoutPtr = &timeout; + } else { + timeoutPtr = (struct timeval*)0; + } + + XSync(dpy, False); + if (xeventmask==0) { + if (XPending(dpy)) + return True; + } else { + XEvent ev; + if (XCheckMaskEvent(dpy, xeventmask, &ev)) { + XPutBackEvent(dpy, &ev); + return True; + } + } + + count = select(1 + maxfd, &rset, &wset, &eset, timeoutPtr); + + if (count > 0) { + handler = inputHandler; + + while (handler) { + int mask; + InputHandler *next; + + mask = 0; + + if (FD_ISSET(handler->fd, &rset)) + mask |= WIReadMask; + + if (FD_ISSET(handler->fd, &wset)) + mask |= WIWriteMask; + + if (FD_ISSET(handler->fd, &eset)) + mask |= WIExceptMask; + + next = handler->next; + + if (mask!=0 && handler->callback) { + (*handler->callback)(handler->fd, mask, + handler->clientData); + } + + handler = next; + } + } + + W_FlushASAPNotificationQueue(); + + return FD_ISSET(ConnectionNumber(dpy), &rset); +#else /* not HAVE_SELECT, not HAVE_POLL */ +Neither select nor poll. You lose. +#endif /* HAVE_SELECT */ +#endif /* HAVE_POLL */ +} + + +void +WMNextEvent(Display *dpy, XEvent *event) +{ + /* Check any expired timers */ + if (timerPending()) { + checkTimerHandlers(); + } + + while (XPending(dpy) == 0) { + /* Do idle stuff */ + /* Do idle and timer stuff while there are no timer or X events */ + while (!XPending(dpy) && idlePending()) { + if (idlePending()) + checkIdleHandlers(); + /* dispatch timer events */ + if (timerPending()) + checkTimerHandlers(); + } + + /* + * Make sure that new events did not arrive while we were doing + * timer/idle stuff. Or we might block forever waiting for + * an event that already arrived. + */ + /* wait to something happen */ + W_WaitForEvent(dpy, 0); + + /* Check any expired timers */ + if (timerPending()) { + checkTimerHandlers(); + } + } + + XNextEvent(dpy, event); +} + +