diff --git a/hllapi.cbp b/hllapi.cbp index b0cc389..4d8ed48 100644 --- a/hllapi.cbp +++ b/hllapi.cbp @@ -41,6 +41,7 @@ + diff --git a/src/core/actions.cc b/src/core/actions.cc index fcb6628..2bd351f 100644 --- a/src/core/actions.cc +++ b/src/core/actions.cc @@ -45,6 +45,10 @@ return HLLAPI_STATUS_SUCCESS; + } catch(const std::system_error &e) { + + return hllapi_translate_error(e); + } catch(const std::exception &e) { hllapi_lasterror = e.what(); diff --git a/src/core/calls.cc b/src/core/calls.cc index 0498975..178f2f6 100644 --- a/src/core/calls.cc +++ b/src/core/calls.cc @@ -223,25 +223,6 @@ return HLLAPI_STATUS_SYSTEM_ERROR; } - HLLAPI_API_CALL hllapi_get_datadir(LPSTR datadir) { - - #ifdef _WIN32 - HKEY hKey = 0; - unsigned long datalen = strlen(datadir); - - *datadir = 0; - - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) - { - unsigned long datatype; // #defined in winnt.h (predefined types 0-11) - if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) datadir,&datalen) != ERROR_SUCCESS) - *datadir = 0; - RegCloseKey(hKey); - } -#endif // _WIN32 - - return *datadir; - } HLLAPI_API_CALL hllapi_wait(WORD seconds) { @@ -321,20 +302,3 @@ } - DWORD hllapi_translate_keyboard_state(LIB3270_KEYBOARD_LOCK_STATE state, HLLAPI_STATUS def) { - - // Is unlocked. - if(state == LIB3270_KL_UNLOCKED) - return def; - - // Is connected? - if((state & LIB3270_KL_NOT_CONNECTED) != 0) - return HLLAPI_STATUS_DISCONNECTED; - - if( (state & (LIB3270_KL_AWAITING_FIRST|LIB3270_KL_OIA_TWAIT)) != 0) - return HLLAPI_STATUS_WAITING; - - return HLLAPI_STATUS_KEYBOARD_LOCKED; - - } - diff --git a/src/core/get.cc b/src/core/get.cc index 0cf2efe..d521fb8 100644 --- a/src/core/get.cc +++ b/src/core/get.cc @@ -37,11 +37,13 @@ TN3270::Host &host = getSession(); - if(!host.isConnected()) - return HLLAPI_STATUS_DISCONNECTED; - + host.waitForReady(); worker(host); + } catch(const std::system_error &e) { + + return hllapi_translate_error(e); + } catch(std::exception &e) { hllapi_lasterror = e.what(); @@ -66,7 +68,7 @@ return get([row,col,buffer](TN3270::Host &host) { size_t length = strlen(buffer); - string contents = host.toString( (int) row, (int) col, length); + string contents = host.toString( (unsigned int) row, (unsigned int) col, (int) length); strncpy((char *) buffer, contents.c_str(), std::min(length,contents.size())); diff --git a/src/core/keyboard.cc b/src/core/keyboard.cc index f852b9b..6650f9f 100644 --- a/src/core/keyboard.cc +++ b/src/core/keyboard.cc @@ -64,6 +64,10 @@ static DWORD set(std::function worker) noexcept { HLLAPI_API_CALL hllapi_pfkey(WORD key) { +#ifdef DEBUG + clog << __FUNCTION__ << "(" << key << ")" << endl; +#endif // DEBUG + return set([key](TN3270::Host &host) { host.pfkey((unsigned short) key); diff --git a/src/core/private.h b/src/core/private.h index 279be8c..a3bddca 100644 --- a/src/core/private.h +++ b/src/core/private.h @@ -36,6 +36,8 @@ #include #include #include + #include + #include #include #include #include @@ -44,10 +46,14 @@ using std::string; using TN3270::Host; using std::exception; + using std::clog; + using std::endl; extern TN3270_PRIVATE std::string hllapi_lasterror; TN3270_PRIVATE TN3270::Host & getSession(); - TN3270_PRIVATE DWORD hllapi_translate_keyboard_state(LIB3270_KEYBOARD_LOCK_STATE state, HLLAPI_STATUS def = HLLAPI_STATUS_SYSTEM_ERROR); + + TN3270_PRIVATE DWORD hllapi_translate_error(LIB3270_KEYBOARD_LOCK_STATE state); + TN3270_PRIVATE DWORD hllapi_translate_error(const std::system_error &error); #endif // PRIVATE_H_INCLUDED diff --git a/src/core/set.cc b/src/core/set.cc index 81e95b3..23d1f69 100644 --- a/src/core/set.cc +++ b/src/core/set.cc @@ -45,6 +45,7 @@ TN3270::Host &host = getSession(); kLock = host.waitForKeyboardUnlock(); + if(kLock == LIB3270_KL_UNLOCKED) { try { @@ -63,6 +64,9 @@ } + } catch(const std::system_error &e) { + + return hllapi_translate_error(e); } catch(const std::exception &e) { @@ -78,7 +82,7 @@ } - return hllapi_translate_keyboard_state(kLock); + return hllapi_translate_error(kLock); } @@ -102,6 +106,9 @@ if(!(text && *text)) return HLLAPI_STATUS_BAD_PARAMETER; + if(!length) + length = strlen(text); + return set([text,length](TN3270::Host &host) { host.input((const char *) text, (int) length, '@'); diff --git a/src/core/tools.cc b/src/core/tools.cc new file mode 100644 index 0000000..c0bba05 --- /dev/null +++ b/src/core/tools.cc @@ -0,0 +1,107 @@ +/* + * "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 - 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 "private.h" + #include + +/*--[ Implement ]------------------------------------------------------------------------------------*/ + + HLLAPI_API_CALL hllapi_get_datadir(LPSTR datadir) { + + #ifdef _WIN32 + HKEY hKey = 0; + unsigned long datalen = strlen(datadir); + + *datadir = 0; + + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\pw3270",0,KEY_QUERY_VALUE,&hKey) == ERROR_SUCCESS) + { + unsigned long datatype; // #defined in winnt.h (predefined types 0-11) + if(RegQueryValueExA(hKey,"datadir",NULL,&datatype,(LPBYTE) datadir,&datalen) != ERROR_SUCCESS) + *datadir = 0; + RegCloseKey(hKey); + } +#endif // _WIN32 + + return *datadir; + } + + DWORD hllapi_translate_error(LIB3270_KEYBOARD_LOCK_STATE state) { + + // Is unlocked. + if(state == LIB3270_KL_UNLOCKED) + return HLLAPI_STATUS_SYSTEM_ERROR; + + // Is connected? + if((state & LIB3270_KL_NOT_CONNECTED) != 0) + return HLLAPI_STATUS_DISCONNECTED; + + if( (state & (LIB3270_KL_AWAITING_FIRST|LIB3270_KL_OIA_TWAIT)) != 0) + return HLLAPI_STATUS_WAITING; + + return HLLAPI_STATUS_KEYBOARD_LOCKED; + + } + + DWORD hllapi_translate_error(const std::system_error &error) { + + static const struct Translate { + int from; + HLLAPI_STATUS to; + } translate[] = { + { ENOTCONN, HLLAPI_STATUS_DISCONNECTED }, + { ECONNRESET, HLLAPI_STATUS_DISCONNECTED }, + { EHOSTDOWN, HLLAPI_STATUS_DISCONNECTED }, + { EINVAL, HLLAPI_STATUS_BAD_PARAMETER }, + { ETIMEDOUT, HLLAPI_STATUS_TIMEOUT }, + { EBUSY, HLLAPI_STATUS_TIMEOUT }, + { EPERM, HLLAPI_STATUS_KEYBOARD_LOCKED }, + { EROFS, HLLAPI_STATUS_KEYBOARD_LOCKED }, + { EOVERFLOW, HLLAPI_STATUS_BAD_POSITION }, + }; + + int value = error.code().value(); + + hllapi_lasterror = error.what(); + + hllapi_lasterror += " (rc="; + hllapi_lasterror += std::to_string(value); + hllapi_lasterror += ")"; + + for(size_t ix = 0; ix < (sizeof(translate)/sizeof(struct Translate)); ix++) { + + if(translate[ix].from == value) + return translate[ix].to; + + } + + return HLLAPI_STATUS_SYSTEM_ERROR; + + } + diff --git a/src/include/lib3270/hllapi.h b/src/include/lib3270/hllapi.h index 38bd618..b2709d6 100644 --- a/src/include/lib3270/hllapi.h +++ b/src/include/lib3270/hllapi.h @@ -199,7 +199,6 @@ HLLAPI_API_CALL hllapi_get_state(void); HLLAPI_API_CALL hllapi_get_screen_at(WORD row, WORD col, LPSTR buffer); HLLAPI_API_CALL hllapi_get_screen(WORD pos, LPSTR buffer, WORD len); - HLLAPI_API_CALL hllapi_enter(void); HLLAPI_API_CALL hllapi_set_text_at(WORD row, WORD col, LPSTR text); HLLAPI_API_CALL hllapi_cmp_text_at(WORD row, WORD col, LPSTR text); HLLAPI_API_CALL hllapi_find_text(LPSTR text); @@ -213,6 +212,7 @@ HLLAPI_API_CALL hllapi_set_session_parameter(LPSTR param, WORD len, WORD value); + HLLAPI_API_CALL hllapi_enter(void); HLLAPI_API_CALL hllapi_erase(void); HLLAPI_API_CALL hllapi_erase_eof(void); HLLAPI_API_CALL hllapi_erase_eol(void); diff --git a/src/testprogram/testprogram.cc b/src/testprogram/testprogram.cc index 51ab806..edb32d2 100644 --- a/src/testprogram/testprogram.cc +++ b/src/testprogram/testprogram.cc @@ -30,6 +30,7 @@ #include #include #include + #include #include #define SCREEN_LENGTH 2000 @@ -43,7 +44,7 @@ char buffer[SCREEN_LENGTH+1]; const char *host = ""; - const char *session = ""; // "pw3270:A"; + const char *session = "pw3270:a"; #pragma GCC diagnostic push static struct option options[] = @@ -92,11 +93,12 @@ memset(buffer,' ',SCREEN_LENGTH); buffer[SCREEN_LENGTH] = 0; + rc = HLLAPI_STATUS_SUCCESS; + if(strcasecmp(cmdline.c_str(),"connect") == 0) { cout << "Connecting..." << endl; rc = hllapi_connect((LPSTR) host,1); - cout << "hllapi_connect returns with rc=" << rc << " (" << hllapi_get_last_error() << ")" << endl; } else if(strcasecmp(cmdline.c_str(),"wait") == 0) { @@ -107,15 +109,12 @@ cout << "Disconnecting..." << endl; rc = hllapi_disconnect(); - cout << "hllapi_disconnect returns with rc=" << rc << " (" << hllapi_get_last_error() << ")" << endl; } else if(strcasecmp(cmdline.c_str(),"luname") == 0) { rc = hllapi_get_lu_name(buffer,SCREEN_LENGTH); if(rc == HLLAPI_STATUS_SUCCESS) { cout << "LU Name is " << buffer << endl; - } else { - cout << "hllapi_get_lu_name returns with rc=" << rc << " (" << hllapi_get_last_error() << ")" << endl; } } else if(strcasecmp(cmdline.c_str(),"contents") == 0) { @@ -124,11 +123,84 @@ cout << "hllapi_get_screen returns with rc=" << rc << " (" << hllapi_get_last_error() << ")" << endl << buffer << endl << endl; + } else if(strncasecmp(cmdline.c_str(),"cursor",6) == 0) { + + unsigned int row, col; + + switch(std::sscanf(cmdline.c_str()+6,"%u,%u",&row,&col)) { + case 1: + cout << "Moving cursor to " << row << endl; + rc = hllapi_set_cursor_address((WORD) row); + break; + + case 2: + cout << "Moving cursor to " << row << "," << col << endl; + rc = hllapi_set_cursor_position((WORD) row, (WORD) col); + break; + } + + } else if(strncasecmp(cmdline.c_str(),"at",2) == 0) { + + unsigned int row, col, len; + + switch(std::sscanf(cmdline.c_str()+3,"%u,%u,%u",&row,&col,&len)) { + case 3: + { + cout << "Getting " << len << " bytes from " << row << "," << col << endl; + + char * buffer = new char[len+1]; + memset(buffer,' ',len+1); + buffer[len] = 0; + + rc = hllapi_get_screen_at(row,col,buffer); + if(rc == HLLAPI_STATUS_SUCCESS) { + cout << "Contents:" << endl << buffer << endl; + } + + delete[] buffer; + } + break; + + case 2: + { + cout << "Getting " << col << " bytes from " << row << endl; + + char * buffer = new char[col+1]; + memset(buffer,' ',col+1); + buffer[col] = 0; + + rc = hllapi_get_screen(row,buffer,col); + if(rc == HLLAPI_STATUS_SUCCESS) { + cout << "Contents:" << endl << buffer << endl; + } + + delete[] buffer; + + } + break; + } + + } else if(strncasecmp(cmdline.c_str(),"enter",5) == 0) { + + rc = hllapi_enter(); + + } else if(strncasecmp(cmdline.c_str(),"pf ",3) == 0) { + + rc = hllapi_pfkey(atoi(cmdline.c_str()+3)); + + } else if(strncasecmp(cmdline.c_str(),"input ",6) == 0) { + + rc = hllapi_input_string((LPSTR) cmdline.c_str()+6,0); + } else { - cout << "Unknown command" << endl; + cout << "Unknown command \"" << cmdline << "\""<< endl; } + if(rc != HLLAPI_STATUS_SUCCESS) { + cout << "rc=" << rc << " (" << hllapi_get_last_error() << ")" << endl; + rc = HLLAPI_STATUS_SUCCESS; + } cout << endl << ">"; cout.flush(); -- libgit2 0.21.2