Commit 8387aa748f058d45da280acd0e0a1f8deb9f5ac8

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

Implementando suporte atk

src/gtk/v3270/accessible.c
... ... @@ -37,6 +37,7 @@
37 37 #include <glib/gi18n.h>
38 38  
39 39 #include <pw3270.h>
  40 + #include <malloc.h>
40 41 #include "v3270.h"
41 42 #include "private.h"
42 43 #include "accessible.h"
... ... @@ -47,6 +48,7 @@
47 48 // http://git.gnome.org/browse/gtk+/tree/gtk/a11y/gtkentryaccessible.c
48 49 //
49 50  
  51 +
50 52 /*--[ Prototipes ]-----------------------------------------------------------------------------------*/
51 53  
52 54 static void atk_component_interface_init (AtkComponentIface *iface);
... ... @@ -69,13 +71,6 @@ G_DEFINE_TYPE_WITH_CODE (v3270Accessible, v3270_accessible, GTK_TYPE_ACCESSIBLE,
69 71  
70 72 /*--[ Implement ]------------------------------------------------------------------------------------*/
71 73  
72   -/*
73   -static const gchar * v3270_accessible_get_description(AtkObject *accessible)
74   -{
75   - return _( "3270 screen" );
76   -}
77   -*/
78   -
79 74 static void v3270_accessible_class_init(v3270AccessibleClass *klass)
80 75 {
81 76 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
... ... @@ -113,14 +108,42 @@ static void atk_component_interface_init(AtkComponentIface *iface)
113 108  
114 109 static gunichar v3270_accessible_get_character_at_offset(AtkText *atk_text, gint offset)
115 110 {
116   - GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text));
  111 + GtkWidget * widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text));
  112 +
  113 + if(widget == NULL)
  114 + {
  115 + H3270 * host = v3270_get_session(widget);
  116 + gchar * text = lib3270_get_text(host,offset,1);
117 117  
118   - trace("*********** %s %p",__FUNCTION__,widget);
  118 + if(text)
  119 + {
  120 + gunichar unichar;
  121 + gsize bytes_written;
  122 + GError * error = NULL;
  123 + gchar * utfstring = g_convert_with_fallback( text,
  124 + -1,
  125 + "UTF-8",
  126 + lib3270_get_charset(host),
  127 + " ",
  128 + NULL,
  129 + &bytes_written,
  130 + &error );
  131 +
  132 + if(error)
  133 + {
  134 + g_warning("%s failed: %s",__FUNCTION__,error->message);
  135 + g_error_free(error);
  136 + }
  137 + unichar = *utfstring;
  138 +
  139 + g_free(utfstring);
  140 +
  141 + return unichar;
  142 + }
119 143  
120   - if (widget == NULL)
121   - return '\0';
  144 + }
122 145  
123   - return 'X';
  146 + return '\0';
124 147 }
125 148  
126 149 static gint v3270_accessible_get_caret_offset(AtkText *text)
... ... @@ -138,8 +161,6 @@ static gint v3270_accessible_get_character_count(AtkText *text)
138 161 int rows,cols;
139 162 GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE(text));
140 163  
141   - trace("*********** %s %p len=%d",__FUNCTION__,widget,lib3270_get_length(GTK_V3270(widget)->host));
142   -
143 164 if(!widget)
144 165 return 0;
145 166  
... ... @@ -150,7 +171,7 @@ static gint v3270_accessible_get_offset_at_point(AtkText *atk_text, gint x, gint
150 171 {
151 172 GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text));
152 173  
153   - trace("*********** %s %p",__FUNCTION__,widget);
  174 + g_warning("Call to incomplete function \"%s\"",__FUNCTION__);
154 175  
155 176 if(!widget)
156 177 return -1;
... ... @@ -164,9 +185,7 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse
164 185 GtkWidget * widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text));
165 186 H3270 * host;
166 187 char * text;
167   - int rows,cols,first;
168   -
169   - trace("*********** %s %p offset=%d",__FUNCTION__,widget,offset);
  188 + int rows,cols,pos;
170 189  
171 190 if(!widget)
172 191 return NULL;
... ... @@ -203,10 +222,10 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse
203 222  
204 223 case ATK_TEXT_BOUNDARY_LINE_START: // Boundary is the initial character of the content or a character immediately following a newline,
205 224 // linefeed, or return character.
206   - first = (offset/cols)*cols;
207   - if(first == offset)
  225 + pos = (offset/cols)*cols;
  226 + if(pos == offset)
208 227 offset++;
209   - text = lib3270_get_text(host,first,(offset-first));
  228 + text = lib3270_get_text(host,pos,(offset-pos));
210 229 break;
211 230  
212 231  
... ... @@ -234,6 +253,8 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse
234 253 g_warning("%s failed: %s",__FUNCTION__,error->message);
235 254 g_error_free(error);
236 255 }
  256 +
  257 + free(text);
237 258 return utfchar;
238 259 }
239 260  
... ...
src/gtk/v3270/genmarshal
... ... @@ -8,3 +8,4 @@ VOID:VOID,UINT,POINTER
8 8 BOOL:VOID,UINT,ENUM
9 9 VOID:VOID,BOOL
10 10 BOOL:VOID,BOOL,BOOL,POINTER
  11 +VOID:VOID,UINT,UINT
... ...
src/gtk/v3270/private.h
... ... @@ -78,6 +78,7 @@ G_BEGIN_DECLS
78 78 SIGNAL_POPUP,
79 79 SIGNAL_PASTENEXT,
80 80 SIGNAL_CLIPBOARD,
  81 + SIGNAL_CHANGED,
81 82  
82 83 LAST_SIGNAL
83 84 };
... ...
src/gtk/v3270/widget.c
... ... @@ -33,6 +33,7 @@
33 33 #include <lib3270/session.h>
34 34 #include <lib3270/actions.h>
35 35 #include <lib3270/log.h>
  36 + #include <malloc.h>
36 37 #include "v3270.h"
37 38 #include "private.h"
38 39 #include "accessible.h"
... ... @@ -437,6 +438,15 @@ static void v3270_class_init(v3270Class *klass)
437 438 pw3270_VOID__VOID_BOOL,
438 439 G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
439 440  
  441 + v3270_widget_signal[SIGNAL_CHANGED] =
  442 + g_signal_new( "changed",
  443 + G_OBJECT_CLASS_TYPE (gobject_class),
  444 + G_SIGNAL_RUN_FIRST,
  445 + 0,
  446 + NULL, NULL,
  447 + pw3270_VOID__VOID_UINT_UINT,
  448 + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
  449 +
440 450 }
441 451  
442 452 void v3270_update_font_metrics(v3270 *terminal, cairo_t *cr, int width, int height)
... ... @@ -541,11 +551,6 @@ static void set_timer(H3270 *session, unsigned char on)
541 551  
542 552 }
543 553  
544   -static void changed(H3270 *session, int bstart, int bend)
545   -{
546   -// gtk_widget_queue_draw(GTK_WIDGET(session->widget));
547   -}
548   -
549 554 static void update_toggle(H3270 *session, LIB3270_TOGGLE ix, unsigned char value, LIB3270_TOGGLE_TYPE reason, const char *name)
550 555 {
551 556 g_signal_emit(GTK_WIDGET(session->widget), v3270_widget_signal[SIGNAL_TOGGLE_CHANGED], 0, (guint) ix, (gboolean) (value != 0), (gchar *) name);
... ... @@ -607,6 +612,51 @@ static void set_selection(H3270 *session, unsigned char status)
607 612 g_signal_emit(GTK_WIDGET(session->widget),v3270_widget_signal[SIGNAL_SELECTING], 0, status ? TRUE : FALSE);
608 613 }
609 614  
  615 +static void changed(H3270 *session, int offset, int len)
  616 +{
  617 + GtkWidget * widget = session->widget;
  618 + AtkObject * obj = gtk_widget_get_accessible(widget);
  619 +
  620 + trace("%s: offset=%d len=%d",__FUNCTION__,offset,len)
  621 +
  622 +// if(obj)
  623 + {
  624 + // Get new text, notify atk
  625 + gsize bytes_written;
  626 + char * text = lib3270_get_text(session,offset,len);
  627 +
  628 + if(text)
  629 + {
  630 + GError * error = NULL;
  631 + gchar * utfchar = g_convert_with_fallback( text,
  632 + -1,
  633 + "UTF-8",
  634 + lib3270_get_charset(session),
  635 + " ",
  636 + NULL,
  637 + &bytes_written,
  638 + &error );
  639 +
  640 + free(text);
  641 +
  642 + if(error)
  643 + {
  644 + g_warning("%s failed: %s",__FUNCTION__,error->message);
  645 + g_error_free(error);
  646 + }
  647 + else
  648 + {
  649 + // g_signal_emit_by_name(obj, "text-insert", offset,len,utfchar);
  650 + g_free(utfchar);
  651 + }
  652 +
  653 + }
  654 + }
  655 +
  656 + g_signal_emit(GTK_WIDGET(widget),v3270_widget_signal[SIGNAL_CHANGED], 0, (guint) offset, (guint) len);
  657 +
  658 +}
  659 +
610 660 static void v3270_init(v3270 *widget)
611 661 {
612 662 trace("%s",__FUNCTION__);
... ... @@ -634,6 +684,7 @@ static void v3270_init(v3270 *widget)
634 684 widget->host->cursor = select_cursor;
635 685 widget->host->update_connect = update_connect;
636 686 widget->host->update_model = update_model;
  687 + widget->host->changed = changed;
637 688  
638 689 // Setup input method
639 690 widget->input_method = gtk_im_multicontext_new();
... ... @@ -1060,13 +1111,22 @@ int v3270_connect(GtkWidget *widget, const gchar *host)
1060 1111 return rc;
1061 1112 }
1062 1113  
  1114 +static gboolean notify_focus(GtkWidget *widget, GdkEventFocus *event)
  1115 +{
  1116 + AtkObject *obj = gtk_widget_get_accessible (widget);
  1117 +
  1118 + if(obj)
  1119 + g_signal_emit_by_name (obj, "focus-event", event->in);
  1120 +
  1121 + return FALSE;
  1122 +}
1063 1123 gboolean v3270_focus_in_event(GtkWidget *widget, GdkEventFocus *event)
1064 1124 {
1065 1125 v3270 * terminal = GTK_V3270(widget);
1066 1126  
1067 1127 gtk_im_context_focus_in(terminal->input_method);
1068 1128  
1069   - return 0;
  1129 + return notify_focus(widget,event);
1070 1130 }
1071 1131  
1072 1132 gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event)
... ... @@ -1075,7 +1135,7 @@ gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event)
1075 1135  
1076 1136 gtk_im_context_focus_out(terminal->input_method);
1077 1137  
1078   - return 0;
  1138 + return notify_focus(widget,event);
1079 1139 }
1080 1140  
1081 1141 static void v3270_activate(GtkWidget *widget)
... ...
src/include/lib3270/session.h
... ... @@ -156,7 +156,7 @@
156 156 // Session based callbacks
157 157 void (*configure)(H3270 *session, unsigned short rows, unsigned short cols);
158 158 void (*update)(H3270 *session, int baddr, unsigned char c, unsigned short attr, unsigned char cursor);
159   - void (*changed)(H3270 *session, int bstart, int bend);
  159 + void (*changed)(H3270 *session, int offset, int len);
160 160  
161 161 void (*update_cursor)(H3270 *session, unsigned short row, unsigned short col, unsigned char c, unsigned short attr);
162 162 void (*update_oia)(H3270 *session, LIB3270_FLAG id, unsigned char on);
... ...
src/lib3270/api.h
... ... @@ -303,10 +303,10 @@
303 303 #define COLOR_ATTR_UNDERLINE LIB3270_ATTR_UNDERLINE
304 304 #define COLOR_ATTR_INTENSIFY LIB3270_ATTR_INTENSIFY
305 305  
306   - #define CHAR_ATTR_CG LIB3270_ATTR_CG
  306 +// #define CHAR_ATTR_CG LIB3270_ATTR_CG
307 307 #define CHAR_ATTR_MARKER LIB3270_ATTR_MARKER
308 308  
309   - #define CHAR_ATTR_UNCONVERTED CHAR_ATTR_CG
  309 + #define CHAR_ATTR_UNCONVERTED LIB3270_ATTR_CG
310 310  
311 311 struct lib3270_option
312 312 {
... ...
src/lib3270/host.c
... ... @@ -476,13 +476,11 @@ static int do_connect(H3270 *hSession, const char *n)
476 476 char nb[2048]; /* name buffer */
477 477 char *s; /* temporary */
478 478 const char *chost; /* to whom we will connect */
479   -// char *target_name;
480 479 char *ps = CN;
481 480 char *port = CN;
482 481 Boolean resolving;
483 482 Boolean pending;
484 483 static Boolean ansi_host;
485   -// const char *localprocess_cmd = NULL;
486 484 Boolean has_colons = False;
487 485  
488 486 if (lib3270_connected(hSession) || hSession->auto_reconnect_inprogress)
... ... @@ -499,7 +497,7 @@ static int do_connect(H3270 *hSession, const char *n)
499 497 }
500 498  
501 499 /* Save in a modifiable buffer. */
502   - (void) strcpy(nb, n);
  500 + (void) strncpy(nb, n, 2047);
503 501  
504 502 /* Strip trailing blanks. */
505 503 s = nb + strlen(nb) - 1;
... ... @@ -509,14 +507,6 @@ static int do_connect(H3270 *hSession, const char *n)
509 507 /* Remember this hostname, as the last hostname we connected to. */
510 508 lib3270_set_host(hSession,nb);
511 509  
512   -/*
513   -#if defined(LOCAL_PROCESS)
514   - if ((localprocess_cmd = parse_localprocess(nb)) != CN) {
515   - chost = localprocess_cmd;
516   - port = appres.port;
517   - } else
518   -#endif
519   -*/
520 510 {
521 511 Boolean needed;
522 512  
... ... @@ -541,23 +531,8 @@ static int do_connect(H3270 *hSession, const char *n)
541 531 * and port number
542 532 * full_current_host is the entire string, for use in reconnecting
543 533 */
544   - if (n != hSession->full_current_host)
545   - lib3270_set_host(hSession,n);
546   -
547 534 Replace(hSession->current_host, CN);
548 535  
549   -/*
550   -
551   - if (localprocess_cmd != CN) {
552   - if (hSession->full_current_host[strlen(OptLocalProcess)] != '\0')
553   - hSession->current_host = NewString(hSession->full_current_host + strlen(OptLocalProcess) + 1);
554   - else
555   - hSession->current_host = NewString("default shell");
556   - } else {
557   - hSession->current_host = s;
558   - }
559   -*/
560   -
561 536 has_colons = (strchr(chost, ':') != NULL);
562 537  
563 538 Replace(hSession->qualified_host,
... ... @@ -780,13 +755,18 @@ LIB3270_EXPORT const char * lib3270_set_host(H3270 *h, const char *n)
780 755  
781 756 Trace("%s: %p",__FUNCTION__,n);
782 757  
783   - if(!n)
784   - return NULL;
  758 + if(n && n != h->full_current_host)
  759 + {
  760 + char *new_hostname = strdup(n);
  761 +
  762 + trace("new hostname is \"%s\"",new_hostname);
785 763  
786   - if(h->full_current_host)
787   - free(h->full_current_host);
  764 + if(h->full_current_host)
  765 + free(h->full_current_host);
788 766  
789   - h->full_current_host = strdup(n);
  767 + h->full_current_host = new_hostname;
  768 +
  769 + }
790 770  
791 771 return h->full_current_host;
792 772 }
... ...
src/lib3270/screen.c
... ... @@ -72,6 +72,8 @@
72 72 #define get_color_pair(fg,bg) (((bg&0x0F) << 4) | (fg&0x0F))
73 73 #define DEFCOLOR_MAP(f) ((((f) & FA_PROTECT) >> 4) | (((f) & FA_INT_HIGH_SEL) >> 3))
74 74  
  75 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  76 +
75 77 static int logpopup(H3270 *session, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg);
76 78  
77 79 static int (*popup_handler)(H3270 *, LIB3270_NOTIFY, const char *, const char *, const char *, va_list) = logpopup;
... ... @@ -84,14 +86,20 @@ static void status_3270_mode(H3270 *session, int ignored, void *dunno);
84 86 static void status_printer(H3270 *session, int on, void *dunno);
85 87 static unsigned short color_from_fa(unsigned char fa);
86 88  
87   -static void addch(H3270 *session, int baddr, unsigned char c, unsigned short attr)
  89 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  90 +
  91 +static void addch(H3270 *session, int baddr, unsigned char c, unsigned short attr, int *first, int *last)
88 92 {
89 93 // If set to keep selection adjust corresponding flag based on the current state
90 94 if(lib3270_get_toggle(session,LIB3270_TOGGLE_KEEP_SELECTED))
91 95 attr |= (session->text[baddr].attr & LIB3270_ATTR_SELECTED);
92 96  
93 97 if(session->text[baddr].chr == c && session->text[baddr].attr == attr)
94   - return;
  98 + return;
  99 +
  100 + if(*first < 0)
  101 + *first = baddr;
  102 + *last = baddr;
95 103  
96 104 /* Converted char has changed, update it */
97 105 session->text[baddr].chr = c;
... ... @@ -275,11 +283,13 @@ LIB3270_EXPORT int lib3270_get_contents(H3270 *h, int first, int last, unsigned
275 283 /* Display what's in the buffer. */
276 284 static void screen_update(H3270 *session, int bstart, int bend)
277 285 {
278   - int baddr;
279   - unsigned short a;
280   - int attr = COLOR_GREEN;
281   - unsigned char fa;
282   - int fa_addr;
  286 + int baddr;
  287 + unsigned short a;
  288 + int attr = COLOR_GREEN;
  289 + unsigned char fa;
  290 + int fa_addr;
  291 + int first = -1;
  292 + int last = -1;
283 293  
284 294 fa = get_field_attribute(session,bstart);
285 295 a = color_from_fa(fa);
... ... @@ -293,12 +303,12 @@ static void screen_update(H3270 *session, int bstart, int bend)
293 303 fa_addr = baddr;
294 304 fa = session->ea_buf[baddr].fa;
295 305 a = calc_attrs(session, baddr, baddr, fa);
296   - addch(session,baddr,' ',(attr = COLOR_GREEN)|CHAR_ATTR_MARKER);
  306 + addch(session,baddr,' ',(attr = COLOR_GREEN)|CHAR_ATTR_MARKER,&first,&last);
297 307 }
298 308 else if (FA_IS_ZERO(fa))
299 309 {
300 310 // Blank.
301   - addch(session,baddr,' ',attr=a);
  311 + addch(session,baddr,' ',attr=a,&first,&last);
302 312 }
303 313 else
304 314 {
... ... @@ -314,23 +324,37 @@ static void screen_update(H3270 *session, int bstart, int bend)
314 324  
315 325 if (session->ea_buf[baddr].cs == CS_LINEDRAW)
316 326 {
317   - addch(session,baddr,session->ea_buf[baddr].cc,attr);
  327 + addch(session,baddr,session->ea_buf[baddr].cc,attr,&first,&last);
318 328 }
319 329 else if (session->ea_buf[baddr].cs == CS_APL || (session->ea_buf[baddr].cs & CS_GE))
320 330 {
321   - addch(session,baddr,session->ea_buf[baddr].cc,attr|CHAR_ATTR_CG);
  331 + addch(session,baddr,session->ea_buf[baddr].cc,attr|LIB3270_ATTR_CG,&first,&last);
322 332 }
323 333 else
324 334 {
325 335 if (toggled(MONOCASE))
326   - addch(session,baddr,asc2uc[ebc2asc[session->ea_buf[baddr].cc]],attr);
  336 + addch(session,baddr,asc2uc[ebc2asc[session->ea_buf[baddr].cc]],attr,&first,&last);
327 337 else
328   - addch(session,baddr,ebc2asc[session->ea_buf[baddr].cc],attr);
  338 + addch(session,baddr,ebc2asc[session->ea_buf[baddr].cc],attr,&first,&last);
329 339 }
330 340 }
331 341  
  342 +
  343 + }
  344 +
  345 + if(first >= 0)
  346 + {
  347 + int len = (last - first)+1;
  348 + int f;
  349 +
  350 + for(f=first;f<last;f++)
  351 + {
  352 + if(f%session->cols == 0)
  353 + len++;
  354 + }
  355 +
  356 + session->changed(session,first,len);
332 357 }
333   - session->changed(session,bstart,bend);
334 358 }
335 359  
336 360 void screen_disp(H3270 *session)
... ...
src/lib3270/selection.c
... ... @@ -409,12 +409,15 @@ static char * get_text(H3270 *hSession,unsigned char all)
409 409  
410 410 LIB3270_EXPORT char * lib3270_get_text(H3270 *h, int offset, int len)
411 411 {
412   - char *buffer;
413   - int col, maxlen;
414   - char *ptr;
  412 + char * buffer;
  413 + int maxlen;
  414 + char * ptr;
415 415  
416 416 CHECK_SESSION_HANDLE(h);
417 417  
  418 + if(!lib3270_connected(h))
  419 + return NULL;
  420 +
418 421 maxlen = h->rows * (h->cols+1);
419 422  
420 423 if(len < 0)
... ... @@ -422,21 +425,28 @@ LIB3270_EXPORT char * lib3270_get_text(H3270 *h, int offset, int len)
422 425 else if(len > maxlen)
423 426 len = maxlen;
424 427  
425   - buffer = malloc(len+1);
426   - col = offset%h->cols;
  428 + buffer = malloc(len+2);
427 429 ptr = buffer;
428 430  
429 431 while(len-- > 0)
430 432 {
431   - *(ptr++) = h->text[offset++].chr;
432   - if(col++ >= h->cols && len > 0)
  433 + if(h->text[offset].attr & LIB3270_ATTR_CG)
  434 + *ptr = ' ';
  435 + else if(h->text[offset].chr)
  436 + *ptr = h->text[offset].chr;
  437 + else
  438 + *ptr = " ";
  439 +
  440 + ptr++;
  441 + offset++;
  442 +
  443 + if((offset%h->cols) == 0)
433 444 {
434   - col = 0;
435 445 *(ptr++) = '\n';
436 446 len--;
437 447 }
438 448 }
439   - *ptr = 0;
  449 + buffer[len] = 0;
440 450  
441 451 return buffer;
442 452 }
... ...
ui/00default.xml
... ... @@ -40,7 +40,7 @@
40 40 * filename='PATH' to save to a predefined file whithout user interaction
41 41  
42 42 --->
43   - <menuitem action='save' src='all' group='online' label='Save screen' />
  43 + <menuitem action='save' src='all' label='Save screen' />
44 44 <menuitem action='save' src='selected' group='selection' label='Save selected' />
45 45 <menuitem action='save' src='copy' group='clipboard' label='Save copy' />
46 46  
... ...