From c4c5be520eebf89f8abee6a9e566f9f9941e35e8 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Tue, 29 Jan 2019 16:07:22 -0200 Subject: [PATCH] Fixing auto unlock when cursor moves. --- src/include/kybdc.h | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- src/include/lib3270.h | 2 ++ src/lib3270/cursor.c | 299 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib3270/kybd.c | 295 ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 4 files changed, 347 insertions(+), 302 deletions(-) create mode 100644 src/lib3270/cursor.c diff --git a/src/include/kybdc.h b/src/include/kybdc.h index 3cfc010..032d2cf 100644 --- a/src/include/kybdc.h +++ b/src/include/kybdc.h @@ -12,15 +12,51 @@ * for more details. */ -/* - * kybdc.h - * Global declarations for kybd.c. +/** + * @brief Global declarations for kybd.c. */ #ifndef KYBDC_H_INCLUDED #define KYBDC_H_INCLUDED + /// @brief Element in typeahead queue. + struct ta + { + struct ta *next; + + enum _ta_type + { + TA_TYPE_DEFAULT, + TA_TYPE_KEY_AID, + TA_TYPE_ACTION, + TA_TYPE_CURSOR_MOVE, + TA_TYPE_USER + } type; + + union + { + unsigned char aid_code; + struct + { + void (*fn)(H3270 *, const char *, const char *); + char *parm[2]; + } def; + + int (*action)(H3270 *); + + struct + { + LIB3270_DIRECTION direction; + unsigned char sel; + int (*fn)(H3270 *, LIB3270_DIRECTION, unsigned char); + } move; + + } args; + + }; + + /* keyboard lock states */ typedef enum lib3270_kl_state { @@ -54,26 +90,25 @@ #define KL_SCROLLED LIB3270_KL_SCROLLED #define KL_OIA_MINUS LIB3270_KL_OIA_MINUS - + #define KYBDLOCK_IS_OERR(hSession) (hSession->kybdlock && !(hSession->kybdlock & ~KL_OERR_MASK)) /* other functions */ LIB3270_INTERNAL void add_xk(KeySym key, KeySym assoc); LIB3270_INTERNAL void clear_xks(void); LIB3270_INTERNAL void do_reset(H3270 *session, Boolean explicit); -// LIB3270_INTERNAL void hex_input(char *s); -// #define kybdlock_clr(session, bits, cause) lib3270_kybdlock_clear(session, bits) LIB3270_INTERNAL void lib3270_kybdlock_clear(H3270 *hSession, LIB3270_KL_STATE bits); LIB3270_INTERNAL void kybd_inhibit(H3270 *session, Boolean inhibit); -// LIB3270_INTERNAL void kybd_init(void); LIB3270_INTERNAL int kybd_prime(H3270 *hSession); LIB3270_INTERNAL void kybd_scroll_lock(Boolean lock); - LIB3270_INTERNAL int run_ta(H3270 *hSession); -// LIB3270_INTERNAL int state_from_keymap(char keymap[32]); LIB3270_INTERNAL void kybd_connect(H3270 *session, int connected, void *dunno); LIB3270_INTERNAL void kybd_in3270(H3270 *session, int in3270, void *dunno); + LIB3270_INTERNAL int run_ta(H3270 *hSession); + LIB3270_INTERNAL struct ta * new_ta(H3270 *hSession, enum _ta_type type); + LIB3270_INTERNAL void enq_action(H3270 *hSession, int (*fn)(H3270 *)); + #endif /* KYBDC_H_INCLUDED */ diff --git a/src/include/lib3270.h b/src/include/lib3270.h index 53af2fa..89c5845 100644 --- a/src/include/lib3270.h +++ b/src/include/lib3270.h @@ -177,6 +177,8 @@ LIB3270_DIR_END, + LIB3270_DIR_COUNT /**< @brief Nº máximo de direções. */ + } LIB3270_DIRECTION; /** diff --git a/src/lib3270/cursor.c b/src/lib3270/cursor.c new file mode 100644 index 0000000..1ffa6cb --- /dev/null +++ b/src/lib3270/cursor.c @@ -0,0 +1,299 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +/** + * @brief This module handles cursor moves. + */ + + +#include "private.h" +#include +#include + +#include "kybdc.h" +#include "ctlrc.h" +#include "ansic.h" +#include "statusc.h" +#include "3270ds.h" + +/*---[ Prototipes ]---------------------------------------------------------------------------------*/ + +static int cursor_left(H3270 *hSession); +static int cursor_right(H3270 *hSession); +static int cursor_up(H3270 *hSession); +static int cursor_down(H3270 *hSession); +static int cursor_end(H3270 *hSession); + +/*---[ Globals ]------------------------------------------------------------------------------------*/ + + static const struct { + int (*exec)(H3270 *hSession); + } calls[LIB3270_DIR_COUNT] = { + { cursor_up }, + { cursor_down }, + { cursor_left }, + { cursor_right }, + { cursor_end } + }; + + +/*---[ Implement ]----------------------------------------------------------------------------------*/ + +/** + * @brief Move cursor. + * + * @param hSession Session handle. + * @param dir Where to move. + * @param sel Non zero if it's selecting. + * + * @return 0 if ok, non zero if not (sets errno). + * + */ +LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, unsigned char sel) +{ + FAIL_IF_NOT_ONLINE(hSession); + + if(dir < 0 || dir >= LIB3270_DIR_COUNT) + { + return errno = EINVAL; + } + + if (hSession->kybdlock) + { + if (KYBDLOCK_IS_OERR(hSession)) + { + lib3270_kybdlock_clear(hSession,KL_OERR_MASK); + status_reset(hSession); + } + else + { + struct ta *ta = new_ta(hSession, TA_TYPE_CURSOR_MOVE); + + ta->args.move.direction = dir; + ta->args.move.fn = lib3270_move_cursor; + ta->args.move.sel = sel; + return 0; + } + } + + int rc = calls[dir].exec(hSession); + if(rc) + return rc; + + if(sel) + lib3270_select_to(hSession,hSession->cursor_addr); + else if(hSession->selected && !lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_SELECTED)) + lib3270_unselect(hSession); + + return 0; +} + +LIB3270_EXPORT int lib3270_cursor_up(H3270 *hSession) +{ + return lib3270_move_cursor(hSession,LIB3270_DIR_UP,0); +} + +LIB3270_EXPORT int lib3270_cursor_down(H3270 *hSession) +{ + return lib3270_move_cursor(hSession,LIB3270_DIR_DOWN,0); +} + +LIB3270_EXPORT int lib3270_cursor_left(H3270 *hSession) +{ + return lib3270_move_cursor(hSession,LIB3270_DIR_LEFT,0); +} + +LIB3270_EXPORT int lib3270_cursor_right(H3270 *hSession) +{ + return lib3270_move_cursor(hSession,LIB3270_DIR_RIGHT,0); +} + +/** + * @brief Cursor left 1 position. + */ +static void do_left(H3270 *hSession) +{ + register int baddr; + enum dbcs_state d; + + baddr = hSession->cursor_addr; + DEC_BA(baddr); + d = ctlr_dbcs_state(baddr); + if (IS_LEFT(d)) + DEC_BA(baddr); + cursor_move(hSession,baddr); +} + +static int cursor_left(H3270 *hSession) +{ + if (hSession->kybdlock) + { + if(KYBDLOCK_IS_OERR(hSession)) + { + lib3270_kybdlock_clear(hSession,KL_OERR_MASK); + status_reset(hSession); + } + else + { + enq_action(hSession, cursor_left); + return 0; + } + } +#if defined(X3270_ANSI) /*[*/ + if (IN_ANSI) + { + ansi_send_left(hSession); + return 0; + } +#endif /*]*/ + + if (!hSession->flipped) + { + do_left(hSession); + } + else + { + register int baddr; + + baddr = hSession->cursor_addr; + INC_BA(baddr); + /* XXX: DBCS? */ + cursor_move(hSession,baddr); + } + return 0; +} + +static int cursor_right(H3270 *hSession) +{ + register int baddr; + enum dbcs_state d; + + if (hSession->kybdlock) + { + if (KYBDLOCK_IS_OERR(hSession)) + { + lib3270_kybdlock_clear(hSession,KL_OERR_MASK); + status_reset(hSession); + } + else + { + enq_action(hSession, cursor_right); + return 0; + } + } +#if defined(X3270_ANSI) /*[*/ + if (IN_ANSI) { + ansi_send_right(hSession); + return 0; + } +#endif /*]*/ + if (!hSession->flipped) + { + baddr = hSession->cursor_addr; + INC_BA(baddr); + d = ctlr_dbcs_state(baddr); + if (IS_RIGHT(d)) + INC_BA(baddr); + cursor_move(hSession,baddr); + } + else + { + do_left(hSession); + } + return 0; +} + +static int cursor_up(H3270 *hSession) +{ + register int baddr; + + trace("kybdlock=%d OERR=%s",(int) hSession->kybdlock, (KYBDLOCK_IS_OERR(hSession) ? "yes" : "no")); + if (hSession->kybdlock) + { + if (KYBDLOCK_IS_OERR(hSession)) + { + lib3270_kybdlock_clear(hSession,KL_OERR_MASK); + status_reset(hSession); + } + else + { + enq_action(hSession, cursor_up); + return 0; + } + } + +#if defined(X3270_ANSI) /*[*/ + if (IN_ANSI) { + ansi_send_up(hSession); + return 0; + } +#endif /*]*/ + + baddr = hSession->cursor_addr - hSession->cols; + if (baddr < 0) + baddr = (hSession->cursor_addr + (hSession->rows * hSession->cols)) - hSession->cols; + cursor_move(hSession,baddr); + return 0; +} + +static int cursor_down(H3270 *hSession) +{ + register int baddr; + + if (hSession->kybdlock) + { + if (KYBDLOCK_IS_OERR(hSession)) + { + lib3270_kybdlock_clear(hSession,KL_OERR_MASK); + status_reset(hSession); + } else + { + enq_action(hSession, cursor_down); +// enq_ta(Down_action, CN, CN); + return 0; + } + } +#if defined(X3270_ANSI) /*[*/ + if (IN_ANSI) + { + ansi_send_down(hSession); + return 0; + } +#endif /*]*/ + baddr = (hSession->cursor_addr + hSession->cols) % (hSession->cols * hSession->rows); + cursor_move(hSession,baddr); + return 0; +} + +static int cursor_end(H3270 *hSession) +{ + cursor_move(hSession,lib3270_get_field_end(hSession,hSession->cursor_addr)); + return 0; +} + diff --git a/src/lib3270/kybd.c b/src/lib3270/kybd.c index 22bb1b5..dca05ca 100644 --- a/src/lib3270/kybd.c +++ b/src/lib3270/kybd.c @@ -66,7 +66,6 @@ struct ta; #include "hostc.h" #include "kybdc.h" #include "popupsc.h" -// #include "printc.h" #include "screenc.h" #include "screen.h" #include "statusc.h" @@ -132,83 +131,8 @@ struct akeysym ((k1).keytype == (k2).keytype)) -struct ta -{ - struct ta *next; - - enum _ta_type - { - TA_TYPE_DEFAULT, - TA_TYPE_KEY_AID, - TA_TYPE_ACTION, - TA_TYPE_CURSOR_MOVE, - TA_TYPE_USER - } type; - - union - { - unsigned char aid_code; - struct - { - void (*fn)(H3270 *, const char *, const char *); - char *parm[2]; - } def; - - int (*action)(H3270 *); - - struct - { - LIB3270_DIRECTION direction; - unsigned char sel; - int (*fn)(H3270 *, LIB3270_DIRECTION, unsigned char); - } move; - - } args; - -}; - static const char dxl[] = "0123456789abcdef"; #define FROM_HEX(c) (strchr(dxl, tolower(c)) - dxl) -#define KYBDLOCK_IS_OERR(hSession) (hSession->kybdlock && !(hSession->kybdlock & ~KL_OERR_MASK)) - -/* - * Check if the typeahead queue is available - */ /* -static int enq_chk(H3270 *hSession) -{ - // If no connection, forget it. - if (!lib3270_connected(hSession)) - { - lib3270_trace_event(hSession," dropped (not connected)\n"); - return -1; - } - - // If operator error, complain and drop it. - if (hSession->kybdlock & KL_OERR_MASK) - { - lib3270_ring_bell(hSession); - lib3270_trace_event(hSession," dropped (operator error)\n"); - return -1; - } - - // If scroll lock, complain and drop it. - if (hSession->kybdlock & KL_SCROLLED) - { - lib3270_ring_bell(hSession); - lib3270_trace_event(hSession," dropped (scrolled)\n"); - return -1; - } - - // If typeahead disabled, complain and drop it. - if (!hSession->typeahead) - { - lib3270_trace_event(hSession," dropped (no typeahead)\n"); - return -1; - } - - return 0; -} -*/ /** * @brief Create a new typeahead action. @@ -217,7 +141,7 @@ static int enq_chk(H3270 *hSession) * * @return new typeahead struct or NULL if it's not available. */ -static struct ta * new_ta(H3270 *hSession, enum _ta_type type) +struct ta * new_ta(H3270 *hSession, enum _ta_type type) { struct ta *ta; @@ -313,7 +237,7 @@ static void enq_ta(H3270 *hSession, void (*fn)(H3270 *, const char *, const char lib3270_trace_event(hSession,"typeahead action queued (kybdlock 0x%x)\n", hSession->kybdlock); } -static void enq_action(H3270 *hSession, int (*fn)(H3270 *)) +void enq_action(H3270 *hSession, int (*fn)(H3270 *)) { struct ta *ta = new_ta(hSession, TA_TYPE_ACTION); @@ -1298,47 +1222,6 @@ static void do_left(H3270 *hSession) cursor_move(hSession,baddr); } -LIB3270_EXPORT int lib3270_cursor_left(H3270 *hSession) -{ - FAIL_IF_NOT_ONLINE(hSession); - - if (hSession->kybdlock) - { - if(KYBDLOCK_IS_OERR(hSession)) - { - lib3270_kybdlock_clear(hSession,KL_OERR_MASK); - status_reset(hSession); - } - else - { - enq_action(hSession, lib3270_cursor_left); - return 0; - } - } -#if defined(X3270_ANSI) /*[*/ - if (IN_ANSI) - { - ansi_send_left(hSession); - return 0; - } -#endif /*]*/ - - if (!hSession->flipped) - { - do_left(hSession); - } - else - { - register int baddr; - - baddr = hSession->cursor_addr; - INC_BA(baddr); - /* XXX: DBCS? */ - lib3270_set_cursor_address(hSession,baddr); - } - return 0; -} - /** * @brief Delete char key. * @@ -1584,51 +1467,6 @@ int lib3270_erase(H3270 *hSession) } /** - * @brief Cursor right 1 position. - */ -LIB3270_EXPORT int lib3270_cursor_right(H3270 *hSession) -{ - register int baddr; - enum dbcs_state d; - - FAIL_IF_NOT_ONLINE(hSession); - - if (hSession->kybdlock) - { - if (KYBDLOCK_IS_OERR(hSession)) - { - lib3270_kybdlock_clear(hSession,KL_OERR_MASK); - status_reset(hSession); - } - else - { - enq_action(hSession, lib3270_cursor_right); - return 0; - } - } -#if defined(X3270_ANSI) /*[*/ - if (IN_ANSI) { - ansi_send_right(hSession); - return 0; - } -#endif /*]*/ - if (!hSession->flipped) - { - baddr = hSession->cursor_addr; - INC_BA(baddr); - d = ctlr_dbcs_state(baddr); - if (IS_RIGHT(d)) - INC_BA(baddr); - lib3270_set_cursor_address(hSession,baddr); - } - else - { - do_left(hSession); - } - return 0; -} - -/** * @brief Cursor to previous word. */ LIB3270_EXPORT int lib3270_previousword(H3270 *hSession) @@ -1820,135 +1658,6 @@ LIB3270_EXPORT int lib3270_nextword(H3270 *hSession) } /** - * @brief Move cursor. - * - * @param hSession Session handle. - * @param dir Where to move. - * @param sel Non zero if it's selecting. - * - */ -LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, unsigned char sel) -{ - FAIL_IF_NOT_ONLINE(hSession); - - if (hSession->kybdlock) { - - struct ta *ta = new_ta(hSession, TA_TYPE_CURSOR_MOVE); - - ta->args.move.direction = dir; - ta->args.move.fn = lib3270_move_cursor; - ta->args.move.sel = sel; - - return 0; - } - - switch(dir) - { - case LIB3270_DIR_UP: - lib3270_cursor_up(hSession); - break; - - case LIB3270_DIR_DOWN: - lib3270_cursor_down(hSession); - break; - - case LIB3270_DIR_LEFT: - lib3270_cursor_left(hSession); - break; - - case LIB3270_DIR_RIGHT: - lib3270_cursor_right(hSession); - break; - - case LIB3270_DIR_END: - cursor_move(hSession,lib3270_get_field_end(hSession,hSession->cursor_addr)); - break; - - default: - errno = EINVAL; - return -1; - } - - if(sel) - lib3270_select_to(hSession,hSession->cursor_addr); - - return 0; -} - -/** - * @brief Cursor up 1 position. - */ -LIB3270_EXPORT int lib3270_cursor_up(H3270 *hSession) -{ - register int baddr; - - FAIL_IF_NOT_ONLINE(hSession); - - trace("kybdlock=%d OERR=%s",(int) hSession->kybdlock, (KYBDLOCK_IS_OERR(hSession) ? "yes" : "no")); - if (hSession->kybdlock) - { - if (KYBDLOCK_IS_OERR(hSession)) - { - lib3270_kybdlock_clear(hSession,KL_OERR_MASK); - status_reset(hSession); - } - else - { - enq_action(hSession, lib3270_cursor_up); - return 0; - } - } - -#if defined(X3270_ANSI) /*[*/ - if (IN_ANSI) { - ansi_send_up(hSession); - return 0; - } -#endif /*]*/ - - baddr = hSession->cursor_addr - hSession->cols; - if (baddr < 0) - baddr = (hSession->cursor_addr + (hSession->rows * hSession->cols)) - hSession->cols; - lib3270_set_cursor_address(hSession,baddr); - return 0; -} - -/** - * @brief Cursor down 1 position. - * - */ -LIB3270_EXPORT int lib3270_cursor_down(H3270 *hSession) -{ - register int baddr; - - FAIL_IF_NOT_ONLINE(hSession); - - if (hSession->kybdlock) - { - if (KYBDLOCK_IS_OERR(hSession)) - { - lib3270_kybdlock_clear(hSession,KL_OERR_MASK); - status_reset(hSession); - } else - { - enq_action(hSession, lib3270_cursor_down); -// enq_ta(Down_action, CN, CN); - return 0; - } - } -#if defined(X3270_ANSI) /*[*/ - if (IN_ANSI) - { - ansi_send_down(hSession); - return 0; - } -#endif /*]*/ - baddr = (hSession->cursor_addr + hSession->cols) % (hSession->cols * hSession->rows); - lib3270_set_cursor_address(hSession,baddr); - return 0; -} - -/** * @brief Cursor to first field on next line or any lines after that. */ LIB3270_EXPORT int lib3270_newline(H3270 *hSession) -- libgit2 0.21.2