131158Sminshall /* 233816Sbostic * Copyright (c) 1988 Regents of the University of California. 333816Sbostic * All rights reserved. 431892Sminshall * 533816Sbostic * Redistribution and use in source and binary forms are permitted 635421Sminshall * provided that the above copyright notice and this paragraph are 735421Sminshall * duplicated in all such forms and that any documentation, 835421Sminshall * advertising materials, and other materials related to such 935421Sminshall * distribution and use acknowledge that the software was developed 1035421Sminshall * by the University of California, Berkeley. The name of the 1135421Sminshall * University may not be used to endorse or promote products derived 1235421Sminshall * from this software without specific prior written permission. 1335421Sminshall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1435421Sminshall * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1535421Sminshall * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1631892Sminshall */ 1731892Sminshall 1831892Sminshall #ifndef lint 19*39468Sminshall static char sccsid[] = "@(#)api.c 4.4 (Berkeley) 10/31/89"; 2033816Sbostic #endif /* not lint */ 2131892Sminshall 2231892Sminshall /* 2331158Sminshall * This file implements the API used in the PC version. 2431158Sminshall */ 2531158Sminshall 2631158Sminshall #include <stdio.h> 2731158Sminshall 2831158Sminshall #include "api.h" 2931183Sminshall #include "../general/general.h" 3031158Sminshall 3131871Sminshall #include "../api/disp_asc.h" 3231226Sminshall 3331871Sminshall #include "screen.h" 3438210Sminshall #include "hostctlr.h" 3531871Sminshall #include "oia.h" 3631193Sminshall 3731183Sminshall #include "../general/globals.h" 3831158Sminshall 39*39468Sminshall int apitrace = 0; 4038924Sminshall 4131158Sminshall /* 42*39468Sminshall * Some defines for things we use internally. 43*39468Sminshall */ 44*39468Sminshall 45*39468Sminshall #define PS_SESSION_ID 23 46*39468Sminshall #define BUF_SESSION_ID 0 47*39468Sminshall 48*39468Sminshall /* 4931193Sminshall * General utility routines. 5031193Sminshall */ 5131193Sminshall 5231193Sminshall #if defined(MSDOS) 5331193Sminshall 5431211Sminshall #if defined(LINT_ARGS) 5531211Sminshall static void movetous(char *, int, int, int); 5631211Sminshall static void movetothem(int, int, char *, int); 5731211Sminshall #endif /* defined(LINT_ARGS) */ 5831211Sminshall 5931507Sminshall #define access_api(foo,length,copyin) (foo) 6031507Sminshall #define unaccess_api(foo,goo,length,copyout) 6131226Sminshall 6231193Sminshall static void 6331193Sminshall movetous(parms, es, di, length) 6431193Sminshall char *parms; 6535421Sminshall int es, di; 6635421Sminshall int length; 6731193Sminshall { 6831211Sminshall char far *farparms = parms; 6931193Sminshall 7035421Sminshall movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length); 7138924Sminshall if (apitrace) { 7238924Sminshall Dump('(', parms, length); 7338924Sminshall } 7431193Sminshall } 7531193Sminshall 7631193Sminshall static void 7731211Sminshall movetothem(es, di, parms, length) 7831211Sminshall int es, di; 7931211Sminshall char *parms; 8031211Sminshall int length; 8131193Sminshall { 8231211Sminshall char far *farparms = parms; 8331193Sminshall 8435421Sminshall movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length); 8538924Sminshall if (apitrace) { 8638924Sminshall Dump(')', parms, length); 8738924Sminshall } 8831193Sminshall } 8931193Sminshall #endif /* defined(MSDOS) */ 9031193Sminshall 9131226Sminshall #if defined(unix) 9235421Sminshall extern char *access_api(); 9335421Sminshall extern void movetous(), movetothem(), unaccess_api(); 9431226Sminshall #endif /* defined(unix) */ 9531226Sminshall 9631470Sminshall 9731193Sminshall /* 9831158Sminshall * Supervisor Services. 9931158Sminshall */ 10031158Sminshall 10131158Sminshall static void 10231193Sminshall name_resolution(regs, sregs) 10331158Sminshall union REGS *regs; 10431158Sminshall struct SREGS *sregs; 10531158Sminshall { 10631167Sminshall NameResolveParms parms; 10731161Sminshall 10831167Sminshall movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); 10931161Sminshall 11031161Sminshall regs->h.cl = 0; 11131193Sminshall if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { 11231161Sminshall regs->x.dx = GATE_SESSMGR; 11331193Sminshall } else if (memcmp((char *)&parms, NAME_KEYBOARD, 11431193Sminshall sizeof parms.gate_name) == 0) { 11531161Sminshall regs->x.dx = GATE_KEYBOARD; 11631193Sminshall } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { 11731161Sminshall regs->x.dx = GATE_COPY; 11831193Sminshall } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) { 11931161Sminshall regs->x.dx = GATE_OIAM; 12031161Sminshall } else { 12131161Sminshall regs->h.cl = 0x2e; /* Name not found */ 12231161Sminshall } 12331161Sminshall regs->h.ch = 0x12; 12431161Sminshall regs->h.bh = 7; 12531158Sminshall } 12631158Sminshall 12731158Sminshall /* 12831158Sminshall * Session Information Services. 12931158Sminshall */ 13031158Sminshall 13131158Sminshall static void 13231158Sminshall query_session_id(regs, sregs) 13331158Sminshall union REGS *regs; 13431158Sminshall struct SREGS *sregs; 13531158Sminshall { 13631167Sminshall QuerySessionIdParms parms; 13731161Sminshall 13831167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 13931161Sminshall 14031211Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 14131211Sminshall parms.rc = 0x0c; 14231211Sminshall } else if (parms.option_code != 0x01) { 14331211Sminshall parms.rc = 0x0d; /* Invalid option code */ 144*39468Sminshall #ifdef NOTOBS 145*39468Sminshall } else if ((parms.data_code != 0x45) && (parms.data_code != 0x00/*OBS*/)) { 14631211Sminshall parms.rc = 0x0b; 147*39468Sminshall #endif /* NOTOBS */ 14831161Sminshall } else { 14931168Sminshall NameArray list; 15031167Sminshall 15131167Sminshall movetous((char *)&list, FP_SEG(parms.name_array), 15235421Sminshall FP_OFF(parms.name_array), sizeof list); 15331168Sminshall if ((list.length < 14) || (list.length > 170)) { 15431167Sminshall parms.rc = 0x12; 15531161Sminshall } else { 15631167Sminshall list.number_matching_session = 1; 15731167Sminshall list.name_array_element.short_name = parms.data_code; 15831167Sminshall list.name_array_element.type = TYPE_DFT; 159*39468Sminshall list.name_array_element.session_id = PS_SESSION_ID; 16031167Sminshall memcpy(list.name_array_element.long_name, "ONLYSESS", 16131167Sminshall sizeof list.name_array_element.long_name); 16231167Sminshall movetothem(FP_SEG(parms.name_array), 16331193Sminshall FP_OFF(parms.name_array), (char *)&list, sizeof list); 16431167Sminshall parms.rc = 0; 16531161Sminshall } 16631161Sminshall } 16731211Sminshall parms.function_id = 0x6b; 16831167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 16931158Sminshall } 17031158Sminshall 17131158Sminshall static void 17231158Sminshall query_session_parameters(regs, sregs) 17331158Sminshall union REGS *regs; 17431158Sminshall struct SREGS *sregs; 17531158Sminshall { 17631167Sminshall QuerySessionParametersParms parms; 17731167Sminshall 17831167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 17931167Sminshall 18031168Sminshall if ((parms.rc !=0) || (parms.function_id != 0)) { 18131211Sminshall parms.rc = 0x0c; 182*39468Sminshall } else if (parms.session_id != PS_SESSION_ID) { 18331211Sminshall parms.rc = 0x02; 18431167Sminshall } else { 18531211Sminshall parms.rc = 0; 18631167Sminshall parms.session_type = TYPE_DFT; 18731167Sminshall parms.session_characteristics = 0; /* Neither EAB nor PSS */ 18831167Sminshall parms.rows = MaxNumberLines; 18931167Sminshall parms.columns = MaxNumberColumns; 19031167Sminshall parms.presentation_space = 0; 19131167Sminshall } 19231211Sminshall parms.function_id = 0x6b; 19331168Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 19431158Sminshall } 19531158Sminshall 19631158Sminshall static void 19731158Sminshall query_session_cursor(regs, sregs) 19831158Sminshall union REGS *regs; 19931158Sminshall struct SREGS *sregs; 20031158Sminshall { 20131167Sminshall QuerySessionCursorParms parms; 20231167Sminshall 20331167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 20431167Sminshall 20531167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 20631167Sminshall parms.rc = 0x0c; 207*39468Sminshall } else if (parms.session_id != PS_SESSION_ID) { 20831167Sminshall parms.rc = 0x02; 20931167Sminshall } else { 21031167Sminshall parms.rc = 0; 21131167Sminshall parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ 21231167Sminshall parms.row_address = ScreenLine(CursorAddress); 21331167Sminshall parms.column_address = ScreenLineOffset(CursorAddress); 21431167Sminshall } 21531167Sminshall 21631211Sminshall parms.function_id = 0x6b; 21731211Sminshall movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms); 21831158Sminshall } 21931158Sminshall 22031158Sminshall /* 22131158Sminshall * Keyboard Services. 22231158Sminshall */ 22331158Sminshall 22431158Sminshall 22531158Sminshall static void 22631158Sminshall connect_to_keyboard(regs, sregs) 22731158Sminshall union REGS *regs; 22831158Sminshall struct SREGS *sregs; 22931158Sminshall { 23031167Sminshall ConnectToKeyboardParms parms; 23131167Sminshall 23231183Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 23331167Sminshall 23431167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 23531167Sminshall parms.rc = 0x0c; 236*39468Sminshall } else if (parms.session_id != PS_SESSION_ID) { 23731167Sminshall parms.rc = 0x02; 23831167Sminshall } else if (parms.intercept_options != 0) { 23931167Sminshall parms.rc = 0x01; 24031167Sminshall } else { 24131167Sminshall parms.rc = 0; 24231167Sminshall parms.first_connection_identifier = 0; 24331167Sminshall } 24431167Sminshall parms.function_id = 0x62; 24531167Sminshall 24631167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 24731158Sminshall } 24831158Sminshall 24931158Sminshall static void 25031167Sminshall disconnect_from_keyboard(regs, sregs) 25131158Sminshall union REGS *regs; 25231158Sminshall struct SREGS *sregs; 25331158Sminshall { 25431167Sminshall DisconnectFromKeyboardParms parms; 25531167Sminshall 25631167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 25731167Sminshall 25831167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 25931167Sminshall parms.rc = 0x0c; 260*39468Sminshall } else if (parms.session_id != PS_SESSION_ID) { 26131167Sminshall parms.rc = 0x02; 26231167Sminshall } else if (parms.connectors_task_id != 0) { 26331167Sminshall parms.rc = 04; /* XXX */ 26431167Sminshall } else { 26531167Sminshall parms.rc = 0; 26631167Sminshall } 26731167Sminshall parms.function_id = 0x62; 26831167Sminshall 26931167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 27031158Sminshall } 27131158Sminshall 27231158Sminshall static void 27331158Sminshall write_keystroke(regs, sregs) 27431158Sminshall union REGS *regs; 27531158Sminshall struct SREGS *sregs; 27631158Sminshall { 27731198Sminshall WriteKeystrokeParms parms; 27831198Sminshall 27931198Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 28031198Sminshall 28131198Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 28231198Sminshall parms.rc = 0x0c; 283*39468Sminshall } else if (parms.session_id != PS_SESSION_ID) { 28431198Sminshall parms.rc = 0x02; 28531198Sminshall } else if (parms.connectors_task_id != 0) { 28631198Sminshall parms.rc = 0x04; 28731198Sminshall } else { 28831198Sminshall parms.number_of_keys_sent = 0; 28931198Sminshall parms.rc = 0; 29031198Sminshall if (parms.options == OPTION_SINGLE_KEYSTROKE) { 29131198Sminshall KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry; 29231198Sminshall 29331198Sminshall if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) { 29431198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */ 29531198Sminshall } 29631198Sminshall parms.number_of_keys_sent++; 29731198Sminshall } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) { 29831198Sminshall KeystrokeList 29931198Sminshall list, 30031198Sminshall far *atlist = parms.keystroke_specifier.keystroke_list; 30131198Sminshall KeystrokeEntry 30231198Sminshall entry[10], /* 10 at a time */ 30331198Sminshall *ourentry, 30431198Sminshall far *theirentry; 30531198Sminshall int 30631198Sminshall todo; 30731198Sminshall 30831198Sminshall movetous((char *)&list, FP_SEG(atlist), 30935421Sminshall FP_OFF(atlist), sizeof *atlist); 31031198Sminshall todo = list.length/2; 31131198Sminshall ourentry = entry+(highestof(entry)+1); 31235421Sminshall theirentry = &atlist->keystrokes; 31331198Sminshall 31431198Sminshall while (todo) { 31531198Sminshall if (ourentry > &entry[highestof(entry)]) { 31631198Sminshall int thistime; 31731198Sminshall 31831198Sminshall thistime = todo; 31931198Sminshall if (thistime > numberof(entry)) { 32031198Sminshall thistime = numberof(entry); 32131198Sminshall } 32231198Sminshall movetous((char *)entry, FP_SEG(theirentry), 32331198Sminshall FP_OFF(theirentry), thistime*sizeof *theirentry); 32431198Sminshall theirentry += thistime; 32531198Sminshall ourentry = entry; 32631198Sminshall } 32731198Sminshall if (AcceptKeystroke(ourentry->scancode, 32831198Sminshall ourentry->shift_state) == 0) { 32931198Sminshall parms.rc = 0x10; /* XXX needs 0x12 too! */ 33031198Sminshall break; 33131198Sminshall } 33231198Sminshall parms.number_of_keys_sent++; 33331198Sminshall ourentry++; 33431198Sminshall todo--; 33531198Sminshall } 33631198Sminshall } else { 33731198Sminshall parms.rc = 0x01; 33831198Sminshall } 33931198Sminshall } 34031198Sminshall parms.function_id = 0x62; 34131198Sminshall 34231198Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 34331167Sminshall /* XXX */ 34431158Sminshall } 34531158Sminshall 34631167Sminshall 34731158Sminshall static void 34831167Sminshall disable_input(regs, sregs) 34931167Sminshall union REGS *regs; 35031167Sminshall struct SREGS *sregs; 35131167Sminshall { 35231167Sminshall DisableInputParms parms; 35331167Sminshall 35431167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 35531167Sminshall 35631167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 35731167Sminshall parms.rc = 0x0c; 358*39468Sminshall } else if (parms.session_id != PS_SESSION_ID) { 35931167Sminshall parms.rc = 0x02; 36031167Sminshall } else if (parms.connectors_task_id != 0) { 36131167Sminshall parms.rc = 0x04; 36231167Sminshall } else { 36331211Sminshall SetOiaApiInhibit(&OperatorInformationArea); 36431167Sminshall parms.rc = 0; 36531167Sminshall } 36631167Sminshall parms.function_id = 0x62; 36731167Sminshall 36831167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 36931167Sminshall } 37031167Sminshall 37131167Sminshall static void 37231158Sminshall enable_input(regs, sregs) 37331158Sminshall union REGS *regs; 37431158Sminshall struct SREGS *sregs; 37531158Sminshall { 37631167Sminshall EnableInputParms parms; 37731167Sminshall 37831167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 37931167Sminshall 38031167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 38131167Sminshall parms.rc = 0x0c; 382*39468Sminshall } else if (parms.session_id != PS_SESSION_ID) { 38331167Sminshall parms.rc = 0x02; 38431167Sminshall } else if (parms.connectors_task_id != 0) { 38531167Sminshall parms.rc = 0x04; 38631167Sminshall } else { 38731211Sminshall ResetOiaApiInhibit(&OperatorInformationArea); 38831167Sminshall parms.rc = 0; 38931167Sminshall } 39031167Sminshall parms.function_id = 0x62; 39131167Sminshall 39231167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 39331158Sminshall } 39431158Sminshall 39531158Sminshall /* 39631158Sminshall * Copy Services. 39731158Sminshall */ 39831158Sminshall 39931507Sminshall static 40031507Sminshall copy_subroutine(target, source, parms, what_is_user, length) 40131226Sminshall BufferDescriptor *target, *source; 40231226Sminshall CopyStringParms *parms; 40331226Sminshall int what_is_user; 40431226Sminshall #define USER_IS_TARGET 0 40531226Sminshall #define USER_IS_SOURCE 1 40631226Sminshall { 40731226Sminshall #define TARGET_NO_EAB 1 40831226Sminshall #define SOURCE_NO_EAB 2 40931226Sminshall #define TARGET_PC 4 41031226Sminshall #define SOURCE_PC 8 41131226Sminshall #define NO_FIELD_ATTRIBUTES 16 41231226Sminshall int needtodo = 0; 41331226Sminshall int access_length; 41431226Sminshall char far *input; 41531226Sminshall char far *output; 41631226Sminshall char far *access_pointer; 41731226Sminshall 41831226Sminshall if ((target->characteristics^source->characteristics) 41931226Sminshall &CHARACTERISTIC_EAB) { 42031226Sminshall if (target->characteristics&CHARACTERISTIC_EAB) { 42131226Sminshall needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */ 42231226Sminshall } else { 42331226Sminshall needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */ 42431226Sminshall } 42531226Sminshall } 42631226Sminshall if (target->session_type != source->session_type) { 42731226Sminshall if (target->session_type == TYPE_PC) { 42831226Sminshall needtodo |= TARGET_PC; /* scan codes to PC */ 42931226Sminshall } else { 43031226Sminshall needtodo |= SOURCE_PC; /* PC to scan codes */ 43131226Sminshall } 43231226Sminshall } 43331226Sminshall if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) { 43431226Sminshall needtodo |= NO_FIELD_ATTRIBUTES; 43531226Sminshall } 43631507Sminshall access_length = length; 43731226Sminshall if (what_is_user == USER_IS_TARGET) { 43831226Sminshall if (target->characteristics&CHARACTERISTIC_EAB) { 43931226Sminshall access_length *= 2; 44031226Sminshall } 44131226Sminshall input = (char far *) &Host[source->begin]; 44231226Sminshall access_pointer = target->buffer; 44331507Sminshall output = access_api(target->buffer, access_length, 0); 44431226Sminshall } else { 44531226Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 44631226Sminshall access_length *= 2; 44731226Sminshall } 44831226Sminshall access_pointer = source->buffer; 44931507Sminshall input = access_api(source->buffer, access_length, 1); 45031226Sminshall output = (char far *) &Host[target->begin]; 45131226Sminshall } 45231226Sminshall while (length--) { 45331226Sminshall if (needtodo&TARGET_PC) { 45431226Sminshall *output++ = disp_asc[*input++]; 45531226Sminshall } else if (needtodo&SOURCE_PC) { 45631226Sminshall *output++ = asc_disp[*input++]; 45731226Sminshall } else { 45831226Sminshall *output++ = *input++; 45931226Sminshall } 46031226Sminshall if (needtodo&TARGET_NO_EAB) { 46135421Sminshall input++; 46231226Sminshall } else if (needtodo&SOURCE_NO_EAB) { 46331226Sminshall *output++ = 0; /* Should figure out good EAB? */ 46431226Sminshall } 46531226Sminshall } 46631226Sminshall if (what_is_user == USER_IS_TARGET) { 46731507Sminshall unaccess_api(target->buffer, access_pointer, access_length, 1); 46831226Sminshall } else { 46931507Sminshall unaccess_api(source->buffer, access_pointer, access_length, 0); 47031226Sminshall } 47131226Sminshall } 47231226Sminshall 47331226Sminshall 47431158Sminshall static void 47531167Sminshall copy_string(regs, sregs) 47631158Sminshall union REGS *regs; 47731158Sminshall struct SREGS *sregs; 47831158Sminshall { 47931167Sminshall CopyStringParms parms; 48031226Sminshall BufferDescriptor *target = &parms.target, *source = &parms.source; 48131226Sminshall int length; 48231167Sminshall 48331167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 48431167Sminshall 48531507Sminshall length = 1+parms.source_end-source->begin; 48631167Sminshall if ((parms.rc != 0) || (parms.function_id !=0)) { 48731167Sminshall parms.rc = 0x0c; 488*39468Sminshall } else if (target->session_id == BUF_SESSION_ID) { /* Target is buffer */ 489*39468Sminshall if (source->session_id != PS_SESSION_ID) { /* A no-no */ 49031226Sminshall parms.rc = 0x2; 49131226Sminshall } else { 49231507Sminshall if ((source->begin < 0) || (source->begin > highestof(Host))) { 49331507Sminshall parms.rc = 0x06; /* invalid source definition */ 49431507Sminshall } else { 49531507Sminshall if ((source->begin+length) > highestof(Host)) { 49631507Sminshall length = highestof(Host)-source->begin; 49731507Sminshall parms.rc = 0x0f; /* Truncate */ 49831507Sminshall } 49931507Sminshall if ((source->characteristics == target->characteristics) && 50031226Sminshall (source->session_type == target->session_type)) { 50131507Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 50231507Sminshall length *= 2; 50331507Sminshall } 50435421Sminshall movetothem(FP_SEG(target->buffer), 50535421Sminshall FP_OFF(target->buffer), 50631507Sminshall (char *)&Host[source->begin], length); 50731507Sminshall } else { 50831507Sminshall copy_subroutine(target, source, &parms, 50931507Sminshall USER_IS_TARGET, length); 51031226Sminshall } 51131226Sminshall } 51231226Sminshall } 513*39468Sminshall } else if (source->session_id != BUF_SESSION_ID) { 51431226Sminshall parms.rc = 0xd; 51531226Sminshall } else { 51638210Sminshall /* Send to presentation space (3270 buffer) */ 51738210Sminshall if ((target->begin < 0) || (target->begin > highestof(Host))) { 51838210Sminshall parms.rc = 0x07; /* invalid target definition */ 51938210Sminshall } if (!UnLocked) { 52038210Sminshall parms.rc = 0x03; /* Keyboard locked */ 52138210Sminshall } else if (parms.copy_mode != 0) { 52238210Sminshall parms.rc = 0x0f; /* Copy of field attr's not allowed */ 52338210Sminshall } else if (IsProtected(target->begin) || /* Make sure no protected */ 52438210Sminshall (WhereAttrByte(target->begin) != /* in range */ 52538210Sminshall WhereAttrByte(target->begin+length-1))) { 52638210Sminshall parms.rc = 0x0e; /* Attempt to write in protected */ 52731507Sminshall } else { 52838210Sminshall if ((target->begin+length) > highestof(Host)) { 52938210Sminshall length = highestof(Host)-target->begin; 53031507Sminshall parms.rc = 0x0f; /* Truncate */ 53131226Sminshall } 53238210Sminshall TurnOnMdt(target->begin); /* Things have changed */ 53331507Sminshall if ((source->characteristics == target->characteristics) && 53431507Sminshall (source->session_type == target->session_type)) { 53531507Sminshall if (source->characteristics&CHARACTERISTIC_EAB) { 53631507Sminshall length *= 2; 53731507Sminshall } 53831507Sminshall movetous((char *)&Host[target->begin], 53935421Sminshall FP_SEG(source->buffer), 54035421Sminshall FP_OFF(source->buffer), length); 54131507Sminshall } else { 54231507Sminshall copy_subroutine(target, source, &parms, USER_IS_SOURCE, length); 54331507Sminshall } 54431226Sminshall } 54531167Sminshall } 546*39468Sminshall parms.function_id = 0x64; 54731183Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 54831158Sminshall } 549*39468Sminshall 550*39468Sminshall 55131158Sminshall /* 55231158Sminshall * Operator Information Area Services. 55331158Sminshall */ 55431158Sminshall 55531158Sminshall static void 55631158Sminshall read_oia_group(regs, sregs) 55731158Sminshall union REGS *regs; 55831158Sminshall struct SREGS *sregs; 55931158Sminshall { 56031167Sminshall ReadOiaGroupParms parms; 56131167Sminshall 56231167Sminshall movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 56331167Sminshall 56431167Sminshall if ((parms.rc != 0) || (parms.function_id != 0)) { 56531167Sminshall parms.rc = 0x0c; 566*39468Sminshall } else if (parms.session_id != PS_SESSION_ID) { 56731167Sminshall parms.rc = 0x02; 56831167Sminshall } else { 56931167Sminshall int group = parms.oia_group_number; 57031193Sminshall char *from; 57131193Sminshall int size; 57231167Sminshall 57331211Sminshall if ((group != API_OIA_ALL_GROUPS) && 57431211Sminshall ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) { 57531193Sminshall } else { 57631193Sminshall if (group == API_OIA_ALL_GROUPS) { 57731193Sminshall size = API_OIA_BYTES_ALL_GROUPS; 57831193Sminshall from = (char *)&OperatorInformationArea; 57931193Sminshall } else if (group == API_OIA_INPUT_INHIBITED) { 58031193Sminshall size = sizeof OperatorInformationArea.input_inhibited; 58131193Sminshall from = (char *)&OperatorInformationArea.input_inhibited[0]; 58231193Sminshall } else { 58331193Sminshall size = 1; 58431193Sminshall from = ((char *)&OperatorInformationArea)+group; 58531193Sminshall } 58631193Sminshall movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), 58731193Sminshall from, size); 58831168Sminshall } 58931167Sminshall } 59031168Sminshall parms.function_id = 0x6d; 59131167Sminshall movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 59231158Sminshall } 59331158Sminshall 59435421Sminshall /*ARGSUSED*/ 59531158Sminshall static void 59631158Sminshall unknown_op(regs, sregs) 59731158Sminshall union REGS *regs; 59831158Sminshall struct SREGS *sregs; 59931158Sminshall { 60031158Sminshall regs->h.ch = 0x12; 60131158Sminshall regs->h.cl = 0x05; 60231158Sminshall } 60331158Sminshall 60431158Sminshall 60531158Sminshall handle_api(regs, sregs) 60631158Sminshall union REGS *regs; 60731158Sminshall struct SREGS *sregs; 60831158Sminshall { 60938924Sminshall /* 61038924Sminshall * Do we need to log this transaction? 61138924Sminshall */ 61238924Sminshall if (apitrace) { 61338924Sminshall Dump('<', (char *)regs, sizeof *regs); 61438924Sminshall Dump('<', (char *)sregs, sizeof *sregs); 61538924Sminshall } 61631158Sminshall if (regs->h.ah == NAME_RESOLUTION) { 61731158Sminshall name_resolution(regs, sregs); 61831517Sminshall #if defined(unix) 61931517Sminshall } else if (regs->h.ah == PS_OR_OIA_MODIFIED) { 62031517Sminshall while ((oia_modified == 0) && (ps_modified == 0)) { 62131517Sminshall (void) Scheduler(1); 62231517Sminshall } 62331517Sminshall oia_modified = ps_modified = 0; 62431517Sminshall #endif /* defined(unix) */ 62531168Sminshall } else if (regs->h.ah != 0x09) { 62631168Sminshall regs->h.ch = 0x12; 62731168Sminshall regs->h.cl = 0x0f; /* XXX Invalid environmental access */ 62831168Sminshall } else if (regs->x.bx != 0x8020) { 62931168Sminshall regs->h.ch = 0x12; 63031168Sminshall regs->h.cl = 0x08; /* XXX Invalid wait specified */ 63131168Sminshall } else if (regs->h.ch != 0) { 63231211Sminshall regs->x.cx = 0x1206; /* XXX Invalid priority */ 63331158Sminshall } else { 63431158Sminshall switch (regs->x.dx) { 63531158Sminshall case GATE_SESSMGR: 63631158Sminshall switch (regs->h.al) { 63731158Sminshall case QUERY_SESSION_ID: 63831168Sminshall if (regs->h.cl != 0) { 63931211Sminshall regs->x.cx = 0x1206; 64031168Sminshall } else { 64131211Sminshall regs->x.cx = 0x1200; 64231168Sminshall query_session_id(regs, sregs); 64331168Sminshall } 64431158Sminshall break; 64531211Sminshall case QUERY_SESSION_PARAMETERS: 64631168Sminshall if (regs->h.cl != 0) { 64731211Sminshall regs->x.cx = 0x1206; 64831168Sminshall } else { 64931211Sminshall regs->x.cx = 0x1200; 65031193Sminshall query_session_parameters(regs, sregs); 65131168Sminshall } 65231158Sminshall break; 65331158Sminshall case QUERY_SESSION_CURSOR: 654*39468Sminshall if ((regs->h.cl != 0xff) && (regs->h.cl != 0x00/*OBS*/)) { 65531211Sminshall regs->x.cx = 0x1206; 65631168Sminshall } else { 65731211Sminshall regs->x.cx = 0x1200; 65831168Sminshall query_session_cursor(regs, sregs); 65931168Sminshall } 66031158Sminshall break; 66131158Sminshall default: 66231158Sminshall unknown_op(regs, sregs); 66331158Sminshall break; 66431158Sminshall } 66531158Sminshall break; 66631158Sminshall case GATE_KEYBOARD: 66731168Sminshall if (regs->h.cl != 00) { 66831211Sminshall regs->x.cx = 0x1206; 66931168Sminshall } else { 67031211Sminshall regs->x.cx = 0x1200; 67131168Sminshall switch (regs->h.al) { 67231168Sminshall case CONNECT_TO_KEYBOARD: 67331168Sminshall connect_to_keyboard(regs, sregs); 67431168Sminshall break; 67531168Sminshall case DISABLE_INPUT: 67631168Sminshall disable_input(regs, sregs); 67731168Sminshall break; 67831168Sminshall case WRITE_KEYSTROKE: 67931168Sminshall write_keystroke(regs, sregs); 68031168Sminshall break; 68131168Sminshall case ENABLE_INPUT: 68231168Sminshall enable_input(regs, sregs); 68331168Sminshall break; 68431168Sminshall case DISCONNECT_FROM_KEYBOARD: 68531168Sminshall disconnect_from_keyboard(regs, sregs); 68631168Sminshall break; 68731168Sminshall default: 68831168Sminshall unknown_op(regs, sregs); 68931168Sminshall break; 69031168Sminshall } 69131158Sminshall } 69231158Sminshall break; 69331158Sminshall case GATE_COPY: 69431168Sminshall if (regs->h.cl != 0xff) { 69531211Sminshall regs->x.cx = 0x1206; 69631168Sminshall } else { 69731211Sminshall regs->x.cx = 0x1200; 69831168Sminshall switch (regs->h.al) { 69931168Sminshall case COPY_STRING: 70031168Sminshall copy_string(regs, sregs); 70131168Sminshall break; 70231168Sminshall default: 70331168Sminshall unknown_op(regs, sregs); 70431168Sminshall break; 70531168Sminshall } 70631158Sminshall } 70731158Sminshall break; 70831158Sminshall case GATE_OIAM: 70931168Sminshall if (regs->h.cl != 0xff) { 71031211Sminshall regs->x.cx = 0x1206; 71131168Sminshall } else { 71231211Sminshall regs->x.cx = 0x1200; 71331168Sminshall switch (regs->h.al) { 71431168Sminshall case READ_OIA_GROUP: 71531168Sminshall read_oia_group(regs, sregs); 71631168Sminshall break; 71731168Sminshall default: 71831168Sminshall unknown_op(regs, sregs); 71931168Sminshall break; 72031168Sminshall } 72131158Sminshall } 72231158Sminshall break; 72331158Sminshall default: 72431168Sminshall regs->h.ch = 0x12; 72531168Sminshall regs->h.cl = 0x34; /* Invalid GATE entry */ 72631158Sminshall break; 72731158Sminshall } 72831158Sminshall } 72938924Sminshall /* 73038924Sminshall * Do we need to log this transaction? 73138924Sminshall */ 73238924Sminshall if (apitrace) { 73338924Sminshall Dump('>', (char *)regs, sizeof *regs); 73438924Sminshall Dump('>', (char *)sregs, sizeof *sregs); 735*39468Sminshall #ifdef MSDOS 736*39468Sminshall { char buf[10]; gets(buf); } 737*39468Sminshall #endif /* MSDOS */ 73838924Sminshall } 73931158Sminshall } 740