Commit c54366961bdddaae67f46b7ce3bba9c143e3f751
1 parent
9b21070e
Exists in
master
and in
1 other branch
Adding method to wait for keyboard unlock.
Showing
11 changed files
with
81 additions
and
42 deletions
Show diff stats
client/src/core/session.cc
| @@ -73,11 +73,16 @@ | @@ -73,11 +73,16 @@ | ||
| 73 | 73 | ||
| 74 | void Session::input(const char *text, const char control_char) { | 74 | void Session::input(const char *text, const char control_char) { |
| 75 | 75 | ||
| 76 | - waitForReady(); | 76 | + size_t sz; |
| 77 | 77 | ||
| 78 | for(const char * ptr = strchr(text,control_char); ptr; ptr = strchr(text,control_char)) { | 78 | for(const char * ptr = strchr(text,control_char); ptr; ptr = strchr(text,control_char)) { |
| 79 | 79 | ||
| 80 | - push(text,(size_t) (ptr-text)); | 80 | + // Wait for unlock, ignore errors. |
| 81 | + sz = (size_t) (ptr-text); | ||
| 82 | + if(sz) { | ||
| 83 | + waitForUnlock(); | ||
| 84 | + push(text,sz); | ||
| 85 | + } | ||
| 81 | 86 | ||
| 82 | switch(*(++ptr)) { | 87 | switch(*(++ptr)) { |
| 83 | case 'P': // Print | 88 | case 'P': // Print |
| @@ -86,7 +91,7 @@ | @@ -86,7 +91,7 @@ | ||
| 86 | 91 | ||
| 87 | case 'E': // Enter | 92 | case 'E': // Enter |
| 88 | push(ENTER); | 93 | push(ENTER); |
| 89 | - waitForReady(); | 94 | + waitForUnlock(); |
| 90 | break; | 95 | break; |
| 91 | 96 | ||
| 92 | case 'F': // Erase EOF | 97 | case 'F': // Erase EOF |
| @@ -95,122 +100,98 @@ | @@ -95,122 +100,98 @@ | ||
| 95 | 100 | ||
| 96 | case '1': // PF1 | 101 | case '1': // PF1 |
| 97 | push(PF_1); | 102 | push(PF_1); |
| 98 | - waitForReady(); | ||
| 99 | break; | 103 | break; |
| 100 | 104 | ||
| 101 | case '2': // PF2 | 105 | case '2': // PF2 |
| 102 | push(PF_2); | 106 | push(PF_2); |
| 103 | - waitForReady(); | ||
| 104 | break; | 107 | break; |
| 105 | 108 | ||
| 106 | case '3': // PF3 | 109 | case '3': // PF3 |
| 107 | push(PF_3); | 110 | push(PF_3); |
| 108 | - waitForReady(); | ||
| 109 | break; | 111 | break; |
| 110 | 112 | ||
| 111 | case '4': // PF4 | 113 | case '4': // PF4 |
| 112 | push(PF_4); | 114 | push(PF_4); |
| 113 | - waitForReady(); | ||
| 114 | break; | 115 | break; |
| 115 | 116 | ||
| 116 | case '5': // PF5 | 117 | case '5': // PF5 |
| 117 | push(PF_5); | 118 | push(PF_5); |
| 118 | - waitForReady(); | ||
| 119 | break; | 119 | break; |
| 120 | 120 | ||
| 121 | case '6': // PF6 | 121 | case '6': // PF6 |
| 122 | push(PF_6); | 122 | push(PF_6); |
| 123 | - waitForReady(); | ||
| 124 | break; | 123 | break; |
| 125 | 124 | ||
| 126 | case '7': // PF7 | 125 | case '7': // PF7 |
| 127 | push(PF_7); | 126 | push(PF_7); |
| 128 | - waitForReady(); | ||
| 129 | break; | 127 | break; |
| 130 | 128 | ||
| 131 | case '8': // PF8 | 129 | case '8': // PF8 |
| 132 | push(PF_8); | 130 | push(PF_8); |
| 133 | - waitForReady(); | ||
| 134 | break; | 131 | break; |
| 135 | 132 | ||
| 136 | case '9': // PF9 | 133 | case '9': // PF9 |
| 137 | push(PF_9); | 134 | push(PF_9); |
| 138 | - waitForReady(); | ||
| 139 | break; | 135 | break; |
| 140 | 136 | ||
| 141 | case 'a': // PF10 | 137 | case 'a': // PF10 |
| 142 | push(PF_10); | 138 | push(PF_10); |
| 143 | - waitForReady(); | ||
| 144 | break; | 139 | break; |
| 145 | 140 | ||
| 146 | case 'b': // PF11 | 141 | case 'b': // PF11 |
| 147 | push(PF_11); | 142 | push(PF_11); |
| 148 | - waitForReady(); | ||
| 149 | break; | 143 | break; |
| 150 | 144 | ||
| 151 | case 'c': // PF12 | 145 | case 'c': // PF12 |
| 152 | push(PF_12); | 146 | push(PF_12); |
| 153 | - waitForReady(); | ||
| 154 | break; | 147 | break; |
| 155 | 148 | ||
| 156 | case 'd': // PF13 | 149 | case 'd': // PF13 |
| 157 | push(PF_13); | 150 | push(PF_13); |
| 158 | - waitForReady(); | ||
| 159 | break; | 151 | break; |
| 160 | 152 | ||
| 161 | case 'e': // PF14 | 153 | case 'e': // PF14 |
| 162 | push(PF_14); | 154 | push(PF_14); |
| 163 | - waitForReady(); | ||
| 164 | break; | 155 | break; |
| 165 | 156 | ||
| 166 | case 'f': // PF15 | 157 | case 'f': // PF15 |
| 167 | push(PF_15); | 158 | push(PF_15); |
| 168 | - waitForReady(); | ||
| 169 | break; | 159 | break; |
| 170 | 160 | ||
| 171 | case 'g': // PF16 | 161 | case 'g': // PF16 |
| 172 | push(PF_16); | 162 | push(PF_16); |
| 173 | - waitForReady(); | ||
| 174 | break; | 163 | break; |
| 175 | 164 | ||
| 176 | case 'h': // PF17 | 165 | case 'h': // PF17 |
| 177 | push(PF_17); | 166 | push(PF_17); |
| 178 | - waitForReady(); | ||
| 179 | break; | 167 | break; |
| 180 | 168 | ||
| 181 | case 'i': // PF18 | 169 | case 'i': // PF18 |
| 182 | push(PF_18); | 170 | push(PF_18); |
| 183 | - waitForReady(); | ||
| 184 | break; | 171 | break; |
| 185 | 172 | ||
| 186 | case 'j': // PF19 | 173 | case 'j': // PF19 |
| 187 | push(PF_19); | 174 | push(PF_19); |
| 188 | - waitForReady(); | ||
| 189 | break; | 175 | break; |
| 190 | 176 | ||
| 191 | case 'k': // PF20 | 177 | case 'k': // PF20 |
| 192 | push(PF_20); | 178 | push(PF_20); |
| 193 | - waitForReady(); | ||
| 194 | break; | 179 | break; |
| 195 | 180 | ||
| 196 | case 'l': // PF21 | 181 | case 'l': // PF21 |
| 197 | push(PF_21); | 182 | push(PF_21); |
| 198 | - waitForReady(); | ||
| 199 | break; | 183 | break; |
| 200 | 184 | ||
| 201 | case 'm': // PF22 | 185 | case 'm': // PF22 |
| 202 | push(PF_22); | 186 | push(PF_22); |
| 203 | - waitForReady(); | ||
| 204 | break; | 187 | break; |
| 205 | 188 | ||
| 206 | case 'n': // PF23 | 189 | case 'n': // PF23 |
| 207 | push(PF_23); | 190 | push(PF_23); |
| 208 | - waitForReady(); | ||
| 209 | break; | 191 | break; |
| 210 | 192 | ||
| 211 | case 'o': // PF24 | 193 | case 'o': // PF24 |
| 212 | push(PF_24); | 194 | push(PF_24); |
| 213 | - waitForReady(); | ||
| 214 | break; | 195 | break; |
| 215 | 196 | ||
| 216 | case '@': // Send '@' character | 197 | case '@': // Send '@' character |
| @@ -219,17 +200,14 @@ | @@ -219,17 +200,14 @@ | ||
| 219 | 200 | ||
| 220 | case 'x': // PA1 | 201 | case 'x': // PA1 |
| 221 | push(PA_1); | 202 | push(PA_1); |
| 222 | - waitForReady(); | ||
| 223 | break; | 203 | break; |
| 224 | 204 | ||
| 225 | case 'y': // PA2 | 205 | case 'y': // PA2 |
| 226 | push(PA_2); | 206 | push(PA_2); |
| 227 | - waitForReady(); | ||
| 228 | break; | 207 | break; |
| 229 | 208 | ||
| 230 | case 'z': // PA3 | 209 | case 'z': // PA3 |
| 231 | push(PA_3); | 210 | push(PA_3); |
| 232 | - waitForReady(); | ||
| 233 | break; | 211 | break; |
| 234 | 212 | ||
| 235 | case 'B': // PC_LEFTTAB = "@B" | 213 | case 'B': // PC_LEFTTAB = "@B" |
| @@ -343,8 +321,10 @@ | @@ -343,8 +321,10 @@ | ||
| 343 | text = (ptr+1); | 321 | text = (ptr+1); |
| 344 | } | 322 | } |
| 345 | 323 | ||
| 346 | - if(*text) { | ||
| 347 | - push(text,strlen(text)); | 324 | + sz = strlen(text); |
| 325 | + if(sz) { | ||
| 326 | + waitForUnlock(); | ||
| 327 | + push(text,sz); | ||
| 348 | } | 328 | } |
| 349 | 329 | ||
| 350 | } | 330 | } |
client/src/host/actions.cc
| @@ -55,3 +55,9 @@ TN3270::Host & TN3270::Host::waitForReady(time_t timeout) { | @@ -55,3 +55,9 @@ TN3270::Host & TN3270::Host::waitForReady(time_t timeout) { | ||
| 55 | return *this; | 55 | return *this; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | +TN3270::Host & TN3270::Host::waitForUnlock(time_t timeout) { | ||
| 59 | + this->session->waitForUnlock(timeout); | ||
| 60 | + return *this; | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | + |
client/src/session/local/actions.cc
| @@ -60,7 +60,7 @@ | @@ -60,7 +60,7 @@ | ||
| 60 | chkResponse(lib3270_disconnect(hSession)); | 60 | chkResponse(lib3270_disconnect(hSession)); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | - void Local::Session::wait(unsigned short seconds) const { | 63 | + void Local::Session::wait(time_t seconds) const { |
| 64 | 64 | ||
| 65 | std::lock_guard<std::mutex> lock(const_cast<Local::Session *>(this)->sync); | 65 | std::lock_guard<std::mutex> lock(const_cast<Local::Session *>(this)->sync); |
| 66 | chkResponse(lib3270_wait(this->hSession, seconds)); | 66 | chkResponse(lib3270_wait(this->hSession, seconds)); |
| @@ -73,7 +73,13 @@ | @@ -73,7 +73,13 @@ | ||
| 73 | chkResponse(lib3270_wait_for_ready(this->hSession, timeout)); | 73 | chkResponse(lib3270_wait_for_ready(this->hSession, timeout)); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | - void Local::Session::waitForChange(unsigned short seconds) const { | 76 | + void Local::Session::waitForUnlock(time_t timeout) const { |
| 77 | + | ||
| 78 | + std::lock_guard<std::mutex> lock(const_cast<Local::Session *>(this)->sync); | ||
| 79 | + chkResponse(lib3270_wait_for_unlock(this->hSession, timeout)); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + void Local::Session::waitForChange(time_t seconds) const { | ||
| 77 | 83 | ||
| 78 | std::lock_guard<std::mutex> lock(const_cast<Local::Session *>(this)->sync); | 84 | std::lock_guard<std::mutex> lock(const_cast<Local::Session *>(this)->sync); |
| 79 | chkResponse(lib3270_wait_for_update(this->hSession, seconds)); | 85 | chkResponse(lib3270_wait_for_update(this->hSession, seconds)); |
client/src/session/local/private.h
| @@ -100,9 +100,10 @@ | @@ -100,9 +100,10 @@ | ||
| 100 | void push(const Action action) override; | 100 | void push(const Action action) override; |
| 101 | void print(LIB3270_CONTENT_OPTION option = LIB3270_CONTENT_ALL) override; | 101 | void print(LIB3270_CONTENT_OPTION option = LIB3270_CONTENT_ALL) override; |
| 102 | 102 | ||
| 103 | - void wait(unsigned short seconds) const override; | 103 | + void wait(time_t seconds) const override; |
| 104 | void waitForReady(time_t timeout) const override; | 104 | void waitForReady(time_t timeout) const override; |
| 105 | - void waitForChange(unsigned short seconds) const override; | 105 | + void waitForChange(time_t timeout) const override; |
| 106 | + void waitForUnlock(time_t seconds) const override; | ||
| 106 | 107 | ||
| 107 | // States | 108 | // States |
| 108 | ProgramMessage getProgramMessage() const override; | 109 | ProgramMessage getProgramMessage() const override; |
client/src/session/remote/actions.cc
| @@ -83,7 +83,7 @@ | @@ -83,7 +83,7 @@ | ||
| 83 | 83 | ||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | - void IPC::Session::wait(unsigned short seconds) const { | 86 | + void IPC::Session::wait(time_t seconds) const { |
| 87 | 87 | ||
| 88 | time_t end = time(nullptr) + seconds; | 88 | time_t end = time(nullptr) + seconds; |
| 89 | 89 | ||
| @@ -128,7 +128,33 @@ | @@ -128,7 +128,33 @@ | ||
| 128 | 128 | ||
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | - void IPC::Session::waitForChange(unsigned short seconds) const { | 131 | + void IPC::Session::waitForUnlock(time_t timeout) const { |
| 132 | + | ||
| 133 | + int rc; | ||
| 134 | + | ||
| 135 | + time_t end = time(nullptr) + timeout; | ||
| 136 | + | ||
| 137 | + while(time(nullptr) < end) { | ||
| 138 | + | ||
| 139 | + debug("Running waitForUnlock request..."); | ||
| 140 | + | ||
| 141 | + Request(*this,"waitForUnlock") | ||
| 142 | + .push((uint32_t) 1) | ||
| 143 | + .call() | ||
| 144 | + .pop(rc); | ||
| 145 | + | ||
| 146 | + debug("Wait for unlock returned ",rc); | ||
| 147 | + | ||
| 148 | + if(rc == 0) | ||
| 149 | + return; | ||
| 150 | + | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + throw std::runtime_error("Keyboard is locked"); | ||
| 154 | + | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + void IPC::Session::waitForChange(time_t seconds) const { | ||
| 132 | 158 | ||
| 133 | int rc; | 159 | int rc; |
| 134 | 160 |
client/src/session/remote/private.h
| @@ -98,9 +98,10 @@ | @@ -98,9 +98,10 @@ | ||
| 98 | void push(const Action action) override; | 98 | void push(const Action action) override; |
| 99 | void print(LIB3270_CONTENT_OPTION option = LIB3270_CONTENT_ALL) override; | 99 | void print(LIB3270_CONTENT_OPTION option = LIB3270_CONTENT_ALL) override; |
| 100 | 100 | ||
| 101 | - void wait(unsigned short seconds) const override; | 101 | + void wait(time_t seconds) const override; |
| 102 | void waitForReady(time_t timeout) const override; | 102 | void waitForReady(time_t timeout) const override; |
| 103 | - void waitForChange(unsigned short seconds) const override; | 103 | + void waitForChange(time_t timeout) const override; |
| 104 | + void waitForUnlock(time_t seconds) const override; | ||
| 104 | 105 | ||
| 105 | // States | 106 | // States |
| 106 | ProgramMessage getProgramMessage() const override; | 107 | ProgramMessage getProgramMessage() const override; |
common/src/include/lib3270/ipc.h
| @@ -327,13 +327,16 @@ | @@ -327,13 +327,16 @@ | ||
| 327 | virtual void disconnect() = 0; | 327 | virtual void disconnect() = 0; |
| 328 | 328 | ||
| 329 | /// @brief Wait. | 329 | /// @brief Wait. |
| 330 | - virtual void wait(unsigned short seconds) const = 0; | 330 | + virtual void wait(time_t seconds) const = 0; |
| 331 | 331 | ||
| 332 | /// @brief Wait until session state changes to "ready". | 332 | /// @brief Wait until session state changes to "ready". |
| 333 | virtual void waitForReady(time_t timeout = DEFAULT_TIMEOUT) const = 0; | 333 | virtual void waitForReady(time_t timeout = DEFAULT_TIMEOUT) const = 0; |
| 334 | 334 | ||
| 335 | /// @brief Wait for screen changes. | 335 | /// @brief Wait for screen changes. |
| 336 | - virtual void waitForChange(unsigned short seconds) const = 0; | 336 | + virtual void waitForChange(time_t seconds = DEFAULT_TIMEOUT) const = 0; |
| 337 | + | ||
| 338 | + /// @brief Wait for screen changes. | ||
| 339 | + virtual void waitForUnlock(time_t seconds = DEFAULT_TIMEOUT) const = 0; | ||
| 337 | 340 | ||
| 338 | /// @brief Send PF. | 341 | /// @brief Send PF. |
| 339 | virtual void pfkey(unsigned short value) = 0; | 342 | virtual void pfkey(unsigned short value) = 0; |
| @@ -436,6 +439,7 @@ | @@ -436,6 +439,7 @@ | ||
| 436 | Host & connect(const char *url = nullptr); | 439 | Host & connect(const char *url = nullptr); |
| 437 | Host & disconnect(); | 440 | Host & disconnect(); |
| 438 | Host & waitForReady(time_t timeout = DEFAULT_TIMEOUT); | 441 | Host & waitForReady(time_t timeout = DEFAULT_TIMEOUT); |
| 442 | + Host & waitForUnlock(time_t timeout = DEFAULT_TIMEOUT); | ||
| 439 | 443 | ||
| 440 | /// @brief Execute action by name. | 444 | /// @brief Execute action by name. |
| 441 | inline Host & action(const char *action_name) { | 445 | inline Host & action(const char *action_name) { |
server/src/core/linux/gobject.c
| @@ -155,6 +155,10 @@ void ipc3270_add_terminal_introspection(GString *introspection) { | @@ -155,6 +155,10 @@ void ipc3270_add_terminal_introspection(GString *introspection) { | ||
| 155 | " <arg type='u' name='seconds' direction='in' />" \ | 155 | " <arg type='u' name='seconds' direction='in' />" \ |
| 156 | " <arg type='i' name='result' direction='out' />" \ | 156 | " <arg type='i' name='result' direction='out' />" \ |
| 157 | " </method>" \ | 157 | " </method>" \ |
| 158 | + " <method name= 'waitForUnlock'>" \ | ||
| 159 | + " <arg type='u' name='seconds' direction='in' />" \ | ||
| 160 | + " <arg type='i' name='result' direction='out' />" \ | ||
| 161 | + " </method>" \ | ||
| 158 | " <method name= 'waitForUpdate'>" \ | 162 | " <method name= 'waitForUpdate'>" \ |
| 159 | " <arg type='u' name='seconds' direction='in' />" \ | 163 | " <arg type='u' name='seconds' direction='in' />" \ |
| 160 | " <arg type='i' name='result' direction='out' />" \ | 164 | " <arg type='i' name='result' direction='out' />" \ |
server/src/core/methods/methods.c
| @@ -49,6 +49,7 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req | @@ -49,6 +49,7 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req | ||
| 49 | { "wait", ipc3270_method_wait }, | 49 | { "wait", ipc3270_method_wait }, |
| 50 | { "waitforready", ipc3270_method_wait_for_ready }, | 50 | { "waitforready", ipc3270_method_wait_for_ready }, |
| 51 | { "waitforupdate", ipc3270_method_wait_for_update }, | 51 | { "waitforupdate", ipc3270_method_wait_for_update }, |
| 52 | + { "waitforunlock", ipc3270_method_wait_for_unlock }, | ||
| 52 | 53 | ||
| 53 | { "getString", ipc3270_method_get_string }, | 54 | { "getString", ipc3270_method_get_string }, |
| 54 | { "getStringAt", ipc3270_method_get_string }, | 55 | { "getStringAt", ipc3270_method_get_string }, |
server/src/core/methods/private.h
| @@ -50,6 +50,7 @@ | @@ -50,6 +50,7 @@ | ||
| 50 | G_GNUC_INTERNAL int ipc3270_method_wait(GObject *session, GVariant *request, GObject *response, GError **error); | 50 | G_GNUC_INTERNAL int ipc3270_method_wait(GObject *session, GVariant *request, GObject *response, GError **error); |
| 51 | G_GNUC_INTERNAL int ipc3270_method_wait_for_ready(GObject *session, GVariant *request, GObject *response, GError **error); | 51 | G_GNUC_INTERNAL int ipc3270_method_wait_for_ready(GObject *session, GVariant *request, GObject *response, GError **error); |
| 52 | G_GNUC_INTERNAL int ipc3270_method_wait_for_update(GObject *session, GVariant *request, GObject *response, GError **error); | 52 | G_GNUC_INTERNAL int ipc3270_method_wait_for_update(GObject *session, GVariant *request, GObject *response, GError **error); |
| 53 | + G_GNUC_INTERNAL int ipc3270_method_wait_for_unlock(GObject *session, GVariant *request, GObject *response, GError **error); | ||
| 53 | 54 | ||
| 54 | G_GNUC_INTERNAL int ipc3270_method_get_field_attribute(GObject *session, GVariant *request, GObject *response, GError **error); | 55 | G_GNUC_INTERNAL int ipc3270_method_get_field_attribute(GObject *session, GVariant *request, GObject *response, GError **error); |
| 55 | 56 |
server/src/core/methods/wait.c
| @@ -55,3 +55,12 @@ int ipc3270_method_wait_for_update(GObject *session, GVariant *request, GObject | @@ -55,3 +55,12 @@ int ipc3270_method_wait_for_update(GObject *session, GVariant *request, GObject | ||
| 55 | return 0; | 55 | return 0; |
| 56 | 56 | ||
| 57 | } | 57 | } |
| 58 | + | ||
| 59 | +int ipc3270_method_wait_for_unlock(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) { | ||
| 60 | + | ||
| 61 | + guint seconds = 1; | ||
| 62 | + g_variant_get(request, "(u)", &seconds); | ||
| 63 | + ipc3270_response_append_int32(response, lib3270_wait_for_unlock(ipc3270_get_session(session),seconds)); | ||
| 64 | + return 0; | ||
| 65 | + | ||
| 66 | +} |