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. */
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)

19
dtach.h
View File

@ -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. */

33
main.c
View File

@ -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",

View File

@ -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)