Wed May 22 11:37:19 2002 Michael Jennings (mej)

Latest Escreen work from Azundris <scream@azundris.com>.


SVN revision: 6270
This commit is contained in:
Michael Jennings 2002-05-22 15:38:35 +00:00
parent d185cd525c
commit 9ce5b286eb
16 changed files with 893 additions and 284 deletions

View File

@ -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>.
----------------------------------------------------------------------

View File

@ -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.

132
doc/escreen.cfg Normal file
View File

@ -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 ####################################################################

View File

@ -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));

View File

@ -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 */
#ifdef NS_DEBUG
fprintf(stderr, NS_PREFIX "font: %d: %p\n", n, menu_list->menus[n]->font);
#endif
if (menu_list->menus[n]->font) {
#ifdef NS_DEBUG
fprintf(stderr, NS_PREFIX "font: %d: %p\n", n, menu_list->menus[n]->font);
#endif
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') {

View File

@ -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_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
/* 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_screenrc(_ns_sess * s)
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
fn name of the file in question
whence which screenrc are we in?
<- error code */
int
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;
}

View File

@ -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

View File

@ -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)

View File

@ -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. */
}

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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