File: setkeycodes.c

package info (click to toggle)
kbd 2.0.4-4
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid
  • size: 14,136 kB
  • sloc: sh: 12,838; ansic: 12,531; pascal: 472; lex: 466; makefile: 394; yacc: 356; perl: 126; sed: 16
file content (81 lines) | stat: -rw-r--r-- 2,067 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
 * call: setkeycode scancode keycode ...
 *  (where scancode is either xx or e0xx, given in hexadecimal,
 *   and keycode is given in decimal)
 *
 * aeb, 941108, 2004-01-11
 */
#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include "getfd.h"
#include "nls.h"
#include "version.h"
#include "kbd_error.h"

static void __attribute__((noreturn))
usage(char *s)
{
	fprintf(stderr, "setkeycode: %s\n", s);
	fprintf(stderr, _(
	                    "usage: setkeycode scancode keycode ...\n"
	                    " (where scancode is either xx or e0xx, given in hexadecimal,\n"
	                    "  and keycode is given in decimal)\n"));
	exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
	char *ep;
	int fd;
	struct kbkeycode a;

	set_progname(argv[0]);

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE_NAME, LOCALEDIR);
	textdomain(PACKAGE_NAME);

	if (argc == 2 && !strcmp(argv[1], "-V"))
		print_version_and_exit();

	if (argc % 2 != 1)
		usage(_("even number of arguments expected"));

	if ((fd = getfd(NULL)) < 0)
		kbd_error(EXIT_FAILURE, 0, _("Couldn't get a file descriptor referring to the console"));

	while (argc > 2) {
		a.keycode  = atoi(argv[2]);
		a.scancode = strtol(argv[1], &ep, 16);
		if (*ep)
			usage(_("error reading scancode"));
		if (a.scancode >= 0xe000) {
			a.scancode -= 0xe000;
			a.scancode += 128; /* some kernels needed +256 */
		}
#if 0
		/* Test is OK up to 2.5.31--later kernels have more keycodes */
		if (a.scancode > 255 || a.keycode > 127)
			usage(_("code outside bounds"));

		/* Both fields are unsigned int, so can be large;
		   for current kernels the correct test might be
		     (a.scancode > 255 || a.keycode > 239)
		   but we can leave testing to the kernel. */
#endif
		if (ioctl(fd, KDSETKEYCODE, &a)) {
			kbd_error(EXIT_FAILURE, errno,
			          _("failed to set scancode %x to keycode %d: ioctl KDSETKEYCODE"),
			          a.scancode, a.keycode);
		}
		argc -= 2;
		argv += 2;
	}
	return EXIT_SUCCESS;
}