summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2011-09-19 21:33:52 +0200
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2011-09-19 21:33:52 +0200
commitabd446c2eebe1f96764b6d95f1c6c61ae9bc40b2 (patch)
treeb313bbeebf50fd53369d303824edab57aa69d016 /src
parentb0b0cddaff10b4cff371b8bb7aa21e045f8e3915 (diff)
parent0caf22a3f7c33578a073cee42c6cfa61f971bc42 (diff)
merge
Diffstat (limited to 'src')
-rw-r--r--src/IO/Url.h3
-rw-r--r--src/IO/about.c83
-rw-r--r--src/IO/http.c10
-rw-r--r--src/IO/iowatch.cc12
-rw-r--r--src/IO/iowatch.hh2
-rw-r--r--src/Makefile.am3
-rw-r--r--src/auth.c4
-rw-r--r--src/bw.c25
-rw-r--r--src/bw.h12
-rw-r--r--src/cache.c34
-rw-r--r--src/capi.c35
-rw-r--r--src/chain.c5
-rw-r--r--src/cookies.c21
-rw-r--r--src/cookies.h5
-rw-r--r--src/css.cc49
-rw-r--r--src/css.hh6
-rw-r--r--src/cssparser.cc22
-rw-r--r--src/cssparser.hh5
-rw-r--r--src/dialog.cc379
-rw-r--r--src/dialog.hh2
-rw-r--r--src/dillo.cc94
-rw-r--r--src/dns.h2
-rw-r--r--src/doctree.hh63
-rw-r--r--src/findbar.cc164
-rw-r--r--src/findbar.hh33
-rw-r--r--src/form.cc10
-rw-r--r--src/gif.c5
-rw-r--r--src/html.cc110
-rw-r--r--src/keys.cc192
-rw-r--r--src/keys.hh3
-rw-r--r--src/keysrc22
-rw-r--r--src/menu.cc558
-rw-r--r--src/menu.hh4
-rw-r--r--src/misc.c34
-rw-r--r--src/misc.h1
-rw-r--r--src/nav.c45
-rw-r--r--src/pixmaps.h32
-rw-r--r--src/prefs.c18
-rw-r--r--src/prefs.h8
-rw-r--r--src/prefsparser.cc30
-rw-r--r--src/styleengine.cc23
-rw-r--r--src/styleengine.hh1
-rw-r--r--src/table.cc9
-rw-r--r--src/timeout.cc9
-rw-r--r--src/ui.cc1010
-rw-r--r--src/ui.hh192
-rw-r--r--src/uicmd.cc894
-rw-r--r--src/uicmd.hh12
-rw-r--r--src/url.c19
-rw-r--r--src/url.h24
-rw-r--r--src/utf8.cc13
-rw-r--r--src/utf8.hh1
-rw-r--r--src/web.cc12
-rw-r--r--src/web.hh3
-rw-r--r--src/xembed.cc65
-rw-r--r--src/xembed.hh8
56 files changed, 2391 insertions, 2049 deletions
diff --git a/src/IO/Url.h b/src/IO/Url.h
index 95919f11..15934e13 100644
--- a/src/IO/Url.h
+++ b/src/IO/Url.h
@@ -18,7 +18,8 @@ int a_Http_proxy_auth(void);
void a_Http_set_proxy_passwd(const char *str);
char *a_Http_make_connect_str(const DilloUrl *url);
const char *a_Http_get_proxy_urlstr();
-Dstr *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy);
+Dstr *a_Http_make_query_str(const DilloUrl *url, const DilloUrl *requester,
+ bool_t use_proxy);
void a_Http_ccc (int Op, int Branch, int Dir, ChainLink *Info,
void *Data1, void *Data2);
diff --git a/src/IO/about.c b/src/IO/about.c
index 508bfd11..77af318f 100644
--- a/src/IO/about.c
+++ b/src/IO/about.c
@@ -61,7 +61,7 @@ const char *const AboutSplash=
" <table border='0' cellspacing='0' cellpadding='2'><tr>\n"
" <td>\n"
" <td>\n"
-" <a href='http://www.dillo.org/dillo2-help.html'>\n"
+" <a href='http://www.dillo.org/dillo3-help.html'>\n"
" Help</a>\n"
" <tr>\n"
" <td>&nbsp;&nbsp;\n"
@@ -153,12 +153,6 @@ const char *const AboutSplash=
" <table border='0' cellspacing='0' cellpadding='5'><tr><td>\n"
" <table border='0' cellpadding='2'><tr>\n"
" <td>&nbsp;&nbsp;\n"
-" <td><a href='http://www.google.com/'>Google</a>\n"
-" <tr>\n"
-" <td>&nbsp;&nbsp;\n"
-" <td><a href='http://www.wikipedia.org/'>Wikipedia</a>\n"
-" <tr>\n"
-" <td>&nbsp;&nbsp;\n"
" <td><a href='http://www.gutenberg.org/'>P.&nbsp;Gutenberg</a>\n"
" <tr>\n"
" <td>&nbsp;&nbsp;\n"
@@ -240,20 +234,27 @@ const char *const AboutSplash=
"<tr>\n"
" <td bgcolor='#CCCCCC'>\n"
" <h4>Release overview</h4>\n"
-" February 11, 2010\n"
+" September 06, 2011\n"
"<tr>\n"
" <td bgcolor='#FFFFFF'>\n"
" <table border='0' cellspacing='0' cellpadding='5'>\n"
" <tr>\n"
" <td>\n"
"<p>\n"
-"This release features a major overhaul of the cookies subsystem,\n"
-"a reimplementation of the DPI API, a configurable connection limit,\n"
-"and various CSS improvements.\n"
+"Dillo-3.0 is a port to FLTK-1.3, which is big news because FLTK-1.3.0 was\n"
+"<a href='http://fltk.org/articles.php?L1086'>released</a>\n"
+"in June, clearing the way for Dillo to return to those distributions\n"
+"which had excluded Dillo2 due to FLTK2 never being officially released.\n"
+"<p>\n"
+"Dillo-3.0 also has plenty of improvements and bugfixes.\n"
+"<p>\n"
+"After this release, the core team will focus on implementing the CSS\n"
+"feature of floating elements. This will <em>greatly</em> improve dillo's\n"
+"web page rendering since many sites have adopted floats instead of tables.\n"
+"<p>\n"
+"The new dillo3 has shown excellent stability in our experience.\n"
+"The core team welcomes developers willing to join our workforce.\n"
"<p>\n"
-"Remember that the dillo project uses a release model where every new\n"
-"version shall be better than the last.\n"
-"<EM>Keep up with the latest one!</EM>\n"
" </table>\n"
"</table>\n"
"</table>\n"
@@ -274,27 +275,39 @@ const char *const AboutSplash=
" <tr>\n"
" <td>\n"
"<ul>\n"
-"<li>Added keybindings for scrolling.\n"
-"<li>Help button and local help file.\n"
-"<li>Add support for multiple class names in CSS.\n"
-"<li>Fix X11 coordinate overflows.\n"
-"<li>Improve CSS font parsing.\n"
-"<li>Enable font face setting via &lt;font&gt; element.\n"
-"<li>Ignore XML comment markers in CSS.\n"
-"<li>Fix user agent style for nested &lt;ul&gt;.\n"
-"<li>Handle signed chars. Added dIsspace() and dIsalnum() to dlib.\n"
-"<li>Changed the CCCs to build in one step (for both HTTP and DPI).\n"
-"<li>Remove the empty cache entry lingering after connection abort.\n"
-"<li>Fixed URL unescaping in the datauri DPI.\n"
-"<li>Changed and reimplemented the DPI API.\n"
-"<li>Allow linebreaks around Chinese/Japanese characters.\n"
-"<li>Fix scrolling for text search.\n"
-"<li>Tooltips.\n"
-"<li>Enable popup menu below bottom of page content.\n"
-"<li>Handle JPEGs with CMYK color space.\n"
-"<li>General cookies overhaul.\n"
-"<li>Fixed a bug in w3c_mode.\n"
-"<li>Limit number of simultaneous connections.\n"
+"<li>Ported Dillo to FLTK-1.3.\n"
+"<li>Native build on OSX.\n"
+"<li>Default binding for close-all changed from Alt-q to Ctrl-q.\n"
+"<li>Default binding for close-tab changed from Ctrl-q to Ctrl-w.\n"
+"<li>Default binding for left-tab changed to Shift-Ctrl-Tab.\n"
+"<li>Rewrote the User Interface: much simpler design and event handling.\n"
+"<li>Added on-the-fly panel resize (tiny/small/medium and normal/small icons).\n"
+"<li>'hide-panels' key action now hides the findbar if present,\n"
+" and toggles display of the control panels otherwise.\n"
+"<li>Allow multiple search engines to be set in dillorc, with a menu\n"
+" in the web search dialog to select between them.\n"
+"<li>Added an optional label to dillorc's search_url.\n"
+" Format: \"[&lt;label&gt; ]&lt;url&gt;\"\n"
+"<li>Add right_click_closes_tab preference (default is middle click).\n"
+"<li>Allow binding to non-ASCII keys and multimedia keys.\n"
+"<li>Avoid a certificate dialog storm on some HTTPS sites (BUG#868).\n"
+"<li>Enable line wrapping for &lt;textarea&gt;. (BUG#903)\n"
+"<li>Avoid double render after going Back or Forward\n"
+" (it takes half the time now!)\n"
+"<li>Implemented a custom tabs handler (to allow fine control of it).\n"
+"<li>Rewrote dw's crossing-events dispatcher (avoids redundant events).\n"
+"<li>Fixed a years old bug: stamped tooltips when scrolling with keyboard.\n"
+"<li>Fixed a border case in URL resolver: empty path + {query|fragment}\n"
+" (BUG#948)\n"
+"<li>Cancel the expected URL after offering a download (BUG#982)\n"
+"<li>Eliminated a pack of 22 compiler warnings (gcc-4.6.1 amd64)\n"
+"<li>Removed 'large' option of panel_size preference.\n"
+"<li>Removed --enable-ansi configure option.\n"
+"<li>Limit saved cookie size.\n"
+"<li>Wrap image alt text.\n"
+"<li>Added support for CSS adjacent sibling selectors.\n"
+"<li>Fix redraw loops and reenabled limit_text_width dillorc option.\n"
+"<li>Collapse parent's and first child's top margin.\n"
"</ul>\n"
" </table>\n"
"</table>\n"
diff --git a/src/IO/http.c b/src/IO/http.c
index 77a1be43..41ee137a 100644
--- a/src/IO/http.c
+++ b/src/IO/http.c
@@ -174,7 +174,7 @@ static void Http_connect_queued_sockets(HostConnection_t *hc)
MSG_BW(sd->web, 1, "ERROR: %s", dStrerror(sd->Err));
a_Chain_bfcb(OpAbort, sd->Info, NULL, "Both");
dFree(sd->Info);
- Http_socket_free((int) sd->Info->LocalKey);
+ Http_socket_free(VOIDP2INT(sd->Info->LocalKey));
} else {
sd->connected_to = hc->host;
hc->active_connections++;
@@ -271,7 +271,8 @@ static Dstr *Http_make_content_type(const DilloUrl *url)
/*
* Make the http query string
*/
-Dstr *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy)
+Dstr *a_Http_make_query_str(const DilloUrl *url, const DilloUrl *requester,
+ bool_t use_proxy)
{
const char *auth;
char *ptr, *cookies, *referer;
@@ -296,7 +297,7 @@ Dstr *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy)
(URL_PATH_(url) || URL_QUERY_(url)) ? "" : "/");
}
- cookies = a_Cookies_get_query(url);
+ cookies = a_Cookies_get_query(url, requester);
auth = a_Auth_get_auth_str(url);
referer = Http_get_referer(url);
if (URL_FLAGS(url) & URL_Post) {
@@ -365,7 +366,8 @@ static void Http_send_query(ChainLink *Info, SocketData_t *S)
DataBuf *dbuf;
/* Create the query */
- query = a_Http_make_query_str(S->web->url, S->flags & HTTP_SOCKET_USE_PROXY);
+ query = a_Http_make_query_str(S->web->url, S->web->requester,
+ S->flags & HTTP_SOCKET_USE_PROXY);
dbuf = a_Chain_dbuf_new(query->str, query->len, 0);
/* actually this message is sent too early.
diff --git a/src/IO/iowatch.cc b/src/IO/iowatch.cc
index f67b711f..f5243934 100644
--- a/src/IO/iowatch.cc
+++ b/src/IO/iowatch.cc
@@ -11,19 +11,17 @@
// Simple ADT for watching file descriptor activity
-#include <fltk/run.h>
+#include <FL/Fl.H>
#include "iowatch.hh"
-using namespace fltk;
-
-
//
// Hook a Callback for a certain activities in a FD
//
-void a_IOwatch_add_fd(int fd, int when, FileHandler Callback, void *usr_data=0)
+void a_IOwatch_add_fd(int fd, int when, Fl_FD_Handler Callback,
+ void *usr_data = 0)
{
if (fd >= 0)
- add_fd(fd, when, Callback, usr_data);
+ Fl::add_fd(fd, when, Callback, usr_data);
}
//
@@ -32,6 +30,6 @@ void a_IOwatch_add_fd(int fd, int when, FileHandler Callback, void *usr_data=0)
void a_IOwatch_remove_fd(int fd, int when)
{
if (fd >= 0)
- remove_fd(fd, when);
+ Fl::remove_fd(fd, when);
}
diff --git a/src/IO/iowatch.hh b/src/IO/iowatch.hh
index 681d0080..e2d497f1 100644
--- a/src/IO/iowatch.hh
+++ b/src/IO/iowatch.hh
@@ -2,7 +2,7 @@
#define __IO_WATCH_H__
/*
- * BUG: enum {READ = 1, WRITE = 4, EXCEPT = 8} borrowed from fltk/run.h
+ * BUG: enum {READ = 1, WRITE = 4, EXCEPT = 8} borrowed from FL/Enumerations.H
*/
#define DIO_READ 1
#define DIO_WRITE 4
diff --git a/src/Makefile.am b/src/Makefile.am
index 0f09b716..9de7eed5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,8 @@ dillo_LDADD = \
$(top_builddir)/dw/libDw-fltk.a \
$(top_builddir)/dw/libDw-core.a \
$(top_builddir)/lout/liblout.a \
- @LIBJPEG_LIBS@ @LIBPNG_LIBS@ @LIBFLTK_LIBS@ @LIBZ_LIBS@ @LIBICONV_LIBS@
+ @LIBJPEG_LIBS@ @LIBPNG_LIBS@ @LIBFLTK_LIBS@ @LIBZ_LIBS@ \
+ @LIBICONV_LIBS@ @LIBPTHREAD_LIBS@
dillo_SOURCES = \
dillo.cc \
diff --git a/src/auth.c b/src/auth.c
index 91baca30..8943c3fd 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -486,8 +486,8 @@ static int Auth_do_auth_dialog(const char *realm, const DilloUrl *url)
AuthDialogData_t *data;
_MSG("auth.c: Auth_do_auth_dialog: realm = '%s'\n", realm);
- message = dStrconcat("Enter a user and password for \"",
- realm, "\".", NULL);
+ message = dStrconcat("The server at ", URL_HOST(url), " requires a username"
+ " and password for \"", realm, "\".", NULL);
data = dNew(AuthDialogData_t, 1);
data->realm_name = dStrdup(realm);
data->url = a_Url_dup(url);
diff --git a/src/bw.c b/src/bw.c
index 7f4785bb..1dfc5a08 100644
--- a/src/bw.c
+++ b/src/bw.c
@@ -55,7 +55,6 @@ BrowserWindow *a_Bw_new()
bw->nav_stack_ptr = -1;
/* Init expect */
- bw->nav_expecting = FALSE;
bw->nav_expect_url = NULL;
bw->redirect_level = 0;
@@ -313,3 +312,27 @@ BrowserWindow *a_Bw_get(int i)
return NULL;
}
+/* expect API ------------------------------------------------------------- */
+
+void a_Bw_expect(BrowserWindow *bw, const DilloUrl *url)
+{
+ a_Url_free(bw->nav_expect_url);
+ bw->nav_expect_url = a_Url_dup(url);
+}
+
+void a_Bw_cancel_expect(BrowserWindow *bw)
+{
+ a_Url_free(bw->nav_expect_url);
+ bw->nav_expect_url = NULL;
+}
+
+bool_t a_Bw_expecting(BrowserWindow *bw)
+{
+ return (bw->nav_expect_url != NULL);
+}
+
+const DilloUrl *a_Bw_expected_url(BrowserWindow *bw)
+{
+ return bw->nav_expect_url;
+}
+
diff --git a/src/bw.h b/src/bw.h
index 4b915b5c..590af4fb 100644
--- a/src/bw.h
+++ b/src/bw.h
@@ -46,12 +46,9 @@ struct _BrowserWindow
/* 'nav_stack_ptr' refers to what's being displayed */
int nav_stack_ptr; /* [0 based; -1 = empty] */
/* When the user clicks a link, the URL isn't pushed directly to history;
- * nav_expect_url holds it until the first answer-bytes are got. Only then
- * it is sent to history and referenced at the top of nav_stack */
+ * nav_expect_url holds it until a dw is assigned to it. Only then an entry
+ * is made in history and referenced at the top of nav_stack */
DilloUrl *nav_expect_url;
- /* 'nav_expecting' is true while dillo waits for non-cached URL data,
- * until a dw is assigned to it. */
- bool_t nav_expecting;
/* Counter for the number of hops on a redirection. Used to stop
* redirection loops (accounts for WEB_RootUrl only) */
@@ -88,6 +85,11 @@ void *a_Bw_get_url_doc(BrowserWindow *bw, const DilloUrl *Url);
void a_Bw_remove_doc(BrowserWindow *bw, void *vdoc);
void a_Bw_add_url(BrowserWindow *bw, const DilloUrl *Url);
void a_Bw_cleanup(BrowserWindow *bw);
+/* expect API */
+void a_Bw_expect(BrowserWindow *bw, const DilloUrl *Url);
+void a_Bw_cancel_expect(BrowserWindow *bw);
+bool_t a_Bw_expecting(BrowserWindow *bw);
+const DilloUrl *a_Bw_expected_url(BrowserWindow *bw);
typedef void (*BwCallback_t)(BrowserWindow *bw, const void *data);
diff --git a/src/cache.c b/src/cache.c
index d26ae610..6094a8d5 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -742,13 +742,29 @@ static void Cache_parse_header(CacheEntry_t *entry)
#ifndef DISABLE_COOKIES
if ((Cookies = Cache_parse_multiple_fields(header, "Set-Cookie"))) {
- char *server_date = Cache_parse_field(header, "Date");
+ CacheClient_t *client;
+
+ for (i = 0; (client = dList_nth_data(ClientQueue, i)); ++i) {
+ if (client->Url == entry->Url) {
+ DilloWeb *web = client->Web;
+
+ if (!web->requester ||
+ a_Url_same_organization(entry->Url, web->requester)) {
+ char *server_date = Cache_parse_field(header, "Date");
+
+ a_Cookies_set(Cookies, entry->Url, server_date);
+ dFree(server_date);
+ break;
+ }
+ }
+ }
+ if (i >= dList_length(ClientQueue)) {
+ MSG("Cache: cookies not accepted from '%s'\n", URL_STR(entry->Url));
+ }
- a_Cookies_set(Cookies, entry->Url, server_date);
for (i = 0; (data = dList_nth_data(Cookies, i)); ++i)
dFree(data);
dList_free(Cookies);
- dFree(server_date);
}
#endif /* !DISABLE_COOKIES */
@@ -893,6 +909,16 @@ void a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
MSG("entry->ExpectedSize = %d, entry->TransferSize = %d\n",
entry->ExpectedSize, entry->TransferSize);
}
+ if (!entry->TransferSize && !(entry->Flags & CA_Redirect) &&
+ (entry->Flags & WEB_RootUrl)) {
+ char *eol = strchr(entry->Header->str, '\n');
+ if (eol) {
+ char *status_line = dStrndup(entry->Header->str,
+ eol - entry->Header->str);
+ MSG_HTTP("Body was empty. Server sent status: %s\n", status_line);
+ dFree(status_line);
+ }
+ }
entry->Flags |= CA_GotData;
entry->Flags &= ~CA_Stopped; /* it may catch up! */
if (entry->TransferDecoder) {
@@ -1166,6 +1192,8 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
}
}
if (AbortEntry) {
+ if (ClientWeb->flags & WEB_RootUrl)
+ a_Nav_cancel_expect_if_eq(Client_bw, Client->Url);
a_Bw_remove_client(Client_bw, Client->Key);
Cache_client_dequeue(Client, NULLKey);
--i; /* Keep the index value in the next iteration */
diff --git a/src/capi.c b/src/capi.c
index 5e2928e3..bcec07bf 100644
--- a/src/capi.c
+++ b/src/capi.c
@@ -300,17 +300,26 @@ static char *Capi_dpi_build_cmd(DilloWeb *web, char *server)
if (strcmp(server, "proto.https") == 0) {
/* Let's be kind and make the HTTP query string for the dpi */
char *proxy_connect = a_Http_make_connect_str(web->url);
- Dstr *http_query = a_Http_make_query_str(web->url, FALSE);
+ Dstr *http_query = a_Http_make_query_str(web->url, web->requester,FALSE);
/* BUG: embedded NULLs in query data will truncate message */
+
+ /* BUG: WORKAROUND: request to only check the root URL's certificate.
+ * This avoids the dialog bombing that stems from loading multiple
+ * https images/resources in a single page. A proper fix would take
+ * either to implement the https-dpi as a server (with state),
+ * or to move back https handling into dillo. */
if (proxy_connect) {
const char *proxy_urlstr = a_Http_get_proxy_urlstr();
cmd = a_Dpip_build_cmd("cmd=%s proxy_url=%s proxy_connect=%s "
- "url=%s query=%s", "open_url", proxy_urlstr,
+ "url=%s query=%s check_cert=%s",
+ "open_url", proxy_urlstr,
proxy_connect, URL_STR(web->url),
- http_query->str);
+ http_query->str,
+ (web->flags & WEB_RootUrl) ? "true" : "false");
} else {
- cmd = a_Dpip_build_cmd("cmd=%s url=%s query=%s",
- "open_url", URL_STR(web->url),http_query->str);
+ cmd = a_Dpip_build_cmd("cmd=%s url=%s query=%s check_cert=%s",
+ "open_url", URL_STR(web->url),http_query->str,
+ (web->flags & WEB_RootUrl) ? "true" : "false");
}
dFree(proxy_connect);
dStr_free(http_query, 1);
@@ -376,9 +385,7 @@ static bool_t Capi_filters_test(const DilloUrl *wanted,
case PREFS_FILTER_SAME_DOMAIN:
{
const char *req_host = URL_HOST(requester),
- *want_host = URL_HOST(wanted),
- *req_suffix,
- *want_suffix;
+ *want_host = URL_HOST(wanted);
if (want_host[0] == '\0') {
ret = (req_host[0] == '\0' ||
!dStrcasecmp(URL_SCHEME(wanted), "data")) ? TRUE : FALSE;
@@ -386,14 +393,12 @@ static bool_t Capi_filters_test(const DilloUrl *wanted,
/* This will regard "www.dillo.org" and "www.dillo.org." as
* different, but it doesn't seem worth caring about.
*/
- req_suffix = a_Url_host_find_public_suffix(req_host);
- want_suffix = a_Url_host_find_public_suffix(want_host);
-
- ret = dStrcasecmp(req_suffix, want_suffix) == 0;
+ ret = a_Url_same_organization(wanted, requester);
+ }
+ if (ret == FALSE) {
+ MSG("Capi_filters_test: deny from '%s' to '%s'\n", req_host,
+ want_host);
}
-
- MSG("Capi_filters_test: %s from '%s' to '%s'\n",
- ret ? "ALLOW" : "DENY", req_host, want_host);
break;
}
case PREFS_FILTER_ALLOW_ALL:
diff --git a/src/chain.c b/src/chain.c
index d4098a2d..a13b3120 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -22,7 +22,7 @@
*/
#if VERBOSE
static void Chain_debug_msg(char *FuncStr, int Op, int Branch, int Dir,
- ChainLink *Info)
+ ChainLink *Info)
{
const char *StrOps[] = {"", "OpStart", "OpSend",
"OpStop", "OpEnd", "OpAbort"};
@@ -31,7 +31,8 @@ static void Chain_debug_msg(char *FuncStr, int Op, int Branch, int Dir,
Info, Info ? Info->Flags : -1);
}
#else
-static void Chain_debug_msg() { }
+static void Chain_debug_msg(char *FuncStr, int Op, int Branch, int Dir,
+ ChainLink *Info) { }
#endif
/*
* Create and initialize a new chain-link
diff --git a/src/cookies.c b/src/cookies.c
index 7b9062e2..d1451dc1 100644
--- a/src/cookies.c
+++ b/src/cookies.c
@@ -179,7 +179,7 @@ void a_Cookies_set(Dlist *cookie_strings, const DilloUrl *set_url,
/*
* Return a string containing cookie data for an HTTP query.
*/
-char *a_Cookies_get_query(const DilloUrl *request_url)
+char *a_Cookies_get_query(const DilloUrl *query_url, const DilloUrl *requester)
{
char *cmd, *dpip_tag, *query;
const char *path;
@@ -188,16 +188,25 @@ char *a_Cookies_get_query(const DilloUrl *request_url)
if (disabled)
return dStrdup("");
- action = Cookies_control_check(request_url);
+ action = Cookies_control_check(query_url);
if (action == COOKIE_DENY) {
- _MSG("Cookies: denied GET for %s\n", URL_HOST_(request_url));
+ _MSG("Cookies: denied GET for %s\n", URL_HOST_(query_url));
return dStrdup("");
}
- path = URL_PATH_(request_url);
+
+ if (requester == NULL) {
+ /* request made by user */
+ } else if (!a_Url_same_organization(query_url, requester)) {
+ MSG("Cookies: No cookies sent for third-party request by '%s' for "
+ "'%s'\n", URL_HOST(requester), URL_STR(query_url));
+ return dStrdup("");
+ }
+
+ path = URL_PATH_(query_url);
cmd = a_Dpip_build_cmd("cmd=%s scheme=%s host=%s path=%s",
- "get_cookie", URL_SCHEME(request_url),
- URL_HOST(request_url), path ? path : "/");
+ "get_cookie", URL_SCHEME(query_url),
+ URL_HOST(query_url), path ? path : "/");
/* Get the answer from cookies.dpi */
_MSG("cookies.c: a_Dpi_send_blocking_cmd cmd = {%s}\n", cmd);
diff --git a/src/cookies.h b/src/cookies.h
index d6ee1ccd..1cdb82ac 100644
--- a/src/cookies.h
+++ b/src/cookies.h
@@ -7,12 +7,13 @@ extern "C" {
#ifdef DISABLE_COOKIES
-# define a_Cookies_get_query(url) dStrdup("")
+# define a_Cookies_get_query(url, requester) dStrdup("")
# define a_Cookies_set() ;
# define a_Cookies_init() ;
# define a_Cookies_freeall() ;
#else
- char *a_Cookies_get_query(const DilloUrl *request_url);
+ char *a_Cookies_get_query(const DilloUrl *query_url,
+ const DilloUrl *requester);
void a_Cookies_set(Dlist *cookie_string, const DilloUrl *set_url,
const char *server_date);
void a_Cookies_init( void );
diff --git a/src/css.cc b/src/css.cc
index cb0864fd..a1d51da1 100644
--- a/src/css.cc
+++ b/src/css.cc
@@ -104,6 +104,7 @@ CssSelector::CssSelector () {
cs = selectorList->getRef (selectorList->size () - 1);
cs->notMatchingBefore = -1;
+ cs->combinator = CHILD;
cs->selector = new CssSimpleSelector ();
};
@@ -133,6 +134,7 @@ bool CssSelector::match (Doctree *docTree, const DoctreeNode *node) {
switch (comb) {
case CHILD:
+ case ADJACENT_SIBLING:
if (!sel->match (node))
return false;
break;
@@ -156,7 +158,11 @@ bool CssSelector::match (Doctree *docTree, const DoctreeNode *node) {
}
comb = cs->combinator;
- node = docTree->parent (node);
+
+ if (comb == ADJACENT_SIBLING)
+ node = docTree->sibling (node);
+ else
+ node = docTree->parent (node);
}
return true;
@@ -200,6 +206,9 @@ void CssSelector::print () {
case DESCENDANT:
fprintf (stderr, "\" \" ");
break;
+ case ADJACENT_SIBLING:
+ fprintf (stderr, "+ ");
+ break;
default:
fprintf (stderr, "? ");
break;
@@ -489,39 +498,21 @@ void CssStyleSheet::apply (CssPropertyList *props,
}
}
-CssStyleSheet *CssContext::userAgentStyle;
-CssStyleSheet *CssContext::userStyle;
-CssStyleSheet *CssContext::userImportantStyle;
-
CssContext::CssContext () {
pos = 0;
- for (int o = CSS_PRIMARY_USER_AGENT; o < CSS_PRIMARY_LAST; o++)
- sheet[o] = NULL;
-
- if (userAgentStyle == NULL) {
- userAgentStyle = new CssStyleSheet ();
- userStyle = new CssStyleSheet ();
- userImportantStyle = new CssStyleSheet ();
+ memset (sheet, 0, sizeof(sheet));
+ sheet[CSS_PRIMARY_USER_AGENT] = new CssStyleSheet ();
+ sheet[CSS_PRIMARY_USER] = new CssStyleSheet ();
+ sheet[CSS_PRIMARY_USER_IMPORTANT] = new CssStyleSheet ();
- sheet[CSS_PRIMARY_USER_AGENT] = userAgentStyle;
- sheet[CSS_PRIMARY_USER] = userStyle;
- sheet[CSS_PRIMARY_USER_IMPORTANT] = userImportantStyle;
-
- buildUserAgentStyle ();
- buildUserStyle ();
- }
-
- sheet[CSS_PRIMARY_USER_AGENT] = userAgentStyle;
- sheet[CSS_PRIMARY_USER] = userStyle;
- sheet[CSS_PRIMARY_USER_IMPORTANT] = userImportantStyle;
+ buildUserAgentStyle ();
+ buildUserStyle ();
}
CssContext::~CssContext () {
for (int o = CSS_PRIMARY_USER_AGENT; o < CSS_PRIMARY_LAST; o++)
- if (sheet[o] != userAgentStyle && sheet[o] != userStyle &&
- sheet[o] != userImportantStyle)
- delete sheet[o];
+ delete sheet[o];
}
/**
@@ -535,7 +526,8 @@ CssContext::~CssContext () {
*/
void CssContext::apply (CssPropertyList *props, Doctree *docTree,
DoctreeNode *node,
- CssPropertyList *tagStyle, CssPropertyList *nonCssHints) {
+ CssPropertyList *tagStyle, CssPropertyList *tagStyleImportant,
+ CssPropertyList *nonCssHints) {
if (sheet[CSS_PRIMARY_USER_AGENT])
sheet[CSS_PRIMARY_USER_AGENT]->apply (props, docTree, node);
@@ -554,6 +546,9 @@ void CssContext::apply (CssPropertyList *props, Doctree *docTree,
if (sheet[CSS_PRIMARY_AUTHOR_IMPORTANT])
sheet[CSS_PRIMARY_AUTHOR_IMPORTANT]->apply (props, docTree, node);
+ if (tagStyleImportant)
+ tagStyleImportant->apply (props);
+
if (sheet[CSS_PRIMARY_USER_IMPORTANT])
sheet[CSS_PRIMARY_USER_IMPORTANT]->apply (props, docTree, node);
}
diff --git a/src/css.hh b/src/css.hh
index bf7d3c1d..20935dfd 100644
--- a/src/css.hh
+++ b/src/css.hh
@@ -458,9 +458,6 @@ class CssStyleSheet {
*/
class CssContext {
private:
- static CssStyleSheet *userAgentStyle;
- static CssStyleSheet *userStyle;
- static CssStyleSheet *userImportantStyle;
CssStyleSheet *sheet[CSS_PRIMARY_USER_IMPORTANT + 1];
int pos;
@@ -475,7 +472,8 @@ class CssContext {
CssPrimaryOrder order);
void apply (CssPropertyList *props,
Doctree *docTree, DoctreeNode *node,
- CssPropertyList *tagStyle, CssPropertyList *nonCssHints);
+ CssPropertyList *tagStyle, CssPropertyList *tagStyleImportant,
+ CssPropertyList *nonCssHints);
};
#endif
diff --git a/src/cssparser.cc b/src/cssparser.cc
index 7b522c8c..f6e60731 100644
--- a/src/cssparser.cc
+++ b/src/cssparser.cc
@@ -1053,7 +1053,7 @@ void CssParser::parseDeclaration(CssPropertyList * props,
CssPropertyList * importantProps)
{
CssPropertyInfo pi = {NULL, {CSS_TYPE_UNUSED}, NULL}, *pip;
- CssShorthandInfo si, *sip;
+ CssShorthandInfo *sip;
CssValueType type = CSS_TYPE_UNUSED;
CssPropertyName prop;
@@ -1091,7 +1091,6 @@ void CssParser::parseDeclaration(CssPropertyList * props,
}
} else {
/* Try shorthands. */
- si.symbol = tval;
sip =
(CssShorthandInfo *) bsearch(&pi, Css_shorthand_info,
CSS_SHORTHAND_NUM,
@@ -1294,6 +1293,9 @@ CssSelector *CssParser::parseSelector()
} else if (ttype == CSS_TK_CHAR && tval[0] == '>') {
selector->addSimpleSelector (CssSelector::CHILD);
nextToken();
+ } else if (ttype == CSS_TK_CHAR && tval[0] == '+') {
+ selector->addSimpleSelector (CssSelector::ADJACENT_SIBLING);
+ nextToken();
} else if (ttype != CSS_TK_END && spaceSeparated) {
selector->addSimpleSelector (CssSelector::DESCENDANT);
} else {
@@ -1526,7 +1528,7 @@ const char * CssParser::propertyNameString(CssPropertyName name)
{
return Css_property_info[name].symbol;
}
-
+
void CssParser::ignoreBlock()
{
int depth = 0;
@@ -1594,22 +1596,16 @@ void CssParser::parse(DilloHtml *html, DilloUrl *url, CssContext * context,
}
}
-CssPropertyList *CssParser::parseDeclarationBlock(const char *buf, int buflen)
+void CssParser::parseDeclarationBlock(const char *buf, int buflen,
+ CssPropertyList *props,
+ CssPropertyList *propsImortant)
{
- CssPropertyList *props = new CssPropertyList (true);
CssParser parser (NULL, CSS_ORIGIN_AUTHOR, buf, buflen);
parser.withinBlock = true;
do
- parser.parseDeclaration(props, NULL);
+ parser.parseDeclaration(props, propsImortant);
while (!(parser.ttype == CSS_TK_END ||
(parser.ttype == CSS_TK_CHAR && parser.tval[0] == '}')));
-
- if (props->size () == 0) {
- delete props;
- props = NULL;
- }
-
- return props;
}
diff --git a/src/cssparser.hh b/src/cssparser.hh
index 1542405d..8609877b 100644
--- a/src/cssparser.hh
+++ b/src/cssparser.hh
@@ -47,8 +47,9 @@ class CssParser {
void ignoreStatement();
public:
- static CssPropertyList *parseDeclarationBlock(const char *buf,
- int buflen);
+ static void parseDeclarationBlock(const char *buf, int buflen,
+ CssPropertyList *props,
+ CssPropertyList *propsImortant);
static void parse(DilloHtml *html, DilloUrl *url, CssContext *context,
const char *buf, int buflen, CssOrigin origin);
static const char *propertyNameString(CssPropertyName name);
diff --git a/src/dialog.cc b/src/dialog.cc
index 47af9921..15e5d7a9 100644
--- a/src/dialog.cc
+++ b/src/dialog.cc
@@ -13,58 +13,192 @@
#include <math.h> // for rint()
-#include <fltk/Window.h>
-#include <fltk/ask.h>
-#include <fltk/file_chooser.h>
-#include <fltk/TextBuffer.h>
-#include <fltk/ReturnButton.h>
-#include <fltk/TextDisplay.h>
-#include <fltk/HighlightButton.h>
-#include <fltk/WordwrapOutput.h>
-#include <fltk/Input.h>
-#include <fltk/SecretInput.h>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_File_Chooser.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Text_Display.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Return_Button.H>
+#include <FL/Fl_Output.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Secret_Input.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Menu_Item.H>
#include "msg.h"
#include "dialog.hh"
#include "misc.h"
#include "prefs.h"
-using namespace fltk;
+/*
+ * Local Data
+ */
+static int input_answer;
+static char *input_str = NULL;
+static int choice5_answer;
+
+
+/*
+ * Local sub classes
+ */
+//----------------------------------------------------------------------------
/*
- * Close dialog window.
+ * Used to enable CTRL+{a,e,d,k} in search dialog (for start,end,del,cut)
+ * TODO: bind down arrow to a search engine selection list.
*/
-static void window_close_cb(Widget *, void *vwin)
+class CustInput3 : public Fl_Input {
+public:
+ CustInput3 (int x, int y, int w, int h, const char* l=0) :
+ Fl_Input(x,y,w,h,l) {};
+ int handle(int e);
+};
+
+int CustInput3::handle(int e)
{
- delete (Window*)vwin;
+ int k = Fl::event_key();
+
+ _MSG("CustInput3::handle event=%d\n", e);
+
+ // We're only interested in some flags
+ unsigned modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT);
+
+ if (e == FL_KEYBOARD && modifier == FL_CTRL) {
+ if (k == 'a' || k == 'e') {
+ position(k == 'a' ? 0 : size());
+ return 1;
+ } else if (k == 'k') {
+ cut(position(), size());
+ return 1;
+ } else if (k == 'd') {
+ cut(position(), position()+1);
+ return 1;
+ }
+ }
+ return Fl_Input::handle(e);
}
/*
+ * Used to make the ENTER key activate the CustChoice
+ */
+class CustChoice : public Fl_Choice {
+public:
+ CustChoice (int x, int y, int w, int h, const char* l=0) :
+ Fl_Choice(x,y,w,h,l) {};
+ int handle(int e) {
+ if (e == FL_KEYBOARD &&
+ (Fl::event_key() == FL_Enter || Fl::event_key() == FL_Down) &&
+ (Fl::event_state() & (FL_SHIFT|FL_CTRL|FL_ALT|FL_META)) == 0) {
+ return Fl_Choice::handle(FL_PUSH);
+ }
+ return Fl_Choice::handle(e);
+ };
+};
+
+//----------------------------------------------------------------------------
+
+
+/*
* Display a message in a popup window.
*/
void a_Dialog_msg(const char *msg)
{
- message("%s", msg);
+ fl_message("%s", msg);
}
+
/*
- * Offer a three choice dialog.
- * The option string that begins with "*" is the default.
- *
- * Return: 0, 1 or 2 (esc = 2, window close = 2)
+ * Callback for a_Dialog_input()
*/
-int a_Dialog_choice3(const char *msg,
- const char *b0, const char *b1, const char *b2)
+static void input_cb(Fl_Widget *button, void *number)
{
- return choice(msg, b0, b1, b2);
+ input_answer = VOIDP2INT(number);
+ button->window()->hide();
}
/*
* Dialog for one line of Input with a message.
+ * avoids the sound bell in fl_input(), and allows customization
+ *
+ * Return value: string on success, NULL upon Cancel or Close window
*/
const char *a_Dialog_input(const char *msg)
{
- return input("%s", "", msg);
+ static Fl_Menu_Item *pm = 0;
+ int ww = 450, wh = 130, gap = 10, ih = 60, bw = 80, bh = 30;
+
+ input_answer = 0;
+
+ Fl_Window *window = new Fl_Window(ww,wh,"Ask");
+ window->set_modal();
+ window->begin();
+ Fl_Group* ib = new Fl_Group(0,0,window->w(),window->h());
+ ib->begin();
+ window->resizable(ib);
+
+ /* '?' Icon */
+ Fl_Box* o = new Fl_Box(gap, gap, ih, ih);
+ o->box(FL_THIN_UP_BOX);
+ o->labelfont(FL_TIMES_BOLD);
+ o->labelsize(34);
+ o->color(FL_WHITE);
+ o->labelcolor(FL_BLUE);
+ o->label("?");
+ o->show();
+
+ Fl_Box *box = new Fl_Box(ih+2*gap,gap,ww-(ih+3*gap),ih/2, msg);
+ box->labelfont(FL_HELVETICA);
+ box->labelsize(14);
+ box->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP|FL_ALIGN_WRAP);
+
+ CustInput3 *c_inp = new CustInput3(ih+2*gap,gap+ih/2+gap,ww-(ih+3*gap),24);
+ c_inp->labelsize(14);
+ c_inp->textsize(14);
+
+ CustChoice *ch = new CustChoice(1*gap,ih+3*gap,180,24);
+ if (!pm) {
+ int n_it = dList_length(prefs.search_urls);
+ pm = new Fl_Menu_Item[n_it+1];
+ memset(pm, '\0', sizeof(Fl_Menu_Item[n_it+1]));
+ for (int i = 0, j = 0; i < n_it; i++) {
+ char *label, *url, *source;
+ source = (char *)dList_nth_data(prefs.search_urls, i);
+ if (!source || a_Misc_parse_search_url(source, &label, &url) < 0)
+ continue;
+ pm[j++].label(FL_NORMAL_LABEL, strdup(label));
+ }
+ }
+ ch->tooltip("Select search engine");
+ ch->menu(pm);
+ ch->value(prefs.search_url_idx);
+ ch->textcolor(FL_DARK_BLUE);
+
+ int xpos = ww-2*(gap+bw), ypos = ih+3*gap;
+ Fl_Return_Button *rb = new Fl_Return_Button(xpos, ypos, bw, bh, "OK");
+ rb->align(FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
+ rb->box(FL_UP_BOX);
+ rb->callback(input_cb, INT2VOIDP(1));
+
+ xpos = ww-(gap+bw);
+ Fl_Button *b = new Fl_Button(xpos, ypos, bw, bh, "Cancel");
+ b->align(FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
+ b->box(FL_UP_BOX);
+ b->callback(input_cb, INT2VOIDP(2));
+
+ window->end();
+
+ window->show();
+ while (window->shown())
+ Fl::wait();
+ if (input_answer == 1) {
+ /* we have a string, save it */
+ dFree(input_str);
+ input_str = dStrdup(c_inp->value());
+ prefs.search_url_idx = ch->value();
+ }
+ delete window;
+
+ return (input_answer == 1) ? input_str : NULL;
}
/*
@@ -72,7 +206,7 @@ const char *a_Dialog_input(const char *msg)
*/
const char *a_Dialog_passwd(const char *msg)
{
- return password("%s", "", msg);
+ return fl_password("%s", "", msg);
}
/*
@@ -83,7 +217,7 @@ const char *a_Dialog_passwd(const char *msg)
const char *a_Dialog_save_file(const char *msg,
const char *pattern, const char *fname)
{
- return file_chooser(msg, pattern, fname);
+ return fl_file_chooser(msg, pattern, fname);
}
/*
@@ -101,7 +235,6 @@ const char *a_Dialog_select_file(const char *msg,
return a_Dialog_save_file(msg, pattern, fname);
}
-//#include <fltk/FileIcon.h>
/*
* Show the open file dialog.
*
@@ -111,69 +244,66 @@ char *a_Dialog_open_file(const char *msg,
const char *pattern, const char *fname)
{
const char *fc_name;
-/*
- static int icons_loaded = 0;
- if (!icons_loaded)
- FileIcon::load_system_icons();
-*/
- fc_name = file_chooser(msg, pattern, fname);
+
+ fc_name = fl_file_chooser(msg, pattern, fname);
return (fc_name) ? a_Misc_escape_chars(fc_name, "% ") : NULL;
}
/*
+ * Close text window.
+ */
+static void text_window_close_cb(Fl_Widget *, void *vtd)
+{
+ Fl_Text_Display *td = (Fl_Text_Display *)vtd;
+ Fl_Text_Buffer *buf = td->buffer();
+
+ delete (Fl_Window*)td->window();
+ delete buf;
+}
+
+/*
* Show a new window with the provided text
*/
void a_Dialog_text_window(const char *txt, const char *title)
{
- //int wh = 600, ww = 650, bh = 30;
int wh = prefs.height, ww = prefs.width, bh = 30;
- int lines, line_num_width;
- Font *textfont = font(prefs.font_monospace, 0);
- Window *window = new Window(ww, wh, title ? title : "Untitled");
- window->callback(window_close_cb, window);
- window->begin();
-
- TextDisplay *td = new TextDisplay(0,0,ww, wh-bh);
- td->buffer()->text(txt);
+ Fl_Window *window = new Fl_Window(ww, wh, title ? title : "Dillo text");
+ Fl_Group::current(0);
- if (textfont)
- td->textfont(textfont);
- td->textsize((int) rint(13.0 * prefs.font_factor));
- fltk::setfont(td->textfont(), td->textsize());
- lines = td->total_lines();
- line_num_width = 2;
- while (lines /= 10)
- ++line_num_width;
- line_num_width = (int)(line_num_width * fltk::getwidth("0"));
- td->linenumber_width(line_num_width);
+ Fl_Text_Buffer *buf = new Fl_Text_Buffer();
+ buf->text(txt);
+ Fl_Text_Display *td = new Fl_Text_Display(0,0,ww, wh-bh);
+ td->buffer(buf);
+ td->textsize((int) rint(14.0 * prefs.font_factor));
/* enable wrapping lines; text uses entire width of window */
td->wrap_mode(true, false);
- /* WORKAROUND: FLTK may not display all the lines without this */
- td->resize(ww+1,wh-bh);
+ window->add(td);
- ReturnButton *b = new ReturnButton (0, wh-bh, ww, bh, "Close");
- b->callback(window_close_cb, window);
+ Fl_Return_Button *b = new Fl_Return_Button (0, wh-bh, ww, bh, "Close");
+ b->callback(text_window_close_cb, td);
+ window->add(b);
+ window->callback(text_window_close_cb, td);
window->resizable(td);
- window->end();
window->show();
}
/*--------------------------------------------------------------------------*/
-static int choice5_answer;
-static void choice5_cb(Widget *button, void *number)
+static void choice5_cb(Fl_Widget *button, void *number)
{
choice5_answer = VOIDP2INT(number);
_MSG("choice5_cb: %d\n", choice5_answer);
- button->window()->make_exec_return(true);
+ button->window()->hide();
}
/*
- * Make a question-dialog with a question and some alternatives.
+ * Make a question-dialog with a question and up to five alternatives.
+ * (if less alternatives, non used parameters must be NULL).
+ *
* Return value: 0 = dialog was cancelled, 1-5 = selected alternative.
*/
int a_Dialog_choice5(const char *QuestionTxt,
@@ -182,56 +312,72 @@ int a_Dialog_choice5(const char *QuestionTxt,
{
choice5_answer = 0;
- int ww = 440, wh = 150, bw = 50, bh = 45, nb = 0;
+ int ww = 440, wh = 120, bw = 50, bh = 45, ih = 50, nb = 0;
const char *txt[7];
txt[0] = txt[6] = NULL;
txt[1] = alt1; txt[2] = alt2; txt[3] = alt3;
txt[4] = alt4; txt[5] = alt5;
- for (int i=1; txt[i]; ++i, ++nb) ;
+ for (int i=1; txt[i]; ++i, ++nb)
+ ;
+
+ if (!nb) {
+ MSG_ERR("a_Dialog_choice5: No choices.\n");
+ return choice5_answer;
+ }
+ ww = 140 + nb*(bw+10);
- Window *window = new Window(ww,wh,"Choice5");
+ Fl_Window *window = new Fl_Window(ww,wh,"Choice5");
+ window->set_modal();
window->begin();
- Group* ib = new Group(0,0,window->w(),window->h());
+ Fl_Group* ib = new Fl_Group(0,0,window->w(),window->h());
ib->begin();
window->resizable(ib);
- Widget *box = new Widget(0,0,ww,wh-bh, QuestionTxt);
- box->box(DOWN_BOX);
- box->labelfont(HELVETICA_BOLD_ITALIC);
+ /* '?' Icon */
+ Fl_Box* o = new Fl_Box(10, (wh-bh-ih)/2, ih, ih);
+ o->box(FL_THIN_UP_BOX);
+ o->labelfont(FL_TIMES_BOLD);
+ o->labelsize(34);
+ o->color(FL_WHITE);
+ o->labelcolor(FL_BLUE);
+ o->label("?");
+ o->show();
+
+ Fl_Box *box = new Fl_Box(60,0,ww-60,wh-bh, QuestionTxt);
+ box->labelfont(FL_HELVETICA);
box->labelsize(14);
+ box->align(FL_ALIGN_WRAP);
- HighlightButton *b;
+ Fl_Button *b;
int xpos = 0, gap = 8;
bw = (ww - gap)/nb - gap;
xpos += gap;
for (int i=1; i <= nb; ++i) {
- b = new HighlightButton(xpos, wh-bh, bw, bh, txt[i]);
- b->align(ALIGN_WRAP|ALIGN_CLIP);
- b->box(UP_BOX);
+ b = new Fl_Button(xpos, wh-bh, bw, bh, txt[i]);
+ b->align(FL_ALIGN_WRAP|FL_ALIGN_CLIP);
+ b->box(FL_UP_BOX);
b->callback(choice5_cb, INT2VOIDP(i));
xpos += bw + gap;
+ /* TODO: set focus to the *-prefixed alternative */
}
window->end();
- //window->hotspot(box);
- window->exec();
+ window->show();
+ while (window->shown())
+ Fl::wait();
+ _MSG("a_Dialog_choice5 answer = %d\n", choice5_answer);
delete window;
- _MSG("Choice5 answer = %d\n", choice5_answer);
return choice5_answer;
}
/*--------------------------------------------------------------------------*/
-/*
- * ret: 0 = Cancel, 1 = OK
- */
-static void Dialog_user_password_cb(Widget *button, void *vIntPtr)
+static void Dialog_user_password_cb(Fl_Widget *button, void *)
{
- int ret = VOIDP2INT(vIntPtr);
- _MSG("Dialog_user_password_cb: %d\n", ret);
- button->window()->make_exec_return(ret);
+ button->window()->user_data(button);
+ button->window()->hide();
}
/*
@@ -241,52 +387,70 @@ static void Dialog_user_password_cb(Widget *button, void *vIntPtr)
*/
int a_Dialog_user_password(const char *message, UserPasswordCB cb, void *vp)
{
- int ok,
- window_w = 300, window_h = 280,
- input_x = 80, input_w = 200, input_h = 30,
- button_y = 230, button_h = 30;
+ int ok = 0, window_h = 280, y, msg_w, msg_h;
+ const int window_w = 300, input_x = 80, input_w = 200, input_h = 30,
+ button_h = 30;
- Window *window =
- new Window(window_w,window_h,"User/Password");
- window->begin();
+ /* window is resized below */
+ Fl_Window *window = new Fl_Window(window_w,window_h,"Dillo User/Password");
+ Fl_Group::current(0);
+ window->user_data(NULL);
/* message */
- WordwrapOutput *message_output =
- new WordwrapOutput(20,20,window_w-40,100);
- message_output->box(DOWN_BOX);
- message_output->text(message);
- message_output->textfont(HELVETICA_BOLD_ITALIC);
- message_output->textsize(14);
+ y = 20;
+ msg_w = window_w - 40;
+ Fl_Box *msg = new Fl_Box(20, y, msg_w, 100); /* resized below */
+ msg->label(message);
+ msg->labelfont(FL_HELVETICA);
+ msg->labelsize(14);
+ msg->align(FL_ALIGN_INSIDE | FL_ALIGN_TOP_LEFT | FL_ALIGN_WRAP);
+
+ fl_font(msg->labelfont(), msg->labelsize());
+ msg_w -= 6; /* The label doesn't fill the entire box. */
+ fl_measure(msg->label(), msg_w, msg_h, 0); /* fl_measure wraps at msg_w */
+ msg->size(msg->w(), msg_h);
+ window->add(msg);
/* inputs */
- Input *user_input =
- new Input(input_x,140,input_w,input_h,"User");
+ y += msg_h + 20;
+ Fl_Input *user_input = new Fl_Input(input_x, y, input_w, input_h, "User");
user_input->labelsize(14);
user_input->textsize(14);
- SecretInput *password_input =
- new SecretInput(input_x,180,input_w,input_h,"Password");
+ window->add(user_input);
+ y += input_h + 10;
+ Fl_Secret_Input *password_input =
+ new Fl_Secret_Input(input_x, y, input_w, input_h, "Password");
password_input->labelsize(14);
password_input->textsize(14);
+ window->add(password_input);
/* "OK" button */
- Button *ok_button =
- new Button(200,button_y,50,button_h,"OK");
+ y += input_h + 20;
+ Fl_Button *ok_button = new Fl_Button(200, y, 50, button_h, "OK");
ok_button->labelsize(14);
ok_button->callback(Dialog_user_password_cb);
- ok_button->user_data(INT2VOIDP(1));
+ window->add(ok_button);
/* "Cancel" button */
- Button *cancel_button =
- new Button(50,button_y,100,button_h,"Cancel");
+ Fl_Button *cancel_button =
+ new Fl_Button(50, y, 100, button_h, "Cancel");
cancel_button->labelsize(14);
cancel_button->callback(Dialog_user_password_cb);
- cancel_button->user_data(INT2VOIDP(0));
+ window->add(cancel_button);
- window->end();
- window->size_range(window_w,window_h,window_w,window_h);
+ y += button_h + 20;
+ window_h = y;
+ window->size(window_w, window_h);
+ window->size_range(window_w, window_h, window_w, window_h);
window->resizable(window);
- if ((ok = window->exec())) {
+ window->show();
+ while (window->shown())
+ Fl::wait();
+
+ ok = ((Fl_Widget *)window->user_data()) == ok_button ? 1 : 0;
+
+ if (ok) {
/* call the callback */
const char *user, *password;
user = user_input->value();
@@ -294,7 +458,6 @@ int a_Dialog_user_password(const char *message, UserPasswordCB cb, void *vp)
_MSG("a_Dialog_user_passwd: ok = %d\n", ok);
(*cb)(user, password, vp);
}
-
delete window;
return ok;
diff --git a/src/dialog.hh b/src/dialog.hh
index 440e9bba..57b21849 100644
--- a/src/dialog.hh
+++ b/src/dialog.hh
@@ -9,8 +9,6 @@ typedef void (*UserPasswordCB)(const char *user, const char *password,
void *vp);
void a_Dialog_msg(const char *msg);
-int a_Dialog_choice3(const char *msg,
- const char *b0, const char *b1, const char *b2);
int a_Dialog_choice5(const char *QuestionTxt,
const char *alt1, const char *alt2, const char *alt3,
const char *alt4, const char *alt5);
diff --git a/src/dillo.cc b/src/dillo.cc
index 3159674e..b05cb16a 100644
--- a/src/dillo.cc
+++ b/src/dillo.cc
@@ -24,10 +24,9 @@
#include <signal.h>
#include <locale.h>
-#include <fltk/Window.h>
-#include <fltk/TabGroup.h>
-#include <fltk/Font.h>
-#include <fltk/run.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_draw.H>
#include "msg.h"
#include "paths.hh"
@@ -49,6 +48,8 @@
#include "cookies.h"
#include "auth.h"
+#include "dw/fltkcore.hh"
+
/*
* Command line options structure
*/
@@ -171,11 +172,55 @@ static OptID getCmdOption(const CLI_options *options, int argc, char **argv,
}
/*
+ * Set FL_NORMAL_LABEL to interpret neither symbols (@) nor shortcuts (&),
+ * and FL_FREE_LABELTYPE to interpret shortcuts.
+ */
+static void custLabelDraw(const Fl_Label* o, int X, int Y, int W, int H,
+ Fl_Align align)
+{
+ const int interpret_symbols = 0;
+
+ fl_draw_shortcut = 0;
+ fl_font(o->font, o->size);
+ fl_color((Fl_Color)o->color);
+ fl_draw(o->value, X, Y, W, H, align, o->image, interpret_symbols);
+}
+
+static void custLabelMeasure(const Fl_Label* o, int& W, int& H)
+{
+ const int interpret_symbols = 0;
+
+ fl_draw_shortcut = 0;
+ fl_font(o->font, o->size);
+ fl_measure(o->value, W, H, interpret_symbols);
+}
+
+static void custMenuLabelDraw(const Fl_Label* o, int X, int Y, int W, int H,
+ Fl_Align align)
+{
+ const int interpret_symbols = 0;
+
+ fl_draw_shortcut = 1;
+ fl_font(o->font, o->size);
+ fl_color((Fl_Color)o->color);
+ fl_draw(o->value, X, Y, W, H, align, o->image, interpret_symbols);
+}
+
+static void custMenuLabelMeasure(const Fl_Label* o, int& W, int& H)
+{
+ const int interpret_symbols = 0;
+
+ fl_draw_shortcut = 1;
+ fl_font(o->font, o->size);
+ fl_measure(o->value, W, H, interpret_symbols);
+}
+
+/*
* Tell the user if default/pref fonts can't be found.
*/
static void checkFont(const char *name, const char *type)
{
- if (::fltk::font(name) == NULL)
+ if (! dw::fltk::FltkFont::fontExists(name))
MSG_WARN("preferred %s font \"%s\" not found.\n", type, name);
}
@@ -318,22 +363,38 @@ int main(int argc, char **argv)
}
// Sets WM_CLASS hint on X11
- fltk::Window::xclass("dillo");
+ Fl_Window::default_xclass("dillo");
+
+ Fl::scheme(prefs.theme);
- // WORKAROUND: sometimes the default pager triggers redraw storms
- fltk::TabGroup::default_pager(fltk::PAGER_SHRINK);
+ if (!prefs.show_tooltip) {
+ // turn off UI tooltips
+ Fl::option(Fl::OPTION_SHOW_TOOLTIPS, false);
+ }
+
+ // Disable '@' and '&' interpretation in normal labels.
+ Fl::set_labeltype(FL_NORMAL_LABEL, custLabelDraw, custLabelMeasure);
+
+ // Use to permit '&' interpretation.
+ Fl::set_labeltype(FL_FREE_LABELTYPE,custMenuLabelDraw,custMenuLabelMeasure);
checkPreferredFonts();
+
/* use preferred font for UI */
- fltk::Font *dfont = fltk::font(prefs.font_sans_serif, 0);
- if (dfont) {
- fltk::Widget::default_style->textfont(dfont);
- fltk::Widget::default_style->labelfont(dfont);
- }
+ Fl_Font defaultFont = dw::fltk::FltkFont::get (prefs.font_sans_serif, 0);
+ Fl::set_font(FL_HELVETICA, defaultFont); // this seems to be the
+ // only way to set the
+ // default font in fltk1.3
// Create a new UI/bw pair
BrowserWindow *bw = a_UIcmd_browser_window_new(0, 0, xid, NULL);
+ /* We need this so that fl_text_extents() in dw/fltkplatform.cc can
+ * work when FLTK is configured without XFT and Dillo is opening
+ * immediately-available URLs from the cmdline (e.g. about:splash).
+ */
+ ((Fl_Widget *)bw->ui)->window()->make_current();
+
/* Proxy authentication */
if (prefs.http_proxyuser && !a_Http_proxy_auth()) {
const char *passwd = a_UIcmd_get_passwd(prefs.http_proxyuser);
@@ -349,7 +410,10 @@ int main(int argc, char **argv)
if (idx == argc) {
/* No URLs/files on cmdline. Send startup screen */
- a_UIcmd_open_url(bw, prefs.start_page);
+ if (strcmp(URL_STR(prefs.start_page), "about:blank") == 0)
+ a_UIcmd_open_url(bw, NULL);
+ else
+ a_UIcmd_open_url(bw, prefs.start_page);
} else {
for (int i = idx; i < argc; i++) {
DilloUrl *start_url = makeStartUrl(argv[i], local);
@@ -369,7 +433,7 @@ int main(int argc, char **argv)
}
}
- fltk::run();
+ Fl::run();
/*
* Memory deallocating routines
diff --git a/src/dns.h b/src/dns.h
index 78f8cf18..70c0b8dc 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -8,7 +8,7 @@ extern "C" {
#endif /* __cplusplus */
-typedef void (*DnsCallback_t)(int Status, Dlist *addr_list, void *data);
+typedef void (*DnsCallback_t)(int status, Dlist *addr_list, void *data);
void a_Dns_init (void);
void a_Dns_freeall(void);
diff --git a/src/doctree.hh b/src/doctree.hh
index ef7faa7c..85c1effd 100644
--- a/src/doctree.hh
+++ b/src/doctree.hh
@@ -6,6 +6,8 @@
class DoctreeNode {
public:
DoctreeNode *parent;
+ DoctreeNode *sibling;
+ DoctreeNode *lastChild;
int num; // unique ascending id
int element;
lout::misc::SimpleVector<char*> *klass;
@@ -14,11 +16,27 @@ class DoctreeNode {
DoctreeNode () {
parent = NULL;
+ sibling = NULL;
+ lastChild = NULL;
klass = NULL;
pseudo = NULL;
id = NULL;
element = 0;
};
+
+ ~DoctreeNode () {
+ dFree ((void*) id);
+ while (lastChild) {
+ DoctreeNode *n = lastChild;
+ lastChild = lastChild->sibling;
+ delete n;
+ }
+ if (klass) {
+ for (int i = 0; i < klass->size (); i++)
+ dFree (klass->get(i));
+ delete klass;
+ }
+ }
};
/**
@@ -26,46 +44,55 @@ class DoctreeNode {
*
* The Doctree class defines the interface to the parsed HTML document tree
* as it is used for CSS selector matching.
- * Currently the Doctree can be represented as stack, however to support
- * CSS adjacent siblings or for future JavaScript support it may have to
- * be extended to a real tree.
*/
class Doctree {
private:
DoctreeNode *topNode;
+ DoctreeNode *rootNode;
int num;
public:
Doctree () {
- topNode = NULL;
+ rootNode = new DoctreeNode;
+ topNode = rootNode;
num = 0;
};
- ~Doctree () { while (top ()) pop (); };
+
+ ~Doctree () {
+ delete rootNode;
+ };
+
DoctreeNode *push () {
DoctreeNode *dn = new DoctreeNode ();
dn->parent = topNode;
+ dn->sibling = dn->parent->lastChild;
+ dn->parent->lastChild = dn;
dn->num = num++;
topNode = dn;
return dn;
};
+
void pop () {
- DoctreeNode *dn = topNode;
- if (dn) {
- dFree ((void*) dn->id);
- if (dn->klass) {
- for (int i = 0; i < dn->klass->size (); i++)
- dFree (dn->klass->get(i));
- delete dn->klass;
- }
- topNode = dn->parent;
- delete dn;
- }
+ assert (topNode != rootNode); // never pop the root node
+ topNode = topNode->parent;
};
+
inline DoctreeNode *top () {
- return topNode;
+ if (topNode != rootNode)
+ return topNode;
+ else
+ return NULL;
};
+
inline DoctreeNode *parent (const DoctreeNode *node) {
- return node->parent;
+ if (node->parent != rootNode)
+ return node->parent;
+ else
+ return NULL;
+ };
+
+ inline DoctreeNode *sibling (const DoctreeNode *node) {
+ return node->sibling;
};
};
diff --git a/src/findbar.cc b/src/findbar.cc
index 8cca52ba..47363db0 100644
--- a/src/findbar.cc
+++ b/src/findbar.cc
@@ -9,8 +9,8 @@
* (at your option) any later version.
*/
-#include <fltk/events.h>
-#include <fltk/Window.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
#include "findbar.hh"
#include "msg.h"
@@ -18,49 +18,58 @@
#include "uicmd.hh"
#include "bw.h"
-using namespace fltk;
-
/*
* Local sub class
* (Used to handle escape in the findbar, may also avoid some shortcuts).
*/
-class MyInput : public Input {
+class MyInput : public Fl_Input {
public:
MyInput (int x, int y, int w, int h, const char* l=0) :
- Input(x,y,w,h,l) {};
+ Fl_Input(x,y,w,h,l) {};
int handle(int e);
};
int MyInput::handle(int e)
{
_MSG("findbar MyInput::handle()\n");
- int ret = 1, k = event_key();
- unsigned modifier = event_state() & (SHIFT | CTRL | ALT | META);
-
- if (e == KEY) {
- if (k == LeftKey || k == RightKey) {
- if (modifier == SHIFT) {
- a_UIcmd_send_event_to_tabs_by_wid(e, this);
+ int ret = 1, k = Fl::event_key();
+ unsigned modifier = Fl::event_state() & (FL_SHIFT| FL_CTRL| FL_ALT|FL_META);
+
+ if (e == FL_KEYBOARD) {
+ if (modifier == FL_SHIFT) {
+ if (k == FL_Left || k == FL_Right) {
+ // Let these keys get to the UI
+ return 0;
+ }
+ } else if (modifier == FL_CTRL) {
+ if (k == 'a' || k == 'e') {
+ position(k == 'a' ? 0 : size());
+ return 1;
+ } else if (k == 'k') {
+ cut(position(), size());
+ return 1;
+ } else if (k == 'd') {
+ cut(position(), position()+1);
return 1;
}
- } else if (k == EscapeKey && modifier == 0) {
+ } else if (k == FL_Escape && modifier == 0) {
// Avoid clearing the text with Esc, just hide the findbar.
return 0;
}
}
if (ret)
- ret = Input::handle(e);
+ ret = Fl_Input::handle(e);
return ret;
};
/*
* Find next occurrence of input key
*/
-void Findbar::search_cb(Widget *, void *vfb)
+void Findbar::search_cb(Fl_Widget *, void *vfb)
{
Findbar *fb = (Findbar *)vfb;
- const char *key = fb->i->text();
+ const char *key = fb->i->value();
bool case_sens = fb->check_btn->value();
if (key[0] != '\0')
@@ -71,10 +80,10 @@ void Findbar::search_cb(Widget *, void *vfb)
/*
* Find previous occurrence of input key
*/
-void Findbar::searchBackwards_cb(Widget *, void *vfb)
+void Findbar::searchBackwards_cb(Fl_Widget *, void *vfb)
{
Findbar *fb = (Findbar *)vfb;
- const char *key = fb->i->text();
+ const char *key = fb->i->value();
bool case_sens = fb->check_btn->value();
if (key[0] != '\0') {
@@ -84,86 +93,74 @@ void Findbar::searchBackwards_cb(Widget *, void *vfb)
}
/*
- * Find next occurrence of input key
- */
-void Findbar::search_cb2(Widget *widget, void *vfb)
-{
- /*
- * Somehow fltk even regards the first loss of focus for the
- * window as a WHEN_ENTER_KEY_ALWAYS event.
- */
- if (event_key() == ReturnKey)
- search_cb(widget, vfb);
-}
-
-/*
* Hide the search bar
*/
-void Findbar::hide_cb(Widget *, void *vfb)
+void Findbar::hide_cb(Fl_Widget *, void *vfb)
{
- ((Findbar *)vfb)->hide();
+ a_UIcmd_findbar_toggle(a_UIcmd_get_bw_by_widget(vfb), 0);
}
/*
* Construct text search bar
*/
Findbar::Findbar(int width, int height) :
- Group(0, 0, width, height)
+ Fl_Group(0, 0, width, height)
{
int button_width = 70;
int gap = 2;
int border = 2;
int input_width = width - (2 * border + 4 * (button_width + gap));
- int x = border;
+ int x = 0;
+
+ Fl_Group::current(0);
+
height -= 2 * border;
- box(PLASTIC_UP_BOX);
- Group::hide();
+ box(FL_THIN_UP_BOX);
- begin();
- hide_btn = new HighlightButton(x, border, 16, height, 0);
- hideImg = new xpmImage(new_s_xpm);
+ hide_btn = new Fl_Button(x, border, 16, height, 0);
+ hideImg = new Fl_Pixmap(new_s_xpm);
hide_btn->image(hideImg);
x += 16 + gap;
hide_btn->callback(hide_cb, this);
- hide_btn->clear_tab_to_focus();
+ hide_btn->clear_visible_focus();
+ hide_btn->box(FL_THIN_UP_BOX);
+ hide_btn->tooltip("Hide");
+ add(hide_btn);
i = new MyInput(x, border, input_width, height);
x += input_width + gap;
resizable(i);
i->color(206);
- i->when(WHEN_ENTER_KEY_ALWAYS);
- i->callback(search_cb2, this);
- i->clear_tab_to_focus();
- i->set_click_to_focus();
+ i->when(FL_WHEN_NEVER);
+ add(i);
- next_btn = new HighlightButton(x, border, button_width, height, "Next");
+ next_btn = new Fl_Button(x, border, button_width, height, "Next");
x += button_width + gap;
- next_btn->add_shortcut(ReturnKey);
- next_btn->add_shortcut(KeypadEnter);
+ next_btn->shortcut(FL_Enter);
next_btn->callback(search_cb, this);
- next_btn->clear_tab_to_focus();
+ next_btn->clear_visible_focus();
+ next_btn->box(FL_THIN_UP_BOX);
+ next_btn->tooltip("Find next occurrence of the search phrase\n"
+ "shortcut: Enter");
+ add(next_btn);
- prev_btn= new HighlightButton(x, border, button_width, height, "Previous");
- prev_btn->add_shortcut(SHIFT+ReturnKey);
- prev_btn->callback(searchBackwards_cb, this);
- prev_btn->clear_tab_to_focus();
+ prev_btn= new Fl_Button(x, border, button_width, height, "Previous");
x += button_width + gap;
+ prev_btn->shortcut(FL_SHIFT+FL_Enter);
+ prev_btn->callback(searchBackwards_cb, this);
+ prev_btn->clear_visible_focus();
+ prev_btn->box(FL_THIN_UP_BOX);
+ prev_btn->tooltip("Find previous occurrence of the search phrase\n"
+ "shortcut: Shift+Enter");
+ add(prev_btn);
- check_btn = new CheckButton(x, border, 2*button_width, height,
+ check_btn = new Fl_Check_Button(x, border, 2*button_width, height,
"Case-sensitive");
- check_btn->clear_tab_to_focus();
x += 2 * button_width + gap;
+ check_btn->clear_visible_focus();
+ add(check_btn);
- end();
-
- if (prefs.show_tooltip) {
- hide_btn->tooltip("Hide");
- next_btn->tooltip("Find next occurrence of the search phrase\n"
- "shortcut: Enter");
- prev_btn->tooltip("Find previous occurrence of the search phrase\n"
- "shortcut: Shift+Enter");
- }
}
Findbar::~Findbar()
@@ -172,23 +169,19 @@ Findbar::~Findbar()
}
/*
- * Handle events. Used to catch EscapeKey events.
+ * Handle events. Used to catch FL_Escape events.
*/
int Findbar::handle(int event)
{
- int ret = 0;
- int k = event_key();
- unsigned modifier = event_state() & (SHIFT | CTRL | ALT | META);
+ int k = Fl::event_key();
+ unsigned modifier = Fl::event_state() & (FL_SHIFT| FL_CTRL| FL_ALT|FL_META);
- if (event == KEY && modifier == 0 && k == EscapeKey) {
- hide();
- ret = 1;
+ if (event == FL_KEYBOARD && modifier == 0 && k == FL_Escape) {
+ /* let the UI handle it */
+ return 0;
}
- if (ret == 0)
- ret = Group::handle(event);
-
- return ret;
+ return Fl_Group::handle(event);
}
/*
@@ -196,21 +189,14 @@ int Findbar::handle(int event)
*/
void Findbar::show()
{
- Group::show();
+ BrowserWindow *bw = a_UIcmd_get_bw_by_widget(this);
+ dReturn_if (bw == NULL);
+
+ // It takes more than just calling show() to do the trick
+ Fl_Group::show();
+
/* select text even if already focused */
i->take_focus();
i->position(i->size(), 0);
}
-/*
- * Hide the findbar and reset the search state
- */
-void Findbar::hide()
-{
- BrowserWindow *bw;
-
- Group::hide();
- if ((bw = a_UIcmd_get_bw_by_widget(this)))
- a_UIcmd_findtext_reset(bw);
- a_UIcmd_focus_main_area(bw);
-}
diff --git a/src/findbar.hh b/src/findbar.hh
index ba7ed8ed..72d24c44 100644
--- a/src/findbar.hh
+++ b/src/findbar.hh
@@ -1,35 +1,32 @@
#ifndef __FINDBAR_HH__
#define __FINDBAR_HH__
-#include <fltk/xpmImage.h>
-#include <fltk/Widget.h>
-#include <fltk/HighlightButton.h>
-#include <fltk/Button.h>
-#include <fltk/Input.h>
-#include <fltk/Group.h>
-#include <fltk/CheckButton.h>
+#include <FL/Fl_Pixmap.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Check_Button.H>
/*
* Searchbar to find text in page.
*/
-class Findbar : public fltk::Group {
- fltk::Button *clrb;
- fltk::HighlightButton *hide_btn, *next_btn, *prev_btn;
- fltk::CheckButton *check_btn;
- fltk::xpmImage *hideImg;
- fltk::Input *i;
+class Findbar : public Fl_Group {
+ Fl_Button *clrb;
+ Fl_Button *hide_btn, *next_btn, *prev_btn;
+ Fl_Check_Button *check_btn;
+ Fl_Pixmap *hideImg;
+ Fl_Input *i;
- static void search_cb (fltk::Widget *, void *);
- static void searchBackwards_cb (fltk::Widget *, void *);
- static void search_cb2 (fltk::Widget *, void *);
- static void hide_cb (fltk::Widget *, void *);
+ static void search_cb (Fl_Widget *, void *);
+ static void searchBackwards_cb (Fl_Widget *, void *);
+ static void hide_cb (Fl_Widget *, void *);
public:
Findbar(int width, int height);
~Findbar();
int handle(int event);
void show();
- void hide();
};
#endif // __FINDBAR_HH__
diff --git a/src/form.cc b/src/form.cc
index 18441fb8..f70bea8c 100644
--- a/src/form.cc
+++ b/src/form.cc
@@ -249,7 +249,9 @@ static void Html_add_input(DilloHtml *html, DilloHtmlInputType type,
html->inputs_outside_form->increase();
html->inputs_outside_form->set(ni, input);
- input->setEnabled(false);
+ if (html->bw->NumPendingStyleSheets > 0) {
+ input->setEnabled(false);
+ }
}
}
@@ -609,7 +611,6 @@ void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize)
/*
* The textarea tag
- * (TODO: It doesn't support wrapping).
*/
void Html_tag_open_textarea(DilloHtml *html, const char *tag, int tagsize)
{
@@ -850,7 +851,10 @@ void Html_tag_open_button(DilloHtml *html, const char *tag, int tagsize)
Embed *embed;
char *name, *value;
- page = new Textblock (prefs.limit_text_width);
+ /* We used to have Textblock (prefs.limit_text_width) here,
+ * but it caused 100% CPU usage.
+ */
+ page = new Textblock (false);
page->setStyle (html->styleEngine->backgroundStyle ());
ResourceFactory *factory = HT2LT(html)->getResourceFactory();
diff --git a/src/gif.c b/src/gif.c
index b5486c46..6911bc87 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -677,7 +677,7 @@ static int Gif_decode(DilloGif *gif, const uchar_t *buf, size_t bsize)
case 2: /* End code... consume remaining data chunks..? */
goto error; /* Could clean up better? */
default:
- printf("dillo_gif_decode: error!\n");
+ MSG("Gif_decode: error!\n");
goto error;
}
}
@@ -810,8 +810,6 @@ static size_t Gif_do_img_desc(DilloGif *gif, void *Buf,
return 0;
}
- gif->linebuf = dMalloc(gif->Width);
-
a_Dicache_set_parms(gif->url, gif->version, gif->Image,
gif->Width, gif->Height, DILLO_IMG_TYPE_INDEXED);
@@ -842,6 +840,7 @@ static size_t Gif_do_img_desc(DilloGif *gif, void *Buf,
gif->y = 0;
Gif_lwz_init(gif);
gif->spill_line_index = 0;
+ gif->linebuf = dMalloc(gif->Width);
gif->state = 3; /*Process the lzw data next */
if (gif->Image && gif->ColorMap_ofs) {
a_Dicache_set_cmap(gif->url, gif->version, gif->Image,
diff --git a/src/html.cc b/src/html.cc
index bcefe14b..98fe7b8b 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -652,7 +652,7 @@ bool_t DilloHtml::unloadedImages()
*/
void DilloHtml::loadImages (const DilloUrl *pattern)
{
- dReturn_if_fail (bw->nav_expecting == FALSE);
+ dReturn_if (a_Bw_expecting(bw));
/* If the user asked for a specific URL, the user (NULL) is the requester,
* but if the user just asked for all URLs, use the page URL as the
@@ -693,12 +693,10 @@ bool DilloHtml::HtmlLinkReceiver::enter (Widget *widget, int link, int img,
if (link == -1) {
_MSG(" Link LEAVE notify...\n");
a_UIcmd_set_msg(bw, "");
- a_UIcmd_set_pointer_on_link(bw, FALSE);
} else {
_MSG(" Link ENTER notify...\n");
Html_set_link_coordinates(html, link, x, y);
a_UIcmd_set_msg(bw, "%s", URL_STR(html->links->get(link)));
- a_UIcmd_set_pointer_on_link(bw, TRUE);
}
return true;
}
@@ -1723,7 +1721,6 @@ static void Html_tag_close_style(DilloHtml *html, int TagIdx)
static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize)
{
const char *attrbuf;
- Textblock *textblock;
int32_t color;
int tag_index_a = a_Html_tag_index ("a");
style::Color *bgColor;
@@ -1741,8 +1738,6 @@ static void Html_tag_open_body(DilloHtml *html, const char *tag, int tagsize)
BUG_MSG("unclosed HEAD element\n");
}
- textblock = HT2TB(html);
-
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) {
color = a_Html_color_parse(html, attrbuf, -1);
if (color != -1)
@@ -2148,8 +2143,7 @@ static bool Html_load_image(BrowserWindow *bw, DilloUrl *url,
DilloWeb *Web;
int ClientKey;
/* Fill a Web structure for the cache query */
- Web = a_Web_new(url, requester);
- Web->bw = bw;
+ Web = a_Web_new(bw, url, requester);
Web->Image = Image;
a_Image_ref(Image);
Web->flags |= WEB_Image;
@@ -2170,7 +2164,6 @@ static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize)
{
DilloImage *Image;
DilloUrl *url, *usemap_url;
- Textblock *textblock;
const char *attrbuf;
/* This avoids loading images. Useful for viewing suspicious HTML email. */
@@ -2181,8 +2174,6 @@ static void Html_tag_open_img(DilloHtml *html, const char *tag, int tagsize)
!(url = a_Html_url_new(html, attrbuf, NULL, 0)))
return;
- textblock = HT2TB(html);
-
usemap_url = NULL;
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "usemap")))
/* TODO: usemap URLs outside of the document are not used. */
@@ -2259,12 +2250,11 @@ static void Html_tag_close_map(DilloHtml *html, int TagIdx)
static
misc::SimpleVector<int> *Html_read_coords(DilloHtml *html, const char *str)
{
- int i, coord;
+ int coord;
const char *tail = str;
char *newtail = NULL;
misc::SimpleVector<int> *coords = new misc::SimpleVector<int> (4);
- i = 0;
while (1) {
coord = strtol(tail, &newtail, 10);
if (coord == 0 && newtail == tail)
@@ -2461,12 +2451,14 @@ static void Html_tag_open_a(DilloHtml *html, const char *tag, int tagsize)
html->InVisitedLink = true;
html->styleEngine->setPseudoVisited ();
if (html->non_css_visited_color != -1)
- html->styleEngine->setNonCssHint(CSS_PROPERTY_COLOR, CSS_TYPE_COLOR,
+ html->styleEngine->setNonCssHint(CSS_PROPERTY_COLOR,
+ CSS_TYPE_COLOR,
html->non_css_visited_color);
} else {
html->styleEngine->setPseudoLink ();
if (html->non_css_link_color != -1)
- html->styleEngine->setNonCssHint(CSS_PROPERTY_COLOR, CSS_TYPE_COLOR,
+ html->styleEngine->setNonCssHint(CSS_PROPERTY_COLOR,
+ CSS_TYPE_COLOR,
html->non_css_link_color);
}
@@ -2744,9 +2736,11 @@ static void Html_tag_open_hr(DilloHtml *html, const char *tag, int tagsize)
html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_LEFT_WIDTH,
CSS_TYPE_LENGTH_PERCENTAGE, size_top);
html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, size_bottom);
+ CSS_TYPE_LENGTH_PERCENTAGE,
+ size_bottom);
html->styleEngine->setNonCssHint (CSS_PROPERTY_BORDER_RIGHT_WIDTH,
- CSS_TYPE_LENGTH_PERCENTAGE, size_bottom);
+ CSS_TYPE_LENGTH_PERCENTAGE,
+ size_bottom);
}
HT2TB(html)->addParbreak (5, html->styleEngine->wordStyle ());
@@ -2850,6 +2844,7 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
const char *p, *equiv, *content, *new_content;
char delay_str[64], *mr_url;
+ DilloUrl *new_url;
int delay;
/* only valid inside HEAD */
@@ -2871,44 +2866,45 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
}
/* Skip to anything after "URL=" */
while (*content && *(content++) != '=') ;
- if (*content) {
-
- /* Handle the case of a quoted URL */
- if (*content == '"' || *content == '\'') {
- if ((p = strchr(content + 1, *content)))
- mr_url = dStrndup(content + 1, p - content - 1);
- else
- mr_url = dStrdup(content + 1);
- } else {
- mr_url = dStrdup(content);
- }
-
- if (delay == 0) {
- /* zero-delay redirection */
- html->stop_parser = true;
- DilloUrl *new_url = a_Url_new(mr_url, URL_STR(html->base_url));
- if (a_Capi_dpi_verify_request(html->bw, new_url))
- a_UIcmd_redirection0((void*)html->bw, new_url);
- a_Url_free(new_url);
- } else {
- /* Send a custom HTML message.
- * TODO: This is a hairy hack,
- * It'd be much better to build a widget. */
- Dstr *ds_msg = dStr_sized_new(256);
- dStr_sprintf(ds_msg, meta_template, mr_url, delay_str);
- {
- int o_InFlags = html->InFlags;
- int o_TagSoup = html->TagSoup;
- html->InFlags = IN_BODY;
- html->TagSoup = false;
- Html_write_raw(html, ds_msg->str, ds_msg->len, 0);
- html->TagSoup = o_TagSoup;
- html->InFlags = o_InFlags;
- }
- dStr_free(ds_msg, 1);
+ /* Handle the case of a quoted URL */
+ if (*content == '"' || *content == '\'') {
+ if ((p = strchr(content + 1, *content)))
+ mr_url = dStrndup(content + 1, p - content - 1);
+ else
+ mr_url = dStrdup(content + 1);
+ } else {
+ mr_url = dStrdup(content);
+ }
+ new_url = a_Url_new(mr_url, URL_STR(html->base_url));
+
+ if (a_Url_cmp(html->base_url, new_url) == 0) {
+ /* redirection loop, or empty url string: ignore */
+ BUG_MSG("META refresh: %s\n",
+ *mr_url ? "redirection loop" : "no target URL");
+ } else if (delay == 0) {
+ /* zero-delay redirection */
+ html->stop_parser = true;
+ if (a_Capi_dpi_verify_request(html->bw, new_url))
+ a_UIcmd_redirection0((void*)html->bw, new_url);
+ } else {
+ /* Send a custom HTML message.
+ * TODO: This is a hairy hack,
+ * It'd be much better to build a widget. */
+ Dstr *ds_msg = dStr_sized_new(256);
+ dStr_sprintf(ds_msg, meta_template, mr_url, delay_str);
+ {
+ int o_InFlags = html->InFlags;
+ int o_TagSoup = html->TagSoup;
+ html->InFlags = IN_BODY;
+ html->TagSoup = false;
+ Html_write_raw(html, ds_msg->str, ds_msg->len, 0);
+ html->TagSoup = o_TagSoup;
+ html->InFlags = o_InFlags;
}
- dFree(mr_url);
+ dStr_free(ds_msg, 1);
}
+ a_Url_free(new_url);
+ dFree(mr_url);
} else if (!dStrcasecmp(equiv, "content-type") &&
(content = a_Html_get_attr(html, tag, tagsize, "content"))) {
@@ -2958,14 +2954,13 @@ void a_Html_load_stylesheet(DilloHtml *html, DilloUrl *url)
if (endq && (endq - data <= 51)) {
/* IANA limits charset names to 40 characters */
- const char *ignored;
char *content_type;
*endq = '\0';
content_type = dStrconcat("text/css; charset=", data+10, NULL);
*endq = '"';
a_Capi_unref_buf(url);
- ignored = a_Capi_set_content_type(url, content_type, "meta");
+ a_Capi_set_content_type(url, content_type, "meta");
dFree(content_type);
a_Capi_get_buf(url, &data, &len);
}
@@ -2976,8 +2971,7 @@ void a_Html_load_stylesheet(DilloHtml *html, DilloUrl *url)
} else {
/* Fill a Web structure for the cache query */
int ClientKey;
- DilloWeb *Web = a_Web_new(url, html->page_url);
- Web->bw = html->bw;
+ DilloWeb *Web = a_Web_new(html->bw, url, html->page_url);
if ((ClientKey = a_Capi_open_url(Web, Html_css_load_callback, NULL))) {
++html->bw->NumPendingStyleSheets;
a_Bw_add_client(html->bw, ClientKey, 0);
@@ -3031,7 +3025,7 @@ static void Html_tag_open_link(DilloHtml *html, const char *tag, int tagsize)
!(url = a_Html_url_new(html, attrbuf, NULL, 0)))
return;
- MSG(" Html_tag_open_link(): addCssUrl %s\n", URL_STR(url));
+ _MSG(" Html_tag_open_link(): addCssUrl %s\n", URL_STR(url));
html->addCssUrl(url);
a_Url_free(url);
diff --git a/src/keys.cc b/src/keys.cc
index 1a39f4c8..bd78fd5f 100644
--- a/src/keys.cc
+++ b/src/keys.cc
@@ -9,7 +9,7 @@
* (at your option) any later version.
*/
-#include <fltk/events.h>
+#include <FL/Fl.H>
#include <stdio.h>
#include <stdlib.h> /* strtol */
#include <string.h>
@@ -17,6 +17,7 @@
#include "dlib/dlib.h"
#include "keys.hh"
+#include "utf8.hh"
#include "msg.h"
/*
@@ -38,80 +39,99 @@ typedef struct {
* Local data
*/
static const Mapping_t keyNames[] = {
- { "Backspace", fltk::BackSpaceKey },
- { "Delete", fltk::DeleteKey },
- { "Down", fltk::DownKey },
- { "End", fltk::EndKey },
- { "Esc", fltk::EscapeKey },
- { "F1", fltk::F1Key },
- { "F2", fltk::F2Key },
- { "F3", fltk::F3Key },
- { "F4", fltk::F4Key },
- { "F5", fltk::F5Key },
- { "F6", fltk::F6Key },
- { "F7", fltk::F7Key },
- { "F8", fltk::F8Key },
- { "F9", fltk::F9Key },
- { "F10", fltk::F10Key },
- { "F11", fltk::F11Key },
- { "F12", fltk::F12Key },
- { "Home", fltk::HomeKey },
- { "Insert", fltk::InsertKey },
- { "Left", fltk::LeftKey },
- { "PageDown", fltk::PageDownKey },
- { "PageUp", fltk::PageUpKey },
- { "Print", fltk::PrintKey },
- { "Return", fltk::ReturnKey },
- { "Right", fltk::RightKey },
- { "Space", fltk::SpaceKey },
- { "Tab", fltk::TabKey },
- { "Up", fltk::UpKey }
+ { "Backspace", FL_BackSpace },
+ { "Delete", FL_Delete },
+ { "Down", FL_Down },
+ { "End", FL_End },
+ { "Esc", FL_Escape },
+ { "F1", FL_F + 1 },
+ { "F2", FL_F + 2 },
+ { "F3", FL_F + 3 },
+ { "F4", FL_F + 4 },
+ { "F5", FL_F + 5 },
+ { "F6", FL_F + 6 },
+ { "F7", FL_F + 7 },
+ { "F8", FL_F + 8 },
+ { "F9", FL_F + 9 },
+ { "F10", FL_F + 10 },
+ { "F11", FL_F + 11 },
+ { "F12", FL_F + 12 },
+ { "Home", FL_Home },
+ { "Insert", FL_Insert },
+ { "Left", FL_Left },
+ { "PageDown", FL_Page_Down },
+ { "PageUp", FL_Page_Up },
+ { "Print", FL_Print },
+ { "Return", FL_Enter },
+ { "Right", FL_Right },
+ { "Space", ' ' },
+ { "Tab", FL_Tab },
+ { "Up", FL_Up },
+ /* multimedia keys */
+ { "Back", FL_Back },
+ { "Favorites", FL_Favorites },
+ { "Forward", FL_Forward },
+ { "HomePage", FL_Home_Page },
+ { "Mail", FL_Mail },
+ { "MediaNext", FL_Media_Next },
+ { "MediaPlay", FL_Media_Play },
+ { "MediaPrev", FL_Media_Prev },
+ { "MediaStop", FL_Media_Stop },
+ { "Refresh", FL_Refresh },
+ { "Search", FL_Search },
+ { "Sleep", FL_Sleep },
+ { "Stop", FL_Stop },
+ { "VolumeDown", FL_Volume_Down },
+ { "VolumeMute", FL_Volume_Mute },
+ { "VolumeUp", FL_Volume_Up },
};
static const Mapping_t modifierNames[] = {
- { "Shift", fltk::SHIFT },
- { "Ctrl", fltk::CTRL },
- { "Alt", fltk::ALT },
- { "Meta", fltk::META },
- { "Button1", fltk::BUTTON1 },
- { "Button2", fltk::BUTTON2 },
- { "Button3", fltk::BUTTON3 }
+ { "Shift", FL_SHIFT },
+ { "Ctrl", FL_CTRL },
+ { "Alt", FL_ALT },
+ { "Meta", FL_META },
+ { "Button1", FL_BUTTON1 },
+ { "Button2", FL_BUTTON2 },
+ { "Button3", FL_BUTTON3 }
};
static const KeyBinding_t default_keys[] = {
- { "nop" , KEYS_NOP , 0 , 0 },
- { "open" , KEYS_OPEN , fltk::CTRL , 'o' },
- { "new-window" , KEYS_NEW_WINDOW , fltk::CTRL , 'n' },
- { "new-tab" , KEYS_NEW_TAB , fltk::CTRL , 't' },
- { "left-tab" , KEYS_LEFT_TAB , fltk::SHIFT , fltk::TabKey },
- { "right-tab" , KEYS_RIGHT_TAB , fltk::CTRL , fltk::TabKey },
- { "close-tab" , KEYS_CLOSE_TAB , fltk::CTRL , 'q' },
- { "find" , KEYS_FIND , fltk::CTRL , 'f' },
- { "websearch" , KEYS_WEBSEARCH , fltk::CTRL , 's' },
- { "bookmarks" , KEYS_BOOKMARKS , fltk::CTRL , 'b' },
- { "fullscreen" , KEYS_FULLSCREEN , fltk::CTRL , fltk::SpaceKey },
- { "reload" , KEYS_RELOAD , fltk::CTRL , 'r' },
- { "stop" , KEYS_STOP , 0 , 0 },
- { "save" , KEYS_SAVE , 0 , 0 },
- { "hide-panels" , KEYS_HIDE_PANELS , 0 , fltk::EscapeKey },
- { "file-menu" , KEYS_FILE_MENU , fltk::ALT , 'f' },
- { "close-all" , KEYS_CLOSE_ALL , fltk::ALT , 'q' },
- { "back" , KEYS_BACK , 0 , fltk::BackSpaceKey },
- { "back" , KEYS_BACK , 0 , ',' },
- { "forward" , KEYS_FORWARD , fltk::SHIFT , fltk::BackSpaceKey },
- { "forward" , KEYS_FORWARD , 0 , '.' },
- { "goto" , KEYS_GOTO , fltk::CTRL , 'l' },
- { "home" , KEYS_HOME , fltk::CTRL , 'h' },
- { "screen-up" , KEYS_SCREEN_UP , 0 , fltk::PageUpKey },
- { "screen-up" , KEYS_SCREEN_UP , 0 , 'b' },
- { "screen-down" , KEYS_SCREEN_DOWN , 0 , fltk::PageDownKey },
- { "screen-down" , KEYS_SCREEN_DOWN , 0 , fltk::SpaceKey },
- { "line-up" , KEYS_LINE_UP , 0 , fltk::UpKey },
- { "line-down" , KEYS_LINE_DOWN , 0 , fltk::DownKey },
- { "left" , KEYS_LEFT , 0 , fltk::LeftKey },
- { "right" , KEYS_RIGHT , 0 , fltk::RightKey },
- { "top" , KEYS_TOP , 0 , fltk::HomeKey },
- { "bottom" , KEYS_BOTTOM , 0 , fltk::EndKey },
+ { "nop" , KEYS_NOP , 0 , 0 },
+ { "open" , KEYS_OPEN , FL_CTRL , 'o' },
+ { "new-window" , KEYS_NEW_WINDOW , FL_CTRL , 'n' },
+ { "new-tab" , KEYS_NEW_TAB , FL_CTRL , 't' },
+ { "left-tab" , KEYS_LEFT_TAB , FL_CTRL |
+ FL_SHIFT , FL_Tab },
+ { "right-tab" , KEYS_RIGHT_TAB , FL_CTRL , FL_Tab },
+ { "close-tab" , KEYS_CLOSE_TAB , FL_CTRL , 'w' },
+ { "find" , KEYS_FIND , FL_CTRL , 'f' },
+ { "websearch" , KEYS_WEBSEARCH , FL_CTRL , 's' },
+ { "bookmarks" , KEYS_BOOKMARKS , FL_CTRL , 'b' },
+ { "reload" , KEYS_RELOAD , FL_CTRL , 'r' },
+ { "stop" , KEYS_STOP , 0 , 0 },
+ { "save" , KEYS_SAVE , 0 , 0 },
+ { "hide-panels" , KEYS_HIDE_PANELS , 0 , FL_Escape },
+ { "file-menu" , KEYS_FILE_MENU , FL_ALT , 'f' },
+ { "close-all" , KEYS_CLOSE_ALL , FL_CTRL , 'q' },
+ { "back" , KEYS_BACK , 0 , FL_BackSpace },
+ { "back" , KEYS_BACK , 0 , ',' },
+ { "forward" , KEYS_FORWARD , FL_SHIFT , FL_BackSpace },
+ { "forward" , KEYS_FORWARD , 0 , '.' },
+ { "goto" , KEYS_GOTO , FL_CTRL , 'l' },
+ { "home" , KEYS_HOME , FL_CTRL , 'h' },
+ { "screen-up" , KEYS_SCREEN_UP , 0 , FL_Page_Up },
+ { "screen-up" , KEYS_SCREEN_UP , 0 , 'b' },
+ { "screen-down" , KEYS_SCREEN_DOWN , 0 , FL_Page_Down },
+ { "screen-down" , KEYS_SCREEN_DOWN , 0 , ' ' },
+ { "screen-left" , KEYS_SCREEN_LEFT , 0 , 0 },
+ { "screen-right" , KEYS_SCREEN_RIGHT , 0 , 0 },
+ { "line-up" , KEYS_LINE_UP , 0 , FL_Up },
+ { "line-down" , KEYS_LINE_DOWN , 0 , FL_Down },
+ { "left" , KEYS_LEFT , 0 , FL_Left },
+ { "right" , KEYS_RIGHT , 0 , FL_Right },
+ { "top" , KEYS_TOP , 0 , FL_Home },
+ { "bottom" , KEYS_BOTTOM , 0 , FL_End },
};
static Dlist *bindings;
@@ -172,20 +192,25 @@ KeysCommand_t Keys::getKeyCmd()
{
KeysCommand_t ret = KEYS_NOP;
KeyBinding_t keyNode;
- // We're only interested in some flags
- keyNode.modifier = fltk::event_state() &
- (fltk::SHIFT | fltk::CTRL | fltk::ALT | fltk::META);
-
- if (keyNode.modifier == fltk::SHIFT &&
- ispunct(fltk::event_text()[0])) {
- // Get key code for a shifted character
- keyNode.key = fltk::event_text()[0];
- keyNode.modifier = 0;
+
+ keyNode.modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL |FL_ALT|FL_META);
+ if (iscntrl(Fl::event_text()[0])) {
+ keyNode.key = Fl::event_key();
} else {
- keyNode.key = fltk::event_key();
+ const char *beyond = Fl::event_text() + Fl::event_length();
+ keyNode.key = a_Utf8_decode(Fl::event_text(), beyond, NULL);
+
+ /* BUG: The idea is to drop the modifiers if their use results in a
+ * different character (e.g., if shift-8 gives '*', drop the shift,
+ * but if ctrl-6 gives '6', keep the ctrl), but we have to compare a
+ * keysym with a Unicode codepoint, which only works for characters
+ * below U+0100 (those known to latin-1).
+ */
+ if (keyNode.key != Fl::event_key())
+ keyNode.modifier = 0;
}
-
- _MSG("getKeyCmd: key=%d, mod=%d\n", keyNode.key, keyNode.modifier);
+ _MSG("getKeyCmd: evkey=0x%x evtext=\'%s\' key=0x%x, mod=0x%x\n",
+ Fl::event_key(), Fl::event_text(), keyNode.key, keyNode.modifier);
void *data = dList_find_sorted(bindings, &keyNode, nodeByKeyCmp);
if (data)
ret = ((KeyBinding_t*)data)->cmd;
@@ -311,8 +336,11 @@ void Keys::parseKey(char *key, char *commandName)
// Get key code
if (!key[1]) {
keycode = *key;
+ } else if (a_Utf8_char_count(keystr, strlen(keystr)) == 1) {
+ const char *beyond = keystr + strlen(keystr);
+ keycode = a_Utf8_decode(keystr, beyond, NULL);
} else if (key[0] == '0' && key[1] == 'x') {
- /* keysym. For details on values reported, see fltk's fltk/events.h */
+ /* keysym */
keycode = strtol(key, NULL, 0x10);
} else if ((st = getKeyCode(keystr)) == -1) {
MSG("Keys::parseKey unknown keyname: %s\n", keystr);
diff --git a/src/keys.hh b/src/keys.hh
index d234838c..d3a5d586 100644
--- a/src/keys.hh
+++ b/src/keys.hh
@@ -27,7 +27,6 @@ typedef enum {
KEYS_FIND,
KEYS_WEBSEARCH,
KEYS_BOOKMARKS,
- KEYS_FULLSCREEN,
KEYS_RELOAD,
KEYS_STOP,
KEYS_SAVE,
@@ -40,6 +39,8 @@ typedef enum {
KEYS_HOME,
KEYS_SCREEN_UP,
KEYS_SCREEN_DOWN,
+ KEYS_SCREEN_LEFT,
+ KEYS_SCREEN_RIGHT,
KEYS_LINE_UP,
KEYS_LINE_DOWN,
KEYS_LEFT,
diff --git a/src/keysrc b/src/keysrc
index 3f53674f..706917df 100644
--- a/src/keysrc
+++ b/src/keysrc
@@ -6,10 +6,16 @@
# The commented-out bindings below show the defaults built into Dillo.
#
# Modifiers recognized: "Shift", "Ctrl", "Alt", "Meta".
+# (OS X: Use "Meta" for Command)
+#
# Key names recognized: "Backspace", "Delete", "Down", "End", "Esc",
# "F1" through "F12", "Home", "Insert", "Left", "PageDown", "PageUp",
# "Print", "Return", "Right", "Space", "Tab", "Up".
#
+# Multimedia keys: "Back", "Favorites", "Forward", "HomePage", "Mail",
+# "MediaNext", "MediaPlay", "MediaPrev", "MediaStop", "Refresh", "Search",
+# "Sleep", "Stop", "VolumeDown", "VolumeMute", VolumeUp".
+#
# If Dillo is running under X11, keys whose names are not recognized can
# be specified using their keysym value in hexadecimal. Use xev to get
# the keysym. Example rule: "0x1008ff27 = forward".
@@ -27,14 +33,13 @@
# "close-tab" closes the current tab.
# Note that this closes the browser window if there is only one tab.
-#<ctrl>q = close-tab
+#<ctrl>w = close-tab
# "close-all" closes all tabs/windows and exits.
-#<alt>q = close-all
+#<ctrl>q = close-all
# "left-tab" and "right-tab" switch to the left/right of the current tab.
-# *** NOT HOOKED UP YET ***
-# <shift>tab = left-tab
+# <ctrl><shift>tab = left-tab
# <ctrl>tab = right-tab
# "back" and "forward" move back/forward through the browser history.
@@ -52,7 +57,7 @@
# "find" lets you search for a text string on the current page.
#<ctrl>f = find
-# "hide-panels" hides the findbar.
+# "hide-panels" hides the findbar if present, control panels if not.
#esc = hide-panels
# "websearch" lets you send a text string to the search engine that you
@@ -62,9 +67,6 @@
# go to your "bookmarks".
#<ctrl>b = bookmarks
-# "fullscreen" hides/shows the panels at the top and bottom of a dillo window.
-#<ctrl>space = fullscreen
-
# "file-menu" pops up the file menu.
#<alt>f = file-menu
@@ -87,6 +89,10 @@
#pagedown = screen-down
#space = screen-down
+#(screen-left has no default binding)
+
+#(screen-right has no default binding)
+
#up = line-up
#down = line-down
diff --git a/src/menu.cc b/src/menu.cc
index d802bddb..658b89bc 100644
--- a/src/menu.cc
+++ b/src/menu.cc
@@ -11,11 +11,8 @@
// Functions/Methods for menus
-#include <fltk/events.h>
-#include <fltk/PopupMenu.h>
-#include <fltk/Item.h>
-#include <fltk/ToggleItem.h>
-#include <fltk/Divider.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Menu_Item.H>
#include "lout/misc.hh" /* SimpleVector */
#include "msg.h"
@@ -27,8 +24,6 @@
#include "keys.hh"
#include "timeout.hh"
-using namespace fltk;
-
/*
* Local data
*/
@@ -38,54 +33,27 @@ using namespace fltk;
static DilloUrl *popup_url = NULL;
// Weak reference to the popup's bw
static BrowserWindow *popup_bw = NULL;
-// Where to place the filemenu popup
+static void *popup_form = NULL;
+// Where to place the popup
static int popup_x, popup_y;
// History popup direction (-1 = back, 1 = forward).
static int history_direction = -1;
// History popup, list of URL-indexes.
static int *history_list = NULL;
-/*
- * Local sub class.
- * Used to add the hint for history popup menus, and to remember
- * the mouse button pressed over a menu item.
- */
-class CustItem : public Item {
- int EventButton;
-public:
- CustItem (const char* label) : Item(label) { EventButton = 0; };
- int button () { return EventButton; };
- void draw();
- int handle(int e) {
- EventButton = event_button();
- return Item::handle(e);
- }
-};
-
-/*
- * This adds a call to a_UIcmd_set_msg() to show the URL in the status bar
- * TODO: erase the URL on popup close.
- */
-void CustItem::draw() {
- const DilloUrl *url;
- if (flags() & SELECTED) {
- url = a_History_get_url(history_list[(VOIDP2INT(user_data()))-1]);
- a_UIcmd_set_msg(popup_bw, "%s", URL_STR(url));
- }
- Item::draw();
+//--------------------------------------------------------------------------
+static void Menu_nop_cb(Fl_Widget*, void*)
+{
}
-
-//--------------------------------------------------------------------------
/*
* Static function for File menu callbacks.
*/
-static void filemenu_cb(Widget *wid, void *data)
+static void filemenu_cb(Fl_Widget*, void *data)
{
if (strcmp((char*)data, "nw") == 0) {
- UI *ui = (UI*)popup_bw->ui;
- a_UIcmd_browser_window_new(ui->w(), ui->h(), 0, popup_bw);
+ a_UIcmd_open_url_nw(popup_bw, NULL);
} else if (strcmp((char*)data, "nt") == 0) {
a_UIcmd_open_url_nt(popup_bw, NULL, 1);
} else if (strcmp((char*)data, "of") == 0) {
@@ -100,13 +68,13 @@ static void filemenu_cb(Widget *wid, void *data)
}
-static void Menu_copy_urlstr_cb(Widget *)
+static void Menu_copy_urlstr_cb(Fl_Widget*, void*)
{
if (popup_url)
a_UIcmd_copy_urlstr(popup_bw, URL_STR(popup_url));
}
-static void Menu_link_cb(Widget*, void *user_data)
+static void Menu_link_cb(Fl_Widget*, void *user_data)
{
DilloUrl *url = (DilloUrl *) user_data ;
_MSG("Menu_link_cb: click! :-)\n");
@@ -118,7 +86,7 @@ static void Menu_link_cb(Widget*, void *user_data)
/*
* Open URL
*/
-static void Menu_open_url_cb(Widget* )
+static void Menu_open_url_cb(Fl_Widget*, void*)
{
_MSG("Open URL cb: click! :-)\n");
a_UIcmd_open_url(popup_bw, popup_url);
@@ -127,7 +95,7 @@ static void Menu_open_url_cb(Widget* )
/*
* Open URL in new window
*/
-static void Menu_open_url_nw_cb(Widget* )
+static void Menu_open_url_nw_cb(Fl_Widget*, void*)
{
_MSG("Open URL in new window cb: click! :-)\n");
a_UIcmd_open_url_nw(popup_bw, popup_url);
@@ -136,17 +104,17 @@ static void Menu_open_url_nw_cb(Widget* )
/*
* Open URL in new Tab
*/
-static void Menu_open_url_nt_cb(Widget* )
+static void Menu_open_url_nt_cb(Fl_Widget*, void*)
{
int focus = prefs.focus_new_tab ? 1 : 0;
- if (event_state(SHIFT)) focus = !focus;
+ if (Fl::event_state(FL_SHIFT)) focus = !focus;
a_UIcmd_open_url_nt(popup_bw, popup_url, focus);
}
/*
* Add bookmark
*/
-static void Menu_add_bookmark_cb(Widget* )
+static void Menu_add_bookmark_cb(Fl_Widget*, void*)
{
a_UIcmd_add_bookmark(popup_bw, popup_url);
}
@@ -154,15 +122,15 @@ static void Menu_add_bookmark_cb(Widget* )
/*
* Find text
*/
-static void Menu_find_text_cb(Widget* )
+static void Menu_find_text_cb(Fl_Widget*, void*)
{
- ((UI *)popup_bw->ui)->set_findbar_visibility(1);
+ ((UI *)popup_bw->ui)->findbar_toggle(1);
}
/*
* Save link
*/
-static void Menu_save_link_cb(Widget* )
+static void Menu_save_link_cb(Fl_Widget*, void*)
{
a_UIcmd_save_link(popup_bw, popup_url);
}
@@ -170,7 +138,7 @@ static void Menu_save_link_cb(Widget* )
/*
* Save current page
*/
-static void Menu_save_page_cb(Widget* )
+static void Menu_save_page_cb(Fl_Widget*, void*)
{
a_UIcmd_save(popup_bw);
}
@@ -178,7 +146,7 @@ static void Menu_save_page_cb(Widget* )
/*
* View current page source
*/
-static void Menu_view_page_source_cb(Widget* )
+static void Menu_view_page_source_cb(Fl_Widget*, void*)
{
a_UIcmd_view_page_source(popup_bw, popup_url);
}
@@ -186,7 +154,7 @@ static void Menu_view_page_source_cb(Widget* )
/*
* View current page's bugs
*/
-static void Menu_view_page_bugs_cb(Widget* )
+static void Menu_view_page_bugs_cb(Fl_Widget*, void*)
{
a_UIcmd_view_page_bugs(popup_bw);
}
@@ -194,7 +162,7 @@ static void Menu_view_page_bugs_cb(Widget* )
/*
* Load images on current page that match URL pattern
*/
-static void Menu_load_images_cb(Widget*, void *user_data)
+static void Menu_load_images_cb(Fl_Widget*, void *user_data)
{
DilloUrl *page_url = (DilloUrl *) user_data;
void *doc = a_Bw_get_url_doc(popup_bw, page_url);
@@ -206,39 +174,38 @@ static void Menu_load_images_cb(Widget*, void *user_data)
/*
* Submit form
*/
-static void Menu_form_submit_cb(Widget*, void *v_form)
+static void Menu_form_submit_cb(Fl_Widget*, void*)
{
void *doc = a_Bw_get_url_doc(popup_bw, popup_url);
if (doc)
- a_Html_form_submit(doc, v_form);
+ a_Html_form_submit(doc, popup_form);
}
/*
* Reset form
*/
-static void Menu_form_reset_cb(Widget*, void *v_form)
+static void Menu_form_reset_cb(Fl_Widget*, void*)
{
void *doc = a_Bw_get_url_doc(popup_bw, popup_url);
if (doc)
- a_Html_form_reset(doc, v_form);
+ a_Html_form_reset(doc, popup_form);
}
/*
* Toggle display of 'hidden' form controls.
*/
-static void Menu_form_hiddens_cb(Widget *w, void *user_data)
+static void Menu_form_hiddens_cb(Fl_Widget*, void *user_data)
{
- void *v_form = w->parent()->user_data();
bool visible = *((bool *) user_data);
void *doc = a_Bw_get_url_doc(popup_bw, popup_url);
if (doc)
- a_Html_form_display_hiddens(doc, v_form, !visible);
+ a_Html_form_display_hiddens(doc, popup_form, !visible);
}
-static void Menu_stylesheet_cb(Widget *w, void *vUrl)
+static void Menu_stylesheet_cb(Fl_Widget*, void *vUrl)
{
const DilloUrl *url = (const DilloUrl *) vUrl;
a_UIcmd_open_url(popup_bw, url);
@@ -247,7 +214,7 @@ static void Menu_stylesheet_cb(Widget *w, void *vUrl)
/*
* Validate URL with the W3C
*/
-static void Menu_bugmeter_validate_w3c_cb(Widget* )
+static void Menu_bugmeter_validate_w3c_cb(Fl_Widget*, void*)
{
Dstr *dstr = dStr_sized_new(128);
@@ -260,7 +227,7 @@ static void Menu_bugmeter_validate_w3c_cb(Widget* )
/*
* Validate URL with the WDG
*/
-static void Menu_bugmeter_validate_wdg_cb(Widget* )
+static void Menu_bugmeter_validate_wdg_cb(Fl_Widget*, void*)
{
Dstr *dstr = dStr_sized_new(128);
@@ -274,7 +241,7 @@ static void Menu_bugmeter_validate_wdg_cb(Widget* )
/*
* Show info page for the bug meter
*/
-static void Menu_bugmeter_about_cb(Widget* )
+static void Menu_bugmeter_about_cb(Fl_Widget*, void*)
{
a_UIcmd_open_urlstr(popup_bw, "http://www.dillo.org/help/bug_meter.html");
}
@@ -283,23 +250,23 @@ static void Menu_bugmeter_about_cb(Widget* )
* Navigation History callback.
* Go to selected URL.
*/
-static void Menu_history_cb(Widget *wid, void *data)
+static void Menu_history_cb(Fl_Widget*, void *data)
{
- int mb = ((CustItem*)wid)->button();
+ int mb = Fl::event_button();
int offset = history_direction * VOIDP2INT(data);
const DilloUrl *url = a_History_get_url(history_list[VOIDP2INT(data)-1]);
- if (mb == 2) {
+ if (mb == 1) {
+ a_UIcmd_nav_jump(popup_bw, offset, 0);
+ } else if (mb == 2) {
// Middle button, open in a new window/tab
if (prefs.middle_click_opens_new_tab) {
int focus = prefs.focus_new_tab ? 1 : 0;
- if (event_state(SHIFT)) focus = !focus;
+ if (Fl::event_state(FL_SHIFT)) focus = !focus;
a_UIcmd_open_url_nt(popup_bw, url, focus);
} else {
a_UIcmd_open_url_nw(popup_bw, url);
}
- } else {
- a_UIcmd_nav_jump(popup_bw, offset, 0);
}
}
@@ -311,18 +278,10 @@ static void Menu_history_cb(Widget *wid, void *data)
*/
static void Menu_popup_cb(void *data)
{
- ((PopupMenu *)data)->popup();
- a_Timeout_remove();
-}
+ const Fl_Menu_Item *m = ((Fl_Menu_Item *)data)->popup(popup_x, popup_y);
-/*
- * Same as above but with coordinates.
- */
-static void Menu_popup_cb2(void *data)
-{
- Menu *m = (Menu *)data;
- m->value(-1);
- m->popup(Rectangle(popup_x,popup_y,m->w(),m->h()), m->label());
+ if (m && m->callback())
+ m->do_callback((Fl_Widget *)data);
a_Timeout_remove();
}
@@ -334,65 +293,49 @@ void a_Menu_page_popup(BrowserWindow *bw, const DilloUrl *url,
{
lout::misc::SimpleVector <DilloUrl*> *cssUrls =
(lout::misc::SimpleVector <DilloUrl*> *) v_cssUrls;
- Item *i;
- int j;
- // One menu for every browser window
- static PopupMenu *pm = 0;
- // Active/inactive control.
- static Item *view_page_bugs_item = 0, *view_source_item = 0;
- static ItemGroup *stylesheets = 0;
-
+ int j = 0;
+
+ static Fl_Menu_Item *stylesheets = NULL;
+ static Fl_Menu_Item pm[] = {
+ {"View page source", 0, Menu_view_page_source_cb,0,0,0,0,0,0},
+ {"View page bugs", 0, Menu_view_page_bugs_cb,0,0,0,0,0,0},
+ {"View stylesheets", 0, Menu_nop_cb,0,FL_SUBMENU_POINTER|FL_MENU_DIVIDER,
+ 0,0,0,0},
+ {"Bookmark this page", 0,Menu_add_bookmark_cb,0,FL_MENU_DIVIDER,0,0,0,0},
+ {"Find text", 0, Menu_find_text_cb,0,0,0,0,0,0},
+ {"Save page as...", 0, Menu_save_page_cb,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0}
+ };
+
+ popup_x = Fl::event_x();
+ popup_y = Fl::event_y();
popup_bw = bw;
a_Url_free(popup_url);
popup_url = a_Url_dup(url);
- if (!pm) {
- pm = new PopupMenu(0,0,0,0,"&PAGE OPTIONS");
- pm->begin();
- i = view_source_item = new Item("View page Source");
- i->callback(Menu_view_page_source_cb);
- i = view_page_bugs_item = new Item("View page Bugs");
- i->callback(Menu_view_page_bugs_cb);
- stylesheets = new ItemGroup("View Stylesheets");
- new Divider();
- i = new Item("Bookmark this page");
- i->callback(Menu_add_bookmark_cb);
- new Divider();
- i = new Item("Find Text");
- i->callback(Menu_find_text_cb);
- //i->shortcut(CTRL+'f');
- i = new Item("Jump to...");
- i->deactivate();
- new Divider();
- i = new Item("Save page As...");
- i->callback(Menu_save_page_cb);
-
- pm->type(PopupMenu::POPUP123);
- pm->end();
- }
-
- if (has_bugs == TRUE)
- view_page_bugs_item->activate();
- else
- view_page_bugs_item->deactivate();
+ has_bugs == TRUE ? pm[1].activate() : pm[1].deactivate();
if (strncmp(URL_STR(url), "dpi:/vsource/", 13) == 0)
- view_source_item->deactivate();
+ pm[0].deactivate();
else
- view_source_item->activate();
-
- int n = stylesheets->children();
- for (j = 0; j < n; j++) {
- /* get rid of the old ones */
- Widget *child = stylesheets->child(0);
- dFree((char *)child->label());
- a_Url_free((DilloUrl *)child->user_data());
- delete child;
+ pm[0].activate();
+
+ if (stylesheets) {
+ while (stylesheets[j].text) {
+ dFree((char *) stylesheets[j].label());
+ a_Url_free((DilloUrl *) stylesheets[j].user_data());
+ j++;
+ }
+ delete [] stylesheets;
+ stylesheets = NULL;
}
if (cssUrls && cssUrls->size () > 0) {
- stylesheets->activate();
+ stylesheets = new Fl_Menu_Item[cssUrls->size() + 1];
+ memset(stylesheets, '\0', sizeof(Fl_Menu_Item[cssUrls->size() + 1]));
+
for (j = 0; j < cssUrls->size(); j++) {
+
/* may want ability to Load individual unloaded stylesheets as well */
const char *action = "View ";
DilloUrl *url = cssUrls->get(j);
@@ -411,17 +354,17 @@ void a_Menu_page_popup(BrowserWindow *bw, const DilloUrl *url,
label = dStrconcat(action, url_str, NULL);
}
- i = new Item(label);
- i->set_flag(RAW_LABEL);
- i->user_data(a_Url_dup(url));
- i->callback(Menu_stylesheet_cb);
- stylesheets->add(i);
+ stylesheets[j].label(FL_NORMAL_LABEL, label);
+ stylesheets[j].callback(Menu_stylesheet_cb, a_Url_dup(url));
}
+
+ pm[2].user_data(stylesheets);
+ pm[2].activate();
} else {
- stylesheets->deactivate();
+ pm[2].deactivate();
}
- a_Timeout_add(0.0, Menu_popup_cb, (void *)pm);
+ a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
}
/*
@@ -429,35 +372,23 @@ void a_Menu_page_popup(BrowserWindow *bw, const DilloUrl *url,
*/
void a_Menu_link_popup(BrowserWindow *bw, const DilloUrl *url)
{
- // One menu for every browser window
- static PopupMenu *pm = 0;
-
+ static Fl_Menu_Item pm[] = {
+ {"Open link in new tab", 0, Menu_open_url_nt_cb,0,0,0,0,0,0},
+ {"Open link in new window", 0, Menu_open_url_nw_cb,0,FL_MENU_DIVIDER,0,0,
+ 0,0},
+ {"Bookmark this link", 0, Menu_add_bookmark_cb,0,0,0,0,0,0},
+ {"Copy link location", 0, Menu_copy_urlstr_cb,0,FL_MENU_DIVIDER,0,0,0,0},
+ {"Save link as...", 0, Menu_save_link_cb,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0}
+ };
+
+ popup_x = Fl::event_x();
+ popup_y = Fl::event_y();
popup_bw = bw;
a_Url_free(popup_url);
popup_url = a_Url_dup(url);
- if (!pm) {
- Item *i;
- pm = new PopupMenu(0,0,0,0,"&LINK OPTIONS");
- //pm->callback(Menu_link_cb, url);
- pm->begin();
- i = new Item("Open Link in New Window");
- i->callback(Menu_open_url_nw_cb);
- i = new Item("Open Link in New Tab");
- i->callback(Menu_open_url_nt_cb);
- new Divider();
- i = new Item("Bookmark this Link");
- i->callback(Menu_add_bookmark_cb);
- i = new Item("Copy Link location");
- i->callback(Menu_copy_urlstr_cb);
- new Divider();
- i = new Item("Save Link As...");
- i->callback(Menu_save_link_cb);
-
- pm->type(PopupMenu::POPUP123);
- pm->end();
- }
- a_Timeout_add(0.0, Menu_popup_cb, (void *)pm);
+ a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
}
/*
@@ -467,14 +398,23 @@ void a_Menu_image_popup(BrowserWindow *bw, const DilloUrl *url,
bool_t loaded_img, DilloUrl *page_url,
DilloUrl *link_url)
{
- // One menu for every browser window
- static PopupMenu *pm = 0;
- // Active/inactive control.
- static Item *link_menuitem = 0;
- static Item *load_img_menuitem = 0;
static DilloUrl *popup_page_url = NULL;
static DilloUrl *popup_link_url = NULL;
-
+ static Fl_Menu_Item pm[] = {
+ {"Isolate image", 0, Menu_open_url_cb,0,0,0,0,0,0},
+ {"Open image in new tab", 0, Menu_open_url_nt_cb,0,0,0,0,0,0},
+ {"Open image in new window", 0, Menu_open_url_nw_cb, 0, FL_MENU_DIVIDER,
+ 0,0,0,0},
+ {"Load image", 0, Menu_load_images_cb,0,0,0,0,0,0},
+ {"Bookmark this image", 0, Menu_add_bookmark_cb,0,0,0,0,0,0},
+ {"Copy image location", 0,Menu_copy_urlstr_cb,0,FL_MENU_DIVIDER,0,0,0,0},
+ {"Save image as...", 0, Menu_save_link_cb, 0, FL_MENU_DIVIDER,0,0,0,0},
+ {"Link menu", 0, Menu_link_cb,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0}
+ };
+
+ popup_x = Fl::event_x();
+ popup_y = Fl::event_y();
popup_bw = bw;
a_Url_free(popup_url);
popup_url = a_Url_dup(url);
@@ -483,49 +423,22 @@ void a_Menu_image_popup(BrowserWindow *bw, const DilloUrl *url,
a_Url_free(popup_link_url);
popup_link_url = a_Url_dup(link_url);
- if (!pm) {
- Item *i;
- pm = new PopupMenu(0,0,0,0,"&IMAGE OPTIONS");
- pm->begin();
- i = new Item("Isolate Image");
- i->callback(Menu_open_url_cb);
- i = new Item("Open Image in New Window");
- i->callback(Menu_open_url_nw_cb);
- i = new Item("Open Image in New Tab");
- i->callback(Menu_open_url_nt_cb);
- new Divider();
- i = load_img_menuitem = new Item("Load image");
- i->callback(Menu_load_images_cb);
- i = new Item("Bookmark this Image");
- i->callback(Menu_add_bookmark_cb);
- i = new Item("Copy Image location");
- i->callback(Menu_copy_urlstr_cb);
- new Divider();
- i = new Item("Save Image As...");
- i->callback(Menu_save_link_cb);
- new Divider();
- i = link_menuitem = new Item("Link menu");
- i->callback(Menu_link_cb);
-
- pm->type(PopupMenu::POPUP123);
- pm->end();
- }
if (loaded_img) {
- load_img_menuitem->deactivate();
+ pm[3].deactivate();
} else {
- load_img_menuitem->activate();
- load_img_menuitem->user_data(popup_page_url);
+ pm[3].activate();
+ pm[3].user_data(popup_page_url);
}
if (link_url) {
- link_menuitem->user_data(popup_link_url);
- link_menuitem->activate();
+ pm[7].activate();
+ pm[7].user_data(popup_link_url);
} else {
- link_menuitem->deactivate();
+ pm[7].deactivate();
}
- a_Timeout_add(0.0, Menu_popup_cb, (void *)pm);
+ a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
}
/*
@@ -534,31 +447,25 @@ void a_Menu_image_popup(BrowserWindow *bw, const DilloUrl *url,
void a_Menu_form_popup(BrowserWindow *bw, const DilloUrl *page_url,
void *formptr, bool_t hidvis)
{
- static PopupMenu *pm = 0;
- static Item *hiddens_item = 0;
static bool hiddens_visible;
-
+ static Fl_Menu_Item pm[] = {
+ {"Submit form", 0, Menu_form_submit_cb,0,0,0,0,0,0},
+ {"Reset form", 0, Menu_form_reset_cb,0,0,0,0,0,0},
+ {0, 0, Menu_form_hiddens_cb, &hiddens_visible, 0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0}
+ };
+
+ popup_x = Fl::event_x();
+ popup_y = Fl::event_y();
popup_bw = bw;
a_Url_free(popup_url);
popup_url = a_Url_dup(page_url);
- if (!pm) {
- Item *i;
- pm = new PopupMenu(0,0,0,0,"FORM OPTIONS");
- pm->add(i = new Item("Submit form"));
- i->callback(Menu_form_submit_cb);
- pm->add(i = new Item("Reset form"));
- i->callback(Menu_form_reset_cb);
- pm->add(hiddens_item = new Item(""));
- hiddens_item->callback(Menu_form_hiddens_cb);
- hiddens_item->user_data(&hiddens_visible);
- pm->type(PopupMenu::POPUP123);
- }
- pm->user_data(formptr);
+ popup_form = formptr;
hiddens_visible = hidvis;
- hiddens_item->label(hiddens_visible ? "Hide hiddens": "Show hiddens");
+ pm[2].label(hiddens_visible ? "Hide hiddens": "Show hiddens");
- a_Timeout_add(0.0, Menu_popup_cb, (void *)pm);
+ a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
}
/*
@@ -566,44 +473,32 @@ void a_Menu_form_popup(BrowserWindow *bw, const DilloUrl *page_url,
*/
void a_Menu_file_popup(BrowserWindow *bw, void *v_wid)
{
- UI *ui = (UI *)bw->ui;
- Widget *wid = (Widget*)v_wid;
- // One menu for every browser window
- static PopupMenu *pm = 0;
+ Fl_Widget *wid = (Fl_Widget*)v_wid;
+
+ static Fl_Menu_Item pm[] = {
+ {"New tab", Keys::getShortcut(KEYS_NEW_TAB), filemenu_cb,
+ (void*)"nt",0,0,0,0,0},
+ {"New window", Keys::getShortcut(KEYS_NEW_WINDOW), filemenu_cb,
+ (void*)"nw", FL_MENU_DIVIDER,0,0,0,0},
+ {"Open file...", Keys::getShortcut(KEYS_OPEN), filemenu_cb,
+ (void*)"of",0,0,0,0,0},
+ {"Open URL...", Keys::getShortcut(KEYS_GOTO), filemenu_cb,
+ (void*)"ou",0,0,0,0,0},
+ {"Close", Keys::getShortcut(KEYS_CLOSE_TAB), filemenu_cb,
+ (void*)"cw", FL_MENU_DIVIDER,0,0,0,0},
+ {"Exit Dillo", Keys::getShortcut(KEYS_CLOSE_ALL), filemenu_cb,
+ (void*)"ed",0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0}
+ };
popup_bw = bw;
popup_x = wid->x();
- popup_y = wid->y() + wid->h() +
- // WORKAROUND: ?? wid->y() doesn't count tabs ??
- (((Group*)ui->tabs())->children() > 1 ? 20 : 0);
+ popup_y = wid->y() + wid->h();
a_Url_free(popup_url);
popup_url = NULL;
- if (!pm) {
- int shortcut;
- Item *i;
- pm = new PopupMenu(0,0,0,0,"File");
- pm->begin();
- shortcut = Keys::getShortcut(KEYS_NEW_WINDOW);
- i = new Item("New Window", shortcut, filemenu_cb, (void*)"nw");
- shortcut = Keys::getShortcut(KEYS_NEW_TAB);
- i = new Item("New Tab", shortcut, filemenu_cb, (void*)"nt");
- new Divider();
- shortcut = Keys::getShortcut(KEYS_OPEN);
- i = new Item("Open File...", shortcut, filemenu_cb, (void*)"of");
- shortcut = Keys::getShortcut(KEYS_GOTO);
- i = new Item("Open URL...", shortcut, filemenu_cb, (void*)"ou");
- shortcut = Keys::getShortcut(KEYS_CLOSE_TAB);
- i = new Item("Close", shortcut, filemenu_cb, (void*)"cw");
- new Divider();
- shortcut = Keys::getShortcut(KEYS_CLOSE_ALL);
- i = new Item("Exit Dillo", shortcut, filemenu_cb, (void*)"ed");
- pm->type(PopupMenu::POPUP123);
- pm->end();
- }
-
- pm->label(wid->visible() ? NULL : "File");
- a_Timeout_add(0.0, Menu_popup_cb2, (void *)pm);
+ //pm->label(wid->visible() ? NULL : "File");
+ a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
}
/*
@@ -611,28 +506,21 @@ void a_Menu_file_popup(BrowserWindow *bw, void *v_wid)
*/
void a_Menu_bugmeter_popup(BrowserWindow *bw, const DilloUrl *url)
{
- // One menu for every browser window
- static PopupMenu *pm = 0;
+ static Fl_Menu_Item pm[] = {
+ {"Validate URL with W3C", 0, Menu_bugmeter_validate_w3c_cb,0,0,0,0,0,0},
+ {"Validate URL with WDG", 0, Menu_bugmeter_validate_wdg_cb, 0,
+ FL_MENU_DIVIDER,0,0,0,0},
+ {"About bug meter", 0, Menu_bugmeter_about_cb,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0}
+ };
+ popup_x = Fl::event_x();
+ popup_y = Fl::event_y();
popup_bw = bw;
a_Url_free(popup_url);
popup_url = a_Url_dup(url);
- if (!pm) {
- Item *i;
- pm = new PopupMenu(0,0,0,0,"&BUG METER OPTIONS");
- pm->begin();
- i = new Item("Validate URL with W3C");
- i->callback(Menu_bugmeter_validate_w3c_cb);
- i = new Item("Validate URL with WDG");
- i->callback(Menu_bugmeter_validate_wdg_cb);
- new Divider();
- i = new Item("About Bug Meter...");
- i->callback(Menu_bugmeter_about_cb);
- pm->type(PopupMenu::POPUP123);
- pm->end();
- }
- pm->popup();
+ a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
}
/*
@@ -640,67 +528,82 @@ void a_Menu_bugmeter_popup(BrowserWindow *bw, const DilloUrl *url)
*
* direction: {backward = -1, forward = 1}
*/
-void a_Menu_history_popup(BrowserWindow *bw, int direction)
+void a_Menu_history_popup(BrowserWindow *bw, int x, int y, int direction)
{
- static PopupMenu *pm = 0;
- Item *it;
- int i;
+ static Fl_Menu_Item *pm = 0;
+ int i, n;
popup_bw = bw;
+ popup_x = x;
+ popup_y = y;
history_direction = direction;
// TODO: hook popdown event with delete or similar.
if (pm)
- delete(pm);
+ delete [] pm;
if (history_list)
dFree(history_list);
- if (direction == -1) {
- pm = new PopupMenu(0,0,0,0, "&PREVIOUS PAGES");
- } else {
- pm = new PopupMenu(0,0,0,0, "&FOLLOWING PAGES");
- }
-
// Get a list of URLs for this popup
history_list = a_UIcmd_get_history(bw, direction);
- pm->begin();
- for (i = 0; history_list[i] != -1; i += 1) {
- // TODO: restrict title size
- it = new CustItem(a_History_get_title(history_list[i], 1));
- it->callback(Menu_history_cb, INT2VOIDP(i+1));
- }
- pm->type(PopupMenu::POPUP123);
- pm->end();
+ for (n = 0; history_list[n] != -1; n++)
+ ;
- pm->popup();
+ pm = new Fl_Menu_Item[n + 1];
+ memset(pm, '\0', sizeof(Fl_Menu_Item[n + 1]));
+
+ for (i = 0; i < n; i++) {
+ pm[i].label(FL_NORMAL_LABEL, a_History_get_title(history_list[i], 1));
+ pm[i].callback(Menu_history_cb, INT2VOIDP(i+1));
+ }
+ a_Timeout_add(0.0, Menu_popup_cb, (void*)pm);
}
/*
* Toggle use of remote stylesheets
*/
-static void Menu_remote_css_cb(Widget *wid)
+static void Menu_remote_css_cb(Fl_Widget *wid, void*)
{
- _MSG("Menu_remote_css_cb\n");
- prefs.load_stylesheets = wid->state() ? 1 : 0;
+ Fl_Menu_Item *item = (Fl_Menu_Item*) wid;
+
+ item->flags ^= FL_MENU_VALUE;
+ prefs.load_stylesheets = item->flags & FL_MENU_VALUE ? 1 : 0;
a_UIcmd_repush(popup_bw);
}
/*
* Toggle use of embedded CSS style
*/
-static void Menu_embedded_css_cb(Widget *wid)
+static void Menu_embedded_css_cb(Fl_Widget *wid, void*)
{
- prefs.parse_embedded_css = wid->state() ? 1 : 0;
+ Fl_Menu_Item *item = (Fl_Menu_Item*) wid;
+
+ item->flags ^= FL_MENU_VALUE;
+ prefs.parse_embedded_css = item->flags & FL_MENU_VALUE ? 1 : 0;
a_UIcmd_repush(popup_bw);
}
+static void Menu_panel_change_cb(Fl_Widget*, void *user_data)
+{
+ UI *ui = (UI*)popup_bw->ui;
+
+ if (VOIDP2INT(user_data) == 10) /* small icons */
+ ui->change_panel(ui->get_panelsize(), !ui->get_smallicons());
+ else
+ ui->change_panel(VOIDP2INT(user_data), ui->get_smallicons());
+}
+
/*
* Toggle loading of images -- and load them if enabling.
*/
-static void Menu_imgload_toggle_cb(Widget *wid)
+static void Menu_imgload_toggle_cb(Fl_Widget *wid, void*)
{
- if ((prefs.load_images = wid->state() ? 1 : 0)) {
+ Fl_Menu_Item *item = (Fl_Menu_Item*) wid;
+
+ item->flags ^= FL_MENU_VALUE;
+
+ if ((prefs.load_images = item->flags & FL_MENU_VALUE ? 1 : 0)) {
void *doc = a_Bw_get_current_doc(popup_bw);
if (doc) {
@@ -713,33 +616,44 @@ static void Menu_imgload_toggle_cb(Widget *wid)
/*
* Tools popup menu (construction & popup)
*/
-void a_Menu_tools_popup(BrowserWindow *bw, void *v_wid)
-{
- // One menu shared by every browser window
- static PopupMenu *pm = NULL;
- Widget *wid = (Widget*)v_wid;
- Item *it;
+void a_Menu_tools_popup(BrowserWindow *bw, int x, int y)
+{
+ const Fl_Menu_Item *item;
+ UI *ui = (UI*)bw->ui;
+
+ static Fl_Menu_Item pm[] = {
+ {"Use remote CSS", 0, Menu_remote_css_cb, 0, FL_MENU_TOGGLE,0,0,0,0},
+ {"Use embedded CSS", 0, Menu_embedded_css_cb, 0,
+ FL_MENU_TOGGLE|FL_MENU_DIVIDER,0,0,0,0},
+ {"Load images", 0, Menu_imgload_toggle_cb, 0,
+ FL_MENU_TOGGLE|FL_MENU_DIVIDER,0,0,0,0},
+ {"Panel size", 0, Menu_nop_cb, (void*)"Submenu1", FL_SUBMENU,0,0,0,0},
+ {"tiny", 0,Menu_panel_change_cb,(void*)0,FL_MENU_RADIO,0,0,0,0},
+ {"small", 0,Menu_panel_change_cb,(void*)1,FL_MENU_RADIO,0,0,0,0},
+ {"medium",0,Menu_panel_change_cb,(void*)2,
+ FL_MENU_RADIO|FL_MENU_DIVIDER,0,0,0,0},
+ {"small icons", 0,Menu_panel_change_cb,(void*)10,
+ FL_MENU_TOGGLE,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0}
+ };
popup_bw = bw;
-
- if (!pm) {
- pm = new PopupMenu(0,0,0,0, "TOOLS");
- pm->begin();
- it = new ToggleItem("Use remote CSS");
- it->callback(Menu_remote_css_cb);
- it->state(prefs.load_stylesheets);
- it = new ToggleItem("Use embedded CSS");
- it->callback(Menu_embedded_css_cb);
- it->state(prefs.parse_embedded_css);
- new Divider();
- it = new ToggleItem("Load images");
- it->callback(Menu_imgload_toggle_cb);
- it->state(prefs.load_images);
- pm->type(PopupMenu::POPUP13);
- pm->end();
+ int cur_panelsize = ui->get_panelsize();
+ int cur_smallicons = ui->get_smallicons();
+
+ if (prefs.load_stylesheets)
+ pm[0].set();
+ if (prefs.parse_embedded_css)
+ pm[1].set();
+ if (prefs.load_images)
+ pm[2].set();
+ pm[4+cur_panelsize].setonly();
+ cur_smallicons ? pm[7].set() : pm[7].clear();
+
+ item = pm->popup(x, y);
+ if (item) {
+ ((Fl_Widget *)item)->do_callback();
}
- //pm->popup();
- pm->value(-1);
- ((Menu*)pm)->popup(Rectangle(0,wid->h(),pm->w(),pm->h()));
}
diff --git a/src/menu.hh b/src/menu.hh
index 668de001..a8170e89 100644
--- a/src/menu.hh
+++ b/src/menu.hh
@@ -17,8 +17,8 @@ void a_Menu_form_popup(BrowserWindow *bw, const DilloUrl *page_url,
void *vform, bool_t showing_hiddens);
void a_Menu_file_popup(BrowserWindow *bw, void *v_wid);
void a_Menu_bugmeter_popup(BrowserWindow *bw, const DilloUrl *url);
-void a_Menu_history_popup(BrowserWindow *bw, int direction);
-void a_Menu_tools_popup(BrowserWindow *bw, void *v_wid);
+void a_Menu_history_popup(BrowserWindow *bw, int x, int y, int direction);
+void a_Menu_tools_popup(BrowserWindow *bw, int x, int y);
#ifdef __cplusplus
diff --git a/src/misc.c b/src/misc.c
index 213b0ada..2abfb988 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -383,6 +383,40 @@ int a_Misc_parse_geometry(char *str, int *x, int *y, int *w, int *h)
}
/*
+ * Parse dillorc's search_url string ("[<label> ]<url>")
+ * Return value: -1 on error, 0 on success (and label and urlstr pointers)
+ */
+int a_Misc_parse_search_url(char *source, char **label, char **urlstr)
+{
+ static char buf[32];
+ char *p, *q;
+ int ret = -1;
+
+ if ((p = strrchr(source, ' '))) {
+ /* label and url pair */
+ strncpy(buf,source,MIN(p-source,31));
+ buf[MIN(p-source,31)] = 0;
+ source = p+1;
+ if ((p = strchr(source, '/')) && p[1] && (q = strchr(p+2,'/'))) {
+ *urlstr = source;
+ ret = 0;
+ }
+ } else {
+ /* url only, make a custom label */
+ if ((p = strchr(source, '/')) && p[1] && (q = strchr(p+2,'/'))) {
+ strncpy(buf,p+2,MIN(q-p-2,31));
+ buf[MIN(q-p-2,31)] = 0;
+ *urlstr = source;
+ ret = 0;
+ }
+ }
+ *label = buf;
+ if (ret == -1)
+ MSG("Invalid search_url: \"%s\"\n", source);
+ return ret;
+}
+
+/*
* Encodes string using base64 encoding.
* Return value: new string or NULL if input string is empty.
*/
diff --git a/src/misc.h b/src/misc.h
index 0b4eaaa5..75f0f78a 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -17,6 +17,7 @@ void a_Misc_parse_content_type(const char *str, char **major, char **minor,
char **charset);
int a_Misc_content_type_cmp(const char* ct1, const char *ct2);
int a_Misc_parse_geometry(char *geom, int *x, int *y, int *w, int *h);
+int a_Misc_parse_search_url(char *source, char **label, char **urlstr);
char *a_Misc_encode_base64(const char *in);
Dstr *a_Misc_file2dstr(const char *filename);
diff --git a/src/nav.c b/src/nav.c
index c5311cfb..bea90dd3 100644
--- a/src/nav.c
+++ b/src/nav.c
@@ -195,13 +195,12 @@ static void Nav_open_url(BrowserWindow *bw, const DilloUrl *url,
const DilloUrl *requester, int offset)
{
const DilloUrl *old_url;
- bool_t MustLoad, ForceReload, Repush, IgnoreScroll;
+ bool_t MustLoad, ForceReload, IgnoreScroll;
int x, y, idx, ClientKey;
DilloWeb *Web;
MSG("Nav_open_url: new url='%s'\n", URL_STR_(url));
- Repush = (URL_FLAGS(url) & URL_ReloadFromCache) != 0;
ForceReload = (URL_FLAGS(url) & (URL_E2EQuery + URL_ReloadFromCache)) != 0;
IgnoreScroll = (URL_FLAGS(url) & URL_IgnoreScroll) != 0;
@@ -233,8 +232,7 @@ static void Nav_open_url(BrowserWindow *bw, const DilloUrl *url,
// a_Menu_pagemarks_new(bw);
- Web = a_Web_new(url, requester);
- Web->bw = bw;
+ Web = a_Web_new(bw, url, requester);
Web->flags |= WEB_RootUrl;
if ((ClientKey = a_Capi_open_url(Web, NULL, NULL)) != 0) {
a_Bw_add_client(bw, ClientKey, 1);
@@ -249,10 +247,9 @@ static void Nav_open_url(BrowserWindow *bw, const DilloUrl *url,
*/
void a_Nav_cancel_expect(BrowserWindow *bw)
{
- if (bw->nav_expecting) {
- a_Url_free(bw->nav_expect_url);
- bw->nav_expect_url = NULL;
- bw->nav_expecting = FALSE;
+ if (a_Bw_expecting(bw)) {
+ a_Bw_cancel_expect(bw);
+ a_UIcmd_set_buttons_sens(bw);
}
if (bw->meta_refresh_status > 0)
--bw->meta_refresh_status;
@@ -263,7 +260,7 @@ void a_Nav_cancel_expect(BrowserWindow *bw)
*/
void a_Nav_cancel_expect_if_eq(BrowserWindow *bw, const DilloUrl *url)
{
- if (bw->nav_expecting && a_Url_cmp(url, bw->nav_expect_url) == 0)
+ if (a_Url_cmp(url, a_Bw_expected_url(bw)) == 0)
a_Nav_cancel_expect(bw);
}
@@ -281,8 +278,8 @@ void a_Nav_expect_done(BrowserWindow *bw)
dReturn_if_fail(bw != NULL);
- if (bw->nav_expecting) {
- url = bw->nav_expect_url;
+ if (a_Bw_expecting(bw)) {
+ url = a_Url_dup(a_Bw_expected_url(bw));
reload = (URL_FLAGS(url) & URL_ReloadPage);
repush = (URL_FLAGS(url) & URL_ReloadFromCache);
e2equery = (URL_FLAGS(url) & URL_E2EQuery);
@@ -293,6 +290,7 @@ void a_Nav_expect_done(BrowserWindow *bw)
m = URL_E2EQuery|URL_ReloadPage|URL_ReloadFromCache|URL_IgnoreScroll;
a_Url_set_flags(url, URL_FLAGS(url) & ~m);
url_idx = a_History_add_url(url);
+ a_Url_free(url);
if (repush) {
MSG("a_Nav_expect_done: repush!\n");
@@ -345,16 +343,17 @@ void a_Nav_expect_done(BrowserWindow *bw)
void a_Nav_push(BrowserWindow *bw, const DilloUrl *url,
const DilloUrl *requester)
{
+ const DilloUrl *e_url;
dReturn_if_fail (bw != NULL);
- if (bw->nav_expecting && !a_Url_cmp(bw->nav_expect_url, url) &&
- !strcmp(URL_FRAGMENT(bw->nav_expect_url),URL_FRAGMENT(url))) {
+ e_url = a_Bw_expected_url(bw);
+ if (e_url && !a_Url_cmp(e_url, url) &&
+ !strcmp(URL_FRAGMENT(e_url),URL_FRAGMENT(url))) {
/* we're already expecting that url (most probably a double-click) */
return;
}
a_Nav_cancel_expect(bw);
- bw->nav_expect_url = a_Url_dup(url);
- bw->nav_expecting = TRUE;
+ a_Bw_expect(bw, url);
Nav_open_url(bw, url, requester, 0);
}
@@ -370,8 +369,7 @@ static void Nav_repush(BrowserWindow *bw)
url = a_Url_dup(a_History_get_url(NAV_TOP_UIDX(bw)));
/* Let's make reload be from Cache */
a_Url_set_flags(url, URL_FLAGS(url) | URL_ReloadFromCache);
- bw->nav_expect_url = a_Url_dup(url);
- bw->nav_expecting = TRUE;
+ a_Bw_expect(bw, url);
Nav_open_url(bw, url, NULL, 0);
a_Url_free(url);
}
@@ -488,9 +486,9 @@ static void Nav_reload_callback(void *data)
confirmed = 0;
} else if (URL_FLAGS(h_url) & URL_Post) {
/* Attempt to repost data, let's confirm... */
- choice = a_Dialog_choice3("Repost form data?",
- "Yes", "*No", "Cancel");
- confirmed = (choice == 0); /* "Yes" */
+ choice = a_Dialog_choice5("Repost form data?",
+ "No", "Yes", "Cancel", NULL, NULL);
+ confirmed = (choice == 2); /* "Yes" */
}
if (confirmed) {
@@ -501,9 +499,9 @@ static void Nav_reload_callback(void *data)
a_Url_set_flags(r_url, URL_FLAGS(r_url) | URL_E2EQuery);
/* This is an explicit reload, so clear the SpamSafe flag */
a_Url_set_flags(r_url, URL_FLAGS(r_url) & ~URL_SpamSafe);
- bw->nav_expect_url = r_url;
- bw->nav_expecting = TRUE;
+ a_Bw_expect(bw, r_url);
Nav_open_url(bw, r_url, NULL, 0);
+ a_Url_free(r_url);
}
}
}
@@ -567,8 +565,7 @@ static void Nav_save_cb(int Op, CacheClient_t *Client)
void a_Nav_save_url(BrowserWindow *bw,
const DilloUrl *url, const char *filename)
{
- DilloWeb *Web = a_Web_new(url, NULL);
- Web->bw = bw;
+ DilloWeb *Web = a_Web_new(bw, url, NULL);
Web->filename = dStrdup(filename);
Web->flags |= WEB_Download;
/* TODO: keep track of this client */
diff --git a/src/pixmaps.h b/src/pixmaps.h
index 83235dd2..9d3c4f28 100644
--- a/src/pixmaps.h
+++ b/src/pixmaps.h
@@ -819,11 +819,11 @@ static const char *const tools_xpm[] = {
" ",
" ",
" .XXo. ",
-" oO $$+. ",
+" oO$$$+. ",
" oo@$$$@# ",
" #o@$$$O# ",
" #X$$$$%X ",
-" &#% #X$$$@o ",
+" &# #X$$$@o ",
" #*o =-@$$$# ",
" oO*o #$@$$$$# ",
" oOOOX oO@;$$$$X ",
@@ -1426,11 +1426,11 @@ static const char *const tools_s_xpm[] = {
" p*45<Xg ",
" h.>885oa ",
" p.3883Xg ",
-" i$O s$488;s ",
+" $O s$488;s ",
" O>1p e;588;a ",
" O331sr;7778:s ",
" O343,**3678;a ",
-" f,643;#%368:s ",
+" O,643;#%368:s ",
" t<64>= &374f ",
" t244>= &379ih",
" d@:;=& &475u",
@@ -1539,22 +1539,22 @@ static const char *const help_xpm[] = {
"D c #000000",
"E c #000000",
"F c #000000",
-" 5555555 ",
-" 544433355 ",
-" 54555438455 ",
-" 44555542835 ",
-" 44445548245 ",
-" 4444554274 ",
-" 544554274 ",
-" 55474 ",
-" 5474 ",
-" 544 ",
+" ",
+" 444333 ",
+" 4 4384 ",
+" 44 4283 ",
+" 4444 4824 ",
+" 4444 4274 ",
+" 44 4274 ",
+" 474 ",
+" 474 ",
+" 44 ",
" 44 ",
" ",
-" 5445 ",
+" 44 ",
" 4764 ",
" 4674 ",
-" 5445 "};
+" 44 "};
/* XPM */
static const char *const full_screen_on_xpm[] = {
diff --git a/src/prefs.c b/src/prefs.c
index f968710a..f243205a 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -18,11 +18,12 @@
#define PREFS_FONT_CURSIVE "URW Chancery L"
#define PREFS_FONT_FANTASY "DejaVu Sans" /* TODO: find good default */
#define PREFS_FONT_MONOSPACE "DejaVu Sans Mono"
-#define PREFS_SEARCH_URL "http://www.google.com/search?ie=UTF-8&oe=UTF-8&q=%s"
+#define PREFS_SEARCH_URL "http://duckduckgo.com/lite/?kp=-1&q=%s"
#define PREFS_NO_PROXY "localhost 127.0.0.1"
#define PREFS_SAVE_DIR "/tmp/"
#define PREFS_HTTP_REFERER "host"
#define PREFS_HTTP_USER_AGENT "Dillo/" VERSION
+#define PREFS_THEME "none"
/*-----------------------------------------------------------------------------
* Global Data
@@ -70,11 +71,15 @@ void a_Prefs_init(void)
prefs.load_stylesheets=TRUE;
prefs.middle_click_drags_page = TRUE;
prefs.middle_click_opens_new_tab = TRUE;
+ prefs.right_click_closes_tab = FALSE;
prefs.no_proxy = dStrdup(PREFS_NO_PROXY);
prefs.panel_size = P_medium;
prefs.parse_embedded_css=TRUE;
prefs.save_dir = dStrdup(PREFS_SAVE_DIR);
- prefs.search_url = dStrdup(PREFS_SEARCH_URL);
+ prefs.search_urls = dList_new(16);
+ dList_append(prefs.search_urls, dStrdup(PREFS_SEARCH_URL));
+ dList_append(prefs.search_urls, NULL); /* flags a default search URL */
+ prefs.search_url_idx = 0;
prefs.show_back = TRUE;
prefs.show_bookmarks = TRUE;
prefs.show_clear_url = TRUE;
@@ -85,6 +90,7 @@ void a_Prefs_init(void)
prefs.show_home = TRUE;
prefs.show_msg = TRUE;
prefs.show_progress_box = TRUE;
+ prefs.show_quit_dialog = TRUE;
prefs.show_reload = TRUE;
prefs.show_save = TRUE;
prefs.show_search = TRUE;
@@ -94,6 +100,7 @@ void a_Prefs_init(void)
prefs.show_url = TRUE;
prefs.small_icons = FALSE;
prefs.start_page = a_Url_new(PREFS_START_PAGE, NULL);
+ prefs.theme = dStrdup(PREFS_THEME);
prefs.w3c_plus_heuristics = TRUE;
}
@@ -103,6 +110,8 @@ void a_Prefs_init(void)
*/
void a_Prefs_freeall(void)
{
+ int i;
+
dFree(prefs.font_cursive);
dFree(prefs.font_fantasy);
dFree(prefs.font_monospace);
@@ -116,6 +125,9 @@ void a_Prefs_freeall(void)
dFree(prefs.http_user_agent);
dFree(prefs.no_proxy);
dFree(prefs.save_dir);
- dFree(prefs.search_url);
+ for (i = 0; i < dList_length(prefs.search_urls); ++i)
+ dFree(dList_nth_data(prefs.search_urls, i));
+ dList_free(prefs.search_urls);
a_Url_free(prefs.start_page);
+ dFree(prefs.theme);
}
diff --git a/src/prefs.h b/src/prefs.h
index 4009925c..f1a3d538 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -24,7 +24,7 @@ extern "C" {
#define PREFS_GEOMETRY_DEFAULT_YPOS -9999
/* Panel sizes */
-enum { P_tiny = 0, P_small, P_medium, P_large };
+enum { P_tiny = 0, P_small, P_medium };
enum {PREFS_FILTER_ALLOW_ALL,
PREFS_FILTER_SAME_DOMAIN};
@@ -49,6 +49,7 @@ struct _DilloPrefs {
int32_t bg_color;
bool_t contrast_visited_color;
bool_t show_tooltip;
+ char *theme;
int panel_size;
bool_t small_icons;
bool_t limit_text_width;
@@ -71,6 +72,7 @@ struct _DilloPrefs {
bool_t show_search;
bool_t show_help;
bool_t show_progress_box;
+ bool_t show_quit_dialog;
bool_t fullwindow_start;
bool_t load_images;
bool_t load_stylesheets;
@@ -84,7 +86,9 @@ struct _DilloPrefs {
char *font_monospace;
bool_t enterpress_forces_submit;
bool_t middle_click_opens_new_tab;
- char *search_url;
+ bool_t right_click_closes_tab;
+ bool_t search_url_idx;
+ Dlist *search_urls;
char *save_dir;
bool_t show_msg;
bool_t show_extra_warnings;
diff --git a/src/prefsparser.cc b/src/prefsparser.cc
index 95f98c16..efe64a0e 100644
--- a/src/prefsparser.cc
+++ b/src/prefsparser.cc
@@ -24,6 +24,7 @@ typedef enum {
PREFS_BOOL,
PREFS_COLOR,
PREFS_STRING,
+ PREFS_STRINGS,
PREFS_URL,
PREFS_INT32,
PREFS_DOUBLE,
@@ -81,11 +82,12 @@ int PrefsParser::parseOption(char *name, char *value)
PREFS_BOOL },
{ "middle_click_opens_new_tab", &prefs.middle_click_opens_new_tab,
PREFS_BOOL },
+ { "right_click_closes_tab", &prefs.right_click_closes_tab, PREFS_BOOL },
{ "no_proxy", &prefs.no_proxy, PREFS_STRING },
{ "panel_size", &prefs.panel_size, PREFS_PANEL_SIZE },
{ "parse_embedded_css", &prefs.parse_embedded_css, PREFS_BOOL },
{ "save_dir", &prefs.save_dir, PREFS_STRING },
- { "search_url", &prefs.search_url, PREFS_STRING },
+ { "search_url", &prefs.search_urls, PREFS_STRINGS },
{ "show_back", &prefs.show_back, PREFS_BOOL },
{ "show_bookmarks", &prefs.show_bookmarks, PREFS_BOOL },
{ "show_clear_url", &prefs.show_clear_url, PREFS_BOOL },
@@ -96,6 +98,7 @@ int PrefsParser::parseOption(char *name, char *value)
{ "show_home", &prefs.show_home, PREFS_BOOL },
{ "show_msg", &prefs.show_msg, PREFS_BOOL },
{ "show_progress_box", &prefs.show_progress_box, PREFS_BOOL },
+ { "show_quit_dialog", &prefs.show_quit_dialog, PREFS_BOOL },
{ "show_reload", &prefs.show_reload, PREFS_BOOL },
{ "show_save", &prefs.show_save, PREFS_BOOL },
{ "show_search", &prefs.show_search, PREFS_BOOL },
@@ -105,6 +108,7 @@ int PrefsParser::parseOption(char *name, char *value)
{ "show_url", &prefs.show_url, PREFS_BOOL },
{ "small_icons", &prefs.small_icons, PREFS_BOOL },
{ "start_page", &prefs.start_page, PREFS_URL },
+ { "theme", &prefs.theme, PREFS_STRING },
{ "w3c_plus_heuristics", &prefs.w3c_plus_heuristics, PREFS_BOOL }
};
@@ -128,11 +132,26 @@ int PrefsParser::parseOption(char *name, char *value)
break;
case PREFS_COLOR:
*(int32_t *)node->pref = a_Color_parse(value, *(int32_t*)node->pref,&st);
+ if (st)
+ MSG("prefs: Color '%s' not recognized.\n", value);
break;
case PREFS_STRING:
dFree(*(char **)node->pref);
*(char **)node->pref = dStrdup(value);
break;
+ case PREFS_STRINGS:
+ {
+ Dlist *lp = *(Dlist **)node->pref;
+ if (dList_length(lp) == 2 && !dList_nth_data(lp, 1)) {
+ /* override the default */
+ void *data = dList_nth_data(lp, 0);
+ dList_remove(lp, data);
+ dList_remove(lp, NULL);
+ dFree(data);
+ }
+ dList_append(lp, dStrdup(value));
+ break;
+ }
case PREFS_URL:
a_Url_free(*(DilloUrl **)node->pref);
*(DilloUrl **)node->pref = a_Url_new(value, NULL);
@@ -161,8 +180,6 @@ int PrefsParser::parseOption(char *name, char *value)
prefs.panel_size = P_tiny;
else if (!dStrcasecmp(value, "small"))
prefs.panel_size = P_small;
- else if (!dStrcasecmp(value, "large"))
- prefs.panel_size = P_large;
else /* default to "medium" */
prefs.panel_size = P_medium;
break;
@@ -170,13 +187,6 @@ int PrefsParser::parseOption(char *name, char *value)
MSG_WARN("prefs: {%s} IS recognized but not handled!\n", name);
break; /* Not reached */
}
-
- if (prefs.limit_text_width) {
- /* BUG: causes 100% CPU usage with <button> or <input type="image"> */
- MSG_WARN("Disabling limit_text_width preference (currently broken).\n");
- prefs.limit_text_width = FALSE;
- }
-
return 0;
}
diff --git a/src/styleengine.cc b/src/styleengine.cc
index 776c1694..a4c31ccb 100644
--- a/src/styleengine.cc
+++ b/src/styleengine.cc
@@ -52,6 +52,7 @@ StyleEngine::StyleEngine (dw::core::Layout *layout) {
n->wordStyle = NULL;
n->backgroundStyle = NULL;
n->styleAttrProperties = NULL;
+ n->styleAttrPropertiesImportant = NULL;
n->nonCssProperties = NULL;
n->inheritBackgroundColor = false;
}
@@ -82,6 +83,7 @@ void StyleEngine::startElement (int element) {
stack->increase ();
Node *n = stack->getRef (stack->size () - 1);
n->styleAttrProperties = NULL;
+ n->styleAttrPropertiesImportant = NULL;
n->nonCssProperties = NULL;
n->style = NULL;
n->wordStyle = NULL;
@@ -138,10 +140,14 @@ void StyleEngine::setStyle (const char *styleAttr) {
Node *n = stack->getRef (stack->size () - 1);
assert (n->styleAttrProperties == NULL);
// parse style information from style="" attribute, if it exists
- if (styleAttr && prefs.parse_embedded_css)
- n->styleAttrProperties =
- CssParser::parseDeclarationBlock (styleAttr,
- strlen (styleAttr));
+ if (styleAttr && prefs.parse_embedded_css) {
+ n->styleAttrProperties = new CssPropertyList (true);
+ n->styleAttrPropertiesImportant = new CssPropertyList (true);
+
+ CssParser::parseDeclarationBlock (styleAttr, strlen (styleAttr),
+ n->styleAttrProperties,
+ n->styleAttrPropertiesImportant);
+ }
};
/**
@@ -213,6 +219,8 @@ void StyleEngine::endElement (int element) {
if (n->styleAttrProperties)
delete n->styleAttrProperties;
+ if (n->styleAttrPropertiesImportant)
+ delete n->styleAttrPropertiesImportant;
if (n->nonCssProperties)
delete n->nonCssProperties;
if (n->style)
@@ -709,7 +717,8 @@ Style * StyleEngine::backgroundStyle () {
* This method is private. Call style() to get a current style object.
*/
Style * StyleEngine::style0 (int i) {
- CssPropertyList props, *styleAttrProperties, *nonCssProperties;
+ CssPropertyList props, *styleAttrProperties, *styleAttrPropertiesImportant;
+ CssPropertyList *nonCssProperties;
// get previous style from the stack
StyleAttrs attrs = *stack->getRef (i - 1)->style;
@@ -726,11 +735,13 @@ Style * StyleEngine::style0 (int i) {
preprocessAttrs (&attrs);
styleAttrProperties = stack->getRef (i)->styleAttrProperties;
+ styleAttrPropertiesImportant = stack->getRef(i)->styleAttrPropertiesImportant;
nonCssProperties = stack->getRef (i)->nonCssProperties;
// merge style information
cssContext->apply (&props, doctree, stack->getRef(i)->doctreeNode,
- styleAttrProperties, nonCssProperties);
+ styleAttrProperties, styleAttrPropertiesImportant,
+ nonCssProperties);
// apply style
apply (i, &attrs, &props);
diff --git a/src/styleengine.hh b/src/styleengine.hh
index e37aeed1..b73a8b5f 100644
--- a/src/styleengine.hh
+++ b/src/styleengine.hh
@@ -21,6 +21,7 @@ class StyleEngine {
private:
struct Node {
CssPropertyList *styleAttrProperties;
+ CssPropertyList *styleAttrPropertiesImportant;
CssPropertyList *nonCssProperties;
dw::core::style::Style *style;
dw::core::style::Style *wordStyle;
diff --git a/src/table.cc b/src/table.cc
index 58cdf22e..d48a0c45 100644
--- a/src/table.cc
+++ b/src/table.cc
@@ -151,7 +151,6 @@ void Html_tag_open_tr(DilloHtml *html, const char *tag, int tagsize)
{
const char *attrbuf;
int32_t bgcolor = -1;
- bool new_style = false;
html->styleEngine->inheritNonCssHints ();
@@ -183,10 +182,8 @@ void Html_tag_open_tr(DilloHtml *html, const char *tag, int tagsize)
if (bgcolor != -1) {
html->styleEngine->setNonCssHint(CSS_PROPERTY_BACKGROUND_COLOR,
CSS_TYPE_COLOR, bgcolor);
- new_style = true;
}
- if (a_Html_tag_set_valign_attr (html, tag, tagsize))
- new_style = true;
+ a_Html_tag_set_valign_attr (html, tag, tagsize);
break;
default:
break;
@@ -318,7 +315,6 @@ static void Html_tag_open_table_cell(DilloHtml *html,
int colspan = 1, rowspan = 1;
const char *attrbuf;
int32_t bgcolor;
- bool_t new_style;
html->styleEngine->inheritNonCssHints ();
@@ -363,8 +359,7 @@ static void Html_tag_open_table_cell(DilloHtml *html,
a_Html_parse_length (html, attrbuf));
}
- if (a_Html_tag_set_valign_attr (html, tag, tagsize))
- new_style = TRUE;
+ a_Html_tag_set_valign_attr (html, tag, tagsize);
if ((attrbuf = a_Html_get_attr(html, tag, tagsize, "bgcolor"))) {
bgcolor = a_Html_color_parse(html, attrbuf, -1);
diff --git a/src/timeout.cc b/src/timeout.cc
index 80eb6425..1ddcd5e1 100644
--- a/src/timeout.cc
+++ b/src/timeout.cc
@@ -11,12 +11,9 @@
// Simple ADT for timeout functions
-#include <fltk/run.h>
+#include <FL/Fl.H>
#include "timeout.hh"
-using namespace fltk;
-
-
// C++ functions with C linkage ----------------------------------------------
/*
@@ -25,7 +22,7 @@ using namespace fltk;
*/
void a_Timeout_add(float t, TimeoutCb_t cb, void *cbdata)
{
- add_timeout(t, cb, cbdata);
+ Fl::add_timeout(t, cb, cbdata);
}
/*
@@ -33,7 +30,7 @@ void a_Timeout_add(float t, TimeoutCb_t cb, void *cbdata)
*/
void a_Timeout_repeat(float t, TimeoutCb_t cb, void *cbdata)
{
- add_timeout(t, cb, cbdata);
+ Fl::add_timeout(t, cb, cbdata);
}
/*
diff --git a/src/ui.cc b/src/ui.cc
index fac78604..afa88073 100644
--- a/src/ui.cc
+++ b/src/ui.cc
@@ -14,73 +14,64 @@
#include <unistd.h>
#include <stdio.h>
-#include <fltk/HighlightButton.h>
-#include <fltk/run.h>
-#include <fltk/damage.h>
-#include <fltk/xpmImage.h>
-#include <fltk/events.h> // for mouse buttons and keys
-#include <fltk/Font.h> // UI label font for tabs
-#include <fltk/InvisibleBox.h>
-#include <fltk/PopupMenu.h>
-#include <fltk/Item.h>
-#include <fltk/Divider.h>
-
#include "keys.hh"
#include "ui.hh"
#include "msg.h"
#include "timeout.hh"
#include "utf8.hh"
-using namespace fltk;
-
+#include <FL/Fl.H>
+#include <FL/Fl_Pixmap.H>
+#include <FL/Fl_Box.H>
+#include <FL/names.h>
// Include image data
#include "pixmaps.h"
#include "uicmd.hh"
struct iconset {
- Image *ImgMeterOK, *ImgMeterBug,
- *ImgHome, *ImgReload, *ImgSave, *ImgBook, *ImgTools,
- *ImgClear,*ImgSearch, *ImgHelp;
- MultiImage *ImgLeftMulti, *ImgRightMulti, *ImgStopMulti;
+ Fl_Image *ImgMeterOK, *ImgMeterBug,
+ *ImgHome, *ImgReload, *ImgSave, *ImgBook, *ImgTools,
+ *ImgClear,*ImgSearch, *ImgHelp, *ImgLeft, *ImgLeftIn,
+ *ImgRight, *ImgRightIn, *ImgStop, *ImgStopIn;
};
static struct iconset standard_icons = {
- new xpmImage(mini_ok_xpm),
- new xpmImage(mini_bug_xpm),
- new xpmImage(home_xpm),
- new xpmImage(reload_xpm),
- new xpmImage(save_xpm),
- new xpmImage(bm_xpm),
- new xpmImage(tools_xpm),
- new xpmImage(new_s_xpm),
- new xpmImage(search_xpm),
- new xpmImage(help_xpm),
- new MultiImage(*new xpmImage(left_xpm), INACTIVE_R,
- *new xpmImage(left_i_xpm)),
- new MultiImage(*new xpmImage(right_xpm), INACTIVE_R,
- *new xpmImage(right_i_xpm)),
- new MultiImage(*new xpmImage(stop_xpm), INACTIVE_R,
- *new xpmImage(stop_i_xpm)),
+ new Fl_Pixmap(mini_ok_xpm),
+ new Fl_Pixmap(mini_bug_xpm),
+ new Fl_Pixmap(home_xpm),
+ new Fl_Pixmap(reload_xpm),
+ new Fl_Pixmap(save_xpm),
+ new Fl_Pixmap(bm_xpm),
+ new Fl_Pixmap(tools_xpm),
+ new Fl_Pixmap(new_s_xpm),
+ new Fl_Pixmap(search_xpm),
+ new Fl_Pixmap(help_xpm),
+ new Fl_Pixmap(left_xpm),
+ new Fl_Pixmap(left_i_xpm),
+ new Fl_Pixmap(right_xpm),
+ new Fl_Pixmap(right_i_xpm),
+ new Fl_Pixmap(stop_xpm),
+ new Fl_Pixmap(stop_i_xpm),
};
static struct iconset small_icons = {
standard_icons.ImgMeterOK,
standard_icons.ImgMeterBug,
- new xpmImage(home_s_xpm),
- new xpmImage(reload_s_xpm),
- new xpmImage(save_s_xpm),
- new xpmImage(bm_s_xpm),
- new xpmImage(tools_s_xpm),
- new xpmImage(new_s_xpm),
+ new Fl_Pixmap(home_s_xpm),
+ new Fl_Pixmap(reload_s_xpm),
+ new Fl_Pixmap(save_s_xpm),
+ new Fl_Pixmap(bm_s_xpm),
+ new Fl_Pixmap(tools_s_xpm),
+ new Fl_Pixmap(new_s_xpm),
standard_icons.ImgSearch,
standard_icons.ImgHelp,
- new MultiImage(*new xpmImage(left_s_xpm), INACTIVE_R,
- *new xpmImage(left_si_xpm)),
- new MultiImage(*new xpmImage(right_s_xpm), INACTIVE_R,
- *new xpmImage(right_si_xpm)),
- new MultiImage(*new xpmImage(stop_s_xpm), INACTIVE_R,
- *new xpmImage(stop_si_xpm)),
+ new Fl_Pixmap(left_s_xpm),
+ new Fl_Pixmap(left_si_xpm),
+ new Fl_Pixmap(right_s_xpm),
+ new Fl_Pixmap(right_si_xpm),
+ new Fl_Pixmap(stop_s_xpm),
+ new Fl_Pixmap(stop_si_xpm),
};
@@ -95,49 +86,69 @@ static struct iconset *icons = &standard_icons;
/*
* (Used to avoid certain shortcuts in the location bar)
*/
-class CustInput : public Input {
+class CustInput : public Fl_Input {
public:
CustInput (int x, int y, int w, int h, const char* l=0) :
- Input(x,y,w,h,l) {};
+ Fl_Input(x,y,w,h,l) {};
int handle(int e);
};
/*
- * Disable: UpKey, DownKey, PageUpKey, PageDownKey and
- * CTRL+{o,r,HomeKey,EndKey}
+ * Disable keys: Up, Down, Page_Up, Page_Down, Tab and
+ * CTRL+{o,r,Home,End} SHIFT+{Left,Right}.
*/
int CustInput::handle(int e)
{
- int k = event_key();
+ int k = Fl::event_key();
_MSG("CustInput::handle event=%d\n", e);
// We're only interested in some flags
- unsigned modifier = event_state() & (SHIFT | CTRL | ALT);
+ unsigned modifier = Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT);
// Don't focus with arrow keys
- if (e == FOCUS &&
- (k == UpKey || k == DownKey || k == LeftKey || k == RightKey)) {
+ if (e == FL_FOCUS &&
+ (k == FL_Up || k == FL_Down || k == FL_Left || k == FL_Right)) {
return 0;
- } else if (e == KEY) {
- if (modifier == CTRL) {
- if (k == 'l') {
+ } else if (e == FL_KEYBOARD) {
+ if (k == FL_Escape && modifier == 0) {
+ // Let the parent group handle this Esc key
+ return 0;
+ } else if (modifier == FL_SHIFT) {
+ if (k == FL_Left || k == FL_Right) {
+ // Let these keys get to the UI
+ return 0;
+ }
+ } else if (modifier == FL_CTRL) {
+ if (k == 'a' || k == 'e') {
+ position(k == 'a' ? 0 : size());
+ return 1;
+ } else if (k == 'k') {
+ cut(position(), size());
+ return 1;
+ } else if (k == 'd') {
+ cut(position(), position()+1);
+ return 1;
+ } else if (k == 'l') {
// Make text selected when already focused.
position(size(), 0);
return 1;
- } else if (k == 'o' || k == 'r' || k == HomeKey || k == EndKey)
+ } else if (k == 'h' || k == 'o' || k == 'r' ||
+ k == FL_Home || k == FL_End) {
+ // Let these keys get to the UI
+ return 0;
+ }
+ } else if (modifier == 0) {
+ if (k == FL_Down || k == FL_Up ||
+ k == FL_Page_Down || k == FL_Page_Up || k == FL_Tab) {
+ // Give up focus and honor the key
+ a_UIcmd_focus_main_area(a_UIcmd_get_bw_by_widget(this));
return 0;
- } else if (modifier == SHIFT) {
- if (k == LeftKey || k == RightKey) {
- _MSG(" CustInput::handle > SHIFT+RightKey\n");
- a_UIcmd_send_event_to_tabs_by_wid(e, this);
- return 1;
}
}
}
- _MSG("\n");
- return Input::handle(e);
+ return Fl_Input::handle(e);
}
//----------------------------------------------------------------------------
@@ -145,24 +156,24 @@ int CustInput::handle(int e)
/*
* Used to handle "paste" within the toolbar's Clear button.
*/
-class CustHighlightButton : public HighlightButton {
+class CustPasteButton : public CustLightButton {
public:
- CustHighlightButton(int x, int y, int w, int h, const char *l=0) :
- HighlightButton(x,y,w,h,l) {};
+ CustPasteButton(int x, int y, int w, int h, const char *l=0) :
+ CustLightButton(x,y,w,h,l) {};
int handle(int e);
};
-int CustHighlightButton::handle(int e)
+int CustPasteButton::handle(int e)
{
- if (e == PASTE) {
- const char* t = event_text();
+ if (e == FL_PASTE) {
+ const char* t = Fl::event_text();
if (t && *t) {
a_UIcmd_set_location_text(a_UIcmd_get_bw_by_widget(this), t);
a_UIcmd_open_urlstr(a_UIcmd_get_bw_by_widget(this), t);
return 1;
}
}
- return HighlightButton::handle(e);
+ return CustLightButton::handle(e);
}
//----------------------------------------------------------------------------
@@ -170,22 +181,19 @@ int CustHighlightButton::handle(int e)
/*
* Used to resize the progress boxes automatically.
*/
-class CustProgressBox : public InvisibleBox {
+class CustProgressBox : public Fl_Box {
int padding;
public:
CustProgressBox(int x, int y, int w, int h, const char *l=0) :
- InvisibleBox(x,y,w,h,l) { padding = 0; };
+ Fl_Box(x,y,w,h,l) { padding = 0; };
void update_label(const char *lbl) {
- int w,h;
+ int w = 0, h = 0;
if (!padding) {
copy_label("W");
measure_label(w, h);
padding = w > 2 ? w/2 : 1;
}
copy_label(lbl);
- measure_label(w,h);
- resize(w+padding,h);
- redraw_label();
}
};
@@ -205,23 +213,23 @@ public:
/*
* Callback for the search button.
*/
-static void search_cb(Widget *wid, void *data)
+static void search_cb(Fl_Widget *wid, void *data)
{
- int k = event_key();
+ int b = Fl::event_button();
- if (k == 1) {
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_search_dialog(a_UIcmd_get_bw_by_widget(wid));
- } else if (k == 2) {
+ } else if (b == FL_MIDDLE_MOUSE) {
((UI*)data)->color_change_cb_i();
- } else if (k == 3) {
- ((UI*)data)->panel_cb_i();
+ } else if (b == FL_RIGHT_MOUSE) {
+ // nothing ATM
}
}
/*
* Callback for the help button.
*/
-static void help_cb(Widget *w, void *)
+static void help_cb(Fl_Widget *w, void *)
{
char *path = dStrconcat(DILLO_DOCDIR, "user_help.html", NULL);
BrowserWindow *bw = a_UIcmd_get_bw_by_widget(w);
@@ -233,7 +241,7 @@ static void help_cb(Widget *w, void *)
} else {
MSG("Can't read local help file at \"%s\"."
" Getting remote help...\n", path);
- a_UIcmd_open_urlstr(bw, "http://www.dillo.org/dillo2-help.html");
+ a_UIcmd_open_urlstr(bw, "http://www.dillo.org/dillo3-help.html");
}
dFree(path);
}
@@ -241,10 +249,10 @@ static void help_cb(Widget *w, void *)
/*
* Callback for the File menu button.
*/
-static void filemenu_cb(Widget *wid, void *)
+static void filemenu_cb(Fl_Widget *wid, void *)
{
- int k = event_key();
- if (k == 1 || k == 3) {
+ int b = Fl::event_button();
+ if (b == FL_LEFT_MOUSE || b == FL_RIGHT_MOUSE) {
a_UIcmd_file_popup(a_UIcmd_get_bw_by_widget(wid), wid);
}
}
@@ -252,105 +260,92 @@ static void filemenu_cb(Widget *wid, void *)
/*
* Callback for the location's clear-button.
*/
-static void clear_cb(Widget *w, void *data)
+static void clear_cb(Fl_Widget *w, void *data)
{
UI *ui = (UI*)data;
- int k = event_key();
- if (k == 1) {
+ int b = Fl::event_button();
+ if (b == FL_LEFT_MOUSE) {
ui->set_location("");
ui->focus_location();
- } if (k == 2) {
+ } if (b == FL_MIDDLE_MOUSE) {
ui->paste_url();
}
}
/*
- * Change the color of the location bar.
- *
-static void color_change_cb(Widget *wid, void *data)
-{
- ((UI*)data)->color_change_cb_i();
-}
- */
-
-
-/*
* Send the browser to the new URL in the location.
*/
-static void location_cb(Widget *wid, void *data)
+static void location_cb(Fl_Widget *wid, void *data)
{
- Input *i = (Input*)wid;
+ Fl_Input *i = (Fl_Input*)wid;
UI *ui = (UI*)data;
_MSG("location_cb()\n");
- /* This test is necessary because WHEN_ENTER_KEY also includes
- * other events we're not interested in. For instance pressing
- * The Back or Forward, buttons, or the first click on a rendered
- * page. BUG: this must be investigated and reported to FLTK2 team */
- if (event_key() == ReturnKey) {
- a_UIcmd_open_urlstr(a_UIcmd_get_bw_by_widget(i), i->value());
- }
- if (ui->get_panelmode() == UI_TEMPORARILY_SHOW_PANELS) {
- ui->set_panelmode(UI_HIDDEN);
- }
+ a_UIcmd_open_urlstr(a_UIcmd_get_bw_by_widget(i), i->value());
+
+ if (ui->temporaryPanels())
+ ui->panels_toggle();
}
/*
* Callback handler for button press on the panel
*/
-static void b1_cb(Widget *wid, void *cb_data)
+static void b1_cb(Fl_Widget *wid, void *cb_data)
{
int bn = VOIDP2INT(cb_data);
- int k = event_key();
- if (k && k <= 7) {
- _MSG("[%s], mouse button %d was pressed\n", button_names[bn], k);
- _MSG("mouse button %d was pressed\n", k);
+ int b = Fl::event_button();
+ if (b >= FL_LEFT_MOUSE && b <= FL_RIGHT_MOUSE) {
+ _MSG("[%s], mouse button %d was pressed\n", button_names[bn], b);
+ _MSG("mouse button %d was pressed\n", b);
}
switch (bn) {
case UI_BACK:
- if (k == 1) {
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_back(a_UIcmd_get_bw_by_widget(wid));
- } else if (k == 3) {
- a_UIcmd_back_popup(a_UIcmd_get_bw_by_widget(wid));
+ } else if (b == FL_RIGHT_MOUSE) {
+ a_UIcmd_back_popup(a_UIcmd_get_bw_by_widget(wid), wid->x(),
+ wid->y() + wid->h());
}
break;
case UI_FORW:
- if (k == 1) {
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_forw(a_UIcmd_get_bw_by_widget(wid));
- } else if (k == 3) {
- a_UIcmd_forw_popup(a_UIcmd_get_bw_by_widget(wid));
+ } else if (b == FL_RIGHT_MOUSE) {
+ a_UIcmd_forw_popup(a_UIcmd_get_bw_by_widget(wid), wid->x(),
+ wid->y() + wid->h());
}
break;
case UI_HOME:
- if (k == 1) {
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_home(a_UIcmd_get_bw_by_widget(wid));
}
break;
case UI_RELOAD:
- if (k == 1) {
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_reload(a_UIcmd_get_bw_by_widget(wid));
}
break;
case UI_SAVE:
- if (k == 1) {
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_save(a_UIcmd_get_bw_by_widget(wid));
}
break;
case UI_STOP:
- if (k == 1) {
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_stop(a_UIcmd_get_bw_by_widget(wid));
}
break;
case UI_BOOK:
- if (k == 1) {
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_book(a_UIcmd_get_bw_by_widget(wid));
}
break;
case UI_TOOLS:
- if (k == 1 || k == 3) {
- a_UIcmd_tools(a_UIcmd_get_bw_by_widget(wid), wid);
+ if (b == FL_LEFT_MOUSE || b == FL_RIGHT_MOUSE) {
+ a_UIcmd_tools(a_UIcmd_get_bw_by_widget(wid), wid->x(),
+ wid->y() + wid->h());
}
break;
default:
@@ -359,24 +354,14 @@ static void b1_cb(Widget *wid, void *cb_data)
}
/*
- * Callback handler for fullscreen button press
- */
-//static void fullscreen_cb(Widget *wid, void *data)
-//{
-// /* TODO: do we want to toggle fullscreen or panelmode?
-// maybe we need to add another button?*/
-// ((UI*)data)->panelmode_cb_i();
-//}
-
-/*
* Callback for the bug meter button.
*/
-static void bugmeter_cb(Widget *wid, void *data)
+static void bugmeter_cb(Fl_Widget *wid, void *data)
{
- int k = event_key();
- if (k == 1) {
+ int b = Fl::event_button();
+ if (b == FL_LEFT_MOUSE) {
a_UIcmd_view_page_bugs(a_UIcmd_get_bw_by_widget(wid));
- } else if (k == 3) {
+ } else if (b == FL_RIGHT_MOUSE) {
a_UIcmd_bugmeter_popup(a_UIcmd_get_bw_by_widget(wid));
}
}
@@ -390,159 +375,136 @@ static void bugmeter_cb(Widget *wid, void *data)
//----------------------------
/*
+ * Make a generic navigation button
+ */
+Fl_Button *UI::make_button(const char *label, Fl_Image *img, Fl_Image *deimg,
+ int b_n, int start)
+{
+ if (start)
+ p_xpos = 0;
+
+ Fl_Button *b = new CustLightButton(p_xpos, 0, bw, bh, (lbl) ? label : NULL);
+ if (img)
+ b->image(img);
+ if (deimg)
+ b->deimage(deimg);
+ b->callback(b1_cb, INT2VOIDP(b_n));
+ b->clear_visible_focus();
+ b->labelsize(12);
+ b->box(FL_FLAT_BOX);
+ b->down_box(FL_THIN_DOWN_FRAME);
+ p_xpos += bw;
+ return b;
+}
+
+/*
* Create the archetipic browser buttons
*/
-PackedGroup *UI::make_toolbar(int tw, int th)
+void UI::make_toolbar(int tw, int th)
{
- HighlightButton *b;
- PackedGroup *p1=new PackedGroup(0,0,tw,th);
- p1->begin();
- Back = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Back" : 0);
- b->image(icons->ImgLeftMulti);
- b->callback(b1_cb, (void *)UI_BACK);
- b->clear_tab_to_focus();
- HighlightButton::default_style->highlight_color(CuteColor);
-
- Forw = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Forw" : 0);
- b->image(icons->ImgRightMulti);
- b->callback(b1_cb, (void *)UI_FORW);
- b->clear_tab_to_focus();
-
- Home = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Home" : 0);
- b->image(icons->ImgHome);
- b->callback(b1_cb, (void *)UI_HOME);
- b->clear_tab_to_focus();
-
- Reload = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Reload" : 0);
- b->image(icons->ImgReload);
- b->callback(b1_cb, (void *)UI_RELOAD);
- b->clear_tab_to_focus();
-
- Save = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Save" : 0);
- b->image(icons->ImgSave);
- b->callback(b1_cb, (void *)UI_SAVE);
- b->clear_tab_to_focus();
-
- Stop = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Stop" : 0);
- b->image(icons->ImgStopMulti);
- b->callback(b1_cb, (void *)UI_STOP);
- b->clear_tab_to_focus();
-
- Bookmarks = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Book" : 0);
- b->image(icons->ImgBook);
- b->callback(b1_cb, (void *)UI_BOOK);
- b->clear_tab_to_focus();
-
- Tools = b = new HighlightButton(xpos, 0, bw, bh, (lbl) ? "Tools" : 0);
- b->image(icons->ImgTools);
- b->callback(b1_cb, (void *)UI_TOOLS);
- b->clear_tab_to_focus();
-
- p1->type(PackedGroup::ALL_CHILDREN_VERTICAL);
- p1->end();
-
- if (prefs.show_tooltip) {
- Back->tooltip("Previous page");
- Forw->tooltip("Next page");
- Home->tooltip("Go to the Home page");
- Reload->tooltip("Reload");
- Save->tooltip("Save this page");
- Stop->tooltip("Stop loading");
- Bookmarks->tooltip("View bookmarks");
- Tools->tooltip("Settings");
- }
- return p1;
+ Back = make_button("Back", icons->ImgLeft, icons->ImgLeftIn, UI_BACK, 1);
+ Forw = make_button("Forw", icons->ImgRight, icons->ImgRightIn, UI_FORW);
+ Home = make_button("Home", icons->ImgHome, NULL, UI_HOME);
+ Reload = make_button("Reload", icons->ImgReload, NULL, UI_RELOAD);
+ Save = make_button("Save", icons->ImgSave, NULL, UI_SAVE);
+ Stop = make_button("Stop", icons->ImgStop, icons->ImgStopIn, UI_STOP);
+ Bookmarks = make_button("Book", icons->ImgBook, NULL, UI_BOOK);
+ Tools = make_button("Tools", icons->ImgTools, NULL, UI_TOOLS);
+
+ Back->tooltip("Previous page");
+ Forw->tooltip("Next page");
+ Home->tooltip("Go to the Home page");
+ Reload->tooltip("Reload");
+ Save->tooltip("Save this page");
+ Stop->tooltip("Stop loading");
+ Bookmarks->tooltip("View bookmarks");
+ Tools->tooltip("Settings");
}
/*
* Create the location box (Clear/Input/Search)
*/
-PackedGroup *UI::make_location()
+void UI::make_location(int ww)
{
- Button *b;
- PackedGroup *pg = new PackedGroup(0,0,0,0);
- pg->begin();
- Clear = b = new CustHighlightButton(2,2,16,22,0);
+ Fl_Button *b;
+
+ Clear = b = new CustPasteButton(p_xpos,0,16,lh,0);
b->image(icons->ImgClear);
b->callback(clear_cb, this);
- b->clear_tab_to_focus();
+ b->clear_visible_focus();
+ b->box(FL_THIN_UP_BOX);
+ b->tooltip("Clear the URL box.\nMiddle-click to paste a URL.");
+ p_xpos += b->w();
- Input *i = Location = new CustInput(0,0,0,0,0);
+ Fl_Input *i = Location = new CustInput(p_xpos,0,ww-p_xpos-32,lh,0);
i->color(CuteColor);
- i->when(WHEN_ENTER_KEY);
+ i->when(FL_WHEN_ENTER_KEY);
i->callback(location_cb, this);
- i->set_click_to_focus();
+ i->tooltip("Location");
+ p_xpos += i->w();
- Search = b = new HighlightButton(0,0,16,22,0);
+ Search = b = new CustLightButton(p_xpos,0,16,lh,0);
b->image(icons->ImgSearch);
b->callback(search_cb, this);
- b->clear_tab_to_focus();
+ b->clear_visible_focus();
+ b->box(FL_THIN_UP_BOX);
+ b->tooltip("Search the Web");
+ p_xpos += b->w();
- Help = b = new HighlightButton(0,0,16,22,0);
+ Help = b = new CustLightButton(p_xpos,0,16,lh,0);
b->image(icons->ImgHelp);
b->callback(help_cb, this);
- b->clear_tab_to_focus();
+ b->clear_visible_focus();
+ b->box(FL_THIN_UP_BOX);
+ b->tooltip("Help");
+ p_xpos += b->w();
- pg->type(PackedGroup::ALL_CHILDREN_VERTICAL);
- pg->resizable(i);
- pg->end();
-
- if (prefs.show_tooltip) {
- Clear->tooltip("Clear the URL box.\nMiddle-click to paste a URL.");
- Location->tooltip("Location");
- Search->tooltip("Search the Web");
- Help->tooltip("Help");
- }
- return pg;
}
/*
* Create the progress bars
*/
-PackedGroup *UI::make_progress_bars(int wide, int thin_up)
+void UI::make_progress_bars(int wide, int thin_up)
{
- ProgBox = new PackedGroup(0,0,0,0);
- ProgBox->begin();
// Images
- IProg = new CustProgressBox(0,0,0,0);
- IProg->box(thin_up ? THIN_UP_BOX : EMBOSSED_BOX);
- IProg->labelcolor(GRAY10);
+ IProg = new CustProgressBox(p_xpos,p_ypos,pw,bh);
+ IProg->labelsize(12);
+ IProg->box(thin_up ? FL_THIN_UP_BOX : FL_EMBOSSED_BOX);
+ IProg->labelcolor(FL_GRAY_RAMP + 2);
IProg->update_label(wide ? "Images\n0 of 0" : "0 of 0");
+ p_xpos += pw;
// Page
- PProg = new CustProgressBox(0,0,0,0);
- PProg->box(thin_up ? THIN_UP_BOX : EMBOSSED_BOX);
- PProg->labelcolor(GRAY10);
+ PProg = new CustProgressBox(p_xpos,p_ypos,pw,bh);
+ PProg->labelsize(12);
+ PProg->box(thin_up ? FL_THIN_UP_BOX : FL_EMBOSSED_BOX);
+ PProg->labelcolor(FL_GRAY_RAMP + 2);
PProg->update_label(wide ? "Page\n0.0KB" : "0.0KB");
- ProgBox->type(PackedGroup::ALL_CHILDREN_VERTICAL);
- ProgBox->end();
-
- return ProgBox;
}
/*
* Create the "File" menu
* Static function for File menu callbacks.
*/
-Widget *UI::make_filemenu_button()
+Fl_Widget *UI::make_filemenu_button()
{
- HighlightButton *btn;
- int w,h, padding;
+ Fl_Button *btn;
+ int w = 0, h = 0, padding;
- FileButton = btn = new HighlightButton(0,0,0,0,"W");
+ FileButton = btn = new Fl_Button(p_xpos,0,bw,bh,"W");
+ btn->labeltype(FL_FREE_LABELTYPE);
btn->measure_label(w, h);
padding = w;
btn->copy_label(PanelSize == P_tiny ? "&F" : "&File");
btn->measure_label(w,h);
- if (PanelSize == P_large)
- h = fh;
- btn->resize(w+padding,h);
+ h = (PanelSize == P_tiny) ? bh : lh;
+ btn->size(w+padding, h);
+ p_xpos += btn->w();
_MSG("UI::make_filemenu_button w=%d h=%d padding=%d\n", w, h, padding);
- btn->box(PanelSize == P_large ? FLAT_BOX : THIN_UP_BOX);
+ btn->box(FL_THIN_UP_BOX);
btn->callback(filemenu_cb, this);
- if (prefs.show_tooltip)
- btn->tooltip("File menu");
- btn->clear_tab_to_focus();
- if (!prefs.show_filemenu && PanelSize != P_large)
+ btn->tooltip("File menu");
+ btn->clear_visible_focus();
+ if (!prefs.show_filemenu)
btn->hide();
return btn;
}
@@ -551,216 +513,173 @@ Widget *UI::make_filemenu_button()
/*
* Create the control panel
*/
-Group *UI::make_panel(int ww)
+void UI::make_panel(int ww)
{
- Widget *w;
- Group *g1, *g2, *g3;
- PackedGroup *pg;
-
- if (PanelSize > P_large) {
- PanelSize = P_tiny;
- Small_Icons = !Small_Icons;
- }
+ Fl_Widget *w;
if (Small_Icons)
icons = &small_icons;
else
icons = &standard_icons;
+ pw = 70;
+ p_xpos = p_ypos = 0;
if (PanelSize == P_tiny) {
if (Small_Icons)
- xpos = 0, bw = 22, bh = 22, fh = 0, lh = 22, lbl = 0;
+ bw = 22, bh = 22, mh = 0, lh = 22, lbl = 0;
else
- xpos = 0, bw = 28, bh = 28, fh = 0, lh = 28, lbl = 0;
+ bw = 28, bh = 28, mh = 0, lh = 28, lbl = 0;
} else if (PanelSize == P_small) {
if (Small_Icons)
- xpos = 0, bw = 20, bh = 20, fh = 0, lh = 20, lbl = 0;
+ bw = 20, bh = 20, mh = 0, lh = 20, lbl = 0;
else
- xpos = 0, bw = 28, bh = 28, fh = 0, lh = 28, lbl = 0;
+ bw = 28, bh = 28, mh = 0, lh = 28, lbl = 0;
} else if (PanelSize == P_medium) {
if (Small_Icons)
- xpos = 0, bw = 42, bh = 36, fh = 0, lh = 22, lbl = 1;
- else
- xpos = 0, bw = 45, bh = 45, fh = 0, lh = 28, lbl = 1;
- } else { // P_large
- if (Small_Icons)
- xpos = 0, bw = 42, bh = 36, fh = 22, lh = 22, lbl = 1;
+ bw = 42, bh = 36, mh = 0, lh = 22, lbl = 1;
else
- xpos = 0, bw = 45, bh = 45, fh = 24, lh = 28, lbl = 1;
+ bw = 45, bh = 45, mh = 0, lh = 28, lbl = 1;
}
+ nh = bh, fh = 28; sh = 20;
+ current(0);
if (PanelSize == P_tiny) {
- g1 = new Group(0,0,ww,bh);
- // Toolbar
- pg = make_toolbar(ww,bh);
- pg->box(EMBOSSED_BOX);
- g1->add(pg);
- w = make_filemenu_button();
- pg->add(w);
- w = make_location();
- pg->add(w);
- pg->resizable(w);
- w = make_progress_bars(0,1);
- pg->add(w);
-
- g1->resizable(pg);
-
+ NavBar = new CustGroupHorizontal(0,0,ww,nh);
+ NavBar->box(FL_NO_BOX);
+ NavBar->begin();
+ make_toolbar(ww,bh);
+ make_filemenu_button();
+ make_location(ww);
+ NavBar->resizable(Location);
+ make_progress_bars(0,1);
+ NavBar->box(FL_THIN_UP_FRAME);
+ NavBar->end();
+ NavBar->rearrange();
+ TopGroup->insert(*NavBar,0);
} else {
- g1 = new Group(0,0,ww,fh+lh+bh);
- g1->begin();
- // File menu
- if (PanelSize == P_large) {
- g3 = new Group(0,0,ww,lh);
- g3->box(FLAT_BOX);
- Widget *bn = make_filemenu_button();
- g3->add(bn);
- g3->add_resizable(*new InvisibleBox(bn->w(),0,ww - bn->w(),lh));
-
- g2 = new Group(0,fh,ww,lh);
- g2->begin();
- pg = make_location();
- pg->resize(ww,lh);
- } else {
- g2 = new PackedGroup(0,fh,ww,lh);
- g2->type(PackedGroup::ALL_CHILDREN_VERTICAL);
- g2->begin();
- make_filemenu_button();
- pg = make_location();
- }
-
- g2->resizable(pg);
- g2->end();
+ // Location
+ LocBar = new CustGroupHorizontal(0,0,ww,lh);
+ LocBar->box(FL_NO_BOX);
+ LocBar->begin();
+ p_xpos = 0;
+ make_filemenu_button();
+ make_location(ww);
+ LocBar->resizable(Location);
+ LocBar->end();
+ LocBar->rearrange();
+ TopGroup->insert(*LocBar,0);
// Toolbar
- g3 = new Group(0,fh+lh,ww,bh);
- g3->begin();
- pg = make_toolbar(ww,bh);
- //w = new InvisibleBox(0,0,0,0,"i n v i s i b l e");
- w = new InvisibleBox(0,0,0,0,0);
- pg->add(w);
- pg->resizable(w);
-
+ p_ypos = 0;
+ NavBar = new CustGroupHorizontal(0,0,ww,bh);
+ NavBar->box(FL_NO_BOX);
+ NavBar->begin();
+ make_toolbar(ww,bh);
+ w = new Fl_Box(p_xpos,0,ww-p_xpos-2*pw,bh);
+ w->box(FL_FLAT_BOX);
+ NavBar->resizable(w);
+ p_xpos = ww - 2*pw;
if (PanelSize == P_small) {
- w = make_progress_bars(0,0);
+ make_progress_bars(0,0);
} else {
- w = make_progress_bars(1,0);
+ make_progress_bars(1,0);
}
- pg->add(w);
-
- g3->resizable(pg); // Better than 'w3' and it also works
- pg->box(BORDER_FRAME);
- //g3->box(EMBOSSED_BOX);
- g3->end();
-
- g1->resizable(g3);
- g1->end();
+ NavBar->end();
+ NavBar->rearrange();
+ TopGroup->insert(*NavBar,1);
}
-
- return g1;
}
/*
* Create the status panel
*/
-Group *UI::make_status_panel(int ww)
+void UI::make_status_bar(int ww, int wh)
{
- const int s_h = 20, bm_w = 16;
- Group *g = new Group(0, 0, ww, s_h, 0);
-
- // Status box
- Status = new Output(0, 0, ww-bm_w, s_h, 0);
- Status->value("");
- Status->box(THIN_DOWN_BOX);
- Status->clear_click_to_focus();
- Status->clear_tab_to_focus();
- Status->color(GRAY80);
- g->add(Status);
- //Status->throw_focus();
-
- // Bug Meter
- BugMeter = new HighlightButton(ww-bm_w,0,bm_w,s_h,0);
- BugMeter->image(icons->ImgMeterOK);
- BugMeter->box(THIN_DOWN_BOX);
- BugMeter->align(ALIGN_INSIDE|ALIGN_CLIP|ALIGN_LEFT);
- if (prefs.show_tooltip)
- BugMeter->tooltip("Show HTML bugs\n(right-click for menu)");
- BugMeter->callback(bugmeter_cb, this);
- BugMeter->clear_tab_to_focus();
- g->add(BugMeter);
-
- g->resizable(Status);
- return g;
+ const int bm_w = 20;
+ StatusBar = new CustGroupHorizontal(0, wh-sh, ww, sh);
+ StatusBar->box(FL_NO_BOX);
+
+ // Status box
+ StatusOutput = new Fl_Output(0, wh-sh, ww-bm_w, sh);
+ StatusOutput->value("http://www.dillo.org");
+ StatusOutput->labelsize(8);
+ StatusOutput->box(FL_THIN_DOWN_BOX);
+ StatusOutput->clear_visible_focus();
+ StatusOutput->color(FL_GRAY_RAMP + 18);
+
+ // Bug Meter
+ BugMeter = new CustLightButton(ww-bm_w,wh-sh,bm_w,sh);
+ BugMeter->image(icons->ImgMeterOK);
+ BugMeter->box(FL_THIN_DOWN_BOX);
+ BugMeter->align(FL_ALIGN_INSIDE | FL_ALIGN_TEXT_NEXT_TO_IMAGE);
+ BugMeter->tooltip("Show HTML bugs\n(right-click for menu)");
+ BugMeter->callback(bugmeter_cb, this);
+ BugMeter->clear_visible_focus();
+
+ StatusBar->end();
+ StatusBar->resizable(StatusOutput);
+ StatusBar->rearrange();
}
/*
* User Interface constructor
*/
-UI::UI(int x, int y, int ww, int wh, const char* label, const UI *cur_ui) :
- Group(x, y, ww, wh, label)
+UI::UI(int x, int y, int ui_w, int ui_h, const char* label, const UI *cur_ui) :
+ CustGroupVertical(x, y, ui_w, ui_h, label)
{
- PointerOnLink = FALSE;
+ LocBar = NavBar = StatusBar = NULL;
Tabs = NULL;
TabTooltip = NULL;
- TopGroup = new PackedGroup(0, 0, ww, wh);
- add(TopGroup);
- resizable(TopGroup);
- set_flag(RAW_LABEL);
+ TopGroup = this;
+ TopGroup->box(FL_NO_BOX);
+ clear_flag(SHORTCUT_LABEL);
+ PanelTemporary = false;
if (cur_ui) {
PanelSize = cur_ui->PanelSize;
CuteColor = cur_ui->CuteColor;
Small_Icons = cur_ui->Small_Icons;
- if (cur_ui->Panelmode == UI_HIDDEN ||
- cur_ui->Panelmode == UI_TEMPORARILY_SHOW_PANELS)
- Panelmode = UI_HIDDEN;
- else
- Panelmode = UI_NORMAL;
+ Panelmode = cur_ui->Panelmode;
} else {
// Set some default values
- //PanelSize = P_tiny, CuteColor = 26, Small_Icons = 0;
PanelSize = prefs.panel_size;
Small_Icons = prefs.small_icons;
CuteColor = 206;
- Panelmode = (UIPanelmode) prefs.fullwindow_start;
+ Panelmode = (prefs.fullwindow_start) ? UI_HIDDEN : UI_NORMAL;
}
// Control panel
- Panel = make_panel(ww);
- TopGroup->add(Panel);
-
- // Render area
- Main = new Widget(0,0,1,1,"Welcome...");
- Main->box(FLAT_BOX);
- Main->color(GRAY15);
- Main->labelfont(HELVETICA_BOLD_ITALIC);
- Main->labelsize(36);
- Main->labeltype(SHADOW_LABEL);
- Main->labelcolor(WHITE);
- TopGroup->add(Main);
- TopGroup->resizable(Main);
- MainIdx = TopGroup->find(Main);
-
- // Find text bar
- findbar = new Findbar(ww, 28);
- TopGroup->add(findbar);
-
- // Status Panel
- StatusPanel = make_status_panel(ww);
- TopGroup->add(StatusPanel);
-
- // Make the full screen button (to be attached to the viewport later)
- // TODO: attach to the viewport
- //FullScreen = new HighlightButton(0,0,15,15);
- //FullScreen->image(ImgFullScreenOn);
- //FullScreen->tooltip("Hide Controls");
- //FullScreen->callback(fullscreen_cb, this);
+ TopGroup->begin();
+ make_panel(ui_w);
+
+ // Render area
+ Main = new Fl_Group(0,0,0,0,"Welcome..."); // size is set by rearrange()
+ Main->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
+ Main->box(FL_FLAT_BOX);
+ Main->color(FL_GRAY_RAMP + 3);
+ Main->labelfont(FL_HELVETICA_BOLD_ITALIC);
+ Main->labelsize(36);
+ Main->labeltype(FL_SHADOW_LABEL);
+ Main->labelcolor(FL_WHITE);
+ TopGroup->add(Main);
+ TopGroup->resizable(Main);
+ MainIdx = TopGroup->find(Main);
+
+ // Find text bar
+ FindBar = new Findbar(ui_w, fh);
+ TopGroup->add(FindBar);
+
+ // Status Panel
+ make_status_bar(ui_w, ui_h);
+ TopGroup->add(StatusBar);
+ TopGroup->end();
+ TopGroup->rearrange();
customize(0);
- if (Panelmode) {
- Panel->hide();
- StatusPanel->hide();
+ if (Panelmode == UI_HIDDEN) {
+ panels_toggle();
}
}
@@ -778,18 +697,27 @@ UI::~UI()
*/
int UI::handle(int event)
{
- _MSG("UI::handle event=%d (%d,%d)\n", event, event_x(), event_y());
- _MSG("Panel->h()=%d Main->h()=%d\n", Panel->h() , Main->h());
+ _MSG("UI::handle event=%s\n", fl_eventnames[event]);
int ret = 0;
+ if (event == FL_KEYBOARD) {
+ /* WORKAROUND: remove the Panel's fltk-tooltip.
+ * Although the expose event is delivered, it has an offset. This
+ * extra call avoids the lingering tooltip. */
+ if (!Fl::event_inside(Main) &&
+ (Fl::event_inside((Fl_Widget*)tabs()) ||
+ Fl::event_inside(NavBar) ||
+ (LocBar && Fl::event_inside(LocBar)) ||
+ (StatusBar && Fl::event_inside(StatusBar))))
+ window()->damage(FL_DAMAGE_EXPOSE,0,0,1,1);
- if (event == KEY) {
return 0; // Receive as shortcut
- } else if (event == SHORTCUT) {
+ } else if (event == FL_SHORTCUT) {
KeysCommand_t cmd = Keys::getKeyCmd();
if (cmd == KEYS_NOP) {
// Do nothing
} else if (cmd == KEYS_SCREEN_UP || cmd == KEYS_SCREEN_DOWN ||
+ cmd == KEYS_SCREEN_LEFT || cmd == KEYS_SCREEN_RIGHT ||
cmd == KEYS_LINE_UP || cmd == KEYS_LINE_DOWN ||
cmd == KEYS_LEFT || cmd == KEYS_RIGHT ||
cmd == KEYS_TOP || cmd == KEYS_BOTTOM) {
@@ -805,26 +733,22 @@ int UI::handle(int event)
a_UIcmd_book(a_UIcmd_get_bw_by_widget(this));
ret = 1;
} else if (cmd == KEYS_FIND) {
- set_findbar_visibility(1);
+ findbar_toggle(1);
ret = 1;
} else if (cmd == KEYS_WEBSEARCH) {
a_UIcmd_search_dialog(a_UIcmd_get_bw_by_widget(this));
ret = 1;
} else if (cmd == KEYS_GOTO) {
+ if (Panelmode == UI_HIDDEN) {
+ panels_toggle();
+ temporaryPanels(true);
+ }
focus_location();
ret = 1;
- } else if (cmd == KEYS_NEW_TAB) {
- a_UIcmd_open_url_nt(a_UIcmd_get_bw_by_widget(this), NULL, 1);
- ret = 1;
- } else if (cmd == KEYS_CLOSE_TAB) {
- a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(this));
- ret = 1;
- } else if (cmd == KEYS_HIDE_PANELS &&
- get_panelmode() == UI_TEMPORARILY_SHOW_PANELS) {
- set_panelmode(UI_HIDDEN);
- ret = 1;
- } else if (cmd == KEYS_NEW_WINDOW) {
- a_UIcmd_browser_window_new(w(),h(),0,a_UIcmd_get_bw_by_widget(this));
+ } else if (cmd == KEYS_HIDE_PANELS) {
+ /* Hide findbar if present, hide panels if not */
+ (FindBar->visible()) ? findbar_toggle(0) : panels_toggle();
+ temporaryPanels(false);
ret = 1;
} else if (cmd == KEYS_OPEN) {
a_UIcmd_open_file(a_UIcmd_get_bw_by_widget(this));
@@ -841,40 +765,26 @@ int UI::handle(int event)
} else if (cmd == KEYS_SAVE) {
a_UIcmd_save(a_UIcmd_get_bw_by_widget(this));
ret = 1;
- } else if (cmd == KEYS_FULLSCREEN) {
- panelmode_cb_i();
- ret = 1;
} else if (cmd == KEYS_FILE_MENU) {
a_UIcmd_file_popup(a_UIcmd_get_bw_by_widget(this), FileButton);
ret = 1;
- } else if (cmd == KEYS_CLOSE_ALL) {
- a_Timeout_add(0.0, a_UIcmd_close_all_bw, NULL);
- ret = 1;
}
- } else if (event == PUSH) {
- if (prefs.middle_click_drags_page == 0 &&
- event_button() == MiddleButton &&
- !a_UIcmd_pointer_on_link(a_UIcmd_get_bw_by_widget(this))) {
- if (Main->Rectangle::contains (event_x (), event_y ())) {
- /* Offer the event to Main's children (form widgets) */
- int save_x = e_x, save_y = e_y;
-
- e_x -= Main->x();
- e_y -= Main->y();
- ret = ((Group *)Main)->Group::handle(event);
- e_x = save_x;
- e_y = save_y;
- }
- if (!ret) {
- /* middle click was not on a link or a form widget */
- paste_url();
- ret = 1;
- }
+ } else if (event == FL_RELEASE) {
+ if (Fl::event_button() == FL_MIDDLE_MOUSE &&
+ prefs.middle_click_drags_page == 0) {
+ /* nobody claimed the event; try paste */
+ paste_url();
+ ret = 1;
}
}
if (!ret) {
- ret = Group::handle(event);
+ ret = Fl_Group::handle(event);
+ }
+ if (!ret && event == FL_PUSH && !prefs.middle_click_drags_page) {
+ /* nobody claimed FL_PUSH: ask for FL_RELEASE,
+ * which is necessary for middle-click paste URL) */
+ ret = 1;
}
return ret;
@@ -899,9 +809,7 @@ const char *UI::get_location()
void UI::set_location(const char *str)
{
if (!str) str = "";
- // This text() call clears fl_pending_callback, avoiding
- // an extra location_cb() call.
- Location->text(str);
+ Location->value(str);
Location->position(strlen(str));
}
@@ -911,9 +819,6 @@ void UI::set_location(const char *str)
*/
void UI::focus_location()
{
- if (get_panelmode() == UI_HIDDEN) {
- set_panelmode(UI_TEMPORARILY_SHOW_PANELS);
- }
Location->take_focus();
// Make text selected when already focused.
Location->position(Location->size(), 0);
@@ -932,7 +837,7 @@ void UI::focus_main()
*/
void UI::set_status(const char *str)
{
- Status->value(str);
+ StatusOutput->value(str);
}
/*
@@ -985,7 +890,7 @@ void UI::set_img_prog(int n_img, int t_img, int cmd)
void UI::set_bug_prog(int n_bug)
{
char str[32];
- int new_w = 16;
+ int new_w = 20;
if (n_bug == 0) {
BugMeter->image(icons->ImgMeterOK);
@@ -995,12 +900,10 @@ void UI::set_bug_prog(int n_bug)
BugMeter->image(icons->ImgMeterBug);
snprintf(str, 32, "%d", n_bug);
BugMeter->copy_label(str);
- BugMeter->redraw_label();
- new_w = strlen(str)*8 + 20;
+ new_w = strlen(str)*9 + 20;
}
- Status->resize(0,0,StatusPanel->w()-new_w,Status->h());
- BugMeter->resize(StatusPanel->w()-new_w, 0, new_w, BugMeter->h());
- StatusPanel->init_sizes();
+ BugMeter->size(new_w, BugMeter->h());
+ StatusBar->rearrange();
}
/*
@@ -1034,25 +937,40 @@ void UI::customize(int flags)
Search->hide();
if ( !prefs.show_help )
Help->hide();
- if ( !prefs.show_progress_box )
- ProgBox->hide();
+ if ( !prefs.show_progress_box ) {
+ IProg->hide();
+ PProg->hide();
+ }
+
+ if (NavBar)
+ NavBar->rearrange();
+ if (LocBar)
+ LocBar->rearrange();
}
/*
* On-the-fly panel style change
*/
-void UI::panel_cb_i()
+void UI::change_panel(int new_size, int small_icons)
{
- Group *NewPanel;
-
- // Create a new Panel
- ++PanelSize;
- NewPanel = make_panel(TopGroup->w());
- TopGroup->replace(*Panel, *NewPanel);
- delete(Panel);
- Panel = NewPanel;
+ // Remove current panel's bars
+ init_sizes();
+ TopGroup->remove(LocBar);
+ Fl::delete_widget(LocBar);
+ TopGroup->remove(NavBar);
+ Fl::delete_widget(NavBar);
+ LocBar = NavBar = NULL;
+
+ // Set internal vars for panel size
+ PanelSize = new_size;
+ Small_Icons = small_icons;
+
+ // make a new panel
+ make_panel(TopGroup->w());
customize(0);
+ a_UIcmd_set_buttons_sens(a_UIcmd_get_bw_by_widget(this));
+ TopGroup->rearrange();
Location->take_focus();
}
@@ -1069,88 +987,21 @@ void UI::color_change_cb_i()
MSG("Location color %d\n", CuteColor);
Location->color(CuteColor);
Location->redraw();
- HighlightButton::default_style->highlight_color(CuteColor);
-}
-
-/*
- * Set or remove the Panelmode flag and update the UI accordingly
- */
-void UI::set_panelmode(UIPanelmode mode)
-{
- if (mode == UI_HIDDEN) {
- Panel->hide();
- StatusPanel->hide();
- } else {
- /* UI_NORMAL or UI_TEMPORARILY_SHOW_PANELS */
- Panel->show();
- StatusPanel->show();
- }
- Panelmode = mode;
-}
-
-/*
- * Get the value of the panelmode flag
- */
-UIPanelmode UI::get_panelmode()
-{
- return Panelmode;
-}
-
-/*
- * Toggle the Control Panel out of the way
- */
-void UI::panelmode_cb_i()
-{
- set_panelmode((UIPanelmode) !Panelmode);
}
/*
* Set 'nw' as the main render area widget
*/
-void UI::set_render_layout(Widget &nw)
+void UI::set_render_layout(Fl_Group *nw)
{
- // BUG: replace() is not working as it should.
- // In our case, replacing the rendering area leaves the vertical
- // scrollbar without events.
- //
- // We'll use a workaround in a_UIcmd_browser_window_new() instead.
- TopGroup->replace(MainIdx, nw);
- delete(Main);
- Main = &nw;
- //TopGroup->box(DOWN_BOX);
- //TopGroup->box(BORDER_FRAME);
- TopGroup->resizable(TopGroup->child(MainIdx));
-}
+ // Resize layout widget to current height
+ nw->resize(0,Main->y(),Main->w(),Main->h());
-/*
- * Set the tab title
- */
-void UI::set_tab_title(const char *label)
-{
- char title[128];
-
- dReturn_if_fail(label != NULL);
-
- if (*label) {
- // Make a label for this tab
- size_t tab_chars = 18, label_len = strlen(label);
-
- if (label_len > tab_chars)
- tab_chars = a_Utf8_end_of_char(label, tab_chars - 1) + 1;
- snprintf(title, tab_chars + 1, "%s", label);
- if (label_len > tab_chars)
- snprintf(title + tab_chars, 4, "...");
- // Avoid unnecessary redraws
- if (strcmp(this->label(), title)) {
- this->copy_label(title);
- this->redraw_label();
- }
-
- // Disabled because of a bug in fltk::Tabgroup
- //dFree(TabTooltip);
- //TabTooltip = dStrdup(label);
- //this->tooltip(TabTooltip);
- }
+ TopGroup->insert(*nw, Main);
+ remove(Main);
+ delete(Main);
+ Main = nw;
+ TopGroup->resizable(Main);
}
/*
@@ -1161,15 +1012,12 @@ void UI::button_set_sens(UIButton btn, int sens)
switch (btn) {
case UI_BACK:
(sens) ? Back->activate() : Back->deactivate();
- Back->redraw(DAMAGE_HIGHLIGHT);
break;
case UI_FORW:
(sens) ? Forw->activate() : Forw->deactivate();
- Forw->redraw(DAMAGE_HIGHLIGHT);
break;
case UI_STOP:
(sens) ? Stop->activate() : Stop->deactivate();
- Stop->redraw(DAMAGE_HIGHLIGHT);
break;
default:
break;
@@ -1181,17 +1029,63 @@ void UI::button_set_sens(UIButton btn, int sens)
*/
void UI::paste_url()
{
- paste(*Clear, false);
+ Fl::paste(*Clear, false);
}
/*
- * Shows or hides the findbar of this window
+ * Adjust space for the findbar (if necessary) and show or remove it
*/
-void UI::set_findbar_visibility(bool visible)
+void UI::findbar_toggle(bool add)
{
- if (visible) {
- findbar->show();
+ /* WORKAROUND:
+ * This is tricky: As fltk-1.3 resizes hidden widgets (which it
+ * doesn't resize when visible!). We need to set the size to (0,0) to
+ * get the desired behaviour.
+ * (STR#2639 in FLTK bug tracker).
+ */
+
+ if (add) {
+ if (!FindBar->visible())
+ FindBar->size(w(), fh);
+ FindBar->show();
} else {
- findbar->hide();
+ // hide
+ FindBar->size(0,0);
+ FindBar->hide();
+ // reset state
+ a_UIcmd_findtext_reset(a_UIcmd_get_bw_by_widget(this));
+ // focus main area
+ focus_main();
+ }
+ TopGroup->rearrange();
+}
+
+/*
+ * Make panels disappear growing the render area.
+ * WORKAROUND: here we avoid hidden widgets resize by setting their
+ * size to (0,0) while hidden.
+ * (Already reported to FLTK team)
+ */
+void UI::panels_toggle()
+{
+ int hide = StatusBar->visible();
+
+ // hide/show panels
+ init_sizes();
+ if (LocBar) {
+ hide ? LocBar->size(0,0) : LocBar->size(w(),lh);
+ hide ? LocBar->hide() : LocBar->show();
}
+ if (NavBar) {
+ hide ? NavBar->size(0,0) : NavBar->size(w(),nh);
+ hide ? NavBar->hide() : NavBar->show();
+ }
+ if (StatusBar) {
+ hide ? StatusBar->size(0,0) : StatusBar->size(w(),sh);;
+ hide ? StatusBar->hide() : StatusBar->show();;
+ StatusBar->rearrange();
+ }
+
+ TopGroup->rearrange();
+ Panelmode = (hide) ? UI_HIDDEN : UI_NORMAL;
}
diff --git a/src/ui.hh b/src/ui.hh
index 9e1b6d4f..775a35ed 100644
--- a/src/ui.hh
+++ b/src/ui.hh
@@ -3,16 +3,13 @@
// UI for dillo --------------------------------------------------------------
-#include <fltk/Window.h>
-#include <fltk/Widget.h>
-#include <fltk/Button.h>
-#include <fltk/Input.h>
-#include <fltk/PackedGroup.h>
-#include <fltk/Output.h>
-#include <fltk/Image.h>
-#include <fltk/MultiImage.h>
-#include <fltk/MenuBuild.h>
-#include <fltk/TabGroup.h>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Output.H>
+#include <FL/Fl_Image.H>
+#include <FL/Fl_Tabs.H>
#include "findbar.hh"
@@ -31,47 +28,153 @@ typedef enum {
typedef enum {
UI_NORMAL = 0, /* make sure it's compatible with bool */
- UI_HIDDEN = 1,
- UI_TEMPORARILY_SHOW_PANELS
+ UI_HIDDEN = 1
} UIPanelmode;
+
+// Min size to fit the full UI
+#define UI_MIN_W 600
+#define UI_MIN_H 200
+
// Private classes
class CustProgressBox;
-class CustTabGroup;
+class CustTabs;
+
+
+// Class definitions ---------------------------------------------------------
+/*
+ * Used to reposition group's widgets when some of them are hidden.
+ * All children get the height of the group but retain their original width.
+ * The resizable child get's the remaining space.
+ */
+class CustGroupHorizontal : public Fl_Group {
+ Fl_Widget *rsz;
+public:
+ CustGroupHorizontal(int x,int y,int w ,int h,const char *l = 0) :
+ Fl_Group(x,y,w,h,l) { };
+
+ void rearrange() {
+ Fl_Widget*const* a = array();
+ int sum = 0, _x = x();
+ int children_ = children();
+
+ if (resizable())
+ rsz = resizable();
+
+ for (int i=0; i < children_; i++)
+ if (a[i] != resizable() && a[i]->visible())
+ sum += a[i]->w();
+
+ for (int i=0; i < children_; i++) {
+ if (a[i] == rsz) {
+ if (w() > sum) {
+ a[i]->resize(_x, y(), w()-sum, h());
+ if (!resizable())
+ resizable(rsz);
+ } else {
+ /* widgets overflow width */
+ a[i]->resize(_x, y(), 0, h());
+ resizable(NULL);
+ }
+ } else {
+ a[i]->resize(_x, y(), a[i]->w(), h());
+ }
+ if (a[i]->visible())
+ _x += a[i]->w();
+ }
+ init_sizes();
+ redraw();
+ }
+};
+
+class CustGroupVertical : public Fl_Group {
+public:
+ CustGroupVertical(int x,int y,int w ,int h,const char *l = 0) :
+ Fl_Group(x,y,w,h,l) { };
+
+ void rearrange() {
+ Fl_Widget*const* a = array();
+ int sum = 0, _y = y();
+ int children_ = children();
+
+ for (int i=0; i < children_; i++)
+ if (a[i] != resizable() && a[i]->visible())
+ sum += a[i]->h();
+
+ for (int i=0; i < children_; i++) {
+ if (a[i] == resizable()) {
+ a[i]->resize(x(), _y, w(), h() - sum);
+ } else {
+ a[i]->resize(x(), _y, w(), a[i]->h());
+ }
+ if (a[i]->visible())
+ _y += a[i]->h();
+ }
+ init_sizes();
+ redraw();
+ }
+};
+
+/*
+ * A button that highlights on mouse over
+ */
+class CustLightButton : public Fl_Button {
+ Fl_Color norm_color, light_color;
+public:
+ CustLightButton(int x, int y, int w, int h, const char *l=0) :
+ Fl_Button(x,y,w,h,l) { norm_color = color(); light_color = 51; };
+ virtual int handle(int e)
+ {
+ if (active()) {
+ if (e == FL_ENTER) {
+ color(light_color); // {17,26,51}
+ redraw();
+ } else if (e == FL_LEAVE || e == FL_RELEASE || e == FL_HIDE) {
+ color(norm_color);
+ redraw();
+ }
+ } else if (e == FL_DEACTIVATE && color() != norm_color) {
+ color(norm_color);
+ redraw();
+ }
+ return Fl_Button::handle(e);
+ }
+ void hl_color(Fl_Color col) { light_color = col; };
+};
//
// UI class definition -------------------------------------------------------
//
-class UI : public fltk::Group {
- CustTabGroup *Tabs;
+class UI : public CustGroupVertical {
+ CustTabs *Tabs;
char *TabTooltip;
- fltk::Group *TopGroup;
- fltk::Button *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks, *Tools,
- *Clear, *Search, *Help, *FullScreen, *BugMeter, *FileButton;
- fltk::Input *Location;
- fltk::PackedGroup *ProgBox;
+ CustGroupVertical *TopGroup;
+ Fl_Button *Back, *Forw, *Home, *Reload, *Save, *Stop, *Bookmarks, *Tools,
+ *Clear, *Search, *Help, *BugMeter, *FileButton;
+ CustGroupHorizontal *LocBar, *NavBar, *StatusBar;
+ Fl_Input *Location;
CustProgressBox *PProg, *IProg;
- fltk::Group *Panel, *StatusPanel;
- fltk::Widget *Main;
- fltk::Output *Status;
+ Fl_Group *Panel, *Main;
+ Fl_Output *StatusOutput;
+ Findbar *FindBar;
int MainIdx;
// Panel customization variables
int PanelSize, CuteColor, Small_Icons;
- int xpos, bw, bh, fh, lh, lbl;
+ int p_xpos, p_ypos, bw, bh, mh, lh, nh, fh, sh, pw, lbl;
+ bool PanelTemporary;
UIPanelmode Panelmode;
- Findbar *findbar;
- int PointerOnLink;
-
- fltk::PackedGroup *make_toolbar(int tw, int th);
- fltk::PackedGroup *make_location();
- fltk::PackedGroup *make_progress_bars(int wide, int thin_up);
+ Fl_Button *make_button(const char *label, Fl_Image *img,
+ Fl_Image*deimg, int b_n, int start = 0);
+ void make_toolbar(int tw, int th);
+ void make_location(int ww);
+ void make_progress_bars(int wide, int thin_up);
void make_menubar(int x, int y, int w, int h);
- fltk::Widget *make_filemenu_button();
- fltk::Group *make_panel(int ww);
- fltk::Group *make_status_panel(int ww);
+ Fl_Widget *make_filemenu_button();
+ void make_panel(int ww);
+ void make_status_bar(int ww, int wh);
public:
@@ -89,27 +192,24 @@ public:
void set_page_prog(size_t nbytes, int cmd);
void set_img_prog(int n_img, int t_img, int cmd);
void set_bug_prog(int n_bug);
- void set_render_layout(Widget &nw);
- void set_tab_title(const char *label);
+ void set_render_layout(Fl_Group *nw);
void customize(int flags);
void button_set_sens(UIButton btn, int sens);
void paste_url();
- void set_panelmode(UIPanelmode mode);
- UIPanelmode get_panelmode();
- void set_findbar_visibility(bool visible);
- Widget *fullscreen_button() { return FullScreen; }
- void fullscreen_toggle() { FullScreen->do_callback(); }
+ int get_panelsize() { return PanelSize; }
+ int get_smallicons() { return Small_Icons; }
+ void change_panel(int new_size, int small_icons);
+ void findbar_toggle(bool add);
+ void panels_toggle();
- CustTabGroup *tabs() { return Tabs; }
- void tabs(CustTabGroup *tabs) { Tabs = tabs; }
- int pointerOnLink() { return PointerOnLink; }
- void pointerOnLink(int flag) { PointerOnLink = flag; }
+ CustTabs *tabs() { return Tabs; }
+ void tabs(CustTabs *tabs) { Tabs = tabs; }
+ bool temporaryPanels() { return PanelTemporary; }
+ void temporaryPanels(bool val) { PanelTemporary = val; }
// Hooks to method callbacks
- void panel_cb_i();
void color_change_cb_i();
void toggle_cb_i();
- void panelmode_cb_i();
};
#endif // __UI_HH__
diff --git a/src/uicmd.cc b/src/uicmd.cc
index 5573db11..38225047 100644
--- a/src/uicmd.cc
+++ b/src/uicmd.cc
@@ -1,7 +1,7 @@
/*
* File: uicmd.cc
*
- * Copyright (C) 2005-2007 Jorge Arellano Cid <jcid@dillo.org>
+ * Copyright (C) 2005-2011 Jorge Arellano Cid <jcid@dillo.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,11 +16,14 @@
#include <stdarg.h>
#include <math.h> /* for rint */
-#include <fltk/draw.h>
-#include <fltk/damage.h>
-#include <fltk/Widget.h>
-#include <fltk/TabGroup.h>
-#include <fltk/Tooltip.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/Fl_Double_Window.H>
+#include <FL/Fl_Wizard.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Pack.H>
+#include <FL/Fl_Scroll.H>
+#include <FL/names.h>
#include "paths.hh"
#include "keys.hh"
@@ -35,12 +38,14 @@
#include "history.h"
#include "msg.h"
#include "prefs.h"
+#include "misc.h"
#include "dw/fltkviewport.hh"
#include "nav.h"
-#define DEFAULT_TAB_LABEL "Dillo"
+//#define DEFAULT_TAB_LABEL "-.untitled.-"
+#define DEFAULT_TAB_LABEL "-.new.-"
// Handy macro
#define BW2UI(bw) ((UI*)((bw)->ui))
@@ -56,316 +61,384 @@ using namespace dw::fltk;
*/
static char *save_dir = NULL;
-using namespace fltk;
-
+/*
+ * Forward declarations
+ */
+static BrowserWindow *UIcmd_tab_new(CustTabs *tabs, UI *old_ui, int focus);
+static void close_tab_btn_cb (Fl_Widget *w, void *cb_data);
//----------------------------------------------------------------------------
-#define BTN_W 25
-#define BTN_H 20
-static int btn_x;
+/*
+ * CustTabs ---------------------------------------------------------------
+ */
/*
- * Adds a tab-close button at the rightmost part
+ * stores the respective UI pointer
*/
-class CustShrinkTabPager : public TabGroupPager {
- bool btn_hl;
- TabGroup *tg;
+class CustTabButton : public Fl_Button {
+ UI *ui_;
public:
- int update_positions(
- TabGroup *g, int numchildren, int &selected,
- int &cumulated_width, int &available_width,
- int *tab_pos, int *tab_width);
- virtual int which(TabGroup* g, int m_x,int m_y);
- virtual TabGroupPager* clone() const;
- virtual const char * mode_name() const {return "Shrink";}
- virtual int id() const {return PAGER_SHRINK;}
- virtual int available_width(TabGroup *g) const;
- virtual bool draw_tabs(TabGroup* g, int selected, int* tab_pos,
- int* tab_width) {
- if (!tg) tg = g;
- if (g->children() > 1) {
- fltk::Rectangle r(btn_x,0,BTN_W,BTN_H);
- setcolor(btn_hl ? 206 : GRAY75);
- fillrect(r);
- if (btn_hl) {
- setcolor(WHITE);
- strokerect(r);
- }
- setcolor(GRAY10);
- //fltk::setfont(fltk::getfont()->bold(), fltk::getsize());
- r.h(r.h()-2);
- drawtext("X", r, ALIGN_CENTER);
- return false;
- } else {
- // WORKAROUND: for http://fltk.org/str.php?L2062
- // By returning true we avoid a call to TabGroup::draw_tab()
- // in TabGroup::draw() in case we don't show the tabs.
- return true;
- }
- }
+ CustTabButton (int x,int y,int w,int h, const char* label = 0) :
+ Fl_Button (x,y,w,h,label) { ui_ = NULL; };
+ void ui(UI *pui) { ui_ = pui; }
+ UI *ui(void) { return ui_; }
+};
- void btn_highlight(bool flag) {
- if (btn_hl != flag) {
- btn_hl = flag;
- if (tg)
- tg->redraw(DAMAGE_VALUE);
- }
- };
- bool btn_highlight() { return btn_hl; };
+/*
+ * Allows fine control of the tabbed interface
+ */
+class CustTabs : public Fl_Group {
+ int tab_w, tab_h, ctab_h, btn_w, ctl_w;
+ Fl_Wizard *Wizard;
+ Fl_Scroll *Scroll;
+ Fl_Pack *Pack;
+ Fl_Group *Control;
+ CustLightButton *CloseBtn;
+ int tabcolor_inactive, tabcolor_active;
- CustShrinkTabPager() : TabGroupPager() {
- noclip(true);
- btn_hl = false;
- tg = NULL;
- }
+ void update_pack_offset(void);
+ void resize(int x, int y, int w, int h)
+ { Fl_Group::resize(x,y,w,h); update_pack_offset(); }
+ int get_btn_idx(UI *ui);
+
+public:
+ CustTabs (int ww, int wh, int th, const char *lbl=0) :
+ Fl_Group(0,0,ww,th,lbl) {
+ Pack = NULL;
+ tab_w = 50, tab_h = th, ctab_h = 1, btn_w = 20, ctl_w = 1*btn_w+2;
+ tabcolor_active = 0x87aca700; tabcolor_inactive = 0xb7beb700;
+ resize(0,0,ww,ctab_h);
+ /* tab buttons go inside a pack within a scroll */
+ Scroll = new Fl_Scroll(0,0,ww-ctl_w,ctab_h);
+ Scroll->type(0); /* no scrollbars */
+ Scroll->box(FL_NO_BOX);
+ Pack = new Fl_Pack(0,0,ww-ctl_w,tab_h);
+ Pack->type(Fl_Pack::HORIZONTAL);
+ Pack->box(FL_NO_BOX); //FL_THIN_DOWN_FRAME
+ Pack->end();
+ Scroll->end();
+ resizable(Scroll);
+
+ /* control buttons go inside a group */
+ Control = new Fl_Group(ww-ctl_w,0,ctl_w,ctab_h);
+ CloseBtn = new CustLightButton(ww-ctl_w+2,0,btn_w,ctab_h, "X");
+ CloseBtn->box(FL_THIN_UP_BOX);
+ CloseBtn->labelcolor(0x00641000);
+ CloseBtn->hl_color(FL_WHITE);
+ CloseBtn->clear_visible_focus();
+ CloseBtn->tooltip(prefs.right_click_closes_tab ?
+ "Close current tab.\nor Right-click tab label to close." :
+ "Close current tab.\nor Middle-click tab label to close.");
+ CloseBtn->callback(close_tab_btn_cb, this);
+ CloseBtn->hide();
+ Control->end();
+
+ box(FL_FLAT_BOX);
+ end();
+
+ Wizard = new Fl_Wizard(0,ctab_h,ww,wh-ctab_h);
+ Wizard->box(FL_NO_BOX);
+ Wizard->end();
+ };
+ int handle(int e);
+ UI *add_new_tab(UI *old_ui, int focus);
+ void remove_tab(UI *ui);
+ Fl_Wizard *wizard(void) { return Wizard; }
+ int num_tabs() { return (Pack ? Pack->children() : 0); }
+ void switch_tab(CustTabButton *cbtn);
+ void prev_tab(void);
+ void next_tab(void);
+ void set_tab_label(UI *ui, const char *title);
};
-int CustShrinkTabPager::available_width(TabGroup *g) const
+/*
+ * Callback for mouse click
+ */
+static void tab_btn_cb (Fl_Widget *w, void *cb_data)
{
- _MSG("CustShrinkTabPager::available_width\n");
- int w = MAX (g->w() - this->slope()-1 - BTN_W, 0);
- btn_x = w + 6;
- return w;
+ CustTabButton *btn = (CustTabButton*) w;
+ CustTabs *tabs = (CustTabs*) cb_data;
+ int b = Fl::event_button();
+
+ if (b == FL_LEFT_MOUSE) {
+ tabs->switch_tab(btn);
+ } else if ((b == FL_RIGHT_MOUSE && prefs.right_click_closes_tab) ||
+ (b == FL_MIDDLE_MOUSE && !prefs.right_click_closes_tab)) {
+ // TODO: just an example, not necessarily final
+ a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(btn->ui()));
+ }
}
-int CustShrinkTabPager::which(TabGroup* g, int event_x,int event_y)
+/*
+ * Callback for the close-tab button
+ */
+static void close_tab_btn_cb (Fl_Widget *, void *cb_data)
{
- int H = g->tab_height();
- if (!H) return -1;
- if (H < 0) {
- if (event_y > g->h() || event_y < g->h()+H) return -1;
- } else {
- if (event_y > H || event_y < 0) return -1;
+ CustTabs *tabs = (CustTabs*) cb_data;
+ int b = Fl::event_button();
+
+ if (b == FL_LEFT_MOUSE) {
+ a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(tabs->wizard()->value()));
}
- if (event_x < 0) return -1;
- int p[128], w[128];
- int selected = g->tab_positions(p, w);
- int d = (event_y-(H>=0?0:g->h()))*slope()/H;
- for (int i=0; i<g->children(); i++) {
- if (event_x < p[i+1]+(i<selected ? slope() - d : d)) return i;
+}
+
+int CustTabs::handle(int e)
+{
+ int ret = 0;
+
+ _MSG("CustTabs::handle e=%s\n", fl_eventnames[e]);
+ if (e == FL_KEYBOARD) {
+ return 0; // Receive as shortcut
+ } else if (e == FL_SHORTCUT) {
+ UI *ui = (UI*)wizard()->value();
+ BrowserWindow *bw = a_UIcmd_get_bw_by_widget(ui);
+ KeysCommand_t cmd = Keys::getKeyCmd();
+ if (cmd == KEYS_NOP) {
+ // Do nothing
+ _MSG("CustTabs::handle KEYS_NOP\n");
+ } else if (cmd == KEYS_NEW_TAB) {
+ a_UIcmd_open_url_nt(bw, NULL, 1);
+ ret = 1;
+ } else if (cmd == KEYS_CLOSE_TAB) {
+ a_UIcmd_close_bw(bw);
+ ret = 1;
+ } else if (cmd == KEYS_LEFT_TAB) {
+ prev_tab();
+ ret = 1;
+ } else if (cmd == KEYS_RIGHT_TAB) {
+ next_tab();
+ ret = 1;
+ } else if (cmd == KEYS_NEW_WINDOW) {
+ a_UIcmd_open_url_nw(bw, NULL);
+ ret = 1;
+ } else if (cmd == KEYS_CLOSE_ALL) {
+ a_Timeout_add(0.0, a_UIcmd_close_all_bw, NULL);
+ ret = 1;
+ }
}
- return -1;
+
+ return (ret) ? ret : Fl_Group::handle(e);
}
/*
- * Prevents tabs from going over the close-tab button.
- * Modified from fltk-2.0.x-r6525.
+ * Create a new tab with its own UI
*/
-int CustShrinkTabPager::update_positions(
- TabGroup *g, int numchildren, int &selected,
- int &cumulated_width, int &available_width,
- int *tab_pos, int *tab_width)
+UI *CustTabs::add_new_tab(UI *old_ui, int focus)
{
- available_width-=BTN_W;
-
- // uh oh, they are too big, we must move them:
- // special case when the selected tab itself is too big, make it fill
- // cumulated_width:
- int i;
+ if (num_tabs() == 1) {
+ // Show tabbar
+ ctab_h = tab_h;
+ Wizard->resize(0,ctab_h,Wizard->w(),window()->h()-ctab_h);
+ resize(0,0,window()->w(),ctab_h); // tabbar
+ CloseBtn->show();
+ {int w = 0, h; Pack->child(0)->measure_label(w, h);
+ Pack->child(0)->size(w+14,ctab_h);}
+ Pack->child(0)->show(); // first tab button
+ window()->init_sizes();
+ }
- if (tab_width[selected] >= available_width) {
- tab_width[selected] = available_width;
- for (i = 0; i <= selected; i++)
- tab_pos[i] = 0;
- for (i = selected + 1; i <= numchildren; i++)
- tab_pos[i] = available_width;
- return selected;
+ /* The UI is constructed in a comfortable fitting size, and then resized
+ * so FLTK doesn't get confused later with even smaller dimensions! */
+ current(0);
+ UI *new_ui = new UI(0,0,UI_MIN_W,UI_MIN_H,"Dillo:",old_ui);
+ new_ui->resize(0,ctab_h,Wizard->w(),Wizard->h());
+ new_ui->tabs(this);
+ Wizard->add(new_ui);
+ new_ui->show();
+
+ CustTabButton *btn = new CustTabButton(num_tabs()*tab_w,0,tab_w,ctab_h);
+ btn->align(FL_ALIGN_INSIDE);
+ btn->labelsize(btn->labelsize()-2);
+ btn->copy_label(DEFAULT_TAB_LABEL);
+ btn->clear_visible_focus();
+ btn->box(FL_GTK_THIN_UP_BOX);
+ btn->color(focus ? tabcolor_active : tabcolor_inactive);
+ btn->ui(new_ui);
+ btn->callback(tab_btn_cb, this);
+ Pack->add(btn); // append
+
+ if (focus) {
+ switch_tab(btn);
+ } else if (num_tabs() == 2) {
+ // no focus and tabbar added: redraw current page
+ Wizard->redraw();
}
+ if (num_tabs() == 1)
+ btn->hide();
+ update_pack_offset();
- int w2[128];
+ return new_ui;
+}
- for (i = 0; i < numchildren; i++)
- w2[i] = tab_width[i];
- i = numchildren - 1;
- int j = 0;
+/*
+ * Remove tab by UI
+ */
+void CustTabs::remove_tab(UI *ui)
+{
+ CustTabButton *btn;
- int minsize = 5;
+ // get active tab idx
+ int act_idx = get_btn_idx((UI*)Wizard->value());
+ // get to-be-removed tab idx
+ int rm_idx = get_btn_idx(ui);
+ btn = (CustTabButton*)Pack->child(rm_idx);
- bool right = true;
+ if (act_idx == rm_idx) {
+ // Active tab is being closed, switch to another one
+ rm_idx > 0 ? prev_tab() : next_tab();
+ }
+ Pack->remove(rm_idx);
+ update_pack_offset();
+ delete btn;
- while (cumulated_width > available_width) {
- int n; // which one to shrink
+ Wizard->remove(ui);
+ delete(ui);
- if (j < selected && (!right || i <= selected)) { // shrink a left one
- n = j++;
- right = true;
- } else if (i > selected) { // shrink a right one
- n = i--;
- right = false;
- } else { // no more space, start making them zero
- minsize = 0;
- i = numchildren - 1;
- j = 0;
- right = true;
- continue;
- }
- cumulated_width -= w2[n] - minsize;
- w2[n] = minsize;
- if (cumulated_width < available_width) {
- w2[n] = available_width - cumulated_width + minsize;
- cumulated_width = available_width;
- break;
- }
+ if (num_tabs() == 1) {
+ // hide tabbar
+ ctab_h = 1;
+ CloseBtn->hide();
+ Pack->child(0)->size(0,0);
+ Pack->child(0)->hide(); // first tab button
+ resize(0,0,window()->w(),ctab_h); // tabbar
+ Wizard->resize(0,ctab_h,Wizard->w(),window()->h()-ctab_h);
+ window()->init_sizes();
+ window()->redraw();
}
- // re-sum the positions:
- cumulated_width = 0;
- for (i = 0; i < numchildren; i++) {
- cumulated_width += w2[i];
- tab_pos[i+1] = cumulated_width;
- }
- return selected;
}
-TabGroupPager* CustShrinkTabPager::clone() const {
- return new CustShrinkTabPager(*this);
+int CustTabs::get_btn_idx(UI *ui)
+{
+ for (int i = 0; i < num_tabs(); ++i) {
+ CustTabButton *btn = (CustTabButton*)Pack->child(i);
+ if (btn->ui() == ui)
+ return i;
+ }
+ return -1;
}
-//----------------------------------------------------------------------------
+/*
+ * Keep active tab visible
+ * (Pack children have unusable x() coordinate)
+ */
+void CustTabs::update_pack_offset()
+{
+ dReturn_if (num_tabs() == 0);
+
+ // get active tab button
+ int act_idx = get_btn_idx((UI*)Wizard->value());
+ CustTabButton *cbtn = (CustTabButton*)Pack->child(act_idx);
+
+ // calculate tab button's x() coordinates
+ int x_i = 0, x_f;
+ for (int j=0; j < act_idx; ++j)
+ x_i += Pack->child(j)->w();
+ x_f = x_i + cbtn->w();
+
+ int scr_x = Scroll->xposition(), scr_y = Scroll->yposition();
+ int px_i = x_i - scr_x;
+ int px_f = px_i + cbtn->w();
+ int pw = Scroll->window()->w() - ctl_w;
+ _MSG(" scr_x=%d btn_x=%d px_i=%d btn_w=%d px_f=%d pw=%d",
+ Scroll->xposition(),cbtn->x(),px_i,cbtn->w(),px_f,pw);
+ if (px_i < 0) {
+ Scroll->scroll_to(x_i, scr_y);
+ } else if (px_i > pw || (px_i > 0 && px_f > pw)) {
+ Scroll->scroll_to(MIN(x_i, x_f-pw), scr_y);
+ }
+ Scroll->redraw();
+ _MSG(" >>scr_x=%d btn0_x=%d\n", scr_x, Pack->child(0)->x());
+}
/*
- * For custom handling of keyboard
+ * Make cbtn's tab the active one
*/
-class CustTabGroup : public fltk::TabGroup {
- Tooltip *toolTip;
- bool tooltipEnabled;
- bool buttonPushed;
-public:
- CustTabGroup (int x, int y, int ww, int wh, const char *lbl=0) :
- TabGroup(x,y,ww,wh,lbl) {
- // The parameter pager is cloned, so free it.
- CustShrinkTabPager *cp = new CustShrinkTabPager();
- this->pager(cp);
- delete cp;
- toolTip = new Tooltip;
- tooltipEnabled = false;
- buttonPushed = false;
- };
- ~CustTabGroup() { delete toolTip; }
- int handle(int e) {
- // Don't focus with arrow keys
- _MSG("CustTabGroup::handle %d\n", e);
- fltk::Rectangle r(btn_x,0,BTN_W,BTN_H);
- if (e == KEY) {
- int k = event_key();
- // We're only interested in some flags
- unsigned modifier = event_state() & (SHIFT | CTRL | ALT);
- if (k == UpKey || k == DownKey || k == TabKey) {
- return 0;
- } else if (k == LeftKey || k == RightKey) {
- if (modifier == SHIFT) {
- int i = value();
- if (k == LeftKey) {i = i ? i-1 : children()-1;}
- else {i++; if (i >= children()) i = 0;}
- selected_child(child(i));
- return 1;
- }
- // Avoid focus change.
- return 0;
- }
- } else if (e == FOCUS_CHANGE) {
- // Update the window title
- BrowserWindow *bw = a_UIcmd_get_bw_by_widget(selected_child());
- const char *title = a_History_get_title(NAV_TOP_UIDX(bw), 1);
- a_UIcmd_set_page_title(bw, title ? title : "");
- } else if (e == MOVE) {
- CustShrinkTabPager *cstp = (CustShrinkTabPager *) pager();
- if (event_inside(r) && children() > 1) {
- /* We're inside the button area */
- cstp->btn_highlight(true);
- if (prefs.show_tooltip) {
- /* Prepare the tooltip for pop-up */
- tooltipEnabled = true;
- /* We use parent() if available because we are returning 0.
- * Returning without having TabGroup processing makes the
- * popup event never reach 'this', but it reaches parent() */
- toolTip->enter(parent() ?parent():this, r, "Close current Tab");
- }
- return 0; // Change focus
- } else {
- cstp->btn_highlight(false);
-
- if (prefs.show_tooltip) {
- /* Hide the tooltip or enable it again.*/
- if (tooltipEnabled) {
- tooltipEnabled = false;
- toolTip->exit();
- } else {
- toolTip->enable();
- }
- }
- }
- } else if (e == PUSH && event_inside(r) &&
- event_button() == 1 && children() > 1) {
- buttonPushed = true;
- return 1; /* non-zero */
- } else if (e == RELEASE) {
- if (event_inside(r) && event_button() == 1 &&
- children() > 1 && buttonPushed) {
- a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(selected_child()));
- } else {
- CustShrinkTabPager *cstp = (CustShrinkTabPager *) pager();
- cstp->btn_highlight(false);
- }
- buttonPushed = false;
- } else if (e == DRAG) {
- /* Ignore this event */
- return 1;
+void CustTabs::switch_tab(CustTabButton *cbtn)
+{
+ int idx;
+ CustTabButton *btn;
+ BrowserWindow *bw;
+ UI *old_ui = (UI*)Wizard->value();
+
+ if (cbtn->ui() != old_ui) {
+ // Set old tab label to normal color
+ if ((idx = get_btn_idx(old_ui)) != -1) {
+ btn = (CustTabButton*)Pack->child(idx);
+ btn->color(tabcolor_inactive);
+ btn->redraw();
}
- int ret = TabGroup::handle(e);
-
- if (e == PUSH) {
- /* WORKAROUND: FLTK raises the window on unhandled clicks,
- * which we do not want.
- */
- ret = 1;
+ Wizard->value(cbtn->ui());
+ cbtn->color(tabcolor_active);
+ cbtn->redraw();
+ update_pack_offset();
+
+ // Update window title
+ if ((bw = a_UIcmd_get_bw_by_widget(cbtn->ui()))) {
+ const char *title = (cbtn->ui())->label();
+ cbtn->window()->copy_label(title ? title : "");
}
- return ret;
}
+}
- void remove (Widget *w) {
- TabGroup::remove (w);
- /* fixup resizable in case we just removed it */
- if (resizable () == w) {
- if (children () > 0)
- resizable (child (children () - 1));
- else
- resizable (NULL);
- }
+void CustTabs::prev_tab()
+{
+ int idx;
- if (children () < 2)
- hideLabels ();
- }
+ if ((idx = get_btn_idx((UI*)Wizard->value())) != -1)
+ switch_tab((CustTabButton*)Pack->child(idx>0 ? idx-1 : num_tabs()-1));
+}
- void add (Widget *w) {
- TabGroup::add (w);
- if (children () > 1)
- showLabels ();
- }
+void CustTabs::next_tab()
+{
+ int idx;
- void hideLabels() {
- for (int i = children () - 1; i >= 0; i--)
- child(i)->resize(x(), y(), w(), h());
- }
+ if ((idx = get_btn_idx((UI*)Wizard->value())) != -1)
+ switch_tab((CustTabButton*)Pack->child((idx+1<num_tabs()) ? idx+1 : 0));
+}
+
+/*
+ * Set this UI's tab button label
+ */
+void CustTabs::set_tab_label(UI *ui, const char *label)
+{
+ char title[128];
+ int idx = get_btn_idx(ui);
+
+ if (idx != -1) {
+ // Make a label for this tab
+ size_t tab_chars = 15, label_len = strlen(label);
- void showLabels() {
- for (int i = children () - 1; i >= 0; i--)
- child(i)->resize(x(), y() + 20, w(), h() - 20);
+ if (label_len > tab_chars)
+ tab_chars = a_Utf8_end_of_char(label, tab_chars - 1) + 1;
+ snprintf(title, tab_chars + 1, "%s", label);
+ if (label_len > tab_chars)
+ snprintf(title + tab_chars, 4, "...");
+
+ // Avoid unnecessary redraws
+ if (strcmp(Pack->child(idx)->label(), title)) {
+ int w = 0, h;
+ Pack->child(idx)->copy_label(title);
+ Pack->child(idx)->measure_label(w, h);
+ Pack->child(idx)->size(w+14,ctab_h);
+ update_pack_offset();
+ }
}
-};
+}
+
//----------------------------------------------------------------------------
-static void win_cb (fltk::Widget *w, void *cb_data) {
- int choice = 0;
- CustTabGroup *tabs = (CustTabGroup*) cb_data;
+static void win_cb (Fl_Widget *w, void *cb_data) {
+ CustTabs *tabs = (CustTabs*) cb_data;
+ int choice = 1, ntabs = tabs->num_tabs();
- if (tabs->children () > 1)
- choice = a_Dialog_choice3 ("Window contains more than one tab.",
- "Close all tabs", "Cancel", NULL);
- if (choice == 0)
- while (tabs->children())
- a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(tabs->child(0)));
+ if (prefs.show_quit_dialog && ntabs > 1)
+ choice = a_Dialog_choice5("Window contains more than one tab.",
+ "Close", "Cancel", NULL, NULL, NULL);
+ if (choice == 1)
+ while (ntabs-- > 0)
+ a_UIcmd_close_bw(a_UIcmd_get_bw_by_widget(tabs->wizard()->value()));
}
/*
@@ -376,27 +449,14 @@ BrowserWindow *a_UIcmd_get_bw_by_widget(void *v_wid)
BrowserWindow *bw;
for (int i = 0; i < a_Bw_num(); ++i) {
bw = a_Bw_get(i);
- if (((fltk::Widget*)bw->ui)->contains((fltk::Widget*)v_wid))
+ if (((UI*)bw->ui)->contains((Fl_Widget*)v_wid)) {
return bw;
+ }
}
return NULL;
}
/*
- * FLTK regards SHIFT + {LeftKey, Right} as navigation keys.
- * Special handling is required to override it. Here we route
- * these events directly to the recipient.
- * TODO: focus is not remembered correctly.
- */
-void a_UIcmd_send_event_to_tabs_by_wid(int e, void *v_wid)
-{
- BrowserWindow *bw = a_UIcmd_get_bw_by_widget(v_wid);
- UI *ui = (UI*)bw->ui;
- if (ui->tabs())
- ui->tabs()->handle(e);
-}
-
-/*
* Create a new UI and its associated BrowserWindow data structure.
* Use style from v_ui. If non-NULL it must be of type UI*.
*/
@@ -405,7 +465,8 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh,
{
BrowserWindow *old_bw = (BrowserWindow*)vbw;
BrowserWindow *new_bw = NULL;
- Window *win;
+ UI *old_ui = old_bw ? BW2UI(old_bw) : NULL;
+ Fl_Window *win;
if (ww <= 0 || wh <= 0) {
// Set default geometry from dillorc.
@@ -415,96 +476,40 @@ BrowserWindow *a_UIcmd_browser_window_new(int ww, int wh,
if (xid)
win = new Xembed(xid, ww, wh);
+ else if (prefs.buffered_drawing != 2)
+ win = new Fl_Window(ww, wh);
else
- win = new Window(ww, wh);
+ win = new Fl_Double_Window(ww, wh);
- win->shortcut(0); // Ignore Escape
- if (prefs.buffered_drawing != 2)
- win->clear_double_buffer();
- win->set_flag(RAW_LABEL);
- CustTabGroup *DilloTabs = new CustTabGroup(0, 0, ww, wh);
- DilloTabs->clear_tab_to_focus();
- DilloTabs->selection_color(156);
- win->add(DilloTabs);
+ win->box(FL_NO_BOX);
+ CustTabs *DilloTabs = new CustTabs(ww, wh, 16);
+ win->end();
- // Create and set the UI
- UI *new_ui = new UI(0, 0, ww, wh, DEFAULT_TAB_LABEL,
- old_bw ? BW2UI(old_bw) : NULL);
- new_ui->set_status("http://www.dillo.org/");
- new_ui->tabs(DilloTabs);
-
- DilloTabs->add(new_ui);
- DilloTabs->resizable(new_ui);
- DilloTabs->window()->resizable(new_ui);
- DilloTabs->window()->show();
+ int focus = 1;
+ new_bw = UIcmd_tab_new(DilloTabs, old_ui, focus);
+ win->resizable(DilloTabs->wizard());
+ win->show();
if (old_bw == NULL && prefs.xpos >= 0 && prefs.ypos >= 0) {
// position the first window according to preferences
- fltk::Rectangle r;
- new_ui->window()->borders(&r);
- // borders() gives x and y border sizes as negative values
- new_ui->window()->position(prefs.xpos - r.x(), prefs.ypos - r.y());
+ DilloTabs->window()->position(prefs.xpos, prefs.ypos);
}
- // Now create the Dw render layout and viewport
- FltkPlatform *platform = new FltkPlatform ();
- Layout *layout = new Layout (platform);
- style::Color *bgColor = style::Color::create (layout, prefs.bg_color);
- layout->setBgColor (bgColor);
-
- FltkViewport *viewport = new FltkViewport (0, 0, 1, 1);
- if (prefs.buffered_drawing == 1)
- viewport->setBufferedDrawing (true);
- else
- viewport->setBufferedDrawing (false);
-
- layout->attachView (viewport);
- new_ui->set_render_layout(*viewport);
-
- viewport->setScrollStep((int) rint(14.0 * prefs.font_factor));
-
- // Now, create a new browser window structure
- new_bw = a_Bw_new();
-
- // Reference the UI from the bw
- new_bw->ui = (void *)new_ui;
- // Copy the layout pointer into the bw data
- new_bw->render_layout = (void*)layout;
-
win->callback(win_cb, DilloTabs);
- new_ui->focus_location();
-
return new_bw;
}
/*
- * Create a new Tab.
- * i.e the new UI and its associated BrowserWindow data structure.
+ * Create a new Tab button, UI and its associated BrowserWindow data
+ * structure.
*/
-static BrowserWindow *UIcmd_tab_new(const void *vbw)
+static BrowserWindow *UIcmd_tab_new(CustTabs *tabs, UI *old_ui, int focus)
{
- _MSG(" UIcmd_tab_new vbw=%p\n", vbw);
-
- dReturn_val_if_fail (vbw != NULL, NULL);
-
- BrowserWindow *new_bw = NULL;
- BrowserWindow *old_bw = (BrowserWindow*)vbw;
- UI *ui = BW2UI(old_bw);
-
- // WORKAROUND: limit the number of tabs because of a fltk bug
- if (ui->tabs()->children() >= 127)
- return a_UIcmd_browser_window_new(ui->window()->w(), ui->window()->h(),
- 0, vbw);
+ _MSG(" UIcmd_tab_new\n");
// Create and set the UI
- UI *new_ui = new UI(0, 0, ui->w(), ui->h(), DEFAULT_TAB_LABEL, ui);
- new_ui->tabs(ui->tabs());
-
- new_ui->tabs()->add(new_ui);
- new_ui->tabs()->resizable(new_ui);
- new_ui->tabs()->window()->resizable(new_ui);
- new_ui->tabs()->window()->show();
+ UI *new_ui = tabs->add_new_tab(old_ui, focus);
// Now create the Dw render layout and viewport
FltkPlatform *platform = new FltkPlatform ();
@@ -512,21 +517,30 @@ static BrowserWindow *UIcmd_tab_new(const void *vbw)
style::Color *bgColor = style::Color::create (layout, prefs.bg_color);
layout->setBgColor (bgColor);
- FltkViewport *viewport = new FltkViewport (0, 0, 1, 1);
-
+ // set_render_layout() sets the proper viewport size
+ FltkViewport *viewport = new FltkViewport (0, 0, 0, 1);
+ viewport->box(FL_NO_BOX);
+ viewport->setBufferedDrawing (prefs.buffered_drawing ? true : false);
+ viewport->setDragScroll (prefs.middle_click_drags_page ? true : false);
layout->attachView (viewport);
- new_ui->set_render_layout(*viewport);
-
- viewport->setScrollStep((int) rint(14.0 * prefs.font_factor));
+ new_ui->set_render_layout(viewport);
+ viewport->setScrollStep((int) rint(28.0 * prefs.font_factor));
// Now, create a new browser window structure
- new_bw = a_Bw_new();
+ BrowserWindow *new_bw = a_Bw_new();
// Reference the UI from the bw
new_bw->ui = (void *)new_ui;
// Copy the layout pointer into the bw data
new_bw->render_layout = (void*)layout;
+ // Clear the window title
+ if (focus)
+ new_ui->window()->copy_label(new_ui->label());
+
+ // WORKAROUND: see findbar_toggle()
+ new_ui->findbar_toggle(0);
+
return new_bw;
}
@@ -537,21 +551,17 @@ void a_UIcmd_close_bw(void *vbw)
{
BrowserWindow *bw = (BrowserWindow *)vbw;
UI *ui = BW2UI(bw);
+ CustTabs *tabs = ui->tabs();
Layout *layout = (Layout*)bw->render_layout;
- MSG("a_UIcmd_close_bw\n");
+ _MSG("a_UIcmd_close_bw\n");
a_Bw_stop_clients(bw, BW_Root + BW_Img + BW_Force);
delete(layout);
- if (ui->tabs()) {
- ui->tabs()->remove(ui);
- ui->tabs()->value(ui->tabs()->children() - 1);
- if (ui->tabs()->value() != -1)
- ui->tabs()->selected_child()->take_focus();
- else
- ui->tabs()->window()->hide();
+ if (tabs) {
+ tabs->remove_tab(ui);
+ if (tabs->num_tabs() == 0)
+ delete tabs->window();
}
- delete(ui);
-
a_Bw_free(bw);
}
@@ -561,12 +571,12 @@ void a_UIcmd_close_bw(void *vbw)
void a_UIcmd_close_all_bw(void *)
{
BrowserWindow *bw;
- int choice = 0;
+ int choice = 1;
- if (a_Bw_num() > 1)
- choice = a_Dialog_choice3 ("More than one open tab or Window.",
- "Close all tabs and windows", "Cancel", NULL);
- if (choice == 0)
+ if (prefs.show_quit_dialog && a_Bw_num() > 1)
+ choice = a_Dialog_choice5("More than one open tab or window.",
+ "Quit", "Cancel", NULL, NULL, NULL);
+ if (choice == 1)
while ((bw = a_Bw_get(0)))
a_UIcmd_close_bw((void*)bw);
}
@@ -616,10 +626,14 @@ void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
*/
void a_UIcmd_open_url(BrowserWindow *bw, const DilloUrl *url)
{
- a_Nav_push(bw, url, NULL);
- if (BW2UI(bw)->get_panelmode() == UI_TEMPORARILY_SHOW_PANELS)
- BW2UI(bw)->set_panelmode(UI_HIDDEN);
- a_UIcmd_focus_main_area(bw);
+ if (url) {
+ a_Nav_push(bw, url, NULL);
+ BW2UI(bw)->focus_main();
+ } else {
+ // Used to start a bw with a blank screen
+ BW2UI(bw)->focus_location();
+ a_UIcmd_set_buttons_sens(bw);
+ }
}
static void UIcmd_open_url_nbw(BrowserWindow *new_bw, const DilloUrl *url)
@@ -632,6 +646,7 @@ static void UIcmd_open_url_nbw(BrowserWindow *new_bw, const DilloUrl *url)
BW2UI(new_bw)->focus_main();
} else {
BW2UI(new_bw)->focus_location();
+ a_UIcmd_set_buttons_sens(new_bw);
}
}
@@ -654,11 +669,9 @@ void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url)
*/
void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus)
{
- BrowserWindow *new_bw = UIcmd_tab_new(vbw);
-
- if (focus)
- BW2UI(new_bw)->tabs()->selected_child(BW2UI(new_bw));
-
+ BrowserWindow *bw = (BrowserWindow *)vbw;
+ BrowserWindow *new_bw = UIcmd_tab_new(BW2UI(bw)->tabs(),
+ bw ? BW2UI(bw) : NULL, focus);
UIcmd_open_url_nbw(new_bw, url);
}
@@ -673,9 +686,9 @@ void a_UIcmd_back(void *vbw)
/*
* Popup the navigation menu of the Back button
*/
-void a_UIcmd_back_popup(void *vbw)
+void a_UIcmd_back_popup(void *vbw, int x, int y)
{
- a_Menu_history_popup((BrowserWindow*)vbw, -1);
+ a_Menu_history_popup((BrowserWindow*)vbw, x, y, -1);
}
/*
@@ -689,9 +702,9 @@ void a_UIcmd_forw(void *vbw)
/*
* Popup the navigation menu of the Forward button
*/
-void a_UIcmd_forw_popup(void *vbw)
+void a_UIcmd_forw_popup(void *vbw, int x, int y)
{
- a_Menu_history_popup((BrowserWindow*)vbw, 1);
+ a_Menu_history_popup((BrowserWindow*)vbw, x, y, 1);
}
/*
@@ -825,9 +838,9 @@ void a_UIcmd_stop(void *vbw)
/*
* Popup the tools menu
*/
-void a_UIcmd_tools(void *vbw, void *v_wid)
+void a_UIcmd_tools(void *vbw, int x, int y)
{
- a_Menu_tools_popup((BrowserWindow*)vbw, v_wid);
+ a_Menu_tools_popup((BrowserWindow*)vbw, x, y);
}
/*
@@ -850,29 +863,33 @@ void a_UIcmd_open_file(void *vbw)
/*
* Returns a newly allocated string holding a search url generated from
- * a string of keywords (separarated by blanks) and prefs.search_url.
+ * a string of keywords (separated by blanks) and the current search_url.
* The search string is urlencoded.
*/
static char *UIcmd_make_search_str(const char *str)
{
- char *keys = a_Url_encode_hex_str(str), *c = prefs.search_url;
+ char *search_url, *l, *u, *c;
+ char *keys = a_Url_encode_hex_str(str),
+ *src = (char*)dList_nth_data(prefs.search_urls, prefs.search_url_idx);
Dstr *ds = dStr_sized_new(128);
- char *search_url;
-
- for (; *c; c++) {
- if (*c == '%')
- switch(*++c) {
- case 's':
- dStr_append(ds, keys); break;;
- case '%':
- dStr_append_c(ds, '%'); break;;
- case 0:
- MSG_WARN("search_url ends with '%%'\n"); c--; break;;
- default:
- MSG_WARN("illegal specifier '%%%c' in search_url\n", *c);
- }
- else
- dStr_append_c(ds, *c);
+
+ /* parse search_url into label and url */
+ if (a_Misc_parse_search_url(src, &l, &u) == 0) {
+ for (c = u; *c; c++) {
+ if (*c == '%')
+ switch(*++c) {
+ case 's':
+ dStr_append(ds, keys); break;;
+ case '%':
+ dStr_append_c(ds, '%'); break;;
+ case 0:
+ MSG_WARN("search_url ends with '%%'\n"); c--; break;;
+ default:
+ MSG_WARN("illegal specifier '%%%c' in search_url\n", *c);
+ }
+ else
+ dStr_append_c(ds, *c);
+ }
}
dFree(keys);
@@ -918,13 +935,11 @@ void a_UIcmd_save_link(BrowserWindow *bw, const DilloUrl *url)
a_UIcmd_set_save_dir(prefs.save_dir);
SuggestedName = UIcmd_make_save_filename(URL_STR(url));
- name = a_Dialog_save_file("Save Link as File", NULL, SuggestedName);
- MSG("a_UIcmd_save_link: %s\n", name);
- dFree(SuggestedName);
-
- if (name) {
+ if ((name = a_Dialog_save_file("Save Link as File", NULL, SuggestedName))) {
+ MSG("a_UIcmd_save_link: %s\n", name);
a_Nav_save_url(bw, url, name);
}
+ dFree(SuggestedName);
}
/*
@@ -1030,7 +1045,7 @@ void a_UIcmd_view_page_source(BrowserWindow *bw, const DilloUrl *url)
}
/*
- * Show a text window with the URL's source
+ * Show the browser window's HTML errors in a text window
*/
void a_UIcmd_view_page_bugs(void *vbw)
{
@@ -1151,6 +1166,8 @@ void a_UIcmd_scroll(BrowserWindow *bw, int icmd)
const mapping_t map[] = {
{KEYS_SCREEN_UP, SCREEN_UP_CMD},
{KEYS_SCREEN_DOWN, SCREEN_DOWN_CMD},
+ {KEYS_SCREEN_LEFT, SCREEN_LEFT_CMD},
+ {KEYS_SCREEN_RIGHT, SCREEN_RIGHT_CMD},
{KEYS_LINE_UP, LINE_UP_CMD},
{KEYS_LINE_DOWN, LINE_DOWN_CMD},
{KEYS_LEFT, LEFT_CMD},
@@ -1217,7 +1234,7 @@ void a_UIcmd_set_bug_prog(BrowserWindow *bw, int n_bug)
}
/*
- * Set the page title in the window titlebar and tab label.
+ * Set the page title in the tab label and window titlebar.
* (Update window titlebar for the current tab only)
*/
void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label)
@@ -1225,16 +1242,17 @@ void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label)
const int size = 128;
char title[size];
- if (a_UIcmd_get_bw_by_widget(BW2UI(bw)->tabs()->selected_child()) == bw) {
+ if (snprintf(title, size, "Dillo: %s", label ? label : "") >= size) {
+ uint_t i = MIN(size - 4, 1 + a_Utf8_end_of_char(title, size - 8));
+ snprintf(title + i, 4, "...");
+ }
+ BW2UI(bw)->copy_label(title);
+ BW2UI(bw)->tabs()->set_tab_label(BW2UI(bw), label ? label : "");
+
+ if (a_UIcmd_get_bw_by_widget(BW2UI(bw)->tabs()->wizard()->value()) == bw) {
// This is the focused bw, set window title
- if (snprintf(title, size, "Dillo: %s", label) >= size) {
- uint_t i = MIN(size - 4, 1 + a_Utf8_end_of_char(title, size - 8));
- snprintf(title + i, 4, "...");
- }
BW2UI(bw)->window()->copy_label(title);
- BW2UI(bw)->window()->redraw_label();
}
- BW2UI(bw)->set_tab_title(label);
}
/*
@@ -1268,32 +1286,16 @@ void a_UIcmd_set_buttons_sens(BrowserWindow *bw)
BW2UI(bw)->button_set_sens(UI_BACK, sens);
// Forward
sens = (a_Nav_stack_ptr(bw) < a_Nav_stack_size(bw) - 1 &&
- !bw->nav_expecting);
+ !a_Bw_expecting(bw));
BW2UI(bw)->button_set_sens(UI_FORW, sens);
}
/*
- * Keep track of mouse pointer over a link.
- */
-void a_UIcmd_set_pointer_on_link(BrowserWindow *bw, int flag)
-{
- BW2UI(bw)->pointerOnLink(flag);
-}
-
-/*
- * Is the mouse pointer over a link?
+ * Toggle control panel
*/
-int a_UIcmd_pointer_on_link(BrowserWindow *bw)
+void a_UIcmd_panels_toggle(BrowserWindow *bw)
{
- return BW2UI(bw)->pointerOnLink();
-}
-
-/*
- * Toggle control panel (aka. fullscreen)
- */
-void a_UIcmd_fullscreen_toggle(BrowserWindow *bw)
-{
- BW2UI(bw)->fullscreen_toggle();
+ BW2UI(bw)->panels_toggle();
}
/*
@@ -1330,6 +1332,14 @@ void a_UIcmd_findtext_reset(BrowserWindow *bw)
}
/*
+ * Tell the UI to hide/show the findbar
+ */
+void a_UIcmd_findbar_toggle(BrowserWindow *bw, int on)
+{
+ BW2UI(bw)->findbar_toggle(on);
+}
+
+/*
* Focus the rendered area.
*/
void a_UIcmd_focus_main_area(BrowserWindow *bw)
diff --git a/src/uicmd.hh b/src/uicmd.hh
index c8fea9e7..c859ba9c 100644
--- a/src/uicmd.hh
+++ b/src/uicmd.hh
@@ -17,16 +17,16 @@ void a_UIcmd_open_url(BrowserWindow *bw, const DilloUrl *url);
void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url);
void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus);
void a_UIcmd_back(void *vbw);
-void a_UIcmd_back_popup(void *vbw);
+void a_UIcmd_back_popup(void *vbw, int x, int y);
void a_UIcmd_forw(void *vbw);
-void a_UIcmd_forw_popup(void *vbw);
+void a_UIcmd_forw_popup(void *vbw, int x, int y);
void a_UIcmd_home(void *vbw);
void a_UIcmd_reload(void *vbw);
void a_UIcmd_repush(void *vbw);
void a_UIcmd_redirection0(void *vbw, const DilloUrl *url);
void a_UIcmd_save(void *vbw);
void a_UIcmd_stop(void *vbw);
-void a_UIcmd_tools(void *vbw, void *v_wid);
+void a_UIcmd_tools(void *vbw, int x, int y);
void a_UIcmd_save_link(BrowserWindow *bw, const DilloUrl *url);
void a_UIcmd_open_file(void *vbw);
const char *a_UIcmd_select_file();
@@ -34,11 +34,12 @@ void a_UIcmd_search_dialog(void *vbw);
const char *a_UIcmd_get_passwd(const char *user);
void a_UIcmd_book(void *vbw);
void a_UIcmd_add_bookmark(BrowserWindow *bw, const DilloUrl *url);
-void a_UIcmd_fullscreen_toggle(BrowserWindow *bw);
+void a_UIcmd_panels_toggle(BrowserWindow *bw);
void a_UIcmd_findtext_dialog(BrowserWindow *bw);
void a_UIcmd_findtext_search(BrowserWindow *bw,const char *key,int case_sens,
int backwards);
void a_UIcmd_findtext_reset(BrowserWindow *bw);
+void a_UIcmd_findbar_toggle(BrowserWindow *bw, int on);
void a_UIcmd_focus_main_area(BrowserWindow *bw);
void a_UIcmd_focus_location(void *vbw);
void a_UIcmd_page_popup(void *vbw, bool_t has_bugs, void *v_cssUrls);
@@ -77,9 +78,6 @@ void a_UIcmd_set_bug_prog(BrowserWindow *bw, int n_bug);
void a_UIcmd_set_page_title(BrowserWindow *bw, const char *label);
void a_UIcmd_set_msg(BrowserWindow *bw, const char *format, ...);
void a_UIcmd_set_buttons_sens(BrowserWindow *bw);
-void a_UIcmd_fullscreen_toggle(BrowserWindow *bw);
-void a_UIcmd_set_pointer_on_link(BrowserWindow *bw, int flag);
-int a_UIcmd_pointer_on_link(BrowserWindow *bw);
#ifdef __cplusplus
}
diff --git a/src/url.c b/src/url.c
index ae1f131b..78f717cf 100644
--- a/src/url.c
+++ b/src/url.c
@@ -233,6 +233,8 @@ static Dstr *Url_resolve_relative(const char *RelStr,
dStr_append(SolvedUrl, BaseStr);
if ((p = strchr(SolvedUrl->str, '#')))
dStr_truncate(SolvedUrl, p - SolvedUrl->str);
+ if (!BaseUrl->path)
+ dStr_append_c(SolvedUrl, '/');
if (RelUrl->query) { /* query */
if (BaseUrl->query)
@@ -687,11 +689,11 @@ static uint_t Url_host_public_internal_dots(const char *host)
if (tld_len > 0) {
/* These TLDs were chosen by examining the current publicsuffix list
- * in January 2010 and picking out those where it was simplest for
+ * in September 2011 and picking out those where it was simplest for
* them to describe the situation by beginning with a "*.[tld]" rule.
*/
- const char *const tlds[] = {"ar","au","bd","bn","bt","ck","cy","do",
- "eg","er","et","fj","fk","gt","gu","id",
+ const char *const tlds[] = {"ar","au","bd","bn","bt","ck","cy",
+ "er","et","fj","fk","gt","gu","id",
"il","jm","ke","kh","kw","ml","mm","mt",
"mz","ni","np","nz","om","pg","py","qa",
"sv","tr","uk","uy","ve","ye","yu","za",
@@ -716,7 +718,7 @@ static uint_t Url_host_public_internal_dots(const char *host)
* domain that is in a registry outside the organization.
* For 'www.dillo.org', that would be 'dillo.org'.
*/
-const char *a_Url_host_find_public_suffix(const char *host)
+static const char *Url_host_find_public_suffix(const char *host)
{
const char *s;
uint_t dots;
@@ -751,3 +753,12 @@ const char *a_Url_host_find_public_suffix(const char *host)
_MSG("public suffix of %s is %s\n", host, s);
return s;
}
+
+bool_t a_Url_same_organization(const DilloUrl *u1, const DilloUrl *u2)
+{
+ if (!u1 || !u2)
+ return FALSE;
+
+ return dStrcasecmp(Url_host_find_public_suffix(URL_HOST(u1)),
+ Url_host_find_public_suffix(URL_HOST(u2))) ? FALSE :TRUE;
+}
diff --git a/src/url.h b/src/url.h
index 5688287a..c5f70615 100644
--- a/src/url.h
+++ b/src/url.h
@@ -47,21 +47,21 @@
* (non '_'-ended macros MUST use these for initialization sake)
*/
/* these MAY return NULL: */
-#define URL_SCHEME_(u) u->scheme
-#define URL_AUTHORITY_(u) u->authority
-#define URL_PATH_(u) u->path
-#define URL_QUERY_(u) u->query
-#define URL_FRAGMENT_(u) u->fragment
+#define URL_SCHEME_(u) (u)->scheme
+#define URL_AUTHORITY_(u) (u)->authority
+#define URL_PATH_(u) (u)->path
+#define URL_QUERY_(u) (u)->query
+#define URL_FRAGMENT_(u) (u)->fragment
#define URL_HOST_(u) a_Url_hostname(u)
-#define URL_ALT_(u) u->alt
+#define URL_ALT_(u) (u)->alt
#define URL_STR_(u) a_Url_str(u)
/* this returns a Dstr* */
-#define URL_DATA_(u) u->data
+#define URL_DATA_(u) (u)->data
/* these return an integer */
-#define URL_PORT_(u) (URL_HOST(u), u->port)
-#define URL_FLAGS_(u) u->flags
-#define URL_ILLEGAL_CHARS_(u) url->illegal_chars
-#define URL_ILLEGAL_CHARS_SPC_(u) url->illegal_chars_spc
+#define URL_PORT_(u) (URL_HOST(u), (u)->port)
+#define URL_FLAGS_(u) (u)->flags
+#define URL_ILLEGAL_CHARS_(u) (u)->illegal_chars
+#define URL_ILLEGAL_CHARS_SPC_(u) (u)->illegal_chars_spc
/*
* Access methods that never return NULL.
@@ -122,7 +122,7 @@ void a_Url_set_ismap_coords(DilloUrl *u, char *coord_str);
char *a_Url_decode_hex_str(const char *str);
char *a_Url_encode_hex_str(const char *str);
char *a_Url_string_strip_delimiters(const char *str);
-const char *a_Url_host_find_public_suffix(const char *host);
+bool_t a_Url_same_organization(const DilloUrl *u1, const DilloUrl *u2);
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/src/utf8.cc b/src/utf8.cc
index 0138c616..3d25f4f5 100644
--- a/src/utf8.cc
+++ b/src/utf8.cc
@@ -9,7 +9,7 @@
* (at your option) any later version.
*/
-#include <fltk/utf.h>
+#include <FL/fl_utf8.h>
#include "../dlib/dlib.h" /* TRUE/FALSE */
#include "utf8.hh"
@@ -45,7 +45,7 @@ uint_t a_Utf8_end_of_char(const char *str, uint_t i)
*/
uint_t a_Utf8_decode(const char* str, const char* end, int* len)
{
- return utf8decode(str, end, len);
+ return fl_utf8decode(str, end, len);
}
/*
@@ -53,7 +53,7 @@ uint_t a_Utf8_decode(const char* str, const char* end, int* len)
*/
int a_Utf8_encode(unsigned int ucs, char *buf)
{
- return utf8encode(ucs, buf);
+ return fl_utf8encode(ucs, buf);
}
/*
@@ -63,7 +63,7 @@ int a_Utf8_encode(unsigned int ucs, char *buf)
*/
int a_Utf8_test(const char* src, unsigned int srclen)
{
- return utf8test(src, srclen);
+ return fl_utf8test(src, srclen);
}
/*
@@ -100,3 +100,8 @@ bool_t a_Utf8_combining_char(int unicode)
(unicode >= 0x20d0 && unicode <= 0x20ff) ||
(unicode >= 0xfe20 && unicode <= 0xfe2f));
}
+
+int a_Utf8_char_count(const char *str, int len)
+{
+ return fl_utf_nb_char((const uchar_t*)str, len);
+}
diff --git a/src/utf8.hh b/src/utf8.hh
index 4ded50b8..ce575118 100644
--- a/src/utf8.hh
+++ b/src/utf8.hh
@@ -24,6 +24,7 @@ int a_Utf8_encode(unsigned int ucs, char *buf);
int a_Utf8_test(const char* src, unsigned int srclen);
bool_t a_Utf8_ideographic(const char *s, const char *end, int *len);
bool_t a_Utf8_combining_char(int unicode);
+int a_Utf8_char_count(const char *str, int len);
#ifdef __cplusplus
}
diff --git a/src/web.cc b/src/web.cc
index 83700845..74851f2b 100644
--- a/src/web.cc
+++ b/src/web.cc
@@ -78,8 +78,11 @@ int a_Web_dispatch_by_type (const char *Type, DilloWeb *Web,
/* This method frees the old dw if any */
layout->setWidget(dw);
- /* Clear the title bar for pages without a <TITLE> tag */
- a_UIcmd_set_page_title(Web->bw, "");
+ /* Set the page title with the bare filename (e.g. for images),
+ * HTML pages with a <TITLE> tag will overwrite it later */
+ const char *p = strrchr(URL_STR(Web->url), '/');
+ a_UIcmd_set_page_title(Web->bw, p ? p+1 : "");
+
a_UIcmd_set_location_text(Web->bw, URL_STR(Web->url));
/* Reset both progress bars */
a_UIcmd_set_page_prog(Web->bw, 0, 2);
@@ -106,14 +109,15 @@ int a_Web_dispatch_by_type (const char *Type, DilloWeb *Web,
/*
* Allocate and set safe values for a DilloWeb structure
*/
-DilloWeb* a_Web_new(const DilloUrl *url, const DilloUrl *requester)
+DilloWeb* a_Web_new(BrowserWindow *bw, const DilloUrl *url,
+ const DilloUrl *requester)
{
DilloWeb *web= dNew(DilloWeb, 1);
_MSG(" a_Web_new: ValidWebs ==> %d\n", dList_length(ValidWebs));
web->url = a_Url_dup(url);
web->requester = a_Url_dup(requester);
- web->bw = NULL;
+ web->bw = bw;
web->flags = 0;
web->Image = NULL;
web->filename = NULL;
diff --git a/src/web.hh b/src/web.hh
index d017903a..2c22edb5 100644
--- a/src/web.hh
+++ b/src/web.hh
@@ -36,7 +36,8 @@ struct _DilloWeb {
};
void a_Web_init(void);
-DilloWeb* a_Web_new (const DilloUrl* url, const DilloUrl *requester);
+DilloWeb* a_Web_new (BrowserWindow *bw, const DilloUrl* url,
+ const DilloUrl *requester);
int a_Web_valid(DilloWeb *web);
void a_Web_free (DilloWeb*);
int a_Web_dispatch_by_type (const char *Type, DilloWeb *web,
diff --git a/src/xembed.cc b/src/xembed.cc
index 04a4362a..f180d81d 100644
--- a/src/xembed.cc
+++ b/src/xembed.cc
@@ -12,14 +12,14 @@
#include <string.h>
#include <ctype.h>
-#include <fltk/Window.h>
-#include <fltk/run.h>
-#include <fltk/events.h>
-#include <fltk/x.h>
+#define FL_INTERNALS
+#include <FL/Fl_Window.H>
+#include <FL/Fl.H>
+#include <FL/x.H>
#include "xembed.hh"
-#if USE_X11
+#ifdef X_PROTOCOL
typedef enum {
XEMBED_EMBEDDED_NOTIFY = 0,
@@ -41,12 +41,12 @@ Xembed::setXembedInfo(unsigned long flags)
{
unsigned long buffer[2];
- Atom xembed_info_atom = XInternAtom (fltk::xdisplay, "_XEMBED_INFO", false);
+ Atom xembed_info_atom = XInternAtom (fl_display, "_XEMBED_INFO", false);
buffer[0] = 1;
buffer[1] = flags;
- XChangeProperty (fltk::xdisplay,
+ XChangeProperty (fl_display,
xid,
xembed_info_atom, xembed_info_atom, 32,
PropModeReplace,
@@ -60,35 +60,36 @@ Xembed::sendXembedEvent(uint32_t message) {
memset (&xclient, 0, sizeof (xclient));
xclient.window = xid;
xclient.type = ClientMessage;
- xclient.message_type = XInternAtom (fltk::xdisplay, "_XEMBED", false);
+ xclient.message_type = XInternAtom (fl_display, "_XEMBED", false);
xclient.format = 32;
- xclient.data.l[0] = fltk::event_time;
+ xclient.data.l[0] = fl_event_time;
xclient.data.l[1] = message;
- XSendEvent(fltk::xdisplay, xid, False, NoEventMask, (XEvent *)&xclient);
- XSync(fltk::xdisplay, False);
+ XSendEvent(fl_display, xid, False, NoEventMask, (XEvent *)&xclient);
+ XSync(fl_display, False);
}
int
Xembed::handle(int e) {
- if (e == fltk::PUSH)
+ if (e == FL_PUSH)
sendXembedEvent(XEMBED_REQUEST_FOCUS);
- return Window::handle(e);
+ return Fl_Window::handle(e);
}
-static int event_handler(int e, fltk::Window *w) {
- Atom xembed_atom = XInternAtom (fltk::xdisplay, "_XEMBED", false);
+static int event_handler(int e, Fl_Window *w) {
+ Atom xembed_atom = XInternAtom (fl_display, "_XEMBED", false);
- if (fltk::xevent.type == ClientMessage) {
- if (fltk::xevent.xclient.message_type == xembed_atom) {
- long message = fltk::xevent.xclient.data.l[1];
+ if (fl_xevent->type == ClientMessage) {
+ if (fl_xevent->xclient.message_type == xembed_atom) {
+ long message = fl_xevent->xclient.data.l[1];
switch (message) {
case XEMBED_WINDOW_ACTIVATE:
// Force a ConfigureNotify message so fltk can get the new
// coordinates after a move of the embedder window.
- w->resize(0, 0, w->w(), w->h());
+ if (w)
+ w->resize(0,0, w->w(), w->h());
break;
case XEMBED_WINDOW_DEACTIVATE:
break;
@@ -98,20 +99,20 @@ static int event_handler(int e, fltk::Window *w) {
}
}
- return 0;
+ return Fl::handle_(e, w);
}
// TODO: Implement more XEMBED support;
-void Xembed::create() {
+void Xembed::show() {
createInternal(xid);
setXembedInfo(1);
- fltk::add_event_handler(event_handler);
+ Fl::event_dispatch(event_handler);
}
void Xembed::createInternal(uint32_t parent) {
- fltk::Window *window = this;
- Colormap colormap = fltk::xcolormap;
+ Fl_Window *window = this;
+ Colormap colormap = fl_colormap;
XSetWindowAttributes attr;
attr.border_pixel = 0;
@@ -133,18 +134,18 @@ void Xembed::createInternal(uint32_t parent) {
| EnterWindowMask | LeaveWindowMask
| PointerMotionMask;
- fltk::CreatedWindow::set_xid(window,
- XCreateWindow(fltk::xdisplay,
+ Fl_X::set_xid(window,
+ XCreateWindow(fl_display,
parent,
X, Y, W, H,
0, // borderwidth
- fltk::xvisual->depth,
+ fl_visual->depth,
InputOutput,
- fltk::xvisual->visual,
+ fl_visual->visual,
mask, &attr));
}
-#else // USE_X11
+#else // X_PROTOCOL
void
Xembed::setXembedInfo(unsigned long flags) {};
@@ -154,12 +155,12 @@ Xembed::sendXembedEvent(uint32_t message) {};
int
Xembed::handle(int e) {
- return Window::handle(e);
+ return Fl_Window::handle(e);
}
void
-Xembed::create() {
- Window::create();
+Xembed::show() {
+ Fl_Window::show();
}
#endif
diff --git a/src/xembed.hh b/src/xembed.hh
index 70d79c5f..d7663c8e 100644
--- a/src/xembed.hh
+++ b/src/xembed.hh
@@ -1,11 +1,11 @@
#ifndef __XEMBED_HH__
#define __XEMBED_HH__
-#include <fltk/Window.h>
+#include <FL/Fl_Window.H>
#include "d_size.h"
-class Xembed : public fltk::Window {
+class Xembed : public Fl_Window {
private:
uint32_t xid;
void createInternal(uint32_t parent);
@@ -13,10 +13,10 @@ class Xembed : public fltk::Window {
void sendXembedEvent(uint32_t message);
public:
- Xembed(uint32_t xid, int _w, int _h) : fltk::Window(_w, _h) {
+ Xembed(uint32_t xid, int _w, int _h) : Fl_Window(_w, _h) {
this->xid = xid;
};
- void create();
+ void show();
int handle(int event);
};