Commit 17909801f97bbe0cb2de0603a3218d0c5e278bc5

Authored by Perry Werneck
2 parents 3b6c25b0 518b2227
Exists in master and in 1 other branch develop

Merge branch 'develop' of https://github.com/PerryWerneck/libipc3270 into develop

client/src/core/session.cc
... ... @@ -93,10 +93,7 @@
93 93 sz = (size_t) (ptr-text);
94 94 if(sz) {
95 95  
96   - // Wait for unlock, insert text.
97   - if( (rc = waitForKeyboardUnlock()) != 0) {
98   - return rc;
99   - }
  96 + // Insert text.
100 97 push(text,sz);
101 98 }
102 99  
... ... @@ -107,7 +104,6 @@
107 104  
108 105 case 'E': // Enter
109 106 push(ENTER);
110   - rc = waitForKeyboardUnlock();
111 107 break;
112 108  
113 109 case 'F': // Erase EOF
... ... @@ -116,122 +112,98 @@
116 112  
117 113 case '1': // PF1
118 114 push(PF_1);
119   - rc = waitForKeyboardUnlock();
120 115 break;
121 116  
122 117 case '2': // PF2
123 118 push(PF_2);
124   - rc = waitForKeyboardUnlock();
125 119 break;
126 120  
127 121 case '3': // PF3
128 122 push(PF_3);
129   - rc = waitForKeyboardUnlock();
130 123 break;
131 124  
132 125 case '4': // PF4
133 126 push(PF_4);
134   - rc = waitForKeyboardUnlock();
135 127 break;
136 128  
137 129 case '5': // PF5
138 130 push(PF_5);
139   - rc = waitForKeyboardUnlock();
140 131 break;
141 132  
142 133 case '6': // PF6
143 134 push(PF_6);
144   - rc = waitForKeyboardUnlock();
145 135 break;
146 136  
147 137 case '7': // PF7
148 138 push(PF_7);
149   - rc = waitForKeyboardUnlock();
150 139 break;
151 140  
152 141 case '8': // PF8
153 142 push(PF_8);
154   - rc = waitForKeyboardUnlock();
155 143 break;
156 144  
157 145 case '9': // PF9
158 146 push(PF_9);
159   - rc = waitForKeyboardUnlock();
160 147 break;
161 148  
162 149 case 'a': // PF10
163 150 push(PF_10);
164   - rc = waitForKeyboardUnlock();
165 151 break;
166 152  
167 153 case 'b': // PF11
168 154 push(PF_11);
169   - rc = waitForKeyboardUnlock();
170 155 break;
171 156  
172 157 case 'c': // PF12
173 158 push(PF_12);
174   - rc = waitForKeyboardUnlock();
175 159 break;
176 160  
177 161 case 'd': // PF13
178 162 push(PF_13);
179   - rc = waitForKeyboardUnlock();
180 163 break;
181 164  
182 165 case 'e': // PF14
183 166 push(PF_14);
184   - rc = waitForKeyboardUnlock();
185 167 break;
186 168  
187 169 case 'f': // PF15
188 170 push(PF_15);
189   - rc = waitForKeyboardUnlock();
190 171 break;
191 172  
192 173 case 'g': // PF16
193 174 push(PF_16);
194   - rc = waitForKeyboardUnlock();
195 175 break;
196 176  
197 177 case 'h': // PF17
198 178 push(PF_17);
199   - rc = waitForKeyboardUnlock();
200 179 break;
201 180  
202 181 case 'i': // PF18
203 182 push(PF_18);
204   - rc = waitForKeyboardUnlock();
205 183 break;
206 184  
207 185 case 'j': // PF19
208 186 push(PF_19);
209   - rc = waitForKeyboardUnlock();
210 187 break;
211 188  
212 189 case 'k': // PF20
213 190 push(PF_20);
214   - rc = waitForKeyboardUnlock();
215 191 break;
216 192  
217 193 case 'l': // PF21
218 194 push(PF_21);
219   - rc = waitForKeyboardUnlock();
220 195 break;
221 196  
222 197 case 'm': // PF22
223 198 push(PF_22);
224   - rc = waitForKeyboardUnlock();
225 199 break;
226 200  
227 201 case 'n': // PF23
228 202 push(PF_23);
229   - rc = waitForKeyboardUnlock();
230 203 break;
231 204  
232 205 case 'o': // PF24
233 206 push(PF_24);
234   - rc = waitForKeyboardUnlock();
235 207 break;
236 208  
237 209 case '@': // Send '@' character
... ... @@ -240,17 +212,14 @@
240 212  
241 213 case 'x': // PA1
242 214 push(PA_1);
243   - rc = waitForKeyboardUnlock();
244 215 break;
245 216  
246 217 case 'y': // PA2
247 218 push(PA_2);
248   - rc = waitForKeyboardUnlock();
249 219 break;
250 220  
251 221 case 'z': // PA3
252 222 push(PA_3);
253   - rc = waitForKeyboardUnlock();
254 223 break;
255 224  
256 225 case 'B': // PC_LEFTTAB = "@B"
... ... @@ -369,9 +338,6 @@
369 338  
370 339 sz = strlen(text);
371 340 if(sz) {
372   - if( (rc = waitForKeyboardUnlock()) != 0) {
373   - return rc;
374   - }
375 341 push(text,sz);
376 342 }
377 343  
... ...
client/src/core/windows/request.cc
... ... @@ -152,7 +152,22 @@
152 152 // It´s an error, extract message
153 153 in.block[in.used] = 0;
154 154 debug("Error was ",rc," (\"",(const char *) (in.block + in.current),"\")");
155   - throw std::system_error(std::error_code(rc,std::system_category()),(const char *) (in.block + in.current));
  155 +
  156 + // Overload system error mostly because of the lack of ENOTCONN message on windows.
  157 + class Error : public std::system_error {
  158 + private:
  159 + std::string message;
  160 +
  161 + public:
  162 + Error(int rc, const char *msg) : std::system_error((int) rc, std::generic_category()), message(msg) {
  163 + }
  164 +
  165 + const char *what() const noexcept override {
  166 + return message.c_str();
  167 + }
  168 + };
  169 +
  170 + throw Error(rc, (const char *) (in.block + in.current));
156 171  
157 172 }
158 173  
... ...
client/src/host/properties.cc
... ... @@ -58,4 +58,10 @@ std::vector<TN3270::Attribute> TN3270::Host::getAttributes() const {
58 58  
59 59 }
60 60  
  61 +void TN3270::Host::setTimeout(time_t timeout) noexcept {
  62 + this->timeout = timeout;
  63 + this->session->setWaitMode(timeout != 0);
  64 +}
  65 +
  66 +
61 67  
... ...
client/src/include/lib3270/ipc.h
... ... @@ -569,6 +569,7 @@
569 569 virtual void setHostURL(const char *url) = 0;
570 570  
571 571 virtual void setUnlockDelay(unsigned short delay = 350) = 0;
  572 + virtual void setWaitMode(bool mode) = 0;
572 573 virtual void setLockOnOperatorError(bool lock = true) = 0;
573 574  
574 575 virtual unsigned short getScreenWidth() const = 0;
... ... @@ -835,9 +836,7 @@
835 836 }
836 837  
837 838 // Set properties
838   - inline void setTimeout(time_t timeout = DEFAULT_TIMEOUT) noexcept {
839   - this->timeout = timeout;
840   - }
  839 + void setTimeout(time_t timeout = DEFAULT_TIMEOUT) noexcept;
841 840  
842 841 inline void setUnlockDelay(unsigned short delay = 350) {
843 842 session->setUnlockDelay(delay);
... ...
client/src/session/local/attribute.cc
... ... @@ -484,6 +484,11 @@
484 484 chkResponse(lib3270_set_unlock_delay(hSession,delay));
485 485 }
486 486  
  487 + void Local::Session::setWaitMode(bool mode) {
  488 + std::lock_guard<std::mutex> lock(sync);
  489 + chkResponse(ENOTSUP);
  490 + }
  491 +
487 492 void Local::Session::setLockOnOperatorError(bool lock) {
488 493 std::lock_guard<std::mutex> guard(sync);
489 494 chkResponse(lib3270_set_lock_on_operator_error(hSession,lock ? 1 : 0));
... ...
client/src/session/local/private.h
... ... @@ -152,6 +152,7 @@
152 152 unsigned short getScreenHeight() const override;
153 153 unsigned short getScreenLength() const override;
154 154 void setUnlockDelay(unsigned short delay) override;
  155 + void setWaitMode(bool mode) override;
155 156 void setLockOnOperatorError(bool lock) override;
156 157 void setCharSet(const char *charset = NULL) override;
157 158 unsigned short setCursor(int addr) override;
... ...
client/src/session/remote/private.h
... ... @@ -160,6 +160,7 @@
160 160 unsigned short getScreenHeight() const override;
161 161 unsigned short getScreenLength() const override;
162 162 void setUnlockDelay(unsigned short delay) override;
  163 + void setWaitMode(bool mode) override;
163 164 void setLockOnOperatorError(bool lock) override;
164 165 void setCharSet(const char *charset = NULL) override;
165 166 unsigned short setCursor(int addr) override;
... ...
client/src/session/remote/properties.cc
... ... @@ -160,6 +160,19 @@
160 160  
161 161 }
162 162  
  163 + void IPC::Session::setWaitMode(bool mode) {
  164 +
  165 + int32_t rc;
  166 +
  167 + Request(*this,"setWaitMode")
  168 + .push(mode)
  169 + .call()
  170 + .pop(rc);
  171 +
  172 + chkResponse(rc);
  173 +
  174 + }
  175 +
163 176 unsigned short IPC::Session::setCursor(unsigned short row, unsigned short col) {
164 177  
165 178 int32_t rc;
... ...
client/src/testprogram/testprogram.cc
... ... @@ -38,13 +38,14 @@
38 38  
39 39 #include <ctime>
40 40  
41   -#ifndef _WIN32
42 41 #include <getopt.h>
43   - #pragma GCC diagnostic ignored "-Wunused-function"
44   -#endif // _WIN32
45 42  
46 43 #if defined(_MSC_VER)
47 44 #pragma comment(lib,"ipc3270.lib")
  45 +#else
  46 + #pragma GCC diagnostic ignored "-Wunused-function"
  47 + #pragma GCC diagnostic ignored "-Wunused-parameter"
  48 + #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
48 49 #endif // _MSC_VER
49 50  
50 51 #include <cstdlib>
... ... @@ -170,11 +171,12 @@
170 171  
171 172 TN3270::Host host{session};
172 173  
173   - // host.connect();
  174 + host.setTimeout(10);
  175 +
  176 + host.connect();
  177 + host.push(TN3270::ENTER);
174 178  
175   - cout << endl << "------------------------" << endl;
176 179 host.toString(14,1,75,0);
177   - cout << endl << "------------------------" << endl;
178 180  
179 181 // host.disconnect();
180 182  
... ... @@ -186,7 +188,6 @@
186 188 << std::endl;
187 189  
188 190 host.setUnlockDelay(0);
189   - host.setTimeout(10);
190 191 host.connect(nullptr);
191 192  
192 193 cout
... ... @@ -237,15 +238,12 @@
237 238  
238 239 const char * session = ":A";
239 240  
240   -#ifndef _WIN32
241   - #pragma GCC diagnostic push
242   - #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
243 241 static struct option options[] = {
244 242 { "session", required_argument, 0, 's' },
  243 + { "perftest", no_argument, 0, 'P' },
245 244 { 0, 0, 0, 0}
246 245  
247 246 };
248   - #pragma GCC diagnostic pop
249 247  
250 248 int long_index =0;
251 249 int opt;
... ... @@ -256,10 +254,13 @@
256 254 session = optarg;
257 255 break;
258 256  
  257 + case 'P':
  258 + testPerformance(session);
  259 + return 0;
  260 +
259 261 }
260 262  
261 263 }
262   -#endif // _WIN32
263 264  
264 265 cout << "Session: " << session << endl;
265 266  
... ...
server/src/core/linux/gobject.c
... ... @@ -120,6 +120,10 @@ void ipc3270_add_terminal_introspection(GString *introspection) {
120 120 " <arg type='s' name='name' direction='in' />" \
121 121 " <arg type='b' name='result' direction='out' />" \
122 122 " </method>"
  123 + " <method name='setwaitmode'>"
  124 + " <arg type='b' name='mode' direction='in' />" \
  125 + " <arg type='i' name='result' direction='out' />" \
  126 + " </method>"
123 127 " <method name='pfkey'>" \
124 128 " <arg type='i' name='keycode' direction='in'/>" \
125 129 " <arg type='i' name='result' direction='out' />" \
... ... @@ -313,3 +317,12 @@ gchar * ipc3270_convert_to_3270(GObject *object, const gchar *string, GError **e
313 317 gchar * ipc3270_convert_from_3270(GObject *object, const gchar *string, GError **error) {
314 318 return g_convert_with_fallback(string,-1,IPC3270(object)->charset,lib3270_get_display_charset(IPC3270(object)->hSession),"?",NULL,NULL,error);
315 319 }
  320 +
  321 +int ipc3270_set_wait(GObject *object, gboolean wait) {
  322 + IPC3270(object)->wait = wait;
  323 + return 0;
  324 +}
  325 +
  326 +gboolean ipc3270_get_wait(GObject *object) {
  327 + return IPC3270(object)->wait;
  328 +}
... ...
server/src/core/linux/gobject.h
... ... @@ -62,6 +62,7 @@
62 62 H3270 * hSession;
63 63 gchar * charset;
64 64 GtkWidget * terminal;
  65 + gboolean wait; ///< @brief If true enable automatic call of "wait for ready".
65 66 GQuark error_domain;
66 67 };
67 68  
... ...
server/src/core/methods/methods.c
... ... @@ -74,6 +74,7 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
74 74  
75 75 { "action", ipc3270_method_action },
76 76 { "activatable", ipc3270_method_activatable },
  77 + { "setwaitmode", ipc3270_method_set_wait_mode },
77 78  
78 79 };
79 80  
... ... @@ -88,18 +89,16 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
88 89  
89 90 if(!g_ascii_strcasecmp(methods[ix].name,method_name)) {
90 91  
91   -#ifdef _DEBUG_
92   - g_message("Calling %s",methods[ix].name);
93   -#endif // _DEBUG_
94   -
  92 + g_message("Running method %s",method_name);
95 93 int rc = methods[ix].call(object,request,response,error);
96 94  
97 95 debug("rc=%d error=%p",rc,*error);
98 96  
99 97 if(rc)
100 98 {
  99 + g_message("Method %s failed with rc=%d (%s)",method_name,rc,ipc3270_get_error_message(rc));
101 100 debug("%s exits with rc=%d (%s)",methods[ix].name,rc,ipc3270_get_error_message(rc));
102   - g_message("%s exits with rc=%d (%s)",methods[ix].name,rc,ipc3270_get_error_message(rc));
  101 + lib3270_write_log(hSession,"IPC","%s exits with rc=%d (%s)",methods[ix].name,rc,ipc3270_get_error_message(rc));
103 102 ipc3270_set_error(object,rc,error);
104 103 debug("Error Message was set to %s",(*error)->message);
105 104 }
... ...
server/src/core/methods/private.h
... ... @@ -60,6 +60,7 @@
60 60  
61 61 G_GNUC_INTERNAL int ipc3270_method_action(GObject *session, GVariant *request, GObject *response, GError **error);
62 62 G_GNUC_INTERNAL int ipc3270_method_activatable(GObject *session, GVariant *request, GObject *response, GError **error);
  63 + G_GNUC_INTERNAL int ipc3270_method_set_wait_mode(GObject *session, GVariant *request, GObject *response, GError **error);
63 64  
64 65 G_GNUC_INTERNAL int ipc3270_method_get_field_attribute(GObject *session, GVariant *request, GObject *response, GError **error);
65 66  
... ...
server/src/core/setproperties.c
... ... @@ -185,3 +185,19 @@ gboolean ipc3270_set_property(GObject *object, const gchar *property_name, GVari
185 185  
186 186 return FALSE;
187 187 }
  188 +
  189 +int ipc3270_method_set_wait_mode(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) {
  190 +
  191 + if(g_variant_n_children(request) != 1) {
  192 + g_message("set wait was called with %u arguments.",(unsigned int) g_variant_n_children(request));
  193 + ipc3270_response_append_int32(response, EINVAL);
  194 + }
  195 +
  196 + GVariant *value = g_variant_get_child_value(request,0);
  197 +
  198 + ipc3270_response_append_int32(response, ipc3270_set_wait(session,g_variant_get_boolean(value)));
  199 +
  200 + g_variant_unref(value);
  201 +
  202 + return 0;
  203 +}
... ...
server/src/core/windows/gobject.c
... ... @@ -124,4 +124,11 @@ gchar * ipc3270_convert_from_3270(GObject *object, const gchar *string, GError *
124 124 return g_convert_with_fallback(string,-1,IPC3270(object)->charset,lib3270_get_display_charset(IPC3270(object)->hSession),"?",NULL,NULL,error);
125 125 }
126 126  
  127 +int ipc3270_set_wait(GObject *object, gboolean wait) {
  128 + IPC3270(object)->wait = wait;
  129 + return 0;
  130 +}
127 131  
  132 +gboolean ipc3270_get_wait(GObject *object) {
  133 + return IPC3270(object)->wait;
  134 +}
... ...
server/src/core/windows/gobject.h
... ... @@ -82,6 +82,7 @@
82 82 H3270 * hSession;
83 83 GtkWidget * terminal;
84 84 gchar * charset;
  85 + gboolean wait; ///< @brief If true enable automatic call of "wait for ready".
85 86 IPC3270_PIPE_SOURCE * source;
86 87 GQuark error_domain;
87 88 };
... ...
server/src/include/ipc-glib.h
... ... @@ -131,6 +131,9 @@
131 131 void ipc3270_set_terminal_widget(GObject *object, GtkWidget *widget);
132 132 void ipc3270_export_object(GObject *object, const char *name, GError **error);
133 133  
  134 + int ipc3270_set_wait(GObject *object, gboolean wait);
  135 + gboolean ipc3270_get_wait(GObject *object);
  136 +
134 137 void ipc3270_add_terminal_introspection(GString *string);
135 138  
136 139 const gchar * ipc3270_get_display_charset(GObject *object);
... ...