diff --git a/configure.ac b/configure.ac
index f26f4fa..deb6806 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,6 +51,9 @@ AC_CONFIG_HEADER([src/include/lib3270/config.h])
dnl Initialise automake stuff.
AM_INIT_AUTOMAKE
+dnl Check for iconv
+AM_ICONV
+
#--[ Check for tools & Libraries ]----------------------------------------------------------------------------------------------------------------------------
AC_PROG_CXX
diff --git a/pw3270.cbp b/pw3270.cbp
index ac233a6..4cc691c 100644
--- a/pw3270.cbp
+++ b/pw3270.cbp
@@ -235,6 +235,8 @@
+
+
diff --git a/src/include/lib3270.h b/src/include/lib3270.h
index 3115d75..79bd5f9 100644
--- a/src/include/lib3270.h
+++ b/src/include/lib3270.h
@@ -667,6 +667,9 @@
LIB3270_EXPORT int lib3270_in_tn3270e(H3270 *h);
LIB3270_EXPORT int lib3270_in_e(H3270 *h);
+ #define lib3270_is_connected(h) lib3270_in_tn3270e(h)
+ #define lib3270_is_ready(h) lib3270_get_program_message(h) == LIB3270_MESSAGE_NONE
+
LIB3270_EXPORT LIB3270_SSL_STATE lib3270_get_secure(H3270 *session);
@@ -746,6 +749,8 @@
*/
LIB3270_EXPORT const char * lib3270_get_charset(H3270 *session);
+ LIB3270_EXPORT const char * lib3270_get_default_charset(void);
+
/**
* Get selected area.
*
diff --git a/src/include/lib3270/config.h.in b/src/include/lib3270/config.h.in
index e90cd05..3276373 100644
--- a/src/include/lib3270/config.h.in
+++ b/src/include/lib3270/config.h.in
@@ -38,6 +38,7 @@
#undef PACKAGE_REVISION
#undef HAVE_GNUC_VISIBILITY
+ #undef HAVE_ICONV
#undef HAVE_LIBM
#undef HAVE_LIBINTL
#undef HAVE_GETADDRINFO
diff --git a/src/lib3270/charset.c b/src/lib3270/charset.c
index 8520c7b..976c793 100644
--- a/src/lib3270/charset.c
+++ b/src/lib3270/charset.c
@@ -726,10 +726,15 @@ void set_display_charset(H3270 *session, const char *dcs)
session->charset = strdup(dcs);
}
+LIB3270_EXPORT const char * lib3270_get_default_charset(void)
+{
+ return "ISO-8859-1";
+}
+
LIB3270_EXPORT const char * lib3270_get_charset(H3270 *session)
{
CHECK_SESSION_HANDLE(session);
- return session->charset ? session->charset : "ISO-8859-1";
+ return session->charset ? session->charset : lib3270_get_default_charset();
}
static KeySym StringToKeysym(char *s)
diff --git a/src/plugins/rx3270/Makefile.in b/src/plugins/rx3270/Makefile.in
index 5308d6d..bd1b8b1 100644
--- a/src/plugins/rx3270/Makefile.in
+++ b/src/plugins/rx3270/Makefile.in
@@ -29,7 +29,7 @@
MODULE_NAME=rx3270
DEPENDS=*.h ../../include/*.h ../../include/lib3270/*.h Makefile
PLUGIN_SRC=pluginmain.cc
-EXTAPI_SRC=rxapimain.cc
+EXTAPI_SRC=rxapimain.cc text.cc typed_routines.cc
#---[ Tools ]------------------------------------------------------------------
diff --git a/src/plugins/rx3270/rx3270.h b/src/plugins/rx3270/rx3270.h
index 4aaaa36..f83fe7c 100644
--- a/src/plugins/rx3270/rx3270.h
+++ b/src/plugins/rx3270/rx3270.h
@@ -38,13 +38,45 @@
#include
#include
+#ifdef HAVE_ICONV
+ #include
+#endif
+
+
/*---[ Exports ]---------------------------------------------------------------------------------------------*/
LIB3270_EXPORT RexxRoutineEntry rx3270_functions[];
LIB3270_EXPORT RexxPackageEntry rx3270_package_entry;
+/*---[ Rexx entry points ]-----------------------------------------------------------------------------------*/
+
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270version);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270QueryCState);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270Disconnect);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270Connect);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270isConnected);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270WaitForEvents);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270Sleep);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270SendENTERKey);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270SendPFKey);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270SendPAKey);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270WaitForTerminalReady);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270WaitForStringAt);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270GetStringAt);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270IsTerminalReady);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270ReadScreen);
+ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270queryStringAt);
+
/*---[ Globals ]---------------------------------------------------------------------------------------------*/
+ #define RX3270SESSION lib3270_get_default_session_handle()
+
+ char * get_contents(H3270 *hSession, int start, int sz);
+
+#ifdef HAVE_ICONV
+ extern iconv_t outputConv;
+ extern iconv_t inputConv;
+#endif
/*--[ Prototipes ]-------------------------------------------------------------------------------------------*/
diff --git a/src/plugins/rx3270/rxapimain.cc b/src/plugins/rx3270/rxapimain.cc
index 279f755..8224ece 100644
--- a/src/plugins/rx3270/rxapimain.cc
+++ b/src/plugins/rx3270/rxapimain.cc
@@ -36,15 +36,29 @@
*/
#include "rx3270.h"
+ #include
+
+#ifdef HAVE_ICONV
+ #include
+#endif
+
+ #include
#if defined WIN32
+
+ #define REXX_DEFAULT_CHARSET "CP1252"
+
BOOL WINAPI DllMain(HANDLE hinst, DWORD dwcallpurpose, LPVOID lpvResvd);
static int librx3270_loaded(void);
static int librx3270_unloaded(void);
#else
+
+ #define REXX_DEFAULT_CHARSET "UTF-8"
+
int librx3270_loaded(void) __attribute__((constructor));
int librx3270_unloaded(void) __attribute__((destructor));
#endif
+
/*--[ Implement ]------------------------------------------------------------------------------------*/
#if defined WIN32
@@ -68,44 +82,84 @@ BOOL WINAPI DllMain(HANDLE hinst, DWORD dwcallpurpose, LPVOID lpvResvd)
int librx3270_loaded(void)
{
- trace("%s %04x %s %s",__FUNCTION__,REXX_CURRENT_INTERPRETER_VERSION,__DATE__,__TIME__);
+#ifdef HAVE_ICONV
+ outputConv = iconv_open(REXX_DEFAULT_CHARSET, lib3270_get_default_charset());
+ inputConv = iconv_open(lib3270_get_default_charset(), REXX_DEFAULT_CHARSET);
+#endif
+
return 0;
}
int librx3270_unloaded(void)
{
- trace("%s",__FUNCTION__);
- return 0;
-}
+#ifdef HAVE_ICONV
-RexxRoutine0(CSTRING, rx3270version)
-{
- return lib3270_get_version();
-}
+ if(outputConv != (iconv_t) (-1))
+ iconv_close(outputConv);
-RexxRoutine0(CSTRING, rx3270QueryCState)
-{
- return "";
-}
+ if(inputConv != (iconv_t) (-1))
+ iconv_close(inputConv);
+#endif
-RexxRoutine0(int, rx3270Disconnect)
-{
return 0;
}
-RexxRoutine2(int, rx3270Connect, CSTRING, hostname, int, timeout)
-{
- return 0;
-}
+/*
+::method setStringAt
+ use arg row, col, str
+return rx3270InputString(row,col,str)
+
+::method setCursorPosition
+ use arg row, col
+return rx3270SetCursorPosition(row,col)
+
+::method RunMode
+return rx3270QueryRunMode()
+
+::method 'encoding='
+ use arg ptr
+return rx3270SetCharset(ptr)
+
+::method sendfile
+ use arg from, tostrncasecmp
+
+ status = rx3270BeginFileSend(from,to)
+ if status <> 0
+ then return status
+
+return rx3270WaitForFTComplete()
+
+::method recvfile
+ use arg from, to
+
+ status = rx3270BeginFileRecv(from,to)
+ if status <> 0
+ then return status
+
+return rx3270WaitForFTComplete()
+*/
// now build the actual entry list
RexxRoutineEntry rx3270_functions[] =
{
- REXX_TYPED_ROUTINE(rx3270version, rx3270version),
- REXX_TYPED_ROUTINE(rx3270QueryCState, rx3270QueryCState),
- REXX_TYPED_ROUTINE(rx3270Disconnect, rx3270Disconnect),
- REXX_TYPED_ROUTINE(rx3270Connect, rx3270Connect),
+ REXX_TYPED_ROUTINE(rx3270version, rx3270version),
+ REXX_TYPED_ROUTINE(rx3270QueryCState, rx3270QueryCState),
+ REXX_TYPED_ROUTINE(rx3270Disconnect, rx3270Disconnect),
+ REXX_TYPED_ROUTINE(rx3270Connect, rx3270Connect),
+ REXX_TYPED_ROUTINE(rx3270isConnected, rx3270isConnected),
+ REXX_TYPED_ROUTINE(rx3270WaitForEvents, rx3270WaitForEvents),
+ REXX_TYPED_ROUTINE(rx3270Sleep, rx3270Sleep),
+ REXX_TYPED_ROUTINE(rx3270SendENTERKey, rx3270SendENTERKey),
+ REXX_TYPED_ROUTINE(rx3270SendPFKey, rx3270SendPFKey),
+ REXX_TYPED_ROUTINE(rx3270SendPAKey, rx3270SendPAKey),
+ REXX_TYPED_ROUTINE(rx3270WaitForTerminalReady, rx3270WaitForTerminalReady),
+ REXX_TYPED_ROUTINE(rx3270WaitForStringAt, rx3270WaitForStringAt),
+ REXX_TYPED_ROUTINE(rx3270GetStringAt, rx3270GetStringAt),
+ REXX_TYPED_ROUTINE(rx3270IsTerminalReady, rx3270IsTerminalReady),
+ REXX_TYPED_ROUTINE(rx3270ReadScreen, rx3270ReadScreen),
+ REXX_TYPED_ROUTINE(rx3270queryStringAt, rx3270queryStringAt),
+
REXX_LAST_METHOD()
};
diff --git a/src/plugins/rx3270/text.cc b/src/plugins/rx3270/text.cc
new file mode 100644
index 0000000..d2c2fd0
--- /dev/null
+++ b/src/plugins/rx3270/text.cc
@@ -0,0 +1,81 @@
+/*
+ * "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.
+ *
+ * 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., 59 Temple
+ * Place, Suite 330, Boston, MA, 02111-1307, USA
+ *
+ * Este programa está nomeado como text.cc e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ *
+ */
+
+ #include "rx3270.h"
+ #include
+
+ #include
+
+
+/*--[ Globals ]--------------------------------------------------------------------------------------*/
+
+#ifdef HAVE_ICONV
+ iconv_t outputConv = (iconv_t) (-1);
+ iconv_t inputConv = (iconv_t) (-1);
+#endif
+
+/*--[ Implement ]------------------------------------------------------------------------------------*/
+
+char * get_contents(H3270 *hSession, int start, int sz)
+{
+ unsigned char str[sz+1];
+ unsigned short attr[sz+1];
+
+ if(!lib3270_get_contents(hSession,start,start+sz,str,attr))
+ return NULL;
+
+#ifdef HAVE_ICONV
+ // Convert received string to rexx encoding
+ if(outputConv != (iconv_t)(-1))
+ {
+ size_t in = strlen((char *) str);
+ size_t out = (in << 1);
+ char *ptr;
+ char *buffer = (char *) malloc(out);
+ char *ret;
+
+ memset(ptr=buffer,0,out);
+
+ iconv(outputConv,NULL,NULL,NULL,NULL); // Reset state
+
+ if(iconv(outputConv,(char **) &str,&in,&ptr,&out) == ((size_t) -1))
+ ret = strdup((char *) str);
+ else
+ ret = strdup(buffer);
+
+ free(buffer);
+
+ return ret;
+ }
+
+#endif // HAVE_ICONV
+
+ return strdup((char *) str);
+}
+
diff --git a/src/plugins/rx3270/typed_routines.cc b/src/plugins/rx3270/typed_routines.cc
new file mode 100644
index 0000000..02838b7
--- /dev/null
+++ b/src/plugins/rx3270/typed_routines.cc
@@ -0,0 +1,244 @@
+/*
+ * "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.
+ *
+ * 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., 59 Temple
+ * Place, Suite 330, Boston, MA, 02111-1307, USA
+ *
+ * Este programa está nomeado como text.cc e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
+ *
+ */
+
+ #include "rx3270.h"
+ #include
+
+ #include
+
+/*--[ Implement ]------------------------------------------------------------------------------------*/
+
+RexxRoutine0(CSTRING, rx3270version)
+{
+ return lib3270_get_version();
+}
+
+RexxRoutine0(CSTRING, rx3270QueryCState)
+{
+ #define DECLARE_XLAT_STATE( x ) { x, #x }
+
+ static const struct _xlat_state
+ {
+ LIB3270_CSTATE state;
+ const char * ret;
+ } xlat_state[] =
+ {
+ { LIB3270_NOT_CONNECTED, "NOT_CONNECTED" },
+ { LIB3270_RESOLVING, "RESOLVING" },
+ { LIB3270_PENDING, "PENDING" },
+ { LIB3270_CONNECTED_INITIAL, "CONNECTED_INITIAL" },
+ { LIB3270_CONNECTED_ANSI, "CONNECTED_ANSI" },
+ { LIB3270_CONNECTED_3270, "CONNECTED_3270" },
+ { LIB3270_CONNECTED_INITIAL_E, "CONNECTED_INITIAL_E" },
+ { LIB3270_CONNECTED_NVT, "CONNECTED_NVT" },
+ { LIB3270_CONNECTED_SSCP, "CONNECTED_SSCP" },
+ { LIB3270_CONNECTED_TN3270E, "CONNECTED_TN3270E" },
+ };
+
+ size_t f;
+ LIB3270_CSTATE state;
+
+ state = lib3270_get_connection_state(RX3270SESSION);
+
+ for(f=0;f < (sizeof(xlat_state)/sizeof(struct _xlat_state)); f++)
+ {
+ if(state == xlat_state[f].state)
+ return xlat_state[f].ret;
+ }
+
+ return "UNEXPECTED";
+}
+
+RexxRoutine0(int, rx3270Disconnect)
+{
+ lib3270_disconnect(RX3270SESSION);
+ return 0;
+}
+
+RexxRoutine2(int, rx3270Connect, CSTRING, hostname, int, wait)
+{
+ return lib3270_connect(RX3270SESSION, hostname, wait);
+}
+
+RexxRoutine0(int, rx3270isConnected)
+{
+ return lib3270_is_connected(RX3270SESSION) ? 1 : 0;
+}
+
+RexxRoutine0(int, rx3270WaitForEvents)
+{
+ H3270 * hSession = RX3270SESSION;
+
+ if(!lib3270_is_connected(hSession))
+ return ENOTCONN;
+
+ lib3270_main_iterate(hSession,1);
+
+ return 0;
+}
+
+RexxRoutine1(int, rx3270Sleep, int, seconds)
+{
+ return lib3270_wait(RX3270SESSION,seconds);
+}
+
+RexxRoutine0(int, rx3270SendENTERKey)
+{
+ return lib3270_enter(RX3270SESSION);
+}
+
+RexxRoutine1(int, rx3270SendPFKey, int, key)
+{
+ return lib3270_pfkey(RX3270SESSION,key);
+}
+
+RexxRoutine1(int, rx3270SendPAKey, int, key)
+{
+ return lib3270_pakey(RX3270SESSION,key);
+}
+
+RexxRoutine1(int, rx3270WaitForTerminalReady, int, seconds)
+{
+ return lib3270_wait_for_ready(RX3270SESSION,seconds);
+}
+
+RexxRoutine4(int, rx3270WaitForStringAt, int, row, int, col, CSTRING, key, int, timeout)
+{
+ H3270 * hSession = RX3270SESSION;
+ time_t end = time(0) + timeout;
+ int sz = strlen(key);
+ int rows;
+ int cols;
+ int start;
+
+ lib3270_get_screen_size(hSession,&rows,&cols);
+
+ if(row < 0 || row > rows || col < 0 || col > cols)
+ return EINVAL;
+
+ start = ((row) * cols) + col;
+
+ while(time(0) < end)
+ {
+ if(!lib3270_is_connected(hSession))
+ {
+ return ENOTCONN;
+ }
+ else if(lib3270_is_ready(hSession))
+ {
+ char *buffer = get_contents(hSession, start, start+sz);
+ if(buffer)
+ {
+ int rc = strncasecmp((const char *) buffer,key,sz);
+ free(buffer);
+ if(rc == 0)
+ return 0;
+ }
+ }
+
+ lib3270_main_iterate(hSession,1);
+
+ }
+
+ return ETIMEDOUT;
+
+}
+
+RexxRoutine3(RexxStringObject, rx3270GetStringAt, int, row, int, col, int, sz)
+{
+ H3270 * hSession = RX3270SESSION;
+ int rows;
+ int cols;
+ char * text;
+
+ lib3270_get_screen_size(hSession,&rows,&cols);
+
+ text = get_contents(hSession, ((row) * cols) + col, sz);
+ if(text)
+ {
+ RexxStringObject ret = context->String((CSTRING) text);
+ free(text);
+ return ret;
+ }
+
+ return context->String("");
+}
+
+RexxRoutine0(int, rx3270IsTerminalReady)
+{
+ return lib3270_is_ready(RX3270SESSION);
+}
+
+RexxRoutine3(RexxStringObject, rx3270ReadScreen, OPTIONAL_int, row, OPTIONAL_int, col, OPTIONAL_int, sz)
+{
+ H3270 * hSession = RX3270SESSION;
+ int rows;
+ int cols;
+ char * text;
+ int start;
+
+ lib3270_get_screen_size(hSession,&rows,&cols);
+
+ start = (row * cols) + col;
+
+ if(sz == 0)
+ sz = (rows*cols) - start;
+
+ text = get_contents(hSession, start, sz);
+ if(text)
+ {
+ RexxStringObject ret = context->String((CSTRING) text);
+ free(text);
+ return ret;
+ }
+
+ return context->String("");
+}
+
+RexxRoutine3(int, rx3270queryStringAt, int, row, int, col, CSTRING, key)
+{
+ H3270 * hSession = RX3270SESSION;
+ int rows;
+ int cols;
+ char * text;
+ size_t sz = strlen(key);
+
+ lib3270_get_screen_size(hSession,&rows,&cols);
+
+ text = get_contents(hSession, (row * cols) + col, sz);
+ if(text)
+ {
+ int rc = strncasecmp(text,key,sz);
+ free(text);
+ return rc;
+ }
+
+ return 0;
+}
+
--
libgit2 0.21.2