mirror of https://github.com/0intro/wmii
Significant changes:
EWMH support Improvements to fullscreen mode Improvements in focus, especially in no-input windows Cleaner rc.wmii, with wmii.rc include Filter out gcc error/warning dups
This commit is contained in:
parent
ad970838dc
commit
aef6e4c22e
1
Makefile
1
Makefile
|
@ -23,5 +23,6 @@ deb:
|
|||
dpkg-buildpackage -rfakeroot
|
||||
|
||||
include ${ROOT}/mk/dir.mk
|
||||
include ${ROOT}/mk/common.mk
|
||||
INSTDIRS = ${PDIRS}
|
||||
|
||||
|
|
|
@ -27,5 +27,10 @@ OWMIIR=wmiir.o ${OFILES} ${LIBIXP}
|
|||
wmiir.O: ${OWMIIR}
|
||||
${LINK} $@ ${STATIC} ${OWMIIR}
|
||||
|
||||
OMENU=menu.o wmii/x11.o ${OFILES} ${LIBIXP}
|
||||
menu.O: ${OMENU} dall
|
||||
${LINK} $@ ${OMENU}
|
||||
|
||||
wmii9menu.O: wmii9menu.o ${OFILES}
|
||||
${LINK} $@ $*.o ${OFILES} ${LIBX11}
|
||||
|
||||
|
|
15
cmd/util.c
15
cmd/util.c
|
@ -1,6 +1,8 @@
|
|||
/* Written by Kris Maglione <fbsdaemon at gmail dot com> */
|
||||
/* Public domain */
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -44,6 +46,19 @@ fatal(const char *fmt, ...) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
_die(char *file, int line, char *msg) {
|
||||
fprint(2, "%s: dieing at %s:%d: %s\n",
|
||||
file, line, msg);
|
||||
kill(getpid(), SIGABRT);
|
||||
abort(); /* Adds too many frames:
|
||||
* _die()
|
||||
* abort()
|
||||
* raise(SIGABRT)
|
||||
* kill(getpid(), SIGABRT)
|
||||
*/
|
||||
}
|
||||
|
||||
/* Can't malloc */
|
||||
static void
|
||||
mfatal(char *name, uint size) {
|
||||
|
|
|
@ -5,7 +5,7 @@ include ${ROOT}/mk/wmii.mk
|
|||
main.c: ${ROOT}/mk/wmii.mk
|
||||
|
||||
TARG = wmii
|
||||
HFILES= dat.h fns.h x11.h
|
||||
HFILES= dat.h fns.h
|
||||
|
||||
LIB = ${LIBIXP}
|
||||
LDFLAGS += -lm ${LIBX11} -lXext ${LIBICONV} -lregexp9 -lbio -lfmt -lutf
|
||||
|
@ -15,19 +15,20 @@ OBJ = area \
|
|||
client \
|
||||
column \
|
||||
event \
|
||||
ewmh \
|
||||
frame \
|
||||
fs \
|
||||
fs \
|
||||
geom \
|
||||
key \
|
||||
main \
|
||||
map \
|
||||
key \
|
||||
main \
|
||||
map \
|
||||
message \
|
||||
mouse \
|
||||
rule \
|
||||
rule \
|
||||
printevent\
|
||||
utf \
|
||||
view \
|
||||
x11 \
|
||||
utf \
|
||||
view \
|
||||
x11 \
|
||||
../util
|
||||
|
||||
include ${ROOT}/mk/one.mk
|
||||
|
|
112
cmd/wmii/area.c
112
cmd/wmii/area.c
|
@ -5,14 +5,11 @@
|
|||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fns.h"
|
||||
|
||||
static void place_frame(Frame *f);
|
||||
|
||||
Client *
|
||||
Client*
|
||||
area_selclient(Area *a) {
|
||||
if(a && a->sel)
|
||||
return a->sel->client;
|
||||
|
@ -41,8 +38,8 @@ area_name(Area *a) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
Area *
|
||||
create_area(View *v, Area *pos, uint w) {
|
||||
Area*
|
||||
area_create(View *v, Area *pos, uint w) {
|
||||
static ushort id = 1;
|
||||
uint areanum, i;
|
||||
uint minwidth;
|
||||
|
@ -61,7 +58,7 @@ create_area(View *v, Area *pos, uint w) {
|
|||
colnum = areanum - 1;
|
||||
if(w == 0) {
|
||||
if(colnum >= 0) {
|
||||
w = newcolw(v, i);
|
||||
w = view_newcolw(v, i);
|
||||
if (w == 0)
|
||||
w = Dx(screen->r) / (colnum + 1);
|
||||
}
|
||||
|
@ -75,7 +72,7 @@ create_area(View *v, Area *pos, uint w) {
|
|||
return nil;
|
||||
|
||||
if(pos)
|
||||
scale_view(v, Dx(screen->r) - w);
|
||||
view_scale(v, Dx(screen->r) - w);
|
||||
|
||||
a = emallocz(sizeof *a);
|
||||
a->view = v;
|
||||
|
@ -105,24 +102,24 @@ create_area(View *v, Area *pos, uint w) {
|
|||
a->floating = True;
|
||||
|
||||
if(v->sel == nil)
|
||||
focus_area(a);
|
||||
area_focus(a);
|
||||
|
||||
if(!a->floating)
|
||||
write_event("CreateColumn %ud\n", i);
|
||||
event("CreateColumn %ud\n", i);
|
||||
return a;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_area(Area *a) {
|
||||
area_destroy(Area *a) {
|
||||
Client *c;
|
||||
Area *ta;
|
||||
View *v;
|
||||
uint i;
|
||||
int idx;
|
||||
|
||||
v = a->view;
|
||||
|
||||
if(a->frame)
|
||||
fatal("destroying non-empty area");
|
||||
die("destroying non-empty area");
|
||||
|
||||
if(v->revert == a)
|
||||
v->revert = nil;
|
||||
|
@ -131,9 +128,7 @@ destroy_area(Area *a) {
|
|||
if(c->revert == a)
|
||||
c->revert = nil;
|
||||
|
||||
i = 0;
|
||||
for(ta=v->area; ta != a; ta=ta->next)
|
||||
i++;
|
||||
idx = area_idx(a);
|
||||
|
||||
if(a->prev)
|
||||
ta = a->prev;
|
||||
|
@ -149,15 +144,17 @@ destroy_area(Area *a) {
|
|||
if(ta && v->sel == a) {
|
||||
if(ta->floating && ta->next)
|
||||
ta = ta->next;
|
||||
focus_area(ta);
|
||||
area_focus(ta);
|
||||
}
|
||||
write_event("DestroyColumn %ud\n", i);
|
||||
event("DestroyArea %d\n", idx);
|
||||
/* Deprecated */
|
||||
event("DestroyColumn %d\n", idx);
|
||||
|
||||
free(a);
|
||||
}
|
||||
|
||||
void
|
||||
send_to_area(Area *to, Frame *f) {
|
||||
area_moveto(Area *to, Frame *f) {
|
||||
Area *from;
|
||||
|
||||
assert(to->view == f->view);
|
||||
|
@ -165,18 +162,20 @@ send_to_area(Area *to, Frame *f) {
|
|||
from = f->area;
|
||||
|
||||
if(to->floating != from->floating) {
|
||||
Rectangle temp = f->revert;
|
||||
Rectangle tr;
|
||||
|
||||
tr = f->revert;
|
||||
f->revert = f->r;
|
||||
f->r = temp;
|
||||
f->r = tr;
|
||||
}
|
||||
f->client->revert = from;
|
||||
|
||||
detach_from_area(f);
|
||||
attach_to_area(to, f);
|
||||
area_detach(f);
|
||||
area_attach(to, f);
|
||||
}
|
||||
|
||||
void
|
||||
attach_to_area(Area *a, Frame *f) {
|
||||
area_attach(Area *a, Frame *f) {
|
||||
uint n_frame;
|
||||
Frame *ft;
|
||||
Client *c;
|
||||
|
@ -196,25 +195,30 @@ attach_to_area(Area *a, Frame *f) {
|
|||
f->r.max.y = Dy(a->r) / n_frame;
|
||||
}
|
||||
|
||||
insert_frame(a->sel, f);
|
||||
frame_insert(a->sel, f);
|
||||
|
||||
if(a->floating) {
|
||||
place_frame(f);
|
||||
resize_client(f->client, &f->r);
|
||||
client_resize(f->client, f->r);
|
||||
}
|
||||
|
||||
focus_frame(f, False);
|
||||
restack_view(a->view);
|
||||
if(!a->sel) {
|
||||
if(a == a->view->sel)
|
||||
frame_focus(f);
|
||||
else
|
||||
a->sel = f;
|
||||
}
|
||||
view_restack(a->view);
|
||||
|
||||
if(!a->floating)
|
||||
arrange_column(a, False);
|
||||
column_arrange(a, False);
|
||||
|
||||
if(a->frame)
|
||||
assert(a->sel);
|
||||
}
|
||||
|
||||
void
|
||||
detach_from_area(Frame *f) {
|
||||
area_detach(Frame *f) {
|
||||
Frame *pr;
|
||||
Client *c, *cp;
|
||||
Area *a;
|
||||
|
@ -225,27 +229,27 @@ detach_from_area(Frame *f) {
|
|||
c = f->client;
|
||||
|
||||
pr = f->aprev;
|
||||
remove_frame(f);
|
||||
frame_remove(f);
|
||||
|
||||
if(a->sel == f) {
|
||||
if(!pr)
|
||||
pr = a->frame;
|
||||
if(pr && (v->sel == a))
|
||||
focus_frame(pr, False);
|
||||
frame_focus(pr);
|
||||
else
|
||||
a->sel = pr;
|
||||
}
|
||||
|
||||
if(!a->floating) {
|
||||
if(a->frame)
|
||||
arrange_column(a, False);
|
||||
column_arrange(a, False);
|
||||
else {
|
||||
if(v->area->next->next)
|
||||
destroy_area(a);
|
||||
area_destroy(a);
|
||||
else if((a->frame == nil) && (v->area->frame))
|
||||
focus_area(v->area);
|
||||
area_focus(v->area);
|
||||
|
||||
arrange_view(v);
|
||||
view_arrange(v);
|
||||
}
|
||||
}else if(!a->frame) {
|
||||
if(c->trans) {
|
||||
|
@ -253,13 +257,13 @@ detach_from_area(Frame *f) {
|
|||
if(cp && cp->frame) {
|
||||
a = cp->sel->area;
|
||||
if(a->view == v) {
|
||||
focus_area(a);
|
||||
area_focus(a);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(v->area->next->frame)
|
||||
focus_area(v->area->next);
|
||||
area_focus(v->area->next);
|
||||
}else
|
||||
assert(a->sel);
|
||||
}
|
||||
|
@ -279,7 +283,7 @@ bit_set(uint *field, uint width, uint x, uint y, int set) {
|
|||
field[y*width + bx] &= ~mask;
|
||||
}
|
||||
|
||||
static Bool
|
||||
static bool
|
||||
bit_get(uint *field, uint width, uint x, uint y) {
|
||||
enum { divisor = sizeof(uint) * 8 };
|
||||
uint bx, mask;
|
||||
|
@ -292,11 +296,11 @@ bit_get(uint *field, uint width, uint x, uint y) {
|
|||
return (field[y*width + bx] & mask) != 0;
|
||||
}
|
||||
|
||||
/* TODO: Replace this. */
|
||||
static void
|
||||
place_frame(Frame *f) {
|
||||
enum { divisor = sizeof(uint) * 8 };
|
||||
enum { dx = 8, dy = 8 };
|
||||
|
||||
static uint mwidth, mx, my;
|
||||
static uint *field = nil;
|
||||
Align align;
|
||||
|
@ -306,7 +310,7 @@ place_frame(Frame *f) {
|
|||
Frame *fr;
|
||||
Client *c;
|
||||
Area *a;
|
||||
Bool fit;
|
||||
bool fit;
|
||||
uint i, j, x, y, cx, cy, maxx, maxy, diff, num;
|
||||
int snap;
|
||||
|
||||
|
@ -321,7 +325,7 @@ place_frame(Frame *f) {
|
|||
if(c->trans)
|
||||
return;
|
||||
if(c->fullscreen || c->w.hints->position || starting) {
|
||||
f->r = gravclient(c, c->r);
|
||||
f->r = client_grav(c, c->r);
|
||||
return;
|
||||
}
|
||||
if(!field) {
|
||||
|
@ -398,23 +402,25 @@ place_frame(Frame *f) {
|
|||
p1 = subpt(p1, f->r.min);
|
||||
f->r = rectaddpt(f->r, p1);
|
||||
|
||||
rects = rects_of_view(a->view, &num, nil);
|
||||
rects = view_rects(a->view, &num, nil);
|
||||
snap_rect(rects, num, &f->r, &align, snap);
|
||||
if(rects)
|
||||
free(rects);
|
||||
}
|
||||
|
||||
void
|
||||
focus_area(Area *a) {
|
||||
area_focus(Area *a) {
|
||||
Frame *f;
|
||||
View *v;
|
||||
Area *old_a;
|
||||
int i;
|
||||
|
||||
v = a->view;
|
||||
f = a->sel;
|
||||
old_a = v->sel;
|
||||
|
||||
if(view_fullscreen_p(v) && a != v->area)
|
||||
return;
|
||||
|
||||
v->sel = a;
|
||||
|
||||
if((old_a) && (a->floating != old_a->floating))
|
||||
|
@ -423,18 +429,20 @@ focus_area(Area *a) {
|
|||
if(v != screen->sel)
|
||||
return;
|
||||
|
||||
move_focus(old_a->sel, f);
|
||||
|
||||
if(f)
|
||||
focus_client(f->client);
|
||||
client_focus(f->client);
|
||||
else
|
||||
focus_client(nil);
|
||||
client_focus(nil);
|
||||
|
||||
if(a != old_a) {
|
||||
i = 0;
|
||||
for(a = v->area; a != v->sel; a = a->next)
|
||||
i++;
|
||||
event("AreaFocus %s\n", area_name(a));
|
||||
/* Deprecated */
|
||||
if(a->floating)
|
||||
write_event("FocusFloating\n");
|
||||
event("FocusFloating\n");
|
||||
else
|
||||
write_event("ColumnFocus %d\n", i);
|
||||
event("ColumnFocus %d\n", area_idx(a));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,15 +3,13 @@
|
|||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "dat.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fns.h"
|
||||
|
||||
static Handlers handlers;
|
||||
static Bar *free_bars;
|
||||
|
||||
void
|
||||
initbar(WMScreen *s) {
|
||||
bar_init(WMScreen *s) {
|
||||
WinAttr wa;
|
||||
|
||||
s->brect = s->r;
|
||||
|
@ -35,12 +33,12 @@ initbar(WMScreen *s) {
|
|||
mapwin(s->barwin);
|
||||
}
|
||||
|
||||
Bar *
|
||||
create_bar(Bar **bp, char *name) {
|
||||
Bar*
|
||||
bar_create(Bar **bp, const char *name) {
|
||||
static uint id = 1;
|
||||
Bar *b;
|
||||
|
||||
b = bar_of_name(*bp, name);;
|
||||
b = bar_find(*bp, name);;
|
||||
if(b)
|
||||
return b;
|
||||
|
||||
|
@ -56,8 +54,8 @@ create_bar(Bar **bp, char *name) {
|
|||
utflcpy(b->name, name, sizeof(b->name));
|
||||
b->col = def.normcolor;
|
||||
|
||||
for(; *bp; bp = &(*bp)->next)
|
||||
if(strcmp((*bp)->name, name) >= 0)
|
||||
for(; *bp; bp = &bp[0]->next)
|
||||
if(strcmp(bp[0]->name, name) >= 0)
|
||||
break;
|
||||
b->next = *bp;
|
||||
*bp = b;
|
||||
|
@ -66,10 +64,10 @@ create_bar(Bar **bp, char *name) {
|
|||
}
|
||||
|
||||
void
|
||||
destroy_bar(Bar **bp, Bar *b) {
|
||||
bar_destroy(Bar **bp, Bar *b) {
|
||||
Bar **p;
|
||||
|
||||
for(p = bp; *p; p = &(*p)->next)
|
||||
for(p = bp; *p; p = &p[0]->next)
|
||||
if(*p == b) break;
|
||||
*p = b->next;
|
||||
|
||||
|
@ -78,7 +76,7 @@ destroy_bar(Bar **bp, Bar *b) {
|
|||
}
|
||||
|
||||
void
|
||||
resize_bar(WMScreen *s) {
|
||||
bar_resize(WMScreen *s) {
|
||||
View *v;
|
||||
|
||||
s->brect = s->r;
|
||||
|
@ -86,14 +84,14 @@ resize_bar(WMScreen *s) {
|
|||
|
||||
reshapewin(s->barwin, s->brect);
|
||||
|
||||
XSync(display, False);
|
||||
draw_bar(s);
|
||||
sync();
|
||||
bar_draw(s);
|
||||
for(v = view; v; v = v->next)
|
||||
arrange_view(v);
|
||||
view_arrange(v);
|
||||
}
|
||||
|
||||
void
|
||||
draw_bar(WMScreen *s) {
|
||||
bar_draw(WMScreen *s) {
|
||||
Bar *b, *tb, *largest, **pb;
|
||||
Rectangle r;
|
||||
Align align;
|
||||
|
@ -113,12 +111,11 @@ draw_bar(WMScreen *s) {
|
|||
width += Dx(b->r);
|
||||
}
|
||||
|
||||
|
||||
if(width > Dx(s->brect)) { /* Not enough room. Shrink bars until they all fit. */
|
||||
for(nb = 0; nb < nelem(s->bar); nb++)
|
||||
for(b = s->bar[nb]; b; b=b->next) {
|
||||
for(pb = &largest; *pb; pb = &(*pb)->smaller)
|
||||
if(Dx((*pb)->r) < Dx(b->r))
|
||||
for(pb = &largest; *pb; pb = &pb[0]->smaller)
|
||||
if(Dx(pb[0]->r) < Dx(b->r))
|
||||
break;
|
||||
b->smaller = *pb;
|
||||
*pb = b;
|
||||
|
@ -131,13 +128,14 @@ draw_bar(WMScreen *s) {
|
|||
if(Dx(tb->r) * shrink >= Dx(tb->smaller->r))
|
||||
break;
|
||||
}
|
||||
SET(shrink);
|
||||
if(tb)
|
||||
for(b = largest; b != tb->smaller; b = b->smaller)
|
||||
b->r.max.x *= shrink;
|
||||
width += tw * shrink;
|
||||
}
|
||||
|
||||
SET(tb);
|
||||
tb = nil;
|
||||
for(nb = 0; nb < nelem(s->bar); nb++)
|
||||
for(b = s->bar[nb]; b; tb=b, b=b->next) {
|
||||
if(b == s->bar[BarRight])
|
||||
|
@ -159,11 +157,11 @@ draw_bar(WMScreen *s) {
|
|||
border(screen->ibuf, b->r, 1, b->col.border);
|
||||
}
|
||||
copyimage(s->barwin, r, screen->ibuf, ZP);
|
||||
XSync(display, False);
|
||||
sync();
|
||||
}
|
||||
|
||||
Bar*
|
||||
bar_of_name(Bar *bp, const char *name) {
|
||||
bar_find(Bar *bp, const char *name) {
|
||||
Bar *b;
|
||||
|
||||
for(b = bp; b; b = b->next)
|
||||
|
@ -180,16 +178,16 @@ bdown_event(Window *w, XButtonPressedEvent *e) {
|
|||
|
||||
/* Ungrab so a menu can receive events before the button is released */
|
||||
XUngrabPointer(display, e->time);
|
||||
XSync(display, False);
|
||||
sync();
|
||||
|
||||
for(b=screen->bar[BarLeft]; b; b=b->next)
|
||||
if(ptinrect(Pt(e->x, e->y), b->r)) {
|
||||
write_event("LeftBarMouseDown %d %s\n", e->button, b->name);
|
||||
if(rect_haspoint_p(Pt(e->x, e->y), b->r)) {
|
||||
event("LeftBarMouseDown %d %s\n", e->button, b->name);
|
||||
return;
|
||||
}
|
||||
for(b=screen->bar[BarRight]; b; b=b->next)
|
||||
if(ptinrect(Pt(e->x, e->y), b->r)) {
|
||||
write_event("RightBarMouseDown %d %s\n", e->button, b->name);
|
||||
if(rect_haspoint_p(Pt(e->x, e->y), b->r)) {
|
||||
event("RightBarMouseDown %d %s\n", e->button, b->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -198,26 +196,24 @@ static void
|
|||
bup_event(Window *w, XButtonPressedEvent *e) {
|
||||
Bar *b;
|
||||
|
||||
USED(w);
|
||||
USED(e);
|
||||
USED(w, e);
|
||||
|
||||
for(b=screen->bar[BarLeft]; b; b=b->next)
|
||||
if(ptinrect(Pt(e->x, e->y), b->r)) {
|
||||
write_event("LeftBarClick %d %s\n", e->button, b->name);
|
||||
if(rect_haspoint_p(Pt(e->x, e->y), b->r)) {
|
||||
event("LeftBarClick %d %s\n", e->button, b->name);
|
||||
return;
|
||||
}
|
||||
for(b=screen->bar[BarRight]; b; b=b->next)
|
||||
if(ptinrect(Pt(e->x, e->y), b->r)) {
|
||||
write_event("RightBarClick %d %s\n", e->button, b->name);
|
||||
if(rect_haspoint_p(Pt(e->x, e->y), b->r)) {
|
||||
event("RightBarClick %d %s\n", e->button, b->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
expose_event(Window *w, XExposeEvent *e) {
|
||||
USED(w);
|
||||
USED(e);
|
||||
draw_bar(screen);
|
||||
USED(w, e);
|
||||
bar_draw(screen);
|
||||
}
|
||||
|
||||
static Handlers handlers = {
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
*/
|
||||
#include "dat.h"
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "fns.h"
|
||||
|
||||
|
@ -25,8 +22,8 @@ enum {
|
|||
| ButtonReleaseMask
|
||||
};
|
||||
|
||||
Client *
|
||||
create_client(XWindow w, XWindowAttributes *wa) {
|
||||
Client*
|
||||
client_create(XWindow w, XWindowAttributes *wa) {
|
||||
Client **t, *c;
|
||||
WinAttr fwa;
|
||||
|
||||
|
@ -40,13 +37,13 @@ create_client(XWindow w, XWindowAttributes *wa) {
|
|||
c->w.w = w;
|
||||
c->w.r = c->r;
|
||||
|
||||
prop_client(c, xatom("WM_PROTOCOLS"));
|
||||
prop_client(c, xatom("WM_TRANSIENT_FOR"));
|
||||
prop_client(c, xatom("WM_NORMAL_HINTS"));
|
||||
prop_client(c, xatom("WM_HINTS"));
|
||||
prop_client(c, xatom("WM_CLASS"));
|
||||
prop_client(c, xatom("WM_NAME"));
|
||||
prop_client(c, xatom("_MOTIF_WM_HINTS"));
|
||||
client_prop(c, xatom("WM_PROTOCOLS"));
|
||||
client_prop(c, xatom("WM_TRANSIENT_FOR"));
|
||||
client_prop(c, xatom("WM_NORMAL_HINTS"));
|
||||
client_prop(c, xatom("WM_HINTS"));
|
||||
client_prop(c, xatom("WM_CLASS"));
|
||||
client_prop(c, xatom("WM_NAME"));
|
||||
client_prop(c, xatom("_MOTIF_WM_HINTS"));
|
||||
|
||||
XSetWindowBorderWidth(display, w, 0);
|
||||
XAddToSaveSet(display, w);
|
||||
|
@ -71,22 +68,24 @@ create_client(XWindow w, XWindowAttributes *wa) {
|
|||
sethandler(c->framewin, &framehandler);
|
||||
sethandler(&c->w, &handlers);
|
||||
|
||||
ewmh_initclient(c);
|
||||
|
||||
grab_button(c->framewin->w, AnyButton, AnyModifier);
|
||||
|
||||
for(t=&client ;; t=&(*t)->next)
|
||||
for(t=&client ;; t=&t[0]->next)
|
||||
if(!*t) {
|
||||
c->next = *t;
|
||||
*t = c;
|
||||
break;
|
||||
}
|
||||
|
||||
write_event("CreateClient %C\n", c);
|
||||
manage_client(c);
|
||||
event("CreateClient %C\n", c);
|
||||
client_manage(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
manage_client(Client *c) {
|
||||
client_manage(Client *c) {
|
||||
Point p;
|
||||
Client *trans;
|
||||
char *tags;
|
||||
|
@ -113,39 +112,39 @@ manage_client(Client *c) {
|
|||
apply_rules(c);
|
||||
|
||||
if(!starting)
|
||||
update_views();
|
||||
view_update_all();
|
||||
|
||||
if(c->sel->view == screen->sel)
|
||||
focus(c, True);
|
||||
if(!(c->w.ewmh.type & TypeSplash))
|
||||
focus(c, false);
|
||||
flushevents(EnterWindowMask, False);
|
||||
}
|
||||
|
||||
static int /* Temporary Xlib error handler */
|
||||
ignoreerrors(Display *d, XErrorEvent *e) {
|
||||
USED(d);
|
||||
USED(e);
|
||||
USED(d, e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_client(Client *c) {
|
||||
client_destroy(Client *c) {
|
||||
int (*handler)(Display*, XErrorEvent*);
|
||||
Rectangle r;
|
||||
char *dummy;
|
||||
Client **tc;
|
||||
Bool hide;
|
||||
bool hide;
|
||||
|
||||
Dprint("client.c:destroy_client(%p) %s\n", c, c->name);
|
||||
Dprint(DGeneric, "client.c:client_destroy(%p) %s\n", c, c->name);
|
||||
|
||||
unmapwin(c->framewin);
|
||||
|
||||
for(tc=&client; *tc; tc=&(*tc)->next)
|
||||
for(tc=&client; *tc; tc=&tc[0]->next)
|
||||
if(*tc == c) {
|
||||
*tc = c->next;
|
||||
break;
|
||||
}
|
||||
|
||||
r = gravclient(c, ZR);
|
||||
r = client_grav(c, ZR);
|
||||
|
||||
hide = False;
|
||||
if(!c->sel || c->sel->view != screen->sel)
|
||||
|
@ -157,8 +156,8 @@ destroy_client(Client *c) {
|
|||
handler = XSetErrorHandler(ignoreerrors);
|
||||
|
||||
dummy = nil;
|
||||
update_client_views(c, &dummy);
|
||||
unmap_client(c, IconicState);
|
||||
view_setclient(c, &dummy);
|
||||
client_unmap(c, IconicState);
|
||||
sethandler(&c->w, nil);
|
||||
|
||||
if(hide)
|
||||
|
@ -167,11 +166,12 @@ destroy_client(Client *c) {
|
|||
reparentwindow(&c->w, &scr.root, r.min);
|
||||
destroywindow(c->framewin);
|
||||
|
||||
XSync(display, False);
|
||||
sync();
|
||||
XSetErrorHandler(handler);
|
||||
XUngrabServer(display);
|
||||
|
||||
write_event("DestroyClient %C\n", c);
|
||||
ewmh_destroyclient(c);
|
||||
event("DestroyClient %C\n", c);
|
||||
|
||||
flushevents(EnterWindowMask, False);
|
||||
free(c->w.hints);
|
||||
|
@ -179,14 +179,24 @@ destroy_client(Client *c) {
|
|||
}
|
||||
|
||||
/* Convenience functions */
|
||||
Client *
|
||||
Frame*
|
||||
client_viewframe(Client *c, View *v) {
|
||||
Frame *f;
|
||||
|
||||
for(f=c->frame; f; f=f->cnext)
|
||||
if(f->area->view == v)
|
||||
break;
|
||||
return f;
|
||||
}
|
||||
|
||||
Client*
|
||||
selclient(void) {
|
||||
if(screen->sel->sel->sel)
|
||||
return screen->sel->sel->sel->client;
|
||||
return nil;
|
||||
}
|
||||
|
||||
Client *
|
||||
Client*
|
||||
win2client(XWindow w) {
|
||||
Client *c;
|
||||
for(c=client; c; c=c->next)
|
||||
|
@ -204,7 +214,7 @@ Cfmt(Fmt *f) {
|
|||
return fmtprint(f, "<nil>");
|
||||
}
|
||||
|
||||
char *
|
||||
char*
|
||||
clientname(Client *c) {
|
||||
if(c)
|
||||
return c->name;
|
||||
|
@ -212,7 +222,7 @@ clientname(Client *c) {
|
|||
}
|
||||
|
||||
Rectangle
|
||||
gravclient(Client *c, Rectangle rd) {
|
||||
client_grav(Client *c, Rectangle rd) {
|
||||
Rectangle r;
|
||||
Point sp;
|
||||
WinHints *h;
|
||||
|
@ -227,17 +237,17 @@ gravclient(Client *c, Rectangle rd) {
|
|||
else
|
||||
r = c->sel->revert;
|
||||
}else
|
||||
r = client2frame(nil, c->r);
|
||||
r = frame_client2rect(nil, c->r);
|
||||
r = gravitate(r, c->r, h->grav);
|
||||
if(h->gravstatic)
|
||||
r = rectaddpt(r, sp);
|
||||
return frame2client(nil, r);
|
||||
return frame_rect2client(nil, r);
|
||||
}else {
|
||||
r = client2frame(nil, rd);
|
||||
r = frame_client2rect(nil, rd);
|
||||
r = gravitate(rd, r, h->grav);
|
||||
if(h->gravstatic)
|
||||
r = rectsubpt(r, sp);
|
||||
return client2frame(nil, r);
|
||||
return frame_client2rect(nil, r);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,9 +262,9 @@ frame_hints(Frame *f, Rectangle r, Align sticky) {
|
|||
return r;
|
||||
|
||||
or = r;
|
||||
r = frame2client(f, r);
|
||||
r = frame_rect2client(f, r);
|
||||
r = sizehint(c->w.hints, r);
|
||||
r = client2frame(f, r);
|
||||
r = frame_client2rect(f, r);
|
||||
|
||||
if(!f->area->floating) {
|
||||
/* Not allowed to grow */
|
||||
|
@ -274,25 +284,25 @@ frame_hints(Frame *f, Rectangle r, Align sticky) {
|
|||
}
|
||||
|
||||
static void
|
||||
set_client_state(Client * c, int state) {
|
||||
client_setstate(Client * c, int state) {
|
||||
long data[] = { state, None };
|
||||
|
||||
changeprop_long(&c->w, "WM_STATE", "WM_STATE", data, nelem(data));
|
||||
}
|
||||
|
||||
void
|
||||
map_client(Client *c) {
|
||||
client_map(Client *c) {
|
||||
if(!c->w.mapped) {
|
||||
mapwin(&c->w);
|
||||
set_client_state(c, NormalState);
|
||||
client_setstate(c, NormalState);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unmap_client(Client *c, int state) {
|
||||
client_unmap(Client *c, int state) {
|
||||
if(c->w.mapped) {
|
||||
unmapwin(&c->w);
|
||||
set_client_state(c, state);
|
||||
client_setstate(c, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,50 +317,55 @@ unmap_frame(Client *c) {
|
|||
}
|
||||
|
||||
void
|
||||
focus(Client *c, Bool restack) {
|
||||
focus(Client *c, bool user) {
|
||||
View *v;
|
||||
Frame *f;
|
||||
|
||||
f = c->sel;
|
||||
if(!f)
|
||||
return;
|
||||
if(!user && c->noinput)
|
||||
return;
|
||||
|
||||
v = f->area->view;
|
||||
v = f->view;
|
||||
if(v != screen->sel)
|
||||
focus_view(screen, v);
|
||||
focus_frame(c->sel, restack);
|
||||
view_focus(screen, v);
|
||||
frame_focus(c->sel);
|
||||
}
|
||||
|
||||
void
|
||||
focus_client(Client *c) {
|
||||
client_focus(Client *c) {
|
||||
flushevents(FocusChangeMask, True);
|
||||
|
||||
Dprint("focus_client(%p[%C]) => %s\n", c, c, clientname(c));
|
||||
Dprint(DFocus, "client_focus(%p[%C]) => %s\n", c, c, clientname(c));
|
||||
|
||||
if((c == nil || !c->noinput) && screen->focus != c) {
|
||||
Dprint("\t%s => %s\n", clientname(screen->focus), clientname(c));
|
||||
if(c && c->noinput)
|
||||
return;
|
||||
|
||||
if(screen->focus != c) {
|
||||
Dprint(DFocus, "\t%s => %s\n", clientname(screen->focus), clientname(c));
|
||||
|
||||
if(c)
|
||||
setfocus(&c->w, RevertToParent);
|
||||
else
|
||||
setfocus(screen->barwin, RevertToParent);
|
||||
|
||||
write_event("ClientFocus %C\n", c);
|
||||
event("ClientFocus %C\n", c);
|
||||
|
||||
XSync(display, False);
|
||||
sync();
|
||||
flushevents(FocusChangeMask, True);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
resize_client(Client *c, Rectangle *r) {
|
||||
client_resize(Client *c, Rectangle r) {
|
||||
Frame *f;
|
||||
|
||||
f = c->sel;
|
||||
resize_frame(f, *r);
|
||||
frame_resize(f, r);
|
||||
|
||||
if(f->area->view != screen->sel) {
|
||||
unmap_client(c, IconicState);
|
||||
client_unmap(c, IconicState);
|
||||
unmap_frame(c);
|
||||
return;
|
||||
}
|
||||
|
@ -359,24 +374,25 @@ resize_client(Client *c, Rectangle *r) {
|
|||
|
||||
if((f->area->mode == Colmax) && (f->area->sel != f)) {
|
||||
unmap_frame(c);
|
||||
unmap_client(c, IconicState);
|
||||
client_unmap(c, IconicState);
|
||||
}else if(f->collapsed) {
|
||||
reshapewin(c->framewin, f->r);
|
||||
map_frame(c);
|
||||
unmap_client(c, IconicState);
|
||||
client_unmap(c, IconicState);
|
||||
}else {
|
||||
map_client(c);
|
||||
client_map(c);
|
||||
reshapewin(c->framewin, f->r);
|
||||
reshapewin(&c->w, f->crect);
|
||||
map_frame(c);
|
||||
configure_client(c);
|
||||
client_configure(c);
|
||||
ewmh_framesize(c);
|
||||
}
|
||||
|
||||
flushevents(FocusChangeMask|ExposureMask, True);
|
||||
}
|
||||
|
||||
void
|
||||
set_cursor(Client *c, Cursor cur) {
|
||||
client_setcursor(Client *c, Cursor cur) {
|
||||
WinAttr wa;
|
||||
|
||||
if(c->cursor != cur) {
|
||||
|
@ -387,7 +403,7 @@ set_cursor(Client *c, Cursor cur) {
|
|||
}
|
||||
|
||||
void
|
||||
configure_client(Client *c) {
|
||||
client_configure(Client *c) {
|
||||
XConfigureEvent e;
|
||||
Rectangle r;
|
||||
|
||||
|
@ -405,30 +421,27 @@ configure_client(Client *c) {
|
|||
e.height = Dy(r);
|
||||
e.border_width = c->border;
|
||||
|
||||
XSendEvent(display, c->w.w,
|
||||
/*propegate*/ False,
|
||||
StructureNotifyMask,
|
||||
(XEvent*)&e);
|
||||
sendevent(&c->w, false, StructureNotifyMask, (XEvent*)&e);
|
||||
}
|
||||
|
||||
static void
|
||||
send_client_message(Client *c, char *name, char *value) {
|
||||
XEvent e;
|
||||
client_sendmessage(Client *c, char *name, char *value) {
|
||||
XClientMessageEvent e;
|
||||
|
||||
e.type = ClientMessage;
|
||||
e.xclient.window = c->w.w;
|
||||
e.xclient.message_type = xatom(name);
|
||||
e.xclient.format = 32;
|
||||
e.xclient.data.l[0] = xatom(value);
|
||||
e.xclient.data.l[1] = CurrentTime;
|
||||
XSendEvent(display, c->w.w, False, NoEventMask, &e);
|
||||
XSync(display, False);
|
||||
e.window = c->w.w;
|
||||
e.message_type = xatom(name);
|
||||
e.format = 32;
|
||||
e.data.l[0] = xatom(value);
|
||||
e.data.l[1] = CurrentTime;
|
||||
sendevent(&c->w, false, NoEventMask, (XEvent*)&e);
|
||||
sync();
|
||||
}
|
||||
|
||||
void
|
||||
kill_client(Client * c) {
|
||||
client_kill(Client * c) {
|
||||
if(c->proto & WM_PROTOCOL_DELWIN)
|
||||
send_client_message(c, "WM_PROTOCOLS", "WM_DELETE_WINDOW");
|
||||
client_sendmessage(c, "WM_PROTOCOLS", "WM_DELETE_WINDOW");
|
||||
else
|
||||
XKillClient(display, c->w.w);
|
||||
}
|
||||
|
@ -442,8 +455,9 @@ fullscreen(Client *c, int fullscreen) {
|
|||
if(fullscreen == c->fullscreen)
|
||||
return;
|
||||
|
||||
write_event("Fullscreen %C %s\n", c, (fullscreen ? "on" : "off"));
|
||||
event("Fullscreen %C %s\n", c, (fullscreen ? "on" : "off"));
|
||||
c->fullscreen = fullscreen;
|
||||
ewmh_updatestate(c);
|
||||
|
||||
if((f = c->sel)) {
|
||||
if(fullscreen) {
|
||||
|
@ -451,18 +465,18 @@ fullscreen(Client *c, int fullscreen) {
|
|||
f->revert = f->r;
|
||||
else {
|
||||
f->r = f->revert;
|
||||
send_to_area(f->view->area, f);
|
||||
area_moveto(f->view->area, f);
|
||||
}
|
||||
focus_client(c);
|
||||
focus(c, true);
|
||||
}else
|
||||
resize_frame(f, f->revert);
|
||||
frame_resize(f, f->revert);
|
||||
if(f->view == screen->sel)
|
||||
focus_view(screen, f->view);
|
||||
view_focus(screen, f->view);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
set_urgent(Client *c, int urgent, Bool write) {
|
||||
client_seturgent(Client *c, int urgent, bool write) {
|
||||
XWMHints *wmh;
|
||||
char *cwrite, *cnot;
|
||||
Frame *f, *ff;
|
||||
|
@ -475,11 +489,12 @@ set_urgent(Client *c, int urgent, Bool write) {
|
|||
cnot = (urgent ? "" : "Not");
|
||||
|
||||
if(urgent != c->urgent) {
|
||||
write_event("%sUrgent %C %s\n", cnot, c, cwrite);
|
||||
event("%sUrgent %C %s\n", cnot, c, cwrite);
|
||||
c->urgent = urgent;
|
||||
ewmh_updatestate(c);
|
||||
if(c->sel) {
|
||||
if(c->sel->view == screen->sel)
|
||||
draw_frame(c->sel);
|
||||
frame_draw(c->sel);
|
||||
for(f=c->frame; f; f=f->cnext) {
|
||||
SET(ff);
|
||||
if(!urgent)
|
||||
|
@ -487,7 +502,7 @@ set_urgent(Client *c, int urgent, Bool write) {
|
|||
for(ff=a->frame; ff; ff=ff->anext)
|
||||
if(ff->client->urgent) break;
|
||||
if(urgent || ff == nil)
|
||||
write_event("%sUrgentTag %s %s\n", cnot, cwrite, f->view->name);
|
||||
event("%sUrgentTag %s %s\n", cnot, cwrite, f->view->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -521,7 +536,7 @@ update_class(Client *c) {
|
|||
}
|
||||
|
||||
static void
|
||||
update_client_name(Client *c) {
|
||||
client_updatename(Client *c) {
|
||||
char *str;
|
||||
|
||||
c->name[0] = '\0';
|
||||
|
@ -535,7 +550,7 @@ update_client_name(Client *c) {
|
|||
|
||||
update_class(c);
|
||||
if(c->sel)
|
||||
draw_frame(c->sel);
|
||||
frame_draw(c->sel);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -543,10 +558,10 @@ updatemwm(Client *c) {
|
|||
enum {
|
||||
All = 0x1,
|
||||
Border = 0x2,
|
||||
Title = 0x8,
|
||||
FlagDecor = 0x2,
|
||||
Flags = 0,
|
||||
Decor = 2,
|
||||
Title = 0x8,
|
||||
FlagDecor = 0x2,
|
||||
Flags = 0,
|
||||
Decor = 2,
|
||||
};
|
||||
Rectangle r;
|
||||
ulong *ret;
|
||||
|
@ -557,28 +572,27 @@ updatemwm(Client *c) {
|
|||
0L, (void*)&ret, 3L);
|
||||
|
||||
if(c->sel)
|
||||
r = frame2client(c->sel, c->sel->r);
|
||||
r = frame_rect2client(c->sel, c->sel->r);
|
||||
|
||||
c->borderless = 0;
|
||||
c->titleless = 0;
|
||||
if(n >= 3 && (ret[Flags]&FlagDecor)) {
|
||||
if(ret[Decor]&All)
|
||||
ret[Decor] ^= ~0;
|
||||
c->borderless = ((ret[Decor]&Border)==0);
|
||||
c->titleless = ((ret[Decor]&Title)==0);
|
||||
}else {
|
||||
c->borderless = 0;
|
||||
c->titleless = 0;
|
||||
c->borderless = !(ret[Decor]&Border);
|
||||
c->titleless = !(ret[Decor]&Title);
|
||||
}
|
||||
free(ret);
|
||||
|
||||
if(c->sel) {
|
||||
r = client2frame(c->sel, r);
|
||||
resize_client(c, &r);
|
||||
draw_frame(c->sel);
|
||||
r = frame_client2rect(c->sel, r);
|
||||
client_resize(c, r);
|
||||
frame_draw(c->sel);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prop_client(Client *c, Atom a) {
|
||||
client_prop(Client *c, Atom a) {
|
||||
XWMHints *wmh;
|
||||
char **class;
|
||||
int n;
|
||||
|
@ -593,6 +607,9 @@ prop_client(Client *c, Atom a) {
|
|||
updatemwm(c);
|
||||
}
|
||||
else switch (a) {
|
||||
default:
|
||||
ewmh_prop(c, a);
|
||||
break;
|
||||
case XA_WM_TRANSIENT_FOR:
|
||||
XGetTransientForHint(display, c->w.w, &c->trans);
|
||||
break;
|
||||
|
@ -605,7 +622,7 @@ prop_client(Client *c, Atom a) {
|
|||
wmh = XGetWMHints(display, c->w.w);
|
||||
if(wmh) {
|
||||
c->noinput = !((wmh->flags&InputFocus) && wmh->input);
|
||||
set_urgent(c, (wmh->flags & XUrgencyHint) != 0, False);
|
||||
client_seturgent(c, (wmh->flags & XUrgencyHint) != 0, False);
|
||||
XFree(wmh);
|
||||
}
|
||||
break;
|
||||
|
@ -619,7 +636,7 @@ prop_client(Client *c, Atom a) {
|
|||
break;
|
||||
case XA_WM_NAME:
|
||||
wmname:
|
||||
update_client_name(c);
|
||||
client_updatename(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -632,43 +649,41 @@ configreq_event(Window *w, XConfigureRequestEvent *e) {
|
|||
|
||||
c = w->aux;
|
||||
|
||||
r = gravclient(c, ZR);
|
||||
r = client_grav(c, ZR);
|
||||
r.max = subpt(r.max, r.min);
|
||||
|
||||
if(e->value_mask&CWX)
|
||||
if(e->value_mask & CWX)
|
||||
r.min.x = e->x;
|
||||
if(e->value_mask&CWY)
|
||||
if(e->value_mask & CWY)
|
||||
r.min.y = e->y;
|
||||
if(e->value_mask&CWWidth)
|
||||
if(e->value_mask & CWWidth)
|
||||
r.max.x = e->width;
|
||||
if(e->value_mask&CWHeight)
|
||||
if(e->value_mask & CWHeight)
|
||||
r.max.y = e->height;
|
||||
|
||||
if(e->value_mask&CWBorderWidth)
|
||||
if(e->value_mask & CWBorderWidth)
|
||||
c->border = e->border_width;
|
||||
|
||||
r.max = addpt(r.min, r.max);
|
||||
cr = r;
|
||||
r = gravclient(c, r);
|
||||
r = client_grav(c, r);
|
||||
|
||||
if((Dx(cr) == Dx(screen->r)) && (Dy(cr) == Dy(screen->r)))
|
||||
fullscreen(c, True);
|
||||
|
||||
if(c->sel->area->floating)
|
||||
resize_client(c, &r);
|
||||
client_resize(c, r);
|
||||
else {
|
||||
c->sel->revert = r;
|
||||
configure_client(c);
|
||||
client_configure(c);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_event(Window *w, XDestroyWindowEvent *e) {
|
||||
USED(w);
|
||||
USED(e);
|
||||
USED(w, e);
|
||||
|
||||
Dprint("client.c:destroy_event(%W)\n", w);
|
||||
destroy_client(w->aux);
|
||||
client_destroy(w->aux);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -678,11 +693,11 @@ enter_event(Window *w, XCrossingEvent *e) {
|
|||
c = w->aux;
|
||||
if(e->detail != NotifyInferior) {
|
||||
if(screen->focus != c) {
|
||||
Dprint("enter_notify(c) => %s\n", c->name);
|
||||
focus(c, False);
|
||||
Dprint(DGeneric, "enter_notify(c) => %s\n", c->name);
|
||||
focus(c, false);
|
||||
}
|
||||
set_cursor(c, cursor[CurNormal]);
|
||||
}else Dprint("enter_notify(c[NotifyInferior]) => %s\n", c->name);
|
||||
client_setcursor(c, cursor[CurNormal]);
|
||||
}else Dprint(DGeneric, "enter_notify(c[NotifyInferior]) => %s\n", c->name);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -700,7 +715,7 @@ focusin_event(Window *w, XFocusChangeEvent *e) {
|
|||
screen->focus = c;
|
||||
if(c != old) {
|
||||
if(c->sel)
|
||||
draw_frame(c->sel);
|
||||
frame_draw(c->sel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,7 +731,7 @@ focusout_event(Window *w, XFocusChangeEvent *e) {
|
|||
print_focus(&c_magic, "<magic>");
|
||||
screen->focus = &c_magic;
|
||||
if(c->sel)
|
||||
draw_frame(c->sel);
|
||||
frame_draw(c->sel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -727,7 +742,7 @@ unmap_event(Window *w, XUnmapEvent *e) {
|
|||
c = w->aux;
|
||||
if(!e->send_event)
|
||||
c->unmapped--;
|
||||
destroy_client(c);
|
||||
client_destroy(c);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -738,7 +753,7 @@ map_event(Window *w, XMapEvent *e) {
|
|||
|
||||
c = w->aux;
|
||||
if(c == selclient())
|
||||
focus_client(c);
|
||||
client_focus(c);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -749,7 +764,7 @@ property_event(Window *w, XPropertyEvent *e) {
|
|||
return;
|
||||
|
||||
c = w->aux;
|
||||
prop_client(c, e->atom);
|
||||
client_prop(c, e->atom);
|
||||
}
|
||||
|
||||
static Handlers handlers = {
|
||||
|
@ -783,12 +798,12 @@ newcol_client(Client *c, char *arg) {
|
|||
if(!strncmp(arg, "prev", 5)) {
|
||||
for(to=v->area; to; to=to->next)
|
||||
if(to->next == a) break;
|
||||
to = new_column(v, to, 0);
|
||||
send_to_area(to, f);
|
||||
to = column_new(v, to, 0);
|
||||
area_moveto(to, f);
|
||||
}
|
||||
else if(!strncmp(arg, "next", 5)) {
|
||||
to = new_column(v, a, 0);
|
||||
send_to_area(to, f);
|
||||
to = column_new(v, a, 0);
|
||||
area_moveto(to, f);
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
@ -797,7 +812,7 @@ newcol_client(Client *c, char *arg) {
|
|||
#endif
|
||||
|
||||
void
|
||||
update_client_views(Client *c, char **tags) {
|
||||
view_setclient(Client *c, char **tags) {
|
||||
Frame **fp, *f;
|
||||
int cmp;
|
||||
|
||||
|
@ -806,13 +821,13 @@ update_client_views(Client *c, char **tags) {
|
|||
SET(cmp);
|
||||
while(*fp) {
|
||||
if(*tags) {
|
||||
cmp = strcmp((*fp)->view->name, *tags);
|
||||
cmp = strcmp(fp[0]->view->name, *tags);
|
||||
if(cmp >= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
f = *fp;
|
||||
detach_from_area(f);
|
||||
area_detach(f);
|
||||
*fp = f->cnext;
|
||||
if(c->sel == f)
|
||||
c->sel = *fp;
|
||||
|
@ -820,18 +835,18 @@ update_client_views(Client *c, char **tags) {
|
|||
}
|
||||
if(*tags) {
|
||||
if(!*fp || cmp > 0) {
|
||||
f = create_frame(c, get_view(*tags));
|
||||
f = frame_create(c, view_create(*tags));
|
||||
if(f->view == screen->sel || !c->sel)
|
||||
c->sel = f;
|
||||
attach_to_view(f->view, f);
|
||||
view_attach(f->view, f);
|
||||
f->cnext = *fp;
|
||||
*fp = f;
|
||||
}
|
||||
if(*fp) fp=&(*fp)->cnext;
|
||||
if(fp[0]) fp=&fp[0]->cnext;
|
||||
tags++;
|
||||
}
|
||||
}
|
||||
update_views();
|
||||
view_update_all();
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -840,8 +855,12 @@ bsstrcmp(const void *a, const void *b) {
|
|||
}
|
||||
|
||||
static int
|
||||
strpcmp(const void *a, const void *b) {
|
||||
return strcmp(*(char **)a, *(char **)b);
|
||||
strpcmp(const void *ap, const void *bp) {
|
||||
char **a, **b;
|
||||
|
||||
a = (char**)ap;
|
||||
b = (char**)bp;
|
||||
return strcmp(*a, *b);
|
||||
}
|
||||
|
||||
static char *badtags[] = {
|
||||
|
@ -853,7 +872,7 @@ static char *badtags[] = {
|
|||
void
|
||||
apply_tags(Client *c, const char *tags) {
|
||||
uint i, j, k, n;
|
||||
Bool add;
|
||||
bool add;
|
||||
char buf[512], last;
|
||||
char *toks[32], *cur;
|
||||
|
||||
|
@ -934,9 +953,9 @@ apply_tags(Client *c, const char *tags) {
|
|||
}
|
||||
toks[n] = nil;
|
||||
|
||||
update_client_views(c, toks);
|
||||
view_setclient(c, toks);
|
||||
|
||||
changeprop_char(&c->w, "_WMII_TAGS", "UTF8_STRING", c->tags, strlen(c->tags));
|
||||
changeprop_string(&c->w, "_WMII_TAGS", c->tags);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "fns.h"
|
||||
|
||||
|
@ -76,7 +74,7 @@ unmapdiv(Divide *d) {
|
|||
}
|
||||
|
||||
void
|
||||
setdiv(Divide *d, int x) {
|
||||
div_set(Divide *d, int x) {
|
||||
Rectangle r;
|
||||
|
||||
d->x = x;
|
||||
|
@ -140,7 +138,7 @@ update_imgs(void) {
|
|||
}
|
||||
|
||||
void
|
||||
update_divs(void) {
|
||||
div_update_all(void) {
|
||||
Divide **dp, *d;
|
||||
Area *a;
|
||||
View *v;
|
||||
|
@ -152,12 +150,12 @@ update_divs(void) {
|
|||
for(a = v->area->next; a; a = a->next) {
|
||||
d = getdiv(dp);
|
||||
dp = &d->next;
|
||||
setdiv(d, a->r.min.x);
|
||||
div_set(d, a->r.min.x);
|
||||
|
||||
if(!a->next) {
|
||||
d = getdiv(dp);
|
||||
dp = &d->next;
|
||||
setdiv(d, a->r.max.x);
|
||||
div_set(d, a->r.max.x);
|
||||
}
|
||||
}
|
||||
for(d = *dp; d; d = d->next)
|
||||
|
@ -190,17 +188,17 @@ static Handlers divhandler = {
|
|||
.expose = expose_event,
|
||||
};
|
||||
|
||||
Area *
|
||||
new_column(View *v, Area *pos, uint w) {
|
||||
Area*
|
||||
column_new(View *v, Area *pos, uint w) {
|
||||
Area *a;
|
||||
|
||||
a = create_area(v, pos, w);
|
||||
a = area_create(v, pos, w);
|
||||
if(!a)
|
||||
return nil;
|
||||
|
||||
arrange_view(v);
|
||||
view_arrange(v);
|
||||
if(v == screen->sel)
|
||||
focus_view(screen, v);
|
||||
view_focus(screen, v);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -223,7 +221,7 @@ scale_column(Area *a) {
|
|||
nuncol = 0;
|
||||
dy = 0;
|
||||
for(f=a->frame; f; f=f->anext) {
|
||||
resize_frame(f, f->r);
|
||||
frame_resize(f, f->r);
|
||||
if(f->collapsed)
|
||||
ncol++;
|
||||
else
|
||||
|
@ -260,7 +258,7 @@ scale_column(Area *a) {
|
|||
if(f->collapsed) {
|
||||
if(i < 0 && (f != a->sel)) {
|
||||
f->collapsed = False;
|
||||
send_to_area(f->view->area, f);
|
||||
area_moveto(f->view->area, f);
|
||||
continue;
|
||||
}
|
||||
i--;
|
||||
|
@ -298,7 +296,7 @@ scale_column(Area *a) {
|
|||
for(f=a->frame; f; f=f->anext) {
|
||||
if(!f->collapsed)
|
||||
f->r.max.y += f->ratio * surplus;
|
||||
resize_frame(f, f->r);
|
||||
frame_resize(f, f->r);
|
||||
dy += Dy(f->r);
|
||||
}
|
||||
surplus = Dy(a->r) - dy;
|
||||
|
@ -307,7 +305,7 @@ scale_column(Area *a) {
|
|||
if(!f->collapsed) {
|
||||
dy = Dy(f->r);
|
||||
f->r.max.y += surplus;
|
||||
resize_frame(f, f->r);
|
||||
frame_resize(f, f->r);
|
||||
f->r.max.y = Dy(f->crect) + labelh(def.font) + 1;
|
||||
surplus -= Dy(f->r) - dy;
|
||||
}
|
||||
|
@ -329,7 +327,7 @@ scale_column(Area *a) {
|
|||
}
|
||||
|
||||
void
|
||||
arrange_column(Area *a, Bool dirty) {
|
||||
column_arrange(Area *a, bool dirty) {
|
||||
Frame *f;
|
||||
|
||||
if(a->floating || !a->frame)
|
||||
|
@ -352,26 +350,26 @@ arrange_column(Area *a, Bool dirty) {
|
|||
}
|
||||
goto resize;
|
||||
default:
|
||||
assert(!"Can't happen");
|
||||
die("can't get here");
|
||||
break;
|
||||
}
|
||||
scale_column(a);
|
||||
resize:
|
||||
if(a->view == screen->sel) {
|
||||
restack_view(a->view);
|
||||
resize_client(a->sel->client, &a->sel->r);
|
||||
view_restack(a->view);
|
||||
client_resize(a->sel->client, a->sel->r);
|
||||
|
||||
for(f=a->frame; f; f=f->anext)
|
||||
if(!f->collapsed && f != a->sel)
|
||||
resize_client(f->client, &f->r);
|
||||
client_resize(f->client, f->r);
|
||||
for(f=a->frame; f; f=f->anext)
|
||||
if(f->collapsed && f != a->sel)
|
||||
resize_client(f->client, &f->r);
|
||||
client_resize(f->client, f->r);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
resize_column(Area *a, int w) {
|
||||
column_resize(Area *a, int w) {
|
||||
Area *an;
|
||||
int dw;
|
||||
|
||||
|
@ -382,8 +380,8 @@ resize_column(Area *a, int w) {
|
|||
a->r.max.x += dw;
|
||||
an->r.min.x += dw;
|
||||
|
||||
arrange_view(a->view);
|
||||
focus_view(screen, a->view);
|
||||
view_arrange(a->view);
|
||||
view_focus(screen, a->view);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -410,18 +408,18 @@ resize_colframeh(Frame *f, Rectangle *r) {
|
|||
|
||||
if(fp) {
|
||||
fp->r.max.y = r->min.y;
|
||||
resize_frame(fp, fp->r);
|
||||
frame_resize(fp, fp->r);
|
||||
}
|
||||
if(fn) {
|
||||
fn->r.min.y = r->max.y;
|
||||
resize_frame(fn, fn->r);
|
||||
frame_resize(fn, fn->r);
|
||||
}
|
||||
|
||||
resize_frame(f, *r);
|
||||
frame_resize(f, *r);
|
||||
}
|
||||
|
||||
void
|
||||
resize_colframe(Frame *f, Rectangle *r) {
|
||||
column_resizeframe(Frame *f, Rectangle *r) {
|
||||
Area *a, *al, *ar;
|
||||
View *v;
|
||||
uint minw;
|
||||
|
@ -441,29 +439,26 @@ resize_colframe(Frame *f, Rectangle *r) {
|
|||
else
|
||||
r->min.x = max(r->min.x, 0);
|
||||
|
||||
if(ar) {
|
||||
if(maxx >= ar->r.max.x - minw)
|
||||
maxx = ar->r.max.x - minw;
|
||||
}
|
||||
if(ar)
|
||||
maxx = min(maxx, a->r.max.x - minw);
|
||||
else
|
||||
if(maxx > screen->r.max.x)
|
||||
maxx = screen->r.max.x;
|
||||
maxx = min(maxx, screen->r.max.x);
|
||||
|
||||
dx = a->r.min.x - r->min.x;
|
||||
dw = maxx - a->r.max.x;
|
||||
if(al) {
|
||||
al->r.max.x -= dx;
|
||||
arrange_column(al, False);
|
||||
column_arrange(al, False);
|
||||
}
|
||||
if(ar) {
|
||||
ar->r.max.x -= dw;
|
||||
arrange_column(ar, False);
|
||||
column_arrange(ar, False);
|
||||
}
|
||||
|
||||
resize_colframeh(f, r);
|
||||
|
||||
a->r.max.x = maxx;
|
||||
arrange_view(a->view);
|
||||
view_arrange(a->view);
|
||||
|
||||
focus_view(screen, v);
|
||||
view_focus(screen, v);
|
||||
}
|
||||
|
|
319
cmd/wmii/dat.h
319
cmd/wmii/dat.h
|
@ -6,43 +6,40 @@
|
|||
#define IXP_P9_STRUCTS
|
||||
#define IXP_NO_P9_
|
||||
#include <regexp9.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ixp.h>
|
||||
#include <util.h>
|
||||
#include <utf.h>
|
||||
#include <fmt.h>
|
||||
#include "x11.h"
|
||||
#include <x11.h>
|
||||
|
||||
#define FONT "-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*"
|
||||
#define FOCUSCOLORS "#ffffff #335577 #447799"
|
||||
#define NORMCOLORS "#222222 #eeeeee #666666"
|
||||
|
||||
enum Align {
|
||||
NORTH = 0x01,
|
||||
EAST = 0x02,
|
||||
SOUTH = 0x04,
|
||||
WEST = 0x08,
|
||||
NEAST = NORTH | EAST,
|
||||
NWEST = NORTH | WEST,
|
||||
SEAST = SOUTH | EAST,
|
||||
SWEST = SOUTH | WEST,
|
||||
CENTER = NEAST | SWEST,
|
||||
};
|
||||
|
||||
typedef struct CTuple CTuple;
|
||||
typedef enum Align Align;
|
||||
|
||||
struct CTuple {
|
||||
ulong bg;
|
||||
ulong fg;
|
||||
ulong border;
|
||||
char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
|
||||
enum EWMHType {
|
||||
TypeDesktop = 1<<0,
|
||||
TypeDock = 1<<1,
|
||||
TypeToolbar = 1<<2,
|
||||
TypeMenu = 1<<3,
|
||||
TypeUtility = 1<<4,
|
||||
TypeSplash = 1<<5,
|
||||
TypeDialog = 1<<6,
|
||||
TypeNormal = 1<<7,
|
||||
};
|
||||
|
||||
enum {
|
||||
Coldefault, Colstack, Colmax,
|
||||
};
|
||||
|
||||
#define TOGGLE(x) \
|
||||
(x == On ? "On" : \
|
||||
x == Off ? "Off" : \
|
||||
x == Toggle ? "Toggle" : \
|
||||
"<toggle>")
|
||||
enum {
|
||||
Off,
|
||||
On,
|
||||
|
@ -62,202 +59,222 @@ enum {
|
|||
WM_PROTOCOL_DELWIN = 1,
|
||||
};
|
||||
|
||||
enum DebugOpt {
|
||||
DEvent = 1<<0,
|
||||
DEwmh = 1<<1,
|
||||
DFocus = 1<<2,
|
||||
DGeneric= 1<<3,
|
||||
};
|
||||
|
||||
/* Data Structures */
|
||||
typedef struct View View;
|
||||
typedef struct Area Area;
|
||||
typedef struct Frame Frame;
|
||||
typedef struct Bar Bar;
|
||||
typedef struct Client Client;
|
||||
typedef struct Divide Divide;
|
||||
typedef struct Frame Frame;
|
||||
typedef struct Key Key;
|
||||
typedef struct Bar Bar;
|
||||
typedef struct Rule Rule;
|
||||
typedef struct Ruleset Ruleset;
|
||||
typedef struct WMScreen WMScreen;
|
||||
typedef struct Map Map;
|
||||
typedef struct MapEnt MapEnt;
|
||||
typedef struct Rule Rule;
|
||||
typedef struct Ruleset Ruleset;
|
||||
typedef struct View View;
|
||||
typedef struct WMScreen WMScreen;
|
||||
|
||||
struct Map {
|
||||
MapEnt **bucket;
|
||||
uint nhash;
|
||||
MapEnt**bucket;
|
||||
uint nhash;
|
||||
};
|
||||
|
||||
struct MapEnt {
|
||||
ulong hash;
|
||||
char *key;
|
||||
void *val;
|
||||
MapEnt *next;
|
||||
ulong hash;
|
||||
const char* key;
|
||||
void* val;
|
||||
MapEnt* next;
|
||||
};
|
||||
|
||||
struct View {
|
||||
View *next;
|
||||
char name[256];
|
||||
ushort id;
|
||||
Area *area;
|
||||
Area *sel;
|
||||
Area *revert;
|
||||
View* next;
|
||||
char name[256];
|
||||
ushort id;
|
||||
Area* area;
|
||||
Area* sel;
|
||||
Area* revert;
|
||||
};
|
||||
|
||||
struct Area {
|
||||
Area *next, *prev;
|
||||
Frame *frame;
|
||||
Frame *stack;
|
||||
Frame *sel;
|
||||
View *view;
|
||||
Bool floating;
|
||||
ushort id;
|
||||
int mode;
|
||||
Rectangle r;
|
||||
Area* next;
|
||||
Area* prev;
|
||||
Frame* frame;
|
||||
Frame* stack;
|
||||
Frame* sel;
|
||||
View* view;
|
||||
bool floating;
|
||||
ushort id;
|
||||
int mode;
|
||||
Rectangle r;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
Frame *cnext;
|
||||
Frame *anext, *aprev;
|
||||
Frame *snext, *sprev;
|
||||
View *view;
|
||||
Area *area;
|
||||
ushort id;
|
||||
Rectangle r;
|
||||
Rectangle crect;
|
||||
Rectangle revert;
|
||||
Client *client;
|
||||
Bool collapsed;
|
||||
Rectangle grabbox;
|
||||
Rectangle titlebar;
|
||||
float ratio;
|
||||
Frame* cnext;
|
||||
Frame* anext;
|
||||
Frame* aprev;
|
||||
Frame* snext;
|
||||
Frame* sprev;
|
||||
View* view;
|
||||
Area* area;
|
||||
Client* client;
|
||||
ushort id;
|
||||
bool collapsed;
|
||||
float ratio;
|
||||
Rectangle r;
|
||||
Rectangle crect;
|
||||
Rectangle revert;
|
||||
Rectangle grabbox;
|
||||
Rectangle titlebar;
|
||||
};
|
||||
|
||||
struct Client {
|
||||
Client *next;
|
||||
Area *revert;
|
||||
Frame *frame;
|
||||
Frame *sel;
|
||||
char name[256];
|
||||
char tags[256];
|
||||
char props[512];
|
||||
uint border;
|
||||
int proto;
|
||||
Bool floating;
|
||||
Bool fixedsize;
|
||||
Bool fullscreen;
|
||||
Bool urgent;
|
||||
Bool borderless;
|
||||
Bool titleless;
|
||||
Bool noinput;
|
||||
int unmapped;
|
||||
Window w;
|
||||
XWindow trans;
|
||||
Window *framewin;
|
||||
Cursor cursor;
|
||||
Client* next;
|
||||
Area* revert;
|
||||
Frame* frame;
|
||||
Frame* sel;
|
||||
Window w;
|
||||
Window* framewin;
|
||||
XWindow trans;
|
||||
Cursor cursor;
|
||||
Rectangle r;
|
||||
XSizeHints size;
|
||||
GC gc;
|
||||
char name[256];
|
||||
char tags[256];
|
||||
char props[512];
|
||||
uint border;
|
||||
int proto;
|
||||
char floating;
|
||||
char fixedsize;
|
||||
char fullscreen;
|
||||
char urgent;
|
||||
char borderless;
|
||||
char titleless;
|
||||
char noinput;
|
||||
int unmapped;
|
||||
};
|
||||
|
||||
struct Divide {
|
||||
Divide *next;
|
||||
Window *w;
|
||||
Bool mapped;
|
||||
int x;
|
||||
Divide* next;
|
||||
Window* w;
|
||||
bool mapped;
|
||||
int x;
|
||||
};
|
||||
|
||||
struct Key {
|
||||
Key *next;
|
||||
Key *lnext;
|
||||
Key *tnext;
|
||||
ushort id;
|
||||
char name[128];
|
||||
ulong mod;
|
||||
KeyCode key;
|
||||
Key* next;
|
||||
Key* lnext;
|
||||
Key* tnext;
|
||||
ushort id;
|
||||
char name[128];
|
||||
ulong mod;
|
||||
KeyCode key;
|
||||
};
|
||||
|
||||
struct Bar {
|
||||
Bar *next;
|
||||
Bar *smaller;
|
||||
char buf[280];
|
||||
char text[256];
|
||||
char name[256];
|
||||
ushort id;
|
||||
Bar* next;
|
||||
Bar* smaller;
|
||||
char buf[280];
|
||||
char text[256];
|
||||
char name[256];
|
||||
ushort id;
|
||||
Rectangle r;
|
||||
CTuple col;
|
||||
CTuple col;
|
||||
};
|
||||
|
||||
struct Rule {
|
||||
Rule *next;
|
||||
Reprog *regex;
|
||||
char value[256];
|
||||
Rule* next;
|
||||
Reprog* regex;
|
||||
char value[256];
|
||||
};
|
||||
|
||||
struct Ruleset {
|
||||
Rule *rule;
|
||||
char *string;
|
||||
uint size;
|
||||
Rule *rule;
|
||||
char *string;
|
||||
uint size;
|
||||
};
|
||||
|
||||
#ifndef EXTERN
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* global variables */
|
||||
struct {
|
||||
CTuple focuscolor;
|
||||
CTuple normcolor;
|
||||
Font *font;
|
||||
uint border;
|
||||
uint snap;
|
||||
char *keys;
|
||||
uint keyssz;
|
||||
EXTERN struct {
|
||||
CTuple focuscolor;
|
||||
CTuple normcolor;
|
||||
Font* font;
|
||||
char* keys;
|
||||
uint keyssz;
|
||||
Ruleset tagrules;
|
||||
Ruleset colrules;
|
||||
char grabmod[5];
|
||||
ulong mod;
|
||||
int colmode;
|
||||
char grabmod[5];
|
||||
ulong mod;
|
||||
uint border;
|
||||
uint snap;
|
||||
int colmode;
|
||||
} def;
|
||||
|
||||
enum {
|
||||
BarLeft, BarRight
|
||||
};
|
||||
|
||||
struct WMScreen {
|
||||
Bar *bar[2];
|
||||
View *sel;
|
||||
Client *focus;
|
||||
Client *hasgrab;
|
||||
Window *barwin;
|
||||
Image *ibuf;
|
||||
#define BLOCK(x) do { x; }while(0)
|
||||
|
||||
EXTERN struct WMScreen {
|
||||
Bar* bar[2];
|
||||
View* sel;
|
||||
Client* focus;
|
||||
Client* hasgrab;
|
||||
Window* barwin;
|
||||
Image* ibuf;
|
||||
|
||||
Rectangle r;
|
||||
Rectangle brect;
|
||||
} *screens, *screen;
|
||||
|
||||
Client *client;
|
||||
View *view;
|
||||
Key *key;
|
||||
Divide *divs;
|
||||
Client c_magic;
|
||||
Client c_root;
|
||||
EXTERN Client* client;
|
||||
EXTERN View* view;
|
||||
EXTERN Key* key;
|
||||
EXTERN Divide* divs;
|
||||
EXTERN Client c_magic;
|
||||
EXTERN Client c_root;
|
||||
|
||||
Handlers framehandler;
|
||||
EXTERN Handlers framehandler;
|
||||
|
||||
char buffer[8092];
|
||||
EXTERN char buffer[8092];
|
||||
EXTERN char* _buffer;
|
||||
static char* const _buf_end = buffer + sizeof buffer;
|
||||
|
||||
#define bufclear() \
|
||||
BLOCK( _buffer = buffer; _buffer[0] = '\0' )
|
||||
#define bufprint(...) \
|
||||
_buffer = seprint(_buffer, _buf_end, __VA_ARGS__)
|
||||
|
||||
/* IXP */
|
||||
IxpServer srv;
|
||||
Ixp9Srv p9srv;
|
||||
EXTERN IxpServer srv;
|
||||
EXTERN Ixp9Srv p9srv;
|
||||
|
||||
/* X11 */
|
||||
uint num_screens;
|
||||
uint valid_mask;
|
||||
uint num_lock_mask;
|
||||
Bool sel_screen;
|
||||
EXTERN uint num_screens;
|
||||
EXTERN uint valid_mask;
|
||||
EXTERN uint numlock_mask;
|
||||
EXTERN bool sel_screen;
|
||||
|
||||
Image xor;
|
||||
EXTERN Cursor cursor[CurLast];
|
||||
|
||||
Cursor cursor[CurLast];
|
||||
void (*handler[LASTEvent]) (XEvent *);
|
||||
typedef void (*XHandler)(XEvent*);
|
||||
EXTERN XHandler handler[LASTEvent];
|
||||
|
||||
/* Misc */
|
||||
Image *broken;
|
||||
Bool starting;
|
||||
Bool verbose;
|
||||
char *user;
|
||||
char *execstr;
|
||||
EXTERN bool starting;
|
||||
EXTERN char* user;
|
||||
EXTERN char* execstr;
|
||||
EXTERN int debug;
|
||||
|
||||
#define Debug if(verbose)
|
||||
#define Dprint(...) do{ Debug fprint(2, __VA_ARGS__); }while(0)
|
||||
#define Debug(x) if(debug&(x))
|
||||
#define Dprint(x, ...) BLOCK( Debug(x) fprint(2, __VA_ARGS__) )
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "dat.h"
|
||||
#include <stdio.h>
|
||||
#include <X11/keysym.h>
|
||||
#include "fns.h"
|
||||
#include "printevent.h"
|
||||
|
||||
void
|
||||
dispatch_event(XEvent *e) {
|
||||
Debug printevent(e);
|
||||
Debug(DEvent)
|
||||
printevent(e);
|
||||
if(handler[e->type])
|
||||
handler[e->type](e);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ dispatch_event(XEvent *e) {
|
|||
#define handle(w, fn, ev) if(!(w)->handler->fn) {}else (w)->handler->fn((w), ev)
|
||||
|
||||
uint
|
||||
flushevents(long event_mask, Bool dispatch) {
|
||||
flushevents(long event_mask, bool dispatch) {
|
||||
XEvent ev;
|
||||
uint n = 0;
|
||||
|
||||
|
@ -72,6 +72,14 @@ configurerequest(XEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clientmessage(XEvent *e) {
|
||||
XClientMessageEvent *ev;
|
||||
|
||||
ev = &e->xclient;
|
||||
ewmh_clientmessage(ev);
|
||||
}
|
||||
|
||||
static void
|
||||
destroynotify(XEvent *e) {
|
||||
XDestroyWindowEvent *ev;
|
||||
|
@ -82,7 +90,7 @@ destroynotify(XEvent *e) {
|
|||
if((w = findwin(ev->window)))
|
||||
handle(w, destroy, ev);
|
||||
else {
|
||||
Dprint("DestroyWindow(%ux) (no handler)\n", (uint)ev->window);
|
||||
Dprint(DGeneric, "DestroyWindow(%ux) (no handler)\n", (uint)ev->window);
|
||||
if((c = win2client(ev->window)))
|
||||
fprint(2, "Badness: Unhandled DestroyNotify: "
|
||||
"Client: %p, Window: %W, Name: %s\n", c, &c->w, c->name);
|
||||
|
@ -102,7 +110,7 @@ enternotify(XEvent *e) {
|
|||
handle(w, enter, ev);
|
||||
else if(ev->window == scr.root.w) {
|
||||
sel_screen = True;
|
||||
draw_frames();
|
||||
frame_draw_all();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,15 +121,15 @@ leavenotify(XEvent *e) {
|
|||
ev = &e->xcrossing;
|
||||
if((ev->window == scr.root.w) && !ev->same_screen) {
|
||||
sel_screen = True;
|
||||
draw_frames();
|
||||
frame_draw_all();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_focus(Client *c, char *to) {
|
||||
Dprint("screen->focus: %p[%C] => %p[%C]\n",
|
||||
print_focus(Client *c, const char *to) {
|
||||
Dprint(DFocus, "screen->focus: %p[%C] => %p[%C]\n",
|
||||
screen->focus, screen->focus, c, c);
|
||||
Dprint("\t%s => %s\n", clientname(screen->focus), to);
|
||||
Dprint(DFocus, "\t%s => %s\n", clientname(screen->focus), to);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -162,7 +170,7 @@ focusin(XEvent *e) {
|
|||
print_focus(&c_magic, "<magic>");
|
||||
screen->focus = &c_magic;
|
||||
if(c->sel)
|
||||
draw_frame(c->sel);
|
||||
frame_draw(c->sel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,11 +242,11 @@ maprequest(XEvent *e) {
|
|||
|
||||
if(wa.override_redirect) {
|
||||
XSelectInput(display, ev->window,
|
||||
(StructureNotifyMask | PropertyChangeMask));
|
||||
(StructureNotifyMask | PropertyChangeMask));
|
||||
return;
|
||||
}
|
||||
if(!win2client(ev->window))
|
||||
create_client(ev->window, &wa);
|
||||
client_create(ev->window, &wa);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -287,6 +295,7 @@ void (*handler[LASTEvent]) (XEvent *) = {
|
|||
[ButtonPress] = buttonpress,
|
||||
[ButtonRelease] = buttonrelease,
|
||||
[ConfigureRequest] = configurerequest,
|
||||
[ClientMessage] = clientmessage,
|
||||
[DestroyNotify] = destroynotify,
|
||||
[EnterNotify] = enternotify,
|
||||
[Expose] = expose,
|
||||
|
|
|
@ -0,0 +1,388 @@
|
|||
/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
Window *ewmhwin;
|
||||
|
||||
#define Net(x) ("_NET_" x)
|
||||
#define Action(x) ("_NET_WM_ACTION_" x)
|
||||
#define State(x) ("_NET_WM_STATE_" x)
|
||||
#define Type(x) ("_NET_WM_WINDOW_TYPE_" x)
|
||||
#define NET(x) xatom(Net(x))
|
||||
#define ACTION(x) xatom(Action(x))
|
||||
#define STATE(x) xatom(State(x))
|
||||
#define TYPE(x) xatom(Type(x))
|
||||
|
||||
void
|
||||
ewmh_init(void) {
|
||||
WinAttr wa;
|
||||
char myname[] = "wmii";
|
||||
long win[1];
|
||||
|
||||
ewmhwin = createwindow(&scr.root,
|
||||
Rect(0, 0, 1, 1), 0 /*depth*/,
|
||||
InputOnly, &wa, 0);
|
||||
|
||||
win[0] = ewmhwin->w;
|
||||
changeprop_long(&scr.root, Net("SUPPORTING_WM_CHECK"), "WINDOW",
|
||||
win, 1);
|
||||
changeprop_long(ewmhwin, Net("SUPPORTING_WM_CHECK"), "WINDOW",
|
||||
win, 1);
|
||||
changeprop_string(ewmhwin, Net("WM_NAME"), myname);
|
||||
changeprop_long(&scr.root, Net("DESKTOP_VIEWPORT"), "CARDINAL",
|
||||
(long[]){0, 0}, 2);
|
||||
|
||||
long supported[] = {
|
||||
/* Misc */
|
||||
NET("SUPPORTED"),
|
||||
/* Root Properties */
|
||||
NET("ACTIVE_WINDOW"),
|
||||
NET("CURRENT_DESKTOP"),
|
||||
/* Client Properties */
|
||||
NET("WM_NAME"),
|
||||
NET("WM_STRUT_PARTIAL"),
|
||||
NET("WM_DESKTOP"),
|
||||
NET("FRAME_EXTENTS"),
|
||||
/* States */
|
||||
NET("WM_STATE"),
|
||||
STATE("DEMANDS_ATTENTION"),
|
||||
STATE("FULLSCREEN"),
|
||||
STATE("SHADED"),
|
||||
/* Window Types */
|
||||
NET("WM_WINDOW_TYPE"),
|
||||
TYPE("DIALOG"),
|
||||
TYPE("DOCK"),
|
||||
TYPE("NORMAL"),
|
||||
TYPE("SPLASH"),
|
||||
/* Actions */
|
||||
NET("WM_ALLOWED_ACTIONS"),
|
||||
ACTION("FULLSCREEN"),
|
||||
/* Desktops */
|
||||
NET("DESKTOP_NAMES"),
|
||||
NET("NUMBER_OF_DESKTOPS"),
|
||||
/* Client List */
|
||||
NET("CLIENT_LIST"),
|
||||
NET("CLIENT_LIST_STACKING"),
|
||||
};
|
||||
changeprop_long(&scr.root, Net("SUPPORTED"), "ATOM", supported, nelem(supported));
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_updateclientlist(void) {
|
||||
Client *c;
|
||||
long *list;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
for(c=client; c; c=c->next)
|
||||
i++;
|
||||
list = emalloc(i * sizeof *list);
|
||||
for(c=client, i=0; c; c=c->next)
|
||||
list[i++] = c->w.w;
|
||||
changeprop_long(&scr.root, Net("CLIENT_LIST"), "WINDOW", list, i);
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_updatestacking(void) {
|
||||
Vector_long vec;
|
||||
Frame *f;
|
||||
Area *a;
|
||||
View *v;
|
||||
|
||||
vector_linit(&vec);
|
||||
|
||||
for(v=view; v; v=v->next)
|
||||
for(f=v->area->stack; f; f=f->snext)
|
||||
if(f->client->sel == f)
|
||||
vector_lpush(&vec, f->client->w.w);
|
||||
for(v=view; v; v=v->next)
|
||||
for(a=v->area->next; a; a=a->next)
|
||||
for(f=a->frame; f; f=f->anext)
|
||||
if(f->client->sel == f)
|
||||
vector_lpush(&vec, f->client->w.w);
|
||||
|
||||
changeprop_long(&scr.root, Net("CLIENT_LIST_STACKING"), "WINDOW", vec.ary, vec.n);
|
||||
vector_lfree(&vec);
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_initclient(Client *c) {
|
||||
long allowed[] = {
|
||||
ACTION("FULLSCREEN"),
|
||||
};
|
||||
|
||||
changeprop_long(&c->w, Net("WM_ALLOWED_ACTIONS"), "ATOM",
|
||||
allowed, nelem(allowed));
|
||||
ewmh_getwintype(c);
|
||||
ewmh_updateclientlist();
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_destroyclient(Client *c) {
|
||||
ewmh_updateclientlist();
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_prop(Client *c, Atom a) {
|
||||
if(a == NET("WM_WINDOW_TYPE"))
|
||||
ewmh_getwintype(c);
|
||||
else
|
||||
if(a == NET("WM_STRUT_PARTIAL"))
|
||||
ewmh_getstrut(c);
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_getwintype(Client *c) {
|
||||
struct {
|
||||
char* name;
|
||||
long mask;
|
||||
Atom atom;
|
||||
} static pairs[] = {
|
||||
{Type("DESKTOP"), TypeDesktop},
|
||||
{Type("DOCK"), TypeDock},
|
||||
{Type("TOOLBAR"), TypeToolbar},
|
||||
{Type("MENU"), TypeMenu},
|
||||
{Type("UTILITY"), TypeUtility},
|
||||
{Type("SPLASH"), TypeSplash},
|
||||
{Type("DIALOG"), TypeDialog},
|
||||
{Type("NORMAL"), TypeNormal},
|
||||
{0, }
|
||||
}, *pair;
|
||||
Atom actual, atom;
|
||||
long *types;
|
||||
long mask;
|
||||
ulong n;
|
||||
int i;
|
||||
|
||||
if(!pairs[0].atom)
|
||||
for(pair=pairs; pair->name; pair++)
|
||||
pair->atom = xatom(pair->name);
|
||||
|
||||
n = getproperty(&c->w, Net("WM_WINDOW_TYPE"), "ATOM", &actual,
|
||||
0L, (void*)&types, nelem(types));
|
||||
|
||||
Dprint(DEwmh, "ewmh_getwintype(%C) actual = %A; n = %d\n", c, actual, n);
|
||||
if(actual != xatom("ATOM"))
|
||||
return;
|
||||
|
||||
mask = 0;
|
||||
for(i=0; i < n; i++) {
|
||||
atom = types[i];
|
||||
Dprint(DEwmh, "\ttypes[%d] = \"%A\"\n", i, types[i], types[i]);
|
||||
for(pair=pairs; pair->name; pair++)
|
||||
if(pair->atom == atom) {
|
||||
mask |= pair->mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
c->w.ewmh.type = mask;
|
||||
if(mask & TypeDock) {
|
||||
c->borderless = 1;
|
||||
c->titleless = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_getstrut(Client *c) {
|
||||
enum {
|
||||
Left, Right, Top, Bottom,
|
||||
LeftMin, LeftMax,
|
||||
RithtMin, RightMax,
|
||||
TopMin, TopMax,
|
||||
BottomMin, BottomMax
|
||||
};
|
||||
Atom actual;
|
||||
long strut[12];
|
||||
ulong n;
|
||||
|
||||
n = getproperty(&c->w, Net("WM_STRUT_PARTIAL"), "CARDINAL", &actual,
|
||||
0L, (void*)&strut, nelem(strut));
|
||||
if(n != nelem(strut))
|
||||
return;
|
||||
if(actual != xatom("ATOM"))
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
ewmh_clientmessage(XClientMessageEvent *e) {
|
||||
Client *c;
|
||||
View *v;
|
||||
long *l;
|
||||
int msg, action, i;
|
||||
|
||||
l = e->data.l;
|
||||
msg = e->message_type;
|
||||
Dprint(DEwmh, "ClientMessage: %A\n", msg);
|
||||
|
||||
if(msg == NET("WM_STATE")) {
|
||||
enum {
|
||||
StateUnset,
|
||||
StateSet,
|
||||
StateToggle,
|
||||
};
|
||||
if(e->format != 32)
|
||||
return -1;
|
||||
c = win2client(e->window);
|
||||
if(c == nil)
|
||||
return 0;
|
||||
switch(l[0]) {
|
||||
case StateUnset: action = Off; break;
|
||||
case StateSet: action = On; break;
|
||||
case StateToggle: action = Toggle; break;
|
||||
default:
|
||||
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, false);
|
||||
}
|
||||
return 1;
|
||||
}else
|
||||
if(msg == NET("ACTIVE_WINDOW")) {
|
||||
if(e->format != 32)
|
||||
return -1;
|
||||
if(l[0] != 2)
|
||||
return 1;
|
||||
c == win2client(e->window);
|
||||
if(c == nil)
|
||||
return 1;
|
||||
focus(c, true);
|
||||
return 1;
|
||||
}else
|
||||
if(msg == NET("CURRENT_DESKTOP")) {
|
||||
print("\t%ld\n", l[0]);
|
||||
if(e->format != 32)
|
||||
return -1;
|
||||
print("\t%ld\n", l[0]);
|
||||
for(v=view, i=l[0]; v; v=v->next, i--)
|
||||
if(i == 0)
|
||||
break;
|
||||
print("\t%d\n", i);
|
||||
if(i == 0)
|
||||
view_select(v->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_framesize(Client *c) {
|
||||
Rectangle r;
|
||||
Frame *f;
|
||||
|
||||
f = c->sel;
|
||||
r.min.x = f->crect.min.x;
|
||||
r.min.y = f->crect.min.y;
|
||||
r.max.x = f->r.max.x - f->crect.max.x;
|
||||
r.max.y = f->r.max.y - f->crect.max.y;
|
||||
|
||||
long extents[] = {
|
||||
r.min.x, r.max.x,
|
||||
r.min.y, r.max.y,
|
||||
};
|
||||
changeprop_long(&c->w, Net("FRAME_EXTENTS"), "CARDINAL",
|
||||
extents, nelem(extents));
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_updatestate(Client *c) {
|
||||
long state[16];
|
||||
Frame *f;
|
||||
int i;
|
||||
|
||||
f = c->sel;
|
||||
if(f->view != screen->sel)
|
||||
return;
|
||||
|
||||
i = 0;
|
||||
if(f->collapsed)
|
||||
state[i++] = STATE("SHADED");
|
||||
if(c->fullscreen)
|
||||
state[i++] = STATE("FULLSCREEN");
|
||||
if(c->urgent)
|
||||
state[i++] = STATE("DEMANDS_ATTENTION");
|
||||
|
||||
assert(i < nelem(state)); /* Can't happen. */
|
||||
if(i > 0)
|
||||
changeprop_long(&c->w, Net("WM_STATE"), "ATOM", state, i);
|
||||
else
|
||||
delproperty(&c->w, Net("WM_STATE"));
|
||||
}
|
||||
|
||||
/* Views */
|
||||
void
|
||||
ewmh_updateviews(void) {
|
||||
View *v;
|
||||
char **tags;
|
||||
long i;
|
||||
|
||||
if(starting)
|
||||
return;
|
||||
|
||||
for(v=view, i=0; v; v=v->next)
|
||||
i++;
|
||||
tags = emalloc((i + 1) * sizeof *tags);
|
||||
for(v=view, i=0; v; v=v->next)
|
||||
tags[i++] = v->name;
|
||||
tags[i] = nil;
|
||||
changeprop_textlist(&scr.root, Net("DESKTOP_NAMES"), "UTF8_STRING", tags);
|
||||
changeprop_long(&scr.root, Net("NUMBER_OF_DESKTOPS"), "CARDINAL", &i, 1);
|
||||
ewmh_updateview();
|
||||
ewmh_updateclients();
|
||||
}
|
||||
|
||||
static int
|
||||
viewidx(View *v) {
|
||||
View *vp;
|
||||
int i;
|
||||
|
||||
for(vp=view, i=0; vp; vp=vp->next, i++)
|
||||
if(vp == v)
|
||||
break;
|
||||
assert(vp);
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_updateview(void) {
|
||||
long i;
|
||||
|
||||
if(starting)
|
||||
return;
|
||||
|
||||
i = viewidx(screen->sel);
|
||||
changeprop_long(&scr.root, Net("CURRENT_DESKTOP"), "CARDINAL", &i, 1);
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_updateclient(Client *c) {
|
||||
long i;
|
||||
|
||||
i = -1;
|
||||
if(c->sel)
|
||||
i = viewidx(c->sel->view);
|
||||
changeprop_long(&c->w, Net("WM_DESKTOP"), "CARDINAL", &i, 1);
|
||||
}
|
||||
|
||||
void
|
||||
ewmh_updateclients(void) {
|
||||
Client *c;
|
||||
|
||||
if(starting)
|
||||
return;
|
||||
|
||||
for(c=client; c; c=c->next)
|
||||
ewmh_updateclient(c);
|
||||
}
|
||||
|
393
cmd/wmii/fns.h
393
cmd/wmii/fns.h
|
@ -3,244 +3,225 @@
|
|||
*/
|
||||
|
||||
#ifdef VARARGCK
|
||||
# pragma varargck argpos write_event 1
|
||||
# pragma varargck argpos event 1
|
||||
#
|
||||
# pragma varargck type "C" Client*
|
||||
# pragma varargck type "W" Window*
|
||||
# pragma varargck type "P" Point
|
||||
# pragma varargck type "R" Rectangle
|
||||
# pragma varargck type "r" void
|
||||
#endif
|
||||
|
||||
/* XXX: These don't belong here. */
|
||||
|
||||
typedef struct Vector_long Vector_long;
|
||||
struct Vector_long {
|
||||
long* ary;
|
||||
long n;
|
||||
long size;
|
||||
};
|
||||
|
||||
static void
|
||||
vector_linit(Vector_long *v) {
|
||||
memset(v, 0, sizeof *v);
|
||||
}
|
||||
|
||||
static void
|
||||
vector_lfree(Vector_long *v) {
|
||||
free(v->ary);
|
||||
memset(v, 0, sizeof *v);
|
||||
}
|
||||
|
||||
static void
|
||||
vector_lpush(Vector_long *v, long val) {
|
||||
if(v->n == v->size) {
|
||||
if(v->size == 0)
|
||||
v->size = 2;
|
||||
v->size <<= 2;
|
||||
v->ary = erealloc(v->ary, v->size * sizeof *v->ary);
|
||||
}
|
||||
v->ary[v->n++] = val;
|
||||
}
|
||||
|
||||
static inline void
|
||||
__grr__(void) {
|
||||
vector_linit(nil);
|
||||
vector_lfree(nil);
|
||||
vector_lpush(nil, 0);
|
||||
}
|
||||
|
||||
/* area.c */
|
||||
char *area_name(Area *a);
|
||||
uint area_idx(Area *a);
|
||||
Area *create_area(View*, Area *pos, uint w);
|
||||
void destroy_area(Area*);
|
||||
Area *area_of_id(View*, ushort id);
|
||||
void focus_area(Area*);
|
||||
void send_to_area(Area*, Frame*);
|
||||
void attach_to_area(Area*, Frame*);
|
||||
void detach_from_area(Frame*);
|
||||
Client *area_selclient(Area*);
|
||||
void area_attach(Area*, Frame*);
|
||||
Area* area_create(View*, Area *pos, uint w);
|
||||
void area_destroy(Area*);
|
||||
void area_detach(Frame*);
|
||||
void area_focus(Area*);
|
||||
uint area_idx(Area*);
|
||||
void area_moveto(Area*, Frame*);
|
||||
char* area_name(Area*);
|
||||
Client* area_selclient(Area*);
|
||||
|
||||
/* bar.c */
|
||||
void initbar(WMScreen *s);
|
||||
Bar *create_bar(Bar **b_link, char *name);
|
||||
void destroy_bar(Bar **b_link, Bar*);
|
||||
void draw_bar(WMScreen *s);
|
||||
void resize_bar(WMScreen *s);
|
||||
Bar *bar_of_name(Bar *b_link, const char *name);
|
||||
Bar* bar_create(Bar**, const char*);
|
||||
void bar_destroy(Bar**, Bar*);
|
||||
void bar_draw(WMScreen*);
|
||||
Bar* bar_find(Bar*, const char*);
|
||||
void bar_init(WMScreen*);
|
||||
void bar_resize(WMScreen*);
|
||||
|
||||
/* client.c */
|
||||
Client *create_client(XWindow, XWindowAttributes*);
|
||||
void destroy_client(Client*);
|
||||
void configure_client(Client*);
|
||||
void update_class(Client *c);
|
||||
void prop_client(Client *c, Atom);
|
||||
void kill_client(Client*);
|
||||
void gravitate_client(Client*, Bool invert);
|
||||
void map_client(Client*);
|
||||
void unmap_client(Client*, int state);
|
||||
int map_frame(Client*);
|
||||
int unmap_frame(Client*);
|
||||
Rectangle gravclient(Client*, Rectangle);
|
||||
void fullscreen(Client*, Bool);
|
||||
void set_urgent(Client *, Bool urgent, Bool write);
|
||||
void set_cursor(Client*, Cursor);
|
||||
void focus_frame(Frame*, Bool restack);
|
||||
void reparent_client(Client*, Window*, Point);
|
||||
void manage_client(Client*);
|
||||
void focus(Client*, Bool restack);
|
||||
void focus_client(Client*);
|
||||
void resize_client(Client*, Rectangle*);
|
||||
void apply_sizehints(Client*, Rectangle*, Bool floating, Bool frame, Align sticky);
|
||||
void move_client(Client*, char *arg);
|
||||
void size_client(Client*, char *arg);
|
||||
Client *selclient(void);
|
||||
Client *win2client(XWindow);
|
||||
int Cfmt(Fmt *f);
|
||||
char *clientname(Client*);
|
||||
void apply_rules(Client*);
|
||||
void apply_tags(Client*, const char*);
|
||||
int Cfmt(Fmt *f);
|
||||
void apply_rules(Client*);
|
||||
void apply_tags(Client*, const char*);
|
||||
void client_configure(Client*);
|
||||
Client* client_create(XWindow, XWindowAttributes*);
|
||||
void client_destroy(Client*);
|
||||
void client_focus(Client*);
|
||||
void client_kill(Client*);
|
||||
void client_manage(Client*);
|
||||
void client_map(Client*);
|
||||
void client_prop(Client*, Atom);
|
||||
void client_reparent(Client*, Window*, Point);
|
||||
void client_resize(Client*, Rectangle);
|
||||
void client_setcursor(Client*, Cursor);
|
||||
void client_seturgent(Client*, int urgent, bool write);
|
||||
void client_unmap(Client*, int state);
|
||||
Frame* client_viewframe(Client *c, View *v);
|
||||
char* clientname(Client*);
|
||||
void focus(Client*, bool restack);
|
||||
void fullscreen(Client*, int);
|
||||
int map_frame(Client*);
|
||||
Client* selclient(void);
|
||||
int unmap_frame(Client*);
|
||||
void update_class(Client*);
|
||||
Client* win2client(XWindow);
|
||||
Rectangle client_grav(Client*, Rectangle);
|
||||
|
||||
/* column.c */
|
||||
void update_divs(void);
|
||||
void draw_div(Divide*);
|
||||
void setdiv(Divide*, int x);
|
||||
void arrange_column(Area*, Bool dirty);
|
||||
void resize_column(Area*, int w);
|
||||
void resize_colframe(Frame*, Rectangle*);
|
||||
int str2colmode(const char *str);
|
||||
char *colmode2str(int i);
|
||||
Area *new_column(View*, Area *pos, uint w);
|
||||
char* colmode2str(int);
|
||||
int str2colmode(const char*);
|
||||
void column_arrange(Area*, bool dirty);
|
||||
Area* column_new(View*, Area *, uint);
|
||||
void column_resize(Area*, int);
|
||||
void column_resizeframe(Frame*, Rectangle*);
|
||||
void div_draw(Divide*);
|
||||
void div_set(Divide*, int x);
|
||||
void div_update_all(void);
|
||||
|
||||
/* event.c */
|
||||
void dispatch_event(XEvent*);
|
||||
void check_x_event(IxpConn*);
|
||||
uint flushevents(long even_mask, Bool dispatch);
|
||||
void print_focus(Client *c, char *to);
|
||||
void check_x_event(IxpConn*);
|
||||
void dispatch_event(XEvent*);
|
||||
uint flushevents(long, bool dispatch);
|
||||
void print_focus(Client*, const char*);
|
||||
|
||||
/* ewmh.c */
|
||||
int ewmh_clientmessage(XClientMessageEvent*);
|
||||
void ewmh_destroyclient(Client*);
|
||||
void ewmh_framesize(Client*);
|
||||
void ewmh_getstrut(Client*);
|
||||
void ewmh_getwintype(Client*);
|
||||
void ewmh_init(void);
|
||||
void ewmh_initclient(Client*);
|
||||
void ewmh_prop(Client*, Atom);
|
||||
void ewmh_updateclient(Client*);
|
||||
void ewmh_updateclientlist(void);
|
||||
void ewmh_updateclients(void);
|
||||
void ewmh_updatestacking(void);
|
||||
void ewmh_updatestate(Client*);
|
||||
void ewmh_updateview(void);
|
||||
void ewmh_updateviews(void);
|
||||
|
||||
/* frame.c */
|
||||
uint frame_idx(Frame *f);
|
||||
Frame *create_frame(Client*, View*);
|
||||
void remove_frame(Frame*);
|
||||
void insert_frame(Frame *pos, Frame*);
|
||||
void resize_frame(Frame*, Rectangle);
|
||||
Bool frame_to_top(Frame *f);
|
||||
void set_frame_cursor(Frame*, Point);
|
||||
void swap_frames(Frame*, Frame*);
|
||||
int frame_delta_h(void);
|
||||
Rectangle frame_hints(Frame*, Rectangle, Align);
|
||||
Rectangle frame2client(Frame*, Rectangle);
|
||||
Rectangle client2frame(Frame*, Rectangle);
|
||||
int ingrabbox(Frame*, int x, int y);
|
||||
void draw_frame(Frame*);
|
||||
void draw_frames(void);
|
||||
void update_frame_widget_colors(Frame*);
|
||||
Frame* frame_create(Client*, View*);
|
||||
int frame_delta_h(void);
|
||||
void frame_draw(Frame*);
|
||||
void frame_draw_all(void);
|
||||
void frame_focus(Frame*);
|
||||
uint frame_idx(Frame*);
|
||||
void frame_insert(Frame *pos, Frame*);
|
||||
void frame_remove(Frame*);
|
||||
void frame_resize(Frame*, Rectangle);
|
||||
void frame_setcursor(Frame*, Point);
|
||||
void frame_swap(Frame*, Frame*);
|
||||
bool frame_to_top(Frame*);
|
||||
int ingrabbox_p(Frame*, int x, int y);
|
||||
void move_focus(Frame*, Frame*);
|
||||
Rectangle constrain(Rectangle);
|
||||
Rectangle frame_client2rect(Frame*, Rectangle);
|
||||
Rectangle frame_hints(Frame*, Rectangle, Align);
|
||||
Rectangle frame_rect2client(Frame*, Rectangle);
|
||||
|
||||
/* fs.c */
|
||||
void fs_attach(Ixp9Req*);
|
||||
void fs_clunk(Ixp9Req*);
|
||||
void fs_create(Ixp9Req*);
|
||||
void fs_flush(Ixp9Req*);
|
||||
void fs_freefid(Fid*);
|
||||
void fs_open(Ixp9Req*);
|
||||
void fs_read(Ixp9Req*);
|
||||
void fs_remove(Ixp9Req*);
|
||||
void fs_stat(Ixp9Req*);
|
||||
void fs_walk(Ixp9Req*);
|
||||
void fs_write(Ixp9Req*);
|
||||
void write_event(char*, ...);
|
||||
void fs_attach(Ixp9Req*);
|
||||
void fs_clunk(Ixp9Req*);
|
||||
void fs_create(Ixp9Req*);
|
||||
void fs_flush(Ixp9Req*);
|
||||
void fs_freefid(Fid*);
|
||||
void fs_open(Ixp9Req*);
|
||||
void fs_read(Ixp9Req*);
|
||||
void fs_remove(Ixp9Req*);
|
||||
void fs_stat(Ixp9Req*);
|
||||
void fs_walk(Ixp9Req*);
|
||||
void fs_write(Ixp9Req*);
|
||||
void event(const char*, ...);
|
||||
|
||||
/* geom.c */
|
||||
Bool ptinrect(Point, Rectangle);
|
||||
Align quadrant(Rectangle, Point);
|
||||
Cursor cursor_of_quad(Align);
|
||||
Align get_sticky(Rectangle src, Rectangle dst);
|
||||
Cursor quad_cursor(Align);
|
||||
Align get_sticky(Rectangle src, Rectangle dst);
|
||||
bool rect_haspoint_p(Point, Rectangle);
|
||||
Align quadrant(Rectangle, Point);
|
||||
|
||||
/* key.c */
|
||||
void kpress(XWindow, ulong mod, KeyCode);
|
||||
void update_keys(void);
|
||||
void init_lock_keys(void);
|
||||
ulong str2modmask(char*);
|
||||
void init_lock_keys(void);
|
||||
void kpress(XWindow, ulong mod, KeyCode);
|
||||
ulong str2modmask(const char*);
|
||||
void update_keys(void);
|
||||
|
||||
/* map.c */
|
||||
MapEnt* mapget(Map*, ulong, int create);
|
||||
MapEnt* hashget(Map*, char*, int create);
|
||||
void* maprm(Map*, ulong);
|
||||
void* hashrm(Map*, char*);
|
||||
MapEnt* hash_get(Map*, const char*, int create);
|
||||
void* hash_rm(Map*, const char*);
|
||||
MapEnt* map_get(Map*, ulong, int create);
|
||||
void* map_rm(Map*, ulong);
|
||||
|
||||
/* message.c */
|
||||
char *getword(IxpMsg*);
|
||||
int getulong(char*, ulong*);
|
||||
int getlong(char*, long*);
|
||||
Area *strarea(View*, char*);
|
||||
char *message_view(View*, IxpMsg*);
|
||||
char *parse_colors(IxpMsg*, CTuple*);
|
||||
char *message_root(void*, IxpMsg*);
|
||||
char *read_root_ctl(void);
|
||||
char *message_client(Client*, IxpMsg*);
|
||||
char *select_area(Area*, IxpMsg*);
|
||||
char *send_client(View*, IxpMsg*, Bool swap);
|
||||
int getlong(const char*, long*);
|
||||
int getulong(const char*, ulong*);
|
||||
char* message_client(Client*, IxpMsg*);
|
||||
char* message_root(void*, IxpMsg*);
|
||||
char* message_view(View*, IxpMsg*);
|
||||
char* msg_getword(IxpMsg*);
|
||||
char* msg_parsecolors(IxpMsg*, CTuple*);
|
||||
char* msg_selectarea(Area*, IxpMsg*);
|
||||
char* msg_sendclient(View*, IxpMsg*, bool swap);
|
||||
char* root_readctl(void);
|
||||
Area* strarea(View*, const char*);
|
||||
|
||||
/* mouse.c */
|
||||
void mouse_resizecol(Divide*);
|
||||
void do_mouse_resize(Client*, Bool opaque, Align);
|
||||
void grab_mouse(XWindow, ulong mod, ulong button);
|
||||
void ungrab_mouse(XWindow, ulong mod, uint button);
|
||||
Align snap_rect(Rectangle *rects, int num, Rectangle *current, Align *mask, int snapw);
|
||||
void grab_button(XWindow, uint button, ulong mod);
|
||||
void mouse_resize(Client*, bool opaque, Align);
|
||||
void mouse_resizecol(Divide*);
|
||||
void grab_button(XWindow, uint button, ulong mod);
|
||||
Align snap_rect(Rectangle *rects, int num, Rectangle *current, Align *mask, int snapw);
|
||||
|
||||
/* rule.c */
|
||||
void update_rules(Rule**, const char*);
|
||||
void trim(char *str, const char *chars);
|
||||
void trim(char *str, const char *chars);
|
||||
void update_rules(Rule**, const char*);
|
||||
|
||||
/* view.c */
|
||||
void arrange_view(View*);
|
||||
void scale_view(View*, int w);
|
||||
View *get_view(const char*);
|
||||
View *create_view(const char*);
|
||||
void focus_view(WMScreen*, View*);
|
||||
void update_client_views(Client*, char**);
|
||||
Rectangle *rects_of_view(View*, uint *num, Frame *ignore);
|
||||
View *view_of_id(ushort);
|
||||
Frame *view_clientframe(View *v, Client *c);
|
||||
void select_view(const char*);
|
||||
void attach_to_view(View*, Frame*);
|
||||
Client *view_selclient(View*);
|
||||
char *message_view(View *v, IxpMsg *m);
|
||||
void restack_view(View*);
|
||||
uchar *view_index(View*);
|
||||
uchar *view_ctl(View *v);
|
||||
void destroy_view(View*);
|
||||
void update_views(void);
|
||||
uint newcolw(View*, int i);
|
||||
void view_arrange(View*);
|
||||
void view_attach(View*, Frame*);
|
||||
View* view_create(const char*);
|
||||
char* view_ctl(View *v);
|
||||
void view_destroy(View*);
|
||||
void view_focus(WMScreen*, View*);
|
||||
bool view_fullscreen_p(View*);
|
||||
char* view_index(View*);
|
||||
uint view_newcolw(View*, int i);
|
||||
void view_restack(View*);
|
||||
void view_scale(View*, int w);
|
||||
Client* view_selclient(View*);
|
||||
void view_select(const char*);
|
||||
void view_setclient(Client*, char**);
|
||||
void view_update_all(void);
|
||||
Rectangle* view_rects(View*, uint *num, Frame *ignore);
|
||||
|
||||
/* wm.c */
|
||||
int win_proto(Window);
|
||||
/* utf.c */
|
||||
char* toutf8(const char*);
|
||||
char* toutf8n(const char*, size_t);
|
||||
|
||||
/* x11.c */
|
||||
XRectangle XRect(Rectangle);
|
||||
int eqrect(Rectangle, Rectangle);
|
||||
int eqpt(Point, Point);
|
||||
Point addpt(Point, Point);
|
||||
Point subpt(Point, Point);
|
||||
Point mulpt(Point p, Point q);
|
||||
Point divpt(Point, Point);
|
||||
Rectangle insetrect(Rectangle, int);
|
||||
Rectangle rectaddpt(Rectangle, Point);
|
||||
Rectangle rectsubpt(Rectangle, Point);
|
||||
void initdisplay(void);
|
||||
Image * allocimage(int w, int h, int depth);
|
||||
void freeimage(Image *);
|
||||
Window *createwindow(Window *parent, Rectangle, int depth, uint class, WinAttr*, int valuemask);
|
||||
void reparentwindow(Window*, Window*, Point);
|
||||
void destroywindow(Window*);
|
||||
void setwinattr(Window*, WinAttr*, int valmask);
|
||||
void reshapewin(Window*, Rectangle);
|
||||
void movewin(Window*, Point);
|
||||
int mapwin(Window*);
|
||||
int unmapwin(Window*);
|
||||
void lowerwin(Window*);
|
||||
void raisewin(Window*);
|
||||
Handlers* sethandler(Window*, Handlers*);
|
||||
Window* findwin(XWindow);
|
||||
uint winprotocols(Window*);
|
||||
void setshapemask(Window *dst, Image *src, Point);
|
||||
void border(Image *dst, Rectangle, int w, ulong col);
|
||||
void fill(Image *dst, Rectangle, ulong col);
|
||||
void drawpoly(Image *dst, Point *pt, int np, int cap, int w, ulong col);
|
||||
void fillpoly(Image *dst, Point *pt, int np, ulong col);
|
||||
void drawline(Image *dst, Point p1, Point p2, int cap, int w, ulong col);
|
||||
void drawstring(Image *dst, Font *font, Rectangle, Align align, char *text, ulong col);
|
||||
void copyimage(Image *dst, Rectangle, Image *src, Point p);
|
||||
Bool namedcolor(char *name, ulong*);
|
||||
Bool loadcolor(CTuple*, char*);
|
||||
Font * loadfont(char*);
|
||||
void freefont(Font*);
|
||||
uint textwidth_l(Font*, char*, uint len);
|
||||
uint textwidth(Font*, char*);
|
||||
uint labelh(Font*);
|
||||
Atom xatom(char*);
|
||||
void freestringlist(char**);
|
||||
ulong getproperty(Window *w, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length);
|
||||
char *gettextproperty(Window*, char*);
|
||||
int gettextlistproperty(Window *w, char *name, char **ret[]);
|
||||
void changeproperty(Window*, char *prop, char *type, int width, uchar *data, int n);
|
||||
void changeprop_char(Window *w, char *prop, char *type, char data[], int len);
|
||||
void changeprop_short(Window *w, char *prop, char *type, short data[], int len);
|
||||
void changeprop_long(Window *w, char *prop, char *type, long data[], int len);
|
||||
void setfocus(Window*, int mode);
|
||||
Point querypointer(Window*);
|
||||
void warppointer(Point);
|
||||
Point translate(Window*, Window*, Point);
|
||||
int grabpointer(Window*, Window *confine, Cursor, int mask);
|
||||
void ungrabpointer(void);
|
||||
Rectangle gravitate(Rectangle dst, Rectangle src, Point grav);
|
||||
Rectangle sizehint(WinHints*, Rectangle);
|
||||
void sethints(Window*);
|
||||
|
||||
char* toutf8n(char*, size_t);
|
||||
char* toutf8(char*);
|
||||
|
|
155
cmd/wmii/frame.c
155
cmd/wmii/frame.c
|
@ -3,7 +3,6 @@
|
|||
*/
|
||||
#include "dat.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "fns.h"
|
||||
|
||||
uint
|
||||
|
@ -17,8 +16,8 @@ frame_idx(Frame *f) {
|
|||
return i;
|
||||
}
|
||||
|
||||
Frame *
|
||||
create_frame(Client *c, View *v) {
|
||||
Frame*
|
||||
frame_create(Client *c, View *v) {
|
||||
static ushort id = 1;
|
||||
Frame *f;
|
||||
|
||||
|
@ -32,7 +31,7 @@ create_frame(Client *c, View *v) {
|
|||
f->r = c->sel->r;
|
||||
}
|
||||
else{
|
||||
f->r = client2frame(f, gravclient(c, ZR));
|
||||
f->r = frame_client2rect(f, client_grav(c, ZR));
|
||||
f->revert = f->r;
|
||||
c->sel = f;
|
||||
}
|
||||
|
@ -42,7 +41,7 @@ create_frame(Client *c, View *v) {
|
|||
}
|
||||
|
||||
void
|
||||
remove_frame(Frame *f) {
|
||||
frame_remove(Frame *f) {
|
||||
Area *a;
|
||||
|
||||
a = f->area;
|
||||
|
@ -65,7 +64,7 @@ remove_frame(Frame *f) {
|
|||
}
|
||||
|
||||
void
|
||||
insert_frame(Frame *pos, Frame *f) {
|
||||
frame_insert(Frame *pos, Frame *f) {
|
||||
Area *a;
|
||||
|
||||
a = f->area;
|
||||
|
@ -90,7 +89,7 @@ insert_frame(Frame *pos, Frame *f) {
|
|||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
bool
|
||||
frame_to_top(Frame *f) {
|
||||
Area *a;
|
||||
|
||||
|
@ -115,7 +114,7 @@ frame_to_top(Frame *f) {
|
|||
/* Handlers */
|
||||
static void
|
||||
bup_event(Window *w, XButtonEvent *e) {
|
||||
write_event("ClientClick %C %d\n", w->aux, e->button);
|
||||
event("ClientClick %C %d\n", w->aux, e->button);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -129,15 +128,15 @@ bdown_event(Window *w, XButtonEvent *e) {
|
|||
if((e->state & def.mod) == def.mod) {
|
||||
switch(e->button) {
|
||||
case Button1:
|
||||
do_mouse_resize(c, False, CENTER);
|
||||
focus(c, True);
|
||||
mouse_resize(c, False, CENTER);
|
||||
focus(c, false);
|
||||
frame_to_top(f);
|
||||
focus(c, True);
|
||||
focus(c, false); /* Blech */
|
||||
break;
|
||||
case Button3:
|
||||
do_mouse_resize(c, False, quadrant(f->r, Pt(e->x_root, e->y_root)));
|
||||
mouse_resize(c, False, quadrant(f->r, Pt(e->x_root, e->y_root)));
|
||||
frame_to_top(f);
|
||||
focus(c, True);
|
||||
focus(c, false);
|
||||
break;
|
||||
default:
|
||||
XAllowEvents(display, ReplayPointer, e->time);
|
||||
|
@ -148,24 +147,24 @@ bdown_event(Window *w, XButtonEvent *e) {
|
|||
}else{
|
||||
if(e->button == Button1) {
|
||||
if(frame_to_top(f))
|
||||
restack_view(f->view);
|
||||
else if(ptinrect(Pt(e->x, e->y), f->grabbox))
|
||||
do_mouse_resize(c, True, CENTER);
|
||||
view_restack(f->view);
|
||||
else if(rect_haspoint_p(Pt(e->x, e->y), f->grabbox))
|
||||
mouse_resize(c, True, CENTER);
|
||||
else if(f->area->floating)
|
||||
if(!e->subwindow && !ptinrect(Pt(e->x, e->y), f->titlebar))
|
||||
do_mouse_resize(c, False, quadrant(f->r, Pt(e->x_root, e->y_root)));
|
||||
if(!e->subwindow && !rect_haspoint_p(Pt(e->x, e->y), f->titlebar))
|
||||
mouse_resize(c, False, quadrant(f->r, Pt(e->x_root, e->y_root)));
|
||||
|
||||
if(f->client != selclient())
|
||||
focus(c, True);
|
||||
focus(c, false);
|
||||
}
|
||||
if(e->subwindow)
|
||||
XAllowEvents(display, ReplayPointer, e->time);
|
||||
else {
|
||||
/* Ungrab so a menu can receive events before the button is released */
|
||||
XUngrabPointer(display, e->time);
|
||||
XSync(display, False);
|
||||
sync();
|
||||
|
||||
write_event("ClientMouseDown %C %d\n", f->client, e->button);
|
||||
event("ClientMouseDown %C %d\n", f->client, e->button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,12 +176,12 @@ enter_event(Window *w, XCrossingEvent *e) {
|
|||
|
||||
c = w->aux;
|
||||
f = c->sel;
|
||||
if(screen->focus != c) {
|
||||
Dprint("enter_notify(f) => %s\n", f->client->name);
|
||||
if(screen->focus != c || selclient() != c) {
|
||||
Dprint(DGeneric, "enter_notify(f) => %s\n", f->client->name);
|
||||
if(f->area->floating || !f->collapsed)
|
||||
focus(f->client, False);
|
||||
focus(f->client, false);
|
||||
}
|
||||
set_frame_cursor(f, Pt(e->x, e->y));
|
||||
frame_setcursor(f, Pt(e->x, e->y));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -193,7 +192,7 @@ expose_event(Window *w, XExposeEvent *e) {
|
|||
|
||||
c = w->aux;
|
||||
if(c->sel)
|
||||
draw_frame(c->sel);
|
||||
frame_draw(c->sel);
|
||||
else
|
||||
fprint(2, "Badness: Expose event on a client frame which shouldn't be visible: %C\n",
|
||||
c);
|
||||
|
@ -204,7 +203,7 @@ motion_event(Window *w, XMotionEvent *e) {
|
|||
Client *c;
|
||||
|
||||
c = w->aux;
|
||||
set_frame_cursor(c->sel, Pt(e->x, e->y));
|
||||
frame_setcursor(c->sel, Pt(e->x, e->y));
|
||||
}
|
||||
|
||||
Handlers framehandler = {
|
||||
|
@ -216,7 +215,7 @@ Handlers framehandler = {
|
|||
};
|
||||
|
||||
Rectangle
|
||||
frame2client(Frame *f, Rectangle r) {
|
||||
frame_rect2client(Frame *f, Rectangle r) {
|
||||
if(f == nil || f->area == nil || f->area->floating) {
|
||||
r.max.x -= def.border * 2;
|
||||
r.max.y -= frame_delta_h();
|
||||
|
@ -238,7 +237,7 @@ frame2client(Frame *f, Rectangle r) {
|
|||
}
|
||||
|
||||
Rectangle
|
||||
client2frame(Frame *f, Rectangle r) {
|
||||
frame_client2rect(Frame *f, Rectangle r) {
|
||||
if(f == nil || f->area == nil || f->area->floating) {
|
||||
r.max.x += def.border * 2;
|
||||
r.max.y += frame_delta_h();
|
||||
|
@ -258,10 +257,11 @@ client2frame(Frame *f, Rectangle r) {
|
|||
}
|
||||
|
||||
void
|
||||
resize_frame(Frame *f, Rectangle r) {
|
||||
frame_resize(Frame *f, Rectangle r) {
|
||||
Align stickycorner;
|
||||
Point pt;
|
||||
Client *c;
|
||||
int collapsed;
|
||||
|
||||
c = f->client;
|
||||
stickycorner = get_sticky(f->r, r);
|
||||
|
@ -276,9 +276,11 @@ resize_frame(Frame *f, Rectangle r) {
|
|||
else
|
||||
f->r = r;
|
||||
|
||||
f->crect = frame2client(f, f->crect);
|
||||
f->crect = frame_rect2client(f, f->crect);
|
||||
f->crect = rectsubpt(f->crect, f->crect.min);
|
||||
|
||||
collapsed = f->collapsed;
|
||||
|
||||
if(!f->area->floating && f->area->mode == Coldefault) {
|
||||
if(Dy(f->r) < 2 * labelh(def.font))
|
||||
f->collapsed = True;
|
||||
|
@ -296,6 +298,9 @@ resize_frame(Frame *f, Rectangle r) {
|
|||
f->crect = f->r;
|
||||
}
|
||||
|
||||
if(collapsed != f->collapsed)
|
||||
ewmh_updatestate(c);
|
||||
|
||||
pt = ZP;
|
||||
if(!f->client->borderless || !f->area->floating)
|
||||
pt.y += 1;
|
||||
|
@ -305,7 +310,7 @@ resize_frame(Frame *f, Rectangle r) {
|
|||
if(f->area->floating) {
|
||||
if(c->fullscreen) {
|
||||
f->crect = screen->r;
|
||||
f->r = client2frame(f, f->crect);
|
||||
f->r = frame_client2rect(f, f->crect);
|
||||
pt.x = (Dx(f->r) - Dx(f->crect)) / 2;
|
||||
f->r = rectsubpt(f->r, pt);
|
||||
}else
|
||||
|
@ -316,34 +321,34 @@ resize_frame(Frame *f, Rectangle r) {
|
|||
}
|
||||
|
||||
void
|
||||
set_frame_cursor(Frame *f, Point pt) {
|
||||
frame_setcursor(Frame *f, Point pt) {
|
||||
Rectangle r;
|
||||
Cursor cur;
|
||||
|
||||
if(f->area->floating
|
||||
&& !ptinrect(pt, f->titlebar)
|
||||
&& !ptinrect(pt, f->crect)) {
|
||||
&& !rect_haspoint_p(pt, f->titlebar)
|
||||
&& !rect_haspoint_p(pt, f->crect)) {
|
||||
r = rectsubpt(f->r, f->r.min);
|
||||
cur = cursor_of_quad(quadrant(r, pt));
|
||||
set_cursor(f->client, cur);
|
||||
cur = quad_cursor(quadrant(r, pt));
|
||||
client_setcursor(f->client, cur);
|
||||
} else
|
||||
set_cursor(f->client, cursor[CurNormal]);
|
||||
client_setcursor(f->client, cursor[CurNormal]);
|
||||
}
|
||||
|
||||
void
|
||||
swap_frames(Frame *fa, Frame *fb) {
|
||||
frame_swap(Frame *fa, Frame *fb) {
|
||||
Frame **fp;
|
||||
Client *c;
|
||||
|
||||
if(fa == fb) return;
|
||||
|
||||
for(fp = &fa->client->frame; *fp; fp = &(*fp)->cnext)
|
||||
for(fp = &fa->client->frame; *fp; fp = &fp[0]->cnext)
|
||||
if(*fp == fa) break;
|
||||
*fp = (*fp)->cnext;
|
||||
fp[0] = fp[0]->cnext;
|
||||
|
||||
for(fp = &fb->client->frame; *fp; fp = &(*fp)->cnext)
|
||||
for(fp = &fb->client->frame; *fp; fp = &fp[0]->cnext)
|
||||
if(*fp == fb) break;
|
||||
*fp = (*fp)->cnext;
|
||||
fp[0] = fp[0]->cnext;
|
||||
|
||||
c = fa->client;
|
||||
fa->client = fb->client;
|
||||
|
@ -356,33 +361,49 @@ swap_frames(Frame *fa, Frame *fb) {
|
|||
c->frame = fa;
|
||||
|
||||
if(c->sel && c->sel->view == screen->sel)
|
||||
focus_view(screen, c->sel->view);
|
||||
view_focus(screen, c->sel->view);
|
||||
}
|
||||
|
||||
void
|
||||
focus_frame(Frame *f, Bool restack) {
|
||||
move_focus(Frame *old_f, Frame *f) {
|
||||
int noinput;
|
||||
|
||||
noinput = (old_f && old_f->client->noinput) ||
|
||||
(f && f->client->noinput) ||
|
||||
screen->hasgrab != &c_root;
|
||||
if(noinput) {
|
||||
if(old_f)
|
||||
frame_draw(old_f);
|
||||
if(f)
|
||||
frame_draw(f);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
frame_focus(Frame *f) {
|
||||
View *v;
|
||||
Area *a, *old_a;
|
||||
Frame *old_f;
|
||||
|
||||
a = f->area;
|
||||
v = f->view;
|
||||
old_a = v->sel;
|
||||
|
||||
old_f = old_a->sel;
|
||||
a->sel = f;
|
||||
|
||||
if(a != old_a)
|
||||
focus_area(f->area);
|
||||
area_focus(f->area);
|
||||
|
||||
if(v != screen->sel)
|
||||
if(v != screen->sel || a != v->sel)
|
||||
return;
|
||||
|
||||
focus_client(f->client);
|
||||
move_focus(old_f, f);
|
||||
|
||||
client_focus(f->client);
|
||||
|
||||
if(!a->floating && ((a->mode == Colstack) || (a->mode == Colmax)))
|
||||
arrange_column(a, False);
|
||||
|
||||
if(restack)
|
||||
restack_view(v);
|
||||
column_arrange(a, False);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -391,7 +412,7 @@ frame_delta_h(void) {
|
|||
}
|
||||
|
||||
void
|
||||
draw_frame(Frame *f) {
|
||||
frame_draw(Frame *f) {
|
||||
Rectangle r, fr;
|
||||
CTuple *col;
|
||||
Frame *tf;
|
||||
|
@ -399,7 +420,8 @@ draw_frame(Frame *f) {
|
|||
if(f->view != screen->sel)
|
||||
return;
|
||||
|
||||
if(f->client == screen->focus)
|
||||
if(f->client == screen->focus
|
||||
|| f->client == selclient())
|
||||
col = &def.focuscolor;
|
||||
else
|
||||
col = &def.normcolor;
|
||||
|
@ -423,6 +445,11 @@ draw_frame(Frame *f) {
|
|||
f->titlebar = insetrect(r, 3);
|
||||
f->titlebar.max.y += 3;
|
||||
|
||||
/* Odd state of focus. */
|
||||
if(f->client != selclient() && col == &def.focuscolor)
|
||||
border(screen->ibuf, insetrect(r, 1),
|
||||
1, def.normcolor.bg);
|
||||
|
||||
/* grabbox */
|
||||
r.min = Pt(2, 2);
|
||||
r.max.x = r.min.x + def.font->height - 3;
|
||||
|
@ -433,6 +460,12 @@ draw_frame(Frame *f) {
|
|||
fill(screen->ibuf, r, col->fg);
|
||||
border(screen->ibuf, r, 1, col->border);
|
||||
|
||||
/* Odd state of focus. */
|
||||
if(f->client != screen->focus && col == &def.focuscolor)
|
||||
border(screen->ibuf, insetrect(r, -1),
|
||||
1, def.normcolor.bg);
|
||||
|
||||
/* Label */
|
||||
r.min.x = r.max.x;
|
||||
r.max.x = fr.max.x;
|
||||
r.min.y = 0;
|
||||
|
@ -440,18 +473,26 @@ draw_frame(Frame *f) {
|
|||
drawstring(screen->ibuf, def.font, r, WEST,
|
||||
f->client->name, col->fg);
|
||||
|
||||
/* Why? Because some non-ICCCM-compliant apps feel the need to
|
||||
* change the background properties of all of their ancestor windows
|
||||
* in order to implement pseudo-transparency. Lovely, no?
|
||||
* What's more, the designers of X11 felt that it would be unfair to
|
||||
* implementers to make it possible to detect, or forbid, such changes.
|
||||
* This is why we love X11 so.
|
||||
*/
|
||||
XSetWindowBackgroundPixmap(display, f->client->framewin->w, None);
|
||||
|
||||
copyimage(f->client->framewin, fr, screen->ibuf, ZP);
|
||||
XSync(display, False);
|
||||
sync();
|
||||
}
|
||||
|
||||
void
|
||||
draw_frames(void) {
|
||||
frame_draw_all(void) {
|
||||
Client *c;
|
||||
|
||||
for(c=client; c; c=c->next)
|
||||
if(c->sel && c->sel->view == screen->sel)
|
||||
draw_frame(c->sel);
|
||||
frame_draw(c->sel);
|
||||
}
|
||||
|
||||
Rectangle
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "fns.h"
|
||||
|
||||
|
@ -110,7 +107,7 @@ dirtab_clients[]={{".", QTDIR, FsDClients, 0500|DMDIR },
|
|||
{nil}},
|
||||
dirtab_client[]= {{".", QTDIR, FsDClient, 0500|DMDIR },
|
||||
{"ctl", QTAPPEND, FsFCctl, 0600|DMAPPEND },
|
||||
{"label", QTFILE, FsFClabel, 0600 },
|
||||
{"label", QTFILE, FsFClabel, 0600 },
|
||||
{"tags", QTFILE, FsFCtags, 0600 },
|
||||
{"props", QTFILE, FsFprops, 0400 },
|
||||
{nil}},
|
||||
|
@ -185,8 +182,9 @@ write_buf(Ixp9Req *r, char *buf, uint len) {
|
|||
|
||||
/* This should be moved to libixp */
|
||||
static void
|
||||
write_to_buf(Ixp9Req *r, void *buf, uint *len, uint max) {
|
||||
write_to_buf(Ixp9Req *r, char **buf, uint *len, uint max) {
|
||||
uint offset, count;
|
||||
char *p;
|
||||
|
||||
offset = (r->fid->omode&OAPPEND) ? *len : r->ifcall.offset;
|
||||
if(offset > *len || r->ifcall.count == 0) {
|
||||
|
@ -199,15 +197,14 @@ write_to_buf(Ixp9Req *r, void *buf, uint *len, uint max) {
|
|||
count = max - offset;
|
||||
|
||||
*len = offset + count;
|
||||
if(max == 0)
|
||||
*buf = erealloc((void*)*buf, *len + 1);
|
||||
|
||||
if(max == 0) {
|
||||
*(void **)buf = erealloc(*(void **)buf, *len + 1);
|
||||
buf = *(void **)buf;
|
||||
}
|
||||
p = *buf;
|
||||
|
||||
memcpy((uchar*)buf + offset, r->ifcall.data, count);
|
||||
memcpy(p+offset, r->ifcall.data, count);
|
||||
r->ofcall.count = count;
|
||||
((char *)buf)[offset+count] = '\0';
|
||||
p[offset+count] = '\0';
|
||||
}
|
||||
|
||||
/* This should be moved to libixp */
|
||||
|
@ -228,7 +225,7 @@ data_to_cstring(Ixp9Req *r) {
|
|||
|
||||
typedef char* (*MsgFunc)(void*, IxpMsg*);
|
||||
|
||||
static char *
|
||||
static char*
|
||||
message(Ixp9Req *r, MsgFunc fn) {
|
||||
char *err, *s, *p, c;
|
||||
FileId *f;
|
||||
|
@ -274,7 +271,7 @@ respond_event(Ixp9Req *r) {
|
|||
}
|
||||
|
||||
void
|
||||
write_event(char *format, ...) {
|
||||
event(const char *format, ...) {
|
||||
uint len, slen;
|
||||
va_list ap;
|
||||
FidLink *f;
|
||||
|
@ -458,7 +455,7 @@ LastItem:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static Bool
|
||||
static bool
|
||||
verify_file(FileId *f) {
|
||||
FileId *nf;
|
||||
int ret;
|
||||
|
@ -583,7 +580,7 @@ fs_stat(Ixp9Req *r) {
|
|||
m = ixp_message(buf, size, MsgPack);
|
||||
ixp_pstat(&m, &s);
|
||||
|
||||
r->ofcall.stat = m.data;
|
||||
r->ofcall.stat = (uchar*)m.data;
|
||||
respond(r, nil);
|
||||
}
|
||||
|
||||
|
@ -660,7 +657,7 @@ fs_read(Ixp9Req *r) {
|
|||
respond(r, nil);
|
||||
return;
|
||||
case FsFRctl:
|
||||
buf = read_root_ctl();
|
||||
buf = root_readctl();
|
||||
write_buf(r, buf, strlen(buf));
|
||||
respond(r, nil);
|
||||
return;
|
||||
|
@ -674,13 +671,13 @@ fs_read(Ixp9Req *r) {
|
|||
respond(r, nil);
|
||||
return;
|
||||
case FsFTindex:
|
||||
buf = (char*)view_index(f->p.view);
|
||||
buf = view_index(f->p.view);
|
||||
n = strlen(buf);
|
||||
write_buf(r, buf, n);
|
||||
respond(r, nil);
|
||||
return;
|
||||
case FsFTctl:
|
||||
buf = (char*)view_ctl(f->p.view);
|
||||
buf = view_ctl(f->p.view);
|
||||
n = strlen(buf);
|
||||
write_buf(r, buf, n);
|
||||
respond(r, nil);
|
||||
|
@ -694,13 +691,14 @@ fs_read(Ixp9Req *r) {
|
|||
* This is an assert because this should this should not be called if
|
||||
* the file is not open for reading.
|
||||
*/
|
||||
assert(!"Read called on an unreadable file");
|
||||
die("Read called on an unreadable file");
|
||||
}
|
||||
|
||||
void
|
||||
fs_write(Ixp9Req *r) {
|
||||
FileId *f;
|
||||
char *errstr;
|
||||
char *p;
|
||||
uint i;
|
||||
|
||||
if(r->ifcall.count == 0) {
|
||||
|
@ -727,7 +725,7 @@ fs_write(Ixp9Req *r) {
|
|||
case FsFClabel:
|
||||
data_to_cstring(r);
|
||||
utfecpy(f->p.client->name, f->p.client->name+sizeof(client->name), r->ifcall.data);
|
||||
draw_frame(f->p.client->sel);
|
||||
frame_draw(f->p.client->sel);
|
||||
update_class(f->p.client);
|
||||
r->ofcall.count = r->ifcall.count;
|
||||
respond(r, nil);
|
||||
|
@ -740,7 +738,9 @@ fs_write(Ixp9Req *r) {
|
|||
return;
|
||||
case FsFBar:
|
||||
i = strlen(f->p.bar->buf);
|
||||
write_to_buf(r, f->p.bar->buf, &i, 279);
|
||||
/* Why the explicit cast? Ask gcc. */
|
||||
p = f->p.bar->buf;
|
||||
write_to_buf(r, &p, &i, 279);
|
||||
r->ofcall.count = i - r->ifcall.offset;
|
||||
respond(r, nil);
|
||||
return;
|
||||
|
@ -761,9 +761,9 @@ fs_write(Ixp9Req *r) {
|
|||
return;
|
||||
case FsFEvent:
|
||||
if(r->ifcall.data[r->ifcall.count-1] == '\n')
|
||||
write_event("%.*s", r->ifcall.count, r->ifcall.data);
|
||||
event("%.*s", (int)r->ifcall.count, r->ifcall.data);
|
||||
else
|
||||
write_event("%.*s\n", r->ifcall.count, r->ifcall.data);
|
||||
event("%.*s\n", (int)r->ifcall.count, r->ifcall.data);
|
||||
r->ofcall.count = r->ifcall.count;
|
||||
respond(r, nil);
|
||||
return;
|
||||
|
@ -772,7 +772,7 @@ fs_write(Ixp9Req *r) {
|
|||
* This is an assert because this function should not be called if
|
||||
* the file is not open for writing.
|
||||
*/
|
||||
assert(!"Write called on an unwritable file");
|
||||
die("Write called on an unwritable file");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -825,7 +825,7 @@ fs_create(Ixp9Req *r) {
|
|||
respond(r, Ebadvalue);
|
||||
return;
|
||||
}
|
||||
create_bar(f->p.bar_p, r->ifcall.name);
|
||||
bar_create(f->p.bar_p, r->ifcall.name);
|
||||
f = lookup_file(f, r->ifcall.name);
|
||||
if(!f) {
|
||||
respond(r, Enofile);
|
||||
|
@ -855,8 +855,8 @@ fs_remove(Ixp9Req *r) {
|
|||
respond(r, Enoperm);
|
||||
return;
|
||||
case FsFBar:
|
||||
destroy_bar(f->next->p.bar_p, f->p.bar);
|
||||
draw_bar(screen);
|
||||
bar_destroy(f->next->p.bar_p, f->p.bar);
|
||||
bar_draw(screen);
|
||||
respond(r, nil);
|
||||
break;
|
||||
}
|
||||
|
@ -884,7 +884,7 @@ fs_clunk(Ixp9Req *r) {
|
|||
update_rules(&f->p.rule->rule, f->p.rule->string);
|
||||
for(c=client; c; c=c->next)
|
||||
apply_rules(c);
|
||||
update_views();
|
||||
view_update_all();
|
||||
break;
|
||||
case FsFKeys:
|
||||
update_keys();
|
||||
|
@ -893,7 +893,7 @@ fs_clunk(Ixp9Req *r) {
|
|||
p = toutf8(f->p.bar->buf);
|
||||
|
||||
m = ixp_message((uchar*)p, strlen(p), 0);
|
||||
parse_colors(&m, &f->p.bar->col);
|
||||
msg_parsecolors(&m, &f->p.bar->col);
|
||||
|
||||
q = (char*)m.end-1;
|
||||
while(q >= (char*)m.pos && *q == '\n')
|
||||
|
@ -904,13 +904,13 @@ fs_clunk(Ixp9Req *r) {
|
|||
|
||||
free(p);
|
||||
|
||||
draw_bar(screen);
|
||||
bar_draw(screen);
|
||||
break;
|
||||
case FsFEvent:
|
||||
for(fl=&peventfid; *fl; fl=&(*fl)->next)
|
||||
if((*fl)->fid == r->fid) {
|
||||
ft = *fl;
|
||||
*fl = (*fl)->next;
|
||||
for(fl=&peventfid; *fl; fl=&fl[0]->next)
|
||||
if(fl[0]->fid == r->fid) {
|
||||
ft = fl[0];
|
||||
fl[0] = fl[0]->next;
|
||||
f = ft->fid->aux;
|
||||
free(f->p.buf);
|
||||
free(ft);
|
||||
|
@ -926,9 +926,9 @@ fs_flush(Ixp9Req *r) {
|
|||
Ixp9Req **i, **j;
|
||||
|
||||
for(i=&peventread; i != &oeventread; i=&oeventread)
|
||||
for(j=i; *j; j=(Ixp9Req**)&(*j)->aux)
|
||||
for(j=i; *j; j=(Ixp9Req**)&j[0]->aux)
|
||||
if(*j == r->oldreq) {
|
||||
*j = (*j)->aux;
|
||||
j[0] = j[0]->aux;
|
||||
respond(r->oldreq, Einterrupted);
|
||||
goto done;
|
||||
}
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "dat.h"
|
||||
#include <stdio.h>
|
||||
#include "fns.h"
|
||||
|
||||
Bool
|
||||
ptinrect(Point pt, Rectangle r) {
|
||||
bool
|
||||
rect_haspoint_p(Point pt, Rectangle r) {
|
||||
return (pt.x >= r.min.x) && (pt.x < r.max.x)
|
||||
&& (pt.y >= r.min.y) && (pt.y < r.max.y);
|
||||
}
|
||||
|
@ -31,7 +30,7 @@ quadrant(Rectangle r, Point pt) {
|
|||
}
|
||||
|
||||
Cursor
|
||||
cursor_of_quad(Align align) {
|
||||
quad_cursor(Align align) {
|
||||
switch(align) {
|
||||
case NEAST:
|
||||
return cursor[CurNECorner];
|
||||
|
|
112
cmd/wmii/key.c
112
cmd/wmii/key.c
|
@ -2,36 +2,38 @@
|
|||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "dat.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/keysym.h>
|
||||
#include "fns.h"
|
||||
|
||||
void
|
||||
init_lock_keys(void) {
|
||||
XModifierKeymap *modmap;
|
||||
KeyCode num_lock;
|
||||
KeyCode numlock;
|
||||
static int masks[] = {
|
||||
ShiftMask, LockMask, ControlMask, Mod1Mask,
|
||||
Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
|
||||
ShiftMask, LockMask, ControlMask,
|
||||
Mod1Mask, Mod2Mask, Mod3Mask,
|
||||
Mod4Mask, Mod5Mask
|
||||
};
|
||||
int i;
|
||||
|
||||
num_lock_mask = 0;
|
||||
numlock_mask = 0;
|
||||
modmap = XGetModifierMapping(display);
|
||||
num_lock = XKeysymToKeycode(display, XStringToKeysym("Num_Lock"));
|
||||
numlock = keycode("Num_Lock");
|
||||
if(numlock)
|
||||
if(modmap && modmap->max_keypermod > 0) {
|
||||
int max = (sizeof(masks) / sizeof(int)) * modmap->max_keypermod;
|
||||
int max;
|
||||
|
||||
max = nelem(masks) * modmap->max_keypermod;
|
||||
for(i = 0; i < max; i++)
|
||||
if(num_lock && (modmap->modifiermap[i] == num_lock))
|
||||
num_lock_mask = masks[i / modmap->max_keypermod];
|
||||
if(modmap->modifiermap[i] == numlock)
|
||||
numlock_mask = masks[i / modmap->max_keypermod];
|
||||
}
|
||||
XFreeModifiermap(modmap);
|
||||
valid_mask = 255 & ~(num_lock_mask | LockMask);
|
||||
valid_mask = 255 & ~(numlock_mask | LockMask);
|
||||
}
|
||||
|
||||
ulong
|
||||
str2modmask(char *val) {
|
||||
str2modmask(const char *val) {
|
||||
ulong mod = 0;
|
||||
|
||||
if (strstr(val, "Shift"))
|
||||
|
@ -52,38 +54,40 @@ str2modmask(char *val) {
|
|||
}
|
||||
|
||||
static void
|
||||
grab_key(Key *k) {
|
||||
grabkey(Key *k) {
|
||||
XGrabKey(display, k->key, k->mod, scr.root.w,
|
||||
True, GrabModeAsync, GrabModeAsync);
|
||||
if(num_lock_mask) {
|
||||
XGrabKey(display, k->key, k->mod | num_lock_mask, scr.root.w,
|
||||
if(numlock_mask) {
|
||||
XGrabKey(display, k->key, k->mod | numlock_mask, scr.root.w,
|
||||
True, GrabModeAsync, GrabModeAsync);
|
||||
XGrabKey(display, k->key, k->mod | num_lock_mask | LockMask, scr.root.w,
|
||||
XGrabKey(display, k->key, k->mod | numlock_mask | LockMask, scr.root.w,
|
||||
True, GrabModeAsync, GrabModeAsync);
|
||||
}
|
||||
XSync(display, False);
|
||||
sync();
|
||||
}
|
||||
|
||||
static void
|
||||
ungrab_key(Key *k) {
|
||||
ungrabkey(Key *k) {
|
||||
XUngrabKey(display, k->key, k->mod, scr.root.w);
|
||||
if(num_lock_mask) {
|
||||
XUngrabKey(display, k->key, k->mod | num_lock_mask, scr.root.w);
|
||||
XUngrabKey(display, k->key, k->mod | num_lock_mask | LockMask, scr.root.w);
|
||||
if(numlock_mask) {
|
||||
XUngrabKey(display, k->key, k->mod | numlock_mask, scr.root.w);
|
||||
XUngrabKey(display, k->key, k->mod | numlock_mask | LockMask, scr.root.w);
|
||||
}
|
||||
XSync(display, False);
|
||||
sync();
|
||||
}
|
||||
|
||||
static Key *
|
||||
name2key(const char *name) {
|
||||
Key *k;
|
||||
|
||||
for(k=key; k; k=k->lnext)
|
||||
if(!strncmp(k->name, name, sizeof(k->name))) break;
|
||||
return k;
|
||||
if(!strncmp(k->name, name, sizeof(k->name)))
|
||||
return k;
|
||||
return nil;
|
||||
}
|
||||
|
||||
static Key *
|
||||
get_key(const char *name) {
|
||||
getkey(const char *name) {
|
||||
char buf[128];
|
||||
char *seq[8];
|
||||
char *kstr;
|
||||
|
@ -94,7 +98,7 @@ get_key(const char *name) {
|
|||
r = nil;
|
||||
|
||||
if((k = name2key(name))) {
|
||||
ungrab_key(k);
|
||||
ungrabkey(k);
|
||||
return k;
|
||||
}
|
||||
utflcpy(buf, name, sizeof(buf));
|
||||
|
@ -139,26 +143,30 @@ next_keystroke(ulong *mod, KeyCode *code) {
|
|||
}
|
||||
|
||||
static void
|
||||
emulate_key_press(ulong mod, KeyCode key) {
|
||||
XEvent e;
|
||||
XWindow client_win;
|
||||
int revert;
|
||||
fake_keypress(ulong mod, KeyCode key) {
|
||||
XKeyEvent e;
|
||||
Client *c;
|
||||
|
||||
XGetInputFocus(display, &client_win, &revert);
|
||||
e.xkey.type = KeyPress;
|
||||
e.xkey.time = CurrentTime;
|
||||
e.xkey.window = client_win;
|
||||
e.xkey.display = display;
|
||||
e.xkey.state = mod;
|
||||
e.xkey.keycode = key;
|
||||
XSendEvent(display, client_win, True, KeyPressMask, &e);
|
||||
e.xkey.type = KeyRelease;
|
||||
XSendEvent(display, client_win, True, KeyReleaseMask, &e);
|
||||
XSync(display, False);
|
||||
c = screen->focus;
|
||||
if(c == nil || c->w.w == 0)
|
||||
return;
|
||||
|
||||
e.time = CurrentTime;
|
||||
e.window = c->w.w;
|
||||
e.display = display;
|
||||
e.state = mod;
|
||||
e.keycode = key;
|
||||
|
||||
e.type = KeyPress;
|
||||
sendevent(&c->w, true, KeyPressMask, (XEvent*)&e);
|
||||
e.type = KeyRelease;
|
||||
sendevent(&c->w, true, KeyReleaseMask, (XEvent*)&e);
|
||||
|
||||
sync();
|
||||
}
|
||||
|
||||
static Key *
|
||||
match_keys(Key *k, ulong mod, KeyCode keycode, Bool seq) {
|
||||
match_keys(Key *k, ulong mod, KeyCode keycode, bool seq) {
|
||||
Key *ret = nil, *next;
|
||||
|
||||
for(next = k->tnext; k; (k=next) && (next=k->tnext)) {
|
||||
|
@ -181,12 +189,12 @@ kpress_seq(XWindow w, Key *done) {
|
|||
next_keystroke(&mod, &key);
|
||||
found = match_keys(done, mod, key, True);
|
||||
if((done->mod == mod) && (done->key == key))
|
||||
emulate_key_press(mod, key); /* double key */
|
||||
fake_keypress(mod, key); /* double key */
|
||||
else {
|
||||
if(!found)
|
||||
XBell(display, 0);
|
||||
else if(!found->tnext && !found->next)
|
||||
write_event("Key %s\n", found->name);
|
||||
event("Key %s\n", found->name);
|
||||
else
|
||||
kpress_seq(w, found);
|
||||
}
|
||||
|
@ -202,13 +210,13 @@ kpress(XWindow w, ulong mod, KeyCode keycode) {
|
|||
if(!found) /* grabbed but not found */
|
||||
XBell(display, 0);
|
||||
else if(!found->tnext && !found->next)
|
||||
write_event("Key %s\n", found->name);
|
||||
event("Key %s\n", found->name);
|
||||
else {
|
||||
XGrabKeyboard(display, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
flushevents(FocusChangeMask, True);
|
||||
kpress_seq(w, found);
|
||||
XUngrabKeyboard(display, CurrentTime);
|
||||
XSync(display, False);
|
||||
sync();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,7 +228,7 @@ update_keys(void) {
|
|||
init_lock_keys();
|
||||
while((k = key)) {
|
||||
key = key->lnext;
|
||||
ungrab_key(k);
|
||||
ungrabkey(k);
|
||||
while((n = k)) {
|
||||
k = k->next;
|
||||
free(n);
|
||||
|
@ -229,8 +237,8 @@ update_keys(void) {
|
|||
for(l = p = def.keys; p && *p;) {
|
||||
if(*p == '\n') {
|
||||
*p = 0;
|
||||
if((k = get_key(l)))
|
||||
grab_key(k);
|
||||
if((k = getkey(l)))
|
||||
grabkey(k);
|
||||
*p = '\n';
|
||||
l = ++p;
|
||||
}
|
||||
|
@ -238,8 +246,8 @@ update_keys(void) {
|
|||
p++;
|
||||
}
|
||||
if(l < p && strlen(l)) {
|
||||
if((k = get_key(l)))
|
||||
grab_key(k);
|
||||
if((k = getkey(l)))
|
||||
grabkey(k);
|
||||
}
|
||||
XSync(display, False);
|
||||
sync();
|
||||
}
|
||||
|
|
218
cmd/wmii/main.c
218
cmd/wmii/main.c
|
@ -2,16 +2,15 @@
|
|||
* Copyright ©2006-2007 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#define EXTERN
|
||||
#include "dat.h"
|
||||
#include <X11/Xproto.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
@ -22,7 +21,7 @@ static const char
|
|||
|
||||
static int (*xlib_errorhandler) (Display*, XErrorEvent*);
|
||||
static char *address, *ns_path;
|
||||
static Bool check_other_wm;
|
||||
static int check_other_wm;
|
||||
static struct sigaction sa;
|
||||
static struct passwd *passwd;
|
||||
static int sleeperfd, sock, exitsignal;
|
||||
|
@ -49,17 +48,19 @@ scan_wins(void) {
|
|||
for(i = 0; i < num; i++) {
|
||||
if(!XGetWindowAttributes(display, wins[i], &wa))
|
||||
continue;
|
||||
/* Skip transients. */
|
||||
if(wa.override_redirect || XGetTransientForHint(display, wins[i], &d1))
|
||||
continue;
|
||||
if(wa.map_state == IsViewable)
|
||||
create_client(wins[i], &wa);
|
||||
client_create(wins[i], &wa);
|
||||
}
|
||||
/* Manage transients. */
|
||||
for(i = 0; i < num; i++) {
|
||||
if(!XGetWindowAttributes(display, wins[i], &wa))
|
||||
continue;
|
||||
if((XGetTransientForHint(display, wins[i], &d1))
|
||||
&& (wa.map_state == IsViewable))
|
||||
create_client(wins[i], &wa);
|
||||
client_create(wins[i], &wa);
|
||||
}
|
||||
}
|
||||
if(wins)
|
||||
|
@ -88,20 +89,21 @@ ns_display(void) {
|
|||
|
||||
static void
|
||||
rmkdir(char *path, int mode) {
|
||||
char *p, *q;
|
||||
char *p;
|
||||
int ret;
|
||||
char c;
|
||||
|
||||
q = path + strlen(ns_path);
|
||||
for(p = &path[1]; p <= q; p++) {
|
||||
for(p = path+1; ; p++) {
|
||||
c = *p;
|
||||
if((c == '/') || (c == '\0')) {
|
||||
*p = '\0';
|
||||
ret = mkdir(path, mode);
|
||||
if((ret == -1) && (errno != EEXIST))
|
||||
fatal("Can't create ns_path '%s': %r", path);
|
||||
fatal("Can't create path '%s': %r", path);
|
||||
*p = c;
|
||||
}
|
||||
if(c == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,7 +123,7 @@ init_ns(void) {
|
|||
else
|
||||
ns_path = ns_display();
|
||||
|
||||
if((ns_path[0] != '/') || (strlen(ns_path) == 0))
|
||||
if(ns_path[0] != '/' || ns_path[0] == '\0')
|
||||
fatal("Bad ns_path");
|
||||
|
||||
rmkdir(ns_path, 0700);
|
||||
|
@ -138,22 +140,13 @@ static void
|
|||
init_environment(void) {
|
||||
init_ns();
|
||||
|
||||
if(address == nil) {
|
||||
address = emalloc(strlen(ns_path) + strlen("unix!/wmii") + 1);
|
||||
sprint(address, "unix!%s/wmii", ns_path);
|
||||
}
|
||||
if(address == nil)
|
||||
address = smprint("unix!%s/wmii", ns_path);
|
||||
|
||||
setenv("WMII_NS_DIR", ns_path, True);
|
||||
setenv("WMII_ADDRESS", address, True);
|
||||
}
|
||||
|
||||
static void
|
||||
init_atoms(void) {
|
||||
Atom net[] = { xatom("_NET_SUPPORTED"), xatom("_NET_WM_NAME") };
|
||||
|
||||
changeprop_long(&scr.root, "_NET_SUPPORTED", "ATOM", (long*)net, nelem(net));
|
||||
}
|
||||
|
||||
static void
|
||||
create_cursor(int ident, uint shape) {
|
||||
cursor[ident] = XCreateFontCursor(display, shape);
|
||||
|
@ -192,40 +185,17 @@ init_cursors(void) {
|
|||
|
||||
static void
|
||||
init_screen(WMScreen *screen) {
|
||||
XWindow w;
|
||||
int ret;
|
||||
unsigned mask;
|
||||
XGCValues gcv;
|
||||
|
||||
gcv.subwindow_mode = IncludeInferiors;
|
||||
gcv.function = GXxor;
|
||||
gcv.foreground = def.normcolor.bg;
|
||||
gcv.plane_mask = AllPlanes;
|
||||
gcv.graphics_exposures = False;
|
||||
|
||||
xor.type = WImage;
|
||||
xor.image = scr.root.w;
|
||||
xor.gc = XCreateGC(display, scr.root.w,
|
||||
GCForeground
|
||||
| GCGraphicsExposures
|
||||
| GCFunction
|
||||
| GCSubwindowMode
|
||||
| GCPlaneMask,
|
||||
&gcv);
|
||||
|
||||
screen->r = scr.rect;
|
||||
def.snap = Dy(scr.rect) / 63;
|
||||
|
||||
sel_screen = XQueryPointer(display, scr.root.w,
|
||||
&w, &w,
|
||||
&ret, &ret, &ret, &ret,
|
||||
&mask);
|
||||
sel_screen = pointerscreen();
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(void) {
|
||||
while(client)
|
||||
destroy_client(client);
|
||||
client_destroy(client);
|
||||
ixp_server_close(&srv);
|
||||
close(sleeperfd);
|
||||
}
|
||||
|
@ -240,6 +210,7 @@ struct {
|
|||
{ X_PolySegment, BadDrawable },
|
||||
{ X_ConfigureWindow, BadMatch },
|
||||
{ X_GrabKey, BadAccess },
|
||||
{ X_GetAtomName, BadAtom },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -250,9 +221,9 @@ struct {
|
|||
*/
|
||||
static int
|
||||
errorhandler(Display *dpy, XErrorEvent *error) {
|
||||
static Bool dead;
|
||||
static int dead;
|
||||
int i;
|
||||
|
||||
|
||||
USED(dpy);
|
||||
|
||||
if(check_other_wm)
|
||||
|
@ -266,7 +237,7 @@ errorhandler(Display *dpy, XErrorEvent *error) {
|
|||
fprint(2, "%s: fatal error: Xrequest code=%d, Xerror code=%d\n",
|
||||
argv0, error->request_code, error->error_code);
|
||||
|
||||
/* Try to cleanup, but only try once, in case we're called again */
|
||||
/* Try to cleanup, but only try once, in case we're called recursively. */
|
||||
if(!dead++)
|
||||
cleanup();
|
||||
return xlib_errorhandler(display, error); /* calls exit() */
|
||||
|
@ -288,47 +259,58 @@ cleanup_handler(int signal) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
closeexec(int fd) {
|
||||
fcntl(fd, F_SETFL, FD_CLOEXEC);
|
||||
}
|
||||
|
||||
static int
|
||||
doublefork(void) {
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
switch(pid=fork()) {
|
||||
case -1:
|
||||
fatal("Can't fork(): %r");
|
||||
case 0:
|
||||
switch(pid=fork()) {
|
||||
case -1:
|
||||
fatal("Can't fork(): %r");
|
||||
case 0:
|
||||
return 0;
|
||||
default:
|
||||
exit(0);
|
||||
}
|
||||
default:
|
||||
waitpid(pid, &status, 0);
|
||||
return pid;
|
||||
}
|
||||
return -1; /* not reached */
|
||||
}
|
||||
|
||||
static void
|
||||
init_traps(void) {
|
||||
char buf[1];
|
||||
pid_t pid;
|
||||
int fd[2], status;
|
||||
int fd[2];
|
||||
|
||||
if(pipe(fd) != 0)
|
||||
fatal("Can't pipe(): %r");
|
||||
|
||||
/* Double fork hack */
|
||||
switch(pid = fork()) {
|
||||
case -1:
|
||||
fatal("Can't fork(): %r");
|
||||
break; /* not reached */
|
||||
case 0:
|
||||
switch(fork()) {
|
||||
case -1:
|
||||
fatal("Can't fork(): %r");
|
||||
break; /* not reached */
|
||||
case 0:
|
||||
close(fd[1]);
|
||||
close(ConnectionNumber(display));
|
||||
setsid();
|
||||
if(doublefork() == 0) {
|
||||
close(fd[1]);
|
||||
close(ConnectionNumber(display));
|
||||
setsid();
|
||||
|
||||
display = XOpenDisplay(0);
|
||||
if(!display)
|
||||
fatal("Can't open display");
|
||||
display = XOpenDisplay(0);
|
||||
if(!display)
|
||||
fatal("Can't open display");
|
||||
|
||||
/* Wait for parent to exit */
|
||||
read(fd[0], buf, 1);
|
||||
/* Wait for parent to exit */
|
||||
read(fd[0], buf, 1);
|
||||
|
||||
XSetInputFocus(display, PointerRoot, RevertToPointerRoot, CurrentTime);
|
||||
XCloseDisplay(display);
|
||||
exit(0);
|
||||
default:
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
waitpid(pid, &status, 0);
|
||||
break;
|
||||
setfocus(pointerwin, RevertToPointerRoot);
|
||||
XCloseDisplay(display);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
close(fd[0]);
|
||||
|
@ -340,50 +322,28 @@ init_traps(void) {
|
|||
sigaction(SIGTERM, &sa, nil);
|
||||
sigaction(SIGQUIT, &sa, nil);
|
||||
sigaction(SIGHUP, &sa, nil);
|
||||
sigaction(SIGUSR1, &sa, nil);
|
||||
sigaction(SIGUSR2, &sa, nil);
|
||||
}
|
||||
|
||||
static void
|
||||
spawn_command(const char *cmd) {
|
||||
char *shell, *p;
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
/* Double fork hack */
|
||||
switch(pid = fork()) {
|
||||
case -1:
|
||||
fatal("Can't fork: %r");
|
||||
break; /* Not reached */
|
||||
case 0:
|
||||
switch(fork()) {
|
||||
case -1:
|
||||
fatal("Can't fork: %r");
|
||||
break; /* Not reached */
|
||||
case 0:
|
||||
if(setsid() == -1)
|
||||
fatal("Can't setsid: %r");
|
||||
close(sock);
|
||||
close(ConnectionNumber(display));
|
||||
if(doublefork() == 0) {
|
||||
if(setsid() == -1)
|
||||
fatal("Can't setsid: %r");
|
||||
|
||||
shell = passwd->pw_shell;
|
||||
if(shell[0] != '/')
|
||||
fatal("Shell is not an absolute path: %s", shell);
|
||||
shell = passwd->pw_shell;
|
||||
if(shell[0] != '/')
|
||||
fatal("Shell is not an absolute path: %s", shell);
|
||||
|
||||
/* Run through the user's shell as a login shell */
|
||||
p = malloc((strlen(shell) + 2));
|
||||
sprint(p, "-%s", strrchr(shell, '/') + 1);
|
||||
/* Run through the user's shell as a login shell */
|
||||
p = smprint("-%s", strrchr(shell, '/') + 1);
|
||||
|
||||
execl(shell, p, "-c", cmd, nil);
|
||||
fatal("Can't exec '%s': %r", cmd);
|
||||
break; /* Not reached */
|
||||
default:
|
||||
exit(0);
|
||||
break; /* Not reached */
|
||||
}
|
||||
default:
|
||||
waitpid(pid, &status, 0);
|
||||
/* if(status != 0)
|
||||
exit(1); */
|
||||
break;
|
||||
execl(shell, p, "-c", cmd, nil);
|
||||
fatal("Can't exec '%s': %r", cmd);
|
||||
/* Not reached */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,9 +377,6 @@ main(int argc, char *argv[]) {
|
|||
case 'v':
|
||||
print("%s", version);
|
||||
exit(0);
|
||||
case 'V':
|
||||
verbose = True;
|
||||
break;
|
||||
case 'a':
|
||||
address = EARGF(usage());
|
||||
break;
|
||||
|
@ -438,16 +395,17 @@ main(int argc, char *argv[]) {
|
|||
starting = True;
|
||||
|
||||
initdisplay();
|
||||
closeexec(ConnectionNumber(display));
|
||||
|
||||
xlib_errorhandler = XSetErrorHandler(errorhandler);
|
||||
|
||||
check_other_wm = True;
|
||||
check_other_wm = true;
|
||||
XSelectInput(display, scr.root.w,
|
||||
SubstructureRedirectMask
|
||||
| EnterWindowMask);
|
||||
XSync(display, False);
|
||||
sync();
|
||||
|
||||
check_other_wm = False;
|
||||
check_other_wm = false;
|
||||
|
||||
passwd = getpwuid(getuid());
|
||||
user = estrdup(passwd->pw_name);
|
||||
|
@ -457,14 +415,15 @@ main(int argc, char *argv[]) {
|
|||
sock = ixp_announce(address);
|
||||
if(sock < 0)
|
||||
fatal("Can't create socket '%s': %r", address);
|
||||
closeexec(sock);
|
||||
|
||||
if(wmiirc)
|
||||
spawn_command(wmiirc);
|
||||
|
||||
init_traps();
|
||||
init_atoms();
|
||||
init_cursors();
|
||||
init_lock_keys();
|
||||
ewmh_init();
|
||||
|
||||
srv.preselect = check_preselect;
|
||||
ixp_listen(&srv, sock, &p9srv, serve_9pcon, nil);
|
||||
|
@ -499,20 +458,21 @@ main(int argc, char *argv[]) {
|
|||
setwinattr(&scr.root, &wa,
|
||||
CWEventMask
|
||||
| CWCursor);
|
||||
initbar(s);
|
||||
bar_init(s);
|
||||
}
|
||||
|
||||
screen->focus = nil;
|
||||
setfocus(screen->barwin, RevertToParent);
|
||||
|
||||
scan_wins();
|
||||
starting = False;
|
||||
starting = false;
|
||||
|
||||
select_view("nil");
|
||||
update_views();
|
||||
write_event("FocusTag %s\n", screen->sel->name);
|
||||
view_select("nil");
|
||||
view_update_all();
|
||||
ewmh_updateviews();
|
||||
|
||||
event("FocusTag %s\n", screen->sel->name);
|
||||
|
||||
check_x_event(nil);
|
||||
i = ixp_serverloop(&srv);
|
||||
if(i)
|
||||
fprint(2, "%s: error: %r\n", argv0);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* Written by Kris Maglione */
|
||||
/* Public domain */
|
||||
#include "dat.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fns.h"
|
||||
|
||||
/* Edit s/^([a-zA-Z].*)\n([a-z].*) {/\1 \2;/g x/^([^a-zA-Z]|static|$)/-+d s/ (\*map|val|*str)//g */
|
||||
|
@ -23,7 +21,7 @@ hash(const char *str) {
|
|||
}
|
||||
|
||||
static void
|
||||
insert(MapEnt **e, ulong val, char *key) {
|
||||
insert(MapEnt **e, ulong val, const char *key) {
|
||||
MapEnt *te;
|
||||
|
||||
te = emallocz(sizeof *te);
|
||||
|
@ -34,7 +32,7 @@ insert(MapEnt **e, ulong val, char *key) {
|
|||
}
|
||||
|
||||
static MapEnt**
|
||||
mapgetp(Map *map, ulong val, int create) {
|
||||
map_getp(Map *map, ulong val, int create) {
|
||||
MapEnt **e;
|
||||
|
||||
e = &map->bucket[val%map->nhash];
|
||||
|
@ -50,13 +48,13 @@ mapgetp(Map *map, ulong val, int create) {
|
|||
}
|
||||
|
||||
static MapEnt**
|
||||
hashgetp(Map *map, char *str, int create) {
|
||||
hash_getp(Map *map, const char *str, int create) {
|
||||
MapEnt **e;
|
||||
ulong h;
|
||||
int cmp;
|
||||
|
||||
h = hash(str);
|
||||
e = mapgetp(map, h, create);
|
||||
e = map_getp(map, h, create);
|
||||
if(*e && (*e)->key == nil)
|
||||
(*e)->key = str;
|
||||
else {
|
||||
|
@ -72,28 +70,28 @@ hashgetp(Map *map, char *str, int create) {
|
|||
}
|
||||
|
||||
MapEnt*
|
||||
mapget(Map *map, ulong val, int create) {
|
||||
map_get(Map *map, ulong val, int create) {
|
||||
MapEnt **e;
|
||||
|
||||
e = mapgetp(map, val, create);
|
||||
e = map_getp(map, val, create);
|
||||
return *e;
|
||||
}
|
||||
|
||||
MapEnt*
|
||||
hashget(Map *map, char *str, int create) {
|
||||
hash_get(Map *map, const char *str, int create) {
|
||||
MapEnt **e;
|
||||
|
||||
e = hashgetp(map, str, create);
|
||||
e = hash_getp(map, str, create);
|
||||
return *e;
|
||||
}
|
||||
|
||||
void*
|
||||
maprm(Map *map, ulong val) {
|
||||
map_rm(Map *map, ulong val) {
|
||||
MapEnt **e, *te;
|
||||
void *ret;
|
||||
|
||||
ret = nil;
|
||||
e = mapgetp(map, val, 0);
|
||||
e = map_getp(map, val, 0);
|
||||
if(*e) {
|
||||
te = *e;
|
||||
ret = te->val;
|
||||
|
@ -104,12 +102,12 @@ maprm(Map *map, ulong val) {
|
|||
}
|
||||
|
||||
void*
|
||||
hashrm(Map *map, char *str) {
|
||||
hash_rm(Map *map, const char *str) {
|
||||
MapEnt **e, *te;
|
||||
void *ret;
|
||||
|
||||
ret = nil;
|
||||
e = hashgetp(map, str, 0);
|
||||
e = hash_getp(map, str, 0);
|
||||
if(*e) {
|
||||
te = *e;
|
||||
ret = te->val;
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fns.h"
|
||||
|
||||
static char* msg_debug(IxpMsg*);
|
||||
static char* msg_selectframe(Frame*, IxpMsg*, int);
|
||||
static char* msg_sendframe(Frame*, int, bool);
|
||||
|
||||
static char
|
||||
Ebadcmd[] = "bad command",
|
||||
Ebadvalue[] = "bad value",
|
||||
|
@ -21,6 +22,7 @@ enum {
|
|||
LBORDER,
|
||||
LCLIENT,
|
||||
LCOLMODE,
|
||||
LDEBUG,
|
||||
LDOWN,
|
||||
LEXEC,
|
||||
LFOCUSCOLORS,
|
||||
|
@ -48,6 +50,7 @@ char *symtab[] = {
|
|||
"border",
|
||||
"client",
|
||||
"colmode",
|
||||
"debug",
|
||||
"down",
|
||||
"exec",
|
||||
"focuscolors",
|
||||
|
@ -70,23 +73,30 @@ char *symtab[] = {
|
|||
"~",
|
||||
};
|
||||
|
||||
char *debugtab[] = {
|
||||
"event",
|
||||
"ewmh",
|
||||
"focus",
|
||||
"generic",
|
||||
};
|
||||
|
||||
/* Edit ,y/^[a-zA-Z].*\n.* {\n/d
|
||||
* Edit s/^([a-zA-Z].*)\n(.*) {\n/\1 \2;\n/
|
||||
* Edit ,x/^static.*\n/d
|
||||
*/
|
||||
|
||||
static int
|
||||
getsym(char *s) {
|
||||
_bsearch(char *s, char **tab, int ntab) {
|
||||
int i, n, m, cmp;
|
||||
|
||||
if(s == nil)
|
||||
return -1;
|
||||
|
||||
n = nelem(symtab);
|
||||
n = ntab;
|
||||
i = 0;
|
||||
while(n) {
|
||||
m = n/2;
|
||||
cmp = strcmp(s, symtab[i+m]);
|
||||
cmp = strcmp(s, tab[i+m]);
|
||||
if(cmp == 0)
|
||||
return i+m;
|
||||
if(cmp < 0 || m == 0)
|
||||
|
@ -99,9 +109,19 @@ getsym(char *s) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
getsym(char *s) {
|
||||
return _bsearch(s, symtab, nelem(symtab));
|
||||
}
|
||||
|
||||
static int
|
||||
getdebug(char *s) {
|
||||
return _bsearch(s, debugtab, nelem(debugtab));
|
||||
}
|
||||
|
||||
static int
|
||||
gettoggle(IxpMsg *m) {
|
||||
switch(getsym(getword(m))) {
|
||||
switch(getsym(msg_getword(m))) {
|
||||
case LON:
|
||||
return On;
|
||||
case LOFF:
|
||||
|
@ -119,7 +139,7 @@ eatrunes(IxpMsg *m, int (*p)(Rune), int val) {
|
|||
int n;
|
||||
|
||||
while(m->pos < m->end) {
|
||||
n = chartorune(&r, (char*)m->pos);
|
||||
n = chartorune(&r, m->pos);
|
||||
if(p(r) != val)
|
||||
break;
|
||||
m->pos += n;
|
||||
|
@ -128,44 +148,46 @@ eatrunes(IxpMsg *m, int (*p)(Rune), int val) {
|
|||
m->pos = m->end;
|
||||
}
|
||||
|
||||
char *
|
||||
getword(IxpMsg *m) {
|
||||
char*
|
||||
msg_getword(IxpMsg *m) {
|
||||
char *ret;
|
||||
Rune r;
|
||||
int n;
|
||||
|
||||
eatrunes(m, isspacerune, 1);
|
||||
ret = (char*)m->pos;
|
||||
ret = m->pos;
|
||||
eatrunes(m, isspacerune, 0);
|
||||
n = chartorune(&r, (char*)m->pos);
|
||||
n = chartorune(&r, m->pos);
|
||||
*m->pos = '\0';
|
||||
m->pos += n;
|
||||
eatrunes(m, isspacerune, 1);
|
||||
|
||||
if(ret == (char*)m->end)
|
||||
if(ret == m->end)
|
||||
return nil;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define strbcmp(str, const) (strncmp((str), (const), sizeof(const)-1))
|
||||
static int
|
||||
getbase(char **s) {
|
||||
char *p;
|
||||
getbase(const char **s) {
|
||||
const char *p;
|
||||
|
||||
p = *s;
|
||||
if(!strbcmp(p, "0x")) {
|
||||
*s += 2;
|
||||
return 16;
|
||||
}
|
||||
if(isdigit(p[0]) && p[1] == 'r') {
|
||||
*s += 2;
|
||||
return p[0] - '0';
|
||||
if(isdigit(p[0])) {
|
||||
if(p[1] == 'r') {
|
||||
*s += 2;
|
||||
return p[0] - '0';
|
||||
}
|
||||
if(isdigit(p[1]) && p[2] == 'r') {
|
||||
*s += 3;
|
||||
return 10*(p[0]-'0') + (p[1]-'0');
|
||||
}
|
||||
}
|
||||
if(isdigit(p[0]) && isdigit(p[1]) && p[2] == 'r') {
|
||||
*s += 3;
|
||||
return 10*(p[0]-'0') + (p[1]-'0');
|
||||
}
|
||||
if(!strbcmp(p, "0")) {
|
||||
if(p[0] == '0') {
|
||||
*s += 1;
|
||||
return 8;
|
||||
}
|
||||
|
@ -173,8 +195,9 @@ getbase(char **s) {
|
|||
}
|
||||
|
||||
int
|
||||
getlong(char *s, long *ret) {
|
||||
char *end, *rend;
|
||||
getlong(const char *s, long *ret) {
|
||||
const char *end;
|
||||
char *rend;
|
||||
int base;
|
||||
|
||||
end = s+strlen(s);
|
||||
|
@ -185,8 +208,9 @@ getlong(char *s, long *ret) {
|
|||
}
|
||||
|
||||
int
|
||||
getulong(char *s, ulong *ret) {
|
||||
char *end, *rend;
|
||||
getulong(const char *s, ulong *ret) {
|
||||
const char *end;
|
||||
char *rend;
|
||||
int base;
|
||||
|
||||
end = s+strlen(s);
|
||||
|
@ -196,7 +220,7 @@ getulong(char *s, ulong *ret) {
|
|||
return (end == rend);
|
||||
}
|
||||
|
||||
static Client *
|
||||
static Client*
|
||||
strclient(View *v, char *s) {
|
||||
ulong id;
|
||||
|
||||
|
@ -208,8 +232,8 @@ strclient(View *v, char *s) {
|
|||
return nil;
|
||||
}
|
||||
|
||||
Area *
|
||||
strarea(View *v, char *s) {
|
||||
Area*
|
||||
strarea(View *v, const char *s) {
|
||||
Area *a;
|
||||
long i;
|
||||
|
||||
|
@ -220,10 +244,10 @@ strarea(View *v, char *s) {
|
|||
if(!getlong(s, &i) || i == 0)
|
||||
return nil;
|
||||
|
||||
if(i > 0)
|
||||
for(a = v->area; a; a = a->next) {
|
||||
if(i > 0) {
|
||||
for(a = v->area; a; a = a->next)
|
||||
if(i-- == 0) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(a = v->area; a->next; a = a->next)
|
||||
;
|
||||
|
@ -235,80 +259,36 @@ strarea(View *v, char *s) {
|
|||
return a;
|
||||
}
|
||||
|
||||
char *
|
||||
message_view(View *v, IxpMsg *m) {
|
||||
Area *a;
|
||||
char*
|
||||
message_client(Client *c, IxpMsg *m) {
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
s = getword(m);
|
||||
s = msg_getword(m);
|
||||
|
||||
switch(getsym(s)) {
|
||||
case LSEND:
|
||||
return send_client(v, m, 0);
|
||||
case LSWAP:
|
||||
return send_client(v, m, 1);
|
||||
case LSELECT:
|
||||
return select_area(v->sel, m);
|
||||
case LCOLMODE:
|
||||
s = getword(m);
|
||||
if((a = strarea(v, s)) == nil || a->floating)
|
||||
return Ebadvalue;
|
||||
|
||||
s = getword(m);
|
||||
if((i = str2colmode(s)) == -1)
|
||||
return Ebadvalue;
|
||||
|
||||
a->mode = i;
|
||||
arrange_column(a, True);
|
||||
restack_view(v);
|
||||
|
||||
if(v == screen->sel)
|
||||
focus_view(screen, v);
|
||||
draw_frames();
|
||||
return nil;
|
||||
case LFULLSCREEN:
|
||||
i = gettoggle(m);
|
||||
if(i == -1)
|
||||
return Ebadusage;
|
||||
fullscreen(c, i);
|
||||
break;
|
||||
case LKILL:
|
||||
client_kill(c);
|
||||
break;
|
||||
case LURGENT:
|
||||
i = gettoggle(m);
|
||||
if(i == -1)
|
||||
return Ebadusage;
|
||||
client_seturgent(c, i, True);
|
||||
break;
|
||||
default:
|
||||
return Ebadcmd;
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
char *
|
||||
parse_colors(IxpMsg *m, CTuple *col) {
|
||||
static char Ebad[] = "bad color string";
|
||||
Rune r;
|
||||
char c, *p;
|
||||
int i, j;
|
||||
|
||||
/* '#%6x #%6x #%6x' */
|
||||
p = (char*)m->pos;
|
||||
for(i = 0; i < 3 && p < (char*)m->end; i++) {
|
||||
if(*p++ != '#')
|
||||
return Ebad;
|
||||
for(j = 0; j < 6 && p < (char*)m->end; j++)
|
||||
if(!isxdigit(*p++))
|
||||
return Ebad;
|
||||
|
||||
chartorune(&r, p);
|
||||
if(i < 2) {
|
||||
if(r != ' ')
|
||||
return Ebad;
|
||||
p++;
|
||||
}else if(!isspacerune(r) && *p != '\0')
|
||||
return Ebad;
|
||||
}
|
||||
|
||||
c = *p;
|
||||
*p = '\0';
|
||||
loadcolor(col, (char*)m->pos);
|
||||
*p = c;
|
||||
|
||||
m->pos = (uchar*)p;
|
||||
eatrunes(m, isspacerune, 1);
|
||||
return nil;
|
||||
}
|
||||
|
||||
char *
|
||||
char*
|
||||
message_root(void *p, IxpMsg *m) {
|
||||
Font *fn;
|
||||
char *s, *ret;
|
||||
|
@ -316,48 +296,38 @@ message_root(void *p, IxpMsg *m) {
|
|||
|
||||
USED(p);
|
||||
ret = nil;
|
||||
s = getword(m);
|
||||
s = msg_getword(m);
|
||||
|
||||
switch(getsym(s)) {
|
||||
case LQUIT:
|
||||
srv.running = 0;
|
||||
case LBORDER:
|
||||
if(!getulong(msg_getword(m), &n))
|
||||
return Ebadvalue;
|
||||
def.border = n;
|
||||
view_focus(screen, screen->sel);
|
||||
break;
|
||||
case LDEBUG:
|
||||
ret = msg_debug(m);
|
||||
break;
|
||||
case LEXEC:
|
||||
execstr = smprint("exec %s", (char*)m->pos);
|
||||
execstr = smprint("exec %s", m->pos);
|
||||
srv.running = 0;
|
||||
break;
|
||||
case LVIEW:
|
||||
select_view((char*)m->pos);
|
||||
break;
|
||||
case LSELCOLORS:
|
||||
fprint(2, "%s: warning: selcolors have been removed\n", argv0);
|
||||
return Ebadcmd;
|
||||
case LFOCUSCOLORS:
|
||||
ret = parse_colors(m, &def.focuscolor);
|
||||
focus_view(screen, screen->sel);
|
||||
break;
|
||||
case LNORMCOLORS:
|
||||
ret = parse_colors(m, &def.normcolor);
|
||||
focus_view(screen, screen->sel);
|
||||
ret = msg_parsecolors(m, &def.focuscolor);
|
||||
view_focus(screen, screen->sel);
|
||||
break;
|
||||
case LFONT:
|
||||
fn = loadfont((char*)m->pos);
|
||||
fn = loadfont(m->pos);
|
||||
if(fn) {
|
||||
freefont(def.font);
|
||||
def.font = fn;
|
||||
resize_bar(screen);
|
||||
bar_resize(screen);
|
||||
}else
|
||||
ret = "can't load font";
|
||||
focus_view(screen, screen->sel);
|
||||
break;
|
||||
case LBORDER:
|
||||
if(!getulong(getword(m), &n))
|
||||
return Ebadvalue;
|
||||
def.border = n;
|
||||
focus_view(screen, screen->sel);
|
||||
view_focus(screen, screen->sel);
|
||||
break;
|
||||
case LGRABMOD:
|
||||
s = getword(m);
|
||||
s = msg_getword(m);
|
||||
n = str2modmask(s);
|
||||
|
||||
if((n & (Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) == 0)
|
||||
|
@ -366,97 +336,276 @@ message_root(void *p, IxpMsg *m) {
|
|||
utflcpy(def.grabmod, s, sizeof(def.grabmod));
|
||||
def.mod = n;
|
||||
break;
|
||||
case LNORMCOLORS:
|
||||
ret = msg_parsecolors(m, &def.normcolor);
|
||||
view_focus(screen, screen->sel);
|
||||
break;
|
||||
case LSELCOLORS:
|
||||
fprint(2, "%s: warning: selcolors have been removed\n", argv0);
|
||||
return Ebadcmd;
|
||||
case LVIEW:
|
||||
view_select(m->pos);
|
||||
break;
|
||||
case LQUIT:
|
||||
srv.running = 0;
|
||||
break;
|
||||
default:
|
||||
return Ebadcmd;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
read_root_ctl(void) {
|
||||
char *b, *e;
|
||||
|
||||
b = buffer;
|
||||
e = b + sizeof(buffer) - 1;
|
||||
b = seprint(b, e, "view %s\n", screen->sel->name);
|
||||
b = seprint(b, e, "focuscolors %s\n", def.focuscolor.colstr);
|
||||
b = seprint(b, e, "normcolors %s\n", def.normcolor.colstr);
|
||||
b = seprint(b, e, "font %s\n", def.font->name);
|
||||
b = seprint(b, e, "grabmod %s\n", def.grabmod);
|
||||
b = seprint(b, e, "border %d\n", def.border);
|
||||
USED(b);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *
|
||||
message_client(Client *c, IxpMsg *m) {
|
||||
char*
|
||||
message_view(View *v, IxpMsg *m) {
|
||||
Area *a;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
s = getword(m);
|
||||
s = msg_getword(m);
|
||||
|
||||
switch(getsym(s)) {
|
||||
case LKILL:
|
||||
kill_client(c);
|
||||
break;
|
||||
case LURGENT:
|
||||
i = gettoggle(m);
|
||||
case LCOLMODE:
|
||||
s = msg_getword(m);
|
||||
a = strarea(v, s);
|
||||
if(a == nil || a->floating)
|
||||
return Ebadvalue;
|
||||
|
||||
s = msg_getword(m);
|
||||
i = str2colmode(s);
|
||||
if(i == -1)
|
||||
return Ebadusage;
|
||||
set_urgent(c, i, True);
|
||||
break;
|
||||
case LFULLSCREEN:
|
||||
i = gettoggle(m);
|
||||
if(i == -1)
|
||||
return Ebadusage;
|
||||
fullscreen(c, i);
|
||||
break;
|
||||
return Ebadvalue;
|
||||
|
||||
a->mode = i;
|
||||
column_arrange(a, True);
|
||||
view_restack(v);
|
||||
|
||||
if(v == screen->sel)
|
||||
view_focus(screen, v);
|
||||
frame_draw_all();
|
||||
return nil;
|
||||
case LSELECT:
|
||||
return msg_selectarea(v->sel, m);
|
||||
case LSEND:
|
||||
return msg_sendclient(v, m, 0);
|
||||
case LSWAP:
|
||||
return msg_sendclient(v, m, 1);
|
||||
default:
|
||||
return Ebadcmd;
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
static void
|
||||
printdebug(void) {
|
||||
int i, j;
|
||||
|
||||
for(i=0, j=0; i < nelem(debugtab); i++)
|
||||
Debug(1<<i) {
|
||||
if(j++ > 0)
|
||||
bufprint(" ");
|
||||
bufprint("%s", debugtab[i]);
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
root_readctl(void) {
|
||||
bufclear();
|
||||
bufprint("view %s\n", screen->sel->name);
|
||||
bufprint("focuscolors %s\n", def.focuscolor.colstr);
|
||||
bufprint("normcolors %s\n", def.normcolor.colstr);
|
||||
bufprint("font %s\n", def.font->name);
|
||||
bufprint("grabmod %s\n", def.grabmod);
|
||||
bufprint("border %d\n", def.border);
|
||||
if(debug) {
|
||||
bufprint("debug ");
|
||||
printdebug();
|
||||
bufprint("\n");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char*
|
||||
msg_debug(IxpMsg *m) {
|
||||
char *opt;
|
||||
int d;
|
||||
char add;
|
||||
|
||||
bufclear();
|
||||
while((opt = msg_getword(m))) {
|
||||
add = '+';
|
||||
if(opt[0] == '+' || opt[0] == '-')
|
||||
add = *opt++;
|
||||
d = getdebug(opt);
|
||||
if(d == -1) {
|
||||
bufprint(", %s", opt);
|
||||
continue;
|
||||
}
|
||||
if(add == '+')
|
||||
debug |= 1<<d;
|
||||
else
|
||||
debug &= ~(1<<d);
|
||||
}
|
||||
if(buffer[0] != '\0') {
|
||||
opt = smprint("Bad debug options: %s", buffer+2);
|
||||
utfecpy(buffer, buffer+sizeof(buffer), opt);
|
||||
free(opt);
|
||||
return buffer;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
char*
|
||||
msg_parsecolors(IxpMsg *m, CTuple *col) {
|
||||
static char Ebad[] = "bad color string";
|
||||
Rune r;
|
||||
char c, *p;
|
||||
int i, j;
|
||||
|
||||
/* '#%6x #%6x #%6x' */
|
||||
p = m->pos;
|
||||
for(i = 0; i < 3 && p < m->end; i++) {
|
||||
if(*p++ != '#')
|
||||
return Ebad;
|
||||
for(j = 0; j < 6; j++)
|
||||
if(p >= m->end || !isxdigit(*p++))
|
||||
return Ebad;
|
||||
|
||||
chartorune(&r, p);
|
||||
if(i < 2) {
|
||||
if(r != ' ')
|
||||
return Ebad;
|
||||
p++;
|
||||
}else if(*p != '\0' && !isspacerune(r))
|
||||
return Ebad;
|
||||
}
|
||||
|
||||
c = *p;
|
||||
*p = '\0';
|
||||
loadcolor(col, m->pos);
|
||||
*p = c;
|
||||
|
||||
m->pos = p;
|
||||
eatrunes(m, isspacerune, 1);
|
||||
return nil;
|
||||
}
|
||||
|
||||
char*
|
||||
msg_selectarea(Area *a, IxpMsg *m) {
|
||||
Frame *f;
|
||||
Area *ap;
|
||||
View *v;
|
||||
char *s;
|
||||
ulong i;
|
||||
int sym;
|
||||
|
||||
v = a->view;
|
||||
s = msg_getword(m);
|
||||
sym = getsym(s);
|
||||
|
||||
switch(sym) {
|
||||
case LTOGGLE:
|
||||
if(!a->floating)
|
||||
ap = v->area;
|
||||
else if(v->revert && v->revert != a)
|
||||
ap = v->revert;
|
||||
else
|
||||
ap = v->area->next;
|
||||
break;
|
||||
case LUP:
|
||||
case LDOWN:
|
||||
case LCLIENT:
|
||||
return msg_selectframe(a->sel, m, sym);
|
||||
case LLEFT:
|
||||
if(a->floating)
|
||||
return Ebadvalue;
|
||||
for(ap=v->area->next; ap->next; ap=ap->next)
|
||||
if(ap->next == a) break;
|
||||
break;
|
||||
case LRIGHT:
|
||||
if(a->floating)
|
||||
return Ebadvalue;
|
||||
ap = a->next;
|
||||
if(ap == nil)
|
||||
ap = v->area->next;
|
||||
break;
|
||||
case LTILDE:
|
||||
ap = v->area;
|
||||
break;
|
||||
default:
|
||||
if(!strcmp(s, "sel"))
|
||||
ap = v->sel;
|
||||
else {
|
||||
if(!getulong(s, &i) || i == 0)
|
||||
return Ebadvalue;
|
||||
for(ap=v->area->next; ap; ap=ap->next)
|
||||
if(--i == 0) break;
|
||||
if(i != 0)
|
||||
return Ebadvalue;
|
||||
}
|
||||
if((s = msg_getword(m))) {
|
||||
if(!getulong(s, &i))
|
||||
return Ebadvalue;
|
||||
for(f = ap->frame; f; f = f->anext)
|
||||
if(--i == 0) break;
|
||||
if(i != 0)
|
||||
return Ebadvalue;
|
||||
frame_focus(f);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
area_focus(ap);
|
||||
return nil;
|
||||
}
|
||||
|
||||
static char*
|
||||
send_frame(Frame *f, int sym, Bool swap) {
|
||||
msg_selectframe(Frame *f, IxpMsg *m, int sym) {
|
||||
Frame *fp;
|
||||
Client *c;
|
||||
Area *a;
|
||||
char *s;
|
||||
ulong i;
|
||||
|
||||
if(!f)
|
||||
return Ebadvalue;
|
||||
a = f->area;
|
||||
|
||||
SET(fp);
|
||||
switch(sym) {
|
||||
case LUP:
|
||||
fp = f->aprev;
|
||||
if(!fp)
|
||||
return Ebadvalue;
|
||||
fp = fp->aprev;
|
||||
for(fp = a->frame; fp->anext; fp = fp->anext)
|
||||
if(fp->anext == f) break;
|
||||
break;
|
||||
case LDOWN:
|
||||
fp = f->anext;
|
||||
if(!fp)
|
||||
return Ebadvalue;
|
||||
if(fp == nil)
|
||||
fp = a->frame;
|
||||
break;
|
||||
case LCLIENT:
|
||||
s = msg_getword(m);
|
||||
if(s == nil || !getulong(s, &i))
|
||||
return "usage: select client <client>";
|
||||
c = win2client(i);
|
||||
if(c == nil)
|
||||
return "unknown client";
|
||||
fp = client_viewframe(c, f->view);
|
||||
break;
|
||||
default:
|
||||
assert(!"can't get here");
|
||||
die("can't get here");
|
||||
}
|
||||
|
||||
if(swap) {
|
||||
if(!fp)
|
||||
return Ebadvalue;
|
||||
swap_frames(f, fp);
|
||||
}else {
|
||||
remove_frame(f);
|
||||
insert_frame(fp, f);
|
||||
}
|
||||
if(fp == nil)
|
||||
return "invalid selection";
|
||||
|
||||
arrange_view(f->view);
|
||||
|
||||
flushevents(EnterWindowMask, False);
|
||||
focus_frame(f, True);
|
||||
update_views();
|
||||
frame_focus(fp);
|
||||
frame_to_top(fp);
|
||||
if(f->view == screen->sel)
|
||||
view_restack(f->view);
|
||||
return nil;
|
||||
}
|
||||
|
||||
char *
|
||||
send_client(View *v, IxpMsg *m, Bool swap) {
|
||||
char*
|
||||
msg_sendclient(View *v, IxpMsg *m, bool swap) {
|
||||
Area *to, *a;
|
||||
Frame *f;
|
||||
Client *c;
|
||||
|
@ -464,26 +613,26 @@ send_client(View *v, IxpMsg *m, Bool swap) {
|
|||
ulong i;
|
||||
int sym;
|
||||
|
||||
s = getword(m);
|
||||
s = msg_getword(m);
|
||||
|
||||
c = strclient(v, s);
|
||||
if(c == nil)
|
||||
return Ebadvalue;
|
||||
|
||||
f = view_clientframe(v, c);
|
||||
f = client_viewframe(c, v);
|
||||
if(f == nil)
|
||||
return Ebadvalue;
|
||||
|
||||
a = f->area;
|
||||
to = nil;
|
||||
|
||||
s = getword(m);
|
||||
s = msg_getword(m);
|
||||
sym = getsym(s);
|
||||
|
||||
switch(sym) {
|
||||
case LUP:
|
||||
case LDOWN:
|
||||
return send_frame(f, sym, swap);
|
||||
return msg_sendframe(f, sym, swap);
|
||||
case LLEFT:
|
||||
if(a->floating)
|
||||
return Ebadvalue;
|
||||
|
@ -516,136 +665,60 @@ send_client(View *v, IxpMsg *m, Bool swap) {
|
|||
}
|
||||
|
||||
if(!to && !swap && (f->anext || f != f->area->frame))
|
||||
to = new_column(v, a, 0);
|
||||
to = column_new(v, a, 0);
|
||||
|
||||
if(!to)
|
||||
return Ebadvalue;
|
||||
|
||||
if(!swap)
|
||||
send_to_area(to, f);
|
||||
area_moveto(to, f);
|
||||
else if(to->sel)
|
||||
swap_frames(f, to->sel);
|
||||
frame_swap(f, to->sel);
|
||||
else
|
||||
return Ebadvalue;
|
||||
|
||||
flushevents(EnterWindowMask, False);
|
||||
focus_frame(f, True);
|
||||
arrange_view(v);
|
||||
update_views();
|
||||
frame_focus(f);
|
||||
view_arrange(v);
|
||||
view_update_all();
|
||||
return nil;
|
||||
}
|
||||
|
||||
static char*
|
||||
select_frame(Frame *f, IxpMsg *m, int sym) {
|
||||
msg_sendframe(Frame *f, int sym, bool swap) {
|
||||
Frame *fp;
|
||||
Client *c;
|
||||
Area *a;
|
||||
char *s;
|
||||
ulong i;
|
||||
|
||||
if(!f)
|
||||
return Ebadvalue;
|
||||
a = f->area;
|
||||
|
||||
SET(fp);
|
||||
switch(sym) {
|
||||
case LUP:
|
||||
for(fp = a->frame; fp->anext; fp = fp->anext)
|
||||
if(fp->anext == f) break;
|
||||
fp = f->aprev;
|
||||
if(!fp)
|
||||
return Ebadvalue;
|
||||
fp = fp->aprev;
|
||||
break;
|
||||
case LDOWN:
|
||||
fp = f->anext;
|
||||
if(fp == nil)
|
||||
fp = a->frame;
|
||||
break;
|
||||
case LCLIENT:
|
||||
s = getword(m);
|
||||
if(s == nil || !getulong(s, &i))
|
||||
return "usage: select client <client>";
|
||||
c = win2client(i);
|
||||
if(c == nil)
|
||||
return "unknown client";
|
||||
fp = view_clientframe(f->view, c);
|
||||
if(!fp)
|
||||
return Ebadvalue;
|
||||
break;
|
||||
default:
|
||||
assert(!"can't get here");
|
||||
die("can't get here");
|
||||
}
|
||||
|
||||
if(fp == nil)
|
||||
return "invalid selection";
|
||||
if(swap) {
|
||||
if(!fp)
|
||||
return Ebadvalue;
|
||||
frame_swap(f, fp);
|
||||
}else {
|
||||
frame_remove(f);
|
||||
frame_insert(fp, f);
|
||||
}
|
||||
|
||||
focus_frame(fp, False);
|
||||
frame_to_top(fp);
|
||||
if(f->view == screen->sel)
|
||||
restack_view(f->view);
|
||||
view_arrange(f->view);
|
||||
|
||||
flushevents(EnterWindowMask, False);
|
||||
frame_focus(f);
|
||||
view_update_all();
|
||||
return nil;
|
||||
}
|
||||
|
||||
char*
|
||||
select_area(Area *a, IxpMsg *m) {
|
||||
Frame *f;
|
||||
Area *ap;
|
||||
View *v;
|
||||
char *s;
|
||||
ulong i;
|
||||
int sym;
|
||||
|
||||
v = a->view;
|
||||
s = getword(m);
|
||||
sym = getsym(s);
|
||||
|
||||
switch(sym) {
|
||||
case LTOGGLE:
|
||||
if(!a->floating)
|
||||
ap = v->area;
|
||||
else if(v->revert && v->revert != a)
|
||||
ap = v->revert;
|
||||
else
|
||||
ap = v->area->next;
|
||||
break;
|
||||
case LUP:
|
||||
case LDOWN:
|
||||
case LCLIENT:
|
||||
return select_frame(a->sel, m, sym);
|
||||
case LLEFT:
|
||||
if(a->floating)
|
||||
return Ebadvalue;
|
||||
for(ap=v->area->next; ap->next; ap=ap->next)
|
||||
if(ap->next == a) break;
|
||||
break;
|
||||
case LRIGHT:
|
||||
if(a->floating)
|
||||
return Ebadvalue;
|
||||
ap = a->next;
|
||||
if(ap == nil)
|
||||
ap = v->area->next;
|
||||
break;
|
||||
case LTILDE:
|
||||
ap = v->area;
|
||||
break;
|
||||
default:
|
||||
if(!strcmp(s, "sel"))
|
||||
ap = v->sel;
|
||||
else {
|
||||
if(!getulong(s, &i) || i == 0)
|
||||
return Ebadvalue;
|
||||
for(ap=v->area->next; ap; ap=ap->next)
|
||||
if(--i == 0) break;
|
||||
if(i != 0)
|
||||
return Ebadvalue;
|
||||
}
|
||||
if((s = getword(m))) {
|
||||
if(!getulong(s, &i))
|
||||
return Ebadvalue;
|
||||
for(f = ap->frame; f; f = f->anext)
|
||||
if(--i == 0) break;
|
||||
if(i != 0)
|
||||
return Ebadvalue;
|
||||
focus_frame(f, True);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
focus_area(ap);
|
||||
return nil;
|
||||
}
|
||||
|
|
149
cmd/wmii/mouse.c
149
cmd/wmii/mouse.c
|
@ -3,9 +3,6 @@
|
|||
*/
|
||||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fns.h"
|
||||
|
||||
enum {
|
||||
|
@ -50,9 +47,9 @@ framerect(Framewin *f) {
|
|||
|
||||
/* Keep onscreen */
|
||||
p = ZP;
|
||||
p.x -= min(r.min.x, 0);
|
||||
p.x -= max(r.max.x - screen->r.max.x, 0);
|
||||
p.y -= max(r.max.y - screen->brect.min.y - Dy(r)/2, 0);
|
||||
p.x -= min(0, r.min.x);
|
||||
p.x -= max(0, r.max.x - screen->r.max.x);
|
||||
p.y -= max(0, r.max.y - screen->brect.min.y - Dy(r)/2);
|
||||
return rectaddpt(r, p);
|
||||
}
|
||||
|
||||
|
@ -238,7 +235,7 @@ do_managed_move(Client *c) {
|
|||
Point pt, pt2;
|
||||
int y;
|
||||
|
||||
focus(c, False);
|
||||
focus(c, false);
|
||||
f = c->sel;
|
||||
|
||||
pt = querypointer(&scr.root);
|
||||
|
@ -254,7 +251,7 @@ do_managed_move(Client *c) {
|
|||
mapwin(cwin);
|
||||
|
||||
horiz:
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
ungrabpointer();
|
||||
if(!grabpointer(&scr.root, nil, cursor[CurIcon], MouseMask))
|
||||
goto done;
|
||||
warppointer(pt);
|
||||
|
@ -276,9 +273,10 @@ horiz:
|
|||
case ButtonRelease:
|
||||
switch(ev.xbutton.button) {
|
||||
case 1:
|
||||
/* TODO: Fix... Tangled, broken mess. */
|
||||
if((f->anext) && (!f->aprev || (fw->fp != f->aprev && fw->fp != f->aprev->aprev))) {
|
||||
f->anext->r.min.y = f->r.min.y;
|
||||
resize_frame(f->anext, f->anext->r);
|
||||
frame_resize(f->anext, f->anext->r);
|
||||
}
|
||||
else if(f->aprev) {
|
||||
if(fw->fp == f->aprev->aprev) {
|
||||
|
@ -286,16 +284,16 @@ horiz:
|
|||
f->aprev->r = f->r;
|
||||
}else
|
||||
f->aprev->r.max.y = f->r.max.y;
|
||||
resize_frame(f->aprev, f->aprev->r);
|
||||
frame_resize(f->aprev, f->aprev->r);
|
||||
}
|
||||
|
||||
remove_frame(f);
|
||||
frame_remove(f);
|
||||
f->area = fw->ra;
|
||||
insert_frame(fw->fp, f);
|
||||
frame_insert(fw->fp, f);
|
||||
|
||||
if(f->aprev) {
|
||||
f->aprev->r.max.y = fw->fr.min.y;
|
||||
resize_frame(f->aprev, f->aprev->r);
|
||||
frame_resize(f->aprev, f->aprev->r);
|
||||
}
|
||||
else
|
||||
fw->fr.min.y = f->area->r.min.y;
|
||||
|
@ -303,9 +301,9 @@ horiz:
|
|||
fw->fr.max.y = f->anext->r.min.y;
|
||||
else
|
||||
fw->fr.max.y = f->area->r.max.y;
|
||||
resize_frame(f, fw->fr);
|
||||
frame_resize(f, fw->fr);
|
||||
|
||||
arrange_view(f->view);
|
||||
view_arrange(f->view);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
@ -319,7 +317,7 @@ horiz:
|
|||
}
|
||||
vert:
|
||||
y = pt.y;
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
ungrabpointer();
|
||||
if(!grabpointer(&scr.root, cwin, cursor[CurIcon], MouseMask))
|
||||
goto done;
|
||||
hplace(fw, pt);
|
||||
|
@ -341,8 +339,8 @@ vert:
|
|||
switch(ev.xbutton.button) {
|
||||
case 1:
|
||||
if(fw->ra) {
|
||||
fw->ra = new_column(f->view, fw->ra, 0);
|
||||
send_to_area(fw->ra, f);
|
||||
fw->ra = column_new(f->view, fw->ra, 0);
|
||||
area_moveto(fw->ra, f);
|
||||
}
|
||||
goto done;
|
||||
case 2:
|
||||
|
@ -353,7 +351,7 @@ vert:
|
|||
}
|
||||
}
|
||||
done:
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
ungrabpointer();
|
||||
framedestroy(fw);
|
||||
destroywindow(cwin);
|
||||
|
||||
|
@ -363,7 +361,7 @@ done:
|
|||
warppointer(pt);
|
||||
}
|
||||
|
||||
static Window *
|
||||
static Window*
|
||||
gethsep(Rectangle r) {
|
||||
Window *w;
|
||||
WinAttr wa;
|
||||
|
@ -471,7 +469,7 @@ mouse_resizecolframe(Frame *f, Align align) {
|
|||
r.min.y = ((align&SOUTH) ? pt.y : pt.y-1);
|
||||
r.max.y = r.min.y+2;
|
||||
|
||||
setdiv(d, pt.x);
|
||||
div_set(d, pt.x);
|
||||
reshapewin(hwin, r);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
|
@ -484,8 +482,9 @@ mouse_resizecolframe(Frame *f, Align align) {
|
|||
r.min.y = pt.y;
|
||||
else
|
||||
r.max.y = pt.y;
|
||||
resize_colframe(f, &r);
|
||||
column_resizeframe(f, &r);
|
||||
|
||||
/* XXX: Magic number... */
|
||||
if(align&WEST)
|
||||
pt.x = f->r.min.x + 4;
|
||||
else
|
||||
|
@ -499,7 +498,7 @@ mouse_resizecolframe(Frame *f, Align align) {
|
|||
}
|
||||
}
|
||||
done:
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
ungrabpointer();
|
||||
destroywindow(cwin);
|
||||
destroywindow(hwin);
|
||||
}
|
||||
|
@ -549,20 +548,20 @@ mouse_resizecol(Divide *d) {
|
|||
break;
|
||||
case MotionNotify:
|
||||
pt.x = ev.xmotion.x_root;
|
||||
setdiv(d, pt.x);
|
||||
div_set(d, pt.x);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
resize_column(a, pt.x - a->r.min.x);
|
||||
column_resize(a, pt.x - a->r.min.x);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
ungrabpointer();
|
||||
destroywindow(cwin);
|
||||
}
|
||||
|
||||
static void
|
||||
rect_morph_xy(Rectangle *r, Point d, Align *mask) {
|
||||
rect_morph(Rectangle *r, Point d, Align *mask) {
|
||||
int n;
|
||||
|
||||
if(*mask & NORTH)
|
||||
|
@ -589,38 +588,43 @@ rect_morph_xy(Rectangle *r, Point d, Align *mask) {
|
|||
}
|
||||
|
||||
static int
|
||||
snap_line(Rectangle *rects, int nrect, int d, int horiz, Rectangle *r, int x, int y) {
|
||||
snap_hline(Rectangle *rects, int nrect, int dy, Rectangle *r, int y) {
|
||||
Rectangle *rp;
|
||||
int i, tx, ty;
|
||||
int i, ty;
|
||||
|
||||
if(horiz) {
|
||||
for(i=0; i < nrect; i++) {
|
||||
rp = &rects[i];
|
||||
if((rp->min.x <= r->max.x) && (rp->max.x >= r->min.x)) {
|
||||
ty = rp->min.y;
|
||||
if(abs(ty - y) <= abs(d))
|
||||
d = ty - y;
|
||||
for(i=0; i < nrect; i++) {
|
||||
rp = &rects[i];
|
||||
if((rp->min.x <= r->max.x) && (rp->max.x >= r->min.x)) {
|
||||
ty = rp->min.y;
|
||||
if(abs(ty - y) <= abs(dy))
|
||||
dy = ty - y;
|
||||
|
||||
ty = rp->max.y;
|
||||
if(abs(ty - y) <= abs(d))
|
||||
d = ty - y;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
for(i=0; i < nrect; i++) {
|
||||
rp = &rects[i];
|
||||
if((rp->min.y <= r->max.y) && (rp->max.y >= r->min.y)) {
|
||||
tx = rp->min.x;
|
||||
if(abs(tx - x) <= abs(d))
|
||||
d = tx - x;
|
||||
|
||||
tx = rp->max.x;
|
||||
if(abs(tx - x) <= abs(d))
|
||||
d = tx - x;
|
||||
}
|
||||
ty = rp->max.y;
|
||||
if(abs(ty - y) <= abs(dy))
|
||||
dy = ty - y;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
return dy;
|
||||
}
|
||||
|
||||
static int
|
||||
snap_vline(Rectangle *rects, int nrect, int dx, Rectangle *r, int x) {
|
||||
Rectangle *rp;
|
||||
int i, tx;
|
||||
|
||||
for(i=0; i < nrect; i++) {
|
||||
rp = &rects[i];
|
||||
if((rp->min.y <= r->max.y) && (rp->max.y >= r->min.y)) {
|
||||
tx = rp->min.x;
|
||||
if(abs(tx - x) <= abs(dx))
|
||||
dx = tx - x;
|
||||
|
||||
tx = rp->max.x;
|
||||
if(abs(tx - x) <= abs(dx))
|
||||
dx = tx - x;
|
||||
}
|
||||
}
|
||||
return dx;
|
||||
}
|
||||
|
||||
/* Returns a gravity for increment handling. It's normally the opposite of the mask
|
||||
|
@ -636,14 +640,14 @@ snap_rect(Rectangle *rects, int num, Rectangle *r, Align *mask, int snap) {
|
|||
d.y = snap+1;
|
||||
|
||||
if(*mask&NORTH)
|
||||
d.y = snap_line(rects, num, d.y, True, r, 0, r->min.y);
|
||||
d.y = snap_hline(rects, num, d.y, r, r->min.y);
|
||||
if(*mask&SOUTH)
|
||||
d.y = snap_line(rects, num, d.y, True, r, 0, r->max.y);
|
||||
d.y = snap_hline(rects, num, d.y, r, r->max.y);
|
||||
|
||||
if(*mask&EAST)
|
||||
d.x = snap_line(rects, num, d.x, False, r, r->max.x, 0);
|
||||
d.x = snap_vline(rects, num, d.x, r, r->max.x);
|
||||
if(*mask&WEST)
|
||||
d.x = snap_line(rects, num, d.x, False, r, r->min.x, 0);
|
||||
d.x = snap_vline(rects, num, d.x, r, r->min.x);
|
||||
|
||||
ret = CENTER;
|
||||
if(abs(d.x) <= snap)
|
||||
|
@ -656,12 +660,13 @@ snap_rect(Rectangle *rects, int num, Rectangle *r, Align *mask, int snap) {
|
|||
else
|
||||
d.y = 0;
|
||||
|
||||
rect_morph_xy(r, d, mask);
|
||||
rect_morph(r, d, mask);
|
||||
return ret ^ *mask;
|
||||
}
|
||||
|
||||
/* Grumble... Messy... TODO: Rewrite. */
|
||||
void
|
||||
do_mouse_resize(Client *c, Bool opaque, Align align) {
|
||||
mouse_resize(Client *c, bool opaque, Align align) {
|
||||
XEvent ev;
|
||||
Rectangle *rects;
|
||||
Rectangle frect, origin;
|
||||
|
@ -684,9 +689,9 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
|
|||
|
||||
origin = f->r;
|
||||
frect = f->r;
|
||||
rects = rects_of_view(f->area->view, &num, c->frame);
|
||||
rects = view_rects(f->area->view, &num, c->frame);
|
||||
|
||||
cur = cursor_of_quad(align);
|
||||
cur = quad_cursor(align);
|
||||
if((align==CENTER) && !opaque)
|
||||
cur = cursor[CurSizing];
|
||||
|
||||
|
@ -704,7 +709,6 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
|
|||
|
||||
if(align != CENTER) {
|
||||
d = hr;
|
||||
|
||||
if(align&NORTH) d.y -= hr.y;
|
||||
if(align&SOUTH) d.y += hr.y;
|
||||
if(align&EAST) d.x += hr.x;
|
||||
|
@ -714,7 +718,7 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
|
|||
warppointer(pt);
|
||||
}
|
||||
else if(f->client->fullscreen) {
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
ungrabpointer();
|
||||
return;
|
||||
}
|
||||
else if(!opaque) {
|
||||
|
@ -745,13 +749,15 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
|
|||
d.y = ev.xmotion.y_root;
|
||||
|
||||
if(align == CENTER && !opaque) {
|
||||
SET(hrx);
|
||||
SET(hry);
|
||||
d.x = (d.x * hrx) - pt.x;
|
||||
d.y = (d.y * hry) - pt.y;
|
||||
}else
|
||||
d = subpt(d, pt);
|
||||
pt = addpt(pt, d);
|
||||
|
||||
rect_morph_xy(&origin, d, &align);
|
||||
rect_morph(&origin, d, &align);
|
||||
origin = constrain(origin);
|
||||
frect = origin;
|
||||
|
||||
|
@ -761,10 +767,10 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
|
|||
frect = constrain(frect);
|
||||
|
||||
//reshapewin(c->framewin, frect);
|
||||
resize_client(c, &frect);
|
||||
client_resize(c, frect);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
resize_client(c, &frect);
|
||||
client_resize(c, frect);
|
||||
|
||||
if(!opaque) {
|
||||
pt = translate(c->framewin, &scr.root,
|
||||
|
@ -775,20 +781,21 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
|
|||
}
|
||||
|
||||
free(rects);
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
ungrabpointer();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Doesn't belong here */
|
||||
void
|
||||
grab_button(XWindow w, uint button, ulong mod) {
|
||||
XGrabButton(display, button, mod, w, False, ButtonMask,
|
||||
GrabModeSync, GrabModeSync, None, None);
|
||||
if((mod != AnyModifier) && (num_lock_mask != 0)) {
|
||||
XGrabButton(display, button, mod | num_lock_mask, w, False, ButtonMask,
|
||||
if((mod != AnyModifier) && (numlock_mask != 0)) {
|
||||
XGrabButton(display, button, mod | numlock_mask, w, False, ButtonMask,
|
||||
GrabModeSync, GrabModeAsync, None, None);
|
||||
XGrabButton(display, button, mod | num_lock_mask | LockMask, w, False,
|
||||
XGrabButton(display, button, mod | numlock_mask | LockMask, w, False,
|
||||
ButtonMask, GrabModeSync, GrabModeAsync, None, None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,9 +41,6 @@
|
|||
|
||||
#include "dat.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <bio.h>
|
||||
//#include "fns.h"
|
||||
#include "printevent.h"
|
||||
|
@ -96,13 +93,13 @@ unmask(Pair * list, uint val)
|
|||
|
||||
static char *
|
||||
strhex(int key) {
|
||||
sprintf(buffer, "0x%x", key);
|
||||
sprint(buffer, "0x%x", key);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char *
|
||||
strdec(int key) {
|
||||
sprintf(buffer, "%d", key);
|
||||
sprint(buffer, "%d", key);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -656,14 +653,13 @@ VerbFocus(XEvent *e) {
|
|||
static void
|
||||
VerbKeymap(XEvent *e) {
|
||||
XKeymapEvent *ev = &e->xkeymap;
|
||||
int i;
|
||||
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "window=0x%x%s", (int)ev->window, sep);
|
||||
fprintf(stderr, "key_vector=");
|
||||
fprint(2, "window=0x%x%s", (int)ev->window, sep);
|
||||
fprint(2, "key_vector=");
|
||||
for (i = 0; i < 32; i++)
|
||||
fprintf(stderr, "%02x", ev->key_vector[i]);
|
||||
fprintf(stderr, "\n");
|
||||
fprint(2, "%02x", ev->key_vector[i]);
|
||||
fprint(2, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -935,7 +931,6 @@ VerbVisibility(XEvent *e) {
|
|||
/******************************************************************************/
|
||||
|
||||
typedef struct Handler Handler;
|
||||
|
||||
struct Handler {
|
||||
int key;
|
||||
void (*fn)(XEvent*);
|
||||
|
@ -945,9 +940,9 @@ void
|
|||
printevent(XEvent *e) {
|
||||
XAnyEvent *ev = &e->xany;
|
||||
|
||||
fprintf(stderr, "%3ld %-20s ", ev->serial, eventtype(e->xany.type));
|
||||
fprint(2, "%3ld %-20s ", ev->serial, eventtype(e->xany.type));
|
||||
if(ev->send_event)
|
||||
fprintf(stderr, "(sendevent) ");
|
||||
fprint(2, "(sendevent) ");
|
||||
/*
|
||||
fprintf(stderr, "type=%s%s", eventtype(e->xany.type), sep);
|
||||
fprintf(stderr, "serial=%lu%s", ev->serial, sep);
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "fns.h"
|
||||
|
||||
/* basic rule matching language /regex/ -> value
|
||||
|
@ -20,14 +18,15 @@ enum {
|
|||
void
|
||||
trim(char *str, const char *chars) {
|
||||
const char *cp;
|
||||
char *sp, *sn;
|
||||
char *p, *q;
|
||||
char c;
|
||||
|
||||
for(cp = chars; *cp; cp++) {
|
||||
for(sp = sn = str; *sn; sn++) {
|
||||
if(*sn != *cp)
|
||||
*(sp++) = *sn;
|
||||
}
|
||||
*sp = 0;
|
||||
for(cp = chars; (c = *cp); cp++) {
|
||||
q = str;
|
||||
for(p = q; *p; p++)
|
||||
if(*p != c)
|
||||
*q++ = *p;
|
||||
*q = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,6 +86,6 @@ update_rules(Rule **rule, const char *data) {
|
|||
*v++ = *p;
|
||||
break;
|
||||
default: /* can't happen */
|
||||
assert(!"invalid state");
|
||||
die("invalid state");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
#include "dat.h"
|
||||
#include <errno.h>
|
||||
#include <iconv.h>
|
||||
#include <string.h>
|
||||
#include "fns.h"
|
||||
|
||||
char*
|
||||
toutf8n(char *str, size_t nstr) {
|
||||
toutf8n(const char *str, size_t nstr) {
|
||||
static iconv_t cd;
|
||||
char *buf, *pos;
|
||||
size_t nbuf, bsize;
|
||||
|
@ -33,7 +32,7 @@ toutf8n(char *str, size_t nstr) {
|
|||
}
|
||||
|
||||
char*
|
||||
toutf8(char *str) {
|
||||
toutf8(const char *str) {
|
||||
return toutf8n(str, strlen(str));
|
||||
}
|
||||
|
||||
|
|
256
cmd/wmii/view.c
256
cmd/wmii/view.c
|
@ -3,13 +3,10 @@
|
|||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "dat.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "fns.h"
|
||||
|
||||
static Bool
|
||||
is_empty(View *v) {
|
||||
static bool
|
||||
empty_p(View *v) {
|
||||
Area *a;
|
||||
for(a=v->area; a; a=a->next)
|
||||
if(a->frame)
|
||||
|
@ -17,86 +14,78 @@ is_empty(View *v) {
|
|||
return True;
|
||||
}
|
||||
|
||||
Frame *
|
||||
view_clientframe(View *v, Client *c) {
|
||||
Frame *f;
|
||||
|
||||
for(f=c->frame; f; f=f->cnext)
|
||||
if(f->area->view == v)
|
||||
break;
|
||||
return f;
|
||||
}
|
||||
|
||||
static void
|
||||
assign_sel_view(View *v) {
|
||||
_view_select(View *v) {
|
||||
if(screen->sel != v) {
|
||||
if(screen->sel)
|
||||
write_event("UnfocusTag %s\n",screen->sel->name);
|
||||
event("UnfocusTag %s\n",screen->sel->name);
|
||||
screen->sel = v;
|
||||
write_event("FocusTag %s\n", screen->sel->name);
|
||||
event("FocusTag %s\n", screen->sel->name);
|
||||
ewmh_updateview();
|
||||
}
|
||||
}
|
||||
|
||||
Client *
|
||||
Client*
|
||||
view_selclient(View *v) {
|
||||
return v->sel && v->sel->sel ? v->sel->sel->client : nil;
|
||||
}
|
||||
|
||||
View *
|
||||
get_view(const char *name) {
|
||||
View *v;
|
||||
int cmp;
|
||||
bool
|
||||
view_fullscreen_p(View *v) {
|
||||
Frame *f;
|
||||
|
||||
SET(cmp);
|
||||
for(v = view; v; v=v->next)
|
||||
if((cmp=strcmp(name, v->name)) >= 0)
|
||||
break;
|
||||
if(!v || cmp != 0)
|
||||
v = create_view(name);
|
||||
return v;
|
||||
for(f=v->area->frame; f; f=f->anext)
|
||||
if(f->client->fullscreen)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
View *
|
||||
create_view(const char *name) {
|
||||
View*
|
||||
view_create(const char *name) {
|
||||
static ushort id = 1;
|
||||
View **i, *v;
|
||||
|
||||
for(v=view; v; v=v->next)
|
||||
if(!strcmp(name, v->name))
|
||||
return v;
|
||||
|
||||
v = emallocz(sizeof(View));
|
||||
v->id = id++;
|
||||
|
||||
utflcpy(v->name, name, sizeof(v->name));
|
||||
|
||||
write_event("CreateTag %s\n", v->name);
|
||||
create_area(v, nil, 0);
|
||||
new_column(v, v->area, 0);
|
||||
event("CreateTag %s\n", v->name);
|
||||
area_create(v, nil, 0);
|
||||
column_new(v, v->area, 0);
|
||||
|
||||
focus_area(v->area->next);
|
||||
area_focus(v->area->next);
|
||||
|
||||
for(i=&view; *i; i=&(*i)->next)
|
||||
if(strcmp((*i)->name, name) < 0)
|
||||
if(strcmp((*i)->name, name) >= 0)
|
||||
break;
|
||||
v->next = *i;
|
||||
*i = v;
|
||||
|
||||
if(!screen->sel)
|
||||
assign_sel_view(v);
|
||||
_view_select(v);
|
||||
ewmh_updateviews();
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_view(View *v) {
|
||||
view_destroy(View *v) {
|
||||
Area *a;
|
||||
View **i, *tv;
|
||||
|
||||
while((a = v->area->next))
|
||||
destroy_area(a);
|
||||
destroy_area(v->area);
|
||||
area_destroy(a);
|
||||
area_destroy(v->area);
|
||||
|
||||
for(i=&view; *i; i=&(*i)->next)
|
||||
if(*i == v) break;
|
||||
*i = v->next;
|
||||
|
||||
write_event("DestroyTag %s\n", v->name);
|
||||
event("DestroyTag %s\n", v->name);
|
||||
|
||||
if(v == screen->sel) {
|
||||
for(tv=view; tv; tv=tv->next)
|
||||
|
@ -104,9 +93,10 @@ destroy_view(View *v) {
|
|||
if(tv == nil)
|
||||
tv = view;
|
||||
if(tv)
|
||||
focus_view(screen, tv);
|
||||
view_focus(screen, tv);
|
||||
}
|
||||
free(v);
|
||||
ewmh_updateviews();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -120,7 +110,7 @@ update_frame_selectors(View *v) {
|
|||
}
|
||||
|
||||
void
|
||||
focus_view(WMScreen *s, View *v) {
|
||||
view_focus(WMScreen *s, View *v) {
|
||||
Frame *f;
|
||||
Client *c;
|
||||
|
||||
|
@ -128,114 +118,109 @@ focus_view(WMScreen *s, View *v) {
|
|||
|
||||
XGrabServer(display);
|
||||
|
||||
assign_sel_view(v);
|
||||
_view_select(v);
|
||||
update_frame_selectors(v);
|
||||
update_divs();
|
||||
div_update_all();
|
||||
for(c=client; c; c=c->next)
|
||||
if((f = c->sel)) {
|
||||
if(f->view == v)
|
||||
resize_client(c, &f->r);
|
||||
client_resize(c, f->r);
|
||||
else {
|
||||
unmap_frame(c);
|
||||
unmap_client(c, IconicState);
|
||||
client_unmap(c, IconicState);
|
||||
}
|
||||
ewmh_updatestate(c);
|
||||
ewmh_updateclient(c);
|
||||
}
|
||||
|
||||
restack_view(v);
|
||||
focus_area(v->sel);
|
||||
draw_frames();
|
||||
view_restack(v);
|
||||
area_focus(v->sel);
|
||||
frame_draw_all();
|
||||
|
||||
XSync(display, False);
|
||||
sync();
|
||||
XUngrabServer(display);
|
||||
flushevents(EnterWindowMask, False);
|
||||
}
|
||||
|
||||
void
|
||||
select_view(const char *arg) {
|
||||
view_select(const char *arg) {
|
||||
char buf[256];
|
||||
|
||||
utflcpy(buf, arg, sizeof(buf));
|
||||
trim(buf, " \t+/");
|
||||
|
||||
if(strlen(buf) == 0)
|
||||
if(buf[0] == '\0')
|
||||
return;
|
||||
if(!strcmp(buf, ".") || !strcmp(buf, ".."))
|
||||
return;
|
||||
|
||||
assign_sel_view(get_view(buf));
|
||||
update_views(); /* performs focus_view */
|
||||
_view_select(view_create(buf));
|
||||
view_update_all(); /* performs view_focus */
|
||||
}
|
||||
|
||||
void
|
||||
attach_to_view(View *v, Frame *f) {
|
||||
view_attach(View *v, Frame *f) {
|
||||
Client *c;
|
||||
Area *a;
|
||||
|
||||
c = f->client;
|
||||
c->revert = nil;
|
||||
|
||||
a = v->sel;
|
||||
if(c->trans || c->floating || c->fixedsize
|
||||
|| c->titleless || c->borderless || c->fullscreen)
|
||||
focus_area(v->area);
|
||||
|| c->titleless || c->borderless || c->fullscreen
|
||||
|| (c->w.ewmh.type & TypeDialog))
|
||||
a = v->area;
|
||||
else if(starting && v->sel->floating)
|
||||
focus_area(v->area->next);
|
||||
attach_to_area(v->sel, f);
|
||||
a = v->area->next;
|
||||
if(!(c->w.ewmh.type & TypeSplash))
|
||||
area_focus(a);
|
||||
area_attach(a, f);
|
||||
}
|
||||
|
||||
void
|
||||
restack_view(View *v) {
|
||||
static XWindow *wins;
|
||||
static uint winssz;
|
||||
view_restack(View *v) {
|
||||
static Vector_long wins;
|
||||
Divide *d;
|
||||
Frame *f;
|
||||
Client *c;
|
||||
Area *a;
|
||||
uint n, i;
|
||||
bool fscrn;
|
||||
|
||||
if(v != screen->sel)
|
||||
return;
|
||||
|
||||
i = 0;
|
||||
for(c = client; c; c = c->next)
|
||||
i++;
|
||||
if(i == 0)
|
||||
return;
|
||||
wins.n = 0;
|
||||
fscrn = view_fullscreen_p(v);
|
||||
|
||||
for(a = v->area; a; a = a->next)
|
||||
i++;
|
||||
|
||||
if(i >= winssz) {
|
||||
winssz = 2 * i;
|
||||
wins = erealloc(wins, sizeof(Window) * winssz);
|
||||
}
|
||||
|
||||
n = 0;
|
||||
wins[n++] = screen->barwin->w;
|
||||
for(f = v->area->frame; f; f = f->anext)
|
||||
if(f->client->fullscreen) {
|
||||
n--;
|
||||
break;
|
||||
}
|
||||
if(!fscrn)
|
||||
vector_lpush(&wins, screen->barwin->w);
|
||||
|
||||
for(f=v->area->stack; f; f=f->snext)
|
||||
wins[n++] = f->client->framewin->w;
|
||||
vector_lpush(&wins, f->client->framewin->w);
|
||||
|
||||
if(fscrn)
|
||||
vector_lpush(&wins, screen->barwin->w);
|
||||
|
||||
for(d = divs; d && d->w->mapped; d = d->next)
|
||||
wins[n++] = d->w->w;
|
||||
vector_lpush(&wins, d->w->w);
|
||||
|
||||
for(a=v->area->next; a; a=a->next)
|
||||
if(a->frame) {
|
||||
wins[n++] = a->sel->client->framewin->w;
|
||||
vector_lpush(&wins, a->sel->client->framewin->w);
|
||||
for(f=a->frame; f; f=f->anext)
|
||||
if(f != a->sel)
|
||||
wins[n++] = f->client->framewin->w;
|
||||
vector_lpush(&wins, f->client->framewin->w);
|
||||
}
|
||||
if(n) {
|
||||
XRaiseWindow(display, wins[0]);
|
||||
XRestackWindows(display, wins, n);
|
||||
|
||||
ewmh_updatestacking();
|
||||
if(wins.n) {
|
||||
XRaiseWindow(display, wins.ary[0]);
|
||||
XRestackWindows(display, (ulong*)wins.ary, wins.n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
scale_view(View *v, int w) {
|
||||
view_scale(View *v, int w) {
|
||||
uint xoff, numcol;
|
||||
uint minwidth;
|
||||
Area *a;
|
||||
|
@ -285,28 +270,28 @@ scale_view(View *v, int w) {
|
|||
}
|
||||
|
||||
void
|
||||
arrange_view(View *v) {
|
||||
view_arrange(View *v) {
|
||||
uint xoff;
|
||||
Area *a;
|
||||
|
||||
if(!v->area->next)
|
||||
return;
|
||||
|
||||
scale_view(v, Dx(screen->r));
|
||||
view_scale(v, Dx(screen->r));
|
||||
xoff = 0;
|
||||
for(a=v->area->next; a; a=a->next) {
|
||||
a->r.min.x = xoff;
|
||||
a->r.min.y = 0;
|
||||
a->r.max.y = screen->brect.min.y;
|
||||
xoff = a->r.max.x;
|
||||
arrange_column(a, False);
|
||||
column_arrange(a, False);
|
||||
}
|
||||
if(v == screen->sel)
|
||||
update_divs();
|
||||
div_update_all();
|
||||
}
|
||||
|
||||
Rectangle *
|
||||
rects_of_view(View *v, uint *num, Frame *ignore) {
|
||||
Rectangle*
|
||||
view_rects(View *v, uint *num, Frame *ignore) {
|
||||
Rectangle *result;
|
||||
Frame *f;
|
||||
int i;
|
||||
|
@ -328,98 +313,88 @@ rects_of_view(View *v, uint *num, Frame *ignore) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/* XXX: This will need cleanup */
|
||||
uchar *
|
||||
char*
|
||||
view_index(View *v) {
|
||||
Rectangle *r;
|
||||
Frame *f;
|
||||
Area *a;
|
||||
char *buf, *end;
|
||||
uint i;
|
||||
int i;
|
||||
|
||||
buf = buffer;
|
||||
end = buffer+sizeof(buffer)-1;
|
||||
for((a=v->area), (i=0); a && buf < end-1; (a=a->next), i++) {
|
||||
bufclear();
|
||||
for((a=v->area), (i=0); a; (a=a->next), i++) {
|
||||
if(a->floating)
|
||||
buf = seprint(buf, end, "# ~ %d %d\n",
|
||||
Dx(a->r), Dy(a->r));
|
||||
bufprint("# ~ %d %d\n", Dx(a->r), Dy(a->r));
|
||||
else
|
||||
buf = seprint(buf, end, "# %d %d %d\n",
|
||||
i, a->r.min.x, Dx(a->r));
|
||||
bufprint("# %d %d %d\n", i, a->r.min.x, Dx(a->r));
|
||||
|
||||
for(f=a->frame; f && buf < end-1; f=f->anext) {
|
||||
for(f=a->frame; f; f=f->anext) {
|
||||
r = &f->r;
|
||||
if(a->floating)
|
||||
buf = seprint(buf, end, "~ %C %d %d %d %d %s\n",
|
||||
bufprint("~ %C %d %d %d %d %s\n",
|
||||
f->client,
|
||||
r->min.x, r->min.y,
|
||||
Dx(*r), Dy(*r),
|
||||
f->client->props);
|
||||
else
|
||||
buf = seprint(buf, end, "%d %C %d %d %s\n",
|
||||
bufprint("%d %C %d %d %s\n",
|
||||
i, f->client,
|
||||
r->min.y, Dy(*r),
|
||||
f->client->props);
|
||||
}
|
||||
}
|
||||
return (uchar*)buffer;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uchar *
|
||||
char*
|
||||
view_ctl(View *v) {
|
||||
Area *a;
|
||||
char *buf, *end;
|
||||
uint i;
|
||||
|
||||
buf = buffer;
|
||||
end = buffer+sizeof(buffer)-1;
|
||||
|
||||
buf = seprint(buf, end, "%s\n", v->name);
|
||||
bufclear();
|
||||
bufprint("%s\n", v->name);
|
||||
|
||||
/* select <area>[ <frame>] */
|
||||
buf = seprint(buf, end, "select %s", area_name(v->sel));
|
||||
bufprint("select %s", area_name(v->sel));
|
||||
if(v->sel->sel)
|
||||
buf = seprint(buf, end, " %d", frame_idx(v->sel->sel));
|
||||
buf = seprint(buf, end, "\n");
|
||||
bufprint(" %d", frame_idx(v->sel->sel));
|
||||
bufprint("\n");
|
||||
|
||||
/* select client <client> */
|
||||
if(v->sel->sel)
|
||||
buf = seprint(buf, end, "select client %C\n", v->sel->sel->client);
|
||||
bufprint("select client %C\n", v->sel->sel->client);
|
||||
|
||||
for(a = v->area->next, i = 1; a && buf < end-1; a = a->next, i++) {
|
||||
buf = seprint(buf, end, "colmode %d %s\n",
|
||||
i, colmode2str(a->mode));
|
||||
}
|
||||
return (uchar*)buffer;
|
||||
for(a = v->area->next, i = 1; a; a = a->next, i++)
|
||||
bufprint("colmode %d %s\n", i, colmode2str(a->mode));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void
|
||||
update_views(void) {
|
||||
view_update_all(void) {
|
||||
View *n, *v, *old;
|
||||
Bool found;
|
||||
int found;
|
||||
|
||||
old = screen->sel;
|
||||
for(v=view; v; v=v->next)
|
||||
update_frame_selectors(v);
|
||||
|
||||
found = False;
|
||||
found = 0;
|
||||
for(v=view; v; v=n) {
|
||||
n=v->next;
|
||||
if(v != old) {
|
||||
if(is_empty(v))
|
||||
destroy_view(v);
|
||||
if(empty_p(v))
|
||||
view_destroy(v);
|
||||
else
|
||||
found = True;
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
if(found && !strcmp(old->name, "nil") && is_empty(old))
|
||||
destroy_view(old);
|
||||
focus_view(screen, screen->sel);
|
||||
if(found && !strcmp(old->name, "nil") && empty_p(old))
|
||||
view_destroy(old);
|
||||
view_focus(screen, screen->sel);
|
||||
}
|
||||
|
||||
uint
|
||||
newcolw(View *v, int num) {
|
||||
view_newcolw(View *v, int num) {
|
||||
Rule *r;
|
||||
ulong n;
|
||||
|
||||
|
@ -438,3 +413,4 @@ newcolw(View *v, int num) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
163
cmd/wmii/x11.c
163
cmd/wmii/x11.c
|
@ -1,23 +1,34 @@
|
|||
/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#define _X11_VISIBLE
|
||||
#define ZP _ZP
|
||||
#define ZR _ZR
|
||||
#define pointerwin __pointerwin
|
||||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <bio.h>
|
||||
#include "fns.h"
|
||||
#undef ZP /* These should be allocated in read-only memory, */
|
||||
#undef ZR /* but declaring them const causes too much trouble
|
||||
* elsewhere. */
|
||||
#undef pointerwin
|
||||
|
||||
Point ZP = {0, 0};
|
||||
Rectangle ZR = {{0, 0}, {0, 0}};
|
||||
const Point ZP = {0, 0};
|
||||
const Rectangle ZR = {{0, 0}, {0, 0}};
|
||||
|
||||
const Window _pointerwin = {
|
||||
.w = PointerRoot
|
||||
};
|
||||
Window *const pointerwin = (Window*)&_pointerwin;
|
||||
|
||||
static Map wmap, amap;
|
||||
static MapEnt *wbucket[137];
|
||||
static MapEnt *abucket[137];
|
||||
|
||||
/* Rectangles/Points */
|
||||
XRectangle
|
||||
XRect(Rectangle r) {
|
||||
XRectangle xr;
|
||||
|
@ -95,6 +106,20 @@ rectsubpt(Rectangle r, Point p) {
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Formatters */
|
||||
static int
|
||||
Afmt(Fmt *f) {
|
||||
Atom a;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
a = va_arg(f->args, Atom);
|
||||
s = XGetAtomName(display, a);
|
||||
i = fmtprint(f, "%s", s);
|
||||
free(s);
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
Rfmt(Fmt *f) {
|
||||
Rectangle r;
|
||||
|
@ -143,13 +168,14 @@ initdisplay(void) {
|
|||
amap.bucket = abucket;
|
||||
amap.nhash = nelem(abucket);
|
||||
|
||||
fmtinstall('A', Afmt);
|
||||
fmtinstall('R', Rfmt);
|
||||
fmtinstall('P', Pfmt);
|
||||
fmtinstall('W', Wfmt);
|
||||
}
|
||||
|
||||
/* Images */
|
||||
Image *
|
||||
Image*
|
||||
allocimage(int w, int h, int depth) {
|
||||
Image *img;
|
||||
|
||||
|
@ -172,7 +198,7 @@ freeimage(Image *img) {
|
|||
}
|
||||
|
||||
/* Windows */
|
||||
Window *
|
||||
Window*
|
||||
createwindow(Window *parent, Rectangle r, int depth, uint class,
|
||||
WinAttr *wa, int valmask)
|
||||
{
|
||||
|
@ -197,6 +223,15 @@ createwindow(Window *parent, Rectangle r, int depth, uint class,
|
|||
return w;
|
||||
}
|
||||
|
||||
Window*
|
||||
window(XWindow w) {
|
||||
static Window win;
|
||||
|
||||
win.type = WWindow;
|
||||
win.w = w;
|
||||
return &win;
|
||||
}
|
||||
|
||||
void
|
||||
reparentwindow(Window *w, Window *par, Point p) {
|
||||
XReparentWindow(display, w->w, par->w, p.x, p.y);
|
||||
|
@ -279,9 +314,9 @@ sethandler(Window *w, Handlers *new) {
|
|||
assert((w->prev != nil && w->next != nil) || w->next == w->prev);
|
||||
|
||||
if(new == nil)
|
||||
maprm(&wmap, (ulong)w->w);
|
||||
map_rm(&wmap, (ulong)w->w);
|
||||
else {
|
||||
e = mapget(&wmap, (ulong)w->w, 1);
|
||||
e = map_get(&wmap, (ulong)w->w, 1);
|
||||
e->val = w;
|
||||
}
|
||||
old = w->handler;
|
||||
|
@ -293,7 +328,7 @@ Window*
|
|||
findwin(XWindow w) {
|
||||
MapEnt *e;
|
||||
|
||||
e = mapget(&wmap, (ulong)w, 0);
|
||||
e = map_get(&wmap, (ulong)w, 0);
|
||||
if(e)
|
||||
return e->val;
|
||||
return nil;
|
||||
|
@ -468,7 +503,7 @@ copyimage(Image *dst, Rectangle r, Image *src, Point p) {
|
|||
}
|
||||
|
||||
/* Colors */
|
||||
Bool
|
||||
bool
|
||||
namedcolor(char *name, ulong *ret) {
|
||||
XColor c, c2;
|
||||
|
||||
|
@ -479,7 +514,7 @@ namedcolor(char *name, ulong *ret) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Bool
|
||||
bool
|
||||
loadcolor(CTuple *c, char *str) {
|
||||
char buf[24];
|
||||
|
||||
|
@ -493,7 +528,7 @@ loadcolor(CTuple *c, char *str) {
|
|||
}
|
||||
|
||||
/* Fonts */
|
||||
Font *
|
||||
Font*
|
||||
loadfont(char *name) {
|
||||
Biobuf *b;
|
||||
Font *f;
|
||||
|
@ -572,17 +607,43 @@ Atom
|
|||
xatom(char *name) {
|
||||
MapEnt *e;
|
||||
|
||||
e = hashget(&amap, name, 1);
|
||||
e = hash_get(&amap, name, 1);
|
||||
if(e->val == nil)
|
||||
e->val = (void*)XInternAtom(display, name, False);
|
||||
return (Atom)e->val;
|
||||
}
|
||||
|
||||
void
|
||||
sendevent(Window *w, bool propegate, long mask, XEvent *e) {
|
||||
XSendEvent(display, w->w, propegate, mask, e);
|
||||
}
|
||||
|
||||
KeyCode
|
||||
keycode(char *name) {
|
||||
return XKeysymToKeycode(display, XStringToKeysym(name));
|
||||
}
|
||||
|
||||
void
|
||||
sync(void) {
|
||||
XSync(display, False);
|
||||
}
|
||||
|
||||
/* Properties */
|
||||
void
|
||||
delproperty(Window *w, char *prop) {
|
||||
XDeleteProperty(display, w->w, xatom(prop));
|
||||
}
|
||||
|
||||
void
|
||||
changeproperty(Window *w, char *prop, char *type, int width, uchar data[], int n) {
|
||||
XChangeProperty(display, w->w, xatom(prop), xatom(type), width, PropModeReplace, data, n);
|
||||
}
|
||||
|
||||
void
|
||||
changeprop_string(Window *w, char *prop, char *string) {
|
||||
changeprop_char(w, prop, "UTF8_STRING", string, strlen(string));
|
||||
}
|
||||
|
||||
void
|
||||
changeprop_char(Window *w, char *prop, char *type, char data[], int len) {
|
||||
changeproperty(w, prop, type, 8, (uchar*)data, len);
|
||||
|
@ -598,6 +659,25 @@ changeprop_long(Window *w, char *prop, char *type, long data[], int len) {
|
|||
changeproperty(w, prop, type, 32, (uchar*)data, len);
|
||||
}
|
||||
|
||||
void
|
||||
changeprop_textlist(Window *w, char *prop, char *type, char *data[]) {
|
||||
char **p, *s, *t;
|
||||
int len, n;
|
||||
|
||||
len = 0;
|
||||
for(p=data; *p; p++)
|
||||
len += strlen(*p) + 1;
|
||||
s = emalloc(len);
|
||||
t = s;
|
||||
for(p=data; *p; p++) {
|
||||
n = strlen(*p) + 1;
|
||||
memcpy(t, *p, n);
|
||||
t += n;
|
||||
}
|
||||
changeprop_char(w, prop, type, s, len);
|
||||
free(s);
|
||||
}
|
||||
|
||||
void
|
||||
freestringlist(char *list[]) {
|
||||
XFreeStringList(list);
|
||||
|
@ -626,6 +706,27 @@ getproperty(Window *w, char *prop, char *type, Atom *actual, ulong offset, uchar
|
|||
return n;
|
||||
}
|
||||
|
||||
char**
|
||||
strlistdup(char *list[], int n) {
|
||||
char **p, *q;
|
||||
int i, m;
|
||||
|
||||
for(i=0, m=0; i < n; i++)
|
||||
m += strlen(list[i])+1;
|
||||
|
||||
p = malloc((n+1)*sizeof(char*) + m);
|
||||
q = (char*)&p[n+1];
|
||||
|
||||
for(i=0; i < n; i++) {
|
||||
p[i] = q;
|
||||
m = strlen(list[i])+1;
|
||||
memcpy(q, list[i], m);
|
||||
q += m;
|
||||
}
|
||||
p[n] = nil;
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
gettextlistproperty(Window *w, char *name, char **ret[]) {
|
||||
XTextProperty prop;
|
||||
|
@ -644,7 +745,7 @@ gettextlistproperty(Window *w, char *name, char **ret[]) {
|
|||
return n;
|
||||
}
|
||||
|
||||
char *
|
||||
char*
|
||||
gettextproperty(Window *w, char *name) {
|
||||
char **list, *str;
|
||||
int n;
|
||||
|
@ -667,15 +768,25 @@ setfocus(Window *w, int mode) {
|
|||
/* Mouse */
|
||||
Point
|
||||
querypointer(Window *w) {
|
||||
XWindow dummy;
|
||||
XWindow win;
|
||||
Point pt;
|
||||
uint ui;
|
||||
int i;
|
||||
|
||||
XQueryPointer(display, w->w, &dummy, &dummy, &i, &i, &pt.x, &pt.y, &ui);
|
||||
XQueryPointer(display, w->w, &win, &win, &i, &i, &pt.x, &pt.y, &ui);
|
||||
return pt;
|
||||
}
|
||||
|
||||
int
|
||||
pointerscreen(void) {
|
||||
XWindow win;
|
||||
Point pt;
|
||||
uint ui;
|
||||
int i;
|
||||
|
||||
return XQueryPointer(display, scr.root.w, &win, &win, &i, &i, &pt.x, &pt.y, &ui);
|
||||
}
|
||||
|
||||
void
|
||||
warppointer(Point pt) {
|
||||
XWarpPointer(display,
|
||||
|
@ -771,18 +882,26 @@ sethints(Window *w) {
|
|||
xs.win_gravity = NorthWestGravity;
|
||||
|
||||
switch (xs.win_gravity) {
|
||||
case EastGravity: case CenterGravity: case WestGravity:
|
||||
case EastGravity:
|
||||
case CenterGravity:
|
||||
case WestGravity:
|
||||
p.y = 1;
|
||||
break;
|
||||
case SouthEastGravity: case SouthGravity: case SouthWestGravity:
|
||||
case SouthEastGravity:
|
||||
case SouthGravity:
|
||||
case SouthWestGravity:
|
||||
p.y = 2;
|
||||
break;
|
||||
}
|
||||
switch (xs.win_gravity) {
|
||||
case NorthGravity: case CenterGravity: case SouthGravity:
|
||||
case NorthGravity:
|
||||
case CenterGravity:
|
||||
case SouthGravity:
|
||||
p.x = 1;
|
||||
break;
|
||||
case NorthEastGravity: case EastGravity: case SouthEastGravity:
|
||||
case NorthEastGravity:
|
||||
case EastGravity:
|
||||
case SouthEastGravity:
|
||||
p.x = 2;
|
||||
break;
|
||||
}
|
||||
|
@ -820,7 +939,7 @@ sizehint(WinHints *h, Rectangle r) {
|
|||
p2 = h->aspect.max;
|
||||
if(p.x * p2.y / p.y > p2.x)
|
||||
r.max.x = h->baspect.x + p.y * p2.x / p2.y;
|
||||
|
||||
|
||||
return rectaddpt(r, o);
|
||||
}
|
||||
|
||||
|
|
119
cmd/wmii/x11.h
119
cmd/wmii/x11.h
|
@ -1,119 +0,0 @@
|
|||
#define Window XWindow
|
||||
#define Font XFont
|
||||
#define Screen XScreen
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#undef Window
|
||||
#undef Font
|
||||
#undef Screen
|
||||
|
||||
typedef struct Point Point;
|
||||
typedef struct Rectangle Rectangle;
|
||||
typedef struct Screen Screen;
|
||||
typedef struct Window Window;
|
||||
typedef struct WinHints WinHints;
|
||||
typedef struct Handlers Handlers;
|
||||
typedef struct Window Image;
|
||||
typedef struct Font Font;
|
||||
typedef XSetWindowAttributes WinAttr;
|
||||
|
||||
struct Point {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct Rectangle {
|
||||
Point min, max;
|
||||
};
|
||||
|
||||
struct Window {
|
||||
int type;
|
||||
XWindow w;
|
||||
Window *parent;
|
||||
Drawable image;
|
||||
GC gc;
|
||||
Rectangle r;
|
||||
void *aux;
|
||||
Handlers *handler;
|
||||
Window *next, *prev;
|
||||
WinHints *hints;
|
||||
Bool mapped;
|
||||
int unmapped;
|
||||
int depth;
|
||||
};
|
||||
|
||||
struct WinHints {
|
||||
Point min, max;
|
||||
Point base, baspect;
|
||||
Point inc;
|
||||
Rectangle aspect;
|
||||
Point grav;
|
||||
Bool gravstatic;
|
||||
Bool position;
|
||||
};
|
||||
|
||||
struct Handlers {
|
||||
void (*bdown)(Window*, XButtonEvent*);
|
||||
void (*bup)(Window*, XButtonEvent*);
|
||||
void (*kdown)(Window*, XKeyEvent*);
|
||||
void (*kup)(Window*, XKeyEvent*);
|
||||
void (*focusin)(Window*, XFocusChangeEvent*);
|
||||
void (*focusout)(Window*, XFocusChangeEvent*);
|
||||
void (*enter)(Window*, XCrossingEvent*);
|
||||
void (*leave)(Window*, XCrossingEvent*);
|
||||
void (*motion)(Window*, XMotionEvent*);
|
||||
void (*destroy)(Window*, XDestroyWindowEvent*);
|
||||
void (*configreq)(Window*, XConfigureRequestEvent*);
|
||||
void (*map)(Window*, XMapEvent*);
|
||||
void (*unmap)(Window*, XUnmapEvent*);
|
||||
void (*property)(Window*, XPropertyEvent*);
|
||||
void (*expose)(Window*, XExposeEvent*);
|
||||
};
|
||||
|
||||
struct Screen {
|
||||
int screen;
|
||||
Window root;
|
||||
Colormap colormap;
|
||||
Visual *visual;
|
||||
Rectangle rect;
|
||||
GC gc;
|
||||
int depth;
|
||||
int fd;
|
||||
ulong black, white;
|
||||
};
|
||||
|
||||
enum { WWindow, WImage };
|
||||
|
||||
struct Font {
|
||||
XFontStruct *xfont;
|
||||
XFontSet set;
|
||||
int ascent;
|
||||
int descent;
|
||||
uint height;
|
||||
char *name;
|
||||
};
|
||||
|
||||
Display *display;
|
||||
Screen scr;
|
||||
|
||||
extern Point ZP;
|
||||
extern Rectangle ZR;
|
||||
|
||||
Rectangle insetrect(Rectangle r, int n);
|
||||
|
||||
Point Pt(int x, int y);
|
||||
Rectangle Rect(int x0, int y0, int x1, int y1);
|
||||
Rectangle Rpt(Point min, Point max);
|
||||
|
||||
XRectangle XRect(Rectangle r);
|
||||
|
||||
#define Dx(r) ((r).max.x - (r).min.x)
|
||||
#define Dy(r) ((r).max.y - (r).min.y)
|
||||
#define Pt(x, y) ((Point){(x), (y)})
|
||||
#define Rpt(p, q) ((Rectangle){p, q})
|
||||
#define Rect(x0, y0, x1, y1) ((Rectangle){Pt(x0, y0), Pt(x1, y1)})
|
||||
#define changeprop(w, prop, type, data, n) \
|
||||
changeproperty(w, prop, type, \
|
||||
((sizeof(*(data)) == 8 ? 4 : sizeof(*(data))) * 8), \
|
||||
(uchar*)(data), n)
|
|
@ -9,10 +9,14 @@ for i in "$PLAN9" `echo P9PATHS`; do
|
|||
fi
|
||||
done
|
||||
|
||||
if [ ! -n "$RC" ]; then
|
||||
if [ -n "$RC" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -x "$PLAN9/bin/read" ]; then
|
||||
echo 1>&2 $0: Found rc, but not read'(1)'. You probably have an out-of-date 9base installed.
|
||||
fi
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
exec "$RC" "$@"
|
||||
else
|
||||
|
|
44
cmd/wmiir.c
44
cmd/wmiir.c
|
@ -17,9 +17,9 @@ static IxpClient *client;
|
|||
static void
|
||||
usage(void) {
|
||||
fprint(1,
|
||||
"usage: %1$s [-a <address>] {create | read | ls [-ld] | remove | rm | write} <file>\n"
|
||||
" %1$s [-a <address>] xwrite <file> <data>\n"
|
||||
" %1$s -v\n", argv0);
|
||||
"usage: %s [-a <address>] {create | read | ls [-ld] | remove | rm | write} <file>\n"
|
||||
" %s [-a <address>] xwrite <file> <data>\n"
|
||||
" %s -v\n", argv0, argv0, argv0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -185,6 +185,7 @@ xcreate(int argc, char *argv[]) {
|
|||
static int
|
||||
xremove(int argc, char *argv[]) {
|
||||
char *file;
|
||||
int n;
|
||||
|
||||
ARGBEGIN{
|
||||
default:
|
||||
|
@ -192,8 +193,12 @@ xremove(int argc, char *argv[]) {
|
|||
}ARGEND;
|
||||
|
||||
file = EARGF(usage());
|
||||
if(ixp_remove(client, file) == 0)
|
||||
fatal("Can't remove file '%s': %r\n", file);
|
||||
do {
|
||||
if(ixp_remove(client, file) == 0) {
|
||||
fprint(2, "%s: Can't remove file '%s': %r\n", argv0, file);
|
||||
n++;
|
||||
}
|
||||
}while((file = ARGF()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -208,18 +213,22 @@ xread(int argc, char *argv[]) {
|
|||
usage();
|
||||
}ARGEND;
|
||||
|
||||
if(argc == 0)
|
||||
usage();
|
||||
file = EARGF(usage());
|
||||
fid = ixp_open(client, file, P9_OREAD);
|
||||
if(fid == nil)
|
||||
fatal("Can't open file '%s': %r\n", file);
|
||||
do {
|
||||
fid = ixp_open(client, file, P9_OREAD);
|
||||
if(fid == nil)
|
||||
fatal("Can't open file '%s': %r\n", file);
|
||||
|
||||
buf = emalloc(fid->iounit);
|
||||
while((count = ixp_read(fid, buf, fid->iounit)) > 0)
|
||||
write(1, buf, count);
|
||||
ixp_close(fid);
|
||||
buf = emalloc(fid->iounit);
|
||||
while((count = ixp_read(fid, buf, fid->iounit)) > 0)
|
||||
write(1, buf, count);
|
||||
ixp_close(fid);
|
||||
|
||||
if(count == -1)
|
||||
fatal("cannot read file/directory '%s': %r\n", file);
|
||||
if(count == -1)
|
||||
fprint(2, "%s: cannot read file/directory '%s': %r\n", argv0, file);
|
||||
}while((file = ARGF()));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -299,6 +308,7 @@ struct exectab {
|
|||
{"write", xwrite},
|
||||
{"xwrite", xawrite},
|
||||
{"read", xread},
|
||||
{"cat", xread},
|
||||
{"create", xcreate},
|
||||
{"remove", xremove},
|
||||
{"rm", xremove},
|
||||
|
@ -308,7 +318,7 @@ struct exectab {
|
|||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
char *cmd, *address;
|
||||
char *address;
|
||||
exectab *tab;
|
||||
int ret;
|
||||
|
||||
|
@ -327,8 +337,6 @@ main(int argc, char *argv[]) {
|
|||
usage();
|
||||
}ARGEND;
|
||||
|
||||
cmd = EARGF(usage());
|
||||
|
||||
if(!address)
|
||||
fatal("$WMII_ADDRESS not set\n");
|
||||
|
||||
|
@ -337,7 +345,7 @@ main(int argc, char *argv[]) {
|
|||
fatal("can't mount: %r\n");
|
||||
|
||||
for(tab = etab; tab->cmd; tab++)
|
||||
if(strcmp(cmd, tab->cmd) == 0) break;
|
||||
if(strcmp(*argv, tab->cmd) == 0) break;
|
||||
if(tab->cmd == 0)
|
||||
usage();
|
||||
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
#!/bin/sh -f
|
||||
# start wmiirc
|
||||
|
||||
export WMII_CONFPATH="$HOME/.wmii-CONFVERSION:CONFPREFIX/wmii-CONFVERSION"
|
||||
export home="$HOME"
|
||||
lconf="$home/.wmii-CONFVERSION"
|
||||
gconf="CONFPREFIX/.wmii-CONFVERSION"
|
||||
|
||||
export WMII_CONFPATH="$conf:$gconf"
|
||||
export POSIXLY_CORRECT=gnu_hippies
|
||||
|
||||
if wmii9rc; then
|
||||
WMIIRC=`PATH="$WMII_CONFPATH:$PATH" which rc.wmii`
|
||||
|
@ -9,5 +14,6 @@ else
|
|||
WMIIRC=`PATH="$WMII_CONFPATH:$PATH" which wmiirc`
|
||||
fi
|
||||
|
||||
mkdir $HOME/.wmii-CONFVERSION 2>/dev/null && CONFPREFIX/wmii-CONFVERSION/welcome &
|
||||
exec "$WMIIRC" $@
|
||||
mkdir $conf 2>/dev/null && $gconf/welcome &
|
||||
exec "$WMIIRC" "$@"
|
||||
|
||||
|
|
|
@ -9,9 +9,10 @@ iconscale = `{*=$epsbox; hoc -e $iconwidth/'('$3-' '$1')'}
|
|||
iconheight = `{*=$epsbox; hoc -e '('$4-' '$2')*'$iconscale}
|
||||
|
||||
icon.png: $eps
|
||||
x = `{hoc -e -'('$epsbox(1)^')'}
|
||||
y = `{hoc -e -'('$epsbox(2)^')'}
|
||||
gs -q -dBATCH -dNOPAUSE -sDEVICE=pngalpha -sOutputFile=$target -g^$iconwidth^x^$iconheight - <<!
|
||||
* = `{hoc -e'-('$epsbox')'}
|
||||
x = $1
|
||||
y = $2
|
||||
gs -q -dBATCH -dNOPAUSE -sDEVICE=pngalpha -sOutputFile=$target -g$iconwidth'x'$iconheight - <<!
|
||||
$iconscale $iconscale scale
|
||||
$x $y translate
|
||||
($eps) run
|
||||
|
|
|
@ -108,41 +108,41 @@ extern int (*fmtdoquote)(int);
|
|||
#endif
|
||||
|
||||
/* Edit .+1,/^$/ | cfn $PLAN9/src/lib9/fmt/?*.c | grep -v static |grep -v __ */
|
||||
int dofmt(Fmt *f, const char *fmt);
|
||||
int dorfmt(Fmt *f, const Rune *fmt);
|
||||
double fmtcharstod(int(*f)(void*), void *vp);
|
||||
int fmtfdflush(Fmt *f);
|
||||
int fmtfdinit(Fmt *f, int fd, char *buf, int size);
|
||||
int fmtinstall(int c, int (*f)(Fmt*));
|
||||
int fmtprint(Fmt *f, const char *fmt, ...);
|
||||
int fmtrune(Fmt *f, int r);
|
||||
int fmtrunestrcpy(Fmt *f, Rune *s);
|
||||
int fmtstrcpy(Fmt *f, const char *s);
|
||||
char* fmtstrflush(Fmt *f);
|
||||
int fmtstrinit(Fmt *f);
|
||||
double fmtstrtod(const char *as, char **aas);
|
||||
int fmtvprint(Fmt *f, const char *fmt, va_list args);
|
||||
int fprint(int fd, const char *fmt, ...);
|
||||
int print(const char *fmt, ...);
|
||||
int dofmt(Fmt*, const char *fmt);
|
||||
int dorfmt(Fmt*, const Rune *fmt);
|
||||
double fmtcharstod(int(*f)(void*), void*);
|
||||
int fmtfdflush(Fmt*);
|
||||
int fmtfdinit(Fmt*, int fd, char *buf, int size);
|
||||
int fmtinstall(int, int (*f)(Fmt*));
|
||||
int fmtprint(Fmt*, const char*, ...);
|
||||
int fmtrune(Fmt*, int);
|
||||
int fmtrunestrcpy(Fmt*, Rune*);
|
||||
int fmtstrcpy(Fmt*, const char*);
|
||||
char* fmtstrflush(Fmt*);
|
||||
int fmtstrinit(Fmt*);
|
||||
double fmtstrtod(const char*, char**);
|
||||
int fmtvprint(Fmt*, const char*, va_list);
|
||||
int fprint(int, const char*, ...);
|
||||
int print(const char*, ...);
|
||||
void quotefmtinstall(void);
|
||||
int quoterunestrfmt(Fmt *f);
|
||||
int quotestrfmt(Fmt *f);
|
||||
Rune* runefmtstrflush(Fmt *f);
|
||||
int runefmtstrinit(Fmt *f);
|
||||
Rune* runeseprint(Rune *buf, Rune *e, const char *fmt, ...);
|
||||
Rune* runesmprint(const char *fmt, ...);
|
||||
int runesnprint(Rune *buf, int len, const char *fmt, ...);
|
||||
int runesprint(Rune *buf, const char *fmt, ...);
|
||||
Rune* runevseprint(Rune *buf, Rune *e, const char *fmt, va_list args);
|
||||
Rune* runevsmprint(const char *fmt, va_list args);
|
||||
int runevsnprint(Rune *buf, int len, const char *fmt, va_list args);
|
||||
char* seprint(char *buf, char *e, const char *fmt, ...);
|
||||
char* smprint(const char *fmt, ...);
|
||||
int snprint(char *buf, int len, const char *fmt, ...);
|
||||
int sprint(char *buf, const char *fmt, ...);
|
||||
int vfprint(int fd, const char *fmt, va_list args);
|
||||
char* vseprint(char *buf, char *e, const char *fmt, va_list args);
|
||||
char* vsmprint(const char *fmt, va_list args);
|
||||
int vsnprint(char *buf, int len, const char *fmt, va_list args);
|
||||
int quoterunestrfmt(Fmt*);
|
||||
int quotestrfmt(Fmt*);
|
||||
Rune* runefmtstrflush(Fmt*);
|
||||
int runefmtstrinit(Fmt*);
|
||||
Rune* runeseprint(Rune*,Rune*, const char*, ...);
|
||||
Rune* runesmprint(const char*, ...);
|
||||
int runesnprint(Rune*, int, const char*, ...);
|
||||
int runesprint(Rune*, const char*, ...);
|
||||
Rune* runevseprint(Rune*, Rune *, const char*, va_list);
|
||||
Rune* runevsmprint(const char*, va_list);
|
||||
int runevsnprint(Rune*, int, const char*, va_list);
|
||||
char* seprint(char*, char*, const char*, ...);
|
||||
char* smprint(const char*, ...);
|
||||
int snprint(char*, int, const char *, ...);
|
||||
int sprint(char*, const char*, ...);
|
||||
int vfprint(int, const char*, va_list);
|
||||
char* vseprint(char*, char*, const char*, va_list);
|
||||
char* vsmprint(const char*, va_list);
|
||||
int vsnprint(char*, int, const char*, va_list);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,11 +9,12 @@
|
|||
# ifndef USED
|
||||
# define USED(x) if(x);else
|
||||
# endif
|
||||
# define uchar _p9uchar
|
||||
# define ushort _p9ushort
|
||||
# define uint _p9uint
|
||||
# define ulong _p9ulong
|
||||
#endif
|
||||
|
||||
#define uchar _p9uchar
|
||||
#define ushort _p9ushort
|
||||
#define uint _p9uint
|
||||
#define ulong _p9ulong
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
|
|
|
@ -16,13 +16,11 @@ typedef struct Reprog Reprog;
|
|||
* Sub expression matches
|
||||
*/
|
||||
struct Resub{
|
||||
union
|
||||
{
|
||||
union {
|
||||
char *sp;
|
||||
Rune *rsp;
|
||||
}s;
|
||||
union
|
||||
{
|
||||
union {
|
||||
char *ep;
|
||||
Rune *rep;
|
||||
}e;
|
||||
|
|
|
@ -14,34 +14,34 @@ enum
|
|||
/* Edit .+1,/^$/ | cfn $PLAN9/src/lib9/utf/?*.c | grep -v static |grep -v __ */
|
||||
int chartorune(Rune *rune, const char *str);
|
||||
int fullrune(const char *str, int n);
|
||||
int isalpharune(Rune c);
|
||||
int islowerrune(Rune c);
|
||||
int isspacerune(Rune c);
|
||||
int istitlerune(Rune c);
|
||||
int isupperrune(Rune c);
|
||||
int runelen(long c);
|
||||
int runenlen(Rune *r, int nrune);
|
||||
Rune* runestrcat(Rune *s1, Rune *s2);
|
||||
Rune* runestrchr(Rune *s, Rune c);
|
||||
int runestrcmp(Rune *s1, Rune *s2);
|
||||
Rune* runestrcpy(Rune *s1, Rune *s2);
|
||||
Rune* runestrdup(Rune *s) ;
|
||||
Rune* runestrecpy(Rune *s1, Rune *es1, Rune *s2);
|
||||
long runestrlen(Rune *s);
|
||||
Rune* runestrncat(Rune *s1, Rune *s2, long n);
|
||||
int runestrncmp(Rune *s1, Rune *s2, long n);
|
||||
Rune* runestrncpy(Rune *s1, Rune *s2, long n);
|
||||
Rune* runestrrchr(Rune *s, Rune c);
|
||||
Rune* runestrstr(Rune *s1, Rune *s2);
|
||||
int runetochar(char *str, Rune *rune);
|
||||
Rune tolowerrune(Rune c);
|
||||
Rune totitlerune(Rune c);
|
||||
Rune toupperrune(Rune c);
|
||||
char* utfecpy(char *to, char *e, const char *from);
|
||||
int utflen(const char *s);
|
||||
int utfnlen(const char *s, long m);
|
||||
char* utfrrune(const char *s, long c);
|
||||
char* utfrune(const char *s, long c);
|
||||
char* utfutf(const char *s1, const char *s2);
|
||||
int isalpharune(Rune);
|
||||
int islowerrune(Rune);
|
||||
int isspacerune(Rune);
|
||||
int istitlerune(Rune);
|
||||
int isupperrune(Rune);
|
||||
int runelen(Rune);
|
||||
int runenlen(const Rune*, int);
|
||||
Rune* runestrcat(Rune*, const Rune*);
|
||||
Rune* runestrchr(const Rune*, Rune);
|
||||
int runestrcmp(const Rune*, const Rune*);
|
||||
Rune* runestrcpy(Rune*, const Rune*);
|
||||
Rune* runestrdup(const Rune*) ;
|
||||
Rune* runestrecpy(Rune*, Rune *e, const Rune*);
|
||||
long runestrlen(const Rune*);
|
||||
Rune* runestrncat(Rune*, const Rune*, long);
|
||||
int runestrncmp(const Rune*, const Rune*, long);
|
||||
Rune* runestrncpy(Rune*, const Rune*, long);
|
||||
Rune* runestrrchr(const Rune*, Rune);
|
||||
Rune* runestrstr(const Rune*, const Rune*);
|
||||
int runetochar(char*, const Rune*);
|
||||
Rune tolowerrune(Rune);
|
||||
Rune totitlerune(Rune);
|
||||
Rune toupperrune(Rune);
|
||||
char* utfecpy(char*, char*, const char*);
|
||||
int utflen(const char*);
|
||||
int utfnlen(const char*, long);
|
||||
char* utfrrune(const char*, long);
|
||||
char* utfrune(const char*, long);
|
||||
char* utfutf(const char*, const char*);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,63 +8,69 @@
|
|||
#undef ulong
|
||||
#undef uvlong
|
||||
#undef vlong
|
||||
#ifndef KENC
|
||||
# define uchar _wmiiuchar
|
||||
# define ushort _wmiiushort
|
||||
# define uint _wmiiuint
|
||||
# define ulong _wmiiulong
|
||||
# define vlong _wmiivlong
|
||||
# define uvlong _wmiiuvlong
|
||||
#endif
|
||||
#define uchar _x_uchar
|
||||
#define ushort _x_ushort
|
||||
#define uint _x_uint
|
||||
#define ulong _x_ulong
|
||||
#define uvlong _x_uvlong
|
||||
#define vlong _x_vlong
|
||||
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned long long uvlong;
|
||||
typedef long long vlong;
|
||||
|
||||
typedef long long vlong;
|
||||
|
||||
#define strlcat wmii_strlcat
|
||||
/* util.c */
|
||||
uint tokenize(char *res[], uint reslen, char *str, char delim);
|
||||
char *estrdup(const char *str);
|
||||
void *erealloc(void *ptr, uint size);
|
||||
void *emallocz(uint size);
|
||||
void *emalloc(uint size);
|
||||
void fatal(const char *fmt, ...);
|
||||
int max(int a, int b);
|
||||
int min(int a, int b);
|
||||
char *str_nil(char *s);
|
||||
int utflcpy(char *to, const char *from, int l);
|
||||
uint strlcat(char *dst, const char *src, unsigned int siz);
|
||||
void _die(char*, int, char*);
|
||||
void* emalloc(uint);
|
||||
void* emallocz(uint);
|
||||
void* erealloc(void*, uint);
|
||||
char* estrdup(const char*);
|
||||
void fatal(const char*, ...);
|
||||
int max(int, int);
|
||||
int min(int, int);
|
||||
char* str_nil(char*);
|
||||
uint strlcat(char*, const char*, uint);
|
||||
uint tokenize(char **, uint, char*, char);
|
||||
int utflcpy(char*, const char*, int);
|
||||
|
||||
#define die(x) \
|
||||
_die(__FILE__, __LINE__, x)
|
||||
|
||||
char *argv0;
|
||||
void *__p;
|
||||
int __i;
|
||||
#undef ARGBEGIN
|
||||
#undef ARGEND
|
||||
#undef ARGF
|
||||
#undef EARGF
|
||||
#define ARGBEGIN \
|
||||
int _argi=0, _argtmp=0, _inargv=0; char *_argv=nil; \
|
||||
if(!argv0) argv0=ARGF(); \
|
||||
int _argtmp=0, _inargv=0; char *_argv=nil; \
|
||||
if(!argv0) argv0=*argv; argv++, argc--; \
|
||||
_inargv=1; USED(_inargv); \
|
||||
while(argc && argv[0][0] == '-') { \
|
||||
_argi=1; _argv=*argv++; argc--; \
|
||||
while(_argv[_argi]) switch(_argv[_argi++])
|
||||
#define ARGEND }_inargv=0;USED(_argtmp);USED(_argv);USED(_argi);USED(_inargv)
|
||||
_argv=&argv[0][1]; argv++; argc--; \
|
||||
if(_argv[0] == '-' && _argv[1] == '\0') \
|
||||
break; \
|
||||
while(*_argv) switch(*_argv++)
|
||||
#define ARGEND }_inargv=0;USED(_argtmp, _argv, _inargv)
|
||||
|
||||
#define ARGF() ((_inargv && _argv[_argi]) ? \
|
||||
(_argtmp=_argi, _argi=strlen(_argv), __i=_argi,_argv+_argtmp) \
|
||||
: ((argc > 0) ? (--argc, ++argv, __i=argc, __p=argv, *(argv-1)) : ((char*)0)))
|
||||
|
||||
#define EARGF(f) ((_inargv && _argv[_argi]) ? \
|
||||
(_argtmp=_argi, _argi=strlen(_argv), __i=_argi, _argv+_argtmp) \
|
||||
: ((argc > 0) ? (--argc, ++argv, __i=argc, __p=argv, *(argv-1)) : ((f), (char*)0)))
|
||||
#define EARGF(f) ((_inargv && *_argv) ? \
|
||||
(_argtmp=strlen(_argv), _argv+=_argtmp, _argv-_argtmp) \
|
||||
: ((argc > 0) ? \
|
||||
(--argc, ++argv, _used(argc), *(argv-1)) \
|
||||
: ((f), (char*)0)))
|
||||
#define ARGF() EARGF(_used(0))
|
||||
|
||||
static inline void
|
||||
_used(long a, ...) {
|
||||
if(a){}
|
||||
}
|
||||
#ifndef KENC
|
||||
# undef USED
|
||||
# undef SET
|
||||
# define USED(x) if(x){}else
|
||||
# define SET(x) ((x)=0)
|
||||
# undef USED
|
||||
# undef SET
|
||||
# define USED(...) _used((long)__VA_ARGS__)
|
||||
# define SET(x) USED(&x)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
#define Window XWindow
|
||||
#define Font XFont
|
||||
#define Screen XScreen
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#ifdef _X11_VISIBLE
|
||||
# include <X11/Xatom.h>
|
||||
# include <X11/extensions/shape.h>
|
||||
#endif
|
||||
#undef Window
|
||||
#undef Font
|
||||
#undef Screen
|
||||
|
||||
enum Align {
|
||||
NORTH = 0x01,
|
||||
EAST = 0x02,
|
||||
SOUTH = 0x04,
|
||||
WEST = 0x08,
|
||||
NEAST = NORTH | EAST,
|
||||
NWEST = NORTH | WEST,
|
||||
SEAST = SOUTH | EAST,
|
||||
SWEST = SOUTH | WEST,
|
||||
CENTER = NEAST | SWEST,
|
||||
};
|
||||
|
||||
typedef enum Align Align;
|
||||
|
||||
typedef struct CTuple CTuple;
|
||||
typedef struct Point Point;
|
||||
typedef struct Rectangle Rectangle;
|
||||
typedef struct Screen Screen;
|
||||
typedef struct Ewmh Ewmh;
|
||||
typedef struct Window Window;
|
||||
typedef struct WinHints WinHints;
|
||||
typedef struct Handlers Handlers;
|
||||
typedef struct Window Image;
|
||||
typedef struct Font Font;
|
||||
typedef XSetWindowAttributes WinAttr;
|
||||
|
||||
struct CTuple {
|
||||
ulong bg;
|
||||
ulong fg;
|
||||
ulong border;
|
||||
char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
|
||||
};
|
||||
|
||||
struct Point {
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct Rectangle {
|
||||
Point min, max;
|
||||
};
|
||||
|
||||
struct Ewmh {
|
||||
long type;
|
||||
};
|
||||
|
||||
struct Window {
|
||||
int type;
|
||||
XWindow w;
|
||||
Window *parent;
|
||||
Drawable image;
|
||||
GC gc;
|
||||
Rectangle r;
|
||||
void *aux;
|
||||
Handlers *handler;
|
||||
Window *next, *prev;
|
||||
WinHints *hints;
|
||||
Ewmh ewmh;
|
||||
bool mapped;
|
||||
int unmapped;
|
||||
int depth;
|
||||
};
|
||||
|
||||
struct WinHints {
|
||||
Point min, max;
|
||||
Point base, baspect;
|
||||
Point inc;
|
||||
Rectangle aspect;
|
||||
Point grav;
|
||||
bool gravstatic;
|
||||
bool position;
|
||||
};
|
||||
|
||||
struct Handlers {
|
||||
void (*bdown)(Window*, XButtonEvent*);
|
||||
void (*bup)(Window*, XButtonEvent*);
|
||||
void (*kdown)(Window*, XKeyEvent*);
|
||||
void (*kup)(Window*, XKeyEvent*);
|
||||
void (*focusin)(Window*, XFocusChangeEvent*);
|
||||
void (*focusout)(Window*, XFocusChangeEvent*);
|
||||
void (*enter)(Window*, XCrossingEvent*);
|
||||
void (*leave)(Window*, XCrossingEvent*);
|
||||
void (*motion)(Window*, XMotionEvent*);
|
||||
void (*destroy)(Window*, XDestroyWindowEvent*);
|
||||
void (*configreq)(Window*, XConfigureRequestEvent*);
|
||||
void (*map)(Window*, XMapEvent*);
|
||||
void (*unmap)(Window*, XUnmapEvent*);
|
||||
void (*property)(Window*, XPropertyEvent*);
|
||||
void (*expose)(Window*, XExposeEvent*);
|
||||
};
|
||||
|
||||
struct Screen {
|
||||
int screen;
|
||||
Window root;
|
||||
Colormap colormap;
|
||||
Visual *visual;
|
||||
Rectangle rect;
|
||||
GC gc;
|
||||
int depth;
|
||||
int fd;
|
||||
ulong black, white;
|
||||
};
|
||||
|
||||
enum { WWindow, WImage };
|
||||
|
||||
struct Font {
|
||||
XFontStruct *xfont;
|
||||
XFontSet set;
|
||||
int ascent;
|
||||
int descent;
|
||||
uint height;
|
||||
char *name;
|
||||
};
|
||||
|
||||
#ifdef VARARGCK
|
||||
# pragma varargck type "A" Atom
|
||||
# pragma varargck type "W" Window*
|
||||
# pragma varargck type "P" Point
|
||||
# pragma varargck type "R" Rectangle
|
||||
#endif
|
||||
|
||||
Display *display;
|
||||
Screen scr;
|
||||
|
||||
extern Point ZP;
|
||||
extern Rectangle ZR;
|
||||
extern Window* pointerwin;
|
||||
|
||||
Rectangle insetrect(Rectangle r, int n);
|
||||
|
||||
Point Pt(int x, int y);
|
||||
Rectangle Rect(int x0, int y0, int x1, int y1);
|
||||
Rectangle Rpt(Point min, Point max);
|
||||
|
||||
XRectangle XRect(Rectangle r);
|
||||
|
||||
#define Dx(r) ((r).max.x - (r).min.x)
|
||||
#define Dy(r) ((r).max.y - (r).min.y)
|
||||
#define Pt(x, y) ((Point){(x), (y)})
|
||||
#define Rpt(p, q) ((Rectangle){p, q})
|
||||
#define Rect(x0, y0, x1, y1) ((Rectangle){Pt(x0, y0), Pt(x1, y1)})
|
||||
#define changeprop(w, prop, type, data, n) \
|
||||
changeproperty(w, prop, type, \
|
||||
((sizeof(*(data)) == 8 ? 4 : sizeof(*(data))) * 8), \
|
||||
(uchar*)(data), n)
|
||||
|
||||
/* x11.c */
|
||||
Window *createwindow(Window *parent, Rectangle, int depth, uint class, WinAttr*, int valuemask);
|
||||
char *gettextproperty(Window*, char*);
|
||||
Point addpt(Point, Point);
|
||||
Image* allocimage(int w, int h, int depth);
|
||||
void border(Image *dst, Rectangle, int w, ulong col);
|
||||
void changeprop_char(Window*, char*, char*, char[], int);
|
||||
void changeprop_long(Window*, char*, char*, long[], int);
|
||||
void changeprop_short(Window*, char*, char*, short[], int);
|
||||
void changeprop_string(Window*, char*, char*);
|
||||
void changeprop_textlist(Window*, char*, char*, char*[]);
|
||||
void changeproperty(Window*, char*, char*, int width, uchar*, int);
|
||||
void copyimage(Image*, Rectangle, Image*, Point);
|
||||
void delproperty(Window*, char*);
|
||||
void destroywindow(Window*);
|
||||
Point divpt(Point, Point);
|
||||
void drawline(Image*, Point, Point, int cap, int w, ulong col);
|
||||
void drawpoly(Image*, Point*, int, int cap, int w, ulong col);
|
||||
void drawstring(Image*, Font*, Rectangle, Align, char*, ulong col);
|
||||
int eqpt(Point, Point);
|
||||
int eqrect(Rectangle, Rectangle);
|
||||
void fill(Image*, Rectangle, ulong col);
|
||||
void fillpoly(Image*, Point*, int, ulong col);
|
||||
Window* findwin(XWindow);
|
||||
void freefont(Font*);
|
||||
void freeimage(Image *);
|
||||
void freestringlist(char**);
|
||||
ulong getproperty(Window*, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length);
|
||||
int gettextlistproperty(Window *w, char *name, char **ret[]);
|
||||
int grabpointer(Window*, Window *confine, Cursor, int mask);
|
||||
void initdisplay(void);
|
||||
KeyCode keycode(char*);
|
||||
uint labelh(Font*);
|
||||
bool loadcolor(CTuple*, char*);
|
||||
Font* loadfont(char*);
|
||||
void lowerwin(Window*);
|
||||
int mapwin(Window*);
|
||||
void movewin(Window*, Point);
|
||||
Point mulpt(Point p, Point q);
|
||||
bool namedcolor(char *name, ulong*);
|
||||
int pointerscreen(void);
|
||||
Point querypointer(Window*);
|
||||
void raisewin(Window*);
|
||||
void reparentwindow(Window*, Window*, Point);
|
||||
void reshapewin(Window*, Rectangle);
|
||||
void sendevent(Window*, bool propegate, long mask, XEvent*);
|
||||
void setfocus(Window*, int mode);
|
||||
void sethints(Window*);
|
||||
void setshapemask(Window *dst, Image *src, Point);
|
||||
void setwinattr(Window*, WinAttr*, int valmask);
|
||||
Point subpt(Point, Point);
|
||||
char** strlistdup(char**, int);
|
||||
void sync(void);
|
||||
uint textwidth(Font*, char*);
|
||||
uint textwidth_l(Font*, char*, uint len);
|
||||
Point translate(Window*, Window*, Point);
|
||||
void ungrabpointer(void);
|
||||
int unmapwin(Window*);
|
||||
void warppointer(Point);
|
||||
Window* window(XWindow);
|
||||
uint winprotocols(Window*);
|
||||
Atom xatom(char*);
|
||||
Handlers* sethandler(Window*, Handlers*);
|
||||
XRectangle XRect(Rectangle);
|
||||
Rectangle gravitate(Rectangle dst, Rectangle src, Point grav);
|
||||
Rectangle insetrect(Rectangle, int);
|
||||
Rectangle rectaddpt(Rectangle, Point);
|
||||
Rectangle rectsubpt(Rectangle, Point);
|
||||
Rectangle sizehint(WinHints*, Rectangle);
|
||||
|
|
@ -97,7 +97,7 @@ bad:
|
|||
}
|
||||
|
||||
int
|
||||
runetochar(char *str, Rune *rune)
|
||||
runetochar(char *str, const Rune *rune)
|
||||
{
|
||||
long c;
|
||||
|
||||
|
@ -132,17 +132,15 @@ runetochar(char *str, Rune *rune)
|
|||
}
|
||||
|
||||
int
|
||||
runelen(long c)
|
||||
runelen(Rune c)
|
||||
{
|
||||
Rune rune;
|
||||
char str[10];
|
||||
|
||||
rune = c;
|
||||
return runetochar(str, &rune);
|
||||
return runetochar(str, &c);
|
||||
}
|
||||
|
||||
int
|
||||
runenlen(Rune *r, int nrune)
|
||||
runenlen(const Rune *r, int nrune)
|
||||
{
|
||||
int nb, c;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <plan9.h>
|
||||
|
||||
Rune*
|
||||
runestrcat(Rune *s1, Rune *s2)
|
||||
runestrcat(Rune *s1, const Rune *s2)
|
||||
{
|
||||
|
||||
runestrcpy(runestrchr(s1, 0), s2);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "utf.h"
|
||||
|
||||
Rune*
|
||||
runestrchr(Rune *s, Rune c)
|
||||
runestrchr(const Rune *s, Rune c)
|
||||
{
|
||||
Rune c0 = c;
|
||||
Rune c1;
|
||||
|
@ -25,11 +25,11 @@ runestrchr(Rune *s, Rune c)
|
|||
if(c == 0) {
|
||||
while(*s++)
|
||||
;
|
||||
return s-1;
|
||||
return (Rune*)s-1;
|
||||
}
|
||||
|
||||
while(c1 = *s++)
|
||||
if(c1 == c0)
|
||||
return s-1;
|
||||
return (Rune*)s-1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "utf.h"
|
||||
|
||||
int
|
||||
runestrcmp(Rune *s1, Rune *s2)
|
||||
runestrcmp(const Rune *s1, const Rune *s2)
|
||||
{
|
||||
Rune c1, c2;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "utf.h"
|
||||
|
||||
Rune*
|
||||
runestrcpy(Rune *s1, Rune *s2)
|
||||
runestrcpy(Rune *s1, const Rune *s2)
|
||||
{
|
||||
Rune *os1;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <plan9.h>
|
||||
|
||||
Rune*
|
||||
runestrdup(Rune *s)
|
||||
runestrdup(const Rune *s)
|
||||
{
|
||||
Rune *ns;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "utf.h"
|
||||
|
||||
Rune*
|
||||
runestrecpy(Rune *s1, Rune *es1, Rune *s2)
|
||||
runestrecpy(Rune *s1, Rune *es1, const Rune *s2)
|
||||
{
|
||||
if(s1 >= es1)
|
||||
return s1;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <plan9.h>
|
||||
|
||||
long
|
||||
runestrlen(Rune *s)
|
||||
runestrlen(const Rune *s)
|
||||
{
|
||||
|
||||
return runestrchr(s, 0) - s;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "utf.h"
|
||||
|
||||
Rune*
|
||||
runestrncat(Rune *s1, Rune *s2, long n)
|
||||
runestrncat(Rune *s1, const Rune *s2, long n)
|
||||
{
|
||||
Rune *os1;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "utf.h"
|
||||
|
||||
int
|
||||
runestrncmp(Rune *s1, Rune *s2, long n)
|
||||
runestrncmp(const Rune *s1, const Rune *s2, long n)
|
||||
{
|
||||
Rune c1, c2;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "utf.h"
|
||||
|
||||
Rune*
|
||||
runestrncpy(Rune *s1, Rune *s2, long n)
|
||||
runestrncpy(Rune *s1, const Rune *s2, long n)
|
||||
{
|
||||
int i;
|
||||
Rune *os1;
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
#include "utf.h"
|
||||
|
||||
Rune*
|
||||
runestrrchr(Rune *s, Rune c)
|
||||
runestrrchr(const Rune *s, Rune c)
|
||||
{
|
||||
Rune *r;
|
||||
const Rune *r;
|
||||
|
||||
if(c == 0)
|
||||
return runestrchr(s, 0);
|
||||
r = 0;
|
||||
while(s = runestrchr(s, c))
|
||||
r = s++;
|
||||
return r;
|
||||
return (Rune*)r;
|
||||
}
|
||||
|
|
|
@ -21,14 +21,15 @@
|
|||
* 0 if none
|
||||
*/
|
||||
Rune*
|
||||
runestrstr(Rune *s1, Rune *s2)
|
||||
runestrstr(const Rune *s1, const Rune *s2)
|
||||
{
|
||||
Rune *p, *pa, *pb;
|
||||
const Rune *pa, *pb;
|
||||
Rune *p;
|
||||
int c0, c;
|
||||
|
||||
c0 = *s2;
|
||||
if(c0 == 0)
|
||||
return s1;
|
||||
return (Rune*)s1;
|
||||
s2++;
|
||||
for(p=runestrchr(s1, c0); p; p=runestrchr(p+1, c0)) {
|
||||
pa = p;
|
||||
|
|
19
mk/gcc.mk
19
mk/gcc.mk
|
@ -1,17 +1,16 @@
|
|||
CFLAGS += \
|
||||
-std=c99 \
|
||||
-pipe \
|
||||
-pedantic \
|
||||
-Wall \
|
||||
-Wno-parentheses \
|
||||
-Wno-missing-braces \
|
||||
-Wno-switch \
|
||||
-Wno-comment \
|
||||
-Wno-sign-compare \
|
||||
-Wno-uninitialized \
|
||||
-Wno-unused-parameter \
|
||||
-Wimplicit \
|
||||
-Wreturn-type \
|
||||
-Wtrigraphs \
|
||||
-Wstrict-prototypes \
|
||||
-Wmissing-prototypes \
|
||||
-Wno-comment \
|
||||
-Wno-missing-braces \
|
||||
-Wno-parentheses \
|
||||
-Wno-sign-compare \
|
||||
-Wno-switch \
|
||||
-Wpointer-arith \
|
||||
-Wreturn-type \
|
||||
-Wstrict-prototypes \
|
||||
-Wtrigraphs \
|
||||
|
|
206
rc/rc.wmii.rc
206
rc/rc.wmii.rc
|
@ -1,45 +1,25 @@
|
|||
#!/usr/bin/env wmii9rc
|
||||
scriptname=$0
|
||||
oldpath=$path; path=($PLAN9/bin $path)
|
||||
. wmii.rc wmiirc # Include utility functions
|
||||
|
||||
# WMII Configuration
|
||||
|
||||
confpath=`{echo $WMII_CONFPATH | sed 'y/:/ /'}
|
||||
oldpath=$path
|
||||
path=($PLAN9/bin $path)
|
||||
|
||||
# Sanity checks
|
||||
if(echo $0 | grep -s '(^|/)rc\.wmii\.local$') {
|
||||
echo >[1=2] Fatal: This file must not be named rc.wmii.local
|
||||
exit badname
|
||||
}
|
||||
|
||||
fn config_whatis {
|
||||
prog = `{@{path=$confpath whatis $1} | grep -v '^fn|= ' || echo /dev/null}
|
||||
shift; echo $prog $*
|
||||
}
|
||||
|
||||
if(! test -x $PLAN9/bin/read) {
|
||||
echo 'Can''t find the ''read'' command' >[1=2]
|
||||
xmessage -file - <<'!'
|
||||
exec `{config_whatis wmiirc}
|
||||
}
|
||||
rc.wmii can't run:
|
||||
You have a Plan 9 utilities installed, but are missing the 'read' command.
|
||||
This likely means that you have an out-of-date 9base installed.
|
||||
|
||||
wmiirc will be run instead.
|
||||
!
|
||||
|
||||
# Configurables
|
||||
# Keys
|
||||
MODKEY=Mod1
|
||||
UP=k
|
||||
DOWN=j
|
||||
LEFT=h
|
||||
RIGHT=l
|
||||
|
||||
WMII_FONT='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*'
|
||||
WMII_NORMCOLORS=('#222222' '#5FBF77' '#2A7F3F')
|
||||
WMII_FOCUSCOLORS=('#ffffff' '#153F1F' '#2A7F3F')
|
||||
WMII_BACKGROUND='#333333'
|
||||
# Theme
|
||||
wmiifont='drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*'
|
||||
wmiifont='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*'
|
||||
wmiinormcol=`{echo '#222222 #5FBF77 #2A7F3F'}
|
||||
wmiifocuscol=`{echo '#ffffff #153F1F #2A7F3F'}
|
||||
wmiibackground='#333333'
|
||||
|
||||
# Programs
|
||||
WMII_TERM=(xterm)
|
||||
|
||||
# Column Rules
|
||||
|
@ -49,68 +29,33 @@ wmiir write /colrules <<!
|
|||
|
||||
# Tagging Rules
|
||||
wmiir write /tagrules <<!
|
||||
/VLC/ -> ~
|
||||
/XMMS.*/ -> ~
|
||||
/MPlayer.*/ -> ~
|
||||
/.*/ -> sel
|
||||
/.*/ -> 1
|
||||
!
|
||||
|
||||
# Status Bar Info
|
||||
fn status { echo -n `{uptime | sed 's/.*://; s/,//g'} '|' `{date} }
|
||||
|
||||
fn viewtitle { echo $* }
|
||||
|
||||
# Convenience Functions
|
||||
fn wmiimenu {
|
||||
dmenu -b -fn $WMII_FONT \
|
||||
-nf $WMII_NORMCOLORS(1) -nb $WMII_NORMCOLORS(2) \
|
||||
-sf $WMII_FOCUSCOLORS(1) -sb $WMII_FOCUSCOLORS(2)
|
||||
fn status {
|
||||
echo -n `{uptime | sed 's/.*://; s/,//g'} \
|
||||
'|' `{date}
|
||||
}
|
||||
|
||||
fn 9menu {
|
||||
wmii9menu -font $WMII_FONT \
|
||||
-^(nf nb br)^$WMII_NORMCOLORS \
|
||||
-^(sf sb br)^$WMII_FOCUSCOLORS $*
|
||||
}
|
||||
# End Configuration
|
||||
|
||||
fn proglist {
|
||||
/bin/ls -lL `{echo $* | sed 'y/:/ /'} >[2]/dev/null \
|
||||
| awk '$1 ~ /^[^d].*x/ { print $NF }' \
|
||||
| sort | uniq
|
||||
}
|
||||
|
||||
fn actionlist {
|
||||
{ proglist $WMII_CONFPATH
|
||||
getfuns Action
|
||||
} | sort | uniq
|
||||
}
|
||||
|
||||
fn run_command { @{
|
||||
rfork ns
|
||||
path=$oldpath
|
||||
eval exec $* &
|
||||
}
|
||||
}
|
||||
|
||||
fn getfuns { env | sed -n 's/^fn#'^$1^'-([^=]+).*/\1/p' }
|
||||
fn initkeys { getfuns Key | wmiir write /keys }
|
||||
fn read_tags { wmiir ls /tag | sed 's,/,,; /^sel$/d' }
|
||||
fn 'fn?' {rc -c 'whatis '$1 >[2]/dev/null | grep -s '^fn ' }
|
||||
ifs='' {nl=`{echo}}
|
||||
confpath=`{echo $WMII_CONFPATH | sed 'y/:/ /'}
|
||||
|
||||
# Events
|
||||
fn Event-Start {
|
||||
switch($1) {
|
||||
case wmiirc
|
||||
rm -f $progs_file
|
||||
exit
|
||||
}
|
||||
fn sigexit {
|
||||
rm -f $progs_file
|
||||
wi_cleankeys
|
||||
}
|
||||
fn Event-Key { Key-$1 $1 }
|
||||
|
||||
fn Event-CreateTag { echo $WMII_NORMCOLORS `{viewtitle $*} | wmiir create /lbar/$"* }
|
||||
fn Event-CreateTag { echo $wmiinormcol $* | wmiir create /lbar/$"* }
|
||||
fn Event-DestroyTag { wmiir remove /lbar/$"* }
|
||||
fn Event-FocusTag { wmiir xwrite /lbar/$"* $WMII_FOCUSCOLORS `{viewtitle $*} }
|
||||
fn Event-UnfocusTag { wmiir xwrite /lbar/$"* $WMII_NORMCOLORS `{viewtitle $*} }
|
||||
fn Event-FocusTag { wmiir xwrite /lbar/$"* $wmiifocuscol $* }
|
||||
fn Event-UnfocusTag { wmiir xwrite /lbar/$"* $wmiinormcol $* }
|
||||
fn Event-UrgentTag { shift; wmiir xwrite /lbar/$"* '*'$"* }
|
||||
fn Event-NotUrgentTag { shift; wmiir xwrite /lbar/$"* $"* }
|
||||
|
||||
|
@ -119,36 +64,38 @@ fn Event-LeftBarClick { shift; wmiir xwrite /ctl view $* }
|
|||
fn Event-ClientMouseDown {
|
||||
client = $1; button = $2
|
||||
if(~ $button 3) {
|
||||
do=`{9menu -initial $menulast Nop Delete Fullscreen}
|
||||
do=`{wi_9menu -initial $menulast Nop Delete Fullscreen}
|
||||
switch($do) {
|
||||
case Delete
|
||||
wmiir xwrite /client/$client/ctl kill
|
||||
case Fullscreen
|
||||
wmiir xwrite /client/$client/ctl Fullscreen on
|
||||
}
|
||||
if(! ~ $#do 0)
|
||||
if(! ~ $do '')
|
||||
menulast = $do;
|
||||
}
|
||||
}
|
||||
menulast = Nop
|
||||
|
||||
# Utility
|
||||
fn 'fn?' {rc -c 'whatis '$1 >[2]/dev/null | grep -s '^fn ' }
|
||||
|
||||
# Actions
|
||||
fn Action {
|
||||
cmd=$1 action=Action-$cmd { shift
|
||||
if('fn?' $action)
|
||||
$action $*
|
||||
if not
|
||||
run_command `{config_whatis $cmd} $*
|
||||
wi_runcmd `{wi_script $cmd} $*
|
||||
} &
|
||||
}
|
||||
|
||||
# Actions
|
||||
fn Action-rehash {
|
||||
if(test -d /proc/$pid)
|
||||
for(i in $WMII_NS_DIR/proglist.*) {
|
||||
id=`{echo $i | sed 's/.*\.(.*)/\1/'} \
|
||||
if(! test -d /proc/$id) rm $i
|
||||
}
|
||||
proglist $PATH >$progs_file
|
||||
comm -23 <{ls $WMII_NS_DIR/proglist.* | awk -F'\.' '{print $NF}'} \
|
||||
<{ps | awk '{print $2}'} |
|
||||
while(id=`{read})
|
||||
rm $WMII_NS_DIR/proglist.$id
|
||||
wi_proglist $PATH >$progs_file
|
||||
}
|
||||
fn Action-quit { wmiir xwrite /ctl quit }
|
||||
fn Action-exec { wmiir xwrite /ctl exec $* }
|
||||
|
@ -156,24 +103,16 @@ fn Action-status {
|
|||
flag x -; flag r -
|
||||
if(wmiir remove /rbar/status >[2]/dev/null)
|
||||
sleep 2
|
||||
echo $WMII_NORMCOLORS | wmiir create /rbar/status
|
||||
echo $wmiinormcol | wmiir create /rbar/status
|
||||
while(status | wmiir write /rbar/status)
|
||||
sleep 1
|
||||
}
|
||||
|
||||
# Source Variables, &c
|
||||
local = `{config_whatis rc.wmii.local}
|
||||
. <{awk '//;
|
||||
/^# Overrides/ {
|
||||
print "xmessage -file - <<!"
|
||||
print "rc.wmii: Warning:"
|
||||
print " Your rc.wmii.local contains an ''# Overrides'' line."
|
||||
print " This line has a deprecated special meaning. Functions"
|
||||
print " you wish to override should be defined in a function"
|
||||
print " called Action-overridekeys"
|
||||
print "!"
|
||||
exit
|
||||
}' $local </dev/null}
|
||||
if(~ $0 rc.wmii.local */rc.wmii.local)
|
||||
wi_notice This file should not be named rc.wmii.local
|
||||
if not
|
||||
. `{wi_script rc.wmii.local} /dev/null
|
||||
|
||||
# Key Bindings
|
||||
fn key {
|
||||
|
@ -182,12 +121,15 @@ fn key {
|
|||
~ $#key 0
|
||||
}
|
||||
|
||||
# This is... ugly.
|
||||
|
||||
key $MODKEY-Control-t || fn $key {
|
||||
switch(`{wmiir read /keys | wc -l}) {
|
||||
case 0 1
|
||||
initkeys
|
||||
wmiir xwrite /ctl $keys
|
||||
wmiir xwrite /ctl grabmod $MODKEY
|
||||
case *
|
||||
ifs=() { keys=`{wmiir read /keys} }
|
||||
wmiir xwrite /keys $MODKEY-Control-t
|
||||
wmiir xwrite /ctl grabmod Mod3
|
||||
}
|
||||
|
@ -213,37 +155,36 @@ key $MODKEY-m || fn $key { wmiir xwrite /tag/sel/ctl colmode sel max }
|
|||
|
||||
key $MODKEY-Shift-c || fn $key { wmiir xwrite /client/sel/ctl kill }
|
||||
|
||||
key $MODKEY-a || fn $key { Action `{actionlist | wmiimenu} & }
|
||||
key $MODKEY-p || fn $key { ifs=() { run_command `{wmiimenu <$progs_file} & } }
|
||||
key $MODKEY-Return || fn $key { run_command $WMII_TERM & }
|
||||
key $MODKEY-a || fn $key { Action `{wi_actions | wi_menu} & }
|
||||
key $MODKEY-p || fn $key { ifs=() { wi_runcmd `{wi_menu <$progs_file} & } }
|
||||
key $MODKEY-Return || fn $key { wi_runcmd $WMII_TERM & }
|
||||
|
||||
key $MODKEY-t || fn $key { wmiir xwrite /ctl view `{read_tags | wmiimenu} & }
|
||||
key $MODKEY-t || fn $key { wmiir xwrite /ctl view `{wi_tags | wi_menu} & }
|
||||
key $MODKEY-Shift-t || fn $key {
|
||||
sel = `{wmiir read /client/sel/ctl | sed 1q} \
|
||||
wmiir xwrite /client/$sel/tags `{read_tags | wmiimenu} &
|
||||
wmiir xwrite /client/$sel/tags `{wi_tags | wi_menu} &
|
||||
}
|
||||
|
||||
key $MODKEY-^`{seq 0 9}|| fn $key { wmiir xwrite /ctl view `{echo $1 | sed 's/.*-//'} }
|
||||
key $MODKEY-^`{seq 0 9} || fn $key {
|
||||
wmiir xwrite /ctl view `{echo $1 | sed 's/.*-//'}
|
||||
}
|
||||
key Shift-$MODKEY-^`{seq 0 9} || fn $key {
|
||||
wmiir xwrite /client/sel/tags `{echo $1 | sed 's/.*-//'}
|
||||
}
|
||||
|
||||
# WM Configuration
|
||||
wmiir write /ctl <<!
|
||||
grabmod $MODKEY
|
||||
border 2
|
||||
font $WMII_FONT
|
||||
focuscolors $WMII_FOCUSCOLORS
|
||||
normcolors $WMII_NORMCOLORS
|
||||
view 1
|
||||
grabmod $MODKEY
|
||||
border 2
|
||||
font $wmiifont
|
||||
focuscolors $wmiifocuscol
|
||||
normcolors $wmiinormcol
|
||||
!
|
||||
xsetroot -solid $WMII_BACKGROUND
|
||||
xsetroot -solid $wmiibackground
|
||||
|
||||
# Source Overrides
|
||||
. <{awk '/^# Overrides/, 0' $local </dev/null}
|
||||
if('fn?' Action-overridekeys)
|
||||
Action-overridekeys
|
||||
if not
|
||||
. `{config_whatis overridekeys}
|
||||
Action overridekeys
|
||||
|
||||
# Misc Setup
|
||||
progs_file=$WMII_NS_DIR/proglist.$pid
|
||||
|
@ -251,27 +192,16 @@ Action status
|
|||
Action rehash
|
||||
|
||||
# Tag Bar Setup
|
||||
ifs='#
|
||||
'{ for(bar in `{comm -23 <{wmiir ls /lbar} <{read_tags}})
|
||||
wmiir remove /lbar/$bar
|
||||
ifs=$nl{
|
||||
wmiir rm `{comm -23 <{wmiir ls /lbar} <{wi_tags}}
|
||||
seltag=`{wmiir read /tag/sel/ctl | sed 1q}
|
||||
for(tag in `{read_tags}) {
|
||||
for(tag in `{wi_tags}) {
|
||||
if(~ $tag $seltag)
|
||||
echo $WMII_FOCUSCOLORS `{viewtitle $tag} | wmiir create /lbar/$tag
|
||||
echo $wmiifocuscol $tag | wmiir create /lbar/$tag
|
||||
if not
|
||||
echo $WMII_NORMCOLORS `{viewtitle $tag} | wmiir create /lbar/$tag
|
||||
echo $wmiinormcol $tag | wmiir create /lbar/$tag
|
||||
}
|
||||
}
|
||||
|
||||
# Keygrab Setup
|
||||
initkeys
|
||||
wi_eventloop
|
||||
|
||||
if(echo Start wmiirc | ! wmiir write /event >[2]/dev/null)
|
||||
exit write
|
||||
|
||||
# Event Loop
|
||||
wmiir read /event |
|
||||
while(*=`{read}) {
|
||||
event = $1; shift
|
||||
Event-$event $*
|
||||
} >[2]/dev/null </dev/null
|
||||
|
|
|
@ -45,8 +45,7 @@ echo '
|
|||
/Firefox/ -> www
|
||||
/XMMS.*/ -> ~
|
||||
/MPlayer.*/ -> ~
|
||||
/.*/ -> !
|
||||
/.*/ -> 1
|
||||
/.*/ -> sel
|
||||
' >/tagrules
|
||||
|
||||
subfn seq {
|
||||
|
@ -139,6 +138,7 @@ Event ClientMouseDown {
|
|||
(client button) := $*
|
||||
if {~ $button 3} {
|
||||
lastcmd = `{9menu -initial $lastcmd Nop Delete Fullscreen}
|
||||
if{~ $#lastcmd 0} {lastcmd=''}
|
||||
cmp := {~ $lastcmd $*}
|
||||
if {$cmp Nop} {
|
||||
} {$cmp Delete} { echo kill >/client/$client/ctl
|
||||
|
|
25
rc/wmiirc.sh
25
rc/wmiirc.sh
|
@ -40,7 +40,7 @@ status() {
|
|||
|
||||
# Event processing
|
||||
# Processed later by `wmiiloop' and evaled.
|
||||
# Duplicate the eval line and replace 'eval' with 'echo' for details.
|
||||
# Uncomment the line before the eval and run for details.
|
||||
eventstuff() {
|
||||
cat <<'!'
|
||||
# Events
|
||||
|
@ -168,6 +168,7 @@ export WMII_MENU WMII_9MENU WMII_FONT WMII_TERM
|
|||
export WMII_FOCUSCOLORS WMII_SELCOLORS WMII_NORMCOLORS
|
||||
|
||||
# Feed events to `wmiiloop' for processing
|
||||
#echo "$(eventstuff | sed 's/^[ ]//' | { . wmiiloop; })"
|
||||
eval "$(eventstuff | sed 's/^[ ]//' | { . wmiiloop; })"
|
||||
|
||||
echo "$Keys" | tr ' ' '\n' | wmiir write /keys
|
||||
|
@ -196,18 +197,14 @@ proglist $PATH >$progsfile &
|
|||
xsetroot -solid "$WMII_BACKGROUND" &
|
||||
|
||||
# Setup Tag Bar
|
||||
seltag="$(wmiir read /tag/sel/ctl 2>/dev/null)"
|
||||
wmiir ls /lbar |
|
||||
while read bar; do
|
||||
wmiir remove "/lbar/$bar"
|
||||
done
|
||||
wmiir ls /tag | sed -e 's|/||; /^sel$/d' |
|
||||
while read tag; do
|
||||
if [ "X$tag" = "X$seltag" ]; then
|
||||
echo "$WMII_FOCUSCOLORS" "$tag" | wmiir create "/lbar/$tag"
|
||||
(IFS="$(echo)"; wmiir rm $(wmiir ls /lbar))
|
||||
seltag="$(wmiir read /tag/sel/ctl 2>/dev/null | sed 1q)"
|
||||
wmiir ls /tag | sed -e 's|/||; /^sel$/d' | while read tag; do
|
||||
if [ "$tag" = "$seltag" ]; then
|
||||
echo "$WMII_FOCUSCOLORS" "$tag"
|
||||
else
|
||||
echo "$WMII_NORMCOLORS" "$tag" | wmiir create "/lbar/$tag"
|
||||
fi
|
||||
echo "$WMII_NORMCOLORS" "$tag"
|
||||
fi | wmiir create "/lbar/$tag"
|
||||
done
|
||||
|
||||
# More functions
|
||||
|
@ -230,9 +227,9 @@ conf_which() {
|
|||
# Stop any running instances of wmiirc
|
||||
echo Start wmiirc | wmiir write /event || exit 1
|
||||
|
||||
wmiir read /event |
|
||||
while read event; do
|
||||
wmiir read /event | while read event; do
|
||||
set -- $event
|
||||
event=$1; shift
|
||||
Event_$event $@
|
||||
done 2>/dev/null
|
||||
|
||||
|
|
41
util/compile
41
util/compile
|
@ -15,10 +15,49 @@ status=$?
|
|||
base=$(echo $BASE | sed 's/,/\\,/g')
|
||||
re='\([^[:space:]/]*\..:[0-9]\)'
|
||||
|
||||
undup() { # GCC is crap.
|
||||
awk '
|
||||
function shift() {
|
||||
for(n=1; n<=3; n++)
|
||||
if(2*n <= nl)
|
||||
for(i=1; i<=n; i++) {
|
||||
if(l[i] != l[i+n])
|
||||
break;
|
||||
if(i == n) {
|
||||
for(i=1; i<=n; i++)
|
||||
print l[i]
|
||||
nl -= 2*n;
|
||||
for(i=1; i<=nl; i++)
|
||||
l[i] = l[i+2*n];
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(nl == 0)
|
||||
return
|
||||
print l[1]
|
||||
for(i=1; i<nl; i++)
|
||||
l[i] = l[i+1]
|
||||
nl--
|
||||
}
|
||||
BEGIN{
|
||||
nl=0
|
||||
maxl=6
|
||||
}
|
||||
{
|
||||
if(nl == maxl)
|
||||
shift()
|
||||
l[++nl] = $0
|
||||
}
|
||||
END{
|
||||
while(nl > 0)
|
||||
shift();
|
||||
}'
|
||||
}
|
||||
|
||||
cat $xtmp | sed "s,^$re,$base&,g; s,\([[:space:]]\)$re,\1$base\2,g" |
|
||||
egrep -v ': error: .Each undeclared identifier|: error: for each function it appears|is dangerous, better use|is almost always misused|: In function |: At top level:|support .long long.|use of C99 long long|ISO C forbids conversion' |
|
||||
sed 's/ .first use in this function.$//; s/\"\([^\"][^\"]*\)\", line \([0-9][0-9]*\)/\1:\2/g' |
|
||||
uniq 1>&2
|
||||
undup 1>&2
|
||||
|
||||
rm -f $xtmp
|
||||
exit $status
|
||||
|
|
Loading…
Reference in New Issue