Wed Jun 26 16:58:14 2002 Michael Jennings (mej)

Latest Escreen stuff from Azundris, including work on twin support
(twin.sourceforge.net).


SVN revision: 6330
This commit is contained in:
Michael Jennings 2002-06-26 21:02:12 +00:00
parent 5cc41f7340
commit ec34068f82
11 changed files with 449 additions and 191 deletions

View File

@ -4730,3 +4730,8 @@ Thu Jun 20 18:55:59 2002 Michael Jennings (mej)
Better fix from Azundris.
----------------------------------------------------------------------
Wed Jun 26 16:58:14 2002 Michael Jennings (mej)
Latest Escreen stuff from Azundris, including work on twin support
(twin.sourceforge.net).
----------------------------------------------------------------------

View File

@ -361,12 +361,40 @@ AC_MSG_CHECKING(for Escreen support)
AC_ARG_ENABLE(escreen,
[ --enable-escreen enable Eterm's built-in screen support], [
if test "$enableval" = "yes"; then
AC_MSG_RESULT(yes)
AC_DEFINE(ESCREEN)
AC_CHECK_PROG(FOUND_SCREEN, screen, screen)
if test ! -z "$FOUND_SCREEN"; then
AC_DEFINE(NS_HAVE_SCREEN,1,[Support the GNU screen text windowing system?])
else
AC_WARN(*** screen support has been disabled because screen was not found ***)
fi
else
AC_MSG_RESULT(no)
fi], AC_MSG_RESULT(no)
)
AC_MSG_CHECKING(for Etwin support)
AC_ARG_ENABLE(etwin,
[ --enable-etwin enable Eterm's built-in twin support], [
if test "$enableval" = "yes"; then
AC_CHECK_LIB(Tw, Tw_Open, FOUND_LIBTWIN=1, FOUND_LIBTWIN=0, $GRLIBS)
if test "$FOUND_LIBTWIN" -ne "1"; then
AC_WARN(*** Twin support has been disabled because libTw was not found ***)
else
AC_DEFINE(NS_HAVE_TWIN,1,[Support the twin text windowing system?])
LIBS="$LIBS -lTw"
fi
else
AC_MSG_RESULT(no)
fi], AC_MSG_RESULT(no)
)
if test ! -z "FOUND_$SCREEN" || ! -z "$FOUND_LIBTWIN"; then
AC_DEFINE(ESCREEN)
fi
if test ! -z "FOUND_$SCREEN" || ! -z "$FOUND_LIBTWIN"; then
AC_DEFINE(ESCREEN)
fi
AC_MSG_CHECKING(if profiling macros should be included)
AC_ARG_ENABLE(profile,
[ --enable-profile compile with code profiling macros enabled], [
@ -866,6 +894,7 @@ AC_ARG_WITH(sense-of-humor, [ --without-sense-of-humor Specify this if you ha
if test -z "$HUMOR"; then
AC_CHECK_LIB(Kenny, life_signs, , [
echo " Oh my god, they killed Kenny! You bastards!"
AC_DEFINE(HAVE_HUMOR,1,[Does user have a sense of humour?])
])
fi

View File

@ -6,7 +6,7 @@
| _/ ___ \ |_| | _ _ | |___\__ \ (__| | | __/ __/ | | |
|_|/_/ \_\__\_\ (_|_) |_____|___/\___|_| \___|\___|_| |_|
Frequently Asked Questions about the Eterm "Escreen" extension
Frequently Asked Questions about the "Escreen/Etwin" extension
@ -86,22 +86,21 @@ A An Eterm should open with a screen (without a status-line) running
Q What's new?
* Dialog boxes now longer block the entire GUI (only Eterm's).
* libscream's functions are available through Eterm's scripting
facility. See escreen.cfg for an example.
* Display-closing has a dialog-box now.
* Preliminary Twin support. For now, Twin-URLs (Eterm -U twin://)
and Twin's mouse-protocol are supported, allowing you start twin
within Eterm (making it the only terminal emulator to support Twin,
AFAIK). Next release should feature Twin support through libscream
(thus exposing Twin to button- and key-bindings through Eterm's
scripting interface).
* Code clean-up. It's actually understandable now.
(You can also compile libscream w/o support for screen now. : )
* Logs debug info through libast now if it available
* Fix for scrollbar (reported by mej).
* Fix for remote sessions with no corresponding local user
(reported by tfing).
For more information on Twin see
http://freshmeat.net/projects/twin/?topic_id=158
* Tear-off tabs. You can select the button-representation of a
display and drag-and-drop it
display and drag-and-drop it [currently under reconstruction]
- to another button:
@ -123,9 +122,6 @@ Q What should I expect in the future? (TODO)
* Limited support for scrolling. screen doesn't give us all the info
we'd need to make this really sexy.
* Possibly support for enhanced screen-clones (like the perchance
forthcoming "scream").
------------------------------------------------------------------------------
@ -142,7 +138,7 @@ A If you call it an Eterm, it will behave like one. Same for an Escreen.
(you'd have to symlink from Escreen to Eterm first, of course).
Additionally, when called with a command-line (-e "/some/program"), the
suite will *always* behave like an Eterm, even if invoked as Escreen.
Likewise, when called with an URL (-U "screen://user@some.host.gov/"),
Likewise, when called with an URL (-U screen://user@some.host.gov/),
it will behave like an Escreen, even if invoked under another name.
@ -154,7 +150,7 @@ A Before you complain:
* Take a deep breath, remember you didn't pay for this.
* Check whether you are using the latest version. Support for each
version stops with the release of a new one!
version ceases with the release of a new one!
* Read all of the FAQ, your question may be answered in there.
Remember that the FAQ grows with almost each release, so re-reading
@ -201,9 +197,10 @@ A Well, yes. ^A talks to the screen program. Put a line
to press to send the escape (^A in the example) to the application
instead); you'll want to put something else to move it around.
See "man screen" for details.
2002/05/13 note that ^A: opens a buffer where you can directly enter
statements like "escape ^Uu"; trying things out will be
easier that way. yes, it will be ^U: afterwards. ; )
Note that ^A: opens a buffer where you can directly enter
statements like "escape ^Uu"; trying things out will be
easier that way. Yes, it the magic key will be ^U: afterwards. ; )
@ -230,7 +227,7 @@ Q Escreen changes the escape on the remote box to the same thing as on
A You can always override the escapes like so:
Eterm -U user@host.com/-e^Xy
Eterm -U screen://user@host.com/-e^Xy
Where ^X is the escape and y the literal (man screen).

View File

@ -1090,10 +1090,19 @@ bbar_draw(buttonbar_t *bbar, unsigned char image_state, unsigned char force_mode
GC gc; /* evil temporary hack */
int f = button->flags & ~NS_SCREAM_BUTTON;
if (f & NS_SCREAM_CURR) {
f = 1;
} else if (f & NS_SCREAM_ACT) {
f = 2;
} else {
f = 0;
}
gc = LIBAST_X_CREATE_GC(0, NULL);
XCopyGC(Xdisplay, bbar->gc, GCFont, gc);
XSetForeground(Xdisplay, gc, PixColors[minBright + f + 2]);
D_BBAR(("bbar_draw: text \"%s\", colour %d.\n", button->text, f));
if (f) {
draw_string(bbar, bbar->bg, gc, button->text_x, button->text_y, button->text, button->len);
LIBAST_X_FREE_GC(gc);

View File

@ -2471,6 +2471,7 @@ upd_disp(void *xd, int n, int flags, char *name)
/* Update flags */
if (flags >= 0) {
button->flags = (flags | NS_SCREAM_BUTTON);
D_ESCREEN(("upd_disp: new flags for \"%s\": %d\n", button->text, flags));
}
/* Redraw buttonbar to reflect new information */
@ -2571,6 +2572,7 @@ exe_prg(void *xd, char **argv)
/****** Azundris' playthings :-) ******/
#ifdef HAVE_HUMOR
#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;
@ -2761,6 +2763,7 @@ waitstate(void *xd, int ms)
return 0;
}
#endif
static _ns_efuns *
escreen_reg_funcs(void)
@ -2790,7 +2793,9 @@ escreen_reg_funcs(void)
ns_register_inp(efuns, input_dialog);
ns_register_tab(efuns, menu_tab);
#ifdef HAVE_HUMOR
ns_register_fun(efuns, waitstate);
#endif
return efuns;
}
@ -2798,15 +2803,22 @@ escreen_reg_funcs(void)
static int
make_escreen_menu(buttonbar_t *bbar)
{
static int been_here = 0;
button_t *button;
menu_t *m;
menuitem_t *i;
if (been_here) { /* the start function may be called more than once */
return 0; /* in later versions, but we only want one EScreen menu */
}
been_here = 1;
if ((m = menu_create(NS_MENU_TITLE))) {
char *sc[] = {
/* display functions */
"New", "es_display(new)", /* \x01:screen\r */
"New (w/ name)...", "es_display(new,ask)",
"New", "es_display(new)", /* \x01:screen\r */
"New...", "es_display(new,ask)",
"Rename...", "es_display(name,ask)",
"Backlog...", "es_display(backlog)",
"Monitor", "es_display(monitor)",
@ -2815,7 +2827,7 @@ make_escreen_menu(buttonbar_t *bbar)
/* region functions */
"Split", "es_region(new)",
"Unsplit", "es_region(full)",
"Prev region", "es_region(prev)", /* NS_SCREEN_PRVS_REG */
"Prev region", "es_region(prev)", /* NS_SCREEN_PRVS_REG */
"Next region", "es_region(next)",
"Kill region", "es_region(kill)",
"-", "",
@ -2883,7 +2895,7 @@ escreen_init(char **argv)
_ns_efuns *efuns;
buttonbar_t *bbar;
if (!TermWin.screen_mode) {
if (TermWin.screen_mode == NS_MODE_NONE) {
return run_command(argv);
}
@ -2905,7 +2917,8 @@ escreen_init(char **argv)
bbar_add(bbar);
}
if ((TermWin.screen = ns_attach_by_URL(rs_url, rs_hop, &efuns, &ns_err, bbar)) == 0) {
if ((TermWin.screen = ns_attach_by_URL(rs_url, rs_hop, &efuns, &ns_err, bbar)) == NULL) {
D_CMD(("ns_attach_by_URL(%s,%s) failed\n", rs_url, rs_hop));
return -1;
}
if (rs_delay >= 0) {
@ -2920,6 +2933,7 @@ escreen_init(char **argv)
parent_resize();
/* add_screen_ctl_button(bbar,"New",'c'); */
D_CMD(("TermWin.screen->fd = %d\n", TermWin.screen->fd));
return TermWin.screen->fd;
}
#endif
@ -2963,7 +2977,7 @@ init_command(char **argv)
AT_LEAST((int) num_fds, pipe_fd + 1);
}
if ((cmd_fd = command_func(argv)) < 0) {
print_error("aborting\n");
print_error("Unable to run sub-command.\n");
exit(EXIT_FAILURE);
}
}
@ -3140,15 +3154,19 @@ cmd_getc(void)
# ifdef NS_HAVE_TWIN
case NS_MODE_TWIN:
if (!TermWin.screen->twin) {
if (!Tw_CheckMagic(libscream_magic)) {
D_ESCREEN(("ns_attach_by_sess: Tw_CheckMagic failed\n"));
TermWin.screen->backend = TermWin.screen_mode = NS_MODE_NONE;
} else {
if (!(TermWin.screen->twin = Tw_Open(TermWin.screen->twin_str))) {
D_ESCREEN(("ns_attach_by_sess: Tw_Open(%s) failed\n", TermWin.screen->twin_str));
if (!TermWin.screen->timestamp) {
TermWin.screen->timestamp = time(NULL);
} else if (TermWin.screen->timestamp < time(NULL)) {
if (!Tw_CheckMagic(libscream_magic)) {
D_ESCREEN(("ns_attach_by_sess: Tw_CheckMagic failed\n"));
TermWin.screen->backend = TermWin.screen_mode = NS_MODE_NONE;
} else {
D_ESCREEN(("ns_attach_by_sess: Tw_Open(%s) succeeded\n", TermWin.screen->twin_str));
if (!(TermWin.screen->twin = Tw_Open(TermWin.screen->twin_str))) {
ns_desc_twin(TermWin.screen, "cmd_getc->Tw_Open");
TermWin.screen->backend = TermWin.screen_mode = NS_MODE_NONE;
} else {
D_ESCREEN(("ns_attach_by_sess: Tw_Open(%s) succeeded: handle @ %p\n", TermWin.screen->twin_str, TermWin.screen->twin));
}
}
}
}

View File

@ -19,6 +19,7 @@
* 2002/05/21 Azundris code restructuring, basic tab tear-off
* 2002/06/04 Azundris advanced tab tear-off
* 2002/06/05 Azundris basic twin support
* 2002/06/11 Azundris more twin support
***************************************************************************/
@ -61,6 +62,7 @@
#ifdef NS_HAVE_TWIN
# include <Tw/Tw.h>
# include <Tw/Tw_1.h>
# include <Tw/Twerrno.h>
#endif
#ifndef MAXPATHLEN
@ -387,6 +389,8 @@ ns_new_sess(void)
s->dsbb = NS_SCREEN_DEFSBB;
s->delay = NS_INIT_DELAY;
s->fd = -1;
s->disp = -1;
s->port = -1;
if (sa) { /* add to end of list */
_ns_sess *r = sa;
@ -632,6 +636,28 @@ ns_sess_init(_ns_sess * sess)
/* return port number for service TWIN.
<- a port number -- 7754 in all likelihood. */
int
ns_get_twin_port(void)
{
#ifdef NS_HAVE_TWIN
static int port = 0;
struct servent *srv;
if (port)
return port;
/* (fixme) replace with getservbyname_r on systems that have it */
srv = getservbyname("twin", "tcp");
return (port = (srv ? ntohs(srv->s_port) : TW_INET_PORT));
#else
return -1;
#endif
}
/* return port number for service SSH (secure shell).
<- a port number -- 22 in all likelihood. */
@ -755,6 +781,28 @@ ns_desc_string(char *c, char *doc)
/* ns_desc_twin
print status of a twin session
sess the session
doc info about the context
!stderr info about the twin session */
void
ns_desc_twin(_ns_sess * sess, char *doc)
{
#ifdef HAVE_TWIN
if (!sess) {
D_ESCREEN(("%s: ns_desc_twin called with broken pointer!\n", doc ? doc : ""));
return;
}
D_ESCREEN(("%s: twin status (%s) is %d-%s, %d-%s\n", doc, sess->twin_str,
Tw_Errno(sess->twin),
Tw_StrError(sess->twin, Tw_Errno(sess->twin)), Tw_ErrnoDetail(sess->twin), Tw_StrErrorDetail(sess->twin, Tw_Errno(sess->twin), Tw_ErrnoDetail(sess->twin))));
#endif
}
/* 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()
@ -764,8 +812,8 @@ ns_desc_string(char *c, char *doc)
static void
ns_desc_hop(_ns_hop * h, char *doc)
{
if (!h && doc) {
D_ESCREEN(("%s: ns_desc_hop called with broken pointer!\n", doc));
if (!h) {
D_ESCREEN(("%s: ns_desc_hop called with broken pointer!\n", doc ? doc : ""));
return;
}
@ -788,16 +836,18 @@ static void
ns_desc_sess(_ns_sess * sess, char *doc)
{
if (!sess) {
D_ESCREEN(("%s: ns_desc_sess called with broken pointer!\n", doc));
D_ESCREEN(("%s: ns_desc_sess called with broken pointer!\n", doc ? doc : ""));
return;
}
if (sess->where == NS_LCL)
D_ESCREEN(("%s: (efuns@%p)\t (user %s) local %s %s\n", doc, sess->efuns, sess->user, sess->proto, sess->rsrc));
D_ESCREEN(("%s: (efuns@%p)\t (user %s) local %s", doc, sess->efuns, sess->user, sess->proto));
else {
D_ESCREEN(("%s: (efuns@%p)\t %s://%s%s%s@%s:%s/%s\n",
doc, sess->efuns, sess->proto ? sess->proto : "???", sess->user, sess->pass ? ":" : "", sess->pass ? sess->pass : "", sess->host,
sess->port, sess->rsrc));
D_ESCREEN(("%s: (efuns@%p)\t %s://%s%s%s@%s",
doc, sess->efuns, sess->proto ? sess->proto : "???", sess->user, sess->pass ? ":" : "", sess->pass ? sess->pass : "", sess->host));
if (sess->port != NS_DFLT_SSH_PORT)
D_ESCREEN((":%s", sess->port));
}
D_ESCREEN(("%c%s\n", sess->where == NS_LCL ? ' ' : '/', sess->rsrc));
if (sess->hop)
ns_desc_hop(sess->hop, NULL);
if (sess->sysrc)
@ -1088,23 +1138,6 @@ ns_attach_by_sess(_ns_sess ** sp, int *err)
D_ESCREEN(("ns_attach_by_sess: screen session-fd is %d, ^%c-%c\n", sess->fd, sess->escape + 'A' - 1, sess->literal));
#ifdef NS_HAVE_TWIN_
if (sess->backend == NS_MODE_TWIN) {
sleep(2);
if (!Tw_CheckMagic(libscream_magic)) {
D_ESCREEN(("ns_attach_by_sess: Tw_CheckMagic failed\n"));
goto fail;
} else {
if (!(sess->twin = Tw_Open(sess->twin_str))) {
D_ESCREEN(("ns_attach_by_sess: Tw_Open(%s) failed\n", sess->twin_str));
goto fail;
}
D_ESCREEN(("ns_attach_by_sess: Tw_Open() succeeded\n"));
ns_desc_sess(sess, "ns_sess_init");
}
}
#endif
return sess;
fail:
@ -1145,18 +1178,22 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
err = &err_dummy;
*err = NS_OOM;
if (!sess)
if (!sess) {
D_ESCREEN(("ns_attach_by_URL: no session...\n"));
return NULL;
}
D_ESCREEN(("ns_attach_by_URL(%s,%s,%p,%p,%p)\n", url, hop, *ef, err, xd));
if (url && strlen(url)) {
char *q;
if (!(d = STRDUP(url)))
if (!(d = strdup(url)))
goto fail;
if ((q = strstr(d, "://"))) { /* protocol, if any */
*q = '\0';
if (!(sess->proto = STRDUP(d)))
if (!(sess->proto = strdup(d)))
goto fail;
q += 3;
} else
@ -1169,15 +1206,15 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
*p = '\0';
if ((r = strchr(q, ':'))) { /* password, if any */
*(r++) = '\0';
if (!(sess->pass = STRDUP(r))) /* password may be empty string! */
if (!(sess->pass = strdup(r))) /* password may be empty string! */
goto fail;
}
sess->user = STRDUP(q);
sess->user = strdup(q);
}
q = p + 1;
}
if ((p = strchr(q, '/'))) {
if ((p = strchr(q, '/'))) { /* rsrc, possibly url-encoded */
*(p++) = '\0';
if (strlen(p)) {
char *r = p;
@ -1210,6 +1247,25 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
r++;
} else {
if (*r == '-') {
# ifdef NS_HAVE_TWIN
if (!strncmp(NS_TWIN_PARA, &r[1], strlen(NS_TWIN_PARA))) {
char *y = strchr(r, '@');
if (y && *++y) {
char *z = strchr(y, ':');
if (z) {
*z++ = '\0';
if (*z)
sess->disp = atoi(z);
if (sess->disp < 0 || sess->disp > NS_MAX_PORT)
sess->disp = 0;
}
if (strlen(y))
sess->host = strdup(y);
}
} else
# endif
# ifdef NS_HAVE_SCREEN
if (*(++r) == 'e') { /* set escape */
char x = 0, y = 0;
@ -1228,7 +1284,7 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
*rx = '\0';
if (*r != '/')
D_ESCREEN(("URL: path for screen's option -c should be absolute (%s)\n", r));
if ((rc = STRDUP(r))) {
if ((rc = strdup(r))) {
if (sess->home) /* this should never happen */
FREE(sess->home);
D_ESCREEN(("URL: searching for rc in %s\n", rc));
@ -1238,8 +1294,9 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
r = rx;
*rx = ' ';
}
}
} else
# endif
;
while (*r && (f || *r != ' ')) {
if (*r == '\"')
f = 1 - f;
@ -1251,7 +1308,7 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
}
}
if (!(sess->rsrc = STRDUP(p)))
if (!(sess->rsrc = strdup(p)))
goto fail;
}
}
@ -1260,11 +1317,12 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
*(p++) = '\0';
if (!*p || !(sess->port = atoi(p)) || sess->port > NS_MAX_PORT) {
*err = NS_MALFORMED_URL;
D_ESCREEN(("malformed URL...\n"));
goto fail;
}
}
if (strlen(q) && !(sess->host = STRDUP(q))) /* host, if any */
if (strlen(q) && !(sess->host = strdup(q))) /* host, if any */
goto fail;
FREE(d);
@ -1275,27 +1333,30 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
if (!sess->user) { /* default user (current user) */
if (!pwe) {
*err = NS_UNKNOWN_USER;
D_ESCREEN(("unknown user...\n"));
goto fail;
}
if (!(sess->user = STRDUP(pwe->pw_name)))
if (!(sess->user = strdup(pwe->pw_name)))
goto fail;
} else if ((sess->host && strcmp(sess->host, "localhost") && strcmp(sess->host, "127.0.0.1")) || sess->port) {
} else if ((sess->host && strcmp(sess->host, "localhost") && strcmp(sess->host, "127.0.0.1")) || (sess->port > 0)) {
pwe = NULL;
} else if (!pwe || strcmp(pwe->pw_name, sess->user)) { /* user!=current_user */
sess->where = NS_SU;
if (!(pwe = getpwnam(sess->user))) {
*err = NS_UNKNOWN_USER;
D_ESCREEN(("unknown user...\n"));
goto fail;
}
} else {
*err = NS_UNKNOWN_USER;
D_ESCREEN(("unknown user...\n"));
goto fail;
}
#ifdef NS_HAVE_SCREEN
if (getenv("SYSSCREENRC")) { /* $SYSSCREENRC */
if (!(sess->sysrc = STRDUP(getenv("SCREENRC"))))
if (!(sess->sysrc = strdup(getenv("SCREENRC"))))
goto fail;
} else {
char *loc[] = { "/usr/local/etc/screenrc", /* official */
@ -1307,56 +1368,96 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
for (n = 0; n < nloc; n++)
if (!access(loc[n], R_OK)) {
if (!(sess->sysrc = STRDUP(loc[n])))
if (!(sess->sysrc = strdup(loc[n])))
goto fail;
n = nloc;
}
}
if (getenv("SCREENRC")) { /* $SCREENRC */
sess->home = STRDUP(getenv("SCREENRC"));
sess->home = strdup(getenv("SCREENRC"));
} 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);
}
#endif
if (!sess->host) { /* no host */
if (!(sess->host = STRDUP("localhost")))
goto fail;
if (!sess->port) { /* no host/port */
sess->where = NS_LCL;
}
} else if ((p = strchr(sess->host, '/'))) /* have host */
*p = '\0';
if (!sess->port) /* no port -> default port (SSH) */
sess->port = ns_get_ssh_port();
sess->backend = NS_MODE_NEGOTIATE;
if (sess->proto) {
#ifdef NS_HAVE_SCREEN
if (!strcmp(sess->proto, "screen")) {
sess->backend = NS_MODE_SCREEN;
} else
#warning compiling in support for GNU screen
#endif
#ifdef NS_HAVE_TWIN
#warning compiling in support for twin
if (!strcmp(sess->proto, "twin")) {
char *twd = getenv("TWDISPLAY");
sess->backend = NS_MODE_TWIN;
if (!sess->twin_str)
sess->twin_str = STRDUP(twd ? twd : ":0");
/* fall back on TWDISPLAY env var only if host not set yet */
if (twd && (!sess->host || !strlen(sess->host) || !strcmp(sess->host, "localhost"))) {
char *twdisp = strrchr(twd, ':');
if (twdisp) {
*twdisp++ = '\0';
if (*twdisp && sess->disp < 0) /* fall back on TWDISPLAY display */
sess->disp = atoi(twdisp);
} /* fall back on TWDISPLAY host */
if (((!sess->host) || (!strlen(sess->host))) && strlen(twd) && strcmp(twd, "localhost"))
sess->host = strdup(twd);
}
/* this is ugly, but does the intuitive thing.
* if you specifically want to connect a twin to a non-twin
* port < 20, make it unambiguous by using the syntax
* twin://host.dom:port/-twin@:disp or
* twin://:port/-twin@host.dom:disp */
else if (sess->host && sess->disp < 0 && sess->port >= 0 && sess->port < 20) {
sess->disp = sess->port;
sess->port = -1;
}
} else
#endif
if (!strcmp(sess->proto, "scream")) {
sess->backend = NS_MODE_SCREAM;
} else {
*err = NS_UNKNOWN_PROTO;
D_ESCREEN(("unknown protocol %s...\n", sess->proto));
fprintf(stderr, "protocol \"%s\" not known...\n", sess->proto);
goto fail;
}
}
if ((sess->disp < 0) || (sess->disp > NS_MAX_PORT))
sess->disp = 0;
#ifdef NS_HAVE_TWIN
/* do this *before* host-fallback */
if (sess->twin_str)
FREE(sess->twin_str);
if (sess->twin_str = MALLOC((sess->host ? strlen(sess->host) : 0) + 7))
sprintf(sess->twin_str, "%s:%d", (sess->host ? sess->host : ""), sess->disp);
#endif
if (!sess->host) { /* no host */
if (!(sess->host = strdup("localhost")))
goto fail;
if (sess->port <= 0) { /* no host/port */
sess->where = NS_LCL;
}
} else if ((p = strchr(sess->host, '/'))) /* have host */
*p = '\0';
if (sess->port <= 0) { /* no port -> default port (SSH) */
if (sess->backend == NS_MODE_TWIN)
sess->port = ns_get_twin_port();
else
sess->port = ns_get_ssh_port();
}
if (!sess->efuns && ef && *ef) {
sess->efuns = ns_ref_efuns(ef);
}
@ -1370,12 +1471,15 @@ ns_attach_by_URL(char *url, char *hop, _ns_efuns ** ef, int *err, void *xd)
}
*err = NS_SUCC;
return ns_attach_by_sess(&sess, err);
fail:
if (d)
FREE(d);
D_ESCREEN(("ns_attach_by_URL: fail...\n"));
return ns_dst_sess(&sess);
}
@ -1457,7 +1561,7 @@ ns_go2_disp(_ns_sess * s, int d)
return ns_screen_command(s, b);
break;
#endif
#ifdef NS_HAVE_TWIN_
#ifdef NS_HAVE_TWIN
case NS_MODE_TWIN:
{
tscreen ts = Tw_FirstScreen(s->twin);
@ -1477,23 +1581,27 @@ ns_go2_disp(_ns_sess * s, int d)
}
}
/* toggle monitor mode for disp (if possible) */
/* toggle monitor mode for disp (if possible). -1 for current disp */
int
ns_mon_disp(_ns_sess * s, int no)
ns_mon_disp(_ns_sess * s, int no, int quiet)
{
if (!s)
return NS_FAIL;
D_ESCREEN(("toggling monitoring for display %d\n", no));
switch (s->backend) {
#ifdef NS_HAVE_SCREEN
case NS_MODE_SCREEN:
ns_go2_disp(s, no);
if (no >= 0)
ns_go2_disp(s, no);
if (quiet == NS_MON_TOGGLE_QUIET)
s->flags |= NS_SESS_NO_MON_MSG;
return ns_screen_command(s, "\x01M");
break;
#endif
default:
return NS_FAIL;
}
return NS_FAIL;
}
/* scrollback buffer mode (if any) */
@ -1553,7 +1661,13 @@ ns_rel_disp(_ns_sess * s, int d)
ns_go2_disp(s, x->index);
}
/* add a client display with the name "name" after display number #after */
/* add a client display and a tab.
s the session to add to
after add after this display (0..n). -1 to add before disp 0.
name NULL: ask. "": let backend choose name. else: set name. */
int
ns_add_disp(_ns_sess * s, int after, char *name)
{
@ -1569,9 +1683,9 @@ ns_add_disp(_ns_sess * s, int after, char *name)
if (after >= 0)
ns_go2_disp(s, after);
if (ns_screen_command(s, "\x01\x03") == NS_SUCC) {
/* yes, -1 for "current_display" works even though we just made a new
display that isn't in our list yet. faith will see you through. */
ns_ren_disp(s, -1, name);
if (!name || strlen(name))
ns_ren_disp(s, -2, name);
ns_mon_disp(s, -2, NS_MON_TOGGLE_QUIET);
}
break;
#endif
@ -1585,6 +1699,7 @@ ns_add_disp(_ns_sess * s, int after, char *name)
}
/* move client display #fm to display slot #to */
int
ns_mov_disp(_ns_sess * s, int fm, int to)
@ -1679,7 +1794,15 @@ ns_rem_disp(_ns_sess * s, int d, int ask)
return ret;
}
/* rename display #d to "name". if d==-1, use current */
/* rename display
s session display is in
d -1 current display
-2 display was just created and is not in list yet
>=0 index of the display
name NULL ask for name
!NULL the name
<- error code */
int
ns_ren_disp(_ns_sess * s, int d, char *name)
{
@ -1696,13 +1819,16 @@ ns_ren_disp(_ns_sess * s, int d, char *name)
return NS_FAIL;
}
if (d < 0) {
if (d == -1)
d = s->curr->index;
}
if (!name || !*name) { /* ask */
i = s->curr->name;
l = strlen(i);
if (d == -2)
l = 32; /* dirty, but effective */
else {
i = s->curr->name;
l = strlen(i);
}
(void) ns_inp_dial(s, "Enter a new name for the current display", 12, &i, NULL);
if (!i || !*i)
return NS_FAIL;
@ -1712,7 +1838,8 @@ ns_ren_disp(_ns_sess * s, int d, char *name)
#ifdef NS_HAVE_SCREEN
case NS_MODE_SCREEN:
if ((n = MALLOC(strlen(i ? i : name) + l + 1))) {
ns_go2_disp(s, d);
if (d >= 0)
ns_go2_disp(s, d);
strcpy(&n[l], i ? i : name); /* copy new name */
while (l) /* prepend backspaces */
n[--l] = '\x08';
@ -2238,29 +2365,25 @@ ns_screen_command(_ns_sess * sess, char *cmd)
char *c;
int ret = NS_SUCC;
D_ESCREEN(("sess %8p, cmd %8p\n", sess, cmd));
if (!cmd || !*cmd)
return NS_FAIL;
D_ESCREEN(("Sending screen command %s\n", safe_print_string(cmd, strlen(cmd))));
if (NS_EFUN_EXISTS(efuns, sess, NULL, inp_text)) {
D_ESCREEN((" -> inp_text is set\n"));
if ((c = STRDUP(cmd))) {
char *p = c; /* replace default escape-char with that */
if ((c = strdup(cmd))) {
{
char *p = c; /* replace default escape-char with that */
D_ESCREEN((" -> translating escapes\n"));
while (*p) { /* actually used in this session */
if (*p == NS_SCREEN_ESCAPE)
*p = sess->escape;
p++;
while (*p) { /* actually used in this session */
if (*p == NS_SCREEN_ESCAPE)
*p = sess->escape;
p++;
}
}
ns_desc_string(c, "ns_screen_command: xlated string");
efuns->inp_text(NULL, sess->fd, c);
FREE(c);
} else {
D_ESCREEN((" -> out of memory\n"));
} else
ret = NS_OOM;
}
} /* out of memory */
else {
ret = NS_EFUN_NOT_SET;
@ -2549,7 +2672,7 @@ ns_parse_screen_interactive(_ns_sess * sess, char *c)
if (!c || !*c)
return NS_FAIL;
#ifdef NS_PARANOID
if (!(s = o = STRDUP(c)))
if (!(s = o = strdup(c)))
return NS_FAIL;
#else
s = c;
@ -2576,6 +2699,32 @@ ns_parse_screen_interactive(_ns_sess * sess, char *c)
/* ns_weird_screen -- damage control
screen the offending session
doc string specifying the context
!stderr a description of the problem
!err_inhibit the problem-type is marked so we don't rewarn.
<- error code (always NS_FAIL) */
static int
ns_screen_weird(_ns_sess * screen, long type, char *doc)
{
if (!(err_inhibit & type)) {
err_inhibit |= type;
fprintf(stderr, "parse_screen: %s (%ld) screen sent weird stuff.\n"
"This should never happen. It is assumed that you use a\n"
"rather unusual configuration for \"screen\". Please\n"
"send the result of 'screen --version' to <scream@azundris.com>\n"
"(together with your ~/.screenrc and /etc/screenrc if present).\n"
"If at all possible, please also run 'Eterm -e screen' and make\n"
"a screenshot of the offending window (and the window only, the\n" "beauty of your desktop is not relevant to this investigation. : ).\n", doc, type);
}
(void) ns_upd_stat(screen);
return NS_FAIL;
}
/* 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
@ -2663,6 +2812,7 @@ ns_parse_screenrc(_ns_sess * s, char *fn, int whence)
as certain functionalities ("add a tab", "show status message")
may be called from here.
p the offending message-line
! mode of operation may be modified using screen->flags
<- returns an error code. */
static int
@ -2670,8 +2820,9 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
{
_ns_efuns *efuns;
char *p2;
char vdate[33], vtype[3], vrem[17];
int ma, mi, mu, ret = NS_SUCC, type;
char vdate[33], vtype[3], vrem[17], win[64];
int ma, mi, mu, ret = NS_SUCC, type, n;
size_t l;
if (!p)
return NS_FAIL;
@ -2681,6 +2832,8 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
while (isspace(*p))
p++;
D_ESCREEN(("got \"%s\"\n", p));
type = (strlen(p) > 1) ? NS_SCREEN_STATUS : NS_SCREEN_ST_CLR;
if (type == NS_SCREEN_ST_CLR) {
@ -2701,7 +2854,7 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
if (screen->name) {
FREE(screen->name);
}
if ((screen->name = STRDUP(&p[strlen(NS_SCREEN_SESS_T)]))) {
if ((screen->name = strdup(&p[strlen(NS_SCREEN_SESS_T)]))) {
size_t lsn = strlen(screen->name);
if (lsn) {
@ -2715,7 +2868,30 @@ ns_parse_screen_msg(_ns_sess * screen, char *p)
!strncmp(p, "msgminwait", strlen("msgminwait")) ||
!strcmp(p, "Press ^@ to destroy or ^@ to resurrect window") || !strcmp(p, "Aborted because of window size change."))
p = NULL;
else if (sscanf(p, NS_SCREEN_VERSION_T, vtype, &ma, &mi, &mu, vrem, vdate) == 6) {
else if ((screen->flags & NS_SESS_NO_MON_MSG) &&
((sscanf(p, "Window %d (%s) is now being monitored for all activity.", &n, win) == 2) ||
(sscanf(p, "Window %d (%s) is no longer being monitored for activity.", &n, win) == 2))) {
D_ESCREEN(("activity toggled quietly for window %d-%s\n", n, win));
p = NULL;
screen->flags = (screen->flags & ~NS_SESS_NO_MON_MSG); /* reset mute flag */
} else if (!strncmp(p, NS_SCREEN_ACT_T, l = strlen(NS_SCREEN_ACT_T))) {
if (NS_EFUN_EXISTS(efuns, screen, NULL, upd_disp)) {
int inx, button;
_ns_disp *d;
p += l;
inx = atoi(p);
button = disp_get_real_by_screen(screen, inx);
if ((d = disp_fetch(screen, inx))) {
D_ESCREEN(("activity in window %d-%s (button %d)\n", inx, d->name, button));
d->flags |= NS_SCREAM_ACT;
efuns->upd_disp(screen->userdef, button, d->flags, NULL);
} else {
D_ESCREEN(("activity in unknown window %d (button %d)...\n", inx, button));
}
}
p = NULL;
} else if (sscanf(p, NS_SCREEN_VERSION_T, vtype, &ma, &mi, &mu, vrem, vdate) == 6) {
if (!strcmp("en", vtype))
screen->backend = NS_MODE_SCREEN;
else if (!strcmp("am", vtype))
@ -2779,7 +2955,7 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
if (!force && screen->timestamp)
return NS_SUCC;
if ((p = STRDUP(p))) {
if ((p = strdup(p))) {
_ns_parse pd[NS_MAX_DISPS];
p2 = &p[width - 1];
@ -2788,13 +2964,19 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
*(p2--) = '\0';
} /* p2 now points behind last item */
D_ESCREEN(("parse_screen: screen sends ::%s::\n", p));
D_ESCREEN(("parse_screen: screen sends (%d) ::%s::\n", strlen(p), p));
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 */
disp->flags &= ~NS_SCREAM_ACT;
while (disp->next) {
disp->flags &= ~NS_SCREAM_CURR;
disp = disp->next;
}
ret = ns_upd_stat(screen);
D_ESCREEN(("parse_screen: qeueing update\n"));
} /* more than once */
else if (!screen->timestamp) {
/* send init string the first time around, just to be on
@ -2820,7 +3002,7 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
screen->timestamp = 1;
D_ESCREEN(("parse_screen: resetting screen...\n"));
} else {
D_ESCREEN(("parse_screen: error, we should never get here\n"));
D_ESCREEN(("parse_screen: nothing to do in exception, updating anyways...\n"));
ret = ns_upd_stat(screen);
}
FREE(p);
@ -2880,28 +3062,42 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
n = pd[r].screen;
disp = disp_fetch(screen, n);
if (pd[r].flags & NS_SCREAM_CURR) {
pd[r].flags &= ~NS_SCREAM_ACT;
}
if (!disp) { /* new display */
if (!(disp = disp_fetch_or_make(screen, n)) || !(disp->name = STRDUP(pd[r].name))) {
if (!(disp = disp_fetch_or_make(screen, n)) || !(disp->name = strdup(pd[r].name))) {
D_ESCREEN(("parse_screen: out of memory in new_display(%d)\n", n));
ret = NS_FAIL;
} else {
if (NS_EFUN_EXISTS(efuns, screen, NULL, ins_disp))
ret = efuns->ins_disp(screen->userdef, pd[r].real - 1, pd[r].screen, disp->name);
}
} else if ((tmp = strcmp(disp->name, pd[r].name)) || /* upd display */
(disp->flags != pd[r].flags)) {
if (tmp) {
FREE(disp->name);
if (!(disp->name = STRDUP(pd[r].name))) {
FREE(p);
return NS_FAIL;
} else {
int fl = (disp->flags & ~NS_SCREAM_CURR) | (pd[r].flags & NS_SCREAM_MASK);
if ((fl & (NS_SCREAM_CURR | NS_SCREAM_ACT)) == (NS_SCREAM_CURR | NS_SCREAM_ACT))
fl &= ~NS_SCREAM_ACT;
if ((tmp = strcmp(disp->name, pd[r].name)) || /* upd display */
(disp->flags != fl)) {
if (tmp) {
FREE(disp->name);
if (!(disp->name = strdup(pd[r].name))) {
FREE(p);
return NS_FAIL;
}
}
if (disp->flags != fl) {
if (pd[r].flags & NS_SCREAM_CURR)
disp->sess->curr = disp;
disp->flags = fl;
} else
fl = -1;
if (NS_EFUN_EXISTS(efuns, screen, NULL, upd_disp))
ret = efuns->upd_disp(screen->userdef, r, fl, (!tmp) ? NULL : disp->name);
}
if (pd[r].flags & NS_SCREAM_CURR)
disp->sess->curr = disp;
disp->flags = pd[r].flags & NS_SCREAM_MASK;
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
@ -2925,19 +3121,9 @@ ns_parse_screen(_ns_sess * screen, int force, int width, char *p)
#ifdef NS_PARANOID
if (!r) {
if (!(err_inhibit & NS_ERR_WEIRDSCREEN)) {
err_inhibit |= NS_ERR_WEIRDSCREEN;
fprintf(stderr, "parse_screen: !r\n"
"This should never happen. It is assumed that you use a\n"
"rather unusual configuration for \"screen\". Please\n"
"send the result of 'screen --version' to <scream@azundris.com>\n"
"(together with your ~/.screenrc and /etc/screenrc if present).\n"
"If at all possible, please also run 'Eterm -e screen' and make\n"
"a screenshot of the offending window (and the window only, the\n" "beauty of your desktop is not relevant to this investigation. : ).\n");
}
ret = ns_upd_stat(screen);
D_ESCREEN(("parse_screen: no elements parsed (!r)...\n"));
FREE(p);
return NS_FAIL;
return ns_screen_weird(screen, NS_ERR_WEIRDSCREEN, "no elements parsed (!r)...");
} else
#endif
/* kill overhang (o/t right) if status-line isn't side-scrolling
@ -3024,6 +3210,7 @@ ns_register_red(_ns_efuns * efuns, int (*redraw) (void *))
efuns->redraw = redraw;
}
/* function that redraw part of the terminal */
void
ns_register_rda(_ns_efuns * efuns, int (*redraw_xywh) (void *, int, int, int, int))
@ -3031,7 +3218,7 @@ ns_register_rda(_ns_efuns * efuns, int (*redraw_xywh) (void *, int, int, int, in
efuns->redraw_xywh = redraw_xywh;
}
/* function that redraw part of the terminal */
/* function that expires buttons */
void
ns_register_exb(_ns_efuns * efuns, int (*expire_buttons) (void *, int))
{

View File

@ -302,7 +302,9 @@ menu_handle_button_release(event_t *ev)
menu_display_submenu(current_menu, item);
} else {
menu_action(item);
menuitem_deselect(current_menu);
if (current_menu) {
menuitem_deselect(current_menu);
}
}
}
/* Reset the state of the menu system. */
@ -413,8 +415,7 @@ menu_dispatch_event(event_t *ev)
return (0);
}
menulist_t *
menulist_add_menu(menulist_t *list, menu_t *menu)
menulist_t *menulist_add_menu(menulist_t *list, menu_t *menu)
{
ASSERT_RVAL(menu != NULL, list);
@ -446,8 +447,7 @@ menulist_clear(menulist_t *list)
FREE(list);
}
menu_t *
menu_create(char *title)
menu_t *menu_create(char *title)
{
menu_t *menu;
static Cursor cursor;
@ -599,8 +599,7 @@ menu_is_child(menu_t *menu, menu_t *submenu)
return 0;
}
menu_t *
find_menu_by_title(menulist_t *list, char *title)
menu_t *find_menu_by_title(menulist_t *list, char *title)
{
register unsigned char i;
@ -614,8 +613,7 @@ find_menu_by_title(menulist_t *list, char *title)
return NULL;
}
menu_t *
find_menu_by_window(menulist_t *list, Window win)
menu_t *find_menu_by_window(menulist_t *list, Window win)
{
register unsigned char i;
@ -629,8 +627,7 @@ find_menu_by_window(menulist_t *list, Window win)
return NULL;
}
menuitem_t *
find_item_by_coords(menu_t *menu, int x, int y)
menuitem_t *find_item_by_coords(menu_t *menu, int x, int y)
{
register unsigned char i;
register menuitem_t *item;
@ -700,8 +697,7 @@ menuitem_change_current(menuitem_t *item)
}
}
menuitem_t *
menuitem_create(char *text)
menuitem_t *menuitem_create(char *text)
{
menuitem_t *menuitem;

View File

@ -323,8 +323,7 @@ static const struct {
OPT_LONG("finished-text", "text to output after program termination", &rs_finished_text),
OPT_LONG("term-name", "value to use for setting $TERM", &rs_term_name),
OPT_LONG("pipe-name", "filename of console pipe to emulate -C", &rs_pipe_name),
OPT_STR('a', "attribute", "parse an attribute in the specified context", NULL),
OPT_BOOL('C', "console", "grab console messages", &Options, Opt_console),
OPT_STR('a', "attribute", "parse an attribute in the specified context", NULL), OPT_BOOL('C', "console", "grab console messages", &Options, Opt_console),
#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),

View File

@ -58,7 +58,7 @@
#define NS_SCREAM_FILE 32
#define NS_SCREAM_SHARED 64
#define NS_SCREAM_ZOMBIE 128
#define NS_SCREAM_BUTTON 0xf0
#define NS_SCREAM_BUTTON 0xf00
#define NS_SCREAM_MASK (~(NS_SCREAM_UTMP|NS_SCREAM_PRVS))
@ -70,6 +70,11 @@
#define NS_ESC_SCREENRC 3
#define NS_ESC_INTERACTIVE 4
#define NS_SESS_NO_MON_MSG 1
#define NS_MON_TOGGLE_QUIET 0
#define NS_MON_TOGGLE_NOISY 1
/***************************************************************************/
@ -90,35 +95,43 @@ typedef struct __ns_hop {
typedef struct __ns_sess { /* a whole screen-session with many clients */
char *name; /* session name */
int where; /* local/remote */
int backend; /* screen/scream */
int backend; /* screen/scream/twin */
int nesting; /* 0=topLevel, 1=screen within a screen etc */
time_t timestamp; /* last updated when? see NS_SCREEN_UPD_FREQ */
time_t timestamp; /* last updated when? */
int delay; /* initialization delay */
int flags; /* miracle flags, see NS_SESS_* */
int fd; /* fd for communication */
int dsbb; /* default length of scroll-back buffer */
char *proto; /* protocol. usually "screen" */
char *host; /* host. numeric or symbolic. ("localhost") */
int port; /* port. usually TCP22: SSH */
int disp; /* display (used by twin etc., not screen) */
char *user; /* user. often current local user */
char *pass; /* password. used for su. for remote sessions, a
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 */
char *name; /* session name */
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 */
struct __ns_disp *dsps; /* first display (that with the lowest index) */
struct __ns_disp *curr; /* current display (NULL for none) */
struct __ns_sess *prvs; /* previous session in session list */
struct __ns_sess *next; /* next session in session list */
char *home; /* user's home dir. so we can find .screenrc */
char *sysrc; /* global screen config */
char escape,literal; /* talking to screen: defaults to ^A, a */
int escdef; /* where was the escape sequence defined? */
#ifdef NS_HAVE_TWIN
tdisplay twin;
char *twin_str;
tdisplay twin; /* twin-display */
char *twin_str; /* twin-display (string specifier) */
#endif
} _ns_sess;
@ -190,9 +203,14 @@ _ns_sess *ns_attach_by_sess(_ns_sess **,int *);
_ns_sess *ns_attach_by_URL(char *,char *,_ns_efuns **,int *,void *);
int ns_detach(_ns_sess **);
/* debug */
void ns_desc_twin(_ns_sess *,char *);
/* convenience */
int ns_run(_ns_efuns *, char *);
int ns_get_ssh_port(void);
int ns_get_twin_port(void);
int disp_get_real_by_screen(_ns_sess *,int);
int disp_get_screen_by_real(_ns_sess *,int);
@ -236,7 +254,7 @@ int ns_rsz_disp(_ns_sess *,int,int,int);
int ns_rem_disp(_ns_sess *,int,int);
int ns_ren_disp(_ns_sess *,int,char *);
int ns_log_disp(_ns_sess *,int,char *);
int ns_mon_disp(_ns_sess *,int);
int ns_mon_disp(_ns_sess *,int,int);
int ns_sbb_disp(_ns_sess *,int);
int ns_tog_region(_ns_sess *,_ns_disp *);

View File

@ -15,12 +15,6 @@
undef it, you're on your own. */
#define NS_PARANOID
/* compile in support for the GNU "screen" program as a backend */
#define NS_HAVE_SCREEN 1
/* compile in support for the "twin" program as a backend */
#undef NS_HAVE_TWIN
#define NS_MAXCMD 512
@ -38,6 +32,8 @@
#define NS_SCREEN_RC ".screenrc"
#define NS_TWIN_CALL "export TERM=xterm; twin %s"
#define NS_TWIN_OPTS "-hw=tty"
#define NS_TWIN_PARA "twin@"
#define NS_TWDISPLAY_OPTS "-" NS_TWIN_PARA "%s"
/* this should never change. the escape-char for an out-of-the-box "screen".
don't change this just because you set something else in your .screenrc */
@ -69,6 +65,7 @@
#define NS_SCREEN_SESS_T "This session is named '"
#define NS_SCREEN_VERSION_T "scre%2s %d.%d.%d %16s %32s"
#define NS_SCREEN_NO_DEBUG "Sorry, screen was compiled without -DDEBUG option."
#define NS_SCREEN_ACT_T "Activity in window "
/* should be 1s */
#define NS_INIT_DELAY 1

View File

@ -484,12 +484,15 @@ script_handler_es_display(char **params)
D_ESCREEN(("Toggle display\n"));
ns_tog_disp(sess);
} else if (!strcmp(p, "new")) {
if (!a || !*a || !strcasecmp(a, "ask")) {
if (!a || !*a) {
D_ESCREEN(("disp new\n"));
ns_add_disp(sess, no, "");
} else if (!a || !*a || !strcasecmp(a, "ask")) {
D_ESCREEN(("disp new ask\n"));
ns_add_disp(sess, no, NULL);
} else {
D_ESCREEN(("disp new \"%s\"\n", a));
ns_ren_disp(sess, no, a);
ns_add_disp(sess, no, a);
}
} else if (!strcmp(p, "title") || !strcmp(p, "name") || !strcmp(p, "rename")) {
if (!a || !*a || !strcasecmp(a, "ask")) {
@ -509,7 +512,7 @@ script_handler_es_display(char **params)
}
} else if (!strcmp(p, "watch") || !strcmp(p, "monitor")) {
D_ESCREEN(("Monitor display %d\n", no));
ns_mon_disp(sess, no);
ns_mon_disp(sess, no, NS_MON_TOGGLE_NOISY);
} else if (!strcmp(p, "back") || !strcmp(p, "backlog") || !strcmp(p, "scrollback")) {
D_ESCREEN(("View scrollback on display %d\n", no));
ns_sbb_disp(sess, no);