Back to index

lightning-sunbird  0.9+nobinonly
TestGtkEmbed.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard.  All Rights Reserved.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Christopher Blizzard <blizzard@mozilla.org>
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "gtkmozembed.h"
00039 #include <gtk/gtk.h>
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <stdlib.h>
00043 
00044 // mozilla specific headers
00045 #include "nsIDOMKeyEvent.h"
00046 #include "nsIDOMMouseEvent.h"
00047 #include "nsIDOMUIEvent.h"
00048 #include "prenv.h"
00049 
00050 #ifdef NS_TRACE_MALLOC
00051 #include "nsTraceMalloc.h"
00052 #endif
00053 
00054 #ifdef MOZ_JPROF
00055 #include "jprof.h"
00056 #endif
00057 
00058 typedef struct _TestGtkBrowser {
00059   GtkWidget  *topLevelWindow;
00060   GtkWidget  *topLevelVBox;
00061   GtkWidget  *menuBar;
00062   GtkWidget  *fileMenuItem;
00063   GtkWidget  *fileMenu;
00064   GtkWidget  *fileOpenNewBrowser;
00065   GtkWidget  *fileStream;
00066   GtkWidget  *fileClose;
00067   GtkWidget  *fileQuit;
00068   GtkWidget  *toolbarHBox;
00069   GtkWidget  *toolbar;
00070   GtkWidget  *backButton;
00071   GtkWidget  *stopButton;
00072   GtkWidget  *forwardButton;
00073   GtkWidget  *reloadButton;
00074   GtkWidget  *urlEntry;
00075   GtkWidget  *mozEmbed;
00076   GtkWidget  *progressAreaHBox;
00077   GtkWidget  *progressBar;
00078   GtkWidget  *statusAlign;
00079   GtkWidget  *statusBar;
00080   const char *statusMessage;
00081   int         loadPercent;
00082   int         bytesLoaded;
00083   int         maxBytesLoaded;
00084   char       *tempMessage;
00085   gboolean menuBarOn;
00086   gboolean toolBarOn;
00087   gboolean locationBarOn;
00088   gboolean statusBarOn;
00089 
00090 } TestGtkBrowser;
00091 
00092 // the list of browser windows currently open
00093 GList *browser_list = g_list_alloc();
00094 
00095 static TestGtkBrowser *new_gtk_browser    (guint32 chromeMask);
00096 static void            set_browser_visibility (TestGtkBrowser *browser,
00097                                           gboolean visibility);
00098 
00099 static int num_browsers = 0;
00100 
00101 // callbacks from the UI
00102 static void     back_clicked_cb    (GtkButton   *button, 
00103                                 TestGtkBrowser *browser);
00104 static void     stop_clicked_cb    (GtkButton   *button,
00105                                 TestGtkBrowser *browser);
00106 static void     forward_clicked_cb (GtkButton   *button,
00107                                 TestGtkBrowser *browser);
00108 static void     reload_clicked_cb  (GtkButton   *button,
00109                                 TestGtkBrowser *browser);
00110 static void     url_activate_cb    (GtkEditable *widget, 
00111                                 TestGtkBrowser *browser);
00112 static void     menu_open_new_cb   (GtkMenuItem *menuitem,
00113                                 TestGtkBrowser *browser);
00114 static void     menu_stream_cb     (GtkMenuItem *menuitem,
00115                                 TestGtkBrowser *browser);
00116 static void     menu_close_cb      (GtkMenuItem *menuitem,
00117                                 TestGtkBrowser *browser);
00118 static void     menu_quit_cb       (GtkMenuItem *menuitem,
00119                                 TestGtkBrowser *browser);
00120 static gboolean delete_cb          (GtkWidget *widget, GdkEventAny *event,
00121                                 TestGtkBrowser *browser);
00122 static void     destroy_cb         (GtkWidget *widget,
00123                                 TestGtkBrowser *browser);
00124 
00125 // callbacks from the widget
00126 static void location_changed_cb  (GtkMozEmbed *embed, TestGtkBrowser *browser);
00127 static void title_changed_cb     (GtkMozEmbed *embed, TestGtkBrowser *browser);
00128 static void load_started_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser);
00129 static void load_finished_cb     (GtkMozEmbed *embed, TestGtkBrowser *browser);
00130 static void net_state_change_cb  (GtkMozEmbed *embed, gint flags,
00131                               guint status, TestGtkBrowser *browser);
00132 static void net_state_change_all_cb (GtkMozEmbed *embed, const char *uri,
00133                                  gint flags, guint status,
00134                                  TestGtkBrowser *browser);
00135 static void progress_change_cb   (GtkMozEmbed *embed, gint cur, gint max,
00136                               TestGtkBrowser *browser);
00137 static void progress_change_all_cb (GtkMozEmbed *embed, const char *uri,
00138                                 gint cur, gint max,
00139                                 TestGtkBrowser *browser);
00140 static void link_message_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser);
00141 static void js_status_cb         (GtkMozEmbed *embed, TestGtkBrowser *browser);
00142 static void new_window_cb        (GtkMozEmbed *embed,
00143                               GtkMozEmbed **retval, guint chromemask,
00144                               TestGtkBrowser *browser);
00145 static void visibility_cb        (GtkMozEmbed *embed, 
00146                               gboolean visibility,
00147                               TestGtkBrowser *browser);
00148 static void destroy_brsr_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser);
00149 static gint open_uri_cb          (GtkMozEmbed *embed, const char *uri,
00150                               TestGtkBrowser *browser);
00151 static void size_to_cb           (GtkMozEmbed *embed, gint width,
00152                               gint height, TestGtkBrowser *browser);
00153 static gint dom_key_down_cb      (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
00154                               TestGtkBrowser *browser);
00155 static gint dom_key_press_cb     (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
00156                               TestGtkBrowser *browser);
00157 static gint dom_key_up_cb        (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
00158                               TestGtkBrowser *browser);
00159 static gint dom_mouse_down_cb    (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00160                               TestGtkBrowser *browser);
00161 static gint dom_mouse_up_cb      (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00162                               TestGtkBrowser *browser);
00163 static gint dom_mouse_click_cb   (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00164                               TestGtkBrowser *browser);
00165 static gint dom_mouse_dbl_click_cb (GtkMozEmbed *embed, 
00166                               nsIDOMMouseEvent *event,
00167                               TestGtkBrowser *browser);
00168 static gint dom_mouse_over_cb    (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00169                               TestGtkBrowser *browser);
00170 static gint dom_mouse_out_cb     (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00171                               TestGtkBrowser *browser);
00172 static gint dom_activate_cb      (GtkMozEmbed *embed, nsIDOMUIEvent *event,
00173                               TestGtkBrowser *browser);
00174 static gint dom_focus_in_cb      (GtkMozEmbed *embed, nsIDOMUIEvent *event,
00175                               TestGtkBrowser *browser);
00176 static gint dom_focus_out_cb     (GtkMozEmbed *embed, nsIDOMUIEvent *event,
00177                               TestGtkBrowser *browser);
00178 
00179 // callbacks from the singleton object
00180 static void new_window_orphan_cb (GtkMozEmbedSingle *embed,
00181                               GtkMozEmbed **retval, guint chromemask,
00182                               gpointer data);
00183 
00184 // some utility functions
00185 static void update_status_bar_text  (TestGtkBrowser *browser);
00186 static void update_temp_message     (TestGtkBrowser *browser,
00187                                  const char *message);
00188 static void update_nav_buttons      (TestGtkBrowser *browser);
00189 
00190 int
00191 main(int argc, char **argv)
00192 {
00193 #ifdef NS_TRACE_MALLOC
00194   argc = NS_TraceMallocStartupArgs(argc, argv);
00195 #endif
00196 
00197   gtk_set_locale();
00198   gtk_init(&argc, &argv);
00199 
00200 #ifdef MOZ_JPROF
00201   setupProfilingStuff();
00202 #endif
00203 
00204   char *home_path;
00205   char *full_path;
00206   home_path = PR_GetEnv("HOME");
00207   if (!home_path) {
00208     fprintf(stderr, "Failed to get HOME\n");
00209     exit(1);
00210   }
00211   
00212   full_path = g_strdup_printf("%s/%s", home_path, ".TestGtkEmbed");
00213   
00214   gtk_moz_embed_set_profile_path(full_path, "TestGtkEmbed");
00215 
00216   TestGtkBrowser *browser = new_gtk_browser(GTK_MOZ_EMBED_FLAG_DEFAULTCHROME);
00217 
00218   // set our minimum size
00219   gtk_widget_set_usize(browser->mozEmbed, 400, 400);
00220 
00221   set_browser_visibility(browser, TRUE);
00222 
00223   if (argc > 1)
00224     gtk_moz_embed_load_url(GTK_MOZ_EMBED(browser->mozEmbed), argv[1]);
00225 
00226   // get the singleton object and hook up to its new window callback
00227   // so we can create orphaned windows.
00228 
00229   GtkMozEmbedSingle *single;
00230 
00231   single = gtk_moz_embed_single_get();
00232   if (!single) {
00233     fprintf(stderr, "Failed to get singleton embed object!\n");
00234     exit(1);
00235   }
00236 
00237   gtk_signal_connect(GTK_OBJECT(single), "new_window_orphan",
00238                    GTK_SIGNAL_FUNC(new_window_orphan_cb), NULL);
00239 
00240   gtk_main();
00241 }
00242 
00243 static TestGtkBrowser *
00244 new_gtk_browser(guint32 chromeMask)
00245 {
00246   guint32         actualChromeMask = chromeMask;
00247   TestGtkBrowser *browser = 0;
00248 
00249   num_browsers++;
00250 
00251   browser = g_new0(TestGtkBrowser, 1);
00252 
00253   browser_list = g_list_prepend(browser_list, browser);
00254 
00255   browser->menuBarOn = FALSE;
00256   browser->toolBarOn = FALSE;
00257   browser->locationBarOn = FALSE;
00258   browser->statusBarOn = FALSE;
00259 
00260   g_print("new_gtk_browser\n");
00261 
00262   if (chromeMask == GTK_MOZ_EMBED_FLAG_DEFAULTCHROME)
00263     actualChromeMask = GTK_MOZ_EMBED_FLAG_ALLCHROME;
00264 
00265   if (actualChromeMask & GTK_MOZ_EMBED_FLAG_MENUBARON)
00266   {
00267     browser->menuBarOn = TRUE;
00268     g_print("\tmenu bar\n");
00269   }
00270   if (actualChromeMask & GTK_MOZ_EMBED_FLAG_TOOLBARON)
00271   {
00272     browser->toolBarOn = TRUE;
00273     g_print("\ttool bar\n");
00274   }
00275   if (actualChromeMask & GTK_MOZ_EMBED_FLAG_LOCATIONBARON)
00276   {
00277     browser->locationBarOn = TRUE;
00278     g_print("\tlocation bar\n");
00279   }
00280   if (actualChromeMask & GTK_MOZ_EMBED_FLAG_STATUSBARON)
00281   {
00282     browser->statusBarOn = TRUE;
00283     g_print("\tstatus bar\n");
00284   }
00285 
00286   // create our new toplevel window
00287   browser->topLevelWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00288   // new vbox
00289   browser->topLevelVBox = gtk_vbox_new(FALSE, 0);
00290   // add it to the toplevel window
00291   gtk_container_add(GTK_CONTAINER(browser->topLevelWindow),
00292                   browser->topLevelVBox);
00293   // create our menu bar
00294   browser->menuBar = gtk_menu_bar_new();
00295   // create the file menu
00296   browser->fileMenuItem = gtk_menu_item_new_with_label("File");
00297   browser->fileMenu = gtk_menu_new();
00298   gtk_menu_item_set_submenu (GTK_MENU_ITEM(browser->fileMenuItem),
00299                           browser->fileMenu);
00300 
00301   browser->fileOpenNewBrowser = 
00302     gtk_menu_item_new_with_label("Open New Browser");
00303   gtk_menu_append(GTK_MENU(browser->fileMenu),
00304                 browser->fileOpenNewBrowser);
00305   
00306   browser->fileStream =
00307     gtk_menu_item_new_with_label("Test Stream");
00308   gtk_menu_append(GTK_MENU(browser->fileMenu),
00309                 browser->fileStream);
00310 
00311   browser->fileClose =
00312     gtk_menu_item_new_with_label("Close");
00313   gtk_menu_append(GTK_MENU(browser->fileMenu),
00314                 browser->fileClose);
00315 
00316   browser->fileQuit =
00317     gtk_menu_item_new_with_label("Quit");
00318   gtk_menu_append(GTK_MENU(browser->fileMenu),
00319                 browser->fileQuit);
00320   
00321   // append it
00322   gtk_menu_bar_append(GTK_MENU_BAR(browser->menuBar), browser->fileMenuItem);
00323 
00324   // add it to the vbox
00325   gtk_box_pack_start(GTK_BOX(browser->topLevelVBox),
00326                    browser->menuBar,
00327                    FALSE, // expand
00328                    FALSE, // fill
00329                    0);    // padding
00330   // create the hbox that will contain the toolbar and the url text entry bar
00331   browser->toolbarHBox = gtk_hbox_new(FALSE, 0);
00332   // add that hbox to the vbox
00333   gtk_box_pack_start(GTK_BOX(browser->topLevelVBox), 
00334                    browser->toolbarHBox,
00335                    FALSE, // expand
00336                    FALSE, // fill
00337                    0);    // padding
00338   // new horiz toolbar with buttons + icons
00339 #ifdef MOZ_WIDGET_GTK
00340   browser->toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL,
00341                                  GTK_TOOLBAR_BOTH);
00342 #endif /* MOZ_WIDGET_GTK */
00343 
00344 #ifdef MOZ_WIDGET_GTK2
00345   browser->toolbar = gtk_toolbar_new();
00346   gtk_toolbar_set_orientation(GTK_TOOLBAR(browser->toolbar),
00347                            GTK_ORIENTATION_HORIZONTAL);
00348   gtk_toolbar_set_style(GTK_TOOLBAR(browser->toolbar),
00349                      GTK_TOOLBAR_BOTH);
00350 #endif /* MOZ_WIDGET_GTK2 */
00351 
00352   // add it to the hbox
00353   gtk_box_pack_start(GTK_BOX(browser->toolbarHBox), browser->toolbar,
00354                  FALSE, // expand
00355                  FALSE, // fill
00356                  0);    // padding
00357   // new back button
00358   browser->backButton =
00359     gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
00360                          "Back",
00361                          "Go Back",
00362                          "Go Back",
00363                          0, // XXX replace with icon
00364                          GTK_SIGNAL_FUNC(back_clicked_cb),
00365                          browser);
00366   // new stop button
00367   browser->stopButton = 
00368     gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
00369                          "Stop",
00370                          "Stop",
00371                          "Stop",
00372                          0, // XXX replace with icon
00373                          GTK_SIGNAL_FUNC(stop_clicked_cb),
00374                          browser);
00375   // new forward button
00376   browser->forwardButton =
00377     gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
00378                          "Forward",
00379                          "Forward",
00380                          "Forward",
00381                          0, // XXX replace with icon
00382                          GTK_SIGNAL_FUNC(forward_clicked_cb),
00383                          browser);
00384   // new reload button
00385   browser->reloadButton = 
00386     gtk_toolbar_append_item(GTK_TOOLBAR(browser->toolbar),
00387                          "Reload",
00388                          "Reload",
00389                          "Reload",
00390                          0, // XXX replace with icon
00391                          GTK_SIGNAL_FUNC(reload_clicked_cb),
00392                          browser);
00393   // create the url text entry
00394   browser->urlEntry = gtk_entry_new();
00395   // add it to the hbox
00396   gtk_box_pack_start(GTK_BOX(browser->toolbarHBox), browser->urlEntry,
00397                    TRUE, // expand
00398                    TRUE, // fill
00399                    0);    // padding
00400   // create our new gtk moz embed widget
00401   browser->mozEmbed = gtk_moz_embed_new();
00402   // add it to the toplevel vbox
00403   gtk_box_pack_start(GTK_BOX(browser->topLevelVBox), browser->mozEmbed,
00404                    TRUE, // expand
00405                    TRUE, // fill
00406                    0);   // padding
00407   // create the new hbox for the progress area
00408   browser->progressAreaHBox = gtk_hbox_new(FALSE, 0);
00409   // add it to the vbox
00410   gtk_box_pack_start(GTK_BOX(browser->topLevelVBox), browser->progressAreaHBox,
00411                    FALSE, // expand
00412                    FALSE, // fill
00413                    0);   // padding
00414   // create our new progress bar
00415   browser->progressBar = gtk_progress_bar_new();
00416   // add it to the hbox
00417   gtk_box_pack_start(GTK_BOX(browser->progressAreaHBox), browser->progressBar,
00418                    FALSE, // expand
00419                    FALSE, // fill
00420                    0); // padding
00421   
00422   // create our status area and the alignment object that will keep it
00423   // from expanding
00424   browser->statusAlign = gtk_alignment_new(0, 0, 1, 1);
00425   gtk_widget_set_usize(browser->statusAlign, 1, -1);
00426   // create the status bar
00427   browser->statusBar = gtk_statusbar_new();
00428   gtk_container_add(GTK_CONTAINER(browser->statusAlign), browser->statusBar);
00429   // add it to the hbox
00430   gtk_box_pack_start(GTK_BOX(browser->progressAreaHBox), browser->statusAlign,
00431                    TRUE, // expand
00432                    TRUE, // fill
00433                    0);   // padding
00434   // by default none of the buttons are marked as sensitive.
00435   gtk_widget_set_sensitive(browser->backButton, FALSE);
00436   gtk_widget_set_sensitive(browser->stopButton, FALSE);
00437   gtk_widget_set_sensitive(browser->forwardButton, FALSE);
00438   gtk_widget_set_sensitive(browser->reloadButton, FALSE);
00439   
00440   // catch the destruction of the toplevel window
00441   gtk_signal_connect(GTK_OBJECT(browser->topLevelWindow), "delete_event",
00442                    GTK_SIGNAL_FUNC(delete_cb), browser);
00443 
00444   // hook up the activate signal to the right callback
00445   gtk_signal_connect(GTK_OBJECT(browser->urlEntry), "activate",
00446                    GTK_SIGNAL_FUNC(url_activate_cb), browser);
00447 
00448   // hook up to the open new browser activation
00449   gtk_signal_connect(GTK_OBJECT(browser->fileOpenNewBrowser), "activate",
00450                    GTK_SIGNAL_FUNC(menu_open_new_cb), browser);
00451   // hook up to the stream test
00452   gtk_signal_connect(GTK_OBJECT(browser->fileStream), "activate",
00453                    GTK_SIGNAL_FUNC(menu_stream_cb), browser);
00454   // close this window
00455   gtk_signal_connect(GTK_OBJECT(browser->fileClose), "activate",
00456                    GTK_SIGNAL_FUNC(menu_close_cb), browser);
00457   // quit the application
00458   gtk_signal_connect(GTK_OBJECT(browser->fileQuit), "activate",
00459                    GTK_SIGNAL_FUNC(menu_quit_cb), browser);
00460 
00461   // hook up the location change to update the urlEntry
00462   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "location",
00463                    GTK_SIGNAL_FUNC(location_changed_cb), browser);
00464   // hook up the title change to update the window title
00465   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "title",
00466                    GTK_SIGNAL_FUNC(title_changed_cb), browser);
00467   // hook up the start and stop signals
00468   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "net_start",
00469                    GTK_SIGNAL_FUNC(load_started_cb), browser);
00470   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "net_stop",
00471                    GTK_SIGNAL_FUNC(load_finished_cb), browser);
00472   // hook up to the change in network status
00473   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "net_state",
00474                    GTK_SIGNAL_FUNC(net_state_change_cb), browser);
00475   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "net_state_all",
00476                    GTK_SIGNAL_FUNC(net_state_change_all_cb), browser);
00477   // hookup to changes in progress
00478   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "progress",
00479                    GTK_SIGNAL_FUNC(progress_change_cb), browser);
00480   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "progress_all",
00481                    GTK_SIGNAL_FUNC(progress_change_all_cb), browser);
00482   // hookup to changes in over-link message
00483   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "link_message",
00484                    GTK_SIGNAL_FUNC(link_message_cb), browser);
00485   // hookup to changes in js status message
00486   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "js_status",
00487                    GTK_SIGNAL_FUNC(js_status_cb), browser);
00488   // hookup to see whenever a new window is requested
00489   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "new_window",
00490                    GTK_SIGNAL_FUNC(new_window_cb), browser);
00491   // hookup to any requested visibility changes
00492   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "visibility",
00493                    GTK_SIGNAL_FUNC(visibility_cb), browser);
00494   // hookup to the signal that says that the browser requested to be
00495   // destroyed
00496   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "destroy_browser",
00497                    GTK_SIGNAL_FUNC(destroy_brsr_cb), browser);
00498   // hookup to the signal that is called when someone clicks on a link
00499   // to load a new uri
00500   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "open_uri",
00501                    GTK_SIGNAL_FUNC(open_uri_cb), browser);
00502   // this signal is emitted when there's a request to change the
00503   // containing browser window to a certain height, like with width
00504   // and height args for a window.open in javascript
00505   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "size_to",
00506                    GTK_SIGNAL_FUNC(size_to_cb), browser);
00507   // key event signals
00508   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_key_down",
00509                    GTK_SIGNAL_FUNC(dom_key_down_cb), browser);
00510   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_key_press",
00511                    GTK_SIGNAL_FUNC(dom_key_press_cb), browser);
00512   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_key_up",
00513                    GTK_SIGNAL_FUNC(dom_key_up_cb), browser);
00514   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_down",
00515                    GTK_SIGNAL_FUNC(dom_mouse_down_cb), browser);
00516   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_up",
00517                    GTK_SIGNAL_FUNC(dom_mouse_up_cb), browser);
00518   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_click",
00519                    GTK_SIGNAL_FUNC(dom_mouse_click_cb), browser);
00520   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_dbl_click",
00521                    GTK_SIGNAL_FUNC(dom_mouse_dbl_click_cb), browser);
00522   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_over",
00523                    GTK_SIGNAL_FUNC(dom_mouse_over_cb), browser);
00524   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_mouse_out",
00525                    GTK_SIGNAL_FUNC(dom_mouse_out_cb), browser);
00526   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_activate",
00527                    GTK_SIGNAL_FUNC(dom_activate_cb), browser);
00528   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_focus_in",
00529                    GTK_SIGNAL_FUNC(dom_focus_in_cb), browser);
00530   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "dom_focus_out",
00531                    GTK_SIGNAL_FUNC(dom_focus_out_cb), browser);
00532   // hookup to when the window is destroyed
00533   gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "destroy",
00534                    GTK_SIGNAL_FUNC(destroy_cb), browser);
00535   
00536   // set the chrome type so it's stored in the object
00537   gtk_moz_embed_set_chrome_mask(GTK_MOZ_EMBED(browser->mozEmbed),
00538                             actualChromeMask);
00539 
00540   return browser;
00541 }
00542 
00543 void
00544 set_browser_visibility (TestGtkBrowser *browser, gboolean visibility)
00545 {
00546   if (!visibility)
00547   {
00548     gtk_widget_hide(browser->topLevelWindow);
00549     return;
00550   }
00551   
00552   if (browser->menuBarOn)
00553     gtk_widget_show_all(browser->menuBar);
00554   else
00555     gtk_widget_hide_all(browser->menuBar);
00556 
00557   // since they are on the same line here...
00558   if (browser->toolBarOn || browser->locationBarOn)
00559     gtk_widget_show_all(browser->toolbarHBox);
00560   else 
00561     gtk_widget_hide_all(browser->toolbarHBox);
00562 
00563   if (browser->statusBarOn)
00564     gtk_widget_show_all(browser->progressAreaHBox);
00565   else
00566     gtk_widget_hide_all(browser->progressAreaHBox);
00567 
00568   gtk_widget_show(browser->mozEmbed);
00569   gtk_widget_show(browser->topLevelVBox);
00570   gtk_widget_show(browser->topLevelWindow);
00571 }
00572 
00573 void
00574 back_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
00575 {
00576   gtk_moz_embed_go_back(GTK_MOZ_EMBED(browser->mozEmbed));
00577 }
00578 
00579 void
00580 stop_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
00581 {
00582   g_print("stop_clicked_cb\n");
00583   gtk_moz_embed_stop_load(GTK_MOZ_EMBED(browser->mozEmbed));
00584 }
00585 
00586 void
00587 forward_clicked_cb (GtkButton *button, TestGtkBrowser *browser)
00588 {
00589   g_print("forward_clicked_cb\n");
00590   gtk_moz_embed_go_forward(GTK_MOZ_EMBED(browser->mozEmbed));
00591 }
00592 
00593 void
00594 reload_clicked_cb  (GtkButton *button, TestGtkBrowser *browser)
00595 {
00596   g_print("reload_clicked_cb\n");
00597   GdkModifierType state = (GdkModifierType)0;
00598   gint x, y;
00599   gdk_window_get_pointer(NULL, &x, &y, &state);
00600   
00601   gtk_moz_embed_reload(GTK_MOZ_EMBED(browser->mozEmbed),
00602                      (state & GDK_SHIFT_MASK) ?
00603                      GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE : 
00604                      GTK_MOZ_EMBED_FLAG_RELOADNORMAL);
00605 }
00606 
00607 void 
00608 stream_clicked_cb  (GtkButton   *button, TestGtkBrowser *browser)
00609 {
00610   const char *data;
00611   const char *data2;
00612   data = "<html>Hi";
00613   data2 = " there</html>\n";
00614   g_print("stream_clicked_cb\n");
00615   gtk_moz_embed_open_stream(GTK_MOZ_EMBED(browser->mozEmbed),
00616                          "file://", "text/html");
00617   gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
00618                          data, strlen(data));
00619   gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
00620                          data2, strlen(data2));
00621   gtk_moz_embed_close_stream(GTK_MOZ_EMBED(browser->mozEmbed));
00622 }
00623 
00624 void
00625 url_activate_cb    (GtkEditable *widget, TestGtkBrowser *browser)
00626 {
00627   gchar *text = gtk_editable_get_chars(widget, 0, -1);
00628   g_print("loading url %s\n", text);
00629   gtk_moz_embed_load_url(GTK_MOZ_EMBED(browser->mozEmbed), text);
00630   g_free(text);
00631 }
00632 
00633 void
00634 menu_open_new_cb   (GtkMenuItem *menuitem, TestGtkBrowser *browser)
00635 {
00636   g_print("opening new browser.\n");
00637   TestGtkBrowser *newBrowser = 
00638     new_gtk_browser(GTK_MOZ_EMBED_FLAG_DEFAULTCHROME);
00639   gtk_widget_set_usize(newBrowser->mozEmbed, 400, 400);
00640   set_browser_visibility(newBrowser, TRUE);
00641 }
00642 
00643 void
00644 menu_stream_cb     (GtkMenuItem *menuitem, TestGtkBrowser *browser)
00645 {
00646   g_print("menu_stream_cb\n");
00647   const char *data;
00648   const char *data2;
00649   data = "<html>Hi";
00650   data2 = " <a href='foo.html'>there</a></html>\n";
00651   g_print("stream_clicked_cb\n");
00652   gtk_moz_embed_open_stream(GTK_MOZ_EMBED(browser->mozEmbed),
00653                          "file://", "text/html");
00654   gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
00655                          data, strlen(data));
00656   gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
00657                          data2, strlen(data2));
00658   gtk_moz_embed_close_stream(GTK_MOZ_EMBED(browser->mozEmbed));
00659 }
00660 
00661 void
00662 menu_close_cb (GtkMenuItem *menuitem, TestGtkBrowser *browser)
00663 {
00664   gtk_widget_destroy(browser->topLevelWindow);
00665 }
00666 
00667 void
00668 menu_quit_cb (GtkMenuItem *menuitem, TestGtkBrowser *browser)
00669 {
00670   TestGtkBrowser *tmpBrowser;
00671   GList *tmp_list = browser_list;
00672   tmpBrowser = (TestGtkBrowser *)tmp_list->data;
00673   while (tmpBrowser) {
00674     tmp_list = tmp_list->next;
00675     gtk_widget_destroy(tmpBrowser->topLevelWindow);
00676     tmpBrowser = (TestGtkBrowser *)tmp_list->data;
00677   }
00678 }
00679 
00680 gboolean
00681 delete_cb(GtkWidget *widget, GdkEventAny *event, TestGtkBrowser *browser)
00682 {
00683   g_print("delete_cb\n");
00684   gtk_widget_destroy(widget);
00685   return TRUE;
00686 }
00687 
00688 void
00689 destroy_cb         (GtkWidget *widget, TestGtkBrowser *browser)
00690 {
00691   GList *tmp_list;
00692   g_print("destroy_cb\n");
00693   num_browsers--;
00694   tmp_list = g_list_find(browser_list, browser);
00695   browser_list = g_list_remove_link(browser_list, tmp_list);
00696   if (browser->tempMessage)
00697     g_free(browser->tempMessage);
00698   if (num_browsers == 0)
00699     gtk_main_quit();
00700 }
00701 
00702 void
00703 location_changed_cb (GtkMozEmbed *embed, TestGtkBrowser *browser)
00704 {
00705   char *newLocation;
00706   int   newPosition = 0;
00707   g_print("location_changed_cb\n");
00708   newLocation = gtk_moz_embed_get_location(embed);
00709   if (newLocation)
00710   {
00711     gtk_editable_delete_text(GTK_EDITABLE(browser->urlEntry), 0, -1);
00712     gtk_editable_insert_text(GTK_EDITABLE(browser->urlEntry),
00713                           newLocation, strlen(newLocation), &newPosition);
00714     g_free(newLocation);
00715   }
00716   else
00717     g_print("failed to get location!\n");
00718   // always make sure to clear the tempMessage.  it might have been
00719   // set from the link before a click and we wouldn't have gotten the
00720   // callback to unset it.
00721   update_temp_message(browser, 0);
00722   // update the nav buttons on a location change
00723   update_nav_buttons(browser);
00724 }
00725 
00726 void
00727 title_changed_cb    (GtkMozEmbed *embed, TestGtkBrowser *browser)
00728 {
00729   char *newTitle;
00730   g_print("title_changed_cb\n");
00731   newTitle = gtk_moz_embed_get_title(embed);
00732   if (newTitle)
00733   {
00734     gtk_window_set_title(GTK_WINDOW(browser->topLevelWindow), newTitle);
00735     g_free(newTitle);
00736   }
00737   
00738 }
00739 
00740 void
00741 load_started_cb     (GtkMozEmbed *embed, TestGtkBrowser *browser)
00742 {
00743   g_print("load_started_cb\n");
00744   gtk_widget_set_sensitive(browser->stopButton, TRUE);
00745   gtk_widget_set_sensitive(browser->reloadButton, FALSE);
00746   browser->loadPercent = 0;
00747   browser->bytesLoaded = 0;
00748   browser->maxBytesLoaded = 0;
00749   update_status_bar_text(browser);
00750 }
00751 
00752 void
00753 load_finished_cb    (GtkMozEmbed *embed, TestGtkBrowser *browser)
00754 {
00755   g_print("load_finished_cb\n");
00756   gtk_widget_set_sensitive(browser->stopButton, FALSE);
00757   gtk_widget_set_sensitive(browser->reloadButton, TRUE);
00758   browser->loadPercent = 0;
00759   browser->bytesLoaded = 0;
00760   browser->maxBytesLoaded = 0;
00761   update_status_bar_text(browser);
00762   gtk_progress_set_percentage(GTK_PROGRESS(browser->progressBar), 0);
00763 }
00764 
00765 
00766 void
00767 net_state_change_cb (GtkMozEmbed *embed, gint flags, guint status,
00768                    TestGtkBrowser *browser)
00769 {
00770   g_print("net_state_change_cb %d\n", flags);
00771   if (flags & GTK_MOZ_EMBED_FLAG_IS_REQUEST) {
00772     if (flags & GTK_MOZ_EMBED_FLAG_REDIRECTING)
00773     browser->statusMessage = "Redirecting to site...";
00774     else if (flags & GTK_MOZ_EMBED_FLAG_TRANSFERRING)
00775     browser->statusMessage = "Transferring data from site...";
00776     else if (flags & GTK_MOZ_EMBED_FLAG_NEGOTIATING)
00777     browser->statusMessage = "Waiting for authorization...";
00778   }
00779 
00780   if (status == GTK_MOZ_EMBED_STATUS_FAILED_DNS)
00781     browser->statusMessage = "Site not found.";
00782   else if (status == GTK_MOZ_EMBED_STATUS_FAILED_CONNECT)
00783     browser->statusMessage = "Failed to connect to site.";
00784   else if (status == GTK_MOZ_EMBED_STATUS_FAILED_TIMEOUT)
00785     browser->statusMessage = "Failed due to connection timeout.";
00786   else if (status == GTK_MOZ_EMBED_STATUS_FAILED_USERCANCELED)
00787     browser->statusMessage = "User canceled connecting to site.";
00788 
00789   if (flags & GTK_MOZ_EMBED_FLAG_IS_DOCUMENT) {
00790     if (flags & GTK_MOZ_EMBED_FLAG_START)
00791       browser->statusMessage = "Loading site...";
00792     else if (flags & GTK_MOZ_EMBED_FLAG_STOP)
00793       browser->statusMessage = "Done.";
00794   }
00795 
00796   update_status_bar_text(browser);
00797   
00798 }
00799 
00800 void net_state_change_all_cb (GtkMozEmbed *embed, const char *uri,
00801                                  gint flags, guint status,
00802                                  TestGtkBrowser *browser)
00803 {
00804   //  g_print("net_state_change_all_cb %s %d %d\n", uri, flags, status);
00805 }
00806 
00807 void progress_change_cb   (GtkMozEmbed *embed, gint cur, gint max,
00808                         TestGtkBrowser *browser)
00809 {
00810   g_print("progress_change_cb cur %d max %d\n", cur, max);
00811 
00812   // avoid those pesky divide by zero errors
00813   if (max < 1)
00814   {
00815     gtk_progress_set_activity_mode(GTK_PROGRESS(browser->progressBar), FALSE);
00816     browser->loadPercent = 0;
00817     browser->bytesLoaded = cur;
00818     browser->maxBytesLoaded = 0;
00819     update_status_bar_text(browser);
00820   }
00821   else
00822   {
00823     browser->bytesLoaded = cur;
00824     browser->maxBytesLoaded = max;
00825     if (cur > max)
00826       browser->loadPercent = 100;
00827     else
00828       browser->loadPercent = (cur * 100) / max;
00829     update_status_bar_text(browser);
00830     gtk_progress_set_percentage(GTK_PROGRESS(browser->progressBar), browser->loadPercent / 100.0);
00831   }
00832   
00833 }
00834 
00835 void progress_change_all_cb (GtkMozEmbed *embed, const char *uri,
00836                           gint cur, gint max,
00837                           TestGtkBrowser *browser)
00838 {
00839   //g_print("progress_change_all_cb %s cur %d max %d\n", uri, cur, max);
00840 }
00841 
00842 void
00843 link_message_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser)
00844 {
00845   char *message;
00846   g_print("link_message_cb\n");
00847   message = gtk_moz_embed_get_link_message(embed);
00848   if (!message || !*message)
00849     update_temp_message(browser, 0);
00850   else
00851     update_temp_message(browser, message);
00852   if (message)
00853     g_free(message);
00854 }
00855 
00856 void
00857 js_status_cb (GtkMozEmbed *embed, TestGtkBrowser *browser)
00858 {
00859  char *message;
00860   g_print("js_status_cb\n");
00861   message = gtk_moz_embed_get_js_status(embed);
00862   if (!message || !*message)
00863     update_temp_message(browser, 0);
00864   else
00865     update_temp_message(browser, message);
00866   if (message)
00867     g_free(message);
00868 }
00869 
00870 void
00871 new_window_cb (GtkMozEmbed *embed, GtkMozEmbed **newEmbed, guint chromemask, TestGtkBrowser *browser)
00872 {
00873   g_print("new_window_cb\n");
00874   g_print("embed is %p chromemask is %d\n", (void *)embed, chromemask);
00875   TestGtkBrowser *newBrowser = new_gtk_browser(chromemask);
00876   gtk_widget_set_usize(newBrowser->mozEmbed, 400, 400);
00877   *newEmbed = GTK_MOZ_EMBED(newBrowser->mozEmbed);
00878   g_print("new browser is %p\n", (void *)*newEmbed);
00879 }
00880 
00881 void
00882 visibility_cb (GtkMozEmbed *embed, gboolean visibility, TestGtkBrowser *browser)
00883 {
00884   g_print("visibility_cb %d\n", visibility);
00885   set_browser_visibility(browser, visibility);
00886 }
00887 
00888 void
00889 destroy_brsr_cb      (GtkMozEmbed *embed, TestGtkBrowser *browser)
00890 {
00891   g_print("destroy_brsr_cb\n");
00892   gtk_widget_destroy(browser->topLevelWindow);
00893 }
00894 
00895 gint
00896 open_uri_cb          (GtkMozEmbed *embed, const char *uri, TestGtkBrowser *browser)
00897 {
00898   g_print("open_uri_cb %s\n", uri);
00899 
00900   // interrupt this test load
00901   if (!strcmp(uri, "http://people.redhat.com/blizzard/monkeys.txt"))
00902     return TRUE;
00903   // don't interrupt anything
00904   return FALSE;
00905 }
00906 
00907 void
00908 size_to_cb (GtkMozEmbed *embed, gint width, gint height,
00909            TestGtkBrowser *browser)
00910 {
00911   g_print("*** size_to_cb %d %d\n", width, height);
00912   gtk_widget_set_usize(browser->mozEmbed, width, height);
00913 }
00914 
00915 gint dom_key_down_cb      (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
00916                         TestGtkBrowser *browser)
00917 {
00918   PRUint32 keyCode = 0;
00919   //  g_print("dom_key_down_cb\n");
00920   event->GetKeyCode(&keyCode);
00921   // g_print("key code is %d\n", keyCode);
00922   return NS_OK;
00923 }
00924 
00925 gint dom_key_press_cb     (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
00926                         TestGtkBrowser *browser)
00927 {
00928   PRUint32 keyCode = 0;
00929   // g_print("dom_key_press_cb\n");
00930   event->GetCharCode(&keyCode);
00931   // g_print("char code is %d\n", keyCode);
00932   return NS_OK;
00933 }
00934 
00935 gint dom_key_up_cb        (GtkMozEmbed *embed, nsIDOMKeyEvent *event,
00936                         TestGtkBrowser *browser)
00937 {
00938   PRUint32 keyCode = 0;
00939   // g_print("dom_key_up_cb\n");
00940   event->GetKeyCode(&keyCode);
00941   // g_print("key code is %d\n", keyCode);
00942   return NS_OK;
00943 }
00944 
00945 gint dom_mouse_down_cb    (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00946                         TestGtkBrowser *browser)
00947 {
00948   //  g_print("dom_mouse_down_cb\n");
00949   return NS_OK;
00950  }
00951 
00952 gint dom_mouse_up_cb      (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00953                         TestGtkBrowser *browser)
00954 {
00955   //  g_print("dom_mouse_up_cb\n");
00956   return NS_OK;
00957 }
00958 
00959 gint dom_mouse_click_cb   (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00960                         TestGtkBrowser *browser)
00961 {
00962   //  g_print("dom_mouse_click_cb\n");
00963   PRUint16 button;
00964   event->GetButton(&button);
00965   printf("button was %d\n", button);
00966   return NS_OK;
00967 }
00968 
00969 gint dom_mouse_dbl_click_cb (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00970                           TestGtkBrowser *browser)
00971 {
00972   //  g_print("dom_mouse_dbl_click_cb\n");
00973   return NS_OK;
00974 }
00975 
00976 gint dom_mouse_over_cb    (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00977                         TestGtkBrowser *browser)
00978 {
00979   //g_print("dom_mouse_over_cb\n");
00980   return NS_OK;
00981 }
00982 
00983 gint dom_mouse_out_cb     (GtkMozEmbed *embed, nsIDOMMouseEvent *event,
00984                         TestGtkBrowser *browser)
00985 {
00986   //g_print("dom_mouse_out_cb\n");
00987   return NS_OK;
00988 }
00989 
00990 gint dom_activate_cb      (GtkMozEmbed *embed, nsIDOMUIEvent *event,
00991                         TestGtkBrowser *browser)
00992 {
00993   //g_print("dom_activate_cb\n");
00994   return NS_OK;
00995 }
00996 
00997 gint dom_focus_in_cb      (GtkMozEmbed *embed, nsIDOMUIEvent *event,
00998                         TestGtkBrowser *browser)
00999 {
01000   //g_print("dom_focus_in_cb\n");
01001   return NS_OK;
01002 }
01003 
01004 gint dom_focus_out_cb     (GtkMozEmbed *embed, nsIDOMUIEvent *event,
01005                         TestGtkBrowser *browser)
01006 {
01007   //g_print("dom_focus_out_cb\n");
01008   return NS_OK;
01009 }
01010 
01011 void new_window_orphan_cb (GtkMozEmbedSingle *embed,
01012                         GtkMozEmbed **retval, guint chromemask,
01013                         gpointer data)
01014 {
01015   g_print("new_window_orphan_cb\n");
01016   g_print("chromemask is %d\n", chromemask);
01017   TestGtkBrowser *newBrowser = new_gtk_browser(chromemask);
01018   *retval = GTK_MOZ_EMBED(newBrowser->mozEmbed);
01019   g_print("new browser is %p\n", (void *)*retval);
01020 }
01021 
01022 // utility functions
01023 
01024 void
01025 update_status_bar_text(TestGtkBrowser *browser)
01026 {
01027   gchar message[256];
01028   
01029   gtk_statusbar_pop(GTK_STATUSBAR(browser->statusBar), 1);
01030   if (browser->tempMessage)
01031     gtk_statusbar_push(GTK_STATUSBAR(browser->statusBar), 1, browser->tempMessage);
01032   else
01033   {
01034     if (browser->loadPercent)
01035     {
01036       g_snprintf(message, 255, "%s (%d%% complete, %d bytes of %d loaded)", browser->statusMessage, browser->loadPercent, browser->bytesLoaded, browser->maxBytesLoaded);
01037     }
01038     else if (browser->bytesLoaded)
01039     {
01040       g_snprintf(message, 255, "%s (%d bytes loaded)", browser->statusMessage, browser->bytesLoaded);
01041     }
01042     else if (browser->statusMessage == NULL)
01043     {
01044       g_snprintf(message, 255, " ");
01045     }
01046     else
01047     {
01048       g_snprintf(message, 255, "%s", browser->statusMessage);
01049     }
01050     gtk_statusbar_push(GTK_STATUSBAR(browser->statusBar), 1, message);
01051   }
01052 }
01053 
01054 void
01055 update_temp_message(TestGtkBrowser *browser, const char *message)
01056 {
01057   if (browser->tempMessage)
01058     g_free(browser->tempMessage);
01059   if (message)
01060     browser->tempMessage = g_strdup(message);
01061   else
01062     browser->tempMessage = 0;
01063   // now that we've updated the temp message, redraw the status bar
01064   update_status_bar_text(browser);
01065 }
01066 
01067 
01068 void
01069 update_nav_buttons      (TestGtkBrowser *browser)
01070 {
01071   gboolean can_go_back;
01072   gboolean can_go_forward;
01073   can_go_back = gtk_moz_embed_can_go_back(GTK_MOZ_EMBED(browser->mozEmbed));
01074   can_go_forward = gtk_moz_embed_can_go_forward(GTK_MOZ_EMBED(browser->mozEmbed));
01075   if (can_go_back)
01076     gtk_widget_set_sensitive(browser->backButton, TRUE);
01077   else
01078     gtk_widget_set_sensitive(browser->backButton, FALSE);
01079   if (can_go_forward)
01080     gtk_widget_set_sensitive(browser->forwardButton, TRUE);
01081   else
01082     gtk_widget_set_sensitive(browser->forwardButton, FALSE);
01083  }
01084