aboutsummaryrefslogtreecommitdiff
path: root/console-tools/showkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'console-tools/showkey.c')
-rw-r--r--console-tools/showkey.c81
1 files changed, 37 insertions, 44 deletions
diff --git a/console-tools/showkey.c b/console-tools/showkey.c
index 149ea6465..e7834f702 100644
--- a/console-tools/showkey.c
+++ b/console-tools/showkey.c
@@ -10,6 +10,20 @@
10#include "libbb.h" 10#include "libbb.h"
11#include <linux/kd.h> 11#include <linux/kd.h>
12 12
13
14struct globals {
15 int kbmode;
16 struct termios tio, tio0;
17};
18#define G (*ptr_to_globals)
19#define kbmode (G.kbmode)
20#define tio (G.tio)
21#define tio0 (G.tio0)
22#define INIT_G() do { \
23 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
24} while (0)
25
26
13// set raw tty mode 27// set raw tty mode
14// also used by microcom 28// also used by microcom
15// libbb candidates? 29// libbb candidates?
@@ -20,62 +34,38 @@ static void xget1(struct termios *t, struct termios *oldt)
20 cfmakeraw(t); 34 cfmakeraw(t);
21} 35}
22 36
23static void xset1(struct termios *tio) 37static void xset1(struct termios *t)
24{ 38{
25 int ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, tio); 39 int ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, t);
26 if (ret) { 40 if (ret) {
27 bb_perror_msg("can't tcsetattr for stdin"); 41 bb_perror_msg("can't tcsetattr for stdin");
28 } 42 }
29} 43}
30 44
31/*
32 * GLOBALS
33 */
34struct globals {
35 int kbmode;
36 struct termios tio, tio0;
37};
38#define G (*ptr_to_globals)
39#define kbmode (G.kbmode)
40#define tio (G.tio)
41#define tio0 (G.tio0)
42#define INIT_G() do { \
43 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
44} while (0)
45
46
47static void signal_handler(int signo)
48{
49 // restore keyboard and console settings
50 xset1(&tio0);
51 xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode);
52 // alarmed? -> exit 0
53 exit(SIGALRM == signo);
54}
55
56int showkey_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 45int showkey_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
57int showkey_main(int argc UNUSED_PARAM, char **argv) 46int showkey_main(int argc UNUSED_PARAM, char **argv)
58{ 47{
59 enum { 48 enum {
60 OPT_a = (1<<0), // display the decimal/octal/hex values of the keys 49 OPT_a = (1<<0), // display the decimal/octal/hex values of the keys
61 OPT_k = (1<<1), // display only the interpreted keycodes (default) 50 OPT_k = (1<<1), // display only the interpreted keycodes (default)
62 OPT_s = (1<<2), // display only the raw scan-codes 51 OPT_s = (1<<2), // display only the raw scan-codes
63 }; 52 };
64 53
54 INIT_G();
55
65 // FIXME: aks are all mutually exclusive 56 // FIXME: aks are all mutually exclusive
66 getopt32(argv, "aks"); 57 getopt32(argv, "aks");
67 58
68 INIT_G();
69
70 // get keyboard settings 59 // get keyboard settings
71 xioctl(STDIN_FILENO, KDGKBMODE, &kbmode); 60 xioctl(STDIN_FILENO, KDGKBMODE, &kbmode);
72 printf("kb mode was %s\n\nPress any keys. Program terminates %s\n\n", 61 printf("kb mode was %s\n\nPress any keys. Program terminates %s\n\n",
73 kbmode == K_RAW ? "RAW" : 62 kbmode == K_RAW ? "RAW" :
74 (kbmode == K_XLATE ? "XLATE" : 63 (kbmode == K_XLATE ? "XLATE" :
75 (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" : 64 (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" :
76 (kbmode == K_UNICODE ? "UNICODE" : "?UNKNOWN?"))) 65 (kbmode == K_UNICODE ? "UNICODE" : "UNKNOWN")))
77 , (option_mask32 & OPT_a) ? "when CTRL+D pressed" : "10s after last keypress" 66 , (option_mask32 & OPT_a) ? "on EOF (ctrl-D)" : "10s after last keypress"
78 ); 67 );
68
79 // prepare for raw mode 69 // prepare for raw mode
80 xget1(&tio, &tio0); 70 xget1(&tio, &tio0);
81 // put stdin in raw mode 71 // put stdin in raw mode
@@ -83,34 +73,37 @@ int showkey_main(int argc UNUSED_PARAM, char **argv)
83 73
84 if (option_mask32 & OPT_a) { 74 if (option_mask32 & OPT_a) {
85 unsigned char c; 75 unsigned char c;
76
86 // just read stdin char by char 77 // just read stdin char by char
87 while (1 == safe_read(STDIN_FILENO, &c, 1)) { 78 while (1 == read(STDIN_FILENO, &c, 1)) {
88 printf("%3u 0%03o 0x%02x\r\n", c, c, c); 79 printf("%3u 0%03o 0x%02x\r\n", c, c, c);
89 if (04 /*CTRL-D*/ == c) 80 if (04 /*CTRL-D*/ == c)
90 break; 81 break;
91 } 82 }
92 } else { 83 } else {
93 // we should exit on any signal
94 bb_signals(BB_FATAL_SIGS, signal_handler);
95 // set raw keyboard mode 84 // set raw keyboard mode
96 xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW)); 85 xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW));
97 86
87 // we should exit on any signal; signals should interrupt read
88 bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo);
89
98 // read and show scancodes 90 // read and show scancodes
99 while (1) { 91 while (!bb_got_signal) {
100 char buf[18]; 92 char buf[18];
101 int i, n; 93 int i, n;
94
102 // setup 10s watchdog 95 // setup 10s watchdog
103 alarm(10); 96 alarm(10);
104 // read scancodes 97 // read scancodes
105 n = read(STDIN_FILENO, buf, sizeof(buf)); 98 n = read(STDIN_FILENO, buf, sizeof(buf));
106 i = 0; 99 i = 0;
107 while (i < n) { 100 while (i < n) {
108 char c = buf[i];
109 // show raw scancodes ordered? ->
110 if (option_mask32 & OPT_s) { 101 if (option_mask32 & OPT_s) {
102 // show raw scancodes
111 printf("0x%02x ", buf[i++]); 103 printf("0x%02x ", buf[i++]);
112 // show interpreted scancodes (default) ? ->
113 } else { 104 } else {
105 // show interpreted scancodes (default)
106 char c = buf[i];
114 int kc; 107 int kc;
115 if (i+2 < n 108 if (i+2 < n
116 && (c & 0x7f) == 0 109 && (c & 0x7f) == 0
@@ -130,9 +123,9 @@ int showkey_main(int argc UNUSED_PARAM, char **argv)
130 } 123 }
131 } 124 }
132 125
133 // cleanup 126 // restore keyboard and console settings
134 signal_handler(SIGALRM); 127 xset1(&tio0);
128 xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode);
135 129
136 // should never be here!
137 return EXIT_SUCCESS; 130 return EXIT_SUCCESS;
138} 131}