Ejemplo n.º 1
0
int
lk_add_key(struct lk_ctx *ctx, unsigned int k_table, unsigned int k_index, int keycode)
{
	struct lk_array *map;
	unsigned int code = keycode + 1;

	if (keycode == CODE_FOR_UNKNOWN_KSYM) {
		/* is safer not to be silent in this case, 
		 * it can be caused by coding errors as well. */
		ERR(ctx, _("lk_add_key called with bad keycode %d"), keycode);
		return -1;
	}

	if (!k_index && keycode == K_NOSUCHMAP)
		return 0;

	map = lk_array_get_ptr(ctx->keymap, k_table);
	if (!map) {
		if (ctx->keywords & LK_KEYWORD_KEYMAPS) {
			ERR(ctx, _("adding map %d violates explicit keymaps line"),
			    k_table);
			return -1;
		}

		if (lk_add_map(ctx, k_table) < 0)
			return -1;
	}

	if ((ctx->keywords & LK_KEYWORD_ALTISMETA) && keycode == K_HOLE &&
	    lk_key_exists(ctx, k_table, k_index))
		return 0;

	map = lk_array_get_ptr(ctx->keymap, k_table);

	if (lk_array_set(map, k_index, &code) < 0) {
		ERR(ctx, _("unable to set key %d for table %d"),
			k_index, k_table);
		return -1;
	}

	if (ctx->keywords & LK_KEYWORD_ALTISMETA) {
		unsigned int alttable = k_table | M_ALT;
		int type = KTYP(keycode);
		int val = KVAL(keycode);

		if (alttable != k_table && lk_map_exists(ctx, alttable) &&
		    !lk_key_exists(ctx, alttable, k_index) &&
		    (type == KT_LATIN || type == KT_LETTER) &&
		    val < 128) {
			if (lk_add_key(ctx, alttable, k_index, K(KT_META, val)) < 0)
				return -1;
		}
	}

	return 0;
}
Ejemplo n.º 2
0
static int
do_constant_key(struct lk_ctx *ctx, int i, unsigned short key)
{
	int typ, val;
	unsigned int j;

	typ = KTYP(key);
	val = KVAL(key);

	if ((typ == KT_LATIN || typ == KT_LETTER) &&
	    ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'))) {
		unsigned short defs[16];
		defs[0] = K(KT_LETTER, val);
		defs[1] = K(KT_LETTER, val ^ 32);
		defs[2] = defs[0];
		defs[3] = defs[1];

		for (j = 4; j < 8; j++)
			defs[j] = K(KT_LATIN, val & ~96);

		for (j = 8; j < 16; j++)
			defs[j] = K(KT_META, KVAL(defs[j - 8]));

		for (j = 0; j < ctx->keymap->total; j++) {
			if (!lk_map_exists(ctx, j))
				continue;

			if (j > 0 && lk_key_exists(ctx, j, i))
				continue;

			if (lk_add_key(ctx, j, i, defs[j % 16]) < 0)
				return -1;
		}

	} else {
		/* do this also for keys like Escape,
		   as promised in the man page */
		for (j = 1; j < ctx->keymap->total; j++) {
			if (!lk_map_exists(ctx, j))
				continue;

			if (lk_key_exists(ctx, j, i))
				continue;

			if (lk_add_key(ctx, j, i, key) < 0)
				return -1;
		}
	}
	return 0;
}
Ejemplo n.º 3
0
static int
defkeys(struct lk_ctx *ctx, int fd, int kbd_mode)
{
	struct kbentry ke;
	int ct = 0;
	int i, j, fail;

	if (ctx->flags & LK_FLAG_UNICODE_MODE) {
		/* temporarily switch to K_UNICODE while defining keys */
		if (ioctl(fd, KDSKBMODE, K_UNICODE)) {
			ERR(ctx, _("KDSKBMODE: %s: could not switch to Unicode mode"),
			    strerror(errno));
			goto fail;
		}
	}

	for (i = 0; i < MAX_NR_KEYMAPS; i++) {
		int exist = lk_map_exists(ctx, i);

		if (exist) {
			for (j = 0; j < NR_KEYS; j++) {
				if (!lk_key_exists(ctx, i, j))
					continue;

				int value = lk_get_key(ctx, i, j);

				if (value < 0 || value > USHRT_MAX) {
					WARN(ctx, _("can not bind key %d to value %d because it is too large"), j, value);
					continue;
				}

				ke.kb_index = (unsigned char) j;
				ke.kb_table = (unsigned char) i;
				ke.kb_value = (unsigned short) value;

				fail = ioctl(fd, KDSKBENT, (unsigned long)&ke);

				if (fail) {
					if (errno == EPERM) {
						ERR(ctx, _("Keymap %d: Permission denied"), i);
						j = NR_KEYS;
						continue;
					}
					ERR(ctx, "%s", strerror(errno));
				} else
					ct++;

				INFO(ctx, _("keycode %d, table %d = %d%s"),
				     j, i, ke.kb_value, fail ? _("    FAILED") : "");

				if (fail)
					WARN(ctx, _("failed to bind key %d to value %d"),
					     j, ke.kb_value);
			}

		} else if ((ctx->keywords & LK_KEYWORD_KEYMAPS) && !exist) {
			/* deallocate keymap */
			ke.kb_index = 0;
			ke.kb_table = (unsigned char) i;
			ke.kb_value = K_NOSUCHMAP;

			DBG(ctx, _("deallocate keymap %d"), i);

			if (ioctl(fd, KDSKBENT, (unsigned long)&ke)) {
				if (errno != EINVAL) {
					ERR(ctx, _("KDSKBENT: %s: could not deallocate keymap %d"),
					    strerror(errno), i);
					goto fail;
				}
				/* probably an old kernel */
				/* clear keymap by hand */
				for (j = 0; j < NR_KEYS; j++) {
					ke.kb_index = (unsigned char) j;
					ke.kb_table = (unsigned char) i;
					ke.kb_value = K_HOLE;

					if (ioctl(fd, KDSKBENT, (unsigned long)&ke)) {
						if (errno == EINVAL && i >= 16)
							break; /* old kernel */

						ERR(ctx, _("KDSKBENT: %s: cannot deallocate or clear keymap"),
						    strerror(errno));
						goto fail;
					}
				}
			}
		}
	}

	if ((ctx->flags & LK_FLAG_UNICODE_MODE) && ioctl(fd, KDSKBMODE, kbd_mode)) {
		ERR(ctx, _("KDSKBMODE: %s: could not return to original keyboard mode"),
		    strerror(errno));
		goto fail;
	}

	return ct;

fail:
	return -1;
}