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