/* scs.c -- Converts scs to forms useable by scs2ascii, scs2ps, and scs2pdf.
* Copyright (C) 2000 Michael Madore
*
* This file is part of TN5250.
*
* TN5250 is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* TN5250 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "tn5250-private.h"
/*
#define DEBUG
#define VERBOSE
*/
/* Device control */
void scs_sic (Tn5250SCS * This);
void scs_sea (Tn5250SCS * This);
void scs_noop (Tn5250SCS * This);
void scs_transparent (Tn5250SCS * This);
void scs_spsu (Tn5250SCS * This);
/* Page control */
void scs_ppm (Tn5250SCS * This);
void scs_spps (Tn5250SCS * This);
void scs_shf (Tn5250SCS * This);
void scs_svf (Tn5250SCS * This);
void scs_ff (Tn5250SCS * This);
void scs_rff (Tn5250SCS * This);
void scs_sto (Tn5250SCS * This);
void scs_shm (Tn5250SCS * This);
void scs_svm (Tn5250SCS * This);
void scs_sffc (Tn5250SCS * This);
/* Font controls */
void scs_scgl (Tn5250SCS * This);
void scs_scg (Tn5250SCS * This);
void scs_sfg (Tn5250SCS * This);
void scs_scd (int *cpi);
/* Cursor control */
void scs_pp (Tn5250SCS * This);
void scs_rdpp (Tn5250SCS * This);
void scs_ahpp (Tn5250SCS * This);
void scs_avpp (Tn5250SCS * This);
void scs_rrpp (Tn5250SCS * This);
void scs_sbs (Tn5250SCS * This);
void scs_sps (Tn5250SCS * This);
void scs_nl (Tn5250SCS * This);
void scs_irs (Tn5250SCS * This);
void scs_rnl (Tn5250SCS * This);
void scs_irt (Tn5250SCS * This);
void scs_stab (Tn5250SCS * This);
void scs_ht (Tn5250SCS * This);
void scs_it (Tn5250SCS * This);
void scs_sil (Tn5250SCS * This);
void scs_lf (Tn5250SCS * This);
void scs_cr (Tn5250SCS * This);
void scs_ssld (Tn5250SCS * This);
void scs_sls (Tn5250SCS * This);
/* Generation controls */
void scs_sgea (Tn5250SCS * This);
void scs_process2b (Tn5250SCS * This);
void scs_processd2 (Tn5250SCS * This);
void scs_process03 (unsigned char nextchar, unsigned char curchar);
void scs_scs (int *cpi);
void scs_process04 (unsigned char nextchar, unsigned char curchar, int *cpi);
void scs_processd1 ();
void scs_process06 ();
void scs_process07 ();
void scs_processd103 ();
void scs_jtf (unsigned char curchar);
void scs_sjm (unsigned char curchar);
void scs_processd3 (Tn5250SCS * This);
void scs_main (Tn5250SCS * This);
void scs_init (Tn5250SCS * This);
void scs_default (Tn5250SCS * This);
/* Set Initial Conditions (SIC). This is part of Device Control. SIC
* has a one byte parameter that follows it with the following meanings:
* 1 - word processing initialization
* 255 - data processing initialization (default)
* all others - invalid
*
* According to the manual, this control is ignored by all printers.
*/
void
scs_sic (Tn5250SCS * This)
{
unsigned char curchar;
curchar = fgetc (stdin);
if (curchar != 1 && curchar != 255)
{
fprintf (stderr, "Invalid SIC parameter (SIC = %x)\n", curchar);
}
else
{
#ifdef DEBUG
fprintf (stderr, "SIC = %x", curchar);
#ifdef VERBOSE
fprintf (stderr, "\tInitializing for data processing");
#endif
fprintf (stderr, "\n");
#endif
}
return;
}
/* Set Exception Action (SEA). This is part of Device Control. SEA
* introduces a sequence of byte pairs. The byte pairs have a length
* of (curchar-2) bytes. The first byte of each pair is the exception
* class. The second is the action.
*
* The exception class bytes has the following meanings:
* 0 - all exception classes
* 1-4 - classes 1-4 respectively
* all others - invalid
*
* The action may be:
* 0 - accept. On the printer this is the same is ignore (1).
* 1 - ignore
* 2 - terminate
* 3 - suspend
*
* If we get an action of 2 or 3 we should probably exit(), but for
* now do nothing.
*/
void
scs_sea (Tn5250SCS * This)
{
unsigned char exception;
unsigned char action;
int loop;
for (loop = 0; loop < This->curchar - 2; loop++)
{
exception = fgetc (stdin);
if (exception > 4)
{
fprintf (stderr, "Invalid exception class (%d)\n", exception);
}
else
{
#ifdef DEBUG
fprintf (stderr, "SEA (length %x) = %d", This->curchar, exception);
#endif
}
action = fgetc (stdin);
if (action > 3)
{
fprintf (stderr,
"Invalid action (exception class: %d, action %d)\n",
exception, action);
}
else
{
#ifdef DEBUG
fprintf (stderr, " %d", action);
#ifdef VERBOSE
switch (action)
{
case 0:
{
if (exception == 0)
{
fprintf (stderr,
"\tUsing action ACCEPT for exception class %d (all exception classes)",
exception);
}
else
{
fprintf (stderr,
"\tUsing action ACCEPT for exception class %d",
exception);
}
break;
}
case 1:
{
if (exception == 0)
{
fprintf (stderr,
"\tUsing action IGNORE for exception class %d (all exception classes)",
exception);
}
else
{
fprintf (stderr,
"\tUsing action IGNORE for exception class %d",
exception);
}
break;
}
case 2:
{
if (exception == 0)
{
fprintf (stderr,
"\tUsing action TERMINATE for exception class %d (all exception classes)",
exception);
}
else
{
fprintf (stderr,
"\tUsing action TERMINATE for exception class %d",
exception);
}
break;
}
case 3:
{
if (exception == 0)
{
fprintf (stderr,
"\tUsing action SUSPEND for exception class %d (all exception classes)",
exception);
}
else
{
fprintf (stderr,
"\tUsing action SUSPEND for exception class %d",
exception);
}
break;
}
}
#endif
fprintf (stderr, "\n");
#endif
}
loop++;
}
return;
}
/* Null (NUL). This is part of Device Control.
* Don't do anything
*/
void
scs_noop (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "NOOP\n");
#endif
return;
}
/* ASCII Transparency (ATRN). This is part of Device Control.
* Only used to send PCL codes to an ascii printer.
*/
void
scs_transparent (Tn5250SCS * This)
{
int bytecount;
int loop;
bytecount = fgetc (stdin);
fprintf (stderr, "TRANSPARENT (%x) = ", bytecount);
for (loop = 0; loop < bytecount; loop++)
{
fprintf (stderr, "%c", fgetc (stdin));
}
return;
}
/* Set Print Setup (SPSU). This is part of Device Control. SPSU
* selects the paper source tray.
*
* The documentation is a little weird on this on. But we ignore it
* anyway, so who cares? Usually the host sends us 03 which means if
* the printer is currently set to manual feed, use tray 1.
*/
void
scs_spsu (Tn5250SCS * This)
{
unsigned char trayparm;
unsigned char nextchar;
int loop;
nextchar = fgetc (stdin);
trayparm = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SPSU (%x) = %x%x", This->curchar, nextchar, trayparm);
#endif
for (loop = 2; loop < This->curchar - 2; loop++)
{
nextchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, " %x", nextchar);
#endif
}
#ifdef DEBUG
#ifdef VERBOSE
if (trayparm < 4)
{
switch (trayparm)
{
case 0:
{
fprintf (stderr, "\tPaper source tray left unchanged");
break;
}
case 1:
{
fprintf (stderr, "\tPaper source tray set to manual");
break;
}
case 2:
{
fprintf (stderr, "\tPaper source tray set to tray 1");
break;
}
case 3:
{
fprintf (stderr, "\tPaper source tray set to tray 1");
break;
}
}
}
#endif
fprintf (stderr, "\n");
#endif
return;
}
/* Page Presentation Media (PPM). This is part of Page Controls.
* This also selects paper source - in seeming conflict with SPSU.
*/
void
scs_ppm (Tn5250SCS * This)
{
unsigned char formscontrol, sourcedrawer, destdraweroffset;
unsigned char destdrawer, quality, duplex;
unsigned char nextchar;
#ifdef DEBUG
fprintf (stderr, "Begin Page Presentation Media (PPM)\n");
fprintf (stderr, "Length of PPM parameters: %d\n", This->curchar);
#endif
nextchar = fgetc (stdin);
nextchar = fgetc (stdin);
formscontrol = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "\tForms control = %x\n", formscontrol);
#endif
if (This->curchar > 5)
{
sourcedrawer = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "\tSource drawer = %x\n", sourcedrawer);
#endif
}
if (This->curchar > 6)
{
destdraweroffset = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "\tDestination drawer offset = %x\n",
destdraweroffset);
#endif
}
if (This->curchar > 7)
{
destdrawer = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "\tDestination drawer = %x\n", destdrawer);
#endif
}
if (This->curchar > 8)
{
quality = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "\tQuality = %x\n", quality);
#endif
}
if (This->curchar > 9)
{
duplex = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "\tDuplex = %x\n", duplex);
#endif
}
#ifdef DEBUG
fprintf (stderr, "End Page Presentation Media (PPM)\n");
#endif
return;
}
/* Set Presentation Page Size (SPPS). This is part of Page Controls.
* Sets the presetation surface width and optionally depth in units of
* 1440ths of an inch. Valid values are 0 - 32767. A value of 0 results
* in no change.
*
* Definately look at the IBM docs for this one. Particularly note that
* the presentation size can be different (even larger) than the actual
* page size.
*/
void
scs_spps (Tn5250SCS * This)
{
int width, length;
width = fgetc (stdin);
width = (width << 8) + fgetc (stdin);
This->pagewidth = width;
length = fgetc (stdin);
length = (length << 8) + fgetc (stdin);
This->pagelength = length;
#ifdef DEBUG
fprintf (stderr, "SPPS (width = %d) (length = %d)", width, length);
#ifdef VERBOSE
fprintf (stderr, "\tPrintable region is %d by %d inches",
(width / 1440), (length / 1440));
#endif
fprintf (stderr, "\n");
#endif
return;
}
/* Set Horizontal Format (SHF). This is part of Page Controls.
* Specifies the presentation surface width.
*/
void
scs_shf (Tn5250SCS * This)
{
unsigned char shf1, shf2;
shf1 = fgetc (stdin);
shf2 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SHF = %x %x\n", shf1, shf2);
#endif
return;
}
/* Set Vertical Format (SVF). This is part of Page Controls.
* Specifies the presentation surface depth.
*/
void
scs_svf (Tn5250SCS * This)
{
unsigned char svf1, svf2;
svf1 = fgetc (stdin);
svf2 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SVF = %x %x\n", svf1, svf2);
#endif
return;
}
/* Form Feed/page end (FF/PE). This is part of Page Controls.
* Prints the current page.
*/
void
scs_ff (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "FF\n");
#endif
return;
}
/* Required Form Feed/page end (RFF/RPE). This is part of Page Controls.
* Prints the current page like form feed, but also restores the indent
* level to the left margin
*/
void
scs_rff (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "RFF\n");
#endif
return;
}
/* Set Text Orientation (STO). This is part of Page Controls.
* Sets the orientation of characters on a page. It has two paramters:
*
* 2-byte parameter for character rotation. This is always ignored.
* 2-byte parameter for page rotation with the following meanings:
*
* 0000 - portrait
* 2D00 - rotate clockwise 270 degrees
* 5A00 - rotate clockwise 180 degrees
* 8700 - rotate clockwise 90 degrees
* FFFE - select COR mode
* FFFF - calculate based on SPPS (default)
* all others - invalid
*/
void
scs_sto (Tn5250SCS * This)
{
unsigned char charrot1;
unsigned char charrot2;
unsigned char pagerot1;
unsigned char pagerot2;
#ifdef DEBUG
fprintf (stderr, "STO = ");
#endif
charrot1 = fgetc (stdin);
charrot2 = fgetc (stdin);
pagerot1 = fgetc (stdin);
pagerot2 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "%x%x %x%x", charrot1, charrot2, pagerot1, pagerot2);
#ifdef VERBOSE
switch (pagerot1)
{
case 0x00:
{
fprintf (stderr, "\tPrinting normal portrait");
break;
}
case 0x2D:
{
fprintf (stderr, "\tPrinting landscape left");
break;
}
case 0x5A:
{
fprintf (stderr, "\tPrinting portrait upside down");
break;
}
case 0x87:
{
fprintf (stderr, "\tPrinting landscape right");
break;
}
case 0xFF:
{
if (pagerot2 == 0xFE)
{
fprintf (stderr, "\tSelected COR mode");
}
else
{
fprintf (stderr,
"\tSetting text orientation based on SPPS command");
}
}
}
#endif
fprintf (stderr, "\n");
#endif
if (pagerot1 != 0xFF && pagerot2 != 0xFF)
{
fprintf (stderr, "Unhandled page rotation!!\n");
}
return;
}
/* Set Horizontal Margins (SHM). This is part of Page Controls.
* Sets the left margin and optionally the right margin in terms
* of 1440ths of an inch from the left and optionally right edges
* of the paper. Valid values are 0 - 32767. A value of 0 means
* to leave the margins unchanged.
*/
void
scs_shm (Tn5250SCS * This)
{
unsigned char left1;
unsigned char left2;
unsigned char right1;
unsigned char right2;
left1 = fgetc (stdin);
left2 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SHM = %d%d", left1, left2);
#endif
if (This->curchar > 5)
{
right1 = fgetc (stdin);
right2 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, " %d%d", right1, right2);
#endif
#ifdef VERBOSE
fprintf (stderr,
"\tSetting margins to %d%d 1440ths of an inch in from the left\n",
left1, left2);
fprintf (stderr,
"\t\tedge and %d%d 1440ths of an inch in from the right edge",
right1, right2);
#endif
}
#ifdef DEBUG
fprintf (stderr, "\n");
#endif
return;
}
/* Set Vertical Margins (SVM). This is part of Page Controls.
* Sets the top margin and optionally the bottom margin in terms
* of 1440ths of an inch from the top and optionally bottom edges
* of the paper. Valid values are 0 - 32767. A value of 0 means
* to leave the margins unchanged.
*/
void
scs_svm (Tn5250SCS * This)
{
unsigned char top1;
unsigned char top2;
unsigned char bottom1;
unsigned char bottom2;
top1 = fgetc (stdin);
top2 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SVM = %d%d", top1, top2);
#endif
if (This->curchar > 5)
{
bottom1 = fgetc (stdin);
bottom2 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, " %d%d", bottom1, bottom2);
#ifdef VERBOSE
fprintf (stderr,
"\tSetting margins to %d%d 1440ths of an inch in from the top\n",
top1, top2);
fprintf (stderr,
"\t\tedge and %d%d 1440ths of an inch in from the bottom edge",
bottom1, bottom2);
#endif
#endif
}
#ifdef DEBUG
fprintf (stderr, "\n");
#endif
return;
}
/* Set Form Feed Control (SFFC). This is part of Page Controls.
* Specifies the number of form feeds to be issued before a page is
* printed. It has one 1-byte parameter. The default is 0x01. Valid
* values are 0x00 - 0xFF. 0x00 means no change.
*/
void
scs_sffc (Tn5250SCS * This)
{
unsigned char nextchar;
nextchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SFFC=%x\n", nextchar);
#ifdef VERBOSE
fprintf (stderr,
"\tRequiring %x form feeds to be issued before printing page\n",
nextchar);
#endif
fprintf (stderr, "\n");
#endif
return;
}
/* Set CGCS through Local ID (SCGL). This is part of Font Controls.
* This has a 1-byte parameter that gives the local ID. The default
* is 0xFF
*/
void
scs_scgl (Tn5250SCS * This)
{
unsigned char nextchar;
nextchar = fgetc (stdin);
if (nextchar != 0xFF)
{
fprintf (stderr, "SCGL = %x\n", nextchar);
}
else
{
#ifdef DEBUG
fprintf (stderr, "SCGL = %x\n", nextchar);
#endif
}
return;
}
/* Set GCGID through GCID (SCG). This is part of Font Controls.
* Sets the code page. This has two 1-byte parameters that give the
* the graphic character set global ID (which is ignored) and the code
* page global ID. The second parameter selects the code page.
*
* See the documentation for a complete table of valid values.
*/
void
scs_scg (Tn5250SCS * This)
{
unsigned char gcgid;
unsigned char cpgid;
gcgid = fgetc (stdin);
cpgid = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "GCGID = %d, CPGID = %d\n", gcgid, cpgid);
#endif
return;
}
/* Set FID through GFID (SFG). This is part of Font Controls.
* Selects the font. This has two 2-byte parameters and one 1-byte
* parameter.
*/
void
scs_sfg (Tn5250SCS * This)
{
unsigned char globalfontid1;
unsigned char globalfontid2;
unsigned char fontwidth1;
unsigned char fontwidth2;
unsigned char fontattribute;
globalfontid1 = fgetc (stdin);
globalfontid2 = fgetc (stdin);
fontwidth1 = fgetc (stdin);
fontwidth2 = fgetc (stdin);
fontattribute = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "FID = %x%x %x%x %x\n", globalfontid1, globalfontid2,
fontwidth1, fontwidth2, fontattribute);
#endif
return;
}
/* Set Character Distance (SCD). This is part of Font Controls.
* This is also known and Set Print Density (SPD). This is the SCS
* alternative method of selecting fonts. This has one 2-byte parameter.
* The following values are supported:
*
* 0x0000 - unchanged
* 0x0005 - courier 5
* 0x000A - courier 10
* 0x000B - courier 12 proportionally spaced
* 0x000C - courier 12
* 0x000F - courier 15
* 0x00FF - use font from operation panel
* all others - invalid
*/
void
scs_scd (int *cpi)
{
unsigned char chardist1;
unsigned char chardist2;
chardist1 = fgetc (stdin);
chardist2 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SCD = %x%x", chardist1, chardist2);
#endif
/* Here we convert characters per inch (CPI) to point size. In the
* future we will probably want these to be user definable.
*/
switch (chardist2)
{
case 0x05:
{
*cpi = 14;
#ifdef DEBUG
#ifdef VERBOSE
fprintf (stderr, "\tFont set to Courier %d", *cpi);
#endif
#endif
break;
}
case 0x0A:
{
*cpi = 10;
#ifdef DEBUG
#ifdef VERBOSE
fprintf (stderr, "\tFont set to Courier %d", *cpi);
#endif
#endif
break;
}
case 0x0B:
{
*cpi = 9;
#ifdef DEBUG
#ifdef VERBOSE
fprintf (stderr, "\tFont set to Courier %d", *cpi);
#endif
#endif
break;
}
case 0x0C:
{
*cpi = 10;
#ifdef DEBUG
#ifdef VERBOSE
fprintf (stderr, "\tFont set to Courier %d", *cpi);
#endif
#endif
break;
}
case 0x0F:
{
*cpi = 7;
#ifdef DEBUG
#ifdef VERBOSE
fprintf (stderr, "\tFont set to Courier %d", *cpi);
#endif
#endif
break;
}
default:
{
*cpi = 10;
#ifdef DEBUG
#ifdef VERBOSE
fprintf (stderr, "\tFont set to Courier %d", *cpi);
#endif
#endif
break;
}
}
#ifdef DEBUG
fprintf (stderr, "\n");
#endif
return;
}
/* Presentation Position (PP). This is part of Cursor Controls.
* Moves the current cursor position based on the given parameters.
*/
void
scs_pp (Tn5250SCS * This)
{
unsigned char curchar;
curchar = fgetc (stdin);
switch (curchar)
{
case SCS_RDPP:
{
scs_rdpp (This);
break;
}
case SCS_AVPP:
{
scs_avpp (This);
break;
}
case SCS_AHPP:
{
scs_ahpp (This);
break;
}
case SCS_RRPP:
{
scs_rrpp (This);
break;
}
default:
{
fprintf (stderr, "ERROR: Unknown 0x34 command %x\n", curchar);
}
}
return;
}
/* Relative move Down (RDPP). This is part of Cursor Controls.
*/
void
scs_rdpp (Tn5250SCS * This)
{
unsigned char rdpp;
rdpp = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "RDPP %d\n", rdpp);
#endif
return;
}
/* Absolute Horizontal move (AHPP). This is part of Cursor Controls.
*/
void
scs_ahpp (Tn5250SCS * This)
{
int position;
int i;
position = fgetc (stdin);
if (This->row > position)
{
for (i = 0; i < position; i++)
{
/* Each application needs to process its own way for adding
* spaces. Add one space for each iteration
*/
/*printf(" "); */
}
}
else
{
for (i = 0; i < (position - This->row); i++)
{
/* Each application needs to process its own way for adding
* spaces. Add one space for each iteration
*/
/*printf(" "); */
}
}
This->row = position;
#ifdef DEBUG
fprintf (stderr, "AHPP %d\n", position);
#endif
return;
}
/* Absolute Vertical move (AVPP). This is part of Cursor Controls.
*/
void
scs_avpp (Tn5250SCS * This)
{
unsigned char nextchar;
nextchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "AVPP %d\n", nextchar);
#endif
return;
}
/* Relative move Right (RRPP). This is part of Cursor Controls.
*/
void
scs_rrpp (Tn5250SCS * This)
{
unsigned char nextchar;
nextchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "RRPP %d\n", nextchar);
#endif
return;
}
/* Subscript (SBS). This is part of Cursor Controls.
*/
void
scs_sbs (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "SBS\n");
#endif
return;
}
/* Superscript (SPS). This is part of Cursor Controls.
*/
void
scs_sps (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "SPS\n");
#endif
return;
}
/* New Line (NL). This is part of Cursor Controls.
*/
void
scs_nl (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "NL\n");
#endif
return;
}
/* Interchange Record Separator (IRS). This is part of Cursor Controls.
* This is the same as a new line control.
*/
void
scs_irs (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "IRS\n");
#endif
return;
}
/* Required New Line (RNL). This is part of Cursor Controls.
*/
void
scs_rnl (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "RNL\n");
#endif
return;
}
/* Index Return (IRT). This is part of Cursor Controls.
* Processed as a required new line.
*/
void
scs_irt (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "IRT\n");
#endif
return;
}
/* Set horizontal Tab stops (STAB). This is part of Cursor Controls.
* Set tab stops. This has two parameters: one 1-byte parameter that
* indicates if the tabs are floating or fixed and one variable sized
* parameter that defines the tab stops.
*/
void
scs_stab (Tn5250SCS * This)
{
unsigned char nextchar;
int loop;
#ifdef DEBUG
fprintf (stderr, "STAB = ");
#endif
for (loop = 0; loop < This->curchar - 2; loop++)
{
nextchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, " %x", nextchar);
#endif
}
#ifdef DEBUG
fprintf (stderr, "\n");
#endif
return;
}
/* Horizontal Tab (HT). This is part of Cursor Controls.
* Moves the cursor to the right to the next tab stop.
*/
void
scs_ht (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "HT\n");
#endif
return;
}
/* Indent Tab (IT). This is part of Cursor Controls.
* This is processed the same as horizontal tab except that the left
* margin is moved to the nex tab stop.
*/
void
scs_it (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "IT\n");
#endif
return;
}
/* Set Indent Level (SIL). This is part of Cursor Controls.
*/
void
scs_sil (Tn5250SCS * This)
{
unsigned char curchar;
curchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SIL = %d", curchar);
#endif
return;
}
/* Line Feed/index (LF). This is part of Cursor Controls.
* Moves the vertical position down one line increment. The horizontal
* position is unchanged.
*/
void
scs_lf (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "LF\n");
#endif
return;
}
/* Carriage Return (CR). This is part of Cursor Controls.
* Moves the horizontal position to the left margin. The vertical
* position is unchanged.
*/
void
scs_cr (Tn5250SCS * This)
{
#ifdef DEBUG
fprintf (stderr, "CR\n");
#endif
return;
}
void
scs_process2b (Tn5250SCS * This)
{
unsigned char curchar;
curchar = fgetc (stdin);
switch (curchar)
{
case 0xD1:
{
scs_processd1 ();
break;
}
case 0xD2:
{
scs_processd2 (This);
break;
}
case 0xD3:
{
scs_processd3 (This);
break;
}
case 0xC8:
{
scs_sgea (This);
break;
}
case 0xC1:
{
scs_shf (This);
break;
}
case 0xC2:
{
scs_svf (This);
break;
}
default:
{
fprintf (stderr, "ERROR: Unknown 0x2B command %x\n", curchar);
}
}
return;
}
void
scs_processd3 (Tn5250SCS * This)
{
unsigned char curchar;
unsigned char nextchar;
curchar = fgetc (stdin);
This->curchar = curchar;
nextchar = fgetc (stdin);
if (nextchar == 0xF6)
{
scs_sto (This);
}
else
{
fprintf (stderr, "ERROR: Unknown 0x2BD3 %x %x", curchar, nextchar);
}
return;
}
void
scs_sgea (Tn5250SCS * This)
{
unsigned char sgea1, sgea2, sgea3;
sgea1 = fgetc (stdin);
sgea2 = fgetc (stdin);
sgea3 = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SGEA = %x %x %x\n", sgea1, sgea2, sgea3);
#endif
return;
}
void
scs_processd1 ()
{
unsigned char curchar;
curchar = fgetc (stdin);
switch (curchar)
{
case 0x06:
{
scs_process06 ();
break;
}
case 0x07:
{
scs_process07 ();
break;
}
case 0x03:
{
scs_processd103 ();
break;
}
default:
{
fprintf (stderr, "ERROR: Unknown 0x2BD1 command %x\n", curchar);
}
}
return;
}
void
scs_process06 ()
{
unsigned char curchar;
curchar = fgetc (stdin);
if (curchar == 0x01)
{
scs_scg (NULL);
}
else
{
fprintf (stderr, "ERROR: Unknown 0x2BD106 command %x\n", curchar);
}
return;
}
void
scs_process07 ()
{
unsigned char curchar;
curchar = fgetc (stdin);
if (curchar == 0x05)
{
scs_sfg (NULL);
}
else
{
fprintf (stderr, "ERROR: Unknown 0x2BD107 command %x\n", curchar);
}
return;
}
void
scs_processd103 ()
{
unsigned char curchar;
curchar = fgetc (stdin);
switch (curchar)
{
case 0x81:
{
scs_scgl (NULL);
break;
}
case 0x87:
{
scs_sffc (NULL);
break;
}
default:
{
fprintf (stderr, "ERROR: Unknown 0x2BD103 command %x\n", curchar);
break;
}
}
return;
}
void
scs_processd2 (Tn5250SCS * This)
{
unsigned char curchar;
unsigned char nextchar;
curchar = fgetc (stdin);
This->curchar = curchar;
nextchar = fgetc (stdin);
switch (nextchar)
{
case 0x01:
{
scs_stab (This);
break;
}
case 0x03:
{
scs_jtf (This->curchar);
break;
}
case 0x0D:
{
scs_sjm (This->curchar);
break;
}
case 0x40:
{
scs_spps (This);
break;
}
case 0x48:
{
scs_ppm (This);
break;
}
case 0x49:
{
scs_svm (This);
break;
}
case 0x4c:
{
scs_spsu (This);
break;
}
case 0x85:
{
scs_sea (This);
break;
}
case 0x11:
{
scs_shm (This);
break;
}
default:
{
switch (curchar)
{
case 0x03:
{
scs_process03 (nextchar, curchar);
break;
}
case 0x04:
{
scs_process04 (nextchar, curchar, &(This->cpi));
break;
}
default:
{
fprintf (stderr, "ERROR: Unknown 0x2BD2 command %x\n", curchar);
}
}
}
}
return;
}
void
scs_jtf (unsigned char curchar)
{
unsigned char nextchar;
int loop;
#ifdef DEBUG
fprintf (stderr, "JTF = ");
#endif
for (loop = 0; loop < curchar - 2; loop++)
{
nextchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, " %x", nextchar);
#endif
}
#ifdef DEBUG
fprintf (stderr, "\n");
#endif
return;
}
void
scs_sjm (unsigned char curchar)
{
unsigned char nextchar;
int loop;
#ifdef DEBUG
fprintf (stderr, "SJM = ");
#endif
for (loop = 0; loop < curchar - 2; loop++)
{
nextchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, " %x", nextchar);
#endif
}
#ifdef DEBUG
fprintf (stderr, "\n");
#endif
return;
}
void
scs_process03 (unsigned char nextchar, unsigned char curchar)
{
switch (nextchar)
{
case 0x45:
{
scs_sic (NULL);
break;
}
case 0x07:
{
scs_sil (NULL);
break;
}
case 0x09:
{
scs_sls (NULL);
break;
}
default:
{
fprintf (stderr, "ERROR: Unknown 0x2BD203 command %x\n", curchar);
}
}
return;
}
void
scs_sls (Tn5250SCS * This)
{
unsigned char curchar;
curchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SLS = %d\n", curchar);
#endif
return;
}
void
scs_process04 (unsigned char nextchar, unsigned char curchar, int *cpi)
{
switch (nextchar)
{
case 0x15:
{
scs_ssld (NULL);
break;
}
case 0x29:
{
scs_scd (cpi);
/*scs_scs (cpi); */
break;
}
default:
{
fprintf (stderr, "ERROR: Unknown 0x2BD204 command %x\n", curchar);
}
}
return;
}
void
scs_ssld (Tn5250SCS * This)
{
unsigned char curchar;
unsigned char nextchar;
curchar = fgetc (stdin);
nextchar = fgetc (stdin);
#ifdef DEBUG
fprintf (stderr, "SSLD = %d %d \n", curchar, nextchar);
#endif
return;
}
/* This function is obsolete - scs_scd() should be used */
void
scs_scs (int *cpi)
{
unsigned char curchar;
fprintf (stderr, "scs_scs was called but is obsolete!!!\n");
curchar = fgetc (stdin);
if (curchar == 0x00)
{
curchar = fgetc (stdin);
/* Here we convert characters per inch (CPI) to point size. In the
* future we will probably want these to be user definable.
*/
switch (curchar)
{
case 5:
{
*cpi = 14;
break;
}
case 10:
{
*cpi = 10;
break;
}
case 12:
{
*cpi = 9;
break;
}
case 13:
{
*cpi = 8;
break;
}
case 15:
{
*cpi = 7;
break;
}
case 16:
{
*cpi = 6;
break;
}
case 18:
{
*cpi = 5;
break;
}
case 20:
{
*cpi = 4;
break;
}
default:
{
*cpi = 10;
break;
}
}
#ifdef DEBUG
fprintf (stderr, "SCS = %d\n", curchar);
#endif
}
else
{
fprintf (stderr, "ERROR: Unknown 0x2BD20429 command %x\n", curchar);
}
return;
}
void
scs_default (Tn5250SCS * This)
{
printf ("%c", This->curchar);
return;
}
/* scs_main - reads the scs stream and calls functions to handle events
*/
void
scs_main (Tn5250SCS * This)
{
int curchar;
while ((curchar = fgetc (stdin)) != EOF)
{
This->curchar = curchar;
#ifdef DEBUG
fprintf (stderr, "%x ", This->curchar);
#endif
switch (This->curchar)
{
case SCS_TRANSPARENT:
{
#ifdef DEBUG
fprintf (stderr, "doing TRANSPARENT\n");
#endif
This->transparent (This);
break;
}
case SCS_NOOP:
{
#ifdef DEBUG
fprintf (stderr, "doing NOOP\n");
#endif
This->noop (This);
break;
}
case SCS_CR:
{
#ifdef DEBUG
fprintf (stderr, "doing CR\n");
#endif
This->cr (This);
break;
}
case SCS_FF:
{
#ifdef DEBUG
fprintf (stderr, "doing FF\n");
#endif
This->ff (This);
break;
}
case SCS_RFF:
{
#ifdef DEBUG
fprintf (stderr, "doing RFF\n");
#endif
This->rff (This);
break;
}
case SCS_NL:
{
#ifdef DEBUG
fprintf (stderr, "doing NL\n");
#endif
This->nl (This);
break;
}
case SCS_RNL:
{
#ifdef DEBUG
fprintf (stderr, "doing RNL\n");
#endif
This->rnl (This);
break;
}
case SCS_HT:
{
#ifdef DEBUG
fprintf (stderr, "doing HT\n");
#endif
This->ht (This);
break;
}
case SCS_PP:
{
#ifdef DEBUG
fprintf (stderr, "doing PP\n");
#endif
This->pp (This);
break;
}
case 0x2B:
{
#ifdef DEBUG
fprintf (stderr, "doing 2B\n");
#endif
This->process2b (This);
break;
}
case 0xFF:
{
/* This is a hack */
/* Don't know where the 0xFF is coming from */
fprintf (stderr, "Unhandled op 0xFF\n");
break;
}
default:
{
#ifdef DEBUG
fprintf (stderr, "doing scsdefault()\n");
#endif
This->scsdefault (This);
break;
}
}
}
return;
}
/* This initializes the scs callbacks
*/
Tn5250SCS *
tn5250_scs_new ()
{
Tn5250SCS *scs = tn5250_new (Tn5250SCS, 1);
if (scs == NULL)
{
return NULL;
}
scs->sic = scs_sic;
scs->sea = scs_sea;
scs->noop = scs_noop;
scs->transparent = scs_transparent;
scs->spsu = scs_spsu;
scs->ppm = scs_ppm;
scs->spps = scs_spps;
scs->shf = scs_shf;
scs->svf = scs_svf;
scs->ff = scs_ff;
scs->rff = scs_rff;
scs->sto = scs_sto;
scs->shm = scs_shm;
scs->svm = scs_svm;
scs->sffc = scs_sffc;
scs->scgl = scs_scgl;
scs->scg = scs_scg;
scs->sfg = scs_sfg;
scs->scd = scs_scd;
scs->pp = scs_pp;
scs->sbs = scs_sbs;
scs->sps = scs_sps;
scs->nl = scs_nl;
scs->irs = scs_irs;
scs->rnl = scs_rnl;
scs->irt = scs_irt;
scs->stab = scs_stab;
scs->ht = scs_ht;
scs->it = scs_it;
scs->sil = scs_sil;
scs->lf = scs_lf;
scs->cr = scs_cr;
scs->ssld = scs_ssld;
scs->sls = scs_sls;
scs->sgea = scs_sgea;
scs->process2b = scs_process2b;
scs->scsdefault = scs_default;
scs->pagewidth = 0;
scs->pagelength = 0;
scs->cpi = 0;
scs->column = 0;
scs->row = 0;
scs->curchar = 0;
scs->data = NULL;
return scs;
}
syntax highlighted by Code2HTML, v. 0.9.1