aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/dumbsh.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2014-04-15 18:38:18 +1000
committerDavid Walter Seikel2014-04-15 18:38:18 +1000
commitbbaa3db47599ba25949277e7075fa61ccc1c5a3c (patch)
tree63ec62f775c4e68de5a100388b6a3bfcd3a50c56 /dumbsh.c
parentAdd a showkey toy. Not standard, I'll see if there's an actual standard later. (diff)
downloadboxes-bbaa3db47599ba25949277e7075fa61ccc1c5a3c.zip
boxes-bbaa3db47599ba25949277e7075fa61ccc1c5a3c.tar.gz
boxes-bbaa3db47599ba25949277e7075fa61ccc1c5a3c.tar.bz2
boxes-bbaa3db47599ba25949277e7075fa61ccc1c5a3c.tar.xz
Change from using a bunch of callbacks to using one, with a structure and type.
Diffstat (limited to 'dumbsh.c')
-rw-r--r--dumbsh.c119
1 files changed, 62 insertions, 57 deletions
diff --git a/dumbsh.c b/dumbsh.c
index 058b03a..92ac46a 100644
--- a/dumbsh.c
+++ b/dumbsh.c
@@ -48,34 +48,6 @@ static void updateLine()
48 fflush(stdout); 48 fflush(stdout);
49} 49}
50 50
51// Callback for incoming CSI commands from the terminal.
52static void handleCSI(long extra, char *command, int *params, int count)
53{
54 // Is it a cursor location report?
55 if (strcmp("R", command) == 0)
56 {
57 // Parameters are cursor line and column.
58 // NOTE - This may be sent at other times, not just during terminal resize.
59 // We are assuming here that it's a resize.
60 // The defaults are 1, which get ignored by the heuristic below.
61 int r = params[0], c = params[1];
62
63 // Check it's not an F3 key variation, coz some of them use
64 // the same CSI function command.
65 // This is a heuristic, we are checking against an unusable terminal size.
66 if ((2 == count) && (8 < r) && (8 < c))
67 {
68 TT.h = r;
69 TT.w = c;
70 updateLine();
71 }
72 }
73 // NOTE - The CSI differs from the sequence callback
74 // in not having to return anything. CSI sequences include a
75 // definite terminating byte, so no need for this callback
76 // to tell handle_keys to keep accumulating.
77}
78
79// The various commands. 51// The various commands.
80static void deleteChar() 52static void deleteChar()
81{ 53{
@@ -184,43 +156,76 @@ static struct keyCommand simpleEmacsKeys[] =
184 {"^P", prevHistory} 156 {"^P", prevHistory}
185}; 157};
186 158
187// Callback for incoming key sequences from the user. 159// Callback for incoming sequences from the terminal.
188static int handleKeySequence(long extra, char *sequence, int isTranslated) 160static int handleEvent(long extra, struct keyevent *event)
189{ 161{
190 int j, l = strlen(sequence); 162 switch (event->type)
191
192 // Search for a key sequence bound to a command.
193 for (j = 0; j < (sizeof(simpleEmacsKeys) / sizeof(*simpleEmacsKeys)); j++)
194 { 163 {
195 if (strncmp(simpleEmacsKeys[j].key, sequence, l) == 0) 164 case HK_KEYS :
196 { 165 {
197 // If it's a partial match, keep accumulating them. 166 int j, l = strlen(event->sequence);
198 if (strlen(simpleEmacsKeys[j].key) != l) 167
199 return 0; 168 // Search for a key sequence bound to a command.
200 else 169 for (j = 0; j < ARRAY_LEN(simpleEmacsKeys); j++)
201 { 170 {
202 if (simpleEmacsKeys[j].handler) simpleEmacsKeys[j].handler(); 171 if (strncmp(simpleEmacsKeys[j].key, event->sequence, l) == 0)
203 return 1; 172 {
173 // If it's a partial match, keep accumulating them.
174 if (strlen(simpleEmacsKeys[j].key) != l)
175 return 0;
176 else
177 {
178 if (simpleEmacsKeys[j].handler) simpleEmacsKeys[j].handler();
179 return 1;
180 }
181 }
204 } 182 }
183
184 // See if it's ordinary keys.
185 // NOTE - with vi style ordinary keys can be commands,
186 // but they would be found by the command check above first.
187 if (!event->isTranslated)
188 {
189 if (TT.x < sizeof(toybuf))
190 {
191 int j, l = strlen(event->sequence);
192
193 for (j = strlen(toybuf); j >= TT.x; j--)
194 toybuf[j + l] = toybuf[j];
195 for (j = 0; j < l; j++)
196 toybuf[TT.x + j] = event->sequence[j];
197 TT.x += l;
198 updateLine();
199 }
200 }
201 break;
205 } 202 }
206 }
207 203
208 // See if it's ordinary keys. 204 case HK_CSI :
209 // NOTE - with vi style ordinary keys can be commands,
210 // but they would be found by the command check above first.
211 if (!isTranslated)
212 {
213 if (TT.x < sizeof(toybuf))
214 { 205 {
215 int j, l = strlen(sequence); 206 // Is it a cursor location report?
216 207 if (strcmp("R", event->sequence) == 0)
217 for (j = strlen(toybuf); j >= TT.x; j--) 208 {
218 toybuf[j + l] = toybuf[j]; 209 // Parameters are cursor line and column.
219 for (j = 0; j < l; j++) 210 // NOTE - This may be sent at other times, not just during terminal resize.
220 toybuf[TT.x + j] = sequence[j]; 211 // We are assuming here that it's a resize.
221 TT.x += l; 212 // The defaults are 1, which get ignored by the heuristic below.
222 updateLine(); 213 int r = event->params[0], c = event->params[1];
214
215 // Check it's not an F3 key variation, coz some of them use
216 // the same CSI function command.
217 // This is a heuristic, we are checking against an unusable terminal size.
218 if ((2 == event->count) && (8 < r) && (8 < c))
219 {
220 TT.h = r;
221 TT.w = c;
222 updateLine();
223 }
224 break;
225 }
223 } 226 }
227
228 default : break;
224 } 229 }
225 230
226 // Tell handle_keys to drop it, coz we dealt with it, or it's not one of ours. 231 // Tell handle_keys to drop it, coz we dealt with it, or it's not one of ours.
@@ -269,7 +274,7 @@ void dumbsh_main(void)
269 274
270 // Let's rock! 275 // Let's rock!
271 updateLine(); 276 updateLine();
272 handle_keys(0, handleKeySequence, handleCSI); 277 handle_keys(0, handleEvent);
273 278
274 // Clean up. 279 // Clean up.
275 tcsetattr(0, TCSANOW, &oldTermIo); 280 tcsetattr(0, TCSANOW, &oldTermIo);