* Copyright (c) 1984-1987 by the Regents of the
* University of California and by Gregory Glenn Minshall.
* Permission to use, copy, modify, and distribute these
* programs and their documentation for any purpose and
* without fee is hereby granted, provided that this
* copyright and permission appear on all copies and
* supporting documentation, the name of the Regents of
* the University of California not be used in advertising
* or publicity pertaining to distribution of the programs
* without specific prior permission, and notice be given in
* supporting documentation that copying and distribution is
* by permission of the Regents of the University of California
* and by Gregory Glenn Minshall. Neither the Regents of the
* University of California nor Gregory Glenn Minshall make
* representations about the suitability of this software
* for any purpose. It is provided "as is" without
* express or implied warranty.
static char sccsid
[] = "@(#)api.c 3.1 (Berkeley) %G%";
* This file implements the API used in the PC version.
#include "../general/general.h"
#include "../api/disp_asc.h"
#include "../general/globals.h"
* General utility routines.
static void movetous(char *, int, int, int);
static void movetothem(int, int, char *, int);
#endif /* defined(LINT_ARGS) */
#define access_api(foo,length,copyin) (foo)
#define unaccess_api(foo,goo,length,copyout)
movetous(parms
, es
, di
, length
)
char far
*farparms
= parms
;
movedata(es
, di
, (int) FP_SEG(farparms
), (int) FP_OFF(farparms
), length
);
movetothem(es
, di
, parms
, length
)
char far
*farparms
= parms
;
movedata((int) FP_SEG(farparms
), (int) FP_OFF(farparms
), es
, di
, length
);
#endif /* defined(MSDOS) */
extern char *access_api(), *unaccess_api();
#endif /* defined(unix) */
name_resolution(regs
, sregs
)
movetous((char *) &parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
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) {
} else if (memcmp((char *)&parms
, NAME_OIAM
, sizeof parms
.gate_name
) == 0) {
regs
->h
.cl
= 0x2e; /* Name not found */
* Session Information Services.
query_session_id(regs
, sregs
)
QuerySessionIdParms parms
;
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!= 0) || (parms
.function_id
!= 0)) {
} else if (parms
.option_code
!= 0x01) {
parms
.rc
= 0x0d; /* Invalid option code */
} else if (parms
.data_code
!= 0x45) {
NameArrayElement element
;
movetous((char *)&list
, FP_SEG(parms
.name_array
),
FP_OFF(parms
.name_array
), sizeof list
);
if ((list
.length
< 14) || (list
.length
> 170)) {
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
= 23;
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
.function_id
= 0x6b;
movetothem(sregs
->es
, regs
->x
.di
, (char *)&parms
, sizeof parms
);
query_session_parameters(regs
, sregs
)
QuerySessionParametersParms parms
;
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!=0) || (parms
.function_id
!= 0)) {
} else if (parms
.session_id
!= 23) {
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
);
query_session_cursor(regs
, sregs
)
QuerySessionCursorParms parms
;
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!= 0) || (parms
.function_id
!= 0)) {
} else if (parms
.session_id
!= 23) {
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
);
connect_to_keyboard(regs
, sregs
)
ConnectToKeyboardParms parms
;
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!= 0) || (parms
.function_id
!= 0)) {
} else if (parms
.session_id
!= 23) {
} else if (parms
.intercept_options
!= 0) {
parms
.first_connection_identifier
= 0;
parms
.function_id
= 0x62;
movetothem(sregs
->es
, regs
->x
.di
, (char *)&parms
, sizeof parms
);
disconnect_from_keyboard(regs
, sregs
)
DisconnectFromKeyboardParms parms
;
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!= 0) || (parms
.function_id
!= 0)) {
} else if (parms
.session_id
!= 23) {
} else if (parms
.connectors_task_id
!= 0) {
parms
.function_id
= 0x62;
movetothem(sregs
->es
, regs
->x
.di
, (char *)&parms
, sizeof parms
);
write_keystroke(regs
, sregs
)
WriteKeystrokeParms parms
;
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!= 0) || (parms
.function_id
!= 0)) {
} else if (parms
.session_id
!= 23) {
} else if (parms
.connectors_task_id
!= 0) {
parms
.number_of_keys_sent
= 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
) {
far
*atlist
= parms
.keystroke_specifier
.keystroke_list
;
entry
[10], /* 10 at a time */
movetous((char *)&list
, FP_SEG(atlist
),
FP_OFF(atlist
), sizeof *atlist
);
ourentry
= entry
+(highestof(entry
)+1);
if (ourentry
> &entry
[highestof(entry
)]) {
if (thistime
> numberof(entry
)) {
thistime
= numberof(entry
);
movetous((char *)entry
, FP_SEG(theirentry
),
FP_OFF(theirentry
), thistime
*sizeof *theirentry
);
if (AcceptKeystroke(ourentry
->scancode
,
ourentry
->shift_state
) == 0) {
parms
.rc
= 0x10; /* XXX needs 0x12 too! */
parms
.number_of_keys_sent
++;
parms
.function_id
= 0x62;
movetothem(sregs
->es
, regs
->x
.di
, (char *)&parms
, sizeof parms
);
disable_input(regs
, sregs
)
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!= 0) || (parms
.function_id
!= 0)) {
} else if (parms
.session_id
!= 23) {
} else if (parms
.connectors_task_id
!= 0) {
SetOiaApiInhibit(&OperatorInformationArea
);
parms
.function_id
= 0x62;
movetothem(sregs
->es
, regs
->x
.di
, (char *)&parms
, sizeof parms
);
enable_input(regs
, sregs
)
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!= 0) || (parms
.function_id
!= 0)) {
} else if (parms
.session_id
!= 23) {
} else if (parms
.connectors_task_id
!= 0) {
ResetOiaApiInhibit(&OperatorInformationArea
);
parms
.function_id
= 0x62;
movetothem(sregs
->es
, regs
->x
.di
, (char *)&parms
, sizeof parms
);
copy_subroutine(target
, source
, parms
, what_is_user
, length
)
BufferDescriptor
*target
, *source
;
#define NO_FIELD_ATTRIBUTES 16
char far
*access_pointer
;
if ((target
->characteristics
^source
->characteristics
)
if (target
->characteristics
&CHARACTERISTIC_EAB
) {
needtodo
|= TARGET_NO_EAB
; /* Need to bump for EAB in target */
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 */
needtodo
|= SOURCE_PC
; /* PC to scan codes */
if ((parms
->copy_mode
©_MODE_FIELD_ATTRIBUTES
) == 0) {
needtodo
|= NO_FIELD_ATTRIBUTES
;
if (what_is_user
== USER_IS_TARGET
) {
if (target
->characteristics
&CHARACTERISTIC_EAB
) {
input
= (char far
*) &Host
[source
->begin
];
access_pointer
= target
->buffer
;
output
= access_api(target
->buffer
, access_length
, 0);
if (source
->characteristics
&CHARACTERISTIC_EAB
) {
access_pointer
= source
->buffer
;
input
= access_api(source
->buffer
, access_length
, 1);
output
= (char far
*) &Host
[target
->begin
];
if (needtodo
&TARGET_PC
) {
*output
++ = disp_asc
[*input
++];
} else if (needtodo
&SOURCE_PC
) {
*output
++ = asc_disp
[*input
++];
if (needtodo
&TARGET_NO_EAB
) {
} 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);
unaccess_api(source
->buffer
, access_pointer
, access_length
, 0);
BufferDescriptor
*target
= &parms
.target
, *source
= &parms
.source
;
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)) {
} else if (target
->session_id
== 0) { /* Target is buffer */
if (source
->session_id
!= 23) { /* A no-no */
if ((source
->begin
< 0) || (source
->begin
> highestof(Host
))) {
parms
.rc
= 0x06; /* invalid source definition */
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
) {
movetothem( (int) FP_SEG(target
->buffer
),
(int) FP_OFF(target
->buffer
),
(char *)&Host
[source
->begin
], length
);
copy_subroutine(target
, source
, &parms
,
} else if (source
->session_id
!= 0) {
if ((target
->begin
< 0) || (source
->begin
> highestof(Host
))) {
parms
.rc
= 0x07; /* invalid source definition */
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
) {
movetous((char *)&Host
[target
->begin
],
(int) FP_SEG(source
->buffer
),
(int) FP_OFF(source
->buffer
), length
);
copy_subroutine(target
, source
, &parms
, USER_IS_SOURCE
, length
);
movetothem(sregs
->es
, regs
->x
.di
, (char *)&parms
, sizeof parms
);
* Operator Information Area Services.
read_oia_group(regs
, sregs
)
movetous((char *)&parms
, sregs
->es
, regs
->x
.di
, sizeof parms
);
if ((parms
.rc
!= 0) || (parms
.function_id
!= 0)) {
} else if (parms
.session_id
!= 23) {
int group
= parms
.oia_group_number
;
if ((group
!= API_OIA_ALL_GROUPS
) &&
((group
> API_OIA_LAST_LEGAL_GROUP
) || (group
< 0))) {
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];
from
= ((char *)&OperatorInformationArea
)+group
;
movetothem(FP_SEG(parms
.oia_buffer
), FP_OFF(parms
.oia_buffer
),
parms
.function_id
= 0x6d;
movetothem(sregs
->es
, regs
->x
.di
, (char *)&parms
, sizeof parms
);
if (regs
->h
.ah
== NAME_RESOLUTION
) {
name_resolution(regs
, sregs
);
} else if (regs
->h
.ah
== PS_OR_OIA_MODIFIED
) {
while ((oia_modified
== 0) && (ps_modified
== 0)) {
oia_modified
= ps_modified
= 0;
#endif /* defined(unix) */
} else if (regs
->h
.ah
!= 0x09) {
regs
->h
.cl
= 0x0f; /* XXX Invalid environmental access */
} else if (regs
->x
.bx
!= 0x8020) {
regs
->h
.cl
= 0x08; /* XXX Invalid wait specified */
} else if (regs
->h
.ch
!= 0) {
regs
->x
.cx
= 0x1206; /* XXX Invalid priority */
query_session_id(regs
, sregs
);
case QUERY_SESSION_PARAMETERS
:
query_session_parameters(regs
, sregs
);
case QUERY_SESSION_CURSOR
:
if (regs
->h
.cl
!= 0xff) {
query_session_cursor(regs
, sregs
);
case CONNECT_TO_KEYBOARD
:
connect_to_keyboard(regs
, sregs
);
disable_input(regs
, sregs
);
write_keystroke(regs
, sregs
);
enable_input(regs
, sregs
);
case DISCONNECT_FROM_KEYBOARD
:
disconnect_from_keyboard(regs
, sregs
);
if (regs
->h
.cl
!= 0xff) {
copy_string(regs
, sregs
);
if (regs
->h
.cl
!= 0xff) {
read_oia_group(regs
, sregs
);
regs
->h
.cl
= 0x34; /* Invalid GATE entry */