Commit c1fd4deeac0abfa03a8dd909584213634cce7016
1 parent
d9da6680
Exists in
master
and in
3 other branches
Working on the new API.
Showing
6 changed files
with
210 additions
and
35 deletions
Show diff stats
src/include/lib3270++.h
@@ -67,6 +67,8 @@ | @@ -67,6 +67,8 @@ | ||
67 | class Host; | 67 | class Host; |
68 | class Controller; | 68 | class Controller; |
69 | 69 | ||
70 | + #define DEFAULT_TIMEOUT 5 | ||
71 | + | ||
70 | class TN3270_PUBLIC Event { | 72 | class TN3270_PUBLIC Event { |
71 | public: | 73 | public: |
72 | enum Type : uint8_t { | 74 | enum Type : uint8_t { |
@@ -200,7 +202,7 @@ | @@ -200,7 +202,7 @@ | ||
200 | virtual void disconnect() = 0; | 202 | virtual void disconnect() = 0; |
201 | 203 | ||
202 | // Wait for session state. | 204 | // Wait for session state. |
203 | - virtual void waitForReady(time_t timeout = 5) throw() = 0; | 205 | + virtual void waitForReady(time_t timeout = DEFAULT_TIMEOUT) throw() = 0; |
204 | 206 | ||
205 | // Gets | 207 | // Gets |
206 | virtual std::string toString(int baddr = 0, size_t len = -1, char lf = '\n') const = 0; | 208 | virtual std::string toString(int baddr = 0, size_t len = -1, char lf = '\n') const = 0; |
@@ -255,6 +257,9 @@ | @@ -255,6 +257,9 @@ | ||
255 | /// @brief Connection with the host | 257 | /// @brief Connection with the host |
256 | Session *session; | 258 | Session *session; |
257 | 259 | ||
260 | + /// @brief How much seconds we wait for the terminal to be ready? | ||
261 | + time_t timeout; | ||
262 | + | ||
258 | protected: | 263 | protected: |
259 | 264 | ||
260 | /// @brief Writes characters to the associated file from the put area | 265 | /// @brief Writes characters to the associated file from the put area |
@@ -273,19 +278,23 @@ | @@ -273,19 +278,23 @@ | ||
273 | void error(const char *fmt, ...) const; | 278 | void error(const char *fmt, ...) const; |
274 | 279 | ||
275 | public: | 280 | public: |
276 | - Host(const char *id = nullptr, const char *url = nullptr); | 281 | + Host(const char *id = nullptr, const char *url = nullptr, time_t timeout = DEFAULT_TIMEOUT); |
277 | ~Host(); | 282 | ~Host(); |
278 | 283 | ||
279 | inline bool operator==(ConnectionState state) const noexcept { | 284 | inline bool operator==(ConnectionState state) const noexcept { |
280 | return session->getConnectionState() == state; | 285 | return session->getConnectionState() == state; |
281 | } | 286 | } |
282 | 287 | ||
283 | - void connect(const char *url); | 288 | + void connect(const char *url, bool sync = true); |
284 | 289 | ||
285 | inline ProgramMessage getProgramMessage() const { | 290 | inline ProgramMessage getProgramMessage() const { |
286 | return session->getProgramMessage(); | 291 | return session->getProgramMessage(); |
287 | } | 292 | } |
288 | 293 | ||
294 | + inline bool isReady() const { | ||
295 | + return getProgramMessage() == MESSAGE_NONE; | ||
296 | + } | ||
297 | + | ||
289 | inline operator ProgramMessage() const { | 298 | inline operator ProgramMessage() const { |
290 | return getProgramMessage(); | 299 | return getProgramMessage(); |
291 | } | 300 | } |
@@ -294,6 +303,10 @@ | @@ -294,6 +303,10 @@ | ||
294 | return session->getConnectionState(); | 303 | return session->getConnectionState(); |
295 | } | 304 | } |
296 | 305 | ||
306 | + inline bool isConnected() const { | ||
307 | + return getConnectionState() == CONNECTED_TN3270E; | ||
308 | + } | ||
309 | + | ||
297 | inline operator ConnectionState() const { | 310 | inline operator ConnectionState() const { |
298 | return getConnectionState(); | 311 | return getConnectionState(); |
299 | } | 312 | } |
@@ -336,22 +349,13 @@ | @@ -336,22 +349,13 @@ | ||
336 | 349 | ||
337 | // Get contents. | 350 | // Get contents. |
338 | 351 | ||
339 | - inline Host & pop(int baddr, std::string &text) { | ||
340 | - session->pop(baddr, text); | ||
341 | - return *this; | ||
342 | - } | ||
343 | - | ||
344 | - inline Host & pop(int row, int col, std::string &text) { | ||
345 | - session->pop(row,col,text); | ||
346 | - return *this; | ||
347 | - } | ||
348 | - | ||
349 | - inline Host & pop(std::string &text) { | ||
350 | - session->pop(text); | ||
351 | - return *this; | ||
352 | - } | 352 | + Host & pop(int baddr, std::string &text); |
353 | + Host & pop(int row, int col, std::string &text); | ||
354 | + Host & pop(std::string &text); | ||
353 | 355 | ||
354 | std::string toString() const; | 356 | std::string toString() const; |
357 | + std::string toString(int baddr, size_t len = -1, char lf = '\n') const; | ||
358 | + std::string toString(int row, int col, size_t sz, char lf = '\n') const; | ||
355 | 359 | ||
356 | // Event listeners | 360 | // Event listeners |
357 | inline Host & insert(Event::Type type, std::function <void(const Event &event)> listener) noexcept { | 361 | inline Host & insert(Event::Type type, std::function <void(const Event &event)> listener) noexcept { |
src/include/lib3270.h
@@ -555,6 +555,18 @@ | @@ -555,6 +555,18 @@ | ||
555 | LIB3270_EXPORT int lib3270_emulate_input(H3270 *session, const char *s, int len, int pasting); | 555 | LIB3270_EXPORT int lib3270_emulate_input(H3270 *session, const char *s, int len, int pasting); |
556 | 556 | ||
557 | /** | 557 | /** |
558 | + * @brief Converts row/col in a buffer address. | ||
559 | + * | ||
560 | + * @param hSession TN3270 Session. | ||
561 | + * @param row Row inside the screen. | ||
562 | + * @param col Col inside the screen. | ||
563 | + * | ||
564 | + * @return Current address or -1 if invalid (sets errno). | ||
565 | + * | ||
566 | + */ | ||
567 | + LIB3270_EXPORT int lib3270_translate_to_address(H3270 *hSession, int row, int col); | ||
568 | + | ||
569 | + /** | ||
558 | * Set string at current cursor position. | 570 | * Set string at current cursor position. |
559 | * | 571 | * |
560 | * Returns are ignored; newlines mean "move to beginning of next line"; | 572 | * Returns are ignored; newlines mean "move to beginning of next line"; |
@@ -578,7 +590,7 @@ | @@ -578,7 +590,7 @@ | ||
578 | * @param h Session handle. | 590 | * @param h Session handle. |
579 | * @param baddr New cursor address. | 591 | * @param baddr New cursor address. |
580 | * | 592 | * |
581 | - * @return last cursor address. | 593 | + * @return or -1 if invalid (sets errno). |
582 | * | 594 | * |
583 | */ | 595 | */ |
584 | LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *h, int baddr); | 596 | LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *h, int baddr); |
@@ -590,7 +602,7 @@ | @@ -590,7 +602,7 @@ | ||
590 | * @param row New cursor row. | 602 | * @param row New cursor row. |
591 | * @param col New cursor col. | 603 | * @param col New cursor col. |
592 | * | 604 | * |
593 | - * @return last cursor address. | 605 | + * @return last cursor address or -1 if invalid (sets errno).. |
594 | * | 606 | * |
595 | */ | 607 | */ |
596 | LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col); | 608 | LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col); |
src/lib3270++/host.cc
@@ -43,7 +43,8 @@ | @@ -43,7 +43,8 @@ | ||
43 | 43 | ||
44 | namespace TN3270 { | 44 | namespace TN3270 { |
45 | 45 | ||
46 | - Host::Host(const char *id, const char *url) { | 46 | + Host::Host(const char *id, const char *url, time_t timeout) { |
47 | + this->timeout = timeout; | ||
47 | this->session = Session::create(id); | 48 | this->session = Session::create(id); |
48 | if(url) { | 49 | if(url) { |
49 | this->connect(url); | 50 | this->connect(url); |
@@ -55,15 +56,17 @@ | @@ -55,15 +56,17 @@ | ||
55 | this->session = nullptr; | 56 | this->session = nullptr; |
56 | } | 57 | } |
57 | 58 | ||
58 | - void Host::connect(const char *url) { | 59 | + void Host::connect(const char *url, bool sync) { |
59 | this->session->connect(url); | 60 | this->session->connect(url); |
60 | - sync(); | 61 | + if(sync) { |
62 | + this->sync(); | ||
63 | + } | ||
61 | } | 64 | } |
62 | 65 | ||
63 | 66 | ||
64 | /// @brief Writes characters to the associated file from the put area | 67 | /// @brief Writes characters to the associated file from the put area |
65 | int Host::sync() { | 68 | int Host::sync() { |
66 | - this->session->waitForReady(); | 69 | + this->session->waitForReady(this->timeout); |
67 | return 0; | 70 | return 0; |
68 | } | 71 | } |
69 | 72 | ||
@@ -89,6 +92,8 @@ | @@ -89,6 +92,8 @@ | ||
89 | 92 | ||
90 | std::string Host::toString() const { | 93 | std::string Host::toString() const { |
91 | 94 | ||
95 | + this->session->waitForReady(this->timeout); | ||
96 | + | ||
92 | if(this->session->getConnectionState() == TN3270::DISCONNECTED) { | 97 | if(this->session->getConnectionState() == TN3270::DISCONNECTED) { |
93 | throw std::system_error(ENOTCONN, std::system_category()); | 98 | throw std::system_error(ENOTCONN, std::system_category()); |
94 | } | 99 | } |
@@ -96,5 +101,70 @@ | @@ -96,5 +101,70 @@ | ||
96 | return this->session->toString(); | 101 | return this->session->toString(); |
97 | } | 102 | } |
98 | 103 | ||
104 | + std::string Host::toString(int baddr, size_t len, char lf) const { | ||
105 | + | ||
106 | + this->session->waitForReady(this->timeout); | ||
107 | + | ||
108 | + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { | ||
109 | + throw std::system_error(ENOTCONN, std::system_category()); | ||
110 | + } | ||
111 | + | ||
112 | + return this->session->toString(baddr,len,lf); | ||
113 | + | ||
114 | + } | ||
115 | + | ||
116 | + std::string Host::toString(int row, int col, size_t sz, char lf) const { | ||
117 | + | ||
118 | + this->session->waitForReady(this->timeout); | ||
119 | + | ||
120 | + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { | ||
121 | + throw std::system_error(ENOTCONN, std::system_category()); | ||
122 | + } | ||
123 | + | ||
124 | + return this->session->toString(row,col,sz,lf); | ||
125 | + | ||
126 | + | ||
127 | + } | ||
128 | + | ||
129 | + Host & Host::pop(int baddr, std::string &text) { | ||
130 | + | ||
131 | + this->session->waitForReady(this->timeout); | ||
132 | + | ||
133 | + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { | ||
134 | + throw std::system_error(ENOTCONN, std::system_category()); | ||
135 | + } | ||
136 | + | ||
137 | + session->pop(baddr, text); | ||
138 | + | ||
139 | + return *this; | ||
140 | + } | ||
141 | + | ||
142 | + Host & Host::pop(int row, int col, std::string &text) { | ||
143 | + | ||
144 | + this->session->waitForReady(this->timeout); | ||
145 | + | ||
146 | + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { | ||
147 | + throw std::system_error(ENOTCONN, std::system_category()); | ||
148 | + } | ||
149 | + | ||
150 | + session->pop(row,col,text); | ||
151 | + | ||
152 | + return *this; | ||
153 | + } | ||
154 | + | ||
155 | + Host & Host::pop(std::string &text) { | ||
156 | + | ||
157 | + this->session->waitForReady(this->timeout); | ||
158 | + | ||
159 | + if(this->session->getConnectionState() == TN3270::DISCONNECTED) { | ||
160 | + throw std::system_error(ENOTCONN, std::system_category()); | ||
161 | + } | ||
162 | + | ||
163 | + session->pop(text); | ||
164 | + | ||
165 | + return *this; | ||
166 | + } | ||
167 | + | ||
168 | + | ||
99 | } | 169 | } |
100 | 170 |
src/lib3270++/local/session.cc
@@ -216,7 +216,19 @@ | @@ -216,7 +216,19 @@ | ||
216 | } | 216 | } |
217 | 217 | ||
218 | TN3270::Session & Local::Session::pop(int baddr, std::string &text) { | 218 | TN3270::Session & Local::Session::pop(int baddr, std::string &text) { |
219 | + | ||
219 | std::lock_guard<std::mutex> lock(sync); | 220 | std::lock_guard<std::mutex> lock(sync); |
221 | + | ||
222 | + char *contents = lib3270_get_field_at(hSession, baddr); | ||
223 | + | ||
224 | + if(!contents) { | ||
225 | + throw std::runtime_error("Can't get field contents"); | ||
226 | + } | ||
227 | + | ||
228 | + text.assign(convertFromHost(contents).c_str()); | ||
229 | + | ||
230 | + lib3270_free(contents); | ||
231 | + | ||
220 | return *this; | 232 | return *this; |
221 | } | 233 | } |
222 | 234 |
src/lib3270++/testprogram/testprogram.cc
src/lib3270/screen.c
@@ -382,20 +382,80 @@ LIB3270_EXPORT int lib3270_get_cursor_address(H3270 *h) | @@ -382,20 +382,80 @@ LIB3270_EXPORT int lib3270_get_cursor_address(H3270 *h) | ||
382 | return h->cursor_addr; | 382 | return h->cursor_addr; |
383 | } | 383 | } |
384 | 384 | ||
385 | -LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *h, int baddr) | 385 | +/** |
386 | + * @brief Converts row/col in a buffer address. | ||
387 | + * | ||
388 | + * @param hSession TN3270 Session. | ||
389 | + * @param row Row inside the screen. | ||
390 | + * @param col Col inside the screen. | ||
391 | + * | ||
392 | + * @return Current address or -1 if invalid (sets errno). | ||
393 | + * | ||
394 | + */ | ||
395 | +LIB3270_EXPORT int lib3270_translate_to_address(H3270 *hSession, int row, int col) | ||
386 | { | 396 | { |
387 | - CHECK_SESSION_HANDLE(h); | 397 | + CHECK_SESSION_HANDLE(hSession); |
398 | + | ||
399 | + row--; | ||
400 | + col--; | ||
401 | + | ||
402 | + if(row < 0 || col < 0 || row > hSession->rows || col > hSession->cols) | ||
403 | + { | ||
404 | + // Invalid coordinates | ||
405 | + errno = EINVAL; | ||
406 | + return -1; | ||
407 | + } | ||
408 | + | ||
409 | + return (row * hSession->cols) + col; | ||
410 | +} | ||
411 | + | ||
412 | + | ||
413 | +/** | ||
414 | + * @brief Move cursor to a new position. | ||
415 | + * | ||
416 | + * @see lib3270_set_cursor_position | ||
417 | + * | ||
418 | + * @param hSession TN3270 session. | ||
419 | + * @param baddr New cursor position. | ||
420 | + * | ||
421 | + * @return Old cursor address or -1 in case of error (sets errno). | ||
422 | + * | ||
423 | + */ | ||
424 | +LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *hSession, int baddr) | ||
425 | +{ | ||
426 | + CHECK_SESSION_HANDLE(hSession); | ||
388 | 427 | ||
389 | trace("%s(%d)",__FUNCTION__,baddr); | 428 | trace("%s(%d)",__FUNCTION__,baddr); |
390 | 429 | ||
391 | - if(h->selected && !lib3270_get_toggle(h,LIB3270_TOGGLE_KEEP_SELECTED)) | ||
392 | - lib3270_unselect(h); | 430 | + if(baddr < 0 || baddr > (hSession->rows * hSession->cols)) |
431 | + { | ||
432 | + errno = EINVAL; | ||
433 | + return -1; | ||
434 | + } | ||
435 | + | ||
436 | + if(hSession->selected && !lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_SELECTED)) | ||
437 | + lib3270_unselect(hSession); | ||
393 | 438 | ||
394 | - return cursor_move(h,baddr); | 439 | + return cursor_move(hSession,baddr); |
395 | } | 440 | } |
396 | 441 | ||
397 | -LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col) | 442 | +/** |
443 | + * @brief Move cursor to a new position. | ||
444 | + * | ||
445 | + * @see lib3270_set_cursor_position | ||
446 | + * | ||
447 | + * @param hSession TN3270 session. | ||
448 | + * @param row New cursor row. | ||
449 | + * @parma col New cursor column. | ||
450 | + * | ||
451 | + * @return Old cursor address or -1 in case of error (sets errno). | ||
452 | + * | ||
453 | + */ | ||
454 | +LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *hSession, int row, int col) | ||
398 | { | 455 | { |
456 | + return lib3270_set_cursor_address(hSession,lib3270_translate_to_address(hSession, row, col)); | ||
457 | + | ||
458 | + /* | ||
399 | int baddr = -1; | 459 | int baddr = -1; |
400 | 460 | ||
401 | CHECK_SESSION_HANDLE(h); | 461 | CHECK_SESSION_HANDLE(h); |
@@ -418,20 +478,37 @@ LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col) | @@ -418,20 +478,37 @@ LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col) | ||
418 | } | 478 | } |
419 | 479 | ||
420 | return baddr; | 480 | return baddr; |
481 | + */ | ||
421 | } | 482 | } |
422 | 483 | ||
423 | - | ||
424 | -int cursor_move(H3270 *h, int baddr) | 484 | +/** |
485 | + * @brief Move cursor to a new position. | ||
486 | + * | ||
487 | + * @see lib3270_set_cursor_address | ||
488 | + * | ||
489 | + * @param hSession TN3270 session. | ||
490 | + * @param baddr New cursor position. | ||
491 | + * | ||
492 | + * @return Old cursor position. | ||
493 | + * | ||
494 | + */ | ||
495 | +int cursor_move(H3270 *hSession, int baddr) | ||
425 | { | 496 | { |
426 | - int ret = h->cursor_addr; | 497 | + int ret = hSession->cursor_addr; |
427 | 498 | ||
428 | if(ret == baddr) | 499 | if(ret == baddr) |
429 | return ret; | 500 | return ret; |
430 | 501 | ||
431 | if(baddr >= 0) | 502 | if(baddr >= 0) |
432 | { | 503 | { |
433 | - h->cursor_addr = baddr; | ||
434 | - h->cbk.update_cursor(h,(unsigned short) (baddr/h->cols),(unsigned short) (baddr%h->cols),h->text[baddr].chr,h->text[baddr].attr); | 504 | + hSession->cursor_addr = baddr; |
505 | + hSession->cbk.update_cursor( | ||
506 | + hSession, | ||
507 | + (unsigned short) (baddr/hSession->cols), | ||
508 | + (unsigned short) (baddr%hSession->cols), | ||
509 | + hSession->text[baddr].chr, | ||
510 | + hSession->text[baddr].attr | ||
511 | + ); | ||
435 | } | 512 | } |
436 | 513 | ||
437 | return ret; | 514 | return ret; |