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