home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / tn3270 / ctlr / api.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-26  |  19.3 KB  |  756 lines

  1. /*-
  2.  * Copyright (c) 1988 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)api.c    4.5 (Berkeley) 4/26/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * This file implements the API used in the PC version.
  40.  */
  41.  
  42. #include <stdio.h>
  43.  
  44. #include "api.h"
  45. #include "../general/general.h"
  46.  
  47. #include "../api/disp_asc.h"
  48.  
  49. #include "screen.h"
  50. #include "hostctlr.h"
  51. #include "oia.h"
  52.  
  53. #include "../general/globals.h"
  54.  
  55. int apitrace = 0;
  56.  
  57. /*
  58.  * Some defines for things we use internally.
  59.  */
  60.  
  61. #define    PS_SESSION_ID    23
  62. #define    BUF_SESSION_ID    0
  63.  
  64. /*
  65.  * General utility routines.
  66.  */
  67.  
  68. #if    defined(MSDOS)
  69.  
  70. #if    defined(LINT_ARGS)
  71. static void movetous(char *, int, int, int);
  72. static void movetothem(int, int, char *, int);
  73. #endif    /* defined(LINT_ARGS) */
  74.  
  75. #define    access_api(foo,length,copyin)    (foo)
  76. #define    unaccess_api(foo,goo,length,copyout)
  77.  
  78. static void
  79. movetous(parms, es, di, length)
  80. char *parms;
  81. int es, di;
  82. int length;
  83. {
  84.     char far *farparms = parms;
  85.  
  86.     movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length);
  87.     if (apitrace) {
  88.     Dump('(', parms, length);
  89.     }
  90. }
  91.  
  92. static void
  93. movetothem(es, di, parms, length)
  94. int es, di;
  95. char *parms;
  96. int length;
  97. {
  98.     char far *farparms = parms;
  99.  
  100.     movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length);
  101.     if (apitrace) {
  102.     Dump(')', parms, length);
  103.     }
  104. }
  105. #endif    /* defined(MSDOS) */
  106.  
  107. #if    defined(unix)
  108. extern char *access_api();
  109. extern void movetous(), movetothem(), unaccess_api();
  110. #endif    /* defined(unix) */
  111.  
  112.  
  113. /*
  114.  * Supervisor Services.
  115.  */
  116.  
  117. static void
  118. name_resolution(regs, sregs)
  119. union REGS *regs;
  120. struct SREGS *sregs;
  121. {
  122.     NameResolveParms parms;
  123.  
  124.     movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
  125.  
  126.     regs->h.cl = 0;
  127.     if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
  128.     regs->x.dx = GATE_SESSMGR;
  129.     } else if (memcmp((char *)&parms, NAME_KEYBOARD,
  130.                     sizeof parms.gate_name) == 0) {
  131.     regs->x.dx = GATE_KEYBOARD;
  132.     } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
  133.     regs->x.dx = GATE_COPY;
  134.     } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
  135.     regs->x.dx = GATE_OIAM;
  136.     } else {
  137.     regs->h.cl = 0x2e;    /* Name not found */
  138.     }
  139.     regs->h.ch = 0x12;
  140.     regs->h.bh = 7;
  141. }
  142.  
  143. /*
  144.  * Session Information Services.
  145.  */
  146.  
  147. static void
  148. query_session_id(regs, sregs)
  149. union REGS *regs;
  150. struct SREGS *sregs;
  151. {
  152.     QuerySessionIdParms parms;
  153.  
  154.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  155.  
  156.     if ((parms.rc != 0) || (parms.function_id != 0)) {
  157.     parms.rc = 0x0c;
  158.     } else if (parms.option_code != 0x01) {
  159.     parms.rc = 0x0d;    /* Invalid option code */
  160. #ifdef    NOTOBS
  161.     } else if ((parms.data_code != 0x45) && (parms.data_code != 0x00/*OBS*/)) {
  162.     parms.rc = 0x0b;
  163. #endif    /* NOTOBS */
  164.     } else {
  165.     NameArray list;
  166.  
  167.     movetous((char *)&list, FP_SEG(parms.name_array),
  168.             FP_OFF(parms.name_array), sizeof list);
  169.     if ((list.length < 14) || (list.length > 170)) {
  170.         parms.rc = 0x12;
  171.     } else {
  172.         list.number_matching_session = 1;
  173.         list.name_array_element.short_name = parms.data_code;
  174.         list.name_array_element.type = TYPE_DFT;
  175.         list.name_array_element.session_id = PS_SESSION_ID;
  176.         memcpy(list.name_array_element.long_name, "ONLYSESS",
  177.                 sizeof list.name_array_element.long_name);
  178.         movetothem(FP_SEG(parms.name_array),
  179.         FP_OFF(parms.name_array), (char *)&list, sizeof list);
  180.         parms.rc = 0;
  181.     }
  182.     }
  183.     parms.function_id = 0x6b;
  184.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  185. }
  186.  
  187. static void
  188. query_session_parameters(regs, sregs)
  189. union REGS *regs;
  190. struct SREGS *sregs;
  191. {
  192.     QuerySessionParametersParms parms;
  193.  
  194.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  195.  
  196.     if ((parms.rc !=0) || (parms.function_id != 0)) {
  197.     parms.rc = 0x0c;
  198.     } else if (parms.session_id != PS_SESSION_ID) {
  199.     parms.rc = 0x02;
  200.     } else {
  201.     parms.rc = 0;
  202.     parms.session_type = TYPE_DFT;
  203.     parms.session_characteristics = 0;    /* Neither EAB nor PSS */
  204.     parms.rows = MaxNumberLines;
  205.     parms.columns = MaxNumberColumns;
  206.     parms.presentation_space = 0;
  207.     }
  208.     parms.function_id = 0x6b;
  209.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  210. }
  211.  
  212. static void
  213. query_session_cursor(regs, sregs)
  214. union REGS *regs;
  215. struct SREGS *sregs;
  216. {
  217.     QuerySessionCursorParms parms;
  218.  
  219.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  220.  
  221.     if ((parms.rc != 0) || (parms.function_id != 0)) {
  222.     parms.rc = 0x0c;
  223.     } else if (parms.session_id != PS_SESSION_ID) {
  224.     parms.rc = 0x02;
  225.     } else {
  226.     parms.rc = 0;
  227.     parms.cursor_type = CURSOR_BLINKING;    /* XXX what is inhibited? */
  228.     parms.row_address = ScreenLine(CursorAddress);
  229.     parms.column_address = ScreenLineOffset(CursorAddress);
  230.     }
  231.  
  232.     parms.function_id = 0x6b;
  233.     movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
  234. }
  235.  
  236. /*
  237.  * Keyboard Services.
  238.  */
  239.  
  240.  
  241. static void
  242. connect_to_keyboard(regs, sregs)
  243. union REGS *regs;
  244. struct SREGS *sregs;
  245. {
  246.     ConnectToKeyboardParms parms;
  247.  
  248.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  249.  
  250.     if ((parms.rc != 0) || (parms.function_id != 0)) {
  251.     parms.rc = 0x0c;
  252.     } else if (parms.session_id != PS_SESSION_ID) {
  253.     parms.rc = 0x02;
  254.     } else if (parms.intercept_options != 0) {
  255.     parms.rc = 0x01;
  256.     } else {
  257.     parms.rc = 0;
  258.     parms.first_connection_identifier = 0;
  259.     }
  260.     parms.function_id = 0x62;
  261.  
  262.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  263. }
  264.  
  265. static void
  266. disconnect_from_keyboard(regs, sregs)
  267. union REGS *regs;
  268. struct SREGS *sregs;
  269. {
  270.     DisconnectFromKeyboardParms parms;
  271.  
  272.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  273.  
  274.     if ((parms.rc != 0) || (parms.function_id != 0)) {
  275.     parms.rc = 0x0c;
  276.     } else if (parms.session_id != PS_SESSION_ID) {
  277.     parms.rc = 0x02;
  278.     } else if (parms.connectors_task_id != 0) {
  279.     parms.rc = 04;            /* XXX */
  280.     } else {
  281.     parms.rc = 0;
  282.     }
  283.     parms.function_id = 0x62;
  284.  
  285.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  286. }
  287.  
  288. static void
  289. write_keystroke(regs, sregs)
  290. union REGS *regs;
  291. struct SREGS *sregs;
  292. {
  293.     WriteKeystrokeParms parms;
  294.  
  295.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  296.  
  297.     if ((parms.rc != 0) || (parms.function_id != 0)) {
  298.     parms.rc = 0x0c;
  299.     } else if (parms.session_id != PS_SESSION_ID) {
  300.     parms.rc = 0x02;
  301.     } else if (parms.connectors_task_id != 0) {
  302.     parms.rc = 0x04;
  303.     } else {
  304.     parms.number_of_keys_sent = 0;
  305.     parms.rc = 0;
  306.     if (parms.options == OPTION_SINGLE_KEYSTROKE) {
  307.         KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
  308.         
  309.         if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
  310.         parms.rc = 0x10;        /* XXX needs 0x12 too! */
  311.         }
  312.         parms.number_of_keys_sent++;
  313.     } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
  314.         KeystrokeList
  315.         list,
  316.         far *atlist = parms.keystroke_specifier.keystroke_list;
  317.         KeystrokeEntry
  318.         entry[10],        /* 10 at a time */
  319.         *ourentry,
  320.         far *theirentry;
  321.         int
  322.         todo;
  323.  
  324.         movetous((char *)&list, FP_SEG(atlist),
  325.             FP_OFF(atlist), sizeof *atlist);
  326.         todo = list.length/2;
  327.         ourentry = entry+(highestof(entry)+1);
  328.         theirentry = &atlist->keystrokes;
  329.  
  330.         while (todo) {
  331.         if (ourentry > &entry[highestof(entry)]) {
  332.             int thistime;
  333.  
  334.             thistime = todo;
  335.             if (thistime > numberof(entry)) {
  336.             thistime = numberof(entry);
  337.             }
  338.             movetous((char *)entry, FP_SEG(theirentry),
  339.                 FP_OFF(theirentry), thistime*sizeof *theirentry);
  340.             theirentry += thistime;
  341.             ourentry = entry;
  342.         }
  343.         if (AcceptKeystroke(ourentry->scancode,
  344.                         ourentry->shift_state) == 0) {
  345.             parms.rc = 0x10;        /* XXX needs 0x12 too! */
  346.             break;
  347.         }
  348.         parms.number_of_keys_sent++;
  349.         ourentry++;
  350.         todo--;
  351.         }
  352.     } else {
  353.         parms.rc = 0x01;
  354.     }
  355.     }
  356.     parms.function_id = 0x62;
  357.  
  358.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  359. /* XXX */
  360. }
  361.  
  362.  
  363. static void
  364. disable_input(regs, sregs)
  365. union REGS *regs;
  366. struct SREGS *sregs;
  367. {
  368.     DisableInputParms parms;
  369.  
  370.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  371.  
  372.     if ((parms.rc != 0) || (parms.function_id != 0)) {
  373.     parms.rc = 0x0c;
  374.     } else if (parms.session_id != PS_SESSION_ID) {
  375.     parms.rc = 0x02;
  376.     } else if (parms.connectors_task_id != 0) {
  377.     parms.rc = 0x04;
  378.     } else {
  379.     SetOiaApiInhibit(&OperatorInformationArea);
  380.     parms.rc = 0;
  381.     }
  382.     parms.function_id = 0x62;
  383.  
  384.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  385. }
  386.  
  387. static void
  388. enable_input(regs, sregs)
  389. union REGS *regs;
  390. struct SREGS *sregs;
  391. {
  392.     EnableInputParms parms;
  393.  
  394.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  395.  
  396.     if ((parms.rc != 0) || (parms.function_id != 0)) {
  397.     parms.rc = 0x0c;
  398.     } else if (parms.session_id != PS_SESSION_ID) {
  399.     parms.rc = 0x02;
  400.     } else if (parms.connectors_task_id != 0) {
  401.     parms.rc = 0x04;
  402.     } else {
  403.     ResetOiaApiInhibit(&OperatorInformationArea);
  404.     parms.rc = 0;
  405.     }
  406.     parms.function_id = 0x62;
  407.  
  408.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  409. }
  410.  
  411. /*
  412.  * Copy Services.
  413.  */
  414.  
  415. static
  416. copy_subroutine(target, source, parms, what_is_user, length)
  417. BufferDescriptor *target, *source;
  418. CopyStringParms *parms;
  419. int what_is_user;
  420. #define    USER_IS_TARGET    0
  421. #define    USER_IS_SOURCE    1
  422. {
  423. #define    TARGET_NO_EAB        1
  424. #define    SOURCE_NO_EAB        2
  425. #define    TARGET_PC        4
  426. #define    SOURCE_PC        8
  427. #define    NO_FIELD_ATTRIBUTES    16
  428.     int needtodo = 0;
  429.     int access_length;
  430.     char far *input;
  431.     char far *output;
  432.     char far *access_pointer;
  433.  
  434.     if ((target->characteristics^source->characteristics)
  435.             &CHARACTERISTIC_EAB) {
  436.     if (target->characteristics&CHARACTERISTIC_EAB) {
  437.         needtodo |= TARGET_NO_EAB;    /* Need to bump for EAB in target */
  438.     } else {
  439.         needtodo |= SOURCE_NO_EAB;    /* Need to bump for EAB in source */
  440.     }
  441.     }
  442.     if (target->session_type != source->session_type) {
  443.     if (target->session_type == TYPE_PC) {
  444.         needtodo |= TARGET_PC;    /* scan codes to PC */
  445.     } else {
  446.         needtodo |= SOURCE_PC;    /* PC to scan codes */
  447.     }
  448.     }
  449.     if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) {
  450.     needtodo |= NO_FIELD_ATTRIBUTES;
  451.     }
  452.     access_length = length;
  453.     if (what_is_user == USER_IS_TARGET) {
  454.     if (target->characteristics&CHARACTERISTIC_EAB) {
  455.         access_length *= 2;
  456.     }
  457.     input = (char far *) &Host[source->begin];
  458.     access_pointer = target->buffer;
  459.     output = access_api(target->buffer, access_length, 0);
  460.     } else {
  461.     if (source->characteristics&CHARACTERISTIC_EAB) {
  462.         access_length *= 2;
  463.     }
  464.     access_pointer = source->buffer;
  465.     input = access_api(source->buffer, access_length, 1);
  466.     output = (char far *) &Host[target->begin];
  467.     }
  468.     while (length--) {
  469.     if (needtodo&TARGET_PC) {
  470.         *output++ = disp_asc[*input++];
  471.     } else if (needtodo&SOURCE_PC) {
  472.         *output++ = asc_disp[*input++];
  473.     } else {
  474.         *output++ = *input++;
  475.     }
  476.     if (needtodo&TARGET_NO_EAB) {
  477.         input++;
  478.     } else if (needtodo&SOURCE_NO_EAB) {
  479.         *output++ = 0;        /* Should figure out good EAB? */
  480.     }
  481.     }
  482.     if (what_is_user == USER_IS_TARGET) {
  483.     unaccess_api(target->buffer, access_pointer, access_length, 1);
  484.     } else {
  485.     unaccess_api(source->buffer, access_pointer, access_length, 0);
  486.     }
  487. }
  488.  
  489.  
  490. static void
  491. copy_string(regs, sregs)
  492. union REGS *regs;
  493. struct SREGS *sregs;
  494. {
  495.     CopyStringParms parms;
  496.     BufferDescriptor *target = &parms.target, *source = &parms.source;
  497.     int length;
  498.  
  499.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  500.  
  501.     length = 1+parms.source_end-source->begin;
  502.     if ((parms.rc != 0) || (parms.function_id !=0)) {
  503.     parms.rc = 0x0c;
  504.     } else if (target->session_id == BUF_SESSION_ID) {    /* Target is buffer */
  505.     if (source->session_id != PS_SESSION_ID) {        /* A no-no */
  506.         parms.rc = 0x2;
  507.     } else {
  508.         if ((source->begin < 0) || (source->begin > highestof(Host))) {
  509.         parms.rc = 0x06;        /* invalid source definition */
  510.         } else {
  511.         if ((source->begin+length) > highestof(Host)) {
  512.             length = highestof(Host)-source->begin;
  513.             parms.rc = 0x0f;    /* Truncate */
  514.         }
  515.             if ((source->characteristics == target->characteristics) &&
  516.             (source->session_type == target->session_type)) {
  517.             if (source->characteristics&CHARACTERISTIC_EAB) {
  518.             length *= 2;
  519.             }
  520.             movetothem(FP_SEG(target->buffer),
  521.                 FP_OFF(target->buffer),
  522.                 (char *)&Host[source->begin], length);
  523.         } else {
  524.             copy_subroutine(target, source, &parms,
  525.                             USER_IS_TARGET, length);
  526.         }
  527.         }
  528.     }
  529.     } else if (source->session_id != BUF_SESSION_ID) {
  530.         parms.rc = 0xd;
  531.     } else {
  532.     /* Send to presentation space (3270 buffer) */
  533.     if ((target->begin < 0) || (target->begin > highestof(Host))) {
  534.         parms.rc = 0x07;        /* invalid target definition */
  535.     } if (!UnLocked) {
  536.         parms.rc = 0x03;    /* Keyboard locked */
  537.     } else if (parms.copy_mode != 0) {
  538.         parms.rc = 0x0f;    /* Copy of field attr's not allowed */
  539.     } else if (IsProtected(target->begin) || /* Make sure no protected */
  540.             (WhereAttrByte(target->begin) !=    /* in range */
  541.                 WhereAttrByte(target->begin+length-1))) {
  542.         parms.rc = 0x0e;    /* Attempt to write in protected */
  543.     } else {
  544.         if ((target->begin+length) > highestof(Host)) {
  545.         length = highestof(Host)-target->begin;
  546.         parms.rc = 0x0f;    /* Truncate */
  547.         }
  548.         TurnOnMdt(target->begin);    /* Things have changed */
  549.         if ((source->characteristics == target->characteristics) &&
  550.             (source->session_type == target->session_type)) {
  551.         if (source->characteristics&CHARACTERISTIC_EAB) {
  552.             length *= 2;
  553.         }
  554.         movetous((char *)&Host[target->begin],
  555.                 FP_SEG(source->buffer),
  556.                 FP_OFF(source->buffer), length);
  557.         } else {
  558.         copy_subroutine(target, source, &parms, USER_IS_SOURCE, length);
  559.         }
  560.     }
  561.     }
  562.     parms.function_id = 0x64;
  563.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  564. }
  565.  
  566.  
  567. /*
  568.  * Operator Information Area Services.
  569.  */
  570.  
  571. static void
  572. read_oia_group(regs, sregs)
  573. union REGS *regs;
  574. struct SREGS *sregs;
  575. {
  576.     ReadOiaGroupParms parms;
  577.  
  578.     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
  579.  
  580.     if ((parms.rc != 0) || (parms.function_id != 0)) {
  581.     parms.rc = 0x0c;
  582.     } else if (parms.session_id != PS_SESSION_ID) {
  583.     parms.rc = 0x02;
  584.     } else {
  585.     int group = parms.oia_group_number;
  586.     char *from;
  587.     int size;
  588.  
  589.     if ((group != API_OIA_ALL_GROUPS) &&
  590.         ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
  591.     } else {
  592.         if (group == API_OIA_ALL_GROUPS) {
  593.         size = API_OIA_BYTES_ALL_GROUPS;
  594.         from = (char *)&OperatorInformationArea;
  595.         } else if (group == API_OIA_INPUT_INHIBITED) {
  596.         size = sizeof OperatorInformationArea.input_inhibited;
  597.         from = (char *)&OperatorInformationArea.input_inhibited[0];
  598.         } else {
  599.         size = 1;
  600.         from = ((char *)&OperatorInformationArea)+group;
  601.         }
  602.         movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
  603.             from, size);
  604.     }
  605.     }
  606.     parms.function_id = 0x6d;
  607.     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
  608. }
  609.  
  610. /*ARGSUSED*/
  611. static void
  612. unknown_op(regs, sregs)
  613. union REGS *regs;
  614. struct SREGS *sregs;
  615. {
  616.     regs->h.ch = 0x12;
  617.     regs->h.cl = 0x05;
  618. }
  619.  
  620.  
  621. handle_api(regs, sregs)
  622. union REGS *regs;
  623. struct SREGS *sregs;
  624. {
  625. /*
  626.  * Do we need to log this transaction?
  627.  */
  628.     if (apitrace) {
  629.     Dump('<', (char *)regs, sizeof *regs);
  630.     Dump('<', (char *)sregs, sizeof *sregs);
  631.     }
  632.     if (regs->h.ah == NAME_RESOLUTION) {
  633.     name_resolution(regs, sregs);
  634. #if    defined(unix)
  635.     } else if (regs->h.ah == PS_OR_OIA_MODIFIED) {
  636.     while ((oia_modified == 0) && (ps_modified == 0)) {
  637.         (void) Scheduler(1);
  638.     }
  639.     oia_modified = ps_modified = 0;
  640. #endif    /* defined(unix) */
  641.     } else if (regs->h.ah != 0x09) {
  642.     regs->h.ch = 0x12;
  643.     regs->h.cl = 0x0f;        /* XXX Invalid environmental access */
  644.     } else if (regs->x.bx != 0x8020) {
  645.     regs->h.ch = 0x12;
  646.     regs->h.cl = 0x08;        /* XXX Invalid wait specified */
  647.     } else if (regs->h.ch != 0) {
  648.     regs->x.cx = 0x1206;        /* XXX Invalid priority */
  649.     } else {
  650.     switch (regs->x.dx) {
  651.     case GATE_SESSMGR:
  652.         switch (regs->h.al) {
  653.         case QUERY_SESSION_ID:
  654.         if (regs->h.cl != 0) {
  655.             regs->x.cx = 0x1206;
  656.         } else {
  657.             regs->x.cx = 0x1200;
  658.             query_session_id(regs, sregs);
  659.         }
  660.         break;
  661.         case QUERY_SESSION_PARAMETERS:
  662.         if (regs->h.cl != 0) {
  663.             regs->x.cx = 0x1206;
  664.         } else {
  665.             regs->x.cx = 0x1200;
  666.             query_session_parameters(regs, sregs);
  667.         }
  668.         break;
  669.         case QUERY_SESSION_CURSOR:
  670.         if ((regs->h.cl != 0xff) && (regs->h.cl != 0x00/*OBS*/)) {
  671.             regs->x.cx = 0x1206;
  672.         } else {
  673.             regs->x.cx = 0x1200;
  674.             query_session_cursor(regs, sregs);
  675.         }
  676.         break;
  677.         default:
  678.         unknown_op(regs, sregs);
  679.         break;
  680.         }
  681.         break;
  682.     case GATE_KEYBOARD:
  683.         if (regs->h.cl != 00) {
  684.         regs->x.cx = 0x1206;
  685.         } else {
  686.         regs->x.cx = 0x1200;
  687.         switch (regs->h.al) {
  688.         case CONNECT_TO_KEYBOARD:
  689.             connect_to_keyboard(regs, sregs);
  690.             break;
  691.         case DISABLE_INPUT:
  692.             disable_input(regs, sregs);
  693.             break;
  694.         case WRITE_KEYSTROKE:
  695.             write_keystroke(regs, sregs);
  696.             break;
  697.         case ENABLE_INPUT:
  698.             enable_input(regs, sregs);
  699.             break;
  700.         case DISCONNECT_FROM_KEYBOARD:
  701.             disconnect_from_keyboard(regs, sregs);
  702.             break;
  703.         default:
  704.             unknown_op(regs, sregs);
  705.             break;
  706.         }
  707.         }
  708.         break;
  709.     case GATE_COPY:
  710.         if (regs->h.cl != 0xff) {
  711.         regs->x.cx = 0x1206;
  712.         } else {
  713.         regs->x.cx = 0x1200;
  714.         switch (regs->h.al) {
  715.         case COPY_STRING:
  716.             copy_string(regs, sregs);
  717.             break;
  718.         default:
  719.             unknown_op(regs, sregs);
  720.             break;
  721.         }
  722.         }
  723.         break;
  724.     case GATE_OIAM:
  725.         if (regs->h.cl != 0xff) {
  726.         regs->x.cx = 0x1206;
  727.         } else {
  728.         regs->x.cx = 0x1200;
  729.         switch (regs->h.al) {
  730.         case READ_OIA_GROUP:
  731.             read_oia_group(regs, sregs);
  732.             break;
  733.         default:
  734.             unknown_op(regs, sregs);
  735.             break;
  736.         }
  737.         }
  738.         break;
  739.     default:
  740.         regs->h.ch = 0x12;
  741.         regs->h.cl = 0x34;        /* Invalid GATE entry */
  742.         break;
  743.     }
  744.     }
  745. /*
  746.  * Do we need to log this transaction?
  747.  */
  748.     if (apitrace) {
  749.     Dump('>', (char *)regs, sizeof *regs);
  750.     Dump('>', (char *)sregs, sizeof *sregs);
  751. #ifdef    MSDOS
  752.     { char buf[10];  gets(buf); }
  753. #endif    /* MSDOS */
  754.     }
  755. }
  756.