00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "config.h"
00035
00036
00037 #include <glib.h>
00038 #include <gtk/gtk.h>
00039 #include <stdlib.h>
00040 #include <math.h>
00041 #include <unistd.h>
00042 #include <gdk/gdkkeysyms.h>
00043 #include <webkit/webkit.h>
00044
00045
00046 #include <libergtk/ergtk.h>
00047 #include <liberutils/display_utils.h>
00048 #include <liberkeyb/erkeyb-client.h>
00049
00050
00051 #include "log.h"
00052 #include "download.h"
00053 #include "i18n.h"
00054 #include "ipc.h"
00055 #include "menu.h"
00056 #include "metadata.h"
00057
00058
00059
00060
00061
00062
00063
00064 #define MAX_BUF_LEN 512
00065 typedef enum
00066 {
00067 COL_TITLE = 0,
00068 COL_SUBTITLE,
00069 COL_THUMBNAIL,
00070 N_COLUMNS
00071 } column_t;
00072
00073 #define COLUMN_TYPES \
00074 G_TYPE_STRING, \
00075 G_TYPE_STRING, \
00076 GDK_TYPE_PIXBUF, \
00077 NULL
00078
00079 #define EBOOK_MALL_HOME "http://redirect.irexnet.com/mall/"
00080
00081
00082
00083
00084
00085
00086 static const gint WEBVIEW_MARGIN = 5;
00087 static const gint BUSY_DIALOG_DELAY_MS = 500;
00088 static const gint MULTIPLE_PAGES = 5;
00089 static const gint PAGE_OVERLAP = 5;
00090
00091 static const gint BACK_H_PADDING = 12;
00092 static const gint BACK_T_PADDING = 10;
00093 static const gint BACK_B_PADDING = 5;
00094
00095
00096
00097
00098
00099
00100 static BrowserWindow *g_browser = NULL;
00101 static gboolean g_page_loaded = FALSE;
00102 static GtkWidget *cancel_button = NULL;
00103 static GtkWidget *busy_dialog = NULL;
00104 static gchar *g_ebook_mall_home = NULL;
00105
00106
00107
00108
00109
00110
00111 static BrowserWindow *create_window (void);
00112
00113 static void go_back_cb (GtkWidget *item, BrowserWindow *window);
00114 static void go_forward_cb (GtkWidget *item, BrowserWindow *window);
00115 static void go_emall_cb (GtkWidget *item, BrowserWindow *window);
00116 static void reload_cb (GtkWidget *item, BrowserWindow *window);
00117 static void stop_cb (GtkWidget *item, BrowserWindow *window);
00118
00119 static void create_locationbar (BrowserWindow *window);
00120 static void create_toolbar (BrowserWindow *window);
00121 static void create_web_view (BrowserWindow *window);
00122 static GtkWidget * create_back (BrowserWindow *window);
00123 static GtkWidget * create_back_listview (GtkListStore * model);
00124 static void update_back_liststore (GtkWidget *listview, GtkListStore * model);
00125 static void on_back_activated (GtkTreeView *view,
00126 GtkTreePath *path,
00127 GtkTreeViewColumn *column,
00128 gpointer user_data);
00129
00130 static void notify_vadjustment_cb (BrowserWindow *window);
00131 static void notify_hadjustment_cb (BrowserWindow *window);
00132 static void destroy_cb (GtkWidget *widget, BrowserWindow *window);
00133 static void activate_uri_entry_cb (GtkWidget *entry, BrowserWindow *window);
00134 static void hadjustment_changed_cb (GtkAdjustment *adjustment, BrowserWindow *window);
00135 static void vadjustment_changed_cb (GtkAdjustment *adjustment, BrowserWindow *window);
00136 static void load_progress_cb (WebKitWebView *web_view, gint progress, BrowserWindow *window);
00137 static void load_started_cb (WebKitWebView *web_view, WebKitWebFrame *frame, BrowserWindow *window);
00138 static void load_finished_cb (WebKitWebView *web_view, WebKitWebFrame *frame, BrowserWindow *window);
00139 static gboolean load_error_cb (WebKitWebView *web_view,
00140 WebKitWebFrame *web_frame,
00141 const gchar *uri,
00142 GError *error,
00143 BrowserWindow *window);
00144 static gboolean key_event_cb (WebKitWebView *web_view,
00145 GdkEventKey *event,
00146 BrowserWindow *window);
00147 static WebKitWebView *create_web_view_cb(WebKitWebView *web_view,
00148 WebKitWebFrame *frame,
00149 BrowserWindow *window);
00150 static gboolean navigation_requested_cb (WebKitWebView *web_view,
00151 WebKitWebFrame *frame,
00152 WebKitNetworkRequest *request,
00153 WebKitWebNavigationAction *navigation_action,
00154 WebKitWebPolicyDecision *policy_decision,
00155 BrowserWindow *window);
00156 static gboolean mime_type_requested_cb (WebKitWebView *web_view,
00157 WebKitWebFrame *frame,
00158 WebKitNetworkRequest *request,
00159 const gchar *mime_type,
00160 WebKitWebPolicyDecision *policy_decision,
00161 BrowserWindow *window);
00162 static void notify_title_cb (WebKitWebView *web_view, GParamSpec *pspec, BrowserWindow *window);
00163 static void notify_uri_cb (WebKitWebView *web_view, GParamSpec *pspec, BrowserWindow *window);
00164 static void update_title (BrowserWindow *window, const gchar *title);
00165
00166 static void go_to_page (BrowserWindow *window, GtkAdjustment *adjustment, gint page);
00167 static gint get_current_page (BrowserWindow *window, GtkAdjustment *adjustment);
00168 static void show_busy_loading (gboolean show);
00169 static void show_busy (gboolean show);
00170 static gchar *magic_uri (const gchar *uri);
00171 static void load_error_page (const gchar *uri, GError *error);
00172 static void set_browser_uri (const gchar *uri);
00173 static void create_show_busy_loading(void);
00174 static gchar* get_file_content (const gchar* file_path);
00175 static gchar* get_ebook_mall_home (void);
00176
00177
00178
00179
00180
00181
00182 BrowserWindow *view_create()
00183 {
00184 LOGPRINTF("entry");
00185
00186 meta_initialize();
00187
00188 g_browser = create_window();
00189 create_show_busy_loading();
00190 g_ebook_mall_home = get_ebook_mall_home();
00191
00192 return g_browser;
00193 }
00194
00195
00196 void view_destroy(void)
00197 {
00198 LOGPRINTF("entry");
00199
00200 if (g_browser)
00201 {
00202 gchar * application = g_object_get_data(G_OBJECT(g_browser->back_listview), "application");
00203 if (application)
00204 {
00205 g_free(application);
00206 }
00207
00208 if (g_browser->window)
00209 {
00210 LOGPRINTF("destroy window");
00211 gtk_widget_destroy(g_browser->window);
00212 g_browser->window = NULL;
00213 }
00214 }
00215
00216 LOGPRINTF("clearing cache");
00217 system("rm -rf /var/cache/webkit");
00218
00219 g_free(g_ebook_mall_home);
00220 }
00221
00222
00223 void view_show_error(const gchar *title, const gchar *message)
00224 {
00225 LOGPRINTF("entry");
00226
00227 gchar *back = NULL;
00228 gchar *data = NULL;
00229
00230 if (webkit_web_view_can_go_back(WEBKIT_WEB_VIEW(g_browser->web_view)))
00231 {
00232 back = g_strdup_printf("<a href=\"javascript:history.go(-1)\">%s</a>",
00233 _("Return to the previous page"));
00234 }
00235 else
00236 {
00237 back = g_strdup("");
00238 }
00239
00240 data = g_strdup_printf(
00241 "<html><title>%s</title><body>"
00242 "<b>%s</b>"
00243 "<p />%s"
00244 "<p />"
00245 "<p />%s"
00246 "</body></html>",
00247 title,
00248 title,
00249 message,
00250 back);
00251
00252 webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(g_browser->web_view), data, NULL);
00253
00254 g_free(data);
00255 g_free(back);
00256 }
00257
00258
00259 void view_zoom_in()
00260 {
00261 LOGPRINTF("entry");
00262
00263 show_busy(TRUE);
00264 webkit_web_view_zoom_in(WEBKIT_WEB_VIEW(g_browser->web_view));
00265
00266 gfloat zoom_level = webkit_web_view_get_zoom_level(WEBKIT_WEB_VIEW(g_browser->web_view));
00267 meta_set_zoom_level(zoom_level);
00268 show_busy(FALSE);
00269 }
00270
00271
00272 void view_zoom_out()
00273 {
00274 LOGPRINTF("entry");
00275
00276 show_busy(TRUE);
00277 webkit_web_view_zoom_out(WEBKIT_WEB_VIEW(g_browser->web_view));
00278
00279 gfloat zoom_level = webkit_web_view_get_zoom_level(WEBKIT_WEB_VIEW(g_browser->web_view));
00280 meta_set_zoom_level(zoom_level);
00281 show_busy(FALSE);
00282 }
00283
00284
00285 void view_set_zoom_level(gfloat zoom_level)
00286 {
00287 LOGPRINTF("entry: %f", zoom_level);
00288
00289 show_busy(TRUE);
00290 webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(g_browser->web_view), zoom_level);
00291 menu_set_zoom_level(zoom_level);
00292 meta_set_zoom_level(zoom_level);
00293 show_busy(FALSE);
00294 }
00295
00296
00297 void view_full_screen(gboolean mode)
00298 {
00299 LOGPRINTF("entry: %d", mode);
00300
00301 g_object_set(G_OBJECT(webkit_web_view_get_window_features(WEBKIT_WEB_VIEW(g_browser->web_view))),
00302 "fullscreen", mode,
00303 NULL);
00304 if (mode)
00305 {
00306 gtk_window_fullscreen(GTK_WINDOW(g_main_window));
00307 }
00308 else
00309 {
00310 gtk_window_unfullscreen(GTK_WINDOW(g_main_window));
00311 }
00312
00313 menu_set_full_screen(mode);
00314 meta_set_full_screen(mode);
00315 }
00316
00317
00318 void view_go_back()
00319 {
00320 LOGPRINTF("entry");
00321 go_back_cb(NULL, g_browser);
00322 }
00323
00324
00325 void view_go_forward()
00326 {
00327 LOGPRINTF("entry");
00328 go_forward_cb(NULL, g_browser);
00329 }
00330
00331
00332 void view_reload()
00333 {
00334 LOGPRINTF("entry");
00335 reload_cb(NULL, g_browser);
00336 }
00337
00338
00339
00340 static gboolean is_local_file(const gchar *uri)
00341 {
00342 return uri && g_str_has_prefix(uri, "file://");
00343 }
00344
00345
00346 static gboolean is_local_uri(const gchar *uri)
00347 {
00348 return uri && ( g_str_has_prefix(uri, "file://") ||
00349 g_str_has_prefix(uri, "http://localhost") ||
00350 g_str_has_prefix(uri, "http://127.0.0.1") );
00351 }
00352
00353
00354 void view_open_last()
00355 {
00356 webkit_web_view_open(WEBKIT_WEB_VIEW(g_browser->web_view), g_browser->uri);
00357 }
00358
00359
00360 void view_open_uri(const char *uri)
00361 {
00362 LOGPRINTF("entry: %s", uri);
00363
00364 gchar *full_uri;
00365 full_uri = magic_uri(uri);
00366
00367 gboolean is_file = is_local_file(full_uri);
00368 if (is_file)
00369 {
00370 gchar *file_path = full_uri+strlen("file://");
00371 if (!g_file_test(file_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
00372 {
00373 load_error_page(full_uri, NULL);
00374 goto err;
00375 }
00376
00377
00378 meta_file_open(file_path);
00379 }
00380
00381 set_browser_uri(full_uri);
00382 webkit_web_view_open(WEBKIT_WEB_VIEW(g_browser->web_view), full_uri);
00383
00384 if (is_file)
00385 {
00386
00387 view_set_zoom_level(meta_get_zoom_level());
00388 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00389 view_full_screen (meta_get_full_screen());
00390 #endif
00391 }
00392
00393 err:
00394 g_free(full_uri);
00395 }
00396
00397
00398 void view_show_busy(gboolean show)
00399 {
00400 LOGPRINTF("entry");
00401 show_busy(show);
00402 }
00403
00404
00405 void view_set_text(void)
00406 {
00407 LOGPRINTF("entry");
00408 if (!g_browser || !g_browser->back_liststore)
00409 {
00410 return;
00411 }
00412
00413 gtk_list_store_clear(g_browser->back_liststore);
00414 update_back_liststore(g_browser->back_listview, g_browser->back_liststore);
00415 }
00416
00417
00418 void view_deactivated(void)
00419 {
00420 LOGPRINTF("entry");
00421 if (!g_browser)
00422 {
00423 return;
00424 }
00425
00426 main_quit();
00427 }
00428
00429
00430 gboolean view_is_page_loaded(void)
00431 {
00432 return g_page_loaded;
00433 }
00434
00435
00436 void view_open_emall(void)
00437 {
00438 view_open_uri(g_ebook_mall_home);
00439 }
00440
00441
00442
00443
00444
00445
00446 static gboolean on_webview_focus_out_cb(GtkWidget* widget, gpointer data)
00447 {
00448 gboolean locationbar_visible = FALSE;
00449 g_object_get(G_OBJECT(webkit_web_view_get_window_features(WEBKIT_WEB_VIEW(widget))),
00450 "locationbar-visible", &locationbar_visible,
00451 NULL);
00452
00453 if (!locationbar_visible)
00454 {
00455
00456 gtk_widget_grab_focus(widget);
00457 return TRUE;
00458 }
00459
00460
00461 return FALSE;
00462 }
00463
00464 static BrowserWindow *create_window()
00465 {
00466 LOGPRINTF("enter");
00467 GtkWidget *alignment = NULL;
00468 GtkWidget *back = NULL;
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 BrowserWindow *window = g_new0(BrowserWindow, 1);
00483
00484 back = create_back(window);
00485 create_locationbar(window);
00486 create_toolbar(window);
00487 create_web_view(window);
00488
00489 window->scrolled_window = gtk_scrolled_window_new(NULL, NULL);
00490 gtk_container_add(GTK_CONTAINER(window->scrolled_window), window->web_view);
00491
00492 alignment = gtk_alignment_new(0, 0, 1, 1);
00493 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), WEBVIEW_MARGIN, WEBVIEW_MARGIN, WEBVIEW_MARGIN, WEBVIEW_MARGIN);
00494 gtk_container_add(GTK_CONTAINER(alignment), window->scrolled_window);
00495 gtk_widget_show(alignment);
00496
00497 g_signal_connect(G_OBJECT(window->scrolled_window), "notify::hadjustment",
00498 G_CALLBACK(notify_hadjustment_cb), window);
00499 g_signal_connect(G_OBJECT(window->scrolled_window), "notify::vadjustment",
00500 G_CALLBACK(notify_vadjustment_cb), window);
00501 notify_hadjustment_cb(window);
00502 notify_vadjustment_cb(window);
00503
00504 window->vbox = gtk_vbox_new(FALSE, 0);
00505 gtk_box_pack_start(GTK_BOX(window->vbox), back, FALSE, FALSE, 0);
00506 gtk_box_pack_start(GTK_BOX(window->vbox), window->locationbar, FALSE, FALSE, 0);
00507 gtk_box_pack_start(GTK_BOX(window->vbox), window->toolbar, FALSE, FALSE, 0);
00508 gtk_box_pack_start(GTK_BOX(window->vbox), alignment, TRUE, TRUE, 0);
00509
00510 window->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00511 g_signal_connect_swapped(G_OBJECT(window->window), "destroy", G_CALLBACK(destroy_cb), window);
00512 gtk_container_add(GTK_CONTAINER(window->window), window->vbox);
00513 gtk_widget_grab_focus(window->web_view);
00514
00515 g_signal_connect(G_OBJECT(window->web_view), "focus-out-event",
00516 G_CALLBACK(on_webview_focus_out_cb), NULL);
00517
00518 return window;
00519 }
00520
00521
00522 static void go_back_cb(GtkWidget *item, BrowserWindow *window)
00523 {
00524 LOGPRINTF("entry");
00525
00526 erkeyb_client_hide();
00527
00528 if (window->web_view) {
00529 webkit_web_view_go_back(WEBKIT_WEB_VIEW(window->web_view));
00530 }
00531 }
00532
00533
00534 static void go_forward_cb(GtkWidget *item, BrowserWindow *window)
00535 {
00536 LOGPRINTF("entry");
00537
00538 erkeyb_client_hide();
00539
00540 if (window->web_view) {
00541 webkit_web_view_go_forward(WEBKIT_WEB_VIEW(window->web_view));
00542 }
00543 }
00544
00545
00546 static void go_emall_cb(GtkWidget *item, BrowserWindow *window)
00547 {
00548 LOGPRINTF("entry");
00549
00550 erkeyb_client_hide();
00551
00552 view_open_emall();
00553 }
00554
00555
00556 static void reload_cb(GtkWidget *item, BrowserWindow *window)
00557 {
00558 LOGPRINTF("entry");
00559 if (window->web_view) {
00560 webkit_web_view_reload_bypass_cache(WEBKIT_WEB_VIEW(window->web_view));
00561 }
00562 }
00563
00564
00565 static void stop_cb(GtkWidget *item, BrowserWindow *window)
00566 {
00567 LOGPRINTF("entry");
00568 webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(window->web_view));
00569 }
00570
00571
00572
00573
00574 static GtkWidget * create_back(BrowserWindow * window)
00575 {
00576 LOGPRINTF("entry");
00577
00578 GtkWidget * alignment = NULL;
00579
00580 alignment = gtk_alignment_new(0, 0, 1, 1);
00581 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment),
00582 BACK_T_PADDING, BACK_B_PADDING, BACK_H_PADDING, BACK_H_PADDING);
00583 gtk_widget_show(alignment);
00584
00585 window->back_liststore = gtk_list_store_new(N_COLUMNS, COLUMN_TYPES);
00586 window->back_listview = create_back_listview(window->back_liststore);
00587 gtk_container_add(GTK_CONTAINER(alignment), window->back_listview);
00588
00589 g_signal_connect(window->back_listview, "row-activated",
00590 G_CALLBACK(on_back_activated), NULL);
00591
00592 return alignment;
00593 }
00594
00595
00596 static GtkWidget * create_back_listview(GtkListStore * model)
00597 {
00598 LOGPRINTF("entry");
00599
00600 GtkWidget * view = ergtk_list_view_new_with_model(GTK_TREE_MODEL(model));
00601 gtk_widget_set_name(view, "contentview-irex-settings");
00602
00603 GtkTreeView * treeview = GTK_TREE_VIEW(view);
00604 erGtkListView * er_listview = ERGTK_LIST_VIEW(view);
00605
00606 gtk_tree_view_set_headers_visible(treeview, FALSE);
00607 ergtk_list_view_set_focus_mode(er_listview, TRUE, FALSE);
00608 GtkTreeSelection * selection = gtk_tree_view_get_selection(treeview);
00609 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
00610
00611
00612 GtkCellRenderer * renderer = gtk_cell_renderer_pixbuf_new();
00613 g_object_set(G_OBJECT(renderer),
00614 "xpad", 10,
00615 "ypad", 0,
00616 "xalign", 0.5,
00617 "yalign", 0.5,
00618 NULL);
00619 GtkTreeViewColumn * column =
00620 gtk_tree_view_column_new_with_attributes("", renderer,
00621 "pixbuf", COL_THUMBNAIL,
00622 NULL);
00623 g_object_set( G_OBJECT(column),
00624 "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE,
00625 "expand", FALSE,
00626 NULL );
00627 ergtk_list_view_append_column(er_listview, column);
00628
00629
00630 renderer = ergtk_cell_renderer_text_new(2);
00631 g_object_set( G_OBJECT(renderer),
00632 "xpad", 0,
00633 "ypad", 0,
00634 "xalign", 0.0,
00635 "yalign", 1.0,
00636 "ellipsize", PANGO_ELLIPSIZE_END,
00637 "ellipsize-set", TRUE,
00638 "font-0", "Normal 10",
00639 "font-1", "Normal italic 9",
00640 "height-0", 32,
00641 "height-1", 22,
00642 "foreground-0", "black",
00643 "foreground-1", "#555555",
00644 NULL );
00645 column =
00646 gtk_tree_view_column_new_with_attributes("", renderer,
00647 "text-0", COL_TITLE,
00648 "text-1", COL_SUBTITLE,
00649 NULL );
00650 g_object_set( G_OBJECT(column),
00651 "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE,
00652 "expand", TRUE,
00653 NULL );
00654 ergtk_list_view_append_column(er_listview, column);
00655
00656
00657
00658 renderer = ergtk_cell_renderer_border_new();
00659 g_object_set( G_OBJECT(renderer),
00660 "xpad", 0,
00661 "ypad", 0,
00662 "xalign", 0.0,
00663 "yalign", 0.5,
00664 "border-width", 2,
00665 "border-offset", 3,
00666 "border-color", "dark grey",
00667 NULL );
00668 column = gtk_tree_view_column_new_with_attributes("", renderer, NULL);
00669 g_object_set( G_OBJECT(column),
00670 "sizing", GTK_TREE_VIEW_COLUMN_AUTOSIZE,
00671 "expand", FALSE,
00672 NULL );
00673 ergtk_list_view_append_column(er_listview, column);
00674
00675 return view;
00676 }
00677
00678
00679 static void update_back_liststore(GtkWidget * listview, GtkListStore * model)
00680 {
00681 LOGPRINTF("entry");
00682
00683 char iconfile[MAX_BUF_LEN + 1];
00684 GdkPixbuf * pixbuf = NULL;
00685 GError * err = NULL;
00686 char title[MAX_BUF_LEN + 1], subtitle[MAX_BUF_LEN + 1];
00687 char * application = NULL;
00688
00689 snprintf(iconfile , MAX_BUF_LEN, "%s/%s", DATADIR, "icon-back-small.png");
00690 pixbuf = gdk_pixbuf_new_from_file ( iconfile, &err );
00691 if (pixbuf == NULL)
00692 {
00693 ERRORPRINTF("cannot load iconfile [%s] error [%s]", iconfile, err->message);
00694 g_clear_error(&err);
00695 }
00696
00697 application = (char *)g_object_get_data(G_OBJECT(listview), "application");
00698 g_snprintf(title, MAX_BUF_LEN,"to %s", application);
00699 g_snprintf(subtitle, MAX_BUF_LEN, "Return to %s screen", application);
00700 gtk_list_store_insert_with_values(model, NULL, -1,
00701 COL_TITLE, title,
00702 COL_SUBTITLE, subtitle,
00703 COL_THUMBNAIL, pixbuf,
00704 -1);
00705
00706 g_object_unref(pixbuf);
00707 }
00708
00709
00710 static void on_back_activated(GtkTreeView *view,
00711 GtkTreePath *path,
00712 GtkTreeViewColumn *column,
00713 gpointer user_data )
00714 {
00715 LOGPRINTF("entry");
00716 main_quit();
00717 }
00718
00719
00720 static void create_locationbar(BrowserWindow *window)
00721 {
00722 LOGPRINTF("entry");
00723 GtkToolItem *item = NULL;
00724
00725 window->locationbar = gtk_toolbar_new();
00726
00727 gtk_toolbar_set_orientation(GTK_TOOLBAR(window->locationbar), GTK_ORIENTATION_HORIZONTAL);
00728 gtk_toolbar_set_tooltips(GTK_TOOLBAR(window->locationbar), FALSE);
00729 gtk_toolbar_set_show_arrow(GTK_TOOLBAR(window->locationbar), FALSE);
00730 gtk_toolbar_set_style(GTK_TOOLBAR(window->locationbar), GTK_TOOLBAR_ICONS);
00731
00732
00733 item = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
00734 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(go_back_cb), window);
00735 gtk_toolbar_insert(GTK_TOOLBAR(window->locationbar), item, -1);
00736
00737 item = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
00738 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(go_forward_cb), window);
00739 gtk_toolbar_insert(GTK_TOOLBAR(window->locationbar), item, -1);
00740
00741 item = gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH);
00742 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(reload_cb), window);
00743 gtk_toolbar_insert(GTK_TOOLBAR(window->locationbar), item, -1);
00744
00745 item = gtk_tool_button_new_from_stock(GTK_STOCK_STOP);
00746 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(stop_cb), window);
00747 gtk_toolbar_insert(GTK_TOOLBAR(window->locationbar), item, -1);
00748
00749
00750 item = gtk_tool_item_new();
00751 gtk_tool_item_set_expand(item, TRUE);
00752 window->uri_entry = gtk_entry_new();
00753 g_signal_connect(G_OBJECT(window->uri_entry), "activate", G_CALLBACK(activate_uri_entry_cb), window);
00754 gtk_container_add(GTK_CONTAINER(item), window->uri_entry);
00755 gtk_toolbar_insert(GTK_TOOLBAR(window->locationbar), item, -1);
00756
00757
00758 item = gtk_tool_button_new_from_stock(GTK_STOCK_OK);
00759 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(activate_uri_entry_cb), window);
00760 gtk_toolbar_insert(GTK_TOOLBAR(window->locationbar), item, -1);
00761
00762 }
00763
00764
00765 static void create_toolbar(BrowserWindow *window)
00766 {
00767 LOGPRINTF("entry");
00768 GtkToolItem *item = NULL;
00769 GtkWidget *icon_widget = NULL;
00770 gchar *filename = NULL;
00771
00772 window->toolbar = gtk_toolbar_new();
00773
00774 gtk_toolbar_set_orientation(GTK_TOOLBAR(window->toolbar), GTK_ORIENTATION_HORIZONTAL);
00775 gtk_toolbar_set_tooltips(GTK_TOOLBAR(window->toolbar), FALSE);
00776 gtk_toolbar_set_show_arrow(GTK_TOOLBAR(window->toolbar), FALSE);
00777 gtk_toolbar_set_style(GTK_TOOLBAR(window->toolbar), GTK_TOOLBAR_BOTH_HORIZ);
00778
00779
00780 filename = g_strconcat(DATADIR, "/", "back.png", NULL);
00781 icon_widget = gtk_image_new_from_file(filename);
00782 g_object_ref(G_OBJECT(icon_widget));
00783 g_free(filename);
00784 item = gtk_tool_button_new(icon_widget, NULL);
00785 gtk_tool_item_set_homogeneous(item, FALSE);
00786 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(go_back_cb), window);
00787 gtk_toolbar_insert(GTK_TOOLBAR(window->toolbar), item, -1);
00788
00789
00790 filename = g_strconcat(DATADIR, "/", "forward.png", NULL);
00791 icon_widget = gtk_image_new_from_file(filename);
00792 g_object_ref(G_OBJECT(icon_widget));
00793 g_free(filename);
00794 item = gtk_tool_button_new(icon_widget, NULL);
00795 gtk_tool_item_set_homogeneous(item, FALSE);
00796 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(go_forward_cb), window);
00797 gtk_toolbar_insert(GTK_TOOLBAR(window->toolbar), item, -1);
00798
00799
00800 filename = g_strconcat(DATADIR, "/", "emall-home.png", NULL);
00801 icon_widget = gtk_image_new_from_file(filename);
00802 g_object_ref(G_OBJECT(icon_widget));
00803 g_free(filename);
00804 item = gtk_tool_button_new(icon_widget, NULL);
00805 GtkWidget *emall_label = gtk_label_new(NULL);
00806 gtk_label_set_use_markup(GTK_LABEL(emall_label), TRUE);
00807 gchar *label_markup = g_markup_printf_escaped ("<u>%s</u>", _("eBook Mall"));
00808 gtk_label_set_markup(GTK_LABEL(emall_label), label_markup);
00809 g_free (label_markup);
00810 gtk_tool_button_set_label_widget(GTK_TOOL_BUTTON(item), emall_label);
00811 gtk_widget_set_name(GTK_WIDGET(item), "irex-mall-button");
00812 gtk_tool_item_set_is_important(item, TRUE);
00813 gtk_tool_item_set_homogeneous(item, FALSE);
00814 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(go_emall_cb), window);
00815 gtk_toolbar_insert(GTK_TOOLBAR(window->toolbar), item, -1);
00816
00817
00818 item = gtk_separator_tool_item_new();
00819 gtk_toolbar_insert(GTK_TOOLBAR(window->toolbar), item, -1);
00820
00821
00822 item = gtk_tool_item_new();
00823 gtk_tool_item_set_expand(item, TRUE);
00824 gtk_tool_item_set_homogeneous(item, FALSE);
00825 window->title = gtk_label_new(NULL);
00826 gtk_misc_set_alignment(GTK_MISC(window->title), 0.0, 0.5);
00827 gtk_label_set_ellipsize(GTK_LABEL(window->title), PANGO_ELLIPSIZE_END);
00828 gtk_container_add(GTK_CONTAINER(item), window->title);
00829 gtk_toolbar_insert(GTK_TOOLBAR(window->toolbar), item, -1);
00830 }
00831
00832
00833 static void create_web_view(BrowserWindow *window)
00834 {
00835 LOGPRINTF("entry");
00836
00837
00838 window->web_view = webkit_web_view_new();
00839 g_signal_connect(G_OBJECT(window->web_view), "load-progress-changed", G_CALLBACK(load_progress_cb), NULL);
00840 g_signal_connect(G_OBJECT(window->web_view), "load-started", G_CALLBACK(load_started_cb), window);
00841 g_signal_connect(G_OBJECT(window->web_view), "load-finished", G_CALLBACK(load_finished_cb), window);
00842 g_signal_connect(G_OBJECT(window->web_view), "load-error", G_CALLBACK(load_error_cb), window);
00843 g_signal_connect(G_OBJECT(window->web_view), "create-web-view", G_CALLBACK(create_web_view_cb), window);
00844 g_signal_connect(G_OBJECT(window->web_view), "key-press-event", G_CALLBACK(key_event_cb), window);
00845 g_signal_connect(G_OBJECT(window->web_view), "download-requested", G_CALLBACK(download_requested_cb), window);
00846 g_signal_connect(G_OBJECT(window->web_view), "navigation-policy-decision-requested", G_CALLBACK(navigation_requested_cb), window);
00847 g_signal_connect(G_OBJECT(window->web_view), "mime-type-policy-decision-requested", G_CALLBACK(mime_type_requested_cb), window);
00848 g_signal_connect(G_OBJECT(window->web_view), "notify::title", G_CALLBACK(notify_title_cb), window);
00849 g_signal_connect(G_OBJECT(window->web_view), "notify::uri", G_CALLBACK(notify_uri_cb), window);
00850
00851 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00852 webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(window->web_view), FALSE);
00853 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00854
00855 webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(window->web_view), TRUE);
00856 #else
00857 #error Unhandled machine type
00858 #endif
00859 }
00860
00861
00862 static void activate_uri_entry_cb(GtkWidget *entry, BrowserWindow *window)
00863 {
00864 LOGPRINTF("entry");
00865
00866 view_open_uri(gtk_entry_get_text(GTK_ENTRY(window->uri_entry)));
00867 }
00868
00869
00870 static void load_progress_cb(WebKitWebView *web_view, gint progress, BrowserWindow *window)
00871 {
00872 LOGPRINTF("entry... progress %d", progress);
00873 }
00874
00875
00876 static void load_started_cb(WebKitWebView *web_view, WebKitWebFrame *frame, BrowserWindow *window)
00877 {
00878 LOGPRINTF("entry [%s]", g_browser ? g_browser->uri : "");
00879
00880 erkeyb_client_hide();
00881
00882 if (!window->uri_entry)
00883 {
00884 LOGPRINTF("uri bar is empty, return");
00885 return;
00886 }
00887
00888
00889 if (g_browser->uri)
00890 {
00891 gtk_entry_set_text(GTK_ENTRY(window->uri_entry), g_browser->uri);
00892 }
00893
00894 show_busy(TRUE);
00895 }
00896
00897
00898 static void load_finished_cb(WebKitWebView *web_view, WebKitWebFrame *frame, BrowserWindow *window)
00899 {
00900 LOGPRINTF("entry");
00901
00902 if (!window->uri_entry)
00903 return;
00904
00905
00906
00907
00908
00909
00910
00911
00912 show_busy(FALSE);
00913 g_page_loaded = TRUE;
00914 }
00915
00916
00917 static gboolean load_error_cb(WebKitWebView *web_view,
00918 WebKitWebFrame *web_frame,
00919 const gchar *uri,
00920 GError *error,
00921 BrowserWindow *window)
00922 {
00923 LOGPRINTF("entry uri [%s] window uri [%s]", uri, window ? window->uri : "");
00924
00925 if (error && error->message)
00926 {
00927 WARNPRINTF("Webkit returned error [%d] [%s]", error->code, error->message);
00928 }
00929
00930 if (window && window->uri && (strcmp(window->uri, "about:blank") != 0))
00931 {
00932 load_error_page(window->uri, error);
00933 }
00934
00935 show_busy(FALSE);
00936
00937
00938 return TRUE;
00939 }
00940
00941
00942 static gchar *page_html(const gchar *title, const gchar *description, const gchar *link)
00943 {
00944 gchar *data = g_strconcat(
00945 "<html><head><title>", title, "</title></head><body><br/><br/><br/><br/>"
00946 "<div style=\"display:block; width:500px; margin:auto; border:10px solid #fff; "
00947 "outline:3px solid black; outline-radius:12px; -webkit-outline-radius:12px\">"
00948 "<h3>", title, "</h3><p>", description, "</p>", link, "</div>"
00949 "</body></html>", NULL);
00950 return data;
00951 }
00952
00953
00954 static gchar *link_html(const gchar *url, const gchar *title)
00955 {
00956 gchar *data = g_strdup_printf("<a href=\"%s\">%s</a>", url, title);
00957 return data;
00958 }
00959
00960
00961 static void load_error_page(const gchar *uri, GError *error)
00962 {
00963 LOGPRINTF("entry");
00964
00965 gboolean toolbar_visible = FALSE;
00966 g_object_get(G_OBJECT(webkit_web_view_get_window_features(WEBKIT_WEB_VIEW(g_browser->web_view))),
00967 "toolbar-visible", &toolbar_visible, NULL);
00968
00969 if (toolbar_visible)
00970 {
00971
00972
00973 gchar *link = NULL;
00974 gchar *page = NULL;
00975
00976
00977 if (error)
00978 {
00979 switch (error->code)
00980 {
00981 case SOUP_STATUS_IO_ERROR:
00982 link = link_html("javascript:history.go(0)",
00983 _("Reload the page"));
00984 page = page_html(_("The connection has terminated unexpectedly"),
00985 _("The signal may be too weak. Try reloading the page by choosing Reload Page from the Menu."),
00986 link);
00987 break;
00988 }
00989 }
00990
00991
00992 if (!page)
00993 {
00994 gboolean can_go_back = webkit_web_view_can_go_back(WEBKIT_WEB_VIEW(g_browser->web_view));
00995 if (can_go_back)
00996 {
00997 link = link_html("javascript:history.go(-1)",
00998 _("Return to the previous page"));
00999 }
01000 else
01001 {
01002 link = link_html(g_ebook_mall_home,
01003 _("Go to eBook Mall home"));
01004 }
01005 page = page_html(_("Page not found"),
01006 _("The page you were trying to retrieve does not exist in the eBook Mall."),
01007 link);
01008 }
01009
01010 webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(g_browser->web_view), page, NULL);
01011 g_free(link);
01012 g_free(page);
01013 }
01014 else
01015 {
01016
01017 gchar *title;
01018 title = g_strdup_printf(_("Error loading %s"), uri);
01019
01020 gchar *message;
01021 message = g_strconcat( _("The requested page could not be found. This may have happened because:"),
01022 "<ul><li>",
01023 _("The URL is incorrect"),
01024 "</li><li>",
01025 _("The page has been moved or renamed"),
01026 "</li><li>",
01027 _("The page no longer exists"),
01028 "</li></ul>",
01029 NULL);
01030 view_show_error(title, message);
01031 g_free(message);
01032 g_free(title);
01033 }
01034 }
01035
01036
01037 static WebKitWebView *create_web_view_cb(WebKitWebView *web_view, WebKitWebFrame *frame, BrowserWindow *window)
01038 {
01039 LOGPRINTF("entry");
01040 set_browser_uri("");
01041 return web_view;
01042 }
01043
01044
01045 static gboolean navigation_requested_cb(WebKitWebView *web_view,
01046 WebKitWebFrame *frame,
01047 WebKitNetworkRequest *request,
01048 WebKitWebNavigationAction *navigation_action,
01049 WebKitWebPolicyDecision *policy_decision,
01050 BrowserWindow *window)
01051 {
01052 LOGPRINTF("entry");
01053
01054 #if (LOGGING_ON)
01055 static const gchar *reason_str[] =
01056 {
01057 [WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED] = "LINK_CLICKED",
01058 [WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED] = "FORM_SUBMITTED",
01059 [WEBKIT_WEB_NAVIGATION_REASON_BACK_FORWARD] = "BACK_FORWARD",
01060 [WEBKIT_WEB_NAVIGATION_REASON_RELOAD] = "RELOAD",
01061 [WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED] = "FORM_RESUBMITTED",
01062 [WEBKIT_WEB_NAVIGATION_REASON_OTHER] = "OTHER"
01063 };
01064 #endif
01065
01066 WebKitWebNavigationReason reason = webkit_web_navigation_action_get_reason(navigation_action);
01067 const gchar *uri = webkit_web_navigation_action_get_original_uri(navigation_action);
01068
01069 LOGPRINTF("original uri [%s]", uri);
01070 LOGPRINTF("window uri [%s]", window ? window->uri : NULL);
01071
01072 if (reason == WEBKIT_WEB_NAVIGATION_REASON_RELOAD && window && window->uri)
01073 {
01074
01075 uri = window->uri;
01076 webkit_web_navigation_action_set_original_uri(navigation_action, uri);
01077 }
01078 else
01079 {
01080 set_browser_uri(uri);
01081 }
01082
01083 LOGPRINTF("load uri [%s] reason [%s]", uri, reason_str[reason]);
01084
01085 gchar *application = g_object_get_data(G_OBJECT(g_browser->back_listview), "application");
01086 gboolean toolbar_visible = FALSE;
01087 g_object_get(G_OBJECT(webkit_web_view_get_window_features(WEBKIT_WEB_VIEW(web_view))),
01088 "toolbar-visible", &toolbar_visible, NULL);
01089
01090
01091
01092 if (uri && strcmp(uri, "about:blank") == 0)
01093 {
01094 LOGPRINTF("empty page, skipped");
01095 webkit_web_policy_decision_ignore(policy_decision);
01096 return TRUE;
01097 }
01098 else if (is_local_uri(uri))
01099 {
01100
01101 }
01102 else
01103 {
01104 gboolean connect = toolbar_visible || application;
01105 if (!connect)
01106 {
01107 ERRORPRINTF("Cannot open web links while browsing offline [%s]", uri);
01108
01109 gchar *msg = g_strdup_printf(_("This link cannot be opened because the reader is not able to open internet links."));
01110 GtkWidget *widget = gtk_message_dialog_new(GTK_WINDOW(g_browser->window),
01111 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
01112 GTK_MESSAGE_INFO,
01113 GTK_BUTTONS_OK,
01114 msg);
01115 gtk_dialog_run(GTK_DIALOG(widget));
01116 gtk_widget_destroy(widget);
01117 g_free(msg);
01118 }
01119
01120 if (!connect || (connect && main_request_connection()))
01121 {
01122 LOGPRINTF("ignore loading page");
01123 webkit_web_policy_decision_ignore(policy_decision);
01124 return TRUE;
01125 }
01126 }
01127
01128
01129
01130 if (toolbar_visible)
01131 {
01132 static gboolean was_hidden = FALSE;
01133
01134 if (g_strstr_len(uri, strlen(uri), "EBM_NO_NAVIGATION") != NULL)
01135 {
01136 if (!was_hidden)
01137 {
01138 gtk_widget_hide(window->toolbar);
01139 was_hidden = TRUE;
01140 }
01141 }
01142 else
01143 {
01144 if (was_hidden)
01145 {
01146 gtk_widget_show(window->toolbar);
01147 was_hidden = FALSE;
01148 }
01149 }
01150 }
01151
01152
01153 return FALSE;
01154 }
01155
01156
01157 static gboolean mime_type_requested_cb(WebKitWebView *web_view,
01158 WebKitWebFrame *frame,
01159 WebKitNetworkRequest *request,
01160 const gchar *mime_type,
01161 WebKitWebPolicyDecision *policy_decision,
01162 BrowserWindow *window)
01163 {
01164 LOGPRINTF("entry");
01165 gboolean retval = FALSE;
01166
01167 if (!webkit_web_view_can_show_mime_type (WEBKIT_WEB_VIEW (web_view), mime_type))
01168 {
01169
01170
01171 webkit_web_policy_decision_download (policy_decision);
01172 window->open_download = FALSE;
01173
01174 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800SW
01175
01176 if (mime_type && strcmp(mime_type, "application/vnd.adobe.adept+xml") == 0)
01177 {
01178 LOGPRINTF("found Adobe Adept MIME type, download and open with Adobe Fullfilment");
01179 window->open_download = TRUE;
01180 }
01181 else if (g_browser->uri)
01182 {
01183 gchar *extension = g_strrstr(g_browser->uri,".");
01184 if (extension && (strncmp(extension, ".acsm", 5) == 0))
01185 {
01186 LOGPRINTF("found .acsm file, download and open with Adobe Fullfilment");
01187 window->open_download = TRUE;
01188 }
01189 }
01190 #endif
01191
01192
01193
01194 webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(web_view));
01195
01196 retval = TRUE;
01197 }
01198
01199 return retval;
01200 }
01201
01202
01203 static void update_title(BrowserWindow *window, const gchar *title)
01204 {
01205 LOGPRINTF("entry");
01206 if (window && window->title)
01207 {
01208 LOGPRINTF("title [%s]", title);
01209 gtk_label_set_text(GTK_LABEL(window->title), title);
01210 }
01211 }
01212
01213
01214 static void notify_title_cb(WebKitWebView *web_view, GParamSpec *pspec, BrowserWindow *window)
01215 {
01216 LOGPRINTF("entry");
01217 const gchar *title;
01218 g_object_get(web_view, "title", &title, NULL);
01219 update_title(window, title);
01220 }
01221
01222
01223 static void notify_uri_cb(WebKitWebView *web_view, GParamSpec *pspec, BrowserWindow *window)
01224 {
01225 LOGPRINTF("entry");
01226 const gchar *uri;
01227 g_object_get(web_view, "uri", &uri, NULL);
01228
01229
01230 if (window && window->toolbar)
01231 {
01232 GtkWidget *item = gtk_bin_get_child(GTK_BIN(gtk_toolbar_get_nth_item(GTK_TOOLBAR(window->toolbar), 2)));
01233 if (window->uri && g_str_has_prefix(window->uri, EBOOK_MALL_HOME))
01234 {
01235 gtk_widget_hide(item);
01236 }
01237 else
01238 {
01239 gtk_widget_show(item);
01240 }
01241 }
01242 }
01243
01244
01245 static gboolean key_event_cb(WebKitWebView *web_view, GdkEventKey *event, BrowserWindow *window)
01246 {
01247 gboolean retval = TRUE;
01248 guint new_keyval = 0;
01249
01250 LOGPRINTF("entry: key %d, state %d", event->keyval, event->state);
01251
01252 g_return_val_if_fail(g_browser, FALSE);
01253
01254 if ((event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) == 0)
01255 {
01256
01257
01258 switch (event->keyval)
01259 {
01260 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
01261 case GDK_Up:
01262 case GDK_KP_Up:
01263 LOGPRINTF("select previous hyperlink in tab order");
01264 event->state = GDK_SHIFT_MASK;
01265 event->keyval = GDK_Tab;
01266 retval = FALSE;
01267 break;
01268 case GDK_Down:
01269 case GDK_KP_Down:
01270 LOGPRINTF("select next hyperlink in tab order");
01271 event->keyval = GDK_Tab;
01272 retval = FALSE;
01273 break;
01274 case GDK_Home:
01275 case GDK_KP_Home:
01276 LOGPRINTF("scroll left");
01277 go_to_page(g_browser, g_browser->hadjustment,
01278 get_current_page(g_browser, g_browser->hadjustment) - 1);
01279 break;
01280 case GDK_Page_Up:
01281 case GDK_KP_Page_Up:
01282 LOGPRINTF("scroll up");
01283 go_to_page(g_browser, g_browser->vadjustment,
01284 get_current_page(g_browser, g_browser->vadjustment) - 1);
01285 break;
01286 case GDK_End:
01287 case GDK_KP_End:
01288 LOGPRINTF("scroll right");
01289 go_to_page(g_browser, g_browser->hadjustment,
01290 get_current_page(g_browser, g_browser->hadjustment) + 1);
01291 break;
01292 case GDK_Page_Down:
01293 case GDK_KP_Page_Down:
01294 LOGPRINTF("scroll down");
01295 go_to_page(g_browser, g_browser->vadjustment,
01296 get_current_page(g_browser, g_browser->vadjustment) + 1);
01297 break;
01298 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
01299 case GDK_Left:
01300 case GDK_KP_Left:
01301 LOGPRINTF("scroll left");
01302 go_to_page(g_browser, g_browser->hadjustment,
01303 get_current_page(g_browser, g_browser->hadjustment) - 1);
01304 break;
01305 case GDK_Up:
01306 case GDK_KP_Up:
01307 LOGPRINTF("scroll up");
01308 go_to_page(g_browser, g_browser->vadjustment,
01309 get_current_page(g_browser, g_browser->vadjustment) - 1);
01310 break;
01311 case GDK_Right:
01312 case GDK_KP_Right:
01313 LOGPRINTF("scroll right");
01314 go_to_page(g_browser, g_browser->hadjustment,
01315 get_current_page(g_browser, g_browser->hadjustment) + 1);
01316 break;
01317 case GDK_Down:
01318 case GDK_KP_Down:
01319 LOGPRINTF("scroll down");
01320 go_to_page(g_browser, g_browser->vadjustment,
01321 get_current_page(g_browser, g_browser->vadjustment) + 1);
01322 break;
01323 case GDK_Home:
01324 case GDK_KP_Home:
01325 LOGPRINTF("scroll 5 pages left");
01326 go_to_page(g_browser, g_browser->hadjustment,
01327 get_current_page(g_browser, g_browser->hadjustment) - MULTIPLE_PAGES);
01328 break;
01329 case GDK_Page_Up:
01330 case GDK_KP_Page_Up:
01331 LOGPRINTF("scroll 5 pages up");
01332 go_to_page(g_browser, g_browser->vadjustment,
01333 get_current_page(g_browser, g_browser->vadjustment) - MULTIPLE_PAGES);
01334 break;
01335 case GDK_End:
01336 case GDK_KP_End:
01337 LOGPRINTF("scroll 5 pages right");
01338 go_to_page(g_browser, g_browser->hadjustment,
01339 get_current_page(g_browser, g_browser->hadjustment) + MULTIPLE_PAGES);
01340 break;
01341 case GDK_Page_Down:
01342 case GDK_KP_Page_Down:
01343 LOGPRINTF("scroll 5 pages down");
01344 go_to_page(g_browser, g_browser->vadjustment,
01345 get_current_page(g_browser, g_browser->vadjustment) + MULTIPLE_PAGES);
01346 break;
01347 #else
01348 #error Unhandled machine type
01349 #endif
01350 default:
01351 LOGPRINTF("other key, propagate");
01352
01353 retval = FALSE;
01354 break;
01355 }
01356 }
01357 else if (event->state & GDK_SHIFT_MASK)
01358 {
01359
01360
01361
01362 switch (event->keyval)
01363 {
01364 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
01365 case GDK_Left:
01366 case GDK_KP_Left:
01367 LOGPRINTF("select previous/left hyperlink");
01368 new_keyval = GDK_Left;
01369 break;
01370 case GDK_Right:
01371 case GDK_KP_Right:
01372 LOGPRINTF("select next/right hyperlink");
01373 new_keyval = GDK_Right;
01374 break;
01375 case GDK_Up:
01376 case GDK_KP_Up:
01377 LOGPRINTF("select previous/up hyperlink");
01378 new_keyval = GDK_Up;
01379 break;
01380 case GDK_Down:
01381 case GDK_KP_Down:
01382 LOGPRINTF("select next/down hyperlink");
01383 new_keyval = GDK_Down;
01384 break;
01385 #endif
01386 default:
01387 new_keyval = 0;
01388 break;
01389 }
01390
01391 if (new_keyval)
01392 {
01393 event->state = GDK_CONTROL_MASK;
01394 event->keyval = new_keyval;
01395 }
01396
01397
01398 retval = FALSE;
01399 }
01400
01401 return retval;
01402 }
01403
01404
01405 static void notify_vadjustment_cb(BrowserWindow *window)
01406 {
01407 LOGPRINTF("entry");
01408
01409 g_return_if_fail(window);
01410
01411 if (window->scrolled_window)
01412 {
01413 if (window->vadjustment)
01414 {
01415 g_object_unref(window->vadjustment);
01416 }
01417 window->vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(window->scrolled_window));
01418 g_signal_connect(G_OBJECT(window->vadjustment), "value-changed", G_CALLBACK(vadjustment_changed_cb), window);
01419 g_object_ref(window->vadjustment);
01420 }
01421 }
01422
01423
01424 static void notify_hadjustment_cb(BrowserWindow *window)
01425 {
01426 LOGPRINTF("entry");
01427
01428 g_return_if_fail(window);
01429
01430 if (window->scrolled_window)
01431 {
01432 if (window->hadjustment)
01433 {
01434 g_object_unref(window->hadjustment);
01435 }
01436 window->hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(window->scrolled_window));
01437 g_signal_connect(G_OBJECT(window->hadjustment), "value-changed", G_CALLBACK(hadjustment_changed_cb), window);
01438 g_object_ref(window->hadjustment);
01439 }
01440 }
01441
01442
01443 static void hadjustment_changed_cb(GtkAdjustment *adjustment, BrowserWindow *window)
01444 {
01445 LOGPRINTF("entry");
01446 if (adjustment->value)
01447 {
01448 meta_set_h_position(adjustment->value);
01449 }
01450 }
01451
01452
01453 static void vadjustment_changed_cb(GtkAdjustment *adjustment, BrowserWindow *window)
01454 {
01455 LOGPRINTF("entry");
01456 if (adjustment->value)
01457 {
01458 meta_set_v_position(adjustment->value);
01459 }
01460 }
01461
01462
01463 static void destroy_cb(GtkWidget *widget, BrowserWindow *window)
01464 {
01465 LOGPRINTF("entry");
01466 meta_finalize();
01467 erkeyb_client_term();
01468 g_browser->window = NULL;
01469 }
01470
01471
01472 static gint get_total_pages(BrowserWindow *window, GtkAdjustment *adjustment)
01473 {
01474 LOGPRINTF("entry");
01475
01476 gdouble upper;
01477 gdouble page_size;
01478 gint total;
01479
01480 g_object_get(G_OBJECT(adjustment),
01481 "upper", &upper,
01482 "page-size", &page_size,
01483 NULL);
01484
01485 if (page_size == upper)
01486 {
01487
01488
01489
01490 total = 1;
01491 }
01492 else
01493 {
01494 total = MAX(ceil(upper / (page_size * (100-PAGE_OVERLAP) / 100)), 1);
01495 }
01496
01497 LOGPRINTF("page-size %f, upper %f, total %d", page_size, upper, total);
01498
01499 return total;
01500 }
01501
01502
01503 static gint get_current_page(BrowserWindow *window, GtkAdjustment *adjustment)
01504 {
01505 LOGPRINTF("entry");
01506
01507 gdouble value;
01508 gdouble page_size;
01509 gdouble upper;
01510 gint current;
01511 gint total;
01512
01513 g_object_get(G_OBJECT(adjustment),
01514 "value", &value,
01515 "page-size", &page_size,
01516 "upper", &upper,
01517 NULL);
01518
01519 current = (int) (value / floor((page_size * (100-PAGE_OVERLAP) / 100)) + 1);
01520
01521 total = get_total_pages(window, adjustment);
01522
01523 LOGPRINTF("page-size %f, upper %f, value %f. total %d, current %d", page_size, upper, value, total, current);
01524
01525 if (current != total && value + page_size >= upper)
01526 {
01527
01528
01529
01530
01531
01532 current = total;
01533 }
01534
01535 return current;
01536 }
01537
01538
01539 static void go_to_page(BrowserWindow *window, GtkAdjustment *adjustment, gint page)
01540 {
01541 LOGPRINTF("entry");
01542
01543 gdouble page_size;
01544 gdouble upper;
01545 gdouble lower;
01546 gdouble value;
01547
01548 g_object_get(G_OBJECT(adjustment),
01549 "page-size", &page_size,
01550 "lower", &lower,
01551 "upper", &upper,
01552 NULL);
01553
01554 value = MAX(
01555 MIN(
01556 floor((page - 1) * (page_size * (100-PAGE_OVERLAP) / 100)),
01557 upper - page_size),
01558 lower);
01559
01560 LOGPRINTF("page-size %f, lower %f, upper %f, gotopage %d, check %f -- %f >> %f",
01561 page_size, lower, upper, page,
01562 (page - 1) * (page_size * (100-PAGE_OVERLAP) / 100),
01563 upper - page_size,
01564 value);
01565
01566 gtk_adjustment_set_value(adjustment, value);
01567 }
01568
01569
01570 static void show_busy_loading(gboolean show)
01571 {
01572 LOGPRINTF("entry");
01573
01574 if (show)
01575 {
01576 gtk_widget_show_all(busy_dialog);
01577 }
01578 else
01579 {
01580 gtk_widget_hide_all(busy_dialog);
01581 }
01582 }
01583
01584
01585 static void show_busy(gboolean show)
01586 {
01587 static gint show_count = 0;
01588
01589 LOGPRINTF("entry [%d] count [%d]", show, show_count);
01590
01591 if (show)
01592 {
01593 show_count++;
01594 if (show_count==1)
01595 {
01596 show_busy_loading(TRUE);
01597 display_gain_control();
01598 ipc_sys_set_busy_nodialog(TRUE);
01599 }
01600 }
01601 else
01602 {
01603 if (show_count > 0)
01604 {
01605 show_count--;
01606 }
01607 if (show_count==0)
01608 {
01609 show_busy_loading(FALSE);
01610 display_return_control();
01611 ipc_sys_set_busy_nodialog(FALSE);
01612 }
01613 }
01614 }
01615
01616
01617
01618
01619
01620
01621 static gchar *magic_uri(const gchar *uri)
01622 {
01623 LOGPRINTF("entry: %s", uri);
01624
01625 gchar *result = NULL;
01626
01627 g_return_val_if_fail(uri, NULL);
01628
01629
01630 if (g_str_has_prefix(uri, "javascript:"))
01631 {
01632 return g_strdup(uri);
01633 }
01634
01635 if (g_mountpoint)
01636 {
01637
01638 gchar *path = g_strconcat(g_mountpoint, uri, NULL);
01639 if (g_file_test(path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
01640 {
01641 result = g_strconcat("file://", path, NULL);
01642 g_free(path);
01643 return result;
01644 }
01645 g_free(path);
01646 }
01647
01648
01649 if (g_path_is_absolute(uri))
01650 {
01651 return g_strconcat("file://", uri, NULL);
01652 }
01653
01654
01655 if (g_file_test(uri, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
01656 {
01657 gchar *current_dir = g_get_current_dir();
01658 result = g_strconcat("file://", current_dir, G_DIR_SEPARATOR_S, uri, NULL);
01659 g_free(current_dir);
01660 return result;
01661 }
01662
01663
01664 if (!strstr(uri, "://"))
01665 {
01666
01667 gchar *search = strchr(uri, ':');
01668 if (search && search[0] && !g_ascii_isalpha(search[1]))
01669 {
01670 if (!strchr(search, '.'))
01671 {
01672 return g_strconcat("http://", uri, NULL);
01673 }
01674 }
01675
01676 if (!strcmp(uri, "localhost") || g_str_has_prefix(uri, "localhost/"))
01677 {
01678 return g_strconcat("http://", uri, NULL);
01679 }
01680
01681 gchar** parts = g_strsplit(uri, ".", 0);
01682 if (!search && parts[0] && parts[1])
01683 {
01684 search = NULL;
01685 if (!(parts[1][1] == '\0' && !g_ascii_isalpha(parts[1][0])))
01686 {
01687 if (!strchr(parts[0], ' ') && !strchr(parts[1], ' '))
01688 {
01689 search = g_strconcat("http://", uri, NULL);
01690 }
01691 }
01692 g_free(parts);
01693 if (search)
01694 {
01695 return search;
01696 }
01697 }
01698 return g_strdup(uri);
01699 }
01700 return g_strdup(uri);
01701 }
01702
01703
01704 static void set_browser_uri(const gchar *uri)
01705 {
01706 LOGPRINTF("entry");
01707
01708 if (g_browser && uri)
01709 {
01710 LOGPRINTF("set uri [%s]", uri);
01711 g_free(g_browser->uri);
01712 g_browser->uri = g_strdup(uri);
01713 }
01714 }
01715
01716
01717 static void on_cancel(GtkWidget *widget, gpointer data)
01718 {
01719 LOGPRINTF("entry");
01720 webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(g_browser->web_view));
01721 }
01722
01723
01724 static void create_show_busy_loading()
01725 {
01726 busy_dialog = ergtk_busy_dialog_new(_("Loading page..."));
01727 cancel_button = gtk_button_new_with_label(_("Cancel"));
01728 gtk_dialog_add_action_widget(GTK_DIALOG(busy_dialog), cancel_button, GTK_RESPONSE_REJECT);
01729 g_signal_connect(G_OBJECT(cancel_button), "clicked", G_CALLBACK(on_cancel), NULL);
01730 }
01731
01732
01733 static gchar* get_file_content(const gchar* file_path)
01734 {
01735 gchar* contents = NULL;
01736 gsize len = 0;
01737
01738 if (g_file_get_contents(file_path, &contents, &len, NULL) == FALSE)
01739 {
01740 return NULL;
01741 }
01742
01743
01744
01745 while (len > 0 && (contents[len - 1] == '\n' || contents[len - 1] == '\0'))
01746 {
01747 contents[len - 1] = '\0';
01748 len--;
01749 }
01750 return contents;
01751 }
01752
01753
01754 static gchar* get_ebook_mall_home()
01755 {
01756 gchar* uri = NULL;
01757 gchar* serial = NULL;
01758 char hostname[100] = {0};
01759 int rc = gethostname(hostname, sizeof(hostname));
01760 if ((rc == 0) && (strcmp(hostname, "qemuarm") == 0))
01761 {
01762
01763 serial = g_strdup("DREMU-LATOR");
01764 }
01765 else
01766 {
01767 serial = get_file_content("/sys/devices/system/sysset/sysset0/fasm/serial");
01768 }
01769
01770 uri = g_strconcat(EBOOK_MALL_HOME, serial, NULL);
01771 g_free(serial);
01772 return uri;
01773 }