diff options
Diffstat (limited to 'src/process.c')
-rw-r--r-- | src/process.c | 1192 |
1 files changed, 676 insertions, 516 deletions
diff --git a/src/process.c b/src/process.c index 115ac0f..d6e948f 100644 --- a/src/process.c +++ b/src/process.c @@ -1,4 +1,7 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -26,6 +29,8 @@ **************************************************************** */ +#include "config.h" + #include <sys/types.h> #include <sys/stat.h> #include <signal.h> @@ -39,8 +44,6 @@ #endif -#include "config.h" - /* for solaris 2.1, Unixware (SVR4.2) and possibly others: */ #ifdef HAVE_STROPTS_H # include <sys/stropts.h> @@ -49,6 +52,9 @@ #include "screen.h" #include "extern.h" #include "logfile.h" +#include "layout.h" +#include "viewport.h" +#include "list_generic.h" extern struct comm comms[]; extern char *rc_name; @@ -57,6 +63,7 @@ extern char *BellString, *ActivityString, *ShellProg, *ShellArgs[]; extern char *hstatusstring, *captionstring, *timestring; extern char *wliststr, *wlisttit; extern int captionalways; +extern int queryflag; extern char *hardcopydir, *screenlogfile, *logtstamp_string; extern int log_flush, logtstamp_on, logtstamp_after; extern char *VisualBellString; @@ -75,6 +82,7 @@ extern char *printcmd; extern int default_startup; extern int defobuflimit; extern int defnonblock; +extern int defmousetrack; extern int ZombieKey_destroy; extern int ZombieKey_resurrect; extern int ZombieKey_onerror; @@ -106,6 +114,7 @@ extern char *kmapadef[]; extern char *kmapmdef[]; #endif extern struct mchar mchar_so, mchar_null; +extern int renditions[]; extern int VerboseCreate; #ifdef UTF8 extern char *screenencodings; @@ -153,6 +162,7 @@ static void pass2 __P((char *, int, char *)); static void pow_detach_fn __P((char *, int, char *)); #endif static void digraph_fn __P((char *, int, char *)); +static int digraph_find __P((const char *buf)); static void confirm_fn __P((char *, int, char *)); static int IsOnDisplay __P((struct win *)); static void ResizeRegions __P((char *, int)); @@ -181,7 +191,7 @@ extern int nethackflag; #endif -struct win *wtab[MAXWIN]; /* window table, should be dynamic */ +extern struct win **wtab; #ifdef MULTIUSER extern char *multi; @@ -228,9 +238,18 @@ int kmap_extn; static int maptimeout = 300; #endif +#ifndef MAX_DIGRAPH +#define MAX_DIGRAPH 512 +#endif + +struct digraph +{ + unsigned char d[2]; + int value; +}; /* digraph table taken from old vim and rfc1345 */ -static const unsigned char digraphs[][3] = { +static struct digraph digraphs[MAX_DIGRAPH + 1] = { {' ', ' ', 160}, /* */ {'N', 'S', 160}, /* */ {'~', '!', 161}, /* ¡ */ @@ -419,6 +438,44 @@ static char *resizeprompts[] = { "resize -l -b # lines: ", }; +static int +parse_input_int(buf, len, val) +const char *buf; +int len; +int *val; +{ + int x = 0, i; + if (len >= 1 && ((*buf == 'U' && buf[1] == '+') || (*buf == '0' && (buf[1] == 'x' || buf[1] == 'X')))) + { + x = 0; + for (i = 2; i < len; i++) + { + if (buf[i] >= '0' && buf[i] <= '9') + x = x * 16 | (buf[i] - '0'); + else if (buf[i] >= 'a' && buf[i] <= 'f') + x = x * 16 | (buf[i] - ('a' - 10)); + else if (buf[i] >= 'A' && buf[i] <= 'F') + x = x * 16 | (buf[i] - ('A' - 10)); + else + return 0; + } + } + else if (buf[0] == '0') + { + x = 0; + for (i = 1; i < len; i++) + { + if (buf[i] < '0' || buf[i] > '7') + return 0; + x = x * 8 | (buf[i] - '0'); + } + } + else + return 0; + *val = x; + return 1; +} + char *noargs[1]; void @@ -534,7 +591,7 @@ InitKeytab() args[1] = NULL; SaveAction(ktab + '-', RC_SELECT, args, 0); } - for (i = 0; i < ((MAXWIN < 10) ? MAXWIN : 10); i++) + for (i = 0; i < ((maxwin && maxwin < 10) ? maxwin : 10); i++) { char *args[2], arg1[10]; args[0] = arg1; @@ -582,7 +639,7 @@ InitKeytab() ktab['\t'].nr = RC_FOCUS; { char *args[2]; - args[0] = "up"; + args[0] = "prev"; args[1] = 0; SaveAction(ktab + T_BACKTAB - T_CAPS + 256, RC_FOCUS, args, 0); } @@ -634,7 +691,7 @@ int create; kp = malloc(sizeof(*kp)); if (kp == 0) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); return 0; } kp->name = SaveStr(class); @@ -642,6 +699,8 @@ int create; { kp->ktab[i].nr = RC_ILLEGAL; kp->ktab[i].args = noargs; + kp->ktab[i].argl = 0; + kp->ktab[i].quiet = 0; } kp->next = 0; *kpp = kp; @@ -938,7 +997,7 @@ struct paster *pa; int FindCommnr(str) -char *str; +const char *str; { int x, m, l = 0, r = RC_LAST; while (l <= r) @@ -1070,6 +1129,16 @@ char *data; LayProcess(&buf, &len); } +/* If the command is not 'quieted', then use Msg to output the message. If it's a remote + * query, then Msg takes care of also outputting the message to the querying client. + * + * If we want the command to be quiet, and it's a remote query, then use QueryMsg so that + * the response does go back to the querying client. + * + * If the command is quieted, and it's not a remote query, then just don't print the message. + */ +#define OutputMsg (!act->quiet ? Msg : queryflag >= 0 ? QueryMsg : Dummy) + /*ARGSUSED*/ void DoAction(act, key) @@ -1093,19 +1162,35 @@ int key; return; } n = comms[nr].flags; + /* Commands will have a CAN_QUERY flag, depending on whether they have + * something to return on a query. For example, 'windows' can return a result, + * but 'other' cannot. + * If some command causes an error, then it should reset queryflag to -1, so that + * the process requesting the query can be notified that an error happened. + */ + if (!(n & CAN_QUERY) && queryflag >= 0) + { + /* Query flag is set, but this command cannot be queried. */ + OutputMsg(0, "%s command cannot be queried.", comms[nr].name); + queryflag = -1; + return; + } if ((n & NEED_DISPLAY) && display == 0) { - Msg(0, "%s: %s: display required", rc_name, comms[nr].name); + OutputMsg(0, "%s: %s: display required", rc_name, comms[nr].name); + queryflag = -1; return; } if ((n & NEED_FORE) && fore == 0) { - Msg(0, "%s: %s: window required", rc_name, comms[nr].name); + OutputMsg(0, "%s: %s: window required", rc_name, comms[nr].name); + queryflag = -1; return; } if ((n & NEED_LAYER) && flayer == 0) { - Msg(0, "%s: %s: display or window required", rc_name, comms[nr].name); + OutputMsg(0, "%s: %s: display or window required", rc_name, comms[nr].name); + queryflag = -1; return; } if ((argc = CheckArgNum(nr, args)) < 0) @@ -1115,8 +1200,9 @@ int key; { if (AclCheckPermCmd(D_user, ACL_EXEC, &comms[nr])) { - Msg(0, "%s: %s: permission denied (user %s)", + OutputMsg(0, "%s: %s: permission denied (user %s)", rc_name, comms[nr].name, (EffectiveAclUser ? EffectiveAclUser : D_user)->u_name); + queryflag = -1; return; } } @@ -1136,7 +1222,10 @@ int key; else if (args[0][0] == '.' && !args[0][1]) { if (!fore) - Msg(0, "select . needs a window"); + { + OutputMsg(0, "select . needs a window"); + queryflag = -1; + } else { SetForeWindow(fore); @@ -1145,22 +1234,24 @@ int key; } else if (ParseWinNum(act, &n) == 0) SwitchWindow(n); + else if (queryflag >= 0) + queryflag = -1; /* ParseWinNum already prints out an appropriate error message. */ break; #ifdef AUTO_NUKE case RC_DEFAUTONUKE: if (ParseOnOff(act, &defautonuke) == 0 && msgok) - Msg(0, "Default autonuke turned %s", defautonuke ? "on" : "off"); + OutputMsg(0, "Default autonuke turned %s", defautonuke ? "on" : "off"); if (display && *rc_name) D_auto_nuke = defautonuke; break; case RC_AUTONUKE: if (ParseOnOff(act, &D_auto_nuke) == 0 && msgok) - Msg(0, "Autonuke turned %s", D_auto_nuke ? "on" : "off"); + OutputMsg(0, "Autonuke turned %s", D_auto_nuke ? "on" : "off"); break; #endif case RC_DEFOBUFLIMIT: if (ParseNum(act, &defobuflimit) == 0 && msgok) - Msg(0, "Default limit set to %d", defobuflimit); + OutputMsg(0, "Default limit set to %d", defobuflimit); if (display && *rc_name) { D_obufmax = defobuflimit; @@ -1169,9 +1260,9 @@ int key; break; case RC_OBUFLIMIT: if (*args == 0) - Msg(0, "Limit is %d, current buffer size is %d", D_obufmax, D_obuflen); + OutputMsg(0, "Limit is %d, current buffer size is %d", D_obufmax, D_obuflen); else if (ParseNum(act, &D_obufmax) == 0 && msgok) - Msg(0, "Limit set to %d", D_obufmax); + OutputMsg(0, "Limit set to %d", D_obufmax); D_obuflenmax = D_obuflen - D_obufmax; break; case RC_DUMPTERMCAP: @@ -1180,22 +1271,27 @@ int key; case RC_HARDCOPY: { int mode = DUMP_HARDCOPY; + char *file = NULL; - if (argc > 1 && !strcmp(*args, "-h")) + if (args[0]) { - mode = DUMP_SCROLLBACK; - args++; - argc--; + if (!strcmp(*args, "-h")) + { + mode = DUMP_SCROLLBACK; + file = args[1]; + } + else if (!strcmp(*args, "--") && args[1]) + file = args[1]; + else + file = args[0]; } - if (*args && args[1]) + + if (args[0] && file == args[0] && args[1]) { - Msg(0, "%s: hardcopy: too many arguments", rc_name); + OutputMsg(0, "%s: hardcopy: too many arguments", rc_name); break; } - if (fore == 0 && *args == 0) - Msg(0, "%s: hardcopy: window required", rc_name); - else - WriteFile(user, *args, mode); + WriteFile(user, file, mode); } break; case RC_DEFLOG: @@ -1237,13 +1333,13 @@ int key; if (fore->w_pwin) { FreePseudowin(fore); - Msg(0, "Filter removed."); + OutputMsg(0, "Filter removed."); break; } #endif name = SaveStr(fore->w_title); KillWindow(fore); - Msg(0, "Window %d (%s) killed.", n, name); + OutputMsg(0, "Window %d (%s) killed.", n, name); if (name) free(name); break; @@ -1282,9 +1378,9 @@ int key; if (!*args) { if (dfp) - Msg(0, "debugging info is written to %s/", DEBUGDIR); + OutputMsg(0, "debugging info is written to %s/", DEBUGDIR); else - Msg(0, "debugging is currently off. Use 'debug on' to enable."); + OutputMsg(0, "debugging is currently off. Use 'debug on' to enable."); break; } if (dfp) @@ -1302,7 +1398,7 @@ int key; # endif /* SIG_NODEBUG */ #else if (*args == 0 || strcmp("off", *args)) - Msg(0, "Sorry, screen was compiled without -DDEBUG option."); + OutputMsg(0, "Sorry, screen was compiled without -DDEBUG option."); #endif break; #ifdef ZMODEM @@ -1315,7 +1411,7 @@ int key; zmodem_sendcmd = SaveStr(args[1]); } if (msgok) - Msg(0, "zmodem sendcmd: %s", zmodem_sendcmd); + OutputMsg(0, "zmodem sendcmd: %s", zmodem_sendcmd); break; } if (*args && !strcmp(*args, "recvcmd")) @@ -1326,7 +1422,7 @@ int key; zmodem_recvcmd = SaveStr(args[1]); } if (msgok) - Msg(0, "zmodem recvcmd: %s", zmodem_recvcmd); + OutputMsg(0, "zmodem recvcmd: %s", zmodem_recvcmd); break; } if (*args) @@ -1338,15 +1434,24 @@ int key; i = 1; if (i == 4) { - Msg(0, "usage: zmodem off|auto|catch|pass"); + OutputMsg(0, "usage: zmodem off|auto|catch|pass"); break; } zmodem_mode = i; } if (msgok) - Msg(0, "zmodem mode is %s", zmodes[zmodem_mode]); + OutputMsg(0, "zmodem mode is %s", zmodes[zmodem_mode]); break; #endif + case RC_UNBINDALL: + { + register unsigned int i; + + for (i = 0; i < sizeof(ktab)/sizeof(*ktab); i++) + ClearAction(&ktab[i]); + OutputMsg(0, "Unbound all keys." ); + break; + } case RC_ZOMBIE: { if (!(s = *args)) @@ -1356,7 +1461,7 @@ int key; } if (*argl == 0 || *argl > 2) { - Msg(0, "%s:zombie: one or two characters expected.", rc_name); + OutputMsg(0, "%s:zombie: one or two characters expected.", rc_name); break; } if (args[1]) @@ -1365,7 +1470,7 @@ int key; { ZombieKey_onerror = 1; } else { - Msg(0, "usage: zombie [keys [onerror]]"); + OutputMsg(0, "usage: zombie [keys [onerror]]"); break; } } else @@ -1383,18 +1488,20 @@ int key; { struct display *olddisplay = display; display = 0; /* no display will cause a broadcast */ - Msg(0, "%s: %s", s, *args); + OutputMsg(0, "%s: %s", s, *args); display = olddisplay; } break; case RC_AT: /* where this AT command comes from: */ + if (!user) + break; #ifdef MULTIUSER - s = SaveStr(D_user->u_name); + s = SaveStr(user->u_name); /* DO NOT RETURN FROM HERE WITHOUT RESETTING THIS: */ - EffectiveAclUser = D_user; + EffectiveAclUser = user; #else - s = SaveStr(D_usertty); + s = SaveStr(display ? D_usertty : user->u_name); #endif n = strlen(args[0]); if (n) n--; @@ -1411,14 +1518,22 @@ int key; struct acluser *u; if (!n) - u = D_user; + u = user; else - for (u = users; u; u = u->u_next) - { - debug3("strncmp('%s', '%s', %d)\n", *args, u->u_name, n); - if (!strncmp(*args, u->u_name, n)) + { + for (u = users; u; u = u->u_next) + { + debug3("strncmp('%s', '%s', %d)\n", *args, u->u_name, n); + if (!strncmp(*args, u->u_name, n)) + break; + } + if (!u) + { + args[0][n] = '\0'; + OutputMsg(0, "Did not find any user matching '%s'", args[0]); break; - } + } + } debug1("at all displays of user %s\n", u->u_name); for (display = displays; display; display = nd) { @@ -1432,7 +1547,7 @@ int key; debug1("AT display %s\n", D_usertty); DoCommand(args + 1, argl + 1); if (display) - Msg(0, "command from %s: %s %s", + OutputMsg(0, "command from %s: %s %s", s, args[1], args[2] ? args[2] : ""); display = NULL; flayer = 0; @@ -1461,7 +1576,7 @@ int key; debug1("AT display %s\n", D_usertty); DoCommand(args + 1, argl + 1); if (display) - Msg(0, "command from %s: %s %s", + OutputMsg(0, "command from %s: %s %s", s, args[1], args[2] ? args[2] : ""); display = NULL; fore = NULL; @@ -1477,7 +1592,7 @@ int key; struct win *nw; int ch; - n++; + n++; ch = args[0][n]; args[0][n] = '\0'; if (!*args[0] || (i = WindowByNumber(args[0])) < 0) @@ -1506,17 +1621,17 @@ int key; if (fore && fore->w_layer.l_cvlist) { display = fore->w_layer.l_cvlist->c_display; - Msg(0, "command from %s: %s %s", + OutputMsg(0, "command from %s: %s %s", s, args[1], args[2] ? args[2] : ""); } } display = NULL; fore = NULL; if (i < 0) - Msg(0, "%s: at '%s': no such window.\n", rc_name, args[0]); + OutputMsg(0, "%s: at '%s': no such window.\n", rc_name, args[0]); break; } - else if (i < MAXWIN && (fore = wtab[i])) + else if (i < maxwin && (fore = wtab[i])) { args[0][n] = ch; /* must restore string in case of bind */ debug2("AT window %d (%s)\n", fore->w_number, fore->w_title); @@ -1527,14 +1642,14 @@ int key; if (fore && fore->w_layer.l_cvlist) { display = fore->w_layer.l_cvlist->c_display; - Msg(0, "command from %s: %s %s", + OutputMsg(0, "command from %s: %s %s", s, args[1], args[2] ? args[2] : ""); } display = NULL; fore = NULL; } else - Msg(0, "%s: at [identifier][%%|*|#] command [args]", rc_name); + OutputMsg(0, "%s: at [identifier][%%|*|#] command [args]", rc_name); break; } } @@ -1553,7 +1668,7 @@ int key; i = FindEncoding(args[1]); if (i == -1) { - Msg(0, "%s: readreg: unknown encoding", rc_name); + OutputMsg(0, "%s: readreg: unknown encoding", rc_name); break; } args += 2; @@ -1572,7 +1687,7 @@ int key; } if (*argl != 1) { - Msg(0, "%s: copyreg: character, ^x, or (octal) \\032 expected.", rc_name); + OutputMsg(0, "%s: copyreg: character, ^x, or (octal) \\032 expected.", rc_name); break; } ch = args[0][0]; @@ -1583,7 +1698,7 @@ int key; { if (args[2]) { - Msg(0, "%s: readreg: too many arguments", rc_name); + OutputMsg(0, "%s: readreg: too many arguments", rc_name); break; } if ((s = ReadFile(args[1], &n))) @@ -1616,7 +1731,7 @@ int key; i = FindEncoding(args[1]); if (i == -1) { - Msg(0, "%s: register: unknown encoding", rc_name); + OutputMsg(0, "%s: register: unknown encoding", rc_name); break; } args += 2; @@ -1625,12 +1740,12 @@ int key; #endif if (argc != 2) { - Msg(0, "%s: register: illegal number of arguments.", rc_name); + OutputMsg(0, "%s: register: illegal number of arguments.", rc_name); break; } if (*argl != 1) { - Msg(0, "%s: register: character, ^x, or (octal) \\032 expected.", rc_name); + OutputMsg(0, "%s: register: character, ^x, or (octal) \\032 expected.", rc_name); break; } ch = args[0][0]; @@ -1670,7 +1785,7 @@ int key; } if (*argl != 1) { - Msg(0, "%s: process: character, ^x, or (octal) \\032 expected.", rc_name); + OutputMsg(0, "%s: process: character, ^x, or (octal) \\032 expected.", rc_name); break; } ch = args[0][0]; @@ -1688,7 +1803,7 @@ int key; { if (strcmp(s, "-k")) { - Msg(0, "%s: stuff: invalid option %s", rc_name, s); + OutputMsg(0, "%s: stuff: invalid option %s", rc_name, s); break; } s = args[1]; @@ -1697,7 +1812,7 @@ int key; break; if (i == T_OCAPS) { - Msg(0, "%s: stuff: unknown key '%s'", rc_name, s); + OutputMsg(0, "%s: stuff: unknown key '%s'", rc_name, s); break; } #ifdef MAPKEYS @@ -1719,7 +1834,7 @@ int key; ShowWindows(-1); break; case RC_VERSION: - Msg(0, "screen %s", version); + OutputMsg(0, "screen %s", version); break; case RC_TIME: if (*args) @@ -1727,7 +1842,7 @@ int key; timestring = SaveStr(*args); break; } - Msg(0, "%s", MakeWinMsg(timestring, fore, '%')); + OutputMsg(0, "%s", MakeWinMsg(timestring, fore, '%')); break; case RC_INFO: ShowInfo(); @@ -1742,7 +1857,7 @@ int key; { if ((ktabp = FindKtab(args[1], 0)) == 0) { - Msg(0, "Unknown command class '%s'", args[1]); + OutputMsg(0, "Unknown command class '%s'", args[1]); break; } } @@ -1801,15 +1916,15 @@ int key; break; } if (n < 0 || n >= (int)(sizeof(types)/sizeof(*types))) - Msg(0, "%s invalid, chose one of %s, %s or %s", *args, types[0], types[1], types[2]); + OutputMsg(0, "%s invalid, chose one of %s, %s or %s", *args, types[0], types[1], types[2]); else { breaktype = n; - Msg(0, "breaktype set to (%d) %s", n, types[n]); + OutputMsg(0, "breaktype set to (%d) %s", n, types[n]); } } else - Msg(0, "breaktype is (%d) %s", breaktype, types[breaktype]); + OutputMsg(0, "breaktype is (%d) %s", breaktype, types[breaktype]); } break; case RC_POW_BREAK: @@ -1843,7 +1958,7 @@ int key; { if (!flayer) { - Msg(0, "%s: %s: window required", rc_name, comms[nr].name); + OutputMsg(0, "%s: %s: window required", rc_name, comms[nr].name); break; } w = flayer->l_width; @@ -1853,7 +1968,7 @@ int key; { if (!display) { - Msg(0, "%s: %s: display required", rc_name, comms[nr].name); + OutputMsg(0, "%s: %s: display required", rc_name, comms[nr].name); break; } w = D_width; @@ -1861,7 +1976,7 @@ int key; } if (*args && args[0][0] == '-') { - Msg(0, "%s: %s: unknown option %s", rc_name, comms[nr].name, *args); + OutputMsg(0, "%s: %s: unknown option %s", rc_name, comms[nr].name, *args); break; } if (nr == RC_HEIGHT) @@ -1908,17 +2023,17 @@ int key; } if (*args && args[1] && args[2]) { - Msg(0, "%s: %s: too many arguments", rc_name, comms[nr].name); + OutputMsg(0, "%s: %s: too many arguments", rc_name, comms[nr].name); break; } if (w <= 0) { - Msg(0, "Illegal width"); + OutputMsg(0, "Illegal width"); break; } if (h <= 0) { - Msg(0, "Illegal height"); + OutputMsg(0, "Illegal height"); break; } if (what == 1) @@ -1944,15 +2059,23 @@ int key; break; } if (h == D_height) - Msg(0, "Your termcap does not specify how to change the terminal's width to %d.", w); + OutputMsg(0, "Your termcap does not specify how to change the terminal's width to %d.", w); else if (w == D_width) - Msg(0, "Your termcap does not specify how to change the terminal's height to %d.", h); + OutputMsg(0, "Your termcap does not specify how to change the terminal's height to %d.", h); else - Msg(0, "Your termcap does not specify how to change the terminal's resolution to %dx%d.", w, h); + OutputMsg(0, "Your termcap does not specify how to change the terminal's resolution to %dx%d.", w, h); } } break; case RC_TITLE: + if (queryflag >= 0) + { + if (fore) + OutputMsg(0, "%s", fore->w_title); + else + queryflag = -1; + break; + } if (*args == 0) InputAKA(); else @@ -1969,14 +2092,14 @@ int key; break; case RC_LASTMSG: if (D_status_lastmsg) - Msg(0, "%s", D_status_lastmsg); + OutputMsg(0, "%s", D_status_lastmsg); break; case RC_SCREEN: DoScreen("key", args); break; case RC_WRAP: if (ParseSwitch(act, &fore->w_wrap) == 0 && msgok) - Msg(0, "%cwrap", fore->w_wrap ? '+' : '-'); + OutputMsg(0, "%cwrap", fore->w_wrap ? '+' : '-'); break; case RC_FLOW: if (*args) @@ -2003,7 +2126,7 @@ int key; } SetFlow(fore->w_flow & FLOW_NOW); if (msgok) - Msg(0, "%cflow%s", (fore->w_flow & FLOW_NOW) ? '+' : '-', + OutputMsg(0, "%cflow%s", (fore->w_flow & FLOW_NOW) ? '+' : '-', (fore->w_flow & FLOW_AUTOFLAG) ? "(auto)" : ""); break; #ifdef MULTIUSER @@ -2037,7 +2160,7 @@ int key; if (!AclCheckPermWin(D_user, ACL_WRITE, fore)) fore->w_wlockuser = D_user; } - Msg(0, "writelock %s", (fore->w_wlock == WLOCK_AUTO) ? "auto" : + OutputMsg(0, "writelock %s", (fore->w_wlock == WLOCK_AUTO) ? "auto" : ((fore->w_wlock == WLOCK_OFF) ? "off" : "on")); break; #endif @@ -2072,7 +2195,7 @@ int key; #endif if (fore->w_monitor == MON_OFF) fore->w_monitor = MON_ON; - Msg(0, "Window %d (%s) is now being monitored for all activity.", fore->w_number, fore->w_title); + OutputMsg(0, "Window %d (%s) is now being monitored for all activity.", fore->w_number, fore->w_title); } else { @@ -2089,7 +2212,7 @@ int key; if (i < 0) #endif fore->w_monitor = MON_OFF; - Msg(0, "Window %d (%s) is no longer being monitored for activity.", fore->w_number, fore->w_title); + OutputMsg(0, "Window %d (%s) is no longer being monitored for activity.", fore->w_number, fore->w_title); } break; #ifdef MULTI @@ -2099,7 +2222,7 @@ int key; #endif case RC_WINDOWLIST: if (!*args) - display_wlist(0, WLIST_NUM, (struct win *)0); + display_windows(0, WLIST_NUM, (struct win *)0); else if (!strcmp(*args, "string")) { if (args[1]) @@ -2109,7 +2232,7 @@ int key; wliststr = SaveStr(args[1]); } if (msgok) - Msg(0, "windowlist string is '%s'", wliststr); + OutputMsg(0, "windowlist string is '%s'", wliststr); } else if (!strcmp(*args, "title")) { @@ -2120,7 +2243,7 @@ int key; wlisttit = SaveStr(args[1]); } if (msgok) - Msg(0, "windowlist title is '%s'", wlisttit); + OutputMsg(0, "windowlist title is '%s'", wlisttit); } else { @@ -2137,11 +2260,11 @@ int key; flag |= WLIST_NESTED; else { - Msg(0, "usage: windowlist [-b] [-g] [-m] [string [string] | title [title]]"); + OutputMsg(0, "usage: windowlist [-b] [-g] [-m] [string [string] | title [title]]"); break; } if (i == argc) - display_wlist(blank, flag, (struct win *)0); + display_windows(blank, flag, (struct win *)0); } break; case RC_HELP: @@ -2150,7 +2273,7 @@ int key; struct action *ktabp; if ((ktabp = FindKtab(args[1], 0)) == 0) { - Msg(0, "Unknown command class '%s'", args[1]); + OutputMsg(0, "Unknown command class '%s'", args[1]); break; } display_help(args[1], ktabp); @@ -2165,10 +2288,11 @@ int key; case RC_COPY: if (flayer->l_layfn != &WinLf) { - Msg(0, "Must be on a window layer"); + OutputMsg(0, "Must be on a window layer"); break; } MarkRoutine(); + WindowChanged(fore, 'P'); break; case RC_HISTORY: { @@ -2177,7 +2301,7 @@ int key; if (flayer->l_layfn != &WinLf) { - Msg(0, "Must be on a window layer"); + OutputMsg(0, "Must be on a window layer"); break; } if (GetHistory() == 0) @@ -2212,7 +2336,7 @@ int key; */ if (args[1] && argl[1] != 1) { - Msg(0, "%s: paste destination: character, ^x, or (octal) \\032 expected.", + OutputMsg(0, "%s: paste destination: character, ^x, or (octal) \\032 expected.", rc_name); break; } @@ -2251,7 +2375,7 @@ int key; } if (l == 0) { - Msg(0, "empty buffer"); + OutputMsg(0, "empty buffer"); break; } /* @@ -2272,7 +2396,7 @@ int key; */ if ((dbuf = (char *)malloc(l)) == 0) { - Msg(0, strnomem); + OutputMsg(0, "%s", strnomem); break; } l = 0; @@ -2334,7 +2458,7 @@ int key; case RC_WRITEBUF: if (!user->u_plop.buf) { - Msg(0, "empty buffer"); + OutputMsg(0, "empty buffer"); break; } #ifdef ENCODINGS @@ -2350,7 +2474,7 @@ int key; enc = FindEncoding(args[1]); if (enc == -1) { - Msg(0, "%s: writebuf: unknown encoding", rc_name); + OutputMsg(0, "%s: writebuf: unknown encoding", rc_name); break; } if (enc != oldplop.enc) @@ -2359,7 +2483,7 @@ int key; newbuf = malloc(l + 1); if (!newbuf) { - Msg(0, strnomem); + OutputMsg(0, "%s", strnomem); break; } user->u_plop.len = RecodeBuf((unsigned char *)oldplop.buf, oldplop.len, oldplop.enc, enc, (unsigned char *)newbuf); @@ -2370,7 +2494,7 @@ int key; } #endif if (args[0] && args[1]) - Msg(0, "%s: writebuf: too many arguments", rc_name); + OutputMsg(0, "%s: writebuf: too many arguments", rc_name); else WriteFile(user, args[0], DUMP_EXCHANGE); #ifdef ENCODINGS @@ -2388,7 +2512,7 @@ int key; i = FindEncoding(args[1]); if (i == -1) { - Msg(0, "%s: readbuf: unknown encoding", rc_name); + OutputMsg(0, "%s: readbuf: unknown encoding", rc_name); break; } args += 2; @@ -2396,7 +2520,7 @@ int key; #endif if (args[0] && args[1]) { - Msg(0, "%s: readbuf: too many arguments", rc_name); + OutputMsg(0, "%s: readbuf: too many arguments", rc_name); break; } if ((s = ReadFile(args[0] ? args[0] : BufferFile, &n))) @@ -2416,7 +2540,7 @@ int key; case RC_IGNORECASE: (void)ParseSwitch(act, &search_ic); if (msgok) - Msg(0, "Will %signore case in searches", search_ic ? "" : "not "); + OutputMsg(0, "Will %signore case in searches", search_ic ? "" : "not "); break; #endif /* COPY_PASTE */ case RC_ESCAPE: @@ -2426,7 +2550,7 @@ int key; SetEscape(user, (int)(unsigned char)args[0][0], (int)(unsigned char)args[0][1]); else { - Msg(0, "%s: two characters required after escape.", rc_name); + OutputMsg(0, "%s: two characters required after escape.", rc_name); break; } /* Change defescape if master user. This is because we only @@ -2442,7 +2566,7 @@ int key; SetEscape(NULL, (int)(unsigned char)args[0][0], (int)(unsigned char)args[0][1]); else { - Msg(0, "%s: two characters required after defescape.", rc_name); + OutputMsg(0, "%s: two characters required after defescape.", rc_name); break; } #ifdef MAPKEYS @@ -2452,7 +2576,7 @@ int key; case RC_CHDIR: s = *args ? *args : home; if (chdir(s) == -1) - Msg(errno, "%s", s); + OutputMsg(errno, "%s", s); break; case RC_SHELL: case RC_DEFSHELL: @@ -2463,7 +2587,7 @@ int key; if (*args) (void)ParseSaveStr(act, &hardcopydir); if (msgok) - Msg(0, "hardcopydir is %s\n", hardcopydir && *hardcopydir ? hardcopydir : "<cwd>"); + OutputMsg(0, "hardcopydir is %s\n", hardcopydir && *hardcopydir ? hardcopydir : "<cwd>"); break; case RC_LOGFILE: if (*args) @@ -2472,19 +2596,19 @@ int key; { log_flush = atoi(args[1]); if (msgok) - Msg(0, "log flush timeout set to %ds\n", log_flush); + OutputMsg(0, "log flush timeout set to %ds\n", log_flush); break; } if (ParseSaveStr(act, &screenlogfile) || !msgok) break; } - Msg(0, "logfile is '%s'", screenlogfile); + OutputMsg(0, "logfile is '%s'", screenlogfile); break; case RC_LOGTSTAMP: if (!*args || !strcmp(*args, "on") || !strcmp(*args, "off")) { if (ParseSwitch(act, &logtstamp_on) == 0 && msgok) - Msg(0, "timestamps turned %s", logtstamp_on ? "on" : "off"); + OutputMsg(0, "timestamps turned %s", logtstamp_on ? "on" : "off"); } else if (!strcmp(*args, "string")) { @@ -2495,7 +2619,7 @@ int key; logtstamp_string = SaveStr(args[1]); } if (msgok) - Msg(0, "logfile timestamp is '%s'", logtstamp_string); + OutputMsg(0, "logfile timestamp is '%s'", logtstamp_string); } else if (!strcmp(*args, "after")) { @@ -2505,10 +2629,10 @@ int key; if (!msgok) break; } - Msg(0, "timestamp printed after %ds\n", logtstamp_after); + OutputMsg(0, "timestamp printed after %ds\n", logtstamp_after); } else - Msg(0, "usage: logtstamp [after [n]|string [str]|on|off]"); + OutputMsg(0, "usage: logtstamp [after [n]|string [str]|on|off]"); break; case RC_SHELLTITLE: (void)ParseSaveStr(act, &nwin_default.aka); @@ -2517,7 +2641,7 @@ int key; case RC_TERMCAPINFO: case RC_TERMINFO: if (!rc_name || !*rc_name) - Msg(0, "Sorry, too late now. Place that in your .screenrc file."); + OutputMsg(0, "Sorry, too late now. Place that in your .screenrc file."); break; case RC_SLEEP: break; /* Already handled */ @@ -2527,7 +2651,7 @@ int key; break; if (strlen(s) >= 20) { - Msg(0, "%s: term: argument too long ( < 20)", rc_name); + OutputMsg(0, "%s: term: argument too long ( < 20)", rc_name); free(s); break; } @@ -2559,9 +2683,12 @@ int key; s = MakeWinMsg(s, fore, '%'); } if (s) - Msg(0, "%s", s); + OutputMsg(0, "%s", s); else - Msg(0, "%s: 'echo [-n] [-p] \"string\"' expected.", rc_name); + { + OutputMsg(0, "%s: 'echo [-n] [-p] \"string\"' expected.", rc_name); + queryflag = -1; + } break; case RC_BELL: case RC_BELL_MSG: @@ -2569,7 +2696,7 @@ int key; { char buf[256]; AddXChars(buf, sizeof(buf), BellString); - Msg(0, "bell_msg is '%s'", buf); + OutputMsg(0, "bell_msg is '%s'", buf); break; } (void)ParseSaveStr(act, &BellString); @@ -2581,7 +2708,7 @@ int key; else if (ParseSaveStr(act, &BufferFile)) break; if (msgok) - Msg(0, "Bufferfile is now '%s'", BufferFile); + OutputMsg(0, "Bufferfile is now '%s'", BufferFile); break; #endif case RC_ACTIVITY: @@ -2593,7 +2720,7 @@ int key; { char buf[256]; AddXChars(buf, sizeof(buf), PowDetachString); - Msg(0, "pow_detach_msg is '%s'", buf); + OutputMsg(0, "pow_detach_msg is '%s'", buf); break; } (void)ParseSaveStr(act, &PowDetachString); @@ -2668,13 +2795,29 @@ int key; if (ParseOnOff(act, &n) == 0) nwin_default.monitor = (n == 0) ? MON_OFF : MON_ON; break; + case RC_DEFMOUSETRACK: + if (ParseOnOff(act, &n) == 0) + defmousetrack = (n == 0) ? 0 : 1000; + break; + case RC_MOUSETRACK: + if (!args[0]) + { + OutputMsg(0, "Mouse tracking for this display is turned %s", D_mousetrack ? "on" : "off"); + } + else if (ParseOnOff(act, &n) == 0) + { + D_mousetrack = n == 0 ? 0 : 1000; + if (D_fore) + MouseMode(D_fore->w_mouse); + } + break; case RC_DEFSILENCE: if (ParseOnOff(act, &n) == 0) nwin_default.silence = (n == 0) ? SILENCE_OFF : SILENCE_ON; break; case RC_VERBOSE: if (!*args) - Msg(0, "W%s echo command when creating windows.", + OutputMsg(0, "W%s echo command when creating windows.", VerboseCreate ? "ill" : "on't"); else if (ParseOnOff(act, &n) == 0) VerboseCreate = n; @@ -2682,7 +2825,7 @@ int key; case RC_HARDSTATUS: if (display) { - Msg(0, "%s", ""); /* wait till mintime (keep gcc quiet) */ + OutputMsg(0, "%s", ""); /* wait till mintime (keep gcc quiet) */ RemoveStatus(); } if (args[0] && strcmp(args[0], "on") && strcmp(args[0], "off")) @@ -2705,13 +2848,13 @@ int key; { char buf[256]; AddXChars(buf, sizeof(buf), hstatusstring); - Msg(0, "hardstatus string is '%s'", buf); + OutputMsg(0, "hardstatus string is '%s'", buf); break; } } else { - Msg(0, "%s: usage: hardstatus [always]lastline|ignore|message|string [string]", rc_name); + OutputMsg(0, "%s: usage: hardstatus [always]lastline|ignore|message|string [string]", rc_name); break; } if (new_use != -1) @@ -2744,7 +2887,7 @@ int key; } (void)ParseSwitch(act, &use_hardstatus); if (msgok) - Msg(0, "messages displayed on %s", use_hardstatus ? "hardstatus line" : "window"); + OutputMsg(0, "messages displayed on %s", use_hardstatus ? "hardstatus line" : "window"); break; case RC_CAPTION: if (strcmp(args[0], "always") == 0 || strcmp(args[0], "splitonly") == 0 || strcmp(args[0], "never") == 0) @@ -2779,13 +2922,13 @@ int key; { char buf[256]; AddXChars(buf, sizeof(buf), captionstring); - Msg(0, "caption string is '%s'", buf); + OutputMsg(0, "caption string is '%s'", buf); break; } } else { - Msg(0, "%s: usage: caption always|splitonly|string <string>", rc_name); + OutputMsg(0, "%s: usage: caption always|splitonly|string <string>", rc_name); break; } if (!args[1]) @@ -2802,12 +2945,12 @@ int key; if (TtyGrabConsole(fore->w_ptyfd, n, rc_name)) break; if (n == 0) - Msg(0, "%s: releasing console %s", rc_name, HostName); + OutputMsg(0, "%s: releasing console %s", rc_name, HostName); else if (console_window) - Msg(0, "%s: stealing console %s from window %d (%s)", rc_name, + OutputMsg(0, "%s: stealing console %s from window %d (%s)", rc_name, HostName, console_window->w_number, console_window->w_title); else - Msg(0, "%s: grabbing console %s", rc_name, HostName); + OutputMsg(0, "%s: grabbing console %s", rc_name, HostName); console_window = n ? fore : 0; break; case RC_ALLPARTIAL: @@ -2816,7 +2959,7 @@ int key; if (!all_norefresh && fore) Activate(-1); if (msgok) - Msg(0, all_norefresh ? "No refresh on window change!\n" : + OutputMsg(0, all_norefresh ? "No refresh on window change!\n" : "Window specific refresh\n"); break; case RC_PARTIAL: @@ -2827,21 +2970,21 @@ int key; if (ParseSwitch(act, &visual_bell) || !msgok) break; if (visual_bell == 0) - Msg(0, "switched to audible bell."); + OutputMsg(0, "switched to audible bell."); else - Msg(0, "switched to visual bell."); + OutputMsg(0, "switched to visual bell."); break; case RC_VBELLWAIT: if (ParseNum1000(act, &VBellWait) == 0 && msgok) - Msg(0, "vbellwait set to %.10g seconds", VBellWait/1000.); + OutputMsg(0, "vbellwait set to %.10g seconds", VBellWait/1000.); break; case RC_MSGWAIT: if (ParseNum1000(act, &MsgWait) == 0 && msgok) - Msg(0, "msgwait set to %.10g seconds", MsgWait/1000.); + OutputMsg(0, "msgwait set to %.10g seconds", MsgWait/1000.); break; case RC_MSGMINWAIT: if (ParseNum1000(act, &MsgMinWait) == 0 && msgok) - Msg(0, "msgminwait set to %.10g seconds", MsgMinWait/1000.); + OutputMsg(0, "msgminwait set to %.10g seconds", MsgMinWait/1000.); break; case RC_SILENCEWAIT: if (ParseNum(act, &SilenceWait)) @@ -2851,11 +2994,11 @@ int key; for (p = windows; p; p = p->w_next) p->w_silencewait = SilenceWait; if (msgok) - Msg(0, "silencewait set to %d seconds", SilenceWait); + OutputMsg(0, "silencewait set to %d seconds", SilenceWait); break; case RC_NUMBER: if (*args == 0) - Msg(0, "This is window %d (%s).\n", fore->w_number, fore->w_title); + OutputMsg(0, queryflag >= 0 ? "%d (%s)" : "This is window %d (%s).", fore->w_number, fore->w_title); else { int old = fore->w_number; @@ -2875,41 +3018,12 @@ int key; n += old; else if (rel < 0) n = old - n; - if (n < 0 || n >= maxwin) + if (!WindowChangeNumber(fore, n)) { - Msg(0, "Given window position is invalid."); + /* Window number could not be changed. */ + queryflag = -1; return; } - p = wtab[n]; - wtab[n] = fore; - fore->w_number = n; - wtab[old] = p; - if (p) - p->w_number = old; -#ifdef MULTIUSER - /* exchange the acls for these windows. */ - AclWinSwap(old, n); -#endif -#ifdef UTMPOK - /* exchange the utmp-slots for these windows */ - if ((fore->w_slot != (slot_t) -1) && (fore->w_slot != (slot_t) 0)) - { - RemoveUtmp(fore); - SetUtmp(fore); - } - if (p && (p->w_slot != (slot_t) -1) && (p->w_slot != (slot_t) 0)) - { - /* XXX: first display wins? */ - display = fore->w_layer.l_cvlist ? fore->w_layer.l_cvlist->c_display : 0; - RemoveUtmp(p); - SetUtmp(p); - } -#endif - - WindowChanged(fore, 'n'); - WindowChanged((struct win *)0, 'w'); - WindowChanged((struct win *)0, 'W'); - WindowChanged((struct win *)0, 0); } break; case RC_SILENCE: @@ -2939,7 +3053,7 @@ int key; if (!msgok) break; - Msg(0, "The window is now being monitored for %d sec. silence.", fore->w_silencewait); + OutputMsg(0, "The window is now being monitored for %d sec. silence.", fore->w_silencewait); } else { @@ -2961,7 +3075,7 @@ int key; } if (!msgok) break; - Msg(0, "The window is no longer being monitored for silence."); + OutputMsg(0, "The window is no longer being monitored for silence."); } break; #ifdef COPY_PASTE @@ -2971,18 +3085,18 @@ int key; case RC_SCROLLBACK: if (flayer->l_layfn == &MarkLf) { - Msg(0, "Cannot resize scrollback buffer in copy/scrollback mode."); + OutputMsg(0, "Cannot resize scrollback buffer in copy/scrollback mode."); break; } (void)ParseNum(act, &n); ChangeWindowSize(fore, fore->w_width, fore->w_height, n); if (msgok) - Msg(0, "scrollback set to %d", fore->w_histheight); + OutputMsg(0, "scrollback set to %d", fore->w_histheight); break; #endif case RC_SESSIONNAME: if (*args == 0) - Msg(0, "This session is named '%s'\n", SockName); + OutputMsg(0, "This session is named '%s'\n", SockName); else { char buf[MAXPATHLEN]; @@ -2992,7 +3106,7 @@ int key; break; if (!*s || strlen(s) + (SockName - SockPath) > MAXPATHLEN - 13 || index(s, '/')) { - Msg(0, "%s: bad session name '%s'\n", rc_name, s); + OutputMsg(0, "%s: bad session name '%s'\n", rc_name, s); free(s); break; } @@ -3001,12 +3115,12 @@ int key; free(s); if ((access(buf, F_OK) == 0) || (errno != ENOENT)) { - Msg(0, "%s: inappropriate path: '%s'.", rc_name, buf); + OutputMsg(0, "%s: inappropriate path: '%s'.", rc_name, buf); break; } if (rename(SockPath, buf)) { - Msg(errno, "%s: failed to rename(%s, %s)", rc_name, SockPath, buf); + OutputMsg(errno, "%s: failed to rename(%s, %s)", rc_name, SockPath, buf); break; } debug2("rename(%s, %s) done\n", SockPath, buf); @@ -3037,12 +3151,12 @@ int key; break; case RC_SLOWPASTE: if (*args == 0) - Msg(0, fore->w_slowpaste ? + OutputMsg(0, fore->w_slowpaste ? "Slowpaste in window %d is %d milliseconds." : "Slowpaste in window %d is unset.", fore->w_number, fore->w_slowpaste); else if (ParseNum(act, &fore->w_slowpaste) == 0 && msgok) - Msg(0, fore->w_slowpaste ? + OutputMsg(0, fore->w_slowpaste ? "Slowpaste in window %d set to %d milliseconds." : "Slowpaste in window %d now unset.", fore->w_number, fore->w_slowpaste); @@ -3050,7 +3164,7 @@ int key; case RC_MARKKEYS: if (CompileKeys(*args, *argl, mark_key_tab)) { - Msg(0, "%s: markkeys: syntax error.", rc_name); + OutputMsg(0, "%s: markkeys: syntax error.", rc_name); break; } debug1("markkeys %s\n", *args); @@ -3058,7 +3172,7 @@ int key; # ifdef FONT case RC_PASTEFONT: if (ParseSwitch(act, &pastefont) == 0 && msgok) - Msg(0, "Will %spaste font settings", pastefont ? "" : "not "); + OutputMsg(0, "Will %spaste font settings", pastefont ? "" : "not "); break; # endif case RC_CRLF: @@ -3066,7 +3180,7 @@ int key; break; case RC_COMPACTHIST: if (ParseSwitch(act, &compacthist) == 0 && msgok) - Msg(0, "%scompacting history lines", compacthist ? "" : "not "); + OutputMsg(0, "%scompacting history lines", compacthist ? "" : "not "); break; #endif #ifdef NETHACK @@ -3082,7 +3196,7 @@ int key; { char buf[256]; AddXChars(buf, sizeof(buf), VisualBellString); - Msg(0, "vbell_msg is '%s'", buf); + OutputMsg(0, "vbell_msg is '%s'", buf); break; } (void)ParseSaveStr(act, &VisualBellString); @@ -3093,12 +3207,12 @@ int key; break; if (n < 0 || n > 0777) { - Msg(0, "%s: mode: Invalid tty mode %o", rc_name, n); + OutputMsg(0, "%s: mode: Invalid tty mode %o", rc_name, n); break; } TtyMode = n; if (msgok) - Msg(0, "Ttymode set to %03o", TtyMode); + OutputMsg(0, "Ttymode set to %03o", TtyMode); break; case RC_AUTODETACH: (void)ParseOnOff(act, &auto_detach); @@ -3116,7 +3230,7 @@ int key; if (!strcmp(user->u_password, "none")) { if (n) - Msg(0, "Password checking disabled"); + OutputMsg(0, "Password checking disabled"); free(user->u_password); user->u_password = NullStr; } @@ -3125,7 +3239,7 @@ int key; { if (!fore) { - Msg(0, "%s: password: window required", rc_name); + OutputMsg(0, "%s: password: window required", rc_name); break; } Input("New screen password:", 100, INP_NOECHO, pass1, display ? (char *)D_user : (char *)users, 0); @@ -3166,7 +3280,7 @@ int key; break; if (n == KMAP_KEYS) { - Msg(0, "%s: bind: unknown key '%s'", rc_name, *args); + OutputMsg(0, "%s: bind: unknown key '%s'", rc_name, *args); break; } n += 256; @@ -3175,7 +3289,7 @@ int key; #endif if (*argl != 1) { - Msg(0, "%s: bind: character, ^x, or (octal) \\032 expected.", rc_name); + OutputMsg(0, "%s: bind: character, ^x, or (octal) \\032 expected.", rc_name); break; } else @@ -3185,7 +3299,7 @@ int key; { if ((i = FindCommnr(args[1])) == RC_ILLEGAL) { - Msg(0, "%s: bind: unknown command '%s'", rc_name, args[1]); + OutputMsg(0, "%s: bind: unknown command '%s'", rc_name, args[1]); break; } if (CheckArgNum(i, args + 2) < 0) @@ -3226,13 +3340,13 @@ int key; } else { - Msg(0, "%s: bindkey: invalid option %s", rc_name, *args); + OutputMsg(0, "%s: bindkey: invalid option %s", rc_name, *args); return; } } if (df && mf) { - Msg(0, "%s: bindkey: -d does not work with -m", rc_name); + OutputMsg(0, "%s: bindkey: -d does not work with -m", rc_name); break; } if (*args == 0) @@ -3249,12 +3363,12 @@ int key; { if (af) { - Msg(0, "%s: bindkey: -a only works with -k", rc_name); + OutputMsg(0, "%s: bindkey: -a only works with -k", rc_name); break; } if (*argl == 0) { - Msg(0, "%s: bindkey: empty string makes no sense", rc_name); + OutputMsg(0, "%s: bindkey: empty string makes no sense", rc_name); break; } for (i = 0, kme = kmap_exts; i < kmap_extn; i++, kme++) @@ -3270,7 +3384,7 @@ int key; { if (!args[1]) { - Msg(0, "%s: bindkey: keybinding not found", rc_name); + OutputMsg(0, "%s: bindkey: keybinding not found", rc_name); break; } kmap_extn += 8; @@ -3282,6 +3396,7 @@ int key; kme->str = 0; kme->dm.nr = kme->mm.nr = kme->um.nr = RC_ILLEGAL; kme->dm.args = kme->mm.args = kme->um.args = noargs; + kme->dm.argl = kme->mm.argl = kme->um.argl = 0; } i -= 8; kme -= 8; @@ -3302,7 +3417,7 @@ int key; break; if (i == T_OCAPS) { - Msg(0, "%s: bindkey: unknown key '%s'", rc_name, *args); + OutputMsg(0, "%s: bindkey: unknown key '%s'", rc_name, *args); break; } if (af && i >= T_CURSOR && i < T_OCAPS) @@ -3315,7 +3430,7 @@ int key; { if ((newnr = FindCommnr(args[1])) == RC_ILLEGAL) { - Msg(0, "%s: bindkey: unknown command '%s'", rc_name, args[1]); + OutputMsg(0, "%s: bindkey: unknown command '%s'", rc_name, args[1]); break; } if (CheckArgNum(newnr, args + 2) < 0) @@ -3353,13 +3468,13 @@ int key; break; if (n < 0) { - Msg(0, "%s: maptimeout: illegal time %d", rc_name, n); + OutputMsg(0, "%s: maptimeout: illegal time %d", rc_name, n); break; } maptimeout = n; } if (*args == 0 || msgok) - Msg(0, "maptimeout is %dms", maptimeout); + OutputMsg(0, "maptimeout is %dms", maptimeout); break; case RC_MAPNOTNEXT: D_dontmap = 1; @@ -3379,7 +3494,7 @@ int key; if (UserDel(args[0], NULL)) break; if (msgok) - Msg(0, "%s removed from acl database", args[0]); + OutputMsg(0, "%s removed from acl database", args[0]); break; case RC_ACLGRP: /* @@ -3394,7 +3509,7 @@ int key; if (AclLinkUser(args[0], args[1])) break; if (msgok) - Msg(0, "User %s joined acl-group %s", args[0], args[1]); + OutputMsg(0, "User %s joined acl-group %s", args[0], args[1]); } else /* remove all groups from user */ { @@ -3420,7 +3535,7 @@ int key; if (!(u = *FindUserPtr(args[0]))) { if (msgok) - Msg(0, "User %s does not exist.", args[0]); + OutputMsg(0, "User %s does not exist.", args[0]); break; } g = u->u_group; @@ -3435,7 +3550,7 @@ int key; } if (ngroups) *(--p) = '\0'; - Msg(0, "%s's group%s: %s.", args[0], (ngroups == 1) ? "" : "s", + OutputMsg(0, "%s's group%s: %s.", args[0], (ngroups == 1) ? "" : "s", (ngroups == 0) ? "none" : buf); } break; @@ -3446,7 +3561,7 @@ int key; char *err = 0; if (AclUmask(display ? D_user : users, s, &err)) - Msg(0, "umask: %s\n", err); + OutputMsg(0, "umask: %s\n", err); } break; case RC_MULTIUSER: @@ -3455,7 +3570,7 @@ int key; multi = n ? "" : 0; chsock(); if (msgok) - Msg(0, "Multiuser mode %s", multi ? "enabled" : "disabled"); + OutputMsg(0, "Multiuser mode %s", multi ? "enabled" : "disabled"); break; #endif /* MULTIUSER */ #ifdef PSEUDOS @@ -3476,11 +3591,11 @@ int key; else break; if (msgok && i == -1) - Msg(0, "display set to blocking mode"); + OutputMsg(0, "display set to blocking mode"); else if (msgok && i == 0) - Msg(0, "display set to nonblocking mode, no timeout"); + OutputMsg(0, "display set to nonblocking mode, no timeout"); else if (msgok) - Msg(0, "display set to nonblocking mode, %.10gs timeout", i/1000.); + OutputMsg(0, "display set to nonblocking mode, %.10gs timeout", i/1000.); D_nonblock = i; if (D_nonblock <= 0) evdeq(&D_blockedev); @@ -3509,7 +3624,7 @@ int key; fore->w_gr = 0; #endif if (ParseSwitch(act, &fore->w_gr) == 0 && msgok) - Msg(0, "Will %suse GR", fore->w_gr ? "" : "not "); + OutputMsg(0, "Will %suse GR", fore->w_gr ? "" : "not "); #ifdef ENCODINGS if (fore->w_gr == 0 && fore->w_FontE) fore->w_gr = 2; @@ -3517,12 +3632,12 @@ int key; break; case RC_C1: if (ParseSwitch(act, &fore->w_c1) == 0 && msgok) - Msg(0, "Will %suse C1", fore->w_c1 ? "" : "not "); + OutputMsg(0, "Will %suse C1", fore->w_c1 ? "" : "not "); break; #ifdef COLOR case RC_BCE: if (ParseSwitch(act, &fore->w_bce) == 0 && msgok) - Msg(0, "Will %serase with background color", fore->w_bce ? "" : "not "); + OutputMsg(0, "Will %serase with background color", fore->w_bce ? "" : "not "); break; #endif #ifdef ENCODINGS @@ -3532,7 +3647,7 @@ int key; if (*args && !strcmp(args[0], "-d")) { if (!args[1]) - Msg(0, "encodings directory is %s", screenencodings ? screenencodings : "<unset>"); + OutputMsg(0, "encodings directory is %s", screenencodings ? screenencodings : "<unset>"); else { free(screenencodings); @@ -3543,18 +3658,18 @@ int key; if (*args && !strcmp(args[0], "-l")) { if (!args[1]) - Msg(0, "encoding: -l: argument required"); + OutputMsg(0, "encoding: -l: argument required"); else if (LoadFontTranslation(-1, args[1])) - Msg(0, "encoding: could not load utf8 encoding file"); + OutputMsg(0, "encoding: could not load utf8 encoding file"); else if (msgok) - Msg(0, "encoding: utf8 encoding file loaded"); + OutputMsg(0, "encoding: utf8 encoding file loaded"); break; } #else if (*args && (!strcmp(args[0], "-l") || !strcmp(args[0], "-d"))) { if (msgok) - Msg(0, "encoding: screen is not compiled for UTF-8."); + OutputMsg(0, "encoding: screen is not compiled for UTF-8."); break; } #endif @@ -3567,7 +3682,7 @@ int key; n = FindEncoding(args[i]); if (n == -1) { - Msg(0, "encoding: unknown encoding '%s'", args[i]); + OutputMsg(0, "encoding: unknown encoding '%s'", args[i]); break; } if (i == 0 && fore) @@ -3584,7 +3699,7 @@ int key; n = FindEncoding(*args); if (n == -1) { - Msg(0, "defencoding: unknown encoding '%s'", *args); + OutputMsg(0, "defencoding: unknown encoding '%s'", *args); break; } nwin_default.encoding = n; @@ -3598,7 +3713,7 @@ int key; { nwin_default.encoding = n ? UTF8 : 0; if (msgok) - Msg(0, "Will %suse UTF-8 encoding for new windows", n ? "" : "not "); + OutputMsg(0, "Will %suse UTF-8 encoding for new windows", n ? "" : "not "); } break; case RC_UTF8: @@ -3614,14 +3729,14 @@ int key; n = 1; else { - Msg(0, "utf8: illegal argument (%s)", args[i]); + OutputMsg(0, "utf8: illegal argument (%s)", args[i]); break; } if (i == 0) { WinSwitchEncoding(fore, n ? UTF8 : 0); if (msgok) - Msg(0, "Will %suse UTF-8 encoding", n ? "" : "not "); + OutputMsg(0, "Will %suse UTF-8 encoding", n ? "" : "not "); } else if (display) D_encoding = n ? UTF8 : 0; @@ -3643,14 +3758,53 @@ int key; if (*args == 0 || msgok) { if (printcmd) - Msg(0, "using '%s' as print command", printcmd); + OutputMsg(0, "using '%s' as print command", printcmd); else - Msg(0, "using termcap entries for printing"); + OutputMsg(0, "using termcap entries for printing"); break; } break; case RC_DIGRAPH: + if (argl && argl[0] > 0 && argl[1] > 0) + { + if (argl[0] != 2) + { + OutputMsg(0, "Two characters expected to define a digraph"); + break; + } + i = digraph_find(args[0]); + digraphs[i].d[0] = args[0][0]; + digraphs[i].d[1] = args[0][1]; + if (!parse_input_int(args[1], argl[1], &digraphs[i].value)) + { + if (!(digraphs[i].value = atoi(args[1]))) + { + if (!args[1][1]) + digraphs[i].value = (int)args[1][0]; +#ifdef UTF8 + else + { + int t; + unsigned char *s = args[1]; + digraphs[i].value = 0; + while (*s) + { + t = FromUtf8(*s++, &digraphs[i].value); + if (t == -1) + continue; + if (t == -2) + digraphs[i].value = 0; + else + digraphs[i].value = t; + break; + } + } +#endif + } + } + break; + } Input("Enter digraph: ", 10, INP_EVERY, digraph_fn, NULL, 0); if (*args && **args) { @@ -3667,7 +3821,7 @@ int key; *buf = 0; if (nwin_default.hstatus) AddXChars(buf, sizeof(buf), nwin_default.hstatus); - Msg(0, "default hstatus is '%s'", buf); + OutputMsg(0, "default hstatus is '%s'", buf); break; } (void)ParseSaveStr(act, &nwin_default.hstatus); @@ -3696,20 +3850,20 @@ int key; *buf = 0; if (nwin_default.charset) AddXChars(buf, sizeof(buf), nwin_default.charset); - Msg(0, "default charset is '%s'", buf); + OutputMsg(0, "default charset is '%s'", buf); break; } n = strlen(*args); if (n == 0 || n > 6) { - Msg(0, "%s: %s: string has illegal size.", rc_name, comms[nr].name); + OutputMsg(0, "%s: %s: string has illegal size.", rc_name, comms[nr].name); break; } if (n > 4 && ( ((args[0][4] < '0' || args[0][4] > '3') && args[0][4] != '.') || ((args[0][5] < '0' || args[0][5] > '3') && args[0][5] && args[0][5] != '.'))) { - Msg(0, "%s: %s: illegal mapping number.", rc_name, comms[nr].name); + OutputMsg(0, "%s: %s: illegal mapping number.", rc_name, comms[nr].name); break; } if (nr == RC_CHARSET) @@ -3747,7 +3901,7 @@ int key; } if (*s || i < 0 || i >= 8) { - Msg(0, "%s: attrcolor: unknown attribute '%s'.", rc_name, args[0]); + OutputMsg(0, "%s: attrcolor: unknown attribute '%s'.", rc_name, args[0]); break; } n = 0; @@ -3763,6 +3917,40 @@ int key; nattr2color = n; break; #endif + case RC_RENDITION: + i = -1; + if (strcmp(args[0], "bell") == 0) + { + i = REND_BELL; + } + else if (strcmp(args[0], "monitor") == 0) + { + i = REND_MONITOR; + } + else if (strcmp(args[0], "silence") == 0) + { + i = REND_SILENCE; + } + else if (strcmp(args[0], "so") != 0) + { + OutputMsg(0, "Invalid option '%s' for rendition", args[0]); + break; + } + + ++args; + ++argl; + + if (i != -1) + { + renditions[i] = ParseAttrColor(args[0], args[1], 1); + WindowChanged((struct win *)0, 'w'); + WindowChanged((struct win *)0, 'W'); + WindowChanged((struct win *)0, 0); + break; + } + + /* We are here, means we want to set the sorendition. */ + /* FALLTHROUGH*/ case RC_SORENDITION: i = 0; if (*args) @@ -3771,13 +3959,14 @@ int key; if (i == -1) break; ApplyAttrColor(i, &mchar_so); + WindowChanged((struct win *)0, 0); debug2("--> %x %x\n", mchar_so.attr, mchar_so.color); } if (msgok) #ifdef COLOR - Msg(0, "Standout attributes 0x%02x color 0x%02x", (unsigned char)mchar_so.attr, 0x99 ^ (unsigned char)mchar_so.color); + OutputMsg(0, "Standout attributes 0x%02x color 0x%02x", (unsigned char)mchar_so.attr, 0x99 ^ (unsigned char)mchar_so.color); #else - Msg(0, "Standout attributes 0x%02x ", (unsigned char)mchar_so.attr); + OutputMsg(0, "Standout attributes 0x%02x ", (unsigned char)mchar_so.attr); #endif break; @@ -3790,7 +3979,7 @@ int key; s = NULL; if (!*args) { - Msg(0, "%s:%s screen login", HostName, SockPath); + OutputMsg(0, "%s:%s screen login", HostName, SockPath); InputSu(D_fore, &D_user, NULL); } else if (!args[1]) @@ -3800,7 +3989,7 @@ int key; else s = DoSu(&D_user, args[0], args[1], args[2]); if (s) - Msg(0, "%s", s); + OutputMsg(0, "%s", s); break; #endif /* MULTIUSER */ case RC_SPLIT: @@ -3828,61 +4017,43 @@ int key; LaySetCursor(); break; case RC_FOCUS: - if (!*args || !strcmp(*args, "down")) - D_forecv = D_forecv->c_next ? D_forecv->c_next : D_cvlist; - else if (!strcmp(*args, "up")) - { - struct canvas *cv; - for (cv = D_cvlist; cv->c_next && cv->c_next != D_forecv; cv = cv->c_next) - ; - D_forecv = cv; - } - else if (!strcmp(*args, "top")) - D_forecv = D_cvlist; - else if (!strcmp(*args, "bottom")) - { - struct canvas *cv; - for (cv = D_cvlist; cv->c_next; cv = cv->c_next) - ; - D_forecv = cv; - } - else - { - Msg(0, "%s: usage: focus [up|down|top|bottom]", rc_name); - break; - } - if ((focusminwidth && (focusminwidth < 0 || D_forecv->c_xe - D_forecv->c_xs + 1 < focusminwidth)) || - (focusminheight && (focusminheight < 0 || D_forecv->c_ye - D_forecv->c_ys + 1 < focusminheight))) - { - ResizeCanvas(&D_canvas); - RecreateCanvasChain(); - RethinkDisplayViewports(); - ResizeLayersToCanvases(); /* redisplays */ - } - fore = D_fore = Layer2Window(D_forecv->c_layer); - if (D_other == fore) - D_other = 0; - flayer = D_forecv->c_layer; -#ifdef RXVT_OSC - if (D_xtermosc[2] || D_xtermosc[3]) - { - Activate(-1); - break; - } -#endif - RefreshHStatus(); -#ifdef RXVT_OSC - RefreshXtermOSC(); -#endif - flayer = D_forecv->c_layer; - CV_CALL(D_forecv, LayRestore();LaySetCursor()); - WindowChanged(0, 'F'); + { + struct canvas *cv = 0; + if (!*args || !strcmp(*args, "next")) + cv = D_forecv->c_next ? D_forecv->c_next : D_cvlist; + else if (!strcmp(*args, "prev")) + { + for (cv = D_cvlist; cv->c_next && cv->c_next != D_forecv; cv = cv->c_next) + ; + } + else if (!strcmp(*args, "top")) + cv = D_cvlist; + else if (!strcmp(*args, "bottom")) + { + for (cv = D_cvlist; cv->c_next; cv = cv->c_next) + ; + } + else if (!strcmp(*args, "up")) + cv = FindCanvas(D_forecv->c_xs, D_forecv->c_ys - 1); + else if (!strcmp(*args, "down")) + cv = FindCanvas(D_forecv->c_xs, D_forecv->c_ye + 2); + else if (!strcmp(*args, "left")) + cv = FindCanvas(D_forecv->c_xs - 1, D_forecv->c_ys); + else if (!strcmp(*args, "right")) + cv = FindCanvas(D_forecv->c_xe + 1, D_forecv->c_ys); + else + { + OutputMsg(0, "%s: usage: focus [next|prev|up|down|left|right|top|bottom]", rc_name); + break; + } + SetForeCanvas(display, cv); + } break; case RC_RESIZE: i = 0; if (D_forecv->c_slorient == SLICE_UNKN) { - Msg(0, "resize: need more than one region"); + OutputMsg(0, "resize: need more than one region"); break; } for (; *args; args++) @@ -3902,7 +4073,7 @@ int key; } if (*args && args[1]) { - Msg(0, "%s: usage: resize [-h] [-v] [-l] [num]\n", rc_name); + OutputMsg(0, "%s: usage: resize [-h] [-v] [-l] [num]\n", rc_name); break; } if (*args) @@ -3926,17 +4097,28 @@ int key; case RC_ALTSCREEN: (void)ParseSwitch(act, &use_altscreen); if (msgok) - Msg(0, "Will %sdo alternate screen switching", use_altscreen ? "" : "not "); + OutputMsg(0, "Will %sdo alternate screen switching", use_altscreen ? "" : "not "); break; case RC_MAXWIN: + if (!args[0]) + { + OutputMsg(0, "maximum windows allowed: %d", maxwin); + break; + } if (ParseNum(act, &n)) break; if (n < 1) - Msg(0, "illegal maxwin number specified"); - else if (n > maxwin) - Msg(0, "may only decrease maxwin number"); + OutputMsg(0, "illegal maxwin number specified"); + else if (n > 2048) + OutputMsg(0, "maximum 2048 windows allowed"); + else if (n > maxwin && windows) + OutputMsg(0, "may increase maxwin only when there's no window"); else - maxwin = n; + { + if (!windows) + wtab = realloc(wtab, n * sizeof(struct win *)); + maxwin = n; + } break; case RC_BACKTICK: if (ParseBase(act, *args, &n, 10, "decimal")) @@ -3948,7 +4130,7 @@ int key; int lifespan, tick; if (argc < 4) { - Msg(0, "%s: usage: backtick num [lifespan tick cmd args...]", rc_name); + OutputMsg(0, "%s: usage: backtick num [lifespan tick cmd args...]", rc_name); break; } if (ParseBase(act, args[1], &lifespan, 10, "decimal")) @@ -3973,6 +4155,21 @@ int key; break; #ifdef BLANKER_PRG case RC_BLANKERPRG: + if (!args[0]) + { + if (blankerprg) + { + char path[MAXPATHLEN]; + char *p = path, **pp; + for (pp = blankerprg; *pp; pp++) + p += snprintf(p, sizeof(path) - (p - path) - 1, "%s ", *pp); + *(p - 1) = '\0'; + OutputMsg(0, "blankerprg: %s", path); + } + else + OutputMsg(0, "No blankerprg set."); + break; + } if (blankerprg) { char **pp; @@ -3997,7 +4194,7 @@ int key; { if ((i = FindCommnr(args[1])) == RC_ILLEGAL) { - Msg(0, "%s: idle: unknown command '%s'", rc_name, args[1]); + OutputMsg(0, "%s: idle: unknown command '%s'", rc_name, args[1]); break; } if (CheckArgNum(i, args + 2) < 0) @@ -4012,9 +4209,9 @@ int key; if (msgok) { if (idletimo) - Msg(0, "idle timeout %ds, %s", idletimo / 1000, comms[idleaction.nr].name); + OutputMsg(0, "idle timeout %ds, %s", idletimo / 1000, comms[idleaction.nr].name); else - Msg(0, "idle off"); + OutputMsg(0, "idle off"); } break; case RC_FOCUSMINSIZE: @@ -4040,7 +4237,7 @@ int key; else sprintf(b[i], "%d", n); } - Msg(0, "focus min size is %s %s\n", b[0], b[1]); + OutputMsg(0, "focus min size is %s %s\n", b[0], b[1]); } break; case RC_GROUP: @@ -4050,7 +4247,7 @@ int key; if (args[0][0]) { fore->w_group = WindowByName(*args); - if (fore->w_group && fore->w_group->w_type != W_TYPE_GROUP) + if (fore->w_group == fore || (fore->w_group && fore->w_group->w_type != W_TYPE_GROUP)) fore->w_group = 0; } WindowChanged((struct win *)0, 'w'); @@ -4060,9 +4257,9 @@ int key; if (msgok) { if (fore->w_group) - Msg(0, "window group is %d (%s)\n", fore->w_group->w_number, fore->w_group->w_title); + OutputMsg(0, "window group is %d (%s)\n", fore->w_group->w_number, fore->w_group->w_title); else - Msg(0, "window belongs to no group"); + OutputMsg(0, "window belongs to no group"); } break; case RC_LAYOUT: @@ -4070,12 +4267,12 @@ int key; { if (!D_layout) { - Msg(0, "not on a layout"); + OutputMsg(0, "not on a layout"); break; } if (!args[1]) { - Msg(0, "current layout is %d (%s)", D_layout->lay_number, D_layout->lay_title); + OutputMsg(0, "current layout is %d (%s)", D_layout->lay_number, D_layout->lay_title); break; } free(D_layout->lay_title); @@ -4085,9 +4282,14 @@ int key; { int old; struct layout *lay; + if (!D_layout) + { + OutputMsg(0, "not on a layout"); + break; + } if (!args[1]) { - Msg(0, "This is layout %d (%s).\n", D_layout->lay_number, D_layout->lay_title); + OutputMsg(0, "This is layout %d (%s).\n", D_layout->lay_number, D_layout->lay_title); break; } old = D_layout->lay_number; @@ -4106,7 +4308,7 @@ int key; { if (!D_layout) { - Msg(0, "not on a layout"); + OutputMsg(0, "not on a layout"); break; } if (args[1]) @@ -4117,12 +4319,12 @@ int key; D_layout->lay_autosave = 0; else { - Msg(0, "invalid argument. Give 'on' or 'off"); + OutputMsg(0, "invalid argument. Give 'on' or 'off"); break; } } if (msgok) - Msg(0, "autosave is %s", D_layout->lay_autosave ? "on" : "off"); + OutputMsg(0, "autosave is %s", D_layout->lay_autosave ? "on" : "off"); } else if (!strcmp(args[0], "new")) { @@ -4150,7 +4352,7 @@ int key; { if (!args[1]) { - Msg(0, "usage: layout save <name>"); + OutputMsg(0, "usage: layout save <name>"); break; } SaveLayout(args[1], &D_canvas); @@ -4173,7 +4375,7 @@ int key; lay = layouts; if (!lay) { - Msg(0, "no layout defined"); + OutputMsg(0, "no layout defined"); break; } if (lay == D_layout) @@ -4193,7 +4395,7 @@ int key; lay = layouts; if (!lay) { - Msg(0, "no layout defined"); + OutputMsg(0, "no layout defined"); break; } if (lay == D_layout) @@ -4206,11 +4408,11 @@ int key; if (!args[1]) { if (!layout_attach) - Msg(0, "no attach layout set"); + OutputMsg(0, "no attach layout set"); else if (layout_attach == &layout_last_marker) - Msg(0, "will attach to last layout"); + OutputMsg(0, "will attach to last layout"); else - Msg(0, "will attach to layout %d (%s)", layout_attach->lay_number, layout_attach->lay_title); + OutputMsg(0, "will attach to layout %d (%s)", layout_attach->lay_number, layout_attach->lay_title); break; } if (!strcmp(args[1], ":last")) @@ -4223,7 +4425,7 @@ int key; lay = FindLayout(args[1]); if (!lay) { - Msg(0, "unknown layout '%s'", args[1]); + OutputMsg(0, "unknown layout '%s'", args[1]); break; } layout_attach = lay; @@ -4241,22 +4443,31 @@ int key; lay = layouts ? FindLayout(args[1]) : (struct layout *)0; if (!lay) { - Msg(0, "unknown layout '%s'", args[1]); + OutputMsg(0, "unknown layout '%s'", args[1]); break; } } if (lay) RemoveLayout(lay); } + else if (!strcmp(args[0], "dump")) + { + if (!display) + OutputMsg(0, "Must have a display for 'layout dump'."); + else if (!LayoutDumpCanvas(&D_canvas, args[1] ? args[1] : "layout-dump")) + OutputMsg(errno, "Error dumping layout."); + else + OutputMsg(0, "Layout dumped to \"%s\"", args[1] ? args[1] : "layout-dump"); + } else - Msg(0, "unknown layout subcommand"); + OutputMsg(0, "unknown layout subcommand"); break; #ifdef DW_CHARS case RC_CJKWIDTH: if(ParseSwitch(act, &cjkwidth) == 0) { if(msgok) - Msg(0, "Treat ambiguous width characters as %s width", cjkwidth ? "full" : "half"); + OutputMsg(0, "Treat ambiguous width characters as %s width", cjkwidth ? "full" : "half"); } break; #endif @@ -4274,6 +4485,7 @@ int key; break; } } +#undef OutputMsg void DoCommand(argv, argl) @@ -4281,10 +4493,26 @@ char **argv; int *argl; { struct action act; + const char *cmd = *argv; - if ((act.nr = FindCommnr(*argv)) == RC_ILLEGAL) + act.quiet = 0; + /* For now, we actually treat both 'supress error' and 'suppress normal message' as the + * same, and ignore all messages on either flag. If we wanted to do otherwise, we would + * need to change the definition of 'OutputMsg' slightly. */ + if (*cmd == '@') /* Suppress error */ { - Msg(0, "%s: unknown command '%s'", rc_name, *argv); + act.quiet |= 0x01; + cmd++; + } + if (*cmd == '-') /* Suppress normal message */ + { + act.quiet |= 0x02; + cmd++; + } + + if ((act.nr = FindCommnr(cmd)) == RC_ILLEGAL) + { + Msg(0, "%s: unknown command '%s'", rc_name, cmd); return; } act.args = argv + 1; @@ -4314,9 +4542,9 @@ int *argl; return; } if ((pp = (char **)malloc((unsigned)(argc + 1) * sizeof(char **))) == 0) - Panic(0, strnomem); + Panic(0, "%s", strnomem); if ((lp = (int *)malloc((unsigned)(argc) * sizeof(int *))) == 0) - Panic(0, strnomem); + Panic(0, "%s", strnomem); act->nr = nr; act->args = pp; act->argl = lp; @@ -4338,7 +4566,7 @@ char **args; while (args[argc]) argc++; if ((pp = ap = (char **)malloc((unsigned)(argc + 1) * sizeof(char **))) == 0) - Panic(0, strnomem); + Panic(0, "%s", strnomem); while (argc--) *pp++ = SaveStr(*args++); *pp = 0; @@ -4370,6 +4598,7 @@ int bufl, *argl; delim = 0; for (;;) { + *lp = 0; while (*p && (*p == ' ' || *p == '\t')) ++p; #ifdef PSEUDOS @@ -4402,7 +4631,7 @@ int bufl, *argl; { if (*p == delim) delim = 0; - else if (delim != '\'' && *p == '\\' && (p[1] == '\'' || p[1] == '"' || p[1] == '\\' || p[1] == '$' || p[1] == '#' || p[1] == '^' || (p[1] >= '0' && p[1] <= '7'))) + else if (delim != '\'' && *p == '\\' && (p[1] == 'n' || p[1] == 'r' || p[1] == 't' || p[1] == '\'' || p[1] == '"' || p[1] == '\\' || p[1] == '$' || p[1] == '#' || p[1] == '^' || (p[1] >= '0' && p[1] <= '7'))) { p++; if (*p >= '0' && *p <= '7') @@ -4421,12 +4650,21 @@ int bufl, *argl; pp++; } else - *pp++ = *p; + { + switch (*p) + { + case 'n': *pp = '\n'; break; + case 'r': *pp = '\r'; break; + case 't': *pp = '\t'; break; + default: *pp = *p; break; + } + pp++; + } } else if (delim != '\'' && *p == '$' && (p[1] == '{' || p[1] == ':' || (p[1] >= 'a' && p[1] <= 'z') || (p[1] >= 'A' && p[1] <= 'Z') || (p[1] >= '0' && p[1] <= '9') || p[1] == '_')) { - char *ps, *pe, op, *v, xbuf[11]; + char *ps, *pe, op, *v, xbuf[11], path[MAXPATHLEN]; int vl; ps = ++p; @@ -4468,6 +4706,22 @@ int bufl, *argl; sprintf(xbuf, "%d", display ? D_width : -1); else if (!strcmp(ps, "LINES")) sprintf(xbuf, "%d", display ? D_height : -1); + else if (!strcmp(ps, "PID")) + sprintf(xbuf, "%d", getpid()); + else if (!strcmp(ps, "PWD")) + { + if (getcwd(path, sizeof(path) - 1) == 0) + v = "?"; + else + v = path; + } + else if (!strcmp(ps, "STY")) + { + if ((v = strchr(SockName, '.'))) /* Skip the PID */ + v++; + else + v = SockName; + } else v = getenv(ps); } @@ -4739,7 +4993,7 @@ char *str; int i; struct win *p; - if ((i = WindowByNumber(str)) < 0 || i >= MAXWIN) + if ((i = WindowByNumber(str)) < 0 || i >= maxwin) { if ((p = WindowByName(str))) return p->w_number; @@ -4844,7 +5098,7 @@ int n; struct win *p; debug1("SwitchWindow %d\n", n); - if (n < 0 || n >= MAXWIN) + if (n < 0 || n >= maxwin) { ShowWindows(-1); return; @@ -4875,118 +5129,6 @@ int n; Activate(fore->w_norefresh); } - -void -SetCanvasWindow(cv, wi) -struct canvas *cv; -struct win *wi; -{ - struct win *p = 0, **pp; - struct layer *l; - struct canvas *cvp, **cvpp; - - l = cv->c_layer; - display = cv->c_display; - - if (l) - { - /* remove old layer */ - for (cvpp = &l->l_cvlist; (cvp = *cvpp); cvpp = &cvp->c_lnext) - if (cvp == cv) - break; - ASSERT(cvp); - *cvpp = cvp->c_lnext; - - p = Layer2Window(l); - l = cv->c_layer; - cv->c_layer = 0; - - if (p && cv == D_forecv) - { -#ifdef MULTIUSER - ReleaseAutoWritelock(display, p); -#endif - if (p->w_silence) - { - SetTimeout(&p->w_silenceev, p->w_silencewait * 1000); - evenq(&p->w_silenceev); - } - D_other = fore; - D_fore = 0; - } - if (l->l_cvlist == 0 && (p == 0 || l != p->w_savelayer)) - KillLayerChain(l); - } - - /* find right layer to display on canvas */ - if (wi && wi->w_type != W_TYPE_GROUP) - { - l = &wi->w_layer; - if (wi->w_savelayer && (wi->w_blocked || wi->w_savelayer->l_cvlist == 0)) - l = wi->w_savelayer; - } - else - { - l = &cv->c_blank; - if (wi) - l->l_data = (char *)wi; - else - l->l_data = 0; - } - - /* add our canvas to the layer's canvaslist */ - ASSERT(l->l_cvlist != cv); - cv->c_lnext = l->l_cvlist; - l->l_cvlist = cv; - cv->c_layer = l; - cv->c_xoff = cv->c_xs; - cv->c_yoff = cv->c_ys; - RethinkViewportOffsets(cv); - - if (flayer == 0) - flayer = l; - - if (wi && wi->w_type == W_TYPE_GROUP) - { - /* auto-start windowlist on groups */ - struct display *d = display; - struct layer *oldflayer = flayer; - flayer = l; - display_wlist(0, 0, wi); - flayer = oldflayer; - display = d; - } - - if (wi && D_other == wi) - D_other = wi->w_next; /* Might be 0, but that's OK. */ - if (cv == D_forecv) - { - D_fore = wi; - fore = D_fore; /* XXX ? */ - if (wi) - { -#ifdef MULTIUSER - ObtainAutoWritelock(display, wi); -#endif - /* - * Place the window at the head of the most-recently-used list - */ - if (windows != wi) - { - for (pp = &windows; (p = *pp); pp = &p->w_next) - if (p == wi) - break; - ASSERT(p); - *pp = p->w_next; - p->w_next = windows; - windows = p; - WListLinkChanged(); - } - } - } -} - - /* * SetForeWindow changes the window in the input focus of the display. * Puts window wi in canvas display->d_forecv. @@ -5060,12 +5202,12 @@ static int NextWindow() { register struct win **pp; - int n = fore ? fore->w_number : MAXWIN; + int n = fore ? fore->w_number : maxwin; struct win *group = fore ? fore->w_group : 0; for (pp = fore ? wtab + n + 1 : wtab; pp != wtab + n; pp++) { - if (pp == wtab + MAXWIN) + if (pp == wtab + maxwin) pp = wtab; if (*pp) { @@ -5088,7 +5230,7 @@ PreviousWindow() for (pp = wtab + n - 1; pp != wtab + n; pp--) { if (pp == wtab - 1) - pp = wtab + MAXWIN - 1; + pp = wtab + maxwin - 1; if (*pp) { if (!fore || group == (*pp)->w_group) @@ -5115,36 +5257,6 @@ MoreWindows() return 0; } -static void -UpdateLayoutCanvas(cv, wi) -struct canvas *cv; -struct win *wi; -{ - for (; cv; cv = cv->c_slnext) - { - if (cv->c_layer && Layer2Window(cv->c_layer) == wi) - { - /* A simplistic version of SetCanvasWindow(cv, 0) */ - struct layer *l = cv->c_layer; - cv->c_layer = 0; - if (l->l_cvlist == 0 && (wi == 0 || l != wi->w_savelayer)) - KillLayerChain(l); - l = &cv->c_blank; - l->l_data = 0; - if (l->l_cvlist != cv) - { - cv->c_lnext = l->l_cvlist; - l->l_cvlist = cv; - } - cv->c_layer = l; - /* Do not end here. Multiple canvases can have the same window */ - } - - if (cv->c_slperp) - UpdateLayoutCanvas(cv->c_slperp, wi); - } -} - void KillWindow(wi) struct win *wi; @@ -5253,15 +5365,21 @@ int where; int l; s = ss = buf; - for (pp = ((flags & 4) && where >= 0) ? wtab + where + 1: wtab; pp < wtab + MAXWIN; pp++) + if ((flags & 8) && where < 0) { + *s = 0; + return ss; + } + for (pp = ((flags & 4) && where >= 0) ? wtab + where + 1: wtab; pp < wtab + maxwin; pp++) + { + int rend = -1; if (pp - wtab == where && ss == buf) - ss = s; + ss = s; if ((p = *pp) == 0) continue; if ((flags & 1) && display && p == D_fore) continue; - if (D_fore && D_fore->w_group != p->w_group) + if (display && D_fore && D_fore->w_group != p->w_group) continue; cmd = p->w_title; @@ -5275,9 +5393,24 @@ int where; *s++ = ' '; *s++ = ' '; } - sprintf(s, "%d", p->w_number); if (p->w_number == where) - ss = s; + { + ss = s; + if (flags & 8) + break; + } + if (!(flags & 4) || where < 0 || ((flags & 4) && where < p->w_number)) + { + if (p->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1) + rend = renditions[REND_MONITOR]; + else if ((p->w_bell == BELL_DONE || p->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1) + rend = renditions[REND_BELL]; + else if ((p->w_silence == SILENCE_FOUND || p->w_silence == SILENCE_DONE) && renditions[REND_SILENCE] != -1) + rend = renditions[REND_SILENCE]; + } + if (rend != -1) + AddWinMsgRend(s, rend); + sprintf(s, "%d", p->w_number); s += strlen(s); if (display && p == D_fore) *s++ = '*'; @@ -5290,6 +5423,8 @@ int where; *s++ = ' '; strncpy(s, cmd, l); s += l; + if (rend != -1) + AddWinMsgRend(s, -1); } *s = 0; return ss; @@ -5388,13 +5523,11 @@ int where; char buf[1024]; char *s, *ss; - if (!display) - return; - if (where == -1 && D_fore) + if (display && where == -1 && D_fore) where = D_fore->w_number; ss = AddWindows(buf, sizeof(buf), 0, where); s = buf + strlen(buf); - if (ss - buf > D_width / 2) + if (display && ss - buf > D_width / 2) { ss -= D_width / 2; if (s - ss < D_width) @@ -5874,7 +6007,7 @@ char *fn, **av; if (*buf != '\0') nwin.aka = buf; num = atoi(*av); - if (num < 0 || num > MAXWIN - 1) + if (num < 0 || (maxwin && num > maxwin - 1) || (!maxwin && num > MAXWIN - 1)) { Msg(0, "%s: illegal screen number %d.", fn, num); num = 0; @@ -5991,7 +6124,7 @@ char *data; /* dummy */ { if ((pp->buf = (char *)malloc(D_user->u_plop.len)) == NULL) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); return; } bcopy(D_user->u_plop.buf, pp->buf, D_user->u_plop.len); @@ -6066,6 +6199,7 @@ char *data; act.nr = *(int *)data; act.args = noargs; act.argl = 0; + act.quiet = 0; DoAction(&act, -1); } @@ -6197,7 +6331,7 @@ char *data; #endif if (!(u->u_plop.buf = SaveStr(u->u_password))) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); D_user->u_plop.len = 0; } else @@ -6209,6 +6343,18 @@ char *data; } #endif /* PASSWORD */ +static int +digraph_find(buf) +const char *buf; +{ + int i; + for (i = 0; i < MAX_DIGRAPH && digraphs[i].d[0]; i++) + if ((digraphs[i].d[0] == (unsigned char)buf[0] && digraphs[i].d[1] == (unsigned char)buf[1]) || + (digraphs[i].d[0] == (unsigned char)buf[1] && digraphs[i].d[1] == (unsigned char)buf[0])) + break; + return i; +} + static void digraph_fn(buf, len, data) char *buf; @@ -6260,43 +6406,14 @@ char *data; /* dummy */ } if (len < 2) return; - if (len >= 1 && ((*buf == 'U' && buf[1] == '+') || (*buf == '0' && (buf[1] == 'x' || buf[1] == 'X')))) - { - x = 0; - for (i = 2; i < len; i++) - { - if (buf[i] >= '0' && buf[i] <= '9') - x = x * 16 | (buf[i] - '0'); - else if (buf[i] >= 'a' && buf[i] <= 'f') - x = x * 16 | (buf[i] - ('a' - 10)); - else if (buf[i] >= 'A' && buf[i] <= 'F') - x = x * 16 | (buf[i] - ('A' - 10)); - else - break; - } - } - else if (buf[0] == '0') + if (!parse_input_int(buf, len, &x)) { - x = 0; - for (i = 1; i < len; i++) - { - if (buf[i] < '0' || buf[i] > '7') - break; - x = x * 8 | (buf[i] - '0'); - } - } - else - { - for (i = 0; i < (int)(sizeof(digraphs)/sizeof(*digraphs)); i++) - if ((digraphs[i][0] == (unsigned char)buf[0] && digraphs[i][1] == (unsigned char)buf[1]) || - (digraphs[i][0] == (unsigned char)buf[1] && digraphs[i][1] == (unsigned char)buf[0])) - break; - if (i == (int)(sizeof(digraphs)/sizeof(*digraphs))) + i = digraph_find(buf); + if ((x = digraphs[i].value) <= 0) { Msg(0, "Unknown digraph"); return; } - x = digraphs[i][2]; } i = 1; *buf = x; @@ -6343,7 +6460,7 @@ int i; fore = D_fore; act = 0; #ifdef COPY_PASTE - if (InMark() || InInput() || InWList()) + if (flayer && flayer->l_mode == 1) act = i < KMAP_KEYS+KMAP_AKEYS ? &mmtab[i] : &kmap_exts[i - (KMAP_KEYS+KMAP_AKEYS)].mm; #endif if ((!act || act->nr == RC_ILLEGAL) && !D_mapdefault) @@ -6827,6 +6944,49 @@ char *data; buf[len] = '\034'; } +void +SetForeCanvas(d, cv) +struct display *d; +struct canvas *cv; +{ + struct display *odisplay = display; + if (d->d_forecv == cv) + return; + + display = d; + D_forecv = cv; + if ((focusminwidth && (focusminwidth < 0 || D_forecv->c_xe - D_forecv->c_xs + 1 < focusminwidth)) || + (focusminheight && (focusminheight < 0 || D_forecv->c_ye - D_forecv->c_ys + 1 < focusminheight))) + { + ResizeCanvas(&D_canvas); + RecreateCanvasChain(); + RethinkDisplayViewports(); + ResizeLayersToCanvases(); /* redisplays */ + } + fore = D_fore = Layer2Window(D_forecv->c_layer); + if (D_other == fore) + D_other = 0; + flayer = D_forecv->c_layer; +#ifdef RXVT_OSC + if (D_xtermosc[2] || D_xtermosc[3]) + { + Activate(-1); + } + else +#endif + { + RefreshHStatus(); +#ifdef RXVT_OSC + RefreshXtermOSC(); +#endif + flayer = D_forecv->c_layer; + CV_CALL(D_forecv, LayRestore();LaySetCursor()); + WindowChanged(0, 'F'); + } + + display = odisplay; +} + #ifdef RXVT_OSC void RefreshXtermOSC() |