diff --git a/.hgignore b/.hgignore index b1aaa093..1c1825b0 100644 --- a/.hgignore +++ b/.hgignore @@ -1,7 +1,7 @@ syntax: regexp (^|/)\.((.*\.)?sw.|depend|hgignore)$ -(^|/)(tags|mkfile)$ -\.([oa]|out|o_pic|so|pyc|pyo)$ +(^|/)(tags|mkfile|diff)$ +\.([oa]|out|o_pic|so|pyc|pyo|diff)$ \.(diff|orig|rej|bak)$ \.(aux|idx|ilg|ind|log|toc)$ ^cmd/(stfo|osd|wiwarp|setfocus)(/|$) diff --git a/Makefile b/Makefile index c3cb429b..163ea83a 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ PDIRS = \ alternative_wmiircs DIRS = \ + libstuff \ libbio \ libfmt \ libregexp \ diff --git a/cmd/Makefile b/cmd/Makefile index 13b9cf9f..5e264cc9 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -12,8 +12,6 @@ TARG = wihack \ wmii9menu \ wmiir -OFILES = util.o - LIBS += $(LIBS9) CFLAGS += $(INCX11) @@ -24,10 +22,7 @@ OWMIIR=wmiir.o $(OFILES) $(LIBIXP) wmiir.out: $(OWMIIR) $(LINK) $@ $(STATIC) $(OWMIIR) -wmii/x11.o wmii/xext.o wmii/geom.o wmii/map.o: dall - true - -O9MENU=wmii9menu.o clientutil.o wmii/x11.o wmii/xext.o wmii/geom.o wmii/map.o $(OFILES) $(LIBIXP) +O9MENU=wmii9menu.o $(ROOT)/lib/libstuff.a $(LIBIXP) wmii9menu.out: $(O9MENU) $(LINK) $@ $(O9MENU) $$(pkg-config --libs $(X11PACKAGES) xrandr xinerama) -lXext diff --git a/cmd/click/Makefile b/cmd/click/Makefile index 1abf6cb1..aa9e8181 100644 --- a/cmd/click/Makefile +++ b/cmd/click/Makefile @@ -11,12 +11,8 @@ PACKAGES += $(X11PACKAGES) xext xrandr xrender xinerama LIB = $(LIBIXP) LIBS += -lm -lXtst $(LIBS9) -CFLAGS += -DVERSION=\"$(VERSION)\" -DIXP_NEEDAPI=86 -OBJ = main \ - _util \ - ../wmii/map \ - ../wmii/x11 \ - ../util +CFLAGS += -DIXP_NEEDAPI=86 +OBJ = main include ${ROOT}/mk/one.mk diff --git a/cmd/click/dat.h b/cmd/click/dat.h index 5096865e..37093d41 100644 --- a/cmd/click/dat.h +++ b/cmd/click/dat.h @@ -3,9 +3,9 @@ #include #include #include -#include +#include +#include #include -#include #define BLOCK(x) do { x; }while(0) @@ -15,13 +15,3 @@ EXTERN Window win; -EXTERN char buffer[8092]; -EXTERN char* _buffer; - -static char* const _buf_end = buffer + sizeof buffer; - -#define bufclear() \ - BLOCK( _buffer = buffer; _buffer[0] = '\0' ) -#define bufprint(...) \ - _buffer = seprint(_buffer, _buf_end, __VA_ARGS__) - diff --git a/cmd/click/fns.h b/cmd/click/fns.h index d41b8400..8b137891 100644 --- a/cmd/click/fns.h +++ b/cmd/click/fns.h @@ -1,4 +1 @@ -bool getlong(const char*, long*); -bool getulong(const char*, ulong*); - diff --git a/cmd/click/main.c b/cmd/click/main.c index 3ddc8efb..06baa82e 100644 --- a/cmd/click/main.c +++ b/cmd/click/main.c @@ -46,10 +46,10 @@ main(int argc, char *argv[]) { initdisplay(); s = ARGF(); - if(s && !getulong(s, &win.w)) + if(s && !getulong(s, &win.xid)) usage(); if (!s) - win.w = getfocus(); + win.xid = getfocus(); if(argc) usage(); diff --git a/cmd/menu/Makefile b/cmd/menu/Makefile index a2fc9ad3..e284d301 100644 --- a/cmd/menu/Makefile +++ b/cmd/menu/Makefile @@ -14,23 +14,14 @@ HFILES= dat.h fns.h PACKAGES += $(X11PACKAGES) xext xrandr xrender xinerama -LIB = $(LIBIXP) -LIBS += -lm $(LIBS9) +LIBS += -lm $(LIBS9) $(LIBIXP) CFLAGS += -DIXP_NEEDAPI=86 OBJ = main \ caret \ history \ - event \ menu \ keys \ - bindings \ - ../wmii/geom \ - ../wmii/map \ - ../wmii/printevent \ - ../wmii/x11 \ - ../wmii/xext \ - ../clientutil \ - ../util + bindings include $(ROOT)/mk/one.mk diff --git a/cmd/menu/dat.h b/cmd/menu/dat.h index 1d805fa0..533568c9 100644 --- a/cmd/menu/dat.h +++ b/cmd/menu/dat.h @@ -7,9 +7,9 @@ #include #include #include -#include +#include +#include #include -#include #define BLOCK(x) do { x; }while(0) @@ -104,13 +104,3 @@ EXTERN int (*compare)(const char*, const char*, size_t); EXTERN char* prompt; EXTERN int promptw; -EXTERN char buffer[8092]; -EXTERN char* _buffer; - -static char* const _buf_end = buffer + sizeof buffer; - -#define bufclear() \ - BLOCK( _buffer = buffer; _buffer[0] = '\0' ) -#define bufprint(...) \ - _buffer = seprint(_buffer, _buf_end, __VA_ARGS__) - diff --git a/cmd/menu/event.c b/cmd/menu/event.c deleted file mode 100644 index fd524f90..00000000 --- a/cmd/menu/event.c +++ /dev/null @@ -1,334 +0,0 @@ -/* Copyright ©2006-2010 Kris Maglione - * See LICENSE file for license details. - */ -#include "dat.h" -#include "fns.h" - -typedef void (*EvHandler)(XEvent*); -static EvHandler handler[LASTEvent]; - -void -dispatch_event(XEvent *e) { - if(e->type < nelem(handler)) { - if(handler[e->type]) - handler[e->type](e); - }else - xext_event(e); -} - -#define handle(w, fn, ev) \ - BLOCK(if((w)->handler->fn) (w)->handler->fn((w), ev)) - -static int -findtime(Display *d, XEvent *e, XPointer v) { - Window *w; - - w = (Window*)v; - if(e->type == PropertyNotify && e->xproperty.window == w->xid) { - xtime = e->xproperty.time; - return true; - } - return false; -} - -void -xtime_kludge(void) { - /* Round trip. */ - static Window *w; - WinAttr wa; - XEvent e; - long l; - - if(w == nil) { - w = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, InputOnly, &wa, 0); - selectinput(w, PropertyChangeMask); - } - changeprop_long(w, "ATOM", "ATOM", &l, 0); - sync(); - XIfEvent(display, &e, findtime, (void*)w); -} - -uint -flushevents(long event_mask, bool dispatch) { - XEvent ev; - uint n = 0; - - while(XCheckMaskEvent(display, event_mask, &ev)) { - if(dispatch) - dispatch_event(&ev); - n++; - } - return n; -} - -static int -findenter(Display *d, XEvent *e, XPointer v) { - long *l; - - USED(d); - l = (long*)v; - if(*l) - return false; - if(e->type == EnterNotify) - return true; - if(e->type == MotionNotify) - (*l)++; - return false; -} - -/* This isn't perfect. If there were motion events in the queue - * before this was called, then it flushes nothing. If we don't - * check for them, we might lose a legitamate enter event. - */ -uint -flushenterevents(void) { - XEvent e; - long l; - int n; - - l = 0; - n = 0; - while(XCheckIfEvent(display, &e, findenter, (void*)&l)) - n++; - return n; -} - -static void -buttonrelease(XButtonPressedEvent *ev) { - Window *w; - - if((w = findwin(ev->window))) - handle(w, bup, ev); -} - -static void -buttonpress(XButtonPressedEvent *ev) { - Window *w; - - if((w = findwin(ev->window))) - handle(w, bdown, ev); - else - XAllowEvents(display, ReplayPointer, ev->time); -} - -static void -configurerequest(XConfigureRequestEvent *ev) { - XWindowChanges wc; - Window *w; - - if((w = findwin(ev->window))) - handle(w, configreq, ev); - else{ - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - XConfigureWindow(display, ev->window, ev->value_mask, &wc); - } -} - -static void -configurenotify(XConfigureEvent *ev) { - Window *w; - - USED(ev); - if((w = findwin(ev->window))) - handle(w, config, ev); -} - -static void -clientmessage(XClientMessageEvent *ev) { - - USED(ev); -} - -static void -destroynotify(XDestroyWindowEvent *ev) { - Window *w; - - if((w = findwin(ev->window))) - handle(w, destroy, ev); -} - -static void -enternotify(XCrossingEvent *ev) { - Window *w; - static int sel_screen; - - xtime = ev->time; - if(ev->mode != NotifyNormal) - return; - - if((w = findwin(ev->window))) - handle(w, enter, ev); - else if(ev->window == scr.root.xid) - sel_screen = true; -} - -static void -leavenotify(XCrossingEvent *ev) { - - xtime = ev->time; -#if 0 - if((ev->window == scr.root.xid) && !ev->same_screen) - sel_screen = true; -#endif -} - -static void -focusin(XFocusChangeEvent *ev) { - Window *w; - - /* Yes, we're focusing in on nothing, here. */ - if(ev->detail == NotifyDetailNone) { - /* FIXME: Do something. */ - return; - } - - if(!((ev->detail == NotifyNonlinear) - ||(ev->detail == NotifyNonlinearVirtual) - ||(ev->detail == NotifyVirtual) - ||(ev->detail == NotifyInferior) - ||(ev->detail == NotifyAncestor))) - return; - if((ev->mode == NotifyWhileGrabbed)) /* && (screen->hasgrab != &c_root)) */ - return; - - if((w = findwin(ev->window))) - handle(w, focusin, ev); -#if 0 - else if(ev->mode == NotifyGrab) { - if(ev->window == scr.root.xid) - screen->hasgrab = &c_root; - /* Some unmanaged window has grabbed focus */ - else if((c = screen->focus)) { - print_focus("focusin", &c_magic, ""); - screen->focus = &c_magic; - if(c->sel) - frame_draw(c->sel); - } - } -#endif -} - -static void -focusout(XFocusChangeEvent *ev) { - Window *w; - - if(!((ev->detail == NotifyNonlinear) - ||(ev->detail == NotifyNonlinearVirtual) - ||(ev->detail == NotifyVirtual) - ||(ev->detail == NotifyInferior) - ||(ev->detail == NotifyAncestor))) - return; -#if 0 - if(ev->mode == NotifyUngrab) - screen->hasgrab = nil; -#endif - - if((w = findwin(ev->window))) - handle(w, focusout, ev); -} - -static void -expose(XExposeEvent *ev) { - Window *w; - - if(ev->count == 0) { - if((w = findwin(ev->window))) - handle(w, expose, ev); - } -} - -static void -keypress(XKeyEvent *ev) { - Window *w; - - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, kdown, ev); -} - -static void -mappingnotify(XMappingEvent *ev) { - - /* Why do you need me to tell you this? */ - XRefreshKeyboardMapping(ev); -} - -static void -maprequest(XMapRequestEvent *ev) { - - USED(ev); -} - -static void -motionnotify(XMotionEvent *ev) { - Window *w; - - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, motion, ev); -} - -static void -propertynotify(XPropertyEvent *ev) { - Window *w; - - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, property, ev); -} - -static void -mapnotify(XMapEvent *ev) { - Window *w; - - if((w = findwin(ev->window))) - handle(w, map, ev); -} - -static void -unmapnotify(XUnmapEvent *ev) { - Window *w; - - if((w = findwin(ev->window)) && (ev->event == w->parent->xid)) { - w->mapped = false; - if(ev->send_event || w->unmapped-- == 0) - handle(w, unmap, ev); - } -} - -static EvHandler handler[LASTEvent] = { - [ButtonPress] = (EvHandler)buttonpress, - [ButtonRelease] = (EvHandler)buttonrelease, - [ConfigureRequest] = (EvHandler)configurerequest, - [ConfigureNotify] = (EvHandler)configurenotify, - [ClientMessage] = (EvHandler)clientmessage, - [DestroyNotify] = (EvHandler)destroynotify, - [EnterNotify] = (EvHandler)enternotify, - [Expose] = (EvHandler)expose, - [FocusIn] = (EvHandler)focusin, - [FocusOut] = (EvHandler)focusout, - [KeyPress] = (EvHandler)keypress, - [LeaveNotify] = (EvHandler)leavenotify, - [MapNotify] = (EvHandler)mapnotify, - [MapRequest] = (EvHandler)maprequest, - [MappingNotify] = (EvHandler)mappingnotify, - [MotionNotify] = (EvHandler)motionnotify, - [PropertyNotify] = (EvHandler)propertynotify, - [UnmapNotify] = (EvHandler)unmapnotify, -}; - -void -check_x_event(IxpConn *c) { - XEvent ev; - - USED(c); - while(XCheckMaskEvent(display, ~0, &ev)) - dispatch_event(&ev); -} - diff --git a/cmd/menu/fns.h b/cmd/menu/fns.h index d95ab7f1..673e7eac 100644 --- a/cmd/menu/fns.h +++ b/cmd/menu/fns.h @@ -19,7 +19,6 @@ char* history_search(int, char*, int); /* main.c */ void debug(int, const char*, ...); Item* filter_list(Item*, char*); -void init_screens(int); void update_filter(bool); void update_input(void); diff --git a/cmd/menu/main.c b/cmd/menu/main.c index aaab27d5..e3047755 100644 --- a/cmd/menu/main.c +++ b/cmd/menu/main.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include "fns.h" #define link _link @@ -19,6 +19,7 @@ static Biobuf* cmplbuf; static Biobuf* inbuf; static bool alwaysprint; static char* cmdsep; +static int screen_hint; static void usage(void) { @@ -169,10 +170,6 @@ update_filter(bool print) { update_input(); } -ErrorCode ignored_xerrors[] = { - { 0, } -}; - static void end(IxpConn *c) { @@ -184,13 +181,13 @@ static void preselect(IxpServer *s) { USED(s); - check_x_event(nil); + event_check(); } enum { PointerScreen = -1 }; void -init_screens(int screen_hint) { +init_screens(void) { Rectangle *rects; Point p; int i, n; @@ -223,12 +220,11 @@ main(int argc, char *argv[]) { static bool nokeys; int i; long ndump; - int screen; quotefmtinstall(); fmtinstall('r', errfmt); address = getenv("WMII_ADDRESS"); - screen = PointerScreen; + screen_hint = PointerScreen; find = strstr; compare = strncmp; @@ -261,7 +257,7 @@ main(int argc, char *argv[]) { prompt = EARGF(usage()); break; case 's': - screen = strtol(EARGF(usage()), nil, 10); + screen_hint = strtol(EARGF(usage()), nil, 10); break; case 'S': cmdsep = EARGF(usage()); @@ -287,7 +283,7 @@ main(int argc, char *argv[]) { client_init(address); srv.preselect = preselect; - ixp_listen(&srv, ConnectionNumber(display), nil, check_x_event, end); + ixp_listen(&srv, ConnectionNumber(display), nil, (void (*)(IxpConn*))preselect, end); ontop = !strcmp(readctl("bar on "), "top"); loadcolor(&cnorm, readctl("normcolors ")); @@ -331,7 +327,7 @@ main(int argc, char *argv[]) { if(barwin == nil) menu_init(); - init_screens(screen); + init_screens(); i = ixp_serverloop(&srv); if(i) diff --git a/cmd/strut/Makefile b/cmd/strut/Makefile index fca4bd2f..762be076 100644 --- a/cmd/strut/Makefile +++ b/cmd/strut/Makefile @@ -13,15 +13,8 @@ LIB = $(LIBIXP) LIBS += -lm $(LIBS9) CFLAGS += -DIXP_NEEDAPI=86 OBJ = main \ - event \ ewmh \ - win \ - _util \ - ../wmii/map \ - ../wmii/printevent \ - printevent_kludge \ - ../wmii/x11 \ - ../util + win include ${ROOT}/mk/one.mk diff --git a/cmd/strut/dat.h b/cmd/strut/dat.h index 810d3843..605fa4e2 100644 --- a/cmd/strut/dat.h +++ b/cmd/strut/dat.h @@ -3,31 +3,16 @@ #include #include #include -#include +#include +#include #include -#include - -#define BLOCK(x) do { x; }while(0) #ifndef EXTERN # define EXTERN extern #endif -extern Handlers handlers; - -EXTERN bool running; +EXTERN Handlers handlers; EXTERN Window win; EXTERN Window frame; -EXTERN long xtime; - -EXTERN char buffer[8092]; -EXTERN char* _buffer; - -static char* const _buf_end = buffer + sizeof buffer; - -#define bufclear() \ - BLOCK( _buffer = buffer; _buffer[0] = '\0' ) -#define bufprint(...) \ - _buffer = seprint(_buffer, _buf_end, __VA_ARGS__) diff --git a/cmd/strut/event.c b/cmd/strut/event.c deleted file mode 100644 index aebd8ba4..00000000 --- a/cmd/strut/event.c +++ /dev/null @@ -1,309 +0,0 @@ -/* Copyright ©2006-2010 Kris Maglione - * See LICENSE file for license details. - */ -#include "dat.h" -#include "fns.h" - -static void (*handler[LASTEvent])(XEvent*); - -void -dispatch_event(XEvent *e) { - /* print("%E\n", e); */ - if(e->type < nelem(handler) && handler[e->type]) - handler[e->type](e); -} - -#define handle(w, fn, ev) \ - BLOCK(if((w)->handler->fn) (w)->handler->fn((w), ev)) - -#ifdef notdef -uint -flushevents(long event_mask, bool dispatch) { - XEvent ev; - uint n = 0; - - while(XCheckMaskEvent(display, event_mask, &ev)) { - if(dispatch) - dispatch_event(&ev); - n++; - } - return n; -} - -static int -findenter(Display *d, XEvent *e, XPointer v) { - long *l; - - USED(d); - l = (long*)v; - if(*l) - return false; - if(e->type == EnterNotify) - return true; - if(e->type == MotionNotify) - (*l)++; - return false; -} - -/* This isn't perfect. If there were motion events in the queue - * before this was called, then it flushes nothing. If we don't - * check for them, we might lose a legitamate enter event. - */ -uint -flushenterevents(void) { - XEvent e; - long l; - int n; - - l = 0; - n = 0; - while(XCheckIfEvent(display, &e, findenter, (void*)&l)) - n++; - return n; -} -#endif - -static int -findtime(Display *d, XEvent *e, XPointer v) { - Window *w; - - w = (Window*)v; - if(e->type == PropertyNotify && e->xproperty.window == w->xid) { - xtime = e->xproperty.time; - return true; - } - return false; -} - -void -xtime_kludge(void) { - Window *w; - WinAttr wa; - XEvent e; - long l; - - w = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, InputOnly, &wa, 0); - - XSelectInput(display, w->xid, PropertyChangeMask); - changeprop_long(w, "ATOM", "ATOM", &l, 0); - XIfEvent(display, &e, findtime, (void*)w); - - destroywindow(w); -} - -static void -buttonrelease(XEvent *e) { - XButtonPressedEvent *ev; - Window *w; - - ev = &e->xbutton; - if((w = findwin(ev->window))) - handle(w, bup, ev); -} - -static void -buttonpress(XEvent *e) { - XButtonPressedEvent *ev; - Window *w; - - ev = &e->xbutton; - if((w = findwin(ev->window))) - handle(w, bdown, ev); - else - XAllowEvents(display, ReplayPointer, ev->time); -} - -static void -clientmessage(XEvent *e) { - XClientMessageEvent *ev; - - ev = &e->xclient; - USED(ev); -} - -static void -configurenotify(XEvent *e) { - XConfigureEvent *ev; - Window *w; - - ev = &e->xconfigure; - if((w = findwin(ev->window))) - handle(w, config, ev); -} - -static void -destroynotify(XEvent *e) { - XDestroyWindowEvent *ev; - Window *w; - - ev = &e->xdestroywindow; - if((w = findwin(ev->window))) - handle(w, destroy, ev); -} - -static void -enternotify(XEvent *e) { - XCrossingEvent *ev; - Window *w; - - ev = &e->xcrossing; - xtime = ev->time; - if(ev->mode != NotifyNormal) - return; - - if((w = findwin(ev->window))) - handle(w, enter, ev); -} - -static void -leavenotify(XEvent *e) { - XCrossingEvent *ev; - - ev = &e->xcrossing; - xtime = ev->time; -} - -static void -focusin(XEvent *e) { - XFocusChangeEvent *ev; - Window *w; - - ev = &e->xfocus; - /* Yes, we're focusing in on nothing, here. */ - if(ev->detail == NotifyDetailNone) { - /* FIXME: Do something. */ - return; - } - - if(!((ev->detail == NotifyNonlinear) - ||(ev->detail == NotifyNonlinearVirtual) - ||(ev->detail == NotifyVirtual) - ||(ev->detail == NotifyInferior) - ||(ev->detail == NotifyAncestor))) - return; - if((ev->mode == NotifyWhileGrabbed)) - return; - - if((w = findwin(ev->window))) - handle(w, focusin, ev); -} - -static void -focusout(XEvent *e) { - XFocusChangeEvent *ev; - Window *w; - - ev = &e->xfocus; - if(!((ev->detail == NotifyNonlinear) - ||(ev->detail == NotifyNonlinearVirtual) - ||(ev->detail == NotifyVirtual) - ||(ev->detail == NotifyInferior) - ||(ev->detail == NotifyAncestor))) - return; - - if((w = findwin(ev->window))) - handle(w, focusout, ev); -} - -static void -expose(XEvent *e) { - XExposeEvent *ev; - Window *w; - - ev = &e->xexpose; - if(ev->count == 0) { - if((w = findwin(ev->window))) - handle(w, expose, ev); - } -} - -static void -keypress(XEvent *e) { - XKeyEvent *ev; - - ev = &e->xkey; - xtime = ev->time; -} - -static void -mappingnotify(XEvent *e) { - XMappingEvent *ev; - - ev = &e->xmapping; - /* Why do you need me to tell you this? */ - XRefreshKeyboardMapping(ev); -} - -static void -motionnotify(XEvent *e) { - XMotionEvent *ev; - Window *w; - - ev = &e->xmotion; - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, motion, ev); -} - -static void -propertynotify(XEvent *e) { - XPropertyEvent *ev; - Window *w; - - ev = &e->xproperty; - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, property, ev); -} - -static void -mapnotify(XEvent *e) { - XMapEvent *ev; - Window *w; - - ev = &e->xmap; - if((w = findwin(ev->window))) - handle(w, map, ev); -} - -static void -unmapnotify(XEvent *e) { - XUnmapEvent *ev; - Window *w; - - ev = &e->xunmap; - if((w = findwin(ev->window)) && w->parent && (ev->event == w->parent->xid)) { - if(ev->send_event || w->unmapped-- == 0) - handle(w, unmap, ev); - } -} - -static void (*handler[LASTEvent])(XEvent*) = { - [ButtonPress] = buttonpress, - [ButtonRelease] = buttonrelease, - [ClientMessage] = clientmessage, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [Expose] = expose, - [FocusIn] = focusin, - [FocusOut] = focusout, - [KeyPress] = keypress, - [LeaveNotify] = leavenotify, - [MapNotify] = mapnotify, - [MappingNotify] = mappingnotify, - [MotionNotify] = motionnotify, - [PropertyNotify] = propertynotify, - [UnmapNotify] = unmapnotify, -}; - -void -xevent_loop(void) { - XEvent ev; - - while(running) { - XNextEvent(display, &ev); - dispatch_event(&ev); - } -} - diff --git a/cmd/strut/fns.h b/cmd/strut/fns.h index af6383ed..f7b3d0a7 100644 --- a/cmd/strut/fns.h +++ b/cmd/strut/fns.h @@ -8,9 +8,6 @@ void xtime_kludge(void); void restrut(void); -bool getlong(const char*, long*); -bool getulong(const char*, ulong*); - void ewmh_getstrut(Window*, Rectangle[4]); void ewmh_setstrut(Window*, Rectangle[4]); diff --git a/cmd/strut/main.c b/cmd/strut/main.c index ef9d27fd..b3a6e2ba 100644 --- a/cmd/strut/main.c +++ b/cmd/strut/main.c @@ -30,8 +30,6 @@ debug(int flag, const char *fmt, ...) { va_end(ap); } -ErrorCode ignored_xerrors[] = { {0,} }; - static Window findframe(Window *w) { XWindow *children; @@ -39,6 +37,7 @@ findframe(Window *w) { Window ret = {0, }; uint n; + xw = w->xid; for(par=w->xid; par != scr.root.xid; ) { xw = par; XQueryTree(display, xw, &root, &par, &children, &n); @@ -93,8 +92,8 @@ extern int fmtevent(Fmt*); sethandler(&frame, &handlers); selectinput(&frame, StructureNotifyMask); - running = true; - xevent_loop(); + event_looprunning = true; + event_loop(); XCloseDisplay(display); return 0; diff --git a/cmd/strut/printevent_kludge.c b/cmd/strut/printevent_kludge.c deleted file mode 100644 index c5e53cb1..00000000 --- a/cmd/strut/printevent_kludge.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "dat.h" - -void dprint(const char *fmt, ...); -void -dprint(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vfprint(2, fmt, ap); - va_end(ap); -} - diff --git a/cmd/strut/win.c b/cmd/strut/win.c index ba607cfa..cbcbc3c3 100644 --- a/cmd/strut/win.c +++ b/cmd/strut/win.c @@ -92,7 +92,7 @@ config(Window *w, XConfigureEvent *ev) { static void destroy(Window *w, XDestroyWindowEvent *ev) { USED(w, ev); - running = false; + event_looprunning = false; } Handlers handlers = { diff --git a/cmd/util.c b/cmd/util.c deleted file mode 100644 index 2556d28f..00000000 --- a/cmd/util.c +++ /dev/null @@ -1,272 +0,0 @@ -/* Written by Kris Maglione */ -/* Public domain */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct VFmt VFmt; -struct VFmt { - const char *fmt; - va_list args; -}; - -#ifdef VARARGCK -# pragma varargck type "V" VFmt* -#endif - -static int -Vfmt(Fmt *f) { - VFmt *vf; - int i; - - vf = va_arg(f->args, VFmt*); - i = fmtvprint(f, vf->fmt, vf->args); - return i; -} - -void -fatal(const char *fmt, ...) { - VFmt fp; - - fmtinstall('V', Vfmt); - fmtinstall('\001', Vfmt); - - fp.fmt = fmt; - va_start(fp.args, fmt); - fprint(2, "%s: fatal: %V\n", argv0, &fp); - va_end(fp.args); - - exit(1); -} - -void* -freelater(void *p) { - static char* obj[16]; - static long nobj; - int id; - - id = nobj++ % nelem(obj); - free(obj[id]); - obj[id] = p; - return p; -} - -char* -vsxprint(const char *fmt, va_list ap) { - char *s; - - s = vsmprint(fmt, ap); - freelater(s); - return s; -} - -char* -sxprint(const char *fmt, ...) { - va_list ap; - char *ret; - - va_start(ap, fmt); - ret = vsxprint(fmt, ap); - va_end(ap); - return ret; -} - -void -_die(char *file, int line, char *msg, ...) { - va_list ap; - - va_start(ap, msg); - fprint(2, "%s: dieing at %s:%d: %s\n", - argv0, file, line, - vsxprint(msg, ap)); - va_end(ap); - - kill(getpid(), SIGABRT); - abort(); /* Adds too many frames: - * _die() - * abort() - * raise(SIGABRT) - * kill(getpid(), SIGABRT) - */ -} - -/* Can't malloc */ -static void -mfatal(char *name, uint size) { - const char - couldnot[] = ": fatal: Could not ", - paren[] = "() ", - bytes[] = " bytes\n"; - char buf[1024]; - char sizestr[8]; - int i; - - i = sizeof sizestr; - do { - sizestr[--i] = '0' + (size%10); - size /= 10; - } while(size > 0); - - strlcat(buf, argv0, sizeof buf); - strlcat(buf, couldnot, sizeof buf); - strlcat(buf, name, sizeof buf); - strlcat(buf, paren, sizeof buf); - strlcat(buf, sizestr+i, sizeof buf); - strlcat(buf, bytes, sizeof buf); - write(2, buf, strlen(buf)); - - exit(1); -} - -void * -emalloc(uint size) { - void *ret = malloc(size); - if(!ret) - mfatal("malloc", size); - return ret; -} - -void * -emallocz(uint size) { - void *ret = emalloc(size); - memset(ret, 0, size); - return ret; -} - -void * -erealloc(void *ptr, uint size) { - void *ret = realloc(ptr, size); - if(!ret) - mfatal("realloc", size); - return ret; -} - -char* -estrdup(const char *str) { - void *ret = strdup(str); - if(!ret) - mfatal("strdup", strlen(str)); - return ret; -} - -char* -estrndup(const char *str, uint len) { - char *ret; - - len = min(len, strlen(str)); - ret = emalloc(len + 1); - memcpy(ret, str, len); - ret[len] = '\0'; - return ret; -} - - -uint -tokenize(char *res[], uint reslen, char *str, char delim) { - char *s; - uint i; - - i = 0; - s = str; - while(i < reslen && *s) { - while(*s == delim) - *(s++) = '\0'; - if(*s) - res[i++] = s; - while(*s && *s != delim) - s++; - } - return i; -} - -uint -stokenize(char *res[], uint reslen, char *str, char *delim) { - char *s; - uint i; - - i = 0; - s = str; - while(i < reslen && *s) { - while(strchr(delim, *s)) - *(s++) = '\0'; - if(*s) - res[i++] = s; - while(*s && !strchr(delim, *s)) - s++; - } - return i; -} - -int -max(int a, int b) { - if(a > b) - return a; - return b; -} - -int -min(int a, int b) { - if(a < b) - return a; - return b; -} - -int -utflcpy(char *to, const char *from, int l) { - char *p; - - p = utfecpy(to, to+l, from); - return p-to; -} - -uint -strlcat(char *dst, const char *src, uint size) { - const char *s; - char *d; - int n, len; - - d = dst; - s = src; - n = size; - while(n-- > 0 && *d != '\0') - d++; - len = n; - - while(*s != '\0') { - if(n-- > 0) - *d++ = *s; - s++; - } - if(len > 0) - *d = '\0'; - return size - n - 1; -} - -/* TODO: Make this UTF-8 compliant. */ -char* -strcasestr(const char *dst, const char *src) { - int dc, sc; - int len; - - len = strlen(src) - 1; - for(; (sc = *src) && *dst; src++) { - sc = tolower(dc); - for(; (dc = *dst); dst++) { - dc = tolower(dc); - if(sc == dc && !strncasecmp(dst+1, src+1, len)) - return (char*)(uintptr_t)dst; - } - } - return nil; -} - diff --git a/cmd/wmii/Makefile b/cmd/wmii/Makefile index 63768f40..10e9efe0 100644 --- a/cmd/wmii/Makefile +++ b/cmd/wmii/Makefile @@ -24,25 +24,18 @@ OBJ = area \ float \ frame \ fs \ - geom \ key \ layout \ main \ - map \ message \ mouse \ print \ root \ rule \ - printevent\ screen \ utf \ - _util \ view \ - xdnd \ - x11 \ - xext \ - ../util + xdnd include $(ROOT)/mk/one.mk diff --git a/cmd/wmii/_util.c b/cmd/wmii/_util.c deleted file mode 100644 index feafba99..00000000 --- a/cmd/wmii/_util.c +++ /dev/null @@ -1,378 +0,0 @@ -/* Copyright ©2008-2010 Kris Maglione - * See LICENSE file for license details. - */ -#include "dat.h" -#include -#include -#include -#include -#include -#include -#include -#include "fns.h" - -/* Blech. */ -#define VECTOR(type, nam, c) \ -void \ -vector_##c##init(Vector_##nam *v) { \ - memset(v, 0, sizeof *v); \ -} \ - \ -void \ -vector_##c##free(Vector_##nam *v) { \ - free(v->ary); \ - memset(v, 0, sizeof *v); \ -} \ - \ -void \ -vector_##c##push(Vector_##nam *v, type val) { \ - if(v->n == v->size) { \ - if(v->size == 0) \ - v->size = 2; \ - v->size <<= 2; \ - v->ary = erealloc(v->ary, v->size * sizeof *v->ary); \ - } \ - v->ary[v->n++] = val; \ -} \ - -VECTOR(long, long, l) -VECTOR(Rectangle, rect, r) -VECTOR(void*, ptr, p) - -int -doublefork(void) { - pid_t pid; - int status; - - switch(pid=fork()) { - case -1: - fatal("Can't fork(): %r"); - case 0: - switch(pid=fork()) { - case -1: - fatal("Can't fork(): %r"); - case 0: - return 0; - default: - exit(0); - } - default: - waitpid(pid, &status, 0); - return pid; - } - /* NOTREACHED */ -} - -void -closeexec(int fd) { - if(fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) - fatal("can't set %d close on exec: %r", fd); -} - -int -spawn3(int fd[3], const char *file, char *argv[]) { - /* Some ideas from Russ Cox's libthread port. */ - int p[2]; - int pid; - - if(pipe(p) < 0) - return -1; - closeexec(p[1]); - - switch(pid = doublefork()) { - case 0: - dup2(fd[0], 0); - dup2(fd[1], 1); - dup2(fd[2], 2); - - execvp(file, argv); - write(p[1], &errno, sizeof errno); - exit(1); - break; - default: - close(p[1]); - if(read(p[0], &errno, sizeof errno) == sizeof errno) - pid = -1; - close(p[0]); - break; - case -1: /* can't happen */ - break; - } - - close(fd[0]); - /* These could fail if any of these was also a previous fd. */ - close(fd[1]); - close(fd[2]); - return pid; -} - -int -spawn3l(int fd[3], const char *file, ...) { - va_list ap; - char **argv; - int i, n; - - va_start(ap, file); - for(n=0; va_arg(ap, char*); n++) - ; - va_end(ap); - - argv = emalloc((n+1) * sizeof *argv); - va_start(ap, file); - quotefmtinstall(); - for(i=0; i <= n; i++) - argv[i] = va_arg(ap, char*); - va_end(ap); - - i = spawn3(fd, file, argv); - free(argv); - return i; -} - -#ifdef __linux__ -# define PROGTXT "exe" -#else -# define PROGTXT "file" -#endif - -static void -_backtrace(int pid, char *btarg) { - char *proc, *spid, *gdbcmd; - int fd[3], p[2]; - int status, cmdfd; - - gdbcmd = estrdup("/tmp/gdbcmd.XXXXXX"); - if(pipe(p) < 0) - goto done; - closeexec(p[0]); - - cmdfd = mkstemp(gdbcmd); - if(cmdfd < 0) - goto done; - - fprint(cmdfd, "bt %s\n", btarg); - fprint(cmdfd, "detach\n"); - close(cmdfd); - - fd[0] = open("/dev/null", O_RDONLY); - fd[1] = p[1]; - fd[2] = dup(2); - - proc = sxprint("/proc/%d/" PROGTXT, pid); - spid = sxprint("%d", pid); - if(spawn3l(fd, "gdb", "gdb", "-batch", "-x", gdbcmd, proc, spid, nil) < 0) { - unlink(gdbcmd); - goto done; - } - - Biobuf bp; - char *s; - - Binit(&bp, p[0], OREAD); - while((s = Brdstr(&bp, '\n', 1))) { - Dprint(DStack, "%s\n", s); - free(s); - } - unlink(gdbcmd); - -done: - free(gdbcmd); - kill(pid, SIGKILL); - waitpid(pid, &status, 0); -} - -void -backtrace(char *btarg) { - int pid; - - /* Fork so we can backtrace the child. Keep this stack - * frame minimal, so the trace is fairly clean. - */ - Debug(DStack) - switch(pid = fork()) { - case -1: - return; - case 0: - kill(getpid(), SIGSTOP); - _exit(0); - default: - _backtrace(pid, btarg); - break; - } - -} - -void -reinit(Regex *r, char *regx) { - - refree(r); - - if(regx[0] != '\0') { - r->regex = estrdup(regx); - r->regc = regcomp(regx); - } -} - -void -refree(Regex *r) { - - free(r->regex); - free(r->regc); - r->regex = nil; - r->regc = nil; -} - -void -uniq(char **toks) { - char **p, **q; - - q = toks; - if(*q == nil) - return; - for(p=q+1; *p; p++) - if(strcmp(*q, *p)) - *++q = *p; - *++q = nil; -} - -char** -comm(int cols, char **toka, char **tokb) { - Vector_ptr vec; - char **ret; - int cmp; - - vector_pinit(&vec); - while(*toka || *tokb) { - if(!*toka) - cmp = 1; - else if(!*tokb) - cmp = -1; - else - cmp = strcmp(*toka, *tokb); - if(cmp < 0) { - if(cols & CLeft) - vector_ppush(&vec, *toka); - toka++; - }else if(cmp > 0) { - if(cols & CRight) - vector_ppush(&vec, *tokb); - tokb++; - }else { - if(cols & CCenter) - vector_ppush(&vec, *toka); - toka++; - tokb++; - } - } - vector_ppush(&vec, nil); - ret = strlistdup((char**)vec.ary); - free(vec.ary); - return ret; -} - -void -grep(char **list, Reprog *re, int flags) { - char **p, **q; - int res; - - q = list; - for(p=q; *p; p++) { - res = 0; - if(re) - res = regexec(re, *p, nil, 0); - if(res && !(flags & GInvert) - || !res && (flags & GInvert)) - *q++ = *p; - } - *q = nil; -} - -char* -join(char **list, char *sep) { - Fmt f; - char **p; - - if(fmtstrinit(&f) < 0) - abort(); - - for(p=list; *p; p++) { - if(p != list) - fmtstrcpy(&f, sep); - fmtstrcpy(&f, *p); - } - - return fmtstrflush(&f); -} - -int -strlcatprint(char *buf, int len, const char *fmt, ...) { - va_list ap; - int buflen; - int ret; - - va_start(ap, fmt); - buflen = strlen(buf); - ret = vsnprint(buf+buflen, len-buflen, fmt, ap); - va_end(ap); - return ret; -} - -char* -pathsearch(const char *path, const char *file, bool slashok) { - char *orig, *p, *s; - - if(!slashok && strchr(file, '/') > file) - file = sxprint("%s/%s", getcwd(buffer, sizeof buffer), file); - else if(!strncmp(file, "./", 2)) - file = sxprint("%s/%s", getcwd(buffer, sizeof buffer), file+2); - if(file[0] == '/') { - if(access(file, X_OK)) - return strdup(file); - return nil; - } - - orig = estrdup(path ? path : getenv("PATH")); - for(p=orig; (s=strtok(p, ":")); p=nil) { - s = smprint("%s/%s", s, file); - if(!access(s, X_OK)) - break; - free(s); - } - free(orig); - return s; -} - -int -unquote(char *buf, char *toks[], int ntoks) { - char *s, *t; - bool inquote; - int n; - - n = 0; - s = buf; - while(*s && n < ntoks) { - while(*s && utfrune(" \t\r\n", *s)) - s++; - inquote = false; - toks[n] = s; - t = s; - while(*s && (inquote || !utfrune(" \t\r\n", *s))) { - if(*s == '\'') { - if(inquote && s[1] == '\'') - *t++ = *s++; - else - inquote = !inquote; - } - else - *t++ = *s; - s++; - } - if(*s) - s++; - *t = '\0'; - if(s != toks[n]) - n++; - } - return n; -} - diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c index 124b18ba..1d83dfe4 100644 --- a/cmd/wmii/client.c +++ b/cmd/wmii/client.c @@ -314,7 +314,7 @@ client_destroy(Client *c) { if(starting > -1) event("DestroyClient %C\n", c); - flushevents(FocusChangeMask, true); + event_flush(FocusChangeMask, true); free(c->w.hints); free(c); } @@ -503,7 +503,7 @@ client_focus(Client *c) { c->group->client = c; sync(); - flushevents(FocusChangeMask, true); + event_flush(FocusChangeMask, true); Dprint(DFocus, "client_focus([%C]%s)\n", c, clientname(c)); Dprint(DFocus, "\t[%C]%s\n\t=> [%C]%s\n", @@ -514,14 +514,14 @@ client_focus(Client *c) { if(!c->noinput) setfocus(&c->w, RevertToParent); else if(c->proto & ProtoTakeFocus) { - xtime_kludge(); + event_updatextime(); client_message(c, "WM_TAKE_FOCUS", 0); } }else setfocus(screen->barwin, RevertToParent); sync(); - flushevents(FocusChangeMask, true); + event_flush(FocusChangeMask, true); } } diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h index 8038026d..2308ea00 100644 --- a/cmd/wmii/dat.h +++ b/cmd/wmii/dat.h @@ -11,11 +11,11 @@ #include #include #include -#include -#include #include -#include -#include +#include +#include +#include +#include #define FONT "-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*" #define FOCUSCOLORS "#ffffff #335577 #447799" @@ -25,22 +25,12 @@ enum { PingTime = 10000, }; -enum { - CLeft = 1<<0, - CCenter = 1<<1, - CRight = 1<<2, -}; - enum IncMode { IIgnore, IShow, ISqueeze, }; -enum { - GInvert = 1<<0, -}; - enum { UrgManager, UrgClient, @@ -79,15 +69,6 @@ enum Barpos { BTop, }; -enum { - CurNormal, - CurNECorner, CurNWCorner, CurSECorner, CurSWCorner, - CurDHArrow, CurDVArrow, CurMove, CurInput, CurSizing, - CurTCross, CurIcon, - CurNone, - CurLast, -}; - enum { NCOL = 16, }; @@ -98,16 +79,16 @@ enum Protocols { ProtoPing = 1<<2, }; -enum DebugOpt { - D9p = 1<<0, - DDnd = 1<<1, - DEvent = 1<<2, - DEwmh = 1<<3, - DFocus = 1<<4, - DGeneric= 1<<5, - DStack = 1<<6, - NDebugOpt = 7, +enum { + CurNormal, + CurNECorner, CurNWCorner, CurSECorner, CurSWCorner, + CurDHArrow, CurDVArrow, CurMove, CurInput, CurSizing, + CurTCross, CurIcon, + CurNone, + CurLast, }; +Cursor cursor[CurLast]; + /* Data Structures */ typedef struct Area Area; @@ -117,9 +98,6 @@ typedef struct Divide Divide; typedef struct Frame Frame; typedef struct Group Group; typedef struct Key Key; -typedef struct Map Map; -typedef struct MapEnt MapEnt; -typedef struct Regex Regex; typedef struct Rule Rule; typedef struct Ruleset Ruleset; typedef struct Strut Strut; @@ -156,11 +134,6 @@ struct Bar { WMScreen* screen; }; -struct Regex { - char* regex; - Reprog* regc; -}; - struct Client { Client* next; Frame* frame; @@ -243,11 +216,6 @@ struct Key { KeyCode key; }; -struct Map { - MapEnt**bucket; - uint nhash; -}; - struct Rule { Rule* next; Reprog* regex; @@ -286,23 +254,6 @@ struct View { Rectangle *pad; }; -/* Yuck. */ -#define VECTOR(type, nam, c) \ -typedef struct Vector_##nam Vector_##nam; \ -struct Vector_##nam { \ - type* ary; \ - long n; \ - long size; \ -}; \ -void vector_##c##free(Vector_##nam*); \ -void vector_##c##init(Vector_##nam*); \ -void vector_##c##push(Vector_##nam*, type); \ - -VECTOR(long, long, l) -VECTOR(Rectangle, rect, r) -VECTOR(void*, ptr, p) -#undef VECTOR - #ifndef EXTERN # define EXTERN extern #endif @@ -328,8 +279,6 @@ enum { BLeft, BRight }; -#define BLOCK(x) do { x; }while(0) - EXTERN struct WMScreen { Bar* bar[2]; Window* barwin; @@ -360,15 +309,6 @@ EXTERN Client c_root; EXTERN Handlers framehandler; -EXTERN char buffer[8092]; -EXTERN char* _buffer; -static char* const _buf_end = buffer + sizeof buffer; - -#define bufclear() \ - BLOCK( _buffer = buffer; _buffer[0] = '\0' ) -#define bufprint(...) \ - _buffer = seprint(_buffer, _buf_end, __VA_ARGS__) - /* IXP */ EXTERN IxpServer srv; EXTERN Ixp9Srv p9srv; @@ -379,26 +319,15 @@ EXTERN uint numlock_mask; EXTERN Image* ibuf; EXTERN Image* ibuf32; -EXTERN Cursor cursor[CurLast]; - -typedef void (*XHandler)(XEvent*); -EXTERN XHandler handler[LASTEvent]; - /* Misc */ EXTERN int starting; EXTERN bool resizing; EXTERN long ignoreenter; EXTERN char* user; EXTERN char* execstr; -EXTERN int debugflag; -EXTERN int debugfile; EXTERN long xtime; -EXTERN Visual* render_visual; EXTERN Client* kludge; extern char* debugtab[]; -#define Debug(x) if(((debugflag|debugfile)&(x)) && setdebug(x)) -#define Dprint(x, ...) BLOCK( if((debugflag|debugfile)&(x)) debug(x, __VA_ARGS__) ) - diff --git a/cmd/wmii/event.c b/cmd/wmii/event.c index 82a51ebc..f73b9720 100644 --- a/cmd/wmii/event.c +++ b/cmd/wmii/event.c @@ -5,105 +5,16 @@ #include #include "fns.h" -typedef void (*EvHandler)(XEvent*); - void -dispatch_event(XEvent *e) { +debug_event(XEvent *e) { Dprint(DEvent, "%E\n", e); - if(e->type < nelem(handler)) { - if(handler[e->type]) - handler[e->type](e); - }else - xext_event(e); } #define handle(w, fn, ev) \ BLOCK(if((w)->handler->fn) (w)->handler->fn((w), ev)) -static int -findtime(Display *d, XEvent *e, XPointer v) { - Window *w; - - w = (Window*)v; - if(e->type == PropertyNotify && e->xproperty.window == w->xid) { - xtime = e->xproperty.time; - return true; - } - return false; -} - void -xtime_kludge(void) { - /* Round trip. */ - static Window *w; - WinAttr wa; - XEvent e; - long l; - - if(w == nil) { - w = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, InputOnly, &wa, 0); - selectinput(w, PropertyChangeMask); - } - changeprop_long(w, "ATOM", "ATOM", &l, 0); - sync(); - XIfEvent(display, &e, findtime, (void*)w); -} - -uint -flushevents(long event_mask, bool dispatch) { - XEvent ev; - uint n = 0; - - while(XCheckMaskEvent(display, event_mask, &ev)) { - if(dispatch) - dispatch_event(&ev); - n++; - } - return n; -} - -static Bool -findenter(Display *d, XEvent *e, XPointer v) { - long *l; - - USED(d); - l = (long*)v; - if(*l) - return false; - if(e->type == EnterNotify) - return true; - if(e->type == MotionNotify) - (*l)++; - return false; -} - -/* This isn't perfect. If there were motion events in the queue - * before this was called, then it flushes nothing. If we don't - * check for them, we might lose a legitamate enter event. - */ -uint -flushenterevents(void) { - XEvent e; - long l; - int n; - - l = 0; - n = 0; - while(XCheckIfEvent(display, &e, findenter, (void*)&l)) - n++; - return n; -} - -static void -buttonrelease(XButtonPressedEvent *ev) { - Window *w; - - if((w = findwin(ev->window))) - handle(w, bup, ev); -} - -static void -buttonpress(XButtonPressedEvent *ev) { +event_buttonpress(XButtonPressedEvent *ev) { Window *w; if((w = findwin(ev->window))) @@ -112,27 +23,8 @@ buttonpress(XButtonPressedEvent *ev) { XAllowEvents(display, ReplayPointer, ev->time); } -static void -configurerequest(XConfigureRequestEvent *ev) { - XWindowChanges wc; - Window *w; - - if((w = findwin(ev->window))) - handle(w, configreq, ev); - else{ - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - XConfigureWindow(display, ev->window, ev->value_mask, &wc); - } -} - -static void -configurenotify(XConfigureEvent *ev) { +void +event_configurenotify(XConfigureEvent *ev) { Window *w; ignoreenter = ev->serial; @@ -140,8 +32,8 @@ configurenotify(XConfigureEvent *ev) { handle(w, config, ev); } -static void -clientmessage(XClientMessageEvent *ev) { +void +event_clientmessage(XClientMessageEvent *ev) { if(ewmh_clientmessage(ev)) return; @@ -149,40 +41,16 @@ clientmessage(XClientMessageEvent *ev) { return; } -static void -destroynotify(XDestroyWindowEvent *ev) { +void +event_destroynotify(XDestroyWindowEvent *ev) { Window *w; Client *c; if((w = findwin(ev->window))) handle(w, destroy, ev); - else { - if((c = win2client(ev->window))) - fprint(2, "Badness: Unhandled DestroyNotify: " - "Client: %p, Window: %W, Name: %s\n", - c, &c->w, c->name); - } -} - -static void -enternotify(XCrossingEvent *ev) { - Window *w; - - xtime = ev->time; - if(ev->mode != NotifyNormal) - return; - - if((w = findwin(ev->window))) - handle(w, enter, ev); -} - -static void -leavenotify(XCrossingEvent *ev) { - Window *w; - - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, leave, ev); + else if((c = win2client(ev->window))) + fprint(2, "Badness: Unhandled DestroyNotify: Client: %p, Window: %W, Name: %s\n", + c, &c->w, c->name); } void @@ -192,8 +60,8 @@ print_focus(const char *fn, Client *c, const char *to) { Dprint(DFocus, "\t%s => %s\n", clientname(disp.focus), to); } -static void -focusin(XFocusChangeEvent *ev) { +void +event_focusin(XFocusChangeEvent *ev) { Window *w; Client *c; @@ -231,8 +99,8 @@ focusin(XFocusChangeEvent *ev) { } } -static void -focusout(XFocusChangeEvent *ev) { +void +event_focusout(XFocusChangeEvent *ev) { XEvent me; Window *w; @@ -247,74 +115,22 @@ focusout(XFocusChangeEvent *ev) { if((ev->mode == NotifyGrab) && XCheckMaskEvent(display, KeyPressMask, &me)) - dispatch_event(&me); + event_dispatch(&me); else if((w = findwin(ev->window))) handle(w, focusout, ev); } -static void -expose(XExposeEvent *ev) { - Window *w; +void +event_mapnotify(XMapEvent *ev) { + Window *w; - if(ev->count == 0) - if((w = findwin(ev->window))) - handle(w, expose, ev); + ignoreenter = ev->serial; + if((w = findwin(ev->window))) + handle(w, map, ev); } -static void -keypress(XKeyEvent *ev) { - Window *w; - - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, kdown, ev); -} - -static void -mappingnotify(XMappingEvent *ev) { - - XRefreshKeyboardMapping(ev); - if(ev->request == MappingKeyboard) - update_keys(); -} - -static void -maprequest(XMapRequestEvent *ev) { - Window *w; - - if((w = findwin(ev->parent))) - handle(w, mapreq, ev); -} - -static void -motionnotify(XMotionEvent *ev) { - Window *w; - - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, motion, ev); -} - -static void -propertynotify(XPropertyEvent *ev) { - Window *w; - - xtime = ev->time; - if((w = findwin(ev->window))) - handle(w, property, ev); -} - -static void -mapnotify(XMapEvent *ev) { - Window *w; - - ignoreenter = ev->serial; - if((w = findwin(ev->window))) - handle(w, map, ev); -} - -static void -unmapnotify(XUnmapEvent *ev) { +void +event_unmapnotify(XUnmapEvent *ev) { Window *w; ignoreenter = ev->serial; @@ -325,35 +141,3 @@ unmapnotify(XUnmapEvent *ev) { } } -EvHandler handler[LASTEvent] = { - [ButtonPress] = (EvHandler)buttonpress, - [ButtonRelease] = (EvHandler)buttonrelease, - [ConfigureRequest] = (EvHandler)configurerequest, - [ConfigureNotify] = (EvHandler)configurenotify, - [ClientMessage] = (EvHandler)clientmessage, - [DestroyNotify] = (EvHandler)destroynotify, - [EnterNotify] = (EvHandler)enternotify, - [Expose] = (EvHandler)expose, - [FocusIn] = (EvHandler)focusin, - [FocusOut] = (EvHandler)focusout, - [KeyPress] = (EvHandler)keypress, - [LeaveNotify] = (EvHandler)leavenotify, - [MapNotify] = (EvHandler)mapnotify, - [MapRequest] = (EvHandler)maprequest, - [MappingNotify] = (EvHandler)mappingnotify, - [MotionNotify] = (EvHandler)motionnotify, - [PropertyNotify] = (EvHandler)propertynotify, - [UnmapNotify] = (EvHandler)unmapnotify, -}; - -void -check_x_event(IxpConn *c) { - XEvent ev; - - USED(c); - while(XPending(display)) { - XNextEvent(display, &ev); - dispatch_event(&ev); - } -} - diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h index 9b53ef95..1c99e74f 100644 --- a/cmd/wmii/fns.h +++ b/cmd/wmii/fns.h @@ -129,12 +129,8 @@ void poperror(void); jmp_buf* pusherror(void); /* event.c */ -void check_x_event(IxpConn*); -void dispatch_event(XEvent*); -uint flushenterevents(void); -uint flushevents(long, bool dispatch); +void debug_event(XEvent*); void print_focus(const char*, Client*, const char*); -void xtime_kludge(void); /* ewmh.c */ int ewmh_clientmessage(XClientMessageEvent*); @@ -197,15 +193,6 @@ void fs_walk(Ixp9Req*); void fs_write(Ixp9Req*); void event(const char*, ...); -/* geom.c */ -Align get_sticky(Rectangle src, Rectangle dst); -Cursor quad_cursor(Align); -Align quadrant(Rectangle, Point); -bool rect_contains_p(Rectangle, Rectangle); -bool rect_haspoint_p(Point, Rectangle); -bool rect_intersect_p(Rectangle, Rectangle); -Rectangle rect_intersection(Rectangle, Rectangle); - /* key.c */ void init_lock_keys(void); void kpress(XWindow, ulong mod, KeyCode); @@ -215,15 +202,7 @@ void update_keys(void); void init_screens(void); void spawn_command(const char*); -/* map.c */ -void** hash_get(Map*, const char*, bool create); -void* hash_rm(Map*, const char*); -void** map_get(Map*, ulong, bool create); -void* map_rm(Map*, ulong); - /* message.c */ -bool getlong(const char*, long*); -bool getulong(const char*, ulong*); char* message_client(Client*, IxpMsg*); char* message_root(void*, IxpMsg*); char* message_view(View*, IxpMsg*); @@ -237,6 +216,7 @@ char* readctl_root(void); char* readctl_view(View*); Area* strarea(View*, ulong, const char*); void warning(const char*, ...); + /* debug */ void debug(int, const char*, ...); void dprint(const char*, ...); @@ -259,9 +239,6 @@ Align snap_rect(const Rectangle *rects, int num, Rectangle *current, Align *mask /* print.c */ int Ffmt(Fmt*); -/* printevent.c */ -void printevent(XEvent*); - /* root.c */ void root_init(void); @@ -295,22 +272,6 @@ void view_update_all(void); void view_update_rect(View*); Rectangle* view_rects(View*, uint *num, Frame *ignore); -/* _util.c */ -void backtrace(char*); -void closeexec(int); -char** comm(int, char**, char**); -int doublefork(void); -void grep(char**, Reprog*, int); -char* join(char**, char*); -char* pathsearch(const char*, const char*, bool); -void refree(Regex*); -void reinit(Regex*, char*); -int strlcatprint(char*, int, const char*, ...); -int spawn3(int[3], const char*, char*[]); -int spawn3l(int[3], const char*, ...); -void uniq(char**); -int unquote(char*, char*[], int); - /* utf.c */ char* toutf8(const char*); char* toutf8n(const char*, size_t); @@ -319,10 +280,3 @@ char* toutf8n(const char*, size_t); int xdnd_clientmessage(XClientMessageEvent*); void xdnd_initwindow(Window*); -/* xext.c */ -void randr_event(XEvent*); -bool render_argb_p(Visual*); -void xext_event(XEvent*); -void xext_init(void); -Rectangle* xinerama_screens(int*); - diff --git a/cmd/wmii/geom.c b/cmd/wmii/geom.c deleted file mode 100644 index 464eb67d..00000000 --- a/cmd/wmii/geom.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright ©2006-2010 Kris Maglione - * See LICENSE file for license details. - */ -#include "dat.h" -#include "fns.h" - -bool -rect_haspoint_p(Point pt, Rectangle r) { - return (pt.x >= r.min.x) && (pt.x < r.max.x) - && (pt.y >= r.min.y) && (pt.y < r.max.y); -} - -bool -rect_intersect_p(Rectangle r, Rectangle r2) { - return r.min.x <= r2.max.x - && r.max.x >= r2.min.x - && r.min.y <= r2.max.y - && r.max.y >= r2.min.y; -} - -Rectangle -rect_intersection(Rectangle r, Rectangle r2) { - Rectangle ret; - - /* ret != canonrect(ret) ≡ no intersection. */ - ret.min.x = max(r.min.x, r2.min.x); - ret.max.x = min(r.max.x, r2.max.x); - ret.min.y = max(r.min.y, r2.min.y); - ret.max.y = min(r.max.y, r2.max.y); - return ret; -} - -bool -rect_contains_p(Rectangle r, Rectangle r2) { - return r2.min.x >= r.min.x - && r2.max.x <= r.max.x - && r2.min.y >= r.min.y - && r2.max.y <= r.max.y; -} - -Align -quadrant(Rectangle r, Point pt) { - Align ret; - - pt = subpt(pt, r.min); - ret = 0; - - if(pt.x >= Dx(r) * .5) - ret |= East; - if(pt.x <= Dx(r) * .5) - ret |= West; - if(pt.y <= Dy(r) * .5) - ret |= North; - if(pt.y >= Dy(r) * .5) - ret |= South; - - return ret; -} - -Cursor -quad_cursor(Align align) { - switch(align) { - case NEast: return cursor[CurNECorner]; - case NWest: return cursor[CurNWCorner]; - case SEast: return cursor[CurSECorner]; - case SWest: return cursor[CurSWCorner]; - case South: - case North: return cursor[CurDVArrow]; - case East: - case West: return cursor[CurDHArrow]; - default: return cursor[CurMove]; - } -} - -Align -get_sticky(Rectangle src, Rectangle dst) { - Align corner; - - corner = 0; - if(src.min.x != dst.min.x - && src.max.x == dst.max.x) - corner |= East; - else - corner |= West; - - if(src.min.y != dst.min.y - && src.max.y == dst.max.y) - corner |= South; - else - corner |= North; - - return corner; -} - diff --git a/cmd/wmii/key.c b/cmd/wmii/key.c index f2c34711..bba06b16 100644 --- a/cmd/wmii/key.c +++ b/cmd/wmii/key.c @@ -208,7 +208,7 @@ kpress(XWindow w, ulong mod, KeyCode keycode) { event("Key %s\n", found->name); else { XGrabKeyboard(display, w, true, GrabModeAsync, GrabModeAsync, CurrentTime); - flushevents(FocusChangeMask, true); + event_flush(FocusChangeMask, true); kpress_seq(w, found); XUngrabKeyboard(display, CurrentTime); } diff --git a/cmd/wmii/main.c b/cmd/wmii/main.c index fba5d5f4..af3bac05 100644 --- a/cmd/wmii/main.c +++ b/cmd/wmii/main.c @@ -323,7 +323,7 @@ static void check_preselect(IxpServer *s) { USED(s); - check_x_event(nil); + event_check(); } static void @@ -412,9 +412,11 @@ extern int fmtevent(Fmt*); ewmh_init(); xext_init(); + event_debug = debug_event; + srv.preselect = check_preselect; ixp_listen(&srv, sock, &p9srv, serve_9pcon, nil); - ixp_listen(&srv, ConnectionNumber(display), nil, check_x_event, closedisplay); + ixp_listen(&srv, ConnectionNumber(display), nil, (void (*)(IxpConn*))check_preselect, closedisplay); def.border = 1; def.colmode = Colstack; diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c index d1dd4a7b..e8131518 100644 --- a/cmd/wmii/message.c +++ b/cmd/wmii/message.c @@ -231,97 +231,6 @@ msg_getword(IxpMsg *m) { return ret; } -#define strbcmp(str, const) (strncmp((str), (const), sizeof(const)-1)) -static int -getbase(const char **s, long *sign) { - const char *p; - int ret; - - ret = 10; - *sign = 1; - if(**s == '-') { - *sign = -1; - *s += 1; - }else if(**s == '+') - *s += 1; - - p = *s; - if(!strbcmp(p, "0x")) { - *s += 2; - ret = 16; - } - else if(isdigit(p[0])) { - if(p[1] == 'r') { - *s += 2; - ret = p[0] - '0'; - } - else if(isdigit(p[1]) && p[2] == 'r') { - *s += 3; - ret = 10*(p[0]-'0') + (p[1]-'0'); - } - } - else if(p[0] == '0') { - ret = 8; - } - if(ret != 10 && (**s == '-' || **s == '+')) - *sign = 0; - return ret; -} - -static bool -getint(const char *s, int *ret) { - long l; - bool res; - - res = getlong(s, &l); - *ret = l; - return res; -} - -bool -getlong(const char *s, long *ret) { - const char *end; - char *rend; - int base; - long sign; - - if(s == nil) - return false; - end = s+strlen(s); - base = getbase(&s, &sign); - if(sign == 0) - return false; - - *ret = sign * strtol(s, &rend, base); - return (end == rend); -} - -bool -getulong(const char *s, ulong *ret) { - const char *end; - char *rend; - int base; - long sign; - - if(s == nil) - return false; - end = s+strlen(s); - base = getbase(&s, &sign); - if(sign < 1) - return false; - - *ret = strtoul(s, &rend, base); - return (end == rend); -} - -static char* -strend(char *s, int n) { - int len; - - len = strlen(s); - return s + max(0, len - n); -} - static Client* strclient(View *v, char *s) { ulong id; diff --git a/cmd/wmii/mouse.c b/cmd/wmii/mouse.c index fb7e2ff5..53cef287 100644 --- a/cmd/wmii/mouse.c +++ b/cmd/wmii/mouse.c @@ -13,6 +13,21 @@ enum { ButtonMask | PointerMotionMask }; +static Cursor +quad_cursor(Align align) { + switch(align) { + case NEast: return cursor[CurNECorner]; + case NWest: return cursor[CurNWCorner]; + case SEast: return cursor[CurSECorner]; + case SWest: return cursor[CurSWCorner]; + case South: + case North: return cursor[CurDVArrow]; + case East: + case West: return cursor[CurDHArrow]; + default: return cursor[CurMove]; + } +} + static void cwin_expose(Window *w, XExposeEvent *e) { @@ -176,7 +191,7 @@ readmouse(Point *p, uint *button) { case Expose: case NoExpose: case PropertyNotify: - dispatch_event(&ev); + event_dispatch(&ev); default: Dprint(DEvent, "readmouse(): ignored: %E\n", &ev); continue; @@ -428,7 +443,7 @@ mouse_resize(Client *c, Align align, bool grabmod) { warppointer(d); } sync(); - flushevents(PointerMotionMask, false); + event_flush(PointerMotionMask, false); while(readmotion(&d)) { if(align == Center) { diff --git a/cmd/wmii/x11.c b/cmd/wmii/x11.c deleted file mode 100644 index dafe85cb..00000000 --- a/cmd/wmii/x11.c +++ /dev/null @@ -1,1317 +0,0 @@ -/* Copyright ©2007-2010 Kris Maglione - * See LICENSE file for license details. - */ -#define _X11_VISIBLE -#define pointerwin __pointerwin -#include "dat.h" -#include -#include -#include -#include -#include -#include "fns.h" -#undef pointerwin - -const Point ZP = {0, 0}; -const Rectangle ZR = {{0, 0}, {0, 0}}; - -const Window _pointerwin = { .xid = PointerRoot }; -Window* const pointerwin = (Window*)&_pointerwin; - -static Map windowmap; -static Map atommap; -static MapEnt* wbucket[137]; -static MapEnt* abucket[137]; - -static int errorhandler(Display*, XErrorEvent*); -static int (*xlib_errorhandler) (Display*, XErrorEvent*); - -static XftColor* xftcolor(Color); - - -/* Rectangles/Points */ -XRectangle -XRect(Rectangle r) { - XRectangle xr; - - xr.x = r.min.x; - xr.y = r.min.y; - xr.width = Dx(r); - xr.height = Dy(r); - return xr; -} - -int -eqrect(Rectangle a, Rectangle b) { - return a.min.x==b.min.x && a.max.x==b.max.x - && a.min.y==b.min.y && a.max.y==b.max.y; -} - -int -eqpt(Point p, Point q) { - return p.x==q.x && p.y==q.y; -} - -Point -addpt(Point p, Point q) { - p.x += q.x; - p.y += q.y; - return p; -} - -Point -subpt(Point p, Point q) { - p.x -= q.x; - p.y -= q.y; - return p; -} - -Point -mulpt(Point p, Point q) { - p.x *= q.x; - p.y *= q.y; - return p; -} - -Point -divpt(Point p, Point q) { - p.x /= q.x; - p.y /= q.y; - return p; -} - -Rectangle -insetrect(Rectangle r, int n) { - r.min.x += n; - r.min.y += n; - r.max.x -= n; - r.max.y -= n; - return r; -} - -Rectangle -rectaddpt(Rectangle r, Point p) { - r.min.x += p.x; - r.max.x += p.x; - r.min.y += p.y; - r.max.y += p.y; - return r; -} - -Rectangle -rectsubpt(Rectangle r, Point p) { - r.min.x -= p.x; - r.max.x -= p.x; - r.min.y -= p.y; - r.max.y -= p.y; - return r; -} - -Rectangle -rectsetorigin(Rectangle r, Point p) { - Rectangle ret; - - ret.min.x = p.x; - ret.min.y = p.y; - ret.max.x = p.x + Dx(r); - ret.max.y = p.y + Dy(r); - return ret; -} - -/* Formatters */ -static int -Afmt(Fmt *f) { - Atom a; - char *s; - int i; - - a = va_arg(f->args, Atom); - s = XGetAtomName(display, a); - i = fmtprint(f, "%s", s); - free(s); - return i; -} - -static int -Rfmt(Fmt *f) { - Rectangle r; - - r = va_arg(f->args, Rectangle); - return fmtprint(f, "%P+%dx%d", r.min, Dx(r), Dy(r)); -} - -static int -Pfmt(Fmt *f) { - Point p; - - p = va_arg(f->args, Point); - return fmtprint(f, "(%d,%d)", p.x, p.y); -} - -static int -Wfmt(Fmt *f) { - Window *w; - - w = va_arg(f->args, Window*); - return fmtprint(f, "0x%ulx", w->xid); -} - -/* Init */ -void -initdisplay(void) { - display = XOpenDisplay(nil); - if(display == nil) - fatal("Can't open display"); - scr.screen = DefaultScreen(display); - scr.colormap = DefaultColormap(display, scr.screen); - scr.visual = DefaultVisual(display, scr.screen); - scr.visual32 = DefaultVisual(display, scr.screen); - scr.gc = DefaultGC(display, scr.screen); - scr.depth = DefaultDepth(display, scr.screen); - - scr.white = WhitePixel(display, scr.screen); - scr.black = BlackPixel(display, scr.screen); - - scr.root.xid = RootWindow(display, scr.screen); - scr.root.r = Rect(0, 0, - DisplayWidth(display, scr.screen), - DisplayHeight(display, scr.screen)); - scr.rect = scr.root.r; - - scr.root.parent = &scr.root; - - windowmap.bucket = wbucket; - windowmap.nhash = nelem(wbucket); - atommap.bucket = abucket; - atommap.nhash = nelem(abucket); - - fmtinstall('A', Afmt); - fmtinstall('R', Rfmt); - fmtinstall('P', Pfmt); - fmtinstall('W', Wfmt); - - xlib_errorhandler = XSetErrorHandler(errorhandler); -} - -/* Error handling */ - -extern ErrorCode ignored_xerrors[]; -static bool _trap_errors; -static long nerrors; - -static int -errorhandler(Display *dpy, XErrorEvent *error) { - ErrorCode *e; - - USED(dpy); - - if(_trap_errors) - nerrors++; - - e = ignored_xerrors; - if(e) - for(; e->rcode || e->ecode; e++) - if((e->rcode == 0 || e->rcode == error->request_code) - && (e->ecode == 0 || e->ecode == error->error_code)) - return 0; - - fprint(2, "%s: fatal error: Xrequest code=%d, Xerror code=%d\n", - argv0, error->request_code, error->error_code); - return xlib_errorhandler(display, error); /* calls exit() */ -} - -int -traperrors(bool enable) { - - sync(); - _trap_errors = enable; - if (enable) - nerrors = 0; - return nerrors; - -} - -/* Images */ -Image* -allocimage(int w, int h, int depth) { - Image *img; - - img = emallocz(sizeof *img); - img->type = WImage; - img->xid = XCreatePixmap(display, scr.root.xid, w, h, depth); - img->gc = XCreateGC(display, img->xid, 0, nil); - img->colormap = scr.colormap; - img->visual = scr.visual; - if(depth == 32) - img->visual = scr.visual32; - img->depth = depth; - img->r = Rect(0, 0, w, h); - return img; -} - -void -freeimage(Image *img) { - if(img == nil) - return; - - assert(img->type == WImage); - - if(img->xft) - XftDrawDestroy(img->xft); - XFreePixmap(display, img->xid); - XFreeGC(display, img->gc); - free(img); -} - -static XftDraw* -xftdrawable(Image *img) { - if(img->xft == nil) - img->xft = XftDrawCreate(display, img->xid, img->visual, img->colormap); - return img->xft; -} - -/* Windows */ -Window* -createwindow_visual(Window *parent, Rectangle r, - int depth, Visual *vis, uint class, - WinAttr *wa, int valmask) { - Window *w; - - assert(parent->type == WWindow); - - w = emallocz(sizeof *w); - w->visual = vis; - w->type = WWindow; - w->parent = parent; - if(valmask & CWColormap) - w->colormap = wa->colormap; - - w->xid = XCreateWindow(display, parent->xid, r.min.x, r.min.y, Dx(r), Dy(r), - 0 /* border */, depth, class, vis, valmask, wa); -#if 0 - print("createwindow_visual(%W, %R, %d, %p, %ud, %p, %x) = %W\n", - parent, r, depth, vis, class, wa, valmask, w); -#endif - if(class != InputOnly) - w->gc = XCreateGC(display, w->xid, 0, nil); - - w->r = r; - w->depth = depth; - return w; -} - -Window* -createwindow(Window *parent, Rectangle r, int depth, uint class, WinAttr *wa, int valmask) { - return createwindow_visual(parent, r, depth, scr.visual, class, wa, valmask); -} - -Window* -window(XWindow xw) { - Window *w; - - w = malloc(sizeof *w); - w->type = WWindow; - w->xid = xw; - return freelater(w); -} - -void -reparentwindow(Window *w, Window *par, Point p) { - assert(w->type == WWindow); - XReparentWindow(display, w->xid, par->xid, p.x, p.y); - w->parent = par; - w->r = rectsubpt(w->r, w->r.min); - w->r = rectaddpt(w->r, p); -} - -void -destroywindow(Window *w) { - assert(w->type == WWindow); - sethandler(w, nil); - if(w->xft) - XftDrawDestroy(w->xft); - if(w->gc) - XFreeGC(display, w->gc); - XDestroyWindow(display, w->xid); - free(w); -} - -void -setwinattr(Window *w, WinAttr *wa, int valmask) { - assert(w->type == WWindow); - XChangeWindowAttributes(display, w->xid, valmask, wa); -} - -void -selectinput(Window *w, long mask) { - XSelectInput(display, w->xid, mask); -} - -static void -configwin(Window *w, Rectangle r, int border) { - XWindowChanges wc; - - if(eqrect(r, w->r) && border == w->border) - return; - - wc.x = r.min.x - border; - wc.y = r.min.y - border; - wc.width = Dx(r); - wc.height = Dy(r); - wc.border_width = border; - XConfigureWindow(display, w->xid, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - - w->r = r; - w->border = border; -} - -void -setborder(Window *w, int width, Color col) { - - assert(w->type == WWindow); - if(width) - XSetWindowBorder(display, w->xid, col.pixel); - if(width != w->border) - configwin(w, w->r, width); -} - -void -reshapewin(Window *w, Rectangle r) { - assert(w->type == WWindow); - assert(Dx(r) > 0 && Dy(r) > 0); /* Rather than an X error. */ - - configwin(w, r, w->border); -} - -void -movewin(Window *w, Point pt) { - Rectangle r; - - assert(w->type == WWindow); - r = rectsetorigin(w->r, pt); - reshapewin(w, r); -} - -int -mapwin(Window *w) { - assert(w->type == WWindow); - if(!w->mapped) { - XMapWindow(display, w->xid); - w->mapped = 1; - return 1; - } - return 0; -} - -int -unmapwin(Window *w) { - assert(w->type == WWindow); - if(w->mapped) { - XUnmapWindow(display, w->xid); - w->mapped = 0; - w->unmapped++; - return 1; - } - return 0; -} - -void -raisewin(Window *w) { - assert(w->type == WWindow); - XRaiseWindow(display, w->xid); -} - -void -lowerwin(Window *w) { - assert(w->type == WWindow); - XLowerWindow(display, w->xid); -} - -Handlers* -sethandler(Window *w, Handlers *new) { - Handlers *old; - void **e; - - assert(w->type == WWindow); - assert((w->prev != nil && w->next != nil) || w->next == w->prev); - - if(new == nil) - map_rm(&windowmap, (ulong)w->xid); - else { - e = map_get(&windowmap, (ulong)w->xid, true); - *e = w; - } - old = w->handler; - w->handler = new; - return old; -} - -Window* -findwin(XWindow w) { - void **e; - - e = map_get(&windowmap, (ulong)w, false); - if(e) - return *e; - return nil; -} - -/* Shape */ -void -setshapemask(Window *dst, Image *src, Point pt) { - /* Assumes that we have the shape extension... */ - XShapeCombineMask (display, dst->xid, - ShapeBounding, pt.x, pt.y, src->xid, ShapeSet); -} - -static void -setgccol(Image *dst, Color col) { - XSetForeground(display, dst->gc, col.pixel); -} - -/* Drawing */ -void -border(Image *dst, Rectangle r, int w, Color col) { - if(w == 0) - return; - - r = insetrect(r, w/2); - r.max.x -= w%2; - r.max.y -= w%2; - - XSetLineAttributes(display, dst->gc, w, LineSolid, CapButt, JoinMiter); - setgccol(dst, col); - XDrawRectangle(display, dst->xid, dst->gc, - r.min.x, r.min.y, Dx(r), Dy(r)); -} - -void -fill(Image *dst, Rectangle r, Color col) { - setgccol(dst, col); - XFillRectangle(display, dst->xid, dst->gc, - r.min.x, r.min.y, Dx(r), Dy(r)); -} - -static XPoint* -convpts(Point *pt, int np) { - XPoint *rp; - int i; - - rp = emalloc(np * sizeof *rp); - for(i = 0; i < np; i++) { - rp[i].x = pt[i].x; - rp[i].y = pt[i].y; - } - return rp; -} - -void -drawpoly(Image *dst, Point *pt, int np, int cap, int w, Color col) { - XPoint *xp; - - xp = convpts(pt, np); - XSetLineAttributes(display, dst->gc, w, LineSolid, cap, JoinMiter); - setgccol(dst, col); - XDrawLines(display, dst->xid, dst->gc, xp, np, CoordModeOrigin); - free(xp); -} - -void -fillpoly(Image *dst, Point *pt, int np, Color col) { - XPoint *xp; - - xp = convpts(pt, np); - setgccol(dst, col); - XFillPolygon(display, dst->xid, dst->gc, xp, np, Complex, CoordModeOrigin); - free(xp); -} - -void -drawline(Image *dst, Point p1, Point p2, int cap, int w, Color col) { - XSetLineAttributes(display, dst->gc, w, LineSolid, cap, JoinMiter); - setgccol(dst, col); - XDrawLine(display, dst->xid, dst->gc, p1.x, p1.y, p2.x, p2.y); -} - -uint -drawstring(Image *dst, Font *font, - Rectangle r, Align align, - char *text, Color col) { - Rectangle tr; - char *buf; - uint x, y, width, height, len; - int shortened; - - shortened = 0; - - len = strlen(text); - buf = emalloc(len+1); - memcpy(buf, text, len+1); - - r.max.y -= font->pad.min.y; - r.min.y += font->pad.max.y; - - height = font->ascent + font->descent; - y = r.min.y + Dy(r) / 2 - height / 2 + font->ascent; - - width = Dx(r) - font->pad.min.x - font->pad.max.x - (font->height & ~1); - - r.min.x += font->pad.min.x; - r.max.x -= font->pad.max.x; - - /* shorten text if necessary */ - tr = ZR; - while(len > 0) { - tr = textextents_l(font, buf, len + min(shortened, 3), nil); - if(Dx(tr) <= width) - break; - while(len > 0 && (buf[--len]&0xC0) == 0x80) - buf[len] = '.'; - buf[len] = '.'; - shortened++; - } - - if(len == 0 || Dx(tr) > width) - goto done; - - /* mark shortened info in the string */ - if(shortened) - len += min(shortened, 3); - - switch (align) { - case East: - x = r.max.x - (tr.max.x + (font->height / 2)); - break; - case Center: - x = r.min.x + (Dx(r) - Dx(tr)) / 2 - tr.min.x; - break; - default: - x = r.min.x + (font->height / 2) - tr.min.x; - break; - } - - setgccol(dst, col); - switch(font->type) { - case FFontSet: - Xutf8DrawString(display, dst->xid, - font->font.set, dst->gc, - x, y, - buf, len); - break; - case FXft: - XftDrawStringUtf8(xftdrawable(dst), xftcolor(col), - font->font.xft, - x, y, (uchar*)buf, len); - break; - case FX11: - XSetFont(display, dst->gc, font->font.x11->fid); - XDrawString(display, dst->xid, dst->gc, - x, y, buf, len); - break; - default: - die("Invalid font type."); - } - -done: - free(buf); - return Dx(tr); -} - -void -copyimage(Image *dst, Rectangle r, Image *src, Point p) { - XCopyArea(display, - src->xid, dst->xid, - dst->gc, - r.min.x, r.min.y, Dx(r), Dy(r), - p.x, p.y); -} - -/* Colors */ -bool -namedcolor(char *name, Color *ret) { - XColor c, c2; - - if(XAllocNamedColor(display, scr.colormap, name, &c, &c2)) { - *ret = (Color) { - c.pixel, { - c.red, - c.green, - c.blue, - 0xffff - }, - }; - return true; - } - return false; -} - -bool -loadcolor(CTuple *c, char *str) { - char buf[24]; - - utflcpy(buf, str, sizeof buf); - memcpy(c->colstr, str, sizeof c->colstr); - - buf[7] = buf[15] = buf[23] = '\0'; - return namedcolor(buf, &c->fg) - && namedcolor(buf+8, &c->bg) - && namedcolor(buf+16, &c->border); -} - -static XftColor* -xftcolor(Color col) { - XftColor *c; - - c = emallocz(sizeof *c); - *c = (XftColor) { - ((col.render.alpha&0xff00) << 24) - | ((col.render.red&0xff00) << 8) - | ((col.render.green&0xff00) << 0) - | ((col.render.blue&0xff00) >> 8), - col.render - }; - return freelater(c); -} - -/* Fonts */ -Font* -loadfont(char *name) { - XFontStruct **xfonts; - char **missing, **font_names; - Biobuf *b; - Font *f; - int n, i; - - missing = nil; - f = emallocz(sizeof *f); - f->name = estrdup(name); - if(!strncmp(f->name, "xft:", 4)) { - f->type = FXft; - - f->font.xft = XftFontOpenXlfd(display, scr.screen, f->name + 4); - if(!f->font.xft) - f->font.xft = XftFontOpenName(display, scr.screen, f->name + 4); - if(!f->font.xft) - goto error; - - f->ascent = f->font.xft->ascent; - f->descent = f->font.xft->descent; - }else { - f->font.set = XCreateFontSet(display, name, &missing, &n, nil); - if(missing) { - if(false) { - b = Bfdopen(dup(2), O_WRONLY); - Bprint(b, "%s: note: missing fontset%s for '%s':", argv0, - (n > 1 ? "s" : ""), name); - for(i = 0; i < n; i++) - Bprint(b, "%s %s", (i ? "," : ""), missing[i]); - Bprint(b, "\n"); - Bterm(b); - } - freestringlist(missing); - } - - if(f->font.set) { - f->type = FFontSet; - XFontsOfFontSet(f->font.set, &xfonts, &font_names); - f->ascent = xfonts[0]->ascent; - f->descent = xfonts[0]->descent; - }else { - f->type = FX11; - f->font.x11 = XLoadQueryFont(display, name); - if(!f->font.x11) - goto error; - - f->ascent = f->font.x11->ascent; - f->descent = f->font.x11->descent; - } - } - f->height = f->ascent + f->descent; - return f; - -error: - fprint(2, "%s: cannot load font: %s\n", argv0, name); - f->type = 0; - freefont(f); - return nil; -} - -void -freefont(Font *f) { - switch(f->type) { - case FFontSet: - XFreeFontSet(display, f->font.set); - break; - case FXft: - XftFontClose(display, f->font.xft); - break; - case FX11: - XFreeFont(display, f->font.x11); - break; - default: - break; - } - free(f->name); - free(f); -} - -Rectangle -textextents_l(Font *font, char *text, uint len, int *offset) { - Rectangle rect; - XRectangle r; - XGlyphInfo i; - int unused; - - if(!offset) - offset = &unused; - - switch(font->type) { - case FFontSet: - *offset = Xutf8TextExtents(font->font.set, text, len, &r, nil); - return Rect(r.x, -r.y - r.height, r.x + r.width, -r.y); - case FXft: - XftTextExtentsUtf8(display, font->font.xft, (uchar*)text, len, &i); - *offset = i.xOff; - return Rect(-i.x, i.y - i.height, -i.x + i.width, i.y); - case FX11: - rect = ZR; - rect.max.x = XTextWidth(font->font.x11, text, len); - rect.max.y = font->ascent; - *offset = rect.max.x; - return rect; - default: - die("Invalid font type"); - return ZR; /* shut up ken */ - } -} - -uint -textwidth_l(Font *font, char *text, uint len) { - Rectangle r; - - r = textextents_l(font, text, len, nil); - return Dx(r); -} - -uint -textwidth(Font *font, char *text) { - return textwidth_l(font, text, strlen(text)); -} - -uint -labelh(Font *font) { - return max(font->height + font->descent + font->pad.min.y + font->pad.max.y, 1); -} - -/* Misc */ -Atom -xatom(char *name) { - void **e; - - e = hash_get(&atommap, name, true); - if(*e == nil) - *e = (void*)XInternAtom(display, name, false); - return (Atom)*e; -} - -void -sendmessage(Window *w, char *name, long l0, long l1, long l2, long l3, long l4) { - XClientMessageEvent e; - - e.type = ClientMessage; - e.window = w->xid; - e.message_type = xatom(name); - e.format = 32; - e.data.l[0] = l0; - e.data.l[1] = l1; - e.data.l[2] = l2; - e.data.l[3] = l3; - e.data.l[4] = l4; - sendevent(w, false, NoEventMask, (XEvent*)&e); -} - -void -sendevent(Window *w, bool propegate, long mask, XEvent *e) { - XSendEvent(display, w->xid, propegate, mask, e); -} - -KeyCode -keycode(char *name) { - return XKeysymToKeycode(display, XStringToKeysym(name)); -} - -typedef struct KMask KMask; - -static struct KMask { - int mask; - const char* name; -} masks[] = { - {ShiftMask, "Shift"}, - {ControlMask, "Control"}, - {Mod1Mask, "Mod1"}, - {Mod2Mask, "Mod2"}, - {Mod3Mask, "Mod3"}, - {Mod4Mask, "Mod4"}, - {Mod5Mask, "Mod5"}, - {0,} -}; - -bool -parsekey(char *str, int *mask, char **key) { - static char *keys[16]; - KMask *m; - int i, nkeys; - - *mask = 0; - nkeys = tokenize(keys, nelem(keys), str, '-'); - for(i=0; i < nkeys; i++) { - for(m=masks; m->mask; m++) - if(!strcasecmp(m->name, keys[i])) { - *mask |= m->mask; - goto next; - } - break; - next: continue; - } - if(key) { - if(nkeys) - *key = keys[i]; - return i == nkeys - 1; - } - else - return i == nkeys; -} - -void -sync(void) { - XSync(display, false); -} - -/* Properties */ -void -delproperty(Window *w, char *prop) { - XDeleteProperty(display, w->xid, xatom(prop)); -} - -void -changeproperty(Window *w, char *prop, char *type, - int width, uchar data[], int n) { - XChangeProperty(display, w->xid, xatom(prop), xatom(type), width, - PropModeReplace, data, n); -} - -void -changeprop_string(Window *w, char *prop, char *string) { - changeprop_char(w, prop, "UTF8_STRING", string, strlen(string)); -} - -void -changeprop_char(Window *w, char *prop, char *type, char data[], int len) { - changeproperty(w, prop, type, 8, (uchar*)data, len); -} - -void -changeprop_short(Window *w, char *prop, char *type, short data[], int len) { - changeproperty(w, prop, type, 16, (uchar*)data, len); -} - -void -changeprop_long(Window *w, char *prop, char *type, long data[], int len) { - changeproperty(w, prop, type, 32, (uchar*)data, len); -} - -void -changeprop_ulong(Window *w, char *prop, char *type, ulong data[], int len) { - changeproperty(w, prop, type, 32, (uchar*)data, len); -} - -void -changeprop_textlist(Window *w, char *prop, char *type, char *data[]) { - char **p, *s, *t; - int len, n; - - len = 0; - for(p=data; *p; p++) - len += strlen(*p) + 1; - s = emalloc(len); - t = s; - for(p=data; *p; p++) { - n = strlen(*p) + 1; - memcpy(t, *p, n); - t += n; - } - changeprop_char(w, prop, type, s, len); - free(s); -} - -void -freestringlist(char *list[]) { - XFreeStringList(list); -} - -static ulong -getprop(Window *w, char *prop, char *type, Atom *actual, int *format, - ulong offset, uchar **ret, ulong length) { - Atom typea; - ulong n, extra; - int status; - - typea = (type ? xatom(type) : 0L); - - status = XGetWindowProperty(display, w->xid, - xatom(prop), offset, length, false /* delete */, - typea, actual, format, &n, &extra, ret); - - if(status != Success) { - *ret = nil; - return 0; - } - if(n == 0) { - free(*ret); - *ret = nil; - } - return n; -} - -ulong -getproperty(Window *w, char *prop, char *type, Atom *actual, - ulong offset, uchar **ret, ulong length) { - int format; - - return getprop(w, prop, type, actual, &format, offset, ret, length); -} - -ulong -getprop_long(Window *w, char *prop, char *type, - ulong offset, long **ret, ulong length) { - Atom actual; - ulong n; - int format; - - n = getprop(w, prop, type, &actual, &format, offset, (uchar**)ret, length); - if(n == 0 || format == 32 && xatom(type) == actual) - return n; - free(*ret); - *ret = 0; - return 0; -} - -ulong -getprop_ulong(Window *w, char *prop, char *type, - ulong offset, ulong **ret, ulong length) { - return getprop_long(w, prop, type, offset, (long**)ret, length); -} - -char** -strlistdup(char *list[]) { - char **p; - char *q; - int i, m, n; - - n = 0; - m = 0; - for(p=list; *p; p++, n++) - m += strlen(*p) + 1; - - p = malloc((n+1) * sizeof(*p) + m); - q = (char*)&p[n+1]; - - for(i=0; i < n; i++) { - p[i] = q; - m = strlen(list[i]) + 1; - memcpy(q, list[i], m); - q += m; - } - p[n] = nil; - return p; -} - -int -getprop_textlist(Window *w, char *name, char **ret[]) { - XTextProperty prop; - char **list; - int n; - - *ret = nil; - n = 0; - - XGetTextProperty(display, w->xid, &prop, xatom(name)); - if(prop.nitems > 0) { - if(Xutf8TextPropertyToTextList(display, &prop, &list, &n) == Success) - *ret = list; - XFree(prop.value); - } - return n; -} - -char* -getprop_string(Window *w, char *name) { - char **list, *str; - int n; - - str = nil; - - n = getprop_textlist(w, name, &list); - if(n > 0) - str = estrdup(*list); - freestringlist(list); - - return str; -} - -Rectangle -getwinrect(Window *w) { - XWindowAttributes wa; - Point p; - - if(!XGetWindowAttributes(display, w->xid, &wa)) - return ZR; - p = translate(w, &scr.root, ZP); - return rectaddpt(Rect(0, 0, wa.width, wa.height), p); -} - -void -setfocus(Window *w, int mode) { - XSetInputFocus(display, w->xid, mode, CurrentTime); -} - -XWindow -getfocus(void) { - XWindow ret; - int revert; - - XGetInputFocus(display, &ret, &revert); - return ret; -} - -/* Mouse */ -Point -querypointer(Window *w) { - XWindow win; - Point pt; - uint ui; - int i; - - XQueryPointer(display, w->xid, &win, &win, &i, &i, &pt.x, &pt.y, &ui); - return pt; -} - -int -pointerscreen(void) { - XWindow win; - Point pt; - uint ui; - int i; - - return XQueryPointer(display, scr.root.xid, &win, &win, &i, &i, - &pt.x, &pt.y, &ui); -} - -void -warppointer(Point pt) { - /* Nasty kludge for xephyr, xnest. */ - static int havereal = -1; - static char* real; - - if(havereal == -1) { - real = getenv("REALDISPLAY"); - havereal = real != nil; - } - if(havereal) - system(sxprint("DISPLAY=%s wiwarp %d %d", real, pt.x, pt.y)); - - XWarpPointer(display, - /* src, dest w */ None, scr.root.xid, - /* src_rect */ 0, 0, 0, 0, - /* target */ pt.x, pt.y); -} - -Point -translate(Window *src, Window *dst, Point sp) { - Point pt; - XWindow w; - - XTranslateCoordinates(display, src->xid, dst->xid, sp.x, sp.y, - &pt.x, &pt.y, &w); - return pt; -} - -int -grabpointer(Window *w, Window *confine, Cursor cur, int mask) { - XWindow cw; - - cw = None; - if(confine) - cw = confine->xid; - return XGrabPointer(display, w->xid, false /* owner events */, mask, - GrabModeAsync, GrabModeAsync, cw, cur, CurrentTime - ) == GrabSuccess; -} - -void -ungrabpointer(void) { - XUngrabPointer(display, CurrentTime); -} - -int -grabkeyboard(Window *w) { - - return XGrabKeyboard(display, w->xid, true /* owner events */, - GrabModeAsync, GrabModeAsync, CurrentTime - ) == GrabSuccess; -} - -void -ungrabkeyboard(void) { - XUngrabKeyboard(display, CurrentTime); -} - -/* Insanity */ -void -sethints(Window *w) { - XSizeHints xs; - XWMHints *wmh; - WinHints *h; - Point p; - long size; - - if(w->hints == nil) - w->hints = emalloc(sizeof *h); - - h = w->hints; - memset(h, 0, sizeof *h); - - h->max = Pt(INT_MAX, INT_MAX); - h->inc = Pt(1,1); - - wmh = XGetWMHints(display, w->xid); - if(wmh) { - if(wmh->flags & WindowGroupHint) - h->group = wmh->window_group; - free(wmh); - } - - if(!XGetWMNormalHints(display, w->xid, &xs, &size)) - return; - - if(xs.flags & PMinSize) { - h->min.x = xs.min_width; - h->min.y = xs.min_height; - } - if(xs.flags & PMaxSize) { - h->max.x = xs.max_width; - h->max.y = xs.max_height; - } - - /* Goddamn buggy clients. */ - if(h->max.x < h->min.x) - h->max.x = h->min.x; - if(h->max.y < h->min.y) - h->max.y = h->min.y; - - h->base = h->min; - if(xs.flags & PBaseSize) { - p.x = xs.base_width; - p.y = xs.base_height; - h->base = p; - h->baspect = p; - } - - if(xs.flags & PResizeInc) { - h->inc.x = max(xs.width_inc, 1); - h->inc.y = max(xs.height_inc, 1); - } - - if(xs.flags & PAspect) { - h->aspect.min.x = xs.min_aspect.x; - h->aspect.min.y = xs.min_aspect.y; - h->aspect.max.x = xs.max_aspect.x; - h->aspect.max.y = xs.max_aspect.y; - } - - h->position = (xs.flags & (USPosition|PPosition)) != 0; - - if(!(xs.flags & PWinGravity)) - xs.win_gravity = NorthWestGravity; - p = ZP; - switch (xs.win_gravity) { - case EastGravity: - case CenterGravity: - case WestGravity: - p.y = 1; - break; - case SouthEastGravity: - case SouthGravity: - case SouthWestGravity: - p.y = 2; - break; - } - switch (xs.win_gravity) { - case NorthGravity: - case CenterGravity: - case SouthGravity: - p.x = 1; - break; - case NorthEastGravity: - case EastGravity: - case SouthEastGravity: - p.x = 2; - break; - } - h->grav = p; - h->gravstatic = (xs.win_gravity == StaticGravity); -} - -Rectangle -sizehint(WinHints *h, Rectangle r) { - Point p, aspect, origin; - - if(h == nil) - return r; - - origin = r.min; - r = rectsubpt(r, origin); - - /* Min/max */ - r.max.x = max(r.max.x, h->min.x); - r.max.y = max(r.max.y, h->min.y); - r.max.x = min(r.max.x, h->max.x); - r.max.y = min(r.max.y, h->max.y); - - /* Increment */ - p = subpt(r.max, h->base); - r.max.x -= p.x % h->inc.x; - r.max.y -= p.y % h->inc.y; - - /* Aspect */ - p = subpt(r.max, h->baspect); - p.y = max(p.y, 1); - - aspect = h->aspect.min; - if(p.x * aspect.y / p.y < aspect.x) - r.max.y = h->baspect.y - + p.x * aspect.y / aspect.x; - - aspect = h->aspect.max; - if(p.x * aspect.y / p.y > aspect.x) - r.max.x = h->baspect.x - + p.y * aspect.x / aspect.y; - - return rectaddpt(r, origin); -} - -Rectangle -gravitate(Rectangle rc, Rectangle rf, Point grav) { - Point d; - - /* Get delta between frame and client rectangles */ - d = subpt(subpt(rf.max, rf.min), - subpt(rc.max, rc.min)); - - /* Divide by 2 and apply gravity */ - d = divpt(d, Pt(2, 2)); - d = mulpt(d, grav); - - return rectsubpt(rc, d); -} - diff --git a/cmd/wmii9menu.c b/cmd/wmii9menu.c index 02049f36..16a8d747 100644 --- a/cmd/wmii9menu.c +++ b/cmd/wmii9menu.c @@ -44,9 +44,10 @@ #include #include #include -#include -#include -#include + +#include +#include +#include char version[] = "wmii9menu-" VERSION " ©2010 Kris Maglione, ©1994 David Hogan, Arnold Robbins"; @@ -81,10 +82,6 @@ void warpmouse(int, int); void memory(void); int args(void); -ErrorCode ignored_xerrors[] = { - { 0, } -}; - /* xext.c */ void xext_init(void); Rectangle* xinerama_screens(int*); diff --git a/cmd/wmiir.c b/cmd/wmiir.c index 1801df87..4dce494b 100644 --- a/cmd/wmiir.c +++ b/cmd/wmiir.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include static IxpClient *client; diff --git a/doc/wmii.tex b/doc/wmii.tex index 3159d763..5c13f045 100644 --- a/doc/wmii.tex +++ b/doc/wmii.tex @@ -45,6 +45,7 @@ \DefineShortVerb{\|} \makeatletter +\let\idx@@heading\chapter \let\:=: \catcode`\:=\active \def:{\@ifnextchar:{\coloncoloneq}{\:}} diff --git a/include/debug.h b/include/debug.h new file mode 100644 index 00000000..03be1475 --- /dev/null +++ b/include/debug.h @@ -0,0 +1,13 @@ +#include + +#define Debug(x) if(((debugflag|debugfile)&(x)) && setdebug(x)) +#define Dprint(x, ...) BLOCK( if((debugflag|debugfile)&(x)) debug(x, __VA_ARGS__) ) + +void debug(int, const char*, ...); +void dprint(const char*, ...); +void dwrite(int, void*, int, bool); +bool setdebug(int); +void vdebug(int, const char*, va_list); + +int debugflag; +int debugfile; diff --git a/include/clientutil.h b/include/stuff/clientutil.h similarity index 56% rename from include/clientutil.h rename to include/stuff/clientutil.h index eeba43c3..4d779ad7 100644 --- a/include/clientutil.h +++ b/include/stuff/clientutil.h @@ -1,3 +1,7 @@ +/* Copyright ©2009-2010 Kris Maglione + * See LICENSE file for license details. + */ + #ifndef CLIENTEXTERN # define CLIENTEXTERN extern #endif diff --git a/include/stuff/geom.h b/include/stuff/geom.h new file mode 100644 index 00000000..b3abf9cd --- /dev/null +++ b/include/stuff/geom.h @@ -0,0 +1,54 @@ +#pragma once + +#include + +typedef struct Point Point; +typedef struct Rectangle Rectangle; + +struct Point { + int x, y; +}; + +struct Rectangle { + Point min, max; +}; + +enum Align { + North = 0x01, + East = 0x02, + South = 0x04, + West = 0x08, + NEast = North | East, + NWest = North | West, + SEast = South | East, + SWest = South | West, + Center = NEast | SWest, +}; + +typedef enum Align Align; + +#define Dx(r) ((r).max.x - (r).min.x) +#define Dy(r) ((r).max.y - (r).min.y) +#define Pt(x, y) ((Point){(x), (y)}) +#define Rpt(p, q) ((Rectangle){p, q}) +#define Rect(x0, y0, x1, y1) ((Rectangle){Pt(x0, y0), Pt(x1, y1)}) + +Point addpt(Point, Point); +Point divpt(Point, Point); +int eqpt(Point, Point); +int eqrect(Rectangle, Rectangle); +Rectangle gravitate(Rectangle dst, Rectangle src, Point grav); +Rectangle insetrect(Rectangle, int); +Point mulpt(Point p, Point q); +Rectangle rectaddpt(Rectangle, Point); +Rectangle rectsetorigin(Rectangle, Point); +Rectangle rectsubpt(Rectangle, Point); +Point subpt(Point, Point); + +Align get_sticky(Rectangle src, Rectangle dst); +Align quadrant(Rectangle, Point); +bool rect_contains_p(Rectangle, Rectangle); +bool rect_haspoint_p(Point, Rectangle); +bool rect_intersect_p(Rectangle, Rectangle); +Rectangle rect_intersection(Rectangle, Rectangle); + diff --git a/include/stuff/util.h b/include/stuff/util.h new file mode 100644 index 00000000..d6d002d3 --- /dev/null +++ b/include/stuff/util.h @@ -0,0 +1,150 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ + +#include + +#include + +#include + +/* Types */ + +typedef struct Regex Regex; + +struct Regex { + char* regex; + Reprog* regc; +}; + +enum { + CLeft = 1<<0, + CCenter = 1<<1, + CRight = 1<<2, +}; +enum DebugOpt { + D9p = 1<<0, + DDnd = 1<<1, + DEvent = 1<<2, + DEwmh = 1<<3, + DFocus = 1<<4, + DGeneric= 1<<5, + DStack = 1<<6, + NDebugOpt = 7, +}; +enum { + GInvert = 1<<0, +}; + +#ifdef VARARGCK +# pragma varargck argpos _die 3 +# pragma varargck argpos fatal 1 +# pragma varargck argpos sxprint 1 +#endif + +#define strlcat stuff_strlcat +#define strcasestr stuff_strcasestr + +void _die(char*, int, char*, ...); +void backtrace(char*); +void closeexec(int); +char** comm(int, char**, char**); +int doublefork(void); +void* emalloc(uint); +void* emallocz(uint); +void* erealloc(void*, uint); +char* estrdup(const char*); +char* estrndup(const char*, uint); +void fatal(const char*, ...); +void* freelater(void*); +int getbase(const char**, long*); +bool getint(const char*, int*); +bool getlong(const char*, long*); +bool getulong(const char*, ulong*); +void grep(char**, Reprog*, int); +char* join(char**, char*); +int max(int, int); +int min(int, int); +char* pathsearch(const char*, const char*, bool); +void refree(Regex*); +void reinit(Regex*, char*); +int spawn3(int[3], const char*, char*[]); +int spawn3l(int[3], const char*, ...); +uint stokenize(char**, uint, char*, char*); +char* strcasestr(const char*, const char*); +char* strend(char*, int); +uint strlcat(char*, const char*, uint); +int strlcatprint(char*, int, const char*, ...); +char* sxprint(const char*, ...); +uint tokenize(char**, uint, char*, char); +void uniq(char**); +int unquote(char*, char*[], int); +int utflcpy(char*, const char*, int); +char* vsxprint(const char*, va_list); + +extern char buffer[8092]; +extern char* _buffer; +extern char* const _buf_end; + +#define bufclear() \ + BLOCK( _buffer = buffer; _buffer[0] = '\0' ) +#define bufprint(...) \ + _buffer = seprint(_buffer, _buf_end, __VA_ARGS__) + +#define die(...) \ + _die(__FILE__, __LINE__, __VA_ARGS__) + +char *argv0; +#undef ARGBEGIN +#undef ARGEND +#undef ARGF +#undef EARGF +#define ARGBEGIN \ + int _argtmp=0, _inargv; char *_argv=nil; \ + if(!argv0) argv0=*argv; argv++, argc--; \ + _inargv=1; USED(_inargv); \ + while(argc && argv[0][0] == '-') { \ + _argv=&argv[0][1]; argv++; argc--; \ + if(_argv[0] == '-' && _argv[1] == '\0') \ + break; \ + while(*_argv) switch(*_argv++) +#define ARGEND }_inargv=0;USED(_argtmp, _argv, _inargv) + +#define EARGF(f) ((_inargv && *_argv) ? \ + (_argtmp=strlen(_argv), _argv+=_argtmp, _argv-_argtmp) \ + : ((argc > 0) ? \ + (--argc, ++argv, _used(argc), *(argv-1)) \ + : ((f), (char*)0))) +#define ARGF() EARGF(_used(0)) + +/* map.c */ +typedef struct Map Map; +typedef struct MapEnt MapEnt; + +struct Map { + MapEnt**bucket; + uint nhash; +}; + +void** hash_get(Map*, const char*, bool create); +void* hash_rm(Map*, const char*); +void** map_get(Map*, ulong, bool create); +void* map_rm(Map*, ulong); + +/* Yuck. */ +#define VECTOR(type, nam, c) \ +typedef struct Vector_##nam Vector_##nam; \ +struct Vector_##nam { \ + type* ary; \ + long n; \ + long size; \ +}; \ +void vector_##c##free(Vector_##nam*); \ +void vector_##c##init(Vector_##nam*); \ +void vector_##c##push(Vector_##nam*, type); \ + +VECTOR(long, long, l) +VECTOR(Rectangle, rect, r) +VECTOR(void*, ptr, p) +#undef VECTOR + diff --git a/include/stuff/x.h b/include/stuff/x.h new file mode 100644 index 00000000..2786ebd2 --- /dev/null +++ b/include/stuff/x.h @@ -0,0 +1,48 @@ +#include +#include +#include + +extern Visual* render_visual; + +extern void init_screens(void); + +/* printevent.c */ +int fmtevent(Fmt*); + +/* xext.c */ +void randr_event(XEvent*); +bool render_argb_p(Visual*); +void xext_event(XEvent*); +void xext_init(void); +Rectangle* xinerama_screens(int*); + +void event_check(void); +void event_dispatch(XEvent*); +uint event_flush(long, bool dispatch); +uint event_flushenter(void); +void event_loop(void); +void event_updatextime(void); + +void event_buttonpress(XButtonPressedEvent*); +void event_buttonrelease(XButtonPressedEvent*); +void event_clientmessage(XClientMessageEvent*); +void event_configurenotify(XConfigureEvent*); +void event_configurerequest(XConfigureRequestEvent*); +void event_destroynotify(XDestroyWindowEvent*); +void event_enternotify(XCrossingEvent*); +void event_expose(XExposeEvent*); +void event_focusin(XFocusChangeEvent*); +void event_focusout(XFocusChangeEvent*); +void event_keypress(XKeyEvent*); +void event_leavenotify(XCrossingEvent*); +void event_mapnotify(XMapEvent*); +void event_maprequest(XMapRequestEvent*); +void event_mappingnotify(XMappingEvent*); +void event_motionnotify(XMotionEvent*); +void event_propertynotify(XPropertyEvent*); +void event_unmapnotify(XUnmapEvent*); + +extern long event_xtime; +extern bool event_looprunning; +extern void (*event_debug)(XEvent*); + diff --git a/include/x11.h b/include/stuff/x11.h similarity index 84% rename from include/x11.h rename to include/stuff/x11.h index 7dea1aa3..a9305178 100644 --- a/include/x11.h +++ b/include/stuff/x11.h @@ -4,6 +4,7 @@ #define Window XWindow #define Font XFont #define Screen XScreen +#include #include #include #include @@ -17,18 +18,6 @@ #undef Font #undef Screen -enum Align { - North = 0x01, - East = 0x02, - South = 0x04, - West = 0x08, - NEast = North | East, - NWest = North | West, - SEast = South | East, - SWest = South | West, - Center = NEast | SWest, -}; - enum FontType { FX11 = 1, FFontSet, @@ -40,23 +29,11 @@ enum WindowType { WImage, }; -typedef enum Align Align; typedef enum FontType FontType; typedef enum WindowType WindowType; typedef XSetWindowAttributes WinAttr; -typedef struct Point Point; -typedef struct Rectangle Rectangle; - -struct Point { - int x, y; -}; - -struct Rectangle { - Point min, max; -}; - typedef struct Color Color; typedef struct CTuple CTuple; typedef struct ErrorCode ErrorCode; @@ -189,24 +166,14 @@ extern const Point ZP; extern const Rectangle ZR; extern Window* pointerwin; -Point Pt(int x, int y); -Rectangle Rect(int x0, int y0, int x1, int y1); -Rectangle Rpt(Point min, Point max); - XRectangle XRect(Rectangle r); -#define Dx(r) ((r).max.x - (r).min.x) -#define Dy(r) ((r).max.y - (r).min.y) -#define Pt(x, y) ((Point){(x), (y)}) -#define Rpt(p, q) ((Rectangle){p, q}) -#define Rect(x0, y0, x1, y1) ((Rectangle){Pt(x0, y0), Pt(x1, y1)}) #define changeprop(w, prop, type, data, n) \ changeproperty(w, prop, type, \ ((sizeof(*(data)) == 8 ? 4 : sizeof(*(data))) * 8), \ (uchar*)(data), n) /* x11.c */ -Point addpt(Point, Point); Image* allocimage(int w, int h, int depth); void border(Image *dst, Rectangle, int w, Color); void changeprop_char(Window*, char*, char*, char[], int); @@ -221,12 +188,9 @@ Window* createwindow(Window*, Rectangle, int depth, uint class, WinAttr*, int va Window* createwindow_visual(Window*, Rectangle, int depth, Visual*, uint class, WinAttr*, int); void delproperty(Window*, char*); void destroywindow(Window*); -Point divpt(Point, Point); void drawline(Image*, Point, Point, int cap, int w, Color); void drawpoly(Image*, Point*, int, int cap, int w, Color); uint drawstring(Image*, Font*, Rectangle, Align, char*, Color); -int eqpt(Point, Point); -int eqrect(Rectangle, Rectangle); void fill(Image*, Rectangle, Color); void fillpoly(Image*, Point*, int, Color); Window* findwin(XWindow); @@ -249,7 +213,6 @@ Font* loadfont(char*); void lowerwin(Window*); int mapwin(Window*); void movewin(Window*, Point); -Point mulpt(Point p, Point q); bool namedcolor(char *name, Color*); bool parsekey(char*, int*, char**); int pointerscreen(void); @@ -258,14 +221,13 @@ void raisewin(Window*); void reparentwindow(Window*, Window*, Point); void reshapewin(Window*, Rectangle); void selectinput(Window*, long); -void sendevent(Window*, bool propegate, long mask, XEvent*); +void sendevent(Window*, bool propagate, long mask, XEvent*); void setborder(Window*, int, Color); void setfocus(Window*, int mode); void sethints(Window*); void setshapemask(Window *dst, Image *src, Point); void setwinattr(Window*, WinAttr*, int valmask); char** strlistdup(char**); -Point subpt(Point, Point); void sync(void); uint textwidth(Font*, char*); uint textwidth_l(Font*, char*, uint len); @@ -282,11 +244,6 @@ Atom xatom(char*); void sendmessage(Window*, char*, long, long, long, long, long); XRectangle XRect(Rectangle); Rectangle getwinrect(Window*); -Rectangle gravitate(Rectangle dst, Rectangle src, Point grav); -Rectangle insetrect(Rectangle, int); -Rectangle rectaddpt(Rectangle, Point); -Rectangle rectsetorigin(Rectangle, Point); -Rectangle rectsubpt(Rectangle, Point); Handlers* sethandler(Window*, Handlers*); Rectangle sizehint(WinHints*, Rectangle); diff --git a/include/util.h b/include/util.h deleted file mode 100644 index 6cfd6044..00000000 --- a/include/util.h +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright ©2007-2010 Kris Maglione - * See LICENSE file for license details. - */ -#define nil ((void*)0) -#define nelem(ary) (sizeof(ary) / sizeof(*ary)) - -/* Types */ -#undef uchar -#undef ushort -#undef uint -#undef ulong -#undef uvlong -#undef vlong -#define uchar _x_uchar -#define ushort _x_ushort -#define uint _x_uint -#define ulong _x_ulong -#define uvlong _x_uvlong -#define vlong _x_vlong - -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; -typedef unsigned long long uvlong; -typedef long long vlong; - -#ifdef VARARGCK -# pragma varargck argpos _die 3 -# pragma varargck argpos fatal 1 -# pragma varargck argpos sxprint 1 -#endif - -#define strlcat wmii_strlcat -#define strcasestr wmii_strcasestr -/* util.c */ -void _die(char*, int, char*, ...); -void* emalloc(uint); -void* emallocz(uint); -void* erealloc(void*, uint); -char* estrdup(const char*); -char* estrndup(const char*, uint); -void fatal(const char*, ...); -void* freelater(void*); -int max(int, int); -int min(int, int); -uint strlcat(char*, const char*, uint); -char* strcasestr(const char*, const char*); -char* sxprint(const char*, ...); -uint tokenize(char**, uint, char*, char); -uint stokenize(char**, uint, char*, char*); -int utflcpy(char*, const char*, int); -char* vsxprint(const char*, va_list); - -#define die(...) \ - _die(__FILE__, __LINE__, __VA_ARGS__) - -char *argv0; -#undef ARGBEGIN -#undef ARGEND -#undef ARGF -#undef EARGF -#define ARGBEGIN \ - int _argtmp=0, _inargv; char *_argv=nil; \ - if(!argv0) argv0=*argv; argv++, argc--; \ - _inargv=1; USED(_inargv); \ - while(argc && argv[0][0] == '-') { \ - _argv=&argv[0][1]; argv++; argc--; \ - if(_argv[0] == '-' && _argv[1] == '\0') \ - break; \ - while(*_argv) switch(*_argv++) -#define ARGEND }_inargv=0;USED(_argtmp, _argv, _inargv) - -#define EARGF(f) ((_inargv && *_argv) ? \ - (_argtmp=strlen(_argv), _argv+=_argtmp, _argv-_argtmp) \ - : ((argc > 0) ? \ - (--argc, ++argv, _used(argc), *(argv-1)) \ - : ((f), (char*)0))) -#define ARGF() EARGF(_used(0)) - -static inline void -_used(long a, ...) { - if(a){} -} -#ifndef KENC -# undef USED -# undef SET -# define USED(...) _used((long)__VA_ARGS__) -# define SET(x) (x = 0) -/* # define SET(x) USED(&x) GCC 4 is 'too smart' for this. */ -#endif diff --git a/libstuff/Makefile b/libstuff/Makefile new file mode 100644 index 00000000..5ba16b2b --- /dev/null +++ b/libstuff/Makefile @@ -0,0 +1,171 @@ +ROOT= .. +include ${ROOT}/mk/hdr.mk + +TARG=libstuff + +PACKAGES += $(X11PACKAGES) xext xrandr xrender xinerama + +OBJ=\ + buffer \ + clientutil \ + event/buttonpress \ + event/buttonrelease \ + event/clientmessage \ + event/configurenotify \ + event/configurerequest \ + event/destroynotify \ + event/enternotify \ + event/event \ + event/expose \ + event/focusin \ + event/focusout \ + event/keypress \ + event/leavenotify \ + event/mapnotify \ + event/maprequest \ + event/mappingnotify \ + event/motionnotify \ + event/propertynotify \ + event/unmapnotify \ + event/xtime \ + geom/get_sticky \ + geom/quadrant \ + geom/rect_contains_p \ + geom/rect_haspoint_p \ + geom/rect_intersect_p \ + geom/rect_intersection \ + init_screens \ + map \ + printevent \ + util/_die \ + util/backtrace \ + util/closeexec \ + util/comm \ + util/doublefork \ + util/emalloc \ + util/emallocz \ + util/erealloc \ + util/estrdup \ + util/estrndup \ + util/fatal \ + util/freelater \ + util/getbase \ + util/getint \ + util/getlong \ + util/getulong \ + util/grep \ + util/join \ + util/max \ + util/mfatal \ + util/min \ + util/pathsearch \ + util/refree \ + util/reinit \ + util/spawn3 \ + util/spawn3l \ + util/stokenize \ + util/strcasestr \ + util/strend \ + util/strlcat \ + util/strlcatprint \ + util/sxprint \ + util/tokenize \ + util/uniq \ + util/unquote \ + util/utflcpy \ + util/vector \ + util/vsxprint \ + x11/convpts \ + x11/errors \ + x11/ignored_xerrors \ + x11/freestringlist \ + x11/initdisplay \ + x11/sendevent \ + x11/sendmessage \ + x11/setgccol \ + x11/sync \ + x11/x11 \ + x11/xatom \ + x11/colors/loadcolor \ + x11/colors/namedcolor \ + x11/colors/xftcolor \ + x11/drawing/border \ + x11/drawing/drawline \ + x11/drawing/drawpoly \ + x11/drawing/drawstring \ + x11/drawing/fill \ + x11/drawing/fillpoly \ + x11/focus/getfocus \ + x11/focus/setfocus \ + x11/geometry/XRect \ + x11/geometry/addpt \ + x11/geometry/divpt \ + x11/geometry/eqpt \ + x11/geometry/eqrect \ + x11/geometry/insetrect \ + x11/geometry/mulpt \ + x11/geometry/rectaddpt \ + x11/geometry/rectsetorigin \ + x11/geometry/rectsubpt \ + x11/geometry/subpt \ + x11/images/allocimage \ + x11/images/copyimage \ + x11/images/freeimage \ + x11/images/xftdrawable \ + x11/insanity/gravitate \ + x11/insanity/sethints \ + x11/insanity/sizehint \ + x11/keyboard/grabkeyboard \ + x11/keyboard/ungrabkeyboard \ + x11/keys/keycode \ + x11/keys/parsekey \ + x11/mouse/grabpointer \ + x11/mouse/pointerscreen \ + x11/mouse/querypointer \ + x11/mouse/translate \ + x11/mouse/ungrabpointer \ + x11/mouse/warppointer \ + x11/properties/changeprop_char \ + x11/properties/changeprop_long \ + x11/properties/changeprop_short \ + x11/properties/changeprop_string \ + x11/properties/changeprop_textlist \ + x11/properties/changeprop_ulong \ + x11/properties/changeproperty \ + x11/properties/delproperty \ + x11/properties/getprop \ + x11/properties/getprop_long \ + x11/properties/getprop_string \ + x11/properties/getprop_textlist \ + x11/properties/getprop_ulong \ + x11/properties/getproperty \ + x11/properties/strlistdup \ + x11/shape/setshapemask \ + x11/text/freefont \ + x11/text/labelh \ + x11/text/loadfont \ + x11/text/textextents_l \ + x11/text/textwidth \ + x11/text/textwidth_l \ + x11/windows/configwin \ + x11/windows/createwindow \ + x11/windows/createwindow_visual \ + x11/windows/destroywindow \ + x11/windows/findwin \ + x11/windows/getwinrect \ + x11/windows/lowerwin \ + x11/windows/mapwin \ + x11/windows/movewin \ + x11/windows/raisewin \ + x11/windows/reparentwindow \ + x11/windows/reshapewin \ + x11/windows/selectinput \ + x11/windows/setborder \ + x11/windows/sethandler \ + x11/windows/setwinattr \ + x11/windows/unmapwin \ + x11/windows/window \ + xext + +include ${ROOT}/mk/lib.mk + diff --git a/libstuff/buffer.c b/libstuff/buffer.c new file mode 100644 index 00000000..33dacaaf --- /dev/null +++ b/libstuff/buffer.c @@ -0,0 +1,8 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ + +char buffer[8092]; +char* _buffer; +char* const _buf_end = buffer + sizeof buffer; + diff --git a/cmd/clientutil.c b/libstuff/clientutil.c similarity index 93% rename from cmd/clientutil.c rename to libstuff/clientutil.c index 411fe674..8d7f3006 100644 --- a/cmd/clientutil.c +++ b/libstuff/clientutil.c @@ -3,8 +3,8 @@ #define CLIENTEXTERN #include #include -#include -#include +#include +#include static IxpCFid* ctlfid; static char ctl[1024]; diff --git a/libstuff/event/buttonpress.c b/libstuff/event/buttonpress.c new file mode 100644 index 00000000..d43cd7d7 --- /dev/null +++ b/libstuff/event/buttonpress.c @@ -0,0 +1,14 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_buttonpress(XButtonPressedEvent *ev) { + Window *w; + + if((w = findwin(ev->window))) + handle(w, bdown, ev); + else + XAllowEvents(display, ReplayPointer, ev->time); +} diff --git a/libstuff/event/buttonrelease.c b/libstuff/event/buttonrelease.c new file mode 100644 index 00000000..4848d559 --- /dev/null +++ b/libstuff/event/buttonrelease.c @@ -0,0 +1,12 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_buttonrelease(XButtonPressedEvent *ev) { + Window *w; + + if((w = findwin(ev->window))) + handle(w, bup, ev); +} diff --git a/libstuff/event/clientmessage.c b/libstuff/event/clientmessage.c new file mode 100644 index 00000000..11be5323 --- /dev/null +++ b/libstuff/event/clientmessage.c @@ -0,0 +1,10 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_clientmessage(XClientMessageEvent *ev) { + + USED(ev); +} diff --git a/libstuff/event/configurenotify.c b/libstuff/event/configurenotify.c new file mode 100644 index 00000000..a008a3ff --- /dev/null +++ b/libstuff/event/configurenotify.c @@ -0,0 +1,12 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_configurenotify(XConfigureEvent *ev) { + Window *w; + + if((w = findwin(ev->window))) + handle(w, config, ev); +} diff --git a/libstuff/event/configurerequest.c b/libstuff/event/configurerequest.c new file mode 100644 index 00000000..e080ef79 --- /dev/null +++ b/libstuff/event/configurerequest.c @@ -0,0 +1,24 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_configurerequest(XConfigureRequestEvent *ev) { + XWindowChanges wc; + Window *w; + + if((w = findwin(ev->window))) + handle(w, configreq, ev); + else{ + wc.x = ev->x; + wc.y = ev->y; + wc.width = ev->width; + wc.height = ev->height; + wc.border_width = ev->border_width; + wc.sibling = ev->above; + wc.stack_mode = ev->detail; + XConfigureWindow(display, ev->window, ev->value_mask, &wc); + } +} + diff --git a/libstuff/event/destroynotify.c b/libstuff/event/destroynotify.c new file mode 100644 index 00000000..d89f5bae --- /dev/null +++ b/libstuff/event/destroynotify.c @@ -0,0 +1,12 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_destroynotify(XDestroyWindowEvent *ev) { + Window *w; + + if((w = findwin(ev->window))) + handle(w, destroy, ev); +} diff --git a/libstuff/event/enternotify.c b/libstuff/event/enternotify.c new file mode 100644 index 00000000..d838c7f3 --- /dev/null +++ b/libstuff/event/enternotify.c @@ -0,0 +1,16 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_enternotify(XCrossingEvent *ev) { + Window *w; + + event_xtime = ev->time; + if(ev->mode != NotifyNormal) + return; + + if((w = findwin(ev->window))) + handle(w, enter, ev); +} diff --git a/libstuff/event/event.c b/libstuff/event/event.c new file mode 100644 index 00000000..4e9f941c --- /dev/null +++ b/libstuff/event/event.c @@ -0,0 +1,107 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void (*event_debug)(XEvent*); +long event_xtime; +bool event_looprunning; + +EventHandler event_handler[LASTEvent] = { + [ButtonPress] = (EventHandler)event_buttonpress, + [ButtonRelease] = (EventHandler)event_buttonrelease, + [ClientMessage] = (EventHandler)event_clientmessage, + [ConfigureNotify] = (EventHandler)event_configurenotify, + [ConfigureRequest] = (EventHandler)event_configurerequest, + [DestroyNotify] = (EventHandler)event_destroynotify, + [EnterNotify] = (EventHandler)event_enternotify, + [Expose] = (EventHandler)event_expose, + [FocusIn] = (EventHandler)event_focusin, + [FocusOut] = (EventHandler)event_focusout, + [KeyPress] = (EventHandler)event_keypress, + [LeaveNotify] = (EventHandler)event_leavenotify, + [MapNotify] = (EventHandler)event_mapnotify, + [MapRequest] = (EventHandler)event_maprequest, + [MappingNotify] = (EventHandler)event_mappingnotify, + [MotionNotify] = (EventHandler)event_motionnotify, + [PropertyNotify] = (EventHandler)event_propertynotify, + [UnmapNotify] = (EventHandler)event_unmapnotify, +}; + +void +event_dispatch(XEvent *e) { + if(event_debug) + event_debug(e); + + if(e->type < nelem(event_handler)) { + if(event_handler[e->type]) + event_handler[e->type](e); + }else + xext_event(e); +} + +void +event_check(void) { + XEvent ev; + + while(XPending(display)) { + XNextEvent(display, &ev); + event_dispatch(&ev); + } +} + +void +event_loop(void) { + XEvent ev; + + while(event_looprunning) { + XNextEvent(display, &ev); + event_dispatch(&ev); + } +} + +uint +event_flush(long event_mask, bool dispatch) { + XEvent ev; + uint n = 0; + + while(XCheckMaskEvent(display, event_mask, &ev)) { + if(dispatch) + event_dispatch(&ev); + n++; + } + return n; +} + +static int +findenter(Display *d, XEvent *e, XPointer v) { + long *l; + + USED(d); + l = (long*)v; + if(*l) + return false; + if(e->type == EnterNotify) + return true; + if(e->type == MotionNotify) + (*l)++; + return false; +} + +/* This isn't perfect. If there were motion events in the queue + * before this was called, then it flushes nothing. If we don't + * check for them, we might lose a legitamate enter event. + */ +uint +event_flushenter(void) { + XEvent e; + long l; + int n; + + l = 0; + n = 0; + while(XCheckIfEvent(display, &e, findenter, (void*)&l)) + n++; + return n; +} + diff --git a/libstuff/event/event.h b/libstuff/event/event.h new file mode 100644 index 00000000..6745c9c0 --- /dev/null +++ b/libstuff/event/event.h @@ -0,0 +1,9 @@ +#include + +typedef void (*EventHandler)(XEvent*); + +#define handle(w, fn, ev) \ + BLOCK(if((w)->handler->fn) (w)->handler->fn((w), ev)) + +extern EventHandler event_handler[LASTEvent]; + diff --git a/libstuff/event/expose.c b/libstuff/event/expose.c new file mode 100644 index 00000000..4e098840 --- /dev/null +++ b/libstuff/event/expose.c @@ -0,0 +1,12 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_expose(XExposeEvent *ev) { + Window *w; + + if(ev->count == 0 && (w = findwin(ev->window))) + handle(w, expose, ev); +} diff --git a/libstuff/event/focusin.c b/libstuff/event/focusin.c new file mode 100644 index 00000000..be6c8bf6 --- /dev/null +++ b/libstuff/event/focusin.c @@ -0,0 +1,27 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_focusin(XFocusChangeEvent *ev) { + Window *w; + + /* Yes, we're focusing in on nothing, here. */ + if(ev->detail == NotifyDetailNone) { + /* FIXME: Do something. */ + return; + } + + if(!((ev->detail == NotifyNonlinear) + ||(ev->detail == NotifyNonlinearVirtual) + ||(ev->detail == NotifyVirtual) + ||(ev->detail == NotifyInferior) + ||(ev->detail == NotifyAncestor))) + return; + if((ev->mode == NotifyWhileGrabbed)) + return; + + if((w = findwin(ev->window))) + handle(w, focusin, ev); +} diff --git a/libstuff/event/focusout.c b/libstuff/event/focusout.c new file mode 100644 index 00000000..61d98ed3 --- /dev/null +++ b/libstuff/event/focusout.c @@ -0,0 +1,19 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_focusout(XFocusChangeEvent *ev) { + Window *w; + + if(!((ev->detail == NotifyNonlinear) + ||(ev->detail == NotifyNonlinearVirtual) + ||(ev->detail == NotifyVirtual) + ||(ev->detail == NotifyInferior) + ||(ev->detail == NotifyAncestor))) + return; + + if((w = findwin(ev->window))) + handle(w, focusout, ev); +} diff --git a/libstuff/event/keypress.c b/libstuff/event/keypress.c new file mode 100644 index 00000000..7b1d72b7 --- /dev/null +++ b/libstuff/event/keypress.c @@ -0,0 +1,13 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_keypress(XKeyEvent *ev) { + Window *w; + + event_xtime = ev->time; + if((w = findwin(ev->window))) + handle(w, kdown, ev); +} diff --git a/libstuff/event/leavenotify.c b/libstuff/event/leavenotify.c new file mode 100644 index 00000000..612183ac --- /dev/null +++ b/libstuff/event/leavenotify.c @@ -0,0 +1,13 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_leavenotify(XCrossingEvent *ev) { + Window *w; + + event_xtime = ev->time; + if((w = findwin(ev->window))) + handle(w, leave, ev); +} diff --git a/libstuff/event/mapnotify.c b/libstuff/event/mapnotify.c new file mode 100644 index 00000000..0a51b5d1 --- /dev/null +++ b/libstuff/event/mapnotify.c @@ -0,0 +1,12 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_mapnotify(XMapEvent *ev) { + Window *w; + + if((w = findwin(ev->window))) + handle(w, map, ev); +} diff --git a/libstuff/event/mappingnotify.c b/libstuff/event/mappingnotify.c new file mode 100644 index 00000000..d5ab85c4 --- /dev/null +++ b/libstuff/event/mappingnotify.c @@ -0,0 +1,11 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_mappingnotify(XMappingEvent *ev) { + + /* Why do you need me to tell you this? */ + XRefreshKeyboardMapping(ev); +} diff --git a/libstuff/event/maprequest.c b/libstuff/event/maprequest.c new file mode 100644 index 00000000..c945d3da --- /dev/null +++ b/libstuff/event/maprequest.c @@ -0,0 +1,12 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_maprequest(XMapRequestEvent *ev) { + Window *w; + + if((w = findwin(ev->parent))) + handle(w, mapreq, ev); +} diff --git a/libstuff/event/motionnotify.c b/libstuff/event/motionnotify.c new file mode 100644 index 00000000..df339dfb --- /dev/null +++ b/libstuff/event/motionnotify.c @@ -0,0 +1,13 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_motionnotify(XMotionEvent *ev) { + Window *w; + + event_xtime = ev->time; + if((w = findwin(ev->window))) + handle(w, motion, ev); +} diff --git a/libstuff/event/propertynotify.c b/libstuff/event/propertynotify.c new file mode 100644 index 00000000..08536b5f --- /dev/null +++ b/libstuff/event/propertynotify.c @@ -0,0 +1,13 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_propertynotify(XPropertyEvent *ev) { + Window *w; + + event_xtime = ev->time; + if((w = findwin(ev->window))) + handle(w, property, ev); +} diff --git a/libstuff/event/unmapnotify.c b/libstuff/event/unmapnotify.c new file mode 100644 index 00000000..797de34c --- /dev/null +++ b/libstuff/event/unmapnotify.c @@ -0,0 +1,15 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "event.h" + +void +event_unmapnotify(XUnmapEvent *ev) { + Window *w; + + if((w = findwin(ev->window)) && (ev->event == w->parent->xid)) { + w->mapped = false; + if(w->parent && (ev->send_event || w->unmapped-- == 0)) + handle(w, unmap, ev); + } +} diff --git a/libstuff/event/xtime.c b/libstuff/event/xtime.c new file mode 100644 index 00000000..5f326fd6 --- /dev/null +++ b/libstuff/event/xtime.c @@ -0,0 +1,33 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include + +static int +findtime(Display *d, XEvent *e, XPointer v) { + Window *w; + + w = (Window*)v; + if(e->type == PropertyNotify && e->xproperty.window == w->xid) { + event_xtime = e->xproperty.time; + return true; + } + return false; +} + +void +event_updatextime(void) { + Window *w; + WinAttr wa; + XEvent e; + long l; + + w = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, InputOnly, &wa, 0); + + XSelectInput(display, w->xid, PropertyChangeMask); + changeprop_long(w, "ATOM", "ATOM", &l, 0); + XIfEvent(display, &e, findtime, (void*)w); + + destroywindow(w); +} + diff --git a/libstuff/geom/get_sticky.c b/libstuff/geom/get_sticky.c new file mode 100644 index 00000000..7d2fd403 --- /dev/null +++ b/libstuff/geom/get_sticky.c @@ -0,0 +1,24 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include + +Align +get_sticky(Rectangle src, Rectangle dst) { + Align corner; + + corner = 0; + if(src.min.x != dst.min.x + && src.max.x == dst.max.x) + corner |= East; + else + corner |= West; + + if(src.min.y != dst.min.y + && src.max.y == dst.max.y) + corner |= South; + else + corner |= North; + + return corner; +} diff --git a/libstuff/geom/quadrant.c b/libstuff/geom/quadrant.c new file mode 100644 index 00000000..82a86480 --- /dev/null +++ b/libstuff/geom/quadrant.c @@ -0,0 +1,23 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include + +Align +quadrant(Rectangle r, Point pt) { + Align ret; + + pt = subpt(pt, r.min); + ret = 0; + + if(pt.x >= Dx(r) * .5) + ret |= East; + if(pt.x <= Dx(r) * .5) + ret |= West; + if(pt.y <= Dy(r) * .5) + ret |= North; + if(pt.y >= Dy(r) * .5) + ret |= South; + + return ret; +} diff --git a/libstuff/geom/rect_contains_p.c b/libstuff/geom/rect_contains_p.c new file mode 100644 index 00000000..6433afc3 --- /dev/null +++ b/libstuff/geom/rect_contains_p.c @@ -0,0 +1,12 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include + +bool +rect_contains_p(Rectangle r, Rectangle r2) { + return r2.min.x >= r.min.x + && r2.max.x <= r.max.x + && r2.min.y >= r.min.y + && r2.max.y <= r.max.y; +} diff --git a/libstuff/geom/rect_haspoint_p.c b/libstuff/geom/rect_haspoint_p.c new file mode 100644 index 00000000..0cb31a09 --- /dev/null +++ b/libstuff/geom/rect_haspoint_p.c @@ -0,0 +1,10 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include + +bool +rect_haspoint_p(Point pt, Rectangle r) { + return (pt.x >= r.min.x) && (pt.x < r.max.x) + && (pt.y >= r.min.y) && (pt.y < r.max.y); +} diff --git a/libstuff/geom/rect_intersect_p.c b/libstuff/geom/rect_intersect_p.c new file mode 100644 index 00000000..f2678f79 --- /dev/null +++ b/libstuff/geom/rect_intersect_p.c @@ -0,0 +1,12 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include + +bool +rect_intersect_p(Rectangle r, Rectangle r2) { + return r.min.x <= r2.max.x + && r.max.x >= r2.min.x + && r.min.y <= r2.max.y + && r.max.y >= r2.min.y; +} diff --git a/libstuff/geom/rect_intersection.c b/libstuff/geom/rect_intersection.c new file mode 100644 index 00000000..e5f11a57 --- /dev/null +++ b/libstuff/geom/rect_intersection.c @@ -0,0 +1,17 @@ +/* Copyright ©2006-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include + +Rectangle +rect_intersection(Rectangle r, Rectangle r2) { + Rectangle ret; + + /* ret != canonrect(ret) ≡ no intersection. */ + ret.min.x = max(r.min.x, r2.min.x); + ret.max.x = min(r.max.x, r2.max.x); + ret.min.y = max(r.min.y, r2.min.y); + ret.max.y = min(r.max.y, r2.max.y); + return ret; +} diff --git a/libstuff/init_screens.c b/libstuff/init_screens.c new file mode 100644 index 00000000..47a05a85 --- /dev/null +++ b/libstuff/init_screens.c @@ -0,0 +1,9 @@ +/* Copyright ©2010 Kris Maglione + * See LICENSE file for license details. + */ + +void init_screens(void); +void +init_screens(void) { +} + diff --git a/cmd/wmii/map.c b/libstuff/map.c similarity index 96% rename from cmd/wmii/map.c rename to libstuff/map.c index 08b137ae..9d0bc5d2 100644 --- a/cmd/wmii/map.c +++ b/libstuff/map.c @@ -1,7 +1,8 @@ /* Written by Kris Maglione */ /* Public domain */ -#include "dat.h" -#include "fns.h" +#include +#include +#include /* Edit s/^([a-zA-Z].*)\n([a-z].*) {/\1 \2;/g x/^([^a-zA-Z]|static|$)/-+d s/ (\*map|val|*str)//g */ diff --git a/cmd/wmii/printevent.c b/libstuff/printevent.c similarity index 99% rename from cmd/wmii/printevent.c rename to libstuff/printevent.c index 5b52c430..b0b09322 100644 --- a/cmd/wmii/printevent.c +++ b/libstuff/printevent.c @@ -39,10 +39,10 @@ * ken@richsun.UUCP */ -#include "dat.h" #include #include -//#include "fns.h" +#include +#include #include "printevent.h" #define Window XWindow diff --git a/cmd/wmii/printevent.h b/libstuff/printevent.h similarity index 100% rename from cmd/wmii/printevent.h rename to libstuff/printevent.h diff --git a/libstuff/util/_die.c b/libstuff/util/_die.c new file mode 100644 index 00000000..2fe12706 --- /dev/null +++ b/libstuff/util/_die.c @@ -0,0 +1,27 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include +#include +#include +#include +#include "util.h" + +void +_die(char *file, int line, char *msg, ...) { + va_list ap; + + va_start(ap, msg); + fprint(2, "%s: dieing at %s:%d: %s\n", + argv0, file, line, + vsxprint(msg, ap)); + va_end(ap); + + kill(getpid(), SIGABRT); + abort(); /* Adds too many frames: + * _die() + * abort() + * raise(SIGABRT) + * kill(getpid(), SIGABRT) + */ +} diff --git a/libstuff/util/backtrace.c b/libstuff/util/backtrace.c new file mode 100644 index 00000000..ce0ee096 --- /dev/null +++ b/libstuff/util/backtrace.c @@ -0,0 +1,88 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#undef nelem +#include +#include "util.h" + +#ifdef __linux__ +# define PROGTXT "exe" +#else +# define PROGTXT "file" +#endif + +static void +_backtrace(int pid, char *btarg) { + char *proc, *spid, *gdbcmd; + int fd[3], p[2]; + int status, cmdfd; + + gdbcmd = estrdup("/tmp/gdbcmd.XXXXXX"); + if(pipe(p) < 0) + goto done; + closeexec(p[0]); + + cmdfd = mkstemp(gdbcmd); + if(cmdfd < 0) + goto done; + + fprint(cmdfd, "bt %s\n", btarg); + fprint(cmdfd, "detach\n"); + close(cmdfd); + + fd[0] = open("/dev/null", O_RDONLY); + fd[1] = p[1]; + fd[2] = dup(2); + + proc = sxprint("/proc/%d/" PROGTXT, pid); + spid = sxprint("%d", pid); + if(spawn3l(fd, "gdb", "gdb", "-batch", "-x", gdbcmd, proc, spid, nil) < 0) { + unlink(gdbcmd); + goto done; + } + + Biobuf bp; + char *s; + + Binit(&bp, p[0], OREAD); + while((s = Brdstr(&bp, '\n', 1))) { + Dprint(DStack, "%s\n", s); + free(s); + } + unlink(gdbcmd); + +done: + free(gdbcmd); + kill(pid, SIGKILL); + waitpid(pid, &status, 0); +} + +void +backtrace(char *btarg) { + int pid; + + /* Fork so we can backtrace the child. Keep this stack + * frame minimal, so the trace is fairly clean. + */ + Debug(DStack) + switch(pid = fork()) { + case -1: + return; + case 0: + kill(getpid(), SIGSTOP); + _exit(0); + default: + _backtrace(pid, btarg); + break; + } + +} diff --git a/libstuff/util/closeexec.c b/libstuff/util/closeexec.c new file mode 100644 index 00000000..bc02e58b --- /dev/null +++ b/libstuff/util/closeexec.c @@ -0,0 +1,12 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include "util.h" + +void +closeexec(int fd) { + if(fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + fatal("can't set %d close on exec: %r", fd); +} diff --git a/libstuff/util/comm.c b/libstuff/util/comm.c new file mode 100644 index 00000000..873fb05c --- /dev/null +++ b/libstuff/util/comm.c @@ -0,0 +1,42 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include "util.h" +#include + + +char** +comm(int cols, char **toka, char **tokb) { + Vector_ptr vec; + char **ret; + int cmp; + + vector_pinit(&vec); + while(*toka || *tokb) { + if(!*toka) + cmp = 1; + else if(!*tokb) + cmp = -1; + else + cmp = strcmp(*toka, *tokb); + if(cmp < 0) { + if(cols & CLeft) + vector_ppush(&vec, *toka); + toka++; + }else if(cmp > 0) { + if(cols & CRight) + vector_ppush(&vec, *tokb); + tokb++; + }else { + if(cols & CCenter) + vector_ppush(&vec, *toka); + toka++; + tokb++; + } + } + vector_ppush(&vec, nil); + ret = strlistdup((char**)vec.ary); + free(vec.ary); + return ret; +} diff --git a/libstuff/util/doublefork.c b/libstuff/util/doublefork.c new file mode 100644 index 00000000..b16bfe47 --- /dev/null +++ b/libstuff/util/doublefork.c @@ -0,0 +1,31 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include +#include "util.h" + +int +doublefork(void) { + pid_t pid; + int status; + + switch(pid=fork()) { + case -1: + fatal("Can't fork(): %r"); + case 0: + switch(pid=fork()) { + case -1: + fatal("Can't fork(): %r"); + case 0: + return 0; + default: + exit(0); + } + default: + waitpid(pid, &status, 0); + return pid; + } + /* NOTREACHED */ +} diff --git a/libstuff/util/emalloc.c b/libstuff/util/emalloc.c new file mode 100644 index 00000000..8714a57c --- /dev/null +++ b/libstuff/util/emalloc.c @@ -0,0 +1,12 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include "util.h" + +void * +emalloc(uint size) { + void *ret = malloc(size); + if(!ret) + mfatal("malloc", size); + return ret; +} diff --git a/libstuff/util/emallocz.c b/libstuff/util/emallocz.c new file mode 100644 index 00000000..1fc7be39 --- /dev/null +++ b/libstuff/util/emallocz.c @@ -0,0 +1,11 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include "util.h" + +void* +emallocz(uint size) { + void *ret = emalloc(size); + memset(ret, 0, size); + return ret; +} diff --git a/libstuff/util/erealloc.c b/libstuff/util/erealloc.c new file mode 100644 index 00000000..61f55045 --- /dev/null +++ b/libstuff/util/erealloc.c @@ -0,0 +1,12 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include "util.h" + +void * +erealloc(void *ptr, uint size) { + void *ret = realloc(ptr, size); + if(!ret) + mfatal("realloc", size); + return ret; +} diff --git a/libstuff/util/estrdup.c b/libstuff/util/estrdup.c new file mode 100644 index 00000000..78c01dd6 --- /dev/null +++ b/libstuff/util/estrdup.c @@ -0,0 +1,12 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include "util.h" + +char* +estrdup(const char *str) { + void *ret = strdup(str); + if(!ret) + mfatal("strdup", strlen(str)); + return ret; +} diff --git a/libstuff/util/estrndup.c b/libstuff/util/estrndup.c new file mode 100644 index 00000000..2a384fe7 --- /dev/null +++ b/libstuff/util/estrndup.c @@ -0,0 +1,15 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include "util.h" + +char* +estrndup(const char *str, uint len) { + char *ret; + + len = min(len, strlen(str)); + ret = emalloc(len + 1); + memcpy(ret, str, len); + ret[len] = '\0'; + return ret; +} diff --git a/libstuff/util/fatal.c b/libstuff/util/fatal.c new file mode 100644 index 00000000..d257a295 --- /dev/null +++ b/libstuff/util/fatal.c @@ -0,0 +1,40 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include +#include "util.h" + +typedef struct VFmt VFmt; +struct VFmt { + const char *fmt; + va_list args; +}; + +#ifdef VARARGCK +# pragma varargck type "V" VFmt* +#endif + +static int +Vfmt(Fmt *f) { + VFmt *vf; + int i; + + vf = va_arg(f->args, VFmt*); + i = fmtvprint(f, vf->fmt, vf->args); + return i; +} + +void +fatal(const char *fmt, ...) { + VFmt fp; + + fmtinstall('V', Vfmt); + fmtinstall('', Vfmt); + + fp.fmt = fmt; + va_start(fp.args, fmt); + fprint(2, "%s: fatal: %V\n", argv0, &fp); + va_end(fp.args); + + exit(1); +} diff --git a/libstuff/util/freelater.c b/libstuff/util/freelater.c new file mode 100644 index 00000000..542a1296 --- /dev/null +++ b/libstuff/util/freelater.c @@ -0,0 +1,16 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include "util.h" + +void* +freelater(void *p) { + static char* obj[16]; + static long nobj; + int id; + + id = nobj++ % nelem(obj); + free(obj[id]); + obj[id] = p; + return p; +} diff --git a/cmd/strut/_util.c b/libstuff/util/getbase.c similarity index 53% rename from cmd/strut/_util.c rename to libstuff/util/getbase.c index 364ff81b..3a245e10 100644 --- a/cmd/strut/_util.c +++ b/libstuff/util/getbase.c @@ -1,13 +1,12 @@ -/* Copyright ©2008-2010 Kris Maglione +/* Copyright ©2008-2010 Kris Maglione * See LICENSE file for license details. */ -#include "dat.h" #include #include -#include "fns.h" +#include #define strbcmp(str, const) (strncmp((str), (const), sizeof(const)-1)) -static int +int getbase(const char **s, long *sign) { const char *p; int ret; @@ -42,36 +41,3 @@ getbase(const char **s, long *sign) { *sign = 0; return ret; } - -bool -getlong(const char *s, long *ret) { - const char *end; - char *rend; - int base; - long sign; - - end = s+strlen(s); - base = getbase(&s, &sign); - if(sign == 0) - return false; - - *ret = sign * strtol(s, &rend, base); - return (end == rend); -} - -bool -getulong(const char *s, ulong *ret) { - const char *end; - char *rend; - int base; - long sign; - - end = s+strlen(s); - base = getbase(&s, &sign); - if(sign < 1) - return false; - - *ret = strtoul(s, &rend, base); - return (end == rend); -} - diff --git a/libstuff/util/getint.c b/libstuff/util/getint.c new file mode 100644 index 00000000..23c08552 --- /dev/null +++ b/libstuff/util/getint.c @@ -0,0 +1,14 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include + +bool +getint(const char *s, int *ret) { + long l; + bool res; + + res = getlong(s, &l); + *ret = l; + return res; +} diff --git a/libstuff/util/getlong.c b/libstuff/util/getlong.c new file mode 100644 index 00000000..44fc8139 --- /dev/null +++ b/libstuff/util/getlong.c @@ -0,0 +1,24 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include + +bool +getlong(const char *s, long *ret) { + const char *end; + char *rend; + int base; + long sign; + + if(s == nil) + return false; + end = s+strlen(s); + base = getbase(&s, &sign); + if(sign == 0) + return false; + + *ret = sign * strtol(s, &rend, base); + return (end == rend); +} diff --git a/libstuff/util/getulong.c b/libstuff/util/getulong.c new file mode 100644 index 00000000..0782bfcd --- /dev/null +++ b/libstuff/util/getulong.c @@ -0,0 +1,24 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include + +bool +getulong(const char *s, ulong *ret) { + const char *end; + char *rend; + int base; + long sign; + + if(s == nil) + return false; + end = s+strlen(s); + base = getbase(&s, &sign); + if(sign < 1) + return false; + + *ret = strtoul(s, &rend, base); + return (end == rend); +} diff --git a/libstuff/util/grep.c b/libstuff/util/grep.c new file mode 100644 index 00000000..f9c5baa9 --- /dev/null +++ b/libstuff/util/grep.c @@ -0,0 +1,22 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "util.h" + + +void +grep(char **list, Reprog *re, int flags) { + char **p, **q; + int res; + + q = list; + for(p=q; *p; p++) { + res = 0; + if(re) + res = regexec(re, *p, nil, 0); + if(res && !(flags & GInvert) + || !res && (flags & GInvert)) + *q++ = *p; + } + *q = nil; +} diff --git a/libstuff/util/join.c b/libstuff/util/join.c new file mode 100644 index 00000000..786285d3 --- /dev/null +++ b/libstuff/util/join.c @@ -0,0 +1,23 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include "util.h" + +char* +join(char **list, char *sep) { + Fmt f; + char **p; + + if(fmtstrinit(&f) < 0) + abort(); + + for(p=list; *p; p++) { + if(p != list) + fmtstrcpy(&f, sep); + fmtstrcpy(&f, *p); + } + + return fmtstrflush(&f); +} diff --git a/libstuff/util/max.c b/libstuff/util/max.c new file mode 100644 index 00000000..b1f2c547 --- /dev/null +++ b/libstuff/util/max.c @@ -0,0 +1,10 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include "util.h" + +int +max(int a, int b) { + if(a > b) + return a; + return b; +} diff --git a/libstuff/util/mfatal.c b/libstuff/util/mfatal.c new file mode 100644 index 00000000..d1e0dbe9 --- /dev/null +++ b/libstuff/util/mfatal.c @@ -0,0 +1,34 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include +#include +#include "util.h" + +/* Can't malloc */ +void +mfatal(char *name, uint size) { + const char + couldnot[] = ": fatal: Could not ", + paren[] = "() ", + bytes[] = " bytes\n"; + char buf[1024]; + char sizestr[8]; + int i; + + i = sizeof sizestr; + do { + sizestr[--i] = '0' + (size%10); + size /= 10; + } while(size > 0); + + strlcat(buf, argv0, sizeof buf); + strlcat(buf, couldnot, sizeof buf); + strlcat(buf, name, sizeof buf); + strlcat(buf, paren, sizeof buf); + strlcat(buf, sizestr+i, sizeof buf); + strlcat(buf, bytes, sizeof buf); + write(2, buf, strlen(buf)); + + exit(1); +} diff --git a/libstuff/util/min.c b/libstuff/util/min.c new file mode 100644 index 00000000..235113aa --- /dev/null +++ b/libstuff/util/min.c @@ -0,0 +1,10 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include "util.h" + +int +min(int a, int b) { + if(a < b) + return a; + return b; +} diff --git a/libstuff/util/pathsearch.c b/libstuff/util/pathsearch.c new file mode 100644 index 00000000..9d9ad3d6 --- /dev/null +++ b/libstuff/util/pathsearch.c @@ -0,0 +1,33 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include +#include +#include "util.h" + +char* +pathsearch(const char *path, const char *file, bool slashok) { + char *orig, *p, *s; + + if(!slashok && strchr(file, '/') > file) + file = sxprint("%s/%s", getcwd(buffer, sizeof buffer), file); + else if(!strncmp(file, "./", 2)) + file = sxprint("%s/%s", getcwd(buffer, sizeof buffer), file+2); + if(file[0] == '/') { + if(access(file, X_OK)) + return strdup(file); + return nil; + } + + orig = estrdup(path ? path : getenv("PATH")); + for(p=orig; (s=strtok(p, ":")); p=nil) { + s = smprint("%s/%s", s, file); + if(!access(s, X_OK)) + break; + free(s); + } + free(orig); + return s; +} diff --git a/libstuff/util/refree.c b/libstuff/util/refree.c new file mode 100644 index 00000000..53699b23 --- /dev/null +++ b/libstuff/util/refree.c @@ -0,0 +1,14 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include "util.h" + +void +refree(Regex *r) { + + free(r->regex); + free(r->regc); + r->regex = nil; + r->regc = nil; +} diff --git a/libstuff/util/reinit.c b/libstuff/util/reinit.c new file mode 100644 index 00000000..0ab42cd8 --- /dev/null +++ b/libstuff/util/reinit.c @@ -0,0 +1,16 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "util.h" + + +void +reinit(Regex *r, char *regx) { + + refree(r); + + if(regx[0] != '\0') { + r->regex = estrdup(regx); + r->regc = regcomp(regx); + } +} diff --git a/libstuff/util/spawn3.c b/libstuff/util/spawn3.c new file mode 100644 index 00000000..7960b2a3 --- /dev/null +++ b/libstuff/util/spawn3.c @@ -0,0 +1,44 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include +#include "util.h" + +int +spawn3(int fd[3], const char *file, char *argv[]) { + /* Some ideas from Russ Cox's libthread port. */ + int p[2]; + int pid; + + if(pipe(p) < 0) + return -1; + closeexec(p[1]); + + switch(pid = doublefork()) { + case 0: + dup2(fd[0], 0); + dup2(fd[1], 1); + dup2(fd[2], 2); + + execvp(file, argv); + write(p[1], &errno, sizeof errno); + exit(1); + break; + default: + close(p[1]); + if(read(p[0], &errno, sizeof errno) == sizeof errno) + pid = -1; + close(p[0]); + break; + case -1: /* can't happen */ + break; + } + + close(fd[0]); + /* These could fail if any of these was also a previous fd. */ + close(fd[1]); + close(fd[2]); + return pid; +} diff --git a/libstuff/util/spawn3l.c b/libstuff/util/spawn3l.c new file mode 100644 index 00000000..9c0f1beb --- /dev/null +++ b/libstuff/util/spawn3l.c @@ -0,0 +1,29 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include "util.h" + +int +spawn3l(int fd[3], const char *file, ...) { + va_list ap; + char **argv; + int i, n; + + va_start(ap, file); + for(n=0; va_arg(ap, char*); n++) + ; + va_end(ap); + + argv = emalloc((n+1) * sizeof *argv); + va_start(ap, file); + quotefmtinstall(); + for(i=0; i <= n; i++) + argv[i] = va_arg(ap, char*); + va_end(ap); + + i = spawn3(fd, file, argv); + free(argv); + return i; +} diff --git a/libstuff/util/stokenize.c b/libstuff/util/stokenize.c new file mode 100644 index 00000000..86fd2256 --- /dev/null +++ b/libstuff/util/stokenize.c @@ -0,0 +1,22 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include "util.h" + +uint +stokenize(char *res[], uint reslen, char *str, char *delim) { + char *s; + uint i; + + i = 0; + s = str; + while(i < reslen && *s) { + while(strchr(delim, *s)) + *(s++) = '\0'; + if(*s) + res[i++] = s; + while(*s && !strchr(delim, *s)) + s++; + } + return i; +} diff --git a/libstuff/util/strcasestr.c b/libstuff/util/strcasestr.c new file mode 100644 index 00000000..9e80a1eb --- /dev/null +++ b/libstuff/util/strcasestr.c @@ -0,0 +1,25 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include +#include +#include +#include "util.h" + +/* TODO: Make this UTF-8 compliant. */ +char* +strcasestr(const char *dst, const char *src) { + int dc, sc; + int len; + + len = strlen(src) - 1; + for(; (sc = *src) && *dst; src++) { + sc = tolower(dc); + for(; (dc = *dst); dst++) { + dc = tolower(dc); + if(sc == dc && !strncasecmp(dst+1, src+1, len)) + return (char*)(uintptr_t)dst; + } + } + return nil; +} diff --git a/libstuff/util/strend.c b/libstuff/util/strend.c new file mode 100644 index 00000000..53b66bac --- /dev/null +++ b/libstuff/util/strend.c @@ -0,0 +1,13 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include + +char* +strend(char *s, int n) { + int len; + + len = strlen(s); + return s + max(0, len - n); +} diff --git a/libstuff/util/strlcat.c b/libstuff/util/strlcat.c new file mode 100644 index 00000000..81bd2f09 --- /dev/null +++ b/libstuff/util/strlcat.c @@ -0,0 +1,26 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include "util.h" + +uint +strlcat(char *dst, const char *src, uint size) { + const char *s; + char *d; + int n, len; + + d = dst; + s = src; + n = size; + while(n-- > 0 && *d != '\0') + d++; + len = n; + + while(*s != '\0') { + if(n-- > 0) + *d++ = *s; + s++; + } + if(len > 0) + *d = '\0'; + return size - n - 1; +} diff --git a/libstuff/util/strlcatprint.c b/libstuff/util/strlcatprint.c new file mode 100644 index 00000000..ffe139fb --- /dev/null +++ b/libstuff/util/strlcatprint.c @@ -0,0 +1,19 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include "util.h" + +int +strlcatprint(char *buf, int len, const char *fmt, ...) { + va_list ap; + int buflen; + int ret; + + va_start(ap, fmt); + buflen = strlen(buf); + ret = vsnprint(buf+buflen, len-buflen, fmt, ap); + va_end(ap); + return ret; +} diff --git a/libstuff/util/sxprint.c b/libstuff/util/sxprint.c new file mode 100644 index 00000000..0a1bf3e4 --- /dev/null +++ b/libstuff/util/sxprint.c @@ -0,0 +1,14 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include "util.h" + +char* +sxprint(const char *fmt, ...) { + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = vsxprint(fmt, ap); + va_end(ap); + return ret; +} diff --git a/libstuff/util/tokenize.c b/libstuff/util/tokenize.c new file mode 100644 index 00000000..af273919 --- /dev/null +++ b/libstuff/util/tokenize.c @@ -0,0 +1,21 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include "util.h" + +uint +tokenize(char *res[], uint reslen, char *str, char delim) { + char *s; + uint i; + + i = 0; + s = str; + while(i < reslen && *s) { + while(*s == delim) + *(s++) = '\0'; + if(*s) + res[i++] = s; + while(*s && *s != delim) + s++; + } + return i; +} diff --git a/libstuff/util/uniq.c b/libstuff/util/uniq.c new file mode 100644 index 00000000..f7322e5d --- /dev/null +++ b/libstuff/util/uniq.c @@ -0,0 +1,18 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include "util.h" + +void +uniq(char **toks) { + char **p, **q; + + q = toks; + if(*q == nil) + return; + for(p=q+1; *p; p++) + if(strcmp(*q, *p)) + *++q = *p; + *++q = nil; +} diff --git a/libstuff/util/unquote.c b/libstuff/util/unquote.c new file mode 100644 index 00000000..7ae5afe3 --- /dev/null +++ b/libstuff/util/unquote.c @@ -0,0 +1,38 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "util.h" + +int +unquote(char *buf, char *toks[], int ntoks) { + char *s, *t; + bool inquote; + int n; + + n = 0; + s = buf; + while(*s && n < ntoks) { + while(*s && utfrune(" \t\r\n", *s)) + s++; + inquote = false; + toks[n] = s; + t = s; + while(*s && (inquote || !utfrune(" \t\r\n", *s))) { + if(*s == '\'') { + if(inquote && s[1] == '\'') + *t++ = *s++; + else + inquote = !inquote; + } + else + *t++ = *s; + s++; + } + if(*s) + s++; + *t = '\0'; + if(s != toks[n]) + n++; + } + return n; +} diff --git a/libstuff/util/utflcpy.c b/libstuff/util/utflcpy.c new file mode 100644 index 00000000..ae67e79e --- /dev/null +++ b/libstuff/util/utflcpy.c @@ -0,0 +1,11 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include "util.h" + +int +utflcpy(char *to, const char *from, int l) { + char *p; + + p = utfecpy(to, to+l, from); + return p-to; +} diff --git a/libstuff/util/util.h b/libstuff/util/util.h new file mode 100644 index 00000000..21dd775c --- /dev/null +++ b/libstuff/util/util.h @@ -0,0 +1,5 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include + +void mfatal(char*, uint); diff --git a/libstuff/util/vector.c b/libstuff/util/vector.c new file mode 100644 index 00000000..9b1f4365 --- /dev/null +++ b/libstuff/util/vector.c @@ -0,0 +1,34 @@ +/* Copyright ©2008-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include +#include +#include "util.h" + +/* Blech. */ +#define VECTOR(type, nam, c) \ +void \ +vector_##c##init(Vector_##nam *v) { \ + memset(v, 0, sizeof *v); \ +} \ + \ +void \ +vector_##c##free(Vector_##nam *v) { \ + free(v->ary); \ + memset(v, 0, sizeof *v); \ +} \ + \ +void \ +vector_##c##push(Vector_##nam *v, type val) { \ + if(v->n == v->size) { \ + if(v->size == 0) \ + v->size = 2; \ + v->size <<= 2; \ + v->ary = erealloc(v->ary, v->size * sizeof *v->ary); \ + } \ + v->ary[v->n++] = val; \ +} \ + +VECTOR(long, long, l) +VECTOR(Rectangle, rect, r) +VECTOR(void*, ptr, p) diff --git a/libstuff/util/vsxprint.c b/libstuff/util/vsxprint.c new file mode 100644 index 00000000..85b2bf5b --- /dev/null +++ b/libstuff/util/vsxprint.c @@ -0,0 +1,13 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include +#include "util.h" + +char* +vsxprint(const char *fmt, va_list ap) { + char *s; + + s = vsmprint(fmt, ap); + freelater(s); + return s; +} diff --git a/libstuff/x11/colors/loadcolor.c b/libstuff/x11/colors/loadcolor.c new file mode 100644 index 00000000..64db595e --- /dev/null +++ b/libstuff/x11/colors/loadcolor.c @@ -0,0 +1,17 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +bool +loadcolor(CTuple *c, char *str) { + char buf[24]; + + utflcpy(buf, str, sizeof buf); + memcpy(c->colstr, str, sizeof c->colstr); + + buf[7] = buf[15] = buf[23] = '\0'; + return namedcolor(buf, &c->fg) + && namedcolor(buf+8, &c->bg) + && namedcolor(buf+16, &c->border); +} diff --git a/libstuff/x11/colors/namedcolor.c b/libstuff/x11/colors/namedcolor.c new file mode 100644 index 00000000..3ecfff65 --- /dev/null +++ b/libstuff/x11/colors/namedcolor.c @@ -0,0 +1,22 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +bool +namedcolor(char *name, Color *ret) { + XColor c, c2; + + if(XAllocNamedColor(display, scr.colormap, name, &c, &c2)) { + *ret = (Color) { + c.pixel, { + c.red, + c.green, + c.blue, + 0xffff + }, + }; + return true; + } + return false; +} diff --git a/libstuff/x11/colors/xftcolor.c b/libstuff/x11/colors/xftcolor.c new file mode 100644 index 00000000..2efbadf9 --- /dev/null +++ b/libstuff/x11/colors/xftcolor.c @@ -0,0 +1,19 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +XftColor* +xftcolor(Color col) { + XftColor *c; + + c = emallocz(sizeof *c); + *c = (XftColor) { + ((col.render.alpha&0xff00) << 24) + | ((col.render.red&0xff00) << 8) + | ((col.render.green&0xff00) << 0) + | ((col.render.blue&0xff00) >> 8), + col.render + }; + return freelater(c); +} diff --git a/libstuff/x11/convpts.c b/libstuff/x11/convpts.c new file mode 100644 index 00000000..244769d1 --- /dev/null +++ b/libstuff/x11/convpts.c @@ -0,0 +1,17 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +XPoint* +convpts(Point *pt, int np) { + XPoint *rp; + int i; + + rp = emalloc(np * sizeof *rp); + for(i = 0; i < np; i++) { + rp[i].x = pt[i].x; + rp[i].y = pt[i].y; + } + return rp; +} diff --git a/libstuff/x11/drawing/border.c b/libstuff/x11/drawing/border.c new file mode 100644 index 00000000..66340e31 --- /dev/null +++ b/libstuff/x11/drawing/border.c @@ -0,0 +1,19 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +border(Image *dst, Rectangle r, int w, Color col) { + if(w == 0) + return; + + r = insetrect(r, w/2); + r.max.x -= w%2; + r.max.y -= w%2; + + XSetLineAttributes(display, dst->gc, w, LineSolid, CapButt, JoinMiter); + setgccol(dst, col); + XDrawRectangle(display, dst->xid, dst->gc, + r.min.x, r.min.y, Dx(r), Dy(r)); +} diff --git a/libstuff/x11/drawing/drawline.c b/libstuff/x11/drawing/drawline.c new file mode 100644 index 00000000..29628c6c --- /dev/null +++ b/libstuff/x11/drawing/drawline.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +drawline(Image *dst, Point p1, Point p2, int cap, int w, Color col) { + XSetLineAttributes(display, dst->gc, w, LineSolid, cap, JoinMiter); + setgccol(dst, col); + XDrawLine(display, dst->xid, dst->gc, p1.x, p1.y, p2.x, p2.y); +} diff --git a/libstuff/x11/drawing/drawpoly.c b/libstuff/x11/drawing/drawpoly.c new file mode 100644 index 00000000..e50e6d84 --- /dev/null +++ b/libstuff/x11/drawing/drawpoly.c @@ -0,0 +1,15 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +drawpoly(Image *dst, Point *pt, int np, int cap, int w, Color col) { + XPoint *xp; + + xp = convpts(pt, np); + XSetLineAttributes(display, dst->gc, w, LineSolid, cap, JoinMiter); + setgccol(dst, col); + XDrawLines(display, dst->xid, dst->gc, xp, np, CoordModeOrigin); + free(xp); +} diff --git a/libstuff/x11/drawing/drawstring.c b/libstuff/x11/drawing/drawstring.c new file mode 100644 index 00000000..02271a90 --- /dev/null +++ b/libstuff/x11/drawing/drawstring.c @@ -0,0 +1,88 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +uint +drawstring(Image *dst, Font *font, + Rectangle r, Align align, + char *text, Color col) { + Rectangle tr; + char *buf; + uint x, y, width, height, len; + int shortened; + + shortened = 0; + + len = strlen(text); + buf = emalloc(len+1); + memcpy(buf, text, len+1); + + r.max.y -= font->pad.min.y; + r.min.y += font->pad.max.y; + + height = font->ascent + font->descent; + y = r.min.y + Dy(r) / 2 - height / 2 + font->ascent; + + width = Dx(r) - font->pad.min.x - font->pad.max.x - (font->height & ~1); + + r.min.x += font->pad.min.x; + r.max.x -= font->pad.max.x; + + /* shorten text if necessary */ + tr = ZR; + while(len > 0) { + tr = textextents_l(font, buf, len + min(shortened, 3), nil); + if(Dx(tr) <= width) + break; + while(len > 0 && (buf[--len]&0xC0) == 0x80) + buf[len] = '.'; + buf[len] = '.'; + shortened++; + } + + if(len == 0 || Dx(tr) > width) + goto done; + + /* mark shortened info in the string */ + if(shortened) + len += min(shortened, 3); + + switch (align) { + case East: + x = r.max.x - (tr.max.x + (font->height / 2)); + break; + case Center: + x = r.min.x + (Dx(r) - Dx(tr)) / 2 - tr.min.x; + break; + default: + x = r.min.x + (font->height / 2) - tr.min.x; + break; + } + + setgccol(dst, col); + switch(font->type) { + case FFontSet: + Xutf8DrawString(display, dst->xid, + font->font.set, dst->gc, + x, y, + buf, len); + break; + case FXft: + XftDrawStringUtf8(xftdrawable(dst), xftcolor(col), + font->font.xft, + x, y, (uchar*)buf, len); + break; + case FX11: + XSetFont(display, dst->gc, font->font.x11->fid); + XDrawString(display, dst->xid, dst->gc, + x, y, buf, len); + break; + default: + die("Invalid font type."); + } + +done: + free(buf); + return Dx(tr); +} diff --git a/libstuff/x11/drawing/fill.c b/libstuff/x11/drawing/fill.c new file mode 100644 index 00000000..dd5326b9 --- /dev/null +++ b/libstuff/x11/drawing/fill.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +fill(Image *dst, Rectangle r, Color col) { + setgccol(dst, col); + XFillRectangle(display, dst->xid, dst->gc, + r.min.x, r.min.y, Dx(r), Dy(r)); +} diff --git a/libstuff/x11/drawing/fillpoly.c b/libstuff/x11/drawing/fillpoly.c new file mode 100644 index 00000000..516e7411 --- /dev/null +++ b/libstuff/x11/drawing/fillpoly.c @@ -0,0 +1,14 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +fillpoly(Image *dst, Point *pt, int np, Color col) { + XPoint *xp; + + xp = convpts(pt, np); + setgccol(dst, col); + XFillPolygon(display, dst->xid, dst->gc, xp, np, Complex, CoordModeOrigin); + free(xp); +} diff --git a/libstuff/x11/errors.c b/libstuff/x11/errors.c new file mode 100644 index 00000000..6bfb09df --- /dev/null +++ b/libstuff/x11/errors.c @@ -0,0 +1,40 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +extern ErrorCode ignored_xerrors[]; +static bool _trap_errors; +static long nerrors; + +int +errorhandler(Display *dpy, XErrorEvent *error) { + ErrorCode *e; + + USED(dpy); + + if(_trap_errors) + nerrors++; + + e = ignored_xerrors; + if(e) + for(; e->rcode || e->ecode; e++) + if((e->rcode == 0 || e->rcode == error->request_code) + && (e->ecode == 0 || e->ecode == error->error_code)) + return 0; + + fprint(2, "%s: fatal error: Xrequest code=%d, Xerror code=%d\n", + argv0, error->request_code, error->error_code); + return xlib_errorhandler(display, error); /* calls exit() */ +} + +int +traperrors(bool enable) { + + sync(); + _trap_errors = enable; + if (enable) + nerrors = 0; + return nerrors; + +} diff --git a/libstuff/x11/focus/getfocus.c b/libstuff/x11/focus/getfocus.c new file mode 100644 index 00000000..967060e7 --- /dev/null +++ b/libstuff/x11/focus/getfocus.c @@ -0,0 +1,13 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +XWindow +getfocus(void) { + XWindow ret; + int revert; + + XGetInputFocus(display, &ret, &revert); + return ret; +} diff --git a/libstuff/x11/focus/setfocus.c b/libstuff/x11/focus/setfocus.c new file mode 100644 index 00000000..35a34e15 --- /dev/null +++ b/libstuff/x11/focus/setfocus.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +setfocus(Window *w, int mode) { + XSetInputFocus(display, w->xid, mode, CurrentTime); +} diff --git a/libstuff/x11/freestringlist.c b/libstuff/x11/freestringlist.c new file mode 100644 index 00000000..372ded89 --- /dev/null +++ b/libstuff/x11/freestringlist.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +void +freestringlist(char *list[]) { + XFreeStringList(list); +} diff --git a/libstuff/x11/geometry/XRect.c b/libstuff/x11/geometry/XRect.c new file mode 100644 index 00000000..11f93867 --- /dev/null +++ b/libstuff/x11/geometry/XRect.c @@ -0,0 +1,15 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +XRectangle +XRect(Rectangle r) { + XRectangle xr; + + xr.x = r.min.x; + xr.y = r.min.y; + xr.width = Dx(r); + xr.height = Dy(r); + return xr; +} diff --git a/libstuff/x11/geometry/addpt.c b/libstuff/x11/geometry/addpt.c new file mode 100644 index 00000000..c4a44765 --- /dev/null +++ b/libstuff/x11/geometry/addpt.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Point +addpt(Point p, Point q) { + p.x += q.x; + p.y += q.y; + return p; +} diff --git a/libstuff/x11/geometry/divpt.c b/libstuff/x11/geometry/divpt.c new file mode 100644 index 00000000..634c3d23 --- /dev/null +++ b/libstuff/x11/geometry/divpt.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Point +divpt(Point p, Point q) { + p.x /= q.x; + p.y /= q.y; + return p; +} diff --git a/libstuff/x11/geometry/eqpt.c b/libstuff/x11/geometry/eqpt.c new file mode 100644 index 00000000..aca91c19 --- /dev/null +++ b/libstuff/x11/geometry/eqpt.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +int +eqpt(Point p, Point q) { + return p.x==q.x && p.y==q.y; +} diff --git a/libstuff/x11/geometry/eqrect.c b/libstuff/x11/geometry/eqrect.c new file mode 100644 index 00000000..0b3995ec --- /dev/null +++ b/libstuff/x11/geometry/eqrect.c @@ -0,0 +1,10 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +int +eqrect(Rectangle a, Rectangle b) { + return a.min.x==b.min.x && a.max.x==b.max.x + && a.min.y==b.min.y && a.max.y==b.max.y; +} diff --git a/libstuff/x11/geometry/insetrect.c b/libstuff/x11/geometry/insetrect.c new file mode 100644 index 00000000..4175a980 --- /dev/null +++ b/libstuff/x11/geometry/insetrect.c @@ -0,0 +1,13 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Rectangle +insetrect(Rectangle r, int n) { + r.min.x += n; + r.min.y += n; + r.max.x -= n; + r.max.y -= n; + return r; +} diff --git a/libstuff/x11/geometry/mulpt.c b/libstuff/x11/geometry/mulpt.c new file mode 100644 index 00000000..ec7c6eb8 --- /dev/null +++ b/libstuff/x11/geometry/mulpt.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Point +mulpt(Point p, Point q) { + p.x *= q.x; + p.y *= q.y; + return p; +} diff --git a/libstuff/x11/geometry/rectaddpt.c b/libstuff/x11/geometry/rectaddpt.c new file mode 100644 index 00000000..a2c2f93a --- /dev/null +++ b/libstuff/x11/geometry/rectaddpt.c @@ -0,0 +1,13 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Rectangle +rectaddpt(Rectangle r, Point p) { + r.min.x += p.x; + r.max.x += p.x; + r.min.y += p.y; + r.max.y += p.y; + return r; +} diff --git a/libstuff/x11/geometry/rectsetorigin.c b/libstuff/x11/geometry/rectsetorigin.c new file mode 100644 index 00000000..e5662e00 --- /dev/null +++ b/libstuff/x11/geometry/rectsetorigin.c @@ -0,0 +1,15 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Rectangle +rectsetorigin(Rectangle r, Point p) { + Rectangle ret; + + ret.min.x = p.x; + ret.min.y = p.y; + ret.max.x = p.x + Dx(r); + ret.max.y = p.y + Dy(r); + return ret; +} diff --git a/libstuff/x11/geometry/rectsubpt.c b/libstuff/x11/geometry/rectsubpt.c new file mode 100644 index 00000000..0430854a --- /dev/null +++ b/libstuff/x11/geometry/rectsubpt.c @@ -0,0 +1,13 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Rectangle +rectsubpt(Rectangle r, Point p) { + r.min.x -= p.x; + r.max.x -= p.x; + r.min.y -= p.y; + r.max.y -= p.y; + return r; +} diff --git a/libstuff/x11/geometry/subpt.c b/libstuff/x11/geometry/subpt.c new file mode 100644 index 00000000..0ecd3a9b --- /dev/null +++ b/libstuff/x11/geometry/subpt.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Point +subpt(Point p, Point q) { + p.x -= q.x; + p.y -= q.y; + return p; +} diff --git a/libstuff/x11/ignored_xerrors.c b/libstuff/x11/ignored_xerrors.c new file mode 100644 index 00000000..55e5a70d --- /dev/null +++ b/libstuff/x11/ignored_xerrors.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +ErrorCode ignored_xerrors[] = { + { 0, }, +}; + diff --git a/libstuff/x11/images/allocimage.c b/libstuff/x11/images/allocimage.c new file mode 100644 index 00000000..ff4e17b0 --- /dev/null +++ b/libstuff/x11/images/allocimage.c @@ -0,0 +1,21 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Image* +allocimage(int w, int h, int depth) { + Image *img; + + img = emallocz(sizeof *img); + img->type = WImage; + img->xid = XCreatePixmap(display, scr.root.xid, w, h, depth); + img->gc = XCreateGC(display, img->xid, 0, nil); + img->colormap = scr.colormap; + img->visual = scr.visual; + if(depth == 32) + img->visual = scr.visual32; + img->depth = depth; + img->r = Rect(0, 0, w, h); + return img; +} diff --git a/libstuff/x11/images/copyimage.c b/libstuff/x11/images/copyimage.c new file mode 100644 index 00000000..f308e683 --- /dev/null +++ b/libstuff/x11/images/copyimage.c @@ -0,0 +1,13 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +copyimage(Image *dst, Rectangle r, Image *src, Point p) { + XCopyArea(display, + src->xid, dst->xid, + dst->gc, + r.min.x, r.min.y, Dx(r), Dy(r), + p.x, p.y); +} diff --git a/libstuff/x11/images/freeimage.c b/libstuff/x11/images/freeimage.c new file mode 100644 index 00000000..9a1e2639 --- /dev/null +++ b/libstuff/x11/images/freeimage.c @@ -0,0 +1,18 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +freeimage(Image *img) { + if(img == nil) + return; + + assert(img->type == WImage); + + if(img->xft) + XftDrawDestroy(img->xft); + XFreePixmap(display, img->xid); + XFreeGC(display, img->gc); + free(img); +} diff --git a/libstuff/x11/images/xftdrawable.c b/libstuff/x11/images/xftdrawable.c new file mode 100644 index 00000000..9bca2f1b --- /dev/null +++ b/libstuff/x11/images/xftdrawable.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +XftDraw* +xftdrawable(Image *img) { + if(img->xft == nil) + img->xft = XftDrawCreate(display, img->xid, img->visual, img->colormap); + return img->xft; +} diff --git a/libstuff/x11/initdisplay.c b/libstuff/x11/initdisplay.c new file mode 100644 index 00000000..9cf9c03b --- /dev/null +++ b/libstuff/x11/initdisplay.c @@ -0,0 +1,84 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +int (*xlib_errorhandler) (Display*, XErrorEvent*); + +Map windowmap; +Map atommap; +MapEnt* wbucket[137]; +MapEnt* abucket[137]; + +static int +Afmt(Fmt *f) { + Atom a; + char *s; + int i; + + a = va_arg(f->args, Atom); + s = XGetAtomName(display, a); + i = fmtprint(f, "%s", s); + free(s); + return i; +} + +static int +Pfmt(Fmt *f) { + Point p; + + p = va_arg(f->args, Point); + return fmtprint(f, "(%d,%d)", p.x, p.y); +} + +static int +Rfmt(Fmt *f) { + Rectangle r; + + r = va_arg(f->args, Rectangle); + return fmtprint(f, "%P+%dx%d", r.min, Dx(r), Dy(r)); +} + +static int +Wfmt(Fmt *f) { + Window *w; + + w = va_arg(f->args, Window*); + return fmtprint(f, "0x%ulx", w->xid); +} + +void +initdisplay(void) { + display = XOpenDisplay(nil); + if(display == nil) + fatal("Can't open display"); + scr.screen = DefaultScreen(display); + scr.colormap = DefaultColormap(display, scr.screen); + scr.visual = DefaultVisual(display, scr.screen); + scr.visual32 = DefaultVisual(display, scr.screen); + scr.gc = DefaultGC(display, scr.screen); + scr.depth = DefaultDepth(display, scr.screen); + + scr.white = WhitePixel(display, scr.screen); + scr.black = BlackPixel(display, scr.screen); + + scr.root.xid = RootWindow(display, scr.screen); + scr.root.r = Rect(0, 0, + DisplayWidth(display, scr.screen), + DisplayHeight(display, scr.screen)); + scr.rect = scr.root.r; + + scr.root.parent = &scr.root; + + windowmap.bucket = wbucket; + windowmap.nhash = nelem(wbucket); + atommap.bucket = abucket; + atommap.nhash = nelem(abucket); + + fmtinstall('A', Afmt); + fmtinstall('R', Rfmt); + fmtinstall('P', Pfmt); + fmtinstall('W', Wfmt); + + xlib_errorhandler = XSetErrorHandler(errorhandler); +} diff --git a/libstuff/x11/insanity/gravitate.c b/libstuff/x11/insanity/gravitate.c new file mode 100644 index 00000000..81a4d1f1 --- /dev/null +++ b/libstuff/x11/insanity/gravitate.c @@ -0,0 +1,19 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Rectangle +gravitate(Rectangle rc, Rectangle rf, Point grav) { + Point d; + + /* Get delta between frame and client rectangles */ + d = subpt(subpt(rf.max, rf.min), + subpt(rc.max, rc.min)); + + /* Divide by 2 and apply gravity */ + d = divpt(d, Pt(2, 2)); + d = mulpt(d, grav); + + return rectsubpt(rc, d); +} diff --git a/libstuff/x11/insanity/sethints.c b/libstuff/x11/insanity/sethints.c new file mode 100644 index 00000000..c5b6e685 --- /dev/null +++ b/libstuff/x11/insanity/sethints.c @@ -0,0 +1,99 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +sethints(Window *w) { + XSizeHints xs; + XWMHints *wmh; + WinHints *h; + Point p; + long size; + + if(w->hints == nil) + w->hints = emalloc(sizeof *h); + + h = w->hints; + memset(h, 0, sizeof *h); + + h->max = Pt(INT_MAX, INT_MAX); + h->inc = Pt(1,1); + + wmh = XGetWMHints(display, w->xid); + if(wmh) { + if(wmh->flags & WindowGroupHint) + h->group = wmh->window_group; + free(wmh); + } + + if(!XGetWMNormalHints(display, w->xid, &xs, &size)) + return; + + if(xs.flags & PMinSize) { + h->min.x = xs.min_width; + h->min.y = xs.min_height; + } + if(xs.flags & PMaxSize) { + h->max.x = xs.max_width; + h->max.y = xs.max_height; + } + + /* Goddamn buggy clients. */ + if(h->max.x < h->min.x) + h->max.x = h->min.x; + if(h->max.y < h->min.y) + h->max.y = h->min.y; + + h->base = h->min; + if(xs.flags & PBaseSize) { + p.x = xs.base_width; + p.y = xs.base_height; + h->base = p; + h->baspect = p; + } + + if(xs.flags & PResizeInc) { + h->inc.x = max(xs.width_inc, 1); + h->inc.y = max(xs.height_inc, 1); + } + + if(xs.flags & PAspect) { + h->aspect.min.x = xs.min_aspect.x; + h->aspect.min.y = xs.min_aspect.y; + h->aspect.max.x = xs.max_aspect.x; + h->aspect.max.y = xs.max_aspect.y; + } + + h->position = (xs.flags & (USPosition|PPosition)) != 0; + + if(!(xs.flags & PWinGravity)) + xs.win_gravity = NorthWestGravity; + p = ZP; + switch (xs.win_gravity) { + case EastGravity: + case CenterGravity: + case WestGravity: + p.y = 1; + break; + case SouthEastGravity: + case SouthGravity: + case SouthWestGravity: + p.y = 2; + break; + } + switch (xs.win_gravity) { + case NorthGravity: + case CenterGravity: + case SouthGravity: + p.x = 1; + break; + case NorthEastGravity: + case EastGravity: + case SouthEastGravity: + p.x = 2; + break; + } + h->grav = p; + h->gravstatic = (xs.win_gravity == StaticGravity); +} diff --git a/libstuff/x11/insanity/sizehint.c b/libstuff/x11/insanity/sizehint.c new file mode 100644 index 00000000..fe65927a --- /dev/null +++ b/libstuff/x11/insanity/sizehint.c @@ -0,0 +1,42 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Rectangle +sizehint(WinHints *h, Rectangle r) { + Point p, aspect, origin; + + if(h == nil) + return r; + + origin = r.min; + r = rectsubpt(r, origin); + + /* Min/max */ + r.max.x = max(r.max.x, h->min.x); + r.max.y = max(r.max.y, h->min.y); + r.max.x = min(r.max.x, h->max.x); + r.max.y = min(r.max.y, h->max.y); + + /* Increment */ + p = subpt(r.max, h->base); + r.max.x -= p.x % h->inc.x; + r.max.y -= p.y % h->inc.y; + + /* Aspect */ + p = subpt(r.max, h->baspect); + p.y = max(p.y, 1); + + aspect = h->aspect.min; + if(p.x * aspect.y / p.y < aspect.x) + r.max.y = h->baspect.y + + p.x * aspect.y / aspect.x; + + aspect = h->aspect.max; + if(p.x * aspect.y / p.y > aspect.x) + r.max.x = h->baspect.x + + p.y * aspect.x / aspect.y; + + return rectaddpt(r, origin); +} diff --git a/libstuff/x11/keyboard/grabkeyboard.c b/libstuff/x11/keyboard/grabkeyboard.c new file mode 100644 index 00000000..6b599c4e --- /dev/null +++ b/libstuff/x11/keyboard/grabkeyboard.c @@ -0,0 +1,12 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +int +grabkeyboard(Window *w) { + + return XGrabKeyboard(display, w->xid, true /* owner events */, + GrabModeAsync, GrabModeAsync, CurrentTime + ) == GrabSuccess; +} diff --git a/libstuff/x11/keyboard/ungrabkeyboard.c b/libstuff/x11/keyboard/ungrabkeyboard.c new file mode 100644 index 00000000..6e650d15 --- /dev/null +++ b/libstuff/x11/keyboard/ungrabkeyboard.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +ungrabkeyboard(void) { + XUngrabKeyboard(display, CurrentTime); +} diff --git a/libstuff/x11/keys/keycode.c b/libstuff/x11/keys/keycode.c new file mode 100644 index 00000000..4e4d15ea --- /dev/null +++ b/libstuff/x11/keys/keycode.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +KeyCode +keycode(char *name) { + return XKeysymToKeycode(display, XStringToKeysym(name)); +} diff --git a/libstuff/x11/keys/parsekey.c b/libstuff/x11/keys/parsekey.c new file mode 100644 index 00000000..c9adf56e --- /dev/null +++ b/libstuff/x11/keys/parsekey.c @@ -0,0 +1,46 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +typedef struct KMask KMask; + +static struct KMask { + int mask; + const char* name; +} masks[] = { + {ShiftMask, "Shift"}, + {ControlMask, "Control"}, + {Mod1Mask, "Mod1"}, + {Mod2Mask, "Mod2"}, + {Mod3Mask, "Mod3"}, + {Mod4Mask, "Mod4"}, + {Mod5Mask, "Mod5"}, + {0,} +}; + +bool +parsekey(char *str, int *mask, char **key) { + static char *keys[16]; + KMask *m; + int i, nkeys; + + *mask = 0; + nkeys = tokenize(keys, nelem(keys), str, '-'); + for(i=0; i < nkeys; i++) { + for(m=masks; m->mask; m++) + if(!strcasecmp(m->name, keys[i])) { + *mask |= m->mask; + goto next; + } + break; + next: continue; + } + if(key) { + if(nkeys) + *key = keys[i]; + return i == nkeys - 1; + } + else + return i == nkeys; +} diff --git a/libstuff/x11/mouse/grabpointer.c b/libstuff/x11/mouse/grabpointer.c new file mode 100644 index 00000000..fffb3590 --- /dev/null +++ b/libstuff/x11/mouse/grabpointer.c @@ -0,0 +1,16 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +int +grabpointer(Window *w, Window *confine, Cursor cur, int mask) { + XWindow cw; + + cw = None; + if(confine) + cw = confine->xid; + return XGrabPointer(display, w->xid, false /* owner events */, mask, + GrabModeAsync, GrabModeAsync, cw, cur, CurrentTime + ) == GrabSuccess; +} diff --git a/libstuff/x11/mouse/pointerscreen.c b/libstuff/x11/mouse/pointerscreen.c new file mode 100644 index 00000000..a09e0de8 --- /dev/null +++ b/libstuff/x11/mouse/pointerscreen.c @@ -0,0 +1,15 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +int +pointerscreen(void) { + XWindow win; + Point pt; + uint ui; + int i; + + return XQueryPointer(display, scr.root.xid, &win, &win, &i, &i, + &pt.x, &pt.y, &ui); +} diff --git a/libstuff/x11/mouse/querypointer.c b/libstuff/x11/mouse/querypointer.c new file mode 100644 index 00000000..d1b5ada7 --- /dev/null +++ b/libstuff/x11/mouse/querypointer.c @@ -0,0 +1,15 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Point +querypointer(Window *w) { + XWindow win; + Point pt; + uint ui; + int i; + + XQueryPointer(display, w->xid, &win, &win, &i, &i, &pt.x, &pt.y, &ui); + return pt; +} diff --git a/libstuff/x11/mouse/translate.c b/libstuff/x11/mouse/translate.c new file mode 100644 index 00000000..2c39a309 --- /dev/null +++ b/libstuff/x11/mouse/translate.c @@ -0,0 +1,14 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Point +translate(Window *src, Window *dst, Point sp) { + Point pt; + XWindow w; + + XTranslateCoordinates(display, src->xid, dst->xid, sp.x, sp.y, + &pt.x, &pt.y, &w); + return pt; +} diff --git a/libstuff/x11/mouse/ungrabpointer.c b/libstuff/x11/mouse/ungrabpointer.c new file mode 100644 index 00000000..a0a2730d --- /dev/null +++ b/libstuff/x11/mouse/ungrabpointer.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +ungrabpointer(void) { + XUngrabPointer(display, CurrentTime); +} diff --git a/libstuff/x11/mouse/warppointer.c b/libstuff/x11/mouse/warppointer.c new file mode 100644 index 00000000..8de857a9 --- /dev/null +++ b/libstuff/x11/mouse/warppointer.c @@ -0,0 +1,23 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +warppointer(Point pt) { + /* Nasty kludge for xephyr, xnest. */ + static int havereal = -1; + static char* real; + + if(havereal == -1) { + real = getenv("REALDISPLAY"); + havereal = real != nil; + } + if(havereal) + system(sxprint("DISPLAY=%s wiwarp %d %d", real, pt.x, pt.y)); + + XWarpPointer(display, + /* src, dest w */ None, scr.root.xid, + /* src_rect */ 0, 0, 0, 0, + /* target */ pt.x, pt.y); +} diff --git a/libstuff/x11/properties/changeprop_char.c b/libstuff/x11/properties/changeprop_char.c new file mode 100644 index 00000000..0ebd55d1 --- /dev/null +++ b/libstuff/x11/properties/changeprop_char.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +changeprop_char(Window *w, char *prop, char *type, char data[], int len) { + changeproperty(w, prop, type, 8, (uchar*)data, len); +} diff --git a/libstuff/x11/properties/changeprop_long.c b/libstuff/x11/properties/changeprop_long.c new file mode 100644 index 00000000..6ac2234e --- /dev/null +++ b/libstuff/x11/properties/changeprop_long.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +changeprop_long(Window *w, char *prop, char *type, long data[], int len) { + changeproperty(w, prop, type, 32, (uchar*)data, len); +} diff --git a/libstuff/x11/properties/changeprop_short.c b/libstuff/x11/properties/changeprop_short.c new file mode 100644 index 00000000..64c22325 --- /dev/null +++ b/libstuff/x11/properties/changeprop_short.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +changeprop_short(Window *w, char *prop, char *type, short data[], int len) { + changeproperty(w, prop, type, 16, (uchar*)data, len); +} diff --git a/libstuff/x11/properties/changeprop_string.c b/libstuff/x11/properties/changeprop_string.c new file mode 100644 index 00000000..b8761790 --- /dev/null +++ b/libstuff/x11/properties/changeprop_string.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +changeprop_string(Window *w, char *prop, char *string) { + changeprop_char(w, prop, "UTF8_STRING", string, strlen(string)); +} diff --git a/libstuff/x11/properties/changeprop_textlist.c b/libstuff/x11/properties/changeprop_textlist.c new file mode 100644 index 00000000..0c9f052c --- /dev/null +++ b/libstuff/x11/properties/changeprop_textlist.c @@ -0,0 +1,23 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +changeprop_textlist(Window *w, char *prop, char *type, char *data[]) { + char **p, *s, *t; + int len, n; + + len = 0; + for(p=data; *p; p++) + len += strlen(*p) + 1; + s = emalloc(len); + t = s; + for(p=data; *p; p++) { + n = strlen(*p) + 1; + memcpy(t, *p, n); + t += n; + } + changeprop_char(w, prop, type, s, len); + free(s); +} diff --git a/libstuff/x11/properties/changeprop_ulong.c b/libstuff/x11/properties/changeprop_ulong.c new file mode 100644 index 00000000..fdf92b9f --- /dev/null +++ b/libstuff/x11/properties/changeprop_ulong.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +changeprop_ulong(Window *w, char *prop, char *type, ulong data[], int len) { + changeproperty(w, prop, type, 32, (uchar*)data, len); +} diff --git a/libstuff/x11/properties/changeproperty.c b/libstuff/x11/properties/changeproperty.c new file mode 100644 index 00000000..052b12ff --- /dev/null +++ b/libstuff/x11/properties/changeproperty.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +changeproperty(Window *w, char *prop, char *type, + int width, uchar data[], int n) { + XChangeProperty(display, w->xid, xatom(prop), xatom(type), width, + PropModeReplace, data, n); +} diff --git a/libstuff/x11/properties/delproperty.c b/libstuff/x11/properties/delproperty.c new file mode 100644 index 00000000..93305347 --- /dev/null +++ b/libstuff/x11/properties/delproperty.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +delproperty(Window *w, char *prop) { + XDeleteProperty(display, w->xid, xatom(prop)); +} diff --git a/libstuff/x11/properties/getprop.c b/libstuff/x11/properties/getprop.c new file mode 100644 index 00000000..839ad2ef --- /dev/null +++ b/libstuff/x11/properties/getprop.c @@ -0,0 +1,28 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +ulong +getprop(Window *w, char *prop, char *type, Atom *actual, int *format, + ulong offset, uchar **ret, ulong length) { + Atom typea; + ulong n, extra; + int status; + + typea = (type ? xatom(type) : 0L); + + status = XGetWindowProperty(display, w->xid, + xatom(prop), offset, length, false /* delete */, + typea, actual, format, &n, &extra, ret); + + if(status != Success) { + *ret = nil; + return 0; + } + if(n == 0) { + free(*ret); + *ret = nil; + } + return n; +} diff --git a/libstuff/x11/properties/getprop_long.c b/libstuff/x11/properties/getprop_long.c new file mode 100644 index 00000000..708c81de --- /dev/null +++ b/libstuff/x11/properties/getprop_long.c @@ -0,0 +1,19 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +ulong +getprop_long(Window *w, char *prop, char *type, + ulong offset, long **ret, ulong length) { + Atom actual; + ulong n; + int format; + + n = getprop(w, prop, type, &actual, &format, offset, (uchar**)ret, length); + if(n == 0 || format == 32 && xatom(type) == actual) + return n; + free(*ret); + *ret = 0; + return 0; +} diff --git a/libstuff/x11/properties/getprop_string.c b/libstuff/x11/properties/getprop_string.c new file mode 100644 index 00000000..7b8ebcbd --- /dev/null +++ b/libstuff/x11/properties/getprop_string.c @@ -0,0 +1,19 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +char* +getprop_string(Window *w, char *name) { + char **list, *str; + int n; + + str = nil; + + n = getprop_textlist(w, name, &list); + if(n > 0) + str = estrdup(*list); + freestringlist(list); + + return str; +} diff --git a/libstuff/x11/properties/getprop_textlist.c b/libstuff/x11/properties/getprop_textlist.c new file mode 100644 index 00000000..4cde6802 --- /dev/null +++ b/libstuff/x11/properties/getprop_textlist.c @@ -0,0 +1,22 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +int +getprop_textlist(Window *w, char *name, char **ret[]) { + XTextProperty prop; + char **list; + int n; + + *ret = nil; + n = 0; + + XGetTextProperty(display, w->xid, &prop, xatom(name)); + if(prop.nitems > 0) { + if(Xutf8TextPropertyToTextList(display, &prop, &list, &n) == Success) + *ret = list; + XFree(prop.value); + } + return n; +} diff --git a/libstuff/x11/properties/getprop_ulong.c b/libstuff/x11/properties/getprop_ulong.c new file mode 100644 index 00000000..1a7a8b68 --- /dev/null +++ b/libstuff/x11/properties/getprop_ulong.c @@ -0,0 +1,10 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +ulong +getprop_ulong(Window *w, char *prop, char *type, + ulong offset, ulong **ret, ulong length) { + return getprop_long(w, prop, type, offset, (long**)ret, length); +} diff --git a/libstuff/x11/properties/getproperty.c b/libstuff/x11/properties/getproperty.c new file mode 100644 index 00000000..685ae533 --- /dev/null +++ b/libstuff/x11/properties/getproperty.c @@ -0,0 +1,12 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +ulong +getproperty(Window *w, char *prop, char *type, Atom *actual, + ulong offset, uchar **ret, ulong length) { + int format; + + return getprop(w, prop, type, actual, &format, offset, ret, length); +} diff --git a/libstuff/x11/properties/strlistdup.c b/libstuff/x11/properties/strlistdup.c new file mode 100644 index 00000000..083f0ffa --- /dev/null +++ b/libstuff/x11/properties/strlistdup.c @@ -0,0 +1,28 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +char** +strlistdup(char *list[]) { + char **p; + char *q; + int i, m, n; + + n = 0; + m = 0; + for(p=list; *p; p++, n++) + m += strlen(*p) + 1; + + p = malloc((n+1) * sizeof(*p) + m); + q = (char*)&p[n+1]; + + for(i=0; i < n; i++) { + p[i] = q; + m = strlen(list[i]) + 1; + memcpy(q, list[i], m); + q += m; + } + p[n] = nil; + return p; +} diff --git a/libstuff/x11/sendevent.c b/libstuff/x11/sendevent.c new file mode 100644 index 00000000..239f4f14 --- /dev/null +++ b/libstuff/x11/sendevent.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +void +sendevent(Window *w, bool propegate, long mask, XEvent *e) { + XSendEvent(display, w->xid, propegate, mask, e); +} diff --git a/libstuff/x11/sendmessage.c b/libstuff/x11/sendmessage.c new file mode 100644 index 00000000..f95b2e1e --- /dev/null +++ b/libstuff/x11/sendmessage.c @@ -0,0 +1,20 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +void +sendmessage(Window *w, char *name, long l0, long l1, long l2, long l3, long l4) { + XClientMessageEvent e; + + e.type = ClientMessage; + e.window = w->xid; + e.message_type = xatom(name); + e.format = 32; + e.data.l[0] = l0; + e.data.l[1] = l1; + e.data.l[2] = l2; + e.data.l[3] = l3; + e.data.l[4] = l4; + sendevent(w, false, NoEventMask, (XEvent*)&e); +} diff --git a/libstuff/x11/setgccol.c b/libstuff/x11/setgccol.c new file mode 100644 index 00000000..a4b09bbc --- /dev/null +++ b/libstuff/x11/setgccol.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +void +setgccol(Image *dst, Color col) { + XSetForeground(display, dst->gc, col.pixel); +} diff --git a/libstuff/x11/shape/setshapemask.c b/libstuff/x11/shape/setshapemask.c new file mode 100644 index 00000000..910a605f --- /dev/null +++ b/libstuff/x11/shape/setshapemask.c @@ -0,0 +1,11 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +setshapemask(Window *dst, Image *src, Point pt) { + /* Assumes that we have the shape extension... */ + XShapeCombineMask (display, dst->xid, + ShapeBounding, pt.x, pt.y, src->xid, ShapeSet); +} diff --git a/libstuff/x11/sync.c b/libstuff/x11/sync.c new file mode 100644 index 00000000..3aa0e780 --- /dev/null +++ b/libstuff/x11/sync.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +void +sync(void) { + XSync(display, false); +} diff --git a/libstuff/x11/text/freefont.c b/libstuff/x11/text/freefont.c new file mode 100644 index 00000000..7bd5436d --- /dev/null +++ b/libstuff/x11/text/freefont.c @@ -0,0 +1,23 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +freefont(Font *f) { + switch(f->type) { + case FFontSet: + XFreeFontSet(display, f->font.set); + break; + case FXft: + XftFontClose(display, f->font.xft); + break; + case FX11: + XFreeFont(display, f->font.x11); + break; + default: + break; + } + free(f->name); + free(f); +} diff --git a/libstuff/x11/text/labelh.c b/libstuff/x11/text/labelh.c new file mode 100644 index 00000000..8bb5f9b4 --- /dev/null +++ b/libstuff/x11/text/labelh.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +uint +labelh(Font *font) { + return max(font->height + font->descent + font->pad.min.y + font->pad.max.y, 1); +} diff --git a/libstuff/x11/text/loadfont.c b/libstuff/x11/text/loadfont.c new file mode 100644 index 00000000..c1baff78 --- /dev/null +++ b/libstuff/x11/text/loadfont.c @@ -0,0 +1,66 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Font* +loadfont(char *name) { + XFontStruct **xfonts; + char **missing, **font_names; + Biobuf *b; + Font *f; + int n, i; + + missing = nil; + f = emallocz(sizeof *f); + f->name = estrdup(name); + if(!strncmp(f->name, "xft:", 4)) { + f->type = FXft; + + f->font.xft = XftFontOpenXlfd(display, scr.screen, f->name + 4); + if(!f->font.xft) + f->font.xft = XftFontOpenName(display, scr.screen, f->name + 4); + if(!f->font.xft) + goto error; + + f->ascent = f->font.xft->ascent; + f->descent = f->font.xft->descent; + }else { + f->font.set = XCreateFontSet(display, name, &missing, &n, nil); + if(missing) { + if(false) { + b = Bfdopen(dup(2), O_WRONLY); + Bprint(b, "%s: note: missing fontset%s for '%s':", argv0, + (n > 1 ? "s" : ""), name); + for(i = 0; i < n; i++) + Bprint(b, "%s %s", (i ? "," : ""), missing[i]); + Bprint(b, "\n"); + Bterm(b); + } + freestringlist(missing); + } + + if(f->font.set) { + f->type = FFontSet; + XFontsOfFontSet(f->font.set, &xfonts, &font_names); + f->ascent = xfonts[0]->ascent; + f->descent = xfonts[0]->descent; + }else { + f->type = FX11; + f->font.x11 = XLoadQueryFont(display, name); + if(!f->font.x11) + goto error; + + f->ascent = f->font.x11->ascent; + f->descent = f->font.x11->descent; + } + } + f->height = f->ascent + f->descent; + return f; + +error: + fprint(2, "%s: cannot load font: %s\n", argv0, name); + f->type = 0; + freefont(f); + return nil; +} diff --git a/libstuff/x11/text/textextents_l.c b/libstuff/x11/text/textextents_l.c new file mode 100644 index 00000000..9b476996 --- /dev/null +++ b/libstuff/x11/text/textextents_l.c @@ -0,0 +1,34 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Rectangle +textextents_l(Font *font, char *text, uint len, int *offset) { + Rectangle rect; + XRectangle r; + XGlyphInfo i; + int unused; + + if(!offset) + offset = &unused; + + switch(font->type) { + case FFontSet: + *offset = Xutf8TextExtents(font->font.set, text, len, &r, nil); + return Rect(r.x, -r.y - r.height, r.x + r.width, -r.y); + case FXft: + XftTextExtentsUtf8(display, font->font.xft, (uchar*)text, len, &i); + *offset = i.xOff; + return Rect(-i.x, i.y - i.height, -i.x + i.width, i.y); + case FX11: + rect = ZR; + rect.max.x = XTextWidth(font->font.x11, text, len); + rect.max.y = font->ascent; + *offset = rect.max.x; + return rect; + default: + die("Invalid font type"); + return ZR; /* shut up ken */ + } +} diff --git a/libstuff/x11/text/textwidth.c b/libstuff/x11/text/textwidth.c new file mode 100644 index 00000000..6fb5da33 --- /dev/null +++ b/libstuff/x11/text/textwidth.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +uint +textwidth(Font *font, char *text) { + return textwidth_l(font, text, strlen(text)); +} diff --git a/libstuff/x11/text/textwidth_l.c b/libstuff/x11/text/textwidth_l.c new file mode 100644 index 00000000..5edb25e1 --- /dev/null +++ b/libstuff/x11/text/textwidth_l.c @@ -0,0 +1,12 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +uint +textwidth_l(Font *font, char *text, uint len) { + Rectangle r; + + r = textextents_l(font, text, len, nil); + return Dx(r); +} diff --git a/libstuff/x11/windows/configwin.c b/libstuff/x11/windows/configwin.c new file mode 100644 index 00000000..ca8c6806 --- /dev/null +++ b/libstuff/x11/windows/configwin.c @@ -0,0 +1,22 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +configwin(Window *w, Rectangle r, int border) { + XWindowChanges wc; + + if(eqrect(r, w->r) && border == w->border) + return; + + wc.x = r.min.x - border; + wc.y = r.min.y - border; + wc.width = Dx(r); + wc.height = Dy(r); + wc.border_width = border; + XConfigureWindow(display, w->xid, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); + + w->r = r; + w->border = border; +} diff --git a/libstuff/x11/windows/createwindow.c b/libstuff/x11/windows/createwindow.c new file mode 100644 index 00000000..e119caaf --- /dev/null +++ b/libstuff/x11/windows/createwindow.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Window* +createwindow(Window *parent, Rectangle r, int depth, uint class, WinAttr *wa, int valmask) { + return createwindow_visual(parent, r, depth, scr.visual, class, wa, valmask); +} diff --git a/libstuff/x11/windows/createwindow_visual.c b/libstuff/x11/windows/createwindow_visual.c new file mode 100644 index 00000000..e30bcb42 --- /dev/null +++ b/libstuff/x11/windows/createwindow_visual.c @@ -0,0 +1,33 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Window* +createwindow_visual(Window *parent, Rectangle r, + int depth, Visual *vis, uint class, + WinAttr *wa, int valmask) { + Window *w; + + assert(parent->type == WWindow); + + w = emallocz(sizeof *w); + w->visual = vis; + w->type = WWindow; + w->parent = parent; + if(valmask & CWColormap) + w->colormap = wa->colormap; + + w->xid = XCreateWindow(display, parent->xid, r.min.x, r.min.y, Dx(r), Dy(r), + 0 /* border */, depth, class, vis, valmask, wa); +#if 0 + print("createwindow_visual(%W, %R, %d, %p, %ud, %p, %x) = %W\n", + parent, r, depth, vis, class, wa, valmask, w); +#endif + if(class != InputOnly) + w->gc = XCreateGC(display, w->xid, 0, nil); + + w->r = r; + w->depth = depth; + return w; +} diff --git a/libstuff/x11/windows/destroywindow.c b/libstuff/x11/windows/destroywindow.c new file mode 100644 index 00000000..e75fa9cf --- /dev/null +++ b/libstuff/x11/windows/destroywindow.c @@ -0,0 +1,16 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +destroywindow(Window *w) { + assert(w->type == WWindow); + sethandler(w, nil); + if(w->xft) + XftDrawDestroy(w->xft); + if(w->gc) + XFreeGC(display, w->gc); + XDestroyWindow(display, w->xid); + free(w); +} diff --git a/libstuff/x11/windows/findwin.c b/libstuff/x11/windows/findwin.c new file mode 100644 index 00000000..ff012767 --- /dev/null +++ b/libstuff/x11/windows/findwin.c @@ -0,0 +1,14 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Window* +findwin(XWindow w) { + void **e; + + e = map_get(&windowmap, (ulong)w, false); + if(e) + return *e; + return nil; +} diff --git a/libstuff/x11/windows/getwinrect.c b/libstuff/x11/windows/getwinrect.c new file mode 100644 index 00000000..485c5b3c --- /dev/null +++ b/libstuff/x11/windows/getwinrect.c @@ -0,0 +1,15 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Rectangle +getwinrect(Window *w) { + XWindowAttributes wa; + Point p; + + if(!XGetWindowAttributes(display, w->xid, &wa)) + return ZR; + p = translate(w, &scr.root, ZP); + return rectaddpt(Rect(0, 0, wa.width, wa.height), p); +} diff --git a/libstuff/x11/windows/lowerwin.c b/libstuff/x11/windows/lowerwin.c new file mode 100644 index 00000000..3647d3e4 --- /dev/null +++ b/libstuff/x11/windows/lowerwin.c @@ -0,0 +1,10 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +lowerwin(Window *w) { + assert(w->type == WWindow); + XLowerWindow(display, w->xid); +} diff --git a/libstuff/x11/windows/mapwin.c b/libstuff/x11/windows/mapwin.c new file mode 100644 index 00000000..6d8587d6 --- /dev/null +++ b/libstuff/x11/windows/mapwin.c @@ -0,0 +1,15 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +int +mapwin(Window *w) { + assert(w->type == WWindow); + if(!w->mapped) { + XMapWindow(display, w->xid); + w->mapped = 1; + return 1; + } + return 0; +} diff --git a/libstuff/x11/windows/movewin.c b/libstuff/x11/windows/movewin.c new file mode 100644 index 00000000..281561fe --- /dev/null +++ b/libstuff/x11/windows/movewin.c @@ -0,0 +1,13 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +movewin(Window *w, Point pt) { + Rectangle r; + + assert(w->type == WWindow); + r = rectsetorigin(w->r, pt); + reshapewin(w, r); +} diff --git a/libstuff/x11/windows/raisewin.c b/libstuff/x11/windows/raisewin.c new file mode 100644 index 00000000..36bb48c0 --- /dev/null +++ b/libstuff/x11/windows/raisewin.c @@ -0,0 +1,10 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +raisewin(Window *w) { + assert(w->type == WWindow); + XRaiseWindow(display, w->xid); +} diff --git a/libstuff/x11/windows/reparentwindow.c b/libstuff/x11/windows/reparentwindow.c new file mode 100644 index 00000000..fc6bd904 --- /dev/null +++ b/libstuff/x11/windows/reparentwindow.c @@ -0,0 +1,13 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +reparentwindow(Window *w, Window *par, Point p) { + assert(w->type == WWindow); + XReparentWindow(display, w->xid, par->xid, p.x, p.y); + w->parent = par; + w->r = rectsubpt(w->r, w->r.min); + w->r = rectaddpt(w->r, p); +} diff --git a/libstuff/x11/windows/reshapewin.c b/libstuff/x11/windows/reshapewin.c new file mode 100644 index 00000000..6b2b61f4 --- /dev/null +++ b/libstuff/x11/windows/reshapewin.c @@ -0,0 +1,12 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +reshapewin(Window *w, Rectangle r) { + assert(w->type == WWindow); + assert(Dx(r) > 0 && Dy(r) > 0); /* Rather than an X error. */ + + configwin(w, r, w->border); +} diff --git a/libstuff/x11/windows/selectinput.c b/libstuff/x11/windows/selectinput.c new file mode 100644 index 00000000..330a2518 --- /dev/null +++ b/libstuff/x11/windows/selectinput.c @@ -0,0 +1,9 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +selectinput(Window *w, long mask) { + XSelectInput(display, w->xid, mask); +} diff --git a/libstuff/x11/windows/setborder.c b/libstuff/x11/windows/setborder.c new file mode 100644 index 00000000..d2a98755 --- /dev/null +++ b/libstuff/x11/windows/setborder.c @@ -0,0 +1,14 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +setborder(Window *w, int width, Color col) { + + assert(w->type == WWindow); + if(width) + XSetWindowBorder(display, w->xid, col.pixel); + if(width != w->border) + configwin(w, w->r, width); +} diff --git a/libstuff/x11/windows/sethandler.c b/libstuff/x11/windows/sethandler.c new file mode 100644 index 00000000..5fdd5ea7 --- /dev/null +++ b/libstuff/x11/windows/sethandler.c @@ -0,0 +1,23 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Handlers* +sethandler(Window *w, Handlers *new) { + Handlers *old; + void **e; + + assert(w->type == WWindow); + assert((w->prev != nil && w->next != nil) || w->next == w->prev); + + if(new == nil) + map_rm(&windowmap, (ulong)w->xid); + else { + e = map_get(&windowmap, (ulong)w->xid, true); + *e = w; + } + old = w->handler; + w->handler = new; + return old; +} diff --git a/libstuff/x11/windows/setwinattr.c b/libstuff/x11/windows/setwinattr.c new file mode 100644 index 00000000..9bdaaf04 --- /dev/null +++ b/libstuff/x11/windows/setwinattr.c @@ -0,0 +1,10 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +void +setwinattr(Window *w, WinAttr *wa, int valmask) { + assert(w->type == WWindow); + XChangeWindowAttributes(display, w->xid, valmask, wa); +} diff --git a/libstuff/x11/windows/unmapwin.c b/libstuff/x11/windows/unmapwin.c new file mode 100644 index 00000000..417a8961 --- /dev/null +++ b/libstuff/x11/windows/unmapwin.c @@ -0,0 +1,16 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +int +unmapwin(Window *w) { + assert(w->type == WWindow); + if(w->mapped) { + XUnmapWindow(display, w->xid); + w->mapped = 0; + w->unmapped++; + return 1; + } + return 0; +} diff --git a/libstuff/x11/windows/window.c b/libstuff/x11/windows/window.c new file mode 100644 index 00000000..fce51fac --- /dev/null +++ b/libstuff/x11/windows/window.c @@ -0,0 +1,14 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "../x11.h" + +Window* +window(XWindow xw) { + Window *w; + + w = malloc(sizeof *w); + w->type = WWindow; + w->xid = xw; + return freelater(w); +} diff --git a/libstuff/x11/x11.c b/libstuff/x11/x11.c new file mode 100644 index 00000000..0ccc943e --- /dev/null +++ b/libstuff/x11/x11.c @@ -0,0 +1,12 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +const Point ZP = {0, 0}; +const Rectangle ZR = {{0, 0}, {0, 0}}; + +const Window _pointerwin = { .xid = PointerRoot }; +Window* const pointerwin = (Window*)&_pointerwin; + + diff --git a/libstuff/x11/x11.h b/libstuff/x11/x11.h new file mode 100644 index 00000000..f6e15d02 --- /dev/null +++ b/libstuff/x11/x11.h @@ -0,0 +1,31 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ + +#define _X11_VISIBLE +#define pointerwin __pointerwin +#include +#include +#include +#include +#include +#include +#include +#include +#undef pointerwin + +extern Map windowmap; +extern Map atommap; +extern MapEnt* wbucket[137]; +extern MapEnt* abucket[137]; + +extern int (*xlib_errorhandler) (Display*, XErrorEvent*); + +void configwin(Window*, Rectangle, int); +XPoint* convpts(Point*, int); +int errorhandler(Display*, XErrorEvent*); +ulong getprop(Window*, char*, char*, Atom*, int*, ulong, uchar**, ulong); +void setgccol(Image*, Color); +XftColor* xftcolor(Color); +XftDraw* xftdrawable(Image*); + diff --git a/libstuff/x11/xatom.c b/libstuff/x11/xatom.c new file mode 100644 index 00000000..d379879d --- /dev/null +++ b/libstuff/x11/xatom.c @@ -0,0 +1,14 @@ +/* Copyright ©2007-2010 Kris Maglione + * See LICENSE file for license details. + */ +#include "x11.h" + +Atom +xatom(char *name) { + void **e; + + e = hash_get(&atommap, name, true); + if(*e == nil) + *e = (void*)XInternAtom(display, name, false); + return (Atom)*e; +} diff --git a/cmd/wmii/xext.c b/libstuff/xext.c similarity index 97% rename from cmd/wmii/xext.c rename to libstuff/xext.c index ba851e5c..abece4a8 100644 --- a/cmd/wmii/xext.c +++ b/libstuff/xext.c @@ -2,10 +2,10 @@ * See LICENSE file for license details. */ #define _X11_VISIBLE -#include "dat.h" +#include +#include #include #include -#include "fns.h" #if RANDR_MAJOR < 1 # error XRandR versions less than 1.0 are not supported @@ -24,6 +24,7 @@ bool have_RandR; bool have_render; bool have_xinerama; int randr_eventbase; +Visual* render_visual; static void handle(XEvent *e, EvHandler h[], int base) { diff --git a/libwmii_hack/Makefile b/libwmii_hack/Makefile index ec1f0fb3..5c8e5fd9 100644 --- a/libwmii_hack/Makefile +++ b/libwmii_hack/Makefile @@ -1,15 +1,17 @@ ROOT= .. include ${ROOT}/mk/hdr.mk -hack.o hack.o_pic: util.c x11.c hack.h x11.h +hack.o hack.o_pic: util.c hack.h x11.h CFLAGS += $(INCX11) SOLDFLAGS += $(LIBX11) TARG = libwmii_hack -OBJ = hack -# util \ -# x11 +# Can't just link libstuff here. We need PIC objects. +OBJ = hack \ + ../libstuff/util/getbase \ + ../libstuff/util/getlong \ + ../libstuff/util/tokenize include ${ROOT}/mk/so.mk diff --git a/libwmii_hack/hack.h b/libwmii_hack/hack.h index 8622d98d..58e5ce46 100644 --- a/libwmii_hack/hack.h +++ b/libwmii_hack/hack.h @@ -12,13 +12,13 @@ typedef unsigned char uchar; #include #include #include -#include +#include #include #define strdup my_strdup +#define smprint my_smprint +#define vsmprint my_vsmprint -static int getlong(const char*, long*); -static uint tokenize(char*[], uint, char*, char); static char* smprint(const char*, ...); static char* vsmprint(const char*, va_list); static char* strdup(const char*); diff --git a/libwmii_hack/util.c b/libwmii_hack/util.c index 32988e48..f990176e 100644 --- a/libwmii_hack/util.c +++ b/libwmii_hack/util.c @@ -2,64 +2,6 @@ #include #include -#define strbcmp(str, const) (strncmp((str), (const), sizeof(const)-1)) -static int -getbase(const char **s) { - const char *p; - - p = *s; - if(!strbcmp(p, "0x")) { - *s += 2; - return 16; - } - if(isdigit(p[0])) { - if(p[1] == 'r') { - *s += 2; - return p[0] - '0'; - } - if(isdigit(p[1]) && p[2] == 'r') { - *s += 3; - return 10*(p[0]-'0') + (p[1]-'0'); - } - } - if(p[0] == '0') { - *s += 1; - return 8; - } - return 10; -} - -static int -getlong(const char *s, long *ret) { - const char *end; - char *rend; - int base; - - end = s+strlen(s); - base = getbase(&s); - - *ret = strtol(s, &rend, base); - return (end == rend); -} - -static uint -tokenize(char *res[], uint reslen, char *str, char delim) { - char *s; - uint i; - - i = 0; - s = str; - while(i < reslen && *s) { - while(*s == delim) - *(s++) = '\0'; - if(*s) - res[i++] = s; - while(*s && *s != delim) - s++; - } - return i; -} - static char* vsmprint(const char *fmt, va_list ap) { va_list al; diff --git a/libwmii_hack/x11.c b/libwmii_hack/x11.c index e3e097fc..b9761c2e 100644 --- a/libwmii_hack/x11.c +++ b/libwmii_hack/x11.c @@ -2,6 +2,7 @@ * See LICENSE file for license details. */ #include +#include "x11.h" /* Misc */ static Atom diff --git a/mk/gcc.mk b/mk/gcc.mk index b37b59cf..fda4e89a 100644 --- a/mk/gcc.mk +++ b/mk/gcc.mk @@ -8,7 +8,7 @@ DEBUGCFLAGS = \ -fno-unroll-loops CFLAGS += \ -std=c99 \ - -pedantic \ + -pedantic-errors \ -pipe \ -fno-strict-aliasing \ -Wall \ diff --git a/mk/hdr.mk b/mk/hdr.mk index 212425d1..1d9335c1 100644 --- a/mk/hdr.mk +++ b/mk/hdr.mk @@ -22,8 +22,9 @@ FILTER = cat EXCFLAGS = $(INCLUDES) -D_XOPEN_SOURCE=600 -COMPILE = $(ROOT)/util/compile "$(CC)" "$(EXCFLAGS) $(CFLAGS) $$(pkg-config --cflags $(PACKAGES))" -COMPILEPIC = $(ROOT)/util/compile "$(CC)" "$(EXCFLAGS) $(CFLAGS) $$(pkg-config --cflags $(PACKAGES)) $(SOCFLAGS)" +COMPILE_FLAGS = $(EXCFLAGS) $(CFLAGS) $$(pkg-config --cflags $(PACKAGES)) +COMPILE = $(ROOT)/util/compile "$(CC)" "$(COMPILE_FLAGS)" +COMPILEPIC = $(ROOT)/util/compile "$(CC)" "$(COMPILE_FLAGS) $(SOCFLAGS)" LINK = $(ROOT)/util/link "$(LD)" "$$(pkg-config --libs $(PACKAGES)) $(LDFLAGS) $(LIBS)" LINKSO = $(ROOT)/util/link "$(LD)" "$$(pkg-config --libs $(PACKAGES)) $(SOLDFLAGS) $(LIBS) $(SHARED)" @@ -61,8 +62,8 @@ all: MAKEFILES=.depend .c.depend: echo MKDEP $< - [ -n "${noisycc}" ] && echo $(MKDEP) $(EXCFLAGS) $(CFLAGS) $$(pkg-config --cflags $(PACKAGES)) $< || true - $(MKDEP) $(EXCFLAGS) $(CFLAGS) $$(pkg-config --cflags $(PACKAGES)) $< >>.depend + [ -n "${noisycc}" ] && echo $(MKDEP) $(COMPILE_FLAGS) $< || true + eval "$(MKDEP) $(COMPILE_FLAGS)" $< >>.depend .sh.depend .rc.depend .1.depend .awk.depend: : diff --git a/mk/wmii.mk b/mk/wmii.mk index a78ec34d..da6687a8 100644 --- a/mk/wmii.mk +++ b/mk/wmii.mk @@ -13,7 +13,7 @@ COPYRIGHT = ©2010 Kris Maglione .MAKE.EXPORTED += WMII_HGVERSION SUBMAKE_EXPORT = WMII_HGVERSION=$(WMII_HGVERSION) -LIBS9 = $(ROOT)/lib/libregexp9.a $(ROOT)/lib/libbio.a $(ROOT)/lib/libfmt.a $(ROOT)/lib/libutf.a +LIBS9 = $(ROOT)/lib/libstuff.a $(ROOT)/lib/libregexp9.a $(ROOT)/lib/libbio.a $(ROOT)/lib/libfmt.a $(ROOT)/lib/libutf.a CFLAGS += '-DVERSION=\"$(VERSION)\"' '-DCOPYRIGHT=\"$(COPYRIGHT)\"' \ '-DCONFVERSION=\"$(CONFVERSION)\"' '-DCONFPREFIX=\"$(ETC)\"' diff --git a/test/grav.c b/test/grav.c index 3b31b9f0..c52e5f84 100644 --- a/test/grav.c +++ b/test/grav.c @@ -21,8 +21,8 @@ #include #include #include -#include -#include +#include +#include char buffer[8196]; void debug() {}