summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-02-12 16:42:21 -0500
committerSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2010-02-12 16:42:21 -0500
commit8d3c168f49d1974180a01e09953702a78993179d (patch)
treedcc108a44f43bc2fff924c46acaedc6069a1e3e9
parent8147d08647d59aba7accb748c42db2aba3f31bc4 (diff)
parent9756ae6fb21fb6421e543173115059d36358c692 (diff)
downloadscreen-8d3c168f49d1974180a01e09953702a78993179d.tar.gz
Merge branch 'master' into query-result
-rw-r--r--src/ChangeLog102
-rw-r--r--src/Makefile.in80
-rw-r--r--src/acconfig.h8
-rw-r--r--src/acls.c5
-rw-r--r--src/ansi.c8
-rw-r--r--src/ansi.h2
-rw-r--r--src/attacher.c2
-rw-r--r--src/braille.c2
-rw-r--r--src/braille.h2
-rw-r--r--src/canvas.c915
-rw-r--r--src/canvas.h101
-rw-r--r--src/comm.c9
-rw-r--r--src/comm.sh4
-rw-r--r--src/configure.in2
-rw-r--r--src/display.c1241
-rw-r--r--src/display.h89
-rw-r--r--src/doc/screen.144
-rw-r--r--src/doc/screen.texinfo524
-rw-r--r--src/extern.h23
-rw-r--r--src/help.c285
-rw-r--r--src/image.h2
-rw-r--r--src/input.c9
-rw-r--r--src/layer.c209
-rw-r--r--src/layer.h54
-rw-r--r--src/layout.c367
-rw-r--r--src/layout.h57
-rw-r--r--src/list_display.c288
-rw-r--r--src/logfile.h2
-rw-r--r--src/mark.c80
-rw-r--r--src/mark.h2
-rw-r--r--src/misc.c38
-rw-r--r--src/os.h7
-rw-r--r--src/osdef.h.in2
-rw-r--r--src/patchlevel.h4
-rw-r--r--src/process.c475
-rw-r--r--src/resize.c61
-rw-r--r--src/sched.h2
-rw-r--r--src/screen.c45
-rw-r--r--src/screen.h3
-rw-r--r--src/socket.c23
-rw-r--r--src/term.c6
-rw-r--r--src/termcap.c5
-rw-r--r--src/viewport.c140
-rw-r--r--src/viewport.h51
-rw-r--r--src/window.c32
-rw-r--r--src/window.h15
46 files changed, 3498 insertions, 1929 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2256d80..5052b35 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,105 @@
+Version 4.1.0 (??/??/20??):
+ New Commands:
+ * '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.
+ * 'layout', with the following sub-commands
+ - 'title'
+ - 'number'
+ - 'autosave' ('autosave on' or 'autosave off')
+ - 'new'
+ - 'save' ('save <name>')
+ - 'select'
+ - 'next'
+ - 'prev'
+ - '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
+ 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.
+
+ 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.
+ * 'blankerprg' shows the currently set command on no argument.
+
+ .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.
+ * '%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').
+ * 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.)
+ * 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)
+
+ Developers:
+ * Juergen Weigert <jw@suse.de>
+ * Michael Schroeder <mls@suse.de>
+ * Micah Cowan <micah@cowan.name>
+ * Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>
+
+ Contributors:
+ * Clavelito <maromomo@hotmail.com>
+ * Dick <dick@mrns.nl>
+ * Gabriel <g2p.code@gmail.com>
+ * Benjamin Andresen <bandresen@gmail.com>
+ * Maarten Billemont <lhunath@gmail.com>
+ * Curtis Brown <mrbrown8@juno.com>
+ * Cyril Brulebois <kibi@debian.org>
+ * Trent W Buck <trentbuck@gmail.com>
+ * Stephane Chazelas <stephane_chazelas@yahoo.fr>
+ * Kees Cook <kees@ubuntu.com>
+ * Thomas Dickey <tom@invisible-island.net>
+ * Christian Ebert <blacktrash@gmx.net>
+ * Geraint Edwards <gedge-lists-screen@yadn.org>
+ * Romain Francoise <romain@orebokech.com>
+ * Emanuele Giaquinta <e.giaquinta@glauco.it>
+ * Yi-Hsuan Hsin <mhsin@mhsin.org>
+ * Steve Kemp <steve@steve.org.uk>
+ * Ryan Niebur <ryan@debian.org>
+ * Jan Christoph Nordholz <hesso@pool.math.tu-berlin.de>
+ * William Pursell <bill.pursell@gmail.com>
+ * Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+ * Peter Teichman <peter@teichman.org>
+
30.10.94
This is a quick overview of screen's life story. But it is not up
diff --git a/src/Makefile.in b/src/Makefile.in
index c551067..8120726 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -61,12 +61,13 @@ 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 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 \
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 layout.o viewport.o
all: screen
@@ -273,66 +274,75 @@ depend.in: $(CFILES) term.h
###############################################################################
### Dependencies:
-screen.o: 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: 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: 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: 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: 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: 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: 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: 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: 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: term.c term.h
-window.o: 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: 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: 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: putenv.c config.h
-help.o: 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 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
-termcap.o: termcap.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
-input.o: 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: 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: 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: 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: 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
-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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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/acconfig.h b/src/acconfig.h
index bc324d5..ffedbbc 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
*/
@@ -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..e728bb8 100644
--- a/src/acls.c
+++ b/src/acls.c
@@ -26,10 +26,9 @@
****************************************************************
*/
-#include <sys/types.h>
-
#include "config.h"
+#include <sys/types.h>
/* XXX: WHY IS THIS HERE?? :XXX */
@@ -56,7 +55,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/ansi.c b/src/ansi.c
index a6fc161..d15867b 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)
@@ -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;
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/attacher.c b/src/attacher.c
index 46c14ec..f8c3217 100644
--- a/src/attacher.c
+++ b/src/attacher.c
@@ -26,12 +26,12 @@
****************************************************************
*/
+#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <signal.h>
-#include "config.h"
#include "screen.h"
#include "extern.h"
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);
}
}
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.c b/src/canvas.c
new file mode 100644
index 0000000..4cc4fe2
--- /dev/null
+++ b/src/canvas.c
@@ -0,0 +1,915 @@
+/* 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;
+ LayerCleanupMemory(&pcv->c_blank);
+ 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);
+ LayerCleanupMemory(&cv->c_blank);
+ 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);
+ LayerCleanupMemory(&cv->c_blank);
+ 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;
+ }
+}
+
+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
new file mode 100644
index 0000000..6aeb3d8
--- /dev/null
+++ b/src/canvas.h
@@ -0,0 +1,101 @@
+/* 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$ GNU
+ */
+
+#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));
+extern void PutWindowCv __P((struct canvas *));
+
+#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/comm.c b/src/comm.c
index 934ad23..f7730cc 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
@@ -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 },
@@ -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
@@ -231,9 +232,10 @@ 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 },
{ "msgminwait", ARGS_1 },
{ "msgwait", ARGS_1 },
#ifdef MULTIUSER
@@ -312,6 +314,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/comm.sh b/src/comm.sh
index 190de58..4fc8cb2 100644
--- a/src/comm.sh
+++ b/src/comm.sh
@@ -63,6 +63,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/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.c b/src/display.c
index e5954ec..0707805 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));
@@ -123,6 +121,7 @@ struct display TheDisplay;
*/
int defobuflimit = OBUF_MAX;
int defnonblock = -1;
+int defmousetrack = 0;
#ifdef AUTO_NUKE
int defautonuke = 0;
#endif
@@ -314,6 +313,7 @@ struct mode *Mode;
D_termname[sizeof(D_termname) - 1] = 0;
D_user = *u;
D_processinput = ProcessInput;
+ D_mousetrack = defmousetrack;
return display;
}
@@ -412,738 +412,17 @@ 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
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()
-{
- 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.
@@ -1205,6 +484,8 @@ FinitTerm()
KeypadMode(0);
CursorkeysMode(0);
CursorVisibility(0);
+ if (D_mousetrack)
+ D_mousetrack = 0;
MouseMode(0);
SetRendition(&mchar_null);
SetFlow(FLOW_NOW);
@@ -1336,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
@@ -1522,7 +811,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)
@@ -2822,6 +2117,69 @@ 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_iscomb(v))
+ {
+ 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)
@@ -2866,7 +2224,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(' ');
@@ -3013,7 +2371,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(' ');
@@ -3505,12 +2863,19 @@ 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[] = "1;\000\00020;\00039;\00049;\000";
+ static char *oscs[][2] = {
+ { WT_FLAG ";", "screen" }, /* set window title */
+ { "20;", "" }, /* background */
+ { "39;", "black" }, /* default foreground (black?) */
+ { "49;", "white" } /* default background (white?) */
+ };
ASSERT(display);
if (!D_CXT)
@@ -3519,17 +2884,13 @@ 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 */
+ 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 * 4);
+ AddStr(oscs[i][0]);
AddStr(s);
AddChar(7);
}
@@ -3540,7 +2901,10 @@ ClearAllXtermOSC()
int i;
for (i = 3; i >= 0; i--)
SetXtermOSC(i, 0);
+ if (D_xtermosc[0])
+ AddStr("\033[23;" WT_FLAG "t"); /* unstack titles (xterm patch #251) */
}
+#undef WT_FLAG
#endif
/*
@@ -3641,9 +3005,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;
@@ -4065,15 +3429,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 || (D_mousetrack && D_forecv->c_layer->l_mode == 1)))
{
- bp[3] = x + 33;
- bp[4] = y + 33;
- i -= 4;
- bp += 4;
- continue;
+ /* 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)
+ {
+ SetForeCanvas(display, cv);
+ /* XXX: Do we want to reset the input buffer? */
}
}
if (bp[0] == '[')
@@ -4170,29 +3548,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)
@@ -4426,338 +3781,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);
- }
-}
-
-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;
- }
-}
+#endif /* BLANKER_PRG */
-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;
-
- 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 aaaf6bf..e8b3b80 100644
--- a/src/display.h
+++ b/src/display.h
@@ -24,9 +24,16 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
****************************************************************
- * $Id$ FAU
+ * $Id$ GNU
*/
+#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,63 +58,6 @@ struct kmap_ext
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;
- 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 */
@@ -150,6 +100,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 +227,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)
@@ -359,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
@@ -385,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/doc/screen.1 b/src/doc/screen.1
index 05b4294..3ac5571 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 ,
@@ -231,7 +233,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 +332,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.
@@ -1088,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
@@ -2227,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
@@ -2285,7 +2293,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
@@ -2572,9 +2581,9 @@ title (a.\|k.\|a.) option (\fB\-t\fP), login options (\fB-l\fP and \fB-ln\fP)
and scrollback option (\fB-h\fP <num>) 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
@@ -2620,7 +2629,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.
@@ -2632,8 +2641,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
@@ -2921,6 +2931,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.
@@ -3324,6 +3342,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 3285aeb..44d233e 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
@@ -175,6 +178,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
@@ -344,12 +350,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
@@ -400,6 +413,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
@@ -919,6 +936,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}
@@ -941,8 +960,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
@@ -965,8 +984,12 @@ 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}]
+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}
@@ -995,6 +1018,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
@@ -1011,7 +1056,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}.
@@ -1021,6 +1066,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 +1128,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}.
@@ -1133,6 +1180,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}]]
@@ -1149,7 +1198,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}.
@@ -1174,9 +1223,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.
@@ -1185,6 +1234,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
@@ -1209,7 +1259,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
@@ -1218,11 +1268,13 @@ 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
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}.
@@ -1298,7 +1350,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
@@ -1398,6 +1450,37 @@ 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]
+(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
+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
@@ -1449,7 +1532,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
@@ -1469,19 +1552,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
@@ -1563,7 +1649,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
@@ -1768,7 +1854,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
@@ -1809,6 +1897,8 @@ 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
@node Split, Focus, , Regions
@@ -1900,7 +1990,7 @@ You can mix both forms by providing the string as an additional
argument.
@end deffn
-@node Fit, , Caption, Regions
+@node Fit, Focusminsize, Caption, Regions
@section Fit
@kindex F
@deffn Command fit
@@ -1910,6 +2000,136 @@ command is needed because screen doesn't adapt the window size
automatically if the window is displayed more than once.
@end deffn
+@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
+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
@@ -2211,7 +2431,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
@@ -2242,6 +2462,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
@@ -2494,7 +2733,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
@@ -2505,7 +2744,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
@@ -2527,7 +2949,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
@@ -2551,7 +2973,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
@@ -2611,7 +3033,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
@@ -2869,7 +3291,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.
@@ -2878,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
@@ -2887,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 @kbd{C-a i}
+@var{num} lines. The default scrollback is 100 lines. Use @code{info}
to view the current setting.
@end deffn
@@ -3370,11 +3793,19 @@ 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
+@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
@@ -3559,10 +3990,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
@@ -3671,7 +4102,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}.
@@ -4114,7 +4545,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
@@ -4358,6 +4789,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
@@ -4468,7 +4900,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
@@ -4546,7 +4979,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
@@ -4628,7 +5061,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.
@@ -4651,7 +5084,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.
@@ -4671,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
@@ -4727,8 +5161,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
@@ -4737,7 +5173,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
@@ -4779,7 +5215,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
@@ -4794,6 +5230,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
@@ -5293,7 +5731,5 @@ from the key sequences, since it is the same for all bindings.
@printindex ky
-@shortcontents
-@contents
@bye
diff --git a/src/extern.h b/src/extern.h
index 9e26883..045aa24 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
@@ -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 *));
@@ -297,17 +297,6 @@ extern void Resize_obuf __P((void));
#ifdef AUTO_NUKE
extern void NukePending __P((void));
#endif
-extern void SetCanvasWindow __P((struct canvas *, struct win *));
-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 *));
@@ -321,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));
@@ -365,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 ac7209f..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
@@ -74,13 +75,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 <pid>.sockname instead of <pid>.<tty>.<host>.\n");
@@ -90,7 +91,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 */
@@ -680,183 +681,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"
/*
**
@@ -867,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));
@@ -888,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,
@@ -922,6 +748,16 @@ int wi, he;
}
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;
@@ -942,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++)
@@ -981,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 */
@@ -1003,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 || 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;
@@ -1013,19 +849,25 @@ 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 */
+ break;
case 0033:
case 0007:
h = wlistdata->start;
@@ -1039,7 +881,7 @@ int *plen;
}
break;
}
- HelpAbort();
+ WListAbort();
display = olddisplay;
if (h >= 0 && wtab[h])
SwitchWindow(h);
@@ -1083,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])
@@ -1114,6 +956,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)
@@ -1131,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];
}
@@ -1165,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;
@@ -1176,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;
}
}
@@ -1195,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;
@@ -1264,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)
@@ -1279,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;
}
@@ -1358,6 +1202,8 @@ 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;
wlistdata->start = onblank && p ? p->w_number : -1;
@@ -1387,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;
@@ -1484,15 +1330,6 @@ WListLinkChanged()
display = olddisplay;
}
-int
-InWList()
-{
- if (flayer && flayer->l_layfn == &WListLf)
- return 1;
- return 0;
-}
-
-
/*
**
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/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..c71c731 100644
--- a/src/layer.c
+++ b/src/layer.c
@@ -96,6 +96,12 @@ int x, y;
struct viewport *vp;
int x2, y2;
+ if (l->l_pause.d)
+ {
+ LayPauseUpdateRegion(l, x, x, y, y);
+ return;
+ }
+
#ifdef HAVE_BRAILLE
if (bd.bd_refreshing)
return;
@@ -143,6 +149,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 +205,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 +273,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 +335,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 +383,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 +449,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 +506,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 +555,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 +629,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 +710,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
@@ -1111,7 +1172,155 @@ ExitOverlayPage()
ocv->c_lnext = cv;
}
oldlay->l_cvlist = 0;
+ LayerCleanupMemory(oldlay);
free((char *)oldlay);
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;
+ }
+}
+
+void LayPause(layer, pause)
+struct layer *layer;
+int pause;
+{
+ struct canvas *cv;
+ struct display *olddisplay = display;
+ int line;
+
+ 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 = -1;
+ return;
+ }
+
+ /* Unpause. So refresh the regions in the displays! */
+ if (layer->l_pause.top == -1 &&
+ layer->l_pause.bottom == -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)
+ {
+ 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)
+ {
+ 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);
+ }
+ }
+
+ 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;
+}
+
+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.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 572c9e6..7d5da0b 100644
--- a/src/layer.h
+++ b/src/layer.h
@@ -24,9 +24,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
****************************************************************
- * $Id$ FAU
+ * $Id$ GNU
*/
+#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.
@@ -54,11 +57,30 @@ 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;
+
+ struct {
+ int d : 1; /* Is the output for the layer blocked? */
+
+ /* After unpausing, what region should we refresh? */
+ int *left, *right;
+ int top, bottom;
+ int lines;
+ } l_pause;
};
#define LayProcess (*flayer->l_layfn->lf_LayProcess)
@@ -108,3 +130,31 @@ struct layer
display = olddisplay; \
} while(0)
+#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));
+
+/**
+ * Free any internal memory for the layer.
+ *
+ * @param layer The layer.
+ */
+void LayerCleanupMemory __P((struct layer *layer));
+
diff --git a/src/layout.c b/src/layout.c
new file mode 100644
index 0000000..6100b5d
--- /dev/null
+++ b/src/layout.c
@@ -0,0 +1,367 @@
+/* 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);
+ }
+}
+
+
+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/layout.h b/src/layout.h
new file mode 100644
index 0000000..065edb7
--- /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$ GNU
+ */
+
+#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/list_display.c b/src/list_display.c
new file mode 100644
index 0000000..3693f01
--- /dev/null
+++ b/src/list_display.c
@@ -0,0 +1,288 @@
+/* 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);
+ if (d == ddata->selected)
+ flayer->l_y = 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(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/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.c b/src/mark.c
index ff8e583..c90201f 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;
@@ -560,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)
{
@@ -609,19 +613,20 @@ int *inlenp;
}
}
- switch (od)
+processchar:
+ switch (od)
{
case 'f': /* fall through */
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;
@@ -1030,6 +1035,7 @@ int *inlenp;
LAY_CALL_UP(LRefreshAll(flayer, 0));
}
ExitOverlayPage();
+ WindowChanged(fore, 'P');
if (append_mode)
LMsg(0, "Appended %d characters to buffer",
newcopylen);
@@ -1040,6 +1046,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");
@@ -1116,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;
}
@@ -1212,6 +1253,8 @@ int tx, ty, line;
#endif
}
}
+ flayer->l_x = tx;
+ flayer->l_y = W2D(ty);
LGotoPos(flayer, tx, W2D(ty));
}
@@ -1239,6 +1282,7 @@ MarkAbort()
rem(markdata->x1, markdata->y1, markdata->cx, markdata->cy, redisp, (char *)0, yend);
}
ExitOverlayPage();
+ WindowChanged(fore, 'P');
}
@@ -1445,14 +1489,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/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/misc.c b/src/misc.c
index c56d87a..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);
}
@@ -651,39 +652,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...
- */
-
-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..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 <stdio.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
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/process.c b/src/process.c
index 1737dcf..923565a 100644
--- a/src/process.c
+++ b/src/process.c
@@ -26,6 +26,8 @@
****************************************************************
*/
+#include "config.h"
+
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
@@ -39,8 +41,6 @@
#endif
-#include "config.h"
-
/* for solaris 2.1, Unixware (SVR4.2) and possibly others: */
#ifdef HAVE_STROPTS_H
# include <sys/stropts.h>
@@ -49,6 +49,8 @@
#include "screen.h"
#include "extern.h"
#include "logfile.h"
+#include "layout.h"
+#include "viewport.h"
extern struct comm comms[];
extern char *rc_name;
@@ -75,6 +77,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;
@@ -162,7 +165,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;
@@ -184,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;
@@ -584,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;
@@ -693,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;
@@ -989,7 +992,7 @@ struct paster *pa;
int
FindCommnr(str)
-char *str;
+const char *str;
{
int x, m, l = 0, r = RC_LAST;
while (l <= r)
@@ -1410,6 +1413,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))
@@ -1452,12 +1464,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--;
@@ -1474,14 +1488,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)
{
@@ -1540,7 +1562,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)
@@ -1579,7 +1601,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);
@@ -2232,6 +2254,7 @@ int key;
break;
}
MarkRoutine();
+ WindowChanged(fore, 'P');
break;
case RC_HISTORY:
{
@@ -2731,6 +2754,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;
@@ -3945,63 +3984,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;
@@ -4054,14 +4067,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"))
@@ -4098,6 +4122,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;
@@ -4378,6 +4417,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;
@@ -4411,10 +4459,23 @@ char **argv;
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(*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;
@@ -4608,6 +4669,10 @@ int bufl, *argl;
sprintf(xbuf, "%d", display ? D_width : -1);
else if (!strcmp(ps, "LINES"))
sprintf(xbuf, "%d", display ? D_height : -1);
+ else if (!strcmp(ps, "PID"))
+ sprintf(xbuf, "%d", getpid());
+ else if (!strcmp(ps, "STY"))
+ v = SockName;
else
v = getenv(ps);
}
@@ -4879,7 +4944,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;
@@ -4984,7 +5049,7 @@ int n;
struct win *p;
debug1("SwitchWindow %d\n", n);
- if (n < 0 || n >= MAXWIN)
+ if (n < 0 || n >= maxwin)
{
ShowWindows(-1);
return;
@@ -5015,118 +5080,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.
@@ -5200,12 +5153,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)
{
@@ -5228,7 +5181,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)
@@ -5255,36 +5208,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;
@@ -5398,7 +5321,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)
@@ -6035,7 +5958,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;
@@ -6227,6 +6150,7 @@ char *data;
act.nr = *(int *)data;
act.args = noargs;
act.argl = 0;
+ act.quiet = 0;
DoAction(&act, -1);
}
@@ -6487,7 +6411,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)
@@ -6789,56 +6713,6 @@ 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;
@@ -7021,6 +6895,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()
diff --git a/src/resize.c b/src/resize.c
index 9c7b70f..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");
@@ -1026,16 +1047,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 +1068,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/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.c b/src/screen.c
index d09359a..ce081ac 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
@@ -236,7 +238,7 @@ int cjkwidth;
#ifdef NETHACK
int nethackflag = 0;
#endif
-int maxwin = MAXWIN;
+int maxwin;
struct layer *flayer;
@@ -464,10 +466,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
@@ -763,7 +765,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.
@@ -1081,7 +1083,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 :
@@ -1478,6 +1480,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)
{
@@ -1730,7 +1740,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;
}
@@ -2190,7 +2209,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;
@@ -2809,6 +2828,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;
diff --git a/src/screen.h b/src/screen.h
index a5145e7..fa4cc82 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"
@@ -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"
diff --git a/src/socket.c b/src/socket.c
index 965a7d0..08b545f 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();
@@ -181,8 +182,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);
@@ -723,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;
@@ -1407,6 +1421,7 @@ struct msg *m;
char *na = 0;
newscreen.nr = RC_SCREEN;
newscreen.args = &na;
+ newscreen.quiet = 0;
DoAction(&newscreen, -1);
}
else
diff --git a/src/term.c b/src/term.c
index 8cf2729..991de1b 100644
--- a/src/term.c
+++ b/src/term.c
@@ -178,6 +178,10 @@ struct term term[T_N] =
/* 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")
@@ -236,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~")
diff --git a/src/termcap.c b/src/termcap.c
index 2b63a24..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 */
@@ -226,7 +224,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)
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..a19b6b8
--- /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$ GNU
+ */
+
+#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 */
+
diff --git a/src/window.c b/src/window.c
index fb271d2..1826b33 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[];
@@ -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 *));
@@ -103,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 */
@@ -280,8 +282,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;
@@ -553,6 +554,13 @@ struct NewWindow *newwin;
extern struct acluser *users;
#endif
+ if (!wtab)
+ {
+ if (!maxwin)
+ maxwin = MAXWIN;
+ 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");
@@ -840,6 +848,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);
@@ -1019,6 +1030,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);
@@ -1026,6 +1038,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
@@ -1906,7 +1919,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;
}
@@ -2049,6 +2066,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 6c6ca76..cd6c7da 100644
--- a/src/window.h
+++ b/src/window.h
@@ -24,9 +24,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
****************************************************************
- * $Id$ FAU
+ * $Id$ GNU
*/
+#ifndef SCREEN_WINDOW_H
+#define SCREEN_WINDOW_H
/* keep this in sync with the initialisations in window.c */
struct NewWindow
@@ -280,6 +282,14 @@ struct win
struct mline *w_alt_hlines;
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
};
@@ -323,3 +333,6 @@ struct win
: &fore->w_mlines[y - fore->w_histheight])
#define Layer2Window(l) ((struct win *)(l)->l_bottom->l_data)
+
+#endif /* SCREEN_WINDOW_H */
+