From f8949ef5e8cfe09715040f5bb3f0690c6e446868 Mon Sep 17 00:00:00 2001 From: garbeam Date: Wed, 7 Dec 2005 02:37:37 +0200 Subject: [PATCH] proceeded with integration of Container struct --- cmd/wm/area.c | 78 +++++++------ cmd/wm/client.c | 13 ++- cmd/wm/event.c | 6 +- cmd/wm/frame.c | 186 +++++++++++++++-------------- cmd/wm/layout_column.c | 158 +++++++++++++------------ cmd/wm/layout_float.c | 34 +++--- cmd/wm/page.c | 257 +++++++++-------------------------------- cmd/wm/wm.c | 61 +++++----- cmd/wm/wm.h | 20 ++-- libcext/cext.h | 2 +- libcext/container.c | 5 +- libwmii/ixputil.c | 2 - libwmii/spawn.c | 2 - libwmii/wm.c | 6 +- 14 files changed, 346 insertions(+), 484 deletions(-) diff --git a/cmd/wm/area.c b/cmd/wm/area.c index 8005e991..a0bba59e 100644 --- a/cmd/wm/area.c +++ b/cmd/wm/area.c @@ -15,7 +15,7 @@ Area *alloc_area(Page *p, XRectangle * r, char *layout) { char buf[MAX_BUF]; Area *a = (Area *) cext_emalloc(sizeof(Area)); - int id = count_items((void **) p->area) + 1; + size_t id = cext_sizeof(&p->areas); *a = zero_area; a->rect = *r; @@ -34,82 +34,86 @@ Area *alloc_area(Page *p, XRectangle * r, char *layout) snprintf(buf, MAX_BUF, "/%s/a/%d/layout", p->file[P_PREFIX]->name, id); a->file[A_LAYOUT] = wmii_create_ixpfile(ixps, buf, layout); a->layout = get_layout(layout); - p->area = (Area **) attach_item_end((void **) p->area, a, sizeof(Area *)); + cext_attach_item(&p->areas, a); p->file[P_SEL_AREA]->content = a->file[A_PREFIX]->content; - p->sel = index_item((void **) p->area, a); return a; } -void destroy_area(Area * a) +static void iter_destroy_area(void *item, void *aux) +{ + destroy_frame((Frame *)item); + free((Frame *)item); +} + +void destroy_area(Area *a) { - unsigned int i; a->layout->deinit(a); - for (i = 0; a->frame && a->frame[i]; i++); - destroy_frame(a->frame[i]); - free(a->frame); + cext_iterate(&a->frames, nil, iter_destroy_area); ixp_remove_file(ixps, a->file[A_PREFIX]); free(a); } -void sel_area(Area * a, int raise) +static void iter_raise_frame(void *item, void *aux) +{ + XRaiseWindow(dpy, ((Frame *)item)->win); +} + +void sel_area(Area *a) { Page *p = a->page; - if (raise && a->frame) { - int i; - for (i = 0; a->frame[i]; i++) - if (i != a->sel) - XRaiseWindow(dpy, a->frame[i]->win); - } - p->sel = index_item((void **) p->area, a); + Frame *f; + Bool raise = cext_get_item_index(&p->areas, a) == 0; + if (raise) + cext_iterate(&a->frames, nil, iter_raise_frame); + cext_top_item(&p->areas, a); p->file[P_SEL_AREA]->content = a->file[A_PREFIX]->content; - if (a->frame) - sel_frame(a->frame[a->sel], raise); + if ((f = get_sel_frame_of_area(a))) + sel_frame(f, raise); } void attach_frame_to_area(Area * a, Frame * f) { wmii_move_ixpfile(f->file[F_PREFIX], a->file[A_FRAME_PREFIX]); a->file[A_SEL_FRAME]->content = f->file[F_PREFIX]->content; - a->frame = (Frame **) attach_item_end((void **) a->frame, f, sizeof(Frame *)); - a->sel = index_item((void **) a->frame, f); + cext_attach_item(&a->frames, f); f->area = a; } void detach_frame_from_area(Frame * f, int ignore_sel_and_destroy) { Area *a = f->area; - a->frame = (Frame **) detach_item((void **) a->frame, f, sizeof(Frame *)); + cext_detach_item(&a->frames, f); f->area = 0; - if (a->sel) - a->sel--; - else - a->sel = 0; } -void draw_area(Area * a) +void draw_area(Area *a) { - int i; - for (i = 0; a->frame && a->frame[i]; i++) - draw_frame(a->frame[i]); + cext_iterate(&a->frames, nil, draw_frame); +} + +static void iter_hide_area(void *item, void *aux) +{ + XUnmapWindow(dpy, ((Frame *)item)->win); } void hide_area(Area * a) { - int i; - for (i = 0; a->frame && a->frame[i]; i++) - XUnmapWindow(dpy, a->frame[i]->win); + cext_iterate(&a->frames, nil, iter_hide_area); +} + +static void iter_show_area(void *item, void *aux) +{ + XMapWindow(dpy, ((Frame *)item)->win); } void show_area(Area * a) { - int i; - for (i = 0; a->frame && a->frame[i]; i++) - XMapWindow(dpy, a->frame[i]->win); + cext_iterate(&a->frames, nil, iter_show_area); } Area *get_sel_area() { - Page *p = cext_get_top_item(&page); + Page *p = get_sel_page(); - return p ? p->area[p->sel] : nil; + return p ? cext_get_top_item(&p->areas) : nil; } diff --git a/cmd/wm/client.c b/cmd/wm/client.c index 742095ac..dea9f12f 100644 --- a/cmd/wm/client.c +++ b/cmd/wm/client.c @@ -184,7 +184,7 @@ void handle_client_property(Client * c, XPropertyEvent * e) c->file[C_NAME]->size = strlen(buf); } if (c->frame) - draw_client(c); + draw_client(c, nil); invoke_wm_event(def[WM_EVENT_CLIENT_UPDATE]); break; case XA_WM_TRANSIENT_FOR: @@ -209,7 +209,7 @@ void destroy_client(Client * c) } /* speed reasoned function for client property change */ -void draw_client(void *item) +void draw_client(void *item, void *aux) { Client *c = item; Frame *f = c->frame; @@ -235,7 +235,7 @@ void draw_client(void *item) void draw_clients(Frame * f) { - cext_iterate(&f->clients, draw_client); + cext_iterate(&f->clients, 0, draw_client); } void gravitate(Client * c, unsigned int tabh, unsigned int bw, int invert) @@ -311,15 +311,18 @@ void attach_client(Client * c) if (t && t->frame) a = t->frame->area; } + cext_attach_item(&a->clients, c); a->layout->attach(a, c); if (old) - draw_frame(old); + draw_frame(old, nil); invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]); } void detach_client(Client *c) { - if (c->frame) + if (c->frame) { + cext_detach_item(&c->frame->area->clients, c); c->frame->area->layout->detach(c->frame->area, c); + } if (c->destroyed) destroy_client(c); sel_page(get_sel_page()); diff --git a/cmd/wm/event.c b/cmd/wm/event.c index 0ef2470f..bc17c165 100644 --- a/cmd/wm/event.c +++ b/cmd/wm/event.c @@ -180,7 +180,7 @@ static void handle_expose(XEvent * e) if (e->xexpose.count == 0) { f = win_to_frame(e->xbutton.window); if (f) - draw_frame(f); + draw_frame(f, nil); } } @@ -249,8 +249,8 @@ static void handle_enternotify(XEvent * e) Frame *old = get_sel_frame(); if (old != c->frame) { sel_frame(c->frame, 1); - draw_frame(old); - draw_frame(c->frame); + draw_frame(old, nil); + draw_frame(c->frame, nil); } } } diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c index 436c1d78..93bb9885 100644 --- a/cmd/wm/frame.c +++ b/cmd/wm/frame.c @@ -102,7 +102,7 @@ Frame *alloc_frame(XRectangle * r) return f; } -void sel_frame(Frame * f, int raise) +void sel_frame(Frame * f, Bool raise) { Area *a = f->area; sel_client(cext_get_top_item(&f->clients)); @@ -122,12 +122,12 @@ static int comp_frame_win(void *pattern, void *frame) Frame *win_to_frame(Window w) { - return cext_find_item(&frames, w, comp_frame_win); + return cext_find_item(&frames, &w, comp_frame_win); } void destroy_frame(Frame * f) { - frame = (Frame **) detach_item((void **) frame, f, sizeof(Frame *)); + cext_detach_item(&frames, f); XFreeGC(dpy, f->gc); XDestroyWindow(dpy, f->win); ixp_remove_file(ixps, f->file[F_PREFIX]); @@ -150,24 +150,32 @@ unsigned int border_width(Frame * f) return 0; } -static void resize_client(Frame * f, int tabh, int bw) +typedef struct { + unsigned int tabh; + unsigned int bw; +} Twouint; + +static void iter_resize_client(void *item, void *aux) { - int i; - for (i = 0; f->client && f->client[i]; i++) { - Client *c = f->client[i]; - c->rect.x = bw; - c->rect.y = tabh ? tabh : bw; - c->rect.width = f->rect.width - 2 * bw; - c->rect.height = f->rect.height - bw - (tabh ? tabh : bw); - XMoveResizeWindow(dpy, c->win, c->rect.x, c->rect.y, - c->rect.width, c->rect.height); - configure_client(c); - } + Client *c = item; + Twouint *v = aux; + c->rect.x = v->bw; + c->rect.y = v->tabh ? v->tabh : v->bw; + c->rect.width = c->frame->rect.width - 2 * v->bw; + c->rect.height = c->frame->rect.height - v->bw - (v->tabh ? v->tabh : v->bw); + XMoveResizeWindow(dpy, c->win, c->rect.x, c->rect.y, c->rect.width, c->rect.height); + configure_client(c); +} + +static void resize_clients(Frame * f, int tabh, int bw) +{ + Twouint aux = { tabh, bw }; + cext_iterate(&f->clients, &aux, iter_resize_client); } static void check_dimensions(Frame * f, unsigned int tabh, unsigned int bw) { - Client *c = f->client ? f->client[f->sel] : 0; + Client *c = get_sel_client(); if (!c) return; @@ -191,7 +199,7 @@ static void check_dimensions(Frame * f, unsigned int tabh, unsigned int bw) static void resize_incremental(Frame * f, unsigned int tabh, unsigned int bw) { - Client *c = f->client ? f->client[f->sel] : 0; + Client *c = get_sel_client(); if (!c) return; /* increment stuff, see chapter 4.1.2.3 of the ICCCM Manual */ @@ -231,7 +239,7 @@ void resize_frame(Frame * f, XRectangle * r, XPoint * pt) resize_incremental(f, tabh, bw); XMoveResizeWindow(dpy, f->win, f->rect.x, f->rect.y, f->rect.width, f->rect.height); - resize_client(f, (tabh ? tabh : bw), bw); + resize_clients(f, (tabh ? tabh : bw), bw); } @@ -274,8 +282,9 @@ void draw_tab(Frame * f, char *text, int x, int y, int w, int h, int sel) * ./norm-style/bg-color "#RRGGBBAA" * ./norm-style/border-color "#RRGGBBAA [#RRGGBBAA [#RRGGBBAA [#RRGGBBAA]]]" */ -void draw_frame(Frame * f) +void draw_frame(void *frame, void *aux) { + Frame *f = frame; Draw d = { 0 }; int bw = border_width(f); XRectangle notch; @@ -289,7 +298,7 @@ void draw_frame(Frame * f) d.gc = f->gc; /* define ground plate (i = 0) */ - if (ISSELFRAME(f)) { + if (f == get_sel_frame()) { d.bg = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_BG_COLOR]->content); d.fg = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_FG_COLOR]->content); d.border = blitz_loadcolor(dpy, screen_num, f->file[F_SEL_BORDER_COLOR]->content); @@ -311,19 +320,16 @@ void draw_frame(Frame * f) void handle_frame_buttonpress(XButtonEvent * e, Frame * f) { Align align; - int bindex; - int size = count_items((void **) f->client); - int cindex = e->x / f->rect.width / size; - if (!f->area->page->sel) - XRaiseWindow(dpy, f->win); - if (cindex != f->sel) { - sel_client(f->client[cindex]); - draw_frame(f); + size_t size = cext_sizeof(&f->clients); + int bindex, cindex = e->x / f->rect.width / size; + Client *c = cext_get_item(&f->clients, cindex); + XRaiseWindow(dpy, f->win); + if (get_sel_client() != c) { + sel_client(c); + draw_frame(f, nil); return; } if (e->button == Button1) { - if (!(f = SELFRAME(page[sel]))) - return; align = cursor_to_align(f->cursor); if (align == CENTER) mouse_move(f); @@ -335,15 +341,14 @@ void handle_frame_buttonpress(XButtonEvent * e, Frame * f) /* frame mouse handling */ if (f->file[bindex]->content) spawn(dpy, f->file[bindex]->content); - draw_frame(f); + draw_frame(f, nil); } void attach_client_to_frame(Frame * f, Client * c) { wmii_move_ixpfile(c->file[C_PREFIX], f->file[F_CLIENT_PREFIX]); f->file[F_SEL_CLIENT]->content = c->file[C_PREFIX]->content; - f->client = (Client **) attach_item_end((void **) f->client, c, sizeof(Client *)); - f->sel = index_item((void **) f->client, c); + cext_attach_item(&f->clients, c); c->frame = f; reparent_client(c, f->win, border_width(f), tab_height(f)); resize_frame(f, &f->rect, 0); @@ -353,100 +358,89 @@ void attach_client_to_frame(Frame * f, Client * c) void detach_client_from_frame(Client * c) { + Client *client; Frame *f = c->frame; wmii_move_ixpfile(c->file[C_PREFIX], def[WM_DETACHED_CLIENT]); c->frame = 0; - f->client = (Client **) detach_item((void **) f->client, c, sizeof(Client *)); - if (f->sel) - f->sel--; - else - f->sel = 0; + cext_detach_item(&f->clients, c); if (!c->destroyed) { if (f) { hide_client(c); - detached = (Client **) attach_item_begin((void **) detached, c, sizeof(Client *)); + cext_attach_item(&detached, c); } reparent_client(c, root, border_width(f), tab_height(f)); } - if (f->client) { - sel_client(f->client[f->sel]); - draw_frame(f); + if ((client = cext_get_top_item(&f->clients))) { + sel_client(client); + draw_frame(f, nil); } } static void select_client(void *obj, char *cmd) { Frame *f = obj; - int size = count_items((void **) f->client); + size_t size = cext_sizeof(&f->clients); if (!f || !cmd || size == 1) return; - if (!strncmp(cmd, "prev", 5)) { - if (f->sel > 0) - f->sel--; - else - f->sel = size - 1; - } else if (!strncmp(cmd, "next", 5)) { - if (f->sel + 1 == size) - f->sel = 0; - else - f->sel++; - } - sel_client(f->client[f->sel]); - draw_frame(f); + if (!strncmp(cmd, "prev", 5)) + cext_top_item(&f->clients, cext_get_up_item(&f->clients, cext_get_top_item(&f->clients))); + else if (!strncmp(cmd, "next", 5)) + cext_top_item(&f->clients, cext_get_down_item(&f->clients, cext_get_top_item(&f->clients))); + sel_client(cext_get_top_item(&f->clients)); + draw_frame(f, nil); } -static void handle_before_read_frame(IXPServer * s, File * f) +static void iter_before_read_frame(void *item, void *aux) { - int i = 0; + Frame *f = item; + File *file = aux; + if (file == f->file[F_GEOMETRY]) { + char buf[64]; + snprintf(buf, 64, "%d,%d,%d,%d", f->rect.x, f->rect.y, f->rect.width, f->rect.height); + if (file->content) + free(file->content); + file->content = cext_estrdup(buf); + file->size = strlen(buf); + } +} - for (i = 0; frame && frame[i]; i++) { - if (f == frame[i]->file[F_GEOMETRY]) { - char buf[64]; - snprintf(buf, 64, "%d,%d,%d,%d", frame[i]->rect.x, - frame[i]->rect.y, frame[i]->rect.width, - frame[i]->rect.height); - if (f->content) - free(f->content); - f->content = cext_estrdup(buf); - f->size = strlen(buf); - return; +static void handle_before_read_frame(IXPServer *s, File *f) +{ + cext_iterate(&frames, f, iter_before_read_frame); +} + +static void iter_after_write_frame(void *item, void *aux) +{ + Frame *f = item; + File *file = aux; + if (file == f->file[F_CTL]) { + run_action(file, f, frame_acttbl); + return; + } + if (file == f->file[F_TAB] || file == f->file[F_BORDER] || file == f->file[F_HANDLE_INC]) { + f->area->layout->arrange(f->area); + draw_page(f->area->page); + return; + } else if (file == f->file[F_GEOMETRY]) { + char *size = f->file[F_GEOMETRY]->content; + if (size && strrchr(size, ',')) { + XRectangle frect; + blitz_strtorect(&rect, &frect, size); + resize_frame(f, &frect, 0); + draw_page(f->area->page); } + return; } } static void handle_after_write_frame(IXPServer * s, File * f) { - int i; - - for (i = 0; frame && frame[i]; i++) { - if (f == frame[i]->file[F_CTL]) { - run_action(f, frame[i], frame_acttbl); - return; - } - if (f == frame[i]->file[F_TAB] - || f == frame[i]->file[F_BORDER] - || f == frame[i]->file[F_HANDLE_INC]) { - if (frame[i]->area) { - frame[i]->area->layout->arrange(frame[i]->area); - draw_page(frame[i]->area->page); - } - return; - } else if (f == frame[i]->file[F_GEOMETRY]) { - char *size = frame[i]->file[F_GEOMETRY]->content; - if (size && strrchr(size, ',')) { - XRectangle frect; - blitz_strtorect(&rect, &frect, size); - resize_frame(frame[i], &frect, 0); - draw_page(frame[i]->area->page); - } - return; - } - } + cext_iterate(&frames, f, iter_after_write_frame); } Frame *get_sel_frame_of_area(Area *a) { - return cext_get_top_item(&a->frame); + return cext_get_top_item(&a->frames); } Frame *get_sel_frame() diff --git a/cmd/wm/layout_column.c b/cmd/wm/layout_column.c index f686891f..c9a606a8 100644 --- a/cmd/wm/layout_column.c +++ b/cmd/wm/layout_column.c @@ -15,13 +15,13 @@ typedef struct Column Column; struct Acme { int sel; - Column **column; + Container columns; }; struct Column { int sel; int refresh; - Frame **frame; + Container frames; XRectangle rect; }; @@ -39,43 +39,47 @@ static Acme zero_acme = { 0 }; void init_layout_column() { - layouts = (Layout **) attach_item_end((void **) layouts, &lcol, sizeof(Layout *)); + cext_attach_item(&layouts, &lcol); } - -static void arrange_column(Area * a, Column * col) +static Column *get_sel_column(Acme *acme) { - int i; - int n = count_items((void **) col->frame); - unsigned int height = a->rect.height / n; - for (i = 0; col->frame && col->frame[i]; i++) { - if (col->refresh) { - col->frame[i]->rect = col->rect; - col->frame[i]->rect.height = height; - col->frame[i]->rect.y = i * height; - } - resize_frame(col->frame[i], &col->frame[i]->rect, 0); - } + return cext_get_top_item(&acme->columns); } -static void arrange_col(Area * a) +static void iter_arrange_column_frame(void *frame, void *height) +{ + unsigned int h = *(unsigned int *)height; + Frame *f = frame; + Column *col = f->aux; + if (col->refresh) { + f->rect = col->rect; + f->rect.height = h; + f->rect.y = cext_get_item_index(&col->frames, f) * h; + } + resize_frame(f, &f->rect, 0); +} + +static void iter_arrange_column(void *column, void *area) +{ + Column *col = column; + size_t size = cext_sizeof(&col->frames); + unsigned int height = ((Area *)area)->rect.height / size; + cext_iterate(&col->frames, &height, iter_arrange_column_frame); +} + +static void arrange_col(Area *a) { Acme *acme = a->aux; - int i; - - if (!acme) { - fprintf(stderr, "%s", "wmiiwm: fatal, page has no layout\n"); - exit(1); - } - for (i = 0; acme->column && acme->column[i]; i++) - arrange_column(a, acme->column[i]); + cext_iterate(&acme->columns, a, iter_arrange_column); } -static void init_col(Area * a) +static void init_col(Area *a) { Acme *acme = cext_emalloc(sizeof(Acme)); - int i, j, n, cols = 1; - unsigned int width = 1; + int i, cols = 1; + unsigned int width; + //size_t size; Column *col; *acme = zero_acme; @@ -83,28 +87,27 @@ static void init_col(Area * a) /* processing argv */ /* - for (i = 1; (i < argc) && (argv[i][0] == '-'); i++) { - switch (argv[i][1]) { - case 'c': - cols = _strtonum(argv[++i], 0, 32); - if (cols < 1) - cols = 1; - break; - } - } - */ + for (i = 1; (i < argc) && (argv[i][0] == '-'); i++) { + switch (argv[i][1]) { + case 'c': + cols = _strtonum(argv[++i], 0, 32); + if (cols < 1) + cols = 1; + break; + } + } + */ width = a->rect.width / cols; - acme->column = cext_emalloc((cols + 1) * sizeof(Column *)); for (i = 0; i < cols; i++) { - acme->column[i] = cext_emalloc(sizeof(Column)); - *acme->column[i] = zero_column; - acme->column[i]->rect = a->rect; - acme->column[i]->rect.x = i * width; - acme->column[i]->rect.width = width; - acme->column[i]->refresh = 1; + col = cext_emalloc(sizeof(Column)); + *col = zero_column; + col->rect = a->rect; + col->rect.x = i * width; + col->rect.width = width; + col->refresh = 1; + cext_attach_item(&acme->columns, col); } - acme->column[cols] = 0; /* null termination of array */ /* * Frame attaching strategy works as follows: 1. If more client than @@ -113,8 +116,9 @@ static void init_col(Area * a) * than column exist, than filling begins from eastmost to westmost * column until no more client exist. */ - n = count_items((void **) client); - if (n > cols) { +#if 0 + size = cext_sizeof(&a->clients); + if (size > cols) { /* 1st. case */ j = 0; for (i = 0; i < (cols - 1); i++) { @@ -147,56 +151,56 @@ static void init_col(Area * a) } } arrange_col(a); +#endif } -static void deinit_col(Area * a) +static void iter_detach_client(void *client, void *aux) +{ + detach_client_from_frame((Client *)client); +} + +static void iter_detach_frame(void *frame, void *aux) +{ + Frame *f = frame; + cext_iterate(&f->clients, nil, iter_detach_client); +} + +static void iter_deinit_col(void *column, void *aux) +{ + Column *col = column; + cext_iterate(&col->frames, nil, iter_detach_frame); +} + +static void deinit_col(Area *a) { Acme *acme = a->aux; - int i; - - for (i = 0; acme->column && acme->column[i]; i++) { - Column *col = acme->column[i]; - int j; - for (j = 0; col->frame && col->frame[j]; j++) { - Frame *f = col->frame[j]; - while (f->client && f->client[0]) - detach_client_from_frame(f->client[0]); - detach_frame_from_area(f, 1); - destroy_frame(f); - } - free(col->frame); - } - free(acme->column); + cext_iterate(&acme->columns, nil, iter_deinit_col); free(acme); a->aux = 0; } -static void attach_col(Area * a, Client * c) +static void attach_col(Area *a, Client *c) { Acme *acme = a->aux; Column *col; Frame *f; - col = acme->column[acme->sel]; + col = get_sel_column(acme); f = alloc_frame(&c->rect); - col->frame = (Frame **) attach_item_end((void **) col->frame, f, sizeof(Frame *)); + cext_attach_item(&col->frames, f); f->aux = col; col->refresh = 1; attach_frame_to_area(a, f); attach_client_to_frame(f, c); - arrange_col(a); } -static void detach_col(Area * a, Client * c) +static void detach_col(Area *a, Client *c) { Frame *f = c->frame; Column *col = f->aux; - if (!col) - return; /* client was not attached, maybe exit(1) in - * such case */ - col->frame = (Frame **) detach_item((void **) col->frame, c->frame, sizeof(Frame *)); + cext_detach_item(&col->frames, f); col->refresh = 1; detach_client_from_frame(c); detach_frame_from_area(f, 1); @@ -207,6 +211,7 @@ static void detach_col(Area * a, Client * c) static void drop_resize(Frame * f, XRectangle * new) { +#if 0 Column *col = f->aux; Acme *acme = f->area->aux; int i, idx, n = 0; @@ -299,10 +304,12 @@ static void drop_resize(Frame * f, XRectangle * new) resize_frame(south, &south->rect, 0); } } +#endif } static void _drop_move(Frame * f, XRectangle * new, XPoint * pt) { +#if 0 Column *tgt = 0, *src = f->aux; Acme *acme = f->area->aux; int i; @@ -351,13 +358,14 @@ static void _drop_move(Frame * f, XRectangle * new, XPoint * pt) (Frame **) attach_item_end((void **) tgt->frame, f, sizeof(Frame *)); tgt->refresh = 1; - arrange_column(f->area, tgt); + iter_arrange_column(tgt, f->area); /* TODO: implement a better target placing strategy */ } +#endif } -static void resize_col(Frame * f, XRectangle * new, XPoint * pt) +static void resize_col(Frame *f, XRectangle *new, XPoint *pt) { if ((f->rect.width == new->width) && (f->rect.height == new->height)) diff --git a/cmd/wm/layout_float.c b/cmd/wm/layout_float.c index 8b2bb8c5..85767c31 100644 --- a/cmd/wm/layout_float.c +++ b/cmd/wm/layout_float.c @@ -10,36 +10,36 @@ #include "wm.h" #include "layout.h" -static void init_float(Area * a); -static void deinit_float(Area * a); -static void arrange_float(Area * a); -static void attach_float(Area * a, Client * c); -static void detach_float(Area * a, Client * c); -static void resize_float(Frame * f, XRectangle * new, XPoint * pt); +static void init_float(Area *a); +static void deinit_float(Area *a); +static void arrange_float(Area *a); +static void attach_float(Area *a, Client *c); +static void detach_float(Area *a, Client *c); +static void resize_float(Frame *f, XRectangle *new, XPoint *pt); static Layout lfloat = { "float", init_float, deinit_float, arrange_float, attach_float, detach_float, resize_float }; void init_layout_float() { - layouts = (Layout **) attach_item_end((void **) layouts, &lfloat, sizeof(Layout *)); + cext_attach_item(&layouts, &lfloat); } -static void arrange_float(Area * a) +static void arrange_float(Area *a) { } -static void init_float(Area * a) +static void init_float(Area *a) { } -static void deinit_float(Area * a) +static void deinit_float(Area *a) { } -static void attach_float(Area * a, Client * c) +static void attach_float(Area *a, Client *c) { - Frame *f = a->frame ? a->frame[a->sel] : 0; + Frame *f = get_sel_frame_of_area(a); /* check for tabbing? */ if (f && (((char *) f->file[F_LOCKED]->content)[0] == '1')) f = 0; @@ -48,16 +48,16 @@ static void attach_float(Area * a, Client * c) attach_frame_to_area(a, f); } attach_client_to_frame(f, c); - if (a->page == page[sel]) + if (a->page == get_sel_page()) XMapRaised(dpy, f->win); - draw_frame(f); + draw_frame(f, nil); } -static void detach_float(Area * a, Client * c) +static void detach_float(Area *a, Client *c) { Frame *f = c->frame; - detach_client_from_frame(f->client[0]); - if (!f->client) { + detach_client_from_frame(c); + if (!cext_sizeof(&f->clients)) { detach_frame_from_area(f, 0); destroy_frame(f); } diff --git a/cmd/wm/page.c b/cmd/wm/page.c index 88b59daa..8eeb6048 100644 --- a/cmd/wm/page.c +++ b/cmd/wm/page.c @@ -9,8 +9,6 @@ #include "wm.h" -static Page zero_page = { 0 }; - static void select_frame(void *obj, char *cmd); static void handle_after_write_page(IXPServer * s, File * f); @@ -24,10 +22,10 @@ Page *alloc_page() { Page *p = cext_emalloc(sizeof(Page)); char buf[MAX_BUF], buf2[16]; - int id = count_items((void **) page) + 1; + size_t id = cext_sizeof(&pages); snprintf(buf2, sizeof(buf2), "%d", id); - *p = zero_page; + p->areas.list = p->areas.stack = 0; snprintf(buf, sizeof(buf), "/%d", id); p->file[P_PREFIX] = ixp_create(ixps, buf); snprintf(buf, sizeof(buf), "/%d/name", id); @@ -41,62 +39,53 @@ Page *alloc_page() p->file[P_CTL] = ixp_create(ixps, buf); p->file[P_CTL]->after_write = handle_after_write_page; alloc_area(p, &rect, "float"); - page = (Page **) attach_item_end((void **) page, p, sizeof(Page *)); - sel = index_item((void **) page, p); + cext_attach_item(&pages, p); def[WM_SEL_PAGE]->content = p->file[P_PREFIX]->content; return p; } -void destroy_page(Page * p) +static void iter_destroy_page(void *item, void *aux) { - unsigned int i; - for (i = 0; p->area[i]; i++) - destroy_area(p->area[i]); - free_page(p); - if (page) { - show_page(page[sel]); - def[WM_SEL_PAGE]->content = page[sel]->file[P_PREFIX]->content; - sel_page(page[sel]); - } + destroy_area((Area *)item); } -void free_page(Page * p) +void destroy_page(Page * p) { - page = (Page **) detach_item((void **) page, p, sizeof(Page *)); - if (page) { - if (sel - 1 >= 0) - sel--; - else - sel = 0; - } + cext_iterate(&p->areas, nil, iter_destroy_page); def[WM_SEL_PAGE]->content = 0; ixp_remove_file(ixps, p->file[P_PREFIX]); if (ixps->errstr) fprintf(stderr, "wmiiwm: free_page(): %s\n", ixps->errstr); free(p); + if ((p = get_sel_page())) { + show_page(p); + sel_page(p); + } } void sel_page(Page * p) { - if (!page) + Page *sel = get_sel_page(); + if (!sel) return; - if (p != page[sel]) { - hide_page(page[sel]); - sel = index_item((void **) page, p); - show_page(page[sel]); - def[WM_SEL_PAGE]->content = p->file[P_PREFIX]->content; + if (p != sel) { + hide_page(sel); + cext_top_item(&pages, p); + show_page(p); } + def[WM_SEL_PAGE]->content = p->file[P_PREFIX]->content; invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]); - sel_area(p->area[p->sel], !p->sel); + sel_area(get_sel_area()); +} + +static void iter_draw_page(void *item, void *aux) +{ + draw_area((Area *)item); } void draw_page(Page * p) { - int i; - if (!p) - return; - for (i = 0; p->area && p->area[i]; i++) - draw_area(p->area[i]); + cext_iterate(&p->areas, nil, iter_draw_page); } XRectangle *rectangles(unsigned int *num) @@ -152,196 +141,60 @@ static void center_pointer(Frame * f) static void select_frame(void *obj, char *cmd) { - int i; + Area *a; Frame *f, *old; - f = old = page ? SELFRAME(page[sel]) : 0; + f = old = get_sel_frame(); if (!f || !cmd) return; - if (!strncmp(cmd, "prev", 5)) { - i = index_prev_item((void **) f->area->frame, f); - f = f->area->frame[i]; - } else if (!strncmp(cmd, "next", 5)) { - i = index_next_item((void **) f->area->frame, f); - f = f->area->frame[i]; - } + a = f->area; + if (!strncmp(cmd, "prev", 5)) + cext_top_item(&a->frames, cext_get_up_item(&a->frames, f)); + else if (!strncmp(cmd, "next", 5)) + cext_top_item(&a->frames, cext_get_down_item(&a->frames, f)); if (old != f) { - sel_frame(f, 1); + sel_frame(f, cext_get_item_index(&a->page->areas, a) == 0); center_pointer(f); - draw_frame(old); - draw_frame(f); + draw_frame(old, nil); + draw_frame(f, nil); } } +static void iter_hide_page(void *item, void *aux) +{ + hide_area((Area *)item); +} + void hide_page(Page * p) { + cext_iterate(&p->areas, nil, iter_hide_page); +} - int i; - for (i = 0; p->area && p->area[i]; i++) - hide_area(p->area[i]); +static void iter_show_page(void *item, void *aux) +{ + show_area((Area *)item); } void show_page(Page * p) { - int i; - for (i = 0; p->area && p->area[i]; i++) - show_area(p->area[i]); + cext_iterate(&p->areas, nil, iter_show_page); } -static void handle_after_write_page(IXPServer * s, File * f) +static void iter_after_write_page(void *item, void *aux) { - int i; - - for (i = 0; page && page[i]; i++) { - Page *p = page[i]; - if (p->file[P_CTL] == f) { - run_action(f, p, page_acttbl); - return; - } - /* - else if (p->file[P_MANAGED_SIZE] == f) { - / resize stuff / - blitz_strtorect(dpy, &rect, &p->managed_rect, - p->file[P_MANAGED_SIZE]->content); - if (!p->managed_rect.width) - p->managed_rect.width = 10; - if (!p->managed_rect.height) - p->managed_rect.height = 10; - if (p->layout) - p->layout->arrange(p); - draw_page(p); - return; - } else if (p->file[P_MANAGED_LAYOUT] == f) { - int had_valid_layout = p->layout ? 1 : 0; - if (p->layout) - p->layout->deinit(p); - p->layout = get_layout(p->file[P_MANAGED_LAYOUT]->content); - if (p->layout) { - p->layout->init(p); - p->layout->arrange(p); - if (!had_valid_layout) { - int j; - Frame **tmp = 0; - for (j = 0; p->floating && p->floating[j]; j++) { - if (!p->floating[j]->floating) - tmp = - (Frame **) attach_item_begin((void **) tmp, - p-> - floating[j], - sizeof(Frame - *)); - } - for (j = 0; tmp && tmp[j]; j++) - toggle_frame(tmp[j]); - free(tmp); - } - } - if (!p->layout) { - / make all managed client floating / - int j; - Frame **tmp = 0; - while (p->managed) { - tmp = (Frame **) attach_item_begin((void **) tmp, - p->managed[0], - sizeof(Frame *)); - detach_frame_from_page(p->managed[0], 1); - } - for (j = 0; tmp && tmp[j]; j++) { - attach_Frameo_page(p, tmp[j], 0); - resize_frame(tmp[j], rect_of_frame(tmp[j]), 0, 1); - } - free(tmp); - } - draw_page(p); - invoke_wm_event(wm_file[CORE_EVENT_PAGE_UPDATE]); - return; - } - */ + Page *p = (Page *)item; + File *file = aux; + if (file == p->file[P_CTL]) { + run_action(file, p, page_acttbl); + return; } } -/* -void -attach_frame_to_page(Page * p, Frame * f, int managed) +static void handle_after_write_page(IXPServer *s, File *f) { - Frame *old = get_selected(p); - XSelectInput(dpy, root, ROOT_MASK & ~StructureNotifyMask); - XMapRaised(dpy, f->win); - if (!f->floating && managed && p->layout) { - int i; - p->managed = (Frame **) attach_item_end((void **) p->managed, f, - sizeof(Frame *)); - p->managed_stack = - (Frame **) attach_item_begin((void **) p->managed_stack, f, - sizeof(Frame *)); - wmii_move_ixpfile(f->file[F_PREFIX], p->file[P_MANAGED_PREFIX]); - p->file[P_MANAGED_SELECTED]->content = - f->file[F_PREFIX]->content; - if (p == page[sel_page]) - for (i = 0; p->floating && p->floating[i]; i++) - XRaiseWindow(dpy, p->floating[i]->win); - } else { - p->floating = (Frame **) attach_item_end((void **) p->floating, f, - sizeof(Frame *)); - p->floating_stack = - (Frame **) attach_item_begin((void **) p->floating_stack, f, - sizeof(Frame *)); - wmii_move_ixpfile(f->file[F_PREFIX], p->file[P_FLOATING_PREFIX]); - p->file[P_FLOATING_SELECTED]->content = - f->file[F_PREFIX]->content; - p->file[P_MODE]->content = p->file[P_FLOATING_PREFIX]->content; - } - f->page = p; - sel_frame(f, 1, 0, 1); - if (is_managed_frame(f) && p->layout) - p->layout->manage(f); - center_pointer(f); - if (old) - draw_frame(old); - draw_frame(f); + cext_iterate(&pages, f, iter_after_write_page); } -void -detach_frame_from_page(Frame * f, int ignore_sel_and_destroy) -{ - Page *p = f->page; - wmii_move_ixpfile(f->file[F_PREFIX], wm_file[CORE_DETACHED_FRAME]); - if (is_managed_frame(f)) { - p->managed = (Frame **) detach_item((void **) p->managed, f, - sizeof(Frame *)); - p->managed_stack = - (Frame **) detach_item((void **) p->managed_stack, f, - sizeof(Frame *)); - p->file[P_MANAGED_SELECTED]->content = 0; - } else { - p->floating = (Frame **) detach_item((void **) p->floating, f, - sizeof(Frame *)); - p->floating_stack = - (Frame **) detach_item((void **) p->floating_stack, f, - sizeof(Frame *)); - p->file[P_FLOATING_SELECTED]->content = 0; - } - XUnmapWindow(dpy, f->win); - if (is_managed_mode(p) && p->layout) - p->layout->unmanage(f); - f->page = 0; - if (!ignore_sel_and_destroy) { - Frame *fr; - if (!p->managed && !p->floating - && _strtonum(p->file[P_AUTO_DESTROY]->content, 0, 1)) { - destroy_page(p); - return; - } - sel_page(p, 0, 1); - fr = get_selected(p); - if (fr) { - center_pointer(fr); - draw_frame(fr); - } - } -} -*/ - Page *get_sel_page() { - return cext_get_top_item(&page); + return cext_get_top_item(&pages); } diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c index a75df815..5f987342 100644 --- a/cmd/wm/wm.c +++ b/cmd/wm/wm.c @@ -16,7 +16,6 @@ #include "wm.h" -static Draw d = { 0 }; static XRectangle initial_rect; static int other_wm_running; static int (*x_error_handler) (Display *, XErrorEvent *); @@ -112,51 +111,53 @@ scale_rect(XRectangle * from_dim, XRectangle * to_dim, tgt->height = 1; } -static void draw_pager_frame(void *item) +static void iter_draw_pager_frame(void *item, void *aux) { + Draw *d = aux; Frame *f = (Frame *)item; if (f == cext_get_top_item(&f->area->frames)) { - d.bg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BG_COLOR]->content); - d.fg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_FG_COLOR]->content); - d.border = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BORDER_COLOR]->content); + d->bg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BG_COLOR]->content); + d->fg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_FG_COLOR]->content); + d->border = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BORDER_COLOR]->content); } else { - d.bg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BG_COLOR]->content); - d.fg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_FG_COLOR]->content); - d.border = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BORDER_COLOR]->content); + d->bg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BG_COLOR]->content); + d->fg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_FG_COLOR]->content); + d->border = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BORDER_COLOR]->content); } - d.data = ((Client *)cext_get_top_item(&f->clients))->file[C_NAME]->content; - scale_rect(&rect, &initial_rect, &f->area->rect, &d.rect); - blitz_drawlabel(dpy, &d); + d->data = ((Client *)cext_get_top_item(&f->clients))->file[C_NAME]->content; + scale_rect(&rect, &initial_rect, &f->area->rect, &d->rect); + blitz_drawlabel(dpy, d); XSync(dpy, False); /* do not clear upwards */ } -static void draw_pager_area(void *item) +static void draw_pager_area(void *item, void *aux) { - cext_iterate(&((Area *)item)->frames, draw_pager_frame); + cext_iterate(&((Area *)item)->frames, aux, iter_draw_pager_frame); } -static void draw_pager_page(Page * p) +static void draw_pager_page(Page *p, Draw *d) { char name[4]; - initial_rect = d.rect; + initial_rect = d->rect; if (p == cext_get_top_item(&pages)) { - d.bg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BG_COLOR]->content); - d.fg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_FG_COLOR]->content); - d.border = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BORDER_COLOR]->content); + d->bg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BG_COLOR]->content); + d->fg = blitz_loadcolor(dpy, screen_num, def[WM_SEL_FG_COLOR]->content); + d->border = blitz_loadcolor(dpy, screen_num, def[WM_SEL_BORDER_COLOR]->content); } else { - d.bg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BG_COLOR]->content); - d.fg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_FG_COLOR]->content); - d.border = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BORDER_COLOR]->content); + d->bg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BG_COLOR]->content); + d->fg = blitz_loadcolor(dpy, screen_num, def[WM_NORM_FG_COLOR]->content); + d->border = blitz_loadcolor(dpy, screen_num, def[WM_NORM_BORDER_COLOR]->content); } snprintf(name, sizeof(name), "%d", cext_get_item_index(&pages, p)); - d.data = name; - blitz_drawlabel(dpy, &d); + d->data = name; + blitz_drawlabel(dpy, d); XSync(dpy, False); - cext_iterate(&p->areas, draw_pager_area); + cext_iterate(&p->areas, d, draw_pager_area); } static void draw_pager() { + Draw d = { 0 }; unsigned int ic, ir, tw, th, rows, cols, size; int i = 0; int dx; @@ -180,7 +181,7 @@ static void draw_pager() d.rect.height = th; if (!(p = cext_get_item(&pages, i))) return; - draw_pager_page(p); + draw_pager_page(p, &d); i++; } } @@ -677,7 +678,7 @@ static int startup_error_handler(Display * dpy, XErrorEvent * error) return -1; } -static void clean_client_up(void *item) +static void clean_client_up(void *item, void *aux) { Client *c = item; Frame *f = c->frame; @@ -693,7 +694,7 @@ static void clean_client_up(void *item) static void cleanup() { - cext_iterate(&clients, clean_client_up); + cext_iterate(&clients, nil, clean_client_up); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); } @@ -708,6 +709,12 @@ static void run() } def[WM_CTL]->after_write = handle_after_write; + detached.list = detached.stack = 0; + pages.list = pages.stack = 0; + frames.list = frames.stack = 0; + clients.list = clients.stack = 0; + layouts.list = layouts.stack = 0; + init_atoms(); init_cursors(); init_default(); diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h index 1c63a8bc..6c9a75f6 100644 --- a/cmd/wm/wm.h +++ b/cmd/wm/wm.h @@ -129,6 +129,8 @@ struct Area { Layout *layout; Page *page; Container frames; + /* XXX: remove frames container, areas shall only contain clients */ + Container clients; XRectangle rect; void *aux; /* free pointer */ File *file[A_LAST]; @@ -165,11 +167,11 @@ int screen_num; Window root; Window transient; XRectangle rect; -Container detached = {0}; -Container pages = {0}; -Container frames = {0}; -Container clients = {0}; -Container layouts = {0}; +Container detached; +Container pages; +Container frames; +Container clients; +Container layouts; XFontStruct *font; XColor xorcolor; GC xorgc; @@ -203,7 +205,7 @@ unsigned int valid_mask, num_lock_mask; /* area.c */ Area *alloc_area(Page *p, XRectangle * r, char *layout); void destroy_area(Area * a); -void sel_area(Area * a, int raise); +void sel_area(Area * a); void attach_frame_to_area(Area * a, Frame * f); void detach_frame_from_area(Frame * f, int ignore_sel_and_destroy); void draw_area(Area * a); @@ -218,7 +220,7 @@ void destroy_client(Client * c); void configure_client(Client * c); void handle_client_property(Client * c, XPropertyEvent * e); void close_client(Client * c); -void draw_client(void *item); +void draw_client(void *item, void *aux); void draw_clients(Frame * f); void gravitate(Client * c, unsigned int tabh, unsigned int bw, int invert); void grab_client(Client * c, unsigned long mod, unsigned int button); @@ -232,12 +234,12 @@ void detach_client(Client *c); Client *get_sel_client(); /* frame.c */ -void sel_frame(Frame * f, int raise); +void sel_frame(Frame * f, Bool raise); Frame *win_to_frame(Window w); Frame *alloc_frame(XRectangle * r); void destroy_frame(Frame * f); void resize_frame(Frame * f, XRectangle * r, XPoint * pt); -void draw_frame(Frame * f); +void draw_frame(void *frame, void *aux); void handle_frame_buttonpress(XButtonEvent * e, Frame * f); void attach_client_to_frame(Frame * f, Client * c); void detach_client_from_frame(Client *c); diff --git a/libcext/cext.h b/libcext/cext.h index fe0bd4af..2c38db77 100644 --- a/libcext/cext.h +++ b/libcext/cext.h @@ -35,7 +35,7 @@ void cext_attach_item(Container *c, void *item); void cext_detach_item(Container *c, void *item); void *cext_find_item(Container *c, void *pattern, int (*comp)(void *pattern, void *item)); void cext_top_item(Container *c, void *item); -void cext_iterate(Container *c, void (*doit)(void *)); +void cext_iterate(Container *c, void *aux, void (*iter)(void *, void *aux)); void *cext_get_top_item(Container *c); void *cext_get_down_item(Container *c, void *item); void *cext_get_up_item(Container *c, void *item); diff --git a/libcext/container.c b/libcext/container.c index b6edf36d..31ade29f 100644 --- a/libcext/container.c +++ b/libcext/container.c @@ -76,11 +76,11 @@ void *cext_find_item(Container *c, void *pattern, int (*comp)(void *pattern, voi return i ? i->item : nil; } -void cext_iterate(Container *c, void (*doit)(void *)) +void cext_iterate(Container *c, void *aux, void (*iter)(void *, void *aux)) { CItem *i; for (i = c->list; i; i = i->next) - doit(i->item); + iter(i->item, aux); } void cext_top_item(Container *c, void *item) @@ -88,7 +88,6 @@ void cext_top_item(Container *c, void *item) CItem *i = cext_find_item(c, item, comp_ptr); if (!i) return; - detach_from_stack(i); attach_to_stack(c, i); } diff --git a/libwmii/ixputil.c b/libwmii/ixputil.c index 401a844a..310f2edf 100644 --- a/libwmii/ixputil.c +++ b/libwmii/ixputil.c @@ -12,8 +12,6 @@ #include "wmii.h" -#include - static pid_t mypid; static char *mysockfile; diff --git a/libwmii/spawn.c b/libwmii/spawn.c index 98abcad2..c6a08c1a 100644 --- a/libwmii/spawn.c +++ b/libwmii/spawn.c @@ -11,8 +11,6 @@ #include "wmii.h" -#include - void spawn(void *dpy, char *cmd) { /* the questionable double-fork is done to catch all zombies */ diff --git a/libwmii/wm.c b/libwmii/wm.c index b6d2812e..3d40886c 100644 --- a/libwmii/wm.c +++ b/libwmii/wm.c @@ -13,11 +13,7 @@ #include "blitz.h" -#include - -int -property(Display * dpy, Window w, Atom a, Atom t, long l, - unsigned char **prop) +int property(Display * dpy, Window w, Atom a, Atom t, long l, unsigned char **prop) { Atom real; int format;