2005-11-18 18:54:58 +03:00
|
|
|
/*
|
|
|
|
* (C)opyright MMIV-MMV Anselm R. Garbe <garbeam at gmail dot com>
|
|
|
|
* See LICENSE file for license details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "wm.h"
|
|
|
|
|
2005-12-05 01:45:59 +03:00
|
|
|
static void handle_after_write_page(IXPServer * s, File * f);
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-06 01:51:01 +03:00
|
|
|
/* action table for /?/ namespace */
|
2005-12-05 01:45:59 +03:00
|
|
|
Action page_acttbl[] = {
|
2005-11-18 18:54:58 +03:00
|
|
|
{0, 0}
|
|
|
|
};
|
|
|
|
|
2005-12-05 22:38:03 +03:00
|
|
|
Page *alloc_page()
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-08 03:31:23 +03:00
|
|
|
Page *p = cext_emallocz(sizeof(Page));
|
2005-12-06 01:51:01 +03:00
|
|
|
char buf[MAX_BUF], buf2[16];
|
2005-12-07 03:37:37 +03:00
|
|
|
size_t id = cext_sizeof(&pages);
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-06 01:51:01 +03:00
|
|
|
snprintf(buf2, sizeof(buf2), "%d", id);
|
2005-12-07 03:37:37 +03:00
|
|
|
p->areas.list = p->areas.stack = 0;
|
2005-12-06 01:51:01 +03:00
|
|
|
snprintf(buf, sizeof(buf), "/%d", id);
|
2005-12-05 22:38:03 +03:00
|
|
|
p->file[P_PREFIX] = ixp_create(ixps, buf);
|
2005-12-06 01:51:01 +03:00
|
|
|
snprintf(buf, sizeof(buf), "/%d/name", id);
|
|
|
|
p->file[P_NAME] = wmii_create_ixpfile(ixps, buf, buf2);
|
2005-12-09 00:12:12 +03:00
|
|
|
snprintf(buf, sizeof(buf), "/%d/layout/", id);
|
2005-12-05 22:38:03 +03:00
|
|
|
p->file[P_AREA_PREFIX] = ixp_create(ixps, buf);
|
2005-12-09 00:12:12 +03:00
|
|
|
snprintf(buf, sizeof(buf), "/%d/layout/sel", id);
|
2005-12-05 22:38:03 +03:00
|
|
|
p->file[P_SEL_AREA] = ixp_create(ixps, buf);
|
|
|
|
p->file[P_SEL_AREA]->bind = 1; /* mount point */
|
2005-12-06 01:51:01 +03:00
|
|
|
snprintf(buf, sizeof(buf), "/%d/ctl", id);
|
2005-12-05 22:38:03 +03:00
|
|
|
p->file[P_CTL] = ixp_create(ixps, buf);
|
|
|
|
p->file[P_CTL]->after_write = handle_after_write_page;
|
|
|
|
alloc_area(p, &rect, "float");
|
2005-12-07 03:37:37 +03:00
|
|
|
cext_attach_item(&pages, p);
|
2005-12-05 22:38:03 +03:00
|
|
|
def[WM_SEL_PAGE]->content = p->file[P_PREFIX]->content;
|
2005-12-09 01:48:32 +03:00
|
|
|
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
|
2005-11-18 18:54:58 +03:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2005-12-09 17:49:55 +03:00
|
|
|
static void iter_destroy_area(void *area, void *aux)
|
2005-12-05 03:36:39 +03:00
|
|
|
{
|
2005-12-09 17:49:55 +03:00
|
|
|
destroy_area((Area *)area);
|
2005-12-05 03:36:39 +03:00
|
|
|
}
|
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
void destroy_page(Page * p)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-09 17:49:55 +03:00
|
|
|
cext_list_iterate(&p->areas, nil, iter_destroy_area);
|
2005-12-05 04:50:02 +03:00
|
|
|
def[WM_SEL_PAGE]->content = 0;
|
2005-12-05 22:38:03 +03:00
|
|
|
ixp_remove_file(ixps, p->file[P_PREFIX]);
|
2005-12-09 17:49:55 +03:00
|
|
|
cext_detach_item(&pages, p);
|
2005-11-18 18:54:58 +03:00
|
|
|
free(p);
|
2005-12-09 17:49:55 +03:00
|
|
|
if ((p = get_sel_page()))
|
2005-12-07 03:37:37 +03:00
|
|
|
sel_page(p);
|
2005-12-09 17:49:55 +03:00
|
|
|
else
|
|
|
|
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-06 00:22:24 +03:00
|
|
|
void sel_page(Page * p)
|
2005-12-05 03:36:39 +03:00
|
|
|
{
|
2005-12-07 03:37:37 +03:00
|
|
|
Page *sel = get_sel_page();
|
|
|
|
if (!sel)
|
2005-12-05 03:36:39 +03:00
|
|
|
return;
|
2005-12-07 03:37:37 +03:00
|
|
|
if (p != sel) {
|
|
|
|
hide_page(sel);
|
2005-12-08 19:35:40 +03:00
|
|
|
cext_stack_top_item(&pages, p);
|
2005-12-07 03:37:37 +03:00
|
|
|
show_page(p);
|
2005-12-05 03:36:39 +03:00
|
|
|
}
|
2005-12-07 03:37:37 +03:00
|
|
|
def[WM_SEL_PAGE]->content = p->file[P_PREFIX]->content;
|
2005-12-05 22:38:03 +03:00
|
|
|
invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]);
|
2005-12-07 03:37:37 +03:00
|
|
|
sel_area(get_sel_area());
|
|
|
|
}
|
|
|
|
|
|
|
|
static void iter_draw_page(void *item, void *aux)
|
|
|
|
{
|
|
|
|
draw_area((Area *)item);
|
2005-12-05 03:36:39 +03:00
|
|
|
}
|
|
|
|
|
2005-12-05 01:45:59 +03:00
|
|
|
void draw_page(Page * p)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-09 17:49:55 +03:00
|
|
|
cext_list_iterate(&p->areas, nil, iter_draw_page);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-05 01:45:59 +03:00
|
|
|
XRectangle *rectangles(unsigned int *num)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-05 01:45:59 +03:00
|
|
|
XRectangle *result = 0;
|
|
|
|
int i, j = 0;
|
|
|
|
Window d1, d2;
|
|
|
|
Window *wins;
|
2005-11-18 18:54:58 +03:00
|
|
|
XWindowAttributes wa;
|
2005-12-05 01:45:59 +03:00
|
|
|
XRectangle r;
|
2005-11-18 18:54:58 +03:00
|
|
|
|
|
|
|
if (XQueryTree(dpy, root, &d1, &d2, &wins, num)) {
|
2005-12-08 03:31:23 +03:00
|
|
|
result = cext_emallocz(*num * sizeof(XRectangle));
|
2005-11-18 18:54:58 +03:00
|
|
|
for (i = 0; i < *num; i++) {
|
|
|
|
if (!XGetWindowAttributes(dpy, wins[i], &wa))
|
|
|
|
continue;
|
|
|
|
if (wa.override_redirect && (wa.map_state == IsViewable)) {
|
|
|
|
r.x = wa.x;
|
|
|
|
r.y = wa.y;
|
|
|
|
r.width = wa.width;
|
|
|
|
r.height = wa.height;
|
|
|
|
result[j++] = r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (wins) {
|
|
|
|
XFree(wins);
|
|
|
|
}
|
|
|
|
*num = j;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
static void iter_hide_page(void *item, void *aux)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-07 03:37:37 +03:00
|
|
|
hide_area((Area *)item);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
void hide_page(Page * p)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-09 17:49:55 +03:00
|
|
|
cext_list_iterate(&p->areas, nil, iter_hide_page);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
static void iter_show_page(void *item, void *aux)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-07 03:37:37 +03:00
|
|
|
show_area((Area *)item);
|
|
|
|
}
|
2005-11-18 18:54:58 +03:00
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
void show_page(Page * p)
|
|
|
|
{
|
2005-12-09 17:49:55 +03:00
|
|
|
cext_list_iterate(&p->areas, nil, iter_show_page);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
static void iter_after_write_page(void *item, void *aux)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-07 03:37:37 +03:00
|
|
|
Page *p = (Page *)item;
|
|
|
|
File *file = aux;
|
|
|
|
if (file == p->file[P_CTL]) {
|
|
|
|
run_action(file, p, page_acttbl);
|
|
|
|
return;
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-07 03:37:37 +03:00
|
|
|
static void handle_after_write_page(IXPServer *s, File *f)
|
2005-11-18 18:54:58 +03:00
|
|
|
{
|
2005-12-09 17:49:55 +03:00
|
|
|
cext_list_iterate(&pages, f, iter_after_write_page);
|
2005-11-18 18:54:58 +03:00
|
|
|
}
|
2005-12-06 20:58:52 +03:00
|
|
|
|
|
|
|
Page *get_sel_page()
|
|
|
|
{
|
2005-12-08 19:35:40 +03:00
|
|
|
return cext_stack_get_top_item(&pages);
|
2005-12-06 20:58:52 +03:00
|
|
|
}
|