source: MondoRescue/branches/3.3/mindi-busybox/console-tools/showkey.c@ 3865

Last change on this file since 3865 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 3.5 KB
RevLine 
[2725]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 source tree.
8 */
9
[3232]10//usage:#define showkey_trivial_usage
11//usage: "[-a | -k | -s]"
12//usage:#define showkey_full_usage "\n\n"
13//usage: "Show keys pressed\n"
14//usage: "\n -a Display decimal/octal/hex values of the keys"
15//usage: "\n -k Display interpreted keycodes (default)"
16//usage: "\n -s Display raw scan-codes"
17
[2725]18#include "libbb.h"
19#include <linux/kd.h>
20
21
22struct globals {
23 int kbmode;
24 struct termios tio, tio0;
25};
26#define G (*ptr_to_globals)
27#define kbmode (G.kbmode)
28#define tio (G.tio)
29#define tio0 (G.tio0)
30#define INIT_G() do { \
31 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
32} while (0)
33
34
35// set raw tty mode
36// also used by microcom
37// libbb candidates?
38static void xget1(struct termios *t, struct termios *oldt)
39{
40 tcgetattr(STDIN_FILENO, oldt);
41 *t = *oldt;
42 cfmakeraw(t);
43}
44
45static void xset1(struct termios *t)
46{
47 int ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, t);
48 if (ret) {
49 bb_perror_msg("can't tcsetattr for stdin");
50 }
51}
52
53int showkey_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
54int showkey_main(int argc UNUSED_PARAM, char **argv)
55{
56 enum {
57 OPT_a = (1<<0), // display the decimal/octal/hex values of the keys
58 OPT_k = (1<<1), // display only the interpreted keycodes (default)
59 OPT_s = (1<<2), // display only the raw scan-codes
60 };
61
62 INIT_G();
63
64 // FIXME: aks are all mutually exclusive
65 getopt32(argv, "aks");
66
67 // prepare for raw mode
68 xget1(&tio, &tio0);
69 // put stdin in raw mode
70 xset1(&tio);
71
[3232]72#define press_keys "Press any keys, program terminates %s:\r\n\n"
73
[2725]74 if (option_mask32 & OPT_a) {
[3232]75 // just read stdin char by char
[2725]76 unsigned char c;
77
[3232]78 printf(press_keys, "on EOF (ctrl-D)");
79
80 // read and show byte values
[2725]81 while (1 == read(STDIN_FILENO, &c, 1)) {
82 printf("%3u 0%03o 0x%02x\r\n", c, c, c);
83 if (04 /*CTRL-D*/ == c)
84 break;
85 }
86 } else {
[3232]87 // we assume a PC keyboard
88 xioctl(STDIN_FILENO, KDGKBMODE, &kbmode);
89 printf("Keyboard mode was %s.\r\n\n",
90 kbmode == K_RAW ? "RAW" :
91 (kbmode == K_XLATE ? "XLATE" :
92 (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" :
93 (kbmode == K_UNICODE ? "UNICODE" : "UNKNOWN")))
94 );
95
[2725]96 // set raw keyboard mode
97 xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW));
98
99 // we should exit on any signal; signals should interrupt read
100 bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo);
101
[3232]102 // inform user that program ends after time of inactivity
103 printf(press_keys, "10s after last keypress");
104
[2725]105 // read and show scancodes
106 while (!bb_got_signal) {
107 char buf[18];
108 int i, n;
109
110 // setup 10s watchdog
111 alarm(10);
[3232]112
[2725]113 // read scancodes
114 n = read(STDIN_FILENO, buf, sizeof(buf));
115 i = 0;
116 while (i < n) {
117 if (option_mask32 & OPT_s) {
118 // show raw scancodes
119 printf("0x%02x ", buf[i++]);
120 } else {
121 // show interpreted scancodes (default)
122 char c = buf[i];
123 int kc;
124 if (i+2 < n
125 && (c & 0x7f) == 0
126 && (buf[i+1] & 0x80) != 0
127 && (buf[i+2] & 0x80) != 0
128 ) {
129 kc = ((buf[i+1] & 0x7f) << 7) | (buf[i+2] & 0x7f);
130 i += 3;
131 } else {
132 kc = (c & 0x7f);
133 i++;
134 }
135 printf("keycode %3u %s", kc, (c & 0x80) ? "release" : "press");
136 }
137 }
138 puts("\r");
139 }
[3232]140
141 // restore keyboard mode
142 xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode);
[2725]143 }
144
[3232]145 // restore console settings
[2725]146 xset1(&tio0);
147
148 return EXIT_SUCCESS;
149}
Note: See TracBrowser for help on using the repository browser.