From 00e3b6b50747e8d5efc8823502ac5ff7cfbd5278 Mon Sep 17 00:00:00 2001 From: perry.werneck@gmail.com Date: Wed, 18 Apr 2012 13:45:35 +0000 Subject: [PATCH] Convertendo janela principal em um widget independente --- src/gtk/main.c | 17 +++++++++++------ src/gtk/v3270/v3270.h | 1 + src/gtk/v3270/widget.c | 12 +++++++++--- src/gtk/window.c | 381 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/include/pw3270.h | 17 +++++++++++++++++ 5 files changed, 248 insertions(+), 180 deletions(-) diff --git a/src/gtk/main.c b/src/gtk/main.c index eb75d0e..ac18c5c 100644 --- a/src/gtk/main.c +++ b/src/gtk/main.c @@ -154,13 +154,18 @@ int main(int argc, char *argv[]) { configuration_init(); - toplevel = create_main_window(host); + toplevel = pw3270_new(host); - if(toplevel) - { - gtk_window_present(GTK_WINDOW(toplevel)); - gtk_main(); - } + gtk_window_set_type_hint(GTK_WINDOW(toplevel),GDK_WINDOW_TYPE_HINT_NORMAL); + gtk_window_set_position(GTK_WINDOW(toplevel),GTK_WIN_POS_CENTER); + gtk_window_set_role(GTK_WINDOW(toplevel),"toplevel"); + + gtk_window_present(GTK_WINDOW(toplevel)); + + if(pw3270_get_toggle(toplevel,LIB3270_TOGGLE_FULL_SCREEN)) + gtk_window_fullscreen(GTK_WINDOW(toplevel)); + + gtk_main(); configuration_deinit(); } diff --git a/src/gtk/v3270/v3270.h b/src/gtk/v3270/v3270.h index ff5a41b..e531cf7 100644 --- a/src/gtk/v3270/v3270.h +++ b/src/gtk/v3270/v3270.h @@ -178,6 +178,7 @@ GtkIMContext * v3270_get_im_context(GtkWidget *widget); gboolean v3270_get_toggle(GtkWidget *widget, LIB3270_TOGGLE ix); + void v3270_set_host(GtkWidget *widget, const gchar *uri); G_END_DECLS diff --git a/src/gtk/v3270/widget.c b/src/gtk/v3270/widget.c index 5bca397..81878a0 100644 --- a/src/gtk/v3270/widget.c +++ b/src/gtk/v3270/widget.c @@ -1203,13 +1203,19 @@ GtkIMContext * v3270_get_im_context(GtkWidget *widget) return GTK_V3270(widget)->input_method; } - gboolean v3270_get_toggle(GtkWidget *widget, LIB3270_TOGGLE ix) - { +gboolean v3270_get_toggle(GtkWidget *widget, LIB3270_TOGGLE ix) +{ g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); if(ix < LIB3270_TOGGLE_COUNT) return lib3270_get_toggle(GTK_V3270(widget)->host,ix) ? TRUE : FALSE; return FALSE; - } +} +void v3270_set_host(GtkWidget *widget, const gchar *uri) +{ + g_return_if_fail(GTK_IS_V3270(widget)); + g_return_if_fail(uri != NULL); + lib3270_set_host(GTK_V3270(widget)->host,uri); +} diff --git a/src/gtk/window.c b/src/gtk/window.c index 827eac0..5f4047f 100644 --- a/src/gtk/window.c +++ b/src/gtk/window.c @@ -32,9 +32,23 @@ #include "globals.h" #include "uiparser/parser.h" -#ifdef DEBUG - #include -#endif + +/*--[ Widget definition ]----------------------------------------------------------------------------*/ + + struct _pw3270 + { + GtkWindow parent; + GtkWidget * terminal; + }; + + struct _pw3270Class + { + GtkWindowClass parent_class; + + int dummy; + }; + + G_DEFINE_TYPE(pw3270, pw3270, GTK_TYPE_WINDOW); /*--[ Globals ]--------------------------------------------------------------------------------------*/ @@ -80,30 +94,25 @@ /*--[ Implement ]------------------------------------------------------------------------------------*/ - static void toggle_changed(GtkWidget *widget, LIB3270_TOGGLE id, gboolean toggled, const gchar *name, GtkWindow *toplevel) +#if GTK_CHECK_VERSION(3,0,0) + static void pw3270_destroy(GtkWidget *widget) +#else + static void pw3270_destroy(GtkObject *widget) +#endif { - GtkAction **list = (GtkAction **) g_object_get_data(G_OBJECT(widget),"toggle_actions"); - gchar *nm = g_ascii_strdown(name,-1); - set_boolean_to_config("toggle",nm,toggled); - g_free(nm); + pw3270 * window = GTK_PW3270(widget); - if(id == LIB3270_TOGGLE_FULL_SCREEN) - { - if(toggled) - gtk_window_fullscreen(GTK_WINDOW(toplevel)); - else - gtk_window_unfullscreen(GTK_WINDOW(toplevel)); - } + trace("%s %p",__FUNCTION__,widget); - if(list[id]) - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(list[id]),toggled); + if(window->terminal) + v3270_disconnect(window->terminal); } - static gboolean window_state_event(GtkWidget *window, GdkEventWindowState *event, GtkWidget *widget) + static gboolean window_state_event(GtkWidget *window, GdkEventWindowState *event, GtkWidget *widget) { - gboolean fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN ? TRUE : FALSE; - GtkAction **action = (GtkAction **) g_object_get_data(G_OBJECT(widget),"named_actions"); + gboolean fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN ? TRUE : FALSE; + GtkAction **action = (GtkAction **) g_object_get_data(G_OBJECT(widget),"named_actions"); // Update fullscreen toggles if(action[ACTION_FULLSCREEN]) @@ -117,85 +126,55 @@ return 0; } - static gboolean window_destroy(GtkWidget *window, GtkWidget *widget) + static void pw3270_class_init(pw3270Class *klass) { - if(widget) - v3270_disconnect(widget); - } + GObjectClass * gobject_class = G_OBJECT_CLASS(klass); + GtkWidgetClass * widget_class = GTK_WIDGET_CLASS(klass); +// GtkWindowClass * window_class = GTK_WINDOW_CLASS(klass); - static void disconnected(GtkWidget *widget, GtkActionGroup **group) - { - gtk_action_group_set_sensitive(group[ACTION_GROUP_PASTE],FALSE); - gtk_action_group_set_sensitive(group[ACTION_GROUP_ONLINE],FALSE); - gtk_action_group_set_sensitive(group[ACTION_GROUP_OFFLINE],TRUE); - gtk_window_set_title(GTK_WINDOW(gtk_widget_get_toplevel(widget)),g_get_application_name()); - } - - static void connected(GtkWidget *widget, const gchar *host, GtkActionGroup **group) - { - set_string_to_config("host","uri","%s",host); - gtk_window_set_title(GTK_WINDOW(gtk_widget_get_toplevel(widget)),host); - gtk_action_group_set_sensitive(group[ACTION_GROUP_ONLINE],TRUE); - gtk_action_group_set_sensitive(group[ACTION_GROUP_OFFLINE],FALSE); - gtk_action_group_set_sensitive(group[ACTION_GROUP_PASTE],TRUE); - } - - static void update_config(GtkWidget *widget, const gchar *name, const gchar *value) - { - set_string_to_config("terminal",name,"%s",value); - } +#if GTK_CHECK_VERSION(3,0,0) + widget_class->destroy = pw3270_destroy; +#else + { + GtkObjectClass *object_class = (GtkObjectClass*) klass; + object_class->destroy = pw3270_destroy; + } +#endif // GTK3 - static void update_model(GtkWidget *widget, guint id, const gchar *name) - { - trace("Widget %p changed to %s (id=%d)",widget,name,id); - set_integer_to_config("terminal","model",id); } - static gboolean popup_menu(GtkWidget *widget, gboolean selected, gboolean online, GdkEventButton *event, GtkWidget **popup) + GtkWidget * pw3270_new(const gchar *host) { - GtkWidget *menu = NULL; + GtkWidget *widget = g_object_new(GTK_TYPE_PW3270, NULL); - if(!online) - menu = popup[POPUP_OFFLINE]; - else if(selected && popup[POPUP_SELECTION]) - menu = popup[POPUP_SELECTION]; - else if(popup[POPUP_ONLINE]) - menu = popup[POPUP_ONLINE]; + if(host) + { + pw3270_set_host(widget,host); + } else - menu = popup[POPUP_DEFAULT]; - - trace("Popup %p on widget %p online=%s selected=%s",menu,widget,online ? "Yes" : "No", selected ? "Yes" : "No"); - - if(!menu) - return FALSE; - - trace("Showing popup \"%s\"",gtk_widget_get_name(menu)); - - gtk_widget_show_all(menu); - gtk_menu_set_screen(GTK_MENU(menu), gtk_widget_get_screen(widget)); - gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button,event->time); - - return TRUE; - } - - static void selecting(GtkWidget *widget, gboolean on, GtkActionGroup **group) - { - GtkAction **action = (GtkAction **) g_object_get_data(G_OBJECT(widget),"named_actions"); - gtk_action_group_set_sensitive(group[ACTION_GROUP_SELECTION],on); + { + gchar *ptr = get_string_from_config("host","uri",""); + if(*ptr) + pw3270_set_host(widget,ptr); + g_free(ptr); + } - if(action[ACTION_RESELECT]) - gtk_action_set_sensitive(action[ACTION_RESELECT],!on); + if(pw3270_get_toggle(widget,LIB3270_TOGGLE_CONNECT_ON_STARTUP)) + v3270_connect(GTK_PW3270(widget)->terminal,NULL); + return widget; } - static void has_text(GtkWidget *widget, gboolean on, GtkActionGroup **group) + void pw3270_set_host(GtkWidget *widget, const gchar *uri) { - gtk_action_group_set_sensitive(group[ACTION_GROUP_CLIPBOARD],on); + g_return_if_fail(GTK_IS_PW3270(widget)); + v3270_set_host(GTK_PW3270(widget)->terminal,uri); } - static void pastenext(GtkWidget *widget, gboolean on, GtkAction **action) + gboolean pw3270_get_toggle(GtkWidget *widget, LIB3270_TOGGLE ix) { - gtk_action_set_sensitive(action[ACTION_PASTENEXT],on); + g_return_if_fail(GTK_IS_PW3270(widget)); + return v3270_get_toggle(GTK_PW3270(widget)->terminal,ix); } static void setup_input_method(GtkWidget *widget, GtkWidget *obj) @@ -251,24 +230,102 @@ gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget),menu); } - static void set_icon_list(GtkWindow *window) + static void pastenext(GtkWidget *widget, gboolean on, GtkAction **action) { - gchar * name = g_strdup_printf("%s.png",g_get_application_name()); - gchar * filename = build_data_filename(name,NULL); - GError * error = NULL; + gtk_action_set_sensitive(action[ACTION_PASTENEXT],on); + } - if(!gtk_window_set_icon_from_file(window,filename,&error)) + static void disconnected(GtkWidget *widget, GtkActionGroup **group) + { + gtk_action_group_set_sensitive(group[ACTION_GROUP_PASTE],FALSE); + gtk_action_group_set_sensitive(group[ACTION_GROUP_ONLINE],FALSE); + gtk_action_group_set_sensitive(group[ACTION_GROUP_OFFLINE],TRUE); + gtk_window_set_title(GTK_WINDOW(gtk_widget_get_toplevel(widget)),g_get_application_name()); + } + + static void connected(GtkWidget *widget, const gchar *host, GtkActionGroup **group) + { + set_string_to_config("host","uri","%s",host); + gtk_window_set_title(GTK_WINDOW(gtk_widget_get_toplevel(widget)),host); + gtk_action_group_set_sensitive(group[ACTION_GROUP_ONLINE],TRUE); + gtk_action_group_set_sensitive(group[ACTION_GROUP_OFFLINE],FALSE); + gtk_action_group_set_sensitive(group[ACTION_GROUP_PASTE],TRUE); + } + + static void update_config(GtkWidget *widget, const gchar *name, const gchar *value) + { + set_string_to_config("terminal",name,"%s",value); + } + + static void update_model(GtkWidget *widget, guint id, const gchar *name) + { + trace("Widget %p changed to %s (id=%d)",widget,name,id); + set_integer_to_config("terminal","model",id); + } + + static void selecting(GtkWidget *widget, gboolean on, GtkActionGroup **group) + { + GtkAction **action = (GtkAction **) g_object_get_data(G_OBJECT(widget),"named_actions"); + gtk_action_group_set_sensitive(group[ACTION_GROUP_SELECTION],on); + + if(action[ACTION_RESELECT]) + gtk_action_set_sensitive(action[ACTION_RESELECT],!on); + + } + + static gboolean popup_menu(GtkWidget *widget, gboolean selected, gboolean online, GdkEventButton *event, GtkWidget **popup) + { + GtkWidget *menu = NULL; + + if(!online) + menu = popup[POPUP_OFFLINE]; + else if(selected && popup[POPUP_SELECTION]) + menu = popup[POPUP_SELECTION]; + else if(popup[POPUP_ONLINE]) + menu = popup[POPUP_ONLINE]; + else + menu = popup[POPUP_DEFAULT]; + + trace("Popup %p on widget %p online=%s selected=%s",menu,widget,online ? "Yes" : "No", selected ? "Yes" : "No"); + + if(!menu) + return FALSE; + + trace("Showing popup \"%s\"",gtk_widget_get_name(menu)); + + gtk_widget_show_all(menu); + gtk_menu_set_screen(GTK_MENU(menu), gtk_widget_get_screen(widget)); + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button,event->time); + + return TRUE; + } + + static void has_text(GtkWidget *widget, gboolean on, GtkActionGroup **group) + { + gtk_action_group_set_sensitive(group[ACTION_GROUP_CLIPBOARD],on); + } + + static void toggle_changed(GtkWidget *widget, LIB3270_TOGGLE id, gboolean toggled, const gchar *name, GtkWindow *toplevel) + { + GtkAction **list = (GtkAction **) g_object_get_data(G_OBJECT(widget),"toggle_actions"); + gchar *nm = g_ascii_strdown(name,-1); + set_boolean_to_config("toggle",nm,toggled); + g_free(nm); + + if(id == LIB3270_TOGGLE_FULL_SCREEN) { - g_warning("Error %s loading icon from %s",error->message,filename); - g_error_free(error); + if(toggled) + gtk_window_fullscreen(GTK_WINDOW(toplevel)); + else + gtk_window_unfullscreen(GTK_WINDOW(toplevel)); } - g_free(filename); - g_free(name); + if(list[id]) + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(list[id]),toggled); } - GtkWidget * create_main_window(const gchar *uri) + static void pw3270_init(pw3270 *widget) { static const UI_WIDGET_SETUP widget_setup[] = { @@ -288,41 +345,22 @@ { "font-family", v3270_set_font_family } }; - GtkWidget * window; - GtkWidget * terminal = v3270_new(); - H3270 * host = v3270_get_session(terminal); - gchar * path = build_data_filename("ui",NULL); - GtkActionGroup **group; - GtkAction **action = g_new0(GtkAction *,ACTION_COUNT); - GtkWidget **popup; - int f; - - gtk_widget_set_tooltip_text(terminal,_( "3270 screen")); - - if(uri) - { - lib3270_set_host(host,uri); - } - else - { - gchar *ptr = get_string_from_config("host","uri",""); - if(*ptr) - lib3270_set_host(host,ptr); - g_free(ptr); - } + int f; + GtkAction **action = g_new0(GtkAction *,ACTION_COUNT); + H3270 * host; - g_object_set_data_full(G_OBJECT(terminal),"toggle_actions",g_new0(GtkAction *,LIB3270_TOGGLE_COUNT),g_free); - g_object_set_data_full(G_OBJECT(terminal),"named_actions",(gpointer) action, (GDestroyNotify) g_free); + // Initialize terminal widget + widget->terminal = v3270_new(); + host = v3270_get_session(widget->terminal); - // Initialize terminal config for(f=0;fterminal,str); if(str) g_free(str); } - lib3270_set_model(host,get_integer_from_config("terminal","model",2)); + lib3270_set_model(v3270_get_session(widget->terminal),get_integer_from_config("terminal","model",2)); for(f=0;fterminal),"toggle_actions",g_new0(GtkAction *,LIB3270_TOGGLE_COUNT),g_free); + g_object_set_data_full(G_OBJECT(widget->terminal),"named_actions",(gpointer) action, (GDestroyNotify) g_free); - if(ui_parse_xml_folder(GTK_WINDOW(window),path,groupname,popupname,terminal,widget_setup)) + // Load UI { - g_object_unref(terminal); - g_object_unref(window); - return NULL; + gchar *path = build_data_filename("ui",NULL); + + if(ui_parse_xml_folder(GTK_WINDOW(widget),path,groupname,popupname,widget->terminal,widget_setup)) + { + g_free(path); + gtk_widget_set_sensitive(widget->terminal,FALSE); + return; + } + + g_free(path); } - group = g_object_get_data(G_OBJECT(window),"action_groups"); - popup = g_object_get_data(G_OBJECT(window),"popup_menus"); - // Setup action groups - gtk_action_group_set_sensitive(group[ACTION_GROUP_SELECTION],FALSE); - gtk_action_group_set_sensitive(group[ACTION_GROUP_CLIPBOARD],FALSE); - gtk_action_group_set_sensitive(group[ACTION_GROUP_FILETRANSFER],FALSE); - gtk_action_group_set_sensitive(group[ACTION_GROUP_PASTE],FALSE); - disconnected(terminal, (gpointer) group); // Setup actions - if(action[ACTION_FULLSCREEN]) - gtk_action_set_visible(action[ACTION_FULLSCREEN],!lib3270_get_toggle(host,LIB3270_TOGGLE_FULL_SCREEN)); + { + GtkWidget **popup = g_object_get_data(G_OBJECT(widget),"popup_menus"); + GtkActionGroup **group = g_object_get_data(G_OBJECT(widget),"action_groups"); - if(action[ACTION_UNFULLSCREEN]) - gtk_action_set_visible(action[ACTION_UNFULLSCREEN],lib3270_get_toggle(host,LIB3270_TOGGLE_FULL_SCREEN)); + // Setup action groups + gtk_action_group_set_sensitive(group[ACTION_GROUP_SELECTION],FALSE); + gtk_action_group_set_sensitive(group[ACTION_GROUP_CLIPBOARD],FALSE); + gtk_action_group_set_sensitive(group[ACTION_GROUP_FILETRANSFER],FALSE); + gtk_action_group_set_sensitive(group[ACTION_GROUP_PASTE],FALSE); - if(action[ACTION_PASTENEXT]) - { - gtk_action_set_sensitive(action[ACTION_PASTENEXT],FALSE); - g_signal_connect(terminal,"pastenext",G_CALLBACK(pastenext),action); - } + disconnected(widget->terminal, (gpointer) group); - if(action[ACTION_RESELECT]) - gtk_action_set_sensitive(action[ACTION_RESELECT],FALSE); + // Setup actions + if(action[ACTION_FULLSCREEN]) + gtk_action_set_visible(action[ACTION_FULLSCREEN],!lib3270_get_toggle(host,LIB3270_TOGGLE_FULL_SCREEN)); - // Connect window signals - g_signal_connect(window,"window_state_event",G_CALLBACK(window_state_event),terminal); - g_signal_connect(window,"destroy",G_CALLBACK(window_destroy),terminal); + if(action[ACTION_UNFULLSCREEN]) + gtk_action_set_visible(action[ACTION_UNFULLSCREEN],lib3270_get_toggle(host,LIB3270_TOGGLE_FULL_SCREEN)); - // Connect widget signals - g_signal_connect(terminal,"toggle_changed",G_CALLBACK(toggle_changed),window); - g_signal_connect(terminal,"disconnected",G_CALLBACK(disconnected),group); - g_signal_connect(terminal,"connected",G_CALLBACK(connected),group); - 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_menu),popup); - g_signal_connect(terminal,"has_text",G_CALLBACK(has_text),group); + if(action[ACTION_PASTENEXT]) + { + gtk_action_set_sensitive(action[ACTION_PASTENEXT],FALSE); + g_signal_connect(widget->terminal,"pastenext",G_CALLBACK(pastenext),action); + } - g_free(path); + if(action[ACTION_RESELECT]) + gtk_action_set_sensitive(action[ACTION_RESELECT],FALSE); + // Connect action signals + g_signal_connect(widget->terminal,"disconnected",G_CALLBACK(disconnected),group); + g_signal_connect(widget->terminal,"connected",G_CALLBACK(connected),group); + g_signal_connect(widget->terminal,"update_config",G_CALLBACK(update_config),0); + g_signal_connect(widget->terminal,"model_changed",G_CALLBACK(update_model),0); + g_signal_connect(widget->terminal,"selecting",G_CALLBACK(selecting),group); + g_signal_connect(widget->terminal,"popup",G_CALLBACK(popup_menu),popup); + g_signal_connect(widget->terminal,"has_text",G_CALLBACK(has_text),group); - // Initialize terminal - if(v3270_get_toggle(terminal,LIB3270_TOGGLE_FULL_SCREEN)) - gtk_window_fullscreen(GTK_WINDOW(window)); + } + // Connect widget signals + g_signal_connect(widget->terminal,"toggle_changed",G_CALLBACK(toggle_changed),widget); + + // Connect window signals + g_signal_connect(widget,"window_state_event",G_CALLBACK(window_state_event),widget->terminal); + + + // Finish setup #ifdef DEBUG lib3270_testpattern(host); #endif trace("%s ends",__FUNCTION__); - gtk_window_set_focus(GTK_WINDOW(window),terminal); - - if(v3270_get_toggle(terminal,LIB3270_TOGGLE_CONNECT_ON_STARTUP)) - lib3270_connect(host,NULL,0); + gtk_window_set_focus(GTK_WINDOW(widget),widget->terminal); - return window; } - - - diff --git a/src/include/pw3270.h b/src/include/pw3270.h index 2ec391d..cb91f7f 100644 --- a/src/include/pw3270.h +++ b/src/include/pw3270.h @@ -40,6 +40,7 @@ #endif #include + #include // Trace #include @@ -82,8 +83,24 @@ #endif + // pw3270 window + G_BEGIN_DECLS + #define GTK_TYPE_PW3270 (pw3270_get_type ()) + #define GTK_PW3270(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PW3270, pw3270)) + #define GTK_PW3270_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PW3270, pw3270Class)) + #define GTK_IS_PW3270(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PW3270)) + #define GTK_IS_PW3270_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PW3270)) + #define GTK_PW3270_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PW3270, pw3270Class)) + typedef struct _pw3270 pw3270; + typedef struct _pw3270Class pw3270Class; + GtkWidget * pw3270_new(const gchar *host); + void pw3270_set_host(GtkWidget *widget, const gchar *uri); + gboolean pw3270_get_toggle(GtkWidget *widget, LIB3270_TOGGLE ix); + + G_END_DECLS + #endif // PW3270_H_INCLUDED -- libgit2 0.21.2