From 33b3deae2bb1c59bfd33d023f7bf0b0792521acf Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 6 Feb 2009 15:03:40 -0500 Subject: Fix compiling when multiuser mode is disabled. --- src/attacher.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/attacher.c b/src/attacher.c index 1866582..dfe111b 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -51,9 +51,7 @@ static void screen_builtin_lck __P((void)); #ifdef DEBUG static sigret_t AttacherChld __P(SIGPROTOARG); #endif -#ifdef MULTIUSER static sigret_t AttachSigCont __P(SIGPROTOARG); -#endif extern int real_uid, real_gid, eff_uid, eff_gid; extern char *SockName, *SockMatch, SockPath[]; @@ -75,7 +73,6 @@ static int multipipe[2]; #endif -#ifdef MULTIUSER static int ContinuePlease; static sigret_t @@ -85,7 +82,6 @@ AttachSigCont SIGDEFARG ContinuePlease = 1; SIGRETURN; } -#endif /* -- cgit v1.2.1 From f5ef12ef83f93b8325420aeff41134d971d1f779 Mon Sep 17 00:00:00 2001 From: Emanuele Giaquinta Date: Fri, 6 Feb 2009 15:09:54 -0500 Subject: DO_NOT_POLL_MASTER is never defined. --- src/attacher.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/attacher.c b/src/attacher.c index dfe111b..5db238f 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -403,9 +403,7 @@ int how; } -#if defined(DEBUG) || !defined(DO_NOT_POLL_MASTER) static int AttacherPanic = 0; -#endif #ifdef DEBUG static sigret_t @@ -595,7 +593,6 @@ Attacher() #endif for (;;) { -#ifndef DO_NOT_POLL_MASTER signal(SIGALRM, AttacherSigAlarm); alarm(15); pause(); @@ -605,10 +602,6 @@ Attacher() debug1("attacher: Panic! MasterPid %d does not exist.\n", MasterPid); AttacherPanic++; } -#else - pause(); -#endif -#if defined(DEBUG) || !defined(DO_NOT_POLL_MASTER) if (AttacherPanic) { fcntl(0, F_SETFL, 0); @@ -616,7 +609,6 @@ Attacher() printf("\nSuddenly the Dungeon collapses!! - You die...\n"); eexit(1); } -#endif #ifdef BSDJOBS if (SuspendPlease) { -- cgit v1.2.1 From 49c9d58217621434c04d670b4037bb3af7b0ec17 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 6 Feb 2009 20:14:24 -0500 Subject: Make sure NAME_MAX is defined. A different fix for this, suggested by Emanuele Giaquinta, was to #undef NAME_MAX before #define-ing it, but somehow I like this better. --- src/os.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/os.h b/src/os.h index be20572..2c1830d 100644 --- a/src/os.h +++ b/src/os.h @@ -41,7 +41,7 @@ # include #endif /* __bsdi__ || __386BSD__ || _CX_UX || hpux || _IBMR2 || linux */ -#ifndef HAVE_LONG_FILE_NAMES +#if !defined(HAVE_LONG_FILE_NAMES) && !defined(NAME_MAX) #define NAME_MAX 14 #endif -- cgit v1.2.1 From 76edff82efbe2f9c228e33b728d2e5f363c8509c Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 7 Feb 2009 19:44:54 -0500 Subject: Allow highlighting bell/monitor windows in caption The command is 'rendition'. Details in man-page. The defaults are currently set in a way to make sure that the new settings are noticeable. This changeset is preferred over either of the patches in savannah #18382, because it allows specifying the renditions for both bell and monitor windows, and is flexible enough that new renditions can be added if desired. --- src/ansi.c | 2 ++ src/comm.c | 1 + src/doc/screen.1 | 9 +++++++++ src/extern.h | 1 + src/help.c | 21 +++++++++++++++++++-- src/image.h | 8 ++++++++ src/process.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/screen.c | 16 ++++++++++++++++ 8 files changed, 101 insertions(+), 2 deletions(-) diff --git a/src/ansi.c b/src/ansi.c index 2ac0f60..a38bd12 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -78,6 +78,8 @@ struct mchar mchar_null; struct mchar mchar_blank = {' ' /* , 0, 0, ... */}; struct mchar mchar_so = {' ', A_SO /* , 0, 0, ... */}; +int renditions[NUM_RENDS] = {6750175 /* =B dd */, 6750205 /* =u dd */}; + /* keep string_t and string_t_string in sync! */ static char *string_t_string[] = { diff --git a/src/comm.c b/src/comm.c index ff218a0..b9b7a24 100644 --- a/src/comm.c +++ b/src/comm.c @@ -277,6 +277,7 @@ struct comm comms[RC_LAST + 1] = #ifdef COPY_PASTE { "removebuf", ARGS_0 }, #endif + { "rendition", ARGS_23 }, { "reset", NEED_FORE|ARGS_0 }, { "resize", NEED_DISPLAY|ARGS_0|ARGS_ORMORE }, { "screen", ARGS_0|ARGS_ORMORE }, diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 879dc83..53af799 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2518,6 +2518,15 @@ Unlinks the screen-exchange file used by the commands \*Qwritebuf\*U and \*Qreadbuf\*U. .sp .ne 3 +.B "rendition bell" | monitor | so +.RB "\fIattr\fR " [ \fIcolor ] +.PP +Change the way +.I screen +renders the titles of windows that have monitor or bell flags set in caption or hardstatus or windowlist. See the \*QSTRING ESCAPES\*U chapter for the syntax of the modifiers. +The default for monitor is currently \*Q=u dd\*U (underline, default colors) and for bell \*Q=B dd\*U (blink, default colors). +.sp +.ne 3 .B "reset" .PP Reset the virtual terminal to its \*Qpower-on\*U values. Useful when strange diff --git a/src/extern.h b/src/extern.h index 6ca155b..e803d36 100644 --- a/src/extern.h +++ b/src/extern.h @@ -50,6 +50,7 @@ extern void Finit __P((int)); extern void MakeNewEnv __P((void)); extern char *MakeWinMsg __P((char *, struct win *, int)); extern char *MakeWinMsgEv __P((char *, struct win *, int, int, struct event *, int)); +extern int AddWinMsgRend __P((const char *, int)); extern void PutWinMsg __P((char *, int, int)); #ifdef BSDWAIT extern void WindowDied __P((struct win *, union wait, int)); diff --git a/src/help.c b/src/help.c index b0d0db0..106af6a 100644 --- a/src/help.c +++ b/src/help.c @@ -40,6 +40,7 @@ extern struct display *display, *displays; extern struct win *windows; extern char *noargs[]; extern struct mchar mchar_blank, mchar_so; +extern int renditions[]; extern unsigned char *blank; extern struct win *wtab[]; #ifdef MAPKEYS @@ -1079,6 +1080,8 @@ int isblank; int yoff, xoff = 0; struct wlistdata *wlistdata; struct win *group; + struct mchar mchar_rend = mchar_blank; + struct mchar *mchar = (struct mchar *)0; if (i == MAXWIN) return; @@ -1094,9 +1097,23 @@ int isblank; if (i != pos && isblank) while (n && str[n - 1] == ' ') n--; - LPutWinMsg(flayer, str, (i == pos || !isblank) ? flayer->l_width : n, i == pos ? &mchar_so : &mchar_blank, xoff, y + yoff); + if (i == pos) + mchar = &mchar_so; + else if (wtab[i]->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1) + { + mchar = &mchar_rend; + ApplyAttrColor(renditions[REND_MONITOR], mchar); + } + else if ((wtab[i]->w_bell == BELL_DONE || wtab[i]->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1) + { + mchar = &mchar_rend; + ApplyAttrColor(renditions[REND_BELL], mchar); + } + else + mchar = &mchar_blank; + LPutWinMsg(flayer, str, (i == pos || !isblank) ? flayer->l_width : n, mchar, xoff, y + yoff); if (xoff) - LPutWinMsg(flayer, "", xoff, i == pos ? &mchar_so : &mchar_blank, 0, y + yoff); + LPutWinMsg(flayer, "", xoff, mchar, 0, y + yoff); #if 0 LPutStr(flayer, str, n, i == pos ? &mchar_so : &mchar_blank, 0, y + yoff); if (i == pos || !isblank) diff --git a/src/image.h b/src/image.h index 67d0aec..5a65ebf 100644 --- a/src/image.h +++ b/src/image.h @@ -166,3 +166,11 @@ IFDWCHAR((mc)->mbcs = 0; ) \ # define cole2i(c) ((c) ^ 9) # endif #endif + +enum +{ + REND_BELL = 0, + REND_MONITOR, + NUM_RENDS +}; + diff --git a/src/process.c b/src/process.c index 929afba..690b677 100644 --- a/src/process.c +++ b/src/process.c @@ -106,6 +106,7 @@ extern char *kmapadef[]; extern char *kmapmdef[]; #endif extern struct mchar mchar_so, mchar_null; +extern int renditions[]; extern int VerboseCreate; #ifdef UTF8 extern char *screenencodings; @@ -3746,6 +3747,36 @@ int key; nattr2color = n; break; #endif + case RC_RENDITION: + i = -1; + if (strcmp(args[0], "bell") == 0) + { + i = REND_BELL; + } + else if (strcmp(args[0], "monitor") == 0) + { + i = REND_MONITOR; + } + else if (strcmp(args[0], "so") != 0) + { + Msg(0, "Invalid option '%s' for rendition", args[0]); + break; + } + + ++args; + ++argl; + + if (i != -1) + { + renditions[i] = ParseAttrColor(args[0], args[1], 1); + WindowChanged((struct win *)0, 'w'); + WindowChanged((struct win *)0, 'W'); + WindowChanged((struct win *)0, 0); + break; + } + + /* We are here, means we want to set the sorendition. */ + /* FALLTHROUGH*/ case RC_SORENDITION: i = 0; if (*args) @@ -3754,6 +3785,7 @@ int key; if (i == -1) break; ApplyAttrColor(i, &mchar_so); + WindowChanged((struct win *)0, 0); debug2("--> %x %x\n", mchar_so.attr, mchar_so.color); } if (msgok) @@ -5238,6 +5270,7 @@ int where; s = ss = buf; for (pp = ((flags & 4) && where >= 0) ? wtab + where + 1: wtab; pp < wtab + MAXWIN; pp++) { + int rend = -1; if (pp - wtab == where && ss == buf) ss = s; if ((p = *pp) == 0) @@ -5258,6 +5291,16 @@ int where; *s++ = ' '; *s++ = ' '; } + if (((flags & 4) && where >= 0 && where < p->w_number) || + (!(flags & 4) && where >= 0 && where > p->w_number)) + { + if (p->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1) + rend = renditions[REND_MONITOR]; + else if ((p->w_bell == BELL_DONE || p->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1) + rend = renditions[REND_BELL]; + } + if (rend != -1) + AddWinMsgRend(s, rend); sprintf(s, "%d", p->w_number); if (p->w_number == where) ss = s; @@ -5273,6 +5316,8 @@ int where; *s++ = ' '; strncpy(s, cmd, l); s += l; + if (rend != -1) + AddWinMsgRend(s, -1); } *s = 0; return ss; diff --git a/src/screen.c b/src/screen.c index 7239560..512e9f6 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2417,6 +2417,22 @@ time_t now; return bt->result; } +int +AddWinMsgRend(str, r) +const char *str; +int r; +{ + if (winmsg_numrend >= MAX_WINMSG_REND || str < winmsg_buf || + str >= winmsg_buf + MAXSTR) + return -1; + + winmsg_rend[winmsg_numrend] = r; + winmsg_rendpos[winmsg_numrend] = str - winmsg_buf; + winmsg_numrend++; + + return 0; +} + char * MakeWinMsgEv(str, win, esc, padlen, ev, rec) char *str; -- cgit v1.2.1 From f04882c76d0d23a35942e736e89ef19268f541b5 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 7 Feb 2009 20:00:26 -0500 Subject: Copyright for 2009 --- src/acls.c | 2 +- src/acls.h | 2 +- src/ansi.c | 2 +- src/ansi.h | 2 +- src/attacher.c | 2 +- src/comm.c | 2 +- src/display.c | 2 +- src/display.h | 2 +- src/extern.h | 2 +- src/fileio.c | 2 +- src/help.c | 4 ++-- src/image.h | 2 +- src/input.c | 2 +- src/layer.c | 2 +- src/layer.h | 7 ++++++- src/loadav.c | 2 +- src/logfile.c | 2 +- src/logfile.h | 2 +- src/mark.c | 2 +- src/mark.h | 2 +- src/misc.c | 2 +- src/nethack.c | 2 +- src/os.h | 2 +- src/patchlevel.h | 2 +- src/process.c | 2 +- src/pty.c | 2 +- src/putenv.c | 2 +- src/resize.c | 2 +- src/sched.c | 2 +- src/sched.h | 2 +- src/screen.c | 2 +- src/screen.h | 2 +- src/search.c | 2 +- src/socket.c | 2 +- src/teln.c | 2 +- src/term.c | 2 +- src/termcap.c | 2 +- src/tty.sh | 2 +- src/utmp.c | 2 +- src/window.c | 2 +- src/window.h | 2 +- 41 files changed, 47 insertions(+), 42 deletions(-) diff --git a/src/acls.c b/src/acls.c index 02b182b..d764023 100644 --- a/src/acls.c +++ b/src/acls.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/acls.h b/src/acls.h index a62933e..907e953 100644 --- a/src/acls.h +++ b/src/acls.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/ansi.c b/src/ansi.c index a38bd12..760e983 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/ansi.h b/src/ansi.h index cada63a..270b76f 100644 --- a/src/ansi.h +++ b/src/ansi.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/attacher.c b/src/attacher.c index 5db238f..a416ec1 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/comm.c b/src/comm.c index b9b7a24..09ec1ba 100644 --- a/src/comm.c +++ b/src/comm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/display.c b/src/display.c index 3e0bdae..ec13ec7 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/display.h b/src/display.h index de25859..ee5a03b 100644 --- a/src/display.h +++ b/src/display.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/extern.h b/src/extern.h index e803d36..1bf7c4b 100644 --- a/src/extern.h +++ b/src/extern.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/fileio.c b/src/fileio.c index 1dd13c2..09a9150 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/help.c b/src/help.c index 106af6a..ac7209f 100644 --- a/src/help.c +++ b/src/help.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -503,7 +503,7 @@ static const char cpmsg[] = "\ \n\ Screen version %v\n\ \n\ -Copyright (c) 2008 Juergen Weigert, Michael Schroeder, Micah Cowan, Sadrul Habib Chowdhury\n\ +Copyright (c) 2008, 2009 Juergen Weigert, Michael Schroeder, Micah Cowan, Sadrul Habib Chowdhury\n\ Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 Juergen Weigert, Michael Schroeder\n\ Copyright (c) 1987 Oliver Laumann\n\ \n\ diff --git a/src/image.h b/src/image.h index 5a65ebf..e267d91 100644 --- a/src/image.h +++ b/src/image.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/input.c b/src/input.c index c9624a6..ae6cde4 100644 --- a/src/input.c +++ b/src/input.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/layer.c b/src/layer.c index a2fd74a..487e45e 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/layer.h b/src/layer.h index d45a5c3..572c9e6 100644 --- a/src/layer.h +++ b/src/layer.h @@ -1,4 +1,9 @@ -/* Copyright (c) 1995-2002 +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Copyright (c) 1987 Oliver Laumann diff --git a/src/loadav.c b/src/loadav.c index 3e2c28e..770010c 100644 --- a/src/loadav.c +++ b/src/loadav.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/logfile.c b/src/logfile.c index 0e2eee0..edee89d 100644 --- a/src/logfile.c +++ b/src/logfile.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/logfile.h b/src/logfile.h index 59c4b36..51f559d 100644 --- a/src/logfile.h +++ b/src/logfile.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/mark.c b/src/mark.c index 9ff7b65..be22df7 100644 --- a/src/mark.c +++ b/src/mark.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/mark.h b/src/mark.h index d9e3c33..5f75ed6 100644 --- a/src/mark.h +++ b/src/mark.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/misc.c b/src/misc.c index dd20ab1..c56d87a 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/nethack.c b/src/nethack.c index 788fbbe..3725922 100644 --- a/src/nethack.c +++ b/src/nethack.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/os.h b/src/os.h index 2c1830d..b56b660 100644 --- a/src/os.h +++ b/src/os.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/patchlevel.h b/src/patchlevel.h index 2eebfb4..86e2475 100644 --- a/src/patchlevel.h +++ b/src/patchlevel.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/process.c b/src/process.c index 690b677..13ed377 100644 --- a/src/process.c +++ b/src/process.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/pty.c b/src/pty.c index 6a6bdd6..def7f93 100644 --- a/src/pty.c +++ b/src/pty.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/putenv.c b/src/putenv.c index f2c18df..2a907f9 100644 --- a/src/putenv.c +++ b/src/putenv.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/resize.c b/src/resize.c index a9a8772..0bf5f3d 100644 --- a/src/resize.c +++ b/src/resize.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/sched.c b/src/sched.c index 74e1afd..c2e00df 100644 --- a/src/sched.c +++ b/src/sched.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/sched.h b/src/sched.h index 5160d9c..fe94642 100644 --- a/src/sched.h +++ b/src/sched.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/screen.c b/src/screen.c index 512e9f6..3d1da36 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/screen.h b/src/screen.h index c0fdecb..d80f0d5 100644 --- a/src/screen.h +++ b/src/screen.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/search.c b/src/search.c index 965dfe9..cd2693e 100644 --- a/src/search.c +++ b/src/search.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/socket.c b/src/socket.c index 48e8ad9..acdd7d1 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/teln.c b/src/teln.c index 518fbe7..1764dbc 100644 --- a/src/teln.c +++ b/src/teln.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/term.c b/src/term.c index 8a04a8a..8cf2729 100644 --- a/src/term.c +++ b/src/term.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/termcap.c b/src/termcap.c index fb9f56c..9bff5cc 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/tty.sh b/src/tty.sh index 54a9a72..f2afd54 100644 --- a/src/tty.sh +++ b/src/tty.sh @@ -24,7 +24,7 @@ sed -e '1,26d' \ chmod -w $1 exit 0 -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/utmp.c b/src/utmp.c index 3214df6..20f3c3c 100644 --- a/src/utmp.c +++ b/src/utmp.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/window.c b/src/window.c index 5b15878..4754a98 100644 --- a/src/window.c +++ b/src/window.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) diff --git a/src/window.h b/src/window.h index eddf6ac..6c6ca76 100644 --- a/src/window.h +++ b/src/window.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008 +/* Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) -- cgit v1.2.1 From a62adf5f7df9bdcabcecba002699af7980dd9203 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 8 Feb 2009 16:14:46 -0500 Subject: Fix the rendition of some specific %w flags. --- src/process.c | 9 ++++++--- src/screen.c | 4 +--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/process.c b/src/process.c index 13ed377..73a7964 100644 --- a/src/process.c +++ b/src/process.c @@ -5272,7 +5272,11 @@ int where; { int rend = -1; if (pp - wtab == where && ss == buf) - ss = s; + { + ss = s; + if (flags & 8) + break; + } if ((p = *pp) == 0) continue; if ((flags & 1) && display && p == D_fore) @@ -5291,8 +5295,7 @@ int where; *s++ = ' '; *s++ = ' '; } - if (((flags & 4) && where >= 0 && where < p->w_number) || - (!(flags & 4) && where >= 0 && where > p->w_number)) + if (!(flags & 4) || where < 0 || ((flags & 4) && where < p->w_number)) { if (p->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1) rend = renditions[REND_MONITOR]; diff --git a/src/screen.c b/src/screen.c index 3d1da36..5064652 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2688,9 +2688,7 @@ int rec; oldfore = D_fore; D_fore = win; } - ss = AddWindows(p, l - 1, (*s == 'w' ? 0 : 1) | (longflg ? 0 : 2) | (plusflg ? 4 : 0), win ? win->w_number : -1); - if (minusflg) - *ss = 0; + ss = AddWindows(p, l - 1, (*s == 'w' ? 0 : 1) | (longflg ? 0 : 2) | (plusflg ? 4 : 0) | (minusflg ? 8 : 0), win ? win->w_number : -1); if (display) D_fore = oldfore; } -- cgit v1.2.1 From 52b776c6f253c39e7b5cf2802a634b44c07ea8ea Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 12 Feb 2009 23:28:58 -0500 Subject: Multiple input history Based on initial patch by Romain Francoise. I had actually committed his patch in a branch, but some bits of the implementation looked a bit more complicated than necessary. So I scratched that for this, which looks pretty similar, but I think is a bit simpler to understand. The behaviour is mostly the same, e.g. duplicate commands are moved at the beginning of the history, and not added again. There is currently no limit to the number of inputs to save in history. But it can certainly be added if necessary. Fixes #25074. --- src/input.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/src/input.c b/src/input.c index ae6cde4..165a4c8 100644 --- a/src/input.c +++ b/src/input.c @@ -46,10 +46,14 @@ struct inpline char buf[101]; /* text buffer */ int len; /* length of the editible string */ int pos; /* cursor position in editable string */ + struct inpline *next, *prev; }; -static struct inpline inphist; /* XXX: should be a dynamic list */ - +/* 'inphist' is used to store the current input when scrolling through history. + * inpline->prev == history-prev + * inpline->next == history-next + */ +static struct inpline inphist; struct inpdata { @@ -147,6 +151,7 @@ int data; inpdata->inpmaxlen = len; inpdata->inpfinfunc = finfunc; inpdata->inp.pos = inpdata->inp.len = 0; + inpdata->inp.prev = inphist.prev; inpdata->inpmode = mode; inpdata->privdata = data; if (!priv) @@ -204,6 +209,7 @@ int *plen; char ch; struct inpdata *inpdata; struct display *inpdisplay; + int prev, next; inpdata = (struct inpdata *)flayer->l_data; inpdisplay = display; @@ -323,22 +329,27 @@ int *plen; LGotoPos(flayer, ++x, INPUTLINE); inpdata->inp.pos++; } - else if (ch == '\020' || (unsigned char)ch == 0220) /* CTRL-P */ - { + else if ((prev = ((ch == '\020' || (unsigned char)ch == 0220) && /* CTRL-P */ + inpdata->inp.prev)) || + (next = ((ch == '\016' || (unsigned char)ch == 0216) && /* CTRL-N */ + inpdata->inp.next))) + { struct mchar mc; mc = mchar_so; if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO)) LClearArea(flayer, inpdata->inpstringlen, INPUTLINE, inpdata->inpstringlen + inpdata->inp.len - 1, INPUTLINE, 0, 0); - inpdata->inp = inphist; /* structure copy */ + if (prev && !inpdata->inp.next) + inphist = inpdata->inp; + memcpy(&inpdata->inp, prev ? inpdata->inp.prev : inpdata->inp.next, sizeof(struct inpline)); if (inpdata->inp.len > inpdata->inpmaxlen) inpdata->inp.len = inpdata->inpmaxlen; if (inpdata->inp.pos > inpdata->inp.len) inpdata->inp.pos = inpdata->inp.len; - x = inpdata->inpstringlen; + x = inpdata->inpstringlen; p = inpdata->inp.buf; - + if (!(inpdata->inpmode & INP_NOECHO)) { while (p < inpdata->inp.buf+inpdata->inp.len) @@ -347,7 +358,7 @@ int *plen; LPutChar(flayer, &mc, x++, INPUTLINE); } } - x = inpdata->inpstringlen + inpdata->inp.pos; + x = inpdata->inpstringlen + inpdata->inp.pos; LGotoPos(flayer, x, INPUTLINE); } @@ -359,9 +370,36 @@ int *plen; inpdata->inp.buf[inpdata->inp.len] = 0; if (inpdata->inp.len && !(inpdata->inpmode & (INP_NOECHO | INP_RAW))) - inphist = inpdata->inp; /* structure copy */ - - flayer->l_data = 0; /* so inpdata does not get freed */ + { + struct inpline *store; + + /* Look for a duplicate first */ + for (store = inphist.prev; store; store = store->prev) + { + if (strcmp(store->buf, inpdata->inp.buf) == 0) + { + if (store->next) + store->next->prev = store->prev; + if (store->prev) + store->prev->next = store->next; + store->pos = inpdata->inp.pos; + break; + } + } + + if (!store) + { + store = malloc(sizeof(struct inpline)); + memcpy(store, &inpdata->inp, sizeof(struct inpline)); + } + store->next = &inphist; + store->prev = inphist.prev; + if (inphist.prev) + inphist.prev->next = store; + inphist.prev = store; + } + + flayer->l_data = 0; /* so inpdata does not get freed */ InpAbort(); /* redisplays... */ *ppbuf = pbuf; *plen = len; -- cgit v1.2.1 From ad76d9023dd21877816b129d4f6e0c4c4d529cde Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 13 Feb 2009 19:42:05 -0500 Subject: terminfo goodness for 256-color support Taken from http://www.xvx.ca/~awg/emacs-colors-howto.txt, written by Trent W Buck. --- src/terminfo/screeninfo.src | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/terminfo/screeninfo.src b/src/terminfo/screeninfo.src index e68f537..c5f254a 100644 --- a/src/terminfo/screeninfo.src +++ b/src/terminfo/screeninfo.src @@ -71,3 +71,10 @@ screen-s|VT 100/ANSI X3.64 virtual terminal with hardstatus line, civis=\E[?25l, cnorm=\E[34h\E[?25h, cvvis=\E[34l, op=\E[39;49m, setab=\E[4%p1%dm, setaf=\E[3%p1%dm, acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++\054\054hhII00, +screen-256color|VT 100/ANSI X3.64 virtual terminal, + ccc, + colors#256, pairs#32767, + initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, + setab=\E[48;5;%p1%dm, setaf=\E[38;5;%p1%dm, + setb=\E[48;5;%p1%dm, setf=\E[38;5;%p1%dm, + use=screen, -- cgit v1.2.1 From 903c7604f7715f0c9453d4e5dba995c2ac927769 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 13 Feb 2009 22:51:42 -0500 Subject: Customizable digraphs This closes a debian wishlist more than 10 years old (#25096), and also a less old feature request on savannah (#25279). --- src/comm.c | 2 +- src/doc/screen.1 | 7 +++- src/process.c | 111 ++++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 85 insertions(+), 35 deletions(-) diff --git a/src/comm.c b/src/comm.c index 09ec1ba..aedfe49 100644 --- a/src/comm.c +++ b/src/comm.c @@ -175,7 +175,7 @@ struct comm comms[RC_LAST + 1] = #ifdef DETACH { "detach", NEED_DISPLAY|ARGS_01 }, #endif - { "digraph", NEED_LAYER|ARGS_01 }, + { "digraph", NEED_LAYER|ARGS_012 }, { "dinfo", NEED_DISPLAY|ARGS_0 }, { "displays", NEED_LAYER|ARGS_0 }, { "dumptermcap", NEED_FORE|ARGS_0 }, diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 53af799..ec695e7 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -1645,7 +1645,7 @@ Shows a tabular listing of all currently connected user front-ends (displays). This is most useful for multiuser sessions. .sp .ne 3 -.BR "digraph " [ \fIpreset ] +.BR "digraph " [ \fIpreset [ \fI unicode-value ] ] .PP This command prompts the user for a digraph sequence. The next two characters typed are looked up in a builtin table and the @@ -1659,6 +1659,11 @@ number instead. The optional argument is treated as user input, thus one can create an \*Qumlaut\*U key. For example the command "bindkey ^K digraph '"'" enables the user to generate an a-umlaut by typing CTRL-K a. +When a non-zero +.I unicode-value +is specified, a new digraph is created with the specified preset. The digraph is unset +if a zero value is provided for the +.I unicode-value. .sp .ne 3 .B dumptermcap diff --git a/src/process.c b/src/process.c index 73a7964..5318b8d 100644 --- a/src/process.c +++ b/src/process.c @@ -154,6 +154,7 @@ static void pass2 __P((char *, int, char *)); static void pow_detach_fn __P((char *, int, char *)); #endif static void digraph_fn __P((char *, int, char *)); +static int digraph_find __P((const char *buf)); static void confirm_fn __P((char *, int, char *)); static int IsOnDisplay __P((struct win *)); static void ResizeRegions __P((char *, int)); @@ -229,9 +230,18 @@ int kmap_extn; static int maptimeout = 300; #endif +#ifndef MAX_DIGRAPH +#define MAX_DIGRAPH 512 +#endif + +struct digraph +{ + unsigned char d[2]; + int value; +}; /* digraph table taken from old vim and rfc1345 */ -static const unsigned char digraphs[][3] = { +static struct digraph digraphs[MAX_DIGRAPH + 1] = { {' ', ' ', 160}, /*   */ {'N', 'S', 160}, /*   */ {'~', '!', 161}, /* ¡ */ @@ -420,6 +430,44 @@ static char *resizeprompts[] = { "resize -l -b # lines: ", }; +static int +parse_input_int(buf, len, val) +const char *buf; +int len; +int *val; +{ + int x = 0, i; + if (len >= 1 && ((*buf == 'U' && buf[1] == '+') || (*buf == '0' && (buf[1] == 'x' || buf[1] == 'X')))) + { + x = 0; + for (i = 2; i < len; i++) + { + if (buf[i] >= '0' && buf[i] <= '9') + x = x * 16 | (buf[i] - '0'); + else if (buf[i] >= 'a' && buf[i] <= 'f') + x = x * 16 | (buf[i] - ('a' - 10)); + else if (buf[i] >= 'A' && buf[i] <= 'F') + x = x * 16 | (buf[i] - ('A' - 10)); + else + return 0; + } + } + else if (buf[0] == '0') + { + x = 0; + for (i = 1; i < len; i++) + { + if (buf[i] < '0' || buf[i] > '7') + return 0; + x = x * 8 | (buf[i] - '0'); + } + } + else + return 0; + *val = x; + return 1; +} + char *noargs[1]; void @@ -3635,6 +3683,20 @@ int key; break; case RC_DIGRAPH: + if (argl && argl[0] > 0 && argl[1] > 0) + { + if (argl[0] != 2) + { + Msg(0, "Two characters expected to define a digraph"); + break; + } + i = digraph_find(args[0]); + digraphs[i].d[0] = args[0][0]; + digraphs[i].d[1] = args[0][1]; + if (!parse_input_int(args[1], argl[1], &digraphs[i].value)) + digraphs[i].value = atoi(args[1]); + break; + } Input("Enter digraph: ", 10, INP_EVERY, digraph_fn, NULL, 0); if (*args && **args) { @@ -6240,6 +6302,18 @@ char *data; } #endif /* PASSWORD */ +static int +digraph_find(buf) +const char *buf; +{ + int i; + for (i = 0; i < MAX_DIGRAPH && digraphs[i].d[0]; i++) + if ((digraphs[i].d[0] == (unsigned char)buf[0] && digraphs[i].d[1] == (unsigned char)buf[1]) || + (digraphs[i].d[0] == (unsigned char)buf[1] && digraphs[i].d[1] == (unsigned char)buf[0])) + break; + return i; +} + static void digraph_fn(buf, len, data) char *buf; @@ -6291,43 +6365,14 @@ char *data; /* dummy */ } if (len < 2) return; - if (len >= 1 && ((*buf == 'U' && buf[1] == '+') || (*buf == '0' && (buf[1] == 'x' || buf[1] == 'X')))) + if (!parse_input_int(buf, len, &x)) { - x = 0; - for (i = 2; i < len; i++) - { - if (buf[i] >= '0' && buf[i] <= '9') - x = x * 16 | (buf[i] - '0'); - else if (buf[i] >= 'a' && buf[i] <= 'f') - x = x * 16 | (buf[i] - ('a' - 10)); - else if (buf[i] >= 'A' && buf[i] <= 'F') - x = x * 16 | (buf[i] - ('A' - 10)); - else - break; - } - } - else if (buf[0] == '0') - { - x = 0; - for (i = 1; i < len; i++) - { - if (buf[i] < '0' || buf[i] > '7') - break; - x = x * 8 | (buf[i] - '0'); - } - } - else - { - for (i = 0; i < (int)(sizeof(digraphs)/sizeof(*digraphs)); i++) - if ((digraphs[i][0] == (unsigned char)buf[0] && digraphs[i][1] == (unsigned char)buf[1]) || - (digraphs[i][0] == (unsigned char)buf[1] && digraphs[i][1] == (unsigned char)buf[0])) - break; - if (i == (int)(sizeof(digraphs)/sizeof(*digraphs))) + i = digraph_find(buf); + if ((x = digraphs[i].value) <= 0) { Msg(0, "Unknown digraph"); return; } - x = digraphs[i][2]; } i = 1; *buf = x; -- cgit v1.2.1 From 6e57c4f1e8e557669a678f143329afc297c43d3f Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Wed, 18 Feb 2009 12:58:20 -0800 Subject: Correct version from 4.01.00devel to 4.10.00devel --- src/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/patchlevel.h b/src/patchlevel.h index 86e2475..7c02e0c 100644 --- a/src/patchlevel.h +++ b/src/patchlevel.h @@ -532,7 +532,7 @@ #define ORIGIN "FAU" #define REV 4 -#define VERS 1 +#define VERS 10 #define PATCHLEVEL 0 #define DATE "2-May-06" #define STATE "devel" -- cgit v1.2.1 From 35804d79c8a3ee7b2447e4289511c6345e048845 Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Thu, 19 Feb 2009 23:46:36 -0800 Subject: Don't trim the trailing spaces from %-w ! --- src/process.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/process.c b/src/process.c index 5318b8d..ee2f915 100644 --- a/src/process.c +++ b/src/process.c @@ -5334,11 +5334,7 @@ int where; { int rend = -1; if (pp - wtab == where && ss == buf) - { - ss = s; - if (flags & 8) - break; - } + ss = s; if ((p = *pp) == 0) continue; if ((flags & 1) && display && p == D_fore) @@ -5368,7 +5364,11 @@ int where; AddWinMsgRend(s, rend); sprintf(s, "%d", p->w_number); if (p->w_number == where) - ss = s; + { + ss = s; + if (flags & 8) + break; + } s += strlen(s); if (display && p == D_fore) *s++ = '*'; -- cgit v1.2.1 From 5ee7c611dc6b4f2d6228b5f3967fa8adb85ebfaf Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 20 Feb 2009 13:50:26 -0500 Subject: Fix caption for 'select -' --- src/process.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/process.c b/src/process.c index ee2f915..66e7cd4 100644 --- a/src/process.c +++ b/src/process.c @@ -5330,6 +5330,11 @@ int where; int l; s = ss = buf; + if ((flags & 8) && where < 0) + { + *s = 0; + return ss; + } for (pp = ((flags & 4) && where >= 0) ? wtab + where + 1: wtab; pp < wtab + MAXWIN; pp++) { int rend = -1; -- cgit v1.2.1 From b4ba7b0a3c5be36050ef0deb68a6b19fd46f501e Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Sun, 22 Feb 2009 00:19:57 -0800 Subject: Don't push bell/monitor attributes onto stack without removing. --- src/process.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/process.c b/src/process.c index 66e7cd4..71c69e1 100644 --- a/src/process.c +++ b/src/process.c @@ -5358,6 +5358,12 @@ int where; *s++ = ' '; *s++ = ' '; } + if (p->w_number == where) + { + ss = s; + if (flags & 8) + break; + } if (!(flags & 4) || where < 0 || ((flags & 4) && where < p->w_number)) { if (p->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1) @@ -5368,12 +5374,6 @@ int where; if (rend != -1) AddWinMsgRend(s, rend); sprintf(s, "%d", p->w_number); - if (p->w_number == where) - { - ss = s; - if (flags & 8) - break; - } s += strlen(s); if (display && p == D_fore) *s++ = '*'; -- cgit v1.2.1 From 476039279dcd62c8759b8b15709371d77a85d380 Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Mon, 23 Feb 2009 21:18:03 -0800 Subject: $STY still reflects the old session name, but only in existing shells. --- src/doc/screen.1 | 3 ++- src/doc/screen.texinfo | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index ec695e7..54ae2d2 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2626,7 +2626,8 @@ latter is useful if used with screen's \*Q-X\*U option. Rename the current session. Note, that for \*Qscreen -list\*U the name shows up with the process-id prepended. If the argument \*Qname\*U is omitted, the name of this session is displayed. Caution: The $STY -environment variables still reflects the old name. This may result in +environment variables will still reflect the old name in pre-existing +shells. This may result in confusion. The default is constructed from the tty and host names. .sp diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 2c60317..1e02c87 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1758,7 +1758,8 @@ Rename the current session. Note that for @code{screen -list} the name shows up with the process-id prepended. If the argument @var{name} is omitted, the name of this session is displayed.@* @emph{Caution}: The @code{$STY} -environment variable still reflects the old name. This may result in +environment variable will still reflect the old name in pre-existing +shells. This may result in confusion. The default is constructed from the tty and host names. @end deffn -- cgit v1.2.1 From c8a9a407a15068f8ac27966237a699550dfc512a Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Wed, 25 Feb 2009 10:05:11 -0800 Subject: Revert 6357c4f1 (wtf was I thinking?) --- src/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/patchlevel.h b/src/patchlevel.h index 7c02e0c..86e2475 100644 --- a/src/patchlevel.h +++ b/src/patchlevel.h @@ -532,7 +532,7 @@ #define ORIGIN "FAU" #define REV 4 -#define VERS 10 +#define VERS 1 #define PATCHLEVEL 0 #define DATE "2-May-06" #define STATE "devel" -- cgit v1.2.1 From 8ddf77842aa041ebb6ea4ec793b134a130d78cf3 Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Wed, 25 Feb 2009 10:08:54 -0800 Subject: Revert d9795ca13, which broke back-tab. END key and C-a ^H seem still to work somehow. --- src/termcap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/termcap.c b/src/termcap.c index 9bff5cc..2b63a24 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -553,6 +553,8 @@ int map; else break; } + if (n < KMAP_KEYS) + domap = 1; if (map == 0 && domap) return 0; if (map && !domap) -- cgit v1.2.1 From 01f23034c7abad0e5f3c5cf6dfe51893dc5826e4 Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Thu, 26 Feb 2009 20:17:33 -0800 Subject: Don't segfault on "layout number" when not on a layout (thanks Soliton) --- src/process.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/process.c b/src/process.c index 71c69e1..b5474e7 100644 --- a/src/process.c +++ b/src/process.c @@ -4162,6 +4162,11 @@ int key; { int old; struct layout *lay; + if (!D_layout) + { + Msg(0, "not on a layout"); + break; + } if (!args[1]) { Msg(0, "This is layout %d (%s).\n", D_layout->lay_number, D_layout->lay_title); -- cgit v1.2.1 From 7fd224a668c06566f4e2c9ace4a35ad9a1e4214a Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 28 Feb 2009 00:23:28 -0500 Subject: Update manual for 'rendition' Fixes #25668. --- src/doc/screen.1 | 2 +- src/doc/screen.texinfo | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 54ae2d2..314b758 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2529,7 +2529,7 @@ Unlinks the screen-exchange file used by the commands \*Qwritebuf\*U and Change the way .I screen renders the titles of windows that have monitor or bell flags set in caption or hardstatus or windowlist. See the \*QSTRING ESCAPES\*U chapter for the syntax of the modifiers. -The default for monitor is currently \*Q=u dd\*U (underline, default colors) and for bell \*Q=B dd\*U (blink, default colors). +The default for monitor is currently \*Q=b \*U (bold, active colors) and for bell \*Q=ub \*U (underline, bold and active colors). .sp .ne 3 .B "reset" diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 1e02c87..7a5d189 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1071,6 +1071,8 @@ Store a string to a register. @xref{Registers}. Kill current region. @xref{Regions}. @item removebuf Delete the screen-exchange file. @xref{Screen Exchange}. +@item rendition bell | monitor | so @var{attr} [@var{color}] +Change text attributes in caption for flagged windows. @xref{Rendition}. @item reset Reset the terminal settings for the window. @xref{Reset}. @item resize [(+/-)lines] @@ -4332,6 +4334,7 @@ categories. * Version:: Display the version of @code{screen}. * Zombie:: Keep dead windows. * Printcmd:: Set command for VT100 printer port emulation. +* Rendition:: Change text attributes in caption for flagged windows. * Sorendition:: Change the text highlighting method. * Attrcolor:: Map attributes to colors. * Setsid:: Change process group management. @@ -4557,7 +4560,7 @@ If it exits normally ('0'), the window disappears. Any other exit value causes the window to become a zombie. @end deffn -@node Printcmd, Sorendition, Zombie, Miscellaneous +@node Printcmd, Rendition, Zombie, Miscellaneous @section Printcmd @deffn Command printcmd [@var{cmd}] (none)@* @@ -4573,7 +4576,20 @@ Warning: Be careful with this command! If other user have write access to your terminal, they will be able to fire off print commands. @end deffn -@node Sorendition, Attrcolor, Printcmd, Miscellaneous +@node Rendition, Sorendition, Printcmd, Miscellaneous +@section Rendition +@deffn Command rendition bell | monitor | so @var{attr} [@var{color}] +(none)@* +Change the way screen renders the titles of windows that have monitor +or bell flags set in caption or hardstatus or windowlist. +See the chapter +about string escapes (@pxref{String Escapes}) for the syntax of +the modifiers. The default for monitor is currently @samp{=b} (bold, +active colors), and for bell is @samp{=ub} (underline, bold and +active colors). +@end deffn + +@node Sorendition, Attrcolor, Rendition, Miscellaneous @section Sorendition @deffn Command sorendition [@var{attr} [@var{color}]] (none)@* -- cgit v1.2.1 From 5c2192b2789765a00356b41279ea71d940fab8c5 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 28 Feb 2009 01:14:09 -0500 Subject: Change the default renditions. --- src/ansi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansi.c b/src/ansi.c index 760e983..29fbe0d 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -78,7 +78,7 @@ struct mchar mchar_null; struct mchar mchar_blank = {' ' /* , 0, 0, ... */}; struct mchar mchar_so = {' ', A_SO /* , 0, 0, ... */}; -int renditions[NUM_RENDS] = {6750175 /* =B dd */, 6750205 /* =u dd */}; +int renditions[NUM_RENDS] = {65529 /* =ub */, 65531 /* =b */}; /* keep string_t and string_t_string in sync! */ static char *string_t_string[] = -- cgit v1.2.1 From d87a0d8f27a979ad1264b3848cc1a2cad0be91c3 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 28 Feb 2009 01:23:00 -0500 Subject: Allow c-style escapes with parameters. With this change, it's possible to use '\n' to represent a new line, instead of '\012' This will be particularly useful for the 'stuff' command. Fixes #25647. --- src/process.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/process.c b/src/process.c index b5474e7..8fd2fa7 100644 --- a/src/process.c +++ b/src/process.c @@ -4484,7 +4484,7 @@ int bufl, *argl; { if (*p == delim) delim = 0; - else if (delim != '\'' && *p == '\\' && (p[1] == '\'' || p[1] == '"' || p[1] == '\\' || p[1] == '$' || p[1] == '#' || p[1] == '^' || (p[1] >= '0' && p[1] <= '7'))) + else if (delim != '\'' && *p == '\\' && (p[1] == 'n' || p[1] == 'r' || p[1] == 't' || p[1] == '\'' || p[1] == '"' || p[1] == '\\' || p[1] == '$' || p[1] == '#' || p[1] == '^' || (p[1] >= '0' && p[1] <= '7'))) { p++; if (*p >= '0' && *p <= '7') @@ -4503,7 +4503,16 @@ int bufl, *argl; pp++; } else - *pp++ = *p; + { + switch (*p) + { + case 'n': *pp = '\n'; break; + case 'r': *pp = '\r'; break; + case 't': *pp = '\t'; break; + default: *pp = *p; break; + } + pp++; + } } else if (delim != '\'' && *p == '$' && (p[1] == '{' || p[1] == ':' || (p[1] >= 'a' && p[1] <= 'z') || (p[1] >= 'A' && p[1] <= 'Z') || (p[1] >= '0' && p[1] <= '9') || p[1] == '_')) -- cgit v1.2.1 From 9a592a1d06a07d30d384fd46b296f0a7e5ff04dd Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Thu, 26 Mar 2009 14:49:57 -0700 Subject: Send ti _after_ is. --- src/display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/display.c b/src/display.c index ec13ec7..c661330 100644 --- a/src/display.c +++ b/src/display.c @@ -1154,8 +1154,8 @@ int adapt; ASSERT(display); ASSERT(D_tcinited); D_top = D_bot = -1; - AddCStr(D_TI); AddCStr(D_IS); + AddCStr(D_TI); /* Check for toggle */ if (D_IM && strcmp(D_IM, D_EI)) AddCStr(D_EI); @@ -3757,8 +3757,8 @@ NukePending() D_obufp = D_obuf; D_obuffree += len; D_top = D_bot = -1; - AddCStr(D_TI); AddCStr(D_IS); + AddCStr(D_TI); /* Turn off all attributes. (Tim MacKenzie) */ if (D_ME) AddCStr(D_ME); -- cgit v1.2.1 From b28008ae6551f1c36ab140da987c4556dafc9964 Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Thu, 26 Mar 2009 14:52:29 -0700 Subject: Don't send strings we don't control as the format string\! --- src/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index c661330..651a281 100644 --- a/src/display.c +++ b/src/display.c @@ -4367,7 +4367,7 @@ char **cmdv; #endif display = 0; execvpe(*cmdv, cmdv, NewEnv + 3); - Panic(errno, *cmdv); + Panic(errno, "%s", *cmdv); default: break; } -- cgit v1.2.1 From bfcc6738e183fb89c45cbd2a288e188675fbf9eb Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Tue, 31 Mar 2009 12:00:05 -0700 Subject: Add info about MakeWinMsgEv to HACKING. --- src/HACKING | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/HACKING b/src/HACKING index 3d41cf4..b78d40f 100644 --- a/src/HACKING +++ b/src/HACKING @@ -35,3 +35,5 @@ WIP notes on hacking the Screen source. window list: WListProcess command input line: InpProcess +* Handling string escapes (in hardstatus and the like), such as %w or + %{= bw}, is done in screen.c, MakeWinMsgEv(). -- cgit v1.2.1 From 803629c10de263919afe701d4fd28be3b03e1ab4 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 8 Apr 2009 11:09:06 -0400 Subject: Fix another instance of unknown format strings. --- src/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fileio.c b/src/fileio.c index 09a9150..d15f346 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -873,7 +873,7 @@ char **cmdv; #endif execvp(*cmdv, cmdv); close(1); - Panic(errno, *cmdv); + Panic(errno, "%s", *cmdv); default: break; } -- cgit v1.2.1 From 9cdf8e20a271dea2c86d571d8ed457ecebbac14c Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 15 May 2009 15:57:12 -0400 Subject: Improve specifying custom digraphs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this change, instead of using the unicode value to create a custom digraph, it will be possible to use the unicode character itself. For example, digraph >= ≥ instead of digraph >= U+2265 --- src/process.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/process.c b/src/process.c index 8fd2fa7..eb4eeb5 100644 --- a/src/process.c +++ b/src/process.c @@ -3694,7 +3694,32 @@ int key; digraphs[i].d[0] = args[0][0]; digraphs[i].d[1] = args[0][1]; if (!parse_input_int(args[1], argl[1], &digraphs[i].value)) - digraphs[i].value = atoi(args[1]); + { + if (!(digraphs[i].value = atoi(args[1]))) + { + if (!args[1][1]) + digraphs[i].value = (int)args[1][0]; +#ifdef UTF8 + else + { + int t; + unsigned char *s = args[1]; + digraphs[i].value = 0; + while (*s) + { + t = FromUtf8(*s++, &digraphs[i].value); + if (t == -1) + continue; + if (t == -2) + digraphs[i].value = 0; + else + digraphs[i].value = t; + break; + } + } +#endif + } + } break; } Input("Enter digraph: ", 10, INP_EVERY, digraph_fn, NULL, 0); -- cgit v1.2.1 From 230855a865ab209b9784ad3ecba8675d3df5ac32 Mon Sep 17 00:00:00 2001 From: Juergen Weigert Date: Wed, 3 Jun 2009 12:52:12 -0700 Subject: Allow user to bypass sleep of 5 seconds. When used as a minicom replacement, the hard coded sleep(5) is really annoying, when trying to find the correct line and parameters. This patch makes this fatal error message behave more like an ordinary message. We now honor msgwait variable and honors user input. --- src/screen.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/screen.c b/src/screen.c index 5064652..ea8f83f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1414,8 +1414,13 @@ char **av; debug("We open one default window, as screenrc did not specify one.\n"); if (MakeWindow(&nwin) == -1) { - Msg(0, "Sorry, could not find a PTY."); - sleep(5); + fd_set rfd; + struct timeval tv = { MsgWait/1000, 1000*(MsgWait%1000) }; + FD_SET(0, &rfd); + + Msg(0, "Sorry, could not find a PTY or TTY."); + // allow user to exit early by pressing any key. + select(1, &rfd, NULL, NULL, &tv); Finit(0); /* NOTREACHED */ } -- cgit v1.2.1 From 6a9b2147844e461515f7cfcea818df297946b63d Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 5 Jul 2009 02:42:01 -0400 Subject: Correctly set the argument length when parsing. Make sure the argument length is set correctly when parsing user input. I think this will fix #26927. --- src/process.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/process.c b/src/process.c index eb4eeb5..5176a82 100644 --- a/src/process.c +++ b/src/process.c @@ -691,6 +691,7 @@ int create; { kp->ktab[i].nr = RC_ILLEGAL; kp->ktab[i].args = noargs; + kp->ktab[i].argl = 0; } kp->next = 0; *kpp = kp; @@ -3314,6 +3315,7 @@ int key; kme->str = 0; kme->dm.nr = kme->mm.nr = kme->um.nr = RC_ILLEGAL; kme->dm.args = kme->mm.args = kme->um.args = noargs; + kme->dm.argl = kme->mm.argl = kme->um.argl = 0; } i -= 8; kme -= 8; @@ -4477,6 +4479,7 @@ int bufl, *argl; delim = 0; for (;;) { + *lp = 0; while (*p && (*p == ' ' || *p == '\t')) ++p; #ifdef PSEUDOS -- cgit v1.2.1 From 976566d89d71f887df8f89f5ebcca73b29f9d73c Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Tue, 7 Jul 2009 18:43:07 -0700 Subject: Document number command's new +/- feature. --- src/doc/screen.1 | 7 ++++--- src/doc/screen.texinfo | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 314b758..80c6483 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2305,11 +2305,12 @@ some time it restarts to accept characters, screen will unblock the display and redisplay the updated window contents. .sp .ne 3 -.BR "number " [ \fIn ] +.BR "number " [[+|-] \fIn ] .PP -Change the current windows number. If the given number \fIn\fP is already +Change the current window's number. If the given number \fIn\fP is already used by another window, both windows exchange their numbers. If no argument is -specified, the current window number (and title) is shown. +specified, the current window number (and title) is shown. Using `+' or `-' +will change the window's number by the relative amount specified. .sp .ne 3 .BR "obuflimit " [ \fIlimit ] diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 7a5d189..1acabe2 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -4475,11 +4475,13 @@ displays is changed. Initial setting is @code{off}. @node Number, Silence, Nonblock, Miscellaneous @section Number @kindex N -@deffn Command number [@var{n}] +@deffn Command number [[+|-]@var{n}] (@kbd{C-a N})@* Change the current window's number. If the given number @var{n} is already used by another window, both windows exchange their numbers. If no argument is -specified, the current window number (and title) is shown. +specified, the current window number (and title) is shown. Using either a +plus (`+') or minus (`-') will change the window's number by the relative +amount specified. @end deffn @node Silence, Time, Number, Miscellaneous -- cgit v1.2.1 From 97708d5800ac845b4c3a25d96d544f0dafa735d7 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Mon, 13 Jul 2009 21:08:35 -0700 Subject: Document the new "-v" argument to the split command. --- src/doc/screen.1 | 11 +++++++---- src/doc/screen.texinfo | 21 +++++++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 80c6483..b781e3a 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -509,7 +509,7 @@ automatic margins on and off). .PD Send a control-s to the current window. .IP "\fBC-a S\fP (split)" -Split the current region into two new ones. +Split the current region horizontally into two new ones. See also \fIonly, remove, focus\fP. .IP "\fBC-a t\fP" .PD 0 @@ -582,6 +582,8 @@ Shows where comes from, where it went to and why you can use it. .IP "\fBC-a _\fP (silence)" Start/stop monitoring the current window for inactivity. +.IP "\fBC-a |\fP (split -v)" +Split the current region vertically into two new ones. .IP "\fBC-a *\fP (displays)" Show a listing of all currently attached displays. @@ -2729,12 +2731,13 @@ The default is currently \*Q=s dd\*U (standout, default colors). .sp .ne 3 .B split +.RB [ -v ] .PP Split the current region into two new ones. All regions on the display are resized to make room for the new region. The blank -window is displayed on the new region. Use the \*Qremove\*U or the -\*Qonly\*U command to delete regions. -Use \*Qfocus\*U to toggle between regions. +window is displayed on the new region. Splits are made horizontally +unless -v is used. Use the \*Qremove\*U or the \*Qonly\*U command +to delete regions. Use \*Qfocus\*U to toggle between regions. .sp .ne 3 .B "startup_message on\fP|\fBoff" diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 1acabe2..cfcbafe 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -705,7 +705,7 @@ Send a ^S (ASCII XOFF) to the current window. @xref{XON/XOFF}. @item @kbd{C-a S} (split)@* -Split the current region into two new ones. @xref{Regions}. +Split the current region horizontally into two new ones. @xref{Regions}. @item @kbd{C-a t} @itemx @kbd{C-a C-t} @@ -799,6 +799,10 @@ Delete the screen-exchange file. @xref{Screen Exchange}. (silence)@* Start/stop monitoring the current window for inactivity. @xref{Silence}, +@item @kbd{C-a |} +(split -v)@* +Split the current region vertically into two new ones. @xref{Regions}. + @item @kbd{C-a ,} (license)@* Show the copyright page. @@ -1808,11 +1812,20 @@ which can contain different windows. @node Split, Focus, , Regions @section Split @kindex S -@deffn Command split -(@kbd{C-a S})@* +@kindex | +@deffn Command split [-v] +(@kbd{C-a S}, @kbd{C-a |})@* Split the current region into two new ones. All regions on the display are resized to make room for the new region. The blank -window is displayed on the new region. +window is displayed on the new region. The default is to create +a horizontal split, putting the new regions on the top and +bottom of each other. Using -v will create a vertical split, +causing the new regions to appear side by side of each other. + +With this current implementation of @code{screen}, scrolling data +will appear much slower in a vertically splited region than one +that is not. This should be taken into consideration if you need +to use system commands such as @code{cat} or @code{tail -f}. @end deffn @node Focus, Only, Split, Regions -- cgit v1.2.1 From ac6264f3bb3a792b523123b44477fdfc83cdfc34 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Mon, 13 Jul 2009 21:12:02 -0700 Subject: Document deprecated status of sorendition. --- src/doc/screen.1 | 6 +----- src/doc/screen.texinfo | 9 ++------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index b781e3a..203f45e 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2723,11 +2723,7 @@ default screenrc files to have an effect. .B sorendition .RB [ "\fIattr\fR " [ \fIcolor ]] .PP -Change the way -.I screen -does highlighting for text marking and printing messages. -See the \*QSTRING ESCAPES\*U chapter for the syntax of the modifiers. -The default is currently \*Q=s dd\*U (standout, default colors). +This command is deprecated. See "rendition so" instead. .sp .ne 3 .B split diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index cfcbafe..001169c 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1108,7 +1108,7 @@ Slow down pasting in windows. @xref{Paste}. @item source @var{file} Run commands from a file. @xref{Source}. @item sorendition [@var{attr} [@var{color}]] -Change text highlighting. @xref{Sorendition}. +Deprecated. Use @code{rendition so} instead. @xref{Rendition}. @item split Split region into two parts. @xref{Regions}. @item startup_message @var{state} @@ -4608,12 +4608,7 @@ active colors). @section Sorendition @deffn Command sorendition [@var{attr} [@var{color}]] (none)@* -Change the way screen does highlighting for text marking and printing -messages. -See the chapter -about string escapes (@pxref{String Escapes}) for the syntax of -the modifiers. The default is currently @samp{=s dd} (standout, -default colors). +This command has been deprecated. Use @code{rendition so} instead. @end deffn @node Attrcolor, Setsid, Sorendition, Miscellaneous -- cgit v1.2.1 From ede107f9d8ca413a21326450090c7090a703fb81 Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Mon, 13 Jul 2009 21:13:10 -0700 Subject: Typo fix in manpage (Thanks positron). --- src/doc/screen.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 203f45e..454205b 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2009,7 +2009,7 @@ Sets a command that is run after the specified number of seconds inactivity is reached. This command will normally be the \*Qblanker\*U command to create a screen blanker, but it can be any screen command. If no command is specified, only the timeout is set. A timeout of -zero (ot the special timeout \fBoff\fP) disables the timer. +zero (or the special timeout \fBoff\fP) disables the timer. If no arguments are given, the current settings are displayed. .sp .ne 3 -- cgit v1.2.1 From 8c0d8987c3f3d298d164d4ec74a0eb780f5c0015 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Tue, 14 Jul 2009 14:14:28 -0700 Subject: Fix keybinding doc glitches. --- src/doc/screen.1 | 2 ++ src/doc/screen.texinfo | 33 ++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 454205b..05b4294 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -561,6 +561,8 @@ Enter command line mode. .IP "\fBC-a esc\fP (copy)" .PD Enter copy/scrollback mode. +.IP "\fBC-a C-]\fP" +.PD 0 .IP "\fBC-a ]\fP (paste .)" .PD Write the contents of the paste buffer to the stdin queue of the diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 001169c..3285aeb 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -620,7 +620,7 @@ Cycle flow among @samp{on}, @samp{off} or @samp{auto}. @xref{Flow}. @item @kbd{C-a F} (fit)@* -Resize the window to the current region size. @xref{Window Size}. +Resize the window to the current region size. @xref{Fit}. @item @kbd{C-a C-g} (vbell)@* @@ -797,7 +797,7 @@ Delete the screen-exchange file. @xref{Screen Exchange}. @item @kbd{C-a _} (silence)@* -Start/stop monitoring the current window for inactivity. @xref{Silence}, +Start/stop monitoring the current window for inactivity. @xref{Silence}. @item @kbd{C-a |} (split -v)@* @@ -805,11 +805,11 @@ Split the current region vertically into two new ones. @xref{Regions}. @item @kbd{C-a ,} (license)@* -Show the copyright page. +Show the copyright page. @xref{License}. @item @kbd{C-a *} (displays)@* -Show the listing of attached displays. +Show the listing of attached displays. @xref{Displays}. @end table @node Command Summary, , Default Key Bindings, Commands @@ -1427,8 +1427,10 @@ pressing space.) @kindex p @kindex C-p +@kindex C-h +@kindex Backspace @deffn Command prev -(@kbd{C-a p}, @kbd{C-a C-p})@* +(@kbd{C-a p}, @kbd{C-a C-p}, @kbd{C-a C-h}, @kbd{C-a @key{Backspace}})@* Switch to the previous window (the opposite of @kbd{C-a n}). @end deffn @@ -2493,7 +2495,7 @@ Keypad enter fe stuff \015 @kindex C-v @deffn Command digraph [preset] -(none)@* +(@kbd{C-a C-v})@* This command prompts the user for a digraph sequence. The next two characters typed are looked up in a builtin table and the resulting character is inserted in the input stream. For example, @@ -3212,8 +3214,9 @@ See also @section History @kindex @{ +@kindex @} @deffn Command history -(@kbd{C-a @{})@* +(@kbd{C-a @{}, @kbd{C-a @}})@* Usually users work with a shell that allows easy access to previous commands. For example, @code{csh} has the command @code{!!} to repeat the last command executed. @code{screen} provides a primitive way of @@ -4214,9 +4217,8 @@ This section describes the commands for keeping a record of your session. @node Hardcopy, Log, , Logging @section hardcopy @kindex h -@kindex C-h @deffn Command hardcopy [-h] [@var{file}] -(@kbd{C-a h}, @kbd{C-a C-h})@* +(@kbd{C-a h})@* Writes out the currently displayed image to the file @var{file}, or, if no filename is specified, to @file{hardcopy.@var{n}} in the default directory, where @var{n} is the number of the @@ -4394,8 +4396,10 @@ work correctly under @code{at} looping over windows. @node Break, Debug, At, Miscellaneous @section Break +@kindex b +@kindex C-b @deffn Command break [duration] -(none)@* +(@kbd{C-a b}, @kbd{C-a C-b})@* Send a break signal for @var{duration}*0.25 seconds to this window. For non-Posix systems the time interval is rounded up to full seconds. Most useful if a character device is attached to the window rather than @@ -4403,8 +4407,9 @@ a shell process (@pxref{Window Types}). The maximum duration of a break signal is limited to 15 seconds. @end deffn +@kindex B @deffn Command pow_break -(none)@* +(@kbd{C-a B})@* Reopen the window's terminal line and send a break condition. @end deffn @@ -4444,8 +4449,9 @@ be turned off once and forever. @node License, Nethack, Debug, Miscellaneous @section License +@kindex , @deffn Command license -(none)@* +(@kbd{C-a ,})@* Display the disclaimer page. This is done whenever @code{screen} is started without options, which should be often enough. @end deffn @@ -4499,8 +4505,9 @@ amount specified. @node Silence, Time, Number, Miscellaneous @section Silence +@kindex _ @deffn Command silence [@var{state}|@var{sec}] -(none)@* +(@kbd{C-a _})@* Toggles silence monitoring of windows. When silence is turned on and an affected window is switched into the background, you will receive the silence notification message in the status line after a specified period -- cgit v1.2.1 From e8ab383af46b75a2b14d446fc6305912c773a7e6 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Thu, 23 Jul 2009 19:26:24 +0200 Subject: - change status message code so that Flush is no longer called - add progress parameter to flush - try to get the window's wait status when EOF is reached --- src/ansi.c | 2 +- src/display.c | 106 ++++++++++++++++++++++++++++++++++++++++++---------------- src/display.h | 2 ++ src/extern.h | 2 +- src/fileio.c | 2 +- src/screen.c | 16 +++++++-- src/window.c | 2 +- 7 files changed, 97 insertions(+), 35 deletions(-) diff --git a/src/ansi.c b/src/ansi.c index 29fbe0d..35e9f79 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -1674,7 +1674,7 @@ PrintFlush() AddCStr(D_PO); AddStrn(curr->w_string, curr->w_stringp - curr->w_string); AddCStr(D_PF); - Flush(); + Flush(3); } curr->w_stringp = curr->w_string; } diff --git a/src/display.c b/src/display.c index 651a281..b2ad636 100644 --- a/src/display.c +++ b/src/display.c @@ -333,7 +333,7 @@ FreeDisplay() #endif if (D_userfd >= 0) { - Flush(); + Flush(3); if (!display) return; SetTTY(D_userfd, &D_OldMode); @@ -1181,7 +1181,7 @@ int adapt; ResizeDisplay(D_defwidth, D_defheight); ChangeScrollRegion(0, D_height - 1); D_x = D_y = 0; - Flush(); + Flush(3); ClearAll(); debug1("we %swant to adapt all our windows to the display\n", (adapt) ? "" : "don't "); @@ -1222,7 +1222,7 @@ FinitTerm() AddChar('\n'); AddCStr(D_TE); } - Flush(); + Flush(3); } @@ -2660,7 +2660,7 @@ char *msg; return; /* XXX: better */ AddStr(msg); AddStr("\r\n"); - Flush(); + Flush(0); return; } if (!use_hardstatus || !D_HS) @@ -2746,15 +2746,15 @@ char *msg; D_status = STATUS_ON_HS; ShowHStatus(msg); } - Flush(); - if (!display) - return; + + D_status_obufpos = D_obufp - D_obuf; + ASSERT(D_status_obufpos > 0); + if (D_status == STATUS_ON_WIN) { struct display *olddisplay = display; struct layer *oldflayer = flayer; - ASSERT(D_obuffree == D_obuflen); /* this is copied over from RemoveStatus() */ D_status = 0; GotoPos(0, STATLINE); @@ -2765,17 +2765,8 @@ char *msg; LaySetCursor(); display = olddisplay; flayer = oldflayer; - D_status_obuflen = D_obuflen; - D_status_obuffree = D_obuffree; - D_obuffree = D_obuflen = 0; D_status = STATUS_ON_WIN; } - gettimeofday(&D_status_time, NULL); - SetTimeout(&D_statusev, MsgWait); - evenq(&D_statusev); -#ifdef HAVE_BRAILLE - RefreshBraille(); /* let user see multiple Msg()s */ -#endif } void @@ -2798,6 +2789,7 @@ RemoveStatus() D_status_obuffree = -1; } D_status = 0; + D_status_obufpos = 0; D_status_bell = 0; evdeq(&D_statusev); olddisplay = display; @@ -3181,8 +3173,8 @@ int from, to, y, bce; void DisplayLine(oml, ml, y, from, to) struct mline *oml, *ml; -int from, to, y;{ - +int from, to, y; +{ register int x; int last2flag = 0, delete_lp = 0; @@ -3588,9 +3580,11 @@ int n; } void -Flush() +Flush(progress) +int progress; { register int l; + int wr; register char *p; ASSERT(display); @@ -3606,29 +3600,57 @@ Flush() return; } p = D_obuf; - if (fcntl(D_userfd, F_SETFL, 0)) - debug1("Warning: BLOCK fcntl failed: %d\n", errno); + if (!progress) + { + if (fcntl(D_userfd, F_SETFL, 0)) + debug1("Warning: BLOCK fcntl failed: %d\n", errno); + } while (l) { - register int wr; + if (progress) + { + fd_set w; + FD_ZERO(&w); + FD_SET(D_userfd, &w); + struct timeval t; + t.tv_sec = progress; + t.tv_usec = 0; + wr = select(FD_SETSIZE, (fd_set *)0, &w, (fd_set *)0, &t); + if (wr == -1) + { + if (errno == EINTR) + continue; + debug1("Warning: select failed: %d\n", errno); + break; + } + if (wr == 0) + { + /* no progress after 3 seconds. sorry. */ + debug1("Warning: no progress after %d seconds\n", progress); + break; + } + } wr = write(D_userfd, p, l); if (wr <= 0) { if (errno == EINTR) continue; debug1("Writing to display: %d\n", errno); - wr = l; + break; } - if (!display) - return; D_obuffree += wr; p += wr; l -= wr; } + if (l) + debug1("Warning: Flush could not write %d bytes\n", l); D_obuffree += l; D_obufp = D_obuf; - if (fcntl(D_userfd, F_SETFL, FNBLOCK)) - debug1("Warning: NBLOCK fcntl failed: %d\n", errno); + if (!progress) + { + if (fcntl(D_userfd, F_SETFL, FNBLOCK)) + debug1("Warning: NBLOCK fcntl failed: %d\n", errno); + } if (D_blocked == 1) D_blocked = 0; D_blocked_fuzz = 0; @@ -3843,6 +3865,8 @@ char *data; len = D_obufp - D_obuf; if (len < size) size = len; + if (D_status_obufpos && size > D_status_obufpos) + size = D_status_obufpos; ASSERT(len >= 0); size = write(D_userfd, D_obuf, size); if (size >= 0) @@ -3855,6 +3879,30 @@ char *data; } D_obufp -= size; D_obuffree += size; + if (D_status_obufpos) + { + D_status_obufpos -= size; + if (!D_status_obufpos) + { + debug("finished writing the status message\n"); + /* we're finished displaying the message! */ + if (D_status == STATUS_ON_WIN) + { + /* setup continue trigger */ + D_status_obuflen = D_obuflen; + D_status_obuffree = D_obuffree; + /* setting obbuffree to 0 will make AddChar call + * ResizeObuf */ + D_obuffree = D_obuflen = 0; + } + gettimeofday(&D_status_time, NULL); + SetTimeout(&D_statusev, MsgWait); + evenq(&D_statusev); +#ifdef HAVE_BRAILLE + RefreshBraille(); /* let user see multiple Msg()s */ +#endif + } + } if (D_blocked_fuzz) { D_blocked_fuzz -= size; @@ -3882,7 +3930,7 @@ char *data; Activate(D_fore ? D_fore->w_norefresh : 0); D_blocked_fuzz = D_obufp - D_obuf; } - } + } else { #ifdef linux diff --git a/src/display.h b/src/display.h index ee5a03b..aaaf6bf 100644 --- a/src/display.h +++ b/src/display.h @@ -164,6 +164,7 @@ struct display int d_status_lasty; /* before status was displayed */ int d_status_obuflen; /* saved obuflen */ int d_status_obuffree; /* saved obuffree */ + int d_status_obufpos; /* end of status position in obuf */ struct event d_statusev; /* timeout event */ struct event d_hstatusev; /* hstatus changed event */ int d_kaablamm; /* display kaablamm msg */ @@ -286,6 +287,7 @@ extern struct display TheDisplay; #define D_status_lasty DISPLAY(d_status_lasty) #define D_status_obuflen DISPLAY(d_status_obuflen) #define D_status_obuffree DISPLAY(d_status_obuffree) +#define D_status_obufpos DISPLAY(d_status_obufpos) #define D_statusev DISPLAY(d_statusev) #define D_hstatusev DISPLAY(d_hstatusev) #define D_kaablamm DISPLAY(d_kaablamm) diff --git a/src/extern.h b/src/extern.h index 1bf7c4b..4e44024 100644 --- a/src/extern.h +++ b/src/extern.h @@ -291,7 +291,7 @@ extern void RemoveStatus __P((void)); extern int ResizeDisplay __P((int, int)); extern void AddStr __P((char *)); extern void AddStrn __P((char *, int)); -extern void Flush __P((void)); +extern void Flush __P((int)); extern void freetty __P((void)); extern void Resize_obuf __P((void)); #ifdef AUTO_NUKE diff --git a/src/fileio.c b/src/fileio.c index d15f346..c9a5eef 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -229,7 +229,7 @@ int nopanic; if (argc != 3) { AddStr("\r\n"); - Flush(); + Flush(0); } } else if (strcmp(args[0], "sleep") == 0) diff --git a/src/screen.c b/src/screen.c index ea8f83f..7d1865e 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1473,6 +1473,18 @@ int wstat_valid; { int killit = 0; +#if defined(BSDJOBS) && !defined(BSDWAIT) + if (!wstat_valid && p->w_pid > 0) + { + /* EOF on file descriptor. The process is probably also dead. + * try a waitpid */ + if (waitpid(p->w_pid, &wstat, WNOHANG | WUNTRACED) == p->w_pid) + { + p->w_pid = 0; + wstat_valid = 1; + } + } +#endif if (ZombieKey_destroy && ZombieKey_onerror && wstat_valid && WIFEXITED(wstat) && WEXITSTATUS(wstat) == 0) killit = 1; @@ -1781,7 +1793,7 @@ int i; RestoreLoginSlot(); #endif AddStr("[screen is terminating]\r\n"); - Flush(); + Flush(3); SetTTY(D_userfd, &D_OldMode); fcntl(D_userfd, F_SETFL, 0); freetty(); @@ -2130,7 +2142,7 @@ VA_DECL if (D_status) RemoveStatus(); FinitTerm(); - Flush(); + Flush(3); #ifdef UTMPOK RestoreLoginSlot(); #endif diff --git a/src/window.c b/src/window.c index 4754a98..fb271d2 100644 --- a/src/window.c +++ b/src/window.c @@ -2099,7 +2099,7 @@ int len; D_readev.condpos = D_readev.condneg = 0; while (len-- > 0) AddChar(*bp++); - Flush(); + Flush(0); Activate(D_fore ? D_fore->w_norefresh : 0); return 1; } -- cgit v1.2.1 From 52a0417cf7fe630c60f730a7dd706394c8e55499 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Fri, 24 Jul 2009 12:05:25 +0200 Subject: - fix reattach segfault when size is too small for windowlist - add focus up/down/left/right commands --- src/display.c | 43 +++++++++++++++++++------------------- src/process.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/socket.c | 2 ++ 3 files changed, 87 insertions(+), 25 deletions(-) diff --git a/src/display.c b/src/display.c index b2ad636..e5954ec 100644 --- a/src/display.c +++ b/src/display.c @@ -67,6 +67,7 @@ static void SetBackColor __P((int)); #endif static void FreePerp __P((struct canvas *)); static struct canvas *AddPerp __P((struct canvas *)); +static void RemoveStatusMinWait __P((void)); extern struct layer *flayer; @@ -2677,19 +2678,11 @@ char *msg; if (strcmp(msg, D_status_lastmsg) == 0) { debug("same message - increase timeout"); - SetTimeout(&D_statusev, MsgWait); + if (!D_status_obufpos) + SetTimeout(&D_statusev, MsgWait); return; } - if (!D_status_bell) - { - struct timeval now; - int ti; - gettimeofday(&now, NULL); - ti = (now.tv_sec - D_status_time.tv_sec) * 1000 + (now.tv_usec - D_status_time.tv_usec) / 1000; - if (ti < MsgMinWait) - DisplaySleep1000(MsgMinWait - ti, 0); - } - RemoveStatus(); + RemoveStatusMinWait(); } for (s = t = msg; *s && t - msg < max; ++s) if (*s == BELL) @@ -2812,6 +2805,23 @@ RemoveStatus() flayer = oldflayer; } +/* Remove the status but make sure that it is seen for MsgMinWait ms */ +static void +RemoveStatusMinWait() +{ + /* XXX: should flush output first if D_status_obufpos is set */ + if (!D_status_bell && !D_status_obufpos) + { + struct timeval now; + int ti; + gettimeofday(&now, NULL); + ti = (now.tv_sec - D_status_time.tv_sec) * 1000 + (now.tv_usec - D_status_time.tv_usec) / 1000; + if (ti < MsgMinWait) + DisplaySleep1000(MsgMinWait - ti, 0); + } + RemoveStatus(); +} + /* refresh the display's hstatus line */ void ShowHStatus(str) @@ -3688,16 +3698,7 @@ Resize_obuf() if (D_status_obuffree >= 0) { ASSERT(D_obuffree == -1); - if (!D_status_bell) - { - struct timeval now; - int ti; - gettimeofday(&now, NULL); - ti = (now.tv_sec - D_status_time.tv_sec) * 1000 + (now.tv_usec - D_status_time.tv_usec) / 1000; - if (ti < MsgMinWait) - DisplaySleep1000(MsgMinWait - ti, 0); - } - RemoveStatus(); + RemoveStatusMinWait(); if (--D_obuffree > 0) /* redo AddChar decrement */ return; } diff --git a/src/process.c b/src/process.c index 5176a82..fa3d06c 100644 --- a/src/process.c +++ b/src/process.c @@ -162,6 +162,7 @@ static void ResizeFin __P((char *, int, char *)); static struct action *FindKtab __P((char *, int)); static void SelectFin __P((char *, int, char *)); static void SelectLayoutFin __P((char *, int, char *)); +static struct canvas *FindCanvas __P((int, int)); extern struct layer *flayer; @@ -631,7 +632,7 @@ InitKeytab() ktab['\t'].nr = RC_FOCUS; { char *args[2]; - args[0] = "up"; + args[0] = "prev"; args[1] = 0; SaveAction(ktab + T_BACKTAB - T_CAPS + 256, RC_FOCUS, args, 0); } @@ -3932,9 +3933,9 @@ int key; LaySetCursor(); break; case RC_FOCUS: - if (!*args || !strcmp(*args, "down")) + if (!*args || !strcmp(*args, "next")) D_forecv = D_forecv->c_next ? D_forecv->c_next : D_cvlist; - else if (!strcmp(*args, "up")) + else if (!strcmp(*args, "prev")) { struct canvas *cv; for (cv = D_cvlist; cv->c_next && cv->c_next != D_forecv; cv = cv->c_next) @@ -3950,9 +3951,17 @@ int key; ; D_forecv = cv; } + else if (!strcmp(*args, "up")) + D_forecv = FindCanvas(D_forecv->c_xs, D_forecv->c_ys - 1); + else if (!strcmp(*args, "down")) + D_forecv = FindCanvas(D_forecv->c_xs, D_forecv->c_ye + 2); + else if (!strcmp(*args, "left")) + D_forecv = FindCanvas(D_forecv->c_xs - 1, D_forecv->c_ys); + else if (!strcmp(*args, "right")) + D_forecv = FindCanvas(D_forecv->c_xe + 1, D_forecv->c_ys); else { - Msg(0, "%s: usage: focus [up|down|top|bottom]", rc_name); + Msg(0, "%s: usage: focus [next|prev|up|down|left|right|top|bottom]", rc_name); break; } if ((focusminwidth && (focusminwidth < 0 || D_forecv->c_xe - D_forecv->c_xs + 1 < focusminwidth)) || @@ -6768,6 +6777,56 @@ int percent; return done; } +static struct canvas * +FindCanvas(x, y) +int x, y; +{ + struct canvas *cv, *mcv = 0; + int m, mm = 0; + + for (cv = D_cvlist; cv; cv = cv->c_next) + { + /* ye + 1 because of caption line */ + if (x >= cv->c_xs && x <= cv->c_xe && y >= cv->c_ys && y <= cv->c_ye + 1) + return cv; + if (cv == D_forecv) + continue; + m = 0; + if (x >= D_forecv->c_xs && x <= D_forecv->c_xe) + { + if (x < cv->c_xs || x > cv->c_xe) + continue; + if (y < D_forecv->c_ys && y < cv->c_ys) + continue; + if (y > D_forecv->c_ye + 1 && y > cv->c_ye + 1) + continue; + if (y < cv->c_ys) + m = cv->c_ys - y; + if (y > cv->c_ye + 1) + m = y - (cv->c_ye + 1); + } + if (y >= D_forecv->c_ys && y <= D_forecv->c_ye + 1) + { + if (y < cv->c_ys || y > cv->c_ye + 1) + continue; + if (x < D_forecv->c_xs && x < cv->c_xs) + continue; + if (x > D_forecv->c_xe && x > cv->c_xe) + continue; + if (x < cv->c_xs) + m = cv->c_xs - x; + if (x > cv->c_xe) + m = x - cv->c_xe; + } + if (m && (!mm || m < mm)) + { + mcv = cv; + mm = m; + } + } + return mcv ? mcv : D_forecv; +} + static void ResizeRegions(arg, flags) char *arg; diff --git a/src/socket.c b/src/socket.c index acdd7d1..7832832 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1378,9 +1378,11 @@ struct msg *m; if (!AclCheckPermCmd(D_user, ACL_EXEC, &comms[RC_WINDOWLIST])) #endif { + struct display *olddisplay = display; flayer = D_forecv->c_layer; display_wlist(1, WLIST_NUM, (struct win *)0); noshowwin = 1; + display = olddisplay; /* display_wlist can change display */ } } Activate(0); -- cgit v1.2.1 From 41daa2215ae124e6b24fb25346f3baa36dfe98b6 Mon Sep 17 00:00:00 2001 From: Micah Cowan Date: Fri, 24 Jul 2009 12:55:24 -0700 Subject: Mail screen-devel@gnu.org for general screen build problems. --- src/INSTALL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/INSTALL b/src/INSTALL index 17c2212..f9750e6 100644 --- a/src/INSTALL +++ b/src/INSTALL @@ -44,7 +44,7 @@ Run 'make'. Screen should compile without too many warnings :) The creation of term.h, comm.h, tty.c or osdef.h may fail on some machines for some odd reason. (E.g. the sed under SCO-unix is known to be case-insensitive and breaks term.h.) If so, please mail a short description -of the problem to screen@uni-erlangen.de and use the files ending in .dist +of the problem to screen-devel@gnu.org and use the files ending in .dist as a replacement (or in case of osdef.h retry with an empty file). You can then try 'make install' (if you dare). -- cgit v1.2.1 From bd1b9d13df786380e96bf610ef6c725b05be60ee Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 23 Sep 2009 12:18:56 -0400 Subject: Fix a crash on source-ing a file whose tilde-expansaion fails. --- src/fileio.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/fileio.c b/src/fileio.c index d15f346..ad47abf 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -112,7 +112,7 @@ char *rcfile; if (!home) { Msg(0, "%s: source: tilde expansion failed", rc_name); - return; + return NULL; } snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", home, rcfile+2); } @@ -124,14 +124,14 @@ char *rcfile; if (!p) { Msg(0, "%s: source: tilde expansion failed for user %s", rc_name, rcfile+1); - return; + return NULL; } snprintf(rcfilename_tilde_exp, MAXPATHLEN, "%s/%s", p->pw_dir, slash_position+1); } else { Msg(0, "%s: source: illegal tilde expression.", rc_name); - return; + return NULL; } rcfile = rcfilename_tilde_exp; } @@ -192,21 +192,23 @@ int nopanic; rc_name = findrcfile(rcfilename); - if ((fp = secfopen(rc_name, "r")) == NULL) + if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) { - if (!rc_recursion && RcFileName && !strcmp(RcFileName, rc_name)) + const char *rc_nonnull = rc_name ? rc_name : rcfilename; + if (!rc_recursion && RcFileName && !strcmp(RcFileName, rc_nonnull)) { /* * User explicitly gave us that name, * this is the only case, where we get angry, if we can't read * the file. */ - debug3("StartRc: '%s','%s', '%s'\n", RcFileName, rc_name, rcfilename); - if (!nopanic) Panic(0, "Unable to open \"%s\".", rc_name); + debug3("StartRc: '%s','%s', '%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename); + if (!nopanic) Panic(0, "Unable to open \"%s\".", rc_nonnull); /* possibly NOTREACHED */ } - debug1("StartRc: '%s' no good. ignored\n", rc_name); - Free(rc_name); + debug1("StartRc: '%s' no good. ignored\n", rc_nonnull); + if (rc_name) + Free(rc_name); rc_name = oldrc_name; return 1; } @@ -302,23 +304,25 @@ char *rcfilename; rc_name = findrcfile(rcfilename); - if ((fp = secfopen(rc_name, "r")) == NULL) + if (rc_name == NULL || (fp = secfopen(rc_name, "r")) == NULL) { + const char *rc_nonnull = rc_name ? rc_name : rcfilename; if (rc_recursion) - Msg(errno, "%s: source %s", oldrc_name, rc_name); - else if (RcFileName && !strcmp(RcFileName, rc_name)) + Msg(errno, "%s: source %s", oldrc_name, rc_nonnull); + else if (RcFileName && !strcmp(RcFileName, rc_nonnull)) { /* * User explicitly gave us that name, * this is the only case, where we get angry, if we can't read * the file. */ - debug3("FinishRc:'%s','%s','%s'\n", RcFileName, rc_name, rcfilename); - Panic(0, "Unable to open \"%s\".", rc_name); + debug3("FinishRc:'%s','%s','%s'\n", RcFileName, rc_name ? rc_name : "(null)", rcfilename); + Panic(0, "Unable to open \"%s\".", rc_nonnull); /* NOTREACHED */ } - debug1("FinishRc: '%s' no good. ignored\n", rc_name); - Free(rc_name); + debug1("FinishRc: '%s' no good. ignored\n", rc_nonnull); + if (rc_name) + Free(rc_name); rc_name = oldrc_name; return; } -- cgit v1.2.1 From 0ca36352b236f6c72e1f79d9556e0759d9905d5d Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 23 Sep 2009 12:23:45 -0400 Subject: Re-indent some code, and reduce code-duplication. --- src/mark.c | 66 ++++++++++++++++++++++++++------------------------------------ 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/src/mark.c b/src/mark.c index be22df7..ff8e583 100644 --- a/src/mark.c +++ b/src/mark.c @@ -162,14 +162,18 @@ nextchar(int *xp, int *yp, int direction, char target, int num) displayed_line = (char *)WIN(*yp) -> image; switch(direction) { - case 't': adjust = -1; /* fall through */ - case 'f': step = 1; /* fall through */ - break; - case 'T': adjust = 1; /* fall through */ - case 'F': step = -1; /* fall through */ - break; - default: - ASSERT(0); + case 't': + adjust = -1; /* fall through */ + case 'f': + step = 1; + break; + case 'T': + adjust = 1; /* fall through */ + case 'F': + step = -1; + break; + default: + ASSERT(0); } x += step; @@ -611,43 +615,29 @@ int *inlenp; case 'F': /* fall through */ case 't': /* fall through */ case 'T': /* fall through */ - /* - * Set f_cmd to do a search on the next key stroke. - * If we break, rep_cnt will be reset, so we - * continue instead. It might be cleaner to - * store the rep_count in f_cmd and - * break here so later followon code will be - * hit. - */ - markdata->f_cmd.flag = 1; - markdata->f_cmd.direction = od; - debug("entering char search\n"); - continue; + /* + * Set f_cmd to do a search on the next key stroke. + * If we break, rep_cnt will be reset, so we + * continue instead. It might be cleaner to + * store the rep_count in f_cmd and + * break here so later followon code will be + * hit. + */ + markdata->f_cmd.flag = 1; + markdata->f_cmd.direction = od; + debug("entering char search\n"); + continue; case ';': + case ',': if (!markdata->f_cmd.target) break; if (!rep_cnt) rep_cnt = 1; - nextchar(&cx, &cy, markdata->f_cmd.direction, markdata->f_cmd.target, rep_cnt ); - revto(cx, cy); - break; - case ',': { - int search_dir; - if (!markdata->f_cmd.target) - break; - if (!rep_cnt) - rep_cnt = 1; - switch (markdata->f_cmd.direction) { - case 't': search_dir = 'T'; break; - case 'T': search_dir = 't'; break; - case 'f': search_dir = 'F'; break; - case 'F': search_dir = 'f'; break; - } - nextchar(&cx, &cy, search_dir, markdata->f_cmd.target, rep_cnt ); + nextchar(&cx, &cy, + od == ';' ? markdata->f_cmd.direction : (markdata->f_cmd.direction ^ 0x20), + markdata->f_cmd.target, rep_cnt ); revto(cx, cy); break; - } - case 'o': case 'x': if (!markdata->second) -- cgit v1.2.1 From d610852510d22b848546adbf56fbb3b7f9d1d6b6 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 23 Sep 2009 13:28:38 -0400 Subject: Add __noreturn__ attribute to some functions. Setting the __noreturn__ attribute to a function helps analyzers such as clang-analyzer to not report false positives. --- src/ansi.c | 2 +- src/extern.h | 10 +++++----- src/layer.c | 4 ++-- src/nethack.c | 4 ++-- src/screen.c | 8 ++++---- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/ansi.c b/src/ansi.c index 29fbe0d..8c56bb5 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -2935,7 +2935,7 @@ char *str; extern struct layer *flayer; struct layer *oldflayer = flayer; flayer = &p->w_layer; - LMsg(err, str); + LMsg(err, "%s", str); flayer = oldflayer; } diff --git a/src/extern.h b/src/extern.h index 1bf7c4b..32a8463 100644 --- a/src/extern.h +++ b/src/extern.h @@ -35,13 +35,13 @@ /* screen.c */ extern int main __P((int, char **)); extern sigret_t SigHup __P(SIGPROTOARG); -extern void eexit __P((int)); +extern void eexit __P((int)) __attribute__((__noreturn__)); extern void Detach __P((int)); extern void Hangup __P((void)); extern void Kill __P((int, int)); #ifdef USEVARARGS -extern void Msg __P((int, char *, ...)) __attribute__((format(printf, 2, 3))); -extern void Panic __P((int, char *, ...)) __attribute__((format(printf, 2, 3))); +extern void Msg __P((int, const char *, ...)) __attribute__((format(printf, 2, 3))); +extern void Panic __P((int, const char *, ...)) __attribute__((format(printf, 2, 3))) __attribute__((__noreturn__)); #else extern void Msg __P(()); extern void Panic __P(()); @@ -457,7 +457,7 @@ extern void LKeypadMode __P((struct layer *, int)); extern void LCursorkeysMode __P((struct layer *, int)); extern void LMouseMode __P((struct layer *, int)); #ifdef USEVARARGS -extern void LMsg __P((int, char *, ...)) __attribute__((format(printf, 2, 3))); +extern void LMsg __P((int, const char *, ...)) __attribute__((format(printf, 2, 3))); #else extern void LMsg __P(()); #endif @@ -479,7 +479,7 @@ extern void TelStatus __P((struct win *, char *, int)); #endif /* nethack.c */ -extern char *DoNLS __P((char *)); +extern const char *DoNLS __P((const char *)); /* encoding.c */ #ifdef ENCODINGS diff --git a/src/layer.c b/src/layer.c index 487e45e..a3ffb3e 100644 --- a/src/layer.c +++ b/src/layer.c @@ -879,11 +879,11 @@ int isblank; void /*VARARGS2*/ #if defined(USEVARARGS) && defined(__STDC__) -LMsg(int err, char *fmt, VA_DOTS) +LMsg(int err, const char *fmt, VA_DOTS) #else LMsg(err, fmt, VA_DOTS) int err; -char *fmt; +const char *fmt; VA_DECL #endif { diff --git a/src/nethack.c b/src/nethack.c index 3725922..d8ae456 100644 --- a/src/nethack.c +++ b/src/nethack.c @@ -120,9 +120,9 @@ static struct nlstrans nethacktrans[] = { }; #endif -char * +const char * DoNLS(from) -char *from; +const char *from; { #ifdef NETHACK struct nlstrans *t; diff --git a/src/screen.c b/src/screen.c index ea8f83f..c221f39 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2028,11 +2028,11 @@ MakeNewEnv() void /*VARARGS2*/ #if defined(USEVARARGS) && defined(__STDC__) -Msg(int err, char *fmt, VA_DOTS) +Msg(int err, const char *fmt, VA_DOTS) #else Msg(err, fmt, VA_DOTS) int err; -char *fmt; +const char *fmt; VA_DECL #endif { @@ -2082,11 +2082,11 @@ VA_DECL void /*VARARGS2*/ #if defined(USEVARARGS) && defined(__STDC__) -Panic(int err, char *fmt, VA_DOTS) +Panic(int err, const char *fmt, VA_DOTS) #else Panic(err, fmt, VA_DOTS) int err; -char *fmt; +const char *fmt; VA_DECL #endif { -- cgit v1.2.1 From 45d0c395945d2ae0f99748d030a8bffcb4cb46f9 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 23 Sep 2009 16:22:06 -0400 Subject: Fix a crash when resizing. The alternate screen has to be reset after a resize. Thanks to Enrico Scholz for pointing this out. Closes savannah bug #26742. --- src/resize.c | 60 +++++++++++++++++++++++------------------------------------- 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/src/resize.c b/src/resize.c index 0bf5f3d..5477bb7 100644 --- a/src/resize.c +++ b/src/resize.c @@ -497,6 +497,7 @@ CheckMaxSize(wi) int wi; { unsigned char *oldnull = null; + unsigned char *oldblank = blank; struct win *p; int i; struct mline *ml; @@ -542,49 +543,34 @@ int wi; # endif #endif +#define RESET_AFC(x, bl) do { if (x == old##bl) x = bl; } while (0) + +#define RESET_LINES(lines, count) \ + do { \ + ml = lines; \ + for (i = 0; i < count; i++, ml++) \ + { \ + RESET_AFC(ml->image, blank); \ + RESET_AFC(ml->attr, null); \ + IFFONT(RESET_AFC(ml->font, null)); \ + IFCOLOR(RESET_AFC(ml->color, null)); \ + IFCOLORX(RESET_AFC(ml->colorx, null)); \ + } \ + } while (0) + /* We have to run through all windows to substitute - * the null references. + * the null and blank references. */ for (p = windows; p; p = p->w_next) { - ml = p->w_mlines; - for (i = 0; i < p->w_height; i++, ml++) - { - if (ml->attr == oldnull) - ml->attr = null; -#ifdef FONT - if (ml->font == oldnull) - ml->font = null; -#endif -#ifdef COLOR - if (ml->color == oldnull) - ml->color= null; -#ifdef COLORS256 - if (ml->colorx == oldnull) - ml->colorx = null; -#endif -#endif - } + RESET_LINES(p->w_mlines, p->w_height); + #ifdef COPY_PASTE - ml = p->w_hlines; - for (i = 0; i < p->w_histheight; i++, ml++) - { - if (ml->attr == oldnull) - ml->attr = null; -# ifdef FONT - if (ml->font == oldnull) - ml->font = null; -# endif -# ifdef COLOR - if (ml->color == oldnull) - ml->color= null; -# ifdef COLORS256 - if (ml->colorx == oldnull) - ml->colorx = null; -# endif -# endif - } + RESET_LINES(p->w_hlines, p->w_histheight); + RESET_LINES(p->w_alt_hlines, p->w_alt_histheight); #endif + + RESET_LINES(p->w_alt_mlines, p->w_alt_height); } } -- cgit v1.2.1 From 7cb17d54cc8fca88e17d6d1e7be2fd49daef1b9d Mon Sep 17 00:00:00 2001 From: Enrico Scholz Date: Wed, 23 Sep 2009 16:24:21 -0400 Subject: Typo fix. Fixing this typo fixes this crash: https://bugzilla.redhat.com/show_bug.cgi?id=515055 --- src/resize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resize.c b/src/resize.c index 5477bb7..9c7b70f 100644 --- a/src/resize.c +++ b/src/resize.c @@ -517,7 +517,7 @@ int wi; #ifdef COLOR mline_old.color = (unsigned char *)xrealloc((char *)mline_old.color, maxwidth); # ifdef COLORS256 - mline_old.colorx = (unsigned char *)xrealloc((char *)mline_old.color, maxwidth); + mline_old.colorx = (unsigned char *)xrealloc((char *)mline_old.colorx, maxwidth); # endif #endif if (!(blank && null && mline_old.image && mline_old.attr IFFONT(&& mline_old.font) IFCOLOR(&& mline_old.color) IFCOLORX(&& mline_old.colorx))) -- cgit v1.2.1 From 8147d08647d59aba7accb748c42db2aba3f31bc4 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 30 Sep 2009 15:54:19 -0400 Subject: 'screen -Q ' to get back results. This is the just the start of querying an existing session. The goal is to allow something like "windows=`screen -Q windows`" in a bash script to get back the results from the 'windows' command. Most of the framework is done. Now the commands need to be updated to specially deal with the queries. --- src/attacher.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/comm.c | 4 ++-- src/comm.sh | 2 ++ src/extern.h | 2 +- src/process.c | 12 +++++++++++ src/screen.c | 7 +++++- src/screen.h | 3 +++ src/socket.c | 51 +++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 138 insertions(+), 10 deletions(-) diff --git a/src/attacher.c b/src/attacher.c index a416ec1..46c14ec 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -83,6 +83,21 @@ AttachSigCont SIGDEFARG SIGRETURN; } +static int QueryResult; + +static sigret_t +QueryResultSuccess SIGDEFARG +{ + QueryResult = 1; + SIGRETURN; +} + +static sigret_t +QueryResultFail SIGDEFARG +{ + QueryResult = 2; + SIGRETURN; +} /* * Send message to a screen backend. @@ -923,10 +938,11 @@ screen_builtin_lck() void -SendCmdMessage(sty, match, av) +SendCmdMessage(sty, match, av, query) char *sty; char *match; char **av; +int query; { int i, s; struct msg m; @@ -954,7 +970,7 @@ char **av; exit(1); } bzero((char *)&m, sizeof(m)); - m.type = MSG_COMMAND; + m.type = query ? MSG_QUERY : MSG_COMMAND; if (attach_tty) { strncpy(m.m_tty, attach_tty, sizeof(m.m_tty) - 1); @@ -979,7 +995,48 @@ char **av; m.m.command.preselect[sizeof(m.m.command.preselect) - 1] = 0; m.m.command.apid = getpid(); debug1("SendCommandMsg writing '%s'\n", m.m.command.cmd); - if (WriteMessage(s, &m)) - Msg(errno, "write"); - close(s); + if (query) + { + /* Create a server socket so we can get back the result */ + char *sp = SockPath + strlen(SockPath); + char query[] = "-queryX"; + char c; + int r = -1; + for (c = 'A'; c <= 'Z'; c++) + { + query[6] = c; + strcpy(sp, query); /* XXX: strncpy? */ + if ((r = MakeServerSocket()) >= 0) + break; + } + + if (r < 0) + Panic(0, "Could not create a listening socket to read the results."); + + strncpy(m.m.command.writeback, SockPath, sizeof(m.m.command.writeback) - 1); + m.m.command.writeback[sizeof(m.m.command.writeback) - 1] = '\0'; + + /* Send the message, then wait for a response */ + signal(SIGCONT, QueryResultSuccess); + signal(SIG_BYE, QueryResultFail); + if (WriteMessage(s, &m)) + Msg(errno, "write"); + close(s); + while (!QueryResult) + pause(); + signal(SIGCONT, SIG_DFL); + signal(SIG_BYE, SIG_DFL); + + /* Read the result and spit it out to stdout */ + ReceiveRaw(r); + unlink(SockPath); + if (QueryResult == 2) /* An error happened */ + exit(1); + } + else + { + if (WriteMessage(s, &m)) + Msg(errno, "write"); + close(s); + } } diff --git a/src/comm.c b/src/comm.c index aedfe49..934ad23 100644 --- a/src/comm.c +++ b/src/comm.c @@ -206,12 +206,12 @@ struct comm comms[RC_LAST + 1] = { "hstatus", NEED_FORE|ARGS_1 }, { "idle", ARGS_0|ARGS_ORMORE }, { "ignorecase", ARGS_01 }, - { "info", NEED_LAYER|ARGS_0 }, + { "info", CAN_QUERY|NEED_LAYER|ARGS_0 }, #ifdef ENCODINGS { "kanji", NEED_FORE|ARGS_12 }, #endif { "kill", NEED_FORE|ARGS_0 }, - { "lastmsg", NEED_DISPLAY|ARGS_0 }, + { "lastmsg", CAN_QUERY|NEED_DISPLAY|ARGS_0 }, { "layout", ARGS_1|ARGS_ORMORE}, { "license", NEED_LAYER|ARGS_0 }, #ifdef LOCK diff --git a/src/comm.sh b/src/comm.sh index 44c83dd..190de58 100644 --- a/src/comm.sh +++ b/src/comm.sh @@ -43,6 +43,8 @@ struct comm #define NEED_FORE (1<<6) /* this command needs a fore window */ #define NEED_DISPLAY (1<<7) /* this command needs a display */ #define NEED_LAYER (1<<8) /* this command needs a layer */ +#define CAN_QUERY (1<<9) /* this command can be queried, i.e. used with -Q to + get back a result to stdout */ #define ARGS_01 (ARGS_0 | ARGS_PLUS1) #define ARGS_02 (ARGS_0 | ARGS_PLUS2) diff --git a/src/extern.h b/src/extern.h index e3e0a59..9e26883 100644 --- a/src/extern.h +++ b/src/extern.h @@ -239,7 +239,7 @@ extern void FreeTransTable __P((void)); extern int Attach __P((int)); extern void Attacher __P((void)); extern sigret_t AttacherFinit __P(SIGPROTOARG); -extern void SendCmdMessage __P((char *, char *, char **)); +extern void SendCmdMessage __P((char *, char *, char **, int)); /* display.c */ extern struct display *MakeDisplay __P((char *, char *, char *, int, int, struct mode *)); diff --git a/src/process.c b/src/process.c index fa3d06c..1737dcf 100644 --- a/src/process.c +++ b/src/process.c @@ -1144,6 +1144,18 @@ int key; return; } n = comms[nr].flags; + /* XXX: Commands will have a CAN_QUERY flag, depending on whether they have + something to return on a query. For example, 'windows' can return a result, + but 'other' cannot. + */ +#if 0 + if (!(n & CAN_QUERY) && queryflag) + { + /* Query flag is set, but this command cannot be queried. */ + Msg(0, "%s command cannot be queried.", comms[nr].name); + return; + } +#endif if ((n & NEED_DISPLAY) && display == 0) { Msg(0, "%s: %s: display required", rc_name, comms[nr].name); diff --git a/src/screen.c b/src/screen.c index e8f4cac..d09359a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -205,6 +205,7 @@ char *wlisttit; int auto_detach = 1; int iflag, rflag, dflag, lsflag, quietflag, wipeflag, xflag; int cmdflag; +int queryflag; int adaptflag; #ifdef MULTIUSER @@ -678,6 +679,10 @@ char **av; case 'q': quietflag = 1; break; + case 'Q': + queryflag = 1; + cmdflag = 1; + break; case 'r': case 'R': #ifdef MULTI @@ -1174,7 +1179,7 @@ char **av; if (!*av) Panic(0, "Please specify a command."); SET_GUID(); - SendCmdMessage(sty, SockMatch, av); + SendCmdMessage(sty, SockMatch, av, queryflag); exit(0); } else if (rflag || xflag) diff --git a/src/screen.h b/src/screen.h index d80f0d5..a5145e7 100644 --- a/src/screen.h +++ b/src/screen.h @@ -172,6 +172,7 @@ struct mode #define MSG_WINCH 6 #define MSG_HANGUP 7 #define MSG_COMMAND 8 +#define MSG_QUERY 9 /* * versions of struct msg: @@ -226,6 +227,8 @@ struct msg char cmd[MAXPATHLEN]; /* command */ int apid; /* pid of frontend */ char preselect[20]; + char writeback[MAXPATHLEN]; /* The socket to write the result. + Only used for MSG_QUERY */ } command; char message[MAXPATHLEN * 2]; diff --git a/src/socket.c b/src/socket.c index 7832832..965a7d0 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1156,14 +1156,58 @@ ReceiveMsg() FinishDetach(&m); break; #endif + case MSG_QUERY: + /* Reset error buffer */ + /* Reset output buffer */ + /* FALLTHROUGH */ case MSG_COMMAND: DoCommandMsg(&m); + if (m.type == MSG_QUERY) + { + char *oldSockPath = SaveStr(SockPath); + strcpy(SockPath, m.m.command.writeback); + int s = MakeClientSocket(0); + strcpy(SockPath, oldSockPath); + Free(oldSockPath); + if (s >= 0) + { + write(s, "So ...", 7); + close(s); + } + Kill(m.m.command.apid, SIGCONT); /* Send SIG_BYE if an error happened, instead */ + } break; default: Msg(0, "Invalid message (type %d).", m.type); } } +void +ReceiveRaw(s) +int s; +{ + char rd[256]; + int len = 0; +#ifdef NAMEDPIPE + if (fcntl(s, F_SETFL, 0) == -1) + Panic(errno, "BLOCK fcntl"); +#else + struct sockaddr_un a; + len = sizeof(a); + if ((s = accept(s, (struct sockaddr *) &a, (void *)&len)) < 0) + { + Msg(errno, "accept"); + return; + } +#endif + while ((len = read(s, rd, 255)) > 0) + { + rd[len] = 0; + printf("%s", rd); + } + close(s); +} + #if defined(_SEQUENT_) && !defined(NAMEDPIPE) #undef connect /* @@ -1590,12 +1634,16 @@ struct msg *mp; if (fc != fullcmd) *--fc = 0; if (Parse(fullcmd, fc - fullcmd, args, argl) <= 0) - return; + { + /* XXX: Return some useful message back if MSG_QUERY */ + return; + } #ifdef MULTIUSER user = *FindUserPtr(mp->m.attach.auser); if (user == 0) { Msg(0, "Unknown user %s tried to send a command!", mp->m.attach.auser); + /* XXX: Return some useful message back if MSG_QUERY */ return; } #else @@ -1605,6 +1653,7 @@ struct msg *mp; if (user->u_password && *user->u_password) { Msg(0, "User %s has a password, cannot use -X option.", mp->m.attach.auser); + /* XXX: Return some useful message back if MSG_QUERY */ return; } #endif -- cgit v1.2.1 From b8bd05cf7df7d0acbb8dd610e3be6fc93298b258 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 9 Nov 2009 12:28:35 -0500 Subject: Fix compile with braille support enabled. --- src/braille.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/braille.c b/src/braille.c index 37c9c11..e12fc8f 100644 --- a/src/braille.c +++ b/src/braille.c @@ -388,7 +388,7 @@ bd_signal() else { AddCStr(D_BL); - Flush(); + Flush(0); } } -- cgit v1.2.1 From 9763857d8857a14f2a20c05e5ed552ca47bba3d8 Mon Sep 17 00:00:00 2001 From: Peter Teichman Date: Mon, 9 Nov 2009 12:35:00 -0500 Subject: Support a PID variable during screenrc evaluation. This evaluates to the current SCREEN process id. --- src/process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/process.c b/src/process.c index fa3d06c..1875ad8 100644 --- a/src/process.c +++ b/src/process.c @@ -4596,6 +4596,8 @@ int bufl, *argl; sprintf(xbuf, "%d", display ? D_width : -1); else if (!strcmp(ps, "LINES")) sprintf(xbuf, "%d", display ? D_height : -1); + else if (!strcmp(ps, "PID")) + sprintf(xbuf, "%d", getpid()); else v = getenv(ps); } -- cgit v1.2.1 From 0456cfb8bd0fe25c3f78cc15a6f10688eb51aa83 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 9 Nov 2009 12:45:33 -0500 Subject: Support 'STY' variable to show the session name. --- src/process.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/process.c b/src/process.c index 1875ad8..970b276 100644 --- a/src/process.c +++ b/src/process.c @@ -4598,6 +4598,8 @@ int bufl, *argl; sprintf(xbuf, "%d", display ? D_height : -1); else if (!strcmp(ps, "PID")) sprintf(xbuf, "%d", getpid()); + else if (!strcmp(ps, "STY")) + v = SockName; else v = getenv(ps); } -- cgit v1.2.1 From 1048d3fce2f4fb52eeab0e30466c62925aafcd86 Mon Sep 17 00:00:00 2001 From: Steve Kemp and Gabriel Date: Tue, 10 Nov 2009 10:22:19 -0500 Subject: unbindall command This command will unbind *all* bindings. This can be useful when screen is used solely for its detaching abilities, such as when letting a console application run as a daemon. If, for some reason, it is necessary to bind commands after this, there is always '-X'. Fixes #27745. --- src/comm.c | 1 + src/process.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/comm.c b/src/comm.c index aedfe49..f87ab11 100644 --- a/src/comm.c +++ b/src/comm.c @@ -312,6 +312,7 @@ struct comm comms[RC_LAST + 1] = { "time", ARGS_01 }, { "title", NEED_FORE|ARGS_01 }, { "umask", ARGS_1|ARGS_ORMORE }, + { "unbindall", ARGS_0 }, { "unsetenv", ARGS_1 }, #ifdef UTF8 { "utf8", NEED_FORE|ARGS_012 }, diff --git a/src/process.c b/src/process.c index 970b276..7553471 100644 --- a/src/process.c +++ b/src/process.c @@ -1398,6 +1398,15 @@ int key; Msg(0, "zmodem mode is %s", zmodes[zmodem_mode]); break; #endif + case RC_UNBINDALL: + { + register unsigned int i; + + for (i = 0; i < sizeof(ktab)/sizeof(*ktab); i++) + ClearAction(&ktab[i]); + Msg(0, "Unbound all keys." ); + break; + } case RC_ZOMBIE: { if (!(s = *args)) -- cgit v1.2.1 From 94d31dc5e9c6e9b0f493af5661ee17cace454d92 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 10 Nov 2009 10:54:34 -0500 Subject: Update document for the 'unbindall' command. --- src/doc/screen.1 | 8 ++++++++ src/doc/screen.texinfo | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 05b4294..b48453f 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2921,6 +2921,14 @@ prompts for one. This command was known as `aka' in previous releases. .sp .ne 3 +.BI "unbindall " +.PP +Unbind all the bindings. This can be useful when +screen is used solely for its detaching abilities, such as when +letting a console application run as a daemon. If, for some reason, +it is necessary to bind commands after this, use 'screen -X'. +.sp +.ne 3 .BI "unsetenv " var .PP Unset an environment variable. diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 3285aeb..ea3a18a 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1133,6 +1133,8 @@ Display time and load average. @xref{Time}. Set the name of the current window. @xref{Title Command}. @item umask [@var{users}]+/-@var{bits} ... Synonym to @code{aclumask}. @xref{Umask}. +@item unbindall +Unset all keybindings. @xref{Bind}. @item unsetenv @var{var} Unset environment variable for new windows. @xref{Setenv}. @item utf8 [@var{state} [@var{dstate}]] @@ -3375,6 +3377,14 @@ new window is bound to @kbd{C-c} and @kbd{c}. The @code{bind} command can be used to redefine the key bindings and to define new bindings. @end deffn +@deffn Command unbindall +(none)@* +Unbind all the bindings. This can be useful when +screen is used solely for its detaching abilities, such as when +letting a console application run as a daemon. If, for some reason, +it is necessary to bind commands after this, use 'screen -X'. +@end deffn + @node Bind Examples, Command Character, Bind, Key Binding @section Examples of the @code{bind} command @noindent -- cgit v1.2.1 From a0e0345f0c7b92e24e50404d7d5ceba83c3e4807 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 10 Nov 2009 12:46:01 -0500 Subject: ChangeLog Start logging changes. This should make it much easier to update documentation, and provide a quick summary of the list of changes to users/developers/packagers etc. --- src/ChangeLog | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 2256d80..2fb3ded 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,86 @@ +Version 4.1.0 (??/??/20??): + New Commands: + * 'unbindall' + * 'up', 'down', 'left', 'right' sub-commands for 'focus' + * 'rendition' + * 'layout', with the following sub-commands + - 'title' + - 'number' + - 'autosave' ('autosave on' or 'autosave off') + - 'new' + - 'save' ('save ') + - 'select' + - 'next' + - 'prev' + - 'attach' + - 'show' + - 'remove' + * 'group' + + Changed Commands: + * '-v' parameter to 'split' command for vertical splits. + * 'sorendition' deprecated in favour of 'rendition so'. + * 'digraph' can take a second parameter to specify custom digraphs. For + example, + 'digraph >= ≥' or 'digraph >= U+2265' + Using '0' as the second parameter will remove the digraph. + * 'stuff' will prompt for input if there's nothing to stuff. + * The argument to ":number" can be prefixed with '+' or '-' to use it as a + relative argument. + * '-g' parameter to 'windowlist' to show nested list of windows. + * '//group' parameter to 'screen' to create a grouped window. + + .screenrc: + * $PID expands to the PID of the screen session. + * $STY expands to the session name. + * Tilde-expansion in pathnames (e.g. for the 'source' command) + * C-style escapes can be used (e.g. "\n" to get a newline with 'stuff') + * '%p' in caption/hardstatus string expands to the PID of the backend, and + '%+p' expands to the PID of the frontend (display). + * '%S' in caption/hardstatus string expands to the session name. + + Window List: + * Nested views when there are window groups (with 'windowlist -g'). + * Press 'm' to toggle the most-recent view. + * Press 'g' to toggle nestedness. + * Press 'a' to view all windows in the list. + + Others: + * Start using 'ChangeLog' for logging changes again. + * Terminfo update for 256-color support. + * Multiple input history (partially from Romain Francoise). + * vi-like fFtT;, searching in copy mode. + * In copy mode, search in reverse direction when 'N' is pressed. + * Tab-completion for command input. + * Some more readline-like bindings in input mode (e.g. ^W, ^D, ^P, ^N etc.) + + In-Progress: + * Scripting support (thanks to Google Summer of Code 2009 project by Rui Guo) + + Developers: + * Juergen Weigert + * Michael Schroeder + * Micah Cowan + * Sadrul Habib Chowdhury + + Contributors: + * Dick + * Gabriel + * Benjamin Andresen + * Maarten Billemont + * Curtis Brown + * Cyril Brulebois + * Trent W Buck + * Stephane Chazelas + * Christian Ebert + * Geraint Edwards + * Romain Francoise + * Emanuele Giaquinta + * Steve Kemp + * William Pursell + * Enrico Scholz + * Peter Teichman + 30.10.94 This is a quick overview of screen's life story. But it is not up -- cgit v1.2.1 From 4f6b575fb65f5436d076210baa449d6e7caaf53a Mon Sep 17 00:00:00 2001 From: Thomas Dickey Date: Wed, 11 Nov 2009 11:05:58 -0500 Subject: Set both Xterm title and icon name. screen's so-called "rxvt_osc" option (actually xterm control sequences) includes handling for OSC parameters 0 and 1. Referring to ctlseqs.ms, these parameters are of interest: Ps = 0 -> Change Icon Name and Window Title to Pt Ps = 1 -> Change Icon Name to Pt Ps = 2 -> Change Window Title to Pt screen allows 0 and 1 (it should allow 2, but it is not used as often, and screen's code is unpalatable). However, it maps the 0 into 1, setting only the icon name. That isn't useful and is opposite to the normal sense these control sequences would be used in. Closes Debian#344759 http://www.xfree86.org/current/ctlseqs.html --- src/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index e5954ec..e430963 100644 --- a/src/display.c +++ b/src/display.c @@ -3510,7 +3510,7 @@ SetXtermOSC(i, s) int i; char *s; { - static char oscs[] = "1;\000\00020;\00039;\00049;\000"; + static char oscs[] = "0;\000\00020;\00039;\00049;\000"; ASSERT(display); if (!D_CXT) -- cgit v1.2.1 From 575b2d074605453e9a694d2704a2ae7bc2e5ff3a Mon Sep 17 00:00:00 2001 From: Thomas Dickey Date: Wed, 11 Nov 2009 11:14:32 -0500 Subject: Add a note about a fixed bug in ncurses. References Debian#344759 --- src/misc.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/misc.c b/src/misc.c index c56d87a..4418803 100644 --- a/src/misc.c +++ b/src/misc.c @@ -657,6 +657,19 @@ int (*outc) __P((int)); * zeros but sleeps instead. This breaks CalcCost, of course. * Also, the ncurses wait functions use a global variable * to store the current outc function. Oh well... + * + * This comment dates from late 1998. See ncurses NEWS (990102): + * + * + provide support for termcap ospeed variable by copying it from the + * internal cur_term member, and using ospeed as the baudrate reference + * for the delay_output and tputs functions. If an application does not + * set ospeed, the library behaves as before, except that _nc_timed_wait + * is no longer used, or needed, since ospeed always has a value. But + * the application can modify ospeed to adjust the output of padding + * characters (from a bug report for screen 3.7.6 and email from Michael + * Schroeder ). + * + * Also read the source code for delay_output() -TD */ int (*save_outc) __P((int)); -- cgit v1.2.1 From 2591a23cfcb30d08236e6f6d9f99b1abb4e998d1 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 11 Nov 2009 11:15:59 -0500 Subject: Update Changelog. --- src/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ChangeLog b/src/ChangeLog index 2fb3ded..f769449 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -72,6 +72,7 @@ Version 4.1.0 (??/??/20??): * Cyril Brulebois * Trent W Buck * Stephane Chazelas + * Thomas Dickey * Christian Ebert * Geraint Edwards * Romain Francoise -- cgit v1.2.1 From fe5ff3987224b31ca0f9fe9950b661870ec174d8 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 11 Nov 2009 16:46:40 -0500 Subject: Refactor some code. --- src/extern.h | 2 + src/process.c | 134 ++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 77 insertions(+), 59 deletions(-) diff --git a/src/extern.h b/src/extern.h index e3e0a59..2607859 100644 --- a/src/extern.h +++ b/src/extern.h @@ -298,6 +298,8 @@ extern void Resize_obuf __P((void)); extern void NukePending __P((void)); #endif extern void SetCanvasWindow __P((struct canvas *, struct win *)); +extern void SetForeCanvas __P((struct display *, struct canvas *)); +extern struct canvas *FindCanvas __P((int, int)); extern int MakeDefaultCanvas __P((void)); extern int AddCanvas __P((int)); extern void RemCanvas __P((void)); diff --git a/src/process.c b/src/process.c index 7553471..219a432 100644 --- a/src/process.c +++ b/src/process.c @@ -162,7 +162,6 @@ static void ResizeFin __P((char *, int, char *)); static struct action *FindKtab __P((char *, int)); static void SelectFin __P((char *, int, char *)); static void SelectLayoutFin __P((char *, int, char *)); -static struct canvas *FindCanvas __P((int, int)); extern struct layer *flayer; @@ -3942,63 +3941,37 @@ int key; LaySetCursor(); break; case RC_FOCUS: - if (!*args || !strcmp(*args, "next")) - D_forecv = D_forecv->c_next ? D_forecv->c_next : D_cvlist; - else if (!strcmp(*args, "prev")) - { - struct canvas *cv; - for (cv = D_cvlist; cv->c_next && cv->c_next != D_forecv; cv = cv->c_next) - ; - D_forecv = cv; - } - else if (!strcmp(*args, "top")) - D_forecv = D_cvlist; - else if (!strcmp(*args, "bottom")) - { - struct canvas *cv; - for (cv = D_cvlist; cv->c_next; cv = cv->c_next) - ; - D_forecv = cv; - } - else if (!strcmp(*args, "up")) - D_forecv = FindCanvas(D_forecv->c_xs, D_forecv->c_ys - 1); - else if (!strcmp(*args, "down")) - D_forecv = FindCanvas(D_forecv->c_xs, D_forecv->c_ye + 2); - else if (!strcmp(*args, "left")) - D_forecv = FindCanvas(D_forecv->c_xs - 1, D_forecv->c_ys); - else if (!strcmp(*args, "right")) - D_forecv = FindCanvas(D_forecv->c_xe + 1, D_forecv->c_ys); - else - { - Msg(0, "%s: usage: focus [next|prev|up|down|left|right|top|bottom]", rc_name); - break; - } - if ((focusminwidth && (focusminwidth < 0 || D_forecv->c_xe - D_forecv->c_xs + 1 < focusminwidth)) || - (focusminheight && (focusminheight < 0 || D_forecv->c_ye - D_forecv->c_ys + 1 < focusminheight))) - { - ResizeCanvas(&D_canvas); - RecreateCanvasChain(); - RethinkDisplayViewports(); - ResizeLayersToCanvases(); /* redisplays */ - } - fore = D_fore = Layer2Window(D_forecv->c_layer); - if (D_other == fore) - D_other = 0; - flayer = D_forecv->c_layer; -#ifdef RXVT_OSC - if (D_xtermosc[2] || D_xtermosc[3]) - { - Activate(-1); - break; - } -#endif - RefreshHStatus(); -#ifdef RXVT_OSC - RefreshXtermOSC(); -#endif - flayer = D_forecv->c_layer; - CV_CALL(D_forecv, LayRestore();LaySetCursor()); - WindowChanged(0, 'F'); + { + struct canvas *cv = 0; + if (!*args || !strcmp(*args, "next")) + cv = D_forecv->c_next ? D_forecv->c_next : D_cvlist; + else if (!strcmp(*args, "prev")) + { + for (cv = D_cvlist; cv->c_next && cv->c_next != D_forecv; cv = cv->c_next) + ; + } + else if (!strcmp(*args, "top")) + cv = D_cvlist; + else if (!strcmp(*args, "bottom")) + { + for (cv = D_cvlist; cv->c_next; cv = cv->c_next) + ; + } + else if (!strcmp(*args, "up")) + cv = FindCanvas(D_forecv->c_xs, D_forecv->c_ys - 1); + else if (!strcmp(*args, "down")) + cv = FindCanvas(D_forecv->c_xs, D_forecv->c_ye + 2); + else if (!strcmp(*args, "left")) + cv = FindCanvas(D_forecv->c_xs - 1, D_forecv->c_ys); + else if (!strcmp(*args, "right")) + cv = FindCanvas(D_forecv->c_xe + 1, D_forecv->c_ys); + else + { + Msg(0, "%s: usage: focus [next|prev|up|down|left|right|top|bottom]", rc_name); + break; + } + SetForeCanvas(display, cv); + } break; case RC_RESIZE: i = 0; @@ -6790,7 +6763,7 @@ int percent; return done; } -static struct canvas * +struct canvas * FindCanvas(x, y) int x, y; { @@ -7022,6 +6995,49 @@ char *data; buf[len] = '\034'; } +void +SetForeCanvas(d, cv) +struct display *d; +struct canvas *cv; +{ + struct display *odisplay = display; + if (d->d_forecv == cv) + return; + + display = d; + D_forecv = cv; + if ((focusminwidth && (focusminwidth < 0 || D_forecv->c_xe - D_forecv->c_xs + 1 < focusminwidth)) || + (focusminheight && (focusminheight < 0 || D_forecv->c_ye - D_forecv->c_ys + 1 < focusminheight))) + { + ResizeCanvas(&D_canvas); + RecreateCanvasChain(); + RethinkDisplayViewports(); + ResizeLayersToCanvases(); /* redisplays */ + } + fore = D_fore = Layer2Window(D_forecv->c_layer); + if (D_other == fore) + D_other = 0; + flayer = D_forecv->c_layer; +#ifdef RXVT_OSC + if (D_xtermosc[2] || D_xtermosc[3]) + { + Activate(-1); + } + else +#endif + { + RefreshHStatus(); +#ifdef RXVT_OSC + RefreshXtermOSC(); +#endif + flayer = D_forecv->c_layer; + CV_CALL(D_forecv, LayRestore();LaySetCursor()); + WindowChanged(0, 'F'); + } + + display = odisplay; +} + #ifdef RXVT_OSC void RefreshXtermOSC() -- cgit v1.2.1 From 7b2854221b487ee6157baf814d1e49035ba11736 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 11 Nov 2009 17:29:33 -0500 Subject: Remove ooooold cruft. The bug in ncurses that this tried to work around has long been fixed. Thanks to Thomas Dickey. --- src/misc.c | 46 ---------------------------------------------- src/os.h | 5 ----- 2 files changed, 51 deletions(-) diff --git a/src/misc.c b/src/misc.c index 4418803..9d7c13d 100644 --- a/src/misc.c +++ b/src/misc.c @@ -651,52 +651,6 @@ int (*outc) __P((int)); return 0; } -# ifdef linux - -/* stupid stupid linux ncurses! It won't to padding with - * zeros but sleeps instead. This breaks CalcCost, of course. - * Also, the ncurses wait functions use a global variable - * to store the current outc function. Oh well... - * - * This comment dates from late 1998. See ncurses NEWS (990102): - * - * + provide support for termcap ospeed variable by copying it from the - * internal cur_term member, and using ospeed as the baudrate reference - * for the delay_output and tputs functions. If an application does not - * set ospeed, the library behaves as before, except that _nc_timed_wait - * is no longer used, or needed, since ospeed always has a value. But - * the application can modify ospeed to adjust the output of padding - * characters (from a bug report for screen 3.7.6 and email from Michael - * Schroeder ). - * - * Also read the source code for delay_output() -TD - */ - -int (*save_outc) __P((int)); - -# undef tputs - -void -xtputs(str, affcnt, outc) -char *str; -int affcnt; -int (*outc) __P((int)); -{ - extern int tputs __P((const char *, int, int (*)(int))); - save_outc = outc; - tputs(str, affcnt, outc); -} - -int -_nc_timed_wait(mode, ms, tlp) -int mode, ms, *tlp; -{ - _delay(ms * 10, save_outc); - return 0; -} - -# endif /* linux */ - #endif /* TERMINFO */ diff --git a/src/os.h b/src/os.h index b56b660..bac2b5f 100644 --- a/src/os.h +++ b/src/os.h @@ -234,11 +234,6 @@ extern int errno; # undef TIOCPKT #endif -/* linux ncurses is broken, we have to use our own tputs */ -#if defined(linux) && defined(TERMINFO) -# define tputs xtputs -#endif - /* Alexandre Oliva: SVR4 style ptys don't work with osf */ #ifdef __osf__ # undef HAVE_SVR4_PTYS -- cgit v1.2.1 From ca20b068fd39f8f9ca0c67353bc2b87141d0d290 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 12 Nov 2009 12:49:52 -0500 Subject: Add support for mouse tracking. Mouse tracking can be turned on/off using 'mousetrack' command. With mouse-tracking turned on, it is possible to switch to a region ('focus') using mouse-clicks. --- src/ChangeLog | 12 +++++++++--- src/comm.c | 2 ++ src/display.c | 47 ++++++++++++++++++++++++++++++++++++++--------- src/display.h | 3 +++ src/process.c | 17 +++++++++++++++++ 5 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index f769449..713a038 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,8 +1,9 @@ Version 4.1.0 (??/??/20??): New Commands: - * 'unbindall' + * 'unbindall' to unbind all commands * 'up', 'down', 'left', 'right' sub-commands for 'focus' - * 'rendition' + * 'rendition' to specify rendition to use in caption/hardstatus for + window-names that have bell/monitor/so turned on. * 'layout', with the following sub-commands - 'title' - 'number' @@ -15,7 +16,12 @@ Version 4.1.0 (??/??/20??): - 'attach' - 'show' - 'remove' - * 'group' + * 'group' for moving window(s) into a group. + * 'defmousetrack' and 'mousetrack', to turn on/off mouse-tracking for + displays. It's turned off by default. With mouse-tracking turned on, it's + possible to switch to a region ('focus') using mouse clicks. Additional + features might be to allow clicking on window-titles in the caption to + switch to that window. Changed Commands: * '-v' parameter to 'split' command for vertical splits. diff --git a/src/comm.c b/src/comm.c index f87ab11..4921911 100644 --- a/src/comm.c +++ b/src/comm.c @@ -157,6 +157,7 @@ struct comm comms[RC_LAST + 1] = #endif { "defmode", ARGS_1 }, { "defmonitor", ARGS_1 }, + { "defmousetrack", ARGS_1 }, #ifdef MULTI { "defnonblock", ARGS_1 }, #endif @@ -234,6 +235,7 @@ struct comm comms[RC_LAST + 1] = { "maxwin", ARGS_1 }, { "meta", NEED_LAYER|ARGS_0 }, { "monitor", NEED_FORE|ARGS_01 }, + { "mousetrack", NEED_DISPLAY | ARGS_01 }, { "msgminwait", ARGS_1 }, { "msgwait", ARGS_1 }, #ifdef MULTIUSER diff --git a/src/display.c b/src/display.c index e430963..d25328d 100644 --- a/src/display.c +++ b/src/display.c @@ -123,6 +123,7 @@ struct display TheDisplay; */ int defobuflimit = OBUF_MAX; int defnonblock = -1; +int defmousetrack = 0; #ifdef AUTO_NUKE int defautonuke = 0; #endif @@ -314,6 +315,7 @@ struct mode *Mode; D_termname[sizeof(D_termname) - 1] = 0; D_user = *u; D_processinput = ProcessInput; + D_mousetrack = defmousetrack; return display; } @@ -412,6 +414,11 @@ FreeDisplay() if (p->w_zdisplay == display) zmodem_abort(p, 0); #endif + if (D_mousetrack) + { + D_mousetrack = 0; + MouseMode(0); + } #ifdef MULTI free((char *)display); #endif @@ -1205,6 +1212,8 @@ FinitTerm() KeypadMode(0); CursorkeysMode(0); CursorVisibility(0); + if (D_mousetrack) + D_mousetrack = 0; MouseMode(0); SetRendition(&mchar_null); SetFlow(FLOW_NOW); @@ -1522,7 +1531,13 @@ void MouseMode(mode) int mode; { - if (display && D_mouse != mode) + if (!display) + return; + + if (mode < D_mousetrack) + mode = D_mousetrack; + + if (D_mouse != mode) { char mousebuf[20]; if (!D_CXT) @@ -4065,15 +4080,29 @@ char *data; y = bp[4] - 33; if (x >= D_forecv->c_xs && x <= D_forecv->c_xe && y >= D_forecv->c_ys && y <= D_forecv->c_ye) { - x -= D_forecv->c_xoff; - y -= D_forecv->c_yoff; - if (x >= 0 && x < D_forecv->c_layer->l_width && y >= 0 && y < D_forecv->c_layer->l_height) + if (D_fore && D_fore->w_mouse) + { + /* Send clicks only if the window is expecting clicks */ + x -= D_forecv->c_xoff; + y -= D_forecv->c_yoff; + if (x >= 0 && x < D_forecv->c_layer->l_width && y >= 0 && y < D_forecv->c_layer->l_height) + { + bp[3] = x + 33; + bp[4] = y + 33; + i -= 4; + bp += 4; + continue; + } + } + } + else if (D_mousetrack && bp[2] == '#') + { + /* 'focus' to the clicked region, only on mouse up */ + struct canvas *cv = FindCanvas(x, y); + if (cv) { - bp[3] = x + 33; - bp[4] = y + 33; - i -= 4; - bp += 4; - continue; + SetForeCanvas(display, cv); + /* XXX: Do we want to reset the input buffer? */ } } if (bp[0] == '[') diff --git a/src/display.h b/src/display.h index aaaf6bf..7ae32e8 100644 --- a/src/display.h +++ b/src/display.h @@ -150,6 +150,8 @@ struct display int d_hstatus; /* hardstatus used */ int d_lp_missing; /* last character on bot line missing */ int d_mouse; /* mouse mode */ + int d_mousetrack; /* set when user wants to use mouse even when the window + does not */ #ifdef RXVT_OSC int d_xtermosc[4]; /* osc used */ #endif @@ -275,6 +277,7 @@ extern struct display TheDisplay; #define D_hstatus DISPLAY(d_hstatus) #define D_lp_missing DISPLAY(d_lp_missing) #define D_mouse DISPLAY(d_mouse) +#define D_mousetrack DISPLAY(d_mousetrack) #define D_xtermosc DISPLAY(d_xtermosc) #define D_lpchar DISPLAY(d_lpchar) #define D_status DISPLAY(d_status) diff --git a/src/process.c b/src/process.c index 219a432..8136fd5 100644 --- a/src/process.c +++ b/src/process.c @@ -75,6 +75,7 @@ extern char *printcmd; extern int default_startup; extern int defobuflimit; extern int defnonblock; +extern int defmousetrack; extern int ZombieKey_destroy; extern int ZombieKey_resurrect; extern int ZombieKey_onerror; @@ -2727,6 +2728,22 @@ int key; if (ParseOnOff(act, &n) == 0) nwin_default.monitor = (n == 0) ? MON_OFF : MON_ON; break; + case RC_DEFMOUSETRACK: + if (ParseOnOff(act, &n) == 0) + defmousetrack = (n == 0) ? 0 : 1000; + break; + case RC_MOUSETRACK: + if (!args[0]) + { + Msg(0, "Mouse tracking for this display is turned %s", D_mousetrack ? "on" : "off"); + } + else if (ParseOnOff(act, &n) == 0) + { + D_mousetrack = n == 0 ? 0 : 1000; + if (D_fore) + MouseMode(D_fore->w_mouse); + } + break; case RC_DEFSILENCE: if (ParseOnOff(act, &n) == 0) nwin_default.silence = (n == 0) ? SILENCE_OFF : SILENCE_ON; -- cgit v1.2.1 From 827243a5521df50824f0371f24a67692d11fe101 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 12 Nov 2009 13:42:55 -0500 Subject: Start refactoring. The Screen code at this stage is somewhat complicated to start working on. So refactor some code so it's easier to manage and hack. Also, the plan is to eventually add some documentation, possibly in the header files showing their usage. --- src/Makefile.in | 71 ++--- src/canvas.c | 894 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/canvas.h | 83 ++++++ src/display.c | 698 +------------------------------------------ src/display.h | 32 -- src/extern.h | 12 - src/process.c | 163 +---------- src/screen.h | 1 + 8 files changed, 1017 insertions(+), 937 deletions(-) create mode 100644 src/canvas.c create mode 100644 src/canvas.h diff --git a/src/Makefile.in b/src/Makefile.in index c551067..28938b0 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -61,12 +61,12 @@ CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \ search.c tty.c term.c window.c utmp.c loadav.c putenv.c help.c \ termcap.c input.c attacher.c pty.c process.c display.c comm.c \ kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \ - sched.c teln.c nethack.c encoding.c + sched.c teln.c nethack.c encoding.c canvas.c OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ termcap.o input.o attacher.o pty.o process.o display.o comm.o \ kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \ - sched.o teln.o nethack.o encoding.o + sched.o teln.o nethack.o encoding.o canvas.o all: screen @@ -273,66 +273,69 @@ depend.in: $(CFILES) term.h ############################################################################### ### Dependencies: -screen.o: screen.c config.h screen.h os.h osdef.h ansi.h acls.h \ +screen.o: canvas.h screen.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h braille.h \ patchlevel.h logfile.h extern.h -ansi.o: ansi.c config.h screen.h os.h osdef.h ansi.h acls.h \ +ansi.o: canvas.h ansi.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h braille.h extern.h \ logfile.h -fileio.o: fileio.c config.h screen.h os.h osdef.h ansi.h acls.h \ +fileio.o: canvas.h fileio.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -mark.o: mark.c config.h screen.h os.h osdef.h ansi.h acls.h \ +mark.o: canvas.h mark.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h mark.h extern.h -misc.o: misc.c config.h screen.h os.h osdef.h ansi.h acls.h \ +misc.o: canvas.h misc.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -resize.o: resize.c config.h screen.h os.h osdef.h ansi.h acls.h \ +resize.o: canvas.h resize.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -socket.o: socket.c config.h screen.h os.h osdef.h ansi.h acls.h \ +socket.o: canvas.h socket.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -search.o: search.c config.h screen.h os.h osdef.h ansi.h acls.h \ +search.o: canvas.h search.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h mark.h extern.h -tty.o: tty.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ +tty.o: canvas.h tty.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ layer.h term.h image.h display.h window.h extern.h -term.o: term.c term.h -window.o: window.c config.h screen.h os.h osdef.h ansi.h acls.h \ +term.o: canvas.h term.c term.h +window.o: canvas.h window.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h -utmp.o: utmp.c config.h screen.h os.h osdef.h ansi.h acls.h \ +utmp.o: canvas.h utmp.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -loadav.o: loadav.c config.h screen.h os.h osdef.h ansi.h acls.h \ +loadav.o: canvas.h loadav.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -putenv.o: putenv.c config.h -help.o: help.c config.h screen.h os.h osdef.h ansi.h acls.h \ +putenv.o: canvas.h putenv.c config.h +help.o: canvas.h help.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -termcap.o: termcap.c config.h screen.h os.h osdef.h ansi.h acls.h \ +termcap.o: canvas.h termcap.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -input.o: input.c config.h screen.h os.h osdef.h ansi.h acls.h \ +input.o: canvas.h input.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -attacher.o: attacher.c config.h screen.h os.h osdef.h ansi.h \ +attacher.o: canvas.h attacher.c config.h screen.h os.h osdef.h ansi.h \ acls.h comm.h layer.h term.h image.h display.h window.h extern.h -pty.o: pty.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ +pty.o: canvas.h pty.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ layer.h term.h image.h display.h window.h extern.h -process.o: process.c config.h screen.h os.h osdef.h ansi.h acls.h \ +process.o: canvas.h process.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h -display.o: display.c config.h screen.h os.h osdef.h ansi.h acls.h \ +display.o: canvas.h display.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h braille.h -comm.o: comm.c config.h acls.h comm.h -kmapdef.o: kmapdef.c config.h -acls.o: acls.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ +canvas.o: canvas.h canvas.c config.h screen.h os.h osdef.h ansi.h acls.h \ + comm.h layer.h term.h image.h display.h window.h extern.h \ + braille.h +comm.o: canvas.h comm.c config.h acls.h comm.h +kmapdef.o: canvas.h kmapdef.c config.h +acls.o: canvas.h acls.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ layer.h term.h image.h display.h window.h extern.h -braille.o: braille.c config.h screen.h os.h osdef.h ansi.h acls.h \ +braille.o: canvas.h braille.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h braille.h -braille_tsi.o: braille_tsi.c config.h screen.h os.h osdef.h ansi.h \ +braille_tsi.o: canvas.h braille_tsi.c config.h screen.h os.h osdef.h ansi.h \ acls.h comm.h layer.h term.h image.h display.h window.h extern.h \ braille.h -logfile.o: logfile.c config.h screen.h os.h osdef.h ansi.h acls.h \ +logfile.o: canvas.h logfile.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h -layer.o: layer.c config.h screen.h os.h osdef.h ansi.h acls.h \ +layer.o: canvas.h layer.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -sched.o: sched.c config.h screen.h os.h osdef.h ansi.h acls.h \ +sched.o: canvas.h sched.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h -teln.o: teln.c config.h screen.h os.h osdef.h ansi.h acls.h \ +teln.o: canvas.h teln.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -nethack.o: nethack.c config.h screen.h os.h osdef.h ansi.h acls.h \ +nethack.o: canvas.h nethack.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -encoding.o: encoding.c config.h screen.h os.h osdef.h ansi.h acls.h \ +encoding.o: canvas.h encoding.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h diff --git a/src/canvas.c b/src/canvas.c new file mode 100644 index 0000000..50752f0 --- /dev/null +++ b/src/canvas.c @@ -0,0 +1,894 @@ +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +#include "config.h" +#include "screen.h" +#include "extern.h" +#include "canvas.h" + +extern struct display *display; +extern struct win *fore, *windows; +extern struct layer *flayer; +extern int captionalways; +extern struct LayFuncs BlankLf; +extern int focusminwidth, focusminheight; + +static void +CanvasInitBlank(cv) +struct canvas *cv; +{ + cv->c_blank.l_cvlist = cv; + cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1; + cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; + cv->c_blank.l_x = cv->c_blank.l_y = 0; + cv->c_blank.l_layfn = &BlankLf; + cv->c_blank.l_data = 0; + cv->c_blank.l_next = 0; + cv->c_blank.l_bottom = &cv->c_blank; + cv->c_blank.l_blocking = 0; + cv->c_layer = &cv->c_blank; +} + +static void +FreePerp(pcv) +struct canvas *pcv; +{ + struct canvas *cv; + + if (!pcv->c_slperp) + return; + cv = pcv->c_slperp; + cv->c_slprev = pcv->c_slprev; + if (cv->c_slprev) + cv->c_slprev->c_slnext = cv; + cv->c_slback = pcv->c_slback; + if (cv->c_slback && cv->c_slback->c_slperp == pcv) + cv->c_slback->c_slperp = cv; + cv->c_slorient = pcv->c_slorient; + cv->c_slweight = pcv->c_slweight; + while (cv->c_slnext) + { + cv = cv->c_slnext; + cv->c_slorient = pcv->c_slorient; + cv->c_slback = pcv->c_slback; + cv->c_slweight = pcv->c_slweight; + } + cv->c_slnext = pcv->c_slnext; + if (cv->c_slnext) + cv->c_slnext->c_slprev = cv; + free(pcv); +} + +void +FreeCanvas(cv) +struct canvas *cv; +{ + struct viewport *vp, *nvp; + struct canvas **cvp; + struct win *p; + + if (cv->c_slprev) + cv->c_slprev->c_slnext = cv->c_slnext; + if (cv->c_slnext) + cv->c_slnext->c_slprev = cv->c_slprev; + if (cv->c_slback && cv->c_slback->c_slperp == cv) + cv->c_slback->c_slperp = cv->c_slnext ? cv->c_slnext : cv->c_slprev; + if (cv->c_slperp) + { + while (cv->c_slperp) + FreeCanvas(cv->c_slperp); + free(cv); + return; + } + + if (display) + { + if (D_forecv == cv) + D_forecv = 0; + /* remove from canvas chain as SetCanvasWindow might call + * some layer function */ + for (cvp = &D_cvlist; *cvp ; cvp = &(*cvp)->c_next) + if (*cvp == cv) + { + *cvp = cv->c_next; + break; + } + } + p = cv->c_layer ? Layer2Window(cv->c_layer) : 0; + SetCanvasWindow(cv, 0); + if (p) + WindowChanged(p, 'u'); + if (flayer == cv->c_layer) + flayer = 0; + for (vp = cv->c_vplist; vp; vp = nvp) + { + vp->v_canvas = 0; + nvp = vp->v_next; + vp->v_next = 0; + free(vp); + } + evdeq(&cv->c_captev); + free(cv); +} + +int +CountCanvas(cv) +struct canvas *cv; +{ + int num = 0; + for (; cv; cv = cv->c_slnext) + { + if (cv->c_slperp) + { + struct canvas *cvp; + int nump = 1, n; + for (cvp = cv->c_slperp; cvp; cvp = cvp->c_slnext) + if (cvp->c_slperp) + { + n = CountCanvas(cvp->c_slperp); + if (n > nump) + nump = n; + } + num += nump; + } + else + num++; + } + return num; +} + +int +CountCanvasPerp(cv) +struct canvas *cv; +{ + struct canvas *cvp; + int num = 1, n; + for (cvp = cv->c_slperp; cvp; cvp = cvp->c_slnext) + if (cvp->c_slperp) + { + n = CountCanvas(cvp->c_slperp); + if (n > num) + num = n; + } + return num; +} + +struct canvas * +FindCanvas(x, y) +int x, y; +{ + struct canvas *cv, *mcv = 0; + int m, mm = 0; + + for (cv = D_cvlist; cv; cv = cv->c_next) + { + /* ye + 1 because of caption line */ + if (x >= cv->c_xs && x <= cv->c_xe && y >= cv->c_ys && y <= cv->c_ye + 1) + return cv; + if (cv == D_forecv) + continue; + m = 0; + if (x >= D_forecv->c_xs && x <= D_forecv->c_xe) + { + if (x < cv->c_xs || x > cv->c_xe) + continue; + if (y < D_forecv->c_ys && y < cv->c_ys) + continue; + if (y > D_forecv->c_ye + 1 && y > cv->c_ye + 1) + continue; + if (y < cv->c_ys) + m = cv->c_ys - y; + if (y > cv->c_ye + 1) + m = y - (cv->c_ye + 1); + } + if (y >= D_forecv->c_ys && y <= D_forecv->c_ye + 1) + { + if (y < cv->c_ys || y > cv->c_ye + 1) + continue; + if (x < D_forecv->c_xs && x < cv->c_xs) + continue; + if (x > D_forecv->c_xe && x > cv->c_xe) + continue; + if (x < cv->c_xs) + m = cv->c_xs - x; + if (x > cv->c_xe) + m = x - cv->c_xe; + } + if (m && (!mm || m < mm)) + { + mcv = cv; + mm = m; + } + } + return mcv ? mcv : D_forecv; +} + +void +SetCanvasWindow(cv, wi) +struct canvas *cv; +struct win *wi; +{ + struct win *p = 0, **pp; + struct layer *l; + struct canvas *cvp, **cvpp; + + l = cv->c_layer; + display = cv->c_display; + + if (l) + { + /* remove old layer */ + for (cvpp = &l->l_cvlist; (cvp = *cvpp); cvpp = &cvp->c_lnext) + if (cvp == cv) + break; + ASSERT(cvp); + *cvpp = cvp->c_lnext; + + p = Layer2Window(l); + l = cv->c_layer; + cv->c_layer = 0; + + if (p && cv == D_forecv) + { +#ifdef MULTIUSER + ReleaseAutoWritelock(display, p); +#endif + if (p->w_silence) + { + SetTimeout(&p->w_silenceev, p->w_silencewait * 1000); + evenq(&p->w_silenceev); + } + D_other = fore; + D_fore = 0; + } + if (l->l_cvlist == 0 && (p == 0 || l != p->w_savelayer)) + KillLayerChain(l); + } + + /* find right layer to display on canvas */ + if (wi && wi->w_type != W_TYPE_GROUP) + { + l = &wi->w_layer; + if (wi->w_savelayer && (wi->w_blocked || wi->w_savelayer->l_cvlist == 0)) + l = wi->w_savelayer; + } + else + { + l = &cv->c_blank; + if (wi) + l->l_data = (char *)wi; + else + l->l_data = 0; + } + + /* add our canvas to the layer's canvaslist */ + ASSERT(l->l_cvlist != cv); + cv->c_lnext = l->l_cvlist; + l->l_cvlist = cv; + cv->c_layer = l; + cv->c_xoff = cv->c_xs; + cv->c_yoff = cv->c_ys; + RethinkViewportOffsets(cv); + + if (flayer == 0) + flayer = l; + + if (wi && wi->w_type == W_TYPE_GROUP) + { + /* auto-start windowlist on groups */ + struct display *d = display; + struct layer *oldflayer = flayer; + flayer = l; + display_wlist(0, 0, wi); + flayer = oldflayer; + display = d; + } + + if (wi && D_other == wi) + D_other = wi->w_next; /* Might be 0, but that's OK. */ + if (cv == D_forecv) + { + D_fore = wi; + fore = D_fore; /* XXX ? */ + if (wi) + { +#ifdef MULTIUSER + ObtainAutoWritelock(display, wi); +#endif + /* + * Place the window at the head of the most-recently-used list + */ + if (windows != wi) + { + for (pp = &windows; (p = *pp); pp = &p->w_next) + if (p == wi) + break; + ASSERT(p); + *pp = p->w_next; + p->w_next = windows; + windows = p; + WListLinkChanged(); + } + } + } +} + +static void +cv_winid_fn(ev, data) +struct event *ev; +char *data; +{ + int ox, oy; + struct canvas *cv = (struct canvas *)data; + + display = cv->c_display; + if (D_status == STATUS_ON_WIN) + { + SetTimeout(ev, 1); + evenq(ev); + return; + } + ox = D_x; + oy = D_y; + if (cv->c_ye + 1 < D_height) + RefreshLine(cv->c_ye + 1, 0, D_width - 1, 0); + if (ox != -1 && oy != -1) + GotoPos(ox, oy); +} + +int +MakeDefaultCanvas() +{ + struct canvas *cv; + + ASSERT(display); + if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0) + return -1; + cv->c_xs = 0; + cv->c_xe = D_width - 1; + cv->c_ys = 0; + cv->c_ye = D_height - 1 - (D_has_hstatus == HSTATUS_LASTLINE) - captionalways; + debug2("MakeDefaultCanvas 0,0 %d,%d\n", cv->c_xe, cv->c_ye); + cv->c_xoff = 0; + cv->c_yoff = 0; + cv->c_next = 0; + cv->c_display = display; + cv->c_vplist = 0; + cv->c_slnext = 0; + cv->c_slprev = 0; + cv->c_slperp = 0; + cv->c_slweight = 1; + cv->c_slback = &D_canvas; + D_canvas.c_slperp = cv; + D_canvas.c_xs = cv->c_xs; + D_canvas.c_xe = cv->c_xe; + D_canvas.c_ys = cv->c_ys; + D_canvas.c_ye = cv->c_ye; + cv->c_slorient = SLICE_UNKN; + cv->c_captev.type = EV_TIMEOUT; + cv->c_captev.data = (char *)cv; + cv->c_captev.handler = cv_winid_fn; + + CanvasInitBlank(cv); + cv->c_lnext = 0; + + D_cvlist = cv; + RethinkDisplayViewports(); + D_forecv = cv; /* default input focus */ + return 0; +} + +static struct canvas ** +CreateCanvasChainRec(cv, cvp) +struct canvas *cv; +struct canvas **cvp; +{ + for (; cv; cv = cv->c_slnext) + { + if (cv->c_slperp) + cvp = CreateCanvasChainRec(cv->c_slperp, cvp); + else + { + *cvp = cv; + cvp = &cv->c_next; + } + } + return cvp; +} + +void +RecreateCanvasChain() +{ + struct canvas **cvp; + cvp = CreateCanvasChainRec(D_canvas.c_slperp, &D_cvlist); + *cvp = 0; +} + +void +EqualizeCanvas(cv, gflag) +struct canvas *cv; +int gflag; +{ + struct canvas *cv2; + for (; cv; cv = cv->c_slnext) + { + if (cv->c_slperp && gflag) + { + cv->c_slweight = CountCanvasPerp(cv); + for (cv2 = cv->c_slperp; cv2; cv2 = cv2->c_slnext) + if (cv2->c_slperp) + EqualizeCanvas(cv2->c_slperp, gflag); + } + else + cv->c_slweight = 1; + } +} + +void +ResizeCanvas(cv) +struct canvas *cv; +{ + struct canvas *cv2, *cvn, *fcv; + int nh, i, maxi, hh, m, w, wsum; + int need, got; + int xs, ys, xe, ye; + int focusmin = 0; + + xs = cv->c_xs; + ys = cv->c_ys; + xe = cv->c_xe; + ye = cv->c_ye; + cv = cv->c_slperp; + debug2("ResizeCanvas: %d,%d", xs, ys); + debug2(" %d,%d\n", xe, ye); + if (cv == 0) + return; + if (cv->c_slorient == SLICE_UNKN) + { + ASSERT(!cv->c_slnext && !cv->c_slperp); + cv->c_xs = xs; + cv->c_xe = xe; + cv->c_ys = ys; + cv->c_ye = ye; + cv->c_xoff = cv->c_xs; + cv->c_yoff = cv->c_ys; + cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1; + cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; + return; + } + + fcv = 0; + if (focusminwidth || focusminheight) + { + debug("searching for focus canvas\n"); + cv2 = D_forecv; + while (cv2->c_slback) + { + if (cv2->c_slback == cv->c_slback) + { + fcv = cv2; + focusmin = cv->c_slorient == SLICE_VERT ? focusminheight : focusminwidth; + if (focusmin > 0) + focusmin--; + else if (focusmin < 0) + focusmin = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2; + debug1("found, focusmin=%d\n", focusmin); + } + cv2 = cv2->c_slback; + } + } + if (focusmin) + { + m = CountCanvas(cv) * 2; + nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2; + nh -= m; + if (nh < 0) + nh = 0; + if (focusmin > nh) + focusmin = nh; + debug1("corrected to %d\n", focusmin); + } + + /* pass 1: calculate weight sum */ + for (cv2 = cv, wsum = 0; cv2; cv2 = cv2->c_slnext) + { + debug1(" weight %d\n", cv2->c_slweight); + wsum += cv2->c_slweight; + } + debug1("wsum = %d\n", wsum); + if (wsum == 0) + wsum = 1; + w = wsum; + + /* pass 2: calculate need/excess space */ + nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2; + for (cv2 = cv, need = got = 0; cv2; cv2 = cv2->c_slnext) + { + m = cv2->c_slperp ? CountCanvasPerp(cv2) * 2 - 1 : 1; + if (cv2 == fcv) + m += focusmin; + hh = cv2->c_slweight ? nh * cv2->c_slweight / w : 0; + w -= cv2->c_slweight; + nh -= hh; + debug2(" should %d min %d\n", hh, m); + if (hh <= m + 1) + need += m + 1 - hh; + else + got += hh - m - 1; + } + debug2("need: %d, got %d\n", need, got); + if (need > got) + need = got; + + /* pass 3: distribute space */ + nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2; + i = cv->c_slorient == SLICE_VERT ? ys : xs; + maxi = cv->c_slorient == SLICE_VERT ? ye : xe; + w = wsum; + for (; cv; cv = cvn) + { + cvn = cv->c_slnext; + if (i > maxi) + { + if (cv->c_slprev && !cv->c_slback->c_slback && !cv->c_slprev->c_slperp && !cv->c_slprev->c_slprev) + { + cv->c_slprev->c_slorient = SLICE_UNKN; + if (!captionalways) + { + cv->c_slback->c_ye++; + cv->c_slprev->c_ye++; + } + } + SetCanvasWindow(cv, 0); + FreeCanvas(cv); + continue; + } + m = cv->c_slperp ? CountCanvasPerp(cv) * 2 - 1 : 1; + if (cv == fcv) + m += focusmin; + hh = cv->c_slweight ? nh * cv->c_slweight / w : 0; + w -= cv->c_slweight; + nh -= hh; + debug2(" should %d min %d\n", hh, m); + if (hh <= m + 1) + { + hh = m + 1; + debug1(" -> %d\n", hh); + } + else + { + int hx = need * (hh - m - 1) / got; + debug3(" -> %d - %d = %d\n", hh, hx, hh - hx); + got -= (hh - m - 1); + hh -= hx; + need -= hx; + debug2(" now need=%d got=%d\n", need, got); + } + ASSERT(hh >= m + 1); + /* hh is window size plus pation line */ + if (i + hh > maxi + 2) + { + hh = maxi + 2 - i; + debug1(" not enough space, reducing to %d\n", hh); + } + if (i + hh == maxi + 1) + { + hh++; + debug(" incrementing as no other canvas will fit\n"); + } + if (cv->c_slorient == SLICE_VERT) + { + cv->c_xs = xs; + cv->c_xe = xe; + cv->c_ys = i; + cv->c_ye = i + hh - 2; + cv->c_xoff = xs; + cv->c_yoff = i; + } + else + { + cv->c_xs = i; + cv->c_xe = i + hh - 2; + cv->c_ys = ys; + cv->c_ye = ye; + cv->c_xoff = i; + cv->c_yoff = ys; + } + cv->c_xoff = cv->c_xs; + cv->c_yoff = cv->c_ys; + cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1; + cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; + if (cv->c_slperp) + { + ResizeCanvas(cv); + if (!cv->c_slperp->c_slnext) + { + debug("deleting perp node\n"); + FreePerp(cv->c_slperp); + FreePerp(cv); + } + } + i += hh; + } +} + +static struct canvas * +AddPerp(cv) +struct canvas *cv; +{ + struct canvas *pcv; + debug("Creating new perp node\n"); + + if ((pcv = (struct canvas *)calloc(1, sizeof *cv)) == 0) + return 0; + pcv->c_next = 0; + pcv->c_display = cv->c_display; + pcv->c_slnext = cv->c_slnext; + pcv->c_slprev = cv->c_slprev; + pcv->c_slperp = cv; + pcv->c_slback = cv->c_slback; + if (cv->c_slback && cv->c_slback->c_slperp == cv) + cv->c_slback->c_slperp = pcv; + pcv->c_slorient = cv->c_slorient; + pcv->c_xoff = 0; + pcv->c_yoff = 0; + pcv->c_xs = cv->c_xs; + pcv->c_xe = cv->c_xe; + pcv->c_ys = cv->c_ys; + pcv->c_ye = cv->c_ye; + if (pcv->c_slnext) + pcv->c_slnext->c_slprev = pcv; + if (pcv->c_slprev) + pcv->c_slprev->c_slnext = pcv; + pcv->c_slweight = cv->c_slweight; + CanvasInitBlank(pcv); + cv->c_slweight = 1; + cv->c_slnext = 0; + cv->c_slprev = 0; + cv->c_slperp = 0; + cv->c_slback = pcv; + cv->c_slorient = SLICE_UNKN; + return pcv; +} + +int +AddCanvas(orient) +int orient; +{ + struct canvas *cv; + int xs, xe, ys, ye; + int h, num; + + cv = D_forecv; + debug2("AddCanvas orient %d, forecv is %d\n", orient, cv->c_slorient); + + if (cv->c_slorient != SLICE_UNKN && cv->c_slorient != orient) + if (!AddPerp(cv)) + return -1; + + cv = D_forecv; + xs = cv->c_slback->c_xs; + xe = cv->c_slback->c_xe; + ys = cv->c_slback->c_ys; + ye = cv->c_slback->c_ye; + if (!captionalways && cv == D_canvas.c_slperp && !cv->c_slnext) + ye--; /* need space for caption */ + debug2("Adding Canvas to slice %d,%d ", xs, ys); + debug2("%d,%d\n", xe, ye); + + num = CountCanvas(cv->c_slback->c_slperp) + 1; + debug1("Num = %d\n", num); + if (orient == SLICE_VERT) + h = ye - ys + 1; + else + h = xe - xs + 1; + + h -= 2 * num - 1; + if (h < 0) + return -1; /* can't fit in */ + + if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0) + return -1; + + D_forecv->c_slback->c_ye = ye; /* in case we modified it above */ + D_forecv->c_slorient = orient; /* in case it was UNKN */ + cv->c_slnext = D_forecv->c_slnext; + cv->c_slprev = D_forecv; + D_forecv->c_slnext = cv; + if (cv->c_slnext) + cv->c_slnext->c_slprev = cv; + cv->c_slorient = orient; + cv->c_slback = D_forecv->c_slback; + + cv->c_xs = xs; + cv->c_xe = xe; + cv->c_ys = ys; + cv->c_ye = ye; + cv->c_xoff = 0; + cv->c_yoff = 0; + cv->c_display = display; + cv->c_vplist = 0; + cv->c_captev.type = EV_TIMEOUT; + cv->c_captev.data = (char *)cv; + cv->c_captev.handler = cv_winid_fn; + + CanvasInitBlank(cv); + cv->c_lnext = 0; + + cv->c_next = 0; + + cv = cv->c_slback; + EqualizeCanvas(cv->c_slperp, 0); + ResizeCanvas(cv); + RecreateCanvasChain(); + RethinkDisplayViewports(); + ResizeLayersToCanvases(); + return 0; +} + +void +RemCanvas() +{ + int xs, xe, ys, ye; + struct canvas *cv; + + debug("RemCanvas\n"); + cv = D_forecv; + if (cv->c_slorient == SLICE_UNKN) + return; + while (cv->c_slprev) + cv = cv->c_slprev; + if (!cv->c_slnext) + return; + if (!cv->c_slnext->c_slnext && cv->c_slback->c_slback) + { + /* two canvases in slice, kill perp node */ + cv = D_forecv; + debug("deleting perp node\n"); + FreePerp(cv->c_slprev ? cv->c_slprev : cv->c_slnext); + FreePerp(cv->c_slback); + } + xs = cv->c_slback->c_xs; + xe = cv->c_slback->c_xe; + ys = cv->c_slback->c_ys; + ye = cv->c_slback->c_ye; + /* free canvas */ + cv = D_forecv; + D_forecv = cv->c_slprev; + if (!D_forecv) + D_forecv = cv->c_slnext; + FreeCanvas(cv); + + cv = D_forecv; + while (D_forecv->c_slperp) + D_forecv = D_forecv->c_slperp; + + /* if only one canvas left, set orient back to unknown */ + if (!cv->c_slnext && !cv->c_slprev && !cv->c_slback->c_slback && !cv->c_slperp) + { + cv->c_slorient = SLICE_UNKN; + if (!captionalways) + cv->c_slback->c_ye = ++ye; /* caption line no longer needed */ + } + cv = cv->c_slback; + EqualizeCanvas(cv->c_slperp, 0); + ResizeCanvas(cv); + + D_fore = Layer2Window(D_forecv->c_layer); + flayer = D_forecv->c_layer; + + RecreateCanvasChain(); + RethinkDisplayViewports(); + ResizeLayersToCanvases(); +} + +void +OneCanvas() +{ + struct canvas *cv = D_forecv, *ocv = 0; + + if (cv->c_slprev) + { + ocv = cv->c_slprev; + cv->c_slprev->c_slnext = cv->c_slnext; + } + if (cv->c_slnext) + { + ocv = cv->c_slnext; + cv->c_slnext->c_slprev = cv->c_slprev; + } + if (!ocv) + return; + if (cv->c_slback && cv->c_slback->c_slperp == cv) + cv->c_slback->c_slperp = ocv; + cv->c_slorient = SLICE_UNKN; + while (D_canvas.c_slperp) + FreeCanvas(D_canvas.c_slperp); + cv = D_forecv; + D_canvas.c_slperp = cv; + cv->c_slback = &D_canvas; + cv->c_slnext = 0; + cv->c_slprev = 0; + ASSERT(!cv->c_slperp); + if (!captionalways) + D_canvas.c_ye++; /* caption line no longer needed */ + ResizeCanvas(&D_canvas); + RecreateCanvasChain(); + RethinkDisplayViewports(); + ResizeLayersToCanvases(); +} + +void +DupLayoutCv(cvf, cvt, save) +struct canvas *cvf, *cvt; +int save; +{ + while(cvf) + { + cvt->c_slorient = cvf->c_slorient; + cvt->c_slweight = cvf->c_slweight; + if (cvf == D_forecv) + D_forecv = cvt; + if (!save) + { + cvt->c_display = display; + if (!cvf->c_slperp) + { + cvt->c_captev.type = EV_TIMEOUT; + cvt->c_captev.data = (char *)cvt; + cvt->c_captev.handler = cv_winid_fn; + cvt->c_blank.l_cvlist = 0; + cvt->c_blank.l_layfn = &BlankLf; + cvt->c_blank.l_bottom = &cvt->c_blank; + } + cvt->c_layer = cvf->c_layer; + } + else + { + struct win *p = cvf->c_layer ? Layer2Window(cvf->c_layer) : 0; + cvt->c_layer = p ? &p->w_layer : 0; + } + if (cvf->c_slperp) + { + cvt->c_slperp = (struct canvas *)calloc(1, sizeof(struct canvas)); + cvt->c_slperp->c_slback = cvt; + CanvasInitBlank(cvt->c_slperp); + DupLayoutCv(cvf->c_slperp, cvt->c_slperp, save); + } + if (cvf->c_slnext) + { + cvt->c_slnext = (struct canvas *)calloc(1, sizeof(struct canvas)); + cvt->c_slnext->c_slprev = cvt; + cvt->c_slnext->c_slback = cvt->c_slback; + CanvasInitBlank(cvt->c_slnext); + } + cvf = cvf->c_slnext; + cvt = cvt->c_slnext; + } +} + diff --git a/src/canvas.h b/src/canvas.h new file mode 100644 index 0000000..9d454a2 --- /dev/null +++ b/src/canvas.h @@ -0,0 +1,83 @@ +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + * $Id$ FAU + */ + +#ifndef SCREEN_CANVAS_H +#define SCREEN_CANVAS_H + +#define SLICE_UNKN 0 +#define SLICE_VERT (1 << 0) +#define SLICE_HORI (1 << 1) + +#define SLICE_THIS (1 << 2) /* used in equal test */ +#define SLICE_GLOBAL (1 << 3) + +struct canvas +{ + struct canvas *c_next; /* next canvas on display */ + struct display *c_display; /* back pointer to display */ + + struct canvas *c_slnext; /* next canvas in display slice */ + struct canvas *c_slprev; /* prev canvas in display slice */ + struct canvas *c_slperp; /* perpendicular slice */ + struct canvas *c_slback; /* perpendicular slice back pointer */ + int c_slorient; /* our slice orientation */ + int c_slweight; /* size ratio */ + + struct viewport *c_vplist; + struct layer *c_layer; /* layer on this canvas */ + struct canvas *c_lnext; /* next canvas that displays layer */ + struct layer c_blank; /* bottom layer, always blank */ + int c_xoff; /* canvas x offset on display */ + int c_yoff; /* canvas y offset on display */ + int c_xs; + int c_xe; + int c_ys; + int c_ye; + struct event c_captev; /* caption changed event */ +}; + +struct win; /* forward declaration */ + +extern void SetCanvasWindow __P((struct canvas *, struct win *)); +extern void SetForeCanvas __P((struct display *, struct canvas *)); +extern struct canvas *FindCanvas __P((int, int)); +extern int MakeDefaultCanvas __P((void)); +extern int AddCanvas __P((int)); +extern void RemCanvas __P((void)); +extern void OneCanvas __P((void)); +extern void FreeCanvas __P((struct canvas *)); +extern void ResizeCanvas __P((struct canvas *)); +extern void RecreateCanvasChain __P((void)); +extern void RethinkViewportOffsets __P((struct canvas *)); +extern int CountCanvasPerp __P((struct canvas *)); +extern void EqualizeCanvas __P((struct canvas *, int)); +extern void DupLayoutCv __P((struct canvas *, struct canvas *, int)); + +#endif + diff --git a/src/display.c b/src/display.c index d25328d..9f4d5e6 100644 --- a/src/display.c +++ b/src/display.c @@ -37,12 +37,12 @@ #include "screen.h" #include "extern.h" #include "braille.h" +#include "canvas.h" static int CountChars __P((int)); static int DoAddChar __P((int)); static int BlankResize __P((int, int)); static int CallRewrite __P((int, int, int, int)); -static void FreeCanvas __P((struct canvas *)); static void disp_readev_fn __P((struct event *, char *)); static void disp_writeev_fn __P((struct event *, char *)); #ifdef linux @@ -65,8 +65,6 @@ static void RAW_PUTCHAR __P((int)); #ifdef COLOR static void SetBackColor __P((int)); #endif -static void FreePerp __P((struct canvas *)); -static struct canvas *AddPerp __P((struct canvas *)); static void RemoveStatusMinWait __P((void)); @@ -425,628 +423,6 @@ FreeDisplay() display = 0; } -static void -CanvasInitBlank(cv) -struct canvas *cv; -{ - cv->c_blank.l_cvlist = cv; - cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1; - cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; - cv->c_blank.l_x = cv->c_blank.l_y = 0; - cv->c_blank.l_layfn = &BlankLf; - cv->c_blank.l_data = 0; - cv->c_blank.l_next = 0; - cv->c_blank.l_bottom = &cv->c_blank; - cv->c_blank.l_blocking = 0; - cv->c_layer = &cv->c_blank; -} - -int -MakeDefaultCanvas() -{ - struct canvas *cv; - - ASSERT(display); - if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0) - return -1; - cv->c_xs = 0; - cv->c_xe = D_width - 1; - cv->c_ys = 0; - cv->c_ye = D_height - 1 - (D_has_hstatus == HSTATUS_LASTLINE) - captionalways; - debug2("MakeDefaultCanvas 0,0 %d,%d\n", cv->c_xe, cv->c_ye); - cv->c_xoff = 0; - cv->c_yoff = 0; - cv->c_next = 0; - cv->c_display = display; - cv->c_vplist = 0; - cv->c_slnext = 0; - cv->c_slprev = 0; - cv->c_slperp = 0; - cv->c_slweight = 1; - cv->c_slback = &D_canvas; - D_canvas.c_slperp = cv; - D_canvas.c_xs = cv->c_xs; - D_canvas.c_xe = cv->c_xe; - D_canvas.c_ys = cv->c_ys; - D_canvas.c_ye = cv->c_ye; - cv->c_slorient = SLICE_UNKN; - cv->c_captev.type = EV_TIMEOUT; - cv->c_captev.data = (char *)cv; - cv->c_captev.handler = cv_winid_fn; - - CanvasInitBlank(cv); - cv->c_lnext = 0; - - D_cvlist = cv; - RethinkDisplayViewports(); - D_forecv = cv; /* default input focus */ - return 0; -} - -static struct canvas ** -CreateCanvasChainRec(cv, cvp) -struct canvas *cv; -struct canvas **cvp; -{ - for (; cv; cv = cv->c_slnext) - { - if (cv->c_slperp) - cvp = CreateCanvasChainRec(cv->c_slperp, cvp); - else - { - *cvp = cv; - cvp = &cv->c_next; - } - } - return cvp; -} - -void -RecreateCanvasChain() -{ - struct canvas **cvp; - cvp = CreateCanvasChainRec(D_canvas.c_slperp, &D_cvlist); - *cvp = 0; -} - -static void -FreeCanvas(cv) -struct canvas *cv; -{ - struct viewport *vp, *nvp; - struct canvas **cvp; - struct win *p; - - if (cv->c_slprev) - cv->c_slprev->c_slnext = cv->c_slnext; - if (cv->c_slnext) - cv->c_slnext->c_slprev = cv->c_slprev; - if (cv->c_slback && cv->c_slback->c_slperp == cv) - cv->c_slback->c_slperp = cv->c_slnext ? cv->c_slnext : cv->c_slprev; - if (cv->c_slperp) - { - while (cv->c_slperp) - FreeCanvas(cv->c_slperp); - free(cv); - return; - } - - if (display) - { - if (D_forecv == cv) - D_forecv = 0; - /* remove from canvas chain as SetCanvasWindow might call - * some layer function */ - for (cvp = &D_cvlist; *cvp ; cvp = &(*cvp)->c_next) - if (*cvp == cv) - { - *cvp = cv->c_next; - break; - } - } - p = cv->c_layer ? Layer2Window(cv->c_layer) : 0; - SetCanvasWindow(cv, 0); - if (p) - WindowChanged(p, 'u'); - if (flayer == cv->c_layer) - flayer = 0; - for (vp = cv->c_vplist; vp; vp = nvp) - { - vp->v_canvas = 0; - nvp = vp->v_next; - vp->v_next = 0; - free(vp); - } - evdeq(&cv->c_captev); - free(cv); -} - -int -CountCanvas(cv) -struct canvas *cv; -{ - int num = 0; - for (; cv; cv = cv->c_slnext) - { - if (cv->c_slperp) - { - struct canvas *cvp; - int nump = 1, n; - for (cvp = cv->c_slperp; cvp; cvp = cvp->c_slnext) - if (cvp->c_slperp) - { - n = CountCanvas(cvp->c_slperp); - if (n > nump) - nump = n; - } - num += nump; - } - else - num++; - } - return num; -} - -int -CountCanvasPerp(cv) -struct canvas *cv; -{ - struct canvas *cvp; - int num = 1, n; - for (cvp = cv->c_slperp; cvp; cvp = cvp->c_slnext) - if (cvp->c_slperp) - { - n = CountCanvas(cvp->c_slperp); - if (n > num) - num = n; - } - return num; -} - -void -EqualizeCanvas(cv, gflag) -struct canvas *cv; -int gflag; -{ - struct canvas *cv2; - for (; cv; cv = cv->c_slnext) - { - if (cv->c_slperp && gflag) - { - cv->c_slweight = CountCanvasPerp(cv); - for (cv2 = cv->c_slperp; cv2; cv2 = cv2->c_slnext) - if (cv2->c_slperp) - EqualizeCanvas(cv2->c_slperp, gflag); - } - else - cv->c_slweight = 1; - } -} - -void -ResizeCanvas(cv) -struct canvas *cv; -{ - struct canvas *cv2, *cvn, *fcv; - int nh, i, maxi, hh, m, w, wsum; - int need, got; - int xs, ys, xe, ye; - int focusmin = 0; - - xs = cv->c_xs; - ys = cv->c_ys; - xe = cv->c_xe; - ye = cv->c_ye; - cv = cv->c_slperp; - debug2("ResizeCanvas: %d,%d", xs, ys); - debug2(" %d,%d\n", xe, ye); - if (cv == 0) - return; - if (cv->c_slorient == SLICE_UNKN) - { - ASSERT(!cv->c_slnext && !cv->c_slperp); - cv->c_xs = xs; - cv->c_xe = xe; - cv->c_ys = ys; - cv->c_ye = ye; - cv->c_xoff = cv->c_xs; - cv->c_yoff = cv->c_ys; - cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1; - cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; - return; - } - - fcv = 0; - if (focusminwidth || focusminheight) - { - debug("searching for focus canvas\n"); - cv2 = D_forecv; - while (cv2->c_slback) - { - if (cv2->c_slback == cv->c_slback) - { - fcv = cv2; - focusmin = cv->c_slorient == SLICE_VERT ? focusminheight : focusminwidth; - if (focusmin > 0) - focusmin--; - else if (focusmin < 0) - focusmin = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2; - debug1("found, focusmin=%d\n", focusmin); - } - cv2 = cv2->c_slback; - } - } - if (focusmin) - { - m = CountCanvas(cv) * 2; - nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2; - nh -= m; - if (nh < 0) - nh = 0; - if (focusmin > nh) - focusmin = nh; - debug1("corrected to %d\n", focusmin); - } - - /* pass 1: calculate weight sum */ - for (cv2 = cv, wsum = 0; cv2; cv2 = cv2->c_slnext) - { - debug1(" weight %d\n", cv2->c_slweight); - wsum += cv2->c_slweight; - } - debug1("wsum = %d\n", wsum); - if (wsum == 0) - wsum = 1; - w = wsum; - - /* pass 2: calculate need/excess space */ - nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2; - for (cv2 = cv, need = got = 0; cv2; cv2 = cv2->c_slnext) - { - m = cv2->c_slperp ? CountCanvasPerp(cv2) * 2 - 1 : 1; - if (cv2 == fcv) - m += focusmin; - hh = cv2->c_slweight ? nh * cv2->c_slweight / w : 0; - w -= cv2->c_slweight; - nh -= hh; - debug2(" should %d min %d\n", hh, m); - if (hh <= m + 1) - need += m + 1 - hh; - else - got += hh - m - 1; - } - debug2("need: %d, got %d\n", need, got); - if (need > got) - need = got; - - /* pass 3: distribute space */ - nh = cv->c_slorient == SLICE_VERT ? ye - ys + 2 : xe - xs + 2; - i = cv->c_slorient == SLICE_VERT ? ys : xs; - maxi = cv->c_slorient == SLICE_VERT ? ye : xe; - w = wsum; - for (; cv; cv = cvn) - { - cvn = cv->c_slnext; - if (i > maxi) - { - if (cv->c_slprev && !cv->c_slback->c_slback && !cv->c_slprev->c_slperp && !cv->c_slprev->c_slprev) - { - cv->c_slprev->c_slorient = SLICE_UNKN; - if (!captionalways) - { - cv->c_slback->c_ye++; - cv->c_slprev->c_ye++; - } - } - SetCanvasWindow(cv, 0); - FreeCanvas(cv); - continue; - } - m = cv->c_slperp ? CountCanvasPerp(cv) * 2 - 1 : 1; - if (cv == fcv) - m += focusmin; - hh = cv->c_slweight ? nh * cv->c_slweight / w : 0; - w -= cv->c_slweight; - nh -= hh; - debug2(" should %d min %d\n", hh, m); - if (hh <= m + 1) - { - hh = m + 1; - debug1(" -> %d\n", hh); - } - else - { - int hx = need * (hh - m - 1) / got; - debug3(" -> %d - %d = %d\n", hh, hx, hh - hx); - got -= (hh - m - 1); - hh -= hx; - need -= hx; - debug2(" now need=%d got=%d\n", need, got); - } - ASSERT(hh >= m + 1); - /* hh is window size plus pation line */ - if (i + hh > maxi + 2) - { - hh = maxi + 2 - i; - debug1(" not enough space, reducing to %d\n", hh); - } - if (i + hh == maxi + 1) - { - hh++; - debug(" incrementing as no other canvas will fit\n"); - } - if (cv->c_slorient == SLICE_VERT) - { - cv->c_xs = xs; - cv->c_xe = xe; - cv->c_ys = i; - cv->c_ye = i + hh - 2; - cv->c_xoff = xs; - cv->c_yoff = i; - } - else - { - cv->c_xs = i; - cv->c_xe = i + hh - 2; - cv->c_ys = ys; - cv->c_ye = ye; - cv->c_xoff = i; - cv->c_yoff = ys; - } - cv->c_xoff = cv->c_xs; - cv->c_yoff = cv->c_ys; - cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1; - cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; - if (cv->c_slperp) - { - ResizeCanvas(cv); - if (!cv->c_slperp->c_slnext) - { - debug("deleting perp node\n"); - FreePerp(cv->c_slperp); - FreePerp(cv); - } - } - i += hh; - } -} - -static struct canvas * -AddPerp(cv) -struct canvas *cv; -{ - struct canvas *pcv; - debug("Creating new perp node\n"); - - if ((pcv = (struct canvas *)calloc(1, sizeof *cv)) == 0) - return 0; - pcv->c_next = 0; - pcv->c_display = cv->c_display; - pcv->c_slnext = cv->c_slnext; - pcv->c_slprev = cv->c_slprev; - pcv->c_slperp = cv; - pcv->c_slback = cv->c_slback; - if (cv->c_slback && cv->c_slback->c_slperp == cv) - cv->c_slback->c_slperp = pcv; - pcv->c_slorient = cv->c_slorient; - pcv->c_xoff = 0; - pcv->c_yoff = 0; - pcv->c_xs = cv->c_xs; - pcv->c_xe = cv->c_xe; - pcv->c_ys = cv->c_ys; - pcv->c_ye = cv->c_ye; - if (pcv->c_slnext) - pcv->c_slnext->c_slprev = pcv; - if (pcv->c_slprev) - pcv->c_slprev->c_slnext = pcv; - pcv->c_slweight = cv->c_slweight; - CanvasInitBlank(pcv); - cv->c_slweight = 1; - cv->c_slnext = 0; - cv->c_slprev = 0; - cv->c_slperp = 0; - cv->c_slback = pcv; - cv->c_slorient = SLICE_UNKN; - return pcv; -} - -static void -FreePerp(pcv) -struct canvas *pcv; -{ - struct canvas *cv; - - if (!pcv->c_slperp) - return; - cv = pcv->c_slperp; - cv->c_slprev = pcv->c_slprev; - if (cv->c_slprev) - cv->c_slprev->c_slnext = cv; - cv->c_slback = pcv->c_slback; - if (cv->c_slback && cv->c_slback->c_slperp == pcv) - cv->c_slback->c_slperp = cv; - cv->c_slorient = pcv->c_slorient; - cv->c_slweight = pcv->c_slweight; - while (cv->c_slnext) - { - cv = cv->c_slnext; - cv->c_slorient = pcv->c_slorient; - cv->c_slback = pcv->c_slback; - cv->c_slweight = pcv->c_slweight; - } - cv->c_slnext = pcv->c_slnext; - if (cv->c_slnext) - cv->c_slnext->c_slprev = cv; - free(pcv); -} - -int -AddCanvas(orient) -int orient; -{ - struct canvas *cv; - int xs, xe, ys, ye; - int h, num; - - cv = D_forecv; - debug2("AddCanvas orient %d, forecv is %d\n", orient, cv->c_slorient); - - if (cv->c_slorient != SLICE_UNKN && cv->c_slorient != orient) - if (!AddPerp(cv)) - return -1; - - cv = D_forecv; - xs = cv->c_slback->c_xs; - xe = cv->c_slback->c_xe; - ys = cv->c_slback->c_ys; - ye = cv->c_slback->c_ye; - if (!captionalways && cv == D_canvas.c_slperp && !cv->c_slnext) - ye--; /* need space for caption */ - debug2("Adding Canvas to slice %d,%d ", xs, ys); - debug2("%d,%d\n", xe, ye); - - num = CountCanvas(cv->c_slback->c_slperp) + 1; - debug1("Num = %d\n", num); - if (orient == SLICE_VERT) - h = ye - ys + 1; - else - h = xe - xs + 1; - - h -= 2 * num - 1; - if (h < 0) - return -1; /* can't fit in */ - - if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0) - return -1; - - D_forecv->c_slback->c_ye = ye; /* in case we modified it above */ - D_forecv->c_slorient = orient; /* in case it was UNKN */ - cv->c_slnext = D_forecv->c_slnext; - cv->c_slprev = D_forecv; - D_forecv->c_slnext = cv; - if (cv->c_slnext) - cv->c_slnext->c_slprev = cv; - cv->c_slorient = orient; - cv->c_slback = D_forecv->c_slback; - - cv->c_xs = xs; - cv->c_xe = xe; - cv->c_ys = ys; - cv->c_ye = ye; - cv->c_xoff = 0; - cv->c_yoff = 0; - cv->c_display = display; - cv->c_vplist = 0; - cv->c_captev.type = EV_TIMEOUT; - cv->c_captev.data = (char *)cv; - cv->c_captev.handler = cv_winid_fn; - - CanvasInitBlank(cv); - cv->c_lnext = 0; - - cv->c_next = 0; - - cv = cv->c_slback; - EqualizeCanvas(cv->c_slperp, 0); - ResizeCanvas(cv); - RecreateCanvasChain(); - RethinkDisplayViewports(); - ResizeLayersToCanvases(); - return 0; -} - -void -RemCanvas() -{ - int xs, xe, ys, ye; - struct canvas *cv; - - debug("RemCanvas\n"); - cv = D_forecv; - if (cv->c_slorient == SLICE_UNKN) - return; - while (cv->c_slprev) - cv = cv->c_slprev; - if (!cv->c_slnext) - return; - if (!cv->c_slnext->c_slnext && cv->c_slback->c_slback) - { - /* two canvases in slice, kill perp node */ - cv = D_forecv; - debug("deleting perp node\n"); - FreePerp(cv->c_slprev ? cv->c_slprev : cv->c_slnext); - FreePerp(cv->c_slback); - } - xs = cv->c_slback->c_xs; - xe = cv->c_slback->c_xe; - ys = cv->c_slback->c_ys; - ye = cv->c_slback->c_ye; - /* free canvas */ - cv = D_forecv; - D_forecv = cv->c_slprev; - if (!D_forecv) - D_forecv = cv->c_slnext; - FreeCanvas(cv); - - cv = D_forecv; - while (D_forecv->c_slperp) - D_forecv = D_forecv->c_slperp; - - /* if only one canvas left, set orient back to unknown */ - if (!cv->c_slnext && !cv->c_slprev && !cv->c_slback->c_slback && !cv->c_slperp) - { - cv->c_slorient = SLICE_UNKN; - if (!captionalways) - cv->c_slback->c_ye = ++ye; /* caption line no longer needed */ - } - cv = cv->c_slback; - EqualizeCanvas(cv->c_slperp, 0); - ResizeCanvas(cv); - - D_fore = Layer2Window(D_forecv->c_layer); - flayer = D_forecv->c_layer; - - RecreateCanvasChain(); - RethinkDisplayViewports(); - ResizeLayersToCanvases(); -} - -void -OneCanvas() -{ - struct canvas *cv = D_forecv, *ocv = 0; - - if (cv->c_slprev) - { - ocv = cv->c_slprev; - cv->c_slprev->c_slnext = cv->c_slnext; - } - if (cv->c_slnext) - { - ocv = cv->c_slnext; - cv->c_slnext->c_slprev = cv->c_slprev; - } - if (!ocv) - return; - if (cv->c_slback && cv->c_slback->c_slperp == cv) - cv->c_slback->c_slperp = ocv; - cv->c_slorient = SLICE_UNKN; - while (D_canvas.c_slperp) - FreeCanvas(D_canvas.c_slperp); - cv = D_forecv; - D_canvas.c_slperp = cv; - cv->c_slback = &D_canvas; - cv->c_slnext = 0; - cv->c_slprev = 0; - ASSERT(!cv->c_slperp); - if (!captionalways) - D_canvas.c_ye++; /* caption line no longer needed */ - ResizeCanvas(&D_canvas); - RecreateCanvasChain(); - RethinkDisplayViewports(); - ResizeLayersToCanvases(); -} - int RethinkDisplayViewports() { @@ -4199,29 +3575,6 @@ char *data; } } -static void -cv_winid_fn(ev, data) -struct event *ev; -char *data; -{ - int ox, oy; - struct canvas *cv = (struct canvas *)data; - - display = cv->c_display; - if (D_status == STATUS_ON_WIN) - { - SetTimeout(ev, 1); - evenq(ev); - return; - } - ox = D_x; - oy = D_y; - if (cv->c_ye + 1 < D_height) - RefreshLine(cv->c_ye + 1, 0, D_width - 1, 0); - if (ox != -1 && oy != -1) - GotoPos(ox, oy); -} - #ifdef MAPKEYS static void disp_map_fn(ev, data) @@ -4482,55 +3835,6 @@ struct canvas *cv; } } -static void -DupLayoutCv(cvf, cvt, save) -struct canvas *cvf, *cvt; -int save; -{ - while(cvf) - { - cvt->c_slorient = cvf->c_slorient; - cvt->c_slweight = cvf->c_slweight; - if (cvf == D_forecv) - D_forecv = cvt; - if (!save) - { - cvt->c_display = display; - if (!cvf->c_slperp) - { - cvt->c_captev.type = EV_TIMEOUT; - cvt->c_captev.data = (char *)cvt; - cvt->c_captev.handler = cv_winid_fn; - cvt->c_blank.l_cvlist = 0; - cvt->c_blank.l_layfn = &BlankLf; - cvt->c_blank.l_bottom = &cvt->c_blank; - } - cvt->c_layer = cvf->c_layer; - } - else - { - struct win *p = cvf->c_layer ? Layer2Window(cvf->c_layer) : 0; - cvt->c_layer = p ? &p->w_layer : 0; - } - if (cvf->c_slperp) - { - cvt->c_slperp = (struct canvas *)calloc(1, sizeof(struct canvas)); - cvt->c_slperp->c_slback = cvt; - CanvasInitBlank(cvt->c_slperp); - DupLayoutCv(cvf->c_slperp, cvt->c_slperp, save); - } - if (cvf->c_slnext) - { - cvt->c_slnext = (struct canvas *)calloc(1, sizeof(struct canvas)); - cvt->c_slnext->c_slprev = cvt; - cvt->c_slnext->c_slback = cvt->c_slback; - CanvasInitBlank(cvt->c_slnext); - } - cvf = cvf->c_slnext; - cvt = cvt->c_slnext; - } -} - void PutWindowCv(cv) struct canvas *cv; diff --git a/src/display.h b/src/display.h index 7ae32e8..f67a7b2 100644 --- a/src/display.h +++ b/src/display.h @@ -53,38 +53,6 @@ struct win; /* forward declaration */ #define MAXLAY 10 -#define SLICE_UNKN 0 -#define SLICE_VERT (1 << 0) -#define SLICE_HORI (1 << 1) - -#define SLICE_THIS (1 << 2) /* used in equal test */ -#define SLICE_GLOBAL (1 << 3) - -struct canvas -{ - struct canvas *c_next; /* next canvas on display */ - struct display *c_display; /* back pointer to display */ - - struct canvas *c_slnext; /* next canvas in display slice */ - struct canvas *c_slprev; /* prev canvas in display slice */ - struct canvas *c_slperp; /* perpendicular slice */ - struct canvas *c_slback; /* perpendicular slice back pointer */ - int c_slorient; /* our slice orientation */ - int c_slweight; /* size ratio */ - - struct viewport *c_vplist; - struct layer *c_layer; /* layer on this canvas */ - struct canvas *c_lnext; /* next canvas that displays layer */ - struct layer c_blank; /* bottom layer, always blank */ - int c_xoff; /* canvas x offset on display */ - int c_yoff; /* canvas y offset on display */ - int c_xs; - int c_xe; - int c_ys; - int c_ye; - struct event c_captev; /* caption changed event */ -}; - struct layout { struct layout *lay_next; diff --git a/src/extern.h b/src/extern.h index 2607859..d4babed 100644 --- a/src/extern.h +++ b/src/extern.h @@ -297,19 +297,7 @@ extern void Resize_obuf __P((void)); #ifdef AUTO_NUKE extern void NukePending __P((void)); #endif -extern void SetCanvasWindow __P((struct canvas *, struct win *)); -extern void SetForeCanvas __P((struct display *, struct canvas *)); -extern struct canvas *FindCanvas __P((int, int)); -extern int MakeDefaultCanvas __P((void)); -extern int AddCanvas __P((int)); -extern void RemCanvas __P((void)); -extern void OneCanvas __P((void)); -extern void ResizeCanvas __P((struct canvas *)); -extern void RecreateCanvasChain __P((void)); extern int RethinkDisplayViewports __P((void)); -extern void RethinkViewportOffsets __P((struct canvas *)); -extern int CountCanvasPerp __P((struct canvas *)); -extern void EqualizeCanvas __P((struct canvas *, int)); #ifdef RXVT_OSC extern void ClearAllXtermOSC __P((void)); extern void SetXtermOSC __P((int, char *)); diff --git a/src/process.c b/src/process.c index 8136fd5..fda3a8e 100644 --- a/src/process.c +++ b/src/process.c @@ -49,6 +49,7 @@ #include "screen.h" #include "extern.h" #include "logfile.h" +#include "canvas.h" extern struct comm comms[]; extern char *rc_name; @@ -5006,118 +5007,6 @@ int n; Activate(fore->w_norefresh); } - -void -SetCanvasWindow(cv, wi) -struct canvas *cv; -struct win *wi; -{ - struct win *p = 0, **pp; - struct layer *l; - struct canvas *cvp, **cvpp; - - l = cv->c_layer; - display = cv->c_display; - - if (l) - { - /* remove old layer */ - for (cvpp = &l->l_cvlist; (cvp = *cvpp); cvpp = &cvp->c_lnext) - if (cvp == cv) - break; - ASSERT(cvp); - *cvpp = cvp->c_lnext; - - p = Layer2Window(l); - l = cv->c_layer; - cv->c_layer = 0; - - if (p && cv == D_forecv) - { -#ifdef MULTIUSER - ReleaseAutoWritelock(display, p); -#endif - if (p->w_silence) - { - SetTimeout(&p->w_silenceev, p->w_silencewait * 1000); - evenq(&p->w_silenceev); - } - D_other = fore; - D_fore = 0; - } - if (l->l_cvlist == 0 && (p == 0 || l != p->w_savelayer)) - KillLayerChain(l); - } - - /* find right layer to display on canvas */ - if (wi && wi->w_type != W_TYPE_GROUP) - { - l = &wi->w_layer; - if (wi->w_savelayer && (wi->w_blocked || wi->w_savelayer->l_cvlist == 0)) - l = wi->w_savelayer; - } - else - { - l = &cv->c_blank; - if (wi) - l->l_data = (char *)wi; - else - l->l_data = 0; - } - - /* add our canvas to the layer's canvaslist */ - ASSERT(l->l_cvlist != cv); - cv->c_lnext = l->l_cvlist; - l->l_cvlist = cv; - cv->c_layer = l; - cv->c_xoff = cv->c_xs; - cv->c_yoff = cv->c_ys; - RethinkViewportOffsets(cv); - - if (flayer == 0) - flayer = l; - - if (wi && wi->w_type == W_TYPE_GROUP) - { - /* auto-start windowlist on groups */ - struct display *d = display; - struct layer *oldflayer = flayer; - flayer = l; - display_wlist(0, 0, wi); - flayer = oldflayer; - display = d; - } - - if (wi && D_other == wi) - D_other = wi->w_next; /* Might be 0, but that's OK. */ - if (cv == D_forecv) - { - D_fore = wi; - fore = D_fore; /* XXX ? */ - if (wi) - { -#ifdef MULTIUSER - ObtainAutoWritelock(display, wi); -#endif - /* - * Place the window at the head of the most-recently-used list - */ - if (windows != wi) - { - for (pp = &windows; (p = *pp); pp = &p->w_next) - if (p == wi) - break; - ASSERT(p); - *pp = p->w_next; - p->w_next = windows; - windows = p; - WListLinkChanged(); - } - } - } -} - - /* * SetForeWindow changes the window in the input focus of the display. * Puts window wi in canvas display->d_forecv. @@ -6780,56 +6669,6 @@ int percent; return done; } -struct canvas * -FindCanvas(x, y) -int x, y; -{ - struct canvas *cv, *mcv = 0; - int m, mm = 0; - - for (cv = D_cvlist; cv; cv = cv->c_next) - { - /* ye + 1 because of caption line */ - if (x >= cv->c_xs && x <= cv->c_xe && y >= cv->c_ys && y <= cv->c_ye + 1) - return cv; - if (cv == D_forecv) - continue; - m = 0; - if (x >= D_forecv->c_xs && x <= D_forecv->c_xe) - { - if (x < cv->c_xs || x > cv->c_xe) - continue; - if (y < D_forecv->c_ys && y < cv->c_ys) - continue; - if (y > D_forecv->c_ye + 1 && y > cv->c_ye + 1) - continue; - if (y < cv->c_ys) - m = cv->c_ys - y; - if (y > cv->c_ye + 1) - m = y - (cv->c_ye + 1); - } - if (y >= D_forecv->c_ys && y <= D_forecv->c_ye + 1) - { - if (y < cv->c_ys || y > cv->c_ye + 1) - continue; - if (x < D_forecv->c_xs && x < cv->c_xs) - continue; - if (x > D_forecv->c_xe && x > cv->c_xe) - continue; - if (x < cv->c_xs) - m = cv->c_xs - x; - if (x > cv->c_xe) - m = x - cv->c_xe; - } - if (m && (!mm || m < mm)) - { - mcv = cv; - mm = m; - } - } - return mcv ? mcv : D_forecv; -} - static void ResizeRegions(arg, flags) char *arg; diff --git a/src/screen.h b/src/screen.h index d80f0d5..d996def 100644 --- a/src/screen.h +++ b/src/screen.h @@ -146,6 +146,7 @@ struct mode /* #include "logfile.h" */ /* (requires stat.h) struct logfile */ #include "image.h" +#include "canvas.h" #include "display.h" #include "window.h" -- cgit v1.2.1 From 36983385404db06b71744d9d42fbdd6d1c105bc2 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 12 Nov 2009 14:24:12 -0500 Subject: Refactor 'layout' and 'viewport' --- src/Makefile.in | 76 ++++++----- src/canvas.c | 18 +++ src/canvas.h | 20 ++- src/display.c | 389 +------------------------------------------------------- src/display.h | 52 ++------ src/extern.h | 7 - src/layout.c | 334 ++++++++++++++++++++++++++++++++++++++++++++++++ src/layout.h | 57 +++++++++ src/process.c | 33 +---- src/viewport.c | 140 ++++++++++++++++++++ src/viewport.h | 51 ++++++++ 11 files changed, 673 insertions(+), 504 deletions(-) create mode 100644 src/layout.c create mode 100644 src/layout.h create mode 100644 src/viewport.c create mode 100644 src/viewport.h diff --git a/src/Makefile.in b/src/Makefile.in index 28938b0..903aae3 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -61,12 +61,12 @@ CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \ search.c tty.c term.c window.c utmp.c loadav.c putenv.c help.c \ termcap.c input.c attacher.c pty.c process.c display.c comm.c \ kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \ - sched.c teln.c nethack.c encoding.c canvas.c + sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ termcap.o input.o attacher.o pty.o process.o display.o comm.o \ kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \ - sched.o teln.o nethack.o encoding.o canvas.o + sched.o teln.o nethack.o encoding.o canvas.o layout.o viewport.o all: screen @@ -273,69 +273,75 @@ depend.in: $(CFILES) term.h ############################################################################### ### Dependencies: -screen.o: canvas.h screen.c config.h screen.h os.h osdef.h ansi.h acls.h \ +screen.o: layout.h viewport.h canvas.h screen.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h braille.h \ patchlevel.h logfile.h extern.h -ansi.o: canvas.h ansi.c config.h screen.h os.h osdef.h ansi.h acls.h \ +ansi.o: layout.h viewport.h canvas.h ansi.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h braille.h extern.h \ logfile.h -fileio.o: canvas.h fileio.c config.h screen.h os.h osdef.h ansi.h acls.h \ +fileio.o: layout.h viewport.h canvas.h fileio.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -mark.o: canvas.h mark.c config.h screen.h os.h osdef.h ansi.h acls.h \ +mark.o: layout.h viewport.h canvas.h mark.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h mark.h extern.h -misc.o: canvas.h misc.c config.h screen.h os.h osdef.h ansi.h acls.h \ +misc.o: layout.h viewport.h canvas.h misc.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -resize.o: canvas.h resize.c config.h screen.h os.h osdef.h ansi.h acls.h \ +resize.o: layout.h viewport.h canvas.h resize.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -socket.o: canvas.h socket.c config.h screen.h os.h osdef.h ansi.h acls.h \ +socket.o: layout.h viewport.h canvas.h socket.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -search.o: canvas.h search.c config.h screen.h os.h osdef.h ansi.h acls.h \ +search.o: layout.h viewport.h canvas.h search.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h mark.h extern.h -tty.o: canvas.h tty.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ +tty.o: layout.h viewport.h canvas.h tty.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ layer.h term.h image.h display.h window.h extern.h -term.o: canvas.h term.c term.h -window.o: canvas.h window.c config.h screen.h os.h osdef.h ansi.h acls.h \ +term.o: layout.h viewport.h canvas.h term.c term.h +window.o: layout.h viewport.h canvas.h window.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h -utmp.o: canvas.h utmp.c config.h screen.h os.h osdef.h ansi.h acls.h \ +utmp.o: layout.h viewport.h canvas.h utmp.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -loadav.o: canvas.h loadav.c config.h screen.h os.h osdef.h ansi.h acls.h \ +loadav.o: layout.h viewport.h canvas.h loadav.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -putenv.o: canvas.h putenv.c config.h -help.o: canvas.h help.c config.h screen.h os.h osdef.h ansi.h acls.h \ +putenv.o: layout.h viewport.h canvas.h putenv.c config.h +help.o: layout.h viewport.h canvas.h help.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -termcap.o: canvas.h termcap.c config.h screen.h os.h osdef.h ansi.h acls.h \ +termcap.o: layout.h viewport.h canvas.h termcap.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -input.o: canvas.h input.c config.h screen.h os.h osdef.h ansi.h acls.h \ +input.o: layout.h viewport.h canvas.h input.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -attacher.o: canvas.h attacher.c config.h screen.h os.h osdef.h ansi.h \ +attacher.o: layout.h viewport.h canvas.h attacher.c config.h screen.h os.h osdef.h ansi.h \ acls.h comm.h layer.h term.h image.h display.h window.h extern.h -pty.o: canvas.h pty.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ +pty.o: layout.h viewport.h canvas.h pty.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ layer.h term.h image.h display.h window.h extern.h -process.o: canvas.h process.c config.h screen.h os.h osdef.h ansi.h acls.h \ +process.o: layout.h viewport.h canvas.h process.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h -display.o: canvas.h display.c config.h screen.h os.h osdef.h ansi.h acls.h \ +display.o: layout.h viewport.h canvas.h display.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h braille.h -canvas.o: canvas.h canvas.c config.h screen.h os.h osdef.h ansi.h acls.h \ +canvas.o: layout.h viewport.h canvas.h canvas.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h \ braille.h -comm.o: canvas.h comm.c config.h acls.h comm.h -kmapdef.o: canvas.h kmapdef.c config.h -acls.o: canvas.h acls.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ +comm.o: layout.h viewport.h canvas.h comm.c config.h acls.h comm.h +kmapdef.o: layout.h viewport.h canvas.h kmapdef.c config.h +acls.o: layout.h viewport.h canvas.h acls.c config.h screen.h os.h osdef.h ansi.h acls.h comm.h \ layer.h term.h image.h display.h window.h extern.h -braille.o: canvas.h braille.c config.h screen.h os.h osdef.h ansi.h acls.h \ +braille.o: layout.h viewport.h canvas.h braille.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h braille.h -braille_tsi.o: canvas.h braille_tsi.c config.h screen.h os.h osdef.h ansi.h \ +braille_tsi.o: layout.h viewport.h canvas.h braille_tsi.c config.h screen.h os.h osdef.h ansi.h \ acls.h comm.h layer.h term.h image.h display.h window.h extern.h \ braille.h -logfile.o: canvas.h logfile.c config.h screen.h os.h osdef.h ansi.h acls.h \ +logfile.o: layout.h viewport.h canvas.h logfile.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h -layer.o: canvas.h layer.c config.h screen.h os.h osdef.h ansi.h acls.h \ +layer.o: layout.h viewport.h canvas.h layer.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -sched.o: canvas.h sched.c config.h screen.h os.h osdef.h ansi.h acls.h \ +sched.o: layout.h viewport.h canvas.h sched.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h -teln.o: canvas.h teln.c config.h screen.h os.h osdef.h ansi.h acls.h \ +teln.o: layout.h viewport.h canvas.h teln.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -nethack.o: canvas.h nethack.c config.h screen.h os.h osdef.h ansi.h acls.h \ +nethack.o: layout.h viewport.h canvas.h nethack.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h -encoding.o: canvas.h encoding.c config.h screen.h os.h osdef.h ansi.h acls.h \ +encoding.o: layout.h viewport.h canvas.h encoding.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h +layout.o: layout.h viewport.h canvas.h layout.c config.h screen.h os.h osdef.h ansi.h acls.h \ + comm.h layer.h term.h image.h display.h window.h extern.h \ + braille.h +viewport.o: layout.h viewport.h canvas.h viewport.c config.h screen.h os.h osdef.h ansi.h acls.h \ + comm.h layer.h term.h image.h display.h window.h extern.h \ + braille.h diff --git a/src/canvas.c b/src/canvas.c index 50752f0..a6c15ab 100644 --- a/src/canvas.c +++ b/src/canvas.c @@ -892,3 +892,21 @@ int save; } } +void +PutWindowCv(cv) +struct canvas *cv; +{ + struct win *p; + for (; cv; cv = cv->c_slnext) + { + if (cv->c_slperp) + { + PutWindowCv(cv->c_slperp); + continue; + } + p = cv->c_layer ? (struct win *)cv->c_layer->l_data : 0; + cv->c_layer = 0; + SetCanvasWindow(cv, p); + } +} + diff --git a/src/canvas.h b/src/canvas.h index 9d454a2..265545e 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -78,6 +78,24 @@ extern void RethinkViewportOffsets __P((struct canvas *)); extern int CountCanvasPerp __P((struct canvas *)); extern void EqualizeCanvas __P((struct canvas *, int)); extern void DupLayoutCv __P((struct canvas *, struct canvas *, int)); +extern void PutWindowCv __P((struct canvas *)); -#endif +#define CV_CALL(cv, cmd) \ +{ \ + struct display *olddisplay = display; \ + struct layer *oldflayer = flayer; \ + struct layer *l = cv->c_layer; \ + struct canvas *cvlist = l->l_cvlist; \ + struct canvas *cvlnext = cv->c_lnext; \ + flayer = l; \ + l->l_cvlist = cv; \ + cv->c_lnext = 0; \ + cmd; \ + flayer = oldflayer; \ + l->l_cvlist = cvlist; \ + cv->c_lnext = cvlnext; \ + display = olddisplay; \ +} + +#endif /* SCREEN_CANVAS_H */ diff --git a/src/display.c b/src/display.c index 9f4d5e6..87363ab 100644 --- a/src/display.c +++ b/src/display.c @@ -423,110 +423,6 @@ FreeDisplay() display = 0; } -int -RethinkDisplayViewports() -{ - struct canvas *cv; - struct viewport *vp, *vpn; - - /* free old viewports */ - for (cv = display->d_cvlist; cv; cv = cv->c_next) - { - for (vp = cv->c_vplist; vp; vp = vpn) - { - vp->v_canvas = 0; - vpn = vp->v_next; - bzero((char *)vp, sizeof(*vp)); - free(vp); - } - cv->c_vplist = 0; - } - display->d_vpxmin = -1; - display->d_vpxmax = -1; - - for (cv = display->d_cvlist; cv; cv = cv->c_next) - { - if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0) - return -1; -#ifdef HOLE - vp->v_canvas = cv; - vp->v_xs = cv->c_xs; - vp->v_ys = (cv->c_ys + cv->c_ye) / 2; - vp->v_xe = cv->c_xe; - vp->v_ye = cv->c_ye; - vp->v_xoff = cv->c_xoff; - vp->v_yoff = cv->c_yoff; - vp->v_next = cv->c_vplist; - cv->c_vplist = vp; - - if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0) - return -1; - vp->v_canvas = cv; - vp->v_xs = (cv->c_xs + cv->c_xe) / 2; - vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4; - vp->v_xe = cv->c_xe; - vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1; - vp->v_xoff = cv->c_xoff; - vp->v_yoff = cv->c_yoff; - vp->v_next = cv->c_vplist; - cv->c_vplist = vp; - - if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0) - return -1; - vp->v_canvas = cv; - vp->v_xs = cv->c_xs; - vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4; - vp->v_xe = (3 * cv->c_xs + cv->c_xe) / 4 - 1; - vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1; - vp->v_xoff = cv->c_xoff; - vp->v_yoff = cv->c_yoff; - vp->v_next = cv->c_vplist; - cv->c_vplist = vp; - - if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0) - return -1; - vp->v_canvas = cv; - vp->v_xs = cv->c_xs; - vp->v_ys = cv->c_ys; - vp->v_xe = cv->c_xe; - vp->v_ye = (3 * cv->c_ys + cv->c_ye) / 4 - 1; - vp->v_xoff = cv->c_xoff; - vp->v_yoff = cv->c_yoff; - vp->v_next = cv->c_vplist; - cv->c_vplist = vp; -#else - vp->v_canvas = cv; - vp->v_xs = cv->c_xs; - vp->v_ys = cv->c_ys; - vp->v_xe = cv->c_xe; - vp->v_ye = cv->c_ye; - vp->v_xoff = cv->c_xoff; - vp->v_yoff = cv->c_yoff; - vp->v_next = cv->c_vplist; - cv->c_vplist = vp; -#endif - - if (cv->c_xs < display->d_vpxmin || display->d_vpxmin == -1) - display->d_vpxmin = cv->c_xs; - if (cv->c_xe > display->d_vpxmax || display->d_vpxmax == -1) - display->d_vpxmax = cv->c_xe; - } - return 0; -} - -void -RethinkViewportOffsets(cv) -struct canvas *cv; -{ - struct viewport *vp; - - for (vp = cv->c_vplist; vp; vp = vp->v_next) - { - vp->v_xoff = cv->c_xoff; - vp->v_yoff = cv->c_yoff; - } -} - /* * if the adaptflag is on, we keep the size of this display, else * we may try to restore our old window sizes. @@ -3808,289 +3704,6 @@ char **cmdv; ClearAll(); } -#endif - -struct layout *layouts; -struct layout *laytab[MAXLAY]; -struct layout *layout_last, layout_last_marker; -struct layout *layout_attach = &layout_last_marker; - -void -FreeLayoutCv(cv) -struct canvas *cv; -{ - struct canvas *cnext, *c = cv; - for (; cv; cv = cnext) - { - if (cv->c_slperp) - { - FreeLayoutCv(cv->c_slperp); - free(cv->c_slperp); - cv->c_slperp = 0; - } - cnext = cv->c_slnext; - cv->c_slnext = 0; - if (cv != c) - free(cv); - } -} - -void -PutWindowCv(cv) -struct canvas *cv; -{ - struct win *p; - for (; cv; cv = cv->c_slnext) - { - if (cv->c_slperp) - { - PutWindowCv(cv->c_slperp); - continue; - } - p = cv->c_layer ? (struct win *)cv->c_layer->l_data : 0; - cv->c_layer = 0; - SetCanvasWindow(cv, p); - } -} - -struct layout * -CreateLayout(title, startat) -char *title; -int startat; -{ - struct layout *lay; - int i; - - if (startat >= MAXLAY || startat < 0) - startat = 0; - for (i = startat; ;) - { - if (!laytab[i]) - break; - if (++i == MAXLAY) - i = 0; - if (i == startat) - { - Msg(0, "No more layouts\n"); - return 0; - } - } - lay = (struct layout *)calloc(1, sizeof(*lay)); - lay->lay_title = SaveStr(title); - lay->lay_autosave = 1; - lay->lay_number = i; - laytab[i] = lay; - lay->lay_next = layouts; - layouts = lay; - return lay; -} - -void -SaveLayout(name, cv) -char *name; -struct canvas *cv; -{ - struct layout *lay; - struct canvas *fcv; - for (lay = layouts; lay; lay = lay->lay_next) - if (!strcmp(lay->lay_title, name)) - break; - if (lay) - FreeLayoutCv(&lay->lay_canvas); - else - lay = CreateLayout(name, 0); - if (!lay) - return; - fcv = D_forecv; - DupLayoutCv(cv, &lay->lay_canvas, 1); - lay->lay_forecv = D_forecv; - D_forecv = fcv; - D_layout = lay; -} - -void -AutosaveLayout(lay) -struct layout *lay; -{ - struct canvas *fcv; - if (!lay || !lay->lay_autosave) - return; - FreeLayoutCv(&lay->lay_canvas); - fcv = D_forecv; - DupLayoutCv(&D_canvas, &lay->lay_canvas, 1); - lay->lay_forecv = D_forecv; - D_forecv = fcv; -} - -struct layout * -FindLayout(name) -char *name; -{ - struct layout *lay; - char *s; - int i; - for (i = 0, s = name; *s >= '0' && *s <= '9'; s++) - i = i * 10 + (*s - '0'); - if (!*s && s != name && i >= 0 && i < MAXLAY) - return laytab[i]; - for (lay = layouts; lay; lay = lay->lay_next) - if (!strcmp(lay->lay_title, name)) - break; - return lay; -} - -void -LoadLayout(lay, cv) -struct layout *lay; -struct canvas *cv; -{ - AutosaveLayout(D_layout); - if (!lay) - { - while (D_canvas.c_slperp) - FreeCanvas(D_canvas.c_slperp); - MakeDefaultCanvas(); - SetCanvasWindow(D_forecv, 0); - D_layout = 0; - return; - } - while (D_canvas.c_slperp) - FreeCanvas(D_canvas.c_slperp); - D_cvlist = 0; - D_forecv = lay->lay_forecv; - DupLayoutCv(&lay->lay_canvas, &D_canvas, 0); - D_canvas.c_ye = D_height - 1 - ((D_canvas.c_slperp && D_canvas.c_slperp->c_slnext) || captionalways) - (D_has_hstatus == HSTATUS_LASTLINE); - ResizeCanvas(&D_canvas); - RecreateCanvasChain(); - RethinkDisplayViewports(); - PutWindowCv(&D_canvas); - ResizeLayersToCanvases(); - D_layout = lay; -} - -void -NewLayout(title, startat) -char *title; -int startat; -{ - struct layout *lay; - struct canvas *fcv; - - lay = CreateLayout(title, startat); - if (!lay) - return; - LoadLayout(0, &D_canvas); - fcv = D_forecv; - DupLayoutCv(&D_canvas, &lay->lay_canvas, 1); - lay->lay_forecv = D_forecv; - D_forecv = fcv; - D_layout = lay; - lay->lay_autosave = 1; -} - -static char * -AddLayoutsInfo(buf, len, where) -char *buf; -int len; -int where; -{ - char *s, *ss, *t; - struct layout *p, **pp; - int l; - - s = ss = buf; - for (pp = laytab; pp < laytab + MAXLAY; pp++) - { - if (pp - laytab == where && ss == buf) - ss = s; - if ((p = *pp) == 0) - continue; - t = p->lay_title; - l = strlen(t); - if (l > 20) - l = 20; - if (s - buf + l > len - 24) - break; - if (s > buf) - { - *s++ = ' '; - *s++ = ' '; - } - sprintf(s, "%d", p->lay_number); - if (p->lay_number == where) - ss = s; - s += strlen(s); - if (display && p == D_layout) - *s++ = '*'; - *s++ = ' '; - strncpy(s, t, l); - s += l; - } - *s = 0; - return ss; -} - -void -ShowLayouts(where) -int where; -{ - char buf[1024]; - char *s, *ss; +#endif /* BLANKER_PRG */ - if (!display) - return; - if (!layouts) - { - Msg(0, "No layouts defined\n"); - return; - } - if (where == -1 && D_layout) - where = D_layout->lay_number; - ss = AddLayoutsInfo(buf, sizeof(buf), where); - s = buf + strlen(buf); - if (ss - buf > D_width / 2) - { - ss -= D_width / 2; - if (s - ss < D_width) - { - ss = s - D_width; - if (ss < buf) - ss = buf; - } - } - else - ss = buf; - Msg(0, "%s", ss); -} - -void -RemoveLayout(lay) -struct layout *lay; -{ - struct layout **layp = &layouts; - - for (; *layp; layp = &(*layp)->lay_next) - { - if (*layp == lay) - { - *layp = lay->lay_next; - break; - } - } - laytab[lay->lay_number] = (struct layout *)0; - - if (display && D_layout == lay) - D_layout = (struct layout *)0; - - FreeLayoutCv(&lay->lay_canvas); - - if (lay->lay_title) - free(lay->lay_title); - free(lay); - - if (layouts) - LoadLayout((display && D_layout) ? D_layout : *layp ? *layp : layouts, - display ? &D_canvas : (struct canvas *)0); - Activate(0); -} diff --git a/src/display.h b/src/display.h index f67a7b2..e3d5ad7 100644 --- a/src/display.h +++ b/src/display.h @@ -27,6 +27,13 @@ * $Id$ FAU */ +#ifndef SCREEN_DISPLAY_H +#define SCREEN_DISPLAY_H + +#include "layout.h" +#include "canvas.h" +#include "viewport.h" + #ifdef MAPKEYS #define KMAP_KEYS (T_OCAPS-T_CAPS) @@ -51,31 +58,6 @@ struct kmap_ext struct win; /* forward declaration */ -#define MAXLAY 10 - -struct layout -{ - struct layout *lay_next; - char *lay_title; - int lay_number; - struct canvas lay_canvas; - struct canvas *lay_forecv; - struct canvas *lay_cvlist; - int lay_autosave; -}; - -struct viewport -{ - struct viewport *v_next; /* next vp on canvas */ - struct canvas *v_canvas; /* back pointer to canvas */ - int v_xoff; /* layer x offset on display */ - int v_yoff; /* layer y offset on display */ - int v_xs; /* vp upper left */ - int v_xe; /* vp upper right */ - int v_ys; /* vp lower left */ - int v_ye; /* vp lower right */ -}; - struct display { struct display *d_next; /* linked list */ @@ -330,23 +312,6 @@ do \ } \ while (0) -#define CV_CALL(cv, cmd) \ -{ \ - struct display *olddisplay = display; \ - struct layer *oldflayer = flayer; \ - struct layer *l = cv->c_layer; \ - struct canvas *cvlist = l->l_cvlist; \ - struct canvas *cvlnext = cv->c_lnext; \ - flayer = l; \ - l->l_cvlist = cv; \ - cv->c_lnext = 0; \ - cmd; \ - flayer = oldflayer; \ - l->l_cvlist = cvlist; \ - cv->c_lnext = cvlnext; \ - display = olddisplay; \ -} - #define STATUS_OFF 0 #define STATUS_ON_WIN 1 #define STATUS_ON_HS 2 @@ -356,3 +321,6 @@ while (0) #define HSTATUS_MESSAGE 2 #define HSTATUS_HS 3 #define HSTATUS_ALWAYS (1<<2) + +#endif /* SCREEN_DISPLAY_H */ + diff --git a/src/extern.h b/src/extern.h index d4babed..28eb105 100644 --- a/src/extern.h +++ b/src/extern.h @@ -297,7 +297,6 @@ extern void Resize_obuf __P((void)); #ifdef AUTO_NUKE extern void NukePending __P((void)); #endif -extern int RethinkDisplayViewports __P((void)); #ifdef RXVT_OSC extern void ClearAllXtermOSC __P((void)); extern void SetXtermOSC __P((int, char *)); @@ -311,12 +310,6 @@ extern int color256to88 __P((int)); extern void ResetIdle __P((void)); extern void KillBlanker __P((void)); extern void DisplaySleep1000 __P((int, int)); -extern void AutosaveLayout __P((struct layout *)); -extern void LoadLayout __P((struct layout *, struct canvas *)); -extern void NewLayout __P((char *, int)); -extern void SaveLayout __P((char *, struct canvas *)); -extern void ShowLayouts __P((int)); -extern struct layout *FindLayout __P((char *)); /* resize.c */ extern int ChangeWindowSize __P((struct win *, int, int, int)); diff --git a/src/layout.c b/src/layout.c new file mode 100644 index 0000000..2aed7d0 --- /dev/null +++ b/src/layout.c @@ -0,0 +1,334 @@ +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +#include "config.h" +#include "screen.h" +#include "extern.h" +#include "layout.h" + +extern struct display *display; +extern int captionalways; + +struct layout *layouts; +struct layout *laytab[MAXLAY]; +struct layout *layout_last, layout_last_marker; +struct layout *layout_attach = &layout_last_marker; + +void +FreeLayoutCv(cv) +struct canvas *cv; +{ + struct canvas *cnext, *c = cv; + for (; cv; cv = cnext) + { + if (cv->c_slperp) + { + FreeLayoutCv(cv->c_slperp); + free(cv->c_slperp); + cv->c_slperp = 0; + } + cnext = cv->c_slnext; + cv->c_slnext = 0; + if (cv != c) + free(cv); + } +} + +struct layout * +CreateLayout(title, startat) +char *title; +int startat; +{ + struct layout *lay; + int i; + + if (startat >= MAXLAY || startat < 0) + startat = 0; + for (i = startat; ;) + { + if (!laytab[i]) + break; + if (++i == MAXLAY) + i = 0; + if (i == startat) + { + Msg(0, "No more layouts\n"); + return 0; + } + } + lay = (struct layout *)calloc(1, sizeof(*lay)); + lay->lay_title = SaveStr(title); + lay->lay_autosave = 1; + lay->lay_number = i; + laytab[i] = lay; + lay->lay_next = layouts; + layouts = lay; + return lay; +} + +void +SaveLayout(name, cv) +char *name; +struct canvas *cv; +{ + struct layout *lay; + struct canvas *fcv; + for (lay = layouts; lay; lay = lay->lay_next) + if (!strcmp(lay->lay_title, name)) + break; + if (lay) + FreeLayoutCv(&lay->lay_canvas); + else + lay = CreateLayout(name, 0); + if (!lay) + return; + fcv = D_forecv; + DupLayoutCv(cv, &lay->lay_canvas, 1); + lay->lay_forecv = D_forecv; + D_forecv = fcv; + D_layout = lay; +} + +void +AutosaveLayout(lay) +struct layout *lay; +{ + struct canvas *fcv; + if (!lay || !lay->lay_autosave) + return; + FreeLayoutCv(&lay->lay_canvas); + fcv = D_forecv; + DupLayoutCv(&D_canvas, &lay->lay_canvas, 1); + lay->lay_forecv = D_forecv; + D_forecv = fcv; +} + +struct layout * +FindLayout(name) +char *name; +{ + struct layout *lay; + char *s; + int i; + for (i = 0, s = name; *s >= '0' && *s <= '9'; s++) + i = i * 10 + (*s - '0'); + if (!*s && s != name && i >= 0 && i < MAXLAY) + return laytab[i]; + for (lay = layouts; lay; lay = lay->lay_next) + if (!strcmp(lay->lay_title, name)) + break; + return lay; +} + +void +LoadLayout(lay, cv) +struct layout *lay; +struct canvas *cv; +{ + AutosaveLayout(D_layout); + if (!lay) + { + while (D_canvas.c_slperp) + FreeCanvas(D_canvas.c_slperp); + MakeDefaultCanvas(); + SetCanvasWindow(D_forecv, 0); + D_layout = 0; + return; + } + while (D_canvas.c_slperp) + FreeCanvas(D_canvas.c_slperp); + D_cvlist = 0; + D_forecv = lay->lay_forecv; + DupLayoutCv(&lay->lay_canvas, &D_canvas, 0); + D_canvas.c_ye = D_height - 1 - ((D_canvas.c_slperp && D_canvas.c_slperp->c_slnext) || captionalways) - (D_has_hstatus == HSTATUS_LASTLINE); + ResizeCanvas(&D_canvas); + RecreateCanvasChain(); + RethinkDisplayViewports(); + PutWindowCv(&D_canvas); + ResizeLayersToCanvases(); + D_layout = lay; +} + +void +NewLayout(title, startat) +char *title; +int startat; +{ + struct layout *lay; + struct canvas *fcv; + + lay = CreateLayout(title, startat); + if (!lay) + return; + LoadLayout(0, &D_canvas); + fcv = D_forecv; + DupLayoutCv(&D_canvas, &lay->lay_canvas, 1); + lay->lay_forecv = D_forecv; + D_forecv = fcv; + D_layout = lay; + lay->lay_autosave = 1; +} + + +static char * +AddLayoutsInfo(buf, len, where) +char *buf; +int len; +int where; +{ + char *s, *ss, *t; + struct layout *p, **pp; + int l; + + s = ss = buf; + for (pp = laytab; pp < laytab + MAXLAY; pp++) + { + if (pp - laytab == where && ss == buf) + ss = s; + if ((p = *pp) == 0) + continue; + t = p->lay_title; + l = strlen(t); + if (l > 20) + l = 20; + if (s - buf + l > len - 24) + break; + if (s > buf) + { + *s++ = ' '; + *s++ = ' '; + } + sprintf(s, "%d", p->lay_number); + if (p->lay_number == where) + ss = s; + s += strlen(s); + if (display && p == D_layout) + *s++ = '*'; + *s++ = ' '; + strncpy(s, t, l); + s += l; + } + *s = 0; + return ss; +} + +void +ShowLayouts(where) +int where; +{ + char buf[1024]; + char *s, *ss; + + if (!display) + return; + if (!layouts) + { + Msg(0, "No layouts defined\n"); + return; + } + if (where == -1 && D_layout) + where = D_layout->lay_number; + ss = AddLayoutsInfo(buf, sizeof(buf), where); + s = buf + strlen(buf); + if (ss - buf > D_width / 2) + { + ss -= D_width / 2; + if (s - ss < D_width) + { + ss = s - D_width; + if (ss < buf) + ss = buf; + } + } + else + ss = buf; + Msg(0, "%s", ss); +} + +void +RemoveLayout(lay) +struct layout *lay; +{ + struct layout **layp = &layouts; + + for (; *layp; layp = &(*layp)->lay_next) + { + if (*layp == lay) + { + *layp = lay->lay_next; + break; + } + } + laytab[lay->lay_number] = (struct layout *)0; + + if (display && D_layout == lay) + D_layout = (struct layout *)0; + + FreeLayoutCv(&lay->lay_canvas); + + if (lay->lay_title) + free(lay->lay_title); + free(lay); + + if (layouts) + LoadLayout((display && D_layout) ? D_layout : *layp ? *layp : layouts, + display ? &D_canvas : (struct canvas *)0); + Activate(0); +} + +void +UpdateLayoutCanvas(cv, wi) +struct canvas *cv; +struct win *wi; +{ + for (; cv; cv = cv->c_slnext) + { + if (cv->c_layer && Layer2Window(cv->c_layer) == wi) + { + /* A simplistic version of SetCanvasWindow(cv, 0) */ + struct layer *l = cv->c_layer; + cv->c_layer = 0; + if (l->l_cvlist == 0 && (wi == 0 || l != wi->w_savelayer)) + KillLayerChain(l); + l = &cv->c_blank; + l->l_data = 0; + if (l->l_cvlist != cv) + { + cv->c_lnext = l->l_cvlist; + l->l_cvlist = cv; + } + cv->c_layer = l; + /* Do not end here. Multiple canvases can have the same window */ + } + + if (cv->c_slperp) + UpdateLayoutCanvas(cv->c_slperp, wi); + } +} + + diff --git a/src/layout.h b/src/layout.h new file mode 100644 index 0000000..2701154 --- /dev/null +++ b/src/layout.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + * $Id$ FAU + */ + +#ifndef SCREEN_LAYOUT_H +#define SCREEN_LAYOUT_H + +#include "canvas.h" + +#define MAXLAY 10 + +struct layout +{ + struct layout *lay_next; + char *lay_title; + int lay_number; + struct canvas lay_canvas; + struct canvas *lay_forecv; + struct canvas *lay_cvlist; + int lay_autosave; +}; + +extern void AutosaveLayout __P((struct layout *)); +extern void LoadLayout __P((struct layout *, struct canvas *)); +extern void NewLayout __P((char *, int)); +extern void SaveLayout __P((char *, struct canvas *)); +extern void ShowLayouts __P((int)); +extern struct layout *FindLayout __P((char *)); +extern void UpdateLayoutCanvas __P((struct canvas *, struct win *)); + +#endif /* SCREEN_LAYOUT_H */ + diff --git a/src/process.c b/src/process.c index fda3a8e..27877c2 100644 --- a/src/process.c +++ b/src/process.c @@ -49,7 +49,8 @@ #include "screen.h" #include "extern.h" #include "logfile.h" -#include "canvas.h" +#include "layout.h" +#include "viewport.h" extern struct comm comms[]; extern char *rc_name; @@ -5135,36 +5136,6 @@ MoreWindows() return 0; } -static void -UpdateLayoutCanvas(cv, wi) -struct canvas *cv; -struct win *wi; -{ - for (; cv; cv = cv->c_slnext) - { - if (cv->c_layer && Layer2Window(cv->c_layer) == wi) - { - /* A simplistic version of SetCanvasWindow(cv, 0) */ - struct layer *l = cv->c_layer; - cv->c_layer = 0; - if (l->l_cvlist == 0 && (wi == 0 || l != wi->w_savelayer)) - KillLayerChain(l); - l = &cv->c_blank; - l->l_data = 0; - if (l->l_cvlist != cv) - { - cv->c_lnext = l->l_cvlist; - l->l_cvlist = cv; - } - cv->c_layer = l; - /* Do not end here. Multiple canvases can have the same window */ - } - - if (cv->c_slperp) - UpdateLayoutCanvas(cv->c_slperp, wi); - } -} - void KillWindow(wi) struct win *wi; diff --git a/src/viewport.c b/src/viewport.c new file mode 100644 index 0000000..f1607d5 --- /dev/null +++ b/src/viewport.c @@ -0,0 +1,140 @@ +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +#include "config.h" +#include "screen.h" +#include "extern.h" +#include "viewport.h" + +extern struct display *display; + +int +RethinkDisplayViewports() +{ + struct canvas *cv; + struct viewport *vp, *vpn; + + /* free old viewports */ + for (cv = display->d_cvlist; cv; cv = cv->c_next) + { + for (vp = cv->c_vplist; vp; vp = vpn) + { + vp->v_canvas = 0; + vpn = vp->v_next; + bzero((char *)vp, sizeof(*vp)); + free(vp); + } + cv->c_vplist = 0; + } + display->d_vpxmin = -1; + display->d_vpxmax = -1; + + for (cv = display->d_cvlist; cv; cv = cv->c_next) + { + if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0) + return -1; +#ifdef HOLE + vp->v_canvas = cv; + vp->v_xs = cv->c_xs; + vp->v_ys = (cv->c_ys + cv->c_ye) / 2; + vp->v_xe = cv->c_xe; + vp->v_ye = cv->c_ye; + vp->v_xoff = cv->c_xoff; + vp->v_yoff = cv->c_yoff; + vp->v_next = cv->c_vplist; + cv->c_vplist = vp; + + if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0) + return -1; + vp->v_canvas = cv; + vp->v_xs = (cv->c_xs + cv->c_xe) / 2; + vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4; + vp->v_xe = cv->c_xe; + vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1; + vp->v_xoff = cv->c_xoff; + vp->v_yoff = cv->c_yoff; + vp->v_next = cv->c_vplist; + cv->c_vplist = vp; + + if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0) + return -1; + vp->v_canvas = cv; + vp->v_xs = cv->c_xs; + vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4; + vp->v_xe = (3 * cv->c_xs + cv->c_xe) / 4 - 1; + vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1; + vp->v_xoff = cv->c_xoff; + vp->v_yoff = cv->c_yoff; + vp->v_next = cv->c_vplist; + cv->c_vplist = vp; + + if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0) + return -1; + vp->v_canvas = cv; + vp->v_xs = cv->c_xs; + vp->v_ys = cv->c_ys; + vp->v_xe = cv->c_xe; + vp->v_ye = (3 * cv->c_ys + cv->c_ye) / 4 - 1; + vp->v_xoff = cv->c_xoff; + vp->v_yoff = cv->c_yoff; + vp->v_next = cv->c_vplist; + cv->c_vplist = vp; +#else + vp->v_canvas = cv; + vp->v_xs = cv->c_xs; + vp->v_ys = cv->c_ys; + vp->v_xe = cv->c_xe; + vp->v_ye = cv->c_ye; + vp->v_xoff = cv->c_xoff; + vp->v_yoff = cv->c_yoff; + vp->v_next = cv->c_vplist; + cv->c_vplist = vp; +#endif + + if (cv->c_xs < display->d_vpxmin || display->d_vpxmin == -1) + display->d_vpxmin = cv->c_xs; + if (cv->c_xe > display->d_vpxmax || display->d_vpxmax == -1) + display->d_vpxmax = cv->c_xe; + } + return 0; +} + +void +RethinkViewportOffsets(cv) +struct canvas *cv; +{ + struct viewport *vp; + + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + vp->v_xoff = cv->c_xoff; + vp->v_yoff = cv->c_yoff; + } +} + + diff --git a/src/viewport.h b/src/viewport.h new file mode 100644 index 0000000..67fa236 --- /dev/null +++ b/src/viewport.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + * $Id$ FAU + */ + +#ifndef SCREEN_VIEWPORT_H +#define SCREEN_VIEWPORT_H + +#include "canvas.h" + +struct viewport +{ + struct viewport *v_next; /* next vp on canvas */ + struct canvas *v_canvas; /* back pointer to canvas */ + int v_xoff; /* layer x offset on display */ + int v_yoff; /* layer y offset on display */ + int v_xs; /* vp upper left */ + int v_xe; /* vp upper right */ + int v_ys; /* vp lower left */ + int v_ye; /* vp lower right */ +}; + +extern int RethinkDisplayViewports __P((void)); +extern void RethinkViewportOffsets __P((struct canvas *)); + +#endif /* SCREEN_VIEWPORT_H */ + -- cgit v1.2.1 From 57553d823a4f47ba00c23f77f1d587166fe26e63 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 12 Nov 2009 14:49:07 -0500 Subject: ifdef checks so doesn't get included more than once. --- src/layer.h | 5 +++++ src/window.h | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/layer.h b/src/layer.h index 572c9e6..fc6d191 100644 --- a/src/layer.h +++ b/src/layer.h @@ -27,6 +27,9 @@ * $Id$ FAU */ +#ifndef SCREEN_LAYER_H +#define SCREEN_LAYER_H + /* * This is the overlay structure. It is used to create a seperate * layer over the current windows. @@ -108,3 +111,5 @@ struct layer display = olddisplay; \ } while(0) +#endif /* SCREEN_LAYER_H */ + diff --git a/src/window.h b/src/window.h index 6c6ca76..ce6af93 100644 --- a/src/window.h +++ b/src/window.h @@ -27,6 +27,8 @@ * $Id$ FAU */ +#ifndef SCREEN_WINDOW_H +#define SCREEN_WINDOW_H /* keep this in sync with the initialisations in window.c */ struct NewWindow @@ -323,3 +325,6 @@ struct win : &fore->w_mlines[y - fore->w_histheight]) #define Layer2Window(l) ((struct win *)(l)->l_bottom->l_data) + +#endif /* SCREEN_WINDOW_H */ + -- cgit v1.2.1 From ee0f7d41e9655c58219624b48d0f4d5759ab3e34 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 12 Nov 2009 15:04:57 -0500 Subject: Use "Km" to determine Xterm mouse tracking. Instead of explicitly looking for "xterm" or "rxvt" in $TERM, look at the termcap/terminfo setting to determine if mouse support is available or not. Closes #24075 --- src/term.c | 3 +++ src/termcap.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/term.c b/src/term.c index 8cf2729..05122db 100644 --- a/src/term.c +++ b/src/term.c @@ -176,6 +176,9 @@ struct term term[T_N] = { "eA", T_STR }, { "XC", T_STR }, +/* mouse */ + { "Km", T_STR }, + /* keycaps */ /* define T_CAPS */ /* nolist */ diff --git a/src/termcap.c b/src/termcap.c index 2b63a24..2545531 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -226,7 +226,8 @@ int he; /* ISO2022 */ if ((D_EA && InStr(D_EA, "\033(B")) || (D_AS && InStr(D_AS, "\033(0"))) D_CG0 = 1; - if (InStr(D_termname, "xterm") || InStr(D_termname, "rxvt")) + if (InStr(D_termname, "xterm") || InStr(D_termname, "rxvt") || + (D_CKM && InStr(D_CKM, "\033[M"))) D_CXT = 1; /* "be" seems to be standard for xterms... */ if (D_CXT) -- cgit v1.2.1 From 2818db1843181da171984e8301d6300cca1d8562 Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Sun, 15 Nov 2009 00:54:27 -0500 Subject: Handle the '2' code for OSC. This makes it possible to set the title using, for example, xtermcontrol. --- src/ansi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ansi.c b/src/ansi.c index a6fc161..a9c7054 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -1530,7 +1530,7 @@ StringEnd() } #endif #ifdef RXVT_OSC - if (typ == 0 || typ == 1 || typ == 20 || typ == 39 || typ == 49) + if (typ == 0 || typ == 1 || typ == 2 || typ == 20 || typ == 39 || typ == 49) { int typ2; typ2 = typ / 10; @@ -1540,7 +1540,7 @@ StringEnd() { strncpy(curr->w_xtermosc[typ2], p, sizeof(curr->w_xtermosc[typ2]) - 1); curr->w_xtermosc[typ2][sizeof(curr->w_xtermosc[typ2]) - 1] = 0; - + for (display = displays; display; display = display->d_next) { if (!D_CXT) -- cgit v1.2.1 From fb6e6cca1d7544a2be3d9d8bcbfc31cdb9177573 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 15 Nov 2009 10:36:07 -0500 Subject: Rearrange some code to make it more readable. --- src/display.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/display.c b/src/display.c index 87363ab..3c026bd 100644 --- a/src/display.c +++ b/src/display.c @@ -2797,7 +2797,12 @@ SetXtermOSC(i, s) int i; char *s; { - static char oscs[] = "0;\000\00020;\00039;\00049;\000"; + static char *oscs[][2] = { + { "2;", "screen" }, /* set window title */ + { "20;", "" }, /* background */ + { "39;", "black" }, /* default foreground (black?) */ + { "49;", "white" } /* default background (white?) */ + }; ASSERT(display); if (!D_CXT) @@ -2806,17 +2811,9 @@ char *s; s = ""; if (!D_xtermosc[i] && !*s) return; - if (i == 0 && !*s) - s = "screen"; /* always set icon name */ - if (i == 1 && !*s) - s = ""; /* no background */ - if (i == 2 && !*s) - s = "black"; /* black text */ - if (i == 3 && !*s) - s = "white"; /* on white background */ D_xtermosc[i] = 1; AddStr("\033]"); - AddStr(oscs + i * 4); + AddStr(oscs[i][0]); AddStr(s); AddChar(7); } -- cgit v1.2.1 From ab216924670dd97ae37cbfd9825b6162323cbd7a Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 15 Nov 2009 12:51:14 -0500 Subject: Stack/Unstack titles. Save the window title the first time screen modifies the xterm title and restore it when terminating (recognized by xterm #251). Thanks to Thomas Dickey. This change is based on his patch. --- src/display.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/display.c b/src/display.c index 3c026bd..f257db9 100644 --- a/src/display.c +++ b/src/display.c @@ -2811,6 +2811,8 @@ char *s; s = ""; if (!D_xtermosc[i] && !*s) return; + if (i == 0 && !D_xtermosc[0]) + AddStr("\033[22;2t"); /* stack titles (xterm patch #251) */ D_xtermosc[i] = 1; AddStr("\033]"); AddStr(oscs[i][0]); @@ -2824,6 +2826,8 @@ ClearAllXtermOSC() int i; for (i = 3; i >= 0; i--) SetXtermOSC(i, 0); + if (D_xtermosc[0]) + AddStr("\033[23;2t"); /* unstack titles (xterm patch #251) */ } #endif -- cgit v1.2.1 From 13180450c61fd67694f09fd04e0a730240d569c7 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 15 Nov 2009 13:06:59 -0500 Subject: Add a note on changing title/icon. Currently we set just the title, and not the icon, on the xterm window. Should we want to change both, we will need to save both on the stack and restore accordingly. This could be configurable, but I am going to forego that for the moment. --- src/display.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/display.c b/src/display.c index f257db9..ebbeed4 100644 --- a/src/display.c +++ b/src/display.c @@ -2792,13 +2792,15 @@ int newtop, newbot; } #ifdef RXVT_OSC +#define WT_FLAG "2" /* change to "0" to set both title and icon */ + void SetXtermOSC(i, s) int i; char *s; { static char *oscs[][2] = { - { "2;", "screen" }, /* set window title */ + { WT_FLAG ";", "screen" }, /* set window title */ { "20;", "" }, /* background */ { "39;", "black" }, /* default foreground (black?) */ { "49;", "white" } /* default background (white?) */ @@ -2812,7 +2814,7 @@ char *s; if (!D_xtermosc[i] && !*s) return; if (i == 0 && !D_xtermosc[0]) - AddStr("\033[22;2t"); /* stack titles (xterm patch #251) */ + AddStr("\033[22;" WT_FLAG "t"); /* stack titles (xterm patch #251) */ D_xtermosc[i] = 1; AddStr("\033]"); AddStr(oscs[i][0]); @@ -2827,8 +2829,9 @@ ClearAllXtermOSC() for (i = 3; i >= 0; i--) SetXtermOSC(i, 0); if (D_xtermosc[0]) - AddStr("\033[23;2t"); /* unstack titles (xterm patch #251) */ + AddStr("\033[23;" WT_FLAG "t"); /* unstack titles (xterm patch #251) */ } +#undef WT_FLAG #endif /* -- cgit v1.2.1 From c75d5fe5080b6327be41a627777f700f33275e10 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 15 Nov 2009 18:16:29 -0500 Subject: Add accidentally omitted code during commit. --- src/display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/display.c b/src/display.c index ebbeed4..5adf751 100644 --- a/src/display.c +++ b/src/display.c @@ -2815,6 +2815,8 @@ char *s; return; if (i == 0 && !D_xtermosc[0]) AddStr("\033[22;" WT_FLAG "t"); /* stack titles (xterm patch #251) */ + if (!*s) + s = oscs[i][1]; D_xtermosc[i] = 1; AddStr("\033]"); AddStr(oscs[i][0]); -- cgit v1.2.1 From ad56f746c6243d45124485d198d577bdbb78071c Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 29 Nov 2009 23:34:25 -0500 Subject: Fix using alternate screen buffers in some cases. Screen would reset the 'main' screen buffer if an app tries to switch to an alternate buffer while it is already using one (in other words, sends multiple 'smcup' without an 'rmcup'). This should fix debian bug #558724. --- src/resize.c | 40 +++++++++++++++++++++++++++++----------- src/window.h | 1 + 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/resize.c b/src/resize.c index 9c7b70f..1afdf5a 100644 --- a/src/resize.c +++ b/src/resize.c @@ -1026,16 +1026,20 @@ struct win *p; struct mline *ml; int t; - ml = p->w_alt_mlines; p->w_alt_mlines = p->w_mlines; p->w_mlines = ml; - t = p->w_alt_width; p->w_alt_width = p->w_width; p->w_width = t; - t = p->w_alt_height; p->w_alt_height = p->w_height; p->w_height = t; - t = p->w_alt_histheight; p->w_alt_histheight = p->w_histheight; p->w_histheight = t; - t = p->w_alt_x; p->w_alt_x = p->w_x; p->w_x = t; - t = p->w_alt_y; p->w_alt_y = p->w_y; p->w_y = t; +#define SWAP(item, t) do { (t) = p->w_alt_##item; p->w_alt_##item = p->w_##item; p->w_##item = (t); } while (0) + + SWAP(mlines, ml); + SWAP(width, t); + SWAP(height, t); + SWAP(histheight, t); + SWAP(x, t); + SWAP(y, t); + #ifdef COPY_PASTE - ml = p->w_alt_hlines; p->w_alt_hlines = p->w_hlines; p->w_hlines = ml; - t = p->w_alt_histidx; p->w_alt_histidx = p->w_histidx; p->w_histidx = t; + SWAP(hlines, ml); + SWAP(histidx, t); #endif +#undef SWAP } void @@ -1043,20 +1047,34 @@ EnterAltScreen(p) struct win *p; { int ox = p->w_x, oy = p->w_y; - FreeAltScreen(p); - SwapAltScreen(p); + if (!p->w_alt_current) + { + /* If not already using the alternate screen buffer, then create + a new one and swap it with the 'real' screen buffer. */ + FreeAltScreen(p); + SwapAltScreen(p); + } + else + { + /* Already using the alternate buffer. Just clear the screen. To do so, it + is only necessary to reset the height(s) without resetting the width. */ + p->w_height = 0; + p->w_histheight = 0; + } ChangeWindowSize(p, p->w_alt_width, p->w_alt_height, p->w_alt_histheight); p->w_x = ox; p->w_y = oy; + p->w_alt_current = 1; } void LeaveAltScreen(p) struct win *p; { - if (!p->w_alt_mlines) + if (!p->w_alt_current) return; SwapAltScreen(p); ChangeWindowSize(p, p->w_alt_width, p->w_alt_height, p->w_alt_histheight); FreeAltScreen(p); + p->w_alt_current = 0; } diff --git a/src/window.h b/src/window.h index ce6af93..ed8506f 100644 --- a/src/window.h +++ b/src/window.h @@ -282,6 +282,7 @@ struct win struct mline *w_alt_hlines; int w_alt_histidx; #endif + int w_alt_current; /* Is the alternate buffer currently being used? */ }; -- cgit v1.2.1 From 16c47c445484caebcd4ddcf8f18694d78fe77e16 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Mon, 30 Nov 2009 00:07:51 -0500 Subject: Doc update for mousetrack and window groups. --- src/doc/screen.texinfo | 82 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index ea3a18a..6aee8e7 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -919,6 +919,8 @@ Select default utmp logging behavior. @xref{Login}. Select default file mode for ptys. @xref{Mode}. @item defmonitor @var{state} Select default activity monitoring behavior. @xref{Monitor}. +@item defmousetrack @var{on}|@var{off} +Select the default mouse tracking behavior. @xref{Mousetrack}. @item defnonblock @var{state}|@var{numsecs} Select default nonblock mode. @xref{Nonblock}. @item defobuflimit @var{limit} @@ -967,6 +969,8 @@ Set flow control behavior. @xref{Flow}. Move focus to next region. @xref{Regions}. @item gr [@var{state}] Change GR charset processing. @xref{Character Processing}. +@item group [@var{grouptitle}] +Change or show the group the current window belongs to. @xref{Window Groups}. @item hardcopy [-h] [@var{file}] Write out the contents of the current window. @xref{Hardcopy}. @item hardcopy_append @var{state} @@ -1021,6 +1025,8 @@ Set the maximum window number. @xref{Maxwin}. Insert the command character. @xref{Command Character}. @item monitor [@var{state}] Monitor activity in window. @xref{Monitor}. +@item mousetrack [@var{on}|@var{off}] +Enable selecting splitted regions with mouse clicks. @xref{Mousetrack}. @item msgminwait @var{sec} Set minimum message wait. @xref{Message Wait}. @item msgwait @var{sec} @@ -1081,11 +1087,11 @@ Change text attributes in caption for flagged windows. @xref{Rendition}. Reset the terminal settings for the window. @xref{Reset}. @item resize [(+/-)lines] Grow or shrink a region -@item screen [@var{opts}] [@var{n}] [@var{cmd} [@var{args}]] +@item screen [@var{opts}] [@var{n}] [@var{cmd} [@var{args}] | //group] Create a new window. @xref{Screen Command}. @item scrollback @var{num} Set size of scrollback buffer. @xref{Scrollback}. -@item select [@var{n}] +@item select [@var{n}|-|.] Switch to a specified window. @xref{Selecting}. @item sessionname [@var{name}] Name this session. @xref{Session Name}. @@ -1151,7 +1157,7 @@ Display @code{screen} version. @xref{Version}. Write a message to all displays. @xref{Multiuser Session}. @item width [@var{cols} [@var{lines}]] Set the width of the window. @xref{Window Size}. -@item windowlist [-b] | string [@var{string}] | title [@var{title}] +@item windowlist [[-b] [-m] [-g]] | string [@var{string}] | title [@var{title}] Present a list of all windows for selection. @xref{Windowlist}. @item windows List active windows. @xref{Windows}. @@ -1187,6 +1193,7 @@ configuration parameter. * Shell:: Parameters for shell windows. * Term:: Set the terminal type for new windows. * Window Types:: Creating different types of windows. +* Window Groups:: Grouping windows together @end menu @node Chdir, Screen Command, , New Window @@ -1211,7 +1218,7 @@ affect all the windows you create interactively. @section Screen Command @kindex c @kindex C-c -@deffn Command screen [opts] [n] [cmd [args]] +@deffn Command screen [opts] [n] [cmd [args] @var{| //group}] (@kbd{C-a c}, @kbd{C-a C-c})@* Establish a new window. The flow-control options (@samp{-f}, @samp{-fn} and @samp{-fa}), title option (@samp{-t}), login options @@ -1225,6 +1232,8 @@ the window number @var{n} is assigned to the newly created window (or, if this number is already in-use, the next available number). If a command is specified after @code{screen}, this command (with the given arguments) is started in the window; otherwise, a shell is created. +If @samp{//group} is supplied, a container-type window is created in +which other windows may be created inside it. @xref{Window Groups}. Screen has built in some functionality of @samp{cu} and @samp{telnet}. @xref{Window Types}. @@ -1300,7 +1309,7 @@ the next @code{screen rlogin othermachine} command. Use the command and resetting the default. @end deffn -@node Window Types, , Term, New Window +@node Window Types, Window Groups, Term, New Window @section Window Types @cindex window types Screen provides three different window types. New windows are created @@ -1400,6 +1409,36 @@ For telnet windows, the command @code{break} sends the telnet code @end itemize +@node Window Groups, , Window Types, New Window +@section Window Groups +@cindex window groups +Screen provides a method for grouping windows together. Windows can be +organized in a heirarchial fashion, resembling a tree structure. New +screens are created using the @code{screen} command while new groups +are created using @code{screen //group}. @xref{Screen Command}. + +Once a new group is created, it will act as a container for windows +and even other groups. When a group is selected, you will see the +output of the @code{windowlist} command, allowing you to select a +window inside. If there are no windows inside a group, use the +@code{screen} command to create one. Once inside a group, using the +commands @code{next} and @code{prev} will switch between windows only +in that group. Using the @code{windowlist} command will give you the +opportunity to leave the group you are in. @xref{Windowlist}. + +@deffn Command group [grouptitle] +Change or show the group the current window belongs to. Windows can +be moved around between different groups by specifying the name of +the destination group. Without specifying a group, the title of the +current group is displayed. +@end deffn + +Using groups in combination with layouts will help create a +multi-desktop experience. One group can be assigned for each +layout made. Windows can be made, split, and organized within each +group as desired. Afterwhich, switching between groups can be as easy +as switching layouts. + @node Selecting, Session Management, New Window, Top @chapter Selecting a Window @@ -1451,7 +1490,7 @@ this command becomes @kbd{]]} (@pxref{Command Character}). @section Select @kindex 0@dots{}9 @kindex ' -@deffn Command select [n] +@deffn Command select [n @var{|-|.}] (@kbd{C-a @var{n}}, @kbd{C-a '})@* Switch to the window with the number @var{n}. If no window number is specified, you get prompted for an @@ -1471,19 +1510,22 @@ current window. The latter is useful if used with screen's @node Windowlist, , Select, Selecting @section Windowlist @kindex " -@deffn Command windowlist [-b] [-m] +@deffn Command windowlist [-b] [-m] [-g] @deffnx Command windowlist string [@var{string}] @deffnx Command windowlist title [@var{title}] (@kbd{C-a "})@* Display all windows in a table for visual window selection. The desired window can be selected via the standard movement keys (@pxref{Movement}) and activated via -the return key. If the @code{-b} option is given, screen will +the return key. If screen was in a window group, screen will +back out of the group and then display the windows in that +group. If the @code{-b} option is given, screen will switch to the blank window before presenting the list, so that the current window is also selectable. The @code{-m} option changes the order of the windows, instead of sorting by window numbers screen uses its internal most-recently-used -list. +list. The @code{-g} option will show the windows inside any groups +in that level and downwards. The table format can be changed with the string and title option, the title is displayed as table heading, while the @@ -2213,7 +2255,7 @@ If this list is too long to fit on the terminal's status line only the portion around the current window is displayed. @end deffn -@node Hardstatus, , Windows, Window Settings +@node Hardstatus, Mousetrack, Windows, Window Settings @section Hardstatus @code{Screen} maintains a hardstatus line for every window. If a window @@ -2244,6 +2286,25 @@ Per default the hardstatus line of new windows is empty. Changes the current window's hardstatus line to @var{status}. @end deffn +@node Mousetrack, , Hardstatus, Miscellaneous +@section Mousetrack + +@deffn Command mousetrack [ @code{on|off} ] +(none)@* +This command determines whether @code{screen} will watch for +mouse clicks. When this command is enabled, regions that have +been split in various ways can be selected by pointing to them +with a mouse and left-clicking them. Without specifying @var{on} +or @var{off}, the current state is displayed. The default state +is determined by the @code{defmousetrack} command. +@end deffn + +@deffn Command defmousetrack @code{on|off} +(none)@* +This command determines the default state of the @code{mousetrack} +command, currently defaulting of @var{off}. +@end deffn + @node Virtual Terminal, Copy and Paste, Window Settings, Top @chapter Virtual Terminal @@ -4368,6 +4429,7 @@ categories. * Backtick:: Program a command for a backtick string escape. * Screen Saver:: Define a screen safer. * Zmodem:: Define how screen treats zmodem requests. +* Mousetrack:: Set whether screen should track mouse events. @end menu @node At, Break, , Miscellaneous -- cgit v1.2.1 From b7eed135e7a84acccbe55cf63dbdff092ae80a94 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Mon, 30 Nov 2009 12:32:14 -0500 Subject: Update info-page for layouts. --- src/doc/screen.texinfo | 139 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 1 deletion(-) diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 6aee8e7..0801296 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -999,6 +999,28 @@ Removed, use @code{paste} instead. @xref{Registers}. Destroy the current window. @xref{Kill}. @item lastmsg Redisplay the last message. @xref{Last Message}. +@item layout new [@var{title}] +Create a layout. @xref{Layout}. +@item layout remove [@var{n}|@var{title}] +Delete a layout. @xref{Layout}. +@item layout next +Select the next layout. @xref{Layout}. +@item layout prev +Select the previous layout. @xref{Layout}. +@item layout select [@var{n}|@var{title}] +Jump to a layout. @xref{Layout}. +@item layout show +List the available layouts. @xref{Layout}. +@item layout title [@var{title}] +Show or set the title of a layout. @xref{Layout}. +@item layout number [@var{n}] +Show or set the number of a layout. @xref{Layout}. +@item layout attach [@var{title}|:last] +Show or set which layout to reattach to. @xref{Layout}. +@item layout save [@var{n}|@var{title}] +Remember the organization of a layout. @xref{Layout}. +@item layout autosave [@var{on}|@var{off}] +Show or set the status of layout saving. @xref{Layout}. @item license Display licensing information. @xref{Startup}. @item lockscreen @@ -1853,6 +1875,7 @@ which can contain different windows. * Resize:: Grow or shrink a region * Caption:: Control the window's caption * Fit:: Resize a window to fit the region +* Layout:: Manage groups of regions @end menu @node Split, Focus, , Regions @@ -1944,7 +1967,7 @@ You can mix both forms by providing the string as an additional argument. @end deffn -@node Fit, , Caption, Regions +@node Fit, Layout, Caption, Regions @section Fit @kindex F @deffn Command fit @@ -1954,6 +1977,120 @@ command is needed because screen doesn't adapt the window size automatically if the window is displayed more than once. @end deffn +@node Layout, , Fit, Regions +@section Layout +@cindex layout +Using regions, and perhaps a large enough terminal, you can create +a more of a desktop feel to @code{screen}. By being able to split +regions horizontally or vertically, you can take advantage of the +lesser used spaces of your terminal. The catch to these splits has +been that they're not kept between screen detachments and reattachments. + +Layouts will help your organization of regions. You can create one +layout of four horizontal regions and then create a separate layout +of regions in a two by two array. The regions don't have to contain +the same windows. You can easily switch between layouts and keep +them between detachments and reattachments. + +Note that there are several subcommands to @code{layout}. + +@deffn Command layout @code{new} [title] +(none)@* +Create a new layout. The screen will change to one whole region +and be switched to the blank window. From here, you build the +regions and the windows they show as you desire. The new layout +will be numbered with the smallest available integer, starting +with zero. You can optionally give a title to your new layout. +Otherwise, it will have a default title of @code{layout}. You +can always change the title later by using the command +@code{layout title}. +@end deffn + +@deffn Command layout @code{remove} [n|title] +(none)@* +Remove, or in other words, delete the specified layout. Either +the number or the title can be specified. Without either +specification, @code{screen} will remove the current layout. + +Removing a layout does not affect your set windows or regions. +@end deffn + +@deffn Command layout @code{next} +(none)@* +Switch to the next layout available +@end deffn + +@deffn Command layout @code{prev} +(none)@* +Switch to the previous layout available +@end deffn + +@deffn Command layout @code{select} [n|title] +(none)@* +Select the desired layout. Either the number or the title can +be specified. Without either specification, @code{screen} will +prompt and ask which screen is desired. To see which layouts are +available, use the @code{layout show} command. +@end deffn + +@deffn Command layout @code{show} +(none)@* +List on the message line the number(s) and title(s) of the available +layout(s). The current layout is flagged. +@end deffn + +@deffn Command layout @code{title} [title] +(none)@* +Change or display the title of the current layout. A string given +will be used to name the layout. Without any options, the current +title and number is displayed on the message line. +@end deffn + +@deffn Command layout @code{number} [n] +(none)@* +Change or display the number of the current layout. An integer given +will be used to number the layout. Without any options, the current +number and title is displayed on the message line. +@end deffn + +@deffn Command layout @code{attach} [title|@code{:last}] +(none)@* +Change or display which layout to reattach back to. The default is +@code{:last}, which tells @code{screen} to reattach back to the last +used layout just before detachment. By supplying a title, You can +instruct @code{screen} to reattach to a particular layout regardless +which one was used at the time of detachment. Without any options, +the layout to reattach to will be shown in the message line. +@end deffn + +@deffn Command layout @code{save} [n|title] +(none)@* +Remember the current arrangement of regions. When used, @code{screen} +will remember the arrangement of vertically and horizontally split +regions. This arrangement is restored when a @code{screen} session +is reattached or switched back from a different layout. If a number +or title is supplied, @code{screen} will remember the arrangement of +that particular layout. Without any options, @code{screen} will +remember the current layout. + +Saving your regions can be done automatically by using the +@code{layout autosave} command. +@end deffn + +@deffn Command layout @code{autosave} [@code{on}|@code{off}] +(none)@* +Change or display the status of automatcally saving layouts. The +default is @code{on}, meaning when @code{screen} is detached or +changed to a different layout, the arrangement of regions and windows +will be remembered at the time of change and restored upon return. +If autosave is set to @code{off}, that arrangement will only be +restored to either to the last manual save, using @code{layout save}, +or to when the layout was first created, to a single region with +a single window. Without either an @code{on} or an @code{off}, the +current status is displayed on the message line. +@end deffn + + @node Window Settings, Virtual Terminal, Regions, Top @chapter Window Settings -- cgit v1.2.1 From abb2194e85650b2169b4da4653eef6ac7a9c28cf Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Mon, 30 Nov 2009 12:38:10 -0500 Subject: Update info-page for digraph. --- src/doc/screen.texinfo | 191 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 187 insertions(+), 4 deletions(-) diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 0801296..1a17776 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -943,8 +943,8 @@ Set default writelock behavior. @xref{Multiuser Session}. Keep dead windows. @xref{Zombie}. @item detach [-h] Disconnect @code{screen} from the terminal. @xref{Detach}. -@item digraph -Enter digraph sequence. @xref{Digraph}. +@item digraph [@var{preset} [@var{unicode-value}]] +Enter a digraph sequence. @xref{Digraph}. @item dinfo Display terminal information. @xref{Info}. @item displays @@ -2694,7 +2694,7 @@ Keypad enter fe stuff \015 @section Digraph @kindex C-v -@deffn Command digraph [preset] +@deffn Command digraph [preset [unicode-value]] (@kbd{C-a C-v})@* This command prompts the user for a digraph sequence. The next two characters typed are looked up in a builtin table and the @@ -2705,7 +2705,190 @@ will treat the following characters (up to three) as an octal number instead. The optional argument @var{preset} is treated as user input, thus one can create an "umlaut" key. For example the command @samp{bindkey ^K digraph '"'} enables the user -to generate an a-umlaut by typing @samp{CTRL-K a}. +to generate an a-umlaut by typing @samp{CTRL-K a}. When a non-zero +@var{unicode-value} is specified, a new digraph is created with the +specified preset. The digraph is unset if a zero value is provided +for the @var{unicode-value}. + +The following table is the builtin sequences. + +@documentencoding ISO-8859-1 +@example + Sequence Octal Digraph Unicode Equivalent + ----------------------------------------------- + ' ', ' ' 160 (space) U+00A0 + 'N', 'S' 160 (space) U+00A0 + '~', '!' 161 ¡ U+00A1 + '!', '!' 161 ¡ U+00A1 + '!', 'I' 161 ¡ U+00A1 + 'c', '|' 162 ¢ U+00A2 + 'c', 't' 162 ¢ U+00A2 + '$', '$' 163 £ U+00A3 + 'P', 'd' 163 £ U+00A3 + 'o', 'x' 164 ¤ U+00A4 + 'C', 'u' 164 ¤ U+00A4 + 'C', 'u' 164 ¤ U+00A4 + 'E', 'u' 164 ¤ U+00A4 + 'Y', '-' 165 ¥ U+00A5 + 'Y', 'e' 165 ¥ U+00A5 + '|', '|' 166 ¦ U+00A6 + 'B', 'B' 166 ¦ U+00A6 + 'p', 'a' 167 § U+00A7 + 'S', 'E' 167 § U+00A7 + '"', '"' 168 ¨ U+00A8 + ''', ':' 168 ¨ U+00A8 + 'c', 'O' 169 © U+00A9 + 'C', 'o' 169 © U+00A9 + 'a', '-' 170 ª U+00AA + '<', '<' 171 « U+00AB + '-', ',' 172 ¬ U+00AC + 'N', 'O' 172 ¬ U+00AC + '-', '-' 173 ­ U+00AD + 'r', 'O' 174 ® U+00AE + 'R', 'g' 174 ® U+00AE + '-', '=' 175 ¯ U+00AF + ''', 'm' 175 ¯ U+00AF + '~', 'o' 176 ° U+00B0 + 'D', 'G' 176 ° U+00B0 + '+', '-' 177 ± U+00B1 + '2', '2' 178 ² U+00B2 + '2', 'S' 178 ² U+00B2 + '3', '3' 179 ³ U+00B3 + '3', 'S' 179 ³ U+00B3 + ''', ''' 180 ´ U+00B4 + 'j', 'u' 181 µ U+00B5 + 'M', 'y' 181 µ U+00B5 + 'p', 'p' 182 ¶ U+00B6 + 'P', 'I' 182 ¶ U+00B6 + '~', '.' 183 · U+00B7 + '.', 'M' 183 · U+00B7 + ',', ',' 184 ¸ U+00B8 + ''', ',' 184 ¸ U+00B8 + '1', '1' 185 ¹ U+00B9 + '1', 'S' 185 ¹ U+00B9 + 'o', '-' 186 º U+00BA + '>', '>' 187 » U+00BB + '1', '4' 188 ¼ U+00BC + '1', '2' 189 ½ U+00BD + '3', '4' 190 ¾ U+00BE + '~', '?' 191 ¿ U+00BF + '?', '?' 191 ¿ U+00BF + '?', 'I' 191 ¿ U+00BF + 'A', '`' 192 À U+00C0 + 'A', '!' 192 À U+00C0 + 'A', ''' 193 Á U+00C1 + 'A', '^' 194  U+00C2 + 'A', '>' 194  U+00C2 + 'A', '~' 195 à U+00C3 + 'A', '?' 195 à U+00C3 + 'A', '"' 196 Ä U+00C4 + 'A', ':' 196 Ä U+00C4 + 'A', '@@' 197 Å U+00C5 + 'A', 'A' 197 Å U+00C5 + 'A', 'E' 198 Æ U+00C6 + 'C', ',' 199 Ç U+00C7 + 'E', '`' 200 È U+00C8 + 'E', '!' 200 È U+00C8 + 'E', ''' 201 É U+00C9 + 'E', '^' 202 Ê U+00CA + 'E', '>' 202 Ê U+00CA + 'E', '"' 203 Ë U+00CB + 'E', ':' 203 Ë U+00CB + 'I', '`' 204 Ì U+00CC + 'I', '!' 204 Ì U+00CC + 'I', ''' 205 Í U+00CD + 'I', '^' 206 Î U+00CE + 'I', '>' 206 Î U+00CE + 'I', '"' 207 Ï U+00CF + 'I', ':' 207 Ï U+00CF + 'D', '-' 208 Ð U+00D0 + 'N', '~' 209 Ñ U+00D1 + 'N', '?' 209 Ñ U+00D1 + 'O', '`' 210 Ò U+00D2 + 'O', '!' 210 Ò U+00D2 + 'O', ''' 211 Ó U+00D3 + 'O', '^' 212 Ô U+00D4 + 'O', '>' 212 Ô U+00D4 + 'O', '~' 213 Õ U+00D5 + 'O', '?' 213 Õ U+00D5 + 'O', '"' 214 Ö U+00D6 + 'O', ':' 214 Ö U+00D6 + '/', '\' 215 × U+00D7 + '*', 'x' 215 × U+00D7 + 'O', '/' 216 Ø U+00D8 + 'U', '`' 217 Ù U+00D9 + 'U', '!' 217 Ù U+00D9 + 'U', ''' 218 Ú U+00DA + 'U', '^' 219 Û U+00DB + 'U', '>' 219 Û U+00DB + 'U', '"' 220 Ü U+00DC + 'U', ':' 220 Ü U+00DC + 'Y', ''' 221 Ý U+00DD + 'I', 'p' 222 Þ U+00DE + 'T', 'H' 222 Þ U+00DE + 's', 's' 223 ß U+00DF + 's', '"' 223 ß U+00DF + 'a', '`' 224 à U+00E0 + 'a', '!' 224 à U+00E0 + 'a', ''' 225 á U+00E1 + 'a', '^' 226 â U+00E2 + 'a', '>' 226 â U+00E2 + 'a', '~' 227 ã U+00E3 + 'a', '?' 227 ã U+00E3 + 'a', '"' 228 ä U+00E4 + 'a', ':' 228 ä U+00E4 + 'a', 'a' 229 å U+00E5 + 'a', 'e' 230 æ U+00E6 + 'c', ',' 231 ç U+00E7 + 'e', '`' 232 è U+00E8 + 'e', '!' 232 è U+00E8 + 'e', ''' 233 é U+00E9 + 'e', '^' 234 ê U+00EA + 'e', '>' 234 ê U+00EA + 'e', '"' 235 ë U+00EB + 'e', ':' 235 ë U+00EB + 'i', '`' 236 ì U+00EC + 'i', '!' 236 ì U+00EC + 'i', ''' 237 í U+00ED + 'i', '^' 238 î U+00EE + 'i', '>' 238 î U+00EE + 'i', '"' 239 ï U+00EF + 'i', ':' 239 ï U+00EF + 'd', '-' 240 ð U+00F0 + 'n', '~' 241 ñ U+00F1 + 'n', '?' 241 ñ U+00F1 + 'o', '`' 242 ò U+00F2 + 'o', '!' 242 ò U+00F2 + 'o', ''' 243 ó U+00F3 + 'o', '^' 244 ô U+00F4 + 'o', '>' 244 ô U+00F4 + 'o', '~' 245 õ U+00F5 + 'o', '?' 245 õ U+00F5 + 'o', '"' 246 ö U+00F6 + 'o', ':' 246 ö U+00F6 + ':', '-' 247 ÷ U+00F7 + 'o', '/' 248 ø U+00F8 + 'u', '`' 249 ù U+00F9 + 'u', '!' 249 ù U+00F9 + 'u', ''' 250 ú U+00FA + 'u', '^' 251 û U+00FB + 'u', '>' 251 û U+00FB + 'u', '"' 252 ü U+00FC + 'u', ':' 252 ü U+00FC + 'y', ''' 253 ý U+00FD + 'i', 'p' 254 þ U+00FE + 't', 'h' 254 þ U+00FE + 'y', '"' 255 ÿ U+00FF + 'y', ':' 255 ÿ U+00FF + '"', '[' 196 Ä U+00C4 + '"', '\' 214 Ö U+00D6 + '"', ']' 220 Ü U+00DC + '"', '@{' 228 ä U+00E4 + '"', '|' 246 ö U+00F6 + '"', '@}' 252 ü U+00FC + '"', '~' 223 ß U+00DF +@end example + @end deffn @node Bell, Clear, Digraph, Virtual Terminal -- cgit v1.2.1 From c78d93a1d7bd6c39fa4e2d94ef26907f9ddf308b Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Mon, 30 Nov 2009 12:46:45 -0500 Subject: More documentation updates. --- src/doc/screen.1 | 8 ++++++-- src/doc/screen.texinfo | 11 +++++++++-- src/help.c | 6 +++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index b48453f..e37c4cc 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -231,7 +231,11 @@ The use of this option is discouraged. turns login mode on or off (for /etc/utmp updating). This can also be defined through the \*Qdeflogin\*U .screenrc command. .TP 5 -.BR \-ls " and " \-list +.BR \-ls " [" \fImatch ] +.PD 0 +.TP 5 +.BR \-list " [" \fImatch ] +.PD does not start .IR screen , but prints a list of @@ -326,7 +330,7 @@ had not been specified. The option is set by default if is run as a login-shell (actually screen uses \*Q-xRR\*U in that case). For combinations with the \fB\-d\fP/\fB\-D\fP option see there. .TP 5 -.B \-s +.BI "\-s " program sets the default shell to the program specified, instead of the value in the environment variable $SHELL (or \*Q/bin/sh\*U if not defined). This can also be defined through the \*Qshell\*U .screenrc command. diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 1a17776..6228cd4 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -344,12 +344,19 @@ This also starts @code{screen} in @emph{detached} mode, but doesn't fork a new process. The command exits if the session terminates. @end table -@item -p @var{name_or_number} +@item -O +Select a more optimal output mode for your terminal rather than true VT100 +emulation (only affects auto-margin terminals without @samp{LP}). This +can also be set in your @file{.screenrc} by specifying @samp{OP} in the +@code{termcap} command. + +@item -p @var{name_or_number}|-|=|+ Preselect a window. This is useful when you want to reattach to a specific window or you want to send a command via the @samp{-X} option to a specific window. As with screen's select command, @samp{-} selects the blank window. As a special case for reattach, @samp{=} -brings up the windowlist on the blank window. +brings up the windowlist on the blank window, while a @samp{+} will +create new window. @item -q Suppress printing of error messages. In combination with @samp{-ls} the exit diff --git a/src/help.c b/src/help.c index ac7209f..a6497ce 100644 --- a/src/help.c +++ b/src/help.c @@ -74,13 +74,13 @@ char *myname, *message, *arg; #if defined(LOGOUTOK) && defined(UTMPOK) printf("-l Login mode on (update %s), -ln = off.\n", UTMPFILE); #endif - printf("-list or -ls. Do nothing, just list our SockDir.\n"); + printf("-ls [match] or -list. Do nothing, just list our SockDir [on possible matches].\n"); printf("-L Turn on output logging.\n"); printf("-m ignore $STY variable, do create a new screen session.\n"); printf("-O Choose optimal output rather than exact vt100 emulation.\n"); printf("-p window Preselect the named window if it exists.\n"); printf("-q Quiet startup. Exits with non-zero return code if unsuccessful.\n"); - printf("-r Reattach to a detached screen process.\n"); + printf("-r [session] Reattach to a detached screen process.\n"); printf("-R Reattach if possible, otherwise start a new session.\n"); printf("-s shell Shell to execute rather than $SHELL.\n"); printf("-S sockname Name this session .sockname instead of ...\n"); @@ -90,7 +90,7 @@ char *myname, *message, *arg; printf("-U Tell screen to use UTF-8 encoding.\n"); #endif printf("-v Print \"Screen version %s\".\n", version); - printf("-wipe Do nothing, just clean up SockDir.\n"); + printf("-wipe [match] Do nothing, just clean up SockDir [on possible matches].\n"); #ifdef MULTI printf("-x Attach to a not detached screen. (Multi display mode).\n"); #endif /* MULTI */ -- cgit v1.2.1 From a2f13ec78529f8e374a8af55d3aa415c2404222e Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 30 Nov 2009 16:48:28 -0500 Subject: Fix displaying unicode in caption/hardstatus. Avoid double encoding issue to fix displaying unicode in utf8-locale. Fixes #18505, #26452. --- src/ChangeLog | 1 + src/display.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 713a038..90fd67f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -59,6 +59,7 @@ Version 4.1.0 (??/??/20??): * In copy mode, search in reverse direction when 'N' is pressed. * Tab-completion for command input. * Some more readline-like bindings in input mode (e.g. ^W, ^D, ^P, ^N etc.) + * Fix displaying unicode characters in the caption/hardstatus on UTF8 locale. In-Progress: * Scripting support (thanks to Google Summer of Code 2009 project by Rui Guo) diff --git a/src/display.c b/src/display.c index 5adf751..d7f5aa0 100644 --- a/src/display.c +++ b/src/display.c @@ -2109,6 +2109,67 @@ RemoveStatusMinWait() RemoveStatus(); } +#ifdef UTF8 +static int +strlen_onscreen(unsigned char *c, unsigned char *end) +{ + int len = 0; + char *s = c; + while (*c && (!end || c < end)) + { + int v, dec = 0; + do + { + v = FromUtf8(*c++, &dec); + if (v == -2) + c--; + } + while (v < 0 && (!end || c < end)); + if (utf8_isdouble(v)) + len++; + len++; + } + + return len; +} + +static int +PrePutWinMsg(s, start, max) +char *s; +int start, max; +{ + /* Avoid double-encoding problem for a UTF-8 message on a UTF-8 locale. + Ideally, this would not be necessary. But fixing it the Right Way will + probably take way more time. So this will have to do for now. */ + if (D_encoding == UTF8) + { + int enc = D_encoding; + int chars = strlen_onscreen(s + start, s + max); + D_encoding = 0; + PutWinMsg(s, start, max); + D_encoding = enc; + D_x -= (max - chars); /* Yak! But this is necessary to count for + the fact that not every byte represents a + character. */ + return start + chars; + } + else + { + PutWinMsg(s, start, max); + return max; + } +} +#else +static int +PrePutWinMsg(s, start, max) +char *s; +int start, max; +{ + PutWinMsg(s, start, max); + return max; +} +#endif + /* refresh the display's hstatus line */ void ShowHStatus(str) @@ -2153,7 +2214,7 @@ char *str; l = D_width; GotoPos(0, D_height - 1); SetRendition(captionalways || D_cvlist == 0 || D_cvlist->c_next ? &mchar_null: &mchar_so); - PutWinMsg(str, 0, l); + l = PrePutWinMsg(str, 0, l); if (!captionalways && D_cvlist && !D_cvlist->c_next) while (l++ < D_width) PUTCHARLP(' '); @@ -2300,7 +2361,7 @@ int y, from, to, isblank; SetRendition(&mchar_so); if (l > xx - cv->c_xs + 1) l = xx - cv->c_xs + 1; - PutWinMsg(buf, from - cv->c_xs, l); + l = PrePutWinMsg(buf, from - cv->c_xs, l); from = cv->c_xs + l; for (; from <= xx; from++) PUTCHARLP(' '); @@ -2934,9 +2995,9 @@ int progress; } } wr = write(D_userfd, p, l); - if (wr <= 0) + if (wr <= 0) { - if (errno == EINTR) + if (errno == EINTR) continue; debug1("Writing to display: %d\n", errno); break; -- cgit v1.2.1 From 28c161010579e59ae5d310db277f8978911ac794 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 30 Nov 2009 16:48:28 -0500 Subject: Fix displaying unicode in caption/hardstatus. Avoid double encoding issue to fix displaying unicode in utf8-locale. Fixes #18505, #26452. --- src/ChangeLog | 1 + src/display.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 713a038..90fd67f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -59,6 +59,7 @@ Version 4.1.0 (??/??/20??): * In copy mode, search in reverse direction when 'N' is pressed. * Tab-completion for command input. * Some more readline-like bindings in input mode (e.g. ^W, ^D, ^P, ^N etc.) + * Fix displaying unicode characters in the caption/hardstatus on UTF8 locale. In-Progress: * Scripting support (thanks to Google Summer of Code 2009 project by Rui Guo) diff --git a/src/display.c b/src/display.c index 5adf751..776243f 100644 --- a/src/display.c +++ b/src/display.c @@ -2109,6 +2109,66 @@ RemoveStatusMinWait() RemoveStatus(); } +#ifdef UTF8 +static int +strlen_onscreen(unsigned char *c, unsigned char *end) +{ + int len = 0; + char *s = c; + while (*c && (!end || c < end)) + { + int v, dec = 0; + do + { + v = FromUtf8(*c++, &dec); + if (v == -2) + c--; + } + while (v < 0 && (!end || c < end)); + if (utf8_isdouble(v)) + len++; + len++; + } + + return len; +} + +static int +PrePutWinMsg(s, start, max) +char *s; +int start, max; +{ + /* Avoid double-encoding problem for a UTF-8 message on a UTF-8 locale. + Ideally, this would not be necessary. But fixing it the Right Way will + probably take way more time. So this will have to do for now. */ + if (D_encoding == UTF8) + { + int chars = strlen_onscreen(s + start, s + max); + D_encoding = 0; + PutWinMsg(s, start, max); + D_encoding = UTF8; + D_x -= (max - chars); /* Yak! But this is necessary to count for + the fact that not every byte represents a + character. */ + return start + chars; + } + else + { + PutWinMsg(s, start, max); + return max; + } +} +#else +static int +PrePutWinMsg(s, start, max) +char *s; +int start, max; +{ + PutWinMsg(s, start, max); + return max; +} +#endif + /* refresh the display's hstatus line */ void ShowHStatus(str) @@ -2153,7 +2213,7 @@ char *str; l = D_width; GotoPos(0, D_height - 1); SetRendition(captionalways || D_cvlist == 0 || D_cvlist->c_next ? &mchar_null: &mchar_so); - PutWinMsg(str, 0, l); + l = PrePutWinMsg(str, 0, l); if (!captionalways && D_cvlist && !D_cvlist->c_next) while (l++ < D_width) PUTCHARLP(' '); @@ -2300,7 +2360,7 @@ int y, from, to, isblank; SetRendition(&mchar_so); if (l > xx - cv->c_xs + 1) l = xx - cv->c_xs + 1; - PutWinMsg(buf, from - cv->c_xs, l); + l = PrePutWinMsg(buf, from - cv->c_xs, l); from = cv->c_xs + l; for (; from <= xx; from++) PUTCHARLP(' '); @@ -2934,9 +2994,9 @@ int progress; } } wr = write(D_userfd, p, l); - if (wr <= 0) + if (wr <= 0) { - if (errno == EINTR) + if (errno == EINTR) continue; debug1("Writing to display: %d\n", errno); break; -- cgit v1.2.1 From ecab862582b966e3eaf1ad98aa75a53b43a8be05 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 30 Nov 2009 17:02:36 -0500 Subject: Use the translation table when possible in utf8 locale. --- src/display.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index 776243f..f54df38 100644 --- a/src/display.c +++ b/src/display.c @@ -617,7 +617,15 @@ int c; AddCStr(D_CE0); goto addedutf8; } - AddUtf8(c); + if (c < 0x80) + { + if (D_xtable && D_xtable[(int)(unsigned char)D_rend.font] && D_xtable[(int)(unsigned char)D_rend.font][(int)(unsigned char)c]) + AddStr(D_xtable[(int)(unsigned char)D_rend.font][(int)(unsigned char)c]); + else + AddChar(c); + } + else + AddUtf8(c); goto addedutf8; } # endif -- cgit v1.2.1 From b9a14d268112b87c77aa2933995028fbfd481e5d Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 1 Dec 2009 15:32:14 -0500 Subject: Fix a bug in windowlist navigation. --- src/help.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/help.c b/src/help.c index a6497ce..0f4b6a5 100644 --- a/src/help.c +++ b/src/help.c @@ -1005,7 +1005,7 @@ int *plen; h = wlistdata->pos; if (h == MAXWIN && Layer2Window(flayer) && Layer2Window(flayer)->w_type == W_TYPE_GROUP) break; - if (display && h != MAXWIN && wtab[h] && (wtab[h]->w_type == W_TYPE_GROUP || wtab[h] == D_fore)) + if (display && h != MAXWIN && wtab[h] && (wtab[h]->w_type == W_TYPE_GROUP) && Layer2Window(flayer) == wtab[h]) { wlistdata->group = wtab[h]; wlistdata->pos = wtab[h]->w_number; -- cgit v1.2.1 From d5666eda97fbfd704fa9896400fde875e5493998 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 5 Dec 2009 21:26:46 -0500 Subject: Don't undef here. --- src/termcap.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/termcap.c b/src/termcap.c index 2545531..42f6a73 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -31,8 +31,6 @@ #include "screen.h" #include "extern.h" -#undef DEBUGG - extern struct display *display, *displays; extern int real_uid, real_gid, eff_uid, eff_gid; extern struct term term[]; /* terminal capabilities */ -- cgit v1.2.1 From 2199ead34441dd5291ffecb737b9ff4e7ae47f0d Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 5 Dec 2009 21:53:52 -0500 Subject: Revamp the display list. Revamp the display list (in works). The future changes are expected to add full mouse control, and perhaps some other utility functions (e.g. detaching a display, changing permissions perhaps? etc.) --- src/ChangeLog | 1 + src/Makefile.in | 5 +- src/display.c | 2 +- src/extern.h | 2 +- src/help.c | 190 +---------------------------------- src/input.c | 9 +- src/layer.c | 24 +++++ src/layer.h | 12 ++- src/list_display.c | 286 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/mark.c | 13 +-- src/misc.c | 5 +- src/process.c | 2 +- src/term.c | 7 +- 13 files changed, 343 insertions(+), 215 deletions(-) create mode 100644 src/list_display.c diff --git a/src/ChangeLog b/src/ChangeLog index 90fd67f..1ce226c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -60,6 +60,7 @@ Version 4.1.0 (??/??/20??): * Tab-completion for command input. * Some more readline-like bindings in input mode (e.g. ^W, ^D, ^P, ^N etc.) * Fix displaying unicode characters in the caption/hardstatus on UTF8 locale. + * A revamped displays list (for 'displays' command) In-Progress: * Scripting support (thanks to Google Summer of Code 2009 project by Rui Guo) diff --git a/src/Makefile.in b/src/Makefile.in index 903aae3..8120726 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -61,7 +61,8 @@ CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \ search.c tty.c term.c window.c utmp.c loadav.c putenv.c help.c \ termcap.c input.c attacher.c pty.c process.c display.c comm.c \ kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \ - sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c + sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c \ + list_display.c OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ termcap.o input.o attacher.o pty.o process.o display.o comm.o \ @@ -302,7 +303,7 @@ loadav.o: layout.h viewport.h canvas.h loadav.c config.h screen.h os.h osdef.h a comm.h layer.h term.h image.h display.h window.h extern.h putenv.o: layout.h viewport.h canvas.h putenv.c config.h help.o: layout.h viewport.h canvas.h help.c config.h screen.h os.h osdef.h ansi.h acls.h \ - comm.h layer.h term.h image.h display.h window.h extern.h + comm.h layer.h term.h image.h display.h window.h extern.h list_display.c termcap.o: layout.h viewport.h canvas.h termcap.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h input.o: layout.h viewport.h canvas.h input.c config.h screen.h os.h osdef.h ansi.h acls.h \ diff --git a/src/display.c b/src/display.c index f54df38..5a461ba 100644 --- a/src/display.c +++ b/src/display.c @@ -3426,7 +3426,7 @@ char *data; y = bp[4] - 33; if (x >= D_forecv->c_xs && x <= D_forecv->c_xe && y >= D_forecv->c_ys && y <= D_forecv->c_ye) { - if (D_fore && D_fore->w_mouse) + if (D_fore && (D_fore->w_mouse || (D_mousetrack && D_forecv->c_layer->l_mode == 1))) { /* Send clicks only if the window is expecting clicks */ x -= D_forecv->c_xoff; diff --git a/src/extern.h b/src/extern.h index 28eb105..98cb2df 100644 --- a/src/extern.h +++ b/src/extern.h @@ -348,7 +348,7 @@ extern char *InStr __P((char *, const char *)); extern char *strerror __P((int)); #endif extern void centerline __P((char *, int)); -extern void leftline __P((char *, int)); +extern void leftline __P((char *, int, struct mchar *)); extern char *Filename __P((char *)); extern char *stripdev __P((char *)); #ifdef NEED_OWN_BCOPY diff --git a/src/help.c b/src/help.c index 0f4b6a5..cbd7bf8 100644 --- a/src/help.c +++ b/src/help.c @@ -680,183 +680,7 @@ int y, xs, xe, isblank; } - -/* -** -** here is all the displays stuff -** -*/ - -#ifdef MULTI - -static void DisplaysProcess __P((char **, int *)); -static void DisplaysRedisplayLine __P((int, int, int, int)); -static void displayspage __P((void)); - -struct displaysdata -{ - int dummy_element_for_solaris; -}; - -static struct LayFuncs DisplaysLf = -{ - DisplaysProcess, - HelpAbort, - DisplaysRedisplayLine, - DefClearLine, - DefRewrite, - DefResize, - DefRestore -}; - -static void -DisplaysProcess(ppbuf, plen) -char **ppbuf; -int *plen; -{ - int done = 0; - - ASSERT(flayer); - while (!done && *plen > 0) - { - switch (**ppbuf) - { - case ' ': - displayspage(); - break; - case '\r': - case '\n': - HelpAbort(); - done = 1; - break; - default: - break; - } - ++*ppbuf; - --*plen; - } -} - - -void -display_displays() -{ - if (flayer->l_width < 10 || flayer->l_height < 5) - { - LMsg(0, "Window size too small for displays page"); - return; - } - if (InitOverlayPage(sizeof(struct displaysdata), &DisplaysLf, 0)) - return; - flayer->l_x = 0; - flayer->l_y = flayer->l_height - 1; - displayspage(); -} - -/* - * layout of the displays page is as follows: - -xterm 80x42 jnweiger@/dev/ttyp4 0(m11) &rWx -facit 80x24 nb mlschroe@/dev/ttyhf 11(tcsh) rwx -xterm 80x42 jnhollma@/dev/ttyp5 0(m11) &R.x - - | | | | | | | | ¦___ window permissions - | | | | | | | | (R. is locked r-only, - | | | | | | | | W has wlock) - | | | | | | | |___ Window is shared - | | | | | | |___ Name/Title of window - | | | | | |___ Number of window - | | | | |___ Name of the display (the attached device) - | | | |___ Username who is logged in at the display - | | |___ Display is in nonblocking mode. Shows 'NB' if obuf is full. - | |___ Displays geometry as width x height. - |___ the terminal type known by screen for this display. - - */ - -static void -displayspage() -{ - int y, l; - char tbuf[80]; - struct display *d; - struct win *w; - static char *blockstates[5] = {"nb", "NB", "Z<", "Z>", "BL"}; - - LClearAll(flayer, 0); - - leftline("term-type size user interface window", 0); - leftline("---------- ------- ---------- ----------------- ----------", 1); - y = 2; - - for (d = displays; d; d = d->d_next) - { - w = d->d_fore; - - if (y >= flayer->l_height - 3) - break; - sprintf(tbuf, "%-10.10s%4dx%-4d%10.10s@%-16.16s%s", - d->d_termname, d->d_width, d->d_height, d->d_user->u_name, - d->d_usertty, - (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); - - if (w) - { - l = 10 - strlen(w->w_title); - if (l < 0) - l = 0; - sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c", - w->w_number, w->w_title, l, "", - /* w->w_dlist->next */ 0 ? '&' : ' ', - /* - * The rwx triple: - * -,r,R no read, read, read only due to foreign wlock - * -,.,w,W no write, write suppressed by foreign wlock, - * write, own wlock - * -,x no execute, execute - */ -#ifdef MULTIUSER - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : - ((w->w_wlock == WLOCK_OFF || d->d_user == w->w_wlockuser) ? - 'r' : 'R')), - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : - ((w->w_wlock == WLOCK_OFF) ? 'w' : - ((d->d_user == w->w_wlockuser) ? 'W' : 'v'))), - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : 'x') -#else - 'r', 'w', 'x' -#endif - ); - } - leftline(tbuf, y); - y++; - } - sprintf(tbuf,"[Press Space %s Return to end.]", - 1 ? "to refresh;" : "or"); - centerline(tbuf, flayer->l_height - 2); - LaySetCursor(); -} - -static void -DisplaysRedisplayLine(y, xs, xe, isblank) -int y, xs, xe, isblank; -{ - ASSERT(flayer); - if (y < 0) - { - displayspage(); - return; - } - if (y != 0 && y != flayer->l_height - 1) - return; - if (isblank) - return; - LClearArea(flayer, xs, y, xe, y, 0, 0); - /* To be filled in... */ -} - -#endif /* MULTI */ - +#include "list_display.c" /* ** @@ -1026,6 +850,8 @@ int *plen; if (h != MAXWIN) SwitchWindow(h); break; + case 0222: /* Mouse event */ + break; case 0033: case 0007: h = wlistdata->start; @@ -1358,6 +1184,7 @@ struct win *group; if (InitOverlayPage(sizeof(*wlistdata), &WListLf, 0)) return; wlistdata = (struct wlistdata *)flayer->l_data; + flayer->l_mode = 1; flayer->l_x = 0; flayer->l_y = flayer->l_height - 1; wlistdata->start = onblank && p ? p->w_number : -1; @@ -1484,15 +1311,6 @@ WListLinkChanged() display = olddisplay; } -int -InWList() -{ - if (flayer && flayer->l_layfn == &WListLf) - return 1; - return 0; -} - - /* ** diff --git a/src/input.c b/src/input.c index 165a4c8..98bef8a 100644 --- a/src/input.c +++ b/src/input.c @@ -147,6 +147,7 @@ int data; } if (InitOverlayPage(sizeof(*inpdata), &InpLf, 1)) return; + flayer->l_mode = 1; inpdata = (struct inpdata *)flayer->l_data; inpdata->inpmaxlen = len; inpdata->inpfinfunc = finfunc; @@ -478,11 +479,3 @@ int y, xs, xe, isblank; } } -int -InInput() -{ - if (flayer && flayer->l_layfn == &InpLf) - return 1; - return 0; -} - diff --git a/src/layer.c b/src/layer.c index a3ffb3e..8b94b99 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1115,3 +1115,27 @@ ExitOverlayPage() LayRestore(); LaySetCursor(); } + +int +LayProcessMouse(struct layer *l, unsigned char ch) +{ + /* XXX: Make sure the layer accepts mouse events */ + int len; + + if (l->l_mouseevent.len >= sizeof(l->l_mouseevent.buffer)) + return -1; + + len = l->l_mouseevent.len++; + l->l_mouseevent.buffer[len] = (len > 0 ? ch - 33 : ch); + return (l->l_mouseevent.len == sizeof(l->l_mouseevent.buffer)); +} + +int +LayProcessMouseSwitch(struct layer *l, int s) +{ + if ((l->l_mouseevent.start = s)) + { + l->l_mouseevent.len = 0; + } +} + diff --git a/src/layer.h b/src/layer.h index fc6d191..163b213 100644 --- a/src/layer.h +++ b/src/layer.h @@ -57,11 +57,21 @@ struct layer int l_y; int l_encoding; struct LayFuncs *l_layfn; - char *l_data; + void *l_data; struct layer *l_next; /* layer stack, should be in data? */ struct layer *l_bottom; /* bottom element of layer stack */ int l_blocking; + int l_mode; /* non-zero == edit mode */ + + struct { + unsigned char buffer[3]; /* [0]: the button + [1]: x + [2]: y + */ + int len; + int start; + } l_mouseevent; }; #define LayProcess (*flayer->l_layfn->lf_LayProcess) diff --git a/src/list_display.c b/src/list_display.c new file mode 100644 index 0000000..4db8a7f --- /dev/null +++ b/src/list_display.c @@ -0,0 +1,286 @@ +/* Copyright (c) 2008, 2009 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Micah Cowan (micah@cowan.name) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +/* Deals with the list of displays */ + +#ifdef MULTI + +struct displaysdata +{ + struct display *selected; /* The selected display */ + struct display *current; /* The current display (that's showing this list) */ +}; + +static void DisplaysProcess __P((char **, int *)); +static void DisplaysRedisplayLine __P((int, int, int, int)); +static void displayspage __P((struct displaysdata *)); + +static struct LayFuncs DisplaysLf = +{ + DisplaysProcess, + HelpAbort, + DisplaysRedisplayLine, + DefClearLine, + DefRewrite, + DefResize, + DefRestore +}; + +void +display_displays() +{ + struct displaysdata *ddata; + if (flayer->l_width < 10 || flayer->l_height < 5) + { + LMsg(0, "Window size too small for displays page"); + return; + } + if (InitOverlayPage(sizeof(struct displaysdata), &DisplaysLf, 0)) + return; + flayer->l_mode = 1; + flayer->l_x = 0; + flayer->l_y = flayer->l_height - 1; + ddata = flayer->l_data; + ddata->current = display; + ddata->selected = display; + displayspage(ddata); +} + +static void +display_list_change(struct displaysdata *ddata, int dir) +{ + struct display *d; + for (d = displays; d; d = d->d_next) + { + if (dir == -1 && d->d_next == ddata->selected) + { + ddata->selected = d; + break; + } + else if (dir == 1 && d == ddata->selected && d->d_next) + { + ddata->selected = d->d_next; + break; + } + } + + if (d) + { + /* Selection changed */ + displayspage(ddata); + } +} + +static void +DisplaysProcess(ppbuf, plen) +char **ppbuf; +int *plen; +{ + int done = 0; + + ASSERT(flayer); + while (!done && *plen > 0) + { + unsigned char ch = (unsigned char)**ppbuf; + ++*ppbuf; + --*plen; + if (flayer->l_mouseevent.start) + { + int r = LayProcessMouse(flayer, ch); + if (r == -1) + LayProcessMouseSwitch(flayer, 0); + else + { + if (r) + ch = 0222; + else + continue; + } + } + switch (ch) + { + case ' ': + displayspage(flayer->l_data); + break; + case '\r': + case '\n': + HelpAbort(); + done = 1; + break; + + case 0220: /* up */ + case 16: /* ^P like emacs */ + case 'k': + display_list_change(flayer->l_data, -1); + break; + + case 0216: /* down */ + case 14: /* ^N like emacs */ + case 'j': + display_list_change(flayer->l_data, 1); + break; + + case 0222: /* mouse event */ + if (flayer->l_mouseevent.start) + { + /* All the data is available to process the mouse event. */ + int button = flayer->l_mouseevent.buffer[0]; + if (button == 'a') + { + /* Scroll down */ + display_list_change(flayer->l_data, 1); + } + else if (button == '`') + { + /* Scroll up */ + display_list_change(flayer->l_data, -1); + } + LayProcessMouseSwitch(flayer, 0); + } + else + LayProcessMouseSwitch(flayer, 1); + break; + + default: + break; + } + } +} + + +/* + * layout of the displays page is as follows: + +xterm 80x42 jnweiger@/dev/ttyp4 0(m11) &rWx +facit 80x24 nb mlschroe@/dev/ttyhf 11(tcsh) rwx +xterm 80x42 jnhollma@/dev/ttyp5 0(m11) &R.x + + | | | | | | | | ¦___ window permissions + | | | | | | | | (R. is locked r-only, + | | | | | | | | W has wlock) + | | | | | | | |___ Window is shared + | | | | | | |___ Name/Title of window + | | | | | |___ Number of window + | | | | |___ Name of the display (the attached device) + | | | |___ Username who is logged in at the display + | | |___ Display is in nonblocking mode. Shows 'NB' if obuf is full. + | |___ Displays geometry as width x height. + |___ the terminal type known by screen for this display. + + */ + +static void +displayspage(ddata) +struct displaysdata *ddata; +{ + int y, l; + char tbuf[80]; + struct display *d; + struct win *w; + static char *blockstates[5] = {"nb", "NB", "Z<", "Z>", "BL"}; + struct mchar m_current = mchar_blank; + m_current.attr = A_BD; + + if (!ddata) + return; + + LClearAll(flayer, 0); + + leftline("term-type size user interface window Perms", 0, 0); + leftline("---------- ------- ---------- ----------------- ---------- -----", 1, 0); + y = 2; + + for (d = displays; d; d = d->d_next) + { + struct mchar *mc; + w = d->d_fore; + + if (y >= flayer->l_height - 3) + break; + sprintf(tbuf, "%-10.10s%4dx%-4d%10.10s@%-16.16s%s", + d->d_termname, d->d_width, d->d_height, d->d_user->u_name, + d->d_usertty, + (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); + + if (w) + { + l = 10 - strlen(w->w_title); + if (l < 0) + l = 0; + sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c", + w->w_number, w->w_title, l, "", + /* w->w_dlist->next */ 0 ? '&' : ' ', + /* + * The rwx triple: + * -,r,R no read, read, read only due to foreign wlock + * -,.,w,W no write, write suppressed by foreign wlock, + * write, own wlock + * -,x no execute, execute + */ +#ifdef MULTIUSER + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : + ((w->w_wlock == WLOCK_OFF || d->d_user == w->w_wlockuser) ? + 'r' : 'R')), + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : + ((w->w_wlock == WLOCK_OFF) ? 'w' : + ((d->d_user == w->w_wlockuser) ? 'W' : 'v'))), + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : 'x') +#else + 'r', 'w', 'x' +#endif + ); + } + leftline(tbuf, y, d == ddata->selected ? &mchar_so : d == ddata->current ? &m_current : 0); + y++; + } + sprintf(tbuf,"[Press Space %s Return to end.]", + 1 ? "to refresh;" : "or"); + centerline(tbuf, flayer->l_height - 2); + LaySetCursor(); +} + +static void +DisplaysRedisplayLine(y, xs, xe, isblank) +int y, xs, xe, isblank; +{ + ASSERT(flayer); + if (y < 0) + { + displayspage(flayer->l_data); + return; + } + if (y != 0 && y != flayer->l_height - 1) + return; + if (isblank) + return; + LClearArea(flayer, xs, y, xe, y, 0, 0); + /* To be filled in... */ +} + +#endif /* MULTI */ + diff --git a/src/mark.c b/src/mark.c index ff8e583..e8763e6 100644 --- a/src/mark.c +++ b/src/mark.c @@ -502,6 +502,7 @@ MarkRoutine() if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1)) return; flayer->l_encoding = fore->w_encoding; + flayer->l_mode = 1; markdata = (struct markdata *)flayer->l_data; markdata->md_user = D_user; /* XXX: Correct? */ markdata->md_window = fore; @@ -615,13 +616,13 @@ int *inlenp; case 'F': /* fall through */ case 't': /* fall through */ case 'T': /* fall through */ - /* + /* * Set f_cmd to do a search on the next key stroke. * If we break, rep_cnt will be reset, so we * continue instead. It might be cleaner to * store the rep_count in f_cmd and * break here so later followon code will be - * hit. + * hit. */ markdata->f_cmd.flag = 1; markdata->f_cmd.direction = od; @@ -1445,14 +1446,6 @@ int n; return n; } -int -InMark() -{ - if (flayer && flayer->l_layfn == &MarkLf) - return 1; - return 0; -} - void MakePaster(pa, buf, len, bufiscopy) struct paster *pa; diff --git a/src/misc.c b/src/misc.c index 9d7c13d..7bc06f6 100644 --- a/src/misc.c +++ b/src/misc.c @@ -125,9 +125,10 @@ int y; } void -leftline(str, y) +leftline(str, y, rend) char *str; int y; +struct mchar *rend; { int l, n; struct mchar mchar_dol; @@ -139,7 +140,7 @@ int y; l = n = strlen(str); if (n > flayer->l_width - 1) n = flayer->l_width - 1; - LPutStr(flayer, str, n, &mchar_blank, 0, y); + LPutStr(flayer, str, n, rend ? rend : &mchar_blank, 0, y); if (n != l) LPutChar(flayer, &mchar_dol, n, y); } diff --git a/src/process.c b/src/process.c index 27877c2..8788ea8 100644 --- a/src/process.c +++ b/src/process.c @@ -6338,7 +6338,7 @@ int i; fore = D_fore; act = 0; #ifdef COPY_PASTE - if (InMark() || InInput() || InWList()) + if (flayer && flayer->l_mode == 1) act = i < KMAP_KEYS+KMAP_AKEYS ? &mmtab[i] : &kmap_exts[i - (KMAP_KEYS+KMAP_AKEYS)].mm; #endif if ((!act || act->nr == RC_ILLEGAL) && !D_mapdefault) diff --git a/src/term.c b/src/term.c index 05122db..0df58d3 100644 --- a/src/term.c +++ b/src/term.c @@ -176,11 +176,12 @@ struct term term[T_N] = { "eA", T_STR }, { "XC", T_STR }, -/* mouse */ - { "Km", T_STR }, - /* keycaps */ /* define T_CAPS */ + +/* mouse */ + { "Km", T_STR }, KMAPDEF("\033[M") KMAPMDEF("\222") + /* nolist */ { "k0", T_STR }, KMAPDEF("\033[10~") { "k1", T_STR }, KMAPDEF("\033OP") -- cgit v1.2.1 From b28f29ad15262fd6beded97811f301c22bf11841 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 6 Dec 2009 00:46:36 -0500 Subject: Mouse clicks to place a mark in copy-mode. With mousetrack on, it's now possible to leave a mark using a left-click in copy mode, or scroll using the scroll wheel. --- src/ChangeLog | 4 +++- src/mark.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 1ce226c..5b7aeb7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -19,7 +19,9 @@ Version 4.1.0 (??/??/20??): * 'group' for moving window(s) into a group. * 'defmousetrack' and 'mousetrack', to turn on/off mouse-tracking for displays. It's turned off by default. With mouse-tracking turned on, it's - possible to switch to a region ('focus') using mouse clicks. Additional + possible to switch to a region ('focus') using mouse clicks. It's also + possible to select a text region in copy-mode using a mouse click to place + a mark and the scroll wheel to scroll through the buffer. Additional features might be to allow clicking on window-titles in the caption to switch to that window. diff --git a/src/mark.c b/src/mark.c index e8763e6..ce94293 100644 --- a/src/mark.c +++ b/src/mark.c @@ -561,19 +561,22 @@ int *inlenp; in_mark = 1; while (in_mark && (inlen /* || extrap */)) { -/* - if (extrap) - { - od = *extrap++; - if (*extrap == 0) - extrap = 0; - } - else -*/ + unsigned char ch = (unsigned char )*pt++; + inlen--; + if (flayer->l_mouseevent.start) { - od = mark_key_tab[(int)(unsigned char)*pt++]; - inlen--; + int r = LayProcessMouse(flayer, ch); + if (r == -1) + LayProcessMouseSwitch(flayer, 0); + else + { + if (r) + ch = 0222; + else + continue; + } } + od = mark_key_tab[(int)ch]; rep_cnt = markdata->rep_cnt; if (od >= '0' && od <= '9' && !markdata->f_cmd.flag) { @@ -610,7 +613,8 @@ int *inlenp; } } - switch (od) +processchar: + switch (od) { case 'f': /* fall through */ case 'F': /* fall through */ @@ -1041,6 +1045,39 @@ int *inlenp; in_mark = 0; break; } + + case 0222: + if (flayer->l_mouseevent.start) + { + int button = flayer->l_mouseevent.buffer[0]; + if (button == 'a') + { + /* Scroll down */ + od = 'j'; + } + else if (button == '`') + { + /* Scroll up */ + od = 'k'; + } + else if (button == ' ') + { + /* Left click */ + cx = flayer->l_mouseevent.buffer[1]; + cy = D2W(flayer->l_mouseevent.buffer[2]); + revto(cx, cy); + od = ' '; + } + else + od = 0; + LayProcessMouseSwitch(flayer, 0); + if (od) + goto processchar; + } + else + LayProcessMouseSwitch(flayer, 1); + break; + default: MarkAbort(); LMsg(0, "Copy mode aborted"); -- cgit v1.2.1 From e8d36bf10b784da5d7ba9a503c77e2e4688c6cda Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 7 Dec 2009 22:01:08 -0500 Subject: Refresh cleverly to improve scrolling speed. This should fix a lot of complaints about slow scrolling in vertical splits. The idea is to update the display once at the end of a screen write, rather than a lot of time during the write, which was the root of the slowness. It is possible that LayPauseUpdateRegion needs to be called in a few more places, but this works for now for the tests I have done. --- src/layer.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/layer.h | 29 ++++++++++++ src/window.c | 4 ++ 3 files changed, 181 insertions(+) diff --git a/src/layer.c b/src/layer.c index 8b94b99..2543527 100644 --- a/src/layer.c +++ b/src/layer.c @@ -96,6 +96,9 @@ int x, y; struct viewport *vp; int x2, y2; + if (l->l_pause.d) + return; + #ifdef HAVE_BRAILLE if (bd.bd_refreshing) return; @@ -143,6 +146,11 @@ struct mline *ol; if (n == 0) return; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, xs, xe, y, y); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -194,6 +202,11 @@ int bce; int ys2, ye2, xs2, xe2; if (n == 0) return; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, 0, l->l_width - 1, ys, ye); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -257,6 +270,11 @@ struct mline *ol; struct mchar *c2, cc; struct mline *rol; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, x, l->l_width - 1, y, y); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -314,6 +332,13 @@ int x, y; return; } #endif + + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, x, x, y, y); + return; + } + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) { display = cv->c_display; @@ -355,6 +380,12 @@ int x, y; return; } #endif + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, x, x + n - 1, y, y); + return; + } + for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -415,6 +446,11 @@ int x, y; return; } #endif + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, x, x + n - 1, y, y); + return; + } len = strlen(s); if (len > n) len = n; @@ -467,6 +503,11 @@ struct mline *ol; xs = l->l_width - 1; if (xe >= l->l_width) xe = l->l_width - 1; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, xs, xe, y, y); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) for (vp = cv->c_vplist; vp; vp = vp->v_next) { @@ -511,6 +552,11 @@ int uself; xs = l->l_width - 1; if (xe >= l->l_width) xe = l->l_width - 1; + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, xs, xe, ys, ye); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) { display = cv->c_display; @@ -580,6 +626,11 @@ int isblank; return; } #endif + if (l->l_pause.d) + { + LayPauseUpdateRegion(l, xs, xe, y, y); + return; + } for (cv = l->l_cvlist; cv; cv = cv->c_lnext) { display = cv->c_display; @@ -656,6 +707,13 @@ int ins; int yy, y2, yy2, top2, bot2; int bce; + if (l->l_pause.d) + { + /* XXX: 'y'? */ + LayPauseUpdateRegion(l, 0, l->l_width - 1, top, bot); + return; + } + #ifdef COLOR bce = rend_getbg(c); #else @@ -1139,3 +1197,93 @@ LayProcessMouseSwitch(struct layer *l, int s) } } +void LayPause(layer, pause) +struct layer *layer; +int pause; +{ + struct canvas *cv; + struct display *olddisplay = display; + + pause = !!pause; + + if (layer->l_pause.d == pause) + return; + + if ((layer->l_pause.d = pause)) + { + /* Start pausing */ + layer->l_pause.top = layer->l_pause.bottom = + layer->l_pause.left = layer->l_pause.right = -1; + return; + } + + /* Unpause. So refresh the regions in the displays! */ + if (layer->l_pause.top == -1 && + layer->l_pause.bottom == -1 && + layer->l_pause.left == -1 && + layer->l_pause.right == -1) + return; + + for (cv = layer->l_cvlist; cv; cv = cv->c_lnext) + { + struct viewport *vp; + + display = cv->c_display; + + for (vp = cv->c_vplist; vp; vp = vp->v_next) + { + int xs = layer->l_pause.left + vp->v_xoff; + int xe = layer->l_pause.right + vp->v_xoff; + int ys = layer->l_pause.top + vp->v_yoff; + int ye = layer->l_pause.bottom + vp->v_yoff; + + if (xs < vp->v_xs) xs = vp->v_xs; + if (xe > vp->v_xe) xe = vp->v_xe; + if (ys < vp->v_ys) ys = vp->v_ys; + if (ye > vp->v_ye) ye = vp->v_ye; + + if (xs <= xe && ys <= ye) + RefreshArea(xs, ys, xe, ye, 0); + } + + if (cv == D_forecv) + { + int cx = layer->l_x + cv->c_xoff; + int cy = layer->l_y + cv->c_yoff; + + if (cx < cv->c_xs) cx = cv->c_xs; + if (cy < cv->c_ys) cy = cv->c_ys; + if (cx > cv->c_xe) cx = cv->c_xe; + if (cy > cv->c_ye) cy = cv->c_ye; + + GotoPos(cx, cy); + } + } + + olddisplay = display; +} + +void +LayPauseUpdateRegion(layer, xs, xe, ys, ye) +struct layer *layer; +int xs, xe; +int ys, ye; +{ + if (!layer->l_pause.d) + return; + + if (ye >= layer->l_height) + ye = layer->l_height - 1; + if (xe >= layer->l_width) + xe = layer->l_width - 1; + + if (layer->l_pause.top == -1 || layer->l_pause.top > ys) + layer->l_pause.top = ys; + if (layer->l_pause.bottom < ye) + layer->l_pause.bottom = ye; + if (layer->l_pause.left == -1 || layer->l_pause.left > xs) + layer->l_pause.left = xs; + if (layer->l_pause.right < xe) + layer->l_pause.right = xe; +} + diff --git a/src/layer.h b/src/layer.h index 163b213..13d745e 100644 --- a/src/layer.h +++ b/src/layer.h @@ -72,6 +72,16 @@ struct layer int len; int start; } l_mouseevent; + + struct { + int d : 1; /* Is the output for the layer blocked? */ + + /* After unpausing, what region should we refresh? */ + int top; + int bottom; + int left; + int right; + } l_pause; }; #define LayProcess (*flayer->l_layfn->lf_LayProcess) @@ -123,3 +133,22 @@ struct layer #endif /* SCREEN_LAYER_H */ +/** + * (Un)Pauses a layer. + * + * @param layer The layer that should be (un)paused. + * @param pause Should we pause the layer? + */ +void LayPause __P((struct layer *layer, int pause)); + +/** + * Update the region to refresh after a layer is unpaused. + * + * @param layer The layer. + * @param xs The left-end of the region. + * @param xe The right-end of the region. + * @param ys The top-end of the region. + * @param ye The bottom-end of the region. + */ +void LayPauseUpdateRegion __P((struct layer *layer, int xs, int xe, int ys, int ye)); + diff --git a/src/window.c b/src/window.c index fb271d2..ea406a5 100644 --- a/src/window.c +++ b/src/window.c @@ -1906,7 +1906,11 @@ char *data; p->w_pwin->p_inlen += len; } #endif + + LayPause(&p->w_layer, 1); WriteString(p, bp, len); + LayPause(&p->w_layer, 0); + return; } -- cgit v1.2.1 From 17b43961982caa5132d98544addc4de3f89103db Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 8 Dec 2009 06:31:33 -0500 Subject: Fix end key. Properly fix the problem with end key for applications inside screen. This fixes savannah bug#23601, debian bug #484647 and a gentoo bug. --- src/term.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/term.c b/src/term.c index 0df58d3..991de1b 100644 --- a/src/term.c +++ b/src/term.c @@ -240,7 +240,7 @@ struct term term[T_N] = { "kh", T_STR }, KMAPDEF("\033[1~") KMAPMDEF("\201") { "@1", T_STR }, { "kH", T_STR }, KMAPDEF("\033[4~") KMAPMDEF("\205") - { "@7", T_STR }, + { "@7", T_STR }, KMAPDEF("\033[4~") KMAPMDEF("\205") { "kN", T_STR }, KMAPDEF("\033[6~") KMAPMDEF("\006") { "kP", T_STR }, KMAPDEF("\033[5~") KMAPMDEF("\002") { "kI", T_STR }, KMAPDEF("\033[2~") -- cgit v1.2.1 From acd9b12b446f8baa673d928b4421948e07b7265e Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 8 Dec 2009 07:01:06 -0500 Subject: Remember to update the region containing the cursor. --- src/layer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/layer.c b/src/layer.c index 2543527..067d2ef 100644 --- a/src/layer.c +++ b/src/layer.c @@ -97,7 +97,10 @@ int x, y; int x2, y2; if (l->l_pause.d) - return; + { + LayPauseUpdateRegion(l, x, x, y, y); + return; + } #ifdef HAVE_BRAILLE if (bd.bd_refreshing) -- cgit v1.2.1 From 8284ab11992952b215f191990ea1da84a7f70e7c Mon Sep 17 00:00:00 2001 From: Emanuele Giaquinta Date: Wed, 9 Dec 2009 12:05:11 -0500 Subject: Combining characters have 0 onscreen width. --- src/display.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/display.c b/src/display.c index 5a461ba..0707805 100644 --- a/src/display.c +++ b/src/display.c @@ -2133,9 +2133,12 @@ strlen_onscreen(unsigned char *c, unsigned char *end) c--; } while (v < 0 && (!end || c < end)); - if (utf8_isdouble(v)) - len++; - len++; + if (!utf8_iscomb(v)) + { + if (utf8_isdouble(v)) + len++; + len++; + } } return len; -- cgit v1.2.1 From 0dc3a24b7bd949dc2c1709416b580828baea5b5f Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 11 Dec 2009 17:29:48 -0500 Subject: New 'dump' subcommand for 'layout'. This command will write a series of screen commands that can later be used to recreate the current layout. I think this will be pretty useful. Users like to create a layout interactively, and use it again for the next session etc. --- src/ChangeLog | 1 + src/layout.c | 33 +++++++++++++++++++++++++++++++++ src/process.c | 9 +++++++++ 3 files changed, 43 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 5b7aeb7..80d400b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -16,6 +16,7 @@ Version 4.1.0 (??/??/20??): - 'attach' - 'show' - 'remove' + - 'dump' * 'group' for moving window(s) into a group. * 'defmousetrack' and 'mousetrack', to turn on/off mouse-tracking for displays. It's turned off by default. With mouse-tracking turned on, it's diff --git a/src/layout.c b/src/layout.c index 2aed7d0..6100b5d 100644 --- a/src/layout.c +++ b/src/layout.c @@ -332,3 +332,36 @@ struct win *wi; } +static void +dump_canvas(cv, file) +struct canvas *cv; +FILE *file; +{ + struct canvas *c; + for (c = cv->c_slperp; c && c->c_slnext; c = c->c_slnext) + { + fprintf(file, "split%s\n", c->c_slorient == SLICE_HORI ? " -v" : ""); + } + + for (c = cv->c_slperp; c; c = c->c_slnext) + { + if (c->c_slperp) + dump_canvas(c, file); + else + fprintf(file, "focus\n"); + } +} + +int +LayoutDumpCanvas(cv, filename) +struct canvas *cv; +char *filename; +{ + FILE *file = secfopen(filename, "a"); + if (!file) + return 0; + dump_canvas(cv, file); + fclose(file); + return 1; +} + diff --git a/src/process.c b/src/process.c index 8788ea8..2874e7e 100644 --- a/src/process.c +++ b/src/process.c @@ -4367,6 +4367,15 @@ int key; if (lay) RemoveLayout(lay); } + else if (!strcmp(args[0], "dump")) + { + if (!display) + Msg(0, "Must have a display for 'layout dump'."); + else if (!LayoutDumpCanvas(&D_canvas, args[1] ? args[1] : "layout-dump")) + Msg(errno, "Error dumping layout."); + else + Msg(0, "Layout dumped to \"%s\"", args[1] ? args[1] : "layout-dump"); + } else Msg(0, "unknown layout subcommand"); break; -- cgit v1.2.1 From 1e4fb57b49754618dc147f397a8a72483fd6c419 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 15 Dec 2009 12:59:18 -0500 Subject: Allow adding visual notification in caption string. '%P' in caption string will set '%?' to true if the current region is in copy/paste mode. So, if you want to simply change the color etc. of your caption, prepend '%?%P%{XXX}%?' to your caption and you're set ('XXX' stands for the usual attribute/color modifier). If, on the other hand, you want to change the caption string in copy mode, change your caption string to '%?%PCaption for copy mode%:Your usual caption%?'. --- src/ChangeLog | 1 + src/doc/screen.1 | 2 ++ src/doc/screen.texinfo | 2 ++ src/mark.c | 2 ++ src/process.c | 1 + src/screen.c | 12 ++++++++++++ 6 files changed, 20 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 80d400b..0dfb9a6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -47,6 +47,7 @@ Version 4.1.0 (??/??/20??): * '%p' in caption/hardstatus string expands to the PID of the backend, and '%+p' expands to the PID of the frontend (display). * '%S' in caption/hardstatus string expands to the session name. + * '%P' in the caption string evaluates to true if the region is in copy mode. Window List: * Nested views when there are window groups (with 'windowlist -g'). diff --git a/src/doc/screen.1 b/src/doc/screen.1 index e37c4cc..a811379 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -3336,6 +3336,8 @@ month number month name .IP n window number +.IP P +sets %? to true if the current region is in copy/paste mode .IP S session name .IP s diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 6228cd4..5e265aa 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -5193,6 +5193,8 @@ month number month name @item n window number +@item P +sets %? to true if the current region is in copy/paste mode @item s seconds @item S diff --git a/src/mark.c b/src/mark.c index ce94293..83eaed1 100644 --- a/src/mark.c +++ b/src/mark.c @@ -1035,6 +1035,7 @@ processchar: LAY_CALL_UP(LRefreshAll(flayer, 0)); } ExitOverlayPage(); + WindowChanged(fore, 'P'); if (append_mode) LMsg(0, "Appended %d characters to buffer", newcopylen); @@ -1277,6 +1278,7 @@ MarkAbort() rem(markdata->x1, markdata->y1, markdata->cx, markdata->cy, redisp, (char *)0, yend); } ExitOverlayPage(); + WindowChanged(fore, 'P'); } diff --git a/src/process.c b/src/process.c index 2874e7e..0e835f0 100644 --- a/src/process.c +++ b/src/process.c @@ -2231,6 +2231,7 @@ int key; break; } MarkRoutine(); + WindowChanged(fore, 'P'); break; case RC_HISTORY: { diff --git a/src/screen.c b/src/screen.c index e8f4cac..10819c9 100644 --- a/src/screen.c +++ b/src/screen.c @@ -118,6 +118,8 @@ int VBellWait, MsgWait, MsgMinWait, SilenceWait; extern struct acluser *users; extern struct display *displays, *display; +extern struct LayFuncs MarkLf; + extern int visual_bell; #ifdef COPY_PASTE @@ -2804,6 +2806,16 @@ int rec; if (minusflg) qmflag = 1; break; + case 'P': + p--; + if (display && ev && ev != &D_hstatusev) /* Hack */ + { + /* Is the layer in the current canvas in copy mode? */ + struct canvas *cv = (struct canvas *)ev->data; + if (ev == &cv->c_captev && cv->c_layer->l_layfn == &MarkLf) + qmflag = 1; + } + break; case '>': truncpos = p - winmsg_buf; truncper = num > 100 ? 100 : num; -- cgit v1.2.1 From e0ac7e1651c48358b4b6e3734f106c06076e0220 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 15 Dec 2009 16:17:33 -0500 Subject: GNUize. --- src/acconfig.h | 2 +- src/ansi.h | 2 +- src/braille.h | 2 +- src/canvas.h | 2 +- src/configure.in | 2 +- src/display.h | 2 +- src/extern.h | 2 +- src/image.h | 2 +- src/layer.h | 2 +- src/layout.h | 2 +- src/logfile.h | 2 +- src/mark.h | 2 +- src/os.h | 2 +- src/osdef.h.in | 2 +- src/patchlevel.h | 4 ++-- src/sched.h | 2 +- src/screen.h | 2 +- src/viewport.h | 2 +- src/window.h | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/acconfig.h b/src/acconfig.h index bc324d5..4f5e2f8 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -19,7 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ diff --git a/src/ansi.h b/src/ansi.h index 270b76f..72992b4 100644 --- a/src/ansi.h +++ b/src/ansi.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #define NATTR 6 diff --git a/src/braille.h b/src/braille.h index ff5fde7..a0cb4e9 100644 --- a/src/braille.h +++ b/src/braille.h @@ -22,7 +22,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #ifdef HAVE_BRAILLE diff --git a/src/canvas.h b/src/canvas.h index 265545e..6aeb3d8 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #ifndef SCREEN_CANVAS_H diff --git a/src/configure.in b/src/configure.in index 9db3dd6..8c5762c 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. dnl -dnl $Id$ FAU +dnl $Id$ GNU dnl dnl Many thanks to David MacKenzie for writing autoconf and dnl providing a sample configure.in file for screen. diff --git a/src/display.h b/src/display.h index e3d5ad7..e8b3b80 100644 --- a/src/display.h +++ b/src/display.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #ifndef SCREEN_DISPLAY_H diff --git a/src/extern.h b/src/extern.h index 98cb2df..0eb811a 100644 --- a/src/extern.h +++ b/src/extern.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #if !defined(__GNUC__) || __GNUC__ < 2 diff --git a/src/image.h b/src/image.h index e267d91..8622534 100644 --- a/src/image.h +++ b/src/image.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ diff --git a/src/layer.h b/src/layer.h index 13d745e..5db4997 100644 --- a/src/layer.h +++ b/src/layer.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #ifndef SCREEN_LAYER_H diff --git a/src/layout.h b/src/layout.h index 2701154..065edb7 100644 --- a/src/layout.h +++ b/src/layout.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #ifndef SCREEN_LAYOUT_H diff --git a/src/logfile.h b/src/logfile.h index 51f559d..c588a32 100644 --- a/src/logfile.h +++ b/src/logfile.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ struct logfile diff --git a/src/mark.h b/src/mark.h index 5f75ed6..a275fe9 100644 --- a/src/mark.h +++ b/src/mark.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ struct markdata diff --git a/src/os.h b/src/os.h index bac2b5f..5c17c83 100644 --- a/src/os.h +++ b/src/os.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #include diff --git a/src/osdef.h.in b/src/osdef.h.in index 36964fb..2253218 100644 --- a/src/osdef.h.in +++ b/src/osdef.h.in @@ -19,7 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ /**************************************************************** diff --git a/src/patchlevel.h b/src/patchlevel.h index 86e2475..0695698 100644 --- a/src/patchlevel.h +++ b/src/patchlevel.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ /**************************************************************** @@ -530,7 +530,7 @@ * 2005-12-19, 4.00.03jw3 syntax error. */ -#define ORIGIN "FAU" +#define ORIGIN "GNU" #define REV 4 #define VERS 1 #define PATCHLEVEL 0 diff --git a/src/sched.h b/src/sched.h index fe94642..fdc3fc4 100644 --- a/src/sched.h +++ b/src/sched.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ struct event diff --git a/src/screen.h b/src/screen.h index d996def..a151e38 100644 --- a/src/screen.h +++ b/src/screen.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #include "os.h" diff --git a/src/viewport.h b/src/viewport.h index 67fa236..a19b6b8 100644 --- a/src/viewport.h +++ b/src/viewport.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #ifndef SCREEN_VIEWPORT_H diff --git a/src/window.h b/src/window.h index ed8506f..9646b6b 100644 --- a/src/window.h +++ b/src/window.h @@ -24,7 +24,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA * **************************************************************** - * $Id$ FAU + * $Id$ GNU */ #ifndef SCREEN_WINDOW_H -- cgit v1.2.1 From d11bdb4fdd5b12dc57cb62d22eafb719f55ecd38 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Tue, 15 Dec 2009 16:27:53 -0500 Subject: Various documentation updates. --- src/doc/screen.texinfo | 59 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 5e265aa..10ac31f 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -407,6 +407,10 @@ Set the title (name) for the default shell or specified program. This option is equivalent to the @code{shelltitle} command (@pxref{Shell}). +@item -T @var{term} +Set the $TERM enviroment varible using the spcified @emph{term} as +opposed to the defualt setting of @code{screen}. + @item -U Run screen in UTF-8 mode. This option tells screen that your terminal sends and understands UTF-8 encoded characters. It also sets the default @@ -974,6 +978,8 @@ Change window size to current display size. @xref{Window Size}. Set flow control behavior. @xref{Flow}. @item focus Move focus to next region. @xref{Regions}. +@item focusminsize +Force the current region to a certain size. @xref{Focusminsize}. @item gr [@var{state}] Change GR charset processing. @xref{Character Processing}. @item group [@var{grouptitle}] @@ -1044,7 +1050,7 @@ Configure logfile time-stamps. @xref{Log}. Use only the default mapping table for the next keystroke. @xref{Bindkey Control}. @item mapnotnext Don't try to do keymapping on the next keystroke. @xref{Bindkey Control}. -@item maptimeout @var{timo} +@item maptimeout @var{n} Set the inter-character timeout used for keymapping. @xref{Bindkey Control}. @item markkeys @var{string} Rebind keys in copy mode. @xref{Copy Mode Keys}. @@ -1636,7 +1642,7 @@ logout if @code{screen} was started from your login shell. The @var{message} specified here is output whenever a power detach is performed. It may be used as a replacement for a logout message or to reset baud rate, etc. -Without parameter, the current message is shown. +Without a parameter, the current message is shown. @end deffn @node Lock, Multiuser Session, Power Detach, Session Management @@ -1882,6 +1888,7 @@ which can contain different windows. * Resize:: Grow or shrink a region * Caption:: Control the window's caption * Fit:: Resize a window to fit the region +* Focusminsize:: Force a minimum size on a current region * Layout:: Manage groups of regions @end menu @@ -1974,7 +1981,7 @@ You can mix both forms by providing the string as an additional argument. @end deffn -@node Fit, Layout, Caption, Regions +@node Fit, Focusminsize, Caption, Regions @section Fit @kindex F @deffn Command fit @@ -1984,7 +1991,23 @@ command is needed because screen doesn't adapt the window size automatically if the window is displayed more than once. @end deffn -@node Layout, , Fit, Regions +@node Focusminsize, Layout, Fit, Regions +@section Focusminsize +@deffn Command focusminsize [ (width|@code{max}|@code{_}) (height|@code{max}|@code{_}) ] +(none)@* +This forces any currently selected region to be automatically +resized at least a certain @var{width} and @var{height}. All +other surrounding regions will be resized in order to accomodate. +This constraint follows everytime the @code{focus} command is +used. The @code{resize} command can be used to increase either +dimension of a region, but never below what is set with +@code{focusminsize}. The underscore @samp{_} is a synonym for +@code{max}. Setting a @var{width} and @var{height} of @code{0 0} +(zero zero) will undo any constraints and allow for manual resizing. +Without any parameters, the minimum width and height is shown. +@end deffn + +@node Layout, , Focusminsize, Regions @section Layout @cindex layout Using regions, and perhaps a large enough terminal, you can create @@ -2917,7 +2940,7 @@ The default message is An empty message can be supplied to the @code{bell_msg} command to suppress output of a message line (@code{bell_msg ""}). -Without parameter, the current message is shown. +Without a parameter, the current message is shown. @end deffn @kindex C-g @@ -2941,7 +2964,7 @@ Sets the visual bell message. @var{Message} is printed to the status line if the window receives a bell character (^G), @code{vbell} is set to @samp{on} and the terminal does not support a visual bell. The default message is @samp{Wuff, Wuff!!}. -Without parameter, the current message is shown. +Without a parameter, the current message is shown. @end deffn @deffn Command vbellwait sec @@ -3001,7 +3024,7 @@ For system information use @code{time}. @deffn Command dinfo (none)@* -Show what screen thinks about your terminal. Useful if you want to know +Show what @code{screen} thinks about your terminal. Useful if you want to know why features like color or the alternate charset don't work. @end deffn @@ -3259,7 +3282,7 @@ outlined below. @subsection CR/LF @deffn Command crlf [state] (none)@* -This affects the copying of text regions with the @kbd{C-a [} command. +This affects the copying of text regions with the @code{copy} command. If it is set to @samp{on}, lines will be separated by the two character sequence @samp{CR}/@samp{LF}. Otherwise only @samp{LF} is used. @code{crlf} is off by default. @@ -3277,7 +3300,7 @@ for new windows is changed. Defaults to 100. @deffn Command scrollback num (none)@* Set the size of the scrollback buffer for the current window to -@var{num} lines. The default scrollback is 100 lines. Use @kbd{C-a i} +@var{num} lines. The default scrollback is 100 lines. Use @copy{info} to view the current setting. @end deffn @@ -3760,7 +3783,7 @@ command to activate a class. Command classes can be used to create multiple command keys or multi-character bindings. By default, most suitable commands are bound to one or more keys -(@pxref{Default Key Bindings}; for instance, the command to create a +(@pxref{Default Key Bindings}); for instance, the command to create a new window is bound to @kbd{C-c} and @kbd{c}. The @code{bind} command can be used to redefine the key bindings and to define new bindings. @end deffn @@ -3957,10 +3980,10 @@ in the default bindkey table. (none)@* Like mapdefault, but don't even look in the default bindkey table. @end deffn -@deffn Command maptimeout timo +@deffn Command maptimeout n (none)@* Set the inter-character timer for input sequence detection to a timeout -of @var{timo} ms. The default timeout is 300ms. Maptimeout with no +of @var{n} ms. The default timeout is 300ms. Maptimeout with no arguments shows the current setting. @end deffn @@ -4069,7 +4092,7 @@ Send a ^S (ASCII XOFF) to the program in the current window. @node Termcap, Message Line, Flow Control, Top @chapter Termcap -@code{screen} demands the most out of your terminal so that it can +@code{Screen} demands the most out of your terminal so that it can perform its VT100 emulation most efficiently. These functions provide means for tweaking the termcap entries for both your physical terminal and the one simulated by @code{screen}. @@ -4512,7 +4535,7 @@ template is just @samp{%}, so the mapping is straightforward: @chapter The Message Line @cindex message line -@code{screen} displays informational messages and other diagnostics in a +@code{Screen} displays informational messages and other diagnostics in a @dfn{message line} at the bottom of the screen. If your terminal has a status line defined in its termcap, screen will use this for displaying its messages, otherwise the last line of the screen will be temporarily @@ -4945,7 +4968,7 @@ like it is described in the string escapes chapter (@pxref{String Escapes}). Scr @deffn Command verbose [on|off] If verbose is switched on, the command name is echoed, whenever a window is created (or resurrected from zombie state). Default is off. -Without parameter, the current setting is shown. +Without a parameter, the current setting is shown. @end deffn @node Version, Zombie, Verbose, Miscellaneous @@ -5027,7 +5050,7 @@ the text. If the attribute is in use, the specified attribute/color modifier is also applied. If no modifier is given, the current one is deleted. See the chapter about string escapes (@pxref{String Escapes}) for the syntax of -the modifier. Screen understands two pseudo-attributes, @code{i} +the modifier. @code{Screen} understands two pseudo-attributes, @code{i} stands for high-intensity foreground color and @code{I} for high-intensity background color. @@ -5050,7 +5073,7 @@ Make bright colored text also bold. @section Setsid @deffn Command setsid state (none)@* -Normally screen uses different sessions and process groups for +Normally @code{screen} uses different sessions and process groups for the windows. If setsid is turned @code{off}, this is not done anymore and all windows will be in the same process group as the screen backend process. This also breaks job-control, so be careful. @@ -5136,7 +5159,7 @@ no arguments are given. @deffnx Command zmodem sendcmd [string] @deffnx Command zmodem recvcmd [string] (none)@* -Define zmodem support for screen. Screen understands two +Define zmodem support for @code{screen}. @code{Screen} understands two different modes when it detects a zmodem request: @code{pass} and @code{catch}. If the mode is set to @code{pass}, screen will relay all data to the attacher until the end of the -- cgit v1.2.1 From 71cd5c06c6b87547c3cb9f1274bc62b810f43565 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 17 Dec 2009 13:11:56 -0500 Subject: Fix cursor positioning after a search in copy mode The problem would show up with splits (both vertical and horizontal), because the layer wouldn't remember the position the cursor was moved to, and when screen refreshes the regions (if there's more than one), it takes the cursor to the old position. The fix is to simply remember the cursor position in the layer. --- src/mark.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mark.c b/src/mark.c index 83eaed1..c90201f 100644 --- a/src/mark.c +++ b/src/mark.c @@ -1155,6 +1155,8 @@ int tx, ty, line; if (markdata->second == 0) { + flayer->l_x = tx; + flayer->l_y = W2D(ty); LGotoPos(flayer, tx, W2D(ty)); return; } @@ -1251,6 +1253,8 @@ int tx, ty, line; #endif } } + flayer->l_x = tx; + flayer->l_y = W2D(ty); LGotoPos(flayer, tx, W2D(ty)); } -- cgit v1.2.1 From 8b2b63cebef17c8b2ba8a9e05e63a1b806578ec0 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 17 Dec 2009 15:32:12 -0500 Subject: Credit for 7f8218c. --- src/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ChangeLog b/src/ChangeLog index 0dfb9a6..4520fba 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -90,6 +90,7 @@ Version 4.1.0 (??/??/20??): * Romain Francoise * Emanuele Giaquinta * Steve Kemp + * Ryan Niebur * William Pursell * Enrico Scholz * Peter Teichman -- cgit v1.2.1 From ce4d17091290ddadf21275077f4158b222b4e426 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 17 Dec 2009 16:03:34 -0500 Subject: Allow attaching to a session whose name starts with digits. Fixes debian bug#549272. --- src/socket.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/socket.c b/src/socket.c index 7832832..68a4258 100644 --- a/src/socket.c +++ b/src/socket.c @@ -181,8 +181,21 @@ char *match; if (strncmp(match, "tty", 3) && strncmp(n, "tty", 3) == 0) n += 3; if (strncmp(match, n, matchlen)) - continue; - cmatch = (*(n + matchlen) == 0); + { + if (n == name && *match > '0' && *match <= '9') + { + while (*n >= '0' && *n <= '9') + n++; + if (*n == '.') + n++; + if (strncmp(match, n, matchlen)) + continue; + } + else + continue; + } + else + cmatch = (*(n + matchlen) == 0); debug1(" -> matched %s\n", match); } sprintf(SockPath + sdirlen, "/%s", name); -- cgit v1.2.1 From 33b7c9ca3968e42fdfb9c4e031434e4d87864146 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 17 Dec 2009 17:48:05 -0500 Subject: Wait a bit before killing a window. Wait a few seconds (10) before killing a window when wait() returns the pid for the child process in the window. This is so the output of the window doesn't get truncated in zombie mode. Micah pointed out the bug and Juergen pointed out the fix at #27061. --- src/screen.c | 19 ++++++++++++++++++- src/window.c | 14 ++++++++++++++ src/window.h | 7 +++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index 10819c9..edec34a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1475,6 +1475,14 @@ int wstat_valid; { int killit = 0; + if (p->w_destroyev.data == (char *)p) + { + wstat = p->w_exitstatus; + wstat_valid = 1; + evdeq(&p->w_destroyev); + p->w_destroyev.data = 0; + } + #if defined(BSDJOBS) && !defined(BSDWAIT) if (!wstat_valid && p->w_pid > 0) { @@ -1727,7 +1735,16 @@ DoWait() else #endif { - WindowDied(p, wstat, 1); + /* Screen will detect the window has died when the window's + * file descriptor signals EOF (which it will do when the process in + * the window terminates). So do this in a timeout of 10 seconds. + * (not doing this at all might also work) + * See #27061 for more details. + */ + p->w_destroyev.data = (char *)p; + p->w_exitstatus = wstat; + SetTimeout(&p->w_destroyev, 10 * 1000); + evenq(&p->w_destroyev); } break; } diff --git a/src/window.c b/src/window.c index ea406a5..dc9fd3a 100644 --- a/src/window.c +++ b/src/window.c @@ -93,6 +93,7 @@ static void pseu_readev_fn __P((struct event *, char *)); static void pseu_writeev_fn __P((struct event *, char *)); #endif static void win_silenceev_fn __P((struct event *, char *)); +static void win_destroyev_fn __P((struct event *, char *)); static int OpenDevice __P((char **, int, int *, char **)); static int ForkWindow __P((struct win *, char **, char *)); @@ -840,6 +841,9 @@ struct NewWindow *newwin; SetTimeout(&p->w_silenceev, p->w_silencewait * 1000); evenq(&p->w_silenceev); } + p->w_destroyev.type = EV_TIMEOUT; + p->w_destroyev.data = 0; + p->w_destroyev.handler = win_destroyev_fn; SetForeWindow(p); Activate(p->w_norefresh); @@ -1026,6 +1030,7 @@ struct win *wp; evdeq(&wp->w_readev); /* just in case */ evdeq(&wp->w_writeev); /* just in case */ evdeq(&wp->w_silenceev); + evdeq(&wp->w_destroyev); #ifdef COPY_PASTE FreePaster(&wp->w_paster); #endif @@ -2053,6 +2058,15 @@ char *data; } } +static void +win_destroyev_fn(ev, data) +struct event *ev; +char *data; +{ + struct win *p = (struct win *)ev->data; + WindowDied(p, p->w_exitstatus, 1); +} + #ifdef ZMODEM static int diff --git a/src/window.h b/src/window.h index 9646b6b..cd6c7da 100644 --- a/src/window.h +++ b/src/window.h @@ -283,6 +283,13 @@ struct win int w_alt_histidx; #endif int w_alt_current; /* Is the alternate buffer currently being used? */ + + struct event w_destroyev; /* window destroy event */ +#ifdef BSDWAIT + union wait w_exitstatus; /* window exit status */ +#else + int w_exitstatus; +#endif }; -- cgit v1.2.1 From 82b2bf34017791501ca549fd6c626a86438cdc95 Mon Sep 17 00:00:00 2001 From: Clavelito Date: Thu, 17 Dec 2009 19:22:43 -0500 Subject: Typo. --- src/ChangeLog | 1 + src/ansi.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 4520fba..2133009 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -76,6 +76,7 @@ Version 4.1.0 (??/??/20??): * Sadrul Habib Chowdhury Contributors: + * Clavelito * Dick * Gabriel * Benjamin Andresen diff --git a/src/ansi.c b/src/ansi.c index a9c7054..d15867b 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -3070,7 +3070,7 @@ int what; p = D_fore; if (inhstr || (inhstrh && p && p->w_hstatus && *p->w_hstatus && WindowChangedCheck(p->w_hstatus, what, (int *)0))) RefreshHStatus(); - if (ox != -1 && ox != -1) + if (ox != -1 && oy != -1) GotoPos(ox, oy); } display = olddisplay; @@ -3102,7 +3102,7 @@ int what; } if (got && inhstr && p == D_fore) RefreshHStatus(); - if (ox != -1 && ox != -1) + if (ox != -1 && oy != -1) GotoPos(ox, oy); } display = olddisplay; -- cgit v1.2.1 From cb86fbaf2557c64acba71425920f14d3993fa5dd Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 17 Dec 2009 22:47:49 -0500 Subject: Move the cursor in the window/display list. This will make it easier to determine which row is selected in case the rendition for standout mode is the same as the normal mode (i.e. '= dd'). Fixes debian bug #446082. --- src/help.c | 2 ++ src/list_display.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/help.c b/src/help.c index cbd7bf8..338c4cd 100644 --- a/src/help.c +++ b/src/help.c @@ -940,6 +940,8 @@ int isblank; LPutWinMsg(flayer, str, (i == pos || !isblank) ? flayer->l_width : n, mchar, xoff, y + yoff); if (xoff) LPutWinMsg(flayer, "", xoff, mchar, 0, y + yoff); + if (mchar == &mchar_so) + flayer->l_y = y + yoff; #if 0 LPutStr(flayer, str, n, i == pos ? &mchar_so : &mchar_blank, 0, y + yoff); if (i == pos || !isblank) diff --git a/src/list_display.c b/src/list_display.c index 4db8a7f..3693f01 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -222,7 +222,7 @@ struct displaysdata *ddata; if (y >= flayer->l_height - 3) break; - sprintf(tbuf, "%-10.10s%4dx%-4d%10.10s@%-16.16s%s", + sprintf(tbuf, " %-10.10s%4dx%-4d%10.10s@%-16.16s%s", d->d_termname, d->d_width, d->d_height, d->d_user->u_name, d->d_usertty, (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); @@ -256,6 +256,8 @@ struct displaysdata *ddata; ); } leftline(tbuf, y, d == ddata->selected ? &mchar_so : d == ddata->current ? &m_current : 0); + if (d == ddata->selected) + flayer->l_y = y; y++; } sprintf(tbuf,"[Press Space %s Return to end.]", -- cgit v1.2.1 From 855b8e7b98894e8f94033945720714c235911262 Mon Sep 17 00:00:00 2001 From: Jan Christoph Nordholz Date: Fri, 18 Dec 2009 16:26:41 -0500 Subject: Discourage the use of 'sessionname' (see debian bug #103771). --- src/doc/screen.1 | 5 +++-- src/doc/screen.texinfo | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index a811379..965567e 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2636,8 +2636,9 @@ Rename the current session. Note, that for \*Qscreen -list\*U the name shows up with the process-id prepended. If the argument \*Qname\*U is omitted, the name of this session is displayed. Caution: The $STY environment variables will still reflect the old name in pre-existing -shells. This may result in -confusion. +shells. This may result in confusion. Use of this command is generally +discouraged. Use the \*Q-S\*U command-line option if you want to +name a new session. The default is constructed from the tty and host names. .sp .ne 3 diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 10ac31f..43a7a55 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1847,7 +1847,9 @@ omitted, the name of this session is displayed.@* @emph{Caution}: The @code{$STY} environment variable will still reflect the old name in pre-existing shells. This may result in -confusion. The default is constructed from the tty and host names. +confusion. Use of this command is generally +discouraged. Use the @code{-S} command-line option if you want to +name a new session.The default is constructed from the tty and host names. @end deffn @node Suspend, Quit, Session Name, Session Management -- cgit v1.2.1 From 04005670529085ef8527608c0ec34b06569f0bd8 Mon Sep 17 00:00:00 2001 From: Jan Christoph Nordholz Date: Fri, 18 Dec 2009 16:28:57 -0500 Subject: Correction in TFM. The builtin 'screen' command can directly reference window IDs up to MAXWIN, not only {0-9}. Additionally mention Debian's MAXWIN default in the man and info pages. --- src/doc/screen.1 | 8 ++++---- src/doc/screen.texinfo | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 965567e..06e8e64 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2576,9 +2576,9 @@ title (a.\|k.\|a.) option (\fB\-t\fP), login options (\fB-l\fP and \fB-ln\fP) and scrollback option (\fB-h\fP ) may be specified with each command. The option (\fB-M\fP) turns monitoring on for this window. The option (\fB-L\fP) turns output logging on for this window. -If an optional number \fIn\fP in the range 0..9 is given, the window -number \fIn\fP is assigned to the newly created window (or, if this -number is already in-use, the next available number). +If an optional number \fIn\fP in the range 0..MAXWIN-1 is given, +the window number \fIn\fP is assigned to the newly created window +(or, if this number is already in-use, the next available number). If a command is specified after \*Qscreen\*U, this command (with the given arguments) is started in the window; otherwise, a shell is created. Thus, if your \*Q.screenrc\*U contains the lines @@ -2624,7 +2624,7 @@ When a new window is established, the first available number is assigned to this window. Thus, the first window can be activated by \*Qselect 0\*U. The number of windows is limited at compile-time by the MAXWIN -configuration parameter. +configuration parameter (which defaults to 40). There are two special WindowIDs, \*Q-\*U selects the internal blank window and \*Q.\*U selects the current window. The latter is useful if used with screen's \*Q-X\*U option. diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 43a7a55..8b925f7 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1217,9 +1217,9 @@ Keep dead windows. @xref{Zombie}. This section describes the commands for creating a new window for running programs. When a new window is created, the first available -number from the range 0@dots{}9 is assigned to it. +number is assigned to it. The number of windows is limited at compile-time by the MAXWIN -configuration parameter. +configuration parameter (which defaults to 40). @menu * Chdir:: Change the working directory for new windows. @@ -1262,7 +1262,7 @@ the all-capability-flag (@samp{-a}) and scrollback option (@samp{-h @var{num}}) may be specified with each command. The option (@samp{-M}) turns monitoring on for this window. The option (@samp{-L}) turns output logging on for this window. -If an optional number @var{n} in the range 0@dots{}9 is given, +If an optional number @var{n} in the range 0@dots{}MAXWIN-1 is given, the window number @var{n} is assigned to the newly created window (or, if this number is already in-use, the next available number). If a command is specified after @code{screen}, this command (with the given -- cgit v1.2.1 From 3b19a1d343e72e4fa786e9ab514d80303902a2c1 Mon Sep 17 00:00:00 2001 From: Jan Christoph Nordholz Date: Fri, 18 Dec 2009 16:31:18 -0500 Subject: Update documentation for 'nethack'. Document that there are two possible causes for 'nethack on' being activated by default... --- src/doc/screen.1 | 3 ++- src/doc/screen.texinfo | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 06e8e64..1c75652 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2289,7 +2289,8 @@ available if .I screen was compiled with the NETHACK flag defined. The default setting is then determined by the presence of the environment -variable $NETHACKOPTIONS. +variable $NETHACKOPTIONS and the file ~/.nethackrc - if either one is present, +the default is \fBon\fP. .sp .ne 3 .B next diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 8b925f7..a56e02f 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -4892,7 +4892,8 @@ to read. Anyway, standard messages often tend to be unclear as well. This option is only available if @code{screen} was compiled with the NETHACK flag defined (@pxref{Installation}). The default setting is then determined by the presence of the environment variable -@code{$NETHACKOPTIONS}. +@code{$NETHACKOPTIONS} and the file @code{~/.nethackrc} - if either one is +present, the default is @code{on}. @end deffn @node Nonblock, Number, Nethack, Miscellaneous -- cgit v1.2.1 From 1e450254e75877b6bb5cacedd5466245dbb54576 Mon Sep 17 00:00:00 2001 From: Jan Christoph Nordholz Date: Fri, 18 Dec 2009 16:33:02 -0500 Subject: Allow symlinked SockDir. I don't know why screen should not allow a symlinked SockDir; so now it does. (Note: this is one of TWO calls to lstat() the whole program has - and this one isn't even wrapped in #ifdef HAVE_LSTAT as it should.) --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index edec34a..212bee2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1078,7 +1078,7 @@ char **av; else { SockDir = SOCKDIR; - if (lstat(SockDir, &st)) + if (stat(SockDir, &st)) { n = (eff_uid == 0 && (real_uid || eff_gid == real_gid)) ? 0755 : (eff_gid != real_gid) ? 0775 : -- cgit v1.2.1 From f6c4b82a35420b679af178dbcb17f4225723dea3 Mon Sep 17 00:00:00 2001 From: Jan Christoph Nordholz Date: Fri, 18 Dec 2009 16:42:12 -0500 Subject: Clarify the manual a little. Document the fact that when calling 'env=var screen app arg' from inside screen the environment variable will go up in smoke. --- src/doc/screen.1 | 4 +++- src/doc/screen.texinfo | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 1c75652..de3df24 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -97,7 +97,9 @@ but will instead supply the command name and its arguments to the window manager (specified in the $STY environment variable) who will use it to create the new window. The above example would start the emacs editor (editing prog.c) and switch -to its window. +to its window. - Note that you cannot transport environment variables from +the invoking shell to the application (emacs in this case), because it is +forked from the parent screen process, not from the invoking shell. .PP If \*Q/etc/utmp\*U is writable by .IR screen , diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index a56e02f..0bed653 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -175,6 +175,9 @@ run another copy of @code{screen}, but will instead supply the command name and its arguments to the window manager (specified in the $STY environment variable) who will use it to create the new window. The above example would start the @code{emacs} editor (editing @file{prog.c}) and switch to its window. +- Note that you cannot transport environment variables from +the invoking shell to the application (emacs in this case), because it is +forked from the parent screen process, not from the invoking shell. If @file{/etc/utmp} is writable by @code{screen}, an appropriate record will be written to this file for each window, and removed when the -- cgit v1.2.1 From 84b8ef5de3aa94d6b49e81fe4562694fb12c5d0a Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 19 Dec 2009 12:32:50 -0500 Subject: Report impermissible write failure to attached display Fixes savannah bug #26401. --- src/window.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/window.c b/src/window.c index dc9fd3a..bb232c2 100644 --- a/src/window.c +++ b/src/window.c @@ -281,8 +281,7 @@ int *lenp; debug2("window %d, user %s: ", fore->w_number, D_user->u_name); debug2("writelock %d (wlockuser %s)\n", fore->w_wlock, fore->w_wlockuser ? fore->w_wlockuser->u_name : "NULL"); - /* XXX FIXME only display !*/ - WBell(fore, visual_bell); + Msg(0, "write: permission denied (user %s)", D_user->u_name); *bufpp += *lenp; *lenp = 0; return; -- cgit v1.2.1 From 52efeb8dfc40be5d5ba36253a1dc3af514d0b226 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 19 Dec 2009 14:23:27 -0500 Subject: Allow no argument to blankerprg. Without any argument, blankerprg will show the command that would be executed on 'blanker'. To unset, use an empty string, i.e. "blankerprg ''". --- src/doc/screen.1 | 3 ++- src/doc/screen.texinfo | 6 ++++-- src/process.c | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index de3df24..bbf7975 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -1094,7 +1094,8 @@ This command is normally used together with the \*Qidle\*U command. .B blankerprg .RI [ "program args" ] .PP -Defines a blanker program. Disables the blanker program if no +Defines a blanker program. Disables the blanker program if an +empty argument is given. Shows the currently set blanker program if no arguments are given. .sp .ne 3 diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 0bed653..618fa70 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -5155,8 +5155,10 @@ command. @end deffn @deffn Command blankerprg [@var{program args}] -Defines a blanker program. Disables the blanker program if -no arguments are given. +Defines a blanker program. Disables the blanker program if an +empty argument is given. Shows the currently set blanker program if no +arguments are given. + @end deffn @node Zmodem, , Screen Saver, Miscellaneous diff --git a/src/process.c b/src/process.c index 0e835f0..76785e1 100644 --- a/src/process.c +++ b/src/process.c @@ -4088,6 +4088,21 @@ int key; break; #ifdef BLANKER_PRG case RC_BLANKERPRG: + if (!args[0]) + { + if (blankerprg) + { + char path[MAXPATHLEN]; + char *p = path, **pp; + for (pp = blankerprg; *pp; pp++) + p += snprintf(p, sizeof(path) - (p - path) - 1, "%s ", *pp); + *(p - 1) = '\0'; + Msg(0, "blankerprg: %s", path); + } + else + Msg(0, "No blankerprg set."); + break; + } if (blankerprg) { char **pp; -- cgit v1.2.1 From f515135eb00ea307f80f096e9ee476d5efc0088f Mon Sep 17 00:00:00 2001 From: Jan Christoph Nordholz Date: Sat, 19 Dec 2009 14:52:51 -0500 Subject: Allow no arguments for blankerprg. --- src/comm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/comm.c b/src/comm.c index 4921911..4e3787e 100644 --- a/src/comm.c +++ b/src/comm.c @@ -103,7 +103,7 @@ struct comm comms[RC_LAST + 1] = #endif { "blanker", NEED_DISPLAY|ARGS_0}, #ifdef BLANKER_PRG - { "blankerprg", ARGS_1|ARGS_ORMORE }, + { "blankerprg", ARGS_0|ARGS_ORMORE }, #endif { "break", NEED_FORE|ARGS_01 }, { "breaktype", NEED_FORE|ARGS_01 }, -- cgit v1.2.1 From 7ac593d74dfd2243cd60c5d848547ebd9971a8b0 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 19 Dec 2009 18:44:45 -0500 Subject: Cap the maximum sizes of a window. --- src/resize.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/resize.c b/src/resize.c index 1afdf5a..553b0ed 100644 --- a/src/resize.c +++ b/src/resize.c @@ -633,6 +633,27 @@ int wi, he, hi; if (p->w_type == W_TYPE_GROUP) return 0; + + if (wi > 1000) + { + Msg(0, "Window width too large. Truncated to 1000."); + wi = 1000; + } + + if (he > 1000) + { + Msg(0, "Window height too large. Truncated to 1000."); + he = 1000; + } + +#ifdef COPY_PASTE + if (hi > 1000) + { + Msg(0, "Window history too big. Truncated to 1000."); + hi = 1000; + } +#endif + if (p->w_width == wi && p->w_height == he && p->w_histheight == hi) { debug("ChangeWindowSize: No change.\n"); -- cgit v1.2.1 From 90afd2d35d8cff7a403dcaf71d3f2fd4857f9994 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sat, 19 Dec 2009 19:48:49 -0500 Subject: Changelog change to blankerprg, and credits. --- src/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 2133009..5052b35 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -38,6 +38,7 @@ Version 4.1.0 (??/??/20??): relative argument. * '-g' parameter to 'windowlist' to show nested list of windows. * '//group' parameter to 'screen' to create a grouped window. + * 'blankerprg' shows the currently set command on no argument. .screenrc: * $PID expands to the PID of the screen session. @@ -85,13 +86,16 @@ Version 4.1.0 (??/??/20??): * Cyril Brulebois * Trent W Buck * Stephane Chazelas + * Kees Cook * Thomas Dickey * Christian Ebert * Geraint Edwards * Romain Francoise * Emanuele Giaquinta + * Yi-Hsuan Hsin * Steve Kemp * Ryan Niebur + * Jan Christoph Nordholz * William Pursell * Enrico Scholz * Peter Teichman -- cgit v1.2.1 From 4b778782ce398747f080b7b7ffd8a2e26c3b0a88 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 20 Dec 2009 00:14:15 -0500 Subject: Allow 'at' command for windows without a display. For window-context, 'at' commands can work without any existing display. So allow for that. If the command specified for 'at' requires a display, then that will still fail, as it should. But for some commands, just an existing window is enough. Fixes savannah bug #26996. --- src/comm.c | 2 +- src/process.c | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/comm.c b/src/comm.c index 4e3787e..883c99a 100644 --- a/src/comm.c +++ b/src/comm.c @@ -58,7 +58,7 @@ struct comm comms[RC_LAST + 1] = #endif { "allpartial", NEED_DISPLAY|ARGS_1 }, { "altscreen", ARGS_01 }, - { "at", NEED_DISPLAY|ARGS_2|ARGS_ORMORE }, + { "at", ARGS_2|ARGS_ORMORE }, #ifdef COLOR { "attrcolor", ARGS_12 }, #endif diff --git a/src/process.c b/src/process.c index 76785e1..70bb4fa 100644 --- a/src/process.c +++ b/src/process.c @@ -1451,12 +1451,14 @@ int key; break; case RC_AT: /* where this AT command comes from: */ + if (!user) + break; #ifdef MULTIUSER - s = SaveStr(D_user->u_name); + s = SaveStr(user->u_name); /* DO NOT RETURN FROM HERE WITHOUT RESETTING THIS: */ - EffectiveAclUser = D_user; + EffectiveAclUser = user; #else - s = SaveStr(D_usertty); + s = SaveStr(display ? D_usertty : user->u_name); #endif n = strlen(args[0]); if (n) n--; @@ -1473,14 +1475,22 @@ int key; struct acluser *u; if (!n) - u = D_user; + u = user; else - for (u = users; u; u = u->u_next) - { - debug3("strncmp('%s', '%s', %d)\n", *args, u->u_name, n); - if (!strncmp(*args, u->u_name, n)) + { + for (u = users; u; u = u->u_next) + { + debug3("strncmp('%s', '%s', %d)\n", *args, u->u_name, n); + if (!strncmp(*args, u->u_name, n)) + break; + } + if (!u) + { + args[0][n] = '\0'; + Msg(0, "Did not find any user matching '%s'", args[0]); break; - } + } + } debug1("at all displays of user %s\n", u->u_name); for (display = displays; display; display = nd) { @@ -1539,7 +1549,7 @@ int key; struct win *nw; int ch; - n++; + n++; ch = args[0][n]; args[0][n] = '\0'; if (!*args[0] || (i = WindowByNumber(args[0])) < 0) -- cgit v1.2.1 From a33070eb0e61eff275c60051161d8310ec2e1851 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Mon, 21 Dec 2009 12:54:56 -0500 Subject: Update manual. Included here are three changes, two of which I wish I had when I was beginning to learn screen. The third is that it just seemed like to me the TOC belongs at the /beginning/ of the manual. Also, a typo from a previous change. --- src/doc/screen.texinfo | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 618fa70..6142de0 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -73,6 +73,9 @@ except that this permission notice may be stated in a translation approved by the Foundation. @end titlepage +@shortcontents +@contents + @node Top, Overview, (dir), (dir) @ifinfo @@ -1465,6 +1468,7 @@ in that group. Using the @code{windowlist} command will give you the opportunity to leave the group you are in. @xref{Windowlist}. @deffn Command group [grouptitle] +(none)@* Change or show the group the current window belongs to. Windows can be moved around between different groups by specifying the name of the destination group. Without specifying a group, the title of the @@ -3296,6 +3300,7 @@ When no parameter is given, the state is toggled. @node Scrollback, Copy Mode Keys, Line Termination, Copy @subsection Scrollback +To access and use the contents in the scrollback buffer, use the @code{copy} command. @xref{Copy}. @deffn Command defscrollback num (none)@* Same as the @code{scrollback} command except that the default setting @@ -3305,7 +3310,7 @@ for new windows is changed. Defaults to 100. @deffn Command scrollback num (none)@* Set the size of the scrollback buffer for the current window to -@var{num} lines. The default scrollback is 100 lines. Use @copy{info} +@var{num} lines. The default scrollback is 100 lines. Use @code{info} to view the current setting. @end deffn @@ -5209,7 +5214,7 @@ day number @item D weekday name @item f -flags of the window +flags of the window. @xref{Windows}, for meanings of the various flags. @item F sets %? to true if the window has the focus @item h @@ -5725,7 +5730,5 @@ from the key sequences, since it is the same for all bindings. @printindex ky -@shortcontents -@contents @bye -- cgit v1.2.1 From a6eea7b4d6dd3e4385919b4a50a58688f9a6b52b Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 24 Dec 2009 15:28:51 -0500 Subject: Re-optimize screen updates. In only the top line and the bottom line had to be updated, we were updating the entire region in between as well! This clearly is bad. So instead of doing that, just update the lines that need changing. Thanks to Chris Jones for reporting the bug. --- src/canvas.c | 3 +++ src/layer.c | 80 +++++++++++++++++++++++++++++++++++++++++++----------------- src/layer.h | 14 ++++++++--- src/window.c | 1 + 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/src/canvas.c b/src/canvas.c index a6c15ab..4cc4fe2 100644 --- a/src/canvas.c +++ b/src/canvas.c @@ -81,6 +81,7 @@ struct canvas *pcv; cv->c_slnext = pcv->c_slnext; if (cv->c_slnext) cv->c_slnext->c_slprev = cv; + LayerCleanupMemory(&pcv->c_blank); free(pcv); } @@ -102,6 +103,7 @@ struct canvas *cv; { while (cv->c_slperp) FreeCanvas(cv->c_slperp); + LayerCleanupMemory(&cv->c_blank); free(cv); return; } @@ -133,6 +135,7 @@ struct canvas *cv; free(vp); } evdeq(&cv->c_captev); + LayerCleanupMemory(&cv->c_blank); free(cv); } diff --git a/src/layer.c b/src/layer.c index 067d2ef..c71c731 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1172,6 +1172,7 @@ ExitOverlayPage() ocv->c_lnext = cv; } oldlay->l_cvlist = 0; + LayerCleanupMemory(oldlay); free((char *)oldlay); LayRestore(); LaySetCursor(); @@ -1206,6 +1207,7 @@ int pause; { struct canvas *cv; struct display *olddisplay = display; + int line; pause = !!pause; @@ -1215,16 +1217,13 @@ int pause; if ((layer->l_pause.d = pause)) { /* Start pausing */ - layer->l_pause.top = layer->l_pause.bottom = - layer->l_pause.left = layer->l_pause.right = -1; + layer->l_pause.top = layer->l_pause.bottom = -1; return; } /* Unpause. So refresh the regions in the displays! */ if (layer->l_pause.top == -1 && - layer->l_pause.bottom == -1 && - layer->l_pause.left == -1 && - layer->l_pause.right == -1) + layer->l_pause.bottom == -1) return; for (cv = layer->l_cvlist; cv; cv = cv->c_lnext) @@ -1235,18 +1234,24 @@ int pause; for (vp = cv->c_vplist; vp; vp = vp->v_next) { - int xs = layer->l_pause.left + vp->v_xoff; - int xe = layer->l_pause.right + vp->v_xoff; - int ys = layer->l_pause.top + vp->v_yoff; - int ye = layer->l_pause.bottom + vp->v_yoff; - - if (xs < vp->v_xs) xs = vp->v_xs; - if (xe > vp->v_xe) xe = vp->v_xe; - if (ys < vp->v_ys) ys = vp->v_ys; - if (ye > vp->v_ye) ye = vp->v_ye; - - if (xs <= xe && ys <= ye) - RefreshArea(xs, ys, xe, ye, 0); + for (line = layer->l_pause.top; line <= layer->l_pause.bottom; line++) + { + int xs, xe; + + if (line + vp->v_yoff >= vp->v_ys && line + vp->v_yoff <= vp->v_ye && + ((xs = layer->l_pause.left[line]) >= 0) && + ((xe = layer->l_pause.right[line]) >= 0)) + { + xs += vp->v_xoff; + xe += vp->v_xoff; + + if (xs < vp->v_xs) xs = vp->v_xs; + if (xe > vp->v_xe) xe = vp->v_xe; + + if (xs <= xe) + RefreshLine(line + vp->v_yoff, xs, xe, 0); + } + } } if (cv == D_forecv) @@ -1263,6 +1268,8 @@ int pause; } } + for (line = layer->l_pause.top; line <= layer->l_pause.bottom; line++) + layer->l_pause.left[line] = layer->l_pause.right[line] = -1; olddisplay = display; } @@ -1274,7 +1281,6 @@ int ys, ye; { if (!layer->l_pause.d) return; - if (ye >= layer->l_height) ye = layer->l_height - 1; if (xe >= layer->l_width) @@ -1283,10 +1289,38 @@ int ys, ye; if (layer->l_pause.top == -1 || layer->l_pause.top > ys) layer->l_pause.top = ys; if (layer->l_pause.bottom < ye) - layer->l_pause.bottom = ye; - if (layer->l_pause.left == -1 || layer->l_pause.left > xs) - layer->l_pause.left = xs; - if (layer->l_pause.right < xe) - layer->l_pause.right = xe; + { + layer->l_pause.bottom = ye; + if (layer->l_pause.lines <= ye) + { + int o = layer->l_pause.lines; + layer->l_pause.lines = ye + 32; + layer->l_pause.left = realloc(layer->l_pause.left, sizeof(int) * layer->l_pause.lines); + layer->l_pause.right = realloc(layer->l_pause.right, sizeof(int) * layer->l_pause.lines); + while (o < layer->l_pause.lines) + { + layer->l_pause.left[o] = layer->l_pause.right[o] = -1; + o++; + } + } + } + + while (ys <= ye) + { + if (layer->l_pause.left[ys] == -1 || layer->l_pause.left[ys] > xs) + layer->l_pause.left[ys] = xs; + if (layer->l_pause.right[ys] < xe) + layer->l_pause.right[ys] = xe; + ys++; + } } +void +LayerCleanupMemory(layer) +struct layer *layer; +{ + if (layer->l_pause.left) + free(layer->l_pause.left); + if (layer->l_pause.right) + free(layer->l_pause.right); +} diff --git a/src/layer.h b/src/layer.h index 5db4997..7d5da0b 100644 --- a/src/layer.h +++ b/src/layer.h @@ -77,10 +77,9 @@ struct layer int d : 1; /* Is the output for the layer blocked? */ /* After unpausing, what region should we refresh? */ - int top; - int bottom; - int left; - int right; + int *left, *right; + int top, bottom; + int lines; } l_pause; }; @@ -152,3 +151,10 @@ void LayPause __P((struct layer *layer, int pause)); */ void LayPauseUpdateRegion __P((struct layer *layer, int xs, int xe, int ys, int ye)); +/** + * Free any internal memory for the layer. + * + * @param layer The layer. + */ +void LayerCleanupMemory __P((struct layer *layer)); + diff --git a/src/window.c b/src/window.c index bb232c2..aaad8ad 100644 --- a/src/window.c +++ b/src/window.c @@ -1022,6 +1022,7 @@ struct win *wp; wp->w_layer.l_cvlist = 0; if (flayer == &wp->w_layer) flayer = 0; + LayerCleanupMemory(&wp->w_layer); #ifdef MULTIUSER FreeWindowAcl(wp); -- cgit v1.2.1 From f33e5cdecb7bf3b6ae8e4a5c0ca394dd5a06a416 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 26 Jan 2010 15:15:24 -0500 Subject: Increase the max-window limit. The limit can be increased using the 'maxwin' command. There is still an upper-limit of 2048 windows. --- src/acconfig.h | 6 ++-- src/acls.c | 2 +- src/comm.c | 2 +- src/doc/screen.1 | 3 +- src/doc/screen.texinfo | 3 +- src/extern.h | 2 +- src/help.c | 87 ++++++++++++++++++++++++++++++-------------------- src/process.c | 44 +++++++++++++++---------- src/screen.c | 8 ++--- src/socket.c | 5 +-- src/window.c | 8 ++++- 11 files changed, 104 insertions(+), 66 deletions(-) diff --git a/src/acconfig.h b/src/acconfig.h index 4f5e2f8..ffedbbc 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -35,7 +35,7 @@ * Maximum of simultaneously allowed windows per screen session. */ #ifndef MAXWIN -# define MAXWIN 40 +# define MAXWIN 100 #endif /* @@ -521,12 +521,12 @@ #undef USESETENV /* - * If setenv() takes 3 arguments sefine HAVE_SETENV_3 + * If setenv() takes 3 arguments define HAVE_SETENV_3 */ #undef HAVE_SETENV_3 /* - * If setenv() takes 2 arguments sefine HAVE_SETENV_2 + * If setenv() takes 2 arguments define HAVE_SETENV_2 */ #undef HAVE_SETENV_2 diff --git a/src/acls.c b/src/acls.c index d764023..e652e74 100644 --- a/src/acls.c +++ b/src/acls.c @@ -56,7 +56,7 @@ ************************************************************************/ extern struct comm comms[]; -extern struct win *windows, *wtab[]; +extern struct win *windows, **wtab; extern char NullStr[]; extern char SockPath[]; extern struct display *display, *displays; diff --git a/src/comm.c b/src/comm.c index 883c99a..17fbd56 100644 --- a/src/comm.c +++ b/src/comm.c @@ -232,7 +232,7 @@ struct comm comms[RC_LAST + 1] = #ifdef COPY_PASTE { "markkeys", ARGS_1 }, #endif - { "maxwin", ARGS_1 }, + { "maxwin", ARGS_01 }, { "meta", NEED_LAYER|ARGS_0 }, { "monitor", NEED_FORE|ARGS_01 }, { "mousetrack", NEED_DISPLAY | ARGS_01 }, diff --git a/src/doc/screen.1 b/src/doc/screen.1 index bbf7975..3ac5571 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2234,7 +2234,8 @@ single statement. .BI "maxwin " num .PP Set the maximum window number screen will create. Doesn't affect -already existing windows. The number may only be decreased. +already existing windows. The number can be increased only when there are no +existing windows. .sp .ne 3 .B meta diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 6142de0..44d233e 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -5104,7 +5104,8 @@ Parses and executes each argument as separate command. @deffn Command maxwin @var{n} (none)@* Set the maximum window number screen will create. Doesn't affect -already existing windows. The number may only be decreased. +already existing windows. The number can be increased only when there are no +existing windows. @end deffn @node Backtick, Screen Saver, Maxwin, Miscellaneous diff --git a/src/extern.h b/src/extern.h index 0eb811a..315daab 100644 --- a/src/extern.h +++ b/src/extern.h @@ -195,7 +195,7 @@ extern void ProcessInput2 __P((char *, int)); #endif extern void DoProcess __P((struct win *, char **, int *, struct paster *)); extern void DoAction __P((struct action *, int)); -extern int FindCommnr __P((char *)); +extern int FindCommnr __P((const char *)); extern void DoCommand __P((char **, int *)); extern void Activate __P((int)); extern void KillWindow __P((struct win *)); diff --git a/src/help.c b/src/help.c index 338c4cd..e98f50c 100644 --- a/src/help.c +++ b/src/help.c @@ -38,11 +38,12 @@ char version[60]; /* initialised by main() */ extern struct layer *flayer; extern struct display *display, *displays; extern struct win *windows; +extern int maxwin; extern char *noargs[]; extern struct mchar mchar_blank, mchar_so; extern int renditions[]; extern unsigned char *blank; -extern struct win *wtab[]; +extern struct win **wtab; #ifdef MAPKEYS extern struct term term[]; #endif @@ -691,6 +692,7 @@ int y, xs, xe, isblank; struct wlistdata; static void WListProcess __P((char **, int *)); +static void WListAbort __P((void)); static void WListRedisplayLine __P((int, int, int, int)); static void wlistpage __P((void)); static void WListLine __P((int, int, int, int)); @@ -712,13 +714,13 @@ struct wlistdata { int order; struct win *group; int nested; - int list[MAXWIN]; + int *list; }; static struct LayFuncs WListLf = { WListProcess, - HelpAbort, + WListAbort, WListRedisplayLine, DefClearLine, DefRewrite, @@ -745,6 +747,16 @@ int wi, he; return 0; } +static void +WListAbort() +{ + struct wlistdata * wlistdata = (struct wlistdata *)flayer->l_data; + if (wlistdata->list) + Free(wlistdata->list); + LAY_CALL_UP(LRefreshAll(flayer, 0)); + ExitOverlayPage(); +} + static void WListProcess(ppbuf, plen) char **ppbuf; @@ -766,7 +778,7 @@ int *plen; { int n = (unsigned char)**ppbuf - '0'; int d = 0; - if (n < MAXWIN && wtab[n] && WTAB_GROUP_MATCHES(n)) + if (n < maxwin && wtab[n] && WTAB_GROUP_MATCHES(n)) { int i; for (d = -wlistdata->npos, i = WListNext(wlistdata, -1, 0); i != n; i = WListNext(wlistdata, i, 1), d++) @@ -805,7 +817,7 @@ int *plen; WListMove(-wlistdata->pos, -1); break; case 0205: /* end */ - WListMove(MAXWIN, -1); + WListMove(maxwin, -1); break; case 'a': /* All-window view */ @@ -827,9 +839,9 @@ int *plen; case '\n': case ' ': h = wlistdata->pos; - if (h == MAXWIN && Layer2Window(flayer) && Layer2Window(flayer)->w_type == W_TYPE_GROUP) + if (h == maxwin && Layer2Window(flayer) && Layer2Window(flayer)->w_type == W_TYPE_GROUP) break; - if (display && h != MAXWIN && wtab[h] && (wtab[h]->w_type == W_TYPE_GROUP) && Layer2Window(flayer) == wtab[h]) + if (display && h != maxwin && wtab[h] && (wtab[h]->w_type == W_TYPE_GROUP) && Layer2Window(flayer) == wtab[h]) { wlistdata->group = wtab[h]; wlistdata->pos = wtab[h]->w_number; @@ -837,17 +849,21 @@ int *plen; break; } done = 1; - if (!display || h == MAXWIN || !wtab[h] || wtab[h] == D_fore || (flayer->l_cvlist && flayer->l_cvlist->c_lnext)) - HelpAbort(); + if (!display || h == maxwin || !wtab[h] || wtab[h] == D_fore || (flayer->l_cvlist && flayer->l_cvlist->c_lnext)) + WListAbort(); #ifdef MULTIUSER else if (AclCheckPermWin(D_user, ACL_READ, wtab[h])) - HelpAbort(); + WListAbort(); #endif else - ExitOverlayPage(); /* no need to redisplay */ + { + if (wlistdata->list) + Free(wlistdata->list); + ExitOverlayPage(); /* no need to redisplay */ + } /* restore display, don't switch wrong user */ display = olddisplay; - if (h != MAXWIN) + if (h != maxwin) SwitchWindow(h); break; case 0222: /* Mouse event */ @@ -865,7 +881,7 @@ int *plen; } break; } - HelpAbort(); + WListAbort(); display = olddisplay; if (h >= 0 && wtab[h]) SwitchWindow(h); @@ -909,7 +925,7 @@ int isblank; struct mchar mchar_rend = mchar_blank; struct mchar *mchar = (struct mchar *)0; - if (i == MAXWIN) + if (i == maxwin) return; wlistdata = (struct wlistdata *)flayer->l_data; if (wlistdata->nested && wtab[i]) @@ -959,21 +975,21 @@ int old, delta; { int i; - if (old == MAXWIN) - return MAXWIN; + if (old == maxwin) + return maxwin; if (old == -1) old = 0; else { - for (i = 0; i < MAXWIN && wlistdata->list[i] != -1; i++) + for (i = 0; i < maxwin && wlistdata->list[i] != -1; i++) if (wlistdata->list[i] == old) break; - if (i < MAXWIN && wlistdata->list[i] != -1) + if (i < maxwin && wlistdata->list[i] != -1) old = i; } old += delta; - if (old < 0 || old >= MAXWIN || wlistdata->list[old] == -1) + if (old < 0 || old >= maxwin || wlistdata->list[old] == -1) old -= delta; return wlistdata->list[old]; } @@ -993,7 +1009,7 @@ int up, oldpos; i = WListNext(wlistdata, pos, -ypos); for (y = 0; y < wlistdata->numwin; y++) { - if (i == MAXWIN || !wtab[i]) + if (i == maxwin || !wtab[i]) return; if (y == 0) wlistdata->first = i; @@ -1004,7 +1020,7 @@ int up, oldpos; wlistdata->ypos = y; oldi = i; i = WListNext(wlistdata, i, 1); - if (i == MAXWIN || i == oldi) + if (i == maxwin || i == oldi) break; } } @@ -1023,11 +1039,11 @@ WListNormalize() ypos = 0; if (ypos >= wlistdata->numwin) ypos = wlistdata->numwin - 1; - for (n = 0, oldi = MAXWIN, i = pos; i != MAXWIN && i != oldi && n < wlistdata->numwin; oldi = i, i = WListNext(wlistdata, i, 1)) + for (n = 0, oldi = maxwin, i = pos; i != maxwin && i != oldi && n < wlistdata->numwin; oldi = i, i = WListNext(wlistdata, i, 1)) n++; if (ypos < wlistdata->numwin - n) ypos = wlistdata->numwin - n; - for (n = 0, oldi = MAXWIN, i = WListNext(wlistdata, -1, 0); i != MAXWIN && i != oldi && i != pos; oldi = i, i = WListNext(wlistdata, i, 1)) + for (n = 0, oldi = maxwin, i = WListNext(wlistdata, -1, 0); i != maxwin && i != oldi && i != pos; oldi = i, i = WListNext(wlistdata, i, 1)) n++; if (ypos > n) ypos = n; @@ -1092,10 +1108,10 @@ struct win *group; { int i; - if (ind >= MAXWIN) + if (ind >= maxwin) return ind; if (ind == 0) - for (i = 0; i < MAXWIN; i++) + for (i = 0; i < maxwin; i++) wlistdata->list[i] = -1; if (wlistdata->order == WLIST_MRU) @@ -1107,23 +1123,23 @@ struct win *group; { if (start == -1) start = 0; - while (start < MAXWIN && !wtab[start]) + while (start < maxwin && !wtab[start]) start++; } - if (start >= MAXWIN || !wtab[start]) + if (start >= maxwin || !wtab[start]) return ind; if (!WTAB_GROUP_MATCHES(start)) { - while (start < MAXWIN && (!wtab[start] || !WTAB_GROUP_MATCHES(start))) + while (start < maxwin && (!wtab[start] || !WTAB_GROUP_MATCHES(start))) if (wlistdata->order != WLIST_MRU) start++; else if (wtab[start]->w_next) start = wtab[start]->w_next->w_number; else - start = MAXWIN; - if (start >= MAXWIN || !wtab[start]) + start = maxwin; + if (start >= maxwin || !wtab[start]) return ind; } @@ -1186,6 +1202,7 @@ struct win *group; if (InitOverlayPage(sizeof(*wlistdata), &WListLf, 0)) return; wlistdata = (struct wlistdata *)flayer->l_data; + wlistdata->list = calloc(maxwin, sizeof(int)); flayer->l_mode = 1; flayer->l_x = 0; flayer->l_y = flayer->l_height - 1; @@ -1216,23 +1233,23 @@ wlistpage() WListOrder(wlistdata, 0, -1, group); pos = wlistdata->pos; - if (pos == MAXWIN || !wtab[pos] || !WTAB_GROUP_MATCHES(pos)) + if (pos == maxwin || !wtab[pos] || !WTAB_GROUP_MATCHES(pos)) { if (wlistdata->order == WLIST_MRU) pos = WListNext(wlistdata, -1, wlistdata->npos); else { /* find new position */ - if (pos < MAXWIN) - while(++pos < MAXWIN) + if (pos < maxwin) + while(++pos < maxwin) if (wtab[pos] && WTAB_GROUP_MATCHES(pos)) break; - if (pos == MAXWIN) + if (pos == maxwin) while (--pos >= 0) if (wtab[pos] && WTAB_GROUP_MATCHES(pos)) break; if (pos == -1) - pos = MAXWIN; + pos = maxwin; } } wlistdata->pos = pos; diff --git a/src/process.c b/src/process.c index 70bb4fa..b67afd5 100644 --- a/src/process.c +++ b/src/process.c @@ -186,7 +186,7 @@ extern int nethackflag; #endif -struct win *wtab[MAXWIN]; /* window table, should be dynamic */ +extern struct win **wtab; #ifdef MULTIUSER extern char *multi; @@ -586,7 +586,7 @@ InitKeytab() args[1] = NULL; SaveAction(ktab + '-', RC_SELECT, args, 0); } - for (i = 0; i < ((MAXWIN < 10) ? MAXWIN : 10); i++) + for (i = 0; i < ((maxwin < 10) ? maxwin : 10); i++) { char *args[2], arg1[10]; args[0] = arg1; @@ -991,7 +991,7 @@ struct paster *pa; int FindCommnr(str) -char *str; +const char *str; { int x, m, l = 0, r = RC_LAST; while (l <= r) @@ -1588,7 +1588,7 @@ int key; Msg(0, "%s: at '%s': no such window.\n", rc_name, args[0]); break; } - else if (i < MAXWIN && (fore = wtab[i])) + else if (i < maxwin && (fore = wtab[i])) { args[0][n] = ch; /* must restore string in case of bind */ debug2("AT window %d (%s)\n", fore->w_number, fore->w_title); @@ -4054,14 +4054,25 @@ int key; Msg(0, "Will %sdo alternate screen switching", use_altscreen ? "" : "not "); break; case RC_MAXWIN: + if (!args[0]) + { + Msg(0, "maximum windows allowed: %d", maxwin); + break; + } if (ParseNum(act, &n)) break; if (n < 1) Msg(0, "illegal maxwin number specified"); - else if (n > maxwin) - Msg(0, "may only decrease maxwin number"); + else if (n > 2048) + Msg(0, "maximum 2048 windows allowed"); + else if (n > maxwin && windows) + Msg(0, "may increase maxwin only when there's no window"); else - maxwin = n; + { + if (!windows) + wtab = realloc(wtab, n * sizeof(struct win)); + maxwin = n; + } break; case RC_BACKTICK: if (ParseBase(act, *args, &n, 10, "decimal")) @@ -4435,10 +4446,11 @@ char **argv; int *argl; { struct action act; + const char *cmd = *argv; - if ((act.nr = FindCommnr(*argv)) == RC_ILLEGAL) + if ((act.nr = FindCommnr(cmd)) == RC_ILLEGAL) { - Msg(0, "%s: unknown command '%s'", rc_name, *argv); + Msg(0, "%s: unknown command '%s'", rc_name, cmd); return; } act.args = argv + 1; @@ -4907,7 +4919,7 @@ char *str; int i; struct win *p; - if ((i = WindowByNumber(str)) < 0 || i >= MAXWIN) + if ((i = WindowByNumber(str)) < 0 || i >= maxwin) { if ((p = WindowByName(str))) return p->w_number; @@ -5012,7 +5024,7 @@ int n; struct win *p; debug1("SwitchWindow %d\n", n); - if (n < 0 || n >= MAXWIN) + if (n < 0 || n >= maxwin) { ShowWindows(-1); return; @@ -5116,12 +5128,12 @@ static int NextWindow() { register struct win **pp; - int n = fore ? fore->w_number : MAXWIN; + int n = fore ? fore->w_number : maxwin; struct win *group = fore ? fore->w_group : 0; for (pp = fore ? wtab + n + 1 : wtab; pp != wtab + n; pp++) { - if (pp == wtab + MAXWIN) + if (pp == wtab + maxwin) pp = wtab; if (*pp) { @@ -5144,7 +5156,7 @@ PreviousWindow() for (pp = wtab + n - 1; pp != wtab + n; pp--) { if (pp == wtab - 1) - pp = wtab + MAXWIN - 1; + pp = wtab + maxwin - 1; if (*pp) { if (!fore || group == (*pp)->w_group) @@ -5284,7 +5296,7 @@ int where; *s = 0; return ss; } - for (pp = ((flags & 4) && where >= 0) ? wtab + where + 1: wtab; pp < wtab + MAXWIN; pp++) + for (pp = ((flags & 4) && where >= 0) ? wtab + where + 1: wtab; pp < wtab + maxwin; pp++) { int rend = -1; if (pp - wtab == where && ss == buf) @@ -5921,7 +5933,7 @@ char *fn, **av; if (*buf != '\0') nwin.aka = buf; num = atoi(*av); - if (num < 0 || num > MAXWIN - 1) + if (num < 0 || num > maxwin - 1) { Msg(0, "%s: illegal screen number %d.", fn, num); num = 0; diff --git a/src/screen.c b/src/screen.c index 212bee2..b1c3dfb 100644 --- a/src/screen.c +++ b/src/screen.c @@ -465,10 +465,10 @@ char **av; screenlogfile = SaveStr("screenlog.%n"); logtstamp_string = SaveStr("-- %n:%t -- time-stamp -- %M/%d/%y %c:%s --\n"); hstatusstring = SaveStr("%h"); - captionstring = SaveStr("%3n %t"); + captionstring = SaveStr("%4n %t"); timestring = SaveStr("%c:%s %M %d %H%? %l%?"); - wlisttit = SaveStr("Num Name%=Flags"); - wliststr = SaveStr("%3n %t%=%f"); + wlisttit = SaveStr(" Num Name%=Flags"); + wliststr = SaveStr("%4n %t%=%f"); #ifdef COPY_PASTE BufferFile = SaveStr(DEFAULT_BUFFERFILE); #endif @@ -760,7 +760,7 @@ char **av; eff_uid = geteuid(); eff_gid = getegid(); if (eff_uid != real_uid) - { + { /* if running with s-bit, we must install a special signal * handler routine that resets the s-bit, so that we get a * core file anyway. diff --git a/src/socket.c b/src/socket.c index 68a4258..cd7ef56 100644 --- a/src/socket.c +++ b/src/socket.c @@ -67,13 +67,14 @@ extern int ServerSocket, real_uid, real_gid, eff_uid, eff_gid; extern int dflag, iflag, rflag, lsflag, quietflag, wipeflag, xflag; extern char *attach_tty, *LoginName, HostName[]; extern struct display *display, *displays; -extern struct win *fore, *wtab[], *console_window, *windows; +extern struct win *fore, **wtab, *console_window, *windows; extern struct layer *flayer; extern struct layout *layout_attach, *layout_last, layout_last_marker; extern struct NewWindow nwin_undef; #ifdef MULTIUSER extern char *multi; #endif +extern int maxwin; extern char *getenv(); @@ -736,7 +737,7 @@ struct msg *mp; if (*buf) nwin.aka = buf; num = atoi(p); - if (num < 0 || num > MAXWIN - 1) + if (num < 0 || num > maxwin - 1) num = 0; nwin.StartAt = num; p += l + 1; diff --git a/src/window.c b/src/window.c index aaad8ad..addd83b 100644 --- a/src/window.c +++ b/src/window.c @@ -41,7 +41,7 @@ #include "logfile.h" /* logfopen() */ extern struct display *displays, *display; -extern struct win *windows, *fore, *wtab[], *console_window; +extern struct win *windows, *fore, *console_window; extern char *ShellArgs[]; extern char *ShellProg; extern char screenterm[]; @@ -104,6 +104,7 @@ static int zmodem_parse __P((struct win *, char *, int)); #endif +struct win **wtab; /* window table */ int VerboseCreate = 0; /* XXX move this to user.h */ @@ -553,6 +554,11 @@ struct NewWindow *newwin; extern struct acluser *users; #endif + if (!wtab) + { + wtab = calloc(maxwin, sizeof(struct win *)); + } + debug1("NewWindow: StartAt %d\n", newwin->StartAt); debug1("NewWindow: aka %s\n", newwin->aka?newwin->aka:"NULL"); debug1("NewWindow: dir %s\n", newwin->dir?newwin->dir:"NULL"); -- cgit v1.2.1 From e6a28cf8bfdac15faa6c267bf476ddcaddf48d67 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 26 Jan 2010 15:17:26 -0500 Subject: Accommodate more color changes in the caption. --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index b1c3dfb..2cceae0 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2204,7 +2204,7 @@ static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; #endif static char winmsg_buf[MAXSTR]; -#define MAX_WINMSG_REND 16 /* rendition changes */ +#define MAX_WINMSG_REND 256 /* rendition changes */ static int winmsg_rend[MAX_WINMSG_REND]; static int winmsg_rendpos[MAX_WINMSG_REND]; static int winmsg_numrend; -- cgit v1.2.1 From 54791bc9f973699cd2c20acd3da1666686fc7c23 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 8 Feb 2010 14:55:28 -0500 Subject: Fix a crash caused by configurable maxwin. --- src/screen.c | 2 +- src/window.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index 2cceae0..92b2001 100644 --- a/src/screen.c +++ b/src/screen.c @@ -237,7 +237,7 @@ int cjkwidth; #ifdef NETHACK int nethackflag = 0; #endif -int maxwin = MAXWIN; +int maxwin; struct layer *flayer; diff --git a/src/window.c b/src/window.c index addd83b..1826b33 100644 --- a/src/window.c +++ b/src/window.c @@ -556,6 +556,8 @@ struct NewWindow *newwin; if (!wtab) { + if (!maxwin) + maxwin = MAXWIN; wtab = calloc(maxwin, sizeof(struct win *)); } -- cgit v1.2.1 From f3415774783781be919cd0452d401bbbe396c879 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 8 Feb 2010 21:19:24 -0500 Subject: Fix escape-# to select windows this time. --- src/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/process.c b/src/process.c index b67afd5..0bb3603 100644 --- a/src/process.c +++ b/src/process.c @@ -586,7 +586,7 @@ InitKeytab() args[1] = NULL; SaveAction(ktab + '-', RC_SELECT, args, 0); } - for (i = 0; i < ((maxwin < 10) ? maxwin : 10); i++) + for (i = 0; i < ((maxwin && maxwin < 10) ? maxwin : 10); i++) { char *args[2], arg1[10]; args[0] = arg1; -- cgit v1.2.1 From b040667633ecccb582426536936f07c8e005c87b Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 12 Feb 2010 16:26:16 -0500 Subject: Put in some flags to suppress messages from commands. A command name can be prefixed by '@' to suppress the error messages, and by '-' to suppress the normal messages. The flags are currently parsed, but not acted upon. --- src/comm.sh | 4 ++++ src/process.c | 14 ++++++++++++++ src/socket.c | 1 + 3 files changed, 19 insertions(+) diff --git a/src/comm.sh b/src/comm.sh index 44c83dd..a4b06e7 100644 --- a/src/comm.sh +++ b/src/comm.sh @@ -61,6 +61,10 @@ struct action int nr; char **args; int *argl; + int quiet; /* Suppress (currently unused) + 0x01 - Error message + 0x02 - Normal message + */ }; #define RC_ILLEGAL -1 diff --git a/src/process.c b/src/process.c index 0bb3603..42da498 100644 --- a/src/process.c +++ b/src/process.c @@ -695,6 +695,7 @@ int create; kp->ktab[i].nr = RC_ILLEGAL; kp->ktab[i].args = noargs; kp->ktab[i].argl = 0; + kp->ktab[i].quiet = 0; } kp->next = 0; *kpp = kp; @@ -4448,6 +4449,18 @@ int *argl; struct action act; const char *cmd = *argv; + act.quiet = 0; + if (*cmd == '@') /* Suppress error */ + { + act.quiet |= 0x01; + cmd++; + } + if (*cmd == '-') /* Suppress normal message */ + { + act.quiet |= 0x02; + cmd++; + } + if ((act.nr = FindCommnr(cmd)) == RC_ILLEGAL) { Msg(0, "%s: unknown command '%s'", rc_name, cmd); @@ -6125,6 +6138,7 @@ char *data; act.nr = *(int *)data; act.args = noargs; act.argl = 0; + act.quiet = 0; DoAction(&act, -1); } diff --git a/src/socket.c b/src/socket.c index cd7ef56..a174b72 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1377,6 +1377,7 @@ struct msg *m; char *na = 0; newscreen.nr = RC_SCREEN; newscreen.args = &na; + newscreen.quiet = 0; DoAction(&newscreen, -1); } else -- cgit v1.2.1 From 9756ae6fb21fb6421e543173115059d36358c692 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 12 Feb 2010 16:38:38 -0500 Subject: Get rid of compile-time warnings. --- src/acls.c | 3 +-- src/attacher.c | 2 +- src/process.c | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/acls.c b/src/acls.c index e652e74..e728bb8 100644 --- a/src/acls.c +++ b/src/acls.c @@ -26,10 +26,9 @@ **************************************************************** */ -#include - #include "config.h" +#include /* XXX: WHY IS THIS HERE?? :XXX */ diff --git a/src/attacher.c b/src/attacher.c index a416ec1..1bba70f 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -26,12 +26,12 @@ **************************************************************** */ +#include "config.h" #include #include #include #include #include -#include "config.h" #include "screen.h" #include "extern.h" diff --git a/src/process.c b/src/process.c index 42da498..128b0e2 100644 --- a/src/process.c +++ b/src/process.c @@ -26,6 +26,8 @@ **************************************************************** */ +#include "config.h" + #include #include #include @@ -39,8 +41,6 @@ #endif -#include "config.h" - /* for solaris 2.1, Unixware (SVR4.2) and possibly others: */ #ifdef HAVE_STROPTS_H # include -- cgit v1.2.1 From 97059b7ad521cf796daee07397c658d9716dd1e7 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 15 Feb 2010 21:47:39 -0500 Subject: Fix compilation on systems where execvpe is defined. --- src/acconfig.h | 5 +++++ src/configure.in | 6 ++++++ src/extern.h | 2 ++ src/window.c | 2 ++ 4 files changed, 15 insertions(+) diff --git a/src/acconfig.h b/src/acconfig.h index ffedbbc..2e46985 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -444,6 +444,11 @@ */ #undef HAVE_SETEUID +/* + * execvpe is now defined in some systems. + */ +#undef HAVE_EXECVPE + /* * If you want the "time" command to display the current load average * define LOADAV. Maybe you must install screen with the needed diff --git a/src/configure.in b/src/configure.in index 8c5762c..bd29de2 100644 --- a/src/configure.in +++ b/src/configure.in @@ -284,6 +284,12 @@ seteuid(0); #endif ], AC_DEFINE(HAVE_SETEUID)) +dnl execvpe +AC_CHECKING(execvpe) +AC_TRY_LINK(,[ + execvpe(0, 0, 0); +], AC_DEFINE(HAVE_EXECVPE)) + dnl dnl **** select() **** dnl diff --git a/src/extern.h b/src/extern.h index 315daab..38a8d6e 100644 --- a/src/extern.h +++ b/src/extern.h @@ -156,7 +156,9 @@ extern void CloseDevice __P((struct win *)); #ifdef ZMODEM extern void zmodem_abort __P((struct win *, struct display *)); #endif +#ifndef HAVE_EXECVPE extern void execvpe __P((char *, char **, char **)); +#endif /* utmp.c */ #ifdef UTMPOK diff --git a/src/window.c b/src/window.c index 1826b33..20bceac 100644 --- a/src/window.c +++ b/src/window.c @@ -1449,6 +1449,7 @@ char **args, *ttyn; return pid; } +#ifndef HAVE_EXECVPE void execvpe(prog, args, env) char *prog, **args, **env; @@ -1494,6 +1495,7 @@ char *prog, **args, **env; if (eaccess) errno = EACCES; } +#endif #ifdef PSEUDOS -- cgit v1.2.1 From 929be520ad026011ac98420f4a56fa93dff06899 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 16 Feb 2010 11:00:58 -0500 Subject: Complete the query-response system. Some commands now can be queried from a remote session using the '-Q' flag, e.g. 'screen -Q windows'. The commands will send the response to the stdout of the querying process. If there was an error in the command, then the querying process will exit with a non-zero status. The commands that can be queried now are: echo info lastmsg time title windows --- src/attacher.c | 11 +++++++++++ src/comm.c | 8 ++++---- src/process.c | 38 ++++++++++++++++++++++++++------------ src/screen.c | 7 +++++-- src/socket.c | 19 +++++++++++-------- 5 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/attacher.c b/src/attacher.c index f8c3217..ef3ce8b 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -1009,6 +1009,16 @@ int query; if ((r = MakeServerSocket()) >= 0) break; } + if (r < 0) + { + for (c = '0'; c <= '9'; c++) + { + query[6] = c; + strcpy(sp, query); + if ((r = MakeServerSocket()) >= 0) + break; + } + } if (r < 0) Panic(0, "Could not create a listening socket to read the results."); @@ -1040,3 +1050,4 @@ int query; close(s); } } + diff --git a/src/comm.c b/src/comm.c index f7730cc..4843e10 100644 --- a/src/comm.c +++ b/src/comm.c @@ -180,7 +180,7 @@ struct comm comms[RC_LAST + 1] = { "dinfo", NEED_DISPLAY|ARGS_0 }, { "displays", NEED_LAYER|ARGS_0 }, { "dumptermcap", NEED_FORE|ARGS_0 }, - { "echo", ARGS_12 }, + { "echo", CAN_QUERY|ARGS_12 }, #ifdef ENCODINGS { "encoding", ARGS_12 }, #endif @@ -311,8 +311,8 @@ struct comm comms[RC_LAST + 1] = { "termcap", ARGS_23 }, { "termcapinfo", ARGS_23 }, { "terminfo", ARGS_23 }, - { "time", ARGS_01 }, - { "title", NEED_FORE|ARGS_01 }, + { "time", CAN_QUERY|ARGS_01 }, + { "title", CAN_QUERY|NEED_FORE|ARGS_01 }, { "umask", ARGS_1|ARGS_ORMORE }, { "unbindall", ARGS_0 }, { "unsetenv", ARGS_1 }, @@ -327,7 +327,7 @@ struct comm comms[RC_LAST + 1] = { "wall", NEED_DISPLAY|ARGS_1}, { "width", ARGS_0123 }, { "windowlist", ARGS_012 }, - { "windows", NEED_DISPLAY|ARGS_0 }, + { "windows", CAN_QUERY|ARGS_0 }, { "wrap", NEED_FORE|ARGS_01 }, #ifdef COPY_PASTE { "writebuf", ARGS_0123 }, diff --git a/src/process.c b/src/process.c index 923565a..5d6941d 100644 --- a/src/process.c +++ b/src/process.c @@ -59,6 +59,7 @@ extern char *BellString, *ActivityString, *ShellProg, *ShellArgs[]; extern char *hstatusstring, *captionstring, *timestring; extern char *wliststr, *wlisttit; extern int captionalways; +extern int queryflag; extern char *hardcopydir, *screenlogfile, *logtstamp_string; extern int log_flush, logtstamp_on, logtstamp_after; extern char *VisualBellString; @@ -1147,31 +1148,35 @@ int key; return; } n = comms[nr].flags; - /* XXX: Commands will have a CAN_QUERY flag, depending on whether they have - something to return on a query. For example, 'windows' can return a result, - but 'other' cannot. + /* Commands will have a CAN_QUERY flag, depending on whether they have + * something to return on a query. For example, 'windows' can return a result, + * but 'other' cannot. + * If some command causes an error, then it should reset queryflag to -1, so that + * the process requesting the query can be notified that an error happened. */ -#if 0 - if (!(n & CAN_QUERY) && queryflag) + if (!(n & CAN_QUERY) && queryflag >= 0) { /* Query flag is set, but this command cannot be queried. */ Msg(0, "%s command cannot be queried.", comms[nr].name); + queryflag = -1; return; } -#endif if ((n & NEED_DISPLAY) && display == 0) { Msg(0, "%s: %s: display required", rc_name, comms[nr].name); + queryflag = -1; return; } if ((n & NEED_FORE) && fore == 0) { Msg(0, "%s: %s: window required", rc_name, comms[nr].name); + queryflag = -1; return; } if ((n & NEED_LAYER) && flayer == 0) { Msg(0, "%s: %s: display or window required", rc_name, comms[nr].name); + queryflag = -1; return; } if ((argc = CheckArgNum(nr, args)) < 0) @@ -1183,6 +1188,7 @@ int key; { Msg(0, "%s: %s: permission denied (user %s)", rc_name, comms[nr].name, (EffectiveAclUser ? EffectiveAclUser : D_user)->u_name); + queryflag = -1; return; } } @@ -2038,6 +2044,13 @@ int key; } break; case RC_TITLE: + if (queryflag >= 0) + { + if (fore) + Msg(0, "%s", fore->w_title); + else + queryflag = -1; + } if (*args == 0) InputAKA(); else @@ -2647,7 +2660,10 @@ int key; if (s) Msg(0, "%s", s); else - Msg(0, "%s: 'echo [-n] [-p] \"string\"' expected.", rc_name); + { + Msg(0, "%s: 'echo [-n] [-p] \"string\"' expected.", rc_name); + queryflag = -1; + } break; case RC_BELL: case RC_BELL_MSG: @@ -5330,7 +5346,7 @@ int where; continue; if ((flags & 1) && display && p == D_fore) continue; - if (D_fore && D_fore->w_group != p->w_group) + if (display && D_fore && D_fore->w_group != p->w_group) continue; cmd = p->w_title; @@ -5472,13 +5488,11 @@ int where; char buf[1024]; char *s, *ss; - if (!display) - return; - if (where == -1 && D_fore) + if (display && where == -1 && D_fore) where = D_fore->w_number; ss = AddWindows(buf, sizeof(buf), 0, where); s = buf + strlen(buf); - if (ss - buf > D_width / 2) + if (display && ss - buf > D_width / 2) { ss -= D_width / 2; if (s - ss < D_width) diff --git a/src/screen.c b/src/screen.c index ce081ac..67cddbc 100644 --- a/src/screen.c +++ b/src/screen.c @@ -207,7 +207,7 @@ char *wlisttit; int auto_detach = 1; int iflag, rflag, dflag, lsflag, quietflag, wipeflag, xflag; int cmdflag; -int queryflag; +int queryflag = -1; int adaptflag; #ifdef MULTIUSER @@ -1181,7 +1181,7 @@ char **av; if (!*av) Panic(0, "Please specify a command."); SET_GUID(); - SendCmdMessage(sty, SockMatch, av, queryflag); + SendCmdMessage(sty, SockMatch, av, queryflag >= 0); exit(0); } else if (rflag || xflag) @@ -2110,6 +2110,9 @@ VA_DECL } else printf("%s\r\n", buf); + + if (queryflag >= 0) + write(queryflag, buf, strlen(buf)); } /* diff --git a/src/socket.c b/src/socket.c index 08b545f..70b57db 100644 --- a/src/socket.c +++ b/src/socket.c @@ -65,6 +65,7 @@ static void AskPassword __P((struct msg *)); extern char *RcFileName, *extra_incap, *extra_outcap; extern int ServerSocket, real_uid, real_gid, eff_uid, eff_gid; extern int dflag, iflag, rflag, lsflag, quietflag, wipeflag, xflag; +extern int queryflag; extern char *attach_tty, *LoginName, HostName[]; extern struct display *display, *displays; extern struct win *fore, **wtab, *console_window, *windows; @@ -1171,12 +1172,6 @@ ReceiveMsg() break; #endif case MSG_QUERY: - /* Reset error buffer */ - /* Reset output buffer */ - /* FALLTHROUGH */ - case MSG_COMMAND: - DoCommandMsg(&m); - if (m.type == MSG_QUERY) { char *oldSockPath = SaveStr(SockPath); strcpy(SockPath, m.m.command.writeback); @@ -1185,12 +1180,20 @@ ReceiveMsg() Free(oldSockPath); if (s >= 0) { - write(s, "So ...", 7); + queryflag = s; + DoCommandMsg(&m); close(s); } - Kill(m.m.command.apid, SIGCONT); /* Send SIG_BYE if an error happened, instead */ + else + queryflag = -1; + + Kill(m.m.command.apid, (queryflag >= 0) ? SIGCONT : SIG_BYE); /* Send SIG_BYE if an error happened */ + queryflag = -1; } break; + case MSG_COMMAND: + DoCommandMsg(&m); + break; default: Msg(0, "Invalid message (type %d).", m.type); } -- cgit v1.2.1 From 7399960d86d8561aebd68d5fe331b44594decbd0 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 16 Feb 2010 11:27:49 -0500 Subject: Allow querying 'select'. Using this, it will be possible to detect if a particular window exists or not. --- src/comm.c | 2 +- src/process.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/comm.c b/src/comm.c index 4843e10..ba9806b 100644 --- a/src/comm.c +++ b/src/comm.c @@ -286,7 +286,7 @@ struct comm comms[RC_LAST + 1] = #ifdef COPY_PASTE { "scrollback", NEED_FORE|ARGS_1 }, #endif - { "select", ARGS_01 }, + { "select", CAN_QUERY|ARGS_01 }, { "sessionname", ARGS_01 }, { "setenv", ARGS_012 }, { "setsid", ARGS_1 }, diff --git a/src/process.c b/src/process.c index 5d6941d..34ed63d 100644 --- a/src/process.c +++ b/src/process.c @@ -1208,7 +1208,10 @@ int key; else if (args[0][0] == '.' && !args[0][1]) { if (!fore) - Msg(0, "select . needs a window"); + { + Msg(0, "select . needs a window"); + queryflag = -1; + } else { SetForeWindow(fore); @@ -1217,6 +1220,8 @@ int key; } else if (ParseWinNum(act, &n) == 0) SwitchWindow(n); + else if (queryflag >= 0) + queryflag = -1; /* ParseWinNum already prints out an appropriate error message. */ break; #ifdef AUTO_NUKE case RC_DEFAUTONUKE: -- cgit v1.2.1 From 2f39e64a76b2db7ce5ae88b6c087b8e60a47ce06 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 16 Feb 2010 11:36:55 -0500 Subject: Update documentation for queries. --- src/doc/screen.1 | 17 ++++++++++++++++- src/doc/screen.texinfo | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 3ac5571..c26bbc8 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -305,6 +305,22 @@ there is no session to resume. 12 (or more) indicates that there are 2 (or more) sessions to resume and you should specify which one to choose. In all other cases \*Q-q\*U has no effect. .TP 5 +.B \-Q +Some commands now can be queried from a remote session using this +flag, e.g. 'screen -Q windows'. The commands will send the +response to the stdout of the querying process. If there was an +error in the command, then the querying process will exit with +a non-zero status. + +The commands that can be queried now are: + \fBecho\fP + \fBinfo\fP + \fBlastmsg\fP + \fBselect\fP + \fBtime\fP + \fBtitle\fP + \fBwindows\fP +.TP 5 .BR \-r " [" \fIpid.tty.host ] .PD 0 .TP 5 @@ -376,7 +392,6 @@ the \fB-d\fP or \fB-r\fP option to tell screen to look only for attached or detached screen sessions. Note that this command doesn't work if the session is password protected. - .SH "DEFAULT KEY BINDINGS" .ta 12n 26n As mentioned, each diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 44d233e..f7371e1 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -374,6 +374,22 @@ there is no session to resume. 12 (or more) indicates that there are 2 (or more) sessions to resume and you should specify which one to choose. In all other cases @samp{-q} has no effect. +@item -Q +Some commands now can be queried from a remote session using this +flag, e.g. 'screen -Q windows'. The commands will send the +response to the stdout of the querying process. If there was an +error in the command, then the querying process will exit with +a non-zero status. + +The commands that can be queried now are: + @code{echo} + @code{info} + @code{lastmsg} + @code{select} + @code{time} + @code{title} + @code{windows} + @item -r [@var{pid.sessionname}] @itemx -r @var{sessionowner}/[@var{pid.sessionname}] Resume a detached @code{screen} session. No other options (except -- cgit v1.2.1 From 6c6d7edccebb2c33abbf461299f2cea99ecb1a17 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 16 Feb 2010 12:45:53 -0500 Subject: Make 'number' query-able. --- src/comm.c | 2 +- src/doc/screen.1 | 1 + src/doc/screen.texinfo | 1 + src/process.c | 3 ++- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/comm.c b/src/comm.c index ba9806b..aa512de 100644 --- a/src/comm.c +++ b/src/comm.c @@ -248,7 +248,7 @@ struct comm comms[RC_LAST + 1] = #ifdef MULTI { "nonblock", NEED_DISPLAY|ARGS_01 }, #endif - { "number", NEED_FORE|ARGS_01 }, + { "number", CAN_QUERY|NEED_FORE|ARGS_01 }, { "obuflimit", NEED_DISPLAY|ARGS_01 }, { "only", NEED_DISPLAY|ARGS_0 }, { "other", ARGS_0 }, diff --git a/src/doc/screen.1 b/src/doc/screen.1 index c26bbc8..afee22b 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -316,6 +316,7 @@ The commands that can be queried now are: \fBecho\fP \fBinfo\fP \fBlastmsg\fP + \fBnumber\fP \fBselect\fP \fBtime\fP \fBtitle\fP diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index f7371e1..2bdc775 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -385,6 +385,7 @@ The commands that can be queried now are: @code{echo} @code{info} @code{lastmsg} + @code{number} @code{select} @code{time} @code{title} diff --git a/src/process.c b/src/process.c index 34ed63d..c1d2da1 100644 --- a/src/process.c +++ b/src/process.c @@ -2961,7 +2961,7 @@ int key; break; case RC_NUMBER: if (*args == 0) - Msg(0, "This is window %d (%s).\n", fore->w_number, fore->w_title); + Msg(0, queryflag >= 0 ? "%d (%s)" : "This is window %d (%s).", fore->w_number, fore->w_title); else { int old = fore->w_number; @@ -2984,6 +2984,7 @@ int key; if (n < 0 || n >= maxwin) { Msg(0, "Given window position is invalid."); + queryflag = -1; return; } p = wtab[n]; -- cgit v1.2.1 From a889d858d6baae4d6bc2da98bf6ee82e52ad5fbc Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 16 Feb 2010 13:37:39 -0500 Subject: Error out if a pre-select window is not found. The man-page is updated to show that if the window selected using '-p' cannot be determined with -X or -Q flags, then the command specified will not be executed. Fixes #28783 in savannah. --- src/doc/screen.1 | 3 ++- src/doc/screen.texinfo | 3 ++- src/socket.c | 18 +++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index afee22b..b580b45 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -293,7 +293,8 @@ Preselect a window. This is useful when you want to reattach to a specific window or you want to send a command via the \*Q-X\*U option to a specific window. As with screen's select command, \*Q-\*U selects the blank window. As a special case for reattach, \*Q=\*U -brings up the windowlist on the blank window. +brings up the windowlist on the blank window. The command will not be +executed if the specified window could not be found. .TP 5 .B \-q Suppress printing of error messages. In combination with \*Q-ls\*U the exit diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 2bdc775..5941523 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -362,7 +362,8 @@ specific window or you want to send a command via the @samp{-X} option to a specific window. As with screen's select command, @samp{-} selects the blank window. As a special case for reattach, @samp{=} brings up the windowlist on the blank window, while a @samp{+} will -create new window. +create new window. The command will not be executed if the specified +window could not be found. @item -q Suppress printing of error messages. In combination with @samp{-ls} the exit diff --git a/src/socket.c b/src/socket.c index 70b57db..9e90564 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1653,7 +1653,7 @@ struct msg *mp; *--fc = 0; if (Parse(fullcmd, fc - fullcmd, args, argl) <= 0) { - /* XXX: Return some useful message back if MSG_QUERY */ + queryflag = -1; return; } #ifdef MULTIUSER @@ -1661,7 +1661,7 @@ struct msg *mp; if (user == 0) { Msg(0, "Unknown user %s tried to send a command!", mp->m.attach.auser); - /* XXX: Return some useful message back if MSG_QUERY */ + queryflag = -1; return; } #else @@ -1670,8 +1670,8 @@ struct msg *mp; #ifdef PASSWORD if (user->u_password && *user->u_password) { - Msg(0, "User %s has a password, cannot use -X option.", mp->m.attach.auser); - /* XXX: Return some useful message back if MSG_QUERY */ + Msg(0, "User %s has a password, cannot use remote commands (using -Q or -X option).", mp->m.attach.auser); + queryflag = -1; return; } #endif @@ -1692,7 +1692,15 @@ struct msg *mp; { int i = -1; if (strcmp(mp->m.command.preselect, "-")) - i = WindowByNoN(mp->m.command.preselect); + { + i = WindowByNoN(mp->m.command.preselect); + if (i < 0 || !wtab[i]) + { + Msg(0, "Could not find pre-select window."); + queryflag = -1; + return; + } + } fore = i >= 0 ? wtab[i] : 0; } else if (!fore) -- cgit v1.2.1 From e9f5aef00625cb54f35246a0da0c0b14236ed475 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Tue, 16 Feb 2010 14:21:57 -0500 Subject: Move 'silence' into 'Monitor' section. Closes #28743 on savannah. --- src/doc/screen.texinfo | 63 ++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 5941523..38d9a70 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -832,7 +832,7 @@ Delete the screen-exchange file. @xref{Screen Exchange}. @item @kbd{C-a _} (silence)@* -Start/stop monitoring the current window for inactivity. @xref{Silence}. +Start/stop monitoring the current window for inactivity. @xref{Monitor}. @item @kbd{C-a |} (split -v)@* @@ -965,7 +965,7 @@ Set default lines of scrollback. @xref{Scrollback}. @item defshell @var{command} Set the default program for new windows. @xref{Shell}. @item defsilence @var{state} -Select default idle monitoring behavior. @xref{Silence}. +Select default idle monitoring behavior. @xref{Monitor}. @item defslowpaste @var{msec} Select the default inter-character timeout when pasting. @xref{Paste}. @item defutf8 @var{state} @@ -1163,9 +1163,9 @@ Set the default program for new windows. @xref{Shell}. @item shelltitle @var{title} Set the default name for new windows. @xref{Shell}. @item silence [@var{state}|@var{seconds}] -Monitor a window for inactivity. @xref{Silence}. +Monitor a window for inactivity. @xref{Monitor}. @item silencewait @var{seconds} -Default timeout to trigger an inactivity notify. @xref{Silence}. +Default timeout to trigger an inactivity notify. @xref{Monitor}. @item sleep @var{num} Pause during startup. @xref{Startup}. @item slowpaste @var{msec} @@ -2161,7 +2161,7 @@ terminal emulation itself. * Kill:: Destroy an unwanted window * Login:: Control @file{/etc/utmp} logging * Mode:: Control the file mode of the pty -* Monitor:: Watch for activity in a window +* Monitor:: Watch for activity or inactivity in a window * Windows:: List the active windows * Hardstatus:: Set a window's hardstatus line @end menu @@ -2424,6 +2424,29 @@ the window-status display (@pxref{Windows}). Monitoring defaults to @samp{off} for all windows. @end deffn +@kindex _ +@deffn Command silence [@var{state}|@var{sec}] +(@kbd{C-a _})@* +Toggles silence monitoring of windows. When silence is turned on and an +affected window is switched into the background, you will receive the +silence notification message in the status line after a specified period +of inactivity (silence). The default timeout can be changed with the +@code{silencewait} command or by specifying a number of seconds instead of +@code{on} or @code{off}. Silence is initially off for all windows. +@end deffn + +@deffn Command defsilence state +(none)@* +Same as the @code{silence} command except that the default setting for +new windows is changed. Initial setting is `off'. +@end deffn + +@deffn Command silencewait @var{seconds} +(none)@* +Define the time that all windows monitored for silence should wait +before displaying a message. Default is 30 seconds. +@end deffn + @node Windows, Hardstatus, Monitor, Window Settings @section Windows @kindex w @@ -4792,7 +4815,6 @@ categories. * Nethack:: Use @code{nethack}-like error messages. * Nonblock:: Disable flow-control to a display. * Number:: Change the current window's number. -* Silence:: Notify on inactivity. * Time:: Display the time and load average. * Verbose:: Display window creation commands. * Version:: Display the version of @code{screen}. @@ -4942,7 +4964,7 @@ Same as the @code{nonblock} command except that the default setting for displays is changed. Initial setting is @code{off}. @end deffn -@node Number, Silence, Nonblock, Miscellaneous +@node Number, Time, Nonblock, Miscellaneous @section Number @kindex N @deffn Command number [[+|-]@var{n}] @@ -4954,32 +4976,7 @@ plus (`+') or minus (`-') will change the window's number by the relative amount specified. @end deffn -@node Silence, Time, Number, Miscellaneous -@section Silence -@kindex _ -@deffn Command silence [@var{state}|@var{sec}] -(@kbd{C-a _})@* -Toggles silence monitoring of windows. When silence is turned on and an -affected window is switched into the background, you will receive the -silence notification message in the status line after a specified period -of inactivity (silence). The default timeout can be changed with the -@code{silencewait} command or by specifying a number of seconds instead of -@code{on} or @code{off}. Silence is initially off for all windows. -@end deffn - -@deffn Command defsilence state -(none)@* -Same as the @code{silence} command except that the default setting for -new windows is changed. Initial setting is `off'. -@end deffn - -@deffn Command silencewait @var{seconds} -(none)@* -Define the time that all windows monitored for silence should wait -before displaying a message. Default is 30 seconds. -@end deffn - -@node Time, Verbose, Silence, Miscellaneous +@node Time, Verbose, Number, Miscellaneous @section Time @kindex t @kindex C-t -- cgit v1.2.1 From a83eee72adcd5519d604a6f4bbf21337e3205618 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Tue, 16 Feb 2010 14:27:27 -0500 Subject: Update the man-page. The man-page is updated for: mousetrack, defmousetrack, focusminsize, group and layout commands. Closes #28715 on savannah. --- src/doc/screen.1 | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 1 deletion(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index b580b45..9da825d 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -1578,6 +1578,12 @@ Same as the \fBmonitor\fP command except that the default setting for new windows is changed. Initial setting is `off'. .sp .ne 3 +.BR "defmousetrack on" | off +.PP +Same as the \fBmousetrack\fP command except that the default setting for new +windows is changed. Initial setting is `off'. +.sp +.ne 3 .B defnonblock .BR on | off | \fInumsecs .PP @@ -1888,6 +1894,20 @@ region respectively. Useful bindings are (j and k as in vi) Note that \fBk\fP is traditionally bound to the \fIkill\fP command. .sp .ne 3 +.BI "focusminsize [ ( " width "|max|_ ) ( " height "|max|_ ) ]" +.PP +This forces any currently selected region to be automatically +resized at least a certain \fIwidth\fP and \fIheight\fP. All +other surrounding regions will be resized in order to accomodate. +This constraint follows everytime the \*Qfocus\*U command is +used. The \*Qresize\*U command can be used to increase either +dimension of a region, but never below what is set with +\*Qfocusminsize\*U. The underscore `_' is a synonym for +\fBmax\fP. Setting a \fIwidth\fP and \fIheight\fP of `0 0' +(zero zero) will undo any constraints and allow for manual resizing. +Without any parameters, the minimum width and height is shown. +.sp +.ne 3 .BR "gr " [ on | off ] .PP Turn GR charset switching on/off. Whenever screen sees an input @@ -1897,6 +1917,15 @@ default (see also \*Qdefgr\*U) is not to process GR switching because otherwise the ISO88591 charset would not work. .sp .ne 3 +.BI group +.RI [ grouptitle ] +.PP +Change or show the group the current window belongs to. Windows can +be moved around between different groups by specifying the name of +the destination group. Without specifying a group, the title of the +current group is displayed. +.sp +.ne 3 .B hardcopy .RB [ -h ] .RI [ file ] @@ -2118,6 +2147,123 @@ away when you press a key (unless your terminal has a hardware status line). Refer to the commands \*Qmsgwait\*U and \*Qmsgminwait\*U for fine tuning. .sp .ne 3 +.BR "layout new " [\fItitle\fP] +.PP +Create a new layout. The screen will change to one whole region +and be switched to the blank window. From here, you build the +regions and the windows they show as you desire. The new layout +will be numbered with the smallest available integer, starting +with zero. You can optionally give a title to your new layout. +Otherwise, it will have a default title of \*Qlayout\*U. You +can always change the title later by using the command +\fBlayout title\fP. +.sp +.ne 3 +.BR "layout remove " [\fIn|title\fP] +.PP +Remove, or in other words, delete the specified layout. Either +the number or the title can be specified. Without either +specification, \fIscreen\fP will remove the current layout. + +Removing a layout does not affect your set windows or regions. +.sp +.ne 3 +.B layout next +.PP +Switch to the next layout available +.sp +.ne 3 +.B layout prev +.PP +Switch to the previous layout available +.sp +.ne 3 +.BR "layout select " [\fIn|title\fP] +.PP +Select the desired layout. Either the number or the title can +be specified. Without either specification, \fIscreen\fP will +prompt and ask which screen is desired. To see which layouts are +available, use the \fBlayout show\fP command. +.sp +.ne 3 +.B layout show +.PP +List on the message line the number(s) and title(s) of the available +layout(s). The current layout is flagged. +.sp +.ne 3 +.BR "layout title " [\fItitle\fP] +.PP +Change or display the title of the current layout. A string given +will be used to name the layout. Without any options, the current +title and number is displayed on the message line. +.sp +.ne 3 +.BR "layout number " [\fIn\fP] +.PP +Change or display the number of the current layout. An integer given +will be used to number the layout. Without any options, the current +number and title is displayed on the message line. +.sp +.ne 3 +.BR "layout attach " [\fItitle\fP|\fB:last\fP] +.PP +Change or display which layout to reattach back to. The default is +\fB:last\fP, which tells \fIscreen\fP to reattach back to the last +used layout just before detachment. By supplying a title, You can +instruct \fIscreen\fP to reattach to a particular layout regardless +which one was used at the time of detachment. Without any options, +the layout to reattach to will be shown in the message line. +.sp +.ne 3 +.BR "layout save " [\fIn|title\fP] +.PP +Remember the current arrangement of regions. When used, \fIscreen\fP +will remember the arrangement of vertically and horizontally split +regions. This arrangement is restored when a \fIscreen\fP session +is reattached or switched back from a different layout. If the +session ends or the \fIscreen\fP process dies, the layout +arrangements are lost. The \fBlayout dump\fP command should help +in this siutation. If a number +or title is supplied, \fIscreen\fP will remember the arrangement of +that particular layout. Without any options, \fIscreen\fP will +remember the current layout. + +Saving your regions can be done automatically by using the +\fBlayout autosave\fP command. +.sp +.ne 3 +.BR "layout autosave " [\fBon|off\fP] +.PP +Change or display the status of automatcally saving layouts. The +default is \fBon\fP, meaning when \fIscreen\fP is detached or +changed to a different layout, the arrangement of regions and windows +will be remembered at the time of change and restored upon return. +If autosave is set to \fBoff\fP, that arrangement will only be +restored to either to the last manual save, using \fBlayout save\fP, +or to when the layout was first created, to a single region with +a single window. Without either an \fBon\fP or \fBoff\fP, the +current status is displayed on the message line. +.sp +.ne 3 +.BR "layout dump " [\fIfilename\fP] +.PP +Write to a file the order of splits made in the current layout. This +is useful to recreate the order of your regions used in your current +layout. Only the current layout is recorded. While the order of the +regions are recorded, the sizes of those regions and which windows +correspond to which regions are not. If no filename is specified, +the default is \fIlayout-dump\fP, saved in the directory that the +\fIscreen\fP process was started in. If the file already exists, +\fBlayout dump\fP will append to that file. As an example: +.PP +.nf + C-a : layout dump /home/user/.screenrc +.fi +.PP +will save or append the layout to the user's \fI.screenrc\fP file. +.sp +.ne 3 .B license .PP Display the disclaimer page. This is done whenever @@ -2270,6 +2416,18 @@ with an `@' in the window-status display. Monitoring is initially off for all windows. .sp .ne 3 +.BR "mousetrack " [ on | off ] +.PP +This command determines whether +.I screen +will watch for +mouse clicks. When this command is enabled, regions that have +been split in various ways can be selected by pointing to them +with a mouse and left-clicking them. Without specifying \fBon\fP +or \fBoff\fP, the current state is displayed. The default state +is determined by the \*Qdefmousetrack\*U command. +.sp +.ne 3 .BI "msgminwait " sec .PP Defines the time @@ -2589,7 +2747,7 @@ resize min minimize current region height .PP .sp .ne 3 -.B "screen \fP[\fI-opts\fP] [\fIn\fP] [\fIcmd\fP [\fIargs\fP]]" +.B "screen \fP[\fI-opts\fP] [\fIn\fP] [\fIcmd\fP [\fIargs\fP]|\fB//group\fP]" .PP Establish a new window. The flow-control options (\fB\-f\fP, \fB\-fn\fP and \fB\-fa\fP), @@ -2603,6 +2761,9 @@ the window number \fIn\fP is assigned to the newly created window (or, if this number is already in-use, the next available number). If a command is specified after \*Qscreen\*U, this command (with the given arguments) is started in the window; otherwise, a shell is created. +If \fB//group\fP is supplied, a container-type window is created in +which other windows may be created inside it. + Thus, if your \*Q.screenrc\*U contains the lines .sp .nf @@ -3044,6 +3205,7 @@ vice versa. .B windowlist .RB [ -b ] .RB [ -m ] +.RB [ -g ] .br .B windowlist .B string @@ -3056,6 +3218,8 @@ vice versa. Display all windows in a table for visual window selection. The desired window can be selected via the standard movement keys (see the \*Qcopy\*U command) and activated via the return key. +If screen was in a window group, screen will +back out of the group and then display the windows in that group. If the .B -b option is given, screen will switch to the blank window before @@ -3064,6 +3228,10 @@ The .B -m option changes the order of the windows, instead of sorting by window numbers screen uses its internal most-recently-used list. +The +.B -g +option will show the windows inside any groups in that level +and downwards. The table format can be changed with the \fBstring\fP and \fBtitle\fP option, the title is displayed as table heading, while -- cgit v1.2.1 From 978f859e5065fa9c4f0e4a904d3db127fd89f4af Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Tue, 16 Feb 2010 14:33:06 -0500 Subject: Document 'layout dump', and clarify 'layout save'. Closes #28586 on savannah. --- src/ChangeLog | 1 + src/doc/screen.texinfo | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 5052b35..e6741cf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -93,6 +93,7 @@ Version 4.1.0 (??/??/20??): * Romain Francoise * Emanuele Giaquinta * Yi-Hsuan Hsin + * Chris Jones * Steve Kemp * Ryan Niebur * Jan Christoph Nordholz diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 38d9a70..58eb617 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1058,6 +1058,8 @@ Show or set which layout to reattach to. @xref{Layout}. Remember the organization of a layout. @xref{Layout}. @item layout autosave [@var{on}|@var{off}] Show or set the status of layout saving. @xref{Layout}. +@item layout dump [filename] +Save the layout arrangement to a file. @xref{Layout}. @item license Display licensing information. @xref{Startup}. @item lockscreen @@ -2125,7 +2127,10 @@ the layout to reattach to will be shown in the message line. Remember the current arrangement of regions. When used, @code{screen} will remember the arrangement of vertically and horizontally split regions. This arrangement is restored when a @code{screen} session -is reattached or switched back from a different layout. If a number +is reattached or switched back from a different layout. If the +session ends or the @code{screen} process dies, the layout +arrangements are lost. The @code{layout dump} command should help +in this siutation. If a number or title is supplied, @code{screen} will remember the arrangement of that particular layout. Without any options, @code{screen} will remember the current layout. @@ -2147,6 +2152,21 @@ a single window. Without either an @code{on} or an @code{off}, the current status is displayed on the message line. @end deffn +@deffn Command layout @code{dump} [filename] +(none)@* +Write to a file the order of splits made in the current layout. This +is useful to recreate the order of your regions used in your current +layout. Only the current layout is recorded. While the order of the +regions are recorded, the sizes of those regions and which windows +correspond to which regions are not. If no filename is specified, +the default is @file{layout-dump}, saved in the directory that the +@code{screen} process was started in. If the file already exists, +@code{layout dump} will append to that file. As an example: +@example +layout dump /home/user/.screenrc +@end example +will save or append the layout to the user's @file{.screenrc} file. +@end deffn @node Window Settings, Virtual Terminal, Regions, Top @chapter Window Settings -- cgit v1.2.1 From 7dc1b16ca3ebac72f1a17c130ca57ff9652f6449 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Tue, 16 Feb 2010 14:36:04 -0500 Subject: Update info-page for 'stuff'. Closes #28616 on savannah. --- src/doc/screen.texinfo | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 58eb617..1c55107 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1180,7 +1180,7 @@ Deprecated. Use @code{rendition so} instead. @xref{Rendition}. Split region into two parts. @xref{Regions}. @item startup_message @var{state} Display copyright notice on startup. @xref{Startup}. -@item stuff @var{string} +@item stuff [@var{string}] Stuff a string in the input buffer of a window. @xref{Paste}. @item su [@var{username} [@var{password} [@var{password2}]]] Identify a user. @xref{Multiuser Session}. @@ -3578,10 +3578,11 @@ display (terminal attached), as the registers are a global resource. The paste buffer exists once for every user. @end deffn -@deffn Command stuff string +@deffn Command stuff [string] (none)@* Stuff the string @var{string} in the input buffer of the current window. This is like the @code{paste} command, but with much less overhead. +Without a paramter, @code{screen} will prompt for a string to stuff. You cannot paste large buffers with the @code{stuff} command. It is most useful for key bindings. @xref{Bindkey}. @end deffn -- cgit v1.2.1 From 45ddce39d1cc4b9c275cd70149686bc686a09368 Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Tue, 16 Feb 2010 14:39:36 -0500 Subject: Spelling fixes. Closes #28473 on savannah. --- src/doc/screen.texinfo | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 1c55107..94c2aa3 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1087,7 +1087,7 @@ Insert the command character. @xref{Command Character}. @item monitor [@var{state}] Monitor activity in window. @xref{Monitor}. @item mousetrack [@var{on}|@var{off}] -Enable selecting splitted regions with mouse clicks. @xref{Mousetrack}. +Enable selecting split regions with mouse clicks. @xref{Mousetrack}. @item msgminwait @var{sec} Set minimum message wait. @xref{Message Wait}. @item msgwait @var{sec} @@ -1474,7 +1474,7 @@ For telnet windows, the command @code{break} sends the telnet code @section Window Groups @cindex window groups Screen provides a method for grouping windows together. Windows can be -organized in a heirarchial fashion, resembling a tree structure. New +organized in a hierarchical fashion, resembling a tree structure. New screens are created using the @code{screen} command while new groups are created using @code{screen //group}. @xref{Screen Command}. @@ -1935,7 +1935,7 @@ bottom of each other. Using -v will create a vertical split, causing the new regions to appear side by side of each other. With this current implementation of @code{screen}, scrolling data -will appear much slower in a vertically splited region than one +will appear much slower in a vertically split region than one that is not. This should be taken into consideration if you need to use system commands such as @code{cat} or @code{tail -f}. @end deffn @@ -2027,7 +2027,7 @@ automatically if the window is displayed more than once. This forces any currently selected region to be automatically resized at least a certain @var{width} and @var{height}. All other surrounding regions will be resized in order to accomodate. -This constraint follows everytime the @code{focus} command is +This constraint follows every time the @code{focus} command is used. The @code{resize} command can be used to increase either dimension of a region, but never below what is set with @code{focusminsize}. The underscore @samp{_} is a synonym for @@ -2039,16 +2039,16 @@ Without any parameters, the minimum width and height is shown. @node Layout, , Focusminsize, Regions @section Layout @cindex layout -Using regions, and perhaps a large enough terminal, you can create -a more of a desktop feel to @code{screen}. By being able to split +Using regions, and perhaps a large enough terminal, you can give +@code{screen} more of a desktop feel. By being able to split regions horizontally or vertically, you can take advantage of the lesser used spaces of your terminal. The catch to these splits has been that they're not kept between screen detachments and reattachments. -Layouts will help your organization of regions. You can create one +Layouts will help organize your regions. You can create one layout of four horizontal regions and then create a separate layout -of regions in a two by two array. The regions don't have to contain -the same windows. You can easily switch between layouts and keep +of regions in a two by two array. The regions could contain the same windows, +but they don't have to. You can easily switch between layouts and keep them between detachments and reattachments. Note that there are several subcommands to @code{layout}. @@ -2141,7 +2141,7 @@ Saving your regions can be done automatically by using the @deffn Command layout @code{autosave} [@code{on}|@code{off}] (none)@* -Change or display the status of automatcally saving layouts. The +Change or display the status of automatically saving layouts. The default is @code{on}, meaning when @code{screen} is detached or changed to a different layout, the arrangement of regions and windows will be remembered at the time of change and restored upon return. -- cgit v1.2.1 From e01e137673bf09e2897ead3170719c5a2fb1f087 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 16 Feb 2010 16:29:34 -0500 Subject: Allow expanding the command to full buffer size. Without this, commands like '-Q echo $STY' would fail with error: no space left for variable expansion. --- src/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/socket.c b/src/socket.c index 9e90564..0f08d60 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1651,7 +1651,7 @@ struct msg *mp; } if (fc != fullcmd) *--fc = 0; - if (Parse(fullcmd, fc - fullcmd, args, argl) <= 0) + if (Parse(fullcmd, sizeof fullcmd, args, argl) <= 0) { queryflag = -1; return; -- cgit v1.2.1 From 058bb9e0df3e8069752464268ce1cfbb062d207b Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 17 Feb 2010 01:30:00 -0500 Subject: Changelog the last few changes. --- src/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index e6741cf..dd85d82 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -39,6 +39,7 @@ Version 4.1.0 (??/??/20??): * '-g' parameter to 'windowlist' to show nested list of windows. * '//group' parameter to 'screen' to create a grouped window. * 'blankerprg' shows the currently set command on no argument. + * 'maxwin' can now be used to increase the number of maximum windows. .screenrc: * $PID expands to the PID of the screen session. @@ -66,6 +67,9 @@ Version 4.1.0 (??/??/20??): * Some more readline-like bindings in input mode (e.g. ^W, ^D, ^P, ^N etc.) * Fix displaying unicode characters in the caption/hardstatus on UTF8 locale. * A revamped displays list (for 'displays' command) + * Increased default maximum number of windows from 40 to 100. + * Increased number color/attribute changes in caption/hardstatus string from 16 to 256. + * Some commands can be remotely queried using the -Q command-line flag. In-Progress: * Scripting support (thanks to Google Summer of Code 2009 project by Rui Guo) -- cgit v1.2.1 From 8b46d8a5d214ab124db868a47c5e569f1e83c33e Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 18 Feb 2010 10:23:07 -0500 Subject: Bump msg revision number so proper checking can be done. --- src/screen.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/screen.h b/src/screen.h index fa4cc82..fe363a1 100644 --- a/src/screen.h +++ b/src/screen.h @@ -178,9 +178,11 @@ struct mode /* * versions of struct msg: * 0: screen version 3.6.6 (version count introduced) - * 1: screen version 4.1.0 + * 1: screen version 4.1.0devel (revisions e3fc19a1 upto 8147d086) + * 2: screen version 4.1.0devel (revisions XXXXXXXX upto YYYYYYYY) */ -#define MSG_VERSION 1 +#define MSG_VERSION 2 + #define MSG_REVISION (('m'<<24) | ('s'<<16) | ('g'<<8) | MSG_VERSION) struct msg { -- cgit v1.2.1 From 75441d0e47f3bcc077bf1875b1338a385f6d77d9 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 18 Feb 2010 10:29:36 -0500 Subject: Update comment regarding msg-version history. --- src/screen.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/screen.h b/src/screen.h index fe363a1..a24c021 100644 --- a/src/screen.h +++ b/src/screen.h @@ -178,8 +178,10 @@ struct mode /* * versions of struct msg: * 0: screen version 3.6.6 (version count introduced) - * 1: screen version 4.1.0devel (revisions e3fc19a1 upto 8147d086) - * 2: screen version 4.1.0devel (revisions XXXXXXXX upto YYYYYYYY) + * 1: screen version 4.1.0devel (revisions e3fc19a upto 8147d08) + * A few revisions after 8147d08 incorrectly + * carried version 1, but should have carried 2. + * 2: screen version 4.1.0devel (revisions 8b46d8a upto YYYYYYY) */ #define MSG_VERSION 2 -- cgit v1.2.1 From b7d33bdc3cc3d60cd23410372f908a8fb5b5a728 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 18 Feb 2010 14:30:41 -0500 Subject: Fix creating numbered windows. This is another bug introduced when the max number of windows was made configurable. Bug reported by Christian Ebert in <20100218160955.GC21624@krille.blacktrash.org>. And fix a typo. --- src/process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/process.c b/src/process.c index c1d2da1..3ea86cb 100644 --- a/src/process.c +++ b/src/process.c @@ -4105,7 +4105,7 @@ int key; else { if (!windows) - wtab = realloc(wtab, n * sizeof(struct win)); + wtab = realloc(wtab, n * sizeof(struct win *)); maxwin = n; } break; @@ -5978,7 +5978,7 @@ char *fn, **av; if (*buf != '\0') nwin.aka = buf; num = atoi(*av); - if (num < 0 || num > maxwin - 1) + if (num < 0 || (maxwin && num > maxwin - 1) || (!maxwin && num > MAXWIN - 1)) { Msg(0, "%s: illegal screen number %d.", fn, num); num = 0; -- cgit v1.2.1 From 23b17abd7a9f00894f820eeba824623940d26a38 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 18 Feb 2010 15:20:36 -0500 Subject: Exclude the PID when expanding $STY. Excluding the PID from the expansion of $STY makes it possible to do, e.g. 'source screenrc-$STY' to load session-specific commands. If the PID is desired, for some reason, then '$PID.$STY' should be used instead. --- src/process.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/process.c b/src/process.c index 3ea86cb..e131384 100644 --- a/src/process.c +++ b/src/process.c @@ -4694,7 +4694,12 @@ int bufl, *argl; else if (!strcmp(ps, "PID")) sprintf(xbuf, "%d", getpid()); else if (!strcmp(ps, "STY")) - v = SockName; + { + if ((v = strchr(SockName, '.'))) /* Skip the PID */ + v++; + else + v = SockName; + } else v = getenv(ps); } -- cgit v1.2.1 From bd6946ebc341b0059b3f5cda51787329fa51b536 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 19 Feb 2010 13:24:00 -0500 Subject: Allow searching in input history. You enter some text in the input, then press ctrl+r to cycle through the history that has the entered text as a substring. --- src/input.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/src/input.c b/src/input.c index 98bef8a..cbe7dc6 100644 --- a/src/input.c +++ b/src/input.c @@ -65,6 +65,7 @@ struct inpdata void (*inpfinfunc) __P((char *buf, int len, char *priv)); char *priv; /* private data for finfunc */ int privdata; /* private data space */ + char *search; /* the search string */ }; static struct LayFuncs InpLf = @@ -160,6 +161,7 @@ int data; inpdata->priv = priv; inpdata->inpstringlen = 0; inpdata->inpstring = NULL; + inpdata->search = NULL; if (istr) inp_setprompt(istr, (char *)NULL); } @@ -210,11 +212,13 @@ int *plen; char ch; struct inpdata *inpdata; struct display *inpdisplay; - int prev, next; + int prev, next, search = 0; inpdata = (struct inpdata *)flayer->l_data; inpdisplay = display; +#define RESET_SEARCH do { if (inpdata->search) Free(inpdata->search); } while (0) + LGotoPos(flayer, inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos), INPUTLINE); if (ppbuf == 0) { @@ -272,14 +276,16 @@ int *plen; LGotoPos(flayer, x, INPUTLINE); } } + RESET_SEARCH; } else if ((ch == '\b' || ch == 0177) && inpdata->inp.pos > 0) { erase_chars(inpdata, p-1, p, x, 1); + RESET_SEARCH; } else if (ch == '\025') /* CTRL-U */ { - x = inpdata->inpstringlen; + x = inpdata->inpstringlen; if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO)) { LClearArea(flayer, x, INPUTLINE, x + inpdata->inp.len - 1, INPUTLINE, 0, 0); @@ -289,7 +295,7 @@ int *plen; } else if (ch == '\013') /* CTRL-K */ { - x = inpdata->inpstringlen + inpdata->inp.pos; + x = inpdata->inpstringlen + inpdata->inp.pos; if (inpdata->inp.len > inpdata->inp.pos && !(inpdata->inpmode & INP_NOECHO)) { LClearArea(flayer, x, INPUTLINE, x + inpdata->inp.len - inpdata->inp.pos - 1, INPUTLINE, 0, 0); @@ -305,10 +311,12 @@ int *plen; while (p > inpdata->inp.buf && *(p - 1) != ' ') p--; erase_chars(inpdata, p, oldp, x, 1); + RESET_SEARCH; } else if (ch == '\004' && inpdata->inp.pos < inpdata->inp.len) /* CTRL-D */ { erase_chars(inpdata, p, p+1, x, 0); + RESET_SEARCH; } else if (ch == '\001' || (unsigned char)ch == 0201) /* CTRL-A */ { @@ -333,16 +341,46 @@ int *plen; else if ((prev = ((ch == '\020' || (unsigned char)ch == 0220) && /* CTRL-P */ inpdata->inp.prev)) || (next = ((ch == '\016' || (unsigned char)ch == 0216) && /* CTRL-N */ - inpdata->inp.next))) + inpdata->inp.next)) || + (search = ((ch == '\022' || (unsigned char)ch == 0222) && inpdata->inp.prev))) { struct mchar mc; + struct inpline *sel; + int pos = -1; + mc = mchar_so; + + if (prev) + sel = inpdata->inp.prev; + else if (next) + sel = inpdata->inp.next; + else + { + /* search */ + inpdata->inp.buf[inpdata->inp.len] = 0; /* Remove the ctrl-r from the end */ + if (!inpdata->search) + inpdata->search = SaveStr(inpdata->inp.buf); + for (sel = inpdata->inp.prev; sel; sel = sel->prev) + { + char *f; + if ((f = strstr(sel->buf, inpdata->search))) + { + pos = f - sel->buf; + break; + } + } + if (!sel) + continue; /* Did not find a match. Process the next input. */ + } + if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO)) LClearArea(flayer, inpdata->inpstringlen, INPUTLINE, inpdata->inpstringlen + inpdata->inp.len - 1, INPUTLINE, 0, 0); - if (prev && !inpdata->inp.next) + if ((prev || search) && !inpdata->inp.next) inphist = inpdata->inp; - memcpy(&inpdata->inp, prev ? inpdata->inp.prev : inpdata->inp.next, sizeof(struct inpline)); + memcpy(&inpdata->inp, sel, sizeof(struct inpline)); + if (pos != -1) + inpdata->inp.pos = pos; if (inpdata->inp.len > inpdata->inpmaxlen) inpdata->inp.len = inpdata->inpmaxlen; if (inpdata->inp.pos > inpdata->inp.len) @@ -409,9 +447,17 @@ int *plen; (*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv); else (*inpdata->inpfinfunc)(pbuf - 1, 0, inpdata->priv); - free((char *)inpdata); + if (inpdata->search) + free(inpdata->search); + free(inpdata); return; } + else + { + /* The user was searching, and then pressed some non-control input. So reset + * the search string. */ + RESET_SEARCH; + } } if (!(inpdata->inpmode & INP_RAW)) { @@ -435,7 +481,7 @@ int y, xs, xe, isblank; { int q, r, s, l, v; struct inpdata *inpdata; - + inpdata = (struct inpdata *)flayer->l_data; if (y != INPUTLINE) { -- cgit v1.2.1 From e29d6de0f8f4c40806e9b3300ed3609aaefc104b Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 21 Feb 2010 01:14:06 -0500 Subject: Start working on a generic list framework. The list of displays uses this framework. Eventually, the list of windows, bindkeys etc. will also use this framework. In the list of displays, you can press 'd' to detach the selected display (and 'D' to power-detach). Eventually, the plan is to add typeahead search in the list too. --- src/Makefile.in | 8 +- src/help.c | 4 +- src/list_display.c | 363 +++++++++++++++++++++++------------------------------ src/list_generic.c | 266 +++++++++++++++++++++++++++++++++++++++ src/list_generic.h | 63 ++++++++++ 5 files changed, 492 insertions(+), 212 deletions(-) create mode 100644 src/list_generic.c create mode 100644 src/list_generic.h diff --git a/src/Makefile.in b/src/Makefile.in index 8120726..0706290 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -62,11 +62,12 @@ CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \ termcap.c input.c attacher.c pty.c process.c display.c comm.c \ kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \ sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c \ - list_display.c + list_display.c list_generic.c OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ termcap.o input.o attacher.o pty.o process.o display.o comm.o \ kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \ + list_generic.o list_display.o \ sched.o teln.o nethack.o encoding.o canvas.o layout.o viewport.o all: screen @@ -303,7 +304,7 @@ loadav.o: layout.h viewport.h canvas.h loadav.c config.h screen.h os.h osdef.h a comm.h layer.h term.h image.h display.h window.h extern.h putenv.o: layout.h viewport.h canvas.h putenv.c config.h help.o: layout.h viewport.h canvas.h help.c config.h screen.h os.h osdef.h ansi.h acls.h \ - comm.h layer.h term.h image.h display.h window.h extern.h list_display.c + comm.h layer.h term.h image.h display.h window.h extern.h list_display.c list_generic.h termcap.o: layout.h viewport.h canvas.h termcap.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h input.o: layout.h viewport.h canvas.h input.c config.h screen.h os.h osdef.h ansi.h acls.h \ @@ -346,3 +347,6 @@ layout.o: layout.h viewport.h canvas.h layout.c config.h screen.h os.h osdef.h a viewport.o: layout.h viewport.h canvas.h viewport.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h \ braille.h +list_generic.o: list_generic.h list_generic.c layer.h +list_display.o: list_generic.h list_display.c layer.h + diff --git a/src/help.c b/src/help.c index e98f50c..1e37354 100644 --- a/src/help.c +++ b/src/help.c @@ -33,6 +33,8 @@ #include "screen.h" #include "extern.h" +#include "list_generic.h" + char version[60]; /* initialised by main() */ extern struct layer *flayer; @@ -681,8 +683,6 @@ int y, xs, xe, isblank; } -#include "list_display.c" - /* ** ** here is the windowlist diff --git a/src/list_display.c b/src/list_display.c index 3693f01..28ec7bb 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -1,4 +1,7 @@ -/* Copyright (c) 2008, 2009 +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -28,150 +31,16 @@ /* Deals with the list of displays */ -#ifdef MULTI - -struct displaysdata -{ - struct display *selected; /* The selected display */ - struct display *current; /* The current display (that's showing this list) */ -}; - -static void DisplaysProcess __P((char **, int *)); -static void DisplaysRedisplayLine __P((int, int, int, int)); -static void displayspage __P((struct displaysdata *)); - -static struct LayFuncs DisplaysLf = -{ - DisplaysProcess, - HelpAbort, - DisplaysRedisplayLine, - DefClearLine, - DefRewrite, - DefResize, - DefRestore -}; +#include "config.h" -void -display_displays() -{ - struct displaysdata *ddata; - if (flayer->l_width < 10 || flayer->l_height < 5) - { - LMsg(0, "Window size too small for displays page"); - return; - } - if (InitOverlayPage(sizeof(struct displaysdata), &DisplaysLf, 0)) - return; - flayer->l_mode = 1; - flayer->l_x = 0; - flayer->l_y = flayer->l_height - 1; - ddata = flayer->l_data; - ddata->current = display; - ddata->selected = display; - displayspage(ddata); -} +#include "screen.h" +#include "list_generic.h" -static void -display_list_change(struct displaysdata *ddata, int dir) -{ - struct display *d; - for (d = displays; d; d = d->d_next) - { - if (dir == -1 && d->d_next == ddata->selected) - { - ddata->selected = d; - break; - } - else if (dir == 1 && d == ddata->selected && d->d_next) - { - ddata->selected = d->d_next; - break; - } - } - - if (d) - { - /* Selection changed */ - displayspage(ddata); - } -} - -static void -DisplaysProcess(ppbuf, plen) -char **ppbuf; -int *plen; -{ - int done = 0; - - ASSERT(flayer); - while (!done && *plen > 0) - { - unsigned char ch = (unsigned char)**ppbuf; - ++*ppbuf; - --*plen; - if (flayer->l_mouseevent.start) - { - int r = LayProcessMouse(flayer, ch); - if (r == -1) - LayProcessMouseSwitch(flayer, 0); - else - { - if (r) - ch = 0222; - else - continue; - } - } - switch (ch) - { - case ' ': - displayspage(flayer->l_data); - break; - case '\r': - case '\n': - HelpAbort(); - done = 1; - break; - - case 0220: /* up */ - case 16: /* ^P like emacs */ - case 'k': - display_list_change(flayer->l_data, -1); - break; - - case 0216: /* down */ - case 14: /* ^N like emacs */ - case 'j': - display_list_change(flayer->l_data, 1); - break; - - case 0222: /* mouse event */ - if (flayer->l_mouseevent.start) - { - /* All the data is available to process the mouse event. */ - int button = flayer->l_mouseevent.buffer[0]; - if (button == 'a') - { - /* Scroll down */ - display_list_change(flayer->l_data, 1); - } - else if (button == '`') - { - /* Scroll up */ - display_list_change(flayer->l_data, -1); - } - LayProcessMouseSwitch(flayer, 0); - } - else - LayProcessMouseSwitch(flayer, 1); - break; - - default: - break; - } - } -} +#ifdef MULTI +extern struct layer *flayer; +extern struct display *display, *displays; +extern struct mchar mchar_blank, mchar_so; /* * layout of the displays page is as follows: @@ -180,7 +49,7 @@ xterm 80x42 jnweiger@/dev/ttyp4 0(m11) &rWx facit 80x24 nb mlschroe@/dev/ttyhf 11(tcsh) rwx xterm 80x42 jnhollma@/dev/ttyp5 0(m11) &R.x - | | | | | | | | ¦___ window permissions + | | | | | | | | ¦___ window permissions | | | | | | | | (R. is locked r-only, | | | | | | | | W has wlock) | | | | | | | |___ Window is shared @@ -191,97 +60,175 @@ xterm 80x42 jnhollma@/dev/ttyp5 0(m11) &R.x | | |___ Display is in nonblocking mode. Shows 'NB' if obuf is full. | |___ Displays geometry as width x height. |___ the terminal type known by screen for this display. - + */ -static void -displayspage(ddata) -struct displaysdata *ddata; +static int +gl_Display_header(struct ListData *ldata) { - int y, l; + leftline("term-type size user interface window Perms", 0, 0); + leftline("---------- ------- ---------- ----------------- ---------- -----", 1, 0); + return 2; +} + +static int +gl_Display_footer(struct ListData *ldata) +{ + centerline("[Press Space to refresh; Return to end.]", flayer->l_height - 1); +} + +static int +gl_Display_row(struct ListData *ldata, struct ListRow *lrow) +{ + struct display *d = lrow->data; char tbuf[80]; - struct display *d; - struct win *w; static char *blockstates[5] = {"nb", "NB", "Z<", "Z>", "BL"}; + struct win *w = d->d_fore; struct mchar m_current = mchar_blank; m_current.attr = A_BD; - if (!ddata) - return; + sprintf(tbuf, " %-10.10s%4dx%-4d%10.10s@%-16.16s%s", + d->d_termname, d->d_width, d->d_height, d->d_user->u_name, + d->d_usertty, + (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); - LClearAll(flayer, 0); + if (w) + { + int l = 10 - strlen(w->w_title); + if (l < 0) + l = 0; + sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c", + w->w_number, w->w_title, l, "", + /* w->w_dlist->next */ 0 ? '&' : ' ', + /* + * The rwx triple: + * -,r,R no read, read, read only due to foreign wlock + * -,.,w,W no write, write suppressed by foreign wlock, + * write, own wlock + * -,x no execute, execute + */ +#ifdef MULTIUSER + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : + ((w->w_wlock == WLOCK_OFF || d->d_user == w->w_wlockuser) ? + 'r' : 'R')), + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : + ((w->w_wlock == WLOCK_OFF) ? 'w' : + ((d->d_user == w->w_wlockuser) ? 'W' : 'v'))), + (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : 'x') +#else + 'r', 'w', 'x' +#endif + ); + } + leftline(tbuf, lrow->y, lrow == ldata->selected ? &mchar_so : d == display ? &m_current : 0); - leftline("term-type size user interface window Perms", 0, 0); - leftline("---------- ------- ---------- ----------------- ---------- -----", 1, 0); - y = 2; + return 1; +} +static void +gl_Display_rebuild(struct ListData *ldata) +{ + /* recreate the rows */ + struct display *d; + struct ListRow *row = NULL; for (d = displays; d; d = d->d_next) { - struct mchar *mc; - w = d->d_fore; + row = glist_add_row(ldata, d, row); + if (d == display) + ldata->selected = row; + } - if (y >= flayer->l_height - 3) - break; - sprintf(tbuf, " %-10.10s%4dx%-4d%10.10s@%-16.16s%s", - d->d_termname, d->d_width, d->d_height, d->d_user->u_name, - d->d_usertty, - (d->d_blocked || d->d_nonblock >= 0) && d->d_blocked <= 4 ? blockstates[d->d_blocked] : " "); + glist_display_all(ldata); +} - if (w) - { - l = 10 - strlen(w->w_title); - if (l < 0) - l = 0; - sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c", - w->w_number, w->w_title, l, "", - /* w->w_dlist->next */ 0 ? '&' : ' ', - /* - * The rwx triple: - * -,r,R no read, read, read only due to foreign wlock - * -,.,w,W no write, write suppressed by foreign wlock, - * write, own wlock - * -,x no execute, execute - */ -#ifdef MULTIUSER - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : - ((w->w_wlock == WLOCK_OFF || d->d_user == w->w_wlockuser) ? - 'r' : 'R')), - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : - ((w->w_wlock == WLOCK_OFF) ? 'w' : - ((d->d_user == w->w_wlockuser) ? 'W' : 'v'))), - (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : 'x') +static int +gl_Display_input(struct ListData *ldata, char **inp, int *len) +{ + struct display *cd = display; + unsigned char ch = (unsigned char) **inp; + + ++*inp; + --*len; + + switch (ch) + { + case ' ': /* Space to refresh */ + glist_remove_rows(ldata); + gl_Display_rebuild(ldata); + break; + + case '\r': + case '\n': + glist_abort(); + *len = 0; + break; + + case 'd': /* Detach */ + case 'D': /* Power detach */ + display = ldata->selected->data; + if (display == cd) /* We do not allow detaching the current display */ + break; + Detach( +#ifdef POW_DETACH + ch == 'D' ? D_REMOTE_POWER : D_REMOTE #else - 'r', 'w', 'x' + D_REMOTE #endif ); - } - leftline(tbuf, y, d == ddata->selected ? &mchar_so : d == ddata->current ? &m_current : 0); - if (d == ddata->selected) - flayer->l_y = y; - y++; + display = cd; + glist_remove_rows(ldata); + gl_Display_rebuild(ldata); + break; + + break; + + default: + /* We didn't actually process the input. */ + --*inp; + ++*len; + return 0; } - sprintf(tbuf,"[Press Space %s Return to end.]", - 1 ? "to refresh;" : "or"); - centerline(tbuf, flayer->l_height - 2); - LaySetCursor(); + return 1; } -static void -DisplaysRedisplayLine(y, xs, xe, isblank) -int y, xs, xe, isblank; +static int +gl_Display_freerow(struct ListData *ldata, struct ListRow *row) { - ASSERT(flayer); - if (y < 0) + /* There was no allocation when row->data was set. So nothing to do here. */ +} + +static struct GenericList gl_Display = +{ + gl_Display_header, + gl_Display_footer, + gl_Display_row, + gl_Display_input, + gl_Display_freerow +}; + +void +display_displays() +{ + struct display *d; + struct ListRow *row = NULL; + struct ListData *ldata; + if (flayer->l_width < 10 || flayer->l_height < 5) { - displayspage(flayer->l_data); + LMsg(0, "Window size too small for displays page"); return; } - if (y != 0 && y != flayer->l_height - 1) - return; - if (isblank) + + ldata = glist_display(&gl_Display); + if (!ldata) return; - LClearArea(flayer, xs, y, xe, y, 0, 0); - /* To be filled in... */ + + for (d = displays; d; d = d->d_next) + { + row = glist_add_row(ldata, d, row); + if (d == display) + ldata->selected = row; + } + glist_display_all(ldata); } #endif /* MULTI */ diff --git a/src/list_generic.c b/src/list_generic.c new file mode 100644 index 0000000..112b588 --- /dev/null +++ b/src/list_generic.c @@ -0,0 +1,266 @@ +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +#include "config.h" +#include "screen.h" +#include "list_generic.h" +#include "layer.h" + +/* Deals with a generic list display */ + +extern struct layer *flayer; + +static void ListProcess __P((char **, int *)); +static void ListAbort __P((void)); +static void ListRedisplayLine __P((int, int, int, int)); +static void ListClearLine __P((int, int, int, int)); +static int ListRewrite __P((int, int, int, struct mchar *, int)); +static int ListResize __P((int, int)); +static void ListRestore __P((void)); + +static struct LayFuncs ListLf = +{ + ListProcess, + ListAbort, + ListRedisplayLine, + ListClearLine, + ListRewrite, + ListResize, + ListRestore +}; + +/** Returns non-zero on success. */ +struct ListData * +glist_display(struct GenericList *list) +{ + struct ListData *ldata; + + if (InitOverlayPage(sizeof(struct ListData), &ListLf, 0)) + return NULL; + ldata = flayer->l_data; + + ldata->list_fn = list; + + flayer->l_mode = 1; + flayer->l_x = 0; + flayer->l_y = flayer->l_height - 1; + + return ldata; +} + +static void ListProcess(char **ppbuf, int *plen) +{ + struct ListData *ldata = flayer->l_data; + + while (*plen > 0) + { + struct ListRow *old; + unsigned char ch; + + if (ldata->list_fn->gl_pinput && + ldata->list_fn->gl_pinput(ldata, ppbuf, plen)) + continue; + + if (!ldata->selected) + *plen = 0; + + ch = **ppbuf; + ++*ppbuf; + --*plen; + + old = ldata->selected; + switch (ch) + { + case ' ': + break; + + case '\r': + case '\n': + break; + + case 0220: /* up */ + case 16: /* ^P */ + case 'k': + if (!ldata->selected->prev) /* There's no where to go */ + break; + ldata->selected = old->prev; + break; + + case 0216: /* down */ + case 14: /* ^N like emacs */ + case 'j': + if (!ldata->selected->next) /* Nothing to do */ + break; + old = ldata->selected; + ldata->selected = old->next; + break; + + case 007: + ListAbort(); + *plen = 0; + return; + } + + if (old == ldata->selected) /* The selection didn't change */ + continue; + + if (ldata->selected->y == -1) + { + /* We need to list all the rows, since we are scrolling down */ + glist_display_all(ldata); + } + else + { + /* just redisplay the two lines. */ + ldata->list_fn->gl_printrow(ldata, old); + ldata->list_fn->gl_printrow(ldata, ldata->selected); + } + } +} + +static void ListAbort(void) +{ + struct ListData *ldata = flayer->l_data; + glist_remove_rows(ldata); + LAY_CALL_UP(LRefreshAll(flayer, 0)); + ExitOverlayPage(); +} + +static void ListRedisplayLine(int y, int xs, int xe, int isblank) +{ + ASSERT(flayer); + if (y < 0) + { + glist_display_all(flayer->l_data); + return; + } + if (y != 0 && y != flayer->l_height - 1) + return; + + if (isblank) + return; + LClearArea(flayer, xs, y, xe, y, 0, 0); +} + +static void ListClearLine(int y, int xs, int xe, int bce) +{ + DefClearLine(y, xs, xe, bce); +} + +static int ListRewrite(int y, int xs, int xe, struct mchar *rend, int doit) +{ + return EXPENSIVE; +} + +static int ListResize (int wi, int he) +{ + if (wi < 10 || he < 5) + return -1; + + flayer->l_width = wi; + flayer->l_height = he; + flayer->l_y = he - 1; + + return 0; +} + +static void ListRestore (void) +{ + DefRestore(); +} + +struct ListRow * +glist_add_row(struct ListData *ldata, void *data, struct ListRow *after) +{ + struct ListRow *r = calloc(1, sizeof(struct ListRow)); + r->data = data; + + if (after) + { + r->next = after->next; + r->prev = after; + after->next = r; + if (r->next) + r->next->prev = r; + } + else + { + r->next = ldata->root; + if (ldata->root) + ldata->root->prev = r; + ldata->root = r; + } + + return r; +} + +void +glist_remove_rows(struct ListData *ldata) +{ + struct ListRow *row; + for (row = ldata->root; row; row = row->next) + { + ldata->list_fn->gl_freerow(ldata, row); + free(row); + } + ldata->root = ldata->selected = ldata->top = NULL; +} + +void +glist_display_all(struct ListData *list) +{ + int y; + struct ListRow *row; + + LClearAll(flayer, 0); + + y = list->list_fn->gl_printheader(list); + + if (!list->top) + list->top = list->root; + + for (row = list->root; row != list->top; row = row->next) + row->y = -1; + + for (row = list->top; row; row = row->next) + { + row->y = y++; + if (!list->list_fn->gl_printrow(list, row)) + { + row->y = -1; + y--; + } + if (y + 1 == flayer->l_height) + break; + } + for (; row; row = row->next) + row->y = -1; + + list->list_fn->gl_printfooter(list); + LaySetCursor(); +} + +void glist_abort(void) +{ + ListAbort(); +} + diff --git a/src/list_generic.h b/src/list_generic.h new file mode 100644 index 0000000..0c0e5b0 --- /dev/null +++ b/src/list_generic.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +struct ListData; + +struct ListRow +{ + void *data; /* Some data relevant to this row */ + struct ListRow *next, *prev; /* doubly linked list */ + struct ListRow *parent, *child; /* can also be tree */ + int y; /* -1 if not on display */ +}; + +struct GenericList +{ + int (*gl_printheader) __P((struct ListData *)); + int (*gl_printfooter) __P((struct ListData *)); + int (*gl_printrow) __P((struct ListData *, struct ListRow *)); + int (*gl_pinput) __P((struct ListData *, char **inp, int *len)); + int (*gl_freerow) __P((struct ListData *, struct ListRow *)); +}; + +struct ListData +{ + struct ListRow *root; /* The first item in the list */ + struct ListRow *selected; /* The selected row */ + struct ListRow *top; /* The topmost visible row */ + + struct GenericList *list_fn; /* The functions that deal with the list */ +}; + + +struct ListRow * glist_add_row __P((struct ListData *ldata, void *data, struct ListRow *after)); + +void glist_remove_rows __P((struct ListData *ldata)); + +void glist_display_all __P((struct ListData *list)); + +struct ListData * glist_display __P((struct GenericList *list)); + +void glist_abort __P((void)); + +void display_displays __P((void)); + -- cgit v1.2.1 From 04f2e5342014efbbc6ba2d7277d33d3be388b2fd Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 22 Feb 2010 20:50:31 -0500 Subject: Revamp the window list. The window list now uses the list-framework. The basic window list is working. The list for a group, or nested/mru lists still need some work. This is going to be a much simpler code than before. --- src/Makefile.in | 7 +- src/help.c | 17 ++++ src/list_display.c | 27 +++-- src/list_generic.c | 10 +- src/list_generic.h | 15 ++- src/list_window.c | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 343 insertions(+), 21 deletions(-) create mode 100644 src/list_window.c diff --git a/src/Makefile.in b/src/Makefile.in index 0706290..2ae57d0 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -62,12 +62,12 @@ CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \ termcap.c input.c attacher.c pty.c process.c display.c comm.c \ kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \ sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c \ - list_display.c list_generic.c + list_display.c list_generic.c list_window.c OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ termcap.o input.o attacher.o pty.o process.o display.o comm.o \ kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \ - list_generic.o list_display.o \ + list_generic.o list_display.o list_window.o \ sched.o teln.o nethack.o encoding.o canvas.o layout.o viewport.o all: screen @@ -304,7 +304,7 @@ loadav.o: layout.h viewport.h canvas.h loadav.c config.h screen.h os.h osdef.h a comm.h layer.h term.h image.h display.h window.h extern.h putenv.o: layout.h viewport.h canvas.h putenv.c config.h help.o: layout.h viewport.h canvas.h help.c config.h screen.h os.h osdef.h ansi.h acls.h \ - comm.h layer.h term.h image.h display.h window.h extern.h list_display.c list_generic.h + comm.h layer.h term.h image.h display.h window.h extern.h list_generic.h termcap.o: layout.h viewport.h canvas.h termcap.c config.h screen.h os.h osdef.h ansi.h acls.h \ comm.h layer.h term.h image.h display.h window.h extern.h input.o: layout.h viewport.h canvas.h input.c config.h screen.h os.h osdef.h ansi.h acls.h \ @@ -349,4 +349,5 @@ viewport.o: layout.h viewport.h canvas.h viewport.c config.h screen.h os.h osdef braille.h list_generic.o: list_generic.h list_generic.c layer.h list_display.o: list_generic.h list_display.c layer.h +list_window.o: list_generic.h list_window.c window.h layer.h diff --git a/src/help.c b/src/help.c index 1e37354..ebcf1d5 100644 --- a/src/help.c +++ b/src/help.c @@ -717,6 +717,7 @@ struct wlistdata { int *list; }; +#if 0 static struct LayFuncs WListLf = { WListProcess, @@ -727,9 +728,11 @@ static struct LayFuncs WListLf = WListResize, DefRestore }; +#endif #define WTAB_GROUP_MATCHES(i) (group == wtab[i]->w_group) +#if 0 static int WListResize(wi, he) int wi, he; @@ -1155,6 +1158,7 @@ struct win *group; return ind; return WListOrder(wlistdata, ind, start, group); } +#endif void display_wlist(onblank, order, group) @@ -1162,9 +1166,13 @@ int onblank; int order; struct win *group; { + display_windows(onblank, order, group); + return; +#if 0 struct win *p; struct wlistdata *wlistdata; + if (flayer->l_width < 10 || flayer->l_height < 6) { LMsg(0, "Window size too small for window list page"); @@ -1214,8 +1222,10 @@ struct win *group; wlistdata->numwin = flayer->l_height - (group ? 4 : 3); wlistdata->nested = (order & WLIST_NESTED); wlistpage(); +#endif } +#if 0 static void wlistpage() { @@ -1299,20 +1309,25 @@ struct win *p; WListLine(y, i, wlistdata->pos, 0); LaySetCursor(); } +#endif void WListUpdatecv(cv, p) struct canvas *cv; struct win *p; { +#if 0 if (cv->c_layer->l_layfn != &WListLf) return; CV_CALL(cv, WListUpdate(p)); +#endif +#warning Fixme } void WListLinkChanged() { +#if 0 struct display *olddisplay = display; struct canvas *cv; struct wlistdata *wlistdata; @@ -1328,6 +1343,8 @@ WListLinkChanged() CV_CALL(cv, WListUpdate(0)); } display = olddisplay; +#endif +#warning Fix me too! } diff --git a/src/list_display.c b/src/list_display.c index 28ec7bb..9223fd8 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -145,8 +145,12 @@ static int gl_Display_input(struct ListData *ldata, char **inp, int *len) { struct display *cd = display; - unsigned char ch = (unsigned char) **inp; + unsigned char ch; + if (!ldata->selected) + return 0; + + ch = (unsigned char) **inp; ++*inp; --*len; @@ -195,6 +199,14 @@ static int gl_Display_freerow(struct ListData *ldata, struct ListRow *row) { /* There was no allocation when row->data was set. So nothing to do here. */ + return 0; +} + +static int +gl_Display_free(struct ListData *ldata) +{ + /* There was no allocation in ldata->data. So nothing to do here. */ + return 0; } static struct GenericList gl_Display = @@ -203,14 +215,13 @@ static struct GenericList gl_Display = gl_Display_footer, gl_Display_row, gl_Display_input, - gl_Display_freerow + gl_Display_freerow, + gl_Display_free }; void display_displays() { - struct display *d; - struct ListRow *row = NULL; struct ListData *ldata; if (flayer->l_width < 10 || flayer->l_height < 5) { @@ -222,13 +233,7 @@ display_displays() if (!ldata) return; - for (d = displays; d; d = d->d_next) - { - row = glist_add_row(ldata, d, row); - if (d == display) - ldata->selected = row; - } - glist_display_all(ldata); + gl_Display_rebuild(ldata); } #endif /* MULTI */ diff --git a/src/list_generic.c b/src/list_generic.c index 112b588..3d93438 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -81,7 +81,10 @@ static void ListProcess(char **ppbuf, int *plen) continue; if (!ldata->selected) - *plen = 0; + { + *plen = 0; + break; + } ch = **ppbuf; ++*ppbuf; @@ -114,7 +117,8 @@ static void ListProcess(char **ppbuf, int *plen) ldata->selected = old->next; break; - case 007: + case 033: /* escape */ + case 007: /* ^G */ ListAbort(); *plen = 0; return; @@ -141,6 +145,8 @@ static void ListAbort(void) { struct ListData *ldata = flayer->l_data; glist_remove_rows(ldata); + if (ldata->list_fn->gl_free) + ldata->list_fn->gl_free(ldata); LAY_CALL_UP(LRefreshAll(flayer, 0)); ExitOverlayPage(); } diff --git a/src/list_generic.h b/src/list_generic.h index 0c0e5b0..c9631ed 100644 --- a/src/list_generic.h +++ b/src/list_generic.h @@ -32,11 +32,12 @@ struct ListRow struct GenericList { - int (*gl_printheader) __P((struct ListData *)); - int (*gl_printfooter) __P((struct ListData *)); - int (*gl_printrow) __P((struct ListData *, struct ListRow *)); - int (*gl_pinput) __P((struct ListData *, char **inp, int *len)); - int (*gl_freerow) __P((struct ListData *, struct ListRow *)); + int (*gl_printheader) __P((struct ListData *)); /* Print the header */ + int (*gl_printfooter) __P((struct ListData *)); /* Print the footer */ + int (*gl_printrow) __P((struct ListData *, struct ListRow *)); /* Print one row */ + int (*gl_pinput) __P((struct ListData *, char **inp, int *len)); /* Process input */ + int (*gl_freerow) __P((struct ListData *, struct ListRow *)); /* Free data for a row */ + int (*gl_free) __P((struct ListData *)); /* Free data for the list */ }; struct ListData @@ -46,6 +47,8 @@ struct ListData struct ListRow *top; /* The topmost visible row */ struct GenericList *list_fn; /* The functions that deal with the list */ + + void *data; /* List specific data */ }; @@ -61,3 +64,5 @@ void glist_abort __P((void)); void display_displays __P((void)); +void display_windows __P((int onblank, int order, struct win *group)); + diff --git a/src/list_window.c b/src/list_window.c new file mode 100644 index 0000000..873e894 --- /dev/null +++ b/src/list_window.c @@ -0,0 +1,288 @@ +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, see + * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + * + **************************************************************** + */ + +/* Deals with the list of windows */ + +#include "config.h" +#include "screen.h" +#include "layer.h" +#include "extern.h" +#include "list_generic.h" + +extern struct layer *flayer; +extern struct display *display; + +extern char *wlisttit; +extern char *wliststr; + +extern struct mchar mchar_blank, mchar_so; +extern int renditions[]; + +extern struct win **wtab, *windows; +extern int maxwin; + +struct gl_Window_Data +{ + struct win *group; /* Currently displaying this group */ + int order; /* MRU? NESTED? etc. */ + int onblank; + struct win *fore; /* The foreground window we had. */ +}; + +static void +gl_Window_rebuild(struct ListData *ldata) +{ + struct ListRow *row = NULL; + struct gl_Window_Data *wdata = ldata->data; + + if (wdata->order == WLIST_MRU) + { + struct win *w; + for (w = windows; w; w = w->w_next) + { + if (w->w_group == wdata->group) + { + row = glist_add_row(ldata, w, row); + if (w == wdata->fore) + ldata->selected = row; + } + } + } + else + { + struct win **w; + struct win *wlist; + for (w = wtab, wlist = windows; wlist && w - wtab < maxwin; w++) + { + if (*w && (*w)->w_group == wdata->group) + { + row = glist_add_row(ldata, *w, row); + if (*w == wdata->fore) + ldata->selected = row; + wlist = wlist->w_next; + } + } + } + glist_display_all(ldata); +} + +static int +gl_Window_header(struct ListData *ldata) +{ + char *str; + + display = 0; + str = MakeWinMsgEv(wlisttit, (struct win *)0, '%', flayer->l_width, (struct event *)0, 0); + + LPutWinMsg(flayer, str, strlen(str), &mchar_blank, 0, 0); + return 2; +} + +static int +gl_Window_footer(struct ListData *ldata) +{ + return 0; +} + +static int +gl_Window_row(struct ListData *ldata, struct ListRow *lrow) +{ + char *str; + struct win *w; + int xoff; + struct mchar *mchar; + struct mchar mchar_rend = mchar_blank; + struct ListRow *par = lrow; + + w = lrow->data; + + /* XXX: First, make sure we want to display this window in the list. + * If we are showing a list for a group, and not on blank, then we must + * only show the windows directly belonging to that group. + * Otherwise, do some more checks. */ + + for (xoff = 0, par = lrow->parent; par; par = par->parent) + { + if (par->y == -1) + break; + xoff += 2; + } + display = Layer2Window(flayer) ? 0 : flayer->l_cvlist ? flayer->l_cvlist->c_display : 0; + str = MakeWinMsgEv(wliststr, w, '%', flayer->l_width - xoff, NULL, 0); + if (ldata->selected == lrow) + mchar = &mchar_so; + else if (w->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1) + { + mchar = &mchar_rend; + ApplyAttrColor(renditions[REND_MONITOR], mchar); + } + else if ((w->w_bell == BELL_DONE || w->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1) + { + mchar = &mchar_rend; + ApplyAttrColor(renditions[REND_BELL], mchar); + } + else + mchar = &mchar_blank; + + LPutWinMsg(flayer, str, flayer->l_width, mchar, xoff, lrow->y); + return 1; +} + +static int +gl_Window_input(struct ListData *ldata, char **inp, int *len) +{ + struct win *win; + unsigned char ch; + struct display *cd = display; + struct gl_Window_Data *wdata = ldata->data; + + if (!ldata->selected) + return 0; + + ch = (unsigned char) **inp; + ++*inp; + --*len; + + switch (ch) + { + case ' ': + case '\n': + case '\r': + win = ldata->selected->data; + if (!win) + break; +#ifdef MULTIUSER + if (display && AclCheckPermWin(D_user, ACL_READ, win)) + return; /* Not allowed to switch to this window. */ +#endif + glist_abort(); + display = cd; + SwitchWindow(win->w_number); + break; + + case 033: /* escape */ + case 007: /* ^G */ + if (wdata->onblank) + { + glist_abort(); + display = cd; + SwitchWindow(wdata->fore->w_number); + *len = 0; + break; + } + /* else FALLTHROUGH */ + default: + --*inp; + ++*len; + return 0; + } + return 1; +} + +static int +gl_Window_freerow(struct ListData *ldata, struct ListRow *row) +{ + return 0; +} + +static int +gl_Window_free(struct ListData *ldata) +{ + Free(ldata->data); + return 0; +} + +static struct GenericList gl_Window = +{ + gl_Window_header, + gl_Window_footer, + gl_Window_row, + gl_Window_input, + gl_Window_freerow, + gl_Window_free +}; + +void +display_windows(int onblank, int order, struct win *group) +{ + struct win *p; + struct wlistdata *wlistdata; + + if (flayer->l_width < 10 || flayer->l_height < 6) + { + LMsg(0, "Window size too small for window list page"); + return; + } + if (onblank) + { + debug3("flayer %x %d %x\n", flayer, flayer->l_width, flayer->l_height); + if (!display) + { + LMsg(0, "windowlist -b: display required"); + return; + } + p = D_fore; + if (p) + { + SetForeWindow((struct win *)0); + if (p->w_group) + { + D_fore = p->w_group; + flayer->l_data = (char *)p->w_group; + } + Activate(0); + } + if (flayer->l_width < 10 || flayer->l_height < 6) + { + LMsg(0, "Window size too small for window list page"); + return; + } + } + else + p = Layer2Window(flayer); + if (!group && p) + group = p->w_group; + + struct ListData *ldata; + struct gl_Window_Data *wdata; + ldata = glist_display(&gl_Window); + if (!ldata) + { + if (onblank && p) + { + /* Could not display the list. So restore the window. */ + SetForeWindow(p); + Activate(1); + } + return; + } + + wdata = calloc(1, sizeof(struct gl_Window_Data)); + wdata->group = group; + wdata->order = order; + wdata->onblank = onblank; + wdata->fore = p; + ldata->data = wdata; + + gl_Window_rebuild(ldata); +} + -- cgit v1.2.1 From c649e67105da3feb4d6d2d48a3d4ec72e484daf4 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 22 Feb 2010 23:36:30 -0500 Subject: It makes no sense to allow a group into itself. --- src/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/process.c b/src/process.c index e131384..b12eafb 100644 --- a/src/process.c +++ b/src/process.c @@ -4236,7 +4236,7 @@ int key; if (args[0][0]) { fore->w_group = WindowByName(*args); - if (fore->w_group && fore->w_group->w_type != W_TYPE_GROUP) + if (fore->w_group == fore || (fore->w_group && fore->w_group->w_type != W_TYPE_GROUP)) fore->w_group = 0; } WindowChanged((struct win *)0, 'w'); -- cgit v1.2.1 From d9262fc5897e54f1b1fc1874acf101811bbb5935 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 23 Feb 2010 12:43:26 -0500 Subject: Update the window-list when necessary. Update the window-list whenever window ordering/etc. changes. There is an unusual bug where the selection in a list changes automatically when switching windows in another display. Need to investigate this issue. Also, left to do: support nested list, and advanced navigations introduced (e.g. toggle MRU, nestedness etc.) --- src/help.c | 39 +--------- src/list_display.c | 4 +- src/list_generic.c | 7 +- src/list_generic.h | 5 +- src/list_window.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 217 insertions(+), 49 deletions(-) diff --git a/src/help.c b/src/help.c index ebcf1d5..be344b7 100644 --- a/src/help.c +++ b/src/help.c @@ -50,6 +50,8 @@ extern struct win **wtab; extern struct term term[]; #endif +extern struct LayFuncs ListLf; + static void PadStr __P((char *, int, int, int)); extern char *wliststr; @@ -1311,43 +1313,6 @@ struct win *p; } #endif -void -WListUpdatecv(cv, p) -struct canvas *cv; -struct win *p; -{ -#if 0 - if (cv->c_layer->l_layfn != &WListLf) - return; - CV_CALL(cv, WListUpdate(p)); -#endif -#warning Fixme -} - -void -WListLinkChanged() -{ -#if 0 - struct display *olddisplay = display; - struct canvas *cv; - struct wlistdata *wlistdata; - - for (display = displays; display; display = display->d_next) - for (cv = D_cvlist; cv; cv = cv->c_next) - { - if (!cv->c_layer || cv->c_layer->l_layfn != &WListLf) - continue; - wlistdata = (struct wlistdata *)cv->c_layer->l_data; - if (wlistdata->order != WLIST_MRU) - continue; - CV_CALL(cv, WListUpdate(0)); - } - display = olddisplay; -#endif -#warning Fix me too! -} - - /* ** ** The bindkey help page diff --git a/src/list_display.c b/src/list_display.c index 9223fd8..56e7f08 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -42,6 +42,8 @@ extern struct layer *flayer; extern struct display *display, *displays; extern struct mchar mchar_blank, mchar_so; +static char ListID[] = "display"; + /* * layout of the displays page is as follows: @@ -229,7 +231,7 @@ display_displays() return; } - ldata = glist_display(&gl_Display); + ldata = glist_display(&gl_Display, ListID); if (!ldata) return; diff --git a/src/list_generic.c b/src/list_generic.c index 3d93438..61122a5 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -37,7 +37,7 @@ static int ListRewrite __P((int, int, int, struct mchar *, int)); static int ListResize __P((int, int)); static void ListRestore __P((void)); -static struct LayFuncs ListLf = +struct LayFuncs ListLf = { ListProcess, ListAbort, @@ -50,7 +50,7 @@ static struct LayFuncs ListLf = /** Returns non-zero on success. */ struct ListData * -glist_display(struct GenericList *list) +glist_display(struct GenericList *list, const char *name) { struct ListData *ldata; @@ -58,6 +58,7 @@ glist_display(struct GenericList *list) return NULL; ldata = flayer->l_data; + ldata->name = name; /* We do not SaveStr, since the strings should be all static literals */ ldata->list_fn = list; flayer->l_mode = 1; @@ -243,6 +244,8 @@ glist_display_all(struct ListData *list) if (!list->top) list->top = list->root; + if (!list->selected) + list->selected = list->root; for (row = list->root; row != list->top; row = row->next) row->y = -1; diff --git a/src/list_generic.h b/src/list_generic.h index c9631ed..3e07c4c 100644 --- a/src/list_generic.h +++ b/src/list_generic.h @@ -42,6 +42,7 @@ struct GenericList struct ListData { + const char *name; /* An identifier for the list */ struct ListRow *root; /* The first item in the list */ struct ListRow *selected; /* The selected row */ struct ListRow *top; /* The topmost visible row */ @@ -51,6 +52,8 @@ struct ListData void *data; /* List specific data */ }; +extern struct LayFuncs ListLf; + struct ListRow * glist_add_row __P((struct ListData *ldata, void *data, struct ListRow *after)); @@ -58,7 +61,7 @@ void glist_remove_rows __P((struct ListData *ldata)); void glist_display_all __P((struct ListData *list)); -struct ListData * glist_display __P((struct GenericList *list)); +struct ListData * glist_display __P((struct GenericList *list, const char *name)); void glist_abort __P((void)); diff --git a/src/list_window.c b/src/list_window.c index 873e894..05a42b7 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -29,7 +29,7 @@ #include "list_generic.h" extern struct layer *flayer; -extern struct display *display; +extern struct display *display, *displays; extern char *wlisttit; extern char *wliststr; @@ -40,11 +40,14 @@ extern int renditions[]; extern struct win **wtab, *windows; extern int maxwin; +static char ListID[] = "window"; + struct gl_Window_Data { - struct win *group; /* Currently displaying this group */ - int order; /* MRU? NESTED? etc. */ + struct win *group; /* Set only for a W_TYPE_GROUP window */ + int order; /* MRU? NUM? */ int onblank; + int nested; struct win *fore; /* The foreground window we had. */ }; @@ -85,6 +88,50 @@ gl_Window_rebuild(struct ListData *ldata) glist_display_all(ldata); } +static struct ListRow * +gl_Window_findrow(struct ListData *ldata, struct win *p) +{ + struct ListRow *row = ldata->root; + for (; row; row = row->next) + { + if (row->data == p) + break; + } + return row; +} + +static int +gl_Window_remove(struct ListData *ldata, struct win *p) +{ + struct ListRow *row = gl_Window_findrow(ldata, p); + if (!row) + return 0; + + /* Remove 'row'. Update 'selected', 'top', 'root' if necessary. */ + if (row->next) + row->next->prev = row->prev; + if (row->prev) + row->prev->next = row->next; + if (row->child) + { + /* Move the children to row->parent. Make sure the ordering is right. */ + } + if (row->parent && row->parent->child == row) + row->parent->child = row->next; + + if (ldata->selected == row) + ldata->selected = row->prev ? row->prev : row->next; + if (ldata->top == row) + ldata->selected = row->prev ? row->prev : row->next; + if (ldata->root == row) + ldata->root = row->next; + + ldata->list_fn->gl_freerow(ldata, row); + free(row); + + return 1; +} + static int gl_Window_header(struct ListData *ldata) { @@ -174,13 +221,20 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) if (display && AclCheckPermWin(D_user, ACL_READ, win)) return; /* Not allowed to switch to this window. */ #endif - glist_abort(); - display = cd; + if (!wdata->group) + { + /* Do not abort the group window. */ + glist_abort(); + display = cd; + } SwitchWindow(win->w_number); + *len = 0; break; case 033: /* escape */ case 007: /* ^G */ + if (wdata->group) + break; /* Do nothing if it's a group window */ if (wdata->onblank) { glist_abort(); @@ -232,6 +286,10 @@ display_windows(int onblank, int order, struct win *group) LMsg(0, "Window size too small for window list page"); return; } + + if (group) + onblank = 0; /* When drawing a group window, ignore 'onblank' */ + if (onblank) { debug3("flayer %x %d %x\n", flayer, flayer->l_width, flayer->l_height); @@ -264,7 +322,7 @@ display_windows(int onblank, int order, struct win *group) struct ListData *ldata; struct gl_Window_Data *wdata; - ldata = glist_display(&gl_Window); + ldata = glist_display(&gl_Window, ListID); if (!ldata) { if (onblank && p) @@ -278,11 +336,148 @@ display_windows(int onblank, int order, struct win *group) wdata = calloc(1, sizeof(struct gl_Window_Data)); wdata->group = group; - wdata->order = order; + wdata->order = (order & ~WLIST_NESTED); + wdata->nested = !!(order & WLIST_NESTED); wdata->onblank = onblank; - wdata->fore = p; + + /* Set the most recent window as selected. */ + wdata->fore = windows; + while (wdata->fore && wdata->fore->w_group != group) + wdata->fore = wdata->fore->w_next; + ldata->data = wdata; gl_Window_rebuild(ldata); } +static void +WListUpdate(struct win *p, struct ListData *ldata) +{ + struct gl_Window_Data *wdata = ldata->data; + struct ListRow *row, *rbefore; + struct win *before; + int d = 0; + + if (!p) + { + if (ldata->selected) + wdata->fore = ldata->selected->data; /* Try to retain the current selection */ + glist_remove_rows(ldata); + gl_Window_rebuild(ldata); + return; + } + + /* First decide if this window should be displayed at all. */ + d = 1; + if (wdata->order == WLIST_NUM || wdata->order == WLIST_MRU) + { + if (p->w_group != wdata->group) + { + if (!wdata->nested) + d = 0; + else + { + struct win *g = p->w_group; + for (; g; g = g->w_group) + if (g->w_group == wdata->group) + break; + if (!g) + d = 0; + } + } + } + + if (!d) + { + if (gl_Window_remove(ldata, p)) + glist_display_all(ldata); + return; + } + + /* OK, so we keep the window in the list. Update the ordering. + * First, find the row where this window should go to. Then, either create + * a new row for that window, or move the exising row for the window to the + * correct place. */ + before = NULL; + if (wdata->order == WLIST_MRU) + { + if (windows != p) + for (before = windows; before; before = before->w_next) + if (before->w_next == p) + break; + } + else if (wdata->order == WLIST_NUM) + { + if (p->w_number != 0) + { + struct win **w = wtab + p->w_number - 1; + for (; w >= wtab; w--) + { + if (*w && (*w)->w_group == wdata->group) + { + before = *w; + break; + } + } + } + } + + if (wdata->nested && before == NULL) + { + /* TODO: insert after the parent */ +#warning Fix me + } + + /* Now, find the row belonging to 'before' */ + if (before) + rbefore = gl_Window_findrow(ldata, before); + else + rbefore = NULL; + + /* For now, just remove the row containing 'p'. */ + gl_Window_remove(ldata, p); + glist_add_row(ldata, p, rbefore); + glist_display_all(ldata); +} + +void +WListUpdatecv(cv, p) +struct canvas *cv; +struct win *p; +{ + struct ListData *ldata; + struct gl_Window_Data *wdata; + + if (cv->c_layer->l_layfn != &ListLf) + return; + ldata = cv->c_layer->l_data; + if (ldata->name != ListID) + return; + wdata = ldata->data; + CV_CALL(cv, WListUpdate(p, ldata)); +} + +void +WListLinkChanged() +{ + struct display *olddisplay = display; + struct canvas *cv; + struct ListData *ldata; + struct gl_Window_Data *wdata; + + for (display = displays; display; display = display->d_next) + for (cv = D_cvlist; cv; cv = cv->c_next) + { + if (!cv->c_layer || cv->c_layer->l_layfn != &ListLf) + continue; + ldata = cv->c_layer->l_data; + if (ldata->name != ListID) + continue; + wdata = ldata->data; + if (!(wdata->order & WLIST_MRU)) + continue; + CV_CALL(cv, WListUpdate(0, ldata)); + } + display = olddisplay; +} + -- cgit v1.2.1 From bafc958a9210a15ff5d206491f9fd634201ce7b8 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 23 Feb 2010 14:43:04 -0500 Subject: Fix the unexpected selection-change bug. Do not remove a row from the list if it is already in the correct position. --- src/list_window.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/list_window.c b/src/list_window.c index 05a42b7..2313cbf 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -434,9 +434,17 @@ WListUpdate(struct win *p, struct ListData *ldata) else rbefore = NULL; - /* For now, just remove the row containing 'p'. */ - gl_Window_remove(ldata, p); - glist_add_row(ldata, p, rbefore); + /* For now, just remove the row containing 'p' if it is not already in the right place . */ + row = gl_Window_findrow(ldata, p); + if (row) + { + if (row->prev != rbefore) + gl_Window_remove(ldata, p); + else + p = NULL; /* the window is in the correct place */ + } + if (p) + glist_add_row(ldata, p, rbefore); glist_display_all(ldata); } -- cgit v1.2.1 From 68af85deb132f9b32685843cf8968c77a7a3d5a8 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 23 Feb 2010 15:10:21 -0500 Subject: Add the navigation support back in the window list. Pressing 'm' toggles the MRU-ness, pressing 'a' shows the list of all windows. Still left to do: deal with nested view. --- src/list_window.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/list_window.c b/src/list_window.c index 2313cbf..d946fe1 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -227,10 +227,61 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) glist_abort(); display = cd; } - SwitchWindow(win->w_number); + if (D_fore != win) + SwitchWindow(win->w_number); *len = 0; break; + case 'm': + /* Toggle MRU-ness */ + wdata->order = wdata->order == WLIST_MRU ? WLIST_NUM : WLIST_MRU; + glist_remove_rows(ldata); + gl_Window_rebuild(ldata); + break; + + case 'a': + /* All-window view */ + if (wdata->group) + { + int order = wdata->order | (wdata->nested ? WLIST_NESTED : 0); + glist_abort(); + display = cd; + display_windows(1, order, NULL); + *len = 0; + } + else if (!wdata->nested) + { + wdata->nested = 1; + glist_remove_rows(ldata); + gl_Window_rebuild(ldata); + } + break; + + case 010: /* ^H */ + case 0177: /* Backspace */ + if (!wdata->group) + break; + if (wdata->group->w_group) + { + /* The parent is another group window. So switch to that window. */ + struct win *g = wdata->group->w_group; + glist_abort(); + display = cd; + SetForeWindow(g); + *len = 0; + } + else + { + /* We were in a group view. Now we are moving to an all-window view. + * So treat it as 'windowlist on blank'. */ + int order = wdata->order | (wdata->nested ? WLIST_NESTED : 0); + glist_abort(); + display = cd; + display_windows(1, order, NULL); + *len = 0; + } + break; + case 033: /* escape */ case 007: /* ^G */ if (wdata->group) -- cgit v1.2.1 From 94d954b97565a4b2625ca04152fca4e87cf9d730 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 23 Feb 2010 20:30:53 -0500 Subject: Final touches to the revamped window list. This window list should be better than the old one, mostly code-wise, as there's yet no new functionality. However, it should be much simpler to add typeahead search and other nifty things now than before. --- src/help.c | 4 +-- src/list_generic.c | 6 ++++ src/list_generic.h | 1 - src/list_window.c | 104 ++++++++++++++++++++++++++++++++++++++--------------- 4 files changed, 82 insertions(+), 33 deletions(-) diff --git a/src/help.c b/src/help.c index be344b7..7b3e3b5 100644 --- a/src/help.c +++ b/src/help.c @@ -691,6 +691,7 @@ int y, xs, xe, isblank; ** */ +#if 0 struct wlistdata; static void WListProcess __P((char **, int *)); @@ -719,7 +720,6 @@ struct wlistdata { int *list; }; -#if 0 static struct LayFuncs WListLf = { WListProcess, @@ -730,11 +730,9 @@ static struct LayFuncs WListLf = WListResize, DefRestore }; -#endif #define WTAB_GROUP_MATCHES(i) (group == wtab[i]->w_group) -#if 0 static int WListResize(wi, he) int wi, he; diff --git a/src/list_generic.c b/src/list_generic.c index 61122a5..9f7d628 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -138,6 +138,8 @@ static void ListProcess(char **ppbuf, int *plen) /* just redisplay the two lines. */ ldata->list_fn->gl_printrow(ldata, old); ldata->list_fn->gl_printrow(ldata, ldata->selected); + flayer->l_y = ldata->selected->y; + LaySetCursor(); } } } @@ -265,6 +267,10 @@ glist_display_all(struct ListData *list) row->y = -1; list->list_fn->gl_printfooter(list); + if (list->selected && list->selected->y != -1) + flayer->l_y = list->selected->y; + else + flayer->l_y = flayer->l_height - 1; LaySetCursor(); } diff --git a/src/list_generic.h b/src/list_generic.h index 3e07c4c..489694c 100644 --- a/src/list_generic.h +++ b/src/list_generic.h @@ -26,7 +26,6 @@ struct ListRow { void *data; /* Some data relevant to this row */ struct ListRow *next, *prev; /* doubly linked list */ - struct ListRow *parent, *child; /* can also be tree */ int y; /* -1 if not on display */ }; diff --git a/src/list_window.c b/src/list_window.c index d946fe1..f21b4f6 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -51,6 +51,59 @@ struct gl_Window_Data struct win *fore; /* The foreground window we had. */ }; +/* Is 'a' an ancestor of 'd'? */ +static int +window_ancestor(struct win *a, struct win *d) +{ + if (!a) + return 1; /* Every window is a descendant of the 'null' group */ + for (; d; d = d->w_group) + if (d->w_group == a) + return 1; + return 0; +} + +static struct ListRow * +gl_Window_add_group(struct ListData *ldata, struct ListRow *row) +{ + /* Right now, 'row' doesn't have any child. */ + struct gl_Window_Data *wdata = ldata->data; + struct win *group = row->data; + struct ListRow *cur = row; + + ASSERT(wdata->nested); + + if (wdata->order == WLIST_MRU) + { + struct win *w; + for (w = windows; w; w = w->w_next) + { + if (w->w_group != group) + continue; + + cur = glist_add_row(ldata, w, cur); + + if (w->w_type == W_TYPE_GROUP) + cur = gl_Window_add_group(ldata, cur); + } + } + else if (wdata->order == WLIST_NUM) + { + struct win **w; + for (w = wtab; w - wtab < maxwin; w++) + { + if (!*w || (*w)->w_group != group) + continue; + + cur = glist_add_row(ldata, *w, cur); + + if ((*w)->w_type == W_TYPE_GROUP) + cur = gl_Window_add_group(ldata, cur); + } + } + return cur; +} + static void gl_Window_rebuild(struct ListData *ldata) { @@ -67,6 +120,8 @@ gl_Window_rebuild(struct ListData *ldata) row = glist_add_row(ldata, w, row); if (w == wdata->fore) ldata->selected = row; + if (w->w_type == W_TYPE_GROUP && wdata->nested) + row = gl_Window_add_group(ldata, row); } } } @@ -82,6 +137,8 @@ gl_Window_rebuild(struct ListData *ldata) if (*w == wdata->fore) ldata->selected = row; wlist = wlist->w_next; + if ((*w)->w_type == W_TYPE_GROUP && wdata->nested) + row = gl_Window_add_group(ldata, row); } } } @@ -112,12 +169,6 @@ gl_Window_remove(struct ListData *ldata, struct win *p) row->next->prev = row->prev; if (row->prev) row->prev->next = row->next; - if (row->child) - { - /* Move the children to row->parent. Make sure the ordering is right. */ - } - if (row->parent && row->parent->child == row) - row->parent->child = row->next; if (ldata->selected == row) ldata->selected = row->prev ? row->prev : row->next; @@ -154,25 +205,21 @@ static int gl_Window_row(struct ListData *ldata, struct ListRow *lrow) { char *str; - struct win *w; + struct win *w, *g; int xoff; struct mchar *mchar; struct mchar mchar_rend = mchar_blank; - struct ListRow *par = lrow; + struct gl_Window_Data *wdata = ldata->data; w = lrow->data; - /* XXX: First, make sure we want to display this window in the list. + /* First, make sure we want to display this window in the list. * If we are showing a list for a group, and not on blank, then we must * only show the windows directly belonging to that group. * Otherwise, do some more checks. */ - for (xoff = 0, par = lrow->parent; par; par = par->parent) - { - if (par->y == -1) - break; - xoff += 2; - } + for (xoff = 0, g = w->w_group; g != wdata->group; g = g->w_group) + xoff += 2; display = Layer2Window(flayer) ? 0 : flayer->l_cvlist ? flayer->l_cvlist->c_display : 0; str = MakeWinMsgEv(wliststr, w, '%', flayer->l_width - xoff, NULL, 0); if (ldata->selected == lrow) @@ -191,6 +238,9 @@ gl_Window_row(struct ListData *ldata, struct ListRow *lrow) mchar = &mchar_blank; LPutWinMsg(flayer, str, flayer->l_width, mchar, xoff, lrow->y); + if (xoff) + LPutWinMsg(flayer, "", xoff, mchar, 0, lrow->y); + return 1; } @@ -239,6 +289,13 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) gl_Window_rebuild(ldata); break; + case 'g': + /* Toggle nestedness */ + wdata->nested = !wdata->nested; + glist_remove_rows(ldata); + gl_Window_rebuild(ldata); + break; + case 'a': /* All-window view */ if (wdata->group) @@ -427,14 +484,7 @@ WListUpdate(struct win *p, struct ListData *ldata) if (!wdata->nested) d = 0; else - { - struct win *g = p->w_group; - for (; g; g = g->w_group) - if (g->w_group == wdata->group) - break; - if (!g) - d = 0; - } + d = window_ancestor(wdata->group, p); } } @@ -473,15 +523,11 @@ WListUpdate(struct win *p, struct ListData *ldata) } } - if (wdata->nested && before == NULL) - { - /* TODO: insert after the parent */ -#warning Fix me - } - /* Now, find the row belonging to 'before' */ if (before) rbefore = gl_Window_findrow(ldata, before); + else if (wdata->nested && p->w_group) /* There's no 'before'. So find the group window */ + rbefore = gl_Window_findrow(ldata, p->w_group); else rbefore = NULL; -- cgit v1.2.1 From 1df022599350ae3882843b772b2bc0869348b894 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 23 Feb 2010 20:35:03 -0500 Subject: Remove old code. --- src/canvas.c | 3 +- src/extern.h | 1 - src/help.c | 626 ---------------------------------------------------------- src/process.c | 5 +- src/socket.c | 5 +- 5 files changed, 8 insertions(+), 632 deletions(-) diff --git a/src/canvas.c b/src/canvas.c index 4cc4fe2..0121892 100644 --- a/src/canvas.c +++ b/src/canvas.c @@ -30,6 +30,7 @@ #include "screen.h" #include "extern.h" #include "canvas.h" +#include "list_generic.h" extern struct display *display; extern struct win *fore, *windows; @@ -307,7 +308,7 @@ struct win *wi; struct display *d = display; struct layer *oldflayer = flayer; flayer = l; - display_wlist(0, 0, wi); + display_windows(0, 0, wi); flayer = oldflayer; display = d; } diff --git a/src/extern.h b/src/extern.h index dc5857e..ee655f5 100644 --- a/src/extern.h +++ b/src/extern.h @@ -132,7 +132,6 @@ extern void display_help __P((char *, struct action *)); extern void display_copyright __P((void)); extern void display_displays __P((void)); extern void display_bindkey __P((char *, struct action *)); -extern void display_wlist __P((int, int, struct win *)); extern int InWList __P((void)); extern void WListUpdatecv __P((struct canvas *, struct win *)); extern void WListLinkChanged __P((void)); diff --git a/src/help.c b/src/help.c index 7b3e3b5..f8ae2fc 100644 --- a/src/help.c +++ b/src/help.c @@ -685,632 +685,6 @@ int y, xs, xe, isblank; } -/* -** -** here is the windowlist -** -*/ - -#if 0 -struct wlistdata; - -static void WListProcess __P((char **, int *)); -static void WListAbort __P((void)); -static void WListRedisplayLine __P((int, int, int, int)); -static void wlistpage __P((void)); -static void WListLine __P((int, int, int, int)); -static void WListLines __P((int, int)); -static void WListMove __P((int, int)); -static void WListUpdate __P((struct win *)); -static int WListNormalize __P((void)); -static int WListResize __P((int, int)); -static int WListNext __P((struct wlistdata *, int, int)); - -struct wlistdata { - int pos; - int ypos; - int npos; - int numwin; - int first; - int last; - int start; - int order; - struct win *group; - int nested; - int *list; -}; - -static struct LayFuncs WListLf = -{ - WListProcess, - WListAbort, - WListRedisplayLine, - DefClearLine, - DefRewrite, - WListResize, - DefRestore -}; - -#define WTAB_GROUP_MATCHES(i) (group == wtab[i]->w_group) - -static int -WListResize(wi, he) -int wi, he; -{ - struct wlistdata *wlistdata; - if (wi < 10 || he < 5) - return -1; - wlistdata = (struct wlistdata *)flayer->l_data; - flayer->l_width = wi; - flayer->l_height = he; - wlistdata->numwin = he - 3; - if (wlistdata->ypos >= wlistdata->numwin) - wlistdata->ypos = wlistdata->numwin - 1; - flayer->l_y = he - 1; - return 0; -} - -static void -WListAbort() -{ - struct wlistdata * wlistdata = (struct wlistdata *)flayer->l_data; - if (wlistdata->list) - Free(wlistdata->list); - LAY_CALL_UP(LRefreshAll(flayer, 0)); - ExitOverlayPage(); -} - -static void -WListProcess(ppbuf, plen) -char **ppbuf; -int *plen; -{ - int done = 0; - struct wlistdata *wlistdata; - struct display *olddisplay = display; - int h; - struct win *group; - - ASSERT(flayer); - wlistdata = (struct wlistdata *)flayer->l_data; - group = wlistdata->group; - h = wlistdata->numwin; - while (!done && *plen > 0) - { - if ((unsigned char)**ppbuf >= '0' && (unsigned char)**ppbuf <= '9') - { - int n = (unsigned char)**ppbuf - '0'; - int d = 0; - if (n < maxwin && wtab[n] && WTAB_GROUP_MATCHES(n)) - { - int i; - for (d = -wlistdata->npos, i = WListNext(wlistdata, -1, 0); i != n; i = WListNext(wlistdata, i, 1), d++) - ; - } - if (d) - WListMove(d, -1); - } - switch ((unsigned char)**ppbuf) - { - case 0220: /* up */ - case 16: /* ^P like emacs */ - case 'k': - WListMove(-1, -1); - break; - case 0216: /* down */ - case 14: /* ^N like emacs */ - case 'j': - WListMove(1, -1); - break; - case '\025': - WListMove(-(h / 2), wlistdata->ypos); - break; - case '\004': - WListMove(h / 2, wlistdata->ypos); - break; - case 0002: - case 'b': - WListMove(-h, -1); - break; - case 0006: - case 'f': - WListMove(h, -1); - break; - case 0201: /* home */ - WListMove(-wlistdata->pos, -1); - break; - case 0205: /* end */ - WListMove(maxwin, -1); - break; - case 'a': - /* All-window view */ - wlistdata->group = 0; - wlistdata->nested = WLIST_NESTED; - wlistpage(); - break; - case 'g': - /* Toggle nested view */ - wlistdata->nested ^= WLIST_NESTED; - wlistpage(); - break; - case 'm': - /* Toggle MRU view */ - wlistdata->order ^= 1; - wlistpage(); - break; - case '\r': - case '\n': - case ' ': - h = wlistdata->pos; - if (h == maxwin && Layer2Window(flayer) && Layer2Window(flayer)->w_type == W_TYPE_GROUP) - break; - if (display && h != maxwin && wtab[h] && (wtab[h]->w_type == W_TYPE_GROUP) && Layer2Window(flayer) == wtab[h]) - { - wlistdata->group = wtab[h]; - wlistdata->pos = wtab[h]->w_number; - wlistpage(); - break; - } - done = 1; - if (!display || h == maxwin || !wtab[h] || wtab[h] == D_fore || (flayer->l_cvlist && flayer->l_cvlist->c_lnext)) - WListAbort(); -#ifdef MULTIUSER - else if (AclCheckPermWin(D_user, ACL_READ, wtab[h])) - WListAbort(); -#endif - else - { - if (wlistdata->list) - Free(wlistdata->list); - ExitOverlayPage(); /* no need to redisplay */ - } - /* restore display, don't switch wrong user */ - display = olddisplay; - if (h != maxwin) - SwitchWindow(h); - break; - case 0222: /* Mouse event */ - break; - case 0033: - case 0007: - h = wlistdata->start; - if (h == -1 && Layer2Window(flayer) && Layer2Window(flayer)->w_type == W_TYPE_GROUP) - { - struct win *p = Layer2Window(flayer); - if (wlistdata->group != p) - { - wlistdata->group = p; - wlistpage(); - } - break; - } - WListAbort(); - display = olddisplay; - if (h >= 0 && wtab[h]) - SwitchWindow(h); - else if (h == -2) - { - struct win *p = FindNiceWindow(display ? D_other : (struct win *)0, 0); - if (p) - SwitchWindow(p->w_number); - } - done = 1; - break; - case '\010': /* ctrl-h */ - case 0177: - if (!wlistdata->group) - break; - wlistdata->pos = wlistdata->group->w_number; - wlistdata->group = wlistdata->group->w_group; - if (wlistdata->group) - wlistdata->pos = wlistdata->group->w_number; - wlistpage(); - break; - default: - break; - } - ++*ppbuf; - --*plen; - } -} - -static void -WListLine(y, i, pos, isblank) -int y, i; -int pos; -int isblank; -{ - char *str; - int n; - int yoff, xoff = 0; - struct wlistdata *wlistdata; - struct win *group; - struct mchar mchar_rend = mchar_blank; - struct mchar *mchar = (struct mchar *)0; - - if (i == maxwin) - return; - wlistdata = (struct wlistdata *)flayer->l_data; - if (wlistdata->nested && wtab[i]) - for (group = wtab[i]->w_group, xoff = 0; group != wlistdata->group; - group = group->w_group, xoff += 2) - ; - yoff = wlistdata->group ? 3 : 2; - display = Layer2Window(flayer) ? 0 : flayer->l_cvlist ? flayer->l_cvlist->c_display : 0; - str = MakeWinMsgEv(wliststr, wtab[i], '%', flayer->l_width - xoff, (struct event *)0, 0); - n = strlen(str); - if (i != pos && isblank) - while (n && str[n - 1] == ' ') - n--; - if (i == pos) - mchar = &mchar_so; - else if (wtab[i]->w_monitor == MON_DONE && renditions[REND_MONITOR] != -1) - { - mchar = &mchar_rend; - ApplyAttrColor(renditions[REND_MONITOR], mchar); - } - else if ((wtab[i]->w_bell == BELL_DONE || wtab[i]->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1) - { - mchar = &mchar_rend; - ApplyAttrColor(renditions[REND_BELL], mchar); - } - else - mchar = &mchar_blank; - LPutWinMsg(flayer, str, (i == pos || !isblank) ? flayer->l_width : n, mchar, xoff, y + yoff); - if (xoff) - LPutWinMsg(flayer, "", xoff, mchar, 0, y + yoff); - if (mchar == &mchar_so) - flayer->l_y = y + yoff; -#if 0 - LPutStr(flayer, str, n, i == pos ? &mchar_so : &mchar_blank, 0, y + yoff); - if (i == pos || !isblank) - while(n < flayer->l_width) - LPutChar(flayer, i == pos ? &mchar_so : &mchar_blank, n++, y + yoff); -#endif - return; -} - - -static int -WListNext(wlistdata, old, delta) -struct wlistdata *wlistdata; -int old, delta; -{ - int i; - - if (old == maxwin) - return maxwin; - if (old == -1) - old = 0; - else - { - for (i = 0; i < maxwin && wlistdata->list[i] != -1; i++) - if (wlistdata->list[i] == old) - break; - if (i < maxwin && wlistdata->list[i] != -1) - old = i; - } - - old += delta; - if (old < 0 || old >= maxwin || wlistdata->list[old] == -1) - old -= delta; - return wlistdata->list[old]; -} - -static void -WListLines(up, oldpos) -int up, oldpos; -{ - struct wlistdata *wlistdata; - int ypos, pos; - int y, i, oldi; - - wlistdata = (struct wlistdata *)flayer->l_data; - ypos = wlistdata->ypos; - pos = wlistdata->pos; - - i = WListNext(wlistdata, pos, -ypos); - for (y = 0; y < wlistdata->numwin; y++) - { - if (i == maxwin || !wtab[i]) - return; - if (y == 0) - wlistdata->first = i; - wlistdata->last = i; - if (((i == oldpos || i == pos) && pos != oldpos) || (up > 0 && y >= wlistdata->numwin - up) || (up < 0 && y < -up)) - WListLine(y, i, pos, i != oldpos); - if (i == pos) - wlistdata->ypos = y; - oldi = i; - i = WListNext(wlistdata, i, 1); - if (i == maxwin || i == oldi) - break; - } -} - -static int -WListNormalize() -{ - struct wlistdata *wlistdata; - int i, oldi, n; - int ypos, pos; - - wlistdata = (struct wlistdata *)flayer->l_data; - ypos = wlistdata->ypos; - pos = wlistdata->pos; - if (ypos < 0) - ypos = 0; - if (ypos >= wlistdata->numwin) - ypos = wlistdata->numwin - 1; - for (n = 0, oldi = maxwin, i = pos; i != maxwin && i != oldi && n < wlistdata->numwin; oldi = i, i = WListNext(wlistdata, i, 1)) - n++; - if (ypos < wlistdata->numwin - n) - ypos = wlistdata->numwin - n; - for (n = 0, oldi = maxwin, i = WListNext(wlistdata, -1, 0); i != maxwin && i != oldi && i != pos; oldi = i, i = WListNext(wlistdata, i, 1)) - n++; - if (ypos > n) - ypos = n; - wlistdata->ypos = ypos; - wlistdata->npos = n; - return ypos; -} - -static void -WListMove(num, ypos) -int num; -int ypos; -{ - struct wlistdata *wlistdata; - int oldpos, oldypos, oldnpos; - int pos, up; - - wlistdata = (struct wlistdata *)flayer->l_data; - oldpos = wlistdata->pos; - oldypos = wlistdata->ypos; - oldnpos = wlistdata->npos; - wlistdata->ypos = ypos == -1 ? oldypos + num : ypos; - pos = WListNext(wlistdata, oldpos, num); - wlistdata->pos = pos; - ypos = WListNormalize(); - up = wlistdata->npos - ypos - (oldnpos - oldypos); - if (up) - { - LScrollV(flayer, up, 2, 2 + wlistdata->numwin - 1, 0); - WListLines(up, oldpos); - LaySetCursor(); - return; - } - if (pos == oldpos) - return; - WListLine(oldypos, oldpos, pos, 0); - WListLine(ypos, pos, pos, 1); - LaySetCursor(); -} - -static void -WListRedisplayLine(y, xs, xe, isblank) -int y, xs, xe, isblank; -{ - ASSERT(flayer); - if (y < 0) - { - wlistpage(); - return; - } - if (y != 0 && y != flayer->l_height - 1) - return; - if (!isblank) - LClearArea(flayer, xs, y, xe, y, 0, 0); -} - -static int -WListOrder(wlistdata, ind, start, group) -struct wlistdata *wlistdata; -int ind, start; -struct win *group; -{ - int i; - - if (ind >= maxwin) - return ind; - if (ind == 0) - for (i = 0; i < maxwin; i++) - wlistdata->list[i] = -1; - - if (wlistdata->order == WLIST_MRU) - { - if (start == -1) - start = windows->w_number; - } - else - { - if (start == -1) - start = 0; - while (start < maxwin && !wtab[start]) - start++; - } - - if (start >= maxwin || !wtab[start]) - return ind; - - if (!WTAB_GROUP_MATCHES(start)) - { - while (start < maxwin && (!wtab[start] || !WTAB_GROUP_MATCHES(start))) - if (wlistdata->order != WLIST_MRU) - start++; - else if (wtab[start]->w_next) - start = wtab[start]->w_next->w_number; - else - start = maxwin; - if (start >= maxwin || !wtab[start]) - return ind; - } - - wlistdata->list[ind++] = start; - if (wlistdata->nested && wtab[start]->w_type == W_TYPE_GROUP) - ind = WListOrder(wlistdata, ind, -1, wtab[start]); - - if (wlistdata->order != WLIST_MRU) - start++; - else if (wtab[start]->w_next) - start = wtab[start]->w_next->w_number; - else - return ind; - return WListOrder(wlistdata, ind, start, group); -} -#endif - -void -display_wlist(onblank, order, group) -int onblank; -int order; -struct win *group; -{ - display_windows(onblank, order, group); - return; -#if 0 - struct win *p; - struct wlistdata *wlistdata; - - - if (flayer->l_width < 10 || flayer->l_height < 6) - { - LMsg(0, "Window size too small for window list page"); - return; - } - if (onblank) - { - debug3("flayer %x %d %x\n", flayer, flayer->l_width, flayer->l_height); - if (!display) - { - LMsg(0, "windowlist -b: display required"); - return; - } - p = D_fore; - if (p) - { - SetForeWindow((struct win *)0); - if (p->w_group) - { - D_fore = p->w_group; - flayer->l_data = (char *)p->w_group; - } - Activate(0); - } - if (flayer->l_width < 10 || flayer->l_height < 6) - { - LMsg(0, "Window size too small for window list page"); - return; - } - } - else - p = Layer2Window(flayer); - if (!group && p) - group = p->w_group; - if (InitOverlayPage(sizeof(*wlistdata), &WListLf, 0)) - return; - wlistdata = (struct wlistdata *)flayer->l_data; - wlistdata->list = calloc(maxwin, sizeof(int)); - flayer->l_mode = 1; - flayer->l_x = 0; - flayer->l_y = flayer->l_height - 1; - wlistdata->start = onblank && p ? p->w_number : -1; - wlistdata->order = (order & 0x1); - wlistdata->group = group; - wlistdata->pos = p ? p->w_number : WListNext(wlistdata, -1, 0); - wlistdata->ypos = wlistdata->npos = 0; - wlistdata->numwin = flayer->l_height - (group ? 4 : 3); - wlistdata->nested = (order & WLIST_NESTED); - wlistpage(); -#endif -} - -#if 0 -static void -wlistpage() -{ - struct wlistdata *wlistdata; - char *str; - int pos; - struct win *group; - - wlistdata = (struct wlistdata *)flayer->l_data; - group = wlistdata->group; - - LClearAll(flayer, 0); - if (wlistdata->start >= 0 && wtab[wlistdata->start] == 0) - wlistdata->start = -2; - - WListOrder(wlistdata, 0, -1, group); - pos = wlistdata->pos; - if (pos == maxwin || !wtab[pos] || !WTAB_GROUP_MATCHES(pos)) - { - if (wlistdata->order == WLIST_MRU) - pos = WListNext(wlistdata, -1, wlistdata->npos); - else - { - /* find new position */ - if (pos < maxwin) - while(++pos < maxwin) - if (wtab[pos] && WTAB_GROUP_MATCHES(pos)) - break; - if (pos == maxwin) - while (--pos >= 0) - if (wtab[pos] && WTAB_GROUP_MATCHES(pos)) - break; - if (pos == -1) - pos = maxwin; - } - } - wlistdata->pos = pos; - - display = 0; - str = MakeWinMsgEv(wlisttit, (struct win *)0, '%', flayer->l_width, (struct event *)0, 0); - if (wlistdata->group) - { - LPutWinMsg(flayer, "Group: ", 7, &mchar_blank, 0, 0); - LPutWinMsg(flayer, wlistdata->group->w_title, strlen(wlistdata->group->w_title), &mchar_blank, 7, 0); - LPutWinMsg(flayer, str, strlen(str), &mchar_blank, 0, 1); - } - else - { - LPutWinMsg(flayer, str, strlen(str), &mchar_blank, 0, 0); - } - WListNormalize(); - WListLines(wlistdata->numwin, -1); - LaySetCursor(); -} - -static void -WListUpdate(p) -struct win *p; -{ - struct wlistdata *wlistdata; - int i, n, y; - - if (p == 0) - { - wlistpage(); - return; - } - wlistdata = (struct wlistdata *)flayer->l_data; - n = p->w_number; - if (wlistdata->order == WLIST_NUM && (n < wlistdata->first || n > wlistdata->last)) - return; - i = wlistdata->first; - for (y = 0; y < wlistdata->numwin; y++) - { - if (i == n) - break; - i = WListNext(wlistdata, i, 1); - } - if (y == wlistdata->numwin) - return; - WListLine(y, i, wlistdata->pos, 0); - LaySetCursor(); -} -#endif - /* ** ** The bindkey help page diff --git a/src/process.c b/src/process.c index b12eafb..add2c2a 100644 --- a/src/process.c +++ b/src/process.c @@ -51,6 +51,7 @@ #include "logfile.h" #include "layout.h" #include "viewport.h" +#include "list_generic.h" extern struct comm comms[]; extern char *rc_name; @@ -2202,7 +2203,7 @@ int key; #endif case RC_WINDOWLIST: if (!*args) - display_wlist(0, WLIST_NUM, (struct win *)0); + display_windows(0, WLIST_NUM, (struct win *)0); else if (!strcmp(*args, "string")) { if (args[1]) @@ -2244,7 +2245,7 @@ int key; break; } if (i == argc) - display_wlist(blank, flag, (struct win *)0); + display_windows(blank, flag, (struct win *)0); } break; case RC_HELP: diff --git a/src/socket.c b/src/socket.c index 0f08d60..680a150 100644 --- a/src/socket.c +++ b/src/socket.c @@ -49,6 +49,7 @@ #endif #include "extern.h" +#include "list_generic.h" static int CheckPid __P((int)); static void ExecCreate __P((struct msg *)); @@ -1442,9 +1443,9 @@ struct msg *m; { struct display *olddisplay = display; flayer = D_forecv->c_layer; - display_wlist(1, WLIST_NUM, (struct win *)0); + display_windows(1, WLIST_NUM, (struct win *)0); noshowwin = 1; - display = olddisplay; /* display_wlist can change display */ + display = olddisplay; /* display_windows can change display */ } } Activate(0); -- cgit v1.2.1 From 8dea5b5ab97087a68a55675cce8e79d4b579b674 Mon Sep 17 00:00:00 2001 From: Juergen Weigert Date: Tue, 23 Feb 2010 20:43:33 -0500 Subject: Reset displays before dumping a core. If defined SHADOWPW, we may have passwd records in core, that the user would not be able to access otherwise. In that case, we should not dump core, as the core file would contain the passwd records, and would be readable for the user. We do not explicitly check for eff_uid == 0, because if his real_uid is also 0 he could have read all this anyway. Leaving only the cases where the two uids differ. --- src/screen.c | 56 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/screen.c b/src/screen.c index 67cddbc..06441dd 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1,4 +1,7 @@ -/* Copyright (c) 2008, 2009 +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -764,17 +767,12 @@ char **av; real_gid = getgid(); eff_uid = geteuid(); eff_gid = getegid(); - if (eff_uid != real_uid) - { - /* if running with s-bit, we must install a special signal - * handler routine that resets the s-bit, so that we get a - * core file anyway. - */ + #ifdef SIGBUS /* OOPS, linux has no bus errors! */ - signal(SIGBUS, CoreDump); + signal(SIGBUS, CoreDump); #endif /* SIGBUS */ - signal(SIGSEGV, CoreDump); - } + signal(SIGSEGV, CoreDump); + #ifdef USE_LOCALE setlocale(LC_ALL, ""); @@ -1636,39 +1634,55 @@ SigInt SIGDEFARG static sigret_t CoreDump SIGDEFARG { + /* if running with s-bit, we must reset the s-bit, so that we get a + * core file anyway. + */ + struct display *disp; char buf[80]; + char *dump_msg = " (core dumped)"; + + int running_w_s_bit = getuid() != geteuid(); +#if defined(SHADOWPW) && !defined(DEBUG) && !defined(DUMPSHADOW) + if (running_w_s_bit) + dump_msg = ""; +#endif + #if defined(SYSVSIGS) && defined(SIGHASARG) signal(sigsig, SIG_IGN); #endif setgid(getgid()); setuid(getuid()); unlink("core"); + #ifdef SIGHASARG - sprintf(buf, "\r\n[screen caught signal %d.%s]\r\n", sigsig, + sprintf(buf, "\r\n[screen caught signal %d.%s]\r\n", sigsig, dump_msg); #else - sprintf(buf, "\r\n[screen caught a fatal signal.%s]\r\n", + sprintf(buf, "\r\n[screen caught a fatal signal.%s]\r\n", dump_msg); #endif -#if defined(SHADOWPW) && !defined(DEBUG) && !defined(DUMPSHADOW) - "" -#else /* SHADOWPW && !DEBUG */ - " (core dumped)" -#endif /* SHADOWPW && !DEBUG */ - ); + for (disp = displays; disp; disp = disp->d_next) { + if (disp->d_nonblock < -1 || disp->d_nonblock > 1000000) + continue; fcntl(disp->d_userfd, F_SETFL, 0); SetTTY(disp->d_userfd, &D_OldMode); write(disp->d_userfd, buf, strlen(buf)); Kill(disp->d_userpid, SIG_BYE); } + + if (running_w_s_bit) + { #if defined(SHADOWPW) && !defined(DEBUG) && !defined(DUMPSHADOW) - Kill(getpid(), SIGKILL); - eexit(11); + Kill(getpid(), SIGKILL); + eexit(11); #else /* SHADOWPW && !DEBUG */ - abort(); + abort(); #endif /* SHADOWPW && !DEBUG */ + } + else + abort(); SIGRETURN; } -- cgit v1.2.1 From 24246d27ea5be518c2c43b36b3187295cb8456a6 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 00:29:19 -0500 Subject: Add some navigation shortcut in list views. Page-up/down, home/end, ^A, ^E, ^B, ^F, ^D, ^U keys do their things. --- src/list_generic.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/list_generic.c b/src/list_generic.c index 9f7d628..02eb220 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -68,9 +68,20 @@ glist_display(struct GenericList *list, const char *name) return ldata; } +static void +glist_decide_top(struct ListData *ldata) +{ + int count = flayer->l_height - 5; /* 2 for header, 1 for footer */ + struct ListRow *top = ldata->selected; + for (; count && top != ldata->root; top = top->prev, count--) + ; + ldata->top = top; +} + static void ListProcess(char **ppbuf, int *plen) { struct ListData *ldata = flayer->l_data; + int count = 0; while (*plen > 0) { @@ -114,7 +125,6 @@ static void ListProcess(char **ppbuf, int *plen) case 'j': if (!ldata->selected->next) /* Nothing to do */ break; - old = ldata->selected; ldata->selected = old->next; break; @@ -123,6 +133,39 @@ static void ListProcess(char **ppbuf, int *plen) ListAbort(); *plen = 0; return; + + case 0201: /* home */ + case 0001: /* ^A */ + ldata->selected = ldata->root; + break; + + case 0205: /* end */ + case 0005: /* ^E */ + while (ldata->selected->next) + ldata->selected = ldata->selected->next; + if (ldata->selected->y != -1) + { + /* Both old and current selections are on the screen. So we can just + * redraw these two affected rows. */ + } + break; + + case 0004: /* ^D (half-page down) */ + case 0006: /* page-down, ^F */ + count = (flayer->l_height - 4) >> (ch == 0004); + for (; ldata->selected->next && --count; + ldata->selected = ldata->selected->next) + ; + break; + + case 0025: /* ^U (half-page up) */ + case 0002: /* page-up, ^B */ + count = (flayer->l_height - 4) >> (ch == 0025); + for (; ldata->selected->prev && --count; + ldata->selected = ldata->selected->prev) + ; + break; + } if (old == ldata->selected) /* The selection didn't change */ @@ -130,7 +173,9 @@ static void ListProcess(char **ppbuf, int *plen) if (ldata->selected->y == -1) { - /* We need to list all the rows, since we are scrolling down */ + /* We need to list all the rows, since we are scrolling down. But first, + * find the top of the visible list. */ + glist_decide_top(ldata); glist_display_all(ldata); } else -- cgit v1.2.1 From ca397618071bc4e494f2810b9368c791c157942f Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 01:36:22 -0500 Subject: Allow searching in the window list. Press '/' to enter the search string, then pressing 'n' will search forward, and 'N' will search backward. Press '/' again to change the search string. --- src/list_display.c | 3 +- src/list_generic.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/list_generic.h | 3 ++ src/list_window.c | 12 ++++++- 4 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/list_display.c b/src/list_display.c index 56e7f08..19566ec 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -218,7 +218,8 @@ static struct GenericList gl_Display = gl_Display_row, gl_Display_input, gl_Display_freerow, - gl_Display_free + gl_Display_free, + NULL /* We do not allow searching in the display list, at the moment */ }; void diff --git a/src/list_generic.c b/src/list_generic.c index 02eb220..369e35a 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -24,6 +24,7 @@ #include "screen.h" #include "list_generic.h" #include "layer.h" +#include "extern.h" /* Deals with a generic list display */ @@ -78,6 +79,67 @@ glist_decide_top(struct ListData *ldata) ldata->top = top; } +static struct ListRow * +glist_search_dir(struct ListData *ldata, struct ListRow *start, int dir) +{ + struct ListRow *row = (dir == 1) ? start->next : start->prev; + for (; row; row = (dir == 1) ? row->next : row->prev) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + return row; + + if (dir == 1) + { + for (row = ldata->root; row != start; row = row->next) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + } + else + { + /* First, go to the end */ + if (!start->next) + row = start; + else + for (row = start->next; row->next; row = row->next) + ; + for (; row != start; row = row->prev) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + } + + return row; +} + +static void +glist_search(char *buf, int len, char *data) +{ + struct ListData *ldata = (struct ListData *)data; + struct ListRow *row; + + if (ldata->search) + Free(ldata->search); + if (len > 0) + ldata->search = SaveStr(buf); + else + return; + + for (row = ldata->selected; row; row = row->next) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + + if (!row) + for (row = ldata->root; row != ldata->selected; row = row->next) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + + if (row == ldata->selected) + return; + + ldata->selected = row; + if (ldata->selected->y == -1) + glist_decide_top(ldata); + glist_display_all(ldata); +} + static void ListProcess(char **ppbuf, int *plen) { struct ListData *ldata = flayer->l_data; @@ -166,6 +228,34 @@ static void ListProcess(char **ppbuf, int *plen) ; break; + case '/': /* start searching */ + if (ldata->list_fn->gl_matchrow) + { + char *s; + Input("Search: ", 80, INP_COOKED, glist_search, (char *)ldata, 0); + if ((s = ldata->search)) + { + for (; *s; s++) + { + char *ss = s; + int n = 1; + LayProcess(&ss, &n); + } + } + } + break; + + /* The following deal with searching. */ + + case 'n': /* search next */ + if (ldata->list_fn->gl_matchrow && ldata->search) + ldata->selected = glist_search_dir(ldata, ldata->selected, 1); + break; + + case 'N': /* search prev */ + if (ldata->list_fn->gl_matchrow && ldata->search) + ldata->selected = glist_search_dir(ldata, ldata->selected, -1); + break; } if (old == ldata->selected) /* The selection didn't change */ @@ -195,6 +285,8 @@ static void ListAbort(void) glist_remove_rows(ldata); if (ldata->list_fn->gl_free) ldata->list_fn->gl_free(ldata); + if (ldata->search) + Free(ldata->search); LAY_CALL_UP(LRefreshAll(flayer, 0)); ExitOverlayPage(); } diff --git a/src/list_generic.h b/src/list_generic.h index 489694c..234f6de 100644 --- a/src/list_generic.h +++ b/src/list_generic.h @@ -37,6 +37,7 @@ struct GenericList int (*gl_pinput) __P((struct ListData *, char **inp, int *len)); /* Process input */ int (*gl_freerow) __P((struct ListData *, struct ListRow *)); /* Free data for a row */ int (*gl_free) __P((struct ListData *)); /* Free data for the list */ + int (*gl_matchrow) __P((struct ListData *, struct ListRow *, const char *)); }; struct ListData @@ -48,6 +49,8 @@ struct ListData struct GenericList *list_fn; /* The functions that deal with the list */ + char *search; /* The search term, if any */ + void *data; /* List specific data */ }; diff --git a/src/list_window.c b/src/list_window.c index f21b4f6..982b781 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -373,6 +373,15 @@ gl_Window_free(struct ListData *ldata) return 0; } +static int +gl_Window_match(struct ListData *ldata, struct ListRow *row, const char *needle) +{ + struct win *w = row->data; + if (InStr(w->w_title, needle)) + return 1; + return 0; +} + static struct GenericList gl_Window = { gl_Window_header, @@ -380,7 +389,8 @@ static struct GenericList gl_Window = gl_Window_row, gl_Window_input, gl_Window_freerow, - gl_Window_free + gl_Window_free, + gl_Window_match }; void -- cgit v1.2.1 From 3a0f07481428333b97a69956ddebdb57d70227a7 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 02:30:59 -0500 Subject: Simplify a little. --- src/list_generic.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/list_generic.c b/src/list_generic.c index 369e35a..24caf48 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -88,11 +88,7 @@ glist_search_dir(struct ListData *ldata, struct ListRow *start, int dir) return row; if (dir == 1) - { - for (row = ldata->root; row != start; row = row->next) - if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) - break; - } + row = ldata->root; else { /* First, go to the end */ @@ -101,11 +97,12 @@ glist_search_dir(struct ListData *ldata, struct ListRow *start, int dir) else for (row = start->next; row->next; row = row->next) ; - for (; row != start; row = row->prev) - if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) - break; } + for (; row != start; row = (dir == 1) ? row->next : row->prev) + if (ldata->list_fn->gl_matchrow(ldata, row, ldata->search)) + break; + return row; } -- cgit v1.2.1 From 42f59cca30ef4e7a390b283ba02a4a015718fb2e Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 02:32:23 -0500 Subject: Typo fixes from Trent W Buck. --- src/attacher.c | 2 +- src/doc/screen.1 | 2 +- src/doc/screen.texinfo | 2 +- src/socket.c | 4 ++-- src/termcap.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/attacher.c b/src/attacher.c index ef3ce8b..88da744 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -453,7 +453,7 @@ AttacherSigInt SIGDEFARG } /* - * Unfortunatelly this is also the SIGHUP handler, so we have to + * Unfortunately this is also the SIGHUP handler, so we have to * check if the backend is already detached. */ diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 9da825d..09ef30d 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -1898,7 +1898,7 @@ Note that \fBk\fP is traditionally bound to the \fIkill\fP command. .PP This forces any currently selected region to be automatically resized at least a certain \fIwidth\fP and \fIheight\fP. All -other surrounding regions will be resized in order to accomodate. +other surrounding regions will be resized in order to accommodate. This constraint follows everytime the \*Qfocus\*U command is used. The \*Qresize\*U command can be used to increase either dimension of a region, but never below what is set with diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index 94c2aa3..d453b07 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -2026,7 +2026,7 @@ automatically if the window is displayed more than once. (none)@* This forces any currently selected region to be automatically resized at least a certain @var{width} and @var{height}. All -other surrounding regions will be resized in order to accomodate. +other surrounding regions will be resized in order to accommodate. This constraint follows every time the @code{focus} command is used. The @code{resize} command can be used to increase either dimension of a region, but never below what is set with diff --git a/src/socket.c b/src/socket.c index 680a150..9e61816 100644 --- a/src/socket.c +++ b/src/socket.c @@ -451,7 +451,7 @@ MakeServerSocket() if (stat(SockPath, &st) == -1) Panic(errno, "stat"); if ((int)st.st_uid != real_uid) - Panic(0, "Unfortunatelly you are not its owner."); + Panic(0, "Unfortunately you are not its owner."); if ((st.st_mode & 0700) == 0600) Panic(0, "To resume it, use \"screen -r\""); else @@ -543,7 +543,7 @@ MakeServerSocket() if (stat(SockPath, &st) == -1) Panic(errno, "stat"); if (st.st_uid != real_uid) - Panic(0, "Unfortunatelly you are not its owner."); + Panic(0, "Unfortunately you are not its owner."); if ((st.st_mode & 0700) == 0600) Panic(0, "To resume it, use \"screen -r\""); else diff --git a/src/termcap.c b/src/termcap.c index 42f6a73..8f6b8b9 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -260,7 +260,7 @@ int he; D_US = D_UE = 0; if (D_SG > 0) D_SO = D_SE = 0; - /* Unfortunatelly there is no 'mg' capability. + /* Unfortunately there is no 'mg' capability. * For now we think that mg > 0 if sg and ug > 0. */ if (D_UG > 0 && D_SG > 0) -- cgit v1.2.1 From fcdce5c6320b37649afb1710fd276fabefa6510e Mon Sep 17 00:00:00 2001 From: Curtis Brown Date: Wed, 24 Feb 2010 02:39:03 -0500 Subject: Man-pages updates for -p, -T, 'stuff' and 'su'. --- src/doc/screen.1 | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 09ef30d..83deb02 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -288,12 +288,13 @@ emulation (only affects auto-margin terminals without `LP'). This can also be set in your .screenrc by specifying `OP' in a \*Qtermcap\*U command. .TP 5 -.BI "\-p " number_or_name +.BI "\-p " number_or_name|-|=|+ Preselect a window. This is useful when you want to reattach to a specific window or you want to send a command via the \*Q-X\*U option to a specific window. As with screen's select command, \*Q-\*U selects the blank window. As a special case for reattach, \*Q=\*U -brings up the windowlist on the blank window. The command will not be +brings up the windowlist on the blank window, while a \*Q+\*U +will create a new window. The command will not be executed if the specified window could not be found. .TP 5 .B \-q @@ -365,6 +366,10 @@ default [\fItty.host\fP] suffix. sets the title (a.\|k.\|a.) for the default shell or specified program. See also the \*Qshelltitle\*U .screenrc command. .TP 5 +.BI "\-T " term +Set the $TERM enviroment varible using the spcified term as +opposed to the defualt setting of \fBscreen\fP. +.TP 5 .B \-U Run screen in UTF-8 mode. This option tells screen that your terminal sends and understands UTF-8 encoded characters. It also sets the default @@ -2932,21 +2937,22 @@ Select whether you want to see the copyright notice during startup. Default is `on', as you probably noticed. .sp .ne 3 -.B stuff -.I string +.B stuff +.RB [ "\fIstring\fR" ] .PP Stuff the string .I string in the input buffer of the current window. This is like the \*Qpaste\*U command but with much less overhead. +Without a paramter, screen will prompt for a string to stuff. You cannot paste large buffers with the \*Qstuff\*U command. It is most useful for key bindings. See also \*Qbindkey\*U. .sp .ne 3 .B su -.RB [ username " [" password -.RB [ password2 ]] +.RI [ username " [" password +.RI [ password2 ]]] .PP Substitute the user of a display. The command prompts for all parameters that are omitted. If passwords are specified as parameters, they have to be -- cgit v1.2.1 From 230cee80c145cf2d359b2c9fbcf6d4f2561b0d4a Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 03:59:53 -0500 Subject: Changelog the search-ability in the windowlist. --- src/ChangeLog | 4 ++++ src/help.c | 6 +++++- src/list_display.c | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index dd85d82..c5c2241 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -56,6 +56,10 @@ Version 4.1.0 (??/??/20??): * Press 'm' to toggle the most-recent view. * Press 'g' to toggle nestedness. * Press 'a' to view all windows in the list. + * Press '/' to search in the list. + + Display List: + * Press 'd' to detach a display, 'D' to power-detach. Others: * Start using 'ChangeLog' for logging changes again. diff --git a/src/help.c b/src/help.c index f8ae2fc..d818ea4 100644 --- a/src/help.c +++ b/src/help.c @@ -1,4 +1,7 @@ -/* Copyright (c) 2008, 2009 +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -508,6 +511,7 @@ static const char cpmsg[] = "\ \n\ Screen version %v\n\ \n\ +Copyright (c) 2010 Juergen Weigert, Sadrul Habib Chowdhury\n\ Copyright (c) 2008, 2009 Juergen Weigert, Michael Schroeder, Micah Cowan, Sadrul Habib Chowdhury\n\ Copyright (c) 1993-2002, 2003, 2005, 2006, 2007 Juergen Weigert, Michael Schroeder\n\ Copyright (c) 1987 Oliver Laumann\n\ diff --git a/src/list_display.c b/src/list_display.c index 19566ec..4e740c1 100644 --- a/src/list_display.c +++ b/src/list_display.c @@ -169,6 +169,7 @@ gl_Display_input(struct ListData *ldata, char **inp, int *len) *len = 0; break; +#ifdef REMOTE_DETACH case 'd': /* Detach */ case 'D': /* Power detach */ display = ldata->selected->data; @@ -185,8 +186,7 @@ gl_Display_input(struct ListData *ldata, char **inp, int *len) glist_remove_rows(ldata); gl_Display_rebuild(ldata); break; - - break; +#endif default: /* We didn't actually process the input. */ -- cgit v1.2.1 From c6a9fa007720396b78a096eed9a9ffb95fc9cbc5 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 06:38:36 -0500 Subject: Typo fix. --- src/list_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/list_window.c b/src/list_window.c index 982b781..66156d1 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -173,7 +173,7 @@ gl_Window_remove(struct ListData *ldata, struct win *p) if (ldata->selected == row) ldata->selected = row->prev ? row->prev : row->next; if (ldata->top == row) - ldata->selected = row->prev ? row->prev : row->next; + ldata->top = row->prev ? row->prev : row->next; if (ldata->root == row) ldata->root = row->next; -- cgit v1.2.1 From d1d0cc4d63eed5234f55aa0228196815f9969ae0 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 08:46:57 -0500 Subject: Allow moving windows around from the window list. Press ',' to switch the selected window with its previous window (in the same group). Similarly, press '.' to switch with the next window. --- src/ChangeLog | 1 + src/list_window.c | 48 +++++++++++++++++++++++++++++++++++++++++++---- src/process.c | 39 ++++++-------------------------------- src/window.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/window.h | 7 ++++++- 5 files changed, 112 insertions(+), 39 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c5c2241..7565fae 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -57,6 +57,7 @@ Version 4.1.0 (??/??/20??): * Press 'g' to toggle nestedness. * Press 'a' to view all windows in the list. * Press '/' to search in the list. + * Press ',' and '.' to re-order windows in the list. Display List: * Press 'd' to detach a display, 'D' to power-detach. diff --git a/src/list_window.c b/src/list_window.c index 66156d1..f637a7a 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -82,6 +82,8 @@ gl_Window_add_group(struct ListData *ldata, struct ListRow *row) continue; cur = glist_add_row(ldata, w, cur); + if (w == wdata->fore) + ldata->selected = cur; if (w->w_type == W_TYPE_GROUP) cur = gl_Window_add_group(ldata, cur); @@ -95,7 +97,9 @@ gl_Window_add_group(struct ListData *ldata, struct ListRow *row) if (!*w || (*w)->w_group != group) continue; - cur = glist_add_row(ldata, *w, cur); + cur = glist_add_row(ldata, *w, cur); + if (*w == wdata->fore) + ldata->selected = cur; if ((*w)->w_type == W_TYPE_GROUP) cur = gl_Window_add_group(ldata, cur); @@ -339,6 +343,35 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) } break; + case ',': /* Switch numbers with the previous window. */ + if (wdata->order == WLIST_NUM && ldata->selected->prev) + { + struct win *pw = ldata->selected->prev->data; + win = ldata->selected->data; + if (win->w_group != pw->w_group) + break; /* Do not allow switching with the parent group */ + + /* When a windows's number is successfully changed, it triggers a WListUpdatecv + * with NULL window. So that causes a redraw of the entire list. So reset the + * 'selected' after that. */ + wdata->fore = win; + WindowChangeNumber(win, pw->w_number); + } + break; + + case '.': /* Switch numbers with the next window. */ + if (wdata->order == WLIST_NUM && ldata->selected->next) + { + struct win *nw = ldata->selected->next->data; + win = ldata->selected->data; + if (win->w_group != nw->w_group) + break; /* Do not allow switching with the parent group */ + + wdata->fore = win; + WindowChangeNumber(win, nw->w_number); + } + break; + case 033: /* escape */ case 007: /* ^G */ if (wdata->group) @@ -474,7 +507,7 @@ WListUpdate(struct win *p, struct ListData *ldata) struct gl_Window_Data *wdata = ldata->data; struct ListRow *row, *rbefore; struct win *before; - int d = 0; + int d = 0, sel = 0; if (!p) { @@ -546,12 +579,19 @@ WListUpdate(struct win *p, struct ListData *ldata) if (row) { if (row->prev != rbefore) - gl_Window_remove(ldata, p); + { + sel = ldata->selected->data == p; + gl_Window_remove(ldata, p); + } else p = NULL; /* the window is in the correct place */ } if (p) - glist_add_row(ldata, p, rbefore); + { + row = glist_add_row(ldata, p, rbefore); + if (sel) + ldata->selected = row; + } glist_display_all(ldata); } diff --git a/src/process.c b/src/process.c index add2c2a..137037d 100644 --- a/src/process.c +++ b/src/process.c @@ -1,4 +1,7 @@ -/* Copyright (c) 2008, 2009 +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -2982,42 +2985,12 @@ int key; n += old; else if (rel < 0) n = old - n; - if (n < 0 || n >= maxwin) + if (!WindowChangeNumber(fore, n)) { - Msg(0, "Given window position is invalid."); + /* Window number could not be changed. */ queryflag = -1; return; } - p = wtab[n]; - wtab[n] = fore; - fore->w_number = n; - wtab[old] = p; - if (p) - p->w_number = old; -#ifdef MULTIUSER - /* exchange the acls for these windows. */ - AclWinSwap(old, n); -#endif -#ifdef UTMPOK - /* exchange the utmp-slots for these windows */ - if ((fore->w_slot != (slot_t) -1) && (fore->w_slot != (slot_t) 0)) - { - RemoveUtmp(fore); - SetUtmp(fore); - } - if (p && (p->w_slot != (slot_t) -1) && (p->w_slot != (slot_t) 0)) - { - /* XXX: first display wins? */ - display = fore->w_layer.l_cvlist ? fore->w_layer.l_cvlist->c_display : 0; - RemoveUtmp(p); - SetUtmp(p); - } -#endif - - WindowChanged(fore, 'n'); - WindowChanged((struct win *)0, 'w'); - WindowChanged((struct win *)0, 'W'); - WindowChanged((struct win *)0, 0); } break; case RC_SILENCE: diff --git a/src/window.c b/src/window.c index 20bceac..edf04dd 100644 --- a/src/window.c +++ b/src/window.c @@ -1,4 +1,7 @@ -/* Copyright (c) 2008, 2009 +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -2261,3 +2264,54 @@ struct display *d; } #endif + +int +WindowChangeNumber(struct win *win, int n) +{ + struct win *p; + int old = win->w_number; + + if (n < 0 || n >= maxwin) + { + Msg(0, "Given window position is invalid."); + return 0; + } + + p = wtab[n]; + wtab[n] = win; + win->w_number = n; + wtab[old] = p; + if (p) + p->w_number = old; +#ifdef MULTIUSER + /* exchange the acls for these windows. */ + AclWinSwap(old, n); +#endif +#ifdef UTMPOK + /* exchange the utmp-slots for these windows */ + if ((win->w_slot != (slot_t) -1) && (win->w_slot != (slot_t) 0)) + { + RemoveUtmp(win); + SetUtmp(win); + } + if (p && (p->w_slot != (slot_t) -1) && (p->w_slot != (slot_t) 0)) + { + /* XXX: first display wins? */ +#if 0 + /* Does this make more sense? */ + display = p->w_lastdisp ? p->w_lastdisp : p->w_layer.l_cvlist ? p->w_layer.l_cvlist->c_display : 0; +#else + display = win->w_layer.l_cvlist ? win->w_layer.l_cvlist->c_display : 0; +#endif + RemoveUtmp(p); + SetUtmp(p); + } +#endif + + WindowChanged(win, 'n'); + WindowChanged((struct win *)0, 'w'); + WindowChanged((struct win *)0, 'W'); + WindowChanged((struct win *)0, 0); + return 1; +} + diff --git a/src/window.h b/src/window.h index cd6c7da..6bd8e2d 100644 --- a/src/window.h +++ b/src/window.h @@ -1,4 +1,7 @@ -/* Copyright (c) 2008, 2009 +/* Copyright (c) 2010 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net) + * Copyright (c) 2008, 2009 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) * Micah Cowan (micah@cowan.name) @@ -334,5 +337,7 @@ struct win #define Layer2Window(l) ((struct win *)(l)->l_bottom->l_data) +int WindowChangeNumber __P((struct win *, int)); + #endif /* SCREEN_WINDOW_H */ -- cgit v1.2.1 From 9a6defe5d992f866f8a82f56ee21e7a3d2ca2a8d Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 09:20:02 -0500 Subject: Some more window-management from the window-list. Pressing 'K' in the window-list will kill a window (after confirmation). Also, added some notes. --- src/ChangeLog | 1 + src/list_window.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 7565fae..c02d5cc 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -58,6 +58,7 @@ Version 4.1.0 (??/??/20??): * Press 'a' to view all windows in the list. * Press '/' to search in the list. * Press ',' and '.' to re-order windows in the list. + * Press 'K' to kill a window (requires confirmation). Display List: * Press 'd' to detach a display, 'D' to power-detach. diff --git a/src/list_window.c b/src/list_window.c index f637a7a..f6f058a 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -22,6 +22,11 @@ /* Deals with the list of windows */ +/* NOTE: A 'struct win *' is used as the 'data' for each row. It might make more sense + * to use 'struct win* ->w_number' as the 'data', instead, because that way, we can + * verify that the window does exist (by looking at wtab[]). + */ + #include "config.h" #include "screen.h" #include "layer.h" @@ -37,9 +42,11 @@ extern char *wliststr; extern struct mchar mchar_blank, mchar_so; extern int renditions[]; -extern struct win **wtab, *windows; +extern struct win **wtab, *windows, *fore; extern int maxwin; +extern char *noargs[]; + static char ListID[] = "window"; struct gl_Window_Data @@ -63,6 +70,35 @@ window_ancestor(struct win *a, struct win *d) return 0; } +static void +window_kill_confirm(char *buf, int len, char *data) +{ + struct win *w = windows; + struct action act; + + if (len || (*buf != 'y' && *buf != 'Y')) + { + *buf = 0; + return; + } + + /* Loop over the windows to make sure that the window actually still exists. */ + for (; w; w = w->w_next) + if (w == (struct win *)data) + break; + + if (!w) + return; + + /* Pretend the selected window is the foreground window. Then trigger a non-interactive 'kill' */ + fore = w; + act.nr = RC_KILL; + act.args = noargs; + act.argl = 0; + act.quiet = 0; + DoAction(&act, -1); +} + static struct ListRow * gl_Window_add_group(struct ListData *ldata, struct ListRow *row) { @@ -263,12 +299,12 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) ++*inp; --*len; + win = ldata->selected->data; switch (ch) { case ' ': case '\n': case '\r': - win = ldata->selected->data; if (!win) break; #ifdef MULTIUSER @@ -347,7 +383,6 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) if (wdata->order == WLIST_NUM && ldata->selected->prev) { struct win *pw = ldata->selected->prev->data; - win = ldata->selected->data; if (win->w_group != pw->w_group) break; /* Do not allow switching with the parent group */ @@ -363,7 +398,6 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) if (wdata->order == WLIST_NUM && ldata->selected->next) { struct win *nw = ldata->selected->next->data; - win = ldata->selected->data; if (win->w_group != nw->w_group) break; /* Do not allow switching with the parent group */ @@ -372,6 +406,15 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) } break; + case 'K': /* Kill a window */ + { + char str[MAXSTR]; + snprintf(str, sizeof(str) - 1, "Really kill window %d (%s) [y/n]", + win->w_number, win->w_title); + Input(str, 1, INP_RAW, window_kill_confirm, (char *)win, 0); + } + break; + case 033: /* escape */ case 007: /* ^G */ if (wdata->group) @@ -430,7 +473,8 @@ void display_windows(int onblank, int order, struct win *group) { struct win *p; - struct wlistdata *wlistdata; + struct ListData *ldata; + struct gl_Window_Data *wdata; if (flayer->l_width < 10 || flayer->l_height < 6) { @@ -471,8 +515,6 @@ display_windows(int onblank, int order, struct win *group) if (!group && p) group = p->w_group; - struct ListData *ldata; - struct gl_Window_Data *wdata; ldata = glist_display(&gl_Window, ListID); if (!ldata) { -- cgit v1.2.1 From b6dd7d868756eccc06aa4b9ef6c2098d41ceaa86 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 24 Feb 2010 09:32:26 -0500 Subject: Print the group name in a group window. --- src/list_window.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/list_window.c b/src/list_window.c index f6f058a..e5695df 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -227,12 +227,20 @@ static int gl_Window_header(struct ListData *ldata) { char *str; + struct gl_Window_Data *wdata = ldata->data; + int g; + + if ((g = (wdata->group != NULL))) + { + LPutWinMsg(flayer, "Group: ", 7, &mchar_blank, 0, 0); + LPutWinMsg(flayer, wdata->group->w_title, strlen(wdata->group->w_title), &mchar_blank, 7, 0); + } display = 0; str = MakeWinMsgEv(wlisttit, (struct win *)0, '%', flayer->l_width, (struct event *)0, 0); - LPutWinMsg(flayer, str, strlen(str), &mchar_blank, 0, 0); - return 2; + LPutWinMsg(flayer, str, strlen(str), &mchar_blank, 0, g); + return 2 + g; } static int -- cgit v1.2.1 From 4f28ba8c8fd9032763eac42ed3591a6b2751f84c Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 26 Feb 2010 11:31:19 -0500 Subject: Some more fixes for the list management. Make sure the allocated memory is always freed. Also, do not reference freed memory. Thank you valgrind. --- src/display.c | 3 ++- src/help.c | 12 ++++++++---- src/input.c | 3 ++- src/layer.c | 6 +++++- src/layer.h | 3 +++ src/list_generic.c | 22 +++++++++++++++------- src/list_window.c | 3 ++- src/mark.c | 3 ++- src/window.c | 3 ++- 9 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/display.c b/src/display.c index 0707805..9f596c5 100644 --- a/src/display.c +++ b/src/display.c @@ -200,7 +200,8 @@ struct LayFuncs BlankLf = DefClearLine, DefRewrite, BlankResize, - DefRestore + DefRestore, + 0 }; /*ARGSUSED*/ diff --git a/src/help.c b/src/help.c index d818ea4..a624941 100644 --- a/src/help.c +++ b/src/help.c @@ -148,7 +148,8 @@ static struct LayFuncs HelpLf = DefClearLine, DefRewrite, DefResize, - DefRestore + DefRestore, + 0 }; @@ -504,7 +505,8 @@ static struct LayFuncs CopyrightLf = DefClearLine, DefRewrite, DefResize, - DefRestore + DefRestore, + 0 }; static const char cpmsg[] = "\ @@ -725,7 +727,8 @@ static struct LayFuncs BindkeyLf = DefClearLine, DefRewrite, DefResize, - DefRestore + DefRestore, + 0 }; @@ -922,7 +925,8 @@ static struct LayFuncs ZmodemLf = DefClearLine, DefRewrite, ZmodemResize, - DefRestore + DefRestore, + 0 }; /*ARGSUSED*/ diff --git a/src/input.c b/src/input.c index cbe7dc6..f0f9982 100644 --- a/src/input.c +++ b/src/input.c @@ -76,7 +76,8 @@ static struct LayFuncs InpLf = DefClearLine, DefRewrite, DefResize, - DefRestore + DefRestore, + 0 }; /* diff --git a/src/layer.c b/src/layer.c index c71c731..88d7360 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1121,7 +1121,11 @@ ExitOverlayPage() debug1("Exiting layer %#x\n", (unsigned int)flayer); oldlay = flayer; if (oldlay->l_data) - free(oldlay->l_data); + { + if (oldlay->l_layfn->lf_LayFree) + LayFree(oldlay->l_data); + free(oldlay->l_data); + } p = Layer2Window(flayer); diff --git a/src/layer.h b/src/layer.h index 7d5da0b..8c42d2b 100644 --- a/src/layer.h +++ b/src/layer.h @@ -46,6 +46,8 @@ struct LayFuncs int (*lf_LayRewrite) __P((int, int, int, struct mchar *, int)); int (*lf_LayResize) __P((int, int)); void (*lf_LayRestore) __P((void)); + void (*lf_LayFree) __P((void *)); /* Should only free any data kept in + flayer->l_data (but not flayer->l_data itself). */ }; struct layer @@ -90,6 +92,7 @@ struct layer #define LayRewrite (*flayer->l_layfn->lf_LayRewrite) #define LayResize (*flayer->l_layfn->lf_LayResize) #define LayRestore (*flayer->l_layfn->lf_LayRestore) +#define LayFree (*flayer->l_layfn->lf_LayFree) #define LaySetCursor() LGotoPos(flayer, flayer->l_x, flayer->l_y) #define LayCanResize(l) (l->l_layfn->LayResize != DefResize) diff --git a/src/list_generic.c b/src/list_generic.c index 24caf48..d2c1742 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -37,6 +37,7 @@ static void ListClearLine __P((int, int, int, int)); static int ListRewrite __P((int, int, int, struct mchar *, int)); static int ListResize __P((int, int)); static void ListRestore __P((void)); +static void ListFree __P((void *)); struct LayFuncs ListLf = { @@ -46,7 +47,8 @@ struct LayFuncs ListLf = ListClearLine, ListRewrite, ListResize, - ListRestore + ListRestore, + ListFree }; /** Returns non-zero on success. */ @@ -278,14 +280,18 @@ static void ListProcess(char **ppbuf, int *plen) static void ListAbort(void) { - struct ListData *ldata = flayer->l_data; + LAY_CALL_UP(LRefreshAll(flayer, 0)); + ExitOverlayPage(); +} + +static void ListFree(void *d) +{ + struct ListData *ldata = d; glist_remove_rows(ldata); if (ldata->list_fn->gl_free) ldata->list_fn->gl_free(ldata); if (ldata->search) Free(ldata->search); - LAY_CALL_UP(LRefreshAll(flayer, 0)); - ExitOverlayPage(); } static void ListRedisplayLine(int y, int xs, int xe, int isblank) @@ -360,10 +366,12 @@ void glist_remove_rows(struct ListData *ldata) { struct ListRow *row; - for (row = ldata->root; row; row = row->next) + for (row = ldata->root; row; ) { - ldata->list_fn->gl_freerow(ldata, row); - free(row); + struct ListRow *r = row; + row = row->next; + ldata->list_fn->gl_freerow(ldata, r); + free(r); } ldata->root = ldata->selected = ldata->top = NULL; } diff --git a/src/list_window.c b/src/list_window.c index e5695df..c6af77f 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -429,9 +429,10 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) break; /* Do nothing if it's a group window */ if (wdata->onblank) { + int fnumber = wdata->fore->w_number; glist_abort(); display = cd; - SwitchWindow(wdata->fore->w_number); + SwitchWindow(fnumber); *len = 0; break; } diff --git a/src/mark.c b/src/mark.c index c90201f..ccb74f9 100644 --- a/src/mark.c +++ b/src/mark.c @@ -77,7 +77,8 @@ struct LayFuncs MarkLf = DefClearLine, MarkRewrite, DefResize, - DefRestore + DefRestore, + 0 }; int join_with_cr = 0; diff --git a/src/window.c b/src/window.c index edf04dd..99e0bc7 100644 --- a/src/window.c +++ b/src/window.c @@ -212,7 +212,8 @@ struct LayFuncs WinLf = WinClearLine, WinRewrite, WinResize, - WinRestore + WinRestore, + 0 }; static int -- cgit v1.2.1 From 48624f98db28bd8c117cf1aebfc2cd326f6243bc Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 26 Feb 2010 12:09:31 -0500 Subject: Reduce a little code duplication. --- src/list_window.c | 107 ++++++++++++++++++++++-------------------------------- 1 file changed, 44 insertions(+), 63 deletions(-) diff --git a/src/list_window.c b/src/list_window.c index c6af77f..df83578 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -58,6 +58,29 @@ struct gl_Window_Data struct win *fore; /* The foreground window we had. */ }; +/* This macro should not be used if 'fn' is expected to update the window list */ +#define FOR_EACH_WINDOW(_wdata, _w, fn) do { \ + if ((_wdata)->order == WLIST_MRU) \ + { \ + struct win *_ww; \ + for (_ww = windows; _ww; _ww = _ww->w_next) \ + { \ + _w = _ww; \ + fn \ + } \ + } \ + else \ + { \ + struct win **_ww, *_witer; \ + for (_ww = wtab, _witer = windows; _witer && _ww - wtab < maxwin; _ww++) \ + { \ + if (!(_w = *_ww)) continue; \ + fn \ + _witer = _witer->w_next; \ + } \ + } \ + } while (0) + /* Is 'a' an ancestor of 'd'? */ static int window_ancestor(struct win *a, struct win *d) @@ -104,43 +127,23 @@ gl_Window_add_group(struct ListData *ldata, struct ListRow *row) { /* Right now, 'row' doesn't have any child. */ struct gl_Window_Data *wdata = ldata->data; - struct win *group = row->data; + struct win *group = row->data, *w; struct ListRow *cur = row; ASSERT(wdata->nested); - if (wdata->order == WLIST_MRU) - { - struct win *w; - for (w = windows; w; w = w->w_next) - { - if (w->w_group != group) - continue; + FOR_EACH_WINDOW(wdata, w, + if (w->w_group != group) + continue; - cur = glist_add_row(ldata, w, cur); - if (w == wdata->fore) - ldata->selected = cur; - - if (w->w_type == W_TYPE_GROUP) - cur = gl_Window_add_group(ldata, cur); - } - } - else if (wdata->order == WLIST_NUM) - { - struct win **w; - for (w = wtab; w - wtab < maxwin; w++) - { - if (!*w || (*w)->w_group != group) - continue; + cur = glist_add_row(ldata, w, cur); + if (w == wdata->fore) + ldata->selected = cur; - cur = glist_add_row(ldata, *w, cur); - if (*w == wdata->fore) - ldata->selected = cur; + if (w->w_type == W_TYPE_GROUP) + cur = gl_Window_add_group(ldata, cur); + ); - if ((*w)->w_type == W_TYPE_GROUP) - cur = gl_Window_add_group(ldata, cur); - } - } return cur; } @@ -149,39 +152,17 @@ gl_Window_rebuild(struct ListData *ldata) { struct ListRow *row = NULL; struct gl_Window_Data *wdata = ldata->data; - - if (wdata->order == WLIST_MRU) - { - struct win *w; - for (w = windows; w; w = w->w_next) - { - if (w->w_group == wdata->group) - { - row = glist_add_row(ldata, w, row); - if (w == wdata->fore) - ldata->selected = row; - if (w->w_type == W_TYPE_GROUP && wdata->nested) - row = gl_Window_add_group(ldata, row); - } - } - } - else - { - struct win **w; - struct win *wlist; - for (w = wtab, wlist = windows; wlist && w - wtab < maxwin; w++) - { - if (*w && (*w)->w_group == wdata->group) - { - row = glist_add_row(ldata, *w, row); - if (*w == wdata->fore) - ldata->selected = row; - wlist = wlist->w_next; - if ((*w)->w_type == W_TYPE_GROUP && wdata->nested) - row = gl_Window_add_group(ldata, row); - } - } - } + struct win *w; + + FOR_EACH_WINDOW(wdata, w, + if (w->w_group != wdata->group) + continue; + row = glist_add_row(ldata, w, row); + if (w == wdata->fore) + ldata->selected = row; + if (w->w_type == W_TYPE_GROUP && wdata->nested) + row = gl_Window_add_group(ldata, row); + ); glist_display_all(ldata); } -- cgit v1.2.1 From da8e87d6505fb33ed131144a33af88c6d0dc96fd Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 3 Mar 2010 11:18:55 -0500 Subject: Sanity check line numbers for non-negative value. It looks like 'ys' can be negative at times, which results in invalid memory reads, and possibly writes. Valgrind log from Friedrich Delgado Friedrichs in savannah bug #29050. --- src/layer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/layer.c b/src/layer.c index 88d7360..9c1fe34 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1285,6 +1285,8 @@ int ys, ye; { if (!layer->l_pause.d) return; + if (ys < 0) + ys = 0; if (ye >= layer->l_height) ye = layer->l_height - 1; if (xe >= layer->l_width) -- cgit v1.2.1 From b9253ef24e70f7a7bbfe320b1c3639da52d740f0 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 3 Mar 2010 11:55:39 -0500 Subject: Do not terminate when size is reduced too much. Height of a window can be negative, when both hardstatus and caption are turned on, and the terminal size is reduced to one-line height. So handle those cases more gracefully. Fixes savannah bug #29037. --- src/ansi.c | 2 +- src/resize.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ansi.c b/src/ansi.c index d15867b..f9e0cc8 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -322,7 +322,7 @@ register int len; curr->w_monitor = MON_FOUND; } - if (cols && rows) + if (cols > 0 && rows > 0) { do { diff --git a/src/resize.c b/src/resize.c index 553b0ed..39f6e28 100644 --- a/src/resize.c +++ b/src/resize.c @@ -628,8 +628,8 @@ int wi, he, hi; int ncx, ncy, naka, t; int y, shift; - if (wi == 0) - he = hi = 0; + if (wi <= 0 || he <= 0) + wi = he = hi = 0; if (p->w_type == W_TYPE_GROUP) return 0; -- cgit v1.2.1 From 30be3fc3a160a0a8c7c1d7190dbc0177f2d9e34f Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 4 Mar 2010 15:39:51 -0500 Subject: Use intelligent screen refresh only in split regions. When there are no splits, pausing output on a layer isn't necessary, since it doesn't hit the performance. But we do want to continue to pause output when there are splits to improve scrolling performance. Fixes savannah bug #29055. Thanks to Kazuo Teramoto for reporting the bug and testing the fix. --- src/layer.c | 100 ++++++++++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 56 deletions(-) diff --git a/src/layer.c b/src/layer.c index 9c1fe34..34cd6a3 100644 --- a/src/layer.c +++ b/src/layer.c @@ -86,6 +86,12 @@ int off; # define RECODE_MLINE(ml) (ml) #endif +#define FOR_EACH_UNPAUSED_CANVAS(l, fn) for (cv = (l)->l_cvlist; cv; cv = cv->c_lnext) \ + { \ + if ((l)->l_pause.d && cv->c_slorient) \ + continue; \ + fn \ + } void LGotoPos(l, x, y) @@ -97,16 +103,13 @@ int x, y; int x2, y2; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, x, y, y); - return; - } + LayPauseUpdateRegion(l, x, x, y, y); #ifdef HAVE_BRAILLE if (bd.bd_refreshing) return; #endif - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -134,6 +137,7 @@ int x, y; break; } } + ); } void @@ -150,11 +154,8 @@ struct mline *ol; if (n == 0) return; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, xs, xe, y, y); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, xs, xe, y, y); + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { y2 = y + vp->v_yoff; @@ -191,6 +192,7 @@ struct mline *ol; if (xs2 <= xe2) RefreshArea(xs2, y2, xe2, y2, 1); } + ); } void @@ -206,11 +208,8 @@ int bce; if (n == 0) return; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, 0, l->l_width - 1, ys, ye); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, 0, l->l_width - 1, ys, ye); + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { xs2 = vp->v_xoff; @@ -258,6 +257,7 @@ int bce; if (ys2 <= ye2) RefreshArea(xs2, ys2, xe2, ye2, 1); } + ); } void @@ -274,11 +274,8 @@ struct mline *ol; struct mline *rol; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, l->l_width - 1, y, y); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, x, l->l_width - 1, y, y); + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { y2 = y + vp->v_yoff; @@ -317,6 +314,7 @@ struct mline *ol; if (f) RefreshArea(xs2, y2, xs2, y2, 1); } + ); } void @@ -337,12 +335,9 @@ int x, y; #endif if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, x, y, y); - return; - } + LayPauseUpdateRegion(l, x, x, y, y); - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -359,6 +354,7 @@ int x, y; break; } } + ); } void @@ -384,12 +380,9 @@ int x, y; } #endif if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, x + n - 1, y, y); - return; - } + LayPauseUpdateRegion(l, x, x + n - 1, y, y); - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { y2 = y + vp->v_yoff; @@ -425,6 +418,7 @@ int x, y; while (xs2++ <= xe2) PUTCHARLP(*s2++); } + ); } void @@ -450,14 +444,11 @@ int x, y; } #endif if (l->l_pause.d) - { - LayPauseUpdateRegion(l, x, x + n - 1, y, y); - return; - } + LayPauseUpdateRegion(l, x, x + n - 1, y, y); len = strlen(s); if (len > n) len = n; - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { y2 = y + vp->v_yoff; @@ -489,6 +480,7 @@ int x, y; while (xs2++ <= xe2) PUTCHARLP(' '); } + ); } void @@ -507,11 +499,8 @@ struct mline *ol; if (xe >= l->l_width) xe = l->l_width - 1; if (l->l_pause.d) - { LayPauseUpdateRegion(l, xs, xe, y, y); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, for (vp = cv->c_vplist; vp; vp = vp->v_next) { xs2 = xs + vp->v_xoff; @@ -530,6 +519,7 @@ struct mline *ol; continue; ClearLine(ol ? mloff(RECODE_MLINE(ol), -vp->v_xoff) : (struct mline *)0, y2, xs2, xe2, bce); } + ); } void @@ -556,11 +546,8 @@ int uself; if (xe >= l->l_width) xe = l->l_width - 1; if (l->l_pause.d) - { - LayPauseUpdateRegion(l, xs, xe, ys, ye); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, xs, xe, ys, ye); + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -610,6 +597,7 @@ int uself; #endif } } + ); } void @@ -630,11 +618,8 @@ int isblank; } #endif if (l->l_pause.d) - { - LayPauseUpdateRegion(l, xs, xe, y, y); - return; - } - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + LayPauseUpdateRegion(l, xs, xe, y, y); + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -658,6 +643,7 @@ int isblank; DisplayLine(isblank ? &mline_blank : &mline_null, mloff(RECODE_MLINE(ml), -vp->v_xoff), y2, xs2, xe2); } } + ); } void @@ -711,11 +697,8 @@ int ins; int bce; if (l->l_pause.d) - { - /* XXX: 'y'? */ - LayPauseUpdateRegion(l, 0, l->l_width - 1, top, bot); - return; - } + /* XXX: 'y'? */ + LayPauseUpdateRegion(l, 0, l->l_width - 1, top, bot); #ifdef COLOR bce = rend_getbg(c); @@ -729,7 +712,7 @@ int ins; /* cursor after wrapping */ yy = y == l->l_height - 1 ? y : y + 1; - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, { y2 = 0; /* gcc -Wall */ display = cv->c_display; @@ -769,12 +752,13 @@ int ins; WrapChar(RECODE_MCHAR(c), vp->v_xoff + l->l_width, y2, vp->v_xoff, -1, vp->v_xoff + l->l_width - 1, -1, ins); } } + ); } else { /* hard case: scroll up*/ - for (cv = l->l_cvlist; cv; cv = cv->c_lnext) + FOR_EACH_UNPAUSED_CANVAS(l, { display = cv->c_display; if (D_blocked) @@ -822,6 +806,7 @@ int ins; WrapChar(RECODE_MCHAR(c), vp->v_xoff + l->l_width, bot2, vp->v_xoff, top2, vp->v_xoff + l->l_width - 1, bot2, ins); } } + ); } } @@ -1234,6 +1219,9 @@ int pause; { struct viewport *vp; + if (!cv->c_slorient) + continue; /* Wasn't split, so already updated. */ + display = cv->c_display; for (vp = cv->c_vplist; vp; vp = vp->v_next) -- cgit v1.2.1 From 824d21489434e94591d9565240ec21fa80173ba4 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 4 Mar 2010 18:09:17 -0500 Subject: Fix terminating an on-window list. --- src/list_window.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/list_window.c b/src/list_window.c index df83578..21ca837 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -300,7 +300,7 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) if (display && AclCheckPermWin(D_user, ACL_READ, win)) return; /* Not allowed to switch to this window. */ #endif - if (!wdata->group) + if (wdata->onblank || (!wdata->onblank && wdata->group)) { /* Do not abort the group window. */ glist_abort(); @@ -406,14 +406,13 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) case 033: /* escape */ case 007: /* ^G */ - if (wdata->group) - break; /* Do nothing if it's a group window */ - if (wdata->onblank) + if (wdata->onblank || (!wdata->onblank && wdata->group)) { int fnumber = wdata->fore->w_number; glist_abort(); display = cd; - SwitchWindow(fnumber); + if (wdata->onblank) + SwitchWindow(fnumber); *len = 0; break; } -- cgit v1.2.1 From 5a540e47c2eed7a84c09f2d4dcf93a808f3e005e Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 4 Mar 2010 18:10:05 -0500 Subject: Fix sending mouse event to a mouse-enabled layer. --- src/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index 9f596c5..36368aa 100644 --- a/src/display.c +++ b/src/display.c @@ -3430,7 +3430,7 @@ char *data; y = bp[4] - 33; if (x >= D_forecv->c_xs && x <= D_forecv->c_xe && y >= D_forecv->c_ys && y <= D_forecv->c_ye) { - if (D_fore && (D_fore->w_mouse || (D_mousetrack && D_forecv->c_layer->l_mode == 1))) + if ((D_fore && D_fore->w_mouse) || (D_mousetrack && D_forecv->c_layer->l_mode == 1)) { /* Send clicks only if the window is expecting clicks */ x -= D_forecv->c_xoff; -- cgit v1.2.1 From 02328ed6c832ce36dd3843c1bf2a99f007e7c2cb Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 4 Mar 2010 18:10:50 -0500 Subject: Handle mouse events in a generic list. Scroll wheels to scroll, left click to select. --- src/list_generic.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/src/list_generic.c b/src/list_generic.c index d2c1742..2b3be4c 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -149,21 +149,40 @@ static void ListProcess(char **ppbuf, int *plen) struct ListRow *old; unsigned char ch; - if (ldata->list_fn->gl_pinput && + if (!flayer->l_mouseevent.start && ldata->list_fn->gl_pinput && ldata->list_fn->gl_pinput(ldata, ppbuf, plen)) continue; + ch = **ppbuf; + ++*ppbuf; + --*plen; + + if (flayer->l_mouseevent.start) + { + int r = LayProcessMouse(flayer, ch); + if (r == -1) + { + LayProcessMouseSwitch(flayer, 0); + continue; + } + else + { + if (r) + ch = 0222; + else + continue; + } + } + if (!ldata->selected) { *plen = 0; break; } - ch = **ppbuf; - ++*ppbuf; - --*plen; - old = ldata->selected; + +processchar: switch (ch) { case ' ': @@ -255,6 +274,35 @@ static void ListProcess(char **ppbuf, int *plen) if (ldata->list_fn->gl_matchrow && ldata->search) ldata->selected = glist_search_dir(ldata, ldata->selected, -1); break; + + /* Now, mouse events. */ + case 0222: + if (flayer->l_mouseevent.start) + { + int button = flayer->l_mouseevent.buffer[0]; + if (button == 'a') /* Scroll down */ + ch = 'j'; + else if (button == '`') /* Scroll up */ + ch = 'k'; + else if (button == ' ') /* Left click */ + { + int y = flayer->l_mouseevent.buffer[2]; + struct ListRow *r = ldata->top; + for (r = ldata->top; r && r->y != -1 && r->y != y; r = r->next) + ; + if (r && r->y == y) + ldata->selected = r; + ch = 0; + } + else + ch = 0; + LayProcessMouseSwitch(flayer, 0); + if (ch) + goto processchar; + } + else + LayProcessMouseSwitch(flayer, 1); + break; } if (old == ldata->selected) /* The selection didn't change */ -- cgit v1.2.1 From 2e62d3683eefb23e6955b55c16ce3266b12aa401 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Thu, 4 Mar 2010 21:40:37 -0500 Subject: Some more fixes for the window list. Detecting when to destroy a window-list is rather complicated. --- src/list_window.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/list_window.c b/src/list_window.c index 21ca837..c46aa9e 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -58,6 +58,9 @@ struct gl_Window_Data struct win *fore; /* The foreground window we had. */ }; +/* Is this wdata for a group window? */ +#define WLIST_FOR_GROUP(wdate) ((wdata)->group && !(wdata)->onblank && Layer2Window(flayer) && Layer2Window(flayer)->w_type == W_TYPE_GROUP) + /* This macro should not be used if 'fn' is expected to update the window list */ #define FOR_EACH_WINDOW(_wdata, _w, fn) do { \ if ((_wdata)->order == WLIST_MRU) \ @@ -300,14 +303,16 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) if (display && AclCheckPermWin(D_user, ACL_READ, win)) return; /* Not allowed to switch to this window. */ #endif - if (wdata->onblank || (!wdata->onblank && wdata->group)) + if (WLIST_FOR_GROUP(wdata)) + SwitchWindow(win->w_number); + else { - /* Do not abort the group window. */ + /* Abort list only when not in a group window. */ glist_abort(); display = cd; + if (D_fore != win) + SwitchWindow(win->w_number); } - if (D_fore != win) - SwitchWindow(win->w_number); *len = 0; break; @@ -406,7 +411,7 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) case 033: /* escape */ case 007: /* ^G */ - if (wdata->onblank || (!wdata->onblank && wdata->group)) + if (!WLIST_FOR_GROUP(wdata)) { int fnumber = wdata->fore->w_number; glist_abort(); @@ -414,9 +419,8 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) if (wdata->onblank) SwitchWindow(fnumber); *len = 0; - break; } - /* else FALLTHROUGH */ + break; default: --*inp; ++*len; -- cgit v1.2.1 From 261a022ce947d17471b73a71345c265df9bfe7a4 Mon Sep 17 00:00:00 2001 From: Michael Scherer Date: Sun, 7 Mar 2010 19:29:39 -0500 Subject: Fix build with -Werror=format-security Some distributions ( mandriva for example ) use -Werror=format-security by default when build C software to try to enhance code quality and prevent security bugs. As the policy is to correct all occurences of the error ( so there is no false positive, nor question about to fix it or not ), a patch that fix the error on gnu screen 4.0.3 have been added to the package. I have rediffed it against latest git snapshot, to be sent upstream. It mainly add "%s" where applicable. --- src/attacher.c | 2 +- src/fileio.c | 8 ++++---- src/misc.c | 4 ++-- src/process.c | 16 ++++++++-------- src/resize.c | 6 +++--- src/screen.c | 6 +++--- src/socket.c | 2 +- src/termcap.c | 8 ++++---- src/window.c | 6 +++--- 9 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/attacher.c b/src/attacher.c index 88da744..370d594 100644 --- a/src/attacher.c +++ b/src/attacher.c @@ -756,7 +756,7 @@ LockTerminal() debug2("Lock: %s: return code %d\n", prg, WEXITSTATUS(wstat)); } else - printf(LockEnd); + printf("%s", LockEnd); } } else diff --git a/src/fileio.c b/src/fileio.c index b889df6..88fbf64 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -75,7 +75,7 @@ register char *str1, *str2; { len2 = strlen(str2); if ((cp = realloc(str2, (unsigned) len1 + len2 + add_colon + 1)) == NULL) - Panic(0, strnomem); + Panic(0, "%s", strnomem); bcopy(cp, cp + len1 + add_colon, len2 + 1); } else @@ -83,8 +83,8 @@ register char *str1, *str2; if (len1 == 0) return 0; if ((cp = malloc((unsigned) len1 + add_colon + 1)) == NULL) - Panic(0, strnomem); - cp[len1 + add_colon] = '\0'; + Panic(0, "%s", strnomem); + cp[len1 + add_colon] = '\0'; } bcopy(str1, cp, len1); if (add_colon) @@ -627,7 +627,7 @@ int *lenp; if ((buf = malloc(size)) == NULL) { close(i); - Msg(0, strnomem); + Msg(0, "%s", strnomem); return NULL; } errno = 0; diff --git a/src/misc.c b/src/misc.c index 7bc06f6..ff3bebb 100644 --- a/src/misc.c +++ b/src/misc.c @@ -57,7 +57,7 @@ register const char *str; register char *cp; if ((cp = malloc(strlen(str) + 1)) == NULL) - Panic(0, strnomem); + Panic(0, "%s", strnomem); else strcpy(cp, str); return cp; @@ -71,7 +71,7 @@ int n; register char *cp; if ((cp = malloc(n + 1)) == NULL) - Panic(0, strnomem); + Panic(0, "%s", strnomem); else { bcopy((char *)str, cp, n); diff --git a/src/process.c b/src/process.c index 137037d..d685501 100644 --- a/src/process.c +++ b/src/process.c @@ -691,7 +691,7 @@ int create; kp = malloc(sizeof(*kp)); if (kp == 0) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); return 0; } kp->name = SaveStr(class); @@ -2380,7 +2380,7 @@ int key; */ if ((dbuf = (char *)malloc(l)) == 0) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); break; } l = 0; @@ -2467,7 +2467,7 @@ int key; newbuf = malloc(l + 1); if (!newbuf) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); break; } user->u_plop.len = RecodeBuf((unsigned char *)oldplop.buf, oldplop.len, oldplop.enc, enc, (unsigned char *)newbuf); @@ -4501,9 +4501,9 @@ int *argl; return; } if ((pp = (char **)malloc((unsigned)(argc + 1) * sizeof(char **))) == 0) - Panic(0, strnomem); + Panic(0, "%s", strnomem); if ((lp = (int *)malloc((unsigned)(argc) * sizeof(int *))) == 0) - Panic(0, strnomem); + Panic(0, "%s", strnomem); act->nr = nr; act->args = pp; act->argl = lp; @@ -4525,7 +4525,7 @@ char **args; while (args[argc]) argc++; if ((pp = ap = (char **)malloc((unsigned)(argc + 1) * sizeof(char **))) == 0) - Panic(0, strnomem); + Panic(0, "%s", strnomem); while (argc--) *pp++ = SaveStr(*args++); *pp = 0; @@ -6074,7 +6074,7 @@ char *data; /* dummy */ { if ((pp->buf = (char *)malloc(D_user->u_plop.len)) == NULL) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); return; } bcopy(D_user->u_plop.buf, pp->buf, D_user->u_plop.len); @@ -6281,7 +6281,7 @@ char *data; #endif if (!(u->u_plop.buf = SaveStr(u->u_password))) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); D_user->u_plop.len = 0; } else diff --git a/src/resize.c b/src/resize.c index 39f6e28..10dfd8e 100644 --- a/src/resize.c +++ b/src/resize.c @@ -521,7 +521,7 @@ int wi; # endif #endif if (!(blank && null && mline_old.image && mline_old.attr IFFONT(&& mline_old.font) IFCOLOR(&& mline_old.color) IFCOLORX(&& mline_old.colorx))) - Panic(0, strnomem); + Panic(0, "%s", strnomem); MakeBlankLine(blank, maxwidth); bzero((char *)null, maxwidth); @@ -691,7 +691,7 @@ int wi, he, hi; if ((nmlines = (struct mline *)calloc(he, sizeof(struct mline))) == 0) { KillWindow(p); - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } } @@ -924,7 +924,7 @@ int wi, he, hi; #endif } KillWindow(p); - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } for (; t < wi; t++) diff --git a/src/screen.c b/src/screen.c index 06441dd..e26e4b8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2052,7 +2052,7 @@ MakeNewEnv() free((char *)NewEnv); NewEnv = np = (char **) malloc((unsigned) (op - environ + 7 + 1) * sizeof(char **)); if (!NewEnv) - Panic(0, strnomem); + Panic(0, "%s", strnomem); sprintf(stybuf, "STY=%s", strlen(SockName) <= MAXSTR - 5 ? SockName : "?"); *np++ = stybuf; /* NewEnv[0] */ *np++ = Term; /* NewEnv[1] */ @@ -2389,7 +2389,7 @@ char **cmdv; bt = (struct backtick *)malloc(sizeof *bt); if (!bt) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); return; } bzero(bt, sizeof(*bt)); @@ -2411,7 +2411,7 @@ char **cmdv; bt->buf = (char *)malloc(MAXSTR); if (bt->buf == 0) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); setbacktick(num, 0, 0, (char **)0); return; } diff --git a/src/socket.c b/src/socket.c index 9e61816..9dbf461 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1540,7 +1540,7 @@ struct msg *m; ASSERT(display); pwdata = (struct pwdata *)malloc(sizeof(struct pwdata)); if (!pwdata) - Panic(0, strnomem); + Panic(0, "%s", strnomem); pwdata->l = 0; pwdata->m = *m; D_processinputdata = (char *)pwdata; diff --git a/src/termcap.c b/src/termcap.c index 8f6b8b9..32ae63d 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -137,7 +137,7 @@ int he; if ((D_tentry = (char *)malloc(TERMCAP_BUFSIZE + (extra_incap ? strlen(extra_incap) + 1 : 0))) == 0) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } @@ -1198,7 +1198,7 @@ char *s; if ((D_xtable = (char ***)calloc(256, sizeof(char **))) == 0) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } @@ -1216,7 +1216,7 @@ char *s; { if ((D_xtable[curchar] = (char **)calloc(257, sizeof(char *))) == 0) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); FreeTransTable(); return -1; } @@ -1250,7 +1250,7 @@ char *s; l = l * templnsub + templlen; if ((ctable[c] = (char *)malloc(l + 1)) == 0) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); FreeTransTable(); return -1; } diff --git a/src/window.c b/src/window.c index 99e0bc7..a800d4a 100644 --- a/src/window.c +++ b/src/window.c @@ -613,7 +613,7 @@ struct NewWindow *newwin; if ((p = (struct win *)calloc(1, sizeof(struct win))) == 0) { close(f); - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } @@ -649,7 +649,7 @@ struct NewWindow *newwin; { free((char *)p); close(f); - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } #endif @@ -1530,7 +1530,7 @@ char **av; } if (!(pwin = (struct pseudowin *)calloc(1, sizeof(struct pseudowin)))) { - Msg(0, strnomem); + Msg(0, "%s", strnomem); return -1; } -- cgit v1.2.1 From 7851249fa3e5a9ce00ad3bf8bd0b417acb335f84 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 7 Mar 2010 19:36:36 -0500 Subject: Changelog. --- src/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ChangeLog b/src/ChangeLog index c02d5cc..44ba74c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -108,6 +108,7 @@ Version 4.1.0 (??/??/20??): * Ryan Niebur * Jan Christoph Nordholz * William Pursell + * Michael Scherer * Enrico Scholz * Peter Teichman -- cgit v1.2.1 From eb4cea75f23df90ac955e001fc5c3e54062d97cb Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 8 Mar 2010 10:01:26 -0500 Subject: Fix refresh when double-cell characters end a line Double cell characters that end a line are not properly displayed when there are split regions. Takeshi Banse detected the problem and a fix for it in Savannag bug #29106. A better fix for this was applied in the unicode++ branch, but that won't work in 'master'. This is approximately the same fix, in a slightly different way. --- src/ChangeLog | 1 + src/layer.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 44ba74c..0ac432a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -91,6 +91,7 @@ Version 4.1.0 (??/??/20??): * Dick * Gabriel * Benjamin Andresen + * Takeshi Banse * Maarten Billemont * Curtis Brown * Cyril Brulebois diff --git a/src/layer.c b/src/layer.c index 34cd6a3..b7cea6a 100644 --- a/src/layer.c +++ b/src/layer.c @@ -1197,6 +1197,7 @@ int pause; struct canvas *cv; struct display *olddisplay = display; int line; + struct win *win; pause = !!pause; @@ -1215,6 +1216,11 @@ int pause; layer->l_pause.bottom == -1) return; + if (layer->l_layfn == &WinLf) /* Currently, this will always be the case! */ + win = layer->l_data; + else + win = NULL; + for (cv = layer->l_cvlist; cv; cv = cv->c_lnext) { struct viewport *vp; @@ -1240,6 +1246,15 @@ int pause; if (xs < vp->v_xs) xs = vp->v_xs; if (xe > vp->v_xe) xe = vp->v_xe; +#if defined(DW_CHARS) && defined(UTF8) + if (layer->l_encoding == UTF8 && xe < vp->v_xe && win) + { + struct mline *ml = win->w_mlines + line; + if (dw_left(ml, xe, UTF8)) + xe++; + } +#endif + if (xs <= xe) RefreshLine(line + vp->v_yoff, xs, xe, 0); } -- cgit v1.2.1 From 25ff9f7a8bf4e7e90ed6e2c26d8e3a32fd5a9368 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 8 Mar 2010 14:29:40 -0500 Subject: Fix a hardstatus update issue. The initial change was to fix a bug in gnome-terminal (https://savannah.gnu.org/bugs/?23699), but that broke hardstatus update issues on bell (https://savannah.gnu.org/bugs/?24096). So apply a proper fix for #23699 without causing #24096. --- src/display.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/display.c b/src/display.c index 36368aa..5fc5f4b 100644 --- a/src/display.c +++ b/src/display.c @@ -2327,26 +2327,7 @@ int y, from, to, isblank; return; /* can't refresh status */ } - /* The following check makes plenty of sense. Unfortunately, - vte-based terminals (notably gnome-terminal) experience a quirk - that causes the final line not to update properly when it falls outside - the scroll region; clearing the line with D_CE avoids the glitch, - so we'll disable this perfectly sensible shortcut until such a time - as widespread vte installations lack the glitch. - - See http://bugzilla.gnome.org/show_bug.cgi?id=542087 for current - status of the VTE bug report, and - https://savannah.gnu.org/bugs/index.php?23699 for the history from - the Savannah BTS. */ -#if 0 - if (y == D_height - 1 && D_has_hstatus == HSTATUS_LASTLINE) - { - RefreshHStatus(); - return; - } -#endif - - if (isblank == 0 && D_CE && to == D_width - 1 && from < to) + if (isblank == 0 && D_CE && to == D_width - 1 && from < to && D_status != STATUS_ON_HS) { GotoPos(from, y); if (D_UT || D_BE) @@ -2354,6 +2335,13 @@ int y, from, to, isblank; AddCStr(D_CE); isblank = 1; } + + if (y == D_height - 1 && D_has_hstatus == HSTATUS_LASTLINE) + { + RefreshHStatus(); + return; + } + while (from <= to) { lcv = 0; -- cgit v1.2.1 From 26c3a1a371aaa55e2ee322d8c722e1f46bed5d38 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Mon, 8 Mar 2010 15:04:22 -0500 Subject: More fixes for -Werror=format-security. --- src/screen.c | 2 +- src/utmp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screen.c b/src/screen.c index e26e4b8..65c51bb 100644 --- a/src/screen.c +++ b/src/screen.c @@ -818,7 +818,7 @@ char **av; size_t newsz; char *newbuf = malloc(3 * len); if (!newbuf) - Panic(0, strnomem); + Panic(0, "%s", strnomem); newsz = RecodeBuf(nwin_options.aka, len, nwin_options.encoding, 0, newbuf); newbuf[newsz] = '\0'; diff --git a/src/utmp.c b/src/utmp.c index 20f3c3c..afa0948 100644 --- a/src/utmp.c +++ b/src/utmp.c @@ -268,7 +268,7 @@ InitUtmp() if ((utmpfd = open(UtmpName, O_RDWR)) == -1) { if (errno != EACCES) - Msg(errno, UtmpName); + Msg(errno, "%s", UtmpName); debug("InitUtmp failed.\n"); utmpok = 0; return; -- cgit v1.2.1 From 2d92e194efbb7973847640a4fb78b4be30603700 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 9 Mar 2010 16:34:06 -0500 Subject: Fix an invalid memory read. The window-list data gets freed when we abort the list. So read what we need to before aborting the list. --- src/list_window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/list_window.c b/src/list_window.c index c46aa9e..ee71fde 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -413,10 +413,10 @@ gl_Window_input(struct ListData *ldata, char **inp, int *len) case 007: /* ^G */ if (!WLIST_FOR_GROUP(wdata)) { - int fnumber = wdata->fore->w_number; + int fnumber = wdata->onblank ? wdata->fore->w_number : -1; glist_abort(); display = cd; - if (wdata->onblank) + if (fnumber >= 0) SwitchWindow(fnumber); *len = 0; } -- cgit v1.2.1 From 9d3938870c639fad97ea9b6cbb23b46cb049c801 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Tue, 9 Mar 2010 17:05:57 -0500 Subject: Fix compiling SIMPLESCREEN. --- src/screen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/screen.c b/src/screen.c index 65c51bb..2a905a8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2847,6 +2847,7 @@ int rec; break; case 'P': p--; +#ifdef COPY_PASTE if (display && ev && ev != &D_hstatusev) /* Hack */ { /* Is the layer in the current canvas in copy mode? */ @@ -2854,6 +2855,7 @@ int rec; if (ev == &cv->c_captev && cv->c_layer->l_layfn == &MarkLf) qmflag = 1; } +#endif break; case '>': truncpos = p - winmsg_buf; -- cgit v1.2.1 From cd874b642ce9f86d63583b6a2d012d5f445895da Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Wed, 10 Mar 2010 00:49:44 -0500 Subject: Make layer-resizing a bit more robust and readable Instead of killing all overlays when resizing, just kill the ones that cannot be resized, and the resized the rest. This fixes a bug where the window-list (or a group-window) is aborted when layer-size changes (because window-size changed, or caption/hardstatus etc. was toggled). This also makes the code robust. So if you are looking at a window/display list, and the window-size is changed, the list won't go away. --- src/list_generic.c | 27 +++++++++++++++----- src/resize.c | 73 ++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/src/list_generic.c b/src/list_generic.c index 2b3be4c..e32acf7 100644 --- a/src/list_generic.c +++ b/src/list_generic.c @@ -344,18 +344,33 @@ static void ListFree(void *d) static void ListRedisplayLine(int y, int xs, int xe, int isblank) { + struct ListData *ldata; ASSERT(flayer); + + ldata = flayer->l_data; if (y < 0) { - glist_display_all(flayer->l_data); + glist_display_all(ldata); return; } - if (y != 0 && y != flayer->l_height - 1) - return; - if (isblank) - return; - LClearArea(flayer, xs, y, xe, y, 0, 0); + if (!isblank) + LClearArea(flayer, xs, y, xe, y, 0, 0); + + if (ldata->top && y < ldata->top->y) + ldata->list_fn->gl_printheader(ldata); + else if (y + 1 == flayer->l_height) + ldata->list_fn->gl_printfooter(ldata); + else + { + struct ListRow *row; + for (row = ldata->top; row && row->y != -1; row = row->next) + if (row->y == y) + { + ldata->list_fn->gl_printrow(ldata, row); + break; + } + } } static void ListClearLine(int y, int xs, int xe, int bce) diff --git a/src/resize.c b/src/resize.c index 10dfd8e..7782c2b 100644 --- a/src/resize.c +++ b/src/resize.c @@ -323,6 +323,34 @@ kaablamm() Msg(0, "Aborted because of window size change."); } +/* Kills non-resizable layers. */ +#define RESIZE_OR_KILL_LAYERS(l, wi, he) do \ + { \ + struct layer *_last = NULL, *_iter; \ + flayer = (l); \ + while (flayer->l_next) \ + { \ + if (LayResize(wi, he) == 0) \ + { \ + _last = flayer; \ + flayer = flayer->l_next; \ + } \ + else \ + { \ + struct canvas *_cv; \ + for (_cv = flayer->l_cvlist; _cv; _cv = _cv->c_lnext) \ + _cv->c_display->d_kaablamm = 1; \ + ExitOverlayPage(); \ + if (_last) \ + _last->l_next = flayer; \ + } \ + } \ + /* We assume that the bottom-most layer, i.e. when flayer->l_next == 0, \ + * is always resizable. Currently, WinLf and BlankLf can be the bottom-most layers. \ + */ \ + LayResize(wi, he); \ + } while (0) + void ResizeLayer(l, wi, he, norefdisp) struct layer *l; @@ -338,52 +366,40 @@ struct display *norefdisp; return; p = Layer2Window(l); + /* If 'flayer' and 'l' are for the same window, then we will not + * restore 'flayer'. */ if (oldflayer && (l == oldflayer || Layer2Window(oldflayer) == p)) while (oldflayer->l_next) oldflayer = oldflayer->l_next; - + + flayer = l; + if (p) { + /* It's a window layer. Kill the overlays on it in all displays. */ for (d = displays; d; d = d->d_next) for (cv = d->d_cvlist; cv; cv = cv->c_next) { if (p == Layer2Window(cv->c_layer)) { - flayer = cv->c_layer; - if (flayer->l_next) - d->d_kaablamm = 1; - while (flayer->l_next) - ExitOverlayPage(); + /* Canvas 'cv' on display 'd' shows this window. Remove any non-resizable + * layers over it. */ + RESIZE_OR_KILL_LAYERS(cv->c_layer, wi, he); } } - l = p->w_savelayer; - } - flayer = l; - if (p == 0 && flayer->l_next && flayer->l_next->l_next == 0 && LayResize(wi, he) == 0) - { - flayer = flayer->l_next; - LayResize(wi, he); - flayer = l; } else { - if (flayer->l_next) - for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext) - cv->c_display->d_kaablamm = 1; - while (flayer->l_next) - ExitOverlayPage(); + /* It's a Blank layer. Just kill the non-resizable overlays over it. */ + RESIZE_OR_KILL_LAYERS(flayer, wi, he); } - if (p) - flayer = &p->w_layer; - LayResize(wi, he); - /* now everybody is on flayer, redisplay */ - l = flayer; + for (display = displays; display; display = display->d_next) { if (display == norefdisp) continue; for (cv = D_cvlist; cv; cv = cv->c_next) - if (cv->c_layer == l) + if (Layer2Window(cv->c_layer) == p) { CV_CALL(cv, LayRedisplayLine(-1, -1, -1, 0)); RefreshArea(cv->c_xs, cv->c_ys, cv->c_xe, cv->c_ye, 0); @@ -394,11 +410,14 @@ struct display *norefdisp; D_kaablamm = 0; } } - flayer = oldflayer; + + /* If we started resizing a non-flayer layer, then restore the flayer. + * Otherwise, flayer should already be updated to the topmost foreground layer. */ + if (Layer2Window(flayer) != Layer2Window(oldflayer)) + flayer = oldflayer; display = olddisplay; } - static void FreeMline(ml) struct mline *ml; -- cgit v1.2.1 From 08939ef8428d4cde3c76adef1ec8ef253c3f669c Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 12 Mar 2010 19:25:50 -0500 Subject: Fix an invalid memory read. Thanks a bunch to Friedrich Delgado Friedrichs for providing the valgrind logs. --- src/resize.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/resize.c b/src/resize.c index 7782c2b..5d1df4b 100644 --- a/src/resize.c +++ b/src/resize.c @@ -369,8 +369,7 @@ struct display *norefdisp; /* If 'flayer' and 'l' are for the same window, then we will not * restore 'flayer'. */ if (oldflayer && (l == oldflayer || Layer2Window(oldflayer) == p)) - while (oldflayer->l_next) - oldflayer = oldflayer->l_next; + oldflayer = NULL; flayer = l; @@ -413,7 +412,7 @@ struct display *norefdisp; /* If we started resizing a non-flayer layer, then restore the flayer. * Otherwise, flayer should already be updated to the topmost foreground layer. */ - if (Layer2Window(flayer) != Layer2Window(oldflayer)) + if (oldflayer) flayer = oldflayer; display = olddisplay; } -- cgit v1.2.1 From 6e67aee852c60c8b8a67981233ed29ca48ff8506 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Fri, 12 Mar 2010 19:27:09 -0500 Subject: Fix a typo. --- src/misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/misc.c b/src/misc.c index ff3bebb..43e93a2 100644 --- a/src/misc.c +++ b/src/misc.c @@ -609,7 +609,7 @@ char *value; * the string space, we can free our buf now. */ free(buf); -# else /* NEEDSETENV */ +# else /* NEEDPUTENV */ /* * For all sysv-ish systems that link a standard putenv() * the string-space buf is added to the environment and must not @@ -617,7 +617,7 @@ char *value; * We are sorry to say that memory is lost here, when setting * the same variable again and again. */ -# endif /* NEEDSETENV */ +# endif /* NEEDPUTENV */ #else /* USESETENV */ # if HAVE_SETENV_3 setenv(var, value, 1); -- cgit v1.2.1 From 8a6abbab0161e6df1cea2ae0033a4c7f4a47f8e9 Mon Sep 17 00:00:00 2001 From: Sadrul Habib Chowdhury Date: Sun, 14 Mar 2010 23:02:37 -0400 Subject: Add special rendition for silence'd windows. The default rendition for silence'd windows in caption/hardstatus or in the windowlist is =u (underline). Closes savannah bug #29205. --- src/ChangeLog | 2 +- src/ansi.c | 4 ++-- src/doc/screen.1 | 4 ++-- src/doc/screen.texinfo | 8 ++++---- src/image.h | 1 + src/list_window.c | 5 +++++ src/process.c | 6 ++++++ src/screen.c | 9 +++++++++ src/screen.h | 8 +++++--- src/window.c | 2 ++ src/window.h | 10 +++++----- 11 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 0ac432a..df04dca 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -3,7 +3,7 @@ Version 4.1.0 (??/??/20??): * 'unbindall' to unbind all commands * 'up', 'down', 'left', 'right' sub-commands for 'focus' * 'rendition' to specify rendition to use in caption/hardstatus for - window-names that have bell/monitor/so turned on. + window-names that have bell/monitor/silence/so turned on. * 'layout', with the following sub-commands - 'title' - 'number' diff --git a/src/ansi.c b/src/ansi.c index f9e0cc8..b75d14f 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -78,10 +78,10 @@ struct mchar mchar_null; struct mchar mchar_blank = {' ' /* , 0, 0, ... */}; struct mchar mchar_so = {' ', A_SO /* , 0, 0, ... */}; -int renditions[NUM_RENDS] = {65529 /* =ub */, 65531 /* =b */}; +int renditions[NUM_RENDS] = {65529 /* =ub */, 65531 /* =b */, 65533 /* =u */ }; /* keep string_t and string_t_string in sync! */ -static char *string_t_string[] = +static char *string_t_string[] = { "NONE", "DCS", /* Device control string */ diff --git a/src/doc/screen.1 b/src/doc/screen.1 index 83deb02..a250b92 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -2717,13 +2717,13 @@ Unlinks the screen-exchange file used by the commands \*Qwritebuf\*U and \*Qreadbuf\*U. .sp .ne 3 -.B "rendition bell" | monitor | so +.B "rendition bell" | monitor | silence | so .RB "\fIattr\fR " [ \fIcolor ] .PP Change the way .I screen renders the titles of windows that have monitor or bell flags set in caption or hardstatus or windowlist. See the \*QSTRING ESCAPES\*U chapter for the syntax of the modifiers. -The default for monitor is currently \*Q=b \*U (bold, active colors) and for bell \*Q=ub \*U (underline, bold and active colors). +The default for monitor is currently \*Q=b \*U (bold, active colors), for bell \*Q=ub \*U (underline, bold and active colors), and \*Q=u \*U for silence. .sp .ne 3 .B "reset" diff --git a/src/doc/screen.texinfo b/src/doc/screen.texinfo index d453b07..03dccdf 100644 --- a/src/doc/screen.texinfo +++ b/src/doc/screen.texinfo @@ -1142,7 +1142,7 @@ Store a string to a register. @xref{Registers}. Kill current region. @xref{Regions}. @item removebuf Delete the screen-exchange file. @xref{Screen Exchange}. -@item rendition bell | monitor | so @var{attr} [@var{color}] +@item rendition bell | monitor | silence | so @var{attr} [@var{color}] Change text attributes in caption for flagged windows. @xref{Rendition}. @item reset Reset the terminal settings for the window. @xref{Reset}. @@ -5069,15 +5069,15 @@ access to your terminal, they will be able to fire off print commands. @node Rendition, Sorendition, Printcmd, Miscellaneous @section Rendition -@deffn Command rendition bell | monitor | so @var{attr} [@var{color}] +@deffn Command rendition bell | monitor | silence | so @var{attr} [@var{color}] (none)@* Change the way screen renders the titles of windows that have monitor or bell flags set in caption or hardstatus or windowlist. See the chapter about string escapes (@pxref{String Escapes}) for the syntax of the modifiers. The default for monitor is currently @samp{=b} (bold, -active colors), and for bell is @samp{=ub} (underline, bold and -active colors). +active colors), for bell @samp{=ub} (underline, bold and active colors), and +for silence @samp{=u}. @end deffn @node Sorendition, Attrcolor, Rendition, Miscellaneous diff --git a/src/image.h b/src/image.h index 8622534..c105949 100644 --- a/src/image.h +++ b/src/image.h @@ -171,6 +171,7 @@ enum { REND_BELL = 0, REND_MONITOR, + REND_SILENCE, NUM_RENDS }; diff --git a/src/list_window.c b/src/list_window.c index ee71fde..b65600d 100644 --- a/src/list_window.c +++ b/src/list_window.c @@ -266,6 +266,11 @@ gl_Window_row(struct ListData *ldata, struct ListRow *lrow) mchar = &mchar_rend; ApplyAttrColor(renditions[REND_BELL], mchar); } + else if ((w->w_silence == SILENCE_FOUND || w->w_silence == SILENCE_DONE) && renditions[REND_SILENCE] != -1) + { + mchar = &mchar_rend; + ApplyAttrColor(renditions[REND_SILENCE], mchar); + } else mchar = &mchar_blank; diff --git a/src/process.c b/src/process.c index d685501..cb90802 100644 --- a/src/process.c +++ b/src/process.c @@ -3894,6 +3894,10 @@ int key; { i = REND_MONITOR; } + else if (strcmp(args[0], "silence") == 0) + { + i = REND_SILENCE; + } else if (strcmp(args[0], "so") != 0) { Msg(0, "Invalid option '%s' for rendition", args[0]); @@ -5357,6 +5361,8 @@ int where; rend = renditions[REND_MONITOR]; else if ((p->w_bell == BELL_DONE || p->w_bell == BELL_FOUND) && renditions[REND_BELL] != -1) rend = renditions[REND_BELL]; + else if ((p->w_silence == SILENCE_FOUND || p->w_silence == SILENCE_DONE) && renditions[REND_SILENCE] != -1) + rend = renditions[REND_SILENCE]; } if (rend != -1) AddWinMsgRend(s, rend); diff --git a/src/screen.c b/src/screen.c index 2a905a8..5c15a39 100644 --- a/src/screen.c +++ b/src/screen.c @@ -3241,6 +3241,15 @@ char *data; } WindowChanged(p, 'f'); } + if (p->w_silence == SILENCE_FOUND) + { + /* Unset the flag if the user switched to this window. */ + if (p->w_layer.l_cvlist) + { + p->w_silence = SILENCE_ON; + WindowChanged(p, 'f'); + } + } } for (display = displays; display; display = display->d_next) diff --git a/src/screen.h b/src/screen.h index a24c021..5c93f32 100644 --- a/src/screen.h +++ b/src/screen.h @@ -256,7 +256,7 @@ struct msg #define VBELLWAIT 1 /* No. of seconds a vbell will be displayed */ #define BELL_ON 0 /* No bell has occurred in the window */ -#define BELL_FOUND 1 /* A bell has occurred, but user not yet notified */ +#define BELL_FOUND 1 /* A bell has occurred, but user not yet notified */ #define BELL_DONE 2 /* A bell has occured, user has been notified */ #define BELL_VISUAL 3 /* A bell has occured in fore win, notify him visually */ @@ -271,8 +271,10 @@ struct msg #define DUMP_EXCHANGE 2 #define DUMP_SCROLLBACK 3 -#define SILENCE_OFF 0 -#define SILENCE_ON 1 +#define SILENCE_OFF 0 /* Not checking for silence */ +#define SILENCE_ON 1 /* Window being monitored for silence */ +#define SILENCE_FOUND 2 /* Window is silent */ +#define SILENCE_DONE 3 /* Window is silent and user is notified */ extern char strnomem[]; diff --git a/src/window.c b/src/window.c index a800d4a..1716796 100644 --- a/src/window.c +++ b/src/window.c @@ -2069,6 +2069,8 @@ char *data; continue; #endif Msg(0, "Window %d: silence for %d seconds", p->w_number, p->w_silencewait); + p->w_silence = SILENCE_FOUND; + WindowChanged(p, 'f'); } } diff --git a/src/window.h b/src/window.h index 6bd8e2d..47f5c9e 100644 --- a/src/window.h +++ b/src/window.h @@ -133,7 +133,7 @@ struct paster struct paster; #endif -struct win +struct win { struct win *w_next; /* next window */ int w_type; /* type of window */ @@ -187,7 +187,7 @@ struct win int w_CharsetR; /* charset number GR */ int w_charsets[4]; /* Font = charsets[Charset] */ #endif - int w_ss; + int w_ss; int w_saved; int w_Saved_x, w_Saved_y; struct mchar w_SavedRend; @@ -227,7 +227,7 @@ struct win int w_monitor; /* monitor status */ int w_silencewait; /* wait for silencewait secs */ int w_silence; /* silence status (Lloyd Zusman) */ - char w_vbwait; + char w_vbwait; char w_norefresh; /* dont redisplay when switching to that win */ #ifdef RXVT_OSC char w_xtermosc[4][MAXSTR]; /* special xterm/rxvt escapes */ @@ -246,8 +246,8 @@ struct win #else int w_histheight; /* always 0 */ #endif - int w_pid; /* process at the other end of ptyfd */ - int w_deadpid; /* saved w_pid of a process that closed the ptyfd to us */ + int w_pid; /* process at the other end of ptyfd */ + int w_deadpid; /* saved w_pid of a process that closed the ptyfd to us */ char *w_cmdargs[MAXARGS]; /* command line argument vector */ char *w_dir; /* directory for chdir */ -- cgit v1.2.1