1 /* 2 * Copyright (c) 1984-1987 by the Regents of the 3 * University of California and by Gregory Glenn Minshall. 4 * 5 * Permission to use, copy, modify, and distribute these 6 * programs and their documentation for any purpose and 7 * without fee is hereby granted, provided that this 8 * copyright and permission appear on all copies and 9 * supporting documentation, the name of the Regents of 10 * the University of California not be used in advertising 11 * or publicity pertaining to distribution of the programs 12 * without specific prior permission, and notice be given in 13 * supporting documentation that copying and distribution is 14 * by permission of the Regents of the University of California 15 * and by Gregory Glenn Minshall. Neither the Regents of the 16 * University of California nor Gregory Glenn Minshall make 17 * representations about the suitability of this software 18 * for any purpose. It is provided "as is" without 19 * express or implied warranty. 20 */ 21 22 #ifndef lint 23 static char sccsid[] = "@(#)apilib.c 1.10 (Berkeley) 07/17/87"; 24 #endif /* not lint */ 25 26 #include "../ctlr/api.h" 27 28 #include "apilib.h" 29 30 int 31 api_sup_errno = 0, /* Supervisor error number */ 32 api_sup_fcn_id = 0, /* Supervisor function id (0x12) */ 33 api_fcn_errno = 0, /* Function error number */ 34 api_fcn_fcn_id = 0; /* Function ID (0x6b, etc.) */ 35 36 static int 37 gate_sessmgr = 0, 38 gate_keyboard = 0, 39 gate_copy = 0, 40 gate_oiam = 0; 41 42 /* 43 * Issue an API request, with reg structures supplied by the caller. 44 * 45 * Only certain routines need this (supervisor services come to mind). 46 */ 47 48 static int 49 api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, regs, sregs) 50 int ah, al, bh, bl, cx, dx; 51 char *parms; 52 int length; 53 union REGS *regs; 54 struct SREGS *sregs; 55 { 56 char far *ourseg = parms; 57 58 regs->h.ah = ah; 59 regs->h.al = al; 60 regs->h.bh = bh; 61 regs->h.bl = bl; 62 regs->x.cx = cx; 63 regs->x.dx = dx; 64 sregs->es = (int) FP_SEG(ourseg); 65 regs->x.di = (int) FP_OFF(ourseg); 66 67 #if defined(MSDOS) 68 int86x(API_INTERRUPT_NUMBER, regs, regs, sregs); 69 #endif /* defined(MSDOS) */ 70 #if defined(unix) 71 api_exch_api(regs, sregs, parms, length); 72 #endif /* defined(unix) */ 73 74 if (regs->h.cl != 0) { 75 api_sup_errno = regs->h.cl; 76 return -1; 77 } else { 78 return 0; 79 } 80 } 81 82 83 /* 84 * Issue an API request without requiring caller to supply 85 * registers. Most routines use this. 86 */ 87 88 static int 89 api_issue(ah, al, bh, bl, cx, dx, parms, length) 90 int 91 ah, 92 al, 93 bh, 94 bl, 95 cx, 96 dx; 97 char *parms; 98 int length; /* Length of parms */ 99 { 100 union REGS regs; 101 struct SREGS sregs; 102 103 return api_issue_regs(ah, al, bh, bl, cx, dx, parms, length, ®s, &sregs); 104 } 105 106 /* 107 * Supervisor Services 108 */ 109 110 int 111 api_name_resolve(name) 112 char *name; 113 { 114 NameResolveParms parms; 115 int i; 116 union REGS regs; 117 struct SREGS sregs; 118 119 for (i = 0; i < sizeof parms.gate_name; i++) { 120 if (*name) { 121 parms.gate_name[i] = *name++; 122 } else { 123 parms.gate_name[i] = ' '; 124 } 125 } 126 127 if (api_issue_regs(NAME_RESOLUTION, 0, 0, 0, 0, 0, &parms, sizeof parms, ®s, &sregs) 128 == -1) { 129 return -1; 130 } else { 131 return regs.x.dx; 132 } 133 } 134 135 #if defined(unix) 136 /* 137 * Block until the oia or ps is modified. 138 */ 139 140 int 141 api_ps_or_oia_modified() 142 { 143 union REGS regs; 144 struct SREGS sregs; 145 146 if (api_issue_regs(PS_OR_OIA_MODIFIED, 0, 0, 0, 0, 0, 0, 0, ®s, &sregs) 147 == -1) { 148 return -1; 149 } else { 150 return 0; 151 } 152 } 153 #endif /* defined(unix) */ 154 155 /* 156 * Session Information Services 157 */ 158 159 api_query_session_id(parms) 160 QuerySessionIdParms *parms; 161 { 162 if (api_issue(0x09, QUERY_SESSION_ID, 0x80, 0x20, 0, 163 gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 164 api_fcn_errno = 0; 165 api_fcn_fcn_id = 0; 166 return -1; 167 } else if (parms->rc == 0) { 168 return 0; 169 } else { 170 api_fcn_errno = parms->rc; 171 api_fcn_fcn_id = parms->function_id; 172 return -1; 173 } 174 } 175 176 177 api_query_session_parameters(parms) 178 QuerySessionParametersParms *parms; 179 { 180 if (api_issue(0x09, QUERY_SESSION_PARAMETERS, 0x80, 0x20, 0, 181 gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 182 api_fcn_errno = 0; 183 api_fcn_fcn_id = 0; 184 return -1; 185 } else if (parms->rc == 0) { 186 return 0; 187 } else { 188 api_fcn_errno = parms->rc; 189 api_fcn_fcn_id = parms->function_id; 190 return -1; 191 } 192 } 193 194 api_query_session_cursor(parms) 195 QuerySessionCursorParms *parms; 196 { 197 if (api_issue(0x09, QUERY_SESSION_CURSOR, 0x80, 0x20, 0xff, 198 gate_sessmgr, (char *)parms, sizeof *parms) == -1) { 199 api_fcn_errno = 0; 200 api_fcn_fcn_id = 0; 201 return -1; 202 } else if (parms->rc == 0) { 203 return 0; 204 } else { 205 api_fcn_errno = parms->rc; 206 api_fcn_fcn_id = parms->function_id; 207 return -1; 208 } 209 } 210 211 /* 212 * Keyboard Services 213 */ 214 215 api_connect_to_keyboard(parms) 216 ConnectToKeyboardParms *parms; 217 { 218 if (api_issue(0x09, CONNECT_TO_KEYBOARD, 0x80, 0x20, 0, 219 gate_keyboard, (char *)parms, sizeof *parms) == -1) { 220 api_fcn_errno = 0; 221 api_fcn_fcn_id = 0; 222 return -1; 223 } else if (parms->rc == 0) { 224 return 0; 225 } else { 226 api_fcn_errno = parms->rc; 227 api_fcn_fcn_id = parms->function_id; 228 return -1; 229 } 230 } 231 232 233 api_disconnect_from_keyboard(parms) 234 DisconnectFromKeyboardParms *parms; 235 { 236 if (api_issue(0x09, DISCONNECT_FROM_KEYBOARD, 0x80, 0x20, 0, 237 gate_keyboard, (char *)parms, sizeof *parms) == -1) { 238 api_fcn_errno = 0; 239 api_fcn_fcn_id = 0; 240 return -1; 241 } else if (parms->rc == 0) { 242 return 0; 243 } else { 244 api_fcn_errno = parms->rc; 245 api_fcn_fcn_id = parms->function_id; 246 return -1; 247 } 248 } 249 250 251 api_write_keystroke(parms) 252 WriteKeystrokeParms *parms; 253 { 254 if (api_issue(0x09, WRITE_KEYSTROKE, 0x80, 0x20, 0, 255 gate_keyboard, (char *)parms, sizeof *parms) == -1) { 256 api_fcn_errno = 0; 257 api_fcn_fcn_id = 0; 258 return -1; 259 } else if (parms->rc == 0) { 260 return 0; 261 } else { 262 api_fcn_errno = parms->rc; 263 api_fcn_fcn_id = parms->function_id; 264 return -1; 265 } 266 } 267 268 269 api_disable_input(parms) 270 DisableInputParms *parms; 271 { 272 if (api_issue(0x09, DISABLE_INPUT, 0x80, 0x20, 0, 273 gate_keyboard, (char *)parms, sizeof *parms) == -1) { 274 api_fcn_errno = 0; 275 api_fcn_fcn_id = 0; 276 return -1; 277 } else if (parms->rc == 0) { 278 return 0; 279 } else { 280 api_fcn_errno = parms->rc; 281 api_fcn_fcn_id = parms->function_id; 282 return -1; 283 } 284 } 285 286 api_enable_input(parms) 287 EnableInputParms *parms; 288 { 289 if (api_issue(0x09, ENABLE_INPUT, 0x80, 0x20, 0, 290 gate_keyboard, (char *)parms, sizeof *parms) == -1) { 291 api_fcn_errno = 0; 292 api_fcn_fcn_id = 0; 293 return -1; 294 } else if (parms->rc == 0) { 295 return 0; 296 } else { 297 api_fcn_errno = parms->rc; 298 api_fcn_fcn_id = parms->function_id; 299 return -1; 300 } 301 } 302 303 /* 304 * Copy Services 305 */ 306 307 api_copy_string(parms) 308 CopyStringParms *parms; 309 { 310 if (api_issue(0x09, COPY_STRING, 0x80, 0x20, 0xff, 311 gate_copy, (char *)parms, sizeof *parms) == -1) { 312 api_fcn_errno = 0; 313 api_fcn_fcn_id = 0; 314 return -1; 315 } else if (parms->rc == 0) { 316 return 0; 317 } else { 318 api_fcn_errno = parms->rc; 319 api_fcn_fcn_id = parms->function_id; 320 return -1; 321 } 322 } 323 324 /* 325 * Operator Information Area Services 326 */ 327 328 api_read_oia_group(parms) 329 ReadOiaGroupParms *parms; 330 { 331 if (api_issue(0x09, READ_OIA_GROUP, 0x80, 0x20, 0xff, 332 gate_oiam, (char *)parms, sizeof *parms) == -1) { 333 api_fcn_errno = 0; 334 api_fcn_fcn_id = 0; 335 return -1; 336 } else if (parms->rc == 0) { 337 return 0; 338 } else { 339 api_fcn_errno = parms->rc; 340 api_fcn_fcn_id = parms->function_id; 341 return -1; 342 } 343 } 344 345 /* 346 * The "we are done" routine. This gets called last. 347 */ 348 349 api_finish() 350 { 351 #if defined(unix) 352 if (api_close_api() == -1) { 353 return -1; 354 } else { 355 return 0; 356 } 357 #endif /* defined(unix) */ 358 } 359 360 361 /* 362 * The initialization routine. Be sure to call this first. 363 */ 364 365 api_init() 366 { 367 union REGS regs; 368 struct SREGS sregs; 369 370 #if defined(MSDOS) 371 regs.h.ah = 0x35; 372 regs.h.al = API_INTERRUPT_NUMBER; 373 intdosx(®s, ®s, &sregs); 374 375 if ((regs.x.bx == 0) && (sregs.es == 0)) { 376 return 0; /* Interrupt not being handled */ 377 } 378 #endif /* defined(MSDOS) */ 379 #if defined(unix) 380 if (api_open_api(0) == -1) { 381 return 0; 382 } 383 #endif /* defined(unix) */ 384 385 gate_sessmgr = api_name_resolve("SESSMGR"); 386 gate_keyboard = api_name_resolve("KEYBOARD"); 387 gate_copy = api_name_resolve("COPY"); 388 gate_oiam = api_name_resolve("OIAM"); 389 390 if ((gate_sessmgr == gate_keyboard) || 391 (gate_sessmgr == gate_copy) || 392 (gate_sessmgr == gate_oiam) || 393 (gate_keyboard == gate_copy) || 394 (gate_keyboard == gate_oiam) || 395 (gate_copy == gate_oiam)) { 396 return 0; /* Interrupt doesn't seem correct */ 397 } 398 return 1; 399 } 400