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((*slave
)->_fileno
, TCSANOW
, term
);
121 ioctl((*slave
)->_fileno
, 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((*slave
)->_fileno
, TCSADRAIN
, &term
);
147 sprintf(buf
, "-Sxx%d", (*master
)->_fileno
);
148 execlp("xterm", "xterm", buf
, NULL
);
149 ERR(console
, "error creating AllocConsole 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((*master
)->_fileno
, TCSADRAIN
, &term
);