From caa90c89a09fe03c144922d44e3137e4c1fe5d8e Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Sun, 25 Sep 2011 23:12:43 +0000 Subject: [PATCH] Add initial Xinerama support --- makefile | 2 +- sys-x11.c | 32 ++++++++++++++++++++++++++++++++ sys.h | 2 ++ util.c | 2 +- wm-wmii.c | 53 ++++++++++++++++++++++++++++++++--------------------- 5 files changed, 68 insertions(+), 23 deletions(-) diff --git a/makefile b/makefile index 6177373..d629e6e 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ SYS=x11 CC=gcc PROG=awm CFLAGS=-g -Werror -Wall -LIBS=-Wl,--as-needed -lX11 +LIBS=-Wl,--as-needed -lX11 -lXinerama TEST=DISPLAY=:2.0 WIN32= diff --git a/sys-x11.c b/sys-x11.c index dbab948..907cde7 100644 --- a/sys-x11.c +++ b/sys-x11.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "util.h" #include "sys.h" @@ -451,24 +452,55 @@ void sys_unwatch(win_t *win, Key_t key, mod_t mod) XUngrabButton(win->sys->dpy, btn2x(key), mod2x(mod), win->sys->xid); } +list_t *sys_info(win_t *win) +{ + int n; + XineramaScreenInfo *info = NULL; + if (XineramaIsActive(win->sys->dpy)) + info = XineramaQueryScreens(win->sys->dpy, &n); + if (!info) { + win_t *screen = new0(win_t); + *screen = *win; + return list_insert(NULL, screen); + } + list_t *screens = NULL; + for (int i = 0; i < n; i++) { + win_t *screen = new0(win_t); + screen->x = info[i].x_org; + screen->y = info[i].y_org; + screen->w = info[i].width; + screen->h = info[i].height; + screens = list_append(screens, screen); + } + return screens; +} + win_t *sys_init(void) { Display *dpy; Window xid; + + /* Open the display */ if (!(dpy = XOpenDisplay(NULL))) error("Unable to get display"); if (!(xid = DefaultRootWindow(dpy))) error("Unable to get root window"); + + /* Setup X11 data */ atoms[wm_proto] = XInternAtom(dpy, "WM_PROTOCOLS", False); atoms[wm_focus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); atoms[net_strut] = XInternAtom(dpy, "_NET_WM_STRUT", False); + colors[clr_focus] = get_color(dpy, "#a0a0ff"); colors[clr_unfocus] = get_color(dpy, "#101066"); colors[clr_urgent] = get_color(dpy, "#ff0000"); printf("colors = #%06lx #%06lx #%06lx\n", colors[0], colors[1], colors[2]); + + /* Selec Window Managmenet events */ XSelectInput(dpy, xid, SubstructureRedirectMask|SubstructureNotifyMask); XSetInputFocus(dpy, None, RevertToNone, CurrentTime); xerrorxlib = XSetErrorHandler(xerror); + return win_find(dpy, xid, 1); } diff --git a/sys.h b/sys.h index d70c893..fdf5356 100644 --- a/sys.h +++ b/sys.h @@ -61,6 +61,8 @@ void sys_focus(win_t *win); void sys_foreach(win_t *win); +list_t *sys_info(win_t *win); + win_t *sys_init(void); void sys_run(win_t *root); diff --git a/util.c b/util.c index 8495a1c..7425be0 100644 --- a/util.c +++ b/util.c @@ -30,7 +30,7 @@ void list_insert_after(list_t *prev, void *data) list_t *list_append(list_t *head, void *data) { list_t *last = head; - while (last->next) + while (last && last->next) last = last->next; list_t *node = new0(list_t); node->data = data; diff --git a/wm-wmii.c b/wm-wmii.c index c616951..e5c1a6c 100644 --- a/wm-wmii.c +++ b/wm-wmii.c @@ -37,7 +37,7 @@ typedef struct { typedef struct { list_t *cols; // of col_t col_t *col; - win_t *root; + win_t *geom; } dpy_t; typedef struct { @@ -49,6 +49,8 @@ typedef struct { typedef struct { list_t *tags; // of tag_t tag_t *tag; + win_t *root; + list_t *screens; } wm_t; /* Mouse drag data */ @@ -112,7 +114,7 @@ static void set_mode(win_t *win, mode_t mode) if (col->mode == split) for (list_t *cur = col->rows; cur; cur = cur->next) { row_t *row = cur->data; - row->height = wm_dpy->root->h; + row->height = wm_dpy->geom->h; } wm_update(); } @@ -210,10 +212,10 @@ static void put_win(win_t *win, col_t *col) col->row = row; wm_dpy->col = col; - row->height = wm_dpy->root->h / MAX(nrows,1); + row->height = wm_dpy->geom->h / MAX(nrows,1); if (nrows == 0) { int ncols = list_length(wm_dpy->cols); - col->width = wm_dpy->root->w / MAX(ncols-1,1); + col->width = wm_dpy->geom->w / MAX(ncols-1,1); } } @@ -296,8 +298,8 @@ void wm_update(void) int sy=0; // Size of focused stack window /* Scale horizontally */ - x = wm_dpy->root->x; - mx = wm_dpy->root->w - (list_length(wm_dpy->cols)+1)*MARGIN; + x = wm_dpy->geom->x; + mx = wm_dpy->geom->w - (list_length(wm_dpy->cols)+1)*MARGIN; for (list_t *lx = wm_dpy->cols; lx; lx = lx->next) tx += COL(lx)->width; for (list_t *lx = wm_dpy->cols; lx; lx = lx->next) @@ -309,8 +311,8 @@ void wm_update(void) ty = 0; for (list_t *ly = col->rows; ly; ly = ly->next) ty += ROW(ly)->height; - y = wm_dpy->root->y; - my = wm_dpy->root->h - (list_length(col->rows)+1)*MARGIN; + y = wm_dpy->geom->y; + my = wm_dpy->geom->h - (list_length(col->rows)+1)*MARGIN; sy = my - (list_length(col->rows)-1)*STACK; for (list_t *ly = col->rows; ly; ly = ly->next) { win_t *win = ROW(ly)->win; @@ -330,7 +332,7 @@ void wm_update(void) case max: case tab: sys_move(win, x+MARGIN, 0+MARGIN, - col->width, wm_dpy->root->h-2*MARGIN); + col->width, wm_dpy->geom->h-2*MARGIN); if (col->row->win == win) sys_raise(win); break; @@ -344,7 +346,7 @@ void wm_update(void) int wm_handle_key(win_t *win, Key_t key, mod_t mod, ptr_t ptr) { - if (!win || win == wm_dpy->root) return 0; + if (!win || win == wm_dpy->geom) return 0; //printf("wm_handle_key: %p - %x %c%c%c%c%c\n", win, key, // mod.up ? '^' : 'v', // mod.alt ? 'a' : '-', @@ -487,24 +489,33 @@ void wm_remove(win_t *win) if (wm_focus) sys_focus(wm_focus); else - sys_focus(wm_dpy->root); + sys_focus(wm->root); wm_update(); print_txt(wm_dpy->cols); } +tag_t *tag_new(list_t *screens, int name) +{ + tag_t *tag = new0(tag_t); + tag->name = name; + for (list_t *cur = screens; cur; cur = cur->next) { + dpy_t *dpy = new0(dpy_t); + dpy->geom = cur->data; + tag->dpys = list_append(tag->dpys, dpy); + } + tag->dpy = tag->dpys->data; + return tag; +} + void wm_init(win_t *root) { printf("wm_init: %p\n", root); - wm = new0(wm_t); - tag_t *tag = new0(tag_t); - dpy_t *dpy = new0(dpy_t); - - dpy->root = root; - tag->dpys = list_insert(NULL, dpy); - tag->dpy = dpy; - tag->name = 1; - wm->tags = list_insert(NULL, tag); - wm->tag = tag; + + wm = new0(wm_t); + wm->root = root; + wm->screens = sys_info(root); + wm->tag = tag_new(wm->screens, 1); + wm->tags = list_insert(NULL, wm->tag); Key_t keys_e[] = {key_enter, key_focus}; Key_t keys_s[] = {'h', 'j', 'k', 'l'}; -- 2.43.2