Example #1
0
/** Get data and parse scancodes.
 * @param arg Pointer to xt_kbd_t structure.
 * @return Never.
 */
int polling(void *arg)
{
    assert(arg);
    const xt_kbd_t *kbd = arg;

    assert(kbd->parent_sess);
    async_exch_t *parent_exch = async_exchange_begin(kbd->parent_sess);
    while (1) {
        if (!parent_exch)
            parent_exch = async_exchange_begin(kbd->parent_sess);

        const int *map = scanmap_simple;
        size_t map_size = sizeof(scanmap_simple) / sizeof(int);

        uint8_t code = 0;
        ssize_t size = chardev_read(parent_exch, &code, 1);

        /** Ignore AT command reply */
        if (code == KBD_ACK || code == KBD_RESEND) {
            continue;
        }

        if (code == KBD_SCANCODE_SET_EXTENDED) {
            map = scanmap_e0;
            map_size = sizeof(scanmap_e0) / sizeof(int);
            size = chardev_read(parent_exch, &code, 1);
            // TODO handle print screen
        }

        /* Invalid read. */
        if (size != 1) {
            continue;
        }


        /* Bit 7 indicates press/release */
        const kbd_event_type_t type =
            (code & 0x80) ? KEY_RELEASE : KEY_PRESS;
        code &= ~0x80;

        const unsigned key = (code < map_size) ? map[code] : 0;
        if (key != 0) {
            async_exch_t *exch =
                async_exchange_begin(kbd->client_sess);
            if (!exch) {
                ddf_msg(LVL_ERROR,
                        "Failed creating exchange.");
                continue;
            }
            async_msg_4(exch, KBDEV_EVENT, type, key, 0, 0);
            async_exchange_end(exch);
        } else {
            ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code);
        }
    }
}
Example #2
0
/** Get data and parse scancodes.
 *
 * @param arg Pointer to at_kbd_t structure.
 *
 * @return EIO on error.
 *
 */
static int polling(void *arg)
{
    const at_kbd_t *kbd = arg;

    assert(kbd);
    assert(kbd->parent_sess);

    async_exch_t *parent_exch = async_exchange_begin(kbd->parent_sess);

    while (true) {
        if (!parent_exch)
            parent_exch = async_exchange_begin(kbd->parent_sess);

        uint8_t code = 0;
        ssize_t size = chardev_read(parent_exch, &code, 1);
        if (size != 1)
            return EIO;

        const unsigned int *map;
        size_t map_size;

        if (code == KBD_SCANCODE_SET_EXTENDED) {
            map = scanmap_e0;
            map_size = sizeof(scanmap_e0) / sizeof(unsigned int);

            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
        } else if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
            if (code != 0x14)
                continue;

            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
            if (code != 0x77)
                continue;

            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
            if (code != 0xe1)
                continue;

            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
            if (code != 0xf0)
                continue;

            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
            if (code != 0x14)
                continue;

            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
            if (code != 0xf0)
                continue;

            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
            if (code == 0x77)
                push_event(kbd->client_sess, KEY_PRESS, KC_BREAK);

            continue;
        } else {
            map = scanmap_simple;
            map_size = sizeof(scanmap_simple) / sizeof(unsigned int);
        }

        kbd_event_type_t type;
        if (code == KBD_SCANCODE_KEY_RELEASE) {
            type = KEY_RELEASE;
            size = chardev_read(parent_exch, &code, 1);
            if (size != 1)
                return EIO;
        } else {
            type = KEY_PRESS;
        }

        const unsigned int key = (code < map_size) ? map[code] : 0;

        if (key != 0)
            push_event(kbd->client_sess, type, key);
        else
            ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code);
    }
}
Example #3
0
/** Get data and parse scancodes.
 *
 * @param arg Pointer to xt_kbd_t structure.
 *
 * @return EIO on error.
 *
 */
static int polling(void *arg)
{
	const xt_kbd_t *kbd = arg;
	
	assert(kbd);
	assert(kbd->parent_sess);
	
	async_exch_t *parent_exch = async_exchange_begin(kbd->parent_sess);
	
	while (true) {
		if (!parent_exch)
			parent_exch = async_exchange_begin(kbd->parent_sess);
		
		const unsigned int *map = scanmap_simple;
		size_t map_size = sizeof(scanmap_simple) / sizeof(unsigned int);
		
		uint8_t code = 0;
		ssize_t size = chardev_read(parent_exch, &code, 1);
		if (size != 1)
			return EIO;
		
		/* Ignore AT command reply */
		if ((code == KBD_ACK) || (code == KBD_RESEND))
			continue;
		
		/* Extended set */
		if (code == KBD_SCANCODE_SET_EXTENDED) {
			map = scanmap_e0;
			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
			
			size = chardev_read(parent_exch, &code, 1);
			if (size != 1)
				return EIO;
			
			/* Handle really special keys */
			
			if (code == 0x2a) {  /* Print Screen */
				size = chardev_read(parent_exch, &code, 1);
				if (size != 1)
					return EIO;
				
				if (code != 0xe0)
					continue;
				
				size = chardev_read(parent_exch, &code, 1);
				if (size != 1)
					return EIO;
				
				if (code == 0x37)
					push_event(kbd->client_sess, KEY_PRESS, KC_PRTSCR);
				
				continue;
			}
			
			if (code == 0x46) {  /* Break */
				size = chardev_read(parent_exch, &code, 1);
				if (size != 1)
					return EIO;
				
				if (code != 0xe0)
					continue;
				
				size = chardev_read(parent_exch, &code, 1);
				if (size != 1)
					return EIO;
				
				if (code == 0xc6)
					push_event(kbd->client_sess, KEY_PRESS, KC_BREAK);
				
				continue;
			}
		}
		
		/* Extended special set */
		if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
			size = chardev_read(parent_exch, &code, 1);
			if (size != 1)
				return EIO;
			
			if (code != 0x1d)
				continue;
			
			size = chardev_read(parent_exch, &code, 1);
			if (size != 1)
				return EIO;
			
			if (code != 0x45)
				continue;
			
			size = chardev_read(parent_exch, &code, 1);
			if (size != 1)
				return EIO;
			
			if (code != 0xe1)
				continue;
			
			size = chardev_read(parent_exch, &code, 1);
			if (size != 1)
				return EIO;
			
			if (code != 0x9d)
				continue;
			
			size = chardev_read(parent_exch, &code, 1);
			if (size != 1)
				return EIO;
			
			if (code == 0xc5)
				push_event(kbd->client_sess, KEY_PRESS, KC_PAUSE);
			
			continue;
		}
		
		/* Bit 7 indicates press/release */
		const kbd_event_type_t type =
		    (code & 0x80) ? KEY_RELEASE : KEY_PRESS;
		code &= ~0x80;
		
		const unsigned int key = (code < map_size) ? map[code] : 0;
		
		if (key != 0)
			push_event(kbd->client_sess, type, key);
		else
			ddf_msg(LVL_WARN, "Unknown scancode: %hhx", code);
	}
}