#include #include #include #include #include #include #include #include #include "config.h" #ifdef WITH_HILDON #include #include #endif #include "web.h" #include "web_utils.h" #include "web_history.h" #include "web_bookmarks.h" #include "web_request.h" static void copy_cb (GtkWindow *main_window) { GtkWidget *widget = gtk_window_get_focus (main_window); if (widget) { if (GTK_IS_EDITABLE (widget)) gtk_editable_copy_clipboard (GTK_EDITABLE (widget)); else if (GTK_IS_TEXT_VIEW (widget)) { GtkTextBuffer *buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW (widget)); gtk_text_buffer_copy_clipboard (buffer, gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)); } else if (GTK_IS_LABEL (widget)) { gint start, end; if (gtk_label_get_selection_bounds (GTK_LABEL (widget), &start, &end)) { const gchar *text = gtk_label_get_text (GTK_LABEL (widget)); gchar *start_text = g_utf8_offset_to_pointer (text, start); gchar *copy_text = g_strndup (start_text, end-start); gtk_clipboard_set_text ( gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), copy_text, end-start); g_free (copy_text); } } } } static void cut_cb (GtkWindow *main_window) { GtkWidget *widget = gtk_window_get_focus (main_window); if (widget) { if (GTK_IS_EDITABLE (widget)) gtk_editable_cut_clipboard (GTK_EDITABLE (widget)); else if (GTK_IS_TEXT_VIEW (widget)) { GtkTextBuffer *buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW (widget)); gtk_text_buffer_cut_clipboard (buffer, gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), TRUE); } else copy_cb (main_window); } } static void paste_cb (GtkWindow *main_window) { GtkWidget *widget = gtk_window_get_focus (main_window); if (widget) { if (GTK_IS_EDITABLE (widget)) gtk_editable_paste_clipboard (GTK_EDITABLE (widget)); else if (GTK_IS_TEXT_VIEW (widget)) { GtkTextBuffer *buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW (widget)); gtk_text_buffer_paste_clipboard (buffer, gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), NULL, TRUE); } } } static void web_reset_url_entry (GladeXML *xml) { GtkWidget *widget = glade_xml_get_widget (xml, "url_notebook"); gtk_widget_hide (widget); gtk_notebook_prev_page (GTK_NOTEBOOK (widget)); gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( glade_xml_get_widget (xml, "go_togglebutton")), FALSE); } void web_stop_cb (GtkWidget *source, WebPages *pages, WebData *data) { if (pages) data = pages->current_page; g_list_foreach (data->requests, (GFunc)web_request_close, NULL); web_reset_url_entry (data->parent->xml); } static gboolean web_go_load_idle (gpointer data) { WebData *web_data = (WebData *)data; guint requests; GtkWidget *widget; if ((requests = g_list_length (web_data->requests)) > 0) { if (requests > web_data->max_requests) web_data->max_requests = requests; if (web_data->parent->current_page == web_data) { widget = glade_xml_get_widget ( web_data->parent->xml, "url_progressbar"); gtk_progress_bar_set_fraction ( GTK_PROGRESS_BAR (widget), 1.0 - (requests/(gdouble)web_data->max_requests)); } return TRUE; } else { if (web_data->parent->current_page == web_data) { web_reset_url_entry (web_data->parent->xml); } return FALSE; } } void web_go (WebData *data, const gchar *url, gboolean preserve_history) { gchar *abs_url, *new_base; /* Get absolute url and base url */ abs_url = web_get_abs_url (data->base_url, url); /* TODO: Display error page */ if (!abs_url) return; new_base = web_get_base_url (abs_url); g_free (data->base_url); data->base_url = new_base; web_stop_cb (NULL, NULL, data); data->parent->backend->clear (data->parent->backend_data, data->page_data); /*if (html_document_open_stream (data->document, "text/html"))*/ { WebRequest *request = g_new0 (WebRequest, 1); GtkWidget *widget; guint history_length; /* Change URL entry and switch to page load status tab */ widget = glade_xml_get_widget (data->parent->xml, "url_entry"); gtk_entry_set_text (GTK_ENTRY (widget), abs_url); widget = glade_xml_get_widget ( data->parent->xml, "url_notebook"); gtk_notebook_next_page (GTK_NOTEBOOK (widget)); gtk_widget_show (widget); widget = glade_xml_get_widget ( data->parent->xml, "url_progressbar"); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (widget), abs_url); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (widget), 0); /* Add url to history and previous url to history menu, * clear forward history. */ if (!preserve_history) { WebHistory *history = g_new0 (WebHistory, 1); history->url = g_strdup (abs_url); history->parent = data; data->history = g_list_append ( data->history, history); g_list_foreach (data->history_forward, (GFunc)web_history_free, NULL); g_list_free (data->history_forward); data->history_forward = NULL; history_length = g_list_length (data->history); if ((data->parent->current_page == data) && (history_length > 1)) { WebHistory *prev_hist = g_list_nth_data ( data->history, history_length - 2); web_history_append (prev_hist, data->parent); web_history_clear (data->parent, FALSE, TRUE); } } if (data->url) g_free (data->url); data->url = g_strdup (abs_url); request->parent = data; request->url = abs_url; request->type = WEB_LINK; web_request_perform (request); data->max_requests = 0; g_idle_add (web_go_load_idle, data); } } static void web_go_cb (GtkWidget *source, WebPages *pages) { WebData *data = pages->current_page; gchar *abs_url; const gchar *url = gtk_entry_get_text (GTK_ENTRY ( glade_xml_get_widget (pages->xml, "url_entry"))); if (strstr (url, "://") == NULL) abs_url = g_strconcat ("http://", url, NULL); else abs_url = g_strdup (url); gtk_widget_hide (glade_xml_get_widget (pages->xml, "bookmarks_window")); web_go (data, abs_url, FALSE); g_free (abs_url); } static void web_apply_ssr (WebPages *pages, WebData *data) { gchar *css; gchar *script; /* if (g_file_get_contents (DATADIR "minimo-userContent.css", &css, NULL, NULL)) { data->ssr_style = pages->backend->add_style ( pages->backend_data, data->page_data, css, NULL); g_free (css); } else g_warning ("Couldn't load CSS");*/ if (g_file_get_contents (DATADIR "ssr.user.js", &script, NULL, NULL)) { data->ssr_script = pages->backend->add_script ( pages->backend_data, data->page_data, script); g_free (script); } else g_warning ("Couldn't load SSR script"); } void web_title_change (WebData *data, const gchar *title) { WebHistory *history = g_list_last (data->history)->data; if (history->title) g_free (history->title); history->title = g_strdup (title); gtk_label_set_text (GTK_LABEL (data->url_label), title); if (data->parent->current_page == data) #ifdef WITH_HILDON hildon_app_set_title (data->parent->window, title); #else gtk_window_set_title (GTK_WINDOW (data->parent->window), title); #endif } static void web_gconf_zoom_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data) { WebPages *pages = user_data; GConfValue *value; value = gconf_entry_get_value (entry); pages->last_zoom = gconf_value_get_float (value); } static void web_gconf_home_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data) { WebPages *pages = user_data; const gchar *home; GConfValue *value; value = gconf_entry_get_value (entry); home = gconf_value_get_string (value); if (home && (strlen (home) > 0)) { g_free (pages->home); pages->home = g_strdup (home); } } static void web_gconf_ssr_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data) { WebPages *pages = user_data; GConfValue *value; gboolean old_ssr = pages->ssr; value = gconf_entry_get_value (entry); pages->ssr = gconf_value_get_bool (value); /* Turn on/off SSR */ if (old_ssr != pages->ssr) { GList *p; for (p = pages->pages; p; p = p->next) { WebData *data = p->data; if (pages->ssr) { web_apply_ssr (pages, data); } else if (data->ssr_style) { pages->backend->remove_style ( pages->backend_data, data->page_data, data->ssr_style); data->ssr_style = NULL; pages->backend->remove_script ( pages->backend_data, data->page_data, data->ssr_script); data->ssr_script = NULL; } } } } static void web_gconf_media_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data) { WebPages *pages = user_data; GConfValue *value; GList *p; const gchar *media; value = gconf_entry_get_value (entry); media = gconf_value_get_string (value); if (media && (strlen (pages->media) > 0)) { g_free (pages->media); pages->media = g_strdup (media); for (p = pages->pages; p; p = p->next) { WebData *data = p->data; pages->backend->set_media (pages->backend_data, data->page_data, pages->media); } } } static void web_resetzoom_cb (GtkWidget *source, WebPages *pages) { GConfClient *client = gconf_client_get_default (); WebData *data = pages->current_page; pages->backend->set_zoom (pages->backend_data, data->page_data, 1.0); gconf_client_set_float (client, GCONF_KEY_ZOOM, 1.0, NULL); } static void web_zoomin_cb (GtkWidget *source, WebPages *pages) { gdouble zoom; GConfClient *client = gconf_client_get_default (); WebData *data = pages->current_page; zoom = pages->backend->get_zoom (pages->backend_data, data->page_data); zoom *= MAG_STEP; pages->backend->set_zoom (pages->backend_data, data->page_data, zoom); gconf_client_set_float (client, GCONF_KEY_ZOOM, zoom, NULL); } static void web_zoomout_cb (GtkWidget *source, WebPages *pages) { gdouble zoom; GConfClient *client = gconf_client_get_default (); WebData *data = pages->current_page; zoom = pages->backend->get_zoom (pages->backend_data, data->page_data); zoom *= 1.0 / MAG_STEP; pages->backend->set_zoom (pages->backend_data, data->page_data, zoom); gconf_client_set_float (client, GCONF_KEY_ZOOM, zoom, NULL); } static void web_go_button_cb (GtkToggleToolButton *button, WebPages *pages) { if (gtk_toggle_tool_button_get_active (button)) { gtk_widget_show (glade_xml_get_widget (pages->xml, "url_notebook")); gtk_widget_show (glade_xml_get_widget (pages->xml, "bookmarks_window")); gtk_widget_grab_focus (glade_xml_get_widget ( pages->xml, "url_entry")); gtk_window_set_default (pages->window, glade_xml_get_widget ( pages->xml, "go_button")); } else { gtk_widget_hide (glade_xml_get_widget (pages->xml, "url_notebook")); gtk_widget_hide (glade_xml_get_widget (pages->xml, "bookmarks_window")); } } static void web_back_cb (GtkWidget *source, WebPages *pages) { web_history_go (NULL, g_list_last (pages->current_page->history)->prev->data); } static void web_forward_cb (GtkWidget *source, WebPages *pages) { web_history_go (NULL, pages->current_page->history_forward->data); } static void web_data_free (WebData *data) { web_stop_cb (NULL, NULL, data); data->parent->backend->destroy ( data->parent->backend_data, data->page_data); if (data->base_url) g_free (data->base_url); if (data->url) g_free (data->url); g_list_foreach (data->history, (GFunc)web_history_free, NULL); g_list_foreach (data->history_forward, (GFunc)web_history_free, NULL); g_list_free (data->history); g_list_free (data->history_forward); if (data->parent->current_page == data) { GtkWidget *widget = g_object_ref (glade_xml_get_widget ( data->parent->xml, "url_notebook")); gtk_container_remove ( GTK_CONTAINER (gtk_widget_get_parent (widget)), widget); widget = g_object_ref (glade_xml_get_widget ( data->parent->xml, "bookmarks_window")); gtk_container_remove ( GTK_CONTAINER (gtk_widget_get_parent (widget)), widget); } g_free (data); } static gboolean web_notebook_scroll_event_cb (GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { gint page = gtk_notebook_get_current_page (GTK_NOTEBOOK (widget)); if ((page == gtk_notebook_get_n_pages (GTK_NOTEBOOK (widget)) - 2) && (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_RIGHT)) return TRUE; else return FALSE; } static void web_close_tab_cb (GtkWidget *button, WebData *data) { gint page = g_list_index (data->parent->pages, data); if (page != -1) { if (gtk_notebook_get_n_pages (data->parent->book) <= 2) { gtk_main_quit (); return; } gtk_notebook_remove_page (data->parent->book, page); data->parent->pages = g_list_remove (data->parent->pages, data); web_data_free (data); } } typedef struct { GtkNotebook *book; guint page_num; } WebNewTabSwitchData; static gboolean web_new_tab_switch_idle (gpointer data) { WebNewTabSwitchData *wdata = data; gtk_notebook_set_current_page (wdata->book, wdata->page_num); g_free (wdata); return FALSE; } static gboolean web_page_button_press_cb (GtkWidget *page, GdkEventButton *event, WebData *data) { GtkWidget *widget = glade_xml_get_widget (data->parent->xml, "edit_button"); if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (widget))) return FALSE; if (data->clicked) return FALSE; /* TODO: A right-click context menu, middle-click open in new tab? */ if (event->button != 1) return TRUE; g_get_current_time (&data->click_start); data->x = event->x_root; data->y = event->y_root; data->moved = FALSE; data->clicked = TRUE; return TRUE; } static gboolean web_page_motion_notify_cb (GtkWidget *page, GdkEventMotion *event, WebData *data) { GtkWidget *widget = glade_xml_get_widget (data->parent->xml, "edit_button"); if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (widget))) return FALSE; if (!data->clicked) return FALSE; if ((abs (event->x_root - data->x) > 3) || (abs (event->y_root - data->y) > 3)) { data->moved = TRUE; } if (data->moved) { gdouble h, v; GtkAdjustment *hadjust = gtk_scrolled_window_get_hadjustment ( GTK_SCROLLED_WINDOW (data->scroll)); GtkAdjustment *vadjust = gtk_scrolled_window_get_vadjustment ( GTK_SCROLLED_WINDOW (data->scroll)); h = gtk_adjustment_get_value (hadjust) - (2*(event->x_root - data->x)); v = gtk_adjustment_get_value (vadjust) - (2*(event->y_root - data->y)); data->x = event->x_root; data->y = event->y_root; if ((h >= hadjust->lower) && (h <= (hadjust->upper - hadjust->page_size))) gtk_adjustment_set_value (hadjust, h); if ((v >= vadjust->lower) && (v <= (vadjust->upper - vadjust->page_size))) gtk_adjustment_set_value (vadjust, v); } return TRUE; } static gboolean web_page_button_release_cb (GtkWidget *page, GdkEventButton *event, WebData *data) { GTimeVal current; GtkWidget *widget = glade_xml_get_widget (data->parent->xml, "edit_button"); if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (widget))) return FALSE; if (!data->clicked) return FALSE; if (event->button != 1) return TRUE; g_get_current_time (¤t); if ((!data->moved) && ((current.tv_sec > data->click_start.tv_sec) || (current.tv_usec - data->click_start.tv_usec > 500))) { /* Send synthetic click event to avoid jitter */ event->type = GDK_BUTTON_PRESS; gtk_widget_event (page, (GdkEvent *)event); data->clicked = FALSE; event->type = GDK_BUTTON_RELEASE; gtk_widget_event (page, (GdkEvent *)event); } data->clicked = FALSE; return TRUE; } static void web_new_tab_cb (GtkWidget *source, WebPages *wdata) { GtkWidget *label, *image, *align, *close_image, *button, *box, *widget; gint page, close_size; WebData *data; WebNewTabSwitchData *idle_data; data = g_new0 (WebData, 1); widget = wdata->backend->new ( wdata->backend_data, &data->page_data, data); data->parent = wdata; /* Set media */ if (wdata->media) wdata->backend->set_media (wdata->backend_data, data->page_data, wdata->media); /* Apply stylesheet */ if (wdata->ssr) web_apply_ssr (wdata, data); wdata->backend->set_zoom (wdata->backend_data, data->page_data, wdata->last_zoom); /* Attach to mouse-button signals for jitter correction and such */ g_signal_connect (G_OBJECT (widget), "button-press-event", G_CALLBACK (web_page_button_press_cb), data); g_signal_connect (G_OBJECT (widget), "button-release-event", G_CALLBACK (web_page_button_release_cb), data); /* Create close button */ button = gtk_button_new (); close_image = gtk_image_new_from_stock ( GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_container_add (GTK_CONTAINER (button), close_image); align = gtk_alignment_new (1, 0.5, 0, 0); gtk_container_add (GTK_CONTAINER (align), button); close_size = gtk_image_get_pixel_size (GTK_IMAGE (close_image)); /* TODO: Is hard-coding pixel size 22 a good idea...? */ gtk_widget_set_size_request (align, 22, 22); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (web_close_tab_cb), data); /* Create tab label */ label = gtk_label_new (wdata->home ? wdata->home : "Empty page"); gtk_label_set_max_width_chars (GTK_LABEL (label), URL_LABEL_SIZE); gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); data->url_label = label; box = gtk_hbox_new (FALSE, 3); gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0); gtk_box_pack_end (GTK_BOX (box), align, TRUE, TRUE, 0); /* Create scrollview */ data->scroll = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (data->scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (data->scroll), widget); g_signal_connect (G_OBJECT (data->scroll), "motion-notify-event", G_CALLBACK (web_page_motion_notify_cb), data); /* Create vpaned and vbox */ data->vpaned = gtk_vpaned_new (); gtk_paned_add2 (GTK_PANED (data->vpaned), data->scroll); data->vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_end (GTK_BOX (data->vbox), GTK_WIDGET (data->vpaned), TRUE, TRUE, 0); gtk_widget_show_all (box); gtk_widget_show_all (data->vbox); page = gtk_notebook_append_page (wdata->book, data->vbox, box) - 1; gtk_notebook_reorder_child (wdata->book, data->vbox, page); wdata->pages = g_list_append (wdata->pages, data); /* Note: Switch to new tab in an idle func - doesn't work otherwise */ idle_data = g_new (WebNewTabSwitchData, 1); idle_data->book = wdata->book; idle_data->page_num = page; g_idle_add (web_new_tab_switch_idle, idle_data); /* gtk_notebook_set_current_page (wdata->book, page);*/ if (wdata->home) web_go (data, wdata->home, FALSE); } static void web_switch_page_cb (GtkNotebook *book, GtkNotebookPage *page, guint page_num, WebPages *wdata) { GtkWidget *widget, *parent; WebData *data; if (page_num == gtk_notebook_get_n_pages (book) - 1) { web_new_tab_cb (NULL, wdata); return; } data = g_list_nth_data (wdata->pages, page_num); if (!data) return; if (data->url) { widget = glade_xml_get_widget (wdata->xml, "url_entry"); gtk_entry_set_text (GTK_ENTRY (widget), data->url); widget = glade_xml_get_widget ( data->parent->xml, "url_progressbar"); gtk_progress_bar_set_text ( GTK_PROGRESS_BAR (widget), data->url); } wdata->current_page = data; widget = glade_xml_get_widget (wdata->xml, "bookmarks_window"); parent = gtk_widget_get_parent (widget); if (parent) gtk_container_remove ( GTK_CONTAINER (parent), g_object_ref (widget)); gtk_paned_add1 (GTK_PANED (data->vpaned), widget); widget = glade_xml_get_widget (wdata->xml, "url_notebook"); parent = gtk_widget_get_parent (widget); if (parent) gtk_container_remove ( GTK_CONTAINER (parent), g_object_ref (widget)); gtk_box_pack_start (GTK_BOX (data->vbox), widget, FALSE, TRUE, 0); web_history_build (data->history, data->history_forward, data->parent); if (g_list_length (data->requests) > 0) { gtk_notebook_next_page (GTK_NOTEBOOK (widget)); gtk_widget_show (widget); } else gtk_notebook_prev_page (GTK_NOTEBOOK (widget)); } static void web_preferences_blank_cb (GtkWidget *source, GtkEntry *entry) { gtk_entry_set_text (entry, ""); } static void web_preferences_current_cb (GtkWidget *source, WebPages *data) { GtkWidget *entry; if (data->current_page->url) { entry = glade_xml_get_widget ( data->xml, "preferences_home_entry"); gtk_entry_set_text (GTK_ENTRY (entry), data->current_page->url); } } static void web_preferences_cb (GtkWidget *source, WebPages *data) { GtkWidget *widget; GConfClient *client; client = gconf_client_get_default (); /* Setup preferences dialog */ widget = glade_xml_get_widget (data->xml, "preferences_home_entry"); if (data->home) gtk_entry_set_text (GTK_ENTRY (widget), data->home); if (data->media) { if (strcmp (data->media, "screen") == 0) { widget = glade_xml_get_widget ( data->xml, "screen_radiobutton"); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (widget), TRUE); } else if (strcmp (data->media, "tv") == 0) { widget = glade_xml_get_widget ( data->xml, "tv_radiobutton"); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (widget), TRUE); } else if (strcmp (data->media, "handheld") == 0) { widget = glade_xml_get_widget ( data->xml, "handheld_radiobutton"); gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (widget), TRUE); } } /* widget = glade_xml_get_widget (data->xml, "ssr_checkbutton"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), gconf_client_get_bool (client, GCONF_KEY_SSR, NULL));*/ /* Run */ widget = glade_xml_get_widget (data->xml, "preferences_dialog"); gtk_dialog_run (GTK_DIALOG (widget)); gtk_widget_hide (widget); /* Write home page settings */ widget = glade_xml_get_widget (data->xml, "preferences_home_entry"); gconf_client_set_string (client, GCONF_KEY_HOME, gtk_entry_get_text (GTK_ENTRY (widget)), NULL); /* Write media settings */ gconf_client_set_bool (client, GCONF_KEY_SSR, FALSE, NULL); widget = glade_xml_get_widget (data->xml, "screen_radiobutton"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) gconf_client_set_string ( client, GCONF_KEY_MEDIA, "screen", NULL); else { widget = glade_xml_get_widget (data->xml, "tv_radiobutton"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { gconf_client_set_string ( client, GCONF_KEY_MEDIA, "tv", NULL); } else { widget = glade_xml_get_widget ( data->xml, "handheld_radiobutton"); if (gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON (widget))) { gconf_client_set_string (client, GCONF_KEY_MEDIA, "handheld", NULL); gconf_client_set_bool (client, GCONF_KEY_SSR, TRUE, NULL); } } } /* Write SSR setting */ /* widget = glade_xml_get_widget (data->xml, "ssr_checkbutton"); gconf_client_set_bool (client, GCONF_KEY_SSR, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)), NULL);*/ } #ifdef WITH_HILDON static gboolean web_key_press_cb (GtkWidget *widget, GdkEventKey *event, WebPages *pages) { switch (event->keyval) { case GDK_F6 : /* Full-screen key */ if (gdk_window_get_state (pages->window->window) && GDK_WINDOW_STATE_FULLSCREEN) hildon_appview_set_fullscreen (pages->appview, FALSE); else hildon_appview_set_fullscreen (pages->appview, TRUE); return TRUE; case GDK_F8 : /* Zoom out key */ web_zoomout_cb (NULL, pages); return TRUE; case GDK_F7 : /* Zoom in key */ web_zoomin_cb (NULL, pages); return TRUE; } return FALSE; } #endif int main (int argc, char **argv) { GtkWidget *widget; #ifdef WITH_HILDON GList *children, *c; GtkMenu *menu; #endif WebPages pages; GConfClient *client; GModule *module; gchar *backend, *backend_full; WebBackEnd * (*info_func)(); /* Standard initialisation for gtk and glade */ g_thread_init (NULL); gtk_init (&argc, &argv); glade_init (); client = gconf_client_get_default (); /* Set critical errors to close application */ /* g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);*/ /* Load interface XML */ pages.xml = glade_xml_new (XML_FILE, NULL, NULL); if (!pages.xml) g_error ("Could not find interface XML file '%s'", XML_FILE); pages.pages = NULL; pages.history = gtk_menu_new (); pages.history_forward = gtk_menu_new (); pages.current_page = 0; /* Load back-end */ pages.backend = NULL; backend = gconf_client_get_string (client, GCONF_KEY_BACKEND, NULL); if (!backend) { backend = g_strdup ("libwebgtkhtml2"); gconf_client_set_string ( client, GCONF_KEY_BACKEND, backend, NULL); } #ifdef WITH_HILDON backend_full = g_module_build_path ( "/var/lib/install" PKGLIBDIR, backend); #else backend_full = g_module_build_path (PKGLIBDIR, backend); #endif module = g_module_open (backend_full, 0); if (!module) g_error ("Could not open module '%s': %s", backend_full, g_module_error ()); if (!g_module_symbol(module, "web_backend_get", (gpointer *)&info_func)) g_error ("'%s' is not a valid Web module", backend_full); pages.backend = info_func (); g_printf ("Loaded backend '%s'\n", pages.backend->name); if (pages.backend->api_version != WEB_API_VERSION) g_critical ("API version mismatch. Required: v%d, found: v%d", WEB_API_VERSION, pages.backend->api_version); pages.backend->init (&(pages.backend_data), &pages); #ifdef WITH_HILDON osso_initialize ("web", "0.0", FALSE, NULL); pages.appview = hildon_appview_new (""); pages.window = hildon_app_new_with_appview (pages.appview); hildon_app_set_title (pages.window, "Web"); gtk_widget_show (pages.appview); /* Reparent widgets to hildon appview */ widget = glade_xml_get_widget (pages.xml, "main_vbox"); gtk_container_remove ( GTK_CONTAINER (gtk_widget_get_parent (widget)), g_object_ref (widget)); gtk_container_add (GTK_CONTAINER (pages.appview), widget); widget = glade_xml_get_widget (pages.xml, "main_toolbar"); gtk_container_remove ( GTK_CONTAINER (gtk_widget_get_parent (widget)), g_object_ref (widget)); gtk_box_pack_end (GTK_BOX (pages.appview->vbox), widget, TRUE, TRUE, 0); gtk_widget_show_all (GTK_WIDGET (pages.appview->vbox)); gtk_widget_destroy (glade_xml_get_widget (pages.xml, "main_window")); /* Reparent menu items */ widget = glade_xml_get_widget (pages.xml, "main_menubar"); menu = hildon_appview_get_menu (pages.appview); children = gtk_container_get_children (GTK_CONTAINER (widget)); for (c = children; c; c = c->next) { GtkWidget *menuitem = GTK_WIDGET (c->data); gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent ( menuitem)), g_object_ref (menuitem)); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); } gtk_widget_destroy (widget); g_list_free (children); g_signal_connect (G_OBJECT (pages.window), "key_press_event", G_CALLBACK (web_key_press_cb), &pages); #else pages.window = glade_xml_get_widget (pages.xml, "main_window"); #endif web_bookmarks_init (&pages); /* Set history menus */ widget = glade_xml_get_widget (pages.xml, "back_menuitem"); gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), pages.history); widget = glade_xml_get_widget (pages.xml, "forward_menuitem"); gtk_menu_item_set_submenu ( GTK_MENU_ITEM (widget), pages.history_forward); /* Create the main notebook and a new page */ pages.book = GTK_NOTEBOOK ( glade_xml_get_widget (pages.xml, "pages_notebook")); /* Set transient parents for about/preferences dialogs */ gtk_window_set_transient_for ( GTK_WINDOW (glade_xml_get_widget (pages.xml, "about_dialog")), GTK_WINDOW (pages.window)); gtk_window_set_transient_for (GTK_WINDOW ( glade_xml_get_widget (pages.xml, "preferences_dialog")), GTK_WINDOW (pages.window)); /* Connect signals */ /* Notebook events */ g_signal_connect (G_OBJECT (pages.book), "switch-page", G_CALLBACK (web_switch_page_cb), &pages); g_signal_connect (G_OBJECT (pages.book), "scroll-event", G_CALLBACK (web_notebook_scroll_event_cb), NULL); /* Menu events */ widget = glade_xml_get_widget (pages.xml, "new_menuitem"); g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (web_new_tab_cb), &pages); widget = glade_xml_get_widget (pages.xml, "preferences_menuitem"); g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (web_preferences_cb), &pages); widget = glade_xml_get_widget (pages.xml, "cut_menuitem"); g_signal_connect_swapped (G_OBJECT (widget), "activate", G_CALLBACK (cut_cb), pages.window); widget = glade_xml_get_widget (pages.xml, "copy_menuitem"); g_signal_connect_swapped (G_OBJECT (widget), "activate", G_CALLBACK (copy_cb), pages.window); widget = glade_xml_get_widget (pages.xml, "paste_menuitem"); g_signal_connect_swapped (G_OBJECT (widget), "activate", G_CALLBACK (paste_cb), pages.window); widget = glade_xml_get_widget (pages.xml, "zoomin_menuitem"); g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (web_zoomin_cb), &pages); widget = glade_xml_get_widget (pages.xml, "zoomout_menuitem"); g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (web_zoomout_cb), &pages); widget = glade_xml_get_widget (pages.xml, "resetzoom_menuitem"); g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (web_resetzoom_cb), &pages); widget = glade_xml_get_widget (pages.xml, "about_menuitem"); g_signal_connect_swapped (G_OBJECT (widget), "activate", G_CALLBACK (gtk_widget_show), glade_xml_get_widget (pages.xml, "about_dialog")); widget = glade_xml_get_widget (pages.xml, "quit_menuitem"); g_signal_connect (G_OBJECT (widget), "activate", G_CALLBACK (gtk_main_quit), NULL); /* Preferences dialog events */ widget = glade_xml_get_widget (pages.xml, "preferences_bpage_button"); g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (web_preferences_blank_cb), glade_xml_get_widget ( pages.xml, "preferences_home_entry")); widget = glade_xml_get_widget (pages.xml, "preferences_cpage_button"); g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (web_preferences_current_cb), &pages); /* Toolbar events */ widget = glade_xml_get_widget (pages.xml, "zoomin_button"); g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (web_zoomin_cb), &pages); widget = glade_xml_get_widget (pages.xml, "zoomout_button"); g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (web_zoomout_cb), &pages); widget = glade_xml_get_widget (pages.xml, "go_togglebutton"); g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (web_go_button_cb), &pages); widget = glade_xml_get_widget (pages.xml, "back_button"); g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (web_back_cb), &pages); widget = glade_xml_get_widget (pages.xml, "forward_button"); g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (web_forward_cb), &pages); widget = glade_xml_get_widget (pages.xml, "go_button"); g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (web_go_cb), &pages); widget = glade_xml_get_widget (pages.xml, "stop_button"); g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (web_stop_cb), &pages); g_signal_connect (G_OBJECT (pages.window), "destroy", G_CALLBACK (gtk_main_quit), NULL); /* Read gconf settings */ pages.last_zoom = gconf_client_get_float (client, GCONF_KEY_ZOOM, NULL); pages.home = gconf_client_get_string (client, GCONF_KEY_HOME, NULL); pages.ssr = gconf_client_get_bool (client, GCONF_KEY_SSR, NULL); pages.media = gconf_client_get_string (client, GCONF_KEY_MEDIA, NULL); if ((pages.media) && (strlen (pages.media) == 0)) { g_free (pages.media); pages.media = NULL; } if ((pages.home) && (strlen (pages.home) == 0)) { g_free (pages.home); pages.home = NULL; } /* Add gconf watches */ gconf_client_add_dir (client, GCONF_PATH, GCONF_CLIENT_PRELOAD_NONE, NULL); gconf_client_notify_add (client, GCONF_KEY_ZOOM, web_gconf_zoom_cb, &pages, NULL, NULL); gconf_client_notify_add (client, GCONF_KEY_HOME, web_gconf_home_cb, &pages, NULL, NULL); gconf_client_notify_add (client, GCONF_KEY_SSR, web_gconf_ssr_cb, &pages, NULL, NULL); gconf_client_notify_add (client, GCONF_KEY_MEDIA, web_gconf_media_cb, &pages, NULL, NULL); /* Initialise request engine */ web_request_init (); /* Add a start tab */ web_new_tab_cb (NULL, &pages); gtk_widget_show (pages.window); gtk_main (); g_module_close (module); return 0; }