mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Initial code for the VT-100 terminal emulator that runs in the W32
subsystem and connects to the PSXSS.EXE (WIP). svn path=/trunk/; revision=2732
This commit is contained in:
parent
8571b1561a
commit
ab561cad5a
9 changed files with 3552 additions and 0 deletions
90
posix/apps/csrterm/00readme.txt
Normal file
90
posix/apps/csrterm/00readme.txt
Normal file
|
@ -0,0 +1,90 @@
|
|||
08/08/96 - John L. Miller, johnmil@cs.cmu.edu, johnmil@jprc.com
|
||||
|
||||
FILES INCLUDED:
|
||||
00readme.txt - this file
|
||||
VT100.H - Definitions for VT-100 emulator.
|
||||
VT100.C - Front end parsing code for VT-100 emulator
|
||||
CONSOLE.C - Back-end code to allow VT-100 in WinNt/Win95 console
|
||||
|
||||
Many UNIX users take terminals for granted, as something you get for free
|
||||
with the operating system. Unfortunately, this isn't the case for many
|
||||
non-unix operating systems, especially PC-based ones. After a number of
|
||||
projects, I decided it would be nice if there was source publicly available
|
||||
for doing VT-100 emulation.
|
||||
|
||||
The files included with this distribution are not a complete implementation
|
||||
of VT-100 terminal emulation, but do provide complete enough coverage to
|
||||
use many vt-100 functions over the network. For instance, its enough to
|
||||
use EMACS to edit, or to connect up to your favorite mud with ANSI color
|
||||
and graphics characters.
|
||||
|
||||
The VT-100 emulator is broken into two parts. The first is the front end,
|
||||
vt100.c and vt100.h. These files were written to be fairly device-independant,
|
||||
though admittedly if you're running under a 16-bit operating system instead
|
||||
of a 32-bit, you might need to change some of the 'int' values to 'long.'
|
||||
Otherwise, it should work 'as-is'.
|
||||
|
||||
The second part is a back-end. The back-end is responsible for doing the
|
||||
workhorse activities. The front-end parses a character stream, and decides
|
||||
whether to clear a part of the screen, or move the cursor, or switch fonts.
|
||||
Then it calls routines in the back-end to perform these activities.
|
||||
|
||||
The back-end functions are, for the most part, very straight forward, and
|
||||
quite easy to implement compared to writing a vt-100 emulator from scratch.
|
||||
CONSOLE.C is a back-end for use in console (command, dos) windows under
|
||||
Windows 95 and Windows NT. This console vt-100 emulator is also being used
|
||||
in my TINTIN-III port and kerberized encrypted telnet port.
|
||||
|
||||
|
||||
TO USE THIS VT-100 EMULATOR:
|
||||
|
||||
First, it's intended to be linked directly into source code. You'll need
|
||||
to change printf's and puts' in your source code to call vtprintf() and
|
||||
vtputs() instead. You can add additional functions to vt100.c as you see
|
||||
fit to handle other output functions like putchar() and write(). Another
|
||||
routine you may want to use is vtProcessedTextOut(), which accepts a
|
||||
buffer to output, and a count of characters in that buffer.
|
||||
|
||||
Second, you need to make sure that your source code calls vtInitVT100()
|
||||
before it does ANYTHING else. This initializes the vt-100 emulator.
|
||||
|
||||
Third, if you want to use this VT-100 emulator with anything besides
|
||||
Windows NT and Windows 95 consoles, you'll need to implement your own
|
||||
back end. The list of functions you will need to supply, as well as what
|
||||
they need to do is contained in vt100.h. The list (minus descriptions)
|
||||
is as follows:
|
||||
|
||||
int beInitVT100Terminal();
|
||||
int beAbsoluteCursor(int row, int col);
|
||||
int beOffsetCursor(int row, int column);
|
||||
int beRestoreCursor(void);
|
||||
int beSaveCursor(void);
|
||||
int beSetTextAttributes(int fore, int back);
|
||||
int beRawTextOut(char *text, int len);
|
||||
int beEraseText(int rowFrom, int colFrom, int rowTo, int colTo);
|
||||
int beDeleteText(int rowFrom, int colFrom, int rowTo, int colTo);
|
||||
int beInsertRow(int row);
|
||||
int beTransmitText(char *text, int len);
|
||||
int beAdvanceToTab(void);
|
||||
int beClearTab(int col);
|
||||
int beSetScrollingRows(int fromRow, int toRow);
|
||||
int beRingBell(void);
|
||||
int beGetTermMode();
|
||||
int beSetTermMode(int newMode);
|
||||
|
||||
For details on what each of these does, read the descriptions of each
|
||||
function included in vt100.h, and read over CONSOLE.C for examples. I've
|
||||
included copious comments in all of these files to try to make them as
|
||||
easy to use as possible.
|
||||
|
||||
In any case, it should be easier than writing a VT-100 emulator from
|
||||
scratch.
|
||||
|
||||
KNOWN BUGS -
|
||||
|
||||
o Many features of VT-100 emulation aren't implemented. This includes
|
||||
support for graphics character set 0 and many of the
|
||||
answerback functions.
|
||||
|
||||
Well, good luck!
|
||||
|
23
posix/apps/csrterm/Makefile
Normal file
23
posix/apps/csrterm/Makefile
Normal file
|
@ -0,0 +1,23 @@
|
|||
# $Id: Makefile,v 1.1 2002/03/17 22:15:39 ea Exp $
|
||||
#
|
||||
# POSIX+ Terminal Emulator that runs in the W32 subsystem.
|
||||
#
|
||||
PATH_TO_TOP=../../../..
|
||||
PATH_TO_TOP_PSX=../..
|
||||
|
||||
TARGET_NAME=csrterm
|
||||
TARGET_TYPE=program
|
||||
TARGET_APPTYPE=console
|
||||
TARGET_CFLAGS =-I$(PATH_TO_TOP_PSX)/include
|
||||
TARGET_SDKLIBS=ntdll.a kernel32.a
|
||||
TARGET_OBJECTS=\
|
||||
$(TARGET_NAME).o \
|
||||
console.o \
|
||||
vt100.o \
|
||||
$(TARGET_NAME).coff
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
||||
# EOF
|
1243
posix/apps/csrterm/console.c
Normal file
1243
posix/apps/csrterm/console.c
Normal file
File diff suppressed because it is too large
Load diff
582
posix/apps/csrterm/csrterm.c
Normal file
582
posix/apps/csrterm/csrterm.c
Normal file
|
@ -0,0 +1,582 @@
|
|||
/* $Id: csrterm.c,v 1.1 2002/03/17 22:15:39 ea Exp $
|
||||
*
|
||||
* PROJECT : ReactOS Operating System / POSIX+ Environment Subsystem
|
||||
* DESCRIPTION: CSRTERM - A DEC VT-100 terminal emulator for the PSX subsystem
|
||||
* DESCRIPTION: that runs in the Win32 subsystem.
|
||||
* COPYRIGHT : Copyright (c) 2001-2002 Emanuele Aliberti
|
||||
* LICENSE : GNU GPL v2
|
||||
* DATE : 2001-05-05
|
||||
* AUTHOR : Emanuele Aliberti <ea@iol.it>
|
||||
* NOTE : This IS a Win32 program, but will fail if the PSX subsystem
|
||||
* NOTE : is not installed. The PSX subsystem consists of two more
|
||||
* NOTE : files: PSXSS.EXE, PSXDLL.DLL.
|
||||
* WARNING : If you use this program under a real NT descendant, be
|
||||
* WARNING : sure to have disabled the PSX subsystem.
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* This software is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; see the file COPYING. If not, write
|
||||
* to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
|
||||
* MA 02139, USA.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
* 2002-03-16 EA Today it actually compiled.
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ntos.h>
|
||||
#include <psx/lpcproto.h>
|
||||
|
||||
#include "vt100.h"
|
||||
#include "csrterm.h"
|
||||
|
||||
/*** OPTIONS *********************************************************/
|
||||
|
||||
#define PRIVATE static
|
||||
|
||||
#define INPUT_QUEUE_SIZE 32
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define TRACE
|
||||
#else
|
||||
#define TRACE OutputDebugString(__FUNCTION__)
|
||||
#endif
|
||||
|
||||
/*** GLOBALS *********************************************************/
|
||||
|
||||
PRIVATE LPCSTR MyName = "CSRTERM";
|
||||
PRIVATE CSRTERM_SESSION Session;
|
||||
|
||||
/*** PRIVATE FUNCTIONS ***********************************************/
|
||||
VOID STDCALL Debug_Print (LPCSTR Format, ...)
|
||||
{
|
||||
CHAR Buffer [512];
|
||||
va_list ArgumentPointer;
|
||||
|
||||
va_start(ArgumentPointer, Format);
|
||||
vsprintf(Buffer, Format, ArgumentPointer);
|
||||
va_end(ArgumentPointer);
|
||||
OutputDebugStringA (Buffer);
|
||||
}
|
||||
/**********************************************************************
|
||||
* OutPort/2 PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Notify to PSXSS that input data is ready by sending a
|
||||
* software interrupt on the \POSIX+\SessionPort port.
|
||||
*/
|
||||
PRIVATE DWORD STDCALL OutPort (PCHAR Buffer, ULONG Size)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PSX_TERMINAL_READ TerminalRead;
|
||||
TRACE;
|
||||
if (Size > 0)
|
||||
{
|
||||
/* LPC */
|
||||
TerminalRead.Header.MessageType = LPC_NEW_MESSAGE;
|
||||
TerminalRead.PsxHeader.Context = PSX_CONNECTION_TYPE_TERMINAL;
|
||||
TerminalRead.PsxHeader.Procedure = PSX_TERMINAL_INTERRUPT;
|
||||
/* Terminal I/O */
|
||||
TerminalRead.Size = Size;
|
||||
RtlCopyMemory (TerminalRead.Buffer, Buffer, Size);
|
||||
#if 0
|
||||
Status = NtRequestWaitReplyPort (
|
||||
Session.ServerPort.Handle,
|
||||
& TerminalRead
|
||||
/* FIXME */
|
||||
);
|
||||
#endif
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
vtprintf ("%s: %s: NtRequestWaitReplyPort failed with %08x\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return Size;
|
||||
}
|
||||
/**********************************************************************
|
||||
* ProcessConnectionRequest/1 PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Initialize our data for managing the control connection
|
||||
* initiated by the PSXSS.EXE process.
|
||||
*/
|
||||
PRIVATE NTSTATUS STDCALL ProcessConnectionRequest (PPSX_MAX_MESSAGE Request)
|
||||
{
|
||||
TRACE;
|
||||
Session.SsLinkIsActive = TRUE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/**********************************************************************
|
||||
* ProcessRequest/1 PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
*/
|
||||
PRIVATE NTSTATUS STDCALL ProcessRequest (PPSX_MAX_MESSAGE Request)
|
||||
{
|
||||
TRACE;
|
||||
/* TODO */
|
||||
vtprintf("TEST VT-100\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/**********************************************************************
|
||||
* PsxSessionPortListener/1 PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Manage messages from the PSXSS, that is LPC messages we get
|
||||
* from the PSXSS process to our \POSIX+\Sessions\P<pid> port.
|
||||
*
|
||||
* NOTE
|
||||
* This function is the thread 's entry point created in
|
||||
* CreateSessionObiects().
|
||||
*/
|
||||
PRIVATE DWORD STDCALL PsxSessionPortListener (LPVOID Arg)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LPC_TYPE RequestType;
|
||||
PSX_MAX_MESSAGE Request;
|
||||
PPSX_MAX_MESSAGE Reply = NULL;
|
||||
BOOL NullReply = FALSE;
|
||||
|
||||
TRACE;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
Reply = NULL;
|
||||
while (!NullReply)
|
||||
{
|
||||
Status = NtReplyWaitReceivePort (
|
||||
Session.Port.Handle,
|
||||
0,
|
||||
(PLPC_MESSAGE) Reply,
|
||||
(PLPC_MESSAGE) & Request
|
||||
);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
RequestType = PORT_MESSAGE_TYPE(Request);
|
||||
switch (RequestType)
|
||||
{
|
||||
case LPC_CONNECTION_REQUEST:
|
||||
ProcessConnectionRequest (& Request);
|
||||
NullReply = TRUE;
|
||||
continue;
|
||||
case LPC_CLIENT_DIED:
|
||||
case LPC_PORT_CLOSED:
|
||||
case LPC_DEBUG_EVENT:
|
||||
case LPC_ERROR_EVENT:
|
||||
case LPC_EXCEPTION:
|
||||
NullReply = TRUE;
|
||||
continue;
|
||||
default:
|
||||
if (RequestType != LPC_REQUEST)
|
||||
{
|
||||
NullReply = TRUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Reply = & Request;
|
||||
Reply->PsxHeader.Status = ProcessRequest (& Request);
|
||||
NullReply = FALSE;
|
||||
}
|
||||
if ((STATUS_INVALID_HANDLE == Status) ||
|
||||
(STATUS_OBJECT_TYPE_MISMATCH == Status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
Session.SsLinkIsActive = FALSE;
|
||||
TerminateThread (GetCurrentThread(), Status);
|
||||
}
|
||||
/**********************************************************************
|
||||
* CreateSessionObiects/1 PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create the session objects which are mananged by our side:
|
||||
*
|
||||
* \POSIX+\Sessions\P<pid>
|
||||
* \POSIX+\Sessions\D<pid>
|
||||
*/
|
||||
PRIVATE NTSTATUS STDCALL CreateSessionObjects (DWORD Pid)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG Id = 0;
|
||||
OBJECT_ATTRIBUTES Oa;
|
||||
|
||||
TRACE;
|
||||
|
||||
|
||||
/* Critical section */
|
||||
Status = RtlInitializeCriticalSection (& Session.Lock);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
vtprintf (
|
||||
"%s: %s: RtlInitializeCriticalSection failed with %08x\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
/* Port and port management thread */
|
||||
swprintf (
|
||||
Session.Port.NameBuffer,
|
||||
PSX_NS_SESSION_PORT_TEMPLATE,
|
||||
PSX_NS_SUBSYSTEM_DIRECTORY_NAME,
|
||||
PSX_NS_SESSION_DIRECTORY_NAME,
|
||||
Pid
|
||||
);
|
||||
RtlInitUnicodeString (& Session.Port.Name, Session.Port.NameBuffer);
|
||||
InitializeObjectAttributes (& Oa, & Session.Port.Name, 0, NULL, NULL);
|
||||
Status = NtCreatePort (& Session.Port.Handle, & Oa, 0, 0, 0x10000);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlDeleteCriticalSection (& Session.Lock);
|
||||
vtprintf ("%s: %s: NtCreatePort failed with %08x\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
Session.Port.Thread.Handle =
|
||||
CreateThread (
|
||||
NULL,
|
||||
0,
|
||||
PsxSessionPortListener,
|
||||
0,
|
||||
CREATE_SUSPENDED,
|
||||
& Session.Port.Thread.Id
|
||||
);
|
||||
if ((HANDLE) NULL == Session.Port.Thread.Handle)
|
||||
{
|
||||
Status = (NTSTATUS) GetLastError();
|
||||
NtClose (Session.Port.Handle);
|
||||
RtlDeleteCriticalSection (& Session.Lock);
|
||||
vtprintf ("%s: %s: CreateThread failed with %d\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
/* Section */
|
||||
swprintf (
|
||||
Session.Section.NameBuffer,
|
||||
PSX_NS_SESSION_DATA_TEMPLATE,
|
||||
PSX_NS_SUBSYSTEM_DIRECTORY_NAME,
|
||||
PSX_NS_SESSION_DIRECTORY_NAME,
|
||||
Pid
|
||||
);
|
||||
RtlInitUnicodeString (& Session.Section.Name, Session.Section.NameBuffer);
|
||||
InitializeObjectAttributes (& Oa, & Session.Section.Name, 0, 0, 0);
|
||||
Status = NtCreateSection (
|
||||
& Session.Section.Handle,
|
||||
0, /* DesiredAccess */
|
||||
& Oa,
|
||||
NULL, /* SectionSize OPTIONAL */
|
||||
PAGE_READWRITE, /* Protect 4 */
|
||||
SEC_COMMIT, /* Attributes */
|
||||
0 /* FileHandle: 0=pagefile.sys */
|
||||
);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
NtClose (Session.Port.Handle);
|
||||
NtTerminateThread (Session.Port.Thread.Handle, Status);
|
||||
RtlDeleteCriticalSection (& Session.Lock);
|
||||
vtprintf ("%s: %s: NtCreateSection failed with %08x\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
Session.Section.BaseAddress = NULL;
|
||||
Session.Section.ViewSize = 0;
|
||||
Status = NtMapViewOfSection (
|
||||
Session.Section.Handle,
|
||||
NtCurrentProcess(),
|
||||
& Session.Section.BaseAddress,
|
||||
0, /* ZeroBits */
|
||||
0, /* Commitsize */
|
||||
0, /* SectionOffset */
|
||||
& Session.Section.ViewSize,
|
||||
ViewUnmap,
|
||||
0, /* AllocationType */
|
||||
PAGE_READWRITE /* Protect 4 */
|
||||
);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
NtClose (Session.Port.Handle);
|
||||
NtTerminateThread (Session.Port.Thread.Handle, Status);
|
||||
NtClose (Session.Section.Handle);
|
||||
RtlDeleteCriticalSection (& Session.Lock);
|
||||
vtprintf ("%s: %s: NtMapViewOfSection failed with %08x\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CreateTerminalToPsxChannel/0 PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
*/
|
||||
PRIVATE NTSTATUS STDCALL CreateTerminalToPsxChannel (VOID)
|
||||
{
|
||||
PSX_CONNECT_PORT_DATA ConnectData;
|
||||
ULONG ConnectDataLength = sizeof ConnectData;
|
||||
SECURITY_QUALITY_OF_SERVICE Sqos;
|
||||
NTSTATUS Status;
|
||||
|
||||
TRACE;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the connection data object before
|
||||
* calling PSXSS.
|
||||
*/
|
||||
ConnectData.ConnectionType = PSX_CONNECTION_TYPE_TERMINAL;
|
||||
ConnectData.Version = PSX_LPC_PROTOCOL_VERSION;
|
||||
/*
|
||||
* Try connecting to \POSIX+\SessionPort.
|
||||
*/
|
||||
Status = NtConnectPort (
|
||||
& Session.ServerPort.Handle,
|
||||
& Session.ServerPort.Name,
|
||||
& Sqos,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
& ConnectData,
|
||||
& ConnectDataLength
|
||||
);
|
||||
if (STATUS_SUCCESS != Status)
|
||||
{
|
||||
vtprintf ("%s: %s: NtConnectPort failed with %08x\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
Session.Identifier = ConnectData.PortIdentifier;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* InitializeSsIoChannel PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create our objects in the system name space
|
||||
* (CreateSessionObjects) and then connect to the session port
|
||||
* (CreateControChannel).
|
||||
*/
|
||||
PRIVATE NTSTATUS STDCALL InitializeSsIoChannel (VOID)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
DWORD Pid = GetCurrentProcessId();
|
||||
|
||||
TRACE;
|
||||
|
||||
|
||||
Status = CreateSessionObjects (Pid);
|
||||
if (STATUS_SUCCESS != Status)
|
||||
{
|
||||
vtprintf ("%s: %s: CreateSessionObjects failed with %08x\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
Status = CreateTerminalToPsxChannel ();
|
||||
if (STATUS_SUCCESS != Status)
|
||||
{
|
||||
vtprintf ("%s: %s: CreateTerminalToPsxChannel failed with %08x\n",
|
||||
MyName, __FUNCTION__, Status);
|
||||
return Status;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/**********************************************************************
|
||||
* PsxCreateLeaderProcess/1 PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Create a new PSXSS process.
|
||||
*/
|
||||
PRIVATE NTSTATUS STDCALL PsxCreateLeaderProcess (char * Command)
|
||||
{
|
||||
|
||||
TRACE;
|
||||
|
||||
if (NULL == Command)
|
||||
{
|
||||
Command = "/bin/sh";
|
||||
}
|
||||
/* TODO: request PSXSS to init the process slot */
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
/**********************************************************************
|
||||
* PrintInformationProcess/0
|
||||
*
|
||||
* DESCRIPTION
|
||||
*/
|
||||
PRIVATE VOID STDCALL PrintInformationProcess (VOID)
|
||||
{
|
||||
|
||||
TRACE;
|
||||
|
||||
vtputs ("Leader:");
|
||||
vtprintf (" UniqueProcess %08x\n", Session.Client.UniqueProcess);
|
||||
vtprintf (" UniqueThread %08x\n", Session.Client.UniqueThread);
|
||||
}
|
||||
/**********************************************************************
|
||||
* PostMortem/0
|
||||
*
|
||||
* DESCRIPTION
|
||||
*/
|
||||
PRIVATE INT STDCALL PostMortem (VOID)
|
||||
{
|
||||
DWORD ExitCode;
|
||||
|
||||
TRACE;
|
||||
|
||||
|
||||
PrintInformationProcess ();
|
||||
if (TRUE == GetExitCodeProcess (Session.Client.UniqueProcess, & ExitCode))
|
||||
{
|
||||
vtprintf (" ExitCode %d\n", ExitCode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**********************************************************************
|
||||
* InputTerminalEmulator/0
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Process user terminal input.
|
||||
*
|
||||
* NOTE
|
||||
* This code is run in the main thread.
|
||||
*/
|
||||
PRIVATE BOOL STDCALL InputTerminalEmulator (VOID)
|
||||
{
|
||||
HANDLE StandardInput;
|
||||
INPUT_RECORD InputRecord [INPUT_QUEUE_SIZE];
|
||||
DWORD NumberOfEventsRead = 0;
|
||||
INT CurrentEvent;
|
||||
|
||||
|
||||
TRACE;
|
||||
|
||||
StandardInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
if (INVALID_HANDLE_VALUE == StandardInput)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
while ((TRUE == Session.SsLinkIsActive) &&
|
||||
ReadConsoleInput (
|
||||
StandardInput,
|
||||
InputRecord,
|
||||
(sizeof InputRecord) / sizeof (INPUT_RECORD),
|
||||
& NumberOfEventsRead
|
||||
))
|
||||
{
|
||||
for ( CurrentEvent = 0;
|
||||
(CurrentEvent < NumberOfEventsRead);
|
||||
CurrentEvent ++
|
||||
)
|
||||
{
|
||||
switch (InputRecord [CurrentEvent].EventType)
|
||||
{
|
||||
case KEY_EVENT:
|
||||
OutPort (& InputRecord [CurrentEvent].Event.KeyEvent.uChar.AsciiChar, 1);
|
||||
break;
|
||||
case MOUSE_EVENT:
|
||||
/* TODO: send a sequence of move cursor codes */
|
||||
/* InputRecord [CurrentEvent].Event.MouseEvent; */
|
||||
break;
|
||||
case WINDOW_BUFFER_SIZE_EVENT:
|
||||
/* TODO: send a SIGWINCH signal to the leader process. */
|
||||
/* InputRecord [CurrentEvent].Event.WindowBufferSizeEvent.dwSize; */
|
||||
break;
|
||||
/* Next events should be ignored. */
|
||||
case MENU_EVENT:
|
||||
vtprintf ("%s: %s: MENU_EVENT received from CSRSS\n", MyName, __FUNCTION__);
|
||||
case FOCUS_EVENT:
|
||||
vtprintf ("%s: %s: FOCUS_EVENT received from CSRSS\n", MyName, __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
NumberOfEventsRead = 0;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
/**********************************************************************
|
||||
* Startup/1
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Initialize the program.
|
||||
*/
|
||||
PRIVATE VOID STDCALL Startup (LPSTR Command)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
DWORD ThreadId;
|
||||
|
||||
|
||||
TRACE;
|
||||
|
||||
/* PSX process info */
|
||||
Session.Client.UniqueProcess = INVALID_HANDLE_VALUE;
|
||||
Session.Client.UniqueThread = INVALID_HANDLE_VALUE;
|
||||
/* Initialize the VT-100 emulator */
|
||||
vtInitVT100 ();
|
||||
/* Connect to PSXSS */
|
||||
Status = InitializeSsIoChannel ();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
vtprintf ("%s: failed to connect to PSXSS (Status=%08x)!\n",
|
||||
MyName, Status);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
/* Create the leading process for this session */
|
||||
Status = PsxCreateLeaderProcess (Command);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
vtprintf ("%s: failed to create the PSX process (Status=%08x)!\n",
|
||||
MyName, Status);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
/**********************************************************************
|
||||
* Shutdown/0 PRIVATE
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Shutdown the program.
|
||||
*/
|
||||
PRIVATE INT STDCALL Shutdown (VOID)
|
||||
{
|
||||
|
||||
TRACE;
|
||||
|
||||
/* TODO: try exiting cleanly: close any open resource */
|
||||
/* TODO: notify PSXSS the session is terminating */
|
||||
RtlDeleteCriticalSection (& Session.Lock);
|
||||
return PostMortem ();
|
||||
}
|
||||
/**********************************************************************
|
||||
*
|
||||
* ENTRY POINT PUBLIC
|
||||
*
|
||||
*********************************************************************/
|
||||
int main (int argc, char * argv [])
|
||||
{
|
||||
|
||||
TRACE;
|
||||
|
||||
Startup (argv[1]); /* Initialization */
|
||||
InputTerminalEmulator (); /* Process user input */
|
||||
return Shutdown ();
|
||||
}
|
||||
/* EOF */
|
53
posix/apps/csrterm/csrterm.h
Normal file
53
posix/apps/csrterm/csrterm.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef _CSRTERM_H
|
||||
#define _CSRTERM_H
|
||||
|
||||
/* PSX session: CSR terminal emulator side */
|
||||
|
||||
#define NAME_BUFFER_SIZE 64
|
||||
|
||||
typedef struct _PSXSS_PORT
|
||||
{
|
||||
UNICODE_STRING Name;
|
||||
WCHAR NameBuffer [NAME_BUFFER_SIZE];
|
||||
HANDLE Handle;
|
||||
|
||||
} PSXSS_PORT, * PPSXSS_PORT;
|
||||
|
||||
typedef struct _CSRTERM_SESSION_PORT
|
||||
{
|
||||
UNICODE_STRING Name;
|
||||
WCHAR NameBuffer [NAME_BUFFER_SIZE];
|
||||
HANDLE Handle;
|
||||
struct {
|
||||
HANDLE Handle;
|
||||
DWORD Id;
|
||||
} Thread;
|
||||
|
||||
} CSRTERM_SESSION_PORT;
|
||||
|
||||
typedef struct _CSRTERM_SESSION_SECTION
|
||||
{
|
||||
UNICODE_STRING Name;
|
||||
WCHAR NameBuffer [NAME_BUFFER_SIZE];
|
||||
HANDLE Handle;
|
||||
ULONG Size;
|
||||
PVOID BaseAddress;
|
||||
ULONG ViewSize;
|
||||
|
||||
} CSRTERM_SESSION_SECTION;
|
||||
|
||||
typedef struct _CSRTERM_SESSION
|
||||
{
|
||||
ULONG Identifier; /* PortID for ServerPort in PSXSS */
|
||||
PSXSS_PORT ServerPort; /* \POSIX+\SessionPort */
|
||||
CSRTERM_SESSION_PORT Port; /* \POSIX+\Sessions\P<pid> */
|
||||
CSRTERM_SESSION_SECTION Section; /* \POSIX+\Sessions\D<pid> */
|
||||
CLIENT_ID Client;
|
||||
CRITICAL_SECTION Lock;
|
||||
BOOL SsLinkIsActive;
|
||||
|
||||
} CSRTERM_SESSION, * PCSRTERM_SESSION;
|
||||
|
||||
#define LOCK_SESSION RtlEnterCriticalSection(& Session.Lock)
|
||||
#define UNLOCK_SESSION RtlLeaveCriticalSection(& Session.Lock)
|
||||
#endif /* ndef _CSRTERM_H */
|
38
posix/apps/csrterm/csrterm.rc
Normal file
38
posix/apps/csrterm/csrterm.rc
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "CSR Terminal Emulator for POSIX+\0"
|
||||
VALUE "FileVersion", RES_STR_FILE_VERSION
|
||||
VALUE "InternalName", "csrterm\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "csrterm.exe\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
79
posix/apps/csrterm/readme.txt
Normal file
79
posix/apps/csrterm/readme.txt
Normal file
|
@ -0,0 +1,79 @@
|
|||
$Id: readme.txt,v 1.1 2002/03/17 22:15:39 ea Exp $
|
||||
|
||||
csrterm - a CSR client terminal emulator for the POSIX+ subsystem
|
||||
|
||||
SYNOPSYS
|
||||
|
||||
csrterm [program]
|
||||
|
||||
program program to be run in the terminal; if none is given,
|
||||
the shell for the current user (W32 session's) is
|
||||
used.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
csrterm emulates a DEC VT-100 terminal (on top of the CSRSS
|
||||
subsystem, hence the name) which is the controlling terminal
|
||||
for a process [program] running in the context of the PSX
|
||||
subsystem. csrterm is a Win32 console application, not a PSX
|
||||
application. The process created by the PSX subsystem on behalf
|
||||
of csrterm is not the child of the csrterm instance that
|
||||
requested it. csrterm simply performs terminal I/O in the CSRSS
|
||||
world (the W32 world!) for [program].
|
||||
|
||||
NOTES
|
||||
|
||||
The role of csrterm is creating a session in the PSX subsystem
|
||||
managing any I/O for it. This is how it works:
|
||||
|
||||
1. csrterm creates two well known named objects in the system
|
||||
name space that will allow the PSX subsystem server to build
|
||||
the I/O channel for the session. To let the PSX subsystem
|
||||
process recognize the objects, they contain a numeric suffix
|
||||
which is the process identifier (n) the system gives to each
|
||||
instance of csrterm:
|
||||
|
||||
\POSIX+\Session\Pn LPC port (IPC rendez-vous object)
|
||||
\POSIX+\Session\Dn section (shared memory object)
|
||||
|
||||
csrterm also creates a new thread to manage the calls though
|
||||
the LPC port. Port Pn is used by the subsystem to control the
|
||||
terminal which csrterm emulates.
|
||||
|
||||
2. csrterm connects to the PSX subsystem session port
|
||||
|
||||
\POSIX+\SessionPort
|
||||
|
||||
and asks the subsystem to create a new session.
|
||||
|
||||
3. The PSX subsystem, if it decides to accept the request, creates
|
||||
a new session for that calling instance of csrterm (n), and in
|
||||
turn connects back to the terminal control port
|
||||
|
||||
\POSIX+\Session\Pn
|
||||
|
||||
4. When csrterm makes the PSX subsystem create the new session, it
|
||||
also tells the subsystem what program should be the session
|
||||
leader process. The PSX subsystem creates that process (the
|
||||
image file to start must be marked IMAGE_SUBSYSTEM_POSIX_GUI or
|
||||
IMAGE_SUBSYSTEM_POSIX_CUI).
|
||||
|
||||
5. The requested process [program] runs in the context of the
|
||||
PSX subsystem and performs any terminal I/O via the channel
|
||||
csrterm and the PSX susbstem created.
|
||||
|
||||
REVISIONS
|
||||
2001-05-05 created
|
||||
2002-03-03 simplified
|
||||
|
||||
AUTHOR
|
||||
|
||||
Emanuele Aliberti <ea@iol.it>
|
||||
|
||||
CREDITS
|
||||
|
||||
John L. Miller (johnmil@cs.cmu.edu, johnmil@jprc.com) code for
|
||||
a basic VT-100 emulator for Win32 consoles is used to process
|
||||
tc* calls output.
|
||||
|
||||
EOF
|
1124
posix/apps/csrterm/vt100.c
Normal file
1124
posix/apps/csrterm/vt100.c
Normal file
File diff suppressed because it is too large
Load diff
320
posix/apps/csrterm/vt100.h
Normal file
320
posix/apps/csrterm/vt100.h
Normal file
|
@ -0,0 +1,320 @@
|
|||
/* vt100.h
|
||||
*
|
||||
* AUTHOR: John L. Miller, johnmil@cs.cmu.edu / johnmil@jprc.com
|
||||
* DATE: 8/4/96
|
||||
*
|
||||
* Copyright (c) 1996 John L. Miller
|
||||
*
|
||||
* Full permission is granted to use, modify and distribute
|
||||
* this code, provided:
|
||||
* 1) This comment field is included in its entirity
|
||||
* 2) No money is charged for any work including or based on
|
||||
* portions of this code.
|
||||
*
|
||||
* If you're a nice person and find this useful, I'd appreciate a
|
||||
* note letting me know about it. e-mail is usually what spurs me
|
||||
* on to improve and support software I've written.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* This identifier should be spit back to the computer when a terminal
|
||||
* id is requested.
|
||||
*/
|
||||
#define ANSWERBACK_MESSAGE "vt100"
|
||||
|
||||
/* Various terminal-related modes Entries are as follows:
|
||||
* Identification esc. ID If set, if clear
|
||||
*/
|
||||
|
||||
/* Keyboard action 2 Locked Unlocked */
|
||||
#define CAPS_MODE 0x00000001
|
||||
/* Insertion 4 Insert Overwrite */
|
||||
#define INSERT_MODE 0x00000002
|
||||
/* Send - Receive 12 Full Echo */
|
||||
#define FULLDUPLEX_MODE 0x00000004
|
||||
/* Line feed/New line 20 New line Line feed */
|
||||
#define NEWLINE_MODE 0x00000008
|
||||
|
||||
|
||||
#define NUM_TERM_ATTR_MODES 9 /* We only track eight '?' escape sequences */
|
||||
|
||||
/* Cursor key ?1 Application Cursor */
|
||||
#define CURSORAPPL_MODE 0x00000010
|
||||
/* ANSI/VT52 ?2 ANSI VT52 */
|
||||
#define ANSI_MODE 0x00000020
|
||||
/* Column ?3 132 80 */
|
||||
#define COL132_MODE 0x00000040
|
||||
/* Scrolling ?4 Smooth Jump */
|
||||
#define SMOOTHSCROLL_MODE 0x00000080
|
||||
/* Screen ?5 Reverse Normal */
|
||||
#define REVSCREEN_MODE 0x00000100
|
||||
/* Origin ?6 Relative Absolute */
|
||||
#define ORIGINREL_MODE 0x00000200
|
||||
/* Wraparound ?7 Wrap Truncate */
|
||||
#define WRAP_MODE 0x00000400
|
||||
/* Auto key repeat ?8 Repeating No repeat */
|
||||
#define REPEAT_MODE 0x00000800
|
||||
|
||||
|
||||
/* Print form feed ?18 Yes No */
|
||||
#define PRINTFF_MODE 0x00001000
|
||||
/* Print extent ?19 Full screen Scrolling region */
|
||||
#define PRINTFULLSCR_MODE 0x00002000
|
||||
/* Keypad application 'Esc =' numeric 'Esc >' */
|
||||
#define KEYPADNUMERIC_MODE 0x00004000
|
||||
/* default mode that we start the emulator with */
|
||||
#define DEFAULT_MODE (NEWLINE_MODE|ANSI_MODE|REPEAT_MODE)
|
||||
|
||||
/* This constant is VERY important - the size of the buffer for
|
||||
* unprocessed vt-100 prints!
|
||||
*/
|
||||
#define MAXVTBUFLEN 4096
|
||||
|
||||
/* Constants used in place of actual row and column numbers
|
||||
* for the cursor movement and text erasing and deleting functions.
|
||||
*/
|
||||
#define CUR_ROW -999
|
||||
#define CUR_COL -999
|
||||
#define ALL_TABS -1999
|
||||
|
||||
#define LEFT_EDGE 0
|
||||
#define RIGHT_EDGE 12000
|
||||
#define TOP_EDGE 0
|
||||
#define BOTTOM_EDGE 12000
|
||||
|
||||
/* Text attribute definitions; color, font, bold. */
|
||||
#define NUM_SC_ATTRIBUTES 11
|
||||
|
||||
#define SC_RED 0x0001
|
||||
#define SC_GREEN 0x0002
|
||||
#define SC_BLUE 0x0004
|
||||
#define SC_BOLD 0x0010
|
||||
#define SC_UL 0x0020 /* Underlined */
|
||||
#define SC_BL 0x0040 /* Blinking */
|
||||
#define SC_RV 0x0080 /* Reverse video */
|
||||
#define SC_ASCII 0x0100 /* Normal ASCII (USASCII) */
|
||||
#define SC_G0 0x0200 /* graphics set G0 */
|
||||
#define SC_G1 0x0400 /* Graphics set G1 */
|
||||
#define SC_GRAPHICS 0x0800 /* Good question */
|
||||
|
||||
|
||||
/* forward variable declarations */
|
||||
|
||||
extern int termAttrMode[NUM_TERM_ATTR_MODES];
|
||||
extern int alltermAttrModes;
|
||||
|
||||
|
||||
/* prototypes from vt100.c */
|
||||
|
||||
/* functions meant for use outside of the emulator */
|
||||
|
||||
int vtputs(char *f);
|
||||
int vtprintf(char *format, ...);
|
||||
int vtInitVT100(void);
|
||||
int vtProcessedTextOut(char *cbuf, int count);
|
||||
|
||||
|
||||
/* Prototype for functions which MUST BE SUPPLIED BY THE BACK END!!! */
|
||||
|
||||
/* Back-end specific initialization is performed in this function.
|
||||
* this is gauranteed to be called before any other requests are made
|
||||
* of the back end.
|
||||
*/
|
||||
|
||||
/* beInitVT100Terminal() -
|
||||
*
|
||||
* This function is called by the VT100 emulator as soon as the
|
||||
* front-end terminal is initialized. It's responsible for setting
|
||||
* initial state of the terminal, and initing our many wacky variables.
|
||||
*/
|
||||
int beInitVT100Terminal();
|
||||
|
||||
|
||||
/* beAbsoluteCursor -
|
||||
*
|
||||
* Given an input row and column, move the cursor to the
|
||||
* absolute screen coordinates requested. Note that if the
|
||||
* display window has scrollbars, the column is adjusted
|
||||
* to take that into account, but the row is not. This allows
|
||||
* for large scrollback in terminal windows.
|
||||
*
|
||||
* ROW must be able to accept CUR_ROW, TOP_EDGE, BOTTOM_EDGE,
|
||||
* or a row number.
|
||||
*
|
||||
* COLUMN must be able to accept CUR_COL, LEFT_EDGE, RIGHT_EDGE,
|
||||
* or a column number.
|
||||
*/
|
||||
int beAbsoluteCursor(int row, int col);
|
||||
|
||||
|
||||
/* beOffsetCursor -
|
||||
*
|
||||
* Given an input row and column offset, move the cursor by that
|
||||
* many positions. For instance, row=0 and column=-1 would move
|
||||
* the cursor left a single column.
|
||||
*
|
||||
* If the cursor can't move the requested amount, results are
|
||||
* unpredictable.
|
||||
*/
|
||||
int beOffsetCursor(int row, int column);
|
||||
|
||||
|
||||
/* beRestoreCursor -
|
||||
*
|
||||
* Saved cursor position should be stored in a static
|
||||
* variable in the back end. This function restores the
|
||||
* cursor to the position stored in that variable.
|
||||
*/
|
||||
int beRestoreCursor(void);
|
||||
|
||||
|
||||
/* beSaveCursor -
|
||||
*
|
||||
* The back-end should maintain a static variable with the
|
||||
* last STORED cursor position in it. This function replaces
|
||||
* the contents of that variable with the current cursor position.
|
||||
* The cursor may be restored to this position by using the
|
||||
* beRestoreCursor function.
|
||||
*/
|
||||
int beSaveCursor(void);
|
||||
|
||||
|
||||
/* beGetTextAttributes -
|
||||
*
|
||||
* given a pointer to 'fore'ground and 'back'ground ints,
|
||||
* fill them with a device-independant description of the
|
||||
* current foreground and background colors, as well as any
|
||||
* font information in the foreground variable.
|
||||
*/
|
||||
int beGetTextAttributes(int *fore, int *back);
|
||||
|
||||
|
||||
/* beSetTextAttributes -
|
||||
*
|
||||
* Given a foreground and a background device independant (SC) color and font
|
||||
* specification, apply these to the display, and save the state in the
|
||||
* static screen variables.
|
||||
*
|
||||
* Note that many font-specific constants (bold/underline/reverse, G0/G1/ASCII)
|
||||
* are stored ONLY in the foreground specification.
|
||||
*/
|
||||
int beSetTextAttributes(int fore, int back);
|
||||
|
||||
|
||||
/* beRawTextOut-
|
||||
*
|
||||
* The name of this function is misleading. Given a pointer to
|
||||
* ascii text and a count of bytes to print, print them to the
|
||||
* display device. If wrapping is enabled, wrap text. If there is a
|
||||
* scrolling region set and the cursor is in it,
|
||||
* scroll only within that region. 'beRawTextOut' means that it's guaranteed
|
||||
* not to have control sequences within the text.
|
||||
*/
|
||||
int beRawTextOut(char *text, int len);
|
||||
|
||||
|
||||
/* beEraseText -
|
||||
*
|
||||
* Given a 'from' and a 'to' position in display coordinates,
|
||||
* this function will fill in all characters between the two
|
||||
* (inclusive) with spaces. Note that the coordinates do NOT
|
||||
* specify a rectangle. erasing from (1,1) to (2,2) erases
|
||||
* all of the first row, and the first two characters of the
|
||||
* second.
|
||||
*
|
||||
* Note that this routine must be able to handle TOP_EDGE,
|
||||
* BOTTOM_EDGE, LEFT_EDGE, RIGHT_EDGE, CUR_ROW, and CUR_COL
|
||||
* in the appropriate parameters.
|
||||
*/
|
||||
int beEraseText(int rowFrom, int colFrom, int rowTo, int colTo);
|
||||
|
||||
|
||||
/* beDeleteText -
|
||||
*
|
||||
* Given a screen cursor 'from' and 'to' position, this function
|
||||
* will delete all text between the two. Text will be scrolled
|
||||
* up as appropriate to fill the deleted space. Note that, as in
|
||||
* beEraseText, the two coordinates don't specify a rectangle, but
|
||||
* rather a starting position and ending position. In other words,
|
||||
* deleting from (1,1) to (2,2) should move the text from (2,3) to the
|
||||
* end of the second row to (1,1), move line 3 up to line 2, and so on.
|
||||
*
|
||||
* This function must be able to process TOP_EDGE, BOTTOM_EDGE, LEFT_EDGE,
|
||||
* RIGHT_EDGE, CUR_ROW, and CUR_COL specifications in the appropriate
|
||||
* variables as well as regular row and column specifications.
|
||||
*/
|
||||
int beDeleteText(int rowFrom, int colFrom, int rowTo, int colTo);
|
||||
|
||||
|
||||
/* beInsertRow -
|
||||
*
|
||||
* Given a row number or CUR_ROW, TOP_EDGE or BOTTOM_EDGE as an input,
|
||||
* this function will scroll all text from the current row down down by one,
|
||||
* and create a blank row under the cursor.
|
||||
*/
|
||||
int beInsertRow(int row);
|
||||
|
||||
|
||||
/* beTransmitText -
|
||||
*
|
||||
* Given a pointer to text and byte count, this routine should transmit data
|
||||
* to whatever host made the request it's responding to. Typically this routin
|
||||
* should transmit data as though the user had typed it in.
|
||||
*/
|
||||
int beTransmitText(char *text, int len);
|
||||
|
||||
|
||||
/* beAdvanceToTab -
|
||||
*
|
||||
* This routine will destructively advance the cursor to the
|
||||
* next set tab, or to the end of the line if there are no
|
||||
* more tabs to the right of the cursor.
|
||||
*/
|
||||
|
||||
int beAdvanceToTab(void);
|
||||
|
||||
|
||||
/* beClearTab -
|
||||
*
|
||||
* This function accepts a constant, and will try to clear tabs
|
||||
* appropriately. Its argument is either
|
||||
* ALL_TABS, meaning all tabs should be removed
|
||||
* CUR_COL, meaning the tab in the current column should be wiped, or
|
||||
* a column value, meaning if there's a tab there it should be wiped.
|
||||
*
|
||||
*/
|
||||
int beClearTab(int col);
|
||||
|
||||
|
||||
/* beSetScrollingRows -
|
||||
*
|
||||
* Given a pair of row numbers, this routine will set the scrolling
|
||||
* rows to those values. Note that this routine will accept
|
||||
* TOP_ROW and BOTTOM_ROW as values, meaning that scrolling should
|
||||
* be enabled for the entire display, regardless of resizing.
|
||||
*/
|
||||
int beSetScrollingRows(int fromRow, int toRow);
|
||||
|
||||
|
||||
/* beRingBell -
|
||||
*
|
||||
* Ring the system bell once.
|
||||
*/
|
||||
int beRingBell(void);
|
||||
|
||||
|
||||
/* beGetTermMode -
|
||||
*
|
||||
* Return the value of conTermMode, which is the terminal settings which
|
||||
* can be queried/set by <esc>[?#h/l.
|
||||
*/
|
||||
int beGetTermMode();
|
||||
|
||||
|
||||
/* beSetTermMode -
|
||||
*
|
||||
* Set the terminal as requested, assuming we can. Right now we only handle a
|
||||
* couple of the possible flags, but we store many of the others.
|
||||
*/
|
||||
int beSetTermMode(int newMode);
|
Loading…
Reference in a new issue