131890Sminshall /* 233820Sbostic * Copyright (c) 1988 Regents of the University of California. 333820Sbostic * All rights reserved. 431890Sminshall * 533820Sbostic * Redistribution and use in source and binary forms are permitted 6*35418Sminshall * provided that the above copyright notice and this paragraph are 7*35418Sminshall * duplicated in all such forms and that any documentation, 8*35418Sminshall * advertising materials, and other materials related to such 9*35418Sminshall * distribution and use acknowledge that the software was developed 10*35418Sminshall * by the University of California, Berkeley. The name of the 11*35418Sminshall * University may not be used to endorse or promote products derived 12*35418Sminshall * from this software without specific prior written permission. 13*35418Sminshall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*35418Sminshall * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*35418Sminshall * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1631890Sminshall */ 1731890Sminshall 1831890Sminshall #ifndef lint 19*35418Sminshall static char sccsid[] = "@(#)apilib.c 3.3 (Berkeley) 08/28/88"; 2033820Sbostic #endif /* not lint */ 2131890Sminshall 2231869Sminshall #include "../ctlr/api.h" 2331202Sminshall 2431205Sminshall #include "apilib.h" 2531202Sminshall 2631202Sminshall int 2731205Sminshall api_sup_errno = 0, /* Supervisor error number */ 2831205Sminshall api_sup_fcn_id = 0, /* Supervisor function id (0x12) */ 2931205Sminshall api_fcn_errno = 0, /* Function error number */ 3031205Sminshall api_fcn_fcn_id = 0; /* Function ID (0x6b, etc.) */ 3131205Sminshall 3231205Sminshall static int 3331205Sminshall gate_sessmgr = 0, 3431205Sminshall gate_keyboard = 0, 3531205Sminshall gate_copy = 0, 3631205Sminshall gate_oiam = 0; 3731205Sminshall 3831205Sminshall /* 3931205Sminshall * Issue an API request, with reg structures supplied by the caller. 4031205Sminshall * 4131205Sminshall * Only certain routines need this (supervisor services come to mind). 4231205Sminshall */ 4331205Sminshall 4431500Sminshall static int 4531500Sminshall api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, regs, sregs) 4631205Sminshall int ah, al, bh, bl, cx, dx; 4731205Sminshall char *parms; 4831500Sminshall int length; 4931205Sminshall union REGS *regs; 5031205Sminshall struct SREGS *sregs; 5131205Sminshall { 5231205Sminshall char far *ourseg = parms; 5331205Sminshall 5431205Sminshall regs->h.ah = ah; 5531205Sminshall regs->h.al = al; 5631205Sminshall regs->h.bh = bh; 5731205Sminshall regs->h.bl = bl; 5831205Sminshall regs->x.cx = cx; 5931205Sminshall regs->x.dx = dx; 60*35418Sminshall sregs->es = FP_SEG(ourseg); 61*35418Sminshall regs->x.di = FP_OFF(ourseg); 6231205Sminshall 6331458Sminshall #if defined(MSDOS) 6431205Sminshall int86x(API_INTERRUPT_NUMBER, regs, regs, sregs); 6531458Sminshall #endif /* defined(MSDOS) */ 6631458Sminshall #if defined(unix) 6731500Sminshall api_exch_api(regs, sregs, parms, length); 6831458Sminshall #endif /* defined(unix) */ 6931458Sminshall 7031205Sminshall if (regs->h.cl != 0) { 7131205Sminshall api_sup_errno = regs->h.cl; 7231205Sminshall return -1; 7331205Sminshall } else { 7431205Sminshall return 0; 7531205Sminshall } 7631205Sminshall } 7731205Sminshall 7831205Sminshall 7931205Sminshall /* 8031205Sminshall * Issue an API request without requiring caller to supply 8131205Sminshall * registers. Most routines use this. 8231205Sminshall */ 8331205Sminshall 8431500Sminshall static int 8531500Sminshall api_issue(ah, al, bh, bl, cx, dx, parms, length) 8631205Sminshall int 8731202Sminshall ah, 8831202Sminshall al, 8931202Sminshall bh, 9031202Sminshall bl, 9131202Sminshall cx, 9231202Sminshall dx; 9331202Sminshall char *parms; 9431500Sminshall int length; /* Length of parms */ 9531202Sminshall { 9631202Sminshall union REGS regs; 9731202Sminshall struct SREGS sregs; 9831202Sminshall 9931500Sminshall return api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, ®s, &sregs); 10031202Sminshall } 10131205Sminshall 10231205Sminshall /* 10331205Sminshall * Supervisor Services 10431205Sminshall */ 10531202Sminshall 10631202Sminshall int 10731202Sminshall api_name_resolve(name) 10831202Sminshall char *name; 10931202Sminshall { 11031202Sminshall NameResolveParms parms; 11131202Sminshall int i; 11231202Sminshall union REGS regs; 11331202Sminshall struct SREGS sregs; 11431202Sminshall 11531202Sminshall for (i = 0; i < sizeof parms.gate_name; i++) { 11631202Sminshall if (*name) { 11731202Sminshall parms.gate_name[i] = *name++; 11831202Sminshall } else { 11931202Sminshall parms.gate_name[i] = ' '; 12031202Sminshall } 12131202Sminshall } 12231202Sminshall 123*35418Sminshall if (api_issue_regs(NAME_RESOLUTION, 0, 0, 0, 0, 0, (char *) &parms, 124*35418Sminshall sizeof parms, ®s, &sregs) == -1) { 12531205Sminshall return -1; 12631205Sminshall } else { 12731205Sminshall return regs.x.dx; 12831202Sminshall } 12931205Sminshall } 13031513Sminshall 13131513Sminshall #if defined(unix) 13231513Sminshall /* 13331513Sminshall * Block until the oia or ps is modified. 13431513Sminshall */ 13531513Sminshall 13631513Sminshall int 13731513Sminshall api_ps_or_oia_modified() 13831513Sminshall { 13931513Sminshall union REGS regs; 14031513Sminshall struct SREGS sregs; 14131513Sminshall 142*35418Sminshall if (api_issue_regs(PS_OR_OIA_MODIFIED, 0, 0, 0, 0, 0, (char *) 0, 143*35418Sminshall 0, ®s, &sregs) == -1) { 14431513Sminshall return -1; 14531513Sminshall } else { 14631513Sminshall return 0; 14731513Sminshall } 14831513Sminshall } 14931513Sminshall #endif /* defined(unix) */ 15031205Sminshall 15131205Sminshall /* 15231205Sminshall * Session Information Services 15331205Sminshall */ 15431202Sminshall 15531210Sminshall api_query_session_id(parms) 15631205Sminshall QuerySessionIdParms *parms; 15731205Sminshall { 15831205Sminshall if (api_issue(0x09, QUERY_SESSION_ID, 0x80, 0x20, 0, 15931500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 16031205Sminshall api_fcn_errno = 0; 16131205Sminshall api_fcn_fcn_id = 0; 16231202Sminshall return -1; 16331205Sminshall } else if (parms->rc == 0) { 16431205Sminshall return 0; 16531202Sminshall } else { 16631205Sminshall api_fcn_errno = parms->rc; 16731205Sminshall api_fcn_fcn_id = parms->function_id; 16831205Sminshall return -1; 16931202Sminshall } 17031202Sminshall } 17131205Sminshall 17231205Sminshall 17331210Sminshall api_query_session_parameters(parms) 17431205Sminshall QuerySessionParametersParms *parms; 17531205Sminshall { 17631210Sminshall if (api_issue(0x09, QUERY_SESSION_PARAMETERS, 0x80, 0x20, 0, 17731500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 17831205Sminshall api_fcn_errno = 0; 17931205Sminshall api_fcn_fcn_id = 0; 18031205Sminshall return -1; 18131205Sminshall } else if (parms->rc == 0) { 18231205Sminshall return 0; 18331205Sminshall } else { 18431205Sminshall api_fcn_errno = parms->rc; 18531205Sminshall api_fcn_fcn_id = parms->function_id; 18631205Sminshall return -1; 18731205Sminshall } 18831205Sminshall } 18931205Sminshall 19031205Sminshall api_query_session_cursor(parms) 19131205Sminshall QuerySessionCursorParms *parms; 19231205Sminshall { 19331210Sminshall if (api_issue(0x09, QUERY_SESSION_CURSOR, 0x80, 0x20, 0xff, 19431500Sminshall gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 19531205Sminshall api_fcn_errno = 0; 19631205Sminshall api_fcn_fcn_id = 0; 19731205Sminshall return -1; 19831205Sminshall } else if (parms->rc == 0) { 19931205Sminshall return 0; 20031205Sminshall } else { 20131205Sminshall api_fcn_errno = parms->rc; 20231205Sminshall api_fcn_fcn_id = parms->function_id; 20331205Sminshall return -1; 20431205Sminshall } 20531205Sminshall } 20631205Sminshall 20731205Sminshall /* 20831205Sminshall * Keyboard Services 20931205Sminshall */ 21031205Sminshall 21131205Sminshall api_connect_to_keyboard(parms) 21231205Sminshall ConnectToKeyboardParms *parms; 21331205Sminshall { 21431205Sminshall if (api_issue(0x09, CONNECT_TO_KEYBOARD, 0x80, 0x20, 0, 21531500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 21631205Sminshall api_fcn_errno = 0; 21731205Sminshall api_fcn_fcn_id = 0; 21831205Sminshall return -1; 21931205Sminshall } else if (parms->rc == 0) { 22031205Sminshall return 0; 22131205Sminshall } else { 22231205Sminshall api_fcn_errno = parms->rc; 22331205Sminshall api_fcn_fcn_id = parms->function_id; 22431205Sminshall return -1; 22531205Sminshall } 22631205Sminshall } 22731205Sminshall 22831205Sminshall 22931205Sminshall api_disconnect_from_keyboard(parms) 23031205Sminshall DisconnectFromKeyboardParms *parms; 23131205Sminshall { 23231205Sminshall if (api_issue(0x09, DISCONNECT_FROM_KEYBOARD, 0x80, 0x20, 0, 23331500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 23431205Sminshall api_fcn_errno = 0; 23531205Sminshall api_fcn_fcn_id = 0; 23631205Sminshall return -1; 23731205Sminshall } else if (parms->rc == 0) { 23831205Sminshall return 0; 23931205Sminshall } else { 24031205Sminshall api_fcn_errno = parms->rc; 24131205Sminshall api_fcn_fcn_id = parms->function_id; 24231205Sminshall return -1; 24331205Sminshall } 24431205Sminshall } 24531205Sminshall 24631205Sminshall 24731205Sminshall api_write_keystroke(parms) 24831205Sminshall WriteKeystrokeParms *parms; 24931205Sminshall { 25031205Sminshall if (api_issue(0x09, WRITE_KEYSTROKE, 0x80, 0x20, 0, 25131500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 25231205Sminshall api_fcn_errno = 0; 25331205Sminshall api_fcn_fcn_id = 0; 25431205Sminshall return -1; 25531205Sminshall } else if (parms->rc == 0) { 25631205Sminshall return 0; 25731205Sminshall } else { 25831205Sminshall api_fcn_errno = parms->rc; 25931205Sminshall api_fcn_fcn_id = parms->function_id; 26031205Sminshall return -1; 26131205Sminshall } 26231205Sminshall } 26331205Sminshall 26431205Sminshall 26531205Sminshall api_disable_input(parms) 26631205Sminshall DisableInputParms *parms; 26731205Sminshall { 26831205Sminshall if (api_issue(0x09, DISABLE_INPUT, 0x80, 0x20, 0, 26931500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 27031205Sminshall api_fcn_errno = 0; 27131205Sminshall api_fcn_fcn_id = 0; 27231205Sminshall return -1; 27331205Sminshall } else if (parms->rc == 0) { 27431205Sminshall return 0; 27531205Sminshall } else { 27631205Sminshall api_fcn_errno = parms->rc; 27731205Sminshall api_fcn_fcn_id = parms->function_id; 27831205Sminshall return -1; 27931205Sminshall } 28031205Sminshall } 28131205Sminshall 28231205Sminshall api_enable_input(parms) 28331205Sminshall EnableInputParms *parms; 28431205Sminshall { 28531205Sminshall if (api_issue(0x09, ENABLE_INPUT, 0x80, 0x20, 0, 28631500Sminshall gate_keyboard, (char *)parms, sizeof *parms) == -1) { 28731205Sminshall api_fcn_errno = 0; 28831205Sminshall api_fcn_fcn_id = 0; 28931205Sminshall return -1; 29031205Sminshall } else if (parms->rc == 0) { 29131205Sminshall return 0; 29231205Sminshall } else { 29331205Sminshall api_fcn_errno = parms->rc; 29431205Sminshall api_fcn_fcn_id = parms->function_id; 29531205Sminshall return -1; 29631205Sminshall } 29731205Sminshall } 29831205Sminshall 29931205Sminshall /* 30031205Sminshall * Copy Services 30131205Sminshall */ 30231205Sminshall 30331205Sminshall api_copy_string(parms) 30431205Sminshall CopyStringParms *parms; 30531205Sminshall { 30631210Sminshall if (api_issue(0x09, COPY_STRING, 0x80, 0x20, 0xff, 30731500Sminshall gate_copy, (char *)parms, sizeof *parms) == -1) { 30831205Sminshall api_fcn_errno = 0; 30931205Sminshall api_fcn_fcn_id = 0; 31031205Sminshall return -1; 31131205Sminshall } else if (parms->rc == 0) { 31231205Sminshall return 0; 31331205Sminshall } else { 31431205Sminshall api_fcn_errno = parms->rc; 31531205Sminshall api_fcn_fcn_id = parms->function_id; 31631205Sminshall return -1; 31731205Sminshall } 31831205Sminshall } 31931205Sminshall 32031205Sminshall /* 32131205Sminshall * Operator Information Area Services 32231205Sminshall */ 32331205Sminshall 32431205Sminshall api_read_oia_group(parms) 32531205Sminshall ReadOiaGroupParms *parms; 32631205Sminshall { 32731210Sminshall if (api_issue(0x09, READ_OIA_GROUP, 0x80, 0x20, 0xff, 32831500Sminshall gate_oiam, (char *)parms, sizeof *parms) == -1) { 32931205Sminshall api_fcn_errno = 0; 33031205Sminshall api_fcn_fcn_id = 0; 33131205Sminshall return -1; 33231205Sminshall } else if (parms->rc == 0) { 33331205Sminshall return 0; 33431205Sminshall } else { 33531205Sminshall api_fcn_errno = parms->rc; 33631205Sminshall api_fcn_fcn_id = parms->function_id; 33731205Sminshall return -1; 33831205Sminshall } 33931205Sminshall } 34031205Sminshall 34131205Sminshall /* 34231493Sminshall * The "we are done" routine. This gets called last. 34331493Sminshall */ 34431493Sminshall 34531493Sminshall api_finish() 34631493Sminshall { 34731493Sminshall #if defined(unix) 34831493Sminshall if (api_close_api() == -1) { 34931493Sminshall return -1; 35031493Sminshall } else { 35131493Sminshall return 0; 35231493Sminshall } 35331493Sminshall #endif /* defined(unix) */ 35431493Sminshall } 35531493Sminshall 35631493Sminshall 35731493Sminshall /* 35831205Sminshall * The initialization routine. Be sure to call this first. 35931205Sminshall */ 36031205Sminshall 36131205Sminshall api_init() 36231205Sminshall { 363*35418Sminshall #if defined(MSDOS) 36431205Sminshall union REGS regs; 36531205Sminshall struct SREGS sregs; 36631205Sminshall 36731205Sminshall regs.h.ah = 0x35; 36831205Sminshall regs.h.al = API_INTERRUPT_NUMBER; 36931205Sminshall intdosx(®s, ®s, &sregs); 37031205Sminshall 37131205Sminshall if ((regs.x.bx == 0) && (sregs.es == 0)) { 37231205Sminshall return 0; /* Interrupt not being handled */ 37331205Sminshall } 37431760Sminshall #endif /* defined(MSDOS) */ 37531458Sminshall #if defined(unix) 376*35418Sminshall if (api_open_api((char *)0) == -1) { 37731458Sminshall return 0; 37831458Sminshall } 37931458Sminshall #endif /* defined(unix) */ 38031205Sminshall 38131205Sminshall gate_sessmgr = api_name_resolve("SESSMGR"); 38231205Sminshall gate_keyboard = api_name_resolve("KEYBOARD"); 38331205Sminshall gate_copy = api_name_resolve("COPY"); 38431205Sminshall gate_oiam = api_name_resolve("OIAM"); 38531205Sminshall 38631205Sminshall if ((gate_sessmgr == gate_keyboard) || 38731205Sminshall (gate_sessmgr == gate_copy) || 38831205Sminshall (gate_sessmgr == gate_oiam) || 38931205Sminshall (gate_keyboard == gate_copy) || 39031205Sminshall (gate_keyboard == gate_oiam) || 39131205Sminshall (gate_copy == gate_oiam)) { 39231205Sminshall return 0; /* Interrupt doesn't seem correct */ 39331205Sminshall } 39431205Sminshall return 1; 39531205Sminshall } 396