diff options
Diffstat (limited to 'usr.bin/tn3270/ctlr')
-rw-r--r-- | usr.bin/tn3270/ctlr/3180.kbd | 182 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/3270pc.kbd | 182 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/api.c | 756 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/api.h | 404 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/ctlr.order | 5 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/declare.h | 54 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/externs.h | 67 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/function.c | 48 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/function.h | 167 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/hostctlr.h | 223 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/inbound.c | 1195 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/oia.c | 52 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/oia.h | 191 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/options.c | 182 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/options.h | 42 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/outbound.c | 606 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/screen.h | 146 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/scrnctlr.h | 49 | ||||
-rw-r--r-- | usr.bin/tn3270/ctlr/unix.kbd | 184 |
19 files changed, 4735 insertions, 0 deletions
diff --git a/usr.bin/tn3270/ctlr/3180.kbd b/usr.bin/tn3270/ctlr/3180.kbd new file mode 100644 index 00000000000..a912e4453f5 --- /dev/null +++ b/usr.bin/tn3270/ctlr/3180.kbd @@ -0,0 +1,182 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)3180.kbd 4.2 (Berkeley) 4/26/91 + */ + +/* + * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ] + * + * keynumber is in decimal, and starts in column 1. + * scancode is hexadecimal. + * unshifted, etc. - these are either a single ascii character, + * or the name of a function or an AID-generating key. + * + * all fields are separated by a single space. + */ +1 0e ` ~ +2 16 1 VERTICAL_BAR +3 1e 2 @ +4 26 3 # +5 25 4 $ +6 2e 5 % +7 36 6 ^ +8 3d 7 & +9 3e 8 * +10 46 9 ( +11 45 0 ) +12 4e - _ +13 55 = + +14 5d +15 66 LEFT +16 0d TAB +17 15 q Q +18 1d w W +19 24 e E +20 2d r R +21 2c t T +22 35 y Y +23 3c u U +24 43 i I +25 44 o O +26 4d p P +27 54 CENTSIGN ! +28 5b \ | +29 5c +30 14 CAPS_LOCK +31 1c a A +32 1b s S +33 23 d D +34 2b f F +35 34 g G +36 33 h H +37 3b j J +38 42 k K +39 4b l L +40 4c ; : +41 52 ' " +42 53 { } +43 5a NL +44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT +45 13 < > +46 1a z Z +47 22 x X +48 21 c C +49 2a v V +50 32 b B +51 31 n N +52 3a m M +53 41 , , +54 49 . . +55 4a / ? +56 51 +57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT +58 11 RESET NULL DVCNL +59 +60 19 MAKE_ALT MAKE_ALT MAKE_ALT +61 29 SPACE SPACE +62 39 MAKE_ALT MAKE_ALT MAKE_ALT +63 +64 58 ENTER +65 06 CLEAR +66 0c NULL NULL EINP +67 0b EEOF +68 0a +69 09 +70 05 ATTN NULL TREQ +71 04 +72 03 +73 83 +74 01 +75 67 PA1 DP +76 64 BTAB +77 +78 61 LEFT NULL LEFT2 +79 +80 6e PA2 FM +81 65 INSRT +82 63 UP +83 62 NULL NULL HOME +84 60 DOWN +85 6f +86 6d DELETE +87 +88 6a RIGHT NULL RIGHT2 +89 +90 76 +91 6c 7 +92 6b 4 +93 69 1 +94 68 +95 77 +96 75 8 +97 73 5 +98 72 2 +99 70 0 +100 7e , +101 7d 9 +102 74 6 +103 7a 3 +104 71 . +105 84 SPACE +106 7c TAB +107 7b - +108 79 ENTER +109 78 +110 07 PF1 +111 0f PF2 +112 17 PF3 +113 1f PF4 +114 27 PF5 +115 2f PF6 +116 37 PF7 +117 3f PF8 NULL MONOCASE +118 47 PF9 +119 4f PF10 +120 56 PF11 +121 5e PF12 +122 08 PF13 +123 10 PF14 +124 18 PF15 +125 20 PF16 +126 28 PF17 +127 30 PF18 +128 38 PF19 +129 40 PF20 +130 48 PF21 +131 50 PF22 +132 57 PF23 +133 5f PF24 +134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT +135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT +136 99 BREAK_ALT BREAK_ALT BREAK_ALT +137 B9 BREAK_ALT BREAK_ALT BREAK_ALT diff --git a/usr.bin/tn3270/ctlr/3270pc.kbd b/usr.bin/tn3270/ctlr/3270pc.kbd new file mode 100644 index 00000000000..161010347fb --- /dev/null +++ b/usr.bin/tn3270/ctlr/3270pc.kbd @@ -0,0 +1,182 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)3270pc.kbd 4.2 (Berkeley) 4/26/91 + */ + +/* + * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ] + * + * keynumber is in decimal, and starts in column 1. + * scancode is hexadecimal. + * unshifted, etc. - these are either a single ascii character, + * or the name of a function or an AID-generating key. + * + * all fields are separated by a single space. + */ +1 0e ` ~ +2 16 1 ! +3 1e 2 @ +4 26 3 # +5 25 4 $ +6 2e 5 % +7 36 6 ^ +8 3d 7 & +9 3e 8 * +10 46 9 ( +11 45 0 ) +12 4e - _ +13 55 = + +14 5d +15 66 LEFT +16 0d TAB BTAB +17 15 q Q +18 1d w W +19 24 e E +20 2d r R +21 2c t T +22 35 y Y +23 3c u U +24 43 i I +25 44 o O +26 4d p P +27 54 [ { +28 5b \ | +29 5c +30 14 CAPS_LOCK +31 1c a A +32 1b s S +33 23 d D +34 2b f F +35 34 g G +36 33 h H +37 3b j J +38 42 k K +39 4b l L +40 4c ; : +41 52 ' " +42 53 ] } +43 5a NL +44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT +45 13 < > +46 1a z Z +47 22 x X +48 21 c C +49 2a v V +50 32 b B +51 31 n N +52 3a m M +53 41 , < +54 49 . > +55 4a / ? +56 51 +57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT +58 11 RESET NULL DVCNL +59 +60 19 MAKE_ALT MAKE_ALT MAKE_ALT +61 29 SPACE SPACE +62 39 MAKE_ALT MAKE_ALT MAKE_ALT +63 +64 58 ENTER +65 06 CLEAR NULL TEST +66 0c NULL NULL ATTN +67 0b EEOF NULL EINP +68 0a +69 09 MAKE_CTRL +70 05 ATTN NULL TREQ +71 04 +72 03 +73 83 +74 01 +75 67 PA1 DP +76 64 BTAB +77 +78 61 LEFT NULL LEFT2 +79 +80 6e PA2 FM +81 65 INSRT +82 63 UP +83 62 NULL NULL HOME +84 60 DOWN +85 6f PA3 +86 6d DELETE +87 +88 6a RIGHT NULL RIGHT2 +89 +90 76 +91 6c 7 +92 6b 4 +93 69 1 +94 68 +95 77 +96 75 8 +97 73 5 +98 72 2 +99 70 0 +100 7e , +101 7d 9 +102 74 6 +103 7a 3 +104 71 . +105 84 SPACE +106 7c TAB +107 7b - +108 79 ENTER +109 78 +110 07 PF1 +111 0f PF2 +112 17 PF3 +113 1f PF4 +114 27 PF5 +115 2f PF6 +116 37 PF7 +117 3f PF8 NULL MONOCASE +118 47 PF9 +119 4f PF10 +120 56 PF11 +121 5e PF12 +122 08 PF13 +123 10 PF14 +124 18 PF15 +125 20 PF16 +126 28 PF17 +127 30 PF18 +128 38 PF19 +129 40 PF20 +130 48 PF21 +131 50 PF22 +132 57 PF23 +133 5f PF24 +134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT +135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT +136 99 BREAK_ALT BREAK_ALT BREAK_ALT +137 B9 BREAK_ALT BREAK_ALT BREAK_ALT diff --git a/usr.bin/tn3270/ctlr/api.c b/usr.bin/tn3270/ctlr/api.c new file mode 100644 index 00000000000..5835532c2c3 --- /dev/null +++ b/usr.bin/tn3270/ctlr/api.c @@ -0,0 +1,756 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +/*static char sccsid[] = "from: @(#)api.c 4.5 (Berkeley) 4/26/91";*/ +static char rcsid[] = "$Id: api.c,v 1.1 1995/10/18 08:46:20 deraadt Exp $"; +#endif /* not lint */ + +/* + * This file implements the API used in the PC version. + */ + +#include <stdio.h> + +#include "api.h" +#include "../general/general.h" + +#include "../api/disp_asc.h" + +#include "screen.h" +#include "hostctlr.h" +#include "oia.h" + +#include "../general/globals.h" + +int apitrace = 0; + +/* + * Some defines for things we use internally. + */ + +#define PS_SESSION_ID 23 +#define BUF_SESSION_ID 0 + +/* + * General utility routines. + */ + +#if defined(MSDOS) + +#if defined(LINT_ARGS) +static void movetous(char *, int, int, int); +static void movetothem(int, int, char *, int); +#endif /* defined(LINT_ARGS) */ + +#define access_api(foo,length,copyin) (foo) +#define unaccess_api(foo,goo,length,copyout) + +static void +movetous(parms, es, di, length) +char *parms; +int es, di; +int length; +{ + char far *farparms = parms; + + movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length); + if (apitrace) { + Dump('(', parms, length); + } +} + +static void +movetothem(es, di, parms, length) +int es, di; +char *parms; +int length; +{ + char far *farparms = parms; + + movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length); + if (apitrace) { + Dump(')', parms, length); + } +} +#endif /* defined(MSDOS) */ + +#if defined(unix) +extern char *access_api(); +extern void movetous(), movetothem(), unaccess_api(); +#endif /* defined(unix) */ + + +/* + * Supervisor Services. + */ + +static void +name_resolution(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + NameResolveParms parms; + + movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); + + regs->h.cl = 0; + if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { + regs->x.dx = GATE_SESSMGR; + } else if (memcmp((char *)&parms, NAME_KEYBOARD, + sizeof parms.gate_name) == 0) { + regs->x.dx = GATE_KEYBOARD; + } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { + regs->x.dx = GATE_COPY; + } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) { + regs->x.dx = GATE_OIAM; + } else { + regs->h.cl = 0x2e; /* Name not found */ + } + regs->h.ch = 0x12; + regs->h.bh = 7; +} + +/* + * Session Information Services. + */ + +static void +query_session_id(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + QuerySessionIdParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc != 0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.option_code != 0x01) { + parms.rc = 0x0d; /* Invalid option code */ +#ifdef NOTOBS + } else if ((parms.data_code != 0x45) && (parms.data_code != 0x00/*OBS*/)) { + parms.rc = 0x0b; +#endif /* NOTOBS */ + } else { + NameArray list; + + movetous((char *)&list, FP_SEG(parms.name_array), + FP_OFF(parms.name_array), sizeof list); + if ((list.length < 14) || (list.length > 170)) { + parms.rc = 0x12; + } else { + list.number_matching_session = 1; + list.name_array_element.short_name = parms.data_code; + list.name_array_element.type = TYPE_DFT; + list.name_array_element.session_id = PS_SESSION_ID; + memcpy(list.name_array_element.long_name, "ONLYSESS", + sizeof list.name_array_element.long_name); + movetothem(FP_SEG(parms.name_array), + FP_OFF(parms.name_array), (char *)&list, sizeof list); + parms.rc = 0; + } + } + parms.function_id = 0x6b; + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +} + +static void +query_session_parameters(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + QuerySessionParametersParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc !=0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.session_id != PS_SESSION_ID) { + parms.rc = 0x02; + } else { + parms.rc = 0; + parms.session_type = TYPE_DFT; + parms.session_characteristics = 0; /* Neither EAB nor PSS */ + parms.rows = MaxNumberLines; + parms.columns = MaxNumberColumns; + parms.presentation_space = 0; + } + parms.function_id = 0x6b; + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +} + +static void +query_session_cursor(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + QuerySessionCursorParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc != 0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.session_id != PS_SESSION_ID) { + parms.rc = 0x02; + } else { + parms.rc = 0; + parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ + parms.row_address = ScreenLine(CursorAddress); + parms.column_address = ScreenLineOffset(CursorAddress); + } + + parms.function_id = 0x6b; + movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms); +} + +/* + * Keyboard Services. + */ + + +static void +connect_to_keyboard(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + ConnectToKeyboardParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc != 0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.session_id != PS_SESSION_ID) { + parms.rc = 0x02; + } else if (parms.intercept_options != 0) { + parms.rc = 0x01; + } else { + parms.rc = 0; + parms.first_connection_identifier = 0; + } + parms.function_id = 0x62; + + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +} + +static void +disconnect_from_keyboard(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + DisconnectFromKeyboardParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc != 0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.session_id != PS_SESSION_ID) { + parms.rc = 0x02; + } else if (parms.connectors_task_id != 0) { + parms.rc = 04; /* XXX */ + } else { + parms.rc = 0; + } + parms.function_id = 0x62; + + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +} + +static void +write_keystroke(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + WriteKeystrokeParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc != 0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.session_id != PS_SESSION_ID) { + parms.rc = 0x02; + } else if (parms.connectors_task_id != 0) { + parms.rc = 0x04; + } else { + parms.number_of_keys_sent = 0; + parms.rc = 0; + if (parms.options == OPTION_SINGLE_KEYSTROKE) { + KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry; + + if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) { + parms.rc = 0x10; /* XXX needs 0x12 too! */ + } + parms.number_of_keys_sent++; + } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) { + KeystrokeList + list, + far *atlist = parms.keystroke_specifier.keystroke_list; + KeystrokeEntry + entry[10], /* 10 at a time */ + *ourentry, + far *theirentry; + int + todo; + + movetous((char *)&list, FP_SEG(atlist), + FP_OFF(atlist), sizeof *atlist); + todo = list.length/2; + ourentry = entry+(highestof(entry)+1); + theirentry = &atlist->keystrokes; + + while (todo) { + if (ourentry > &entry[highestof(entry)]) { + int thistime; + + thistime = todo; + if (thistime > numberof(entry)) { + thistime = numberof(entry); + } + movetous((char *)entry, FP_SEG(theirentry), + FP_OFF(theirentry), thistime*sizeof *theirentry); + theirentry += thistime; + ourentry = entry; + } + if (AcceptKeystroke(ourentry->scancode, + ourentry->shift_state) == 0) { + parms.rc = 0x10; /* XXX needs 0x12 too! */ + break; + } + parms.number_of_keys_sent++; + ourentry++; + todo--; + } + } else { + parms.rc = 0x01; + } + } + parms.function_id = 0x62; + + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +/* XXX */ +} + + +static void +disable_input(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + DisableInputParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc != 0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.session_id != PS_SESSION_ID) { + parms.rc = 0x02; + } else if (parms.connectors_task_id != 0) { + parms.rc = 0x04; + } else { + SetOiaApiInhibit(&OperatorInformationArea); + parms.rc = 0; + } + parms.function_id = 0x62; + + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +} + +static void +enable_input(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + EnableInputParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc != 0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.session_id != PS_SESSION_ID) { + parms.rc = 0x02; + } else if (parms.connectors_task_id != 0) { + parms.rc = 0x04; + } else { + ResetOiaApiInhibit(&OperatorInformationArea); + parms.rc = 0; + } + parms.function_id = 0x62; + + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +} + +/* + * Copy Services. + */ + +static +copy_subroutine(target, source, parms, what_is_user, length) +BufferDescriptor *target, *source; +CopyStringParms *parms; +int what_is_user; +#define USER_IS_TARGET 0 +#define USER_IS_SOURCE 1 +{ +#define TARGET_NO_EAB 1 +#define SOURCE_NO_EAB 2 +#define TARGET_PC 4 +#define SOURCE_PC 8 +#define NO_FIELD_ATTRIBUTES 16 + int needtodo = 0; + int access_length; + char far *input; + char far *output; + char far *access_pointer; + + if ((target->characteristics^source->characteristics) + &CHARACTERISTIC_EAB) { + if (target->characteristics&CHARACTERISTIC_EAB) { + needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */ + } else { + needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */ + } + } + if (target->session_type != source->session_type) { + if (target->session_type == TYPE_PC) { + needtodo |= TARGET_PC; /* scan codes to PC */ + } else { + needtodo |= SOURCE_PC; /* PC to scan codes */ + } + } + if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) { + needtodo |= NO_FIELD_ATTRIBUTES; + } + access_length = length; + if (what_is_user == USER_IS_TARGET) { + if (target->characteristics&CHARACTERISTIC_EAB) { + access_length *= 2; + } + input = (char far *) &Host[source->begin]; + access_pointer = target->buffer; + output = access_api(target->buffer, access_length, 0); + } else { + if (source->characteristics&CHARACTERISTIC_EAB) { + access_length *= 2; + } + access_pointer = source->buffer; + input = access_api(source->buffer, access_length, 1); + output = (char far *) &Host[target->begin]; + } + while (length--) { + if (needtodo&TARGET_PC) { + *output++ = disp_asc[*input++]; + } else if (needtodo&SOURCE_PC) { + *output++ = asc_disp[*input++]; + } else { + *output++ = *input++; + } + if (needtodo&TARGET_NO_EAB) { + input++; + } else if (needtodo&SOURCE_NO_EAB) { + *output++ = 0; /* Should figure out good EAB? */ + } + } + if (what_is_user == USER_IS_TARGET) { + unaccess_api(target->buffer, access_pointer, access_length, 1); + } else { + unaccess_api(source->buffer, access_pointer, access_length, 0); + } +} + + +static void +copy_string(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + CopyStringParms parms; + BufferDescriptor *target = &parms.target, *source = &parms.source; + int length; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + length = 1+parms.source_end-source->begin; + if ((parms.rc != 0) || (parms.function_id !=0)) { + parms.rc = 0x0c; + } else if (target->session_id == BUF_SESSION_ID) { /* Target is buffer */ + if (source->session_id != PS_SESSION_ID) { /* A no-no */ + parms.rc = 0x2; + } else { + if ((source->begin < 0) || (source->begin > highestof(Host))) { + parms.rc = 0x06; /* invalid source definition */ + } else { + if ((source->begin+length) > highestof(Host)) { + length = highestof(Host)-source->begin; + parms.rc = 0x0f; /* Truncate */ + } + if ((source->characteristics == target->characteristics) && + (source->session_type == target->session_type)) { + if (source->characteristics&CHARACTERISTIC_EAB) { + length *= 2; + } + movetothem(FP_SEG(target->buffer), + FP_OFF(target->buffer), + (char *)&Host[source->begin], length); + } else { + copy_subroutine(target, source, &parms, + USER_IS_TARGET, length); + } + } + } + } else if (source->session_id != BUF_SESSION_ID) { + parms.rc = 0xd; + } else { + /* Send to presentation space (3270 buffer) */ + if ((target->begin < 0) || (target->begin > highestof(Host))) { + parms.rc = 0x07; /* invalid target definition */ + } if (!UnLocked) { + parms.rc = 0x03; /* Keyboard locked */ + } else if (parms.copy_mode != 0) { + parms.rc = 0x0f; /* Copy of field attr's not allowed */ + } else if (IsProtected(target->begin) || /* Make sure no protected */ + (WhereAttrByte(target->begin) != /* in range */ + WhereAttrByte(target->begin+length-1))) { + parms.rc = 0x0e; /* Attempt to write in protected */ + } else { + if ((target->begin+length) > highestof(Host)) { + length = highestof(Host)-target->begin; + parms.rc = 0x0f; /* Truncate */ + } + TurnOnMdt(target->begin); /* Things have changed */ + if ((source->characteristics == target->characteristics) && + (source->session_type == target->session_type)) { + if (source->characteristics&CHARACTERISTIC_EAB) { + length *= 2; + } + movetous((char *)&Host[target->begin], + FP_SEG(source->buffer), + FP_OFF(source->buffer), length); + } else { + copy_subroutine(target, source, &parms, USER_IS_SOURCE, length); + } + } + } + parms.function_id = 0x64; + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +} + + +/* + * Operator Information Area Services. + */ + +static void +read_oia_group(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + ReadOiaGroupParms parms; + + movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); + + if ((parms.rc != 0) || (parms.function_id != 0)) { + parms.rc = 0x0c; + } else if (parms.session_id != PS_SESSION_ID) { + parms.rc = 0x02; + } else { + int group = parms.oia_group_number; + char *from; + int size; + + if ((group != API_OIA_ALL_GROUPS) && + ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) { + } else { + if (group == API_OIA_ALL_GROUPS) { + size = API_OIA_BYTES_ALL_GROUPS; + from = (char *)&OperatorInformationArea; + } else if (group == API_OIA_INPUT_INHIBITED) { + size = sizeof OperatorInformationArea.input_inhibited; + from = (char *)&OperatorInformationArea.input_inhibited[0]; + } else { + size = 1; + from = ((char *)&OperatorInformationArea)+group; + } + movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), + from, size); + } + } + parms.function_id = 0x6d; + movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); +} + +/*ARGSUSED*/ +static void +unknown_op(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ + regs->h.ch = 0x12; + regs->h.cl = 0x05; +} + + +handle_api(regs, sregs) +union REGS *regs; +struct SREGS *sregs; +{ +/* + * Do we need to log this transaction? + */ + if (apitrace) { + Dump('<', (char *)regs, sizeof *regs); + Dump('<', (char *)sregs, sizeof *sregs); + } + if (regs->h.ah == NAME_RESOLUTION) { + name_resolution(regs, sregs); +#if defined(unix) + } else if (regs->h.ah == PS_OR_OIA_MODIFIED) { + while ((oia_modified == 0) && (ps_modified == 0)) { + (void) Scheduler(1); + } + oia_modified = ps_modified = 0; +#endif /* defined(unix) */ + } else if (regs->h.ah != 0x09) { + regs->h.ch = 0x12; + regs->h.cl = 0x0f; /* XXX Invalid environmental access */ + } else if (regs->x.bx != 0x8020) { + regs->h.ch = 0x12; + regs->h.cl = 0x08; /* XXX Invalid wait specified */ + } else if (regs->h.ch != 0) { + regs->x.cx = 0x1206; /* XXX Invalid priority */ + } else { + switch (regs->x.dx) { + case GATE_SESSMGR: + switch (regs->h.al) { + case QUERY_SESSION_ID: + if (regs->h.cl != 0) { + regs->x.cx = 0x1206; + } else { + regs->x.cx = 0x1200; + query_session_id(regs, sregs); + } + break; + case QUERY_SESSION_PARAMETERS: + if (regs->h.cl != 0) { + regs->x.cx = 0x1206; + } else { + regs->x.cx = 0x1200; + query_session_parameters(regs, sregs); + } + break; + case QUERY_SESSION_CURSOR: + if ((regs->h.cl != 0xff) && (regs->h.cl != 0x00/*OBS*/)) { + regs->x.cx = 0x1206; + } else { + regs->x.cx = 0x1200; + query_session_cursor(regs, sregs); + } + break; + default: + unknown_op(regs, sregs); + break; + } + break; + case GATE_KEYBOARD: + if (regs->h.cl != 00) { + regs->x.cx = 0x1206; + } else { + regs->x.cx = 0x1200; + switch (regs->h.al) { + case CONNECT_TO_KEYBOARD: + connect_to_keyboard(regs, sregs); + break; + case DISABLE_INPUT: + disable_input(regs, sregs); + break; + case WRITE_KEYSTROKE: + write_keystroke(regs, sregs); + break; + case ENABLE_INPUT: + enable_input(regs, sregs); + break; + case DISCONNECT_FROM_KEYBOARD: + disconnect_from_keyboard(regs, sregs); + break; + default: + unknown_op(regs, sregs); + break; + } + } + break; + case GATE_COPY: + if (regs->h.cl != 0xff) { + regs->x.cx = 0x1206; + } else { + regs->x.cx = 0x1200; + switch (regs->h.al) { + case COPY_STRING: + copy_string(regs, sregs); + break; + default: + unknown_op(regs, sregs); + break; + } + } + break; + case GATE_OIAM: + if (regs->h.cl != 0xff) { + regs->x.cx = 0x1206; + } else { + regs->x.cx = 0x1200; + switch (regs->h.al) { + case READ_OIA_GROUP: + read_oia_group(regs, sregs); + break; + default: + unknown_op(regs, sregs); + break; + } + } + break; + default: + regs->h.ch = 0x12; + regs->h.cl = 0x34; /* Invalid GATE entry */ + break; + } + } +/* + * Do we need to log this transaction? + */ + if (apitrace) { + Dump('>', (char *)regs, sizeof *regs); + Dump('>', (char *)sregs, sizeof *sregs); +#ifdef MSDOS + { char buf[10]; gets(buf); } +#endif /* MSDOS */ + } +} diff --git a/usr.bin/tn3270/ctlr/api.h b/usr.bin/tn3270/ctlr/api.h new file mode 100644 index 00000000000..30fac649334 --- /dev/null +++ b/usr.bin/tn3270/ctlr/api.h @@ -0,0 +1,404 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)api.h 4.4 (Berkeley) 4/26/91 + * $Id: api.h,v 1.1 1995/10/18 08:46:20 deraadt Exp $ + */ + +/* + * This file contains header information used by the PC API routines. + */ + +#if !defined(MSDOS) +#define far /* For 'far *' checks */ +#endif /* !defined(MSDOS) */ + +#define API_INTERRUPT_NUMBER 0x7A /* API Interrupt Number */ + +/* + * Define the gate numbers. These are returned via the Name Resolution + * service. + */ + +#define GATE_SESSMGR 1234 +#define GATE_KEYBOARD 5678 +#define GATE_COPY 9101 +#define GATE_OIAM 1121 + +/* + * The names which correspond to the above gate numbers. + */ + +#define NAME_SESSMGR "SESSMGR " +#define NAME_KEYBOARD "KEYBOARD" +#define NAME_COPY "COPY " +#define NAME_OIAM "OIAM " + + +/* + * Name Resolution is specified in AH. + */ + +#define NAME_RESOLUTION 0x81 + +#if defined(unix) +/* + * In unix, we offer a service to allow the application to keep from + * having to poll us constantly. + */ +#define PS_OR_OIA_MODIFIED 0x99 + +#endif /* defined(unix) */ + +/* + * Codes specified in AL for various services. + */ + +#define QUERY_SESSION_ID 0x01 +#define QUERY_SESSION_PARAMETERS 0x02 +#define QUERY_SESSION_CURSOR 0x0b + +#define CONNECT_TO_KEYBOARD 0x01 +#define DISCONNECT_FROM_KEYBOARD 0x02 +#define WRITE_KEYSTROKE 0x04 +#define DISABLE_INPUT 0x05 +#define ENABLE_INPUT 0x06 + +#define COPY_STRING 0x01 + +#define READ_OIA_GROUP 0x02 + +/* + * For each service, we define the assoicated parameter blocks. + */ + +/* + * Supervisor Services + */ + +typedef struct { + char gate_name[8]; +} NameResolveParms; + + +/* + * Session Information Services + */ + +typedef struct { + char + short_name, + type, + session_id, + reserved, + long_name[8]; +} NameArrayElement; + +typedef struct { + unsigned char + length, + number_matching_session; + NameArrayElement + name_array_element; /* Variable number */ +} NameArray; + +typedef struct { + char + rc, + function_id, + option_code, + data_code; + NameArray far + *name_array; + char + long_name[8]; +} QuerySessionIdParms; + +#define ID_OPTION_BY_NAME 0x01 /* By short (or long) name */ +#define ID_OPTION_ALL 0x00 /* All (of specified type */ + +typedef struct { + char + rc, + function_id, + session_id, + reserved, + session_type, + session_characteristics, + rows, + columns; + char far + *presentation_space; +} QuerySessionParametersParms; + +#define TYPE_WSCTL 0x01 /* Work Station Control */ +#define TYPE_DFT 0x02 /* DFT Host Session */ +#define TYPE_CUT 0x03 /* CUT Host Session */ +#define TYPE_NOTEPAD 0x04 /* Notepad Session */ +#define TYPE_PC 0x05 /* Personal Computer Session */ + +#define CHARACTERISTIC_EAB 0x80 /* Extended Attribute Buffer */ +#define CHARACTERISTIC_PSS 0x40 /* Program Symbols Supported */ + +typedef struct { + char + rc, + function_id, + session_id, + cursor_type, + row_address, /* from 0 */ + column_address; /* from 0 */ +} QuerySessionCursorParms; + +#define CURSOR_INHIBITED_AUTOSCROLL 0x10 +#define CURSOR_INHIBITED 0x04 +#define CURSOR_BLINKING 0x02 +#define CURSOR_BOX 0x01 +typedef struct { + char + rc, + function_id, + session_id, + reserved; + short + event_queue_id, + input_queue_id; + char + intercept_options, + first_connection_identifier; +} ConnectToKeyboardParms; + +typedef struct { + char + rc, + function_id, + session_id, + reserved; + short + connectors_task_id; +} DisconnectFromKeyboardParms; + +typedef struct { + unsigned char + scancode, + shift_state; +} KeystrokeEntry; + +typedef struct { + short + length; /* Length (in bytes) of list */ + KeystrokeEntry keystrokes; /* Variable size */ +} KeystrokeList; + +typedef struct { + char + rc, + function_id, + session_id, + reserved; + short + connectors_task_id; + char + options, + number_of_keys_sent; + union { + KeystrokeEntry + keystroke_entry; + KeystrokeList far + *keystroke_list; + } keystroke_specifier; +} WriteKeystrokeParms; + +#define OPTION_SINGLE_KEYSTROKE 0x20 +#define OPTION_MULTIPLE_KEYSTROKES 0x30 + +typedef struct { + char + rc, + function_id, + session_id, + reserved; + short + connectors_task_id; +} DisableInputParms; + +typedef DisableInputParms EnableInputParms; + +typedef struct { + char + session_id, + reserved; + char far + *buffer; + char + characteristics, + session_type; + short + begin; /* Offset within buffer */ +} BufferDescriptor; + +typedef struct { + char + rc, + function_id; + BufferDescriptor + source; + short + source_end; /* Offset within source buffer */ + BufferDescriptor + target; + char + copy_mode, + reserved; +} CopyStringParms; + +#define COPY_MODE_7_COLOR 0x80 /* Else 4 color mode */ +#define COPY_MODE_FIELD_ATTRIBUTES 0x40 /* Else don't copy attributes */ + +typedef struct { + char + rc, + function_id, + session_id, + reserved; + char far + *oia_buffer; + char + oia_group_number; +} ReadOiaGroupParms; + +/* If the user wants all groups, we return API_OIA_BYTES_ALL_GROUPS bytes */ +#define API_OIA_ALL_GROUPS '\377' +#define API_OIA_BYTES_ALL_GROUPS 22 /* 22 bytes of data */ + +/* API_OIA_INPUT_INHIBITED is special. It returns more than on byte of data */ +#define API_OIA_INPUT_INHIBITED 8 + +#define API_OIA_LAST_LEGAL_GROUP 18 /* Highest legal number */ + + + +#if defined(MSDOS) + +#if !defined(FP_SEG) +#include <dos.h> +#endif /* !defined(FP_SEG) */ + +#else /* defined(MSDOS) */ + +/* + * These definitions are here to provide the descriptions of + * some registers which are, normally, defined in <dos.h> on + * a dos system. + */ + +#define FP_SEG(x) ((unsigned int)(((unsigned long)(x))>>16)) +#define FP_OFF(y) ((unsigned int)(((unsigned long)(y))&0xFFFF)) + +/* + * Undo the preceeding. + */ + +#define SEG_OFF_BACK(x,y) (((x)<<16)|(y)) + +/* + * Now, it is somewhat of a pain, but we need to keep + * 8086 conventions about which of the "highlow"'s map + * into which of the "words". + */ + +#include <sys/param.h> /* Get ENDIAN from machine/endian.h */ + +/* Determine endian'ess (if necessary) */ + +#if !(defined(BYTE_ORDER) && defined(BIG_ENDIAN)) +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ + +#if defined(vax) || defined(ns32000) || defined(i386) || (defined(mips)&&defined(MIPSEL)) +#define BYTE_ORDER LITTLE_ENDIAN +#endif /* defined(vax) || defined(ns32000) */ + +#if defined(sun) || defined(tahoe) || defined(ibm032) || defined(pyr) || defined(gould) || (defined(mips)&&defined(MIPSEB)) +#define BYTE_ORDER BIG_ENDIAN +#endif /* defined(sun) || defined(tahoe) || defined(ibm032) || defined(pyr) || defined(gould) */ + +#endif /* !(defined(BYTE_ORDER) && defined(BIG_ENDIAN)) */ + +struct highlow { + unsigned char +#if BYTE_ORDER == LITTLE_ENDIAN + al, + ah, + bl, + bh, + cl, + ch, + dl, + dh; +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +#if BYTE_ORDER == BIG_ENDIAN + ah, + al, + bh, + bl, + ch, + cl, + dh, + dl; +#endif /* BYTE_ORDER == BIG_ENDIAN */ +}; + +struct words { + unsigned short + ax, + bx, + cx, + dx; + unsigned short + si, + di; +}; + +union REGS { + struct highlow h; + struct words x; +}; + +struct SREGS { + unsigned short + cs, + ds, + es, + ss; +}; +#endif /* defined(MSDOS) (else section) */ diff --git a/usr.bin/tn3270/ctlr/ctlr.order b/usr.bin/tn3270/ctlr/ctlr.order new file mode 100644 index 00000000000..90fba838932 --- /dev/null +++ b/usr.bin/tn3270/ctlr/ctlr.order @@ -0,0 +1,5 @@ +api.o +inbound.o +oia.o +options.o +outbound.o diff --git a/usr.bin/tn3270/ctlr/declare.h b/usr.bin/tn3270/ctlr/declare.h new file mode 100644 index 00000000000..41320ef5743 --- /dev/null +++ b/usr.bin/tn3270/ctlr/declare.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)declare.h 4.2 (Berkeley) 4/26/91 + * $Id: declare.h,v 1.1 1995/10/18 08:46:20 deraadt Exp $ + */ + +/* + * Declarations of routines from the controller. + */ + +extern void + AddHost(), + DoReadModified(), + DoReadBuffer(), + OptInit(), + SendToIBM(), + SendTransparent(); + +extern int + DataFrom3270(), + DataFromNetwork(), + OptOrder(), + OutputClock, + TransparentClock; diff --git a/usr.bin/tn3270/ctlr/externs.h b/usr.bin/tn3270/ctlr/externs.h new file mode 100644 index 00000000000..ef703e9c729 --- /dev/null +++ b/usr.bin/tn3270/ctlr/externs.h @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)externs.h 4.2 (Berkeley) 4/26/91 + * $Id: externs.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $ + */ + +/* + * External references from the controller. + */ + +#if !defined(MSDOS) +extern char *access_api(); +extern void movetous(), movetothem(), unaccess_api(); +#endif /* !defined(MSDOS) */ + +extern unsigned char + *memNSchr(); /* Search for a character ANDED, increment by stride */ + +extern int + DataToNetwork(), + OutputClock, + suspend(), + TransparentClock, + UnLocked; /* keyboard is UnLocked? */ + +extern void + command(), + ConnectScreen(), + ExitString(), + init_inbound(), + LocalClearScreen(), + RefreshScreen(), + RingBell(), + setconnmode(), + StopScreen(), + TransOut(), + TransStop(); diff --git a/usr.bin/tn3270/ctlr/function.c b/usr.bin/tn3270/ctlr/function.c new file mode 100644 index 00000000000..437d7becdc7 --- /dev/null +++ b/usr.bin/tn3270/ctlr/function.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +/*static char sccsid[] = "from: @(#)function.c 4.2 (Berkeley) 4/26/91";*/ +static char rcsid[] = "$Id: function.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $"; +#endif /* not lint */ + +/* + * This file, which never produces a function.o, is used solely to + * be run through the preprocessor. + * + * On a 4.3 system (or even msdos), "cc -E function.h" would produce + * the correct output. Unfortunately, 4.2 compilers aren't quite that + * useful. + */ + +#include "function.h" diff --git a/usr.bin/tn3270/ctlr/function.h b/usr.bin/tn3270/ctlr/function.h new file mode 100644 index 00000000000..8366d5d1d81 --- /dev/null +++ b/usr.bin/tn3270/ctlr/function.h @@ -0,0 +1,167 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)function.h 4.2 (Berkeley) 4/26/91 + * $Id: function.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $ + */ + +/* + * The following are the various functions which the keyboard can ask + * the controller to perform. + * + * Note that this file (the following entries) are scanned by mkhit.c, + * and that the format must remain more-or-less consistent + * [ \t]*TOKEN + */ + +enum ctlrfcn { + + undefined = 0, /* Not yet touched */ + + FCN_NULL, /* Illegal sequence */ + + FCN_RESET, /* unlock keyboard */ + FCN_MAKE_SHIFT_LOCK, + FCN_BREAK_SHIFT_LOCK, + + FCN_MAKE_SHIFT, /* shift key pressed DOWN */ + FCN_BREAK_SHIFT, /* shift key released */ + + FCN_MAKE_ALT, /* alt key pressed DOWN */ + FCN_BREAK_ALT, /* alt key released */ + + FCN_MAKE_CTRL, + + FCN_CAPS_LOCK, + + FCN_MONOCASE, /* DISPLAY in upper case */ + FCN_DVCNL, + + FCN_CHARACTER, /* Not one of the following, but ... */ + FCN_VERTICAL_BAR, /* EBCDIC solid vertical bar */ + FCN_CENTSIGN, /* EBCDIC cent sign */ + FCN_SPACE, /* EBCDIC space */ + FCN_DP, /* EBCDIC dup character */ + FCN_FM, /* EBCDIC field mark */ + + FCN_AID, /* Some AID key */ + FCN_ATTN, + FCN_CURSEL, /* Cursor select function (and aid) */ + FCN_TEST, /* Test function */ + + FCN_EINP, /* erase input (dangerous) */ + FCN_EEOF, + FCN_DELETE, + FCN_INSRT, + FCN_TAB, + FCN_BTAB, + FCN_NL, + FCN_HOME, + FCN_UP, + FCN_DOWN, + FCN_RIGHT, + FCN_LEFT, + FCN_LEFT2, + FCN_RIGHT2, + +#if !defined(PURE3274) + /* + * Local editing functions + */ + FCN_SETTAB, /* set a column tab */ + FCN_DELTAB, + FCN_COLTAB, + FCN_COLBAK, + FCN_INDENT, /* more margin over one col tab */ + FCN_UNDENT, + FCN_SETMRG, + FCN_SETHOM, + FCN_CLRTAB, + FCN_ERASE, /* erase last character */ + FCN_WERASE, + FCN_FERASE, + FCN_WORDTAB, /* tab to start of next word */ + FCN_WORDBACKTAB, + FCN_WORDEND, /* find next end of word */ + FCN_FIELDEND, /* find next end of field */ + + /* + * APL functions + */ + FCN_APLON, /* start using apl character set */ + FCN_APLOFF, + FCN_APLEND, + + FCN_PCON, + FCN_PCOFF, + FCN_INIT, /* re-init screen */ + FCN_SYNCH, /* synch up after line/control error */ + FCN_FLINP, /* flush input buffer */ + FCN_RESHOW, /* redraw screen */ + FCN_MASTER_RESET, /* FLINP, RESET, RESHOW, + more */ + + FCN_DISC, /* suspend application */ + FCN_ESCAPE, /* enter command mode */ + + FCN_ALTK, /* Dvorak keyboard */ + + FCN_XOFF, /* suspend output to screen */ + FCN_XON, /* resume output to screen */ + + FCN_LPRT /* print screen on printer */ +#endif /* !defined(PURE3274) */ +}; +/* + * The following is the structure which defines what a 3270 keystroke + * can do. + */ + +struct hits { + unsigned char keynumber; + struct hit { + enum ctlrfcn ctlrfcn; + unsigned char code; /* AID value or 3270 display code */ + } hit[4]; /* plain, shifted, alted, shiftalted */ +}; + +extern struct hits hits[]; + +/* + * Definitions of the shift state (and the left/right shift key position). + */ + +#define SHIFT_RIGHT 0x20 /* Right shift key is down */ +#define SHIFT_LEFT 0x10 /* Left shift key is down */ +#define SHIFT_CONTROL 0x08 /* Control shift state (unused) */ +#define SHIFT_ALT 0x04 /* ALT shift state */ +#define SHIFT_CAPS 0x02 /* Caps lock state */ +#define SHIFT_UPSHIFT 0x01 /* Upshift state */ diff --git a/usr.bin/tn3270/ctlr/hostctlr.h b/usr.bin/tn3270/ctlr/hostctlr.h new file mode 100644 index 00000000000..21358db89f4 --- /dev/null +++ b/usr.bin/tn3270/ctlr/hostctlr.h @@ -0,0 +1,223 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)hostctlr.h 4.2 (Berkeley) 4/26/91 + * $Id: hostctlr.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $ + */ + +#define INCLUDED_HOST3270 + +/* define orders given to 3270's */ + +#define ORDER_SF 0x1d /* Start Field */ +#define ORDER_SFE 0x29 /* Start Field Extended */ +#define ORDER_SBA 0x11 /* Set Buffer Address (for output) */ +#define ORDER_SA 0x28 /* Set Attribute */ +#define ORDER_MF 0x2c /* Modify field */ +#define ORDER_IC 0x13 /* Insert Cursor (at buffer address) */ +#define ORDER_PT 0x05 /* Program Tab (absurdly complicated) */ +#define ORDER_RA 0x3c /* Repeat next character to some addr */ +#define ORDER_EUA 0x12 /* Null out every unprotected field + * to some address. + */ +#define ORDER_GE 0x08 /* Graphics Escape */ +#define ORDER_YALE 0x2b /* This is a special YALE order, which + * introduces YALE extended orders + * (like setting tabs, etc.). + */ + +/* The following is defined for initialization and error messages. */ + +struct orders_def { + int + code; /* As in 3270 data stream */ + char + *short_name, /* Short name */ + *long_name; /* Long name */ +}; + +#define ORDERS_DEF { \ + ORDER_SF, "SF", "Start Field", \ + ORDER_SFE, "SFE", "Start Field Extended", \ + ORDER_SBA, "SBA", "Set Buffer Address", \ + ORDER_SA, "SA", "Set Attribute", \ + ORDER_MF, "MF", "Modify Field", \ + ORDER_IC, "IC", "Insert Cursor", \ + ORDER_PT, "PT", "Program Tab", \ + ORDER_RA, "RA", "Repeat to Address", \ + ORDER_EUA, "EUA", "Erase Unprotected to Address", \ + ORDER_GE, "GE", "Graphics Escape", \ + ORDER_YALE, "YALE", "Yale Order" \ + } + + +#define ATTR_RESET 0x00 /* SA only - reset to default */ +# define ATTR_DEFAULT 0x00 /* reset to default */ + /* Also for 0x41-43 below */ +#define ATTR_FIELD 0xC0 /* Field attributes */ +# define ATTR_MASK 0xc0 /* control bits */ +# define ATTR_PROT 0x20 /* protected bit */ +# define ATTR_NUMERIC 0x10 /* numeric field */ +# define ATTR_AUTO_SKIP_MASK 0x30 /* mask to check auto skip */ +# define ATTR_AUTO_SKIP_VALUE 0x30 /* value to have auto skip */ +# define ATTR_DSPD_MASK 0x0c /* highlighting, etc. */ +# define ATTR_DSPD_DNSPD 0x00 /* display, no select */ +# define ATTR_DSPD_DSPD 0x04 /* display, select */ +# define ATTR_DSPD_HIGH 0x08 /* highlighted, select */ +# define ATTR_DSPD_NONDISPLAY 0x0c /* non-display, no select */ +# define ATTR_MDT 0x01 /* modified data tag */ + +#define ATTR_EXTENDED_HIGHLIGHT 0x41 /* Extended highlighting */ +# define ATTR_BLINK 0xf1 /* Blinking */ +# define ATTR_REVERSE_VIDEO 0xf2 /* Reverse video */ +# define ATTR_UNDERSCORE 0xf3 /* Underline */ +#define ATTR_COLOR 0x42 /* Color */ +# define ATTR_BLUE 0xf1 +# define ATTR_RED 0xf2 +# define ATTR_PINK 0xf3 +# define ATTR_GREEN 0xf4 +# define ATTR_TURQUOISE 0xf5 +# define ATTR_YELLOW 0xf6 +# define ATTR_WHITE 0xf7 /* for 3279; black for 3287; */ + /* multicolor for triple */ + /* plane symbol */ +#define ATTR_PROGRAMMED_SYMBOLS 0x43 /* Programmed Symbols */ +# define ATTR_SYMBOL_SET_LOW 0x40 /* Lowest loadable set ID */ +# define ATTR_SYMBOL_SET_HIGH 0xef /* Highest loadable set ID */ +# define ATTR_SYMBOL_SET_APLTEXT 0xf1 + +/* Non-SNA control unit commands */ + +#define CMD_ERASE_ALL_UNPROTECTED 0x0f +#define CMD_ERASE_WRITE 0x05 +#define CMD_ERASE_WRITE_ALTERNATE 0x0d +#define CMD_READ_BUFFER 0x02 +#define CMD_READ_MODIFIED 0x06 +#define CMD_WRITE 0x01 +#define CMD_WRITE_STRUCTURED_FIELD 0x11 + +/* SNA control unit commands */ + +#define CMD_SNA_COPY 0xf7 +#define CMD_SNA_ERASE_ALL_UNPROTECTED 0x6f +#define CMD_SNA_ERASE_WRITE 0xf5 +#define CMD_SNA_ERASE_WRITE_ALTERNATE 0x7e +#define CMD_SNA_READ_BUFFER 0xf2 +#define CMD_SNA_READ_MODIFIED 0xf6 +#define CMD_SNA_READ_MODIFIED_ALL 0x6e +#define CMD_SNA_WRITE 0xf1 +#define CMD_SNA_WRITE_STRUCTURED_FIELD 0xf3 + + +#define WCC_RESET 0x40 +#define WCC_ALARM 0x04 +#define WCC_RESTORE 0x02 +#define WCC_RESET_MDT 0x01 + + +/* Special EBCDIC characters unique to a 3270 */ + +#define EBCDIC_BLANK 0x40 /* Space */ +#define EBCDIC_CENTSIGN 0x4a /* Cent sign */ +#define EBCDIC_DUP 0x1c /* DUP character */ +#define EBCDIC_FM 0x1e /* Field mark character */ +#define EBCDIC_PERCENT 0x6c /* Percent sign */ +#define EBCDIC_SLASH 0x61 /* Slash */ +#define EBCDIC_SOH 0x01 /* Start of Heading */ +#define EBCDIC_STX 0x02 /* Start of Text */ + +/* Structured field types */ +#define SF_3270DS 0x40 /* For write operations */ +#define SF_LPS 0x06 /* Load Programmed Symbols */ +#define SF_SRM 0x09 /* Set Reply Mode */ +#define SF_SWO 0x0b /* Set Window Origin */ +#define SF_READ_PARTITION 0x01 /* Read Partition (Query) */ +#define SF_ERASE_RESET 0x03 /* Erase (and/or Reset) */ +#define SF_SCS_DATA 0x41 /* SCS Data */ +#define SF_CREATE_PARTITION 0x0c /* Create a partition */ + +/* AID characters sent to host. + * + * Note that this file (the following entries) are scanned by mkhit.c, + * and that the format must remain more-or-less consistent + * (#define\tAID_name\t[\t]*TOKEN) + */ + +#define AID_NONE 0x60 /* No AID (display) */ +#define AID_NONE_PRINTER 0xe8 /* No AID (printer) */ + +#define AID_PA1 0x6c +#define AID_PA2 0x6e +#define AID_PA3 0x6b +#define AID_CLEAR 0x6d +#define AID_TREQ 0xf0 +#define AID_ENTER 0x7d +#define AID_SELPEN 0x7e /* + * Really, only SELPEN with DESIGNATOR + * = space or null + */ +#define AID_PF1 0xf1 +#define AID_PF2 0xf2 +#define AID_PF3 0xf3 +#define AID_PF4 0xf4 +#define AID_PF5 0xf5 +#define AID_PF6 0xf6 +#define AID_PF7 0xf7 +#define AID_PF8 0xf8 +#define AID_PF9 0xf9 +#define AID_PF10 0x7a +#define AID_PF11 0x7b +#define AID_PF12 0x7c +#define AID_PF13 0xc1 +#define AID_PF14 0xc2 +#define AID_PF15 0xc3 +#define AID_PF16 0xc4 +#define AID_PF17 0xc5 +#define AID_PF18 0xc6 +#define AID_PF19 0xc7 +#define AID_PF20 0xc8 +#define AID_PF21 0xc9 +#define AID_PF22 0x4a +#define AID_PF23 0x4b +#define AID_PF24 0x4c +#define AID_PF25 0xd1 +#define AID_PF26 0xd2 +#define AID_PF27 0xd3 +#define AID_PF28 0xd4 +#define AID_PF29 0xd5 +#define AID_PF30 0xd6 +#define AID_PF31 0xd7 +#define AID_PF32 0xd8 +#define AID_PF33 0xd9 +#define AID_PF34 0x5a +#define AID_PF35 0x5b +#define AID_PF36 0x5c diff --git a/usr.bin/tn3270/ctlr/inbound.c b/usr.bin/tn3270/ctlr/inbound.c new file mode 100644 index 00000000000..babadac867b --- /dev/null +++ b/usr.bin/tn3270/ctlr/inbound.c @@ -0,0 +1,1195 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +/*static char sccsid[] = "from: @(#)inbound.c 4.3 (Berkeley) 4/26/91";*/ +static char rcsid[] = "$Id: inbound.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $"; +#endif /* not lint */ + +#include <stdio.h> + +#include "../general/general.h" +#include "function.h" +#include "hostctlr.h" +#include "oia.h" +#include "scrnctlr.h" +#include "screen.h" +#include "options.h" +#include "../api/dctype.h" +#include "../api/ebc_disp.h" + +#include "../general/globals.h" +#include "externs.h" +#include "declare.h" + +#define EmptyChar() (ourPTail == ourPHead) +#define FullChar() (ourPHead == ourBuffer+sizeof ourBuffer) + + +/* + * We define something to allow us to to IsProtected() quickly + * on unformatted screens (with the current algorithm for fields, + * unprotected takes exponential time...). + * + * The idea is to call SetXIsProtected() BEFORE the + * loop, then use XIsProtected(). + */ + +#define SetXIsProtected() (XWasSF = 1) +#define XIsProtected(p) (IsStartField(p)? \ + XWasSF = 1 : \ + (XWasSF? \ + (XWasSF = 0, XProtected = IsProtected(p)) : \ + XProtected)) + +static char ourBuffer[400]; + +static char *ourPHead = ourBuffer, + *ourPTail = ourBuffer; + +static int HadAid; /* Had an AID haven't sent */ + +static int InsertMode; /* is the terminal in insert mode? */ + +static unsigned int + rememberedshiftstate; /* Shift (alt) state of terminal */ + +# define HITNUM(s) ((((s)&(SHIFT_CAPS|SHIFT_UPSHIFT))? 1:0) \ + + ((((s)&SHIFT_ALT)? 1:0)<<1)) + +static int XWasSF, XProtected; /* For optimizations */ +#if !defined(PURE3274) +extern int TransparentClock, OutputClock; +#endif /* !defined(PURE3274) */ + +#include "kbd.out" /* Get keyboard mapping function */ + +/* the following are global variables */ + +extern int UnLocked; /* keyboard is UnLocked? */ + + +/* + * init_inbound : + * + * Reset variables to initial state. + */ + +void +init_inbound() +{ + ourPHead = ourPTail = ourBuffer; + HadAid = 0; + rememberedshiftstate = 0; + InsertMode = 0; +} + + +/* Tab() - sets cursor to the start of the next unprotected field */ +static void +Tab() +{ + register int i, j; + + i = CursorAddress; + j = WhereAttrByte(CursorAddress); + do { + if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { + break; + } + i = FieldInc(i); + } while (i != j); + if (IsStartField(i) && IsUnProtected(ScreenInc(i))) { + CursorAddress = ScreenInc(i); + } else { + CursorAddress = SetBufferAddress(0,0); + } +} + + +/* BackTab() - sets cursor to the start of the most recent field */ + +static void +BackTab() +{ + register int i; + + i = ScreenDec(CursorAddress); + for (;;) { + if (IsStartField(ScreenDec(i)) && IsUnProtected(i)) { + CursorAddress = i; + break; + } + if (i == CursorAddress) { + CursorAddress = SetBufferAddress(0,0); + break; + } + i = ScreenDec(i); + } +} + +/* + * ModifyMdt() - Turn a modified data tag bit on or off (watch + * out for unformatted screens). + */ + +ModifyMdt(x,on) +int x; +int on; +{ + int i = x; + + if (IsStartField(i)) { /* If we are at a start field position... */ + if (on) { + ModifyHost(i, |= ATTR_MDT); /* Turn it on */ + } else { + ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */ + } + } else { + i = WhereAttrByte(i); /* Find beginning of field */ + if (IsStartField(i)) { /* Is there one? */ + if (on) { + ModifyHost(i, |= ATTR_MDT); /* Turn it on */ + } else { + ModifyHost(i, &= ~ATTR_MDT); /* Turn it off */ + } + } /* else, don't modify - this is an unformatted screen */ + } +} + + +/* EraseEndOfField - erase all characters to the end of a field */ + +static void +EraseEndOfField() +{ + register int i; + + if (IsProtected(CursorAddress)) { + RingBell("Protected Field"); + } else { + TurnOnMdt(CursorAddress); + if (FormattedScreen()) { + i = CursorAddress; + do { + AddHost(i, 0); + i = ScreenInc(i); + } while ((i != CursorAddress) && !IsStartField(i)); + } else { /* Screen is Unformatted */ + i = CursorAddress; + do { + AddHost(i, 0); + i = ScreenInc(i); + } while (i != HighestScreen()); + } + } +} + +/* Delete() - deletes a character from the screen + * + * What we want to do is delete the section + * [where, from-1] from the screen, + * filling in with what comes at from. + * + * The deleting continues to the end of the field (or + * until the cursor wraps). + * + * From can be a start of a field. We + * check for that. However, there can't be any + * fields that start between where and from. + * We don't check for that. + * + * Also, we assume that the protection status of + * everything has been checked by the caller. + * + */ + +static void +Delete(where, from) +register int where, /* Where to start deleting from */ + from; /* Where to pull back from */ +{ + register int i; + + TurnOnMdt(where); /* Only do this once in this field */ + i = where; + do { + if (IsStartField(from)) { + AddHost(i, 0); /* Stick the edge at the start field */ + } else { + AddHost(i, (char)GetHost(from)); + from = ScreenInc(from); /* Move the edge */ + } + i = ScreenInc(i); + } while ((!IsStartField(i)) && (i != where)); +} + +static void +ColBak() +{ + register int i; + + i = ScreenLineOffset(CursorAddress); + for (i = i-1; i >= 0; i--) { + if (OptColTabs[i]) { + break; + } + } + if (i < 0) { + i = 0; + } + CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); +} + +static void +ColTab() +{ + register int i; + + i = ScreenLineOffset(CursorAddress); + for (i = i+1; i < NumberColumns; i++) { + if (OptColTabs[i]) { + break; + } + } + if (i >= NumberColumns) { + i = NumberColumns-1; + } + CursorAddress = SetBufferAddress(ScreenLine(CursorAddress), i); +} + +static void +Home() +{ + register int i; + register int j; + + i = SetBufferAddress(OptHome, 0); + j = WhereLowByte(i); + /* + * If the initial value of i points to the field attribute of + * an unprotected field, we need to return the address of the + * first data byte in the field (assuming there are any!). + */ + if (IsStartField(i) && IsUnProtected(j)) { + CursorAddress = j; + return; + } + do { + if (IsUnProtected(i)) { + CursorAddress = i; + return; + } + /* the following could be a problem if we got here with an + * unformatted screen. However, this is "impossible", since + * with an unformatted screen, the IsUnProtected(i) above + * should be true. + */ + i = ScreenInc(FieldInc(i)); + } while (i != j); + CursorAddress = LowestScreen(); +} + +static +LastOfField(i) +register int i; /* position to start from */ +{ + register int j; + register int k; + + k = j = i; + SetXIsProtected(); + while (XIsProtected(i) || Disspace(GetHost(i))) { + i = ScreenInc(i); + if (i == j) { + break; + } + } + /* We are now IN a word IN an unprotected field (or wrapped) */ + while (!XIsProtected(i)) { + if (!Disspace(GetHost(i))) { + k = i; + } + i = ScreenInc(i); + if (i == j) { + break; + } + } + return(k); +} + + +static void +FlushChar() +{ + ourPTail = ourPHead = ourBuffer; +} + + +/* + * Add one EBCDIC (NOT display code) character to the buffer. + */ + +static void +AddChar(character) +char character; +{ + if (FullChar()) { + ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 0); + if (EmptyChar()) { + FlushChar(); + } else { + char buffer[100]; + + sprintf(buffer, "File %s, line %d: No room in network buffer!\n", + __FILE__, __LINE__); + ExitString(buffer, 1); + /*NOTREACHED*/ + } + } + *ourPHead++ = character; +} + + +static void +SendUnformatted() +{ + register int i, j; + register int Nulls; + register int c; + + /* look for start of field */ + Nulls = 0; + i = j = LowestScreen(); + do { + c = GetHost(i); + if (c == 0) { + Nulls++; + } else { + while (Nulls) { + Nulls--; + AddChar(EBCDIC_BLANK); /* put in blanks */ + } + AddChar((char)disp_ebc[c]); + } + i = ScreenInc(i); + } while (i != j); +} + +static +SendField(i, cmd) +register int i; /* where we saw MDT bit */ +int cmd; /* The command code (type of read) */ +{ + register int j; + register int k; + register int Nulls; + register int c; + + /* look for start of field */ + i = j = WhereLowByte(i); + + /* On a test_request_read, don't send sba and address */ + if ((AidByte != AID_TREQ) + || (cmd == CMD_SNA_READ_MODIFIED_ALL)) { + AddChar(ORDER_SBA); /* set start field */ + AddChar(BufferTo3270_0(j)); /* set address of this field */ + AddChar(BufferTo3270_1(j)); + } + /* + * Only on read_modified_all do we return the contents + * of the field when the attention was caused by a + * selector pen. + */ + if ((AidByte != AID_SELPEN) + || (cmd == CMD_SNA_READ_MODIFIED_ALL)) { + if (!IsStartField(j)) { + Nulls = 0; + k = ScreenInc(WhereHighByte(j)); + do { + c = GetHost(j); + if (c == 0) { + Nulls++; + } else { + while (Nulls) { + Nulls--; + AddChar(EBCDIC_BLANK); /* put in blanks */ + } + AddChar((char)disp_ebc[c]); + } + j = ScreenInc(j); + } while ((j != k) && (j != i)); + } + } else { + j = FieldInc(j); + } + return(j); +} + +/* Various types of reads... */ +void +DoReadModified(cmd) +int cmd; /* The command sent */ +{ + register int i, j; + + if (AidByte) { + if (AidByte != AID_TREQ) { + AddChar(AidByte); + } else { + /* Test Request Read header */ + AddChar(EBCDIC_SOH); + AddChar(EBCDIC_PERCENT); + AddChar(EBCDIC_SLASH); + AddChar(EBCDIC_STX); + } + } else { + AddChar(AID_NONE); + } + if (((AidByte != AID_PA1) && (AidByte != AID_PA2) + && (AidByte != AID_PA3) && (AidByte != AID_CLEAR)) + || (cmd == CMD_SNA_READ_MODIFIED_ALL)) { + if ((AidByte != AID_TREQ) + || (cmd == CMD_SNA_READ_MODIFIED_ALL)) { + /* Test request read_modified doesn't give cursor address */ + AddChar(BufferTo3270_0(CursorAddress)); + AddChar(BufferTo3270_1(CursorAddress)); + } + i = j = WhereAttrByte(LowestScreen()); + /* Is this an unformatted screen? */ + if (!IsStartField(i)) { /* yes, handle separate */ + SendUnformatted(); + } else { + do { + if (HasMdt(i)) { + i = SendField(i, cmd); + } else { + i = FieldInc(i); + } + } while (i != j); + } + } + ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); + if (EmptyChar()) { + FlushChar(); + HadAid = 0; /* killed that buffer */ + } +} + +/* A read buffer operation... */ + +void +DoReadBuffer() +{ + register int i, j; + + if (AidByte) { + AddChar(AidByte); + } else { + AddChar(AID_NONE); + } + AddChar(BufferTo3270_0(CursorAddress)); + AddChar(BufferTo3270_1(CursorAddress)); + i = j = LowestScreen(); + do { + if (IsStartField(i)) { + AddChar(ORDER_SF); + AddChar(BufferTo3270_1(FieldAttributes(i))); + } else { + AddChar((char)disp_ebc[GetHost(i)]); + } + i = ScreenInc(i); + } while (i != j); + ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); + if (EmptyChar()) { + FlushChar(); + HadAid = 0; /* killed that buffer */ + } +} + +/* Send some transparent data to the host */ + +void +SendTransparent(buffer, count) +char *buffer; +int count; +{ + char stuff[3]; + + stuff[0] = AID_NONE_PRINTER; + stuff[1] = BufferTo3270_0(count); + stuff[2] = BufferTo3270_1(count); + DataToNetwork(stuff, sizeof stuff, 0); + DataToNetwork(buffer, count, 1); +} + + +/* Try to send some data to host */ + +void +SendToIBM() +{ +#if !defined(PURE3274) + if (TransparentClock >= OutputClock) { + if (HadAid) { + AddChar(AidByte); + HadAid = 0; + } else { + AddChar(AID_NONE_PRINTER); + } + do { + ourPTail += DataToNetwork(ourPTail, ourPHead-ourPTail, 1); + } while (!EmptyChar()); + FlushChar(); + } else if (HadAid) { + DoReadModified(CMD_READ_MODIFIED); + } +#else /* !defined(PURE3274) */ + if (HadAid) { + DoReadModified(CMD_READ_MODIFIED); + } +#endif /* !defined(PURE3274) */ +} + +/* This takes in one character from the keyboard and places it on the + * screen. + */ + +static void +OneCharacter(c, insert) +int c; /* character (Ebcdic) to be shoved in */ +int insert; /* are we in insert mode? */ +{ + register int i, j; + + if (IsProtected(CursorAddress)) { + RingBell("Protected Field"); + return; + } + if (insert) { + /* is the last character in the field a blank or null? */ + i = ScreenDec(FieldInc(CursorAddress)); + j = GetHost(i); + if (!Disspace(j)) { + RingBell("No more room for insert"); + return; + } else { + for (j = ScreenDec(i); i != CursorAddress; + j = ScreenDec(j), i = ScreenDec(i)) { + AddHost(i, (char)GetHost(j)); + } + } + } + AddHost(CursorAddress, c); + TurnOnMdt(CursorAddress); + CursorAddress = ScreenInc(CursorAddress); + if (IsStartField(CursorAddress) && + ((FieldAttributes(CursorAddress)&ATTR_AUTO_SKIP_MASK) == + ATTR_AUTO_SKIP_VALUE)) { + Tab(); + } +} + +/* + * AcceptKeystroke() + * + * Processes one keystroke. + * + * Returns: + * + * 0 if this keystroke was NOT processed. + * 1 if everything went OK. + */ + +int +AcceptKeystroke(scancode, shiftstate) +unsigned int + scancode, /* 3270 scancode */ + shiftstate; /* The shift state */ +{ + register int c; + register int i; + register int j; + enum ctlrfcn ctlrfcn; + + if (scancode >= numberof(hits)) { + ExitString( + "Unknown scancode encountered in AcceptKeystroke.\n", 1); + /*NOTREACHED*/ + } + ctlrfcn = hits[scancode].hit[HITNUM(shiftstate)].ctlrfcn; + c = hits[scancode].hit[HITNUM(shiftstate)].code; + + if (!UnLocked || HadAid) { + if (HadAid) { + SendToIBM(); + if (!EmptyChar()) { + return 0; /* nothing to do */ + } + } +#if !defined(PURE3274) + if (!HadAid && EmptyChar()) { + if ((ctlrfcn == FCN_RESET) || (ctlrfcn == FCN_MASTER_RESET)) { + UnLocked = 1; + } + } +#endif /* !defined(PURE3274) */ + if (!UnLocked) { + return 0; + } + } + + /* now, either empty, or haven't seen aid yet */ + +#if !defined(PURE3274) + /* + * If we are in transparent (output) mode, do something special + * with keystrokes. + */ + if (TransparentClock == OutputClock) { + if (ctlrfcn == FCN_AID) { + UnLocked = 0; + InsertMode = 0; + AidByte = (c); + HadAid = 1; + } else { + switch (ctlrfcn) { + case FCN_ESCAPE: + StopScreen(1); + command(0, NULL, 0); + if (shell_active == 0) { + ConnectScreen(); + } + break; + + case FCN_RESET: + case FCN_MASTER_RESET: + UnLocked = 1; + break; + + default: + return 0; + } + } + } +#endif /* !defined(PURE3274) */ + + if (ctlrfcn == FCN_CHARACTER) { + /* Add the character to the buffer */ + OneCharacter(c, InsertMode); + } else if (ctlrfcn == FCN_AID) { /* got Aid */ + if (c == AID_CLEAR) { + LocalClearScreen(); /* Side effect is to clear 3270 */ + } + ResetOiaOnlineA(&OperatorInformationArea); + SetOiaTWait(&OperatorInformationArea); + ResetOiaInsert(&OperatorInformationArea); + InsertMode = 0; /* just like a 3278 */ + SetOiaSystemLocked(&OperatorInformationArea); + SetOiaModified(); + UnLocked = 0; + AidByte = c; + HadAid = 1; + SendToIBM(); + } else { + switch (ctlrfcn) { + + case FCN_CURSEL: + c = FieldAttributes(CursorAddress)&ATTR_DSPD_MASK; + if (!FormattedScreen() + || ((c != ATTR_DSPD_DSPD) && (c != ATTR_DSPD_HIGH))) { + RingBell("Cursor not in selectable field"); + } else { + i = ScreenInc(WhereAttrByte(CursorAddress)); + c = GetHost(i); + if (c == DISP_QUESTION) { + AddHost(i, DISP_GREATER_THAN); + TurnOnMdt(i); + } else if (c == DISP_GREATER_THAN) { + AddHost(i, DISP_QUESTION); + TurnOffMdt(i); + } else if (c == DISP_BLANK || c == DISP_NULL + || c == DISP_AMPERSAND) { + UnLocked = 0; + InsertMode = 0; + ResetOiaOnlineA(&OperatorInformationArea); + SetOiaTWait(&OperatorInformationArea); + SetOiaSystemLocked(&OperatorInformationArea); + ResetOiaInsert(&OperatorInformationArea); + SetOiaModified(); + if (c == DISP_AMPERSAND) { + TurnOnMdt(i); /* Only for & type */ + AidByte = AID_ENTER; + } else { + AidByte = AID_SELPEN; + } + HadAid = 1; + SendToIBM(); + } else { + RingBell( + "Cursor not in a selectable field (designator)"); + } + } + break; + +#if !defined(PURE3274) + case FCN_ERASE: + if (IsProtected(ScreenDec(CursorAddress))) { + RingBell("Protected Field"); + } else { + CursorAddress = ScreenDec(CursorAddress); + Delete(CursorAddress, ScreenInc(CursorAddress)); + } + break; + case FCN_WERASE: + j = CursorAddress; + i = ScreenDec(j); + if (IsProtected(i)) { + RingBell("Protected Field"); + } else { + SetXIsProtected(); + while ((!XIsProtected(i) && Disspace(GetHost(i))) + && (i != j)) { + i = ScreenDec(i); + } + /* we are pointing at a character in a word, or + * at a protected position + */ + while ((!XIsProtected(i) && !Disspace(GetHost(i))) + && (i != j)) { + i = ScreenDec(i); + } + /* we are pointing at a space, or at a protected + * position + */ + CursorAddress = ScreenInc(i); + Delete(CursorAddress, j); + } + break; + + case FCN_FERASE: + if (IsProtected(CursorAddress)) { + RingBell("Protected Field"); + } else { + CursorAddress = ScreenInc(CursorAddress); /* for btab */ + BackTab(); + EraseEndOfField(); + } + break; + + case FCN_RESET: + if (InsertMode) { + InsertMode = 0; + ResetOiaInsert(&OperatorInformationArea); + SetOiaModified(); + } + break; + case FCN_MASTER_RESET: + if (InsertMode) { + InsertMode = 0; + ResetOiaInsert(&OperatorInformationArea); + SetOiaModified(); + } + RefreshScreen(); + break; +#endif /* !defined(PURE3274) */ + + case FCN_UP: + CursorAddress = ScreenUp(CursorAddress); + break; + + case FCN_LEFT: + CursorAddress = ScreenDec(CursorAddress); + break; + + case FCN_RIGHT: + CursorAddress = ScreenInc(CursorAddress); + break; + + case FCN_DOWN: + CursorAddress = ScreenDown(CursorAddress); + break; + + case FCN_DELETE: + if (IsProtected(CursorAddress)) { + RingBell("Protected Field"); + } else { + Delete(CursorAddress, ScreenInc(CursorAddress)); + } + break; + + case FCN_INSRT: + InsertMode = !InsertMode; + if (InsertMode) { + SetOiaInsert(&OperatorInformationArea); + } else { + ResetOiaInsert(&OperatorInformationArea); + } + SetOiaModified(); + break; + + case FCN_HOME: + Home(); + break; + + case FCN_NL: + /* The algorithm is to look for the first unprotected + * column after column 0 of the following line. Having + * found that unprotected column, we check whether the + * cursor-address-at-entry is at or to the right of the + * LeftMargin AND the LeftMargin column of the found line + * is unprotected. If this conjunction is true, then + * we set the found pointer to the address of the LeftMargin + * column in the found line. + * Then, we set the cursor address to the found address. + */ + i = SetBufferAddress(ScreenLine(ScreenDown(CursorAddress)), 0); + j = ScreenInc(WhereAttrByte(CursorAddress)); + do { + if (IsUnProtected(i)) { + break; + } + /* Again (see comment in Home()), this COULD be a problem + * with an unformatted screen. + */ + /* If there was a field with only an attribute byte, + * we may be pointing to the attribute byte of the NEXT + * field, so just look at the next byte. + */ + if (IsStartField(i)) { + i = ScreenInc(i); + } else { + i = ScreenInc(FieldInc(i)); + } + } while (i != j); + if (!IsUnProtected(i)) { /* couldn't find unprotected */ + i = SetBufferAddress(0,0); + } + if (OptLeftMargin <= ScreenLineOffset(CursorAddress)) { + if (IsUnProtected(SetBufferAddress(ScreenLine(i), + OptLeftMargin))) { + i = SetBufferAddress(ScreenLine(i), OptLeftMargin); + } + } + CursorAddress = i; + break; + + case FCN_EINP: + if (!FormattedScreen()) { + i = CursorAddress; + TurnOffMdt(i); + do { + AddHost(i, 0); + i = ScreenInc(i); + } while (i != CursorAddress); + } else { + /* + * The algorithm is: go through each unprotected + * field on the screen, clearing it out. When + * we are at the start of a field, skip that field + * if its contents are protected. + */ + i = j = FieldInc(CursorAddress); + do { + if (IsUnProtected(ScreenInc(i))) { + i = ScreenInc(i); + TurnOffMdt(i); + do { + AddHost(i, 0); + i = ScreenInc(i); + } while (!IsStartField(i)); + } else { + i = FieldInc(i); + } + } while (i != j); + } + Home(); + break; + + case FCN_EEOF: + EraseEndOfField(); + break; + + case FCN_SPACE: + OneCharacter(DISP_BLANK, InsertMode); /* Add cent */ + break; + + case FCN_CENTSIGN: + OneCharacter(DISP_CENTSIGN, InsertMode); /* Add cent */ + break; + + case FCN_FM: + OneCharacter(DISP_FM, InsertMode); /* Add field mark */ + break; + + case FCN_DP: + if (IsProtected(CursorAddress)) { + RingBell("Protected Field"); + } else { + OneCharacter(DISP_DUP, InsertMode);/* Add dup character */ + Tab(); + } + break; + + case FCN_TAB: + Tab(); + break; + + case FCN_BTAB: + BackTab(); + break; + +#ifdef NOTUSED /* Actually, this is superseded by unix flow + * control. + */ + case FCN_XOFF: + Flow = 0; /* stop output */ + break; + + case FCN_XON: + if (!Flow) { + Flow = 1; /* turn it back on */ + DoTerminalOutput(); + } + break; +#endif /* NOTUSED */ + +#if !defined(PURE3274) + case FCN_ESCAPE: + /* FlushChar(); do we want to flush characters from before? */ + StopScreen(1); + command(0, NULL, 0); + if (shell_active == 0) { + ConnectScreen(); + } + break; + + case FCN_DISC: + StopScreen(1); + suspend(); + setconnmode(); + ConnectScreen(); + break; + + case FCN_RESHOW: + RefreshScreen(); + break; + + case FCN_SETTAB: + OptColTabs[ScreenLineOffset(CursorAddress)] = 1; + break; + + case FCN_DELTAB: + OptColTabs[ScreenLineOffset(CursorAddress)] = 0; + break; + + /* + * Clear all tabs, home line, and left margin. + */ + case FCN_CLRTAB: + for (i = 0; i < sizeof OptColTabs; i++) { + OptColTabs[i] = 0; + } + OptHome = 0; + OptLeftMargin = 0; + break; + + case FCN_COLTAB: + ColTab(); + break; + + case FCN_COLBAK: + ColBak(); + break; + + case FCN_INDENT: + ColTab(); + OptLeftMargin = ScreenLineOffset(CursorAddress); + break; + + case FCN_UNDENT: + ColBak(); + OptLeftMargin = ScreenLineOffset(CursorAddress); + break; + + case FCN_SETMRG: + OptLeftMargin = ScreenLineOffset(CursorAddress); + break; + + case FCN_SETHOM: + OptHome = ScreenLine(CursorAddress); + break; + + /* + * Point to first character of next unprotected word on + * screen. + */ + case FCN_WORDTAB: + i = CursorAddress; + SetXIsProtected(); + while (!XIsProtected(i) && !Disspace(GetHost(i))) { + i = ScreenInc(i); + if (i == CursorAddress) { + break; + } + } + /* i is either protected, a space (blank or null), + * or wrapped + */ + while (XIsProtected(i) || Disspace(GetHost(i))) { + i = ScreenInc(i); + if (i == CursorAddress) { + break; + } + } + CursorAddress = i; + break; + + case FCN_WORDBACKTAB: + i = ScreenDec(CursorAddress); + SetXIsProtected(); + while (XIsProtected(i) || Disspace(GetHost(i))) { + i = ScreenDec(i); + if (i == CursorAddress) { + break; + } + } + /* i is pointing to a character IN an unprotected word + * (or i wrapped) + */ + while (!Disspace(GetHost(i))) { + i = ScreenDec(i); + if (i == CursorAddress) { + break; + } + } + CursorAddress = ScreenInc(i); + break; + + /* Point to last non-blank character of this/next + * unprotected word. + */ + case FCN_WORDEND: + i = ScreenInc(CursorAddress); + SetXIsProtected(); + while (XIsProtected(i) || Disspace(GetHost(i))) { + i = ScreenInc(i); + if (i == CursorAddress) { + break; + } + } + /* we are pointing at a character IN an + * unprotected word (or we wrapped) + */ + while (!Disspace(GetHost(i))) { + i = ScreenInc(i); + if (i == CursorAddress) { + break; + } + } + CursorAddress = ScreenDec(i); + break; + + /* Get to last non-blank of this/next unprotected + * field. + */ + case FCN_FIELDEND: + i = LastOfField(CursorAddress); + if (i != CursorAddress) { + CursorAddress = i; /* We moved; take this */ + } else { + j = FieldInc(CursorAddress); /* Move to next field */ + i = LastOfField(j); + if (i != j) { + CursorAddress = i; /* We moved; take this */ + } + /* else - nowhere else on screen to be; stay here */ + } + break; +#endif /* !defined(PURE3274) */ + + default: + /* We don't handle this yet */ + RingBell("Function not implemented"); + } + } + return 1; /* We did something! */ +} + + +/* + * We get data from the terminal. We keep track of the shift state + * (including ALT, CONTROL), and then call AcceptKeystroke to actually + * process any non-shift keys. + */ + +int +DataFrom3270(buffer, count) +unsigned char *buffer; /* where the data is */ +int count; /* how much data there is */ +{ + int origCount; + + origCount = count; + + while (count) { + if (*buffer >= numberof(hits)) { + ExitString("Unknown scancode encountered in DataFrom3270.\n", 1); + /*NOTREACHED*/ + } + + switch (hits[*buffer].hit[HITNUM(rememberedshiftstate)].ctlrfcn) { + + case FCN_MAKE_SHIFT: + rememberedshiftstate |= (SHIFT_RIGHT|SHIFT_UPSHIFT); + break; + case FCN_BREAK_SHIFT: + rememberedshiftstate &= ~(SHIFT_RIGHT|SHIFT_UPSHIFT); + break; + case FCN_MAKE_ALT: + rememberedshiftstate |= SHIFT_ALT; + break; + case FCN_BREAK_ALT: + rememberedshiftstate &= ~SHIFT_ALT; + break; + default: + if (AcceptKeystroke(*buffer, rememberedshiftstate) == 0) { + return(origCount-count); + } + break; + } + buffer++; + count--; + } + return(origCount-count); +} diff --git a/usr.bin/tn3270/ctlr/oia.c b/usr.bin/tn3270/ctlr/oia.c new file mode 100644 index 00000000000..7de14480fae --- /dev/null +++ b/usr.bin/tn3270/ctlr/oia.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +/*static char sccsid[] = "from: @(#)oia.c 4.2 (Berkeley) 4/26/91";*/ +static char rcsid[] = "$Id: oia.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $"; +#endif /* not lint */ + +/* + * Routines to maintain the Operator Information Area. + */ + +#include "../general/general.h" + +#include "oia.h" +#include "../general/globals.h" + + +init_oia() +{ + ClearElement(OperatorInformationArea); +} diff --git a/usr.bin/tn3270/ctlr/oia.h b/usr.bin/tn3270/ctlr/oia.h new file mode 100644 index 00000000000..33c61128527 --- /dev/null +++ b/usr.bin/tn3270/ctlr/oia.h @@ -0,0 +1,191 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)oia.h 4.2 (Berkeley) 4/26/91 + * $Id: oia.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $ + */ + +/* + * This file describes the Operator Information Area in the 3270. + * + * Our OIA looks like that used by the 3270 PC and PC 3270 products. + */ + +#define INCLUDED_OIA + +typedef struct { + char + online_ownership, + character_selection, + shift_state, + pss_group_1, + highlight_group_1, + color_group_1, + insert, + input_inhibited[5], + pss_group_2, + highlight_group_2, + color_group_2, + comm_error_reminder, + printer_status, + reserved_group_14, + reserved_group_15, + autokey_play_record_status, + autokey_abort_pause_status, + enlarge_state; +} OIA; + +/* Bits in online_ownership */ +#define OIA_SETUP 0x80 +#define OIA_TEST 0x40 +#define OIA_SSCP_LU 0x20 +#define OIA_LU_LU 0x10 +#define OIA_UNOWNED 0x08 +#define OIA_SUBSYSTEM_READY 0x04 + +/* Bit in character_selection */ +#define OIA_EXTENDED_SELECT 0x80 +#define OIA_APL 0x40 +#define OIA_KANA 0x20 +#define OIA_ALPHA 0x10 +#define OIA_TEXT 0x08 + +/* Bits in shift_state */ +#define OIA_NUMERIC 0x80 +#define OIA_UPPER_SHIFT 0x40 + +/* Bits in pss_group_1, highlight_group_1, and color_group_1 */ +#define OIA_SELECTABLE 0x80 +#define OIA_FIELD_INHERIT 0x40 + +/* Bits in insert */ +#define OIA_INSERT_MODE 0x80 + +/* We define this to be a 'long' followed by a 'char' (5 bytes) */ + +#define OIA_NON_RESETTABLE 0x80 +#define OIA_SECURITY_KEY 0x40 +#define OIA_MACHINE_CHECK 0x20 +#define OIA_COMM_CHECK 0x10 +#define OIA_PROGRAM_CHECK 0x08 +#define OIA_RETRY 0x04 +#define OIA_DEVICE_NOT_WORKING 0x02 +#define OIA_DEVICE_VERY_BUSY 0x01 + +#define OIA_DEVICE_BUSY 0x80 +#define OIA_TERMINAL_WAIT 0x40 +#define OIA_MINUS_SYMBOL 0x20 +#define OIA_MINUS_FUNCTION 0x10 +#define OIA_TOO_MUCH_ENTERED 0x08 +#define OIA_NOT_ENOUGH_ENTERED 0x04 +#define OIA_WRONG_NUMBER 0x02 +#define OIA_NUMERIC_FIELD 0x01 + +#define OIA_OP_UNAUTHORIZED 0x80 +#define OIA_OP_UNAUTHORIZED_MIN 0x40 +#define OIA_INVALID_DEAD_KEY_COMBO 0x20 +#define OIA_WRONG_PLACE 0x10 + +#define OIA_MESSAGE_PENDING 0x80 +#define OIA_PARTITION_WAIT 0x40 +#define OIA_SYSTEM_WAIT 0x20 +#define OIA_HARDWARE_MISMATCH 0x10 +#define OIA_LOGICAL_TERM_NOT_CONF 0x08 + + +#define OIA_AUTOKEY_INHIBIT 0x80 +#define OIA_API_INHIBIT 0x40 + +/* Bits in pss_group_2 */ +#define OIA_PS_SELECTED 0x80 +#define OIA_PC_DISPLAY_DISABLE 0x40 + +/* Bits in highlight_group_2 and color_group_2 */ +#define OIA_SELECTED 0x80 + +/* Bits in comm_error_reminder */ +#define OIA_COMM_ERROR 0x80 +#define OIA_RTM 0x40 + +/* Bits in printer_status */ +#define OIA_PRINT_NOT_CUSTOM 0x80 +#define OIA_PRINTER_MALFUNCTION 0x40 +#define OIA_PRINTER_PRINTING 0x20 +#define OIA_ASSIGN_PRINTER 0x10 +#define OIA_WHAT_PRINTER 0x08 +#define OIA_PRINTER_ASSIGNMENT 0x04 + +/* Bits in autokey_play_record_status */ +#define OIA_PLAY 0x80 +#define OIA_RECORD 0x40 + +/* Bits in autokey_abort_pause_status */ +#define OIA_RECORDING_OVERFLOW 0x80 +#define OIA_PAUSE 0x40 + +/* Bits in enlarge_state */ +#define OIA_WINDOW_IS_ENLARGED 0x80 + +/* Define functions to set and read the oia */ + +#define SetOiaOnlineA(oia) SetOiaMyJob((oia)) /* Side-effect */ +#define ResetOiaOnlineA(oia) \ + /* Nothing defined for this */ + +#define IsOiaReady3274(oia) ((oia)->online_ownership&OIA_SUBSYSTEM_READY) +#define ResetOiaReady3274(oia) (oia)->online_ownership &= ~OIA_SUBSYSTEM_READY +#define SetOiaReady3274(oia) (oia)->online_ownership |= OIA_SUBSYSTEM_READY + +#define IsOiaMyJob(oia) ((oia)->online_ownership&OIA_LU_LU) +#define ResetOiaMyJob(oia) (oia)->online_ownership &= ~OIA_LU_LU +#define SetOiaMyJob(oia) (oia)->online_ownership |= OIA_LU_LU + +#define IsOiaInsert(oia) ((oia)->online_ownership&OIA_INSERT_MODE) +#define ResetOiaInsert(oia) (oia)->online_ownership &= ~OIA_INSERT_MODE +#define SetOiaInsert(oia) (oia)->online_ownership |= OIA_INSERT_MODE + +#define IsOiaSystemLocked(oia) ((oia)->input_inhibited[3]&OIA_SYSTEM_WAIT) +#define ResetOiaSystemLocked(oia) \ + (oia)->input_inhibited[3] &= ~OIA_SYSTEM_WAIT +#define SetOiaSystemLocked(oia) (oia)->input_inhibited[3] |= OIA_SYSTEM_WAIT + +#define IsOiaTWait(oia) ((oia)->input_inhibited[1]&OIA_TERMINAL_WAIT) +#define ResetOiaTWait(oia) (oia)->input_inhibited[1] &= ~OIA_TERMINAL_WAIT +#define SetOiaTWait(oia) (oia)->input_inhibited[1] |= OIA_TERMINAL_WAIT + +#define IsOiaApiInhibit(oia) ((oia)->input_inhibited[4] & OIA_API_INHIBIT) +#define ResetOiaApiInhibit(oia) ((oia)->input_inhibited[4] &= ~OIA_API_INHIBIT) +#define SetOiaApiInhibit(oia) ((oia)->input_inhibited[4] |= OIA_API_INHIBIT) + +/* A macro to let the world know that someone has modified the OIA. */ +#define SetOiaModified() oia_modified = 1 +#define SetPsModified() ps_modified = 1 diff --git a/usr.bin/tn3270/ctlr/options.c b/usr.bin/tn3270/ctlr/options.c new file mode 100644 index 00000000000..6c0f49243e6 --- /dev/null +++ b/usr.bin/tn3270/ctlr/options.c @@ -0,0 +1,182 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +/*static char sccsid[] = "from: @(#)options.c 4.2 (Berkeley) 4/26/91";*/ +static char rcsid[] = "$Id: options.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $"; +#endif /* not lint */ + +/* + * this file contains the definitions, initialization, and processing of + * commands to handle the various local options (APL ON, etc.) + */ + +#include "options.h" + +#include "../general/globals.h" +#include "declare.h" + +void +OptInit() +{ + register int i; + + OptAPLmode = 0; + OptNullProcessing = 1; /* improved null processing */ + OptZonesMode = 0; /* zones mode off */ + OptEnterNL = 0; /* regular enter/new line keys */ + OptColFieldTab = 0; /* regular column/field tab keys */ + OptPacing = 1; /* do pacing */ + OptAlphaInNumeric = 0; /* allow alpha in numeric fields */ + for (i = 0; i < sizeof OptColTabs; i++) { + OptColTabs[i] = ((i%8) == 0); /* every 8 columns */ + } + OptHome = 0; + OptLeftMargin = 0; + OptWordWrap = 0; +} + +OptOrder(pointer, count, control) +unsigned char *pointer; +int count; +int control; +{ + int i, j, character, origCount; + + origCount = count; + + if (count == 0) { + return(0); + } + character = *pointer&0xff; + pointer++; + count--; + switch (character) { + case 0xa0: + OptAPLmode = 1; + break; + case 0x61: + OptAPLmode = 0; + break; + case 0x95: + OptNullProcessing = 0; + break; + case 0xd5: + OptNullProcessing = 1; + break; + case 0xa9: + OptZonesMode = 1; + break; + case 0xe9: + OptZonesMode = 0; + break; + case 0x85: + OptEnterNL = 1; + break; + case 0xc5: + OptEnterNL = 0; + break; + case 0x83: + OptColFieldTab = 1; + break; + case 0xc3: + OptColFieldTab = 0; + break; + case 0x97: + OptPacing = 0; + break; + case 0xd7: + OptPacing = 1; + break; + case 0xa5: + OptAlphaInNumeric = 1; + break; + case 0xe5: + OptAlphaInNumeric = 0; + break; + case 0xe3: + if (!control && count < 30) { + return(0); /* want more! */ + } + for (i = 0; i < sizeof OptColTabs; i++) { + OptColTabs[i] = 0; + } + if (!count) { + break; + } + j = (*pointer&0xff)-0x40; + count--; + pointer++; + if (j < 0 || j >= 24) { + break; + } + OptHome = j; + if (!count) { + break; + } + j = (*pointer&0xff)-0x40; + count--; + pointer++; + if (j < 0 || j >= 80) { + break; + } + OptLeftMargin = j; + if (!count) { + break; + } + i = count; + if (i > 28) { + i = 28; + } + while (i) { + j = (*pointer&0xff)-0x40; + if (j < 0 || j >= sizeof OptColTabs) { + break; + } + OptColTabs[j] = 1; + i --; + pointer++; + count--; + } + break; + case 0xa6: + OptWordWrap = 1; + break; + case 0xe6: + OptWordWrap = 0; + break; + default: + break; + } + return(origCount - count); +} diff --git a/usr.bin/tn3270/ctlr/options.h b/usr.bin/tn3270/ctlr/options.h new file mode 100644 index 00000000000..fe2fbfa1f7e --- /dev/null +++ b/usr.bin/tn3270/ctlr/options.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)options.h 4.2 (Berkeley) 4/26/91 + * $Id: options.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $ + */ + +/* + * the various options that run our life. Very few of these are implemented + * as yet. + */ + +#define INCLUDED_OPTIONS diff --git a/usr.bin/tn3270/ctlr/outbound.c b/usr.bin/tn3270/ctlr/outbound.c new file mode 100644 index 00000000000..eda42e2475c --- /dev/null +++ b/usr.bin/tn3270/ctlr/outbound.c @@ -0,0 +1,606 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +/*static char sccsid[] = "from: @(#)outbound.c 4.3 (Berkeley) 4/26/91";*/ +static char rcsid[] = "$Id: outbound.c,v 1.1 1995/10/18 08:46:21 deraadt Exp $"; +#endif /* not lint */ + +#include <stdio.h> + +#include "../general/general.h" + +#include "hostctlr.h" +#include "oia.h" +#include "screen.h" +#include "../api/ebc_disp.h" + +#include "../general/globals.h" +#include "externs.h" +#include "declare.h" + +#define SetHighestLowest(position) { \ + if (position < Lowest) { \ + Lowest = position; \ + } \ + if (position > Highest) { \ + Highest = position; \ + } \ + } + + +static int LastWasTerminated = 1; /* was "control" = 1 last time? */ + +/* some globals */ + +#if !defined(PURE3274) +int OutputClock; /* what time it is */ +int TransparentClock; /* time we were last in transparent */ +#endif /* !defined(PURE3274) */ + +char CIABuffer[64] = { + 0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f +}; + +static struct orders_def orders_def[] = ORDERS_DEF; + +/* + * init_ctlr() + * + * Initialize all data from the 'data' portion to their startup values. + */ + +void +init_ctlr() +{ + LastWasTerminated = 1; + init_inbound(); + init_oia(); +} + + +FieldInc(position) +register int position; /* Position in previous field */ +{ + register ScreenImage *ptr; + + ptr = (ScreenImage *)memNSchr((char *)Host+position+1, ATTR_MASK, + HighestScreen()-position, ATTR_MASK, sizeof Host[0]); + if (ptr == 0) { + ptr = (ScreenImage *)memNSchr((char *)Host+LowestScreen(), ATTR_MASK, + position-LowestScreen(), ATTR_MASK, sizeof Host[0]); + if (ptr == 0) { + return LowestScreen(); + } + } + return ptr-Host; +} + +FieldDec(position) +int position; +{ + register ScreenImage *ptr; + + ptr = (ScreenImage *)memNSchr((char *)(Host+position)-1, ATTR_MASK, + position-LowestScreen(), ATTR_MASK, -sizeof Host[0]); + if (ptr == 0) { + ptr = (ScreenImage *)memNSchr((char *)Host+HighestScreen(), ATTR_MASK, + HighestScreen()-position, ATTR_MASK, -sizeof Host[0]); + if (ptr == 0) { + return LowestScreen(); + } + } + return ptr-Host; +} + +/* Clear3270 - called to clear the screen */ + +void +Clear3270() +{ + ClearArray(Host); + DeleteAllFields(); /* get rid of all fields */ + BufferAddress = SetBufferAddress(0,0); + CursorAddress = SetBufferAddress(0,0); + Lowest = LowestScreen(); + Highest = HighestScreen(); +} + +/* AddHost - called to add a character to the buffer. + * We use a macro in this module, since we call it so + * often from loops. + * + * NOTE: It is a macro, so don't go around using AddHost(p, *c++), or + * anything similar. (I don't define any temporary variables, again + * just for the speed.) + */ +void +AddHost(position, character) +int position; +char character; +{ +# define AddHostA(p,c) \ + { \ + if (IsStartField(p)) { \ + DeleteField(p); \ + Highest = HighestScreen(); \ + Lowest = LowestScreen(); \ + SetHighestLowest(p); \ + } \ + SetHost(p, c); \ + } +# define AddHost(p,c) \ + { \ + if (c != GetHost(p)) { \ + SetHighestLowest(p); \ + } \ + AddHostA(p,c); \ + } /* end of macro of AddHost */ + + AddHost(position, character); +} + +/* returns the number of characters consumed */ +int +DataFromNetwork(Buffer, count, control) +char *Buffer; /* what the data is */ +register int count; /* and how much there is */ +int control; /* this buffer ended block? */ +{ + int origCount; + register unsigned char *buffer = (unsigned char *)Buffer; + register int c; + register int i; + static int Command; + static int Wcc; + + origCount = count; + + /* + * If this is the start of a new data stream, then look + * for an op-code and (possibly) a WCC. + */ + if (LastWasTerminated) { + + if (count < 2) { + if (count == 0) { + ExitString("Short count received from host!\n", 1); + return(count); + } + Command = buffer[0]; + switch (Command) { /* This had better be a read command */ + case CMD_READ_MODIFIED: + case CMD_SNA_READ_MODIFIED: + case CMD_SNA_READ_MODIFIED_ALL: + SetOiaOnlineA(&OperatorInformationArea); + SetOiaModified(); + DoReadModified(Command); + break; + case CMD_READ_BUFFER: + case CMD_SNA_READ_BUFFER: + SetOiaOnlineA(&OperatorInformationArea); + SetOiaModified(); + DoReadBuffer(); + break; + default: + { + char s_buffer[100]; + + sprintf(s_buffer, + "Unexpected read command code 0x%x received.\n", + Command); + ExitString(s_buffer, 1); + break; + } + } + return(1); /* We consumed everything */ + } + Command = buffer[0]; + Wcc = buffer[1]; + if (Wcc & WCC_RESET_MDT) { + i = c = WhereAttrByte(LowestScreen()); + do { + if (HasMdt(i)) { + TurnOffMdt(i); + } + i = FieldInc(i); + } while (i != c); + } + + switch (Command) { + case CMD_ERASE_WRITE: + case CMD_ERASE_WRITE_ALTERNATE: + case CMD_SNA_ERASE_WRITE: + case CMD_SNA_ERASE_WRITE_ALTERNATE: + { + int newlines, newcolumns; + + SetOiaOnlineA(&OperatorInformationArea); + ResetOiaTWait(&OperatorInformationArea); + SetOiaModified(); + if ((Command == CMD_ERASE_WRITE) + || (Command == CMD_SNA_ERASE_WRITE)) { + newlines = 24; + newcolumns = 80; + } else { + newlines = MaxNumberLines; + newcolumns = MaxNumberColumns; + } + if ((newlines != NumberLines) + || (newcolumns != NumberColumns)) { + /* + * The LocalClearScreen() is really for when we + * are going from a larger screen to a smaller + * screen, and we need to clear off the stuff + * at the end of the lines, or the lines at + * the end of the screen. + */ + LocalClearScreen(); + NumberLines = newlines; + NumberColumns = newcolumns; + ScreenSize = NumberLines * NumberColumns; + } + Clear3270(); +#if !defined(PURE3274) + if (TransparentClock == OutputClock) { + TransStop(); + } +#endif /* !defined(PURE3274) */ + break; + } + + case CMD_ERASE_ALL_UNPROTECTED: + case CMD_SNA_ERASE_ALL_UNPROTECTED: + SetOiaOnlineA(&OperatorInformationArea); + ResetOiaTWait(&OperatorInformationArea); + SetOiaModified(); + CursorAddress = HighestScreen()+1; + for (i = LowestScreen(); i <= HighestScreen(); i = ScreenInc(i)) { + if (IsUnProtected(i)) { + if (CursorAddress > i) { + CursorAddress = i; + } + AddHost(i, '\0'); + } + if (HasMdt(i)) { + TurnOffMdt(i); + } + } + if (CursorAddress == HighestScreen()+1) { + CursorAddress = SetBufferAddress(0,0); + } + UnLocked = 1; + AidByte = 0; + ResetOiaSystemLocked(&OperatorInformationArea); + SetOiaModified(); + TerminalIn(); + break; + case CMD_WRITE: + case CMD_SNA_WRITE: + SetOiaOnlineA(&OperatorInformationArea); + ResetOiaTWait(&OperatorInformationArea); + SetOiaModified(); + break; + default: + { + char s_buffer[100]; + + sprintf(s_buffer, + "Unexpected write command code 0x%x received.\n", + Command); + ExitString(s_buffer, 1); + break; + } + } + + count -= 2; /* strip off command and wcc */ + buffer += 2; + + } else { +#if !defined(PURE3274) + if (TransparentClock == OutputClock) { + TransOut(buffer, count, -1, control); + count = 0; + } +#endif /* !defined(PURE3274) */ + } + LastWasTerminated = 0; /* then, reset at end... */ + + while (count) { + count--; + c = *buffer++; + if (IsOrder(c)) { + /* handle an order */ + switch (c) { +# define Ensure(x) if (count < x) { \ + if (!control) { \ + return(origCount-(count+1)); \ + } else { \ + /* XXX - should not occur */ \ + count = 0; \ + break; \ + } \ + } + case ORDER_SF: + Ensure(1); + c = *buffer++; + count--; + if ( ! (IsStartField(BufferAddress) && + FieldAttributes(BufferAddress) == c)) { + SetHighestLowest(BufferAddress); + NewField(BufferAddress,c); + } + BufferAddress = ScreenInc(BufferAddress); + break; + case ORDER_SBA: + Ensure(2); + i = buffer[0]; + c = buffer[1]; +#if !defined(PURE3274) + /* Check for transparent write */ + if ((i == 0) && ((c == 0) || (c == 1) || (c == 5))) { + TransparentClock = OutputClock+1; + TransOut(buffer+2, count-2, c, control); + buffer += count; + count -= count; + break; + } +#endif /* !defined(PURE3274) */ + BufferAddress = Addr3270(i, c); + buffer += 2; + count -= 2; + break; + case ORDER_IC: + CursorAddress = BufferAddress; + break; + /* + * XXX - PT is supposed to null fill the screen buffer + * under certain draconian conditions. + */ + case ORDER_PT: + i = BufferAddress; + do { + if (IsStartField(i)) { + if (!IsProtected(ScreenInc(i))) { + break; + } + } + i = ScreenInc(i); + } while (i != HighestScreen()); + BufferAddress = ScreenInc(i); + break; + case ORDER_RA: + Ensure(3); + i = Addr3270(buffer[0], buffer[1]); + if ((i < 0) || (i > HighestScreen())) { + char s_buffer[200]; + + sprintf(s_buffer, "tn3270: %s%d.\n\t%s%d%s%d%s\n", + "Invalid 3270 order 'Repeat to Address' to address ", + i, + "(Screen currently set to ", + NumberLines, + " by ", + NumberColumns, + ".)"); + ExitString(s_buffer, 1); + /*NOTREACHED*/ + } + c = buffer[2]; + if (c == ORDER_GE) { + Ensure(4); + c = buffer[3]; + buffer += 4; + count -= 4; + } else { + buffer += 3; + count -= 3; + } + do { + AddHost(BufferAddress, ebc_disp[c]); + BufferAddress = ScreenInc(BufferAddress); + } while (BufferAddress != i); + break; + case ORDER_EUA: /* (from [here,there), ie: half open interval] */ + Ensure(2); + /* + * Compiler error - msc version 4.0: + * "expression too complicated". + */ + i = WhereAttrByte(BufferAddress); + c = FieldAttributes(i); + i = Addr3270(buffer[0], buffer[1]); + if ((i < 0) || (i > HighestScreen())) { + char s_buffer[200]; + + sprintf(s_buffer, "tn3270: %s%d.\n\t%s%d%s%d%s\n", + "Invalid 3270 order 'Erase Unprotected to Address' to address ", + i, + "(Screen currently set to ", + NumberLines, + " by ", + NumberColumns, + ".)"); + ExitString(s_buffer, 1); + /*NOTREACHED*/ + } + do { + if (IsStartField(BufferAddress)) { + c = FieldAttributes(BufferAddress); + } else if (!IsProtectedAttr(BufferAddress, c)) { + AddHost(BufferAddress, 0); + } + BufferAddress = ScreenInc(BufferAddress); + } while (i != BufferAddress); + buffer += 2; + count -= 2; + break; + case ORDER_GE: + Ensure(2); + /* XXX Should do SOMETHING! */ + /* XXX buffer += 0; */ + /* XXX count -= 0; *//* For now, just use this character */ + break; + case ORDER_YALE: /* special YALE defined order */ + Ensure(2); /* need at least two characters */ + if (*buffer == 0x5b) { + i = OptOrder(buffer+1, count-1, control); + if (i == 0) { + return(origCount-(count+1)); /* come here again */ + } else { + buffer += 1 + i; + count -= (1 + i); + } + } + break; + default: + { + char s_buffer[100]; + static struct orders_def unk_order + = { 0, "??", "(unknown)" }; + struct orders_def *porder = &unk_order; + int s_i; + + for (s_i = 0; s_i <= highestof(orders_def); s_i++) { + if (orders_def[s_i].code == c) { + porder = &orders_def[s_i]; + break; + } + } + sprintf(s_buffer, + "Unsupported order '%s' (%s, 0x%x) received.\n", + porder->long_name, porder->short_name, c); + ExitString(s_buffer, 1); + /*NOTREACHED*/ + } + } + if (count < 0) { + count = 0; + } + } else { + /* Data comes in large clumps - take it all */ + i = BufferAddress; + AddHostA(i, ebc_disp[c]); + SetHighestLowest(i); + i = ScreenInc(i); + c = *buffer; + while (count && !IsOrder(c)) { + AddHostA(i, ebc_disp[c]); + i = ScreenInc(i); + if (i == LowestScreen()) { + SetHighestLowest(HighestScreen()); + } + count--; + buffer++; + c = *buffer; + } + SetHighestLowest(i); + BufferAddress = i; + } + } + if (count == 0) { + if (control) { +#if !defined(PURE3274) + OutputClock++; /* time rolls on */ +#endif /* !defined(PURE3274) */ + if (Wcc & WCC_RESTORE) { +#if !defined(PURE3274) + if (TransparentClock != OutputClock) { + AidByte = 0; + } +#else /* !defined(PURE3274) */ + AidByte = 0; +#endif /* !defined(PURE3274) */ + UnLocked = 1; + ResetOiaSystemLocked(&OperatorInformationArea); + SetOiaModified(); + SetPsModified(); + TerminalIn(); + } + if (Wcc & WCC_ALARM) { + RingBell((char *)0); + } + } + LastWasTerminated = control; /* state for next time */ + return(origCount); + } else { + return(origCount-count); + } +} + +/* + * Init3270() + * + * Initialize any 3270 (controller) variables to an initial state + * in preparation for accepting a connection. + */ + +void +Init3270() +{ + int i; + + OptInit(); /* initialize mappings */ + + ClearArray(Host); + + ClearArray(Orders); + for (i = 0; i <= highestof(orders_def); i++) { + Orders[orders_def[i].code] = 1; + } + + DeleteAllFields(); /* Clear screen */ + Lowest = HighestScreen()+1; + Highest = LowestScreen()-1; + CursorAddress = BufferAddress = SetBufferAddress(0,0); + UnLocked = 1; +#if !defined(PURE3274) + OutputClock = 1; + TransparentClock = -1; +#endif /* !defined(PURE3274) */ + SetOiaReady3274(&OperatorInformationArea); +} + + +void +Stop3270() +{ + ResetOiaReady3274(&OperatorInformationArea); +} diff --git a/usr.bin/tn3270/ctlr/screen.h b/usr.bin/tn3270/ctlr/screen.h new file mode 100644 index 00000000000..f4a76154ea2 --- /dev/null +++ b/usr.bin/tn3270/ctlr/screen.h @@ -0,0 +1,146 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)screen.h 4.3 (Berkeley) 4/26/91 + * $Id: screen.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $ + */ + +#define INCLUDED_SCREEN + +/* defines and defines to describe how to deal with the screen */ + +#if !defined(MSDOS) +#define MAXNUMBERLINES 43 /* 3278-4 */ +#define MAXNUMBERCOLUMNS 132 /* 3278-5 */ +#define MAXSCREENSIZE 3564 /* (27*132) 3278-5 */ +#else /* !defined(MSDOS) */ /* MSDOS has memory constraints */ +#define MAXNUMBERLINES 25 /* XXX */ +#define MAXNUMBERCOLUMNS 80 +#define MAXSCREENSIZE (MAXNUMBERLINES*MAXNUMBERCOLUMNS) +#endif /* !defined(MSDOS) */ /* MSDOS has memory constraints */ +#define LowestScreen() 0 +#define HighestScreen() (ScreenSize-1) + +#define ScreenLineOffset(x) ((x)%NumberColumns) +#define ScreenLine(x) ((int)((x)/NumberColumns)) +#define ScreenInc(x) (((x)==HighestScreen())? LowestScreen():x+1) +#define ScreenDec(x) (((x)==LowestScreen())? HighestScreen():x-1) +#define ScreenUp(x) (((x)+(ScreenSize-NumberColumns))%ScreenSize) +#define ScreenDown(x) (((x)+NumberColumns)%ScreenSize) +#define IsOrder(x) (Orders[x]) +#define BAIC(x) ((x)&0x3f) +#define CIAB(x) (CIABuffer[(x)&0x3f]) +#define BufferTo3270_0(x) (CIABuffer[(int)((x)/0x40)]) +#define BufferTo3270_1(x) (CIABuffer[(x)&0x3f]) +#define Addr3270(x,y) (BAIC(x)*64+BAIC(y)) +#define SetBufferAddress(x,y) ((x)*NumberColumns+(y)) + +/* These know how fields are implemented... */ + +#define WhereAttrByte(p) (IsStartField(p)? p: FieldDec(p)) +#define WhereHighByte(p) ScreenDec(FieldInc(p)) +#define WhereLowByte(p) ScreenInc(WhereAttrByte(p)) +#define FieldAttributes(x) (IsStartField(x)? GetHost(x) : \ + GetHost(WhereAttrByte(x))) +#define FieldAttributesPointer(p) (IsStartFieldPointer(p)? \ + GetHostPointer(p): \ + GetHost(WhereAttrByte((p)-&Host[0]))) + +/* + * The MDT functions need to protect against the case where the screen + * is unformatted (sigh). + */ + +/* Turn off the Modified Data Tag */ +#define TurnOffMdt(x) \ + if (HasMdt(WhereAttrByte(x))) { \ + ModifyMdt(x, 0); \ + } + +/* Turn on the Modified Data Tag */ +#define TurnOnMdt(x) \ + if (!HasMdt(WhereAttrByte(x))) { \ + ModifyMdt(x, 1); \ + } + +/* If this location has the MDT bit turned on (implies start of field) ... */ +#define HasMdt(x) \ + ((GetHost(x)&(ATTR_MDT|ATTR_MASK)) == (ATTR_MDT|ATTR_MASK)) + + /* + * Is the screen formatted? Some algorithms change depending + * on whether there are any attribute bytes lying around. + */ +#define FormattedScreen() \ + ((WhereAttrByte(0) != 0) || ((GetHost(0)&ATTR_MASK) == ATTR_MASK)) + + /* field starts here */ +#define IsStartField(x) ((GetHost(x)&ATTR_MASK) == ATTR_MASK) +#define IsStartFieldPointer(p) ((GetHostPointer(p)&ATTR_MASK) == ATTR_MASK) + +#define NewField(p,a) SetHost(p, (a)|ATTR_MASK) +#define DeleteField(p) SetHost(p, 0) +#define DeleteAllFields() + +/* The following are independent of the implementation of fields */ +#define IsProtectedAttr(p,a) (IsStartField(p) || ((a)&ATTR_PROT)) +#define IsProtected(p) IsProtectedAttr(p,FieldAttributes(p)) + +#define IsUnProtected(x) (!IsProtected(x)) + +#define IsAutoSkip(x) (FieldAttributes(x)&ATTR_AUTO_SKIP) + +#define IsNonDisplayAttr(c) (((c)&ATTR_DSPD_MASK) == ATTR_DSPD_NONDISPLAY) +#define IsNonDisplay(p) IsNonDisplayAttr(FieldAttributes(p)) + +#define IsHighlightedAttr(c) \ + (((c)&ATTR_DSPD_MASK) == ATTR_DSPD_HIGH) +#define IsHighlighted(p) \ + (IsHighlightedAttr(FieldAttributes(p)) && !IsStartField(p)) + +typedef unsigned char ScreenImage; + +extern int + FieldFind(); + +extern char + CIABuffer[]; + +#define GetGeneric(i,h) (h)[i] +#define GetGenericPointer(p) (*(p)) +#define SetGeneric(i,c,h) ((h)[i] = (c)) +#define ModifyGeneric(i,what,h) {(h)[i] what;} + +#define GetHost(i) GetGeneric(i,Host) +#define GetHostPointer(p) GetGenericPointer(p) +#define SetHost(i,c) SetGeneric(i,c,Host) +#define ModifyHost(i,what) ModifyGeneric(i,what,Host) diff --git a/usr.bin/tn3270/ctlr/scrnctlr.h b/usr.bin/tn3270/ctlr/scrnctlr.h new file mode 100644 index 00000000000..8da484f7253 --- /dev/null +++ b/usr.bin/tn3270/ctlr/scrnctlr.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)scrnctlr.h 4.2 (Berkeley) 4/26/91 + * $Id: scrnctlr.h,v 1.1 1995/10/18 08:46:21 deraadt Exp $ + */ + +/* + * definitions that have to do with the interface between the + * controller and the screen. + */ + +#define DISP_AMPERSAND 0x30 +#define DISP_BLANK 0x10 +#define DISP_CENTSIGN 0x1b +#define DISP_DUP 0x9f +#define DISP_FM 0x9e +#define DISP_GREATER_THAN 0x08 +#define DISP_NULL 0x00 +#define DISP_QUESTION 0x18 diff --git a/usr.bin/tn3270/ctlr/unix.kbd b/usr.bin/tn3270/ctlr/unix.kbd new file mode 100644 index 00000000000..e0e30db06cc --- /dev/null +++ b/usr.bin/tn3270/ctlr/unix.kbd @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)unix.kbd 4.2 (Berkeley) 4/26/91 + */ + +/* + * keynumber [ scancode [ unshifted [ shifted [ alted [ shiftalted ] ] ] ] ] + * + * keynumber is in decimal, and starts in column 1. + * scancode is hexadecimal. + * unshifted, etc. - these are either a single ascii character, + * or the name of a function or an AID-generating key. + * + * all fields are separated by a single space. + */ + +extern struct hits hits[]; +1 0e ` ~ LPRT +2 16 1 ! XON +3 1e 2 @ XOFF +4 26 3 # ALTK +5 25 4 $ ESCAPE +6 2e 5 % DISC +7 36 6 ^ MASTER_RESET +8 3d 7 & RESHOW +9 3e 8 * FLINP +10 46 9 ( SYNCH +11 45 0 ) INIT +12 4e - _ PCOFF +13 55 = + PCON +14 5d APLON APLOFF APLEND +15 66 LEFT +16 0d TAB BTAB +17 15 q Q FIELDEND +18 1d w W WORDEND +19 24 e E WORDBACKTAB +20 2d r R FERASE +21 2c t T WERASE +22 35 y Y ERASE +23 3c u U CLRTAB +24 43 i I SETHOM +25 44 o O SETMRG +26 4d p P UNDENT +27 54 [ { INDENT +28 5b \ | SETTAB +29 5c DELTAB COLTAB COLBAK +30 14 CAPS_LOCK +31 1c a A WORDTAB +32 1b s S CURSEL +33 23 d D VERTICAL_BAR +34 2b f F CENTSIGN +35 34 g G PF25 +36 33 h H PF26 +37 3b j J PF27 +38 42 k K PF28 +39 4b l L PF29 +40 4c ; : PF30 +41 52 ' " PF31 +42 53 ] } PF32 +43 5a NL +44 12 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT +45 13 < > PF33 +46 1a z Z PF34 +47 22 x X PF35 +48 21 c C PF36 +49 2a v V +50 32 b B +51 31 n N +52 3a m M +53 41 , < +54 49 . > +55 4a / ? +56 51 +57 59 MAKE_SHIFT MAKE_SHIFT MAKE_SHIFT +58 11 RESET NULL DVCNL +59 +60 19 MAKE_ALT MAKE_ALT MAKE_ALT +61 29 SPACE SPACE +62 39 MAKE_ALT MAKE_ALT MAKE_ALT +63 +64 58 ENTER +65 06 CLEAR NULL TEST +66 0c NULL NULL ATTN +67 0b EEOF NULL EINP +68 0a +69 09 MAKE_CTRL +70 05 ATTN NULL TREQ +71 04 +72 03 +73 83 +74 01 +75 67 PA1 DP +76 64 BTAB +77 +78 61 LEFT NULL LEFT2 +79 +80 6e PA2 FM +81 65 INSRT +82 63 UP +83 62 NULL NULL HOME +84 60 DOWN +85 6f PA3 +86 6d DELETE +87 +88 6a RIGHT NULL RIGHT2 +89 +90 76 +91 6c 7 +92 6b 4 +93 69 1 +94 68 +95 77 +96 75 8 +97 73 5 +98 72 2 +99 70 0 +100 7e , +101 7d 9 +102 74 6 +103 7a 3 +104 71 . +105 84 SPACE +106 7c TAB +107 7b - +108 79 ENTER +109 78 +110 07 PF1 +111 0f PF2 +112 17 PF3 +113 1f PF4 +114 27 PF5 +115 2f PF6 +116 37 PF7 +117 3f PF8 NULL MONOCASE +118 47 PF9 +119 4f PF10 +120 56 PF11 +121 5e PF12 +122 08 PF13 +123 10 PF14 +124 18 PF15 +125 20 PF16 +126 28 PF17 +127 30 PF18 +128 38 PF19 +129 40 PF20 +130 48 PF21 +131 50 PF22 +132 57 PF23 +133 5f PF24 +134 92 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT +135 D9 BREAK_SHIFT BREAK_SHIFT BREAK_SHIFT +136 99 BREAK_ALT BREAK_ALT BREAK_ALT +137 B9 BREAK_ALT BREAK_ALT BREAK_ALT |