diff options
Diffstat (limited to 'src/libvterm/bin/vterm-ctrl.c')
-rw-r--r-- | src/libvterm/bin/vterm-ctrl.c | 366 |
1 files changed, 0 insertions, 366 deletions
diff --git a/src/libvterm/bin/vterm-ctrl.c b/src/libvterm/bin/vterm-ctrl.c deleted file mode 100644 index 9e06011d1..000000000 --- a/src/libvterm/bin/vterm-ctrl.c +++ /dev/null @@ -1,366 +0,0 @@ -#define _XOPEN_SOURCE 500 // strdup - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#define streq(a,b) (strcmp(a,b)==0) -#define TRUE 1 -#define FALSE 0 - -#include <termios.h> - -static char *getvalue(int *argip, int argc, char *argv[]) -{ - if(*argip >= argc) { - fprintf(stderr, "Expected an option value\n"); - exit(1); - } - - return argv[(*argip)++]; -} - -static int getchoice(int *argip, int argc, char *argv[], const char *options[]) -{ - const char *arg = getvalue(argip, argc, argv); - - int value = -1; - while(options[++value]) - if(streq(arg, options[value])) - return value; - - fprintf(stderr, "Unrecognised option value %s\n", arg); - exit(1); -} - -typedef enum { - OFF, - ON, - QUERY, -} BoolQuery; - -static BoolQuery getboolq(int *argip, int argc, char *argv[]) -{ - const char *choices[] = {"off", "on", "query", NULL}; - return getchoice(argip, argc, argv, choices); -} - -static char *helptext[] = { - "reset", - "s8c1t [off|on]", - "keypad [app|num]", - "screen [off|on|query]", - "cursor [off|on|query]", - "curblink [off|on|query]", - "curshape [block|under|bar|query]", - "mouse [off|click|clickdrag|motion]", - "reportfocus [off|on|query]", - "altscreen [off|on|query]", - "bracketpaste [off|on|query]", - "icontitle [STR]", - "icon [STR]", - "title [STR]", - NULL -}; - -static int seticanon(int icanon, int echo) -{ - struct termios termios; - int ret; - - tcgetattr(0, &termios); - - ret = (termios.c_lflag & ICANON); - - if(icanon) termios.c_lflag |= ICANON; - else termios.c_lflag &= ~ICANON; - - if(echo) termios.c_lflag |= ECHO; - else termios.c_lflag &= ~ECHO; - - tcsetattr(0, TCSANOW, &termios); - - return ret; -} - -static void await_c1(unsigned char c1) -{ - unsigned char c; - - // await CSI - 8bit or 2byte 7bit form - int in_esc = FALSE; - while((c = getchar())) { - if(c == c1) - break; - if(in_esc && c == (char)(c1 - 0x40)) - break; - if(!in_esc && c == 0x1b) - in_esc = TRUE; - else - in_esc = FALSE; - } -} - -static char *read_csi() -{ - unsigned char csi[32]; - int i = 0; - - await_c1(0x9B); // CSI - - // TODO: This really should be a more robust CSI parser - for(; i < sizeof(csi)-1; i++) { - int c = csi[i] = getchar(); - if(c >= 0x40 && c <= 0x7e) - break; - } - csi[++i] = 0; - - // TODO: returns longer than 32? - - return strdup((char *)csi); -} - -static char *read_dcs() -{ - unsigned char dcs[32]; - int in_esc = FALSE; - int i; - - await_c1(0x90); - - for(i = 0; i < sizeof(dcs)-1; ) { - char c = getchar(); - if(c == 0x9c) // ST - break; - if(in_esc && c == 0x5c) - break; - if(!in_esc && c == 0x1b) - in_esc = TRUE; - else { - dcs[i++] = c; - in_esc = FALSE; - } - } - dcs[++i] = 0; - - return strdup((char *)dcs); -} - -static void usage(int exitcode) -{ - char **p; - - fprintf(stderr, "Control a libvterm-based terminal\n" - "\n" - "Options:\n"); - - for(p = helptext; *p; p++) - fprintf(stderr, " %s\n", *p); - - exit(exitcode); -} - -static int query_dec_mode(int mode) -{ - char *s = NULL; - - printf("\x1b[?%d$p", mode); - - do { - int reply_mode, reply_value; - char reply_cmd; - - if(s) - free(s); - s = read_csi(); - - // expect "?" mode ";" value "$y" - - // If the sscanf format string ends in a literal, we can't tell from - // its return value if it matches. Hence we'll %c the cmd and check it - // explicitly - if(sscanf(s, "?%d;%d$%c", &reply_mode, &reply_value, &reply_cmd) < 3) - continue; - if(reply_cmd != 'y') - continue; - - if(reply_mode != mode) - continue; - - free(s); - - if(reply_value == 1 || reply_value == 3) - return TRUE; - if(reply_value == 2 || reply_value == 4) - return FALSE; - - printf("Unrecognised reply to DECRQM: %d\n", reply_value); - return FALSE; - } while(1); -} - -static void do_dec_mode(int mode, BoolQuery val, const char *name) -{ - switch(val) { - case OFF: - case ON: - printf("\x1b[?%d%c", mode, val == ON ? 'h' : 'l'); - break; - - case QUERY: - if(query_dec_mode(mode)) - printf("%s on\n", name); - else - printf("%s off\n", name); - break; - } -} - -static int query_rqss_numeric(char *cmd) -{ - char *s = NULL; - - printf("\x1bP$q%s\x1b\\", cmd); - - do { - int num; - - if(s) - free(s); - s = read_dcs(); - - if(!s) - return -1; - if(strlen(s) < strlen(cmd)) - return -1; - if(strcmp(s + strlen(s) - strlen(cmd), cmd) != 0) { - printf("No match\n"); - continue; - } - - if(s[0] != '1' || s[1] != '$' || s[2] != 'r') - return -1; - - if(sscanf(s + 3, "%d", &num) != 1) - return -1; - - return num; - } while(1); -} - -int wasicanon; - -void restoreicanon(void) -{ - seticanon(wasicanon, TRUE); -} - -int main(int argc, char *argv[]) -{ - int argi = 1; - - if(argc == 1) - usage(0); - - wasicanon = seticanon(FALSE, FALSE); - atexit(restoreicanon); - - while(argi < argc) { - const char *arg = argv[argi++]; - - if(streq(arg, "reset")) { - printf("\x1b" "c"); - } - else if(streq(arg, "s8c1t")) { - const char *choices[] = {"off", "on", NULL}; - switch(getchoice(&argi, argc, argv, choices)) { - case 0: - printf("\x1b F"); break; - case 1: - printf("\x1b G"); break; - } - } - else if(streq(arg, "keypad")) { - const char *choices[] = {"app", "num", NULL}; - switch(getchoice(&argi, argc, argv, choices)) { - case 0: - printf("\x1b="); break; - case 1: - printf("\x1b>"); break; - } - } - else if(streq(arg, "screen")) { - do_dec_mode(5, getboolq(&argi, argc, argv), "screen"); - } - else if(streq(arg, "cursor")) { - do_dec_mode(25, getboolq(&argi, argc, argv), "cursor"); - } - else if(streq(arg, "curblink")) { - do_dec_mode(12, getboolq(&argi, argc, argv), "curblink"); - } - else if(streq(arg, "curshape")) { - // TODO: This ought to query the current value of DECSCUSR because it - // may need blinking on or off - const char *choices[] = {"block", "under", "bar", "query", NULL}; - int shape = getchoice(&argi, argc, argv, choices); - switch(shape) { - case 3: // query - shape = query_rqss_numeric(" q"); - switch(shape) { - case 1: case 2: - printf("curshape block\n"); - break; - case 3: case 4: - printf("curshape under\n"); - break; - case 5: case 6: - printf("curshape bar\n"); - break; - } - break; - - case 0: - case 1: - case 2: - printf("\x1b[%d q", 1 + (shape * 2)); - break; - } - } - else if(streq(arg, "mouse")) { - const char *choices[] = {"off", "click", "clickdrag", "motion", NULL}; - switch(getchoice(&argi, argc, argv, choices)) { - case 0: - printf("\x1b[?1000l"); break; - case 1: - printf("\x1b[?1000h"); break; - case 2: - printf("\x1b[?1002h"); break; - case 3: - printf("\x1b[?1003h"); break; - } - } - else if(streq(arg, "reportfocus")) { - do_dec_mode(1004, getboolq(&argi, argc, argv), "reportfocus"); - } - else if(streq(arg, "altscreen")) { - do_dec_mode(1049, getboolq(&argi, argc, argv), "altscreen"); - } - else if(streq(arg, "bracketpaste")) { - do_dec_mode(2004, getboolq(&argi, argc, argv), "bracketpaste"); - } - else if(streq(arg, "icontitle")) { - printf("\x1b]0;%s\a", getvalue(&argi, argc, argv)); - } - else if(streq(arg, "icon")) { - printf("\x1b]1;%s\a", getvalue(&argi, argc, argv)); - } - else if(streq(arg, "title")) { - printf("\x1b]2;%s\a", getvalue(&argi, argc, argv)); - } - else { - fprintf(stderr, "Unrecognised command %s\n", arg); - exit(1); - } - } - return 0; -} |