131890Sminshall /* 2*33820Sbostic * Copyright (c) 1988 Regents of the University of California. 3*33820Sbostic * All rights reserved. 431890Sminshall * 5*33820Sbostic * Redistribution and use in source and binary forms are permitted 6*33820Sbostic * provided that this notice is preserved and that due credit is given 7*33820Sbostic * to the University of California at Berkeley. The name of the University 8*33820Sbostic * may not be used to endorse or promote products derived from this 9*33820Sbostic * software without specific prior written permission. This software 10*33820Sbostic * is provided ``as is'' without express or implied warranty. 1131890Sminshall */ 1231890Sminshall 1331890Sminshall #ifndef lint 14*33820Sbostic static char sccsid[] = "@(#)apilib.c 3.2 (Berkeley) 03/28/88"; 15*33820Sbostic #endif /* not lint */ 1631890Sminshall 1731869Sminshall #include "../ctlr/api.h" 1831202Sminshall 1931205Sminshall #include "apilib.h" 2031202Sminshall 2131202Sminshall int 2231205Sminshall api_sup_errno = 0, /* Supervisor error number */ 2331205Sminshall api_sup_fcn_id = 0, /* Supervisor function id (0x12) */ 2431205Sminshall api_fcn_errno = 0, /* Function error number */ 2531205Sminshall api_fcn_fcn_id = 0; /* Function ID (0x6b, etc.) */ 2631205Sminshall 2731205Sminshall static int 2831205Sminshall gate_sessmgr = 0, 2931205Sminshall gate_keyboard = 0, 3031205Sminshall gate_copy = 0, 3131205Sminshall gate_oiam = 0; 3231205Sminshall 3331205Sminshall /* 3431205Sminshall * Issue an API request, with reg structures supplied by the caller. 3531205Sminshall * 3631205Sminshall * Only certain routines need this (supervisor services come to mind). 3731205Sminshall */ 3831205Sminshall 3931500Sminshall static int 4031500Sminshall api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, regs, sregs) 4131205Sminshall int ah, al, bh, bl, cx, dx; 4231205Sminshall char *parms; 4331500Sminshall int length; 4431205Sminshall union REGS *regs; 4531205Sminshall struct SREGS *sregs; 4631205Sminshall { 4731205Sminshall char far *ourseg = parms; 4831205Sminshall 4931205Sminshall regs->h.ah = ah; 5031205Sminshall regs->h.al = al; 5131205Sminshall regs->h.bh = bh; 5231205Sminshall regs->h.bl = bl; 5331205Sminshall regs->x.cx = cx; 5431205Sminshall regs->x.dx = dx; 5531205Sminshall sregs->es = (int) FP_SEG(ourseg); 5631205Sminshall regs->x.di = (int) FP_OFF(ourseg); 5731205Sminshall 5831458Sminshall #if defined(MSDOS) 5931205Sminshall int86x(API_INTERRUPT_NUMBER, regs, regs, sregs); 6031458Sminshall #endif /* defined(MSDOS) */ 6131458Sminshall #if defined(unix) 6231500Sminshall api_exch_api(regs, sregs, parms, length); 6331458Sminshall #endif /* defined(unix) */ 6431458Sminshall 6531205Sminshall if (regs->h.cl != 0) { 6631205Sminshall api_sup_errno = regs->h.cl; 6731205Sminshall return -1; 6831205Sminshall } else { 6931205Sminshall return 0; 7031205Sminshall } 7131205Sminshall } 7231205Sminshall 7331205Sminshall 7431205Sminshall /* 7531205Sminshall * Issue an API request without requiring caller to supply 7631205Sminshall * registers. Most routines use this. 7731205Sminshall */ 7831205Sminshall 7931500Sminshall static int 8031500Sminshall api_issue(ah, al, bh, bl, cx, dx, parms, length) 8131205Sminshall int 8231202Sminshall ah, 8331202Sminshall al, 8431202Sminshall bh, 8531202Sminshall bl, 8631202Sminshall cx, 8731202Sminshall dx; 8831202Sminshall char *parms; 8931500Sminshall int length; /* Length of parms */ 9031202Sminshall { 9131202Sminshall union REGS regs; 9231202Sminshall struct SREGS sregs; 9331202Sminshall 9431500Sminshall return api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, ®s, &sregs); 9531202Sminshall } 9631205Sminshall 9731205Sminshall /* 9831205Sminshall * Supervisor Services 9931205Sminshall */ 10031202Sminshall 10131202Sminshall int 10231202Sminshall api_name_resolve(name) 10331202Sminshall char *name; 10431202Sminshall { 10531202Sminshall NameResolveParms parms; 10631202Sminshall int i; 10731202Sminshall union REGS regs; 10831202Sminshall struct SREGS sregs; 10931202Sminshall 11031202Sminshall for (i = 0; i < sizeof parms.gate_name; i++) { 11131202Sminshall if (*name) { 11231202Sminshall parms.gate_name[i] = *name++; 11331202Sminshall } else { 11431202Sminshall parms.gate_name[i] = ' '; 11531202Sminshall } 11631202Sminshall } 11731202Sminshall 11831500Sminshall if (api_issue_regs(NAME_RESOLUTION, 0, 0, 0, 0, 0, &parms, sizeof parms, ®s, &sregs) 11931205Sminshall == -1) { 12031205Sminshall return -1; 12131205Sminshall } else { 12231205Sminshall return regs.x.dx; 12331202Sminshall } 12431205Sminshall } 12531513Sminshall 12631513Sminshall #if defined(unix) 12731513Sminshall /* 12831513Sminshall * Block until the oia or ps is modified. 12931513Sminshall */ 13031513Sminshall 13131513Sminshall int 13231513Sminshall api_ps_or_oia_modified() 13331513Sminshall { 13431513Sminshall union REGS regs; 13531513Sminshall struct SREGS sregs; 13631513Sminshall 13731513Sminshall if (api_issue_regs(PS_OR_OIA_MODIFIED, 0, 0, 0, 0, 0, 0, 0, ®s, &sregs) 13831513Sminshall == -1) { 13931513Sminshall return -1; 14031513Sminshall } else { 14131513Sminshall return 0; 14231513Sminshall } 14331513Sminshall } 14431513Sminshall #endif /* defined(unix) */ 14531205Sminshall 14631205Sminshall /* 14731205Sminshall * Session Information Services 14831205Sminshall */ 14931202Sminshall 15031210Sminshall api_query_session_id(parms) 15131205Sminshall QuerySessionIdParms *parms; 15231205Sminshall { 15331205Sminshall if (api_issue(0x09, QUERY_SESSION_ID, 0x80, 0x20, 0, 15431500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 15531205Sminshall api_fcn_errno = 0; 15631205Sminshall api_fcn_fcn_id = 0; 15731202Sminshall return -1; 15831205Sminshall } else if (parms->rc == 0) { 15931205Sminshall return 0; 16031202Sminshall } else { 16131205Sminshall api_fcn_errno = parms->rc; 16231205Sminshall api_fcn_fcn_id = parms->function_id; 16331205Sminshall return -1; 16431202Sminshall } 16531202Sminshall } 16631205Sminshall 16731205Sminshall 16831210Sminshall api_query_session_parameters(parms) 16931205Sminshall QuerySessionParametersParms *parms; 17031205Sminshall { 17131210Sminshall if (api_issue(0x09, QUERY_SESSION_PARAMETERS, 0x80, 0x20, 0, 17231500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 17331205Sminshall api_fcn_errno = 0; 17431205Sminshall api_fcn_fcn_id = 0; 17531205Sminshall return -1; 17631205Sminshall } else if (parms->rc == 0) { 17731205Sminshall return 0; 17831205Sminshall } else { 17931205Sminshall api_fcn_errno = parms->rc; 18031205Sminshall api_fcn_fcn_id = parms->function_id; 18131205Sminshall return -1; 18231205Sminshall } 18331205Sminshall } 18431205Sminshall 18531205Sminshall api_query_session_cursor(parms) 18631205Sminshall QuerySessionCursorParms *parms; 18731205Sminshall { 18831210Sminshall if (api_issue(0x09, QUERY_SESSION_CURSOR, 0x80, 0x20, 0xff, 18931500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 19031205Sminshall api_fcn_errno = 0; 19131205Sminshall api_fcn_fcn_id = 0; 19231205Sminshall return -1; 19331205Sminshall } else if (parms->rc == 0) { 19431205Sminshall return 0; 19531205Sminshall } else { 19631205Sminshall api_fcn_errno = parms->rc; 19731205Sminshall api_fcn_fcn_id = parms->function_id; 19831205Sminshall return -1; 19931205Sminshall } 20031205Sminshall } 20131205Sminshall 20231205Sminshall /* 20331205Sminshall * Keyboard Services 20431205Sminshall */ 20531205Sminshall 20631205Sminshall api_connect_to_keyboard(parms) 20731205Sminshall ConnectToKeyboardParms *parms; 20831205Sminshall { 20931205Sminshall if (api_issue(0x09, CONNECT_TO_KEYBOARD, 0x80, 0x20, 0, 21031500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 21131205Sminshall api_fcn_errno = 0; 21231205Sminshall api_fcn_fcn_id = 0; 21331205Sminshall return -1; 21431205Sminshall } else if (parms->rc == 0) { 21531205Sminshall return 0; 21631205Sminshall } else { 21731205Sminshall api_fcn_errno = parms->rc; 21831205Sminshall api_fcn_fcn_id = parms->function_id; 21931205Sminshall return -1; 22031205Sminshall } 22131205Sminshall } 22231205Sminshall 22331205Sminshall 22431205Sminshall api_disconnect_from_keyboard(parms) 22531205Sminshall DisconnectFromKeyboardParms *parms; 22631205Sminshall { 22731205Sminshall if (api_issue(0x09, DISCONNECT_FROM_KEYBOARD, 0x80, 0x20, 0, 22831500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 22931205Sminshall api_fcn_errno = 0; 23031205Sminshall api_fcn_fcn_id = 0; 23131205Sminshall return -1; 23231205Sminshall } else if (parms->rc == 0) { 23331205Sminshall return 0; 23431205Sminshall } else { 23531205Sminshall api_fcn_errno = parms->rc; 23631205Sminshall api_fcn_fcn_id = parms->function_id; 23731205Sminshall return -1; 23831205Sminshall } 23931205Sminshall } 24031205Sminshall 24131205Sminshall 24231205Sminshall api_write_keystroke(parms) 24331205Sminshall WriteKeystrokeParms *parms; 24431205Sminshall { 24531205Sminshall if (api_issue(0x09, WRITE_KEYSTROKE, 0x80, 0x20, 0, 24631500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 24731205Sminshall api_fcn_errno = 0; 24831205Sminshall api_fcn_fcn_id = 0; 24931205Sminshall return -1; 25031205Sminshall } else if (parms->rc == 0) { 25131205Sminshall return 0; 25231205Sminshall } else { 25331205Sminshall api_fcn_errno = parms->rc; 25431205Sminshall api_fcn_fcn_id = parms->function_id; 25531205Sminshall return -1; 25631205Sminshall } 25731205Sminshall } 25831205Sminshall 25931205Sminshall 26031205Sminshall api_disable_input(parms) 26131205Sminshall DisableInputParms *parms; 26231205Sminshall { 26331205Sminshall if (api_issue(0x09, DISABLE_INPUT, 0x80, 0x20, 0, 26431500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 26531205Sminshall api_fcn_errno = 0; 26631205Sminshall api_fcn_fcn_id = 0; 26731205Sminshall return -1; 26831205Sminshall } else if (parms->rc == 0) { 26931205Sminshall return 0; 27031205Sminshall } else { 27131205Sminshall api_fcn_errno = parms->rc; 27231205Sminshall api_fcn_fcn_id = parms->function_id; 27331205Sminshall return -1; 27431205Sminshall } 27531205Sminshall } 27631205Sminshall 27731205Sminshall api_enable_input(parms) 27831205Sminshall EnableInputParms *parms; 27931205Sminshall { 28031205Sminshall if (api_issue(0x09, ENABLE_INPUT, 0x80, 0x20, 0, 28131500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 28231205Sminshall api_fcn_errno = 0; 28331205Sminshall api_fcn_fcn_id = 0; 28431205Sminshall return -1; 28531205Sminshall } else if (parms->rc == 0) { 28631205Sminshall return 0; 28731205Sminshall } else { 28831205Sminshall api_fcn_errno = parms->rc; 28931205Sminshall api_fcn_fcn_id = parms->function_id; 29031205Sminshall return -1; 29131205Sminshall } 29231205Sminshall } 29331205Sminshall 29431205Sminshall /* 29531205Sminshall * Copy Services 29631205Sminshall */ 29731205Sminshall 29831205Sminshall api_copy_string(parms) 29931205Sminshall CopyStringParms *parms; 30031205Sminshall { 30131210Sminshall if (api_issue(0x09, COPY_STRING, 0x80, 0x20, 0xff, 30231500Sminshall gate_copy, (char *)parms, sizeof *parms) == -1) { 30331205Sminshall api_fcn_errno = 0; 30431205Sminshall api_fcn_fcn_id = 0; 30531205Sminshall return -1; 30631205Sminshall } else if (parms->rc == 0) { 30731205Sminshall return 0; 30831205Sminshall } else { 30931205Sminshall api_fcn_errno = parms->rc; 31031205Sminshall api_fcn_fcn_id = parms->function_id; 31131205Sminshall return -1; 31231205Sminshall } 31331205Sminshall } 31431205Sminshall 31531205Sminshall /* 31631205Sminshall * Operator Information Area Services 31731205Sminshall */ 31831205Sminshall 31931205Sminshall api_read_oia_group(parms) 32031205Sminshall ReadOiaGroupParms *parms; 32131205Sminshall { 32231210Sminshall if (api_issue(0x09, READ_OIA_GROUP, 0x80, 0x20, 0xff, 32331500Sminshall gate_oiam, (char *)parms, sizeof *parms) == -1) { 32431205Sminshall api_fcn_errno = 0; 32531205Sminshall api_fcn_fcn_id = 0; 32631205Sminshall return -1; 32731205Sminshall } else if (parms->rc == 0) { 32831205Sminshall return 0; 32931205Sminshall } else { 33031205Sminshall api_fcn_errno = parms->rc; 33131205Sminshall api_fcn_fcn_id = parms->function_id; 33231205Sminshall return -1; 33331205Sminshall } 33431205Sminshall } 33531205Sminshall 33631205Sminshall /* 33731493Sminshall * The "we are done" routine. This gets called last. 33831493Sminshall */ 33931493Sminshall 34031493Sminshall api_finish() 34131493Sminshall { 34231493Sminshall #if defined(unix) 34331493Sminshall if (api_close_api() == -1) { 34431493Sminshall return -1; 34531493Sminshall } else { 34631493Sminshall return 0; 34731493Sminshall } 34831493Sminshall #endif /* defined(unix) */ 34931493Sminshall } 35031493Sminshall 35131493Sminshall 35231493Sminshall /* 35331205Sminshall * The initialization routine. Be sure to call this first. 35431205Sminshall */ 35531205Sminshall 35631205Sminshall api_init() 35731205Sminshall { 35831205Sminshall union REGS regs; 35931205Sminshall struct SREGS sregs; 36031205Sminshall 36131458Sminshall #if defined(MSDOS) 36231205Sminshall regs.h.ah = 0x35; 36331205Sminshall regs.h.al = API_INTERRUPT_NUMBER; 36431205Sminshall intdosx(®s, ®s, &sregs); 36531205Sminshall 36631205Sminshall if ((regs.x.bx == 0) && (sregs.es == 0)) { 36731205Sminshall return 0; /* Interrupt not being handled */ 36831205Sminshall } 36931760Sminshall #endif /* defined(MSDOS) */ 37031458Sminshall #if defined(unix) 37131458Sminshall if (api_open_api(0) == -1) { 37231458Sminshall return 0; 37331458Sminshall } 37431458Sminshall #endif /* defined(unix) */ 37531205Sminshall 37631205Sminshall gate_sessmgr = api_name_resolve("SESSMGR"); 37731205Sminshall gate_keyboard = api_name_resolve("KEYBOARD"); 37831205Sminshall gate_copy = api_name_resolve("COPY"); 37931205Sminshall gate_oiam = api_name_resolve("OIAM"); 38031205Sminshall 38131205Sminshall if ((gate_sessmgr == gate_keyboard) || 38231205Sminshall (gate_sessmgr == gate_copy) || 38331205Sminshall (gate_sessmgr == gate_oiam) || 38431205Sminshall (gate_keyboard == gate_copy) || 38531205Sminshall (gate_keyboard == gate_oiam) || 38631205Sminshall (gate_copy == gate_oiam)) { 38731205Sminshall return 0; /* Interrupt doesn't seem correct */ 38831205Sminshall } 38931205Sminshall return 1; 39031205Sminshall } 391