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