mirror of https://github.com/0intro/wmii
Factor out common code into library.
This commit is contained in:
parent
3550e7afef
commit
ab2d1760f8
|
@ -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)(/|$)
|
||||
|
|
1
Makefile
1
Makefile
|
@ -11,6 +11,7 @@ PDIRS = \
|
|||
alternative_wmiircs
|
||||
|
||||
DIRS = \
|
||||
libstuff \
|
||||
libbio \
|
||||
libfmt \
|
||||
libregexp \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <stuff/x.h>
|
||||
#include <stuff/util.h>
|
||||
#include <ixp.h>
|
||||
#include <x11.h>
|
||||
|
||||
#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__)
|
||||
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
|
||||
bool getlong(const char*, long*);
|
||||
bool getulong(const char*, ulong*);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <stuff/x.h>
|
||||
#include <stuff/util.h>
|
||||
#include <ixp.h>
|
||||
#include <x11.h>
|
||||
|
||||
#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__)
|
||||
|
||||
|
|
334
cmd/menu/event.c
334
cmd/menu/event.c
|
@ -1,334 +0,0 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* 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, "<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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <bio.h>
|
||||
#include <clientutil.h>
|
||||
#include <stuff/clientutil.h>
|
||||
#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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -3,31 +3,16 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <stuff/x.h>
|
||||
#include <stuff/util.h>
|
||||
#include <ixp.h>
|
||||
#include <x11.h>
|
||||
|
||||
#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__)
|
||||
|
||||
|
|
|
@ -1,309 +0,0 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 = {
|
||||
|
|
272
cmd/util.c
272
cmd/util.c
|
@ -1,272 +0,0 @@
|
|||
/* Written by Kris Maglione <fbsdaemon at gmail dot com> */
|
||||
/* Public domain */
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <fmt.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('\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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
378
cmd/wmii/_util.c
378
cmd/wmii/_util.c
|
@ -1,378 +0,0 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "dat.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <bio.h>
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ixp.h>
|
||||
#include <util.h>
|
||||
#include <utf.h>
|
||||
#include <fmt.h>
|
||||
#include <x11.h>
|
||||
#include <stuff/x.h>
|
||||
#include <stuff/util.h>
|
||||
#include <debug.h>
|
||||
#include <ixp.h>
|
||||
|
||||
#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__) )
|
||||
|
||||
|
|
254
cmd/wmii/event.c
254
cmd/wmii/event.c
|
@ -5,105 +5,16 @@
|
|||
#include <X11/keysym.h>
|
||||
#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,41 +41,17 @@ 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",
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
print_focus(const char *fn, Client *c, const char *to) {
|
||||
|
@ -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,65 +115,13 @@ 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;
|
||||
|
||||
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) {
|
||||
|
||||
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) {
|
||||
void
|
||||
event_mapnotify(XMapEvent *ev) {
|
||||
Window *w;
|
||||
|
||||
ignoreenter = ev->serial;
|
||||
|
@ -313,8 +129,8 @@ mapnotify(XMapEvent *ev) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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*);
|
||||
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
1317
cmd/wmii/x11.c
1317
cmd/wmii/x11.c
File diff suppressed because it is too large
Load Diff
|
@ -44,9 +44,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <clientutil.h>
|
||||
#include <util.h>
|
||||
#include <x11.h>
|
||||
|
||||
#include <stuff/clientutil.h>
|
||||
#include <stuff/util.h>
|
||||
#include <stuff/x11.h>
|
||||
|
||||
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*);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <ixp.h>
|
||||
#include <util.h>
|
||||
#include <stuff/util.h>
|
||||
#include <fmt.h>
|
||||
|
||||
static IxpClient *client;
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
\DefineShortVerb{\|}
|
||||
|
||||
\makeatletter
|
||||
\let\idx@@heading\chapter
|
||||
\let\:=:
|
||||
\catcode`\:=\active
|
||||
\def:{\@ifnextchar:{\coloncoloneq}{\:}}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#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;
|
|
@ -1,3 +1,7 @@
|
|||
/* Copyright ©2009-2010 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
#ifndef CLIENTEXTERN
|
||||
# define CLIENTEXTERN extern
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
|
||||
#include <stuff/base.h>
|
||||
|
||||
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);
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/* Copyright ©2007-2010 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
#include <stuff/geom.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <regexp9.h>
|
||||
|
||||
/* 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
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#include <stuff/base.h>
|
||||
#include <stuff/x11.h>
|
||||
#include <fmt.h>
|
||||
|
||||
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*);
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#define Window XWindow
|
||||
#define Font XFont
|
||||
#define Screen XScreen
|
||||
#include <stuff/geom.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
|
@ -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);
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/* Copyright ©2007-2010 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* 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
|
|
@ -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
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
char buffer[8092];
|
||||
char* _buffer;
|
||||
char* const _buf_end = buffer + sizeof buffer;
|
||||
|
|
@ -3,8 +3,8 @@
|
|||
#define CLIENTEXTERN
|
||||
#include <string.h>
|
||||
#include <ixp.h>
|
||||
#include <clientutil.h>
|
||||
#include <util.h>
|
||||
#include <stuff/clientutil.h>
|
||||
#include <stuff/util.h>
|
||||
|
||||
static IxpCFid* ctlfid;
|
||||
static char ctl[1024];
|
|
@ -0,0 +1,14 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "event.h"
|
||||
|
||||
void
|
||||
event_clientmessage(XClientMessageEvent *ev) {
|
||||
|
||||
USED(ev);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#include <stuff/x.h>
|
||||
|
||||
typedef void (*EventHandler)(XEvent*);
|
||||
|
||||
#define handle(w, fn, ev) \
|
||||
BLOCK(if((w)->handler->fn) (w)->handler->fn((w), ev))
|
||||
|
||||
extern EventHandler event_handler[LASTEvent];
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stuff/x.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stuff/geom.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stuff/geom.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stuff/geom.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stuff/geom.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);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stuff/geom.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stuff/geom.h>
|
||||
#include <stuff/util.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
void init_screens(void);
|
||||
void
|
||||
init_screens(void) {
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
/* Written by Kris Maglione */
|
||||
/* Public domain */
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stuff/util.h>
|
||||
|
||||
/* Edit s/^([a-zA-Z].*)\n([a-z].*) {/\1 \2;/g x/^([^a-zA-Z]|static|$)/-+d s/ (\*map|val|*str)//g */
|
||||
|
|
@ -39,10 +39,10 @@
|
|||
* ken@richsun.UUCP
|
||||
*/
|
||||
|
||||
#include "dat.h"
|
||||
#include <stdarg.h>
|
||||
#include <bio.h>
|
||||
//#include "fns.h"
|
||||
#include <stuff/x.h>
|
||||
#include <stuff/util.h>
|
||||
#include "printevent.h"
|
||||
#define Window XWindow
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fmt.h>
|
||||
#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)
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <bio.h>
|
||||
#include <plan9.h>
|
||||
#undef nelem
|
||||
#include <debug.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include <stuff/x11.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#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 */
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
|
||||
void *
|
||||
emalloc(uint size) {
|
||||
void *ret = malloc(size);
|
||||
if(!ret)
|
||||
mfatal("malloc", size);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
void*
|
||||
emallocz(uint size) {
|
||||
void *ret = emalloc(size);
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
|
||||
void *
|
||||
erealloc(void *ptr, uint size) {
|
||||
void *ret = realloc(ptr, size);
|
||||
if(!ret)
|
||||
mfatal("realloc", size);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
char*
|
||||
estrdup(const char *str) {
|
||||
void *ret = strdup(str);
|
||||
if(!ret)
|
||||
mfatal("strdup", strlen(str));
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <string.h>
|
||||
#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;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <stdlib.h>
|
||||
#include <fmt.h>
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <stdlib.h>
|
||||
#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;
|
||||
}
|
|
@ -1,13 +1,12 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <fbsdaemon@gmail.com>
|
||||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "dat.h"
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "fns.h"
|
||||
#include <stuff/util.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stuff/util.h>
|
||||
|
||||
bool
|
||||
getint(const char *s, int *ret) {
|
||||
long l;
|
||||
bool res;
|
||||
|
||||
res = getlong(s, &l);
|
||||
*ret = l;
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stuff/util.h>
|
||||
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stuff/util.h>
|
||||
|
||||
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);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <fmt.h>
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include "util.h"
|
||||
|
||||
int
|
||||
max(int a, int b) {
|
||||
if(a > b)
|
||||
return a;
|
||||
return b;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#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);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/* Written by Kris Maglione <maglione.k at Gmail> */
|
||||
/* Public domain */
|
||||
#include "util.h"
|
||||
|
||||
int
|
||||
min(int a, int b) {
|
||||
if(a < b)
|
||||
return a;
|
||||
return b;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fmt.h>
|
||||
#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;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
|
||||
void
|
||||
refree(Regex *r) {
|
||||
|
||||
free(r->regex);
|
||||
free(r->regc);
|
||||
r->regex = nil;
|
||||
r->regc = nil;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
|
||||
* 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);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue