diff options
author | François Revel <mmu_man@netsurf-browser.org> | 2012-03-22 21:48:24 +0000 |
---|---|---|
committer | François Revel <mmu_man@netsurf-browser.org> | 2012-03-22 21:48:24 +0000 |
commit | a66adbbfefcc61f4f577b80398a9a0d8941b8441 (patch) | |
tree | b6f6fafc52ec3e0c3d3aff2e7123058b49ec5d69 /beos/scaffolding.cpp | |
parent | 974f53679449da36b10bdccb3241b1f36f0f1936 (diff) | |
download | netsurf-a66adbbfefcc61f4f577b80398a9a0d8941b8441.tar.gz netsurf-a66adbbfefcc61f4f577b80398a9a0d8941b8441.tar.bz2 |
Rename BeOS frontend files to strip the useless beos_ prefix. Fix includes and the rest so it builds.
svn path=/trunk/netsurf/; revision=13554
Diffstat (limited to 'beos/scaffolding.cpp')
-rw-r--r-- | beos/scaffolding.cpp | 2417 |
1 files changed, 2417 insertions, 0 deletions
diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp new file mode 100644 index 000000000..afe36bd8f --- /dev/null +++ b/beos/scaffolding.cpp @@ -0,0 +1,2417 @@ +/* + * Copyright 2008 François Revol <mmu_man@users.sourceforge.net> + * Copyright 2006 Rob Kendrick <rjek@rjek.com> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define __STDBOOL_H__ 1 +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <BeBuild.h> +#include <Button.h> +#include <Dragger.h> +#include <Menu.h> +#include <MenuBar.h> +#include <MenuItem.h> +#include <Node.h> +#include <Path.h> +#include <PopUpMenu.h> +#include <Screen.h> +#include <ScrollView.h> +#include <String.h> +#include <StringView.h> +#include <TextControl.h> +#include <View.h> +#include <Window.h> +#include <fs_attr.h> +extern "C" { +#include "content/content.h" +#include "desktop/browser.h" +#include "desktop/history_core.h" +#include "desktop/gui.h" +#include "desktop/netsurf.h" +#include "desktop/plotters.h" +#include "desktop/options.h" +#include "desktop/selection.h" +#include "desktop/textinput.h" +#include "render/box.h" +#include "render/font.h" +#include "render/form.h" +#include "render/html.h" +#include "utils/messages.h" +#include "utils/schedule.h" +#include "utils/utils.h" +#include "utils/log.h" +} +#include "beos/gui.h" +#include "beos/plotters.h" +#include "beos/scaffolding.h" +#include "beos/gui_options.h" +//#include "beos/completion.h" +#include "beos/throbber.h" +#include "beos/window.h" +//#include "beos/schedule.h" +//#include "beos/download.h" + +#define TOOLBAR_HEIGHT 32 +#define DRAGGER_WIDTH 8 + +struct beos_history_window; + +class NSBrowserWindow; +class NSThrobber; + +struct beos_scaffolding { + NSBrowserWindow *window; // top-level container object + + // top-level view, contains toolbar & top-level browser view + NSBaseView *top_view; + + BMenuBar *menu_bar; + + BPopUpMenu *popup_menu; + + BDragger *dragger; + + BView *tool_bar; + + BControl *back_button; + BControl *forward_button; + BControl *stop_button; + BControl *reload_button; + BControl *home_button; + + BTextControl *url_bar; + //BMenuField *url_bar_completion; + + NSThrobber *throbber; + + BStringView *status_bar; + + BScrollView *scroll_view; +#warning XXX +#if 0 /* GTK */ + GtkEntryCompletion *url_bar_completion; + GtkMenuBar *menu_bar; + GtkMenuItem *back_menu; + GtkMenuItem *forward_menu; + GtkMenuItem *stop_menu; + GtkMenuItem *reload_menu; + + GladeXML *popup_xml; + GtkMenu *popup_menu; + +#endif + struct beos_history_window *history_window; + + int throb_frame; + struct gui_window *top_level; + int being_destroyed; + + bool fullscreen; +}; + +struct beos_history_window { + struct beos_scaffolding *g; + BWindow *window; + +#warning XXX +#if 0 /* GTK */ + GtkWindow *window; + GtkScrolledWindow *scrolled; + GtkDrawingArea *drawing_area; +#endif +}; + +struct menu_events { + const char *widget; +#warning XXX +#if 0 /* GTK */ + GCallback handler; +#endif +}; + +// passed to the replicant main thread +struct replicant_thread_info { + char app[B_PATH_NAME_LENGTH]; + BString url; + char *args[3]; +}; + + +static int open_windows = 0; /**< current number of open browsers */ +static struct beos_scaffolding *current_model; /**< current window for model dialogue use */ +static NSBaseView *replicant_view = NULL; /**< if not NULL, the replicant View we are running NetSurf for */ +static sem_id replicant_done_sem = -1; + +static void nsbeos_window_update_back_forward(struct beos_scaffolding *); +static void nsbeos_throb(void *); +static int32 nsbeos_replicant_main_thread(void *_arg); + +// in beos_gui.cpp +extern int main(int argc, char** argv); + +#warning XXX +#if 0 /* GTK */ +static gboolean nsbeos_window_url_activate_event(beosWidget *, gpointer); +static gboolean nsbeos_window_url_changed(beosWidget *, GdkEventKey *, gpointer); + +static gboolean nsbeos_history_expose_event(beosWidget *, GdkEventExpose *, + gpointer); +static gboolean nsbeos_history_button_press_event(beosWidget *, GdkEventButton *, + gpointer); + +static void nsbeos_attach_menu_handlers(GladeXML *, gpointer); + +gboolean nsbeos_openfile_open(beosWidget *widget, gpointer data); + +#define MENUEVENT(x) { #x, G_CALLBACK(nsbeos_on_##x##_activate) } +#define MENUPROTO(x) static gboolean nsbeos_on_##x##_activate( \ + beosMenuItem *widget, gpointer g) +/* prototypes for menu handlers */ +/* file menu */ +MENUPROTO(new_window); +MENUPROTO(open_location); +MENUPROTO(open_file); +MENUPROTO(close_window); +MENUPROTO(quit); + +/* edit menu */ +MENUPROTO(preferences); + +/* view menu */ +MENUPROTO(stop); +MENUPROTO(reload); +MENUPROTO(zoom_in); +MENUPROTO(normal_size); +MENUPROTO(zoom_out); +MENUPROTO(full_screen); +MENUPROTO(menu_bar); +MENUPROTO(tool_bar); +MENUPROTO(status_bar); +MENUPROTO(downloads); +MENUPROTO(save_window_size); +MENUPROTO(toggle_debug_rendering); +MENUPROTO(save_box_tree); + +/* navigate menu */ +MENUPROTO(back); +MENUPROTO(forward); +MENUPROTO(home); +MENUPROTO(local_history); +MENUPROTO(global_history); + +/* help menu */ +MENUPROTO(about); + +/* structure used by nsbeos_attach_menu_handlers to connect menu items to + * their handling functions. + */ +static struct menu_events menu_events[] = { + /* file menu */ + MENUEVENT(new_window), + MENUEVENT(open_location), + MENUEVENT(open_file), + MENUEVENT(close_window), + MENUEVENT(quit), + + /* edit menu */ + MENUEVENT(preferences), + + /* view menu */ + MENUEVENT(stop), + MENUEVENT(reload), + MENUEVENT(zoom_in), + MENUEVENT(normal_size), + MENUEVENT(zoom_out), + MENUEVENT(full_screen), + MENUEVENT(menu_bar), + MENUEVENT(tool_bar), + MENUEVENT(status_bar), + MENUEVENT(downloads), + MENUEVENT(save_window_size), + MENUEVENT(toggle_debug_rendering), + MENUEVENT(save_box_tree), + + /* navigate menu */ + MENUEVENT(back), + MENUEVENT(forward), + MENUEVENT(home), + MENUEVENT(local_history), + MENUEVENT(global_history), + + /* help menu */ + MENUEVENT(about), + + /* sentinel */ + { NULL, NULL } +}; + +void nsbeos_attach_menu_handlers(GladeXML *xml, gpointer g) +{ + struct menu_events *event = menu_events; + + while (event->widget != NULL) + { + beosWidget *w = glade_xml_get_widget(xml, event->widget); + g_signal_connect(G_OBJECT(w), "activate", event->handler, g); + event++; + } +} +#endif + +// #pragma mark - class NSThrobber + +class NSThrobber : public BView { +public: + NSThrobber(BRect frame); +virtual ~NSThrobber(); + +virtual void MessageReceived(BMessage *message); +virtual void Draw(BRect updateRect); +void SetBitmap(const BBitmap *bitmap); + +private: + const BBitmap *fBitmap; +}; + +NSThrobber::NSThrobber(BRect frame) + : BView(frame, "NSThrobber", B_FOLLOW_TOP | B_FOLLOW_RIGHT, B_WILL_DRAW), + fBitmap(NULL) +{ +} + + +NSThrobber::~NSThrobber() +{ +} + + +void +NSThrobber::MessageReceived(BMessage *message) +{ + BView::MessageReceived(message); +} + + +void +NSThrobber::Draw(BRect updateRect) +{ + if (!fBitmap) + return; + DrawBitmap(fBitmap); +} + + +void +NSThrobber::SetBitmap(const BBitmap *bitmap) +{ + fBitmap = bitmap; +} + + +// #pragma mark - class NSBaseView + + +NSBaseView::NSBaseView(BRect frame) + : BView(frame, "NetSurf", B_FOLLOW_ALL_SIDES, + 0 /*B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS*/ /*| B_SUBPIXEL_PRECISE*/), + fScaffolding(NULL) +{ +} + +NSBaseView::NSBaseView(BMessage *archive) + : BView(archive), + fScaffolding(NULL) +{ +} + + +NSBaseView::~NSBaseView() +{ + //warn_user ("~NSBaseView()", NULL); + BMessage *message = new BMessage(B_QUIT_REQUESTED); + nsbeos_pipe_message_top(message, NULL, fScaffolding); + while (acquire_sem(replicant_done_sem) == EINTR); +} + + +void +NSBaseView::MessageReceived(BMessage *message) +{ + switch (message->what) { + case B_SIMPLE_DATA: + case B_ARGV_RECEIVED: + case B_REFS_RECEIVED: + case B_COPY: + case B_CUT: + case B_PASTE: + case B_SELECT_ALL: + //case B_MOUSE_WHEEL_CHANGED: + case B_UI_SETTINGS_CHANGED: + // NetPositive messages + case B_NETPOSITIVE_OPEN_URL: + case B_NETPOSITIVE_BACK: + case B_NETPOSITIVE_FORWARD: + case B_NETPOSITIVE_HOME: + case B_NETPOSITIVE_RELOAD: + case B_NETPOSITIVE_STOP: + case B_NETPOSITIVE_DOWN: + case B_NETPOSITIVE_UP: + // messages for top-level + case 'back': + case 'forw': + case 'stop': + case 'relo': + case 'home': + case 'urlc': + case 'urle': + case 'menu': + case NO_ACTION: + case HELP_OPEN_CONTENTS: + case HELP_OPEN_GUIDE: + case HELP_OPEN_INFORMATION: + case HELP_OPEN_ABOUT: + case HELP_LAUNCH_INTERACTIVE: + case HISTORY_SHOW_LOCAL: + case HISTORY_SHOW_GLOBAL: + case HOTLIST_ADD_URL: + case HOTLIST_SHOW: + case COOKIES_SHOW: + case COOKIES_DELETE: + case BROWSER_PAGE: + case BROWSER_PAGE_INFO: + case BROWSER_PRINT: + case BROWSER_NEW_WINDOW: + case BROWSER_VIEW_SOURCE: + case BROWSER_OBJECT: + case BROWSER_OBJECT_INFO: + case BROWSER_OBJECT_RELOAD: + case BROWSER_OBJECT_SAVE: + case BROWSER_OBJECT_EXPORT_SPRITE: + case BROWSER_OBJECT_SAVE_URL_URI: + case BROWSER_OBJECT_SAVE_URL_URL: + case BROWSER_OBJECT_SAVE_URL_TEXT: + case BROWSER_SAVE: + case BROWSER_SAVE_COMPLETE: + case BROWSER_EXPORT_DRAW: + case BROWSER_EXPORT_TEXT: + case BROWSER_SAVE_URL_URI: + case BROWSER_SAVE_URL_URL: + case BROWSER_SAVE_URL_TEXT: + case HOTLIST_EXPORT: + case HISTORY_EXPORT: + case BROWSER_NAVIGATE_HOME: + case BROWSER_NAVIGATE_BACK: + case BROWSER_NAVIGATE_FORWARD: + case BROWSER_NAVIGATE_UP: + case BROWSER_NAVIGATE_RELOAD: + case BROWSER_NAVIGATE_RELOAD_ALL: + case BROWSER_NAVIGATE_STOP: + case BROWSER_NAVIGATE_URL: + case BROWSER_SCALE_VIEW: + case BROWSER_FIND_TEXT: + case BROWSER_IMAGES_FOREGROUND: + case BROWSER_IMAGES_BACKGROUND: + case BROWSER_BUFFER_ANIMS: + case BROWSER_BUFFER_ALL: + case BROWSER_SAVE_VIEW: + case BROWSER_WINDOW_DEFAULT: + case BROWSER_WINDOW_STAGGER: + case BROWSER_WINDOW_COPY: + case BROWSER_WINDOW_RESET: + case TREE_NEW_FOLDER: + case TREE_NEW_LINK: + case TREE_EXPAND_ALL: + case TREE_EXPAND_FOLDERS: + case TREE_EXPAND_LINKS: + case TREE_COLLAPSE_ALL: + case TREE_COLLAPSE_FOLDERS: + case TREE_COLLAPSE_LINKS: + case TREE_SELECTION: + case TREE_SELECTION_EDIT: + case TREE_SELECTION_LAUNCH: + case TREE_SELECTION_DELETE: + case TREE_SELECT_ALL: + case TREE_CLEAR_SELECTION: + case TOOLBAR_BUTTONS: + case TOOLBAR_ADDRESS_BAR: + case TOOLBAR_THROBBER: + case TOOLBAR_EDIT: + case CHOICES_SHOW: + case APPLICATION_QUIT: + if (Window()) + Window()->DetachCurrentMessage(); + nsbeos_pipe_message_top(message, NULL, fScaffolding); + break; + default: + message->PrintToStream(); + BView::MessageReceived(message); + } +} + + +status_t +NSBaseView::Archive(BMessage *archive, bool deep) const +{ + // force archiving only the base view + deep = false; + status_t err; + err = BView::Archive(archive, deep); + if (err < B_OK) + return err; + // add our own fields + // we try to reuse the same fields as NetPositive + archive->AddString("add_on", "application/x-vnd.NetSurf"); + //archive->AddInt32("version", 2); + archive->AddString("url", fScaffolding->url_bar->Text()); + archive->AddBool("openAsText", false); + archive->AddInt32("encoding", 258); + return err; +} + + +BArchivable * +NSBaseView::Instantiate(BMessage *archive) +{ + if (!validate_instantiation(archive, "NSBaseView")) + return NULL; + const char *url; + if (archive->FindString("url", &url) < B_OK) { + return NULL; + } + + struct replicant_thread_info *info = new replicant_thread_info; + info->url = url; + if (nsbeos_find_app_path(info->app) < B_OK) + return NULL; + info->args[0] = info->app; + info->args[1] = (char *)info->url.String(); + info->args[2] = NULL; + NSBaseView *view = new NSBaseView(archive); + replicant_view = view; + replicated = true; + + //TODO:FIXME: fix replicants + // netsurf_init() needs different args now... + //netsurf_init(2, info->args); + //return NULL; + + replicant_done_sem = create_sem(0, "NS Replicant created"); + thread_id nsMainThread = spawn_thread(nsbeos_replicant_main_thread, + "NetSurf Main Thread", B_NORMAL_PRIORITY, info); + if (nsMainThread < B_OK) { + delete_sem(replicant_done_sem); + delete info; + delete view; + return NULL; + } + resume_thread(nsMainThread); + while (acquire_sem(replicant_done_sem) == EINTR); + + return view; +} + + +void +NSBaseView::SetScaffolding(struct beos_scaffolding *scaf) +{ + fScaffolding = scaf; +} + + +// AttachedToWindow() is not enough to get the dragger and status bar +// stick to the panel color +void +NSBaseView::AllAttached() +{ + BView::AllAttached(); + struct beos_scaffolding *g = fScaffolding; + if (!g) + return; + // set targets to the topmost ns view + g->back_button->SetTarget(this); + g->forward_button->SetTarget(this); + g->stop_button->SetTarget(this); + g->reload_button->SetTarget(this); + g->home_button->SetTarget(this); + + g->url_bar->SetTarget(this); + + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + g->tool_bar->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + g->dragger->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + g->status_bar->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + g->status_bar->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)) ; +#if defined(__HAIKU__) || defined(B_DANO_VERSION) + g->status_bar->SetHighColor(ui_color(B_PANEL_TEXT_COLOR)); +#endif +} + + +// #pragma mark - class NSBrowserWindow + + +NSBrowserWindow::NSBrowserWindow(BRect frame, struct beos_scaffolding *scaf) + : BWindow(frame, "NetSurf", B_DOCUMENT_WINDOW, 0), + fScaffolding(scaf) +{ +} + + +NSBrowserWindow::~NSBrowserWindow() +{ +} + + +void +NSBrowserWindow::DispatchMessage(BMessage *message, BHandler *handler) +{ + BMessage *msg; + switch (message->what) { + case B_UI_SETTINGS_CHANGED: + msg = new BMessage(*message); + nsbeos_pipe_message_top(msg, this, fScaffolding); + break; + } + BWindow::DispatchMessage(message, handler); +} + + +void +NSBrowserWindow::MessageReceived(BMessage *message) +{ + switch (message->what) { + case B_ARGV_RECEIVED: + case B_REFS_RECEIVED: + case B_UI_SETTINGS_CHANGED: + DetachCurrentMessage(); + nsbeos_pipe_message_top(message, this, fScaffolding); + break; + default: + BWindow::MessageReceived(message); + } +} + +bool +NSBrowserWindow::QuitRequested(void) +{ + BWindow::QuitRequested(); + BMessage *message = DetachCurrentMessage(); + // BApplication::Quit() calls us directly... + if (message == NULL) + message = new BMessage(B_QUIT_REQUESTED); + nsbeos_pipe_message_top(message, this, fScaffolding); + return false; // we will Quit() ourselves from the main thread +} + + +// #pragma mark - implementation + +int32 nsbeos_replicant_main_thread(void *_arg) +{ + struct replicant_thread_info *info = (struct replicant_thread_info *)_arg; + int32 ret; + ret = main(2, info->args); + //netsurf_main_loop(); + //netsurf_exit(); + delete info; + //release + delete_sem(replicant_done_sem); + return ret; +} + + +/* event handlers and support functions for them */ + +static void nsbeos_window_destroy_event(NSBrowserWindow *window, nsbeos_scaffolding *g, BMessage *event) +{ + LOG(("Being Destroyed = %d", g->being_destroyed)); + + if (--open_windows == 0) + netsurf_quit = true; + + if (window) { + window->Lock(); + window->Quit(); + } + + if (!g->being_destroyed) { + g->being_destroyed = 1; + nsbeos_window_destroy_browser(g->top_level); + } +} + + +void nsbeos_scaffolding_update_colors(nsbeos_scaffolding *g) +{ + if (!g->top_view->LockLooper()) + return; + rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR); + g->top_view->SetViewColor(c); + + g->tool_bar->SetViewColor(c); + g->back_button->SetViewColor(c); + g->forward_button->SetViewColor(c); + g->stop_button->SetViewColor(c); + g->reload_button->SetViewColor(c); + g->home_button->SetViewColor(c); + g->url_bar->SetViewColor(c); + g->throbber->SetViewColor(c); + g->scroll_view->SetViewColor(c); + + g->dragger->SetViewColor(c); + + g->status_bar->SetViewColor(c); + g->status_bar->SetLowColor(c); +#if defined(__HAIKU__) || defined(B_DANO_VERSION) + g->status_bar->SetHighColor(ui_color(B_PANEL_TEXT_COLOR)); +#endif + g->top_view->UnlockLooper(); +} + + +void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *message) +{ + int width, height; + struct browser_window *bw; + bw = nsbeos_get_browser_for_gui(scaffold->top_level); + bool reloadAll = false; + + LOG(("nsbeos_scaffolding_dispatch_event() what = 0x%08lx", message->what)); + switch (message->what) { + case B_QUIT_REQUESTED: + nsbeos_scaffolding_destroy(scaffold); + break; + case B_NETPOSITIVE_DOWN: + //XXX WRITEME + break; + case B_SIMPLE_DATA: + { + if (!message->HasRef("refs")) { + // XXX handle DnD + break; + } + // FALL THROUGH + // handle refs + } + case B_REFS_RECEIVED: + { + int32 i; + entry_ref ref; + + for (i = 0; message->FindRef("refs", i, &ref) >= B_OK; i++) { + BString url("file://"); + BPath path(&ref); + if (path.InitCheck() < B_OK) + break; + + BNode node(path.Path()); + if (node.InitCheck() < B_OK) + break; + if (node.IsSymLink()) { + // dereference the symlink + BEntry entry(path.Path(), true); + if (entry.InitCheck() < B_OK) + break; + if (entry.GetPath(&path) < B_OK) + break; + if (node.SetTo(path.Path()) < B_OK) + break; + } + + attr_info ai; + if (node.GetAttrInfo("META:url", &ai) >= B_OK) { + char data[(size_t)ai.size + 1]; + memset(data, 0, (size_t)ai.size + 1); + if (node.ReadAttr("META:url", B_STRING_TYPE, 0LL, data, (size_t)ai.size) < 4) + break; + url = data; + } else + url << path.Path(); + + if (/*message->WasDropped() &&*/ i == 0) + browser_window_go(bw, url.String(), 0, true); + else + browser_window_create(url.String(), bw, NULL, false, false); + } + break; + } + case B_ARGV_RECEIVED: + { + int32 i; + BString url; + for (i = 1; message->FindString("argv", i, &url) >= B_OK; i++) { + browser_window_create(url.String(), bw, NULL, false, false); + } + break; + } + case B_UI_SETTINGS_CHANGED: + nsbeos_update_system_ui_colors(); + nsbeos_scaffolding_update_colors(scaffold); + break; + case B_NETPOSITIVE_OPEN_URL: + { + int32 i; + BString url; + if (message->FindString("be:url", &url) < B_OK) + break; + browser_window_go(bw, url.String(), 0, true); + break; + } + case B_COPY: + gui_copy_to_clipboard(browser_window_get_selection(bw)); + break; + case B_CUT: + browser_window_key_press(bw, 24); + break; + case B_PASTE: + gui_paste_from_clipboard(scaffold->top_level, 0, 0); + break; + case B_SELECT_ALL: + LOG(("Selecting all text")); + selection_select_all(browser_window_get_selection(bw)); + break; + case B_NETPOSITIVE_BACK: + case BROWSER_NAVIGATE_BACK: + case 'back': + if (!history_back_available(bw->history)) + break; + history_back(bw, bw->history); + nsbeos_window_update_back_forward(scaffold); + break; + case B_NETPOSITIVE_FORWARD: + case BROWSER_NAVIGATE_FORWARD: + case 'forw': + if (!history_forward_available(bw->history)) + break; + history_forward(bw, bw->history); + nsbeos_window_update_back_forward(scaffold); + break; + case B_NETPOSITIVE_STOP: + case BROWSER_NAVIGATE_STOP: + case 'stop': + browser_window_stop(bw); + break; + case B_NETPOSITIVE_RELOAD: + case BROWSER_NAVIGATE_RELOAD_ALL: + case 'relo': + reloadAll = true; + // FALLTHRU + case BROWSER_NAVIGATE_RELOAD: + browser_window_reload(bw, reloadAll); + break; + case B_NETPOSITIVE_HOME: + case BROWSER_NAVIGATE_HOME: + case 'home': + { + static const char *addr = NETSURF_HOMEPAGE; + + if (nsoption_charp(homepage_url) != NULL) + addr = nsoption_charp(homepage_url); + + browser_window_go(bw, addr, 0, true); + break; + } + case 'urle': + { + BString text; + if (!scaffold->url_bar->LockLooper()) + break; + text = scaffold->url_bar->Text(); + scaffold->scroll_view->Target()->MakeFocus(); + scaffold->url_bar->UnlockLooper(); + browser_window_go(bw, text.String(), 0, true); + break; + } + case 'urlc': + { + BString text; + if (!scaffold->url_bar->LockLooper()) + break; + text = scaffold->url_bar->Text(); + scaffold->url_bar->UnlockLooper(); + //nsbeos_completion_update(text.String()); + break; + } +/* + case 'menu': + { + menu_action action; + if (message->FindInt32("action", (int32 *)&action) < B_OK) + break; + switch (action) { + case NO_ACTION: + case HELP_OPEN_CONTENTS: + case HELP_OPEN_GUIDE: + case HELP_OPEN_INFORMATION: + case HELP_OPEN_ABOUT: + case HELP_LAUNCH_INTERACTIVE: + + break; + } +#warning XXX + break; + } +*/ + case NO_ACTION: + break; + case HELP_OPEN_CONTENTS: + break; + case HELP_OPEN_GUIDE: + break; + case HELP_OPEN_INFORMATION: + break; + case HELP_OPEN_ABOUT: + break; + case HELP_LAUNCH_INTERACTIVE: + break; + case HISTORY_SHOW_LOCAL: + break; + case HISTORY_SHOW_GLOBAL: + break; + case HOTLIST_ADD_URL: + break; + case HOTLIST_SHOW: + break; + case COOKIES_SHOW: + break; + case COOKIES_DELETE: + break; + case BROWSER_PAGE: + break; + case BROWSER_PAGE_INFO: + break; + case BROWSER_PRINT: + break; + case BROWSER_NEW_WINDOW: + { + BString text; + if (!scaffold->url_bar->LockLooper()) + break; + text = scaffold->url_bar->Text(); + scaffold->url_bar->UnlockLooper(); + + browser_window_create(text.String(), bw, NULL, false, false); + break; + } + case BROWSER_VIEW_SOURCE: + { + if (!bw || !bw->current_content) + break; + nsbeos_gui_view_source(bw->current_content, + browser_window_get_selection(bw)); + break; + } + case BROWSER_OBJECT: + break; + case BROWSER_OBJECT_INFO: + break; + case BROWSER_OBJECT_RELOAD: + break; + case BROWSER_OBJECT_SAVE: + break; + case BROWSER_OBJECT_EXPORT_SPRITE: + break; + case BROWSER_OBJECT_SAVE_URL_URI: + break; + case BROWSER_OBJECT_SAVE_URL_URL: + break; + case BROWSER_OBJECT_SAVE_URL_TEXT: + break; + case BROWSER_SAVE: + break; + case BROWSER_SAVE_COMPLETE: + break; + case BROWSER_EXPORT_DRAW: + break; + case BROWSER_EXPORT_TEXT: + break; + case BROWSER_SAVE_URL_URI: + break; + case BROWSER_SAVE_URL_URL: + break; + case BROWSER_SAVE_URL_TEXT: + break; + case HOTLIST_EXPORT: + break; + case HISTORY_EXPORT: + break; + case B_NETPOSITIVE_UP: + case BROWSER_NAVIGATE_UP: + break; + case BROWSER_NAVIGATE_URL: + if (!scaffold->url_bar->LockLooper()) + break; + scaffold->url_bar->MakeFocus(); + scaffold->url_bar->UnlockLooper(); + break; + case BROWSER_SCALE_VIEW: + break; + case BROWSER_FIND_TEXT: + break; + case BROWSER_IMAGES_FOREGROUND: + break; + case BROWSER_IMAGES_BACKGROUND: + break; + case BROWSER_BUFFER_ANIMS: + break; + case BROWSER_BUFFER_ALL: + break; + case BROWSER_SAVE_VIEW: + break; + case BROWSER_WINDOW_DEFAULT: + break; + case BROWSER_WINDOW_STAGGER: + break; + case BROWSER_WINDOW_COPY: + break; + case BROWSER_WINDOW_RESET: + break; + case TREE_NEW_FOLDER: + case TREE_NEW_LINK: + case TREE_EXPAND_ALL: + case TREE_EXPAND_FOLDERS: + case TREE_EXPAND_LINKS: + case TREE_COLLAPSE_ALL: + case TREE_COLLAPSE_FOLDERS: + case TREE_COLLAPSE_LINKS: + case TREE_SELECTION: + case TREE_SELECTION_EDIT: + case TREE_SELECTION_LAUNCH: + case TREE_SELECTION_DELETE: + case TREE_SELECT_ALL: + case TREE_CLEAR_SELECTION: + break; + case TOOLBAR_BUTTONS: + break; + case TOOLBAR_ADDRESS_BAR: + break; + case TOOLBAR_THROBBER: + break; + case TOOLBAR_EDIT: + break; + case CHOICES_SHOW: + break; + case APPLICATION_QUIT: + netsurf_quit = true; + break; + default: + break; + } +} + +void nsbeos_scaffolding_destroy(nsbeos_scaffolding *scaffold) +{ + LOG(("Being Destroyed = %d", scaffold->being_destroyed)); + if (scaffold->being_destroyed) return; + scaffold->being_destroyed = 1; + nsbeos_window_destroy_event(scaffold->window, scaffold, NULL); +} + + +void nsbeos_window_update_back_forward(struct beos_scaffolding *g) +{ + int width, height; + struct browser_window *bw = nsbeos_get_browser_for_gui(g->top_level); + + if (!g->top_view->LockLooper()) + return; + + g->back_button->SetEnabled(history_back_available(bw->history)); + g->forward_button->SetEnabled(history_forward_available(bw->history)); + + g->top_view->UnlockLooper(); + +#warning XXX +#if 0 /* GTK */ + beos_widget_set_sensitive(beos_WIDGET(g->back_button), + history_back_available(bw->history)); + beos_widget_set_sensitive(beos_WIDGET(g->forward_button), + history_forward_available(bw->history)); + + beos_widget_set_sensitive(beos_WIDGET(g->back_menu), + history_back_available(bw->history)); + beos_widget_set_sensitive(beos_WIDGET(g->forward_menu), + history_forward_available(bw->history)); + + /* update the local history window, as well as queuing a redraw + * for it. + */ + history_size(bw->history, &width, &height); + beos_widget_set_size_request(beos_WIDGET(g->history_window->drawing_area), + width, height); + beos_widget_queue_draw(beos_WIDGET(g->history_window->drawing_area)); +#endif +} + +void nsbeos_throb(void *p) +{ + struct beos_scaffolding *g = (struct beos_scaffolding *)p; + + if (g->throb_frame >= (nsbeos_throbber->nframes - 1)) + g->throb_frame = 1; + else + g->throb_frame++; + + if (!g->top_view->LockLooper()) + return; + +#if 0 + g->throbber->SetViewBitmap(nsbeos_throbber->framedata[g->throb_frame], + B_FOLLOW_RIGHT | B_FOLLOW_TOP); +#endif + g->throbber->SetBitmap(nsbeos_throbber->framedata[g->throb_frame]); + g->throbber->Invalidate(); + + g->top_view->UnlockLooper(); + + schedule(10, nsbeos_throb, p); + +} + +#warning XXX +#if 0 /* GTK */ + +gboolean nsbeos_openfile_open(beosWidget *widget, gpointer data) +{ + struct browser_window *bw = nsbeos_get_browser_for_gui( + current_model->top_level); + char *filename = beos_file_chooser_get_filename( + beos_FILE_CHOOSER(wndOpenFile)); + char *url = malloc(strlen(filename) + sizeof("file://")); + + sprintf(url, "file://%s", filename); + + browser_window_go(bw, url, 0, true); + + g_free(filename); + free(url); + + return TRUE; +} +#endif + +#warning XXX +#if 0 /* GTK */ +/* signal handlers for menu entries */ +#define MENUHANDLER(x) gboolean nsbeos_on_##x##_activate(beosMenuItem *widget, \ + gpointer g) + +MENUHANDLER(new_window) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + struct browser_window *bw = nsbeos_get_browser_for_gui(gw->top_level); + const char *url = beos_entry_get_text(beos_ENTRY(gw->url_bar)); + + browser_window_create(url, bw, NULL, false); + + return TRUE; +} + +MENUHANDLER(open_location) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + + beos_widget_grab_focus(beos_WIDGET(gw->url_bar)); + + return TRUE; +} + +MENUHANDLER(open_file) +{ + current_model = (struct beos_scaffolding *)g; + beos_dialog_run(wndOpenFile); + + return TRUE; +} + +MENUHANDLER(close_window) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + + beos_widget_destroy(beos_WIDGET(gw->window)); + + return TRUE; +} + +MENUHANDLER(quit) +{ + netsurf_quit = true; + return TRUE; +} + +MENUHANDLER(preferences) +{ + beos_widget_show(beos_WIDGET(wndPreferences)); + + return TRUE; +} + +MENUHANDLER(zoom_in) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + struct browser_window *bw = nsbeos_get_browser_for_gui(gw->top_level); + float old_scale = nsbeos_get_scale_for_gui(gw->top_level); + + browser_window_set_scale(bw, old_scale + 0.05, true); + + return TRUE; +} + +MENUHANDLER(normal_size) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + struct browser_window *bw = nsbeos_get_browser_for_gui(gw->top_level); + + browser_window_set_scale(bw, 1.0, true); + + return TRUE; +} + +MENUHANDLER(zoom_out) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + struct browser_window *bw = nsbeos_get_browser_for_gui(gw->top_level); + float old_scale = nsbeos_get_scale_for_gui(gw->top_level); + + browser_window_set_scale(bw, old_scale - 0.05, true); + + return TRUE; +} + +MENUHANDLER(full_screen) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + + if (gw->fullscreen) { + beos_window_unfullscreen(gw->window); + } else { + beos_window_fullscreen(gw->window); + } + + gw->fullscreen = !gw->fullscreen; + + return TRUE; +} + +MENUHANDLER(menu_bar) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + + if (beos_check_menu_item_get_active(beos_CHECK_MENU_ITEM(widget))) { + beos_widget_show(beos_WIDGET(gw->menu_bar)); + } else { + beos_widget_hide(beos_WIDGET(gw->menu_bar)); + } + + return TRUE; +} + +MENUHANDLER(tool_bar) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + + if (beos_check_menu_item_get_active(beos_CHECK_MENU_ITEM(widget))) { + beos_widget_show(beos_WIDGET(gw->tool_bar)); + } else { + beos_widget_hide(beos_WIDGET(gw->tool_bar)); + } + + return TRUE; +} + +MENUHANDLER(status_bar) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + + if (beos_check_menu_item_get_active(beos_CHECK_MENU_ITEM(widget))) { + beos_widget_show(beos_WIDGET(gw->status_bar)); + } else { + beos_widget_hide(beos_WIDGET(gw->status_bar)); + } + + return TRUE; +} + +MENUHANDLER(downloads) +{ + nsbeos_download_show(); + + return TRUE; +} + +MENUHANDLER(save_window_size) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + int x,y,w,h; + + nsoption_set_int(toolbar_status_width, + beos_paned_get_position(gw->status_pane)); + beos_window_get_position(gw->window, &x, &y); + beos_window_get_size(gw->window, &w, &h); + + nsoption_set_int(window_x, x); + nsoption_set_int(window_y, y); + nsoption_set_int(window_width, w); + nsoption_set_int(window_height, h); + + nsoption_write(options_file_location); + + return TRUE; +} + +MENUHANDLER(toggle_debug_rendering) +{ + html_redraw_debug = !html_redraw_debug; + nsbeos_reflow_all_windows(); + return TRUE; +} + +MENUHANDLER(save_box_tree) +{ + beosWidget *save_dialog; + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + + save_dialog = beos_file_chooser_dialog_new("Save File", gw->window, + beos_FILE_CHOOSER_ACTION_SAVE, + beos_STOCK_CANCEL, beos_RESPONSE_CANCEL, + beos_STOCK_SAVE, beos_RESPONSE_ACCEPT, + NULL); + + beos_file_chooser_set_current_folder(beos_FILE_CHOOSER(save_dialog), + getenv("HOME") ? getenv("HOME") : "/"); + + beos_file_chooser_set_current_name(beos_FILE_CHOOSER(save_dialog), + "boxtree.txt"); + + if (beos_dialog_run(beos_DIALOG(save_dialog)) == beos_RESPONSE_ACCEPT) { + char *filename = beos_file_chooser_get_filename( + beos_FILE_CHOOSER(save_dialog)); + FILE *fh; + LOG(("Saving box tree dump to %s...\n", filename)); + + fh = fopen(filename, "w"); + if (fh == NULL) { + warn_user("Error saving box tree dump.", + "Unable to open file for writing."); + } else { + struct browser_window *bw; + bw = nsbeos_get_browser_window(gw->top_level); + + if (bw->current_content && + bw->current_content->type == + CONTENT_HTML) { + box_dump(fh, + bw->current_content->data.html.layout, + 0); + } + + fclose(fh); + } + + g_free(filename); + } + + beos_widget_destroy(save_dialog); +} + +MENUHANDLER(stop) +{ + return nsbeos_window_stop_button_clicked(beos_WIDGET(widget), g); +} + +MENUHANDLER(reload) +{ + return nsbeos_window_reload_button_clicked(beos_WIDGET(widget), g); +} + +MENUHANDLER(back) +{ + return nsbeos_window_back_button_clicked(beos_WIDGET(widget), g); +} + +MENUHANDLER(forward) +{ + return nsbeos_window_forward_button_clicked(beos_WIDGET(widget), g); +} + +MENUHANDLER(home) +{ + return nsbeos_window_home_button_clicked(beos_WIDGET(widget), g); +} + +MENUHANDLER(local_history) +{ + struct beos_scaffolding *gw = (struct beos_scaffolding *)g; + + beos_widget_show(beos_WIDGET(gw->history_window->window)); + gdk_window_raise(beos_WIDGET(gw->history_window->window)->window); + + return TRUE; +} + +MENUHANDLER(global_history) +{ + beos_widget_show(beos_WIDGET(wndHistory)); + gdk_window_raise(beos_WIDGET(wndHistory)->window); + + return TRUE; +} + +MENUHANDLER(about) +{ + beos_widget_show(beos_WIDGET(wndAbout)); + gdk_window_raise(beos_WIDGET(wndAbout)->window); + return TRUE; +} + +/* signal handler functions for the local history window */ +gboolean nsbeos_history_expose_event(beosWidget *widget, + GdkEventExpose *event, gpointer g) +{ + struct beos_history_window *hw = (struct beos_history_window *)g; + struct browser_window *bw = nsbeos_get_browser_for_gui(hw->g->top_level); + + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &nsbeos_plotters + }; + + current_widget = widget; + current_drawable = widget->window; + current_gc = gdk_gc_new(current_drawable); +#ifdef CAIRO_VERSION + current_cr = gdk_cairo_create(current_drawable); +#endif + plot = nsbeos_plotters; + + history_redraw(bw->history, &ctx); + + g_object_unref(current_gc); +#ifdef CAIRO_VERSION + cairo_destroy(current_cr); +#endif + return FALSE; +} + +gboolean nsbeos_history_button_press_event(beosWidget *widget, + GdkEventButton *event, gpointer g) +{ + struct beos_history_window *hw = (struct beos_history_window *)g; + struct browser_window *bw = nsbeos_get_browser_for_gui(hw->g->top_level); + + LOG(("X=%g, Y=%g", event->x, event->y)); + + history_click(bw, bw->history, + event->x, event->y, false); + + return TRUE; +} + +#define GET_WIDGET(x) glade_xml_get_widget(g->xml, (x)) + +static gboolean do_scroll_event(beosWidget *widget, GdkEvent *ev, + gpointer data) +{ + switch (((GdkEventScroll *)ev)->direction) + { + case GDK_SCROLL_UP: + case GDK_SCROLL_DOWN: + beos_widget_event(g_object_get_data( + G_OBJECT(widget), "vScroll"), ev); + break; + default: + beos_widget_event(g_object_get_data( + G_OBJECT(widget), "hScroll"), ev); + } + + return TRUE; +} +#endif + +NSBrowserWindow *nsbeos_find_last_window(void) +{ + int32 i; + if (!be_app || !be_app->Lock()) + return NULL; + for (i = be_app->CountWindows() - 1; i >= 0; i--) { + if (be_app->WindowAt(i) == NULL) + continue; + NSBrowserWindow *win; + win = dynamic_cast<NSBrowserWindow *>(be_app->WindowAt(i)); + if (win) { + win->Lock(); + be_app->Unlock(); + return win; + } + } + be_app->Unlock(); + return NULL; +} + +NSBrowserWindow *nsbeos_get_bwindow_for_scaffolding(nsbeos_scaffolding *scaffold) +{ + return scaffold->window; +} + +static void recursively_set_menu_items_target(BMenu *menu, BHandler *handler) +{ + menu->SetTargetForItems(handler); + for (int i = 0; menu->ItemAt(i); i++) { + if (!menu->SubmenuAt(i)) + continue; + recursively_set_menu_items_target(menu->SubmenuAt(i), handler); + } +} + +void nsbeos_attach_toplevel_view(nsbeos_scaffolding *g, BView *view) +{ + LOG(("Attaching view to scaffolding %p", g)); + + // this is a replicant,... and it went bad + if (!g->window) { + if (g->top_view->Looper() && !g->top_view->LockLooper()) + return; + } + + BRect rect(g->top_view->Bounds()); + rect.top += TOOLBAR_HEIGHT; + rect.right -= B_V_SCROLL_BAR_WIDTH; + rect.bottom -= B_H_SCROLL_BAR_HEIGHT; + + view->ResizeTo(rect.Width() /*+ 1*/, rect.Height() /*+ 1*/); + view->MoveTo(rect.LeftTop()); + + + g->scroll_view = new BScrollView("NetSurfScrollView", view, + B_FOLLOW_ALL, 0, true, true, B_NO_BORDER); + + g->top_view->AddChild(g->scroll_view); + + view->MakeFocus(); + + // resize the horiz scrollbar to make room for the status bar and add it. + + BScrollBar *sb = g->scroll_view->ScrollBar(B_HORIZONTAL); + rect = sb->Frame(); + float divider = rect.Width() + 1; + //divider /= 2; + divider *= 67.0/100; // 67% + + sb->ResizeBy(-divider, 0); + sb->MoveBy(divider, 0); + + rect.right = rect.left + divider - 1; + + /* + BBox *statusBarBox = new BBox(rect, "StatusBarBox", + B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM, + B_WILL_DRAW | B_FRAME_EVENTS, + B_RAISED_BORDER); + */ + + g->status_bar->MoveTo(rect.LeftTop()); + g->status_bar->ResizeTo(rect.Width() + 1, rect.Height() + 1); + g->scroll_view->AddChild(g->status_bar); + g->status_bar->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + g->status_bar->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)) ; +#if defined(__HAIKU__) || defined(B_DANO_VERSION) + g->status_bar->SetHighColor(ui_color(B_PANEL_TEXT_COLOR)); +#endif + + + + // set targets to the topmost ns view, + // we might not have a window later (replicant ?) + // this won't work for replicants, since the base view isn't attached yet + // we'll redo this in NSBaseView::AllAttached + g->back_button->SetTarget(view); + g->forward_button->SetTarget(view); + g->stop_button->SetTarget(view); + g->reload_button->SetTarget(view); + g->home_button->SetTarget(view); + + g->url_bar->SetTarget(view); + + if (g->window) { + recursively_set_menu_items_target(g->menu_bar, view); + + // add toolbar shortcuts + BMessage *message; + + message = new BMessage('back'); + message->AddPointer("scaffolding", g); + g->window->AddShortcut(B_LEFT_ARROW, 0, message, view); + + message = new BMessage('forw'); + message->AddPointer("scaffolding", g); + g->window->AddShortcut(B_RIGHT_ARROW, 0, message, view); + + message = new BMessage('stop'); + message->AddPointer("scaffolding", g); + g->window->AddShortcut('S', 0, message, view); + + message = new BMessage('relo'); + message->AddPointer("scaffolding", g); + g->window->AddShortcut('R', 0, message, view); + + message = new BMessage('home'); + message->AddPointer("scaffolding", g); + g->window->AddShortcut('H', 0, message, view); + + g->window->Show(); + } else { + if (g->top_view->Looper()) + g->top_view->UnlockLooper(); + } + + +#warning XXX +#if 0 /* GTK */ + beosWidget *scrollbar; + + /* Insert the viewport into the right part of our table */ + beosTable *table = beos_TABLE(GET_WIDGET("centreTable")); + LOG(("Attaching viewport to scaffolding %p", g)); + beos_table_attach_defaults(table, beos_WIDGET(vp), 0, 1, 0, 1); + + /* connect our scrollbars to the viewport */ + scrollbar = GET_WIDGET("coreScrollHorizontal"); + beos_viewport_set_hadjustment(vp, + beos_range_get_adjustment(beos_RANGE(scrollbar))); + g_object_set_data(G_OBJECT(vp), "hScroll", scrollbar); + scrollbar = GET_WIDGET("coreScrollVertical"); + beos_viewport_set_vadjustment(vp, + beos_range_get_adjustment(beos_RANGE(scrollbar))); + g_object_set_data(G_OBJECT(vp), "vScroll", scrollbar); + g_signal_connect(G_OBJECT(vp), "scroll_event", + G_CALLBACK(do_scroll_event), NULL); + + gdk_window_set_accept_focus (beos_WIDGET(vp)->window, TRUE); + + /* And set the size-request to zero to cause it to get its act together */ + beos_widget_set_size_request(beos_WIDGET(vp), 0, 0); + +#endif +} + +static BMenuItem *make_menu_item(const char *name, BMessage *message) +{ + BMenuItem *item; + BString label(messages_get(name)); + BString accel; + uint32 mods = 0; + char key = 0; + // try to understand accelerators + int32 start = label.IFindLast(" "); + if (start > 0 && (label.Length() - start > 1) + && (label.Length() - start < 7) + && (label[start + 1] == 'F' + || !strcmp(label.String() + start + 1, "PRINT") + || label[start + 1] == '\xe2' + || label[start + 1] == '^')) { + + label.MoveInto(accel, start + 1, label.Length()); + // strip the trailing spaces + while (label[label.Length() - 1] == ' ') + label.Truncate(label.Length() - 1); + + if (accel.FindFirst("\xe2\x87\x91") > -1) { + accel.RemoveFirst("\xe2\x87\x91"); + mods |= B_SHIFT_KEY; + } + if (accel.FindFirst("^") > -1) { + accel.RemoveFirst("^"); + mods |= B_CONTROL_KEY; // ALT!!! + } + if (accel.FindFirst("PRINT") > -1) { + accel.RemoveFirst("PRINT"); + //mods |= ; // ALT!!! + key = B_PRINT_KEY; + } + if (accel.Length() > 1 && accel[0] == 'F') { // Function key + int num; + if (sscanf(accel.String(), "F%d", &num) > 0) { + // + } + } else if (accel.Length() > 0) { + key = accel[0]; + } + //printf("MENU: detected accel '%s' mods 0x%08lx, key %d\n", accel.String(), mods, key); + } + + // turn ... into ellipsis + label.ReplaceAll("...", B_UTF8_ELLIPSIS); + + item = new BMenuItem(label.String(), message, key, mods); + + return item; +} + +nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) +{ + struct beos_scaffolding *g = (struct beos_scaffolding *)malloc(sizeof(*g)); + + LOG(("Constructing a scaffold of %p for gui_window %p", g, toplevel)); + + g->top_level = toplevel; + g->being_destroyed = 0; + g->fullscreen = false; + + open_windows++; + + BMessage *message; + BRect rect; + + g->window = NULL; + g->menu_bar = NULL; + g->window = NULL; + + if (replicated && !replicant_view) { + warn_user("Error: No subwindow allowed when replicated.", NULL); + return NULL; + } + + + if (!replicant_view) { + + BRect frame(0, 0, 600-1, 500-1); + if (nsoption_int(window_width) > 0) { + frame.Set(0, 0, nsoption_int(window_width) - 1, nsoption_int(window_height) - 1); + frame.OffsetToSelf(nsoption_int(window_x), nsoption_int(window_y)); + } else { + BPoint pos(50, 50); + // XXX: use last BApplication::WindowAt()'s dynamic_cast<NSBrowserWindow *> Frame() + NSBrowserWindow *win = nsbeos_find_last_window(); + if (win) { + pos = win->Frame().LeftTop(); + win->Unlock(); + } + pos += BPoint(20, 20); + BScreen screen; + BRect screenFrame(screen.Frame()); + if (pos.y + frame.Height() >= screenFrame.Height()) { + pos.y = 50; + pos.x += 50; + } + if (pos.x + frame.Width() >= screenFrame.Width()) { + pos.x = 50; + pos.y = 50; + } + frame.OffsetToSelf(pos); + } + + g->window = new NSBrowserWindow(frame, g); + + rect = frame.OffsetToCopy(0,0); + rect.bottom = rect.top + 20; + + // build menus + g->menu_bar = new BMenuBar(rect, "menu_bar"); + g->window->AddChild(g->menu_bar); + + BMenu *menu; + BMenu *submenu; + BMenuItem *item; + + // App menu + //XXX: use icon item ? + + menu = new BMenu(messages_get("NetSurf")); + g->menu_bar->AddItem(menu); + + message = new BMessage(NO_ACTION); + item = make_menu_item("Info", message); + menu->AddItem(item); + + message = new BMessage(NO_ACTION); + item = make_menu_item("AppHelp", message); + menu->AddItem(item); + + submenu = new BMenu(messages_get("Open")); + menu->AddItem(submenu); + + message = new BMessage(NO_ACTION); + item = make_menu_item("OpenURL", message); + submenu->AddItem(item); + + message = new BMessage(CHOICES_SHOW); + item = make_menu_item("Choices", message); + menu->AddItem(item); + + message = new BMessage(APPLICATION_QUIT); + item = make_menu_item("Quit", message); + menu->AddItem(item); + + // Page menu + + menu = new BMenu(messages_get("Page")); + g->menu_bar->AddItem(menu); + + message = new BMessage(BROWSER_PAGE_INFO); + item = make_menu_item("PageInfo", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_SAVE); + item = make_menu_item("Save", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_SAVE_COMPLETE); + item = make_menu_item("SaveComp", message); + menu->AddItem(item); + + submenu = new BMenu(messages_get("Export")); + menu->AddItem(submenu); + + /* + message = new BMessage(BROWSER_EXPORT_DRAW); + item = make_menu_item("Draw", message); + submenu->AddItem(item); + */ + + message = new BMessage(BROWSER_EXPORT_TEXT); + item = make_menu_item("Text", message); + submenu->AddItem(item); + + + submenu = new BMenu(messages_get("SaveURL")); + menu->AddItem(submenu); + + //XXX + message = new BMessage(BROWSER_OBJECT_SAVE_URL_URL); + item = make_menu_item("URL", message); + submenu->AddItem(item); + + + message = new BMessage(BROWSER_PRINT); + item = make_menu_item("Print", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_NEW_WINDOW); + item = make_menu_item("NewWindow", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_VIEW_SOURCE); + item = make_menu_item("ViewSrc", message); + menu->AddItem(item); + + // Object menu + + menu = new BMenu(messages_get("Object")); + g->menu_bar->AddItem(menu); + + message = new BMessage(BROWSER_OBJECT_INFO); + item = make_menu_item("ObjInfo", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_OBJECT_SAVE); + item = make_menu_item("ObjSave", message); + menu->AddItem(item); + // XXX: submenu: Sprite ? + + message = new BMessage(BROWSER_OBJECT_RELOAD); + item = make_menu_item("ObjReload", message); + menu->AddItem(item); + + // Navigate menu + + menu = new BMenu(messages_get("Navigate")); + g->menu_bar->AddItem(menu); + + message = new BMessage(BROWSER_NAVIGATE_HOME); + item = make_menu_item("Home", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_NAVIGATE_BACK); + item = make_menu_item("Back", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_NAVIGATE_FORWARD); + item = make_menu_item("Forward", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_NAVIGATE_UP); + item = make_menu_item("UpLevel", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_NAVIGATE_RELOAD); + item = make_menu_item("Reload", message); + menu->AddItem(item); + + message = new BMessage(BROWSER_NAVIGATE_STOP); + item = make_menu_item("Stop", message); + menu->AddItem(item); + + // View menu + + menu = new BMenu(messages_get("View")); + g->menu_bar->AddItem(menu); + + message = new BMessage(BROWSER_SCALE_VIEW); + item = make_menu_item("ScaleView", message); + menu->AddItem(item); + + submenu = new BMenu(messages_get("Images")); + menu->AddItem(submenu); + + message = new BMessage(BROWSER_IMAGES_FOREGROUND); + item = make_menu_item("ForeImg", message); + submenu->AddItem(item); + + message = new BMessage(BROWSER_IMAGES_BACKGROUND); + item = make_menu_item("BackImg", message); + submenu->AddItem(item); + + + submenu = new BMenu(messages_get("Toolbars")); + menu->AddItem(submenu); + submenu->SetEnabled(false); + + message = new BMessage(NO_ACTION); + item = make_menu_item("ToolButtons", message); + submenu->AddItem(item); + + message = new BMessage(NO_ACTION); + item = make_menu_item("ToolAddress", message); + submenu->AddItem(item); + + message = new BMessage(NO_ACTION); + item = make_menu_item("ToolThrob", message); + submenu->AddItem(item); + + message = new BMessage(NO_ACTION); + item = make_menu_item("ToolStatus", message); + submenu->AddItem(item); + + + submenu = new BMenu(messages_get("Render")); + menu->AddItem(submenu); + + message = new BMessage(BROWSER_BUFFER_ANIMS); + item = make_menu_item("RenderAnims", message); + submenu->AddItem(item); + + message = new BMessage(BROWSER_BUFFER_ALL); + item = make_menu_item("RenderAll", message); + submenu->AddItem(item); + + + message = new BMessage(NO_ACTION); + item = make_menu_item("OptDefault", message); + menu->AddItem(item); + + // Utilities menu + + menu = new BMenu(messages_get("Utilities")); + g->menu_bar->AddItem(menu); + + submenu = new BMenu(messages_get("Hotlist")); + menu->AddItem(submenu); + + message = new BMessage(HOTLIST_ADD_URL); + item = make_menu_item("HotlistAdd", message); + submenu->AddItem(item); + + message = new BMessage(HOTLIST_SHOW); + item = make_menu_item("HotlistShow", message); + submenu->AddItem(item); + + + submenu = new BMenu(messages_get("History")); + menu->AddItem(submenu); + + message = new BMessage(HISTORY_SHOW_LOCAL); + item = make_menu_item("HistLocal", message); + submenu->AddItem(item); + + message = new BMessage(HISTORY_SHOW_GLOBAL); + item = make_menu_item("HistGlobal", message); + submenu->AddItem(item); + + + submenu = new BMenu(messages_get("Cookies")); + menu->AddItem(submenu); + + message = new BMessage(COOKIES_SHOW); + item = make_menu_item("ShowCookies", message); + submenu->AddItem(item); + + message = new BMessage(COOKIES_DELETE); + item = make_menu_item("DeleteCookies", message); + submenu->AddItem(item); + + + message = new BMessage(BROWSER_FIND_TEXT); + item = make_menu_item("FindText", message); + menu->AddItem(item); + + submenu = new BMenu(messages_get("Window")); + menu->AddItem(submenu); + + message = new BMessage(BROWSER_WINDOW_DEFAULT); + item = make_menu_item("WindowSave", message); + submenu->AddItem(item); + + message = new BMessage(BROWSER_WINDOW_STAGGER); + item = make_menu_item("WindowStagr", message); + submenu->AddItem(item); + + message = new BMessage(BROWSER_WINDOW_COPY); + item = make_menu_item("WindowSize", message); + submenu->AddItem(item); + + message = new BMessage(BROWSER_WINDOW_RESET); + item = make_menu_item("WindowReset", message); + submenu->AddItem(item); + + + // Help menu + + menu = new BMenu(messages_get("Help")); + g->menu_bar->AddItem(menu); + + message = new BMessage(HELP_OPEN_CONTENTS); + item = make_menu_item("HelpContent", message); + menu->AddItem(item); + + message = new BMessage(HELP_OPEN_GUIDE); + item = make_menu_item("HelpGuide", message); + menu->AddItem(item); + + message = new BMessage(HELP_OPEN_INFORMATION); + item = make_menu_item("HelpInfo", message); + menu->AddItem(item); + + message = new BMessage(HELP_OPEN_ABOUT); + item = make_menu_item("HelpAbout", message); + menu->AddItem(item); + + message = new BMessage(HELP_LAUNCH_INTERACTIVE); + item = make_menu_item("HelpInter", message); + menu->AddItem(item); + + // the base view that receives the toolbar, statusbar and top-level view. + rect = frame.OffsetToCopy(0,0); + rect.top = g->menu_bar->Bounds().Height() + 1; + //rect.top = 20 + 1; // XXX + //rect.bottom -= B_H_SCROLL_BAR_HEIGHT; + g->top_view = new NSBaseView(rect); + // add the top view to the window + g->window->AddChild(g->top_view); + } else { // replicant_view + // the base view has already been created with the archive constructor + g->top_view = replicant_view; + } + g->top_view->SetScaffolding(g); + + // build popup menu + g->popup_menu = new BPopUpMenu(""); + + + // the dragger to allow replicating us + // XXX: try to stuff it in the status bar at the bottom + // (BDragger *must* be a parent, sibiling or direct child of NSBaseView!) + rect = g->top_view->Bounds(); + rect.bottom = rect.top + TOOLBAR_HEIGHT - 1; + rect.left = rect.right - DRAGGER_WIDTH + 1; + g->dragger = new BDragger(rect, g->top_view, + B_FOLLOW_RIGHT | B_FOLLOW_TOP, B_WILL_DRAW); + g->top_view->AddChild(g->dragger); + g->dragger->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + g->dragger->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)) ; + + // tool_bar + // the toolbar is also the dragger for now + // XXX: try to stuff it in the status bar at the bottom + // (BDragger *must* be a parent, sibiling or direct child of NSBaseView!) + rect = g->top_view->Bounds(); + rect.bottom = rect.top + TOOLBAR_HEIGHT - 1; + rect.right = rect.right - DRAGGER_WIDTH; + g->tool_bar = new BView(rect, "Toolbar", + B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, B_WILL_DRAW); + g->top_view->AddChild(g->tool_bar); + g->tool_bar->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + g->tool_bar->SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)) ; + + // buttons +#warning use BPictureButton + rect = g->tool_bar->Bounds(); + rect.right = TOOLBAR_HEIGHT; + rect.InsetBySelf(5, 5); + rect.OffsetBySelf(0, -1); + int nButtons = 0; + + message = new BMessage('back'); + message->AddPointer("scaffolding", g); + g->back_button = new BButton(rect, "back_button", "<", message); + g->tool_bar->AddChild(g->back_button); + nButtons++; + + rect.OffsetBySelf(TOOLBAR_HEIGHT, 0); + message = new BMessage('forw'); + message->AddPointer("scaffolding", g); + g->forward_button = new BButton(rect, "forward_button", ">", message); + g->tool_bar->AddChild(g->forward_button); + nButtons++; + + rect.OffsetBySelf(TOOLBAR_HEIGHT, 0); + message = new BMessage('stop'); + message->AddPointer("scaffolding", g); + g->stop_button = new BButton(rect, "stop_button", "S", message); + g->tool_bar->AddChild(g->stop_button); + nButtons++; + + rect.OffsetBySelf(TOOLBAR_HEIGHT, 0); + message = new BMessage('relo'); + message->AddPointer("scaffolding", g); + g->reload_button = new BButton(rect, "reload_button", "R", message); + g->tool_bar->AddChild(g->reload_button); + nButtons++; + + rect.OffsetBySelf(TOOLBAR_HEIGHT, 0); + message = new BMessage('home'); + message->AddPointer("scaffolding", g); + g->home_button = new BButton(rect, "home_button", "H", message); + g->tool_bar->AddChild(g->home_button); + nButtons++; + + + // url bar + rect = g->tool_bar->Bounds(); + rect.left += TOOLBAR_HEIGHT * nButtons; + rect.right -= TOOLBAR_HEIGHT * 1; + rect.InsetBySelf(5, 5); + message = new BMessage('urle'); + message->AddPointer("scaffolding", g); + g->url_bar = new BTextControl(rect, "url_bar", "url", "", message, + B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); + g->url_bar->SetDivider(g->url_bar->StringWidth("url ")); + g->tool_bar->AddChild(g->url_bar); + + + // throbber + rect.Set(0, 0, 24, 24); + rect.OffsetTo(g->tool_bar->Bounds().right - 24 - (TOOLBAR_HEIGHT - 24) / 2, + (TOOLBAR_HEIGHT - 24) / 2); + g->throbber = new NSThrobber(rect); + g->tool_bar->AddChild(g->throbber); + g->throbber->SetViewColor(g->tool_bar->ViewColor()); + g->throbber->SetLowColor(g->tool_bar->ViewColor()); + g->throbber->SetDrawingMode(B_OP_ALPHA); + g->throbber->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); + /* set up the throbber. */ + g->throbber->SetBitmap(nsbeos_throbber->framedata[0]); + g->throb_frame = 0; + + + // the status bar at the bottom + BString status("NetSurf"); + status << " " << netsurf_version; + g->status_bar = new BStringView(BRect(0,0,-1,-1), "StatusBar", + status.String(), B_FOLLOW_LEFT/*_RIGHT*/ | B_FOLLOW_BOTTOM); + + // will be added to the scrollview when adding the top view. + + // notify the thread creating the replicant that we're done + if (replicant_view) + release_sem(replicant_done_sem); + + replicant_view = NULL; + +#warning XXX +#if 0 /* GTK */ + /* load the window template from the glade xml file, and extract + * widget references from it for later use. + */ + g->xml = glade_xml_new(glade_file_location, "wndBrowser", NULL); + glade_xml_signal_autoconnect(g->xml); + g->window = beos_WINDOW(GET_WIDGET("wndBrowser")); + g->url_bar = beos_ENTRY(GET_WIDGET("URLBar")); + g->menu_bar = beos_MENU_BAR(GET_WIDGET("menubar")); + g->status_bar = beos_LABEL(GET_WIDGET("statusBar")); + g->tool_bar = beos_TOOLBAR(GET_WIDGET("toolbar")); + g->back_button = beos_TOOL_BUTTON(GET_WIDGET("toolBack")); + g->forward_button = beos_TOOL_BUTTON(GET_WIDGET("toolForward")); + g->stop_button = beos_TOOL_BUTTON(GET_WIDGET("toolStop")); + g->reload_button = beos_TOOL_BUTTON(GET_WIDGET("toolReload")); + g->back_menu = beos_MENU_ITEM(GET_WIDGET("back")); + g->forward_menu = beos_MENU_ITEM(GET_WIDGET("forward")); + g->stop_menu = beos_MENU_ITEM(GET_WIDGET("stop")); + g->reload_menu = beos_MENU_ITEM(GET_WIDGET("reload")); + g->throbber = beos_IMAGE(GET_WIDGET("throbber")); + g->status_pane = beos_PANED(GET_WIDGET("hpaned1")); + + /* set this window's size and position to what's in the options, or + * or some sensible default if they're not set yet. + */ + if (nsoption_int(window_width) > 0) { + beos_window_move(g->window, nsoption_int(window_x), nsoption_int(window_y)); + beos_window_resize(g->window, nsoption_int(window_width), + nsoption_int(window_height)); + } else { + beos_window_set_default_size(g->window, 600, 600); + } + + /* set the size of the hpane with status bar and h scrollbar */ + beos_paned_set_position(g->status_pane, nsoption_int(toolbar_status_width)); + + /* set the URL entry box to expand, as we can't do this from within + * glade because of the way it emulates toolbars. + */ + beos_tool_item_set_expand(beos_TOOL_ITEM(GET_WIDGET("toolURLBar")), TRUE); + + /* disable toolbar buttons that make no sense initially. */ + beos_widget_set_sensitive(beos_WIDGET(g->back_button), FALSE); + beos_widget_set_sensitive(beos_WIDGET(g->forward_button), FALSE); + beos_widget_set_sensitive(beos_WIDGET(g->stop_button), FALSE); + + /* create the local history window to be assoicated with this browser */ + g->history_window = malloc(sizeof(struct beos_history_window)); + g->history_window->g = g; + g->history_window->window = beos_WINDOW( + beos_window_new(beos_WINDOW_TOPLEVEL)); + beos_window_set_transient_for(g->history_window->window, g->window); + beos_window_set_default_size(g->history_window->window, 400, 400); + beos_window_set_title(g->history_window->window, "NetSurf History"); + beos_window_set_type_hint(g->history_window->window, + GDK_WINDOW_TYPE_HINT_UTILITY); + g->history_window->scrolled = beos_SCROLLED_WINDOW( + beos_scrolled_window_new(0, 0)); + beos_container_add(beos_CONTAINER(g->history_window->window), + beos_WIDGET(g->history_window->scrolled)); + + beos_widget_show(beos_WIDGET(g->history_window->scrolled)); + g->history_window->drawing_area = beos_DRAWING_AREA( + beos_drawing_area_new()); + + beos_widget_set_events(beos_WIDGET(g->history_window->drawing_area), + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK); + beos_widget_modify_bg(beos_WIDGET(g->history_window->drawing_area), + beos_STATE_NORMAL, + &((GdkColor) { 0, 0xffff, 0xffff, 0xffff } )); + beos_scrolled_window_add_with_viewport(g->history_window->scrolled, + beos_WIDGET(g->history_window->drawing_area)); + beos_widget_show(beos_WIDGET(g->history_window->drawing_area)); + + /* set up URL bar completion */ + g->url_bar_completion = beos_entry_completion_new(); + beos_entry_set_completion(g->url_bar, g->url_bar_completion); + beos_entry_completion_set_match_func(g->url_bar_completion, + nsbeos_completion_match, NULL, NULL); + beos_entry_completion_set_model(g->url_bar_completion, + beos_TREE_MODEL(nsbeos_completion_list)); + beos_entry_completion_set_text_column(g->url_bar_completion, 0); + beos_entry_completion_set_minimum_key_length(g->url_bar_completion, 1); + beos_entry_completion_set_popup_completion(g->url_bar_completion, TRUE); + g_object_set(G_OBJECT(g->url_bar_completion), + "popup-set-width", TRUE, + "popup-single-match", TRUE, + NULL); + + /* set up the throbber. */ + beos_image_set_from_pixbuf(g->throbber, nsbeos_throbber->framedata[0]); + g->throb_frame = 0; + +#define CONNECT(obj, sig, callback, ptr) \ + g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) + + /* connect history window signals to their handlers */ + CONNECT(g->history_window->drawing_area, "expose_event", + nsbeos_history_expose_event, g->history_window); +// CONNECT(g->history_window->drawing_area, "motion_notify_event", +// nsbeos_history_motion_notify_event, g->history_window); + CONNECT(g->history_window->drawing_area, "button_press_event", + nsbeos_history_button_press_event, g->history_window); + CONNECT(g->history_window->window, "delete_event", + beos_widget_hide_on_delete, NULL); + + /* connect signals to handlers. */ + CONNECT(g->window, "destroy", nsbeos_window_destroy_event, g); + + /* toolbar and URL bar signal handlers */ + CONNECT(g->back_button, "clicked", nsbeos_window_back_button_clicked, g); + CONNECT(g->forward_button, "clicked", + nsbeos_window_forward_button_clicked, g); + CONNECT(g->stop_button, "clicked", nsbeos_window_stop_button_clicked, g); + CONNECT(g->reload_button, "clicked", + nsbeos_window_reload_button_clicked, g); + CONNECT(GET_WIDGET("toolHome"), "clicked", + nsbeos_window_home_button_clicked, g); + CONNECT(g->url_bar, "activate", nsbeos_window_url_activate_event, g); + CONNECT(g->url_bar, "changed", nsbeos_window_url_changed, g); + + /* set up the menu signal handlers */ + nsbeos_attach_menu_handlers(g->xml, g); + + g->being_destroyed = 0; + + g->fullscreen = false; + + /* create the popup version of the menu */ + g->popup_xml = glade_xml_new(glade_file_location, "menuPopup", NULL); + g->popup_menu = beos_MENU(glade_xml_get_widget(g->popup_xml, "menuPopup")); + +#define POPUP_ATTACH(x, y) beos_menu_item_set_submenu( \ + beos_MENU_ITEM(glade_xml_get_widget(g->popup_xml, x)),\ + beos_WIDGET(glade_xml_get_widget(g->xml, y))) + + POPUP_ATTACH("menupopup_file", "menumain_file"); + POPUP_ATTACH("menupopup_edit", "menumain_edit"); + POPUP_ATTACH("menupopup_view", "menumain_view"); + POPUP_ATTACH("menupopup_navigate", "menumain_navigate"); + POPUP_ATTACH("menupopup_help", "menumain_help"); + +#undef POPUP_ATTACH + + /* finally, show the window. */ + beos_widget_show(beos_WIDGET(g->window)); + +#endif + return g; +} + +void gui_window_set_title(struct gui_window *_g, const char *title) +{ + struct beos_scaffolding *g = nsbeos_get_scaffold(_g); + if (g->top_level != _g) return; + + // if we're a replicant, discard + if (!g->window) + return; + + BString nt(title); + if (nt.Length()) + nt << " - "; + nt << "NetSurf"; + + if (!g->top_view->LockLooper()) + return; + + g->window->SetTitle(nt.String()); + + g->top_view->UnlockLooper(); +} + +void gui_window_set_status(struct gui_window *_g, const char *text) +{ + struct beos_scaffolding *g = nsbeos_get_scaffold(_g); + assert(g); + assert(g->status_bar); + + if (!g->top_view->LockLooper()) + return; + + if (text == NULL || text[0] == '\0') + { + BString status("NetSurf"); + status << " " << netsurf_version; + g->status_bar->SetText(status.String()); + } + else + { + g->status_bar->SetText(text); + } + g->top_view->UnlockLooper(); +} + +void gui_window_set_url(struct gui_window *_g, const char *url) +{ + struct beos_scaffolding *g = nsbeos_get_scaffold(_g); + if (g->top_level != _g) return; + assert(g->status_bar); + + if (!g->top_view->LockLooper()) + return; + + g->url_bar->SetText(url); + + g->top_view->UnlockLooper(); +} + +void gui_window_start_throbber(struct gui_window* _g) +{ + struct beos_scaffolding *g = nsbeos_get_scaffold(_g); + + if (!g->top_view->LockLooper()) + return; + + g->stop_button->SetEnabled(true); + g->reload_button->SetEnabled(false); + + g->top_view->UnlockLooper(); + + nsbeos_window_update_back_forward(g); + + schedule(10, nsbeos_throb, g); +} + +void gui_window_stop_throbber(struct gui_window* _g) +{ + struct beos_scaffolding *g = nsbeos_get_scaffold(_g); + + nsbeos_window_update_back_forward(g); + + schedule_remove(nsbeos_throb, g); + + if (!g->top_view->LockLooper()) + return; + + g->stop_button->SetEnabled(false); + g->reload_button->SetEnabled(true); + + g->throbber->SetBitmap(nsbeos_throbber->framedata[0]); + g->throbber->Invalidate(); + + g->top_view->UnlockLooper(); +} + +/** + * add retrieved favicon to the gui + */ +void gui_window_set_icon(struct gui_window *g, hlcache_handle *icon) +{ +} + +/** +* set gui display of a retrieved favicon representing the search provider +* \param ico may be NULL for local calls; then access current cache from +* search_web_ico() +*/ +void gui_window_set_search_ico(hlcache_handle *ico) +{ +} + +#warning XXX +#if 0 /* GTK */ +gboolean nsbeos_scaffolding_is_busy(nsbeos_scaffolding *scaffold) +{ + /* We are considered "busy" if the stop button is sensitive */ + return beos_WIDGET_SENSITIVE((beos_WIDGET(scaffold->stop_button))); +} +#endif + +void nsbeos_scaffolding_popup_menu(nsbeos_scaffolding *g, BPoint where) +{ + g->popup_menu->Go(where); +} |