xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 31183)
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