home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
network
/
3270
/
elep2kbd.c
< prev
next >
Wrap
Text File
|
1993-03-25
|
20KB
|
407 lines
/*█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
█ █
█ Name : ELEP2KBD.C (ELEP2KBD.DLL) █
█ █
█ Function : Collection of functions called by ELEP2. They are assigned █
█ via the ELEP2KEY program. █
█ █
█ History : 07/90 (Kenneth Kahn) █
█ - Created █
█ █
█ 05/91 (Kenneth Kahn) V4.00 █
█ █
█ - External name changed to allow CP78 to be given to █
█ customers. The new name is: █
█ █
█ "OS/2 Entry Level 3270 Emulation Program" █
█ █
█ OS : OS/2 V1.x V2.x █
█ █
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀*/
/*╔═════════════════════════════════════════════════════════════════════════╗
║ OS/2 API Includes ║
╚═════════════════════════════════════════════════════════════════════════╝*/
#define INCL_DOSDEVICES
#define INCL_DOSFILEMGR
#define INCL_DOSMODULEMGR
#define INCL_DOSMISC
#define INCL_DOSQUEUES
#include <OS2.H>
/*╔═════════════════════════════════════════════════════════════════════════╗
║ C/2 Includes ║
╚═════════════════════════════════════════════════════════════════════════╝*/
#include <STRING.H>
#include <STDIO.H>
#include <IO.H>
#include <DOS.H>
#include <STDLIB.H>
/*╔═════════════════════════════════════════════════════════════════════════╗
║ ELEP2KBD.DLL Parameter List ║
╚═════════════════════════════════════════════════════════════════════════╝*/
#include <ELEP2KBD.H>
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Definition of all Parameter Lists Passed to ELEP2DD IOCTL ║
╚═════════════════════════════════════════════════════════════════════════╝*/
union {
/*╔═══════════════════════════════════════════════════════════════════════╗
║ IOCTL10 - Send a key to the Host with ASCII Translation ║
╚═══════════════════════════════════════════════════════════════════════╝*/
struct {
UCHAR CardNo;
UINT AsciiCode;
} IOCTL10;
/*╔═══════════════════════════════════════════════════════════════════════╗
║ IOCTL14 - Load new KeyBoard table into ELEP2DD ║
╚═══════════════════════════════════════════════════════════════════════╝*/
struct {
UCHAR CardNo;
UINT KBD_Seg;
UINT KBD_Ofs;
UINT KBD_Size;
} IOCTL14;
} IOCTLParms;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Definition of Data List passed Back from ELEP2DD IOCTL ║
╚═════════════════════════════════════════════════════════════════════════╝*/
struct {
int RC; /* return Code */
} IOCTLData;
#define DCA_Char *(ELEP_Parms->DCA+DCA_Ptr)
#define LVB_Char *(ELEP_Parms->LVB+LVB_Ptr)
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Values for Key Type ║
╚═════════════════════════════════════════════════════════════════════════╝*/
#define ASCII 10 /* Send HostKey with ASCII Translation */
#define SCAN 3 /* Send HostKey as Raw Scan Code */
#define HOLD 1 /* Queue Key if Input Prohibited */
#define NOHOLD 0 /* Send key in any case */
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Valid Scan Codes for Type=SCAN ║
╚═════════════════════════════════════════════════════════════════════════╝*/
#define Right 0x001A /* 3174 Scan Code for Right Cursor */
#define Left 0x0016 /* 3174 Scan Code for Left Cursor */
#define Reset 0x0034 /* 3174 Scan Code for Reset */
#define Insert 0x000C /* 3174 Scan Code for Insert */
#define Delete 0x000D /* 3174 Scan Code for Delete */
#define EraseEOL 0x0055 /* 3174 Scan Code for EOF key */
/*╔═════════════════════════════════════════════════════════════════════════╗
║ ║
║ Global Variables ║
║ ║
╚═════════════════════════════════════════════════════════════════════════╝*/
HFILE DD_Handle; /* ELEP2DD handle From DosOpen */
HQUEUE KBD_Handle; /* ELEP2 KBD Queue Handle */
UINT LVB_Max; /* Maximum LVB index */
UINT LVB_Ptr; /* Current LVB index */
USHORT KBD_Q_Request;
USHORT KBD_Q_Length;
UCHAR KBD_Q_Priority;
UINT DCA_Max; /* Maximum DCA index */
UINT DCA_Ptr; /* Current DCA index */
CHAR *FileName,*DLLName,*KBDName;
FILE *DLL_List;
FILE *KBD_List;
FILE *KBD_Table;
UINT Max_Path_Length = 255;
INT (pascal far *Proc_Addr)(ELEPKBD_PList);
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Table used to read binary file into to pass to IOCTL 14 ║
╚═════════════════════════════════════════════════════════════════════════╝*/
UCHAR *Transfer_Buffer;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ ║
║ Function Prototypes (Local) ║
║ ║
╚═════════════════════════════════════════════════════════════════════════╝*/
INT EXPENTRY _saveregs ELEP2KBD_Entry(ELEPKBD_PList);
INT Skip_Word(ELEPKBD_PList);
INT Load_KBD_Table(ELEPKBD_PList);
VOID Host_Key(USHORT,UCHAR,UCHAR);
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Name : ELEP2KBD_Entry ║
║ ║
║ Function : Main Entry Point for ELEP2KBD Functions. ║
║ ║
╚═════════════════════════════════════════════════════════════════════════╝*/
INT EXPENTRY _saveregs ELEP2KBD_Entry(ELEPKBD_PList ELEP_Parms) {
BYTE Function;
HMODULE DLL_Handle;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Allocate a buffer for the returned fully qualified ELEP2DLL.$L$ name ║
╚═════════════════════════════════════════════════════════════════════════╝*/
FileName = (CHAR *)malloc(Max_Path_Length*sizeof(CHAR));
/*╔═════════════════════════════════════════════════════════════════════════╗
║ See if the ELEP2DLL.$L$ exists on DPATH and get the fully qualified name║
╚═════════════════════════════════════════════════════════════════════════╝*/
if (!(DosSearchPath(3,"DPATH","ELEP2DLL.$L$",FileName,Max_Path_Length))) {
/*╔═══════════════════════════════════════════════════════════════════════╗
║ Open ELEP2KBD.$L$ R/O in Text mode ║
╚═══════════════════════════════════════════════════════════════════════╝*/
if ((DLL_List = fopen(FileName,"r")) != NULL) {
/*╔═════════════════════════════════════════════════════════════════════╗
║ Allocate a buffer for the DLL file name ║
╚═════════════════════════════════════════════════════════════════════╝*/
DLLName = (CHAR *)malloc(Max_Path_Length*sizeof(CHAR));
/*╔═════════════════════════════════════════════════════════════════════╗
║ Loop through all the records in ELEP2DLL.$L$ until a DLL is found ║
║ that can process the function. ║
╚═════════════════════════════════════════════════════════════════════╝*/
while (fgets(FileName,Max_Path_Length,DLL_List) != NULL) {
/*╔═══════════════════════════════════════════════════════════════════╗
║ If the line starts with a '*', treat it as a comment line. ║
╚═══════════════════════════════════════════════════════════════════╝*/
if (FileName[0] == '*') {
continue;
}
sscanf(FileName,"%[^\n]\n",DLLName); /* Remove trailing CRLF, if any */
/*╔═══════════════════════════════════════════════════════════════════╗
║ Load the DLL into storage ║
╚═══════════════════════════════════════════════════════════════════╝*/
if (DosLoadModule(NULL,0,DLLName,&DLL_Handle) == 0) {
/*╔═════════════════════════════════════════════════════════════════╗
║ Call the requested Function ║
╚═════════════════════════════════════════════════════════════════╝*/
if ((DosGetProcAddr(DLL_Handle,MAKEP(0,ELEP_Parms->Ordinal),(PFN *)&Proc_Addr) == 0)) {
free(FileName);
free(DLLName);
fclose(DLL_List);
return (*Proc_Addr)(ELEP_Parms);
}
}
}
free(DLLName);
fclose(DLL_List);
}
}
free(FileName);
DD_Handle = ELEP_Parms->ELEP2DD_Handle;
KBD_Handle = ELEP_Parms->KBD_Q_Handle;
IOCTLParms.IOCTL10.CardNo = ELEP_Parms->CardNo;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Set the maximum LVB index. Subtract 1 from the HostRows to skip the ║
║ OIA line. ║
╚═════════════════════════════════════════════════════════════════════════╝*/
LVB_Max = ((ELEP_Parms->Host_Rows - 1) * ELEP_Parms->Host_Cols) * 2;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Get the initial LVB pointer. ║
╚═════════════════════════════════════════════════════════════════════════╝*/
LVB_Ptr = (ELEP_Parms->DCA_Address-ELEP_Parms->Host_Cols) * 2;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Set the maximum DCA index. ║
╚═════════════════════════════════════════════════════════════════════════╝*/
DCA_Max = ELEP_Parms->Host_Rows * ELEP_Parms->Host_Cols;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Get the initial DCA pointer. ║
╚═════════════════════════════════════════════════════════════════════════╝*/
DCA_Ptr = ELEP_Parms->DCA_Address;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Extract out function code from low byte of argument. ║
╚═════════════════════════════════════════════════════════════════════════╝*/
Function = (BYTE) (ELEP_Parms->Argument & 0x00FF);
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Call the indicated function ║
╚═════════════════════════════════════════════════════════════════════════╝*/
switch (Function) {
case 1:
return Skip_Word(ELEP_Parms);
break;
case 2:
return Load_KBD_Table(ELEP_Parms);
break;
default:
break;
}
return -1; /* Indicate invalid function */
}
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Name : Skip_word ║
║ ║
║ Function : Skips to the beginning of the Next Word. Use the Logical ║
║ Video Buffer (LVB) to avoid having to worry about attribute ║
║ bytes. ║
║ ║
╚═════════════════════════════════════════════════════════════════════════╝*/
INT Skip_Word(ELEPKBD_PList ELEP_Parms) {
UINT Count = 0;; /* How many Right's to send to host */
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Skip to the end of the current word. If the next to last character ║
║ cell on the screen is reached, no next word is possible so the search ║
║ can be stopped. ║
╚═════════════════════════════════════════════════════════════════════════╝*/
while ((LVB_Ptr < (LVB_Max-2)) && (LVB_Char != ' ')) {
Count++;
LVB_Ptr += 2;
}
if (LVB_Ptr == (LVB_Max-2))
return 1;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Skip to the Begining of the next word ║
╚═════════════════════════════════════════════════════════════════════════╝*/
while ((LVB_Ptr < LVB_Max) && (*(ELEP_Parms->LVB+LVB_Ptr) == ' ')) {
Count++;
LVB_Ptr += 2;
}
if (LVB_Ptr >= LVB_Max)
return 1;
Count++; /* Bump count past last blank */
/*╔═════════════════════════════════════════════════════════════════════════╗
║ If we haven't reached the end of the LVB, then move the cursor to it's ║
║ new position. ║
╚═════════════════════════════════════════════════════════════════════════╝*/
if (LVB_Ptr < LVB_Max) {
while (--Count != 0) {
Host_Key (Right,SCAN,HOLD);
}
}
return 0;
}
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Name : Load_KBD_Table ║
║ ║
║ Function : The file ELEP2KBD.$L$ contains a list of KeyBoard XLation ║
║ tables, compiled via ELEP2KEY. This routine will load one ║
║ of these tables into the ELEP2DD Device Driver. ║
║ ║
║ InPut : - Relative record number of ELEP2KBD.$L$ containing the name ║
║ of the new keyboard translation table to load. ║
║ ║
╚═════════════════════════════════════════════════════════════════════════╝*/
INT Load_KBD_Table(ELEPKBD_PList ELEP_Parms) {
BYTE KBD_Record_No; /* ELEP2KBD.$L$ record number */
BYTE Count;
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Extract out the ELEP2KBD.$L$ record number from the argument ║
╚═════════════════════════════════════════════════════════════════════════╝*/
KBD_Record_No = (BYTE) ((ELEP_Parms->Argument >> 8) & 0x00FF);
/*╔═════════════════════════════════════════════════════════════════════════╗
║ Allocate a buffer for the returned fully qualified ELEP2KBD.$L$ name ║
╚═════════════════════════════════════════════════════════════════════════╝*/
FileName = (CHAR *)malloc(Max_Path_Length*sizeof(CHAR));
/*╔═════════════════════════════════════════════════════════════════════════╗
║ See if the ELEP2KBD.$L$ exists on DPATH and get the fully qualified name║
╚═════════════════════════════════════════════════════════════════════════╝*/
if (!(DosSearchPath(3,"DPATH","ELEP2KBD.$L$",FileName,Max_Path_Length))) {
/*╔═══════════════════════════════════════════════════════════════════════╗
║ Open ELEP2KBD.$L$ R/O in Text mode ║
╚═══════════════════════════════════════════════════════════════════════╝*/
if ((KBD_List = fopen(FileName,"r")) != NULL) {
/*╔═════════════════════════════════════════════════════════════════════╗
║ Allocate a buffer for the KBD Translation Table name ║
╚═════════════════════════════════════════════════════════════════════╝*/
KBDName = (CHAR *)malloc(Max_Path_Length*sizeof(CHAR));
/*╔═════════════════════════════════════════════════════════════════════╗
║ Read in the requested record from ELEP2KBD.$L$ ║
╚═════════════════════════════════════════════════════════════════════╝*/
for (Count=1;((fgets(FileName,Max_Path_Length,KBD_List) != NULL) && (Count < KBD_Record_No));Count++) {}
/*╔═════════════════════════════════════════════════════════════════════╗
║ If the record was found, then Load the specified keyboard table ║
║ into the ELEP2 Device Driver. ║
╚═════════════════════════════════════════════════════════════════════╝*/
if (!feof(KBD_List)) {
sscanf(FileName,"%[^\n]\n",KBDName);
if ((KBD_Table = fopen(KBDName,"rb")) != NULL) {
IOCTLParms.IOCTL14.KBD_Size = (INT) filelength(fileno(KBD_Table));
Transfer_Buffer = calloc(IOCTLParms.IOCTL14.KBD_Size,1);
fread (Transfer_Buffer,1,IOCTLParms.IOCTL14.KBD_Size,KBD_Table);
IOCTLParms.IOCTL14.KBD_Seg = FP_SEG(Transfer_Buffer);
IOCTLParms.IOCTL14.KBD_Ofs = FP_OFF(Transfer_Buffer);
DosDevIOCtl((PCHAR)&IOCTLData,(PCHAR)&IOCTLParms,14,0x80,DD_Handle);
fclose(KBD_Table);
}
}
free (Transfer_Buffer);
free(KBDName);
fclose(KBD_List);
}
}
free(FileName);
return 0;
}
/*╔═════════════════════════════════════════════════════════════════════════╗
║ ║
║ Name : Host_Key ║
║ ║
║ Function : Send keys to the host with or without ASCII Translation. ║
║ ║
╚═════════════════════════════════════════════════════════════════════════╝*/
void Host_Key(USHORT Key, UCHAR Type, UCHAR Hold) {
KBD_Q_Request = Key;
KBD_Q_Length = MAKEUSHORT(Type,Hold);
KBD_Q_Priority = (Hold) ? (UCHAR)0 : (UCHAR)15;
DosWriteQueue (KBD_Handle,KBD_Q_Request,KBD_Q_Length,NULL,KBD_Q_Priority);
return;
}