Commit 8387aa748f058d45da280acd0e0a1f8deb9f5ac8

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

Implementando suporte atk

src/gtk/v3270/accessible.c
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 #include <glib/gi18n.h> 37 #include <glib/gi18n.h>
38 38
39 #include <pw3270.h> 39 #include <pw3270.h>
  40 + #include <malloc.h>
40 #include "v3270.h" 41 #include "v3270.h"
41 #include "private.h" 42 #include "private.h"
42 #include "accessible.h" 43 #include "accessible.h"
@@ -47,6 +48,7 @@ @@ -47,6 +48,7 @@
47 // http://git.gnome.org/browse/gtk+/tree/gtk/a11y/gtkentryaccessible.c 48 // http://git.gnome.org/browse/gtk+/tree/gtk/a11y/gtkentryaccessible.c
48 // 49 //
49 50
  51 +
50 /*--[ Prototipes ]-----------------------------------------------------------------------------------*/ 52 /*--[ Prototipes ]-----------------------------------------------------------------------------------*/
51 53
52 static void atk_component_interface_init (AtkComponentIface *iface); 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,13 +71,6 @@ G_DEFINE_TYPE_WITH_CODE (v3270Accessible, v3270_accessible, GTK_TYPE_ACCESSIBLE,
69 71
70 /*--[ Implement ]------------------------------------------------------------------------------------*/ 72 /*--[ Implement ]------------------------------------------------------------------------------------*/
71 73
72 -/*  
73 -static const gchar * v3270_accessible_get_description(AtkObject *accessible)  
74 -{  
75 - return _( "3270 screen" );  
76 -}  
77 -*/  
78 -  
79 static void v3270_accessible_class_init(v3270AccessibleClass *klass) 74 static void v3270_accessible_class_init(v3270AccessibleClass *klass)
80 { 75 {
81 AtkObjectClass *class = ATK_OBJECT_CLASS (klass); 76 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
@@ -113,14 +108,42 @@ static void atk_component_interface_init(AtkComponentIface *iface) @@ -113,14 +108,42 @@ static void atk_component_interface_init(AtkComponentIface *iface)
113 108
114 static gunichar v3270_accessible_get_character_at_offset(AtkText *atk_text, gint offset) 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 static gint v3270_accessible_get_caret_offset(AtkText *text) 149 static gint v3270_accessible_get_caret_offset(AtkText *text)
@@ -138,8 +161,6 @@ static gint v3270_accessible_get_character_count(AtkText *text) @@ -138,8 +161,6 @@ static gint v3270_accessible_get_character_count(AtkText *text)
138 int rows,cols; 161 int rows,cols;
139 GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE(text)); 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 if(!widget) 164 if(!widget)
144 return 0; 165 return 0;
145 166
@@ -150,7 +171,7 @@ static gint v3270_accessible_get_offset_at_point(AtkText *atk_text, gint x, gint @@ -150,7 +171,7 @@ static gint v3270_accessible_get_offset_at_point(AtkText *atk_text, gint x, gint
150 { 171 {
151 GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text)); 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 if(!widget) 176 if(!widget)
156 return -1; 177 return -1;
@@ -164,9 +185,7 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse @@ -164,9 +185,7 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse
164 GtkWidget * widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text)); 185 GtkWidget * widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text));
165 H3270 * host; 186 H3270 * host;
166 char * text; 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 if(!widget) 190 if(!widget)
172 return NULL; 191 return NULL;
@@ -203,10 +222,10 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse @@ -203,10 +222,10 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse
203 222
204 case ATK_TEXT_BOUNDARY_LINE_START: // Boundary is the initial character of the content or a character immediately following a newline, 223 case ATK_TEXT_BOUNDARY_LINE_START: // Boundary is the initial character of the content or a character immediately following a newline,
205 // linefeed, or return character. 224 // linefeed, or return character.
206 - first = (offset/cols)*cols;  
207 - if(first == offset) 225 + pos = (offset/cols)*cols;
  226 + if(pos == offset)
208 offset++; 227 offset++;
209 - text = lib3270_get_text(host,first,(offset-first)); 228 + text = lib3270_get_text(host,pos,(offset-pos));
210 break; 229 break;
211 230
212 231
@@ -234,6 +253,8 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse @@ -234,6 +253,8 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse
234 g_warning("%s failed: %s",__FUNCTION__,error->message); 253 g_warning("%s failed: %s",__FUNCTION__,error->message);
235 g_error_free(error); 254 g_error_free(error);
236 } 255 }
  256 +
  257 + free(text);
237 return utfchar; 258 return utfchar;
238 } 259 }
239 260
src/gtk/v3270/genmarshal
@@ -8,3 +8,4 @@ VOID:VOID,UINT,POINTER @@ -8,3 +8,4 @@ VOID:VOID,UINT,POINTER
8 BOOL:VOID,UINT,ENUM 8 BOOL:VOID,UINT,ENUM
9 VOID:VOID,BOOL 9 VOID:VOID,BOOL
10 BOOL:VOID,BOOL,BOOL,POINTER 10 BOOL:VOID,BOOL,BOOL,POINTER
  11 +VOID:VOID,UINT,UINT
src/gtk/v3270/private.h
@@ -78,6 +78,7 @@ G_BEGIN_DECLS @@ -78,6 +78,7 @@ G_BEGIN_DECLS
78 SIGNAL_POPUP, 78 SIGNAL_POPUP,
79 SIGNAL_PASTENEXT, 79 SIGNAL_PASTENEXT,
80 SIGNAL_CLIPBOARD, 80 SIGNAL_CLIPBOARD,
  81 + SIGNAL_CHANGED,
81 82
82 LAST_SIGNAL 83 LAST_SIGNAL
83 }; 84 };
src/gtk/v3270/widget.c
@@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
33 #include <lib3270/session.h> 33 #include <lib3270/session.h>
34 #include <lib3270/actions.h> 34 #include <lib3270/actions.h>
35 #include <lib3270/log.h> 35 #include <lib3270/log.h>
  36 + #include <malloc.h>
36 #include "v3270.h" 37 #include "v3270.h"
37 #include "private.h" 38 #include "private.h"
38 #include "accessible.h" 39 #include "accessible.h"
@@ -437,6 +438,15 @@ static void v3270_class_init(v3270Class *klass) @@ -437,6 +438,15 @@ static void v3270_class_init(v3270Class *klass)
437 pw3270_VOID__VOID_BOOL, 438 pw3270_VOID__VOID_BOOL,
438 G_TYPE_NONE, 1, G_TYPE_BOOLEAN); 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 void v3270_update_font_metrics(v3270 *terminal, cairo_t *cr, int width, int height) 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,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 static void update_toggle(H3270 *session, LIB3270_TOGGLE ix, unsigned char value, LIB3270_TOGGLE_TYPE reason, const char *name) 554 static void update_toggle(H3270 *session, LIB3270_TOGGLE ix, unsigned char value, LIB3270_TOGGLE_TYPE reason, const char *name)
550 { 555 {
551 g_signal_emit(GTK_WIDGET(session->widget), v3270_widget_signal[SIGNAL_TOGGLE_CHANGED], 0, (guint) ix, (gboolean) (value != 0), (gchar *) name); 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,6 +612,51 @@ static void set_selection(H3270 *session, unsigned char status)
607 g_signal_emit(GTK_WIDGET(session->widget),v3270_widget_signal[SIGNAL_SELECTING], 0, status ? TRUE : FALSE); 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 static void v3270_init(v3270 *widget) 660 static void v3270_init(v3270 *widget)
611 { 661 {
612 trace("%s",__FUNCTION__); 662 trace("%s",__FUNCTION__);
@@ -634,6 +684,7 @@ static void v3270_init(v3270 *widget) @@ -634,6 +684,7 @@ static void v3270_init(v3270 *widget)
634 widget->host->cursor = select_cursor; 684 widget->host->cursor = select_cursor;
635 widget->host->update_connect = update_connect; 685 widget->host->update_connect = update_connect;
636 widget->host->update_model = update_model; 686 widget->host->update_model = update_model;
  687 + widget->host->changed = changed;
637 688
638 // Setup input method 689 // Setup input method
639 widget->input_method = gtk_im_multicontext_new(); 690 widget->input_method = gtk_im_multicontext_new();
@@ -1060,13 +1111,22 @@ int v3270_connect(GtkWidget *widget, const gchar *host) @@ -1060,13 +1111,22 @@ int v3270_connect(GtkWidget *widget, const gchar *host)
1060 return rc; 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 gboolean v3270_focus_in_event(GtkWidget *widget, GdkEventFocus *event) 1123 gboolean v3270_focus_in_event(GtkWidget *widget, GdkEventFocus *event)
1064 { 1124 {
1065 v3270 * terminal = GTK_V3270(widget); 1125 v3270 * terminal = GTK_V3270(widget);
1066 1126
1067 gtk_im_context_focus_in(terminal->input_method); 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 gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event) 1132 gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event)
@@ -1075,7 +1135,7 @@ 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 gtk_im_context_focus_out(terminal->input_method); 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 static void v3270_activate(GtkWidget *widget) 1141 static void v3270_activate(GtkWidget *widget)
src/include/lib3270/session.h
@@ -156,7 +156,7 @@ @@ -156,7 +156,7 @@
156 // Session based callbacks 156 // Session based callbacks
157 void (*configure)(H3270 *session, unsigned short rows, unsigned short cols); 157 void (*configure)(H3270 *session, unsigned short rows, unsigned short cols);
158 void (*update)(H3270 *session, int baddr, unsigned char c, unsigned short attr, unsigned char cursor); 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 void (*update_cursor)(H3270 *session, unsigned short row, unsigned short col, unsigned char c, unsigned short attr); 161 void (*update_cursor)(H3270 *session, unsigned short row, unsigned short col, unsigned char c, unsigned short attr);
162 void (*update_oia)(H3270 *session, LIB3270_FLAG id, unsigned char on); 162 void (*update_oia)(H3270 *session, LIB3270_FLAG id, unsigned char on);
src/lib3270/api.h
@@ -303,10 +303,10 @@ @@ -303,10 +303,10 @@
303 #define COLOR_ATTR_UNDERLINE LIB3270_ATTR_UNDERLINE 303 #define COLOR_ATTR_UNDERLINE LIB3270_ATTR_UNDERLINE
304 #define COLOR_ATTR_INTENSIFY LIB3270_ATTR_INTENSIFY 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 #define CHAR_ATTR_MARKER LIB3270_ATTR_MARKER 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 struct lib3270_option 311 struct lib3270_option
312 { 312 {
src/lib3270/host.c
@@ -476,13 +476,11 @@ static int do_connect(H3270 *hSession, const char *n) @@ -476,13 +476,11 @@ static int do_connect(H3270 *hSession, const char *n)
476 char nb[2048]; /* name buffer */ 476 char nb[2048]; /* name buffer */
477 char *s; /* temporary */ 477 char *s; /* temporary */
478 const char *chost; /* to whom we will connect */ 478 const char *chost; /* to whom we will connect */
479 -// char *target_name;  
480 char *ps = CN; 479 char *ps = CN;
481 char *port = CN; 480 char *port = CN;
482 Boolean resolving; 481 Boolean resolving;
483 Boolean pending; 482 Boolean pending;
484 static Boolean ansi_host; 483 static Boolean ansi_host;
485 -// const char *localprocess_cmd = NULL;  
486 Boolean has_colons = False; 484 Boolean has_colons = False;
487 485
488 if (lib3270_connected(hSession) || hSession->auto_reconnect_inprogress) 486 if (lib3270_connected(hSession) || hSession->auto_reconnect_inprogress)
@@ -499,7 +497,7 @@ static int do_connect(H3270 *hSession, const char *n) @@ -499,7 +497,7 @@ static int do_connect(H3270 *hSession, const char *n)
499 } 497 }
500 498
501 /* Save in a modifiable buffer. */ 499 /* Save in a modifiable buffer. */
502 - (void) strcpy(nb, n); 500 + (void) strncpy(nb, n, 2047);
503 501
504 /* Strip trailing blanks. */ 502 /* Strip trailing blanks. */
505 s = nb + strlen(nb) - 1; 503 s = nb + strlen(nb) - 1;
@@ -509,14 +507,6 @@ static int do_connect(H3270 *hSession, const char *n) @@ -509,14 +507,6 @@ static int do_connect(H3270 *hSession, const char *n)
509 /* Remember this hostname, as the last hostname we connected to. */ 507 /* Remember this hostname, as the last hostname we connected to. */
510 lib3270_set_host(hSession,nb); 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 Boolean needed; 511 Boolean needed;
522 512
@@ -541,23 +531,8 @@ static int do_connect(H3270 *hSession, const char *n) @@ -541,23 +531,8 @@ static int do_connect(H3270 *hSession, const char *n)
541 * and port number 531 * and port number
542 * full_current_host is the entire string, for use in reconnecting 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 Replace(hSession->current_host, CN); 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 has_colons = (strchr(chost, ':') != NULL); 536 has_colons = (strchr(chost, ':') != NULL);
562 537
563 Replace(hSession->qualified_host, 538 Replace(hSession->qualified_host,
@@ -780,13 +755,18 @@ LIB3270_EXPORT const char * lib3270_set_host(H3270 *h, const char *n) @@ -780,13 +755,18 @@ LIB3270_EXPORT const char * lib3270_set_host(H3270 *h, const char *n)
780 755
781 Trace("%s: %p",__FUNCTION__,n); 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 return h->full_current_host; 771 return h->full_current_host;
792 } 772 }
src/lib3270/screen.c
@@ -72,6 +72,8 @@ @@ -72,6 +72,8 @@
72 #define get_color_pair(fg,bg) (((bg&0x0F) << 4) | (fg&0x0F)) 72 #define get_color_pair(fg,bg) (((bg&0x0F) << 4) | (fg&0x0F))
73 #define DEFCOLOR_MAP(f) ((((f) & FA_PROTECT) >> 4) | (((f) & FA_INT_HIGH_SEL) >> 3)) 73 #define DEFCOLOR_MAP(f) ((((f) & FA_PROTECT) >> 4) | (((f) & FA_INT_HIGH_SEL) >> 3))
74 74
  75 +/*--[ Implement ]------------------------------------------------------------------------------------*/
  76 +
75 static int logpopup(H3270 *session, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg); 77 static int logpopup(H3270 *session, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg);
76 78
77 static int (*popup_handler)(H3270 *, LIB3270_NOTIFY, const char *, const char *, const char *, va_list) = logpopup; 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,14 +86,20 @@ static void status_3270_mode(H3270 *session, int ignored, void *dunno);
84 static void status_printer(H3270 *session, int on, void *dunno); 86 static void status_printer(H3270 *session, int on, void *dunno);
85 static unsigned short color_from_fa(unsigned char fa); 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 // If set to keep selection adjust corresponding flag based on the current state 93 // If set to keep selection adjust corresponding flag based on the current state
90 if(lib3270_get_toggle(session,LIB3270_TOGGLE_KEEP_SELECTED)) 94 if(lib3270_get_toggle(session,LIB3270_TOGGLE_KEEP_SELECTED))
91 attr |= (session->text[baddr].attr & LIB3270_ATTR_SELECTED); 95 attr |= (session->text[baddr].attr & LIB3270_ATTR_SELECTED);
92 96
93 if(session->text[baddr].chr == c && session->text[baddr].attr == attr) 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 /* Converted char has changed, update it */ 104 /* Converted char has changed, update it */
97 session->text[baddr].chr = c; 105 session->text[baddr].chr = c;
@@ -275,11 +283,13 @@ LIB3270_EXPORT int lib3270_get_contents(H3270 *h, int first, int last, unsigned @@ -275,11 +283,13 @@ LIB3270_EXPORT int lib3270_get_contents(H3270 *h, int first, int last, unsigned
275 /* Display what's in the buffer. */ 283 /* Display what's in the buffer. */
276 static void screen_update(H3270 *session, int bstart, int bend) 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 fa = get_field_attribute(session,bstart); 294 fa = get_field_attribute(session,bstart);
285 a = color_from_fa(fa); 295 a = color_from_fa(fa);
@@ -293,12 +303,12 @@ static void screen_update(H3270 *session, int bstart, int bend) @@ -293,12 +303,12 @@ static void screen_update(H3270 *session, int bstart, int bend)
293 fa_addr = baddr; 303 fa_addr = baddr;
294 fa = session->ea_buf[baddr].fa; 304 fa = session->ea_buf[baddr].fa;
295 a = calc_attrs(session, baddr, baddr, fa); 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 else if (FA_IS_ZERO(fa)) 308 else if (FA_IS_ZERO(fa))
299 { 309 {
300 // Blank. 310 // Blank.
301 - addch(session,baddr,' ',attr=a); 311 + addch(session,baddr,' ',attr=a,&first,&last);
302 } 312 }
303 else 313 else
304 { 314 {
@@ -314,23 +324,37 @@ static void screen_update(H3270 *session, int bstart, int bend) @@ -314,23 +324,37 @@ static void screen_update(H3270 *session, int bstart, int bend)
314 324
315 if (session->ea_buf[baddr].cs == CS_LINEDRAW) 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 else if (session->ea_buf[baddr].cs == CS_APL || (session->ea_buf[baddr].cs & CS_GE)) 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 else 333 else
324 { 334 {
325 if (toggled(MONOCASE)) 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 else 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 void screen_disp(H3270 *session) 360 void screen_disp(H3270 *session)
src/lib3270/selection.c
@@ -409,12 +409,15 @@ static char * get_text(H3270 *hSession,unsigned char all) @@ -409,12 +409,15 @@ static char * get_text(H3270 *hSession,unsigned char all)
409 409
410 LIB3270_EXPORT char * lib3270_get_text(H3270 *h, int offset, int len) 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 CHECK_SESSION_HANDLE(h); 416 CHECK_SESSION_HANDLE(h);
417 417
  418 + if(!lib3270_connected(h))
  419 + return NULL;
  420 +
418 maxlen = h->rows * (h->cols+1); 421 maxlen = h->rows * (h->cols+1);
419 422
420 if(len < 0) 423 if(len < 0)
@@ -422,21 +425,28 @@ LIB3270_EXPORT char * lib3270_get_text(H3270 *h, int offset, int len) @@ -422,21 +425,28 @@ LIB3270_EXPORT char * lib3270_get_text(H3270 *h, int offset, int len)
422 else if(len > maxlen) 425 else if(len > maxlen)
423 len = maxlen; 426 len = maxlen;
424 427
425 - buffer = malloc(len+1);  
426 - col = offset%h->cols; 428 + buffer = malloc(len+2);
427 ptr = buffer; 429 ptr = buffer;
428 430
429 while(len-- > 0) 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 *(ptr++) = '\n'; 445 *(ptr++) = '\n';
436 len--; 446 len--;
437 } 447 }
438 } 448 }
439 - *ptr = 0; 449 + buffer[len] = 0;
440 450
441 return buffer; 451 return buffer;
442 } 452 }
ui/00default.xml
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 * filename='PATH' to save to a predefined file whithout user interaction 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 <menuitem action='save' src='selected' group='selection' label='Save selected' /> 44 <menuitem action='save' src='selected' group='selection' label='Save selected' />
45 <menuitem action='save' src='copy' group='clipboard' label='Save copy' /> 45 <menuitem action='save' src='copy' group='clipboard' label='Save copy' />
46 46