summaryrefslogtreecommitdiff
path: root/src/libvterm/bin/vterm-ctrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libvterm/bin/vterm-ctrl.c')
-rw-r--r--src/libvterm/bin/vterm-ctrl.c366
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;
-}