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 | 67 | class Host; |
68 | 68 | class Controller; |
69 | 69 | |
70 | + #define DEFAULT_TIMEOUT 5 | |
71 | + | |
70 | 72 | class TN3270_PUBLIC Event { |
71 | 73 | public: |
72 | 74 | enum Type : uint8_t { |
... | ... | @@ -200,7 +202,7 @@ |
200 | 202 | virtual void disconnect() = 0; |
201 | 203 | |
202 | 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 | 207 | // Gets |
206 | 208 | virtual std::string toString(int baddr = 0, size_t len = -1, char lf = '\n') const = 0; |
... | ... | @@ -255,6 +257,9 @@ |
255 | 257 | /// @brief Connection with the host |
256 | 258 | Session *session; |
257 | 259 | |
260 | + /// @brief How much seconds we wait for the terminal to be ready? | |
261 | + time_t timeout; | |
262 | + | |
258 | 263 | protected: |
259 | 264 | |
260 | 265 | /// @brief Writes characters to the associated file from the put area |
... | ... | @@ -273,19 +278,23 @@ |
273 | 278 | void error(const char *fmt, ...) const; |
274 | 279 | |
275 | 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 | 282 | ~Host(); |
278 | 283 | |
279 | 284 | inline bool operator==(ConnectionState state) const noexcept { |
280 | 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 | 290 | inline ProgramMessage getProgramMessage() const { |
286 | 291 | return session->getProgramMessage(); |
287 | 292 | } |
288 | 293 | |
294 | + inline bool isReady() const { | |
295 | + return getProgramMessage() == MESSAGE_NONE; | |
296 | + } | |
297 | + | |
289 | 298 | inline operator ProgramMessage() const { |
290 | 299 | return getProgramMessage(); |
291 | 300 | } |
... | ... | @@ -294,6 +303,10 @@ |
294 | 303 | return session->getConnectionState(); |
295 | 304 | } |
296 | 305 | |
306 | + inline bool isConnected() const { | |
307 | + return getConnectionState() == CONNECTED_TN3270E; | |
308 | + } | |
309 | + | |
297 | 310 | inline operator ConnectionState() const { |
298 | 311 | return getConnectionState(); |
299 | 312 | } |
... | ... | @@ -336,22 +349,13 @@ |
336 | 349 | |
337 | 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 | 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 | 360 | // Event listeners |
357 | 361 | inline Host & insert(Event::Type type, std::function <void(const Event &event)> listener) noexcept { | ... | ... |
src/include/lib3270.h
... | ... | @@ -555,6 +555,18 @@ |
555 | 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 | 570 | * Set string at current cursor position. |
559 | 571 | * |
560 | 572 | * Returns are ignored; newlines mean "move to beginning of next line"; |
... | ... | @@ -578,7 +590,7 @@ |
578 | 590 | * @param h Session handle. |
579 | 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 | 596 | LIB3270_EXPORT int lib3270_set_cursor_address(H3270 *h, int baddr); |
... | ... | @@ -590,7 +602,7 @@ |
590 | 602 | * @param row New cursor row. |
591 | 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 | 608 | LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col); | ... | ... |
src/lib3270++/host.cc
... | ... | @@ -43,7 +43,8 @@ |
43 | 43 | |
44 | 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 | 48 | this->session = Session::create(id); |
48 | 49 | if(url) { |
49 | 50 | this->connect(url); |
... | ... | @@ -55,15 +56,17 @@ |
55 | 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 | 60 | this->session->connect(url); |
60 | - sync(); | |
61 | + if(sync) { | |
62 | + this->sync(); | |
63 | + } | |
61 | 64 | } |
62 | 65 | |
63 | 66 | |
64 | 67 | /// @brief Writes characters to the associated file from the put area |
65 | 68 | int Host::sync() { |
66 | - this->session->waitForReady(); | |
69 | + this->session->waitForReady(this->timeout); | |
67 | 70 | return 0; |
68 | 71 | } |
69 | 72 | |
... | ... | @@ -89,6 +92,8 @@ |
89 | 92 | |
90 | 93 | std::string Host::toString() const { |
91 | 94 | |
95 | + this->session->waitForReady(this->timeout); | |
96 | + | |
92 | 97 | if(this->session->getConnectionState() == TN3270::DISCONNECTED) { |
93 | 98 | throw std::system_error(ENOTCONN, std::system_category()); |
94 | 99 | } |
... | ... | @@ -96,5 +101,70 @@ |
96 | 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 | 216 | } |
217 | 217 | |
218 | 218 | TN3270::Session & Local::Session::pop(int baddr, std::string &text) { |
219 | + | |
219 | 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 | 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 | 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 | 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 | 459 | int baddr = -1; |
400 | 460 | |
401 | 461 | CHECK_SESSION_HANDLE(h); |
... | ... | @@ -418,20 +478,37 @@ LIB3270_EXPORT int lib3270_set_cursor_position(H3270 *h, int row, int col) |
418 | 478 | } |
419 | 479 | |
420 | 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 | 499 | if(ret == baddr) |
429 | 500 | return ret; |
430 | 501 | |
431 | 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 | 514 | return ret; | ... | ... |