diff --git a/lib3270.cbp b/lib3270.cbp index 859c305..82463d3 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -113,6 +113,9 @@ + + @@ -248,6 +251,7 @@ + diff --git a/src/core/host.c b/src/core/host.c index 9c664b0..bfaf4c1 100644 --- a/src/core/host.c +++ b/src/core/host.c @@ -174,97 +174,11 @@ void lib3270_set_disconnected(H3270 *hSession) } /** - * @brief Register a function interested in a state change. - * - * @param hSession Session handle. - * @param tx State ID - * @param func Callback - * @param data Data - * - * @return State change identifier. - * - */ -LIB3270_EXPORT const void * lib3270_register_schange(H3270 *hSession, LIB3270_STATE tx, void (*func)(H3270 *, int, void *),void *data) -{ - struct lib3270_state_callback *st; - - CHECK_SESSION_HANDLE(hSession); - - st = (struct lib3270_state_callback *) lib3270_malloc(sizeof(struct lib3270_state_callback)); - st->func = func; - st->data = data; - - if (hSession->listeners.state.last[tx]) - hSession->listeners.state.last[tx]->next = st; - else - hSession->listeners.state.callbacks[tx] = st; - - hSession->listeners.state.last[tx] = st; - - return (void *) st; - -} - -LIB3270_EXPORT int lib3270_unregister_schange(H3270 *hSession, LIB3270_STATE tx, const void * id) -{ - struct lib3270_state_callback *st; - struct lib3270_state_callback *prev = (struct lib3270_state_callback *) NULL; - -#ifdef DEBUG - { - debug("Before remove of %p (last=%p):",id,hSession->listeners.state.last[tx]); - - for (st = hSession->listeners.state.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) - { - debug("%p",st); - } - } -#endif // DEBUG - - for (st = hSession->listeners.state.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) - { - if (st == (struct lib3270_state_callback *)id) - break; - - prev = st; - } - - if (st == (struct lib3270_state_callback *)NULL) - { - lib3270_write_log(hSession,"lib3270","Invalid call to (%s): %p wasnt found in the list",__FUNCTION__,id); - return errno = ENOENT; - } - - if (prev != (struct lib3270_state_callback *) NULL) - prev->next = st->next; - else - hSession->listeners.state.callbacks[tx] = (struct lib3270_state_callback *) st->next; - - for(st = hSession->listeners.state.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) - hSession->listeners.state.last[tx] = st; - - lib3270_free((void *) id); - -#ifdef DEBUG - { - debug("After Remove of %p (last=%p):",id,hSession->listeners.state.last[tx]); - - for (st = hSession->listeners.state.callbacks[tx]; st != (struct lib3270_state_callback *) NULL; st = (struct lib3270_state_callback *) st->next) - { - debug("%p",st); - } - } -#endif // DEBUG - - return 0; -} - - -/** * @brief Signal a state change. */ void lib3270_st_changed(H3270 *h, LIB3270_STATE tx, int mode) { + /* #if defined(DEBUG) static const char * state_name[LIB3270_STATE_USER] = { @@ -280,7 +194,16 @@ void lib3270_st_changed(H3270 *h, LIB3270_STATE tx, int mode) "LIB3270_STATE_CHARSET" }; #endif // DEBUG + */ + + struct lib3270_linked_list_node * node; + + for(node = h->listeners.state[tx].first; node; node = node->next) + { + ((struct lib3270_state_callback *) node)->func(h,mode,node->userdata); + } + /* struct lib3270_state_callback *st; CHECK_SESSION_HANDLE(h); @@ -291,6 +214,7 @@ void lib3270_st_changed(H3270 *h, LIB3270_STATE tx, int mode) { st->func(h,mode,st->data); } + */ trace("%s ends",__FUNCTION__); } diff --git a/src/core/keyboard/properties.c b/src/core/keyboard/properties.c index 531a84a..1042f38 100644 --- a/src/core/keyboard/properties.c +++ b/src/core/keyboard/properties.c @@ -45,11 +45,22 @@ LIB3270_EXPORT int lib3270_set_lock_on_operator_error(H3270 *hSession, int enabl return 0; } +LIB3270_EXPORT int lib3270_set_numeric_lock(H3270 *hSession, int enable) +{ + hSession->numeric_lock = (enable ? 1 : 0); + return 0; +} + int lib3270_get_lock_on_operator_error(const H3270 *hSession) { return (int) hSession->oerr_lock; } +int lib3270_get_numeric_lock(const H3270 *hSession) +{ + return (int) hSession->numeric_lock; +} + LIB3270_EXPORT int lib3270_set_unlock_delay(H3270 *hSession, unsigned int delay) { hSession->unlock_delay = (delay == 0 ? 0 : 1); diff --git a/src/core/linkelist.c b/src/core/linkelist.c new file mode 100644 index 0000000..a47ae3e --- /dev/null +++ b/src/core/linkelist.c @@ -0,0 +1,139 @@ +/* + * "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 linkedlist.c 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 Handle linked lists. + */ + + #include + #include + #include + #include + +/*---[ Implement ]------------------------------------------------------------------------------------------------------------*/ + +void * lib3270_linked_list_append_node(struct lib3270_linked_list_head *head, size_t szBlock, void *userdata) +{ + struct lib3270_linked_list_node * node = lib3270_malloc(szBlock); + + memset(node,0,szBlock); + node->userdata = userdata; + + if(head->last) + { + head->last->next = node; + node->prev = head->last; + } + else + { + head->first = node; + } + + head->last = node; + +#ifdef DEBUG + { + struct lib3270_linked_list_node * dCurrent; + + debug("%s: head=%p first=%p last=%p", __FUNCTION__, head, head->first, head->last); + + for(dCurrent = head->first; dCurrent; dCurrent = dCurrent->next) + { + debug("node=%p prev=%p next=%p",dCurrent,dCurrent->prev,dCurrent->next); + } + + } +#endif // DEBUG + + return (void *) node; + +} + +int lib3270_linked_list_delete_node(struct lib3270_linked_list_head *head, const void *node) +{ + + struct lib3270_linked_list_node * current; + + for(current = head->first;current;current = current->next) + { + + if(current == node) + { + + if(current->prev) + current->prev->next = current->next; + else + head->first = current->next; + + if(current->next) + current->next->prev = current->prev; + else + head->last = current->prev; + + lib3270_free(current); + +#ifdef DEBUG + { + struct lib3270_linked_list_node * dCurrent; + + debug("%s: head=%p first=%p last=%p", __FUNCTION__, head, head->first, head->last); + + for(dCurrent = head->first; dCurrent; dCurrent = dCurrent->next) + { + debug("node=%p prev=%p next=%p",dCurrent,dCurrent->prev,dCurrent->next); + } + + } +#endif // DEBUG + + return 0; + + } + + } + + return errno = ENOENT; +} + +void lib3270_linked_list_free(struct lib3270_linked_list_head *head) +{ + struct lib3270_linked_list_node * node = head->first; + + while(node) + { + void * ptr = (void *) node; + node = node->next; + lib3270_free(ptr); + } + + head->first = head->last = NULL; + +} + diff --git a/src/core/properties/boolean.c b/src/core/properties/boolean.c index 1ba65eb..0f0d8e1 100644 --- a/src/core/properties/boolean.c +++ b/src/core/properties/boolean.c @@ -163,6 +163,13 @@ }, { + .name = "numericlock", // Property name. + .description = N_( "numeric lock" ), // Property description. + .get = lib3270_get_numeric_lock, // Get value. + .set = lib3270_set_numeric_lock // Set value. + }, + + { .name = NULL, .description = NULL, .get = NULL, diff --git a/src/core/session.c b/src/core/session.c index 3075568..02af5af 100644 --- a/src/core/session.c +++ b/src/core/session.c @@ -91,25 +91,12 @@ void lib3270_session_free(H3270 *h) // Release state change callbacks for(f=0;flisteners.state.callbacks[f]) - { - struct lib3270_state_callback *next = h->listeners.state.callbacks[f]->next; - lib3270_free(h->listeners.state.callbacks[f]); - h->listeners.state.callbacks[f] = next; - } - } + lib3270_linked_list_free(&h->listeners.state[f]); + // Release toggle change listeners. for(f=0;flisteners.toggle.callbacks[f]) - { - struct lib3270_toggle_callback *next = h->listeners.toggle.callbacks[f]->next; - lib3270_free(h->listeners.toggle.callbacks[f]); - h->listeners.toggle.callbacks[f] = next; - } - } + lib3270_linked_list_free(&h->listeners.toggle[f]); // Release memory #define release_pointer(x) lib3270_free(x); x = NULL; diff --git a/src/core/toggles/getset.c b/src/core/toggles/getset.c index 1f61118..50c1741 100644 --- a/src/core/toggles/getset.c +++ b/src/core/toggles/getset.c @@ -57,18 +57,26 @@ LIB3270_EXPORT unsigned char lib3270_get_toggle(const H3270 *hSession, LIB3270_T */ static void toggle_notify(H3270 *session, struct lib3270_toggle *t, LIB3270_TOGGLE_ID ix) { - struct lib3270_toggle_callback * st; - trace("%s: ix=%d upcall=%p",__FUNCTION__,ix,t->upcall); + t->upcall(session, t, LIB3270_TOGGLE_TYPE_INTERACTIVE); if(session->cbk.update_toggle) session->cbk.update_toggle(session,ix,t->value,LIB3270_TOGGLE_TYPE_INTERACTIVE,toggle_descriptor[ix].name); + // Notify customers. + struct lib3270_linked_list_node * node; + for(node = session->listeners.toggle[ix].first; node; node = node->next) + { + ((struct lib3270_toggle_callback *) node)->func(session, ix, t->value, node->userdata); + } + + /* for(st = session->listeners.toggle.callbacks[ix]; st != (struct lib3270_toggle_callback *) NULL; st = (struct lib3270_toggle_callback *) st->next) { st->func(session, ix, t->value, st->data); } + */ } diff --git a/src/core/toggles/listener.c b/src/core/toggles/listener.c index e252f21..c7b4540 100644 --- a/src/core/toggles/listener.c +++ b/src/core/toggles/listener.c @@ -46,20 +46,9 @@ LIB3270_EXPORT const void * lib3270_register_toggle_listener(H3270 *hSession, LIB3270_TOGGLE_ID tx, void (*func)(H3270 *, LIB3270_TOGGLE_ID, char, void *),void *data) { - struct lib3270_toggle_callback *st; + struct lib3270_toggle_callback *st = (struct lib3270_toggle_callback *) lib3270_linked_list_append_node(&hSession->listeners.toggle[tx], sizeof(struct lib3270_toggle_callback), data); - CHECK_SESSION_HANDLE(hSession); - - st = (struct lib3270_toggle_callback *) lib3270_malloc(sizeof(struct lib3270_toggle_callback)); - st->func = func; - st->data = data; - - if (hSession->listeners.toggle.last[tx]) - hSession->listeners.toggle.last[tx]->next = st; - else - hSession->listeners.toggle.callbacks[tx] = st; - - hSession->listeners.toggle.last[tx] = st; + st->func = func; return (void *) st; @@ -67,33 +56,33 @@ LIB3270_EXPORT const void * lib3270_register_toggle_listener(H3270 *hSession, LI LIB3270_EXPORT int lib3270_unregister_toggle_listener(H3270 *hSession, LIB3270_TOGGLE_ID tx, const void *id) { - struct lib3270_toggle_callback *st; - struct lib3270_toggle_callback *prev = (struct lib3270_toggle_callback *) NULL; - - for (st = hSession->listeners.toggle.callbacks[tx]; st != (struct lib3270_toggle_callback *) NULL; st = (struct lib3270_toggle_callback *) st->next) - { - if (st == (struct lib3270_toggle_callback *)id) - break; + return lib3270_linked_list_delete_node(&hSession->listeners.toggle[tx], id); +} - prev = st; - } +/** + * @brief Register a function interested in a state change. + * + * @param hSession Session handle. + * @param tx State ID + * @param func Callback + * @param data Data + * + * @return State change identifier. + * + */ +LIB3270_EXPORT const void * lib3270_register_schange(H3270 *hSession, LIB3270_STATE tx, void (*func)(H3270 *, int, void *),void *data) +{ + struct lib3270_state_callback * st = (struct lib3270_state_callback *) lib3270_linked_list_append_node(&hSession->listeners.state[tx], sizeof(struct lib3270_state_callback), data); - if (st == (struct lib3270_toggle_callback *)NULL) - { - lib3270_write_log(hSession,"lib3270","Invalid call to (%s): %p wasnt found in the list",__FUNCTION__,id); - return errno = ENOENT; - } + st->func = func; - if (prev != (struct lib3270_toggle_callback *) NULL) - prev->next = st->next; - else - hSession->listeners.toggle.callbacks[tx] = (struct lib3270_toggle_callback *) st->next; + return (void *) st; +} - for(st = hSession->listeners.toggle.callbacks[tx]; st != (struct lib3270_toggle_callback *) NULL; st = (struct lib3270_toggle_callback *) st->next) - hSession->listeners.toggle.last[tx] = st; +LIB3270_EXPORT int lib3270_unregister_schange(H3270 *hSession, LIB3270_STATE tx, const void * id) +{ + return lib3270_linked_list_delete_node(&hSession->listeners.state[tx], id); +} - lib3270_free((void *) id); - return 0; -} diff --git a/src/include/lib3270-internals.h b/src/include/lib3270-internals.h index 416ae88..50090a3 100644 --- a/src/include/lib3270-internals.h +++ b/src/include/lib3270-internals.h @@ -32,9 +32,9 @@ #include #endif // WIN32 -/* Autoconf settings. */ #include /* autoconf settings */ #include /* lib3270 API calls and defs */ +#include #include #include // #include "api.h" @@ -323,15 +323,15 @@ typedef struct _input_t struct lib3270_state_callback { - struct lib3270_state_callback * next; /**< @brief Next callback in chain */ - void * data; /**< @brief User data */ - void (*func)(H3270 *, int, void *); /**< @brief Function to call */ + LIB3270_LINKED_LIST_HEAD; + + void (*func)(H3270 *, int, void *); /**< @brief Function to call */ }; struct lib3270_toggle_callback { - struct lib3270_toggle_callback * next; /**< @brief Next callback in chain */ - void * data; /**< @brief User data */ + LIB3270_LINKED_LIST_HEAD; + void (*func)(H3270 *, LIB3270_TOGGLE_ID, char, void *); /**< @brief Function to call */ }; @@ -695,22 +695,14 @@ struct _h3270 void *userdata; } trace; - // Listeners. + /// @brief Event Listeners. struct { - // State. - struct - { - struct lib3270_state_callback * callbacks[LIB3270_STATE_USER]; - struct lib3270_state_callback * last[LIB3270_STATE_USER]; - } state; + /// @brief State listeners. + struct lib3270_linked_list_head state[LIB3270_STATE_USER]; - // Toggle change listeners - struct - { - struct lib3270_toggle_callback * callbacks[LIB3270_TOGGLE_COUNT]; - struct lib3270_toggle_callback * last[LIB3270_TOGGLE_COUNT]; - } toggle; + /// @brief Toggle listeners. + struct lib3270_linked_list_head toggle[LIB3270_TOGGLE_COUNT]; } listeners; diff --git a/src/include/lib3270/keyboard.h b/src/include/lib3270/keyboard.h index fbf4a2c..d42955c 100644 --- a/src/include/lib3270/keyboard.h +++ b/src/include/lib3270/keyboard.h @@ -85,6 +85,10 @@ LIB3270_EXPORT int lib3270_set_lock_on_operator_error(H3270 *hSession, int enable); LIB3270_EXPORT int lib3270_get_lock_on_operator_error(const H3270 *hSession); + LIB3270_EXPORT int lib3270_set_numeric_lock(H3270 *hSession, int enable); + LIB3270_EXPORT int lib3270_get_numeric_lock(const H3270 *hSession); + + #ifdef __cplusplus } #endif diff --git a/src/include/linkedlist.h b/src/include/linkedlist.h new file mode 100644 index 0000000..a24ba26 --- /dev/null +++ b/src/include/linkedlist.h @@ -0,0 +1,62 @@ +/* + * "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) + * + */ + +/** + * @file linkedlist.h + * @brief Global declarations for linkedlist.c. + */ + +#ifndef LIB3270_LINKED_LIST_H_INCLUDED + + #define LIB3270_LINKED_LIST_H_INCLUDED + + #include + #include + + #define LIB3270_LINKED_LIST_HEAD \ + struct lib3270_linked_list_node * prev; \ + struct lib3270_linked_list_node * next; \ + void * userdata; + + struct lib3270_linked_list_node + { + LIB3270_LINKED_LIST_HEAD + }; + + struct lib3270_linked_list_head + { + struct lib3270_linked_list_node * first; + struct lib3270_linked_list_node * last; + }; + + LIB3270_INTERNAL void * lib3270_linked_list_append_node(struct lib3270_linked_list_head *head, size_t szBlock, void *userdata); + LIB3270_INTERNAL int lib3270_linked_list_delete_node(struct lib3270_linked_list_head *head, const void *node); + LIB3270_INTERNAL void lib3270_linked_list_free(struct lib3270_linked_list_head *head); + +#endif // LIB3270_LINKED_LIST_H_INCLUDED -- libgit2 0.21.2