From 8387aa748f058d45da280acd0e0a1f8deb9f5ac8 Mon Sep 17 00:00:00 2001 From: perry.werneck@gmail.com Date: Thu, 5 Apr 2012 12:24:30 +0000 Subject: [PATCH] Implementando suporte atk --- src/gtk/v3270/accessible.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------------------- src/gtk/v3270/genmarshal | 1 + src/gtk/v3270/private.h | 1 + src/gtk/v3270/widget.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- src/include/lib3270/session.h | 2 +- src/lib3270/api.h | 4 ++-- src/lib3270/host.c | 42 +++++++++++------------------------------- src/lib3270/screen.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- src/lib3270/selection.c | 28 +++++++++++++++++++--------- ui/00default.xml | 2 +- 10 files changed, 183 insertions(+), 86 deletions(-) diff --git a/src/gtk/v3270/accessible.c b/src/gtk/v3270/accessible.c index 82e3acf..fb29af6 100644 --- a/src/gtk/v3270/accessible.c +++ b/src/gtk/v3270/accessible.c @@ -37,6 +37,7 @@ #include #include + #include #include "v3270.h" #include "private.h" #include "accessible.h" @@ -47,6 +48,7 @@ // http://git.gnome.org/browse/gtk+/tree/gtk/a11y/gtkentryaccessible.c // + /*--[ Prototipes ]-----------------------------------------------------------------------------------*/ static void atk_component_interface_init (AtkComponentIface *iface); @@ -69,13 +71,6 @@ G_DEFINE_TYPE_WITH_CODE (v3270Accessible, v3270_accessible, GTK_TYPE_ACCESSIBLE, /*--[ Implement ]------------------------------------------------------------------------------------*/ -/* -static const gchar * v3270_accessible_get_description(AtkObject *accessible) -{ - return _( "3270 screen" ); -} -*/ - static void v3270_accessible_class_init(v3270AccessibleClass *klass) { AtkObjectClass *class = ATK_OBJECT_CLASS (klass); @@ -113,14 +108,42 @@ static void atk_component_interface_init(AtkComponentIface *iface) static gunichar v3270_accessible_get_character_at_offset(AtkText *atk_text, gint offset) { - GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text)); + GtkWidget * widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text)); + + if(widget == NULL) + { + H3270 * host = v3270_get_session(widget); + gchar * text = lib3270_get_text(host,offset,1); - trace("*********** %s %p",__FUNCTION__,widget); + if(text) + { + gunichar unichar; + gsize bytes_written; + GError * error = NULL; + gchar * utfstring = g_convert_with_fallback( text, + -1, + "UTF-8", + lib3270_get_charset(host), + " ", + NULL, + &bytes_written, + &error ); + + if(error) + { + g_warning("%s failed: %s",__FUNCTION__,error->message); + g_error_free(error); + } + unichar = *utfstring; + + g_free(utfstring); + + return unichar; + } - if (widget == NULL) - return '\0'; + } - return 'X'; + return '\0'; } static gint v3270_accessible_get_caret_offset(AtkText *text) @@ -138,8 +161,6 @@ static gint v3270_accessible_get_character_count(AtkText *text) int rows,cols; GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE(text)); - trace("*********** %s %p len=%d",__FUNCTION__,widget,lib3270_get_length(GTK_V3270(widget)->host)); - if(!widget) return 0; @@ -150,7 +171,7 @@ static gint v3270_accessible_get_offset_at_point(AtkText *atk_text, gint x, gint { GtkWidget *widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text)); - trace("*********** %s %p",__FUNCTION__,widget); + g_warning("Call to incomplete function \"%s\"",__FUNCTION__); if(!widget) return -1; @@ -164,9 +185,7 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse GtkWidget * widget = gtk_accessible_get_widget(GTK_ACCESSIBLE (atk_text)); H3270 * host; char * text; - int rows,cols,first; - - trace("*********** %s %p offset=%d",__FUNCTION__,widget,offset); + int rows,cols,pos; if(!widget) return NULL; @@ -203,10 +222,10 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse case ATK_TEXT_BOUNDARY_LINE_START: // Boundary is the initial character of the content or a character immediately following a newline, // linefeed, or return character. - first = (offset/cols)*cols; - if(first == offset) + pos = (offset/cols)*cols; + if(pos == offset) offset++; - text = lib3270_get_text(host,first,(offset-first)); + text = lib3270_get_text(host,pos,(offset-pos)); break; @@ -234,6 +253,8 @@ static gchar * v3270_accessible_get_text_at_offset(AtkText *atk_text, gint offse g_warning("%s failed: %s",__FUNCTION__,error->message); g_error_free(error); } + + free(text); return utfchar; } diff --git a/src/gtk/v3270/genmarshal b/src/gtk/v3270/genmarshal index 45c6c39..d615b87 100644 --- a/src/gtk/v3270/genmarshal +++ b/src/gtk/v3270/genmarshal @@ -8,3 +8,4 @@ VOID:VOID,UINT,POINTER BOOL:VOID,UINT,ENUM VOID:VOID,BOOL BOOL:VOID,BOOL,BOOL,POINTER +VOID:VOID,UINT,UINT diff --git a/src/gtk/v3270/private.h b/src/gtk/v3270/private.h index aa7bce8..9dc74b3 100644 --- a/src/gtk/v3270/private.h +++ b/src/gtk/v3270/private.h @@ -78,6 +78,7 @@ G_BEGIN_DECLS SIGNAL_POPUP, SIGNAL_PASTENEXT, SIGNAL_CLIPBOARD, + SIGNAL_CHANGED, LAST_SIGNAL }; diff --git a/src/gtk/v3270/widget.c b/src/gtk/v3270/widget.c index 4c31173..7225784 100644 --- a/src/gtk/v3270/widget.c +++ b/src/gtk/v3270/widget.c @@ -33,6 +33,7 @@ #include #include #include + #include #include "v3270.h" #include "private.h" #include "accessible.h" @@ -437,6 +438,15 @@ static void v3270_class_init(v3270Class *klass) pw3270_VOID__VOID_BOOL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + v3270_widget_signal[SIGNAL_CHANGED] = + g_signal_new( "changed", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + pw3270_VOID__VOID_UINT_UINT, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + } 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) } -static void changed(H3270 *session, int bstart, int bend) -{ -// gtk_widget_queue_draw(GTK_WIDGET(session->widget)); -} - static void update_toggle(H3270 *session, LIB3270_TOGGLE ix, unsigned char value, LIB3270_TOGGLE_TYPE reason, const char *name) { 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) g_signal_emit(GTK_WIDGET(session->widget),v3270_widget_signal[SIGNAL_SELECTING], 0, status ? TRUE : FALSE); } +static void changed(H3270 *session, int offset, int len) +{ + GtkWidget * widget = session->widget; + AtkObject * obj = gtk_widget_get_accessible(widget); + + trace("%s: offset=%d len=%d",__FUNCTION__,offset,len) + +// if(obj) + { + // Get new text, notify atk + gsize bytes_written; + char * text = lib3270_get_text(session,offset,len); + + if(text) + { + GError * error = NULL; + gchar * utfchar = g_convert_with_fallback( text, + -1, + "UTF-8", + lib3270_get_charset(session), + " ", + NULL, + &bytes_written, + &error ); + + free(text); + + if(error) + { + g_warning("%s failed: %s",__FUNCTION__,error->message); + g_error_free(error); + } + else + { + // g_signal_emit_by_name(obj, "text-insert", offset,len,utfchar); + g_free(utfchar); + } + + } + } + + g_signal_emit(GTK_WIDGET(widget),v3270_widget_signal[SIGNAL_CHANGED], 0, (guint) offset, (guint) len); + +} + static void v3270_init(v3270 *widget) { trace("%s",__FUNCTION__); @@ -634,6 +684,7 @@ static void v3270_init(v3270 *widget) widget->host->cursor = select_cursor; widget->host->update_connect = update_connect; widget->host->update_model = update_model; + widget->host->changed = changed; // Setup input method widget->input_method = gtk_im_multicontext_new(); @@ -1060,13 +1111,22 @@ int v3270_connect(GtkWidget *widget, const gchar *host) return rc; } +static gboolean notify_focus(GtkWidget *widget, GdkEventFocus *event) +{ + AtkObject *obj = gtk_widget_get_accessible (widget); + + if(obj) + g_signal_emit_by_name (obj, "focus-event", event->in); + + return FALSE; +} gboolean v3270_focus_in_event(GtkWidget *widget, GdkEventFocus *event) { v3270 * terminal = GTK_V3270(widget); gtk_im_context_focus_in(terminal->input_method); - return 0; + return notify_focus(widget,event); } gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event) @@ -1075,7 +1135,7 @@ gboolean v3270_focus_out_event(GtkWidget *widget, GdkEventFocus *event) gtk_im_context_focus_out(terminal->input_method); - return 0; + return notify_focus(widget,event); } static void v3270_activate(GtkWidget *widget) diff --git a/src/include/lib3270/session.h b/src/include/lib3270/session.h index 1329c32..25fdb0a 100644 --- a/src/include/lib3270/session.h +++ b/src/include/lib3270/session.h @@ -156,7 +156,7 @@ // Session based callbacks void (*configure)(H3270 *session, unsigned short rows, unsigned short cols); void (*update)(H3270 *session, int baddr, unsigned char c, unsigned short attr, unsigned char cursor); - void (*changed)(H3270 *session, int bstart, int bend); + void (*changed)(H3270 *session, int offset, int len); void (*update_cursor)(H3270 *session, unsigned short row, unsigned short col, unsigned char c, unsigned short attr); void (*update_oia)(H3270 *session, LIB3270_FLAG id, unsigned char on); diff --git a/src/lib3270/api.h b/src/lib3270/api.h index 3c18cbe..f0a8497 100644 --- a/src/lib3270/api.h +++ b/src/lib3270/api.h @@ -303,10 +303,10 @@ #define COLOR_ATTR_UNDERLINE LIB3270_ATTR_UNDERLINE #define COLOR_ATTR_INTENSIFY LIB3270_ATTR_INTENSIFY - #define CHAR_ATTR_CG LIB3270_ATTR_CG +// #define CHAR_ATTR_CG LIB3270_ATTR_CG #define CHAR_ATTR_MARKER LIB3270_ATTR_MARKER - #define CHAR_ATTR_UNCONVERTED CHAR_ATTR_CG + #define CHAR_ATTR_UNCONVERTED LIB3270_ATTR_CG struct lib3270_option { diff --git a/src/lib3270/host.c b/src/lib3270/host.c index ebc9450..9c082ed 100644 --- a/src/lib3270/host.c +++ b/src/lib3270/host.c @@ -476,13 +476,11 @@ static int do_connect(H3270 *hSession, const char *n) char nb[2048]; /* name buffer */ char *s; /* temporary */ const char *chost; /* to whom we will connect */ -// char *target_name; char *ps = CN; char *port = CN; Boolean resolving; Boolean pending; static Boolean ansi_host; -// const char *localprocess_cmd = NULL; Boolean has_colons = False; if (lib3270_connected(hSession) || hSession->auto_reconnect_inprogress) @@ -499,7 +497,7 @@ static int do_connect(H3270 *hSession, const char *n) } /* Save in a modifiable buffer. */ - (void) strcpy(nb, n); + (void) strncpy(nb, n, 2047); /* Strip trailing blanks. */ s = nb + strlen(nb) - 1; @@ -509,14 +507,6 @@ static int do_connect(H3270 *hSession, const char *n) /* Remember this hostname, as the last hostname we connected to. */ lib3270_set_host(hSession,nb); -/* -#if defined(LOCAL_PROCESS) - if ((localprocess_cmd = parse_localprocess(nb)) != CN) { - chost = localprocess_cmd; - port = appres.port; - } else -#endif -*/ { Boolean needed; @@ -541,23 +531,8 @@ static int do_connect(H3270 *hSession, const char *n) * and port number * full_current_host is the entire string, for use in reconnecting */ - if (n != hSession->full_current_host) - lib3270_set_host(hSession,n); - Replace(hSession->current_host, CN); -/* - - if (localprocess_cmd != CN) { - if (hSession->full_current_host[strlen(OptLocalProcess)] != '\0') - hSession->current_host = NewString(hSession->full_current_host + strlen(OptLocalProcess) + 1); - else - hSession->current_host = NewString("default shell"); - } else { - hSession->current_host = s; - } -*/ - has_colons = (strchr(chost, ':') != NULL); Replace(hSession->qualified_host, @@ -780,13 +755,18 @@ LIB3270_EXPORT const char * lib3270_set_host(H3270 *h, const char *n) Trace("%s: %p",__FUNCTION__,n); - if(!n) - return NULL; + if(n && n != h->full_current_host) + { + char *new_hostname = strdup(n); + + trace("new hostname is \"%s\"",new_hostname); - if(h->full_current_host) - free(h->full_current_host); + if(h->full_current_host) + free(h->full_current_host); - h->full_current_host = strdup(n); + h->full_current_host = new_hostname; + + } return h->full_current_host; } diff --git a/src/lib3270/screen.c b/src/lib3270/screen.c index 2732bec..e300441 100644 --- a/src/lib3270/screen.c +++ b/src/lib3270/screen.c @@ -72,6 +72,8 @@ #define get_color_pair(fg,bg) (((bg&0x0F) << 4) | (fg&0x0F)) #define DEFCOLOR_MAP(f) ((((f) & FA_PROTECT) >> 4) | (((f) & FA_INT_HIGH_SEL) >> 3)) +/*--[ Implement ]------------------------------------------------------------------------------------*/ + static int logpopup(H3270 *session, LIB3270_NOTIFY type, const char *title, const char *msg, const char *fmt, va_list arg); 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); static void status_printer(H3270 *session, int on, void *dunno); static unsigned short color_from_fa(unsigned char fa); -static void addch(H3270 *session, int baddr, unsigned char c, unsigned short attr) +/*--[ Implement ]------------------------------------------------------------------------------------*/ + +static void addch(H3270 *session, int baddr, unsigned char c, unsigned short attr, int *first, int *last) { // If set to keep selection adjust corresponding flag based on the current state if(lib3270_get_toggle(session,LIB3270_TOGGLE_KEEP_SELECTED)) attr |= (session->text[baddr].attr & LIB3270_ATTR_SELECTED); if(session->text[baddr].chr == c && session->text[baddr].attr == attr) - return; + return; + + if(*first < 0) + *first = baddr; + *last = baddr; /* Converted char has changed, update it */ session->text[baddr].chr = c; @@ -275,11 +283,13 @@ LIB3270_EXPORT int lib3270_get_contents(H3270 *h, int first, int last, unsigned /* Display what's in the buffer. */ static void screen_update(H3270 *session, int bstart, int bend) { - int baddr; - unsigned short a; - int attr = COLOR_GREEN; - unsigned char fa; - int fa_addr; + int baddr; + unsigned short a; + int attr = COLOR_GREEN; + unsigned char fa; + int fa_addr; + int first = -1; + int last = -1; fa = get_field_attribute(session,bstart); a = color_from_fa(fa); @@ -293,12 +303,12 @@ static void screen_update(H3270 *session, int bstart, int bend) fa_addr = baddr; fa = session->ea_buf[baddr].fa; a = calc_attrs(session, baddr, baddr, fa); - addch(session,baddr,' ',(attr = COLOR_GREEN)|CHAR_ATTR_MARKER); + addch(session,baddr,' ',(attr = COLOR_GREEN)|CHAR_ATTR_MARKER,&first,&last); } else if (FA_IS_ZERO(fa)) { // Blank. - addch(session,baddr,' ',attr=a); + addch(session,baddr,' ',attr=a,&first,&last); } else { @@ -314,23 +324,37 @@ static void screen_update(H3270 *session, int bstart, int bend) if (session->ea_buf[baddr].cs == CS_LINEDRAW) { - addch(session,baddr,session->ea_buf[baddr].cc,attr); + addch(session,baddr,session->ea_buf[baddr].cc,attr,&first,&last); } else if (session->ea_buf[baddr].cs == CS_APL || (session->ea_buf[baddr].cs & CS_GE)) { - addch(session,baddr,session->ea_buf[baddr].cc,attr|CHAR_ATTR_CG); + addch(session,baddr,session->ea_buf[baddr].cc,attr|LIB3270_ATTR_CG,&first,&last); } else { if (toggled(MONOCASE)) - addch(session,baddr,asc2uc[ebc2asc[session->ea_buf[baddr].cc]],attr); + addch(session,baddr,asc2uc[ebc2asc[session->ea_buf[baddr].cc]],attr,&first,&last); else - addch(session,baddr,ebc2asc[session->ea_buf[baddr].cc],attr); + addch(session,baddr,ebc2asc[session->ea_buf[baddr].cc],attr,&first,&last); } } + + } + + if(first >= 0) + { + int len = (last - first)+1; + int f; + + for(f=first;fcols == 0) + len++; + } + + session->changed(session,first,len); } - session->changed(session,bstart,bend); } void screen_disp(H3270 *session) diff --git a/src/lib3270/selection.c b/src/lib3270/selection.c index 7ef4b61..f25678e 100644 --- a/src/lib3270/selection.c +++ b/src/lib3270/selection.c @@ -409,12 +409,15 @@ static char * get_text(H3270 *hSession,unsigned char all) LIB3270_EXPORT char * lib3270_get_text(H3270 *h, int offset, int len) { - char *buffer; - int col, maxlen; - char *ptr; + char * buffer; + int maxlen; + char * ptr; CHECK_SESSION_HANDLE(h); + if(!lib3270_connected(h)) + return NULL; + maxlen = h->rows * (h->cols+1); if(len < 0) @@ -422,21 +425,28 @@ LIB3270_EXPORT char * lib3270_get_text(H3270 *h, int offset, int len) else if(len > maxlen) len = maxlen; - buffer = malloc(len+1); - col = offset%h->cols; + buffer = malloc(len+2); ptr = buffer; while(len-- > 0) { - *(ptr++) = h->text[offset++].chr; - if(col++ >= h->cols && len > 0) + if(h->text[offset].attr & LIB3270_ATTR_CG) + *ptr = ' '; + else if(h->text[offset].chr) + *ptr = h->text[offset].chr; + else + *ptr = " "; + + ptr++; + offset++; + + if((offset%h->cols) == 0) { - col = 0; *(ptr++) = '\n'; len--; } } - *ptr = 0; + buffer[len] = 0; return buffer; } diff --git a/ui/00default.xml b/ui/00default.xml index 902f55b..2f2a4f3 100644 --- a/ui/00default.xml +++ b/ui/00default.xml @@ -40,7 +40,7 @@ * filename='PATH' to save to a predefined file whithout user interaction ---> - + -- libgit2 0.21.2