diff --git a/src/plugins/dbus3270/gobject.c b/src/plugins/dbus3270/gobject.c index 9883034..7e4f49e 100644 --- a/src/plugins/dbus3270/gobject.c +++ b/src/plugins/dbus3270/gobject.c @@ -252,3 +252,65 @@ void pw3270_dbus_get_text_at(PW3270Dbus *object, int row, int col, int len, DBus } + void pw3270_dbus_is_connected(PW3270Dbus *object, DBusGMethodInvocation *context) + { + trace("%s object=%p context=%p",__FUNCTION__,object,context); + dbus_g_method_return(context,lib3270_is_connected(pw3270_dbus_get_session_handle(object))); + } + + void pw3270_dbus_is_ready(PW3270Dbus *object, DBusGMethodInvocation *context) + { + trace("%s object=%p context=%p",__FUNCTION__,object,context); + dbus_g_method_return(context,lib3270_is_ready(pw3270_dbus_get_session_handle(object))); + } + + void pw3270_dbus_wait_for_ready(PW3270Dbus *object, int timeout, DBusGMethodInvocation *context) + { + trace("%s object=%p context=%p",__FUNCTION__,object,context); + dbus_g_method_return(context,lib3270_wait_for_ready(pw3270_dbus_get_session_handle(object),timeout)); + } + + void pw3270_dbus_set_cursor_at(PW3270Dbus *object, int row, int col, DBusGMethodInvocation *context) + { + trace("%s object=%p context=%p",__FUNCTION__,object,context); + dbus_g_method_return(context,lib3270_set_cursor_position(pw3270_dbus_get_session_handle(object),row,col)); + } + + void pw3270_dbus_set_toggle(PW3270Dbus *object, int id, int value, DBusGMethodInvocation *context) + { + trace("%s object=%p context=%p",__FUNCTION__,object,context); + lib3270_set_toggle(pw3270_dbus_get_session_handle(object),id,value); + dbus_g_method_return(context,0); + } + +void pw3270_dbus_cmp_text_at(PW3270Dbus *object, int row, int col, const gchar *utftext, DBusGMethodInvocation *context) +{ + gchar * text; + H3270 * hSession = pw3270_dbus_get_session_handle(object); + + trace("%s object=%p context=%p",__FUNCTION__,object,context); + if(pw3270_dbus_check_valid_state(object,context)) + return; + + text = g_convert_with_fallback(utftext,-1,lib3270_get_charset(hSession),"UTF-8","?",NULL,NULL,NULL); + + dbus_g_method_return(context,lib3270_cmp_text_at(hSession,row,col,text)); + + g_free(text); +} + +void pw3270_dbus_pf_key(PW3270Dbus *object, int key, DBusGMethodInvocation *context) +{ + trace("%s object=%p context=%p",__FUNCTION__,object,context); + if(pw3270_dbus_check_valid_state(object,context)) + return; + dbus_g_method_return(context,lib3270_pfkey(pw3270_dbus_get_session_handle(object),key)); +} + +void pw3270_dbus_pa_key(PW3270Dbus *object, int key, DBusGMethodInvocation *context) +{ + trace("%s object=%p context=%p",__FUNCTION__,object,context); + if(pw3270_dbus_check_valid_state(object,context)) + return; + dbus_g_method_return(context,lib3270_pakey(pw3270_dbus_get_session_handle(object),key)); +} diff --git a/src/plugins/dbus3270/main.c b/src/plugins/dbus3270/main.c index 69e1778..f3e0f81 100644 --- a/src/plugins/dbus3270/main.c +++ b/src/plugins/dbus3270/main.c @@ -161,7 +161,10 @@ dbus_g_method_return(context,0); } -H3270 * pw3270_dbus_get_session_handle(PW3270Dbus *object) -{ + H3270 * pw3270_dbus_get_session_handle(PW3270Dbus *object) + { return lib3270_get_default_session_handle(); -} + } + + + diff --git a/src/plugins/dbus3270/pw3270dbus.xml b/src/plugins/dbus3270/pw3270dbus.xml index 27aaaf1..9d34a87 100644 --- a/src/plugins/dbus3270/pw3270dbus.xml +++ b/src/plugins/dbus3270/pw3270dbus.xml @@ -34,6 +34,16 @@ + + + + + + + + + + @@ -45,6 +55,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/plugins/dbus3270/service.h b/src/plugins/dbus3270/service.h index d90afa6..04d1115 100644 --- a/src/plugins/dbus3270/service.h +++ b/src/plugins/dbus3270/service.h @@ -73,10 +73,21 @@ H3270 * pw3270_dbus_get_session_handle(PW3270Dbus *object); GError * pw3270_dbus_get_error_from_errno(int code); + void pw3270_dbus_is_connected(PW3270Dbus *object, DBusGMethodInvocation *context); + void pw3270_dbus_is_ready(PW3270Dbus *object, DBusGMethodInvocation *context); + + void pw3270_dbus_set_cursor_at(PW3270Dbus *object, int row, int col, DBusGMethodInvocation *context); + void pw3270_dbus_set_toggle(PW3270Dbus *object, int id, int value, DBusGMethodInvocation *context); + + void pw3270_dbus_wait_for_ready(PW3270Dbus *object, int timeout, DBusGMethodInvocation *context); + // Actions void pw3270_dbus_enter(PW3270Dbus *object, DBusGMethodInvocation *context); + void pw3270_dbus_pf_key(PW3270Dbus *object, int key, DBusGMethodInvocation *context); + void pw3270_dbus_pa_key(PW3270Dbus *object, int key, DBusGMethodInvocation *context); void pw3270_dbus_set_text_at(PW3270Dbus *object, int row, int col, const gchar *text, DBusGMethodInvocation *context); void pw3270_dbus_get_text_at(PW3270Dbus *object, int row, int col, int len, DBusGMethodInvocation *context); + void pw3270_dbus_cmp_text_at(PW3270Dbus *object, int row, int col, const gchar *text, DBusGMethodInvocation *context); G_END_DECLS diff --git a/src/plugins/rx3270/local.cc b/src/plugins/rx3270/local.cc index e5d5aa7..25eef56 100644 --- a/src/plugins/rx3270/local.cc +++ b/src/plugins/rx3270/local.cc @@ -30,12 +30,9 @@ #include "rx3270.h" #include -#if defined WIN32 - #define REXX_DEFAULT_CHARSET "CP1252" -#else +#if !defined WIN32 #include #include - #define REXX_DEFAULT_CHARSET "UTF-8" #endif #ifdef HAVE_SYSLOG @@ -120,11 +117,20 @@ /*--[ Implement ]------------------------------------------------------------------------------------*/ -rx3270::rx3270() +rx3270::rx3270(const char *local, const char *remote) { #ifdef HAVE_ICONV - this->conv2Local = iconv_open(REXX_DEFAULT_CHARSET, "ISO-8859-1"); - this->conv2Host = iconv_open("ISO-8859-1",REXX_DEFAULT_CHARSET); + + if(strcmp(local,remote)) + { + // Local and remote charsets aren't the same, setup conversion + this->conv2Local = iconv_open(local, remote); + this->conv2Host = iconv_open(remote,local); + } + else + { + this->conv2Local = this->conv2Host = (iconv_t)(-1); + } #endif if(!defSession) diff --git a/src/plugins/rx3270/remote.cc b/src/plugins/rx3270/remote.cc index f3c6448..49b116d 100644 --- a/src/plugins/rx3270/remote.cc +++ b/src/plugins/rx3270/remote.cc @@ -40,6 +40,7 @@ #include #include + #include /*--[ Class definition ]-----------------------------------------------------------------------------*/ @@ -124,7 +125,11 @@ rx3270 * rx3270::create_remote(const char *name) } +#if defined(HAVE_DBUS) +remote::remote(const char *name) : rx3270(REXX_DEFAULT_CHARSET,"UTF-8") +#else remote::remote(const char *name) +#endif // HAVE_DBUS { #if defined(WIN32) static DWORD dwMode = PIPE_READMODE_MESSAGE; @@ -138,6 +143,8 @@ remote::remote(const char *name) { if(*ptr == ':') *ptr = '_'; + else + *ptr = tolower(*ptr); } snprintf(buffer,4095,"\\\\.\\pipe\\%s",str); @@ -172,7 +179,12 @@ remote::remote(const char *name) DBusError err; int rc; char * str = strdup(name); - char * ptr = strchr(str,':'); + char * ptr; + + for(ptr=str;*ptr;ptr++) + *ptr = tolower(*ptr); + + ptr = strchr(str,':'); if(ptr) { @@ -200,11 +212,28 @@ remote::remote(const char *name) strncpy(intf,prefix_dest,sz); strncat(intf,str,sz); - } else { - exit(-1); + size_t sz; + + // Build destination + sz = strlen(str)+strlen(prefix_dest)+2; + dest = (char *) malloc(sz+1); + strncpy(dest,prefix_dest,sz); + strncat(dest,str,sz); + + // Build path + sz = strlen(str)+strlen(prefix_path); + path = (char *) malloc(sz+1); + strncpy(path,prefix_path,sz); + strncat(path,str,sz); + + // Build intf + sz = strlen(str)+strlen(prefix_dest)+1; + intf = (char *) malloc(sz+1); + strncpy(intf,prefix_dest,sz); + strncat(intf,str,sz); } @@ -290,62 +319,73 @@ DBusMessage * remote::call(DBusMessage *msg) } -char * remote::query_string(const char *method) +char * get_string(DBusMessage * msg) { char *rc = NULL; - - if(conn) + if(msg) { - DBusMessage * msg = call(create_message(method)); - if(msg) - { - DBusMessageIter iter; + DBusMessageIter iter; - if(dbus_message_iter_init(msg, &iter)) + if(dbus_message_iter_init(msg, &iter)) + { + if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) { - if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) - { - const char * str; - dbus_message_iter_get_basic(&iter, &str); - rc = strdup(str); - } + const char * str; + dbus_message_iter_get_basic(&iter, &str); + trace("Response: [%s]",str); + rc = strdup(str); } - - dbus_message_unref(msg); +#ifdef DEBUG + else + { + trace("Arg type is %c, expecting %c",dbus_message_iter_get_arg_type(&iter),DBUS_TYPE_STRING); + } +#endif } - } + dbus_message_unref(msg); + } return rc; } -int remote::query_intval(const char *method) +char * remote::query_string(const char *method) +{ + if(conn) + return get_string(call(create_message(method))); + return NULL; +} + +int get_intval(DBusMessage * msg) { int rc = -1; - if(conn) + if(msg) { - DBusMessage * msg = call(create_message(method)); - if(msg) - { - DBusMessageIter iter; + DBusMessageIter iter; - if(dbus_message_iter_init(msg, &iter)) + if(dbus_message_iter_init(msg, &iter)) + { + if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) { - if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) - { - dbus_int32_t iSigned; - dbus_message_iter_get_basic(&iter, &iSigned); - rc = (int) iSigned; - } + dbus_int32_t iSigned; + dbus_message_iter_get_basic(&iter, &iSigned); + rc = (int) iSigned; } - - dbus_message_unref(msg); } + + dbus_message_unref(msg); } return rc; } +int remote::query_intval(const char *method) +{ + if(conn) + return get_intval(call(create_message(method))); + return -1; +} + #endif // HAVE_DBUS @@ -374,7 +414,7 @@ LIB3270_CSTATE remote::get_cstate(void) if(hPipe != INVALID_HANDLE_VALUE) { - + #warning Implementar } return (LIB3270_CSTATE) -1; @@ -449,6 +489,20 @@ int remote::connect(const char *uri, bool wait) #elif defined(HAVE_DBUS) + int rc; + DBusMessage * msg = create_message("connect"); + if(!msg) + return -1; + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &uri, DBUS_TYPE_INVALID); + + rc = get_intval(call(msg)); + + if(!rc && wait) + return wait_for_ready(120); + + return rc; + #endif return -1; @@ -469,6 +523,8 @@ bool remote::is_connected(void) #elif defined(HAVE_DBUS) + return query_intval("isConnected") != 0; + #endif return false; @@ -480,11 +536,13 @@ bool remote::is_ready(void) if(hPipe != INVALID_HANDLE_VALUE) { - + #warning Implementar } #elif defined(HAVE_DBUS) + return query_intval("isReady") != 0; + #endif return false; @@ -564,6 +622,29 @@ int remote::wait_for_ready(int seconds) #elif defined(HAVE_DBUS) + time_t end = time(0)+seconds; + + while(time(0) < end) + { + static const dbus_int32_t delay = 2; + + DBusMessage * msg = create_message("waitForReady"); + int rc; + + if(!msg) + return -1; + + dbus_message_append_args(msg, DBUS_TYPE_INT32, &delay, DBUS_TYPE_INVALID); + + rc = get_intval(call(msg)); + trace("waitForReady exits with rc=%d",rc); + if(rc != ETIMEDOUT) + return rc; + } + + + return ETIMEDOUT; + #endif return -1; @@ -598,6 +679,19 @@ char * remote::get_text_at(int row, int col, size_t sz) #elif defined(HAVE_DBUS) + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + dbus_int32_t l = (dbus_int32_t) sz; + + DBusMessage * msg = create_message("getTextAt"); + if(!msg) + return NULL; + + trace("%s(%d,%d,%d)",__FUNCTION__,r,c,l); + dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_INT32, &l, DBUS_TYPE_INVALID); + + return get_string(call(msg)); + #endif return NULL; @@ -629,6 +723,16 @@ int remote::cmp_text_at(int row, int col, const char *text) #elif defined(HAVE_DBUS) + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + + DBusMessage * msg = create_message("cmpTextAt"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + #endif return 0; @@ -659,6 +763,16 @@ int remote::set_text_at(int row, int col, const char *str) #elif defined(HAVE_DBUS) + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + + DBusMessage * msg = create_message("setTextAt"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + #endif return -1; @@ -670,11 +784,21 @@ int remote::set_cursor_position(int row, int col) if(hPipe != INVALID_HANDLE_VALUE) { - + #warning Implementar } #elif defined(HAVE_DBUS) + dbus_int32_t r = (dbus_int32_t) row; + dbus_int32_t c = (dbus_int32_t) col; + + DBusMessage * msg = create_message("setCursorAt"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &r, DBUS_TYPE_INT32, &c, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + #endif return -1; @@ -722,6 +846,15 @@ int remote::pfkey(int key) #elif defined(HAVE_DBUS) + dbus_int32_t k = (dbus_int32_t) key; + + DBusMessage * msg = create_message("pfKey"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + #endif return -1; @@ -742,6 +875,15 @@ int remote::pakey(int key) #elif defined(HAVE_DBUS) + dbus_int32_t k = (dbus_int32_t) key; + + DBusMessage * msg = create_message("paKey"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &k, DBUS_TYPE_INVALID); + return get_intval(call(msg)); + } + #endif return -1; @@ -758,6 +900,17 @@ void remote::set_toggle(LIB3270_TOGGLE ix, bool value) #elif defined(HAVE_DBUS) + dbus_int32_t i = (dbus_int32_t) ix; + dbus_int32_t v = (dbus_int32_t) value; + + DBusMessage * msg = create_message("setToggle"); + if(msg) + { + dbus_message_append_args(msg, DBUS_TYPE_INT32, &i, DBUS_TYPE_INT32, &v, DBUS_TYPE_INVALID); + get_intval(call(msg)); + } + + #endif } diff --git a/src/plugins/rx3270/rx3270.h b/src/plugins/rx3270/rx3270.h index 2ef9b4b..e1cbf55 100644 --- a/src/plugins/rx3270/rx3270.h +++ b/src/plugins/rx3270/rx3270.h @@ -56,6 +56,13 @@ #include #endif // HAVE_ICONV +#ifdef WIN32 + #define REXX_DEFAULT_CHARSET "CP1252" +#else + #define REXX_DEFAULT_CHARSET "UTF-8" +#endif // WIN32 + + /*---[ Rexx entry points ]-----------------------------------------------------------------------------------*/ REXX_TYPED_ROUTINE_PROTOTYPE(rx3270version); @@ -119,7 +126,8 @@ public: - rx3270(); + rx3270(const char *local = REXX_DEFAULT_CHARSET, const char *remote = "ISO-8859-1"); + virtual ~rx3270(); static rx3270 * create(const char *name = NULL); diff --git a/src/plugins/rx3270/sample/remote.rex b/src/plugins/rx3270/sample/remote.rex index 6bcdc99..5287365 100644 --- a/src/plugins/rx3270/sample/remote.rex +++ b/src/plugins/rx3270/sample/remote.rex @@ -4,7 +4,15 @@ use arg uri host = .rx3270~new("pw3270:a") say "PW3270 version is "||host~revision() -say "Connections state is "||rx3270QueryCState() +say "Connection state is "||host~connected() +say "Ready state is "||host~ready() + +if uri <> "URI" + then say "Connect rc="||host~connect(uri) + +say "Wait for ready is "||host~WaitForReady(60) + +say "Text[3,2,27]="||host~GetTextAt(3,2,27) return 0 -- libgit2 0.21.2