"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "tn3270-5.2.0-glibc/tn3270/ctlr/api.c" of archive tn3270-5.2.0-glibc.tgz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18 #ifndef lint
19 static char sccsid[] = "@(#)api.c 4.1 (Berkeley) 12/4/88";
20 #endif /* not lint */
21
22 /*
23 * This file implements the API used in the PC version.
24 */
25
26 #include <stdio.h>
27
28 #include "api.h"
29 #include "../general/general.h"
30
31 #include "../api/disp_asc.h"
32
33 #include "screen.h"
34 #include "oia.h"
35
36 #include "../general/globals.h"
37
38 /*
39 * General utility routines.
40 */
41
42 #if defined(MSDOS)
43
44 #if defined(LINT_ARGS)
45 static void movetous(char *, int, int, int);
46 static void movetothem(int, int, char *, int);
47 #endif /* defined(LINT_ARGS) */
48
49 #define access_api(foo,length,copyin) (foo)
50 #define unaccess_api(foo,goo,length,copyout)
51
52 static void
53 movetous(parms, es, di, length)
54 char *parms;
55 int es, di;
56 int length;
57 {
58 char far *farparms = parms;
59
60 movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length);
61 }
62
63 static void
64 movetothem(es, di, parms, length)
65 int es, di;
66 char *parms;
67 int length;
68 {
69 char far *farparms = parms;
70
71 movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length);
72 }
73 #endif /* defined(MSDOS) */
74
75 #if defined(unix)
76 extern char *access_api();
77 extern void movetous(), movetothem(), unaccess_api();
78 #endif /* defined(unix) */
79
80
81 /*
82 * Supervisor Services.
83 */
84
85 static void
86 name_resolution(regs, sregs)
87 union REGS *regs;
88 struct SREGS *sregs;
89 {
90 NameResolveParms parms;
91
92 movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
93
94 regs->h.cl = 0;
95 if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) {
96 regs->x.dx = GATE_SESSMGR;
97 } else if (memcmp((char *)&parms, NAME_KEYBOARD,
98 sizeof parms.gate_name) == 0) {
99 regs->x.dx = GATE_KEYBOARD;
100 } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) {
101 regs->x.dx = GATE_COPY;
102 } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) {
103 regs->x.dx = GATE_OIAM;
104 } else {
105 regs->h.cl = 0x2e; /* Name not found */
106 }
107 regs->h.ch = 0x12;
108 regs->h.bh = 7;
109 }
110
111 /*
112 * Session Information Services.
113 */
114
115 static void
116 query_session_id(regs, sregs)
117 union REGS *regs;
118 struct SREGS *sregs;
119 {
120 QuerySessionIdParms parms;
121
122 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
123
124 if ((parms.rc != 0) || (parms.function_id != 0)) {
125 parms.rc = 0x0c;
126 } else if (parms.option_code != 0x01) {
127 parms.rc = 0x0d; /* Invalid option code */
128 } else if (parms.data_code != 0x45) {
129 parms.rc = 0x0b;
130 } else {
131 NameArray list;
132
133 movetous((char *)&list, FP_SEG(parms.name_array),
134 FP_OFF(parms.name_array), sizeof list);
135 if ((list.length < 14) || (list.length > 170)) {
136 parms.rc = 0x12;
137 } else {
138 list.number_matching_session = 1;
139 list.name_array_element.short_name = parms.data_code;
140 list.name_array_element.type = TYPE_DFT;
141 list.name_array_element.session_id = 23;
142 memcpy(list.name_array_element.long_name, "ONLYSESS",
143 sizeof list.name_array_element.long_name);
144 movetothem(FP_SEG(parms.name_array),
145 FP_OFF(parms.name_array), (char *)&list, sizeof list);
146 parms.rc = 0;
147 }
148 }
149 parms.function_id = 0x6b;
150 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
151 }
152
153 static void
154 query_session_parameters(regs, sregs)
155 union REGS *regs;
156 struct SREGS *sregs;
157 {
158 QuerySessionParametersParms parms;
159
160 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
161
162 if ((parms.rc !=0) || (parms.function_id != 0)) {
163 parms.rc = 0x0c;
164 } else if (parms.session_id != 23) {
165 parms.rc = 0x02;
166 } else {
167 parms.rc = 0;
168 parms.session_type = TYPE_DFT;
169 parms.session_characteristics = 0; /* Neither EAB nor PSS */
170 parms.rows = MaxNumberLines;
171 parms.columns = MaxNumberColumns;
172 parms.presentation_space = 0;
173 }
174 parms.function_id = 0x6b;
175 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
176 }
177
178 static void
179 query_session_cursor(regs, sregs)
180 union REGS *regs;
181 struct SREGS *sregs;
182 {
183 QuerySessionCursorParms parms;
184
185 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
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 {
192 parms.rc = 0;
193 parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */
194 parms.row_address = ScreenLine(CursorAddress);
195 parms.column_address = ScreenLineOffset(CursorAddress);
196 }
197
198 parms.function_id = 0x6b;
199 movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms);
200 }
201
202 /*
203 * Keyboard Services.
204 */
205
206
207 static void
208 connect_to_keyboard(regs, sregs)
209 union REGS *regs;
210 struct SREGS *sregs;
211 {
212 ConnectToKeyboardParms parms;
213
214 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
215
216 if ((parms.rc != 0) || (parms.function_id != 0)) {
217 parms.rc = 0x0c;
218 } else if (parms.session_id != 23) {
219 parms.rc = 0x02;
220 } else if (parms.intercept_options != 0) {
221 parms.rc = 0x01;
222 } else {
223 parms.rc = 0;
224 parms.first_connection_identifier = 0;
225 }
226 parms.function_id = 0x62;
227
228 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
229 }
230
231 static void
232 disconnect_from_keyboard(regs, sregs)
233 union REGS *regs;
234 struct SREGS *sregs;
235 {
236 DisconnectFromKeyboardParms parms;
237
238 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
239
240 if ((parms.rc != 0) || (parms.function_id != 0)) {
241 parms.rc = 0x0c;
242 } else if (parms.session_id != 23) {
243 parms.rc = 0x02;
244 } else if (parms.connectors_task_id != 0) {
245 parms.rc = 04; /* XXX */
246 } else {
247 parms.rc = 0;
248 }
249 parms.function_id = 0x62;
250
251 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
252 }
253
254 static void
255 write_keystroke(regs, sregs)
256 union REGS *regs;
257 struct SREGS *sregs;
258 {
259 WriteKeystrokeParms parms;
260
261 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
262
263 if ((parms.rc != 0) || (parms.function_id != 0)) {
264 parms.rc = 0x0c;
265 } else if (parms.session_id != 23) {
266 parms.rc = 0x02;
267 } else if (parms.connectors_task_id != 0) {
268 parms.rc = 0x04;
269 } else {
270 parms.number_of_keys_sent = 0;
271 parms.rc = 0;
272 if (parms.options == OPTION_SINGLE_KEYSTROKE) {
273 KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry;
274
275 if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) {
276 parms.rc = 0x10; /* XXX needs 0x12 too! */
277 }
278 parms.number_of_keys_sent++;
279 } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) {
280 KeystrokeList
281 list,
282 far *atlist = parms.keystroke_specifier.keystroke_list;
283 KeystrokeEntry
284 entry[10], /* 10 at a time */
285 *ourentry,
286 far *theirentry;
287 int
288 todo;
289
290 movetous((char *)&list, FP_SEG(atlist),
291 FP_OFF(atlist), sizeof *atlist);
292 todo = list.length/2;
293 ourentry = entry+(highestof(entry)+1);
294 theirentry = &atlist->keystrokes;
295
296 while (todo) {
297 if (ourentry > &entry[highestof(entry)]) {
298 int thistime;
299
300 thistime = todo;
301 if (thistime > numberof(entry)) {
302 thistime = numberof(entry);
303 }
304 movetous((char *)entry, FP_SEG(theirentry),
305 FP_OFF(theirentry), thistime*sizeof *theirentry);
306 theirentry += thistime;
307 ourentry = entry;
308 }
309 if (AcceptKeystroke(ourentry->scancode,
310 ourentry->shift_state) == 0) {
311 parms.rc = 0x10; /* XXX needs 0x12 too! */
312 break;
313 }
314 parms.number_of_keys_sent++;
315 ourentry++;
316 todo--;
317 }
318 } else {
319 parms.rc = 0x01;
320 }
321 }
322 parms.function_id = 0x62;
323
324 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
325 /* XXX */
326 }
327
328
329 static void
330 disable_input(regs, sregs)
331 union REGS *regs;
332 struct SREGS *sregs;
333 {
334 DisableInputParms parms;
335
336 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
337
338 if ((parms.rc != 0) || (parms.function_id != 0)) {
339 parms.rc = 0x0c;
340 } else if (parms.session_id != 23) {
341 parms.rc = 0x02;
342 } else if (parms.connectors_task_id != 0) {
343 parms.rc = 0x04;
344 } else {
345 SetOiaApiInhibit(&OperatorInformationArea);
346 parms.rc = 0;
347 }
348 parms.function_id = 0x62;
349
350 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
351 }
352
353 static void
354 enable_input(regs, sregs)
355 union REGS *regs;
356 struct SREGS *sregs;
357 {
358 EnableInputParms parms;
359
360 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
361
362 if ((parms.rc != 0) || (parms.function_id != 0)) {
363 parms.rc = 0x0c;
364 } else if (parms.session_id != 23) {
365 parms.rc = 0x02;
366 } else if (parms.connectors_task_id != 0) {
367 parms.rc = 0x04;
368 } else {
369 ResetOiaApiInhibit(&OperatorInformationArea);
370 parms.rc = 0;
371 }
372 parms.function_id = 0x62;
373
374 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
375 }
376
377 /*
378 * Copy Services.
379 */
380
381 static
382 copy_subroutine(target, source, parms, what_is_user, length)
383 BufferDescriptor *target, *source;
384 CopyStringParms *parms;
385 int what_is_user;
386 #define USER_IS_TARGET 0
387 #define USER_IS_SOURCE 1
388 {
389 #define TARGET_NO_EAB 1
390 #define SOURCE_NO_EAB 2
391 #define TARGET_PC 4
392 #define SOURCE_PC 8
393 #define NO_FIELD_ATTRIBUTES 16
394 int needtodo = 0;
395 int access_length;
396 char far *input;
397 char far *output;
398 char far *access_pointer;
399
400 if ((target->characteristics^source->characteristics)
401 &CHARACTERISTIC_EAB) {
402 if (target->characteristics&CHARACTERISTIC_EAB) {
403 needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */
404 } else {
405 needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */
406 }
407 }
408 if (target->session_type != source->session_type) {
409 if (target->session_type == TYPE_PC) {
410 needtodo |= TARGET_PC; /* scan codes to PC */
411 } else {
412 needtodo |= SOURCE_PC; /* PC to scan codes */
413 }
414 }
415 if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) {
416 needtodo |= NO_FIELD_ATTRIBUTES;
417 }
418 access_length = length;
419 if (what_is_user == USER_IS_TARGET) {
420 if (target->characteristics&CHARACTERISTIC_EAB) {
421 access_length *= 2;
422 }
423 input = (char far *) &Host[source->begin];
424 access_pointer = target->buffer;
425 output = access_api(target->buffer, access_length, 0);
426 } else {
427 if (source->characteristics&CHARACTERISTIC_EAB) {
428 access_length *= 2;
429 }
430 access_pointer = source->buffer;
431 input = access_api(source->buffer, access_length, 1);
432 output = (char far *) &Host[target->begin];
433 }
434 while (length--) {
435 if (needtodo&TARGET_PC) {
436 *output++ = disp_asc[*input++];
437 } else if (needtodo&SOURCE_PC) {
438 *output++ = asc_disp[*input++];
439 } else {
440 *output++ = *input++;
441 }
442 if (needtodo&TARGET_NO_EAB) {
443 input++;
444 } else if (needtodo&SOURCE_NO_EAB) {
445 *output++ = 0; /* Should figure out good EAB? */
446 }
447 }
448 if (what_is_user == USER_IS_TARGET) {
449 unaccess_api(target->buffer, access_pointer, access_length, 1);
450 } else {
451 unaccess_api(source->buffer, access_pointer, access_length, 0);
452 }
453 }
454
455
456 static void
457 copy_string(regs, sregs)
458 union REGS *regs;
459 struct SREGS *sregs;
460 {
461 CopyStringParms parms;
462 BufferDescriptor *target = &parms.target, *source = &parms.source;
463 int length;
464
465 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
466
467 length = 1+parms.source_end-source->begin;
468 if ((parms.rc != 0) || (parms.function_id !=0)) {
469 parms.rc = 0x0c;
470 } else if (target->session_id == 0) { /* Target is buffer */
471 if (source->session_id != 23) { /* A no-no */
472 parms.rc = 0x2;
473 } else {
474 if ((source->begin < 0) || (source->begin > highestof(Host))) {
475 parms.rc = 0x06; /* invalid source definition */
476 } else {
477 if ((source->begin+length) > highestof(Host)) {
478 length = highestof(Host)-source->begin;
479 parms.rc = 0x0f; /* Truncate */
480 }
481 if ((source->characteristics == target->characteristics) &&
482 (source->session_type == target->session_type)) {
483 if (source->characteristics&CHARACTERISTIC_EAB) {
484 length *= 2;
485 }
486 movetothem(FP_SEG(target->buffer),
487 FP_OFF(target->buffer),
488 (char *)&Host[source->begin], length);
489 } else {
490 copy_subroutine(target, source, &parms,
491 USER_IS_TARGET, length);
492 }
493 }
494 }
495 } else if (source->session_id != 0) {
496 parms.rc = 0xd;
497 } else {
498 if ((target->begin < 0) || (source->begin > highestof(Host))) {
499 parms.rc = 0x07; /* invalid source definition */
500 } else {
501 if ((source->begin+length) > highestof(Host)) {
502 length = highestof(Host)-source->begin;
503 parms.rc = 0x0f; /* Truncate */
504 }
505 if ((source->characteristics == target->characteristics) &&
506 (source->session_type == target->session_type)) {
507 if (source->characteristics&CHARACTERISTIC_EAB) {
508 length *= 2;
509 }
510 movetous((char *)&Host[target->begin],
511 FP_SEG(source->buffer),
512 FP_OFF(source->buffer), length);
513 } else {
514 copy_subroutine(target, source, &parms, USER_IS_SOURCE, length);
515 }
516 }
517 }
518 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
519 }
520 /*
521 * Operator Information Area Services.
522 */
523
524 static void
525 read_oia_group(regs, sregs)
526 union REGS *regs;
527 struct SREGS *sregs;
528 {
529 ReadOiaGroupParms parms;
530
531 movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
532
533 if ((parms.rc != 0) || (parms.function_id != 0)) {
534 parms.rc = 0x0c;
535 } else if (parms.session_id != 23) {
536 parms.rc = 0x02;
537 } else {
538 int group = parms.oia_group_number;
539 char *from;
540 int size;
541
542 if ((group != API_OIA_ALL_GROUPS) &&
543 ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) {
544 } else {
545 if (group == API_OIA_ALL_GROUPS) {
546 size = API_OIA_BYTES_ALL_GROUPS;
547 from = (char *)&OperatorInformationArea;
548 } else if (group == API_OIA_INPUT_INHIBITED) {
549 size = sizeof OperatorInformationArea.input_inhibited;
550 from = (char *)&OperatorInformationArea.input_inhibited[0];
551 } else {
552 size = 1;
553 from = ((char *)&OperatorInformationArea)+group;
554 }
555 movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer),
556 from, size);
557 }
558 }
559 parms.function_id = 0x6d;
560 movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
561 }
562
563 /*ARGSUSED*/
564 static void
565 unknown_op(regs, sregs)
566 union REGS *regs;
567 struct SREGS *sregs;
568 {
569 regs->h.ch = 0x12;
570 regs->h.cl = 0x05;
571 }
572
573
574 handle_api(regs, sregs)
575 union REGS *regs;
576 struct SREGS *sregs;
577 {
578 if (regs->h.ah == NAME_RESOLUTION) {
579 name_resolution(regs, sregs);
580 #if defined(unix)
581 } else if (regs->h.ah == PS_OR_OIA_MODIFIED) {
582 while ((oia_modified == 0) && (ps_modified == 0)) {
583 (void) Scheduler(1);
584 }
585 oia_modified = ps_modified = 0;
586 #endif /* defined(unix) */
587 } else if (regs->h.ah != 0x09) {
588 regs->h.ch = 0x12;
589 regs->h.cl = 0x0f; /* XXX Invalid environmental access */
590 } else if (regs->x.bx != 0x8020) {
591 regs->h.ch = 0x12;
592 regs->h.cl = 0x08; /* XXX Invalid wait specified */
593 } else if (regs->h.ch != 0) {
594 regs->x.cx = 0x1206; /* XXX Invalid priority */
595 } else {
596 switch (regs->x.dx) {
597 case GATE_SESSMGR:
598 switch (regs->h.al) {
599 case QUERY_SESSION_ID:
600 if (regs->h.cl != 0) {
601 regs->x.cx = 0x1206;
602 } else {
603 regs->x.cx = 0x1200;
604 query_session_id(regs, sregs);
605 }
606 break;
607 case QUERY_SESSION_PARAMETERS:
608 if (regs->h.cl != 0) {
609 regs->x.cx = 0x1206;
610 } else {
611 regs->x.cx = 0x1200;
612 query_session_parameters(regs, sregs);
613 }
614 break;
615 case QUERY_SESSION_CURSOR:
616 if (regs->h.cl != 0xff) {
617 regs->x.cx = 0x1206;
618 } else {
619 regs->x.cx = 0x1200;
620 query_session_cursor(regs, sregs);
621 }
622 break;
623 default:
624 unknown_op(regs, sregs);
625 break;
626 }
627 break;
628 case GATE_KEYBOARD:
629 if (regs->h.cl != 00) {
630 regs->x.cx = 0x1206;
631 } else {
632 regs->x.cx = 0x1200;
633 switch (regs->h.al) {
634 case CONNECT_TO_KEYBOARD:
635 connect_to_keyboard(regs, sregs);
636 break;
637 case DISABLE_INPUT:
638 disable_input(regs, sregs);
639 break;
640 case WRITE_KEYSTROKE:
641 write_keystroke(regs, sregs);
642 break;
643 case ENABLE_INPUT:
644 enable_input(regs, sregs);
645 break;
646 case DISCONNECT_FROM_KEYBOARD:
647 disconnect_from_keyboard(regs, sregs);
648 break;
649 default:
650 unknown_op(regs, sregs);
651 break;
652 }
653 }
654 break;
655 case GATE_COPY:
656 if (regs->h.cl != 0xff) {
657 regs->x.cx = 0x1206;
658 } else {
659 regs->x.cx = 0x1200;
660 switch (regs->h.al) {
661 case COPY_STRING:
662 copy_string(regs, sregs);
663 break;
664 default:
665 unknown_op(regs, sregs);
666 break;
667 }
668 }
669 break;
670 case GATE_OIAM:
671 if (regs->h.cl != 0xff) {
672 regs->x.cx = 0x1206;
673 } else {
674 regs->x.cx = 0x1200;
675 switch (regs->h.al) {
676 case READ_OIA_GROUP:
677 read_oia_group(regs, sregs);
678 break;
679 default:
680 unknown_op(regs, sregs);
681 break;
682 }
683 }
684 break;
685 default:
686 regs->h.ch = 0x12;
687 regs->h.cl = 0x34; /* Invalid GATE entry */
688 break;
689 }
690 }
691 }