xref: /csrg-svn/usr.bin/tn3270/ctlr/api.c (revision 31183)
131158Sminshall /*
231158Sminshall  * This file implements the API used in the PC version.
331158Sminshall  */
431158Sminshall 
531158Sminshall #include <stdio.h>
631158Sminshall 
731158Sminshall #include "api.h"
8*31183Sminshall #include "../general/general.h"
931158Sminshall 
1031168Sminshall #include "../ctlr/screen.h"
11*31183Sminshall #include "../general/globals.h"
1231158Sminshall 
1331168Sminshall int ApiDisableInput = 0;
1431168Sminshall 
1531158Sminshall /*
1631158Sminshall  * Supervisor Services.
1731158Sminshall  */
1831158Sminshall 
1931158Sminshall static void
2031158Sminshall name_resolve(regs, sregs)
2131158Sminshall union REGS *regs;
2231158Sminshall struct SREGS *sregs;
2331158Sminshall {
2431167Sminshall     NameResolveParms parms;
2531161Sminshall 
2631167Sminshall     movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms);
2731161Sminshall 
2831161Sminshall     regs->h.cl = 0;
2931167Sminshall     if (strcmp((char *)&parms, NAME_SESSMGR) == 0) {
3031161Sminshall 	regs->x.dx = GATE_SESSMGR;
3131167Sminshall     } else if (strcmp((char *)&parms, NAME_KEYBOARD) == 0) {
3231161Sminshall 	regs->x.dx = GATE_KEYBOARD;
3331167Sminshall     } else if (strcmp((char *)&parms, NAME_COPY) == 0) {
3431161Sminshall 	regs->x.dx = GATE_COPY;
3531167Sminshall     } else if (strcmp((char *)&parms, NAME_OIAM) == 0) {
3631161Sminshall 	regs->x.dx = GATE_OIAM;
3731161Sminshall     } else {
3831161Sminshall 	regs->h.cl = 0x2e;	/* Name not found */
3931161Sminshall     }
4031161Sminshall     regs->h.ch = 0x12;
4131161Sminshall     regs->h.bh = 7;
4231158Sminshall }
4331158Sminshall 
4431158Sminshall /*
4531158Sminshall  * Session Information Services.
4631158Sminshall  */
4731158Sminshall 
4831158Sminshall static void
4931158Sminshall query_session_id(regs, sregs)
5031158Sminshall union REGS *regs;
5131158Sminshall struct SREGS *sregs;
5231158Sminshall {
5331167Sminshall     QuerySessionIdParms parms;
5431161Sminshall 
5531167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
5631161Sminshall 
5731167Sminshall     if (parms.rc != 0) {
5831167Sminshall 	regs->h.cl = 0x0c;
5931167Sminshall 	return;
6031167Sminshall     }
6131167Sminshall     if (parms.option_code != 0x01) {
6231167Sminshall 	regs->h.cl = 0x0d;	/* Invalid option code */
6331167Sminshall     } else if (parms.data_code != 0x45) {
6431167Sminshall 	regs->h.cl = 0x0b;
6531161Sminshall     } else {
6631168Sminshall 	NameArray list;
6731167Sminshall 	NameArrayElement element;
6831167Sminshall 
6931167Sminshall 	movetous((char *)&list, FP_SEG(parms.name_array),
7031167Sminshall 			    FP_OFFSET(parms.name_array), sizeof list);
7131168Sminshall 	if ((list.length < 14) || (list.length > 170)) {
7231167Sminshall 	    parms.rc = 0x12;
7331168Sminshall 	    regs->h.cl = 0x12;
7431161Sminshall 	} else {
7531167Sminshall 	    list.number_matching_session = 1;
7631167Sminshall 	    list.name_array_element.short_name = parms.data_code;
7731167Sminshall 	    list.name_array_element.type = TYPE_DFT;
7831167Sminshall 	    list.name_array_element.session_id = 23;
7931167Sminshall 	    memcpy(list.name_array_element.long_name, "ONLYSESS",
8031167Sminshall 			    sizeof list.name_array_element.long_name);
8131167Sminshall 	    movetothem(FP_SEG(parms.name_array),
8231167Sminshall 		FP_OFFSET(parms.name_array), (char *)&list, sizeof list);
8331167Sminshall 	    parms.rc = 0;
8431161Sminshall 	    regs->h.cl = 0;
8531161Sminshall 	}
8631161Sminshall     }
8731168Sminshall     parms.function_id = 0x6d;
8831167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
8931158Sminshall }
9031158Sminshall 
9131158Sminshall static void
9231158Sminshall query_session_parameters(regs, sregs)
9331158Sminshall union REGS *regs;
9431158Sminshall struct SREGS *sregs;
9531158Sminshall {
9631167Sminshall     QuerySessionParametersParms parms;
9731167Sminshall 
9831167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
9931167Sminshall 
10031168Sminshall     if ((parms.rc !=0) || (parms.function_id != 0)) {
10131167Sminshall 	regs->h.cl = 0x0c;
10231167Sminshall 	return;
10331167Sminshall     }
10431167Sminshall     if (parms.session_id != 23) {
10531168Sminshall 	regs->h.cl = parms.rc = 0x02;
10631167Sminshall     } else {
10731168Sminshall 	regs->h.cl = parms.rc = 0;
10831167Sminshall 	parms.function_id = 0x6b;
10931167Sminshall 	parms.session_type = TYPE_DFT;
11031167Sminshall 	parms.session_characteristics = 0;	/* Neither EAB nor PSS */
11131167Sminshall 	parms.rows = MaxNumberLines;
11231167Sminshall 	parms.columns = MaxNumberColumns;
11331167Sminshall 	parms.presentation_space = 0;
11431167Sminshall     }
11531168Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
11631158Sminshall }
11731158Sminshall 
11831158Sminshall static void
11931158Sminshall query_session_cursor(regs, sregs)
12031158Sminshall union REGS *regs;
12131158Sminshall struct SREGS *sregs;
12231158Sminshall {
12331167Sminshall     QuerySessionCursorParms parms;
12431167Sminshall 
12531167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
12631167Sminshall 
12731167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
12831167Sminshall 	parms.rc = 0x0c;
12931167Sminshall     } else if (parms.session_id != 23) {
13031167Sminshall 	parms.rc = 0x02;
13131167Sminshall     } else {
13231167Sminshall 	parms.rc = 0;
13331167Sminshall 	parms.function_id = 0x6b;
13431167Sminshall 	parms.cursor_type = CURSOR_BLINKING;	/* XXX what is inhibited? */
13531167Sminshall 	parms.row_address = ScreenLine(CursorAddress);
13631167Sminshall 	parms.column_address = ScreenLineOffset(CursorAddress);
13731167Sminshall     }
13831167Sminshall 
13931167Sminshall     movetothem(sregs->es, regs->x.di, sizeof parms);
14031158Sminshall }
14131158Sminshall 
14231158Sminshall /*
14331158Sminshall  * Keyboard Services.
14431158Sminshall  */
14531158Sminshall 
14631158Sminshall 
14731158Sminshall static void
14831158Sminshall connect_to_keyboard(regs, sregs)
14931158Sminshall union REGS *regs;
15031158Sminshall struct SREGS *sregs;
15131158Sminshall {
15231167Sminshall     ConnectToKeyboardParms parms;
15331167Sminshall 
154*31183Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
15531167Sminshall 
15631167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
15731167Sminshall 	parms.rc = 0x0c;
15831167Sminshall     } else if (parms.session_id != 23) {
15931167Sminshall 	parms.rc = 0x02;
16031167Sminshall     } else if (parms.intercept_options != 0) {
16131167Sminshall 	parms.rc = 0x01;
16231167Sminshall     } else {
16331167Sminshall 	parms.rc = 0;
16431167Sminshall 	parms.first_connection_identifier = 0;
16531167Sminshall     }
16631167Sminshall     parms.function_id = 0x62;
16731167Sminshall 
16831167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
16931158Sminshall }
17031158Sminshall 
17131158Sminshall static void
17231167Sminshall disconnect_from_keyboard(regs, sregs)
17331158Sminshall union REGS *regs;
17431158Sminshall struct SREGS *sregs;
17531158Sminshall {
17631167Sminshall     DisconnectFromKeyboardParms parms;
17731167Sminshall 
17831167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
17931167Sminshall 
18031167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
18131167Sminshall 	parms.rc = 0x0c;
18231167Sminshall     } else if (parms.session_id != 23) {
18331167Sminshall 	parms.rc = 0x02;
18431167Sminshall     } else if (parms.connectors_task_id != 0) {
18531167Sminshall 	parms.rc = 04;			/* XXX */
18631167Sminshall     } else {
18731167Sminshall 	parms.rc = 0;
18831167Sminshall     }
18931167Sminshall     parms.function_id = 0x62;
19031167Sminshall 
19131167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
19231158Sminshall }
19331158Sminshall 
19431158Sminshall static void
19531158Sminshall write_keystroke(regs, sregs)
19631158Sminshall union REGS *regs;
19731158Sminshall struct SREGS *sregs;
19831158Sminshall {
19931167Sminshall /* XXX */
20031158Sminshall }
20131158Sminshall 
20231167Sminshall 
20331158Sminshall static void
20431167Sminshall disable_input(regs, sregs)
20531167Sminshall union REGS *regs;
20631167Sminshall struct SREGS *sregs;
20731167Sminshall {
20831167Sminshall     DisableInputParms parms;
20931167Sminshall 
21031167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
21131167Sminshall 
21231167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
21331167Sminshall 	parms.rc = 0x0c;
21431167Sminshall     } else if (parms.session_id != 23) {
21531167Sminshall 	parms.rc = 0x02;
21631167Sminshall     } else if (parms.connectors_task_id != 0) {
21731167Sminshall 	parms.rc = 0x04;
21831167Sminshall     } else {
21931167Sminshall 	ApiDisableInput = 1;
22031167Sminshall 	parms.rc = 0;
22131167Sminshall     }
22231167Sminshall     parms.function_id = 0x62;
22331167Sminshall 
22431167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
22531167Sminshall }
22631167Sminshall 
22731167Sminshall static void
22831158Sminshall enable_input(regs, sregs)
22931158Sminshall union REGS *regs;
23031158Sminshall struct SREGS *sregs;
23131158Sminshall {
23231167Sminshall     EnableInputParms parms;
23331167Sminshall 
23431167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
23531167Sminshall 
23631167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
23731167Sminshall 	parms.rc = 0x0c;
23831167Sminshall     } else if (parms.session_id != 23) {
23931167Sminshall 	parms.rc = 0x02;
24031167Sminshall     } else if (parms.connectors_task_id != 0) {
24131167Sminshall 	parms.rc = 0x04;
24231167Sminshall     } else {
24331167Sminshall 	ApiDisableInput = 0;
24431167Sminshall 	parms.rc = 0;
24531167Sminshall     }
24631167Sminshall     parms.function_id = 0x62;
24731167Sminshall 
24831167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
24931158Sminshall }
25031158Sminshall 
25131158Sminshall /*
25231158Sminshall  * Copy Services.
25331158Sminshall  */
25431158Sminshall 
25531158Sminshall static void
25631167Sminshall copy_string(regs, sregs)
25731158Sminshall union REGS *regs;
25831158Sminshall struct SREGS *sregs;
25931158Sminshall {
26031167Sminshall     CopyStringParms parms;
26131167Sminshall     BufferDescriptor *target, *source;
26231167Sminshall 
26331167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
26431167Sminshall 
26531167Sminshall     if ((parms.rc != 0) || (parms.function_id !=0)) {
26631167Sminshall 	parms.rc = 0x0c;
26731167Sminshall     }
26831167Sminshall     /* XXX do something! */
269*31183Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
27031158Sminshall }
27131158Sminshall /*
27231158Sminshall  * Operator Information Area Services.
27331158Sminshall  */
27431158Sminshall 
27531158Sminshall static void
27631158Sminshall read_oia_group(regs, sregs)
27731158Sminshall union REGS *regs;
27831158Sminshall struct SREGS *sregs;
27931158Sminshall {
28031167Sminshall     ReadOiaGroupParms parms;
28131167Sminshall 
28231167Sminshall     movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms);
28331167Sminshall 
28431167Sminshall     if ((parms.rc != 0) || (parms.function_id != 0)) {
28531167Sminshall 	parms.rc = 0x0c;
28631167Sminshall     } else if (parms.session_id != 23) {
28731167Sminshall 	parms.rc = 0x02;
28831167Sminshall     } else {
28931167Sminshall 	int group = parms.oia_group_number;
29031167Sminshall 	char far *where = parms.oia_buffer;
29131167Sminshall 
29231167Sminshall 	switch (group) {
29331167Sminshall 	case OIA_ALL_GROUPS:
29431167Sminshall 	case OIA_ONLINE_OWNERSHIP:
29531167Sminshall 	    if (group != OIA_ALL_GROUPS) {
29631167Sminshall 		break;
29731167Sminshall 	    } /* else, fall through */
29831167Sminshall 	case OIA_CHARACTER_SELECTION:
29931167Sminshall 	    if (group != OIA_ALL_GROUPS) {
30031167Sminshall 		break;
30131167Sminshall 	    } /* else, fall through */
30231167Sminshall 	case OIA_SHIFT_STATE:
30331167Sminshall 	    if (group != OIA_ALL_GROUPS) {
30431167Sminshall 		break;
30531167Sminshall 	    } /* else, fall through */
30631167Sminshall 	case OIA_PSS_GROUP_1:
30731167Sminshall 	    if (group != OIA_ALL_GROUPS) {
30831167Sminshall 		break;
30931167Sminshall 	    } /* else, fall through */
31031167Sminshall 	case OIA_HIGHLIGHT_GROUP_1:
31131167Sminshall 	    if (group != OIA_ALL_GROUPS) {
31231167Sminshall 		break;
31331167Sminshall 	    } /* else, fall through */
31431167Sminshall 	case OIA_COLOR_GROUP_1:
31531167Sminshall 	    if (group != OIA_ALL_GROUPS) {
31631167Sminshall 		break;
31731167Sminshall 	    } /* else, fall through */
31831167Sminshall 	case OIA_INSERT:
31931167Sminshall 	    if (group != OIA_ALL_GROUPS) {
32031167Sminshall 		break;
32131167Sminshall 	    } /* else, fall through */
32231167Sminshall 	case OIA_INPUT_INHIBITED:
32331167Sminshall 	    if (group != OIA_ALL_GROUPS) {
32431167Sminshall 		break;
32531167Sminshall 	    } /* else, fall through */
32631167Sminshall 	case OIA_PSS_GROUP_2:
32731167Sminshall 	    if (group != OIA_ALL_GROUPS) {
32831167Sminshall 		break;
32931167Sminshall 	    } /* else, fall through */
33031167Sminshall 	case OIA_HIGHLIGHT_GROUP_2:
33131167Sminshall 	    if (group != OIA_ALL_GROUPS) {
33231167Sminshall 		break;
33331167Sminshall 	    } /* else, fall through */
33431167Sminshall 	case OIA_COLOR_GROUP_2:
33531167Sminshall 	    if (group != OIA_ALL_GROUPS) {
33631167Sminshall 		break;
33731167Sminshall 	    } /* else, fall through */
338*31183Sminshall 	case OIA_COMM_ERROR_REMINDER:
33931167Sminshall 	    if (group != OIA_ALL_GROUPS) {
34031167Sminshall 		break;
34131167Sminshall 	    } /* else, fall through */
34231167Sminshall 	case OIA_PRINTER_STATUS:
34331167Sminshall 	    if (group != OIA_ALL_GROUPS) {
34431167Sminshall 		break;
34531167Sminshall 	    } /* else, fall through */
34631167Sminshall 	case OIA_AUTOKEY_PLAY_RECORD_STATUS:
34731167Sminshall 	    if (group != OIA_ALL_GROUPS) {
34831167Sminshall 		break;
34931167Sminshall 	    } /* else, fall through */
35031167Sminshall 	case OIA_AUTOKEY_ABORT_PAUSE_STATUS:
35131167Sminshall 	    if (group != OIA_ALL_GROUPS) {
35231167Sminshall 		break;
35331167Sminshall 	    } /* else, fall through */
35431167Sminshall 	case OIA_ENLARGE_STATE:
35531167Sminshall 	    if (group != OIA_ALL_GROUPS) {
35631167Sminshall 		break;
35731167Sminshall 	    } /* else, fall through */
35831167Sminshall 
35931167Sminshall 	    /* oops, we are done! */
36031167Sminshall 	    break;
36131167Sminshall 	default:
36231167Sminshall 	    break;
36331168Sminshall 	}
36431167Sminshall     }
36531168Sminshall     parms.function_id = 0x6d;
36631167Sminshall     movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms);
36731158Sminshall }
36831158Sminshall 
36931158Sminshall static void
37031158Sminshall unknown_op(regs, sregs)
37131158Sminshall union REGS *regs;
37231158Sminshall struct SREGS *sregs;
37331158Sminshall {
37431158Sminshall     regs->h.ch = 0x12;
37531158Sminshall     regs->h.cl = 0x05;
37631158Sminshall }
37731158Sminshall 
37831158Sminshall 
37931158Sminshall handle_api(regs, sregs)
38031158Sminshall union REGS *regs;
38131158Sminshall struct SREGS *sregs;
38231158Sminshall {
38331158Sminshall     if (regs->h.ah == NAME_RESOLUTION) {
38431158Sminshall 	name_resolution(regs, sregs);
38531168Sminshall     } else if (regs->h.ah != 0x09) {
38631168Sminshall 	regs->h.ch = 0x12;
38731168Sminshall 	regs->h.cl = 0x0f;		/* XXX Invalid environmental access */
38831168Sminshall     } else if (regs->x.bx != 0x8020) {
38931168Sminshall 	regs->h.ch = 0x12;
39031168Sminshall 	regs->h.cl = 0x08;		/* XXX Invalid wait specified */
39131168Sminshall     } else if (regs->h.ch != 0) {
39231168Sminshall 	regs->h.ch = 0x12;
39331168Sminshall 	regs->h.cl = 0x07;		/* XXX Invalid reply specified */
39431158Sminshall     } else {
39531158Sminshall 	switch (regs->x.dx) {
39631158Sminshall 	case GATE_SESSMGR:
39731158Sminshall 	    switch (regs->h.al) {
39831158Sminshall 	    case QUERY_SESSION_ID:
39931168Sminshall 		if (regs->h.cl != 0) {
40031168Sminshall 		} else {
40131168Sminshall 		    query_session_id(regs, sregs);
40231168Sminshall 		}
40331158Sminshall 		break;
40431158Sminshall 	    case QUERY_SESSION_PARMS:
40531168Sminshall 		if (regs->h.cl != 0) {
40631168Sminshall 		} else {
40731168Sminshall 		    query_session_parms(regs, sregs);
40831168Sminshall 		}
40931158Sminshall 		break;
41031158Sminshall 	    case QUERY_SESSION_CURSOR:
41131168Sminshall 		if (regs->h.cl != 0xff) {
41231168Sminshall 		} else {
41331168Sminshall 		    query_session_cursor(regs, sregs);
41431168Sminshall 		}
41531158Sminshall 		break;
41631158Sminshall 	    default:
41731158Sminshall 		unknown_op(regs, sregs);
41831158Sminshall 		break;
41931158Sminshall 	    }
42031158Sminshall 	    break;
42131158Sminshall 	case GATE_KEYBOARD:
42231168Sminshall 	    if (regs->h.cl != 00) {
42331168Sminshall 	    } else {
42431168Sminshall 		switch (regs->h.al) {
42531168Sminshall 		case CONNECT_TO_KEYBOARD:
42631168Sminshall 		    connect_to_keyboard(regs, sregs);
42731168Sminshall 		    break;
42831168Sminshall 		case DISABLE_INPUT:
42931168Sminshall 		    disable_input(regs, sregs);
43031168Sminshall 		    break;
43131168Sminshall 		case WRITE_KEYSTROKE:
43231168Sminshall 		    write_keystroke(regs, sregs);
43331168Sminshall 		    break;
43431168Sminshall 		case ENABLE_INPUT:
43531168Sminshall 		    enable_input(regs, sregs);
43631168Sminshall 		    break;
43731168Sminshall 		case DISCONNECT_FROM_KEYBOARD:
43831168Sminshall 		    disconnect_from_keyboard(regs, sregs);
43931168Sminshall 		    break;
44031168Sminshall 		default:
44131168Sminshall 		    unknown_op(regs, sregs);
44231168Sminshall 		    break;
44331168Sminshall 		}
44431158Sminshall 	    }
44531158Sminshall 	    break;
44631158Sminshall 	case GATE_COPY:
44731168Sminshall 	    if (regs->h.cl != 0xff) {
44831168Sminshall 	    } else {
44931168Sminshall 		switch (regs->h.al) {
45031168Sminshall 		case COPY_STRING:
45131168Sminshall 		    copy_string(regs, sregs);
45231168Sminshall 		    break;
45331168Sminshall 		default:
45431168Sminshall 		    unknown_op(regs, sregs);
45531168Sminshall 		    break;
45631168Sminshall 		}
45731158Sminshall 	    }
45831158Sminshall 	    break;
45931158Sminshall 	case GATE_OIAM:
46031168Sminshall 	    if (regs->h.cl != 0xff) {
46131168Sminshall 	    } else {
46231168Sminshall 		switch (regs->h.al) {
46331168Sminshall 		case READ_OIA_GROUP:
46431168Sminshall 		    read_oia_group(regs, sregs);
46531168Sminshall 		    break;
46631168Sminshall 		default:
46731168Sminshall 		    unknown_op(regs, sregs);
46831168Sminshall 		    break;
46931168Sminshall 		}
47031158Sminshall 	    }
47131158Sminshall 	    break;
47231158Sminshall 	default:
47331168Sminshall 	    regs->h.ch = 0x12;
47431168Sminshall 	    regs->h.cl = 0x34;		/* Invalid GATE entry */
47531158Sminshall 	    break;
47631158Sminshall 	}
47731158Sminshall     }
47831158Sminshall }
479