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.
6 Currently, it supports resizing and separating debug messages from
8 It does not currently support changing the title bar.
12 #include "wine/port.h"
17 #include <sys/ioctl.h>
30 #include "debugtools.h"
32 DEFAULT_DEBUG_CHANNEL(console);
34 char console_xterm_prog[80];
36 static BOOL wine_create_console(FILE **master, FILE **slave, pid_t *pid);
38 /* The console -- I chose to keep the master and slave
39 * (UNIX) file descriptors around in case they are needed for
40 * ioctls later. The pid is needed to destroy the xterm on close
42 typedef struct _XTERM_CONSOLE {
43 FILE *master; /* xterm side of pty */
44 FILE *slave; /* wine side of pty */
45 pid_t pid; /* xterm's pid, -1 if no xterm */
48 static XTERM_CONSOLE xterm_console;
51 FILE *old_in, *old_out;
53 void XTERM_Start(void)
55 /* Here, this is a supplementary driver so we should remember to call
57 chain.init = driver.init;
58 driver.init = XTERM_Init;
60 chain.close = driver.close;
61 driver.close = XTERM_Close;
63 chain.resizeScreen = driver.resizeScreen;
64 driver.resizeScreen = XTERM_ResizeScreen;
66 /* Read in driver configuration */
67 PROFILE_GetWineIniString("console", "XtermProg",
68 "xterm", console_xterm_prog, 79);
74 wine_create_console(&xterm_console.master, &xterm_console.slave,
77 old_in = driver.console_in;
78 driver.console_in = xterm_console.slave;
80 old_out = driver.console_out;
81 driver.console_out = xterm_console.slave;
83 /* Then call the chain... */
90 /* Call the chain first... */
94 driver.console_in = old_in;
95 driver.console_out = old_out;
97 /* make sure a xterm exists to kill */
98 if (xterm_console.pid != -1) {
99 kill(xterm_console.pid, SIGTERM);
103 void XTERM_ResizeScreen(int x, int y)
107 /* Call the chain first, there shoudln't be any... */
108 if (chain.resizeScreen)
109 chain.resizeScreen(x, y);
111 sprintf(temp, "\x1b[8;%d;%dt", y, x);
112 CONSOLE_WriteRawString(temp);
114 CONSOLE_NotifyResizeScreen(x, y);
118 static BOOL wine_create_console(FILE **master, FILE **slave, pid_t *pid)
120 /* There is definately a bug in this routine that causes a lot
121 of garbage to be written to the screen, but I can't find it...
129 char xterm_resolution[10];
131 sprintf(xterm_resolution, "%dx%d", driver.x_res,
134 if (tcgetattr(0, &term) < 0) return FALSE;
135 term.c_lflag |= ICANON;
136 term.c_lflag &= ~ECHO;
137 if (openpty(&tmaster, &tslave, NULL, &term, NULL) < 0)
139 *master = fdopen(tmaster, "r+");
140 *slave = fdopen(tslave, "r+");
142 if ((*pid=fork()) == 0) {
143 tcsetattr(fileno(*slave), TCSADRAIN, &term);
144 sprintf(buf, "-Sxx%d", fileno(*master));
145 execlp(console_xterm_prog, console_xterm_prog, buf, "-fg",
146 "white", "-bg", "black", "-g",
147 xterm_resolution, NULL);
148 ERR("error creating xterm (file not found?)\n");
152 /* most xterms like to print their window ID when used with -S;
153 * read it and continue before the user has a chance...
154 * NOTE: this is the reason we started xterm with ECHO off,
155 * we'll turn it back on below
158 for (i=0; c!='\n'; (status=fread(&c, 1, 1, *slave)), i++) {
159 if (status == -1 && c == '\0') {
160 /* wait for xterm to be created */
164 WARN("can't read xterm WID\n");
169 term.c_lflag |= ECHO;
170 tcsetattr(fileno(*master), TCSADRAIN, &term);