X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=i3-input%2Fmain.c;h=b570952397ccfd5f1e55ef75d1eb625f3d0f89e4;hb=4172e43c9caa192812dfb4e3d89368fe6e19798b;hp=bd4592e7543c5c279659813953d77631ea16f83d;hpb=cb9bbcfccff7b27e4a2cbe5e9b2bdbd6e5260bb2;p=i3%2Fi3 diff --git a/i3-input/main.c b/i3-input/main.c index bd4592e7..b5709523 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -2,13 +2,10 @@ * vim:ts=4:sw=4:expandtab * * i3 - an improved dynamic tiling window manager - * - * © 2009-2011 Michael Stapelberg and contributors - * - * See file LICENSE for license information. + * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE) * * i3-input/main.c: Utility which lets the user input commands and sends them - * to i3. + * to i3. * */ #include @@ -44,8 +41,6 @@ static char *format; static char *socket_path; static int sockfd; static xcb_key_symbols_t *symbols; -static int modeswitchmask; -static int numlockmask; static bool modeswitch_active = false; static xcb_window_t win; static xcb_pixmap_t pixmap; @@ -53,11 +48,12 @@ static xcb_gcontext_t pixmap_gc; static char *glyphs_ucs[512]; static char *glyphs_utf8[512]; static int input_position; -static int font_height; +static i3Font font; static char *prompt; -static int prompt_len; +static size_t prompt_len; static int limit; xcb_window_t root; +xcb_connection_t *conn; /* * Concats the glyphs (either UCS-2 or UTF-8) to a single string, suitable for @@ -91,14 +87,16 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t printf("expose!\n"); /* re-draw the background */ - xcb_rectangle_t border = {0, 0, 500, font_height + 8}, inner = {2, 2, 496, font_height + 8 - 4}; + xcb_rectangle_t border = {0, 0, 500, font.height + 8}, inner = {2, 2, 496, font.height + 8 - 4}; xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FF0000") }); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &border); xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#000000") }); xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &inner); /* restore font color */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]){ get_colorpixel("#FFFFFF") }); + set_font_colors(pixmap_gc, get_colorpixel("#FFFFFF"), get_colorpixel("#000000")); + + /* draw the text */ uint8_t *con = concat_strings(glyphs_ucs, input_position); char *full_text = (char*)con; if (prompt != NULL) { @@ -108,11 +106,11 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t memcpy(full_text, prompt, prompt_len * 2); memcpy(full_text + (prompt_len * 2), con, input_position * 2); } - xcb_image_text_16(conn, input_position + prompt_len, pixmap, pixmap_gc, 4 /* X */, - font_height + 2 /* Y = baseline of font */, (xcb_char2b_t*)full_text); + if (input_position + prompt_len != 0) + draw_text(full_text, input_position + prompt_len, true, pixmap, pixmap_gc, 4, 4, 492); /* Copy the contents of the pixmap to the real window */ - xcb_copy_area(conn, pixmap, win, pixmap_gc, 0, 0, 0, 0, /* */ 500, font_height + 8); + xcb_copy_area(conn, pixmap, win, pixmap_gc, 0, 0, 0, 0, /* */ 500, font.height + 8); xcb_flush(conn); free(con); if (prompt != NULL) @@ -128,8 +126,15 @@ static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t static int handle_key_release(void *ignored, xcb_connection_t *conn, xcb_key_release_event_t *event) { printf("releasing %d, state raw = %d\n", event->detail, event->state); - /* fix state */ - event->state &= ~numlockmask; + /* See the documentation of xcb_key_symbols_get_keysym for this one. + * Basically: We get either col 0 or col 1, depending on whether shift is + * pressed. */ + int col = (event->state & XCB_MOD_MASK_SHIFT); + + /* If modeswitch is currently active, we need to look in group 2 or 3, + * respectively. */ + if (modeswitch_active) + col += 2; xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, event->state); if (sym == XK_Mode_switch) { @@ -196,16 +201,17 @@ static void finish_input() { static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) { printf("Keypress %d, state raw = %d\n", event->detail, event->state); - /* fix state */ - if (modeswitch_active) - event->state |= modeswitchmask; + /* See the documentation of xcb_key_symbols_get_keysym for this one. + * Basically: We get either col 0 or col 1, depending on whether shift is + * pressed. */ + int col = (event->state & XCB_MOD_MASK_SHIFT); - /* Apparantly, after activating numlock once, the numlock modifier - * stays turned on (use xev(1) to verify). So, to resolve useful - * keysyms, we remove the numlock flag from the event state */ - event->state &= ~numlockmask; + /* If modeswitch is currently active, we need to look in group 2 or 3, + * respectively. */ + if (modeswitch_active) + col += 2; - xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, event->state); + xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, col); if (sym == XK_Mode_switch) { printf("Mode switch enabled\n"); modeswitch_active = true; @@ -256,14 +262,14 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press printf("inp[0] = %02x, inp[1] = %02x, inp[2] = %02x\n", inp[0], inp[1], inp[2]); /* convert it to UTF-8 */ - char *out = convert_ucs_to_utf8((char*)inp); + char *out = convert_ucs2_to_utf8((xcb_char2b_t*)inp, 1); printf("converted to %s\n", out); glyphs_ucs[input_position] = malloc(3 * sizeof(uint8_t)); if (glyphs_ucs[input_position] == NULL) err(EXIT_FAILURE, "malloc() failed\n"); memcpy(glyphs_ucs[input_position], inp, 3); - glyphs_utf8[input_position] = strdup(out); + glyphs_utf8[input_position] = out; input_position++; if (input_position == limit) @@ -276,7 +282,7 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press int main(int argc, char *argv[]) { format = strdup("%s"); socket_path = getenv("I3SOCK"); - char *pattern = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1"; + char *pattern = sstrdup("-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1"); int o, option_index = 0; static struct option long_options[] = { @@ -336,7 +342,7 @@ int main(int argc, char *argv[]) { printf("using format \"%s\"\n", format); if (socket_path == NULL) - socket_path = socket_path_from_x11(); + socket_path = root_atom_contents("I3_SOCKET_PATH"); if (socket_path == NULL) socket_path = "/tmp/i3-ipc.sock"; @@ -344,38 +350,52 @@ int main(int argc, char *argv[]) { sockfd = ipc_connect(socket_path); if (prompt != NULL) - prompt = convert_utf8_to_ucs2(prompt, &prompt_len); + prompt = (char*)convert_utf8_to_ucs2(prompt, &prompt_len); int screens; - xcb_connection_t *conn = xcb_connect(NULL, &screens); - if (xcb_connection_has_error(conn)) + conn = xcb_connect(NULL, &screens); + if (!conn || xcb_connection_has_error(conn)) die("Cannot open display\n"); xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screens); root = root_screen->root; - modeswitchmask = get_mod_mask(conn, XK_Mode_switch); - numlockmask = get_mod_mask(conn, XK_Num_Lock); symbols = xcb_key_symbols_alloc(conn); - uint32_t font_id = get_font_id(conn, pattern, &font_height); + font = load_font(pattern, true); + set_font(&font); /* Open an input window */ - win = open_input_window(conn, 500, font_height + 8); + win = xcb_generate_id(conn); + xcb_create_window( + conn, + XCB_COPY_FROM_PARENT, + win, /* the window id */ + root, /* parent == root */ + 50, 50, 500, font.height + 8, /* dimensions */ + 0, /* X11 border = 0, we draw our own */ + XCB_WINDOW_CLASS_INPUT_OUTPUT, + XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */ + XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, + (uint32_t[]){ + 0, /* back pixel: black */ + 1, /* override redirect: don’t manage this window */ + XCB_EVENT_MASK_EXPOSURE + }); + + /* Map the window (make it visible) */ + xcb_map_window(conn, win); /* Create pixmap */ pixmap = xcb_generate_id(conn); pixmap_gc = xcb_generate_id(conn); - xcb_create_pixmap(conn, root_screen->root_depth, pixmap, win, 500, font_height + 8); + xcb_create_pixmap(conn, root_screen->root_depth, pixmap, win, 500, font.height + 8); xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); /* Set input focus (we have override_redirect=1, so the wm will not do * this for us) */ xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, win, XCB_CURRENT_TIME); - /* Create graphics context */ - xcb_change_gc(conn, pixmap_gc, XCB_GC_FONT, (uint32_t[]){ font_id }); - /* Grab the keyboard to get all input */ xcb_flush(conn);