diff options
Diffstat (limited to '')
-rw-r--r-- | src/boxes/showkey.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/src/boxes/showkey.c b/src/boxes/showkey.c new file mode 100644 index 0000000..de1f804 --- /dev/null +++ b/src/boxes/showkey.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* showkey.c - Shows the keys pressed. | ||
2 | * | ||
3 | * Copyright 2014 David Seikel <won_fang@yahoo.com.au> | ||
4 | * | ||
5 | * Not actually a standard, seems to be three different versions. | ||
6 | * The original kbd - http://kbd-project.org/ | ||
7 | * The kbd fork console-tools - http://lct.sourceforge.net/ | ||
8 | * A utility invented by Eric S. Raymond - http://catb.org/esr/showkey/ | ||
9 | |||
10 | USE_SHOWKEY(NEWTOY(showkey, "", TOYFLAG_USR|TOYFLAG_BIN)) | ||
11 | |||
12 | config SHOWKEY | ||
13 | bool "showkey" | ||
14 | default n | ||
15 | help | ||
16 | usage: showkey | ||
17 | |||
18 | Shows the keys pressed. | ||
19 | */ | ||
20 | |||
21 | #include "toys.h" | ||
22 | #include "lib/handlekeys.h" | ||
23 | |||
24 | typedef void (*eventHandler) (void); | ||
25 | |||
26 | struct keyCommand | ||
27 | { | ||
28 | char *key; | ||
29 | eventHandler handler; | ||
30 | }; | ||
31 | |||
32 | GLOBALS( | ||
33 | unsigned h, w; | ||
34 | int x, y; | ||
35 | ) | ||
36 | |||
37 | #define TT this.showkey | ||
38 | |||
39 | |||
40 | static void quit() | ||
41 | { | ||
42 | printf("Quitting.\r\n"); | ||
43 | handle_keys_quit(); | ||
44 | } | ||
45 | |||
46 | // The key to command mappings. | ||
47 | static struct keyCommand simpleKeys[] = | ||
48 | { | ||
49 | {"^C", quit} | ||
50 | }; | ||
51 | |||
52 | // Callback for incoming sequences from the terminal. | ||
53 | static int handleEvent(long extra, struct keyevent *event) | ||
54 | { | ||
55 | int i; | ||
56 | |||
57 | switch (event->type) | ||
58 | { | ||
59 | case HK_RAW : | ||
60 | { | ||
61 | printf("RAW "); | ||
62 | for (i = 0; event->sequence[i]; i++) | ||
63 | { | ||
64 | printf("(%x) ", (int) event->sequence[i]); | ||
65 | if (32 > event->sequence[i]) | ||
66 | printf("^%c, ", (int) event->sequence[i] + 'A' - 1); | ||
67 | else | ||
68 | printf("%c, ", (int) event->sequence[i]); | ||
69 | } | ||
70 | printf("-> "); | ||
71 | break; | ||
72 | } | ||
73 | |||
74 | case HK_KEYS : | ||
75 | { | ||
76 | int l = strlen(event->sequence); | ||
77 | |||
78 | if (event->isTranslated) | ||
79 | printf("TRANSLATED - "); | ||
80 | else | ||
81 | printf("KEY - "); | ||
82 | printf("%s\r\n", event->sequence); | ||
83 | |||
84 | // Search for a key sequence bound to a command. | ||
85 | for (i = 0; i < ARRAY_LEN(simpleKeys); i++) | ||
86 | { | ||
87 | if (strncmp(simpleKeys[i].key, event->sequence, l) == 0) | ||
88 | { | ||
89 | // If it's a partial match, keep accumulating them. | ||
90 | if (strlen(simpleKeys[i].key) != l) | ||
91 | return 0; | ||
92 | else | ||
93 | if (simpleKeys[i].handler) simpleKeys[i].handler(); | ||
94 | } | ||
95 | } | ||
96 | break; | ||
97 | } | ||
98 | |||
99 | case HK_CSI : | ||
100 | { | ||
101 | // Is it a cursor location report? | ||
102 | if (strcmp("R", event->sequence) == 0) | ||
103 | { | ||
104 | printf("CSI cursor position - line %d, column %d\r\n", event->params[0], event->params[1]); | ||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | printf("CSI command %s - ", event->sequence); | ||
109 | for (i = 0; i < event->count; i++) | ||
110 | printf("%d ", event->params[i]); | ||
111 | printf("\r\n"); | ||
112 | break; | ||
113 | } | ||
114 | |||
115 | default : break; | ||
116 | } | ||
117 | |||
118 | return 1; | ||
119 | } | ||
120 | |||
121 | void showkey_main(void) | ||
122 | { | ||
123 | struct termios termIo, oldTermIo; | ||
124 | |||
125 | // Grab the old terminal settings and save it. | ||
126 | tcgetattr(0, &oldTermIo); | ||
127 | tcflush(0, TCIFLUSH); | ||
128 | termIo = oldTermIo; | ||
129 | |||
130 | // Mould the terminal to our will. | ||
131 | // In this example we are turning off all the terminal smarts, but real code | ||
132 | // might not want that. | ||
133 | termIo.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | ||
134 | | IUCLC | IXON | IXOFF | IXANY); | ||
135 | termIo.c_oflag &= ~OPOST; | ||
136 | termIo.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | TOSTOP | ICANON | ISIG | ||
137 | | IEXTEN); | ||
138 | termIo.c_cflag &= ~(CSIZE | PARENB); | ||
139 | termIo.c_cflag |= CS8; | ||
140 | termIo.c_cc[VTIME]=0; // deciseconds. | ||
141 | termIo.c_cc[VMIN]=1; | ||
142 | tcsetattr(0, TCSANOW, &termIo); | ||
143 | |||
144 | handle_keys(0, handleEvent); | ||
145 | |||
146 | tcsetattr(0, TCSANOW, &oldTermIo); | ||
147 | puts(""); | ||
148 | fflush(stdout); | ||
149 | } | ||