mirror of
https://github.com/gryf/wmaker.git
synced 2026-01-29 11:35:47 +01:00
Started to make modifications to support libWUtil
This commit is contained in:
@@ -67,6 +67,7 @@ libWINGs_a_SOURCES = \
|
|||||||
selection.c \
|
selection.c \
|
||||||
userdefaults.c \
|
userdefaults.c \
|
||||||
wapplication.c \
|
wapplication.c \
|
||||||
|
wappresource.c \
|
||||||
wballoon.c \
|
wballoon.c \
|
||||||
wbrowser.c \
|
wbrowser.c \
|
||||||
wbutton.c \
|
wbutton.c \
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ wmquery_LDADD = libWINGs.a $(LIBLIST)
|
|||||||
EXTRA_DIST = logo.xpm BUGS
|
EXTRA_DIST = logo.xpm BUGS
|
||||||
|
|
||||||
# wbutton.c
|
# 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
|
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@
|
X_PRE_LIBS = @X_PRE_LIBS@
|
||||||
libWINGs_a_LIBADD =
|
libWINGs_a_LIBADD =
|
||||||
libWINGs_a_OBJECTS = configuration.o llist.o international.o \
|
libWINGs_a_OBJECTS = configuration.o llist.o international.o \
|
||||||
notification.o selection.o userdefaults.o wapplication.o wballoon.o \
|
notification.o selection.o userdefaults.o wapplication.o wappresource.o \
|
||||||
wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o wevent.o \
|
wballoon.o wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o \
|
||||||
wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o wlist.o \
|
wevent.o wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o \
|
||||||
wmisc.o wpanel.o wpixmap.o wpopupbutton.o wscroller.o wscrollview.o \
|
wlist.o wmisc.o wpanel.o wpixmap.o wpopupbutton.o wscroller.o \
|
||||||
wslider.o wsplitview.o wtabview.o wtextfield.o wwindow.o wview.o \
|
wscrollview.o wslider.o wsplitview.o wtabview.o wtextfield.o wwindow.o \
|
||||||
error.o findfile.o hashtable.o memory.o usleep.o
|
wview.o error.o findfile.o hashtable.o memory.o usleep.o
|
||||||
AR = ar
|
AR = ar
|
||||||
PROGRAMS = $(noinst_PROGRAMS)
|
PROGRAMS = $(noinst_PROGRAMS)
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ extern "C" {
|
|||||||
event.xclient.message_type=scrPtr->internalMessage;
|
event.xclient.message_type=scrPtr->internalMessage;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct W_Application {
|
||||||
|
char *applicationName;
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
char *resourcePath;
|
||||||
|
} W_Application;
|
||||||
|
|
||||||
|
|
||||||
typedef struct W_Font {
|
typedef struct W_Font {
|
||||||
struct W_Screen *screen;
|
struct W_Screen *screen;
|
||||||
|
|
||||||
|
|||||||
@@ -4,36 +4,10 @@
|
|||||||
|
|
||||||
#include "WINGsP.h"
|
#include "WINGsP.h"
|
||||||
|
|
||||||
#include <X11/Xutil.h>
|
|
||||||
|
|
||||||
/* 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);
|
extern void W_InitNotificationCenter(void);
|
||||||
|
|
||||||
|
|
||||||
typedef struct W_Application {
|
|
||||||
char *applicationName;
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
char *resourcePath;
|
|
||||||
} W_Application;
|
|
||||||
|
|
||||||
|
|
||||||
struct W_Application WMApplication;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
105
WINGs/wappresource.c
Normal file
105
WINGs/wappresource.c
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "WINGsP.h"
|
||||||
|
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
579
WINGs/wutil.c
Normal file
579
WINGs/wutil.c
Normal file
@@ -0,0 +1,579 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This event handling stuff was based on Tk.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WINGsP.h"
|
||||||
|
|
||||||
|
#include "../src/config.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//#include <X11/Xos.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
# include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user