示例#1
0
/*
 * Instead of polling the X connection socket we leave this to
 * xcb_poll_for_event() which knows better than we can ever know.
 *
 */
static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
    xcb_generic_event_t *event;

    while ((event = xcb_poll_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            xcb_generic_error_t *error = (xcb_generic_error_t*)event;
            if (debug_mode)
                fprintf(stderr, "X11 Error received! sequence 0x%x, error_code = %d\n",
                        error->sequence, error->error_code);
            free(event);
            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((xcb_key_press_event_t*)event);
                break;

            case XCB_KEY_RELEASE:
                handle_key_release((xcb_key_release_event_t*)event);

                /* If this was the backspace or escape key we are back at an
                 * empty input, so turn off the screen if DPMS is enabled */
                if (dpms && input_position == 0)
                    dpms_turn_off_screen(conn);

                break;

            case XCB_VISIBILITY_NOTIFY:
                handle_visibility_notify((xcb_visibility_notify_event_t*)event);
                break;

            case XCB_MAP_NOTIFY:
                if (!dont_fork) {
                    /* After the first MapNotify, we never fork again. We don’t
                     * expect to get another MapNotify, but better be sure… */
                    dont_fork = true;

                    /* In the parent process, we exit */
                    if (fork() != 0)
                        exit(0);

                    ev_loop_fork(EV_DEFAULT);
                }
                break;

            case XCB_MAPPING_NOTIFY:
                handle_mapping_notify((xcb_mapping_notify_event_t*)event);
                break;

            case XCB_CONFIGURE_NOTIFY:
                handle_screen_resize();
                break;
        }

        free(event);
    }
}
示例#2
0
文件: i3lock.c 项目: Kamori/i3lock
/*
 * Instead of polling the X connection socket we leave this to
 * xcb_poll_for_event() which knows better than we can ever know.
 *
 */
static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
    xcb_generic_event_t *event;

    while ((event = xcb_poll_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            xcb_generic_error_t *error = (xcb_generic_error_t*)event;
            if (debug_mode)
                fprintf(stderr, "X11 Error received! sequence 0x%x, error_code = %d\n",
                        error->sequence, error->error_code);
            free(event);
            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((xcb_key_press_event_t*)event);
                break;

            case XCB_KEY_RELEASE:
                /* If this was the backspace or escape key we are back at an
                 * empty input, so turn off the screen if DPMS is enabled, but
                 * only do that after some timeout: maybe user mistyped and
                 * will type again right away */
                START_TIMER(dpms_timeout, TSTAMP_N_SECS(inactivity_timeout),
                            turn_off_monitors_cb);
                break;

            case XCB_VISIBILITY_NOTIFY:
                handle_visibility_notify(conn, (xcb_visibility_notify_event_t*)event);
                break;

            case XCB_MAP_NOTIFY:
                if (!dont_fork) {
                    /* After the first MapNotify, we never fork again. We don’t
                     * expect to get another MapNotify, but better be sure… */
                    dont_fork = true;

                    /* In the parent process, we exit */
                    if (fork() != 0)
                        exit(0);

                    ev_loop_fork(EV_DEFAULT);
                }
                break;

            case XCB_CONFIGURE_NOTIFY:
                handle_screen_resize();
                break;

            default:
                if (type == xkb_base_event)
                    process_xkb_event(event);
        }

        free(event);
    }
}
示例#3
0
/*
 * Instead of polling the X connection socket we leave this to
 * xcb_poll_for_event() which knows better than we can ever know.
 *
 */
static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
    xcb_generic_event_t *event;

    if (xcb_connection_has_error(conn))
        errx(EXIT_FAILURE, "X11 connection broke, did your server terminate?\n");

    while ((event = xcb_poll_for_event(conn)) != NULL) {
        if (event->response_type == 0) {

            xcb_generic_error_t *error = (xcb_generic_error_t *)event;
            if (debug_mode)
                fprintf(stderr, "X11 Error received! sequence 0x%x, error_code = %d\n",
                        error->sequence, error->error_code);
            free(event);
            continue;
        }
        /* Strip off the highest bit (set if the event is generated) */
        int type = (event->response_type & 0x7F);

        switch (type) {
        case XCB_BUTTON_PRESS:
            handle_button_press((xcb_button_press_event_t *)event);
            break;

        case XCB_KEY_PRESS:
            handle_key_press((xcb_key_press_event_t *)event);
            break;

        case XCB_VISIBILITY_NOTIFY:
            handle_visibility_notify(conn, (xcb_visibility_notify_event_t *)event);
            break;

        case XCB_MAP_NOTIFY:
            if (!dont_fork) {
                /* After the first MapNotify, we never fork again. We don’t
                 * expect to get another MapNotify, but better be sure… */
                dont_fork = true;

                /* In the parent process, we exit */
                if (fork() != 0)
                    exit(0);

                ev_loop_fork(EV_DEFAULT);
            }
            break;

        case XCB_CONFIGURE_NOTIFY:
            handle_screen_resize();
            break;

        default:
            if (type == xkb_base_event)
                process_xkb_event(event);
        }

        free(event);
    }
}
示例#4
0
/*
 * This function is called from a fork()ed child and will raise the i3lock
 * window when the window is obscured, even when the main i3lock process is
 * blocked due to PAM.
 *
 */
static void raise_loop(xcb_window_t window) {
    xcb_connection_t *conn;
    xcb_generic_event_t *event;
    int screens;

    if ((conn = xcb_connect(NULL, &screens)) == NULL ||
        xcb_connection_has_error(conn))
        errx(EXIT_FAILURE, "Cannot open display\n");

    /* We need to know about the window being obscured or getting destroyed. */
    xcb_change_window_attributes(conn, window, XCB_CW_EVENT_MASK,
                                 (uint32_t[]){XCB_EVENT_MASK_VISIBILITY_CHANGE |
                                              XCB_EVENT_MASK_STRUCTURE_NOTIFY});
    xcb_flush(conn);

    DEBUG("Watching window 0x%08x\n", window);
    while ((event = xcb_wait_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            xcb_generic_error_t *error = (xcb_generic_error_t *)event;
            DEBUG("X11 Error received! sequence 0x%x, error_code = %d\n",
                  error->sequence, error->error_code);
            free(event);
            continue;
        }
        /* Strip off the highest bit (set if the event is generated) */
        int type = (event->response_type & 0x7F);
        DEBUG("Read event of type %d\n", type);
        switch (type) {
            case XCB_VISIBILITY_NOTIFY:
                handle_visibility_notify(
                    conn, (xcb_visibility_notify_event_t *)event);
                break;
            case XCB_UNMAP_NOTIFY:
                DEBUG("UnmapNotify for 0x%08x\n",
                      (((xcb_unmap_notify_event_t *)event)->window));
                if (((xcb_unmap_notify_event_t *)event)->window == window)
                    exit(EXIT_SUCCESS);
                break;
            case XCB_DESTROY_NOTIFY:
                DEBUG("DestroyNotify for 0x%08x\n",
                      (((xcb_destroy_notify_event_t *)event)->window));
                if (((xcb_destroy_notify_event_t *)event)->window == window)
                    exit(EXIT_SUCCESS);
                break;
            default:
                DEBUG("Unhandled event type %d\n", type);
                break;
        }
        free(event);
    }
}
示例#5
0
/*
 * Instead of polling the X connection socket we leave this to
 * xcb_poll_for_event() which knows better than we can ever know.
 *
 */
static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
    xcb_generic_event_t *event;

    if (xcb_connection_has_error(conn))
        errx(EXIT_FAILURE,
             "X11 connection broke, did your server terminate?\n");

    while ((event = xcb_poll_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            xcb_generic_error_t *error = (xcb_generic_error_t *)event;

            /* Ignore errors when damage report is about destroyed window
             * or damage object is created for already destroyed window */
            if (error->major_code == dam_ext_data->major_opcode &&
                (error->minor_code == XCB_DAMAGE_SUBTRACT ||
                 error->minor_code == XCB_DAMAGE_CREATE)) {
                free(event);
                continue;
            }

            if (debug_mode)
                fprintf(stderr, "X11 Error received! sequence 0x%x, error_code "
                                "= %d, major = 0x%x, minor = 0x%x\n",
                        error->sequence, error->error_code, error->major_code,
                        error->minor_code);
            free(event);
            continue;
        }

        if (fuzzy &&
            event->response_type ==
                dam_ext_data->first_event + XCB_DAMAGE_NOTIFY) {
            xcb_damage_notify_event_t *ev = (xcb_damage_notify_event_t *)event;
            xcb_damage_subtract(conn, ev->damage, XCB_NONE, XCB_NONE);
            redraw_screen();
        }

        /* 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((xcb_key_press_event_t *)event);
                break;

            case XCB_VISIBILITY_NOTIFY:
                handle_visibility_notify(
                    conn, (xcb_visibility_notify_event_t *)event);
                break;

            case XCB_MAP_NOTIFY:
                handle_map_notify((xcb_map_notify_event_t *)event);
                break;

            case XCB_CONFIGURE_NOTIFY:
                handle_screen_resize();
                break;

            default:
                if (type == xkb_base_event)
                    process_xkb_event(event);
        }

        free(event);
    }
}