1*48754Sbostic /*- 2*48754Sbostic * Copyright (c) 1988 The Regents of the University of California. 333820Sbostic * All rights reserved. 431890Sminshall * 5*48754Sbostic * %sccs.include.redist.c% 631890Sminshall */ 731890Sminshall 831890Sminshall #ifndef lint 9*48754Sbostic static char sccsid[] = "@(#)apilib.c 4.2 (Berkeley) 04/26/91"; 1033820Sbostic #endif /* not lint */ 1131890Sminshall 1231869Sminshall #include "../ctlr/api.h" 1331202Sminshall 1431205Sminshall #include "apilib.h" 1531202Sminshall 1631202Sminshall int 1731205Sminshall api_sup_errno = 0, /* Supervisor error number */ 1831205Sminshall api_sup_fcn_id = 0, /* Supervisor function id (0x12) */ 1931205Sminshall api_fcn_errno = 0, /* Function error number */ 2031205Sminshall api_fcn_fcn_id = 0; /* Function ID (0x6b, etc.) */ 2131205Sminshall 2231205Sminshall static int 2331205Sminshall gate_sessmgr = 0, 2431205Sminshall gate_keyboard = 0, 2531205Sminshall gate_copy = 0, 2631205Sminshall gate_oiam = 0; 2731205Sminshall 2831205Sminshall /* 2931205Sminshall * Issue an API request, with reg structures supplied by the caller. 3031205Sminshall * 3131205Sminshall * Only certain routines need this (supervisor services come to mind). 3231205Sminshall */ 3331205Sminshall 3431500Sminshall static int 3531500Sminshall api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, regs, sregs) 3631205Sminshall int ah, al, bh, bl, cx, dx; 3731205Sminshall char *parms; 3831500Sminshall int length; 3931205Sminshall union REGS *regs; 4031205Sminshall struct SREGS *sregs; 4131205Sminshall { 4231205Sminshall char far *ourseg = parms; 4331205Sminshall 4431205Sminshall regs->h.ah = ah; 4531205Sminshall regs->h.al = al; 4631205Sminshall regs->h.bh = bh; 4731205Sminshall regs->h.bl = bl; 4831205Sminshall regs->x.cx = cx; 4931205Sminshall regs->x.dx = dx; 5035418Sminshall sregs->es = FP_SEG(ourseg); 5135418Sminshall regs->x.di = FP_OFF(ourseg); 5231205Sminshall 5331458Sminshall #if defined(MSDOS) 5431205Sminshall int86x(API_INTERRUPT_NUMBER, regs, regs, sregs); 5531458Sminshall #endif /* defined(MSDOS) */ 5631458Sminshall #if defined(unix) 5731500Sminshall api_exch_api(regs, sregs, parms, length); 5831458Sminshall #endif /* defined(unix) */ 5931458Sminshall 6031205Sminshall if (regs->h.cl != 0) { 6131205Sminshall api_sup_errno = regs->h.cl; 6231205Sminshall return -1; 6331205Sminshall } else { 6431205Sminshall return 0; 6531205Sminshall } 6631205Sminshall } 6731205Sminshall 6831205Sminshall 6931205Sminshall /* 7031205Sminshall * Issue an API request without requiring caller to supply 7131205Sminshall * registers. Most routines use this. 7231205Sminshall */ 7331205Sminshall 7431500Sminshall static int 7531500Sminshall api_issue(ah, al, bh, bl, cx, dx, parms, length) 7631205Sminshall int 7731202Sminshall ah, 7831202Sminshall al, 7931202Sminshall bh, 8031202Sminshall bl, 8131202Sminshall cx, 8231202Sminshall dx; 8331202Sminshall char *parms; 8431500Sminshall int length; /* Length of parms */ 8531202Sminshall { 8631202Sminshall union REGS regs; 8731202Sminshall struct SREGS sregs; 8831202Sminshall 8931500Sminshall return api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, ®s, &sregs); 9031202Sminshall } 9131205Sminshall 9231205Sminshall /* 9331205Sminshall * Supervisor Services 9431205Sminshall */ 9531202Sminshall 9631202Sminshall int 9731202Sminshall api_name_resolve(name) 9831202Sminshall char *name; 9931202Sminshall { 10031202Sminshall NameResolveParms parms; 10131202Sminshall int i; 10231202Sminshall union REGS regs; 10331202Sminshall struct SREGS sregs; 10431202Sminshall 10531202Sminshall for (i = 0; i < sizeof parms.gate_name; i++) { 10631202Sminshall if (*name) { 10731202Sminshall parms.gate_name[i] = *name++; 10831202Sminshall } else { 10931202Sminshall parms.gate_name[i] = ' '; 11031202Sminshall } 11131202Sminshall } 11231202Sminshall 11335418Sminshall if (api_issue_regs(NAME_RESOLUTION, 0, 0, 0, 0, 0, (char *) &parms, 11435418Sminshall sizeof parms, ®s, &sregs) == -1) { 11531205Sminshall return -1; 11631205Sminshall } else { 11731205Sminshall return regs.x.dx; 11831202Sminshall } 11931205Sminshall } 12031513Sminshall 12131513Sminshall #if defined(unix) 12231513Sminshall /* 12331513Sminshall * Block until the oia or ps is modified. 12431513Sminshall */ 12531513Sminshall 12631513Sminshall int 12731513Sminshall api_ps_or_oia_modified() 12831513Sminshall { 12931513Sminshall union REGS regs; 13031513Sminshall struct SREGS sregs; 13131513Sminshall 13235418Sminshall if (api_issue_regs(PS_OR_OIA_MODIFIED, 0, 0, 0, 0, 0, (char *) 0, 13335418Sminshall 0, ®s, &sregs) == -1) { 13431513Sminshall return -1; 13531513Sminshall } else { 13631513Sminshall return 0; 13731513Sminshall } 13831513Sminshall } 13931513Sminshall #endif /* defined(unix) */ 14031205Sminshall 14131205Sminshall /* 14231205Sminshall * Session Information Services 14331205Sminshall */ 14431202Sminshall 14531210Sminshall api_query_session_id(parms) 14631205Sminshall QuerySessionIdParms *parms; 14731205Sminshall { 14831205Sminshall if (api_issue(0x09, QUERY_SESSION_ID, 0x80, 0x20, 0, 14931500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 15031205Sminshall api_fcn_errno = 0; 15131205Sminshall api_fcn_fcn_id = 0; 15231202Sminshall return -1; 15331205Sminshall } else if (parms->rc == 0) { 15431205Sminshall return 0; 15531202Sminshall } else { 15631205Sminshall api_fcn_errno = parms->rc; 15731205Sminshall api_fcn_fcn_id = parms->function_id; 15831205Sminshall return -1; 15931202Sminshall } 16031202Sminshall } 16131205Sminshall 16231205Sminshall 16331210Sminshall api_query_session_parameters(parms) 16431205Sminshall QuerySessionParametersParms *parms; 16531205Sminshall { 16631210Sminshall if (api_issue(0x09, QUERY_SESSION_PARAMETERS, 0x80, 0x20, 0, 16731500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 16831205Sminshall api_fcn_errno = 0; 16931205Sminshall api_fcn_fcn_id = 0; 17031205Sminshall return -1; 17131205Sminshall } else if (parms->rc == 0) { 17231205Sminshall return 0; 17331205Sminshall } else { 17431205Sminshall api_fcn_errno = parms->rc; 17531205Sminshall api_fcn_fcn_id = parms->function_id; 17631205Sminshall return -1; 17731205Sminshall } 17831205Sminshall } 17931205Sminshall 18031205Sminshall api_query_session_cursor(parms) 18131205Sminshall QuerySessionCursorParms *parms; 18231205Sminshall { 18331210Sminshall if (api_issue(0x09, QUERY_SESSION_CURSOR, 0x80, 0x20, 0xff, 18431500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 18531205Sminshall api_fcn_errno = 0; 18631205Sminshall api_fcn_fcn_id = 0; 18731205Sminshall return -1; 18831205Sminshall } else if (parms->rc == 0) { 18931205Sminshall return 0; 19031205Sminshall } else { 19131205Sminshall api_fcn_errno = parms->rc; 19231205Sminshall api_fcn_fcn_id = parms->function_id; 19331205Sminshall return -1; 19431205Sminshall } 19531205Sminshall } 19631205Sminshall 19731205Sminshall /* 19831205Sminshall * Keyboard Services 19931205Sminshall */ 20031205Sminshall 20131205Sminshall api_connect_to_keyboard(parms) 20231205Sminshall ConnectToKeyboardParms *parms; 20331205Sminshall { 20431205Sminshall if (api_issue(0x09, CONNECT_TO_KEYBOARD, 0x80, 0x20, 0, 20531500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 20631205Sminshall api_fcn_errno = 0; 20731205Sminshall api_fcn_fcn_id = 0; 20831205Sminshall return -1; 20931205Sminshall } else if (parms->rc == 0) { 21031205Sminshall return 0; 21131205Sminshall } else { 21231205Sminshall api_fcn_errno = parms->rc; 21331205Sminshall api_fcn_fcn_id = parms->function_id; 21431205Sminshall return -1; 21531205Sminshall } 21631205Sminshall } 21731205Sminshall 21831205Sminshall 21931205Sminshall api_disconnect_from_keyboard(parms) 22031205Sminshall DisconnectFromKeyboardParms *parms; 22131205Sminshall { 22231205Sminshall if (api_issue(0x09, DISCONNECT_FROM_KEYBOARD, 0x80, 0x20, 0, 22331500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 22431205Sminshall api_fcn_errno = 0; 22531205Sminshall api_fcn_fcn_id = 0; 22631205Sminshall return -1; 22731205Sminshall } else if (parms->rc == 0) { 22831205Sminshall return 0; 22931205Sminshall } else { 23031205Sminshall api_fcn_errno = parms->rc; 23131205Sminshall api_fcn_fcn_id = parms->function_id; 23231205Sminshall return -1; 23331205Sminshall } 23431205Sminshall } 23531205Sminshall 23631205Sminshall 23731205Sminshall api_write_keystroke(parms) 23831205Sminshall WriteKeystrokeParms *parms; 23931205Sminshall { 24031205Sminshall if (api_issue(0x09, WRITE_KEYSTROKE, 0x80, 0x20, 0, 24131500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 24231205Sminshall api_fcn_errno = 0; 24331205Sminshall api_fcn_fcn_id = 0; 24431205Sminshall return -1; 24531205Sminshall } else if (parms->rc == 0) { 24631205Sminshall return 0; 24731205Sminshall } else { 24831205Sminshall api_fcn_errno = parms->rc; 24931205Sminshall api_fcn_fcn_id = parms->function_id; 25031205Sminshall return -1; 25131205Sminshall } 25231205Sminshall } 25331205Sminshall 25431205Sminshall 25531205Sminshall api_disable_input(parms) 25631205Sminshall DisableInputParms *parms; 25731205Sminshall { 25831205Sminshall if (api_issue(0x09, DISABLE_INPUT, 0x80, 0x20, 0, 25931500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 26031205Sminshall api_fcn_errno = 0; 26131205Sminshall api_fcn_fcn_id = 0; 26231205Sminshall return -1; 26331205Sminshall } else if (parms->rc == 0) { 26431205Sminshall return 0; 26531205Sminshall } else { 26631205Sminshall api_fcn_errno = parms->rc; 26731205Sminshall api_fcn_fcn_id = parms->function_id; 26831205Sminshall return -1; 26931205Sminshall } 27031205Sminshall } 27131205Sminshall 27231205Sminshall api_enable_input(parms) 27331205Sminshall EnableInputParms *parms; 27431205Sminshall { 27531205Sminshall if (api_issue(0x09, ENABLE_INPUT, 0x80, 0x20, 0, 27631500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 27731205Sminshall api_fcn_errno = 0; 27831205Sminshall api_fcn_fcn_id = 0; 27931205Sminshall return -1; 28031205Sminshall } else if (parms->rc == 0) { 28131205Sminshall return 0; 28231205Sminshall } else { 28331205Sminshall api_fcn_errno = parms->rc; 28431205Sminshall api_fcn_fcn_id = parms->function_id; 28531205Sminshall return -1; 28631205Sminshall } 28731205Sminshall } 28831205Sminshall 28931205Sminshall /* 29031205Sminshall * Copy Services 29131205Sminshall */ 29231205Sminshall 29331205Sminshall api_copy_string(parms) 29431205Sminshall CopyStringParms *parms; 29531205Sminshall { 29631210Sminshall if (api_issue(0x09, COPY_STRING, 0x80, 0x20, 0xff, 29731500Sminshall gate_copy, (char *)parms, sizeof *parms) == -1) { 29831205Sminshall api_fcn_errno = 0; 29931205Sminshall api_fcn_fcn_id = 0; 30031205Sminshall return -1; 30131205Sminshall } else if (parms->rc == 0) { 30231205Sminshall return 0; 30331205Sminshall } else { 30431205Sminshall api_fcn_errno = parms->rc; 30531205Sminshall api_fcn_fcn_id = parms->function_id; 30631205Sminshall return -1; 30731205Sminshall } 30831205Sminshall } 30931205Sminshall 31031205Sminshall /* 31131205Sminshall * Operator Information Area Services 31231205Sminshall */ 31331205Sminshall 31431205Sminshall api_read_oia_group(parms) 31531205Sminshall ReadOiaGroupParms *parms; 31631205Sminshall { 31731210Sminshall if (api_issue(0x09, READ_OIA_GROUP, 0x80, 0x20, 0xff, 31831500Sminshall gate_oiam, (char *)parms, sizeof *parms) == -1) { 31931205Sminshall api_fcn_errno = 0; 32031205Sminshall api_fcn_fcn_id = 0; 32131205Sminshall return -1; 32231205Sminshall } else if (parms->rc == 0) { 32331205Sminshall return 0; 32431205Sminshall } else { 32531205Sminshall api_fcn_errno = parms->rc; 32631205Sminshall api_fcn_fcn_id = parms->function_id; 32731205Sminshall return -1; 32831205Sminshall } 32931205Sminshall } 33031205Sminshall 33131205Sminshall /* 33231493Sminshall * The "we are done" routine. This gets called last. 33331493Sminshall */ 33431493Sminshall 33531493Sminshall api_finish() 33631493Sminshall { 33731493Sminshall #if defined(unix) 33831493Sminshall if (api_close_api() == -1) { 33931493Sminshall return -1; 34031493Sminshall } else { 34131493Sminshall return 0; 34231493Sminshall } 34331493Sminshall #endif /* defined(unix) */ 34431493Sminshall } 34531493Sminshall 34631493Sminshall 34731493Sminshall /* 34831205Sminshall * The initialization routine. Be sure to call this first. 34931205Sminshall */ 35031205Sminshall 35131205Sminshall api_init() 35231205Sminshall { 35335418Sminshall #if defined(MSDOS) 35431205Sminshall union REGS regs; 35531205Sminshall struct SREGS sregs; 35631205Sminshall 35731205Sminshall regs.h.ah = 0x35; 35831205Sminshall regs.h.al = API_INTERRUPT_NUMBER; 35931205Sminshall intdosx(®s, ®s, &sregs); 36031205Sminshall 36131205Sminshall if ((regs.x.bx == 0) && (sregs.es == 0)) { 36231205Sminshall return 0; /* Interrupt not being handled */ 36331205Sminshall } 36431760Sminshall #endif /* defined(MSDOS) */ 36531458Sminshall #if defined(unix) 36635418Sminshall if (api_open_api((char *)0) == -1) { 36731458Sminshall return 0; 36831458Sminshall } 36931458Sminshall #endif /* defined(unix) */ 37031205Sminshall 37131205Sminshall gate_sessmgr = api_name_resolve("SESSMGR"); 37231205Sminshall gate_keyboard = api_name_resolve("KEYBOARD"); 37331205Sminshall gate_copy = api_name_resolve("COPY"); 37431205Sminshall gate_oiam = api_name_resolve("OIAM"); 37531205Sminshall 37631205Sminshall if ((gate_sessmgr == gate_keyboard) || 37731205Sminshall (gate_sessmgr == gate_copy) || 37831205Sminshall (gate_sessmgr == gate_oiam) || 37931205Sminshall (gate_keyboard == gate_copy) || 38031205Sminshall (gate_keyboard == gate_oiam) || 38131205Sminshall (gate_copy == gate_oiam)) { 38231205Sminshall return 0; /* Interrupt doesn't seem correct */ 38331205Sminshall } 38431205Sminshall return 1; 38531205Sminshall } 386