1 /* 2 * This file implements the API used in the PC version. 3 */ 4 5 #include <stdio.h> 6 7 #include "api.h" 8 #include "../general/general.h" 9 10 #include "../ctlr/screen.h" 11 #include "../general/globals.h" 12 13 int ApiDisableInput = 0; 14 15 /* 16 * Supervisor Services. 17 */ 18 19 static void 20 name_resolve(regs, sregs) 21 union REGS *regs; 22 struct SREGS *sregs; 23 { 24 NameResolveParms parms; 25 26 movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); 27 28 regs->h.cl = 0; 29 if (strcmp((char *)&parms, NAME_SESSMGR) == 0) { 30 regs->x.dx = GATE_SESSMGR; 31 } else if (strcmp((char *)&parms, NAME_KEYBOARD) == 0) { 32 regs->x.dx = GATE_KEYBOARD; 33 } else if (strcmp((char *)&parms, NAME_COPY) == 0) { 34 regs->x.dx = GATE_COPY; 35 } else if (strcmp((char *)&parms, NAME_OIAM) == 0) { 36 regs->x.dx = GATE_OIAM; 37 } else { 38 regs->h.cl = 0x2e; /* Name not found */ 39 } 40 regs->h.ch = 0x12; 41 regs->h.bh = 7; 42 } 43 44 /* 45 * Session Information Services. 46 */ 47 48 static void 49 query_session_id(regs, sregs) 50 union REGS *regs; 51 struct SREGS *sregs; 52 { 53 QuerySessionIdParms parms; 54 55 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 56 57 if (parms.rc != 0) { 58 regs->h.cl = 0x0c; 59 return; 60 } 61 if (parms.option_code != 0x01) { 62 regs->h.cl = 0x0d; /* Invalid option code */ 63 } else if (parms.data_code != 0x45) { 64 regs->h.cl = 0x0b; 65 } else { 66 NameArray list; 67 NameArrayElement element; 68 69 movetous((char *)&list, FP_SEG(parms.name_array), 70 FP_OFFSET(parms.name_array), sizeof list); 71 if ((list.length < 14) || (list.length > 170)) { 72 parms.rc = 0x12; 73 regs->h.cl = 0x12; 74 } else { 75 list.number_matching_session = 1; 76 list.name_array_element.short_name = parms.data_code; 77 list.name_array_element.type = TYPE_DFT; 78 list.name_array_element.session_id = 23; 79 memcpy(list.name_array_element.long_name, "ONLYSESS", 80 sizeof list.name_array_element.long_name); 81 movetothem(FP_SEG(parms.name_array), 82 FP_OFFSET(parms.name_array), (char *)&list, sizeof list); 83 parms.rc = 0; 84 regs->h.cl = 0; 85 } 86 } 87 parms.function_id = 0x6d; 88 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 89 } 90 91 static void 92 query_session_parameters(regs, sregs) 93 union REGS *regs; 94 struct SREGS *sregs; 95 { 96 QuerySessionParametersParms parms; 97 98 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 99 100 if ((parms.rc !=0) || (parms.function_id != 0)) { 101 regs->h.cl = 0x0c; 102 return; 103 } 104 if (parms.session_id != 23) { 105 regs->h.cl = parms.rc = 0x02; 106 } else { 107 regs->h.cl = parms.rc = 0; 108 parms.function_id = 0x6b; 109 parms.session_type = TYPE_DFT; 110 parms.session_characteristics = 0; /* Neither EAB nor PSS */ 111 parms.rows = MaxNumberLines; 112 parms.columns = MaxNumberColumns; 113 parms.presentation_space = 0; 114 } 115 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 116 } 117 118 static void 119 query_session_cursor(regs, sregs) 120 union REGS *regs; 121 struct SREGS *sregs; 122 { 123 QuerySessionCursorParms parms; 124 125 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 126 127 if ((parms.rc != 0) || (parms.function_id != 0)) { 128 parms.rc = 0x0c; 129 } else if (parms.session_id != 23) { 130 parms.rc = 0x02; 131 } else { 132 parms.rc = 0; 133 parms.function_id = 0x6b; 134 parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ 135 parms.row_address = ScreenLine(CursorAddress); 136 parms.column_address = ScreenLineOffset(CursorAddress); 137 } 138 139 movetothem(sregs->es, regs->x.di, sizeof parms); 140 } 141 142 /* 143 * Keyboard Services. 144 */ 145 146 147 static void 148 connect_to_keyboard(regs, sregs) 149 union REGS *regs; 150 struct SREGS *sregs; 151 { 152 ConnectToKeyboardParms parms; 153 154 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 155 156 if ((parms.rc != 0) || (parms.function_id != 0)) { 157 parms.rc = 0x0c; 158 } else if (parms.session_id != 23) { 159 parms.rc = 0x02; 160 } else if (parms.intercept_options != 0) { 161 parms.rc = 0x01; 162 } else { 163 parms.rc = 0; 164 parms.first_connection_identifier = 0; 165 } 166 parms.function_id = 0x62; 167 168 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 169 } 170 171 static void 172 disconnect_from_keyboard(regs, sregs) 173 union REGS *regs; 174 struct SREGS *sregs; 175 { 176 DisconnectFromKeyboardParms parms; 177 178 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 179 180 if ((parms.rc != 0) || (parms.function_id != 0)) { 181 parms.rc = 0x0c; 182 } else if (parms.session_id != 23) { 183 parms.rc = 0x02; 184 } else if (parms.connectors_task_id != 0) { 185 parms.rc = 04; /* XXX */ 186 } else { 187 parms.rc = 0; 188 } 189 parms.function_id = 0x62; 190 191 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 192 } 193 194 static void 195 write_keystroke(regs, sregs) 196 union REGS *regs; 197 struct SREGS *sregs; 198 { 199 /* XXX */ 200 } 201 202 203 static void 204 disable_input(regs, sregs) 205 union REGS *regs; 206 struct SREGS *sregs; 207 { 208 DisableInputParms parms; 209 210 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 211 212 if ((parms.rc != 0) || (parms.function_id != 0)) { 213 parms.rc = 0x0c; 214 } else if (parms.session_id != 23) { 215 parms.rc = 0x02; 216 } else if (parms.connectors_task_id != 0) { 217 parms.rc = 0x04; 218 } else { 219 ApiDisableInput = 1; 220 parms.rc = 0; 221 } 222 parms.function_id = 0x62; 223 224 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 225 } 226 227 static void 228 enable_input(regs, sregs) 229 union REGS *regs; 230 struct SREGS *sregs; 231 { 232 EnableInputParms parms; 233 234 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 235 236 if ((parms.rc != 0) || (parms.function_id != 0)) { 237 parms.rc = 0x0c; 238 } else if (parms.session_id != 23) { 239 parms.rc = 0x02; 240 } else if (parms.connectors_task_id != 0) { 241 parms.rc = 0x04; 242 } else { 243 ApiDisableInput = 0; 244 parms.rc = 0; 245 } 246 parms.function_id = 0x62; 247 248 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 249 } 250 251 /* 252 * Copy Services. 253 */ 254 255 static void 256 copy_string(regs, sregs) 257 union REGS *regs; 258 struct SREGS *sregs; 259 { 260 CopyStringParms parms; 261 BufferDescriptor *target, *source; 262 263 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 264 265 if ((parms.rc != 0) || (parms.function_id !=0)) { 266 parms.rc = 0x0c; 267 } 268 /* XXX do something! */ 269 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 270 } 271 /* 272 * Operator Information Area Services. 273 */ 274 275 static void 276 read_oia_group(regs, sregs) 277 union REGS *regs; 278 struct SREGS *sregs; 279 { 280 ReadOiaGroupParms parms; 281 282 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); 283 284 if ((parms.rc != 0) || (parms.function_id != 0)) { 285 parms.rc = 0x0c; 286 } else if (parms.session_id != 23) { 287 parms.rc = 0x02; 288 } else { 289 int group = parms.oia_group_number; 290 char far *where = parms.oia_buffer; 291 292 switch (group) { 293 case OIA_ALL_GROUPS: 294 case OIA_ONLINE_OWNERSHIP: 295 if (group != OIA_ALL_GROUPS) { 296 break; 297 } /* else, fall through */ 298 case OIA_CHARACTER_SELECTION: 299 if (group != OIA_ALL_GROUPS) { 300 break; 301 } /* else, fall through */ 302 case OIA_SHIFT_STATE: 303 if (group != OIA_ALL_GROUPS) { 304 break; 305 } /* else, fall through */ 306 case OIA_PSS_GROUP_1: 307 if (group != OIA_ALL_GROUPS) { 308 break; 309 } /* else, fall through */ 310 case OIA_HIGHLIGHT_GROUP_1: 311 if (group != OIA_ALL_GROUPS) { 312 break; 313 } /* else, fall through */ 314 case OIA_COLOR_GROUP_1: 315 if (group != OIA_ALL_GROUPS) { 316 break; 317 } /* else, fall through */ 318 case OIA_INSERT: 319 if (group != OIA_ALL_GROUPS) { 320 break; 321 } /* else, fall through */ 322 case OIA_INPUT_INHIBITED: 323 if (group != OIA_ALL_GROUPS) { 324 break; 325 } /* else, fall through */ 326 case OIA_PSS_GROUP_2: 327 if (group != OIA_ALL_GROUPS) { 328 break; 329 } /* else, fall through */ 330 case OIA_HIGHLIGHT_GROUP_2: 331 if (group != OIA_ALL_GROUPS) { 332 break; 333 } /* else, fall through */ 334 case OIA_COLOR_GROUP_2: 335 if (group != OIA_ALL_GROUPS) { 336 break; 337 } /* else, fall through */ 338 case OIA_COMM_ERROR_REMINDER: 339 if (group != OIA_ALL_GROUPS) { 340 break; 341 } /* else, fall through */ 342 case OIA_PRINTER_STATUS: 343 if (group != OIA_ALL_GROUPS) { 344 break; 345 } /* else, fall through */ 346 case OIA_AUTOKEY_PLAY_RECORD_STATUS: 347 if (group != OIA_ALL_GROUPS) { 348 break; 349 } /* else, fall through */ 350 case OIA_AUTOKEY_ABORT_PAUSE_STATUS: 351 if (group != OIA_ALL_GROUPS) { 352 break; 353 } /* else, fall through */ 354 case OIA_ENLARGE_STATE: 355 if (group != OIA_ALL_GROUPS) { 356 break; 357 } /* else, fall through */ 358 359 /* oops, we are done! */ 360 break; 361 default: 362 break; 363 } 364 } 365 parms.function_id = 0x6d; 366 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); 367 } 368 369 static void 370 unknown_op(regs, sregs) 371 union REGS *regs; 372 struct SREGS *sregs; 373 { 374 regs->h.ch = 0x12; 375 regs->h.cl = 0x05; 376 } 377 378 379 handle_api(regs, sregs) 380 union REGS *regs; 381 struct SREGS *sregs; 382 { 383 if (regs->h.ah == NAME_RESOLUTION) { 384 name_resolution(regs, sregs); 385 } else if (regs->h.ah != 0x09) { 386 regs->h.ch = 0x12; 387 regs->h.cl = 0x0f; /* XXX Invalid environmental access */ 388 } else if (regs->x.bx != 0x8020) { 389 regs->h.ch = 0x12; 390 regs->h.cl = 0x08; /* XXX Invalid wait specified */ 391 } else if (regs->h.ch != 0) { 392 regs->h.ch = 0x12; 393 regs->h.cl = 0x07; /* XXX Invalid reply specified */ 394 } else { 395 switch (regs->x.dx) { 396 case GATE_SESSMGR: 397 switch (regs->h.al) { 398 case QUERY_SESSION_ID: 399 if (regs->h.cl != 0) { 400 } else { 401 query_session_id(regs, sregs); 402 } 403 break; 404 case QUERY_SESSION_PARMS: 405 if (regs->h.cl != 0) { 406 } else { 407 query_session_parms(regs, sregs); 408 } 409 break; 410 case QUERY_SESSION_CURSOR: 411 if (regs->h.cl != 0xff) { 412 } else { 413 query_session_cursor(regs, sregs); 414 } 415 break; 416 default: 417 unknown_op(regs, sregs); 418 break; 419 } 420 break; 421 case GATE_KEYBOARD: 422 if (regs->h.cl != 00) { 423 } else { 424 switch (regs->h.al) { 425 case CONNECT_TO_KEYBOARD: 426 connect_to_keyboard(regs, sregs); 427 break; 428 case DISABLE_INPUT: 429 disable_input(regs, sregs); 430 break; 431 case WRITE_KEYSTROKE: 432 write_keystroke(regs, sregs); 433 break; 434 case ENABLE_INPUT: 435 enable_input(regs, sregs); 436 break; 437 case DISCONNECT_FROM_KEYBOARD: 438 disconnect_from_keyboard(regs, sregs); 439 break; 440 default: 441 unknown_op(regs, sregs); 442 break; 443 } 444 } 445 break; 446 case GATE_COPY: 447 if (regs->h.cl != 0xff) { 448 } else { 449 switch (regs->h.al) { 450 case COPY_STRING: 451 copy_string(regs, sregs); 452 break; 453 default: 454 unknown_op(regs, sregs); 455 break; 456 } 457 } 458 break; 459 case GATE_OIAM: 460 if (regs->h.cl != 0xff) { 461 } else { 462 switch (regs->h.al) { 463 case READ_OIA_GROUP: 464 read_oia_group(regs, sregs); 465 break; 466 default: 467 unknown_op(regs, sregs); 468 break; 469 } 470 } 471 break; 472 default: 473 regs->h.ch = 0x12; 474 regs->h.cl = 0x34; /* Invalid GATE entry */ 475 break; 476 } 477 } 478 } 479