Added console support.

This commit is contained in:
Joseph Pranevich 1998-12-02 19:58:08 +00:00 committed by Alexandre Julliard
parent d6a91b7a74
commit 791cd6a342
15 changed files with 802 additions and 165 deletions

View File

@ -27,6 +27,7 @@ LIBSUBDIRS = \
tools \
tools/wrc \
controls \
console \
dlls/comctl32 \
dlls/imagehlp \
dlls/msacm \
@ -89,6 +90,7 @@ INSTALLSUBDIRS = $(DOCSUBDIRS)
LIBOBJS = \
controls/controls.o \
console/console.o \
dlls/comctl32/comctl32.o \
dlls/imagehlp/imagehlp.o \
dlls/msacm/msacm.o \

340
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -43,8 +43,12 @@ AC_ARG_ENABLE(trace,
[ --disable-trace compile out TRACE messages],
[if test "$enableval" = "no"; then TRACE_MSGS="no"; fi])
AC_ARG_WITH(ncurses,
[ --with-ncurses compile in the ncurses terminal],
[if test "$withval" = "yes"; then LIBS="$LIBS -lncurses"; AC_DEFINE(WINE_NCURSES) fi])
AC_ARG_WITH(reentrant-x,
[ --without-reentrant-x Compile for use with non-reentrant X libraries])
[ --without-reentrant-x compile for use with non-reentrant X libraries])
AC_SUBST(MAIN_TARGET)
AC_SUBST(LIB_TARGET)
@ -501,6 +505,7 @@ AC_SUBST_FILE(MAKE_RULES)
AC_OUTPUT([
Make.rules
Makefile
console/Makefile
controls/Makefile
debugger/Makefile
dlls/Makefile

1
console/.cvsignore Normal file
View File

@ -0,0 +1 @@
Makefile

18
console/Makefile.in Normal file
View File

@ -0,0 +1,18 @@
DEFS = @DLLFLAGS@ -D__WINE__
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = console
C_SRCS = \
generic.c \
interface.c \
ncurses.c \
tty.c
all: $(MODULE).o
@MAKE_RULES@
### Dependencies:

163
console/generic.c Normal file
View File

@ -0,0 +1,163 @@
/* generic.c */
/* This is a driver to implement, when possible, "high-level"
routines using only low level calls. This is to make it possible
to have accelerated functions for the individual drivers...
or to simply not bother with them. */
/* When creating new drivers, you need to assign all the functions that
that driver supports into the driver struct. If it is a supplementary
driver, it should make sure to perserve the old values. */
#include <stdio.h>
#include "console.h"
#include "config.h"
#include "debug.h"
void GENERIC_Start()
{
/* Here, we only want to add a driver if there is not one already
defined. */
TRACE(console, "GENERIC_Start\n");
if (!driver.clearWindow)
driver.clearWindow = GENERIC_ClearWindow;
if (!driver.scrollUpWindow)
driver.scrollUpWindow = GENERIC_ScrollUpWindow;
if (!driver.scrollDownWindow)
driver.scrollDownWindow = GENERIC_ScrollDownWindow;
if (!driver.getCharacter)
driver.getCharacter = GENERIC_GetCharacter;
}
void GENERIC_ClearWindow(char row1, char col1, char row2, char col2,
int bg_color, int attribute)
{
char trow, tcol;
char x, y;
int old_refresh;
TRACE(console, "GENERIC_ClearWindow()\n");
/* Abort if we have only partial functionality */
if (!(driver.getCursorPosition && driver.moveCursor && driver.write))
return;
old_refresh = CONSOLE_GetRefresh();
CONSOLE_SetRefresh(FALSE);
CONSOLE_GetCursorPosition(&trow, &tcol);
for (x = row1; x < row2; x++)
{
CONSOLE_MoveCursor(x, col1);
for (y = col1; y < col2; y++)
{
CONSOLE_Write(' ', 0, bg_color, attribute);
}
}
CONSOLE_MoveCursor(trow, tcol);
CONSOLE_SetRefresh(old_refresh);
TRACE(console, "GENERIC_ClearWindow() completed.\n");
}
/* These are in-progress. I just haven't finished them yet... */
void GENERIC_ScrollUpWindow(char row1, char col1, char row2, char col2,
char lines, int bg_color, int attribute)
{
char trow, tcol;
int x, y;
char ch;
int bg, fg, attr;
int old_refresh;
TRACE(console, "GENERIC_ScrollUpWindow()\n");
/* Abort if we have only partial functionality */
if (!(driver.getCursorPosition && driver.moveCursor && driver.write
&& driver.getCharacterAtCursor && driver.clearWindow))
return;
old_refresh = CONSOLE_GetRefresh();
CONSOLE_SetRefresh(FALSE);
CONSOLE_GetCursorPosition(&trow, &tcol);
for (x = row1 + lines; x < row2; x++)
{
for (y = col1; y < col2; y++)
{
CONSOLE_MoveCursor(x, y);
CONSOLE_GetCharacterAtCursor(&ch, &fg, &bg, &attr);
CONSOLE_MoveCursor(x - lines, y);
CONSOLE_Write(ch, fg, bg, attr);
}
}
CONSOLE_ClearWindow(row2 - lines, col1, row2, col2, bg_color,
attribute);
CONSOLE_MoveCursor(trow, tcol);
CONSOLE_SetRefresh(old_refresh);
TRACE(console, "GENERIC_ScrollUpWindow() completed.\n");
}
void GENERIC_ScrollDownWindow(char row1, char col1, char row2, char col2,
char lines, int bg_color, int attribute)
{
char trow, tcol;
int x, y;
char ch;
int bg, fg, attr;
int old_refresh;
TRACE(console, "GENERIC_ScrollDownWindow()\n");
/* Abort if we have only partial functionality */
if (!(driver.getCursorPosition && driver.moveCursor && driver.write
&& driver.getCharacterAtCursor && driver.clearWindow))
return;
old_refresh = CONSOLE_GetRefresh();
CONSOLE_SetRefresh(FALSE);
CONSOLE_GetCursorPosition(&trow, &tcol);
for (x = row2 - lines; x > row1; x--)
{
for (y = col1; y < col2; y++)
{
CONSOLE_MoveCursor(x, y);
CONSOLE_GetCharacterAtCursor(&ch, &fg, &bg, &attr);
CONSOLE_MoveCursor(x + lines, y);
CONSOLE_Write(ch, fg, bg, attr);
}
}
CONSOLE_ClearWindow(row1, col1, row1 + lines, col2, bg_color,
attribute);
CONSOLE_MoveCursor(trow, tcol);
CONSOLE_SetRefresh(old_refresh);
TRACE(console, "GENERIC_ScrollDownWindow() completed.\n");
}
char GENERIC_GetCharacter()
{
/* Keep getting keys until we get one with a char value */
char ch = (char) 0, scan;
while (!ch)
{
CONSOLE_GetKeystroke(&ch, &scan);
}
return ch;
}

156
console/interface.c Normal file
View File

@ -0,0 +1,156 @@
/* interface.c */
/* The primary purpose of this function is to provide CONSOLE_*
reotines that immediately call the appropiate driver handler.
This cleans up code in the individual modules considerably.
This could be done using a macro, but additional functionality
may be provided here in the future. */
#include "windows.h"
#include "console.h"
#include "config.h"
void CONSOLE_Write(char out, int fg_color, int bg_color, int attribute)
{
if (driver.write)
{
driver.write(out, fg_color, bg_color, attribute);
if (!driver.norefresh)
CONSOLE_Refresh();
}
}
void CONSOLE_Init()
{
/* Eventually, this will be a command-line choice */
#ifndef WINE_NCURSES
TTY_Start();
#else
NCURSES_Start();
#endif
GENERIC_Start();
if (driver.init)
driver.init();
}
void CONSOLE_Close()
{
if (driver.close)
driver.close();
}
void CONSOLE_MoveCursor(char row, char col)
{
if (driver.moveCursor)
{
driver.moveCursor(row, col);
if (!driver.norefresh)
CONSOLE_Refresh();
}
}
void CONSOLE_ClearWindow(char row1, char col1, char row2, char col2,
int bg_color, int attribute)
{
if (driver.clearWindow)
{
driver.clearWindow(row1, col1, row2, col2, bg_color, attribute);
if (!driver.norefresh)
CONSOLE_Refresh();
}
}
void CONSOLE_ScrollUpWindow(char row1, char col1, char row2, char col2,
char lines, int bg_color, int attribute)
{
if (driver.scrollUpWindow)
{
driver.scrollUpWindow(row1, col1, row2, col2, lines, bg_color,
attribute);
if (!driver.norefresh)
CONSOLE_Refresh();
}
}
void CONSOLE_ScrollDownWindow(char row1, char col1, char row2, char col2,
char lines, int bg_color, int attribute)
{
if (driver.scrollDownWindow)
{
driver.scrollDownWindow(row1, col1, row2, col2, lines, bg_color,
attribute);
if (!driver.norefresh)
CONSOLE_Refresh();
}
}
int CONSOLE_CheckForKeystroke(char *scan, char *ascii)
/* These functions need to go through a conversion layer. Scancodes
should *not* be determined by the driver, rather they should have
a conv_* function in int16.c. Yuck. */
{
if (driver.checkForKeystroke)
return driver.checkForKeystroke(scan, ascii);
else
return FALSE;
}
void CONSOLE_GetKeystroke(char *scan, char *ascii)
{
if (driver.getKeystroke)
return driver.getKeystroke(scan, ascii);
}
void CONSOLE_GetCursorPosition(char *row, char *col)
{
if (driver.getCursorPosition)
return driver.getCursorPosition(row, col);
}
void CONSOLE_GetCharacterAtCursor(char *ch, int *fg, int *bg, int *a)
{
if (driver.getCharacterAtCursor)
return driver.getCharacterAtCursor(ch, fg, bg, a);
}
void CONSOLE_Refresh()
{
if (driver.refresh)
return driver.refresh();
}
/* This function is only at the CONSOLE level. */
/* Admittably, calling the variable norefresh might be a bit dumb...*/
void CONSOLE_SetRefresh(int setting)
{
if (setting)
driver.norefresh = FALSE;
else
driver.norefresh = TRUE;
}
/* This function is only at the CONSOLE level. */
int CONSOLE_GetRefresh()
{
if (driver.norefresh)
return FALSE;
else
return TRUE;
}
void CONSOLE_ClearScreen()
{
if (driver.clearScreen)
return driver.clearScreen();
}
char CONSOLE_GetCharacter()
{
/* I'm not sure if we need this really. This is a function that can be
accelerated that returns the next *non extended* keystroke */
if (driver.getCharacter)
return driver.getCharacter();
else
return (char) 0; /* Sure, this will probably break programs... */
}

133
console/ncurses.c Normal file
View File

@ -0,0 +1,133 @@
/* ncurses.c */
#include "config.h"
#ifdef WINE_NCURSES
/* This is the console driver for systems that support the ncurses
interface.
*/
/* Actually, this should work for curses, as well. But there may be
individual functions that are unsupported in plain curses or other
variants. Those should be detected and special-cased by autoconf.
*/
/* When creating new drivers, you need to assign all the functions that
that driver supports into the driver struct. If it is a supplementary
driver, it should make sure to perserve the old values.
*/
#include "console.h"
#include "debug.h"
#undef ERR /* Use ncurses's err() */
#include <curses.h>
void NCURSES_Start()
{
/* This should be the root driver so we can ignore anything
already in the struct. */
driver.norefresh = FALSE;
driver.init = NCURSES_Init;
driver.write = NCURSES_Write;
driver.close = NCURSES_Close;
driver.moveCursor = NCURSES_MoveCursor;
driver.getCursorPosition = NCURSES_GetCursorPosition;
driver.getCharacterAtCursor = NCURSES_GetCharacterAtCursor;
driver.clearScreen = NCURSES_ClearScreen;
driver.checkForKeystroke = NCURSES_CheckForKeystroke;
driver.getKeystroke = NCURSES_GetKeystroke;
driver.refresh = NCURSES_Refresh;
}
void NCURSES_Init()
{
initscr();
cbreak();
noecho();
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
nodelay(stdscr, TRUE);
}
void NCURSES_Write(char output, int fg, int bg, int attribute)
{
/* We can discard all extended information. */
addch(output);
}
void NCURSES_Close()
{
endwin();
}
void NCURSES_GetKeystroke(char *scan, char *ascii)
{
while (!NCURSES_CheckForKeystroke(scan, ascii))
{} /* Wait until keystroke is detected */
/* 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();
}
int NCURSES_CheckForKeystroke(char *scan, char *ascii)
{
/* We don't currently support scan codes here */
/* FIXME */
int temp;
temp = getch();
if (temp == ERR)
{
return FALSE;
}
else
{
ungetch(temp); /* Keystroke not removed from buffer */
*ascii = (char) temp;
return TRUE;
}
}
void NCURSES_MoveCursor(char row, char col)
{
move(row, col);
}
void NCURSES_GetCursorPosition(char *row, char *col)
{
int trow, tcol;
getyx(stdscr, trow, tcol); /* MACRO, no need to pass pointer */
*row = (char) trow;
*col = (char) tcol;
}
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();
*fg_color = 0;
*bg_color = 0;
*attribute = 0;
};
void NCURSES_Refresh()
{
refresh();
}
void NCURSES_ClearScreen()
{
erase();
}
#endif /* WINE_NCURSES */

41
console/tty.c Normal file
View File

@ -0,0 +1,41 @@
/* tty.c */
/* This is the console driver for TTY-based consoles, i.e. consoles
without cursor placement, etc. It's also a pretty decent starting
point for other driers.
*/
/* When creating new drivers, you need to assign all the functions that
that driver supports into the driver struct. If it is a supplementary
driver, it should make sure to perserve the old values. */
#include <stdio.h>
#include "console.h"
#include "config.h"
#include "wintypes.h" /* FALSE */
#include "windows.h" /* _lread16() */
void TTY_Start()
{
/* This should be the root driver so we can ignore anything
already in the struct. */
driver.norefresh = FALSE;
driver.write = TTY_Write;
driver.getKeystroke = TTY_GetKeystroke;
}
void TTY_Write(char output, int fg, int bg, int attribute)
{
/* We can discard all extended information. */
printf("%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);
}

View File

@ -53,3 +53,6 @@
/* Define if the struct statfs is defined by <sys/mount.h> */
#undef STATFS_DEFINED_BY_SYS_MOUNT
/* Define if we want to use ncurses instead of the TTY terminal */
#undef WINE_NCURSES

View File

@ -66,6 +66,9 @@
/* Define if the struct statfs is defined by <sys/mount.h> */
#undef STATFS_DEFINED_BY_SYS_MOUNT
/* Define if we want to use ncurses instead of the TTY terminal */
#undef WINE_NCURSES
/* The number of bytes in a long long. */
#undef SIZEOF_LONG_LONG

90
include/console.h Normal file
View File

@ -0,0 +1,90 @@
/* Console.H */
/* Include file for definitions pertaining to Wine's text-console
interface.
*/
#ifndef CONSOLE_H
#define CONSOLE_H
#include "config.h"
typedef struct CONSOLE_DRIVER
{
void (*init)();
void (*close)();
void (*write)(char, int, int, int);
void (*moveCursor)(char, char);
void (*getCursorPosition)(char *, char *);
void (*getCharacterAtCursor)(char *, int *, int *, int *);
void (*clearScreen)();
/* Keyboard Functions */
int (*checkForKeystroke)(char *, char *);
void (*getKeystroke)(char *, char *);
/* Accellerator Functions (Screen) */
void (*clearWindow)(char, char, char, char, int, int);
void (*scrollUpWindow)(char, char, char, char, char, int, int);
void (*scrollDownWindow)(char, char, char, char, char, int, int);
/* Accellerator Functions (Keyboard) */
char (*getCharacter)();
/* Other functions */
void (*refresh)();
/* Other data */
int norefresh;
} CONSOLE_device;
CONSOLE_device driver; /* Global driver struct */
/* Generic defines */
void CONSOLE_Init();
void CONSOLE_Close();
void CONSOLE_Write(char out, int fg_color, int bg_color, int attribute);
void CONSOLE_MoveCursor(char row, char col);
void CONSOLE_ClearWindow(char, char, char, char, int, int);
void CONSOLE_ScrollUpWindow(char, char, char, char, char, int, int);
void CONSOLE_ScrollDownWindow(char, char, char, char, char, int, int);
int CONSOLE_CheckForKeystroke(char *, char*);
void CONSOLE_GetKeystroke(char *, char *);
void CONSOLE_GetCursorPosition(char *, char *);
void CONSOLE_GetCharacterAtCursor(char *, int *, int *, int *);
void CONSOLE_Refresh();
void CONSOLE_SetRefresh(int);
int CONSOLE_GetRefresh();
void CONSOLE_ClearScreen();
char CONSOLE_GetCharacter();
/* Generic Defines */
void GENERIC_Start();
void GENERIC_ClearWindow(char, char, char, char, int, int);
void GENERIC_ScrollUpWindow(char, char, char, char, char, int, int);
void GENERIC_ScrollDownWindow(char, char, char, char, char, int, int);
char GENERIC_GetCharacter();
/* TTY specific defines */
void TTY_Write(char out, int fg_color, int bg_color, int attribute);
void TTY_Start();
void TTY_GetKeystroke(char *, char *);
#ifdef WINE_NCURSES
/* ncurses defines */
void NCURSES_Write(char out, int fg_color, int bg_color, int attribute);
void NCURSES_Start();
void NCURSES_Init();
void NCURSES_Close();
int NCURSES_CheckForKeystroke(char *, char *);
void NCURSES_GetKeystroke(char *, char *);
void NCURSES_MoveCursor(char ,char);
void NCURSES_GetCursorPosition(char *, char *);
void NCURSES_GetCharacterAtCursor(char *, int *, int *, int *);
void NCURSES_Refresh();
void NCURSES_ClearScreen();
#endif /* WINE_NCURSES */
#endif /* CONSOLE_H */

View File

@ -170,7 +170,9 @@ typedef HANDLE32 *PHANDLE;
#define FL_reg(context) (*(WORD*)&EFL_reg(context))
#define SET_CFLAG(context) (EFL_reg(context) |= 0x0001)
#define RESET_CFLAG(context) (EFL_reg(context) &= 0xfffffffe)
#define RESET_CFLAG(context) (EFL_reg(context) &= ~0x0001)
#define SET_ZFLAG(context) (EFL_reg(context) |= 0x0040)
#define RESET_ZFLAG(context) (EFL_reg(context) &= ~0x0040)
#define ISV86(context) (EFL_reg(context) & 0x00020000)
#define V86BASE(context) ((context)->Dr7) /* ugly */

View File

@ -42,6 +42,7 @@
#include "task.h"
#include "debug.h"
#include "psdrv.h"
#include "console.h"
int __winelib = 1; /* Winelib run-time flag */
@ -80,6 +81,9 @@ BOOL32 MAIN_MainInit(void)
/* registry initialisation */
SHELL_LoadRegistry();
/* Set up text-mode stuff */
CONSOLE_Init();
return TRUE;
}

View File

@ -35,6 +35,7 @@
#include "version.h"
#include "winnls.h"
#include "x11drv.h"
#include "console.h"
/* when adding new languages look at ole/ole2nls.c
* for proper iso name and Windows code (add 0x0400
@ -987,6 +988,7 @@ static void called_at_exit(void)
WINSOCK_Shutdown();
/* FIXME: should check for other processes or threads */
DeleteCriticalSection( HEAP_SystemLock );
CONSOLE_Close();
}
static int WINE_X11_ErrorHandler(Display *display,XErrorEvent *error_evt)