Commit d0ffcc126997aa09e5d6ec81781567a998fd4ba1

Authored by Perry Werneck
1 parent 48e7d682

Reorganizing and isolating clipboard management code.

lib3270.cbp
... ... @@ -217,7 +217,10 @@
217 217 <Unit filename="src/lib3270/see.c">
218 218 <Option compilerVar="CC" />
219 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 224 <Option compilerVar="CC" />
222 225 </Unit>
223 226 <Unit filename="src/lib3270/session.c">
... ...
src/lib3270/Makefile.in
... ... @@ -30,6 +30,7 @@ LIBNAME=lib@LIB3270_NAME@
30 30  
31 31 SOURCES= \
32 32 $(wildcard *.c) \
  33 + $(wildcard selection/*.c) \
33 34 $(wildcard @OSNAME@/*.c) \
34 35 $(wildcard ssl/*.c) \
35 36 $(wildcard ssl/@OSNAME@/*.c) \
... ...
src/lib3270/private.h
... ... @@ -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 661 /* Library internal calls */
652 662 LIB3270_INTERNAL void key_ACharacter(H3270 *hSession, unsigned char c, enum keytype keytype, enum iaction cause,Boolean *skipped);
653 663 LIB3270_INTERNAL int cursor_move(H3270 *session, int baddr);
... ... @@ -660,6 +670,9 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession);
660 670  
661 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 677 * @brief Called from timer to attempt an automatic reconnection.
665 678 */
... ...
src/lib3270/selection.c
... ... @@ -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 @@
  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 @@
  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 @@
  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 +
... ...