From eb28188661262eef8aad4b530a3f16532aceffd4 Mon Sep 17 00:00:00 2001 From: Adrien Destugues - PulkoMandy Date: Thu, 15 Nov 2012 22:34:42 +0100 Subject: [PATCH] Update the BeOS/Haiku port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Toolbar use HVIF icons on Haiku * Download window * Some tweaks to the event loop to let network traffic happen Signed-off-by: François Revol --- Makefile | 2 +- beos/Makefile.target | 21 ++-- beos/WindowStack.h | 45 ++++++++ beos/download.cpp | 246 +++++++++++++++++++++++++++++++++++++++++++ beos/download.h | 18 ++++ beos/fetch_rsrc.cpp | 8 +- beos/gui.cpp | 111 ++++++------------- beos/login.cpp | 25 +++-- beos/res.rdef | 41 ++++++++ beos/scaffolding.cpp | 152 ++++++++++++++++++++++++-- beos/scaffolding.h | 4 + beos/schedule.cpp | 6 +- beos/window.cpp | 62 +++++++++-- utils/config.h | 4 +- 14 files changed, 616 insertions(+), 129 deletions(-) create mode 100644 beos/WindowStack.h create mode 100644 beos/download.cpp create mode 100644 beos/download.h diff --git a/Makefile b/Makefile index c80378cbc..428aa74b4 100644 --- a/Makefile +++ b/Makefile @@ -453,7 +453,7 @@ ifeq ($(TARGET),beos) $(Q)$(BEOS_SETVER) $(EXETARGET) \ -app $(VERSION_MAJ) $(VERSION_MIN) 0 d 0 \ -short "NetSurf $(VERSION_FULL)" \ - -long "NetSurf $(VERSION_FULL) © 2003 - 2008 The NetSurf Developers" + -long "NetSurf $(VERSION_FULL) © 2003 - 2012 The NetSurf Developers" $(VQ)echo " MIMESET: $(EXETARGET)" $(Q)$(BEOS_MIMESET) $(EXETARGET) endif diff --git a/beos/Makefile.target b/beos/Makefile.target index af7c939ad..f4b51ab3c 100644 --- a/beos/Makefile.target +++ b/beos/Makefile.target @@ -9,8 +9,10 @@ # for Haiku LDFLAGS += -L/boot/common/lib # some people do *not* have libm... - LDFLAGS += -lcurl -liconv - LDFLAGS += -lssl -lcrypto -lcss -ldom -lparserutils -lhubbub -lwapcaplet + LDFLAGS += -lssl -lcrypto -lcss + $(eval $(call feature_enabled,NSSVG,-DWITH_NS_SVG,-lsvgtiny,SVG (libsvgtiny))) + LDFLAGS += -ldom -lparserutils -lhubbub -lwapcaplet + LDFLAGS += -lexpat -lxml2 -lcurl -liconv CFLAGS += -I. -O $(WARNFLAGS) -Dnsbeos \ -D_BSD_SOURCE -D_POSIX_C_SOURCE \ @@ -59,9 +61,8 @@ # cross: Haiku ? NETLDFLAGS := -lnetwork endif - LDFLAGS += -lbe -ltranslation $(NETLDFLAGS) + LDFLAGS += -lbe -ltranslation -ltracker $(NETLDFLAGS) -lstdc++ -lsupc++ - $(eval $(call feature_enabled,NSSVG,-DWITH_NS_SVG,-lsvgtiny,SVG (libsvgtiny))) ifeq ($(HOST),beos) CFLAGS += -I$(PREFIX)/include LDFLAGS += -L$(PREFIX)/lib @@ -82,11 +83,9 @@ # ---------------------------------------------------------------------------- # S_BEOS are sources purely for the BeOS build -S_BEOS := about.cpp bitmap.cpp fetch_rsrc.cpp \ - filetype.cpp font.cpp gui.cpp login.cpp \ - gui_options.cpp plotters.cpp \ - scaffolding.cpp search.cpp schedule.cpp \ - thumbnail.cpp treeview.cpp throbber.cpp \ +S_BEOS := about.cpp bitmap.cpp download.cpp fetch_rsrc.cpp filetype.cpp \ + font.cpp gui.cpp login.cpp gui_options.cpp plotters.cpp scaffolding.cpp \ + search.cpp schedule.cpp thumbnail.cpp treeview.cpp throbber.cpp \ window.cpp system_colour.cpp S_BEOS := $(addprefix beos/,$(S_BEOS)) @@ -98,7 +97,7 @@ RDEF_IMP_BEOS := $(addprefix $(OBJROOT)/,$(subst /,_,$(RDEF_IMP_BEOS))) RDEP_BEOS := \ adblock.css beosdefault.css default.css internal.css quirks.css \ - netsurf.png ca-bundle.txt messages + netsurf.png ca-bundle.txt RDEP_BEOS := $(addprefix beos/res/,$(RDEP_BEOS)) \ $(wildcard beos/res/Icons/*.png) \ $(wildcard beos/res/throbber/throbber*.png) @@ -126,7 +125,7 @@ install-beos: @cp -vRL beos/res/beosdefault.css $(DESTDIR)$(NETSURF_BEOS_RESOURCES) @cp -vRL gtk/res/license $(DESTDIR)$(NETSURF_BEOS_RESOURCES) # @cp -vRL beos/res/throbber/*.png $(DESTDIR)$(NETSURF_BEOS_RESOURCES)throbber - gzip -9v < beos/res/messages > $(DESTDIR)$(NETSURF_BEOS_RESOURCES)messages + $(call split_install_messages, beos, $(DESTDIR)$(NETSURF_BEOS_RESOURCES)) # ---------------------------------------------------------------------------- # Package target diff --git a/beos/WindowStack.h b/beos/WindowStack.h new file mode 100644 index 000000000..947b14360 --- /dev/null +++ b/beos/WindowStack.h @@ -0,0 +1,45 @@ +/* + * Copyright 2010, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef WINDOW_STACK_H +#define WINDOW_STACK_H + + +#include + + +class BWindowStack { +public: + BWindowStack(BWindow* window); + ~BWindowStack(); + + status_t AddWindow(const BWindow* window); + status_t AddWindow(const BMessenger& window); + status_t AddWindowAt(const BWindow* window, + int32 position); + status_t AddWindowAt(const BMessenger& window, + int32 position); + + status_t RemoveWindow(const BWindow* window); + status_t RemoveWindow(const BMessenger& window); + status_t RemoveWindowAt(int32 position, + BMessenger* window = NULL); + + int32 CountWindows(); + + status_t WindowAt(int32 position, + BMessenger& messenger); + bool HasWindow(const BWindow* window); + bool HasWindow(const BMessenger& window); + +private: + status_t _AttachMessenger(const BMessenger& window); + status_t _ReadMessenger(BMessenger& window); + status_t _StartMessage(int32 what); + + BPrivate::PortLink* fLink; +}; + + +#endif diff --git a/beos/download.cpp b/beos/download.cpp new file mode 100644 index 000000000..e1a0c8c0f --- /dev/null +++ b/beos/download.cpp @@ -0,0 +1,246 @@ +/* + * Copyright 2012 Adrien Destugues + * + * 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 . + */ + +extern "C" { +#include "desktop/gui.h" +} +#include "beos/download.h" + +#include +#include +#include +#include +#include +#include + +class NSDownloadWindow: public BWindow +{ + public: + NSDownloadWindow(download_context* ctx); + ~NSDownloadWindow(); + + void MessageReceived(BMessage* message); + + void Progress(int size); + void Failure(const char* error); + void Success(); + private: + download_context* ctx; + BStatusBar* bar; + unsigned long progress; + bool success; +}; + + +struct gui_download_window { + download_context* ctx; + NSDownloadWindow* window; + + BLocker* storageLock; + BDataIO* storage; +}; + + +NSDownloadWindow::NSDownloadWindow(download_context* ctx) + : BWindow(BRect(30, 30, 400, 200), "Downloads", B_TITLED_WINDOW, + B_NOT_RESIZABLE) + , ctx(ctx) + , progress(0) + , success(false) +{ + unsigned long dlsize = download_context_get_total_length(ctx); + char* buffer = human_friendly_bytesize(dlsize); + + // Create the status bar + BRect rect = Bounds(); + rect.InsetBy(3, 3); + bar = new BStatusBar(rect, "progress", + download_context_get_filename(ctx), buffer); + bar->SetMaxValue(dlsize); + + // Create the backgroundview (just so that the area around the progress bar + // is B_PANEL_BACKGROUND_COLOR instead of white) + BView* back = new BView(Bounds(), "back", B_FOLLOW_ALL_SIDES, B_WILL_DRAW); + back->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + // Add the views to the window + back->AddChild(bar); + AddChild(back); + + // Resize the window to leave a margin around the progress bar + BRect size = bar->Bounds(); + ResizeTo(size.Width() + 6, size.Height() + 6); + Show(); +} + + +NSDownloadWindow::~NSDownloadWindow() +{ + download_context_abort(ctx); + download_context_destroy(ctx); +} + + +void +NSDownloadWindow::MessageReceived(BMessage* message) +{ + switch(message->what) + { + case B_SAVE_REQUESTED: + { + entry_ref directory; + const char* name; + struct gui_download_window* dw; + BFilePanel* source; + + message->FindRef("directory", &directory); + message->FindString("name", &name); + message->FindPointer("dw", (void**)&dw); + + BDirectory dir(&directory); + BFile* storage = new BFile(&dir, name, + B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + dw->storageLock->Lock(); + + BMallocIO* tempstore = dynamic_cast(dw->storage); + + storage->Write(tempstore->Buffer(), tempstore->BufferLength()); + delete dw->storage; + + if (success) + delete storage; // File is already finished downloading ! + else + dw->storage = storage; + dw->storageLock->Unlock(); + + message->FindPointer("source", (void**)&source); + delete source; + + break; + } + default: + BWindow::MessageReceived(message); + } +} + + +void +NSDownloadWindow::Progress(int size) +{ + progress += size; + + char* buffer = human_friendly_bytesize(progress); + strcat(buffer, "/"); + + bar->LockLooper(); + bar->Update(size, NULL, buffer); + bar->Invalidate(); + bar->UnlockLooper(); +} + + +void +NSDownloadWindow::Success() +{ + bar->LockLooper(); + bar->SetBarColor(ui_color(B_SUCCESS_COLOR)); + bar->UnlockLooper(); + + success = true; +} + + +void +NSDownloadWindow::Failure(const char* error) +{ + bar->LockLooper(); + bar->Update(0, NULL, error); + bar->SetBarColor(ui_color(B_FAILURE_COLOR)); + bar->UnlockLooper(); +} + + +struct gui_download_window *gui_download_window_create(download_context *ctx, + struct gui_window *parent) +{ + struct gui_download_window *download = (struct gui_download_window*)malloc(sizeof *download); + if (download == NULL) + return NULL; + + download->storageLock = new BLocker("storage_lock"); + download->storage = new BMallocIO(); + download->ctx = ctx; + + download->window = new NSDownloadWindow(ctx); + + // Also ask the user where to save the file + // TODO inject the suggested name somehow + BMessage* msg = new BMessage(B_SAVE_REQUESTED); + + BFilePanel* panel = new BFilePanel(B_SAVE_PANEL, + new BMessenger(download->window), NULL, 0, false); + + msg->AddPointer("source", panel); + msg->AddPointer("dw", download); + panel->SetMessage(msg); + + panel->Show(); + + return download; +} + + +nserror gui_download_window_data(struct gui_download_window *dw, + const char *data, unsigned int size) +{ + dw->window->Progress(size); + + dw->storageLock->Lock(); + dw->storage->Write(data, size); + dw->storageLock->Unlock(); + + return NSERROR_OK; +} + + +void gui_download_window_error(struct gui_download_window *dw, + const char *error_msg) +{ + dw->window->Failure(error_msg); + + delete dw->storageLock; + delete dw->storage; +} + + +void gui_download_window_done(struct gui_download_window *dw) +{ + dw->window->Success(); + + dw->storageLock->Lock(); + + // Only delete if the storage is already a file. Else, we must wait for the + // user to select something in the BFilePanel! + BFile* file = dynamic_cast(dw->storage); + delete file; + if (file) + delete dw->storageLock; + else + dw->storageLock->Unlock(); +} + diff --git a/beos/download.h b/beos/download.h new file mode 100644 index 000000000..9c8d3adcd --- /dev/null +++ b/beos/download.h @@ -0,0 +1,18 @@ +/* + * Copyright 2012 Adrien Destugues + * + * 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 . + */ + diff --git a/beos/fetch_rsrc.cpp b/beos/fetch_rsrc.cpp index 79dea4e76..563f43145 100644 --- a/beos/fetch_rsrc.cpp +++ b/beos/fetch_rsrc.cpp @@ -48,6 +48,7 @@ extern "C" { #include #include +#include struct fetch_rsrc_context { struct fetch *parent_fetch; @@ -209,8 +210,13 @@ static bool fetch_rsrc_process(struct fetch_rsrc_context *c) else found = gAppResources->HasResource(type, c->name); if (!found) { + BString error("Cannot locate resource: "); + if (id) + error << id; + else + error << c->name; msg.type = FETCH_ERROR; - msg.data.error = "Cannot locate rsrc: URL"; + msg.data.error = error.String(); fetch_rsrc_send_callback(&msg, c); return false; } diff --git a/beos/gui.cpp b/beos/gui.cpp index b275616f5..c4e7feb2f 100644 --- a/beos/gui.cpp +++ b/beos/gui.cpp @@ -450,7 +450,6 @@ static void gui_init2(int argc, char** argv) /** Normal entry point from OS */ int main(int argc, char** argv) { - char buf[PATH_MAX]; setbuf(stderr, NULL); BPath options; @@ -458,12 +457,10 @@ int main(int argc, char** argv) options.Append("x-vnd.NetSurf"); } - find_resource(buf, "messages", "./beos/res/messages"); - LOG(("Using '%s' as Messages file", buf)); - //messages_load(buf); + char* messages = "/boot/apps/netsurf/res/en/Messages"; /* initialise netsurf */ - netsurf_init(&argc, &argv, options.Path(), buf); + netsurf_init(&argc, &argv, options.Path(), messages); gui_init(argc, argv); gui_init2(argc, argv); @@ -553,37 +550,38 @@ void gui_init(int argc, char** argv) /* check what the font settings are, setting them to a default font * if they're not set - stops Pango whinging */ +#define SETFONTDEFAULT(OPTION,y) if (nsoption_charp(OPTION) == NULL) nsoption_set_charp(OPTION, strdup((y))) //XXX: use be_plain_font & friends, when we can check if font is serif or not. /* font_family family; font_style style; be_plain_font->GetFamilyAndStyle(&family, &style); - nsoption_setnull_charp(font_sans, family); - nsoption_setnull_charp(font_serif, family); - nsoption_setnull_charp(font_mono, family); - nsoption_setnull_charp(font_cursive, family); - nsoption_setnull_charp(font_fantasy, family); + SETFONTDEFAULT(font_sans, family); + SETFONTDEFAULT(font_serif, family); + SETFONTDEFAULT(font_mono, family); + SETFONTDEFAULT(font_cursive, family); + SETFONTDEFAULT(font_fantasy, family); */ #ifdef __HAIKU__ - nsoption_setnull_charp(font_sans, "DejaVu Sans"); - nsoption_setnull_charp(font_serif, "DejaVu Serif"); - nsoption_setnull_charp(font_mono, "DejaVu Mono"); - nsoption_setnull_charp(font_cursive, "DejaVu Sans"); - nsoption_setnull_charp(font_fantasy, "DejaVu Sans"); + SETFONTDEFAULT(font_sans, "DejaVu Sans"); + SETFONTDEFAULT(font_serif, "DejaVu Serif"); + SETFONTDEFAULT(font_mono, "DejaVu Mono"); + SETFONTDEFAULT(font_cursive, "DejaVu Sans"); + SETFONTDEFAULT(font_fantasy, "DejaVu Sans"); #else - nsoption_setnull_charp(font_sans, "Bitstream Vera Sans"); - nsoption_setnull_charp(font_serif, "Bitstream Vera Serif"); - nsoption_setnull_charp(font_mono, "Bitstream Vera Sans Mono"); - nsoption_setnull_charp(font_cursive, "Bitstream Vera Serif"); - nsoption_setnull_charp(font_fantasy, "Bitstream Vera Serif"); + SETFONTDEFAULT(font_sans, "Bitstream Vera Sans"); + SETFONTDEFAULT(font_serif, "Bitstream Vera Serif"); + SETFONTDEFAULT(font_mono, "Bitstream Vera Sans Mono"); + SETFONTDEFAULT(font_cursive, "Bitstream Vera Serif"); + SETFONTDEFAULT(font_fantasy, "Bitstream Vera Serif"); #if 0 - nsoption_setnull_charp(font_sans, "Swis721 BT"); - nsoption_setnull_charp(font_serif, "Dutch801 Rm BT"); - //nsoption_setnull_charp(font_mono, "Monospac821 BT"); - nsoption_setnull_charp(font_mono, "Courier10 BT"); - nsoption_setnull_charp(font_cursive, "Swis721 BT"); - nsoption_setnull_charp(font_fantasy, "Swis721 BT"); + SETFONTDEFAULT(font_sans, "Swis721 BT"); + SETFONTDEFAULT(font_serif, "Dutch801 Rm BT"); + //SETFONTDEFAULT(font_mono, "Monospac821 BT"); + SETFONTDEFAULT(font_mono, "Courier10 BT"); + SETFONTDEFAULT(font_cursive, "Swis721 BT"); + SETFONTDEFAULT(font_fantasy, "Swis721 BT"); #endif #endif @@ -681,46 +679,32 @@ void nsbeos_pipe_message_top(BMessage *message, BWindow *_this, struct beos_scaf void gui_poll(bool active) { //CALLED(); - CURLMcode code; - fd_set read_fd_set, write_fd_set, exc_fd_set; - int max_fd = 0; struct timeval timeout; unsigned int fd_count = 0; - bool block = true; + bigtime_t next_schedule = 0; - if (browser_reformat_pending) - block = false; + schedule_run(); FD_ZERO(&read_fd_set); FD_ZERO(&write_fd_set); FD_ZERO(&exc_fd_set); - if (active) { - code = curl_multi_fdset(fetch_curl_multi, - &read_fd_set, - &write_fd_set, - &exc_fd_set, - &max_fd); - assert(code == CURLM_OK); - } - // our own event pipe FD_SET(sEventPipe[0], &read_fd_set); - max_fd = MAX(max_fd, sEventPipe[0] + 1); - bigtime_t next_schedule = earliest_callback_timeout - system_time(); - if (!block) - next_schedule = 0LL; // now - if (block && earliest_callback_timeout != B_INFINITE_TIMEOUT) - block = false; + // If there are pending events elsewhere, we should not be blocking + if ((!browser_reformat_pending) && (!active)) { + next_schedule = earliest_callback_timeout - system_time(); + + } // else, we're not allowed to sleep, there is other activity going on. + timeout.tv_sec = (long)(next_schedule / 1000000LL); timeout.tv_usec = (long)(next_schedule % 1000000LL); - LOG(("gui_poll: select(%d, ..., %Ldus", max_fd, next_schedule)); - fd_count = select(max_fd, &read_fd_set, &write_fd_set, &exc_fd_set, - block ? NULL : &timeout); + fd_count = select(sEventPipe[0] + 1, &read_fd_set, &write_fd_set, &exc_fd_set, + &timeout); if (fd_count > 0 && FD_ISSET(sEventPipe[0], &read_fd_set)) { BMessage *message; @@ -730,8 +714,6 @@ void gui_poll(bool active) nsbeos_dispatch_event(message); } - schedule_run(); - if (browser_reformat_pending) nsbeos_window_process_reformats(); } @@ -751,31 +733,6 @@ void gui_quit(void) } - -struct gui_download_window *gui_download_window_create(download_context *ctx, - struct gui_window *gui) -{ - return NULL; -} - - -nserror gui_download_window_data(struct gui_download_window *dw, - const char *data, unsigned int size) -{ - return NSERROR_OK; -} - - -void gui_download_window_error(struct gui_download_window *dw, - const char *error_msg) -{ -} - - -void gui_download_window_done(struct gui_download_window *dw) -{ -} - #if 0 /* GTK */ static void nsbeos_select_menu_clicked(BCheckMenuItem *checkmenuitem, gpointer user_data) diff --git a/beos/login.cpp b/beos/login.cpp index 32860de20..90cadde7b 100644 --- a/beos/login.cpp +++ b/beos/login.cpp @@ -45,7 +45,7 @@ class LoginAlert : public BAlert { public: LoginAlert(nserror (*callback)(bool proceed, void *pw), void *callbaclpw, - const char *url, + nsurl *url, const char *host, const char *realm, const char *text); @@ -53,7 +53,7 @@ public: void MessageReceived(BMessage *message); private: - BString fUrl; /**< URL being fetched */ + nsurl* fUrl; /**< URL being fetched */ BString fHost; /**< Host for user display */ BString fRealm; /**< Authentication realm */ nserror (*fCallback)(bool proceed, void *pw); @@ -63,8 +63,8 @@ private: BTextControl *fPassControl; }; -static void create_login_window(const char *host, - const char *realm, const char *fetchurl, +static void create_login_window(nsurl *host, + lwc_string *realm, const char *fetchurl, nserror (*cb)(bool proceed, void *pw), void *cbpw); @@ -73,7 +73,7 @@ static void create_login_window(const char *host, LoginAlert::LoginAlert(nserror (*callback)(bool proceed, void *pw), void *callbackpw, - const char *url, + nsurl *url, const char *host, const char *realm, const char *text) @@ -140,7 +140,7 @@ LoginAlert::MessageReceived(BMessage *message) break; BMessage *m = new BMessage(*message); m->what = 'nsLO'; - m->AddString("URL", fUrl.String()); + m->AddPointer("URL", fUrl); m->AddString("Host", fHost.String()); m->AddString("Realm", fRealm.String()); m->AddPointer("callback", (void *)fCallback); @@ -163,14 +163,13 @@ LoginAlert::MessageReceived(BMessage *message) } -void gui_401login_open(const char *url, const char *realm, +extern "C" void gui_401login_open(nsurl *url, const char *realm, nserror (*cb)(bool proceed, void *pw), void *cbpw) { - char *host; + lwc_string *host; url_func_result res; - res = url_host(url, &host); - assert(res == URL_FUNC_OK); + host = nsurl_get_component(url, NSURL_HOST); create_login_window(url, host, realm, cb, cbpw); @@ -179,7 +178,7 @@ void gui_401login_open(const char *url, const char *realm, //void create_login_window(struct browser_window *bw, const char *host, // const char *realm, const char *fetchurl) -static void create_login_window(const char *url, const char *host, +static void create_login_window(nsurl *url, lwc_string *host, const char *realm, nserror (*cb)(bool proceed, void *pw), void *cbpw) { @@ -191,8 +190,8 @@ static void create_login_window(const char *url, const char *host, text << "Host: " << host << "\n"; //text << "\n"; - LoginAlert *a = new LoginAlert(cb, cbpw, url, host, r.String(), - text.String()); + LoginAlert *a = new LoginAlert(cb, cbpw, url, lwc_string_data(host), + r.String(), text.String()); // asynchronously a->Go(NULL); diff --git a/beos/res.rdef b/beos/res.rdef index b047bd02a..b41130ad7 100644 --- a/beos/res.rdef +++ b/beos/res.rdef @@ -32,6 +32,7 @@ resource(408, "throbber8.png") #'data' import "res/throbber/throbber8.png"; /* */ resource(500, "credits.html") #'data' import "res/en/credits.html,faf"; resource(501, "licence.html") #'data' import "res/en/licence.html,faf"; +resource(502, "welcome.html") #'data' import "res/en/welcome.html,faf"; resource(1, "BEOS:APP_FLAGS") (#'APPF') $"01000000"; @@ -397,3 +398,43 @@ resource(101, "BEOS:V:STD_ICON") #'zICO' array { $"7F793EDCE3F417BB10DA0B" }; +resource(102, "forward_button") #'VICN' array { + $"6E6369660304006603005900020006020000003C6000C000000000004C000048" + $"A0000080FF80FF00B300010A0748353448343E223E222C342C3422030A000100" + $"30222201178322040A0101001001178322040A02010000" +}; + +resource(103, "back_button") #'VICN' array { + $"6E6369660304006603005900020006020000003C6000C000000000004C000048" + $"A0000080FF80FF00B300010A0722353622362C482C483E363E3648030A000100" + $"30222201178322040A0101001001178322040A02010000" +}; + +resource(104, "stop_button") #'VICN' array { + $"6E6369660304006603800000020006020000003C6000C000000000004C000048" + $"A00000FFABABFFD900000208022A40402A02043525BEE325B7D825253525B7D8" + $"25BEE33545B7D845BEE345453545BEE345B7D8030A0002000130222201178900" + $"040A010200011001178900040A02020100100117850004" +}; + +resource(105, "reload_button") #'VICN' array { + $"6E6369660404006603004080020006020000003A0000C000000000004C000046" + $"7FFF00ABD5FFFF006CD9020006020000003A0000C000000000004C0000467FFF" + $"FFAAD4FF00006CD9010606C60F482232383D2D3D2D3826222A2B2329224327BC" + $"B7B25A4327060A00010030222201178322040A0101001001178322040A020100" + $"000A00010012C00000000000000000C000004AC0004AC00001178422040A0101" + $"0012C00000000000000000C000004AA0004AA00001178422040A03010002C000" + $"00000000000000C000004AA0004AA000" +}; + +resource(106, "home_button") #'VICN' array { + $"6E6369660804006603800000020006020000003A8000C000000000004C000047" + $"000000FFABABFFD900000554020016020000003AC000C000000000004BE00048" + $"A00000FFFFE50300590002000602000000370000C000000000004C00004A5000" + $"0080FF80FF00B20003806040040A064836483035222230223635280A04484848" + $"42224222480A0542404234352A283428400A042C342C4032403234080A030102" + $"1001178400040A040102000A0101001001178402040A020100000A0501011001" + $"178402040A060101000A070103000A0701030240AAAA0000000000003E000045" + $"0000468000" +}; + diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp index 4003b0951..74c3c81e5 100644 --- a/beos/scaffolding.cpp +++ b/beos/scaffolding.cpp @@ -22,7 +22,9 @@ #include #include #include + #include +#include #include #include #include @@ -31,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -38,6 +42,12 @@ #include #include #include + +#if defined(__HAIKU__) +#include +#include "WindowStack.h" +#endif + #include extern "C" { #include "content/content.h" @@ -320,6 +330,7 @@ void NSThrobber::SetBitmap(const BBitmap *bitmap) { fBitmap = bitmap; + Invalidate(); } @@ -458,7 +469,7 @@ NSBaseView::MessageReceived(BMessage *message) nsbeos_pipe_message_top(message, NULL, fScaffolding); break; default: - message->PrintToStream(); + //message->PrintToStream(); BView::MessageReceived(message); } } @@ -539,6 +550,7 @@ void NSBaseView::AllAttached() { BView::AllAttached(); + struct beos_scaffolding *g = fScaffolding; if (!g) return; @@ -576,6 +588,8 @@ NSBrowserWindow::NSBrowserWindow(BRect frame, struct beos_scaffolding *scaf) NSBrowserWindow::~NSBrowserWindow() { + if(activeWindow == this) + activeWindow = NULL; } @@ -621,6 +635,16 @@ NSBrowserWindow::QuitRequested(void) } +void +NSBrowserWindow::WindowActivated(bool active) +{ + if(active) + activeWindow = this; + else if(activeWindow == this) + activeWindow = NULL; +} + + // #pragma mark - implementation int32 nsbeos_replicant_main_thread(void *_arg) @@ -686,6 +710,10 @@ void nsbeos_scaffolding_update_colors(nsbeos_scaffolding *g) } +/*static*/ BWindow* +NSBrowserWindow::activeWindow = NULL; + + void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *message) { int width, height; @@ -907,6 +935,7 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m text = scaffold->url_bar->Text(); scaffold->url_bar->UnlockLooper(); + NSBrowserWindow::activeWindow = scaffold->window; browser_window_create(text.String(), bw, NULL, false, false); break; } @@ -1570,7 +1599,19 @@ void nsbeos_attach_toplevel_view(nsbeos_scaffolding *g, BView *view) message->AddPointer("scaffolding", g); g->window->AddShortcut('H', 0, message, view); + +#if defined(__HAIKU__) + // Make sure the window is layouted and answering to events, but do not + // show it before it is actually resized + g->window->Hide(); g->window->Show(); + + if(NSBrowserWindow::activeWindow) { + BWindowStack(NSBrowserWindow::activeWindow).AddWindow(g->window); + } +#endif + g->window->Show(); + } else { if (g->top_view->Looper()) g->top_view->UnlockLooper(); @@ -1659,6 +1700,97 @@ static BMenuItem *make_menu_item(const char *name, BMessage *message) return item; } + +class BBitmapButton: public BButton +{ + public: + BBitmapButton(BRect rect, const char* name, const char* label, + BMessage* message); + ~BBitmapButton(); + + void Draw(BRect updateRect); + void SetBitmap(const char* attrName); + private: + BBitmap* fBitmap; + BBitmap* fDisabledBitmap; +}; + + +BBitmapButton::BBitmapButton(BRect rect, const char* name, const char* label, + BMessage* message) + : BButton(rect, name, label, message) +{ + SetBitmap(name); +} + + +BBitmapButton::~BBitmapButton() +{ + delete fBitmap; + delete fDisabledBitmap; +} + + +void BBitmapButton::Draw(BRect updateRect) +{ + if(fBitmap == NULL) { + BButton::Draw(updateRect); + return; + } + + SetDrawingMode(B_OP_COPY); + FillRect(updateRect, B_SOLID_LOW); + rgb_color color = LowColor(); + + SetDrawingMode(B_OP_ALPHA); + if(IsEnabled()) { + if(Value() != 0) { + // button is clicked + DrawBitmap(fBitmap, BPoint(1, 1)); + } else { + // button is released + DrawBitmap(fBitmap, BPoint(0, 0)); + } + } else + DrawBitmap(fDisabledBitmap, BPoint(0, 0)); +} + + +void BBitmapButton::SetBitmap(const char* attrname) +{ +#ifdef __HAIKU__ + size_t size = 0; + const void* data = BApplication::AppResources()->LoadResource('VICN', attrname, &size); + + if (!data) { + printf("CANT LOAD RESOURCE %s\n", attrname); + return; + } + + fBitmap = new BBitmap(BRect(0, 0, 32, 32), B_RGB32); + status_t status = BIconUtils::GetVectorIcon((const uint8*)data, size, fBitmap); + + if(status != B_OK) { + fprintf(stderr, "%s > oops %s\n", attrname, strerror(status)); + delete fBitmap; + fBitmap = NULL; + } + + fDisabledBitmap = new BBitmap(fBitmap); + rgb_color* pixel = (rgb_color*)fDisabledBitmap->Bits(); + for(int i = 0; i < fDisabledBitmap->BitsLength()/4; i++) + { + *pixel = tint_color(*pixel, B_DISABLED_MARK_TINT); + pixel++; + } +#else + // No vector icon support on BeOS. We could try to load a bitmap one + fBitmap = NULL; + fDisabledBitmap = NULL; +#endif +} + + nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) { struct beos_scaffolding *g = (struct beos_scaffolding *)malloc(sizeof(*g)); @@ -1676,7 +1808,6 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) g->window = NULL; g->menu_bar = NULL; - g->window = NULL; if (replicated && !replicant_view) { warn_user("Error: No subwindow allowed when replicated.", NULL); @@ -1685,7 +1816,6 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) 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); @@ -1696,7 +1826,7 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) NSBrowserWindow *win = nsbeos_find_last_window(); if (win) { pos = win->Frame().LeftTop(); - win->Unlock(); + win->UnlockLooper(); } pos += BPoint(20, 20); BScreen screen; @@ -2038,14 +2168,13 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) 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", + g->tool_bar = new BBox(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); @@ -2054,35 +2183,35 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel) message = new BMessage('back'); message->AddPointer("scaffolding", g); - g->back_button = new BButton(rect, "back_button", "<", message); + g->back_button = new BBitmapButton(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->forward_button = new BBitmapButton(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->stop_button = new BBitmapButton(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->reload_button = new BBitmapButton(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->home_button = new BBitmapButton(rect, "home_button", "H", message); g->tool_bar->AddChild(g->home_button); nButtons++; @@ -2407,3 +2536,4 @@ void nsbeos_scaffolding_popup_menu(nsbeos_scaffolding *g, BPoint where) { g->popup_menu->Go(where); } + diff --git a/beos/scaffolding.h b/beos/scaffolding.h index ae7839175..bd13230e7 100644 --- a/beos/scaffolding.h +++ b/beos/scaffolding.h @@ -61,11 +61,15 @@ virtual ~NSBrowserWindow(); virtual void DispatchMessage(BMessage *message, BHandler *handler); virtual void MessageReceived(BMessage *message); virtual bool QuitRequested(void); +void WindowActivated(bool active); struct beos_scaffolding *Scaffolding() const { return fScaffolding; }; +static BWindow* activeWindow; private: struct beos_scaffolding *fScaffolding; + + }; diff --git a/beos/schedule.cpp b/beos/schedule.cpp index 3f822352a..db0992e63 100644 --- a/beos/schedule.cpp +++ b/beos/schedule.cpp @@ -95,8 +95,9 @@ schedule(int t, void (*callback)(void *p), void *p) cb->context = p; cb->callback_killed = cb->callback_fired = false; cb->timeout = timeout; - if (earliest_callback_timeout > timeout) + if (earliest_callback_timeout > timeout) { earliest_callback_timeout = timeout; + } callbacks->AddItem(cb); } @@ -104,11 +105,12 @@ bool schedule_run(void) { LOG(("schedule_run()")); + + earliest_callback_timeout = B_INFINITE_TIMEOUT; if (callbacks == NULL) return false; /* Nothing to do */ bigtime_t now = system_time(); - earliest_callback_timeout = B_INFINITE_TIMEOUT; int32 i; LOG(("Checking %ld callbacks to for deadline.", this_run->CountItems())); diff --git a/beos/window.cpp b/beos/window.cpp index 253b5d1c0..3e6b2f518 100644 --- a/beos/window.cpp +++ b/beos/window.cpp @@ -131,7 +131,7 @@ static GdkCursor *nsbeos_create_menu_cursor(void); NSBrowserFrameView::NSBrowserFrameView(BRect frame, struct gui_window *gui) : BView(frame, "NSBrowserFrameView", B_FOLLOW_ALL_SIDES, - B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS /*| B_SUBPIXEL_PRECISE*/), + B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS ), fGuiWindow(gui) { } @@ -250,7 +250,7 @@ NSBrowserFrameView::MessageReceived(BMessage *message) nsbeos_pipe_message_top(message, NULL, fGuiWindow->scaffold); break; default: - message->PrintToStream(); + //message->PrintToStream(); BView::MessageReceived(message); } } @@ -756,18 +756,25 @@ void nsbeos_dispatch_event(BMessage *message) break; case 'nsLO': // login { - BString url; + nsurl* url; BString realm; BString auth; - if (message->FindString("URL", &url) < B_OK) + void* cbpw; + nserror (*cb)(bool proceed, void* pw); + + if (message->FindPointer("URL", (void**)&url) < B_OK) break; if (message->FindString("Realm", &realm) < B_OK) break; if (message->FindString("Auth", &auth) < B_OK) break; + if (message->FindPointer("callback", (void**)&cb) < B_OK) + break; + if (message->FindPointer("callback_pw", (void**)&cbpw) < B_OK) + break; //printf("login to '%s' with '%s'\n", url.String(), auth.String()); - urldb_set_auth_details(url.String(), realm.String(), auth.String()); - browser_window_go(gui->bw, url.String(), 0, true); + urldb_set_auth_details(url, realm.String(), auth.String()); + cb(true, cbpw); break; } default: @@ -926,11 +933,44 @@ void nsbeos_window_keypress_event(BView *view, gui_window *g, BMessage *event) nskey = utf8_to_ucs4(bytes, numbytes); } - bool done = browser_window_key_press(g->bw, nskey); - LOG(("nskey %d %d", nskey, done)); - //if (browser_window_key_press(g->bw, nskey)) + if(browser_window_key_press(g->bw, nskey)) return; - + + // Remaining events are for scrolling the page around + float hdelta = 0.0f, vdelta = 0.0f; + g->view->LockLooper(); + BRect size = g->view->Bounds(); + switch (byte) { + case B_HOME: + g->view->ScrollTo(0.0f, 0.0f); + break; + case B_END: + { + // TODO + break; + } + case B_PAGE_UP: + vdelta = -size.Height(); + break; + case B_PAGE_DOWN: + vdelta = size.Height(); + break; + case B_LEFT_ARROW: + hdelta = -10; + break; + case B_RIGHT_ARROW: + hdelta = 10; + break; + case B_UP_ARROW: + vdelta = -10; + break; + case B_DOWN_ARROW: + vdelta = 10; + break; + } + + g->view->ScrollBy(hdelta, vdelta); + g->view->UnlockLooper(); } #warning WRITEME @@ -1674,7 +1714,7 @@ bool gui_add_to_clipboard(const char *text, size_t length, bool space, BFont font; text_run *run = new text_run; - nsbeos_style_to_font(font, &fstyle); + nsbeos_style_to_font(font, fstyle); run->offset = current_selection.Length(); run->font = font; run->color = nsbeos_rgb_colour(fstyle->foreground); diff --git a/utils/config.h b/utils/config.h index bd2e3035e..1c1eef6c4 100644 --- a/utils/config.h +++ b/utils/config.h @@ -24,14 +24,14 @@ /* Try to detect which features the target OS supports */ -#if (defined(_GNU_SOURCE) && !defined(__APPLE__)) +#if (defined(_GNU_SOURCE) && !defined(__APPLE__) || defined(__HAIKU__)) #define HAVE_STRNDUP #else #undef HAVE_STRNDUP char *strndup(const char *s, size_t n); #endif -#if (defined(_GNU_SOURCE) || defined(__APPLE__)) +#if (defined(_GNU_SOURCE) || defined(__APPLE__) || defined(__HAIKU__)) #define HAVE_STRCASESTR #else #undef HAVE_STRCASESTR