From 92d516aaab9b2ab2aac3b3a452c786d146400b5d Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Mon, 14 Oct 2019 14:08:27 -0300 Subject: [PATCH] Fixing GAction<->lib3270 adapters. --- src/actions/abstract.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ src/actions/lib3270/action.c | 39 ++++++++++++--------------------------- src/actions/lib3270/toggle.c | 51 +++++++++++++++++++++++++++++++-------------------- src/actions/private.h | 17 ++++++++++++++--- src/actions/testprogram/testprogram.c | 2 ++ src/actions/window.c | 6 ++++-- src/include/pw3270/actions.h | 11 +++++------ 7 files changed, 175 insertions(+), 88 deletions(-) diff --git a/src/actions/abstract.c b/src/actions/abstract.c index 8da34cb..6c5a25b 100644 --- a/src/actions/abstract.c +++ b/src/actions/abstract.c @@ -28,6 +28,7 @@ */ #include "private.h" + #include static void pw3270_action_iface_init(GActionInterface *iface); static void pw3270Action_class_init(pw3270ActionClass *klass); @@ -35,6 +36,12 @@ static void pw3270_action_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void pw3270_action_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void pw3270_action_set_state(GAction *action, GVariant *value); + static gboolean pw3270_action_get_enabled(GAction *action); + static void pw3270_action_activate(GAction *action, GVariant *parameter); + + static gboolean get_enabled(GAction *action, GtkWidget *terminal); + static void activate(GAction *action, GVariant *parameter, GtkWidget *terminal); + static void change_widget(GAction *action, GtkWidget *from, GtkWidget *to); static void finalize(GObject *object); @@ -66,20 +73,18 @@ iface->activate = pw3270_action_activate; } - static gboolean return_false(GAction G_GNUC_UNUSED(*action), GtkWidget G_GNUC_UNUSED(*window)) { - return FALSE; - } - void pw3270Action_class_init(pw3270ActionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); + klass->change_widget = change_widget; + klass->get_enabled = get_enabled; + klass->activate = activate; + object_class->finalize = finalize; object_class->set_property = pw3270_action_set_property; object_class->get_property = pw3270_action_get_property; - klass->get_enabled = return_false; - // Install properties g_object_class_install_property(object_class, PROP_NAME, g_param_spec_string ("name", @@ -129,9 +134,9 @@ void pw3270Action_init(pw3270Action *action) { - action->name = NULL; - action->window = NULL; - action->state = NULL; + action->name = NULL; + action->terminal = NULL; + action->state = NULL; } @@ -139,6 +144,9 @@ pw3270Action * action = PW3270_ACTION(object); + if(action->terminal) + pw3270_action_set_terminal_widget(G_ACTION(object),NULL); + if(action->name) { debug("Finalizing action \"%s\"",action->name); @@ -242,23 +250,6 @@ return PW3270_ACTION(action)->state; } - gboolean pw3270_action_get_enabled(GAction *action) { - GtkWidget *window = PW3270_ACTION(action)->window; - - if(window) - return PW3270_ACTION_GET_CLASS(action)->get_enabled(action,window); - - return FALSE; - } - - void pw3270_action_activate(GAction *action, GVariant *parameter) { - GtkWidget *window = PW3270_ACTION(action)->window; - - if(window) - PW3270_ACTION_GET_CLASS(action)->activate(action,window); - - } - const GVariantType * pw3270_action_get_parameter_type(GAction *action) { debug("%s",__FUNCTION__); return NULL; @@ -280,11 +271,97 @@ return NULL; } - void pw3270_action_change_state(GAction *action, GVariant *value) { - debug("%s",__FUNCTION__); - pw3270_action_set_state (action, value); + void pw3270_action_change_state(GAction *object, GVariant *value) { + + /* + pw3270Action * action = PW3270_ACTION(object); + + if (g_signal_has_handler_pending(object, pw3270_action_signals[SIGNAL_CHANGE_STATE], 0, TRUE)) + g_signal_emit(action, pw3270_action_signals[SIGNAL_CHANGE_STATE], 0, value); + */ + + pw3270_action_set_state(object, value); + } - void pw3270_action_set_state(GAction *action, GVariant *value) { + void pw3270_action_set_state(GAction *object, GVariant *value) { + + if(value) { + + pw3270Action * action = PW3270_ACTION(object); + + g_variant_ref_sink(value); + + if (!action->state || !g_variant_equal(action->state, value)) { + + if(action->state) + g_variant_unref(action->state); + + action->state = g_variant_ref(value); + + g_object_notify(G_OBJECT(object), "state"); + } + + g_variant_unref(value); + + } + + } + + static void change_widget(GAction *action, GtkWidget G_GNUC_UNUSED(*from), GtkWidget *to) { + PW3270_ACTION(action)->terminal = to; + } + + void pw3270_action_set_terminal_widget(GAction *object, GtkWidget *widget) { + + g_return_if_fail(PW3270_IS_ACTION(object) && GTK_IS_V3270(widget)); + + pw3270Action * action = PW3270_ACTION(object); + + if(action->terminal != widget) { + PW3270_ACTION_GET_CLASS(object)->change_widget(object,action->terminal,widget); + action->terminal = widget; + } + + } + + void pw3270_action_change_state_boolean(GAction *action, gboolean state) { + pw3270_action_change_state(action,g_variant_new_boolean(state)); + } + + gboolean pw3270_action_get_enabled(GAction *object) { + + pw3270Action * action = PW3270_ACTION(object); + + debug("%s: terminal=%p",__FUNCTION__,action->terminal); + + if(action && action->terminal) { + + return PW3270_ACTION_GET_CLASS(object)->get_enabled(object,action->terminal); + + } + + return FALSE; + + } + + void pw3270_action_activate(GAction *object, GVariant *parameter) { + + pw3270Action * action = PW3270_ACTION(object); + + debug("%s: terminal=%p",__FUNCTION__,action->terminal); + + if(action && action->terminal) { + return PW3270_ACTION_GET_CLASS(object)->activate(object,parameter,action->terminal); + } + + } + + gboolean get_enabled(GAction *object, GtkWidget *terminal) { debug("%s",__FUNCTION__); + return TRUE; + } + + void activate(GAction *action, GVariant G_GNUC_UNUSED(*parameter), GtkWidget G_GNUC_UNUSED(*terminal)) { + g_message("Action %s can't be activated",pw3270_action_get_name(action)); } diff --git a/src/actions/lib3270/action.c b/src/actions/lib3270/action.c index 124d929..53095fd 100644 --- a/src/actions/lib3270/action.c +++ b/src/actions/lib3270/action.c @@ -33,7 +33,7 @@ */ #include "../private.h" - #include + #include #define PW3270_TYPE_LIB3270_ACTION (Lib3270Action_get_type()) #define PW3270_LIB3270_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), PW3270_TYPE_LIB3270_ACTION, Lib3270Action)) @@ -56,48 +56,33 @@ G_DEFINE_TYPE(Lib3270Action, Lib3270Action, PW3270_TYPE_ACTION); - static gboolean action_enabled(GAction *action, GtkWidget *window) { - - H3270 * hSession = pw3270_window_get_session_handle(window); - - if(hSession) - return PW3270_LIB3270_ACTION(action)->definition->activatable(hSession) > 0 ? TRUE : FALSE; - - return FALSE; + static gboolean get_enabled(GAction *action, GtkWidget *terminal) { + return PW3270_LIB3270_ACTION(action)->definition->activatable(v3270_get_session(terminal)) > 0 ? TRUE : FALSE; } - static void action_activate(GAction *action, GtkWidget *window) { - - H3270 * hSession = pw3270_window_get_session_handle(window); - - debug("Activating action %s on hSession %p", pw3270_action_get_name(action), hSession); - - if(hSession) - PW3270_LIB3270_ACTION(action)->definition->activate(hSession); - else - g_message("Action \"%s\" requires a lib3270 session", pw3270_action_get_name(action)); - + static void activate(GAction *action, GVariant *parameter, GtkWidget *terminal) { + PW3270_LIB3270_ACTION(action)->definition->activate(v3270_get_session(terminal)); } void Lib3270Action_class_init(Lib3270ActionClass *klass) { - pw3270ActionClass * action = PW3270_ACTION_CLASS(klass); + pw3270ActionClass * action = PW3270_ACTION_CLASS(klass); - action->get_enabled = action_enabled; - action->activate = action_activate; + action->activate = activate; + action->get_enabled = get_enabled; } void Lib3270Action_init(Lib3270Action *action) { } - GAction * pw3270_action_new_from_lib3270(const LIB3270_ACTION * definition, GtkWidget *window) { + GAction * pw3270_action_new_from_lib3270(const LIB3270_ACTION * definition) { Lib3270Action * action = (Lib3270Action *) g_object_new(PW3270_TYPE_LIB3270_ACTION, NULL); - pw3270Action * abstract = PW3270_ACTION(action); - action->definition = definition; - abstract->window = window; + + // Setup the default name. + pw3270Action * abstract = PW3270_ACTION(action); if(abstract->name) g_free(abstract->name); diff --git a/src/actions/lib3270/toggle.c b/src/actions/lib3270/toggle.c index 4e18a36..a52ca59 100644 --- a/src/actions/lib3270/toggle.c +++ b/src/actions/lib3270/toggle.c @@ -34,9 +34,10 @@ #include "../private.h" #include + #include #define PW3270_TYPE_LIB3270_TOGGLE_ACTION (Lib3270ToggleAction_get_type()) - #define PW3270_LIB3270_TOGGLE_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), PW3270_TYPE_LIB3270_TOGGLE_ACTION, Lib3270Action)) + #define PW3270_LIB3270_TOGGLE_ACTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), PW3270_TYPE_LIB3270_TOGGLE_ACTION, Lib3270ToggleAction)) #define PW3270_IS_LIB3270_TOGGLE_ACTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), PW3270_TYPE_LIB3270_TOGGLE_ACTION)) typedef struct _Lib3270ToggleActionClass { @@ -47,45 +48,54 @@ typedef struct _Lib3270ToggleAction { pw3270Action parent; - const LIB3270_TOGGLE_ENTRY * definition; + const LIB3270_TOGGLE * definition; + const void * listener; } Lib3270ToggleAction; - static void Lib3270ToggleAction_class_init(Lib3270ActionClass *klass); - static void Lib3270ToggleAction_init(Lib3270Action *action); + static void Lib3270ToggleAction_class_init(Lib3270ToggleActionClass *klass); + static void Lib3270ToggleAction_init(Lib3270ToggleAction *action); G_DEFINE_TYPE(Lib3270ToggleAction, Lib3270ToggleAction, PW3270_TYPE_ACTION); - static gboolean action_enabled(GAction *action, GtkWidget *window) { - - - return FALSE; + static void change_state(H3270 *hSession, LIB3270_TOGGLE_ID id, char state, void * action) { + pw3270_action_change_state_boolean(PW3270_ACTION(action), state == 0 ? FALSE : TRUE); } - static void action_activate(GAction *action, GtkWidget *window) { + static void change_widget(GAction *object, GtkWidget *from, GtkWidget *to) { + Lib3270ToggleAction * action = PW3270_LIB3270_TOGGLE_ACTION(object); - } + if(action->listener) { + lib3270_unregister_toggle_listener(v3270_get_session(from),action->definition->id,object); + } - void Lib3270Action_class_init(Lib3270ActionClass *klass) { + if(to) { + action->listener = lib3270_register_toggle_listener(v3270_get_session(from),action->definition->id,change_state,object); + pw3270_action_change_state_boolean(object,lib3270_get_toggle(v3270_get_session(to),action->definition->id)); + } - pw3270ActionClass * action = PW3270_TOGGLE_ACTION_CLASS(klass); + PW3270_ACTION_CLASS(Lib3270ToggleAction_parent_class)->change_widget(object,from,to); - action->get_enabled = action_enabled; - action->activate = action_activate; + } + void Lib3270ToggleAction_class_init(Lib3270ToggleActionClass *klass) { } - void Lib3270Action_init(Lib3270Action *action) { + void Lib3270ToggleAction_init(Lib3270ToggleAction *action) { + + action->definition = NULL; + action->listener = NULL; + } - GAction * pw3270_toggle_action_new_from_lib3270(const LIB3270_TOGGLE_ENTRY * definition, GtkWidget *window) { + GAction * pw3270_toggle_action_new_from_lib3270(const LIB3270_TOGGLE * definition) { - Lib3270Action * action = (Lib3270Action *) g_object_new(PW3270_TYPE_LIB3270_TOGGLE_ACTION, NULL); - pw3270Action * abstract = PW3270_ACTION(action); + Lib3270ToggleAction * action = (Lib3270ToggleAction *) g_object_new(PW3270_TYPE_LIB3270_TOGGLE_ACTION, NULL); + action->definition = definition; - action->definition = definition; - abstract->window = window; + // Setup the default name. + pw3270Action * abstract = PW3270_ACTION(action); if(abstract->name) g_free(abstract->name); @@ -93,6 +103,7 @@ abstract->name = g_strconcat("win.",definition->name,NULL); return G_ACTION(action); + } diff --git a/src/actions/private.h b/src/actions/private.h index a5ec49e..32b0cd1 100644 --- a/src/actions/private.h +++ b/src/actions/private.h @@ -42,6 +42,10 @@ #include #include + + #include + #include + #include struct _pw3270Action { @@ -49,7 +53,7 @@ GVariantType * parameter_type; GVariant * state; - GtkWidget * window; + GtkWidget * terminal; gchar * name; }; @@ -57,9 +61,16 @@ struct _pw3270ActionClass { GObjectClass parent_class; - gboolean (*get_enabled)(GAction *action, GtkWidget *window); - void (*activate)(GAction *action, GtkWidget *window); + void (*change_widget)(GAction *action, GtkWidget *from, GtkWidget *to); + gboolean (*get_enabled)(GAction *action, GtkWidget *terminal); + void (*activate)(GAction *action, GVariant *parameter, GtkWidget *terminal); }; + G_GNUC_INTERNAL GAction * pw3270_action_new_from_lib3270(const LIB3270_ACTION * definition); + G_GNUC_INTERNAL GAction * pw3270_toggle_action_new_from_lib3270(const LIB3270_TOGGLE * definition); + + G_GNUC_INTERNAL void pw3270_action_change_state_boolean(GAction *action, gboolean state); + + #endif // PRIVATE_H_INCLUDED diff --git a/src/actions/testprogram/testprogram.c b/src/actions/testprogram/testprogram.c index e3ce2e8..c4e84a1 100644 --- a/src/actions/testprogram/testprogram.c +++ b/src/actions/testprogram/testprogram.c @@ -40,9 +40,11 @@ return g_object_get_data(G_OBJECT(window), "v3270_terminal"); } + /* H3270 * pw3270_window_get_session_handle(GtkWidget *window) { return v3270_get_session(pw3270_window_get_terminal_widget(window)); } + */ static gboolean handle_command(GtkWidget *trace, const gchar *cmd, const gchar *args, GtkWidget *window) { diff --git a/src/actions/window.c b/src/actions/window.c index 3c9578e..16e2184 100644 --- a/src/actions/window.c +++ b/src/actions/window.c @@ -37,11 +37,13 @@ void pw3270_window_add_actions(GtkWidget * appwindow) { - GActionMap *map = G_ACTION_MAP(appwindow); + GActionMap * map = G_ACTION_MAP(appwindow); + GtkWidget * terminal = pw3270_window_get_terminal_widget(appwindow); // g_action_map_add_action(map,pw3270_action_new_from_lib3270(lib3270_action_get_by_name("testpattern"), appwindow)); - GAction *action = pw3270_action_new_from_lib3270(lib3270_action_get_by_name("testpattern"), appwindow); + GAction *action = pw3270_action_new_from_lib3270(lib3270_action_get_by_name("testpattern")); + pw3270_action_set_terminal_widget(action,terminal); debug("--> \"%s\"",pw3270_action_get_name(action)); diff --git a/src/include/pw3270/actions.h b/src/include/pw3270/actions.h index 2b8791b..1392af1 100644 --- a/src/include/pw3270/actions.h +++ b/src/include/pw3270/actions.h @@ -38,7 +38,6 @@ #include #include - #include G_BEGIN_DECLS @@ -54,14 +53,14 @@ GType pw3270Action_get_type(void) G_GNUC_CONST; - GAction * pw3270_action_new_from_lib3270(const LIB3270_ACTION * definition, GtkWidget *window); - GAction * pw3270_toggle_action_new_from_lib3270(const LIB3270_TOGGLE_ENTRY * definition, GtkWidget *window); - const gchar * pw3270_action_get_name(GAction *action); void pw3270_action_set_name(GAction *action, const gchar *name); - gboolean pw3270_action_get_enabled(GAction *action); - void pw3270_action_activate(GAction *action, GVariant *parameter); + /// @brief Associate action with the terminal widget. + void pw3270_action_set_terminal_widget(GAction *action, GtkWidget *terminal); + + /// @brief Get lib3270 session handle. + H3270 * pw3270_action_get_session(GAction *action); /// @brief Add lib3270 actions to an application window. void pw3270_window_add_actions(GtkWidget * appwindow); -- libgit2 0.21.2