mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 01:48:47 +00:00
Big internal reorganisation to move tty control into parent.
This commit is contained in:
parent
97eca99d0b
commit
76c8a590db
12
CHANGES
12
CHANGES
@ -1,3 +1,13 @@
|
|||||||
|
27 November 2007
|
||||||
|
|
||||||
|
* Big internal reorganisation. Rather than leaving control of the tty solely in
|
||||||
|
the client and piping all data through a socket to it, change so that the
|
||||||
|
server opens the tty again and reads and writes to it directly. This avoids
|
||||||
|
a lot of buffering and copying.Also reorganise the redrawing stuff so that
|
||||||
|
everything goes through screen_draw_* - this makes the code simpler, but
|
||||||
|
still needs broken up more, and all the ways of writing to screens should be
|
||||||
|
more consistent.
|
||||||
|
|
||||||
26 November 2007
|
26 November 2007
|
||||||
|
|
||||||
* Rather than shifting up one line at a time once the history is full,
|
* Rather than shifting up one line at a time once the history is full,
|
||||||
@ -273,4 +283,4 @@
|
|||||||
(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.86 2007-11-26 22:18:57 nicm Exp $
|
$Id: CHANGES,v 1.87 2007-11-27 19:23:32 nicm Exp $
|
||||||
|
7
Makefile
7
Makefile
@ -1,4 +1,4 @@
|
|||||||
# $Id: Makefile,v 1.48 2007-11-23 17:52:54 nicm Exp $
|
# $Id: Makefile,v 1.49 2007-11-27 19:23:33 nicm Exp $
|
||||||
|
|
||||||
.SUFFIXES: .c .o .y .h
|
.SUFFIXES: .c .o .y .h
|
||||||
.PHONY: clean update-index.html upload-index.html
|
.PHONY: clean update-index.html upload-index.html
|
||||||
@ -17,7 +17,7 @@ META?= \002 # C-b
|
|||||||
|
|
||||||
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
|
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-display.c \
|
xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c screen-display.c \
|
||||||
window.c session.c local.c log.c client.c client-msg.c client-fn.c \
|
window.c session.c log.c client.c client-msg.c client-fn.c \
|
||||||
key-string.c key-bindings.c resize.c cmd.c cmd-new-session.c \
|
key-string.c key-bindings.c resize.c cmd.c cmd-new-session.c \
|
||||||
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.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-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
|
||||||
@ -27,7 +27,8 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
|
|||||||
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c \
|
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c \
|
||||||
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.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-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
|
||||||
cmd-paste-buffer.c window-scroll.c window-more.c window-copy.c
|
cmd-paste-buffer.c window-scroll.c window-more.c window-copy.c \
|
||||||
|
tty.c tty-keys.c tty-write.c
|
||||||
|
|
||||||
CC?= cc
|
CC?= cc
|
||||||
INCDIRS+= -I. -I- -I/usr/local/include
|
INCDIRS+= -I. -I- -I/usr/local/include
|
||||||
|
17
TODO
17
TODO
@ -1,31 +1,16 @@
|
|||||||
- it would be nice if there wasn't so much copying buffers about, audit uses
|
|
||||||
- useful env vars like WINDOW?
|
- useful env vars like WINDOW?
|
||||||
- sort out who controls the buffers in local.c a bit
|
|
||||||
- better checking/emulation for missing term requirements
|
- better checking/emulation for missing term requirements
|
||||||
- alt charset, borders etc (terminfo(5)/Line Graphics)
|
- alt charset, borders etc (terminfo(5)/Line Graphics)
|
||||||
- new window command prompt
|
- new window command prompt
|
||||||
- mouse handling and some other bits elinks needs
|
- mouse handling and some other bits elinks needs
|
||||||
- server doesn't handle SIGTERM anymore...
|
|
||||||
- the whole input/screen/local thing sucks a bit, reorganise/redesign it
|
|
||||||
- line mode/char-at-a-time mode a la telnet?
|
- line mode/char-at-a-time mode a la telnet?
|
||||||
- some of the uses of buffers really sucks. buffer_reverse_add/remove,
|
|
||||||
and buffer_insert_range/delete_range are abominations. this should be
|
|
||||||
rethought
|
|
||||||
- handle ioctl/termios stuff on window sockets
|
- handle ioctl/termios stuff on window sockets
|
||||||
- figure out once and for all what is going on with backspace and del
|
- figure out once and for all what is going on with backspace and del
|
||||||
backspace should be translated per the termios setting.
|
backspace should be translated per the termios setting.
|
||||||
del passed through?
|
del passed through?
|
||||||
- window creation/idle time
|
- window creation/idle time
|
||||||
- attributes could be 8 not 16 bits
|
|
||||||
- profile/optimise, particularly (i suspect) input.c
|
- profile/optimise, particularly (i suspect) input.c
|
||||||
- tidy up input.c a bit
|
|
||||||
- decide about customised status line
|
- decide about customised status line
|
||||||
- client could pass term/tty fd up to server and then do nothing. what problems
|
|
||||||
would this cause? -- need access to all terminfo data at once... signals?
|
|
||||||
- cleanup/redesign IPC
|
|
||||||
IPC is slightly arse-about-face: overhead? 8-byte header for
|
|
||||||
each packet... hrm. already scanning output for \e, could add an extra
|
|
||||||
byte to it for message
|
|
||||||
- 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?)
|
||||||
- commands should have to care less about CMD_KEY
|
- commands should have to care less about CMD_KEY
|
||||||
@ -71,6 +56,8 @@
|
|||||||
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
|
||||||
|
- screen_draw_* moved out/renamed (accept TTY_*?)
|
||||||
|
- SIGWINCH can probably be handled in server
|
||||||
|
|
||||||
-- For 0.2 --------------------------------------------------------------------
|
-- For 0.2 --------------------------------------------------------------------
|
||||||
- window splitting?
|
- window splitting?
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: buffer-poll.c,v 1.2 2007-11-07 19:41:17 nicm Exp $ */
|
/* $Id: buffer-poll.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -53,3 +53,24 @@ 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) {
|
||||||
|
pfd.fd = fd;
|
||||||
|
pfd.events = POLLIN|POLLOUT;
|
||||||
|
|
||||||
|
if (poll(&pfd, 1, INFTIM) == -1) {
|
||||||
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
|
continue;
|
||||||
|
fatal("poll failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer_poll(&pfd, in, out) != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
43
buffer.c
43
buffer.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: buffer.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
|
/* $Id: buffer.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -179,3 +179,44 @@ buffer_read(struct buffer *b, void *data, size_t size)
|
|||||||
memcpy(data, BUFFER_OUT(b), size);
|
memcpy(data, BUFFER_OUT(b), size);
|
||||||
buffer_remove(b, size);
|
buffer_remove(b, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Store an 8-bit value. */
|
||||||
|
void
|
||||||
|
buffer_write8(struct buffer *b, uint8_t n)
|
||||||
|
{
|
||||||
|
buffer_ensure(b, 1);
|
||||||
|
BUFFER_IN(b)[0] = n;
|
||||||
|
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. */
|
||||||
|
uint8_t
|
||||||
|
buffer_read8(struct buffer *b)
|
||||||
|
{
|
||||||
|
uint8_t n;
|
||||||
|
|
||||||
|
n = BUFFER_OUT(b)[0];
|
||||||
|
buffer_remove(b, 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
25
client-msg.c
25
client-msg.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: client-msg.c,v 1.10 2007-10-19 20:50:01 nicm Exp $ */
|
/* $Id: client-msg.c,v 1.11 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
|
|
||||||
int client_msg_fn_data(struct hdr *, struct client_ctx *, char **);
|
|
||||||
int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
|
int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
|
||||||
int client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
|
int client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
|
||||||
int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
|
int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
|
||||||
@ -38,11 +37,9 @@ struct client_msg {
|
|||||||
int (*fn)(struct hdr *, struct client_ctx *, char **);
|
int (*fn)(struct hdr *, struct client_ctx *, char **);
|
||||||
};
|
};
|
||||||
struct client_msg client_msg_table[] = {
|
struct client_msg client_msg_table[] = {
|
||||||
{ MSG_DATA, client_msg_fn_data },
|
|
||||||
{ MSG_DETACH, client_msg_fn_detach },
|
{ MSG_DETACH, client_msg_fn_detach },
|
||||||
{ MSG_ERROR, client_msg_fn_error },
|
{ MSG_ERROR, client_msg_fn_error },
|
||||||
{ MSG_EXIT, client_msg_fn_exit },
|
{ MSG_EXIT, client_msg_fn_exit },
|
||||||
{ MSG_PAUSE, client_msg_fn_pause },
|
|
||||||
};
|
};
|
||||||
#define NCLIENTMSG (sizeof client_msg_table / sizeof client_msg_table[0])
|
#define NCLIENTMSG (sizeof client_msg_table / sizeof client_msg_table[0])
|
||||||
|
|
||||||
@ -71,26 +68,6 @@ client_msg_dispatch(struct client_ctx *cctx, char **error)
|
|||||||
fatalx("unexpected message");
|
fatalx("unexpected message");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
client_msg_fn_data(
|
|
||||||
struct hdr *hdr, struct client_ctx *cctx, unused char **error)
|
|
||||||
{
|
|
||||||
local_output(cctx->srv_in, hdr->size);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
client_msg_fn_pause(
|
|
||||||
struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
|
|
||||||
{
|
|
||||||
if (hdr->size != 0)
|
|
||||||
fatalx("bad MSG_PAUSE size");
|
|
||||||
|
|
||||||
cctx->flags |= CCTX_PAUSE;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
61
client.c
61
client.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: client.c,v 1.22 2007-11-26 20:36:30 nicm Exp $ */
|
/* $Id: client.c,v 1.23 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -33,7 +33,6 @@
|
|||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
|
|
||||||
void client_handle_winch(struct client_ctx *);
|
void client_handle_winch(struct client_ctx *);
|
||||||
int client_process_local(struct client_ctx *, char **);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
client_init(const char *path, struct client_ctx *cctx, int start_server)
|
client_init(const char *path, struct client_ctx *cctx, int start_server)
|
||||||
@ -113,6 +112,7 @@ retry:
|
|||||||
if (ttyname_r(STDIN_FILENO, data.tty, sizeof data.tty) != 0)
|
if (ttyname_r(STDIN_FILENO, data.tty, sizeof data.tty) != 0)
|
||||||
fatal("ttyname_r failed");
|
fatal("ttyname_r failed");
|
||||||
client_write_server(cctx, MSG_IDENTIFY, &data, sizeof data);
|
client_write_server(cctx, MSG_IDENTIFY, &data, sizeof data);
|
||||||
|
cmd_send_string(cctx->srv_out, getenv("TERM"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -121,13 +121,11 @@ retry:
|
|||||||
int
|
int
|
||||||
client_main(struct client_ctx *cctx)
|
client_main(struct client_ctx *cctx)
|
||||||
{
|
{
|
||||||
struct pollfd pfds[2];
|
struct pollfd pfd;
|
||||||
char *error;
|
char *error;
|
||||||
int timeout;
|
int timeout;
|
||||||
|
|
||||||
siginit();
|
siginit();
|
||||||
if ((cctx->loc_fd = local_init(&cctx->loc_in, &cctx->loc_out)) == -1)
|
|
||||||
return (1);
|
|
||||||
|
|
||||||
logfile("client");
|
logfile("client");
|
||||||
#ifndef NO_SETPROCTITLE
|
#ifndef NO_SETPROCTITLE
|
||||||
@ -140,33 +138,19 @@ client_main(struct client_ctx *cctx)
|
|||||||
if (sigwinch)
|
if (sigwinch)
|
||||||
client_handle_winch(cctx);
|
client_handle_winch(cctx);
|
||||||
|
|
||||||
pfds[0].fd = cctx->srv_fd;
|
pfd.fd = cctx->srv_fd;
|
||||||
pfds[0].events = POLLIN;
|
pfd.events = POLLIN;
|
||||||
if (BUFFER_USED(cctx->srv_out) > 0)
|
if (BUFFER_USED(cctx->srv_out) > 0)
|
||||||
pfds[0].events |= POLLOUT;
|
pfd.events |= POLLOUT;
|
||||||
pfds[1].fd = cctx->loc_fd;
|
|
||||||
pfds[1].events = POLLIN;
|
|
||||||
if (BUFFER_USED(cctx->loc_out) > 0)
|
|
||||||
pfds[1].events |= POLLOUT;
|
|
||||||
|
|
||||||
if (poll(pfds, 2, timeout) == -1) {
|
if (poll(&pfd, 1, timeout) == -1) {
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
fatal("poll failed");
|
fatal("poll failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_poll(&pfds[0], cctx->srv_in, cctx->srv_out) != 0)
|
if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
|
||||||
goto server_dead;
|
goto server_dead;
|
||||||
if (buffer_poll(&pfds[1], cctx->loc_in, cctx->loc_out) != 0)
|
|
||||||
goto local_dead;
|
|
||||||
|
|
||||||
if (cctx->flags & CCTX_PAUSE) {
|
|
||||||
usleep(750000);
|
|
||||||
cctx->flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client_process_local(cctx, &error) == -1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
switch (client_msg_dispatch(cctx, &error)) {
|
switch (client_msg_dispatch(cctx, &error)) {
|
||||||
case -1:
|
case -1:
|
||||||
@ -183,8 +167,6 @@ client_main(struct client_ctx *cctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
local_done();
|
|
||||||
|
|
||||||
if (sigterm) {
|
if (sigterm) {
|
||||||
printf("[terminated]\n");
|
printf("[terminated]\n");
|
||||||
return (1);
|
return (1);
|
||||||
@ -204,14 +186,8 @@ out:
|
|||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
server_dead:
|
server_dead:
|
||||||
local_done();
|
|
||||||
|
|
||||||
printf("[lost server]\n");
|
printf("[lost server]\n");
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
local_dead:
|
|
||||||
/* Can't do much here. Log and die. */
|
|
||||||
fatalx("local socket dead");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -229,24 +205,3 @@ client_handle_winch(struct client_ctx *cctx)
|
|||||||
|
|
||||||
sigwinch = 0;
|
sigwinch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
client_process_local(struct client_ctx *cctx, unused char **error)
|
|
||||||
{
|
|
||||||
struct buffer *b;
|
|
||||||
int key;
|
|
||||||
|
|
||||||
b = buffer_create(BUFSIZ);
|
|
||||||
while ((key = local_key()) != KEYC_NONE)
|
|
||||||
input_store16(b, (uint16_t) key);
|
|
||||||
|
|
||||||
log_debug("transmitting %zu bytes of input", BUFFER_USED(b));
|
|
||||||
if (BUFFER_USED(b) != 0) {
|
|
||||||
client_write_server(
|
|
||||||
cctx, MSG_KEYS, BUFFER_OUT(b), BUFFER_USED(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer_destroy(b);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cmd-attach-session.c,v 1.9 2007-11-16 21:12:31 nicm Exp $ */
|
/* $Id: cmd-attach-session.c,v 1.10 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -83,6 +83,7 @@ void
|
|||||||
cmd_attach_session_exec(void *ptr, struct cmd_ctx *ctx)
|
cmd_attach_session_exec(void *ptr, struct cmd_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct cmd_attach_session_data *data = ptr;
|
struct cmd_attach_session_data *data = ptr;
|
||||||
|
char *cause;
|
||||||
|
|
||||||
if (ctx->flags & CMD_KEY)
|
if (ctx->flags & CMD_KEY)
|
||||||
return;
|
return;
|
||||||
@ -92,6 +93,12 @@ cmd_attach_session_exec(void *ptr, struct cmd_ctx *ctx)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tty_open(&ctx->cmdclient->tty, &cause) != 0) {
|
||||||
|
ctx->error(ctx, "%s", cause);
|
||||||
|
xfree(cause);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (data->flag_detach)
|
if (data->flag_detach)
|
||||||
server_write_session(ctx->session, MSG_DETACH, NULL, 0);
|
server_write_session(ctx->session, MSG_DETACH, NULL, 0);
|
||||||
ctx->cmdclient->session = ctx->session;
|
ctx->cmdclient->session = ctx->session;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cmd-copy-mode.c,v 1.1 2007-11-23 14:28:47 nicm Exp $ */
|
/* $Id: cmd-copy-mode.c,v 1.2 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -47,7 +47,7 @@ cmd_copy_mode_exec(unused void *ptr, struct cmd_ctx *ctx)
|
|||||||
if (w->mode == NULL && ctx->flags & CMD_KEY) {
|
if (w->mode == NULL && ctx->flags & CMD_KEY) {
|
||||||
w->mode = &window_copy_mode;
|
w->mode = &window_copy_mode;
|
||||||
w->mode->init(w);
|
w->mode->init(w);
|
||||||
server_redraw_window_all(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->cmdclient != NULL)
|
if (ctx->cmdclient != NULL)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cmd-list-clients.c,v 1.2 2007-11-16 21:12:31 nicm Exp $ */
|
/* $Id: cmd-list-clients.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -51,8 +51,8 @@ cmd_list_clients_exec(unused void *ptr, struct cmd_ctx *ctx)
|
|||||||
if (c == NULL || c->session == NULL)
|
if (c == NULL || c->session == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ctx->print(ctx,
|
ctx->print(ctx, "%s: %s [%ux%u]",
|
||||||
"%s: %s [%ux%u]", c->tty, c->session->name, c->sx, c->sy);
|
c->tty.path, c->session->name, c->sx, c->sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->cmdclient != NULL)
|
if (ctx->cmdclient != NULL)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cmd-new-session.c,v 1.17 2007-11-16 21:12:31 nicm Exp $ */
|
/* $Id: cmd-new-session.c,v 1.18 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -100,8 +100,8 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
|
|||||||
{
|
{
|
||||||
struct cmd_new_session_data *data = ptr;
|
struct cmd_new_session_data *data = ptr;
|
||||||
struct cmd_new_session_data std = { NULL, NULL, NULL, 0 };
|
struct cmd_new_session_data std = { NULL, NULL, NULL, 0 };
|
||||||
struct client *c;
|
struct client *c = ctx->cmdclient;
|
||||||
char *cmd;
|
char *cmd, *cause;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
@ -110,7 +110,6 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
|
|||||||
if (ctx->flags & CMD_KEY)
|
if (ctx->flags & CMD_KEY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
c = ctx->cmdclient;
|
|
||||||
if (!data->flag_detached && !(c->flags & CLIENT_TERMINAL)) {
|
if (!data->flag_detached && !(c->flags & CLIENT_TERMINAL)) {
|
||||||
ctx->error(ctx, "not a terminal");
|
ctx->error(ctx, "not a terminal");
|
||||||
return;
|
return;
|
||||||
@ -126,6 +125,12 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
|
|||||||
sy = status_lines + 1;
|
sy = status_lines + 1;
|
||||||
sy -= status_lines;
|
sy -= status_lines;
|
||||||
|
|
||||||
|
if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) {
|
||||||
|
ctx->error(ctx, "%s", cause);
|
||||||
|
xfree(cause);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cmd = data->cmd;
|
cmd = data->cmd;
|
||||||
if (cmd == NULL)
|
if (cmd == NULL)
|
||||||
cmd = default_command;
|
cmd = default_command;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: cmd-scroll-mode.c,v 1.3 2007-11-22 18:09:43 nicm Exp $ */
|
/* $Id: cmd-scroll-mode.c,v 1.4 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -47,7 +47,7 @@ cmd_scroll_mode_exec(unused void *ptr, struct cmd_ctx *ctx)
|
|||||||
if (w->mode == NULL && ctx->flags & CMD_KEY) {
|
if (w->mode == NULL && ctx->flags & CMD_KEY) {
|
||||||
w->mode = &window_scroll_mode;
|
w->mode = &window_scroll_mode;
|
||||||
w->mode->init(w);
|
w->mode->init(w);
|
||||||
server_redraw_window_all(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->cmdclient != NULL)
|
if (ctx->cmdclient != NULL)
|
||||||
|
10
input-keys.c
10
input-keys.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: input-keys.c,v 1.3 2007-11-21 13:11:41 nicm Exp $ */
|
/* $Id: input-keys.c,v 1.4 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -55,13 +55,13 @@ struct {
|
|||||||
|
|
||||||
/* Translate a key code from client into an output key sequence. */
|
/* Translate a key code from client into an output key sequence. */
|
||||||
void
|
void
|
||||||
input_key(struct buffer *b, int key)
|
input_key(struct window *w, int key)
|
||||||
{
|
{
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
log_debug2("writing key %d", key);
|
log_debug2("writing key %d", key);
|
||||||
if (key != KEYC_NONE && key >= 0) {
|
if (key != KEYC_NONE && key >= 0) {
|
||||||
input_store8(b, key);
|
buffer_write8(w->out, (uint8_t) key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,8 +69,8 @@ input_key(struct buffer *b, int key)
|
|||||||
if (input_keys[i].key == key) {
|
if (input_keys[i].key == key) {
|
||||||
log_debug2(
|
log_debug2(
|
||||||
"found key %d: \"%s\"", key, input_keys[i].data);
|
"found key %d: \"%s\"", key, input_keys[i].data);
|
||||||
buffer_write(
|
buffer_write(w->out,
|
||||||
b, input_keys[i].data, strlen(input_keys[i].data));
|
input_keys[i].data, strlen(input_keys[i].data));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
217
input.c
217
input.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: input.c,v 1.38 2007-11-24 23:29:49 nicm Exp $ */
|
/* $Id: input.c,v 1.39 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -36,7 +36,9 @@
|
|||||||
|
|
||||||
int input_get_argument(struct input_ctx *, u_int, uint16_t *, uint16_t);
|
int input_get_argument(struct input_ctx *, u_int, uint16_t *, uint16_t);
|
||||||
int input_new_argument(struct input_ctx *);
|
int input_new_argument(struct input_ctx *);
|
||||||
int input_add_argument(struct input_ctx *, u_char ch);
|
int input_add_argument(struct input_ctx *, u_char);
|
||||||
|
|
||||||
|
void input_write(struct input_ctx *, int, ...);
|
||||||
|
|
||||||
void *input_state_first(u_char, struct input_ctx *);
|
void *input_state_first(u_char, struct input_ctx *);
|
||||||
void *input_state_escape(u_char, struct input_ctx *);
|
void *input_state_escape(u_char, struct input_ctx *);
|
||||||
@ -131,6 +133,19 @@ input_get_argument(struct input_ctx *ictx, u_int i, uint16_t *n, uint16_t d)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
input_write(struct input_ctx *ictx, int cmd, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (ictx->w->screen.mode & (MODE_HIDDEN|MODE_BACKGROUND))
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_start(ap, cmd);
|
||||||
|
tty_vwrite_window(ictx->w, cmd, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
input_init(struct window *w)
|
input_init(struct window *w)
|
||||||
{
|
{
|
||||||
@ -146,7 +161,7 @@ input_free(struct window *w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
input_parse(struct window *w, struct buffer *b)
|
input_parse(struct window *w)
|
||||||
{
|
{
|
||||||
struct input_ctx *ictx = &w->ictx;
|
struct input_ctx *ictx = &w->ictx;
|
||||||
u_char ch;
|
u_char ch;
|
||||||
@ -159,7 +174,6 @@ input_parse(struct window *w, struct buffer *b)
|
|||||||
ictx->off = 0;
|
ictx->off = 0;
|
||||||
|
|
||||||
ictx->w = w;
|
ictx->w = w;
|
||||||
ictx->b = b;
|
|
||||||
|
|
||||||
log_debug2("entry; buffer=%zu", ictx->len);
|
log_debug2("entry; buffer=%zu", ictx->len);
|
||||||
|
|
||||||
@ -264,8 +278,7 @@ input_state_title_next(u_char ch, struct input_ctx *ictx)
|
|||||||
switch (ictx->title_type) {
|
switch (ictx->title_type) {
|
||||||
case 0:
|
case 0:
|
||||||
strlcpy(s->title, ictx->title_buf, sizeof s->title);
|
strlcpy(s->title, ictx->title_buf, sizeof s->title);
|
||||||
input_store_one(ictx->b, CODE_TITLE, ictx->title_len);
|
input_write(ictx, TTY_TITLE, s->title);
|
||||||
buffer_write(ictx->b, ictx->title_buf, ictx->title_len);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (input_state_first);
|
return (input_state_first);
|
||||||
@ -373,10 +386,8 @@ input_handle_character(u_char ch, struct input_ctx *ictx)
|
|||||||
log_debug2("-- ch %zu: %hhu (%c)", ictx->off, ch, ch);
|
log_debug2("-- ch %zu: %hhu (%c)", ictx->off, ch, ch);
|
||||||
|
|
||||||
if (s->cx == screen_size_x(s)) {
|
if (s->cx == screen_size_x(s)) {
|
||||||
if (!screen_hidden(s)) {
|
input_write(ictx, TTY_CHARACTER, '\r');
|
||||||
input_store8(ictx->b, '\r');
|
input_write(ictx, TTY_CHARACTER, '\n');
|
||||||
input_store8(ictx->b, '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
s->cx = 0;
|
s->cx = 0;
|
||||||
screen_display_cursor_down(s);
|
screen_display_cursor_down(s);
|
||||||
@ -384,8 +395,7 @@ input_handle_character(u_char ch, struct input_ctx *ictx)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
screen_display_cursor_set(s, ch);
|
screen_display_cursor_set(s, ch);
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CHARACTER, ch);
|
||||||
input_store8(ictx->b, ch);
|
|
||||||
|
|
||||||
s->cx++;
|
s->cx++;
|
||||||
}
|
}
|
||||||
@ -399,7 +409,7 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
|
|||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '\0': /* NUL */
|
case '\0': /* NUL */
|
||||||
break;
|
return;
|
||||||
case '\n': /* LF */
|
case '\n': /* LF */
|
||||||
screen_display_cursor_down(s);
|
screen_display_cursor_down(s);
|
||||||
break;
|
break;
|
||||||
@ -419,28 +429,21 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
|
|||||||
s->cx = 0;
|
s->cx = 0;
|
||||||
screen_display_cursor_down(s);
|
screen_display_cursor_down(s);
|
||||||
}
|
}
|
||||||
if (screen_hidden(s))
|
input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
|
||||||
return;
|
|
||||||
input_store_two(ictx->b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
|
|
||||||
return;
|
return;
|
||||||
case '\016': /* SO */
|
case '\016': /* SO */
|
||||||
s->attr |= ATTR_DRAWING;
|
s->attr |= ATTR_DRAWING;
|
||||||
if (screen_hidden(s))
|
input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
|
||||||
return;
|
|
||||||
input_store_two(ictx->b, CODE_ATTRIBUTES, s->attr, s->colr);
|
|
||||||
return;
|
return;
|
||||||
case '\017': /* SI */
|
case '\017': /* SI */
|
||||||
s->attr &= ~ATTR_DRAWING;
|
s->attr &= ~ATTR_DRAWING;
|
||||||
if (screen_hidden(s))
|
input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
|
||||||
return;
|
|
||||||
input_store_two(ictx->b, CODE_ATTRIBUTES, s->attr, s->colr);
|
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
log_debug("unknown c0: %hhu", ch);
|
log_debug("unknown c0: %hhu", ch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CHARACTER, ch);
|
||||||
input_store8(ictx->b, ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -453,8 +456,7 @@ input_handle_c1_control(u_char ch, struct input_ctx *ictx)
|
|||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'M': /* RI */
|
case 'M': /* RI */
|
||||||
screen_display_cursor_up(s);
|
screen_display_cursor_up(s);
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_REVERSEINDEX);
|
||||||
input_store_zero(ictx->b, CODE_REVERSEINDEX);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("unknown c1: %hhu", ch);
|
log_debug("unknown c1: %hhu", ch);
|
||||||
@ -471,12 +473,10 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
|
|||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '=': /* DECKPAM */
|
case '=': /* DECKPAM */
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_KKEYPADON);
|
||||||
input_store_zero(ictx->b, CODE_KKEYPADON);
|
|
||||||
break;
|
break;
|
||||||
case '>': /* DECKPNM*/
|
case '>': /* DECKPNM*/
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_KKEYPADOFF);
|
||||||
input_store_zero(ictx->b, CODE_KKEYPADOFF);
|
|
||||||
break;
|
break;
|
||||||
case '7': /* DECSC */
|
case '7': /* DECSC */
|
||||||
s->saved_cx = s->cx;
|
s->saved_cx = s->cx;
|
||||||
@ -492,10 +492,8 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
|
|||||||
s->cy = s->saved_cy;
|
s->cy = s->saved_cy;
|
||||||
s->attr = s->saved_attr;
|
s->attr = s->saved_attr;
|
||||||
s->colr = s->saved_colr;
|
s->colr = s->saved_colr;
|
||||||
if (screen_hidden(s))
|
input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
|
||||||
break;
|
input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
|
||||||
input_store_two(ictx->b, CODE_ATTRIBUTES, s->attr, s->colr);
|
|
||||||
input_store_two(ictx->b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("unknown p2: %hhu", ch);
|
log_debug("unknown p2: %hhu", ch);
|
||||||
@ -583,8 +581,7 @@ input_handle_sequence_cuu(struct input_ctx *ictx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->cy -= n;
|
s->cy -= n;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSORUP, n);
|
||||||
input_store_one(ictx->b, CODE_CURSORUP, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -606,8 +603,7 @@ input_handle_sequence_cud(struct input_ctx *ictx)
|
|||||||
input_limit(n, 1, screen_last_y(s) - s->cy);
|
input_limit(n, 1, screen_last_y(s) - s->cy);
|
||||||
|
|
||||||
s->cy += n;
|
s->cy += n;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSORDOWN, n);
|
||||||
input_store_one(ictx->b, CODE_CURSORDOWN, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -629,8 +625,7 @@ input_handle_sequence_cuf(struct input_ctx *ictx)
|
|||||||
input_limit(n, 1, screen_last_x(s) - s->cx);
|
input_limit(n, 1, screen_last_x(s) - s->cx);
|
||||||
|
|
||||||
s->cx += n;
|
s->cx += n;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSORRIGHT, n);
|
||||||
input_store_one(ictx->b, CODE_CURSORRIGHT, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -653,8 +648,7 @@ input_handle_sequence_cub(struct input_ctx *ictx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->cx -= n;
|
s->cx -= n;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSORLEFT, n);
|
||||||
input_store_one(ictx->b, CODE_CURSORLEFT, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -676,8 +670,7 @@ input_handle_sequence_dch(struct input_ctx *ictx)
|
|||||||
input_limit(n, 1, screen_last_x(s) - s->cx);
|
input_limit(n, 1, screen_last_x(s) - s->cx);
|
||||||
|
|
||||||
screen_display_delete_characters(s, s->cx, s->cy, n);
|
screen_display_delete_characters(s, s->cx, s->cy, n);
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_DELETECHARACTER, n);
|
||||||
input_store_one(ictx->b, CODE_DELETECHARACTER, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -702,8 +695,7 @@ input_handle_sequence_dl(struct input_ctx *ictx)
|
|||||||
screen_display_delete_lines(s, s->cy, n);
|
screen_display_delete_lines(s, s->cy, n);
|
||||||
else
|
else
|
||||||
screen_display_delete_lines_region(s, s->cy, n);
|
screen_display_delete_lines_region(s, s->cy, n);
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_DELETELINE, n);
|
||||||
input_store_one(ictx->b, CODE_DELETELINE, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -725,8 +717,7 @@ input_handle_sequence_ich(struct input_ctx *ictx)
|
|||||||
input_limit(n, 1, screen_last_x(s) - s->cx);
|
input_limit(n, 1, screen_last_x(s) - s->cx);
|
||||||
|
|
||||||
screen_display_insert_characters(s, s->cx, s->cy, n);
|
screen_display_insert_characters(s, s->cx, s->cy, n);
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_INSERTCHARACTER, n);
|
||||||
input_store_one(ictx->b, CODE_INSERTCHARACTER, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -751,8 +742,7 @@ input_handle_sequence_il(struct input_ctx *ictx)
|
|||||||
screen_display_insert_lines(s, s->cy, n);
|
screen_display_insert_lines(s, s->cy, n);
|
||||||
else
|
else
|
||||||
screen_display_insert_lines_region(s, s->cy, n);
|
screen_display_insert_lines_region(s, s->cy, n);
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_INSERTLINE, n);
|
||||||
input_store_one(ictx->b, CODE_INSERTLINE, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -774,8 +764,7 @@ input_handle_sequence_vpa(struct input_ctx *ictx)
|
|||||||
input_limit(n, 1, screen_size_y(s));
|
input_limit(n, 1, screen_size_y(s));
|
||||||
|
|
||||||
s->cy = n - 1;
|
s->cy = n - 1;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
|
||||||
input_store_two(ictx->b, CODE_CURSORMOVE, n, s->cx + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -797,8 +786,7 @@ input_handle_sequence_hpa(struct input_ctx *ictx)
|
|||||||
input_limit(n, 1, screen_size_x(s));
|
input_limit(n, 1, screen_size_x(s));
|
||||||
|
|
||||||
s->cx = n - 1;
|
s->cx = n - 1;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
|
||||||
input_store_two(ictx->b, CODE_CURSORMOVE, s->cy + 1, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -822,8 +810,7 @@ input_handle_sequence_cup(struct input_ctx *ictx)
|
|||||||
|
|
||||||
s->cx = m - 1;
|
s->cx = m - 1;
|
||||||
s->cy = n - 1;
|
s->cy = n - 1;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
|
||||||
input_store_two(ictx->b, CODE_CURSORMOVE, n, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -849,28 +836,21 @@ input_handle_sequence_ed(struct input_ctx *ictx)
|
|||||||
screen_display_fill_cursor_eos(
|
screen_display_fill_cursor_eos(
|
||||||
s, SCREEN_DEFDATA, s->attr, s->colr);
|
s, SCREEN_DEFDATA, s->attr, s->colr);
|
||||||
|
|
||||||
if (screen_hidden(s))
|
for (i = s->cy; i < screen_size_y(s); i++) {
|
||||||
break;
|
input_write(ictx, TTY_CURSORMOVE, i, 0);
|
||||||
input_store_zero(ictx->b, CODE_CLEARLINE);
|
input_write(ictx, TTY_CLEARENDOFLINE);
|
||||||
for (i = s->cy + 1; i < screen_size_y(s); i++) {
|
|
||||||
input_store_two(ictx->b, CODE_CURSORMOVE, i + 1, 1);
|
|
||||||
input_store_zero(ictx->b, CODE_CLEARLINE);
|
|
||||||
}
|
}
|
||||||
input_store_two(
|
input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
|
||||||
ictx->b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
screen_display_fill_lines(
|
screen_display_fill_lines(
|
||||||
s, 0, screen_size_y(s), SCREEN_DEFDATA, s->attr, s->colr);
|
s, 0, screen_size_y(s), SCREEN_DEFDATA, s->attr, s->colr);
|
||||||
|
|
||||||
if (screen_hidden(s))
|
|
||||||
break;
|
|
||||||
for (i = 0; i < screen_size_y(s); i++) {
|
for (i = 0; i < screen_size_y(s); i++) {
|
||||||
input_store_two(ictx->b, CODE_CURSORMOVE, i + 1, 1);
|
input_write(ictx, TTY_CURSORMOVE, i, 0);
|
||||||
input_store_zero(ictx->b, CODE_CLEARLINE);
|
input_write(ictx, TTY_CLEARENDOFLINE);
|
||||||
}
|
}
|
||||||
input_store_two(
|
input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
|
||||||
ictx->b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -896,23 +876,17 @@ input_handle_sequence_el(struct input_ctx *ictx)
|
|||||||
case 0:
|
case 0:
|
||||||
screen_display_fill_cursor_eol(
|
screen_display_fill_cursor_eol(
|
||||||
s, SCREEN_DEFDATA, s->attr, s->colr);
|
s, SCREEN_DEFDATA, s->attr, s->colr);
|
||||||
|
input_write(ictx, TTY_CLEARENDOFLINE);
|
||||||
if (!screen_hidden(s))
|
|
||||||
input_store_zero(ictx->b, CODE_CLEARENDOFLINE);
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
screen_display_fill_cursor_bol(
|
screen_display_fill_cursor_bol(
|
||||||
s, SCREEN_DEFDATA, s->attr, s->colr);
|
s, SCREEN_DEFDATA, s->attr, s->colr);
|
||||||
|
input_write(ictx, TTY_CLEARSTARTOFLINE);
|
||||||
if (!screen_hidden(s))
|
|
||||||
input_store_zero(ictx->b, CODE_CLEARSTARTOFLINE);
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
screen_display_fill_line(
|
screen_display_fill_line(
|
||||||
s, s->cy, SCREEN_DEFDATA, s->attr, s->colr);
|
s, s->cy, SCREEN_DEFDATA, s->attr, s->colr);
|
||||||
|
input_write(ictx, TTY_CLEARLINE);
|
||||||
if (!screen_hidden(s))
|
|
||||||
input_store_zero(ictx->b, CODE_CLEARLINE);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -932,13 +906,11 @@ input_handle_sequence_sm(struct input_ctx *ictx)
|
|||||||
switch (n) {
|
switch (n) {
|
||||||
case 1: /* GATM */
|
case 1: /* GATM */
|
||||||
s->mode |= MODE_KCURSOR;
|
s->mode |= MODE_KCURSOR;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_KCURSORON);
|
||||||
input_store_zero(ictx->b, CODE_KCURSORON);
|
|
||||||
break;
|
break;
|
||||||
case 25: /* TCEM */
|
case 25: /* TCEM */
|
||||||
s->mode |= MODE_CURSOR;
|
s->mode |= MODE_CURSOR;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSORON);
|
||||||
input_store_zero(ictx->b, CODE_CURSORON);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("unknown SM [%hhu]: %u", ictx->private, n);
|
log_debug("unknown SM [%hhu]: %u", ictx->private, n);
|
||||||
@ -948,8 +920,7 @@ input_handle_sequence_sm(struct input_ctx *ictx)
|
|||||||
switch (n) {
|
switch (n) {
|
||||||
case 4: /* IRM */
|
case 4: /* IRM */
|
||||||
s->mode |= MODE_INSERT;
|
s->mode |= MODE_INSERT;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_INSERTON);
|
||||||
input_store_zero(ictx->b, CODE_INSERTON);
|
|
||||||
break;
|
break;
|
||||||
case 34:
|
case 34:
|
||||||
/* Cursor high visibility not supported. */
|
/* Cursor high visibility not supported. */
|
||||||
@ -976,13 +947,11 @@ input_handle_sequence_rm(struct input_ctx *ictx)
|
|||||||
switch (n) {
|
switch (n) {
|
||||||
case 1: /* GATM */
|
case 1: /* GATM */
|
||||||
s->mode &= ~MODE_KCURSOR;
|
s->mode &= ~MODE_KCURSOR;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_KCURSOROFF);
|
||||||
input_store_zero(ictx->b, CODE_KCURSOROFF);
|
|
||||||
break;
|
break;
|
||||||
case 25: /* TCEM */
|
case 25: /* TCEM */
|
||||||
s->mode &= ~MODE_CURSOR;
|
s->mode &= ~MODE_CURSOR;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_CURSOROFF);
|
||||||
input_store_zero(ictx->b, CODE_CURSOROFF);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("unknown RM [%hhu]: %u", ictx->private, n);
|
log_debug("unknown RM [%hhu]: %u", ictx->private, n);
|
||||||
@ -992,8 +961,7 @@ input_handle_sequence_rm(struct input_ctx *ictx)
|
|||||||
switch (n) {
|
switch (n) {
|
||||||
case 4: /* IRM */
|
case 4: /* IRM */
|
||||||
s->mode &= ~MODE_INSERT;
|
s->mode &= ~MODE_INSERT;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_INSERTOFF);
|
||||||
input_store_zero(ictx->b, CODE_INSERTOFF);
|
|
||||||
break;
|
break;
|
||||||
case 34:
|
case 34:
|
||||||
/* Cursor high visibility not supported. */
|
/* Cursor high visibility not supported. */
|
||||||
@ -1067,8 +1035,7 @@ input_handle_sequence_decstbm(struct input_ctx *ictx)
|
|||||||
|
|
||||||
s->rupper = n - 1;
|
s->rupper = n - 1;
|
||||||
s->rlower = m - 1;
|
s->rlower = m - 1;
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_SCROLLREGION, s->rupper, s->rlower);
|
||||||
input_store_two(ictx->b, CODE_SCROLLREGION, n, m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1152,67 +1119,5 @@ input_handle_sequence_sgr(struct input_ctx *ictx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!screen_hidden(s))
|
input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
|
||||||
input_store_two(ictx->b, CODE_ATTRIBUTES, s->attr, s->colr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
input_store_zero(struct buffer *b, u_char code)
|
|
||||||
{
|
|
||||||
input_store8(b, '\e');
|
|
||||||
input_store8(b, code);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
input_store_one(struct buffer *b, u_char code, uint16_t ua)
|
|
||||||
{
|
|
||||||
input_store8(b, '\e');
|
|
||||||
input_store8(b, code);
|
|
||||||
input_store16(b, ua);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
input_store_two(struct buffer *b, u_char code, uint16_t ua, uint16_t ub)
|
|
||||||
{
|
|
||||||
input_store8(b, '\e');
|
|
||||||
input_store8(b, code);
|
|
||||||
input_store16(b, ua);
|
|
||||||
input_store16(b, ub);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
input_store8(struct buffer *b, uint8_t n)
|
|
||||||
{
|
|
||||||
buffer_ensure(b, 1);
|
|
||||||
BUFFER_IN(b)[0] = n;
|
|
||||||
buffer_add(b, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
input_store16(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
input_extract8(struct buffer *b)
|
|
||||||
{
|
|
||||||
uint8_t n;
|
|
||||||
|
|
||||||
n = BUFFER_OUT(b)[0];
|
|
||||||
buffer_remove(b, 1);
|
|
||||||
return (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t
|
|
||||||
input_extract16(struct buffer *b)
|
|
||||||
{
|
|
||||||
uint16_t n;
|
|
||||||
|
|
||||||
n = BUFFER_OUT(b)[0] | (BUFFER_OUT(b)[1] << 8);
|
|
||||||
buffer_remove(b, 2);
|
|
||||||
return (n);
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: key-bindings.c,v 1.21 2007-11-23 17:52:54 nicm Exp $ */
|
/* $Id: key-bindings.c,v 1.22 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -204,5 +204,5 @@ key_bindings_dispatch(int key, struct client *c)
|
|||||||
cmd_exec(bd->cmd, &ctx);
|
cmd_exec(bd->cmd, &ctx);
|
||||||
|
|
||||||
if (c->session->curw->window->mode == &window_more_mode)
|
if (c->session->curw->window->mode == &window_more_mode)
|
||||||
server_redraw_window_all(c->session->curw->window);
|
server_redraw_window(c->session->curw->window);
|
||||||
}
|
}
|
||||||
|
793
local.c
793
local.c
@ -1,793 +0,0 @@
|
|||||||
/* $Id: local.c,v 1.23 2007-11-26 20:36:30 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <curses.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define TTYDEFCHARS
|
|
||||||
/* glibc requires unistd.h before termios.h for TTYDEFCHARS. */
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <term.h>
|
|
||||||
|
|
||||||
#include "tmux.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Functions to translate input and write output to the local client terminal.
|
|
||||||
* This file should probably be called tty or terminal.c.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int local_cmp(const void *, const void *);
|
|
||||||
int local_putc(int);
|
|
||||||
void local_putp(const char *);
|
|
||||||
void local_attributes(u_char, u_char);
|
|
||||||
u_char local_translate_acs(u_char);
|
|
||||||
|
|
||||||
/* Local key types and key codes. */
|
|
||||||
struct local_key {
|
|
||||||
const char *name;
|
|
||||||
char *string;
|
|
||||||
size_t size;
|
|
||||||
int code;
|
|
||||||
};
|
|
||||||
struct local_key local_keys[] = {
|
|
||||||
{ "ka1", NULL, 0, KEYC_A1 },
|
|
||||||
{ "ka3", NULL, 0, KEYC_A3 },
|
|
||||||
{ "kb2", NULL, 0, KEYC_B2 },
|
|
||||||
{ "kbeg", NULL, 0, KEYC_BEG },
|
|
||||||
{ "kcbt", NULL, 0, KEYC_BTAB },
|
|
||||||
{ "kc1", NULL, 0, KEYC_C1 },
|
|
||||||
{ "kc3", NULL, 0, KEYC_C3 },
|
|
||||||
{ "kcan", NULL, 0, KEYC_CANCEL },
|
|
||||||
{ "ktbc", NULL, 0, KEYC_CATAB },
|
|
||||||
{ "kclr", NULL, 0, KEYC_CLEAR },
|
|
||||||
{ "kclo", NULL, 0, KEYC_CLOSE },
|
|
||||||
{ "kcmd", NULL, 0, KEYC_COMMAND },
|
|
||||||
{ "kcpy", NULL, 0, KEYC_COPY },
|
|
||||||
{ "kcrt", NULL, 0, KEYC_CREATE },
|
|
||||||
{ "kctab", NULL, 0, KEYC_CTAB },
|
|
||||||
{ "kdch1", NULL, 0, KEYC_DC },
|
|
||||||
{ "kdl1", NULL, 0, KEYC_DL },
|
|
||||||
{ "kcud1", NULL, 0, KEYC_DOWN },
|
|
||||||
{ "krmir", NULL, 0, KEYC_EIC },
|
|
||||||
{ "kend", NULL, 0, KEYC_END },
|
|
||||||
{ "kent", NULL, 0, KEYC_ENTER },
|
|
||||||
{ "kel", NULL, 0, KEYC_EOL },
|
|
||||||
{ "ked", NULL, 0, KEYC_EOS },
|
|
||||||
{ "kext", NULL, 0, KEYC_EXIT },
|
|
||||||
{ "kf0", NULL, 0, KEYC_F0 },
|
|
||||||
{ "kf1", NULL, 0, KEYC_F1 },
|
|
||||||
{ "kf10", NULL, 0, KEYC_F10 },
|
|
||||||
{ "kf11", NULL, 0, KEYC_F11 },
|
|
||||||
{ "kf12", NULL, 0, KEYC_F12 },
|
|
||||||
{ "kf13", NULL, 0, KEYC_F13 },
|
|
||||||
{ "kf14", NULL, 0, KEYC_F14 },
|
|
||||||
{ "kf15", NULL, 0, KEYC_F15 },
|
|
||||||
{ "kf16", NULL, 0, KEYC_F16 },
|
|
||||||
{ "kf17", NULL, 0, KEYC_F17 },
|
|
||||||
{ "kf18", NULL, 0, KEYC_F18 },
|
|
||||||
{ "kf19", NULL, 0, KEYC_F19 },
|
|
||||||
{ "kf2", NULL, 0, KEYC_F2 },
|
|
||||||
{ "kf20", NULL, 0, KEYC_F20 },
|
|
||||||
{ "kf21", NULL, 0, KEYC_F21 },
|
|
||||||
{ "kf22", NULL, 0, KEYC_F22 },
|
|
||||||
{ "kf23", NULL, 0, KEYC_F23 },
|
|
||||||
{ "kf24", NULL, 0, KEYC_F24 },
|
|
||||||
{ "kf25", NULL, 0, KEYC_F25 },
|
|
||||||
{ "kf26", NULL, 0, KEYC_F26 },
|
|
||||||
{ "kf27", NULL, 0, KEYC_F27 },
|
|
||||||
{ "kf28", NULL, 0, KEYC_F28 },
|
|
||||||
{ "kf29", NULL, 0, KEYC_F29 },
|
|
||||||
{ "kf3", NULL, 0, KEYC_F3 },
|
|
||||||
{ "kf30", NULL, 0, KEYC_F30 },
|
|
||||||
{ "kf31", NULL, 0, KEYC_F31 },
|
|
||||||
{ "kf32", NULL, 0, KEYC_F32 },
|
|
||||||
{ "kf33", NULL, 0, KEYC_F33 },
|
|
||||||
{ "kf34", NULL, 0, KEYC_F34 },
|
|
||||||
{ "kf35", NULL, 0, KEYC_F35 },
|
|
||||||
{ "kf36", NULL, 0, KEYC_F36 },
|
|
||||||
{ "kf37", NULL, 0, KEYC_F37 },
|
|
||||||
{ "kf38", NULL, 0, KEYC_F38 },
|
|
||||||
{ "kf39", NULL, 0, KEYC_F39 },
|
|
||||||
{ "kf4", NULL, 0, KEYC_F4 },
|
|
||||||
{ "kf40", NULL, 0, KEYC_F40 },
|
|
||||||
{ "kf41", NULL, 0, KEYC_F41 },
|
|
||||||
{ "kf42", NULL, 0, KEYC_F42 },
|
|
||||||
{ "kf43", NULL, 0, KEYC_F43 },
|
|
||||||
{ "kf44", NULL, 0, KEYC_F44 },
|
|
||||||
{ "kf45", NULL, 0, KEYC_F45 },
|
|
||||||
{ "kf46", NULL, 0, KEYC_F46 },
|
|
||||||
{ "kf47", NULL, 0, KEYC_F47 },
|
|
||||||
{ "kf48", NULL, 0, KEYC_F48 },
|
|
||||||
{ "kf49", NULL, 0, KEYC_F49 },
|
|
||||||
{ "kf5", NULL, 0, KEYC_F5 },
|
|
||||||
{ "kf50", NULL, 0, KEYC_F50 },
|
|
||||||
{ "kf51", NULL, 0, KEYC_F51 },
|
|
||||||
{ "kf52", NULL, 0, KEYC_F52 },
|
|
||||||
{ "kf53", NULL, 0, KEYC_F53 },
|
|
||||||
{ "kf54", NULL, 0, KEYC_F54 },
|
|
||||||
{ "kf55", NULL, 0, KEYC_F55 },
|
|
||||||
{ "kf56", NULL, 0, KEYC_F56 },
|
|
||||||
{ "kf57", NULL, 0, KEYC_F57 },
|
|
||||||
{ "kf58", NULL, 0, KEYC_F58 },
|
|
||||||
{ "kf59", NULL, 0, KEYC_F59 },
|
|
||||||
{ "kf6", NULL, 0, KEYC_F6 },
|
|
||||||
{ "kf60", NULL, 0, KEYC_F60 },
|
|
||||||
{ "kf61", NULL, 0, KEYC_F61 },
|
|
||||||
{ "kf62", NULL, 0, KEYC_F62 },
|
|
||||||
{ "kf63", NULL, 0, KEYC_F63 },
|
|
||||||
{ "kf7", NULL, 0, KEYC_F7 },
|
|
||||||
{ "kf8", NULL, 0, KEYC_F8 },
|
|
||||||
{ "kf9", NULL, 0, KEYC_F9 },
|
|
||||||
{ "kfnd", NULL, 0, KEYC_FIND },
|
|
||||||
{ "khlp", NULL, 0, KEYC_HELP },
|
|
||||||
{ "khome", NULL, 0, KEYC_HOME },
|
|
||||||
{ "kich1", NULL, 0, KEYC_IC },
|
|
||||||
{ "kil1", NULL, 0, KEYC_IL },
|
|
||||||
{ "kcub1", NULL, 0, KEYC_LEFT },
|
|
||||||
{ "kll", NULL, 0, KEYC_LL },
|
|
||||||
{ "kmrk", NULL, 0, KEYC_MARK },
|
|
||||||
{ "kmsg", NULL, 0, KEYC_MESSAGE },
|
|
||||||
{ "kmov", NULL, 0, KEYC_MOVE },
|
|
||||||
{ "knxt", NULL, 0, KEYC_NEXT },
|
|
||||||
{ "knp", NULL, 0, KEYC_NPAGE },
|
|
||||||
{ "kopn", NULL, 0, KEYC_OPEN },
|
|
||||||
{ "kopt", NULL, 0, KEYC_OPTIONS },
|
|
||||||
{ "kpp", NULL, 0, KEYC_PPAGE },
|
|
||||||
{ "kprv", NULL, 0, KEYC_PREVIOUS },
|
|
||||||
{ "kprt", NULL, 0, KEYC_PRINT },
|
|
||||||
{ "krdo", NULL, 0, KEYC_REDO },
|
|
||||||
{ "kref", NULL, 0, KEYC_REFERENCE },
|
|
||||||
{ "krfr", NULL, 0, KEYC_REFRESH },
|
|
||||||
{ "krpl", NULL, 0, KEYC_REPLACE },
|
|
||||||
{ "krst", NULL, 0, KEYC_RESTART },
|
|
||||||
{ "kres", NULL, 0, KEYC_RESUME },
|
|
||||||
{ "kcuf1", NULL, 0, KEYC_RIGHT },
|
|
||||||
{ "ksav", NULL, 0, KEYC_SAVE },
|
|
||||||
{ "kBEG", NULL, 0, KEYC_SBEG },
|
|
||||||
{ "kCAN", NULL, 0, KEYC_SCANCEL },
|
|
||||||
{ "kCMD", NULL, 0, KEYC_SCOMMAND },
|
|
||||||
{ "kCPY", NULL, 0, KEYC_SCOPY },
|
|
||||||
{ "kCRT", NULL, 0, KEYC_SCREATE },
|
|
||||||
{ "kDC", NULL, 0, KEYC_SDC },
|
|
||||||
{ "kDL", NULL, 0, KEYC_SDL },
|
|
||||||
{ "kslt", NULL, 0, KEYC_SELECT },
|
|
||||||
{ "kEND", NULL, 0, KEYC_SEND },
|
|
||||||
{ "kEOL", NULL, 0, KEYC_SEOL },
|
|
||||||
{ "kEXT", NULL, 0, KEYC_SEXIT },
|
|
||||||
{ "kind", NULL, 0, KEYC_SF },
|
|
||||||
{ "kFND", NULL, 0, KEYC_SFIND },
|
|
||||||
{ "kHLP", NULL, 0, KEYC_SHELP },
|
|
||||||
{ "kHOM", NULL, 0, KEYC_SHOME },
|
|
||||||
{ "kIC", NULL, 0, KEYC_SIC },
|
|
||||||
{ "kLFT", NULL, 0, KEYC_SLEFT },
|
|
||||||
{ "kMSG", NULL, 0, KEYC_SMESSAGE },
|
|
||||||
{ "kMOV", NULL, 0, KEYC_SMOVE },
|
|
||||||
{ "kNXT", NULL, 0, KEYC_SNEXT },
|
|
||||||
{ "kOPT", NULL, 0, KEYC_SOPTIONS },
|
|
||||||
{ "kPRV", NULL, 0, KEYC_SPREVIOUS },
|
|
||||||
{ "kPRT", NULL, 0, KEYC_SPRINT },
|
|
||||||
{ "kri", NULL, 0, KEYC_SR },
|
|
||||||
{ "kRDO", NULL, 0, KEYC_SREDO },
|
|
||||||
{ "kRPL", NULL, 0, KEYC_SREPLACE },
|
|
||||||
{ "kRIT", NULL, 0, KEYC_SRIGHT },
|
|
||||||
{ "kRES", NULL, 0, KEYC_SRSUME },
|
|
||||||
{ "kSAV", NULL, 0, KEYC_SSAVE },
|
|
||||||
{ "kSPD", NULL, 0, KEYC_SSUSPEND },
|
|
||||||
{ "khts", NULL, 0, KEYC_STAB },
|
|
||||||
{ "kUND", NULL, 0, KEYC_SUNDO },
|
|
||||||
{ "kspd", NULL, 0, KEYC_SUSPEND },
|
|
||||||
{ "kund", NULL, 0, KEYC_UNDO },
|
|
||||||
{ "kcuu1", NULL, 0, KEYC_UP },
|
|
||||||
{ "pmous", NULL, 0, KEYC_MOUSE },
|
|
||||||
{ NULL, NULL, 0, KEYC_NONE }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tty file descriptor and local terminal buffers. */
|
|
||||||
int local_fd = -1;
|
|
||||||
int local_log = -1;
|
|
||||||
struct buffer *local_in;
|
|
||||||
struct buffer *local_out;
|
|
||||||
struct termios local_tio;
|
|
||||||
u_char local_attr;
|
|
||||||
u_char local_colr;
|
|
||||||
|
|
||||||
/* Initialise local terminal. */
|
|
||||||
int
|
|
||||||
local_init(struct buffer **in, struct buffer **out)
|
|
||||||
{
|
|
||||||
char *tty, *path;
|
|
||||||
const char *name;
|
|
||||||
int mode, error;
|
|
||||||
struct termios tio;
|
|
||||||
struct local_key *lk;
|
|
||||||
u_int i, j;
|
|
||||||
static const char *const reqd[] = {
|
|
||||||
"carriage_return",
|
|
||||||
"change_scroll_region",
|
|
||||||
"clear_screen",
|
|
||||||
"clr_bol",
|
|
||||||
"clr_eol",
|
|
||||||
"cursor_address",
|
|
||||||
"cursor_left",
|
|
||||||
"cursor_down",
|
|
||||||
"parm_dch",
|
|
||||||
"parm_delete_line",
|
|
||||||
"parm_down_cursor",
|
|
||||||
"parm_ich",
|
|
||||||
"parm_insert_line",
|
|
||||||
"parm_left_cursor",
|
|
||||||
"parm_right_cursor",
|
|
||||||
"parm_up_cursor",
|
|
||||||
"scroll_reverse",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
if ((tty = ttyname(STDIN_FILENO)) == NULL)
|
|
||||||
fatal("ttyname failed");
|
|
||||||
if ((local_fd = open(tty, O_RDWR)) == -1)
|
|
||||||
fatal("open failed");
|
|
||||||
if ((mode = fcntl(local_fd, F_GETFL)) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
if (fcntl(local_fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
|
||||||
fatal("fcntl failed");
|
|
||||||
|
|
||||||
if ((name = getenv("TERM")) == NULL || *name == '\0')
|
|
||||||
name = "unknown";
|
|
||||||
if (newterm(name, stdout, stdin) == NULL) {
|
|
||||||
log_warnx("error opening terminal: %s", name);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
for (i = 0; reqd[i] != NULL; i++) {
|
|
||||||
error = 0;
|
|
||||||
|
|
||||||
for (j = 0; strfnames[j] != NULL; j++) {
|
|
||||||
if (strcmp(strfnames[j], reqd[i]) == 0) {
|
|
||||||
if (strcodes[j] == NULL)
|
|
||||||
error = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (error != -1) {
|
|
||||||
for (j = 0; numfnames[j] != NULL; j++) {
|
|
||||||
if (strcmp(numfnames[j], reqd[i]) == 0) {
|
|
||||||
if (numcodes[j] == NULL)
|
|
||||||
error = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (error != -1) {
|
|
||||||
for (j = 0; boolfnames[j] != NULL; j++) {
|
|
||||||
if (strcmp(boolfnames[j], reqd[i]) == 0) {
|
|
||||||
if (boolcodes[j] == NULL)
|
|
||||||
error = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == -1) {
|
|
||||||
log_warnx("required capability missing: %s", reqd[i]);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*in = local_in = buffer_create(BUFSIZ);
|
|
||||||
*out = local_out = buffer_create(BUFSIZ);
|
|
||||||
|
|
||||||
if (tcgetattr(local_fd, &local_tio) != 0)
|
|
||||||
fatal("tcgetattr failed");
|
|
||||||
memset(&tio, 0, sizeof tio);
|
|
||||||
tio.c_iflag = TTYDEF_IFLAG & ~(IXON|IXOFF|ICRNL|INLCR);
|
|
||||||
tio.c_oflag = TTYDEF_OFLAG & ~(OPOST|ONLCR|OCRNL|ONLRET);
|
|
||||||
tio.c_lflag =
|
|
||||||
TTYDEF_LFLAG & ~(IEXTEN|ICANON|ECHO|ECHOE|ECHOKE|ECHOCTL|ISIG);
|
|
||||||
tio.c_cflag = TTYDEF_CFLAG;
|
|
||||||
memcpy(&tio.c_cc, ttydefchars, sizeof tio.c_cc);
|
|
||||||
cfsetspeed(&tio, TTYDEF_SPEED);
|
|
||||||
if (tcsetattr(local_fd, TCSANOW, &tio) != 0)
|
|
||||||
fatal("tcsetattr failed");
|
|
||||||
|
|
||||||
if (enter_ca_mode != NULL)
|
|
||||||
local_putp(enter_ca_mode);
|
|
||||||
if (keypad_xmit != NULL)
|
|
||||||
local_putp(keypad_xmit);
|
|
||||||
if (ena_acs != NULL)
|
|
||||||
local_putp(ena_acs);
|
|
||||||
local_putp(clear_screen);
|
|
||||||
|
|
||||||
for (lk = local_keys; lk->name != NULL; lk++) {
|
|
||||||
lk->string = tigetstr(lk->name);
|
|
||||||
if (lk->string == (char *) -1 || lk->string == (char *) 0)
|
|
||||||
lk->string = NULL;
|
|
||||||
else {
|
|
||||||
lk->size = strlen(lk->string);
|
|
||||||
log_debug("string for %s (%d): \"%s\", length %zu",
|
|
||||||
lk->name, lk->code, lk->string, lk->size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qsort(local_keys, sizeof local_keys /
|
|
||||||
sizeof local_keys[0], sizeof local_keys[0], local_cmp);
|
|
||||||
|
|
||||||
local_attr = 0;
|
|
||||||
local_colr = 0x88;
|
|
||||||
|
|
||||||
if (debug_level > 2) {
|
|
||||||
xasprintf(
|
|
||||||
&path, "%s-output-%ld.log", __progname,(long) getpid());
|
|
||||||
local_log = open(
|
|
||||||
path, O_RDWR|O_APPEND|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
|
|
||||||
xfree(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (local_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare keys. */
|
|
||||||
int
|
|
||||||
local_cmp(const void *ptr1, const void *ptr2)
|
|
||||||
{
|
|
||||||
const struct local_key *lk1 = ptr1, *lk2 = ptr2;
|
|
||||||
|
|
||||||
if (lk1->string == NULL && lk2->string == NULL)
|
|
||||||
return (0);
|
|
||||||
if (lk1->string == NULL)
|
|
||||||
return (1);
|
|
||||||
if (lk2->string == NULL)
|
|
||||||
return (-1);
|
|
||||||
return (lk2->size - lk1->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tidy up and reset local terminal. */
|
|
||||||
void
|
|
||||||
local_done(void)
|
|
||||||
{
|
|
||||||
struct winsize ws;
|
|
||||||
|
|
||||||
buffer_destroy(local_in);
|
|
||||||
buffer_destroy(local_out);
|
|
||||||
|
|
||||||
if (tcsetattr(local_fd, TCSANOW, &local_tio) != 0)
|
|
||||||
fatal("tcsetattr failed");
|
|
||||||
close(local_fd);
|
|
||||||
|
|
||||||
if (local_log != -1)
|
|
||||||
close(local_log);
|
|
||||||
|
|
||||||
if (change_scroll_region != NULL) {
|
|
||||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
|
|
||||||
fatal("ioctl(TIOCGWINSZ)");
|
|
||||||
putp(tparm(change_scroll_region, 0, ws.ws_row - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
endwin();
|
|
||||||
if (keypad_local != NULL)
|
|
||||||
putp(keypad_local); /* not local_putp */
|
|
||||||
if (exit_ca_mode != NULL)
|
|
||||||
putp(exit_ca_mode);
|
|
||||||
putp(clear_screen);
|
|
||||||
if (cursor_normal != NULL)
|
|
||||||
putp(cursor_normal);
|
|
||||||
if (exit_attribute_mode != NULL)
|
|
||||||
putp(exit_attribute_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put a character. Used as parameter to tputs. */
|
|
||||||
int
|
|
||||||
local_putc(int c)
|
|
||||||
{
|
|
||||||
u_char ch = c;
|
|
||||||
|
|
||||||
if (c < 0 || c > (int) UCHAR_MAX)
|
|
||||||
fatalx("invalid character");
|
|
||||||
|
|
||||||
if (local_log != -1)
|
|
||||||
write(local_log, &ch, 1);
|
|
||||||
if (acs_chars != NULL && local_attr & ATTR_DRAWING) {
|
|
||||||
ch = local_translate_acs(ch);
|
|
||||||
if (ch == '\0')
|
|
||||||
ch = '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer_write(local_out, &ch, 1);
|
|
||||||
return (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put terminfo string. */
|
|
||||||
void
|
|
||||||
local_putp(const char *s)
|
|
||||||
{
|
|
||||||
if (s == NULL)
|
|
||||||
fatalx("null pointer");
|
|
||||||
|
|
||||||
tputs(s, 1, local_putc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return waiting keys if any. */
|
|
||||||
int
|
|
||||||
local_key(void)
|
|
||||||
{
|
|
||||||
struct local_key *lk;
|
|
||||||
u_int i;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
size = BUFFER_USED(local_in);
|
|
||||||
if (size == 0)
|
|
||||||
return (KEYC_NONE);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
lk = local_keys;
|
|
||||||
while (lk->string != NULL) {
|
|
||||||
if (strncmp(BUFFER_OUT(local_in), lk->string, size) == 0) {
|
|
||||||
if (size < lk->size)
|
|
||||||
return (KEYC_NONE);
|
|
||||||
log_debug("got key: "
|
|
||||||
"%s %d \"%s\"", lk->name, lk->code, lk->string);
|
|
||||||
buffer_remove(local_in, lk->size);
|
|
||||||
return (lk->code);
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
lk = local_keys + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (input_extract8(local_in));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display output data. */
|
|
||||||
void
|
|
||||||
local_output(struct buffer *b, size_t size)
|
|
||||||
{
|
|
||||||
u_char ch;
|
|
||||||
uint16_t ua, ub;
|
|
||||||
|
|
||||||
while (size != 0) {
|
|
||||||
if (size < 1)
|
|
||||||
break;
|
|
||||||
size--;
|
|
||||||
ch = input_extract8(b);
|
|
||||||
if (ch != '\e') {
|
|
||||||
switch (ch) {
|
|
||||||
case '\n': /* LF */
|
|
||||||
local_putp(cursor_down);
|
|
||||||
break;
|
|
||||||
case '\r': /* CR */
|
|
||||||
local_putp(carriage_return);
|
|
||||||
break;
|
|
||||||
case '\007': /* BEL */
|
|
||||||
if (bell != NULL)
|
|
||||||
local_putp(bell);
|
|
||||||
break;
|
|
||||||
case '\010': /* BS */
|
|
||||||
local_putp(cursor_left);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
local_putc(ch);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size < 1)
|
|
||||||
fatalx("underflow");
|
|
||||||
size--;
|
|
||||||
ch = input_extract8(b);
|
|
||||||
|
|
||||||
log_debug("received code %hhu", ch);
|
|
||||||
switch (ch) {
|
|
||||||
case CODE_CURSORUP:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_CURSORUP underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
local_putp(tparm(parm_up_cursor, ua));
|
|
||||||
break;
|
|
||||||
case CODE_CURSORDOWN:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_CURSORDOWN underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
local_putp(tparm(parm_down_cursor, ua));
|
|
||||||
break;
|
|
||||||
case CODE_CURSORRIGHT:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_CURSORRIGHT underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
local_putp(tparm(parm_right_cursor, ua));
|
|
||||||
break;
|
|
||||||
case CODE_CURSORLEFT:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_CURSORLEFT underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
local_putp(tparm(parm_left_cursor, ua));
|
|
||||||
break;
|
|
||||||
case CODE_CURSORMOVE:
|
|
||||||
if (size < 4)
|
|
||||||
fatalx("CODE_CURSORMOVE underflow");
|
|
||||||
size -= 4;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
ub = input_extract16(b);
|
|
||||||
local_putp(tparm(cursor_address, ua - 1, ub - 1));
|
|
||||||
break;
|
|
||||||
case CODE_CLEARENDOFLINE:
|
|
||||||
local_putp(clr_eol);
|
|
||||||
break;
|
|
||||||
case CODE_CLEARSTARTOFLINE:
|
|
||||||
local_putp(clr_bol);
|
|
||||||
break;
|
|
||||||
case CODE_CLEARLINE:
|
|
||||||
local_putp(clr_eol); /* XXX */
|
|
||||||
break;
|
|
||||||
case CODE_INSERTLINE:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_INSERTLINE underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
local_putp(tparm(parm_insert_line, ua));
|
|
||||||
break;
|
|
||||||
case CODE_DELETELINE:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_DELETELINE underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
local_putp(tparm(parm_delete_line, ua));
|
|
||||||
break;
|
|
||||||
case CODE_INSERTCHARACTER:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_INSERTCHARACTER underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
local_putp(tparm(parm_ich, ua));
|
|
||||||
break;
|
|
||||||
case CODE_DELETECHARACTER:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_DELETECHARACTER underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
local_putp(tparm(parm_dch, ua));
|
|
||||||
break;
|
|
||||||
case CODE_CURSORON:
|
|
||||||
if (cursor_normal != NULL)
|
|
||||||
local_putp(cursor_normal);
|
|
||||||
break;
|
|
||||||
case CODE_CURSOROFF:
|
|
||||||
if (cursor_invisible != NULL)
|
|
||||||
local_putp(cursor_invisible);
|
|
||||||
break;
|
|
||||||
case CODE_REVERSEINDEX:
|
|
||||||
local_putp(scroll_reverse);
|
|
||||||
break;
|
|
||||||
case CODE_SCROLLREGION:
|
|
||||||
if (size < 4)
|
|
||||||
fatalx("CODE_SCROLLREGION underflow");
|
|
||||||
size -= 4;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
ub = input_extract16(b);
|
|
||||||
local_putp(tparm(change_scroll_region, ua - 1, ub - 1));
|
|
||||||
break;
|
|
||||||
case CODE_INSERTON:
|
|
||||||
if (enter_insert_mode != NULL)
|
|
||||||
local_putp(enter_insert_mode);
|
|
||||||
break;
|
|
||||||
case CODE_INSERTOFF:
|
|
||||||
if (exit_insert_mode != NULL)
|
|
||||||
local_putp(exit_insert_mode);
|
|
||||||
break;
|
|
||||||
case CODE_KCURSOROFF:
|
|
||||||
/*
|
|
||||||
t = tigetstr("CE");
|
|
||||||
if (t != (char *) 0 && t != (char *) -1)
|
|
||||||
local_putp(t);
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case CODE_KCURSORON:
|
|
||||||
/*
|
|
||||||
t = tigetstr("CS");
|
|
||||||
if (t != (char *) 0 && t != (char *) -1)
|
|
||||||
local_putp(t);
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case CODE_KKEYPADOFF:
|
|
||||||
/*
|
|
||||||
if (keypad_local != NULL)
|
|
||||||
local_putp(keypad_local);
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case CODE_KKEYPADON:
|
|
||||||
/*
|
|
||||||
if (keypad_xmit != NULL)
|
|
||||||
local_putp(keypad_xmit);
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case CODE_TITLE:
|
|
||||||
if (size < 2)
|
|
||||||
fatalx("CODE_TITLE underflow");
|
|
||||||
size -= 2;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
|
|
||||||
if (size < ua)
|
|
||||||
fatalx("CODE_TITLE underflow");
|
|
||||||
size -= ua;
|
|
||||||
buffer_remove(b, ua);
|
|
||||||
break;
|
|
||||||
case CODE_ATTRIBUTES:
|
|
||||||
if (size < 4)
|
|
||||||
fatalx("CODE_ATTRIBUTES underflow");
|
|
||||||
size -= 4;
|
|
||||||
ua = input_extract16(b);
|
|
||||||
ub = input_extract16(b);
|
|
||||||
|
|
||||||
local_attributes(ua, ub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
local_attributes(u_char attr, u_char colr)
|
|
||||||
{
|
|
||||||
u_char fg, bg;
|
|
||||||
|
|
||||||
if (attr == local_attr && colr == local_colr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* If any bits are being cleared, reset everything. */
|
|
||||||
if (local_attr & ~attr) {
|
|
||||||
if ((local_attr & ATTR_DRAWING) &&
|
|
||||||
exit_alt_charset_mode != NULL)
|
|
||||||
local_putp(exit_alt_charset_mode);
|
|
||||||
local_putp(exit_attribute_mode);
|
|
||||||
local_colr = 0x88;
|
|
||||||
local_attr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Filter out bits already set. */
|
|
||||||
attr &= ~local_attr;
|
|
||||||
local_attr |= attr;
|
|
||||||
|
|
||||||
if ((attr & ATTR_BRIGHT) && enter_bold_mode != NULL)
|
|
||||||
local_putp(enter_bold_mode);
|
|
||||||
if ((attr & ATTR_DIM) && enter_dim_mode != NULL)
|
|
||||||
local_putp(enter_dim_mode);
|
|
||||||
if ((attr & ATTR_ITALICS) && enter_standout_mode != NULL)
|
|
||||||
local_putp(enter_standout_mode);
|
|
||||||
if ((attr & ATTR_UNDERSCORE) && enter_underline_mode != NULL)
|
|
||||||
local_putp(enter_underline_mode);
|
|
||||||
if ((attr & ATTR_BLINK) && enter_blink_mode != NULL)
|
|
||||||
local_putp(enter_blink_mode);
|
|
||||||
if ((attr & ATTR_REVERSE) && enter_reverse_mode != NULL)
|
|
||||||
local_putp(enter_reverse_mode);
|
|
||||||
if ((attr & ATTR_HIDDEN) && enter_secure_mode != NULL)
|
|
||||||
local_putp(enter_secure_mode);
|
|
||||||
if ((attr & ATTR_DRAWING) && enter_alt_charset_mode != NULL)
|
|
||||||
local_putp(enter_alt_charset_mode);
|
|
||||||
|
|
||||||
fg = (colr >> 4) & 0xf;
|
|
||||||
if (fg != ((local_colr >> 4) & 0xf)) {
|
|
||||||
if (tigetflag("AX") == TRUE) {
|
|
||||||
if (fg == 7)
|
|
||||||
fg = 8;
|
|
||||||
} else {
|
|
||||||
if (fg == 8)
|
|
||||||
fg = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fg == 8)
|
|
||||||
local_putp("\e[39m");
|
|
||||||
else if (set_a_foreground != NULL)
|
|
||||||
local_putp(tparm(set_a_foreground, fg));
|
|
||||||
}
|
|
||||||
|
|
||||||
bg = colr & 0xf;
|
|
||||||
if (bg != (local_colr & 0xf)) {
|
|
||||||
if (tigetflag("AX") == TRUE) {
|
|
||||||
if (bg == 0)
|
|
||||||
bg = 8;
|
|
||||||
} else {
|
|
||||||
if (bg == 8)
|
|
||||||
bg = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bg == 8)
|
|
||||||
local_putp("\e[49m");
|
|
||||||
else if (set_a_background != NULL)
|
|
||||||
local_putp(tparm(set_a_background, bg));
|
|
||||||
}
|
|
||||||
|
|
||||||
local_colr = colr;
|
|
||||||
}
|
|
||||||
|
|
||||||
u_char
|
|
||||||
local_translate_acs(u_char ch)
|
|
||||||
{
|
|
||||||
switch (ch) {
|
|
||||||
case '~':
|
|
||||||
return (ACS_BULLET);
|
|
||||||
case '}':
|
|
||||||
return (ACS_STERLING);
|
|
||||||
case '|':
|
|
||||||
return (ACS_NEQUAL);
|
|
||||||
case '{':
|
|
||||||
return (ACS_PI);
|
|
||||||
case 'z':
|
|
||||||
return (ACS_GEQUAL);
|
|
||||||
case 'y':
|
|
||||||
return (ACS_LEQUAL);
|
|
||||||
case 'x':
|
|
||||||
return (ACS_VLINE);
|
|
||||||
case 'w':
|
|
||||||
return (ACS_TTEE);
|
|
||||||
case 'v':
|
|
||||||
return (ACS_BTEE);
|
|
||||||
case 'u':
|
|
||||||
return (ACS_RTEE);
|
|
||||||
case 't':
|
|
||||||
return (ACS_LTEE);
|
|
||||||
case 's':
|
|
||||||
return (ACS_S9);
|
|
||||||
case 'r':
|
|
||||||
return (ACS_S7);
|
|
||||||
case 'q':
|
|
||||||
return (ACS_HLINE);
|
|
||||||
case 'p':
|
|
||||||
return (ACS_S3);
|
|
||||||
case 'o':
|
|
||||||
return (ACS_S1);
|
|
||||||
case 'n':
|
|
||||||
return (ACS_PLUS);
|
|
||||||
case 'm':
|
|
||||||
return (ACS_LLCORNER);
|
|
||||||
case 'l':
|
|
||||||
return (ACS_ULCORNER);
|
|
||||||
case 'k':
|
|
||||||
return (ACS_URCORNER);
|
|
||||||
case 'j':
|
|
||||||
return (ACS_LRCORNER);
|
|
||||||
case 'i':
|
|
||||||
return (ACS_LANTERN);
|
|
||||||
case 'h':
|
|
||||||
return (ACS_BOARD);
|
|
||||||
case 'g':
|
|
||||||
return (ACS_PLMINUS);
|
|
||||||
case 'f':
|
|
||||||
return (ACS_DEGREE);
|
|
||||||
case 'a':
|
|
||||||
return (ACS_CKBOARD);
|
|
||||||
case '`':
|
|
||||||
return (ACS_DIAMOND);
|
|
||||||
case '0':
|
|
||||||
return (ACS_BLOCK);
|
|
||||||
case '.':
|
|
||||||
return (ACS_DARROW);
|
|
||||||
case '-':
|
|
||||||
return (ACS_UARROW);
|
|
||||||
case ',':
|
|
||||||
return (ACS_LARROW);
|
|
||||||
case '+':
|
|
||||||
return (ACS_RARROW);
|
|
||||||
}
|
|
||||||
return (ch);
|
|
||||||
}
|
|
6
resize.c
6
resize.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: resize.c,v 1.6 2007-11-21 13:11:41 nicm Exp $ */
|
/* $Id: resize.c,v 1.7 2007-11-27 19:23:33 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -117,8 +117,8 @@ recalculate_sizes(void)
|
|||||||
log_debug("window size %u,%u (was %u,%u)", ssx, ssy,
|
log_debug("window size %u,%u (was %u,%u)", ssx, ssy,
|
||||||
screen_size_x(&w->screen), screen_size_y(&w->screen));
|
screen_size_x(&w->screen), screen_size_y(&w->screen));
|
||||||
|
|
||||||
server_clear_window_cur(w);
|
|
||||||
window_resize(w, ssx, ssy);
|
window_resize(w, ssx, ssy);
|
||||||
server_redraw_window_cur(w);
|
server_clear_window(w);
|
||||||
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
153
screen.c
153
screen.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: screen.c,v 1.49 2007-11-26 22:06:11 nicm Exp $ */
|
/* $Id: screen.c,v 1.50 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -267,13 +267,45 @@ screen_destroy(struct screen *s)
|
|||||||
xfree(s->grid_size);
|
xfree(s->grid_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialise redrawing a window. */
|
||||||
|
void
|
||||||
|
screen_draw_start_window(
|
||||||
|
struct screen_draw_ctx *ctx, struct window *w, u_int ox, u_int oy)
|
||||||
|
{
|
||||||
|
struct screen *t = &w->screen;
|
||||||
|
|
||||||
|
screen_draw_start(ctx, t, tty_write_window, w, ox, oy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialise redrawing a client. */
|
||||||
|
void
|
||||||
|
screen_draw_start_client(
|
||||||
|
struct screen_draw_ctx *ctx, struct client *c, u_int ox, u_int oy)
|
||||||
|
{
|
||||||
|
struct screen *t = &c->session->curw->window->screen;
|
||||||
|
|
||||||
|
screen_draw_start(ctx, t, tty_write_client, c, ox, oy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialise redrawing a session. */
|
||||||
|
void
|
||||||
|
screen_draw_start_session(
|
||||||
|
struct screen_draw_ctx *ctx, struct session *s, u_int ox, u_int oy)
|
||||||
|
{
|
||||||
|
struct screen *t = &s->curw->window->screen;
|
||||||
|
|
||||||
|
screen_draw_start(ctx, t, tty_write_session, s, ox, oy);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialise drawing. */
|
/* Initialise drawing. */
|
||||||
void
|
void
|
||||||
screen_draw_start(struct screen_draw_ctx *ctx,
|
screen_draw_start(struct screen_draw_ctx *ctx, struct screen *s,
|
||||||
struct screen *s, struct buffer *b, u_int ox, u_int oy)
|
void (*write)(void *, int, ...), void *data, u_int ox, u_int oy)
|
||||||
{
|
{
|
||||||
|
ctx->write = write;
|
||||||
|
ctx->data = data;
|
||||||
|
|
||||||
ctx->s = s;
|
ctx->s = s;
|
||||||
ctx->b = b;
|
|
||||||
|
|
||||||
ctx->ox = ox;
|
ctx->ox = ox;
|
||||||
ctx->oy = oy;
|
ctx->oy = oy;
|
||||||
@ -287,8 +319,8 @@ screen_draw_start(struct screen_draw_ctx *ctx,
|
|||||||
ctx->attr = s->attr;
|
ctx->attr = s->attr;
|
||||||
ctx->colr = s->colr;
|
ctx->colr = s->colr;
|
||||||
|
|
||||||
input_store_two(b, CODE_SCROLLREGION, 1, screen_size_y(s));
|
ctx->write(ctx->data, TTY_SCROLLREGION, 0, screen_last_y(s));
|
||||||
input_store_zero(b, CODE_CURSOROFF);
|
ctx->write(ctx->data, TTY_CURSOROFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set selection. */
|
/* Set selection. */
|
||||||
@ -356,44 +388,112 @@ void
|
|||||||
screen_draw_stop(struct screen_draw_ctx *ctx)
|
screen_draw_stop(struct screen_draw_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct buffer *b = ctx->b;
|
|
||||||
|
|
||||||
input_store_two(b, CODE_SCROLLREGION, s->rupper + 1, s->rlower + 1);
|
ctx->write(ctx->data, TTY_SCROLLREGION, s->rupper, s->rlower);
|
||||||
|
|
||||||
if (ctx->cx != s->cx || ctx->cy != s->cy)
|
if (ctx->cx != s->cx || ctx->cy != s->cy)
|
||||||
input_store_two(b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
|
ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
|
||||||
|
|
||||||
if (ctx->attr != s->attr || ctx->colr != s->colr)
|
if (ctx->attr != s->attr || ctx->colr != s->colr)
|
||||||
input_store_two(b, CODE_ATTRIBUTES, s->attr, s->colr);
|
ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->colr);
|
||||||
|
|
||||||
if (s->mode & MODE_BACKGROUND) {
|
if (s->mode & MODE_BACKGROUND) {
|
||||||
if (s->mode & MODE_BGCURSOR)
|
if (s->mode & MODE_BGCURSOR)
|
||||||
input_store_zero(b, CODE_CURSORON);
|
ctx->write(ctx->data, TTY_CURSORON);
|
||||||
} else {
|
} else {
|
||||||
if (s->mode & MODE_CURSOR)
|
if (s->mode & MODE_CURSOR)
|
||||||
input_store_zero(b, CODE_CURSORON);
|
ctx->write(ctx->data, TTY_CURSORON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Insert lines. */
|
||||||
|
void
|
||||||
|
screen_draw_insert_lines(struct screen_draw_ctx *ctx, u_int ny)
|
||||||
|
{
|
||||||
|
ctx->write(ctx->data, TTY_INSERTLINE, ny);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete lines. */
|
||||||
|
void
|
||||||
|
screen_draw_delete_lines(struct screen_draw_ctx *ctx, u_int ny)
|
||||||
|
{
|
||||||
|
ctx->write(ctx->data, TTY_DELETELINE, ny);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert characters. */
|
||||||
|
void
|
||||||
|
screen_draw_insert_characters(struct screen_draw_ctx *ctx, u_int nx)
|
||||||
|
{
|
||||||
|
ctx->write(ctx->data, TTY_INSERTCHARACTER, nx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete characters. */
|
||||||
|
void
|
||||||
|
screen_draw_delete_characters(struct screen_draw_ctx *ctx, u_int nx)
|
||||||
|
{
|
||||||
|
ctx->write(ctx->data, TTY_DELETECHARACTER, nx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear end of line. */
|
||||||
|
void
|
||||||
|
screen_draw_clear_line_to(struct screen_draw_ctx *ctx, u_int px)
|
||||||
|
{
|
||||||
|
while (ctx->cx <= px) {
|
||||||
|
ctx->write(ctx->data, TTY_CHARACTER, SCREEN_DEFDATA);
|
||||||
|
ctx->cx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear screen. */
|
||||||
|
void
|
||||||
|
screen_draw_clear_screen(struct screen_draw_ctx *ctx)
|
||||||
|
{
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
for (i = 0; i < screen_size_y(ctx->s); i++) {
|
||||||
|
screen_draw_move_cursor(ctx, 0, i);
|
||||||
|
screen_draw_clear_line_to(ctx, screen_size_x(ctx->s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write string. */
|
||||||
|
void printflike2
|
||||||
|
screen_draw_write_string(struct screen_draw_ctx *ctx, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
struct screen *s = ctx->s;
|
||||||
|
va_list ap;
|
||||||
|
char *msg, *ptr;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
xvasprintf(&msg, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
for (ptr = msg; *ptr != '\0'; ptr++) {
|
||||||
|
if (ctx->cx > screen_last_x(s))
|
||||||
|
break;
|
||||||
|
ctx->write(ctx->data, TTY_CHARACTER, *ptr);
|
||||||
|
ctx->cx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree(msg);
|
||||||
|
}
|
||||||
|
|
||||||
/* Move cursor. */
|
/* Move cursor. */
|
||||||
void
|
void
|
||||||
screen_draw_move(struct screen_draw_ctx *ctx, u_int px, u_int py)
|
screen_draw_move_cursor(struct screen_draw_ctx *ctx, u_int px, u_int py)
|
||||||
{
|
{
|
||||||
if (px == ctx->cx && py == ctx->cy)
|
if (px == ctx->cx && py == ctx->cy)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* XXX disabled while things outside can move the cursor (eg
|
|
||||||
window-more.c writes characters)
|
|
||||||
if (px == 0 && py == ctx->cy)
|
if (px == 0 && py == ctx->cy)
|
||||||
input_store8(ctx->b, '\r');
|
ctx->write(ctx->data, TTY_CHARACTER, '\r');
|
||||||
else if (px == ctx->cx && py == ctx->cy + 1)
|
else if (px == ctx->cx && py == ctx->cy + 1)
|
||||||
input_store8(ctx->b, '\n');
|
ctx->write(ctx->data, TTY_CHARACTER, '\n');
|
||||||
else if (px == 0 && py == ctx->cy + 1) {
|
else if (px == 0 && py == ctx->cy + 1) {
|
||||||
input_store8(ctx->b, '\r');
|
ctx->write(ctx->data, TTY_CHARACTER, '\r');
|
||||||
input_store8(ctx->b, '\n');
|
ctx->write(ctx->data, TTY_CHARACTER, '\n');
|
||||||
} else
|
} else
|
||||||
*/
|
ctx->write(ctx->data, TTY_CURSORMOVE, py, px);
|
||||||
input_store_two(ctx->b, CODE_CURSORMOVE, py + 1, px + 1);
|
|
||||||
|
|
||||||
ctx->cx = px;
|
ctx->cx = px;
|
||||||
ctx->cy = py;
|
ctx->cy = py;
|
||||||
@ -405,7 +505,7 @@ screen_draw_set_attributes(
|
|||||||
struct screen_draw_ctx *ctx, u_char attr, u_char colr)
|
struct screen_draw_ctx *ctx, u_char attr, u_char colr)
|
||||||
{
|
{
|
||||||
if (attr != ctx->attr || colr != ctx->colr) {
|
if (attr != ctx->attr || colr != ctx->colr) {
|
||||||
input_store_two(ctx->b, CODE_ATTRIBUTES, attr, colr);
|
ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr);
|
||||||
ctx->attr = attr;
|
ctx->attr = attr;
|
||||||
ctx->colr = colr;
|
ctx->colr = colr;
|
||||||
}
|
}
|
||||||
@ -415,14 +515,13 @@ screen_draw_set_attributes(
|
|||||||
void
|
void
|
||||||
screen_draw_cell(struct screen_draw_ctx *ctx, u_int px, u_int py)
|
screen_draw_cell(struct screen_draw_ctx *ctx, u_int px, u_int py)
|
||||||
{
|
{
|
||||||
struct buffer *b = ctx->b;
|
|
||||||
u_char data, attr, colr;
|
u_char data, attr, colr;
|
||||||
|
|
||||||
screen_draw_move(ctx, px, py);
|
screen_draw_move_cursor(ctx, px, py);
|
||||||
|
|
||||||
screen_draw_get_cell(ctx, px, py, &data, &attr, &colr);
|
screen_draw_get_cell(ctx, px, py, &data, &attr, &colr);
|
||||||
screen_draw_set_attributes(ctx, attr, colr);
|
screen_draw_set_attributes(ctx, attr, colr);
|
||||||
input_store8(b, data);
|
ctx->write(ctx->data, TTY_CHARACTER, data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't try to wrap as it will cause problems when screen is smaller
|
* Don't try to wrap as it will cause problems when screen is smaller
|
||||||
@ -465,8 +564,8 @@ screen_draw_line(struct screen_draw_ctx *ctx, u_int py)
|
|||||||
screen_draw_cells(ctx, 0, py, screen_size_x(ctx->s));
|
screen_draw_cells(ctx, 0, py, screen_size_x(ctx->s));
|
||||||
else {
|
else {
|
||||||
screen_draw_cells(ctx, 0, py, cx);
|
screen_draw_cells(ctx, 0, py, cx);
|
||||||
screen_draw_move(ctx, cx, py);
|
screen_draw_move_cursor(ctx, cx, py);
|
||||||
input_store_zero(ctx->b, CODE_CLEARENDOFLINE);
|
ctx->write(ctx->data, TTY_CLEARENDOFLINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
276
server-fn.c
276
server-fn.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: server-fn.c,v 1.34 2007-11-24 18:32:52 nicm Exp $ */
|
/* $Id: server-fn.c,v 1.35 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -105,7 +105,7 @@ server_write_session(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_write_window_cur(
|
server_write_window(
|
||||||
struct window *w, enum hdrtype type, const void *buf, size_t len)
|
struct window *w, enum hdrtype type, const void *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct client *c;
|
||||||
@ -120,262 +120,144 @@ server_write_window_cur(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
server_write_window_all(
|
|
||||||
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 (session_has(c->session, w))
|
|
||||||
server_write_client(c, type, buf, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
server_status_client(struct client *c)
|
|
||||||
{
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (status_lines == 0 || c->sy <= status_lines)
|
|
||||||
return;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
status_write(c);
|
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
server_clear_client(struct client *c)
|
server_clear_client(struct client *c)
|
||||||
{
|
{
|
||||||
struct screen *s = &c->session->curw->window->screen;
|
struct screen_draw_ctx ctx;
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
u_int i;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
screen_draw_start_client(&ctx, c, 0, 0);
|
||||||
buffer_add(c->out, sizeof hdr);
|
screen_draw_clear_screen(&ctx);
|
||||||
size = BUFFER_USED(c->out);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
input_store_zero(c->out, CODE_CURSOROFF);
|
status_write_client(c);
|
||||||
for (i = 0; i < screen_size_y(s); i++) {
|
|
||||||
input_store_two(c->out, CODE_CURSORMOVE, i + 1, 1);
|
|
||||||
input_store_zero(c->out, CODE_CLEARLINE);
|
|
||||||
}
|
|
||||||
input_store_two(c->out, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
|
|
||||||
if (s->mode & MODE_BACKGROUND) {
|
|
||||||
if (s->mode & MODE_BGCURSOR)
|
|
||||||
input_store_zero(c->out, CODE_CURSORON);
|
|
||||||
} else {
|
|
||||||
if (s->mode & MODE_CURSOR)
|
|
||||||
input_store_zero(c->out, CODE_CURSORON);
|
|
||||||
}
|
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_redraw_client(struct client *c)
|
server_redraw_client(struct client *c)
|
||||||
{
|
{
|
||||||
|
struct screen_draw_ctx ctx;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = c->session->curw->window;
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
screen_draw_start_client(&ctx, c, 0, 0);
|
||||||
buffer_add(c->out, sizeof hdr);
|
window_draw(w, &ctx, 0, screen_size_y(&w->screen));
|
||||||
size = BUFFER_USED(c->out);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
window_draw(w, c->out, 0, screen_size_y(&w->screen));
|
status_write_client(c);
|
||||||
|
}
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
void
|
||||||
log_debug("redrawing window, %zu bytes", size);
|
server_status_client(struct client *c)
|
||||||
if (size != 0) {
|
{
|
||||||
hdr.type = MSG_DATA;
|
status_write_client(c);
|
||||||
hdr.size = size;
|
}
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
} else
|
|
||||||
buffer_reverse_add(c->out, sizeof hdr);
|
|
||||||
|
|
||||||
server_status_client(c);
|
void
|
||||||
|
server_clear_session(struct session *s)
|
||||||
|
{
|
||||||
|
struct screen_draw_ctx ctx;
|
||||||
|
|
||||||
|
screen_draw_start_session(&ctx, s, 0, 0);
|
||||||
|
screen_draw_clear_screen(&ctx);
|
||||||
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
|
status_write_session(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_redraw_session(struct session *s)
|
server_redraw_session(struct session *s)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct screen_draw_ctx ctx;
|
||||||
u_int i;
|
struct window *w = s->curw->window;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_session(&ctx, s, 0, 0);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
window_draw(w, &ctx, 0, screen_size_y(&w->screen));
|
||||||
if (c != NULL && c->session == s)
|
screen_draw_stop(&ctx);
|
||||||
server_redraw_client(c);
|
|
||||||
}
|
status_write_session(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_status_session(struct session *s)
|
server_status_session(struct session *s)
|
||||||
{
|
{
|
||||||
struct client *c;
|
status_write_session(s);
|
||||||
u_int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
|
||||||
c = ARRAY_ITEM(&clients, i);
|
|
||||||
if (c != NULL && c->session == s)
|
|
||||||
server_status_client(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_clear_window_cur(struct window *w)
|
server_clear_window(struct window *w)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct screen_draw_ctx ctx;
|
||||||
u_int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, 0, 0);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
screen_draw_clear_screen(&ctx);
|
||||||
if (c != NULL &&
|
screen_draw_stop(&ctx);
|
||||||
c->session != NULL && c->session->curw->window == w)
|
|
||||||
server_clear_client(c);
|
status_write_window(w);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_clear_window_all(struct window *w)
|
server_redraw_window(struct window *w)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct screen_draw_ctx ctx;
|
||||||
u_int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, 0, 0);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
window_draw(w, &ctx, 0, screen_size_y(&w->screen));
|
||||||
if (c == NULL || c->session == NULL)
|
screen_draw_stop(&ctx);
|
||||||
continue;
|
|
||||||
if (session_has(c->session, w))
|
status_write_window(w);
|
||||||
server_redraw_client(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_redraw_window_cur(struct window *w)
|
server_status_window(struct window *w)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct session *s;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
/*
|
||||||
c = ARRAY_ITEM(&clients, i);
|
* This is slightly different. We want to redraw the status line of any
|
||||||
if (c != NULL &&
|
* clients containing this window rather than any where it is the
|
||||||
c->session != NULL && c->session->curw->window == w)
|
* current window.
|
||||||
server_redraw_client(c);
|
*/
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
|
||||||
server_redraw_window_all(struct window *w)
|
s = ARRAY_ITEM(&sessions, i);
|
||||||
{
|
if (s != NULL && session_has(s, w))
|
||||||
struct client *c;
|
server_status_session(s);
|
||||||
u_int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
|
||||||
c = ARRAY_ITEM(&clients, i);
|
|
||||||
if (c == NULL || c->session == NULL)
|
|
||||||
continue;
|
|
||||||
if (session_has(c->session, w))
|
|
||||||
server_redraw_client(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
server_status_window_cur(struct window *w)
|
|
||||||
{
|
|
||||||
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 && c->session->curw->window == w)
|
|
||||||
server_status_client(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
server_status_window_all(struct window *w)
|
|
||||||
{
|
|
||||||
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 (session_has(c->session, w))
|
|
||||||
server_status_client(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printflike2
|
void printflike2
|
||||||
server_write_message(struct client *c, const char *fmt, ...)
|
server_write_message(struct client *c, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
struct window *w = c->session->curw->window;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct hdr hdr;
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
char *msg;
|
char *msg;
|
||||||
size_t size;
|
size_t size;
|
||||||
u_int i;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
screen_draw_start_client(&ctx, c, 0, 0);
|
||||||
buffer_add(c->out, sizeof hdr);
|
screen_draw_move_cursor(&ctx, 0, c->sy - 1);
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, &w->screen, c->out, 0, 0);
|
|
||||||
screen_draw_move(&ctx, 0, c->sy - 1);
|
|
||||||
screen_draw_set_attributes(&ctx, ATTR_REVERSE, 0x88);
|
screen_draw_set_attributes(&ctx, ATTR_REVERSE, 0x88);
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
xvasprintf(&msg, fmt, ap);
|
xvasprintf(&msg, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (strlen(msg) > c->sx - 1)
|
|
||||||
|
size = strlen(msg);
|
||||||
|
if (size < c->sx - 1) {
|
||||||
|
msg = xrealloc(msg, 1, c->sx);
|
||||||
msg[c->sx - 1] = '\0';
|
msg[c->sx - 1] = '\0';
|
||||||
buffer_write(c->out, msg, strlen(msg));
|
memset(msg + size, SCREEN_DEFDATA, (c->sx - 1) - size);
|
||||||
for (i = strlen(msg); i < c->sx; i++)
|
}
|
||||||
input_store8(c->out, ' ');
|
screen_draw_write_string(&ctx, "%s", msg);
|
||||||
xfree(msg);
|
xfree(msg);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
buffer_flush(c->tty.fd, c->tty.in, c->tty.out);
|
||||||
hdr.type = MSG_DATA;
|
usleep(750000);
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
|
|
||||||
hdr.type = MSG_PAUSE;
|
|
||||||
hdr.size = 0;
|
|
||||||
buffer_write(c->out, &hdr, sizeof hdr);
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
|
if (status_lines == 0) {
|
||||||
|
window_draw(c->session->curw->window, &ctx, c->sy - 1, 1);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
if (status_lines == 0)
|
} else {
|
||||||
window_draw(w, c->out, c->sy - 1, 1);
|
screen_draw_stop(&ctx);
|
||||||
else
|
status_write_client(c);
|
||||||
status_write(c);
|
}
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
}
|
||||||
|
44
server-msg.c
44
server-msg.c
@ -1,4 +1,5 @@
|
|||||||
/* $Id: server-msg.c,v 1.37 2007-11-24 20:08:49 nicm Exp $ */
|
|
||||||
|
/* $Id: server-msg.c,v 1.38 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -18,6 +19,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -26,7 +28,6 @@
|
|||||||
|
|
||||||
int server_msg_fn_command(struct hdr *, struct client *);
|
int server_msg_fn_command(struct hdr *, struct client *);
|
||||||
int server_msg_fn_identify(struct hdr *, struct client *);
|
int server_msg_fn_identify(struct hdr *, struct client *);
|
||||||
int server_msg_fn_keys(struct hdr *, struct client *);
|
|
||||||
int server_msg_fn_resize(struct hdr *, struct client *);
|
int server_msg_fn_resize(struct hdr *, struct client *);
|
||||||
|
|
||||||
void printflike2 server_msg_fn_command_error(
|
void printflike2 server_msg_fn_command_error(
|
||||||
@ -43,7 +44,6 @@ const struct server_msg server_msg_table[] = {
|
|||||||
{ MSG_IDENTIFY, server_msg_fn_identify },
|
{ MSG_IDENTIFY, server_msg_fn_identify },
|
||||||
{ MSG_COMMAND, server_msg_fn_command },
|
{ MSG_COMMAND, server_msg_fn_command },
|
||||||
{ MSG_RESIZE, server_msg_fn_resize },
|
{ MSG_RESIZE, server_msg_fn_resize },
|
||||||
{ MSG_KEYS, server_msg_fn_keys },
|
|
||||||
};
|
};
|
||||||
#define NSERVERMSG (sizeof server_msg_table / sizeof server_msg_table[0])
|
#define NSERVERMSG (sizeof server_msg_table / sizeof server_msg_table[0])
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
|
|||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||||
/* XXX fnmatch, multi clients etc */
|
/* XXX fnmatch, multi clients etc */
|
||||||
c = ARRAY_ITEM(&clients, i);
|
c = ARRAY_ITEM(&clients, i);
|
||||||
if (c != NULL && strcmp(client, c->tty) == 0)
|
if (c != NULL && strcmp(client, c->tty.path) == 0)
|
||||||
ctx.client = c;
|
ctx.client = c;
|
||||||
}
|
}
|
||||||
if (ctx.client == NULL) {
|
if (ctx.client == NULL) {
|
||||||
@ -192,10 +192,12 @@ int
|
|||||||
server_msg_fn_identify(struct hdr *hdr, struct client *c)
|
server_msg_fn_identify(struct hdr *hdr, struct client *c)
|
||||||
{
|
{
|
||||||
struct msg_identify_data data;
|
struct msg_identify_data data;
|
||||||
|
char *term;
|
||||||
|
|
||||||
if (hdr->size < sizeof data)
|
if (hdr->size < sizeof data)
|
||||||
fatalx("bad MSG_IDENTIFY size");
|
fatalx("bad MSG_IDENTIFY size");
|
||||||
buffer_read(c->in, &data, sizeof data);
|
buffer_read(c->in, &data, sizeof data);
|
||||||
|
term = cmd_recv_string(c->in);
|
||||||
|
|
||||||
log_debug("identify msg from client: %u,%u", data.sx, data.sy);
|
log_debug("identify msg from client: %u,%u", data.sx, data.sy);
|
||||||
|
|
||||||
@ -203,7 +205,8 @@ server_msg_fn_identify(struct hdr *hdr, struct client *c)
|
|||||||
c->sy = data.sy;
|
c->sy = data.sy;
|
||||||
|
|
||||||
data.tty[(sizeof data.tty) - 1] = '\0';
|
data.tty[(sizeof data.tty) - 1] = '\0';
|
||||||
c->tty = xstrdup(data.tty);
|
tty_init(&c->tty, data.tty, xstrdup(term));
|
||||||
|
xfree(term);
|
||||||
|
|
||||||
c->flags |= CLIENT_TERMINAL;
|
c->flags |= CLIENT_TERMINAL;
|
||||||
|
|
||||||
@ -235,34 +238,3 @@ server_msg_fn_resize(struct hdr *hdr, struct client *c)
|
|||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
server_msg_fn_keys(struct hdr *hdr, struct client *c)
|
|
||||||
{
|
|
||||||
struct window *w = c->session->curw->window;
|
|
||||||
int key;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (hdr->size & 0x1)
|
|
||||||
fatalx("bad MSG_KEYS size");
|
|
||||||
|
|
||||||
size = hdr->size;
|
|
||||||
while (size != 0) {
|
|
||||||
key = (int16_t) input_extract16(c->in);
|
|
||||||
size -= 2;
|
|
||||||
|
|
||||||
if (c->flags & CLIENT_PREFIX) {
|
|
||||||
key_bindings_dispatch(key, c);
|
|
||||||
c->flags &= ~CLIENT_PREFIX;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key == prefix_key) {
|
|
||||||
c->flags |= CLIENT_PREFIX;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
window_key(w, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
77
server.c
77
server.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: server.c,v 1.39 2007-11-21 13:11:41 nicm Exp $ */
|
/* $Id: server.c,v 1.40 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -49,6 +49,7 @@ void server_handle_windows(struct pollfd **);
|
|||||||
void server_fill_clients(struct pollfd **);
|
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_window(struct window *);
|
void server_handle_window(struct window *);
|
||||||
void server_lost_client(struct client *);
|
void server_lost_client(struct client *);
|
||||||
void server_lost_window(struct window *);
|
void server_lost_window(struct window *);
|
||||||
@ -139,7 +140,7 @@ server_main(const char *srv_path, int srv_fd)
|
|||||||
pfds = NULL;
|
pfds = NULL;
|
||||||
while (!sigterm) {
|
while (!sigterm) {
|
||||||
/* Initialise pollfd array. */
|
/* Initialise pollfd array. */
|
||||||
nfds = 1 + ARRAY_LENGTH(&windows) + ARRAY_LENGTH(&clients);
|
nfds = 1 + ARRAY_LENGTH(&windows) + ARRAY_LENGTH(&clients) * 2;
|
||||||
pfds = xrealloc(pfds, nfds, sizeof *pfds);
|
pfds = xrealloc(pfds, nfds, sizeof *pfds);
|
||||||
pfd = pfds;
|
pfd = pfds;
|
||||||
|
|
||||||
@ -246,7 +247,9 @@ server_fill_clients(struct pollfd **pfd)
|
|||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||||
if ((c = ARRAY_ITEM(&clients, i)) == NULL)
|
c = ARRAY_ITEM(&clients, i);
|
||||||
|
|
||||||
|
if (c == NULL)
|
||||||
(*pfd)->fd = -1;
|
(*pfd)->fd = -1;
|
||||||
else {
|
else {
|
||||||
(*pfd)->fd = c->fd;
|
(*pfd)->fd = c->fd;
|
||||||
@ -255,6 +258,16 @@ server_fill_clients(struct pollfd **pfd)
|
|||||||
(*pfd)->events |= POLLOUT;
|
(*pfd)->events |= POLLOUT;
|
||||||
}
|
}
|
||||||
(*pfd)++;
|
(*pfd)++;
|
||||||
|
|
||||||
|
if (c == NULL || c->tty.fd == -1)
|
||||||
|
(*pfd)->fd = -1;
|
||||||
|
else {
|
||||||
|
(*pfd)->fd = c->tty.fd;
|
||||||
|
(*pfd)->events = POLLIN;
|
||||||
|
if (BUFFER_USED(c->tty.out) > 0)
|
||||||
|
(*pfd)->events |= POLLOUT;
|
||||||
|
}
|
||||||
|
(*pfd)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,11 +279,23 @@ server_handle_clients(struct pollfd **pfd)
|
|||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||||
if ((c = ARRAY_ITEM(&clients, i)) != NULL) {
|
c = ARRAY_ITEM(&clients, i);
|
||||||
if (buffer_poll(*pfd, c->in, c->out) != 0)
|
|
||||||
|
if (c != NULL) {
|
||||||
|
if (buffer_poll(*pfd, c->in, c->out) != 0) {
|
||||||
|
server_lost_client(c);
|
||||||
|
(*pfd) += 2;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
server_msg_dispatch(c);
|
||||||
|
}
|
||||||
|
(*pfd)++;
|
||||||
|
|
||||||
|
if (c != NULL && c->tty.fd != -1) {
|
||||||
|
if (buffer_poll(*pfd, c->tty.in, c->tty.out) != 0)
|
||||||
server_lost_client(c);
|
server_lost_client(c);
|
||||||
else
|
else
|
||||||
server_msg_dispatch(c);
|
server_handle_client(c);
|
||||||
}
|
}
|
||||||
(*pfd)++;
|
(*pfd)++;
|
||||||
}
|
}
|
||||||
@ -302,6 +327,8 @@ server_accept_client(int srv_fd)
|
|||||||
c->in = buffer_create(BUFSIZ);
|
c->in = buffer_create(BUFSIZ);
|
||||||
c->out = buffer_create(BUFSIZ);
|
c->out = buffer_create(BUFSIZ);
|
||||||
|
|
||||||
|
c->tty.fd = -1;
|
||||||
|
|
||||||
c->session = NULL;
|
c->session = NULL;
|
||||||
c->sx = 80;
|
c->sx = 80;
|
||||||
c->sy = 25;
|
c->sy = 25;
|
||||||
@ -316,6 +343,25 @@ server_accept_client(int srv_fd)
|
|||||||
return (c);
|
return (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Input data from client. */
|
||||||
|
void
|
||||||
|
server_handle_client(struct client *c)
|
||||||
|
{
|
||||||
|
struct window *w = c->session->curw->window;
|
||||||
|
int key;
|
||||||
|
|
||||||
|
while (tty_keys_next(&c->tty, &key) == 0) {
|
||||||
|
if (c->flags & CLIENT_PREFIX) {
|
||||||
|
key_bindings_dispatch(key, c);
|
||||||
|
c->flags &= ~CLIENT_PREFIX;
|
||||||
|
continue;
|
||||||
|
} else if (key == prefix_key)
|
||||||
|
c->flags |= CLIENT_PREFIX;
|
||||||
|
else
|
||||||
|
window_key(w, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Lost a client. */
|
/* Lost a client. */
|
||||||
void
|
void
|
||||||
server_lost_client(struct client *c)
|
server_lost_client(struct client *c)
|
||||||
@ -327,8 +373,8 @@ server_lost_client(struct client *c)
|
|||||||
ARRAY_SET(&clients, i, NULL);
|
ARRAY_SET(&clients, i, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->tty != NULL)
|
tty_free(&c->tty);
|
||||||
xfree(c->tty);
|
|
||||||
close(c->fd);
|
close(c->fd);
|
||||||
buffer_destroy(c->in);
|
buffer_destroy(c->in);
|
||||||
buffer_destroy(c->out);
|
buffer_destroy(c->out);
|
||||||
@ -341,17 +387,10 @@ server_lost_client(struct client *c)
|
|||||||
void
|
void
|
||||||
server_handle_window(struct window *w)
|
server_handle_window(struct window *w)
|
||||||
{
|
{
|
||||||
struct buffer *b;
|
|
||||||
struct session *s;
|
struct session *s;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
b = buffer_create(BUFSIZ);
|
window_parse(w);
|
||||||
window_parse(w, b);
|
|
||||||
if (BUFFER_USED(b) != 0) {
|
|
||||||
server_write_window_cur(
|
|
||||||
w, MSG_DATA, BUFFER_OUT(b), BUFFER_USED(b));
|
|
||||||
}
|
|
||||||
buffer_destroy(b);
|
|
||||||
|
|
||||||
if (!(w->flags & WINDOW_BELL))
|
if (!(w->flags & WINDOW_BELL))
|
||||||
return;
|
return;
|
||||||
@ -364,17 +403,17 @@ server_handle_window(struct window *w)
|
|||||||
|
|
||||||
switch (bell_action) {
|
switch (bell_action) {
|
||||||
case BELL_ANY:
|
case BELL_ANY:
|
||||||
server_write_window_all(w, MSG_DATA, "\007", 1);
|
tty_write_window(w, TTY_CHARACTER, '\007');
|
||||||
break;
|
break;
|
||||||
case BELL_CURRENT:
|
case BELL_CURRENT:
|
||||||
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
|
||||||
s = ARRAY_ITEM(&sessions, i);
|
s = ARRAY_ITEM(&sessions, i);
|
||||||
if (s != NULL && s->curw->window == w)
|
if (s != NULL && s->curw->window == w)
|
||||||
server_write_session(s, MSG_DATA, "\007", 1);
|
tty_write_session(s, TTY_CHARACTER, '\007');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
server_status_window_all(w);
|
server_status_window(w);
|
||||||
|
|
||||||
w->flags &= ~WINDOW_BELL;
|
w->flags &= ~WINDOW_BELL;
|
||||||
}
|
}
|
||||||
|
81
status.c
81
status.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: status.c,v 1.13 2007-11-22 18:09:43 nicm Exp $ */
|
/* $Id: status.c,v 1.14 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -25,19 +25,19 @@
|
|||||||
void printflike3 status_print(struct buffer *, size_t *, const char *, ...);
|
void printflike3 status_print(struct buffer *, size_t *, const char *, ...);
|
||||||
|
|
||||||
void
|
void
|
||||||
status_write(struct client *c)
|
status_write_client(struct client *c)
|
||||||
{
|
{
|
||||||
struct screen *s = &c->session->curw->window->screen;
|
struct screen_draw_ctx ctx;
|
||||||
struct buffer *b = c->out;
|
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
size_t size;
|
|
||||||
char flag;
|
char flag;
|
||||||
|
|
||||||
input_store_zero(b, CODE_CURSOROFF);
|
if (status_lines == 0 || c->sy <= status_lines)
|
||||||
input_store_two(b, CODE_CURSORMOVE, c->sy - status_lines + 1, 1);
|
return;
|
||||||
input_store_two(b, CODE_ATTRIBUTES, 0, status_colour);
|
|
||||||
|
screen_draw_start_client(&ctx, c, 0, 0);
|
||||||
|
screen_draw_move_cursor(&ctx, 0, c->sy - status_lines);
|
||||||
|
screen_draw_set_attributes(&ctx, 0, status_colour);
|
||||||
|
|
||||||
size = c->sx;
|
|
||||||
RB_FOREACH(wl, winlinks, &c->session->windows) {
|
RB_FOREACH(wl, winlinks, &c->session->windows) {
|
||||||
flag = ' ';
|
flag = ' ';
|
||||||
if (wl == c->session->lastw)
|
if (wl == c->session->lastw)
|
||||||
@ -46,45 +46,50 @@ status_write(struct client *c)
|
|||||||
flag = '*';
|
flag = '*';
|
||||||
if (session_hasbell(c->session, wl))
|
if (session_hasbell(c->session, wl))
|
||||||
flag = '!';
|
flag = '!';
|
||||||
status_print(
|
screen_draw_write_string(
|
||||||
b, &size, "%d:%s%c ", wl->idx, wl->window->name, flag);
|
&ctx, "%d:%s%c ", wl->idx, wl->window->name, flag);
|
||||||
|
|
||||||
if (size == 0)
|
if (ctx.cx >= screen_last_x(ctx.s))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (size-- > 0)
|
screen_draw_clear_line_to(&ctx, screen_last_x(ctx.s));
|
||||||
input_store8(b, ' ');
|
|
||||||
|
|
||||||
input_store_two(b, CODE_ATTRIBUTES, s->attr, s->colr);
|
screen_draw_stop(&ctx);
|
||||||
input_store_two(b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
|
|
||||||
if (s->mode & MODE_BACKGROUND) {
|
|
||||||
if (s->mode & MODE_BGCURSOR)
|
|
||||||
input_store_zero(c->out, CODE_CURSORON);
|
|
||||||
} else {
|
|
||||||
if (s->mode & MODE_CURSOR)
|
|
||||||
input_store_zero(c->out, CODE_CURSORON);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printflike3
|
void
|
||||||
status_print(struct buffer *b, size_t *size, const char *fmt, ...)
|
status_write_window(struct window *w)
|
||||||
{
|
{
|
||||||
va_list ap;
|
struct client *c;
|
||||||
char *msg, *ptr;
|
u_int i;
|
||||||
int n;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
if (w->screen.mode & MODE_HIDDEN)
|
||||||
n = xvasprintf(&msg, fmt, ap);
|
return;
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if ((size_t) n > *size) {
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||||
msg[*size] = '\0';
|
c = ARRAY_ITEM(&clients, i);
|
||||||
n = *size;
|
if (c == NULL || c->session == NULL)
|
||||||
|
continue;
|
||||||
|
if (c->session->curw->window != w)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
status_write_client(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ptr = msg; *ptr != '\0'; ptr++)
|
void
|
||||||
input_store8(b, *ptr);
|
status_write_session(struct session *s)
|
||||||
(*size) -= n;
|
{
|
||||||
|
struct client *c;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
xfree(msg);
|
if (s->flags & SESSION_UNATTACHED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||||
|
c = ARRAY_ITEM(&clients, i);
|
||||||
|
if (c == NULL || c->session != s)
|
||||||
|
continue;
|
||||||
|
status_write_client(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
208
tmux.h
208
tmux.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tmux.h,v 1.100 2007-11-24 23:29:49 nicm Exp $ */
|
/* $Id: tmux.h,v 1.101 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -41,6 +41,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <term.h>
|
||||||
|
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
|
||||||
@ -255,34 +256,32 @@ struct buffer {
|
|||||||
#define KEYC_UP -149
|
#define KEYC_UP -149
|
||||||
#define KEYC_MOUSE -150
|
#define KEYC_MOUSE -150
|
||||||
|
|
||||||
/* Translated escape codes. */
|
/* Output codes. */
|
||||||
#define CODE_CURSORUP 0
|
#define TTY_CHARACTER 0
|
||||||
#define CODE_CURSORDOWN 1
|
#define TTY_CURSORUP 1
|
||||||
#define CODE_CURSORRIGHT 2
|
#define TTY_CURSORDOWN 2
|
||||||
#define CODE_CURSORLEFT 3
|
#define TTY_CURSORRIGHT 3
|
||||||
#define CODE_INSERTCHARACTER 4
|
#define TTY_CURSORLEFT 4
|
||||||
#define CODE_DELETECHARACTER 5
|
#define TTY_INSERTCHARACTER 5
|
||||||
#define CODE_INSERTLINE 6
|
#define TTY_DELETECHARACTER 6
|
||||||
#define CODE_DELETELINE 7
|
#define TTY_INSERTLINE 7
|
||||||
#define CODE_CLEARLINE 8
|
#define TTY_DELETELINE 8
|
||||||
/* 9 unused */
|
#define TTY_CLEARLINE 9
|
||||||
/* 10 unused */
|
#define TTY_CLEARENDOFLINE 10
|
||||||
#define CODE_CLEARENDOFLINE 11
|
#define TTY_CLEARSTARTOFLINE 11
|
||||||
#define CODE_CLEARSTARTOFLINE 12
|
#define TTY_CURSORMOVE 12
|
||||||
#define CODE_CURSORMOVE 13
|
#define TTY_ATTRIBUTES 13
|
||||||
#define CODE_ATTRIBUTES 14
|
#define TTY_CURSOROFF 14
|
||||||
#define CODE_CURSOROFF 15
|
#define TTY_CURSORON 15
|
||||||
#define CODE_CURSORON 16
|
#define TTY_REVERSEINDEX 16
|
||||||
#define CODE_REVERSEINDEX 17
|
#define TTY_SCROLLREGION 17
|
||||||
/* 18 unused */
|
#define TTY_INSERTON 18
|
||||||
#define CODE_SCROLLREGION 19
|
#define TTY_INSERTOFF 19
|
||||||
#define CODE_INSERTON 20
|
#define TTY_KCURSOROFF 20
|
||||||
#define CODE_INSERTOFF 21
|
#define TTY_KCURSORON 21
|
||||||
#define CODE_KCURSOROFF 22
|
#define TTY_KKEYPADOFF 22
|
||||||
#define CODE_KCURSORON 23
|
#define TTY_KKEYPADON 23
|
||||||
#define CODE_KKEYPADOFF 24
|
#define TTY_TITLE 24
|
||||||
#define CODE_KKEYPADON 25
|
|
||||||
#define CODE_TITLE 26
|
|
||||||
|
|
||||||
/* Message codes. */
|
/* Message codes. */
|
||||||
enum hdrtype {
|
enum hdrtype {
|
||||||
@ -294,9 +293,6 @@ enum hdrtype {
|
|||||||
MSG_READY,
|
MSG_READY,
|
||||||
MSG_DETACH,
|
MSG_DETACH,
|
||||||
MSG_RESIZE,
|
MSG_RESIZE,
|
||||||
MSG_DATA,
|
|
||||||
MSG_KEYS,
|
|
||||||
MSG_PAUSE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Message header structure. */
|
/* Message header structure. */
|
||||||
@ -317,6 +313,8 @@ struct msg_identify_data {
|
|||||||
|
|
||||||
u_int sx;
|
u_int sx;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
|
|
||||||
|
size_t termlen;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msg_resize_data {
|
struct msg_resize_data {
|
||||||
@ -394,8 +392,10 @@ struct screen_draw_sel {
|
|||||||
|
|
||||||
/* Screen redraw context. */
|
/* Screen redraw context. */
|
||||||
struct screen_draw_ctx {
|
struct screen_draw_ctx {
|
||||||
|
void *data;
|
||||||
|
void (*write)(void *, int, ...);
|
||||||
|
|
||||||
struct screen *s;
|
struct screen *s;
|
||||||
struct buffer *b;
|
|
||||||
|
|
||||||
u_int cx;
|
u_int cx;
|
||||||
u_int cy;
|
u_int cy;
|
||||||
@ -423,8 +423,6 @@ struct screen_draw_ctx {
|
|||||||
#define screen_in_y(s, y) ((y) < screen_size_y(s))
|
#define screen_in_y(s, y) ((y) < screen_size_y(s))
|
||||||
#define screen_in_region(s, y) ((y) >= (s)->rupper && (y) <= (s)->rlower)
|
#define screen_in_region(s, y) ((y) >= (s)->rupper && (y) <= (s)->rlower)
|
||||||
|
|
||||||
#define screen_hidden(s) ((s)->mode & (MODE_HIDDEN|MODE_BACKGROUND))
|
|
||||||
|
|
||||||
/* Screen default contents. */
|
/* Screen default contents. */
|
||||||
#define SCREEN_DEFDATA ' '
|
#define SCREEN_DEFDATA ' '
|
||||||
#define SCREEN_DEFATTR 0
|
#define SCREEN_DEFATTR 0
|
||||||
@ -439,7 +437,6 @@ struct input_arg {
|
|||||||
/* Input parser context. */
|
/* Input parser context. */
|
||||||
struct input_ctx {
|
struct input_ctx {
|
||||||
struct window *w;
|
struct window *w;
|
||||||
struct buffer *b;
|
|
||||||
|
|
||||||
u_char *buf;
|
u_char *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -462,7 +459,8 @@ struct input_ctx {
|
|||||||
struct window_mode {
|
struct window_mode {
|
||||||
void (*init)(struct window *);
|
void (*init)(struct window *);
|
||||||
void (*resize)(struct window *, u_int, u_int);
|
void (*resize)(struct window *, u_int, u_int);
|
||||||
void (*draw)(struct window *, struct buffer *, u_int, u_int);
|
void (*draw)(
|
||||||
|
struct window *, struct screen_draw_ctx *, u_int, u_int);
|
||||||
void (*key)(struct window *, int);
|
void (*key)(struct window *, int);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -516,19 +514,49 @@ struct session {
|
|||||||
};
|
};
|
||||||
ARRAY_DECL(sessions, struct session *);
|
ARRAY_DECL(sessions, struct session *);
|
||||||
|
|
||||||
/* Client connection. */
|
/* TTY information. */
|
||||||
struct client {
|
struct tty_key {
|
||||||
char *tty;
|
int code;
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
RB_ENTRY(tty_key) entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tty {
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
char *term;
|
||||||
|
TERMINAL *termp;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
struct buffer *in;
|
struct buffer *in;
|
||||||
struct buffer *out;
|
struct buffer *out;
|
||||||
|
|
||||||
|
struct termios tio;
|
||||||
|
|
||||||
|
u_int attr;
|
||||||
|
u_int colr;
|
||||||
|
|
||||||
|
u_char acs[UCHAR_MAX + 1];
|
||||||
|
|
||||||
|
size_t ksize; /* maximum key size */
|
||||||
|
RB_HEAD(tty_keys, tty_key) ktree;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Client connection. */
|
||||||
|
struct client {
|
||||||
|
int fd;
|
||||||
|
struct buffer *in;
|
||||||
|
struct buffer *out;
|
||||||
|
|
||||||
|
struct tty tty;
|
||||||
|
|
||||||
u_int sx;
|
u_int sx;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
|
|
||||||
#define CLIENT_TERMINAL 0x1
|
#define CLIENT_TERMINAL 0x1
|
||||||
#define CLIENT_PREFIX 0x2
|
#define CLIENT_PREFIX 0x2
|
||||||
|
#define CLIENT_ATTACHED 0x4
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
struct session *session;
|
struct session *session;
|
||||||
@ -541,13 +569,8 @@ struct client_ctx {
|
|||||||
struct buffer *srv_in;
|
struct buffer *srv_in;
|
||||||
struct buffer *srv_out;
|
struct buffer *srv_out;
|
||||||
|
|
||||||
int loc_fd;
|
#define CCTX_DETACH 0x1
|
||||||
struct buffer *loc_in;
|
#define CCTX_EXIT 0x2
|
||||||
struct buffer *loc_out;
|
|
||||||
|
|
||||||
#define CCTX_PAUSE 0x1
|
|
||||||
#define CCTX_DETACH 0x2
|
|
||||||
#define CCTX_EXIT 0x4
|
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -629,6 +652,28 @@ void logfile(const char *);
|
|||||||
void siginit(void);
|
void siginit(void);
|
||||||
void sigreset(void);
|
void sigreset(void);
|
||||||
|
|
||||||
|
/* tty.c */
|
||||||
|
void tty_init(struct tty *, char *, char *);
|
||||||
|
int tty_open(struct tty *, char **);
|
||||||
|
void tty_close(struct tty *);
|
||||||
|
void tty_free(struct tty *);
|
||||||
|
void tty_vwrite(struct tty *, int, va_list);
|
||||||
|
|
||||||
|
/* tty-keys.c */
|
||||||
|
int tty_keys_cmp(struct tty_key *, struct tty_key *);
|
||||||
|
RB_PROTOTYPE(tty_keys, tty_key, entry, tty_keys_cmp);
|
||||||
|
void tty_keys_init(struct tty *);
|
||||||
|
void tty_keys_free(struct tty *);
|
||||||
|
int tty_keys_next(struct tty *, int *);
|
||||||
|
|
||||||
|
/* tty-write.c */
|
||||||
|
void tty_write_client(void *, int, ...);
|
||||||
|
void tty_vwrite_client(void *, int, va_list);
|
||||||
|
void tty_write_window(void *, int, ...);
|
||||||
|
void tty_vwrite_window(void *, int, va_list);
|
||||||
|
void tty_write_session(void *, int, ...);
|
||||||
|
void tty_vwrite_session(void *, int, va_list);
|
||||||
|
|
||||||
/* cmd.c */
|
/* cmd.c */
|
||||||
struct cmd *cmd_parse(int, char **, char **);
|
struct cmd *cmd_parse(int, char **, char **);
|
||||||
void cmd_exec(struct cmd *, struct cmd_ctx *);
|
void cmd_exec(struct cmd *, struct cmd_ctx *);
|
||||||
@ -708,25 +753,23 @@ void server_write_client(
|
|||||||
struct client *, enum hdrtype, const void *, size_t);
|
struct client *, enum hdrtype, const void *, size_t);
|
||||||
void server_write_session(
|
void server_write_session(
|
||||||
struct session *, enum hdrtype, const void *, size_t);
|
struct session *, enum hdrtype, const void *, size_t);
|
||||||
void server_write_window_cur(
|
void server_write_window(
|
||||||
struct window *, enum hdrtype, const void *, size_t);
|
struct window *, enum hdrtype, const void *, size_t);
|
||||||
void server_write_window_all(
|
|
||||||
struct window *, enum hdrtype, const void *, size_t);
|
|
||||||
void server_status_client(struct client *);
|
|
||||||
void server_clear_client(struct client *);
|
void server_clear_client(struct client *);
|
||||||
void server_redraw_client(struct client *);
|
void server_redraw_client(struct client *);
|
||||||
void server_status_session(struct session *);
|
void server_status_client(struct client *);
|
||||||
|
void server_clear_session(struct session *);
|
||||||
void server_redraw_session(struct session *);
|
void server_redraw_session(struct session *);
|
||||||
void server_status_window_cur(struct window *);
|
void server_status_session(struct session *);
|
||||||
void server_status_window_all(struct window *);
|
void server_clear_window(struct window *);
|
||||||
void server_clear_window_cur(struct window *);
|
void server_redraw_window(struct window *);
|
||||||
void server_clear_window_all(struct window *);
|
void server_status_window(struct window *);
|
||||||
void server_redraw_window_cur(struct window *);
|
|
||||||
void server_redraw_window_all(struct window *);
|
|
||||||
void printflike2 server_write_message(struct client *, const char *, ...);
|
void printflike2 server_write_message(struct client *, const char *, ...);
|
||||||
|
|
||||||
/* status.c */
|
/* status.c */
|
||||||
void status_write(struct client *c);
|
void status_write_client(struct client *);
|
||||||
|
void status_write_session(struct session *);
|
||||||
|
void status_write_window(struct window *);
|
||||||
|
|
||||||
/* resize.c */
|
/* resize.c */
|
||||||
void recalculate_sizes(void);
|
void recalculate_sizes(void);
|
||||||
@ -734,17 +777,10 @@ void recalculate_sizes(void);
|
|||||||
/* input.c */
|
/* input.c */
|
||||||
void input_init(struct window *);
|
void input_init(struct window *);
|
||||||
void input_free(struct window *);
|
void input_free(struct window *);
|
||||||
void input_parse(struct window *, struct buffer *);
|
void input_parse(struct window *);
|
||||||
uint8_t input_extract8(struct buffer *);
|
|
||||||
uint16_t input_extract16(struct buffer *);
|
|
||||||
void input_store8(struct buffer *, uint8_t);
|
|
||||||
void input_store16(struct buffer *, uint16_t);
|
|
||||||
void input_store_zero(struct buffer *, u_char);
|
|
||||||
void input_store_one(struct buffer *, u_char, uint16_t);
|
|
||||||
void input_store_two(struct buffer *, u_char, uint16_t, uint16_t);
|
|
||||||
|
|
||||||
/* input-key.c */
|
/* input-key.c */
|
||||||
void input_key(struct buffer *, int);
|
void input_key(struct window *, int);
|
||||||
|
|
||||||
/* screen-display.c */
|
/* screen-display.c */
|
||||||
void screen_display_make_lines(struct screen *, u_int, u_int);
|
void screen_display_make_lines(struct screen *, u_int, u_int);
|
||||||
@ -788,15 +824,29 @@ void screen_reduce_line(struct screen *, u_int, u_int);
|
|||||||
void screen_get_cell(
|
void screen_get_cell(
|
||||||
struct screen *, u_int, u_int, u_char *, u_char *, u_char *);
|
struct screen *, u_int, u_int, u_char *, u_char *, u_char *);
|
||||||
void screen_set_cell(struct screen *, u_int, u_int, u_char, u_char, u_char);
|
void screen_set_cell(struct screen *, u_int, u_int, u_char, u_char, u_char);
|
||||||
void screen_draw_start(struct screen_draw_ctx *,
|
void screen_draw_start_window(
|
||||||
struct screen *, struct buffer *, u_int, u_int);
|
struct screen_draw_ctx *, struct window *, u_int, u_int);
|
||||||
|
void screen_draw_start_client(
|
||||||
|
struct screen_draw_ctx *, struct client *, u_int, u_int);
|
||||||
|
void screen_draw_start_session(
|
||||||
|
struct screen_draw_ctx *, struct session *, u_int, u_int);
|
||||||
|
void screen_draw_start(struct screen_draw_ctx *, struct screen *s,
|
||||||
|
void (*)(void *, int, ...), void *, u_int, u_int);
|
||||||
void screen_draw_stop(struct screen_draw_ctx *);
|
void screen_draw_stop(struct screen_draw_ctx *);
|
||||||
void screen_draw_set_selection(
|
void screen_draw_set_selection(
|
||||||
struct screen_draw_ctx *, int, u_int, u_int, u_int, u_int);
|
struct screen_draw_ctx *, int, u_int, u_int, u_int, u_int);
|
||||||
int screen_draw_check_selection(struct screen_draw_ctx *, u_int, u_int);
|
int screen_draw_check_selection(struct screen_draw_ctx *, u_int, u_int);
|
||||||
void screen_draw_get_cell(struct screen_draw_ctx *,
|
void screen_draw_get_cell(struct screen_draw_ctx *,
|
||||||
u_int, u_int, u_char *, u_char *, u_char *);
|
u_int, u_int, u_char *, u_char *, u_char *);
|
||||||
void screen_draw_move(struct screen_draw_ctx *, u_int, u_int);
|
void screen_draw_insert_characters(struct screen_draw_ctx *, u_int);
|
||||||
|
void screen_draw_delete_characters(struct screen_draw_ctx *, u_int);
|
||||||
|
void screen_draw_insert_lines(struct screen_draw_ctx *, u_int);
|
||||||
|
void screen_draw_delete_lines(struct screen_draw_ctx *, u_int);
|
||||||
|
void screen_draw_clear_line_to(struct screen_draw_ctx *, u_int);
|
||||||
|
void screen_draw_clear_screen(struct screen_draw_ctx *);
|
||||||
|
void printflike2 screen_draw_write_string(
|
||||||
|
struct screen_draw_ctx *, const char *, ...);
|
||||||
|
void screen_draw_move_cursor(struct screen_draw_ctx *, u_int, u_int);
|
||||||
void screen_draw_set_attributes(struct screen_draw_ctx *, u_char, u_char);
|
void screen_draw_set_attributes(struct screen_draw_ctx *, u_char, u_char);
|
||||||
void screen_draw_cell(struct screen_draw_ctx *, u_int, u_int);
|
void screen_draw_cell(struct screen_draw_ctx *, u_int, u_int);
|
||||||
void screen_draw_cells(struct screen_draw_ctx *, u_int, u_int, u_int);
|
void screen_draw_cells(struct screen_draw_ctx *, u_int, u_int, u_int);
|
||||||
@ -812,12 +862,6 @@ void screen_fill_lines(
|
|||||||
void screen_fill_cells(
|
void screen_fill_cells(
|
||||||
struct screen *, u_int, u_int, u_int, u_char, u_char, u_char);
|
struct screen *, u_int, u_int, u_int, u_char, u_char, u_char);
|
||||||
|
|
||||||
/* local.c */
|
|
||||||
int local_init(struct buffer **, struct buffer **);
|
|
||||||
void local_done(void);
|
|
||||||
int local_key(void);
|
|
||||||
void local_output(struct buffer *, size_t);
|
|
||||||
|
|
||||||
/* window.c */
|
/* window.c */
|
||||||
extern struct windows windows;
|
extern struct windows windows;
|
||||||
int window_cmp(struct window *, struct window *);
|
int window_cmp(struct window *, struct window *);
|
||||||
@ -835,8 +879,9 @@ struct window *window_create(
|
|||||||
const char *, const char *, const char **, u_int, u_int);
|
const char *, const char *, const char **, u_int, u_int);
|
||||||
void window_destroy(struct window *);
|
void window_destroy(struct window *);
|
||||||
int window_resize(struct window *, u_int, u_int);
|
int window_resize(struct window *, u_int, u_int);
|
||||||
void window_parse(struct window *, struct buffer *);
|
void window_parse(struct window *);
|
||||||
void window_draw(struct window *, struct buffer *, u_int, u_int);
|
void window_draw(
|
||||||
|
struct window *, struct screen_draw_ctx *, u_int, u_int);
|
||||||
void window_key(struct window *, int);
|
void window_key(struct window *, int);
|
||||||
|
|
||||||
/* window-copy.c */
|
/* window-copy.c */
|
||||||
@ -881,9 +926,14 @@ void buffer_insert_range(struct buffer *, size_t, size_t);
|
|||||||
void buffer_delete_range(struct buffer *, size_t, size_t);
|
void buffer_delete_range(struct buffer *, size_t, size_t);
|
||||||
void buffer_write(struct buffer *, const void *, size_t);
|
void buffer_write(struct buffer *, const void *, size_t);
|
||||||
void buffer_read(struct buffer *, void *, size_t);
|
void buffer_read(struct buffer *, void *, size_t);
|
||||||
|
void buffer_write8(struct buffer *, uint8_t);
|
||||||
|
void buffer_write16(struct buffer *, uint16_t);
|
||||||
|
uint8_t buffer_read8(struct buffer *);
|
||||||
|
uint16_t buffer_read16(struct buffer *);
|
||||||
|
|
||||||
/* buffer-poll.c */
|
/* buffer-poll.c */
|
||||||
int buffer_poll(struct pollfd *, struct buffer *, struct buffer *);
|
int buffer_poll(struct pollfd *, struct buffer *, struct buffer *);
|
||||||
|
void buffer_flush(int, struct buffer *n, struct buffer *);
|
||||||
|
|
||||||
/* log.c */
|
/* log.c */
|
||||||
void log_open(FILE *, int, int);
|
void log_open(FILE *, int, int);
|
||||||
|
273
tty-keys.c
Normal file
273
tty-keys.c
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
/* $Id: tty-keys.c,v 1.1 2007-11-27 19:23:34 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "tmux.h"
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
int code;
|
||||||
|
} tty_keys[] = {
|
||||||
|
{ "kBEG", KEYC_SBEG },
|
||||||
|
{ "kCAN", KEYC_SCANCEL },
|
||||||
|
{ "kCMD", KEYC_SCOMMAND },
|
||||||
|
{ "kCPY", KEYC_SCOPY },
|
||||||
|
{ "kCRT", KEYC_SCREATE },
|
||||||
|
{ "kDC", KEYC_SDC },
|
||||||
|
{ "kDL", KEYC_SDL },
|
||||||
|
{ "kEND", KEYC_SEND },
|
||||||
|
{ "kEOL", KEYC_SEOL },
|
||||||
|
{ "kEXT", KEYC_SEXIT },
|
||||||
|
{ "kFND", KEYC_SFIND },
|
||||||
|
{ "kHLP", KEYC_SHELP },
|
||||||
|
{ "kHOM", KEYC_SHOME },
|
||||||
|
{ "kIC", KEYC_SIC },
|
||||||
|
{ "kLFT", KEYC_SLEFT },
|
||||||
|
{ "kMOV", KEYC_SMOVE },
|
||||||
|
{ "kMSG", KEYC_SMESSAGE },
|
||||||
|
{ "kNXT", KEYC_SNEXT },
|
||||||
|
{ "kOPT", KEYC_SOPTIONS },
|
||||||
|
{ "kPRT", KEYC_SPRINT },
|
||||||
|
{ "kPRV", KEYC_SPREVIOUS },
|
||||||
|
{ "kRDO", KEYC_SREDO },
|
||||||
|
{ "kRES", KEYC_SRSUME },
|
||||||
|
{ "kRIT", KEYC_SRIGHT },
|
||||||
|
{ "kRPL", KEYC_SREPLACE },
|
||||||
|
{ "kSAV", KEYC_SSAVE },
|
||||||
|
{ "kSPD", KEYC_SSUSPEND },
|
||||||
|
{ "kUND", KEYC_SUNDO },
|
||||||
|
{ "ka1", KEYC_A1 },
|
||||||
|
{ "ka3", KEYC_A3 },
|
||||||
|
{ "kb2", KEYC_B2 },
|
||||||
|
{ "kbeg", KEYC_BEG },
|
||||||
|
{ "kc1", KEYC_C1 },
|
||||||
|
{ "kc3", KEYC_C3 },
|
||||||
|
{ "kcan", KEYC_CANCEL },
|
||||||
|
{ "kcbt", KEYC_BTAB },
|
||||||
|
{ "kclo", KEYC_CLOSE },
|
||||||
|
{ "kclr", KEYC_CLEAR },
|
||||||
|
{ "kcmd", KEYC_COMMAND },
|
||||||
|
{ "kcpy", KEYC_COPY },
|
||||||
|
{ "kcrt", KEYC_CREATE },
|
||||||
|
{ "kctab", KEYC_CTAB },
|
||||||
|
{ "kcub1", KEYC_LEFT },
|
||||||
|
{ "kcud1", KEYC_DOWN },
|
||||||
|
{ "kcuf1", KEYC_RIGHT },
|
||||||
|
{ "kcuu1", KEYC_UP },
|
||||||
|
{ "kdch1", KEYC_DC },
|
||||||
|
{ "kdl1", KEYC_DL },
|
||||||
|
{ "ked", KEYC_EOS },
|
||||||
|
{ "kel", KEYC_EOL },
|
||||||
|
{ "kend", KEYC_END },
|
||||||
|
{ "kent", KEYC_ENTER },
|
||||||
|
{ "kext", KEYC_EXIT },
|
||||||
|
{ "kf0", KEYC_F0 },
|
||||||
|
{ "kf1", KEYC_F1 },
|
||||||
|
{ "kf10", KEYC_F10 },
|
||||||
|
{ "kf11", KEYC_F11 },
|
||||||
|
{ "kf12", KEYC_F12 },
|
||||||
|
{ "kf13", KEYC_F13 },
|
||||||
|
{ "kf14", KEYC_F14 },
|
||||||
|
{ "kf15", KEYC_F15 },
|
||||||
|
{ "kf16", KEYC_F16 },
|
||||||
|
{ "kf17", KEYC_F17 },
|
||||||
|
{ "kf18", KEYC_F18 },
|
||||||
|
{ "kf19", KEYC_F19 },
|
||||||
|
{ "kf2", KEYC_F2 },
|
||||||
|
{ "kf20", KEYC_F20 },
|
||||||
|
{ "kf21", KEYC_F21 },
|
||||||
|
{ "kf22", KEYC_F22 },
|
||||||
|
{ "kf23", KEYC_F23 },
|
||||||
|
{ "kf24", KEYC_F24 },
|
||||||
|
{ "kf25", KEYC_F25 },
|
||||||
|
{ "kf26", KEYC_F26 },
|
||||||
|
{ "kf27", KEYC_F27 },
|
||||||
|
{ "kf28", KEYC_F28 },
|
||||||
|
{ "kf29", KEYC_F29 },
|
||||||
|
{ "kf3", KEYC_F3 },
|
||||||
|
{ "kf30", KEYC_F30 },
|
||||||
|
{ "kf31", KEYC_F31 },
|
||||||
|
{ "kf32", KEYC_F32 },
|
||||||
|
{ "kf33", KEYC_F33 },
|
||||||
|
{ "kf34", KEYC_F34 },
|
||||||
|
{ "kf35", KEYC_F35 },
|
||||||
|
{ "kf36", KEYC_F36 },
|
||||||
|
{ "kf37", KEYC_F37 },
|
||||||
|
{ "kf38", KEYC_F38 },
|
||||||
|
{ "kf39", KEYC_F39 },
|
||||||
|
{ "kf4", KEYC_F4 },
|
||||||
|
{ "kf40", KEYC_F40 },
|
||||||
|
{ "kf41", KEYC_F41 },
|
||||||
|
{ "kf42", KEYC_F42 },
|
||||||
|
{ "kf43", KEYC_F43 },
|
||||||
|
{ "kf44", KEYC_F44 },
|
||||||
|
{ "kf45", KEYC_F45 },
|
||||||
|
{ "kf46", KEYC_F46 },
|
||||||
|
{ "kf47", KEYC_F47 },
|
||||||
|
{ "kf48", KEYC_F48 },
|
||||||
|
{ "kf49", KEYC_F49 },
|
||||||
|
{ "kf5", KEYC_F5 },
|
||||||
|
{ "kf50", KEYC_F50 },
|
||||||
|
{ "kf51", KEYC_F51 },
|
||||||
|
{ "kf52", KEYC_F52 },
|
||||||
|
{ "kf53", KEYC_F53 },
|
||||||
|
{ "kf54", KEYC_F54 },
|
||||||
|
{ "kf55", KEYC_F55 },
|
||||||
|
{ "kf56", KEYC_F56 },
|
||||||
|
{ "kf57", KEYC_F57 },
|
||||||
|
{ "kf58", KEYC_F58 },
|
||||||
|
{ "kf59", KEYC_F59 },
|
||||||
|
{ "kf6", KEYC_F6 },
|
||||||
|
{ "kf60", KEYC_F60 },
|
||||||
|
{ "kf61", KEYC_F61 },
|
||||||
|
{ "kf62", KEYC_F62 },
|
||||||
|
{ "kf63", KEYC_F63 },
|
||||||
|
{ "kf7", KEYC_F7 },
|
||||||
|
{ "kf8", KEYC_F8 },
|
||||||
|
{ "kf9", KEYC_F9 },
|
||||||
|
{ "kfnd", KEYC_FIND },
|
||||||
|
{ "khlp", KEYC_HELP },
|
||||||
|
{ "khome", KEYC_HOME },
|
||||||
|
{ "khts", KEYC_STAB },
|
||||||
|
{ "kich1", KEYC_IC },
|
||||||
|
{ "kil1", KEYC_IL },
|
||||||
|
{ "kind", KEYC_SF },
|
||||||
|
{ "kll", KEYC_LL },
|
||||||
|
{ "kmov", KEYC_MOVE },
|
||||||
|
{ "kmrk", KEYC_MARK },
|
||||||
|
{ "kmsg", KEYC_MESSAGE },
|
||||||
|
{ "knp", KEYC_NPAGE },
|
||||||
|
{ "knxt", KEYC_NEXT },
|
||||||
|
{ "kopn", KEYC_OPEN },
|
||||||
|
{ "kopt", KEYC_OPTIONS },
|
||||||
|
{ "kpp", KEYC_PPAGE },
|
||||||
|
{ "kprt", KEYC_PRINT },
|
||||||
|
{ "kprv", KEYC_PREVIOUS },
|
||||||
|
{ "krdo", KEYC_REDO },
|
||||||
|
{ "kref", KEYC_REFERENCE },
|
||||||
|
{ "kres", KEYC_RESUME },
|
||||||
|
{ "krfr", KEYC_REFRESH },
|
||||||
|
{ "kri", KEYC_SR },
|
||||||
|
{ "krmir", KEYC_EIC },
|
||||||
|
{ "krpl", KEYC_REPLACE },
|
||||||
|
{ "krst", KEYC_RESTART },
|
||||||
|
{ "ksav", KEYC_SAVE },
|
||||||
|
{ "kslt", KEYC_SELECT },
|
||||||
|
{ "kspd", KEYC_SUSPEND },
|
||||||
|
{ "ktbc", KEYC_CATAB },
|
||||||
|
{ "kund", KEYC_UNDO },
|
||||||
|
{ "pmous", KEYC_MOUSE },
|
||||||
|
};
|
||||||
|
#define NTTYKEYS (sizeof tty_keys / sizeof tty_keys[0])
|
||||||
|
|
||||||
|
RB_GENERATE(tty_keys, tty_key, entry, tty_keys_cmp);
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_keys_cmp(struct tty_key *k1, struct tty_key *k2)
|
||||||
|
{
|
||||||
|
return (strcmp(k1->string, k2->string));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_keys_init(struct tty *tty)
|
||||||
|
{
|
||||||
|
struct tty_key *tk;
|
||||||
|
u_int i;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
RB_INIT(&tty->ktree);
|
||||||
|
|
||||||
|
tty->ksize = 0;
|
||||||
|
for (i = 0; i < NTTYKEYS; i++) {
|
||||||
|
s = tigetstr(tty_keys[i].name);
|
||||||
|
if (s == (char *) -1 || s == (char *) 0)
|
||||||
|
continue;
|
||||||
|
if (s[0] != '\e' || s[1] == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tk = xmalloc(sizeof *tk);
|
||||||
|
tk->string = xstrdup(s + 1);
|
||||||
|
tk->code = tty_keys[i].code;
|
||||||
|
|
||||||
|
if (strlen(tk->string) > tty->ksize)
|
||||||
|
tty->ksize = strlen(tk->string);
|
||||||
|
RB_INSERT(tty_keys, &tty->ktree, tk);
|
||||||
|
|
||||||
|
log_debug("found key %d: size now %zu", tk->code, tty->ksize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_keys_free(struct tty *tty)
|
||||||
|
{
|
||||||
|
struct tty_key *tk, *tl;
|
||||||
|
|
||||||
|
for (tk = RB_MIN(tty_keys, &tty->ktree); tk != NULL; tk = tl) {
|
||||||
|
tl = RB_NEXT(tty_keys, &tty->ktree, tk);
|
||||||
|
RB_REMOVE(tty_keys, &tty->ktree, tk);
|
||||||
|
xfree(tk->string);
|
||||||
|
xfree(tk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_keys_next(struct tty *tty, int *code)
|
||||||
|
{
|
||||||
|
struct tty_key *tk, tl;
|
||||||
|
size_t size;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if (BUFFER_USED(tty->in) == 0)
|
||||||
|
return (1);
|
||||||
|
log_debug("keys have %zu bytes", BUFFER_USED(tty->in));
|
||||||
|
|
||||||
|
if (*BUFFER_OUT(tty->in) != '\e') {
|
||||||
|
*code = buffer_read8(tty->in);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
tk = NULL;
|
||||||
|
s = xmalloc(tty->ksize + 1);
|
||||||
|
for (size = tty->ksize; size > 0; size--) {
|
||||||
|
if (size >= BUFFER_USED(tty->in))
|
||||||
|
continue;
|
||||||
|
memcpy(s, BUFFER_OUT(tty->in) + 1, size);
|
||||||
|
s[size] = '\0';
|
||||||
|
|
||||||
|
tl.string = s;
|
||||||
|
tk = RB_FIND(tty_keys, &tty->ktree, &tl);
|
||||||
|
if (tk != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xfree(s);
|
||||||
|
if (tk == NULL) {
|
||||||
|
/*
|
||||||
|
* XXX Pass through unchanged.
|
||||||
|
*/
|
||||||
|
*code = '\e';
|
||||||
|
buffer_remove(tty->in, 1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
buffer_remove(tty->in, size + 1);
|
||||||
|
|
||||||
|
*code = tk->code;
|
||||||
|
return (0);
|
||||||
|
}
|
107
tty-write.c
Normal file
107
tty-write.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/* $Id: tty-write.c,v 1.1 2007-11-27 19:23:34 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "tmux.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_write_client(void *ptr, int cmd, ...)
|
||||||
|
{
|
||||||
|
struct client *c = ptr;
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, cmd);
|
||||||
|
tty_vwrite_client(c, cmd, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_vwrite_client(void *ptr, int cmd, va_list ap)
|
||||||
|
{
|
||||||
|
struct client *c = ptr;
|
||||||
|
|
||||||
|
tty_vwrite(&c->tty, cmd, ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_write_window(void *ptr, int cmd, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, cmd);
|
||||||
|
tty_vwrite_window(ptr, cmd, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_vwrite_window(void *ptr, int cmd, va_list ap)
|
||||||
|
{
|
||||||
|
struct window *w = ptr;
|
||||||
|
struct client *c;
|
||||||
|
va_list aq;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
if (w->screen.mode & MODE_HIDDEN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
va_copy(aq, ap);
|
||||||
|
tty_vwrite(&c->tty, cmd, aq);
|
||||||
|
va_end(aq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_write_session(void *ptr, int cmd, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, cmd);
|
||||||
|
tty_vwrite_session(ptr, cmd, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_vwrite_session(void *ptr, int cmd, va_list ap)
|
||||||
|
{
|
||||||
|
struct session *s = ptr;
|
||||||
|
struct client *c;
|
||||||
|
va_list aq;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
if (s->flags & SESSION_UNATTACHED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||||
|
c = ARRAY_ITEM(&clients, i);
|
||||||
|
if (c == NULL || c->session != s)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
va_copy(aq, ap);
|
||||||
|
tty_vwrite(&c->tty, cmd, aq);
|
||||||
|
va_end(aq);
|
||||||
|
}
|
||||||
|
}
|
401
tty.c
Normal file
401
tty.c
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
/* $Id: tty.c,v 1.1 2007-11-27 19:23:34 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#define TTYDEFCHARS
|
||||||
|
/* glibc requires unistd.h before termios.h for TTYDEFCHARS. */
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#include "tmux.h"
|
||||||
|
|
||||||
|
void tty_fill_acs(struct tty *);
|
||||||
|
u_char tty_get_acs(struct tty *, u_char);
|
||||||
|
|
||||||
|
void tty_raw(struct tty *, const char *);
|
||||||
|
void tty_puts(struct tty *, const char *);
|
||||||
|
void tty_putc(struct tty *, char);
|
||||||
|
|
||||||
|
void tty_attributes(struct tty *, u_char, u_char);
|
||||||
|
char tty_translate(char);
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_init(struct tty *tty, char *path, char *term)
|
||||||
|
{
|
||||||
|
tty->path = xstrdup(path);
|
||||||
|
tty->term = xstrdup(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_open(struct tty *tty, char **cause)
|
||||||
|
{
|
||||||
|
struct termios tio;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
tty->fd = open(tty->path, O_RDWR|O_NONBLOCK);
|
||||||
|
if (tty->fd == -1) {
|
||||||
|
xasprintf(cause, "%s: %s", tty->path, strerror(errno));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tty->term == NULL)
|
||||||
|
tty->term = xstrdup("unknown");
|
||||||
|
if (setupterm(tty->term, tty->fd, &error) != OK) {
|
||||||
|
switch (error) {
|
||||||
|
case 0:
|
||||||
|
xasprintf(cause, "can't use hardcopy terminal");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
xasprintf(cause, "missing or unsuitable terminal");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
xasprintf(cause, "can't find terminfo database");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
xasprintf(cause, "unknown error");
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
tty->termp = cur_term;
|
||||||
|
|
||||||
|
tty->in = buffer_create(BUFSIZ);
|
||||||
|
tty->out = buffer_create(BUFSIZ);
|
||||||
|
|
||||||
|
tty->attr = SCREEN_DEFATTR;
|
||||||
|
tty->colr = SCREEN_DEFCOLR;
|
||||||
|
|
||||||
|
tty_keys_init(tty);
|
||||||
|
|
||||||
|
tty_fill_acs(tty);
|
||||||
|
|
||||||
|
if (tcgetattr(tty->fd, &tty->tio) != 0)
|
||||||
|
fatal("tcgetattr failed");
|
||||||
|
memset(&tio, 0, sizeof tio);
|
||||||
|
tio.c_iflag = TTYDEF_IFLAG & ~(IXON|IXOFF|ICRNL|INLCR);
|
||||||
|
tio.c_oflag = TTYDEF_OFLAG & ~(OPOST|ONLCR|OCRNL|ONLRET);
|
||||||
|
tio.c_lflag =
|
||||||
|
TTYDEF_LFLAG & ~(IEXTEN|ICANON|ECHO|ECHOE|ECHOKE|ECHOCTL|ISIG);
|
||||||
|
tio.c_cflag = TTYDEF_CFLAG;
|
||||||
|
memcpy(&tio.c_cc, ttydefchars, sizeof tio.c_cc);
|
||||||
|
cfsetspeed(&tio, TTYDEF_SPEED);
|
||||||
|
if (tcsetattr(tty->fd, TCSANOW, &tio) != 0)
|
||||||
|
fatal("tcsetattr failed");
|
||||||
|
|
||||||
|
if (enter_ca_mode != NULL)
|
||||||
|
tty_puts(tty, enter_ca_mode);
|
||||||
|
if (keypad_xmit != NULL)
|
||||||
|
tty_puts(tty, keypad_xmit);
|
||||||
|
if (ena_acs != NULL)
|
||||||
|
tty_puts(tty, ena_acs);
|
||||||
|
tty_puts(tty, clear_screen);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_close(struct tty *tty)
|
||||||
|
{
|
||||||
|
struct winsize ws;
|
||||||
|
|
||||||
|
if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1)
|
||||||
|
fatal("ioctl(TIOCGWINSZ)");
|
||||||
|
|
||||||
|
if (keypad_local != NULL)
|
||||||
|
tty_raw(tty, keypad_local);
|
||||||
|
if (exit_ca_mode != NULL)
|
||||||
|
tty_raw(tty, exit_ca_mode);
|
||||||
|
tty_raw(tty, clear_screen);
|
||||||
|
if (cursor_normal != NULL)
|
||||||
|
tty_raw(tty, cursor_normal);
|
||||||
|
if (exit_attribute_mode != NULL)
|
||||||
|
tty_raw(tty, exit_attribute_mode);
|
||||||
|
if (change_scroll_region != NULL)
|
||||||
|
tty_raw(tty, tparm(change_scroll_region, 0, ws.ws_row - 1));
|
||||||
|
|
||||||
|
if (tcsetattr(tty->fd, TCSANOW, &tty->tio) != 0)
|
||||||
|
fatal("tcsetattr failed");
|
||||||
|
del_curterm(tty->termp);
|
||||||
|
|
||||||
|
tty_keys_free(tty);
|
||||||
|
|
||||||
|
close(tty->fd);
|
||||||
|
buffer_destroy(tty->in);
|
||||||
|
buffer_destroy(tty->out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_free(struct tty *tty)
|
||||||
|
{
|
||||||
|
if (tty->fd != -1)
|
||||||
|
tty_close(tty);
|
||||||
|
|
||||||
|
if (tty->path != NULL)
|
||||||
|
xfree(tty->path);
|
||||||
|
if (tty->term != NULL)
|
||||||
|
xfree(tty->term);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_fill_acs(struct tty *tty)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
memset(tty->acs, 0, sizeof tty->acs);
|
||||||
|
if (acs_chars == NULL || (strlen(acs_chars) % 2) != 0)
|
||||||
|
return;
|
||||||
|
for (ptr = acs_chars; *ptr != '\0'; ptr += 2)
|
||||||
|
tty->acs[(u_char) ptr[0]] = ptr[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
u_char
|
||||||
|
tty_get_acs(struct tty *tty, u_char ch)
|
||||||
|
{
|
||||||
|
if (tty->acs[ch] != '\0')
|
||||||
|
return (tty->acs[ch]);
|
||||||
|
return (ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_raw(struct tty *tty, const char *s)
|
||||||
|
{
|
||||||
|
write(tty->fd, s, strlen(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_puts(struct tty *tty, const char *s)
|
||||||
|
{
|
||||||
|
buffer_write(tty->out, s, strlen(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_putc(struct tty *tty, char ch)
|
||||||
|
{
|
||||||
|
if (tty->attr & ATTR_DRAWING)
|
||||||
|
ch = tty_get_acs(tty, ch);
|
||||||
|
buffer_write8(tty->out, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_vwrite(struct tty *tty, int cmd, va_list ap)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
u_int ua, ub;
|
||||||
|
|
||||||
|
set_curterm(tty->termp);
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
|
case TTY_CHARACTER:
|
||||||
|
ch = va_arg(ap, int);
|
||||||
|
switch (ch) {
|
||||||
|
case '\n': /* LF */
|
||||||
|
tty_puts(tty, cursor_down);
|
||||||
|
break;
|
||||||
|
case '\r': /* CR */
|
||||||
|
tty_puts(tty, carriage_return);
|
||||||
|
break;
|
||||||
|
case '\007': /* BEL */
|
||||||
|
if (bell != NULL)
|
||||||
|
tty_puts(tty, bell);
|
||||||
|
break;
|
||||||
|
case '\010': /* BS */
|
||||||
|
tty_puts(tty, cursor_left);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tty_putc(tty, ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TTY_CURSORUP:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(parm_up_cursor, ua));
|
||||||
|
break;
|
||||||
|
case TTY_CURSORDOWN:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(parm_down_cursor, ua));
|
||||||
|
break;
|
||||||
|
case TTY_CURSORRIGHT:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(parm_right_cursor, ua));
|
||||||
|
break;
|
||||||
|
case TTY_CURSORLEFT:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(parm_left_cursor, ua));
|
||||||
|
break;
|
||||||
|
case TTY_CURSORMOVE:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
ub = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(cursor_address, ua, ub));
|
||||||
|
break;
|
||||||
|
case TTY_CLEARENDOFLINE:
|
||||||
|
tty_puts(tty, clr_eol);
|
||||||
|
break;
|
||||||
|
case TTY_CLEARSTARTOFLINE:
|
||||||
|
tty_puts(tty, clr_bol);
|
||||||
|
break;
|
||||||
|
case TTY_CLEARLINE:
|
||||||
|
tty_puts(tty, clr_eol); /* XXX */
|
||||||
|
break;
|
||||||
|
case TTY_INSERTLINE:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(parm_insert_line, ua));
|
||||||
|
break;
|
||||||
|
case TTY_DELETELINE:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(parm_delete_line, ua));
|
||||||
|
break;
|
||||||
|
case TTY_INSERTCHARACTER:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(parm_ich, ua));
|
||||||
|
break;
|
||||||
|
case TTY_DELETECHARACTER:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(parm_dch, ua));
|
||||||
|
break;
|
||||||
|
case TTY_CURSORON:
|
||||||
|
if (cursor_normal != NULL)
|
||||||
|
tty_puts(tty, cursor_normal);
|
||||||
|
break;
|
||||||
|
case TTY_CURSOROFF:
|
||||||
|
if (cursor_invisible != NULL)
|
||||||
|
tty_puts(tty, cursor_invisible);
|
||||||
|
break;
|
||||||
|
case TTY_REVERSEINDEX:
|
||||||
|
tty_puts(tty, scroll_reverse);
|
||||||
|
break;
|
||||||
|
case TTY_SCROLLREGION:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
ub = va_arg(ap, u_int);
|
||||||
|
tty_puts(tty, tparm(change_scroll_region, ua, ub));
|
||||||
|
break;
|
||||||
|
case TTY_INSERTON:
|
||||||
|
if (enter_insert_mode != NULL)
|
||||||
|
tty_puts(tty, enter_insert_mode);
|
||||||
|
break;
|
||||||
|
case TTY_INSERTOFF:
|
||||||
|
if (exit_insert_mode != NULL)
|
||||||
|
tty_puts(tty, exit_insert_mode);
|
||||||
|
break;
|
||||||
|
#if 0
|
||||||
|
case TTY_KCURSOROFF:
|
||||||
|
t = tigetstr("CE");
|
||||||
|
if (t != (char *) 0 && t != (char *) -1)
|
||||||
|
tty_puts(tty, t);
|
||||||
|
break;
|
||||||
|
case TTY_KCURSORON:
|
||||||
|
t = tigetstr("CS");
|
||||||
|
if (t != (char *) 0 && t != (char *) -1)
|
||||||
|
tty_puts(tty, t);
|
||||||
|
break;
|
||||||
|
case TTY_KKEYPADOFF:
|
||||||
|
if (keypad_local != NULL)
|
||||||
|
tty_puts(tty, keypad_local);
|
||||||
|
break;
|
||||||
|
case TTY_KKEYPADON:
|
||||||
|
if (keypad_xmit != NULL)
|
||||||
|
tty_puts(tty, keypad_xmit);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case TTY_TITLE:
|
||||||
|
break;
|
||||||
|
case TTY_ATTRIBUTES:
|
||||||
|
ua = va_arg(ap, u_int);
|
||||||
|
ub = va_arg(ap, u_int);
|
||||||
|
tty_attributes(tty, ua, ub);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_attributes(struct tty *tty, u_char attr, u_char colr)
|
||||||
|
{
|
||||||
|
u_char fg, bg;
|
||||||
|
|
||||||
|
if (attr == tty->attr && colr == tty->colr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If any bits are being cleared, reset everything. */
|
||||||
|
if (tty->attr & ~attr) {
|
||||||
|
if ((tty->attr & ATTR_DRAWING) &&
|
||||||
|
exit_alt_charset_mode != NULL)
|
||||||
|
tty_puts(tty, exit_alt_charset_mode);
|
||||||
|
tty_puts(tty, exit_attribute_mode);
|
||||||
|
tty->colr = 0x88;
|
||||||
|
tty->attr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filter out bits already set. */
|
||||||
|
attr &= ~tty->attr;
|
||||||
|
tty->attr |= attr;
|
||||||
|
|
||||||
|
if ((attr & ATTR_BRIGHT) && enter_bold_mode != NULL)
|
||||||
|
tty_puts(tty, enter_bold_mode);
|
||||||
|
if ((attr & ATTR_DIM) && enter_dim_mode != NULL)
|
||||||
|
tty_puts(tty, enter_dim_mode);
|
||||||
|
if ((attr & ATTR_ITALICS) && enter_standout_mode != NULL)
|
||||||
|
tty_puts(tty, enter_standout_mode);
|
||||||
|
if ((attr & ATTR_UNDERSCORE) && enter_underline_mode != NULL)
|
||||||
|
tty_puts(tty, enter_underline_mode);
|
||||||
|
if ((attr & ATTR_BLINK) && enter_blink_mode != NULL)
|
||||||
|
tty_puts(tty, enter_blink_mode);
|
||||||
|
if ((attr & ATTR_REVERSE) && enter_reverse_mode != NULL)
|
||||||
|
tty_puts(tty, enter_reverse_mode);
|
||||||
|
if ((attr & ATTR_HIDDEN) && enter_secure_mode != NULL)
|
||||||
|
tty_puts(tty, enter_secure_mode);
|
||||||
|
if ((attr & ATTR_DRAWING) && enter_alt_charset_mode != NULL)
|
||||||
|
tty_puts(tty, enter_alt_charset_mode);
|
||||||
|
|
||||||
|
fg = (colr >> 4) & 0xf;
|
||||||
|
if (fg != ((tty->colr >> 4) & 0xf)) {
|
||||||
|
if (tigetflag("AX") == TRUE) {
|
||||||
|
if (fg == 7)
|
||||||
|
fg = 8;
|
||||||
|
} else {
|
||||||
|
if (fg == 8)
|
||||||
|
fg = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fg == 8)
|
||||||
|
tty_puts(tty, "\e[39m");
|
||||||
|
else if (set_a_foreground != NULL)
|
||||||
|
tty_puts(tty, tparm(set_a_foreground, fg));
|
||||||
|
}
|
||||||
|
|
||||||
|
bg = colr & 0xf;
|
||||||
|
if (bg != (tty->colr & 0xf)) {
|
||||||
|
if (tigetflag("AX") == TRUE) {
|
||||||
|
if (bg == 0)
|
||||||
|
bg = 8;
|
||||||
|
} else {
|
||||||
|
if (bg == 8)
|
||||||
|
bg = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bg == 8)
|
||||||
|
tty_puts(tty, "\e[49m");
|
||||||
|
else if (set_a_background != NULL)
|
||||||
|
tty_puts(tty, tparm(set_a_background, bg));
|
||||||
|
}
|
||||||
|
|
||||||
|
tty->colr = colr;
|
||||||
|
}
|
221
window-copy.c
221
window-copy.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: window-copy.c,v 1.9 2007-11-26 20:57:54 nicm Exp $ */
|
/* $Id: window-copy.c,v 1.10 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -24,7 +24,8 @@
|
|||||||
|
|
||||||
void window_copy_init(struct window *);
|
void window_copy_init(struct window *);
|
||||||
void window_copy_resize(struct window *, u_int, u_int);
|
void window_copy_resize(struct window *, u_int, u_int);
|
||||||
void window_copy_draw(struct window *, struct buffer *, u_int, u_int);
|
void window_copy_draw(
|
||||||
|
struct window *, struct screen_draw_ctx *, u_int, u_int);
|
||||||
void window_copy_key(struct window *, int);
|
void window_copy_key(struct window *, int);
|
||||||
|
|
||||||
void window_copy_draw_position(struct window *, struct screen_draw_ctx *);
|
void window_copy_draw_position(struct window *, struct screen_draw_ctx *);
|
||||||
@ -103,37 +104,32 @@ window_copy_draw_position(struct window *w, struct screen_draw_ctx *ctx)
|
|||||||
|
|
||||||
screen_draw_cells(ctx, 0, 0, screen_size_x(ctx->s) - len);
|
screen_draw_cells(ctx, 0, 0, screen_size_x(ctx->s) - len);
|
||||||
|
|
||||||
screen_draw_move(ctx, screen_size_x(ctx->s) - len, 0);
|
screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
|
||||||
screen_draw_set_attributes(ctx, 0, status_colour);
|
screen_draw_set_attributes(ctx, 0, status_colour);
|
||||||
buffer_write(ctx->b, ptr, len);
|
screen_draw_write_string(ctx, "%s", ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_copy_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
|
window_copy_draw(
|
||||||
|
struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
|
||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = w->modedata;
|
struct window_copy_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
struct screen *s = &w->screen;
|
||||||
struct screen_draw_ctx ctx;
|
|
||||||
|
|
||||||
if (s->hsize != data->size) {
|
if (s->hsize != data->size) {
|
||||||
data->oy += s->hsize - data->size;
|
data->oy += s->hsize - data->size;
|
||||||
data->size = s->hsize;
|
data->size = s->hsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, b, data->ox, data->oy);
|
|
||||||
screen_draw_set_selection(&ctx, data->selflag, data->selx, data->sely,
|
|
||||||
data->cx + data->ox, data->size + data->cy - data->oy);
|
|
||||||
if (py != 0)
|
if (py != 0)
|
||||||
screen_draw_lines(&ctx, py, ny);
|
screen_draw_lines(ctx, py, ny);
|
||||||
else if (ny > 1)
|
else {
|
||||||
screen_draw_lines(&ctx, py + 1, ny - 1);
|
if (ny > 1)
|
||||||
|
screen_draw_lines(ctx, py + 1, ny - 1);
|
||||||
|
window_copy_draw_position(w, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (py == 0)
|
window_copy_move_cursor(w);
|
||||||
window_copy_draw_position(w, &ctx);
|
|
||||||
|
|
||||||
screen_draw_stop(&ctx);
|
|
||||||
|
|
||||||
input_store_two(b, CODE_CURSORMOVE, data->cy + 1, data->cx + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -205,7 +201,7 @@ window_copy_key(struct window *w, int key)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data->oy != oy) {
|
if (data->oy != oy) {
|
||||||
server_redraw_window_all(w);
|
server_redraw_window(w);
|
||||||
window_copy_move_cursor(w);
|
window_copy_move_cursor(w);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -217,7 +213,7 @@ done:
|
|||||||
w->screen.mode &= ~MODE_BACKGROUND;
|
w->screen.mode &= ~MODE_BACKGROUND;
|
||||||
|
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
server_redraw_window_all(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -322,30 +318,8 @@ void
|
|||||||
window_copy_move_cursor(struct window *w)
|
window_copy_move_cursor(struct window *w)
|
||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = w->modedata;
|
struct window_copy_mode_data *data = w->modedata;
|
||||||
struct client *c;
|
|
||||||
u_int i;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
tty_write_window(w, TTY_CURSORMOVE, data->cy, data->cx);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
|
||||||
if (c == NULL || c->session == NULL)
|
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
input_store_two(
|
|
||||||
c->out, CODE_CURSORMOVE, data->cy + 1, data->cx + 1);
|
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -467,44 +441,20 @@ window_copy_cursor_down(struct window *w)
|
|||||||
void
|
void
|
||||||
window_copy_draw_lines(struct window *w, u_int py, u_int ny)
|
window_copy_draw_lines(struct window *w, u_int py, u_int ny)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct window_copy_mode_data *data = w->modedata;
|
||||||
struct buffer *b;
|
struct screen_draw_ctx ctx;
|
||||||
u_int i;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
window_copy_draw(w, &ctx, py, ny);
|
||||||
if (c == NULL || c->session == NULL)
|
screen_draw_stop(&ctx);
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
b = c->out;
|
|
||||||
|
|
||||||
buffer_ensure(b, sizeof hdr);
|
|
||||||
buffer_add(b, sizeof hdr);
|
|
||||||
size = BUFFER_USED(b);
|
|
||||||
|
|
||||||
window_copy_draw(w, b, py, ny);
|
|
||||||
|
|
||||||
size = BUFFER_USED(b) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(b) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_copy_scroll_left(struct window *w, u_int nx)
|
window_copy_scroll_left(struct window *w, u_int nx)
|
||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = w->modedata;
|
struct window_copy_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
u_int i;
|
||||||
struct buffer *b;
|
|
||||||
u_int i, j;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->ox > SHRT_MAX - nx)
|
if (data->ox > SHRT_MAX - nx)
|
||||||
nx = SHRT_MAX - data->ox;
|
nx = SHRT_MAX - data->ox;
|
||||||
@ -512,49 +462,26 @@ window_copy_scroll_left(struct window *w, u_int nx)
|
|||||||
return;
|
return;
|
||||||
data->ox += nx;
|
data->ox += nx;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
|
||||||
if (c == NULL || c->session == NULL)
|
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
b = c->out;
|
|
||||||
|
|
||||||
buffer_ensure(b, sizeof hdr);
|
|
||||||
buffer_add(b, sizeof hdr);
|
|
||||||
size = BUFFER_USED(b);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, b, data->ox, data->oy);
|
|
||||||
screen_draw_set_selection(&ctx,
|
screen_draw_set_selection(&ctx,
|
||||||
data->selflag, data->selx, data->sely,
|
data->selflag, data->selx, data->sely,
|
||||||
data->cx + data->ox, data->size + data->cy - data->oy);
|
data->cx + data->ox, data->size + data->cy - data->oy);
|
||||||
for (j = 1; j < screen_size_y(s); j++) {
|
for (i = 1; i < screen_size_y(&w->screen); i++) {
|
||||||
screen_draw_move(&ctx, 0, j);
|
screen_draw_move_cursor(&ctx, 0, i);
|
||||||
input_store_one(b, CODE_DELETECHARACTER, nx);
|
screen_draw_delete_characters(&ctx, nx);
|
||||||
}
|
}
|
||||||
for (j = 0; j < nx; j++)
|
for (i = 0; i < nx; i++)
|
||||||
screen_draw_column(&ctx, screen_last_x(s) - j);
|
screen_draw_column(&ctx, screen_last_x(&w->screen) - i);
|
||||||
window_copy_draw_position(w, &ctx);
|
window_copy_draw_position(w, &ctx);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(b) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(b) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_copy_scroll_right(struct window *w, u_int nx)
|
window_copy_scroll_right(struct window *w, u_int nx)
|
||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = w->modedata;
|
struct window_copy_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
u_int i;
|
||||||
struct buffer *b;
|
|
||||||
u_int i, j;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->ox < nx)
|
if (data->ox < nx)
|
||||||
nx = data->ox;
|
nx = data->ox;
|
||||||
@ -562,48 +489,26 @@ window_copy_scroll_right(struct window *w, u_int nx)
|
|||||||
return;
|
return;
|
||||||
data->ox -= nx;
|
data->ox -= nx;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
|
||||||
if (c == NULL || c->session == NULL)
|
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
b = c->out;
|
|
||||||
|
|
||||||
buffer_ensure(b, sizeof hdr);
|
|
||||||
buffer_add(b, sizeof hdr);
|
|
||||||
size = BUFFER_USED(b);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, b, data->ox, data->oy);
|
|
||||||
screen_draw_set_selection(&ctx,
|
screen_draw_set_selection(&ctx,
|
||||||
data->selflag, data->selx, data->sely,
|
data->selflag, data->selx, data->sely,
|
||||||
data->cx + data->ox, data->size + data->cy - data->oy);
|
data->cx + data->ox, data->size + data->cy - data->oy);
|
||||||
for (j = 1; j < screen_size_y(s); j++) {
|
for (i = 1; i < screen_size_y(&w->screen); i++) {
|
||||||
screen_draw_move(&ctx, 0, j);
|
screen_draw_move_cursor(&ctx, 0, i);
|
||||||
input_store_one(b, CODE_INSERTCHARACTER, nx);
|
screen_draw_insert_characters(&ctx, nx);
|
||||||
}
|
}
|
||||||
for (j = 0; j < nx; j++)
|
for (i = 0; i < nx; i++)
|
||||||
screen_draw_column(&ctx, j);
|
screen_draw_column(&ctx, i);
|
||||||
window_copy_draw_position(w, &ctx);
|
window_copy_draw_position(w, &ctx);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(b) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(b) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_copy_scroll_up(struct window *w, u_int ny)
|
window_copy_scroll_up(struct window *w, u_int ny)
|
||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = w->modedata;
|
struct window_copy_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
|
||||||
u_int i;
|
u_int i;
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->oy < ny)
|
if (data->oy < ny)
|
||||||
ny = data->oy;
|
ny = data->oy;
|
||||||
@ -611,47 +516,26 @@ window_copy_scroll_up(struct window *w, u_int ny)
|
|||||||
return;
|
return;
|
||||||
data->oy -= ny;
|
data->oy -= ny;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
|
||||||
if (c == NULL || c->session == NULL)
|
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
|
|
||||||
screen_draw_set_selection(&ctx,
|
screen_draw_set_selection(&ctx,
|
||||||
data->selflag, data->selx, data->sely,
|
data->selflag, data->selx, data->sely,
|
||||||
data->cx + data->ox, data->size + data->cy - data->oy);
|
data->cx + data->ox, data->size + data->cy - data->oy);
|
||||||
screen_draw_move(&ctx, 0, 0);
|
screen_draw_move_cursor(&ctx, 0, 0);
|
||||||
input_store_one(c->out, CODE_DELETELINE, ny);
|
screen_draw_delete_lines(&ctx, ny);
|
||||||
for (i = 0; i < ny; i++)
|
for (i = 0; i < ny; i++)
|
||||||
screen_draw_line(&ctx, screen_last_y(s) - i);
|
screen_draw_line(&ctx, screen_last_y(&w->screen) - i);
|
||||||
if (data->selflag)
|
if (data->selflag)
|
||||||
screen_draw_line(&ctx, screen_last_y(s) - ny);
|
screen_draw_line(&ctx, screen_last_y(&w->screen) - ny);
|
||||||
window_copy_draw_position(w, &ctx);
|
window_copy_draw_position(w, &ctx);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_copy_scroll_down(struct window *w, u_int ny)
|
window_copy_scroll_down(struct window *w, u_int ny)
|
||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = w->modedata;
|
struct window_copy_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
|
||||||
u_int i;
|
u_int i;
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (ny > data->size)
|
if (ny > data->size)
|
||||||
return;
|
return;
|
||||||
@ -662,31 +546,14 @@ window_copy_scroll_down(struct window *w, u_int ny)
|
|||||||
return;
|
return;
|
||||||
data->oy += ny;
|
data->oy += ny;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
|
||||||
if (c == NULL || c->session == NULL)
|
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
|
|
||||||
screen_draw_set_selection(&ctx,
|
screen_draw_set_selection(&ctx,
|
||||||
data->selflag, data->selx, data->sely,
|
data->selflag, data->selx, data->sely,
|
||||||
data->cx + data->ox, data->size + data->cy - data->oy);
|
data->cx + data->ox, data->size + data->cy - data->oy);
|
||||||
screen_draw_move(&ctx, 0, 0);
|
screen_draw_move_cursor(&ctx, 0, 0);
|
||||||
input_store_one(c->out, CODE_INSERTLINE, ny);
|
screen_draw_insert_lines(&ctx, ny);
|
||||||
for (i = 1; i < ny + 1; i++)
|
for (i = 1; i < ny + 1; i++)
|
||||||
screen_draw_line(&ctx, i);
|
screen_draw_line(&ctx, i);
|
||||||
window_copy_draw_position(w, &ctx);
|
window_copy_draw_position(w, &ctx);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
122
window-more.c
122
window-more.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: window-more.c,v 1.4 2007-11-22 18:09:43 nicm Exp $ */
|
/* $Id: window-more.c,v 1.5 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -24,7 +24,8 @@
|
|||||||
|
|
||||||
void window_more_init(struct window *);
|
void window_more_init(struct window *);
|
||||||
void window_more_resize(struct window *, u_int, u_int);
|
void window_more_resize(struct window *, u_int, u_int);
|
||||||
void window_more_draw(struct window *, struct buffer *, u_int, u_int);
|
void window_more_draw(
|
||||||
|
struct window *, struct screen_draw_ctx *, u_int, u_int);
|
||||||
void window_more_key(struct window *, int);
|
void window_more_key(struct window *, int);
|
||||||
|
|
||||||
void window_more_draw_position(struct window *, struct screen_draw_ctx *);
|
void window_more_draw_position(struct window *, struct screen_draw_ctx *);
|
||||||
@ -90,8 +91,6 @@ window_more_draw_position(struct window *w, struct screen_draw_ctx *ctx)
|
|||||||
char *ptr, buf[32];
|
char *ptr, buf[32];
|
||||||
size_t len;
|
size_t len;
|
||||||
char *line;
|
char *line;
|
||||||
size_t n;
|
|
||||||
|
|
||||||
|
|
||||||
len = xsnprintf(
|
len = xsnprintf(
|
||||||
buf, sizeof buf, "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
|
buf, sizeof buf, "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
|
||||||
@ -102,68 +101,50 @@ window_more_draw_position(struct window *w, struct screen_draw_ctx *ctx)
|
|||||||
len -= len - screen_size_x(ctx->s);
|
len -= len - screen_size_x(ctx->s);
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_draw_move(ctx, 0, 0);
|
screen_draw_move_cursor(ctx, 0, 0);
|
||||||
|
|
||||||
if (data->top < ARRAY_LENGTH(&data->list)) {
|
if (data->top < ARRAY_LENGTH(&data->list)) {
|
||||||
line = ARRAY_ITEM(&data->list, data->top);
|
line = xstrdup(ARRAY_ITEM(&data->list, data->top));
|
||||||
n = strlen(line);
|
if (strlen(line) > screen_size_x(ctx->s) - len)
|
||||||
if (n > screen_size_x(ctx->s) - len)
|
line[screen_size_x(ctx->s) - len] = '\0';
|
||||||
n = screen_size_x(ctx->s) - len;
|
screen_draw_write_string(ctx, "%s", line);
|
||||||
buffer_write(ctx->b, line, n);
|
xfree(line);
|
||||||
} else
|
}
|
||||||
n = 0;
|
screen_draw_clear_line_to(ctx, screen_size_x(ctx->s) - len - 1);
|
||||||
for (; n < screen_size_x(ctx->s) - len; n++)
|
|
||||||
input_store8(ctx->b, SCREEN_DEFDATA);
|
|
||||||
|
|
||||||
screen_draw_move(ctx, screen_size_x(ctx->s) - len, 0);
|
screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
|
||||||
screen_draw_set_attributes(ctx, 0, status_colour);
|
screen_draw_set_attributes(ctx, 0, status_colour);
|
||||||
buffer_write(ctx->b, buf, len);
|
screen_draw_write_string(ctx, "%s", ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_more_draw_line(struct window *w, struct screen_draw_ctx *ctx, u_int py)
|
window_more_draw_line(struct window *w, struct screen_draw_ctx *ctx, u_int py)
|
||||||
{
|
{
|
||||||
struct window_more_mode_data *data = w->modedata;
|
struct window_more_mode_data *data = w->modedata;
|
||||||
char *line;
|
|
||||||
size_t n;
|
|
||||||
u_int p;
|
u_int p;
|
||||||
|
|
||||||
screen_draw_move(ctx, 0, py);
|
screen_draw_move_cursor(ctx, 0, py);
|
||||||
screen_draw_set_attributes(ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
|
screen_draw_set_attributes(ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
|
||||||
|
|
||||||
p = data->top + py;
|
p = data->top + py;
|
||||||
if (p >= ARRAY_LENGTH(&data->list)) {
|
if (p < ARRAY_LENGTH(&data->list))
|
||||||
input_store_zero(ctx->b, CODE_CLEARLINE);
|
screen_draw_write_string(ctx, "%s", ARRAY_ITEM(&data->list, p));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
line = ARRAY_ITEM(&data->list, p);
|
screen_draw_clear_line_to(ctx, screen_last_x(ctx->s));
|
||||||
n = strlen(line);
|
|
||||||
if (n > screen_size_x(ctx->s))
|
|
||||||
n = screen_size_x(ctx->s);
|
|
||||||
buffer_write(ctx->b, line, n);
|
|
||||||
for (; n < screen_size_x(ctx->s); n++)
|
|
||||||
input_store8(ctx->b, SCREEN_DEFDATA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_more_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
|
window_more_draw(
|
||||||
|
struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
|
||||||
{
|
{
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, b, 0, 0);
|
|
||||||
|
|
||||||
for (i = py; i < py + ny; i++) {
|
for (i = py; i < py + ny; i++) {
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
continue;
|
window_more_draw_position(w, ctx);
|
||||||
window_more_draw_line(w, &ctx, i);
|
else
|
||||||
|
window_more_draw_line(w, ctx, i);
|
||||||
}
|
}
|
||||||
if (py == 0)
|
|
||||||
window_more_draw_position(w, &ctx);
|
|
||||||
|
|
||||||
screen_draw_stop(&ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -189,7 +170,7 @@ window_more_key(struct window *w, int key)
|
|||||||
w->screen.mode &= ~MODE_BACKGROUND;
|
w->screen.mode &= ~MODE_BACKGROUND;
|
||||||
|
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
server_redraw_window_all(w);
|
server_redraw_window(w);
|
||||||
return;
|
return;
|
||||||
case 'k':
|
case 'k':
|
||||||
case 'K':
|
case 'K':
|
||||||
@ -217,47 +198,25 @@ window_more_key(struct window *w, int key)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (top != data->top)
|
if (top != data->top)
|
||||||
server_redraw_window_all(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_more_up_1(struct window *w)
|
window_more_up_1(struct window *w)
|
||||||
{
|
{
|
||||||
struct window_more_mode_data *data = w->modedata;
|
struct window_more_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
|
||||||
u_int i;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->top == 0)
|
if (data->top == 0)
|
||||||
return;
|
return;
|
||||||
data->top--;
|
data->top--;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, 0, 0);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
screen_draw_move_cursor(&ctx, 0, 0);
|
||||||
if (c == NULL || c->session == NULL)
|
screen_draw_insert_lines(&ctx, 1);
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, c->out, 0, 0);
|
|
||||||
screen_draw_move(&ctx, 0, 0);
|
|
||||||
input_store_one(c->out, CODE_INSERTLINE, 1);
|
|
||||||
window_more_draw_position(w, &ctx);
|
window_more_draw_position(w, &ctx);
|
||||||
window_more_draw_line(w, &ctx, 1);
|
window_more_draw_line(w, &ctx, 1);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -266,36 +225,15 @@ window_more_down_1(struct window *w)
|
|||||||
struct window_more_mode_data *data = w->modedata;
|
struct window_more_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
struct screen *s = &w->screen;
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
|
||||||
u_int i;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->top >= ARRAY_LENGTH(&data->list))
|
if (data->top >= ARRAY_LENGTH(&data->list))
|
||||||
return;
|
return;
|
||||||
data->top++;
|
data->top++;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, 0, 0);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
screen_draw_move_cursor(&ctx, 0, 0);
|
||||||
if (c == NULL || c->session == NULL)
|
screen_draw_delete_lines(&ctx, 1);
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, c->out, 0, 0);
|
|
||||||
screen_draw_move(&ctx, 0, 0);
|
|
||||||
input_store_one(c->out, CODE_DELETELINE, 1);
|
|
||||||
window_more_draw_line(w, &ctx, screen_last_y(s));
|
window_more_draw_line(w, &ctx, screen_last_y(s));
|
||||||
window_more_draw_position(w, &ctx);
|
window_more_draw_position(w, &ctx);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
154
window-scroll.c
154
window-scroll.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: window-scroll.c,v 1.12 2007-11-22 18:09:43 nicm Exp $ */
|
/* $Id: window-scroll.c,v 1.13 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -24,7 +24,8 @@
|
|||||||
|
|
||||||
void window_scroll_init(struct window *);
|
void window_scroll_init(struct window *);
|
||||||
void window_scroll_resize(struct window *, u_int, u_int);
|
void window_scroll_resize(struct window *, u_int, u_int);
|
||||||
void window_scroll_draw(struct window *, struct buffer *, u_int, u_int);
|
void window_scroll_draw(
|
||||||
|
struct window *, struct screen_draw_ctx *, u_int, u_int);
|
||||||
void window_scroll_key(struct window *, int);
|
void window_scroll_key(struct window *, int);
|
||||||
|
|
||||||
void window_scroll_draw_position(struct window *, struct screen_draw_ctx *);
|
void window_scroll_draw_position(struct window *, struct screen_draw_ctx *);
|
||||||
@ -83,33 +84,29 @@ window_scroll_draw_position(struct window *w, struct screen_draw_ctx *ctx)
|
|||||||
|
|
||||||
screen_draw_cells(ctx, 0, 0, screen_size_x(ctx->s) - len);
|
screen_draw_cells(ctx, 0, 0, screen_size_x(ctx->s) - len);
|
||||||
|
|
||||||
screen_draw_move(ctx, screen_size_x(ctx->s) - len, 0);
|
screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
|
||||||
screen_draw_set_attributes(ctx, 0, status_colour);
|
screen_draw_set_attributes(ctx, 0, status_colour);
|
||||||
buffer_write(ctx->b, ptr, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_scroll_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
|
window_scroll_draw(
|
||||||
|
struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
|
||||||
{
|
{
|
||||||
struct window_scroll_mode_data *data = w->modedata;
|
struct window_scroll_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
struct screen *s = &w->screen;
|
||||||
struct screen_draw_ctx ctx;
|
|
||||||
|
|
||||||
if (s->hsize != data->size) {
|
if (s->hsize != data->size) {
|
||||||
data->oy += s->hsize - data->size;
|
data->oy += s->hsize - data->size;
|
||||||
data->size = s->hsize;
|
data->size = s->hsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, b, data->ox, data->oy);
|
|
||||||
if (py != 0)
|
if (py != 0)
|
||||||
screen_draw_lines(&ctx, py, ny);
|
screen_draw_lines(ctx, py, ny);
|
||||||
else if (ny > 1)
|
else {
|
||||||
screen_draw_lines(&ctx, py + 1, ny - 1);
|
if (ny > 1)
|
||||||
|
screen_draw_lines(ctx, py + 1, ny - 1);
|
||||||
if (py == 0)
|
window_scroll_draw_position(w, ctx);
|
||||||
window_scroll_draw_position(w, &ctx);
|
}
|
||||||
|
|
||||||
screen_draw_stop(&ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -133,7 +130,7 @@ window_scroll_key(struct window *w, int key)
|
|||||||
w->screen.mode &= ~MODE_BACKGROUND;
|
w->screen.mode &= ~MODE_BACKGROUND;
|
||||||
|
|
||||||
recalculate_sizes();
|
recalculate_sizes();
|
||||||
server_redraw_window_all(w);
|
server_redraw_window(w);
|
||||||
return;
|
return;
|
||||||
case 'h':
|
case 'h':
|
||||||
case KEYC_LEFT:
|
case KEYC_LEFT:
|
||||||
@ -169,169 +166,84 @@ window_scroll_key(struct window *w, int key)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ox != data->ox || oy != data->oy)
|
if (ox != data->ox || oy != data->oy)
|
||||||
server_redraw_window_all(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_scroll_up_1(struct window *w)
|
window_scroll_up_1(struct window *w)
|
||||||
{
|
{
|
||||||
struct window_scroll_mode_data *data = w->modedata;
|
struct window_scroll_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
|
||||||
u_int i;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->oy >= data->size)
|
if (data->oy >= data->size)
|
||||||
return;
|
return;
|
||||||
data->oy++;
|
data->oy++;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
screen_draw_move_cursor(&ctx, 0, 0);
|
||||||
if (c == NULL || c->session == NULL)
|
screen_draw_insert_lines(&ctx, 1);
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
|
|
||||||
screen_draw_move(&ctx, 0, 0);
|
|
||||||
input_store_one(c->out, CODE_INSERTLINE, 1);
|
|
||||||
window_scroll_draw_position(w, &ctx);
|
window_scroll_draw_position(w, &ctx);
|
||||||
screen_draw_line(&ctx, 1); /* nuke old position display */
|
screen_draw_line(&ctx, 1);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_scroll_down_1(struct window *w)
|
window_scroll_down_1(struct window *w)
|
||||||
{
|
{
|
||||||
struct window_scroll_mode_data *data = w->modedata;
|
struct window_scroll_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
|
||||||
u_int i;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->oy == 0)
|
if (data->oy == 0)
|
||||||
return;
|
return;
|
||||||
data->oy--;
|
data->oy--;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
screen_draw_move_cursor(&ctx, 0, 0);
|
||||||
if (c == NULL || c->session == NULL)
|
screen_draw_delete_lines(&ctx, 1);
|
||||||
continue;
|
screen_draw_line(&ctx, screen_last_y(&w->screen));
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
|
|
||||||
screen_draw_move(&ctx, 0, 0);
|
|
||||||
input_store_one(c->out, CODE_DELETELINE, 1);
|
|
||||||
screen_draw_line(&ctx, screen_last_y(s));
|
|
||||||
window_scroll_draw_position(w, &ctx);
|
window_scroll_draw_position(w, &ctx);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_scroll_right_1(struct window *w)
|
window_scroll_right_1(struct window *w)
|
||||||
{
|
{
|
||||||
struct window_scroll_mode_data *data = w->modedata;
|
struct window_scroll_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
u_int i;
|
||||||
u_int i, j;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->ox >= SHRT_MAX)
|
if (data->ox >= SHRT_MAX)
|
||||||
return;
|
return;
|
||||||
data->ox++;
|
data->ox++;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
c = ARRAY_ITEM(&clients, i);
|
for (i = 1; i < screen_size_y(&w->screen); i++) {
|
||||||
if (c == NULL || c->session == NULL)
|
screen_draw_move_cursor(&ctx, 0, i);
|
||||||
continue;
|
screen_draw_delete_characters(&ctx, 1);
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
|
||||||
buffer_add(c->out, sizeof hdr);
|
|
||||||
size = BUFFER_USED(c->out);
|
|
||||||
|
|
||||||
screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
|
|
||||||
for (j = 1; j < screen_size_y(s); j++) {
|
|
||||||
screen_draw_move(&ctx, 0, j);
|
|
||||||
input_store_one(c->out, CODE_DELETECHARACTER, 1);
|
|
||||||
}
|
}
|
||||||
screen_draw_column(&ctx, screen_last_x(s));
|
screen_draw_column(&ctx, screen_last_x(&w->screen));
|
||||||
window_scroll_draw_position(w, &ctx);
|
window_scroll_draw_position(w, &ctx);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_scroll_left_1(struct window *w)
|
window_scroll_left_1(struct window *w)
|
||||||
{
|
{
|
||||||
struct window_scroll_mode_data *data = w->modedata;
|
struct window_scroll_mode_data *data = w->modedata;
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
struct screen_draw_ctx ctx;
|
||||||
struct client *c;
|
u_int i;
|
||||||
u_int i, j;
|
|
||||||
struct hdr hdr;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
if (data->ox == 0)
|
if (data->ox == 0)
|
||||||
return;
|
return;
|
||||||
data->ox--;
|
data->ox--;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
|
||||||
c = ARRAY_ITEM(&clients, i);
|
|
||||||
if (c == NULL || c->session == NULL)
|
|
||||||
continue;
|
|
||||||
if (!session_has(c->session, w))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
buffer_ensure(c->out, sizeof hdr);
|
screen_draw_start_window(&ctx, w, data->ox, data->oy);
|
||||||
buffer_add(c->out, sizeof hdr);
|
for (i = 1; i < screen_size_y(&w->screen); i++) {
|
||||||
size = BUFFER_USED(c->out);
|
screen_draw_move_cursor(&ctx, 0, i);
|
||||||
|
screen_draw_insert_characters(&ctx, 1);
|
||||||
screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
|
|
||||||
for (j = 1; j < screen_size_y(s); j++) {
|
|
||||||
screen_draw_move(&ctx, 0, j);
|
|
||||||
input_store_one(c->out, CODE_INSERTCHARACTER, 1);
|
|
||||||
}
|
}
|
||||||
screen_draw_column(&ctx, 0);
|
screen_draw_column(&ctx, 0);
|
||||||
window_scroll_draw_position(w, &ctx);
|
window_scroll_draw_position(w, &ctx);
|
||||||
screen_draw_stop(&ctx);
|
screen_draw_stop(&ctx);
|
||||||
|
|
||||||
size = BUFFER_USED(c->out) - size;
|
|
||||||
hdr.type = MSG_DATA;
|
|
||||||
hdr.size = size;
|
|
||||||
memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
22
window.c
22
window.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: window.c,v 1.31 2007-11-21 19:53:57 nicm Exp $ */
|
/* $Id: window.c,v 1.32 2007-11-27 19:23:34 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -274,24 +274,18 @@ window_resize(struct window *w, u_int sx, u_int sy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_parse(struct window *w, struct buffer *b)
|
window_parse(struct window *w)
|
||||||
{
|
{
|
||||||
input_parse(w, b);
|
input_parse(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
|
window_draw(struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
|
||||||
{
|
{
|
||||||
struct screen *s = &w->screen;
|
|
||||||
struct screen_draw_ctx ctx;
|
|
||||||
|
|
||||||
if (w->mode != NULL)
|
if (w->mode != NULL)
|
||||||
w->mode->draw(w, b, py, ny);
|
w->mode->draw(w, ctx, py, ny);
|
||||||
else {
|
else
|
||||||
screen_draw_start(&ctx, s, b, 0, 0);
|
screen_draw_lines(ctx, py, ny);
|
||||||
screen_draw_lines(&ctx, py, ny);
|
|
||||||
screen_draw_stop(&ctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -300,5 +294,5 @@ window_key(struct window *w, int key)
|
|||||||
if (w->mode != NULL)
|
if (w->mode != NULL)
|
||||||
w->mode->key(w, key);
|
w->mode->key(w, key);
|
||||||
else
|
else
|
||||||
input_key(w->out, key);
|
input_key(w, key);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user