diff options
| author | David Walter Seikel | 2014-04-15 18:38:18 +1000 |
|---|---|---|
| committer | David Walter Seikel | 2014-04-15 18:38:18 +1000 |
| commit | bbaa3db47599ba25949277e7075fa61ccc1c5a3c (patch) | |
| tree | 63ec62f775c4e68de5a100388b6a3bfcd3a50c56 /dumbsh.c | |
| parent | Add a showkey toy. Not standard, I'll see if there's an actual standard later. (diff) | |
| download | boxes-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.c | 119 |
1 files changed, 62 insertions, 57 deletions
| @@ -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. | ||
| 52 | static 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. |
| 80 | static void deleteChar() | 52 | static 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. |
| 188 | static int handleKeySequence(long extra, char *sequence, int isTranslated) | 160 | static 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); |
