diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5761abcf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/Makefile b/Makefile index cf143121..874b779a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,18 @@ -all: - gcc -Wall -gdwarf-2 -g3 -I/usr/include/xcb -c mainx.c - gcc -Wall -gdwarf-2 -g3 -I/usr/include/xcb -c table.c - gcc -Wall -gdwarf-2 -g3 -I/usr/include/xcb -c test_table.c - gcc -Wall -gdwarf-2 -g3 -I/usr/include/xcb -o mainx mainx.o table.o -lxcb-wm - gcc -Wall -gdwarf-2 -g3 -I/usr/include/xcb -o tt test_table.o table.o +CFLAGS += -Wall +# Extended debugging flags, macros shall be available in gcc +CFLAGS += -gdwarf-2 +CFLAGS += -g3 +CFLAGS += -I/usr/include/xcb + +LDFLAGS += -lxcb-wm + +FILES=$(patsubst %.c,%.o,$(wildcard *.c)) + +%.o: %.c %.h + $(CC) $(CFLAGS) -c -o $@ $< + +all: ${FILES} + $(CC) -o mainx ${FILES} $(LDFLAGS) + +clean: + rm -f *.o diff --git a/data.h b/data.h index a9524c38..2c26ec81 100644 --- a/data.h +++ b/data.h @@ -37,8 +37,14 @@ struct Cell { * */ struct Font { + /* The name of the font, that is what the pattern resolves to */ char *name; + /* A copy of the pattern to build a cache */ + char *pattern; + /* The height of the font, built from font_ascent + font_descent */ int height; + /* The xcb-id for the font */ + xcb_font_t id; }; /* diff --git a/font.c b/font.c new file mode 100644 index 00000000..eed3d134 --- /dev/null +++ b/font.c @@ -0,0 +1,48 @@ +/* + * Handles font loading + * + */ +#include +#include +#include +#include + +#include "data.h" + +/* TODO: This is just here to be somewhere. Move it somewhere else. */ +void check_error(xcb_connection_t *connection, xcb_void_cookie_t cookie, char *errMessage) { + xcb_generic_error_t *error = xcb_request_check (connection, cookie); + if (error != NULL) { + fprintf(stderr, "ERROR: %s : %d\n", errMessage , error->error_code); + xcb_disconnect(connection); + exit(-1); + } +} + + +Font *load_font(xcb_connection_t *c, const char *pattern) { + Font *new = malloc(sizeof(Font)); + + 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); + if (!reply) { + printf("Could not load font\n"); + exit(1); + } + + /* Oh my, this is so ugly :-(. Why can’t they just return a null-terminated + * string? That’s what abstraction layers are for. */ + char buffer[xcb_list_fonts_with_info_name_length(reply)+1]; + memset(buffer, 0, sizeof(buffer)); + memcpy(buffer, xcb_list_fonts_with_info_name(reply), sizeof(buffer)-1); + new->name = strdup(buffer); + new->pattern = strdup(pattern); + new->height = reply->font_ascent + reply->font_descent; + + /* Actually load the font */ + new->id = xcb_generate_id(c); + xcb_void_cookie_t font_cookie = xcb_open_font_checked(c, new->id, strlen(pattern), pattern); + check_error(c, font_cookie, "Could not open font"); + + return new; +} diff --git a/font.h b/font.h new file mode 100644 index 00000000..0aec278b --- /dev/null +++ b/font.h @@ -0,0 +1,10 @@ +#include + +#include "data.h" + +#ifndef _FONT_H +#define _FONT_H + +Font *load_font(xcb_connection_t *c, const char *pattern); + +#endif diff --git a/main.c b/main.c deleted file mode 100644 index db0b54e9..00000000 --- a/main.c +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include - -enum { move, snap, select }; - -struct foo { - int width; - int height; - int x; - int y; -}; - - -int main() { - int c; - int mode; - struct termios tbuf, obuf; - if (tcgetattr(STDIN_FILENO, &obuf) < 0 || - tcgetattr(STDIN_FILENO, &tbuf) < 0) - perror("tcgetattr()"); - tbuf.c_lflag &= ~ICANON; - tbuf.c_cc[VMIN] = 1; - tbuf.c_cc[VTIME] = 0; - tcsetattr(STDIN_FILENO, TCSANOW, &tbuf); - - int table[10][10]; - int colspan[10]; - int rowspan[10]; - int current_row = 0; - int current_col = 0; - int current = -1; - int created_terms = 0; - - for (c = 0; c < 10; c++) { - int i; - for (i = 0; i < 10; i++) - table[c][i] = -1; - colspan[c] = 1; - rowspan[c] = 1; - } - - mode = select; - while (printf("%s> ", (mode == move ? "move" : (mode == select ? "select" : "snap"))), c = getchar()) { - - printf("char %c, %d\n", c, c); - if (c == 'm') - mode = move; - else if (c == 's') - mode = snap; - else if (c == 'u') { - /* insert new 'terminal' below current one */ - int i; - printf("current row = %d\n", current_row); - printf("current col = %d\n", current_col); - for (i = current_row; i < 10; i++) { - if (table[current_col][i] == -1) { - printf("found empty entry at %d\n", i); - created_terms++; - table[current_col][i] = created_terms; - current_row = i; - printf("created terminal %d\n", created_terms); - printf("current_row = %d\n", current_row); - break; - } - } - } - else if (c == 'n') { - if (mode == move) { - printf("move window left\n"); - table[current_col-1][current_row] = table[current_col][current_row]; - table[current_col][current_row] = -1; - - } else if (mode == snap) { - printf("snap window left\n"); - } else if (mode == select) { - printf("go to left window\n"); - if (current_col > 0) - current_col--; - printf("col now: %d\n", current_col); - } - mode = select; - - } - else if (c == 'r') { - if (mode == move) { - printf("move window down\n"); - table[current_col][current_row+1] = table[current_col][current_row]; - table[current_col][current_row] = -1; - - } else if (mode == snap) { - printf("snap window down\n"); - } else if (mode == select) { - printf("go to window below\n"); - if (current_row < 9) - current_row++; - printf("row now: %d\n", current_row); - } - mode = select; - - } - else if (c == 't') { - if (mode == move) { - printf("move window up\n"); - table[current_col][current_row-1] = table[current_col][current_row]; - table[current_col][current_row] = -1; - } else if (mode == snap) { - printf("snap window up\n"); - } else if (mode == select) { - printf("go to upper window\n"); - if (current_row > 0) - current_row--; - printf("row now: %d\n", current_row); - } - mode = select; - - } - else if (c == 'd') { - if (mode == move) { - printf("move window right\n"); - table[current_col+1][current_row] = table[current_col][current_row]; - table[current_col][current_row] = -1; - current_col++; - } else if (mode == snap) { - printf("snap window right\n"); - colspan[table[current_col][current_row]]++; - printf("colspan now is: %d\n", colspan[table[current_col][current_row]]++); - - } else if (mode == select) { - printf("go to right window\n"); - if (current_col < 9) - current_col++; - printf("col now: %d\n", current_col); - } - mode = select; - - } - - int rows, cols; - printf("your windows are as following:\n"); - system("/tmp/killgeom.sh"); - for (rows = 0; rows < 10; rows++) - for (cols = 0; cols < 10; cols++) { - if (table[cols][rows] != -1) { - printf("client %d, x = %d, y = %d, width = %d, height = %d", - table[cols][rows], cols * 60, rows * 60, 15 * 1, 15 * 1); - if (cols == current_col && rows == current_row) - printf(" < ===== YOU ARE HERE\n"); - else printf("\n"); - char *buffer; - asprintf(&buffer, "/bin/sh -c \"urxvt -geometry %dx%d+%d+%d %s&\"", - 15 * colspan[table[cols][rows]], 15, cols * 200, rows * 200, (cols == current_col && rows == current_row ? "-bg white" : "-bg gray")); - printf("executing %s\n", buffer); - - system(buffer); - free(buffer); - } - } - printf("that's all\n"); - } -} diff --git a/mainx.c b/mainx.c index 8fe6ebf3..b87803a3 100644 --- a/mainx.c +++ b/mainx.c @@ -19,8 +19,9 @@ #include "queue.h" #include "table.h" +#include "font.h" -Font myfont; +Font *myfont; static const int TOP = 20; static const int LEFT = 5; @@ -32,6 +33,7 @@ table_t *byChild = 0; table_t *byParent = 0; xcb_window_t root_win; +char *pattern = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso8859-1"; int current_col = 0; @@ -324,15 +326,14 @@ void decorate_window(xcb_connection_t *conn, Client *client) { mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; - xcb_font_t font = xcb_generate_id (conn); - char *font_name = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso8859-1"; - xcb_void_cookie_t fontCookie = xcb_open_font_checked (conn, font, strlen (font_name), font_name ); + Font *font = load_font(conn, pattern); values[0] = root_screen->black_pixel; - if (globalc++ > 1) + if (client->container->currently_focused == client) { + printf("oh, currently active = %p\n", client); values[1] = get_colorpixel(conn, client->window, 65535, 0, 0); - else values[1] = get_colorpixel(conn, client->window, 0, 0, 65535); - values[2] = font; + }else values[1] = get_colorpixel(conn, client->window, 0, 0, 65535); + values[2] = font->id; xcb_change_gc(conn, client->titlegc, mask, values); @@ -341,7 +342,7 @@ void decorate_window(xcb_connection_t *conn, Client *client) { //char *label = "i3 rocks :>"; char *label; asprintf(&label, "gots win %08x", client->window); - xcb_void_cookie_t textCookie = xcb_image_text_8_checked (conn, strlen (label), client->window, client->titlegc, 2, 15, label ); + xcb_void_cookie_t textCookie = xcb_image_text_8_checked (conn, strlen (label), client->window, client->titlegc, 2, 2 + font->height, label ); } void render_container(xcb_connection_t *connection, Container *container) { @@ -430,8 +431,7 @@ void render_layout(xcb_connection_t *conn) { */ void reparent_window(xcb_connection_t *conn, xcb_window_t child, xcb_visualid_t visual, xcb_window_t root, uint8_t depth, - int16_t x, int16_t y, uint16_t width, uint16_t height) -{ + int16_t x, int16_t y, uint16_t width, uint16_t height) { Client *new = table_get(byChild, child); if (new == NULL) { @@ -533,6 +533,7 @@ static bool focus_window_in_container(xcb_connection_t *connection, Container *c /* Set focus if we could successfully move */ container->currently_focused = candidad; xcb_set_input_focus(connection, XCB_INPUT_FOCUS_NONE, candidad->child, XCB_CURRENT_TIME); + render_layout(connection); xcb_flush(connection); return true; @@ -562,6 +563,7 @@ static void focus_window(xcb_connection_t *connection, direction_t direction) { if (CUR_CELL->currently_focused != NULL) { xcb_set_input_focus(connection, XCB_INPUT_FOCUS_NONE, CUR_CELL->currently_focused->child, XCB_CURRENT_TIME); + render_layout(connection); xcb_flush(connection); } @@ -798,8 +800,7 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *c, xcb_unmap_notify_ -static int handleExposeEvent(void *data, xcb_connection_t *c, xcb_expose_event_t *e) -{ +static int handleExposeEvent(void *data, xcb_connection_t *c, xcb_expose_event_t *e) { printf("exposeevent\n"); Client *client = table_get(byParent, e->window); if(!client || e->count != 0) @@ -807,8 +808,7 @@ printf("exposeevent\n"); decorate_window(c, client); return 1; } -void manage_existing_windows(xcb_connection_t *c, xcb_property_handlers_t *prophs, xcb_window_t root) -{ +void manage_existing_windows(xcb_connection_t *c, xcb_property_handlers_t *prophs, xcb_window_t root) { xcb_query_tree_cookie_t wintree; xcb_query_tree_reply_t *rep; int i, len; @@ -861,18 +861,7 @@ int main() { /* Font loading */ -char *pattern = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso8859-1"; - -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); -if (!reply) { - printf("Could not load font\n"); - return 1; -} - -myfont.name = strdup(xcb_list_fonts_with_info_name(reply)); -myfont.height = reply->font_ascent + reply->font_descent; - + myfont = load_font(c, pattern); xcb_event_handlers_init(c, &evenths); for(i = 2; i < 128; ++i) diff --git a/table.c b/table.c index a94fc1b3..32062f7e 100644 --- a/table.c +++ b/table.c @@ -20,11 +20,19 @@ Container ***table = NULL; struct table_dimensions_t table_dims = {0, 0}; +/* + * Initialize table + * + */ void init_table() { expand_table_cols(); expand_table_rows(); } +/* + * Add one row to the table + * + */ void expand_table_rows() { int c; Container *new; @@ -38,6 +46,10 @@ void expand_table_rows() { } } +/* + * Add one column to the table + * + */ void expand_table_cols() { int c; Container *new; @@ -59,4 +71,3 @@ bool cell_exists(int col, int row) { return (col >= 0 && col < table_dims.x) && (row >= 0 && row < table_dims.y); } - diff --git a/test_table.c b/tests/test_table.c similarity index 100% rename from test_table.c rename to tests/test_table.c