wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 418e341a18c45291f62f6bf5d426aa6bad25b675
parent 4e97cabdfb7e52702afbd848798d91ff2d20ff00
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Mon,  6 Feb 2006 17:33:10 +0100

finished wmiikeys


Diffstat:
Makefile | 2+-
cmd/wm/wm.c | 2+-
cmd/wmiikeys.c | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
libixp/client.c | 3+++
libwmii/spawn.c | 41++++++++++++++++++++++++++++++-----------
libwmii/wmii.h | 2+-
6 files changed, 117 insertions(+), 37 deletions(-)

diff --git a/Makefile b/Makefile @@ -6,7 +6,7 @@ include config.mk SUBDIRS = libcext liblitz libixp libwmii cmd BIN = cmd/wm/wmii cmd/wm/wmiiwm cmd/wmiibar cmd/wmiifs \ - cmd/wmiikeys cmd/wmiimenu cmd/wmiiplumb cmd/wmiir cmd/wmiir2 cmd/wmiiwarp + cmd/wmiikeys cmd/wmiimenu cmd/wmiiplumb cmd/wmiir cmd/wmiiwarp MAN1 = cmd/wm/wmii.1 cmd/wm/wmiiwm.1 cmd/wmiibar.1 cmd/wmiifs.1 \ cmd/wmiikeys.1 cmd/wmiimenu.1 cmd/wmiir.1 diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c @@ -81,7 +81,7 @@ draw_pager_page(size_t idx, Draw *d) Area *a = page[idx]->area[i]; if(!a->nclient) continue; - for(j = a->nclient - 1; j >= 0; j--) + for(j = 0; j < a->nclient; j++) draw_pager_client(a->client[j], d); } } diff --git a/cmd/wmiikeys.c b/cmd/wmiikeys.c @@ -142,22 +142,13 @@ create_shortcut(char *name, char *cmd) k = chain[i]; s->key = XKeysymToKeycode(dpy, XStringToKeysym(k)); s->mod = blitz_strtomod(chain[i]); - s->cmd = cmd; + s->cmd = strdup(cmd); } r->id = id++; return r; } -/* create - if(r) { - s->cmd = cmd; - shortcut = (Shortcut **)cext_attach_array((void **)shortcut, r, &shortcutsz); - nshortcut++; - grab_shortcut(r); - } - */ - static void destroy_shortcut(Shortcut *s) { @@ -232,6 +223,7 @@ handle_shortcut_gkb(Window w, unsigned long mod, KeyCode key) for(i = 0; i < nshortcut; i++) { Shortcut *s = shortcut[i]; if((s->mod == mod) && (s->key == key)) { + fprintf(stderr, "invoking %s\n", s->cmd); if(s->cmd) wmii_spawn(dpy, s->cmd); return; @@ -397,12 +389,9 @@ name_to_type(char *name) static int mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) { - unsigned short id = qpath_id(dir->path); - int i, type = name_to_type(wname); + Shortcut *s; + int type = name_to_type(wname); - if(id && ((i = index_of_id(id)) == -1)) - return -1; - if((dir->type != IXP_QTDIR) || (type == -1)) return -1; @@ -417,11 +406,14 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) new->path = mkqpath(Dshortcut, 0); break; case Fshortcut: - if(i >= nshortcut) + if(!(s = shortcut_of_name(wname))) return -1; + new->type = IXP_QTFILE; + new->path = mkqpath(type, s->id); + break; default: new->type = IXP_QTFILE; - new->path = mkqpath(type, id); + new->path = mkqpath(type, 0); break; } return 0; @@ -498,11 +490,9 @@ mkstat(Stat *stat, Qid *dir, char *name, unsigned long long length, unsigned int static unsigned int type_to_stat(Stat *stat, char *name, Qid *dir) { - int i, type = name_to_type(name); - unsigned short id = qpath_id(dir->path); + Shortcut *s; + int type = name_to_type(name); - if(id && ((i = index_of_id(id)) == -1)) - return 0; switch (type) { case Droot: case Dshortcut: @@ -519,7 +509,9 @@ type_to_stat(Stat *stat, char *name, Qid *dir) return mkstat(stat, dir, name, 23, DMREAD | DMWRITE); break; case Fshortcut: - return mkstat(stat, dir, name, strlen(shortcut[i]->cmd), DMREAD | DMWRITE); + if(!(s = shortcut_of_name(name))) + return -1; + return mkstat(stat, dir, name, strlen(s->cmd), DMREAD | DMWRITE); break; } return 0; @@ -544,6 +536,7 @@ xremove(IXPConn *c, Fcall *fcall) /* now detach the item */ cext_array_detach((void **)shortcut, s, &shortcutsz); nshortcut--; + free(s->cmd); destroy_shortcut(s); fcall->id = RREMOVE; ixp_server_respond_fcall(c, fcall); @@ -559,7 +552,7 @@ xread(IXPConn *c, Fcall *fcall) IXPMap *m = ixp_server_fid2map(c, fcall->fid); unsigned short id; unsigned char *p = fcall->data; - unsigned int len; + unsigned int len = 0; int i; if(!m) @@ -575,12 +568,14 @@ xread(IXPConn *c, Fcall *fcall) /* jump to offset */ for(i = 0; i < nshortcut; i++) { len += type_to_stat(&stat, shortcut[i]->name, &m->qid); + fprintf(stderr, "len=%d <= fcall->offset=%lld\n", len, fcall->offset); if(len <= fcall->offset) continue; break; } /* offset found, proceeding */ for(; i < nshortcut; i++) { + fprintf(stderr, "offset xread %s\n", shortcut[i]->name); len = type_to_stat(&stat, shortcut[i]->name, &m->qid); if(fcall->count + len > fcall->iounit) break; @@ -608,6 +603,7 @@ xread(IXPConn *c, Fcall *fcall) break; case Dshortcut: for(i = 0; i < nshortcut; i++) { + fprintf(stderr, "normal xread %s\n", shortcut[i]->name); len = type_to_stat(&stat, shortcut[i]->name, &m->qid); if(fcall->count + len > fcall->iounit) break; @@ -658,6 +654,27 @@ xstat(IXPConn *c, Fcall *fcall) return nil; } +static void +process_reset_line(char *line) +{ + Shortcut *s; + char *p; + fprintf(stderr, "got line: '%s'\n", line); + + /* ignore comments */ + for(p = line; *p && ((*p == ' ') || (*p == '\t')); p++); + if(*p && ((*p == '#') || (*p == '\n'))) + return; + + p = strchr(line, ' '); + *p = 0; + ++p; + s = create_shortcut(line, p); + shortcut = (Shortcut **)cext_array_attach((void **)shortcut, s, sizeof(Shortcut *), &shortcutsz); + nshortcut++; + grab_shortcut(s); +} + static char * xwrite(IXPConn *c, Fcall *fcall) { @@ -702,6 +719,46 @@ xwrite(IXPConn *c, Fcall *fcall) blitz_loadcolor(dpy, screen, colstr, &box.color); break; case Freset: + { + if(fcall->count > 2048) + goto error_xwrite; + static size_t lastcount; + static char last[2048]; /* iounit */ + char fcallbuf[2048], tmp[2048]; /* iounit */ + char *p1, *p2; + if(!fcall->offset) { + while(nshortcut) { + Shortcut *s = shortcut[0]; + ungrab_shortcut(s); + cext_array_detach((void **)shortcut, s, &shortcutsz); + nshortcut--; + free(s->cmd); + destroy_shortcut(s); + } + } + memcpy(fcallbuf, fcall->data, fcall->count); + fcallbuf[fcall->count] = 0; + if(fcall->offset) { + p1 = strrchr(last, '\n'); + p2 = strchr(fcallbuf, '\n'); + memcpy(tmp, p1, lastcount - (p1 - last)); + memcpy(tmp + (lastcount - (p1 - last)), p2, p2 - fcallbuf); + tmp[(lastcount - (p1 - last)) + (p2 - fcallbuf)] = 0; + process_reset_line(tmp); + } + else p2 = fcallbuf; + lastcount = fcall->count; + memcpy(last, fcall->data, fcall->count); + while(p2 - fcallbuf < fcall->count) { + p1 = strchr(p2, '\n'); + *p1 = 0; + process_reset_line(p2); + *p1 = '\n'; + p2 = ++p1; + } + lastcount = fcall->count; + memcpy(last, fcall->data, fcall->count); + } break; case Fshortcut: { @@ -715,6 +772,7 @@ xwrite(IXPConn *c, Fcall *fcall) s->cmd[fcall->count] = 0; } break; +error_xwrite: default: return "invalid write"; break; diff --git a/libixp/client.c b/libixp/client.c @@ -48,10 +48,12 @@ ixp_client_init(IXPClient * c, char *sockfile) c->fcall.maxmsg = IXP_MAX_MSG; cext_strlcpy(c->fcall.version, IXP_VERSION, sizeof(c->fcall.version)); if(do_fcall(c) == -1) { + fprintf(stderr, "error: %s\n", c->fcall.errstr); ixp_client_deinit(c); return -1; } if(strncmp(c->fcall.version, IXP_VERSION, strlen(IXP_VERSION))) { + fprintf(stderr, "error: %s\n", c->fcall.errstr); c->errstr = "9P versions differ"; ixp_client_deinit(c); return -1; /* we cannot handle this version */ @@ -66,6 +68,7 @@ ixp_client_init(IXPClient * c, char *sockfile) cext_strlcpy(c->fcall.uname, getenv("USER"), sizeof(c->fcall.uname)); c->fcall.aname[0] = 0; if(do_fcall(c) == -1) { + fprintf(stderr, "error: %s\n", c->fcall.errstr); ixp_client_deinit(c); return -1; } diff --git a/libwmii/spawn.c b/libwmii/spawn.c @@ -15,10 +15,10 @@ static void spawn_ixp_write(char *cmd) { - static IXPClient c; + IXPClient c; char *file = cmd; char *data = strchr(cmd, ' '); - char *address = getenv("WMII_ADDRESS"); + char *address = strdup(getenv("WMII_ADDRESS")); unsigned int fid = c.root_fid << 2; size_t len; @@ -27,11 +27,14 @@ spawn_ixp_write(char *cmd) *data = 0; data++; len = strlen(data); + fprintf(stderr, "spawn_ixp_write write file=%s data=%s address=%s\n", file, data, address); if(ixp_client_init(&c, address) == -1) { + free(address); fprintf(stderr, "libwmii: %s\n", c.errstr); return; } + free(address); /* open */ if(ixp_client_open(&c, fid, file, IXP_OWRITE) == -1) { fprintf(stderr, "libwmii: cannot open file '%s': %s\n", file, c.errstr); @@ -48,18 +51,34 @@ spawn_ixp_write(char *cmd) void wmii_spawn(void *dpy, char *cmd) { - /* the questionable double-fork is done to catch all zombies */ + static char *ixpcmd = nil; + static size_t ixpcmdsz = 0; + size_t len; + if(!cmd) return; - if(!strncmp(cmd, "#write ", 7)) - spawn_ixp_write(&cmd[7]); - else if(fork() == 0) { + if(!strncmp(cmd, "#write ", 7)) { + if(!(len = strlen(&cmd[7]) + 1)) + return; + if(len > ixpcmdsz) { + ixpcmdsz = len + 1; + if(ixpcmd) + free(ixpcmd); + ixpcmd = cext_emallocz(ixpcmdsz); + } + cext_strlcpy(ixpcmd, &cmd[7], len); + spawn_ixp_write(ixpcmd); + return; + } + + /* the questionable double-fork is done to catch all zombies */ + if(fork() == 0) { if(fork() == 0) { - setsid(); - close(ConnectionNumber(dpy)); - execlp("rc", "rc", "-c", cmd, (char *) 0); - perror("failed"); - exit(1); + setsid(); + close(ConnectionNumber(dpy)); + execlp("rc", "rc", "-c", cmd, (char *) 0); + perror("failed"); + exit(1); } exit(0); } diff --git a/libwmii/wmii.h b/libwmii/wmii.h @@ -9,7 +9,7 @@ /* ixp.c */ #define E9pversion "9P version not supported" #define Enoperm "permission denied" -#define Enofid "fid not assigned" +#define Enofid "fid not found" #define Enofile "file not found" #define Enomode "mode not supported" #define Enofunc "function not supported"