From df9fa0dd8f3ba04cfc4a877ae10570ecb1588152 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Tue, 10 Feb 2009 05:50:35 +0100 Subject: [PATCH] Add XKB for getting correct state, add colspan test code --- Makefile | 9 ++++--- data.h | 5 +++- font.c | 4 +-- font.h | 2 +- mainx.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++------- table.c | 19 ++++++++------ 6 files changed, 94 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 7e71cabd..727bd895 100644 --- a/Makefile +++ b/Makefile @@ -7,16 +7,19 @@ CFLAGS += -g3 CFLAGS += -I/usr/include/xcb CFLAGS += -I/usr/local/include/ CFLAGS += -I/usr/local/include/xcb +CFLAGS += -I/usr/pkg/include LDFLAGS += -lxcb-wm -LDFLAGS += -L/usr/local/lib +LDFLAGS += -lxcb-keysyms +LDFLAGS += -lX11 +LDFLAGS += -L/usr/local/lib -L/usr/pkg/lib ifeq ($(UNAME),NetBSD) -LDFLAGS += -Wl,-rpath,/usr/local/lib +LDFLAGS += -Wl,-rpath,/usr/local/lib -Wl,-rpath,/usr/pkg/lib endif FILES=$(patsubst %.c,%.o,$(wildcard *.c)) -%.o: %.c %.h +%.o: %.c %.h data.h $(CC) $(CFLAGS) -c -o $@ $< all: ${FILES} diff --git a/data.h b/data.h index 9fc04f1c..9fa7b063 100644 --- a/data.h +++ b/data.h @@ -10,7 +10,7 @@ /* Forward definitions */ typedef struct Cell Cell; -typedef struct Font Font; +typedef struct Font i3Font; typedef struct Container Container; typedef struct Client Client; @@ -77,6 +77,8 @@ struct Client { struct Container { /* Those are speaking for themselves: */ Client *currently_focused; + int colspan; + int rowspan; /* Position of the container inside our table */ int row; @@ -84,6 +86,7 @@ struct Container { /* Width/Height of the container. Changeable by the user */ int width; int height; + /* Ensure MODE_DEFAULT maps to 0 because we use calloc for initialization later */ enum { MODE_DEFAULT = 0, MODE_STACK = 1 } mode; CIRCLEQ_HEAD(client_head, Client) clients; diff --git a/font.c b/font.c index c118741e..407955a0 100644 --- a/font.c +++ b/font.c @@ -20,9 +20,9 @@ void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *e } -Font *load_font(xcb_connection_t *c, const char *pattern) { +i3Font *load_font(xcb_connection_t *c, const char *pattern) { /* TODO: this function should be caching */ - Font *new = malloc(sizeof(Font)); + i3Font *new = malloc(sizeof(i3Font)); xcb_list_fonts_with_info_cookie_t cookie = xcb_list_fonts_with_info(c, 1, strlen(pattern), pattern); xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(c, cookie, NULL); diff --git a/font.h b/font.h index 0aec278b..732c369e 100644 --- a/font.h +++ b/font.h @@ -5,6 +5,6 @@ #ifndef _FONT_H #define _FONT_H -Font *load_font(xcb_connection_t *c, const char *pattern); +i3Font *load_font(xcb_connection_t *c, const char *pattern); #endif diff --git a/mainx.c b/mainx.c index ca557660..dfe1abdf 100644 --- a/mainx.c +++ b/mainx.c @@ -10,6 +10,9 @@ #include +#include +#include + #include "xcb_wm.h" #include "xcb_aux.h" #include "xcb_event.h" @@ -23,7 +26,8 @@ #define TERMINAL "/usr/pkg/bin/urxvt" -Font *myfont; +i3Font *myfont; +Display *xkbdpy; static const int TOP = 20; static const int LEFT = 5; @@ -344,7 +348,7 @@ void decorate_window(xcb_connection_t *conn, Client *client) { uint32_t mask = 0; uint32_t values[3]; xcb_screen_t *root_screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; - Font *font = load_font(conn, pattern); + i3Font *font = load_font(conn, pattern); uint32_t background_color, text_color, border_color; @@ -412,7 +416,7 @@ void render_container(xcb_connection_t *connection, Container *container) { XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; - Font *font = load_font(connection, pattern); + i3Font *font = load_font(connection, pattern); if (container->mode == MODE_DEFAULT) { int num_clients = 0; @@ -476,11 +480,14 @@ void render_layout(xcb_connection_t *conn) { for (cols = 0; cols < table_dims.x; cols++) for (rows = 0; rows < table_dims.y; rows++) if (table[cols][rows] != NULL) { + Container *con = table[cols][rows]; + printf("container has %d colspan, %d rowspan\n", + con->colspan, con->rowspan); /* Update position of the container */ - table[cols][rows]->row = rows; - table[cols][rows]->col = cols; - table[cols][rows]->width = width / num_cols; - table[cols][rows]->height = height / num_rows; + con->row = rows; + con->col = cols; + con->width = (width / num_cols) * con->colspan; + con->height = (height / num_rows) * con->rowspan; /* Render it */ render_container(conn, table[cols][rows]); @@ -562,7 +569,7 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, table_put(byChild, child, new); /* Moves the original window into the new frame we've created for it */ - Font *font = load_font(conn, pattern); + i3Font *font = load_font(conn, pattern); xcb_reparent_window(conn, child, new->frame, 0, font->height); /* We are interested in property changes */ @@ -797,14 +804,32 @@ static void start_application(char *path, char *args) { * */ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) { - /* FIXME: We need to translate the keypress + state into a string (like, ä) because they do not generate keysyms (use xev and see for yourself) */ printf("oh yay!\n"); printf("gots press %d\n", event->detail); + + /* We need to get the keysym group (There are group 1 to group 4, each holding + two keysyms (without shift and with shift) using Xkb because X fails to + provide them reliably (it works in Xephyr, it does not in real X) */ + XkbStateRec state; + if (XkbGetState(xkbdpy, XkbUseCoreKbd, &state) == Success) { + if (state.group+1 == 2) + event->state |= 0x2; + } printf("i'm in state %d\n", event->state); + + xcb_key_symbols_t *keysyms = xcb_key_symbols_alloc(conn); + + xcb_keysym_t k0 = xcb_key_symbols_get_keysym(keysyms, event->detail, event->state); + if (k0 == XCB_NONE) + printf("couldn't get k0\n"); + + printf("gots keysym %d and \n", k0); + + /* 30 = u * 57 = n * 27 = r @@ -817,6 +842,7 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press if (event->detail == 30) { /* 'u' */ start_application(TERMINAL, NULL); + return 1; } else if (event->detail == 57) { direction = D_LEFT; @@ -826,6 +852,14 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press direction = D_UP; } else if (event->detail == 40) { direction = D_RIGHT; + } else if (event->detail == 25) { + Container *con = CUR_CELL; + if (con->colspan == 1) + con->colspan++; + else con->colspan--; + render_layout(conn); + xcb_flush(conn); + return 1; } else { printf("don't want this.\n"); return 1; @@ -865,6 +899,9 @@ static int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_ old_client = client->container->currently_focused; client->container->currently_focused = client; + current_col = client->container->col; + current_row = client->container->row; + /* Set focus to the entered window, and flush xcb buffer immediately */ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, client->child, XCB_CURRENT_TIME); /* Update last/current client’s titlebar */ @@ -876,6 +913,7 @@ static int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_ return 1; } + int handle_map_notify_event(void *prophs, xcb_connection_t *c, xcb_map_notify_event_t *e) { window_attributes_t wa = { TAG_VALUE }; @@ -1002,6 +1040,24 @@ int main(int argc, char *argv[], char *env[]) { printf("x screen is %d\n", screens); + int major, minor, error; + + major = XkbMajorVersion; + minor = XkbMinorVersion; + + int evBase, errBase; + + if ((xkbdpy = XkbOpenDisplay(getenv("DISPLAY"), &evBase, &errBase, &major, &minor, &error)) == NULL) { + fprintf(stderr, "XkbOpenDisplay() failed\n"); + return 1; + } + + int i1; + if (!XkbQueryExtension(xkbdpy,&i1,&evBase,&errBase,&major,&minor)) { + fprintf(stderr, "XKB not supported by X-server\n"); + return 1; + } + /* Font loading */ myfont = load_font(c, pattern); @@ -1038,6 +1094,9 @@ int main(int argc, char *argv[], char *env[]) { //xcb_grab_key(c, 0, root, 0, 38, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_key(c, 0, root, 0, 30, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); + xcb_grab_key(c, 0, root, 0, 38, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); + + xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 57, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 28, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_key(c, 0, root, XCB_MOD_MASK_1, 27, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); @@ -1047,6 +1106,8 @@ int main(int argc, char *argv[], char *env[]) { xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 28, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 27, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 40, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); + xcb_grab_key(c, 0, root, XCB_MOD_MASK_CONTROL, 25, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); + //xcb_grab_key(c, 0, root, XCB_BUTTON_MASK_ANY, 40, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); diff --git a/table.c b/table.c index 32062f7e..d689ce72 100644 --- a/table.c +++ b/table.c @@ -29,20 +29,26 @@ void init_table() { expand_table_rows(); } +static void new_container(Container **container) { + Container *new; + new = *container = calloc(sizeof(Container), 1); + CIRCLEQ_INIT(&(new->clients)); + new->colspan = 1; + new->rowspan = 1; +} + /* * Add one row to the table * */ void expand_table_rows() { int c; - Container *new; table_dims.y++; for (c = 0; c < table_dims.x; c++) { table[c] = realloc(table[c], sizeof(Container*) * table_dims.y); - new = table[c][table_dims.y-1] = calloc(sizeof(Container), 1); - CIRCLEQ_INIT(&(new->clients)); + new_container(&(table[c][table_dims.y-1])); } } @@ -52,15 +58,12 @@ void expand_table_rows() { */ void expand_table_cols() { int c; - Container *new; table_dims.x++; table = realloc(table, sizeof(Container**) * table_dims.x); table[table_dims.x-1] = calloc(sizeof(Container*) * table_dims.y, 1); - for (c = 0; c < table_dims.y; c++) { - new = table[table_dims.x-1][c] = calloc(sizeof(Container), 1); - CIRCLEQ_INIT(&(new->clients)); - } + for (c = 0; c < table_dims.y; c++) + new_container(&(table[table_dims.x-1][c])); } /*