mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (05/30/90)
Submitted-by: robert%shangri-la@gatech.edu (Robert Viduya) Posting-number: Volume 2, Issue 11 Archive-name: 3270tool/part01 This is something I wrote a couple of years ago, but due to some problems here at Tech, have only just now gotten permission to release. As a result, the code has been in production use here on campus for most of that time and has proven to be pretty solid. I won't guarantee that it's entirely bug free (I'm not *that* stupid) but I'll just say that I've not found any in quite some time and none of the people who use it have reported any. There are certainly some areas of improvement but more on that later. This program is called 3270tool and is meant to replace tn3270 in a SunView environment. It's biggest advantage over tn3270 is that it takes advantage of it's environment by supporting the full IBM 3278 character set (something an ASCII terminal can't do) and not forcing the user to remember what key on his keyboard maps to a particular IBM key since all such keys are available from the mouse as well as the keyboard. The man page explains how to do things and the README talks a bit about the program as well as areas of improvements but since I've pretty much moved into an X environment, I don't think those improvements will be coming from me. The X version of the program is almost done and offers a few significant improvements already like a user-definable keyboard mapping (those .Xdefaults files are a *big* improvement over SunView's .defaults file) as well as a wider range of font sizes and a wider range of IBM terminal types that are supported. Anyway, share and enjoy... robert ---cut here--- #! /bin/sh # Run the following text with /bin/sh to create: # File kybd.c (28446 bytes) # File screen.c (24454 bytes) # File README (2205 bytes) # File BtnClear (541 bytes) if test -f 'kybd.c' then echo "`basename $0`: can't extract" 'kybd.c' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_kybd.c--' > 'kybd.c' X/* X * Copyright 1989 by Georgia Tech Research Corporation, Atlanta, GA. X * Copyright 1988, 1989 by Robert Viduya. X * X * All Rights Reserved X */ X X/* X * kybd.c X * This module handles the keyboard for the 3270 emulator. X */ X#include <sys/types.h> X#include <suntool/sunview.h> X#include <suntool/menu.h> X#include <suntool/canvas.h> X#include <suntool/seln.h> X#include <suntool/panel.h> X#include <sundev/kbio.h> X#include <sundev/kbd.h> X#include <fcntl.h> X#include <stdio.h> X#include "3270.h" X#include "3270_enc.h" X X/* X * The following table is used to translate ascii key codes to 3270 X * character generator symbol. Note that this is not an ebcdic X * translation. See xlate.h for details. X */ Xu_char asc2cg[128] = { X CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, X CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, X CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, X CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, X CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, X CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, X CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, CG_CENT, X CG_SOLIDBAR, CG_NULLBLANK, CG_NULLBLANK, CG_NULLBLANK, X CG_BLANK, CG_EXCLAMATION, CG_DQUOTE, CG_NUMBER, X CG_DOLLAR, CG_PERCENT, CG_AMPERSAND, CG_SQUOTE, X CG_LPAREN, CG_RPAREN, CG_ASTERISK, CG_PLUS, X CG_COMMA, CG_MINUS, CG_PERIOD, CG_FSLASH, X CG_ZERO, CG_ONE, CG_TWO, CG_THREE, X CG_FOUR, CG_FIVE, CG_SIX, CG_SEVEN, X CG_EIGHT, CG_NINE, CG_COLON, CG_SEMICOLON, X CG_LESS, CG_EQUAL, CG_GREATER, CG_QUESTION, X CG_AT, CG_CA, CG_CB, CG_CC, X CG_CD, CG_CE, CG_CF, CG_CG, X CG_CH, CG_CI, CG_CJ, CG_CK, X CG_CL, CG_CM, CG_CN, CG_CO, X CG_CP, CG_CQ, CG_CR, CG_CS, X CG_CT, CG_CU, CG_CV, CG_CW, X CG_CX, CG_CY, CG_CZ, CG_LBRACKET, X CG_BSLASH, CG_RBRACKET, CG_NOT, CG_UNDERSCORE, X CG_GRAVE, CG_LA, CG_LB, CG_LC, X CG_LD, CG_LE, CG_LF, CG_LG, X CG_LH, CG_LI, CG_LJ, CG_LK, X CG_LL, CG_LM, CG_LN, CG_LO, X CG_LP, CG_LQ, CG_LR, CG_LS, X CG_LT, CG_LU, CG_LV, CG_LW, X CG_LX, CG_LY, CG_LZ, CG_LBRACE, X CG_BROKENBAR, CG_RBRACE, CG_TILDE, CG_NULLBLANK X}; X Xu_char cg2asc[256] = { X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X '>', '<', '[', ']', ')', '(', '}', '{', X ' ', '=', '\'', '"', '/', '\\', '|', '|', X '?', '!', '$', 'c', 'L', 'Y', 'P', 'o', X '0', '1', '2', '3', '4', '5', '6', '7', X '8', '9', 'B', 'S', '#', '@', '%', '_', X '&', '-', '.', ',', ':', '+', '^', '~', X '*', '^', '^', '~', '~', '`', '\'', ',', X 'a', 'e', 'i', 'o', 'u', 'a', 'o', 'y', X 'a', 'e', 'e', 'i', 'o', 'u', 'u', 'c', X 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', X 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'n', X 'A', 'E', 'I', 'O', 'U', 'A', 'O', 'Y', X 'A', 'E', 'E', 'I', 'O', 'U', 'Y', 'C', X 'A', 'E', 'I', 'O', 'U', 'A', 'E', 'I', X 'O', 'U', 'A', 'E', 'I', 'O', 'U', 'N', X 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', X 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', X 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', X 'y', 'z', 'a', '0', 'a', 'c', ';', '*', X 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', X 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', X 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', X 'Y', 'Z', 'A', '0', 'A', 'C', ';', '*', X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', X}; X Xbool kybdlock = FALSE, /* kybd locked */ X insert = FALSE; /* insert mode */ Xu_char aid = AID_NO; /* current attention ID */ XMenu Key_menu; X Xextern u_char screen_buf[ROWS * COLS]; Xextern int cursor_addr, buffer_addr; Xextern Pixwin *pixwin; Xextern Canvas canvas; Xextern Pixfont *ibmfont; Xextern Frame frame; Xextern int net_sock; Xextern bool formatted, cursor_alt, cursor_blink, mono_case; Xextern Seln_client s_client; Xextern int char_width, char_height, char_base; X Xextern int key_panel_toggle (); Xextern u_char *get_field_attribute (); Xextern int stuff_seln (); X X X/* X * Toggle insert mode. X */ Xinsert_mode (on) Xbool on; X{ X if (on) { X insert = TRUE; X status_disp (51, CG_INSERT); X } X else { X insert = FALSE; X status_disp (51, CG_BLANK); X } X} X X X/* X * Update shift mode indicator. Not used currently, until I can figure out X * how to reliably read the state of the CAPS lock key. X */ Xupdate_shift () X{ X int on, v; X X v = (int) window_get (canvas, WIN_EVENT_STATE, SHIFT_LEFT); X printf ("SHIFT_LEFT=%d ", v); X on = v; X X v = (int) window_get (canvas, WIN_EVENT_STATE, SHIFT_RIGHT); X printf ("SHIFT_RIGHT=%d ", v); X on |= v; X X v = (int) window_get (canvas, WIN_EVENT_STATE, SHIFT_LOCK); X printf ("SHIFT_LOCK=%d ", v); X on |= v; X X v = (int) window_get (canvas, WIN_EVENT_STATE, SHIFT_CAPSLOCK); X printf ("SHIFT_CAPSLOCK=%d\n", v); X on |= v; X X status_disp (41, on ? CG_UPSHIFT : CG_BLANK); X} X X X/* X * Handle an AID (Attention IDentifier) key. This is the common stuff that X * gets executed for all AID keys (PFs, PAs, Clear and etc). X */ Xkey_AID (aid_code) Xint aid_code; X{ X status_disp (1, CG_BLANK); X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_CLOCKLEFT); X status_disp (11, CG_CLOCKRIGHT); X insert_mode (FALSE); X kybdlock = TRUE; X aid = aid_code; X do_read_modified (); X status_disp (1, CG_UNDERA); X} X X X/* X * Handle an ordinary displayable character key. Lots of stuff to handle X * insert-mode, protected fields and etc. X */ Xbool Xkey_Character (cgcode) Xint cgcode; X{ X register int baddr, end_baddr, t_baddr; X register u_char *fa; X X if (kybdlock) X return (FALSE); X baddr = cursor_addr; X fa = get_field_attribute (baddr); X if (IS_FA (screen_buf[baddr]) || FA_IS_PROTECTED (*fa)) { X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_LEFTARROW); X status_disp (11, CG_HUMAN); X status_disp (12, CG_RIGHTARROW); X kybdlock = TRUE; X return (FALSE); X } X else { X if (FA_IS_NUMERIC (*fa) X && !((cgcode >= CG_ZERO && cgcode <= CG_NINE) || cgcode == CG_MINUS || cgcode == CG_PERIOD)) { X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_HUMAN); X status_disp (11, CG_CN); X status_disp (12, CG_CU); X status_disp (13, CG_CM); X kybdlock = TRUE; X return (FALSE); X } X else { X if (insert && screen_buf[baddr]) { X /* find next null or next fa */ X end_baddr = baddr; X do { X INC_BA (end_baddr); X if (screen_buf[end_baddr] == CG_NULLBLANK X || IS_FA (screen_buf[end_baddr])) X break; X } while (end_baddr != baddr); X if (screen_buf[end_baddr] != CG_NULLBLANK) { X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_HUMAN); X status_disp (11, CG_GREATER); X kybdlock = TRUE; X return (FALSE); X } X else { X if (end_baddr > baddr) X bcopy ((char *) &screen_buf[baddr], (char *) &screen_buf[baddr+1], end_baddr - baddr); X else { X bcopy ((char *) &screen_buf[0], (char *) &screen_buf[1], end_baddr); X screen_buf[0] = screen_buf[(ROWS * COLS) - 1]; X bcopy ((char *) &screen_buf[baddr], (char *) &screen_buf[baddr+1], ((ROWS * COLS) - 1) - baddr); X } X screen_buf[baddr] = cgcode; X cursor_off (); X t_baddr = baddr; X while (t_baddr != end_baddr) { X screen_update (t_baddr, *fa); X INC_BA (t_baddr); X } X screen_update (t_baddr, *fa); X } X } X else { X screen_buf[baddr] = cgcode; X cursor_off (); X screen_update (baddr, *fa); X } X INC_BA (baddr); X if (IS_FA (screen_buf[baddr])) { X if (FA_IS_NUMERIC (screen_buf[baddr])) { X if (FA_IS_PROTECTED (screen_buf[baddr])) { X /* skip to next unprotected */ X while (TRUE) { X INC_BA (baddr); X if (IS_FA (screen_buf[baddr]) X && !FA_IS_PROTECTED (screen_buf[baddr])) X break; X } X INC_BA (baddr); X } X else X INC_BA (baddr); X } X else X INC_BA (baddr); X } X cursor_move (baddr); X cursor_on (); X *fa |= FA_MODIFY; X } X } X return (TRUE); X} X X X/* X * Toggle underline/block cursor. X */ Xkey_AltCr () X{ X alt_cursor ((bool) (!cursor_alt)); X} X X X/* X * Toggle blink/no-blink cursor. X */ Xkey_CursorBlink () X{ X blink_cursor ((bool) (!cursor_blink)); X} X X X/* X * Toggle mono-/dual-case operation. X */ Xkey_MonoCase () X{ X change_case ((bool) (!mono_case)); X} X X X/* X * Tab forward to next field. X */ Xkey_FTab () X{ X register int baddr, nbaddr; X X if (kybdlock) X return; X nbaddr = cursor_addr; X INC_BA (nbaddr); X while (TRUE) { X baddr = nbaddr; X INC_BA (nbaddr); X if (IS_FA (screen_buf[baddr]) X && !FA_IS_PROTECTED (screen_buf[baddr]) X && !IS_FA (screen_buf[nbaddr])) X break; X if (baddr == cursor_addr) { X cursor_move (0); X return; X } X } X INC_BA (baddr); X cursor_move (baddr); X} X X X/* X * Tab backward to previous field. X */ Xkey_BTab () X{ X register int baddr, nbaddr; X int sbaddr; X X if (kybdlock) X return; X baddr = cursor_addr; X DEC_BA (baddr); X if (IS_FA (screen_buf[baddr])) /* at bof */ X DEC_BA (baddr); X sbaddr = baddr; X while (TRUE) { X nbaddr = baddr; X INC_BA (nbaddr); X if (IS_FA (screen_buf[baddr]) X && !FA_IS_PROTECTED (screen_buf[baddr]) X && !IS_FA (screen_buf[nbaddr])) X break; X DEC_BA (baddr); X if (baddr == sbaddr) { X cursor_move (0); X return; X } X } X INC_BA (baddr); X cursor_move (baddr); X} X X X/* X * Reset keyboard lock. X */ Xkey_Reset () X{ X register int i; X X kybdlock = FALSE; X insert_mode (FALSE); X for (i = 0; i < 9; i++) X status_disp (i + 8, CG_BLANK); X} X X X/* X * Move to first unprotected field on screen. X */ Xkey_Home () X{ X register int baddr, nbaddr; X register u_char *fa; X X if (kybdlock) X return; X fa = get_field_attribute (0); X if (!FA_IS_PROTECTED (*fa)) X cursor_move (0); X else { X nbaddr = 1; /* start at 2nd col, 1st col is fa */ X while (TRUE) { X baddr = nbaddr; X INC_BA (nbaddr); X if (IS_FA (screen_buf[baddr]) X && !FA_IS_PROTECTED (screen_buf[baddr]) X && !IS_FA (screen_buf[nbaddr])) X break; X if (baddr == 0) { X cursor_move (0); X return; X } X } X INC_BA (baddr); X cursor_move (baddr); X } X} X X X/* X * Cursor left 1 position. X */ Xkey_Left () X{ X register int baddr; X X if (kybdlock) X return; X baddr = cursor_addr; X DEC_BA (baddr); X cursor_move (baddr); X} X X X/* X * Cursor right 1 position. X */ Xkey_Right () X{ X register int baddr; X X if (kybdlock) X return; X baddr = cursor_addr; X INC_BA (baddr); X cursor_move (baddr); X} X X X/* X * Cursor left 2 positions. X */ Xkey_Left2 () X{ X register int baddr; X X if (kybdlock) X return; X baddr = cursor_addr; X DEC_BA (baddr); X DEC_BA (baddr); X cursor_move (baddr); X} X X X/* X * Cursor right 2 positions. X */ Xkey_Right2 () X{ X register int baddr; X X if (kybdlock) X return; X baddr = cursor_addr; X INC_BA (baddr); X INC_BA (baddr); X cursor_move (baddr); X} X X X/* X * Cursor up 1 position. X */ Xkey_Up () X{ X register int baddr; X X if (kybdlock) X return; X baddr = cursor_addr - COLS; X if (baddr < 0) X baddr = (cursor_addr + (ROWS * COLS)) - COLS; X cursor_move (baddr); X} X X X/* X * Cursor down 1 position. X */ Xkey_Down () X{ X register int baddr; X X if (kybdlock) X return; X baddr = (cursor_addr + COLS) % (COLS * ROWS); X cursor_move (baddr); X} X X X/* X * Cursor to first field on next line or any lines after that. X */ Xkey_Newline () X{ X register int baddr; X register u_char *fa; X X if (kybdlock) X return; X baddr = (cursor_addr + COLS) % (COLS * ROWS); /* down */ X baddr = (baddr / COLS) * COLS; /* 1st col */ X fa = get_field_attribute (baddr); X if (fa != (&screen_buf[baddr]) && !FA_IS_PROTECTED (*fa)) X cursor_move (baddr); X else { /* find next unprotected */ X if (fa == (&screen_buf[baddr]) && !FA_IS_PROTECTED (*fa)) { X INC_BA (baddr); X } X else { X while (TRUE) { X INC_BA (baddr); X if (IS_FA (screen_buf[baddr]) X && !FA_IS_PROTECTED (screen_buf[baddr])) X break; X if (baddr == cursor_addr) { X cursor_move (0); X return; X } X } X INC_BA (baddr); X } X cursor_move (baddr); X } X} X X X/* X * DUP key X */ Xkey_Dup () X{ X register int baddr, nbaddr; X X if (key_Character (CG_DUP)) { X nbaddr = cursor_addr; X INC_BA (nbaddr); X while (TRUE) { X baddr = nbaddr; X INC_BA (nbaddr); X if (IS_FA (screen_buf[baddr]) X && !FA_IS_PROTECTED (screen_buf[baddr]) X && !IS_FA (screen_buf[nbaddr])) X break; X if (baddr == cursor_addr) { X cursor_move (0); X return; X } X } X INC_BA (baddr); X cursor_move (baddr); X } X} X X X/* X * FM key X */ Xkey_FieldMark () X{ X (void) key_Character (CG_FM); X} X X X/* X * Enter AID key. X */ Xkey_Enter () X{ X if (kybdlock) X return; X key_AID (AID_ENTER); X} X X X/* X * PA1 AID key X */ Xkey_PA1 () X{ X if (kybdlock) X return; X key_AID (AID_PA1); X} X X X/* X * PA2 AID key X */ Xkey_PA2 () X{ X if (kybdlock) X return; X key_AID (AID_PA2); X} X X X/* X * PA3 AID key X */ Xkey_PA3 () X{ X if (kybdlock) X return; X key_AID (AID_PA3); X} X X X/* X * PF1 AID key X */ Xkey_PF1 () X{ X if (kybdlock) X return; X key_AID (AID_PF1); X} X X X/* X * PF2 AID key X */ Xkey_PF2 () X{ X if (kybdlock) X return; X key_AID (AID_PF2); X} X X X/* X * PF3 AID key X */ Xkey_PF3 () X{ X if (kybdlock) X return; X key_AID (AID_PF3); X} X X X/* X * PF4 AID key X */ Xkey_PF4 () X{ X if (kybdlock) X return; X key_AID (AID_PF4); X} X X X/* X * PF5 AID key X */ Xkey_PF5 () X{ X if (kybdlock) X return; X key_AID (AID_PF5); X} X X X/* X * PF6 AID key X */ Xkey_PF6 () X{ X if (kybdlock) X return; X key_AID (AID_PF6); X} X X X/* X * PF7 AID key X */ Xkey_PF7 () X{ X if (kybdlock) X return; X key_AID (AID_PF7); X} X X X/* X * PF8 AID key X */ Xkey_PF8 () X{ X if (kybdlock) X return; X key_AID (AID_PF8); X} X X X/* X * PF9 AID key X */ Xkey_PF9 () X{ X if (kybdlock) X return; X key_AID (AID_PF9); X} X X X/* X * PF10 AID key X */ Xkey_PF10 () X{ X if (kybdlock) X return; X key_AID (AID_PF10); X} X X X/* X * PF11 AID key X */ Xkey_PF11 () X{ X if (kybdlock) X return; X key_AID (AID_PF11); X} X X X/* X * PF12 AID key X */ Xkey_PF12 () X{ X if (kybdlock) X return; X key_AID (AID_PF12); X} X X X/* X * PF13 AID key X */ Xkey_PF13 () X{ X if (kybdlock) X return; X key_AID (AID_PF13); X} X X X/* X * PF14 AID key X */ Xkey_PF14 () X{ X if (kybdlock) X return; X key_AID (AID_PF14); X} X X X/* X * PF15 AID key X */ Xkey_PF15 () X{ X if (kybdlock) X return; X key_AID (AID_PF15); X} X X X/* X * PF16 AID key X */ Xkey_PF16 () X{ X if (kybdlock) X return; X key_AID (AID_PF16); X} X X X/* X * PF17 AID key X */ Xkey_PF17 () X{ X if (kybdlock) X return; X key_AID (AID_PF17); X} X X X/* X * PF18 AID key X */ Xkey_PF18 () X{ X if (kybdlock) X return; X key_AID (AID_PF18); X} X X X/* X * PF19 AID key X */ Xkey_PF19 () X{ X if (kybdlock) X return; X key_AID (AID_PF19); X} X X X/* X * PF20 AID key X */ Xkey_PF20 () X{ X if (kybdlock) X return; X key_AID (AID_PF20); X} X X X/* X * PF21 AID key X */ Xkey_PF21 () X{ X if (kybdlock) X return; X key_AID (AID_PF21); X} X X X/* X * PF22 AID key X */ Xkey_PF22 () X{ X if (kybdlock) X return; X key_AID (AID_PF22); X} X X X/* X * PF23 AID key X */ Xkey_PF23 () X{ X if (kybdlock) X return; X key_AID (AID_PF23); X} X X X/* X * PF24 AID key X */ Xkey_PF24 () X{ X if (kybdlock) X return; X key_AID (AID_PF24); X} X X X/* X * System Request AID key X */ Xkey_SysReq () X{ X if (kybdlock) X return; X key_AID (AID_SYSREQ); X} X X X/* X * Clear AID key X */ Xkey_Clear () X{ X if (kybdlock) X return; X bzero ((char *) screen_buf, sizeof (screen_buf)); X buffer_addr = 0; X cursor_off (); X pw_writebackground (pixwin, 0, 0, COL_TO_X (COLS), ROW_TO_Y (ROWS), PIX_CLR); X cursor_move (0); X cursor_on (); X key_AID (AID_CLEAR); X} X X X/* X * Cursor Select key (light pen simulator). X */ Xkey_CursorSelect () X{ X register u_char *fa, *sel; X X if (kybdlock) X return; X fa = get_field_attribute (cursor_addr); X if (!FA_IS_SELECTABLE (*fa)) { X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_LEFTARROW); X status_disp (11, CG_HUMAN); X status_disp (12, CG_RIGHTARROW); X kybdlock = TRUE; X } X else { X sel = fa + 1; X switch (*sel) { X case CG_GREATER: /* > */ X *sel = CG_QUESTION; /* change to ? */ X screen_update (sel - screen_buf, *fa); X *fa &= ~FA_MODIFY; /* clear mdt */ X break; X case CG_QUESTION: /* ? */ X *sel = CG_GREATER; /* change to > */ X screen_update (sel - screen_buf, *fa); X *fa |= FA_MODIFY; /* set mdt */ X break; X case CG_BLANK: /* space */ X case CG_NULLBLANK: /* null */ X key_AID (AID_SELECT); X break; X case CG_AMPERSAND: /* & */ X key_AID (AID_ENTER); X break; X default: X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_LEFTARROW); X status_disp (11, CG_HUMAN); X status_disp (12, CG_RIGHTARROW); X kybdlock = TRUE; X } X } X} X X X/* X * Erase End Of Field Key. X */ Xkey_EraseEOF () X{ X register int baddr; X register u_char *fa; X X if (kybdlock) X return; X baddr = cursor_addr; X fa = get_field_attribute (baddr); X if (FA_IS_PROTECTED (*fa) || IS_FA (screen_buf[baddr])) { X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_LEFTARROW); X status_disp (11, CG_HUMAN); X status_disp (12, CG_RIGHTARROW); X kybdlock = TRUE; X } X else { X if (formatted) { /* erase to next field attribute */ X cursor_off (); X do { X screen_buf[baddr] = CG_NULLBLANK; X screen_update (baddr, *fa); X INC_BA (baddr); X } while (!IS_FA (screen_buf[baddr])); X *fa |= FA_MODIFY; X cursor_on (); X } X else { /* erase to end of screen */ X cursor_off (); X do { X screen_buf[baddr] = CG_NULLBLANK; X screen_update (baddr, *fa); X INC_BA (baddr); X } while (baddr != 0); X cursor_on (); X } X } X} X X X/* X * Erase all Input Key. X */ Xkey_EraseInput () X{ X register int baddr, sbaddr; X u_char fa; X bool f; X X if (kybdlock) X return; X cursor_off (); X if (formatted) { X /* find first field attribute */ X baddr = 0; X do { X if (IS_FA (screen_buf[baddr])) X break; X INC_BA (baddr); X } while (baddr != 0); X sbaddr = baddr; X f = FALSE; X do { X fa = screen_buf[baddr]; X if (!FA_IS_PROTECTED (fa)) { X screen_buf[baddr] &= ~FA_MODIFY; X do { X INC_BA (baddr); X if (!f) { X cursor_move (baddr); X f = TRUE; X } X if (!IS_FA (screen_buf[baddr])) { X screen_buf[baddr] = CG_NULLBLANK; X screen_update (baddr, fa); X } X } X while (!IS_FA (screen_buf[baddr])); X } X else { /* skip protected */ X do { X INC_BA (baddr); X } while (!IS_FA (screen_buf[baddr])); X } X } while (baddr != sbaddr); X if (!f) X cursor_move (0); X } X else { X bzero ((char *) screen_buf, sizeof (screen_buf)); X pw_writebackground ( X pixwin, X 0, 0, COL_TO_X (COLS), ROW_TO_Y (ROWS), X PIX_CLR X ); X cursor_move (0); X } X cursor_on (); X} X X X/* X * Delete char key. X */ Xkey_Delete () X{ X register int baddr, end_baddr, t_baddr; X register u_char *fa; X X if (kybdlock) X return; X baddr = cursor_addr; X fa = get_field_attribute (baddr); X if (FA_IS_PROTECTED (*fa) || IS_FA (screen_buf[baddr])) { X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_LEFTARROW); X status_disp (11, CG_HUMAN); X status_disp (12, CG_RIGHTARROW); X kybdlock = TRUE; X } X else { X /* find next fa */ X end_baddr = baddr; X do { X INC_BA (end_baddr); X if (IS_FA (screen_buf[end_baddr])) X break; X } while (end_baddr != baddr); X DEC_BA (end_baddr); X if (end_baddr > baddr) X bcopy ((char *) &screen_buf[baddr+1], (char *) &screen_buf[baddr], end_baddr - baddr); X else { X bcopy ((char *) &screen_buf[baddr+1], (char *) &screen_buf[baddr], ((ROWS * COLS) - 1) - baddr); X screen_buf[(ROWS * COLS) - 1] = screen_buf[0]; X bcopy ((char *) &screen_buf[1], (char *) &screen_buf[0], end_baddr); X } X screen_buf[end_baddr] = CG_NULLBLANK; X cursor_off (); X t_baddr = baddr; X while (t_baddr != end_baddr) { X screen_update (t_baddr, *fa); X INC_BA (t_baddr); X } X screen_update (t_baddr, *fa); X cursor_on (); X } X} X X X/* X * Set insert mode key. X */ Xkey_Insert () X{ X if (kybdlock) X return; X insert_mode (TRUE); X} X X X/* X * Catch and dispatch events coming in from suntools. There are currently X * two versions of this routine, one for type 3 keyboards (on Sun3's) and X * one for type 4 keyboards (on Sun 386i's). This should really be revamped X * and made more general using a user customizable key definition configuration X * file. Mouse actions are also handled in here. X */ X/*ARGSUSED*/ XNotify_value Xcanvas_event_proc (win, event, arg) XWindow win; XEvent *event; Xcaddr_t arg; X{ X register int baddr; X int cgcode; X X#ifdef DEBUG X printf ( X "event: code=%d, flags=0x%x, shiftmask=0x%x, x,y=%d,%d\n", X event->ie_code, event->ie_flags, event->ie_shiftmask, X event->ie_locx, event->ie_locy X ); X#endif X switch (event_id (event)) { X X /* function keys on top of keyboard */ X#ifdef TYPE4KBD X case KEY_TOP(1): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_AltCr (); X else X key_PF1 (); X break; X case KEY_TOP(2): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_CursorBlink (); X else X key_PF2 (); X break; X case KEY_TOP(3): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_Reset (); X else X key_PF3 (); X break; X case KEY_TOP(4): X key_PF4 (); X break; X case KEY_TOP(5): X key_PF5 (); X break; X case KEY_TOP(6): X key_PF6 (); X break; X case KEY_TOP(7): X key_PF7 (); X break; X case KEY_TOP(8): X key_PF8 (); X break; X case KEY_TOP(9): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_MonoCase (); X else X key_PF9 (); X break; X case KEY_TOP(10): X key_PF10 (); X break; X case KEY_TOP(11): X key_PF11 (); X break; X case KEY_TOP(12): X key_PF12 (); X break; X#else X case KEY_TOP(1): X key_AltCr (); X break; X case KEY_TOP(2): X key_CursorBlink (); X break; X case KEY_TOP(3): X key_Reset (); X break; X case KEY_TOP(9): X key_MonoCase (); X break; X#endif X X /* function keys on right of keyboard */ X case KEY_RIGHT(1): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PA1 (); X else X key_Dup (); X break; X case KEY_RIGHT(2): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PA2 (); X else X key_FieldMark (); X break; X case KEY_RIGHT(3): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_Clear (); X else X key_CursorSelect (); X break; X case KEY_RIGHT(4): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF13 (); X else X key_EraseEOF (); X break; X case KEY_RIGHT(5): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF14 (); X else X key_EraseInput (); X break; X case KEY_RIGHT(6): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF15 (); X else X key_SysReq (); X break; X case KEY_RIGHT(7): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF16 (); X else X key_Delete (); X break; X case KEY_RIGHT(8): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF17 (); X else X key_Up (); X break; X case KEY_RIGHT(9): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF18 (); X else X key_Insert (); X break; X case KEY_RIGHT(10): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF19 (); X else X key_Left (); X break; X case KEY_RIGHT(11): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF20 (); X else X key_Home (); X break; X case KEY_RIGHT(12): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF21 (); X else X key_Right (); X break; X case KEY_RIGHT(13): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF22 (); X else X key_Left2 (); X break; X case KEY_RIGHT(14): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF23 (); X else X key_Down (); X break; X case KEY_RIGHT(15): X if (event_shiftmask (event) & META_SHIFT_MASK) X key_PF24 (); X else X key_Right2 (); X break; X X /* mouse events */ X case MS_LEFT: /* left mouse move cursor under pointer */ X if (kybdlock) X return (NOTIFY_IGNORED); X baddr = ROWCOL_TO_BA(Y_TO_ROW (event_y (event)), X X_TO_COL (event_x (event))); X while (baddr >= (COLS * ROWS)) X baddr -= COLS; X cursor_move (baddr); X break; X case MS_MIDDLE: /* middle mouse sets selections */ X baddr = ROWCOL_TO_BA(Y_TO_ROW (event_y (event)), X X_TO_COL (event_x (event))); X while (baddr >= (COLS * ROWS)) X baddr -= COLS; X set_seln (cursor_addr, baddr); X break; X case MS_RIGHT: /* right mouse pops up canvas menu */ X if (event_is_down (event)) X menu_show (Key_menu, win, event, 0); X break; X case LOC_RGNENTER: /* mouse entered window */ X if (seln_acquire (s_client, SELN_CARET) != SELN_CARET) X fprintf (stderr, "can't acquire SELN_CARET!\n"); X break; X X#ifdef DEBUG X /* things we need to catch in order for stuff to work X * right, but we don't need to do anything explicitely X * with them. X */ X case LOC_RGNEXIT: X case KBD_USE: X case KBD_DONE: X case WIN_REPAINT: X case WIN_RESIZE: X break; X X /* the system seems to pass these on AFTER it's X * finished processing them. so we gotta ignore them. X */ X case KEY_LEFT(1): /* STOP */ X case KEY_LEFT(2): /* AGAIN */ X case KEY_LEFT(3): /* PROPS */ X case KEY_LEFT(4): /* UNDO */ X case KEY_LEFT(5): /* EXPOSE */ X case KEY_LEFT(6): /* PUT */ X case KEY_LEFT(7): /* OPEN */ X case KEY_LEFT(8): /* GET */ X case KEY_LEFT(9): /* FIND */ X case KEY_LEFT(10): /* DELETE */ X break; X#endif X X /* miscellany (character keys) */ X default: X if ((event_shiftmask (event) & META_SHIFT_MASK)) { X event_set_id (event, (event_id (event) & ~0x80)); X switch (event_id (event)) { X case 0x7F: /* delete */ X case 0x08: /* backspace */ X /* alt-delete or alt-backspace is home */ X key_Home (); X break; X case '1': X key_PF1 (); X break; X case '2': X key_PF2 (); X break; X case '3': X key_PF3 (); X break; X case '4': X key_PF4 (); X break; X case '5': X key_PF5 (); X break; X case '6': X key_PF6 (); X break; X case '7': X key_PF7 (); X break; X case '8': X key_PF8 (); X break; X case '9': X key_PF9 (); X break; X case '0': X key_PF10 (); X break; X case '-': X key_PF11 (); X break; X case '=': X key_PF12 (); X break; X default: X return (NOTIFY_IGNORED); X break; X } X } X else if ((event_id (event) >= ' ' && event_id (event) <= '~') X || event_id (event) == 0x1B) { X /* if a printable key or the escape key */ X if (event_id (event) == 0x1B X && (event_shiftmask (event) & SHIFTMASK) != 0) { X /* fake shift-ESC to something unique */ X event_set_id (event, 0x1C); X } X cgcode = asc2cg[event_id (event)]; X if (cgcode == CG_NULLBLANK) X return (NOTIFY_IGNORED); X else X (void) key_Character (cgcode); X } X else if (event_id (event) == 0x08) X key_Left (); X else if (event_id (event) == 0x09) X key_FTab (); X else if (event_id (event) == 0x0A) X key_Newline (); X else if (event_id (event) == 0x0D) X key_Enter (); X else if (event_id (event) == 0x7F) X key_BTab (); X else { X#ifdef DEBUG X fprintf (stderr, "unknown event: %d\n", event_id (event)); X#endif X return (NOTIFY_IGNORED); X } X break; X } X return (NOTIFY_DONE); X} X X X/* X * Initialize the canvas menu. X */ Xmenu_init () X{ X X Key_menu = menu_create ( X MENU_ITEM, X MENU_STRING, "Show/Hide Key Panel", X MENU_ACTION_PROC, key_panel_toggle, X 0, X MENU_PULLRIGHT_ITEM, "Other Keys", menu_create ( X MENU_ITEM, X MENU_STRING, "Reset", X MENU_ACTION_PROC, key_Reset, X 0, X MENU_ITEM, X MENU_STRING, "Erase EOF", X MENU_ACTION_PROC, key_EraseEOF, X 0, X MENU_ITEM, X MENU_STRING, "Erase Inp", X MENU_ACTION_PROC, key_EraseInput, X 0, X MENU_ITEM, X MENU_STRING, "Delete", X MENU_ACTION_PROC, key_Delete, X 0, X MENU_ITEM, X MENU_STRING, "Insert", X MENU_ACTION_PROC, key_Insert, X 0, X MENU_ITEM, X MENU_STRING, "Dup", X MENU_ACTION_PROC, key_Dup, X 0, X MENU_ITEM, X MENU_STRING, "FM", X MENU_ACTION_PROC, key_FieldMark, X 0, X MENU_ITEM, X MENU_STRING, "CursorSel", X MENU_ACTION_PROC, key_CursorSelect, X 0, X MENU_ITEM, X MENU_STRING, "Alternate Cursor", X MENU_ACTION_PROC, key_AltCr, X 0, X MENU_ITEM, X MENU_STRING, "Cursor Blink", X MENU_ACTION_PROC, key_CursorBlink, X 0, X MENU_ITEM, X MENU_STRING, "Monocase", X MENU_ACTION_PROC, key_MonoCase, X 0, X 0 X ), X MENU_ITEM, X MENU_STRING, "Stuff", X MENU_ACTION_PROC, stuff_seln, X 0, X 0 X ); X X} --End_of_kybd.c-- if test 28446 -ne `wc -c < 'kybd.c'` then echo "`basename $0`: error in" 'kybd.c' ": sent 28446 chars, received `wc -c < 'kybd.c'`" 1>&2 fi fi if test -f 'screen.c' then echo "`basename $0`: can't extract" 'screen.c' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_screen.c--' > 'screen.c' X/* X * Copyright 1989 by Georgia Tech Research Corporation, Atlanta, GA. X * Copyright 1988, 1989 by Robert Viduya. X * X * All Rights Reserved X */ X X/* X * screen.c X * This module handles interpretation of the 3270 data stream X * and other screen management actions. X */ X#include <sys/types.h> X#include <sys/time.h> X#include <errno.h> X#include <suntool/sunview.h> X#include <suntool/canvas.h> X#include <suntool/menu.h> X#include <stdio.h> X#include "3270.h" X#include "3270_enc.h" X X/* ebcdic to 3270 character generator xlate table */ X Xu_char ebc2cg[256] = { X CG_NULLBLANK, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_OVERBAR2, CG_OVERBAR6, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_OVERBAR3, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_OVERBAR1, CG_PERIOD, CG_PERIOD, X CG_DUP, CG_PERIOD, CG_FM, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_PERIOD, CG_PERIOD, CG_PERIOD, CG_OVERBAR4, X CG_BLANK, CG_LBRACKET, CG_RBRACKET, CG_POUND, X CG_YEN, CG_PT, CG_CURRENCY, CG_SHARPS, X CG_SECTION, CG_OVERSCORE, CG_CENT, CG_PERIOD, X CG_LESS, CG_LPAREN, CG_PLUS, CG_SOLIDBAR, X CG_AMPERSAND, CG_DEGREE, CG_BREVE, CG_CIRCUMFLEX, X CG_DIAERESIS, CG_ACUTE, CG_CEDILLA, CG_LAACUTE1, X CG_LEACUTE1, CG_LIACUTE1, CG_EXCLAMATION, CG_DOLLAR, X CG_ASTERISK, CG_RPAREN, CG_SEMICOLON, CG_NOT, X CG_MINUS, CG_FSLASH, CG_LOACUTE1, CG_LUACUTE1, X CG_LATILDE, CG_LOTILDE, CG_LYDIAERESIS, CG_LAACUTE2, X CG_LEACUTE2, CG_LEGRAVE1, CG_BROKENBAR, CG_COMMA, X CG_PERCENT, CG_UNDERSCORE, CG_GREATER, CG_QUESTION, X CG_LIACUTE2, CG_LOACUTE2, CG_LUACUTE2, CG_LUDIAERESIS1, X CG_LCCEDILLA1, CG_LADIAERESIS, CG_LEDIAERESIS, CG_LIDIAERESIS, X CG_LODIAERESIS, CG_GRAVE, CG_COLON, CG_NUMBER, X CG_AT, CG_SQUOTE, CG_EQUAL, CG_DQUOTE, X CG_LUDIAERESIS2,CG_LA, CG_LB, CG_LC, X CG_LD, CG_LE, CG_LF, CG_LG, X CG_LH, CG_LI, CG_LACIRCUMFLEX,CG_LECIRCUMFLEX, X CG_LICIRCUMFLEX,CG_LOCIRCUMFLEX,CG_LUCIRCUMFLEX,CG_LAGRAVE, X CG_LEGRAVE2, CG_LJ, CG_LK, CG_LL, X CG_LM, CG_LN, CG_LO, CG_LP, X CG_LQ, CG_LR, CG_LIGRAVE, CG_LOGRAVE, X CG_LUGRAVE, CG_LNTILDE, CG_CAACUTE, CG_CEACUTE, X CG_CIACUTE, CG_TILDE, CG_LS, CG_LT, X CG_LU, CG_LV, CG_LW, CG_LX, X CG_LY, CG_LZ, CG_COACUTE, CG_CUACUTE, X CG_CATILDE, CG_COTILDE, CG_CY1, CG_CA1, X CG_CE1, CG_CE2, CG_CI1, CG_CO1, X CG_CU1, CG_CY2, CG_CC1, CG_CADIAERESIS, X CG_CEDIAERESIS, CG_CIDIAERESIS, CG_CODIAERESIS, CG_CUDIAERESIS, X CG_CACIRCUMFLEX,CG_CECIRCUMFLEX,CG_CICIRCUMFLEX,CG_COCIRCUMFLEX, X CG_LBRACE, CG_CA, CG_CB, CG_CC, X CG_CD, CG_CE, CG_CF, CG_CG, X CG_CH, CG_CI, CG_CUCIRCUMFLEX,CG_CAGRAVE, X CG_CEGRAVE, CG_CIGRAVE, CG_PERIOD, CG_PERIOD, X CG_RBRACE, CG_CJ, CG_CK, CG_CL, X CG_CM, CG_CN, CG_CO, CG_CP, X CG_CQ, CG_CR, CG_COGRAVE, CG_CUGRAVE, X CG_CNTILDE, CG_PERIOD, CG_PERIOD, CG_PERIOD, X CG_BSLASH, CG_LAE, CG_CS, CG_CT, X CG_CU, CG_CV, CG_CW, CG_CX, X CG_CY, CG_CZ, CG_SSLASH0, CG_LADOT, X CG_LCCEDILLA2, CG_PERIOD, CG_PERIOD, CG_MINUS, X CG_ZERO, CG_ONE, CG_TWO, CG_THREE, X CG_FOUR, CG_FIVE, CG_SIX, CG_SEVEN, X CG_EIGHT, CG_NINE, CG_CAE, CG_BSLASH0, X CG_CADOT, CG_CCCEDILLA, CG_MINUS, CG_OVERBAR7 X}; X X/* 3270 character generator to ebcdic xlate table */ X/* generated programmatically from ebc2cg */ X Xu_char cg2ebc[256] = { X 0x00, 0x19, 0x0c, 0x15, 0x3f, 0x00, 0x0d, 0xff, /* 0x00 */ X 0x6e, 0x4c, 0x41, 0x42, 0x5d, 0x4d, 0xd0, 0xc0, X 0x40, 0x7e, 0x7d, 0x7f, 0x61, 0xe0, 0x4f, 0x6a, /* 0x10 */ X 0x6f, 0x5a, 0x5b, 0x4a, 0x43, 0x44, 0x45, 0x46, X 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x20 */ X 0xf8, 0xf9, 0x47, 0x48, 0x7b, 0x7c, 0x6c, 0x6d, X 0x50, 0x60, 0x4b, 0x6b, 0x7a, 0x4e, 0x5f, 0x49, /* 0x30 */ X 0x51, 0x52, 0x53, 0xa1, 0x54, 0x79, 0x55, 0x56, X 0x57, 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, /* 0x40 */ X 0x67, 0x68, 0x69, 0x70, 0x71, 0x72, 0x73, 0x74, X 0x75, 0x76, 0x77, 0x78, 0x80, 0x8a, 0x8b, 0x8c, /* 0x50 */ X 0x8d, 0x8e, 0x8f, 0x90, 0x9a, 0x9b, 0x9c, 0x9d, X 0x9e, 0x9f, 0xa0, 0xaa, 0xab, 0xac, 0xad, 0xae, /* 0x60 */ X 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, X 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, /* 0x70 */ X 0xbf, 0xca, 0xcb, 0xcc, 0xcd, 0xda, 0xdb, 0xdc, X 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, /* 0x80 */ X 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, X 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x90 */ X 0xa8, 0xa9, 0xe1, 0xea, 0xeb, 0xec, 0x1e, 0x1c, X 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, /* 0xA0 */ X 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, X 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xB0 */ X 0xe8, 0xe9, 0xfa, 0xfb, 0xfc, 0xfd, 0x5e, 0x5c, X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC0 */ X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD0 */ X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xE0 */ X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xF0 */ X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 X}; X X#define ITIMER_NULL ((struct itimerval *) 0) X#define TIMER_IVAL 250000L /* usec's */ X X/* code_table is used to translate buffer addresses to the 3270 X * datastream representation X */ Xu_char code_table[64] = { X 0x40, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, X 0xC8, 0xC9, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, X 0x50, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, X 0xD8, 0xD9, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, X 0x60, 0x61, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, X 0xE8, 0xE9, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, X 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, X 0xF8, 0xF9, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, X}; X Xextern Frame frame; XCanvas canvas; XPixwin *pixwin; XCursor cursor; XPixfont *ibmfont; Xint cursor_addr, buffer_addr; Xbool cursor_displayed = FALSE; Xbool cursor_blink_on = TRUE; Xbool cursor_alt = FALSE, cursor_blink = FALSE; Xbool mono_case = FALSE; X X/* the following are set from values in the 3270 font */ Xint char_width, char_height, char_base; X Xu_char screen_buf[ROWS * COLS]; Xbool formatted = FALSE; /* set in screen_disp */ Xstruct itimerval blink_timer; X Xextern u_char obuf[], *obptr; Xextern u_char aid; X XNotify_value timer (); Xextern Notify_value canvas_event_proc (); X X X/* X * Initialize the screen canvas. Should only be called once. X */ Xscreen_init () X{ X if ((ibmfont = pf_open (FONT3270)) == (Pixfont *) 0) { X perror ("3270tool: can't open 3270.font"); X exit (1); X } X char_width = CHAR_WIDTH; X char_height = CHAR_HEIGHT; X char_base = CHAR_BASE; X canvas = window_create ( X frame, CANVAS, X CANVAS_AUTO_EXPAND, FALSE, X CANVAS_AUTO_SHRINK, FALSE, X CANVAS_HEIGHT, ROW_TO_Y (ROWS + 1) + 4, X CANVAS_WIDTH, COL_TO_X (COLS), X CANVAS_MARGIN, 0, X CANVAS_RETAINED, TRUE, X WIN_HEIGHT, ROW_TO_Y (ROWS + 1) + 4 + 0, X WIN_WIDTH, COL_TO_X (COLS) + 0, X WIN_EVENT_PROC, canvas_event_proc, X WIN_CONSUME_PICK_EVENTS,WIN_NO_EVENTS, X LOC_WINENTER, X LOC_WINEXIT, X WIN_MOUSE_BUTTONS, X WIN_UP_EVENTS, X 0, X WIN_CONSUME_KBD_EVENTS, WIN_NO_EVENTS, X KBD_USE, X KBD_DONE, X WIN_ASCII_EVENTS, X WIN_LEFT_KEYS, X WIN_RIGHT_KEYS, X WIN_TOP_KEYS, X 0, X 0 X ); X cursor = window_get (canvas, WIN_CURSOR); X cursor_set (cursor, CURSOR_OP, PIX_SRC^PIX_DST, 0); X window_set (canvas, WIN_CURSOR, cursor, 0); X window_fit (canvas); X window_fit (frame); X pixwin = canvas_pixwin (canvas); X pw_vector ( X pixwin, X 0, ROW_TO_Y (ROWS) + 2, X COL_TO_X (COLS), ROW_TO_Y (ROWS) + 2, X PIX_SET, 1 X ); X bzero ((char *) screen_buf, sizeof (screen_buf)); X cursor_addr = 0; X buffer_addr = 0; X pw_batch_on (pixwin); X screen_disp (); X cursor_on (); X status_disp (0, CG_BOX4); X status_disp (1, CG_UNDERA); X status_disp (2, CG_BOXSOLID); X blink_timer.it_interval.tv_sec = 0; X blink_timer.it_interval.tv_usec = TIMER_IVAL; X blink_timer.it_value.tv_sec = 0; X blink_timer.it_value.tv_usec = TIMER_IVAL; X (void) notify_set_itimer_func (&blink_timer, timer, ITIMER_REAL, &blink_timer, ITIMER_NULL); X} X X X/* X * Update the status line by displaying "symbol" at column "col". X */ Xstatus_disp (col, symbol) Xint col, symbol; X{ X PW_CHAR (pixwin, COL_TO_X (col), ROW_TO_Y (ROWS) + 4, PIX_SRC, symbol); X} X X X/* X * Timer function for implementing cursor blink. X */ X/*ARGSUSED*/ XNotify_value Xtimer (client, which) XNotify_client client; Xint which; X{ X if (cursor_blink && cursor_displayed) { /* blink the cursor */ X cursor_blink_on = !cursor_blink_on; X if (cursor_alt) X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr)), X COL_TO_X (1), X ROW_TO_Y (1), X PIX_SET^PIX_DST X ); X else X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr) + 1) - 1, X COL_TO_X (1), X 1, X PIX_SET^PIX_DST X ); X } X return (NOTIFY_DONE); X} X X X/* X * Turn off the timer/cursor-blink so we can safely update the screen. X */ Xtimer_hold () X{ X (void) notify_set_itimer_func (&blink_timer, timer, ITIMER_REAL, ITIMER_NULL, ITIMER_NULL); X if (cursor_blink && cursor_displayed && !cursor_blink_on) { X cursor_blink_on = TRUE; X if (cursor_alt) X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr)), X COL_TO_X (1), X ROW_TO_Y (1), X PIX_SET^PIX_DST X ); X else X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr) + 1) - 1, X COL_TO_X (1), X 1, X PIX_SET^PIX_DST X ); X } X} X X X/* X * Turn on the timer/cursor-blink after we have safely updated the screen. X */ Xtimer_release () X{ X cursor_blink_on = TRUE; X blink_timer.it_interval.tv_sec = 0; X blink_timer.it_interval.tv_usec = TIMER_IVAL; X blink_timer.it_value.tv_sec = 0; X blink_timer.it_value.tv_usec = TIMER_IVAL; X (void) notify_set_itimer_func (&blink_timer, timer, ITIMER_REAL, &blink_timer, ITIMER_NULL); X} X X X/* X * Toggle cursor blink X */ Xblink_cursor (on) Xbool on; X{ X timer_hold (); X cursor_blink = on; X timer_release (); X} X X X/* X * Make the cursor disappear. X */ Xcursor_off () X{ X timer_hold (); X if (cursor_displayed) { X cursor_displayed = FALSE; X pw_batch_on (pixwin); X if (cursor_alt) X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr)), X COL_TO_X (1), X ROW_TO_Y (1), X PIX_SET^PIX_DST X ); X else X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr) + 1) - 1, X COL_TO_X (1), X 1, X PIX_SET^PIX_DST X ); X } X timer_release (); X clear_seln (); X} X X X/* X * Make the cursor visible. X */ Xcursor_on () X{ X timer_hold (); X if (!cursor_displayed) { X if (cursor_alt) X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr)), X COL_TO_X (1), X ROW_TO_Y (1), X PIX_SET^PIX_DST X ); X else X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr) + 1) - 1, X COL_TO_X (1), X 1, X PIX_SET^PIX_DST X ); X cursor_displayed = TRUE; X pw_batch_off (pixwin); X } X timer_release (); X} X X X/* X * Toggle the cursor (block/underline). X */ Xalt_cursor (alt) Xbool alt; X{ X if (alt != cursor_alt) { X cursor_off (); X cursor_alt = alt; X cursor_on (); X } X} X X X/* X * Move the cursor to the specified buffer address. X */ Xcursor_move (baddr) Xint baddr; X{ X timer_hold (); X if (cursor_displayed) { X if (cursor_alt) X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr)), X COL_TO_X (1), X ROW_TO_Y (1), X PIX_SET^PIX_DST X ); X else X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr) + 1) - 1, X COL_TO_X (1), X 1, X PIX_SET^PIX_DST X ); X } X cursor_addr = baddr; X if (cursor_displayed) { X if (cursor_alt) X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr)), X COL_TO_X (1), X ROW_TO_Y (1), X PIX_SET^PIX_DST X ); X else X pw_writebackground ( X pixwin, X COL_TO_X (BA_TO_COL (cursor_addr)), X ROW_TO_Y (BA_TO_ROW (cursor_addr) + 1) - 1, X COL_TO_X (1), X 1, X PIX_SET^PIX_DST X ); X } X timer_release (); X} X X X/* X * Redraw the entire screen. X */ Xscreen_disp () X{ X register int baddr, sbaddr; X register u_char ch; X bool is_zero, is_high; X X cursor_off (); X formatted = FALSE; X baddr = 0; X do { X if (IS_FA (screen_buf[baddr])) { X formatted = TRUE; X break; X } X INC_BA (baddr); X } while (baddr != 0); X if (formatted) { /* formatted display */ X sbaddr = baddr; X do { X is_zero = FA_IS_ZERO (screen_buf[baddr]); X is_high = FA_IS_HIGH (screen_buf[baddr]); X do { /* display the field */ X INC_BA (baddr); X if (is_zero) X ch = CG_BLANK; X else { X ch = screen_buf[baddr]; X /* this if xlates lowercase to uppercase */ X if (mono_case && ((ch & 0xE0) == 0x40 || (ch & 0xE0) == 0x80)) X ch |= 0x20; X } X PW_CHAR ( X pixwin, X COL_TO_X (BA_TO_COL (baddr)), X ROW_TO_Y (BA_TO_ROW (baddr)), X PIX_SRC, ch X ); X if (is_high) X PW_CHAR ( X pixwin, X COL_TO_X (BA_TO_COL (baddr)) + 1, X ROW_TO_Y (BA_TO_ROW (baddr)), X PIX_SRC|PIX_DST, ch X ); X } while (!IS_FA (screen_buf[baddr])); X } while (baddr != sbaddr); X } X else { /* unformatted display */ X baddr = 0; X do { X ch = screen_buf[baddr]; X /* this if xlates lowercase to uppercase */ X if (mono_case && ((ch & 0xE0) == 0x40 || (ch & 0xE0) == 0x80)) X ch |= 0x20; X PW_CHAR ( X pixwin, X COL_TO_X (BA_TO_COL (baddr)), X ROW_TO_Y (BA_TO_ROW (baddr)), X PIX_SRC, ch X ); X INC_BA (baddr); X } while (baddr != 0); X } X cursor_on (); X} X X X/* X * Set the formatted screen flag. A formatted screen is a screen that X * has at least one field somewhere on it. X */ Xset_formatted () X{ X register int baddr; X X formatted = FALSE; X baddr = 0; X do { X if (IS_FA (screen_buf[baddr])) { X formatted = TRUE; X break; X } X INC_BA (baddr); X } while (baddr != 0); X} X X X/* X * Find the field attribute for the given buffer address. X */ Xu_char * Xget_field_attribute (baddr) Xregister int baddr; X{ X static u_char fake_fa; X int sbaddr; X X sbaddr = baddr; X do { X if (IS_FA (screen_buf[baddr])) X return (&(screen_buf[baddr])); X DEC_BA (baddr); X } while (baddr != sbaddr); X fake_fa = 0xE0; X return (&fake_fa); X} X X X/* X * Update the character on the screen addressed by the given buffer address X * from the off-screen buffer. X */ Xscreen_update (baddr, fa) Xregister int baddr; Xu_char fa; X{ X register u_char ch; X bool is_zero, is_high; X X is_zero = FA_IS_ZERO (fa); X is_high = FA_IS_HIGH (fa); X if (is_zero) X ch = CG_BLANK; X else { X ch = screen_buf[baddr]; X /* this if xlates lowercase to uppercase */ X if (mono_case && ((ch & 0xE0) == 0x40 || (ch & 0xE0) == 0x80)) X ch |= 0x20; X } X PW_CHAR ( X pixwin, X COL_TO_X (BA_TO_COL (baddr)), X ROW_TO_Y (BA_TO_ROW (baddr)), X PIX_SRC, ch X ); X if (is_high) X PW_CHAR ( X pixwin, X COL_TO_X (BA_TO_COL (baddr)) + 1, X ROW_TO_Y (BA_TO_ROW (baddr)), X PIX_SRC|PIX_DST, ch X ); X} X X X/* X * Toggle mono-/dual-case mode. X */ Xchange_case (mono) Xbool mono; X{ X if (mono_case != mono) { X mono_case = mono; X screen_disp (); X } X} X X X/* X * Interpret an incoming 3270 datastream. X */ Xnet_process (buf, buflen) Xu_char *buf; Xint buflen; X{ X switch (buf[0]) { /* 3270 command */ X case CMD_EAU: /* erase all unprotected */ X do_erase_all_unprotected (); X break; X case CMD_EWA: /* erase/write alternate */ X /* on 3278-2, same as erase/write. fallthrough */ X case CMD_EW: /* erase/write */ X bzero ((char *) screen_buf, sizeof (screen_buf)); X buffer_addr = 0; X cursor_off (); X pw_writebackground (pixwin, 0, 0, COL_TO_X (COLS), ROW_TO_Y (ROWS), PIX_CLR); X cursor_move (0); X /* fallthrough into write */ X case CMD_W: /* write */ X do_write (buf, buflen); X break; X case CMD_RB: /* read buffer */ X do_read_buffer (); X break; X case CMD_RM: /* read modifed */ X do_read_modified (); X break; X case CMD_NOP: /* no-op */ X break; X default: X /* unknown 3270 command */ X exit (1); X } X} X X X/* X * Process a 3270 Read-Modified command and transmit the data back to the X * host. X */ Xdo_read_modified () X{ X register int baddr, sbaddr; X X obptr = &obuf[0]; X if (aid != AID_PA1 && aid != AID_PA2 X && aid != AID_PA3 && aid != AID_CLEAR) { X if (aid == AID_SYSREQ) { X *obptr++ = 0x01; /* soh */ X *obptr++ = 0x5B; /* % */ X *obptr++ = 0x61; /* / */ X *obptr++ = 0x02; /* stx */ X } X else { X *obptr++ = aid; X *obptr++ = code_table[(cursor_addr >> 6) & 0x3F]; X *obptr++ = code_table[cursor_addr & 0x3F]; X } X baddr = 0; X if (formatted) { X /* find first field attribute */ X do { X if (IS_FA (screen_buf[baddr])) X break; X INC_BA (baddr); X } while (baddr != 0); X sbaddr = baddr; X do { X if (FA_IS_MODIFIED (screen_buf[baddr])) { X INC_BA (baddr); X *obptr++ = ORDER_SBA; X *obptr++ = code_table[(baddr >> 6) & 0x3F]; X *obptr++ = code_table[baddr & 0x3F]; X do { X if (screen_buf[baddr]) X *obptr++ = cg2ebc[screen_buf[baddr]]; X INC_BA (baddr); X } while (!IS_FA (screen_buf[baddr])); X } X else { /* not modified - skip */ X do { X INC_BA (baddr); X } while (!IS_FA (screen_buf[baddr])); X } X } while (baddr != sbaddr); X } X else { X do { X if (screen_buf[baddr]) X *obptr++ = cg2ebc[screen_buf[baddr]]; X INC_BA (baddr); X } while (baddr != 0); X } X } X else X *obptr++ = aid; X net_output (obuf, obptr - obuf); X} X X X/* X * Process a 3270 Read-Buffer command and transmit the data back to the X * host. X */ Xdo_read_buffer () X{ X register int baddr; X u_char fa; X X obptr = &obuf[0]; X *obptr++ = aid; X *obptr++ = code_table[(cursor_addr >> 6) & 0x3F]; X *obptr++ = code_table[cursor_addr & 0x3F]; X baddr = 0; X do { X if (IS_FA (screen_buf[baddr])) { X *obptr++ = ORDER_SF; X fa = 0x00; X if (FA_IS_PROTECTED (screen_buf[baddr])) X fa |= 0x20; X if (FA_IS_NUMERIC (screen_buf[baddr])) X fa |= 0x10; X if (FA_IS_MODIFIED (screen_buf[baddr])) X fa |= 0x01; X fa |= ((screen_buf[baddr] | FA_INTENSITY) << 2); X *obptr++ = fa; X } X else X *obptr++ = cg2ebc[screen_buf[baddr]]; X INC_BA (baddr); X } while (baddr != 0); X net_output (obuf, obptr - obuf); X} X X X/* X * Process a 3270 Erase All Unprotected command. X */ Xdo_erase_all_unprotected () X{ X register int baddr, sbaddr; X u_char fa; X bool f; X X cursor_off (); X if (formatted) { X /* find first field attribute */ X baddr = 0; X do { X if (IS_FA (screen_buf[baddr])) X break; X INC_BA (baddr); X } while (baddr != 0); X sbaddr = baddr; X f = FALSE; X do { X fa = screen_buf[baddr]; X if (!FA_IS_PROTECTED (fa)) { X screen_buf[baddr] &= ~FA_MODIFY; X do { X INC_BA (baddr); X if (!f) { X cursor_move (baddr); X f = TRUE; X } X if (!IS_FA (screen_buf[baddr])) { X screen_buf[baddr] = CG_NULLBLANK; X screen_update (baddr, fa); X } X } while (!IS_FA (screen_buf[baddr])); X } X else { X do { X INC_BA (baddr); X } while (!IS_FA (screen_buf[baddr])); X } X } while (baddr != sbaddr); X if (!f) X cursor_move (0); X } X else { X bzero ((char *) screen_buf, sizeof (screen_buf)); X pw_writebackground (pixwin, 0, 0, COL_TO_X (COLS), ROW_TO_Y (ROWS), PIX_CLR); X buffer_addr = 0; X cursor_move (0); X } X cursor_on (); X aid = AID_NO; X key_Reset (); X} X X X/* X * Process a 3270 Write command. X */ Xdo_write (buf, buflen) Xu_char buf[]; Xint buflen; X{ X register u_char *cp; X register int baddr; X u_char *current_fa; X bool last_cmd; X bool wcc_keyboard_restore, wcc_sound_alarm; X X buffer_addr = cursor_addr; X wcc_sound_alarm = WCC_SOUND_ALARM (buf[1]); X wcc_keyboard_restore = WCC_KEYBOARD_RESTORE (buf[1]); X status_disp (8, CG_LOCK); X status_disp (9, CG_BLANK); X status_disp (10, CG_CS); X status_disp (11, CG_CY); X status_disp (12, CG_CS); X status_disp (13, CG_CT); X status_disp (14, CG_CE); X status_disp (15, CG_CM); X if (WCC_RESET_MDT (buf[1])) { X baddr = 0; X do { X if (IS_FA (screen_buf[baddr])) X screen_buf[baddr] &= ~FA_MODIFY; X INC_BA (baddr); X } while (baddr != 0); X } X last_cmd = TRUE; X cursor_off (); X current_fa = get_field_attribute (buffer_addr); X for (cp = &buf[2]; cp < (buf + buflen); cp++) { X switch (*cp) { X case ORDER_GE: /* graphic escape - ignore */ X last_cmd = TRUE; X break; X case ORDER_SF: /* start field */ X cp++; /* skip field attribute */ X screen_buf[buffer_addr] = FA_BASE; X if (*cp & 0x20) X screen_buf[buffer_addr] |= FA_PROTECT; X if (*cp & 0x10) X screen_buf[buffer_addr] |= FA_NUMERIC; X if (*cp & 0x01) X screen_buf[buffer_addr] |= FA_MODIFY; X screen_buf[buffer_addr] |= (*cp >> 2) & FA_INTENSITY; X current_fa = &(screen_buf[buffer_addr]); X screen_update (buffer_addr, *current_fa); X formatted = TRUE; X INC_BA (buffer_addr); X last_cmd = TRUE; X break; X case ORDER_SBA: /* set buffer address */ X cp += 2; /* skip buffer address */ X if ((*(cp-1) & 0xC0) == 0x00) /* 14-bit binary */ X buffer_addr = ((*(cp-1) & 0x3F) << 8) | *cp; X else /* 12-bit coded */ X buffer_addr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F); X buffer_addr %= (COLS * ROWS); X current_fa = get_field_attribute (buffer_addr); X last_cmd = TRUE; X break; X case ORDER_IC: /* insert cursor */ X cursor_move (buffer_addr); X last_cmd = TRUE; X break; X case ORDER_PT: /* program tab */ X baddr = buffer_addr; X while (TRUE) { X if (IS_FA (screen_buf[baddr]) X && (!FA_IS_PROTECTED (screen_buf[baddr]))) { X current_fa = &screen_buf[baddr]; X INC_BA (baddr); X buffer_addr = baddr; X if (!last_cmd) { X while (!IS_FA (screen_buf[baddr])) { X screen_buf[baddr] = CG_NULLBLANK; X screen_update (baddr, *current_fa); X INC_BA (baddr); X } X } X break; X } X else { X INC_BA (baddr); X if (baddr == 0) { X buffer_addr = baddr; X current_fa = get_field_attribute (baddr); X break; X } X } X } X last_cmd = TRUE; X break; X case ORDER_RA: /* repeat to address */ X cp += 2; /* skip buffer address */ X if ((*(cp-1) & 0xC0) == 0x00) /* 14-bit binary */ X baddr = ((*(cp-1) & 0x3F) << 8) | *cp; X else /* 12-bit coded */ X baddr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F); X baddr %= (COLS * ROWS); X cp++; /* skip char to repeat */ X if (*cp == ORDER_GE) X cp++; X if (buffer_addr == baddr) { X screen_buf[buffer_addr] = ebc2cg[*cp]; X screen_update (buffer_addr, *current_fa); X INC_BA (buffer_addr); X } X while (buffer_addr != baddr) { X screen_buf[buffer_addr] = ebc2cg[*cp]; X screen_update (buffer_addr, *current_fa); X INC_BA (buffer_addr); X } X current_fa = get_field_attribute (buffer_addr); X last_cmd = TRUE; X break; X case ORDER_EUA: /* erase unprotected to address */ X cp += 2; /* skip buffer address */ X if ((*(cp-1) & 0xC0) == 0x00) /* 14-bit binary */ X baddr = ((*(cp-1) & 0x3F) << 8) | *cp; X else /* 12-bit coded */ X baddr = ((*(cp-1) & 0x3F) << 6) | (*cp & 0x3F); X baddr %= (COLS * ROWS); X do { X if (IS_FA (screen_buf[buffer_addr])) X current_fa = &(screen_buf[buffer_addr]); X else if (!FA_IS_PROTECTED (*current_fa)) { X screen_buf[buffer_addr] = CG_NULLBLANK; X screen_update (buffer_addr, *current_fa); X } X INC_BA (buffer_addr); X } while (buffer_addr != baddr); X current_fa = get_field_attribute (buffer_addr); X last_cmd = TRUE; X break; X case ORDER_MF: /* modify field */ X case ORDER_SFE: /* start field extended */ X case ORDER_SA: /* set attribute */ X /* unsupported 3270 order */ X break; X default: /* enter character */ X screen_buf[buffer_addr] = ebc2cg[*cp]; X screen_update (buffer_addr, *current_fa); X INC_BA (buffer_addr); X last_cmd = FALSE; X break; X } X } X cursor_on (); X set_formatted (); X if (wcc_keyboard_restore) { X key_Reset (); X aid = AID_NO; X } X if (wcc_sound_alarm) X window_bell (canvas); X} --End_of_screen.c-- if test 24454 -ne `wc -c < 'screen.c'` then echo "`basename $0`: error in" 'screen.c' ": sent 24454 chars, received `wc -c < 'screen.c'`" 1>&2 fi fi if test -f 'README' then echo "`basename $0`: can't extract" 'README' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_README--' > 'README' X X Copyright 1989 by Georgia Tech Research Corporation, Atlanta, GA. X Copyright 1988, 1989 by Robert Viduya. X X All Rights Reserved X X XTwo things to do before compiling and installing 3270tool: X X 1. Copy 3270.font to wherever you want to keep it. It's the X vfont file that 3270tool requires to run. Change the X definition for FONT3270 in the Makefile to point to this file. X Also change the man page FILES section. X X 2. If you're compiling on a system with a type-4 keyboard, X add "-DTYPE4KBD" to the CFLAGS defintion in the Makefile. X This enables the special keyboard mapping described in X the manual page. X XTo compile: X make X XTo install: X make install X X XNotes: X X3270tool was written as a replacement for tn3270 after I got tired of Xhaving to remember all the key mappings. I fanatically wrote it to be as Xclose to a 3278 as possible. The font used was created by peering Xthrough a magnifying glass at a real IBM terminal and copying the Xsymbols pixel by pixel. The font encoding doesn't use EBCDIC, but Xinstead matches the 3270 character generator as documented in chapter X12 in the "3270 Information Display System - Character Set Reference" Xmanual. This actually made some operations easier. The drawback is Xthat incoming characters have to be mapped from EBCDIC to the internal Xmap. Other manuals used were "3270 Information Display System - Data XStream Programmer's Reference" and "3270 Information Display System - X3278 Display Station Operator's Guide". These manuals, particularly Xthe Programmer's Reference, are not for casual reading. X XSome future enhancements would be nice. Emulating a real 3270 light Xpen with the mouse wouldn't be difficult. Supporting different models Xof the 3278 so that Erase/Write-Alternate commands changes the screen Xsize would be a little more difficult. I don't have a color sun, so I Xdidn't put in color. Basic four color support shouldn't be that hard Xto add. Extended Field Attributes and Character Attributes are not Xsupported as well as Programmed Symbol Sets and Partitions. A Xmonochrome sun is capable of handling most of these, a color sun Xis capable of handling all of them. Printer support would also be nice. --End_of_README-- if test 2205 -ne `wc -c < 'README'` then echo "`basename $0`: error in" 'README' ": sent 2205 chars, received `wc -c < 'README'`" 1>&2 fi fi if test -f 'BtnClear' then echo "`basename $0`: can't extract" 'BtnClear' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_BtnClear--' > 'BtnClear' X/* Format_version=1, Width=32, Height=32, Depth=1, Valid_bits_per_item=16 X */ X 0xFFFF,0xFFFF,0x8000,0x0001,0x8000,0x0001,0x8000,0x0001, X 0x8000,0x0001,0x8000,0x0001,0x8000,0x0001,0x8000,0x0001, X 0x8000,0x0001,0x8000,0x0001,0x8000,0x0001,0x8000,0x0001, X 0x9860,0x0001,0xA421,0x8629,0xA022,0x4135,0xA023,0x8721, X 0xA422,0x0921,0x9821,0xC521,0x8000,0x0001,0x8000,0x0001, X 0x8000,0x0001,0x8000,0x0001,0x8000,0x0001,0x8000,0x0001, X 0x8000,0x0001,0x8000,0x0001,0x8000,0x0001,0x8000,0x0001, X 0x8000,0x0001,0x8000,0x0001,0x8000,0x0001,0xFFFF,0xFFFF --End_of_BtnClear-- if test 541 -ne `wc -c < 'BtnClear'` then echo "`basename $0`: error in" 'BtnClear' ": sent 541 chars, received `wc -c < 'BtnClear'`" 1>&2 fi fi exit 0 -- Robert Viduya robert@shangri-la.gatech.edu Office of Computing Services Georgia Institute of Technology (404) 894-6296 Atlanta, Georgia 30332-0275