Example #1
0
/*
 * Parse a string (change)
 *
 */
static int mode_string_cb(void *params_, const unsigned char *val, size_t len) {
    struct mode_json_params *params = (struct mode_json_params *)params_;

    if (!strcmp(params->cur_key, "change")) {
        /* Save the name */
        params->mode->name = i3string_from_markup_with_length((const char *)val, len);
        /* Save its rendered width */
        params->mode->width = predict_text_width(params->mode->name);

        DLOG("Got mode change: %s\n", i3string_as_utf8(params->mode->name));
        FREE(params->cur_key);

        return 1;
    }

    return 0;
}
Example #2
0
File: main.c Project: Fresne/i3-1
 */
static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
    /* re-draw the background */
    xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {color_background});
    xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &rect);

    /* restore font color */
    set_font_colors(pixmap_gc, color_text, color_background);
    draw_text(prompt, pixmap, pixmap_gc,
              4 + 4, 4 + 4, rect.width - 4 - 4);

    /* render close button */
    const char *close_button_label = "X";
    int line_width = 4;
    /* set width to the width of the label */
    int w = predict_text_width(i3string_from_utf8(close_button_label));
    /* account for left/right padding, which seems to be set to 8px (total) below */
    w += 8;
    int y = rect.width;
    uint32_t values[3];
    values[0] = color_button_background;
    values[1] = line_width;
    xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH, values);

    xcb_rectangle_t close = {y - w - (2 * line_width), 0, w + (2 * line_width), rect.height};
    xcb_poly_fill_rectangle(conn, pixmap, pixmap_gc, 1, &close);

    xcb_change_gc(conn, pixmap_gc, XCB_GC_FOREGROUND, (uint32_t[]) {color_border});
    xcb_point_t points[] = {
        {y - w - (2 * line_width), line_width / 2},
        {y - (line_width / 2), line_width / 2},
Example #3
0
int main(int argc, char *argv[]) {
    format = sstrdup("%s");
    char *socket_path = NULL;
    char *pattern = sstrdup("pango:monospace 8");
    int o, option_index = 0;

    static struct option long_options[] = {
        {"socket", required_argument, 0, 's'},
        {"version", no_argument, 0, 'v'},
        {"limit", required_argument, 0, 'l'},
        {"prompt", required_argument, 0, 'P'},
        {"prefix", required_argument, 0, 'p'},
        {"format", required_argument, 0, 'F'},
        {"font", required_argument, 0, 'f'},
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}};

    char *options_string = "s:p:P:f:l:F:vh";

    while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
        switch (o) {
            case 's':
                FREE(socket_path);
                socket_path = sstrdup(optarg);
                break;
            case 'v':
                printf("i3-input " I3_VERSION);
                return 0;
            case 'p':
                /* This option is deprecated, but will still work in i3 v4.1, 4.2 and 4.3 */
                fprintf(stderr, "i3-input: WARNING: the -p option is DEPRECATED in favor of the -F (format) option\n");
                FREE(format);
                sasprintf(&format, "%s%%s", optarg);
                break;
            case 'l':
                limit = atoi(optarg);
                break;
            case 'P':
                i3string_free(prompt);
                prompt = i3string_from_utf8(optarg);
                break;
            case 'f':
                FREE(pattern);
                pattern = sstrdup(optarg);
                break;
            case 'F':
                FREE(format);
                format = sstrdup(optarg);
                break;
            case 'h':
                printf("i3-input " I3_VERSION "\n");
                printf("i3-input [-s <socket>] [-F <format>] [-l <limit>] [-P <prompt>] [-f <font>] [-v]\n");
                printf("\n");
                printf("Example:\n");
                printf("    i3-input -F 'workspace \"%%s\"' -P 'Switch to workspace: '\n");
                return 0;
        }
    }

    printf("using format \"%s\"\n", format);

    int screen;
    conn = xcb_connect(NULL, &screen);
    if (!conn || xcb_connection_has_error(conn))
        die("Cannot open display\n");

    sockfd = ipc_connect(socket_path);

    root_screen = xcb_aux_get_screen(conn, screen);
    root = root_screen->root;

    symbols = xcb_key_symbols_alloc(conn);

    init_dpi();
    font = load_font(pattern, true);
    set_font(&font);

    if (prompt != NULL)
        prompt_offset = predict_text_width(prompt);

    const xcb_rectangle_t win_pos = get_window_position();

    /* Open an input window */
    win = xcb_generate_id(conn);
    xcb_create_window(
        conn,
        XCB_COPY_FROM_PARENT,
        win,                                                 /* the window id */
        root,                                                /* parent == root */
        win_pos.x, win_pos.y, win_pos.width, win_pos.height, /* 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);

    /* Initialize the drawable surface */
    draw_util_surface_init(conn, &surface, win, get_visualtype(root_screen), win_pos.width, win_pos.height);

    /* Grab the keyboard to get all input */
    xcb_flush(conn);

    /* Try (repeatedly, if necessary) to grab the keyboard. We might not
     * get the keyboard at the first attempt because of the keybinding
     * still being active when started via a wm’s keybinding. */
    xcb_grab_keyboard_cookie_t cookie;
    xcb_grab_keyboard_reply_t *reply = NULL;

    int count = 0;
    while ((reply == NULL || reply->status != XCB_GRAB_STATUS_SUCCESS) && (count++ < 500)) {
        cookie = xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
        reply = xcb_grab_keyboard_reply(conn, cookie, NULL);
        usleep(1000);
    }

    if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
        fprintf(stderr, "Could not grab keyboard, status = %d\n", reply->status);
        exit(-1);
    }

    xcb_flush(conn);

    xcb_generic_event_t *event;
    while ((event = xcb_wait_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
            continue;
        }

        /* Strip off the highest bit (set if the event is generated) */
        int type = (event->response_type & 0x7F);

        switch (type) {
            case XCB_KEY_PRESS:
                handle_key_press(NULL, conn, (xcb_key_press_event_t *)event);
                break;

            case XCB_KEY_RELEASE:
                handle_key_release(NULL, conn, (xcb_key_release_event_t *)event);
                break;

            case XCB_EXPOSE:
                if (((xcb_expose_event_t *)event)->count == 0) {
                    handle_expose(NULL, conn, (xcb_expose_event_t *)event);
                }

                break;
        }

        free(event);
    }

    draw_util_surface_free(conn, &surface);
    return 0;
}