Best just read the diff.

This commit is contained in:
Kris Maglione 2008-08-25 12:47:56 -04:00
parent fc5e60f952
commit 5d69ff8dd8
26 changed files with 307 additions and 651 deletions

3
TODO
View File

@ -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.

View File

@ -73,6 +73,7 @@ Event Key
!
eval "cat <<!
$(sed "$_sed" | sed '/^[ ]/s/\([$`]\)/\\\1/g')
!
"
}

View File

@ -10,7 +10,7 @@ HFILES= dat.h fns.h
LIB = ${LIBIXP}
LDFLAGS += -lm ${LIBX11} -lXext -lXrandr ${LIBICONV} -lregexp9 -lbio -lfmt -lutf
CFLAGS += ${INCX11} ${INCICONV} -DVERSION=\"${VERSION}\" \
-DIXP_NEEDAPI=86
-DIXP_NEEDAPI=97
OBJ = area \
bar \
client \

View File

@ -89,7 +89,10 @@ area_create(View *v, Area *pos, uint w) {
a = emallocz(sizeof *a);
a->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;

View File

@ -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) {

View File

@ -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;

View File

@ -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)

View File

@ -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")) {

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
/*

View File

@ -8,75 +8,22 @@
#include <unistd.h>
#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 <ixp_srvutil.h>
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<<i))
pending_write(pdebug+i, buf, n);
ixp_pending_write(pdebug+i, buf, n);
}
static uint fs_size(IxpFileId*);
static void
dostat(Stat *s, uint len, FileId *f) {
dostat(Stat *s, IxpFileId *f) {
s->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<<f->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<<f->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);
}
}

View File

@ -92,7 +92,7 @@ name2key(const char *name) {
return nil;
}
static Key *
static Key*
getkey(const char *name) {
char buf[128];
char *seq[8];

View File

@ -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;

View File

@ -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<<i)) {
if(j++ > 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 <area>[ <frame>] */
bufprint("select %a", v->sel);
if(v->sel->sel)
bufprint(" %d", frame_idx(v->sel->sel));
bufprint("\n");
/* select client <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<<i)) {
if(j++ > 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 <area>[ <frame>] */
bufprint("select %a", v->sel);
if(v->sel->sel)
bufprint(" %d", frame_idx(v->sel->sel));
bufprint("\n");
/* select client <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;

View File

@ -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)

View File

@ -35,6 +35,7 @@
* Heavily modified by Kris Maglione for use with wmii.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@ -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);

View File

@ -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

View File

@ -18,8 +18,6 @@ enum {
Timeout = 10,
};
typedef int (*XErrorHandler)(Display*, XErrorEvent*);
static void* xlib;
static long lastwin;

View File

@ -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"; \

View File

@ -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
}&}

View File

@ -211,7 +211,6 @@ unset events local_events
# WM Configuration
wmiir write /ctl <<!
view 1
font $WMII_FONT
focuscolors $WMII_FOCUSCOLORS
normcolors $WMII_NORMCOLORS

View File

@ -11,6 +11,7 @@ echo CC $($bin/cleanname ${BASE}$outfile)
[ -n "$noisycc" ] && echo $CC -o $outfile $CFLAGS $@
$CC -o $outfile $CFLAGS $@ >$xtmp 2>&1
status=$?
[ $? -eq 0 ] || echo $CC -o $outfile $CFLAGS $@ >&2
base=$(echo $BASE | sed 's/,/\\,/g')
re='\([^[:space:]/]*\..:[0-9]\)'

View File

@ -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

View File

@ -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'