diff --git a/TODO b/TODO index 3f10d5e0..3f57b0d3 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,9 @@ BUGS 4.0 * Opaque managed moves. I know I've argued against it, but it may be doable. +* Clicking layout boxes should do useful things. +* Collapse/uncollapse frames with the keyboard. +* Open modes (to replace colmodes). * Resizable managed area. Maybe. Struts seem to do everything this might. * New dmenu, with real cursor; snarfable. diff --git a/cmd/wmii.sh.sh b/cmd/wmii.sh.sh index 2293ffd9..04c29b6c 100755 --- a/cmd/wmii.sh.sh +++ b/cmd/wmii.sh.sh @@ -73,6 +73,7 @@ Event Key ! eval "cat <view = v; a->id = id++; - a->mode = def.colmode; + if(v->area) + a->mode = def.colmode; + else + a->mode = Coldefault; a->frame = nil; a->sel = nil; @@ -245,8 +248,11 @@ area_focus(Area *a) { if(!a->floating) v->selcol = area_idx(a); - if((old_a) && (a->floating != old_a->floating)) + if((old_a) && (a->floating != old_a->floating)) { v->revert = old_a; + if(v->area->max) + view_update(v); + } if(v != screen->sel) return; diff --git a/cmd/wmii/client.c b/cmd/wmii/client.c index 4593f1b5..c95898f8 100644 --- a/cmd/wmii/client.c +++ b/cmd/wmii/client.c @@ -469,8 +469,6 @@ focus(Client *c, bool user) { void client_focus(Client *c) { /* Round trip. */ - static long id; - long _id; if(c && c->group) c->group->client = c; @@ -478,9 +476,8 @@ client_focus(Client *c) { sync(); flushevents(FocusChangeMask, true); - _id = id++ % 99; - Dprint(DFocus, "client_focus([%C]%s) %ld\n", c, clientname(c), _id); - Dprint(DFocus, "\t%02d [%C]%s\n\t=> [%C]%s\n", _id, + Dprint(DFocus, "client_focus([%C]%s)\n", c, clientname(c)); + Dprint(DFocus, "\t[%C]%s\n\t=> [%C]%s\n", screen->focus, clientname(screen->focus), c, clientname(c)); if(screen->focus != c) { diff --git a/cmd/wmii/column.c b/cmd/wmii/column.c index 437a869c..fb68b4ab 100644 --- a/cmd/wmii/column.c +++ b/cmd/wmii/column.c @@ -129,7 +129,7 @@ stack_info(Frame *f, Frame **firstp, int *dyp, int *nframep) { nframe = 0; dy = 0; - first = nil; + first = f; for(ft=f; ft && ft->collapsed; ft=ft->anext) ; if(ft && ft != f) { @@ -513,7 +513,9 @@ column_scale(Area *a) { f->colr.max.x = a->r.max.x; if(!f->collapsed) f->colr.max.y += ((float)f->dy / dy) * surplus; - assert(f->collapsed ? Dy(f->r) >= 0 : dy > 0); + if(btassert("6 full", !(f->collapsed ? Dy(f->r) >= 0 : dy > 0))) + warning("Something's fucked: %s:%d:%s()", + __FILE__, __LINE__, __func__); frame_resize(f, f->colr); } @@ -527,6 +529,8 @@ column_arrange(Area *a, bool dirty) { Frame *f; View *v; + if(a->floating) + float_arrange(a); if(a->floating || !a->frame) return; diff --git a/cmd/wmii/event.c b/cmd/wmii/event.c index 3c25455e..69cfb362 100644 --- a/cmd/wmii/event.c +++ b/cmd/wmii/event.c @@ -274,7 +274,7 @@ keypress(XKeyEvent *ev) { xtime = ev->time; ev->state &= valid_mask; if(ev->window == scr.root.w) - kpress(scr.root.w, ev->state, (KeyCode) ev->keycode); + kpress(scr.root.w, ev->state, (KeyCode)ev->keycode); } static void @@ -325,6 +325,7 @@ static void mapnotify(XMapEvent *ev) { Window *w; + ignoreenter = ev->serial; if((w = findwin(ev->window))) handle(w, map, ev); } @@ -333,6 +334,7 @@ static void unmapnotify(XUnmapEvent *ev) { Window *w; + ignoreenter = ev->serial; if((w = findwin(ev->window)) && (ev->event == w->parent->w)) { w->mapped = false; if(ev->send_event || w->unmapped-- == 0) diff --git a/cmd/wmii/ewmh.c b/cmd/wmii/ewmh.c index a773df20..d023c8e0 100644 --- a/cmd/wmii/ewmh.c +++ b/cmd/wmii/ewmh.c @@ -7,6 +7,9 @@ Window *ewmhwin; +static void ewmh_getwinstate(Client*); +static void ewmh_setstate(Client*, Atom, int); + #define Net(x) ("_NET_" x) #define Action(x) ("_NET_WM_ACTION_" x) #define State(x) ("_NET_WM_STATE_" x) @@ -117,6 +120,7 @@ ewmh_initclient(Client *c) { changeprop_long(&c->w, Net("WM_ALLOWED_ACTIONS"), "ATOM", allowed, nelem(allowed)); ewmh_getwintype(c); + ewmh_getwinstate(c); ewmh_getstrut(c); ewmh_updateclientlist(); } @@ -237,6 +241,18 @@ ewmh_getwintype(Client *c) { } } +static void +ewmh_getwinstate(Client *c) { + ulong *vals; + long n; + + n = getprop_ulong(&c->w, Net("WM_STATE"), "ATOM", + 0L, &vals, 16); + while(--n >= 0) + ewmh_setstate(c, vals[n], On); + free(vals); +} + long ewmh_protocols(Window *w) { static Prop props[] = { @@ -297,6 +313,20 @@ ewmh_getstrut(Client *c) { view_update(screen->sel); } +static void +ewmh_setstate(Client *c, Atom state, int action) { + + Dprint(DEwmh, "\tSTATE = %A\n", state); + if(state == 0) + return; + + if(state == STATE("FULLSCREEN")) + fullscreen(c, action); + else + if(state == STATE("DEMANDS_ATTENTION")) + client_seturgent(c, action, UrgClient); +} + int ewmh_clientmessage(XClientMessageEvent *e) { Client *c; @@ -328,16 +358,8 @@ ewmh_clientmessage(XClientMessageEvent *e) { return -1; } Dprint(DEwmh, "\tAction: %s\n", TOGGLE(action)); - for(i = 1; i <= 2; i++) { - if(l[i] == 0) - break; - Dprint(DEwmh, "\tl[%d] = %A\n", i, l[i]); - if(l[i] == STATE("FULLSCREEN")) - fullscreen(c, action); - else - if(l[i] == STATE("DEMANDS_ATTENTION")) - client_seturgent(c, action, UrgClient); - } + ewmh_setstate(c, l[1], action); + ewmh_setstate(c, l[2], action); return 1; }else if(msg == NET("ACTIVE_WINDOW")) { diff --git a/cmd/wmii/float.c b/cmd/wmii/float.c index 0305ace2..0695b47b 100644 --- a/cmd/wmii/float.c +++ b/cmd/wmii/float.c @@ -59,6 +59,30 @@ float_resizeframe(Frame *f, Rectangle r) { frame_resize(f, r); } +void +float_arrange(Area *a) { + Frame *f; + + assert(a->floating); + + switch(a->mode) { + case Coldefault: + for(f=a->frame; f; f=f->anext) + f->collapsed = false; + break; + case Colstack: + for(f=a->frame; f; f=f->anext) + f->collapsed = (f != a->sel); + break; + default: + die("not reached"); + break; + } + for(f=a->frame; f; f=f->anext) + f->r = f->floatr; + view_update(a->view); +} + static void rect_push(Vector_rect *vec, Rectangle r) { Rectangle *rp; @@ -163,6 +187,6 @@ float_placeframe(Frame *f) { } } - f->r = rectsetorigin(f->r, p); + f->floatr = rectsetorigin(f->r, p); } diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h index fa8eb2bb..c2c5cb34 100644 --- a/cmd/wmii/fns.h +++ b/cmd/wmii/fns.h @@ -120,6 +120,7 @@ void ewmh_updateview(void); void ewmh_updateviews(void); /* float.c */ +void float_arrange(Area*); void float_attach(Area*, Frame*); void float_detach(Frame*); void float_resizeframe(Frame*, Rectangle); diff --git a/cmd/wmii/frame.c b/cmd/wmii/frame.c index 8af111c0..2b3fdf5b 100644 --- a/cmd/wmii/frame.c +++ b/cmd/wmii/frame.c @@ -215,6 +215,7 @@ enter_event(Window *w, XCrossingEvent *e) { f->client, f->client->name, ignoreenter == e->serial ? " (ignored)" : ""); if(e->detail != NotifyInferior) if(e->serial != ignoreenter && (f->area->floating || !f->collapsed)) + if(!(c->w.ewmh.type & TypeSplash)) focus(f->client, false); } mouse_checkresize(f, Pt(e->x, e->y), false); @@ -296,26 +297,30 @@ frame_gethints(Frame *f) { return h; } +#define ADJ(PE, ME) \ + if(c->fullscreen) \ + return r; \ + \ + if(!floating) { \ + r.min.x PE 1; \ + r.min.y PE labelh(def.font); \ + r.max.x ME 1; \ + r.max.y ME 1; \ + }else { \ + if(!c->borderless) { \ + r.min.x PE def.border; \ + r.max.x ME def.border; \ + r.max.y ME def.border; \ + } \ + if(!c->titleless) \ + r.min.y PE labelh(def.font); \ + } \ + Rectangle frame_rect2client(Client *c, Rectangle r, bool floating) { - if(c->fullscreen) - return r; + ADJ(+=, -=) - if(!floating) { - r.min.x += 1; - r.min.y += labelh(def.font); - r.max.x -= 1; - r.max.y -= 1; - }else { - if(!c->borderless) { - r.min.x += def.border; - r.max.x -= def.border; - r.max.y -= def.border; - } - if(!c->titleless) - r.min.y += labelh(def.font); - } r.max.x = max(r.max.x, r.min.x+1); r.max.y = max(r.max.y, r.min.y+1); return r; @@ -324,26 +329,13 @@ frame_rect2client(Client *c, Rectangle r, bool floating) { Rectangle frame_client2rect(Client *c, Rectangle r, bool floating) { - if(c->fullscreen) - return r; + ADJ(-=, +=) - if(!floating) { - r.min.x -= 1; - r.min.y -= labelh(def.font); - r.max.x += 1; - r.max.y += 1; - }else { - if(!c->borderless) { - r.min.x -= def.border; - r.max.x += def.border; - r.max.y += def.border; - } - if(!c->titleless) - r.min.y -= labelh(def.font); - } return r; } +#undef ADJ + void frame_resize(Frame *f, Rectangle r) { Client *c; @@ -364,8 +356,10 @@ frame_resize(Frame *f, Rectangle r) { return; } + /* if(f->area->floating) f->collapsed = false; + */ fr = frame_hints(f, r, get_sticky(f->r, r)); if(f->area->floating && !c->strut) @@ -398,7 +392,7 @@ frame_resize(Frame *f, Rectangle r) { } f->crect = rectsubpt(cr, f->r.min); - if(f->area->floating) + if(f->area->floating && !f->collapsed) f->floatr = f->r; } @@ -458,7 +452,7 @@ frame_draw(Frame *f) { f->titlebar = insetrect(r, 3); f->titlebar.max.y += 3; - /* Odd focus. Ulselected, with keyboard focus. */ + /* Odd focus. Unselected, with keyboard focus. */ /* Draw a border just inside the titlebar. */ if(c != selclient() && c == screen->focus) { border(img, insetrect(r, 1), 1, def.normcolor.bg); @@ -481,7 +475,7 @@ frame_draw(Frame *f) { border(img, insetrect(r, -1), 1, def.normcolor.bg); /* Draw a border on borderless+titleless selected apps. */ - if(c->borderless && c->titleless && c == selclient()) + if(f->area->floating && c->borderless && c->titleless && c == selclient()) setborder(c->framewin, def.border, def.focuscolor.border); else setborder(c->framewin, 0, 0); @@ -626,6 +620,8 @@ frame_focus(Frame *f) { return; move_focus(old_f, f); + if(a->floating) + float_arrange(a); client_focus(f->client); /* diff --git a/cmd/wmii/fs.c b/cmd/wmii/fs.c index b68b630c..ca392ac3 100644 --- a/cmd/wmii/fs.c +++ b/cmd/wmii/fs.c @@ -8,75 +8,22 @@ #include #include "fns.h" - -/* Datatypes: */ -typedef struct Dirtab Dirtab; -typedef struct FileId FileId; -typedef struct PLink PLink; -typedef struct Pending Pending; -typedef struct RLink RLink; -typedef struct Queue Queue; - -struct PLink { - PLink* next; - PLink* prev; - IxpFid* fid; - Queue* queue; - Pending* pending; +typedef union IxpFileIdU IxpFileIdU; +union IxpFileIdU { + Bar* bar; + Bar** bar_p; + CTuple* col; + Client* client; + Ruleset* rule; + View* view; + char* buf; + void* ref; }; -struct RLink { - RLink* next; - RLink* prev; - Ixp9Req* req; -}; +#include -struct Pending { - RLink req; - PLink fids; -}; - -struct Queue { - Queue* link; - char* dat; - long len; -}; - -static Pending events; -static Pending pdebug[NDebugOpt]; - -struct Dirtab { - char* name; - uchar qtype; - uint type; - uint perm; - uint flags; -}; - -struct FileId { - FileId* next; - union { - Bar* bar; - Bar** bar_p; - CTuple* col; - Client* client; - PLink* p; - Ruleset* rule; - View* view; - char* buf; - void* ref; - } p; - bool pending; - uint id; - uint index; - Dirtab tab; - ushort nref; - uchar volatil; -}; - -enum { - FLHide = 1, -}; +static IxpPending events; +static IxpPending pdebug[NDebugOpt]; /* Constants */ enum { /* Dirs */ @@ -115,8 +62,6 @@ static char /* Global Vars */ /***************/ -FileId *free_fileid; - Ixp9Srv p9srv = { .open= fs_open, .walk= fs_walk, @@ -134,7 +79,7 @@ Ixp9Srv p9srv = { /* ad-hoc file tree. Empty names ("") indicate dynamic entries to be filled * in by lookup_file */ -static Dirtab +static IxpDirtab dirtab_root[]= {{".", QTDIR, FsRoot, 0500|DMDIR }, {"rbar", QTDIR, FsDBars, 0700|DMDIR }, {"lbar", QTDIR, FsDBars, 0700|DMDIR }, @@ -169,7 +114,7 @@ dirtab_tag[]= {{".", QTDIR, FsDTag, 0500|DMDIR }, {"ctl", QTAPPEND, FsFTctl, 0600|DMAPPEND }, {"index", QTFILE, FsFTindex, 0400 }, {nil}}; -static Dirtab* dirtab[] = { +static IxpDirtab* dirtab[] = { [FsRoot] = dirtab_root, [FsDBars] = dirtab_bars, [FsDClients] = dirtab_clients, @@ -178,238 +123,8 @@ static Dirtab* dirtab[] = { [FsDTags] = dirtab_tags, [FsDTag] = dirtab_tag, }; - -/* Utility Functions */ -static FileId * -get_file(void) { - FileId *temp; - if(!free_fileid) { - uint i = 15; - temp = emallocz(i * sizeof *temp); - for(; i; i--) { - temp->next = free_fileid; - free_fileid = temp++; - } - } - temp = free_fileid; - free_fileid = temp->next; - temp->volatil = 0; - temp->nref = 1; - temp->next = nil; - temp->pending = false; - return temp; -} - -static void -free_file(FileId *f) { - if(--f->nref) - return; - free(f->tab.name); - f->next = free_fileid; - free_fileid = f; -} - -/* Increase the reference counts of the FileId list */ -static void -clone_files(FileId *f) { - for(; f; f=f->next) - assert(f->nref++); -} - -/* This should be moved to libixp */ -static void -write_buf(Ixp9Req *r, char *buf, uint len) { - if(r->ifcall.offset >= len) - return; - - len -= r->ifcall.offset; - if(len > r->ifcall.count) - len = r->ifcall.count; - r->ofcall.data = emalloc(len); - memcpy(r->ofcall.data, buf + r->ifcall.offset, len); - r->ofcall.count = len; -} - -/* This should be moved to libixp */ -static void -write_to_buf(Ixp9Req *r, char **buf, uint *len, uint max) { - FileId *f; - char *p; - uint offset, count; - - f = r->fid->aux; - - offset = r->ifcall.offset; - if(f->tab.perm & DMAPPEND) - offset = *len; - - if(offset > *len || r->ifcall.count == 0) { - r->ofcall.count = 0; - return; - } - - count = r->ifcall.count; - if(max && (offset + count > max)) - count = max - offset; - - *len = offset + count; - if(max == 0) - *buf = erealloc(*buf, *len + 1); - p = *buf; - - memcpy(p+offset, r->ifcall.data, count); - r->ofcall.count = count; - p[offset+count] = '\0'; -} - -/* This should be moved to libixp */ -static void -data_to_cstring(Ixp9Req *r) { - char *p; - uint i; - - i = r->ifcall.count; - p = r->ifcall.data; - if(p[i - 1] == '\n') - i--; - - r->ifcall.data = toutf8n(p, i); - assert(r->ifcall.data); - free(p); -} - typedef char* (*MsgFunc)(void*, IxpMsg*); -static char* -message(Ixp9Req *r, MsgFunc fn) { - char *err, *s, *p, c; - FileId *f; - IxpMsg m; - - f = r->fid->aux; - - data_to_cstring(r); - s = r->ifcall.data; - - err = nil; - c = *s; - while(c != '\0') { - while(*s == '\n') - s++; - p = s; - while(*p != '\0' && *p != '\n') - p++; - c = *p; - *p = '\0'; - - m = ixp_message(s, p-s, 0); - s = fn(f->p.ref, &m); - if(s) - err = s; - s = p + 1; - } - return err; -} - -/* FIXME: Move to external lib */ -static void -pending_respond(Ixp9Req *r) { - FileId *f; - PLink *p; - RLink *rl; - Queue *q; - - f = r->fid->aux; - p = f->p.p; - assert(f->pending); - if(p->queue) { - q = p->queue; - p->queue = q->link; - r->ofcall.data = q->dat; - r->ofcall.count = q->len; - if(r->aux) { - rl = r->aux; - rl->next->prev = rl->prev; - rl->prev->next = rl->next; - free(rl); - } - respond(r, nil); - free(q); - }else { - rl = emallocz(sizeof *rl); - rl->req = r; - rl->next = &p->pending->req; - rl->prev = rl->next->prev; - rl->next->prev = rl; - rl->prev->next = rl; - r->aux = rl; - } -} - -static void -pending_write(Pending *p, char *dat, long n) { - RLink rl; - Queue **qp, *q; - PLink *pp; - RLink *rp; - - if(n == 0) - return; - - if(p->req.next == nil) { - p->req.next = &p->req; - p->req.prev = &p->req; - p->fids.prev = &p->fids; - p->fids.next = &p->fids; - } - - for(pp=p->fids.next; pp != &p->fids; pp=pp->next) { - for(qp=&pp->queue; *qp; qp=&qp[0]->link) - ; - q = emallocz(sizeof *q); - q->dat = emalloc(n); - memcpy(q->dat, dat, n); - q->len = n; - *qp = q; - } - rl.next = &rl; - rl.prev = &rl; - if(p->req.next != &p->req) { - rl.next = p->req.next; - rl.prev = p->req.prev; - p->req.prev = &p->req; - p->req.next = &p->req; - } - rl.prev->next = &rl; - rl.next->prev = &rl; - while((rp = rl.next) != &rl) - pending_respond(rp->req); -} - -static void -pending_pushfid(Pending *p, IxpFid *f) { - PLink *pl; - FileId *fi; - - if(p->req.next == nil) { - p->req.next = &p->req; - p->req.prev = &p->req; - p->fids.prev = &p->fids; - p->fids.next = &p->fids; - } - - fi = f->aux; - pl = emallocz(sizeof *pl); - pl->fid = f; - pl->pending = p; - pl->next = &p->fids; - pl->prev = pl->next->prev; - pl->next->prev = pl; - pl->prev->next = pl; - fi->pending = true; - fi->p.p = pl; -} - void event(const char *format, ...) { va_list ap; @@ -418,10 +133,11 @@ event(const char *format, ...) { vsnprint(buffer, sizeof buffer, format, ap); va_end(ap); - pending_write(&events, buffer, strlen(buffer)); + ixp_pending_write(&events, buffer, strlen(buffer)); } static int dflags; + bool setdebug(int flag) { dflags = flag; @@ -474,11 +190,13 @@ dwrite(int flag, void *buf, int n, bool always) { if(debugfile&flag) for(i=0; i < nelem(pdebug); i++) if(flag & (1<type = 0; s->dev = 0; s->qid.path = QID(f->tab.type, f->id); @@ -486,8 +204,8 @@ dostat(Stat *s, uint len, FileId *f) { s->qid.type = f->tab.qtype; s->mode = f->tab.perm; s->atime = time(nil); - s->mtime = time(nil); - s->length = len; + s->mtime = s->atime; + s->length = fs_size(f);; s->name = f->tab.name; s->uid = user; s->gid = user; @@ -496,11 +214,11 @@ dostat(Stat *s, uint len, FileId *f) { /* All lookups and directory organization should be performed through * lookup_file, mostly through the dirtabs[] tree. */ -static FileId * -lookup_file(FileId *parent, char *name) +static IxpFileId* +lookup_file(IxpFileId *parent, char *name) { - FileId *ret, *file, **last; - Dirtab *dir; + IxpFileId *ret, *file, **last; + IxpDirtab *dir; Client *c; View *v; Bar *b; @@ -515,7 +233,7 @@ lookup_file(FileId *parent, char *name) ret = nil; for(; dir->name; dir++) { # define push_file(nam) \ - file = get_file(); \ + file = ixp_srv_getfile(); \ *last = file; \ last = &file->next; \ file->tab = *dir; \ @@ -602,6 +320,7 @@ lookup_file(FileId *parent, char *name) file->p.bar_p = &screen[0].bar[BLeft]; else file->p.bar_p = &screen[0].bar[BRight]; + file->id = (int)(uintptr_t)file->p.bar_p; break; case FsFColRules: file->p.rule = &def.colrules; @@ -621,92 +340,29 @@ LastItem: return ret; } -static bool -verify_file(FileId *f) { - FileId *nf; - int ret; - - if(!f->next) - return true; - - ret = false; - if(verify_file(f->next)) { - nf = lookup_file(f->next, f->tab.name); - if(nf) { - if(!nf->volatil || nf->p.ref == f->p.ref) - ret = true; - free_file(nf); - } - } - return ret; -} - /* Service Functions */ void fs_attach(Ixp9Req *r) { - FileId *f = get_file(); + IxpFileId *f; + + f = ixp_srv_getfile(); f->tab = dirtab[FsRoot][0]; f->tab.name = estrdup("/"); - f->p.ref = nil; r->fid->aux = f; r->fid->qid.type = f->tab.qtype; r->fid->qid.path = QID(f->tab.type, 0); - r->ofcall.qid = r->fid->qid; + r->ofcall.rattach.qid = r->fid->qid; respond(r, nil); } void fs_walk(Ixp9Req *r) { - FileId *f, *nf; - int i; - f = r->fid->aux; - clone_files(f); - for(i=0; i < r->ifcall.nwname; i++) { - if(!strcmp(r->ifcall.wname[i], "..")) { - if(f->next) { - nf=f; - f=f->next; - free_file(nf); - } - }else{ - nf = lookup_file(f, r->ifcall.wname[i]); - if(!nf) - break; - assert(!nf->next); - if(strcmp(r->ifcall.wname[i], ".")) { - nf->next = f; - f = nf; - } - } - r->ofcall.wqid[i].type = f->tab.qtype; - r->ofcall.wqid[i].path = QID(f->tab.type, f->id); - } - /* There should be a way to do this on freefid() */ - if(i < r->ifcall.nwname) { - while((nf = f)) { - f=f->next; - free_file(nf); - } - respond(r, Enofile); - return; - } - /* Remove refs for r->fid if no new fid */ - if(r->ifcall.fid == r->ifcall.newfid) { - nf = r->fid->aux; - r->fid->aux = f; - while((f = nf)) { - nf = nf->next; - free_file(f); - } - }else - r->newfid->aux = f; - r->ofcall.nwqid = i; - respond(r, nil); + ixp_srv_walkandclone(r, lookup_file); } static uint -fs_size(FileId *f) { +fs_size(IxpFileId *f) { switch(f->tab.type) { default: return 0; @@ -730,128 +386,99 @@ fs_stat(Ixp9Req *r) { Stat s; int size; char *buf; - FileId *f; + IxpFileId *f; f = r->fid->aux; - if(!verify_file(f)) { + if(!ixp_srv_verifyfile(f, lookup_file)) { respond(r, Enofile); return; } - dostat(&s, fs_size(f), f); - r->ofcall.nstat = size = ixp_sizeof_stat(&s); + dostat(&s, f); + size = ixp_sizeof_stat(&s); + r->ofcall.rstat.nstat = size; buf = emallocz(size); m = ixp_message(buf, size, MsgPack); ixp_pstat(&m, &s); - r->ofcall.stat = (uchar*)m.data; + r->ofcall.rstat.stat = (uchar*)m.data; respond(r, nil); } void fs_read(Ixp9Req *r) { char *buf; - FileId *f, *tf; - int n, offset; - ulong size; + IxpFileId *f; + int n; f = r->fid->aux; - if(!verify_file(f)) { + if(!ixp_srv_verifyfile(f, lookup_file)) { respond(r, Enofile); return; } if(f->tab.perm & DMDIR && f->tab.perm & 0400) { - Stat s; - IxpMsg m; - - size = r->ifcall.count; - if(size > r->fid->iounit) - size = r->fid->iounit; - buf = emallocz(size); - m = ixp_message(buf, size, MsgPack); - - tf = f = lookup_file(f, nil); - /* Note: f->tab.name == "." so we skip it */ - offset = 0; - for(f=f->next; f; f=f->next) { - dostat(&s, fs_size(f), f); - n = ixp_sizeof_stat(&s); - if(offset >= r->ifcall.offset) { - if(size < n) - break; - ixp_pstat(&m, &s); - size -= n; - } - offset += n; - } - while((f = tf)) { - tf=tf->next; - free_file(f); - } - r->ofcall.count = m.pos - m.data; - r->ofcall.data = m.data; - respond(r, nil); + ixp_srv_readdir(r, lookup_file, dostat); return; } else{ if(f->pending) { - pending_respond(r); + ixp_pending_respond(r); return; } switch(f->tab.type) { case FsFprops: - write_buf(r, f->p.client->props, strlen(f->p.client->props)); + ixp_srv_readbuf(r, f->p.client->props, strlen(f->p.client->props)); respond(r, nil); return; case FsFColRules: case FsFTagRules: - write_buf(r, f->p.rule->string, f->p.rule->size); + ixp_srv_readbuf(r, f->p.rule->string, f->p.rule->size); respond(r, nil); return; case FsFKeys: - write_buf(r, def.keys, def.keyssz); + ixp_srv_readbuf(r, def.keys, def.keyssz); respond(r, nil); return; case FsFCtags: - write_buf(r, f->p.client->tags, strlen(f->p.client->tags)); + ixp_srv_readbuf(r, f->p.client->tags, strlen(f->p.client->tags)); respond(r, nil); return; case FsFClabel: - write_buf(r, f->p.client->name, strlen(f->p.client->name)); + ixp_srv_readbuf(r, f->p.client->name, strlen(f->p.client->name)); respond(r, nil); return; case FsFBar: - write_buf(r, f->p.bar->buf, strlen(f->p.bar->buf)); + ixp_srv_readbuf(r, f->p.bar->buf, strlen(f->p.bar->buf)); respond(r, nil); return; case FsFRctl: buf = readctl_root(); - write_buf(r, buf, strlen(buf)); + ixp_srv_readbuf(r, buf, strlen(buf)); respond(r, nil); return; case FsFCctl: - if(r->ifcall.offset) { + if(r->ifcall.io.offset) { respond(r, nil); return; } - r->ofcall.data = smprint("%C", f->p.client); - r->ofcall.count = strlen(r->ofcall.data); /* will die if nil */ + r->ofcall.io.data = smprint("%C", f->p.client); + r->ofcall.io.count = strlen(r->ofcall.io.data); /* will die if nil */ respond(r, nil); return; case FsFTindex: buf = view_index(f->p.view); n = strlen(buf); - write_buf(r, buf, n); + ixp_srv_readbuf(r, buf, n); respond(r, nil); return; case FsFTctl: buf = readctl_view(f->p.view); n = strlen(buf); - write_buf(r, buf, n); + ixp_srv_readbuf(r, buf, n); respond(r, nil); return; } @@ -865,18 +492,19 @@ fs_read(Ixp9Req *r) { void fs_write(Ixp9Req *r) { - FileId *f; + MsgFunc mf; + IxpFileId *f; char *errstr; char *p; uint i; - if(r->ifcall.count == 0) { + if(r->ifcall.io.count == 0) { respond(r, nil); return; } f = r->fid->aux; - if(!verify_file(f)) { + if(!ixp_srv_verifyfile(f, lookup_file)) { respond(r, Enofile); return; } @@ -884,55 +512,54 @@ fs_write(Ixp9Req *r) { switch(f->tab.type) { case FsFColRules: case FsFTagRules: - write_to_buf(r, &f->p.rule->string, &f->p.rule->size, 0); + ixp_srv_writebuf(r, &f->p.rule->string, &f->p.rule->size, 0); respond(r, nil); return; case FsFKeys: - write_to_buf(r, &def.keys, &def.keyssz, 0); + ixp_srv_writebuf(r, &def.keys, &def.keyssz, 0); respond(r, nil); return; case FsFClabel: - data_to_cstring(r); - utfecpy(f->p.client->name, f->p.client->name+sizeof(client->name), r->ifcall.data); + ixp_srv_data2cstring(r); + utfecpy(f->p.client->name, f->p.client->name+sizeof(client->name), r->ifcall.io.data); frame_draw(f->p.client->sel); update_class(f->p.client); - r->ofcall.count = r->ifcall.count; + r->ofcall.io.count = r->ifcall.io.count; respond(r, nil); return; case FsFCtags: - data_to_cstring(r); - apply_tags(f->p.client, r->ifcall.data); - r->ofcall.count = r->ifcall.count; + ixp_srv_data2cstring(r); + apply_tags(f->p.client, r->ifcall.io.data); + r->ofcall.io.count = r->ifcall.io.count; respond(r, nil); return; case FsFBar: i = strlen(f->p.bar->buf); p = f->p.bar->buf; - write_to_buf(r, &p, &i, 279); - r->ofcall.count = i - r->ifcall.offset; + ixp_srv_writebuf(r, &p, &i, 279); + r->ofcall.io.count = i - r->ifcall.io.offset; respond(r, nil); return; case FsFCctl: - errstr = message(r, (MsgFunc)message_client); - r->ofcall.count = r->ifcall.count; - respond(r, errstr); - return; + mf = (MsgFunc)message_client; + goto msg; case FsFTctl: - errstr = message(r, (MsgFunc)message_view); - r->ofcall.count = r->ifcall.count; - respond(r, errstr); - return; + mf = (MsgFunc)message_view; + goto msg; case FsFRctl: - errstr = message(r, (MsgFunc)message_root); - r->ofcall.count = r->ifcall.count; + mf = (MsgFunc)message_root; + goto msg; + msg: + errstr = ixp_srv_writectl(r, mf); + r->ofcall.io.count = r->ifcall.io.count; respond(r, errstr); return; case FsFEvent: - if(r->ifcall.data[r->ifcall.count-1] == '\n') - event("%.*s", (int)r->ifcall.count, r->ifcall.data); + if(r->ifcall.io.data[r->ifcall.io.count-1] == '\n') + event("%.*s", (int)r->ifcall.io.count, r->ifcall.io.data); else - event("%.*s\n", (int)r->ifcall.count, r->ifcall.data); - r->ofcall.count = r->ifcall.count; + event("%.*s\n", (int)r->ifcall.io.count, r->ifcall.io.data); + r->ofcall.io.count = r->ifcall.io.count; respond(r, nil); return; } @@ -945,46 +572,37 @@ fs_write(Ixp9Req *r) { void fs_open(Ixp9Req *r) { - FileId *f; + IxpFileId *f; f = r->fid->aux; - if(!verify_file(f)) { + if(!ixp_srv_verifyfile(f, lookup_file)) { respond(r, Enofile); return; } switch(f->tab.type) { case FsFEvent: - pending_pushfid(&events, r->fid); + ixp_pending_pushfid(&events, r->fid); break; case FsFDebug: - pending_pushfid(pdebug+f->id, r->fid); + ixp_pending_pushfid(pdebug+f->id, r->fid); debugfile |= 1<id; break; } - if((r->ifcall.mode&3) == OEXEC) { + + if((r->ifcall.topen.mode&3) == OEXEC + || (r->ifcall.topen.mode&3) != OREAD && !(f->tab.perm & 0200) + || (r->ifcall.topen.mode&3) != OWRITE && !(f->tab.perm & 0400) + || (r->ifcall.topen.mode & ~(3|OAPPEND|OTRUNC))) respond(r, Enoperm); - return; - } - if((r->ifcall.mode&3) != OREAD && !(f->tab.perm & 0200)) { - respond(r, Enoperm); - return; - } - if((r->ifcall.mode&3) != OWRITE && !(f->tab.perm & 0400)) { - respond(r, Enoperm); - return; - } - if((r->ifcall.mode&~(3|OAPPEND|OTRUNC))) { - respond(r, Enoperm); - return; - } - respond(r, nil); + else + respond(r, nil); } void fs_create(Ixp9Req *r) { - FileId *f; + IxpFileId *f; f = r->fid->aux; @@ -993,18 +611,18 @@ fs_create(Ixp9Req *r) { respond(r, Enoperm); return; case FsDBars: - if(!strlen(r->ifcall.name)) { + if(!strlen(r->ifcall.tcreate.name)) { respond(r, Ebadvalue); return; } - bar_create(f->p.bar_p, r->ifcall.name); - f = lookup_file(f, r->ifcall.name); + bar_create(f->p.bar_p, r->ifcall.tcreate.name); + f = lookup_file(f, r->ifcall.tcreate.name); if(!f) { respond(r, Enofile); return; } - r->ofcall.qid.type = f->tab.qtype; - r->ofcall.qid.path = QID(f->tab.type, f->id); + r->ofcall.ropen.qid.type = f->tab.qtype; + r->ofcall.ropen.qid.path = QID(f->tab.type, f->id); f->next = r->fid->aux; r->fid->aux = f; respond(r, nil); @@ -1014,9 +632,10 @@ fs_create(Ixp9Req *r) { void fs_remove(Ixp9Req *r) { - FileId *f = r->fid->aux; - - if(!verify_file(f)) { + IxpFileId *f; + + f = r->fid->aux; + if(!ixp_srv_verifyfile(f, lookup_file)) { respond(r, Enofile); return; } @@ -1036,36 +655,22 @@ fs_remove(Ixp9Req *r) { void fs_clunk(Ixp9Req *r) { - FileId *f; - PLink *pl; - Queue *qu; + IxpFileId *f; char *p, *q; IxpMsg m; f = r->fid->aux; - if(!verify_file(f)) { + if(!ixp_srv_verifyfile(f, lookup_file)) { respond(r, nil); return; } if(f->pending) { /* Should probably be in freefid */ - pl = f->p.p; - pl->prev->next = pl->next; - pl->next->prev = pl->prev; - while((qu = pl->queue)) { - pl->queue = qu->link; - free(qu->dat); - free(qu); - }; - switch(f->tab.type) { - case FsFDebug: - if(pl->pending->fids.next == &pl->pending->fids) + if(ixp_pending_clunk(r)) { + if(f->tab.type == FsFDebug) debugfile &= ~(1<id); - break; } - free(pl); - respond(r, nil); return; } @@ -1085,8 +690,7 @@ fs_clunk(Ixp9Req *r) { update_keys(); break; case FsFBar: - p = toutf8(f->p.bar->buf); - + p = f->p.bar->buf; m = ixp_message(p, strlen(p), 0); msg_parsecolors(&m, &f->p.bar->col); @@ -1097,8 +701,6 @@ fs_clunk(Ixp9Req *r) { q = f->p.bar->text; utflcpy(q, (char*)m.pos, sizeof ((Bar*)0)->text); - free(p); - bar_draw(screen); break; } @@ -1108,31 +710,25 @@ fs_clunk(Ixp9Req *r) { void fs_flush(Ixp9Req *r) { Ixp9Req *or; - FileId *f; - RLink *rl; + IxpFileId *f; or = r->oldreq; f = or->fid->aux; - if(f->pending) { - rl = or->aux; - if(rl) { - rl->prev->next = rl->next; - rl->next->prev = rl->prev; - free(rl); - } - } + if(f->pending) + ixp_pending_flush(r); + /* else die() ? */ respond(r->oldreq, Einterrupted); respond(r, nil); } void fs_freefid(Fid *f) { - FileId *id, *tid; + IxpFileId *id, *tid; tid = f->aux; while((id = tid)) { tid = id->next; - free_file(id); + ixp_srv_freefile(id); } } diff --git a/cmd/wmii/key.c b/cmd/wmii/key.c index 80b647148..0272355c 100644 --- a/cmd/wmii/key.c +++ b/cmd/wmii/key.c @@ -92,7 +92,7 @@ name2key(const char *name) { return nil; } -static Key * +static Key* getkey(const char *name) { char buf[128]; char *seq[8]; diff --git a/cmd/wmii/main.c b/cmd/wmii/main.c index 0b291efb..ab53613b 100644 --- a/cmd/wmii/main.c +++ b/cmd/wmii/main.c @@ -372,7 +372,7 @@ extern int fmtevent(Fmt*); ixp_listen(&srv, ConnectionNumber(display), nil, check_x_event, closedisplay); def.border = 1; - def.colmode = Coldefault; + def.colmode = Colstack; def.font = loadfont(FONT); def.incmode = ISqueeze; diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c index 3ea55edd..4682d160 100644 --- a/cmd/wmii/message.c +++ b/cmd/wmii/message.c @@ -16,7 +16,7 @@ static char Ebadvalue[] = "bad value", Ebadusage[] = "bad usage"; -/* Edit |sort Edit s/"([^"]+)"/L\1/g Edit |tr 'a-z' 'A-Z' */ +/* Edit |sort Edit |sed 's/"([^"]+)"/L\1/g' | tr 'a-z' 'A-Z' */ enum { LFULLSCREEN, LURGENT, @@ -501,6 +501,41 @@ message_root(void *p, IxpMsg *m) { return ret; } +static void +printdebug(int mask) { + int i, j; + + for(i=0, j=0; i < nelem(debugtab); i++) + if(mask & (1< 0) bufprint(" "); + bufprint("%s", debugtab[i]); + } +} + +char* +readctl_root(void) { + bufclear(); + bufprint("bar on %s\n", barpostab[screen->barpos]); + bufprint("border %d\n", def.border); + if(debugflag) { + bufprint("debug "); + printdebug(debugflag); + bufprint("\n"); + } + if(debugfile) { + bufprint("debugfile "); + printdebug(debugfile); + bufprint("\n"); + } + bufprint("focuscolors %s\n", def.focuscolor.colstr); + bufprint("font %s\n", def.font->name); + bufprint("grabmod %s\n", def.grabmod); + bufprint("incmode %s\n", incmodetab[screen->barpos]); + bufprint("normcolors %s\n", def.normcolor.colstr); + bufprint("view %s\n", screen->sel->name); + return buffer; +} + char* message_view(View *v, IxpMsg *m) { Area *a; @@ -555,7 +590,7 @@ message_view(View *v, IxpMsg *m) { case LCOLMODE: s = msg_getword(m); a = strarea(v, s); - if(a == nil || a->floating) + if(a == nil) /* || a->floating) */ return Ebadvalue; s = msg_getword(m); @@ -583,6 +618,29 @@ message_view(View *v, IxpMsg *m) { /* not reached */ } +char* +readctl_view(View *v) { + Area *a; + uint i; + + bufclear(); + bufprint("%s\n", v->name); + + /* select [ ] */ + bufprint("select %a", v->sel); + if(v->sel->sel) + bufprint(" %d", frame_idx(v->sel->sel)); + bufprint("\n"); + + /* select client */ + if(v->sel->sel) + bufprint("select client %C\n", v->sel->sel->client); + + for(a = v->area->next, i = 1; a; a = a->next, i++) + bufprint("colmode %d %s\n", i, column_getmode(a)); + return buffer; +} + static char* msg_debug(IxpMsg *m) { char *opt; @@ -1027,65 +1085,6 @@ msg_sendframe(Frame *f, int sym, bool swap) { return nil; } -static void -printdebug(int mask) { - int i, j; - - for(i=0, j=0; i < nelem(debugtab); i++) - if(mask & (1< 0) - bufprint(" "); - bufprint("%s", debugtab[i]); - } -} - -char* -readctl_root(void) { - bufclear(); - bufprint("bar on %s\n", barpostab[screen->barpos]); - bufprint("border %d\n", def.border); - if(debugflag) { - bufprint("debug "); - printdebug(debugflag); - bufprint("\n"); - } - if(debugfile) { - bufprint("debugfile "); - printdebug(debugfile); - bufprint("\n"); - } - bufprint("focuscolors %s\n", def.focuscolor.colstr); - bufprint("font %s\n", def.font->name); - bufprint("grabmod %s\n", def.grabmod); - bufprint("incmode %s\n", incmodetab[screen->barpos]); - bufprint("normcolors %s\n", def.normcolor.colstr); - bufprint("view %s\n", screen->sel->name); - return buffer; -} - -char* -readctl_view(View *v) { - Area *a; - uint i; - - bufclear(); - bufprint("%s\n", v->name); - - /* select [ ] */ - bufprint("select %a", v->sel); - if(v->sel->sel) - bufprint(" %d", frame_idx(v->sel->sel)); - bufprint("\n"); - - /* select client */ - if(v->sel->sel) - bufprint("select client %C\n", v->sel->sel->client); - - for(a = v->area->next, i = 1; a; a = a->next, i++) - bufprint("colmode %d %s\n", i, column_getmode(a)); - return buffer; -} - void warning(const char *fmt, ...) { va_list ap; diff --git a/cmd/wmii/view.c b/cmd/wmii/view.c index 216af8e7..addf2f5c 100644 --- a/cmd/wmii/view.c +++ b/cmd/wmii/view.c @@ -252,7 +252,8 @@ view_update(View *v) { for(c=client; c; c=c->next) { f = c->sel; - if(f && f->view == v) + if(f && f->view == v + && !(f->area->max && f->area->floating && f->area != v->sel)) client_resize(c, f->r); else { unmap_frame(c); @@ -304,8 +305,11 @@ view_attach(View *v, Frame *f) { c = f->client; a = v->sel; - if(client_floats_p(c)) + if(client_floats_p(c)) { + if(v->sel != v->area) + v->oldsel = v->sel; a = v->area; + } else if((ff = client_groupframe(c, v))) a = ff->area; else if(starting && v->sel->floating) diff --git a/cmd/wmii9menu.c b/cmd/wmii9menu.c index 9e6e3b94..c7cdf811 100644 --- a/cmd/wmii9menu.c +++ b/cmd/wmii9menu.c @@ -35,6 +35,7 @@ * Heavily modified by Kris Maglione for use with wmii. */ +#include #include #include #include diff --git a/cmd/wmiir.c b/cmd/wmiir.c index 8673184b..1e59c171 100644 --- a/cmd/wmiir.c +++ b/cmd/wmiir.c @@ -147,7 +147,7 @@ xawrite(int argc, char *argv[]) { if(fid == nil) fatal("Can't open file '%s': %r\n", file); - nbuf = 0; + nbuf = 1; for(i=0; i < argc; i++) nbuf += strlen(argv[i]) + (i > 0); buf = emalloc(nbuf); diff --git a/config.mk b/config.mk index 5dc29384..27eb98c1 100644 --- a/config.mk +++ b/config.mk @@ -49,7 +49,7 @@ LIBIXP = $(LIBDIR)/libixp.a #LD=pcc # *BSD -#LIBICONV = -liconv +#LIBICONV = -L/usr/local/lib -liconv # +Darwin #STATIC = # Darwin doesn't like static linking #SHARED = -dynamiclib diff --git a/libwmii_hack/hack.c b/libwmii_hack/hack.c index b4ff16b2..ce6d0f6a 100644 --- a/libwmii_hack/hack.c +++ b/libwmii_hack/hack.c @@ -18,8 +18,6 @@ enum { Timeout = 10, }; -typedef int (*XErrorHandler)(Display*, XErrorEvent*); - static void* xlib; static long lastwin; diff --git a/mk/hdr.mk b/mk/hdr.mk index d765a5ff..4d8addc7 100644 --- a/mk/hdr.mk +++ b/mk/hdr.mk @@ -84,7 +84,7 @@ all: .man1.install: set -e; \ - man=$(<:$*.man%=%); \ + man=1; \ path="$(MAN)/man$$man/$*.$$man"; \ echo INSTALL man $$($(CLEANNAME) "$(BASE)/$*($$man)"); \ cp "$<" "$$path"; \ diff --git a/rc/rc.wmii.rc b/rc/rc.wmii.rc index 3bf59136..1e1069e1 100755 --- a/rc/rc.wmii.rc +++ b/rc/rc.wmii.rc @@ -90,7 +90,7 @@ fn Event-Unresponsive { msg = 'The following client is not responding. What would you like to do?' resp = `{wihack -transient $client \ xmessage -nearmouse -buttons Kill,Wait -print \ - $msg $wi_nl '' `{wmiir read /client/sel/label}} + $msg $wi_nl '' `{wmiir read /client/$client/label}} if(~ $resp Kill) wmiir xwrite /client/$client/ctl slay }&} diff --git a/rc/wmiirc.sh b/rc/wmiirc.sh index 3548add6..37af29be 100644 --- a/rc/wmiirc.sh +++ b/rc/wmiirc.sh @@ -211,7 +211,6 @@ unset events local_events # WM Configuration wmiir write /ctl <$xtmp 2>&1 status=$? +[ $? -eq 0 ] || echo $CC -o $outfile $CFLAGS $@ >&2 base=$(echo $BASE | sed 's/,/\\,/g') re='\([^[:space:]/]*\..:[0-9]\)' diff --git a/util/genconfig b/util/genconfig index 3a872c6a..2287191c 100755 --- a/util/genconfig +++ b/util/genconfig @@ -96,7 +96,8 @@ prompt() { unset val if [ -z "$def" -o -n "$force" ]; then echo "$@" - read -p "$var[$def]$(equals) " val + echo -n "$var[$def]$(equals) " + read val echo fi diff --git a/util/link b/util/link index a3ab6f94..7c11fc4a 100755 --- a/util/link +++ b/util/link @@ -24,6 +24,7 @@ echo LD "$($bin/cleanname ${BASE}$outfile)" [ -n "$noisycc" ] && echo $LD -o $outfile $ofiles $LDFLAGS $args $LD -o $outfile $ofiles $LDFLAGS $args >$xtmp 2>&1 status=$? +[ $? -eq 0 ] || $LD -o $outfile $ofiles $LDFLAGS $args >&2 sed 's/.*: In function `[^:]*: *//' $xtmp | egrep . | egrep -v 'is almost always misused|is dangerous, better use|in statically linked applications requires at runtime'