3 /* This "driver" is designed to go on top of an existing driver
4 to provide support for features only present if using an
5 xterm or compatible program for your console output. It should
6 inlcude such features as resizing, separation of output from the
7 standard wine console, and a configurable title bar for
9 /* Right now, it doesn't have any "special" features */
12 #include <sys/ioctl.h>
22 static BOOL32 wine_create_console(FILE **master, FILE **slave, int *pid);
23 static FILE *wine_openpty(FILE **master, FILE **slave, char *name,
24 struct termios *term, struct winsize *winsize);
26 /* The console -- I chose to keep the master and slave
27 * (UNIX) file descriptors around in case they are needed for
28 * ioctls later. The pid is needed to destroy the xterm on close
30 typedef struct _XTERM_CONSOLE {
31 FILE *master; /* xterm side of pty */
32 FILE *slave; /* wine side of pty */
33 int pid; /* xterm's pid, -1 if no xterm */
36 static XTERM_CONSOLE xterm_console;
39 FILE *old_in, *old_out;
43 /* Here, this is a supplementary driver so we should remember to call
45 chain.init = driver.init;
46 driver.init = XTERM_Init;
48 chain.close = driver.close;
49 driver.close = XTERM_Close;
54 wine_create_console(&xterm_console.master, &xterm_console.slave,
57 old_in = driver.console_in;
58 driver.console_in = xterm_console.slave;
60 old_out = driver.console_out;
61 driver.console_out = xterm_console.slave;
63 /* Then call the chain... */
70 /* Call the chain first... */
74 driver.console_in = old_in;
75 driver.console_out = old_out;
77 /* make sure a xterm exists to kill */
78 if (xterm_console.pid != -1) {
79 kill(xterm_console.pid, SIGTERM);
84 * It looks like the openpty that comes with glibc in RedHat 5.0
85 * is buggy (second call returns what looks like a dup of 0 and 1
86 * instead of a new pty), this is a generic replacement.
88 /** Can't we determine this using autoconf?
91 static FILE *wine_openpty(FILE **master, FILE **slave, char *name,
92 struct termios *term, struct winsize *winsize)
98 strcpy (pts_name, "/dev/ptyXY");
99 for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) {
101 for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) {
104 if ((fdm = fopen(pts_name, "r+")) == NULL) {
111 if ((fds = fopen(pts_name, "r+")) == NULL) {
119 tcsetattr(fileno(*slave), TCSANOW, term);
121 ioctl(fileno(*slave), TIOCSWINSZ, winsize);
124 strcpy(name, pts_name);
131 static BOOL32 wine_create_console(FILE **master, FILE **slave, int *pid)
139 if (tcgetattr(0, &term) < 0) return FALSE;
140 term.c_lflag |= ICANON;
141 term.c_lflag &= ~ECHO;
142 if (wine_openpty(master, slave, NULL, &term, NULL) < 0)
145 if ((*pid=fork()) == 0) {
146 tcsetattr(fileno(*slave), TCSADRAIN, &term);
147 sprintf(buf, "-Sxx%d", fileno(*master));
148 execlp("xterm", "xterm", buf, NULL);
149 ERR(console, "error creating xterm\n");
153 /* most xterms like to print their window ID when used with -S;
154 * read it and continue before the user has a chance...
155 * NOTE: this is the reason we started xterm with ECHO off,
156 * we'll turn it back on below
159 for (i=0; c!='\n'; (status=fread(&c, 1, 1, *slave)), i++) {
160 if (status == -1 && c == '\0') {
161 /* wait for xterm to be created */
165 WARN(console, "can't read xterm WID\n");
170 term.c_lflag |= ECHO;
171 tcsetattr(fileno(*master), TCSADRAIN, &term);