home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
xaio1.exe
/
XAIOC.C
< prev
next >
Wrap
Text File
|
1994-09-07
|
22KB
|
797 lines
/****************************************************************************
** File: XAIOC.C
**
** Desc: Sample AIO ANSI terminal emulator for NetWare NLM platform.
**
** Disclaimer:
**
** Novell, Inc. makes no representations or warranties with respect to
** any NetWare software, and specifically disclaims any express or
** implied warranties of merchantability, title, or fitness for a
** particular purpose.
**
** Distribution of any NetWare software is forbidden without the
** express written consent of Novell, Inc. Further, Novell reserves
** the right to discontinue distribution of any NetWare software.
**
** Novell is not responsible for lost profits or revenue, loss of use
** of the software, loss of data, costs of re-creating lost data, the
** cost of any substitute equipment or program, or claims by any party
** other than you. Novell strongly recommends a backup be made before
** any software is installed. Technical support for this software
** may be provided at the discretion of Novell.
**
** QMK386 options used:
**
** /ia - AIO support
**
** Programmers:
**
** Ini Who Firm
** -----------------------------------------------------------------------
** ABJ Adam B. Jerome Novell Developer Support.
**
** History:
**
** When Who What
** -----------------------------------------------------------------------
** 08-04-94 ABJ First code.
*/
/****************************************************************************
** Include headers, function prototypes, macros, etc.
*/
/*------------------------------------------------------------------------
** ANSI
*/
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <string.h>
#include <ctype.h>
/*------------------------------------------------------------------------
** Platform specific
*/
#include <conio.h>
/*------------------------------------------------------------------------
** NetWare NLM
*/
#include <aio.h>
/*------------------------------------------------------------------------
** This module.
*/
#define BUFFER_SIZE 128
#define KEY_F1 315
#define KEY_F2 316
/****************************************************************************
** Global storage.
*/
int NLM_ansiMode=(-1L); /* Enable ANSI mode (-1=YES, 0=NO). */
/****************************************************************************
** Get the curser position.
**
** Generally returns row range 0:24 and column range 0:79; but can return
** row 25 and column 0, which indicates that the next character sent to the
** screen will cause a horizonal scroll.
*/
void GetCursorPosition(WORD *row, WORD *col)
{
GetPositionOfOutputCursor(row, col);
return;
}
/****************************************************************************
** Set the curser position.
*/
void SetCursorPosition(WORD row, WORD col)
{
/*------------------------------------------------------------------------
** Bounds checking.
**
** [Row 25 : Col 0] causes ABEND under NW3.12, while under other nw
** versions, it just means to scroll when next char is printed.
**
** If [Row 25] and [Col != 0], it will abend most nw versions.
*/
if(row > 24)
{
if(col != 0)
{
row=24; col=79;
getch();
}
else
{
printf(" \b"); /* Cause a scroll to happen */
row = 24;
}
}
SetPositionOfInputCursor(row, col);
}
/****************************************************************************
** Update help line.
*/
void UpdateHelp(void)
{
WORD sRow, sCol;
char szTemp[80+1];
GetCursorPosition(&sRow, &sCol);
SetCursorPosition(0,0);
sprintf(szTemp, "F1:Exit F2:%s",
NLM_ansiMode ? "Turn off ANSI translation" : "Turn on ANSI translation"
);
printf("%80s", szTemp);
SetCursorPosition(sRow, sCol);
return;
}
/****************************************************************************
** Put a character on the screen, ANSI style.
*/
int ANSI_PutCh(char ch)
{
static int escMode=0; /* Flag that remembers if we are in an esc seq */
static char escStr[128+1]; /* Escape string. */
static char *escEnd;
static WORD sRow = 1;
static WORD sCol = 0;
static int autoLF=0; /* Flag indicates that the previous character caused an auto-Line feed */
short cRow;
short cCol;
short tRow;
short tCol;
char *cp;
int x;
/*------------------------------------------------------------------------
** Activate ESC mode?
*/
if((!escMode) && (ch == 27) && (NLM_ansiMode))
{
memset(escStr, 0x00, sizeof(escStr));
escEnd=NULL;
++escMode;
return(0);
}
/*------------------------------------------------------------------------
** If we are not in ESC mode, print directly.
*/
if(!escMode)
{
/*---------------------------------------------------------------------
** Weed-patch fix for unwanted cursor bluping.
*/
if((autoLF) && (ch == '\n'))
{
autoLF = 0;
return(0);
}
GetCursorPosition((WORD *)&cRow, (WORD *)&cCol);
printf("%c", ch);
/*---------------------------------------------------------------------
** cRow = 25 means we just scrolled.
*/
if(cRow == 25) UpdateHelp();
/*---------------------------------------------------------------------
** More weed-patch.
*/
GetCursorPosition((WORD *)&tRow, (WORD *)&tCol);
if((tRow != cRow) && (ch != '\n')) autoLF=1;
return(0);
}
/*------------------------------------------------------------------------
** Second char of esc sequence is always a open bracket.
*/
if(escMode == 1)
{
++escMode;
if(ch != '[')
{
printf("[ANSI BRACKET ERROR]");
goto CLR_ESC_MODE;
}
return(0);
}
/*------------------------------------------------------------------------
** If we have overflowed the ESC buffer, pewk and terminate esc mode.
*/
if(strlen(escStr) > sizeof(escStr) - 2)
{
printf("[%s]", escStr);
goto CLR_ESC_MODE;
}
/*------------------------------------------------------------------------
** Build the esc buffer.
*/
if(escEnd == NULL) escEnd = escStr;
else ++escEnd;
*escEnd = ch;
++escMode;
/*------------------------------------------------------------------------
** Check the last char of string.
*/
switch(*escEnd)
{
/*---------------------------------------------------------------------
** Moves the cursor up specifed rows (1-24, default=1). Has no effect
** if cursor is on the top row.
*/
case 'A': /* 0 - 24 0 - 79 */
GetCursorPosition((WORD *)&cRow, (WORD *)&cCol);
x = atoi(escStr);
if(!x) x=1;
cRow += x;
if(cRow > 24) cRow=24;
SetCursorPosition((WORD)cRow, (WORD)cCol);
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Move the cursor down specified rows (1-24, default=1). Has no effect
** if cursor is on the bottom row.
*/
case 'B': /* 0 - 24 0 - 79 */
GetCursorPosition((WORD *)&cRow, (WORD *)&cCol);
x = atoi(escStr);
if(!x) x=1;
cRow -= x;
if(cRow < 0) cRow=0;
SetCursorPosition((WORD)cRow, (WORD)cCol);
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Move the cursor right specified number of rows. (1-79, default = 1).
** Has no effect if cursor is in the far right column.
*/
case 'C': /* 0 - 24 0 - 79 */
GetCursorPosition((WORD *)&cRow, (WORD *)&cCol);
x = atoi(escStr);
if(!x) x=1;
cCol += x;
if(cCol > 79) cCol=79;
if((cRow == 25) && (cCol != 0))
{
printf("\n[ESC-C R:%hd,C:%hd]\n", cRow, cCol);
getch();
}
SetCursorPosition((WORD)cRow, (WORD)cCol);
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Move the cursor left specified rows (1-79, default=1). Has no
** effect if cursor is in the far left column.
*/
case 'D': /* 0 - 24 0 - 79 */
GetCursorPosition((WORD *)&cRow, (WORD *)&cCol);
x = atoi(escStr);
if(!x) x=1;
cCol -= x;
if(cCol < 0) cCol=0;
SetCursorPosition((WORD)cRow, (WORD)cCol);
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Moves the cursor to the specified row (1-25, default=1) and column
** (1-80, default=1). If row is omitted, the semicolon before column
** must be specified.
*/
case 'H':
case 'f':
cRow = atoi(escStr);
if(!cRow) cRow=1;
if(cRow > 25) cRow=25;
if(cRow < 1) cRow=1;
/* Do not zero index the row, being that ANSI is only 24 rows.*/
cp=strchr(escStr, ';');
if(cp == NULL) cCol=1;
else
{
++cp;
cCol=atoi(cp);
if(cCol > 80) cCol=80;
if(cCol < 1) cCol=1;
}
--cCol; /* zero index */
/* 0 - 24 0 - 79 */
SetCursorPosition((WORD)cRow, (WORD)cCol);
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Store the current row and column position of the cursor. Cursor can
** be restored to this position later with a Restore Cursor Position
** escape sequence.
*/
case 's':
GetCursorPosition(&sRow, &sCol);
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Moves the cursor to the position of the most recent Save Cursor
** Position escape sequences.
**
*/
case 'u':
SetCursorPosition(sRow, sCol);
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Clear the screen and place cursor at the home position.
*/
case 'J':
clrscr();
SetCursorPosition(1,0);
UpdateHelp();
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Erases from cursor position to the end of the same row.
*/
case 'K':
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** Controls specific graphics attributes such as intensity, blinking,
** superscript, and sub script, as well as the foreground and
** background colors. May contain multiple fields separated by
** semicolons.
**
** Being that color and attributes are a bit difficult to handle in the
** NetWare 3.x environment, this section will do little more than
** acknoledge the operations.
*/
case 'm':
cp=escStr;
while(cp < escEnd)
{
switch(*cp)
{
case ';': /* Ignore the field separator. */
case 0: /* All attributes off. */
case 1: /* High intensity (bold). */
case 2: /* Normal intensity. */
case 4: /* Undrline. */
case 5: /* Blink. */
case 7: /* Reverse video. */
case 8: /* Concealed (invisible). */
case 30: /* Black foreground. */
case 31: /* Red foreground. */
case 32: /* Green foreground. */
case 33: /* Yellow foreground. */
case 34: /* Blue foreground. */
case 35: /* Magenta foreground. */
case 36: /* Cyan foreground. */
case 37: /* White foreground. */
case 40: /* Black background. */
case 41: /* Red background. */
case 42: /* Green background. */
case 43: /* Yellow background. */
case 44: /* Blue background. */
case 45: /* Magenta background. */
case 46: /* Cyan background. */
case 47: /* White background. */
break;
default:
break;
}
++cp;
}
goto CLR_ESC_MODE;
/*---------------------------------------------------------------------
** I don't know what this does.
*/
default:
if(isalpha(ch))
{
printf("[Unresolved escape code: {%s} %02X %02X %02X]",
escStr,
0x000000FF & escStr[0],
0x000000FF & escStr[1],
0x000000FF & escStr[2]
);
getch();
goto CLR_ESC_MODE;
}
break;
}
return(0);
CLR_ESC_MODE:
escMode=0;
return(0);
}
/****************************************************************************
** Program start.
*/
void main(void)
{
int portHandle = -1;
int ch;
int x;
int cCode;
LONG count;
WORD state;
char buffer[BUFFER_SIZE];
AIOPORTCAPABILITIES portCaps;
int hardwareType;
int boardNumber;
int portNumber;
/*------------------------------------------------------------------------
** Acquire any available port.
*/
hardwareType = AIO_HARDWARE_TYPE_WILDCARD /* AIO_COMX_TYPE */;
boardNumber = AIO_BOARD_NUMBER_WILDCARD;
portNumber = AIO_PORT_NUMBER_WILDCARD;
cCode=AIOAcquirePort(
/* IO hardwareType */ &hardwareType,
/* IO boardNumber */ &boardNumber,
/* IO portNumber */ &portNumber,
/* -O portHandle */ &portHandle
);
switch(cCode)
{
case AIO_SUCCESS:
break;
case AIO_FAILURE:
printf("ERROR: AIOAcquirePort() failed.\n");
break;
case AIO_PORT_NOT_AVAILABLE:
printf("ERROR: AIOAcquirePort() reported: No ports available.\n");
goto END;
case AIO_TYPE_NUMBER_INVALID:
printf("ERROR: AIOAcquirePort() reported: Invalid hardware type specified.\n");
goto END;
case AIO_BOARD_NUMBER_INVALID:
printf("ERROR: AIOAcquirePort() reported: Invalid board number specified.\n");
goto END;
case AIO_PORT_NUMBER_INVALID:
printf("ERROR: AIOAcquirePort() reported: Invalid port number specified.\n");
goto END;
default:
printf("ERROR: AIOAcquirePort() reported unknown error: %d.\n", cCode);
goto END;
}
printf("Acquired port for driver %d, board %d, port %d.\n",
hardwareType, boardNumber, portNumber);
/*------------------------------------------------------------------------
** Get the high-level capabilities of the acquired port.
*/
cCode=AIOGetPortCapability(
/* I- portHandle */ portHandle,
/* IO capabilities */ &portCaps,
/* IO dvrCapabilities*/ NULL /* NULL means we don't need this. */
);
switch(cCode)
{
case AIO_SUCCESS:
break;
case AIO_BAD_HANDLE:
printf("ERROR: AIOGetPortCapability() reported: Bad handle specified.\n");
break;
case AIO_FAILURE:
printf("ERROR: AIOGetPortCapability() failed.\n");
break;
case AIO_PORT_GONE:
printf("ERROR: AIOGetPortCapability() reported: Port is gone.\n");
goto END;
default:
printf("ERROR: AIOGetPortCapability() reported unknown error: %d.\n", cCode);
goto END;
}
/*------------------------------------------------------------------------
** Verify that the structures are current or newer
*/
if(portCaps.returnLength < sizeof(portCaps))
printf("WARNING: Obsolete structures in use!\n");
else
{
/*---------------------------------------------------------------------
** Verify that the port can handle 2400 baud
*/
if((portCaps.minBitRate > AIO_BAUD_2400) || (portCaps.maxBitRate < AIO_BAUD_2400))
printf("WARNING: Port cannot be configured for 2400bps rate requirement.\n");
}
/*------------------------------------------------------------------------
** Configure the port for use
*/
cCode=AIOConfigurePort(
/* I- portHandle */ portHandle,
/* I- bitRate */ AIO_BAUD_2400,
/* I- dataBits */ AIO_DATA_BITS_8,
/* I- stopBits */ AIO_STOP_BITS_1,
/* I- parityMode */ AIO_PARITY_NONE,
/* I- flowCtrlMode */ AIO_SOFTWARE_FLOW_CONTROL_ON
);
switch(cCode)
{
case AIO_SUCCESS:
break;
case AIO_BAD_HANDLE:
printf("ERROR: AIOConfigurePort() reported: Bad handle specified.\n");
break;
case AIO_FAILURE:
printf("ERROR: AIOConfigurePort() failed.\n");
break;
case AIO_QUALIFIED_SUCCESS:
printf("ERROR: AIOConfigurePort() reported: Couldn't configure port exactly as requested.\n");
break;
case AIO_PORT_GONE:
printf("ERROR: AIOConfigurePort() reported: Port is gone.\n");
goto END;
default:
printf("ERROR: AIOConfigurePort() reported unknown error: %d.\n", cCode);
goto END;
}
/*------------------------------------------------------------------------
** Set DTR and RTS on
*/
cCode=AIOSetExternalControl(
/* I- portHandle */ portHandle,
/* I- requestType */ AIO_EXTERNAL_CONTROL,
/* I- requestValue */ AIO_EXTCTRL_DTR|AIO_EXTCTRL_RTS
);
switch(cCode)
{
case AIO_SUCCESS:
break;
case AIO_BAD_HANDLE:
printf("ERROR: AIOSetExternalControl() reported: Bad handle specified.\n");
break;
case AIO_FAILURE:
printf("ERROR: AIOSetExternalControl() failed.\n");
break;
case AIO_FUNC_NOT_SUPPORTED:
printf("ERROR: AIOSetExternalControl() reported: Function not supported.\n");
break;
case AIO_INVALID_PARAMETER:
printf("ERROR: AIOSetExternalControl() reported: Invalid parameter.\n");
break;
case AIO_BAD_REQUEST_TYPE:
printf("ERROR: AIOSetExternalControl() reported: Bad request type.\n");
break;
case AIO_PORT_GONE:
printf("ERROR: AIOSetExternalControl() reported: Port is gone.\n");
goto END;
default:
printf("ERROR: AIOSetExternalControl() reported unknown error: %d.\n", cCode);
goto END;
}
/*------------------------------------------------------------------------
** Set-up screen.
*/
SetCursorCouplingMode(TRUE);
clrscr();
UpdateHelp();
SetCursorPosition(1,0);
/*------------------------------------------------------------------------
** Terminal operations loop.
*/
while(1)
{
/*---------------------------------------------------------------------
** Keyboard handler.
*/
if(kbhit())
{
ch=getch(); /* Get regular keystroke. */
if(!ch) ch=getch() + 0x0100; /* Get special keystroke. */
if(ch == KEY_F1) break; /* Exit terminal emulator. */
if(ch == KEY_F2) /* Toggle ANSI emulation. */
{
NLM_ansiMode = !NLM_ansiMode;
UpdateHelp();
continue;
}
ch &= 0x00FF;
cCode=AIOWriteData(
/* I- portHandle */ portHandle,
/* I- buffer */ (char *)&ch,
/* I- lengthOfBuffer */ 1,
/* -O numberOfBytesWritten */ &count
);
switch(cCode)
{
case AIO_SUCCESS:
break;
case AIO_BAD_HANDLE:
printf("ERROR: AIOWriteData() reported: Bad handle specified.\n");
break;
case AIO_FAILURE:
printf("ERROR: AIOWriteData() failed.\n");
break;
case AIO_PORT_GONE:
printf("ERROR: AIOWriteData() reported: Port is gone.\n");
goto END;
default:
printf("ERROR: AIOWriteData() reported unknown error: %d.\n", cCode);
goto END;
}
/*------------------------------------------------------------------------
** Make sure that everything was sent.
*/
if(count < 1)
{
printf("ERROR: AIOWriteData() reported incomplete write. (0 bytes written)\n");
goto END;
}
}
/*---------------------------------------------------------------------
** AIO handler.
*/
cCode=AIOReadStatus(
/* I- portHandle */ portHandle,
/* I- count */ &count,
/* -O state */ &state
);
switch(cCode)
{
case AIO_SUCCESS:
break;
case AIO_BAD_HANDLE:
printf("ERROR: AIOReadStatus() reported: Bad handle specified.\n");
break;
case AIO_FAILURE:
printf("ERROR: AIOReadStatus() failed.\n");
break;
case AIO_PORT_GONE:
printf("ERROR: AIOReadStatus() reported: Port is gone.\n");
goto END;
default:
printf("ERROR: AIOReadStatus() reported unknown error: %d.\n", cCode);
goto END;
}
if(count)
{
memset(buffer, 0x00, BUFFER_SIZE);
cCode=AIOReadData(
/* I- portHandle */ portHandle,
/* I- buffer */ buffer,
/* I- lengthOfBuffer */ BUFFER_SIZE,
/* -O numberOfBytesRead */ &count
);
switch(cCode)
{
case AIO_SUCCESS:
break;
case AIO_BAD_HANDLE:
printf("ERROR: AIOReadData() reported: Bad handle specified.\n");
break;
case AIO_FAILURE:
printf("ERROR: AIOReadData() failed.\n");
break;
case AIO_PORT_GONE:
printf("ERROR: AIOReadData() reported: Port is gone.\n");
goto END;
default:
printf("ERROR: AIOReadData() reported unknown error: %d.\n", cCode);
goto END;
}
for(x=0; x < count; ++x) ANSI_PutCh(buffer[x]);
}
/*---------------------------------------------------------------------
** Give someone else a turn to play in the sandbox.
*/
ThreadSwitch();
}
END:
/*------------------------------------------------------------------------
** Release the port
*/
if(portHandle != (-1))
{
cCode=AIOReleasePort(portHandle);
switch(cCode)
{
case AIO_SUCCESS:
break;
case AIO_BAD_HANDLE:
printf("ERROR: AIOReleasePort() reported: Bad handle specified.\n");
break;
case AIO_FAILURE:
printf("ERROR: AIOReleasePort() failed.\n");
break;
default:
printf("ERROR: AIOReleasePort() reported unknown error: %d.\n", cCode);
goto END;
}
}
return;
}