Exemple #1
0
void handle_event(struct input_event *ev)
{
    if (ev->type == EV_KEY) {
        if (test_mode) {
            if (ev->value == VA_PRESS)
            {
                if (reg_key_from_keycode(ev->code, &reg_key))
                    printf("%s (%u)\n", reg_key.name, reg_key.keycode);
                else if (mod_key_from_keycode(ev->code, &mod_key))
                    printf("%s (%u)\n", mod_key.name, mod_key.keycode);
                else
                    printf("? (%u)\n", ev->code);
                if (ev->code == KEY_ESC)
                    running = false;
            }
            return;
        }

        if (!care_for[ev->code])
            return;

        if (ev->value == VA_PRESS || ev->value == VA_REPEAT || ev->value == VA_RELEASE) {
            /* search for the hotkey */
            hotkey_t *hk = NULL;
            if (ev->value == VA_RELEASE) {
                hk = find_hotkey(modmask | RELEASE_MASK, ev->code, current_mode);
            } else {
                hk = find_hotkey(modmask, ev->code, current_mode);
            }

            if (hk != NULL) {
                /* change mode if the hotkey specifies a new mode */
                if (hk->next_mode != NULL) {
                    current_mode = hk->next_mode;
                }
                /* run the hotkey's command */
                char *cmd[] = {SHELL, "-c", hk->command, NULL};
                if (spawnv(cmd[0], cmd) == -1)
                    warn("failed to execute command: %s\n", hk->command);
            } else if (ev->value == VA_PRESS && mod_key_from_keycode(ev->code, &mod_key)) {
                modmask |= mod_key.modval;
            }
        }

        /* remove released modifiers from the current modmask */
        if (ev->value == VA_RELEASE) {
            if (mod_key_from_keycode(ev->code, &mod_key))
                modmask &= ~mod_key.modval;
        }
    }
}
Exemple #2
0
void key_button_event(xcb_generic_event_t *evt, uint8_t event_type)
{
	xcb_keysym_t keysym = XCB_NO_SYMBOL;
	xcb_button_t button = XCB_NONE;
	bool replay_event = false;
	uint16_t modfield = 0;
	uint16_t lockfield = num_lock | caps_lock | scroll_lock;
	parse_event(evt, event_type, &keysym, &button, &modfield);
	modfield &= ~lockfield & MOD_STATE_FIELD;
	if (keysym != XCB_NO_SYMBOL || button != XCB_NONE) {
		hotkey_t *hk = find_hotkey(keysym, button, modfield, event_type, &replay_event);
		if (hk != NULL) {
			run(hk->command, hk->sync);
			if (status_fifo != NULL)
				put_status(COMMAND_PREFIX, hk->command);
		}
	}
	switch (event_type) {
		case XCB_BUTTON_PRESS:
		case XCB_BUTTON_RELEASE:
			if (replay_event)
				xcb_allow_events(dpy, XCB_ALLOW_REPLAY_POINTER, XCB_CURRENT_TIME);
			else
				xcb_allow_events(dpy, XCB_ALLOW_SYNC_POINTER, XCB_CURRENT_TIME);
			break;
		case XCB_KEY_PRESS:
		case XCB_KEY_RELEASE:
			if (replay_event)
				xcb_allow_events(dpy, XCB_ALLOW_REPLAY_KEYBOARD, XCB_CURRENT_TIME);
			else
				xcb_allow_events(dpy, XCB_ALLOW_SYNC_KEYBOARD, XCB_CURRENT_TIME);
			break;
	}
	xcb_flush(dpy);
}
Exemple #3
0
hotkey_t *find_hotkey(xcb_keysym_t keysym, xcb_button_t button, uint16_t modfield, uint8_t event_type, bool *replay_event)
{
	int num_active = 0;
	int num_locked = 0;
	hotkey_t *result = NULL;

	for (hotkey_t *hk = hotkeys_head; hk != NULL; hk = hk->next) {
		chain_t *c = hk->chain;
		if ((chained && c->state == c->head) || (locked && c->state != c->tail))
			continue;
		if (match_chord(c->state, event_type, keysym, button, modfield)) {
			if (status_fifo != NULL && num_active == 0) {
				if (!chained) {
					snprintf(progress, sizeof(progress), "%s", c->state->repr);
				} else {
					strncat(progress, ";", sizeof(progress) - strlen(progress) - 1);
					strncat(progress, c->state->repr, sizeof(progress) - strlen(progress) - 1);
				}
				put_status(HOTKEY_PREFIX, progress);
			}
			if (replay_event != NULL && c->state->replay_event)
				*replay_event = true;
			if (c->state->lock_chain) {
				num_locked += 1;
				if (timeout > 0)
					alarm(0);
			}
			if (c->state == c->tail) {
				if (hk->cycle != NULL) {
					unsigned char delay = hk->cycle->delay;
					hk->cycle->delay = (delay == 0 ? hk->cycle->period - 1 : delay - 1);
					if (delay == 0)
						result = hk;
					continue;
				}
				if (chained && !locked)
					abort_chain();
				return hk;
			} else {
				c->state = c->state->next;
				num_active++;
				grab_chord(c->state);
			}
		} else if (chained) {
			if (!locked && c->state->event_type == event_type)
				c->state = c->head;
			else
				num_active++;
		}
	}

	if (result != NULL)
		return result;

	if (num_locked > 0) {
		locked = true;
	}

	if (!chained) {
		if (num_active > 0) {
			chained = true;
			put_status(BEGIN_CHAIN_PREFIX, "Begin chain");
			grab_chord(abort_chord);
		}
	} else if (num_active == 0 || match_chord(abort_chord, event_type, keysym, button, modfield)) {
		abort_chain();
		return find_hotkey(keysym, button, modfield, event_type, replay_event);
	}
	if (chained && !locked && timeout > 0)
		alarm(timeout);
	PRINTF("num active %i\n", num_active);

	return NULL;
}