mirror of
https://github.com/0intro/wmii
synced 2024-12-22 19:36:51 +03:00
Best just read the diff.
This commit is contained in:
parent
fc5e60f952
commit
5d69ff8dd8
3
TODO
3
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.
|
||||
|
||||
|
@ -73,6 +73,7 @@ Event Key
|
||||
!
|
||||
eval "cat <<!
|
||||
$(sed "$_sed" | sed '/^[ ]/s/\([$`]\)/\\\1/g')
|
||||
!
|
||||
"
|
||||
}
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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")) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
638
cmd/wmii/fs.c
638
cmd/wmii/fs.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ name2key(const char *name) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
static Key *
|
||||
static Key*
|
||||
getkey(const char *name) {
|
||||
char buf[128];
|
||||
char *seq[8];
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -18,8 +18,6 @@ enum {
|
||||
Timeout = 10,
|
||||
};
|
||||
|
||||
typedef int (*XErrorHandler)(Display*, XErrorEvent*);
|
||||
|
||||
static void* xlib;
|
||||
|
||||
static long lastwin;
|
||||
|
@ -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"; \
|
||||
|
@ -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
|
||||
}&}
|
||||
|
@ -211,7 +211,6 @@ unset events local_events
|
||||
|
||||
# WM Configuration
|
||||
wmiir write /ctl <<!
|
||||
view 1
|
||||
font $WMII_FONT
|
||||
focuscolors $WMII_FOCUSCOLORS
|
||||
normcolors $WMII_NORMCOLORS
|
||||
|
@ -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]\)'
|
||||
|
@ -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
|
||||
|
||||
|
@ -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'
|
||||
|
Loading…
Reference in New Issue
Block a user