Commit d0ffcc126997aa09e5d6ec81781567a998fd4ba1

Authored by Perry Werneck
1 parent 48e7d682

Reorganizing and isolating clipboard management code.

@@ -217,7 +217,10 @@ @@ -217,7 +217,10 @@
217 <Unit filename="src/lib3270/see.c"> 217 <Unit filename="src/lib3270/see.c">
218 <Option compilerVar="CC" /> 218 <Option compilerVar="CC" />
219 </Unit> 219 </Unit>
220 - <Unit filename="src/lib3270/selection.c"> 220 + <Unit filename="src/lib3270/selection/actions.c">
  221 + <Option compilerVar="CC" />
  222 + </Unit>
  223 + <Unit filename="src/lib3270/selection/selection.c">
221 <Option compilerVar="CC" /> 224 <Option compilerVar="CC" />
222 </Unit> 225 </Unit>
223 <Unit filename="src/lib3270/session.c"> 226 <Unit filename="src/lib3270/session.c">
src/lib3270/Makefile.in
@@ -30,6 +30,7 @@ LIBNAME=lib@LIB3270_NAME@ @@ -30,6 +30,7 @@ LIBNAME=lib@LIB3270_NAME@
30 30
31 SOURCES= \ 31 SOURCES= \
32 $(wildcard *.c) \ 32 $(wildcard *.c) \
  33 + $(wildcard selection/*.c) \
33 $(wildcard @OSNAME@/*.c) \ 34 $(wildcard @OSNAME@/*.c) \
34 $(wildcard ssl/*.c) \ 35 $(wildcard ssl/*.c) \
35 $(wildcard ssl/@OSNAME@/*.c) \ 36 $(wildcard ssl/@OSNAME@/*.c) \
src/lib3270/private.h
@@ -648,6 +648,16 @@ struct _h3270 @@ -648,6 +648,16 @@ struct _h3270
648 648
649 }; 649 };
650 650
  651 +#define SELECTION_LEFT 0x01
  652 +#define SELECTION_TOP 0x02
  653 +#define SELECTION_RIGHT 0x04
  654 +#define SELECTION_BOTTOM 0x08
  655 +
  656 +#define SELECTION_SINGLE_COL 0x10
  657 +#define SELECTION_SINGLE_ROW 0x20
  658 +
  659 +#define SELECTION_ACTIVE 0x80
  660 +
651 /* Library internal calls */ 661 /* Library internal calls */
652 LIB3270_INTERNAL void key_ACharacter(H3270 *hSession, unsigned char c, enum keytype keytype, enum iaction cause,Boolean *skipped); 662 LIB3270_INTERNAL void key_ACharacter(H3270 *hSession, unsigned char c, enum keytype keytype, enum iaction cause,Boolean *skipped);
653 LIB3270_INTERNAL int cursor_move(H3270 *session, int baddr); 663 LIB3270_INTERNAL int cursor_move(H3270 *session, int baddr);
@@ -660,6 +670,9 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); @@ -660,6 +670,9 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession);
660 670
661 LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block); 671 LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block);
662 672
  673 +LIB3270_INTERNAL void do_select(H3270 *h, int start, int end, int rect);
  674 +
  675 +
663 /** 676 /**
664 * @brief Called from timer to attempt an automatic reconnection. 677 * @brief Called from timer to attempt an automatic reconnection.
665 */ 678 */
src/lib3270/selection.c
@@ -1,912 +0,0 @@ @@ -1,912 +0,0 @@
1 -/*  
2 - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270  
3 - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a  
4 - * aplicativos mainframe. Registro no INPI sob o nome G3270.  
5 - *  
6 - * Copyright (C) <2008> <Banco do Brasil S.A.>  
7 - *  
8 - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob  
9 - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela  
10 - * Free Software Foundation.  
11 - *  
12 - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER  
13 - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO  
14 - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para  
15 - * obter mais detalhes.  
16 - *  
17 - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este  
18 - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin  
19 - * St, Fifth Floor, Boston, MA 02110-1301 USA  
20 - *  
21 - * Este programa está nomeado como selection.c e possui - linhas de código.  
22 - *  
23 - * Contatos:  
24 - *  
25 - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)  
26 - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)  
27 - *  
28 - */  
29 -  
30 - #include "private.h"  
31 - #include <lib3270.h>  
32 - #include <lib3270/actions.h>  
33 - #include <lib3270/session.h>  
34 - #include <lib3270/selection.h>  
35 - #include "3270ds.h"  
36 -  
37 - #define SELECTION_LEFT 0x01  
38 - #define SELECTION_TOP 0x02  
39 - #define SELECTION_RIGHT 0x04  
40 - #define SELECTION_BOTTOM 0x08  
41 -  
42 - #define SELECTION_SINGLE_COL 0x10  
43 - #define SELECTION_SINGLE_ROW 0x20  
44 -  
45 - #define SELECTION_ACTIVE 0x80  
46 -  
47 - static void do_select(H3270 *h, int start, int end, int rect);  
48 -  
49 - /*--[ Implement ]------------------------------------------------------------------------------------*/  
50 -  
51 -static void get_selected_addr(H3270 *session, int *start, int *end)  
52 -{  
53 - if(session->select.start > session->select.end)  
54 - {  
55 - *end = session->select.start;  
56 - *start = session->select.end;  
57 - }  
58 - else  
59 - {  
60 - *start = session->select.start;  
61 - *end = session->select.end;  
62 - }  
63 -}  
64 -  
65 -static void update_selected_rectangle(H3270 *session)  
66 -{  
67 - struct  
68 - {  
69 - int row;  
70 - int col;  
71 - } p[2];  
72 -  
73 -  
74 - int begin, end, row, col, baddr;  
75 -  
76 - get_selected_addr(session,&begin,&end);  
77 -  
78 - // Get start & end posision  
79 - p[0].row = (begin/session->cols);  
80 - p[0].col = (begin%session->cols);  
81 - p[1].row = (end/session->cols);  
82 - p[1].col = (end%session->cols);  
83 -  
84 - if(p[0].row > p[1].row)  
85 - {  
86 - int swp = p[0].row;  
87 - p[0].row = p[1].row;  
88 - p[1].row = swp;  
89 - }  
90 -  
91 - if(p[0].col > p[1].col)  
92 - {  
93 - int swp = p[0].col;  
94 - p[0].col = p[1].col;  
95 - p[1].col = swp;  
96 - }  
97 -  
98 - // First remove unselected areas  
99 - baddr = 0;  
100 - for(row=0;row < session->rows;row++)  
101 - {  
102 - for(col = 0; col < session->cols;col++)  
103 - {  
104 - if(!(row >= p[0].row && row <= p[1].row && col >= p[0].col && col <= p[1].col) && (session->text[baddr].attr & LIB3270_ATTR_SELECTED))  
105 - {  
106 - session->text[baddr].attr &= ~LIB3270_ATTR_SELECTED;  
107 - session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);  
108 - }  
109 - baddr++;  
110 - }  
111 - }  
112 -  
113 - // Then, draw selected ones  
114 - baddr = 0;  
115 - for(row=0;row < session->rows;row++)  
116 - {  
117 - for(col = 0; col < session->cols;col++)  
118 - {  
119 - if((row >= p[0].row && row <= p[1].row && col >= p[0].col && col <= p[1].col) && !(session->text[baddr].attr & LIB3270_ATTR_SELECTED))  
120 - {  
121 - session->text[baddr].attr |= LIB3270_ATTR_SELECTED;  
122 - session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);  
123 - }  
124 - baddr++;  
125 - }  
126 - }  
127 -  
128 -}  
129 -  
130 -static void update_selected_region(H3270 *session)  
131 -{  
132 - int baddr,begin,end;  
133 - int len = session->rows*session->cols;  
134 -  
135 - get_selected_addr(session,&begin,&end);  
136 -  
137 - // First remove unselected areas  
138 - for(baddr = 0; baddr < begin; baddr++)  
139 - {  
140 - if(session->text[baddr].attr & LIB3270_ATTR_SELECTED)  
141 - {  
142 - session->text[baddr].attr &= ~LIB3270_ATTR_SELECTED;  
143 - session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);  
144 - }  
145 - }  
146 -  
147 - for(baddr = end+1; baddr < len; baddr++)  
148 - {  
149 - if(session->text[baddr].attr & LIB3270_ATTR_SELECTED)  
150 - {  
151 - session->text[baddr].attr &= ~LIB3270_ATTR_SELECTED;  
152 - session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);  
153 - }  
154 - }  
155 -  
156 - // Then draw the selected ones  
157 - for(baddr = begin; baddr <= end; baddr++)  
158 - {  
159 - if(!(session->text[baddr].attr & LIB3270_ATTR_SELECTED))  
160 - {  
161 - session->text[baddr].attr |= LIB3270_ATTR_SELECTED;  
162 - session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);  
163 - }  
164 - }  
165 -  
166 -}  
167 -  
168 -void toggle_rectselect(H3270 *session, struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt))  
169 -{  
170 - if(!session->selected)  
171 - return;  
172 -  
173 - if(t->value)  
174 - update_selected_rectangle(session);  
175 - else  
176 - update_selected_region(session);  
177 -}  
178 -  
179 -LIB3270_EXPORT int lib3270_unselect(H3270 *hSession)  
180 -{  
181 - int a;  
182 -  
183 - CHECK_SESSION_HANDLE(hSession);  
184 -  
185 - trace("%s",__FUNCTION__);  
186 -  
187 - if(hSession->selected)  
188 - {  
189 - hSession->selected = 0;  
190 -  
191 - for(a = 0; a < hSession->rows*hSession->cols; a++)  
192 - {  
193 - if(hSession->text[a].attr & LIB3270_ATTR_SELECTED)  
194 - {  
195 - hSession->text[a].attr &= ~LIB3270_ATTR_SELECTED;  
196 - if(hSession->cbk.update)  
197 - hSession->cbk.update(hSession,a,hSession->text[a].chr,hSession->text[a].attr,a == hSession->cursor_addr);  
198 - }  
199 - }  
200 -  
201 - hSession->cbk.set_selection(hSession,0);  
202 - hSession->cbk.update_selection(hSession,-1,-1);  
203 - }  
204 -  
205 - return 0;  
206 -}  
207 -  
208 -LIB3270_EXPORT void lib3270_select_to(H3270 *session, int baddr)  
209 -{  
210 - int start, end;  
211 -  
212 - CHECK_SESSION_HANDLE(session);  
213 -  
214 - if(!lib3270_connected(session))  
215 - return;  
216 -  
217 - start = session->selected ? session->select.start : session->cursor_addr;  
218 -  
219 - cursor_move(session,end = baddr);  
220 -  
221 - do_select(session,start,end,lib3270_get_toggle(session,LIB3270_TOGGLE_RECTANGLE_SELECT));  
222 -  
223 -}  
224 -  
225 -LIB3270_EXPORT int lib3270_select_region(H3270 *h, int start, int end)  
226 -{  
227 - int maxlen;  
228 -  
229 - CHECK_SESSION_HANDLE(h);  
230 -  
231 - if(!lib3270_connected(h))  
232 - return ENOTCONN;  
233 -  
234 - maxlen = (h->rows * h->cols);  
235 -  
236 - // Check bounds  
237 - if(start < 0 || start > maxlen || end < 0 || end > maxlen || start > end)  
238 - return EINVAL;  
239 -  
240 - do_select(h,start,end,lib3270_get_toggle(h,LIB3270_TOGGLE_RECTANGLE_SELECT));  
241 - cursor_move(h,h->select.end);  
242 -  
243 - return 0;  
244 -}  
245 -  
246 -static void do_select(H3270 *h, int start, int end, int rect)  
247 -{  
248 - if(start < 0 || end > (h->rows * h->cols))  
249 - return;  
250 -  
251 - // Do we really need to change selection?  
252 - if(start == h->select.start && end == h->select.end && h->selected)  
253 - return;  
254 -  
255 - // Start address is inside the screen?  
256 - h->select.start = start;  
257 - h->select.end = end;  
258 -  
259 - if(rect)  
260 - {  
261 - h->rectsel = 1;  
262 - update_selected_rectangle(h);  
263 - }  
264 - else  
265 - {  
266 - h->rectsel = 0;  
267 - update_selected_region(h);  
268 - }  
269 -  
270 - if(!h->selected)  
271 - {  
272 - h->selected = 1;  
273 - h->cbk.set_selection(h,1);  
274 - }  
275 -  
276 - h->cbk.update_selection(h,start,end);  
277 -  
278 -}  
279 -  
280 -LIB3270_EXPORT unsigned char lib3270_get_selection_flags(H3270 *hSession, int baddr)  
281 -{  
282 - int row,col;  
283 - unsigned char rc = 0;  
284 -  
285 - CHECK_SESSION_HANDLE(hSession);  
286 -  
287 - if(!(lib3270_connected(hSession) && (hSession->text[baddr].attr & LIB3270_ATTR_SELECTED)))  
288 - return rc;  
289 -  
290 - row = baddr / hSession->cols;  
291 - col = baddr % hSession->cols;  
292 - rc |= SELECTION_ACTIVE;  
293 -  
294 - if( (hSession->select.start % hSession->cols) == (hSession->select.end % hSession->cols) )  
295 - {  
296 - rc |= SELECTION_SINGLE_COL;  
297 - }  
298 - else  
299 - {  
300 - if( (col == 0) || !(hSession->text[baddr-1].attr & LIB3270_ATTR_SELECTED) )  
301 - rc |= SELECTION_LEFT;  
302 -  
303 - if( (col == hSession->cols) || !(hSession->text[baddr+1].attr & LIB3270_ATTR_SELECTED) )  
304 - rc |= SELECTION_RIGHT;  
305 - }  
306 -  
307 - if( (hSession->select.start / hSession->cols) == (hSession->select.end / hSession->cols) )  
308 - {  
309 - rc |= SELECTION_SINGLE_ROW;  
310 - }  
311 - else  
312 - {  
313 - if( (row == 0) || !(hSession->text[baddr-hSession->cols].attr & LIB3270_ATTR_SELECTED) )  
314 - rc |= SELECTION_TOP;  
315 -  
316 - if( (row == hSession->rows) || !(hSession->text[baddr+hSession->cols].attr & LIB3270_ATTR_SELECTED) )  
317 - rc |= SELECTION_BOTTOM;  
318 - }  
319 -  
320 - return rc;  
321 -}  
322 -  
323 -LIB3270_EXPORT int lib3270_select_word_at(H3270 *session, int baddr)  
324 -{  
325 - int start, end;  
326 -  
327 - if(lib3270_get_word_bounds(session,baddr,&start,&end))  
328 - return -1;  
329 -  
330 - trace("%s: baddr=%d start=%d end=%d",__FUNCTION__,baddr,start,end);  
331 -  
332 - do_select(session,start,end,0);  
333 -  
334 - return 0;  
335 -}  
336 -  
337 -LIB3270_EXPORT int lib3270_select_field_at(H3270 *session, int baddr)  
338 -{  
339 - int start, end;  
340 -  
341 - if(lib3270_get_field_bounds(session,baddr,&start,&end))  
342 - return -1;  
343 -  
344 - do_select(session,start,end,0);  
345 -  
346 - return 0;  
347 -}  
348 -  
349 -LIB3270_EXPORT int lib3270_select_field(H3270 *hSession)  
350 -{  
351 - CHECK_SESSION_HANDLE(hSession);  
352 - lib3270_select_field_at(hSession,hSession->cursor_addr);  
353 - return 0;  
354 -}  
355 -  
356 -LIB3270_EXPORT int lib3270_select_all(H3270 * hSession)  
357 -{  
358 - FAIL_IF_NOT_ONLINE(hSession);  
359 -  
360 - do_select(hSession,0,(hSession->rows*hSession->cols)-1,0);  
361 -  
362 - return 0;  
363 -}  
364 -  
365 -LIB3270_EXPORT int lib3270_reselect(H3270 *hSession)  
366 -{  
367 - FAIL_IF_NOT_ONLINE(hSession);  
368 -  
369 - if(hSession->select.start == hSession->select.end || hSession->selected)  
370 - return 0;  
371 -  
372 - do_select(hSession, hSession->select.start,hSession->select.end,lib3270_get_toggle(hSession,LIB3270_TOGGLE_RECTANGLE_SELECT));  
373 -  
374 - return 0;  
375 -}  
376 -  
377 -static char * get_text(H3270 *hSession,unsigned char all, unsigned char tok)  
378 -{  
379 - int row, col, baddr;  
380 - char * ret;  
381 - size_t buflen = (hSession->rows * (hSession->cols+1))+1;  
382 - size_t sz = 0;  
383 - unsigned short attr = 0xFFFF;  
384 -  
385 - if(!(lib3270_connected(hSession) && hSession->text))  
386 - {  
387 - errno = ENOTCONN;  
388 - return NULL;  
389 - }  
390 -  
391 - ret = lib3270_malloc(buflen);  
392 -  
393 - baddr = 0;  
394 -  
395 - for(row=0;row < hSession->rows;row++)  
396 - {  
397 - int cr = 0;  
398 -  
399 - for(col = 0; col < hSession->cols;col++)  
400 - {  
401 - if(all || hSession->text[baddr].attr & LIB3270_ATTR_SELECTED)  
402 - {  
403 - if(tok && attr != hSession->text[baddr].attr)  
404 - {  
405 - attr = hSession->text[baddr].attr;  
406 - ret[sz++] = tok;  
407 - ret[sz++] = (attr & 0x0F);  
408 - ret[sz++] = ((attr & 0xF0) >> 4);  
409 - }  
410 -  
411 - cr++;  
412 - ret[sz++] = hSession->text[baddr].chr;  
413 - }  
414 - baddr++;  
415 - }  
416 -  
417 - if(cr)  
418 - ret[sz++] = '\n';  
419 -  
420 - if((sz+10) > buflen)  
421 - {  
422 - buflen += 100;  
423 - ret = lib3270_realloc(ret,buflen);  
424 - }  
425 - }  
426 -  
427 - if(!sz)  
428 - {  
429 - lib3270_free(ret);  
430 - errno = ENOENT;  
431 - return NULL;  
432 - }  
433 - else if(sz > 1 && ret[sz-1] == '\n') // Remove ending \n  
434 - {  
435 - ret[sz-1] = 0;  
436 - }  
437 -  
438 - ret[sz++] = 0;  
439 -  
440 - if(sz != buflen)  
441 - ret = lib3270_realloc(ret,sz);  
442 -  
443 - return ret;  
444 -}  
445 -  
446 -LIB3270_EXPORT char * lib3270_get_region(H3270 *h, int start_pos, int end_pos, unsigned char all)  
447 -{  
448 - char * text;  
449 - int maxlen;  
450 - int sz = 0;  
451 - int baddr;  
452 -  
453 - CHECK_SESSION_HANDLE(h);  
454 -  
455 - if(!lib3270_connected(h))  
456 - return NULL;  
457 -  
458 - maxlen = h->rows * (h->cols+1);  
459 -  
460 - if(start_pos < 0 || start_pos > maxlen || end_pos < 0 || end_pos > maxlen || end_pos < start_pos)  
461 - return NULL;  
462 -  
463 - text = lib3270_malloc(maxlen);  
464 -  
465 - for(baddr=start_pos;baddr<end_pos;baddr++)  
466 - {  
467 - if(all || h->text[baddr].attr & LIB3270_ATTR_SELECTED)  
468 - text[sz++] = (h->text[baddr].attr & LIB3270_ATTR_CG) ? ' ' : h->text[baddr].chr;  
469 -  
470 - if((baddr%h->cols) == 0 && sz > 0)  
471 - text[sz++] = '\n';  
472 - }  
473 - text[sz++] = 0;  
474 -  
475 - return lib3270_realloc(text,sz);  
476 -}  
477 -  
478 -LIB3270_EXPORT char * lib3270_get_string_at_address(H3270 *h, int offset, int len, char lf)  
479 -{  
480 - char * buffer;  
481 - int maxlen;  
482 - char * ptr;  
483 -  
484 - CHECK_SESSION_HANDLE(h);  
485 -  
486 - if(!lib3270_connected(h))  
487 - {  
488 - errno = ENOTCONN;  
489 - return NULL;  
490 - }  
491 -  
492 - maxlen = (h->rows * (h->cols+1)) - offset;  
493 - if(maxlen <= 0 || offset < 0)  
494 - {  
495 - errno = EINVAL;  
496 - return NULL;  
497 - }  
498 -  
499 - if(len < 0 || len > maxlen)  
500 - len = maxlen;  
501 -  
502 - buffer = lib3270_malloc(len+1);  
503 - ptr = buffer;  
504 -  
505 -// trace("len=%d buffer=%p",len,buffer);  
506 -  
507 - while(len > 0)  
508 - {  
509 - if(h->text[offset].attr & LIB3270_ATTR_CG)  
510 - *ptr = ' ';  
511 - else if(h->text[offset].chr)  
512 - *ptr = h->text[offset].chr;  
513 - else  
514 - *ptr = ' ';  
515 -  
516 - ptr++;  
517 - offset++;  
518 - len--;  
519 -  
520 - if(lf && (offset%h->cols) == 0 && len > 0)  
521 - {  
522 - *(ptr++) = lf;  
523 - len--;  
524 - }  
525 - }  
526 -// trace("len=%d buffer=%p pos=%d",len,buffer,ptr-buffer);  
527 -  
528 - *ptr = 0;  
529 -  
530 - return buffer;  
531 -}  
532 -  
533 -LIB3270_EXPORT char * lib3270_get_string_at(H3270 *h, int row, int col, int len, char lf)  
534 -{  
535 - CHECK_SESSION_HANDLE(h);  
536 - return lib3270_get_string_at_address(h, ((row-1) * h->cols) + (col-1), len, lf);  
537 -}  
538 -  
539 -LIB3270_EXPORT int lib3270_cmp_text_at(H3270 *h, int row, int col, const char *text, char lf)  
540 -{  
541 - int rc;  
542 - size_t sz = strlen(text);  
543 - char * contents;  
544 -  
545 - contents = lib3270_get_string_at(h,row,col,sz,lf);  
546 - if(!contents)  
547 - return -1;  
548 -  
549 - rc = strncmp(contents,text,sz);  
550 -  
551 - lib3270_free(contents);  
552 -  
553 - return rc;  
554 -}  
555 -  
556 -  
557 -/**  
558 - * Get field contents  
559 - *  
560 - * @param session Session handle  
561 - * @param baddr Field addr  
562 - *  
563 - * @return String with the field contents (release it with lib3270_free()  
564 - */  
565 -LIB3270_EXPORT char * lib3270_get_field_text_at(H3270 *session, int baddr)  
566 -{  
567 - int first = lib3270_field_addr(session,baddr);  
568 -  
569 - if(first < 0)  
570 - return NULL;  
571 -  
572 - return lib3270_get_string_at_address(session,first,lib3270_field_length(session,first)+1,0);  
573 -}  
574 -  
575 -LIB3270_EXPORT int lib3270_has_selection(H3270 *hSession)  
576 -{  
577 - CHECK_SESSION_HANDLE(hSession);  
578 - return hSession->selected != 0;  
579 -}  
580 -  
581 -LIB3270_EXPORT char * lib3270_get_selected(H3270 *hSession)  
582 -{  
583 - CHECK_SESSION_HANDLE(hSession);  
584 -  
585 - if(!hSession->selected || hSession->select.start == hSession->select.end)  
586 - return NULL;  
587 -  
588 - if(!lib3270_connected(hSession))  
589 - return NULL;  
590 -  
591 -  
592 - return get_text(hSession,0,0);  
593 -}  
594 -  
595 -static void copy_chr(H3270 *hSession, int from, int to)  
596 -{  
597 - if(hSession->text[from].chr == hSession->text[to].chr)  
598 - return;  
599 -  
600 - hSession->text[to].chr = hSession->text[from].chr;  
601 -  
602 - memcpy(&hSession->ea_buf[to], &hSession->ea_buf[from],sizeof(struct lib3270_ea));  
603 - hSession->ea_buf[from].fa = 0;  
604 -  
605 - hSession->cbk.update( hSession,  
606 - to,  
607 - hSession->text[to].chr,  
608 - hSession->text[to].attr,  
609 - to == hSession->cursor_addr );  
610 -}  
611 -  
612 -static void clear_chr(H3270 *hSession, int baddr)  
613 -{  
614 - hSession->text[baddr].chr = ' ';  
615 -  
616 - hSession->ea_buf[baddr].cc = EBC_null;  
617 - hSession->ea_buf[baddr].cs = 0;  
618 -  
619 - hSession->cbk.update( hSession,  
620 - baddr,  
621 - hSession->text[baddr].chr,  
622 - hSession->text[baddr].attr,  
623 - baddr == hSession->cursor_addr );  
624 -}  
625 -  
626 -int cut_addr(H3270 *hSession, int daddr, int saddr, int maxlen, int *sattr)  
627 -{  
628 - if(hSession->ea_buf[saddr].fa)  
629 - *sattr = hSession->ea_buf[saddr++].fa;  
630 -  
631 - if(FA_IS_PROTECTED(*sattr) || saddr >= maxlen)  
632 - clear_chr(hSession,daddr);  
633 - else  
634 - copy_chr(hSession,saddr++,daddr);  
635 -  
636 - return saddr;  
637 -}  
638 -  
639 -char * cut_text(H3270 *hSession, char tok)  
640 -{  
641 - unsigned short attr = 0xFFFF;  
642 -  
643 - CHECK_SESSION_HANDLE(hSession);  
644 -  
645 - if(!hSession->selected || hSession->select.start == hSession->select.end)  
646 - return NULL;  
647 -  
648 - if(!(lib3270_connected(hSession) && hSession->text))  
649 - return NULL;  
650 -  
651 - trace("Rectangle select is %s",lib3270_get_toggle(hSession,LIB3270_TOGGLE_RECTANGLE_SELECT) ? "Active" : "Inactive");  
652 -  
653 - if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_RECTANGLE_SELECT))  
654 - {  
655 - // Rectangle cut is not implemented  
656 - lib3270_popup_dialog(hSession, LIB3270_NOTIFY_INFO, _( "Not available" ), _( "Invalid cut action" ), "%s", _( "Can't cut rectangular regions") );  
657 - }  
658 - else  
659 - {  
660 - int end;  
661 - size_t szText;  
662 - size_t buflen;  
663 - size_t bufpos = 0;  
664 - int daddr; /* Destination addr */  
665 - int dattr; /* Destination addr attribute */  
666 - int saddr; /* Source addr (First field after the selected area) */  
667 - int sattr; /* Source addr attribute */  
668 - char *text;  
669 - size_t maxlen = hSession->rows * hSession->cols;  
670 - size_t f;  
671 -  
672 - get_selected_addr(hSession,&daddr,&end);  
673 -  
674 - lib3270_set_cursor_address(hSession,daddr);  
675 -  
676 - if(daddr >= end)  
677 - return NULL;  
678 -  
679 - dattr = lib3270_field_attribute(hSession,daddr); /* Get first attribute */  
680 -  
681 - szText = (end-daddr)+1;  
682 - buflen = szText;  
683 - bufpos = 0;  
684 -  
685 - text = lib3270_malloc(buflen+1);  
686 -  
687 - saddr = daddr+szText;  
688 - sattr = lib3270_field_attribute(hSession,saddr);  
689 -  
690 - for(f=0;f<szText;f++)  
691 - {  
692 - if(hSession->ea_buf[daddr].fa)  
693 - dattr = hSession->ea_buf[daddr].fa;  
694 -  
695 - if((bufpos+10) > buflen)  
696 - {  
697 - buflen += 100;  
698 - text = lib3270_realloc(text,buflen);  
699 - }  
700 -  
701 - if(tok && attr != hSession->text[daddr].attr)  
702 - {  
703 - attr = hSession->text[daddr].attr;  
704 - text[bufpos++] = tok;  
705 - text[bufpos++] = (attr & 0x0F);  
706 - text[bufpos++] = ((attr & 0xF0) >> 4);  
707 - }  
708 -  
709 - text[bufpos++] = hSession->text[daddr].chr;  
710 -  
711 - if(!FA_IS_PROTECTED(dattr))  
712 - saddr = cut_addr(hSession,daddr,saddr,maxlen,&sattr);  
713 -  
714 - daddr++;  
715 - }  
716 -  
717 - text[bufpos++] = 0;  
718 - text = lib3270_realloc(text,bufpos);  
719 -  
720 - // Move contents of the current field  
721 - while(daddr < (int) (maxlen-1) && !hSession->ea_buf[daddr].fa)  
722 - {  
723 - saddr = cut_addr(hSession,daddr,saddr,maxlen,&sattr);  
724 - daddr++;  
725 - }  
726 -  
727 - if(!hSession->ea_buf[daddr].fa)  
728 - clear_chr(hSession,daddr);  
729 -  
730 - hSession->cbk.changed(hSession,0,maxlen);  
731 -  
732 - lib3270_unselect(hSession);  
733 - return text;  
734 - }  
735 -  
736 - return NULL;  
737 -}  
738 -  
739 -LIB3270_EXPORT char * lib3270_cut_selected(H3270 *hSession)  
740 -{  
741 - return cut_text(hSession,0);  
742 -}  
743 -  
744 -LIB3270_EXPORT int lib3270_get_selection_bounds(H3270 *hSession, int *start, int *end)  
745 -{  
746 - int first, last;  
747 -  
748 - CHECK_SESSION_HANDLE(hSession);  
749 -  
750 - if(!hSession->selected || hSession->select.start == hSession->select.end)  
751 - return 0;  
752 -  
753 - if(hSession->select.end > hSession->select.start)  
754 - {  
755 - first = hSession->select.start;  
756 - last = hSession->select.end;  
757 - }  
758 - else  
759 - {  
760 - first = hSession->select.end;  
761 - last = hSession->select.start;  
762 - }  
763 -  
764 - if(start)  
765 - *start = first;  
766 -  
767 - if(end)  
768 - *end = last;  
769 -  
770 - return 1;  
771 -}  
772 -  
773 -LIB3270_EXPORT int lib3270_move_selected_area(H3270 *hSession, int from, int to)  
774 -{  
775 - int pos[2];  
776 - int rows, cols, f, step;  
777 -  
778 - if(from == to)  
779 - return from;  
780 -  
781 - if(!lib3270_get_selection_bounds(hSession,&pos[0],&pos[1]))  
782 - return from;  
783 -  
784 - rows = (to / hSession->cols) - (from / hSession->cols);  
785 - cols = (to % hSession->cols) - (from % hSession->cols);  
786 -  
787 - for(f=0;f<2;f++)  
788 - {  
789 - int row = (pos[f] / hSession->cols) + rows;  
790 - int col = (pos[f] % hSession->cols) + cols;  
791 -  
792 - if(row < 0)  
793 - rows = - (pos[f] / hSession->cols);  
794 -  
795 - if(col < 0)  
796 - cols = - (pos[f] % hSession->cols);  
797 -  
798 - if(row >= (hSession->rows))  
799 - rows = hSession->rows - ((pos[f] / hSession->cols)+1);  
800 -  
801 - if(col >= hSession->cols)  
802 - cols = hSession->cols - ((pos[f] % hSession->cols)+1);  
803 - }  
804 -  
805 - step = (rows * hSession->cols) + cols;  
806 -  
807 - do_select(hSession,hSession->select.start + step,hSession->select.end + step,hSession->rectsel);  
808 - cursor_move(hSession,hSession->select.end);  
809 -  
810 - return from+step;  
811 -}  
812 -  
813 -LIB3270_EXPORT int lib3270_drag_selection(H3270 *h, unsigned char flag, int origin, int baddr)  
814 -{  
815 - int first, last, row, col;  
816 -  
817 - if(!lib3270_get_selection_bounds(h,&first,&last))  
818 - return origin;  
819 -  
820 -/*  
821 - trace("%s: flag=%04x %s %s %s %s",__FUNCTION__,  
822 - flag,  
823 - flag & SELECTION_LEFT ? "Left" : "-",  
824 - flag & SELECTION_TOP ? "Top" : "-",  
825 - flag & SELECTION_RIGHT ? "Right" : "-",  
826 - flag & SELECTION_BOTTOM ? "Bottom" : "-"  
827 - );  
828 -*/  
829 -  
830 - if(!flag)  
831 - return origin;  
832 - else if((flag&0x8F) == SELECTION_ACTIVE)  
833 - return lib3270_move_selected_area(h,origin,baddr);  
834 -  
835 - row = baddr/h->cols;  
836 - col = baddr%h->cols;  
837 -  
838 - if(flag & SELECTION_LEFT) // Update left margin  
839 - origin = first = ((first/h->cols)*h->cols) + col;  
840 -  
841 - if(flag & SELECTION_TOP) // Update top margin  
842 - origin = first = (row*h->cols) + (first%h->cols);  
843 -  
844 - if(flag & SELECTION_RIGHT) // Update right margin  
845 - origin = last = ((last/h->cols)*h->cols) + col;  
846 -  
847 - if(flag & SELECTION_BOTTOM) // Update bottom margin  
848 - origin = last = (row*h->cols) + (last%h->cols);  
849 -  
850 - trace("origin=%d first=%d last=%d",origin,first,last);  
851 -  
852 - if(first < last)  
853 - do_select(h,first,last,h->rectsel);  
854 - else  
855 - do_select(h,last,first,h->rectsel);  
856 -  
857 - cursor_move(h,h->select.end);  
858 -  
859 - return origin;  
860 -}  
861 -  
862 -  
863 -LIB3270_EXPORT int lib3270_move_selection(H3270 *hSession, LIB3270_DIRECTION dir)  
864 -{  
865 - int start, end;  
866 -  
867 - if(!hSession->selected || hSession->select.start == hSession->select.end)  
868 - return ENOENT;  
869 -  
870 - start = hSession->select.start;  
871 - end = hSession->select.end;  
872 -  
873 - switch(dir)  
874 - {  
875 - case LIB3270_DIR_UP:  
876 - if(start <= hSession->cols)  
877 - return EINVAL;  
878 - start -= hSession->cols;  
879 - end -= hSession->cols;  
880 - break;  
881 -  
882 - case LIB3270_DIR_DOWN:  
883 - if(end >= (hSession->cols * (hSession->rows-1)))  
884 - return EINVAL;  
885 - start += hSession->cols;  
886 - end += hSession->cols;  
887 - break;  
888 -  
889 - case LIB3270_DIR_LEFT:  
890 - if( (start % hSession->cols) < 1)  
891 - return EINVAL;  
892 - start--;  
893 - end--;  
894 - break;  
895 -  
896 - case LIB3270_DIR_RIGHT:  
897 - if( (end % hSession->cols) >= (hSession->cols-1))  
898 - return EINVAL;  
899 - start++;  
900 - end++;  
901 - break;  
902 -  
903 - default:  
904 - return -1;  
905 - }  
906 -  
907 - do_select(hSession,start,end,hSession->rectsel);  
908 - cursor_move(hSession,hSession->select.end);  
909 -  
910 - return 0;  
911 -}  
912 -  
src/lib3270/selection/actions.c 0 → 100644
@@ -0,0 +1,328 @@ @@ -0,0 +1,328 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como selection.c e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 + #include "../private.h"
  31 + #include <lib3270.h>
  32 + #include <lib3270/actions.h>
  33 + #include <lib3270/session.h>
  34 + #include <lib3270/selection.h>
  35 + #include "3270ds.h"
  36 +
  37 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  38 +
  39 +LIB3270_EXPORT int lib3270_unselect(H3270 *hSession)
  40 +{
  41 + int a;
  42 +
  43 + CHECK_SESSION_HANDLE(hSession);
  44 +
  45 + trace("%s",__FUNCTION__);
  46 +
  47 + if(hSession->selected)
  48 + {
  49 + hSession->selected = 0;
  50 +
  51 + for(a = 0; a < hSession->rows*hSession->cols; a++)
  52 + {
  53 + if(hSession->text[a].attr & LIB3270_ATTR_SELECTED)
  54 + {
  55 + hSession->text[a].attr &= ~LIB3270_ATTR_SELECTED;
  56 + if(hSession->cbk.update)
  57 + hSession->cbk.update(hSession,a,hSession->text[a].chr,hSession->text[a].attr,a == hSession->cursor_addr);
  58 + }
  59 + }
  60 +
  61 + hSession->cbk.set_selection(hSession,0);
  62 + hSession->cbk.update_selection(hSession,-1,-1);
  63 + }
  64 +
  65 + return 0;
  66 +}
  67 +
  68 +LIB3270_EXPORT void lib3270_select_to(H3270 *session, int baddr)
  69 +{
  70 + int start, end;
  71 +
  72 + CHECK_SESSION_HANDLE(session);
  73 +
  74 + if(!lib3270_connected(session))
  75 + return;
  76 +
  77 + start = session->selected ? session->select.start : session->cursor_addr;
  78 +
  79 + cursor_move(session,end = baddr);
  80 +
  81 + do_select(session,start,end,lib3270_get_toggle(session,LIB3270_TOGGLE_RECTANGLE_SELECT));
  82 +
  83 +}
  84 +
  85 +LIB3270_EXPORT int lib3270_select_region(H3270 *h, int start, int end)
  86 +{
  87 + int maxlen;
  88 +
  89 + CHECK_SESSION_HANDLE(h);
  90 +
  91 + if(!lib3270_connected(h))
  92 + return ENOTCONN;
  93 +
  94 + maxlen = (h->rows * h->cols);
  95 +
  96 + // Check bounds
  97 + if(start < 0 || start > maxlen || end < 0 || end > maxlen || start > end)
  98 + return EINVAL;
  99 +
  100 + do_select(h,start,end,lib3270_get_toggle(h,LIB3270_TOGGLE_RECTANGLE_SELECT));
  101 + cursor_move(h,h->select.end);
  102 +
  103 + return 0;
  104 +}
  105 +
  106 +LIB3270_EXPORT int lib3270_select_word_at(H3270 *session, int baddr)
  107 +{
  108 + int start, end;
  109 +
  110 + if(lib3270_get_word_bounds(session,baddr,&start,&end))
  111 + return -1;
  112 +
  113 + trace("%s: baddr=%d start=%d end=%d",__FUNCTION__,baddr,start,end);
  114 +
  115 + do_select(session,start,end,0);
  116 +
  117 + return 0;
  118 +}
  119 +
  120 +LIB3270_EXPORT int lib3270_select_field_at(H3270 *session, int baddr)
  121 +{
  122 + int start, end;
  123 +
  124 + if(lib3270_get_field_bounds(session,baddr,&start,&end))
  125 + return -1;
  126 +
  127 + do_select(session,start,end,0);
  128 +
  129 + return 0;
  130 +}
  131 +
  132 +LIB3270_EXPORT int lib3270_select_field(H3270 *hSession)
  133 +{
  134 + CHECK_SESSION_HANDLE(hSession);
  135 + lib3270_select_field_at(hSession,hSession->cursor_addr);
  136 + return 0;
  137 +}
  138 +
  139 +LIB3270_EXPORT int lib3270_select_all(H3270 * hSession)
  140 +{
  141 + FAIL_IF_NOT_ONLINE(hSession);
  142 +
  143 + do_select(hSession,0,(hSession->rows*hSession->cols)-1,0);
  144 +
  145 + return 0;
  146 +}
  147 +
  148 +LIB3270_EXPORT int lib3270_reselect(H3270 *hSession)
  149 +{
  150 + FAIL_IF_NOT_ONLINE(hSession);
  151 +
  152 + if(hSession->select.start == hSession->select.end || hSession->selected)
  153 + return 0;
  154 +
  155 + do_select(hSession, hSession->select.start,hSession->select.end,lib3270_get_toggle(hSession,LIB3270_TOGGLE_RECTANGLE_SELECT));
  156 +
  157 + return 0;
  158 +}
  159 +
  160 +LIB3270_EXPORT int lib3270_get_selection_bounds(H3270 *hSession, int *start, int *end)
  161 +{
  162 + int first, last;
  163 +
  164 + CHECK_SESSION_HANDLE(hSession);
  165 +
  166 + if(!hSession->selected || hSession->select.start == hSession->select.end)
  167 + return 0;
  168 +
  169 + if(hSession->select.end > hSession->select.start)
  170 + {
  171 + first = hSession->select.start;
  172 + last = hSession->select.end;
  173 + }
  174 + else
  175 + {
  176 + first = hSession->select.end;
  177 + last = hSession->select.start;
  178 + }
  179 +
  180 + if(start)
  181 + *start = first;
  182 +
  183 + if(end)
  184 + *end = last;
  185 +
  186 + return 1;
  187 +}
  188 +
  189 +LIB3270_EXPORT int lib3270_move_selected_area(H3270 *hSession, int from, int to)
  190 +{
  191 + int pos[2];
  192 + int rows, cols, f, step;
  193 +
  194 + if(from == to)
  195 + return from;
  196 +
  197 + if(!lib3270_get_selection_bounds(hSession,&pos[0],&pos[1]))
  198 + return from;
  199 +
  200 + rows = (to / hSession->cols) - (from / hSession->cols);
  201 + cols = (to % hSession->cols) - (from % hSession->cols);
  202 +
  203 + for(f=0;f<2;f++)
  204 + {
  205 + int row = (pos[f] / hSession->cols) + rows;
  206 + int col = (pos[f] % hSession->cols) + cols;
  207 +
  208 + if(row < 0)
  209 + rows = - (pos[f] / hSession->cols);
  210 +
  211 + if(col < 0)
  212 + cols = - (pos[f] % hSession->cols);
  213 +
  214 + if(row >= (hSession->rows))
  215 + rows = hSession->rows - ((pos[f] / hSession->cols)+1);
  216 +
  217 + if(col >= hSession->cols)
  218 + cols = hSession->cols - ((pos[f] % hSession->cols)+1);
  219 + }
  220 +
  221 + step = (rows * hSession->cols) + cols;
  222 +
  223 + do_select(hSession,hSession->select.start + step,hSession->select.end + step,hSession->rectsel);
  224 + cursor_move(hSession,hSession->select.end);
  225 +
  226 + return from+step;
  227 +}
  228 +
  229 +LIB3270_EXPORT int lib3270_drag_selection(H3270 *h, unsigned char flag, int origin, int baddr)
  230 +{
  231 + int first, last, row, col;
  232 +
  233 + if(!lib3270_get_selection_bounds(h,&first,&last))
  234 + return origin;
  235 +
  236 +/*
  237 + trace("%s: flag=%04x %s %s %s %s",__FUNCTION__,
  238 + flag,
  239 + flag & SELECTION_LEFT ? "Left" : "-",
  240 + flag & SELECTION_TOP ? "Top" : "-",
  241 + flag & SELECTION_RIGHT ? "Right" : "-",
  242 + flag & SELECTION_BOTTOM ? "Bottom" : "-"
  243 + );
  244 +*/
  245 +
  246 + if(!flag)
  247 + return origin;
  248 + else if((flag&0x8F) == SELECTION_ACTIVE)
  249 + return lib3270_move_selected_area(h,origin,baddr);
  250 +
  251 + row = baddr/h->cols;
  252 + col = baddr%h->cols;
  253 +
  254 + if(flag & SELECTION_LEFT) // Update left margin
  255 + origin = first = ((first/h->cols)*h->cols) + col;
  256 +
  257 + if(flag & SELECTION_TOP) // Update top margin
  258 + origin = first = (row*h->cols) + (first%h->cols);
  259 +
  260 + if(flag & SELECTION_RIGHT) // Update right margin
  261 + origin = last = ((last/h->cols)*h->cols) + col;
  262 +
  263 + if(flag & SELECTION_BOTTOM) // Update bottom margin
  264 + origin = last = (row*h->cols) + (last%h->cols);
  265 +
  266 + trace("origin=%d first=%d last=%d",origin,first,last);
  267 +
  268 + if(first < last)
  269 + do_select(h,first,last,h->rectsel);
  270 + else
  271 + do_select(h,last,first,h->rectsel);
  272 +
  273 + cursor_move(h,h->select.end);
  274 +
  275 + return origin;
  276 +}
  277 +
  278 +LIB3270_EXPORT int lib3270_move_selection(H3270 *hSession, LIB3270_DIRECTION dir)
  279 +{
  280 + int start, end;
  281 +
  282 + if(!hSession->selected || hSession->select.start == hSession->select.end)
  283 + return ENOENT;
  284 +
  285 + start = hSession->select.start;
  286 + end = hSession->select.end;
  287 +
  288 + switch(dir)
  289 + {
  290 + case LIB3270_DIR_UP:
  291 + if(start <= hSession->cols)
  292 + return EINVAL;
  293 + start -= hSession->cols;
  294 + end -= hSession->cols;
  295 + break;
  296 +
  297 + case LIB3270_DIR_DOWN:
  298 + if(end >= (hSession->cols * (hSession->rows-1)))
  299 + return EINVAL;
  300 + start += hSession->cols;
  301 + end += hSession->cols;
  302 + break;
  303 +
  304 + case LIB3270_DIR_LEFT:
  305 + if( (start % hSession->cols) < 1)
  306 + return EINVAL;
  307 + start--;
  308 + end--;
  309 + break;
  310 +
  311 + case LIB3270_DIR_RIGHT:
  312 + if( (end % hSession->cols) >= (hSession->cols-1))
  313 + return EINVAL;
  314 + start++;
  315 + end++;
  316 + break;
  317 +
  318 + default:
  319 + return -1;
  320 + }
  321 +
  322 + do_select(hSession,start,end,hSession->rectsel);
  323 + cursor_move(hSession,hSession->select.end);
  324 +
  325 + return 0;
  326 +}
  327 +
  328 +
src/lib3270/selection/selection.c 0 → 100644
@@ -0,0 +1,610 @@ @@ -0,0 +1,610 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como selection.c e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 + #include "../private.h"
  31 + #include <lib3270.h>
  32 + #include <lib3270/actions.h>
  33 + #include <lib3270/session.h>
  34 + #include <lib3270/selection.h>
  35 + #include "3270ds.h"
  36 +
  37 + /*--[ Implement ]------------------------------------------------------------------------------------*/
  38 +
  39 +static void get_selected_addr(H3270 *session, int *start, int *end)
  40 +{
  41 + if(session->select.start > session->select.end)
  42 + {
  43 + *end = session->select.start;
  44 + *start = session->select.end;
  45 + }
  46 + else
  47 + {
  48 + *start = session->select.start;
  49 + *end = session->select.end;
  50 + }
  51 +}
  52 +
  53 +static void update_selected_rectangle(H3270 *session)
  54 +{
  55 + struct
  56 + {
  57 + int row;
  58 + int col;
  59 + } p[2];
  60 +
  61 +
  62 + int begin, end, row, col, baddr;
  63 +
  64 + get_selected_addr(session,&begin,&end);
  65 +
  66 + // Get start & end posision
  67 + p[0].row = (begin/session->cols);
  68 + p[0].col = (begin%session->cols);
  69 + p[1].row = (end/session->cols);
  70 + p[1].col = (end%session->cols);
  71 +
  72 + if(p[0].row > p[1].row)
  73 + {
  74 + int swp = p[0].row;
  75 + p[0].row = p[1].row;
  76 + p[1].row = swp;
  77 + }
  78 +
  79 + if(p[0].col > p[1].col)
  80 + {
  81 + int swp = p[0].col;
  82 + p[0].col = p[1].col;
  83 + p[1].col = swp;
  84 + }
  85 +
  86 + // First remove unselected areas
  87 + baddr = 0;
  88 + for(row=0;row < session->rows;row++)
  89 + {
  90 + for(col = 0; col < session->cols;col++)
  91 + {
  92 + if(!(row >= p[0].row && row <= p[1].row && col >= p[0].col && col <= p[1].col) && (session->text[baddr].attr & LIB3270_ATTR_SELECTED))
  93 + {
  94 + session->text[baddr].attr &= ~LIB3270_ATTR_SELECTED;
  95 + session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);
  96 + }
  97 + baddr++;
  98 + }
  99 + }
  100 +
  101 + // Then, draw selected ones
  102 + baddr = 0;
  103 + for(row=0;row < session->rows;row++)
  104 + {
  105 + for(col = 0; col < session->cols;col++)
  106 + {
  107 + if((row >= p[0].row && row <= p[1].row && col >= p[0].col && col <= p[1].col) && !(session->text[baddr].attr & LIB3270_ATTR_SELECTED))
  108 + {
  109 + session->text[baddr].attr |= LIB3270_ATTR_SELECTED;
  110 + session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);
  111 + }
  112 + baddr++;
  113 + }
  114 + }
  115 +
  116 +}
  117 +
  118 +static void update_selected_region(H3270 *session)
  119 +{
  120 + int baddr,begin,end;
  121 + int len = session->rows*session->cols;
  122 +
  123 + get_selected_addr(session,&begin,&end);
  124 +
  125 + // First remove unselected areas
  126 + for(baddr = 0; baddr < begin; baddr++)
  127 + {
  128 + if(session->text[baddr].attr & LIB3270_ATTR_SELECTED)
  129 + {
  130 + session->text[baddr].attr &= ~LIB3270_ATTR_SELECTED;
  131 + session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);
  132 + }
  133 + }
  134 +
  135 + for(baddr = end+1; baddr < len; baddr++)
  136 + {
  137 + if(session->text[baddr].attr & LIB3270_ATTR_SELECTED)
  138 + {
  139 + session->text[baddr].attr &= ~LIB3270_ATTR_SELECTED;
  140 + session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);
  141 + }
  142 + }
  143 +
  144 + // Then draw the selected ones
  145 + for(baddr = begin; baddr <= end; baddr++)
  146 + {
  147 + if(!(session->text[baddr].attr & LIB3270_ATTR_SELECTED))
  148 + {
  149 + session->text[baddr].attr |= LIB3270_ATTR_SELECTED;
  150 + session->cbk.update(session,baddr,session->text[baddr].chr,session->text[baddr].attr,baddr == session->cursor_addr);
  151 + }
  152 + }
  153 +
  154 +}
  155 +
  156 +void toggle_rectselect(H3270 *session, struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt))
  157 +{
  158 + if(!session->selected)
  159 + return;
  160 +
  161 + if(t->value)
  162 + update_selected_rectangle(session);
  163 + else
  164 + update_selected_region(session);
  165 +}
  166 +
  167 +void do_select(H3270 *h, int start, int end, int rect)
  168 +{
  169 + if(start < 0 || end > (h->rows * h->cols))
  170 + return;
  171 +
  172 + // Do we really need to change selection?
  173 + if(start == h->select.start && end == h->select.end && h->selected)
  174 + return;
  175 +
  176 + // Start address is inside the screen?
  177 + h->select.start = start;
  178 + h->select.end = end;
  179 +
  180 + if(rect)
  181 + {
  182 + h->rectsel = 1;
  183 + update_selected_rectangle(h);
  184 + }
  185 + else
  186 + {
  187 + h->rectsel = 0;
  188 + update_selected_region(h);
  189 + }
  190 +
  191 + if(!h->selected)
  192 + {
  193 + h->selected = 1;
  194 + h->cbk.set_selection(h,1);
  195 + }
  196 +
  197 + h->cbk.update_selection(h,start,end);
  198 +
  199 +}
  200 +
  201 +LIB3270_EXPORT unsigned char lib3270_get_selection_flags(H3270 *hSession, int baddr)
  202 +{
  203 + int row,col;
  204 + unsigned char rc = 0;
  205 +
  206 + CHECK_SESSION_HANDLE(hSession);
  207 +
  208 + if(!(lib3270_connected(hSession) && (hSession->text[baddr].attr & LIB3270_ATTR_SELECTED)))
  209 + return rc;
  210 +
  211 + row = baddr / hSession->cols;
  212 + col = baddr % hSession->cols;
  213 + rc |= SELECTION_ACTIVE;
  214 +
  215 + if( (hSession->select.start % hSession->cols) == (hSession->select.end % hSession->cols) )
  216 + {
  217 + rc |= SELECTION_SINGLE_COL;
  218 + }
  219 + else
  220 + {
  221 + if( (col == 0) || !(hSession->text[baddr-1].attr & LIB3270_ATTR_SELECTED) )
  222 + rc |= SELECTION_LEFT;
  223 +
  224 + if( (col == hSession->cols) || !(hSession->text[baddr+1].attr & LIB3270_ATTR_SELECTED) )
  225 + rc |= SELECTION_RIGHT;
  226 + }
  227 +
  228 + if( (hSession->select.start / hSession->cols) == (hSession->select.end / hSession->cols) )
  229 + {
  230 + rc |= SELECTION_SINGLE_ROW;
  231 + }
  232 + else
  233 + {
  234 + if( (row == 0) || !(hSession->text[baddr-hSession->cols].attr & LIB3270_ATTR_SELECTED) )
  235 + rc |= SELECTION_TOP;
  236 +
  237 + if( (row == hSession->rows) || !(hSession->text[baddr+hSession->cols].attr & LIB3270_ATTR_SELECTED) )
  238 + rc |= SELECTION_BOTTOM;
  239 + }
  240 +
  241 + return rc;
  242 +}
  243 +
  244 +static char * get_text(H3270 *hSession,unsigned char all, unsigned char tok)
  245 +{
  246 + int row, col, baddr;
  247 + char * ret;
  248 + size_t buflen = (hSession->rows * (hSession->cols+1))+1;
  249 + size_t sz = 0;
  250 + unsigned short attr = 0xFFFF;
  251 +
  252 + if(!(lib3270_connected(hSession) && hSession->text))
  253 + {
  254 + errno = ENOTCONN;
  255 + return NULL;
  256 + }
  257 +
  258 + ret = lib3270_malloc(buflen);
  259 +
  260 + baddr = 0;
  261 +
  262 + for(row=0;row < hSession->rows;row++)
  263 + {
  264 + int cr = 0;
  265 +
  266 + for(col = 0; col < hSession->cols;col++)
  267 + {
  268 + if(all || hSession->text[baddr].attr & LIB3270_ATTR_SELECTED)
  269 + {
  270 + if(tok && attr != hSession->text[baddr].attr)
  271 + {
  272 + attr = hSession->text[baddr].attr;
  273 + ret[sz++] = tok;
  274 + ret[sz++] = (attr & 0x0F);
  275 + ret[sz++] = ((attr & 0xF0) >> 4);
  276 + }
  277 +
  278 + cr++;
  279 + ret[sz++] = hSession->text[baddr].chr;
  280 + }
  281 + baddr++;
  282 + }
  283 +
  284 + if(cr)
  285 + ret[sz++] = '\n';
  286 +
  287 + if((sz+10) > buflen)
  288 + {
  289 + buflen += 100;
  290 + ret = lib3270_realloc(ret,buflen);
  291 + }
  292 + }
  293 +
  294 + if(!sz)
  295 + {
  296 + lib3270_free(ret);
  297 + errno = ENOENT;
  298 + return NULL;
  299 + }
  300 + else if(sz > 1 && ret[sz-1] == '\n') // Remove ending \n
  301 + {
  302 + ret[sz-1] = 0;
  303 + }
  304 +
  305 + ret[sz++] = 0;
  306 +
  307 + if(sz != buflen)
  308 + ret = lib3270_realloc(ret,sz);
  309 +
  310 + return ret;
  311 +}
  312 +
  313 +LIB3270_EXPORT char * lib3270_get_region(H3270 *h, int start_pos, int end_pos, unsigned char all)
  314 +{
  315 + char * text;
  316 + int maxlen;
  317 + int sz = 0;
  318 + int baddr;
  319 +
  320 + CHECK_SESSION_HANDLE(h);
  321 +
  322 + if(!lib3270_connected(h))
  323 + return NULL;
  324 +
  325 + maxlen = h->rows * (h->cols+1);
  326 +
  327 + if(start_pos < 0 || start_pos > maxlen || end_pos < 0 || end_pos > maxlen || end_pos < start_pos)
  328 + return NULL;
  329 +
  330 + text = lib3270_malloc(maxlen);
  331 +
  332 + for(baddr=start_pos;baddr<end_pos;baddr++)
  333 + {
  334 + if(all || h->text[baddr].attr & LIB3270_ATTR_SELECTED)
  335 + text[sz++] = (h->text[baddr].attr & LIB3270_ATTR_CG) ? ' ' : h->text[baddr].chr;
  336 +
  337 + if((baddr%h->cols) == 0 && sz > 0)
  338 + text[sz++] = '\n';
  339 + }
  340 + text[sz++] = 0;
  341 +
  342 + return lib3270_realloc(text,sz);
  343 +}
  344 +
  345 +LIB3270_EXPORT char * lib3270_get_string_at_address(H3270 *h, int offset, int len, char lf)
  346 +{
  347 + char * buffer;
  348 + int maxlen;
  349 + char * ptr;
  350 +
  351 + CHECK_SESSION_HANDLE(h);
  352 +
  353 + if(!lib3270_connected(h))
  354 + {
  355 + errno = ENOTCONN;
  356 + return NULL;
  357 + }
  358 +
  359 + maxlen = (h->rows * (h->cols+1)) - offset;
  360 + if(maxlen <= 0 || offset < 0)
  361 + {
  362 + errno = EINVAL;
  363 + return NULL;
  364 + }
  365 +
  366 + if(len < 0 || len > maxlen)
  367 + len = maxlen;
  368 +
  369 + buffer = lib3270_malloc(len+1);
  370 + ptr = buffer;
  371 +
  372 +// trace("len=%d buffer=%p",len,buffer);
  373 +
  374 + while(len > 0)
  375 + {
  376 + if(h->text[offset].attr & LIB3270_ATTR_CG)
  377 + *ptr = ' ';
  378 + else if(h->text[offset].chr)
  379 + *ptr = h->text[offset].chr;
  380 + else
  381 + *ptr = ' ';
  382 +
  383 + ptr++;
  384 + offset++;
  385 + len--;
  386 +
  387 + if(lf && (offset%h->cols) == 0 && len > 0)
  388 + {
  389 + *(ptr++) = lf;
  390 + len--;
  391 + }
  392 + }
  393 +// trace("len=%d buffer=%p pos=%d",len,buffer,ptr-buffer);
  394 +
  395 + *ptr = 0;
  396 +
  397 + return buffer;
  398 +}
  399 +
  400 +LIB3270_EXPORT char * lib3270_get_string_at(H3270 *h, int row, int col, int len, char lf)
  401 +{
  402 + CHECK_SESSION_HANDLE(h);
  403 + return lib3270_get_string_at_address(h, ((row-1) * h->cols) + (col-1), len, lf);
  404 +}
  405 +
  406 +LIB3270_EXPORT int lib3270_cmp_text_at(H3270 *h, int row, int col, const char *text, char lf)
  407 +{
  408 + int rc;
  409 + size_t sz = strlen(text);
  410 + char * contents;
  411 +
  412 + contents = lib3270_get_string_at(h,row,col,sz,lf);
  413 + if(!contents)
  414 + return -1;
  415 +
  416 + rc = strncmp(contents,text,sz);
  417 +
  418 + lib3270_free(contents);
  419 +
  420 + return rc;
  421 +}
  422 +
  423 +
  424 +/**
  425 + * Get field contents
  426 + *
  427 + * @param session Session handle
  428 + * @param baddr Field addr
  429 + *
  430 + * @return String with the field contents (release it with lib3270_free()
  431 + */
  432 +LIB3270_EXPORT char * lib3270_get_field_text_at(H3270 *session, int baddr)
  433 +{
  434 + int first = lib3270_field_addr(session,baddr);
  435 +
  436 + if(first < 0)
  437 + return NULL;
  438 +
  439 + return lib3270_get_string_at_address(session,first,lib3270_field_length(session,first)+1,0);
  440 +}
  441 +
  442 +LIB3270_EXPORT int lib3270_has_selection(H3270 *hSession)
  443 +{
  444 + CHECK_SESSION_HANDLE(hSession);
  445 + return hSession->selected != 0;
  446 +}
  447 +
  448 +LIB3270_EXPORT char * lib3270_get_selected(H3270 *hSession)
  449 +{
  450 + CHECK_SESSION_HANDLE(hSession);
  451 +
  452 + if(!hSession->selected || hSession->select.start == hSession->select.end)
  453 + return NULL;
  454 +
  455 + if(!lib3270_connected(hSession))
  456 + return NULL;
  457 +
  458 +
  459 + return get_text(hSession,0,0);
  460 +}
  461 +
  462 +static void copy_chr(H3270 *hSession, int from, int to)
  463 +{
  464 + if(hSession->text[from].chr == hSession->text[to].chr)
  465 + return;
  466 +
  467 + hSession->text[to].chr = hSession->text[from].chr;
  468 +
  469 + memcpy(&hSession->ea_buf[to], &hSession->ea_buf[from],sizeof(struct lib3270_ea));
  470 + hSession->ea_buf[from].fa = 0;
  471 +
  472 + hSession->cbk.update( hSession,
  473 + to,
  474 + hSession->text[to].chr,
  475 + hSession->text[to].attr,
  476 + to == hSession->cursor_addr );
  477 +}
  478 +
  479 +static void clear_chr(H3270 *hSession, int baddr)
  480 +{
  481 + hSession->text[baddr].chr = ' ';
  482 +
  483 + hSession->ea_buf[baddr].cc = EBC_null;
  484 + hSession->ea_buf[baddr].cs = 0;
  485 +
  486 + hSession->cbk.update( hSession,
  487 + baddr,
  488 + hSession->text[baddr].chr,
  489 + hSession->text[baddr].attr,
  490 + baddr == hSession->cursor_addr );
  491 +}
  492 +
  493 +int cut_addr(H3270 *hSession, int daddr, int saddr, int maxlen, int *sattr)
  494 +{
  495 + if(hSession->ea_buf[saddr].fa)
  496 + *sattr = hSession->ea_buf[saddr++].fa;
  497 +
  498 + if(FA_IS_PROTECTED(*sattr) || saddr >= maxlen)
  499 + clear_chr(hSession,daddr);
  500 + else
  501 + copy_chr(hSession,saddr++,daddr);
  502 +
  503 + return saddr;
  504 +}
  505 +
  506 +char * cut_text(H3270 *hSession, char tok)
  507 +{
  508 + unsigned short attr = 0xFFFF;
  509 +
  510 + CHECK_SESSION_HANDLE(hSession);
  511 +
  512 + if(!hSession->selected || hSession->select.start == hSession->select.end)
  513 + return NULL;
  514 +
  515 + if(!(lib3270_connected(hSession) && hSession->text))
  516 + return NULL;
  517 +
  518 + trace("Rectangle select is %s",lib3270_get_toggle(hSession,LIB3270_TOGGLE_RECTANGLE_SELECT) ? "Active" : "Inactive");
  519 +
  520 + if(lib3270_get_toggle(hSession,LIB3270_TOGGLE_RECTANGLE_SELECT))
  521 + {
  522 + // Rectangle cut is not implemented
  523 + lib3270_popup_dialog(hSession, LIB3270_NOTIFY_INFO, _( "Not available" ), _( "Invalid cut action" ), "%s", _( "Can't cut rectangular regions") );
  524 + }
  525 + else
  526 + {
  527 + int end;
  528 + size_t szText;
  529 + size_t buflen;
  530 + size_t bufpos = 0;
  531 + int daddr; /* Destination addr */
  532 + int dattr; /* Destination addr attribute */
  533 + int saddr; /* Source addr (First field after the selected area) */
  534 + int sattr; /* Source addr attribute */
  535 + char *text;
  536 + size_t maxlen = hSession->rows * hSession->cols;
  537 + size_t f;
  538 +
  539 + get_selected_addr(hSession,&daddr,&end);
  540 +
  541 + lib3270_set_cursor_address(hSession,daddr);
  542 +
  543 + if(daddr >= end)
  544 + return NULL;
  545 +
  546 + dattr = lib3270_field_attribute(hSession,daddr); /* Get first attribute */
  547 +
  548 + szText = (end-daddr)+1;
  549 + buflen = szText;
  550 + bufpos = 0;
  551 +
  552 + text = lib3270_malloc(buflen+1);
  553 +
  554 + saddr = daddr+szText;
  555 + sattr = lib3270_field_attribute(hSession,saddr);
  556 +
  557 + for(f=0;f<szText;f++)
  558 + {
  559 + if(hSession->ea_buf[daddr].fa)
  560 + dattr = hSession->ea_buf[daddr].fa;
  561 +
  562 + if((bufpos+10) > buflen)
  563 + {
  564 + buflen += 100;
  565 + text = lib3270_realloc(text,buflen);
  566 + }
  567 +
  568 + if(tok && attr != hSession->text[daddr].attr)
  569 + {
  570 + attr = hSession->text[daddr].attr;
  571 + text[bufpos++] = tok;
  572 + text[bufpos++] = (attr & 0x0F);
  573 + text[bufpos++] = ((attr & 0xF0) >> 4);
  574 + }
  575 +
  576 + text[bufpos++] = hSession->text[daddr].chr;
  577 +
  578 + if(!FA_IS_PROTECTED(dattr))
  579 + saddr = cut_addr(hSession,daddr,saddr,maxlen,&sattr);
  580 +
  581 + daddr++;
  582 + }
  583 +
  584 + text[bufpos++] = 0;
  585 + text = lib3270_realloc(text,bufpos);
  586 +
  587 + // Move contents of the current field
  588 + while(daddr < (int) (maxlen-1) && !hSession->ea_buf[daddr].fa)
  589 + {
  590 + saddr = cut_addr(hSession,daddr,saddr,maxlen,&sattr);
  591 + daddr++;
  592 + }
  593 +
  594 + if(!hSession->ea_buf[daddr].fa)
  595 + clear_chr(hSession,daddr);
  596 +
  597 + hSession->cbk.changed(hSession,0,maxlen);
  598 +
  599 + lib3270_unselect(hSession);
  600 + return text;
  601 + }
  602 +
  603 + return NULL;
  604 +}
  605 +
  606 +LIB3270_EXPORT char * lib3270_cut_selected(H3270 *hSession)
  607 +{
  608 + return cut_text(hSession,0);
  609 +}
  610 +
src/lib3270/valgrind.suppression
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +{
  2 + libcrypt_FIPS_selftest
  3 + Memcheck:Cond
  4 + ...
  5 + fun:FIPS_selftest
  6 +}
  7 +
  8 +{
  9 + libcrypt_FIPS_mode_set
  10 + Memcheck:Cond
  11 + ...
  12 + fun:FIPS_mode_set
  13 +}
  14 +