summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Jennings <mej@kainx.org>2002-05-22 15:38:35 +0000
committerMichael Jennings <mej@kainx.org>2002-05-22 15:38:35 +0000
commit9ce5b286eb67b2a8a9431f1aa8a3ee4c2d543085 (patch)
treedeac047a954b5da8e7270a4ed35b6dbcd01e3bf7
parentd185cd525ccead491607e5616277941af404378d (diff)
downloadeterm-9ce5b286eb67b2a8a9431f1aa8a3ee4c2d543085.tar.gz
Wed May 22 11:37:19 2002 Michael Jennings (mej)
Latest Escreen work from Azundris <scream@azundris.com>. SVN revision: 6270
-rw-r--r--ChangeLog4
-rw-r--r--doc/README.Escreen (renamed from src/README.Escreen)75
-rw-r--r--doc/escreen.cfg132
-rw-r--r--src/actions.c2
-rw-r--r--src/command.c271
-rw-r--r--src/libscream.c473
-rw-r--r--src/menus.c31
-rw-r--r--src/menus.h1
-rw-r--r--src/options.c14
-rw-r--r--src/options.h1
-rw-r--r--src/pixmap.c107
-rw-r--r--src/scream.h21
-rw-r--r--src/screamcfg.h18
-rw-r--r--src/screen.c18
-rw-r--r--src/screen.h3
-rw-r--r--src/startup.c2
16 files changed, 891 insertions, 282 deletions
diff --git a/ChangeLog b/ChangeLog
index a07a2fc..ba97c1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4663,3 +4663,7 @@ Wed May 22 09:16:55 2002 Michael Jennings (mej)
Touch-ups to help info.
----------------------------------------------------------------------
+Wed May 22 11:37:19 2002 Michael Jennings (mej)
+
+Latest Escreen work from Azundris <scream@azundris.com>.
+----------------------------------------------------------------------
diff --git a/src/README.Escreen b/doc/README.Escreen
index a1cee8d..62a2d60 100644
--- a/src/README.Escreen
+++ b/doc/README.Escreen
@@ -47,18 +47,13 @@ a menu of screen-related actions. If you normally don't use a button-bar,
Escreen will create one for you. Otherwise, it will add buttons to your
existing bar.
+* .screenrc, $SCREENRC, [/usr/local]/etc/screenrc and $SYSSCREENRC are
+ supported.
+* Eterm-buttons are supported (left click on display-name to activate
+ the display, middle to close it, right to rename it).
-5 - What's new?
-
-* Support for ".screenrc". This was temporarily disabled to aid in
- debugging and has now returned in conjunction with
-
-* Escreen accepting non-default key setups and
-
-* renaming of displays
-
-* sending statements to screen (^A: in the default setup) with
+* Sending statements to screen (^A: in the default setup) with
tab-completion
* support for screen command-line options:
@@ -68,14 +63,27 @@ existing bar.
escape-character in the ECHO action; Escreen will remap it to
whatever is actually used in the session)
-* rewrite of key parts for enhanced compatibility
-
* alert boxes for messages from screen
* support for SSH-tunneling through firewalls
+5 - What's new?
+
+* Entering and exiting copy mode no longer produces a dialog box.
+ Just too bloody annoying, that.
+
+* SCREENRC, SYSSCREENRC, .../etc/screenrc support (thanks mej)
+
+* Easy-to-remember key-layout (optional, see below)
+
+* Comes up much faster
+
+* You can pass arbitrary paramters to screen/scream now
+
+
+
6 - What should I expect in the future? (TODO)
* Limited support for scrolling. screen doesn't give us all the info
@@ -88,15 +96,6 @@ existing bar.
9 - FAQ
-Q I don't see any buttons when I connect to a remote screen!
-
-A Some Debian-users reported this before, and it is presumed to be a
- problem with the terminfo-data. Call up Eterm (or xterm, or whatnot).
- *Then* call up "screen" from inside that terminal. Is the last line
- inverted? If it isn't, something is seriously weird with your setup,
- and it's not a problem in Escreen. Sorry. : (
- 2002/05/13 rewritten code should handle most of these cases
-
Q ^A does funny things!
A Well, yes. ^A talks to the screen program. Put a line
@@ -116,11 +115,31 @@ A You probably already have changed the magic escape key to something
Er, you *did* hold Control, then press A, rather then typing a ^ and
an A, right?
-Q I'd like for the button labels to be in a different colour.
+Q But I don't like all this control-whatever stuff, can I have easier
+ to remember bindings?
-A At this time, the labels follow the general (text) colours.
- You will be able to define colours for (foreground|background|active|bell)
- windows' labels in later releases.
+A Sure. Eterm is The Configurable Terminal, after all. A pret-a-porter
+ example that you can simply add to your theme.cfg file (or %include
+ from it) lives in escreen.cfg -- enjoy.
+
+Q Escreen changes the escape on the remote box to the same thing as on
+ the local box, does it have to?
+
+A You can always override the escapes like so:
+
+ Eterm -U user@host.com/-e^Xy
+
+ Where ^X is the escape and y the literal (man screen).
+
+Q I don't see any buttons when I connect to a remote screen!
+
+A Some Debian-users reported this before, and it is presumed to be a
+ problem with the terminfo-data. Call up Eterm (or xterm, or whatnot).
+ *Then* call up "screen" from inside that terminal. Is the last line
+ inverted? If it isn't, something is seriously weird with your setup,
+ and it's not a problem in Escreen. Sorry. : (
+ 2002/05/13 rewritten code should handle most of these cases
+ 2002/05/18 rewritten code should handle even more of these cases : )
Q Escreen opens, then closes again.
@@ -137,6 +156,12 @@ Q Escreen works, except when I use -Z to tunnel through a firewall?
A Try to manually ssh to the firewall, see how long that takes. Then,
tune the -Z option accordingly (cf man Eterm).
+Q I'd like for the button labels to be in a different colour.
+
+A At this time, the labels follow the general (text) colours.
+ You will be able to define colours for (foreground|background|active|bell)
+ windows' labels in later releases.
+
Q "screen" support rocks! Can we have it in konsole/multi-gnome-terminal?
A I will not attempt anything like that before I am happy with Escreen.
diff --git a/doc/escreen.cfg b/doc/escreen.cfg
new file mode 100644
index 0000000..ec6b43b
--- /dev/null
+++ b/doc/escreen.cfg
@@ -0,0 +1,132 @@
+<Eterm-0.9.1>
+
+ # key-bindings for Escreen.
+ # for those who don't like the traditional ones (as used by the "screen"
+ # program). you may use the control variety, the alt variety, or both.
+ # you can copy the statements you like into the "action" context of your
+ # Eterm theme, or you could include this file via %include "escreen.cfg"
+ # See "man Eterm" for more information.
+ # 2002/05/19 Azundris <scream@azundris.com>
+
+ # CONTROL VARIETY #########################################################
+
+ # ctrl-left -> previous display, ctrl-right -> next display
+ bind ctrl Left to echo ^Ap
+ bind ctrl Right to echo ^An
+
+ # ctl-pg_up -> previous display, ctl-pg_dn -> next display (Galeon-like)
+ bind ctrl Prior to echo ^Ap
+ bind ctrl Next to echo ^An
+
+ # no ctrl-up/down; we shouldn't steal that from the app.
+
+ # ctl-space -> toggle between last two displays
+ bind ctrl space to echo ^A^A
+
+ # ctrl-1..ctrl-0 -> display_0..display_9
+ bind ctrl 0x31 to echo ^A0
+ bind ctrl 0x32 to echo ^A1
+ bind ctrl 0x33 to echo ^A2
+ bind ctrl 0x34 to echo ^A3
+ bind ctrl 0x35 to echo ^A4
+ bind ctrl 0x36 to echo ^A5
+ bind ctrl 0x37 to echo ^A6
+ bind ctrl 0x38 to echo ^A7
+ bind ctrl 0x39 to echo ^A8
+ bind ctrl 0x30 to echo ^A9
+
+ # ALT VARIETY #############################################################
+
+ # alt-left -> previous display, alt-right -> next display
+ bind alt Left to echo ^Ap
+ bind alt Right to echo ^An
+
+ # alt-up -> previous region, alt-down -> next region
+ bind alt Down to echo ^A\t
+
+ # alt-pg_up -> previous display, alt-pg_dn -> next display
+ bind alt Prior to echo ^Ap
+ bind alt Next to echo ^An
+
+ # alt-space -> toggle between last two displays
+ bind alt space to echo ^A^A
+
+ # alt-1..alt-0 -> display_0..display_9
+ bind alt 0x31 to echo ^A0
+ bind alt 0x32 to echo ^A1
+ bind alt 0x33 to echo ^A2
+ bind alt 0x34 to echo ^A3
+ bind alt 0x35 to echo ^A4
+ bind alt 0x36 to echo ^A5
+ bind alt 0x37 to echo ^A6
+ bind alt 0x38 to echo ^A7
+ bind alt 0x39 to echo ^A8
+ bind alt 0x30 to echo ^A9
+
+ # FUNCTION KEYS ###########################################################
+
+ # F1..F10 -> display_0..display_9
+ bind F1 to echo ^A0
+ bind F2 to echo ^A1
+ bind F3 to echo ^A2
+ bind F4 to echo ^A3
+ bind F5 to echo ^A4
+ bind F6 to echo ^A5
+ bind F7 to echo ^A6
+ bind F8 to echo ^A7
+ bind F9 to echo ^A8
+ bind F10 to echo ^A9
+
+ # alt F4 -> close display
+ bind alt F4 to echo ^Ak
+
+ # MISC STUFF ##############################################################
+
+ # DISPLAY
+
+ # alt-n -> new display
+ bind alt n to echo ^Ac
+
+ # alt-r -> rename display
+ bind alt r to echo ^AA
+
+ # alt-c -> close display
+ bind alt c to echo ^Ak
+
+ # alt-m -> monitor display
+ bind alt m to echo ^AM
+
+ # alt-b -> backlog
+ bind alt b to echo ^A^[
+
+
+ # REGION
+
+ # alt-s -> split
+ bind alt s to echo ^AS
+
+ # alt-u -> unsplit
+ bind alt u to echo ^AQ
+
+ # alt-o -> other region
+ bind alt o to echo ^A^I
+
+ # alt-k -> kill region
+ bind alt k to echo ^AX
+
+ # ^Tab -> next region
+ bind ctrl Tab to echo ^A^I
+
+
+
+ # OTHER
+
+ # alt-S -> statement
+ bind alt shift S to echo ^A:
+
+ # alt-R -> reset
+ bind alt shift R to echo ^AZ
+
+
+
+ # ENDS ####################################################################
diff --git a/src/actions.c b/src/actions.c
index bf52cb1..2379ea9 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -61,7 +61,7 @@ action_handle_echo(event_t *ev, action_t *action)
REQUIRE_RVAL(action->param.string != NULL, 0);
#ifdef ESCREEN
if (TermWin.screen_mode && TermWin.screen) /* translate escapes */
- ns_screen_command(TermWin.screen, action->param.string);
+ ns_parse_screen_interactive(TermWin.screen, action->param.string);
else
#endif
tt_write((unsigned char *) action->param.string, strlen(action->param.string));
diff --git a/src/command.c b/src/command.c
index fdd93b8..5b1a4a1 100644
--- a/src/command.c
+++ b/src/command.c
@@ -1131,7 +1131,8 @@ clean_exit(void)
font_cache_clear();
eterm_font_list_clear();
# ifdef PIXMAP_SUPPORT
- FOREACH_IMAGE(free_eterm_image(&(images[idx])););
+ FOREACH_IMAGE(free_eterm_image(&(images[idx]));
+ );
# endif
for (i = 0; i < NRS_COLORS; i++) {
if (rs_color[i]) {
@@ -2101,18 +2102,6 @@ run_command(char **argv)
ttymode_t tio;
int ptyfd;
-#ifdef NS_DEBUG
- {
- char **a = argv;
- if (a) {
- while (*a) {
- fprintf(stderr, NS_PREFIX "run_command: %s\n", *a);
- a++;
- }
- }
- }
-#endif
-
/* Save and then give up any super-user privileges */
privileges(IGNORE);
@@ -2506,9 +2495,23 @@ upd_disp(void *xd, int n, int flags, char *name)
/* display a status line the screen program sent us */
int
err_msg(void *xd, int err, char *msg)
-{
- if (strlen(msg))
- menu_dial(NULL, msg, 0, NULL, NULL);
+{ /* there are certain things that would make sense if we were displaying
+ a status-line; they do not, however, warrant an alert-box, so we drop
+ them here. */
+
+ char *sc[] = { "Copy mode", "Bell in" };
+ int n, nsc = sizeof(sc) / sizeof(char *);
+
+ if (strlen(msg)) {
+ for (n = 0; n < nsc; n++) {
+ if (!strncmp(msg, sc[n], strlen(sc[n]))) {
+ break;
+ }
+ }
+ if (n >= nsc) {
+ menu_dial(NULL, msg, 0, NULL, NULL);
+ }
+ }
return NS_SUCC;
}
@@ -2547,6 +2550,194 @@ exe_prg(void *xd, char **argv)
return run_command(argv);
}
+
+
+#define DIRECT_MASK (~(RS_Cursor|RS_Select|RS_fontMask))
+#define COLOUR_MASK (RS_fgMask|RS_bgMask)
+#define DIRECT_SET_SCREEN(x,y,fg,bg) (screen.text[ys+y])[x]=fg; (screen.rend[ys+y])[x]=bg&DIRECT_MASK;
+#define CLEAR (1<<16)
+
+void
+direct_write_screen(int x, int y, char *fg, rend_t bg)
+{
+ int ys = TermWin.saveLines - TermWin.view_start;
+ text_t *t = screen.text[ys + y];
+ rend_t *r = screen.rend[ys + y];
+ if (!fg)
+ return;
+ while (*fg && (x >= 0) && (x < TermWin.ncol)) {
+ t[x] = *(fg++);
+ r[x++] = bg & DIRECT_MASK;
+ }
+}
+
+
+
+void
+bosconian(int n)
+{
+ int x, y;
+ int ys = TermWin.saveLines - TermWin.view_start;
+ while (n--) {
+ for (y = 0; y < TermWin.nrow; y++) {
+ text_t *t = screen.text[ys + y];
+ rend_t *r = screen.rend[ys + y];
+ for (x = 0; x < TermWin.ncol; x++) {
+ t[x] = random() & 0xff;
+ r[x] = random() & COLOUR_MASK;
+ }
+ }
+ scr_refresh(FAST_REFRESH);
+ }
+}
+
+
+
+void
+unbosconian(void)
+{
+ int x, y;
+ int ys = TermWin.saveLines - TermWin.view_start;
+ rend_t bg;
+ do {
+ bg = CLEAR;
+ for (y = 0; (bg == CLEAR) && y < TermWin.nrow; y++) {
+ text_t *t = screen.text[ys + y];
+ rend_t *r = screen.rend[ys + y];
+ for (x = 0; (bg == CLEAR) && x < TermWin.ncol; x++) {
+ if (r[x] != CLEAR) {
+ bg = r[x];
+ }
+ }
+ }
+ if (bg != CLEAR) {
+ for (y = 0; y < TermWin.nrow; y++) {
+ text_t *t = screen.text[ys + y];
+ rend_t *r = screen.rend[ys + y];
+ for (x = 0; x < TermWin.ncol; x++) {
+ if (r[x] == bg) {
+ r[x] = CLEAR;
+ t[x] = ' ';
+ }
+ }
+ }
+ scr_refresh(FAST_REFRESH);
+ }
+ } while (bg != CLEAR);
+}
+
+
+
+void
+matrix(int n)
+{
+ int x, y, w, f;
+ int ys = TermWin.saveLines - TermWin.view_start;
+ text_t *s = malloc(TermWin.ncol);
+ text_t *t, *t2;
+ rend_t *r, *r2;
+
+ if (!s) {
+ puts("fail");
+ return;
+ }
+
+ memset(s, 0, TermWin.ncol);
+#define MATRIX_HI CLEAR
+#define MATRIX_LO ((4<<8)|CLEAR)
+
+ while (n--) {
+ for (x = 0; x < TermWin.ncol; x++) {
+ if (!(random() & 3)) {
+ if ((y = s[x])) {
+ w = random() & 15;
+ } else {
+ w = 0;
+ }
+ t = screen.text[ys + y];
+ r = screen.rend[ys + y];
+
+ switch (w) {
+ case 0: /* restart */
+ if (s[x]) {
+ r[x] = MATRIX_LO;
+ s[x] = 0;
+ t = screen.text[ys];
+ r = screen.rend[ys];
+ }
+ r[x] = MATRIX_HI;
+ t[x] = random() & 0xff;
+ s[x]++;
+ /* fall-through */
+
+ case 1: /* continue */
+ case 2:
+ case 3:
+ f = random() & 7;
+ while (f--) {
+ if (y < TermWin.nrow - 1) {
+ t2 = screen.text[ys + y + 1];
+ r2 = screen.rend[ys + y + 1];
+ t2[x] = t[x];
+ r2[x] = r[x];
+ s[x]++;
+ y++;
+ } else {
+ s[x] = 0;
+ f = 0;
+ }
+ r[x] = MATRIX_LO;
+ t[x] = random() & 0xff;
+ if (f) {
+ scr_refresh(FAST_REFRESH);
+ t = screen.text[ys + y];
+ r = screen.rend[ys + y];
+ }
+ }
+ break;
+
+ default: /* hold */
+ t[x] = random() & 0xff;
+ }
+ }
+ }
+ scr_refresh(FAST_REFRESH);
+ }
+ free(s);
+}
+
+
+
+/* do whatever for ms milli-seconds */
+int
+waitstate(void *xd, int ms)
+{
+ int y = 1;
+ time_t dur = (time_t) (ms / 1000), fin = dur + time(NULL);
+
+ if (!(random() & 7)) {
+ if (!(random() & 3)) {
+ matrix(31);
+ unbosconian();
+ }
+ bosconian(4);
+ unbosconian();
+ }
+
+ direct_write_screen(0, y++, " **** COMMODORE 64 BASIC V2 ****", (0 << 8) | CLEAR);
+ direct_write_screen(0, y++, " 64K RAM SYSTEM 38911 BASIC BYTES FREE", (0 << 8) | CLEAR);
+ y += 2;
+ direct_write_screen(0, y++, "READY.", (0 << 8) | CLEAR);
+ screen.row = y;
+ screen.col = 0;
+
+ scr_refresh(FAST_REFRESH);
+
+ sleep(dur);
+
+ return 0;
+}
+
#endif
@@ -2579,6 +2770,8 @@ init_command(char **argv)
ns_register_txt(efuns, inp_text);
ns_register_inp(efuns, inp_dial);
ns_register_tab(efuns, menu_tab);
+
+ ns_register_fun(efuns, waitstate);
#endif
/* Initialize the command connection. This should be called after
@@ -2613,16 +2806,38 @@ init_command(char **argv)
button_t *button;
menu_t *m;
menuitem_t *i;
+ if (rs_delay >= 0) {
+ TermWin.screen->delay = rs_delay; /* more flexible ways later */
+ }
if ((m = menu_create(NS_MENU_TITLE))) {
- char *sc[] = { "New", "\x01\x03", "Close", "\x01k" };
+ char *sc[] = {
+ /* display functions */
+ "New", "\x01:screen\r",
+ "New ...", "\x01\x03\x01\x41",
+ "Backlog ...", "\x01\x1b",
+ "Monitor", "\x01M",
+ "Close", "\x01k",
+ "-", "",
+ /* region functions */
+ "Split", "\x01S",
+ "Unsplit", "\x01Q",
+ "Prvs region", NS_SCREEN_PRVS_REG,
+ "Next region", "\x01\t",
+ "Kill region", "\x01X",
+ "-", "",
+ /* screen functions */
+ "Reset", NS_SCREEN_INIT,
+ "Statement", "\x01:",
+ "-", ""
+ };
int n, nsc = sizeof(sc) / sizeof(char *);
if (menu_list) {
for (n = 0; n < menu_list->nummenus; n++) { /* blend in w/ l&f */
+ if (menu_list->menus[n]->font) {
#ifdef NS_DEBUG
- fprintf(stderr, NS_PREFIX "font: %d: %p\n", n, menu_list->menus[n]->font);
+ fprintf(stderr, NS_PREFIX "font: %d: %p\n", n, menu_list->menus[n]->font);
#endif
- if (menu_list->menus[n]->font) {
m->font = menu_list->menus[n]->font;
m->fwidth = menu_list->menus[n]->fwidth;
m->fheight = menu_list->menus[n]->fheight;
@@ -2635,11 +2850,22 @@ init_command(char **argv)
}
for (n = 0; n < (nsc - 1); n += 2) {
- if ((i = menuitem_create(sc[n]))) {
+ if (!strcmp(sc[n], "-")) { /* separator */
+ if ((i = menuitem_create(NULL))) {
+ menu_add_item(m, i);
+ menuitem_set_action(i, MENUITEM_SEP, NULL);
+ }
+ } /* menu entry */
+ else if ((i = menuitem_create(sc[n]))) {
+ menuitem_set_action(i, n && strcmp(sc[n + 1], NS_SCREEN_INIT)
+ && strcmp(sc[n + 1], NS_SCREEN_PRVS_REG) ? MENUITEM_ECHO : MENUITEM_LITERAL, sc[n + 1]);
# ifdef NS_DEBUG
- fprintf(stderr, NS_PREFIX "register %s (%d)\n", &sc[n + 1][1], *sc[n + 1]);
+ {
+ char buf[64];
+ sprintf(buf, NS_PREFIX "escreen_menu: registered %s as", sc[n]);
+ ns_desc_string(i->action.string, buf);
+ }
# endif
- menuitem_set_action(i, MENUITEM_ECHO, sc[n + 1]);
menu_add_item(m, i);
}
}
@@ -3054,6 +3280,7 @@ main_loop(void)
check_pixmap_change(0);
}
#endif
+
do {
while ((ch = cmd_getc()) == 0); /* wait for something */
if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
diff --git a/src/libscream.c b/src/libscream.c
index 82882a3..a46a3fc 100644
--- a/src/libscream.c
+++ b/src/libscream.c
@@ -12,6 +12,8 @@
* 2002/05/04 Azundris support for esoteric screens, thanks to Till
* 2002/05/12 Azundris edit display names, send statement, tab completion
* 2002/05/13 Azundris ssh tunnel through firewall
+ * 2002/05/17 Azundris supports systemwide screenrc (thanks mej)
+ * 2002/05/18 Azundris remote handling improved (thanks tillsan, tfing)
***************************************************************************/
@@ -42,6 +44,26 @@
+/* test if we have a valid callback for function-type "e".
+ !p a variable of the "_ns_efuns *" type. will contain a pointer to
+ an efun struct containing a function pointer to the requested function
+ if such a struct exists, or NULL, if it doesn't exist
+ s a variable of the "_ns_sess *" type, or NULL (see ns_get_efuns())
+ d a variable of the "_nd_disp *" type, or NULL (see ns_get_efuns())
+ e the name of an element of "_ns_efuns"
+ !<- conditional execution of next (compound-) statement (which would
+ normally be (p)->(e)(...), the call of the function e).
+ */
+#define NS_EFUN_EXISTS(p,s,d,e) (((p) = ns_get_efuns((s),(d))) && ((p)->e))
+
+
+
+/***************************************************************************/
+/* module-global vars */
+/**********************/
+
+
+
static long err_inhibit = 0; /* bits. avoid telling same error twice. */
static _ns_sess *sa = NULL; /* anchor for session list */
static _ns_hop *ha = NULL; /* anchor for hop list */
@@ -54,6 +76,20 @@ static _ns_hop *ha = NULL; /* anchor for hop list */
+/* ns_free
+ free a string (or whatever) */
+
+void *
+ns_free(char **x)
+{
+ if (!x || !*x)
+ return;
+ free(*x);
+ *x = NULL;
+}
+
+
+
/* ns_new_hop. create and initialize a hop struct.
lp local port. if 0: if otherwise matching hop exists, reuse that.
otherwise, find the first free (as in, not used
@@ -280,6 +316,7 @@ ns_new_sess(void)
s->escape = NS_SCREEN_ESCAPE; /* default setup for the screen program */
s->literal = NS_SCREEN_LITERAL;
s->dsbb = NS_SCREEN_DEFSBB;
+ s->delay = NS_INIT_DELAY;
if (sa) { /* add to end of list */
_ns_sess *r = sa;
while (r->next)
@@ -341,28 +378,33 @@ ns_dst_sess(_ns_sess ** ss)
int
ns_screen_command(_ns_sess * sess, char *cmd)
{
+ _ns_efuns *efuns;
char *c;
int ret = NS_SUCC;
- if (!cmd || !*cmd)
+ if (!cmd || !*cmd) {
return NS_FAIL;
+ }
- if (sess->efuns->inp_text) {
+ if (NS_EFUN_EXISTS(efuns, sess, NULL, inp_text)) {
if ((c = strdup(cmd))) {
- {
- char *p = c; /* replace default escape-char with that */
- while (*p) { /* actually used in this session */
- if (*p == NS_SCREEN_ESCAPE)
- *p = sess->escape;
- p++;
+ char *p; /* replace default escape-char with that */
+
+ for (p = c; *p; p++) { /* actually used in this session */
+ if (*p == NS_SCREEN_ESCAPE) {
+ *p = sess->escape;
}
}
- sess->efuns->inp_text(NULL, sess->fd, c);
+#ifdef NS_DEBUG
+ ns_desc_string(c, "ns_screen_command: xlated string");
+#endif
+ efuns->inp_text(NULL, sess->fd, c);
free(c);
- } else
+ } else {
+ /* out of memory */
ret = NS_OOM;
- } /* out of memory */
- else {
+ }
+ } else {
ret = NS_EFUN_NOT_SET;
fprintf(stderr, NS_PREFIX "ns_screen_command: sess->efuns->inp_text not set!\n");
}
@@ -472,10 +514,12 @@ ns_upd_stat(_ns_sess * s)
int
ns_inp_dial(_ns_sess * s, char *prompt, int maxlen, char **retstr, int (*inp_tab) (void *, char *, size_t, size_t))
{
+ _ns_efuns *efuns;
char *c;
int ret = NS_SUCC;
- if (s->efuns->inp_dial) {
- (void) s->efuns->inp_dial((void *) s, prompt, maxlen, retstr, inp_tab);
+
+ if (NS_EFUN_EXISTS(efuns, s, NULL, inp_dial)) {
+ (void) efuns->inp_dial((void *) s, prompt, maxlen, retstr, inp_tab);
} else {
ret = NS_EFUN_NOT_SET;
fprintf(stderr, NS_PREFIX "ns_screen_command: sess->efuns->inp_dial not set!\n");
@@ -499,8 +543,10 @@ ns_inp_dial(_ns_sess * s, char *prompt, int maxlen, char **retstr, int (*inp_tab
int
ns_sess_init(_ns_sess * sess)
{
- if ((sess->backend == NS_MODE_NEGOTIATE) || (sess->backend == NS_MODE_SCREEN))
- return ns_parse_screenrc(sess);
+ if ((sess->backend == NS_MODE_NEGOTIATE) || (sess->backend == NS_MODE_SCREEN)) {
+ (void) ns_parse_screenrc(sess, sess->sysrc, NS_ESC_SYSSCREENRC);
+ return ns_parse_screenrc(sess, sess->home, NS_ESC_SCREENRC);
+ }
return NS_SUCC;
}
@@ -579,11 +625,47 @@ ns_parse_hop(_ns_sess * s, char *h)
+/* ns_desc_string
+ c the string
+ doc context-info
+ !stdout the string, in human-readable form */
+
+void
+ns_desc_string(char *c, char *doc)
+{
+ char *p = c;
+
+ if (doc)
+ fprintf(stderr, NS_PREFIX "%s: ", doc);
+
+ if (!c) {
+ fputs("NULL\n", stderr);
+ return;
+ } else if (!*c) {
+ fputs("empty\n", stderr);
+ return;
+ }
+
+ while (*p) {
+ if (*p < ' ')
+ fprintf(stderr, "^%c", *p + 'A' - 1);
+ else
+ fputc(*p, stderr);
+ p++;
+ }
+
+ fputs("\n", stderr);
+
+ return;
+}
+
+
+
/* ns_desc_hop
print basic info about a hop (tunnel, firewall). mostly for debugging.
hop: a hop struct as generated by (eg) ns_attach_by_URL()
doc: info about the context
- ! stdout: info about the hop */
+ ! stderr: info about the hop */
void
ns_desc_hop(_ns_hop * h, char *doc)
@@ -607,13 +689,14 @@ ns_desc_hop(_ns_hop * h, char *doc)
print basic info about a session. mostly for debugging.
sess: a session struct as generated by (eg) ns_attach_by_URL()
doc: info about the context
- ! stdout: info about the session */
+ ! stderr: info about the session */
void
ns_desc_sess(_ns_sess * sess, char *doc)
{
if (!sess) {
fprintf(stderr, NS_PREFIX "%s: ns_desc_sess called with broken pointer!\n", doc);
+ fflush(stderr);
return;
}
if (sess->where == NS_LCL)
@@ -627,8 +710,12 @@ ns_desc_sess(_ns_sess * sess, char *doc)
fprintf(stderr, "%c%s\n", sess->where == NS_LCL ? ' ' : '/', sess->rsrc);
if (sess->hop)
ns_desc_hop(sess->hop, NULL);
+ if (sess->sysrc)
+ fprintf(stderr, NS_PREFIX "info: searching for sysrc in %s\n", sess->sysrc);
if (sess->home)
- fprintf(stderr, NS_PREFIX "info: searching for rc in %s\n", sess->home);
+ fprintf(stderr, NS_PREFIX "info: searching for usrrc in %s\n", sess->home);
+ fprintf(stderr, NS_PREFIX "info: escapes set to ^%c-%c\n", sess->escape + 'A' - 1, sess->literal);
+ fflush(stderr);
}
@@ -716,6 +803,64 @@ ns_run(_ns_efuns * efuns, char *cmd)
+/* create a call line. used in ns_attach_ssh/lcl
+ tmpl the template. should contain one %s
+ dflt the default value
+ opt the user-supplied value (or NULL)
+ <- a new malloc'd string (or NULL) */
+
+char *
+ns_make_call_el(char *tmpl, char *dflt, char *opt)
+{
+ size_t l, r;
+ char *p;
+
+ if (tmpl && dflt && *tmpl && strstr(tmpl, "%s")) {
+ l = strlen(tmpl) + (opt ? strlen(opt) : strlen(dflt)) - 1L;
+ if ((p = malloc(l))) {
+ r = snprintf(p, l, tmpl, opt ? opt : dflt);
+ if ((r >= 0) && (r < l)) {
+ return p;
+ }
+ free(p);
+ }
+ }
+ return NULL;
+}
+
+
+
+char *
+ns_make_call(_ns_sess * sess)
+{
+ char *call, *tmp = NULL, *screen = NULL, *scream = NULL, *screem = NULL;
+
+ /* unless decidedly in other mode... */
+ if (sess->backend != NS_MODE_SCREEN)
+ tmp = scream = ns_make_call_el(NS_SCREAM_CALL, NS_SCREAM_OPTS, sess->rsrc);
+ if (sess->backend != NS_MODE_SCREAM)
+ tmp = screen = ns_make_call_el(NS_SCREEN_CALL, NS_SCREEN_OPTS, sess->rsrc);
+ if (sess->backend == NS_MODE_NEGOTIATE) {
+ size_t r, l = strlen(NS_SCREEM_CALL) + strlen(scream) + strlen(screen) - 3;
+ if ((screem = malloc(l))) {
+ r = snprintf(screem, l, NS_SCREEM_CALL, scream, screen);
+#ifdef NS_PARANOID
+ if ((r < 0) || (r > l)) {
+ ns_free(&screem);
+ }
+#endif
+ }
+ tmp = screem;
+ }
+ call = ns_make_call_el(NS_WRAP_CALL, tmp, NULL);
+ ns_free(&screen);
+ ns_free(&scream);
+ ns_free(&screem);
+ return call;
+}
+
+
+
/* attach a local session (using screen/scream)
sp the session
<- NS_FAIL, or the result of ns_run() */
@@ -724,28 +869,37 @@ int
ns_attach_lcl(_ns_sess ** sp)
{
_ns_sess *sess;
-#define MAXCMD 512
- char cmd[MAXCMD + 1];
- int ret;
+ char *call;
+ int ret = -1;
if (!sp || !*sp)
- return NS_FAIL;
+ return ret;
+
sess = *sp;
- ret = snprintf(cmd, MAXCMD, "%s %s", NS_SCREEN_CALL, sess->rsrc ? sess->rsrc : NS_SCREEN_OPTS);
- return (ret < 0 || ret > MAXCMD) ? NS_FAIL : ns_run(sess->efuns, cmd);
+
+ if (call = ns_make_call(sess)) {
+ char *c2 = ns_make_call_el("/bin/sh -c \"%s\"", call, NULL);
+ ns_free(&call);
+ if (c2) {
+ ret = ns_run(sess->efuns, c2);
+ ns_free(&c2);
+ }
+ }
+ return ret;
}
/* attach a remote session (using screen/scream via ssh)
sp the session
- <- NS_FAIL, or the result of ns_run() */
+ <- -1, or the result of ns_run() */
int
ns_attach_ssh(_ns_sess ** sp)
{
_ns_sess *sess;
- char cmd[MAXCMD + 1];
+ char cmd[NS_MAXCMD + 1];
+ char *call;
int ret;
if (!sp || !*sp)
@@ -753,23 +907,31 @@ ns_attach_ssh(_ns_sess ** sp)
sess = *sp;
+ call = ns_make_call(sess);
+
if (sess->hop) {
if (sess->hop->established == NS_HOP_DOWN) { /* the nightmare foe */
- ret = snprintf(cmd, MAXCMD, "%s %s -p %d -L %d:%s:%d %s@%s",
+ ret = snprintf(cmd, NS_MAXCMD, "%s %s -p %d -L %d:%s:%d %s@%s",
NS_SSH_CALL, NS_SSH_TUNNEL_OPTS,
- sess->hop->fwport, sess->hop->localport, sess->host, sess->port, sess->user, sess->hop->fw, NS_SCREEM_CALL);
- if (ret < 0 || ret > MAXCMD)
+ sess->hop->fwport, sess->hop->localport, sess->host, sess->port, sess->user, sess->hop->fw);
+ if (ret < 0 || ret > NS_MAXCMD)
return NS_FAIL;
ns_run(sess->efuns, cmd);
sleep(sess->hop->delay);
}
- ret = snprintf(cmd, MAXCMD, "%s %s -p %d %s@localhost %s",
- NS_SSH_CALL, NS_SSH_OPTS, sess->hop->localport, sess->user, NS_SCREEM_CALL);
+ ret = snprintf(cmd, NS_MAXCMD, "%s %s -p %d %s@localhost \"%s -e^%c%c\"",
+ NS_SSH_CALL, NS_SSH_OPTS, sess->hop->localport, sess->user, call, sess->escape + 'A' - 1, sess->literal);
} else {
- ret = snprintf(cmd, MAXCMD, "%s %s -p %d %s@%s %s", NS_SSH_CALL, NS_SSH_OPTS, sess->port, sess->user, sess->host, NS_SCREEM_CALL);
+ ret =
+ snprintf(cmd, NS_MAXCMD, "%s %s -p %d %s@%s \"%s -e^%c%c\"", NS_SSH_CALL, NS_SSH_OPTS, sess->port, sess->user, sess->host, call,
+ sess->escape + 'A' - 1, sess->literal);
}
-
- return (ret < 0 || ret > MAXCMD) ? NS_FAIL : ns_run(sess->efuns, cmd);
+ ns_free(&call);
+#ifdef NS_DEBUG
+ fprintf(stderr, "\n\n>>%s\n>>%s\n\n", call, cmd);
+ fflush(stderr);
+#endif
+ return (ret < 0 || ret > NS_MAXCMD) ? NS_FAIL : ns_run(sess->efuns, cmd);
}
@@ -801,6 +963,8 @@ ns_attach_by_sess(_ns_sess ** sp, int *err)
ns_desc_sess(sess, "ns_attach_by_sess()");
#endif
+ (void) ns_sess_init(sess);
+
switch (sess->where) {
case NS_LCL:
sess->fd = ns_attach_lcl(&sess);
@@ -817,10 +981,9 @@ ns_attach_by_sess(_ns_sess ** sp, int *err)
}
#ifdef NS_DEBUG
- fprintf(stderr, NS_PREFIX "ns_attach_by_sess: screen session-fd is %d\n", sess->fd);
+ fprintf(stderr, NS_PREFIX "ns_attach_by_sess: screen session-fd is %d, ^%c-%c\n", sess->fd, sess->escape + 'A' - 1, sess->literal);
#endif
- (void) ns_sess_init(sess);
return sess;
fail:
@@ -929,6 +1092,7 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
if ((x = ns_parse_esc(&r)) && (y = ns_parse_esc(&r))) {
sess->escape = x;
sess->literal = y;
+ sess->escdef = NS_ESC_CMDLINE;
}
} else if (*r == 'c') { /* alt screenrc */
char *rc, *rx;
@@ -991,20 +1155,37 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
goto fail;
} else if (pwe && strcmp(pwe->pw_name, sess->user)) { /* user!=current_user */
sess->where = NS_SU;
- if (!(pwe = getpwnam(sess->user))) {
+ if (!(pwe = getpwnam(sess->user)) && !sess->host && !sess->port) {
*err = NS_UNKNOWN_USER;
goto fail;
}
}
- if (getenv("SCREENRC")) {
+ if (getenv("SYSSCREENRC")) { /* $SYSSCREENRC */
+ if (!(sess->sysrc = strdup(getenv("SCREENRC"))))
+ goto fail;
+ } else {
+ char *loc[] = { "/usr/local/etc/screenrc", /* official */
+ "/etc/screenrc", /* actual (on SuSE) */
+ "/usr/etc/screenrc",
+ "/opt/etc/screenrc"
+ };
+ int n, nloc = sizeof(loc) / sizeof(char *);
+ for (n = 0; n < nloc; n++)
+ if (!access(loc[n], R_OK)) {
+ if (!(sess->sysrc = strdup(loc[n])))
+ goto fail;
+ n = nloc;
+ }
+ }
+
+ if (getenv("SCREENRC")) { /* $SCREENRC */
sess->home = strdup(getenv("SCREENRC"));
- } else if (pwe && !sess->home) {
+ } else if (pwe && !sess->home) { /* ~/.screenrc */
if ((sess->home = malloc(strlen(pwe->pw_dir) + strlen(NS_SCREEN_RC) + 2)))
sprintf(sess->home, "%s/%s", pwe->pw_dir, NS_SCREEN_RC);
- else
- goto fail;
- }
+ } else
+ goto fail;
if (!sess->host) { /* no host */
if (!(sess->host = strdup("localhost")))
@@ -1020,7 +1201,7 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
sess->backend = NS_MODE_NEGOTIATE;
if (!sess->proto) {
- if (!(sess->proto = strdup("scream")))
+ if (!(sess->proto = strdup("screXX")))
goto fail;
} else if (!strcmp(sess->proto, "screen"))
sess->backend = NS_MODE_SCREEN;
@@ -1061,7 +1242,9 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
int
ns_detach(_ns_sess ** sess)
{
+#ifdef NS_DEBUG
ns_desc_sess(*sess, "ns_detach");
+#endif
(void) ns_dst_sess(sess);
return NS_SUCC;
}
@@ -1181,6 +1364,15 @@ ns_register_tab(_ns_efuns * efuns, int (*inp_tab) (void *, char *[], int, char *
+/* function that will do whatever while waiting */
+void
+ns_register_fun(_ns_efuns * efuns, int (*inp_fun) (void *, int))
+{
+ efuns->waitstate = inp_fun;
+}
+
+
+
/* get callbacks. at least one of session and display must be non-NULL.
s session, or NULL. if NULL, will be initialized from d->sess
d display, or NULL. if NULL, will be initialized from s->curr.
@@ -1208,20 +1400,6 @@ ns_get_efuns(_ns_sess * s, _ns_disp * d)
-/* test if we have a valid callback for function-type "e".
- !p a variable of the "_ns_efuns *" type. will contain a pointer to
- an efun struct containing a function pointer to the requested function
- if such a struct exists, or NULL, if it doesn't exist
- s a variable of the "_ns_sess *" type, or NULL (see ns_get_efuns())
- d a variable of the "_nd_disp *" type, or NULL (see ns_get_efuns())
- e the name of an element of "_ns_efuns"
- !<- conditional execution of next (compound-) statement (which would
- normally be (p)->(e)(...), the call of the function e).
- */
-#define NS_IF_EFUN_EXISTS(p,s,d,e) if(((p)=ns_get_efuns((s),(d)))&&((p)->e))
-
-
-
/***************************************************************************/
/* display-handling */
/********************/
@@ -1282,10 +1460,8 @@ disp_fetch_or_make(_ns_sess * s, int n)
d->sess = s; /* note session on display */
-#if 1
if (!d->sess->curr) /* note as current on session if first display */
d->sess->curr = d;
-#endif
return d;
}
@@ -1407,11 +1583,13 @@ ns_inp_tab(void *xd, char *b, size_t l, size_t m)
"writelock", "xoff", "xon", "zombie"
};
+ _ns_efuns *efuns;
_ns_sess *s = (_ns_sess *) xd;
int nsc = sizeof(sc) / sizeof(char *);
- if (s->efuns->inp_tab)
- return s->efuns->inp_tab((void *) s, sc, nsc, b, l, m) < 0 ? NS_FAIL : NS_SUCC;
+ if (NS_EFUN_EXISTS(efuns, s, NULL, inp_tab)) {
+ return efuns->inp_tab((void *) s, sc, nsc, b, l, m) < 0 ? NS_FAIL : NS_SUCC;
+ }
fprintf(stderr, NS_PREFIX "ns_screen_command: sess->efuns->inp_tab not set!\n");
return NS_EFUN_NOT_SET;
@@ -1470,12 +1648,13 @@ ns_parse_esc(char **x)
/* ns_parse_screen_cmd
parse a command the user intends to send to the screen program,
either via .screenrc or using ^A:
- s the affected (current) session. s->current should be set.
- p the command
+ s the affected (current) session. s->current should be set.
+ p the command
+ whence which parsing stage (screenrc, interactive, ...)
<- error code */
int
-ns_parse_screen_cmd(_ns_sess * s, char *p)
+ns_parse_screen_cmd(_ns_sess * s, char *p, int whence)
{
char *p2;
long v1 = -1;
@@ -1492,21 +1671,33 @@ ns_parse_screen_cmd(_ns_sess * s, char *p)
v1 = -1;
}
#define IS_CMD(b) (strncasecmp(p,b,strlen(b))==0)
- if (!p2)
+ if (!p2) {
fprintf(stderr, NS_PREFIX "screenrc: ignoring \"%s\" without an argument...\n", p);
- else if (IS_CMD("defescape"))
+ /* must return success so it's fowarded to screen in interactive mode.
+ that way, the user can read the original reply instead of a fake
+ one from us. */
+ return NS_SUCC;
+ } else if (IS_CMD("defescape"))
fprintf(stderr, NS_PREFIX "screenrc: ignoring \"defescape\", did you mean \"escape\"?\n");
- else if (IS_CMD("defhstatus") || IS_CMD("hardstatus") || IS_CMD("echo") ||
- IS_CMD("colon") || IS_CMD("nethack") ||
- IS_CMD("info") || IS_CMD("time") || IS_CMD("title") || IS_CMD("wall") ||
- IS_CMD("lastmsg") || IS_CMD("msgwait") || IS_CMD("msgminwait"))
+ else if (IS_CMD("defhstatus") || IS_CMD("hardstatus") || IS_CMD("echo") || IS_CMD("colon") || IS_CMD("wall") ||
+#ifdef NS_PARANOID
+ IS_CMD("nethack") ||
+#endif
+ IS_CMD("info") || IS_CMD("time") || IS_CMD("title") || IS_CMD("lastmsg") || IS_CMD("msgwait") || IS_CMD("msgminwait")) {
fprintf(stderr, NS_PREFIX "screenrc: ignoring \"%s\", not applicable...\n", p);
- else if (IS_CMD("escape")) {
+ return NS_NOT_ALLOWED;
+ } else if (IS_CMD("escape")) {
char x = 0, y = 0;
if ((x = ns_parse_esc(&p2)) && (y = ns_parse_esc(&p2))) {
- s->escape = x;
- s->literal = y;
- return NS_SUCC;
+ if (s->escdef == NS_ESC_CMDLINE) {
+ fprintf(stderr, NS_PREFIX "screenrc: ignoring \"escape\"; overridden on command-line...\n", x, y);
+ return NS_NOT_ALLOWED;
+ } else {
+ s->escape = x;
+ s->literal = y;
+ s->escdef = whence;
+ return NS_SUCC;
+ }
} else
fprintf(stderr, NS_PREFIX "screenrc: ignoring \"escape\" because of invalid arguments %o %o...\n", x, y);
} else if (IS_CMD("defscrollback")) {
@@ -1570,8 +1761,11 @@ ns_parse_screen_key(_ns_sess * s, char c)
case NS_SCREEN_CMD: /* send command (statement) to screen server */
(void) ns_inp_dial((void *) s, "Enter a command to send to the \"screen\" program", 64, &i, ns_inp_tab);
if (i) {
- ret = ns_screen_xcommand(s, c, i);
- (void) ns_parse_screen_cmd(s, i);
+ if ((ret = ns_parse_screen_cmd(s, i, NS_ESC_INTERACTIVE)) == NS_SUCC) {
+ ret = ns_screen_xcommand(s, c, i);
+ } else if (ret == NS_NOT_ALLOWED) {
+ menu_dial(NULL, "Sorry, David, I cannot allow that.", 0, NULL, NULL);
+ }
free(i);
}
break;
@@ -1600,24 +1794,72 @@ ns_parse_screen_key(_ns_sess * s, char c)
+/* ns_parse_screen_interactive
+ parse a whole string that may contain screen-escapes that should be
+ handled interactively (that should open dialog boxes etc.).
+ this will normally be called by menus, buttons etc. that want to send
+ input to the add without generating X events for the keystrokes (real
+ keystrokes do not come through here; the keyboard-handler should call
+ ns_parse_screen_key() directly when it sees the session's escape-char).
+ s the session in question
+ c the string to parse
+ <- error code */
+
+int
+ns_parse_screen_interactive(_ns_sess * sess, char *c)
+{
+ char *s, *p, *o;
+
+ if (!c || !*c)
+ return NS_FAIL;
+#ifdef NS_PARANOID
+ if (!(s = o = strdup(c)))
+ return NS_FAIL;
+#else
+ s = c;
+#endif
+
+ p = s;
+
+ while ((p = strchr(s, NS_SCREEN_ESCAPE))) {
+ *p = '\0';
+ (void) ns_screen_command(sess, s);
+ *p = NS_SCREEN_ESCAPE;
+ if (*(++p))
+ ns_parse_screen_key(sess, *(p++));
+ s = p;
+ }
+ (void) ns_screen_command(sess, s);
+
+#ifdef NS_PARANOID
+ free(o);
+#endif
+
+ return NS_SUCC;
+}
+
+
+
/* ns_parse_screenrc -- read the user's screenrc (if we can find it),
parse it (we need to know if she changes the escapes etc.), and
send it to the actually screen
- s the session in question
- <- error code */
+ s the session
+ fn name of the file in question
+ whence which screenrc are we in?
+ <- error code */
int
-ns_parse_screenrc(_ns_sess * s)
+ns_parse_screenrc(_ns_sess * s, char *fn, int whence)
{
int fd = -1;
char *rc = NULL;
char _e = '\0', _l = '\0', *esc = NULL;
- if (s->home) {
+ if (fn) {
struct stat st;
ssize_t rd = 0;
- if ((fd = open(s->home, 0)) >= 0) {
+ if ((fd = open(fn, 0)) >= 0) {
if (!fstat(fd, &st)) {
if ((rc = malloc(st.st_size + 1))) {
char *p;
@@ -1655,7 +1897,7 @@ ns_parse_screenrc(_ns_sess * s)
}
if (strlen(p)) /* any commands in line? */
- ns_parse_screen_cmd(s, p);
+ ns_parse_screen_cmd(s, p, whence);
p = n; /* done, next line */
}
free(rc);
@@ -1705,8 +1947,9 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
type = (strlen(p) > 1) ? NS_SCREEN_STATUS : NS_SCREEN_ST_CLR;
if (type == NS_SCREEN_ST_CLR) {
- NS_IF_EFUN_EXISTS(efuns, screen, NULL, err_msg)
+ if (NS_EFUN_EXISTS(efuns, screen, NULL, err_msg)) {
ret = efuns->err_msg(NULL, type, "");
+ }
}
/* a screen display can disappear because the program in it dies, or
because we explicitly ask screen to kill the display. in the latter
@@ -1723,15 +1966,19 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
p = NULL;
} else if (!strcmp(p, "New screen...") || !strncmp(p, "msgwait", strlen("msgwait")) || !strncmp(p, "msgminwait", strlen("msgminwait")))
p = NULL;
+#ifndef NS_PARANOID
+ /* FIXME. */
else if (sscanf(p, NS_SCREEN_VERSION, &p3, &ma, &mi, &mu, &p2, &d) == 6) {
if (!strcmp("en", p3))
screen->backend = NS_MODE_SCREEN;
else if (!strcmp("am", p3))
screen->backend = NS_MODE_SCREAM;
-#ifdef NS_DEBUG
+# ifdef NS_DEBUG
fprintf(stderr, NS_PREFIX "ns_parse_screen_msg: scre%s %d.%2d.%2d %s a/o %s\n", p3, ma, mi, mu, p2, d);
+# endif
+ }
#endif
- } else if (!strcmp(p, NS_SCREEN_NO_DEBUG))
+ else if (!strcmp(p, NS_SCREEN_NO_DEBUG))
p = "debug info was not compiled into \"screen\"...";
else if (!strncmp(p, NS_SCREEN_DK_CMD, strlen(NS_SCREEN_DK_CMD))) {
p[strlen(p) - 1] = '\0';
@@ -1739,8 +1986,9 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
p = "unknown screen statement ignored";
}
if (p) { /* status. send to status-line or dialog or whatever */
- NS_IF_EFUN_EXISTS(efuns, screen, NULL, err_msg)
+ if (NS_EFUN_EXISTS(efuns, screen, NULL, err_msg)) {
ret = efuns->err_msg(NULL, type, p);
+ }
}
return ret;
}
@@ -1788,7 +2036,7 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
if (!screen || !p || !width)
return NS_FAIL;
- if (!force)
+ if (!force && screen->timestamp)
return NS_SUCC;
if (p = strdup(p)) {
@@ -1803,17 +2051,26 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
fprintf(stderr, NS_PREFIX "parse_screen: screen sends ::%s::\n", p);
#endif
-#ifdef NS_PARANOID_
if (strlen(p) < 2) { /* special case: display 0 */
disp = screen->dsps; /* might not get a status-line in d0! */
if (disp && !(disp->flags & NS_SCREAM_CURR)) { /* flags need updating */
disp->flags |= NS_SCREAM_CURR; /* set flag to avoid calling inp_text */
ret = ns_upd_stat(screen);
- } /* more than once */
+ } /* more than once */
+ else if (!screen->timestamp) {
+ screen->timestamp = time(NULL);
+ if (screen->delay > 0) {
+ if (NS_EFUN_EXISTS(efuns, screen, NULL, waitstate)) {
+ ret = efuns->waitstate(NULL, screen->delay * 1000);
+ } else {
+ sleep(screen->delay);
+ }
+ }
+ (void) ns_screen_command(screen, NS_SCREEN_INIT);
+ }
free(p);
return ret;
}
-#endif
p3 = p;
while (isspace(*p3)) /* skip left padding */
@@ -1876,8 +2133,9 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
fprintf(stderr, NS_PREFIX "parse_screen: out of memory in new_display(%d)\n", n);
ret = NS_FAIL;
} else {
- NS_IF_EFUN_EXISTS(efuns, screen, NULL, ins_disp)
+ if (NS_EFUN_EXISTS(efuns, screen, NULL, ins_disp)) {
ret = efuns->ins_disp(screen->userdef, pd[r].real - 1, disp->name);
+ }
}
} else if ((tmp = strcmp(disp->name, pd[r].name)) || /* upd display */
(disp->flags != pd[r].flags)) {
@@ -1891,8 +2149,9 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
if (pd[r].flags & NS_SCREAM_CURR)
disp->sess->curr = disp;
disp->flags = pd[r].flags & NS_SCREAM_MASK;
- NS_IF_EFUN_EXISTS(efuns, screen, NULL, upd_disp)
+ if (NS_EFUN_EXISTS(efuns, screen, NULL, upd_disp)) {
ret = efuns->upd_disp(screen->userdef, r, disp->flags, disp->name);
+ }
}
/* remove any displays from list that have disappeared
@@ -1904,8 +2163,9 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
fprintf(stderr, NS_PREFIX "parse_screen: remove expired middle %d \"%s\"...\n", d3->index, d3->name);
#endif
d4 = d3->prvs;
- NS_IF_EFUN_EXISTS(efuns, screen, NULL, del_disp)
+ if (NS_EFUN_EXISTS(efuns, screen, NULL, del_disp)) {
ret = efuns->del_disp(screen->userdef, disp_get_real_by_screen(screen, d3->index));
+ }
disp_kill(d3);
d3 = d4;
}
@@ -1945,8 +2205,9 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
if (d2->sess->curr == d2)
d2->sess->curr = d3;
disp = disp->next;
- NS_IF_EFUN_EXISTS(efuns, screen, NULL, del_disp)
+ if (NS_EFUN_EXISTS(efuns, screen, NULL, del_disp)) {
ret = efuns->del_disp(screen->userdef, disp_get_real_by_screen(screen, d2->index));
+ }
disp_kill(d2);
}
d3->next = NULL;
@@ -1963,26 +2224,12 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
we could send it before entering this function for the first time,
but that would break if escapes or screenrc were set from the
command-line. don't ask. */
-#ifdef NS_DEBUG
- if (!screen)
- fprintf(stderr, NS_PREFIX "parse_screen: session went away!?\n\n CONDITION RED!\n CONDITION RED!\n DANGER WILL ROBINSON!!!\n\n");
- else
-#endif
- {
- if (!screen->timestamp) {
- screen->timestamp = time(NULL);
-#ifdef NS_DEBUG
- fprintf(stderr, NS_PREFIX "parse_screen: sending NS_SCREEN_INIT with prefix %d...\n", screen->escape);
-#endif
- ret = ns_screen_command(screen, NS_SCREEN_INIT);
- }
#if (NS_SCREEN_UPD_FREQ>0)
- else if ((t2 - screen->timestamp) > NS_SCREEN_UPD_FREQ) {
- (void) ns_upd_stat(screen);
- screen->timestamp = t2;
- }
-#endif
+ if ((t2 - screen->timestamp) > NS_SCREEN_UPD_FREQ) {
+ (void) ns_upd_stat(screen);
+ screen->timestamp = t2;
}
+#endif
return ret;
}
diff --git a/src/menus.c b/src/menus.c
index 641e7d3..a559ef7 100644
--- a/src/menus.c
+++ b/src/menus.c
@@ -43,6 +43,9 @@ static const char cvs_ident[] = "$Id$";
#include "script.h"
#include "term.h"
#include "windows.h"
+#ifdef ESCREEN
+# include "screamcfg.h"
+#endif
menulist_t *menu_list = NULL;
#ifndef ESCREEN
@@ -721,7 +724,7 @@ menuitem_delete(menuitem_t *item)
if (item->icon) {
free_simage(item->icon);
}
- if (item->type == MENUITEM_STRING || item->type == MENUITEM_ECHO) {
+ if (item->type == MENUITEM_STRING || item->type == MENUITEM_LITERAL || item->type == MENUITEM_ECHO) {
FREE(item->action.string);
} else if (item->type == MENUITEM_SCRIPT) {
FREE(item->action.script);
@@ -779,9 +782,11 @@ menuitem_set_action(menuitem_t *item, unsigned char type, char *action)
break;
case MENUITEM_STRING:
case MENUITEM_ECHO:
+ case MENUITEM_LITERAL:
item->action.string = (char *) MALLOC(strlen(action) + 2);
strcpy(item->action.string, action);
- parse_escaped_string(item->action.string);
+ if (type != MENUITEM_LITERAL)
+ parse_escaped_string(item->action.string);
break;
default:
break;
@@ -1219,20 +1224,14 @@ menu_action(menuitem_t *item)
case MENUITEM_ECHO:
#ifdef ESCREEN
if (TermWin.screen_mode && TermWin.screen) { /* translate escapes */
-# ifdef NS_DEBUG
- {
- char *p = item->action.string;
- fprintf(stderr, NS_PREFIX "::menu_action: ");
- while (*p) {
- if (*p < ' ')
- fprintf(stderr, "^%c", *p - 1 + 'A');
- else
- fprintf(stderr, "%c", *p);
- p++;
- }
- fputs("\n", stderr);
- }
-# endif
+ ns_parse_screen_interactive(TermWin.screen, item->action.string);
+ } else
+#endif
+ tt_write((unsigned char *) item->action.string, strlen(item->action.string));
+ break;
+ case MENUITEM_LITERAL:
+#ifdef ESCREEN
+ if (TermWin.screen_mode && TermWin.screen) { /* translate escapes */
(void) ns_screen_command(TermWin.screen, item->action.string);
} else
#endif
diff --git a/src/menus.h b/src/menus.h
index 5f461ee..e628888 100644
--- a/src/menus.h
+++ b/src/menus.h
@@ -35,6 +35,7 @@
#define MENUITEM_ECHO (1UL << 3)
#define MENUITEM_SCRIPT (1UL << 4)
#define MENUITEM_ALERT (1UL << 5)
+#define MENUITEM_LITERAL (1UL << 6)
#define MENU_STATE_IS_MAPPED (1UL << 0)
#define MENU_STATE_IS_CURRENT (1UL << 1)
diff --git a/src/options.c b/src/options.c
index f3ed570..3702292 100644
--- a/src/options.c
+++ b/src/options.c
@@ -139,6 +139,7 @@ char *rs_config_file = NULL;
#ifdef ESCREEN
char *rs_url = NULL;
char *rs_hop = NULL;
+int rs_delay = -1;
#endif
unsigned int rs_line_space = 0;
unsigned int rs_meta_mod = 0, rs_alt_mod = 0, rs_numlock_mod = 0;
@@ -168,6 +169,7 @@ static const struct {
#ifdef ESCREEN
OPT_STR('U', "URL", "an URL pointing at a screen-session to pick up", &rs_url),
OPT_STR('Z', "[lclport:]fw[:fwport]", "the destination machine -U can only be seen by the firewall fw. tunnel.", &rs_hop),
+ OPT_INT('z', "delay", "initial delay in seconds", &rs_delay),
#endif
#if DEBUG <= 0
OPT_ILONG("debug", "level of debugging information to show (support not compiled in)", &DEBUG_LEVEL),
@@ -1566,10 +1568,12 @@ parse_toggles(char *buff, void *state)
} else if (!BEG_STRCASECMP(buff, "buttonbar")) {
if (bool_val) {
- FOREACH_BUTTONBAR(bbar_set_visible(bbar, 1););
+ FOREACH_BUTTONBAR(bbar_set_visible(bbar, 1);
+ );
rs_buttonbars = 1; /* Reset for future use. */
} else {
- FOREACH_BUTTONBAR(bbar_set_visible(bbar, 0););
+ FOREACH_BUTTONBAR(bbar_set_visible(bbar, 0);
+ );
rs_buttonbars = 1; /* Reset for future use. */
}
@@ -3055,9 +3059,11 @@ post_parse(void)
specified. If specified, it will either become 3 (on) or 0 (off). */
if (rs_buttonbars != 1) {
if (rs_buttonbars) {
- FOREACH_BUTTONBAR(bbar_set_visible(bbar, 1););
+ FOREACH_BUTTONBAR(bbar_set_visible(bbar, 1);
+ );
} else {
- FOREACH_BUTTONBAR(bbar_set_visible(bbar, 0););
+ FOREACH_BUTTONBAR(bbar_set_visible(bbar, 0);
+ );
}
rs_buttonbars = 1; /* Reset for future use. */
}
diff --git a/src/options.h b/src/options.h
index 1d01a5c..9653a1d 100644
--- a/src/options.h
+++ b/src/options.h
@@ -137,6 +137,7 @@ extern char *rs_config_file;
#ifdef ESCREEN
extern char *rs_url;
extern char *rs_hop;
+extern int rs_delay;
#endif
extern unsigned int rs_line_space;
extern unsigned int rs_meta_mod, rs_alt_mod, rs_numlock_mod;
diff --git a/src/pixmap.c b/src/pixmap.c
index 9128ab3..353e748 100644
--- a/src/pixmap.c
+++ b/src/pixmap.c
@@ -614,8 +614,6 @@ check_image_ipc(unsigned char reset)
print_error("ImageClass \"%s\" is not defined in Enlightenment. Disallowing \"auto\" mode for this image.\n", iclass);
image_mode_fallback(i);
} else if (strstr(reply, "Error")) {
- print_error("Looks like this version of Enlightenment doesn't support the IPC "
- "commands I need. Disallowing \"auto\" mode for all images.\n");
/* *INDENT-OFF* */
FOREACH_IMAGE(
if (image_mode_is(idx, MODE_AUTO)) {
@@ -630,6 +628,8 @@ check_image_ipc(unsigned char reset)
}
);
/* *INDENT-ON* */
+ print_error("Looks like this version of Enlightenment doesn't support the IPC "
+ "commands I need. Disallowing \"auto\" mode for all images.\n");
FREE(reply);
checked = 2;
return 0;
@@ -678,8 +678,8 @@ create_trans_pixmap(simage_t *simg, unsigned char which, Drawable d, int x, int
XSetFillStyle(Xdisplay, gc, FillTiled);
XFillRectangle(Xdisplay, p, gc, 0, 0, width, height);
} else {
- D_PIXMAP(("Copying %hux%hu rectangle at %d, %d from %ux%u desktop pixmap 0x%08x onto p.\n", width, height, x, y, pw, ph,
- desktop_pixmap));
+ D_PIXMAP(("Copying %hux%hu rectangle at %d, %d from %ux%u desktop pixmap 0x%08x onto p.\n", width, height, x, y, pw,
+ ph, desktop_pixmap));
XCopyArea(Xdisplay, desktop_pixmap, p, gc, x, y, width, height, 0, 0);
}
if ((which != image_bg || (image_toggles & IMOPT_ITRANS) || images[image_bg].current != images[image_bg].norm)
@@ -687,8 +687,8 @@ create_trans_pixmap(simage_t *simg, unsigned char which, Drawable d, int x, int
colormod_trans(p, simg->iml, gc, width, height);
}
if (simg->iml->bevel != NULL) {
- D_PIXMAP(("Beveling pixmap 0x%08x with edges %d, %d, %d, %d\n", p, simg->iml->bevel->edges->left, simg->iml->bevel->edges->top,
- simg->iml->bevel->edges->right, simg->iml->bevel->edges->bottom));
+ D_PIXMAP(("Beveling pixmap 0x%08x with edges %d, %d, %d, %d\n", p, simg->iml->bevel->edges->left,
+ simg->iml->bevel->edges->top, simg->iml->bevel->edges->right, simg->iml->bevel->edges->bottom));
bevel_pixmap(p, width, height, simg->iml->bevel->edges, simg->iml->bevel->up);
}
}
@@ -706,12 +706,10 @@ create_viewport_pixmap(simage_t *simg, Drawable d, int x, int y, unsigned short
Pixmap p = None, mask = None;
GC gc;
Screen *scr;
-
D_PIXMAP(("create_viewport_pixmap(%8p, 0x%08x, %d, %d, %hu, %hu) called.\n", simg, d, x, y, width, height));
scr = ScreenOfDisplay(Xdisplay, Xscreen);
if (!scr)
return None;
-
if (desktop_window == None) {
get_desktop_window();
if (desktop_window == None) {
@@ -721,7 +719,6 @@ create_viewport_pixmap(simage_t *simg, Drawable d, int x, int y, unsigned short
}
if (viewport_pixmap == None) {
imlib_t *tmp_iml = images[image_bg].current->iml;
-
imlib_context_set_image(tmp_iml->im);
imlib_context_set_drawable(d);
imlib_image_set_has_alpha(0);
@@ -736,7 +733,6 @@ create_viewport_pixmap(simage_t *simg, Drawable d, int x, int y, unsigned short
imlib_image_set_border(&bord_none);
}
imlib_context_set_color_modifier((tmp_iml->mod && tmp_iml->mod->imlib_mod) ? tmp_iml->mod->imlib_mod : NULL);
-
if ((images[image_bg].current->pmap->w > 0) || (images[image_bg].current->pmap->op & OP_SCALE)) {
D_PIXMAP(("Scaling image to %dx%d\n", scr->width, scr->height));
imlib_render_pixmaps_for_whole_image_at_size(&viewport_pixmap, &mask, scr->width, scr->height);
@@ -786,23 +782,19 @@ create_viewport_pixmap(simage_t *simg, Drawable d, int x, int y, unsigned short
}
void
-paste_simage(simage_t *simg, unsigned char which, Window win, Drawable d, unsigned short x, unsigned short y, unsigned short w,
- unsigned short h)
+paste_simage(simage_t *simg, unsigned char which, Window win, Drawable d, unsigned short x, unsigned short y,
+ unsigned short w, unsigned short h)
{
Pixmap pmap = None, mask = None;
GC gc;
-
ASSERT(simg != NULL);
REQUIRE(d != None);
-
- D_PIXMAP(("paste_simage(%8p, %s, 0x%08x, 0x%08x, %hd, %hd, %hd, %hd) called.\n", simg, get_image_type(which), (int) win, (int) d, x, y,
- w, h));
-
+ D_PIXMAP(("paste_simage(%8p, %s, 0x%08x, 0x%08x, %hd, %hd, %hd, %hd) called.\n", simg, get_image_type(which),
+ (int) win, (int) d, x, y, w, h));
if (which != image_max) {
if (image_mode_is(which, MODE_AUTO) && image_mode_is(which, ALLOW_AUTO)) {
char buff[255], *reply;
const char *iclass, *state;
-
check_image_ipc(0);
if (image_mode_is(which, MODE_AUTO)) {
iclass = get_iclass_name(which);
@@ -814,7 +806,6 @@ paste_simage(simage_t *simg, unsigned char which, Window win, Drawable d, unsign
state = "normal";
}
D_PIXMAP((" -> iclass == \"%s\", state == \"%s\"\n", NONULL(iclass), NONULL(state)));
-
if (iclass) {
snprintf(buff, sizeof(buff), "imageclass %s apply_copy 0x%x %s %hd %hd", iclass, (int) d, state, w, h);
reply = enl_send_and_wait(buff);
@@ -848,7 +839,6 @@ paste_simage(simage_t *simg, unsigned char which, Window win, Drawable d, unsign
}
} else if (image_mode_is(which, MODE_TRANS) && image_mode_is(which, ALLOW_TRANS)) {
Pixmap p;
-
gc = LIBAST_X_CREATE_GC(0, NULL);
p = create_trans_pixmap(simg, which, win, x, y, w, h);
if (p != None) {
@@ -860,7 +850,6 @@ paste_simage(simage_t *simg, unsigned char which, Window win, Drawable d, unsign
LIBAST_X_FREE_GC(gc);
} else if (image_mode_is(which, MODE_VIEWPORT) && image_mode_is(which, ALLOW_VIEWPORT)) {
Pixmap p;
-
gc = LIBAST_X_CREATE_GC(0, NULL);
p = create_viewport_pixmap(simg, win, x, y, w, h);
if (simg->iml->bevel != NULL) {
@@ -884,7 +873,6 @@ paste_simage(simage_t *simg, unsigned char which, Window win, Drawable d, unsign
imlib_image_set_border(&bord_none);
}
imlib_context_set_color_modifier((simg->iml->mod && simg->iml->mod->imlib_mod) ? simg->iml->mod->imlib_mod : NULL);
-
if (w == imlib_image_get_width() && h == imlib_image_get_height()) {
imlib_render_pixmaps_for_whole_image(&pmap, &mask);
} else {
@@ -962,16 +950,13 @@ copy_buffer_pixmap(unsigned char mode, unsigned long fill, unsigned short width,
{
GC gc;
XGCValues gcvalue;
-
ASSERT(buffer_pixmap == None);
buffer_pixmap = LIBAST_X_CREATE_PIXMAP(width, height);
gcvalue.foreground = (Pixel) fill;
gc = LIBAST_X_CREATE_GC(GCForeground, &gcvalue);
XSetGraphicsExposures(Xdisplay, gc, False);
-
if (mode == MODE_SOLID) {
simage_t *simg;
-
simg = images[image_bg].current;
if (simg->pmap->pixmap) {
LIBAST_X_FREE_PIXMAP(simg->pmap->pixmap);
@@ -998,20 +983,16 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
unsigned short rendered = 0;
unsigned short xscaled = 0, yscaled = 0;
#endif
-
scr = ScreenOfDisplay(Xdisplay, Xscreen);
if (!scr)
return;
-
ASSERT(simg != NULL);
ASSERT(simg->iml != NULL);
ASSERT(simg->pmap != NULL);
REQUIRE(win != None);
-
- D_PIXMAP(("Rendering simg->iml->im %8p (%s) at %hux%hu onto window 0x%08x\n", simg->iml->im, get_image_type(which), width, height,
- win));
+ D_PIXMAP(("Rendering simg->iml->im %8p (%s) at %hux%hu onto window 0x%08x\n", simg->iml->im, get_image_type(which),
+ width, height, win));
D_PIXMAP(("Image mode is 0x%02x\n", images[which].mode));
-
#ifdef PIXMAP_SUPPORT
if ((which == image_bg) && image_mode_is(image_bg, MODE_VIEWPORT)) {
width = scr->width;
@@ -1020,11 +1001,9 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
#endif
if (!(width) || !(height))
return;
-
gcvalue.foreground = gcvalue.background = PixColors[bgColor];
gc = LIBAST_X_CREATE_GC(GCForeground | GCBackground, &gcvalue);
pixmap = simg->pmap->pixmap; /* Save this for later */
-
if ((which == image_bg) && (buffer_pixmap != None)) {
LIBAST_X_FREE_PIXMAP(buffer_pixmap);
buffer_pixmap = None;
@@ -1033,7 +1012,6 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
if ((images[which].mode & MODE_AUTO) && (images[which].mode & ALLOW_AUTO)) {
char buff[255];
const char *iclass, *state;
-
check_image_ipc(0);
if (image_mode_is(which, MODE_AUTO)) {
iclass = get_iclass_name(which);
@@ -1047,7 +1025,6 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
if (iclass) {
if (renderop & RENDER_FORCE_PIXMAP) {
char *reply;
-
snprintf(buff, sizeof(buff), "imageclass %s apply_copy 0x%x %s %hd %hd", iclass, (int) win, state, width, height);
reply = enl_send_and_wait(buff);
if (strstr(reply, "Error")) {
@@ -1057,7 +1034,6 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
FREE(reply);
} else {
Pixmap pmap, mask;
-
pmap = (Pixmap) strtoul(reply, (char **) NULL, 0);
mask = (Pixmap) strtoul(get_pword(2, reply), (char **) NULL, 0);
FREE(reply);
@@ -1118,7 +1094,6 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
}
} else if (image_mode_is(which, MODE_VIEWPORT) && image_mode_is(which, ALLOW_VIEWPORT)) {
Pixmap p;
-
D_PIXMAP(("Viewport mode enabled. viewport_pixmap == 0x%08x and simg->pmap->pixmap == 0x%08x\n", viewport_pixmap,
simg->pmap->pixmap));
p = create_viewport_pixmap(simg, win, 0, 0, width, height);
@@ -1151,7 +1126,6 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
int h = simg->pmap->h;
int x = simg->pmap->x;
int y = simg->pmap->y;
-
imlib_context_set_image(simg->iml->im);
imlib_context_set_drawable(win);
imlib_context_set_anti_alias(1);
@@ -1160,10 +1134,8 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
xsize = imlib_image_get_width();
ysize = imlib_image_get_height();
D_PIXMAP(("w == %d, h == %d, x == %d, y == %d, xsize == %d, ysize == %d\n", w, h, x, y, xsize, ysize));
-
if ((simg->pmap->op & OP_PROPSCALE) && w && h) {
double x_ratio, y_ratio;
-
x_ratio = ((double) width) / ((double) xsize);
y_ratio = ((double) height) / ((double) ysize);
if (x_ratio > 1) {
@@ -1195,7 +1167,6 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
xpos = (short) ((width - xscaled) * ((float) x / 100.0));
ypos = (short) ((height - yscaled) * ((float) y / 100.0));
D_PIXMAP(("Calculated scaled size as %hux%hu with origin at (%hd, %hd)\n", xscaled, yscaled, xpos, ypos));
-
if (simg->iml->border) {
D_PIXMAP(("Setting image border: { left [%d], right [%d], top [%d], bottom [%d] }\n",
simg->iml->border->left, simg->iml->border->right, simg->iml->border->top, simg->iml->border->bottom));
@@ -1204,7 +1175,6 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
imlib_image_set_border(&bord_none);
}
imlib_context_set_color_modifier((simg->iml->mod && simg->iml->mod->imlib_mod) ? simg->iml->mod->imlib_mod : NULL);
-
D_PIXMAP(("Rendering image simg->iml->im [%8p] to %hdx%hd pixmap\n", simg->iml->im, xscaled, yscaled));
imlib_render_pixmaps_for_whole_image_at_size(&simg->pmap->pixmap, &simg->pmap->mask, xscaled, yscaled);
rendered = 1;
@@ -1215,10 +1185,8 @@ render_simage(simage_t *simg, Window win, unsigned short width, unsigned short h
}
if (xscaled != width || yscaled != height || xpos != 0 || ypos != 0) {
unsigned char single;
-
/* This tells us if we have a single, non-tiled image which does not entirely fill the window */
single = ((xscaled < width || yscaled < height) && !(simg->pmap->op & OP_TILE)) ? 1 : 0;
-
pixmap = simg->pmap->pixmap;
simg->pmap->pixmap = LIBAST_X_CREATE_PIXMAP(width, height);
if (single) {
@@ -1307,7 +1275,6 @@ search_path(const char *pathlist, const char *file)
const char *path;
int maxpath, len;
struct stat fst;
-
if (!pathlist || !file) { /* If either one is NULL, there really isn't much point in going on.... */
return ((const char *) NULL);
}
@@ -1337,16 +1304,13 @@ search_path(const char *pathlist, const char *file)
if ((p = strchr(file, '@')) == NULL)
p = strchr(file, '\0');
len = (p - file);
-
/* leave room for an extra '/' and trailing '\0' */
maxpath = sizeof(name) - (len + 2);
if (maxpath <= 0)
return NULL;
-
/* check if we can find it now */
strncpy(name, file, len);
name[len] = '\0';
-
D_OPTIONS(("Checking for file \"%s\"\n", name));
if (!access(name, R_OK)) {
if (stat(name, &fst)) {
@@ -1364,21 +1328,17 @@ search_path(const char *pathlist, const char *file)
}
for (path = pathlist; path != NULL && *path != '\0'; path = p) {
int n;
-
/* colon delimited */
if ((p = strchr(path, ':')) == NULL)
p = strchr(path, '\0');
-
n = (p - path);
if (*p != '\0')
p++;
-
if (n > 0 && n <= maxpath) {
if (*path == '~') {
unsigned int l;
char *home_dir = getenv("HOME");
-
if (home_dir && *home_dir) {
l = strlen(home_dir);
if (l + n < (unsigned) maxpath) {
@@ -1394,7 +1354,6 @@ search_path(const char *pathlist, const char *file)
name[n++] = '/';
name[n] = '\0';
strncat(name, file, len);
-
D_OPTIONS(("Checking for file \"%s\"\n", name));
if (!access(name, R_OK)) {
if (stat(name, &fst)) {
@@ -1423,12 +1382,9 @@ load_image(const char *file, simage_t *simg)
Imlib_Image *im;
Imlib_Load_Error im_err;
char *geom;
-
ASSERT_RVAL(file != NULL, 0);
ASSERT_RVAL(simg != NULL, 0);
-
D_PIXMAP(("load_image(%s, %8p)\n", file, simg));
-
if (*file != '\0') {
if ((geom = strchr(file, '@')) != NULL) {
*geom++ = 0;
@@ -1464,7 +1420,6 @@ void
update_cmod(colormod_t *cmod)
{
ASSERT(cmod != NULL);
-
/* When a particular R/G/B color modifier is changed, this function must be called
to resync the Imlib2 color modifier (imlib_mod) with our new brightness,
contrast, and gamma values. */
@@ -1492,9 +1447,7 @@ update_cmod_tables(imlib_t *iml)
{
colormod_t *mod = iml->mod, *rmod = iml->rmod, *gmod = iml->gmod, *bmod = iml->bmod;
DATA8 rt[256], gt[256], bt[256];
-
REQUIRE(mod || rmod || gmod || bmod);
-
/* When any changes is made to any individual color modifier for an image,
this function must be called to update the overall Imlib2 color modifier. */
D_PIXMAP(("Updating color modifier tables for %8p\n", iml));
@@ -1510,7 +1463,6 @@ update_cmod_tables(imlib_t *iml)
imlib_reset_color_modifier();
}
imlib_get_color_modifier_tables(rt, gt, bt, NULL);
-
if (rmod && rmod->imlib_mod) {
imlib_context_set_color_modifier(rmod->imlib_mod);
imlib_get_color_modifier_tables(rt, NULL, NULL, NULL);
@@ -1525,7 +1477,6 @@ update_cmod_tables(imlib_t *iml)
}
imlib_context_set_color_modifier(mod->imlib_mod);
imlib_set_color_modifier_tables(rt, gt, bt, NULL);
-
if (mod->brightness != 0x100) {
imlib_modify_color_modifier_brightness((double) (mod->brightness - 255.0) / 255.0);
}
@@ -1559,7 +1510,6 @@ shade_ximage_15(void *data, int bpl, int w, int h, int rm, int gm, int bm)
{
unsigned char *ptr;
int x, y;
-
ptr = (unsigned char *) data + (w * sizeof(DATA16));
if ((rm <= 256) && (gm <= 256) && (bm <= 256)) {
/* No saturation */
@@ -1602,7 +1552,6 @@ shade_ximage_16(void *data, int bpl, int w, int h, int rm, int gm, int bm)
{
unsigned char *ptr;
int x, y;
-
ptr = (unsigned char *) data + (w * sizeof(DATA16));
if ((rm <= 256) && (gm <= 256) && (bm <= 256)) {
/* No saturation */
@@ -1645,7 +1594,6 @@ shade_ximage_32(void *data, int bpl, int w, int h, int rm, int gm, int bm)
{
unsigned char *ptr;
int x, y;
-
ptr = (unsigned char *) data + (w * 4);
if ((rm <= 256) && (gm <= 256) && (bm <= 256)) {
/* No saturation */
@@ -1708,7 +1656,6 @@ shade_ximage_24(void *data, int bpl, int w, int h, int rm, int gm, int bm)
{
unsigned char *ptr;
int x, y;
-
ptr = (unsigned char *) data + (w * 3);
if ((rm <= 256) && (gm <= 256) && (bm <= 256)) {
/* No saturation */
@@ -1781,10 +1728,8 @@ colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h
unsigned short rm, gm, bm, shade;
Imlib_Color ctab[256];
int real_depth = 0;
-
D_PIXMAP(("colormod_trans(p == 0x%08x, gc, w == %hu, h == %hu) called.\n", p, w, h));
REQUIRE(p != None);
-
if (iml->mod) {
shade = iml->mod->brightness;
} else {
@@ -1810,11 +1755,9 @@ colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h
return; /* Nothing to do */
}
D_PIXMAP((" -> rm == %hu, gm == %hu, bm == %hu, shade == %hu\n", rm, gm, bm, shade));
-
if (Xdepth <= 8) {
XColor cols[256];
-
for (i = 0; i < (unsigned long) (1 << Xdepth); i++) {
cols[i].pixel = i;
cols[i].flags = DoRed | DoGreen | DoBlue;
@@ -1828,7 +1771,6 @@ colormod_trans(Pixmap p, imlib_t *iml, GC gc, unsigned short w, unsigned short h
} else if (Xdepth == 16) {
XWindowAttributes xattr;
-
XGetWindowAttributes(Xdisplay, desktop_window, &xattr);
if ((xattr.visual->green_mask == 0x3e0)) {
real_depth = 15;
@@ -1913,7 +1855,6 @@ update_desktop_info(int *w, int *h)
unsigned int pw, ph, pb, pd;
int px, py;
Window dummy;
-
if (w) {
*w = 0;
}
@@ -1966,7 +1907,6 @@ get_desktop_window(void)
unsigned char *data;
unsigned int nchildren;
Window w, root, *children, parent;
-
D_PIXMAP(("Current desktop window is 0x%08x\n", (unsigned int) desktop_window));
if ((desktop_window != None) && (desktop_window != Xroot)) {
XSelectInput(Xdisplay, desktop_window, None);
@@ -1975,7 +1915,6 @@ get_desktop_window(void)
for (w = TermWin.parent; w; w = parent) {
D_PIXMAP((" Current window ID is: 0x%08x\n", w));
-
if ((XQueryTree(Xdisplay, w, &root, &parent, &children, &nchildren)) == False) {
D_PIXMAP((" Egad! XQueryTree() returned false!\n"));
return None;
@@ -2023,7 +1962,6 @@ get_desktop_pixmap(void)
static Pixmap color_pixmap = None, orig_desktop_pixmap;
unsigned long length, after;
unsigned char *data;
-
D_PIXMAP(("Current desktop pixmap is 0x%08x\n", (unsigned int) desktop_pixmap));
if (desktop_pixmap == None) {
orig_desktop_pixmap = None; /* Forced re-read. */
@@ -2039,8 +1977,8 @@ get_desktop_pixmap(void)
LIBAST_X_FREE_PIXMAP(color_pixmap);
color_pixmap = None;
}
- XGetWindowProperty(Xdisplay, desktop_window, props[PROP_TRANS_PIXMAP], 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after,
- &data);
+ XGetWindowProperty(Xdisplay, desktop_window, props[PROP_TRANS_PIXMAP], 0L, 1L, False, AnyPropertyType, &type,
+ &format, &length, &after, &data);
if (type == XA_PIXMAP) {
p = *((Pixmap *) data);
XFree(data);
@@ -2060,7 +1998,6 @@ get_desktop_pixmap(void)
GC gc;
XGCValues gcvalue;
Screen *scr = ScreenOfDisplay(Xdisplay, Xscreen);
-
gcvalue.foreground = gcvalue.background = PixColors[bgColor];
gc = LIBAST_X_CREATE_GC(GCForeground | GCBackground, &gcvalue);
XGetGeometry(Xdisplay, p, &w, &px, &py, &pw, &ph, &pb, &pd);
@@ -2088,13 +2025,12 @@ get_desktop_pixmap(void)
} else {
XFree(data);
}
- XGetWindowProperty(Xdisplay, desktop_window, props[PROP_TRANS_COLOR], 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after,
- &data);
+ XGetWindowProperty(Xdisplay, desktop_window, props[PROP_TRANS_COLOR], 0L, 1L, False, AnyPropertyType, &type,
+ &format, &length, &after, &data);
if (type == XA_CARDINAL) {
XGCValues gcvalue;
GC gc;
Pixel pix;
-
free_desktop_pixmap();
pix = *((Pixel *) data);
XFree(data);
@@ -2102,7 +2038,6 @@ get_desktop_pixmap(void)
gcvalue.foreground = pix;
gcvalue.background = pix;
gc = LIBAST_X_CREATE_GC(GCForeground | GCBackground, &gcvalue);
-
color_pixmap = LIBAST_X_CREATE_PIXMAP(16, 16);
XFillRectangle(Xdisplay, color_pixmap, gc, 0, 0, 16, 16);
D_PIXMAP(("Created solid color pixmap 0x%08x for desktop_pixmap.\n", color_pixmap));
@@ -2133,16 +2068,12 @@ shaped_window_apply_mask(Drawable d, Pixmap mask)
{
static signed char have_shape = -1;
-
REQUIRE(d != None);
REQUIRE(mask != None);
-
D_PIXMAP(("shaped_window_apply_mask(d [0x%08x], mask [0x%08x]) called.\n", d, mask));
-
# ifdef HAVE_X_SHAPE_EXT
if (have_shape == -1) { /* Don't know yet. */
int unused;
-
D_PIXMAP(("Looking for shape extension.\n"));
if (XQueryExtension(Xdisplay, "SHAPE", &unused, &unused, &unused)) {
have_shape = 1;
@@ -2171,7 +2102,6 @@ set_icon_pixmap(char *filename, XWMHints * pwm_hints)
Imlib_Color_Modifier tmp_cmod;
XWMHints *wm_hints;
int w = 8, h = 8;
-
if (pwm_hints) {
wm_hints = pwm_hints;
} else {
@@ -2182,15 +2112,12 @@ set_icon_pixmap(char *filename, XWMHints * pwm_hints)
tmp_cmod = imlib_create_color_modifier();
imlib_context_set_color_modifier(tmp_cmod);
imlib_reset_color_modifier();
-
if (filename && *filename) {
if ((icon_path = search_path(rs_path, filename)) == NULL)
icon_path = search_path(getenv(PATH_ENV), filename);
-
if (icon_path != NULL) {
XIconSize *icon_sizes;
int count, i;
-
temp_im = imlib_load_image_with_error_return(filename, &im_err);
if (temp_im == NULL) {
print_error("Unable to load icon file \"%s\" -- %s\n", filename, imlib_strerror(im_err));
@@ -2240,10 +2167,8 @@ set_icon_pixmap(char *filename, XWMHints * pwm_hints)
wm_hints->flags |= IconWindowHint;
}
imlib_free_image_and_decache();
-
wm_hints->icon_x = wm_hints->icon_y = 0;
wm_hints->flags |= IconPositionHint;
-
/* Only set the hints ourselves if we were passed a NULL pointer for pwm_hints */
if (!pwm_hints) {
XSetWMHints(Xdisplay, TermWin.parent, wm_hints);
diff --git a/src/scream.h b/src/scream.h
index 223bab4..b4332ad 100644
--- a/src/scream.h
+++ b/src/scream.h
@@ -33,6 +33,7 @@
#define NS_SCREEN_ST_CLR 12
#define NS_EFUN_NOT_SET 13
#define NS_USER_CXL 14
+#define NS_NOT_ALLOWED 15
#define NS_ERR_WEIRDSCREEN 1
@@ -50,6 +51,11 @@
#define NS_HOP_DOWN 0
#define NS_HOP_UP 1
+#define NS_ESC_CMDLINE 1
+#define NS_ESC_SYSSCREENRC 2
+#define NS_ESC_SCREENRC 3
+#define NS_ESC_INTERACTIVE 4
+
/***************************************************************************/
@@ -82,9 +88,12 @@ typedef struct __ns_sess { /* a whole screen-session with many clients */
ssh-key should be on the remote machine. */
char *rsrc; /* add'l parameter to screen/scream. URL-enc */
char *home; /* user's home dir. so we can find .screenrc */
+ char *sysrc; /* global screen config */
void *userdef; /* the term-app can store a pointer here */
int fd; /* fd for communication */
char escape,literal; /* talking to screen: defaults to ^A, a */
+ int escdef; /* where was the escape sequence defined? */
+ int delay; /* initialization delay */
int dsbb; /* default length of scroll-back buffer */
struct __ns_efuns *efuns; /* callbacks into the terminal program. */
struct __ns_hop *hop; /* tunnel, if any */
@@ -130,6 +139,7 @@ typedef struct __ns_efuns { /* callbacks into the terminal program */
int (*inp_text)(void *,int,char *);
int (*inp_dial)(void *,char *,int,char **,int (*)(void *,char *,size_t,size_t));
int (*inp_tab)(void *,char *[],int,char *,size_t,size_t);
+ int (*waitstate)(void *,int);
} _ns_efuns;
@@ -153,6 +163,7 @@ _ns_efuns *ns_dst_efuns(_ns_efuns **);
_ns_efuns *ns_get_efuns(_ns_sess *,_ns_disp *);
/* debug */
+void ns_desc_string(char *,char *);
void ns_desc_hop(_ns_hop *,char *);
void ns_desc_sess(_ns_sess *,char *);
@@ -167,15 +178,18 @@ _ns_sess *ns_attach_by_URL(char *,char *,_ns_efuns **,int *,void *);
/* send command to screen */
int ns_screen_command(_ns_sess *, char *);
-/* send statement to screen */
+/* send statement to screen (prefixing it with the session's ^A: equiv) */
int ns_screen_xcommand(_ns_sess *,char , char *);
-/* parse and forward a screen-statement */
-int ns_parse_screen_cmd(_ns_sess *,char *);
+/* parse and forward a screen-statement (from ^A: input or screenrc) */
+int ns_parse_screen_cmd(_ns_sess *,char *,int);
/* parse and forward a screen-hotkey */
int ns_parse_screen_key(_ns_sess *,char);
+/* parse and forward a string */
+int ns_parse_screen_interactive(_ns_sess *, char *);
+
/* parse screen escape setup */
char ns_parse_esc(char **);
@@ -222,6 +236,7 @@ void ns_register_txt(_ns_efuns *,int (*inp_text)(void *,int,char *));
void ns_register_inp(_ns_efuns *,int (*)(void *,char *,int,char **,int (*)(void *,char *,size_t,size_t)));
void ns_register_tab(_ns_efuns *,int (*)(void *,char *[],int,char *,size_t,size_t));
+void ns_register_fun(_ns_efuns *,int (*)(void *,int));
diff --git a/src/screamcfg.h b/src/screamcfg.h
index 71359d6..8ae78e0 100644
--- a/src/screamcfg.h
+++ b/src/screamcfg.h
@@ -16,19 +16,23 @@
#define NS_PARANOID
/* define NS_DEBUG to get debug-info. no support for those who undef this. */
-#undef NS_DEBUG
+#undef NS_DEBUG
/* debug memory stuff. never actually used this. */
#undef NS_DEBUG_MEM
+#define NS_MAXCMD 512
+
#define NS_SSH_CALL "ssh"
#define NS_SSH_OPTS "-t"
#define NS_SSH_TUNNEL_OPTS "-N"
-#define NS_SCREAM_CALL "scream"
+#define NS_SCREAM_CALL "scream %s"
#define NS_SCREAM_OPTS "-xRR"
-#define NS_SCREEN_CALL "screen"
+#define NS_SCREEN_CALL "screen %s"
#define NS_SCREEN_OPTS "-xRR"
-#define NS_SCREEM_CALL "\"" NS_SCREAM_CALL " " NS_SCREAM_OPTS " 2>/dev/null || " NS_SCREEN_CALL " " NS_SCREEN_OPTS "\""
+#define NS_SCREEN_GREP "grep escape \"$SCREENRC\" 2>/dev/null || grep escape ~/.screenrc 2>/dev/null || grep escape \"$SYSSCREENRC\" 2>/dev/null || grep escape /etc/screenrc 2>/dev/null || grep escape /usr/local/etc/screenrc 2>/dev/null || echo \"escape ^Aa\"\n"
+#define NS_SCREEM_CALL "%s 2>/dev/null || %s"
+#define NS_WRAP_CALL "export TERM=vt100; %s"
#define NS_SCREEN_RC ".screenrc"
/* this should never change. the escape-char for an out-of-the-box "screen".
@@ -44,7 +48,8 @@
else is used in the session, libscream will convert it on the fly. */
/* DO NOT use \005Lw for your status, it breaks older screens!! */
#define NS_SCREEN_UPDATE "\x01w"
-#define NS_SCREEN_INIT "\x01:hardstatus lastline\r\x01:defhstatus \"\\005w\"\r\x01:hstatus \"\\005w\"\r\x01:msgminwait 0\r\x01:msgwait 1\r\x01:nethack off\r" NS_SCREEN_UPDATE
+#define NS_SCREEN_INIT "\x0c\x01Z\x01:hardstatus lastline\r\x01:defhstatus \"\\005w\"\r\x01:hstatus \"\\005w\"\r\x01:msgminwait 0\r\x01:msgwait 1\r\x01:nethack off\r" NS_SCREEN_UPDATE
+#define NS_SCREEN_PRVS_REG "\x01:focus up\r"
#define NS_DFLT_SSH_PORT 22
#define NS_MIN_PORT 1025
@@ -62,6 +67,9 @@
a bit of a last resort. */
#define NS_SCREEN_UPD_FREQ 0
+/* should be 1s */
+#define NS_INIT_DELAY 1
+
/* how many seconds to wait for an SSH-tunnel to build when using the
-Z option (tunnel through firewall). 2 for very fast networks,
much more for slow connections. */
diff --git a/src/screen.c b/src/screen.c
index 682c97a..67e3c0d 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -52,7 +52,10 @@ static rend_t **buf_rend = NULL;
/* Tab stop locations */
static char *tabs = NULL;
-static screen_t screen = {
+#ifndef ESCREEN
+static
+#endif
+screen_t screen = {
NULL, NULL, 0, 0, 0, 0, 0, Screen_DefaultFlags
};
@@ -3366,8 +3369,21 @@ xim_get_position(XPoint * pos)
void
parse_screen_status_if_necessary(void)
{
+ static int hc = 0;
ns_parse_screen(TermWin.screen, (TermWin.screen_pending > 1), TermWin.ncol, screen.text[TermWin.nrow + TermWin.saveLines - 1]);
if (TermWin.screen_pending > 1)
TermWin.screen_pending = 0;
+#if 0
+ {
+ FILE *fh;
+ int c;
+ if ((fh = fopen("Escreen.log", "a"))) {
+ for (c = 0; c < 8; c++)
+ if (strcmp(drawn_text[c], drawn_text[c + 1]))
+ fprintf(fh, "%2d \"%s\"\n", c, drawn_text[c]);
+ fclose(fh);
+ }
+ }
+#endif
}
#endif
diff --git a/src/screen.h b/src/screen.h
index 97617df..2190263 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -231,6 +231,9 @@ extern unsigned char refresh_all;
#ifdef MULTI_CHARSET
extern encoding_t encoding_method;
#endif
+#ifdef ESCREEN
+extern screen_t screen;
+#endif
/************ Function Prototypes ************/
_XFUNCPROTOBEGIN
diff --git a/src/startup.c b/src/startup.c
index 758e0b1..82e6846 100644
--- a/src/startup.c
+++ b/src/startup.c
@@ -211,7 +211,7 @@ eterm_bootstrap(int argc, char *argv[])
fputs("You called me \"Eterm\"!\n", stderr);
else
fputs("Stop calling me funky names!\n", stderr);
- fprintf(stderr, "Escreen mode is %d (%d rows, %s)\n", TermWin.screen_mode, TermWin.nrow, rs_url);
+ fprintf(stderr, "Escreen mode is %d (%d rows, URL is \"%s\")\n", TermWin.screen_mode, TermWin.nrow, rs_url);
# endif
}
#endif