Commit 04548e41fa30b4e00357171e3fb5cc20d37e8485

Authored by perry.werneck@gmail.com
1 parent cc8c8904

Melhorando plugin hllapi

src/include/lib3270.h
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 #include <errno.h> 36 #include <errno.h>
37 37
38 #ifndef ENOTCONN 38 #ifndef ENOTCONN
39 - #define ENOTCONN 107 39 + #define ENOTCONN 126
40 #endif // !ENOTCONN 40 #endif // !ENOTCONN
41 41
42 #if defined(__GNUC__) 42 #if defined(__GNUC__)
src/include/pw3270/v3270.h
@@ -186,7 +186,7 @@ @@ -186,7 +186,7 @@
186 LIB3270_EXPORT void v3270_popup_message(GtkWidget *widget, LIB3270_NOTIFY type, const gchar *title, const gchar *message, const gchar *text); 186 LIB3270_EXPORT void v3270_popup_message(GtkWidget *widget, LIB3270_NOTIFY type, const gchar *title, const gchar *message, const gchar *text);
187 LIB3270_EXPORT const gchar * v3270_get_session_name(GtkWidget *widget); 187 LIB3270_EXPORT const gchar * v3270_get_session_name(GtkWidget *widget);
188 LIB3270_EXPORT void v3270_set_session_name(GtkWidget *widget, const gchar *name); 188 LIB3270_EXPORT void v3270_set_session_name(GtkWidget *widget, const gchar *name);
189 - LIB3270_EXPORT int v3270_set_script(GtkWidget *widget, const gchar id, unsigned char on); 189 + LIB3270_EXPORT int v3270_set_script(GtkWidget *widget, const gchar id, gboolean on);
190 LIB3270_EXPORT void v3270_set_scaled_fonts(GtkWidget *widget, gboolean on); 190 LIB3270_EXPORT void v3270_set_scaled_fonts(GtkWidget *widget, gboolean on);
191 191
192 LIB3270_EXPORT void v3270_set_host(GtkWidget *widget, const gchar *uri); 192 LIB3270_EXPORT void v3270_set_host(GtkWidget *widget, const gchar *uri);
src/lib3270/iocalls.c
@@ -726,6 +726,9 @@ LIB3270_EXPORT int lib3270_wait_for_ready(H3270 *hSession, int seconds) @@ -726,6 +726,9 @@ LIB3270_EXPORT int lib3270_wait_for_ready(H3270 *hSession, int seconds)
726 { 726 {
727 time_t end = time(0)+seconds; 727 time_t end = time(0)+seconds;
728 728
  729 + if(hSession->oia_status == LIB3270_STATUS_BLANK)
  730 + return 0;
  731 +
729 while(time(0) < end) 732 while(time(0) < end)
730 { 733 {
731 event_dispatcher(hSession,1); 734 event_dispatcher(hSession,1);
src/plugins/remotectl/hllapi.c
@@ -79,7 +79,7 @@ @@ -79,7 +79,7 @@
79 } 79 }
80 80
81 81
82 - static char * run_query(unsigned long func, const char *arg, size_t length, unsigned short *rc) 82 + static char * run_query(unsigned long func, const char *arg, size_t *length, unsigned short *rc)
83 { 83 {
84 char *outBuffer = NULL; 84 char *outBuffer = NULL;
85 85
@@ -93,7 +93,7 @@ @@ -93,7 +93,7 @@
93 else 93 else
94 { 94 {
95 HLLAPI_DATA *buffer = malloc(HLLAPI_MAXLENGTH+1); 95 HLLAPI_DATA *buffer = malloc(HLLAPI_MAXLENGTH+1);
96 - DWORD cbSize = sizeof(HLLAPI_DATA) + length; 96 + DWORD cbSize = sizeof(HLLAPI_DATA) + *length;
97 HLLAPI_DATA *data = malloc(cbSize+1); 97 HLLAPI_DATA *data = malloc(cbSize+1);
98 98
99 memset(buffer,0,HLLAPI_MAXLENGTH); 99 memset(buffer,0,HLLAPI_MAXLENGTH);
@@ -101,10 +101,10 @@ @@ -101,10 +101,10 @@
101 data->id = HLLAPI_REQUEST_ID; 101 data->id = HLLAPI_REQUEST_ID;
102 data->func = func; 102 data->func = func;
103 data->rc = *rc; 103 data->rc = *rc;
104 - data->len = length; 104 + data->len = *length;
105 105
106 - if(arg && length > 0)  
107 - memcpy(data->string,arg,length); 106 + if(arg && *length > 0)
  107 + memcpy(data->string,arg,*length);
108 108
109 memset(buffer,0,HLLAPI_MAXLENGTH); 109 memset(buffer,0,HLLAPI_MAXLENGTH);
110 110
@@ -115,7 +115,8 @@ @@ -115,7 +115,8 @@
115 } 115 }
116 else 116 else
117 { 117 {
118 - *rc = buffer->rc; 118 + *rc = buffer->rc;
  119 + *length = buffer->len;
119 120
120 trace("buffer->len=%d rc=%d",buffer->len,buffer->rc); 121 trace("buffer->len=%d rc=%d",buffer->len,buffer->rc);
121 122
@@ -162,6 +163,7 @@ @@ -162,6 +163,7 @@
162 { 163 {
163 char * inBuffer = NULL; 164 char * inBuffer = NULL;
164 char * outBuffer = NULL; 165 char * outBuffer = NULL;
  166 + size_t szOutBuffer;
165 167
166 if(*length < 0 || *length > HLLAPI_MAXLENGTH) 168 if(*length < 0 || *length > HLLAPI_MAXLENGTH)
167 { 169 {
@@ -169,6 +171,8 @@ @@ -169,6 +171,8 @@
169 return 0; 171 return 0;
170 } 172 }
171 173
  174 + szOutBuffer = (size_t) *length;
  175 +
172 // Copy input argument 176 // Copy input argument
173 if(*length) 177 if(*length)
174 { 178 {
@@ -187,7 +191,7 @@ @@ -187,7 +191,7 @@
187 *rc = cmd_connect_ps(inBuffer); 191 *rc = cmd_connect_ps(inBuffer);
188 if(!*rc) 192 if(!*rc)
189 { 193 {
190 - outBuffer = run_query(*func, inBuffer, *length, rc); 194 + outBuffer = run_query(*func, inBuffer, &szOutBuffer, rc);
191 if(*rc) 195 if(*rc)
192 { 196 {
193 trace("Closing pipe rc=%d",*rc); 197 trace("Closing pipe rc=%d",*rc);
@@ -205,7 +209,7 @@ @@ -205,7 +209,7 @@
205 } 209 }
206 else 210 else
207 { 211 {
208 - outBuffer = run_query(*func, inBuffer, *length, rc); 212 + outBuffer = run_query(*func, inBuffer, &szOutBuffer, rc);
209 CloseHandle(hPipe); 213 CloseHandle(hPipe);
210 hPipe = INVALID_HANDLE_VALUE; 214 hPipe = INVALID_HANDLE_VALUE;
211 } 215 }
@@ -214,14 +218,18 @@ @@ -214,14 +218,18 @@
214 218
215 default: 219 default:
216 trace("Calling function %d",(int) *func); 220 trace("Calling function %d",(int) *func);
217 - outBuffer = run_query(*func, inBuffer, *length, rc); 221 + outBuffer = run_query(*func, inBuffer, &szOutBuffer, rc);
218 } 222 }
219 223
220 if(*rc) 224 if(*rc)
221 copyString(buffer,length,strerror(*rc)); 225 copyString(buffer,length,strerror(*rc));
222 else if(outBuffer) 226 else if(outBuffer)
223 - copyString(buffer,length,outBuffer); 227 + {
  228 + if(szOutBuffer < *length)
  229 + *length = szOutBuffer;
224 230
  231 + copyString(buffer,length,outBuffer);
  232 + }
225 if(outBuffer) 233 if(outBuffer)
226 free(outBuffer); 234 free(outBuffer);
227 235
src/plugins/remotectl/pipesource.c
@@ -66,7 +66,7 @@ @@ -66,7 +66,7 @@
66 66
67 static void wait_for_client(pipe_source *source) 67 static void wait_for_client(pipe_source *source)
68 { 68 {
69 - v3270_set_script(pw3270_get_terminal_widget(NULL),'H',0); 69 + set_active(FALSE);
70 if(ConnectNamedPipe(source->hPipe,&source->overlap)) 70 if(ConnectNamedPipe(source->hPipe,&source->overlap))
71 { 71 {
72 popup_lasterror("%s",_( "Error in ConnectNamedPipe" )); 72 popup_lasterror("%s",_( "Error in ConnectNamedPipe" ));
@@ -84,7 +84,7 @@ static void wait_for_client(pipe_source *source) @@ -84,7 +84,7 @@ static void wait_for_client(pipe_source *source)
84 // Client is already connected, so signal an event. 84 // Client is already connected, so signal an event.
85 case ERROR_PIPE_CONNECTED: 85 case ERROR_PIPE_CONNECTED:
86 trace("%s: ERROR_PIPE_CONNECTED",__FUNCTION__); 86 trace("%s: ERROR_PIPE_CONNECTED",__FUNCTION__);
87 - v3270_set_script(pw3270_get_terminal_widget(NULL),'H',1); 87 + set_active(TRUE);
88 if(SetEvent(source->overlap.hEvent)) 88 if(SetEvent(source->overlap.hEvent))
89 break; 89 break;
90 90
@@ -137,21 +137,101 @@ static void wait_for_client(pipe_source *source) @@ -137,21 +137,101 @@ static void wait_for_client(pipe_source *source)
137 137
138 static void process_input(pipe_source *source, DWORD cbRead) 138 static void process_input(pipe_source *source, DWORD cbRead)
139 { 139 {
140 - HLLAPI_DATA *data = (HLLAPI_DATA *) source->buffer; 140 + HLLAPI_DATA * data = (HLLAPI_DATA *) source->buffer;
  141 + QUERY * qry = g_malloc0(sizeof(QUERY)+cbRead+1);
141 142
142 - source->buffer[cbRead] = 0; 143 + qry->hPipe = source->hPipe;
  144 + qry->text = (const gchar *) (qry+1);
143 145
144 if(data->id == 0x01) 146 if(data->id == 0x01)
145 { 147 {
146 - DWORD wrote;  
147 - data->rc = run_hllapi(data->func,data->string,data->len,data->rc);  
148 - wrote = sizeof(HLLAPI_DATA)+data->len; 148 + // HLLAPI query
  149 + qry->cmd = (int) data->func;
  150 + qry->pos = (int) data->rc;
  151 + qry->length = data->len;
  152 + memcpy((gchar *)(qry->text),data->string,qry->length);
  153 + }
  154 + else
  155 + {
  156 + qry->cmd = -1;
  157 + }
  158 +
  159 + enqueue_request(qry);
  160 + }
  161 +
  162 + void request_complete(QUERY *qry, int rc, const gchar *text)
  163 + {
  164 + request_buffer(qry,rc,strlen(text),(const gpointer) text);
  165 + }
  166 +
  167 + void request_status(QUERY *qry, int rc)
  168 + {
  169 + if(rc)
  170 + {
  171 + const gchar *msg = strerror(rc);
  172 + request_buffer(qry, rc, strlen(msg), (const gpointer) msg);
  173 + }
  174 + else
  175 + {
  176 + request_buffer(qry, rc, 0, NULL);
  177 + }
  178 +/*
  179 + HLLAPI_DATA data;
  180 +
  181 + memset(&data,0,sizeof(data));
  182 +
  183 + data.id = 0x01;
  184 + data.func = qry->cmd;
  185 + data.rc = rc;
  186 +
  187 + trace("rc=%d",rc);
  188 +
  189 +#ifdef WIN32
  190 + {
  191 + DWORD wrote = sizeof(data);
  192 + WriteFile(qry->hPipe,&data,wrote,&wrote,NULL);
  193 + }
  194 +#endif // WIN32
  195 +
  196 + g_free(qry);
  197 +*/
  198 + }
149 199
150 - trace("%s rc=%d",__FUNCTION__,(int) data->rc); 200 + void request_buffer(QUERY *qry, int rc, size_t szBuffer, const gpointer buffer)
  201 + {
  202 + size_t sz;
  203 + HLLAPI_DATA *data;
151 204
152 - WriteFile(source->hPipe,data,wrote,&wrote,NULL); 205 + if(buffer)
  206 + {
  207 + sz = sizeof(HLLAPI_DATA)+szBuffer;
  208 + data = g_malloc0(sz);
  209 + data->len = szBuffer;
  210 + memcpy(data->string,buffer,szBuffer);
  211 + }
  212 + else
  213 + {
  214 + sz = sizeof(HLLAPI_DATA);
  215 + data = g_malloc0(sz);
153 } 216 }
154 217
  218 + data->id = 0x01;
  219 + data->func = qry->cmd;
  220 + data->rc = rc;
  221 +
  222 + trace("rc=%d data->len=%d",rc,(int) data->len);
  223 +
  224 +#ifdef WIN32
  225 + {
  226 + DWORD wrote = sz;
  227 + WriteFile(qry->hPipe,data,wrote,&wrote,NULL);
  228 + trace("Wrote=%d len=%d",(int) wrote, (int) sz);
  229 + }
  230 +#endif // WIN32
  231 +
  232 + g_free(data);
  233 + g_free(qry);
  234 +
155 } 235 }
156 236
157 static void read_input_pipe(pipe_source *source) 237 static void read_input_pipe(pipe_source *source)
@@ -179,9 +259,10 @@ static void wait_for_client(pipe_source *source) @@ -179,9 +259,10 @@ static void wait_for_client(pipe_source *source)
179 259
180 case ERROR_BROKEN_PIPE: 260 case ERROR_BROKEN_PIPE:
181 trace("%s: ERROR_BROKEN_PIPE",__FUNCTION__); 261 trace("%s: ERROR_BROKEN_PIPE",__FUNCTION__);
  262 +
182 if(!DisconnectNamedPipe(source->hPipe)) 263 if(!DisconnectNamedPipe(source->hPipe))
183 { 264 {
184 - v3270_set_script(pw3270_get_terminal_widget(NULL),'H',0); 265 + set_active(FALSE);
185 popup_lasterror("%s",_( "Error in DisconnectNamedPipe" )); 266 popup_lasterror("%s",_( "Error in DisconnectNamedPipe" ));
186 } 267 }
187 else 268 else
@@ -192,7 +273,7 @@ static void wait_for_client(pipe_source *source) @@ -192,7 +273,7 @@ static void wait_for_client(pipe_source *source)
192 273
193 case ERROR_PIPE_NOT_CONNECTED: 274 case ERROR_PIPE_NOT_CONNECTED:
194 trace("%s: ERROR_PIPE_NOT_CONNECTED",__FUNCTION__); 275 trace("%s: ERROR_PIPE_NOT_CONNECTED",__FUNCTION__);
195 - v3270_set_script(pw3270_get_terminal_widget(NULL),'H',0); 276 + set_active(FALSE);
196 break; 277 break;
197 278
198 default: 279 default:
@@ -227,7 +308,7 @@ static void wait_for_client(pipe_source *source) @@ -227,7 +308,7 @@ static void wait_for_client(pipe_source *source)
227 if(fSuccess) 308 if(fSuccess)
228 { 309 {
229 trace("Pipe connected (cbRet=%d)",(int) cbRead); 310 trace("Pipe connected (cbRet=%d)",(int) cbRead);
230 - v3270_set_script(pw3270_get_terminal_widget(NULL),'H',1); 311 + set_active(TRUE);
231 ((pipe_source *) source)->state = PIPE_STATE_READ; 312 ((pipe_source *) source)->state = PIPE_STATE_READ;
232 } 313 }
233 else 314 else
src/plugins/remotectl/remotectl.c
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 41
42 /*--[ Implement ]------------------------------------------------------------------------------------*/ 42 /*--[ Implement ]------------------------------------------------------------------------------------*/
43 43
44 - static const gchar control_char = '@'; 44 + static const gchar control_char = '@';
45 45
46 /*--[ Implement ]------------------------------------------------------------------------------------*/ 46 /*--[ Implement ]------------------------------------------------------------------------------------*/
47 47
@@ -137,55 +137,64 @@ @@ -137,55 +137,64 @@
137 #error Nao implementado 137 #error Nao implementado
138 138
139 #endif // WIN32 139 #endif // WIN32
  140 +
  141 + set_active(FALSE);
  142 +
140 return 0; 143 return 0;
141 } 144 }
142 145
143 - static int cmd_connectps(H3270 *hSession, unsigned short rc, char *string, unsigned short length) 146 + static void cmd_connectps(QUERY *qry)
144 { 147 {
145 g_message("%s","HLLAPI ConnectPS request received"); 148 g_message("%s","HLLAPI ConnectPS request received");
146 - return v3270_set_script(pw3270_get_terminal_widget(NULL),'H',1); 149 + request_status(qry,v3270_set_script(pw3270_get_terminal_widget(NULL),'H',TRUE));
147 } 150 }
148 151
149 - static int cmd_disconnectps(H3270 *hSession, unsigned short rc, char *string, unsigned short length) 152 + static void cmd_disconnectps(QUERY *qry)
150 { 153 {
151 g_message("%s","HLLAPI DisconnectPS request received"); 154 g_message("%s","HLLAPI DisconnectPS request received");
152 - return 0; 155 + request_status(qry,0);
153 } 156 }
154 157
155 - static int cmd_getrevision(H3270 *hSession, unsigned short rc, char *string, unsigned short length) 158 + static void cmd_getrevision(QUERY *qry)
156 { 159 {
157 - strncpy(string,lib3270_get_revision(),length);  
158 - return 0; 160 + request_complete(qry,0,lib3270_get_revision());
159 } 161 }
160 162
161 - static int cmd_setcursor(H3270 *hSession, unsigned short rc, char *string, unsigned short length) 163 + static void cmd_setcursor(QUERY *qry)
162 { 164 {
163 - if(!lib3270_connected(hSession))  
164 - return ENOTCONN; 165 + int rc = ENOTCONN;
165 166
166 - trace("%s: pos=%d row=%d col=%d",__FUNCTION__,rc,rc/80,rc%80);  
167 - lib3270_set_cursor_address(hSession,((int) rc) -1);  
168 - return 0; 167 + if(lib3270_connected(qry->hSession))
  168 + {
  169 + trace("%s: pos=%d row=%d col=%d",__FUNCTION__,rc,rc/80,rc%80);
  170 + lib3270_set_cursor_address(qry->hSession,qry->pos -1);
  171 + rc = 0;
  172 + }
  173 +
  174 + request_status(qry,rc);
169 } 175 }
170 176
171 - static int cmd_sendstring(H3270 *hSession, unsigned short dunno, char *buffer, unsigned short length) 177 + static void cmd_sendstring(QUERY *qry)
172 { 178 {
173 gchar * text; 179 gchar * text;
174 GError * error = NULL; 180 GError * error = NULL;
175 gsize bytes_read; 181 gsize bytes_read;
176 gsize bytes_written; 182 gsize bytes_written;
177 const gchar * charset; 183 const gchar * charset;
178 - int rc = -1;  
179 184
180 - if(!lib3270_connected(hSession))  
181 - return ENOTCONN; 185 + if(!lib3270_connected(qry->hSession))
  186 + {
  187 + request_status(qry,ENOTCONN);
  188 + return;
  189 + }
182 190
183 g_get_charset(&charset); 191 g_get_charset(&charset);
184 192
185 - text = g_convert(buffer,length,lib3270_get_charset(hSession),charset,&bytes_read,&bytes_written,&error); 193 + text = g_convert(qry->text,qry->length,lib3270_get_charset(qry->hSession),charset,&bytes_read,&bytes_written,&error);
186 if(text) 194 if(text)
187 { 195 {
188 - rc = 0; 196 + int rc = 0;
  197 +
189 if(strchr(text,control_char)) 198 if(strchr(text,control_char))
190 { 199 {
191 // Convert control char 200 // Convert control char
@@ -196,7 +205,7 @@ @@ -196,7 +205,7 @@
196 { 205 {
197 *(ptr++) = 0; 206 *(ptr++) = 0;
198 207
199 - lib3270_emulate_input(hSession,buffer,-1,0); 208 + lib3270_emulate_input(qry->hSession,buffer,-1,0);
200 209
201 switch(*(ptr++)) 210 switch(*(ptr++))
202 { 211 {
@@ -205,112 +214,160 @@ @@ -205,112 +214,160 @@
205 break; 214 break;
206 215
207 case 'E': // Enter 216 case 'E': // Enter
208 - lib3270_enter(hSession); 217 + lib3270_enter(qry->hSession);
209 break; 218 break;
210 219
211 case 'F': // Erase EOF 220 case 'F': // Erase EOF
212 - lib3270_eraseeof(hSession); 221 + lib3270_eraseeof(qry->hSession);
213 break; 222 break;
214 223
215 case '1': // PF1 224 case '1': // PF1
216 - lib3270_pfkey(hSession,1); 225 + lib3270_pfkey(qry->hSession,1);
217 break; 226 break;
218 227
219 case '2': // PF2 228 case '2': // PF2
220 - lib3270_pfkey(hSession,2); 229 + lib3270_pfkey(qry->hSession,2);
221 break; 230 break;
222 231
223 case '3': // PF3 232 case '3': // PF3
224 - lib3270_pfkey(hSession,3); 233 + lib3270_pfkey(qry->hSession,3);
225 break; 234 break;
226 235
227 case '4': // PF4 236 case '4': // PF4
228 - lib3270_pfkey(hSession,4); 237 + lib3270_pfkey(qry->hSession,4);
229 break; 238 break;
230 239
231 case '5': // PF5 240 case '5': // PF5
232 - lib3270_pfkey(hSession,5); 241 + lib3270_pfkey(qry->hSession,5);
233 break; 242 break;
234 243
235 case '6': // PF6 244 case '6': // PF6
236 - lib3270_pfkey(hSession,6); 245 + lib3270_pfkey(qry->hSession,6);
237 break; 246 break;
238 247
239 case '7': // PF7 248 case '7': // PF7
240 - lib3270_pfkey(hSession,7); 249 + lib3270_pfkey(qry->hSession,7);
241 break; 250 break;
242 251
243 case '8': // PF8 252 case '8': // PF8
244 - lib3270_pfkey(hSession,8); 253 + lib3270_pfkey(qry->hSession,8);
245 break; 254 break;
246 255
247 case '9': // PF9 256 case '9': // PF9
248 - lib3270_pfkey(hSession,9); 257 + lib3270_pfkey(qry->hSession,9);
249 break; 258 break;
250 259
251 case 'a': // PF10 260 case 'a': // PF10
252 - lib3270_pfkey(hSession,10); 261 + lib3270_pfkey(qry->hSession,10);
253 break; 262 break;
254 263
255 case 'b': // PF11 264 case 'b': // PF11
256 - lib3270_pfkey(hSession,11); 265 + lib3270_pfkey(qry->hSession,11);
257 break; 266 break;
258 267
259 case 'c': // PF12 268 case 'c': // PF12
260 - lib3270_pfkey(hSession,12); 269 + lib3270_pfkey(qry->hSession,12);
261 break; 270 break;
262 } 271 }
263 272
264 } 273 }
265 274
266 - lib3270_emulate_input(hSession,buffer,-1,0); 275 + lib3270_emulate_input(qry->hSession,buffer,-1,0);
267 276
268 } 277 }
269 else 278 else
270 { 279 {
271 - lib3270_emulate_input(hSession,text,strlen(text),0); 280 + lib3270_emulate_input(qry->hSession,text,strlen(text),0);
272 } 281 }
273 g_free(text); 282 g_free(text);
  283 +
  284 + request_status(qry,rc);
  285 +
  286 + return;
274 } 287 }
275 - else 288 +
  289 + request_complete(qry, error->code, error->message);
  290 + g_error_free(error);
  291 +
  292 + }
  293 +
  294 + struct wait
  295 + {
  296 + QUERY * qry;
  297 + time_t end;
  298 + };
  299 +
  300 + static gboolean do_wait(struct wait *w)
  301 + {
  302 + if(lib3270_get_program_message(w->qry->hSession) == LIB3270_MESSAGE_NONE)
276 { 303 {
277 - strncpy(buffer,error->message,length);  
278 - rc = error->code;  
279 - g_error_free(error); 304 + request_status(w->qry,0);
  305 + return FALSE;
280 } 306 }
281 307
282 - return rc; 308 + if(time(0) > w->end)
  309 + {
  310 + trace("%s: TIMEOUT",__FUNCTION__);
  311 + request_status(w->qry,ETIMEDOUT);
  312 + return FALSE;
  313 + }
  314 +
  315 + return TRUE;
283 } 316 }
284 317
285 - static int cmd_wait(H3270 *hSession, unsigned short rc, char *text, unsigned short length) 318 + static void cmd_wait(QUERY *qry)
286 { 319 {
287 - return lib3270_wait_for_ready(hSession,pw3270_get_integer(pw3270_get_toplevel(),"hllapi","wait",2)); 320 + struct wait *w;
  321 +
  322 + if(lib3270_get_program_message(qry->hSession) == LIB3270_MESSAGE_NONE)
  323 + {
  324 + request_status(qry,0);
  325 + return;
  326 + }
  327 +
  328 + w = g_malloc0(sizeof(struct wait));
  329 + w->qry = qry;
  330 + w->end = time(0)+pw3270_get_integer(pw3270_get_toplevel(),"hllapi","wait",2);
  331 +
  332 + g_timeout_add_full(G_PRIORITY_DEFAULT, (guint) 300, (GSourceFunc) do_wait, w, g_free);
288 } 333 }
289 334
290 - static int cmd_copypstostr(H3270 *hSession, unsigned short pos, char *outBuff, unsigned short length) 335 + static void cmd_copypstostr(QUERY *qry)
291 { 336 {
292 int rows; 337 int rows;
293 int cols; 338 int cols;
294 unsigned short * attr; 339 unsigned short * attr;
295 unsigned char * text; 340 unsigned char * text;
296 int rc; 341 int rc;
  342 + unsigned char * buffer;
  343 + size_t length;
297 344
298 - lib3270_get_screen_size(hSession,&rows,&cols); 345 + if(!lib3270_connected(qry->hSession))
  346 + {
  347 + request_status(qry,ENOTCONN);
  348 + return;
  349 + }
299 350
300 - if(pos < 1 || (pos+length) >= (rows*cols))  
301 - return EINVAL; 351 + lib3270_get_screen_size(qry->hSession,&rows,&cols);
  352 +
  353 + if(qry->pos < 1 || (qry->pos+qry->length) >= (rows*cols))
  354 + {
  355 + request_status(qry,EINVAL);
  356 + return;
  357 + }
302 358
303 - pos--; 359 + qry->pos--;
304 360
305 - attr = g_new0(unsigned short, length+0);  
306 - text = g_new0(unsigned char, length+1); 361 + length = (qry->length * sizeof(unsigned short)) + qry->length + 2;
  362 + text = buffer = g_malloc0(length+1);
  363 + attr = (unsigned short *) (text+qry->length+1);
307 364
308 - trace("%s: pos=%d length=%d",__FUNCTION__,pos,length);  
309 - rc = lib3270_get_contents(hSession,pos,pos+(length-1),text,attr); 365 + trace("%s: pos=%d length=%d",__FUNCTION__,qry->pos,qry->length);
  366 + rc = lib3270_get_contents(qry->hSession,qry->pos,qry->pos+(qry->length-1),text,attr);
310 367
311 if(rc) 368 if(rc)
312 { 369 {
313 - strncpy(outBuff,strerror(rc),length); 370 + request_status(qry,rc);
314 } 371 }
315 else 372 else
316 { 373 {
@@ -324,44 +381,66 @@ @@ -324,44 +381,66 @@
324 381
325 g_get_charset(&charset); 382 g_get_charset(&charset);
326 383
327 - local = g_convert((const gchar *) text,length,charset,lib3270_get_charset(hSession),&bytes_read,&bytes_written,&error);  
328 -  
329 - g_free(attr);  
330 - g_free(text); 384 + local = g_convert((const gchar *) text,-1,charset,lib3270_get_charset(qry->hSession),&bytes_read,&bytes_written,&error);
331 385
332 if(!local) 386 if(!local)
333 { 387 {
334 - rc = error->code;  
335 - strncpy(outBuff,error->message,length); 388 + request_complete(qry,error->code,error->message);
336 g_error_free(error); 389 g_error_free(error);
337 } 390 }
338 else 391 else
339 { 392 {
340 - strncpy(outBuff,(const char *) local,length); 393 + strncpy((char *) text,(const char *) local,qry->length);
  394 +
  395 + trace("response: [%s] len=%d",buffer,length);
  396 + request_buffer(qry,0,length,buffer);
341 g_free(local); 397 g_free(local);
342 } 398 }
343 } 399 }
344 - return rc; 400 +
  401 + g_free(buffer);
345 } 402 }
346 403
347 - int run_hllapi(unsigned long function, char *string, unsigned short length, unsigned short rc) 404 + void enqueue_request(QUERY *qry)
348 { 405 {
349 static const struct _cmd 406 static const struct _cmd
350 { 407 {
351 - unsigned long function;  
352 - int (*exec)(H3270 *hSession, unsigned short rc, char *string, unsigned short length); 408 + int cmd;
  409 + void (*exec)(QUERY *qry);
353 } cmd[] = 410 } cmd[] =
354 { 411 {
355 { HLLAPI_CMD_CONNECTPS, cmd_connectps }, 412 { HLLAPI_CMD_CONNECTPS, cmd_connectps },
356 { HLLAPI_CMD_DISCONNECTPS, cmd_disconnectps }, 413 { HLLAPI_CMD_DISCONNECTPS, cmd_disconnectps },
357 { HLLAPI_CMD_INPUTSTRING, cmd_sendstring }, 414 { HLLAPI_CMD_INPUTSTRING, cmd_sendstring },
358 - { HLLAPI_CMD_WAIT, cmd_wait },  
359 { HLLAPI_CMD_SETCURSOR, cmd_setcursor }, 415 { HLLAPI_CMD_SETCURSOR, cmd_setcursor },
360 { HLLAPI_CMD_GETREVISION, cmd_getrevision }, 416 { HLLAPI_CMD_GETREVISION, cmd_getrevision },
361 - { HLLAPI_CMD_COPYPSTOSTR, cmd_copypstostr } 417 + { HLLAPI_CMD_COPYPSTOSTR, cmd_copypstostr },
  418 + { HLLAPI_CMD_WAIT, cmd_wait },
362 }; 419 };
  420 +
363 int f; 421 int f;
364 422
  423 + trace("HLLAPI function %d",(int) qry->cmd);
  424 +
  425 + qry->hSession = lib3270_get_default_session_handle();
  426 +
  427 + for(f=0;f<G_N_ELEMENTS(cmd);f++)
  428 + {
  429 + if(cmd[f].cmd == qry->cmd)
  430 + {
  431 + cmd[f].exec(qry);
  432 + return;
  433 + }
  434 + }
  435 +
  436 + g_warning("Unexpected HLLAPI function %d",(int) qry->cmd);
  437 + request_status(qry,EINVAL);
  438 + }
  439 +
  440 +/*
  441 + int run_hllapi(unsigned long function, char *string, unsigned short length, unsigned short rc)
  442 + {
  443 +
365 trace("HLLAPI function %d",(int) function); 444 trace("HLLAPI function %d",(int) function);
366 445
367 for(f=0;f<G_N_ELEMENTS(cmd);f++) 446 for(f=0;f<G_N_ELEMENTS(cmd);f++)
@@ -373,4 +452,11 @@ @@ -373,4 +452,11 @@
373 g_warning("Unexpected HLLAPI function %d",(int) function); 452 g_warning("Unexpected HLLAPI function %d",(int) function);
374 return EINVAL; 453 return EINVAL;
375 } 454 }
  455 +*/
  456 +
  457 + G_GNUC_INTERNAL void set_active(gboolean on)
  458 + {
  459 + v3270_set_script(pw3270_get_terminal_widget(NULL),'H',on);
  460 + }
  461 +
376 462
src/plugins/remotectl/remotectl.h
@@ -42,7 +42,30 @@ @@ -42,7 +42,30 @@
42 #include <lib3270/log.h> 42 #include <lib3270/log.h>
43 #include <pw3270/hllapi.h> 43 #include <pw3270/hllapi.h>
44 44
45 - int run_hllapi(unsigned long function, char *string, unsigned short length, unsigned short rc); 45 + typedef struct _remotequery
  46 + {
  47 +#ifdef WIN32
  48 + HANDLE hPipe; /**< Pipe handle (for response) */
  49 +#endif // WIN32
  50 +
  51 + H3270 * hSession; /**< 3270 Session */
  52 + int cmd; /**< Command */
  53 + int rc; /**< Response status */
  54 +
  55 + int pos;
  56 + unsigned short length; /**< Query string length */
  57 + const gchar * text; /**< Query string */
  58 +
  59 + } QUERY;
  60 +
  61 + G_GNUC_INTERNAL void set_active(gboolean on);
  62 + G_GNUC_INTERNAL void enqueue_request(QUERY *qry);
  63 + G_GNUC_INTERNAL void request_complete(QUERY *qry, int rc, const gchar *text);
  64 + G_GNUC_INTERNAL void request_status(QUERY *qry, int rc);
  65 + G_GNUC_INTERNAL void request_buffer(QUERY *qry, int rc, size_t sz, const gpointer buffer);
  66 +
  67 +// int run_hllapi(unsigned long function, char *string, unsigned short length, unsigned short rc);
  68 +
46 69
47 #ifdef WIN32 70 #ifdef WIN32
48 71
src/pw3270/v3270/oia.c
@@ -1087,7 +1087,7 @@ static void release_script(v3270 *widget) @@ -1087,7 +1087,7 @@ static void release_script(v3270 *widget)
1087 widget->script.id = 0; 1087 widget->script.id = 0;
1088 } 1088 }
1089 1089
1090 -LIB3270_EXPORT int v3270_set_script(GtkWidget *widget, const gchar id, unsigned char on) 1090 +LIB3270_EXPORT int v3270_set_script(GtkWidget *widget, const gchar id, gboolean on)
1091 { 1091 {
1092 v3270 *terminal; 1092 v3270 *terminal;
1093 g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL); 1093 g_return_val_if_fail(GTK_IS_V3270(widget),EINVAL);