782 lines
20 KiB
C
782 lines
20 KiB
C
/* $NetBSD: api.c,v 1.5 1998/07/09 18:33:32 msaitoh Exp $ */
|
||
|
||
/*-
|
||
* Copyright (c) 1988 The Regents of the University of California.
|
||
* All rights reserved.
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without
|
||
* modification, are permitted provided that the following conditions
|
||
* are met:
|
||
* 1. Redistributions of source code must retain the above copyright
|
||
* notice, this list of conditions and the following disclaimer.
|
||
* 2. Redistributions in binary form must reproduce the above copyright
|
||
* notice, this list of conditions and the following disclaimer in the
|
||
* documentation and/or other materials provided with the distribution.
|
||
* 3. All advertising materials mentioning features or use of this software
|
||
* must display the following acknowledgement:
|
||
* This product includes software developed by the University of
|
||
* California, Berkeley and its contributors.
|
||
* 4. Neither the name of the University nor the names of its contributors
|
||
* may be used to endorse or promote products derived from this software
|
||
* without specific prior written permission.
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
* SUCH DAMAGE.
|
||
*/
|
||
|
||
#include <sys/cdefs.h>
|
||
#ifndef lint
|
||
#if 0
|
||
static char sccsid[] = "@(#)api.c 4.5 (Berkeley) 4/26/91";
|
||
#else
|
||
__RCSID("$NetBSD: api.c,v 1.5 1998/07/09 18:33:32 msaitoh Exp $");
|
||
#endif
|
||
#endif /* not lint */
|
||
|
||
/*
|
||
* This file implements the API used in the PC version.
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
|
||
#include "api.h"
|
||
#include "../general/general.h"
|
||
|
||
#include "../api/disp_asc.h"
|
||
|
||
#include "screen.h"
|
||
#include "hostctlr.h"
|
||
#include "oia.h"
|
||
#include "declare.h"
|
||
|
||
#include "externs.h"
|
||
|
||
#include "../general/globals.h"
|
||
|
||
int apitrace = 0;
|
||
|
||
/*
|
||
* Some defines for things we use internally.
|
||
*/
|
||
|
||
#define PS_SESSION_ID 23
|
||
#define BUF_SESSION_ID 0
|
||
|
||
|
||
/* api.c */
|
||
#if defined(MSDOS)
|
||
static void movetous __P((char *, int, int , int));
|
||
static void movetothem __P((int, int , char *, int));
|
||
#else
|
||
#include "../sys_curses/telextrn.h"
|
||
#endif
|
||
static void name_resolution __P((union REGS *, struct SREGS *));
|
||
static void query_session_id __P((union REGS *, struct SREGS *));
|
||
static void query_session_parameters __P((union REGS *, struct SREGS *));
|
||
static void query_session_cursor __P((union REGS *, struct SREGS *));
|
||
static void connect_to_keyboard __P((union REGS *, struct SREGS *));
|
||
static void disconnect_from_keyboard __P((union REGS *, struct SREGS *));
|
||
static void write_keystroke __P((union REGS *, struct SREGS *));
|
||
static void disable_input __P((union REGS *, struct SREGS *));
|
||
static void enable_input __P((union REGS *, struct SREGS *));
|
||
static void copy_subroutine __P((BufferDescriptor *, BufferDescriptor *,
|
||
CopyStringParms *, int, int ));
|
||
static void copy_string __P((union REGS *, struct SREGS *));
|
||
static void read_oia_group __P((union REGS *, struct SREGS *));
|
||
static void unknown_op __P((union REGS *, struct SREGS *));
|
||
|
||
/*
|
||
* General utility routines.
|
||
*/
|
||
|
||
#if defined(MSDOS)
|
||
|
||
#define access_api(foo,length,copyin) (foo)
|
||
#define unaccess_api(foo,goo,length,copyout)
|
||
|
||
static void
|
||
movetous(parms, es, di, length)
|
||
char *parms;
|
||
int es, di;
|
||
int length;
|
||
{
|
||
char far *farparms = parms;
|
||
|
||
movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length);
|
||
if (apitrace) {
|
||
Dump('(', parms, length);
|
||
}
|
||
}
|
||
|
||
static void
|
||
movetothem(es, di, parms, length)
|
||
int es, di;
|
||
char *parms;
|
||
int length;
|
||
{
|
||
char far *farparms = parms;
|
||
|
||
movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length);
|
||
if (apitrace) {
|
||
Dump(')', parms, length);
|
||
}
|
||
}
|
||
#endif /* defined(MSDOS) */
|
||
|
||
/*
|
||
* Supervisor Services.
|
||
*/
|
||
|
||
static void
|
||
name_resolution(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
NameResolveParms parms;
|
||
|
||
movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
regs->h.cl = 0;
|
||
if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
|
||
regs->x.dx = GATE_SESSMGR;
|
||
} else if (memcmp((char *)&parms, NAME_KEYBOARD,
|
||
sizeof parms.gate_name) == 0) {
|
||
regs->x.dx = GATE_KEYBOARD;
|
||
} else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
|
||
regs->x.dx = GATE_COPY;
|
||
} else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
|
||
regs->x.dx = GATE_OIAM;
|
||
} else {
|
||
regs->h.cl = 0x2e; /* Name not found */
|
||
}
|
||
regs->h.ch = 0x12;
|
||
regs->h.bh = 7;
|
||
}
|
||
|
||
/*
|
||
* Session Information Services.
|
||
*/
|
||
|
||
static void
|
||
query_session_id(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
QuerySessionIdParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc != 0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.option_code != 0x01) {
|
||
parms.rc = 0x0d; /* Invalid option code */
|
||
#ifdef NOTOBS
|
||
} else if ((parms.data_code != 0x45) && (parms.data_code != 0x00/*OBS*/)) {
|
||
parms.rc = 0x0b;
|
||
#endif /* NOTOBS */
|
||
} else {
|
||
NameArray list;
|
||
|
||
movetous((char *)&list, FP_SEG(parms.name_array),
|
||
FP_OFF(parms.name_array), sizeof list);
|
||
if ((list.length < 14) || (list.length > 170)) {
|
||
parms.rc = 0x12;
|
||
} else {
|
||
list.number_matching_session = 1;
|
||
list.name_array_element.short_name = parms.data_code;
|
||
list.name_array_element.type = TYPE_DFT;
|
||
list.name_array_element.session_id = PS_SESSION_ID;
|
||
memcpy(list.name_array_element.long_name, "ONLYSESS",
|
||
sizeof list.name_array_element.long_name);
|
||
movetothem(FP_SEG(parms.name_array),
|
||
FP_OFF(parms.name_array), (char *)&list, sizeof list);
|
||
parms.rc = 0;
|
||
}
|
||
}
|
||
parms.function_id = 0x6b;
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
}
|
||
|
||
static void
|
||
query_session_parameters(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
QuerySessionParametersParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc !=0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.session_id != PS_SESSION_ID) {
|
||
parms.rc = 0x02;
|
||
} else {
|
||
parms.rc = 0;
|
||
parms.session_type = TYPE_DFT;
|
||
parms.session_characteristics = 0; /* Neither EAB nor PSS */
|
||
parms.rows = MaxNumberLines;
|
||
parms.columns = MaxNumberColumns;
|
||
parms.presentation_space = 0;
|
||
}
|
||
parms.function_id = 0x6b;
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
}
|
||
|
||
static void
|
||
query_session_cursor(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
QuerySessionCursorParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc != 0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.session_id != PS_SESSION_ID) {
|
||
parms.rc = 0x02;
|
||
} else {
|
||
parms.rc = 0;
|
||
parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */
|
||
parms.row_address = ScreenLine(CursorAddress);
|
||
parms.column_address = ScreenLineOffset(CursorAddress);
|
||
}
|
||
|
||
parms.function_id = 0x6b;
|
||
movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
|
||
}
|
||
|
||
/*
|
||
* Keyboard Services.
|
||
*/
|
||
|
||
|
||
static void
|
||
connect_to_keyboard(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
ConnectToKeyboardParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc != 0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.session_id != PS_SESSION_ID) {
|
||
parms.rc = 0x02;
|
||
} else if (parms.intercept_options != 0) {
|
||
parms.rc = 0x01;
|
||
} else {
|
||
parms.rc = 0;
|
||
parms.first_connection_identifier = 0;
|
||
}
|
||
parms.function_id = 0x62;
|
||
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
}
|
||
|
||
static void
|
||
disconnect_from_keyboard(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
DisconnectFromKeyboardParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc != 0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.session_id != PS_SESSION_ID) {
|
||
parms.rc = 0x02;
|
||
} else if (parms.connectors_task_id != 0) {
|
||
parms.rc = 04; /* XXX */
|
||
} else {
|
||
parms.rc = 0;
|
||
}
|
||
parms.function_id = 0x62;
|
||
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
}
|
||
|
||
static void
|
||
write_keystroke(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
WriteKeystrokeParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc != 0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.session_id != PS_SESSION_ID) {
|
||
parms.rc = 0x02;
|
||
} else if (parms.connectors_task_id != 0) {
|
||
parms.rc = 0x04;
|
||
} else {
|
||
parms.number_of_keys_sent = 0;
|
||
parms.rc = 0;
|
||
if (parms.options == OPTION_SINGLE_KEYSTROKE) {
|
||
KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
|
||
|
||
if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
|
||
parms.rc = 0x10; /* XXX needs 0x12 too! */
|
||
}
|
||
parms.number_of_keys_sent++;
|
||
} else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
|
||
KeystrokeList
|
||
list,
|
||
far *atlist = parms.keystroke_specifier.keystroke_list;
|
||
KeystrokeEntry
|
||
entry[10], /* 10 at a time */
|
||
*ourentry,
|
||
far *theirentry;
|
||
int
|
||
todo;
|
||
|
||
movetous((char *)&list, FP_SEG(atlist),
|
||
FP_OFF(atlist), sizeof *atlist);
|
||
todo = list.length/2;
|
||
ourentry = entry+(highestof(entry)+1);
|
||
theirentry = &atlist->keystrokes;
|
||
|
||
while (todo) {
|
||
if (ourentry > &entry[highestof(entry)]) {
|
||
int thistime;
|
||
|
||
thistime = todo;
|
||
if (thistime > numberof(entry)) {
|
||
thistime = numberof(entry);
|
||
}
|
||
movetous((char *)entry, FP_SEG(theirentry),
|
||
FP_OFF(theirentry), thistime*sizeof *theirentry);
|
||
theirentry += thistime;
|
||
ourentry = entry;
|
||
}
|
||
if (AcceptKeystroke(ourentry->scancode,
|
||
ourentry->shift_state) == 0) {
|
||
parms.rc = 0x10; /* XXX needs 0x12 too! */
|
||
break;
|
||
}
|
||
parms.number_of_keys_sent++;
|
||
ourentry++;
|
||
todo--;
|
||
}
|
||
} else {
|
||
parms.rc = 0x01;
|
||
}
|
||
}
|
||
parms.function_id = 0x62;
|
||
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
/* XXX */
|
||
}
|
||
|
||
|
||
static void
|
||
disable_input(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
DisableInputParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc != 0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.session_id != PS_SESSION_ID) {
|
||
parms.rc = 0x02;
|
||
} else if (parms.connectors_task_id != 0) {
|
||
parms.rc = 0x04;
|
||
} else {
|
||
SetOiaApiInhibit(&OperatorInformationArea);
|
||
parms.rc = 0;
|
||
}
|
||
parms.function_id = 0x62;
|
||
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
}
|
||
|
||
static void
|
||
enable_input(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
EnableInputParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc != 0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.session_id != PS_SESSION_ID) {
|
||
parms.rc = 0x02;
|
||
} else if (parms.connectors_task_id != 0) {
|
||
parms.rc = 0x04;
|
||
} else {
|
||
ResetOiaApiInhibit(&OperatorInformationArea);
|
||
parms.rc = 0;
|
||
}
|
||
parms.function_id = 0x62;
|
||
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
}
|
||
|
||
/*
|
||
* Copy Services.
|
||
*/
|
||
|
||
static void
|
||
copy_subroutine(target, source, parms, what_is_user, length)
|
||
BufferDescriptor *target, *source;
|
||
CopyStringParms *parms;
|
||
int what_is_user;
|
||
int length;
|
||
#define USER_IS_TARGET 0
|
||
#define USER_IS_SOURCE 1
|
||
{
|
||
#define TARGET_NO_EAB 1
|
||
#define SOURCE_NO_EAB 2
|
||
#define TARGET_PC 4
|
||
#define SOURCE_PC 8
|
||
#define NO_FIELD_ATTRIBUTES 16
|
||
int needtodo = 0;
|
||
int access_length;
|
||
unsigned char far *input;
|
||
char far *output;
|
||
char far *access_pointer;
|
||
|
||
if ((target->characteristics^source->characteristics)
|
||
&CHARACTERISTIC_EAB) {
|
||
if (target->characteristics&CHARACTERISTIC_EAB) {
|
||
needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */
|
||
} else {
|
||
needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */
|
||
}
|
||
}
|
||
if (target->session_type != source->session_type) {
|
||
if (target->session_type == TYPE_PC) {
|
||
needtodo |= TARGET_PC; /* scan codes to PC */
|
||
} else {
|
||
needtodo |= SOURCE_PC; /* PC to scan codes */
|
||
}
|
||
}
|
||
if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) {
|
||
needtodo |= NO_FIELD_ATTRIBUTES;
|
||
}
|
||
access_length = length;
|
||
if (what_is_user == USER_IS_TARGET) {
|
||
if (target->characteristics&CHARACTERISTIC_EAB) {
|
||
access_length *= 2;
|
||
}
|
||
input = (unsigned char far *) &Host[source->begin];
|
||
access_pointer = target->buffer;
|
||
output = access_api(target->buffer, access_length, 0);
|
||
} else {
|
||
if (source->characteristics&CHARACTERISTIC_EAB) {
|
||
access_length *= 2;
|
||
}
|
||
access_pointer = source->buffer;
|
||
input = (unsigned char far *)
|
||
access_api(source->buffer, access_length, 1);
|
||
output = (char far *) &Host[target->begin];
|
||
}
|
||
while (length--) {
|
||
if (needtodo&TARGET_PC) {
|
||
*output++ = disp_asc[*input++];
|
||
} else if (needtodo&SOURCE_PC) {
|
||
*output++ = asc_disp[*input++];
|
||
} else {
|
||
*output++ = *input++;
|
||
}
|
||
if (needtodo&TARGET_NO_EAB) {
|
||
/* XXX: So why are we doing this? (bug) */
|
||
input++;
|
||
} else if (needtodo&SOURCE_NO_EAB) {
|
||
*output++ = 0; /* Should figure out good EAB? */
|
||
}
|
||
}
|
||
if (what_is_user == USER_IS_TARGET) {
|
||
unaccess_api(target->buffer, access_pointer, access_length, 1);
|
||
} else {
|
||
unaccess_api(source->buffer, access_pointer, access_length, 0);
|
||
}
|
||
}
|
||
|
||
|
||
static void
|
||
copy_string(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
CopyStringParms parms;
|
||
BufferDescriptor *target = &parms.target, *source = &parms.source;
|
||
int length;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
length = 1+parms.source_end-source->begin;
|
||
if ((parms.rc != 0) || (parms.function_id !=0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (target->session_id == BUF_SESSION_ID) { /* Target is buffer */
|
||
if (source->session_id != PS_SESSION_ID) { /* A no-no */
|
||
parms.rc = 0x2;
|
||
} else {
|
||
if ((source->begin < 0) || (source->begin > highestof(Host))) {
|
||
parms.rc = 0x06; /* invalid source definition */
|
||
} else {
|
||
if ((source->begin+length) > highestof(Host)) {
|
||
length = highestof(Host)-source->begin;
|
||
parms.rc = 0x0f; /* Truncate */
|
||
}
|
||
if ((source->characteristics == target->characteristics) &&
|
||
(source->session_type == target->session_type)) {
|
||
if (source->characteristics&CHARACTERISTIC_EAB) {
|
||
length *= 2;
|
||
}
|
||
movetothem(FP_SEG(target->buffer),
|
||
FP_OFF(target->buffer),
|
||
(char *)&Host[source->begin], length);
|
||
} else {
|
||
copy_subroutine(target, source, &parms,
|
||
USER_IS_TARGET, length);
|
||
}
|
||
}
|
||
}
|
||
} else if (source->session_id != BUF_SESSION_ID) {
|
||
parms.rc = 0xd;
|
||
} else {
|
||
/* Send to presentation space (3270 buffer) */
|
||
if ((target->begin < 0) || (target->begin > highestof(Host))) {
|
||
parms.rc = 0x07; /* invalid target definition */
|
||
} if (!UnLocked) {
|
||
parms.rc = 0x03; /* Keyboard locked */
|
||
} else if (parms.copy_mode != 0) {
|
||
parms.rc = 0x0f; /* Copy of field attr's not allowed */
|
||
} else if (IsProtected(target->begin) || /* Make sure no protected */
|
||
(WhereAttrByte(target->begin) != /* in range */
|
||
WhereAttrByte(target->begin+length-1))) {
|
||
parms.rc = 0x0e; /* Attempt to write in protected */
|
||
} else {
|
||
if ((target->begin+length) > highestof(Host)) {
|
||
length = highestof(Host)-target->begin;
|
||
parms.rc = 0x0f; /* Truncate */
|
||
}
|
||
TurnOnMdt(target->begin); /* Things have changed */
|
||
if ((source->characteristics == target->characteristics) &&
|
||
(source->session_type == target->session_type)) {
|
||
if (source->characteristics&CHARACTERISTIC_EAB) {
|
||
length *= 2;
|
||
}
|
||
movetous((char *)&Host[target->begin],
|
||
FP_SEG(source->buffer),
|
||
FP_OFF(source->buffer), length);
|
||
} else {
|
||
copy_subroutine(target, source, &parms, USER_IS_SOURCE, length);
|
||
}
|
||
}
|
||
}
|
||
parms.function_id = 0x64;
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
}
|
||
|
||
|
||
/*
|
||
* Operator Information Area Services.
|
||
*/
|
||
|
||
static void
|
||
read_oia_group(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
ReadOiaGroupParms parms;
|
||
|
||
movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
|
||
|
||
if ((parms.rc != 0) || (parms.function_id != 0)) {
|
||
parms.rc = 0x0c;
|
||
} else if (parms.session_id != PS_SESSION_ID) {
|
||
parms.rc = 0x02;
|
||
} else {
|
||
int group = parms.oia_group_number;
|
||
char *from;
|
||
int size;
|
||
|
||
if ((group != API_OIA_ALL_GROUPS) &&
|
||
((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
|
||
} else {
|
||
if (group == API_OIA_ALL_GROUPS) {
|
||
size = API_OIA_BYTES_ALL_GROUPS;
|
||
from = (char *)&OperatorInformationArea;
|
||
} else if (group == API_OIA_INPUT_INHIBITED) {
|
||
size = sizeof OperatorInformationArea.input_inhibited;
|
||
from = (char *)&OperatorInformationArea.input_inhibited[0];
|
||
} else {
|
||
size = 1;
|
||
from = ((char *)&OperatorInformationArea)+group;
|
||
}
|
||
movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
|
||
from, size);
|
||
}
|
||
}
|
||
parms.function_id = 0x6d;
|
||
movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
|
||
}
|
||
|
||
/*ARGSUSED*/
|
||
static void
|
||
unknown_op(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
regs->h.ch = 0x12;
|
||
regs->h.cl = 0x05;
|
||
}
|
||
|
||
|
||
void
|
||
handle_api(regs, sregs)
|
||
union REGS *regs;
|
||
struct SREGS *sregs;
|
||
{
|
||
/*
|
||
* Do we need to log this transaction?
|
||
*/
|
||
if (apitrace) {
|
||
Dump('<', (char *)regs, sizeof *regs);
|
||
Dump('<', (char *)sregs, sizeof *sregs);
|
||
}
|
||
if (regs->h.ah == NAME_RESOLUTION) {
|
||
name_resolution(regs, sregs);
|
||
#if defined(unix)
|
||
} else if (regs->h.ah == PS_OR_OIA_MODIFIED) {
|
||
while ((oia_modified == 0) && (ps_modified == 0)) {
|
||
(void) Scheduler(1);
|
||
}
|
||
oia_modified = ps_modified = 0;
|
||
#endif /* defined(unix) */
|
||
} else if (regs->h.ah != 0x09) {
|
||
regs->h.ch = 0x12;
|
||
regs->h.cl = 0x0f; /* XXX Invalid environmental access */
|
||
} else if (regs->x.bx != 0x8020) {
|
||
regs->h.ch = 0x12;
|
||
regs->h.cl = 0x08; /* XXX Invalid wait specified */
|
||
} else if (regs->h.ch != 0) {
|
||
regs->x.cx = 0x1206; /* XXX Invalid priority */
|
||
} else {
|
||
switch (regs->x.dx) {
|
||
case GATE_SESSMGR:
|
||
switch (regs->h.al) {
|
||
case QUERY_SESSION_ID:
|
||
if (regs->h.cl != 0) {
|
||
regs->x.cx = 0x1206;
|
||
} else {
|
||
regs->x.cx = 0x1200;
|
||
query_session_id(regs, sregs);
|
||
}
|
||
break;
|
||
case QUERY_SESSION_PARAMETERS:
|
||
if (regs->h.cl != 0) {
|
||
regs->x.cx = 0x1206;
|
||
} else {
|
||
regs->x.cx = 0x1200;
|
||
query_session_parameters(regs, sregs);
|
||
}
|
||
break;
|
||
case QUERY_SESSION_CURSOR:
|
||
if ((regs->h.cl != 0xff) && (regs->h.cl != 0x00/*OBS*/)) {
|
||
regs->x.cx = 0x1206;
|
||
} else {
|
||
regs->x.cx = 0x1200;
|
||
query_session_cursor(regs, sregs);
|
||
}
|
||
break;
|
||
default:
|
||
unknown_op(regs, sregs);
|
||
break;
|
||
}
|
||
break;
|
||
case GATE_KEYBOARD:
|
||
if (regs->h.cl != 00) {
|
||
regs->x.cx = 0x1206;
|
||
} else {
|
||
regs->x.cx = 0x1200;
|
||
switch (regs->h.al) {
|
||
case CONNECT_TO_KEYBOARD:
|
||
connect_to_keyboard(regs, sregs);
|
||
break;
|
||
case DISABLE_INPUT:
|
||
disable_input(regs, sregs);
|
||
break;
|
||
case WRITE_KEYSTROKE:
|
||
write_keystroke(regs, sregs);
|
||
break;
|
||
case ENABLE_INPUT:
|
||
enable_input(regs, sregs);
|
||
break;
|
||
case DISCONNECT_FROM_KEYBOARD:
|
||
disconnect_from_keyboard(regs, sregs);
|
||
break;
|
||
default:
|
||
unknown_op(regs, sregs);
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case GATE_COPY:
|
||
if (regs->h.cl != 0xff) {
|
||
regs->x.cx = 0x1206;
|
||
} else {
|
||
regs->x.cx = 0x1200;
|
||
switch (regs->h.al) {
|
||
case COPY_STRING:
|
||
copy_string(regs, sregs);
|
||
break;
|
||
default:
|
||
unknown_op(regs, sregs);
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
case GATE_OIAM:
|
||
if (regs->h.cl != 0xff) {
|
||
regs->x.cx = 0x1206;
|
||
} else {
|
||
regs->x.cx = 0x1200;
|
||
switch (regs->h.al) {
|
||
case READ_OIA_GROUP:
|
||
read_oia_group(regs, sregs);
|
||
break;
|
||
default:
|
||
unknown_op(regs, sregs);
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
regs->h.ch = 0x12;
|
||
regs->h.cl = 0x34; /* Invalid GATE entry */
|
||
break;
|
||
}
|
||
}
|
||
/*
|
||
* Do we need to log this transaction?
|
||
*/
|
||
if (apitrace) {
|
||
Dump('>', (char *)regs, sizeof *regs);
|
||
Dump('>', (char *)sregs, sizeof *sregs);
|
||
#ifdef MSDOS
|
||
{ char buf[10]; gets(buf); }
|
||
#endif /* MSDOS */
|
||
}
|
||
}
|