]> git.sur5r.net Git - i3/i3/commitdiff
Add XKB for getting correct state, add colspan test code
authorMichael Stapelberg <michael+git@stapelberg.de>
Tue, 10 Feb 2009 04:50:35 +0000 (05:50 +0100)
committerMichael Stapelberg <michael+git@stapelberg.de>
Tue, 10 Feb 2009 04:50:35 +0000 (05:50 +0100)
Makefile
data.h
font.c
font.h
mainx.c
table.c

index 7e71cabd48a97d184b9ef9a8c0d55d41e6eb033d..727bd895e1672edf61fef8004a9f299a18f01791 100644 (file)
--- 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 9fc04f1c42582541a7d2d1bc0053d5391605310d..9fa7b0632a9e3114adfd1445943da44588710e40 100644 (file)
--- 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 c118741e856404e5e75d48d4f5b2ca145bcd3a91..407955a0be508c19d37ccae3d37932e8a0689318 100644 (file)
--- 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 0aec278b040be705db01ea01501342693f3c6f4f..732c369eed6646c32401b26b5bc8881a7f121ff2 100644 (file)
--- 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 ca557660e0cf697124340c01c617dec66c86baef..dfe1abdf41dcd7d5f41b107aa36e4e965eb24a38 100644 (file)
--- a/mainx.c
+++ b/mainx.c
@@ -10,6 +10,9 @@
 
 #include <xcb/xcb.h>
 
+#include <X11/XKBlib.h>
+#include <X11/extensions/XKB.h>
+
 #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 32062f7e198533e48feccab4a804c5390e670595..d689ce72c0c4d92d8301ee0313d3d586e99f18c4 100644 (file)
--- 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]));
 }
 
 /*