diff --git a/src/gtk/mainwindow.c b/src/gtk/mainwindow.c index a27079d..a72d680 100644 --- a/src/gtk/mainwindow.c +++ b/src/gtk/mainwindow.c @@ -97,6 +97,12 @@ set_integer_to_config("terminal","model",id); } + static gboolean popup(GtkWidget *widget, gboolean selected, gboolean online, GdkEventButton *event, gpointer popup) + { + trace("Popup on widget %p online=%s selected=%s",widget,online ? "Yes" : "No", selected ? "Yes" : "No"); + return TRUE; + } + static void selecting(GtkWidget *widget, gboolean on, GtkActionGroup **group) { trace("Widget %p selection state changed to %s",widget,on ? "Yes" : "No"); @@ -219,6 +225,7 @@ g_signal_connect(terminal,"update_config",G_CALLBACK(update_config),0); g_signal_connect(terminal,"model_changed",G_CALLBACK(update_model),0); g_signal_connect(terminal,"selecting",G_CALLBACK(selecting),group); + g_signal_connect(terminal,"popup",G_CALLBACK(popup),NULL); g_free(path); gtk_widget_grab_focus(terminal); diff --git a/src/gtk/v3270/genmarshal b/src/gtk/v3270/genmarshal index 835ba71..a43bd27 100644 --- a/src/gtk/v3270/genmarshal +++ b/src/gtk/v3270/genmarshal @@ -6,3 +6,4 @@ VOID:VOID,POINTER,POINTER VOID:VOID,UINT,POINTER BOOL:VOID,UINT,ENUM VOID:VOID,BOOL +VOID:VOID,BOOL,BOOL,POINTER diff --git a/src/gtk/v3270/mouse.c b/src/gtk/v3270/mouse.c index f4e1f4c..abe2f64 100644 --- a/src/gtk/v3270/mouse.c +++ b/src/gtk/v3270/mouse.c @@ -63,10 +63,12 @@ static void button_1_press(GtkWidget *widget, GdkEventType type, int baddr) lib3270_clear_selection(GTK_V3270(widget)->host); break; - case GDK_2BUTTON_PRESS: // Double click - Select work + case GDK_2BUTTON_PRESS: // Double click - Select word + lib3270_select_word(GTK_V3270(widget)->host,baddr); break; case GDK_3BUTTON_PRESS: // Triple clock - Select field + lib3270_select_field(GTK_V3270(widget)->host,baddr); break; #ifdef DEBUG @@ -76,6 +78,26 @@ static void button_1_press(GtkWidget *widget, GdkEventType type, int baddr) } } +void v3270_emit_popup(v3270 *widget, int baddr, GdkEventButton *event) +{ + unsigned char chr = 0; + unsigned short attr; + gboolean handled = FALSE; + + lib3270_get_contents(widget->host,baddr,baddr,&chr,&attr); + + g_signal_emit(GTK_WIDGET(widget), v3270_widget_signal[SIGNAL_POPUP], 0, + (attr & LIB3270_ATTR_SELECTED) ? TRUE : FALSE, + lib3270_connected(widget->host) ? TRUE : FALSE, + event, + &handled); + + if(handled) + return; + + gdk_beep(); +} + gboolean v3270_button_press_event(GtkWidget *widget, GdkEventButton *event) { int baddr = decode_position(GTK_V3270(widget),event->x,event->y); @@ -87,11 +109,13 @@ gboolean v3270_button_press_event(GtkWidget *widget, GdkEventButton *event) switch(event->button) { - case 1: + case 1: // Left button button_1_press(widget,event->type,baddr); -// lib3270_set_cursor_address(GTK_V3270(widget)->host,baddr); -// GTK_V3270(widget)->selecting = 1; -// lib3270_clear_selection(GTK_V3270(widget)->host); + break; + + case 3: // Right button + if(event->type == GDK_BUTTON_PRESS) + v3270_emit_popup(GTK_V3270(widget),baddr,event); break; default: diff --git a/src/gtk/v3270/private.h b/src/gtk/v3270/private.h index ad77254..59023e3 100644 --- a/src/gtk/v3270/private.h +++ b/src/gtk/v3270/private.h @@ -73,6 +73,7 @@ G_BEGIN_DECLS SIGNAL_UPDATE_CONFIG, SIGNAL_MODEL_CHANGED, SIGNAL_SELECTING, + SIGNAL_POPUP, LAST_SIGNAL }; @@ -127,5 +128,6 @@ void v3270_key_commit(GtkIMContext *imcontext, gchar *str, v3270 *widget); gboolean v3270_button_press_event(GtkWidget *widget, GdkEventButton *event); gboolean v3270_button_release_event(GtkWidget *widget, GdkEventButton*event); gboolean v3270_motion_notify_event(GtkWidget *widget, GdkEventMotion *event); +void v3270_emit_popup(v3270 *widget, int baddr, GdkEventButton *event); G_END_DECLS diff --git a/src/gtk/v3270/widget.c b/src/gtk/v3270/widget.c index 8eb3327..f2d62b8 100644 --- a/src/gtk/v3270/widget.c +++ b/src/gtk/v3270/widget.c @@ -124,6 +124,23 @@ static void loghandler(H3270 *session, const char *module, int rc, const char *f g_logv(module,rc ? G_LOG_LEVEL_WARNING : G_LOG_LEVEL_MESSAGE, fmt, args); } +static gboolean v3270_popup_menu(GtkWidget * widget) +{ + GdkEventButton event; + + memset(&event,0,sizeof(event)); + + event.time = gtk_get_current_event_time(); + event.button = 3; + event.type = GDK_BUTTON_PRESS; + + v3270_emit_popup( GTK_V3270(widget), + lib3270_get_cursor_address(GTK_V3270(widget)->host), + &event ); + + return TRUE; +} + static void v3270_class_init(v3270Class *klass) { GObjectClass * gobject_class = G_OBJECT_CLASS(klass); @@ -140,6 +157,7 @@ static void v3270_class_init(v3270Class *klass) widget_class->button_press_event = v3270_button_press_event; widget_class->button_release_event = v3270_button_release_event; widget_class->motion_notify_event = v3270_motion_notify_event; + widget_class->popup_menu = v3270_popup_menu; klass->activate = v3270_activate; klass->toggle_changed = v3270_toggle_changed; @@ -262,6 +280,15 @@ static void v3270_class_init(v3270Class *klass) NULL, NULL, pw3270_VOID__VOID_BOOL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + v3270_widget_signal[SIGNAL_POPUP] = + g_signal_new( "popup", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + pw3270_VOID__VOID_BOOL_BOOL_POINTER, + G_TYPE_NONE, 3, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_POINTER); } void v3270_update_font_metrics(v3270 *terminal, cairo_t *cr, int width, int height) diff --git a/src/lib3270/selection.c b/src/lib3270/selection.c index cb37a70..50d6130 100644 --- a/src/lib3270/selection.c +++ b/src/lib3270/selection.c @@ -182,6 +182,9 @@ LIB3270_EXPORT void lib3270_select_to(H3270 *session, int baddr) { CHECK_SESSION_HANDLE(session); + if(!lib3270_connected(session)) + return; + lib3270_set_cursor_address(session,session->selected.end = baddr); if(session->selected.begin < 0) @@ -200,22 +203,34 @@ LIB3270_EXPORT void lib3270_select_word(H3270 *session, int baddr) CHECK_SESSION_HANDLE(session); + if(!lib3270_connected(session) || isspace(ea_buf[baddr].chr)) + { + ring_bell(); + return; + } + for(pos = baddr; pos > 0 && !isspace(ea_buf[pos].chr);pos--); - session->selected.begin = pos; + session->selected.begin = pos > 0 ? pos+1 : 0; len = session->rows * session->cols; for(pos = baddr; pos < len && !isspace(ea_buf[pos].chr);pos++); - session->selected.end = pos; + session->selected.end = pos < len ? pos-1 : len; update_selected_region(session); } LIB3270_EXPORT int lib3270_select_field(H3270 *session, int baddr) { - int start; + int start,len; CHECK_SESSION_HANDLE(session); + if(!lib3270_connected(session)) + { + ring_bell(); + return; + } + start = lib3270_field_addr(session,baddr); if(start < 0) @@ -224,8 +239,13 @@ LIB3270_EXPORT int lib3270_select_field(H3270 *session, int baddr) return -1; } - session->selected.begin = start; + session->selected.begin = (start+1); + + len = (session->rows * session->cols)-1; + session->selected.end = start + lib3270_field_length(session,start); + if(session->selected.end > len) + session->selected.end = len; update_selected_region(session); -- libgit2 0.21.2