wmii/cmd/wm/bar.c

223 lines
4.4 KiB
C
Raw Normal View History

/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include <string.h>
2006-03-09 04:15:43 +03:00
#include <stdlib.h>
#include "wm.h"
2006-03-09 04:15:43 +03:00
static int
comp_bar_intern(const void *b1, const void *b2)
2006-03-09 04:15:43 +03:00
{
Bar *bb1 = *(Bar **)b1;
Bar *bb2 = *(Bar **)b2;
if(bb1->intern && !bb2->intern)
return -1;
if(!bb1->intern && bb2->intern)
return 1;
return 0;
}
static int
comp_bar_name(const void *b1, const void *b2)
{
Bar *bb1 = *(Bar **)b1;
Bar *bb2 = *(Bar **)b2;
return strcmp(bb1->name, bb2->name);
2006-03-09 04:15:43 +03:00
}
static Vector *
vector_of_bars(BarVector *bv)
{
return (Vector *) bv;
}
2006-04-12 12:44:07 +04:00
Bar *
create_bar(char *name, Bool intern)
{
static unsigned int id = 1;
Bar *b = bar_of_name(name);
if(b)
return b;
b = cext_emallocz(sizeof(Bar));
b->id = id++;
b->intern = intern;
cext_strlcpy(b->name, name, sizeof(b->name));
cext_strlcpy(b->colstr, def.selcolor, sizeof(b->colstr));
b->color = def.sel;
cext_vattach(vector_of_bars(&bar), b);
2006-04-13 18:52:33 +04:00
qsort(bar.data, bar.size, sizeof(Bar *), comp_bar_name);
qsort(bar.data, bar.size, sizeof(Bar *), comp_bar_intern);
return b;
}
void
destroy_bar(Bar *b)
{
cext_vdetach(vector_of_bars(&bar), b);
free(b);
}
unsigned int
2006-04-12 12:44:07 +04:00
height_of_bar()
{
enum { BAR_PADDING = 4 };
return blitzfont.xfont->ascent + blitzfont.xfont->descent + BAR_PADDING;
}
void
2006-04-12 12:44:07 +04:00
resize_bar()
{
unsigned int i, j;
brect = rect;
2006-04-12 12:44:07 +04:00
brect.height = height_of_bar();
brect.y = rect.height - brect.height;
XMoveResizeWindow(dpy, barwin, brect.x, brect.y, brect.width, brect.height);
XSync(dpy, False);
XFreePixmap(dpy, barpmap);
barpmap = XCreatePixmap(dpy, barwin, brect.width, brect.height,
DefaultDepth(dpy, screen));
XSync(dpy, False);
draw_bar();
for(i = 0; i < view.size; i++) {
for(j = 1; j < view.data[i]->area.size; j++) {
Area *a = view.data[i]->area.data[j];
a->rect.height = rect.height - brect.height;
arrange_column(a, False);
}
for(j = 0; j < view.data[i]->area.data[0]->frame.size; j++) {
Frame *f = view.data[i]->area.data[0]->frame.data[j];
resize_client(f->client, &f->rect, False);
}
}
}
void
draw_bar()
{
unsigned int i = 0, w = 0;
int exp = -1;
BlitzDraw d = { 0 };
Bar *b = nil;
d.gc = bargc;
d.drawable = barpmap;
d.rect = brect;
d.rect.x = d.rect.y = 0;
d.font = blitzfont;
d.color = def.norm;
blitz_drawlabel(dpy, &d);
blitz_drawborder(dpy, &d);
2006-04-13 18:52:33 +04:00
if(!bar.size)
return;
2006-04-13 18:52:33 +04:00
for(i = 0; (i < bar.size) && (w < brect.width); i++) {
b = bar.data[i];
if(b->intern) {
if(view.size && !strncmp(b->name, view.data[sel]->name, sizeof(b->name)))
b->color = def.sel;
else
b->color = def.norm;
}
b->rect.x = 0;
b->rect.y = 0;
b->rect.width = brect.height;
if(strlen(b->data))
b->rect.width += blitz_textwidth(dpy, &blitzfont, b->data);
b->rect.height = brect.height;
w += b->rect.width;
}
2006-04-13 18:52:33 +04:00
if(i != bar.size) { /* give all bars same width */
w = brect.width / bar.size;
for(i = 0; i < bar.size; i++) {
b = bar.data[i];
b->rect.x = i * w;
b->rect.width = w;
}
}
2006-04-13 18:52:33 +04:00
else { /* expand bar properly */
for(exp = 0; (exp < bar.size) && (bar.data[exp]->intern); exp++);
if(exp == bar.size)
exp = -1;
else
2006-04-13 18:52:33 +04:00
bar.data[exp]->rect.width += (brect.width - w);
for(i = 1; i < bar.size; i++)
bar.data[i]->rect.x = bar.data[i - 1]->rect.x + bar.data[i - 1]->rect.width;
}
2006-04-13 18:52:33 +04:00
for(i = 0; i < bar.size; i++) {
b = bar.data[i];
d.color = b->color;
d.rect = b->rect;
d.data = b->data;
if(i == exp)
d.align = EAST;
else
d.align = CENTER;
blitz_drawlabel(dpy, &d);
blitz_drawborder(dpy, &d);
}
XCopyArea(dpy, barpmap, barwin, bargc, 0, 0, brect.width, brect.height, 0, 0);
XSync(dpy, False);
}
2006-03-09 04:15:43 +03:00
int
idx_of_bar(Bar *b)
2006-03-09 04:15:43 +03:00
{
int i;
2006-04-13 18:52:33 +04:00
for(i = 0; i < bar.size; i++)
if(bar.data[i] == b)
2006-03-09 04:15:43 +03:00
return i;
return -1;
}
int
2006-04-12 12:44:07 +04:00
idx_of_bar_id(unsigned short id)
{
int i;
2006-04-13 18:52:33 +04:00
for(i = 0; i < bar.size; i++)
if(bar.data[i]->id == id)
return i;
return -1;
}
2006-03-09 04:15:43 +03:00
2006-04-12 12:44:07 +04:00
Bar *
bar_of_name(const char *name)
2006-03-09 04:15:43 +03:00
{
static char buf[256];
2006-03-09 04:15:43 +03:00
unsigned int i;
cext_strlcpy(buf, name, sizeof(buf));
2006-04-13 18:52:33 +04:00
for(i = 0; i < bar.size; i++)
if(!strncmp(bar.data[i]->name, name, sizeof(bar.data[i]->name)))
return bar.data[i];
2006-03-09 04:15:43 +03:00
return nil;
}
void
2006-04-12 12:44:07 +04:00
update_view_bars()
{
unsigned int i;
Bar *b = nil;
2006-04-13 18:52:33 +04:00
for(i = 0; (i < bar.size) && bar.data[i]->intern; i++) {
b = bar.data[i];
if(!view_of_name(b->name)) {
destroy_bar(b);
i--;
}
}
for(i = 0; i < view.size; i++) {
b = create_bar(view.data[i]->name, True);
cext_strlcpy(b->data, view.data[i]->name, sizeof(b->data));
}
draw_bar();
}