|
|
Microsoft OS/2 SDK PM 08-08-1988
/* ------------------------------------ */
/* VIO File Browser Demo */
/* Version 5 */
/* Created 1988 Microsoft Corp. */
/* ------------------------------------ */
/* ------------------------------------ */
/* library includes */
/* ------------------------------------ */
#define INCL_BASE
#include <stdlib.h>
#include <stdio.h>
#include <os2.h>
#include <string.h>
#include "viobrows.h"
/* ------------------------------------ */
/* global variables */
/* ------------------------------------ */
FILE *pFile_In;
char *apchDataLines[ NUM_DATA_LINES ];
SHORT HighestLine= -1;
USHORT Vid_Cols, Vid_Rows;
SHORT HorScrollPos=0;
/* ================================================================ */
/* Functions */
/* ================================================================ */
void cdecl main( argc, argv )
int argc;
char *argv[];
{
if (Initialize(argc,argv))
exit(-1);
ManipulateFile();
exit(0);
}
/* ================================================================ */
SHORT Initialize(argc,argv)
int argc;
char *argv[];
/* tries to open input file and initialize global variables */
/* plus any other misc. functions */
{
char *achInFile;
VIOMODEINFO viomiMode;
/* -------------------------- */
/* get input file ready */
/* -------------------------- */
if (argc==1)
pFile_In=stdin;
else {
achInFile=argv[1];
if ((pFile_In=fopen(achInFile,"r"))==NULL) {
fprintf(stderr,"Error--could not open %s",achInFile);
return(-1);
}
}
/* -------------------------- */
/* read input file */
/* -------------------------- */
if (ReadFile())
return(-1);
/* -------------------------- */
/* get video parameters */
/* -------------------------- */
viomiMode.cb = sizeof(viomiMode);
VioGetMode(&viomiMode, 0);
Vid_Cols=viomiMode.col;
Vid_Rows=viomiMode.row;
DisplayScreen(0, TRUE);
}
/* ================================================================ */
SHORT ReadFile( void )
/* reads data lines from the file to memory. */
/* if an error occurs, it will abort the program */
/* stores the lines as null-terminated ascii, with */
/* no /n's in the strings. */
{ char achLine[256];
while (fgets(achLine,128,pFile_In)) {
/* strip LF character from end of string before storing */
/* by converting LF to /0 */
if (achLine[strlen(achLine)-1]=='\n')
achLine[strlen(achLine)-1]=0;
else {
fprintf(stderr,"Internal error in ReadFile.\n");
return(-1);
}
if (StoreLine(achLine)) {
fprintf(stderr,"Error while storing line in ReadFile.\n");
return(-1);
}
}
fclose(pFile_In);
return(0);
}
/* ================================================================ */
void ManipulateFile( void )
/* this takes lines from memory and displays to user's pleasure */
/* other functions such as DisplayLineNumber and SwitchFile */
/* should be added here */
{
USHORT CurLine=0;
UserLoop();
/* set cursor at a nice place before exiting */
VioSetCurPos(Vid_Rows-1,0,0);
}
/* ================================================================ */
/* Line-handling subsystem */
/* ================================================================ */
SHORT StoreLine( pchLine )
char *pchLine;
/* store a line in memory at end of list. */
/* creates the line number automatically */
/* extensions to allow >64K data go here and in RetrieveLine */
{
/* don't forget to malloc space for \0 */
if (HighestLine==NUM_DATA_LINES ||
(apchDataLines[++HighestLine]=malloc(strlen(pchLine)+1))==NULL )
return(-1);
/* copy (to, from) */
strcpy(apchDataLines[HighestLine],pchLine);
return(0);
}
/* ================================================================ */
SHORT RetrieveLine( ppchLine , LineNum )
char **ppchLine;
USHORT LineNum;
/* take line number and convert it to a string of data from memory */
/* extensions to allow >64K data also incorporated here */
{
if (LineNum > HighestLine)
return(-1);
*ppchLine=apchDataLines[LineNum];
return(0);
}
/* ================================================================ */
/* Video-handling subsystem */
/* ================================================================ */
void ClearScreen( void )
/* self-explanitory I hope */
/* uses technique from qh examples */
/* clearing=scrolldown(maxlines) */
{
BYTE bBlank[2];
bBlank[0] = 0x20; /* space character */
bBlank[1] = 0x07; /* white attribute (EGA) */
VioScrollDn(0, /* top row */
0, /* left column */
-1, /* bottom row */
-1, /* right column */
-1, /* number of lines */
bBlank, /* cell to write */
WINDOW); /* video handle */
}
/* ================================================================ */
void DisplayScreen( USHORT TopLine, BOOL force)
/* display lines from memory to video, starting at line number TopLine */
/* has 'smarts' to scroll+paint remainder. */
{
SHORT LineDiff;
static USHORT OldTopLine;
/* horizontal shift should go here, but is not implemented yet */
LineDiff=TopLine-OldTopLine;
if ( (abs(LineDiff) < Vid_Rows ) && !force ) {
/* is legal to apply scroll+paint remainder algorithm */
/* (usually applied when user wants line up/down) */
if (LineDiff<0) {
/* user scrolls back; repaint top part of screen */
ScrollDown( -LineDiff );
VidRefresh(TopLine, -LineDiff, 0);
}
else {
/* user scrolls forward; repaint bottom part */
ScrollUp( LineDiff );
VidRefresh( TopLine+Vid_Rows-LineDiff, LineDiff, Vid_Rows-LineDiff);
}
}
else {
/* repaint entire screen */
ClearScreen();
VidRefresh(TopLine, Vid_Rows, 0);
}
OldTopLine=TopLine;
}
/* ================================================================ */
void VidRefresh ( USHORT LineFrom, USHORT NumLines, USHORT VidRowStart)
/* Redisplay lines LineFrom to LineTo starting at video VidRowStart */
/* Will NOT check that you haven't given it stupid arguments */
{
USHORT LineOffset;
char *pchLine;
for (LineOffset=0; LineOffset < NumLines ; LineOffset++) {
if (LineOffset + LineFrom > HighestLine)
break;
RetrieveLine(&pchLine, LineOffset + LineFrom);
VioSetCurPos(
VidRowStart+LineOffset, /* vertical pos */
0 , /* horizontal pos */
WINDOW /* hvio */
);
VioWrtTTY(
pchLine, /* string to print */
strlen(pchLine), /* string length */
WINDOW /* hvio */
);
}
}
void ScrollUp(int Nlines)
{
BYTE bBlank[2];
bBlank[0] = 0x20; /* space character */
bBlank[1] = 0x07; /* white attribute (EGA) */
VioScrollUp(0, /* top row */
0, /* left column */
-1, /* bottom row */
-1, /* right column */
Nlines, /* number of lines */
bBlank, /* cell to write */
WINDOW); /* video handle */
}
void ScrollDown(int Nlines)
{
BYTE bBlank[2];
bBlank[0] = 0x20; /* space character */
bBlank[1] = 0x07; /* white attribute (EGA) */
VioScrollDn(0, /* top row */
0, /* left column */
-1, /* bottom row */
-1, /* right column */
Nlines, /* number of lines */
bBlank, /* cell to write */
WINDOW); /* video handle */
}
/* ================================================================ */
/* User input subsystem */
/* ================================================================ */
VOID UserLoop( VOID )
{
CHAR ch;
while ( (ch=GetKbdInput()) != EXIT )
ExecuteAction(ch);
}
VOID ExecuteAction( CHAR ch)
/* interact with the user somehow to discover new line number */
/* at top of screen */
/* extensions to allow PM windowing go here */
/* returns 1 if successful */
/* returns 0 if unsuccessful (user wants to quit) */
{
static USHORT OldLine ;
BOOL bForce=FALSE;
#define downbound( X, A, B) ( (X) > ((B)-(A)) )? (B) : (X)+(A)
#define upbound( X, A, B) ( (X) < ((B)+(A)) )? (B) : (X)-(A)
switch (ch) {
case LINE_UP:
OldLine=upbound( OldLine, 1, 0);
break;
case LINE_DOWN:
OldLine=downbound( OldLine, 1, MAX_START_LINE);
break;
case PAGE_UP:
OldLine=upbound( OldLine, Vid_Rows, 0);
break;
case PAGE_DOWN:
OldLine=downbound( OldLine, Vid_Rows, MAX_START_LINE);
break;
case GOTO_TOP:
OldLine= 0;
break;
case GOTO_BOTTOM:
OldLine= MAX_START_LINE;
break;
case GOTO_LINE:
/* Not Implemented */
break;
case CHAR_RIGHT:
HorScrollPos= downbound ( HorScrollPos, 1, HIGHEST_HSCROLL);
break;
case CHAR_LEFT:
HorScrollPos = upbound( HorScrollPos, 1, 0);
break;
case PAGE_RIGHT:
HorScrollPos = downbound( HorScrollPos, HSCROLL_PAGESIZE, HIGHEST_HSCROLL);
break;
case PAGE_LEFT:
HorScrollPos = upbound( HorScrollPos, HSCROLL_PAGESIZE, 0);
break;
case GOTO_HSCROLL:
/* Not Implemented */
break;
case NULL:
bForce= TRUE;
break;
}
DisplayScreen( OldLine, bForce );
}
/* ================================================================ */
CHAR GetKbdInput( void )
/* get an action code based on keyboard input */
/* action codes are #defined constants. */
{
switch(GetScanCode()) {
case 1: /* escape */
return ( EXIT );
case 0x48: /* up-arrow */
return( LINE_UP );
case 0x50: /* down-arrow */
return( LINE_DOWN );
case 0x4d: /* right-arrow */
return( CHAR_RIGHT );
case 0x4b: /* left-arrow */
return( CHAR_LEFT );
case 0x49: /* PageUp */
return( PAGE_UP );
case 0x51: /* PageDown */
return( PAGE_DOWN );
case 0x47: /* Home */
return( GOTO_TOP );
case 0x4f:
return( GOTO_BOTTOM );
case 0x0f: /* Tab */
return( GOTO_LINE );
}
}
/* ================================================================ */
UCHAR GetScanCode( void )
/* wait for a single keystroke and return its scan code */
{
KBDKEYINFO kbciKeyInfo;
KbdCharIn(&kbciKeyInfo, /* buffer for data */
IO_WAIT, /* WAIT/NOWAIT */
0); /* keyboard handle */
return(kbciKeyInfo.chScan);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.