removed liblitz

This commit is contained in:
Anselm R. Garbe 2006-10-12 16:10:57 +02:00
parent 4a7273b827
commit 8e8e40516e
23 changed files with 586 additions and 947 deletions

View File

@ -1,65 +1,65 @@
# wmii - window manager improved 2
# (C)opyright MMIV-MMVI Anselm R. Garbe
# window manager improved 2 - window manager improved 2
# (C)opyright MMVI Anselm R. Garbe
include config.mk
SUBDIRS = liblitz
SRC = area.c bar.c brush.c client.c color.c column.c draw.c event.c \
font.c frame.c fs.c geom.c key.c mouse.c rule.c view.c wm.c
OBJ = ${SRC:.c=.o}
BIN = cmd/wm/wmii cmd/wm/wmiiwm cmd/wmiir
all: options wmiiwm
MAN1 = cmd/wm/wmii.1 cmd/wm/wmiiwm.1 cmd/wmiir.1
all:
options:
@echo wmii build options:
@echo "LIBS = ${LIBS}"
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
@for i in ${SUBDIRS} cmd/wm; do \
(cd $$i; make) \
done
@echo "LD = ${LD}"
dist: clean
mkdir -p wmii-${VERSION}
cp -R Makefile README LICENSE config.mk rc ${SUBDIRS} wmii-${VERSION}
tar -cf wmii-${VERSION}.tar wmii-${VERSION}
gzip wmii-${VERSION}.tar
rm -rf wmii-${VERSION}
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
${OBJ}: wm.h config.mk
wmiiwm: ${OBJ}
@echo LD $@
@${LD} -o $@ ${OBJ} ${LDFLAGS}
@strip $@
clean:
rm -f *.o
for i in ${SUBDIRS} cmd/wm; do \
(cd $$i; make clean); \
done
rm -rf wmii-${VERSION}*
@echo cleaning
@rm -f wmiiwm ${OBJ} wmii-${VERSION}.tar.gz
dist: clean
@echo creating dist tarball
@mkdir -p wmii-${VERSION}
@cp -R LICENSE Makefile README wmii config.mk \
wmii.1 wmiiwm.1 wm.h ${SRC} wmii-${VERSION}
@tar -cf wmii-${VERSION}.tar wmii-${VERSION}
@gzip wmii-${VERSION}.tar
@rm -rf wmii-${VERSION}
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f ${BIN} ${DESTDIR}${PREFIX}/bin
@sed 's|CONFPREFIX|${CONFPREFIX}|g' <cmd/wm/wmii >${DESTDIR}${PREFIX}/bin/wmii
@for i in ${BIN}; do \
chmod 755 ${DESTDIR}${PREFIX}/bin/`basename $$i`; \
done
@echo installed executable files to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${CONFPREFIX}/wmii-${VERSION}
@cd rc; for i in *; do \
sed 's|CONFPREFIX|${CONFPREFIX}|g' <$$i >${DESTDIR}${CONFPREFIX}/wmii-${VERSION}/$$i; \
chmod 755 ${DESTDIR}${CONFPREFIX}/wmii-${VERSION}/$$i; \
done
@echo installed rc scripts to ${DESTDIR}${CONFPREFIX}/wmii-${VERSION}
@cp -f wmii ${DESTDIR}${PREFIX}/bin
@cp -f wmiiwm ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/wmii
@chmod 755 ${DESTDIR}${PREFIX}/bin/wmiiwm
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
@cp -f ${MAN1} ${DESTDIR}${MANPREFIX}/man1
@sed 's|CONFPREFIX|${CONFPREFIX}|g' <cmd/wm/wmii.1 >${DESTDIR}${MANPREFIX}/man1/wmii.1
@for i in ${MAN1}; do \
chmod 444 ${DESTDIR}${MANPREFIX}/man1/`basename $$i`; \
done
@echo installed manual pages to ${DESTDIR}${MANPREFIX}/man1
@sed 's/VERSION/${VERSION}/g' < wmii.1 > ${DESTDIR}${MANPREFIX}/man1/wmii.1
@sed 's/VERSION/${VERSION}/g' < wmiiwm.1 > ${DESTDIR}${MANPREFIX}/man1/wmiiwm.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/wmii.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/wmiiwm.1
uninstall:
for i in ${BIN}; do \
rm -f ${DESTDIR}${PREFIX}/bin/`basename $$i`; \
done
for i in ${MAN1}; do \
rm -f ${DESTDIR}${MANPREFIX}/man1/`basename $$i`; \
done
rm -rf ${DESTDIR}${CONFPREFIX}/wmii-${VERSION}
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/wmii
@rm -f ${DESTDIR}${PREFIX}/bin/wmiiwm
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/wmii.1
@rm -f ${DESTDIR}${MANPREFIX}/man1/wmiiwm.1
.PHONY: all options clean dist install uninstall

91
area.c
View File

@ -1,32 +1,26 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "wm.h"
Client *
sel_client_of_area(Area *a)
{
return a && a->sel ? a->sel->client : nil;
sel_client_of_area(Area *a) {
return a && a->sel ? a->sel->client : NULL;
}
Area *
create_area(View *v, Area *pos, unsigned int w)
{
create_area(View *v, Area *pos, unsigned int w) {
static unsigned short id = 1;
unsigned int area_size, col_size;
unsigned int min_width = screen->rect.width/NCOL;
Area *a, **p = pos ? &pos->next : &v->area;
for(area_size = 0, a=v->area; a; a=a->next, area_size++);
col_size = area_size ? area_size - 1 : 0;
if(!w) {
if(col_size)
w = screen->rect.width / (col_size + 1);
@ -35,45 +29,36 @@ create_area(View *v, Area *pos, unsigned int w)
}
if(w < min_width)
w = min_width;
if(col_size && col_size * min_width + w > screen->rect.width)
return nil;
return NULL;
if(area_size > 1)
scale_view(v, screen->rect.width - w);
a = cext_emallocz(sizeof(Area));
a = ixp_emallocz(sizeof(Area));
a->view = v;
a->id = id++;
a->rect = screen->rect;
a->rect.height = screen->rect.height - screen->brect.height;
a->mode = def.colmode;
a->rect.width = w;
a->frame = nil;
a->sel = nil;
a->frame = NULL;
a->sel = NULL;
a->next = *p;
*p = a;
v->sel = a;
return a;
}
void
destroy_area(Area *a)
{
destroy_area(Area *a) {
Client *c;
Area *ta;
View *v = a->view;
cext_assert(!a->frame && "wmiiwm: fatal, destroying non-empty area");
assert(!a->frame && "wmiiwm: fatal, destroying non-empty area");
if(v->revert == a)
v->revert = nil;
v->revert = NULL;
for(c=client; c; c=c->next)
if(c->revert == a)
c->revert = nil;
c->revert = NULL;
for(ta=v->area; ta && ta->next != a; ta=ta->next);
if(ta) {
ta->next = a->next;
@ -84,10 +69,9 @@ destroy_area(Area *a)
}
static void
place_client(Area *a, Client *c)
{
place_client(Area *a, Client *c) {
static unsigned int mx, my;
static Bool *field = nil;
static Bool *field = NULL;
Frame *fr;
Bool fit = False;
BlitzAlign align = CENTER;
@ -104,18 +88,15 @@ place_client(Area *a, Client *c)
|| c->size.flags & USPosition
|| c->size.flags & PPosition)
return;
rects = rects_of_view(a->view, &num);
if(!field) {
mx = screen->rect.width / 8;
my = screen->rect.height / 8;
field = cext_emallocz(my * mx * sizeof(Bool));
field = ixp_emallocz(my * mx * sizeof(Bool));
}
for(y = 0; y < my; y++)
for(x = 0; x < mx; x++)
field[y*mx + x] = True;
dx = screen->rect.width / mx;
dy = screen->rect.height / my;
for(fr=a->frame; fr; fr=fr->anext) {
@ -138,7 +119,6 @@ place_client(Area *a, Client *c)
for(i = x; i < mx && i < maxx; i++)
field[j*mx + i] = False;
}
for(y = 0; y < my; y++)
for(x = 0; x < mx; x++) {
if(field[y*mx + x]) {
@ -155,36 +135,30 @@ place_client(Area *a, Client *c)
}
}
}
if(fit) {
p1.x *= dx;
p1.y *= dy;
}
if(fit && (p1.x + f->rect.width < a->rect.x + a->rect.width))
f->rect.x = p1.x;
else {
diff = a->rect.width - f->rect.width;
f->rect.x = a->rect.x + (random() % (diff ? diff : 1));
}
if(fit && (p1.y + f->rect.height < a->rect.y + a->rect.height))
f->rect.y = p1.y;
else {
diff = a->rect.height - f->rect.height;
f->rect.y = a->rect.y + (random() % (diff ? diff : 1));
}
snap_rect(rects, num, &f->rect, &align, snap);
if(rects)
free(rects);
}
void
send_to_area(Area *to, Area *from, Frame *f)
{
cext_assert(to->view == f->view);
send_to_area(Area *to, Area *from, Frame *f) {
assert(to->view == f->view);
if(to->floating != from->floating) {
XRectangle temp = f->revert;
f->revert = f->rect;
@ -197,15 +171,13 @@ send_to_area(Area *to, Area *from, Frame *f)
}
void
attach_to_area(Area *a, Frame *f, Bool send)
{
attach_to_area(Area *a, Frame *f, Bool send) {
unsigned int h, n_frame;
Frame **fa, *ft;
View *v = a->view;
Client *c = f->client;
for(ft=a->frame, n_frame=1; ft; ft=ft->anext, n_frame++);
h = 0;
c->floating = a->floating;
if(!c->floating) {
@ -213,7 +185,6 @@ attach_to_area(Area *a, Frame *f, Bool send)
if(a->frame)
scale_column(a, a->rect.height - h);
}
if(!send && !c->floating) { /* column */
unsigned int w = newcolw_of_view(v);
if(v->area->next->frame && w) {
@ -221,14 +192,11 @@ attach_to_area(Area *a, Frame *f, Bool send)
arrange_view(v);
}
}
fa = a->sel ? &a->sel->anext : &a->frame;
f->anext = *fa;
*fa = f;
f->area = a;
a->sel = f;
if(!c->floating) { /* column */
f->rect.height = h;
arrange_column(a, False);
@ -237,9 +205,8 @@ attach_to_area(Area *a, Frame *f, Bool send)
}
void
detach_from_area(Area *a, Frame *f)
{
Frame **ft, *pr = nil;
detach_from_area(Area *a, Frame *f) {
Frame **ft, *pr = NULL;
Client *c = f->client;
View *v = a->view;
@ -247,12 +214,10 @@ detach_from_area(Area *a, Frame *f)
if(*ft == f) break;
pr = *ft;
}
cext_assert(*ft == f);
assert(*ft == f);
*ft = f->anext;
if(a->sel == f)
a->sel = pr ? pr : *ft;
if(!a->floating) {
if(a->frame)
arrange_column(a, False);
@ -280,8 +245,7 @@ detach_from_area(Area *a, Frame *f)
}
char *
select_area(Area *a, char *arg)
{
select_area(Area *a, char *arg) {
Area *new;
unsigned int i;
Frame *p, *f;
@ -290,7 +254,6 @@ select_area(Area *a, char *arg)
v = a->view;
f = a->sel;
if(!strncmp(arg, "toggle", 7)) {
if(a != v->area)
new = v->area;
@ -321,7 +284,7 @@ select_area(Area *a, char *arg)
if(v == screen->sel)
focus_view(screen, v);
flush_masked_events(EnterWindowMask);
return nil;
return NULL;
}
else if(!strncmp(arg, "down", 5)) {
if(!f)
@ -332,7 +295,7 @@ select_area(Area *a, char *arg)
if(v == screen->sel)
focus_view(screen, v);
flush_masked_events(EnterWindowMask);
return nil;
return NULL;
}
else {
if(sscanf(arg, "%d", &i) != 1)
@ -344,5 +307,5 @@ select_area(Area *a, char *arg)
v->sel = new;
if(a->floating != new->floating)
v->revert = a;
return nil;
return NULL;
}

46
bar.c
View File

@ -1,37 +1,31 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "wm.h"
Bar *free_bars = nil;
Bar *free_bars = NULL;
Bar *
create_bar(Bar **b_link, char *name)
{
create_bar(Bar **b_link, char *name) {
static unsigned int id = 1;
Bar **i, *b = bar_of_name(*b_link, name);;
if(b)
return b;
if(free_bars) {
b = free_bars;
free_bars = b->next;
memset(b, 0, sizeof(*b));
}
else
b = cext_emallocz(sizeof(Bar));
b = ixp_emallocz(sizeof(Bar));
b->id = id++;
cext_strlcpy(b->name, name, sizeof(b->name));
strncpy(b->name, name, sizeof(b->name));
b->brush = screen->bbrush;
b->brush.color = def.normcolor;
for(i=b_link; *i; i=&(*i)->next)
if(strcmp((*i)->name, name) >= 0)
break;
@ -42,19 +36,17 @@ create_bar(Bar **b_link, char *name)
}
void
destroy_bar(Bar **b_link, Bar *b)
{
destroy_bar(Bar **b_link, Bar *b) {
Bar **p;
for(p=b_link; *p && *p != b; p=&(*p)->next);
*p = b->next;
b->next = free_bars;
free_bars = b;
}
void
resize_bar(WMScreen *s)
{
resize_bar(WMScreen *s) {
View *v;
s->brect = s->rect;
@ -63,26 +55,21 @@ resize_bar(WMScreen *s)
XMoveResizeWindow(blz.dpy, s->barwin, s->brect.x, s->brect.y, s->brect.width, s->brect.height);
XSync(blz.dpy, False);
draw_bar(s);
for(v=view; v; v=v->next)
arrange_view(v);
}
void
draw_bar(WMScreen *s)
{
draw_bar(WMScreen *s) {
unsigned int width, tw, nb, size;
float shrink;
Bar *b, *tb, *largest, **pb;
blitz_draw_tile(&s->bbrush);
if(!s->lbar && !s->rbar)
goto MapBar;
largest = b = tb = nil;
largest = b = tb = NULL;
tw = width = nb = size = 0;
for(b=s->lbar, nb=2 ;nb; --nb && (b = s->rbar))
for(; b; b=b->next) {
b->brush.rect.x = b->brush.rect.y = 0;
@ -92,7 +79,6 @@ draw_bar(WMScreen *s)
b->brush.rect.height = s->brect.height;
width += b->brush.rect.width;
}
/* Not enough room. Shrink bars until they all fit */
if(width > s->brect.width) {
for(b=s->lbar, nb=2 ;nb; --nb && (b = s->rbar))
@ -114,9 +100,8 @@ draw_bar(WMScreen *s)
for(b=largest; b != tb->smaller; b=b->smaller)
b->brush.rect.width = floor(b->brush.rect.width * shrink);
width += tw * shrink;
tb=nil;
tb=NULL;
}
for(b=s->lbar, nb=2 ;nb; b=s->rbar, nb--)
for(; b; tb = b, b=b->next) {
if(b == s->rbar) {
@ -135,12 +120,11 @@ MapBar:
}
Bar *
bar_of_name(Bar *b_link, const char *name)
{
bar_of_name(Bar *b_link, const char *name) {
static char buf[256];
Bar *b;
cext_strlcpy(buf, name, sizeof(buf));
strncpy(buf, name, sizeof(buf));
for(b=b_link; b; b=b->next)
if(!strncmp(b->name, name, sizeof(b->name))) break;
return b;

View File

@ -1,51 +1,41 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "blitz.h"
void
blitz_draw_tile(BlitzBrush *b)
{
blitz_draw_tile(BlitzBrush *b) {
blitz_drawbg(b->blitz->dpy, b->drawable, b->gc, b->rect,
b->color, b->border);
}
void
blitz_draw_label(BlitzBrush *b, char *text)
{
blitz_draw_label(BlitzBrush *b, char *text) {
unsigned int x, y, w, h, len;
Bool shortened = False;
static char buf[2048];
XGCValues gcv;
blitz_draw_tile(b);
if(!text)
return;
shortened = 0;
strncpy(buf, text, sizeof(buf));
len = strlen(buf);
gcv.foreground = b->color.fg;
gcv.background = b->color.bg;
h = b->font->ascent + b->font->descent;
y = b->rect.y + b->rect.height / 2 - h / 2 + b->font->ascent;
/* shorten text if necessary */
while(len && (w = blitz_textwidth(b->font, buf)) > b->rect.width - h) {
buf[--len] = 0;
shortened = True;
}
if(w > b->rect.width)
return;
/* mark shortened info in the string */
if(shortened) {
if (len > 3)
@ -55,7 +45,6 @@ blitz_draw_label(BlitzBrush *b, char *text)
if (len > 1)
buf[len - 1] = '.';
}
switch (b->align) {
case EAST:
x = b->rect.x + b->rect.width - (w + (b->font->height / 2));
@ -64,7 +53,6 @@ blitz_draw_label(BlitzBrush *b, char *text)
x = b->rect.x + (b->font->height / 2);
break;
}
if(b->font->set) {
XChangeGC(b->blitz->dpy, b->gc, GCForeground | GCBackground, &gcv);
XmbDrawImageString(b->blitz->dpy, b->drawable, b->font->set, b->gc,

193
client.c
View File

@ -1,28 +1,24 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xatom.h>
#include "wm.h"
static char *Ebadcmd = "bad command",
*Ebadvalue = "bad value";
#define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask | EnterWindowMask)
Client *
sel_client()
{
return screen->sel && screen->sel->sel->sel ? screen->sel->sel->sel->client : nil;
sel_client() {
return screen->sel && screen->sel->sel->sel ? screen->sel->sel->sel->client : NULL;
}
int
idx_of_client(Client *c)
{
idx_of_client(Client *c) {
Client *cl;
int i = 0;
for(cl=client; cl && cl != c; cl=cl->next, i++);
@ -30,28 +26,25 @@ idx_of_client(Client *c)
}
Client *
client_of_win(Window w)
{
client_of_win(Window w) {
Client *c;
for(c=client; c && c->win != w; c=c->next);
return c;
}
Frame *
frame_of_win(Window w)
{
frame_of_win(Window w) {
Client *c;
for(c=client; c && c->framewin != w; c=c->next);
return c ? c->frame : nil;
return c ? c->frame : NULL;
}
static void
update_client_name(Client *c)
{
update_client_name(Client *c) {
XTextProperty name;
XClassHint ch;
int n;
char **list = nil;
char **list = NULL;
name.nitems = 0;
c->name[0] = 0;
@ -61,12 +54,12 @@ update_client_name(Client *c)
if(!name.nitems)
return;
if(name.encoding == XA_STRING)
cext_strlcpy(c->name, (char *)name.value, sizeof(c->name));
strncpy(c->name, (char *)name.value, sizeof(c->name));
else {
if(XmbTextPropertyToTextList(blz.dpy, &name, &list, &n) >= Success
&& n > 0 && *list)
{
cext_strlcpy(c->name, *list, sizeof(c->name));
strncpy(c->name, *list, sizeof(c->name));
XFreeStringList(list);
}
}
@ -84,9 +77,8 @@ update_client_name(Client *c)
}
Client *
create_client(Window w, XWindowAttributes *wa)
{
Client **t, *c = (Client *) cext_emallocz(sizeof(Client));
create_client(Window w, XWindowAttributes *wa) {
Client **t, *c = (Client *) ixp_emallocz(sizeof(Client));
XSetWindowAttributes fwa;
long msize;
unsigned int i;
@ -117,7 +109,6 @@ create_client(Window w, XWindowAttributes *wa)
fwa.event_mask =
SubstructureRedirectMask | SubstructureNotifyMask | ExposureMask
| ButtonPressMask | PointerMotionMask | ButtonReleaseMask | KeyPressMask;
c->framewin = XCreateWindow(blz.dpy, blz.root, c->rect.x, c->rect.y,
c->rect.width + 2 * def.border,
c->rect.height + def.border + blitz_labelh(&def.font), 0,
@ -126,18 +117,15 @@ create_client(Window w, XWindowAttributes *wa)
CWOverrideRedirect | CWBackPixmap | CWEventMask, &fwa);
c->gc = XCreateGC(blz.dpy, c->framewin, 0, 0);
XSync(blz.dpy, False);
for(t=&client, i=0; *t; t=&(*t)->next, i++);
c->next = *t; /* *t == nil */
c->next = *t; /* *t == NULL */
*t = c;
write_event("CreateClient %d\n", i);
return c;
}
void
update_client_grab(Client *c, Bool is_sel)
{
update_client_grab(Client *c, Bool is_sel) {
if(is_sel) {
ungrab_mouse(c->framewin, AnyModifier, AnyButton);
grab_mouse(c->framewin, def.mod, Button1);
@ -148,8 +136,7 @@ update_client_grab(Client *c, Bool is_sel)
}
void
focus_client(Client *c, Bool restack)
{
focus_client(Client *c, Bool restack) {
Client *old_in_area;
Client *old;
Frame *f;
@ -157,16 +144,13 @@ focus_client(Client *c, Bool restack)
if(!sel_screen)
return;
f = c->sel;
v = f->area->view;
old = sel_client();
old_in_area = sel_client_of_area(f->area);
v->sel = f->area;
f->area->sel = f;
c->floating = f->area->floating;
if(restack)
restack_view(v);
else {
@ -174,7 +158,6 @@ focus_client(Client *c, Bool restack)
update_client_grab(old, False);
update_client_grab(c, True);
}
if(!c->floating && f->area->mode == Colstack)
arrange_column(f->area, False);
XSetInputFocus(blz.dpy, c->win, RevertToPointerRoot, CurrentTime);
@ -193,34 +176,31 @@ focus_client(Client *c, Bool restack)
}
void
map_client(Client *c)
{
map_client(Client *c) {
XSelectInput(blz.dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
XMapWindow(blz.dpy, c->win);
XSelectInput(blz.dpy, c->win, CLIENT_MASK);
}
void
unmap_client(Client *c)
{
unmap_client(Client *c) {
XSelectInput(blz.dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
XUnmapWindow(blz.dpy, c->win);
XSelectInput(blz.dpy, c->win, CLIENT_MASK);
}
void
reparent_client(Client *c, Window w, int x, int y)
{
reparent_client(Client *c, Window w, int x, int y) {
XSelectInput(blz.dpy, c->win, CLIENT_MASK & ~StructureNotifyMask);
XReparentWindow(blz.dpy, c->win, w, x, y);
XSelectInput(blz.dpy, c->win, CLIENT_MASK);
}
void
configure_client(Client *c)
{
configure_client(Client *c) {
XConfigureEvent e;
Frame *f = c->sel;
e.type = ConfigureNotify;
e.event = c->win;
e.window = c->win;
@ -241,23 +221,21 @@ configure_client(Client *c)
}
static void
send_client_message(Window w, Atom a, long value)
{
send_client_message(Window w, Atom a, long value) {
XEvent e;
e.type = ClientMessage;
e.xclient.window = w;
e.xclient.message_type = a;
e.xclient.format = 32;
e.xclient.data.l[0] = value;
e.xclient.data.l[1] = CurrentTime;
XSendEvent(blz.dpy, w, False, NoEventMask, &e);
XSync(blz.dpy, False);
}
void
kill_client(Client * c)
{
kill_client(Client * c) {
if(c->proto & WM_PROTOCOL_DELWIN)
send_client_message(c->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
else
@ -265,8 +243,7 @@ kill_client(Client * c)
}
void
prop_client(Client *c, XPropertyEvent *e)
{
prop_client(Client *c, XPropertyEvent *e) {
long msize;
if(e->atom == wm_atom[WMProtocols]) {
@ -297,15 +274,13 @@ prop_client(Client *c, XPropertyEvent *e)
}
void
gravitate_client(Client *c, Bool invert)
{
gravitate_client(Client *c, Bool invert) {
int dx = 0, dy = 0;
int gravity = NorthWestGravity;
if(c->size.flags & PWinGravity) {
gravity = c->size.win_gravity;
}
/* y */
switch (gravity) {
case StaticGravity:
@ -327,7 +302,6 @@ gravitate_client(Client *c, Bool invert)
default:
break;
}
/* x */
switch (gravity) {
case StaticGravity:
@ -359,27 +333,21 @@ gravitate_client(Client *c, Bool invert)
}
void
manage_client(Client *c)
{
manage_client(Client *c) {
XTextProperty tags;
Client *trans;
tags.nitems = 0;
XGetTextProperty(blz.dpy, c->win, &tags, tags_atom);
if(c->trans && (trans = client_of_win(c->trans)))
cext_strlcpy(c->tags, trans->tags, sizeof(c->tags));
strncpy(c->tags, trans->tags, sizeof(c->tags));
else if(tags.nitems)
cext_strlcpy(c->tags, (char *)tags.value, sizeof(c->tags));
strncpy(c->tags, (char *)tags.value, sizeof(c->tags));
XFree(tags.value);
if(!strlen(c->tags))
apply_rules(c);
apply_tags(c, c->tags);
reparent_client(c, c->framewin, c->rect.x, c->rect.y);
if(!starting)
update_views();
map_client(c);
@ -391,40 +359,31 @@ manage_client(Client *c)
}
static int
dummy_error_handler(Display *dpy, XErrorEvent *error)
{
dummy_error_handler(Display *dpy, XErrorEvent *error) {
return 0;
}
void
destroy_client(Client *c)
{
char *dummy = nil;
destroy_client(Client *c) {
char *dummy = NULL;
Client **tc;
XGrabServer(blz.dpy);
XSetErrorHandler(dummy_error_handler);
if(c->frame) {
c->rect.x = c->sel->rect.x;
c->rect.y = c->sel->rect.y;
}
update_client_views(c, &dummy);
unmap_client(c);
reparent_client(c, blz.root, c->rect.x, c->rect.y);
XFreeGC(blz.dpy, c->gc);
XDestroyWindow(blz.dpy, c->framewin);
for(tc=&client; *tc && *tc != c; tc=&(*tc)->next);
cext_assert(*tc == c);
assert(*tc == c);
*tc = c->next;
update_views();
free(c);
XSync(blz.dpy, False);
XSetErrorHandler(wmii_error_handler);
XUngrabServer(blz.dpy);
@ -432,8 +391,7 @@ destroy_client(Client *c)
}
void
match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky)
{
match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky) {
XSizeHints *s = &c->size;
unsigned int dx = 2 * def.border;
unsigned int dy = def.border + blitz_labelh(&def.font);
@ -467,10 +425,8 @@ match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky)
r->y += hdiff;
}
}
if(s->flags & PResizeInc) {
int w = 0, h = 0;
if(s->flags & PBaseSize) {
w = s->base_width;
h = s->base_height;
@ -487,7 +443,6 @@ match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky)
if((sticky & EAST) && !(sticky & WEST))
r->x += wdiff;
}
h = r->height - dy - h;
if(s->height_inc > 0) {
hdiff = h % s->height_inc;
@ -499,8 +454,7 @@ match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky)
}
void
resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
{
resize_client(Client *c, XRectangle *r, Bool ignore_xcall) {
Frame *f = c->sel;
Bool floating = f->area->floating;
unsigned int max_height;
@ -514,12 +468,9 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
stickycorner |= SOUTH;
else
stickycorner |= NORTH;
f->rect = *r;
if((f->area->mode != Colstack) || (f->area->sel == f))
match_sizehints(c, &c->sel->rect, floating, stickycorner);
max_height = screen->rect.height - blitz_labelh(&def.font);
if(!ignore_xcall) {
if(floating) {
@ -549,7 +500,6 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
XMoveResizeWindow(blz.dpy, c->framewin, 2 * screen->rect.width + f->rect.x,
f->rect.y, f->rect.width, f->rect.height);
}
c->rect.x = def.border;
c->rect.y = blitz_labelh(&def.font);
if((f->area->sel == f) || (f->area->mode != Colstack)) {
@ -564,8 +514,7 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
}
void
newcol_client(Client *c, char *arg)
{
newcol_client(Client *c, char *arg) {
Frame *f = c->sel;
Area *to, *a = f->area;
View *v = a->view;
@ -574,7 +523,6 @@ newcol_client(Client *c, char *arg)
return;
if(!f->anext && f == a->frame)
return;
if(!strncmp(arg, "prev", 5)) {
for(to=v->area; to && to->next != a; to=to->next);
to = new_column(v, to, 0);
@ -590,8 +538,7 @@ newcol_client(Client *c, char *arg)
}
void
move_client(Client *c, char *arg)
{
move_client(Client *c, char *arg) {
Frame *f = c->sel;
XRectangle new = f->rect;
int x, y;
@ -601,14 +548,13 @@ move_client(Client *c, char *arg)
new.x += x;
new.y += y;
if(!f->area->floating)
resize_column(f->client, &new, nil);
resize_column(f->client, &new, NULL);
else
resize_client(f->client, &new, False);
}
void
size_client(Client *c, char *arg)
{
size_client(Client *c, char *arg) {
Frame *f = c->sel;
XRectangle new = f->rect;
int w, h;
@ -618,14 +564,13 @@ size_client(Client *c, char *arg)
new.width += w;
new.height += h;
if(!f->area->floating)
resize_column(f->client, &new, nil);
resize_column(f->client, &new, NULL);
else
resize_client(f->client, &new, False);
}
char *
send_client(Frame *f, char *arg)
{
send_client(Frame *f, char *arg) {
Area *to, *a;
Client *c;
Frame *tf;
@ -635,7 +580,6 @@ send_client(Frame *f, char *arg)
a = f->area;
v = a->view;
c = f->client;
if(!strncmp(arg, "toggle", 7)) {
if(!a->floating)
to = v->area;
@ -695,30 +639,28 @@ send_client(Frame *f, char *arg)
focus_client(f->client, False);
focus_view(screen, f->view);
}
return nil;
return NULL;
}
/* convenience function */
void
focus(Client *c, Bool restack)
{
focus(Client *c, Bool restack) {
View *v;
Frame *f;
if(!(f = c->sel)) return;
v = f->area->view;
arrange_column(f->area, False);
focus_client(c, restack);
focus_view(screen, v);
}
void
update_client_views(Client *c, char **tags)
{
update_client_views(Client *c, char **tags) {
int cmp;
Frame *f;
Frame **fp = &c->frame;
while(*fp || *tags) {
while(*fp && (!*tags || (cmp=strcmp((*fp)->view->name, *tags)) < 0)) {
f = *fp;
@ -728,7 +670,6 @@ update_client_views(Client *c, char **tags)
if(c->sel == f)
c->sel = *fp;
}
if(*tags) {
if(!*fp || cmp > 0) {
f = create_frame(c, get_view(*tags));
@ -751,73 +692,65 @@ compare_tags(const void *a, const void *b) {
}
void
apply_tags(Client *c, const char *tags)
{
apply_tags(Client *c, const char *tags) {
unsigned int i, j, n;
int len;
char buf[256];
char *toks[32];
cext_strlcpy(buf, tags, sizeof(buf));
if(!(n = cext_tokenize(toks, 31, buf, '+')))
strncpy(buf, tags, sizeof(buf));
if(!(n = ixp_tokenize(toks, 31, buf, '+')))
return;
for(i=0, j=0; i < n; i++) {
if(!strncmp(toks[i], "~", 2))
c->floating = True;
else if(!strncmp(toks[i], "!", 2))
toks[j++] = view ? screen->sel->name : "nil";
toks[j++] = view ? screen->sel->name : "NULL";
else if(strncmp(toks[i], "sel", 4))
toks[j++] = toks[i];
}
c->tags[0] = '\0';
qsort(toks, j, sizeof(char *), compare_tags);
len = sizeof(c->tags);
if(!j) toks[j++] = "nil";
if(!j) toks[j++] = "NULL";
for(i=0, n=0; i < j && len > 1; i++)
if(!n || strcmp(toks[i], toks[n-1])) {
if(n)
len -= cext_strlcat(c->tags, "+", len);
len -= cext_strlcat(c->tags, toks[i], len);
strncat(c->tags, "+", len);
len -= strlen(c->tags);
strncat(c->tags, toks[i], len);
len -= strlen(c->tags);
toks[n++] = toks[i];
}
toks[n] = nil;
toks[n] = NULL;
update_client_views(c, toks);
XChangeProperty(blz.dpy, c->win, tags_atom, XA_STRING, 8,
PropModeReplace, (unsigned char *)c->tags, strlen(c->tags));
}
static void
match_tags(Client *c, const char *prop)
{
match_tags(Client *c, const char *prop) {
Rule *r;
regmatch_t tmpregm;
for(r=def.tagrules.rule; r; r=r->next)
if(!regexec(&r->regex, prop, 1, &tmpregm, 0))
if(!strlen(c->tags) || !strncmp(c->tags, "nil", 4))
if(!strlen(c->tags) || !strncmp(c->tags, "NULL", 4))
apply_tags(c, r->value);
}
void
apply_rules(Client *c)
{
apply_rules(Client *c) {
if(def.tagrules.string)
match_tags(c, c->props);
if(!strlen(c->tags))
apply_tags(c, "nil");
apply_tags(c, "NULL");
}
char *
message_client(Client *c, char *message)
{
message_client(Client *c, char *message) {
if(!strncmp(message, "kill", 5)) {
kill_client(c);
return nil;
return NULL;
}
return Ebadcmd;
}

View File

@ -1,15 +1,11 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <string.h>
#include "blitz.h"
static unsigned long
xloadcolor(Blitz *blitz, char *colstr)
{
xloadcolor(Blitz *blitz, char *colstr) {
XColor color;
char col[8];
@ -21,8 +17,7 @@ xloadcolor(Blitz *blitz, char *colstr)
}
int
blitz_loadcolor(Blitz *blitz, BlitzColor *c)
{
blitz_loadcolor(Blitz *blitz, BlitzColor *c) {
if(!c->colstr || strlen(c->colstr) != 23)
return -1;
c->fg = xloadcolor(blitz, &c->colstr[0]);
@ -30,4 +25,3 @@ blitz_loadcolor(Blitz *blitz, BlitzColor *c)
c->border = xloadcolor(blitz, &c->colstr[16]);
return 0;
}

View File

@ -1,28 +1,24 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <stdlib.h>
#include <string.h>
#include "wm.h"
char *
str_of_column_mode(int mode)
{
str_of_column_mode(int mode) {
switch(mode) {
case Coldefault: return "default"; break;
case Colstack: return "stack"; break;
case Colmax: return "max"; break;
default: break;
}
return nil;
return NULL;
}
int
column_mode_of_str(char *arg)
{
column_mode_of_str(char *arg) {
if(!strncmp("default", arg, 8))
return Coldefault;
if(!strncmp("stack", arg, 6))
@ -33,8 +29,7 @@ column_mode_of_str(char *arg)
}
static void
relax_column(Area *a)
{
relax_column(Area *a) {
unsigned int frame_size, yoff, h;
Frame *f;
int hdiff;
@ -42,11 +37,9 @@ relax_column(Area *a)
if(!a->frame)
return;
frame_size = 0;
for(f=a->frame; f; f=f->anext)
frame_size++;
switch(a->mode) {
case Coldefault:
h = a->rect.height / frame_size;
@ -61,16 +54,14 @@ relax_column(Area *a)
yoff = a->rect.y;
break;
}
if(fallthrough) {
for(f=a->frame; f; f=f->anext) {
f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2;
f->rect.y = a->rect.y + (a->rect.height - f->rect.height) / 2;
//resize_client(f->client, &f->rect, True);
//resize_client(f->client, &f->rect, True);
}
return;
}
/* some relaxing from potential increment gaps */
h = 0;
for(f=a->frame; f; f=f->anext) {
@ -81,7 +72,6 @@ relax_column(Area *a)
else
h += f->rect.height;
}
hdiff = a->rect.height - h;
if((a->mode == Coldefault) && (hdiff > 0)) {
int hx;
@ -93,7 +83,6 @@ relax_column(Area *a)
hdiff -= (f->rect.height - tmp);
}
}
if(hdiff < 0)
hdiff = 0;
hdiff /= frame_size;
@ -109,8 +98,7 @@ relax_column(Area *a)
}
void
scale_column(Area *a, float h)
{
scale_column(Area *a, float h) {
unsigned int yoff, frame_size = 0;
Frame *f;
unsigned int min_height = 2 * blitz_labelh(&def.font);
@ -119,10 +107,8 @@ scale_column(Area *a, float h)
if(!a->frame)
return;
for(f=a->frame; f; f=f->anext, frame_size++)
dy += f->rect.height;
scale = h / dy;
yoff = 0;
for(f=a->frame; f; f=f->anext) {
@ -131,7 +117,6 @@ scale_column(Area *a, float h)
f->rect.height = h - yoff;
yoff += f->rect.height;
}
/* min_height can only be respected when there is enough space; the caller should guarantee this */
if(frame_size * min_height > h)
return;
@ -148,18 +133,15 @@ scale_column(Area *a, float h)
}
void
arrange_column(Area *a, Bool dirty)
{
arrange_column(Area *a, Bool dirty) {
Frame *f;
unsigned int num_frames = 0, yoff = a->rect.y, h;
unsigned int min_height = 2 * blitz_labelh(&def.font);
if(a->floating || !a->frame)
return;
for(f=a->frame; f; f=f->anext)
num_frames++;
switch(a->mode) {
case Coldefault:
h = a->rect.height / num_frames;
@ -204,14 +186,12 @@ Fallthrough:
default:
break;
}
relax_column(a);
flush_masked_events(EnterWindowMask);
}
static void
match_horiz(Area *a, XRectangle *r)
{
match_horiz(Area *a, XRectangle *r) {
Frame *f;
for(f=a->frame; f; f=f->anext) {
@ -222,21 +202,18 @@ match_horiz(Area *a, XRectangle *r)
}
static void
drop_resize(Frame *f, XRectangle *new)
{
Area *west = nil, *east = nil, *a = f->area;
drop_resize(Frame *f, XRectangle *new) {
Area *west = NULL, *east = NULL, *a = f->area;
View *v = a->view;
Frame *north = nil, *south = nil;
Frame *north = NULL, *south = NULL;
unsigned int min_height = 2 * blitz_labelh(&def.font);
unsigned int min_width = screen->rect.width/NCOL;
for(west=v->area->next; west && west->next != a; west=west->next);
/* first managed area is indexed 1, thus (i > 1) ? ... */
east = a->next;
for(north=a->frame; north && north->anext != f; north=north->anext);
south = f->anext;
/* validate (and trim if necessary) horizontal resize */
if(new->width < min_width) {
if(new->x + new->width == f->rect.x + f->rect.width)
@ -259,7 +236,6 @@ drop_resize(Frame *f, XRectangle *new)
new->width = (a->rect.x + a->rect.width) - new->x;
if(new->width < min_width)
goto AfterHorizontal;
/* horizontal resize */
if(west && (new->x != a->rect.x)) {
west->rect.width = new->x - west->rect.x;
@ -278,11 +254,9 @@ drop_resize(Frame *f, XRectangle *new)
relax_column(east);
}
AfterHorizontal:
/* skip vertical resize unless the column is in equal mode */
if(a->mode != Coldefault)
goto AfterVertical;
/* validate (and trim if necessary) vertical resize */
if(new->height < min_height) {
if(f->rect.height < min_height
@ -303,14 +277,13 @@ AfterHorizontal:
}
if(new->height < min_height)
goto AfterVertical;
/* vertical resize */
if(north && (new->y != f->rect.y)) {
north->rect.height = new->y - north->rect.y;
f->rect.height += f->rect.y - new->y;
f->rect.y = new->y;
//resize_client(north->client, &north->rect, True);
//resize_client(f->client, &f->rect, True);
//resize_client(north->client, &north->rect, True);
//resize_client(f->client, &f->rect, True);
}
if(south && (new->y + new->height != f->rect.y + f->rect.height)) {
south->rect.height -= new->y + new->height - south->rect.y;
@ -321,21 +294,18 @@ AfterHorizontal:
//resize_client(south->client, &south->rect, True);
}
AfterVertical:
relax_column(a);
focus_view(screen, v);
}
static Frame *
frame_of_point(XPoint *pt)
{
frame_of_point(XPoint *pt) {
Area *a;
View *v = screen->sel;
Frame *f = nil;
Frame *f = NULL;
if(!v)
return nil;
return NULL;
for(a=v->area->next; a && !ispointinrect(pt->x, pt->y, &a->rect);
a=a->next);
if(a)
@ -345,19 +315,16 @@ frame_of_point(XPoint *pt)
}
static void
drop_move(Frame *f, XRectangle *new, XPoint *pt)
{
drop_move(Frame *f, XRectangle *new, XPoint *pt) {
Area *tgt, *src;
Frame *ft;
View *v;
tgt = nil;
tgt = NULL;
src = f->area;
v = src->view;
if(!pt)
return;
for(tgt=v->area->next; tgt && !ispointinrect(pt->x, pt->y, &tgt->rect);
tgt=tgt->next);
if(tgt) {
@ -381,15 +348,12 @@ drop_move(Frame *f, XRectangle *new, XPoint *pt)
return;
before = pt->y < (ft->rect.y + ft->rect.height / 2);
send_to_area(tgt, src, f);
f = c->sel;
remove_frame(f);
if(before)
insert_frame(ft, f, True);
else
insert_frame(ft, f, False);
tgt->sel = f;
arrange_column(tgt, False);
}
@ -397,12 +361,10 @@ drop_move(Frame *f, XRectangle *new, XPoint *pt)
if(!(ft = frame_of_point(pt)) || (f == ft))
return;
remove_frame(f);
if(pt->y < (ft->rect.y + ft->rect.height / 2))
insert_frame(ft, f, True);
else
insert_frame(ft, f, False);
tgt->sel = f;
arrange_column(tgt, False);
}
@ -410,8 +372,7 @@ drop_move(Frame *f, XRectangle *new, XPoint *pt)
}
void
resize_column(Client *c, XRectangle *r, XPoint *pt)
{
resize_column(Client *c, XRectangle *r, XPoint *pt) {
Frame *f = c->sel;
if((f->rect.width == r->width) && (f->rect.height == r->height))
drop_move(f, r, pt);
@ -423,7 +384,7 @@ Area *
new_column(View *v, Area *pos, unsigned int w) {
Area *a = create_area(v, pos, w);
if(!a)
return nil;
return NULL;
arrange_view(v);
return a;
}

View File

@ -1,29 +1,25 @@
# Customize to fit your system
# wmii version
VERSION = 3.5
# Customize below to fit your system
# paths
PREFIX = /usr/local
CONFPREFIX = ${PREFIX}/etc
MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
VERSION = 3.5
# includes and libs
LIBS = -L${PREFIX}/lib -L/usr/lib -lc
X11LIBS = -L${X11LIB} -lX11
INCS = -I. -I${PREFIX}/include -I/usr/include -I${X11INC}
LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -L${PREFIX} -lixp -lm
# Linux/BSD
CFLAGS = -g -Wall -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \
-DVERSION=\"${VERSION}\"
LDFLAGS = -g ${LIBS}
X11LDFLAGS = ${LDFLAGS} ${X11LIBS}
# flags
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = ${LIBS}
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS}
# Solaris
#CFLAGS = -fast -xtarget=ultra ${INCLUDES} -DVERSION=\"${VERSION}\"
#LIBS += -lnsl -lsocket
AR = ar cr
# compiler and linker
CC = cc
RANLIB = ranlib
LD = ${CC}

View File

@ -1,10 +1,7 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include <stdio.h>
#include "blitz.h"
#include "wm.h"
void
blitz_drawbg(Display *dpy, Drawable drawable, GC gc, XRectangle rect,

61
event.c
View File

@ -1,15 +1,12 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <X11/keysym.h>
#include "wm.h"
/* local functions */
static void buttonpress(XEvent *e);
static void buttonrelease(XEvent *e);
@ -40,8 +37,7 @@ void (*handler[LASTEvent]) (XEvent *) = {
};
void
check_x_event(IXPConn *c)
{
check_x_event(IXPConn *c) {
XEvent ev;
while(XPending(blz.dpy)) { /* main event loop */
XNextEvent(blz.dpy, &ev);
@ -51,8 +47,7 @@ check_x_event(IXPConn *c)
}
unsigned int
flush_masked_events(long even_mask)
{
flush_masked_events(long even_mask) {
XEvent ev;
unsigned int n = 0;
while(XCheckMaskEvent(blz.dpy, even_mask, &ev)) n++;
@ -60,8 +55,7 @@ flush_masked_events(long even_mask)
}
static void
buttonrelease(XEvent *e)
{
buttonrelease(XEvent *e) {
Frame *f;
Bar *b;
XButtonPressedEvent *ev = &e->xbutton;
@ -80,8 +74,7 @@ buttonrelease(XEvent *e)
}
static void
buttonpress(XEvent *e)
{
buttonpress(XEvent *e) {
Frame *f;
XButtonPressedEvent *ev = &e->xbutton;
@ -105,8 +98,7 @@ buttonpress(XEvent *e)
}
static void
configurerequest(XEvent *e)
{
configurerequest(XEvent *e) {
XConfigureRequestEvent *ev = &e->xconfigurerequest;
XWindowChanges wc;
XRectangle *frect;
@ -116,7 +108,6 @@ configurerequest(XEvent *e)
ev->value_mask &= ~CWSibling;
if(c) {
gravitate_client(c, True);
if(ev->value_mask & CWX)
c->rect.x = ev->x;
if(ev->value_mask & CWY)
@ -127,15 +118,12 @@ configurerequest(XEvent *e)
c->rect.height = ev->height;
if(ev->value_mask & CWBorderWidth)
c->border = ev->border_width;
gravitate_client(c, False);
if(c->frame) {
if(c->sel->area->floating)
frect=&c->sel->rect;
else
frect=&c->sel->revert;
if(c->rect.width >= screen->rect.width && c->rect.height >= screen->rect.height) {
frect->y = wc.y = -blitz_labelh(&def.font);
frect->x = wc.x = -def.border;
@ -158,32 +146,27 @@ configurerequest(XEvent *e)
}
}
}
wc.x = ev->x;
wc.y = ev->y;
wc.width = ev->width;
wc.height = ev->height;
if(c && c->frame) {
wc.x = def.border;
wc.y = blitz_labelh(&def.font);
wc.width = c->sel->rect.width - 2 * def.border;
wc.height = c->sel->rect.height - def.border - blitz_labelh(&def.font);
}
wc.border_width = 0;
wc.sibling = None;
wc.stack_mode = Above;
ev->value_mask &= ~CWStackMode;
ev->value_mask |= CWBorderWidth;
XConfigureWindow(blz.dpy, ev->window, ev->value_mask, &wc);
XSync(blz.dpy, False);
}
static void
destroynotify(XEvent *e)
{
destroynotify(XEvent *e) {
Client *c;
XDestroyWindowEvent *ev = &e->xdestroywindow;
@ -192,14 +175,12 @@ destroynotify(XEvent *e)
}
static void
enternotify(XEvent *e)
{
enternotify(XEvent *e) {
XCrossingEvent *ev = &e->xcrossing;
Client *c;
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
return;
if((c = client_of_win(ev->window))) {
Frame *f = c->sel;
Area *a = f->area;
@ -214,8 +195,7 @@ enternotify(XEvent *e)
}
static void
leavenotify(XEvent *e)
{
leavenotify(XEvent *e) {
XCrossingEvent *ev = &e->xcrossing;
if((ev->window == blz.root) && !ev->same_screen) {
@ -225,8 +205,7 @@ leavenotify(XEvent *e)
}
static void
expose(XEvent *e)
{
expose(XEvent *e) {
XExposeEvent *ev = &e->xexpose;
static Frame *f;
@ -239,8 +218,7 @@ expose(XEvent *e)
}
static void
keypress(XEvent *e)
{
keypress(XEvent *e) {
XKeyEvent *ev = &e->xkey;
KeySym k = 0;
char buf[32];
@ -262,8 +240,7 @@ keypress(XEvent *e)
}
static void
mappingnotify(XEvent *e)
{
mappingnotify(XEvent *e) {
XMappingEvent *ev = &e->xmapping;
XRefreshKeyboardMapping(ev);
@ -272,40 +249,34 @@ mappingnotify(XEvent *e)
}
static void
maprequest(XEvent *e)
{
maprequest(XEvent *e) {
XMapRequestEvent *ev = &e->xmaprequest;
static XWindowAttributes wa;
if(!XGetWindowAttributes(blz.dpy, ev->window, &wa))
return;
if(wa.override_redirect) {
XSelectInput(blz.dpy, ev->window,
(StructureNotifyMask | PropertyChangeMask));
return;
}
if(!client_of_win(ev->window))
manage_client(create_client(ev->window, &wa));
}
static void
propertynotify(XEvent *e)
{
propertynotify(XEvent *e) {
XPropertyEvent *ev = &e->xproperty;
Client *c;
if(ev->state == PropertyDelete)
return; /* ignore */
if((c = client_of_win(ev->window)))
prop_client(c, ev);
}
static void
unmapnotify(XEvent *e)
{
unmapnotify(XEvent *e) {
Client *c;
XUnmapEvent *ev = &e->xunmap;

View File

@ -1,17 +1,14 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include "blitz.h"
unsigned int
blitz_textwidth_l(BlitzFont *font, char *text, unsigned int len)
{
blitz_textwidth_l(BlitzFont *font, char *text, unsigned int len) {
if(font->set) {
XRectangle r;
XmbTextExtents(font->set, text, len, NULL, &r);
@ -21,14 +18,12 @@ blitz_textwidth_l(BlitzFont *font, char *text, unsigned int len)
}
unsigned int
blitz_textwidth(BlitzFont *font, char *text)
{
blitz_textwidth(BlitzFont *font, char *text) {
return blitz_textwidth_l(font, text, strlen(text));
}
void
blitz_loadfont(Blitz *blitz, BlitzFont *font)
{
blitz_loadfont(Blitz *blitz, BlitzFont *font) {
char *fontname = font->fontstr;
char **missing = NULL, *def = "?";
int n;
@ -51,7 +46,6 @@ blitz_loadfont(Blitz *blitz, BlitzFont *font)
XFontStruct **xfonts;
char **font_names;
unsigned int i;
font->ascent = font->descent = 0;
font_extents = XExtentsOfFontSet(font->set);
n = XFontsOfFontSet(font->set, &xfonts, &font_names);
@ -83,7 +77,6 @@ blitz_loadfont(Blitz *blitz, BlitzFont *font)
}
unsigned int
blitz_labelh(BlitzFont *font)
{
blitz_labelh(BlitzFont *font) {
return font->height + 4;
}

39
frame.c
View File

@ -1,23 +1,18 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <stdlib.h>
#include <string.h>
#include "wm.h"
Frame *
create_frame(Client *c, View *v)
{
create_frame(Client *c, View *v) {
static unsigned short id = 1;
Frame *f = cext_emallocz(sizeof(Frame));
Frame *f = ixp_emallocz(sizeof(Frame));
f->id = id++;
f->client = c;
f->view = v;
if(c->frame) {
f->revert = c->sel->revert;
f->rect = c->sel->rect;
@ -28,7 +23,6 @@ create_frame(Client *c, View *v)
f->revert.height = f->rect.height += def.border + blitz_labelh(&def.font);
}
f->collapsed = False;
f->tile.blitz = &blz;
f->tile.drawable = pmap;
f->tile.gc = c->gc;
@ -42,20 +36,18 @@ create_frame(Client *c, View *v)
}
void
remove_frame(Frame *f)
{
remove_frame(Frame *f) {
Area *a = f->area;
Frame **ft = &a->frame;
for(; *ft && *ft != f; ft=&(*ft)->anext);
cext_assert(*ft == f);
*ft = f->anext;
}
void
insert_frame(Frame *pos, Frame *f, Bool before)
{
insert_frame(Frame *pos, Frame *f, Bool before) {
Area *a = f->area;
if(before) {
Frame *ft;
for(ft=a->frame; ft && ft->anext != pos; ft=ft->anext);
@ -67,13 +59,11 @@ insert_frame(Frame *pos, Frame *f, Bool before)
}
void
update_frame_widget_colors(Frame *f)
{
if(sel_screen && (f->client == sel_client()))
update_frame_widget_colors(Frame *f) {
if(sel_screen && (f->client == sel_client()))
f->tile.color = f->titlebar.color = def.selcolor;
else
f->tile.color = f->titlebar.color = def.normcolor;
if(f->area->sel == f)
f->grabbox.color = def.selcolor;
else
@ -81,21 +71,17 @@ update_frame_widget_colors(Frame *f)
}
void
draw_frame(Frame *f)
{
draw_frame(Frame *f) {
if(def.border) {
f->tile.rect = f->rect;
f->tile.rect.x = f->tile.rect.y = 0;
}
f->grabbox.rect = f->tile.rect;
f->grabbox.rect.height = blitz_labelh(&def.font);
f->grabbox.rect.width = def.font.height;
f->titlebar.rect = f->grabbox.rect;
f->titlebar.rect.x = f->grabbox.rect.x + f->grabbox.rect.width;
f->titlebar.rect.width = f->rect.width - f->titlebar.rect.x;
blitz_draw_tile(&f->tile);
blitz_draw_tile(&f->grabbox);
blitz_draw_label(&f->titlebar, f->client->name);
@ -105,13 +91,12 @@ draw_frame(Frame *f)
}
void
draw_frames()
{
draw_frames() {
Client *c;
for(c=client; c; c=c->next)
if(c->sel && c->sel->view == screen->sel) {
update_frame_widget_colors(c->sel);
draw_frame(c->sel);
}
}

209
fs.c
View File

@ -1,15 +1,14 @@
/*
* (C)opyright MMVI Kris Maglione <fbsdaemon at gmail dot com>
/* (C)opyright MMVI Kris Maglione <fbsdaemon at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "wm.h"
/* Datatypes: */
/**************/
@ -71,8 +70,8 @@ static char
/* Global Vars */
/***************/
FileId *free_fileid = nil;
P9Req *pending_event_reads = nil;
FileId *free_fileid = NULL;
P9Req *pending_event_reads = NULL;
FidLink *pending_event_fids;
P9Srv p9srv = {
.open= fs_open,
@ -101,25 +100,25 @@ dirtab_root[]= {{".", P9QTDIR, FsRoot, 0500|P9DMDIR },
{"event", P9QTFILE, FsFEvent, 0600 },
{"keys", P9QTFILE, FsFKeys, 0600 },
{"tagrules", P9QTFILE, FsFTagRules, 0600 },
{nil}},
{NULL}},
dirtab_clients[]={{".", P9QTDIR, FsDClients, 0500|P9DMDIR },
{"", P9QTDIR, FsDClient, 0500|P9DMDIR },
{nil}},
{NULL}},
dirtab_client[]= {{".", P9QTDIR, FsDClient, 0500|P9DMDIR },
{"ctl", P9QTAPPEND, FsFCctl, 0600|P9DMAPPEND },
{"tags", P9QTFILE, FsFCtags, 0600 },
{"props", P9QTFILE, FsFprops, 0400 },
{nil}},
{NULL}},
dirtab_bars[]= {{".", P9QTDIR, FsDBars, 0700|P9DMDIR },
{"", P9QTFILE, FsFBar, 0600 },
{nil}},
{NULL}},
dirtab_tags[]= {{".", P9QTDIR, FsDTags, 0500|P9DMDIR },
{"", P9QTDIR, FsDTag, 0500|P9DMDIR },
{nil}},
{NULL}},
dirtab_tag[]= {{".", P9QTDIR, FsDTag, 0500|P9DMDIR },
{"ctl", P9QTAPPEND, FsFTctl, 0600|P9DMAPPEND },
{"index", P9QTFILE, FsFTindex, 0400 },
{nil}};
{NULL}};
/* Writing the lists separately and using an array of their references
* removes the need for casting and allows for C90 conformance,
* since otherwise we would need to use compound literals */
@ -143,7 +142,7 @@ get_file() {
FileId *temp;
if(!free_fileid) {
unsigned int i = 15;
temp = cext_emallocz(sizeof(FileId) * i);
temp = ixp_emallocz(sizeof(FileId) * i);
for(; i; i--) {
temp->next = free_fileid;
free_fileid = temp++;
@ -152,7 +151,7 @@ get_file() {
temp = free_fileid;
free_fileid = temp->next;
temp->nref = 1;
temp->next = nil;
temp->next = NULL;
return temp;
}
@ -170,7 +169,7 @@ free_file(FileId *f) {
static void
clone_files(FileId *f) {
for(; f; f=f->next)
cext_assert(f->nref++);
assert(f->nref++);
}
/* This should be moved to libixp */
@ -182,7 +181,7 @@ write_buf(P9Req *r, void *buf, unsigned int len) {
len -= r->ifcall.offset;
if(len > r->ifcall.count)
len = r->ifcall.count;
r->ofcall.data = cext_emalloc(len);
r->ofcall.data = ixp_emalloc(len);
memcpy(r->ofcall.data, buf + r->ifcall.offset, len);
r->ofcall.count = len;
}
@ -205,7 +204,7 @@ write_to_buf(P9Req *r, void *buf, unsigned int *len, unsigned int max) {
*len = offset + count;
if(max == 0) {
*(void **)buf = cext_erealloc(*(void **)buf, *len + 1);
*(void **)buf = ixp_erealloc(*(void **)buf, *len + 1);
buf = *(void **)buf;
}
@ -220,8 +219,8 @@ data_to_cstring(P9Req *r) {
unsigned int i;
i = r->ifcall.count;
if(!i || r->ifcall.data[i - 1] != '\n')
r->ifcall.data = cext_erealloc(r->ifcall.data, ++i);
cext_assert(r->ifcall.data);
r->ifcall.data = ixp_erealloc(r->ifcall.data, ++i);
assert(r->ifcall.data);
r->ifcall.data[i - 1] = '\0';
}
@ -240,7 +239,7 @@ parse_colors(char **buf, int *buflen, BlitzColor *col) {
(*buf)++;
(*buflen)--;
}
return nil;
return NULL;
}
char *
@ -252,7 +251,6 @@ message_root(char *message)
snprintf(buffer, BUFFER_SIZE, "%s ", message);
message = buffer;
}
if(!strncmp(message, "quit ", 5))
srv.running = 0;
else if(!strncmp(message, "view ", 5))
@ -261,52 +259,58 @@ message_root(char *message)
message += 10;
n = strlen(message);
return parse_colors(&message, (int *)&n, &def.selcolor);
}else if(!strncmp(message, "normcolors ", 11)) {
}
else if(!strncmp(message, "normcolors ", 11)) {
message += 11;
n = strlen(message);
return parse_colors(&message, (int *)&n, &def.normcolor);
}else if(!strncmp(message, "b1colors ", 9)) {
}
else if(!strncmp(message, "b1colors ", 9)) {
message += 9;
n = strlen(message);
return parse_colors(&message, (int *)&n, &def.bcolor[0]);
}else if(!strncmp(message, "b2colors ", 9)) {
}
else if(!strncmp(message, "b2colors ", 9)) {
message += 9;
n = strlen(message);
return parse_colors(&message, (int *)&n, &def.bcolor[1]);
}else if(!strncmp(message, "b3colors ", 9)) {
}
else if(!strncmp(message, "b3colors ", 9)) {
message += 9;
n = strlen(message);
return parse_colors(&message, (int *)&n, &def.bcolor[2]);
}else if(!strncmp(message, "font ", 5)) {
}
else if(!strncmp(message, "font ", 5)) {
message += 5;
free(def.font.fontstr);
def.font.fontstr = cext_estrdup(message);
def.font.fontstr = ixp_estrdup(message);
blitz_loadfont(&blz, &def.font);
}else if(!strncmp(message, "border ", 7)) {
}
else if(!strncmp(message, "border ", 7)) {
message += 7;
n = (unsigned int)strtol(message, &message, 10);
if(*message)
return Ebadvalue;
def.border = n;
}else if(!strncmp(message, "grabmod ", 8)) {
}
else if(!strncmp(message, "grabmod ", 8)) {
message += 8;
unsigned long mod;
mod = mod_key_of_str(message);
if(!(mod & (Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)))
return Ebadvalue;
cext_strlcpy(def.grabmod, message, sizeof(def.grabmod));
strncpy(def.grabmod, message, sizeof(def.grabmod));
def.mod = mod;
if(view)
restack_view(screen->sel);
}else
}
else
return Ebadcmd;
return nil;
return NULL;
}
char *
read_root_ctl()
{
read_root_ctl() {
unsigned int i = 0;
if(screen->sel)
i += snprintf(&buffer[i], (BUFFER_SIZE - i), "view %s\n", screen->sel->name);
@ -325,8 +329,8 @@ respond_event(P9Req *r) {
if(f->buf) {
r->ofcall.data = (void *)f->buf;
r->ofcall.count = strlen(f->buf);
respond(r, nil);
f->buf = nil;
respond(r, NULL);
f->buf = NULL;
}else{
r->aux = pending_event_reads;
pending_event_reads = r;
@ -344,13 +348,12 @@ write_event(char *format, ...) {
va_start(ap, format);
vsnprintf(buffer, BUFFER_SIZE, format, ap);
va_end(ap);
if(!(len = strlen(buffer)))
return;
for(f=pending_event_fids; f; f=f->next) {
fi = f->fid->aux;
slen = fi->buf ? strlen(fi->buf) : 0;
fi->buf = cext_erealloc(fi->buf, slen + len + 1);
fi->buf = ixp_erealloc(fi->buf, slen + len + 1);
fi->buf[slen] = '\0';
strcat(fi->buf, buffer);
}
@ -368,8 +371,8 @@ dostat(Stat *s, unsigned int len, FileId *f) {
s->qid.version = 0;
s->qid.type = f->tab.qtype;
s->mode = f->tab.perm;
s->atime = time(nil);
s->mtime = time(nil);
s->atime = time(NULL);
s->mtime = time(NULL);
s->length = len;
s->name = f->tab.name;
s->uid = user;
@ -392,12 +395,10 @@ lookup_file(FileId *parent, char *name)
unsigned int i, id;
if(!(parent->tab.perm & P9DMDIR))
return nil;
return NULL;
dir = dirtab[parent->tab.type];
last = &ret;
ret = nil;
ret = NULL;
for(; dir->name; dir++) {
/* Dynamic dirs */
if(!*dir->name) { /* strlen(dir->name) == 0 */
@ -412,14 +413,13 @@ lookup_file(FileId *parent, char *name)
file->id = c->id;
file->index = idx_of_client(c);
file->tab = *dir;
file->tab.name = cext_estrdup("sel");
file->tab.name = ixp_estrdup("sel");
}if(name) goto LastItem;
}
if(name) {
id = (unsigned int)strtol(name, &name, 10);
if(*name) goto NextItem;
}
i=0;
for(c=client; c; c=c->next, i++) {
if(!name || i == id) {
@ -429,7 +429,7 @@ lookup_file(FileId *parent, char *name)
file->ref = c;
file->id = c->id;
file->tab = *dir;
file->tab.name = cext_emallocz(16);
file->tab.name = ixp_emallocz(16);
snprintf(file->tab.name, 16, "%d", i);
if(name) goto LastItem;
}
@ -444,7 +444,7 @@ lookup_file(FileId *parent, char *name)
file->ref = screen->sel;
file->id = screen->sel->id;
file->tab = *dir;
file->tab.name = cext_estrdup("sel");
file->tab.name = ixp_estrdup("sel");
}if(name) goto LastItem;
}
for(v=view; v; v=v->next) {
@ -455,7 +455,7 @@ lookup_file(FileId *parent, char *name)
file->ref = v;
file->id = v->id;
file->tab = *dir;
file->tab.name = cext_estrdup(v->name);
file->tab.name = ixp_estrdup(v->name);
if(name) goto LastItem;
}
}
@ -469,7 +469,7 @@ lookup_file(FileId *parent, char *name)
file->ref = b;
file->id = b->id;
file->tab = *dir;
file->tab.name = cext_estrdup(b->name);
file->tab.name = ixp_estrdup(b->name);
if(name) goto LastItem;
}
}
@ -484,8 +484,7 @@ lookup_file(FileId *parent, char *name)
file->ref = parent->ref;
file->index = parent->index;
file->tab = *dir;
file->tab.name = cext_estrdup(file->tab.name);
file->tab.name = ixp_estrdup(file->tab.name);
/* Special considerations: */
switch(file->tab.type) {
case FsDBars:
@ -507,7 +506,7 @@ lookup_file(FileId *parent, char *name)
continue;
}
LastItem:
*last = nil;
*last = NULL;
return ret;
}
@ -517,13 +516,13 @@ void
fs_attach(P9Req *r) {
FileId *f = get_file();
f->tab = dirtab[FsRoot][0];
f->tab.name = cext_estrdup("/");
f->ref = nil; /* shut up valgrind */
f->tab.name = ixp_estrdup("/");
f->ref = NULL; /* shut up valgrind */
r->fid->aux = f;
r->fid->qid.type = f->tab.qtype;
r->fid->qid.path = QID(f->tab.type, 0);
r->ofcall.qid = r->fid->qid;
respond(r, nil);
respond(r, NULL);
}
void
@ -532,7 +531,6 @@ fs_walk(P9Req *r) {
int i;
f = r->fid->aux;
clone_files(f);
for(i=0; i < r->ifcall.nwname; i++) {
if(!strncmp(r->ifcall.wname[i], "..", 3)) {
@ -545,7 +543,7 @@ fs_walk(P9Req *r) {
nf = lookup_file(f, r->ifcall.wname[i]);
if(!nf)
break;
cext_assert(!nf->next);
assert(!nf->next);
if(strncmp(r->ifcall.wname[i], ".", 2)) {
nf->next = f;
f = nf;
@ -562,7 +560,6 @@ fs_walk(P9Req *r) {
}
return respond(r, Enofile);
}
/* Remove refs for r->fid if no new fid */
/* If Fids were ref counted, this could be
* done in their decref function */
@ -574,10 +571,9 @@ fs_walk(P9Req *r) {
free_file(nf);
}
}
r->newfid->aux = f;
r->ofcall.nwqid = i;
respond(r, nil);
respond(r, NULL);
}
unsigned int
@ -605,11 +601,10 @@ fs_stat(P9Req *r) {
dostat(&s, fs_size(r->fid->aux), r->fid->aux);
r->ofcall.nstat = size = ixp_sizeof_stat(&s);
buf = cext_emallocz(size);
buf = ixp_emallocz(size);
r->ofcall.stat = buf;
ixp_pack_stat(&buf, &size, &s);
respond(r, nil);
respond(r, NULL);
}
void
@ -621,15 +616,13 @@ fs_read(P9Req *r) {
offset = 0;
f = r->fid->aux;
if(f->tab.perm & P9DMDIR && f->tab.perm & 0400) {
Stat s;
offset = 0;
size = r->ifcall.count;
buf = cext_emallocz(size);
buf = ixp_emallocz(size);
r->ofcall.data = buf;
tf = f = lookup_file(f, nil);
tf = f = lookup_file(f, NULL);
/* Note: f->tab.name == "." so we skip it */
for(f=f->next; f; f=f->next) {
dostat(&s, fs_size(f), f);
@ -641,52 +634,51 @@ fs_read(P9Req *r) {
}
offset += n;
}
while((f = tf)) {
tf=tf->next;
free_file(f);
}
r->ofcall.count = r->ifcall.count - size;
return respond(r, nil);
}else{
return respond(r, NULL);
}
else{
switch(f->tab.type) {
case FsFprops:
write_buf(r, (void *)f->client->props, strlen(f->client->props));
return respond(r, nil);
return respond(r, NULL);
case FsFColRules:
case FsFTagRules:
write_buf(r, (void *)f->rule->string, f->rule->size);
return respond(r, nil);
return respond(r, NULL);
case FsFKeys:
write_buf(r, (void *)def.keys, def.keyssz);
return respond(r, nil);
return respond(r, NULL);
case FsFCtags:
write_buf(r, (void *)f->client->tags, strlen(f->client->tags));
return respond(r, nil);
return respond(r, NULL);
case FsFTctl:
write_buf(r, (void *)f->view->name, strlen(f->view->name));
return respond(r, nil);
return respond(r, NULL);
case FsFBar:
write_buf(r, (void *)f->bar->buf, strlen(f->bar->buf));
return respond(r, nil);
return respond(r, NULL);
case FsFRctl:
buf = read_root_ctl();
write_buf(r, buf, strlen(buf));
return respond(r, nil);
return respond(r, NULL);
case FsFCctl:
if(r->ifcall.offset)
return respond(r, nil);
r->ofcall.data = cext_emallocz(16);
return respond(r, NULL);
r->ofcall.data = ixp_emallocz(16);
n = snprintf(r->ofcall.data, 16, "%d", f->index);
cext_assert(n >= 0);
assert(n >= 0);
r->ofcall.count = n;
return respond(r, nil);
return respond(r, NULL);
case FsFTindex:
buf = (char *)view_index(f->view);
n = strlen(buf);
write_buf(r, (void *)buf, n);
return respond(r, nil);
return respond(r, NULL);
case FsFEvent:
respond_event(r);
return;
@ -694,57 +686,56 @@ fs_read(P9Req *r) {
}
/* This is an assert because it should this should not be called if
* the file is not open for reading. */
cext_assert(!"Read called on an unreadable file");
assert(!"Read called on an unreadable file");
}
/* This function needs to be seriously cleaned up */
void
fs_write(P9Req *r) {
FileId *f;
char *errstr = nil;
char *errstr = NULL;
unsigned int i;
if(r->ifcall.count == 0)
return respond(r, nil);
return respond(r, NULL);
f = r->fid->aux;
switch(f->tab.type) {
case FsFColRules:
case FsFTagRules:
write_to_buf(r, &f->rule->string, &f->rule->size, 0);
return respond(r, nil);
return respond(r, NULL);
case FsFKeys:
write_to_buf(r, &def.keys, &def.keyssz, 0);
return respond(r, nil);
return respond(r, NULL);
case FsFCtags:
data_to_cstring(r);
i=strlen(f->client->tags);
write_to_buf(r, &f->client->tags, &i, 255);
r->ofcall.count = i- r->ifcall.offset;
return respond(r, nil);
return respond(r, NULL);
case FsFBar:
/* XXX: This should validate after each write */
i = strlen(f->bar->buf);
write_to_buf(r, &f->bar->buf, &i, 279);
r->ofcall.count = i - r->ifcall.offset;
return respond(r, nil);
return respond(r, NULL);
case FsFCctl:
data_to_cstring(r);
if((errstr = message_client(f->client, r->ifcall.data)))
return respond(r, errstr);
r->ofcall.count = r->ifcall.count;
return respond(r, nil);
return respond(r, NULL);
case FsFTctl:
data_to_cstring(r);
if((errstr = message_view(f->view, r->ifcall.data)))
return respond(r, errstr);
r->ofcall.count = r->ifcall.count;
return respond(r, nil);
return respond(r, NULL);
case FsFRctl:
data_to_cstring(r);
{ unsigned int n;
char *toks[32];
n = cext_tokenize(toks, 32, r->ifcall.data, '\n');
n = ixp_tokenize(toks, 32, r->ifcall.data, '\n');
for(i = 0; i < n; i++) {
if(errstr)
message_root(toks[i]);
@ -755,27 +746,28 @@ fs_write(P9Req *r) {
if(errstr)
return respond(r, errstr);
r->ofcall.count = r->ifcall.count;
return respond(r, nil);
return respond(r, NULL);
case FsFEvent:
if(r->ifcall.data[r->ifcall.count-1] == '\n')
write_event("%.*s", r->ifcall.count, r->ifcall.data);
else
write_event("%.*s\n", r->ifcall.count, r->ifcall.data);
r->ofcall.count = r->ifcall.count;
return respond(r, nil);
return respond(r, NULL);
}
/* This is an assert because it should this should not be called if
* the file is not open for writing. */
cext_assert(!"Write called on an unwritable file");
assert(!"Write called on an unwritable file");
}
void
fs_open(P9Req *r) {
FidLink *fl;
FileId *f = r->fid->aux;
switch(f->tab.type) {
case FsFEvent:
fl = cext_emallocz(sizeof(FidLink));
fl = ixp_emallocz(sizeof(FidLink));
fl->fid = r->fid;
fl->next = pending_event_fids;
pending_event_fids = fl;
@ -789,13 +781,13 @@ fs_open(P9Req *r) {
return respond(r, Enoperm);
if((r->ifcall.mode&~(3|P9OAPPEND|P9OTRUNC)))
return respond(r, Enoperm);
respond(r, nil);
respond(r, NULL);
}
void
fs_create(P9Req *r) {
FileId *f = r->fid->aux;
switch(f->tab.type) {
default:
/* XXX: This should be taken care of by the library */
@ -807,12 +799,11 @@ fs_create(P9Req *r) {
f = lookup_file(f, r->ifcall.name);
if(!f)
return respond(r, Enofile);
r->ofcall.qid.type = f->tab.qtype;
r->ofcall.qid.path = QID(f->tab.type, f->id);
f->next = r->fid->aux;
r->fid->aux = f;
respond(r, nil);
respond(r, NULL);
break;
}
}
@ -820,6 +811,7 @@ fs_create(P9Req *r) {
void
fs_remove(P9Req *r) {
FileId *f = r->fid->aux;
switch(f->tab.type) {
default:
/* XXX: This should be taken care of by the library */
@ -827,7 +819,7 @@ fs_remove(P9Req *r) {
case FsFBar:
destroy_bar(f->next->bar_p, f->bar);
draw_bar(screen);
respond(r, nil);
respond(r, NULL);
break;
}
}
@ -864,7 +856,7 @@ fs_clunk(P9Req *r) {
parse_colors(&buf, &i, &f->bar->brush.color);
while(i > 0 && buf[i - 1] == '\n')
buf[--i] = '\0';
cext_strlcpy(f->bar->text, buf, sizeof(f->bar->text));
strncpy(f->bar->text, buf, sizeof(f->bar->text));
draw_bar(screen);
break;
case FsFEvent:
@ -879,19 +871,20 @@ fs_clunk(P9Req *r) {
}
break;
}
respond(r, nil);
respond(r, NULL);
}
void
fs_flush(P9Req *r) {
P9Req **t;
for(t=&pending_event_reads; *t; t=(P9Req **)&(*t)->aux)
if(*t == r->oldreq) {
*t = (*t)->aux;
respond(r->oldreq, Einterrupted);
break;
}
respond(r, nil);
respond(r, NULL);
}
void

16
geom.c
View File

@ -1,22 +1,17 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <math.h>
#include "wm.h"
Bool
ispointinrect(int x, int y, XRectangle * r)
{
ispointinrect(int x, int y, XRectangle * r) {
return (x >= r->x) && (x <= r->x + r->width)
&& (y >= r->y) && (y <= r->y + r->height);
}
BlitzAlign
quadofcoord(XRectangle *rect, int x, int y)
{
quadofcoord(XRectangle *rect, int x, int y) {
BlitzAlign ret = 0;
x -= rect->x;
y -= rect->y;
@ -35,8 +30,7 @@ quadofcoord(XRectangle *rect, int x, int y)
/* Syntax: <x> <y> <width> <height> */
int
strtorect(XRectangle *r, const char *val)
{
strtorect(XRectangle *r, const char *val) {
XRectangle new;
if (!val)
return -1;

73
key.c
View File

@ -1,18 +1,14 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include "wm.h"
void
init_lock_keys()
{
init_lock_keys() {
XModifierKeymap *modmap;
KeyCode num_lock;
static int masks[] = {
@ -24,7 +20,6 @@ init_lock_keys()
num_lock_mask = 0;
modmap = XGetModifierMapping(blz.dpy);
num_lock = XKeysymToKeycode(blz.dpy, XStringToKeysym("Num_Lock"));
if(modmap && modmap->max_keypermod > 0) {
int max = (sizeof(masks) / sizeof(int)) * modmap->max_keypermod;
for(i = 0; i < max; i++)
@ -32,14 +27,13 @@ init_lock_keys()
num_lock_mask = masks[i / modmap->max_keypermod];
}
XFreeModifiermap(modmap);
valid_mask = 255 & ~(num_lock_mask | LockMask);
}
unsigned long
mod_key_of_str(char *val)
{
mod_key_of_str(char *val) {
unsigned long mod = 0;
if (strstr(val, "Shift"))
mod |= ShiftMask;
if (strstr(val, "Control"))
@ -58,8 +52,7 @@ mod_key_of_str(char *val)
}
static void
grab_key(Key *k)
{
grab_key(Key *k) {
XGrabKey(blz.dpy, k->key, k->mod, blz.root,
True, GrabModeAsync, GrabModeAsync);
if(num_lock_mask) {
@ -72,8 +65,7 @@ grab_key(Key *k)
}
static void
ungrab_key(Key *k)
{
ungrab_key(Key *k) {
XUngrabKey(blz.dpy, k->key, k->mod, blz.root);
if(num_lock_mask) {
XUngrabKey(blz.dpy, k->key, k->mod | num_lock_mask, blz.root);
@ -83,16 +75,14 @@ ungrab_key(Key *k)
}
static Key *
name2key(const char *name)
{
name2key(const char *name) {
Key *k;
for(k=key; k && strncmp(k->name, name, sizeof(k->name)); k=k->lnext);
return k;
}
static Key *
get_key(const char *name)
{
get_key(const char *name) {
char buf[128];
char *seq[8];
char *kstr;
@ -104,18 +94,16 @@ get_key(const char *name)
ungrab_key(k);
return k;
}
cext_strlcpy(buf, name, sizeof(buf));
toks = cext_tokenize(seq, 8, buf, ',');
strncpy(buf, name, sizeof(buf));
toks = ixp_tokenize(seq, 8, buf, ',');
for(i = 0; i < toks; i++) {
if(!k)
r = k = cext_emallocz(sizeof(Key));
r = k = ixp_emallocz(sizeof(Key));
else {
k->next = cext_emallocz(sizeof(Key));
k->next = ixp_emallocz(sizeof(Key));
k = k->next;
}
cext_strlcpy(k->name, name, sizeof(k->name));
strncpy(k->name, name, sizeof(k->name));
kstr = strrchr(seq[i], '-');
if(kstr)
kstr++;
@ -134,11 +122,11 @@ get_key(const char *name)
}
static void
next_keystroke(unsigned long *mod, KeyCode *code)
{
next_keystroke(unsigned long *mod, KeyCode *code) {
XEvent e;
KeySym sym;
*mod = 0;
do {
XMaskEvent(blz.dpy, KeyPressMask, &e);
*mod |= e.xkey.state & valid_mask;
@ -148,14 +136,12 @@ next_keystroke(unsigned long *mod, KeyCode *code)
}
static void
emulate_key_press(unsigned long mod, KeyCode key)
{
emulate_key_press(unsigned long mod, KeyCode key) {
XEvent e;
Window client_win;
int revert;
XGetInputFocus(blz.dpy, &client_win, &revert);
e.xkey.type = KeyPress;
e.xkey.time = CurrentTime;
e.xkey.window = client_win;
@ -169,9 +155,9 @@ emulate_key_press(unsigned long mod, KeyCode key)
}
static Key *
match_keys(Key *k, unsigned long mod, KeyCode keycode, Bool seq)
{
Key *ret = nil, *next;
match_keys(Key *k, unsigned long mod, KeyCode keycode, Bool seq) {
Key *ret = NULL, *next;
for(next = k->tnext; k; (k=next) && (next=k->tnext)) {
if(seq)
k = k->next;
@ -184,14 +170,12 @@ match_keys(Key *k, unsigned long mod, KeyCode keycode, Bool seq)
}
static void
kpress_seq(Window w, Key *done)
{
kpress_seq(Window w, Key *done) {
unsigned long mod;
KeyCode key;
Key *found;
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 */
@ -207,13 +191,11 @@ kpress_seq(Window w, Key *done)
}
void
kpress(Window w, unsigned long mod, KeyCode keycode)
{
Key *k;
kpress(Window w, unsigned long mod, KeyCode keycode) {
Key *k, *found;
for(k=key; k; k->tnext=k->lnext, k=k->lnext);
Key *found = match_keys(key, mod, keycode, False);
found = match_keys(key, mod, keycode, False);
if(!found) {
XBell(blz.dpy, 0);
} /* grabbed but not found */
@ -228,23 +210,19 @@ kpress(Window w, unsigned long mod, KeyCode keycode)
}
void
update_keys()
{
update_keys() {
Key *k, *n;
char *l, *p;
init_lock_keys();
while((k = key)) {
key = key->lnext;
ungrab_key(k);
while((n = k)) {
k = k->next;
free(n);
}
}
for(l = p = def.keys; p && *p;) {
if(*p == '\n') {
*p = 0;
@ -260,6 +238,5 @@ update_keys()
if((k = get_key(l)))
grab_key(k);
}
XSync(blz.dpy, False);
}

View File

@ -1,25 +0,0 @@
# liblitz - non wimp GUI toolkit
# (C)opyright MMIV-MMVI Anselm R. Garbe
include ../config.mk
CFLAGS += -I../libixp -I../libcext
LDFLAGS += -L../libixp -lixp -L../libcext -lcext
SRC = brush.c color.c draw.c font.c
OBJ = ${SRC:.c=.o}
all: liblitz.a
@echo built liblitz
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
liblitz.a: ${OBJ}
@echo AR $@
@${AR} $@ ${OBJ}
@${RANLIB} $@
clean:
rm -f liblitz.a *.o

View File

@ -1,85 +0,0 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include <X11/Xlib.h>
#include <X11/Xlocale.h>
#define BLITZ_FONT "fixed"
#define BLITZ_SELCOLORS "#ffffff #335577 #447799"
#define BLITZ_NORMCOLORS "#222222 #eeeeee #666666"
#define BLITZ_B1COLORS "#000000 #00ffff #000000"
#define BLITZ_B2COLORS "#000000 #ff0000 #000000"
#define BLITZ_B3COLORS "#000000 #00ff00 #000000"
typedef struct Blitz Blitz;
typedef enum BlitzAlign BlitzAlign;
typedef struct BlitzColor BlitzColor;
typedef struct BlitzFont BlitzFont;
typedef struct BlitzBrush BlitzBrush;
typedef struct BlitzInput BlitzInput;
struct Blitz {
Display *dpy;
int screen;
Window root;
};
enum BlitzAlign {
NORTH = 0x01,
EAST = 0x02,
SOUTH = 0x04,
WEST = 0x08,
NEAST = NORTH | EAST,
NWEST = NORTH | WEST,
SEAST = SOUTH | EAST,
SWEST = SOUTH | WEST,
CENTER = NEAST | SWEST
};
struct BlitzColor {
unsigned long bg;
unsigned long fg;
unsigned long border;
char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
};
struct BlitzFont {
XFontStruct *xfont;
XFontSet set;
int ascent;
int descent;
unsigned int height;
char *fontstr;
};
struct BlitzBrush {
Blitz *blitz;
Drawable drawable;
GC gc;
Bool border;
BlitzColor color;
BlitzAlign align;
BlitzFont *font;
XRectangle rect; /* relative rect */
};
/* brush.c */
extern void blitz_draw_label(BlitzBrush *b, char *text);
extern void blitz_draw_tile(BlitzBrush *b);
/* color.c */
extern int blitz_loadcolor(Blitz *blitz, BlitzColor *c);
/* draw.c */
extern void blitz_drawbg(Display *dpy, Drawable drawable, GC gc,
XRectangle rect, BlitzColor c, Bool border);
extern void blitz_drawcursor(Display *dpy, Drawable drawable, GC gc,
int x, int y, unsigned int h, BlitzColor c);
/* font.c */
extern unsigned int blitz_textwidth(BlitzFont *font, char *text);
extern unsigned int blitz_textwidth_l(BlitzFont *font, char *text, unsigned int len);
extern void blitz_loadfont(Blitz *blitz, BlitzFont *font);
extern unsigned int blitz_labelh(BlitzFont *font);

45
mouse.c
View File

@ -1,21 +1,17 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* (C)opyright MMVI Kris Maglione <fbsdaemon@gmail.com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "wm.h"
#define ButtonMask (ButtonPressMask | ButtonReleaseMask)
#define MouseMask (ButtonMask | PointerMotionMask)
static void
rect_morph_xy(XRectangle *rect, int dx, int dy, BlitzAlign *mask)
{
rect_morph_xy(XRectangle *rect, int dx, int dy, BlitzAlign *mask) {
BlitzAlign new_mask = 0;
if(*mask & NORTH) {
if(rect->height - dy >= 0 || *mask & SOUTH) {
@ -69,8 +65,7 @@ typedef struct {
} SnapArgs;
static void
snap_line(SnapArgs *a)
{
snap_line(SnapArgs *a) {
int i, t_xy;
/* horizontal */
@ -110,7 +105,7 @@ BlitzAlign
snap_rect(XRectangle *rects, int num, XRectangle *current,
BlitzAlign *mask, int snap)
{
SnapArgs a = { rects, num, 0, 0, 0, 0, *mask, nil };
SnapArgs a = { rects, num, 0, 0, 0, 0, *mask, NULL };
int dx = snap + 1, dy = snap + 1;
BlitzAlign ret;
@ -125,7 +120,6 @@ snap_rect(XRectangle *rects, int num, XRectangle *current,
a.y2 = a.y1 = current->y + current->height;
snap_line(&a);
}
a.y1 = current->y;
a.y2 = current->y + current->height;
a.delta = &dx;
@ -137,22 +131,18 @@ snap_rect(XRectangle *rects, int num, XRectangle *current,
a.x1 = a.x2 = current->x;
snap_line(&a);
}
rect_morph_xy(current, abs(dx) <= snap ? dx : 0,
abs(dy) <= snap ? dy : 0, mask);
ret = *mask;
if(abs(dx) <= snap)
ret ^= EAST|WEST;
if(abs(dy) <= snap)
ret ^= NORTH|SOUTH;
return ret ^ CENTER;
}
static void
draw_xor_border(XRectangle *r)
{
draw_xor_border(XRectangle *r) {
XRectangle xor = *r;
xor.x += 2;
@ -170,8 +160,7 @@ draw_xor_border(XRectangle *r)
}
void
do_mouse_resize(Client *c, BlitzAlign align)
{
do_mouse_resize(Client *c, BlitzAlign align) {
BlitzAlign grav;
int px, py, ox, oy, i;
float rx, ry;
@ -181,7 +170,7 @@ do_mouse_resize(Client *c, BlitzAlign align)
Frame *f = c->sel;
Bool floating = f->area->floating;
int snap = floating ? screen->rect.height / 66 : 0;
XRectangle *rects = floating ? rects_of_view(f->area->view, &num) : nil;
XRectangle *rects = floating ? rects_of_view(f->area->view, &num) : NULL;
XRectangle frect = f->rect, ofrect;
XRectangle origin = frect;
XPoint pt;
@ -189,7 +178,6 @@ do_mouse_resize(Client *c, BlitzAlign align)
XQueryPointer(blz.dpy, c->framewin, &dummy, &dummy, &i, &i, &ox, &oy, &di);
rx = (float)ox / frect.width;
ry = (float)oy / frect.height;
if (floating || align != CENTER) {
px = ox = frect.width / 2;
py = oy = frect.height / 2;
@ -201,18 +189,14 @@ do_mouse_resize(Client *c, BlitzAlign align)
ox += px;
if(align&WEST)
ox -= px;
XWarpPointer(blz.dpy, None, c->framewin, 0, 0, 0, 0, ox, oy);
}
XTranslateCoordinates(blz.dpy, c->framewin, blz.root, ox, oy, &ox, &oy, &dummy);
pt.x = ox; pt.y = oy;
XSync(blz.dpy, False);
if(XGrabPointer(blz.dpy, c->framewin, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize], CurrentTime) != GrabSuccess)
return;
XGrabServer(blz.dpy);
draw_xor_border(&frect);
for(;;) {
@ -221,7 +205,7 @@ do_mouse_resize(Client *c, BlitzAlign align)
case ButtonRelease:
draw_xor_border(&frect);
if(!floating)
resize_column(c, &frect, (align == CENTER) ? &pt : nil);
resize_column(c, &frect, (align == CENTER) ? &pt : NULL);
else
resize_client(c, &frect, False);
if(rects)
@ -229,29 +213,24 @@ do_mouse_resize(Client *c, BlitzAlign align)
XUngrabServer(blz.dpy);
XUngrabPointer(blz.dpy, CurrentTime);
XSync(blz.dpy, False);
XWarpPointer(blz.dpy, None, c->framewin, 0, 0, 0, 0,
frect.width * rx, frect.height * ry);
return;
break;
case MotionNotify:
ofrect = frect;
pt.x = ev.xmotion.x;
pt.y = ev.xmotion.y;
XTranslateCoordinates(blz.dpy, c->framewin, blz.root, ev.xmotion.x,
ev.xmotion.y, &px, &py, &dummy);
rect_morph_xy(&origin, px-ox, py-oy, &align);
frect=origin;
ox=px; oy=py;
if(floating)
grav = snap_rect(rects, num, &frect, &align, snap);
else
grav = align ^ CENTER;
match_sizehints(c, &frect, floating, grav);
draw_xor_border(&ofrect);
draw_xor_border(&frect);
break;
@ -264,8 +243,7 @@ do_mouse_resize(Client *c, BlitzAlign align)
}
void
grab_mouse(Window w, unsigned long mod, unsigned int button)
{
grab_mouse(Window w, unsigned long mod, unsigned int button) {
XGrabButton(blz.dpy, button, mod, w, False, ButtonMask,
GrabModeAsync, GrabModeSync, None, None);
if((mod != AnyModifier) && num_lock_mask) {
@ -277,8 +255,7 @@ grab_mouse(Window w, unsigned long mod, unsigned int button)
}
void
ungrab_mouse(Window w, unsigned long mod, unsigned int button)
{
ungrab_mouse(Window w, unsigned long mod, unsigned int button) {
XUngrabButton(blz.dpy, button, mod, w);
if(mod != AnyModifier && num_lock_mask) {
XUngrabButton(blz.dpy, button, mod | num_lock_mask, w);

27
rule.c
View File

@ -17,21 +17,32 @@ enum {
};
void
update_rules(Rule **rule, const char *data)
{
trim(char *str, const char *chars) {
const char *cp;
char *sp, *sn;
for(cp = chars; *cp; cp++) {
for(sp = sn = str; *sn; sn++) {
if(*sn != *cp)
*(sp++) = *sn;
}
*sp = 0;
}
}
void
update_rules(Rule **rule, const char *data) {
int mode = IGNORE;
Rule *rul;
char *p, *r = nil, *v = nil, regex[256], value[256];
char *p, *r = NULL, *v = NULL, regex[256], value[256];
if(!data || !strlen(data))
return;
while((rul = *rule)) {
*rule = rul->next;
regfree(&rul->regex);
free(rul);
}
for(p = (char *)data; *p; p++)
switch(mode) {
case IGNORE:
@ -57,11 +68,11 @@ update_rules(Rule **rule, const char *data)
break;
case VALUE:
if(*p == '\n' || *p == 0) {
*rule = cext_emallocz(sizeof(Rule));
*rule = ixp_emallocz(sizeof(Rule));
*v = 0;
cext_trim(value, " \t/");
trim(value, " \t/");
if(!regcomp(&(*rule)->regex, regex, 0)) {
cext_strlcpy((*rule)->value, value, sizeof(rul->value));
strncpy((*rule)->value, value, sizeof(rul->value));
rule = &(*rule)->next;
}
else free(*rule);

39
util.c Normal file
View File

@ -0,0 +1,39 @@
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
/* extern */
void *
emallocz(unsigned int size) {
void *res = calloc(1, size);
if(!res)
eprint("fatal: could not malloc() %u bytes\n", size);
return res;
}
void
eprint(const char *errstr, ...) {
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(EXIT_FAILURE);
}
void *
erealloc(void *ptr, unsigned int size) {
void *res = realloc(ptr, size);
if(!res)
eprint("fatal: could not malloc() %u bytes\n", size);
return res;
}

109
view.c
View File

@ -10,8 +10,7 @@
#include "wm.h"
static Bool
is_empty(View *v)
{
is_empty(View *v) {
Area *a;
for(a=v->area; a; a=a->next)
if(a->frame)
@ -20,8 +19,7 @@ is_empty(View *v)
}
Frame *
clientframe_of_view(View *v, Client *c)
{
clientframe_of_view(View *v, Client *c) {
Frame *f;
for(f=c->frame; f; f=f->cnext)
if(f->area->view == v)
@ -30,8 +28,7 @@ clientframe_of_view(View *v, Client *c)
}
static void
assign_sel_view(View *v)
{
assign_sel_view(View *v) {
if(screen->sel != v) {
if(screen->sel)
write_event("UnfocusTag %s\n",screen->sel->name);
@ -42,14 +39,14 @@ assign_sel_view(View *v)
Client *
sel_client_of_view(View *v) {
return v->sel && v->sel->sel ? v->sel->sel->client : nil;
return v->sel && v->sel->sel ? v->sel->sel->client : NULL;
}
View *
get_view(const char *name)
{
get_view(const char *name) {
View *v;
int cmp;
for(v = view; v; v=v->next)
if((cmp=strcmp(name, v->name)) >= 0)
break;
@ -59,32 +56,27 @@ get_view(const char *name)
}
View *
create_view(const char *name)
{
create_view(const char *name) {
static unsigned short id = 1;
View **i, *v = cext_emallocz(sizeof(View));
View **i, *v = ixp_emallocz(sizeof(View));
v->id = id++;
cext_strlcpy(v->name, name, sizeof(v->name));
create_area(v, nil, 0);
strncpy(v->name, name, sizeof(v->name));
create_area(v, NULL, 0);
create_area(v, v->area, 0);
v->area->floating = True;
for(i=&view; *i; i=&(*i)->next)
if(strcmp((*i)->name, name) < 0) break;
v->next = *i;
*i = v;
write_event("CreateTag %s\n", v->name);
if(!screen->sel)
assign_sel_view(v);
return v;
}
void
destroy_view(View *v)
{
destroy_view(View *v) {
Area *a;
View **i;
@ -92,40 +84,34 @@ destroy_view(View *v)
v->area = a->next;
destroy_area(a);
};
for(i=&view; *i; i=&(*i)->next)
if(*i == v) break;
*i = v->next;
if(screen->sel == v)
for(screen->sel=view; screen->sel && screen->sel->next; screen->sel=screen->sel->next)
if(screen->sel->next == *i) break;
write_event("DestroyTag %s\n", v->name);
free(v);
}
static void
update_frame_selectors(View *v)
{
update_frame_selectors(View *v) {
Area *a;
Frame *f;
for(a=v->area; a; a=a->next)
for(f=a->frame; f; f=f->anext)
f->client->sel = f;
}
void
focus_view(WMScreen *s, View *v)
{
focus_view(WMScreen *s, View *v) {
Frame *f;
Client *c;
XGrabServer(blz.dpy);
assign_sel_view(v);
update_frame_selectors(v);
/* gives all(!) clients proper geometry (for use of different tags) */
for(c=client; c; c=c->next)
if((f = c->sel)) {
@ -136,10 +122,8 @@ focus_view(WMScreen *s, View *v)
XMoveWindow(blz.dpy, c->framewin, 2 * s->rect.width + f->rect.x,
f->rect.y);
}
if((c = sel_client()))
focus_client(c, True);
draw_frames();
XSync(blz.dpy, False);
XUngrabServer(blz.dpy);
@ -147,11 +131,11 @@ focus_view(WMScreen *s, View *v)
}
void
select_view(const char *arg)
{
select_view(const char *arg) {
char buf[256];
cext_strlcpy(buf, arg, sizeof(buf));
cext_trim(buf, " \t+");
strncpy(buf, arg, sizeof(buf));
trim(buf, " \t+");
if(!strlen(buf))
return;
assign_sel_view(get_view(arg));
@ -159,13 +143,11 @@ select_view(const char *arg)
}
void
attach_to_view(View *v, Frame *f)
{
attach_to_view(View *v, Frame *f) {
Area *a;
Client *c = f->client;
c->revert = nil;
c->revert = NULL;
if(c->trans || c->floating || c->fixedsize
|| (c->rect.width == screen->rect.width && c->rect.height == screen->rect.height))
a = v->area;
@ -178,21 +160,19 @@ attach_to_view(View *v, Frame *f)
}
void
restack_view(View *v)
{
restack_view(View *v) {
Area *a;
Frame *f;
Client *c;
unsigned int n=0, i=0;
static Window *wins = nil;
static Window *wins = NULL;
static unsigned int winssz = 0;
for(c=client; c; c=c->next, i++);
if(i > winssz) {
winssz = 2 * i;
wins = cext_erealloc(wins, sizeof(Window) * winssz);
wins = ixp_erealloc(wins, sizeof(Window) * winssz);
}
for(a=v->area; a; a=a->next) {
if(a->frame) {
wins[n++] = a->sel->client->framewin;
@ -207,14 +187,12 @@ restack_view(View *v)
}
}
}
if(n)
XRestackWindows(blz.dpy, wins, n);
}
void
scale_view(View *v, float w)
{
scale_view(View *v, float w) {
unsigned int xoff, col_size = 0;
unsigned int min_width = screen->rect.width/NCOL;
Area *a;
@ -223,7 +201,6 @@ scale_view(View *v, float w)
if(!v->area->next)
return;
for(a=v->area->next; a; a=a->next, col_size++)
dx += a->rect.width;
scale = w / dx;
@ -234,7 +211,6 @@ scale_view(View *v, float w)
a->rect.width = w - xoff;
xoff += a->rect.width;
}
/* min_width can only be respected when there is enough space; the caller should guarantee this */
if(col_size * min_width > w)
return;
@ -251,14 +227,12 @@ scale_view(View *v, float w)
}
void
arrange_view(View *v)
{
arrange_view(View *v) {
unsigned int xoff = 0;
Area *a;
if(!v->area->next)
return;
scale_view(v, screen->rect.width);
for(a=v->area->next; a; a=a->next) {
a->rect.x = xoff;
@ -270,20 +244,17 @@ arrange_view(View *v)
}
XRectangle *
rects_of_view(View *v, unsigned int *num)
{
rects_of_view(View *v, unsigned int *num) {
XRectangle *result;
Frame *f;
*num = 2;
for(f=v->area->frame; f; f=f->anext, (*num)++);
result = cext_emallocz(*num * sizeof(XRectangle));
result = ixp_emallocz(*num * sizeof(XRectangle));
for(f=v->area->frame; f; f=f->anext)
*result++ = f->rect;
*result++ = screen->rect;
*result++ = screen->brect;
return result - *num;
}
@ -327,8 +298,7 @@ view_index(View *v) {
}
Client *
client_of_message(View *v, char *message, unsigned int *next)
{
client_of_message(View *v, char *message, unsigned int *next) {
unsigned int i;
Client *c;
@ -337,7 +307,7 @@ client_of_message(View *v, char *message, unsigned int *next)
return sel_client_of_view(v);
}
if((1 != sscanf(message, "%d %n", &i, next)))
return nil;
return NULL;
for(c=client; i && c; c=c->next, i--);
return c;
}
@ -354,7 +324,7 @@ area_of_message(View *v, char *message, unsigned int *next) {
if(!strncmp(message, "~ ", 2))
return v->area;
if(1 != sscanf(message, "%d %n", &i, next) || i == 0)
return nil;
return NULL;
for(a=v->area; i && a; a=a->next, i--);
return a;
}
@ -391,27 +361,23 @@ message_view(View *v, char *message) {
if(v == screen->sel)
focus_view(screen, v);
draw_frames();
return nil;
return NULL;
}
return Ebadvalue;
}
void
update_views()
{
update_views() {
View *n, *v;
View *old = screen->sel;
for(v=view; v; v=v->next)
update_frame_selectors(v);
if(old && !strncmp(old->name, "nil", 4))
old = nil;
if(old && !strncmp(old->name, "NULL", 4))
old = NULL;
for((v=view) && (n=v->next); v; (v=n) && (n=v->next))
if((v != old) && is_empty(v))
destroy_view(v);
if(old)
focus_view(screen, old);
else if(screen->sel)
@ -419,8 +385,7 @@ update_views()
}
unsigned int
newcolw_of_view(View *v)
{
newcolw_of_view(View *v) {
Rule *r;
Area *a;
unsigned int i, n;
@ -430,8 +395,8 @@ newcolw_of_view(View *v)
if(!regexec(&r->regex, v->name, 1, &tmpregm, 0)) {
char buf[256];
char *toks[16];
cext_strlcpy(buf, r->value, sizeof(buf));
n = cext_tokenize(toks, 16, buf, '+');
strncpy(buf, r->value, sizeof(buf));
n = ixp_tokenize(toks, 16, buf, '+');
for(a=v->area, i=0; a; a=a->next, i++);
if(n && n >= i) {
if(sscanf(toks[i - 1], "%u", &n) == 1)

127
wm.c
View File

@ -1,8 +1,7 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "wm.h"
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
@ -18,31 +17,18 @@
#include <X11/Xatom.h>
#include <X11/Xproto.h>
#include "wm.h"
static int other_wm_running;
static int (*x_error_handler) (Display *, XErrorEvent *);
static char version[] = "wmiiwm - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Garbe\n";
static void
usage()
{
usage() {
fputs("usage: wmiiwm -a <address> [-r <wmiirc>] [-v]\n", stderr);
exit(1);
}
static void
error(char *errstr, ...) {
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(1);
}
static void
scan_wins()
{
scan_wins() {
int i;
unsigned int num;
Window *wins;
@ -64,8 +50,7 @@ scan_wins()
}
static int
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
{
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) {
Atom real;
int format;
unsigned long res, extra;
@ -73,7 +58,6 @@ win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
status = XGetWindowProperty(blz.dpy, w, a, 0L, l, False, t, &real, &format,
&res, &extra, prop);
if(status != Success || *prop == 0) {
return 0;
}
@ -84,8 +68,7 @@ win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
}
int
win_proto(Window w)
{
win_proto(Window w) {
Atom *protocols;
long res;
int protos = 0;
@ -106,21 +89,18 @@ win_proto(Window w)
static void
init_atoms()
{
init_atoms() {
wm_atom[WMProtocols] = XInternAtom(blz.dpy, "WM_PROTOCOLS", False);
wm_atom[WMDelete] = XInternAtom(blz.dpy, "WM_DELETE_WINDOW", False);
net_atom[NetSupported] = XInternAtom(blz.dpy, "_NET_SUPPORTED", False);
net_atom[NetWMName] = XInternAtom(blz.dpy, "_NET_WM_NAME", False);
tags_atom = XInternAtom(blz.dpy, "_WIN_TAGS", False);
XChangeProperty(blz.dpy, blz.root, net_atom[NetSupported], XA_ATOM, 32,
PropModeReplace, (unsigned char *) net_atom, NetLast);
}
static void
init_cursors()
{
init_cursors() {
cursor[CurNormal] = XCreateFontCursor(blz.dpy, XC_left_ptr);
cursor[CurResize] = XCreateFontCursor(blz.dpy, XC_sizing);
cursor[CurMove] = XCreateFontCursor(blz.dpy, XC_fleur);
@ -128,8 +108,7 @@ init_cursors()
}
static void
init_screen(WMScreen *screen)
{
init_screen(WMScreen *screen) {
Window w;
int ret;
unsigned mask;
@ -142,12 +121,10 @@ init_screen(WMScreen *screen)
gcv.graphics_exposures = False;
xorgc = XCreateGC(blz.dpy, blz.root, GCForeground | GCGraphicsExposures |
GCFunction | GCSubwindowMode | GCPlaneMask, &gcv);
screen->rect.x = screen->rect.y = 0;
screen->rect.width = DisplayWidth(blz.dpy, blz.screen);
screen->rect.height = DisplayHeight(blz.dpy, blz.screen);
def.snap = screen->rect.height / 63;
sel_screen = XQueryPointer(blz.dpy, blz.root, &w, &w, &ret, &ret, &ret, &ret, &mask);
}
@ -158,8 +135,7 @@ init_screen(WMScreen *screen)
* calls exit().
*/
int
wmii_error_handler(Display *dpy, XErrorEvent *error)
{
wmii_error_handler(Display *dpy, XErrorEvent *error) {
if(error->error_code == BadWindow
|| (error->request_code == X_SetInputFocus
&& error->error_code == BadMatch)
@ -184,16 +160,15 @@ wmii_error_handler(Display *dpy, XErrorEvent *error)
* is already running.
*/
static int
startup_error_handler(Display * dpy, XErrorEvent * error)
{
startup_error_handler(Display * dpy, XErrorEvent * error) {
other_wm_running = 1;
return -1;
}
static void
cleanup()
{
cleanup() {
Client *c;
for(c=client; c; c=c->next)
reparent_client(c, blz.root, c->sel->rect.x, c->sel->rect.y);
XSetInputFocus(blz.dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
@ -201,10 +176,9 @@ cleanup()
}
int
main(int argc, char *argv[])
{
main(int argc, char *argv[]) {
int i;
char *address = nil, *wmiirc = nil, *namespace, *errstr;
char *address = NULL, *wmiirc = NULL, *namespace, *errstr;
WMScreen *s;
struct passwd *passwd;
XSetWindowAttributes wa;
@ -233,33 +207,26 @@ main(int argc, char *argv[])
break;
}
}
starting = True;
blz.dpy = XOpenDisplay(0);
if(!blz.dpy)
error("wmiiwm: cannot open dpy\n");
blz.screen = DefaultScreen(blz.dpy);
blz.root = RootWindow(blz.dpy, blz.screen);
/* check if another WM is already running */
other_wm_running = 0;
XSetErrorHandler(startup_error_handler);
/* this causes an error if some other WM is running */
XSelectInput(blz.dpy, blz.root, SubstructureRedirectMask | EnterWindowMask);
XSync(blz.dpy, False);
if(other_wm_running)
error("wmiiwm: another window manager is already running\n");
if(!address)
usage();
/* Check namespace permissions */
if(!strncmp(address, "unix!", 5)) {
struct stat st;
namespace = cext_estrdup(&address[5]);
namespace = ixp_estrdup(&address[5]);
for(i = strlen(namespace) - 1; i >= 0; i--)
if(namespace[i] == '/') break;
namespace[i+1] = '\0';
@ -275,10 +242,9 @@ main(int argc, char *argv[])
namespace);
free(namespace);
}
XSetErrorHandler(0);
x_error_handler = XSetErrorHandler(wmii_error_handler);
errstr = nil;
errstr = NULL;
i = ixp_create_sock(address, &errstr);
if(i < 0)
error("wmiiwm: fatal: %s\n", errstr);
@ -294,7 +260,7 @@ main(int argc, char *argv[])
close(i);
close(ConnectionNumber(blz.dpy));
snprintf(execstr, name_len, "exec %s", wmiirc);
execl("/bin/sh", "sh", "-c", execstr, nil);
execl("/bin/sh", "sh", "-c", execstr, NULL);
error("wmiiwm: can't exec \"%s\": %s\n", wmiirc, strerror(errno));
case -1:
perror("wmiiwm: cannot fork wmiirc");
@ -304,68 +270,56 @@ main(int argc, char *argv[])
}
/* IXP server */
ixp_server_open_conn(&srv, i, &p9srv, serve_9pcon, nil);
ixp_server_open_conn(&srv, i, &p9srv, serve_9pcon, NULL);
/* X server */
ixp_server_open_conn(&srv, ConnectionNumber(blz.dpy), nil, check_x_event, nil);
view = nil;
client = nil;
key = nil;
ixp_server_open_conn(&srv, ConnectionNumber(blz.dpy), NULL, check_x_event, NULL);
view = NULL;
client = NULL;
key = NULL;
passwd = getpwuid(getuid());
user = cext_estrdup(passwd->pw_name);
def.colrules.string = nil;
user = ixp_estrdup(passwd->pw_name);
def.colrules.string = NULL;
def.colrules.size = 0;
def.tagrules.string = nil;
def.tagrules.string = NULL;
def.tagrules.size = 0;
def.keys = nil;
def.keys = NULL;
def.keyssz = 0;
def.font.fontstr = cext_estrdup(BLITZ_FONT);
def.font.fontstr = ixp_estrdup(BLITZ_FONT);
def.border = 2;
def.colmode = Coldefault;
cext_strlcpy(def.selcolor.colstr, BLITZ_SELCOLORS, sizeof(def.selcolor.colstr));
strncpy(def.selcolor.colstr, BLITZ_SELCOLORS, sizeof(def.selcolor.colstr));
blitz_loadcolor(&blz, &def.selcolor);
cext_strlcpy(def.normcolor.colstr, BLITZ_NORMCOLORS, sizeof(def.normcolor.colstr));
strncpy(def.normcolor.colstr, BLITZ_NORMCOLORS, sizeof(def.normcolor.colstr));
blitz_loadcolor(&blz, &def.normcolor);
cext_strlcpy(def.bcolor[0].colstr, BLITZ_B1COLORS, sizeof(def.bcolor[0].colstr));
cext_strlcpy(def.bcolor[1].colstr, BLITZ_B2COLORS, sizeof(def.bcolor[1].colstr));
cext_strlcpy(def.bcolor[2].colstr, BLITZ_B3COLORS, sizeof(def.bcolor[2].colstr));
strncpy(def.bcolor[0].colstr, BLITZ_B1COLORS, sizeof(def.bcolor[0].colstr));
strncpy(def.bcolor[1].colstr, BLITZ_B2COLORS, sizeof(def.bcolor[1].colstr));
strncpy(def.bcolor[2].colstr, BLITZ_B3COLORS, sizeof(def.bcolor[2].colstr));
blitz_loadcolor(&blz, &def.bcolor[0]);
blitz_loadcolor(&blz, &def.bcolor[1]);
blitz_loadcolor(&blz, &def.bcolor[2]);
cext_strlcpy(def.grabmod, "Mod1", sizeof(def.grabmod));
strncpy(def.grabmod, "Mod1", sizeof(def.grabmod));
def.mod = Mod1Mask;
init_atoms();
init_cursors();
blitz_loadfont(&blz, &def.font);
init_lock_keys();
num_screens = 1;
screens = cext_emallocz(num_screens * sizeof(*screens));
screens = ixp_emallocz(num_screens * sizeof(*screens));
for(i = 0; i < num_screens; i++) {
s = &screens[i];
s->lbar = nil;
s->rbar = nil;
s->sel = nil;
s->lbar = NULL;
s->rbar = NULL;
s->sel = NULL;
init_screen(s);
pmap = XCreatePixmap(blz.dpy, blz.root, s->rect.width, s->rect.height,
DefaultDepth(blz.dpy, blz.screen));
wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(blz.dpy, blz.root, CWEventMask | CWCursor, &wa);
wa.override_redirect = 1;
wa.background_pixmap = ParentRelative;
wa.event_mask = ExposureMask | ButtonReleaseMask
| SubstructureRedirectMask | SubstructureNotifyMask;
s->brect = s->rect;
s->brect.height = blitz_labelh(&def.font);
s->brect.y = s->rect.height - s->brect.height;
@ -376,7 +330,6 @@ main(int argc, char *argv[])
CopyFromParent, DefaultVisual(blz.dpy, blz.screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
XSync(blz.dpy, False);
s->bbrush.blitz = &blz;
s->bbrush.gc = XCreateGC(blz.dpy, s->barwin, 0, 0);
s->bbrush.drawable = pmap;
@ -386,7 +339,6 @@ main(int argc, char *argv[])
s->bbrush.color = def.normcolor;
s->bbrush.font = &def.font;
s->bbrush.border = True;
draw_bar(s);
XMapRaised(blz.dpy, s->barwin);
}
@ -394,17 +346,14 @@ main(int argc, char *argv[])
screen = &screens[0];
scan_wins();
update_views();
starting = False;
/* main event loop */
errstr = ixp_server_loop(&srv);
if(errstr)
fprintf(stderr, "wmii: fatal: %s\n", errstr);
cleanup();
XCloseDisplay(blz.dpy);
ixp_server_close(&srv);
return errstr ? 1 : 0;
}

81
wm.h
View File

@ -7,9 +7,68 @@
#include <regex.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xlocale.h>
#include <ixp.h>
#include <blitz.h>
#define BLITZ_FONT "fixed"
#define BLITZ_SELCOLORS "#ffffff #335577 #447799"
#define BLITZ_NORMCOLORS "#222222 #eeeeee #666666"
#define BLITZ_B1COLORS "#000000 #00ffff #000000"
#define BLITZ_B2COLORS "#000000 #ff0000 #000000"
#define BLITZ_B3COLORS "#000000 #00ff00 #000000"
typedef struct Blitz Blitz;
typedef enum BlitzAlign BlitzAlign;
typedef struct BlitzColor BlitzColor;
typedef struct BlitzFont BlitzFont;
typedef struct BlitzBrush BlitzBrush;
typedef struct BlitzInput BlitzInput;
struct Blitz {
Display *dpy;
int screen;
Window root;
};
enum BlitzAlign {
NORTH = 0x01,
EAST = 0x02,
SOUTH = 0x04,
WEST = 0x08,
NEAST = NORTH | EAST,
NWEST = NORTH | WEST,
SEAST = SOUTH | EAST,
SWEST = SOUTH | WEST,
CENTER = NEAST | SWEST
};
struct BlitzColor {
unsigned long bg;
unsigned long fg;
unsigned long border;
char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
};
struct BlitzFont {
XFontStruct *xfont;
XFontSet set;
int ascent;
int descent;
unsigned int height;
char *fontstr;
};
struct BlitzBrush {
Blitz *blitz;
Drawable drawable;
GC gc;
Bool border;
BlitzColor color;
BlitzAlign align;
BlitzFont *font;
XRectangle rect; /* relative rect */
};
/* WM atoms */
enum { WMProtocols, WMDelete, WMLast };
@ -202,6 +261,10 @@ extern void draw_bar(WMScreen *s);
extern void resize_bar();
extern Bar *bar_of_name(Bar *b_link, const char *name);
/* brush.c */
extern void blitz_draw_label(BlitzBrush *b, char *text);
extern void blitz_draw_tile(BlitzBrush *b);
/* client.c */
extern Client *create_client(Window w, XWindowAttributes *wa);
extern void destroy_client(Client *c);
@ -230,6 +293,9 @@ extern void update_client_grab(Client *c, Bool is_sel);
extern void apply_rules(Client *c);
extern void apply_tags(Client *c, const char *tags);
/* color.c */
extern int blitz_loadcolor(Blitz *blitz, BlitzColor *c);
/* column.c */
extern void arrange_column(Area *a, Bool dirty);
extern void scale_column(Area *a, float h);
@ -238,6 +304,12 @@ extern int column_mode_of_str(char *arg);
extern char *str_of_column_mode(int mode);
extern Area *new_column(View *v, Area *pos, unsigned int w);
/* draw.c */
extern void blitz_drawbg(Display *dpy, Drawable drawable, GC gc,
XRectangle rect, BlitzColor c, Bool border);
extern void blitz_drawcursor(Display *dpy, Drawable drawable, GC gc,
int x, int y, unsigned int h, BlitzColor c);
/* event.c */
extern void check_x_event(IXPConn *c);
extern unsigned int flush_masked_events(long even_mask);
@ -250,6 +322,12 @@ extern void draw_frame(Frame *f);
extern void draw_frames();
extern void update_frame_widget_colors(Frame *f);
/* font.c */
extern unsigned int blitz_textwidth(BlitzFont *font, char *text);
extern unsigned int blitz_textwidth_l(BlitzFont *font, char *text, unsigned int len);
extern void blitz_loadfont(Blitz *blitz, BlitzFont *font);
extern unsigned int blitz_labelh(BlitzFont *font);
/* fs.c */
extern void fs_attach(P9Req *r);
extern void fs_clunk(P9Req *r);
@ -284,6 +362,7 @@ extern BlitzAlign snap_rect(XRectangle *rects, int num, XRectangle *current,
/* rule.c */
extern void update_rules(Rule **rule, const char *data);
extern void trim(char *str, const char *chars);
/* view.c */
extern void arrange_view(View *v);