aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/boxes/showkey.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boxes/showkey.c149
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
10USE_SHOWKEY(NEWTOY(showkey, "", TOYFLAG_USR|TOYFLAG_BIN))
11
12config 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
24typedef void (*eventHandler) (void);
25
26struct keyCommand
27{
28 char *key;
29 eventHandler handler;
30};
31
32GLOBALS(
33 unsigned h, w;
34 int x, y;
35)
36
37#define TT this.showkey
38
39
40static void quit()
41{
42 printf("Quitting.\r\n");
43 handle_keys_quit();
44}
45
46// The key to command mappings.
47static struct keyCommand simpleKeys[] =
48{
49 {"^C", quit}
50};
51
52// Callback for incoming sequences from the terminal.
53static 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
121void 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}