1 Commits
0.9 ... 0.8

Author SHA1 Message Date
no_author
c23359e5d7 This commit was manufactured by cvs2svn to create tag 'TMUX_0_8'. 2009-04-21 20:10:23 +00:00
126 changed files with 3192 additions and 3840 deletions

120
CHANGES
View File

@@ -1,121 +1,3 @@
CHANGES FROM 0.8 TO 0.9, 01 July 2009
* Major changes to build infrastructure: cleanup of makefiles and addition
of a configure script.
* monitor-content window option to monitor a window for a specific fnmatch(3)
pattern. The find-window command also now accepts fnmatch(3) patterns.
* previous-layout and select-layout commands, and a main-horizontal layout.
* Recreate the server socket on SIGUSR1.
* clear-history command.
* Use ACS line drawing characters for pane separator lines.
* UTF-8 improvements, and code to detect UTF-8 support by looking at
environment variables.
* The resize-pane-up and resize-pane-down commands are now merged together
into a new resize-pane command with -U and -D flags.
* confirm-before command to request a yes/no answer before executing dangerous
commands.
* Status line bug fixes, support for UTF-8 (status-utf8 option), and a key to
paste from the paste buffer.
* Support for some additional escape sequences and terminal features, including
better support for insert mode and tab stops.
* Improved window resizing behaviour, modelled after xterm.
* Some code reduction and a number of miscellaneous bug fixes.
================================================================================
On 01 June 2009, tmux was imported into the OpenBSD base system. From this date
onward changes are logged as part of the normal CVS commit message to either
OpenBSD or SourceForge CVS. This file will be updated to contain a summary of
major changes with each release, and to mention important configuration or
command syntax changes during development.
The list of older changes is below.
================================================================================
21 May 2009
* stat(2) files before trying to load them to avoid problems, for example
with "source-file /dev/zero".
19 May 2009
* Try to guess if the window is UTF-8 by outputting a three-byte UTF-8 wide
character and seeing how much the cursor moves. Currently tries to figure out
if this works by some stupid checks on the terminal, these need to be
rethought. Also might be better using a width 1 character rather than width 2.
* If LANG contains "UTF-8", assume the terminal supports UTF-8, on the grounds
that anyone who configures it probably wants UTF-8. Not certain if this is
a perfect idea but let's see if it causes any problems.
* New window option: monitor-content. Searches for a string in a window and if
it matches, highlight the status line.
18 May 2009
* main-horizontal layout and main-pane-height option to match vertical.
* New window option main-pane-width to set the width of the large left pane with
main-vertical (was left-vertical) layout.
* Lots of layout cleanup. manual layout is now manual-vertical.
16 May 2009
* select-layout command and a few default key bindings (M-0, M-1, M-2, M-9) to
select layouts.
* Recreate server socket on SIGUSR1, per SF feature request 2792533.
14 May 2009
* Keys in status line (p in vi mode, M-y in emacs) to paste the first line
of the upper paste buffer. Suggested by Dan Colish.
* clear-history command to clear a pane's history.
* Don't force wrapping with \n when asked, let the cursor code figure it out.
Should fix terminals which use this to detect line breaks.
* Major cleanup and restructuring of build infrastructure. Still separate files
for GNU and BSD make, but they are now hugely simplified at the expense of
adding a configure script which must be run before make. Now build and
install with:
$ ./configure && make && sudo make install
04 May 2009
* Use ACS line drawing characters for pane separator lines.
30 April 2009
* Support command sequences without a space before the semicolon, for example
"neww; neww" now works as well as "neww ; neww". "neww;neww" is still an
error.
* previous-layout command.
* Display the layout name in window lists.
* Merge resize-pane-up and resize-pane-down into resize-pane with -U and -D
flags.
29 April 2009
* Get rid of compat/vis.* - only one function was used which is easily
replaced,and less compat code == good.
27 April 2009
* Avoid using the prompt history when the server is locked, and prevent any
input entered from being added to the client's prompt history.
* New command, confirm-before (alias confirm), which asks for confirmation
before executing a command. Bound "&" and "x" by default to confirm-before
"kill-window" and confirm-before "kill-pane", respectively.
23 April 2009
* Support NEL, yet another way of making newline. Fixes the output from some
Gentoo packaging thing. Reported by someone on SF then logs that allowed a
fix sent by tcunha.
* Use the xenl terminfo flag to detect early-wrap terminals like the FreeBSD
console. Many thanks for a very informative email from Christian Weisgerber.
21 April 2009
* tmux 0.8 released.
17 April 2009 17 April 2009
* Remove the right number of characters from the buffer when escape then * Remove the right number of characters from the buffer when escape then
@@ -1322,7 +1204,7 @@ The list of older changes is below.
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.299 2009-07-01 22:15:16 nicm Exp $ $Id: CHANGES,v 1.272 2009-04-17 12:36:21 nicm Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms

16
FAQ
View File

@@ -87,10 +87,9 @@ for each tmux window or globally by setting the "utf8" flag:
setw -g utf8 on setw -g utf8 on
As of release 0.9, tmux attempts to autodetect a UTF-8-capable terminal by And, as it is not possible to automatically detect that a terminal is UTF-8
checking the LC_ALL, LC_CTYPE and LANG environment variables. list-clients may capable, tmux must be told by passing the -u flag when creating or
be used to check if this is detected correctly; if not, the -u command-line attaching a client to a tmux session:
flag may be specified when creating or attaching a client to a tmux session:
$ tmux -u new $ tmux -u new
@@ -187,11 +186,4 @@ Automatic window renaming may use a lot of CPU, particularly on slow computers:
if this is a problem, turn it off with "setw -g automatic-rename off". If this if this is a problem, turn it off with "setw -g automatic-rename off". If this
doesn't fix it, please report the problem. doesn't fix it, please report the problem.
* How do I prevent tmux from resizing my PuTTY window? $Id: FAQ,v 1.21 2009-03-31 23:17:28 nicm Exp $
This isn't tmux's fault, but happens because the initialisation strings for the
terminal in use (set through TERM) request it. PuTTY can be told to ignore such
requests: in the configuration window under Terminal -> Features, check the
"Disable remote-controlled terminal resizing" box.
$Id: FAQ,v 1.23 2009-07-01 19:49:56 nicm Exp $

View File

@@ -1,57 +1,144 @@
# $Id: GNUmakefile,v 1.107 2009-07-01 22:10:06 nicm Exp $ # $Id: GNUmakefile,v 1.82 2009-04-21 20:10:22 nicm Exp $
.PHONY: clean .PHONY: clean
VERSION= 0.9 PROG= tmux
VERSION= 0.8
DATE= $(shell date +%Y%m%d-%H%M)
#FDEBUG= 1 #FDEBUG= 1
META?= \002
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c input.c input-keys.c \
screen.c screen-write.c screen-redraw.c \
grid.c grid-view.c \
window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
key-string.c key-bindings.c resize.c arg.c mode-key.c \
layout.c cmd.c cmd-generic.c cmd-string.c cmd-list.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
cmd-list-windows.c cmd-attach-session.c cmd-send-prefix.c \
cmd-refresh-client.c cmd-kill-window.c cmd-list-clients.c \
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \
cmd-kill-server.c cmd-set-window-option.c cmd-show-options.c \
cmd-show-window-options.c cmd-command-prompt.c cmd-set-buffer.c \
cmd-show-buffer.c cmd-list-buffers.c cmd-delete-buffer.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
cmd-save-buffer.c cmd-select-pane.c cmd-split-window.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
cmd-suspend-client.c cmd-find-window.c cmd-load-buffer.c \
cmd-copy-buffer.c cmd-break-pane.c cmd-swap-pane.c cmd-next-layout.c \
cmd-rotate-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c util.c names.c \
osdep-unknown.c osdep-openbsd.c osdep-freebsd.c osdep-linux.c \
osdep-darwin.c attributes.c
CC?= gcc CC?= gcc
CFLAGS+= -DBUILD="\"$(VERSION)\"" INCDIRS+= -I. -I-
LDFLAGS+= -L/usr/local/lib CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\"" -DMETA="'${META}'"
LIBS+= -lncurses
# This sort of sucks but gets rid of the stupid warning and should work on
# most platforms...
ifeq ($(shell (LC_ALL=C $(CC) -v 2>&1|awk '/gcc version 4/') || true), )
CPPFLAGS:= -I. -I- $(CPPFLAGS)
else
CPPFLAGS:= -iquote. $(CPPFLAGS)
endif
ifdef FDEBUG ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG CFLAGS+= -g -ggdb -DDEBUG
LDFLAGS+= -rdynamic
LIBS+= -ldl
endif
ifeq (${CC},gcc)
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
endif endif
LDFLAGS+=
LIBS+= -lncurses
PREFIX?= /usr/local PREFIX?= /usr/local
INSTALLDIR= install -d INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555 INSTALLBIN= install -g bin -o root -m 555
INSTALLMAN= install -g bin -o root -m 444 INSTALLMAN= install -g bin -o root -m 444
SRCS= $(shell echo *.c|sed 's|osdep-[a-z0-9]*.c||g') ifeq ($(shell uname),AIX)
include config.mk INCDIRS+= -I/usr/local/include/ncurses -Icompat
SRCS+= compat/vis.c compat/strlcpy.c compat/strlcat.c compat/strtonum.c \
compat/fgetln.c compat/asprintf.c compat/daemon.c compat/forkpty-aix.c \
compat/getopt_long.c compat/bsd-poll.c
CFLAGS+= -DNO_TREE_H -DNO_ASPRINTF -DNO_QUEUE_H -DNO_VSYSLOG \
-DNO_PROGNAME -DNO_STRLCPY -DNO_STRLCAT -DNO_STRTONUM \
-DNO_SETPROCTITLE -DNO_QUEUE_H -DNO_TREE_H -DNO_FORKPTY -DNO_FGETLN \
-DBROKEN_GETOPT -DBROKEN_POLL -DNO_PATHS_H
LDFLAGS+= -L/usr/local/lib
endif
ifeq ($(shell uname),IRIX64)
INCDIRS+= -Icompat -I/usr/local/include/ncurses
SRCS+= compat/strlcpy.c compat/strtonum.c compat/daemon.c \
compat/asprintf.c compat/fgetln.c compat/forkpty-irix.c
CFLAGS+= -DNO_STRLCPY -DNO_STRTONUM -DNO_TREE_H -DNO_SETPROCTITLE \
-DNO_DAEMON -DNO_FORKPTY -DNO_PROGNAME -DNO_ASPRINTF -DNO_FGETLN \
-DBROKEN_VSNPRINTF -D_SGI_SOURCE -std=c99
LDFLAGS+= -L/usr/local/lib
LIBS+= -lgen
endif
ifeq ($(shell uname),SunOS)
INCDIRS+= -Icompat -I/usr/local/include/ncurses
SRCS+= compat/strtonum.c compat/daemon.c compat/forkpty-sunos.c \
compat/asprintf.c compat/fgetln.c compat/vis.c
CFLAGS+= -DNO_STRTONUM -DNO_TREE_H -DNO_PATHS_H -DNO_SETPROCTITLE \
-DNO_DAEMON -DNO_FORKPTY -DNO_PROGNAME -DNO_ASPRINTF -DNO_FGETLN
LDFLAGS+= -L/usr/local/lib
LIBS+= -lsocket -lnsl
endif
ifeq ($(shell uname),Darwin)
INCDIRS+= -Icompat
SRCS+= compat/strtonum.c compat/bsd-poll.c compat/vis.c
CFLAGS+= -DNO_STRTONUM -DNO_SETRESUID -DNO_SETRESGID -DNO_SETPROCTITLE \
-DNO_QUEUE_H -DNO_TREE_H -DBROKEN_POLL
endif
ifeq ($(shell uname),Linux)
INCDIRS+= -Icompat
SRCS+= compat/strlcpy.c compat/strlcat.c compat/strtonum.c \
compat/fgetln.c compat/getopt_long.c compat/vis.c
CFLAGS+= $(shell getconf LFS_CFLAGS) -D_GNU_SOURCE \
-DNO_STRLCPY -DNO_STRLCAT -DNO_STRTONUM -DNO_SETPROCTITLE \
-DNO_QUEUE_H -DNO_TREE_H -DUSE_PTY_H -DNO_FGETLN \
-DBROKEN_GETOPT -std=c99
LIBS+= -lcrypt -lutil
endif
OBJS= $(patsubst %.c,%.o,$(SRCS)) OBJS= $(patsubst %.c,%.o,$(SRCS))
all: tmux CLEANFILES= ${PROG} *.o .depend *~ ${PROG}.core *.log compat/*.o index.html
tmux: $(OBJS) CPPFLAGS:= ${INCDIRS} ${CPPFLAGS}
$(CC) $(LDFLAGS) -o tmux $+ $(LIBS)
depend: $(SRCS) all: $(PROG)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
$(PROG): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $+ $(LIBS)
depend: $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
install:
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/bin
$(INSTALLBIN) $(PROG) $(DESTDIR)$(PREFIX)/bin/$(PROG)
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1
$(INSTALLMAN) $(PROG).1 $(DESTDIR)$(PREFIX)/man/man1/$(PROG).1
clean: clean:
rm -f tmux *.o .depend *~ *.core *.log compat/*.o rm -f $(CLEANFILES)
clean-all: clean
rm -f config.h config.mk
install: all
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/bin
$(INSTALLBIN) tmux $(DESTDIR)$(PREFIX)/bin/tmux
$(INSTALLDIR) $(DESTDIR)$(PREFIX)/man/man1
$(INSTALLMAN) tmux.1 $(DESTDIR)$(PREFIX)/man/man1/tmux.1

156
Makefile
View File

@@ -1,62 +1,158 @@
# $Id: Makefile,v 1.142 2009-07-01 22:10:06 nicm Exp $ # $Id: Makefile,v 1.121 2009-04-21 20:10:22 nicm Exp $
.SUFFIXES: .c .o .SUFFIXES: .c .o .y .h
.PHONY: clean .PHONY: clean update-index.html upload-index.html
VERSION= 0.9 PROG= tmux
VERSION= 0.8
OS!= uname
REL!= uname -r
DATE!= date +%Y%m%d-%H%M
#FDEBUG= 1 #FDEBUG= 1
CC?= cc META?= \002 # C-b
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+= -lncurses
# This sort of sucks but gets rid of the stupid warning and should work on SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
# most platforms... xmalloc.c xmalloc-debug.c input.c input-keys.c \
CCV!= (LC_ALL=C ${CC} -v 2>&1|awk '/gcc version 4/') || true screen.c screen-write.c screen-redraw.c \
.if empty(CCV) grid.c grid-view.c \
CPPFLAGS:= -I. -I- -I/usr/local/include ${CPPFLAGS} window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
.else layout.c key-string.c key-bindings.c resize.c arg.c mode-key.c \
CPPFLAGS:= -iquote. -I/usr/local/include ${CPPFLAGS} cmd.c cmd-generic.c cmd-string.c cmd-list.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
cmd-list-windows.c cmd-attach-session.c cmd-send-prefix.c \
cmd-refresh-client.c cmd-kill-window.c cmd-list-clients.c \
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
cmd-paste-buffer.c cmd-new-session.c cmd-start-server.c \
cmd-kill-server.c cmd-set-window-option.c cmd-show-options.c \
cmd-show-window-options.c cmd-command-prompt.c cmd-set-buffer.c \
cmd-show-buffer.c cmd-list-buffers.c cmd-delete-buffer.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
cmd-save-buffer.c cmd-select-pane.c cmd-split-window.c \
cmd-resize-pane-up.c cmd-resize-pane-down.c cmd-kill-pane.c \
cmd-up-pane.c cmd-down-pane.c cmd-choose-window.c cmd-choose-session.c \
cmd-suspend-client.c cmd-find-window.c cmd-load-buffer.c \
cmd-copy-buffer.c cmd-break-pane.c cmd-swap-pane.c cmd-next-layout.c \
cmd-rotate-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
window-choose.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c util.c names.c attributes.c \
osdep-unknown.c osdep-openbsd.c osdep-freebsd.c osdep-linux.c \
osdep-darwin.c osdep-netbsd.c
CC?= c
INCDIRS+= -I. -I- -I/usr/local/include
CFLAGS+= -DMETA="'${META}'"
.ifdef PROFILE
# Don't use ccache
CC= /usr/bin/gcc
CFLAGS+= -pg -DPROFILE -O0
.endif .endif
.ifdef FDEBUG .ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG CFLAGS+= -g -ggdb -DDEBUG
LDFLAGS+= -Wl,-E
CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\""
.else
CFLAGS+= -DBUILD="\"$(VERSION)\""
.endif
#CFLAGS+= -pedantic -std=c99
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
.endif
PREFIX?= /usr/local PREFIX?= /usr/local
INSTALLDIR= install -d INSTALLDIR= install -d
INSTALLBIN= install -g bin -o root -m 555 INSTALLBIN= install -g bin -o root -m 555
INSTALLMAN= install -g bin -o root -m 444 INSTALLMAN= install -g bin -o root -m 444
SRCS!= echo *.c|sed 's|osdep-[a-z0-9]*.c||g' LDFLAGS+= -L/usr/local/lib
.include "config.mk" .ifdef PROFILE
OBJS= ${SRCS:S/.c/.o/} LDFLAGS+= -pg
.endif
LIBS+= -lutil -lncurses
# FreeBSD and DragonFly
.if ${OS} == "FreeBSD" || ${OS} == "DragonFly"
INCDIRS+= -Icompat
SRCS+= compat/vis.c
CFLAGS+= -DUSE_LIBUTIL_H -DNO_QUEUE_H -DNO_TREE_H
LIBS+= -lcrypt
.endif
# NetBSD
.if ${OS} == "NetBSD"
INCDIRS= -Icompat
SRCS+= compat/strtonum.c compat/vis.c
LIBS+= -lcrypt
CFLAGS+=-DNO_STRTONUM
.endif
OBJS= ${SRCS:S/.c/.o/:S/.y/.o/}
DISTDIR= ${PROG}-${VERSION}
DISTFILES= *.[chyl] Makefile GNUmakefile *.[1-9] NOTES TODO CHANGES FAQ \
`find examples compat -type f -and ! -path '*CVS*'`
CLEANFILES= ${PROG} *.o .depend *~ ${PROG}.core *.log compat/*.o index.html
CPPFLAGS:= ${INCDIRS} ${CPPFLAGS}
.c.o: .c.o:
${CC} ${CPPFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} ${CC} ${CPPFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
all: tmux .y.o:
${YACC} ${.IMPSRC}
${CC} ${CPPFLAGS} ${CFLAGS} -c y.tab.c -o ${.TARGET}
tmux: ${OBJS} all: ${PROG}
${CC} ${LDFLAGS} -o tmux ${OBJS} ${LIBS}
${PROG}: ${OBJS}
${CC} ${LDFLAGS} -o ${PROG} ${OBJS} ${LIBS}
depend: depend:
mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c} mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c}
clean: dist: clean
rm -f tmux *.o .depend *~ *.core *.log compat/*.o grep '^#FDEBUG=' Makefile
grep '^#FDEBUG=' GNUmakefile
[ "`(grep '^VERSION' Makefile; grep '^VERSION' GNUmakefile)| \
uniq -u`" = "" ]
tar -zc \
-s '/.*/${DISTDIR}\/\0/' \
-f ${DISTDIR}.tar.gz ${DISTFILES}
clean-all: clean lint:
rm -f config.h config.mk lint -chvx ${CFLAGS:M-D*} ${SRCS:M*.c}
clean:
rm -f ${CLEANFILES}
upload-index.html: update-index.html
scp index.html images/*.png \
nicm,tmux@web.sf.net:/home/groups/t/tm/tmux/htdocs
rm -f images/small-*
update-index.html:
(cd images && \
rm -f small-* && \
for i in *.png; do \
convert "$$i" -resize 200x150 "small-$$i"; \
done \
)
sed "s/%%VERSION%%/${VERSION}/g" index.html.in >index.html
install: all install: all
${INSTALLDIR} ${DESTDIR}${PREFIX}/bin ${INSTALLDIR} ${DESTDIR}${PREFIX}/bin
${INSTALLBIN} tmux ${DESTDIR}${PREFIX}/bin/ ${INSTALLBIN} ${PROG} ${DESTDIR}${PREFIX}/bin/
${INSTALLDIR} ${DESTDIR}${PREFIX}/man/man1 ${INSTALLDIR} ${DESTDIR}${PREFIX}/man/man1
${INSTALLMAN} tmux.1 ${DESTDIR}${PREFIX}/man/man1/ ${INSTALLMAN} ${PROG}.1 ${DESTDIR}${PREFIX}/man/man1/

25
NOTES
View File

@@ -4,10 +4,9 @@ tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen. simple, modern, BSD-licensed alternative to programs such as GNU screen.
This 0.9 release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still This 0.8 release runs on OpenBSD, FreeBSD, Linux and OS X and may still run on
run on Solaris and AIX (although they hasn't been tested in a while). It is Solaris (although it hasn't been tested in a while). It is usable, although
usable, although there remain a number of missing features and some remaining there remain a number of missing features and some remaining bugs are expected.
bugs are expected.
If upgrading from 0.5, PLEASE NOTE the following configuration file changes: it If upgrading from 0.5, PLEASE NOTE the following configuration file changes: it
is now required to pass the -g flag to set-option or set-window-option to set is now required to pass the -g flag to set-option or set-window-option to set
@@ -43,6 +42,7 @@ The following is a summary of major features implemented in this version:
And major missing features: And major missing features:
- Proper mouse support.
- No support for programs changing termios(4) settings or other tty(4) ioctls. - No support for programs changing termios(4) settings or other tty(4) ioctls.
A more extensive, but rough, todo list is included in the TODO file. A more extensive, but rough, todo list is included in the TODO file.
@@ -55,10 +55,8 @@ xterm-color or rxvt for colour.
tmux supports UTF-8. To use it, the utf8 option must be set on each window; tmux supports UTF-8. To use it, the utf8 option must be set on each window;
this may be turned on for all windows by setting it as a global option, see this may be turned on for all windows by setting it as a global option, see
tmux(1) and the FAQ file. As of 0.9, tmux attempts to autodetect a tmux(1) and the FAQ file. In addition, when starting tmux or attaching to an
UTF-8-capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment existing session from a UTF-8-capable terminal, the -u flag must be specified.
variables. list-clients may be used to check if this is detected correctly; if
not, the -u command-line flag may be specified.
A Vim syntax file is available in the examples directory. To install it: A Vim syntax file is available in the examples directory. To install it:
@@ -76,6 +74,15 @@ A Vim syntax file is available in the examples directory. To install it:
For debugging, running tmux with -v or -vv will generate server and client log For debugging, running tmux with -v or -vv will generate server and client log
files in the current directory. files in the current directory.
The CVS HEAD version of tmux often has additional features from the release
versions; if interested, testing it is encouraged. It can be obtained by
anonymous CVS from SourceForge:
$ cvs -d:pserver:anoncvs@tmux.cvs.sf.net:/cvsroot/tmux co tmux
If running CVS HEAD, please note it is development code and there may be bugs
and undocumented features; please read the CHANGES file for information.
tmux mailing lists are available; visit: tmux mailing lists are available; visit:
https://sourceforge.net/mail/?group_id=200378 https://sourceforge.net/mail/?group_id=200378
@@ -87,4 +94,4 @@ welcome. Please send by email to:
-- Nicholas Marriott <nicm@users.sf.net> -- Nicholas Marriott <nicm@users.sf.net>
$Id: NOTES,v 1.48 2009-07-01 19:49:56 nicm Exp $ $Id: NOTES,v 1.45 2009-04-21 20:06:12 nicm Exp $

101
TODO
View File

@@ -1,20 +1,32 @@
- line mode/char-at-a-time mode a la telnet?
- handle ioctl/termios stuff on window sockets
- figure out once and for all what is going on with backspace and del
backspace should be translated per the termios setting.
del passed through?
- window creation/idle time - window creation/idle time
- profile/optimise, particularly (i suspect) input.c
- could use bsearch all over the place or get rid of smaller tables (clientmsg) - could use bsearch all over the place or get rid of smaller tables (clientmsg)
- better errors when creating new windows/sessions (how?) - better errors when creating new windows/sessions (how?)
- implicitly add exec to the commands for new windows (switch to disable it)? - Implicitly add exec to the commands for new windows (switch to disable it)
- it would be nice to have multichar commands eg C-b K K - it would be nice to have multichar commands so you could have C-b K K for
kill-window to limit accidental presses
- commands: - commands:
extend list-clients to list clients attached to a session (-a for all?) extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session? bring back detach-session to detach all clients on a session?
clone-session command to link all windows to a new session
- allow fnmatch for -c, so that you can, eg, detach all clients - allow fnmatch for -c, so that you can, eg, detach all clients
- bind non prefix keys - bind non prefix keys
- garbage collect window history (100 lines at a time?) if it hasn't been used - garbage collect window history (100 lines at a time?) if it hasn't been used
in $x time (need window creation/use times) in $x time (need window creation/use times)
- lift SHRT_MAX limits for history? - lift SHRT_MAX limits for history
- audit copy/scroll and other modes for problems with very small windows - audit copy/scroll and other modes for problems with very small windows
- split clients into three RB trees by fd: attached/unattached/dead?
or tailqs? what would be fastest per-char?
- c/p is still borken in some ways
- better mode features: search, back word, forward word, etc - better mode features: search, back word, forward word, etc
- flags to centre screen in window - flags to centre screen in window
- better terminal emulation (identify, insert mode, some other bits) - better terminal emulation (identify, insert mode, some other bits)
- when resizing, use history
- audit for leftover/unused code - audit for leftover/unused code
- activity/bell should be per-window not per-link? what if it is cur win in - activity/bell should be per-window not per-link? what if it is cur win in
session not being watched? session not being watched?
@@ -29,64 +41,63 @@
unwrapping unwrapping
- input.c is too complicated. simplify? - input.c is too complicated. simplify?
- use a better termcap internally instead of screen, perhaps xterm - use a better termcap internally instead of screen, perhaps xterm
- a command to display the status line briefly when it is turned off
- FAQ "Can I have some examples of cool things I can do with tmux?" -- linkw,
more??
- kill all but current pane - kill all but current pane
- fix rxvt cursor fg issue (text under cursor can have non-white fg) - fix rxvt cursor fg issue (text under cursor can have non-white fg)
- key handling sucks a bit and may need to be reworked - key handling sucks a bit and needs to be reworked
- some people find first window being 0 rather than 1 is awkward on the - some people find first window being 0 rather than 1 is awkward on the
keyboard keyboard. what about a new-window-index option that sets the base at which
tmux starts numbering new windows, then they can do: set -g new-window-index
1; bind 0 selectw -t:10
- some way to change status line colours based on something? command?
- client sx/sy should be in tty, then can let the terminal wrap at edge - client sx/sy should be in tty, then can let the terminal wrap at edge
to allow xterm to pick up it should be one line for its c/p to allow xterm to pick up it should be one line for its c/p
- should be able to move to a hidden pane and it would be moved into view. pane - should be able to move to a hidden pane and it would be moved into view. pane
number in status line/top-right would be cool for this number in status line/top-right would be cool for this
- command to run something without a window at all - output to - command to run something without a window at all - output to
window-more. what for? isnt this the same as doing it w/ splitw/neww now? window-more. what for? isnt this the same as doing it w/ splitw/neww now?
- command to purge window history? or apply history-limit changes?
- clone session command
- make command sequences more usable: don't require space around ;, handle
errors better
- would be nice if tmux could be the shell (tmux attach, but hard link to tmux - would be nice if tmux could be the shell (tmux attach, but hard link to tmux
binary as "tmuxsh" or wrapper script?) problems with tty dev permissions binary as "tmuxsh" or wrapper script?) -- problems with tty dev permissions
- support other mouse modes (highlight etc) and use it in copy mode - support other mouse modes (highlight etc) and use it in copy mode
- set-remain-on-exit is a bit of a hack, some way to do it generically? - set-remain-on-exit is a bit of a hack, some way to do it generically?
- set-option should be set-session-option and should be overall global options - set-option should be set-session-option and should be overall global options
for stuff like mode keys? for stuff like mode keys?
also quiet, utf8 and maybe other flags? - a confirm-before command which asks "Are you sure? (y/n)" before executing
-g is a bit unexpected in conf file command, eg bind-key "&" confirm-before "kill-window"
- clear window title on exit
- refer to windows by name etc (duplicates? fnmatch?)
- the output code (tty.c) could do with optimisation depending on term
capibilities
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- goto line and search history in copy/scroll modes
- a command to display the status line briefly when it is turned off
- clone session command
- make command sequences more usable: don't require space after ;, handle
errors better
- might be nice if attach-session behaved like switch-client inside an - might be nice if attach-session behaved like switch-client inside an
existing client existing client
- key to switch to copy mode from scroll mode - key to switch to copy mode from scroll mode
- attach should have a flag to create session if it doesn't exist - attach should have a flag to create session if it doesn't exist
- clear window title on exit
- better support for stupid margin terminals. strcmp for cons25 sucks, how can
these be autodetected?
- refer to windows by name etc (duplicates? fnmatch?)
- the output code (tty.c) could do with optimisation depending on term
capibilities
- resize-pane-up/down should be resize-pane -U/-D. ditto up-pane/down-pane
should be select-pane -U/-D
- layout/split stuff: - layout/split stuff:
** NEW layout design: horiz split command, and similar resizing commands as for vert split
1. finish rewrite manual with tree of layout_cell display the layout in a readable format somewhere
2. convert automatic layout modes to produce a tree and make previous-layout command
them one-off operations select-layout command
3. move any size/position details from window_pane to layout_cell make manual layout a bit less of a hack and make it handle a grid
3.5. fix -p/-l on split should the layout be a window option???
4. a way to address panes by name ("top-left") and position ("0,0") more layouts
TO TEST: force-width/height OK, respawn-window, rotate-window OK, break-pane?? better resizing of shells when changing layout
** rename split-window -> split-pane find and fix bug with clear screen after horiz split
- fix UTF-8 guesswork on sparc64, improve tty checks speed improvements? -- still too slow over ssh!
- choice and more mode would be better per client than per window? hardcoded 81 for left-vertical is nasty
- some way to force a screen to use the entire terminal even if it is forced - test bug sshing from freebsd console (tom iirc?)
to be smaller by other clients. pan smaller terminal? (like screen F) - fix build on solaris 10
- close/redirect stderr when popen to child proc for #() in status line - rotate-window has redraw bugs... :-/
- if-shell-command command to run a tmux command if a shell command returns true
- hooks to which commands may be attached, for example: (hopefully) for 0.8, in no particular order:
tmux add-hook "new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file $HOME/.tmux-session.conf - nothing!
- get it passing all the vttest tests that don't require resizing the terminal
- does tmux require a exmple conf? where does it go?
- there are an awful lot of commands. maybe separate man page for conf
file/commands -similar to ssh/ssh_config?
- esc seq to set window title should be documented and should set automatic-rename
- *** get rid of PANE_HIDDEN -- initially just check for outside window
- way to set socket path from config file
- the "window with one pane" vs window distinction is weird, eg you can't kill-pane the last pane

6
arg.c
View File

@@ -1,4 +1,4 @@
/* $Id: arg.c,v 1.6 2009-06-25 15:25:45 nicm Exp $ */ /* $Id: arg.c,v 1.5 2008-08-28 17:45:25 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -76,7 +76,7 @@ arg_parse_client(const char *arg)
/* Trim a trailing : if any from the argument. */ /* Trim a trailing : if any from the argument. */
n = strlen(arg2); n = strlen(arg2);
if (n && arg2[n - 1] == ':') if (arg2[n - 1] == ':')
arg2[n - 1] = '\0'; arg2[n - 1] = '\0';
/* Try and look up the client name. */ /* Try and look up the client name. */
@@ -101,7 +101,7 @@ arg_parse_session(const char *arg)
/* Trim a trailing : if any from the argument. */ /* Trim a trailing : if any from the argument. */
n = strlen(arg2); n = strlen(arg2);
if (n && arg2[n - 1] == ':') if (arg2[n - 1] == ':')
arg2[n - 1] = '\0'; arg2[n - 1] = '\0';
/* See if the argument matches a session. */ /* See if the argument matches a session. */

View File

@@ -1,4 +1,4 @@
/* $Id: attributes.c,v 1.2 2009-06-25 15:25:45 nicm Exp $ */ /* $Id: attributes.c,v 1.1 2009-01-27 20:22:33 nicm Exp $ */
/* /*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org> * Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -45,8 +45,7 @@ attributes_tostring(u_char ch)
strlcat(buf, "hidden,", sizeof (buf)); strlcat(buf, "hidden,", sizeof (buf));
if (ch & GRID_ATTR_ITALICS) if (ch & GRID_ATTR_ITALICS)
strlcat(buf, "italics,", sizeof (buf)); strlcat(buf, "italics,", sizeof (buf));
if (*buf) *(strrchr(buf, ',')) = '\0';
*(strrchr(buf, ',')) = '\0';
return (buf); return (buf);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: buffer-poll.c,v 1.14 2009-06-25 16:22:36 nicm Exp $ */ /* $Id: buffer-poll.c,v 1.10 2008-09-09 22:16:36 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,19 +23,39 @@
#include "tmux.h" #include "tmux.h"
/* Set up pollfd for buffers. */
void
buffer_set(
struct pollfd *pfd, int fd, unused struct buffer *in, struct buffer *out)
{
pfd->fd = fd;
pfd->events = POLLIN;
if (BUFFER_USED(out) > 0)
pfd->events |= POLLOUT;
}
/* Fill buffers from socket based on poll results. */ /* Fill buffers from socket based on poll results. */
int int
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out) buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
{ {
ssize_t n; ssize_t n;
#ifdef HAVE_POLL #if 0
log_debug("buffer_poll (%ld): fd=%d, revents=%d; out=%zu in=%zu",
(long) getpid(),
pfd->fd, pfd->revents, BUFFER_USED(out), BUFFER_USED(in));
#endif
#ifndef BROKEN_POLL
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP)) if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
return (-1); return (-1);
#endif #endif
if (pfd->revents & POLLIN) { if (pfd->revents & POLLIN) {
buffer_ensure(in, BUFSIZ); buffer_ensure(in, BUFSIZ);
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in)); n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
#if 0
log_debug("buffer_poll: fd=%d, read=%zd", pfd->fd, n);
#endif
if (n == 0) if (n == 0)
return (-1); return (-1);
if (n == -1) { if (n == -1) {
@@ -46,6 +66,9 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
} }
if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) { if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out)); n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
#if 0
log_debug("buffer_poll: fd=%d, write=%zd", pfd->fd, n);
#endif
if (n == -1) { if (n == -1) {
if (errno != EINTR && errno != EAGAIN) if (errno != EINTR && errno != EAGAIN)
return (-1); return (-1);
@@ -54,3 +77,23 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
} }
return (0); return (0);
} }
/* Flush buffer output to socket. */
void
buffer_flush(int fd, struct buffer *in, struct buffer *out)
{
struct pollfd pfd;
while (BUFFER_USED(out) > 0) {
buffer_set(&pfd, fd, in, out);
if (poll(&pfd, 1, INFTIM) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
}
if (buffer_poll(&pfd, in, out) != 0)
break;
}
}

View File

@@ -1,4 +1,4 @@
/* $Id: buffer.c,v 1.7 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: buffer.c,v 1.5 2008-08-07 20:20:52 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,6 +47,14 @@ buffer_destroy(struct buffer *b)
xfree(b); xfree(b);
} }
/* Empty a buffer. */
void
buffer_clear(struct buffer *b)
{
b->size = 0;
b->off = 0;
}
/* Ensure free space for size in buffer. */ /* Ensure free space for size in buffer. */
void void
buffer_ensure(struct buffer *b, size_t size) buffer_ensure(struct buffer *b, size_t size)
@@ -83,6 +91,18 @@ buffer_add(struct buffer *b, size_t size)
b->size += size; b->size += size;
} }
/* Reverse buffer add. */
void
buffer_reverse_add(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
b->size -= size;
}
/* Adjust buffer after data removed. */ /* Adjust buffer after data removed. */
void void
buffer_remove(struct buffer *b, size_t size) buffer_remove(struct buffer *b, size_t size)
@@ -96,6 +116,50 @@ buffer_remove(struct buffer *b, size_t size)
b->off += size; b->off += size;
} }
/* Reverse buffer remove. */
void
buffer_reverse_remove(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->off)
fatalx("overflow");
b->size += size;
b->off -= size;
}
/* Insert a section into the buffer. */
void
buffer_insert_range(struct buffer *b, size_t base, size_t size)
{
if (size == 0)
fatalx("zero size");
if (base > b->size)
fatalx("range outside buffer");
buffer_ensure(b, size);
memmove(b->base + b->off + base + size,
b->base + b->off + base, b->size - base);
b->size += size;
}
/* Delete a section from the buffer. */
void
buffer_delete_range(struct buffer *b, size_t base, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("size too big");
if (base + size > b->size)
fatalx("range outside buffer");
memmove(b->base + b->off + base,
b->base + b->off + base + size, b->size - base - size);
b->size -= size;
}
/* Copy data into a buffer. */ /* Copy data into a buffer. */
void void
buffer_write(struct buffer *b, const void *data, size_t size) buffer_write(struct buffer *b, const void *data, size_t size)
@@ -130,6 +194,16 @@ buffer_write8(struct buffer *b, uint8_t n)
buffer_add(b, 1); buffer_add(b, 1);
} }
/* Store a 16-bit value. */
void
buffer_write16(struct buffer *b, uint16_t n)
{
buffer_ensure(b, 2);
BUFFER_IN(b)[0] = n & 0xff;
BUFFER_IN(b)[1] = n >> 8;
buffer_add(b, 2);
}
/* Extract an 8-bit value. */ /* Extract an 8-bit value. */
uint8_t uint8_t
buffer_read8(struct buffer *b) buffer_read8(struct buffer *b)
@@ -140,3 +214,14 @@ buffer_read8(struct buffer *b)
buffer_remove(b, 1); buffer_remove(b, 1);
return (n); return (n);
} }
/* Extract a 16-bit value. */
uint16_t
buffer_read16(struct buffer *b)
{
uint16_t n;
n = BUFFER_OUT(b)[0] | (BUFFER_OUT(b)[1] << 8);
buffer_remove(b, 2);
return (n);
}

14
cfg.c
View File

@@ -1,4 +1,4 @@
/* $Id: cfg.c,v 1.18 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: cfg.c,v 1.15 2009-03-31 22:23:43 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -17,7 +17,6 @@
*/ */
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@@ -30,6 +29,7 @@
* argv array and executed as a command. * argv array and executed as a command.
*/ */
char *cfg_string(FILE *, char, int);
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...); void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...); void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
@@ -55,21 +55,11 @@ load_cfg(const char *path, char **cause)
{ {
FILE *f; FILE *f;
u_int n; u_int n;
struct stat sb;
char *buf, *line, *ptr; char *buf, *line, *ptr;
size_t len; size_t len;
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd_ctx ctx; struct cmd_ctx ctx;
if (stat(path, &sb) != 0) {
xasprintf(cause, "%s: %s", path, strerror(errno));
return (-1);
}
if (!S_ISREG(sb.st_mode)) {
xasprintf(cause, "%s: not a regular file", path);
return (-1);
}
if ((f = fopen(path, "rb")) == NULL) { if ((f = fopen(path, "rb")) == NULL) {
xasprintf(cause, "%s: %s", path, strerror(errno)); xasprintf(cause, "%s: %s", path, strerror(errno));
return (1); return (1);

View File

@@ -1,4 +1,4 @@
/* $Id: client-msg.c,v 1.19 2009-06-25 15:25:45 nicm Exp $ */ /* $Id: client-msg.c,v 1.18 2009-01-21 22:47:31 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -73,7 +73,7 @@ client_msg_dispatch(struct client_ctx *cctx, char **error)
int int
client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error) client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
{ {
if (hdr->size == SIZE_MAX) if (hdr->size > SIZE_MAX - 1)
fatalx("bad MSG_ERROR size"); fatalx("bad MSG_ERROR size");
*error = xmalloc(hdr->size + 1); *error = xmalloc(hdr->size + 1);

View File

@@ -1,4 +1,4 @@
/* $Id: client.c,v 1.53 2009-07-01 23:06:32 nicm Exp $ */ /* $Id: client.c,v 1.46 2009-03-31 22:20:42 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,15 +46,6 @@ client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
int mode; int mode;
struct buffer *b; struct buffer *b;
char *name; char *name;
#ifdef HAVE_SETPROCTITLE
char rpathbuf[MAXPATHLEN];
#endif
#ifdef HAVE_SETPROCTITLE
if (realpath(path, rpathbuf) == NULL)
strlcpy(rpathbuf, path, sizeof rpathbuf);
setproctitle("client (%s)", rpathbuf);
#endif
if (lstat(path, &sb) != 0) { if (lstat(path, &sb) != 0) {
if (start_server && errno == ENOENT) { if (start_server && errno == ENOENT) {
@@ -144,8 +135,12 @@ client_main(struct client_ctx *cctx)
siginit(); siginit();
logfile("client"); logfile("client");
#ifndef NO_SETPROCTITLE
setproctitle("client");
#endif
error = NULL; error = NULL;
xtimeout = INFTIM;
while (!sigterm) { while (!sigterm) {
if (sigchld) { if (sigchld) {
waitpid(WAIT_ANY, NULL, WNOHANG); waitpid(WAIT_ANY, NULL, WNOHANG);

View File

@@ -1,4 +1,4 @@
/* $Id: clock.c,v 1.4 2009-05-04 17:58:25 nicm Exp $ */ /* $Id: clock.c,v 1.3 2009-03-27 16:59:57 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-attach-session.c,v 1.26 2009-06-25 16:34:50 nicm Exp $ */ /* $Id: cmd-attach-session.c,v 1.24 2009-01-23 16:59:14 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -77,3 +77,4 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (1); return (1);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-bind-key.c,v 1.21 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-bind-key.c,v 1.20 2009-03-28 14:08:09 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-break-pane.c,v 1.3 2009-05-18 21:01:38 nicm Exp $ */ /* $Id: cmd-break-pane.c,v 1.1 2009-03-07 09:29:54 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -74,18 +74,18 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl->window->active == NULL) if (wl->window->active == NULL)
wl->window->active = TAILQ_NEXT(wp, entry); wl->window->active = TAILQ_NEXT(wp, entry);
} }
layout_refresh(wl->window, 0); window_fit_panes(wl->window);
w = wp->window = window_create1(s->sx, s->sy); w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp; w->active = wp;
window_fit_panes(w);
w->name = default_window_name(w); w->name = default_window_name(w);
wl = session_attach(s, w, -1, &cause); /* can't fail */ wl = session_attach(s, w, -1, &cause); /* can't fail */
if (!(data->flags & CMD_DFLAG)) if (!(data->flags & CMD_DFLAG))
session_select(s, wl->idx); session_select(s, wl->idx);
layout_refresh(w, 0);
server_redraw_session(s); server_redraw_session(s);
return (0); return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-session.c,v 1.7 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-choose-session.c,v 1.6 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-window.c,v 1.9 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-choose-window.c,v 1.7 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -76,8 +76,8 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
idx++; idx++;
window_choose_add(wl->window->active, window_choose_add(wl->window->active,
wm->idx, "%3d: %s [%ux%u %s] (%u panes)", wm->idx, w->name, wm->idx, "%3d: %s [%ux%u] (%u panes)", wm->idx, w->name,
w->sx, w->sy, layout_name(w), window_count_panes(w)); w->sx, w->sy, window_count_panes(w));
} }
cdata = xmalloc(sizeof *cdata); cdata = xmalloc(sizeof *cdata);

View File

@@ -1,67 +0,0 @@
/* $Id: cmd-clear-history.c,v 1.3 2009-06-25 16:21:32 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include "tmux.h"
/*
* Clear pane history.
*/
int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
CMD_PANE_WINDOW_USAGE,
0,
cmd_pane_init,
cmd_pane_parse,
cmd_clear_history_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
};
int
cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
struct grid *gd;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
gd = wp->base.grid;
grid_move_lines(gd, 0, gd->hsize, gd->sy);
gd->hsize = 0;
return (0);
}

View File

@@ -1,141 +0,0 @@
/* $Id: cmd-confirm-before.c,v 1.4 2009-04-28 18:29:44 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <ctype.h>
#include <string.h>
#include "tmux.h"
/*
* Asks for confirmation before executing a command.
*/
int cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *);
void cmd_confirm_before_init(struct cmd *, int);
int cmd_confirm_before_callback(void *, const char *);
struct cmd_confirm_before_data {
struct client *c;
char *cmd;
};
const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
CMD_TARGET_CLIENT_USAGE " command",
CMD_ARG1,
cmd_confirm_before_init,
cmd_target_parse,
cmd_confirm_before_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
void
cmd_confirm_before_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case '&':
data->arg = xstrdup("kill-window");
break;
case 'x':
data->arg = xstrdup("kill-pane");
break;
}
}
int
cmd_confirm_before_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_confirm_before_data *cdata;
struct client *c;
char *buf, *cmd, *ptr;
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
return (-1);
}
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
ptr = xstrdup(data->arg);
if ((cmd = strtok(ptr, " \t")) == NULL)
cmd = ptr;
xasprintf(&buf, "Confirm '%s'? (y/n) ", cmd);
xfree(ptr);
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg);
cdata->c = c;
status_prompt_set(
cdata->c, buf, cmd_confirm_before_callback, cdata, PROMPT_SINGLE);
xfree(buf);
return (1);
}
int
cmd_confirm_before_callback(void *data, const char *s)
{
struct cmd_confirm_before_data *cdata = data;
struct client *c = cdata->c;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
char *cause;
if (s == NULL || tolower((u_char) s[0]) != 'y' || s[1] != '\0')
goto out;
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
*cause = toupper((u_char) *cause);
status_message_set(c, cause);
xfree(cause);
}
goto out;
}
ctx.msgdata = NULL;
ctx.cursession = c->session;
ctx.curclient = c;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
ctx.info = key_bindings_info;
ctx.cmdclient = NULL;
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
out:
if (cdata->cmd != NULL)
xfree(cdata->cmd);
xfree(cdata);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-mode.c,v 1.19 2009-07-01 23:06:32 nicm Exp $ */ /* $Id: cmd-copy-mode.c,v 1.16 2009-02-25 21:56:46 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,15 +44,13 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
wp = wl->window->active;
window_pane_set_mode(wp, &window_copy_mode); window_pane_set_mode(wl->window->active, &window_copy_mode);
if (wp->mode == &window_copy_mode && data->flags & CMD_UFLAG) if (data->flags & CMD_UFLAG)
window_copy_pageup(wp); window_copy_pageup(wl->window->active);
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-delete-buffer.c,v 1.5 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-delete-buffer.c,v 1.4 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-find-window.c,v 1.10 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: cmd-find-window.c,v 1.6 2009-03-29 11:18:28 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,7 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <fnmatch.h>
#include <string.h> #include <string.h>
#include "tmux.h" #include "tmux.h"
@@ -30,6 +29,7 @@
int cmd_find_window_exec(struct cmd *, struct cmd_ctx *); int cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_find_window_callback(void *, int); void cmd_find_window_callback(void *, int);
char *cmd_find_window_search(struct window_pane *, const char *);
const struct cmd_entry cmd_find_window_entry = { const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw", "find-window", "findw",
@@ -59,8 +59,8 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window_pane *wp; struct window_pane *wp;
ARRAY_DECL(, u_int) list_idx; ARRAY_DECL(, u_int) list_idx;
ARRAY_DECL(, char *) list_ctx; ARRAY_DECL(, char *) list_ctx;
char *sres, *sctx, *searchstr; char *sres, *sctx;
u_int i, line; u_int i;
if (ctx->curclient == NULL) { if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively"); ctx->error(ctx, "must be run interactively");
@@ -74,18 +74,17 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
ARRAY_INIT(&list_idx); ARRAY_INIT(&list_idx);
ARRAY_INIT(&list_ctx); ARRAY_INIT(&list_ctx);
xasprintf(&searchstr, "*%s*", data->arg);
RB_FOREACH(wm, winlinks, &s->windows) { RB_FOREACH(wm, winlinks, &s->windows) {
i = 0; i = 0;
TAILQ_FOREACH(wp, &wm->window->panes, entry) { TAILQ_FOREACH(wp, &wm->window->panes, entry) {
i++; i++;
if (fnmatch(searchstr, wm->window->name, 0) == 0) if (strstr(wm->window->name, data->arg) != NULL)
sctx = xstrdup(""); sctx = xstrdup("");
else { else {
sres = window_pane_search(wp, data->arg, &line); sres = cmd_find_window_search(wp, data->arg);
if (sres == NULL && if (sres == NULL &&
fnmatch(searchstr, wp->base.title, 0) != 0) strstr(wp->base.title, data->arg) == NULL)
continue; continue;
if (sres == NULL) { if (sres == NULL) {
@@ -93,9 +92,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
"pane %u title: \"%s\"", i - 1, "pane %u title: \"%s\"", i - 1,
wp->base.title); wp->base.title);
} else { } else {
xasprintf(&sctx, xasprintf(&sctx, "\"%s\"", sres);
"pane %u line %u: \"%s\"", i - 1,
line + 1, sres);
xfree(sres); xfree(sres);
} }
} }
@@ -104,7 +101,6 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
ARRAY_ADD(&list_ctx, sctx); ARRAY_ADD(&list_ctx, sctx);
} }
} }
xfree(searchstr);
if (ARRAY_LENGTH(&list_idx) == 0) { if (ARRAY_LENGTH(&list_idx) == 0) {
ctx->error(ctx, "no windows matching: %s", data->arg); ctx->error(ctx, "no windows matching: %s", data->arg);
@@ -163,3 +159,46 @@ cmd_find_window_callback(void *data, int idx)
} }
xfree(cdata); xfree(cdata);
} }
char *
cmd_find_window_search(struct window_pane *wp, const char *searchstr)
{
const struct grid_cell *gc;
const struct grid_utf8 *gu;
char *buf, *s;
size_t off;
u_int i, j, k;
buf = xmalloc(1);
for (j = 0; j < screen_size_y(&wp->base); j++) {
off = 0;
for (i = 0; i < screen_size_x(&wp->base); i++) {
gc = grid_view_peek_cell(wp->base.grid, i, j);
if (gc->flags & GRID_FLAG_UTF8) {
gu = grid_view_peek_utf8(wp->base.grid, i, j);
buf = xrealloc(buf, 1, off + 8);
for (k = 0; k < UTF8_SIZE; k++) {
if (gu->data[k] == 0xff)
break;
buf[off++] = gu->data[k];
}
} else {
buf = xrealloc(buf, 1, off + 1);
buf[off++] = gc->data;
}
}
while (off > 0 && buf[off - 1] == ' ')
off--;
buf[off] = '\0';
if ((s = strstr(buf, searchstr)) != NULL) {
s = section_string(buf, off, s - buf, 40);
xfree(buf);
return (s);
}
}
xfree(buf);
return (NULL);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-generic.c,v 1.28 2009-05-21 19:47:57 nicm Exp $ */ /* $Id: cmd-generic.c,v 1.25 2009-04-03 17:31:44 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,8 +24,8 @@
#include "tmux.h" #include "tmux.h"
#define CMD_FLAGS "adDgkuU" #define CMD_FLAGS "adDgkuU"
#define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_BIGDFLAG|CMD_GFLAG|CMD_KFLAG| \ #define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_UPPERDFLAG|CMD_GFLAG|CMD_KFLAG| \
CMD_UFLAG|CMD_BIGUFLAG) CMD_UFLAG|CMD_UPPERUFLAG)
int cmd_do_flags(int, int, int *); int cmd_do_flags(int, int, int *);
size_t cmd_print_flags(char *, size_t, size_t, int); size_t cmd_print_flags(char *, size_t, size_t, int);
@@ -34,7 +34,7 @@ int cmd_fill_argument(int, char **, int, char **);
size_t size_t
cmd_prarg(char *buf, size_t len, const char *prefix, char *arg) cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
{ {
if (strchr(arg, ' ') != NULL) if (strchr(arg, ' ' ) != NULL)
return (xsnprintf(buf, len, "%s\"%s\"", prefix, arg)); return (xsnprintf(buf, len, "%s\"%s\"", prefix, arg));
return (xsnprintf(buf, len, "%s%s", prefix, arg)); return (xsnprintf(buf, len, "%s%s", prefix, arg));
} }
@@ -56,8 +56,8 @@ cmd_do_flags(int opt, int iflags, int *oflags)
} }
return (-1); return (-1);
case 'D': case 'D':
if (iflags & CMD_BIGDFLAG) { if (iflags & CMD_UPPERDFLAG) {
(*oflags) |= CMD_BIGDFLAG; (*oflags) |= CMD_UPPERDFLAG;
return (0); return (0);
} }
return (-1); return (-1);
@@ -80,8 +80,8 @@ cmd_do_flags(int opt, int iflags, int *oflags)
} }
return (-1); return (-1);
case 'U': case 'U':
if (iflags & CMD_BIGUFLAG) { if (iflags & CMD_UPPERUFLAG) {
(*oflags) |= CMD_BIGUFLAG; (*oflags) |= CMD_UPPERUFLAG;
return (0); return (0);
} }
return (-1); return (-1);
@@ -99,7 +99,7 @@ cmd_print_flags(char *buf, size_t len, size_t off, int flags)
off += xsnprintf(buf + off, len - off, " -"); off += xsnprintf(buf + off, len - off, " -");
if (off < len && flags & CMD_AFLAG) if (off < len && flags & CMD_AFLAG)
off += xsnprintf(buf + off, len - off, "a"); off += xsnprintf(buf + off, len - off, "a");
if (off < len && flags & CMD_BIGDFLAG) if (off < len && flags & CMD_UPPERDFLAG)
off += xsnprintf(buf + off, len - off, "D"); off += xsnprintf(buf + off, len - off, "D");
if (off < len && flags & CMD_DFLAG) if (off < len && flags & CMD_DFLAG)
off += xsnprintf(buf + off, len - off, "d"); off += xsnprintf(buf + off, len - off, "d");
@@ -109,7 +109,7 @@ cmd_print_flags(char *buf, size_t len, size_t off, int flags)
off += xsnprintf(buf + off, len - off, "k"); off += xsnprintf(buf + off, len - off, "k");
if (off < len && flags & CMD_UFLAG) if (off < len && flags & CMD_UFLAG)
off += xsnprintf(buf + off, len - off, "u"); off += xsnprintf(buf + off, len - off, "u");
if (off < len && flags & CMD_BIGUFLAG) if (off < len && flags & CMD_UPPERUFLAG)
off += xsnprintf(buf + off, len - off, "U"); off += xsnprintf(buf + off, len - off, "U");
return (off - boff); return (off - boff);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.7 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-kill-pane.c,v 1.6 2009-04-01 21:10:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-clients.c,v 1.16 2009-06-25 16:34:50 nicm Exp $ */ /* $Id: cmd-list-clients.c,v 1.13 2009-02-11 17:50:32 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,20 +47,14 @@ cmd_list_clients_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{ {
struct client *c; struct client *c;
u_int i; u_int i;
const char *s_utf8;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL) if (c == NULL || c->session == NULL)
continue; continue;
if (c->tty.flags & TTY_UTF8) ctx->print(ctx, "%s: %s [%ux%u %s]", c->tty.path,
s_utf8 = " (utf8)"; c->session->name, c->tty.sx, c->tty.sy, c->tty.termname);
else
s_utf8 = "";
ctx->print(ctx, "%s: %s [%ux%u %s]%s", c->tty.path,
c->session->name, c->tty.sx, c->tty.sy,
c->tty.termname, s_utf8);
} }
return (0); return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-keys.c,v 1.14 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-list-keys.c,v 1.13 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.35 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-list-windows.c,v 1.33 2009-03-28 20:17:29 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -78,9 +78,8 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
else else
name = "unknown"; name = "unknown";
ctx->print(ctx, ctx->print(ctx,
" %s [%ux%u %s] [history %u/%u, %llu bytes]", " %s [%ux%u] [history %u/%u, %llu bytes]",
name, wp->sx, wp->sy, layout_name(w), gd->hsize, name, wp->sx, wp->sy, gd->hsize, gd->hlimit, size);
gd->hlimit, size);
} }
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list.c,v 1.5 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-list.c,v 1.3 2009-02-16 18:57:16 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,43 +28,28 @@ cmd_list_parse(int argc, char **argv, char **cause)
struct cmd_list *cmdlist; struct cmd_list *cmdlist;
struct cmd *cmd; struct cmd *cmd;
int i, lastsplit; int i, lastsplit;
size_t arglen, new_argc;
char **new_argv;
cmdlist = xmalloc(sizeof *cmdlist); cmdlist = xmalloc(sizeof *cmdlist);
TAILQ_INIT(cmdlist); TAILQ_INIT(cmdlist);
lastsplit = 0; lastsplit = 0;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
arglen = strlen(argv[i]); if (strcmp(argv[i], "\\;") == 0) {
if (arglen == 0 || argv[i][arglen - 1] != ';') argv[i][0] = ';';
continue; argv[i][1] = '\0';
argv[i][arglen - 1] = '\0'; } else if (strcmp(argv[i], ";") == 0) {
cmd = cmd_parse(i - lastsplit, argv + lastsplit, cause);
if (arglen > 1 && argv[i][arglen - 2] == '\\') { if (cmd == NULL)
argv[i][arglen - 2] = ';'; goto bad;
continue; TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
lastsplit = i + 1;
} }
new_argc = i - lastsplit;
new_argv = argv + lastsplit;
if (arglen != 1)
new_argc++;
cmd = cmd_parse(new_argc, new_argv, cause);
if (cmd == NULL)
goto bad;
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
lastsplit = i + 1;
} }
if (lastsplit != argc) { cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause); if (cmd == NULL)
if (cmd == NULL) goto bad;
goto bad; TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
}
return (cmdlist); return (cmdlist);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-load-buffer.c,v 1.4 2009-05-21 19:38:51 nicm Exp $ */ /* $Id: cmd-load-buffer.c,v 1.2 2009-01-27 23:26:15 nicm Exp $ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -62,12 +62,8 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1); return (-1);
} }
if (!S_ISREG(statbuf.st_mode)) {
ctx->error(ctx, "%s: not a regular file", data->arg);
return (-1);
}
if ((f = fopen(data->arg, "rb")) == NULL) { if ((f = fopen(data->arg, "r")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1); return (-1);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-server.c,v 1.4 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: cmd-lock-server.c,v 1.2 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,6 +30,8 @@
int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *); int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
int cmd_lock_server_callback(void *, const char *);
const struct cmd_entry cmd_lock_server_entry = { const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock", "lock-server", "lock",
"", "",

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.41 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-new-session.c,v 1.40 2009-04-01 18:21:24 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-layout.c,v 1.2 2009-04-30 21:17:06 nicm Exp $ */ /* $Id: cmd-next-layout.c,v 1.1 2009-04-01 18:21:26 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -49,7 +49,6 @@ cmd_next_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1); return (-1);
layout_next(wl->window); layout_next(wl->window);
ctx->info(ctx, "layout now: %s", layout_name(wl->window));
return (0); return (0);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-window.c,v 1.17 2009-06-25 15:29:34 nicm Exp $ */ /* $Id: cmd-next-window.c,v 1.16 2009-03-28 14:08:09 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_next_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_window_entry = { const struct cmd_entry cmd_next_window_entry = {
"next-window", "next", "next-window", "next",
"[-a] " CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
CMD_AFLAG, CMD_AFLAG,
cmd_next_window_init, cmd_next_window_init,
cmd_target_parse, cmd_target_parse,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-paste-buffer.c,v 1.16 2009-07-02 16:23:54 nicm Exp $ */ /* $Id: cmd-paste-buffer.c,v 1.15 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,7 +63,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
} }
if (pb != NULL && *pb->data != '\0') if (pb != NULL)
buffer_write(w->active->out, pb->data, strlen(pb->data)); buffer_write(w->active->out, pb->data, strlen(pb->data));
/* Delete the buffer if -d. */ /* Delete the buffer if -d. */

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-window.c,v 1.17 2009-06-25 15:29:34 nicm Exp $ */ /* $Id: cmd-previous-window.c,v 1.16 2009-03-28 14:08:09 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_previous_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_window_entry = { const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev", "previous-window", "prev",
"[-a] " CMD_TARGET_SESSION_USAGE, CMD_TARGET_SESSION_USAGE,
CMD_AFLAG, CMD_AFLAG,
cmd_previous_window_init, cmd_previous_window_init,
cmd_target_parse, cmd_target_parse,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.27 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-rename-window.c,v 1.26 2009-01-20 19:35:03 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>

122
cmd-resize-pane-down.c Normal file
View File

@@ -0,0 +1,122 @@
/* $Id: cmd-resize-pane-down.c,v 1.8 2009-04-02 21:11:52 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include "tmux.h"
/*
* Decrease pane size.
*/
void cmd_resize_pane_down_init(struct cmd *, int);
int cmd_resize_pane_down_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_down_entry = {
"resize-pane-down", "resizep-down",
CMD_PANE_WINDOW_USAGE " [adjustment]",
CMD_ARG01,
cmd_resize_pane_down_init,
cmd_pane_parse,
cmd_resize_pane_down_exec,
cmd_pane_send,
cmd_pane_recv,
cmd_pane_free,
cmd_pane_print
};
void
cmd_resize_pane_down_init(struct cmd *self, int key)
{
struct cmd_pane_data *data;
cmd_pane_init(self, key);
data = self->data;
if (key == KEYC_ADDESC(KEYC_DOWN))
data->arg = xstrdup("5");
}
int
cmd_resize_pane_down_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_pane_data *data = self->data;
struct winlink *wl;
const char *errstr;
struct window_pane *wp, *wq;
u_int adjust;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if (wl->window->layout != 0) {
ctx->error(ctx, "window not in manual layout");
return (-1);
}
if (data->pane == -1)
wp = wl->window->active;
else {
wp = window_pane_at_index(wl->window, data->pane);
if (wp == NULL) {
ctx->error(ctx, "no pane: %d", data->pane);
return (-1);
}
}
if (data->arg == NULL)
adjust = 1;
else {
adjust = strtonum(data->arg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "adjustment %s: %s", errstr, data->arg);
return (-1);
}
}
/*
* If this is not the last window, keep trying to increase size and
* remove it from the next windows. If it is the last, do so on the
* previous window.
*/
if (TAILQ_NEXT(wp, entry) == NULL) {
if (wp == TAILQ_FIRST(&wl->window->panes)) {
/* Only one pane. */
return (0);
}
wp = TAILQ_PREV(wp, window_panes, entry);
}
while (adjust-- > 0) {
wq = wp;
while ((wq = TAILQ_NEXT(wq, entry)) != NULL) {
if (wq->sy > PANE_MINIMUM) {
window_pane_resize(wq, wq->sx, wq->sy - 1);
break;
}
}
if (wq == NULL)
break;
window_pane_resize(wp, wp->sx, wp->sy + 1);
}
window_update_panes(wl->window);
server_redraw_window(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-resize-pane.c,v 1.7 2009-05-21 19:46:00 nicm Exp $ */ /* $Id: cmd-resize-pane-up.c,v 1.8 2009-04-02 21:11:52 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,19 +23,19 @@
#include "tmux.h" #include "tmux.h"
/* /*
* Increase or decrease pane size. * Increase pane size.
*/ */
void cmd_resize_pane_init(struct cmd *, int); void cmd_resize_pane_up_init(struct cmd *, int);
int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *); int cmd_resize_pane_up_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_entry = { const struct cmd_entry cmd_resize_pane_up_entry = {
"resize-pane", "resizep", "resize-pane-up", "resizep-up",
CMD_PANE_WINDOW_USAGE "[-DU] [adjustment]", CMD_PANE_WINDOW_USAGE " [adjustment]",
CMD_ARG01|CMD_BIGUFLAG|CMD_BIGDFLAG, CMD_ARG01,
cmd_resize_pane_init, cmd_resize_pane_up_init,
cmd_pane_parse, cmd_pane_parse,
cmd_resize_pane_exec, cmd_resize_pane_up_exec,
cmd_pane_send, cmd_pane_send,
cmd_pane_recv, cmd_pane_recv,
cmd_pane_free, cmd_pane_free,
@@ -43,35 +43,32 @@ const struct cmd_entry cmd_resize_pane_entry = {
}; };
void void
cmd_resize_pane_init(struct cmd *self, int key) cmd_resize_pane_up_init(struct cmd *self, int key)
{ {
struct cmd_pane_data *data; struct cmd_pane_data *data;
cmd_pane_init(self, key); cmd_pane_init(self, key);
data = self->data; data = self->data;
if (key == KEYC_ADDCTL(KEYC_DOWN))
data->flags |= CMD_BIGDFLAG;
if (key == KEYC_ADDESC(KEYC_UP)) if (key == KEYC_ADDESC(KEYC_UP))
data->arg = xstrdup("5"); data->arg = xstrdup("5");
if (key == KEYC_ADDESC(KEYC_DOWN)) {
data->flags |= CMD_BIGDFLAG;
data->arg = xstrdup("5");
}
} }
int int
cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx) cmd_resize_pane_up_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_pane_data *data = self->data; struct cmd_pane_data *data = self->data;
struct winlink *wl; struct winlink *wl;
const char *errstr; const char *errstr;
struct window_pane *wp; struct window_pane *wp, *wq;
u_int adjust; u_int adjust;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
if (wl->window->layout != 0) {
ctx->error(ctx, "window not in manual layout");
return (-1);
}
if (data->pane == -1) if (data->pane == -1)
wp = wl->window->active; wp = wl->window->active;
else { else {
@@ -92,13 +89,28 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
} }
if (!(data->flags & CMD_BIGDFLAG)) /*
adjust = -adjust; * If this is not the last window, keep trying to reduce size and add
if (layout_resize(wp, adjust) != 0) { * to the following window. If it is the last, do so on the previous
ctx->error(ctx, "layout %s " * window.
"does not support resizing", layout_name(wp->window)); */
return (-1); wq = TAILQ_NEXT(wp, entry);
if (wq == NULL) {
if (wp == TAILQ_FIRST(&wl->window->panes)) {
/* Only one pane. */
return (0);
}
wq = wp;
wp = TAILQ_PREV(wq, window_panes, entry);
} }
while (adjust-- > 0) {
if (wp->sy <= PANE_MINIMUM)
break;
window_pane_resize(wq, wq->sx, wq->sy + 1);
window_pane_resize(wp, wp->sx, wp->sy - 1);
}
window_update_panes(wl->window);
server_redraw_window(wl->window); server_redraw_window(wl->window);
return (0); return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rotate-window.c,v 1.4 2009-06-25 15:28:08 nicm Exp $ */ /* $Id: cmd-rotate-window.c,v 1.2 2009-04-21 20:06:46 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rotate_window_entry = { const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew", "rotate-window", "rotatew",
"[-DU] " CMD_TARGET_WINDOW_USAGE, "[-DU] " CMD_TARGET_WINDOW_USAGE,
CMD_BIGUFLAG|CMD_BIGDFLAG, CMD_UPPERUFLAG|CMD_UPPERDFLAG,
cmd_rotate_window_init, cmd_rotate_window_init,
cmd_target_parse, cmd_target_parse,
cmd_rotate_window_exec, cmd_rotate_window_exec,
@@ -49,7 +49,7 @@ cmd_rotate_window_init(struct cmd *self, int key)
data = self->data; data = self->data;
if (key == KEYC_ADDESC('o')) if (key == KEYC_ADDESC('o'))
data->flags |= CMD_BIGDFLAG; data->flags |= CMD_UPPERDFLAG;
} }
int int
@@ -60,31 +60,25 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window *w; struct window *w;
struct window_pane *wp, *wp2; struct window_pane *wp, *wp2;
u_int sx, sy, xoff, yoff; u_int sx, sy, xoff, yoff;
int flags;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
w = wl->window; w = wl->window;
if (data->flags & CMD_BIGDFLAG) { if (data->flags & CMD_UPPERDFLAG) {
wp = TAILQ_LAST(&w->panes, window_panes); wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
xoff = wp->xoff; yoff = wp->yoff; xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy; sx = wp->sx; sy = wp->sy;
flags = wp->flags;
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL) if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL)
break; break;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= wp2->flags & PANE_HIDDEN;
window_pane_resize(wp, wp2->sx, wp2->sy); window_pane_resize(wp, wp2->sx, wp2->sy);
} }
wp->xoff = xoff; wp->yoff = yoff; wp->xoff = xoff; wp->yoff = yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= flags & PANE_HIDDEN;
window_pane_resize(wp, sx, sy); window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL) if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL)
@@ -97,18 +91,13 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
xoff = wp->xoff; yoff = wp->yoff; xoff = wp->xoff; yoff = wp->yoff;
sx = wp->sx; sy = wp->sy; sx = wp->sx; sy = wp->sy;
flags = wp->flags;
TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) { TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) {
if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL) if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL)
break; break;
wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= wp2->flags & PANE_HIDDEN;
window_pane_resize(wp, wp2->sx, wp2->sy); window_pane_resize(wp, wp2->sx, wp2->sy);
} }
wp->xoff = xoff; wp->yoff = yoff; wp->xoff = xoff; wp->yoff = yoff;
wp->flags &= ~PANE_HIDDEN;
wp->flags |= flags & PANE_HIDDEN;
window_pane_resize(wp, sx, sy); window_pane_resize(wp, sx, sy);
if ((wp = TAILQ_NEXT(w->active, entry)) == NULL) if ((wp = TAILQ_NEXT(w->active, entry)) == NULL)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-save-buffer.c,v 1.5 2009-05-18 16:22:30 nicm Exp $ */ /* $Id: cmd-save-buffer.c,v 1.4 2009-02-08 13:36:40 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -69,9 +69,9 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
mask = umask(S_IRWXG | S_IRWXO); mask = umask(S_IRWXG | S_IRWXO);
if (data->flags & CMD_AFLAG) if (data->flags & CMD_AFLAG)
f = fopen(data->arg, "ab"); f = fopen(data->arg, "a");
else else
f = fopen(data->arg, "wb"); f = fopen(data->arg, "w");
if (f == NULL) { if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1); return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-scroll-mode.c,v 1.19 2009-07-01 23:06:32 nicm Exp $ */ /* $Id: cmd-scroll-mode.c,v 1.16 2009-01-27 23:35:44 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -60,15 +60,13 @@ cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{ {
struct cmd_target_data *data = self->data; struct cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1); return (-1);
wp = wl->window->active;
window_pane_set_mode(wp, &window_scroll_mode); window_pane_set_mode(wl->window->active, &window_scroll_mode);
if (wp->mode == &window_scroll_mode && data->flags & CMD_UFLAG) if (data->flags & CMD_UFLAG)
window_scroll_pageup(wp); window_scroll_pageup(wl->window->active);
return (0); return (0);
} }

View File

@@ -1,86 +0,0 @@
/* $Id: cmd-select-layout.c,v 1.3 2009-06-25 16:34:50 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include "tmux.h"
/*
* Switch window to selected layout.
*/
void cmd_select_layout_init(struct cmd *, int);
int cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
CMD_TARGET_WINDOW_USAGE " layout-name",
CMD_ARG1,
cmd_select_layout_init,
cmd_target_parse,
cmd_select_layout_exec,
cmd_target_send,
cmd_target_recv,
cmd_target_free,
cmd_target_print
};
void
cmd_select_layout_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case KEYC_ADDESC('0'):
data->arg = xstrdup("manual-vertical");
break;
case KEYC_ADDESC('1'):
data->arg = xstrdup("even-horizontal");
break;
case KEYC_ADDESC('2'):
data->arg = xstrdup("even-vertical");
break;
case KEYC_ADDESC('9'):
data->arg = xstrdup("active-only");
break;
}
}
int
cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
if ((layout = layout_lookup(data->arg)) == -1) {
ctx->error(ctx, "unknown or ambiguous layout: %s", data->arg);
return (-1);
}
if (layout_select(wl->window, layout) == 0)
ctx->info(ctx, "layout now: %s", layout_name(wl->window));
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.20 2009-06-25 20:27:31 nicm Exp $ */ /* $Id: cmd-server-info.c,v 1.14 2009-04-02 23:28:16 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,6 +23,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <vis.h>
#include "tmux.h" #include "tmux.h"
@@ -59,7 +60,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct utsname un; struct utsname un;
struct grid *gd; struct grid *gd;
u_int i, j, k; u_int i, j, k;
char out[80]; char out[BUFSIZ];
char *tim; char *tim;
time_t t; time_t t;
u_int lines, ulines; u_int lines, ulines;
@@ -90,8 +91,8 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
if (c == NULL || c->session == NULL) if (c == NULL || c->session == NULL)
continue; continue;
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] " ctx->print(ctx, "%2d: %p %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x]", i, c->tty.path, c->fd, c->tty.fd, "[flags=0x%x/0x%x]", i, c, c->tty.path, c->fd, c->tty.fd,
c->session->name, c->tty.sx, c->tty.sy, c->tty.termname, c->session->name, c->tty.sx, c->tty.sy, c->tty.termname,
c->flags, c->tty.flags); c->flags, c->tty.flags);
} }
@@ -108,15 +109,14 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
tim = ctime(&t); tim = ctime(&t);
*strchr(tim, '\n') = '\0'; *strchr(tim, '\n') = '\0';
ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] " ctx->print(ctx, "%2u: %p %s: %u windows (created %s) [%ux%u] "
"[flags=0x%x]", i, s->name, winlink_count(&s->windows), "[flags=0x%x]", i, s, s->name, winlink_count(&s->windows),
tim, s->sx, s->sy, s->flags); tim, s->sx, s->sy, s->flags);
RB_FOREACH(wl, winlinks, &s->windows) { RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window; w = wl->window;
ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, " ctx->print(ctx, "%4u: %p/%p %s [%ux%u] [flags=0x%x, "
"references=%u, layout=%u]", wl->idx, w->name, "references=%u, layout=%u]", wl->idx, wl, w, w->name,
w->sx, w->sy, w->flags, w->references, w->sx, w->sy, w->flags, w->references, w->layout);
w->layout);
j = 0; j = 0;
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
lines = ulines = size = usize = 0; lines = ulines = size = usize = 0;
@@ -133,8 +133,8 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
sizeof (**gd->udata); sizeof (**gd->udata);
} }
} }
ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu " ctx->print(ctx, "%6u: %p %s %lu %d %u/%u, %zu "
"bytes; UTF-8 %u/%u, %zu bytes", j, "bytes; UTF-8 %u/%u, %zu bytes", j, wp,
wp->tty, (u_long) wp->pid, wp->fd, lines, wp->tty, (u_long) wp->pid, wp->fd, lines,
gd->hsize + gd->sy, size, ulines, gd->hsize + gd->sy, size, ulines,
gd->hsize + gd->sy, usize); gd->hsize + gd->sy, usize);
@@ -157,8 +157,10 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ent->code, ent->name); ent->code, ent->name);
break; break;
case TTYCODE_STRING: case TTYCODE_STRING:
strnvis(out, code->value.string, sizeof out, strnvis(out, code->value.string,
VIS_OCTAL|VIS_TAB|VIS_NL); sizeof out, VIS_OCTAL|VIS_WHITE);
out[(sizeof out) - 1] = '\0';
ctx->print(ctx, "%2u: %s: (string) %s", ctx->print(ctx, "%2u: %s: (string) %s",
ent->code, ent->name, out); ent->code, ent->name, out);
break; break;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-option.c,v 1.62 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: cmd-set-option.c,v 1.60 2009-03-21 12:44:06 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -73,7 +73,6 @@ const struct set_option_entry set_option_table[NSETOPTION] = {
{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-right", SET_OPTION_STRING, 0, 0, NULL }, { "status-right", SET_OPTION_STRING, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL }, { "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
}; };
int int

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-password.c,v 1.5 2009-06-25 16:47:00 nicm Exp $ */ /* $Id: cmd-set-password.c,v 1.3 2009-01-19 18:23:40 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.28 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: cmd-set-window-option.c,v 1.24 2009-01-30 00:24:49 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,7 +27,12 @@
* Set a window option. * Set a window option.
*/ */
int cmd_set_window_option_parse(struct cmd *, int, char **, char **);
int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *); int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_window_option_send(struct cmd *, struct buffer *);
void cmd_set_window_option_recv(struct cmd *, struct buffer *);
void cmd_set_window_option_free(struct cmd *);
size_t cmd_set_window_option_print(struct cmd *, char *, size_t);
const struct cmd_entry cmd_set_window_option_entry = { const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw", "set-window-option", "setw",
@@ -56,13 +61,11 @@ const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list }, SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, { "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL }, { "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list }, { "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL }, { "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL }, { "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL }, { "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-split-window.c,v 1.15 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: cmd-split-window.c,v 1.12 2009-04-03 17:21:46 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -141,8 +141,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window_pane *wp; struct window_pane *wp;
const char **env; const char **env;
char *cmd, *cwd, *cause; char *cmd, *cwd, *cause;
u_int hlimit; u_int hlimit, lines;
int lines;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1); return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-string.c,v 1.17 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: cmd-string.c,v 1.13 2009-02-16 19:29:17 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,7 +63,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
if ((t = strchr(s, ' ')) == NULL && (t = strchr(s, '\t')) == NULL) if ((t = strchr(s, ' ')) == NULL && (t = strchr(s, '\t')) == NULL)
t = strchr(s, '\0'); t = strchr(s, '\0');
if ((u = strchr(s, '=')) != NULL && u < t) { if ((u = strchr(s, '=')) != NULL && u < t) {
if (putenv(xstrdup(s)) != 0) { if (putenv(s) != 0) {
xasprintf(cause, "assignment failed: %s", s); xasprintf(cause, "assignment failed: %s", s);
return (-1); return (-1);
} }
@@ -274,7 +274,7 @@ cmd_string_variable(const char *s, size_t *p)
buf = xrealloc(buf, 1, len + 1); buf = xrealloc(buf, 1, len + 1);
buf[len++] = ch; buf[len++] = ch;
for (;;) { for(;;) {
ch = cmd_string_getc(s, p); ch = cmd_string_getc(s, p);
if (ch == EOF || !cmd_string_other(ch)) if (ch == EOF || !cmd_string_other(ch))
break; break;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-pane.c,v 1.6 2009-06-25 15:28:08 nicm Exp $ */ /* $Id: cmd-swap-pane.c,v 1.4 2009-04-03 17:21:46 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -158,7 +158,6 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
struct window *w; struct window *w;
struct window_pane *tmp_wp, *src_wp, *dst_wp; struct window_pane *tmp_wp, *src_wp, *dst_wp;
u_int xx, yy; u_int xx, yy;
int flags;
if (data == NULL) if (data == NULL)
return (0); return (0);
@@ -210,15 +209,10 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
xx = src_wp->xoff; xx = src_wp->xoff;
yy = src_wp->yoff; yy = src_wp->yoff;
flags = src_wp->flags;
src_wp->xoff = dst_wp->xoff; src_wp->xoff = dst_wp->xoff;
src_wp->yoff = dst_wp->yoff; src_wp->yoff = dst_wp->yoff;
src_wp->flags &= ~PANE_HIDDEN;
src_wp->flags |= dst_wp->flags & PANE_HIDDEN;
dst_wp->xoff = xx; dst_wp->xoff = xx;
dst_wp->yoff = yy; dst_wp->yoff = yy;
dst_wp->flags &= ~PANE_HIDDEN;
dst_wp->flags |= flags & PANE_HIDDEN;
xx = src_wp->sx; xx = src_wp->sx;
yy = src_wp->sy; yy = src_wp->sy;
@@ -226,10 +220,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
window_pane_resize(dst_wp, xx, yy); window_pane_resize(dst_wp, xx, yy);
if (!data->flag_detached) { if (!data->flag_detached) {
tmp_wp = dst_wp; window_set_active_pane(w, dst_wp);
if (tmp_wp->flags & PANE_HIDDEN)
tmp_wp = src_wp;
window_set_active_pane(w, tmp_wp);
layout_refresh(w, 0); layout_refresh(w, 0);
} }

13
cmd.c
View File

@@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.97 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: cmd.c,v 1.89 2009-04-03 17:21:46 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,10 +31,8 @@ const struct cmd_entry *cmd_table[] = {
&cmd_break_pane_entry, &cmd_break_pane_entry,
&cmd_choose_session_entry, &cmd_choose_session_entry,
&cmd_choose_window_entry, &cmd_choose_window_entry,
&cmd_clear_history_entry,
&cmd_clock_mode_entry, &cmd_clock_mode_entry,
&cmd_command_prompt_entry, &cmd_command_prompt_entry,
&cmd_confirm_before_entry,
&cmd_copy_buffer_entry, &cmd_copy_buffer_entry,
&cmd_copy_mode_entry, &cmd_copy_mode_entry,
&cmd_delete_buffer_entry, &cmd_delete_buffer_entry,
@@ -62,17 +60,16 @@ const struct cmd_entry *cmd_table[] = {
&cmd_next_layout_entry, &cmd_next_layout_entry,
&cmd_next_window_entry, &cmd_next_window_entry,
&cmd_paste_buffer_entry, &cmd_paste_buffer_entry,
&cmd_previous_layout_entry,
&cmd_previous_window_entry, &cmd_previous_window_entry,
&cmd_refresh_client_entry, &cmd_refresh_client_entry,
&cmd_rename_session_entry, &cmd_rename_session_entry,
&cmd_rename_window_entry, &cmd_rename_window_entry,
&cmd_resize_pane_entry, &cmd_resize_pane_down_entry,
&cmd_resize_pane_up_entry,
&cmd_respawn_window_entry, &cmd_respawn_window_entry,
&cmd_rotate_window_entry, &cmd_rotate_window_entry,
&cmd_save_buffer_entry, &cmd_save_buffer_entry,
&cmd_scroll_mode_entry, &cmd_scroll_mode_entry,
&cmd_select_layout_entry,
&cmd_select_pane_entry, &cmd_select_pane_entry,
&cmd_select_prompt_entry, &cmd_select_prompt_entry,
&cmd_select_window_entry, &cmd_select_window_entry,
@@ -108,10 +105,8 @@ cmd_parse(int argc, char **argv, char **cause)
int opt; int opt;
*cause = NULL; *cause = NULL;
if (argc == 0) { if (argc == 0)
xasprintf(cause, "no command");
return (NULL); return (NULL);
}
entry = NULL; entry = NULL;
for (entryp = cmd_table; *entryp != NULL; entryp++) { for (entryp = cmd_table; *entryp != NULL; entryp++) {

View File

@@ -1,4 +1,4 @@
/* $Id: colour.c,v 1.6 2009-05-18 15:42:30 nicm Exp $ */ /* $Id: colour.c,v 1.5 2009-03-07 10:29:06 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -48,6 +48,7 @@ colour_tostring(u_char c)
return (NULL); return (NULL);
} }
/* String to colour. */
int int
colour_fromstring(const char *s) colour_fromstring(const char *s)
{ {

228
compat.h
View File

@@ -1,228 +0,0 @@
/* $Id: compat.h,v 1.6 2009-07-02 07:30:59 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HAVE_PATHS_H
#define _PATH_BSHELL "/bin/sh"
#define _PATH_TMP "/tmp/"
#define _PATH_DEVNULL "/dev/null"
#define _PATH_TTY "/dev/tty"
#endif
#ifdef HAVE_QUEUE_H
#include <sys/queue.h>
#else
#include "compat/queue.h"
#endif
#ifdef HAVE_TREE_H
#include <sys/tree.h>
#else
#include "compat/tree.h"
#endif
#ifdef HAVE_BITSTRING_H
#include <bitstring.h>
#else
#include "compat/bitstring.h"
#endif
#ifdef HAVE_POLL
#include <poll.h>
#else
#include "compat/bsd-poll.h"
#endif
#ifdef HAVE_GETOPT
#include <getopt.h>
#endif
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_FORKPTY
#ifdef HAVE_LIBUTIL_H
#include <libutil.h>
#endif
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#endif
#ifdef HAVE_VIS
#include <vis.h>
#else
#include "compat/vis.h"
#endif
#ifndef INFTIM
#define INFTIM -1
#endif
#ifndef WAIT_ANY
#define WAIT_ANY -1
#endif
#ifndef SUN_LEN
#define SUN_LEN(sun) (sizeof (sun)->sun_path)
#endif
#ifndef __dead
#define __dead __attribute__ ((__noreturn__))
#endif
#ifndef __packed
#define __packed __attribute__ ((__packed__))
#endif
#ifndef timercmp
#define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
#ifndef timeradd
#define timeradd(tvp, uvp, vvp) \
do { \
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((vvp)->tv_usec >= 1000000) { \
(vvp)->tv_sec++; \
(vvp)->tv_usec -= 1000000; \
} \
} while (0)
#endif
#ifndef TTY_NAME_MAX
#define TTY_NAME_MAX 32
#endif
#ifndef HAVE_STRCASESTR
/* strcasestr.c */
char *strcasestr(const char *, const char *);
#endif
#ifndef HAVE_STRTONUM
/* strtonum.c */
long long strtonum(const char *, long long, long long, const char **);
#endif
#ifndef HAVE_STRLCPY
/* strlcpy.c */
size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef HAVE_STRLCAT
/* strlcat.c */
size_t strlcat(char *, const char *, size_t);
#endif
#ifndef HAVE_DAEMON
/* daemon.c */
int daemon(int, int);
#endif
#ifndef HAVE_FORKPTY
/* forkpty.c */
pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif
#ifndef HAVE_ASPRINTF
/* asprintf.c */
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_FGETLN
/* fgetln.c */
char *fgetln(FILE *, size_t *);
#endif
#ifndef HAVE_GETOPT
/* getopt.c */
extern int BSDopterr;
extern int BSDoptind;
extern int BSDoptopt;
extern int BSDoptreset;
extern char *BSDoptarg;
int BSDgetopt(int, char *const *, const char *);
#define getopt(ac, av, o) BSDgetopt(ac, av, o)
#define opterr BSDopterr
#define optind BSDoptind
#define optopt BSDoptopt
#define optreset BSDoptreset
#define optarg BSDoptarg
#endif
#ifndef HAVE_STRTONUM
/* strtonum.c */
long long strtonum(const char *, long long, long long, const char **);
#endif
#ifndef HAVE_STRLCPY
/* strlcpy.c */
size_t strlcpy(char *, const char *, size_t);
#endif
#ifndef HAVE_STRLCAT
/* strlcat.c */
size_t strlcat(char *, const char *, size_t);
#endif
#ifndef HAVE_DAEMON
/* daemon.c */
int daemon(int, int);
#endif
#ifndef HAVE_FORKPTY
/* forkpty.c */
pid_t forkpty(int *, char *, struct termios *, struct winsize *);
#endif
#ifndef HAVE_ASPRINTF
/* asprintf.c */
int asprintf(char **, const char *, ...);
int vasprintf(char **, const char *, va_list);
#endif
#ifndef HAVE_FGETLN
/* fgetln.c */
char *fgetln(FILE *, size_t *);
#endif
#ifndef HAVE_GETOPT
/* getopt.c */
extern int BSDopterr;
extern int BSDoptind;
extern int BSDoptopt;
extern int BSDoptreset;
extern char *BSDoptarg;
int BSDgetopt(int, char *const *, const char *);
#define getopt(ac, av, o) BSDgetopt(ac, av, o)
#define opterr BSDopterr
#define optind BSDoptind
#define optopt BSDoptopt
#define optreset BSDoptreset
#define optarg BSDoptarg
#endif

View File

@@ -1,129 +0,0 @@
/* $Id: bitstring.h,v 1.1 2009-06-25 17:02:59 nicm Exp $ */
/* $OpenBSD: bitstring.h,v 1.5 2003/06/02 19:34:12 millert Exp $ */
/* $NetBSD: bitstring.h,v 1.5 1997/05/14 15:49:55 pk Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Paul Vixie.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bitstring.h 8.1 (Berkeley) 7/19/93
*/
#ifndef _BITSTRING_H_
#define _BITSTRING_H_
/* modified for SV/AT and bitstring bugfix by M.R.Murphy, 11oct91
* bitstr_size changed gratuitously, but shorter
* bit_alloc spelling error fixed
* the following were efficient, but didn't work, they've been made to
* work, but are no longer as efficient :-)
* bit_nclear, bit_nset, bit_ffc, bit_ffs
*/
typedef unsigned char bitstr_t;
/* internal macros */
/* byte of the bitstring bit is in */
#define _bit_byte(bit) \
((bit) >> 3)
/* mask for the bit within its byte */
#define _bit_mask(bit) \
(1 << ((bit)&0x7))
/* external macros */
/* bytes in a bitstring of nbits bits */
#define bitstr_size(nbits) \
(((nbits) + 7) >> 3)
/* allocate a bitstring */
#define bit_alloc(nbits) \
(bitstr_t *)calloc((size_t)bitstr_size(nbits), sizeof(bitstr_t))
/* allocate a bitstring on the stack */
#define bit_decl(name, nbits) \
((name)[bitstr_size(nbits)])
/* is bit N of bitstring name set? */
#define bit_test(name, bit) \
((name)[_bit_byte(bit)] & _bit_mask(bit))
/* set bit N of bitstring name */
#define bit_set(name, bit) \
((name)[_bit_byte(bit)] |= _bit_mask(bit))
/* clear bit N of bitstring name */
#define bit_clear(name, bit) \
((name)[_bit_byte(bit)] &= ~_bit_mask(bit))
/* clear bits start ... stop in bitstring */
#define bit_nclear(name, start, stop) do { \
register bitstr_t *_name = name; \
register int _start = start, _stop = stop; \
while (_start <= _stop) { \
bit_clear(_name, _start); \
_start++; \
} \
} while(0)
/* set bits start ... stop in bitstring */
#define bit_nset(name, start, stop) do { \
register bitstr_t *_name = name; \
register int _start = start, _stop = stop; \
while (_start <= _stop) { \
bit_set(_name, _start); \
_start++; \
} \
} while(0)
/* find first bit clear in name */
#define bit_ffc(name, nbits, value) do { \
register bitstr_t *_name = name; \
register int _bit, _nbits = nbits, _value = -1; \
for (_bit = 0; _bit < _nbits; ++_bit) \
if (!bit_test(_name, _bit)) { \
_value = _bit; \
break; \
} \
*(value) = _value; \
} while(0)
/* find first bit set in name */
#define bit_ffs(name, nbits, value) do { \
register bitstr_t *_name = name; \
register int _bit, _nbits = nbits, _value = -1; \
for (_bit = 0; _bit < _nbits; ++_bit) \
if (bit_test(_name, _bit)) { \
_value = _bit; \
break; \
} \
*(value) = _value; \
} while(0)
#endif /* !_BITSTRING_H_ */

View File

@@ -1,4 +1,4 @@
/* $Id: bsd-poll.c,v 1.2 2009-05-13 23:50:42 nicm Exp $ */ /* $Id: bsd-poll.c,v 1.1 2008-08-28 17:45:30 nicm Exp $ */
/* /*
* Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au).
@@ -29,8 +29,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include "bsd-poll.h"
#include "compat/bsd-poll.h"
/* /*
* A minimal implementation of poll(2), built on top of select(2). * A minimal implementation of poll(2), built on top of select(2).

View File

@@ -27,6 +27,7 @@
/* OPENBSD ORIGINAL: sys/sys/poll.h */ /* OPENBSD ORIGINAL: sys/sys/poll.h */
#if !defined(HAVE_POLL) && !defined(HAVE_POLL_H)
#ifndef _COMPAT_POLL_H_ #ifndef _COMPAT_POLL_H_
#define _COMPAT_POLL_H_ #define _COMPAT_POLL_H_
@@ -57,3 +58,4 @@ typedef unsigned int nfds_t;
int poll(struct pollfd *, nfds_t, int); int poll(struct pollfd *, nfds_t, int);
#endif /* !_COMPAT_POLL_H_ */ #endif /* !_COMPAT_POLL_H_ */
#endif /* !HAVE_POLL_H */

View File

@@ -32,7 +32,7 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_PATHS_H #ifndef NO_PATHS_H
#include <paths.h> #include <paths.h>
#endif #endif

View File

@@ -1,4 +1,3 @@
/* $Id: fgetln.c,v 1.5 2009-04-29 22:45:32 nicm Exp $ */
/* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */ /* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */
/*- /*-

83
compat/forkpty-irix.c Normal file
View File

@@ -0,0 +1,83 @@
/* $Id: forkpty-irix.c,v 1.2 2008-09-26 06:45:28 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include "tmux.h"
pid_t
forkpty(int *master,
unused char *name, unused struct termios *tio, struct winsize *ws)
{
int slave, fd;
char *path;
pid_t pid;
void *old;
path = _getpty(master, O_RDWR, 0622, 0);
if (path == NULL)
goto out;
if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
goto out;
switch (pid = fork()) {
case -1:
goto out;
case 0:
close(*master);
setsid();
old = signal(SIGHUP, SIG_IGN);
vhangup();
signal(SIGHUP, old);
if ((fd = open(path, O_RDWR)) == -1)
fatal("open failed");
close(slave);
slave = fd;
if (ioctl(slave, TIOCSWINSZ, ws) == -1)
fatal("ioctl failed");
dup2(slave, 0);
dup2(slave, 1);
dup2(slave, 2);
if (slave > 2)
close(slave);
return (0);
}
close(slave);
return (pid);
out:
if (*master != -1)
close(*master);
if (slave != -1)
close(slave);
return (-1);
}

View File

@@ -1,117 +0,0 @@
/* $Id: getopt.c,v 1.1 2009-05-13 22:20:48 nicm Exp $ */
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt.c */
#include "tmux.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int BSDopterr = 1, /* if error message should be printed */
BSDoptind = 1, /* index into parent argv vector */
BSDoptopt, /* character checked for validity */
BSDoptreset; /* reset getopt */
char *BSDoptarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
BSDgetopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (ostr == NULL)
return (-1);
if (BSDoptreset || !*place) { /* update scanning pointer */
BSDoptreset = 0;
if (BSDoptind >= nargc || *(place = nargv[BSDoptind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++BSDoptind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((BSDoptopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, BSDoptopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (BSDoptopt == (int)'-')
return (-1);
if (!*place)
++BSDoptind;
if (BSDopterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __progname, BSDoptopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
BSDoptarg = NULL;
if (!*place)
++BSDoptind;
}
else { /* need an argument */
if (*place) /* no white space */
BSDoptarg = place;
else if (nargc <= ++BSDoptind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (BSDopterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
__progname, BSDoptopt);
return (BADCH);
}
else /* white space */
BSDoptarg = nargv[BSDoptind];
place = EMSG;
++BSDoptind;
}
return (BSDoptopt); /* dump back option letter */
}

76
compat/getopt.h Normal file
View File

@@ -0,0 +1,76 @@
/* $OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $ */
/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GETOPT_H_
#define _GETOPT_H_
#include <sys/cdefs.h>
/*
* GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
*/
#define no_argument 0
#define required_argument 1
#define optional_argument 2
struct option {
/* name of long option */
const char *name;
/*
* one of no_argument, required_argument, and optional_argument:
* whether option takes an argument
*/
int has_arg;
/* if not NULL, set *flag to val when option found */
int *flag;
/* if flag not NULL, value to set *flag to; else return value */
int val;
};
int getopt_long(int, char * const *, const char *,
const struct option *, int *);
int getopt_long_only(int, char * const *, const char *,
const struct option *, int *);
#ifndef _GETOPT_DEFINED_
#define _GETOPT_DEFINED_
int getopt(int, char * const *, const char *);
int getsubopt(char **, char * const *, char **);
extern char *optarg; /* getopt(3) external variables */
extern int opterr;
extern int optind;
extern int optopt;
extern int optreset;
extern char *suboptarg; /* getsubopt(3) external variable */
#endif
#endif /* !_GETOPT_H_ */

523
compat/getopt_long.c Normal file
View File

@@ -0,0 +1,523 @@
/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* #include <err.h> */
#include <errno.h>
/* #include <getopt.h> */
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
int
warnx(const char *fmt, ...)
{
}
#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
#ifdef REPLACE_GETOPT
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#endif
#define PRINT_ERROR ((opterr) && (*options != ':'))
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#define EMSG ""
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
const struct option *, int *, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
static char *place = EMSG; /* option letter processing */
/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
/*
* Compute the greatest common divisor of a and b.
*/
static int
gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return (b);
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
/* LINTED const cast */
((char **) nargv)[pos] = nargv[cstart];
/* LINTED const cast */
((char **)nargv)[cstart] = swap;
}
}
}
/*
* parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int
parse_long_options(char * const *nargv, const char *options,
const struct option *long_options, int *idx, int short_too)
{
char *current_argv, *has_equal;
size_t current_argv_len;
int i, match;
current_argv = place;
match = -1;
optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* partial match */
match = i;
else {
/* ambiguous abbreviation */
if (PRINT_ERROR)
warnx(ambig, (int)current_argv_len,
current_argv);
optopt = 0;
return (BADCH);
}
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
warnx(noarg, (int)current_argv_len,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
return (BADARG);
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
optarg = nargv[optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
warnx(recargstring,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
--optind;
return (BADARG);
}
} else { /* unknown option */
if (short_too) {
--optind;
return (-1);
}
if (PRINT_ERROR)
warnx(illoptstring, current_argv);
optopt = 0;
return (BADCH);
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return (0);
} else
return (long_options[match].val);
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
static int posixly_correct = -1;
if (options == NULL)
return (-1);
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*/
if (posixly_correct == -1)
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
else if (*options == '-')
flags |= FLAG_ALLARGS;
if (*options == '+' || *options == '-')
options++;
/*
* XXX Some GNU programs (like cvs) set optind to 0 instead of
* XXX using optreset. Work around this braindamage.
*/
if (optind == 0)
optind = optreset = 1;
optarg = NULL;
if (optreset)
nonopt_start = nonopt_end = -1;
start:
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc) { /* end of argument vector */
place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set optind
* to the first of them.
*/
optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
return (INORDER);
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return (-1);
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = optind;
else if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
nonopt_start = optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = optind;
/*
* If we have "-" do nothing, if "--" we are done.
*/
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
optind++;
place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are getopt_long_only()
*/
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
if (*place == '-')
place++; /* --foo long option */
else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
idx, short_too);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
if ((optchar = (int)*place++) == (int)':' ||
(optchar == (int)'-' && *place != '\0') ||
(oli = strchr(options, optchar)) == NULL) {
/*
* If the user specified "-" and '-' isn't listed in
* options, return -1 (non-option) as per POSIX.
* Otherwise, it is an unknown option character (or ':').
*/
if (optchar == (int)'-' && *place == '\0')
return (-1);
if (!*place)
++optind;
if (PRINT_ERROR)
warnx(illoptchar, optchar);
optopt = optchar;
return (BADCH);
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*place) /* no space */
/* NOTHING */;
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
optchar = parse_long_options(nargv, options, long_options,
idx, 0);
place = EMSG;
return (optchar);
}
if (*++oli != ':') { /* doesn't take argument */
if (!*place)
++optind;
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
}
place = EMSG;
++optind;
}
/* dump back option letter */
return (optchar);
}
#ifdef REPLACE_GETOPT
/*
* getopt --
* Parse argc/argv argument vector.
*
* [eventually this will replace the BSD getopt]
*/
int
getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We don't pass FLAG_PERMUTE to getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
#endif /* REPLACE_GETOPT */
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE));
}
/*
* getopt_long_only --
* Parse argc/argv argument vector.
*/
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY));
}

View File

@@ -1,61 +0,0 @@
/* $Id: strcasestr.c,v 1.1 2009-07-02 07:31:02 nicm Exp $ */
/* $OpenBSD: strcasestr.c,v 1.3 2006/03/31 05:34:55 deraadt Exp $ */
/* $NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <ctype.h>
#include <string.h>
/*
* Find the first occurrence of find in s, ignore case.
*/
char *
strcasestr(const char *s, const char *find)
{
char c, sc;
size_t len;
if ((c = *find++) != 0) {
c = (char)tolower((unsigned char)c);
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
} while ((char)tolower((unsigned char)sc) != c);
} while (strncasecmp(s, find, len) != 0);
s--;
}
return ((char *)s);
}

View File

@@ -1,5 +1,4 @@
/* $Id: tree.h,v 1.4 2009-05-26 18:31:10 nicm Exp $ */ /* $OpenBSD: tree.h,v 1.11 2008/05/11 22:19:09 millert Exp $ */
/* $OpenBSD: tree.h,v 1.12 2009/03/02 09:42:55 mikeb Exp $ */
/* /*
* Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved. * All rights reserved.
@@ -330,7 +329,7 @@ struct { \
} while (0) } while (0)
#ifndef RB_AUGMENT #ifndef RB_AUGMENT
#define RB_AUGMENT(x) do {} while (0) #define RB_AUGMENT(x)
#endif #endif
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \

View File

@@ -32,8 +32,7 @@
#include <limits.h> #include <limits.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <vis.h>
#include "tmux.h"
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define isvisible(c) \ #define isvisible(c) \

View File

@@ -1,4 +1,3 @@
/* $Id: vis.h,v 1.5 2009-07-01 23:22:46 nicm Exp $ */
/* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 millert Exp $ */ /* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 millert Exp $ */
/* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ /* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */
@@ -72,6 +71,8 @@
*/ */
#define UNVIS_END 1 /* no more characters */ #define UNVIS_END 1 /* no more characters */
#include <sys/cdefs.h>
char *vis(char *, int, int, int); char *vis(char *, int, int, int);
int strvis(char *, const char *, int); int strvis(char *, const char *, int);
int strnvis(char *, const char *, size_t, int); int strnvis(char *, const char *, size_t, int);

216
configure vendored
View File

@@ -1,216 +0,0 @@
#!/bin/sh
# $Id: configure,v 1.17 2009-07-02 07:31:01 nicm Exp $
TMUX_PLATFORM=${TMUX_PLATFORM:-`uname -s`}
CONFIG_H=config.h
rm -f $CONFIG_H
echo "/* $TMUX_PLATFORM */" >$CONFIG_H
CONFIG_MK=config.mk
rm -f $CONFIG_MK
echo "# $TMUX_PLATFORM" >$CONFIG_MK
cat <<EOF >>$CONFIG_H
#undef HAVE_ASPRINTF
#undef HAVE_CRYPT_H
#undef HAVE_DAEMON
#undef HAVE_FGETLN
#undef HAVE_FORKPTY
#undef HAVE_GETOPT
#undef HAVE_LIBUTIL_H
#undef HAVE_PATHS_H
#undef HAVE_POLL
#undef HAVE_PROGNAME
#undef HAVE_PTY_H
#undef HAVE_QUEUE_H
#undef HAVE_SETPROCTITLE
#undef HAVE_STRCASESTR
#undef HAVE_STRLCAT
#undef HAVE_STRLCPY
#undef HAVE_STRTONUM
#undef HAVE_TREE_H
#undef HAVE_UTIL_H
#undef HAVE_VIS
EOF
case $TMUX_PLATFORM in
# ------------------------------------------------------------------------------
OpenBSD)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_BITSTRING_H
#define HAVE_DAEMON
#define HAVE_FGETLN
#define HAVE_FORKPTY
#define HAVE_GETOPT
#define HAVE_PATHS_H
#define HAVE_POLL
#define HAVE_PROGNAME
#define HAVE_QUEUE_H
#define HAVE_SETPROCTITLE
#define HAVE_STRCASESTR
#define HAVE_STRLCAT
#define HAVE_STRLCPY
#define HAVE_STRTONUM
#define HAVE_TREE_H
#define HAVE_UTIL_H
#define HAVE_VIS
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-openbsd.c
LIBS+= -lutil
EOF
;;
# ------------------------------------------------------------------------------
Linux)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_DAEMON
#define HAVE_FORKPTY
#define HAVE_PATHS_H
#define HAVE_POLL
#define HAVE_PROGNAME
#define HAVE_PTY_H
#define HAVE_STRCASESTR
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-linux.c \
compat/fgetln.c \
compat/strlcat.c \
compat/strlcpy.c \
compat/strtonum.c \
compat/getopt.c \
compat/vis.c
CFLAGS+= -D_GNU_SOURCE -D_POSIX_SOURCE
LIBS+= -lcrypt -lutil
EOF
;;
# ------------------------------------------------------------------------------
AIX)
cat <<EOF >>$CONFIG_H
#define HAVE_DAEMON
EOF
cat <<EOF >>$CONFIG_MK
CPPFLAGS+= -I/usr/local/include/ncurses
SRCS+= osdep-unknown.c \
compat/asprintf.c \
compat/bsd-poll.c \
compat/daemon.c \
compat/forkpty-aix.c \
compat/strcasestr.c \
compat/strlcat.c \
compat/strlcpy.c \
compat/strtonum.c \
compat/fgetln.c \
compat/getopt.c \
compat/vis.c
EOF
;;
# ------------------------------------------------------------------------------
SunOS)
cat <<EOF >>$CONFIG_H
#define HAVE_CRYPT_H
#define HAVE_POLL
#define HAVE_STRLCAT
#define HAVE_STRLCPY
EOF
cat <<EOF >>$CONFIG_MK
CPPFLAGS+= -I/usr/local/include/ncurses \
-I/opt/csw/include -I/opt/csw/include/ncurses \
-I/opt/sfw/include -I/opt/sfw/include/ncurses
LDFLAGS+= -L/usr/gnu/lib \
-L/opt/csw/lib \
-L/opt/sfw/lib
LIBS+= -lsocket -lnsl
SRCS+= osdep-unknown.c \
compat/asprintf.c \
compat/daemon.c \
compat/fgetln.c \
compat/forkpty-sunos.c \
compat/getopt.c \
compat/strcasestr.c \
compat/strtonum.c \
compat/vis.c
EOF
;;
# ------------------------------------------------------------------------------
Darwin)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_DAEMON
#define HAVE_FGETLN
#define HAVE_FORKPTY
#define HAVE_GETOPT
#define HAVE_PATHS_H
#define HAVE_PROGNAME
#define HAVE_STRCASESTR
#define HAVE_STRLCAT
#define HAVE_STRLCPY
#define HAVE_UTIL_H
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-darwin.c \
compat/bsd-poll.c \
compat/strtonum.c \
compat/vis.c
EOF
;;
# ------------------------------------------------------------------------------
FreeBSD|DragonFly)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_DAEMON
#define HAVE_FGETLN
#define HAVE_FORKPTY
#define HAVE_GETOPT
#define HAVE_LIBUTIL_H
#define HAVE_PATHS_H
#define HAVE_POLL
#define HAVE_PROGNAME
#define HAVE_SETPROCTITLE
#define HAVE_STRCASESTR
#define HAVE_STRLCAT
#define HAVE_STRLCPY
#define HAVE_STRTONUM
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-freebsd.c \
compat/vis.c
LIBS+= -lcrypt -lutil
EOF
;;
# ------------------------------------------------------------------------------
NetBSD)
cat <<EOF >>$CONFIG_H
#define HAVE_ASPRINTF
#define HAVE_DAEMON
#define HAVE_FGETLN
#define HAVE_FORKPTY
#define HAVE_GETOPT
#define HAVE_PATHS_H
#define HAVE_POLL
#define HAVE_PROGNAME
#define HAVE_SETPROCTITLE
#define HAVE_STRCASESTR
#define HAVE_STRLCAT
#define HAVE_STRLCPY
#define HAVE_UTIL_H
EOF
cat <<EOF >>$CONFIG_MK
SRCS+= osdep-netbsd.c \
compat/strtonum.c \
compat/vis.c
LIBS+= -lcrypt -lutil
CPPFLAGS+= -I/usr/pkg/include
LDFLAGS+= -L/usr/pkg/lib
EOF
;;
# ------------------------------------------------------------------------------
*)
echo Unable to configure for $TMUX_PLATFORM
exit 1
esac
echo Configured for $TMUX_PLATFORM
exit 0

View File

@@ -1,7 +1,7 @@
" Vim syntax file " Vim syntax file
" Language: tmux(1) configuration file " Language: tmux(1) configuration file
" Maintainer: Tiago Cunha <me@tiagocunha.org> " Maintainer: Tiago Cunha <me@tiagocunha.org>
" Last Change: $Date: 2009-07-02 13:50:27 $ " Last Change: $Date: 2009-02-08 01:54:23 $
if version < 600 if version < 600
syntax clear syntax clear
@@ -16,12 +16,12 @@ syn keyword tmuxAction any current none
syn keyword tmuxBoolean off on syn keyword tmuxBoolean off on
syn keyword tmuxCmds detach[-client] ls list-sessions neww new-window syn keyword tmuxCmds detach[-client] ls list-sessions neww new-window
syn keyword tmuxCmds bind[-key] unbind[-key] prev[ious-window] last[-window] syn keyword tmuxCmds bind[-key] unbind[-key] prev[ious-window] last
syn keyword tmuxCmds lsk list-keys set[-option] renamew rename-window selectw syn keyword tmuxCmds last[-window] lsk list-keys set[-option] renamew
syn keyword tmuxCmds select-window lsw list-windows attach[-session] syn keyword tmuxCmds rename-window selectw select-window lsw list-windows
syn keyword tmuxCmds send-prefix refresh[-client] killw kill-window lsc syn keyword tmuxCmds attach[-session] send-prefix refresh[-client] killw
syn keyword tmuxCmds list-clients linkw link-window unlinkw unlink-window syn keyword tmuxCmds kill-window lsc list-clients linkw link-window unlinkw
syn keyword tmuxCmds next[-window] send[-keys] swapw swap-window syn keyword tmuxCmds unlink-window next[-window] send[-keys] swapw swap-window
syn keyword tmuxCmds rename[-session] kill-session switchc switch-client syn keyword tmuxCmds rename[-session] kill-session switchc switch-client
syn keyword tmuxCmds has[-session] scroll-mode copy-mode pasteb paste-buffer syn keyword tmuxCmds has[-session] scroll-mode copy-mode pasteb paste-buffer
syn keyword tmuxCmds new[-session] start[-server] kill-server setw syn keyword tmuxCmds new[-session] start[-server] kill-server setw
@@ -31,27 +31,24 @@ syn keyword tmuxCmds list-buffers deleteb delete-buffer lscm list-commands
syn keyword tmuxCmds movew move-window select-prompt respawnw respawn-window syn keyword tmuxCmds movew move-window select-prompt respawnw respawn-window
syn keyword tmuxCmds source[-file] info server-info clock-mode lock[-server] syn keyword tmuxCmds source[-file] info server-info clock-mode lock[-server]
syn keyword tmuxCmds pass set-password saveb save-buffer downp down-pane killp syn keyword tmuxCmds pass set-password saveb save-buffer downp down-pane killp
syn keyword tmuxCmds kill-pane resizep resize-pane selectp select-pane swapp syn keyword tmuxCmds kill-pane resizep-down resize-pane-down resizep-up
syn keyword tmuxCmds swap-pane splitw split-window upp up-pane choose-session syn keyword tmuxCmds resize-pane-up selectp select-pane splitw split-window
syn keyword tmuxCmds choose-window loadb load-buffer copyb copy-buffer suspendc syn keyword tmuxCmds upp up-pane choose-session choose-window loadb load-buffer
syn keyword tmuxCmds suspend-client findw find-window breakp break-pane nextl syn keyword tmuxCmds copyb copy-buffer suspendc suspend-client findw
syn keyword tmuxCmds next-layout rotatew rotate-window confirm[-before] syn keyword tmuxCmds find-window
syn keyword tmuxCmds clearhist clear-history selectl select-layout
syn keyword tmuxOptsSet prefix status status-fg status-bg bell-action syn keyword tmuxOptsSet prefix status status-fg status-bg bell-action
syn keyword tmuxOptsSet default-command history-limit status-left status-right syn keyword tmuxOptsSet default-command history-limit status-left status-right
syn keyword tmuxOptsSet status-interval set-titles display-time buffer-limit syn keyword tmuxOptsSet status-interval set-titles display-time buffer-limit
syn keyword tmuxOptsSet status-left-length status-right-length message-fg syn keyword tmuxOptsSet status-left-length status-right-length message-fg
syn keyword tmuxOptsSet message-bg lock-after-time default-path repeat-time syn keyword tmuxOptsSet message-bg lock-after-time default-path repeat-time
syn keyword tmuxOptsSet message-attr status-attr status-keys set-remain-on-exit syn keyword tmuxOptsSet message-attr status-attr
syn keyword tmuxOptsSet status-utf8
syn keyword tmuxOptsSetw monitor-activity aggressive-resize force-width syn keyword tmuxOptsSetw monitor-activity aggressive-resize force-width
syn keyword tmuxOptsSetw force-height remain-on-exit uft8 mode-fg mode-bg syn keyword tmuxOptsSetw force-height remain-on-exit uft8 mode-fg mode-bg
syn keyword tmuxOptsSetw mode-keys clock-mode-colour clock-mode-style syn keyword tmuxOptsSetw mode-keys clock-mode-colour clock-mode-style
syn keyword tmuxOptsSetw xterm-keys mode-attr window-status-attr syn keyword tmuxOptsSetw xterm-keys mode-attr window-status-attr
syn keyword tmuxOptsSetw window-status-bg window-status-fg automatic-rename syn keyword tmuxOptsSetw window-status-bg window-status-fg automatic-rename
syn keyword tmuxOptsSetw main-pane-width main-pane-height monitor-content
syn keyword tmuxTodo FIXME NOTE TODO XXX contained syn keyword tmuxTodo FIXME NOTE TODO XXX contained

View File

@@ -1,4 +1,4 @@
/* $Id: grid-view.c,v 1.15 2009-07-01 19:14:33 nicm Exp $ */ /* $Id: grid-view.c,v 1.11 2009-03-28 20:17:29 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -133,7 +133,7 @@ grid_view_insert_lines(struct grid *gd, u_int py, u_int ny)
/* Insert lines in region. */ /* Insert lines in region. */
void void
grid_view_insert_lines_region( grid_view_insert_lines_region(
struct grid *gd, unused u_int rupper, u_int rlower, u_int py, u_int ny) struct grid *gd, u_int rupper, u_int rlower, u_int py, u_int ny)
{ {
GRID_DEBUG( GRID_DEBUG(
gd, "rupper=%u, rlower=%u, py=%u, ny=%u", rupper, rlower, py, ny); gd, "rupper=%u, rlower=%u, py=%u, ny=%u", rupper, rlower, py, ny);
@@ -158,13 +158,12 @@ grid_view_delete_lines(struct grid *gd, u_int py, u_int ny)
sy = grid_view_y(gd, gd->sy); sy = grid_view_y(gd, gd->sy);
grid_move_lines(gd, py, py + ny, sy - py - ny); grid_move_lines(gd, py, py + ny, sy - py - ny);
grid_clear(gd, 0, sy - ny, gd->sx, py + ny - (sy - ny));
} }
/* Delete lines inside scroll region. */ /* Delete lines inside scroll region. */
void void
grid_view_delete_lines_region( grid_view_delete_lines_region(
struct grid *gd, unused u_int rupper, u_int rlower, u_int py, u_int ny) struct grid *gd, u_int rupper, u_int rlower, u_int py, u_int ny)
{ {
GRID_DEBUG( GRID_DEBUG(
gd, "rupper=%u, rlower=%u, py=%u, ny=%u", rupper, rlower, py, ny); gd, "rupper=%u, rlower=%u, py=%u, ny=%u", rupper, rlower, py, ny);
@@ -192,7 +191,7 @@ grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx)
if (px == sx - 1) if (px == sx - 1)
grid_clear(gd, px, py, 1, 1); grid_clear(gd, px, py, 1, 1);
else else
grid_move_cells(gd, px + nx, px, py, sx - px - nx); grid_move_cells(gd, px + nx, px, py, (sx - 1) - (px + nx));
} }
/* Delete characters. */ /* Delete characters. */
@@ -208,18 +207,5 @@ grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx)
sx = grid_view_x(gd, gd->sx); sx = grid_view_x(gd, gd->sx);
grid_move_cells(gd, px, px + nx, py, sx - px - nx); grid_move_cells(gd, px, px + nx, py, (sx - 1) - (px + nx));
grid_clear(gd, sx - nx, py, px + nx - (sx - nx), 1);
}
/* Convert cells into a string. */
char *
grid_view_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
px = grid_view_x(gd, px);
py = grid_view_y(gd, py);
return (grid_string_cells(gd, px, py, nx));
} }

74
grid.c
View File

@@ -1,4 +1,4 @@
/* $Id: grid.c,v 1.21 2009-06-25 16:34:50 nicm Exp $ */ /* $Id: grid.c,v 1.15 2009-03-30 19:44:55 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -430,6 +430,31 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
} }
} }
/* Clear a group of cells. */
void
grid_clear_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
u_int xx;
GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
if (nx == 0)
return;
if (grid_check_x(gd, px) != 0)
return;
if (grid_check_x(gd, px + nx - 1) != 0)
return;
if (grid_check_y(gd, py) != 0)
return;
for (xx = px; xx < px + nx; xx++) {
if (xx >= gd->size[py])
break;
grid_put_cell(gd, xx, py, &grid_default_cell);
}
}
/* Move a group of cells. */ /* Move a group of cells. */
void void
grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx) grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
@@ -469,51 +494,4 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
} }
} }
/* Convert cells into a string. */
char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
{
const struct grid_cell *gc;
const struct grid_utf8 *gu;
char *buf;
size_t len, off;
u_int xx, i;
GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
len = 128;
buf = xmalloc(len);
off = 0;
for (xx = px; xx < px + nx; xx++) {
gc = grid_peek_cell(gd, xx, py);
if (gc->flags & GRID_FLAG_PADDING)
continue;
if (gc->flags & GRID_FLAG_UTF8) {
while (len < off + UTF8_SIZE + 1) {
buf = xrealloc(buf, 2, len);
len *= 2;
}
gu = grid_peek_utf8(gd, xx, py);
for (i = 0; i < UTF8_SIZE; i++) {
if (gu->data[i] == 0xff)
break;
buf[off++] = gu->data[i];
}
} else {
while (len < off + 2) {
buf = xrealloc(buf, 2, len);
len *= 2;
}
buf[off++] = gc->data;
}
}
while (off > 0 && buf[off - 1] == ' ')
off--;
buf[off] = '\0';
return (buf);
}

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -1,4 +1,4 @@
<!-- $Id: index.html.in,v 1.1 2009-05-17 18:20:59 nicm Exp $ --> <!-- $Id: index.html.in,v 1.6 2009-04-21 20:10:22 nicm Exp $ -->
<html> <html>
<head> <head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="content-type" content="text/html; charset=UTF-8">

View File

@@ -1,4 +1,4 @@
/* $Id: input-keys.c,v 1.27 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: input-keys.c,v 1.26 2009-03-02 18:05:40 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>

171
input.c
View File

@@ -1,4 +1,4 @@
/* $Id: input.c,v 1.86 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: input.c,v 1.76 2009-03-28 20:17:29 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -67,7 +67,6 @@ void input_handle_sequence_cud(struct input_ctx *);
void input_handle_sequence_cuf(struct input_ctx *); void input_handle_sequence_cuf(struct input_ctx *);
void input_handle_sequence_cub(struct input_ctx *); void input_handle_sequence_cub(struct input_ctx *);
void input_handle_sequence_dch(struct input_ctx *); void input_handle_sequence_dch(struct input_ctx *);
void input_handle_sequence_cbt(struct input_ctx *);
void input_handle_sequence_dl(struct input_ctx *); void input_handle_sequence_dl(struct input_ctx *);
void input_handle_sequence_ich(struct input_ctx *); void input_handle_sequence_ich(struct input_ctx *);
void input_handle_sequence_il(struct input_ctx *); void input_handle_sequence_il(struct input_ctx *);
@@ -75,7 +74,6 @@ void input_handle_sequence_vpa(struct input_ctx *);
void input_handle_sequence_hpa(struct input_ctx *); void input_handle_sequence_hpa(struct input_ctx *);
void input_handle_sequence_cup(struct input_ctx *); void input_handle_sequence_cup(struct input_ctx *);
void input_handle_sequence_cup(struct input_ctx *); void input_handle_sequence_cup(struct input_ctx *);
void input_handle_sequence_tbc(struct input_ctx *);
void input_handle_sequence_ed(struct input_ctx *); void input_handle_sequence_ed(struct input_ctx *);
void input_handle_sequence_el(struct input_ctx *); void input_handle_sequence_el(struct input_ctx *);
void input_handle_sequence_sm(struct input_ctx *); void input_handle_sequence_sm(struct input_ctx *);
@@ -103,10 +101,8 @@ const struct input_sequence_entry input_sequence_table[] = {
{ 'L', input_handle_sequence_il }, { 'L', input_handle_sequence_il },
{ 'M', input_handle_sequence_dl }, { 'M', input_handle_sequence_dl },
{ 'P', input_handle_sequence_dch }, { 'P', input_handle_sequence_dch },
{ 'Z', input_handle_sequence_cbt },
{ 'd', input_handle_sequence_vpa }, { 'd', input_handle_sequence_vpa },
{ 'f', input_handle_sequence_cup }, { 'f', input_handle_sequence_cup },
{ 'g', input_handle_sequence_tbc },
{ 'h', input_handle_sequence_sm }, { 'h', input_handle_sequence_sm },
{ 'l', input_handle_sequence_rm }, { 'l', input_handle_sequence_rm },
{ 'm', input_handle_sequence_sgr }, { 'm', input_handle_sequence_sgr },
@@ -398,34 +394,15 @@ input_state_sequence_first(u_char ch, struct input_ctx *ictx)
ictx->private = '\0'; ictx->private = '\0';
ARRAY_CLEAR(&ictx->args); ARRAY_CLEAR(&ictx->args);
/* Most C0 control are accepted within CSI. */
if (INPUT_C0CONTROL(ch)) {
if (ch == 0x1b) { /* ESC */
/* Abort sequence and begin with new. */
input_state(ictx, input_state_escape);
return;
} else if (ch == 0x18 || ch == 0x1a) { /* CAN and SUB */
/* Abort sequence. */
input_state(ictx, input_state_first);
return;
}
/* Handle C0 immediately. */
input_handle_c0_control(ch, ictx);
/*
* Just come back to this state, in case the next character
* is the start of a private sequence.
*/
return;
}
input_state(ictx, input_state_sequence_next); input_state(ictx, input_state_sequence_next);
/* Private sequence: always the first character. */ if (INPUT_PARAMETER(ch)) {
if (ch >= 0x3c && ch <= 0x3f) { input_new_argument(ictx);
ictx->private = ch; if (ch >= 0x3c && ch <= 0x3f) {
return; /* Private control sequence. */
ictx->private = ch;
return;
}
} }
/* Pass character on directly. */ /* Pass character on directly. */
@@ -446,9 +423,6 @@ input_state_sequence_next(u_char ch, struct input_ctx *ictx)
} }
if (INPUT_PARAMETER(ch)) { if (INPUT_PARAMETER(ch)) {
if (ARRAY_EMPTY(&ictx->args))
input_new_argument(ictx);
if (ch == ';') { if (ch == ';') {
if (input_add_argument(ictx, '\0') != 0) if (input_add_argument(ictx, '\0') != 0)
input_state(ictx, input_state_first); input_state(ictx, input_state_first);
@@ -469,24 +443,6 @@ input_state_sequence_next(u_char ch, struct input_ctx *ictx)
return; return;
} }
/* Most C0 control are accepted within CSI. */
if (INPUT_C0CONTROL(ch)) {
if (ch == 0x1b) { /* ESC */
/* Abort sequence and begin with new. */
input_state(ictx, input_state_escape);
return;
} else if (ch == 0x18 || ch == 0x1a) { /* CAN and SUB */
/* Abort sequence. */
input_state(ictx, input_state_first);
return;
}
/* Handle C0 immediately. */
input_handle_c0_control(ch, ictx);
return;
}
input_state(ictx, input_state_first); input_state(ictx, input_state_first);
} }
@@ -519,7 +475,7 @@ input_state_string_next(u_char ch, struct input_ctx *ictx)
return; return;
} }
if (ch >= 0x20) { if (ch >= 0x20 && ch != 0x7f) {
if (input_add_string(ictx, ch) != 0) if (input_add_string(ictx, ch) != 0)
input_state(ictx, input_state_first); input_state(ictx, input_state_first);
return; return;
@@ -649,19 +605,12 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
screen_write_cursorleft(&ictx->ctx, 1); screen_write_cursorleft(&ictx->ctx, 1);
break; break;
case '\011': /* TAB */ case '\011': /* TAB */
/* Don't tab beyond the end of the line. */ s->cx = ((s->cx / 8) * 8) + 8;
if (s->cx >= screen_size_x(s) - 1) if (s->cx > screen_size_x(s) - 1) {
break; s->cx = 0;
screen_write_cursordown(&ictx->ctx, 1);
/* Find the next tab point, or use the last column if none. */ }
do { screen_write_cursormove(&ictx->ctx, s->cx, s->cy);
s->cx++;
if (bit_test(s->tabs, s->cx))
break;
} while (s->cx < screen_size_x(s) - 1);
break;
case '\013': /* VT */
screen_write_linefeed(&ictx->ctx);
break; break;
case '\016': /* SO */ case '\016': /* SO */
ictx->cell.attr |= GRID_ATTR_CHARSET; ictx->cell.attr |= GRID_ATTR_CHARSET;
@@ -678,22 +627,9 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
void void
input_handle_c1_control(u_char ch, struct input_ctx *ictx) input_handle_c1_control(u_char ch, struct input_ctx *ictx)
{ {
struct screen *s = ictx->ctx.s;
log_debug2("-- c1 %zu: %hhu (%c)", ictx->off, ch, ch); log_debug2("-- c1 %zu: %hhu (%c)", ictx->off, ch, ch);
switch (ch) { switch (ch) {
case 'D': /* IND */
screen_write_linefeed(&ictx->ctx);
break;
case 'E': /* NEL */
screen_write_carriagereturn(&ictx->ctx);
screen_write_linefeed(&ictx->ctx);
break;
case 'H': /* HTS */
if (s->cx < screen_size_x(s))
bit_set(s->tabs, s->cx);
break;
case 'M': /* RI */ case 'M': /* RI */
screen_write_reverseindex(&ictx->ctx); screen_write_reverseindex(&ictx->ctx);
break; break;
@@ -712,7 +648,7 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
"-- p2 %zu: %hhu (%c) %hhu", ictx->off, ch, ch, ictx->intermediate); "-- p2 %zu: %hhu (%c) %hhu", ictx->off, ch, ch, ictx->intermediate);
switch (ch) { switch (ch) {
case '0': /* SCS */ case '0': /* Dscs (graphics) */
/* /*
* Not really supported, but fake it up enough for those that * Not really supported, but fake it up enough for those that
* use it to switch character sets (by redefining G0 to * use it to switch character sets (by redefining G0 to
@@ -725,36 +661,22 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
} }
break; break;
case '=': /* DECKPAM */ case '=': /* DECKPAM */
if (ictx->intermediate != '\0')
break;
screen_write_kkeypadmode(&ictx->ctx, 1); screen_write_kkeypadmode(&ictx->ctx, 1);
log_debug("kkeypad on (application mode)"); log_debug("kkeypad on (application mode)");
break; break;
case '>': /* DECKPNM */ case '>': /* DECKPNM */
if (ictx->intermediate != '\0')
break;
screen_write_kkeypadmode(&ictx->ctx, 0); screen_write_kkeypadmode(&ictx->ctx, 0);
log_debug("kkeypad off (number mode)"); log_debug("kkeypad off (number mode)");
break; break;
case '7': /* DECSC */ case '7': /* DECSC */
if (ictx->intermediate != '\0')
break;
memcpy(&ictx->saved_cell, &ictx->cell, sizeof ictx->saved_cell); memcpy(&ictx->saved_cell, &ictx->cell, sizeof ictx->saved_cell);
ictx->saved_cx = s->cx; ictx->saved_cx = s->cx;
ictx->saved_cy = s->cy; ictx->saved_cy = s->cy;
break; break;
case '8': case '8': /* DECRC */
switch (ictx->intermediate) { memcpy(&ictx->cell, &ictx->saved_cell, sizeof ictx->cell);
case '\0': /* DECRC */ screen_write_cursormove(
memcpy( &ictx->ctx, ictx->saved_cx, ictx->saved_cy);
&ictx->cell, &ictx->saved_cell, sizeof ictx->cell);
screen_write_cursormove(
&ictx->ctx, ictx->saved_cx, ictx->saved_cy);
break;
case '#': /* DECALN */
screen_write_alignmenttest(&ictx->ctx);
break;
}
break; break;
default: default:
log_debug("unknown p2: %hhu", ch); log_debug("unknown p2: %hhu", ch);
@@ -769,7 +691,7 @@ input_handle_standard_two(u_char ch, struct input_ctx *ictx)
"-- s2 %zu: %hhu (%c) %hhu", ictx->off, ch, ch, ictx->intermediate); "-- s2 %zu: %hhu (%c) %hhu", ictx->off, ch, ch, ictx->intermediate);
switch (ch) { switch (ch) {
case 'B': /* SCS */ case 'B': /* Dscs (ASCII) */
/* /*
* Not really supported, but fake it up enough for those that * Not really supported, but fake it up enough for those that
* use it to switch character sets (by redefining G0 to * use it to switch character sets (by redefining G0 to
@@ -788,8 +710,6 @@ input_handle_standard_two(u_char ch, struct input_ctx *ictx)
ictx->saved_cx = 0; ictx->saved_cx = 0;
ictx->saved_cy = 0; ictx->saved_cy = 0;
screen_reset_tabs(ictx->ctx.s);
screen_write_scrollregion( screen_write_scrollregion(
&ictx->ctx, 0, screen_size_y(ictx->ctx.s) - 1); &ictx->ctx, 0, screen_size_y(ictx->ctx.s) - 1);
@@ -929,30 +849,6 @@ input_handle_sequence_dch(struct input_ctx *ictx)
screen_write_deletecharacter(&ictx->ctx, n); screen_write_deletecharacter(&ictx->ctx, n);
} }
void
input_handle_sequence_cbt(struct input_ctx *ictx)
{
struct screen *s = ictx->ctx.s;
uint16_t n;
if (ictx->private != '\0')
return;
if (ARRAY_LENGTH(&ictx->args) > 1)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
if (n == 0)
n = 1;
/* Find the previous tab point, n times. */
while (s->cx > 0 && n-- > 0) {
do
s->cx--;
while (s->cx > 0 && !bit_test(s->tabs, s->cx));
}
}
void void
input_handle_sequence_dl(struct input_ctx *ictx) input_handle_sequence_dl(struct input_ctx *ictx)
{ {
@@ -1067,31 +963,6 @@ input_handle_sequence_cup(struct input_ctx *ictx)
screen_write_cursormove(&ictx->ctx, m - 1, n - 1); screen_write_cursormove(&ictx->ctx, m - 1, n - 1);
} }
void
input_handle_sequence_tbc(struct input_ctx *ictx)
{
struct screen *s = ictx->ctx.s;
uint16_t n;
if (ictx->private != '\0')
return;
if (ARRAY_LENGTH(&ictx->args) > 1)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
switch (n) {
case 0:
if (s->cx < screen_size_x(s))
bit_clear(s->tabs, s->cx);
break;
case 3:
bit_nclear(s->tabs, 0, screen_size_x(s) - 1);
break;
}
}
void void
input_handle_sequence_ed(struct input_ctx *ictx) input_handle_sequence_ed(struct input_ctx *ictx)
{ {

View File

@@ -1,4 +1,4 @@
/* $Id: key-bindings.c,v 1.72 2009-05-16 11:48:47 nicm Exp $ */ /* $Id: key-bindings.c,v 1.66 2009-04-03 17:21:46 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -74,7 +74,7 @@ key_bindings_remove(int key)
void void
key_bindings_init(void) key_bindings_init(void)
{ {
static const struct { struct {
int key; int key;
int can_repeat; int can_repeat;
const struct cmd_entry *entry; const struct cmd_entry *entry;
@@ -83,7 +83,7 @@ key_bindings_init(void)
{ '!', 0, &cmd_break_pane_entry }, { '!', 0, &cmd_break_pane_entry },
{ '"', 0, &cmd_split_window_entry }, { '"', 0, &cmd_split_window_entry },
{ '#', 0, &cmd_list_buffers_entry }, { '#', 0, &cmd_list_buffers_entry },
{ '&', 0, &cmd_confirm_before_entry }, { '&', 0, &cmd_kill_window_entry },
{ ',', 0, &cmd_command_prompt_entry }, { ',', 0, &cmd_command_prompt_entry },
{ '-', 0, &cmd_delete_buffer_entry }, { '-', 0, &cmd_delete_buffer_entry },
{ '.', 0, &cmd_command_prompt_entry }, { '.', 0, &cmd_command_prompt_entry },
@@ -115,24 +115,19 @@ key_bindings_init(void)
{ 's', 0, &cmd_choose_session_entry }, { 's', 0, &cmd_choose_session_entry },
{ 't', 0, &cmd_clock_mode_entry }, { 't', 0, &cmd_clock_mode_entry },
{ 'w', 0, &cmd_choose_window_entry }, { 'w', 0, &cmd_choose_window_entry },
{ 'x', 0, &cmd_confirm_before_entry }, { 'x', 0, &cmd_kill_pane_entry, },
{ '{', 0, &cmd_swap_pane_entry }, { '{', 0, &cmd_swap_pane_entry },
{ '}', 0, &cmd_swap_pane_entry }, { '}', 0, &cmd_swap_pane_entry },
{ '\002', 0, &cmd_send_prefix_entry }, { META, 0, &cmd_send_prefix_entry },
{ KEYC_ADDESC('0'), 0, &cmd_select_layout_entry },
{ KEYC_ADDESC('1'), 0, &cmd_select_layout_entry },
{ KEYC_ADDESC('2'), 0, &cmd_select_layout_entry },
{ KEYC_ADDESC('9'), 0, &cmd_select_layout_entry },
{ KEYC_ADDCTL(KEYC_DOWN), 1, &cmd_resize_pane_entry },
{ KEYC_PPAGE, 0, &cmd_scroll_mode_entry }, { KEYC_PPAGE, 0, &cmd_scroll_mode_entry },
{ KEYC_ADDESC('n'), 0, &cmd_next_window_entry }, { KEYC_ADDESC('n'), 0, &cmd_next_window_entry },
{ KEYC_ADDESC('p'), 0, &cmd_previous_window_entry }, { KEYC_ADDESC('p'), 0, &cmd_previous_window_entry },
{ KEYC_UP, 1, &cmd_up_pane_entry }, { KEYC_UP, 1, &cmd_up_pane_entry },
{ KEYC_DOWN, 1, &cmd_down_pane_entry }, { KEYC_DOWN, 1, &cmd_down_pane_entry },
{ KEYC_ADDESC(KEYC_UP), 1, &cmd_resize_pane_entry }, { KEYC_ADDESC(KEYC_UP), 1, &cmd_resize_pane_up_entry },
{ KEYC_ADDESC(KEYC_DOWN), 1, &cmd_resize_pane_entry }, { KEYC_ADDESC(KEYC_DOWN), 1, &cmd_resize_pane_down_entry },
{ KEYC_ADDCTL(KEYC_UP), 1, &cmd_resize_pane_entry }, { KEYC_ADDCTL(KEYC_UP), 1, &cmd_resize_pane_up_entry },
{ KEYC_ADDCTL(KEYC_DOWN), 1, &cmd_resize_pane_entry }, { KEYC_ADDCTL(KEYC_DOWN), 1, &cmd_resize_pane_down_entry },
{ KEYC_ADDESC('o'), 0, &cmd_rotate_window_entry }, { KEYC_ADDESC('o'), 0, &cmd_rotate_window_entry },
{ '\017', 0, &cmd_rotate_window_entry }, { '\017', 0, &cmd_rotate_window_entry },
}; };

View File

@@ -1,183 +0,0 @@
/* $Id: layout-manual.c,v 1.3 2009-05-18 21:29:11 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include "tmux.h"
void layout_manual_v_update_offsets(struct window *);
void
layout_manual_v_refresh(struct window *w, unused int active_only)
{
struct window_pane *wp;
u_int npanes, canfit, total;
int left;
if (active_only)
return;
if (TAILQ_EMPTY(&w->panes))
return;
/* Clear hidden flags. */
TAILQ_FOREACH(wp, &w->panes, entry)
wp->flags &= ~PANE_HIDDEN;
/* Check the new size. */
npanes = window_count_panes(w);
if (w->sy <= PANE_MINIMUM * npanes) {
/* How many can we fit? */
canfit = w->sy / PANE_MINIMUM;
if (canfit == 0) {
/* None. Just use this size for the first. */
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp == TAILQ_FIRST(&w->panes))
wp->sy = w->sy;
else
wp->flags |= PANE_HIDDEN;
}
} else {
/* >=1, set minimum for them all. */
TAILQ_FOREACH(wp, &w->panes, entry) {
if (canfit-- > 0)
wp->sy = PANE_MINIMUM - 1;
else
wp->flags |= PANE_HIDDEN;
}
/* And increase the first by the rest. */
TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM;
}
} else {
/* In theory they will all fit. Find the current total. */
total = 0;
TAILQ_FOREACH(wp, &w->panes, entry)
total += wp->sy;
total += npanes - 1;
/* Growing or shrinking? */
left = w->sy - total;
if (left > 0) {
/* Growing. Expand evenly. */
while (left > 0) {
TAILQ_FOREACH(wp, &w->panes, entry) {
wp->sy++;
if (--left == 0)
break;
}
}
} else {
/* Shrinking. Reduce evenly down to minimum. */
while (left < 0) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->sy <= PANE_MINIMUM - 1)
continue;
wp->sy--;
if (++left == 0)
break;
}
}
}
}
/* Now do the resize. */
TAILQ_FOREACH(wp, &w->panes, entry) {
wp->sy--;
window_pane_resize(wp, w->sx, wp->sy + 1);
}
/* Fill in the offsets. */
layout_manual_v_update_offsets(w);
/* Switch the active window if necessary. */
window_set_active_pane(w, w->active);
}
void
layout_manual_v_resize(struct window_pane *wp, int adjust)
{
struct window *w = wp->window;
struct window_pane *wq;
if (adjust > 0) {
/*
* If this is not the last pane, keep trying to increase size
* and remove it from the next panes. If it is the last, do
* so on the previous pane.
*/
if (TAILQ_NEXT(wp, entry) == NULL) {
if (wp == TAILQ_FIRST(&w->panes)) {
/* Only one pane. */
return;
}
wp = TAILQ_PREV(wp, window_panes, entry);
}
while (adjust-- > 0) {
wq = wp;
while ((wq = TAILQ_NEXT(wq, entry)) != NULL) {
if (wq->sy <= PANE_MINIMUM)
continue;
window_pane_resize(wq, wq->sx, wq->sy - 1);
break;
}
if (wq == NULL)
break;
window_pane_resize(wp, wp->sx, wp->sy + 1);
}
} else {
adjust = -adjust;
/*
* If this is not the last pane, keep trying to reduce size
* and add to the following pane. If it is the last, do so on
* the previous pane.
*/
wq = TAILQ_NEXT(wp, entry);
if (wq == NULL) {
if (wp == TAILQ_FIRST(&w->panes)) {
/* Only one pane. */
return;
}
wq = wp;
wp = TAILQ_PREV(wq, window_panes, entry);
}
while (adjust-- > 0) {
if (wp->sy <= PANE_MINIMUM)
break;
window_pane_resize(wq, wq->sx, wq->sy + 1);
window_pane_resize(wp, wp->sx, wp->sy - 1);
}
}
layout_manual_v_update_offsets(w);
}
void
layout_manual_v_update_offsets(struct window *w)
{
struct window_pane *wp;
u_int yoff;
yoff = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->flags & PANE_HIDDEN)
continue;
wp->xoff = 0;
wp->yoff = yoff;
yoff += wp->sy + 1;
}
}

205
layout.c
View File

@@ -1,4 +1,4 @@
/* $Id: layout.c,v 1.14 2009-05-18 22:17:24 nicm Exp $ */ /* $Id: layout.c,v 1.3 2009-04-01 21:10:08 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,111 +18,57 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
/* /*
* Each layout has two functions, _refresh to relayout the panes and _resize to * Layout functions: second argument (int) is 1 if definitely the /only/ change
* resize a single pane. * has been the active pane has changed. If 0 then panes, active pane or both
* * may have changed.
* Second argument (int) to _refresh is 1 if the only change has been that the
* active pane has changed. If 0 then panes, active pane or both may have
* changed.
*/ */
void layout_manual(struct window *, int);
void layout_active_only_refresh(struct window *, int); void layout_active_only(struct window *, int);
void layout_even_h_refresh(struct window *, int); void layout_even_horizontal(struct window *, int);
void layout_even_v_refresh(struct window *, int); void layout_even_vertical(struct window *, int);
void layout_main_h_refresh(struct window *, int); void layout_left_vertical(struct window *, int);
void layout_main_v_refresh(struct window *, int);
const struct { const struct {
const char *name; const char *name;
void (*refresh)(struct window *, int); void (*fn)(struct window *, int);
void (*resize)(struct window_pane *, int);
} layouts[] = { } layouts[] = {
{ "manual-vertical", layout_manual_v_refresh, layout_manual_v_resize }, { "manual", layout_manual },
{ "active-only", layout_active_only_refresh, NULL }, { "active-only", layout_active_only },
{ "even-horizontal", layout_even_h_refresh, NULL }, { "even-horizontal", layout_even_horizontal },
{ "even-vertical", layout_even_v_refresh, NULL }, { "even-vertical", layout_even_vertical },
{ "main-horizontal", layout_main_h_refresh, NULL }, { "left-vertical", layout_left_vertical },
{ "main-vertical", layout_main_v_refresh, NULL },
}; };
const char *
layout_name(struct window *w)
{
return (layouts[w->layout].name);
}
int
layout_lookup(const char *name)
{
u_int i;
int matched = -1;
for (i = 0; i < nitems(layouts); i++) {
if (strncmp(layouts[i].name, name, strlen(name)) == 0) {
if (matched != -1) /* ambiguous */
return (-1);
matched = i;
}
}
return (matched);
}
int
layout_select(struct window *w, u_int layout)
{
if (layout > nitems(layouts) - 1 || layout == w->layout)
return (-1);
w->layout = layout;
layout_refresh(w, 0);
return (0);
}
void void
layout_next(struct window *w) layout_next(struct window *w)
{ {
w->layout++; w->layout++;
if (w->layout > nitems(layouts) - 1) if (w->layout > nitems(layouts) - 1) {
w->layout = 0; w->layout = 0;
/* XXX Special-case manual. */
window_fit_panes(w);
window_update_panes(w);
}
layout_refresh(w, 0); layout_refresh(w, 0);
} }
void void
layout_previous(struct window *w) layout_refresh(struct window *w, unused int active_changed)
{ {
if (w->layout == 0) layouts[w->layout].fn(w, active_changed);
w->layout = nitems(layouts) - 1;
else
w->layout--;
layout_refresh(w, 0);
}
void
layout_refresh(struct window *w, int active_only)
{
layouts[w->layout].refresh(w, active_only);
server_redraw_window(w); server_redraw_window(w);
} }
int void
layout_resize(struct window_pane *wp, int adjust) layout_manual(unused struct window *w, unused int active_changed)
{ {
struct window *w = wp->window;
if (layouts[w->layout].resize == NULL)
return (-1);
layouts[w->layout].resize(wp, adjust);
return (0);
} }
void void
layout_active_only_refresh(struct window *w, unused int active_only) layout_active_only(struct window *w, unused int active_changed)
{ {
struct window_pane *wp; struct window_pane *wp;
@@ -137,12 +83,12 @@ layout_active_only_refresh(struct window *w, unused int active_only)
} }
void void
layout_even_h_refresh(struct window *w, int active_only) layout_even_horizontal(struct window *w, int active_changed)
{ {
struct window_pane *wp; struct window_pane *wp;
u_int i, n, width, xoff; u_int i, n, width, xoff;
if (active_only) if (active_changed)
return; return;
/* Get number of panes. */ /* Get number of panes. */
@@ -185,12 +131,12 @@ layout_even_h_refresh(struct window *w, int active_only)
} }
void void
layout_even_v_refresh(struct window *w, int active_only) layout_even_vertical(struct window *w, int active_changed)
{ {
struct window_pane *wp; struct window_pane *wp;
u_int i, n, height, yoff; u_int i, n, height, yoff;
if (active_only) if (active_changed)
return; return;
/* Get number of panes. */ /* Get number of panes. */
@@ -233,12 +179,12 @@ layout_even_v_refresh(struct window *w, int active_only)
} }
void void
layout_main_v_refresh(struct window *w, int active_only) layout_left_vertical(struct window *w, int active_changed)
{ {
struct window_pane *wp; struct window_pane *wp;
u_int i, n, mainwidth, height, yoff; u_int i, n, height, yoff;
if (active_only) if (active_changed)
return; return;
/* Get number of panes. */ /* Get number of panes. */
@@ -246,12 +192,9 @@ layout_main_v_refresh(struct window *w, int active_only)
if (n == 0) if (n == 0)
return; return;
/* Get the main pane width and add one for separator line. */
mainwidth = options_get_number(&w->options, "main-pane-width") + 1;
/* Need >1 pane and minimum columns; if fewer, display active only. */ /* Need >1 pane and minimum columns; if fewer, display active only. */
if (n == 1 || w->sx < mainwidth + PANE_MINIMUM) { if (n == 1 || w->sx < 82 + PANE_MINIMUM) {
layout_active_only_refresh(w, active_only); layout_active_only(w, active_changed);
return; return;
} }
n--; n--;
@@ -269,7 +212,7 @@ layout_main_v_refresh(struct window *w, int active_only)
if (wp == TAILQ_FIRST(&w->panes)) { if (wp == TAILQ_FIRST(&w->panes)) {
wp->xoff = 0; wp->xoff = 0;
wp->yoff = 0; wp->yoff = 0;
window_pane_resize(wp, mainwidth - 1, w->sy); window_pane_resize(wp, 81, w->sy);
wp->flags &= ~PANE_HIDDEN; wp->flags &= ~PANE_HIDDEN;
continue; continue;
} }
@@ -280,12 +223,12 @@ layout_main_v_refresh(struct window *w, int active_only)
} }
wp->flags &= ~PANE_HIDDEN; wp->flags &= ~PANE_HIDDEN;
wp->xoff = mainwidth; wp->xoff = 82;
wp->yoff = yoff; wp->yoff = yoff;
if (i != n - 1) if (i != n - 1)
window_pane_resize(wp, w->sx - mainwidth, height - 1); window_pane_resize(wp, w->sx - 82, height - 1);
else else
window_pane_resize(wp, w->sx - mainwidth, height); window_pane_resize(wp, w->sx - 82, height);
i++; i++;
yoff += height; yoff += height;
@@ -301,73 +244,3 @@ layout_main_v_refresh(struct window *w, int active_only)
window_pane_resize(wp, wp->sx, wp->sy + 1); window_pane_resize(wp, wp->sx, wp->sy + 1);
} }
} }
void
layout_main_h_refresh(struct window *w, int active_only)
{
struct window_pane *wp;
u_int i, n, mainheight, width, xoff;
if (active_only)
return;
/* Get number of panes. */
n = window_count_panes(w);
if (n == 0)
return;
/* Get the main pane height and add one for separator line. */
mainheight = options_get_number(&w->options, "main-pane-height") + 1;
/* Need >1 pane and minimum rows; if fewer, display active only. */
if (n == 1 || w->sy < mainheight + PANE_MINIMUM) {
layout_active_only_refresh(w, active_only);
return;
}
n--;
/* How many can we fit, not including first? */
if (w->sx / n < PANE_MINIMUM) {
width = PANE_MINIMUM;
n = w->sx / PANE_MINIMUM;
} else
width = w->sx / n;
/* Fit the panes. */
i = xoff = 0;
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp == TAILQ_FIRST(&w->panes)) {
wp->xoff = 0;
wp->yoff = 0;
window_pane_resize(wp, w->sx, mainheight - 1);
wp->flags &= ~PANE_HIDDEN;
continue;
}
if (i > n) {
wp->flags |= PANE_HIDDEN;
continue;
}
wp->flags &= ~PANE_HIDDEN;
wp->xoff = xoff;
wp->yoff = mainheight;
if (i != n - 1)
window_pane_resize(wp, width - 1, w->sy - mainheight);
else
window_pane_resize(wp, width - 1, w->sy - mainheight);
i++;
xoff += width;
}
/* Any space left? */
while (xoff++ < w->sx + 1) {
wp = TAILQ_LAST(&w->panes, window_panes);
while (wp != NULL && wp == TAILQ_FIRST(&w->panes))
wp = TAILQ_PREV(wp, window_panes, entry);
if (wp == NULL)
break;
window_pane_resize(wp, wp->sx + 1, wp->sy);
}
}

38
log.c
View File

@@ -1,4 +1,4 @@
/* $Id: log.c,v 1.15 2009-06-25 16:23:35 nicm Exp $ */ /* $Id: log.c,v 1.11 2009-03-31 21:22:10 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,8 +29,9 @@
/* Logging type. */ /* Logging type. */
#define LOG_TYPE_OFF 0 #define LOG_TYPE_OFF 0
#define LOG_TYPE_TTY 1 #define LOG_TYPE_SYSLOG 1
#define LOG_TYPE_FILE 2 #define LOG_TYPE_TTY 2
#define LOG_TYPE_FILE 3
int log_type = LOG_TYPE_OFF; int log_type = LOG_TYPE_OFF;
/* Log file, if needed. */ /* Log file, if needed. */
@@ -39,8 +40,17 @@ FILE *log_file;
/* Debug level. */ /* Debug level. */
int log_level; int log_level;
void log_vwrite(int, const char *, va_list); /* Open logging to syslog. */
__dead void log_vfatal(const char *, va_list); void
log_open_syslog(int level)
{
log_type = LOG_TYPE_SYSLOG;
log_level = level;
openlog(__progname, LOG_PID|LOG_NDELAY, LOG_FACILITY);
tzset();
}
/* Open logging to tty. */ /* Open logging to tty. */
void void
@@ -81,6 +91,17 @@ log_close(void)
log_type = LOG_TYPE_OFF; log_type = LOG_TYPE_OFF;
} }
/* Write a log message. */
void
log_write(int pri, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
log_vwrite(pri, msg, ap);
va_end(ap);
}
/* Write a log message. */ /* Write a log message. */
void void
log_vwrite(int pri, const char *msg, va_list ap) log_vwrite(int pri, const char *msg, va_list ap)
@@ -89,6 +110,13 @@ log_vwrite(int pri, const char *msg, va_list ap)
FILE *f = log_file; FILE *f = log_file;
switch (log_type) { switch (log_type) {
case LOG_TYPE_SYSLOG:
#ifdef NO_VSYSLOG
/* XXX */
#else
vsyslog(pri, msg, ap);
#endif
break;
case LOG_TYPE_TTY: case LOG_TYPE_TTY:
if (pri == LOG_INFO) if (pri == LOG_INFO)
f = stdout; f = stdout;

View File

@@ -1,4 +1,4 @@
/* $Id: mode-key.c,v 1.12 2009-05-14 19:36:56 nicm Exp $ */ /* $Id: mode-key.c,v 1.10 2009-02-21 17:46:13 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -54,13 +54,6 @@ mode_key_lookup(struct mode_key_data *mdata, int key)
enum mode_key_cmd enum mode_key_cmd
mode_key_lookup_vi(struct mode_key_data *mdata, int key) mode_key_lookup_vi(struct mode_key_data *mdata, int key)
{ {
if (KEYC_ISESC(key)) {
key = KEYC_REMOVEESC(key);
if (mdata->flags & MODEKEY_CANEDIT)
mdata->flags ^= MODEKEY_EDITMODE;
}
if (mdata->flags & MODEKEY_EDITMODE) { if (mdata->flags & MODEKEY_EDITMODE) {
switch (key) { switch (key) {
case '\003': case '\003':
@@ -138,8 +131,6 @@ mode_key_lookup_vi(struct mode_key_data *mdata, int key)
case 'k': case 'k':
case KEYC_UP: case KEYC_UP:
return (MODEKEYCMD_UP); return (MODEKEYCMD_UP);
case 'p':
return (MODEKEYCMD_PASTE);
} }
return (MODEKEYCMD_NONE); return (MODEKEYCMD_NONE);
@@ -182,8 +173,6 @@ mode_key_lookup_emacs(struct mode_key_data *mdata, int key)
return (MODEKEYCMD_NEXTPAGE); return (MODEKEYCMD_NEXTPAGE);
case KEYC_ADDESC('f'): case KEYC_ADDESC('f'):
return (MODEKEYCMD_NEXTWORD); return (MODEKEYCMD_NEXTWORD);
case '\031':
return (MODEKEYCMD_PASTE);
case KEYC_ADDESC('v'): case KEYC_ADDESC('v'):
case KEYC_PPAGE: case KEYC_PPAGE:
return (MODEKEYCMD_PREVIOUSPAGE); return (MODEKEYCMD_PREVIOUSPAGE);

23
names.c
View File

@@ -1,4 +1,4 @@
/* $Id: names.c,v 1.11 2009-07-02 18:26:55 nicm Exp $ */ /* $Id: names.c,v 1.4 2009-02-13 00:43:04 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,7 +19,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h> #include <ctype.h>
#include <libgen.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@@ -59,16 +58,7 @@ set_window_names(void)
if (name == NULL) if (name == NULL)
wname = default_window_name(w); wname = default_window_name(w);
else { else {
/* wname = parse_window_name(name);
* If tmux is using the default command, it will be a
* login shell and argv[0] may have a - prefix. Remove
* this if it is present. Ick.
*/
if (w->active->cmd != NULL && *w->active->cmd == '\0' &&
name != NULL && name[0] == '-' && name[1] != '\0')
wname = parse_window_name(name + 1);
else
wname = parse_window_name(name);
xfree(name); xfree(name);
} }
@@ -87,9 +77,7 @@ default_window_name(struct window *w)
{ {
if (w->active->screen != &w->active->base) if (w->active->screen != &w->active->base)
return (xstrdup("[tmux]")); return (xstrdup("[tmux]"));
if (w->active->cmd != NULL && *w->active->cmd != '\0') return (parse_window_name(w->active->cmd));
return (parse_window_name(w->active->cmd));
return (parse_window_name(window_default_command()));
} }
char * char *
@@ -108,13 +96,14 @@ parse_window_name(const char *in)
if (*name != '\0') { if (*name != '\0') {
ptr = name + strlen(name) - 1; ptr = name + strlen(name) - 1;
while (ptr > name && !isalnum((u_char)*ptr)) while (ptr > name && !isalnum(*ptr))
*ptr-- = '\0'; *ptr-- = '\0';
} }
if (*name == '/') if (*name == '/')
name = basename(name); name = xbasename(name);
name = xstrdup(name); name = xstrdup(name);
xfree(copy); xfree(copy);
return (name); return (name);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: options.c,v 1.5 2009-05-15 12:57:36 nicm Exp $ */ /* $Id: options.c,v 1.4 2009-01-07 19:53:17 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,7 +63,7 @@ options_find1(struct options *oo, const char *name)
{ {
struct options_entry p; struct options_entry p;
p.name = (char *) name; p.name = name;
return (SPLAY_FIND(options_tree, &oo->tree, &p)); return (SPLAY_FIND(options_tree, &oo->tree, &p));
} }
@@ -72,7 +72,7 @@ options_find(struct options *oo, const char *name)
{ {
struct options_entry *o, p; struct options_entry *o, p;
p.name = (char *) name; p.name = name;
o = SPLAY_FIND(options_tree, &oo->tree, &p); o = SPLAY_FIND(options_tree, &oo->tree, &p);
while (o == NULL) { while (o == NULL) {
oo = oo->parent; oo = oo->parent;

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-darwin.c,v 1.11 2009-05-04 17:58:27 nicm Exp $ */ /* $Id: osdep-darwin.c,v 1.9 2009-02-13 00:43:04 nicm Exp $ */
/* /*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org> * Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -16,6 +16,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifdef __APPLE__
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
@@ -45,3 +47,5 @@ osdep_get_name(int fd, unused char *tty)
return (strdup(kp.kp_proc.p_comm)); return (strdup(kp.kp_proc.p_comm));
} }
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-freebsd.c,v 1.16 2009-06-26 15:31:15 nicm Exp $ */ /* $Id: osdep-freebsd.c,v 1.14 2009-02-13 00:43:04 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,6 +16,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifdef __FreeBSD__
#include <sys/param.h> #include <sys/param.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -31,9 +33,7 @@
char *osdep_get_name(int, char *); char *osdep_get_name(int, char *);
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#define is_runnable(p) \ #define is_runnable(p) \
((p)->ki_stat == SRUN || (p)->ki_stat == SIDL) ((p)->ki_stat == SRUN || (p)->ki_stat == SIDL)
@@ -121,3 +121,5 @@ retry:
free(buf); free(buf);
return (name); return (name);
} }
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-linux.c,v 1.6 2009-04-29 23:07:35 nicm Exp $ */ /* $Id: osdep-linux.c,v 1.5 2009-02-13 00:43:04 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,6 +16,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifdef __linux__
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -57,3 +59,5 @@ osdep_get_name(int fd, unused char *tty)
fclose(f); fclose(f);
return (buf); return (buf);
} }
#endif

View File

@@ -1,5 +1,3 @@
/* $Id: osdep-netbsd.c,v 1.4 2009-06-26 15:54:52 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* *
@@ -16,37 +14,109 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifdef __NetBSD__
#include <sys/param.h> #include <sys/param.h>
#include <sys/proc.h> #include <sys/proc.h>
#include <sys/stat.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/user.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#define is_runnable(p) \
((p)->p_stat == LSRUN || (p)->p_stat == SIDL)
#define is_stopped(p) \
((p)->p_stat == LSSTOP || (p)->p_stat == SZOMB)
char *osdep_get_name(int, char *); char *osdep_get_name(int, char *);
char * char *
osdep_get_name(int fd, __unused char *tty) osdep_get_name(int fd, char *tty)
{ {
int mib[6]; int mib[4] = { CTL_KERN, KERN_PROC2, KERN_PROC_PGRP, 0 };
struct stat sb;
size_t len; size_t len;
struct kinfo_proc2 p; struct kinfo_proc2 *buf, *newbuf, *p, *bestp;
u_int i;
char *name;
buf = NULL;
if (stat(tty, &sb) == -1)
return (NULL);
if ((mib[3] = tcgetpgrp(fd)) == -1) if ((mib[3] = tcgetpgrp(fd)) == -1)
return (NULL); return (NULL);
len = sizeof(p); retry:
mib[0] = CTL_KERN; if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
mib[1] = KERN_PROC2;
mib[2] = KERN_PROC_PID;
mib[4] = sizeof(p);
mib[5] = 1;
if (sysctl(mib, nitems(mib), &p, &len, NULL, 0) == -1)
return (NULL); return (NULL);
len = (len * 5) / 4;
return (strdup(p.p_comm)); if ((newbuf = realloc(buf, len)) == NULL) {
free(buf);
return (NULL);
}
buf = newbuf;
if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) {
if (errno == ENOMEM)
goto retry;
free(buf);
return (NULL);
}
bestp = NULL;
for (i = 0; i < len / sizeof (struct kinfo_proc); i++) {
if (buf[i].p_tdev != sb.st_rdev)
continue;
p = &buf[i];
if (bestp == NULL) {
bestp = p;
continue;
}
if (is_runnable(p) && !is_runnable(bestp))
bestp = p;
else if (!is_runnable(p) && is_runnable(bestp))
continue;
if (!is_stopped(p) && is_stopped(bestp))
bestp = p;
else if (is_stopped(p) && !is_stopped(bestp))
continue;
if (p->p_estcpu > bestp->p_estcpu)
bestp = p;
else if (p->p_estcpu < bestp->p_estcpu)
continue;
if (p->p_slptime < bestp->p_slptime)
bestp = p;
else if (p->p_slptime > bestp->p_slptime)
continue;
if (strcmp(p->p_comm, p->p_comm) < 0)
bestp = p;
else if (strcmp(p->p_comm, p->p_comm) > 0)
continue;
if (p->p_pid > bestp->p_pid)
bestp = p;
}
name = NULL;
if (bestp != NULL)
name = strdup(bestp->p_comm);
free(buf);
return (name);
} }
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-openbsd.c,v 1.16 2009-06-26 15:31:15 nicm Exp $ */ /* $Id: osdep-openbsd.c,v 1.14 2009-02-17 18:54:14 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,6 +16,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#ifdef __OpenBSD__
#include <sys/param.h> #include <sys/param.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -25,9 +27,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#define is_runnable(p) \ #define is_runnable(p) \
((p)->p_stat == SRUN || (p)->p_stat == SIDL || (p)->p_stat == SONPROC) ((p)->p_stat == SRUN || (p)->p_stat == SIDL || (p)->p_stat == SONPROC)
@@ -130,3 +130,5 @@ retry:
free(buf); free(buf);
return (name); return (name);
} }
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: osdep-unknown.c,v 1.5 2009-04-29 23:07:35 nicm Exp $ */ /* $Id: osdep-unknown.c,v 1.4 2009-03-31 21:22:10 nicm Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -16,6 +16,9 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#if !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__linux__) && \
!defined(__APPLE__) && !defined(__NetBSD__)
#include <sys/types.h> #include <sys/types.h>
#include "tmux.h" #include "tmux.h"
@@ -25,3 +28,5 @@ osdep_get_name(unused int fd, unused char *tty)
{ {
return (NULL); return (NULL);
} }
#endif

View File

@@ -1,4 +1,4 @@
/* $Id: paste.c,v 1.7 2009-07-02 16:23:54 nicm Exp $ */ /* $Id: paste.c,v 1.6 2009-01-25 18:51:28 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -101,9 +101,6 @@ paste_add(struct paste_stack *ps, char *data, u_int limit)
{ {
struct paste_buffer *pb; struct paste_buffer *pb;
if (*data == '\0')
return;
while (ARRAY_LENGTH(ps) >= limit) while (ARRAY_LENGTH(ps) >= limit)
ARRAY_TRUNC(ps, 1); ARRAY_TRUNC(ps, 1);

View File

@@ -1,4 +1,4 @@
/* $Id: screen-redraw.c,v 1.38 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: screen-redraw.c,v 1.34 2009-04-02 21:08:13 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -67,40 +67,23 @@ screen_redraw_screen(struct client *c)
struct window *w = c->session->curw->window; struct window *w = c->session->curw->window;
struct tty *tty = &c->tty; struct tty *tty = &c->tty;
struct window_pane *wp; struct window_pane *wp;
struct screen *s;
u_int i, j, sx, sy; u_int i, j, sx, sy;
int status, has_acs; int status;
u_char choriz, cvert, cbackg;
/* Get status line, er, status. */ /* Get status line, er, status. */
status = options_get_number(&c->session->options, "status"); status = options_get_number(&c->session->options, "status");
/* Work out ACS characters. */
if (tty_term_has(tty->term, TTYC_ACSC)) {
has_acs = 1;
choriz = tty_get_acs(tty, 'q');
cvert = tty_get_acs(tty, 'x');
cbackg = tty_get_acs(tty, '~');
} else {
has_acs = 0;
choriz = '-';
cvert = '|';
cbackg = '.';
}
/* Clear the screen. */ /* Clear the screen. */
tty_reset(tty); tty_reset(tty);
if (has_acs)
tty_putcode(tty, TTYC_SMACS);
for (j = 0; j < tty->sy - status; j++) { for (j = 0; j < tty->sy - status; j++) {
for (i = 0; i < tty->sx; i++) { for (i = 0; i < tty->sx; i++) {
if (!screen_redraw_check_cell(c, i, j)) { if (!screen_redraw_check_cell(c, i, j)) {
tty_cursor(tty, i, j, 0, 0); tty_cursor(tty, i, j, 0, 0);
tty_putc(tty, cbackg); tty_putc(tty, '.');
} }
} }
} }
if (has_acs)
tty_putcode(tty, TTYC_RMACS);
/* Draw the panes. */ /* Draw the panes. */
TAILQ_FOREACH(wp, &w->panes, entry) { TAILQ_FOREACH(wp, &w->panes, entry) {
@@ -109,22 +92,21 @@ screen_redraw_screen(struct client *c)
tty_reset(tty); tty_reset(tty);
s = wp->screen;
sx = wp->sx; sx = wp->sx;
sy = wp->sy; sy = wp->sy;
/* Draw left and right borders. */ /* Draw left and right borders. */
if (has_acs)
tty_putcode(tty, TTYC_SMACS);
if (wp->xoff > 0) { if (wp->xoff > 0) {
for (i = wp->yoff; i < wp->yoff + sy; i++) { for (i = wp->yoff; i < wp->yoff + sy; i++) {
tty_cursor(tty, wp->xoff - 1, i, 0, 0); tty_cursor(tty, wp->xoff - 1, i, 0, 0);
tty_putc(tty, cvert); tty_putc(tty, '|');
} }
} }
if (wp->xoff + sx < tty->sx) { if (wp->xoff + sx < tty->sx) {
for (i = wp->yoff; i < wp->yoff + sy; i++) { for (i = wp->yoff; i < wp->yoff + sy; i++) {
tty_cursor(tty, wp->xoff + sx, i, 0, 0); tty_cursor(tty, wp->xoff + sx, i, 0, 0);
tty_putc(&c->tty, cvert); tty_putc(&c->tty, '|');
} }
} }
@@ -132,15 +114,13 @@ screen_redraw_screen(struct client *c)
if (wp->yoff > 0) { if (wp->yoff > 0) {
tty_cursor(tty, wp->xoff, wp->yoff - 1, 0, 0); tty_cursor(tty, wp->xoff, wp->yoff - 1, 0, 0);
for (i = 0; i < sx; i++) for (i = 0; i < sx; i++)
tty_putc(tty, choriz); tty_putc(tty, '-');
} }
if (wp->yoff + sy < tty->sy - status) { if (wp->yoff + sy < tty->sy - status) {
tty_cursor(tty, wp->xoff, wp->yoff + sy, 0, 0); tty_cursor(tty, wp->xoff, wp->yoff + sy, 0, 0);
for (i = 0; i < sx; i++) for (i = 0; i < sx; i++)
tty_putc(tty, choriz); tty_putc(tty, '-');
} }
if (has_acs)
tty_putcode(tty, TTYC_RMACS);
/* Draw the pane. */ /* Draw the pane. */
screen_redraw_pane(c, wp); screen_redraw_pane(c, wp);

View File

@@ -1,4 +1,4 @@
/* $Id: screen-write.c,v 1.56 2009-07-01 19:14:33 nicm Exp $ */ /* $Id: screen-write.c,v 1.43 2009-03-30 20:14:50 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -52,126 +52,20 @@ screen_write_putc(
screen_write_cell(ctx, gc, NULL); screen_write_cell(ctx, gc, NULL);
} }
/* Calculate string length. */ /* Write string. */
size_t printflike2
screen_write_strlen(int utf8flag, const char *fmt, ...)
{
va_list ap;
char *msg;
u_char *ptr, utf8buf[4];
size_t left, size = 0;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
ptr = msg;
while (*ptr != '\0') {
if (utf8flag && *ptr > 0x7f) {
memset(utf8buf, 0xff, sizeof utf8buf);
left = strlen(ptr);
if (*ptr >= 0xc2 && *ptr <= 0xdf && left >= 2) {
memcpy(utf8buf, ptr, 2);
ptr += 2;
} else if (*ptr >= 0xe0 && *ptr <= 0xef && left >= 3) {
memcpy(utf8buf, ptr, 3);
ptr += 3;
} else if (*ptr >= 0xf0 && *ptr <= 0xf4 && left >= 4) {
memcpy(utf8buf, ptr, 4);
ptr += 4;
} else {
*utf8buf = *ptr;
ptr++;
}
size += utf8_width(utf8buf);
} else {
size++;
ptr++;
}
}
return (size);
}
/* Write simple string (no UTF-8 or maximum length). */
void printflike3 void printflike3
screen_write_puts( screen_write_puts(
struct screen_write_ctx *ctx, struct grid_cell *gc, const char *fmt, ...) struct screen_write_ctx *ctx, struct grid_cell *gc, const char *fmt, ...)
{ {
va_list ap; va_list ap;
char *msg, *ptr;
va_start(ap, fmt); va_start(ap, fmt);
screen_write_vnputs(ctx, -1, gc, 0, fmt, ap);
va_end(ap);
}
/* Write string with length limit (-1 for unlimited). */
void printflike5
screen_write_nputs(struct screen_write_ctx *ctx,
ssize_t maxlen, struct grid_cell *gc, int utf8flag, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
screen_write_vnputs(ctx, maxlen, gc, utf8flag, fmt, ap);
va_end(ap);
}
void
screen_write_vnputs(struct screen_write_ctx *ctx, ssize_t maxlen,
struct grid_cell *gc, int utf8flag, const char *fmt, va_list ap)
{
char *msg;
u_char *ptr, utf8buf[4];
size_t left, size = 0;
int width;
xvasprintf(&msg, fmt, ap); xvasprintf(&msg, fmt, ap);
va_end(ap);
ptr = msg; for (ptr = msg; *ptr != '\0'; ptr++)
while (*ptr != '\0') { screen_write_putc(ctx, gc, (u_char) *ptr);
if (utf8flag && *ptr > 0x7f) {
memset(utf8buf, 0xff, sizeof utf8buf);
left = strlen(ptr);
if (*ptr >= 0xc2 && *ptr <= 0xdf && left >= 2) {
memcpy(utf8buf, ptr, 2);
ptr += 2;
} else if (*ptr >= 0xe0 && *ptr <= 0xef && left >= 3) {
memcpy(utf8buf, ptr, 3);
ptr += 3;
} else if (*ptr >= 0xf0 && *ptr <= 0xf4 && left >= 4) {
memcpy(utf8buf, ptr, 4);
ptr += 4;
} else {
*utf8buf = *ptr;
ptr++;
}
width = utf8_width(utf8buf);
if (maxlen > 0 && size + width > (size_t) maxlen) {
while (size < (size_t) maxlen) {
screen_write_putc(ctx, gc, ' ');
size++;
}
break;
}
size += width;
gc->flags |= GRID_FLAG_UTF8;
screen_write_cell(ctx, gc, utf8buf);
gc->flags &= ~GRID_FLAG_UTF8;
} else {
if (maxlen > 0 && size + 1 > (size_t) maxlen)
break;
size++;
screen_write_putc(ctx, gc, *ptr);
ptr++;
}
}
xfree(msg); xfree(msg);
} }
@@ -291,31 +185,6 @@ screen_write_cursorleft(struct screen_write_ctx *ctx, u_int nx)
s->cx -= nx; s->cx -= nx;
} }
/* VT100 alignment test. */
void
screen_write_alignmenttest(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
struct grid_cell gc;
u_int xx, yy;
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.data = 'E';
for (yy = 0; yy < screen_size_y(s); yy++) {
for (xx = 0; xx < screen_size_x(s); xx++)
grid_view_set_cell(s->grid, xx, yy, &gc);
}
s->cx = 0;
s->cy = 0;
s->rupper = 0;
s->rlower = screen_size_y(s) - 1;
tty_write_cmd(ctx->wp, TTY_ALIGNMENTTEST);
}
/* Insert nx characters. */ /* Insert nx characters. */
void void
screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx) screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx)
@@ -325,8 +194,8 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0) if (nx == 0)
nx = 1; nx = 1;
if (nx > screen_size_x(s) - s->cx) if (nx > screen_size_x(s) - 1 - s->cx)
nx = screen_size_x(s) - s->cx; nx = screen_size_x(s) - 1 - s->cx;
if (nx == 0) if (nx == 0)
return; return;
@@ -347,8 +216,8 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0) if (nx == 0)
nx = 1; nx = 1;
if (nx > screen_size_x(s) - s->cx) if (nx > screen_size_x(s) - 1 - s->cx)
nx = screen_size_x(s) - s->cx; nx = screen_size_x(s) - 1 - s->cx;
if (nx == 0) if (nx == 0)
return; return;
@@ -369,8 +238,8 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0) if (ny == 0)
ny = 1; ny = 1;
if (ny > screen_size_y(s) - s->cy) if (ny > screen_size_y(s) - 1 - s->cy)
ny = screen_size_y(s) - s->cy; ny = screen_size_y(s) - 1 - s->cy;
if (ny == 0) if (ny == 0)
return; return;
@@ -395,8 +264,8 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0) if (ny == 0)
ny = 1; ny = 1;
if (ny > screen_size_y(s) - s->cy) if (ny > screen_size_y(s) - 1 - s->cy)
ny = screen_size_y(s) - s->cy; ny = screen_size_y(s) - 1 - s->cy;
if (ny == 0) if (ny == 0)
return; return;
@@ -630,11 +499,11 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx)
sx = screen_size_x(s); sx = screen_size_x(s);
if (s->cy > 0) if (s->cy > 0)
grid_view_clear(s->grid, 0, 0, sx, s->cy); grid_view_clear(s->grid, 0, 0, sx, s->cy - 1);
if (s->cx > sx - 1) if (s->cx > sx - 1)
grid_view_clear(s->grid, 0, s->cy, sx, 1); grid_view_clear(s->grid, 0, s->cy, sx, 1);
else else
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1); grid_view_clear(s->grid, 0, s->cy, s->cx, 1);
tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFSCREEN); tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFSCREEN);
} }
@@ -660,10 +529,9 @@ screen_write_cell(
struct screen *s = ctx->s; struct screen *s = ctx->s;
struct grid *gd = s->grid; struct grid *gd = s->grid;
struct grid_utf8 gu, *tmp_gu; struct grid_utf8 gu, *tmp_gu;
u_int width, xx, i; u_int width, uvalue, xx, i;
struct grid_cell tmp_gc, *tmp_gc2; struct grid_cell tmp_gc, *tmp_gc2;
size_t size; size_t size;
int insert = 0;
/* Ignore padding. */ /* Ignore padding. */
if (gc->flags & GRID_FLAG_PADDING) if (gc->flags & GRID_FLAG_PADDING)
@@ -671,7 +539,8 @@ screen_write_cell(
/* Find character width. */ /* Find character width. */
if (gc->flags & GRID_FLAG_UTF8) { if (gc->flags & GRID_FLAG_UTF8) {
width = utf8_width(udata); uvalue = utf8_combine(udata);
width = utf8_width(uvalue);
gu.width = width; gu.width = width;
memcpy(&gu.data, udata, sizeof gu.data); memcpy(&gu.data, udata, sizeof gu.data);
@@ -715,13 +584,6 @@ screen_write_cell(
gc = &tmp_gc; gc = &tmp_gc;
} }
/* If in insert mode, make space for the cells. */
if (s->mode & MODE_INSERT && s->cx <= screen_size_x(s) - width) {
xx = screen_size_x(s) - s->cx - width;
grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx);
insert = 1;
}
/* Check this will fit on the current line; scroll if not. */ /* Check this will fit on the current line; scroll if not. */
if (s->cx > screen_size_x(s) - width) { if (s->cx > screen_size_x(s) - width) {
screen_write_carriagereturn(ctx); screen_write_carriagereturn(ctx);
@@ -755,8 +617,6 @@ screen_write_cell(
s->cx += width; s->cx += width;
/* Draw to the screen if necessary. */ /* Draw to the screen if necessary. */
if (insert)
tty_write_cmd(ctx->wp, TTY_INSERTCHARACTER, width);
if (screen_check_selection(s, s->cx - width, s->cy)) { if (screen_check_selection(s, s->cx - width, s->cy)) {
s->sel.cell.data = gc->data; s->sel.cell.data = gc->data;
tty_write_cmd(ctx->wp, TTY_CELL, &s->sel.cell, &gu); tty_write_cmd(ctx->wp, TTY_CELL, &s->sel.cell, &gu);

119
screen.c
View File

@@ -1,4 +1,4 @@
/* $Id: screen.c,v 1.88 2009-06-25 20:27:31 nicm Exp $ */ /* $Id: screen.c,v 1.81 2009-03-28 20:17:29 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,7 +18,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "tmux.h" #include "tmux.h"
@@ -34,8 +33,6 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
s->title = xstrdup(""); s->title = xstrdup("");
s->tabs = NULL;
screen_reinit(s); screen_reinit(s);
} }
@@ -51,8 +48,6 @@ screen_reinit(struct screen *s)
s->mode = MODE_CURSOR; s->mode = MODE_CURSOR;
screen_reset_tabs(s);
grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy - 1); grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy - 1);
screen_clear_selection(s); screen_clear_selection(s);
@@ -66,31 +61,12 @@ screen_free(struct screen *s)
grid_destroy(s->grid); grid_destroy(s->grid);
} }
/* Reset tabs to default, eight spaces apart. */
void
screen_reset_tabs(struct screen *s)
{
u_int i;
if (s->tabs != NULL)
xfree(s->tabs);
if ((s->tabs = bit_alloc(screen_size_x(s))) == NULL)
fatal("bit_alloc failed");
for (i = 8; i < screen_size_x(s); i += 8)
bit_set(s->tabs, i);
}
/* Set screen title. */ /* Set screen title. */
void void
screen_set_title(struct screen *s, const char *title) screen_set_title(struct screen *s, const char *title)
{ {
char tmp[BUFSIZ];
strnvis(tmp, title, sizeof tmp, VIS_OCTAL|VIS_TAB|VIS_NL);
xfree(s->title); xfree(s->title);
s->title = xstrdup(tmp); s->title = xstrdup(title);
} }
/* Resize screen. */ /* Resize screen. */
@@ -102,17 +78,8 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
if (sy < 1) if (sy < 1)
sy = 1; sy = 1;
if (sx != screen_size_x(s)) { if (sx != screen_size_x(s))
screen_resize_x(s, sx); screen_resize_x(s, sx);
/*
* It is unclear what should happen to tabs on resize. xterm
* seems to try and maintain them, rxvt resets them. Resetting
* is simpler and more reliable so let's do that.
*/
screen_reset_tabs(s);
}
if (sy != screen_size_y(s)) if (sy != screen_size_y(s))
screen_resize_y(s, sy); screen_resize_y(s, sy);
} }
@@ -168,42 +135,38 @@ void
screen_resize_y(struct screen *s, u_int sy) screen_resize_y(struct screen *s, u_int sy)
{ {
struct grid *gd = s->grid; struct grid *gd = s->grid;
u_int needed, available, oldy, i; u_int oy, yy, ny;
if (sy == 0) if (sy == 0)
fatalx("zero size"); fatalx("zero size");
oldy = screen_size_y(s);
/*
* When resizing:
*
* If the height is decreasing, delete lines from the bottom until
* hitting the cursor, then push lines from the top into the history.
*
* When increasing, pull as many lines as possible from the history to
* the top, then fill the remaining with blanks at the bottom.
*/
/* Size decreasing. */ /* Size decreasing. */
if (sy < oldy) { if (sy < screen_size_y(s)) {
needed = oldy - sy; oy = screen_size_y(s);
/* Delete as many lines as possible from the bottom. */ if (s->cy != 0) {
available = oldy - 1 - s->cy; /*
if (available > 0) { * The cursor is not at the start. Try to remove as
if (available > needed) * many lines as possible from the top. (Up to the
available = needed; * cursor line.)
grid_view_delete_lines(gd, oldy - available, available); */
ny = s->cy;
if (ny > oy - sy)
ny = oy - sy;
grid_view_delete_lines(gd, 0, ny);
s->cy -= ny;
oy -= ny;
} }
needed -= available;
/* if (sy < oy) {
* Now just increase the history size to take over the lines /* Remove any remaining lines from the bottom. */
* which are left. XXX Should apply history limit? grid_view_delete_lines(gd, sy, oy - sy);
*/ if (s->cy >= sy)
gd->hsize += needed; s->cy = sy - 1;
s->cy -= needed; }
} }
/* Resize line arrays. */ /* Resize line arrays. */
gd->size = xrealloc(gd->size, gd->hsize + sy, sizeof *gd->size); gd->size = xrealloc(gd->size, gd->hsize + sy, sizeof *gd->size);
@@ -212,30 +175,18 @@ screen_resize_y(struct screen *s, u_int sy)
gd->udata = xrealloc(gd->udata, gd->hsize + sy, sizeof *gd->udata); gd->udata = xrealloc(gd->udata, gd->hsize + sy, sizeof *gd->udata);
/* Size increasing. */ /* Size increasing. */
if (sy > oldy) { if (sy > screen_size_y(s)) {
needed = sy - oldy; oy = screen_size_y(s);
for (yy = gd->hsize + oy; yy < gd->hsize + sy; yy++) {
/* Try to pull as much as possible out of the history. */ gd->size[yy] = 0;
available = gd->hsize; gd->data[yy] = NULL;
if (available > 0) { gd->usize[yy] = 0;
if (available > needed) gd->udata[yy] = NULL;
available = needed;
gd->hsize -= available;
s->cy += available;
}
needed -= available;
/* Then fill the rest in with blanks. */
for (i = gd->hsize + sy - needed; i < gd->hsize + sy; i++) {
gd->size[i] = 0;
gd->data[i] = NULL;
gd->usize[i] = 0;
gd->udata[i] = NULL;
} }
} }
/* Set the new size, and reset the scroll region. */
gd->sy = sy; gd->sy = sy;
s->rupper = 0; s->rupper = 0;
s->rlower = screen_size_y(s) - 1; s->rlower = screen_size_y(s) - 1;
} }

View File

@@ -1,4 +1,4 @@
/* $Id: server-fn.c,v 1.65 2009-07-01 19:15:12 nicm Exp $ */ /* $Id: server-fn.c,v 1.58 2009-04-02 20:30:20 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,7 +20,6 @@
#include <sys/time.h> #include <sys/time.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
#include "tmux.h" #include "tmux.h"
@@ -76,6 +75,22 @@ server_write_session(
} }
} }
void
server_write_window(
struct window *w, enum hdrtype type, const void *buf, size_t len)
{
struct client *c;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c->session->curw->window == w)
server_write_client(c, type, buf, len);
}
}
void void
server_redraw_client(struct client *c) server_redraw_client(struct client *c)
{ {
@@ -168,8 +183,7 @@ server_lock(void)
continue; continue;
status_prompt_clear(c); status_prompt_clear(c);
status_prompt_set( status_prompt_set(c, "Password: ", server_lock_callback, c, 1);
c, "Password: ", server_lock_callback, c, PROMPT_HIDDEN);
server_redraw_client(c); server_redraw_client(c);
} }
server_locked = 1; server_locked = 1;
@@ -190,14 +204,13 @@ server_unlock(const char *s)
if (!server_locked) if (!server_locked)
return (0); return (0);
server_activity = time(NULL);
if (server_password != NULL) { if (server_password != NULL) {
if (s == NULL) if (s == NULL)
return (-1); return (-1);
out = crypt(s, server_password); out = crypt(s, server_password);
if (strcmp(out, server_password) != 0) if (strcmp(out, server_password) != 0)
goto wrong; return (-1);
} }
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -208,20 +221,7 @@ server_unlock(const char *s)
status_prompt_clear(c); status_prompt_clear(c);
server_redraw_client(c); server_redraw_client(c);
} }
server_locked = 0; server_locked = 0;
return (0); return (0);
wrong:
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->prompt_buffer == NULL)
continue;
*c->prompt_buffer = '\0';
c->prompt_index = 0;
server_status_client(c);
}
return (-1);
} }

View File

@@ -1,4 +1,4 @@
/* $Id: server-msg.c,v 1.69 2009-06-25 16:21:32 nicm Exp $ */ /* $Id: server-msg.c,v 1.65 2009-03-07 10:29:06 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -196,7 +196,6 @@ server_msg_fn_identify(struct hdr *hdr, struct client *c)
c->tty.sy = data.sy; c->tty.sy = data.sy;
c->cwd = NULL; c->cwd = NULL;
data.cwd[(sizeof data.cwd) - 1] = '\0';
if (*data.cwd != '\0') if (*data.cwd != '\0')
c->cwd = xstrdup(data.cwd); c->cwd = xstrdup(data.cwd);
@@ -279,14 +278,13 @@ server_msg_fn_unlock(struct hdr *hdr, struct client *c)
if (server_unlock(pass) != 0) { if (server_unlock(pass) != 0) {
#define MSG "bad password" #define MSG "bad password"
server_write_client(c, MSG_ERROR, MSG, (sizeof MSG) - 1); server_write_client(c, MSG_ERROR, MSG, (sizeof MSG) - 1);
server_write_client(c, MSG_EXIT, NULL, 0);
return (0);
#undef MSG #undef MSG
} }
server_write_client(c, MSG_EXIT, NULL, 0); server_write_client(c, MSG_EXIT, NULL, 0);
memset(pass, 0, strlen(pass));
xfree(pass);
return (0); return (0);
} }

219
server.c
View File

@@ -1,4 +1,4 @@
/* $Id: server.c,v 1.153 2009-07-01 23:06:32 nicm Exp $ */ /* $Id: server.c,v 1.137 2009-04-16 10:59:59 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -43,7 +43,6 @@
/* Client list. */ /* Client list. */
struct clients clients; struct clients clients;
int server_create_socket(void);
int server_main(int); int server_main(int);
void server_shutdown(void); void server_shutdown(void);
void server_child_signal(void); void server_child_signal(void);
@@ -53,13 +52,7 @@ void server_fill_clients(struct pollfd **);
void server_handle_clients(struct pollfd **); void server_handle_clients(struct pollfd **);
struct client *server_accept_client(int); struct client *server_accept_client(int);
void server_handle_client(struct client *); void server_handle_client(struct client *);
void server_handle_window(struct window *, struct window_pane *); void server_handle_window(struct window *, struct window_pane *wp);
int server_check_window_bell(struct session *, struct window *,
struct window_pane *);
int server_check_window_activity(struct session *,
struct window *);
int server_check_window_content(struct session *, struct window *,
struct window_pane *);
void server_lost_client(struct client *); void server_lost_client(struct client *);
void server_check_window(struct window *); void server_check_window(struct window *);
void server_check_redraw(struct client *); void server_check_redraw(struct client *);
@@ -131,10 +124,13 @@ server_client_index(struct client *c)
int int
server_start(char *path) server_start(char *path)
{ {
int pair[2], srv_fd, null_fd; struct sockaddr_un sa;
char *cause; size_t size;
#ifdef HAVE_SETPROCTITLE mode_t mask;
char rpathbuf[MAXPATHLEN]; int n, fd, pair[2], mode;
char *cause;
#ifndef NO_SETPROCTITLE
char rpathbuf[MAXPATHLEN];
#endif #endif
/* The first client is special and gets a socketpair; create it. */ /* The first client is special and gets a socketpair; create it. */
@@ -152,6 +148,10 @@ server_start(char *path)
} }
close(pair[0]); close(pair[0]);
#ifdef DEBUG
xmalloc_clear();
#endif
/* /*
* Must daemonise before loading configuration as the PID changes so * Must daemonise before loading configuration as the PID changes so
* $TMUX would be wrong for sessions created in the config file. * $TMUX would be wrong for sessions created in the config file.
@@ -163,7 +163,6 @@ server_start(char *path)
ARRAY_INIT(&clients); ARRAY_INIT(&clients);
ARRAY_INIT(&sessions); ARRAY_INIT(&sessions);
key_bindings_init(); key_bindings_init();
utf8_build();
server_locked = 0; server_locked = 0;
server_password = NULL; server_password = NULL;
@@ -178,42 +177,15 @@ server_start(char *path)
} }
logfile("server"); logfile("server");
/*
* Close stdin/stdout/stderr. Can't let daemon() do this as they are
* needed until now to print configuration file errors.
*/
if ((null_fd = open(_PATH_DEVNULL, O_RDWR)) != -1) {
dup2(null_fd, STDIN_FILENO);
dup2(null_fd, STDOUT_FILENO);
dup2(null_fd, STDERR_FILENO);
if (null_fd > 2)
close(null_fd);
}
log_debug("server started, pid %ld", (long) getpid()); log_debug("server started, pid %ld", (long) getpid());
log_debug("socket path %s", socket_path); log_debug("socket path %s", socket_path);
#ifdef HAVE_SETPROCTITLE #ifndef NO_SETPROCTITLE
if (realpath(socket_path, rpathbuf) == NULL) if (realpath(socket_path, rpathbuf) == NULL)
strlcpy(rpathbuf, socket_path, sizeof rpathbuf); strlcpy(rpathbuf, socket_path, sizeof rpathbuf);
setproctitle("server (%s)", rpathbuf); setproctitle("server (%s)", rpathbuf);
#endif #endif
srv_fd = server_create_socket();
server_create_client(pair[1]);
exit(server_main(srv_fd));
}
/* Create server socket. */
int
server_create_socket(void)
{
struct sockaddr_un sa;
size_t size;
mode_t mask;
int fd, mode;
memset(&sa, 0, sizeof sa); memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX; sa.sun_family = AF_UNIX;
size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path); size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
@@ -241,7 +213,13 @@ server_create_socket(void)
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed"); fatal("fcntl failed");
return (fd); server_create_client(pair[1]);
n = server_main(fd);
#ifdef DEBUG
xmalloc_report(getpid(), "server");
#endif
exit(n);
} }
/* Main server loop. */ /* Main server loop. */
@@ -270,13 +248,6 @@ server_main(int srv_fd)
sigchld = 0; sigchld = 0;
} }
/* Recreate socket on SIGUSR1. */
if (sigusr1) {
close(srv_fd);
srv_fd = server_create_socket();
sigusr1 = 0;
}
/* Initialise pollfd array. */ /* Initialise pollfd array. */
nfds = 1; nfds = 1;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) { for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
@@ -301,10 +272,10 @@ server_main(int srv_fd)
/* Update socket permissions. */ /* Update socket permissions. */
xtimeout = INFTIM; xtimeout = INFTIM;
if (sigterm || server_update_socket() != 0) if (sigterm || server_update_socket() != 0)
xtimeout = POLL_TIMEOUT; xtimeout = 100;
/* Do the poll. */ /* Do the poll. */
if (poll(pfds, nfds, xtimeout) == -1) { if ((nfds = poll(pfds, nfds, xtimeout)) == -1) {
if (errno == EAGAIN || errno == EINTR) if (errno == EAGAIN || errno == EINTR)
continue; continue;
fatal("poll failed"); fatal("poll failed");
@@ -312,7 +283,7 @@ server_main(int srv_fd)
pfd = pfds; pfd = pfds;
/* Handle server socket. */ /* Handle server socket. */
#ifdef HAVE_POLL #ifndef BROKEN_POLL
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP)) if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
fatalx("lost server socket"); fatalx("lost server socket");
#endif #endif
@@ -624,12 +595,12 @@ server_check_timers(struct client *c)
if (!options_get_number(&s->options, "status")) if (!options_get_number(&s->options, "status"))
return; return;
/* Check timer; resolution is only a second so don't be too clever. */
interval = options_get_number(&s->options, "status-interval"); interval = options_get_number(&s->options, "status-interval");
if (interval == 0) if (interval == 0)
return; return;
if (tv.tv_sec < c->status_timer.tv_sec ||
((u_int) tv.tv_sec) - c->status_timer.tv_sec >= interval) tv.tv_sec -= interval;
if (timercmp(&c->status_timer, &tv, <))
c->flags |= CLIENT_STATUS; c->flags |= CLIENT_STATUS;
} }
@@ -888,12 +859,13 @@ void
server_handle_window(struct window *w, struct window_pane *wp) server_handle_window(struct window *w, struct window_pane *wp)
{ {
struct session *s; struct session *s;
u_int i; struct client *c;
int update; u_int i, j;
int action, update;
window_pane_parse(wp); window_pane_parse(wp);
if ((w->flags & (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT)) == 0) if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY))
return; return;
update = 0; update = 0;
@@ -902,89 +874,48 @@ server_handle_window(struct window *w, struct window_pane *wp)
if (s == NULL || !session_has(s, w)) if (s == NULL || !session_has(s, w))
continue; continue;
update += server_check_window_bell(s, w, wp); if (w->flags & WINDOW_BELL &&
update += server_check_window_activity(s, w); !session_alert_has_window(s, w, WINDOW_BELL)) {
update += server_check_window_content(s, w, wp); session_alert_add(s, w, WINDOW_BELL);
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
if (s->flags & SESSION_UNATTACHED)
break;
for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
c = ARRAY_ITEM(&clients, j);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
case BELL_CURRENT:
if (w->active != wp)
break;
for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
c = ARRAY_ITEM(&clients, j);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
}
update = 1;
}
if (options_get_number(&w->options, "monitor-activity") &&
(w->flags & WINDOW_ACTIVITY) &&
!session_alert_has_window(s, w, WINDOW_ACTIVITY)) {
session_alert_add(s, w, WINDOW_ACTIVITY);
update = 1;
}
} }
if (update) if (update)
server_status_window(w); server_status_window(w);
w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT); w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY);
} }
int /* Check if window still exists.. */
server_check_window_bell(
struct session *s, struct window *w, struct window_pane *wp)
{
struct client *c;
u_int i;
int action;
if (!(w->flags & WINDOW_BELL))
return (0);
if (session_alert_has_window(s, w, WINDOW_BELL))
return (0);
session_alert_add(s, w, WINDOW_BELL);
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
if (s->flags & SESSION_UNATTACHED)
break;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
case BELL_CURRENT:
if (w->active != wp)
break;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
}
return (1);
}
int
server_check_window_activity(struct session *s, struct window *w)
{
if (!(w->flags & WINDOW_ACTIVITY))
return (0);
if (!options_get_number(&w->options, "monitor-activity"))
return (0);
if (session_alert_has_window(s, w, WINDOW_ACTIVITY))
return (0);
session_alert_add(s, w, WINDOW_ACTIVITY);
return (1);
}
int
server_check_window_content(
struct session *s, struct window *w, struct window_pane *wp)
{
char *found, *ptr;
if (!(w->flags & WINDOW_CONTENT))
return (0);
if ((ptr = options_get_string(&w->options, "monitor-content")) == NULL)
return (0);
if (*ptr == '\0')
return (0);
if (session_alert_has_window(s, w, WINDOW_CONTENT))
return (0);
if ((found = window_pane_search(wp, ptr, NULL)) == NULL)
return (0);
session_alert_add(s, w, WINDOW_CONTENT);
xfree(found);
return (1);
}
/* Check if window still exists. */
void void
server_check_window(struct window *w) server_check_window(struct window *w)
{ {
@@ -1002,18 +933,13 @@ server_check_window(struct window *w)
wp = TAILQ_FIRST(&w->panes); wp = TAILQ_FIRST(&w->panes);
while (wp != NULL) { while (wp != NULL) {
wq = TAILQ_NEXT(wp, entry); wq = TAILQ_NEXT(wp, entry);
/* if (wp->fd != -1)
* If the pane has died and the remain-on-exit flag is not set, destroyed = 0;
* remove the pane; otherwise, if the flag is set, don't allow else if (!flag) {
* the window to be destroyed (or it'll close when the last
* pane dies).
*/
if (wp->fd == -1 && !flag) {
window_remove_pane(w, wp); window_remove_pane(w, wp);
server_redraw_window(w); server_redraw_window(w);
layout_refresh(w, 0); layout_refresh(w, 0);
} else }
destroyed = 0;
wp = wq; wp = wq;
} }
@@ -1082,7 +1008,6 @@ server_second_timers(void)
} }
} }
/* Check for a minute having passed. */
gmtime_r(&t, &now); gmtime_r(&t, &now);
gmtime_r(&last_t, &then); gmtime_r(&last_t, &then);
if (now.tm_min == then.tm_min) if (now.tm_min == then.tm_min)
@@ -1100,7 +1025,7 @@ server_second_timers(void)
/* Update socket execute permissions based on whether sessions are attached. */ /* Update socket execute permissions based on whether sessions are attached. */
int int
server_update_socket(void) server_update_socket()
{ {
struct session *s; struct session *s;
u_int i; u_int i;

Some files were not shown because too many files have changed in this diff Show More