summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed T. Crigler <crigler@users.sourceforge.net>2004-06-24 01:57:02 +0000
committerNed T. Crigler <crigler@users.sourceforge.net>2004-06-24 01:57:02 +0000
commita5599b4610788c17f5166685612f48c71d7537ac (patch)
tree97826e9812b600d3c4777bd265c932700c63babe
parent302917ca33d7cdfac786f562986b2c669f64ad49 (diff)
Allow the redraw method to be chosen by the user, and include the old Ctrl L
character method again.
-rw-r--r--attach.c18
-rw-r--r--dtach.h19
-rw-r--r--main.c33
-rw-r--r--master.c58
4 files changed, 102 insertions, 26 deletions
diff --git a/attach.c b/attach.c
index 26ca9fd..5fe18a2 100644
--- a/attach.c
+++ b/attach.c
@@ -96,7 +96,7 @@ process_kbd(int s, struct packet *pkt)
{
/* Tell the master that we are suspending. */
pkt->type = MSG_DETACH;
- write(s, pkt, sizeof(*pkt));
+ write(s, pkt, sizeof(struct packet));
/* And suspend... */
tcsetattr(0, TCSADRAIN, &orig_term);
@@ -106,8 +106,13 @@ process_kbd(int s, struct packet *pkt)
/* Tell the master that we are returning. */
pkt->type = MSG_ATTACH;
+ write(s, pkt, sizeof(struct packet));
+
+ /* We would like a redraw, too. */
+ pkt->type = MSG_REDRAW;
+ pkt->len = redraw_method;
ioctl(0, TIOCGWINSZ, &pkt->u.ws);
- write(s, pkt, sizeof(*pkt));
+ write(s, pkt, sizeof(struct packet));
return;
}
/* Detach char? */
@@ -121,7 +126,7 @@ process_kbd(int s, struct packet *pkt)
win_changed = 1;
/* Push it out */
- write(s, pkt, sizeof(*pkt));
+ write(s, pkt, sizeof(struct packet));
}
int
@@ -176,8 +181,13 @@ attach_main(int noerror)
/* Tell the master that we want to attach. */
pkt.type = MSG_ATTACH;
+ write(s, &pkt, sizeof(struct packet));
+
+ /* We would like a redraw, too. */
+ pkt.type = MSG_REDRAW;
+ pkt.len = redraw_method;
ioctl(0, TIOCGWINSZ, &pkt.u.ws);
- write(s, &pkt, sizeof(pkt));
+ write(s, &pkt, sizeof(struct packet));
/* Wait for things to happen */
while (1)
diff --git a/dtach.h b/dtach.h
index 5373404..f28099a 100644
--- a/dtach.h
+++ b/dtach.h
@@ -74,15 +74,24 @@
#include <sys/un.h>
extern char *progname, *sockname;
-extern int detach_char, no_suspend;
+extern int detach_char, no_suspend, redraw_method;
extern struct termios orig_term;
enum
{
- MSG_PUSH,
- MSG_ATTACH,
- MSG_DETACH,
- MSG_WINCH,
+ MSG_PUSH = 0,
+ MSG_ATTACH = 1,
+ MSG_DETACH = 2,
+ MSG_WINCH = 3,
+ MSG_REDRAW = 4,
+};
+
+enum
+{
+ REDRAW_UNSPEC = 0,
+ REDRAW_NONE = 1,
+ REDRAW_CTRL_L = 2,
+ REDRAW_WINCH = 3,
};
/* The client to master protocol. */
diff --git a/main.c b/main.c
index 0835a5e..328a12c 100644
--- a/main.c
+++ b/main.c
@@ -35,6 +35,8 @@ char *sockname;
int detach_char = '\\' - 64;
/* 1 if we should not interpret the suspend character. */
int no_suspend;
+/* The default redraw method. Initially set to unspecified. */
+int redraw_method = REDRAW_UNSPEC;
/*
** The original terminal settings. Shared between the master and attach
@@ -63,6 +65,10 @@ usage()
" -e <char>\tSet the detach character to <char>, defaults "
"to ^\\.\n"
" -E\t\tDisable the detach character.\n"
+ " -r <method>\tUse the specified redraw method when redrawing:\n"
+ "\t\t none: Don't redraw at all.\n"
+ "\t\t ctrl_l: Send a Ctrl L character to the program.\n"
+ "\t\t winch: Send a WINCH signal to the program.\n"
" -z\t\tDisable processing of the suspend key.\n"
"\nReport any bugs to <" PACKAGE_BUGREPORT ">.\n",
PACKAGE_VERSION, __DATE__, __TIME__);
@@ -153,6 +159,33 @@ main(int argc, char **argv)
detach_char = argv[0][0];
break;
}
+ else if (*p == 'r')
+ {
+ ++argv; --argc;
+ if (argc < 1)
+ {
+ printf("%s: No redraw method "
+ "specified.\n", progname);
+ printf("Try '%s --help' for more "
+ "information.\n", progname);
+ return 1;
+ }
+ if (strcmp(argv[0], "none") == 0)
+ redraw_method = REDRAW_NONE;
+ else if (strcmp(argv[0], "ctrl_l") == 0)
+ redraw_method = REDRAW_CTRL_L;
+ else if (strcmp(argv[0], "winch") == 0)
+ redraw_method = REDRAW_WINCH;
+ else
+ {
+ printf("%s: Invalid redraw method "
+ "specified.\n", progname);
+ printf("Try '%s --help' for more "
+ "information.\n", progname);
+ return 1;
+ }
+ break;
+ }
else
{
printf("%s: Invalid option '-%c'\n",
diff --git a/master.c b/master.c
index 8d31651..612ce2f 100644
--- a/master.c
+++ b/master.c
@@ -238,7 +238,7 @@ client_activity(struct client *p)
struct packet pkt;
/* Read the activity. */
- len = read(p->fd, &pkt, sizeof(pkt));
+ len = read(p->fd, &pkt, sizeof(struct packet));
/* Close the client on an error. */
if (len <= 0)
{
@@ -254,24 +254,9 @@ client_activity(struct client *p)
if (pkt.type == MSG_PUSH)
write(the_pty.fd, pkt.u.buf, pkt.len);
- /* When attaching, we set the window size and force a redraw by sending
- ** the WINCH signal to the program.
- **
- ** XXX: Are there any programs that don't handle the WINCH signal
- ** properly? Full-screen programs should fully redraw themselves, and
- ** line-oriented programs should redraw the prompt, or do nothing.
- */
+ /* Attach or detach from the program. */
else if (pkt.type == MSG_ATTACH)
- {
p->attached = 1;
- if (memcmp(&the_pty.ws, &pkt.u.ws, sizeof(struct winsize)) != 0)
- {
- the_pty.ws = pkt.u.ws;
- ioctl(the_pty.fd, TIOCSWINSZ, &the_pty.ws);
- }
- else
- killpty(&the_pty, SIGWINCH);
- }
else if (pkt.type == MSG_DETACH)
p->attached = 0;
@@ -281,6 +266,41 @@ client_activity(struct client *p)
the_pty.ws = pkt.u.ws;
ioctl(the_pty.fd, TIOCSWINSZ, &the_pty.ws);
}
+
+ /* Force a redraw using a particular method. */
+ else if (pkt.type == MSG_REDRAW)
+ {
+ int method = pkt.len;
+
+ /* If the client didn't specify a particular method, use
+ ** whatever we had on startup. */
+ if (method == REDRAW_UNSPEC)
+ method = redraw_method;
+ if (method == REDRAW_NONE)
+ return;
+
+ /* Set the window size. */
+ the_pty.ws = pkt.u.ws;
+ ioctl(the_pty.fd, TIOCSWINSZ, &the_pty.ws);
+
+ /* Send a ^L character if the terminal is in no-echo and
+ ** character-at-a-time mode. */
+ if (method == REDRAW_CTRL_L)
+ {
+ char c = '\f';
+
+ if (((the_pty.term.c_lflag & (ECHO|ICANON)) == 0) &&
+ (the_pty.term.c_cc[VMIN] == 1))
+ {
+ write(the_pty.fd, &c, 1);
+ }
+ }
+ /* Send a WINCH signal to the program. */
+ else if (method == REDRAW_WINCH)
+ {
+ killpty(&the_pty, SIGWINCH);
+ }
+ }
}
/* The master process - It watches over the pty process and the attached */
@@ -368,6 +388,10 @@ master_main(char **argv)
int s;
pid_t pid;
+ /* Use a default redraw method if one hasn't been specified yet. */
+ if (redraw_method == REDRAW_UNSPEC)
+ redraw_method = REDRAW_CTRL_L;
+
/* Create the unix domain socket. */
s = create_socket(sockname);
if (s < 0)