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