commit ab5eb008a851dc6997d149eb0d1d0d0768e3b4c7
parent 571c792922a86aaaca3eba619f01932d3f3b9c17
Author: garbeam <garbeam@localhost.localdomain>
Date: Mon, 5 Dec 2005 03:15:25 +0200
removed frking core.c
Diffstat:
7 files changed, 525 insertions(+), 535 deletions(-)
diff --git a/cmd/wm/Makefile.wm b/cmd/wm/Makefile.wm
@@ -8,7 +8,7 @@ CFLAGS += -I../../liblitz -I../../libixp -I../../libwmii \
LDFLAGS += -L../../liblitz -llitz -L../../libixp -lixp \
-L../../libwmii -lwmii -L../../libcext -lcext
-SRC = wm.c core.c client.c event.c mouse.c frame.c area.c page.c layout.c
+SRC = wm.c client.c event.c mouse.c frame.c area.c page.c layout.c
include layout.mk
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -61,7 +61,7 @@ void focus_client(Client * c, int raise, int up)
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
} else
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
- invoke_core_event(defaults[WM_EVENT_CLIENT_UPDATE]);
+ invoke_wm_event(defaults[WM_EVENT_CLIENT_UPDATE]);
if (up && f)
focus_frame(f, raise, up, 0);
}
@@ -207,7 +207,7 @@ void handle_client_property(Client * c, XPropertyEvent * e)
}
if (c->frame)
draw_client(c);
- invoke_core_event(defaults[WM_EVENT_CLIENT_UPDATE]);
+ invoke_wm_event(defaults[WM_EVENT_CLIENT_UPDATE]);
break;
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &c->trans);
diff --git a/cmd/wm/core.c b/cmd/wm/core.c
@@ -1,514 +0,0 @@
-/*
- * (C)opyright MMIV-MMV Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-
-#include "wm.h"
-
-static void new_page(void *obj, char *cmd);
-static void _select_page(void *obj, char *cmd);
-static void _destroy_page(void *obj, char *cmd);
-static void quit(void *obj, char *cmd);
-static void _attach_client(void *obj, char *cmd);
-static void _detach_client(void *obj, char *cmd);
-static void _close_client(void *obj, char *cmd);
-static void pager(void *obj, char *cmd);
-static void icons(void *obj, char *cmd);
-
-/* action table for /ctl namespace */
-Action core_acttbl[] = {
- {"new", new_page},
- {"destroy", _destroy_page},
- {"select", _select_page},
- {"attach", _attach_client},
- {"detach", _detach_client},
- {"close", _close_client},
- {"quit", quit},
- {"pager", pager},
- {"icons", icons},
- {0, 0}
-};
-
-void run_action(File * f, void *obj, Action * acttbl)
-{
- int i;
- size_t len;
-
- if (!f->content)
- return;
- for (i = 0; acttbl[i].name; i++) {
- len = strlen(acttbl[i].name);
- if (!strncmp(acttbl[i].name, (char *) f->content, len)) {
- if (f->size > len)
- acttbl[i].func(obj, &((char *) f->content)[len + 1]);
- else
- acttbl[i].func(obj, 0);
- return;
- break;
- }
- }
- fprintf(stderr, "wmiiwm: unknown action '%s'\n"
- " or invalid ctl device\n", (char *) f->content);
-}
-
-static void quit(void *obj, char *cmd)
-{
- ixps->runlevel = SHUTDOWN;
-}
-
-void invoke_core_event(File * f)
-{
- if (!f->content)
- return;
- spawn(dpy, f->content);
-}
-
-static void
-scale_rect(XRectangle * from_dim, XRectangle * to_dim,
- XRectangle * src, XRectangle * tgt)
-{
- double wfact = (double) to_dim->width / (double) from_dim->width;
- double hfact = (double) to_dim->height / (double) from_dim->height;
-
- tgt->x = to_dim->x + (src->x * wfact);
- tgt->y = to_dim->y + (src->y * hfact);
- tgt->width = (src->width * wfact);
- tgt->height = (src->height * hfact);
-
- if (tgt->width < 1)
- tgt->width = 1;
- if (tgt->height < 1)
- tgt->height = 1;
-}
-
-static void draw_pager_page(Page * p, Draw * d)
-{
- unsigned int i, j;
- XRectangle r = d->rect;
- char name[4];
- if (p == pages[sel]) {
- d->bg = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_BG_COLOR]->content);
- d->fg = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_FG_COLOR]->content);
- d->border = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_BORDER_COLOR]->content);
- d->font = font;
- } else {
- d->bg = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_BG_COLOR]->content);
- d->fg = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_FG_COLOR]->content);
- d->border = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_BORDER_COLOR]->content);
- d->font = font;
- }
- snprintf(name, sizeof(name), "%d", index_item((void **) pages, p));
- d->data = name;
- blitz_drawlabel(dpy, d);
- XSync(dpy, False);
-
- for (i = 0; p->areas[i]; i++) {
- for (j = 0; p->areas[i]->frames[j]; j++) {
- if (i == p->sel && j == p->areas[i]->sel) {
- d->bg = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_BG_COLOR]->content);
- d->fg = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_FG_COLOR]->content);
- d->border = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_BORDER_COLOR]->content);
- d->font = font;
- } else {
- d->bg = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_BG_COLOR]->content);
- d->fg = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_FG_COLOR]->content);
- d->border = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_BORDER_COLOR]->content);
- d->font = font;
- }
- d->data = p->areas[i]->frames[j]->clients[p->areas[i]->frames[j]->sel]->files[C_NAME]->content;
- scale_rect(&rect, &r, &p->areas[i]->rect, &d->rect);
- blitz_drawlabel(dpy, d);
- XSync(dpy, False); /* do not clear upwards */
- }
- }
-}
-
-static void draw_pager()
-{
- unsigned int ic, ir, tw, th, rows, cols, size;
- int i = 0;
- int dx;
- Draw d = { 0 };
-
- blitz_getbasegeometry((void **) pages, &size, &cols, &rows);
- dx = (cols - 1) * GAP; /* GAPpx space */
- tw = (rect.width - dx) / cols;
- th = ((double) tw / rect.width) * rect.height;
- d.drawable = transient;
- d.gc = transient_gc;
- for (ir = 0; ir < rows; ir++) {
- for (ic = 0; ic < cols; ic++) {
- d.rect.x = ic * tw + (ic * GAP);
- d.rect.width = tw;
- if (rows == 1)
- d.rect.y = 0;
- else
- d.rect.y = ir * (rect.height - th) / (rows - 1);
- d.rect.height = th;
- if (!pages[i])
- return;
- draw_pager_page(pages[i], &d);
- i++;
- }
- }
-}
-
-static Page *xy_to_pager_page(int x, int y)
-{
- unsigned int ic, ir, tw, th, rows, cols, size;
- int i = 0;
- int dx;
- XRectangle r;
-
- if (!pages)
- return 0;
- blitz_getbasegeometry((void **) pages, &size, &cols, &rows);
- dx = (cols - 1) * GAP; /* GAPpx space */
- tw = (rect.width - dx) / cols;
- th = ((double) tw / rect.width) * rect.height;
-
- for (ir = 0; ir < rows; ir++) {
- for (ic = 0; ic < cols; ic++) {
- r.x = ic * tw + (ic * GAP);
- r.width = tw;
- if (rows == 1)
- r.y = 0;
- else
- r.y = ir * (rect.height - th) / (rows - 1);
- r.height = th;
- if (!pages[i])
- return 0;
- if (blitz_ispointinrect(x, y, &r))
- return pages[i];
- i++;
- }
- }
- return 0;
-}
-
-static int handle_kpress(XKeyEvent * e)
-{
- KeySym ksym = XKeycodeToKeysym(dpy, e->keycode, 0);
-
- if (ksym >= XK_1 && ksym <= XK_9)
- return ksym - XK_1;
- else if (ksym == XK_0)
- return 9;
- else if (ksym >= XK_a && ksym <= XK_z)
- return 10 + ksym - XK_a;
-
- return -1;
-}
-
-static void pager(void *obj, char *cmd)
-{
- XEvent ev;
- int i;
-
- if (!pages)
- return;
-
- XClearWindow(dpy, transient);
- XMapRaised(dpy, transient);
- draw_pager();
- while (XGrabKeyboard
- (dpy, transient, True, GrabModeAsync, GrabModeAsync,
- CurrentTime) != GrabSuccess)
- usleep(1000);
-
- for (;;) {
- while (!XCheckWindowEvent
- (dpy, transient, ButtonPressMask | KeyPressMask, &ev)) {
- usleep(20000);
- continue;
- }
-
- switch (ev.type) {
- case KeyPress:
- XUnmapWindow(dpy, transient);
- if ((i = handle_kpress(&ev.xkey)) != -1)
- if (i < count_items((void **) pages))
- focus_page(pages[i], 0, 1);
- XUngrabKeyboard(dpy, CurrentTime);
- return;
- break;
- case ButtonPress:
- XUnmapWindow(dpy, transient);
- if (ev.xbutton.button == Button1) {
- Page *p = xy_to_pager_page(ev.xbutton.x, ev.xbutton.y);
- if (p)
- focus_page(p, 0, 1);
- }
- return;
- break;
- }
- }
-}
-
-static void draw_icons()
-{
- unsigned int i, ic, ir, tw, th, rows, cols, size;
- int dx, dy;
-
- if (!detached)
- return;
- blitz_getbasegeometry((void **) detached, &size, &cols, &rows);
- dx = (cols - 1) * GAP; /* GAPpx space */
- dy = (rows - 1) * GAP; /* GAPpx space */
- tw = (rect.width - dx) / cols;
- th = (rect.height - dy) / rows;
-
- XClearWindow(dpy, transient);
- XMapRaised(dpy, transient);
- i = 0;
- for (ir = 0; ir < rows; ir++) {
- for (ic = 0; ic < cols; ic++) {
- Client *c = detached[i++];
- XRectangle cr;
- if (!c)
- return;
- cr.x = ic * tw + (ic * GAP);
- cr.y = ir * th + (ir * GAP);
- cr.width = tw;
- cr.height = th;
- XMoveResizeWindow(dpy, c->win, cr.x, cr.y, cr.width,
- cr.height);
- configure_client(c);
- show_client(c);
- XRaiseWindow(dpy, c->win);
- grab_client(c, AnyModifier, AnyButton);
- XSync(dpy, False);
- }
- }
-}
-
-
-static void icons(void *obj, char *cmd)
-{
- XEvent ev;
- int i, n;
- Client *c;
-
- if (!detached)
- return;
-
- XClearWindow(dpy, transient);
- XMapRaised(dpy, transient);
- draw_icons();
- while (XGrabKeyboard
- (dpy, transient, True, GrabModeAsync, GrabModeAsync,
- CurrentTime) != GrabSuccess)
- usleep(1000);
-
- for (;;) {
- while (!XCheckMaskEvent(dpy, ButtonPressMask | KeyPressMask, &ev)) {
- usleep(20000);
- continue;
- }
- switch (ev.type) {
- case KeyPress:
- XUnmapWindow(dpy, transient);
- if ((n = handle_kpress(&ev.xkey)) != -1) {
- for (i = 0; detached && detached[i]; i++)
- hide_client(detached[i]);
- if (n - 1 < i) {
- c = detached[n];
- detached =
- (Client **) detach_item((void **) detached, c,
- sizeof(Client *));
- attach_client(c);
- }
- } else {
- for (i = 0; detached && detached[i]; i++)
- hide_client(detached[i]);
- }
- XUngrabKeyboard(dpy, CurrentTime);
- return;
- break;
- case ButtonPress:
- if (ev.xbutton.button == Button1) {
- XUnmapWindow(dpy, transient);
- for (i = 0; detached && detached[i]; i++)
- hide_client(detached[i]);
- if ((c = win_to_client(ev.xbutton.window))) {
- detached =
- (Client **) detach_item((void **) detached, c,
- sizeof(Client *));
- attach_client(c);
- }
- XUngrabKeyboard(dpy, CurrentTime);
- }
- return;
- break;
- }
- }
-}
-
-static void _close_client(void *obj, char *cmd)
-{
- Frame *f = pages ? SELFRAME(pages[sel]) : 0;
- if (f->clients[f->sel])
- close_client(f->clients[f->sel]);
-}
-
-static void _attach_client(void *obj, char *cmd)
-{
- if (detached) {
- Client *c = detached[0];
- detached =
- (Client **) detach_item((void **) detached, c,
- sizeof(Client *));
- attach_client(c);
- }
-}
-
-static void _detach_client(void *obj, char *cmd)
-{
- Frame *f;
- if (!pages)
- return;
- f = SELFRAME(pages[sel]);
- if (!f)
- return;
- detach_client_from_frame(f->clients[f->sel], 0, 0);
-}
-
-static void _select_page(void *obj, char *cmd)
-{
- if (!pages || !cmd)
- return;
- if (!strncmp(cmd, "prev", 5))
- sel = index_prev_item((void **) pages, pages[sel]);
- else if (!strncmp(cmd, "next", 5))
- sel = index_next_item((void **) pages, pages[sel]);
- else
- sel = _strtonum(cmd, 0, count_items((void **) pages));
- focus_page(pages[sel], 0, 1);
-}
-
-static void _destroy_page(void *obj, char *cmd)
-{
- if (!pages)
- return;
- destroy_page(pages[sel]);
-}
-
-static void new_page(void *obj, char *cmd)
-{
- if (pages)
- hide_page(pages[sel]);
- alloc_page("0");
-}
-
-Client *win_to_client(Window w)
-{
- int i;
-
- for (i = 0; clients && clients[i]; i++)
- if (clients[i]->win == w)
- return clients[i];
- return 0;
-}
-
-void scan_wins()
-{
- int i;
- unsigned int num;
- Window *wins;
- XWindowAttributes wa;
- Window d1, d2;
- Client *c;
-
- if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
- for (i = 0; i < num; i++) {
- if (!XGetWindowAttributes(dpy, wins[i], &wa))
- continue;
- if (wa.override_redirect
- || XGetTransientForHint(dpy, wins[i], &d1))
- continue;
- if (wa.map_state == IsViewable) {
- c = alloc_client(wins[i]);
- _init_client(c, &wa);
- attach_client(c);
- }
- }
- }
- if (wins)
- XFree(wins);
-}
-
-void *get_func(void *acttbl[][2], int rows, char *fname)
-{
- int i;
- for (i = 0; i < rows; i++) {
- if (!strncmp((char *) acttbl[i][0], fname, MAX_BUF)) {
- return acttbl[i][1];
- }
- }
- return 0;
-}
-
-int win_proto(Window w)
-{
- Atom *protocols;
- long res;
- int protos = 0;
- int i;
-
- res = property(dpy, w, wm_protocols, XA_ATOM,
- 20L, ((unsigned char **) &protocols));
- if (res <= 0) {
- return protos;
- }
- for (i = 0; i < res; i++) {
- if (protocols[i] == wm_delete) {
- protos |= PROTO_DEL;
- }
- }
- free((char *) protocols);
- return protos;
-}
-
-int win_state(Window w)
-{
- /* state hints */
- XWMHints *hints = XGetWMHints(dpy, w);
- int res;
-
- long *prop = 0;
- if (property(dpy, w, wm_state, wm_state,
- 2L, ((unsigned char **) &prop)) > 0) {
- res = (int) *prop;
- free((long *) prop);
- } else {
- res = hints ? hints->initial_state : NormalState;
- }
-
- if (hints) {
- free(hints);
- }
- return res;
-}
-
-void handle_after_write(IXPServer * s, File * f)
-{
- if (f == defaults[WM_CTL])
- run_action(f, 0, core_acttbl);
- else if (f == defaults[WM_TRANS_COLOR]) {
- unsigned long col[1];
- col[0] = xorcolor.pixel;
- XFreeColors(dpy, DefaultColormap(dpy, screen_num), col, 1, 0);
- XAllocNamedColor(dpy, DefaultColormap(dpy, screen_num),
- defaults[WM_TRANS_COLOR]->content,
- &xorcolor, &xorcolor);
- XSetForeground(dpy, xorgc, xorcolor.pixel);
- }
- check_event(0);
-}
diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c
@@ -445,7 +445,7 @@ void attach_client(Client * c)
attach_frame_to_area(p->areas[p->sel], f);
attach_client_to_frame(f, c);
draw_frame(f);
- invoke_core_event(defaults[WM_EVENT_PAGE_UPDATE]);
+ invoke_wm_event(defaults[WM_EVENT_PAGE_UPDATE]);
}
void detach_client_from_frame(Client * c, int unmapped, int destroyed)
@@ -477,7 +477,7 @@ void detach_client_from_frame(Client * c, int unmapped, int destroyed)
if (pages)
focus_page(pages[sel], 0, 1);
}
- invoke_core_event(defaults[WM_EVENT_PAGE_UPDATE]);
+ invoke_wm_event(defaults[WM_EVENT_PAGE_UPDATE]);
}
static void mouse()
diff --git a/cmd/wm/page.c b/cmd/wm/page.c
@@ -44,7 +44,7 @@ Page *alloc_page(char *autodestroy)
pages = (Page **) attach_item_end((void **) pages, p, sizeof(Page *));
sel = index_item((void **) pages, p);
defaults[WM_SEL_PAGE]->content = p->files[P_PREFIX]->content;
- invoke_core_event(defaults[WM_EVENT_PAGE_UPDATE]);
+ invoke_wm_event(defaults[WM_EVENT_PAGE_UPDATE]);
return p;
}
@@ -59,7 +59,7 @@ void destroy_page(Page * p)
defaults[WM_SEL_PAGE]->content =
pages[sel]->files[P_PREFIX]->content;
focus_page(pages[sel], 0, 1);
- invoke_core_event(defaults[WM_EVENT_PAGE_UPDATE]);
+ invoke_wm_event(defaults[WM_EVENT_PAGE_UPDATE]);
}
}
@@ -88,7 +88,7 @@ void focus_page(Page * p, int raise, int down)
sel = index_item((void **) pages, p);
show_page(pages[sel]);
defaults[WM_SEL_PAGE]->content = p->files[P_PREFIX]->content;
- invoke_core_event(defaults[WM_EVENT_PAGE_UPDATE]);
+ invoke_wm_event(defaults[WM_EVENT_PAGE_UPDATE]);
}
if (down)
focus_area(p->areas[p->sel], raise, 0, down);
@@ -270,7 +270,7 @@ static void handle_after_write_page(IXPServer * s, File * f)
free(tmp);
}
draw_page(p);
- invoke_core_event(core_files[CORE_EVENT_PAGE_UPDATE]);
+ invoke_wm_event(wm_files[CORE_EVENT_PAGE_UPDATE]);
return;
}
*/
@@ -322,7 +322,7 @@ void
detach_frame_from_page(Frame * f, int ignore_focus_and_destroy)
{
Page *p = f->page;
- wmii_move_ixpfile(f->files[F_PREFIX], core_files[CORE_DETACHED_FRAME]);
+ wmii_move_ixpfile(f->files[F_PREFIX], wm_files[CORE_DETACHED_FRAME]);
if (is_managed_frame(f)) {
p->managed = (Frame **) detach_item((void **) p->managed, f,
sizeof(Frame *));
diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c
@@ -10,12 +10,39 @@
#include <sys/wait.h>
#include <X11/cursorfont.h>
#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include <X11/Xproto.h>
#include "wm.h"
static int other_wm_running;
static int (*x_error_handler) (Display *, XErrorEvent *);
+static void new_page(void *obj, char *cmd);
+static void _select_page(void *obj, char *cmd);
+static void _destroy_page(void *obj, char *cmd);
+static void quit(void *obj, char *cmd);
+static void _attach_client(void *obj, char *cmd);
+static void _detach_client(void *obj, char *cmd);
+static void _close_client(void *obj, char *cmd);
+static void pager(void *obj, char *cmd);
+static void icons(void *obj, char *cmd);
+
+/* action table for /ctl namespace */
+Action wm_acttbl[] = {
+ {"new", new_page},
+ {"destroy", _destroy_page},
+ {"select", _select_page},
+ {"attach", _attach_client},
+ {"detach", _detach_client},
+ {"close", _close_client},
+ {"quit", quit},
+ {"pager", pager},
+ {"icons", icons},
+ {0, 0}
+};
+
char *version[] = {
"wmiiwm - window manager improved 2 - " VERSION "\n"
" (C)opyright MMIV-MMV Anselm R. Garbe\n", 0
@@ -31,6 +58,483 @@ static void usage()
exit(1);
}
+void run_action(File * f, void *obj, Action * acttbl)
+{
+ int i;
+ size_t len;
+
+ if (!f->content)
+ return;
+ for (i = 0; acttbl[i].name; i++) {
+ len = strlen(acttbl[i].name);
+ if (!strncmp(acttbl[i].name, (char *) f->content, len)) {
+ if (f->size > len)
+ acttbl[i].func(obj, &((char *) f->content)[len + 1]);
+ else
+ acttbl[i].func(obj, 0);
+ return;
+ break;
+ }
+ }
+ fprintf(stderr, "wmiiwm: unknown action '%s'\n"
+ " or invalid ctl device\n", (char *) f->content);
+}
+
+static void quit(void *obj, char *cmd)
+{
+ ixps->runlevel = SHUTDOWN;
+}
+
+void invoke_wm_event(File * f)
+{
+ if (!f->content)
+ return;
+ spawn(dpy, f->content);
+}
+
+static void
+scale_rect(XRectangle * from_dim, XRectangle * to_dim,
+ XRectangle * src, XRectangle * tgt)
+{
+ double wfact = (double) to_dim->width / (double) from_dim->width;
+ double hfact = (double) to_dim->height / (double) from_dim->height;
+
+ tgt->x = to_dim->x + (src->x * wfact);
+ tgt->y = to_dim->y + (src->y * hfact);
+ tgt->width = (src->width * wfact);
+ tgt->height = (src->height * hfact);
+
+ if (tgt->width < 1)
+ tgt->width = 1;
+ if (tgt->height < 1)
+ tgt->height = 1;
+}
+
+static void draw_pager_page(Page * p, Draw * d)
+{
+ unsigned int i, j;
+ XRectangle r = d->rect;
+ char name[4];
+ if (p == pages[sel]) {
+ d->bg = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_BORDER_COLOR]->content);
+ d->font = font;
+ } else {
+ d->bg = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_BORDER_COLOR]->content);
+ d->font = font;
+ }
+ snprintf(name, sizeof(name), "%d", index_item((void **) pages, p));
+ d->data = name;
+ blitz_drawlabel(dpy, d);
+ XSync(dpy, False);
+
+ for (i = 0; p->areas[i]; i++) {
+ for (j = 0; p->areas[i]->frames[j]; j++) {
+ if (i == p->sel && j == p->areas[i]->sel) {
+ d->bg = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen_num, defaults[WM_SEL_BORDER_COLOR]->content);
+ d->font = font;
+ } else {
+ d->bg = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_BG_COLOR]->content);
+ d->fg = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_FG_COLOR]->content);
+ d->border = blitz_loadcolor(dpy, screen_num, defaults[WM_NORM_BORDER_COLOR]->content);
+ d->font = font;
+ }
+ d->data = p->areas[i]->frames[j]->clients[p->areas[i]->frames[j]->sel]->files[C_NAME]->content;
+ scale_rect(&rect, &r, &p->areas[i]->rect, &d->rect);
+ blitz_drawlabel(dpy, d);
+ XSync(dpy, False); /* do not clear upwards */
+ }
+ }
+}
+
+static void draw_pager()
+{
+ unsigned int ic, ir, tw, th, rows, cols, size;
+ int i = 0;
+ int dx;
+ Draw d = { 0 };
+
+ blitz_getbasegeometry((void **) pages, &size, &cols, &rows);
+ dx = (cols - 1) * GAP; /* GAPpx space */
+ tw = (rect.width - dx) / cols;
+ th = ((double) tw / rect.width) * rect.height;
+ d.drawable = transient;
+ d.gc = transient_gc;
+ for (ir = 0; ir < rows; ir++) {
+ for (ic = 0; ic < cols; ic++) {
+ d.rect.x = ic * tw + (ic * GAP);
+ d.rect.width = tw;
+ if (rows == 1)
+ d.rect.y = 0;
+ else
+ d.rect.y = ir * (rect.height - th) / (rows - 1);
+ d.rect.height = th;
+ if (!pages[i])
+ return;
+ draw_pager_page(pages[i], &d);
+ i++;
+ }
+ }
+}
+
+static Page *xy_to_pager_page(int x, int y)
+{
+ unsigned int ic, ir, tw, th, rows, cols, size;
+ int i = 0;
+ int dx;
+ XRectangle r;
+
+ if (!pages)
+ return 0;
+ blitz_getbasegeometry((void **) pages, &size, &cols, &rows);
+ dx = (cols - 1) * GAP; /* GAPpx space */
+ tw = (rect.width - dx) / cols;
+ th = ((double) tw / rect.width) * rect.height;
+
+ for (ir = 0; ir < rows; ir++) {
+ for (ic = 0; ic < cols; ic++) {
+ r.x = ic * tw + (ic * GAP);
+ r.width = tw;
+ if (rows == 1)
+ r.y = 0;
+ else
+ r.y = ir * (rect.height - th) / (rows - 1);
+ r.height = th;
+ if (!pages[i])
+ return 0;
+ if (blitz_ispointinrect(x, y, &r))
+ return pages[i];
+ i++;
+ }
+ }
+ return 0;
+}
+
+static int handle_kpress(XKeyEvent * e)
+{
+ KeySym ksym = XKeycodeToKeysym(dpy, e->keycode, 0);
+
+ if (ksym >= XK_1 && ksym <= XK_9)
+ return ksym - XK_1;
+ else if (ksym == XK_0)
+ return 9;
+ else if (ksym >= XK_a && ksym <= XK_z)
+ return 10 + ksym - XK_a;
+
+ return -1;
+}
+
+static void pager(void *obj, char *cmd)
+{
+ XEvent ev;
+ int i;
+
+ if (!pages)
+ return;
+
+ XClearWindow(dpy, transient);
+ XMapRaised(dpy, transient);
+ draw_pager();
+ while (XGrabKeyboard
+ (dpy, transient, True, GrabModeAsync, GrabModeAsync,
+ CurrentTime) != GrabSuccess)
+ usleep(1000);
+
+ for (;;) {
+ while (!XCheckWindowEvent
+ (dpy, transient, ButtonPressMask | KeyPressMask, &ev)) {
+ usleep(20000);
+ continue;
+ }
+
+ switch (ev.type) {
+ case KeyPress:
+ XUnmapWindow(dpy, transient);
+ if ((i = handle_kpress(&ev.xkey)) != -1)
+ if (i < count_items((void **) pages))
+ focus_page(pages[i], 0, 1);
+ XUngrabKeyboard(dpy, CurrentTime);
+ return;
+ break;
+ case ButtonPress:
+ XUnmapWindow(dpy, transient);
+ if (ev.xbutton.button == Button1) {
+ Page *p = xy_to_pager_page(ev.xbutton.x, ev.xbutton.y);
+ if (p)
+ focus_page(p, 0, 1);
+ }
+ return;
+ break;
+ }
+ }
+}
+
+static void draw_icons()
+{
+ unsigned int i, ic, ir, tw, th, rows, cols, size;
+ int dx, dy;
+
+ if (!detached)
+ return;
+ blitz_getbasegeometry((void **) detached, &size, &cols, &rows);
+ dx = (cols - 1) * GAP; /* GAPpx space */
+ dy = (rows - 1) * GAP; /* GAPpx space */
+ tw = (rect.width - dx) / cols;
+ th = (rect.height - dy) / rows;
+
+ XClearWindow(dpy, transient);
+ XMapRaised(dpy, transient);
+ i = 0;
+ for (ir = 0; ir < rows; ir++) {
+ for (ic = 0; ic < cols; ic++) {
+ Client *c = detached[i++];
+ XRectangle cr;
+ if (!c)
+ return;
+ cr.x = ic * tw + (ic * GAP);
+ cr.y = ir * th + (ir * GAP);
+ cr.width = tw;
+ cr.height = th;
+ XMoveResizeWindow(dpy, c->win, cr.x, cr.y, cr.width,
+ cr.height);
+ configure_client(c);
+ show_client(c);
+ XRaiseWindow(dpy, c->win);
+ grab_client(c, AnyModifier, AnyButton);
+ XSync(dpy, False);
+ }
+ }
+}
+
+
+static void icons(void *obj, char *cmd)
+{
+ XEvent ev;
+ int i, n;
+ Client *c;
+
+ if (!detached)
+ return;
+
+ XClearWindow(dpy, transient);
+ XMapRaised(dpy, transient);
+ draw_icons();
+ while (XGrabKeyboard
+ (dpy, transient, True, GrabModeAsync, GrabModeAsync,
+ CurrentTime) != GrabSuccess)
+ usleep(1000);
+
+ for (;;) {
+ while (!XCheckMaskEvent(dpy, ButtonPressMask | KeyPressMask, &ev)) {
+ usleep(20000);
+ continue;
+ }
+ switch (ev.type) {
+ case KeyPress:
+ XUnmapWindow(dpy, transient);
+ if ((n = handle_kpress(&ev.xkey)) != -1) {
+ for (i = 0; detached && detached[i]; i++)
+ hide_client(detached[i]);
+ if (n - 1 < i) {
+ c = detached[n];
+ detached =
+ (Client **) detach_item((void **) detached, c,
+ sizeof(Client *));
+ attach_client(c);
+ }
+ } else {
+ for (i = 0; detached && detached[i]; i++)
+ hide_client(detached[i]);
+ }
+ XUngrabKeyboard(dpy, CurrentTime);
+ return;
+ break;
+ case ButtonPress:
+ if (ev.xbutton.button == Button1) {
+ XUnmapWindow(dpy, transient);
+ for (i = 0; detached && detached[i]; i++)
+ hide_client(detached[i]);
+ if ((c = win_to_client(ev.xbutton.window))) {
+ detached =
+ (Client **) detach_item((void **) detached, c,
+ sizeof(Client *));
+ attach_client(c);
+ }
+ XUngrabKeyboard(dpy, CurrentTime);
+ }
+ return;
+ break;
+ }
+ }
+}
+
+static void _close_client(void *obj, char *cmd)
+{
+ Frame *f = pages ? SELFRAME(pages[sel]) : 0;
+ if (f->clients[f->sel])
+ close_client(f->clients[f->sel]);
+}
+
+static void _attach_client(void *obj, char *cmd)
+{
+ if (detached) {
+ Client *c = detached[0];
+ detached =
+ (Client **) detach_item((void **) detached, c,
+ sizeof(Client *));
+ attach_client(c);
+ }
+}
+
+static void _detach_client(void *obj, char *cmd)
+{
+ Frame *f;
+ if (!pages)
+ return;
+ f = SELFRAME(pages[sel]);
+ if (!f)
+ return;
+ detach_client_from_frame(f->clients[f->sel], 0, 0);
+}
+
+static void _select_page(void *obj, char *cmd)
+{
+ if (!pages || !cmd)
+ return;
+ if (!strncmp(cmd, "prev", 5))
+ sel = index_prev_item((void **) pages, pages[sel]);
+ else if (!strncmp(cmd, "next", 5))
+ sel = index_next_item((void **) pages, pages[sel]);
+ else
+ sel = _strtonum(cmd, 0, count_items((void **) pages));
+ focus_page(pages[sel], 0, 1);
+}
+
+static void _destroy_page(void *obj, char *cmd)
+{
+ if (!pages)
+ return;
+ destroy_page(pages[sel]);
+}
+
+static void new_page(void *obj, char *cmd)
+{
+ if (pages)
+ hide_page(pages[sel]);
+ alloc_page("0");
+}
+
+Client *win_to_client(Window w)
+{
+ int i;
+
+ for (i = 0; clients && clients[i]; i++)
+ if (clients[i]->win == w)
+ return clients[i];
+ return 0;
+}
+
+void scan_wins()
+{
+ int i;
+ unsigned int num;
+ Window *wins;
+ XWindowAttributes wa;
+ Window d1, d2;
+ Client *c;
+
+ if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
+ for (i = 0; i < num; i++) {
+ if (!XGetWindowAttributes(dpy, wins[i], &wa))
+ continue;
+ if (wa.override_redirect
+ || XGetTransientForHint(dpy, wins[i], &d1))
+ continue;
+ if (wa.map_state == IsViewable) {
+ c = alloc_client(wins[i]);
+ _init_client(c, &wa);
+ attach_client(c);
+ }
+ }
+ }
+ if (wins)
+ XFree(wins);
+}
+
+void *get_func(void *acttbl[][2], int rows, char *fname)
+{
+ int i;
+ for (i = 0; i < rows; i++) {
+ if (!strncmp((char *) acttbl[i][0], fname, MAX_BUF)) {
+ return acttbl[i][1];
+ }
+ }
+ return 0;
+}
+
+int win_proto(Window w)
+{
+ Atom *protocols;
+ long res;
+ int protos = 0;
+ int i;
+
+ res = property(dpy, w, wm_protocols, XA_ATOM,
+ 20L, ((unsigned char **) &protocols));
+ if (res <= 0) {
+ return protos;
+ }
+ for (i = 0; i < res; i++) {
+ if (protocols[i] == wm_delete) {
+ protos |= PROTO_DEL;
+ }
+ }
+ free((char *) protocols);
+ return protos;
+}
+
+int win_state(Window w)
+{
+ /* state hints */
+ XWMHints *hints = XGetWMHints(dpy, w);
+ int res;
+
+ long *prop = 0;
+ if (property(dpy, w, wm_state, wm_state,
+ 2L, ((unsigned char **) &prop)) > 0) {
+ res = (int) *prop;
+ free((long *) prop);
+ } else {
+ res = hints ? hints->initial_state : NormalState;
+ }
+
+ if (hints) {
+ free(hints);
+ }
+ return res;
+}
+
+void handle_after_write(IXPServer * s, File * f)
+{
+ if (f == defaults[WM_CTL])
+ run_action(f, 0, wm_acttbl);
+ else if (f == defaults[WM_TRANS_COLOR]) {
+ unsigned long col[1];
+ col[0] = xorcolor.pixel;
+ XFreeColors(dpy, DefaultColormap(dpy, screen_num), col, 1, 0);
+ XAllocNamedColor(dpy, DefaultColormap(dpy, screen_num),
+ defaults[WM_TRANS_COLOR]->content,
+ &xorcolor, &xorcolor);
+ XSetForeground(dpy, xorgc, xorcolor.pixel);
+ }
+ check_event(0);
+}
+
static void init_atoms()
{
wm_state = XInternAtom(dpy, "WM_STATE", False);
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -236,17 +236,6 @@ void show_client(Client * c);
void reparent_client(Client * c, Window w, int x, int y);
void focus_client(Client * c, int raise, int up);
-/* core.c */
-void invoke_core_event(File * f);
-void run_action(File * f, void *obj, Action * acttbl);
-void scan_wins();
-Client *win_to_client(Window w);
-int win_proto(Window w);
-int win_state(Window w);
-void handle_after_write(IXPServer * s, File * f);
-void detach(Frame * f, int client_destroyed);
-void set_client_state(Client * c, int state);
-
/* frame.c */
void focus_frame(Frame * f, int raise, int up, int down);
Frame *win_to_frame(Window w);
@@ -287,3 +276,14 @@ Layout *get_layout(char *name);
/* layout.c */
void init_layouts();
+
+/* wm.c */
+void invoke_wm_event(File * f);
+void run_action(File * f, void *obj, Action * acttbl);
+void scan_wins();
+Client *win_to_client(Window w);
+int win_proto(Window w);
+int win_state(Window w);
+void handle_after_write(IXPServer * s, File * f);
+void detach(Frame * f, int client_destroyed);
+void set_client_state(Client * c, int state);