home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / ELEP2F.ZIP / elep2kbd.c < prev    next >
Text File  |  1993-03-25  |  20KB  |  407 lines

  1. /*█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
  2.   █                                                                          █
  3.   █     Name : ELEP2KBD.C (ELEP2KBD.DLL)                                     █
  4.   █                                                                          █
  5.   █ Function : Collection of functions called by ELEP2.  They are assigned   █
  6.   █            via the ELEP2KEY program.                                     █
  7.   █                                                                          █
  8.   █  History : 07/90 (Kenneth Kahn)                                          █
  9.   █            - Created                                                     █
  10.   █                                                                          █
  11.   █            05/91 (Kenneth Kahn)  V4.00                                   █
  12.   █                                                                          █
  13.   █             - External name changed to allow CP78 to be given to         █
  14.   █               customers.  The new name is:                               █
  15.   █                                                                          █
  16.   █                 "OS/2 Entry Level 3270 Emulation Program"                █
  17.   █                                                                          █
  18.   █       OS : OS/2 V1.x V2.x                                                █
  19.   █                                                                          █
  20.   ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀*/
  21.  
  22. /*╔═════════════════════════════════════════════════════════════════════════╗
  23.   ║                          OS/2 API Includes                              ║
  24.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  25. #define INCL_DOSDEVICES
  26. #define INCL_DOSFILEMGR
  27. #define INCL_DOSMODULEMGR
  28. #define INCL_DOSMISC
  29. #define INCL_DOSQUEUES
  30. #include <OS2.H>
  31.  
  32.  
  33. /*╔═════════════════════════════════════════════════════════════════════════╗
  34.   ║                           C/2 Includes                                  ║
  35.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  36. #include <STRING.H>
  37. #include <STDIO.H>
  38. #include <IO.H>
  39. #include <DOS.H>
  40. #include <STDLIB.H>
  41.  
  42. /*╔═════════════════════════════════════════════════════════════════════════╗
  43.   ║ ELEP2KBD.DLL Parameter List                                             ║
  44.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  45. #include <ELEP2KBD.H>
  46.  
  47. /*╔═════════════════════════════════════════════════════════════════════════╗
  48.   ║ Definition of all Parameter Lists Passed to ELEP2DD IOCTL               ║
  49.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  50. union {
  51.  
  52.   /*╔═══════════════════════════════════════════════════════════════════════╗
  53.     ║ IOCTL10 - Send a key to the Host with ASCII Translation               ║
  54.     ╚═══════════════════════════════════════════════════════════════════════╝*/
  55.   struct {
  56.     UCHAR CardNo;
  57.     UINT  AsciiCode;
  58.   } IOCTL10;
  59.  
  60.   /*╔═══════════════════════════════════════════════════════════════════════╗
  61.     ║ IOCTL14  - Load new KeyBoard table into ELEP2DD                       ║
  62.     ╚═══════════════════════════════════════════════════════════════════════╝*/
  63.   struct {
  64.     UCHAR CardNo;
  65.     UINT  KBD_Seg;
  66.     UINT  KBD_Ofs;
  67.     UINT  KBD_Size;
  68.   } IOCTL14;
  69.  
  70. } IOCTLParms;
  71.  
  72. /*╔═════════════════════════════════════════════════════════════════════════╗
  73.   ║ Definition of Data List passed Back from ELEP2DD IOCTL                  ║
  74.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  75. struct {
  76.   int RC;                         /* return Code                             */
  77. } IOCTLData;
  78.  
  79. #define DCA_Char       *(ELEP_Parms->DCA+DCA_Ptr)
  80. #define LVB_Char       *(ELEP_Parms->LVB+LVB_Ptr)
  81.  
  82. /*╔═════════════════════════════════════════════════════════════════════════╗
  83.   ║ Values for Key Type                                                     ║
  84.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  85. #define ASCII              10     /* Send HostKey with ASCII Translation     */
  86. #define SCAN                3     /* Send HostKey as Raw Scan Code           */
  87.  
  88. #define HOLD                1     /* Queue Key if Input Prohibited           */
  89. #define NOHOLD              0     /* Send key in any case                    */
  90.  
  91. /*╔═════════════════════════════════════════════════════════════════════════╗
  92.   ║ Valid Scan Codes for Type=SCAN                                          ║
  93.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  94. #define Right          0x001A     /* 3174 Scan Code for Right Cursor         */
  95. #define Left           0x0016     /* 3174 Scan Code for Left  Cursor         */
  96. #define Reset          0x0034     /* 3174 Scan Code for Reset                */
  97. #define Insert         0x000C     /* 3174 Scan Code for Insert               */
  98. #define Delete         0x000D     /* 3174 Scan Code for Delete               */
  99. #define EraseEOL       0x0055     /* 3174 Scan Code for EOF   key            */
  100.  
  101.  
  102. /*╔═════════════════════════════════════════════════════════════════════════╗
  103.   ║                                                                         ║
  104.   ║                      Global Variables                                   ║
  105.   ║                                                                         ║
  106.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  107. HFILE   DD_Handle;                /* ELEP2DD handle From DosOpen             */
  108. HQUEUE  KBD_Handle;               /* ELEP2 KBD Queue Handle                  */
  109.  
  110. UINT   LVB_Max;                   /* Maximum LVB index                       */
  111. UINT   LVB_Ptr;                   /* Current LVB index                       */
  112.  
  113. USHORT KBD_Q_Request;
  114. USHORT KBD_Q_Length;
  115. UCHAR  KBD_Q_Priority;
  116.  
  117. UINT   DCA_Max;                   /* Maximum DCA index                       */
  118. UINT   DCA_Ptr;                   /* Current DCA index                       */
  119.  
  120. CHAR   *FileName,*DLLName,*KBDName;
  121. FILE   *DLL_List;
  122. FILE   *KBD_List;
  123. FILE   *KBD_Table;
  124. UINT   Max_Path_Length = 255;
  125. INT    (pascal far *Proc_Addr)(ELEPKBD_PList);
  126.  
  127. /*╔═════════════════════════════════════════════════════════════════════════╗
  128.   ║ Table used to read binary file into to pass to IOCTL 14                 ║
  129.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  130. UCHAR *Transfer_Buffer;
  131.  
  132. /*╔═════════════════════════════════════════════════════════════════════════╗
  133.   ║                                                                         ║
  134.   ║                      Function Prototypes (Local)                        ║
  135.   ║                                                                         ║
  136.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  137. INT  EXPENTRY _saveregs ELEP2KBD_Entry(ELEPKBD_PList);
  138.  
  139. INT  Skip_Word(ELEPKBD_PList);
  140. INT  Load_KBD_Table(ELEPKBD_PList);
  141.  
  142. VOID Host_Key(USHORT,UCHAR,UCHAR);
  143.  
  144. /*╔═════════════════════════════════════════════════════════════════════════╗
  145.   ║     Name : ELEP2KBD_Entry                                               ║
  146.   ║                                                                         ║
  147.   ║ Function : Main Entry Point for ELEP2KBD Functions.                     ║
  148.   ║                                                                         ║
  149.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  150. INT EXPENTRY _saveregs ELEP2KBD_Entry(ELEPKBD_PList ELEP_Parms) {
  151.  
  152. BYTE    Function;
  153. HMODULE DLL_Handle;
  154.  
  155. /*╔═════════════════════════════════════════════════════════════════════════╗
  156.   ║ Allocate a buffer for the returned fully qualified ELEP2DLL.$L$ name    ║
  157.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  158. FileName = (CHAR *)malloc(Max_Path_Length*sizeof(CHAR));
  159.  
  160. /*╔═════════════════════════════════════════════════════════════════════════╗
  161.   ║ See if the ELEP2DLL.$L$ exists on DPATH and get the fully qualified name║
  162.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  163. if (!(DosSearchPath(3,"DPATH","ELEP2DLL.$L$",FileName,Max_Path_Length))) {
  164.   /*╔═══════════════════════════════════════════════════════════════════════╗
  165.     ║ Open ELEP2KBD.$L$ R/O in Text mode                                    ║
  166.     ╚═══════════════════════════════════════════════════════════════════════╝*/
  167.   if ((DLL_List = fopen(FileName,"r")) != NULL) {
  168.     /*╔═════════════════════════════════════════════════════════════════════╗
  169.       ║ Allocate a buffer for the DLL file name                             ║
  170.       ╚═════════════════════════════════════════════════════════════════════╝*/
  171.     DLLName = (CHAR *)malloc(Max_Path_Length*sizeof(CHAR));
  172.  
  173.     /*╔═════════════════════════════════════════════════════════════════════╗
  174.       ║ Loop through all the records in ELEP2DLL.$L$ until a DLL is found   ║
  175.       ║ that can process the function.                                      ║
  176.       ╚═════════════════════════════════════════════════════════════════════╝*/
  177.     while (fgets(FileName,Max_Path_Length,DLL_List) != NULL) {
  178.  
  179.       /*╔═══════════════════════════════════════════════════════════════════╗
  180.         ║ If the line starts with a '*', treat it as a comment line.        ║
  181.         ╚═══════════════════════════════════════════════════════════════════╝*/
  182.       if (FileName[0] == '*') {
  183.         continue;
  184.       }
  185.  
  186.       sscanf(FileName,"%[^\n]\n",DLLName);   /* Remove trailing CRLF, if any */
  187.       /*╔═══════════════════════════════════════════════════════════════════╗
  188.         ║ Load the DLL into storage                                         ║
  189.         ╚═══════════════════════════════════════════════════════════════════╝*/
  190.       if (DosLoadModule(NULL,0,DLLName,&DLL_Handle) == 0) {
  191.         /*╔═════════════════════════════════════════════════════════════════╗
  192.           ║ Call the requested Function                                     ║
  193.           ╚═════════════════════════════════════════════════════════════════╝*/
  194.         if ((DosGetProcAddr(DLL_Handle,MAKEP(0,ELEP_Parms->Ordinal),(PFN *)&Proc_Addr) == 0)) {
  195.           free(FileName);
  196.           free(DLLName);
  197.           fclose(DLL_List);
  198.           return (*Proc_Addr)(ELEP_Parms);
  199.         }
  200.       }
  201.     }
  202.     free(DLLName);
  203.     fclose(DLL_List);
  204.   }
  205. }
  206.  
  207. free(FileName);
  208.  
  209. DD_Handle  = ELEP_Parms->ELEP2DD_Handle;
  210. KBD_Handle = ELEP_Parms->KBD_Q_Handle;
  211.  
  212. IOCTLParms.IOCTL10.CardNo = ELEP_Parms->CardNo;
  213.  
  214. /*╔═════════════════════════════════════════════════════════════════════════╗
  215.   ║ Set the maximum LVB index.  Subtract 1 from the HostRows to skip the    ║
  216.   ║ OIA line.                                                               ║
  217.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  218. LVB_Max = ((ELEP_Parms->Host_Rows - 1) * ELEP_Parms->Host_Cols) * 2;
  219.  
  220. /*╔═════════════════════════════════════════════════════════════════════════╗
  221.   ║ Get the initial LVB pointer.                                            ║
  222.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  223. LVB_Ptr = (ELEP_Parms->DCA_Address-ELEP_Parms->Host_Cols) * 2;
  224.  
  225. /*╔═════════════════════════════════════════════════════════════════════════╗
  226.   ║ Set the maximum DCA index.                                              ║
  227.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  228. DCA_Max = ELEP_Parms->Host_Rows * ELEP_Parms->Host_Cols;
  229.  
  230. /*╔═════════════════════════════════════════════════════════════════════════╗
  231.   ║ Get the initial DCA pointer.                                            ║
  232.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  233. DCA_Ptr = ELEP_Parms->DCA_Address;
  234.  
  235. /*╔═════════════════════════════════════════════════════════════════════════╗
  236.   ║ Extract out function code from low byte of argument.                    ║
  237.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  238. Function = (BYTE) (ELEP_Parms->Argument & 0x00FF);
  239.  
  240. /*╔═════════════════════════════════════════════════════════════════════════╗
  241.   ║ Call the indicated function                                             ║
  242.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  243. switch (Function) {
  244.  
  245. case 1:
  246.   return Skip_Word(ELEP_Parms);
  247.   break;
  248.  
  249. case 2:
  250.   return Load_KBD_Table(ELEP_Parms);
  251.   break;
  252.  
  253. default:
  254.   break;
  255.  
  256. }
  257.  
  258. return -1;                        /* Indicate invalid function               */
  259.  
  260. }
  261.  
  262. /*╔═════════════════════════════════════════════════════════════════════════╗
  263.   ║     Name : Skip_word                                                    ║
  264.   ║                                                                         ║
  265.   ║ Function : Skips to the beginning of the Next Word.  Use the Logical    ║
  266.   ║            Video Buffer (LVB) to avoid having to worry about attribute  ║
  267.   ║            bytes.                                                       ║
  268.   ║                                                                         ║
  269.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  270. INT Skip_Word(ELEPKBD_PList ELEP_Parms) {
  271.  
  272. UINT  Count = 0;;                 /* How many Right's to send to host        */
  273.  
  274. /*╔═════════════════════════════════════════════════════════════════════════╗
  275.   ║ Skip to the end of the current word.  If the next to last character     ║
  276.   ║ cell on the screen is reached, no next word is possible so the search   ║
  277.   ║ can be stopped.                                                         ║
  278.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  279. while ((LVB_Ptr < (LVB_Max-2)) && (LVB_Char != ' ')) {
  280.   Count++;
  281.   LVB_Ptr += 2;
  282. }
  283.  
  284. if (LVB_Ptr == (LVB_Max-2))
  285.   return 1;
  286.  
  287. /*╔═════════════════════════════════════════════════════════════════════════╗
  288.   ║ Skip to the Begining of the next word                                   ║
  289.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  290. while ((LVB_Ptr < LVB_Max) && (*(ELEP_Parms->LVB+LVB_Ptr) == ' ')) {
  291.   Count++;
  292.   LVB_Ptr += 2;
  293. }
  294.  
  295. if (LVB_Ptr >= LVB_Max)
  296.   return 1;
  297.  
  298. Count++;                          /* Bump count past last blank              */
  299.  
  300. /*╔═════════════════════════════════════════════════════════════════════════╗
  301.   ║ If we haven't reached the end of the LVB, then move the cursor to it's  ║
  302.   ║ new position.                                                           ║
  303.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  304. if (LVB_Ptr < LVB_Max) {
  305.   while (--Count != 0) {
  306.     Host_Key (Right,SCAN,HOLD);
  307.   }
  308. }
  309.  
  310. return 0;
  311.  
  312. }
  313.  
  314. /*╔═════════════════════════════════════════════════════════════════════════╗
  315.   ║     Name : Load_KBD_Table                                               ║
  316.   ║                                                                         ║
  317.   ║ Function : The file ELEP2KBD.$L$ contains a list of KeyBoard XLation    ║
  318.   ║            tables, compiled via ELEP2KEY.  This routine will load one   ║
  319.   ║            of these tables into the ELEP2DD Device Driver.              ║
  320.   ║                                                                         ║
  321.   ║    InPut : - Relative record number of ELEP2KBD.$L$ containing the name ║
  322.   ║              of the new keyboard translation table to load.             ║
  323.   ║                                                                         ║
  324.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  325. INT Load_KBD_Table(ELEPKBD_PList ELEP_Parms) {
  326.  
  327. BYTE  KBD_Record_No;              /* ELEP2KBD.$L$ record number              */
  328. BYTE  Count;
  329.  
  330. /*╔═════════════════════════════════════════════════════════════════════════╗
  331.   ║ Extract out the ELEP2KBD.$L$ record number from the argument            ║
  332.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  333. KBD_Record_No = (BYTE) ((ELEP_Parms->Argument >> 8) & 0x00FF);
  334.  
  335. /*╔═════════════════════════════════════════════════════════════════════════╗
  336.   ║ Allocate a buffer for the returned fully qualified ELEP2KBD.$L$ name    ║
  337.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  338. FileName = (CHAR *)malloc(Max_Path_Length*sizeof(CHAR));
  339.  
  340. /*╔═════════════════════════════════════════════════════════════════════════╗
  341.   ║ See if the ELEP2KBD.$L$ exists on DPATH and get the fully qualified name║
  342.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  343. if (!(DosSearchPath(3,"DPATH","ELEP2KBD.$L$",FileName,Max_Path_Length))) {
  344.   /*╔═══════════════════════════════════════════════════════════════════════╗
  345.     ║ Open ELEP2KBD.$L$ R/O in Text mode                                    ║
  346.     ╚═══════════════════════════════════════════════════════════════════════╝*/
  347.   if ((KBD_List = fopen(FileName,"r")) != NULL) {
  348.     /*╔═════════════════════════════════════════════════════════════════════╗
  349.       ║ Allocate a buffer for the KBD Translation Table name                ║
  350.       ╚═════════════════════════════════════════════════════════════════════╝*/
  351.     KBDName = (CHAR *)malloc(Max_Path_Length*sizeof(CHAR));
  352.  
  353.     /*╔═════════════════════════════════════════════════════════════════════╗
  354.       ║ Read in the requested record from ELEP2KBD.$L$                      ║
  355.       ╚═════════════════════════════════════════════════════════════════════╝*/
  356.     for (Count=1;((fgets(FileName,Max_Path_Length,KBD_List) != NULL) && (Count < KBD_Record_No));Count++) {}
  357.  
  358.     /*╔═════════════════════════════════════════════════════════════════════╗
  359.       ║ If the record was found, then Load the specified keyboard table     ║
  360.       ║ into the ELEP2 Device Driver.                                       ║
  361.       ╚═════════════════════════════════════════════════════════════════════╝*/
  362.     if (!feof(KBD_List)) {
  363.       sscanf(FileName,"%[^\n]\n",KBDName);
  364.       if ((KBD_Table = fopen(KBDName,"rb")) != NULL) {
  365.         IOCTLParms.IOCTL14.KBD_Size = (INT) filelength(fileno(KBD_Table));
  366.         Transfer_Buffer = calloc(IOCTLParms.IOCTL14.KBD_Size,1);
  367.         fread (Transfer_Buffer,1,IOCTLParms.IOCTL14.KBD_Size,KBD_Table);
  368.         IOCTLParms.IOCTL14.KBD_Seg  = FP_SEG(Transfer_Buffer);
  369.         IOCTLParms.IOCTL14.KBD_Ofs  = FP_OFF(Transfer_Buffer);
  370.         DosDevIOCtl((PCHAR)&IOCTLData,(PCHAR)&IOCTLParms,14,0x80,DD_Handle);
  371.         fclose(KBD_Table);
  372.       }
  373.     }
  374.  
  375.     free (Transfer_Buffer);
  376.     free(KBDName);
  377.     fclose(KBD_List);
  378.  
  379.  
  380.   }
  381. }
  382.  
  383. free(FileName);
  384.  
  385. return 0;
  386.  
  387. }
  388.  
  389. /*╔═════════════════════════════════════════════════════════════════════════╗
  390.   ║                                                                         ║
  391.   ║     Name : Host_Key                                                     ║
  392.   ║                                                                         ║
  393.   ║ Function : Send keys to the host with or without ASCII Translation.     ║
  394.   ║                                                                         ║
  395.   ╚═════════════════════════════════════════════════════════════════════════╝*/
  396. void Host_Key(USHORT Key, UCHAR Type, UCHAR Hold) {
  397.  
  398. KBD_Q_Request = Key;
  399. KBD_Q_Length  = MAKEUSHORT(Type,Hold);
  400. KBD_Q_Priority = (Hold) ? (UCHAR)0 : (UCHAR)15;
  401.  
  402. DosWriteQueue (KBD_Handle,KBD_Q_Request,KBD_Q_Length,NULL,KBD_Q_Priority);
  403.  
  404. return;
  405.  
  406. }
  407.