diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-08-17 14:17:48 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-08-17 14:17:48 +0000 |
commit | d7cc2e601d9d909ca9de168da746dede7487e860 (patch) | |
tree | 53b88892f0199d42d78380bbb0161d0ebef483e1 /console-tools | |
parent | c8d02aa959d3543239701d7170e0255c49ad6d9e (diff) | |
download | busybox-w32-d7cc2e601d9d909ca9de168da746dede7487e860.tar.gz busybox-w32-d7cc2e601d9d909ca9de168da746dede7487e860.tar.bz2 busybox-w32-d7cc2e601d9d909ca9de168da746dede7487e860.zip |
showkey: new applet by Vladimir
Diffstat (limited to 'console-tools')
-rw-r--r-- | console-tools/Config.in | 6 | ||||
-rw-r--r-- | console-tools/Kbuild | 1 | ||||
-rw-r--r-- | console-tools/showkey.c | 138 |
3 files changed, 145 insertions, 0 deletions
diff --git a/console-tools/Config.in b/console-tools/Config.in index efba9cd09..a08ee42f7 100644 --- a/console-tools/Config.in +++ b/console-tools/Config.in | |||
@@ -114,4 +114,10 @@ config SETLOGCONS | |||
114 | help | 114 | help |
115 | This program redirects the output console of kernel messages. | 115 | This program redirects the output console of kernel messages. |
116 | 116 | ||
117 | config SHOWKEY | ||
118 | bool "showkey" | ||
119 | default n | ||
120 | help | ||
121 | Shows keys presses. | ||
122 | |||
117 | endmenu | 123 | endmenu |
diff --git a/console-tools/Kbuild b/console-tools/Kbuild index 0a182500e..df5ffdb96 100644 --- a/console-tools/Kbuild +++ b/console-tools/Kbuild | |||
@@ -19,3 +19,4 @@ lib-$(CONFIG_RESIZE) += resize.o | |||
19 | lib-$(CONFIG_SETFONT) += loadfont.o | 19 | lib-$(CONFIG_SETFONT) += loadfont.o |
20 | lib-$(CONFIG_SETKEYCODES) += setkeycodes.o | 20 | lib-$(CONFIG_SETKEYCODES) += setkeycodes.o |
21 | lib-$(CONFIG_SETLOGCONS) += setlogcons.o | 21 | lib-$(CONFIG_SETLOGCONS) += setlogcons.o |
22 | lib-$(CONFIG_SHOWKEY) += showkey.o | ||
diff --git a/console-tools/showkey.c b/console-tools/showkey.c new file mode 100644 index 000000000..e4603e2d3 --- /dev/null +++ b/console-tools/showkey.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * shows keys pressed. inspired by kbd package | ||
4 | * | ||
5 | * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com> | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this tarball for details. | ||
8 | */ | ||
9 | |||
10 | #include "libbb.h" | ||
11 | #include <linux/kd.h> | ||
12 | |||
13 | // set raw tty mode | ||
14 | // also used by microcom | ||
15 | // libbb candidates? | ||
16 | static void xget1(int fd, struct termios *t, struct termios *oldt) | ||
17 | { | ||
18 | tcgetattr(fd, oldt); | ||
19 | *t = *oldt; | ||
20 | cfmakeraw(t); | ||
21 | } | ||
22 | |||
23 | static int xset1(int fd, struct termios *tio, const char *device) | ||
24 | { | ||
25 | int ret = tcsetattr(fd, TCSAFLUSH, tio); | ||
26 | |||
27 | if (ret) { | ||
28 | bb_perror_msg("can't tcsetattr for %s", device); | ||
29 | } | ||
30 | return ret; | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * GLOBALS | ||
35 | */ | ||
36 | struct globals { | ||
37 | int kbmode; | ||
38 | struct termios tio, tio0; | ||
39 | }; | ||
40 | #define G (*ptr_to_globals) | ||
41 | #define kbmode (G.kbmode) | ||
42 | #define tio (G.tio) | ||
43 | #define tio0 (G.tio0) | ||
44 | #define INIT_G() do { \ | ||
45 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | ||
46 | } while (0) | ||
47 | |||
48 | |||
49 | static void signal_handler(int signo) | ||
50 | { | ||
51 | // restore keyboard and console settings | ||
52 | xset1(STDIN_FILENO, &tio0, "stdin"); | ||
53 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)kbmode); | ||
54 | // alarmed? -> exit 0 | ||
55 | exit(SIGALRM == signo); | ||
56 | } | ||
57 | |||
58 | int showkey_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
59 | int showkey_main(int argc UNUSED_PARAM, char **argv) | ||
60 | { | ||
61 | enum { | ||
62 | OPT_a = (1<<0), // display the decimal/octal/hex values of the keys | ||
63 | OPT_k = (1<<1), // display only the interpreted keycodes (default) | ||
64 | OPT_s = (1<<2), // display only the raw scan-codes | ||
65 | }; | ||
66 | |||
67 | // FIXME: aks are all mutually exclusive | ||
68 | getopt32(argv, "aks"); | ||
69 | |||
70 | INIT_G(); | ||
71 | |||
72 | // get keyboard settings | ||
73 | xioctl(STDIN_FILENO, KDGKBMODE, &kbmode); | ||
74 | printf("kb mode was %s\n\nPress any keys. Program terminates %s\n\n", | ||
75 | kbmode == K_RAW ? "RAW" : | ||
76 | (kbmode == K_XLATE ? "XLATE" : | ||
77 | (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" : | ||
78 | (kbmode == K_UNICODE ? "UNICODE" : "?UNKNOWN?"))) | ||
79 | , (option_mask32 & OPT_a) ? "when CTRL+D pressed" : "10s after last keypress" | ||
80 | ); | ||
81 | // prepare for raw mode | ||
82 | xget1(STDIN_FILENO, &tio, &tio0); | ||
83 | // put stdin in raw mode | ||
84 | xset1(STDIN_FILENO, &tio, "stdin"); | ||
85 | |||
86 | if (option_mask32 & OPT_a) { | ||
87 | char c; | ||
88 | // just read stdin char by char | ||
89 | while (1 == safe_read(STDIN_FILENO, &c, 1)) { | ||
90 | printf("%3d 0%03o 0x%02x\r\n", c, c, c); | ||
91 | if (04 /*CTRL-D*/ == c) | ||
92 | break; | ||
93 | } | ||
94 | } else { | ||
95 | // we should exit on any signal | ||
96 | bb_signals(BB_FATAL_SIGS, signal_handler); | ||
97 | // set raw keyboard mode | ||
98 | xioctl(STDIN_FILENO, KDSKBMODE, (void *)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW)); | ||
99 | |||
100 | // read and show scancodes | ||
101 | while (1) { | ||
102 | char buf[18]; | ||
103 | int i, n; | ||
104 | // setup 10s watchdog | ||
105 | alarm(10); | ||
106 | // read scancodes | ||
107 | n = read(STDIN_FILENO, buf, sizeof(buf)); | ||
108 | i = 0; | ||
109 | while (i < n) { | ||
110 | char c = buf[i]; | ||
111 | // show raw scancodes ordered? -> | ||
112 | if (option_mask32 & OPT_s) { | ||
113 | printf("0x%02x ", buf[i++]); | ||
114 | // show interpreted scancodes (default) ? -> | ||
115 | } else { | ||
116 | int kc; | ||
117 | if (i+2 < n && (c & 0x7f) == 0 | ||
118 | && (buf[i+1] & 0x80) != 0 | ||
119 | && (buf[i+2] & 0x80) != 0) { | ||
120 | kc = ((buf[i+1] & 0x7f) << 7) | (buf[i+2] & 0x7f); | ||
121 | i += 3; | ||
122 | } else { | ||
123 | kc = (c & 0x7f); | ||
124 | i++; | ||
125 | } | ||
126 | printf("keycode %3d %s", kc, (c & 0x80) ? "release" : "press"); | ||
127 | } | ||
128 | } | ||
129 | puts("\r"); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | // cleanup | ||
134 | signal_handler(SIGALRM); | ||
135 | |||
136 | // should never be here! | ||
137 | return EXIT_SUCCESS; | ||
138 | } | ||