Add a driver to open up a new xterm window whenever console output is
needed. Derived from console/win32.c but we are not yet ready to merge the code completely.
This commit is contained in:
parent
b13f23e4fc
commit
55768384ff
|
@ -9,7 +9,8 @@ C_SRCS = \
|
|||
generic.c \
|
||||
interface.c \
|
||||
ncurses.c \
|
||||
tty.c
|
||||
tty.c \
|
||||
xterm.c
|
||||
|
||||
all: $(MODULE).o
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
driver, it should make sure to perserve the old values. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
|
|
|
@ -6,10 +6,16 @@
|
|||
This could be done using a macro, but additional functionality
|
||||
may be provided here in the future. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windows.h"
|
||||
#include "console.h"
|
||||
#include "config.h"
|
||||
|
||||
/* I did this without realizing that CONSOLE_* was actually used by
|
||||
the Win32 console driver. I will definately have to rename these
|
||||
functions to avoid the name clash... */
|
||||
|
||||
void CONSOLE_Write(char out, int fg_color, int bg_color, int attribute)
|
||||
{
|
||||
if (driver.write)
|
||||
|
@ -22,6 +28,9 @@ void CONSOLE_Write(char out, int fg_color, int bg_color, int attribute)
|
|||
|
||||
void CONSOLE_Init()
|
||||
{
|
||||
/* Suitable defaults... */
|
||||
driver.console_out = stdout;
|
||||
driver.console_in = stdin;
|
||||
/* Eventually, this will be a command-line choice */
|
||||
#ifndef WINE_NCURSES
|
||||
TTY_Start();
|
||||
|
@ -30,6 +39,8 @@ void CONSOLE_Init()
|
|||
#endif
|
||||
GENERIC_Start();
|
||||
|
||||
/*XTERM_Start();*/
|
||||
|
||||
if (driver.init)
|
||||
driver.init();
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#undef ERR /* Use ncurses's err() */
|
||||
#include <curses.h>
|
||||
|
||||
SCREEN *ncurses_screen;
|
||||
|
||||
void NCURSES_Start()
|
||||
{
|
||||
/* This should be the root driver so we can ignore anything
|
||||
|
@ -46,7 +48,9 @@ void NCURSES_Start()
|
|||
|
||||
void NCURSES_Init()
|
||||
{
|
||||
initscr();
|
||||
ncurses_screen = newterm("xterm", driver.console_out,
|
||||
driver.console_in);
|
||||
set_term(ncurses_screen);
|
||||
cbreak();
|
||||
noecho();
|
||||
nonl();
|
||||
|
@ -58,7 +62,7 @@ void NCURSES_Init()
|
|||
void NCURSES_Write(char output, int fg, int bg, int attribute)
|
||||
{
|
||||
/* We can discard all extended information. */
|
||||
addch(output);
|
||||
waddch(stdscr, output);
|
||||
}
|
||||
|
||||
void NCURSES_Close()
|
||||
|
@ -74,7 +78,7 @@ void NCURSES_GetKeystroke(char *scan, char *ascii)
|
|||
/* When it is detected, we will already have the right value
|
||||
in scan and ascii, but we need to take this keystroke
|
||||
out of the buffer. */
|
||||
getch();
|
||||
wgetch(stdscr);
|
||||
}
|
||||
|
||||
int NCURSES_CheckForKeystroke(char *scan, char *ascii)
|
||||
|
@ -82,7 +86,7 @@ int NCURSES_CheckForKeystroke(char *scan, char *ascii)
|
|||
/* We don't currently support scan codes here */
|
||||
/* FIXME */
|
||||
int temp;
|
||||
temp = getch();
|
||||
temp = wgetch(stdscr);
|
||||
if (temp == ERR)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -97,7 +101,7 @@ int NCURSES_CheckForKeystroke(char *scan, char *ascii)
|
|||
|
||||
void NCURSES_MoveCursor(char row, char col)
|
||||
{
|
||||
move(row, col);
|
||||
wmove(stdscr, row, col);
|
||||
}
|
||||
|
||||
void NCURSES_GetCursorPosition(char *row, char *col)
|
||||
|
@ -114,7 +118,7 @@ void NCURSES_GetCharacterAtCursor(char *ch, int *fg_color, int
|
|||
*bg_color, int *attribute)
|
||||
{
|
||||
/* We will eventually have to convert the color data */
|
||||
*ch = (char) inch();
|
||||
*ch = (char) winch(stdscr);
|
||||
*fg_color = 0;
|
||||
*bg_color = 0;
|
||||
*attribute = 0;
|
||||
|
@ -122,12 +126,12 @@ void NCURSES_GetCharacterAtCursor(char *ch, int *fg_color, int
|
|||
|
||||
void NCURSES_Refresh()
|
||||
{
|
||||
refresh();
|
||||
wrefresh(stdscr);
|
||||
}
|
||||
|
||||
void NCURSES_ClearScreen()
|
||||
{
|
||||
erase();
|
||||
werase(stdscr);
|
||||
}
|
||||
|
||||
#endif /* WINE_NCURSES */
|
||||
|
|
|
@ -28,14 +28,14 @@ void TTY_Start()
|
|||
void TTY_Write(char output, int fg, int bg, int attribute)
|
||||
{
|
||||
/* We can discard all extended information. */
|
||||
printf("%c", output);
|
||||
fprintf(driver.console_out, "%c", output);
|
||||
}
|
||||
|
||||
void TTY_GetKeystroke(char *ch, char *scan)
|
||||
{
|
||||
/* All we have are character input things, nothing for extended */
|
||||
/* This is just the TTY driver, after all. We'll cope. */
|
||||
_lread16(0, ch, 0);
|
||||
*ch = fgetc(driver.console_in);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/* xterm.c */
|
||||
|
||||
/* This "driver" is designed to go on top of an existing driver
|
||||
to provide support for features only present if using an
|
||||
xterm or compatible program for your console output. It should
|
||||
inlcude such features as resizing, separation of output from the
|
||||
standard wine console, and a configurable title bar for
|
||||
Win32 console. */
|
||||
/* Right now, it doesn't have any "special" features */
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "windows.h"
|
||||
#include "console.h"
|
||||
#include "debug.h"
|
||||
|
||||
static BOOL32 wine_create_console(FILE **master, FILE **slave, int *pid);
|
||||
static FILE *wine_openpty(FILE **master, FILE **slave, char *name,
|
||||
struct termios *term, struct winsize *winsize);
|
||||
|
||||
/* The console -- I chose to keep the master and slave
|
||||
* (UNIX) file descriptors around in case they are needed for
|
||||
* ioctls later. The pid is needed to destroy the xterm on close
|
||||
*/
|
||||
typedef struct _XTERM_CONSOLE {
|
||||
FILE *master; /* xterm side of pty */
|
||||
FILE *slave; /* wine side of pty */
|
||||
int pid; /* xterm's pid, -1 if no xterm */
|
||||
} XTERM_CONSOLE;
|
||||
|
||||
static XTERM_CONSOLE xterm_console;
|
||||
|
||||
CONSOLE_device chain;
|
||||
FILE *old_in, *old_out;
|
||||
|
||||
void XTERM_Start()
|
||||
{
|
||||
/* Here, this is a supplementary driver so we should remember to call
|
||||
the chain. */
|
||||
chain.init = driver.init;
|
||||
driver.init = XTERM_Init;
|
||||
|
||||
chain.close = driver.close;
|
||||
driver.close = XTERM_Close;
|
||||
}
|
||||
|
||||
void XTERM_Init()
|
||||
{
|
||||
wine_create_console(&xterm_console.master, &xterm_console.slave,
|
||||
&xterm_console.pid);
|
||||
|
||||
old_in = driver.console_in;
|
||||
driver.console_in = xterm_console.slave;
|
||||
|
||||
old_out = driver.console_out;
|
||||
driver.console_out = xterm_console.slave;
|
||||
|
||||
/* Then call the chain... */
|
||||
if (chain.init)
|
||||
chain.init();
|
||||
}
|
||||
|
||||
void XTERM_Close()
|
||||
{
|
||||
/* Call the chain first... */
|
||||
if (chain.close)
|
||||
chain.close();
|
||||
|
||||
driver.console_in = old_in;
|
||||
driver.console_out = old_out;
|
||||
|
||||
/* make sure a xterm exists to kill */
|
||||
if (xterm_console.pid != -1) {
|
||||
kill(xterm_console.pid, SIGTERM);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It looks like the openpty that comes with glibc in RedHat 5.0
|
||||
* is buggy (second call returns what looks like a dup of 0 and 1
|
||||
* instead of a new pty), this is a generic replacement.
|
||||
*/
|
||||
/** Can't we determine this using autoconf?
|
||||
*/
|
||||
|
||||
static FILE *wine_openpty(FILE **master, FILE **slave, char *name,
|
||||
struct termios *term, struct winsize *winsize)
|
||||
{
|
||||
FILE *fdm, *fds;
|
||||
char *ptr1, *ptr2;
|
||||
char pts_name[512];
|
||||
|
||||
strcpy (pts_name, "/dev/ptyXY");
|
||||
for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) {
|
||||
pts_name[8] = *ptr1;
|
||||
for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) {
|
||||
pts_name[9] = *ptr2;
|
||||
|
||||
if ((fdm = fopen(pts_name, "r+")) == NULL) {
|
||||
if (errno == ENOENT)
|
||||
return (FILE *) -1;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
pts_name[5] = 't';
|
||||
if ((fds = fopen(pts_name, "r+")) == NULL) {
|
||||
pts_name[5] = 'p';
|
||||
continue;
|
||||
}
|
||||
*master = fdm;
|
||||
*slave = fds;
|
||||
|
||||
if (term != NULL)
|
||||
tcsetattr((*slave)->_fileno, TCSANOW, term);
|
||||
if (winsize != NULL)
|
||||
ioctl((*slave)->_fileno, TIOCSWINSZ, winsize);
|
||||
|
||||
if (name != NULL)
|
||||
strcpy(name, pts_name);
|
||||
return fds;
|
||||
}
|
||||
}
|
||||
return (FILE *) -1;
|
||||
}
|
||||
|
||||
static BOOL32 wine_create_console(FILE **master, FILE **slave, int *pid)
|
||||
{
|
||||
struct termios term;
|
||||
char buf[1024];
|
||||
char c = '\0';
|
||||
int status = 0;
|
||||
int i;
|
||||
|
||||
if (tcgetattr(0, &term) < 0) return FALSE;
|
||||
term.c_lflag |= ICANON;
|
||||
term.c_lflag &= ~ECHO;
|
||||
if (wine_openpty(master, slave, NULL, &term, NULL) < 0)
|
||||
return FALSE;
|
||||
|
||||
if ((*pid=fork()) == 0) {
|
||||
tcsetattr((*slave)->_fileno, TCSADRAIN, &term);
|
||||
sprintf(buf, "-Sxx%d", (*master)->_fileno);
|
||||
execlp("xterm", "xterm", buf, NULL);
|
||||
ERR(console, "error creating AllocConsole xterm\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* most xterms like to print their window ID when used with -S;
|
||||
* read it and continue before the user has a chance...
|
||||
* NOTE: this is the reason we started xterm with ECHO off,
|
||||
* we'll turn it back on below
|
||||
*/
|
||||
|
||||
for (i=0; c!='\n'; (status=fread(&c, 1, 1, *slave)), i++) {
|
||||
if (status == -1 && c == '\0') {
|
||||
/* wait for xterm to be created */
|
||||
usleep(100);
|
||||
}
|
||||
if (i > 10000) {
|
||||
WARN(console, "can't read xterm WID\n");
|
||||
kill(*pid, SIGKILL);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
term.c_lflag |= ECHO;
|
||||
tcsetattr((*master)->_fileno, TCSADRAIN, &term);
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
typedef struct CONSOLE_DRIVER
|
||||
|
@ -36,6 +38,9 @@ typedef struct CONSOLE_DRIVER
|
|||
|
||||
/* Other data */
|
||||
int norefresh;
|
||||
FILE *console_out;
|
||||
FILE *console_in;
|
||||
|
||||
} CONSOLE_device;
|
||||
|
||||
CONSOLE_device driver; /* Global driver struct */
|
||||
|
@ -87,4 +92,9 @@ void NCURSES_ClearScreen();
|
|||
|
||||
#endif /* WINE_NCURSES */
|
||||
|
||||
/* Xterm specific defines */
|
||||
void XTERM_Start();
|
||||
void XTERM_Close();
|
||||
void XTERM_Init();
|
||||
|
||||
#endif /* CONSOLE_H */
|
||||
|
|
Loading…
Reference in New Issue