aboutsummaryrefslogtreecommitdiff
path: root/console-tools
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-08-17 14:17:48 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-08-17 14:17:48 +0000
commitd7cc2e601d9d909ca9de168da746dede7487e860 (patch)
tree53b88892f0199d42d78380bbb0161d0ebef483e1 /console-tools
parentc8d02aa959d3543239701d7170e0255c49ad6d9e (diff)
downloadbusybox-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.in6
-rw-r--r--console-tools/Kbuild1
-rw-r--r--console-tools/showkey.c138
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
117config SHOWKEY
118 bool "showkey"
119 default n
120 help
121 Shows keys presses.
122
117endmenu 123endmenu
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
19lib-$(CONFIG_SETFONT) += loadfont.o 19lib-$(CONFIG_SETFONT) += loadfont.o
20lib-$(CONFIG_SETKEYCODES) += setkeycodes.o 20lib-$(CONFIG_SETKEYCODES) += setkeycodes.o
21lib-$(CONFIG_SETLOGCONS) += setlogcons.o 21lib-$(CONFIG_SETLOGCONS) += setlogcons.o
22lib-$(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?
16static void xget1(int fd, struct termios *t, struct termios *oldt)
17{
18 tcgetattr(fd, oldt);
19 *t = *oldt;
20 cfmakeraw(t);
21}
22
23static 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 */
36struct 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
49static 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
58int showkey_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
59int 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}