Allow the redraw method to be chosen by the user, and include the old Ctrl L

character method again.
This commit is contained in:
Ned T. Crigler 2004-06-24 01:57:02 +00:00
parent 302917ca33
commit a5599b4610
4 changed files with 102 additions and 26 deletions

View File

@ -96,7 +96,7 @@ process_kbd(int s, struct packet *pkt)
{ {
/* Tell the master that we are suspending. */ /* Tell the master that we are suspending. */
pkt->type = MSG_DETACH; pkt->type = MSG_DETACH;
write(s, pkt, sizeof(*pkt)); write(s, pkt, sizeof(struct packet));
/* And suspend... */ /* And suspend... */
tcsetattr(0, TCSADRAIN, &orig_term); tcsetattr(0, TCSADRAIN, &orig_term);
@ -106,8 +106,13 @@ process_kbd(int s, struct packet *pkt)
/* Tell the master that we are returning. */ /* Tell the master that we are returning. */
pkt->type = MSG_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); ioctl(0, TIOCGWINSZ, &pkt->u.ws);
write(s, pkt, sizeof(*pkt)); write(s, pkt, sizeof(struct packet));
return; return;
} }
/* Detach char? */ /* Detach char? */
@ -121,7 +126,7 @@ process_kbd(int s, struct packet *pkt)
win_changed = 1; win_changed = 1;
/* Push it out */ /* Push it out */
write(s, pkt, sizeof(*pkt)); write(s, pkt, sizeof(struct packet));
} }
int int
@ -176,8 +181,13 @@ attach_main(int noerror)
/* Tell the master that we want to attach. */ /* Tell the master that we want to attach. */
pkt.type = MSG_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); ioctl(0, TIOCGWINSZ, &pkt.u.ws);
write(s, &pkt, sizeof(pkt)); write(s, &pkt, sizeof(struct packet));
/* Wait for things to happen */ /* Wait for things to happen */
while (1) while (1)

19
dtach.h
View File

@ -74,15 +74,24 @@
#include <sys/un.h> #include <sys/un.h>
extern char *progname, *sockname; extern char *progname, *sockname;
extern int detach_char, no_suspend; extern int detach_char, no_suspend, redraw_method;
extern struct termios orig_term; extern struct termios orig_term;
enum enum
{ {
MSG_PUSH, MSG_PUSH = 0,
MSG_ATTACH, MSG_ATTACH = 1,
MSG_DETACH, MSG_DETACH = 2,
MSG_WINCH, 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. */ /* The client to master protocol. */

33
main.c
View File

@ -35,6 +35,8 @@ char *sockname;
int detach_char = '\\' - 64; int detach_char = '\\' - 64;
/* 1 if we should not interpret the suspend character. */ /* 1 if we should not interpret the suspend character. */
int no_suspend; 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 ** The original terminal settings. Shared between the master and attach
@ -63,6 +65,10 @@ usage()
" -e <char>\tSet the detach character to <char>, defaults " " -e <char>\tSet the detach character to <char>, defaults "
"to ^\\.\n" "to ^\\.\n"
" -E\t\tDisable the detach character.\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" " -z\t\tDisable processing of the suspend key.\n"
"\nReport any bugs to <" PACKAGE_BUGREPORT ">.\n", "\nReport any bugs to <" PACKAGE_BUGREPORT ">.\n",
PACKAGE_VERSION, __DATE__, __TIME__); PACKAGE_VERSION, __DATE__, __TIME__);
@ -153,6 +159,33 @@ main(int argc, char **argv)
detach_char = argv[0][0]; detach_char = argv[0][0];
break; 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 else
{ {
printf("%s: Invalid option '-%c'\n", printf("%s: Invalid option '-%c'\n",

View File

@ -238,7 +238,7 @@ client_activity(struct client *p)
struct packet pkt; struct packet pkt;
/* Read the activity. */ /* Read the activity. */
len = read(p->fd, &pkt, sizeof(pkt)); len = read(p->fd, &pkt, sizeof(struct packet));
/* Close the client on an error. */ /* Close the client on an error. */
if (len <= 0) if (len <= 0)
{ {
@ -254,24 +254,9 @@ client_activity(struct client *p)
if (pkt.type == MSG_PUSH) if (pkt.type == MSG_PUSH)
write(the_pty.fd, pkt.u.buf, pkt.len); write(the_pty.fd, pkt.u.buf, pkt.len);
/* When attaching, we set the window size and force a redraw by sending /* Attach or detach from the program. */
** 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.
*/
else if (pkt.type == MSG_ATTACH) else if (pkt.type == MSG_ATTACH)
{
p->attached = 1; 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) else if (pkt.type == MSG_DETACH)
p->attached = 0; p->attached = 0;
@ -281,6 +266,41 @@ client_activity(struct client *p)
the_pty.ws = pkt.u.ws; the_pty.ws = pkt.u.ws;
ioctl(the_pty.fd, TIOCSWINSZ, &the_pty.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 */ /* The master process - It watches over the pty process and the attached */
@ -368,6 +388,10 @@ master_main(char **argv)
int s; int s;
pid_t pid; 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. */ /* Create the unix domain socket. */
s = create_socket(sockname); s = create_socket(sockname);
if (s < 0) if (s < 0)