summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Weidauer <sven@5sw.de>2017-06-22 18:05:15 (GMT)
committer Sven Weidauer <sven@5sw.de>2017-06-22 18:05:15 (GMT)
commit2e5519f22742e7f5751d8a6098e8479bfbc9919b (patch)
tree8a18836960ee282f55352c29f3ea48c78b2aa333
parent711dcabe7ca4bd3551b7e4af10b98715f746fb3f (diff)
parent2b2bbbe76502b6cb528752a2dad89d3f1f6c6409 (diff)
downloadnetsurf-2e5519f22742e7f5751d8a6098e8479bfbc9919b.tar.gz
netsurf-2e5519f22742e7f5751d8a6098e8479bfbc9919b.tar.bz2
Merge remote-tracking branch 'origin/master' into svenw/cocoa
-rw-r--r--Docs/JavaScript16
-rw-r--r--Docs/QUICK-START108
-rw-r--r--Docs/USING-Monkey318
-rw-r--r--Docs/core-window-interface679
-rw-r--r--Makefile2
-rw-r--r--content/urldb.c6
-rw-r--r--desktop/browser.c2
-rw-r--r--desktop/browser_history.c352
-rw-r--r--desktop/browser_history.h142
-rw-r--r--desktop/browser_private.h95
-rw-r--r--desktop/local_history.c341
-rw-r--r--desktop/local_history.h62
-rw-r--r--desktop/scrollbar.h10
-rw-r--r--docs/Doxyfile (renamed from Docs/Doxyfile)13
-rw-r--r--docs/PACKAGING-GTK (renamed from Docs/PACKAGING-GTK)0
-rw-r--r--docs/UnimplementedJavascript.txt (renamed from Docs/UnimplementedJavascript.txt)0
-rw-r--r--docs/building-AmigaCross.md (renamed from Docs/BUILDING-AmigaCross)0
-rw-r--r--docs/building-AmigaOS.md (renamed from Docs/BUILDING-AmigaOS)0
-rw-r--r--docs/building-Framebuffer.md (renamed from Docs/BUILDING-Framebuffer)0
-rw-r--r--docs/building-GTK.md (renamed from Docs/BUILDING-GTK)0
-rw-r--r--docs/building-Haiku.md (renamed from Docs/BUILDING-BeOS)0
-rw-r--r--docs/building-Windows.md (renamed from Docs/BUILDING-Windows)0
-rw-r--r--docs/core-window-interface.md677
-rw-r--r--docs/env.sh (renamed from Docs/env.sh)4
-rwxr-xr-xdocs/gource.sh (renamed from Docs/gource.sh)0
-rw-r--r--docs/ideas/cache.txt (renamed from Docs/ideas/cache.txt)0
-rw-r--r--docs/ideas/css-engine.txt (renamed from Docs/ideas/css-engine.txt)0
-rw-r--r--docs/ideas/render-library.txt (renamed from Docs/ideas/render-library.txt)0
-rw-r--r--docs/mainpage.md93
-rw-r--r--docs/netsurf-fb.1 (renamed from Docs/netsurf-fb.1)0
-rw-r--r--docs/netsurf-gtk.1 (renamed from Docs/netsurf-gtk.1)0
-rw-r--r--docs/netsurf-libraries.md (renamed from Docs/LIBRARIES)0
-rw-r--r--docs/netsurf-options.md (renamed from Docs/Options)0
-rw-r--r--docs/quick-start.md111
-rw-r--r--docs/source-object-backing-store.md (renamed from Docs/source-object-backing-store)0
-rw-r--r--docs/unit-testing (renamed from Docs/unit-testing)0
-rw-r--r--docs/updating-duktape.md (renamed from Docs/updating-duktape.md)10
-rw-r--r--docs/using-framebuffer.md (renamed from Docs/USING-Framebuffer)0
-rw-r--r--docs/using-monkey.md373
-rw-r--r--frontends/amiga/corewindow.c3
-rw-r--r--frontends/amiga/gui.c11
-rw-r--r--frontends/amiga/gui.h7
-rw-r--r--frontends/amiga/gui_menu.c2
-rw-r--r--[-rwxr-xr-x]frontends/amiga/history_local.c519
-rw-r--r--[-rwxr-xr-x]frontends/amiga/history_local.h23
-rw-r--r--frontends/amiga/os3support.c2
-rw-r--r--frontends/framebuffer/Makefile2
-rw-r--r--frontends/framebuffer/corewindow.c262
-rw-r--r--frontends/framebuffer/corewindow.h107
-rw-r--r--frontends/framebuffer/framebuffer.c5
-rw-r--r--frontends/framebuffer/gui.c4
-rw-r--r--frontends/framebuffer/gui.h18
-rw-r--r--frontends/framebuffer/local_history.c248
-rw-r--r--frontends/framebuffer/local_history.h49
-rw-r--r--frontends/framebuffer/localhistory.c144
-rw-r--r--frontends/gtk/bitmap.c4
-rw-r--r--frontends/gtk/cookies.c2
-rw-r--r--frontends/gtk/corewindow.c3
-rw-r--r--frontends/gtk/corewindow.h2
-rw-r--r--frontends/gtk/global_history.c2
-rw-r--r--frontends/gtk/hotlist.c2
-rw-r--r--frontends/gtk/local_history.c4
-rw-r--r--frontends/gtk/window.c2
-rw-r--r--frontends/monkey/401login.c32
-rw-r--r--frontends/monkey/bitmap.c112
-rw-r--r--frontends/monkey/browser.c516
-rw-r--r--frontends/monkey/browser.h14
-rw-r--r--frontends/monkey/cert.c32
-rw-r--r--frontends/monkey/dispatch.c110
-rw-r--r--frontends/monkey/download.c46
-rw-r--r--frontends/monkey/farmer.py363
-rw-r--r--frontends/monkey/fetch.c12
-rw-r--r--frontends/monkey/layout.c62
-rw-r--r--frontends/monkey/main.c483
-rw-r--r--frontends/monkey/plot.c54
-rw-r--r--frontends/monkey/schedule.c281
-rw-r--r--frontends/riscos/cookies.c2
-rw-r--r--frontends/riscos/corewindow.c1
-rw-r--r--frontends/riscos/dialog.c1
-rw-r--r--frontends/riscos/global_history.c2
-rw-r--r--frontends/riscos/gui.h29
-rw-r--r--frontends/riscos/hotlist.c2
-rw-r--r--frontends/riscos/local_history.c15
-rw-r--r--frontends/riscos/save.c1
-rw-r--r--frontends/riscos/textselection.c1
-rw-r--r--frontends/riscos/url_complete.c1
-rw-r--r--frontends/riscos/window.c5849
-rw-r--r--frontends/riscos/window.h193
-rw-r--r--frontends/windows/cookies.c2
-rw-r--r--frontends/windows/corewindow.c55
-rw-r--r--frontends/windows/corewindow.h2
-rw-r--r--frontends/windows/global_history.c2
-rw-r--r--frontends/windows/hotlist.c2
-rw-r--r--frontends/windows/local_history.c8
-rw-r--r--render/html.c20
95 files changed, 7096 insertions, 6050 deletions
diff --git a/Docs/JavaScript b/Docs/JavaScript
deleted file mode 100644
index ced2fbe..0000000
--- a/Docs/JavaScript
+++ b/dev/null
@@ -1,16 +0,0 @@
---------------------------------------------------------------------------------
- NetSurf: JavaScript 8 April 2013
---------------------------------------------------------------------------------
-
- NetSurf may be built with primitive support for JavaScript.
-
- | Note: NetSurf's JavaScript handling is currently:
- |
- | * incomplete,
- | * unsupported,
- | * disabled by default.
-
- To test it, you may build NetSurf with JavaScript and ensure NetSurf's
- "enable_javascript" run-time configuration option is set to "1". To do this
- you may set the option in the frontend's settings GUI, create/edit a Choices
- file, or pass --enable_javascript=1 to the executable.
diff --git a/Docs/QUICK-START b/Docs/QUICK-START
deleted file mode 100644
index 9ff3fb5..0000000
--- a/Docs/QUICK-START
+++ b/dev/null
@@ -1,108 +0,0 @@
---------------------------------------------------------------------------------
- Quick Build Steps for NetSurf 24 February 2015
---------------------------------------------------------------------------------
-
- This document provides steps for building NetSurf.
-
-
- Grab a temporary env.sh
---------------------------
-
- $ wget http://git.netsurf-browser.org/netsurf.git/plain/Docs/env.sh
- $ source env.sh
-
-
- Install any packages you need
--------------------------------
-
- Installs all packages required to build NetSurf and the NetSurf project
- libraries.
-
- $ ns-package-install
-
- If your package manager is not supported, you will have to install third
- party packages manually.
-
-
- Get the NetSurf project source code from Git
-----------------------------------------------
-
- $ ns-clone
-
-
- Build and install our project libraries
------------------------------------------
-
- Updates NetSurf project library sources to latest, builds and installs them.
-
- $ ns-pull-install
-
-
- Switch to new NetSurf workspace
----------------------------------
-
- $ rm env.sh
- $ cd ~/dev-netsurf/workspace
- $ source env.sh
-
-
- Build and run NetSurf
------------------------
-
- $ cd netsurf
-
- To build the native front end (the GTK front end on Linux, BSDs, etc) you
- could do:
-
- $ make
- $ ./nsgtk
-
- To build the framebuffer front end, you could do:
-
- $ make TARGET=framebuffer
- $ ./nsfb
-
-
- Cross Compiling
-=================
-
- If you are cross compiling, you can follow the above steps, but when sourcing
- env.sh, you should set TARGET_ABI to the appropriate triplet for your cross
- compiler. For example, to cross compile for RISC OS:
-
- $ TARGET_ABI=arm-unknown-riscos source env.sh
-
- After that, the commands such as `ns-package-install` and `ns-pull-install`
- will do what is appropriate for the platform you are building for.
-
- To do the final build of NetSurf, pass the appropriate TARGET to make. For
- example, to cross compile for RISC OS:
-
- $ make TARGET=riscos
-
- Finally, you can package up your build to transfer to the system you are
- developing for. For example, to produce a package for RISC OS:
-
- $ make TARGET=riscos package
-
- Getting a cross compiler set up
----------------------------------
-
- We maintain cross compilation environments and an SDK for a number of
- platforms. These may be found in our toolchains repository.
-
- $ git clone git://git.netsurf-browser.org/toolchains
-
- Pre-built versions of the toolchains for Debian systems are often available
- via our automated build and test infrastructure:
-
- http://ci.netsurf-browser.org/builds/toolchains/
-
-
- Not working?
-==============
-
- If the above steps are inapplicable, or don't work, you can build manually.
- Follow the instructions in the BUILDING-* documents in the Docs/ directory
- the NetSurf browser source tree.
-
diff --git a/Docs/USING-Monkey b/Docs/USING-Monkey
deleted file mode 100644
index 33e5042..0000000
--- a/Docs/USING-Monkey
+++ b/dev/null
@@ -1,318 +0,0 @@
---------------------------------------------------------------------------------
- Usage Instructions for Monkey NetSurf 13 March 2011
---------------------------------------------------------------------------------
-
- This document provides usage instructions for the Monkey version of
- NetSurf.
-
- Monkey NetSurf has been tested on Ubuntu.
-
-Overview
-========
-
- What it is
- ----------
-
- The NetSurf Monkey front end is a developer debug tool used to
- test how the core interacts with the user interface. It allows
- the developers to profile NetSurf and to interact with the core
- directly as though the developer were a front end.
-
- What it is not
- --------------
-
- Monkey is not a tool for building web-crawling robots or indeed
- anything other than a debug tool for the NetSurf developers.
-
- How to interact with nsmonkey
- -----------------------------
-
- In brief, monkey will produce tagged output on stdout and expect
- commands on stdin. Windows are numbered and for the most part
- tokens are space separated. In some cases (e.g. title or status)
- the final element on the output line is a string which might have
- spaces embedded within it. As such, output from nsmonkey should be
- parsed a token at a time, so that when such a string is encountered,
- the parser can stop splitting and return the rest.
-
- Commands to Monkey are namespaced. For example commands related to
- browser windows are prefixed by WINDOW.
-
- Top level tags for nsmonkey
- ---------------------------
-
- QUIT
-
- WINDOW
-
- Top level response tags for nsmonkey
- ------------------------------------
-
- GENERIC
-
- WARN, ERROR, DIE
-
- WINDOW
-
- DOWNLOAD_WINDOW
-
- SSLCERT
-
- 401LOGIN
-
- PLOT
-
- In the below, %something% indicates a substitution made by Monkey.
-
- %url% will be a URL
- %id% will be an opaque ID
- %n% will be a number
- %bool% will be TRUE or FALSE
- %str% is a string and will only ever be at the end of an output line.
-
- Warnings, errors etc
- --------------------
-
- Warnings (tagged WARN) come from the NetSurf core.
- Errors (tagged ERROR) tend to come from Monkey's parsers
- Death (tagged DIE) comes from the core and kills Monkey dead.
-
-Commands
-========
-
- Generic commands
- ----------------
-
- QUIT
- Cause monkey to quit cleanly.
- This will cleanly destroy open windows etc.
-
- Window commands
- ---------------
-
- WINDOW NEW [%url%]
- Create a new browser window, optionally giving the core
- a URL to immediately navigate to.
- Minimally you will receive a WINDOW NEW WIN %id% response.
-
- WINDOW DESTROY %id%
- Destroy the given browser window.
- Minimally you will recieve a WINDOW DESTROY WIN %id% response.
-
- WINDOW GO %id% %url% [%url%]
- Cause the given browser window to visit the given URL.
- Optionally you can give a referrer URL to also use (simulating
- a click in the browser on a link).
- Minimally you can expect throbber, url etc responses.
-
- WINDOW REDRAW %id% [%num% %num% %num% %num%]
- Cause a browser window to redraw. Optionally you can give a
- set of coordinates to simulate a partial expose of the window.
- Said coordinates are in traditional X0 Y0 X1 Y1 order.
- The coordinates are in canvas, not window, coordinates. So you
- should take into account the scroll offsets when issuing this
- command.
- Minimally you can expect redraw start/stop messages and you
- can likely expect some number of PLOT results.
-
- WINDOW RELOAD %id%
- Cause a browser window to reload its current content.
- Expect responses similar to a GO command.
-
-
-Responses
-=========
-
- Generic messages
- ----------------
-
- GENERIC STARTED
- Monkey has started and is ready for commands
-
- GENERIC CLOSING_DOWN
- Monkey has been told to shut down and is doing so
-
- GENERIC FINISHED
- Monkey has finished and will now exit
-
- GENERIC LAUNCH URL %url%
- The core asked monkey to launch the given URL
-
- GENERIC THUMBNAIL URL %url%
- The core asked monkey to thumbnail a content without
- a window.
-
- GENERIC POLL BLOCKING
- Monkey reached a point where it could sleep waiting for
- commands or scheduled timeouts. No fetches nor redraws
- were pending.
-
- Window messages
- ---------------
-
- WINDOW NEW WIN %id% FOR %id% CLONE %id% NEWTAB %bool%
- The core asked Monkey to open a new window. The IDs for 'FOR' and
- 'CLONE' are core window IDs, the WIN id is a Monkey window ID.
-
- WINDOW SIZE WIN %id% WIDTH %n% HEIGHT %n%
- The window specified has been set to the shown width and height.
-
- WINDOW DESTROY WIN %id%
- The core has instructed Monkey to destroy the named window.
-
- WINDOW TITLE WIN %id% STR %str%
- The core supplied a titlebar title for the given window.
-
- WINDOW REDRAW WIN %id%
- The core asked that Monkey redraw the given window.
-
- WINDOW GET_DIMENSIONS WIN %id% WIDTH %n% HEIGHT %n%
- The core asked Monkey what the dimensions of the window are.
- Monkey has to respond immediately and returned the supplied width
- and height values to the core.
-
- WINDOW NEW_CONTENT WIN %id%
- The core has informed Monkey that the named window has a new
- content object.
-
- WINDOW NEW_ICON WIN %id%
- The core has informed Monkey that the named window hsa a new
- icon (favicon) available.
-
- WINDOW START_THROBBER WIN %id%
- The core asked Monkey to start the throbber for the named
- window. This indicates to the user that the window is busy.
-
- WINDOW STOP_THROBBER WIN %id%
- The core asked Monkey to stop the throbber for the named
- window. This indicates to the user that the window is finished.
-
- WINDOW SET_SCROLL WIN %id% X %n% Y %n%
- The core asked Monkey to set the named window's scroll offsets
- to the given X and Y position.
-
- WINDOW UPDATE_BOX WIN %id% X %n% Y %n% WIDTH %n% HEIGHT %n%
- The core asked Monkey to redraw the given portion of the content
- display. Note these coordinates refer to the content, not the
- viewport which Monkey is simulating.
-
- WINDOW UPDATE_EXTENT WIN %id% WIDTH %n% HEIGHT %n%
- The core has told us that the content in the given window has a
- total width and height as shown. This allows us (along with the
- window's width and height) to know the scroll limits.
-
- WINDOW SET_STATUS WIN %id% STR %str%
- The core has told us that the given window needs its status bar
- updating with the given message.
-
- WINDOW SET_POINTER WIN %id% POINTER %id%
- The core has told us to update the mouse pointer for the given
- window to the given pointer ID.
-
- WINDOW SET_SCALE WIN %id% SCALE %n%
- The core has asked us to scale the given window by the given scale
- factor.
-
- WINDOW SET_URL WIN %id% URL %url%
- The core has informed us that the given window's URL bar needs
- updating to the given url.
-
- WINDOW GET_SCROLL WIN %id% X %n% Y %n%
- The core asked Monkey for the scroll offsets. Monkey returned the
- numbers shown for the window named.
-
- WINDOW SCROLL_START WIN %id%
- The core asked Monkey to scroll the named window to the top/left.
-
- WINDOW POSITION_FRAME WIN %id% X0 %n% Y0 %n% X1 %n% Y1 %n%
- The core asked Monkey to position the named window as a frame at
- the given coordinates of its parent.
-
- WINDOW SCROLL_VISIBLE WIN %id% X0 %n% Y0 %n% X1 %n% Y1 %n%
- The core asked Monkey to scroll the named window until the
- indicated box is visible.
-
- WINDOW PLACE_CARET WIN %id% X %n% Y %n% HEIGHT %n%
- The core asked Monkey to render a caret in the named window at the
- indicated position with the indicated height.
-
- WINDOW REMOVE_CARET WIN %id%
- The core asked Monkey to remove any caret in the named window.
-
- WINDOW SCROLL_START WIN %id% X0 %n% Y0 %n% X1 %n% Y1 %n%
- The core asked Monkey to scroll the named window to the start of
- the given box.
-
- WINDOW SELECT_MENU WIN %id%
- The core asked Monkey to produce a selection menu for the named
- window.
-
- WINDOW SAVE_LINK WIN %id% URL %url% TITLE %str%
- The core asked Monkey to save a link from the given window with
- the given URL and anchor title.
-
- WINDOW THUMBNAIL WIN %id% URL %url%
- The core asked Monkey to render a thumbnail for the given window
- which is currently at the given URL.
-
- WINDOW REDRAW WIN %id% START
- WINDOW REDRAW WIN %id% STOP
- The core wraps redraws in these messages. Thus PLOT responses can
- be allocated to the appropriate window.
-
- Download window messages
- ------------------------
-
- DOWNLOAD_WINDOW CREATE DWIN %id% WIN %id%
- The core asked Monkey to create a download window owned by the
- given browser window.
-
- DOWNLOAD_WINDOW DATA DWIN %id% SIZE %n% DATA %str%
- The core asked Monkey to update the named download window with
- the given byte size and data string.
-
- DOWNLOAD_WINDOW ERROR DWIN %id% ERROR %str%
- The core asked Monkey to update the named download window with
- the given error message.
-
- DOWNLOAD_WINDOW DONE DWIN %id%
- The core asked Monkey to destroy the named download window.
-
- SSL Certificate messages
- ------------------------
-
- SSLCERT VERIFY CERT %id% URL %url%
- The core asked Monkey to say whether or not a given SSL
- certificate is OK.
-
- 401 Login messages
- ------------------
-
- 401LOGIN OPEN M4 %id% URL %url% REALM %str%
- The core asked Monkey to ask for identification for the named
- realm at the given URL.
-
- Plotter messages
- ----------------
-
- Note, Monkey won't clip coordinates, but sometimes the core does.
-
- PLOT CLIP X0 %n% Y0 %n% X1 %n% Y1 %n%
- The core asked Monkey to clip plotting to the given clipping
- rectangle (X0,Y0) (X1,Y1)
-
- PLOT TEXT X %n% Y %n% STR %str%
- The core asked Monkey to plot the given string at the
- given coordinates.
-
- PLOT LINE X0 %n% Y0 %n% X1 %n% Y1 %n%
- The core asked Monkey to plot a line with the given start
- and end coordinates.
-
- PLOT RECT X0 %n% Y0 %n% X1 %n% Y1 %n%
- The core asked Monkey to plot a rectangle with the given
- coordinates as the corners.
-
- PLOT BITMAP X %n% Y %n% WIDTH %n% HEIGHT %n%
- The core asked Monkey to plot a bitmap at the given
- coordinates, scaled to the given width/height.
diff --git a/Docs/core-window-interface b/Docs/core-window-interface
deleted file mode 100644
index 83c5f58..0000000
--- a/Docs/core-window-interface
+++ b/dev/null
@@ -1,679 +0,0 @@
-Core Window Interface
-=====================
-
-The NetSurf core provides an optional API to frontend implementations
-which allows a number of "standard" window content interfaces to be
-provided.
-
-The currently available user interfaces are:
-
- - Cookies
- - Global history
- - Hotlist
- - SSL certificate view
-
-Although not currently included in future additional user interfaces
-will be available for:
-
- - local history
- - browser render
-
-To be clear these are generic implementations of this functionality
-that any frontend may use. Frontends are free to implement these
-interfaces in any manner as they see fit, the corewindow interface
-simply provides a default.
-
-core window API
----------------
-
-The API is fairly simple and simply involves passing a callback table
-and context pointer to the interface element being constructed.
-
-The header that defines the callback interface is netsurf/core_window.h
-
-The callback table contains five function pointer interfaces which the
-frontend must implement for the core.
-
- - invalidate
- invalidate an area of a window
-
- - update_size
- Update the limits of the window
-
- - scroll_visible
- Scroll the window to make area visible
-
- - get_window_dimensions
- Get window viewport dimensions
-
- - drag_status
- Inform corewindow owner of drag status
-
-Each callback will be passed the context pointer for the corewindow
-instance and the relevant additional information necessary to perform
-the operation.
-
-Each exported user interface element wraps this generic interface with
-a concrete implementation. For example the SSL certificate viewer is
-initialised with:
-
-nserror sslcert_viewer_init(struct core_window_callback_table *cw_t,
- void *core_window_handle,
- struct sslcert_session_data *ssl_d);
-
-This call creates a context which will display and navigate the ssl
-session data passed. The frontend must service the callbacks from the
-core to provide the necessary interactions with the frontend windowing
-system.
-
-These actions should ideally use the standard frontend window
-processing. So for the GTK frontend when the core calls the invalidate
-operation it simply marks the area passed as damaged (using
-gtk_widget_queue_draw_area()) and lets the standard expose event cause
-the redraw to occur.
-
-If the frontend needs to redraw an area of a window (perhaps an expose
-event occurred or the window has had an area marked as invalid) it
-must call the core window API wrappers implementation which will
-perform the plot operations required to update an area of the window.
-
-e.g in the case of ssl certificate viewer
-
-void sslcert_viewer_redraw(struct sslcert_session_data *ssl_d,
- int x, int y, struct rect *clip,
- const struct redraw_context *ctx);
-
-would perform the plot operations for that SSL data window.
-
-Usage
------
-
-The usage pattern that is expected is for a frontend to create a core
-window implementation that implements the necessary five API in a
-generic way and allows the frontend to provide the specific
-specialisation for each of the user interface elements it wishes to
-use (cookies, SSL viewer etc).
-
-The GTK frontend for example:
-
-has source corewindow.[ch] which implement the five core callbacks
-using generic GTK operations (invalidate calls
-gtk_widget_queue_draw_area() etc.) and then provides additional
-operations on a GTK drawing area object to attach expose event
-processing, keypress processing etc.
-
-The GTK corewindow (not to be confused with the core window API
-itself, this is purely the gtk wrapper) is used by ssl_cert.c which
-creates a nsgtk_crtvrfy_window structure containing the
-nsgtk_corewindow structure. It attaches actual GTK window handles to
-this structure and populates elements of nsgtk_corewindow and then
-calls sslcert_viewer_init() directly.
-
-frontend skeleton
------------------
-
-An example core window implementation for a frontend ssl certificate
-viewer is presented here. This implements the suggested usage above
-and provides generic corewindow helpers.
-
-
-frontends/example/corewindow.h
-------------------------------
-
-/*
- * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef EXAMPLE_COREWINDOW_H
-#define EXAMPLE_COREWINDOW_H
-
-#include "netsurf/core_window.h"
-
-/**
- * example core window state
- */
-struct example_corewindow {
-
-
- /*
- * Any variables common to any frontend window would go here.
- * e.g. drawing area handles, toolkit pointers or other state
- */
- example_toolkit_widget *tk_widget;
-
-
-
- /** drag status set by core */
- core_window_drag_status drag_staus;
-
- /** table of callbacks for core window operations */
- struct core_window_callback_table *cb_table;
-
- /**
- * callback to draw on drawable area of example core window
- *
- * \param example_cw The example core window structure.
- * \param r The rectangle of the window that needs updating.
- * \return NSERROR_OK on success otherwise apropriate error code
- */
- nserror (*draw)(struct example_corewindow *example_cw, struct rect *r);
-
- /**
- * callback for keypress on example core window
- *
- * \param example_cw The example core window structure.
- * \param nskey The netsurf key code.
- * \return NSERROR_OK if key processed,
- * NSERROR_NOT_IMPLEMENTED if key not processed
- * otherwise apropriate error code
- */
- nserror (*key)(struct example_corewindow *example_cw, uint32_t nskey);
-
- /**
- * callback for mouse event on example core window
- *
- * \param example_cw The example core window structure.
- * \param mouse_state mouse state
- * \param x location of event
- * \param y location of event
- * \return NSERROR_OK on sucess otherwise apropriate error code.
- */
- nserror (*mouse)(struct example_corewindow *example_cw, browser_mouse_state mouse_state, int x, int y);
-};
-
-/**
- * initialise elements of example core window.
- *
- * As a pre-requisite the draw, key and mouse callbacks must be defined
- *
- * \param example_cw A example core window structure to initialise
- * \return NSERROR_OK on successful initialisation otherwise error code.
- */
-nserror example_corewindow_init(struct example_corewindow *example_cw);
-
-/**
- * finalise elements of example core window.
- *
- * \param example_cw A example core window structure to initialise
- * \return NSERROR_OK on successful finalisation otherwise error code.
- */
-nserror example_corewindow_fini(struct example_corewindow *example_cw);
-
-#endif
-
-frontends/example/corewindow.c
-------------------------------
-
-/*
- * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * \file
- * EXAMPLE generic core window interface.
- *
- * Provides interface for core renderers to the example toolkit drawable area.
- *
- * This module is an object that must be encapsulated. Client users
- * should embed a struct example_corewindow at the beginning of their
- * context for this display surface, fill in relevant data and then
- * call example_corewindow_init()
- *
- * The example core window structure requires the callback for draw, key and
- * mouse operations.
- */
-
-#include <assert.h>
-#include <string.h>
-#include <math.h>
-
-#include "utils/log.h"
-#include "utils/utils.h"
-#include "utils/messages.h"
-#include "utils/utf8.h"
-#include "netsurf/keypress.h"
-#include "netsurf/mouse.h"
-#include "netsurf/plot_style.h"
-
-/* extremely likely there will be additional headers required in a real frontend */
-#include "example/corewindow.h"
-
-
-/* toolkit event handlers that do generic things and call internal callbacks */
-
-
-static bool
-example_cw_mouse_press_event(toolkit_widget *widget, toolkit_button bt, int x, int y, void *ctx)
-{
- struct example_corewindow *example_cw = (struct example_corewindow *)ctx;
-
- example_cw->mouse(example_cw, state, x, y);
-
- return true;
-}
-
-static bool
-example_cw_keyrelease_event(toolkit_widget *widget, void *ctx)
-{
- struct example_corewindow *example_cw = (struct example_corewindow *)ctx;
-
- example_cw->key(example_cw, keycode);
-
- return true;
-}
-
-
-
-/* signal handler for toolkit window redraw */
-static bool
-example_cw_draw_event(toolkit_widget *widget,
- toolkit_area *tk_area,
- void *ctx)
-{
- struct example_corewindow *example_cw = (struct example_corewindow *)ctx;
- struct rect clip;
-
- clip.x0 = tk_area.x;
- clip.y0 = tk_area.y;
- clip.x1 = tk_area.width;
- clip.y1 = tk_area.height;
-
- example_cw->draw(example_cw, &clip);
-
- return true;
-}
-
-
-/**
- * callback from core to request a redraw
- */
-static nserror
-example_cw_invalidate(struct core_window *cw, const struct rect *r)
-{
- struct example_corewindow *example_cw = (struct example_corewindow *)cw;
-
- toolkit_widget_queue_draw_area(example_cw->widget,
- r->x0, r->y0,
- r->x1 - r->x0, r->y1 - r->y0);
-}
-
-
-static void
-example_cw_update_size(struct core_window *cw, int width, int height)
-{
- struct example_corewindow *example_cw = (struct example_corewindow *)cw;
-
- toolkit_widget_set_size_request(EXAMPLE_WIDGET(example_cw->drawing_area),
- width, height);
-}
-
-
-static void
-example_cw_scroll_visible(struct core_window *cw, const struct rect *r)
-{
- struct example_corewindow *example_cw = (struct example_corewindow *)cw;
-
- toolkit_scroll_widget(example_cw->widget, r);
-}
-
-
-static void
-example_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
-{
- struct example_corewindow *example_cw = (struct example_corewindow *)cw;
-
- *width = toolkit_get_widget_width(example_cw->widget);
- *height = toolkit_get_widget_height(example_cw->widget);
-}
-
-
-static void
-example_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
-{
- struct example_corewindow *example_cw = (struct example_corewindow *)cw;
- example_cw->drag_staus = ds;
-}
-
-
-struct core_window_callback_table example_cw_cb_table = {
- .invalidate = example_cw_invalidate,
- .update_size = example_cw_update_size,
- .scroll_visible = example_cw_scroll_visible,
- .get_window_dimensions = example_cw_get_window_dimensions,
- .drag_status = example_cw_drag_status
-};
-
-/* exported function documented example/corewindow.h */
-nserror example_corewindow_init(struct example_corewindow *example_cw)
-{
- /* setup the core window callback table */
- example_cw->cb_table = &example_cw_cb_table;
-
- /* frontend toolkit specific method of causing example_cw_draw_event to be called when a drawing operation is required */
- toolkit_connect_draw_event(example_cw->tk_widget,
- example_cw_draw_event,
- example_cw);
-
- /* frontend toolkit specific method of causing example_cw_button_press_event to be called when a button press occours */
- toolkit_connect_button_press_event(example_cw->tk_widget,
- example_cw_button_press_event,
- example_cw);
-
- /* frontend toolkit specific method of causing example_cw_button_release_event to be called when a button release occours */
- toolkit_connect_button_release_event(example_cw->tk_widget,
- example_cw_button_release_event,
- example_cw);
-
- /* frontend toolkit specific method of causing example_cw_motion_notify_event to be called when there is motion over the widget */
- toolkit_connect_motion_event(example_cw->tk_widget,
- example_cw_motion_notify_event,
- example_cw);
-
- /* frontend toolkit specific method of causing example_cw_key_press_event to be called when a key press occours */
- toolkit_connect_button_press_event(example_cw->tk_widget,
- example_cw_key_press_event,
- example_cw);
-
- /* frontend toolkit specific method of causing example_cw_key_release_event to be called when a key release occours */
- toolkit_connect_button_release_event(example_cw->tk_widget,
- example_cw_key_release_event,
- example_cw);
-
-
- return NSERROR_OK;
-}
-
-/* exported interface documented in example/corewindow.h */
-nserror example_corewindow_fini(struct example_corewindow *example_cw)
-{
- return NSERROR_OK;
-}
-
-
-frontends/example/ssl_cert.h
-----------------------------
-
-/*
- * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NETSURF_EXAMPLE_SSL_CERT_H
-#define NETSURF_EXAMPLE_SSL_CERT_H 1
-
-struct nsurl;
-struct ssl_cert_info;
-
-/**
- * Prompt the user to verify a certificate with issuse.
- *
- * \param url The URL being verified.
- * \param certs The certificate to be verified
- * \param num The number of certificates to be verified.
- * \param cb Callback upon user decision.
- * \param cbpw Context pointer passed to cb
- * \return NSERROR_OK or error code if prompt creation failed.
- */
-nserror example_cert_verify(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
-
-#endif
-
-frontends/example/ssl_cert.c
-----------------------------
-
-/*
- * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * \file
- * Implementation of example certificate viewing using example core windows.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "utils/log.h"
-#include "netsurf/keypress.h"
-#include "netsurf/plotters.h"
-#include "desktop/sslcert_viewer.h"
-
-#include "example/corewindow.h"
-
-
-/**
- * EXAMPLE certificate viewing window context
- */
-struct example_crtvrfy_window {
- /** example core window context */
- struct example_corewindow core;
-
- /** SSL certificate viewer context data */
- struct sslcert_session_data *ssl_data;
-};
-
-/**
- * destroy a previously created certificate view
- */
-static nserror example_crtvrfy_destroy(struct example_crtvrfy_window *crtvrfy_win)
-{
- nserror res;
-
- res = sslcert_viewer_fini(crtvrfy_win->ssl_data);
- if (res == NSERROR_OK) {
- res = example_corewindow_fini(&crtvrfy_win->core);
- toolkit_windown_destroy(crtvrfy_win->window);
- free(crtvrfy_win);
- }
- return res;
-}
-
-static void
-example_crtvrfy_accept(ExampleButton *w, gpointer data)
-{
- struct example_crtvrfy_window *crtvrfy_win;
- crtvrfy_win = (struct example_crtvrfy_window *)data;
-
- sslcert_viewer_accept(crtvrfy_win->ssl_data);
-
- example_crtvrfy_destroy(crtvrfy_win);
-}
-
-static void
-example_crtvrfy_reject(ExampleWidget *w, gpointer data)
-{
- struct example_crtvrfy_window *crtvrfy_win;
- crtvrfy_win = (struct example_crtvrfy_window *)data;
-
- sslcert_viewer_reject(crtvrfy_win->ssl_data);
-
- example_crtvrfy_destroy(crtvrfy_win);
-}
-
-
-/**
- * callback for mouse action for certificate verify on core window
- *
- * \param example_cw The example core window structure.
- * \param mouse_state netsurf mouse state on event
- * \param x location of event
- * \param y location of event
- * \return NSERROR_OK on success otherwise apropriate error code
- */
-static nserror
-example_crtvrfy_mouse(struct example_corewindow *example_cw,
- browser_mouse_state mouse_state,
- int x, int y)
-{
- struct example_crtvrfy_window *crtvrfy_win;
- /* technically degenerate container of */
- crtvrfy_win = (struct example_crtvrfy_window *)example_cw;
-
- sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
-
- return NSERROR_OK;
-}
-
-/**
- * callback for keypress for certificate verify on core window
- *
- * \param example_cw The example core window structure.
- * \param nskey The netsurf key code
- * \return NSERROR_OK on success otherwise apropriate error code
- */
-static nserror
-example_crtvrfy_key(struct example_corewindow *example_cw, uint32_t nskey)
-{
- struct example_crtvrfy_window *crtvrfy_win;
-
- /* technically degenerate container of */
- crtvrfy_win = (struct example_crtvrfy_window *)example_cw;
-
- if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
- return NSERROR_OK;
- }
- return NSERROR_NOT_IMPLEMENTED;
-}
-
-/**
- * callback on draw event for certificate verify on core window
- *
- * \param example_cw The example core window structure.
- * \param r The rectangle of the window that needs updating.
- * \return NSERROR_OK on success otherwise apropriate error code
- */
-static nserror
-example_crtvrfy_draw(struct example_corewindow *example_cw, struct rect *r)
-{
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &example_plotters
- };
- struct example_crtvrfy_window *crtvrfy_win;
-
- /* technically degenerate container of */
- crtvrfy_win = (struct example_crtvrfy_window *)example_cw;
-
- sslcert_viewer_redraw(crtvrfy_win->ssl_data, 0, 0, r, &ctx);
-
- return NSERROR_OK;
-}
-
-/* exported interface documented in example/ssl_cert.h */
-nserror example_cert_verify(struct nsurl *url,
- const struct ssl_cert_info *certs,
- unsigned long num,
- nserror (*cb)(bool proceed, void *pw),
- void *cbpw)
-{
- struct example_crtvrfy_window *ncwin;
- nserror res;
-
- ncwin = malloc(sizeof(struct example_crtvrfy_window));
- if (ncwin == NULL) {
- return NSERROR_NOMEM;
- }
-
- res = toolkit_create_window(&ncwin->window);
- if (res != NSERROR_OK) {
- LOG("SSL UI builder init failed");
- free(ncwin);
- return res;
- }
-
- /* store the widget that the toolkit is drawing into */
- ncwin->core.widget = toolkit_get_widget(ncwin->window, "SSLDrawingArea"));
-
- /* would typicaly setup toolkit accept/reject buttons etc. here */
- toolkit_connect_button_press(ncwin->tk_accept_button,
- example_crtvrfy_accept,
- ncwin);
-
-
- /* initialise example core window */
- ncwin->core.draw = example_crtvrfy_draw;
- ncwin->core.key = example_crtvrfy_key;
- ncwin->core.mouse = example_crtvrfy_mouse;
-
- res = example_corewindow_init(&ncwin->core);
- if (res != NSERROR_OK) {
- free(ncwin);
- return res;
- }
-
- /* initialise certificate viewing interface */
- res = sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
- &ncwin->ssl_data);
- if (res != NSERROR_OK) {
- free(ncwin);
- return res;
- }
-
- res = sslcert_viewer_init(ncwin->core.cb_table,
- (struct core_window *)ncwin,
- ncwin->ssl_data);
- if (res != NSERROR_OK) {
- free(ncwin);
- return res;
- }
-
- toolkit_widget_show(ncwin->window);
-
- return NSERROR_OK;
-}
diff --git a/Makefile b/Makefile
index 97a8128..fa1420b 100644
--- a/Makefile
+++ b/Makefile
@@ -890,7 +890,7 @@ install: all-program install-$(TARGET)
.PHONY: docs
-docs: Docs/Doxyfile
+docs: docs/Doxyfile
doxygen $<
diff --git a/content/urldb.c b/content/urldb.c
index d702e58..313ec31 100644
--- a/content/urldb.c
+++ b/content/urldb.c
@@ -696,8 +696,8 @@ static bool urldb__host_is_ip_address(const char *host)
}
ipv6_addr_len = host_len - 2;
- if (ipv6_addr_len > sizeof(ipv6_addr)) {
- ipv6_addr_len = sizeof(ipv6_addr);
+ if (ipv6_addr_len >= sizeof(ipv6_addr)) {
+ ipv6_addr_len = sizeof(ipv6_addr) - 1;
}
strncpy(ipv6_addr, sane_host + 1, ipv6_addr_len);
ipv6_addr[ipv6_addr_len] = '\0';
@@ -849,7 +849,7 @@ urldb_iterate_partial_host(struct search_node *root,
*
* Given: http://www.example.org/a/b/c/d//e
* and assuming a path tree:
- * .
+ * ^
* / \
* a1 b1
* / \
diff --git a/desktop/browser.c b/desktop/browser.c
index 4b6a5bb..e7ff158 100644
--- a/desktop/browser.c
+++ b/desktop/browser.c
@@ -593,7 +593,7 @@ static void browser_window_set_selection(struct browser_window *bw,
* scrolls the viewport to ensure the specified rectangle of the
* content is shown.
*
- * \param gw gui_window to scroll
+ * \param bw window to scroll
* \param rect The rectangle to ensure is shown.
* \return NSERROR_OK on success or apropriate error code.
*/
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index cf70c47..dbbc67d 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -31,13 +31,11 @@
#include "utils/log.h"
#include "utils/utils.h"
#include "netsurf/layout.h"
-#include "netsurf/plotters.h"
#include "netsurf/content.h"
#include "content/hlcache.h"
#include "content/urldb.h"
#include "netsurf/bitmap.h"
-#include "desktop/system_colour.h"
#include "desktop/gui_internal.h"
#include "desktop/browser_history.h"
#include "desktop/browser_private.h"
@@ -47,39 +45,6 @@
#define RIGHT_MARGIN 50
#define BOTTOM_MARGIN 30
-struct history_page {
- nsurl *url; /**< Page URL, never 0. */
- lwc_string *frag_id; /** Fragment identifier, or 0. */
- char *title; /**< Page title, never 0. */
-};
-
-/** A node in the history tree. */
-struct history_entry {
- struct history_page page;
- struct history_entry *back; /**< Parent. */
- struct history_entry *next; /**< Next sibling. */
- struct history_entry *forward; /**< First child. */
- struct history_entry *forward_pref; /**< Child in direction of
- current entry. */
- struct history_entry *forward_last; /**< Last child. */
- unsigned int children; /**< Number of children. */
- int x; /**< Position of node. */
- int y; /**< Position of node. */
- struct bitmap *bitmap; /**< Thumbnail bitmap, or 0. */
-};
-
-/** History tree for a window. */
-struct history {
- /** First page in tree (page that window opened with). */
- struct history_entry *start;
- /** Current position in tree. */
- struct history_entry *current;
- /** Width of layout. */
- int width;
- /** Height of layout. */
- int height;
-};
-
/**
* Clone a history entry
@@ -236,208 +201,9 @@ static void browser_window_history__layout(struct history *history)
history->height += BOTTOM_MARGIN / 2;
}
-/** plot style for drawing lines between nodes */
-static plot_style_t pstyle_line = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_width = 2,
-};
-
-/** plot style for drawing background */
-static plot_style_t pstyle_bg = {
- .fill_type = PLOT_OP_TYPE_SOLID,
-};
-
-/** plot style for drawing rectangle round unselected nodes */
-static plot_style_t pstyle_rect = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_width = 1,
-};
-
-/** plot style for drawing rectangle round selected nodes */
-static plot_style_t pstyle_rect_sel = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_width = 3,
-};
-
-/** plot style for font on unselected nodes */
-static plot_font_style_t pfstyle_node = {
- .family = PLOT_FONT_FAMILY_SANS_SERIF,
- .size = 8 * FONT_SIZE_SCALE,
- .weight = 400,
- .flags = FONTF_NONE,
-};
-
-/** plot style for font on unselected nodes */
-static plot_font_style_t pfstyle_node_sel = {
- .family = PLOT_FONT_FAMILY_SANS_SERIF,
- .size = 8 * FONT_SIZE_SCALE,
- .weight = 900,
- .flags = FONTF_NONE,
-};
-
-/**
- * Recursively redraw a history_entry.
- *
- * \param history history containing the entry
- * \param entry entry to render
- * \param x0 area top left x coordinate
- * \param y0 area top left y coordinate
- * \param x1 area bottom right x coordinate
- * \param y1 area bottom right y coordinate
- * \param x window x offset
- * \param y window y offset
- * \param clip clip redraw
- * \param ctx current redraw context
- */
-static bool
-browser_window_history__redraw_entry(struct history *history,
- struct history_entry *entry,
- int x0, int y0, int x1, int y1,
- int x, int y, bool clip,
- const struct redraw_context *ctx)
-{
- size_t char_offset;
- int actual_x;
- struct history_entry *child;
- int tailsize = 5;
- int xoffset = x - x0;
- int yoffset = y - y0;
-
- plot_style_t *pstyle;
- plot_font_style_t *pfstyle;
- struct rect rect;
- nserror res;
-
- /* setup plot styles */
- if (entry == history->current) {
- pstyle = &pstyle_rect_sel;
- pfstyle = &pfstyle_node_sel;
- } else {
- pstyle = &pstyle_rect;
- pfstyle = &pfstyle_node;
- }
-
- /* setup clip area */
- if (clip) {
- rect.x0 = x0 + xoffset;
- rect.y0 = y0 + yoffset;
- rect.x1 = x1 + xoffset;
- rect.y1 = y1 + yoffset;
- res = ctx->plot->clip(ctx, &rect);
- if (res != NSERROR_OK) {
- return false;
- }
- }
-
- /* Only attempt to plot bitmap if it is present */
- if (entry->bitmap != NULL) {
- res = ctx->plot->bitmap(ctx,
- entry->bitmap,
- entry->x + xoffset,
- entry->y + yoffset,
- WIDTH, HEIGHT,
- 0xffffff,
- 0);
- if (res != NSERROR_OK) {
- return false;
- }
- }
-
- rect.x0 = entry->x - 1 + xoffset;
- rect.y0 = entry->y - 1 + yoffset;
- rect.x1 = entry->x + xoffset + WIDTH;
- rect.y1 = entry->y + yoffset + HEIGHT;
- res = ctx->plot->rectangle(ctx, pstyle, &rect);
- if (res != NSERROR_OK) {
- return false;
- }
-
- res = guit->layout->position(plot_style_font, entry->page.title,
- strlen(entry->page.title), WIDTH,
- &char_offset, &actual_x);
- if (res != NSERROR_OK) {
- return false;
- }
-
- res = ctx->plot->text(ctx,
- pfstyle,
- entry->x + xoffset,
- entry->y + HEIGHT + 12 + yoffset,
- entry->page.title,
- char_offset);
- if (res != NSERROR_OK) {
- return false;
- }
-
- /* for each child node draw a line and recurse redraw into it */
- for (child = entry->forward; child; child = child->next) {
- rect.x0 = entry->x + WIDTH + xoffset;
- rect.y0 = entry->y + HEIGHT / 2 + yoffset;
- rect.x1 = entry->x + WIDTH + tailsize + xoffset;
- rect.y1 = entry->y + HEIGHT / 2 + yoffset;
- res = ctx->plot->line(ctx, &pstyle_line, &rect);
- if (res != NSERROR_OK) {
- return false;
- }
-
- rect.x0 = entry->x + WIDTH + tailsize + xoffset;
- rect.y0 = entry->y + HEIGHT / 2 + yoffset;
- rect.x1 = child->x - tailsize + xoffset;
- rect.y1 = child->y + HEIGHT / 2 + yoffset;
- res = ctx->plot->line(ctx, &pstyle_line, &rect);
- if (res != NSERROR_OK) {
- return false;
- }
-
- rect.x0 = child->x - tailsize + xoffset;
- rect.y0 = child->y + HEIGHT / 2 + yoffset;
- rect.x1 = child->x + xoffset;
- rect.y1 = child->y + HEIGHT / 2 + yoffset;
- res = ctx->plot->line(ctx, &pstyle_line, &rect);
- if (res != NSERROR_OK) {
- return false;
- }
-
- if (!browser_window_history__redraw_entry(history, child,
- x0, y0, x1, y1, x, y, clip, ctx)) {
- return false;
- }
- }
-
- return true;
-}
-
-
-/**
- * Find the history entry at a position.
- *
- * \param entry entry to search from
- * \param x coordinate
- * \param y coordinate
- * \return an entry if found, 0 if none
- */
-
-static struct history_entry *browser_window_history__find_position(
- struct history_entry *entry, int x, int y)
-{
- struct history_entry *child;
- struct history_entry *found;
-
- if (!entry)
- return 0;
- if (entry->x <= x && x <= entry->x + WIDTH &&
- entry->y <= y && y <= entry->y + HEIGHT)
- return entry;
- for (child = entry->forward; child; child = child->next) {
- found = browser_window_history__find_position(child, x, y);
- if (found)
- return found;
- }
- return 0;
-}
/**
* Enumerate subentries in history
@@ -478,29 +244,8 @@ static bool browser_window_history__enumerate_entry(
/* exported interface documented in desktop/browser_history.h */
nserror browser_window_history_create(struct browser_window *bw)
{
- nserror res;
struct history *history;
- res = ns_system_colour_char("Window", &pstyle_bg.fill_colour);
- if (res != NSERROR_OK) {
- return res;
- }
- pfstyle_node.background = pstyle_bg.fill_colour;
- pfstyle_node_sel.background = pstyle_bg.fill_colour;
-
- res = ns_system_colour_char("GrayText", &pstyle_line.stroke_colour);
- if (res != NSERROR_OK) {
- return res;
- }
- pstyle_rect.stroke_colour = pstyle_line.stroke_colour;
- pfstyle_node.foreground = pstyle_line.stroke_colour;
-
- res = ns_system_colour_char("Highlight", &pstyle_rect_sel.stroke_colour);
- if (res != NSERROR_OK) {
- return res;
- }
- pfstyle_node_sel.foreground = pstyle_rect_sel.stroke_colour;
-
bw->history = NULL;
history = calloc(1, sizeof *history);
@@ -769,98 +514,6 @@ nserror browser_window_history_go(struct browser_window *bw,
/* exported interface documented in desktop/browser_history.h */
-void browser_window_history_size(struct browser_window *bw,
- int *width, int *height)
-{
- assert(bw != NULL);
- assert(bw->history != NULL);
-
- *width = bw->history->width;
- *height = bw->history->height;
-}
-
-
-/* exported interface documented in desktop/browser_history.h */
-bool browser_window_history_redraw(struct browser_window *bw,
- const struct redraw_context *ctx)
-{
- struct history *history;
-
- assert(bw != NULL);
- history = bw->history;
-
- if (history == NULL) {
- LOG("Attempt to draw NULL history.");
- return false;
- }
-
- if (!history->start)
- return true;
-
- return browser_window_history__redraw_entry(history, history->start,
- 0, 0, 0, 0, 0, 0, false, ctx);
-}
-
-
-/* exported interface documented in desktop/browser_history.h */
-bool browser_window_history_redraw_rectangle(struct browser_window *bw,
- int x0, int y0, int x1, int y1,
- int x, int y, const struct redraw_context *ctx)
-{
- struct history *history;
-
- assert(bw != NULL);
- history = bw->history;
-
- if (!history->start)
- return true;
-
- return browser_window_history__redraw_entry(history, history->start,
- x0, y0, x1, y1, x, y, true, ctx);
-}
-
-
-/* exported interface documented in desktop/browser_history.h */
-bool browser_window_history_click(struct browser_window *bw,
- int x, int y, bool new_window)
-{
- struct history_entry *entry;
- struct history *history;
-
- assert(bw != NULL);
- history = bw->history;
-
- entry = browser_window_history__find_position(history->start, x, y);
- if (!entry)
- return false;
- if (entry == history->current)
- return false;
-
- browser_window_history_go(bw, entry, new_window);
-
- return true;
-}
-
-
-/* exported interface documented in desktop/browser_history.h */
-const char *browser_window_history_position_url(struct browser_window *bw,
- int x, int y)
-{
- struct history_entry *entry;
- struct history *history;
-
- assert(bw != NULL);
- history = bw->history;
-
- entry = browser_window_history__find_position(history->start, x, y);
- if (!entry)
- return 0;
-
- return nsurl_access(entry->page.url);
-}
-
-
-/* exported interface documented in desktop/browser_history.h */
void browser_window_history_enumerate_forward(const struct browser_window *bw,
browser_window_history_enumerate_cb cb, void *user_data)
{
@@ -907,10 +560,9 @@ void browser_window_history_enumerate(const struct browser_window *bw,
/* exported interface documented in desktop/browser_history.h */
-const char *browser_window_history_entry_get_url(
- const struct history_entry *entry)
+nsurl *browser_window_history_entry_get_url(const struct history_entry *entry)
{
- return nsurl_access(entry->page.url);
+ return nsurl_ref(entry->page.url);
}
diff --git a/desktop/browser_history.h b/desktop/browser_history.h
index 8ffb612..9140e2c 100644
--- a/desktop/browser_history.h
+++ b/desktop/browser_history.h
@@ -16,71 +16,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Browser history tree (interface).
+/**
+ * \file
+ * Interface to browser history operations
+ *
+ * The are operations on a browsing contexts history. These interfaces
+ * allow navigation forward and backwards in the history as well as
+ * enumerating the entries.
+ *
+ * The local history viewing is distinct via corewindow defined in
+ * desktop/local_history.h
*/
-#ifndef _NETSURF_DESKTOP_BROWSER_HISTORY_H_
-#define _NETSURF_DESKTOP_BROWSER_HISTORY_H_
+#ifndef NETSURF_DESKTOP_BROWSER_HISTORY_H
+#define NETSURF_DESKTOP_BROWSER_HISTORY_H
#include <stdbool.h>
-#include <libwapcaplet/libwapcaplet.h>
#include "utils/errors.h"
-struct hlcache_handle;
struct browser_window;
struct history_entry;
-struct redraw_context;
-
-/**
- * Create a new history tree for a browser window window.
- *
- * \param bw browser window to create history for.
- *
- * \return NSERROR_OK or appropriate error otherwise
- */
-nserror browser_window_history_create(struct browser_window *bw);
-
-/**
- * Clone a bw's history tree for new bw
- *
- * \param existing browser window with history to clone.
- * \param clone browser window to make cloned history for.
- *
- * \return NSERROR_OK or appropriate error otherwise
- */
-nserror browser_window_history_clone(const struct browser_window *existing,
- struct browser_window *clone);
-/**
- * Insert a url into the history tree.
- *
- * \param bw browser window with history object
- * \param content content to add to history
- * \param frag_id fragment identifier, or NULL.
- * \return NSERROR_OK or error code on faliure.
- *
- * The page is added after the current entry and becomes current.
- */
-nserror browser_window_history_add(struct browser_window *bw,
- struct hlcache_handle *content, lwc_string *frag_id);
-
-/**
- * Update the thumbnail for the current entry.
- *
- * \param bw The browser window to update the history within.
- * \param content content for current entry
- * \return NSERROR_OK or error code on faliure.
- */
-nserror browser_window_history_update(struct browser_window *bw,
- struct hlcache_handle *content);
-
-/**
- * Free a history structure.
- *
- * \param bw The browser window to destroy the history within.
- */
-void browser_window_history_destroy(struct browser_window *bw);
/**
* Go back in the history.
@@ -91,6 +47,7 @@ void browser_window_history_destroy(struct browser_window *bw);
*/
nserror browser_window_history_back(struct browser_window *bw, bool new_window);
+
/**
* Go forward in the history.
*
@@ -100,6 +57,7 @@ nserror browser_window_history_back(struct browser_window *bw, bool new_window);
*/
nserror browser_window_history_forward(struct browser_window *bw, bool new_window);
+
/**
* Check whether it is pssible to go back in the history.
*
@@ -108,6 +66,7 @@ nserror browser_window_history_forward(struct browser_window *bw, bool new_windo
*/
bool browser_window_history_back_available(struct browser_window *bw);
+
/**
* Check whether it is pssible to go forwards in the history.
*
@@ -116,63 +75,6 @@ bool browser_window_history_back_available(struct browser_window *bw);
*/
bool browser_window_history_forward_available(struct browser_window *bw);
-/**
- * Get the dimensions of a history.
- *
- * \param bw browser window with history object.
- * \param width updated to width
- * \param height updated to height
- */
-void browser_window_history_size(struct browser_window *bw,
- int *width, int *height);
-
-/**
- * Redraw all of a history area.
- *
- * \param bw browser window with history object.
- * \param ctx current redraw context
- */
-bool browser_window_history_redraw(struct browser_window *bw,
- const struct redraw_context *ctx);
-
-/**
- * Redraw part of a history area.
- *
- * \param bw browser window with history object.
- * \param x0 left X co-ordinate of redraw area
- * \param y0 top Y co-ordinate of redraw area
- * \param x1 right X co-ordinate of redraw area
- * \param y1 lower Y co-ordinate of redraw area
- * \param x start X co-ordinate on plot canvas
- * \param y start Y co-ordinate on plot canvas
- * \param ctx current redraw context
- */
-bool browser_window_history_redraw_rectangle(struct browser_window *bw,
- int x0, int y0, int x1, int y1, int x, int y,
- const struct redraw_context *ctx);
-
-/**
- * Handle a mouse click in a history.
- *
- * \param bw browser window containing history
- * \param x click coordinate
- * \param y click coordinate
- * \param new_window open a new window instead of using bw
- * \return true if action was taken, false if click was not on an entry
- */
-bool browser_window_history_click(struct browser_window *bw,
- int x, int y, bool new_window);
-
-/**
- * Determine the URL of the entry at a position.
- *
- * \param bw browser window containing history
- * \param x x coordinate.
- * \param y y coordinate.
- * \return URL, or 0 if no entry at (x, y)
- */
-const char *browser_window_history_position_url(struct browser_window *bw,
- int x, int y);
/**
* Callback function type for history enumeration
@@ -187,6 +89,7 @@ typedef bool (*browser_window_history_enumerate_cb)(
int x0, int y0, int x1, int y1,
const struct history_entry *entry, void *user_data);
+
/**
* Enumerate all entries in the history.
* Do not change the history while it is being enumerated.
@@ -198,6 +101,7 @@ typedef bool (*browser_window_history_enumerate_cb)(
void browser_window_history_enumerate(const struct browser_window *bw,
browser_window_history_enumerate_cb cb, void *user_data);
+
/**
* Enumerate all entries that will be reached by the 'forward' button
*
@@ -208,6 +112,7 @@ void browser_window_history_enumerate(const struct browser_window *bw,
void browser_window_history_enumerate_forward(const struct browser_window *bw,
browser_window_history_enumerate_cb cb, void *user_data);
+
/**
* Enumerate all entries that will be reached by the 'back' button
*
@@ -218,14 +123,15 @@ void browser_window_history_enumerate_forward(const struct browser_window *bw,
void browser_window_history_enumerate_back(const struct browser_window *bw,
browser_window_history_enumerate_cb cb, void *user_data);
+
/**
* Returns the URL to a history entry
*
- * \param entry the history entry to retrieve the URL from
- * \return the URL
+ * \param entry the history entry to retrieve the URL from
+ * \return A referenced nsurl URL
*/
-const char *browser_window_history_entry_get_url(
- const struct history_entry *entry);
+struct nsurl *browser_window_history_entry_get_url(const struct history_entry *entry);
+
/**
* Returns the URL to a history entry
@@ -236,6 +142,7 @@ const char *browser_window_history_entry_get_url(
const char *browser_window_history_entry_get_fragment_id(
const struct history_entry *entry);
+
/**
* Returns the title of a history entry
*
@@ -245,6 +152,7 @@ const char *browser_window_history_entry_get_fragment_id(
const char *browser_window_history_entry_get_title(
const struct history_entry *entry);
+
/**
* Navigate to specified history entry, optionally in new window
*
diff --git a/desktop/browser_private.h b/desktop/browser_private.h
index 5a53e2f..8bbc573 100644
--- a/desktop/browser_private.h
+++ b/desktop/browser_private.h
@@ -35,8 +35,48 @@
struct box;
struct hlcache_handle;
struct gui_window;
-struct history;
struct selection;
+struct nsurl;
+
+/**
+ * history entry page information
+ */
+struct history_page {
+ struct nsurl *url; /**< Page URL, never NULL. */
+ lwc_string *frag_id; /** Fragment identifier, or NULL. */
+ char *title; /**< Page title, never NULL. */
+};
+
+/**
+ * A node in the history tree.
+ */
+struct history_entry {
+ struct history_page page;
+ struct history_entry *back; /**< Parent. */
+ struct history_entry *next; /**< Next sibling. */
+ struct history_entry *forward; /**< First child. */
+ struct history_entry *forward_pref; /**< Child in direction of
+ current entry. */
+ struct history_entry *forward_last; /**< Last child. */
+ unsigned int children; /**< Number of children. */
+ int x; /**< Position of node. */
+ int y; /**< Position of node. */
+ struct bitmap *bitmap; /**< Thumbnail bitmap, or 0. */
+};
+
+/**
+ * History tree for a window.
+ */
+struct history {
+ /** First page in tree (page that window opened with). */
+ struct history_entry *start;
+ /** Current position in tree. */
+ struct history_entry *current;
+ /** Width of layout. */
+ int width;
+ /** Height of layout. */
+ int height;
+};
/**
* Browser window data.
@@ -249,4 +289,57 @@ void browser_window_set_status(struct browser_window *bw, const char *text);
*/
struct browser_window * browser_window_get_root(struct browser_window *bw);
+
+/**
+ * Create a new history tree for a browser window window.
+ *
+ * \param bw browser window to create history for.
+ *
+ * \return NSERROR_OK or appropriate error otherwise
+ */
+nserror browser_window_history_create(struct browser_window *bw);
+
+/**
+ * Clone a bw's history tree for new bw
+ *
+ * \param existing browser window with history to clone.
+ * \param clone browser window to make cloned history for.
+ *
+ * \return NSERROR_OK or appropriate error otherwise
+ */
+nserror browser_window_history_clone(const struct browser_window *existing,
+ struct browser_window *clone);
+
+
+/**
+ * Insert a url into the history tree.
+ *
+ * \param bw browser window with history object
+ * \param content content to add to history
+ * \param frag_id fragment identifier, or NULL.
+ * \return NSERROR_OK or error code on faliure.
+ *
+ * The page is added after the current entry and becomes current.
+ */
+nserror browser_window_history_add(struct browser_window *bw,
+ struct hlcache_handle *content, lwc_string *frag_id);
+
+/**
+ * Update the thumbnail for the current entry.
+ *
+ * \param bw The browser window to update the history within.
+ * \param content content for current entry
+ * \return NSERROR_OK or error code on faliure.
+ */
+nserror browser_window_history_update(struct browser_window *bw,
+ struct hlcache_handle *content);
+
+/**
+ * Free a history structure.
+ *
+ * \param bw The browser window to destroy the history within.
+ */
+void browser_window_history_destroy(struct browser_window *bw);
+
+
#endif
diff --git a/desktop/local_history.c b/desktop/local_history.c
index 6d07c8a..01222e2 100644
--- a/desktop/local_history.c
+++ b/desktop/local_history.c
@@ -22,28 +22,272 @@
*/
#include <stdlib.h>
+#include <string.h>
#include "utils/errors.h"
+#include "utils/nsurl.h"
#include "netsurf/types.h"
+#include "netsurf/layout.h"
#include "netsurf/core_window.h"
+#include "netsurf/plotters.h"
+#include "desktop/gui_internal.h"
+#include "desktop/system_colour.h"
+#include "desktop/browser_private.h"
#include "desktop/browser_history.h"
#include "desktop/local_history.h"
+#define WIDTH 100
+#define HEIGHT 86
+
+/**
+ * local history viewer context
+ */
struct local_history_session {
struct browser_window *bw;
struct core_window_callback_table *cw_t;
void *core_window_handle;
};
+
+/**
+ * plot style for drawing lines between nodes
+ */
+static plot_style_t pstyle_line = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 2,
+};
+
+
+/**
+ * plot style for drawing background
+ */
+static plot_style_t pstyle_bg = {
+ .fill_type = PLOT_OP_TYPE_SOLID,
+};
+
+
+/**
+ * plot style for drawing rectangle round unselected nodes
+ */
+static plot_style_t pstyle_rect = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 1,
+};
+
+
+/**
+ * plot style for drawing rectangle round selected nodes
+ */
+static plot_style_t pstyle_rect_sel = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 3,
+};
+
+
+/**
+ * plot style for font on unselected nodes
+ */
+static plot_font_style_t pfstyle_node = {
+ .family = PLOT_FONT_FAMILY_SANS_SERIF,
+ .size = 8 * FONT_SIZE_SCALE,
+ .weight = 400,
+ .flags = FONTF_NONE,
+};
+
+
+/**
+ * plot style for font on unselected nodes
+ */
+static plot_font_style_t pfstyle_node_sel = {
+ .family = PLOT_FONT_FAMILY_SANS_SERIF,
+ .size = 8 * FONT_SIZE_SCALE,
+ .weight = 900,
+ .flags = FONTF_NONE,
+};
+
+
+/**
+ * Recursively redraw a history entry.
+ *
+ * \param history history containing the entry
+ * \param entry entry to render
+ * \param clip redraw area
+ * \param x window x offset
+ * \param y window y offset
+ * \param ctx current redraw context
+ */
+static nserror
+redraw_entry(struct history *history,
+ struct history_entry *entry,
+ struct rect *clip,
+ int x, int y,
+ const struct redraw_context *ctx)
+{
+ size_t char_offset;
+ int actual_x;
+ struct history_entry *child;
+ int tailsize = 5;
+
+ plot_style_t *pstyle;
+ plot_font_style_t *pfstyle;
+ struct rect rect;
+ nserror res;
+
+ /* setup plot styles */
+ if (entry == history->current) {
+ pstyle = &pstyle_rect_sel;
+ pfstyle = &pfstyle_node_sel;
+ } else {
+ pstyle = &pstyle_rect;
+ pfstyle = &pfstyle_node;
+ }
+
+ /* Only attempt to plot bitmap if it is present */
+ if (entry->bitmap != NULL) {
+ res = ctx->plot->bitmap(ctx,
+ entry->bitmap,
+ entry->x + x,
+ entry->y + y,
+ WIDTH, HEIGHT,
+ 0xffffff,
+ 0);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ }
+
+ rect.x0 = entry->x - 1 + x;
+ rect.y0 = entry->y - 1 + y;
+ rect.x1 = entry->x + x + WIDTH;
+ rect.y1 = entry->y + y + HEIGHT;
+ res = ctx->plot->rectangle(ctx, pstyle, &rect);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ res = guit->layout->position(plot_style_font, entry->page.title,
+ strlen(entry->page.title), WIDTH,
+ &char_offset, &actual_x);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ res = ctx->plot->text(ctx,
+ pfstyle,
+ entry->x + x,
+ entry->y + HEIGHT + 12 + y,
+ entry->page.title,
+ char_offset);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ /* for each child node draw a line and recurse redraw into it */
+ for (child = entry->forward; child; child = child->next) {
+ rect.x0 = entry->x + WIDTH + x;
+ rect.y0 = entry->y + HEIGHT / 2 + y;
+ rect.x1 = entry->x + WIDTH + tailsize + x;
+ rect.y1 = entry->y + HEIGHT / 2 + y;
+ res = ctx->plot->line(ctx, &pstyle_line, &rect);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ rect.x0 = entry->x + WIDTH + tailsize + x;
+ rect.y0 = entry->y + HEIGHT / 2 + y;
+ rect.x1 = child->x - tailsize + x;
+ rect.y1 = child->y + HEIGHT / 2 + y;
+ res = ctx->plot->line(ctx, &pstyle_line, &rect);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ rect.x0 = child->x - tailsize + x;
+ rect.y0 = child->y + HEIGHT / 2 + y;
+ rect.x1 = child->x + x;
+ rect.y1 = child->y + HEIGHT / 2 + y;
+ res = ctx->plot->line(ctx, &pstyle_line, &rect);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ res = redraw_entry(history, child, clip, x, y, ctx);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ }
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Find the history entry at a position.
+ *
+ * \param entry entry to search from
+ * \param x coordinate
+ * \param y coordinate
+ * \return an entry if found, 0 if none
+ */
+static struct history_entry *
+find_entry_position(struct history_entry *entry, int x, int y)
+{
+ struct history_entry *child;
+ struct history_entry *found;
+
+ if (!entry) {
+ return NULL;
+ }
+
+ if ((entry->x <= x) &&
+ (x <= entry->x + WIDTH) &&
+ (entry->y <= y) &&
+ (y <= entry->y + HEIGHT)) {
+ return entry;
+ }
+
+ for (child = entry->forward; child; child = child->next) {
+ found = find_entry_position(child, x, y);
+ if (found) {
+ return found;
+ }
+ }
+
+ return NULL;
+}
+
+
/* exported interface documented in desktop/local_history.h */
-nserror local_history_init(struct core_window_callback_table *cw_t,
- void *core_window_handle,
- struct browser_window *bw,
- struct local_history_session **session)
+nserror
+local_history_init(struct core_window_callback_table *cw_t,
+ void *core_window_handle,
+ struct browser_window *bw,
+ struct local_history_session **session)
{
+ nserror res;
struct local_history_session *nses;
+ res = ns_system_colour_char("Window", &pstyle_bg.fill_colour);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ pfstyle_node.background = pstyle_bg.fill_colour;
+ pfstyle_node_sel.background = pstyle_bg.fill_colour;
+
+ res = ns_system_colour_char("GrayText", &pstyle_line.stroke_colour);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ pstyle_rect.stroke_colour = pstyle_line.stroke_colour;
+ pfstyle_node.foreground = pstyle_line.stroke_colour;
+
+ res = ns_system_colour_char("Highlight", &pstyle_rect_sel.stroke_colour);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ pfstyle_node_sel.foreground = pstyle_rect_sel.stroke_colour;
+
nses = calloc(1, sizeof(struct local_history_session));
if (nses == NULL) {
return NSERROR_NOMEM;
@@ -55,6 +299,7 @@ nserror local_history_init(struct core_window_callback_table *cw_t,
local_history_set(nses, bw);
*session = nses;
+
return NSERROR_OK;
}
@@ -75,26 +320,69 @@ local_history_redraw(struct local_history_session *session,
struct rect *clip,
const struct redraw_context *ctx)
{
- if (session->bw != NULL) {
- browser_window_history_redraw_rectangle(session->bw,
- clip->x0, clip->y0, clip->x1, clip->y1, x, y, ctx);
+ struct rect r = {
+ .x0 = clip->x0 + x,
+ .y0 = clip->y0 + y,
+ .x1 = clip->x1 + x,
+ .y1 = clip->y1 + y,
+ };
+
+ if (session->bw == NULL) {
+ return NSERROR_OK;
}
- return NSERROR_OK;
+
+ if (session->bw->history->start == NULL) {
+ return NSERROR_OK;
+ }
+
+ ctx->plot->clip(ctx, &r);
+ ctx->plot->rectangle(ctx, &pstyle_bg, &r);
+
+ return redraw_entry(session->bw->history,
+ session->bw->history->start,
+ clip,
+ x, y,
+ ctx);
}
/* exported interface documented in desktop/local_history.h */
-void
+nserror
local_history_mouse_action(struct local_history_session *session,
enum browser_mouse_state mouse,
int x,
int y)
{
+ struct history_entry *entry;
+ bool new_window;
+
+ if (session->bw == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ if ((mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2)) == 0) {
+ return NSERROR_NOT_IMPLEMENTED;
+ }
+
+ entry = find_entry_position(session->bw->history->start, x, y);
+ if (entry == NULL) {
+ return NSERROR_NOT_FOUND;
+ }
+
+ if (entry == session->bw->history->current) {
+ return NSERROR_PERMISSION;
+ }
+
if (mouse & BROWSER_MOUSE_PRESS_1) {
- browser_window_history_click(session->bw, x, y, false);
- } else if (mouse & BROWSER_MOUSE_PRESS_2) {
- browser_window_history_click(session->bw, x, y, true);
+ new_window = false;
+ } else if (mouse & BROWSER_MOUSE_PRESS_2) {
+ new_window = true;
+ } else {
+ new_window = false;
}
+ browser_window_history_go(session->bw, entry, new_window);
+
+ return NSERROR_OK;
}
/* exported interface documented in desktop/local_history.h */
@@ -109,15 +397,13 @@ nserror
local_history_set(struct local_history_session *session,
struct browser_window *bw)
{
- int width;
- int height;
-
session->bw = bw;
if (bw != NULL) {
- browser_window_history_size(session->bw, &width, &height);
+ assert(session->bw->history != NULL);
session->cw_t->update_size(session->core_window_handle,
- width, height);
+ session->bw->history->width,
+ session->bw->history->height);
}
return NSERROR_OK;
@@ -130,10 +416,8 @@ local_history_get_size(struct local_history_session *session,
int *width,
int *height)
{
-
- browser_window_history_size(session->bw, width, height);
- *width += 20;
- *height += 20;
+ *width = session->bw->history->width + 20;
+ *height = session->bw->history->height + 20;
return NSERROR_OK;
}
@@ -143,15 +427,20 @@ local_history_get_size(struct local_history_session *session,
nserror
local_history_get_url(struct local_history_session *session,
int x, int y,
- const char **url_out)
+ nsurl **url_out)
{
- const char *url;
- url = browser_window_history_position_url(session->bw, x, y);
- if (url == NULL) {
+ struct history_entry *entry;
+
+ if (session->bw == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ entry = find_entry_position(session->bw->history->start, x, y);
+ if (entry == NULL) {
return NSERROR_NOT_FOUND;
}
- *url_out = url;
+ *url_out = nsurl_ref(entry->page.url);
return NSERROR_OK;
}
diff --git a/desktop/local_history.h b/desktop/local_history.h
index 2ce2a5c..7f85a63 100644
--- a/desktop/local_history.h
+++ b/desktop/local_history.h
@@ -35,14 +35,15 @@ struct browser_window;
/**
* Initialise the local history.
*
- * This iterates through the URL database, generating the local history data,
- * and creates a treeview.
+ * This iterates through the history object of a browser window and
+ * creates tree of visited pages with thumbnails which may be selected
+ * to cause navigation.
*
* This must be called before any other local_history_* function.
*
- * \param cw_t Callback table for core_window containing the treeview.
- * \param core_window_handle The core_window in which the treeview is shown.
- * \param bw browser window to show history of.
+ * \param[in] cw_t Callback table for core_window containing the treeview.
+ * \param[in] core_window_handle The core_window in which the treeview is shown.
+ * \param[in] bw browser window to show history of.
* \param[out] session The created local history session context.
* \return NSERROR_OK on success and session set, appropriate error code otherwise
*/
@@ -54,12 +55,12 @@ nserror local_history_init(struct core_window_callback_table *cw_t,
/**
* Finalise the local history.
*
- * This destroys the local history treeview and the local history module's
- * internal data. After calling this if ocall history is required again,
- * local_history_init must be called.
+ * This destroys the local history view and the local history module's
+ * internal data. After calling this if local history is required again,
+ * local_history_init must be called to create a new session.
*
* \param session The local history session to finalise.
- * \return NSERROR_OK on success, appropriate error otherwise
+ * \return NSERROR_OK on success and session freed appropriate error otherwise
*/
nserror local_history_fini(struct local_history_session *session);
@@ -67,42 +68,53 @@ nserror local_history_fini(struct local_history_session *session);
/**
* Redraw the local history.
*
- * \param session The local history session context.
- * \param x X coordinate to render history at
- * \param y Y coordinate to render history at
- * \param clip Current clip rectangle (wrt tree origin)
- * \param ctx Current redraw context
+ * Causes the local history viewer to issue plot operations to redraw
+ * the specified area of the viewport.
+ *
+ * \param[in] session The local history session context.
+ * \param[in] x X coordinate to render history at
+ * \param[in] y Y coordinate to render history at
+ * \param[in] clip Current clip rectangle (wrt tree origin)
+ * \param[in] ctx Current redraw context
*/
nserror local_history_redraw(struct local_history_session *session, int x, int y, struct rect *clip, const struct redraw_context *ctx);
+
/**
* Handles all kinds of mouse action
*
- * \param session The local history session context.
- * \param mouse The current mouse state
- * \param x X coordinate
- * \param y Y coordinate
+ * \param[in] session The local history session context.
+ * \param[in] mouse The current mouse state
+ * \param[in] x The current mouse X coordinate
+ * \param[in] y The current mouse Y coordinate
+ * \return NSERROR_OK if mouse action was processed.
+ * NSERROR_NOT_FOUND if nothing under the pointer where it was clicked
+ * NSERROR_NOT_IMPLEMENTED if the action was not processed.
+ * NSERROR_PERMISSION if the clicked item was the current page
*/
-void local_history_mouse_action(struct local_history_session *session, enum browser_mouse_state mouse, int x, int y);
+nserror local_history_mouse_action(struct local_history_session *session, enum browser_mouse_state mouse, int x, int y);
+
/**
* Key press handling.
*
- * \param session The local history session context.
- * \param key The ucs4 character codepoint
+ * \param[in] session The local history session context.
+ * \param[in] key The ucs4 character codepoint
* \return true if the keypress is dealt with, false otherwise.
*/
bool local_history_keypress(struct local_history_session *session, uint32_t key);
+
/**
* Change the browser window to draw local history for.
*
- * \param session The local history session context.
+ * \param[in] session The local history session context.
* \param bw browser window to show history of.
* \return NSERROR_OK or appropriate error code.
*/
nserror local_history_set(struct local_history_session *session, struct browser_window *bw);
+
/**
* get size of local history content area.
*
@@ -113,6 +125,7 @@ nserror local_history_set(struct local_history_session *session, struct browser_
*/
nserror local_history_get_size(struct local_history_session *session, int *width, int *height);
+
/**
* get url of entry at position in local history content area.
*
@@ -121,10 +134,11 @@ nserror local_history_get_size(struct local_history_session *session, int *width
* \param[in] session The local history session context.
* \param[in] x The x coordinate to get url of.
* \param[in] y The y coordinate to get url of.
- * \param[out] url_out string representation of the url at the coordinates.
+ * \param[out] url_out referenced url.
* \return NSERROR_OK and url_out updated or NSERROR_NOT_FOUND if no url at
* location.
*/
-nserror local_history_get_url(struct local_history_session *session, int x, int y, const char **url_out);
+nserror local_history_get_url(struct local_history_session *session, int x, int y, struct nsurl **url_out);
+
#endif
diff --git a/desktop/scrollbar.h b/desktop/scrollbar.h
index f715331..fa5e167 100644
--- a/desktop/scrollbar.h
+++ b/desktop/scrollbar.h
@@ -19,6 +19,8 @@
/**
* \file
* Scrollbar widget interface.
+ *
+ * Scrollbar widgets used in frames code, not for frontend use
*/
#ifndef NETSURF_DESKTOP_SCROLLBAR_H
@@ -30,10 +32,10 @@
#define SCROLLBAR_WIDTH 16
/* Region dependent values for scrollbar_scroll function */
-#define SCROLL_TOP INT_MIN
-#define SCROLL_PAGE_UP INT_MIN + 1
-#define SCROLL_PAGE_DOWN INT_MAX - 1
-#define SCROLL_BOTTOM INT_MAX
+#define SCROLL_TOP INT_MIN
+#define SCROLL_PAGE_UP (INT_MIN + 1)
+#define SCROLL_PAGE_DOWN (INT_MAX - 1)
+#define SCROLL_BOTTOM INT_MAX
struct scrollbar;
diff --git a/Docs/Doxyfile b/docs/Doxyfile
index f3fdd1e..e549981 100644
--- a/Docs/Doxyfile
+++ b/docs/Doxyfile
@@ -753,7 +753,10 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
-INPUT = frontends/amiga \
+INPUT = docs \
+ docs/env.sh \
+ docs/UnimplementedJavascript.txt \
+ frontends/amiga \
frontends/amiga/stringview \
frontends/atari \
frontends/atari/plot \
@@ -780,8 +783,7 @@ INPUT = frontends/amiga \
content/handlers/javascript \
content/handlers/javascript/duktape \
utils \
- utils/http \
- Docs/UnimplementedJavascript.txt
+ utils/http
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -806,7 +808,8 @@ FILE_PATTERNS = *.c \
*.y \
*.l \
*.cpp \
- *.m
+ *.m \
+ *.md
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
@@ -922,7 +925,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
-USE_MDFILE_AS_MAINPAGE =
+USE_MDFILE_AS_MAINPAGE = mainpage.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
diff --git a/Docs/PACKAGING-GTK b/docs/PACKAGING-GTK
index 8f67522..8f67522 100644
--- a/Docs/PACKAGING-GTK
+++ b/docs/PACKAGING-GTK
diff --git a/Docs/UnimplementedJavascript.txt b/docs/UnimplementedJavascript.txt
index 1b851b8..1b851b8 100644
--- a/Docs/UnimplementedJavascript.txt
+++ b/docs/UnimplementedJavascript.txt
diff --git a/Docs/BUILDING-AmigaCross b/docs/building-AmigaCross.md
index 32762cd..32762cd 100644
--- a/Docs/BUILDING-AmigaCross
+++ b/docs/building-AmigaCross.md
diff --git a/Docs/BUILDING-AmigaOS b/docs/building-AmigaOS.md
index 3f05b9c..3f05b9c 100644
--- a/Docs/BUILDING-AmigaOS
+++ b/docs/building-AmigaOS.md
diff --git a/Docs/BUILDING-Framebuffer b/docs/building-Framebuffer.md
index 3c8858a..3c8858a 100644
--- a/Docs/BUILDING-Framebuffer
+++ b/docs/building-Framebuffer.md
diff --git a/Docs/BUILDING-GTK b/docs/building-GTK.md
index 4ac0fc8..4ac0fc8 100644
--- a/Docs/BUILDING-GTK
+++ b/docs/building-GTK.md
diff --git a/Docs/BUILDING-BeOS b/docs/building-Haiku.md
index 8642861..8642861 100644
--- a/Docs/BUILDING-BeOS
+++ b/docs/building-Haiku.md
diff --git a/Docs/BUILDING-Windows b/docs/building-Windows.md
index dc6769f..dc6769f 100644
--- a/Docs/BUILDING-Windows
+++ b/docs/building-Windows.md
diff --git a/docs/core-window-interface.md b/docs/core-window-interface.md
new file mode 100644
index 0000000..8f6951f
--- a/dev/null
+++ b/docs/core-window-interface.md
@@ -0,0 +1,677 @@
+Core Window Interface
+=====================
+
+The NetSurf core provides an optional API to frontend implementations
+which allows a number of "standard" window content interfaces to be
+provided.
+
+The currently available user interfaces are:
+
+ - Cookies
+ - Global history
+ - Hotlist
+ - SSL certificate view
+ - local history
+
+Although not currently included in future additional user interfaces
+will be available for the main browser render.
+
+To be clear these are generic implementations of this functionality
+that any frontend may use. Frontends are free to implement these
+interfaces in any manner as they see fit, the corewindow interface
+simply provides a default.
+
+core window API
+---------------
+
+The API is fairly simple and simply involves passing a callback table
+and context pointer to the interface element being constructed.
+
+The header that defines the callback interface is netsurf/core_window.h
+
+The callback table contains five function pointer interfaces which the
+frontend must implement for the core.
+
+ - invalidate
+ invalidate an area of a window
+
+ - update_size
+ Update the limits of the window
+
+ - scroll_visible
+ Scroll the window to make area visible
+
+ - get_window_dimensions
+ Get window viewport dimensions
+
+ - drag_status
+ Inform corewindow owner of drag status
+
+Each callback will be passed the context pointer for the corewindow
+instance and the relevant additional information necessary to perform
+the operation.
+
+Each exported user interface element wraps this generic interface with
+a concrete implementation. For example the SSL certificate viewer is
+initialised with:
+
+ nserror sslcert_viewer_init(struct core_window_callback_table *cw_t,
+ void *core_window_handle,
+ struct sslcert_session_data *ssl_d);
+
+This call creates a context which will display and navigate the ssl
+session data passed. The frontend must service the callbacks from the
+core to provide the necessary interactions with the frontend windowing
+system.
+
+These actions should ideally use the standard frontend window
+processing. So for the GTK frontend when the core calls the invalidate
+operation it simply marks the area passed as damaged (using
+gtk_widget_queue_draw_area()) and lets the standard expose event cause
+the redraw to occur.
+
+If the frontend needs to redraw an area of a window (perhaps an expose
+event occurred or the window has had an area marked as invalid) it
+must call the core window API wrappers implementation which will
+perform the plot operations required to update an area of the window.
+
+e.g in the case of ssl certificate viewer
+
+ void sslcert_viewer_redraw(struct sslcert_session_data *ssl_d,
+ int x, int y, struct rect *clip,
+ const struct redraw_context *ctx);
+
+would perform the plot operations for that SSL data window.
+
+Usage
+-----
+
+The usage pattern that is expected is for a frontend to create a core
+window implementation that implements the necessary five API in a
+generic way and allows the frontend to provide the specific
+specialisation for each of the user interface elements it wishes to
+use (cookies, SSL viewer etc).
+
+The GTK frontend for example:
+
+has source corewindow.[ch] which implement the five core callbacks
+using generic GTK operations (invalidate calls
+gtk_widget_queue_draw_area() etc.) and then provides additional
+operations on a GTK drawing area object to attach expose event
+processing, keypress processing etc.
+
+The GTK corewindow (not to be confused with the core window API
+itself, this is purely the gtk wrapper) is used by ssl_cert.c which
+creates a nsgtk_crtvrfy_window structure containing the
+nsgtk_corewindow structure. It attaches actual GTK window handles to
+this structure and populates elements of nsgtk_corewindow and then
+calls sslcert_viewer_init() directly.
+
+frontend skeleton
+-----------------
+
+An example core window implementation for a frontend ssl certificate
+viewer is presented here. This implements the suggested usage above
+and provides generic corewindow helpers.
+
+
+frontends/example/corewindow.h
+------------------------------
+
+ /*
+ * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ #ifndef EXAMPLE_COREWINDOW_H
+ #define EXAMPLE_COREWINDOW_H
+
+ #include "netsurf/core_window.h"
+
+ /**
+ * example core window state
+ */
+ struct example_corewindow {
+
+
+ /*
+ * Any variables common to any frontend window would go here.
+ * e.g. drawing area handles, toolkit pointers or other state
+ */
+ example_toolkit_widget *tk_widget;
+
+
+
+ /** drag status set by core */
+ core_window_drag_status drag_status;
+
+ /** table of callbacks for core window operations */
+ struct core_window_callback_table *cb_table;
+
+ /**
+ * callback to draw on drawable area of example core window
+ *
+ * \param example_cw The example core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ nserror (*draw)(struct example_corewindow *example_cw, struct rect *r);
+
+ /**
+ * callback for keypress on example core window
+ *
+ * \param example_cw The example core window structure.
+ * \param nskey The netsurf key code.
+ * \return NSERROR_OK if key processed,
+ * NSERROR_NOT_IMPLEMENTED if key not processed
+ * otherwise apropriate error code
+ */
+ nserror (*key)(struct example_corewindow *example_cw, uint32_t nskey);
+
+ /**
+ * callback for mouse event on example core window
+ *
+ * \param example_cw The example core window structure.
+ * \param mouse_state mouse state
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on sucess otherwise apropriate error code.
+ */
+ nserror (*mouse)(struct example_corewindow *example_cw, browser_mouse_state mouse_state, int x, int y);
+ };
+
+ /**
+ * initialise elements of example core window.
+ *
+ * As a pre-requisite the draw, key and mouse callbacks must be defined
+ *
+ * \param example_cw A example core window structure to initialise
+ * \return NSERROR_OK on successful initialisation otherwise error code.
+ */
+ nserror example_corewindow_init(struct example_corewindow *example_cw);
+
+ /**
+ * finalise elements of example core window.
+ *
+ * \param example_cw A example core window structure to initialise
+ * \return NSERROR_OK on successful finalisation otherwise error code.
+ */
+ nserror example_corewindow_fini(struct example_corewindow *example_cw);
+
+ #endif
+
+frontends/example/corewindow.c
+------------------------------
+
+ /*
+ * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ /**
+ * file
+ * EXAMPLE generic core window interface.
+ *
+ * Provides interface for core renderers to the example toolkit drawable area.
+ *
+ * This module is an object that must be encapsulated. Client users
+ * should embed a struct example_corewindow at the beginning of their
+ * context for this display surface, fill in relevant data and then
+ * call example_corewindow_init()
+ *
+ * The example core window structure requires the callback for draw, key and
+ * mouse operations.
+ */
+
+ #include <assert.h>
+ #include <string.h>
+ #include <math.h>
+
+ #include "utils/log.h"
+ #include "utils/utils.h"
+ #include "utils/messages.h"
+ #include "utils/utf8.h"
+ #include "netsurf/keypress.h"
+ #include "netsurf/mouse.h"
+ #include "netsurf/plot_style.h"
+
+ /* extremely likely there will be additional headers required in a real frontend */
+ #include "example/corewindow.h"
+
+
+ /* toolkit event handlers that do generic things and call internal callbacks */
+
+
+ static bool
+ example_cw_mouse_press_event(toolkit_widget *widget, toolkit_button bt, int x, int y, void *ctx)
+ {
+ struct example_corewindow *example_cw = (struct example_corewindow *)ctx;
+
+ example_cw->mouse(example_cw, state, x, y);
+
+ return true;
+ }
+
+ static bool
+ example_cw_keyrelease_event(toolkit_widget *widget, void *ctx)
+ {
+ struct example_corewindow *example_cw = (struct example_corewindow *)ctx;
+
+ example_cw->key(example_cw, keycode);
+
+ return true;
+ }
+
+
+
+ /* signal handler for toolkit window redraw */
+ static bool
+ example_cw_draw_event(toolkit_widget *widget,
+ toolkit_area *tk_area,
+ void *ctx)
+ {
+ struct example_corewindow *example_cw = (struct example_corewindow *)ctx;
+ struct rect clip;
+
+ clip.x0 = tk_area.x;
+ clip.y0 = tk_area.y;
+ clip.x1 = tk_area.width;
+ clip.y1 = tk_area.height;
+
+ example_cw->draw(example_cw, &clip);
+
+ return true;
+ }
+
+
+ /**
+ * callback from core to request a redraw
+ */
+ static nserror
+ example_cw_invalidate(struct core_window *cw, const struct rect *r)
+ {
+ struct example_corewindow *example_cw = (struct example_corewindow *)cw;
+
+ toolkit_widget_queue_draw_area(example_cw->widget,
+ r->x0, r->y0,
+ r->x1 - r->x0, r->y1 - r->y0);
+ }
+
+
+ static void
+ example_cw_update_size(struct core_window *cw, int width, int height)
+ {
+ struct example_corewindow *example_cw = (struct example_corewindow *)cw;
+
+ toolkit_widget_set_size_request(EXAMPLE_WIDGET(example_cw->drawing_area),
+ width, height);
+ }
+
+
+ static void
+ example_cw_scroll_visible(struct core_window *cw, const struct rect *r)
+ {
+ struct example_corewindow *example_cw = (struct example_corewindow *)cw;
+
+ toolkit_scroll_widget(example_cw->widget, r);
+ }
+
+
+ static void
+ example_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
+ {
+ struct example_corewindow *example_cw = (struct example_corewindow *)cw;
+
+ *width = toolkit_get_widget_width(example_cw->widget);
+ *height = toolkit_get_widget_height(example_cw->widget);
+ }
+
+
+ static void
+ example_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
+ {
+ struct example_corewindow *example_cw = (struct example_corewindow *)cw;
+ example_cw->drag_status = ds;
+ }
+
+
+ struct core_window_callback_table example_cw_cb_table = {
+ .invalidate = example_cw_invalidate,
+ .update_size = example_cw_update_size,
+ .scroll_visible = example_cw_scroll_visible,
+ .get_window_dimensions = example_cw_get_window_dimensions,
+ .drag_status = example_cw_drag_status
+ };
+
+ /* exported function documented example/corewindow.h */
+ nserror example_corewindow_init(struct example_corewindow *example_cw)
+ {
+ /* setup the core window callback table */
+ example_cw->cb_table = &example_cw_cb_table;
+
+ /* frontend toolkit specific method of causing example_cw_draw_event to be called when a drawing operation is required */
+ toolkit_connect_draw_event(example_cw->tk_widget,
+ example_cw_draw_event,
+ example_cw);
+
+ /* frontend toolkit specific method of causing example_cw_button_press_event to be called when a button press occours */
+ toolkit_connect_button_press_event(example_cw->tk_widget,
+ example_cw_button_press_event,
+ example_cw);
+
+ /* frontend toolkit specific method of causing example_cw_button_release_event to be called when a button release occours */
+ toolkit_connect_button_release_event(example_cw->tk_widget,
+ example_cw_button_release_event,
+ example_cw);
+
+ /* frontend toolkit specific method of causing example_cw_motion_notify_event to be called when there is motion over the widget */
+ toolkit_connect_motion_event(example_cw->tk_widget,
+ example_cw_motion_notify_event,
+ example_cw);
+
+ /* frontend toolkit specific method of causing example_cw_key_press_event to be called when a key press occours */
+ toolkit_connect_button_press_event(example_cw->tk_widget,
+ example_cw_key_press_event,
+ example_cw);
+
+ /* frontend toolkit specific method of causing example_cw_key_release_event to be called when a key release occours */
+ toolkit_connect_button_release_event(example_cw->tk_widget,
+ example_cw_key_release_event,
+ example_cw);
+
+
+ return NSERROR_OK;
+ }
+
+ /* exported interface documented in example/corewindow.h */
+ nserror example_corewindow_fini(struct example_corewindow *example_cw)
+ {
+ return NSERROR_OK;
+ }
+
+
+frontends/example/ssl_cert.h
+----------------------------
+
+ /*
+ * Copyright 2016 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ #ifndef NETSURF_EXAMPLE_SSL_CERT_H
+ #define NETSURF_EXAMPLE_SSL_CERT_H 1
+
+ struct nsurl;
+ struct ssl_cert_info;
+
+ /**
+ * Prompt the user to verify a certificate with issuse.
+ *
+ * \param url The URL being verified.
+ * \param certs The certificate to be verified
+ * \param num The number of certificates to be verified.
+ * \param cb Callback upon user decision.
+ * \param cbpw Context pointer passed to cb
+ * \return NSERROR_OK or error code if prompt creation failed.
+ */
+ nserror example_cert_verify(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+
+ #endif
+
+frontends/example/ssl_cert.c
+----------------------------
+
+ /*
+ * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ /**
+ * file
+ * Implementation of example certificate viewing using example core windows.
+ */
+
+ #include <stdint.h>
+ #include <stdlib.h>
+
+ #include "utils/log.h"
+ #include "netsurf/keypress.h"
+ #include "netsurf/plotters.h"
+ #include "desktop/sslcert_viewer.h"
+
+ #include "example/corewindow.h"
+
+
+ /**
+ * EXAMPLE certificate viewing window context
+ */
+ struct example_crtvrfy_window {
+ /** example core window context */
+ struct example_corewindow core;
+
+ /** SSL certificate viewer context data */
+ struct sslcert_session_data *ssl_data;
+ };
+
+ /**
+ * destroy a previously created certificate view
+ */
+ static nserror example_crtvrfy_destroy(struct example_crtvrfy_window *crtvrfy_win)
+ {
+ nserror res;
+
+ res = sslcert_viewer_fini(crtvrfy_win->ssl_data);
+ if (res == NSERROR_OK) {
+ res = example_corewindow_fini(&crtvrfy_win->core);
+ toolkit_windown_destroy(crtvrfy_win->window);
+ free(crtvrfy_win);
+ }
+ return res;
+ }
+
+ static void
+ example_crtvrfy_accept(ExampleButton *w, gpointer data)
+ {
+ struct example_crtvrfy_window *crtvrfy_win;
+ crtvrfy_win = (struct example_crtvrfy_window *)data;
+
+ sslcert_viewer_accept(crtvrfy_win->ssl_data);
+
+ example_crtvrfy_destroy(crtvrfy_win);
+ }
+
+ static void
+ example_crtvrfy_reject(ExampleWidget *w, gpointer data)
+ {
+ struct example_crtvrfy_window *crtvrfy_win;
+ crtvrfy_win = (struct example_crtvrfy_window *)data;
+
+ sslcert_viewer_reject(crtvrfy_win->ssl_data);
+
+ example_crtvrfy_destroy(crtvrfy_win);
+ }
+
+
+ /**
+ * callback for mouse action for certificate verify on core window
+ *
+ * \param example_cw The example core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ static nserror
+ example_crtvrfy_mouse(struct example_corewindow *example_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+ {
+ struct example_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct example_crtvrfy_window *)example_cw;
+
+ sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
+
+ return NSERROR_OK;
+ }
+
+ /**
+ * callback for keypress for certificate verify on core window
+ *
+ * \param example_cw The example core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ static nserror
+ example_crtvrfy_key(struct example_corewindow *example_cw, uint32_t nskey)
+ {
+ struct example_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct example_crtvrfy_window *)example_cw;
+
+ if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+ }
+
+ /**
+ * callback on draw event for certificate verify on core window
+ *
+ * \param example_cw The example core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ static nserror
+ example_crtvrfy_draw(struct example_corewindow *example_cw, struct rect *r)
+ {
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &example_plotters
+ };
+ struct example_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct example_crtvrfy_window *)example_cw;
+
+ sslcert_viewer_redraw(crtvrfy_win->ssl_data, 0, 0, r, &ctx);
+
+ return NSERROR_OK;
+ }
+
+ /* exported interface documented in example/ssl_cert.h */
+ nserror example_cert_verify(struct nsurl *url,
+ const struct ssl_cert_info *certs,
+ unsigned long num,
+ nserror (*cb)(bool proceed, void *pw),
+ void *cbpw)
+ {
+ struct example_crtvrfy_window *ncwin;
+ nserror res;
+
+ ncwin = malloc(sizeof(struct example_crtvrfy_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ res = toolkit_create_window(&ncwin->window);
+ if (res != NSERROR_OK) {
+ LOG("SSL UI builder init failed");
+ free(ncwin);
+ return res;
+ }
+
+ /* store the widget that the toolkit is drawing into */
+ ncwin->core.widget = toolkit_get_widget(ncwin->window, "SSLDrawingArea"));
+
+ /* would typicaly setup toolkit accept/reject buttons etc. here */
+ toolkit_connect_button_press(ncwin->tk_accept_button,
+ example_crtvrfy_accept,
+ ncwin);
+
+
+ /* initialise example core window */
+ ncwin->core.draw = example_crtvrfy_draw;
+ ncwin->core.key = example_crtvrfy_key;
+ ncwin->core.mouse = example_crtvrfy_mouse;
+
+ res = example_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise certificate viewing interface */
+ res = sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
+ &ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ res = sslcert_viewer_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin,
+ ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ toolkit_widget_show(ncwin->window);
+
+ return NSERROR_OK;
+ }
diff --git a/Docs/env.sh b/docs/env.sh
index 9cfc956..518123e 100644
--- a/Docs/env.sh
+++ b/docs/env.sh
@@ -272,8 +272,8 @@ ns-clone()
done
# put current env.sh in place in workspace
- if [ ! -f "${TARGET_WORKSPACE}/env.sh" -a -f ${TARGET_WORKSPACE}/${NS_BROWSER}/Docs/env.sh ]; then
- cp ${TARGET_WORKSPACE}/${NS_BROWSER}/Docs/env.sh ${TARGET_WORKSPACE}/env.sh
+ if [ ! -f "${TARGET_WORKSPACE}/env.sh" -a -f ${TARGET_WORKSPACE}/${NS_BROWSER}/docs/env.sh ]; then
+ cp ${TARGET_WORKSPACE}/${NS_BROWSER}/docs/env.sh ${TARGET_WORKSPACE}/env.sh
fi
}
diff --git a/Docs/gource.sh b/docs/gource.sh
index a1fbcbe..a1fbcbe 100755
--- a/Docs/gource.sh
+++ b/docs/gource.sh
diff --git a/Docs/ideas/cache.txt b/docs/ideas/cache.txt
index fda0617..fda0617 100644
--- a/Docs/ideas/cache.txt
+++ b/docs/ideas/cache.txt
diff --git a/Docs/ideas/css-engine.txt b/docs/ideas/css-engine.txt
index 1ea8778..1ea8778 100644
--- a/Docs/ideas/css-engine.txt
+++ b/docs/ideas/css-engine.txt
diff --git a/Docs/ideas/render-library.txt b/docs/ideas/render-library.txt
index db645c4..db645c4 100644
--- a/Docs/ideas/render-library.txt
+++ b/docs/ideas/render-library.txt
diff --git a/docs/mainpage.md b/docs/mainpage.md
new file mode 100644
index 0000000..41f26d4
--- a/dev/null
+++ b/docs/mainpage.md
@@ -0,0 +1,93 @@
+NetSurf web browser
+===================
+
+![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1037/badge)[*](https://bestpractices.coreinfrastructure.org/projects/1037)
+
+The NetSurf code makes use of Doxygen for code documentation.
+
+User Interface
+--------------
+
+There are some basic user guides for the
+[framebuffer](docs/using-framebuffer.md) and
+[monkey](docs/using-monkey.md) frontends.
+
+The [core user options](docs/netsurf-options.md) of the browser are
+documented which are augmented by each frontend in a specific manner.
+
+Documented API
+--------------
+
+There are several documents which detail specific aspects of the
+codebase and APIs.
+
+### Core window
+
+The [core window API](docs/core-window-interface.md) allows frontends
+to use generic core code for user interface elements beyond the
+browser render.
+
+### Source object caching
+
+The [source object caching](docs/source-object-backing-store.md)
+provides a way for downloaded content to be kept on a persistent
+storage medium such as hard disc to make future retrieval of that
+content quickly.
+
+### Javascript
+
+JavaScript is provided by integrating the duktape library. There are [instructions](docs/updating-duktape.md) on how to update the library.
+
+A list of [unimplemented DOM and CSSOM methods](unimplemented.html)
+is available outlining the remaining API that have to be implemented.
+
+Development
+-----------
+
+Compiling a development edition of NetSurf requires a POSIX style
+environment. Typically this means a Linux based system although Free
+BSD, Open BSD, Mac OS X and Haiku all known to work.
+
+### Working with the team
+
+Generally it is sensible to check with the other developers if you are
+planning to make a change to NetSurf intended to be merged.
+
+We are often about on the IRC channel but failing that the developer
+mailing list is a good place to try.
+
+All the project sources are held in [public git repositories](http://source.netsurf-browser.org/)
+
+### Toolchains
+
+Compilation for non POSIX toolkits/frontends (e.g. RISC OS) generally
+relies upon a cross compilation environment which is generated using
+the makefiles found in our
+[toolchains](http://source.netsurf-browser.org/toolchains.git/)
+repository. These toolchains are built by the Continuous Integration
+(CI) system and the
+[results of the system](http://ci.netsurf-browser.org/builds/toolchains/)
+are published as a convenience.
+
+### Quick setup
+
+The [quick start guide](docs/quick-start.md) can be used to get a
+development environment setup quickly and uses the
+[env.sh](env_8sh_source.html) script the core team utilises.
+
+### Manual setup
+
+The Manual environment setup and compilation method is covered by the
+details in the [netsurf libraries](docs/netsurf-libraries.md) document
+for the core libraries and then one of the building documents for the
+specific frontend.
+
+- [Amiga Os cross](docs/building-AmigaCross.md) and [Amiga OS](docs/building-AmigaOS.md)
+- [Framebuffer](docs/building-Framebuffer.md)
+- [GTK](docs/building-GTK.md)
+- [Haiku (BeOS)](docs/building-Haiku.md)
+- [Windows Win32](docs/building-Windows.md)
+
+These documents are sometimes not completely up to
+date and the env.sh script should be considered canonical.
+
diff --git a/Docs/netsurf-fb.1 b/docs/netsurf-fb.1
index e4c3100..e4c3100 100644
--- a/Docs/netsurf-fb.1
+++ b/docs/netsurf-fb.1
diff --git a/Docs/netsurf-gtk.1 b/docs/netsurf-gtk.1
index 7b2f4f4..7b2f4f4 100644
--- a/Docs/netsurf-gtk.1
+++ b/docs/netsurf-gtk.1
diff --git a/Docs/LIBRARIES b/docs/netsurf-libraries.md
index dc5a980..dc5a980 100644
--- a/Docs/LIBRARIES
+++ b/docs/netsurf-libraries.md
diff --git a/Docs/Options b/docs/netsurf-options.md
index 89b8814..89b8814 100644
--- a/Docs/Options
+++ b/docs/netsurf-options.md
diff --git a/docs/quick-start.md b/docs/quick-start.md
new file mode 100644
index 0000000..8bc90de
--- a/dev/null
+++ b/docs/quick-start.md
@@ -0,0 +1,111 @@
+Quick Build Steps for NetSurf
+=============================
+
+Last Updated: 24 February 2015
+
+This document provides steps for building NetSurf.
+
+
+Grab a temporary env.sh
+-----------------------
+
+ $ wget http://git.netsurf-browser.org/netsurf.git/plain/docs/env.sh
+ $ source env.sh
+
+
+Install any packages you need
+-----------------------------
+
+Installs all packages required to build NetSurf and the NetSurf project
+libraries.
+
+ $ ns-package-install
+
+If your package manager is not supported, you will have to install third
+ party packages manually.
+
+
+Get the NetSurf project source code from Git
+--------------------------------------------
+
+ $ ns-clone
+
+
+Build and install our project libraries
+---------------------------------------
+
+Updates NetSurf project library sources to latest, builds and installs them.
+
+ $ ns-pull-install
+
+
+Switch to new NetSurf workspace
+-------------------------------
+
+Remove the bootstrack script and use the newly installed one
+
+ $ rm env.sh
+ $ cd ~/dev-netsurf/workspace
+ $ source env.sh
+
+
+Build and run NetSurf
+---------------------
+
+ $ cd netsurf
+
+To build the native front end (the GTK front end on Linux, BSDs, etc) you
+could do:
+
+ $ make
+ $ ./nsgtk
+
+To build the framebuffer front end, you could do:
+
+ $ make TARGET=framebuffer
+ $ ./nsfb
+
+
+Cross Compiling
+===============
+
+If you are cross compiling, you can follow the above steps, but when
+sourcing env.sh, you should set HOST environment variable to the
+appropriate triplet for your cross compiler. For example, to cross
+compile for RISC OS:
+
+ $ HOST=arm-unknown-riscos source env.sh
+
+After that, the commands such as `ns-package-install` and
+`ns-pull-install` will do what is appropriate for the platform you
+are building for.
+
+To do the final build of NetSurf, pass the appropriate TARGET to make.
+For example, to cross compile for RISC OS:
+
+ $ make TARGET=riscos
+
+Finally, you can package up your build to transfer to the system you
+are developing for. For example, to produce a package for RISC OS:
+
+ $ make TARGET=riscos package
+
+Getting a cross compiler set up
+-------------------------------
+
+We maintain cross compilation environments and an SDK for a number of
+platforms. These may be found in our toolchains repository.
+
+ $ git clone git://git.netsurf-browser.org/toolchains
+
+Pre-built versions of the toolchains for Debian systems are often available
+via our [automated build and test infrastructure](http://ci.netsurf-browser.org/builds/toolchains/)
+
+
+Not working?
+============
+
+If the above steps are inapplicable, or don't work, you can build manually.
+Follow the instructions in the BUILDING-* documents in the docs/ directory
+the NetSurf browser source tree.
+
diff --git a/Docs/source-object-backing-store b/docs/source-object-backing-store.md
index 0fb3614..0fb3614 100644
--- a/Docs/source-object-backing-store
+++ b/docs/source-object-backing-store.md
diff --git a/Docs/unit-testing b/docs/unit-testing
index 49d82ed..49d82ed 100644
--- a/Docs/unit-testing
+++ b/docs/unit-testing
diff --git a/Docs/updating-duktape.md b/docs/updating-duktape.md
index a3e5a79..672fccc 100644
--- a/Docs/updating-duktape.md
+++ b/docs/updating-duktape.md
@@ -13,11 +13,11 @@ Updating Duktape
2. Run the following command:
- python2 tools/configure.py \
- --output-directory /tmp/output \
- --source-directory src-input \
- --config-metadata config \
- --fixup-line '#include "duk_custom.h"'
+ python2 tools/configure.py \
+ --output-directory /tmp/output \
+ --source-directory src-input \
+ --config-metadata config \
+ --fixup-line '#include "duk_custom.h"'
3. This generates a suitable set of duktape
sources in `/tmp/output`
diff --git a/Docs/USING-Framebuffer b/docs/using-framebuffer.md
index 3af8f98..3af8f98 100644
--- a/Docs/USING-Framebuffer
+++ b/docs/using-framebuffer.md
diff --git a/docs/using-monkey.md b/docs/using-monkey.md
new file mode 100644
index 0000000..d6082bd
--- a/dev/null
+++ b/docs/using-monkey.md
@@ -0,0 +1,373 @@
+Usage Instructions for Monkey NetSurf
+=====================================
+
+This document provides usage instructions for the Monkey version of NetSurf.
+
+Monkey NetSurf has been tested on Ubuntu and Debian.
+
+Overview
+--------
+
+### What it is
+
+The NetSurf Monkey front end is a developer debug tool used to test how the
+core interacts with the user interface. It allows the developers to profile
+NetSurf and to interact with the core directly as though the developer were a
+front end.
+
+### What it is not
+
+Monkey is not a tool for building web-crawling robots or indeed anything other
+than a debug tool for the NetSurf developers.
+
+### How to interact with `nsmonkey`
+
+In brief, `nsmonkey` will produce tagged output on stdout and expect
+commands on stdin. Windows are numbered and for the most part
+tokens are space separated. In some cases (e.g. title or status)
+the final element on the output line is a string which might have
+spaces embedded within it. As such, output from `nsmonkey` should be
+parsed a token at a time, so that when such a string is encountered,
+the parser can stop splitting and return the rest.
+
+Commands to `nsmonkey` are namespaced. For example commands related to
+browser windows are prefixed by `WINDOW`.
+
+### Top level tags for `nsmonkey`
+
+* `QUIT`
+
+* `WINDOW`
+
+* `OPTIONS`
+
+### Top level response tags for nsmonkey
+
+* `GENERIC`: Generic messages such as poll loops etc.
+
+* `WARN`, `ERROR`, `DIE`: Error messages of varying importance
+
+* `WINDOW`: Anything about browser windows in general
+
+* `DOWNLOAD_WINDOW`: Anything about the download window.
+
+* `SSLCERT`: Anything about SSL certificates
+
+* `401LOGIN`: Anything about HTTP Basic Authentication logins
+
+* `PLOT`: Plot calls which come from the core.
+
+In the below, _%something%_ indicates a substitution made by Monkey.
+
+* _%url%_ will be a URL
+* _%id%_ will be an opaque ID
+* _%n%_ will be a number
+* _%bool%_ will be TRUE or FALSE
+* _%str%_ is a string and will only ever be at the end of an output line.
+
+### Warnings, errors etc
+
+* Warnings (tagged `WARN`) come from the NetSurf core.
+* Errors (tagged `ERROR`) tend to come from Monkey's parsers
+* Death (tagged `DIE`) comes from the core and kills Monkey dead.
+
+Commands
+--------
+
+### Generic commands
+
+* `QUIT`
+
+ Cause monkey to quit cleanly.
+ This will cleanly destroy open windows etc.
+
+* `OPTIONS` _%str_
+
+ Cause monkey to set options. The passed options should be in the same
+ form as the command line, e.g. `OPTIONS --enable_javascript=1`
+
+
+### Window commands
+
+* `WINDOW NEW` [_%url%_]
+
+ Create a new browser window, optionally giving the core
+ a URL to immediately navigate to.
+ Minimally you will receive a `WINDOW NEW WIN` _%id%_ response.
+
+* `WINDOW DESTROY` _%id%_
+
+ Destroy the given browser window.
+ Minimally you will receive a `WINDOW DESTROY WIN` _%id%_ response.
+
+* `WINDOW GO` _%id%_ _%url%_ [_%url%_]
+
+ Cause the given browser window to visit the given URL.
+ Optionally you can give a referrer URL to also use (simulating
+ a click in the browser on a link).
+ Minimally you can expect throbber, url etc responses.
+
+* `WINDOW REDRAW` _%id%_ [_%num% %num% %num% %num%_]
+
+ Cause a browser window to redraw. Optionally you can give a
+ set of coordinates to simulate a partial expose of the window.
+ Said coordinates are in traditional X0 Y0 X1 Y1 order.
+ The coordinates are in canvas, not window, coordinates. So you
+ should take into account the scroll offsets when issuing this
+ command.
+ Minimally you can expect redraw start/stop messages and you
+ can likely expect some number of `PLOT` results.
+
+* `WINDOW RELOAD` _%id%_
+
+ Cause a browser window to reload its current content.
+ Expect responses similar to a GO command.
+
+
+Responses
+---------
+
+### Generic messages
+
+* `GENERIC STARTED`
+
+ Monkey has started and is ready for commands
+
+* `GENERIC CLOSING_DOWN`
+
+ Monkey has been told to shut down and is doing so
+
+* `GENERIC FINISHED`
+
+ Monkey has finished and will now exit
+
+* `GENERIC LAUNCH URL` _%url%_
+
+ The core asked monkey to launch the given URL
+
+* `GENERIC THUMBNAIL URL` _%url%_
+
+ The core asked monkey to thumbnail a content without
+ a window.
+
+* `GENERIC POLL BLOCKING`
+* `GENERIC POLL TIMED` _%n%_
+
+ Monkey reached a point where it could sleep waiting for
+ commands or scheduled timeouts. No fetches nor redraws
+ were pending. If there are no timeouts or other pending
+ jobs then this will be a BLOCKING poll, otherwise the number
+ given is in milliseconds.
+
+### Window messages
+
+* `WINDOW NEW WIN` _%id%_ `FOR` _%id%_ `CLONE` _%id%_ `NEWTAB` _%bool%_
+
+ The core asked Monkey to open a new window. The IDs for `FOR` and
+ `CLONE` are core window IDs, the `WIN` id is a Monkey window ID.
+
+* `WINDOW SIZE WIN` _%id%_ `WIDTH` _%n%_ `HEIGHT` _%n%_
+
+ The window specified has been set to the shown width and height.
+
+* `WINDOW DESTROY WIN` _%id%_
+
+ The core has instructed Monkey to destroy the named window.
+
+* `WINDOW TITLE WIN` _%id%_ `STR` _%str%_
+
+ The core supplied a titlebar title for the given window.
+
+* `WINDOW REDRAW WIN` _%id%_
+
+ The core asked that Monkey redraw the given window.
+
+* `WINDOW GET_DIMENSIONS WIN` _%id%_ `WIDTH` _%n%_ `HEIGHT` _%n%_
+
+ The core asked Monkey what the dimensions of the window are.
+ Monkey has to respond immediately and returned the supplied width
+ and height values to the core.
+
+* `WINDOW NEW_CONTENT WIN` _%id%_
+
+ The core has informed Monkey that the named window has a new
+ content object.
+
+* `WINDOW NEW_ICON WIN` _%id%_
+
+ The core has informed Monkey that the named window has a new
+ icon (favicon) available.
+
+* `WINDOW START_THROBBER WIN` _%id%_
+
+ The core asked Monkey to start the throbber for the named
+ window. This indicates to the user that the window is busy.
+
+* `WINDOW STOP_THROBBER WIN` _%id%_
+
+ The core asked Monkey to stop the throbber for the named
+ window. This indicates to the user that the window is finished.
+
+* `WINDOW SET_SCROLL WIN` _%id%_ `X` _%n%_ `Y` _%n%_
+
+ The core asked Monkey to set the named window's scroll offsets
+ to the given X and Y position.
+
+* `WINDOW UPDATE_BOX WIN` _%id%_ `X` _%n%_ `Y` _%n%_ `WIDTH` _%n%_ `HEIGHT` _%n%_
+
+ The core asked Monkey to redraw the given portion of the content
+ display. Note these coordinates refer to the content, not the
+ viewport which Monkey is simulating.
+
+* `WINDOW UPDATE_EXTENT WIN` _%id%_ `WIDTH` _%n%_ `HEIGHT` _%n%_
+
+ The core has told us that the content in the given window has a
+ total width and height as shown. This allows us (along with the
+ window's width and height) to know the scroll limits.
+
+* `WINDOW SET_STATUS WIN` _%id%_ `STR` _%str%_
+
+ The core has told us that the given window needs its status bar
+ updating with the given message.
+
+* `WINDOW SET_POINTER WIN` _%id%_ `POINTER` _%id%_
+
+ The core has told us to update the mouse pointer for the given
+ window to the given pointer ID.
+
+* `WINDOW SET_SCALE WIN` _%id%_ `SCALE` _%n%_
+
+ The core has asked us to scale the given window by the given scale
+ factor.
+
+* `WINDOW SET_URL WIN` _%id%_ `URL` _%url%_
+
+ The core has informed us that the given window's URL bar needs
+ updating to the given url.
+
+* `WINDOW GET_SCROLL WIN` _%id%_ `X` _%n%_ `Y` _%n%_
+
+ The core asked Monkey for the scroll offsets. Monkey returned the
+ numbers shown for the window named.
+
+* `WINDOW SCROLL_START WIN` _%id%_
+
+ The core asked Monkey to scroll the named window to the top/left.
+
+* `WINDOW POSITION_FRAME WIN` _%id%_ `X0` _%n%_ `Y0` _%n%_ `X1` _%n%_ `Y1` _%n%_
+
+ The core asked Monkey to position the named window as a frame at
+ the given coordinates of its parent.
+
+* `WINDOW SCROLL_VISIBLE WIN` _%id%_ `X0` _%n%_ `Y0` _%n%_ `X1` _%n%_ `Y1` _%n%_
+
+ The core asked Monkey to scroll the named window until the
+ indicated box is visible.
+
+* `WINDOW PLACE_CARET WIN` _%id%_ `X` _%n%_ `Y` _%n%_ `HEIGHT` _%n%_
+
+ The core asked Monkey to render a caret in the named window at the
+ indicated position with the indicated height.
+
+* `WINDOW REMOVE_CARET WIN` _%id%_
+
+ The core asked Monkey to remove any caret in the named window.
+
+* `WINDOW SCROLL_START WIN` _%id%_ `X0` _%n%_ `Y0` _%n%_ `X1` _%n%_ `Y1` _%n%_
+
+ The core asked Monkey to scroll the named window to the start of
+ the given box.
+
+* `WINDOW SELECT_MENU WIN` _%id%_
+
+ The core asked Monkey to produce a selection menu for the named
+ window.
+
+* `WINDOW SAVE_LINK WIN` _%id%_ `URL` _%url%_ `TITLE` _%str%_
+
+ The core asked Monkey to save a link from the given window with
+ the given URL and anchor title.
+
+* `WINDOW THUMBNAIL WIN` _%id%_ `URL` _%url%_
+
+ The core asked Monkey to render a thumbnail for the given window
+ which is currently at the given URL.
+
+* `WINDOW REDRAW WIN` _%id%_ `START`
+
+ and
+
+ `WINDOW REDRAW WIN` _%id%_ `STOP`
+
+ The core wraps redraws in these messages. Thus `PLOT` responses can
+ be allocated to the appropriate window.
+
+### Download window messages
+
+* `DOWNLOAD_WINDOW CREATE DWIN` _%id%_ `WIN` _%id%_
+
+ The core asked Monkey to create a download window owned by the
+ given browser window.
+
+* `DOWNLOAD_WINDOW DATA DWIN` _%id%_ `SIZE` _%n%_ `DATA` _%str%_
+
+ The core asked Monkey to update the named download window with
+ the given byte size and data string.
+
+* `DOWNLOAD_WINDOW ERROR DWIN` _%id%_ `ERROR` _%str%_
+
+ The core asked Monkey to update the named download window with
+ the given error message.
+
+* `DOWNLOAD_WINDOW DONE DWIN` _%id%_
+
+ The core asked Monkey to destroy the named download window.
+
+### SSL Certificate messages
+
+* `SSLCERT VERIFY CERT` _%id%_ `URL` _%url%_
+
+ The core asked Monkey to say whether or not a given SSL
+ certificate is OK.
+
+> TODO: Implement the rest of the SSL certificat verification behaviour
+
+### 401 Login messages
+
+* `401LOGIN OPEN M4` _%id%_ `URL` _%url%_ `REALM` _%str%_
+
+ The core asked Monkey to ask for identification for the named
+ realm at the given URL.
+
+> TODO: Implement support to control the 401LOGIN process
+
+### Plotter messages
+
+> **Note, Monkey won't clip coordinates, but sometimes the core does.**
+
+* `PLOT CLIP X0` _%n%_ `Y0` _%n%_ `X1` _%n%_ `Y1` _%n%_
+
+ The core asked Monkey to clip plotting to the given clipping
+ rectangle (X0,Y0) (X1,Y1)
+
+* `PLOT TEXT X` _%n%_ `Y` _%n%_ `STR` _%str%_
+
+ The core asked Monkey to plot the given string at the
+ given coordinates.
+
+* `PLOT LINE X0` _%n%_ `Y0` _%n%_ `X1` _%n%_ `Y1` _%n%_
+
+ The core asked Monkey to plot a line with the given start
+ and end coordinates.
+
+* `PLOT RECT X0` _%n%_ `Y0` _%n%_ `X1` _%n%_ `Y1` _%n%_
+
+ The core asked Monkey to plot a rectangle with the given
+ coordinates as the corners.
+
+* `PLOT BITMAP X` _%n%_ `Y` _%n%_ `WIDTH` _%n%_ `HEIGHT` _%n%_
+
+ The core asked Monkey to plot a bitmap at the given
+ coordinates, scaled to the given width/height.
+
+> TODO: Check if other things are implemented and add them to the docs
diff --git a/frontends/amiga/corewindow.c b/frontends/amiga/corewindow.c
index 6b2d9e8..1a94dd3 100644
--- a/frontends/amiga/corewindow.c
+++ b/frontends/amiga/corewindow.c
@@ -806,7 +806,7 @@ static const struct ami_win_event_table ami_cw_table = {
* invalidated.
*
* \param[in] cw The core window to invalidate.
- * \param[in] rect area to redraw or NULL for the entire window area.
+ * \param[in] r area to redraw or NULL for the entire window area.
* \return NSERROR_OK on success or appropriate error code.
*/
static nserror
@@ -920,6 +920,7 @@ nserror ami_corewindow_init(struct ami_corewindow *ami_cw)
{
/* setup the core window callback table */
ami_cw->cb_table = &ami_cw_cb_table;
+ ami_cw->drag_status = CORE_WINDOW_DRAG_NONE;
/* clear some vars */
ami_cw->mouse_state = BROWSER_MOUSE_HOVER;
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index 7eacda7..5c6700a 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -90,6 +90,7 @@
#include <math.h>
#include <string.h>
#include <stdlib.h>
+#include <limits.h>
/* NetSurf core includes */
#include "utils/log.h"
@@ -115,7 +116,6 @@
#include "desktop/hotlist.h"
#include "desktop/version.h"
#include "desktop/save_complete.h"
-#include "desktop/scrollbar.h"
#include "desktop/searchweb.h"
/* NetSurf Amiga platform includes */
@@ -158,6 +158,11 @@
#define NSA_KBD_SCROLL_PX 10
#define NSA_MAX_HOTLIST_BUTTON_LEN 20
+#define SCROLL_TOP INT_MIN
+#define SCROLL_PAGE_UP (INT_MIN + 1)
+#define SCROLL_PAGE_DOWN (INT_MAX - 1)
+#define SCROLL_BOTTOM (INT_MAX)
+
/* Extra mouse button defines to match those in intuition/intuition.h */
#define SIDEDOWN (IECODE_4TH_BUTTON)
#define SIDEUP (IECODE_4TH_BUTTON | IECODE_UP_PREFIX)
@@ -4596,7 +4601,7 @@ static void gui_window_destroy(struct gui_window *g)
if(g->hw)
{
- ami_history_close(g->hw);
+ ami_history_local_destroy(g->hw);
win_destroyed = true;
}
@@ -4986,7 +4991,7 @@ static bool gui_window_get_scroll(struct gui_window *g, int *restrict sx, int *r
* content is shown. The amiga implementation scrolls the contents so
* the specified point in the content is at the top of the viewport.
*
- * \param gw gui_window to scroll
+ * \param g gui_window to scroll
* \param rect The rectangle to ensure is shown.
* \return NSERROR_OK on success or apropriate error code.
*/
diff --git a/frontends/amiga/gui.h b/frontends/amiga/gui.h
index 5cec82d..bf4ec91 100644
--- a/frontends/amiga/gui.h
+++ b/frontends/amiga/gui.h
@@ -87,7 +87,8 @@ enum
};
struct find_window;
-struct history_window;
+struct ami_history_local_window;
+struct ami_menu_data;
#define AMI_GUI_TOOLBAR_MAX 20
@@ -110,8 +111,6 @@ struct ami_generic_window {
const struct ami_win_event_table *tbl;
};
-struct ami_menu_data;
-
struct gui_window_2 {
struct ami_generic_window w;
struct Window *win;
@@ -174,7 +173,7 @@ struct gui_window
int c_h_temp;
int scrollx;
int scrolly;
- struct history_window *hw;
+ struct ami_history_local_window *hw;
struct List dllist;
struct hlcache_handle *favicon;
bool throbbing;
diff --git a/frontends/amiga/gui_menu.c b/frontends/amiga/gui_menu.c
index 0469dd5..6ee0800 100644
--- a/frontends/amiga/gui_menu.c
+++ b/frontends/amiga/gui_menu.c
@@ -326,7 +326,7 @@ HOOKF(void, ami_menu_item_browser_localhistory, APTR, window, struct IntuiMessag
struct gui_window_2 *gwin;
GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
- ami_history_open(gwin->gw);
+ ami_history_local_present(gwin->gw);
}
HOOKF(void, ami_menu_item_browser_globalhistory, APTR, window, struct IntuiMessage *)
diff --git a/frontends/amiga/history_local.c b/frontends/amiga/history_local.c
index 368557d..c293f59 100755..100644
--- a/frontends/amiga/history_local.c
+++ b/frontends/amiga/history_local.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009, 2010 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,341 +16,300 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Browser history window (AmigaOS implementation).
- *
- * There is only one history window, not one per browser window.
+/**
+ * \file
+ * Implementation of Amiga local history using core windows.
*/
-#include "amiga/os3support.h"
-
-#include <stdbool.h>
+#include <stdint.h>
#include <stdlib.h>
-#include <string.h>
+
#include <proto/intuition.h>
-#include <proto/exec.h>
-#include <proto/graphics.h>
-#include <intuition/icclass.h>
-#include <proto/utility.h>
-#include <proto/window.h>
-#include <proto/space.h>
-#include <proto/layout.h>
+
#include <classes/window.h>
-#include <gadgets/space.h>
+#include <gadgets/button.h>
+#include <gadgets/layout.h>
#include <gadgets/scroller.h>
-#include <reaction/reaction.h>
+#include <gadgets/space.h>
+#include <images/label.h>
+
+#include <intuition/icclass.h>
#include <reaction/reaction_macros.h>
#include "utils/log.h"
-#include "utils/utils.h"
-#include "utils/messages.h"
-#include "desktop/browser_history.h"
-#include "netsurf/browser_window.h"
+#include "netsurf/keypress.h"
#include "netsurf/plotters.h"
-#include "netsurf/window.h"
-#include "graphics/rpattr.h"
+#include "desktop/local_history.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
+#include "utils/nsurl.h"
-#include "amiga/libs.h"
-#include "amiga/misc.h"
-#include "amiga/object.h"
-#include "amiga/plotters.h"
+#include "amiga/corewindow.h"
#include "amiga/gui.h"
+#include "amiga/libs.h"
#include "amiga/history_local.h"
+#include "amiga/utf8.h"
-struct history_window {
- struct ami_generic_window w;
- struct Window *win;
- Object *objects[GID_LAST];
- struct gui_window *gw;
- struct Hook scrollerhook;
- struct gui_globals *gg;
-};
-static void ami_history_update_extent(struct history_window *hw);
-HOOKF(void, ami_history_scroller_hook, Object *, object, struct IntuiMessage *);
+/**
+ * Amiga local history viewing window context
+ */
+struct ami_history_local_window {
+ /** Amiga core window context */
+ struct ami_corewindow core;
-static BOOL ami_history_event(void *w);
+ /** Amiga GUI stuff */
+ struct gui_window *gw;
-static const struct ami_win_event_table ami_localhistory_table = {
- ami_history_event,
- NULL, /* we don't explicitly close the local history window on quit */
+ /** local history viewer context data */
+ struct local_history_session *session;
};
+static struct ami_history_local_window *history_local_window = NULL;
+
/**
- * Redraw history window.
+ * destroy a previously created local history view
*/
-
-static void ami_history_redraw(struct history_window *hw)
+nserror
+ami_history_local_destroy(struct ami_history_local_window *history_local_win)
{
- struct IBox *bbox;
- ULONG xs,ys;
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &amiplot,
- .priv = hw->gg
- };
-
- GetAttr(SCROLLER_Top,hw->objects[OID_HSCROLL],(ULONG *)&xs);
- GetAttr(SCROLLER_Top,hw->objects[OID_VSCROLL],(ULONG *)&ys);
- if(ami_gui_get_space_box(hw->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
- }
+ nserror res;
-/* core should clear this area for us
- SetRPAttrs(glob->rp, RPTAG_APenColor, 0xffffffff, TAG_DONE);
- RectFill(glob->rp, 0, 0, bbox->Width - 1, bbox->Height - 1);
-*/
+ if (history_local_win == NULL) {
+ return NSERROR_OK;
+ }
- browser_window_history_redraw_rectangle(hw->gw->bw, xs, ys,
- bbox->Width + xs, bbox->Height + ys, 0, 0, &ctx);
+ res = local_history_fini(history_local_win->session);
+ if (res == NSERROR_OK) {
+ history_local_win->gw->hw = NULL;
+ res = ami_corewindow_fini(&history_local_win->core); /* closes the window for us */
+ history_local_window = NULL;
+ }
+ return res;
+}
- ami_clearclipreg(hw->gg);
- ami_history_update_extent(hw);
+/**
+ * callback for mouse action for local history on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_history_local_mouse(struct ami_corewindow *ami_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ struct ami_history_local_window *history_local_win;
+ /* technically degenerate container of */
+ history_local_win = (struct ami_history_local_window *)ami_cw;
+
+ nsurl *url;
+
+ if(local_history_get_url(history_local_win->session, x, y, &url) == NSERROR_OK) {
+ if (url == NULL) {
+ SetGadgetAttrs(
+ (struct Gadget *)ami_cw->objects[GID_CW_DRAW],
+ ami_cw->win,
+ NULL,
+ GA_HintInfo,
+ NULL,
+ TAG_DONE);
+ } else {
+ SetGadgetAttrs(
+ (struct Gadget *)ami_cw->objects[GID_CW_DRAW],
+ ami_cw->win,
+ NULL,
+ GA_HintInfo,
+ nsurl_access(url),
+ TAG_DONE);
+ nsurl_unref(url);
+ }
+ }
- BltBitMapRastPort(ami_plot_ra_get_bitmap(hw->gg), 0, 0, hw->win->RPort,
- bbox->Left, bbox->Top, bbox->Width, bbox->Height, 0x0C0);
+ local_history_mouse_action(history_local_win->session, mouse_state, x, y);
- ami_gui_free_space_box(bbox);
+ return NSERROR_OK;
}
-
-/* exported interface documented in amiga/history_local.h */
-void ami_history_open(struct gui_window *gw)
+/**
+ * callback for keypress for local history on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_history_local_key(struct ami_corewindow *ami_cw, uint32_t nskey)
{
- struct history *history;
- int width, height;
+ struct ami_history_local_window *history_local_win;
- if (gw->bw == NULL)
- return;
-
- history = browser_window_get_history(gw->bw);
- if (history == NULL)
- return;
-
- if(!gw->hw)
- {
- gw->hw = calloc(1, sizeof(struct history_window));
- gw->hw->gg = ami_plot_ra_alloc(scrn->Width, scrn->Height, false, true);
-
- gw->hw->gw = gw;
- browser_window_history_size(gw->bw, &width, &height);
-
- gw->hw->scrollerhook.h_Entry = (void *)ami_history_scroller_hook;
- gw->hw->scrollerhook.h_Data = gw->hw;
-
- gw->hw->objects[OID_MAIN] = WindowObj,
- WA_ScreenTitle, ami_gui_get_screen_title(),
- WA_Title, messages_get("History"),
- WA_Activate, TRUE,
- WA_DepthGadget, TRUE,
- WA_DragBar, TRUE,
- WA_CloseGadget, TRUE,
- WA_SizeGadget, TRUE,
- WA_PubScreen,scrn,
- WA_InnerWidth,width,
- WA_InnerHeight,height + 10,
- WINDOW_SharedPort,sport,
- WINDOW_UserData,gw->hw,
- WINDOW_IconifyGadget, FALSE,
- WINDOW_GadgetHelp, TRUE,
- WINDOW_Position, WPOS_CENTERSCREEN,
- WINDOW_HorizProp,1,
- WINDOW_VertProp,1,
- WINDOW_IDCMPHook,&gw->hw->scrollerhook,
- WINDOW_IDCMPHookBits,IDCMP_IDCMPUPDATE,
-// WA_ReportMouse,TRUE,
- WA_IDCMP,IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE, // | IDCMP_MOUSEMOVE,
- WINDOW_ParentGroup, gw->hw->objects[GID_MAIN] = LayoutVObj,
- LAYOUT_AddChild, gw->hw->objects[GID_BROWSER] = SpaceObj,
- GA_ID,GID_BROWSER,
-// SPACE_MinWidth,width,
-// SPACE_MinHeight,height,
- SpaceEnd,
- EndGroup,
- EndWindow;
-
- gw->hw->win = (struct Window *)RA_OpenWindow(gw->hw->objects[OID_MAIN]);
- ami_gui_win_list_add(gw->hw, AMINS_HISTORYWINDOW, &ami_localhistory_table);
-
- GetAttr(WINDOW_HorizObject,gw->hw->objects[OID_MAIN],(ULONG *)&gw->hw->objects[OID_HSCROLL]);
- GetAttr(WINDOW_VertObject,gw->hw->objects[OID_MAIN],(ULONG *)&gw->hw->objects[OID_VSCROLL]);
-
- RefreshSetGadgetAttrs((APTR)gw->hw->objects[OID_VSCROLL],gw->hw->win,NULL,
- GA_ID,OID_VSCROLL,
- SCROLLER_Top,0,
- ICA_TARGET,ICTARGET_IDCMP,
- TAG_DONE);
-
- RefreshSetGadgetAttrs((APTR)gw->hw->objects[OID_HSCROLL],gw->hw->win,NULL,
- GA_ID,OID_HSCROLL,
- SCROLLER_Top,0,
- ICA_TARGET,ICTARGET_IDCMP,
- TAG_DONE);
- }
+ /* technically degenerate container of */
+ history_local_win = (struct ami_history_local_window *)ami_cw;
- ami_history_redraw(gw->hw);
+ if (local_history_keypress(history_local_win->session, nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
}
-
/**
- * Handle mouse clicks in the history window.
+ * callback on draw event for certificate verify on core window
*
- * \return true if the event was handled, false to pass it on
+ * \param ami_cw The Amiga core window structure.
+ * \param x the x coordinate to draw
+ * \param y the y coordinate to draw
+ * \param r The rectangle of the window that needs updating.
+ * \param ctx The drawing context
+ * \return NSERROR_OK on success otherwise apropriate error code
*/
+static nserror
+ami_history_local_draw(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
+{
+ struct ami_history_local_window *history_local_win;
-static bool ami_history_click(struct history_window *hw, uint16 code)
+ /* technically degenerate container of */
+ history_local_win = (struct ami_history_local_window *)ami_cw;
+
+ //ctx->plot->clip(ctx, r); //??
+ local_history_redraw(history_local_win->session, x, y, r, ctx);
+
+ return NSERROR_OK;
+}
+
+static nserror
+ami_history_local_create_window(struct ami_history_local_window *history_local_win)
{
- int x, y;
- struct IBox *bbox;
- ULONG xs, ys;
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)&history_local_win->core;
+ ULONG refresh_mode = WA_SmartRefresh;
- if(ami_gui_get_space_box(hw->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return false;
+ if(nsoption_bool(window_simple_refresh) == true) {
+ refresh_mode = WA_SimpleRefresh;
}
- GetAttr(SCROLLER_Top,hw->objects[OID_HSCROLL],(ULONG *)&xs);
- x = hw->win->MouseX - bbox->Left +xs;
- GetAttr(SCROLLER_Top,hw->objects[OID_VSCROLL],(ULONG *)&ys);
- y = hw->win->MouseY - bbox->Top + ys;
-
- ami_gui_free_space_box(bbox);
-
- switch(code)
- {
- case SELECTUP:
- browser_window_history_click(hw->gw->bw, x, y, false);
- ami_history_redraw(hw);
- ami_schedule_redraw(hw->gw->shared, true);
- break;
-
- case MIDDLEUP:
- browser_window_history_click(hw->gw->bw, x, y, true);
- ami_history_redraw(hw);
- break;
+ ami_cw->objects[GID_CW_WIN] = WindowObj,
+ WA_ScreenTitle, ami_gui_get_screen_title(),
+ WA_Title, ami_cw->wintitle,
+ WA_Activate, TRUE,
+ WA_DepthGadget, TRUE,
+ WA_DragBar, TRUE,
+ WA_CloseGadget, TRUE,
+ WA_SizeGadget, TRUE,
+ WA_SizeBRight, TRUE,
+ WA_Width, 100,
+ WA_Height, 100,
+ WA_PubScreen, scrn,
+ WA_ReportMouse, TRUE,
+ refresh_mode, TRUE,
+ WA_IDCMP, IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
+ IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
+ IDCMP_EXTENDEDMOUSE | IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_IDCMPHook, &ami_cw->idcmp_hook,
+ WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_EXTENDEDMOUSE |
+ IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_SharedPort, sport,
+ WINDOW_HorizProp, 1,
+ WINDOW_VertProp, 1,
+ WINDOW_UserData, history_local_win,
+// WINDOW_MenuStrip, NULL,
+ WINDOW_MenuUserData, WGUD_HOOK,
+ WINDOW_IconifyGadget, FALSE,
+ WINDOW_Position, WPOS_CENTERSCREEN,
+ WINDOW_ParentGroup, ami_cw->objects[GID_CW_MAIN] = LayoutVObj,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_DRAW] = SpaceObj,
+ GA_ID, GID_CW_DRAW,
+ SPACE_Transparent, TRUE,
+ SPACE_BevelStyle, BVS_DISPLAY,
+ GA_RelVerify, TRUE,
+ SpaceEnd,
+ EndGroup,
+ EndWindow;
+
+ if(ami_cw->objects[GID_CW_WIN] == NULL) {
+ return NSERROR_NOMEM;
}
- return true;
+ return NSERROR_OK;
}
-void ami_history_close(struct history_window *hw)
+/* exported interface documented in amiga/history_local.h */
+nserror ami_history_local_present(struct gui_window *gw)
{
- ami_plot_ra_free(hw->gg);
- hw->gw->hw = NULL;
- DisposeObject(hw->objects[OID_MAIN]);
- ami_gui_win_list_remove(hw);
-}
+ struct ami_history_local_window *ncwin;
+ nserror res;
+ int width, height;
-static BOOL ami_history_event(void *w)
-{
- /* return TRUE if window destroyed */
- struct history_window *hw = (struct history_window *)w;
- ULONG result = 0;
- uint16 code;
- const char *url;
- struct IBox *bbox;
- ULONG xs, ys;
-
- while((result = RA_HandleInput(hw->objects[OID_MAIN],&code)) != WMHI_LASTMSG)
- {
- switch(result & WMHI_CLASSMASK) // class
- {
-/* no menus yet, copied in as will probably need it later
- case WMHI_MENUPICK:
- item = ItemAddress(gwin->win->MenuStrip,code);
- while (code != MENUNULL)
- {
- ami_menupick(code,gwin);
- if(win_destroyed) break;
- code = item->NextSelect;
- }
- break;
-*/
-
- case WMHI_MOUSEMOVE:
- GetAttr(SCROLLER_Top, hw->objects[OID_HSCROLL], (ULONG *)&xs);
- GetAttr(SCROLLER_Top, hw->objects[OID_VSCROLL], (ULONG *)&ys);
-
- if(ami_gui_get_space_box(hw->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- break;
- }
-
- url = browser_window_history_position_url(hw->gw->bw,
- hw->win->MouseX - bbox->Left + xs,
- hw->win->MouseY - bbox->Top + ys);
-
- ami_gui_free_space_box(bbox);
-
- RefreshSetGadgetAttrs((APTR)hw->objects[GID_BROWSER],
- hw->win, NULL,
- GA_HintInfo, url,
- TAG_DONE);
- break;
-
- case WMHI_NEWSIZE:
- ami_history_redraw(hw);
- break;
-
- case WMHI_MOUSEBUTTONS:
- ami_history_click(hw,code);
- break;
-
- case WMHI_CLOSEWINDOW:
- ami_history_close(hw);
- return TRUE;
- break;
+ if(history_local_window != NULL) {
+ //windowtofront()
+
+ if (gw->hw != NULL) {
+ res = local_history_set(gw->hw->session, gw->bw);
+ return res;
}
+
+ return NSERROR_OK;
}
- return FALSE;
-}
-static void ami_history_update_extent(struct history_window *hw)
-{
- struct IBox *bbox;
- int width, height;
+ ncwin = calloc(1, sizeof(struct ami_history_local_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
- browser_window_history_size(hw->gw->bw, &width, &height);
- if(ami_gui_get_space_box(hw->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
+ ncwin->core.wintitle = ami_utf8_easy((char *)messages_get("History"));
+
+ res = ami_history_local_create_window(ncwin);
+ if (res != NSERROR_OK) {
+ LOG("SSL UI builder init failed");
+ ami_utf8_free(ncwin->core.wintitle);
+ free(ncwin);
+ return res;
}
- RefreshSetGadgetAttrs((APTR)hw->objects[OID_VSCROLL], hw->win, NULL,
- GA_ID, OID_VSCROLL,
- SCROLLER_Total, height,
- SCROLLER_Visible, bbox->Height,
- ICA_TARGET, ICTARGET_IDCMP,
- TAG_DONE);
+ /* initialise Amiga core window */
+ ncwin->core.draw = ami_history_local_draw;
+ ncwin->core.key = ami_history_local_key;
+ ncwin->core.mouse = ami_history_local_mouse;
+ ncwin->core.close = ami_history_local_destroy;
+ ncwin->core.event = NULL;
+ ncwin->core.drag_end = NULL;
+ ncwin->core.icon_drop = NULL;
+
+ res = ami_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ res = local_history_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin,
+ gw->bw,
+ &ncwin->session);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ res = local_history_get_size(ncwin->session,
+ &width,
+ &height);
- RefreshSetGadgetAttrs((APTR)hw->objects[OID_HSCROLL], hw->win, NULL,
- GA_ID, OID_HSCROLL,
- SCROLLER_Total, width,
- SCROLLER_Visible, bbox->Width,
- ICA_TARGET, ICTARGET_IDCMP,
+ /*TODO: Adjust these to account for window borders */
+
+ SetAttrs(ncwin->core.objects[GID_CW_WIN],
+ WA_Width, width,
+ WA_Height, height,
TAG_DONE);
- ami_gui_free_space_box(bbox);
+ ncwin->gw = gw;
+ history_local_window = ncwin;
+ gw->hw = ncwin;
+
+ return NSERROR_OK;
}
-HOOKF(void, ami_history_scroller_hook, Object *, object, struct IntuiMessage *)
-{
- ULONG gid;
- struct history_window *hw = hook->h_Data;
-
- if (msg->Class == IDCMP_IDCMPUPDATE)
- {
- gid = GetTagData( GA_ID, 0, msg->IAddress );
-
- switch( gid )
- {
- case OID_HSCROLL:
- case OID_VSCROLL:
- ami_history_redraw(hw);
- break;
- }
- }
-// ReplyMsg((struct Message *)msg);
-}
diff --git a/frontends/amiga/history_local.h b/frontends/amiga/history_local.h
index 97aea05..72ba7fa 100755..100644
--- a/frontends/amiga/history_local.h
+++ b/frontends/amiga/history_local.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,23 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef AMIGA_HISTORY_LOCAL_H
-#define AMIGA_HISTORY_LOCAL_H
-
-#include <exec/types.h>
-#include <intuition/classusr.h>
+#ifndef AMIGA_HISTORY_GLOBAL_H
+#define AMIGA_HISTORY_GLOBAL_H
struct gui_window;
-struct gui_globals;
-struct history_window;
-
-/**
- * Open history window.
- *
- * \param gw gui_window to open history for
- */
-void ami_history_open(struct gui_window *gw);
+struct ami_history_local_window;
-void ami_history_close(struct history_window *hw);
+/** Open the global history viewer */
+nserror ami_history_local_present(struct gui_window *gw);
+nserror ami_history_local_destroy(struct ami_history_local_window *history_local_win);
#endif
diff --git a/frontends/amiga/os3support.c b/frontends/amiga/os3support.c
index 5c1e40d..6dc9579 100644
--- a/frontends/amiga/os3support.c
+++ b/frontends/amiga/os3support.c
@@ -338,7 +338,7 @@ int64 GetFileSize(BPTR fh)
ExamineFH(fh, fib);
size = fib->fib_Size;
- free(fib);
+ FreeDosObject(DOS_FIB, fib);
return (int64)size;
}
diff --git a/frontends/framebuffer/Makefile b/frontends/framebuffer/Makefile
index 6d2acb0..760e85b 100644
--- a/frontends/framebuffer/Makefile
+++ b/frontends/framebuffer/Makefile
@@ -146,7 +146,7 @@ $(eval $(foreach V,$(filter FB_FONT_$(NETSURF_FB_FONTLIB)_%,$(.VARIABLES)),$(cal
# S_FRONTEND are sources purely for the framebuffer build
S_FRONTEND := gui.c framebuffer.c schedule.c bitmap.c fetch.c \
- findfile.c localhistory.c clipboard.c
+ findfile.c corewindow.c local_history.c clipboard.c
# toolkit sources
S_FRAMEBUFFER_FBTK := fbtk.c event.c fill.c bitmap.c user.c window.c \
diff --git a/frontends/framebuffer/corewindow.c b/frontends/framebuffer/corewindow.c
new file mode 100644
index 0000000..93f88ff
--- a/dev/null
+++ b/frontends/framebuffer/corewindow.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * framebuffer generic core window interface.
+ *
+ * Provides interface for core renderers to the framebufefr toolkit
+ * drawable area.
+ *
+ * This module is an object that must be encapsulated. Client users
+ * should embed a struct fb_corewindow at the beginning of their
+ * context for this display surface, fill in relevant data and then
+ * call fb_corewindow_init()
+ *
+ * The fb core window structure requires the callback for draw, key and
+ * mouse operations.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+#include <libnsfb_event.h>
+
+#include "utils/log.h"
+#include "utils/utils.h"
+#include "utils/messages.h"
+#include "utils/utf8.h"
+#include "utils/nsoption.h"
+#include "netsurf/keypress.h"
+#include "netsurf/mouse.h"
+#include "netsurf/plot_style.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/corewindow.h"
+
+
+/* toolkit event handlers that do generic things and call internal callbacks */
+
+
+static int
+fb_cw_mouse_press_event(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ struct fb_corewindow *fb_cw = (struct fb_corewindow *)cbi->context;
+ browser_mouse_state state;
+
+ /** \todo frambuffer corewindow mouse event handling needs improving */
+ if (cbi->event->type != NSFB_EVENT_KEY_UP) {
+ state = BROWSER_MOUSE_HOVER;
+ } else {
+ state = BROWSER_MOUSE_PRESS_1;
+ }
+
+ fb_cw->mouse(fb_cw, state, cbi->x, cbi->y);
+
+ return 1;
+}
+
+/*
+static bool
+fb_cw_input_event(toolkit_widget *widget, void *ctx)
+{
+ struct fb_corewindow *fb_cw = (struct fb_corewindow *)ctx;
+
+ fb_cw->key(fb_cw, keycode);
+
+ return true;
+}
+*/
+
+/**
+ * handler for toolkit window redraw event
+ */
+static int fb_cw_draw_event(fbtk_widget_t *widget, fbtk_callback_info *cbi)
+{
+ struct fb_corewindow *fb_cw;
+ nsfb_bbox_t rbox;
+ struct rect clip;
+
+ fb_cw = (struct fb_corewindow *)cbi->context;
+
+ rbox.x0 = fbtk_get_absx(widget);
+ rbox.y0 = fbtk_get_absy(widget);
+
+ rbox.x1 = rbox.x0 + fbtk_get_width(widget);
+ rbox.y1 = rbox.y0 + fbtk_get_height(widget);
+
+ nsfb_claim(fbtk_get_nsfb(widget), &rbox);
+
+ clip.x0 = fb_cw->scrollx;
+ clip.y0 = fb_cw->scrolly;
+ clip.x1 = fbtk_get_width(widget) + fb_cw->scrollx;
+ clip.y1 = fbtk_get_height(widget) + fb_cw->scrolly;
+
+ fb_cw->draw(fb_cw, &clip);
+
+ nsfb_update(fbtk_get_nsfb(widget), &rbox);
+
+ return 0;
+}
+
+
+/**
+ * callback from core to request a redraw
+ */
+static nserror
+fb_cw_invalidate(struct core_window *cw, const struct rect *r)
+{
+/* struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw;
+
+ toolkit_widget_queue_draw_area(fb_cw->widget,
+ r->x0, r->y0,
+ r->x1 - r->x0, r->y1 - r->y0);
+*/
+ return NSERROR_OK;
+}
+
+
+static void
+fb_cw_update_size(struct core_window *cw, int width, int height)
+{
+/* struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw;
+
+ toolkit_widget_set_size_request(FB_WIDGET(fb_cw->drawing_area),
+ width, height);
+*/
+}
+
+
+static void
+fb_cw_scroll_visible(struct core_window *cw, const struct rect *r)
+{
+/* struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw;
+
+ toolkit_scroll_widget(fb_cw->widget, r);
+*/
+}
+
+
+static void
+fb_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
+{
+ struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw;
+
+ *width = fbtk_get_width(fb_cw->drawable);
+ *height = fbtk_get_height(fb_cw->drawable);
+}
+
+
+static void
+fb_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
+{
+ struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw;
+ fb_cw->drag_status = ds;
+}
+
+
+struct core_window_callback_table fb_cw_cb_table = {
+ .invalidate = fb_cw_invalidate,
+ .update_size = fb_cw_update_size,
+ .scroll_visible = fb_cw_scroll_visible,
+ .get_window_dimensions = fb_cw_get_window_dimensions,
+ .drag_status = fb_cw_drag_status
+};
+
+/* exported function documented fb/corewindow.h */
+nserror fb_corewindow_init(fbtk_widget_t *parent, struct fb_corewindow *fb_cw)
+{
+ int furniture_width;
+
+ furniture_width = nsoption_int(fb_furniture_size);
+
+ /* setup the core window callback table */
+ fb_cw->cb_table = &fb_cw_cb_table;
+ fb_cw->drag_status = CORE_WINDOW_DRAG_NONE;
+
+ /* container window */
+ fb_cw->wnd = fbtk_create_window(parent, 0, 0, 0, 0, 0);
+
+ fb_cw->drawable = fbtk_create_user(fb_cw->wnd,
+ 0, 0,
+ -furniture_width, -furniture_width,
+ fb_cw);
+
+ fbtk_set_handler(fb_cw->drawable,
+ FBTK_CBT_REDRAW,
+ fb_cw_draw_event,
+ fb_cw);
+
+ fbtk_set_handler(fb_cw->drawable,
+ FBTK_CBT_CLICK,
+ fb_cw_mouse_press_event,
+ fb_cw);
+/*
+ fbtk_set_handler(fb_cw->drawable,
+ FBTK_CBT_INPUT,
+ fb_cw_input_event,
+ fb_cw);
+
+ fbtk_set_handler(fb_cw->drawable,
+ FBTK_CBT_POINTERMOVE,
+ fb_cw_move_event,
+ fb_cw);
+*/
+
+ /* create horizontal scrollbar */
+ fb_cw->hscroll = fbtk_create_hscroll(fb_cw->wnd,
+ 0,
+ fbtk_get_height(fb_cw->wnd) - furniture_width,
+ fbtk_get_width(fb_cw->wnd) - furniture_width,
+ furniture_width,
+ FB_SCROLL_COLOUR,
+ FB_FRAME_COLOUR,
+ NULL,
+ NULL);
+
+ fb_cw->vscroll = fbtk_create_vscroll(fb_cw->wnd,
+ fbtk_get_width(fb_cw->wnd) - furniture_width,
+ 0,
+ furniture_width,
+ fbtk_get_height(fb_cw->wnd) - furniture_width,
+ FB_SCROLL_COLOUR,
+ FB_FRAME_COLOUR,
+ NULL,
+ NULL);
+
+ fbtk_create_fill(fb_cw->wnd,
+ fbtk_get_width(fb_cw->wnd) - furniture_width,
+ fbtk_get_height(fb_cw->wnd) - furniture_width,
+ furniture_width,
+ furniture_width,
+ FB_FRAME_COLOUR);
+
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in fb/corewindow.h */
+nserror fb_corewindow_fini(struct fb_corewindow *fb_cw)
+{
+ return NSERROR_OK;
+}
diff --git a/frontends/framebuffer/corewindow.h b/frontends/framebuffer/corewindow.h
new file mode 100644
index 0000000..5546c09
--- a/dev/null
+++ b/frontends/framebuffer/corewindow.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef FB_COREWINDOW_H
+#define FB_COREWINDOW_H
+
+#include "netsurf/core_window.h"
+
+/**
+ * fb core window state
+ */
+struct fb_corewindow {
+
+ /**
+ * framebuffer toolkit window.
+ */
+ struct fbtk_widget_s *wnd;
+ /**
+ * framebuffer toolkit horizontal scrollbar.
+ */
+ struct fbtk_widget_s *hscroll;
+ /**
+ * framebuffer toolkit vertical scrollbar.
+ */
+ struct fbtk_widget_s *vscroll;
+ /**
+ * framebuffer toolkit user drawable widget.
+ */
+ struct fbtk_widget_s *drawable;
+
+ int scrollx, scrolly; /**< scroll offsets. */
+
+
+ /** drag status set by core */
+ core_window_drag_status drag_status;
+
+ /** table of callbacks for core window operations */
+ struct core_window_callback_table *cb_table;
+
+ /**
+ * callback to draw on drawable area of fb core window
+ *
+ * \param fb_cw The fb core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ nserror (*draw)(struct fb_corewindow *fb_cw, struct rect *r);
+
+ /**
+ * callback for keypress on fb core window
+ *
+ * \param fb_cw The fb core window structure.
+ * \param nskey The netsurf key code.
+ * \return NSERROR_OK if key processed,
+ * NSERROR_NOT_IMPLEMENTED if key not processed
+ * otherwise apropriate error code
+ */
+ nserror (*key)(struct fb_corewindow *fb_cw, uint32_t nskey);
+
+ /**
+ * callback for mouse event on fb core window
+ *
+ * \param fb_cw The fb core window structure.
+ * \param mouse_state mouse state
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on sucess otherwise apropriate error code.
+ */
+ nserror (*mouse)(struct fb_corewindow *fb_cw, browser_mouse_state mouse_state, int x, int y);
+};
+
+
+/**
+ * initialise elements of fb core window.
+ *
+ * As a pre-requisite the draw, key and mouse callbacks must be defined
+ *
+ * \param fb_cw A fb core window structure to initialise
+ * \return NSERROR_OK on successful initialisation otherwise error code.
+ */
+nserror fb_corewindow_init(fbtk_widget_t *parent, struct fb_corewindow *fb_cw);
+
+
+/**
+ * finalise elements of fb core window.
+ *
+ * \param fb_cw A fb core window structure to initialise
+ * \return NSERROR_OK on successful finalisation otherwise error code.
+ */
+nserror fb_corewindow_fini(struct fb_corewindow *fb_cw);
+
+#endif
diff --git a/frontends/framebuffer/framebuffer.c b/frontends/framebuffer/framebuffer.c
index 649862a..de8a369 100644
--- a/frontends/framebuffer/framebuffer.c
+++ b/frontends/framebuffer/framebuffer.c
@@ -333,7 +333,10 @@ framebuffer_plot_bitmap(const struct redraw_context *ctx,
loc.x1 = loc.x0 + width;
loc.y1 = loc.y0 + height;
- return nsfb_plot_copy(bm, NULL, nsfb, &loc);
+ if (!nsfb_plot_copy(bm, NULL, nsfb, &loc)) {
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
}
nsfb_plot_get_clip(nsfb, &clipbox);
diff --git a/frontends/framebuffer/gui.c b/frontends/framebuffer/gui.c
index 062cb56..1460c77 100644
--- a/frontends/framebuffer/gui.c
+++ b/frontends/framebuffer/gui.c
@@ -54,6 +54,7 @@
#include "framebuffer/clipboard.h"
#include "framebuffer/fetch.h"
#include "framebuffer/bitmap.h"
+#include "framebuffer/local_history.h"
#define NSFB_TOOLBAR_DEFAULT_LAYOUT "blfsrutc"
@@ -1150,7 +1151,7 @@ fb_localhistory_btn_clik(fbtk_widget_t *widget, fbtk_callback_info *cbi)
if (cbi->event->type != NSFB_EVENT_KEY_UP)
return 0;
- fb_localhistory_map(gw->localhistory);
+ fb_local_history_present(fbtk, gw->bw);
return 0;
}
@@ -1782,7 +1783,6 @@ gui_window_create(struct browser_window *bw,
gw->bw = bw;
create_normal_browser_window(gw, nsoption_int(fb_furniture_size));
- gw->localhistory = fb_create_localhistory(bw, fbtk, nsoption_int(fb_furniture_size));
/* map and request redraw of gui window */
fbtk_set_mapping(gw->window, true);
diff --git a/frontends/framebuffer/gui.h b/frontends/framebuffer/gui.h
index 0de1add..abb27c4 100644
--- a/frontends/framebuffer/gui.h
+++ b/frontends/framebuffer/gui.h
@@ -27,17 +27,6 @@ typedef struct fb_cursor_s fb_cursor_t;
/* bounding box */
typedef struct nsfb_bbox_s bbox_t;
-struct gui_localhistory {
- struct browser_window *bw;
-
- struct fbtk_widget_s *window;
- struct fbtk_widget_s *hscroll;
- struct fbtk_widget_s *vscroll;
- struct fbtk_widget_s *history;
-
- int scrollx, scrolly; /**< scroll offsets. */
-};
-
struct gui_window {
struct browser_window *bw;
@@ -59,8 +48,6 @@ struct gui_window {
int throbber_index;
- struct gui_localhistory *localhistory;
-
struct gui_window *next;
struct gui_window *prev;
};
@@ -68,13 +55,8 @@ struct gui_window {
extern struct gui_window *window_list;
-struct gui_localhistory *fb_create_localhistory(struct browser_window *bw,
- struct fbtk_widget_s *parent, int furniture_width);
-void fb_localhistory_map(struct gui_localhistory * glh);
-
void gui_resize(struct fbtk_widget_s *root, int width, int height);
-
#endif /* NETSURF_FB_GUI_H */
/*
diff --git a/frontends/framebuffer/local_history.c b/frontends/framebuffer/local_history.c
new file mode 100644
index 0000000..cc45b1f
--- a/dev/null
+++ b/frontends/framebuffer/local_history.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Implementation of framebuffer local history manager.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include <libnsfb.h>
+#include <libnsfb_plot.h>
+#include <libnsfb_event.h>
+
+#include "utils/log.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
+#include "desktop/local_history.h"
+
+#include "framebuffer/gui.h"
+#include "framebuffer/fbtk.h"
+#include "framebuffer/framebuffer.h"
+#include "framebuffer/corewindow.h"
+#include "framebuffer/local_history.h"
+
+struct fb_local_history_window {
+ struct fb_corewindow core;
+
+ struct local_history_session *session;
+};
+
+static struct fb_local_history_window *local_history_window = NULL;
+
+
+/**
+ * callback for mouse action on local history window
+ *
+ * \param fb_cw The fb core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+fb_local_history_mouse(struct fb_corewindow *fb_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ struct fb_local_history_window *lhw;
+ /* technically degenerate container of */
+ lhw = (struct fb_local_history_window *)fb_cw;
+
+ local_history_mouse_action(lhw->session, mouse_state, x, y);
+
+ if (mouse_state != BROWSER_MOUSE_HOVER) {
+ fbtk_set_mapping(lhw->core.wnd, false);
+ }
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * callback for keypress on local history window
+ *
+ * \param fb_cw The fb core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+fb_local_history_key(struct fb_corewindow *fb_cw, uint32_t nskey)
+{
+ struct fb_local_history_window *lhw;
+ /* technically degenerate container of */
+ lhw = (struct fb_local_history_window *)fb_cw;
+
+ if (local_history_keypress(lhw->session, nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * callback on draw event for local history window
+ *
+ * \param fb_cw The fb core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+fb_local_history_draw(struct fb_corewindow *fb_cw, struct rect *r)
+{
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &fb_plotters
+ };
+ struct fb_local_history_window *lhw;
+
+ /* technically degenerate container of */
+ lhw = (struct fb_local_history_window *)fb_cw;
+
+ local_history_redraw(lhw->session, 0, 0, r, &ctx);
+
+ return NSERROR_OK;
+}
+
+/**
+ * Creates the window for the local history view.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror
+fb_local_history_init(fbtk_widget_t *parent,
+ struct browser_window *bw,
+ struct fb_local_history_window **win_out)
+{
+ struct fb_local_history_window *ncwin;
+ nserror res;
+
+ /* memoise window so it can be represented when necessary
+ * instead of recreating every time.
+ */
+ if ((*win_out) != NULL) {
+ res = local_history_set((*win_out)->session, bw);
+ return res;
+ }
+
+ ncwin = calloc(1, sizeof(*ncwin));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ ncwin->core.draw = fb_local_history_draw;
+ ncwin->core.key = fb_local_history_key;
+ ncwin->core.mouse = fb_local_history_mouse;
+
+ res = fb_corewindow_init(parent, &ncwin->core);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ res = local_history_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin,
+ bw,
+ &ncwin->session);
+ if (res != NSERROR_OK) {
+ free(ncwin);
+ return res;
+ }
+
+ *win_out = ncwin;
+
+ return NSERROR_OK;
+}
+
+
+/* exported function documented gtk/history.h */
+nserror fb_local_history_present(fbtk_widget_t *parent,
+ struct browser_window *bw)
+{
+ nserror res;
+ int prnt_width, prnt_height;
+ int width, height;
+
+ res = fb_local_history_init(parent, bw, &local_history_window);
+ if (res == NSERROR_OK) {
+
+ prnt_width = fbtk_get_width(parent);
+ prnt_height = fbtk_get_height(parent);
+
+ /* resize history widget ensureing the drawing area is
+ * no larger than parent window
+ */
+ res = local_history_get_size(local_history_window->session,
+ &width,
+ &height);
+ if (width > prnt_width) {
+ width = prnt_width;
+ }
+ if (height > prnt_height) {
+ height = prnt_height;
+ }
+ /* should update scroll area with contents */
+
+ fbtk_set_zorder(local_history_window->core.wnd, INT_MIN);
+ fbtk_set_mapping(local_history_window->core.wnd, true);
+ }
+
+ return res;
+}
+
+
+/* exported function documented gtk/history.h */
+nserror fb_local_history_hide(void)
+{
+ nserror res = NSERROR_OK;
+
+ if (local_history_window != NULL) {
+ fbtk_set_mapping(local_history_window->core.wnd, false);
+
+ res = local_history_set(local_history_window->session, NULL);
+ }
+
+ return res;
+}
+
+
+/* exported function documented gtk/history.h */
+nserror fb_local_history_destroy(void)
+{
+ nserror res;
+
+ if (local_history_window == NULL) {
+ return NSERROR_OK;
+ }
+
+ res = local_history_fini(local_history_window->session);
+ if (res == NSERROR_OK) {
+ res = fb_corewindow_fini(&local_history_window->core);
+ //gtk_widget_destroy(GTK_WIDGET(local_history_window->wnd));
+ free(local_history_window);
+ local_history_window = NULL;
+ }
+
+ return res;
+
+}
diff --git a/frontends/framebuffer/local_history.h b/frontends/framebuffer/local_history.h
new file mode 100644
index 0000000..929eeac
--- a/dev/null
+++ b/frontends/framebuffer/local_history.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Interface to framebuffer local history manager
+ */
+
+#ifndef FB_LOCAL_HISTORY_H
+#define FB_LOCAL_HISTORY_H
+
+struct browser_window;
+
+/**
+ * make the local history window visible.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+nserror fb_local_history_present(fbtk_widget_t *parent, struct browser_window *bw);
+
+/**
+ * hide the local history window from being visible.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+nserror fb_local_history_hide(void);
+
+/**
+ * Destroys the local history window and performs any other necessary cleanup
+ * actions.
+ */
+nserror fb_local_history_destroy(void);
+
+#endif
diff --git a/frontends/framebuffer/localhistory.c b/frontends/framebuffer/localhistory.c
deleted file mode 100644
index 3192f07..0000000
--- a/frontends/framebuffer/localhistory.c
+++ b/dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <limits.h>
-
-#include <libnsfb.h>
-#include <libnsfb_plot.h>
-#include <libnsfb_event.h>
-
-#include "desktop/browser_history.h"
-#include "netsurf/plotters.h"
-
-#include "framebuffer/gui.h"
-#include "framebuffer/fbtk.h"
-#include "framebuffer/framebuffer.h"
-
-static int
-localhistory_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- struct gui_localhistory *glh = cbi->context;
- nsfb_bbox_t rbox;
-
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &fb_plotters
- };
-
- rbox.x0 = fbtk_get_absx(widget);
- rbox.y0 = fbtk_get_absy(widget);
-
- rbox.x1 = rbox.x0 + fbtk_get_width(widget);
- rbox.y1 = rbox.y0 + fbtk_get_height(widget);
-
- nsfb_claim(fbtk_get_nsfb(widget), &rbox);
-
- nsfb_plot_rectangle_fill(fbtk_get_nsfb(widget), &rbox, 0xffffffff);
-
- browser_window_history_redraw_rectangle(glh->bw,
- glh->scrollx,
- glh->scrolly,
- fbtk_get_width(widget) + glh->scrollx,
- fbtk_get_height(widget) + glh->scrolly,
- 0, 0, &ctx);
-
- nsfb_update(fbtk_get_nsfb(widget), &rbox);
-
- return 0;
-}
-
-static int
-localhistory_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
-{
- struct gui_localhistory *glh = cbi->context;
-
- if (cbi->event->type != NSFB_EVENT_KEY_UP)
- return 0;
-
- browser_window_history_click(glh->bw, cbi->x, cbi->y, false);
-
- fbtk_set_mapping(glh->window, false);
-
- return 1;
-}
-
-struct gui_localhistory *
-fb_create_localhistory(struct browser_window *bw,
- fbtk_widget_t *parent,
- int furniture_width)
-{
- struct gui_localhistory *glh;
- glh = calloc(1, sizeof(struct gui_localhistory));
-
- if (glh == NULL)
- return NULL;
-
- glh->bw = bw;
-
- /* container window */
- glh->window = fbtk_create_window(parent, 0, 0, 0, 0, 0);
-
- glh->history = fbtk_create_user(glh->window, 0, 0, -furniture_width, -furniture_width, glh);
-
- fbtk_set_handler(glh->history, FBTK_CBT_REDRAW, localhistory_redraw, glh);
- fbtk_set_handler(glh->history, FBTK_CBT_CLICK, localhistory_click, glh);
- /*
- fbtk_set_handler(gw->localhistory, FBTK_CBT_INPUT, fb_browser_window_input, gw);
- fbtk_set_handler(gw->localhistory, FBTK_CBT_POINTERMOVE, fb_browser_window_move, bw);
- */
-
- /* create horizontal scrollbar */
- glh->hscroll = fbtk_create_hscroll(glh->window,
- 0,
- fbtk_get_height(glh->window) - furniture_width,
- fbtk_get_width(glh->window) - furniture_width,
- furniture_width,
- FB_SCROLL_COLOUR,
- FB_FRAME_COLOUR,
- NULL,
- NULL);
-
- glh->vscroll = fbtk_create_vscroll(glh->window,
- fbtk_get_width(glh->window) - furniture_width,
- 0,
- furniture_width,
- fbtk_get_height(glh->window) - furniture_width,
- FB_SCROLL_COLOUR,
- FB_FRAME_COLOUR,
- NULL,
- NULL);
-
- fbtk_create_fill(glh->window,
- fbtk_get_width(glh->window) - furniture_width,
- fbtk_get_height(glh->window) - furniture_width,
- furniture_width,
- furniture_width,
- FB_FRAME_COLOUR);
-
- return glh;
-}
-
-void
-fb_localhistory_map(struct gui_localhistory * glh)
-{
- fbtk_set_zorder(glh->window, INT_MIN);
- fbtk_set_mapping(glh->window, true);
-}
diff --git a/frontends/gtk/bitmap.c b/frontends/gtk/bitmap.c
index b428142..36b614c 100644
--- a/frontends/gtk/bitmap.c
+++ b/frontends/gtk/bitmap.c
@@ -18,9 +18,9 @@
/**
* \file
- * Generic bitmap handling (GDK / GTK+ implementation).
+ * GTK bitmap handling.
*
- * This implements the interface given by desktop/bitmap.h using GdkPixbufs.
+ * This implements the bitmap interface using cairo image surfaces
*/
#include <assert.h>
diff --git a/frontends/gtk/cookies.c b/frontends/gtk/cookies.c
index dc77e1c..500cd07 100644
--- a/frontends/gtk/cookies.c
+++ b/frontends/gtk/cookies.c
@@ -246,7 +246,7 @@ static nserror nsgtk_cookies_init(void)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct nsgtk_cookie_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/gtk/corewindow.c b/frontends/gtk/corewindow.c
index 9ad644d..ddc61c7 100644
--- a/frontends/gtk/corewindow.c
+++ b/frontends/gtk/corewindow.c
@@ -662,7 +662,7 @@ static void
nsgtk_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
{
struct nsgtk_corewindow *nsgtk_cw = (struct nsgtk_corewindow *)cw;
- nsgtk_cw->drag_staus = ds;
+ nsgtk_cw->drag_status = ds;
}
@@ -682,6 +682,7 @@ static struct core_window_callback_table nsgtk_cw_cb_table = {
nserror nsgtk_corewindow_init(struct nsgtk_corewindow *nsgtk_cw)
{
nsgtk_cw->cb_table = &nsgtk_cw_cb_table;
+ nsgtk_cw->drag_status = CORE_WINDOW_DRAG_NONE;
/* input method setup */
nsgtk_cw->input_method = gtk_im_multicontext_new();
diff --git a/frontends/gtk/corewindow.h b/frontends/gtk/corewindow.h
index 90bfd61..6100e67 100644
--- a/frontends/gtk/corewindow.h
+++ b/frontends/gtk/corewindow.h
@@ -51,7 +51,7 @@ struct nsgtk_corewindow {
/** mouse state */
struct nsgtk_corewindow_mouse mouse_state;
/** drag status set by core */
- core_window_drag_status drag_staus;
+ core_window_drag_status drag_status;
/**
* callback to draw on drawable area of nsgtk core window
diff --git a/frontends/gtk/global_history.c b/frontends/gtk/global_history.c
index 66ba1a6..360eb4e 100644
--- a/frontends/gtk/global_history.c
+++ b/frontends/gtk/global_history.c
@@ -299,7 +299,7 @@ static nserror nsgtk_global_history_init(void)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct nsgtk_global_history_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/gtk/hotlist.c b/frontends/gtk/hotlist.c
index 34a1377..936573a 100644
--- a/frontends/gtk/hotlist.c
+++ b/frontends/gtk/hotlist.c
@@ -319,7 +319,7 @@ static nserror nsgtk_hotlist_init(void)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct nsgtk_hotlist_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/gtk/local_history.c b/frontends/gtk/local_history.c
index 650cb4f..cc95801 100644
--- a/frontends/gtk/local_history.c
+++ b/frontends/gtk/local_history.c
@@ -116,7 +116,7 @@ nsgtk_local_history_draw(struct nsgtk_corewindow *nsgtk_cw, struct rect *r)
lhw = (struct nsgtk_local_history_window *)nsgtk_cw;
ctx.plot->clip(&ctx, r);
- local_history_redraw(lhw->session, r->x0, r->y0, r, &ctx);
+ local_history_redraw(lhw->session, 0, 0, r, &ctx);
return NSERROR_OK;
}
@@ -141,7 +141,7 @@ nsgtk_local_history_init(struct browser_window *bw,
return res;
}
- ncwin = malloc(sizeof(struct nsgtk_local_history_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/gtk/window.c b/frontends/gtk/window.c
index 78a6f62..de5311e 100644
--- a/frontends/gtk/window.c
+++ b/frontends/gtk/window.c
@@ -1048,7 +1048,7 @@ static void gui_window_set_status(struct gui_window *g, const char *text)
* content is shown. The GTK implementation scrolls the contents so
* the specified point in the content is at the top of the viewport.
*
- * \param gw gui window to scroll
+ * \param g gui window to scroll
* \param rect The rectangle to ensure is shown.
* \return NSERROR_OK on success or apropriate error code.
*/
diff --git a/frontends/monkey/401login.c b/frontends/monkey/401login.c
index 8b4d33d..090f189 100644
--- a/frontends/monkey/401login.c
+++ b/frontends/monkey/401login.c
@@ -24,11 +24,11 @@
#include "monkey/401login.h"
typedef struct monkey401 {
- struct monkey401 *r_next, *r_prev;
- uint32_t num;
- lwc_string *host; /* Ignore */
- nserror (*cb)(bool,void*);
- void *pw;
+ struct monkey401 *r_next, *r_prev;
+ uint32_t num;
+ lwc_string *host; /* Ignore */
+ nserror (*cb)(bool,void*);
+ void *pw;
} monkey401_t;
static monkey401_t *m4_ring = NULL;
@@ -37,19 +37,19 @@ static uint32_t m4_ctr = 0;
void gui_401login_open(nsurl *url, const char *realm,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
- monkey401_t *m4t = calloc(sizeof(*m4t), 1);
- if (m4t == NULL) {
- cb(false, cbpw);
- return;
- }
- m4t->cb = cb;
- m4t->pw = cbpw;
- m4t->num = m4_ctr++;
+ monkey401_t *m4t = calloc(sizeof(*m4t), 1);
+ if (m4t == NULL) {
+ cb(false, cbpw);
+ return;
+ }
+ m4t->cb = cb;
+ m4t->pw = cbpw;
+ m4t->num = m4_ctr++;
- RING_INSERT(m4_ring, m4t);
+ RING_INSERT(m4_ring, m4t);
- fprintf(stdout, "401LOGIN OPEN M4 %u URL %s REALM %s\n",
- m4t->num, nsurl_access(url), realm);
+ fprintf(stdout, "401LOGIN OPEN M4 %u URL %s REALM %s\n",
+ m4t->num, nsurl_access(url), realm);
}
diff --git a/frontends/monkey/bitmap.c b/frontends/monkey/bitmap.c
index 3313e11..83b8566 100644
--- a/frontends/monkey/bitmap.c
+++ b/frontends/monkey/bitmap.c
@@ -26,125 +26,125 @@
#include "monkey/bitmap.h"
struct bitmap {
- void *ptr;
- size_t rowstride;
- int width;
- int height;
- unsigned int state;
+ void *ptr;
+ size_t rowstride;
+ int width;
+ int height;
+ unsigned int state;
};
static void *bitmap_create(int width, int height, unsigned int state)
{
- struct bitmap *ret = calloc(sizeof(*ret), 1);
- if (ret == NULL)
- return NULL;
+ struct bitmap *ret = calloc(sizeof(*ret), 1);
+ if (ret == NULL)
+ return NULL;
- ret->width = width;
- ret->height = height;
- ret->state = state;
+ ret->width = width;
+ ret->height = height;
+ ret->state = state;
- ret->ptr = calloc(width, height * 4);
+ ret->ptr = calloc(width, height * 4);
- if (ret->ptr == NULL) {
- free(ret);
- return NULL;
- }
+ if (ret->ptr == NULL) {
+ free(ret);
+ return NULL;
+ }
- return ret;
+ return ret;
}
static void bitmap_destroy(void *bitmap)
{
- struct bitmap *bmap = bitmap;
- free(bmap->ptr);
- free(bmap);
+ struct bitmap *bmap = bitmap;
+ free(bmap->ptr);
+ free(bmap);
}
static void bitmap_set_opaque(void *bitmap, bool opaque)
{
- struct bitmap *bmap = bitmap;
+ struct bitmap *bmap = bitmap;
- if (opaque)
- bmap->state |= (BITMAP_OPAQUE);
- else
- bmap->state &= ~(BITMAP_OPAQUE);
+ if (opaque)
+ bmap->state |= (BITMAP_OPAQUE);
+ else
+ bmap->state &= ~(BITMAP_OPAQUE);
}
static bool bitmap_test_opaque(void *bitmap)
{
- return false;
+ return false;
}
static bool bitmap_get_opaque(void *bitmap)
{
- struct bitmap *bmap = bitmap;
+ struct bitmap *bmap = bitmap;
- return (bmap->state & BITMAP_OPAQUE) == BITMAP_OPAQUE;
+ return (bmap->state & BITMAP_OPAQUE) == BITMAP_OPAQUE;
}
static unsigned char *bitmap_get_buffer(void *bitmap)
{
- struct bitmap *bmap = bitmap;
+ struct bitmap *bmap = bitmap;
- return (unsigned char *)(bmap->ptr);
+ return (unsigned char *)(bmap->ptr);
}
static size_t bitmap_get_rowstride(void *bitmap)
{
- struct bitmap *bmap = bitmap;
- return bmap->width * 4;
+ struct bitmap *bmap = bitmap;
+ return bmap->width * 4;
}
static size_t bitmap_get_bpp(void *bitmap)
{
- /* OMG?! */
- return 4;
+ /* OMG?! */
+ return 4;
}
static bool bitmap_save(void *bitmap, const char *path, unsigned flags)
{
- return true;
+ return true;
}
static void bitmap_modified(void *bitmap)
{
- struct bitmap *bmap = bitmap;
- bmap->state |= BITMAP_MODIFIED;
+ struct bitmap *bmap = bitmap;
+ bmap->state |= BITMAP_MODIFIED;
}
static int bitmap_get_width(void *bitmap)
{
- struct bitmap *bmap = bitmap;
- return bmap->width;
+ struct bitmap *bmap = bitmap;
+ return bmap->width;
}
static int bitmap_get_height(void *bitmap)
{
- struct bitmap *bmap = bitmap;
- return bmap->height;
+ struct bitmap *bmap = bitmap;
+ return bmap->height;
}
static nserror bitmap_render(struct bitmap *bitmap,
struct hlcache_handle *content)
{
- fprintf(stdout, "GENERIC BITMAP RENDER\n");
- return NSERROR_OK;
+ fprintf(stdout, "GENERIC BITMAP RENDER\n");
+ return NSERROR_OK;
}
static struct gui_bitmap_table bitmap_table = {
- .create = bitmap_create,
- .destroy = bitmap_destroy,
- .set_opaque = bitmap_set_opaque,
- .get_opaque = bitmap_get_opaque,
- .test_opaque = bitmap_test_opaque,
- .get_buffer = bitmap_get_buffer,
- .get_rowstride = bitmap_get_rowstride,
- .get_width = bitmap_get_width,
- .get_height = bitmap_get_height,
- .get_bpp = bitmap_get_bpp,
- .save = bitmap_save,
- .modified = bitmap_modified,
- .render = bitmap_render,
+ .create = bitmap_create,
+ .destroy = bitmap_destroy,
+ .set_opaque = bitmap_set_opaque,
+ .get_opaque = bitmap_get_opaque,
+ .test_opaque = bitmap_test_opaque,
+ .get_buffer = bitmap_get_buffer,
+ .get_rowstride = bitmap_get_rowstride,
+ .get_width = bitmap_get_width,
+ .get_height = bitmap_get_height,
+ .get_bpp = bitmap_get_bpp,
+ .save = bitmap_save,
+ .modified = bitmap_modified,
+ .render = bitmap_render,
};
struct gui_bitmap_table *monkey_bitmap_table = &bitmap_table;
diff --git a/frontends/monkey/browser.c b/frontends/monkey/browser.c
index 93360aa..16d3301 100644
--- a/frontends/monkey/browser.c
+++ b/frontends/monkey/browser.c
@@ -42,71 +42,71 @@ static struct gui_window *gw_ring = NULL;
/* exported function documented in monkey/browser.h */
nserror monkey_warn_user(const char *warning, const char *detail)
{
- fprintf(stderr, "WARN %s %s\n", warning, detail);
- return NSERROR_OK;
+ fprintf(stderr, "WARN %s %s\n", warning, detail);
+ return NSERROR_OK;
}
struct gui_window *
monkey_find_window_by_num(uint32_t win_num)
{
- struct gui_window *ret = NULL;
+ struct gui_window *ret = NULL;
- RING_ITERATE_START(struct gui_window, gw_ring, c_ring) {
- if (c_ring->win_num == win_num) {
- ret = c_ring;
- RING_ITERATE_STOP(gw_ring, c_ring);
- }
- } RING_ITERATE_END(gw_ring, c_ring);
+ RING_ITERATE_START(struct gui_window, gw_ring, c_ring) {
+ if (c_ring->win_num == win_num) {
+ ret = c_ring;
+ RING_ITERATE_STOP(gw_ring, c_ring);
+ }
+ } RING_ITERATE_END(gw_ring, c_ring);
- return ret;
+ return ret;
}
void
monkey_kill_browser_windows(void)
{
- while (gw_ring != NULL) {
- browser_window_destroy(gw_ring->bw);
- }
+ while (gw_ring != NULL) {
+ browser_window_destroy(gw_ring->bw);
+ }
}
static struct gui_window *
gui_window_create(struct browser_window *bw,
- struct gui_window *existing,
- gui_window_create_flags flags)
+ struct gui_window *existing,
+ gui_window_create_flags flags)
{
- struct gui_window *ret = calloc(sizeof(*ret), 1);
- if (ret == NULL)
- return NULL;
+ struct gui_window *ret = calloc(sizeof(*ret), 1);
+ if (ret == NULL)
+ return NULL;
- ret->win_num = win_ctr++;
- ret->bw = bw;
+ ret->win_num = win_ctr++;
+ ret->bw = bw;
- ret->width = 800;
- ret->height = 600;
+ ret->width = 800;
+ ret->height = 600;
- fprintf(stdout, "WINDOW NEW WIN %u FOR %p EXISTING %p NEWTAB %s CLONE %s\n",
- ret->win_num, bw, existing, flags & GW_CREATE_TAB ? "TRUE" : "FALSE",
- flags & GW_CREATE_CLONE ? "TRUE" : "FALSE");
- fprintf(stdout, "WINDOW SIZE WIN %u WIDTH %d HEIGHT %d\n",
- ret->win_num, ret->width, ret->height);
+ fprintf(stdout, "WINDOW NEW WIN %u FOR %p EXISTING %p NEWTAB %s CLONE %s\n",
+ ret->win_num, bw, existing, flags & GW_CREATE_TAB ? "TRUE" : "FALSE",
+ flags & GW_CREATE_CLONE ? "TRUE" : "FALSE");
+ fprintf(stdout, "WINDOW SIZE WIN %u WIDTH %d HEIGHT %d\n",
+ ret->win_num, ret->width, ret->height);
- RING_INSERT(gw_ring, ret);
+ RING_INSERT(gw_ring, ret);
- return ret;
+ return ret;
}
static void
gui_window_destroy(struct gui_window *g)
{
- fprintf(stdout, "WINDOW DESTROY WIN %u\n", g->win_num);
- RING_REMOVE(gw_ring, g);
- free(g);
+ fprintf(stdout, "WINDOW DESTROY WIN %u\n", g->win_num);
+ RING_REMOVE(gw_ring, g);
+ free(g);
}
static void
gui_window_set_title(struct gui_window *g, const char *title)
{
- fprintf(stdout, "WINDOW TITLE WIN %u STR %s\n", g->win_num, title);
+ fprintf(stdout, "WINDOW TITLE WIN %u STR %s\n", g->win_num, title);
}
/**
@@ -122,36 +122,36 @@ static nserror
gui_window_get_dimensions(struct gui_window *g, int *width, int *height,
bool scaled)
{
- fprintf(stdout, "WINDOW GET_DIMENSIONS WIN %u WIDTH %d HEIGHT %d\n",
- g->win_num, g->width, g->height);
- *width = g->width;
- *height = g->height;
+ fprintf(stdout, "WINDOW GET_DIMENSIONS WIN %u WIDTH %d HEIGHT %d\n",
+ g->win_num, g->width, g->height);
+ *width = g->width;
+ *height = g->height;
- return NSERROR_OK;
+ return NSERROR_OK;
}
static void
gui_window_new_content(struct gui_window *g)
{
- fprintf(stdout, "WINDOW NEW_CONTENT WIN %u\n", g->win_num);
+ fprintf(stdout, "WINDOW NEW_CONTENT WIN %u\n", g->win_num);
}
static void
gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon)
{
- fprintf(stdout, "WINDOW NEW_ICON WIN %u\n", g->win_num);
+ fprintf(stdout, "WINDOW NEW_ICON WIN %u\n", g->win_num);
}
static void
gui_window_start_throbber(struct gui_window *g)
{
- fprintf(stdout, "WINDOW START_THROBBER WIN %u\n", g->win_num);
+ fprintf(stdout, "WINDOW START_THROBBER WIN %u\n", g->win_num);
}
static void
gui_window_stop_throbber(struct gui_window *g)
{
- fprintf(stdout, "WINDOW STOP_THROBBER WIN %u\n", g->win_num);
+ fprintf(stdout, "WINDOW STOP_THROBBER WIN %u\n", g->win_num);
}
@@ -168,12 +168,12 @@ gui_window_stop_throbber(struct gui_window *g)
static nserror
gui_window_set_scroll(struct gui_window *gw, const struct rect *rect)
{
- gw->scrollx = rect->x0;
- gw->scrolly = rect->y0;
+ gw->scrollx = rect->x0;
+ gw->scrolly = rect->y0;
- fprintf(stdout, "WINDOW SET_SCROLL WIN %u X0 %d Y0 %d X1 %d Y1 %d\n",
- gw->win_num, rect->x0, rect->y0, rect->x1, rect->y1);
- return NSERROR_OK;
+ fprintf(stdout, "WINDOW SET_SCROLL WIN %u X %d Y %d\n",
+ gw->win_num, rect->x0, rect->y0);
+ return NSERROR_OK;
}
@@ -204,144 +204,144 @@ monkey_window_invalidate_area(struct gui_window *gw, const struct rect *rect)
static void
gui_window_update_extent(struct gui_window *g)
{
- int width, height;
+ int width, height;
- if (browser_window_get_extents(g->bw, false, &width, &height) != NSERROR_OK)
- return;
+ if (browser_window_get_extents(g->bw, false, &width, &height) != NSERROR_OK)
+ return;
- fprintf(stdout, "WINDOW UPDATE_EXTENT WIN %u WIDTH %d HEIGHT %d\n",
- g->win_num, width, height);
+ fprintf(stdout, "WINDOW UPDATE_EXTENT WIN %u WIDTH %d HEIGHT %d\n",
+ g->win_num, width, height);
}
static void
gui_window_set_status(struct gui_window *g, const char *text)
{
- fprintf(stdout, "WINDOW SET_STATUS WIN %u STR %s\n", g->win_num, text);
+ fprintf(stdout, "WINDOW SET_STATUS WIN %u STR %s\n", g->win_num, text);
}
static void
gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
{
- const char *ptr_name = "UNKNOWN";
+ const char *ptr_name = "UNKNOWN";
- switch (shape) {
- case GUI_POINTER_POINT:
- ptr_name = "POINT";
- break;
- case GUI_POINTER_CARET:
- ptr_name = "CARET";
- break;
- case GUI_POINTER_UP:
- ptr_name = "UP";
- break;
- case GUI_POINTER_DOWN:
- ptr_name = "DOWN";
- break;
- case GUI_POINTER_LEFT:
- ptr_name = "LEFT";
- break;
- case GUI_POINTER_RIGHT:
- ptr_name = "RIGHT";
- break;
- case GUI_POINTER_LD:
- ptr_name = "LD";
- break;
- case GUI_POINTER_RD:
- ptr_name = "RD";
- break;
- case GUI_POINTER_LU:
- ptr_name = "LU";
- break;
- case GUI_POINTER_RU:
- ptr_name = "RU";
- break;
- case GUI_POINTER_CROSS:
- ptr_name = "CROSS";
- break;
- case GUI_POINTER_MOVE:
- ptr_name = "MOVE";
- break;
- case GUI_POINTER_WAIT:
- ptr_name = "WAIT";
- break;
- case GUI_POINTER_HELP:
- ptr_name = "HELP";
- break;
- case GUI_POINTER_MENU:
- ptr_name = "MENU";
- break;
- case GUI_POINTER_PROGRESS:
- ptr_name = "PROGRESS";
- break;
- case GUI_POINTER_NO_DROP:
- ptr_name = "NO_DROP";
- break;
- case GUI_POINTER_NOT_ALLOWED:
- ptr_name = "NOT_ALLOWED";
- break;
- case GUI_POINTER_DEFAULT:
- ptr_name = "DEFAULT";
- break;
- default:
- break;
- }
- fprintf(stdout, "WINDOW SET_POINTER WIN %u POINTER %s\n", g->win_num, ptr_name);
+ switch (shape) {
+ case GUI_POINTER_POINT:
+ ptr_name = "POINT";
+ break;
+ case GUI_POINTER_CARET:
+ ptr_name = "CARET";
+ break;
+ case GUI_POINTER_UP:
+ ptr_name = "UP";
+ break;
+ case GUI_POINTER_DOWN:
+ ptr_name = "DOWN";
+ break;
+ case GUI_POINTER_LEFT:
+ ptr_name = "LEFT";
+ break;
+ case GUI_POINTER_RIGHT:
+ ptr_name = "RIGHT";
+ break;
+ case GUI_POINTER_LD:
+ ptr_name = "LD";
+ break;
+ case GUI_POINTER_RD:
+ ptr_name = "RD";
+ break;
+ case GUI_POINTER_LU:
+ ptr_name = "LU";
+ break;
+ case GUI_POINTER_RU:
+ ptr_name = "RU";
+ break;
+ case GUI_POINTER_CROSS:
+ ptr_name = "CROSS";
+ break;
+ case GUI_POINTER_MOVE:
+ ptr_name = "MOVE";
+ break;
+ case GUI_POINTER_WAIT:
+ ptr_name = "WAIT";
+ break;
+ case GUI_POINTER_HELP:
+ ptr_name = "HELP";
+ break;
+ case GUI_POINTER_MENU:
+ ptr_name = "MENU";
+ break;
+ case GUI_POINTER_PROGRESS:
+ ptr_name = "PROGRESS";
+ break;
+ case GUI_POINTER_NO_DROP:
+ ptr_name = "NO_DROP";
+ break;
+ case GUI_POINTER_NOT_ALLOWED:
+ ptr_name = "NOT_ALLOWED";
+ break;
+ case GUI_POINTER_DEFAULT:
+ ptr_name = "DEFAULT";
+ break;
+ default:
+ break;
+ }
+ fprintf(stdout, "WINDOW SET_POINTER WIN %u POINTER %s\n", g->win_num, ptr_name);
}
static nserror
gui_window_set_url(struct gui_window *g, nsurl *url)
{
- fprintf(stdout, "WINDOW SET_URL WIN %u URL %s\n", g->win_num, nsurl_access(url));
- return NSERROR_OK;
+ fprintf(stdout, "WINDOW SET_URL WIN %u URL %s\n", g->win_num, nsurl_access(url));
+ return NSERROR_OK;
}
static bool
gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
{
- fprintf(stdout, "WINDOW GET_SCROLL WIN %u X %d Y %d\n",
- g->win_num, g->scrollx, g->scrolly);
- *sx = g->scrollx;
- *sy = g->scrolly;
- return true;
+ fprintf(stdout, "WINDOW GET_SCROLL WIN %u X %d Y %d\n",
+ g->win_num, g->scrollx, g->scrolly);
+ *sx = g->scrollx;
+ *sy = g->scrolly;
+ return true;
}
static bool
gui_window_scroll_start(struct gui_window *g)
{
- fprintf(stdout, "WINDOW SCROLL_START WIN %u\n", g->win_num);
- g->scrollx = g->scrolly = 0;
- return true;
+ fprintf(stdout, "WINDOW SCROLL_START WIN %u\n", g->win_num);
+ g->scrollx = g->scrolly = 0;
+ return true;
}
static void
gui_window_place_caret(struct gui_window *g, int x, int y, int height,
- const struct rect *clip)
+ const struct rect *clip)
{
- fprintf(stdout, "WINDOW PLACE_CARET WIN %u X %d Y %d HEIGHT %d\n",
- g->win_num, x, y, height);
+ fprintf(stdout, "WINDOW PLACE_CARET WIN %u X %d Y %d HEIGHT %d\n",
+ g->win_num, x, y, height);
}
static void
gui_window_remove_caret(struct gui_window *g)
{
- fprintf(stdout, "WINDOW REMOVE_CARET WIN %u\n", g->win_num);
+ fprintf(stdout, "WINDOW REMOVE_CARET WIN %u\n", g->win_num);
}
static bool
gui_window_drag_start(struct gui_window *g, gui_drag_type type,
const struct rect *rect)
{
- fprintf(stdout, "WINDOW SCROLL_START WIN %u TYPE %i\n", g->win_num, type);
- return false;
+ fprintf(stdout, "WINDOW SCROLL_START WIN %u TYPE %i\n", g->win_num, type);
+ return false;
}
static nserror
gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
{
- fprintf(stdout, "WINDOW SAVE_LINK WIN %u URL %s TITLE %s\n",
- g->win_num, nsurl_access(url), title);
- return NSERROR_OK;
+ fprintf(stdout, "WINDOW SAVE_LINK WIN %u URL %s TITLE %s\n",
+ g->win_num, nsurl_access(url), title);
+ return NSERROR_OK;
}
@@ -351,169 +351,169 @@ gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
static void
monkey_window_handle_new(int argc, char **argv)
{
- nsurl *url = NULL;
- nserror error = NSERROR_OK;
-
- if (argc > 3)
- return;
-
- if (argc == 3) {
- error = nsurl_create(argv[2], &url);
- }
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
- if (url != NULL) {
- nsurl_unref(url);
- }
- }
- if (error != NSERROR_OK) {
- monkey_warn_user(messages_get_errorcode(error), 0);
- }
+ nsurl *url = NULL;
+ nserror error = NSERROR_OK;
+
+ if (argc > 3)
+ return;
+
+ if (argc == 3) {
+ error = nsurl_create(argv[2], &url);
+ }
+ if (error == NSERROR_OK) {
+ error = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
+ if (url != NULL) {
+ nsurl_unref(url);
+ }
+ }
+ if (error != NSERROR_OK) {
+ monkey_warn_user(messages_get_errorcode(error), 0);
+ }
}
static void
monkey_window_handle_destroy(int argc, char **argv)
{
- struct gui_window *gw;
- uint32_t nr = atoi((argc > 2) ? argv[2] : "-1");
+ struct gui_window *gw;
+ uint32_t nr = atoi((argc > 2) ? argv[2] : "-1");
- gw = monkey_find_window_by_num(nr);
+ gw = monkey_find_window_by_num(nr);
- if (gw == NULL) {
- fprintf(stdout, "ERROR WINDOW NUM BAD\n");
- } else {
- browser_window_destroy(gw->bw);
- }
+ if (gw == NULL) {
+ fprintf(stdout, "ERROR WINDOW NUM BAD\n");
+ } else {
+ browser_window_destroy(gw->bw);
+ }
}
static void
monkey_window_handle_go(int argc, char **argv)
{
- struct gui_window *gw;
- nsurl *url;
- nsurl *ref_url = NULL;
- nserror error;
+ struct gui_window *gw;
+ nsurl *url;
+ nsurl *ref_url = NULL;
+ nserror error;
- if (argc < 4 || argc > 5) {
- fprintf(stdout, "ERROR WINDOW GO ARGS BAD\n");
- return;
- }
+ if (argc < 4 || argc > 5) {
+ fprintf(stdout, "ERROR WINDOW GO ARGS BAD\n");
+ return;
+ }
- gw = monkey_find_window_by_num(atoi(argv[2]));
+ gw = monkey_find_window_by_num(atoi(argv[2]));
- if (gw == NULL) {
- fprintf(stdout, "ERROR WINDOW NUM BAD\n");
- return;
- }
-
- error = nsurl_create(argv[3], &url);
- if (error == NSERROR_OK) {
- if (argc == 5) {
- error = nsurl_create(argv[4], &ref_url);
- }
-
- if (error == NSERROR_OK) {
- error = browser_window_navigate(gw->bw,
- url,
- ref_url,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- if (ref_url != NULL) {
- nsurl_unref(ref_url);
- }
- }
- nsurl_unref(url);
- }
-
- if (error != NSERROR_OK) {
- monkey_warn_user(messages_get_errorcode(error), 0);
- }
+ if (gw == NULL) {
+ fprintf(stdout, "ERROR WINDOW NUM BAD\n");
+ return;
+ }
+
+ error = nsurl_create(argv[3], &url);
+ if (error == NSERROR_OK) {
+ if (argc == 5) {
+ error = nsurl_create(argv[4], &ref_url);
+ }
+
+ if (error == NSERROR_OK) {
+ error = browser_window_navigate(gw->bw,
+ url,
+ ref_url,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ if (ref_url != NULL) {
+ nsurl_unref(ref_url);
+ }
+ }
+ nsurl_unref(url);
+ }
+
+ if (error != NSERROR_OK) {
+ monkey_warn_user(messages_get_errorcode(error), 0);
+ }
}
static void
monkey_window_handle_redraw(int argc, char **argv)
{
- struct gui_window *gw;
- struct rect clip;
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = monkey_plotters
- };
+ struct gui_window *gw;
+ struct rect clip;
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = monkey_plotters
+ };
- if (argc != 3 && argc != 7) {
- fprintf(stdout, "ERROR WINDOW REDRAW ARGS BAD\n");
- return;
- }
+ if (argc != 3 && argc != 7) {
+ fprintf(stdout, "ERROR WINDOW REDRAW ARGS BAD\n");
+ return;
+ }
- gw = monkey_find_window_by_num(atoi(argv[2]));
+ gw = monkey_find_window_by_num(atoi(argv[2]));
- if (gw == NULL) {
- fprintf(stdout, "ERROR WINDOW NUM BAD\n");
- return;
- }
+ if (gw == NULL) {
+ fprintf(stdout, "ERROR WINDOW NUM BAD\n");
+ return;
+ }
- clip.x0 = 0;
- clip.y0 = 0;
- clip.x1 = gw->width;
- clip.y1 = gw->height;
+ clip.x0 = 0;
+ clip.y0 = 0;
+ clip.x1 = gw->width;
+ clip.y1 = gw->height;
- if (argc == 7) {
- clip.x0 = atoi(argv[3]);
- clip.y0 = atoi(argv[4]);
- clip.x1 = atoi(argv[5]);
- clip.y1 = atoi(argv[6]);
- }
+ if (argc == 7) {
+ clip.x0 = atoi(argv[3]);
+ clip.y0 = atoi(argv[4]);
+ clip.x1 = atoi(argv[5]);
+ clip.y1 = atoi(argv[6]);
+ }
- LOG("Issue redraw");
- fprintf(stdout, "WINDOW REDRAW WIN %d START\n", atoi(argv[2]));
- browser_window_redraw(gw->bw, gw->scrollx, gw->scrolly, &clip, &ctx);
- fprintf(stdout, "WINDOW REDRAW WIN %d STOP\n", atoi(argv[2]));
+ LOG("Issue redraw");
+ fprintf(stdout, "WINDOW REDRAW WIN %d START\n", atoi(argv[2]));
+ browser_window_redraw(gw->bw, gw->scrollx, gw->scrolly, &clip, &ctx);
+ fprintf(stdout, "WINDOW REDRAW WIN %d STOP\n", atoi(argv[2]));
}
static void
monkey_window_handle_reload(int argc, char **argv)
{
- struct gui_window *gw;
- if (argc != 3 && argc != 4) {
- fprintf(stdout, "ERROR WINDOW RELOAD ARGS BAD\n");
- }
+ struct gui_window *gw;
+ if (argc != 3 && argc != 4) {
+ fprintf(stdout, "ERROR WINDOW RELOAD ARGS BAD\n");
+ }
- gw = monkey_find_window_by_num(atoi(argv[2]));
+ gw = monkey_find_window_by_num(atoi(argv[2]));
- if (gw == NULL) {
- fprintf(stdout, "ERROR WINDOW NUM BAD\n");
- } else {
- browser_window_reload(gw->bw, argc == 4);
- }
+ if (gw == NULL) {
+ fprintf(stdout, "ERROR WINDOW NUM BAD\n");
+ } else {
+ browser_window_reload(gw->bw, argc == 4);
+ }
}
void
monkey_window_handle_command(int argc, char **argv)
{
- if (argc == 1)
- return;
+ if (argc == 1)
+ return;
- if (strcmp(argv[1], "NEW") == 0) {
- monkey_window_handle_new(argc, argv);
- } else if (strcmp(argv[1], "DESTROY") == 0) {
- monkey_window_handle_destroy(argc, argv);
- } else if (strcmp(argv[1], "GO") == 0) {
- monkey_window_handle_go(argc, argv);
- } else if (strcmp(argv[1], "REDRAW") == 0) {
- monkey_window_handle_redraw(argc, argv);
- } else if (strcmp(argv[1], "RELOAD") == 0) {
- monkey_window_handle_reload(argc, argv);
- } else {
- fprintf(stdout, "ERROR WINDOW COMMAND UNKNOWN %s\n", argv[1]);
- }
+ if (strcmp(argv[1], "NEW") == 0) {
+ monkey_window_handle_new(argc, argv);
+ } else if (strcmp(argv[1], "DESTROY") == 0) {
+ monkey_window_handle_destroy(argc, argv);
+ } else if (strcmp(argv[1], "GO") == 0) {
+ monkey_window_handle_go(argc, argv);
+ } else if (strcmp(argv[1], "REDRAW") == 0) {
+ monkey_window_handle_redraw(argc, argv);
+ } else if (strcmp(argv[1], "RELOAD") == 0) {
+ monkey_window_handle_reload(argc, argv);
+ } else {
+ fprintf(stdout, "ERROR WINDOW COMMAND UNKNOWN %s\n", argv[1]);
+ }
}
diff --git a/frontends/monkey/browser.h b/frontends/monkey/browser.h
index 2b03402..8cbbb94 100644
--- a/frontends/monkey/browser.h
+++ b/frontends/monkey/browser.h
@@ -25,16 +25,16 @@ extern struct gui_window_table *monkey_window_table;
extern struct gui_download_table *monkey_download_table;
struct gui_window {
- struct gui_window *r_next;
- struct gui_window *r_prev;
+ struct gui_window *r_next;
+ struct gui_window *r_prev;
- uint32_t win_num;
- struct browser_window *bw;
+ uint32_t win_num;
+ struct browser_window *bw;
- int width, height;
- int scrollx, scrolly;
+ int width, height;
+ int scrollx, scrolly;
- char *host; /* Ignore this, it's in case RING*() gets debugging for fetchers */
+ char *host; /* Ignore this, it's in case RING*() gets debugging for fetchers */
};
diff --git a/frontends/monkey/cert.c b/frontends/monkey/cert.c
index 710e710..a199755 100644
--- a/frontends/monkey/cert.c
+++ b/frontends/monkey/cert.c
@@ -25,11 +25,11 @@
#include "monkey/cert.h"
typedef struct monkey_cert {
- struct monkey_cert *r_next, *r_prev;
- uint32_t num;
- char *host; /* Ignore */
- nserror (*cb)(bool,void*);
- void *pw;
+ struct monkey_cert *r_next, *r_prev;
+ uint32_t num;
+ char *host; /* Ignore */
+ nserror (*cb)(bool,void*);
+ void *pw;
} monkey_cert_t;
static monkey_cert_t *cert_ring = NULL;
@@ -40,20 +40,20 @@ gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
unsigned long num, nserror (*cb)(bool proceed, void *pw),
void *cbpw)
{
- monkey_cert_t *m4t = calloc(sizeof(*m4t), 1);
- if (m4t == NULL) {
- return NSERROR_NOMEM;
- }
- m4t->cb = cb;
- m4t->pw = cbpw;
- m4t->num = cert_ctr++;
+ monkey_cert_t *m4t = calloc(sizeof(*m4t), 1);
+ if (m4t == NULL) {
+ return NSERROR_NOMEM;
+ }
+ m4t->cb = cb;
+ m4t->pw = cbpw;
+ m4t->num = cert_ctr++;
- RING_INSERT(cert_ring, m4t);
+ RING_INSERT(cert_ring, m4t);
- fprintf(stdout, "SSLCERT VERIFY CERT %u URL %s\n",
- m4t->num, nsurl_access(url));
+ fprintf(stdout, "SSLCERT VERIFY CERT %u URL %s\n",
+ m4t->num, nsurl_access(url));
- return NSERROR_OK;
+ return NSERROR_OK;
}
diff --git a/frontends/monkey/dispatch.c b/frontends/monkey/dispatch.c
index 563534d..b531f05 100644
--- a/frontends/monkey/dispatch.c
+++ b/frontends/monkey/dispatch.c
@@ -28,9 +28,9 @@
#include "monkey/dispatch.h"
typedef struct cmdhandler {
- struct cmdhandler *r_next, *r_prev;
- const char *cmd;
- handle_command_fn fn;
+ struct cmdhandler *r_next, *r_prev;
+ const char *cmd;
+ handle_command_fn fn;
} monkey_cmdhandler_t;
static monkey_cmdhandler_t *handler_ring = NULL;
@@ -38,68 +38,68 @@ static monkey_cmdhandler_t *handler_ring = NULL;
nserror
monkey_register_handler(const char *cmd, handle_command_fn fn)
{
- monkey_cmdhandler_t *ret = calloc(sizeof(*ret), 1);
- if (ret == NULL) {
- LOG("Unable to allocate handler");
- return NSERROR_NOMEM;
- }
- ret->cmd = strdup(cmd);
- ret->fn = fn;
- RING_INSERT(handler_ring, ret);
- return NSERROR_OK;
+ monkey_cmdhandler_t *ret = calloc(sizeof(*ret), 1);
+ if (ret == NULL) {
+ LOG("Unable to allocate handler");
+ return NSERROR_NOMEM;
+ }
+ ret->cmd = strdup(cmd);
+ ret->fn = fn;
+ RING_INSERT(handler_ring, ret);
+ return NSERROR_OK;
}
void
monkey_process_command(void)
{
- char buffer[PATH_MAX];
- int argc = 0;
- char **argv = NULL;
- char *p, *r = NULL;
- handle_command_fn fn = NULL;
- char **nargv;
+ char buffer[PATH_MAX];
+ int argc = 0;
+ char **argv = NULL;
+ char *p, *r = NULL;
+ handle_command_fn fn = NULL;
+ char **nargv;
- if (fgets(buffer, PATH_MAX, stdin) == NULL) {
- /* end of input or read error so issue QUIT */
- sprintf(buffer, "QUIT\n");
- }
+ if (fgets(buffer, PATH_MAX, stdin) == NULL) {
+ /* end of input or read error so issue QUIT */
+ sprintf(buffer, "QUIT\n");
+ }
- /* remove newline */
- buffer[strlen(buffer) - 1] = '\0';
+ /* remove newline */
+ buffer[strlen(buffer) - 1] = '\0';
- argv = malloc(sizeof *argv);
- if (argv == NULL) {
- return;
- }
- argc = 1;
- *argv = buffer;
+ argv = malloc(sizeof *argv);
+ if (argv == NULL) {
+ return;
+ }
+ argc = 1;
+ *argv = buffer;
- for (p = r = buffer; *p != '\0'; p++) {
- if (*p == ' ') {
- nargv = realloc(argv, sizeof(*argv) * (argc + 1));
- if (nargv == NULL) {
- /* reallocation of argument vector failed, try using what is
- * already processed.
- */
- break;
- } else {
- argv = nargv;
- }
- argv[argc++] = r = p + 1;
- *p = '\0';
- }
- }
+ for (p = r = buffer; *p != '\0'; p++) {
+ if (*p == ' ') {
+ nargv = realloc(argv, sizeof(*argv) * (argc + 1));
+ if (nargv == NULL) {
+ /* reallocation of argument vector failed, try using what is
+ * already processed.
+ */
+ break;
+ } else {
+ argv = nargv;
+ }
+ argv[argc++] = r = p + 1;
+ *p = '\0';
+ }
+ }
- RING_ITERATE_START(monkey_cmdhandler_t, handler_ring, handler) {
- if (strcmp(argv[0], handler->cmd) == 0) {
- fn = handler->fn;
- RING_ITERATE_STOP(handler_ring, handler);
- }
- } RING_ITERATE_END(handler_ring, handler);
+ RING_ITERATE_START(monkey_cmdhandler_t, handler_ring, handler) {
+ if (strcmp(argv[0], handler->cmd) == 0) {
+ fn = handler->fn;
+ RING_ITERATE_STOP(handler_ring, handler);
+ }
+ } RING_ITERATE_END(handler_ring, handler);
- if (fn != NULL) {
- fn(argc, argv);
- }
+ if (fn != NULL) {
+ fn(argc, argv);
+ }
- free(argv);
+ free(argv);
}
diff --git a/frontends/monkey/download.c b/frontends/monkey/download.c
index f2e1cbf..5c9ce1b 100644
--- a/frontends/monkey/download.c
+++ b/frontends/monkey/download.c
@@ -30,11 +30,11 @@
static uint32_t dwin_ctr = 0;
struct gui_download_window {
- struct gui_download_window *r_next;
- struct gui_download_window *r_prev;
- struct gui_window *g;
- uint32_t dwin_num;
- char *host; /* ignore */
+ struct gui_download_window *r_next;
+ struct gui_download_window *r_prev;
+ struct gui_window *g;
+ uint32_t dwin_num;
+ char *host; /* ignore */
};
static struct gui_download_window *dw_ring = NULL;
@@ -43,44 +43,44 @@ static struct gui_download_window *
gui_download_window_create(download_context *ctx,
struct gui_window *parent)
{
- struct gui_download_window *ret = calloc(sizeof(*ret), 1);
- if (ret == NULL)
- return NULL;
- ret->g = parent;
- ret->dwin_num = dwin_ctr++;
+ struct gui_download_window *ret = calloc(sizeof(*ret), 1);
+ if (ret == NULL)
+ return NULL;
+ ret->g = parent;
+ ret->dwin_num = dwin_ctr++;
- RING_INSERT(dw_ring, ret);
+ RING_INSERT(dw_ring, ret);
- fprintf(stdout, "DOWNLOAD_WINDOW CREATE DWIN %u WIN %u\n",
- ret->dwin_num, parent->win_num);
+ fprintf(stdout, "DOWNLOAD_WINDOW CREATE DWIN %u WIN %u\n",
+ ret->dwin_num, parent->win_num);
- return ret;
+ return ret;
}
static nserror
gui_download_window_data(struct gui_download_window *dw,
const char *data, unsigned int size)
{
- fprintf(stdout, "DOWNLOAD_WINDOW DATA DWIN %u SIZE %u DATA %s\n",
- dw->dwin_num, size, data);
- return NSERROR_OK;
+ fprintf(stdout, "DOWNLOAD_WINDOW DATA DWIN %u SIZE %u DATA %s\n",
+ dw->dwin_num, size, data);
+ return NSERROR_OK;
}
static void
gui_download_window_error(struct gui_download_window *dw,
const char *error_msg)
{
- fprintf(stdout, "DOWNLOAD_WINDOW ERROR DWIN %u ERROR %s\n",
- dw->dwin_num, error_msg);
+ fprintf(stdout, "DOWNLOAD_WINDOW ERROR DWIN %u ERROR %s\n",
+ dw->dwin_num, error_msg);
}
static void
gui_download_window_done(struct gui_download_window *dw)
{
- fprintf(stdout, "DOWNLOAD_WINDOW DONE DWIN %u\n",
- dw->dwin_num);
- RING_REMOVE(dw_ring, dw);
- free(dw);
+ fprintf(stdout, "DOWNLOAD_WINDOW DONE DWIN %u\n",
+ dw->dwin_num);
+ RING_REMOVE(dw_ring, dw);
+ free(dw);
}
static struct gui_download_table download_table = {
diff --git a/frontends/monkey/farmer.py b/frontends/monkey/farmer.py
new file mode 100644
index 0000000..d4b4b1e
--- a/dev/null
+++ b/frontends/monkey/farmer.py
@@ -0,0 +1,363 @@
+#!/usr/bin/python
+
+# Copyright 2017 Daniel Silverstone <dsilvers@digital-scurf.org>
+#
+# This file is part of NetSurf, http://www.netsurf-browser.org/
+#
+# NetSurf is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# NetSurf is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Monkey Farmer
+
+The monkey farmer is a wrapper around `nsmonkey` which can be used to simplify
+access to the monkey behaviours and ultimately to write useful tests in an
+expressive but not overcomplicated DSLish way. Tests are, ultimately, still
+Python code.
+
+"""
+
+import asyncore
+import os
+import socket
+import subprocess
+import time
+
+#monkey_cmd = ['./nsmonkey', '--accept_language=fr']
+monkey_cmd = ['./nsmonkey']
+
+class MonkeyFarmer(asyncore.dispatcher):
+ def __init__(self, online, quiet=False):
+ (mine, monkeys) = socket.socketpair()
+
+ asyncore.dispatcher.__init__(self, sock=mine)
+
+ self.monkey = subprocess.Popen(
+ monkey_cmd,
+ stdin=monkeys,
+ stdout=monkeys,
+ close_fds=[mine])
+
+ monkeys.close()
+
+ self.buffer = ""
+ self.incoming = ""
+ self.lines = []
+ self.scheduled = []
+ self.deadmonkey = False
+ self.online = online
+ self.quiet = quiet
+
+ def handle_connect(self):
+ pass
+
+ def handle_read(self):
+ got = self.recv(8192)
+ if got == "" or got is None:
+ self.deadmonkey = True
+ return
+ self.incoming += got
+ if "\n" in self.incoming:
+ lines = self.incoming.split("\n")
+ self.incoming = lines.pop()
+ self.lines = lines
+
+ def writable(self):
+ return (len(self.buffer) > 0)
+
+ def handle_write(self):
+ sent = self.send(self.buffer)
+ self.buffer = self.buffer[sent:]
+
+ def tell_monkey(self, *args):
+ cmd = (" ".join(args))
+ if not self.quiet:
+ print ">>> %s" % cmd
+ self.buffer += "%s\n" % cmd
+
+ def monkey_says(self, line):
+ if not self.quiet:
+ print "<<< %s" % line
+ self.online(line)
+
+ def schedule_event(self, event, secs=None, when=None):
+ assert(secs is not None or when is not None)
+ if when is None:
+ when = time.time() + secs
+ self.scheduled.append((when, event))
+ self.scheduled.sort(lambda a,b: cmp(a[0],b[0]))
+
+ def unschedule_event(self, event):
+ self.scheduled = [x for x in self.scheduled if x[1] != event]
+
+ def loop(self, once=False):
+ if len(self.lines) > 0:
+ self.monkey_says(self.lines.pop(0))
+ if once:
+ return
+ while not self.deadmonkey:
+ now = time.time()
+ while len(self.scheduled) > 0 and now >= self.scheduled[0][0]:
+ func = self.scheduled[0][1]
+ self.scheduled.pop(0)
+ func(self)
+ now = time.time()
+ if len(self.scheduled) > 0:
+ next = self.scheduled[0][0]
+ asyncore.loop(timeout=next-now, count=1)
+ else:
+ asyncore.loop(count=1)
+ if len(self.lines) > 0:
+ self.monkey_says(self.lines.pop(0))
+ if once:
+ break
+
+class Browser:
+ def __init__(self, quiet=False):
+ self.farmer = MonkeyFarmer(online=self.on_monkey_line, quiet=quiet)
+ self.windows = {}
+ self.current_draw_target = None
+
+ def pass_options(self, *opts):
+ if len(opts) > 0:
+ self.farmer.tell_monkey("OPTIONS " + (" ".join(opts)))
+
+ def on_monkey_line(self, line):
+ parts = line.split(" ")
+ handler = getattr(self, "handle_" + parts[0], None)
+ if handler is not None:
+ handler(*parts[1:])
+
+ def quit(self):
+ self.farmer.tell_monkey("QUIT")
+
+ def quit_and_wait(self):
+ self.quit()
+ self.farmer.loop()
+
+ def handle_GENERIC(self, what, *args):
+ pass
+
+ def handle_WINDOW(self, action, _win, winid, *args):
+ if action == "NEW":
+ new_win = BrowserWindow(self, winid, *args)
+ self.windows[winid] = new_win
+ else:
+ win = self.windows.get(winid, None)
+ if win is None:
+ print " Unknown window id %s" % winid
+ else:
+ win.handle(action, *args)
+
+ def handle_PLOT(self, *args):
+ if self.current_draw_target is not None:
+ self.current_draw_target.handle_plot(*args)
+
+ def new_window(self, url=None):
+ if url is None:
+ self.farmer.tell_monkey("WINDOW NEW")
+ else:
+ self.farmer.tell_monkey("WINDOW NEW %s" % url)
+ wins_known = set(self.windows.keys())
+ while len(set(self.windows.keys()).difference(wins_known)) == 0:
+ self.farmer.loop(once=True)
+ poss_wins = set(self.windows.keys()).difference(wins_known)
+ return self.windows[poss_wins.pop()]
+
+
+class BrowserWindow:
+ def __init__(self, browser, winid, _for, coreid, _existing, otherid, _newtab, newtab, _clone, clone):
+ self.alive = True
+ self.browser = browser
+ self.winid = winid
+ self.coreid = coreid
+ self.existing = browser.windows.get(otherid, None)
+ self.newtab = newtab == "TRUE"
+ self.clone = clone == "TRUE"
+ self.width = 0
+ self.height = 0
+ self.title = ""
+ self.throbbing = False
+ self.scrollx = 0
+ self.scrolly = 0
+ self.content_width = 0
+ self.content_height = 0
+ self.status = ""
+ self.pointer = ""
+ self.scale = 1.0
+ self.url = ""
+ self.plotted = []
+ self.plotting = False
+
+ def kill(self):
+ self.browser.farmer.tell_monkey("WINDOW DESTROY %s" % self.winid)
+
+ def go(self, url, referer = None):
+ if referer is None:
+ self.browser.farmer.tell_monkey("WINDOW GO %s %s" % (
+ self.winid, url))
+ else:
+ self.browser.farmer.tell_monkey("WINDOW GO %s %s %s" % (
+ self.winid, url, referer))
+
+ def reload(self):
+ self.browser.farmer.tell_monkey("WINDOW RELOAD %s" % self.winid)
+
+ def redraw(self, coords=None):
+ if coords is None:
+ self.browser.farmer.tell_monkey("WINDOW REDRAW %s" % self.winid)
+ else:
+ self.browser.farmer.tell_monkey("WINDOW REDRAW %s %s" % (
+ self.winid, (" ".join(coords))))
+
+ def handle(self, action, *args):
+ handler = getattr(self, "handle_window_" + action, None)
+ if handler is not None:
+ handler(*args)
+
+ def handle_window_SIZE(self, _width, width, _height, height):
+ self.width = int(width)
+ self.height = int(height)
+
+ def handle_window_DESTROY(self):
+ self.alive = False
+
+ def handle_window_TITLE(self, _str, *title):
+ self.title = " ".join(title)
+
+ def handle_window_REDRAW(self):
+ pass
+
+ def handle_window_GET_DIMENSIONS(self, _width, width, _height, height):
+ self.width = width
+ self.height = height
+
+ def handle_window_NEW_CONTENT(self):
+ pass
+
+ def handle_window_NEW_ICON(self):
+ pass
+
+ def handle_window_START_THROBBER(self):
+ self.throbbing = True
+
+ def handle_window_STOP_THROBBER(self):
+ self.throbbing = False
+
+ def handle_window_SET_SCROLL(self, _x, x, _y, y):
+ self.scrollx = int(x)
+ self.scrolly = int(y)
+
+ def handle_window_UPDATE_BOX(self, _x, x, _y, y, _width, width, _height, height):
+ x = int(x)
+ y = int(y)
+ width = int(width)
+ height = int(height)
+ pass
+
+ def handle_window_UPDATE_EXTENT(self, _width, width, _height, height):
+ self.content_width = int(width)
+ self.content_height = int(height)
+
+ def handle_window_SET_STATUS(self, _str, *status):
+ self.status = (" ".join(status))
+
+ def handle_window_SET_POINTER(self, _ptr, ptr):
+ self.pointer = ptr
+
+ def handle_window_SET_SCALE(self, _scale, scale):
+ self.scale = float(scale)
+
+ def handle_window_SET_URL(self, _url, url):
+ self.url = url
+
+ def handle_window_GET_SCROLL(self, _x, x, _y, y):
+ self.scrollx = int(x)
+ self.scrolly = int(y)
+
+ def handle_window_SCROLL_START(self):
+ self.scrollx = 0
+ self.scrolly = 0
+
+ def handle_window_REDRAW(self, act):
+ if act == "START":
+ self.browser.current_draw_target = self
+ self.plotted = []
+ self.plotting = True
+ else:
+ self.browser.current_draw_target = None
+ self.plotting = False
+
+ def load_page(self, url=None, referer=None):
+ if url is not None:
+ self.go(url, referer)
+ self.wait_loaded()
+
+ def reload(self):
+ self.browser.farmer.tell_monkey("WINDOW RELOAD %s" % self.winid)
+ self.wait_loaded()
+
+ def wait_loaded(self):
+ while not self.throbbing:
+ self.browser.farmer.loop(once=True)
+ while self.throbbing:
+ self.browser.farmer.loop(once=True)
+
+ def handle_plot(self, *args):
+ self.plotted.append(args)
+
+ def redraw(self, coords=None):
+ if coords is None:
+ self.browser.farmer.tell_monkey("WINDOW REDRAW %s" % self.winid)
+ else:
+ self.browser.farmer.tell_monkey("WINDOW REDRAW %s %s" % (
+ self.winid, (" ".join(coords))))
+ while not self.plotting:
+ self.browser.farmer.loop(once=True)
+ while self.plotting:
+ self.browser.farmer.loop(once=True)
+ return self.plotted
+
+
+# Simple test is as follows...
+
+browser = Browser(quiet=True)
+
+win = browser.new_window()
+
+fname = "test/js/inline-doc-write-simple.html"
+full_fname = os.path.join(os.getcwd(), fname)
+
+browser.pass_options("--enable_javascript=0")
+win.load_page("file://" + full_fname)
+
+print("Loaded, URL is %s" % win.url)
+
+cmds = win.redraw()
+print("Received %d plot commands" % len(cmds))
+for cmd in cmds:
+ if cmd[0] == "TEXT":
+ print "%s %s -> %s" % (cmd[2], cmd[4], (" ".join(cmd[6:])))
+
+
+browser.pass_options("--enable_javascript=1")
+win.load_page("file://" + full_fname)
+
+print("Loaded, URL is %s" % win.url)
+
+cmds = win.redraw()
+print("Received %d plot commands" % len(cmds))
+for cmd in cmds:
+ if cmd[0] == "TEXT":
+ print "%s %s -> %s" % (cmd[2], cmd[4], (" ".join(cmd[6:])))
+
+browser.quit_and_wait()
diff --git a/frontends/monkey/fetch.c b/frontends/monkey/fetch.c
index 4985329..256d79b 100644
--- a/frontends/monkey/fetch.c
+++ b/frontends/monkey/fetch.c
@@ -36,18 +36,18 @@ extern char **respaths;
static nsurl *gui_get_resource_url(const char *path)
{
- char buf[PATH_MAX];
- nsurl *url = NULL;
+ char buf[PATH_MAX];
+ nsurl *url = NULL;
- netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url);
+ netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url);
- return url;
+ return url;
}
static struct gui_fetch_table fetch_table = {
- .filetype = monkey_fetch_filetype,
+ .filetype = monkey_fetch_filetype,
- .get_resource_url = gui_get_resource_url,
+ .get_resource_url = gui_get_resource_url,
};
struct gui_fetch_table *monkey_fetch_table = &fetch_table;
diff --git a/frontends/monkey/layout.c b/frontends/monkey/layout.c
index 4bcc51b..7b72231 100644
--- a/frontends/monkey/layout.c
+++ b/frontends/monkey/layout.c
@@ -30,11 +30,11 @@
#include "monkey/layout.h"
static nserror nsfont_width(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int *width)
+ const char *string, size_t length,
+ int *width)
{
- *width = (fstyle->size * utf8_bounded_length(string, length)) / FONT_SIZE_SCALE;
- return NSERROR_OK;
+ *width = (fstyle->size * utf8_bounded_length(string, length)) / FONT_SIZE_SCALE;
+ return NSERROR_OK;
}
/**
@@ -50,14 +50,14 @@ static nserror nsfont_width(const plot_font_style_t *fstyle,
*/
static nserror nsfont_position_in_string(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
{
- *char_offset = x / (fstyle->size / FONT_SIZE_SCALE);
- if (*char_offset > length)
- *char_offset = length;
- *actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE);
- return NSERROR_OK;
+ *char_offset = x / (fstyle->size / FONT_SIZE_SCALE);
+ if (*char_offset > length)
+ *char_offset = length;
+ *actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE);
+ return NSERROR_OK;
}
@@ -85,27 +85,27 @@ static nserror nsfont_position_in_string(const plot_font_style_t *fstyle,
*/
static nserror nsfont_split(const plot_font_style_t *fstyle,
- const char *string, size_t length,
- int x, size_t *char_offset, int *actual_x)
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
{
- int c_off = *char_offset = x / (fstyle->size / FONT_SIZE_SCALE);
- if (*char_offset > length) {
- *char_offset = length;
- } else {
- while (*char_offset > 0) {
- if (string[*char_offset] == ' ')
- break;
- (*char_offset)--;
- }
- if (*char_offset == 0) {
- *char_offset = c_off;
- while (*char_offset < length && string[*char_offset] != ' ') {
- (*char_offset)++;
- }
- }
- }
- *actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE);
- return NSERROR_OK;
+ int c_off = *char_offset = x / (fstyle->size / FONT_SIZE_SCALE);
+ if (*char_offset > length) {
+ *char_offset = length;
+ } else {
+ while (*char_offset > 0) {
+ if (string[*char_offset] == ' ')
+ break;
+ (*char_offset)--;
+ }
+ if (*char_offset == 0) {
+ *char_offset = c_off;
+ while (*char_offset < length && string[*char_offset] != ' ') {
+ (*char_offset)++;
+ }
+ }
+ }
+ *actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE);
+ return NSERROR_OK;
}
static struct gui_layout_table layout_table = {
diff --git a/frontends/monkey/main.c b/frontends/monkey/main.c
index 0059ff0..1bea024 100644
--- a/frontends/monkey/main.c
+++ b/frontends/monkey/main.c
@@ -66,8 +66,8 @@ static bool monkey_done = false;
*/
static void die(const char * const error)
{
- fprintf(stderr, "DIE %s\n", error);
- exit(EXIT_FAILURE);
+ fprintf(stderr, "DIE %s\n", error);
+ exit(EXIT_FAILURE);
}
/** obtain language from environment
@@ -78,29 +78,29 @@ static void die(const char * const error)
*/
static const char *get_language(void)
{
- const char *lang;
+ const char *lang;
- lang = getenv("LANGUAGE");
- if ((lang != NULL) && (lang[0] != '\0')) {
- return lang;
- }
+ lang = getenv("LANGUAGE");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
- lang = getenv("LC_ALL");
- if ((lang != NULL) && (lang[0] != '\0')) {
- return lang;
- }
+ lang = getenv("LC_ALL");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
- lang = getenv("LC_MESSAGES");
- if ((lang != NULL) && (lang[0] != '\0')) {
- return lang;
- }
+ lang = getenv("LC_MESSAGES");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
- lang = getenv("LANG");
- if ((lang != NULL) && (lang[0] != '\0')) {
- return lang;
- }
+ lang = getenv("LANG");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
- return NULL;
+ return NULL;
}
@@ -120,92 +120,97 @@ static const char *get_language(void)
*/
static const char * const *get_languagev(void)
{
- static const char *langv[LANGV_SIZE];
- int langidx = 0; /* index of next entry in vector */
- static char langs[LANGS_SIZE];
- char *curp; /* next language parameter in langs string */
- const char *lange; /* language from environment variable */
- int lang_len;
- char *cln; /* colon in lange */
-
- /* return cached vector */
- if (langv[0] != NULL) {
- return &langv[0];
- }
-
- curp = &langs[0];
-
- lange = get_language();
-
- if (lange != NULL) {
- lang_len = strlen(lange) + 1;
- if (lang_len < (LANGS_SIZE - 2)) {
- memcpy(curp, lange, lang_len);
- while ((curp[0] != 0) &&
- (langidx < (LANGV_SIZE - 2))) {
- /* avoid using strchrnul as it is not portable */
- cln = strchr(curp, ':');
- if (cln == NULL) {
- langv[langidx++] = curp;
- curp += lang_len;
- break;
- } else {
- if ((cln - curp) > 1) {
- /* only place non empty entries in vector */
- langv[langidx++] = curp;
- }
- *cln++ = 0; /* null terminate */
- lang_len -= (cln - curp);
- curp = cln;
+ static const char *langv[LANGV_SIZE];
+ int langidx = 0; /* index of next entry in vector */
+ static char langs[LANGS_SIZE];
+ char *curp; /* next language parameter in langs string */
+ const char *lange; /* language from environment variable */
+ int lang_len;
+ char *cln; /* colon in lange */
+
+ /* return cached vector */
+ if (langv[0] != NULL) {
+ return &langv[0];
}
- }
- }
- }
- /* ensure C language is present */
- langv[langidx++] = curp;
- *curp++ = 'C';
- *curp++ = 0;
- langv[langidx] = NULL;
+ curp = &langs[0];
+
+ lange = get_language();
+
+ if (lange != NULL) {
+ lang_len = strlen(lange) + 1;
+ if (lang_len < (LANGS_SIZE - 2)) {
+ memcpy(curp, lange, lang_len);
+ while ((curp[0] != 0) &&
+ (langidx < (LANGV_SIZE - 2))) {
+ /* avoid using strchrnul as it is not portable */
+ cln = strchr(curp, ':');
+ if (cln == NULL) {
+ langv[langidx++] = curp;
+ curp += lang_len;
+ break;
+ } else {
+ if ((cln - curp) > 1) {
+ /* only place non empty entries in vector */
+ langv[langidx++] = curp;
+ }
+ *cln++ = 0; /* null terminate */
+ lang_len -= (cln - curp);
+ curp = cln;
+ }
+ }
+ }
+ }
- return &langv[0];
+ /* ensure C language is present */
+ langv[langidx++] = curp;
+ *curp++ = 'C';
+ *curp++ = 0;
+ langv[langidx] = NULL;
+
+ return &langv[0];
}
/* Stolen from gtk/gui.c */
static char **
nsmonkey_init_resource(const char *resource_path)
{
- const char * const *langv;
- char **pathv; /* resource path string vector */
- char **respath; /* resource paths vector */
+ const char * const *langv;
+ char **pathv; /* resource path string vector */
+ char **respath; /* resource paths vector */
- pathv = filepath_path_to_strvec(resource_path);
+ pathv = filepath_path_to_strvec(resource_path);
- langv = get_languagev();
+ langv = get_languagev();
- respath = filepath_generate(pathv, langv);
+ respath = filepath_generate(pathv, langv);
- filepath_free_strvec(pathv);
+ filepath_free_strvec(pathv);
- return respath;
+ return respath;
}
static void monkey_quit(void)
{
- urldb_save_cookies(nsoption_charp(cookie_jar));
- urldb_save(nsoption_charp(url_file));
- monkey_fetch_filetype_fin();
+ urldb_save_cookies(nsoption_charp(cookie_jar));
+ urldb_save(nsoption_charp(url_file));
+ monkey_fetch_filetype_fin();
}
static nserror gui_launch_url(struct nsurl *url)
{
- fprintf(stdout, "GENERIC LAUNCH URL %s\n", nsurl_access(url));
- return NSERROR_OK;
+ fprintf(stdout, "GENERIC LAUNCH URL %s\n", nsurl_access(url));
+ return NSERROR_OK;
}
static void quit_handler(int argc, char **argv)
{
- monkey_done = true;
+ monkey_done = true;
+}
+
+static void monkey_options_handle_command(int argc, char **argv)
+{
+ nsoption_commandline(&argc, argv, nsoptions);
}
/**
@@ -216,12 +221,12 @@ static void quit_handler(int argc, char **argv)
*/
static nserror set_defaults(struct nsoption_s *defaults)
{
- /* Set defaults for absent option strings */
- nsoption_setnull_charp(cookie_file, strdup("~/.netsurf/Cookies"));
- nsoption_setnull_charp(cookie_jar, strdup("~/.netsurf/Cookies"));
- nsoption_setnull_charp(url_file, strdup("~/.netsurf/URLs"));
+ /* Set defaults for absent option strings */
+ nsoption_setnull_charp(cookie_file, strdup("~/.netsurf/Cookies"));
+ nsoption_setnull_charp(cookie_jar, strdup("~/.netsurf/Cookies"));
+ nsoption_setnull_charp(url_file, strdup("~/.netsurf/URLs"));
- return NSERROR_OK;
+ return NSERROR_OK;
}
@@ -230,170 +235,174 @@ static nserror set_defaults(struct nsoption_s *defaults)
*/
static bool nslog_stream_configure(FILE *fptr)
{
- /* set log stream to be non-buffering */
- setbuf(fptr, NULL);
+ /* set log stream to be non-buffering */
+ setbuf(fptr, NULL);
- return true;
+ return true;
}
static struct gui_misc_table monkey_misc_table = {
- .schedule = monkey_schedule,
- .warning = monkey_warn_user,
+ .schedule = monkey_schedule,
+ .warning = monkey_warn_user,
- .quit = monkey_quit,
- .launch_url = gui_launch_url,
- .cert_verify = gui_cert_verify,
- .login = gui_401login_open,
+ .quit = monkey_quit,
+ .launch_url = gui_launch_url,
+ .cert_verify = gui_cert_verify,
+ .login = gui_401login_open,
};
static void monkey_run(void)
{
- fd_set read_fd_set, write_fd_set, exc_fd_set;
- int max_fd;
- int rdy_fd;
- int schedtm;
- struct timeval tv;
- struct timeval* timeout;
-
- while (!monkey_done) {
-
- /* clears fdset */
- fetch_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
-
- /* add stdin to the set */
- if (max_fd < 0) {
- max_fd = 0;
- }
- FD_SET(0, &read_fd_set);
- FD_SET(0, &exc_fd_set);
-
- /* discover the next scheduled event time */
- schedtm = monkey_schedule_run();
-
- /* setup timeout */
- switch (schedtm) {
- case -1:
- LOG("Iterate blocking");
- fprintf(stdout, "GENERIC POLL BLOCKING\n");
- timeout = NULL;
- break;
-
- case 0:
- LOG("Iterate immediate");
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- timeout = &tv;
- break;
-
- default:
- LOG("Iterate non-blocking");
- fprintf(stdout, "GENERIC POLL TIMED\n");
- tv.tv_sec = schedtm / 1000; /* miliseconds to seconds */
- tv.tv_usec = (schedtm % 1000) * 1000; /* remainder to microseconds */
- timeout = &tv;
- break;
- }
-
- rdy_fd = select(max_fd + 1,
- &read_fd_set,
- &write_fd_set,
- &exc_fd_set,
- timeout);
- if (rdy_fd < 0) {
- monkey_done = true;
- } else if (rdy_fd > 0) {
- if (FD_ISSET(0, &read_fd_set)) {
- monkey_process_command();
- }
- }
- }
-
+ fd_set read_fd_set, write_fd_set, exc_fd_set;
+ int max_fd;
+ int rdy_fd;
+ int schedtm;
+ struct timeval tv;
+ struct timeval* timeout;
+
+ while (!monkey_done) {
+
+ /* clears fdset */
+ fetch_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
+
+ /* add stdin to the set */
+ if (max_fd < 0) {
+ max_fd = 0;
+ }
+ FD_SET(0, &read_fd_set);
+ FD_SET(0, &exc_fd_set);
+
+ /* discover the next scheduled event time */
+ schedtm = monkey_schedule_run();
+
+ /* setup timeout */
+ switch (schedtm) {
+ case -1:
+ LOG("Iterate blocking");
+ fprintf(stdout, "GENERIC POLL BLOCKING\n");
+ timeout = NULL;
+ break;
+
+ case 0:
+ LOG("Iterate immediate");
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ timeout = &tv;
+ break;
+
+ default:
+ LOG("Iterate non-blocking");
+ fprintf(stdout, "GENERIC POLL TIMED %d\n", schedtm);
+ tv.tv_sec = schedtm / 1000; /* miliseconds to seconds */
+ tv.tv_usec = (schedtm % 1000) * 1000; /* remainder to microseconds */
+ timeout = &tv;
+ break;
+ }
+
+ rdy_fd = select(max_fd + 1,
+ &read_fd_set,
+ &write_fd_set,
+ &exc_fd_set,
+ timeout);
+ if (rdy_fd < 0) {
+ monkey_done = true;
+ } else if (rdy_fd > 0) {
+ if (FD_ISSET(0, &read_fd_set)) {
+ monkey_process_command();
+ }
+ }
+ }
}
int
main(int argc, char **argv)
{
- char *messages;
- char *options;
- char buf[PATH_MAX];
- nserror ret;
- struct netsurf_table monkey_table = {
- .misc = &monkey_misc_table,
- .window = monkey_window_table,
- .download = monkey_download_table,
- .fetch = monkey_fetch_table,
- .bitmap = monkey_bitmap_table,
- .layout = monkey_layout_table,
- };
-
- ret = netsurf_register(&monkey_table);
- if (ret != NSERROR_OK) {
- die("NetSurf operation table failed registration");
- }
-
- /* Unbuffer stdin/out/err */
- setbuf(stdin, NULL);
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
-
- /* Prep the search paths */
- respaths = nsmonkey_init_resource("${HOME}/.netsurf/:${NETSURFRES}:"MONKEY_RESPATH":./monkey/res");
-
- /* initialise logging. Not fatal if it fails but not much we can do
- * about it either.
- */
- nslog_init(nslog_stream_configure, &argc, argv);
-
- /* user options setup */
- ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default);
- if (ret != NSERROR_OK) {
- die("Options failed to initialise");
- }
- options = filepath_find(respaths, "Choices");
- nsoption_read(options, nsoptions);
- free(options);
- nsoption_commandline(&argc, argv, nsoptions);
-
- messages = filepath_find(respaths, "Messages");
- ret = messages_add_from_file(messages);
- if (ret != NSERROR_OK) {
- LOG("Messages failed to load");
- }
-
- /* common initialisation */
- ret = netsurf_init(NULL);
- free(messages);
- if (ret != NSERROR_OK) {
- die("NetSurf failed to initialise");
- }
-
- filepath_sfinddef(respaths, buf, "mime.types", "/etc/");
- monkey_fetch_filetype_init(buf);
-
- urldb_load(nsoption_charp(url_file));
- urldb_load_cookies(nsoption_charp(cookie_file));
-
- ret = monkey_register_handler("QUIT", quit_handler);
- if (ret != NSERROR_OK) {
- die("quit handler failed to register");
- }
-
- ret = monkey_register_handler("WINDOW", monkey_window_handle_command);
- if (ret != NSERROR_OK) {
- die("window handler fialed to register");
- }
-
- fprintf(stdout, "GENERIC STARTED\n");
- monkey_run();
-
- fprintf(stdout, "GENERIC CLOSING_DOWN\n");
- monkey_kill_browser_windows();
-
- netsurf_exit();
- fprintf(stdout, "GENERIC FINISHED\n");
-
- /* finalise options */
- nsoption_finalise(nsoptions, nsoptions_default);
-
- return 0;
+ char *messages;
+ char *options;
+ char buf[PATH_MAX];
+ nserror ret;
+ struct netsurf_table monkey_table = {
+ .misc = &monkey_misc_table,
+ .window = monkey_window_table,
+ .download = monkey_download_table,
+ .fetch = monkey_fetch_table,
+ .bitmap = monkey_bitmap_table,
+ .layout = monkey_layout_table,
+ };
+
+ ret = netsurf_register(&monkey_table);
+ if (ret != NSERROR_OK) {
+ die("NetSurf operation table failed registration");
+ }
+
+ /* Unbuffer stdin/out/err */
+ setbuf(stdin, NULL);
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+
+ /* Prep the search paths */
+ respaths = nsmonkey_init_resource("${HOME}/.netsurf/:${NETSURFRES}:"MONKEY_RESPATH":./frontends/monkey/res");
+
+ /* initialise logging. Not fatal if it fails but not much we can do
+ * about it either.
+ */
+ nslog_init(nslog_stream_configure, &argc, argv);
+
+ /* user options setup */
+ ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default);
+ if (ret != NSERROR_OK) {
+ die("Options failed to initialise");
+ }
+ options = filepath_find(respaths, "Choices");
+ nsoption_read(options, nsoptions);
+ free(options);
+ nsoption_commandline(&argc, argv, nsoptions);
+
+ messages = filepath_find(respaths, "Messages");
+ ret = messages_add_from_file(messages);
+ if (ret != NSERROR_OK) {
+ LOG("Messages failed to load");
+ }
+
+ /* common initialisation */
+ ret = netsurf_init(NULL);
+ free(messages);
+ if (ret != NSERROR_OK) {
+ die("NetSurf failed to initialise");
+ }
+
+ filepath_sfinddef(respaths, buf, "mime.types", "/etc/");
+ monkey_fetch_filetype_init(buf);
+
+ urldb_load(nsoption_charp(url_file));
+ urldb_load_cookies(nsoption_charp(cookie_file));
+
+ ret = monkey_register_handler("QUIT", quit_handler);
+ if (ret != NSERROR_OK) {
+ die("quit handler failed to register");
+ }
+
+ ret = monkey_register_handler("WINDOW", monkey_window_handle_command);
+ if (ret != NSERROR_OK) {
+ die("window handler failed to register");
+ }
+
+ ret = monkey_register_handler("OPTIONS", monkey_options_handle_command);
+ if (ret != NSERROR_OK) {
+ die("options handler failed to register");
+ }
+
+ fprintf(stdout, "GENERIC STARTED\n");
+ monkey_run();
+
+ fprintf(stdout, "GENERIC CLOSING_DOWN\n");
+ monkey_kill_browser_windows();
+
+ netsurf_exit();
+ fprintf(stdout, "GENERIC FINISHED\n");
+
+ /* finalise options */
+ nsoption_finalise(nsoptions, nsoptions_default);
+
+ return 0;
}
diff --git a/frontends/monkey/plot.c b/frontends/monkey/plot.c
index 7ed2205..d00dca7 100644
--- a/frontends/monkey/plot.c
+++ b/frontends/monkey/plot.c
@@ -58,8 +58,8 @@ monkey_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
*/
static nserror
monkey_plot_arc(const struct redraw_context *ctx,
- const plot_style_t *style,
- int x, int y, int radius, int angle1, int angle2)
+ const plot_style_t *style,
+ int x, int y, int radius, int angle1, int angle2)
{
fprintf(stdout,
"PLOT ARC X %d Y %d RADIUS %d ANGLE1 %d ANGLE2 %d\n",
@@ -82,8 +82,8 @@ monkey_plot_arc(const struct redraw_context *ctx,
*/
static nserror
monkey_plot_disc(const struct redraw_context *ctx,
- const plot_style_t *style,
- int x, int y, int radius)
+ const plot_style_t *style,
+ int x, int y, int radius)
{
fprintf(stdout,
"PLOT DISC X %d Y %d RADIUS %d\n",
@@ -105,8 +105,8 @@ monkey_plot_disc(const struct redraw_context *ctx,
*/
static nserror
monkey_plot_line(const struct redraw_context *ctx,
- const plot_style_t *style,
- const struct rect *line)
+ const plot_style_t *style,
+ const struct rect *line)
{
fprintf(stdout,
"PLOT LINE X0 %d Y0 %d X1 %d Y1 %d\n",
@@ -130,8 +130,8 @@ monkey_plot_line(const struct redraw_context *ctx,
*/
static nserror
monkey_plot_rectangle(const struct redraw_context *ctx,
- const plot_style_t *style,
- const struct rect *rect)
+ const plot_style_t *style,
+ const struct rect *rect)
{
fprintf(stdout,
"PLOT RECT X0 %d Y0 %d X1 %d Y1 %d\n",
@@ -156,9 +156,9 @@ monkey_plot_rectangle(const struct redraw_context *ctx,
*/
static nserror
monkey_plot_polygon(const struct redraw_context *ctx,
- const plot_style_t *style,
- const int *p,
- unsigned int n)
+ const plot_style_t *style,
+ const int *p,
+ unsigned int n)
{
fprintf(stdout,
"PLOT POLYGON VERTICIES %d\n",
@@ -183,11 +183,11 @@ monkey_plot_polygon(const struct redraw_context *ctx,
*/
static nserror
monkey_plot_path(const struct redraw_context *ctx,
- const plot_style_t *pstyle,
- const float *p,
- unsigned int n,
- float width,
- const float transform[6])
+ const plot_style_t *pstyle,
+ const float *p,
+ unsigned int n,
+ float width,
+ const float transform[6])
{
fprintf(stdout,
"PLOT PATH VERTICIES %d WIDTH %f\n",
@@ -222,12 +222,12 @@ monkey_plot_path(const struct redraw_context *ctx,
*/
static nserror
monkey_plot_bitmap(const struct redraw_context *ctx,
- struct bitmap *bitmap,
- int x, int y,
- int width,
- int height,
- colour bg,
- bitmap_flags_t flags)
+ struct bitmap *bitmap,
+ int x, int y,
+ int width,
+ int height,
+ colour bg,
+ bitmap_flags_t flags)
{
fprintf(stdout,
"PLOT BITMAP X %d Y %d WIDTH %d HEIGHT %d\n",
@@ -249,11 +249,11 @@ monkey_plot_bitmap(const struct redraw_context *ctx,
*/
static nserror
monkey_plot_text(const struct redraw_context *ctx,
- const struct plot_font_style *fstyle,
- int x,
- int y,
- const char *text,
- size_t length)
+ const struct plot_font_style *fstyle,
+ int x,
+ int y,
+ const char *text,
+ size_t length)
{
fprintf(stdout,
"PLOT TEXT X %d Y %d STR %*s\n",
diff --git a/frontends/monkey/schedule.c b/frontends/monkey/schedule.c
index 8c638c0..af1144a 100644
--- a/frontends/monkey/schedule.c
+++ b/frontends/monkey/schedule.c
@@ -38,10 +38,10 @@ static struct nscallback *schedule_list = NULL;
*/
struct nscallback
{
- struct nscallback *next;
- struct timeval tv;
- void (*callback)(void *p);
- void *p;
+ struct nscallback *next;
+ struct timeval tv;
+ void (*callback)(void *p);
+ void *p;
};
/**
@@ -54,170 +54,163 @@ struct nscallback
*/
static nserror schedule_remove(void (*callback)(void *p), void *p)
{
- struct nscallback *cur_nscb;
- struct nscallback *prev_nscb;
- struct nscallback *unlnk_nscb;
-
- /* check there is something on the list to remove */
- if (schedule_list == NULL) {
- return NSERROR_OK;
- }
-
- SRLOG("removing %p, %p", callback, p);
-
- cur_nscb = schedule_list;
- prev_nscb = NULL;
-
- while (cur_nscb != NULL) {
- if ((cur_nscb->callback == callback) &&
- (cur_nscb->p == p)) {
- /* item to remove */
-
- SRLOG("callback entry %p removing %p(%p)",
- cur_nscb, cur_nscb->callback, cur_nscb->p);
-
- /* remove callback */
- unlnk_nscb = cur_nscb;
- cur_nscb = unlnk_nscb->next;
-
- if (prev_nscb == NULL) {
- schedule_list = cur_nscb;
- } else {
- prev_nscb->next = cur_nscb;
- }
- free (unlnk_nscb);
- } else {
- /* move to next element */
- prev_nscb = cur_nscb;
- cur_nscb = prev_nscb->next;
- }
- }
-
- return NSERROR_OK;
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+
+ /* check there is something on the list to remove */
+ if (schedule_list == NULL) {
+ return NSERROR_OK;
+ }
+
+ SRLOG("removing %p, %p", callback, p);
+
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+
+ while (cur_nscb != NULL) {
+ if ((cur_nscb->callback == callback) &&
+ (cur_nscb->p == p)) {
+ /* item to remove */
+
+ SRLOG("callback entry %p removing %p(%p)",
+ cur_nscb, cur_nscb->callback, cur_nscb->p);
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+ cur_nscb = unlnk_nscb->next;
+
+ if (prev_nscb == NULL) {
+ schedule_list = cur_nscb;
+ } else {
+ prev_nscb->next = cur_nscb;
+ }
+ free (unlnk_nscb);
+ } else {
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ return NSERROR_OK;
}
-/* exported function documented in framebuffer/schedule.h */
+/* exported function documented in monkey/schedule.h */
nserror monkey_schedule(int tival, void (*callback)(void *p), void *p)
{
- struct nscallback *nscb;
- struct timeval tv;
- nserror ret;
+ struct nscallback *nscb;
+ struct timeval tv;
+ nserror ret;
- /* ensure uniqueness of the callback and context */
- ret = schedule_remove(callback, p);
- if ((tival < 0) || (ret != NSERROR_OK)) {
- return ret;
- }
+ /* ensure uniqueness of the callback and context */
+ ret = schedule_remove(callback, p);
+ if ((tival < 0) || (ret != NSERROR_OK)) {
+ return ret;
+ }
- SRLOG("Adding %p(%p) in %d", callback, p, tival);
+ SRLOG("Adding %p(%p) in %d", callback, p, tival);
- tv.tv_sec = tival / 1000; /* miliseconds to seconds */
- tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */
+ tv.tv_sec = tival / 1000; /* miliseconds to seconds */
+ tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */
- nscb = calloc(1, sizeof(struct nscallback));
+ nscb = calloc(1, sizeof(struct nscallback));
- gettimeofday(&nscb->tv, NULL);
- timeradd(&nscb->tv, &tv, &nscb->tv);
+ gettimeofday(&nscb->tv, NULL);
+ timeradd(&nscb->tv, &tv, &nscb->tv);
- nscb->callback = callback;
- nscb->p = p;
+ nscb->callback = callback;
+ nscb->p = p;
- /* add to list front */
- nscb->next = schedule_list;
- schedule_list = nscb;
+ /* add to list front */
+ nscb->next = schedule_list;
+ schedule_list = nscb;
- return NSERROR_OK;
+ return NSERROR_OK;
}
-/* exported function documented in framebuffer/schedule.h */
+/* exported function documented in monkey/schedule.h */
int monkey_schedule_run(void)
{
- struct timeval tv;
- struct timeval nexttime;
- struct timeval rettime;
- struct nscallback *cur_nscb;
- struct nscallback *prev_nscb;
- struct nscallback *unlnk_nscb;
-
- if (schedule_list == NULL)
- return -1;
-
- /* reset enumeration to the start of the list */
- cur_nscb = schedule_list;
- prev_nscb = NULL;
- nexttime = cur_nscb->tv;
-
- gettimeofday(&tv, NULL);
-
- while (cur_nscb != NULL) {
- if (timercmp(&tv, &cur_nscb->tv, >)) {
- /* scheduled time */
-
- /* remove callback */
- unlnk_nscb = cur_nscb;
-
- if (prev_nscb == NULL) {
- schedule_list = unlnk_nscb->next;
- } else {
- prev_nscb->next = unlnk_nscb->next;
- }
-
- unlnk_nscb->callback(unlnk_nscb->p);
-
- free(unlnk_nscb);
-
- /* need to deal with callback modifying the list. */
- if (schedule_list == NULL)
- return -1; /* no more callbacks scheduled */
-
- /* reset enumeration to the start of the list */
- cur_nscb = schedule_list;
- prev_nscb = NULL;
- nexttime = cur_nscb->tv;
- } else {
- /* if the time to the event is sooner than the
- * currently recorded soonest event record it
- */
- if (timercmp(&nexttime, &cur_nscb->tv, >)) {
+ struct timeval tv;
+ struct timeval nexttime;
+ struct timeval rettime;
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+
+ if (schedule_list == NULL)
+ return -1;
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
nexttime = cur_nscb->tv;
- }
- /* move to next element */
- prev_nscb = cur_nscb;
- cur_nscb = prev_nscb->next;
- }
- }
- /* make rettime relative to now */
- timersub(&nexttime, &tv, &rettime);
-
- SRLOG("returning time to next event as %ldms",
- (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
-
- /* return next event time in milliseconds (24days max wait) */
- return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
+ gettimeofday(&tv, NULL);
+
+ while (cur_nscb != NULL) {
+ if (timercmp(&tv, &cur_nscb->tv, >)) {
+ /* scheduled time */
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+
+ if (prev_nscb == NULL) {
+ schedule_list = unlnk_nscb->next;
+ } else {
+ prev_nscb->next = unlnk_nscb->next;
+ }
+
+ unlnk_nscb->callback(unlnk_nscb->p);
+
+ free(unlnk_nscb);
+
+ /* need to deal with callback modifying the list. */
+ if (schedule_list == NULL)
+ return -1; /* no more callbacks scheduled */
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+ } else {
+ /* if the time to the event is sooner than the
+ * currently recorded soonest event record it
+ */
+ if (timercmp(&nexttime, &cur_nscb->tv, >)) {
+ nexttime = cur_nscb->tv;
+ }
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ /* make rettime relative to now */
+ timersub(&nexttime, &tv, &rettime);
+
+ SRLOG("returning time to next event as %ldms",
+ (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
+
+ /* return next event time in milliseconds (24days max wait) */
+ return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
}
void monkey_schedule_list(void)
{
- struct timeval tv;
- struct nscallback *cur_nscb;
+ struct timeval tv;
+ struct nscallback *cur_nscb;
- gettimeofday(&tv, NULL);
+ gettimeofday(&tv, NULL);
- LOG("schedule list at %lld:%ld", (long long)tv.tv_sec, tv.tv_usec);
+ LOG("schedule list at %lld:%ld", (long long)tv.tv_sec, tv.tv_usec);
- cur_nscb = schedule_list;
+ cur_nscb = schedule_list;
- while (cur_nscb != NULL) {
- LOG("Schedule %p at %lld:%ld",
- cur_nscb, (long long)cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
- cur_nscb = cur_nscb->next;
- }
+ while (cur_nscb != NULL) {
+ LOG("Schedule %p at %lld:%ld",
+ cur_nscb, (long long)cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
+ cur_nscb = cur_nscb->next;
+ }
}
-
-
-/*
- * Local Variables:
- * c-basic-offset:2
- * End:
- */
diff --git a/frontends/riscos/cookies.c b/frontends/riscos/cookies.c
index 38963ab..614bc3d 100644
--- a/frontends/riscos/cookies.c
+++ b/frontends/riscos/cookies.c
@@ -377,7 +377,7 @@ static nserror ro_cookie_init(void)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct ro_cookie_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/riscos/corewindow.c b/frontends/riscos/corewindow.c
index a885977..77dd1c3 100644
--- a/frontends/riscos/corewindow.c
+++ b/frontends/riscos/corewindow.c
@@ -42,6 +42,7 @@
#include "riscos/wimp_event.h"
#include "riscos/dialog.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/toolbar.h"
#include "riscos/mouse.h"
#include "riscos/corewindow.h"
diff --git a/frontends/riscos/dialog.c b/frontends/riscos/dialog.c
index 7a0197c..6414778 100644
--- a/frontends/riscos/dialog.c
+++ b/frontends/riscos/dialog.c
@@ -47,6 +47,7 @@
#include "riscos/local_history.h"
#include "riscos/global_history.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/hotlist.h"
#include "riscos/menus.h"
#include "riscos/save.h"
diff --git a/frontends/riscos/global_history.c b/frontends/riscos/global_history.c
index 94e1d4a..d122a4d 100644
--- a/frontends/riscos/global_history.c
+++ b/frontends/riscos/global_history.c
@@ -405,7 +405,7 @@ static nserror ro_global_history_init(void)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct ro_global_history_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/riscos/gui.h b/frontends/riscos/gui.h
index 35be4e1..49a8ba4 100644
--- a/frontends/riscos/gui.h
+++ b/frontends/riscos/gui.h
@@ -139,35 +139,6 @@ void ro_gui_401login_init(void);
void gui_401login_open(struct nsurl *url, const char *realm,
nserror (*cb)(bool proceed, void *pw), void *cbpw);
-/* in window.c */
-void ro_gui_window_set_scale(struct gui_window *g, float scale);
-bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message);
-void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data);
-void ro_gui_window_iconise(struct gui_window *g,
- wimp_full_message_window_info *wi);
-bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message);
-void ro_gui_window_redraw_all(void);
-void ro_gui_window_update_boxes(void);
-void ro_gui_window_quit(void);
-/* void ro_gui_window_close_all(void); */
-#define ro_gui_window_close_all ro_gui_window_quit /* no need for a separate fn */
-void ro_gui_throb(void);
-void ro_gui_window_default_options(struct gui_window *gui);
-struct gui_window *ro_gui_window_lookup(wimp_w window);
-struct gui_window *ro_gui_toolbar_lookup(wimp_w window);
-bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
- os_coord *pos);
-bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
- os_coord *pos);
-enum browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
- wimp_icon_flags type);
-enum browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
- wimp_icon_flags type);
-bool ro_gui_shift_pressed(void);
-bool ro_gui_ctrl_pressed(void);
-bool ro_gui_alt_pressed(void);
-void gui_window_set_pointer(struct gui_window *g, enum gui_pointer_shape shape);
-
/* in schedule.c */
extern bool sched_active;
extern os_t sched_time;
diff --git a/frontends/riscos/hotlist.c b/frontends/riscos/hotlist.c
index d348009..b055d1b 100644
--- a/frontends/riscos/hotlist.c
+++ b/frontends/riscos/hotlist.c
@@ -466,7 +466,7 @@ static nserror ro_hotlist_init(void)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct ro_hotlist_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/riscos/local_history.c b/frontends/riscos/local_history.c
index fae78e6..f9f1f2e 100644
--- a/frontends/riscos/local_history.c
+++ b/frontends/riscos/local_history.c
@@ -28,6 +28,7 @@
#include "utils/nsoption.h"
#include "utils/messages.h"
#include "utils/log.h"
+#include "utils/nsurl.h"
#include "netsurf/window.h"
#include "netsurf/plotters.h"
#include "netsurf/keypress.h"
@@ -90,7 +91,7 @@ ro_local_history_draw(struct ro_corewindow *ro_cw,
ro_plot_origin_x = originx;
ro_plot_origin_y = originy;
no_font_blending = true;
- local_history_redraw(lhw->session, r->x0, r->y0, r, &ctx);
+ local_history_redraw(lhw->session, 0, 0, r, &ctx);
no_font_blending = false;
return NSERROR_OK;
@@ -127,7 +128,7 @@ static nserror
ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
{
int width;
- const char *url;
+ nsurl *url;
wimp_window_state state;
wimp_icon_state ic;
os_box box = {0, 0, 0, 0};
@@ -162,17 +163,19 @@ ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y)
}
/* get width of string */
- error = xwimptextop_string_width(url,
- strlen(url) > 256 ? 256 : strlen(url),
+ error = xwimptextop_string_width(nsurl_access(url),
+ nsurl_length(url) > 256 ? 256 : nsurl_length(url),
&width);
if (error) {
LOG("xwimptextop_string_width: 0x%x: %s",
error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
+ nsurl_unref(url);
return NSERROR_NOMEM;
}
- ro_gui_set_icon_string(dialog_tooltip, 0, url, true);
+ ro_gui_set_icon_string(dialog_tooltip, 0, nsurl_access(url), true);
+ nsurl_unref(url);
/* resize icon appropriately */
ic.w = dialog_tooltip;
@@ -296,7 +299,7 @@ ro_local_history_init(struct browser_window *bw,
return res;
}
- ncwin = malloc(sizeof(struct ro_local_history_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/riscos/save.c b/frontends/riscos/save.c
index 37474b8..bed0f5d 100644
--- a/frontends/riscos/save.c
+++ b/frontends/riscos/save.c
@@ -56,6 +56,7 @@
#include "riscos/bitmap.h"
#include "riscos/dialog.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/menus.h"
#include "riscos/message.h"
#include "riscos/mouse.h"
diff --git a/frontends/riscos/textselection.c b/frontends/riscos/textselection.c
index bce3575..5a430c0 100644
--- a/frontends/riscos/textselection.c
+++ b/frontends/riscos/textselection.c
@@ -36,6 +36,7 @@
#include "netsurf/browser_window.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/menus.h"
#include "riscos/message.h"
#include "riscos/mouse.h"
diff --git a/frontends/riscos/url_complete.c b/frontends/riscos/url_complete.c
index 3ca9be4..16c6e3a 100644
--- a/frontends/riscos/url_complete.c
+++ b/frontends/riscos/url_complete.c
@@ -36,6 +36,7 @@
#include "riscos/global_history.h"
#include "riscos/gui.h"
+#include "riscos/window.h"
#include "riscos/mouse.h"
#include "riscos/toolbar.h"
#include "riscos/url_complete.h"
diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c
index de0fcab..6dbcc32 100644
--- a/frontends/riscos/window.c
+++ b/frontends/riscos/window.c
@@ -35,6 +35,7 @@
#include <stdint.h>
#include <time.h>
#include <string.h>
+#include <limits.h>
#include <oslib/colourtrans.h>
#include <oslib/osbyte.h>
#include <oslib/osfile.h>
@@ -63,7 +64,6 @@
#include "netsurf/keypress.h"
#include "desktop/browser_history.h"
#include "desktop/cookie_manager.h"
-#include "desktop/scrollbar.h"
#include "riscos/bitmap.h"
#include "riscos/buffer.h"
@@ -91,70 +91,6 @@
#include "riscos/ucstables.h"
#include "riscos/filetype.h"
-static void gui_window_set_extent(struct gui_window *g, int width, int height);
-
-static void ro_gui_window_redraw(wimp_draw *redraw);
-static void ro_gui_window_scroll(wimp_scroll *scroll);
-static void ro_gui_window_pointer_entering(wimp_entering *entering);
-static void ro_gui_window_track_end(wimp_leaving *leaving, void *data);
-static void ro_gui_window_open(wimp_open *open);
-static void ro_gui_window_close(wimp_w w);
-static bool ro_gui_window_click(wimp_pointer *mouse);
-static bool ro_gui_window_keypress(wimp_key *key);
-static bool ro_gui_window_toolbar_keypress(void *data, wimp_key *key);
-static bool ro_gui_window_handle_local_keypress(struct gui_window *g,
- wimp_key *key, bool is_toolbar);
-static bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
- wimp_pointer *pointer);
-static void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
- wimp_selection *selection, menu_action action);
-static bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
- wimp_selection *selection, menu_action action);
-static void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu);
-
-static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data);
-
-static void ro_gui_window_scroll_action(struct gui_window *g,
- int scroll_x, int scroll_y);
-
-static void ro_gui_window_toolbar_click(void *data,
- toolbar_action_type action_type, union toolbar_action action);
-
-static bool ro_gui_window_content_export_types(struct hlcache_handle *h,
- bool *export_draw, bool *export_sprite);
-static void ro_gui_window_prepare_pageinfo(struct gui_window *g);
-static void ro_gui_window_prepare_objectinfo(struct hlcache_handle *object,
- nsurl *target_url);
-
-static void ro_gui_window_launch_url(struct gui_window *g, const char *url);
-static void ro_gui_window_action_home(struct gui_window *g);
-static void ro_gui_window_action_new_window(struct gui_window *g);
-static void ro_gui_window_action_local_history(struct gui_window *g);
-static void ro_gui_window_action_save(struct gui_window *g,
- gui_save_type save_type);
-static void ro_gui_window_action_search(struct gui_window *g);
-static void ro_gui_window_action_zoom(struct gui_window *g);
-static void ro_gui_window_action_add_bookmark(struct gui_window *g);
-static void ro_gui_window_action_remove_bookmark(struct gui_window *g);
-static void ro_gui_window_action_print(struct gui_window *g);
-static void ro_gui_window_action_page_info(struct gui_window *g);
-
-static void ro_gui_window_remove_update_boxes(struct gui_window *g);
-static void ro_gui_window_update_toolbar_buttons(struct gui_window *g);
-static void ro_gui_window_update_toolbar(void *data);
-static void ro_gui_window_save_toolbar_buttons(void *data, char *config);
-static void ro_gui_window_update_theme(void *data, bool ok);
-
-static bool ro_gui_window_import_text(struct gui_window *g,
- const char *filename);
-static void ro_gui_window_clone_options(
- struct gui_window *new_gui,
- struct gui_window *old_gui);
-
-static bool ro_gui_window_prepare_form_select_menu(struct gui_window *bw,
- struct form_control *control);
-static void ro_gui_window_process_form_select_menu(struct gui_window *g,
- wimp_selection *selection);
#ifndef wimp_KEY_END
#define wimp_KEY_END wimp_KEY_COPY
@@ -167,6 +103,11 @@ static void ro_gui_window_process_form_select_menu(struct gui_window *g,
#define SCROLL_VISIBLE_PADDING 32
+#define SCROLL_TOP INT_MIN
+#define SCROLL_PAGE_UP (INT_MIN + 1)
+#define SCROLL_PAGE_DOWN (INT_MAX - 1)
+#define SCROLL_BOTTOM INT_MAX
+
/** Remembers which iconised sprite numbers are in use */
static bool iconise_used[64];
static int iconise_next = 0;
@@ -205,7 +146,8 @@ struct ro_gui_pointer_entry {
int yactive;
};
-/** Map from gui_pointer_shape to pointer sprite data. Must be ordered as
+/**
+ * Map from gui_pointer_shape to pointer sprite data. Must be ordered as
* enum gui_pointer_shape. */
struct ro_gui_pointer_entry ro_gui_pointer_table[] = {
{ true, "ptr_default", 0, 0 },
@@ -242,143 +184,22 @@ struct update_box {
struct update_box *pending_updates;
#define MARGIN 4
-static const struct toolbar_callbacks ro_gui_window_toolbar_callbacks = {
- ro_gui_window_update_theme,
- ro_gui_window_update_toolbar,
- (void (*)(void *)) ro_gui_window_update_toolbar_buttons,
- ro_gui_window_toolbar_click,
- ro_gui_window_toolbar_keypress,
- ro_gui_window_save_toolbar_buttons
-};
-
-
-/**
- * Initialise the browser window module and its menus.
- */
-
-void ro_gui_window_initialise(void)
-{
- /* Build the browser window menu. */
-
- static const struct ns_menu browser_definition = {
- "NetSurf", {
- { "Page", BROWSER_PAGE, 0 },
- { "Page.PageInfo",BROWSER_PAGE_INFO, &dialog_pageinfo },
- { "Page.Save", BROWSER_SAVE, &dialog_saveas },
- { "Page.SaveComp", BROWSER_SAVE_COMPLETE, &dialog_saveas },
- { "Page.Export", NO_ACTION, 0 },
-#ifdef WITH_DRAW_EXPORT
- { "Page.Export.Draw", BROWSER_EXPORT_DRAW, &dialog_saveas },
-#endif
-#ifdef WITH_PDF_EXPORT
- { "Page.Export.PDF", BROWSER_EXPORT_PDF, &dialog_saveas },
-#endif
- { "Page.Export.Text", BROWSER_EXPORT_TEXT, &dialog_saveas },
- { "Page.SaveURL", NO_ACTION, 0 },
- { "Page.SaveURL.URI", BROWSER_SAVE_URL_URI, &dialog_saveas },
- { "Page.SaveURL.URL", BROWSER_SAVE_URL_URL, &dialog_saveas },
- { "Page.SaveURL.LinkText", BROWSER_SAVE_URL_TEXT, &dialog_saveas },
- { "_Page.Print", BROWSER_PRINT, &dialog_print },
- { "Page.NewWindow", BROWSER_NEW_WINDOW, 0 },
- { "Page.FindText", BROWSER_FIND_TEXT, &dialog_search },
- { "Page.ViewSrc", BROWSER_VIEW_SOURCE, 0 },
- { "Object", BROWSER_OBJECT, 0 },
- { "Object.Object", BROWSER_OBJECT_OBJECT, 0 },
- { "Object.Object.ObjInfo", BROWSER_OBJECT_INFO, &dialog_objinfo },
- { "Object.Object.ObjSave", BROWSER_OBJECT_SAVE, &dialog_saveas },
- { "Object.Object.Export", BROWSER_OBJECT_EXPORT, 0 },
- { "Object.Object.Export.Sprite", BROWSER_OBJECT_EXPORT_SPRITE, &dialog_saveas },
-#ifdef WITH_DRAW_EXPORT
- { "Object.Object.Export.ObjDraw", BROWSER_OBJECT_EXPORT_DRAW, &dialog_saveas },
-#endif
- { "Object.Object.SaveURL", NO_ACTION, 0 },
- { "Object.Object.SaveURL.URI", BROWSER_OBJECT_SAVE_URL_URI, &dialog_saveas },
- { "Object.Object.SaveURL.URL", BROWSER_OBJECT_SAVE_URL_URL, &dialog_saveas },
- { "Object.Object.SaveURL.LinkText", BROWSER_OBJECT_SAVE_URL_TEXT, &dialog_saveas },
- { "Object.Object.ObjPrint", BROWSER_OBJECT_PRINT, 0 },
- { "Object.Object.ObjReload", BROWSER_OBJECT_RELOAD, 0 },
- { "Object.Link", BROWSER_OBJECT_LINK, 0 },
- { "Object.Link.LinkSave", BROWSER_LINK_SAVE, 0 },
- { "Object.Link.LinkSave.URI", BROWSER_LINK_SAVE_URI, &dialog_saveas },
- { "Object.Link.LinkSave.URL", BROWSER_LINK_SAVE_URL, &dialog_saveas },
- { "Object.Link.LinkSave.LinkText", BROWSER_LINK_SAVE_TEXT, &dialog_saveas },
- { "_Object.Link.LinkDload", BROWSER_LINK_DOWNLOAD, 0 },
- { "Object.Link.LinkNew", BROWSER_LINK_NEW_WINDOW, 0 },
- { "Selection", BROWSER_SELECTION, 0 },
- { "_Selection.SelSave", BROWSER_SELECTION_SAVE, &dialog_saveas },
- { "Selection.Copy", BROWSER_SELECTION_COPY, 0 },
- { "Selection.Cut", BROWSER_SELECTION_CUT, 0 },
- { "_Selection.Paste", BROWSER_SELECTION_PASTE, 0 },
- { "Selection.Clear", BROWSER_SELECTION_CLEAR, 0 },
- { "Selection.SelectAll", BROWSER_SELECTION_ALL, 0 },
- { "Navigate", NO_ACTION, 0 },
- { "Navigate.Home", BROWSER_NAVIGATE_HOME, 0 },
- { "Navigate.Back", BROWSER_NAVIGATE_BACK, 0 },
- { "Navigate.Forward", BROWSER_NAVIGATE_FORWARD, 0 },
- { "_Navigate.UpLevel", BROWSER_NAVIGATE_UP, 0 },
- { "Navigate.Reload", BROWSER_NAVIGATE_RELOAD_ALL, 0 },
- { "Navigate.Stop", BROWSER_NAVIGATE_STOP, 0 },
- { "View", NO_ACTION, 0 },
- { "View.ScaleView", BROWSER_SCALE_VIEW, &dialog_zoom },
- { "View.Images", NO_ACTION, 0 },
- { "View.Images.ForeImg", BROWSER_IMAGES_FOREGROUND, 0 },
- { "View.Images.BackImg", BROWSER_IMAGES_BACKGROUND, 0 },
- { "View.Toolbars", NO_ACTION, 0 },
- { "View.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
- { "View.Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 },
- { "_View.Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 },
- { "View.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 },
- { "_View.Render", NO_ACTION, 0 },
- { "View.Render.RenderAnims", BROWSER_BUFFER_ANIMS, 0 },
- { "View.Render.RenderAll", BROWSER_BUFFER_ALL, 0 },
- { "_View.OptDefault", BROWSER_SAVE_VIEW, 0 },
- { "View.Window", NO_ACTION, 0 },
- { "View.Window.WindowSave", BROWSER_WINDOW_DEFAULT, 0 },
- { "View.Window.WindowStagr", BROWSER_WINDOW_STAGGER, 0 },
- { "_View.Window.WindowSize", BROWSER_WINDOW_COPY, 0 },
- { "View.Window.WindowReset", BROWSER_WINDOW_RESET, 0 },
- { "Utilities", NO_ACTION, 0 },
- { "Utilities.Hotlist", HOTLIST_SHOW, 0 },
- { "Utilities.Hotlist.HotlistAdd", HOTLIST_ADD_URL, 0 },
- { "Utilities.Hotlist.HotlistShow", HOTLIST_SHOW, 0 },
- { "Utilities.History", HISTORY_SHOW_GLOBAL, 0 },
- { "Utilities.History.HistLocal", HISTORY_SHOW_LOCAL, 0 },
- { "Utilities.History.HistGlobal", HISTORY_SHOW_GLOBAL, 0 },
- { "Utilities.Cookies", COOKIES_SHOW, 0 },
- { "Utilities.Cookies.ShowCookies", COOKIES_SHOW, 0 },
- { "Utilities.Cookies.DeleteCookies", COOKIES_DELETE, 0 },
- { "Help", HELP_OPEN_CONTENTS, 0 },
- { "Help.HelpContent", HELP_OPEN_CONTENTS, 0 },
- { "Help.HelpGuide", HELP_OPEN_GUIDE, 0 },
- { "_Help.HelpInfo", HELP_OPEN_INFORMATION, 0 },
- { "Help.HelpCredits", HELP_OPEN_CREDITS, 0 },
- { "_Help.HelpLicence", HELP_OPEN_LICENCE, 0 },
- { "Help.HelpInter", HELP_LAUNCH_INTERACTIVE, 0 },
- {NULL, 0, 0}
- }
- };
- ro_gui_browser_window_menu =
- ro_gui_menu_define_menu(&browser_definition);
-
-}
-
-
-/*
- * Interface With Core
- */
/**
* Place the caret in a browser window.
*
- * \param g window with caret
- * \param x coordinates of caret
- * \param y coordinates of caret
- * \param height height of caret
- * \param clip clip rectangle, or NULL if none
+ * \param g window with caret
+ * \param x coordinates of caret
+ * \param y coordinates of caret
+ * \param height height of caret
+ * \param clip clip rectangle, or NULL if none
*/
-
-static void gui_window_place_caret(struct gui_window *g, int x, int y, int height,
- const struct rect *clip)
+static void
+gui_window_place_caret(struct gui_window *g,
+ int x,
+ int y,
+ int height,
+ const struct rect *clip)
{
os_error *error;
@@ -390,552 +211,229 @@ static void gui_window_place_caret(struct gui_window *g, int x, int y, int heigh
}
}
+
/**
- * Create and open a new browser window.
+ * Updates a windows extent.
*
- * \param bw bw to create gui_window for
- * \param existing an existing gui_window, may be NULL
- * \param flags flags for gui window creation
- * \return gui window, or NULL on error
+ * \param g the gui_window to update
+ * \param width the minimum width, or -1 to use window width
+ * \param height the minimum height, or -1 to use window height
*/
-
-static struct gui_window *gui_window_create(struct browser_window *bw,
- struct gui_window *existing,
- gui_window_create_flags flags)
+static void gui_window_set_extent(struct gui_window *g, int width, int height)
{
- int screen_width, screen_height;
- static int window_count = 2;
- wimp_window window;
+ int screen_width;
+ int toolbar_height = 0;
wimp_window_state state;
os_error *error;
- bool open_centred = true;
- struct gui_window *g;
- g = malloc(sizeof *g);
- if (!g) {
- ro_warn_user("NoMemory", 0);
- return 0;
+ if (g->toolbar) {
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
}
- g->bw = bw;
- g->toolbar = 0;
- g->status_bar = 0;
- g->old_width = 0;
- g->old_height = 0;
- g->update_extent = true;
- g->active = false;
- strcpy(g->title, "NetSurf");
- g->iconise_icon = -1;
- g->scale = browser_window_get_scale(bw);
- /* Set the window position */
- if (existing != NULL &&
- flags & GW_CREATE_CLONE &&
- nsoption_bool(window_size_clone)) {
- state.w = existing->window;
+ /* get the current state */
+ if ((height == -1) || (width == -1)) {
+ state.w = g->window;
error = xwimp_get_window_state(&state);
if (error) {
LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
+ return;
}
- window.visible.x0 = state.visible.x0;
- window.visible.x1 = state.visible.x1;
- window.visible.y0 = state.visible.y0 - 48;
- window.visible.y1 = state.visible.y1 - 48;
- open_centred = false;
- } else {
- int win_width, win_height;
- ro_gui_screen_size(&screen_width, &screen_height);
-
- /* Check if we have a preferred position */
- if ((nsoption_int(window_screen_width) != 0) &&
- (nsoption_int(window_screen_height) != 0)) {
- win_width = (nsoption_int(window_width) *
- screen_width) /
- nsoption_int(window_screen_width);
- win_height = (nsoption_int(window_height) *
- screen_height) /
- nsoption_int(window_screen_height);
- window.visible.x0 = (nsoption_int(window_x) *
- screen_width) /
- nsoption_int(window_screen_width);
- window.visible.y0 = (nsoption_int(window_y) *
- screen_height) /
- nsoption_int(window_screen_height);
- if (nsoption_bool(window_stagger)) {
- window.visible.y0 += 96 -
- (48 * (window_count % 5));
- }
- open_centred = false;
- if (win_width < 100)
- win_width = 100;
- if (win_height < 100)
- win_height = 100;
- } else {
-
- /* Base how we define the window height/width
- on the compile time options set */
- win_width = screen_width * 3 / 4;
- if (1600 < win_width)
- win_width = 1600;
- win_height = win_width * 3 / 4;
-
- window.visible.x0 = (screen_width - win_width) / 2;
- window.visible.y0 = ((screen_height - win_height) / 2) +
- 96 - (48 * (window_count % 5));
+ if (width == -1)
+ width = state.visible.x1 - state.visible.x0;
+ if (height == -1) {
+ height = state.visible.y1 - state.visible.y0;
+ height -= toolbar_height;
}
- window.visible.x1 = window.visible.x0 + win_width;
- window.visible.y1 = window.visible.y0 + win_height;
}
- /* General flags for a non-movable, non-resizable, no-title bar window */
- window.xscroll = 0;
- window.yscroll = 0;
- window.next = wimp_TOP;
- window.flags = wimp_WINDOW_MOVEABLE |
- wimp_WINDOW_NEW_FORMAT |
- wimp_WINDOW_VSCROLL |
- wimp_WINDOW_HSCROLL |
- wimp_WINDOW_IGNORE_XEXTENT |
- wimp_WINDOW_IGNORE_YEXTENT |
- wimp_WINDOW_SCROLL_REPEAT;
- window.title_fg = wimp_COLOUR_BLACK;
- window.title_bg = wimp_COLOUR_LIGHT_GREY;
- window.work_fg = wimp_COLOUR_LIGHT_GREY;
- window.work_bg = wimp_COLOUR_TRANSPARENT;
- window.scroll_outer = wimp_COLOUR_DARK_GREY;
- window.scroll_inner = wimp_COLOUR_MID_LIGHT_GREY;
- window.highlight_bg = wimp_COLOUR_CREAM;
- window.extra_flags = wimp_WINDOW_USE_EXTENDED_SCROLL_REQUEST |
- wimp_WINDOW_GIVE_SHADED_ICON_INFO;
- window.extent.x0 = 0;
- window.extent.y0 = -(window.visible.y1 - window.visible.y0);
- window.extent.x1 = window.visible.x1 - window.visible.x0;
- window.extent.y1 = 0;
- window.title_flags = wimp_ICON_TEXT |
- wimp_ICON_INDIRECTED |
- wimp_ICON_HCENTRED;
- window.work_flags = wimp_BUTTON_DOUBLE_CLICK_DRAG <<
- wimp_ICON_BUTTON_TYPE_SHIFT;
- window.sprite_area = wimpspriteop_AREA;
- window.xmin = 1;
- window.ymin = 1;
- window.title_data.indirected_text.text = g->title;
- window.title_data.indirected_text.validation = (char *) -1;
- window.title_data.indirected_text.size = 255;
- window.icon_count = 0;
-
- /* Add in flags */
- window.flags |= wimp_WINDOW_SIZE_ICON |
- wimp_WINDOW_BACK_ICON |
- wimp_WINDOW_CLOSE_ICON |
- wimp_WINDOW_TITLE_ICON |
- wimp_WINDOW_TOGGLE_ICON;
-
- if (open_centred) {
- int scroll_width = ro_get_vscroll_width(NULL);
- window.visible.x0 -= scroll_width;
- }
-
- error = xwimp_create_window(&window, &g->window);
- if (error) {
- LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- free(g);
- return 0;
+ /* the top-level framed window is a total pain. to get it to maximise
+ * to the top of the screen we need to fake it having a suitably large
+ * extent */
+ if (browser_window_is_frameset(g->bw)) {
+ ro_gui_screen_size(&screen_width, &height);
+ if (g->toolbar)
+ height -= ro_toolbar_full_height(g->toolbar);
+ height -= ro_get_hscroll_height(g->window);
+ height -= ro_get_title_height(g->window);
}
-
- /* Link into window list */
- g->prev = 0;
- g->next = window_list;
- if (window_list)
- window_list->prev = g;
- window_list = g;
- window_count++;
-
- /* Add in a toolbar and status bar */
- g->status_bar = ro_gui_status_bar_create(g->window,
- nsoption_int(toolbar_status_size));
- g->toolbar = ro_toolbar_create(NULL, g->window,
- THEME_STYLE_BROWSER_TOOLBAR, TOOLBAR_FLAGS_NONE,
- &ro_gui_window_toolbar_callbacks, g,
- "HelpToolbar");
- if (g->toolbar != NULL) {
- ro_toolbar_add_buttons(g->toolbar,
- brower_toolbar_buttons,
- nsoption_charp(toolbar_browser));
- ro_toolbar_add_url(g->toolbar);
- ro_toolbar_add_throbber(g->toolbar);
- ro_toolbar_rebuild(g->toolbar);
+ if (browser_window_has_content(g->bw)) {
+ int w, h;
+ browser_window_get_extents(g->bw, true, &w, &h);
+ width = max(width, w * 2);
+ height = max(height, h * 2);
}
-
- /* Register event handlers. Do this quickly, as some of the things
- * that follow will indirectly look up our user data: this MUST
- * be set first!
- */
- ro_gui_wimp_event_set_user_data(g->window, g);
- ro_gui_wimp_event_register_open_window(g->window, ro_gui_window_open);
- ro_gui_wimp_event_register_close_window(g->window, ro_gui_window_close);
- ro_gui_wimp_event_register_redraw_window(g->window, ro_gui_window_redraw);
- ro_gui_wimp_event_register_scroll_window(g->window, ro_gui_window_scroll);
- ro_gui_wimp_event_register_pointer_entering_window(g->window, ro_gui_window_pointer_entering);
- ro_gui_wimp_event_register_keypress(g->window, ro_gui_window_keypress);
- ro_gui_wimp_event_register_mouse_click(g->window, ro_gui_window_click);
- ro_gui_wimp_event_register_menu(g->window, ro_gui_browser_window_menu,
- true, false);
- ro_gui_wimp_event_register_menu_prepare(g->window,
- ro_gui_window_menu_prepare);
- ro_gui_wimp_event_register_menu_selection(g->window,
- ro_gui_window_menu_select);
- ro_gui_wimp_event_register_menu_warning(g->window,
- ro_gui_window_menu_warning);
- ro_gui_wimp_event_register_menu_close(g->window,
- ro_gui_window_menu_close);
-
- /* Set the window options */
- ro_gui_window_clone_options(g, existing);
- ro_gui_window_update_toolbar_buttons(g);
-
- /* Open the window at the top of the stack */
- state.w = g->window;
- error = xwimp_get_window_state(&state);
+ os_box extent = { 0, -height, width, toolbar_height };
+ error = xwimp_set_extent(g->window, &extent);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
- return g;
+ return;
}
-
- state.next = wimp_TOP;
-
- ro_gui_window_open(PTR_WIMP_OPEN(&state));
-
- /* Claim the caret */
- if (ro_toolbar_take_caret(g->toolbar))
- ro_gui_url_complete_start(g->toolbar);
- else
- gui_window_place_caret(g, -100, -100, 0, NULL);
-
- return g;
}
/**
- * Close a browser window and free any related resources.
+ * Open a window
*
- * \param g gui_window to destroy
+ * opens a window using the given wimp_open, handling toolbars and resizing.
+ *
+ * \param open the window open event information
*/
-
-static void gui_window_destroy(struct gui_window *g)
+static void ro_gui_window_open(wimp_open *open)
{
+ struct gui_window *g;
+ int width = open->visible.x1 - open->visible.x0;
+ int height = open->visible.y1 - open->visible.y0;
+ browser_scrolling h_scroll;
+ browser_scrolling v_scroll;
+ int toolbar_height = 0;
+ float new_scale = 0;
+ wimp_window_state state;
os_error *error;
- wimp_w w;
-
- assert(g);
-
- /* stop any tracking */
- ro_mouse_kill(g);
+ wimp_w parent;
+ bits linkage;
+ bool have_content;
- /* remove from list */
- if (g->prev)
- g->prev->next = g->next;
- else
- window_list = g->next;
- if (g->next)
- g->next->prev = g->prev;
+ g = (struct gui_window *)ro_gui_wimp_event_get_user_data(open->w);
- /* destroy toolbar */
- if (g->toolbar)
- ro_toolbar_destroy(g->toolbar);
- if (g->status_bar)
- ro_gui_status_bar_destroy(g->status_bar);
+ if (open->next == wimp_TOP && g->iconise_icon >= 0) {
+ /* window is no longer iconised, release its sprite number */
+ iconise_used[g->iconise_icon] = false;
+ g->iconise_icon = -1;
+ }
- w = g->window;
- ro_gui_url_complete_close();
- ro_gui_dialog_close_persistent(w);
- if (current_menu_window == w)
- ro_gui_menu_destroy();
- ro_gui_window_remove_update_boxes(g);
+ have_content = browser_window_has_content(g->bw);
- /* delete window */
- error = xwimp_delete_window(w);
+ /* get the current flags/nesting state */
+ state.w = g->window;
+ error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage);
if (error) {
- LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
+ LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
+ return;
}
- ro_gui_wimp_event_finalise(w);
-
- free(g);
-}
-
-/**
- * Set the title of a browser window.
- *
- * \param g gui_window to update
- * \param title new window title, copied
- */
-
-static void gui_window_set_title(struct gui_window *g, const char *title)
-{
- assert(g);
- assert(title);
-
- if (g->scale != 1.0) {
- int scale_disp = g->scale * 100;
-
- if (ABS((float)scale_disp - g->scale * 100) >= 0.05)
- snprintf(g->title, sizeof g->title, "%s (%.1f%%)",
- title, g->scale * 100);
- else
- snprintf(g->title, sizeof g->title, "%s (%i%%)",
- title, scale_disp);
- } else {
- strncpy(g->title, title, sizeof g->title);
- }
+ /* account for toolbar height, if present */
+ if (g->toolbar)
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
+ height -= toolbar_height;
- ro_gui_set_window_title(g->window, g->title);
-}
+ /* work with the state from now on so we can modify flags */
+ state.visible = open->visible;
+ state.xscroll = open->xscroll;
+ state.yscroll = open->yscroll;
+ state.next = open->next;
-/* exported interface documented in riscos/window.h */
-nserror ro_gui_window_invalidate_area(struct gui_window *g,
- const struct rect *rect)
-{
- bool use_buffer;
- int x0, y0, x1, y1;
- struct update_box *cur;
- wimp_window_info info;
- os_error *error;
+ browser_window_get_scrollbar_type(g->bw, &h_scroll, &v_scroll);
- assert(g);
+ /* handle 'auto' scroll bars' and non-fitting scrollbar removal */
+ if ((h_scroll != BW_SCROLLING_NO) && (v_scroll != BW_SCROLLING_NO)) {
+ int size;
- if (rect == NULL) {
- info.w = g->window;
- error = xwimp_get_window_info_header_only(&info);
- if (error) {
- LOG("xwimp_get_window_info_header_only: 0x%x: %s",
- error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return NSERROR_INVALID;
- }
+ /* windows lose scrollbars when containing a frameset */
+ bool no_hscroll = false;
+ bool no_vscroll = browser_window_is_frameset(g->bw);
- error = xwimp_force_redraw(g->window,
- info.extent.x0, info.extent.y0,
- info.extent.x1, info.extent.y1);
- if (error) {
- LOG("xwimp_force_redraw: 0x%x: %s",
- error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return NSERROR_INVALID;
+ /* hscroll */
+ size = ro_get_hscroll_height(NULL);
+ size -= 2; /* 1px border on both sides */
+ if (!no_hscroll) {
+ if (!(state.flags & wimp_WINDOW_HSCROLL)) {
+ height -= size;
+ state.visible.y0 += size;
+ if (have_content) {
+ browser_window_schedule_reformat(g->bw);
+ }
+ }
+ state.flags |= wimp_WINDOW_HSCROLL;
+ } else {
+ if (state.flags & wimp_WINDOW_HSCROLL) {
+ height += size;
+ state.visible.y0 -= size;
+ if (have_content) {
+ browser_window_schedule_reformat(g->bw);
+ }
+ }
+ state.flags &= ~wimp_WINDOW_HSCROLL;
}
- return NSERROR_OK;
- }
-
- x0 = floorf(rect->x0 * 2 * g->scale);
- y0 = -ceilf(rect->y1 * 2 * g->scale);
- x1 = ceilf(rect->x1 * 2 * g->scale) + 1;
- y1 = -floorf(rect->y0 * 2 * g->scale) + 1;
- use_buffer =
- (g->option.buffer_everything || g->option.buffer_animations);
- /* try to optimise buffered redraws */
- if (use_buffer) {
- for (cur = pending_updates; cur != NULL; cur = cur->next) {
- if ((cur->g != g) || (!cur->use_buffer)) {
- continue;
+ /* vscroll */
+ size = ro_get_vscroll_width(NULL);
+ size -= 2; /* 1px border on both sides */
+ if (!no_vscroll) {
+ if (!(state.flags & wimp_WINDOW_VSCROLL)) {
+ width -= size;
+ state.visible.x1 -= size;
+ if (have_content) {
+ browser_window_schedule_reformat(g->bw);
+ }
}
- if ((((cur->x0 - x1) < MARGIN) ||
- ((cur->x1 - x0) < MARGIN)) &&
- (((cur->y0 - y1) < MARGIN) ||
- ((cur->y1 - y0) < MARGIN))) {
- cur->x0 = min(cur->x0, x0);
- cur->y0 = min(cur->y0, y0);
- cur->x1 = max(cur->x1, x1);
- cur->y1 = max(cur->y1, y1);
- return NSERROR_OK;
+ state.flags |= wimp_WINDOW_VSCROLL;
+ } else {
+ if (state.flags & wimp_WINDOW_VSCROLL) {
+ width += size;
+ state.visible.x1 += size;
+ if (have_content) {
+ browser_window_schedule_reformat(g->bw);
+ }
}
+ state.flags &= ~wimp_WINDOW_VSCROLL;
}
}
- cur = malloc(sizeof(struct update_box));
- if (!cur) {
- LOG("No memory for malloc.");
- return NSERROR_NOMEM;
- }
- cur->x0 = x0;
- cur->y0 = y0;
- cur->x1 = x1;
- cur->y1 = y1;
- cur->next = pending_updates;
- pending_updates = cur;
- cur->g = g;
- cur->use_buffer = use_buffer;
-
- return NSERROR_OK;
-}
-
-
-/**
- * Get the scroll position of a browser window.
- *
- * \param g gui_window
- * \param sx receives x ordinate of point at top-left of window
- * \param sy receives y ordinate of point at top-left of window
- * \return true iff successful
- */
-
-static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
-{
- wimp_window_state state;
- os_error *error;
- int toolbar_height = 0;
-
- assert(g);
-
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
+ /* reformat or change extent if necessary */
+ if (have_content &&
+ (g->old_width != width || g->old_height != height)) {
+ /* Ctrl-resize of a top-level window scales the content size */
+ if ((g->old_width > 0) && (g->old_width != width) &&
+ (ro_gui_ctrl_pressed()))
+ new_scale = (g->scale * width) / g->old_width;
+ browser_window_schedule_reformat(g->bw);
+ }
+ if (g->update_extent || g->old_width != width ||
+ g->old_height != height) {
+ g->old_width = width;
+ g->old_height = height;
+ g->update_extent = false;
+ gui_window_set_extent(g, width, height);
}
- if (g->toolbar)
- toolbar_height = ro_toolbar_full_height(g->toolbar);
- *sx = state.xscroll / (2 * g->scale);
- *sy = -(state.yscroll - toolbar_height) / (2 * g->scale);
- return true;
-}
-
+ /* first resize stops any flickering by making the URL window on top */
+ ro_gui_url_complete_resize(g->toolbar, PTR_WIMP_OPEN(&state));
-/**
- * Set the scroll position of a riscos browser window.
- *
- * Scrolls the viewport to ensure the specified rectangle of the
- * content is shown.
- *
- * \param g gui window to scroll
- * \param rect The rectangle to ensure is shown.
- * \return NSERROR_OK on success or apropriate error code.
- */
-static nserror
-gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
-{
- wimp_window_state state;
- os_error *error;
- int toolbar_height = 0;
+ /* Windows containing framesets can only be scrolled via the core, which
+ * is implementing frame scrollbars itself. The x and y offsets are
+ * therefore fixed.
+ */
- assert(g);
+ if (browser_window_is_frameset(g->bw)) {
+ state.xscroll = 0;
+ state.yscroll = toolbar_height;
+ }
- state.w = g->window;
- error = xwimp_get_window_state(&state);
+ error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s",
- error->errnum, error->errmess);
+ LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
- return NSERROR_BAD_PARAMETER;
+ return;
}
+ /* update the toolbar */
+ if (g->status_bar)
+ ro_gui_status_bar_resize(g->status_bar);
if (g->toolbar) {
- toolbar_height = ro_toolbar_full_height(g->toolbar);
- }
-
- if ((rect->x0 == rect->x1) && (rect->y0 == rect->y1)) {
- /* scroll to top */
- state.xscroll = rect->x0 * 2 * g->scale;
- state.yscroll = (-rect->y0 * 2 * g->scale) + toolbar_height;
- } else {
- /* scroll area into view with padding */
- int x0, y0, x1, y1;
- int cx0, cy0, width, height;
- int padding_available;
- int correction;
-
- x0 = rect->x0 * 2 * g->scale;
- y0 = rect->y0 * 2 * g->scale;
- x1 = rect->x1 * 2 * g->scale;
- y1 = rect->y1 * 2 * g->scale;
-
- cx0 = state.xscroll;
- cy0 = -state.yscroll + toolbar_height;
- width = state.visible.x1 - state.visible.x0;
- height = state.visible.y1 - state.visible.y0 - toolbar_height;
-
- /* make sure we're visible */
- correction = (x1 - cx0 - width);
- if (correction > 0) {
- cx0 += correction;
- }
- correction = (y1 - cy0 - height);
- if (correction > 0) {
- cy0 += correction;
- }
- if (x0 < cx0) {
- cx0 = x0;
- }
- if (y0 < cy0) {
- cy0 = y0;
- }
-
- /* try to give a SCROLL_VISIBLE_PADDING border of space around us */
- padding_available = (width - x1 + x0) / 2;
- if (padding_available > 0) {
- if (padding_available > SCROLL_VISIBLE_PADDING) {
- padding_available = SCROLL_VISIBLE_PADDING;
- }
- correction = (cx0 + width - x1);
- if (correction < padding_available) {
- cx0 += padding_available;
- }
- correction = (x0 - cx0);
- if (correction < padding_available) {
- cx0 -= padding_available;
- }
- }
- padding_available = (height - y1 + y0) / 2;
- if (padding_available > 0) {
- if (padding_available > SCROLL_VISIBLE_PADDING) {
- padding_available = SCROLL_VISIBLE_PADDING;
- }
- correction = (cy0 + height - y1);
- if (correction < padding_available) {
- cy0 += padding_available;
- }
- correction = (y0 - cy0);
- if (correction < padding_available) {
- cy0 -= padding_available;
- }
- }
-
- state.xscroll = cx0;
- state.yscroll = -cy0 + toolbar_height;
+ ro_toolbar_process(g->toolbar, -1, false);
+ /* second resize updates to the new URL bar width */
+ ro_gui_url_complete_resize(g->toolbar, open);
}
- ro_gui_window_open(PTR_WIMP_OPEN(&state));
-
- return NSERROR_OK;
-}
-
-/**
- * Find the current dimensions of a browser window's content area.
- *
- * \param gw gui window to measure
- * \param width receives width of window
- * \param height receives height of window
- * \param scaled whether to return scaled values
- */
-static nserror
-gui_window_get_dimensions(struct gui_window *gw,
- int *width, int *height,
- bool scaled)
-{
- /* use the cached window sizes */
- *width = gw->old_width / 2;
- *height = gw->old_height / 2;
-
- if (scaled) {
- *width /= gw->scale;
- *height /= gw->scale;
+ /* set the new scale from a ctrl-resize. this must be done at the end as
+ * it may cause a frameset recalculation based on the new window size.
+ */
+ if (new_scale > 0) {
+ ro_gui_window_set_scale(g, new_scale);
}
- return NSERROR_OK;
}
@@ -943,20 +441,20 @@ gui_window_get_dimensions(struct gui_window *gw,
* Update the extent of the inside of a browser window to that of the
* current content.
*
- * \param g gui_window to update the extent of
+ * \param g gui_window to update the extent of
*/
-
static void gui_window_update_extent(struct gui_window *g)
{
- os_error *error;
- wimp_window_info info;
+ os_error *error;
+ wimp_window_info info;
assert(g);
info.w = g->window;
error = xwimp_get_window_info_header_only(&info);
if (error) {
- LOG("xwimp_get_window_info_header_only: 0x%x: %s", error->errnum, error->errmess);
+ LOG("xwimp_get_window_info_header_only: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
return;
}
@@ -974,872 +472,736 @@ static void gui_window_update_extent(struct gui_window *g)
/**
- * Set the status bar of a browser window.
+ * Update a window and its toolbar
*
- * \param g gui_window to update
- * \param text new status text
+ * makes a window and toolbar reflect a new theme: used as a callback
+ * by the toolbar module when a theme change affects a toolbar.
+ *
+ * \param data void pointer to the window's gui_window struct
+ * \param ok true if the bar still exists; else false.
*/
-
-static void riscos_window_set_status(struct gui_window *g, const char *text)
+static void ro_gui_window_update_theme(void *data, bool ok)
{
- if (g->status_bar)
- ro_gui_status_bar_set_text(g->status_bar, text);
+ struct gui_window *g = (struct gui_window *) data;
+
+ if (g != NULL && g->toolbar != NULL) {
+ if (ok) {
+ gui_window_update_extent(g);
+ } else {
+ g->toolbar = NULL;
+ }
+ }
}
/**
- * Change mouse pointer shape
+ * Update a window to reflect a change in toolbar size: used as a callback by
+ * the toolbar module when a toolbar height changes.
+ *
+ * \param data void pointer the window's gui_window struct
*/
+static void ro_gui_window_update_toolbar(void *data)
+{
+ struct gui_window *g = (struct gui_window *) data;
-void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
+ if (g != NULL) {
+ gui_window_update_extent(g);
+ }
+}
+
+
+/**
+ * Update the toolbar buttons for a given browser window to reflect the
+ * current state of its contents.
+ *
+ * Note that the parameters to this function are arranged so that it can be
+ * supplied to the toolbar module as an button state update callback.
+ *
+ * \param g The browser window to update.
+ */
+static void ro_gui_window_update_toolbar_buttons(struct gui_window *g)
{
- static gui_pointer_shape curr_pointer = GUI_POINTER_DEFAULT;
- struct ro_gui_pointer_entry *entry;
- os_error *error;
+ struct browser_window *bw;
+ struct toolbar *toolbar;
- if (shape == curr_pointer)
+ if (g == NULL || g->toolbar == NULL)
return;
- assert(shape < sizeof ro_gui_pointer_table /
- sizeof ro_gui_pointer_table[0]);
+ bw = g->bw;
+ toolbar = g->toolbar;
- entry = &ro_gui_pointer_table[shape];
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_RELOAD,
+ !browser_window_reload_available(bw));
- if (entry->wimp_area) {
- /* pointer in the Wimp's sprite area */
- error = xwimpspriteop_set_pointer_shape(entry->sprite_name,
- 1, entry->xactive, entry->yactive, 0, 0);
- if (error) {
- LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- } else {
- /* pointer in our own sprite area */
- error = xosspriteop_set_pointer_shape(osspriteop_USER_AREA,
- gui_sprites,
- (osspriteop_id) entry->sprite_name,
- 1, entry->xactive, entry->yactive, 0, 0);
- if (error) {
- LOG("xosspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- }
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_STOP,
+ !browser_window_stop_available(bw));
- curr_pointer = shape;
-}
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_BACK,
+ !browser_window_back_available(bw));
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_FORWARD,
+ !browser_window_forward_available(bw));
-/* exported function documented in riscos/window.h */
-nserror ro_gui_window_set_url(struct gui_window *g, nsurl *url)
-{
- size_t idn_url_l;
- char *idn_url_s = NULL;
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_UP,
+ !browser_window_up_available(bw));
- if (g->toolbar) {
- if (nsoption_bool(display_decoded_idn) == true) {
- if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK)
- idn_url_s = NULL;
- }
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SEARCH,
+ !browser_window_can_search(bw));
- ro_toolbar_set_url(g->toolbar, idn_url_s ? idn_url_s : nsurl_access(url), true, false);
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SCALE,
+ !browser_window_has_content(bw));
- if (idn_url_s)
- free(idn_url_s);
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_PRINT,
+ !browser_window_has_content(bw));
- ro_gui_url_complete_start(g->toolbar);
- }
+ ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SAVE_SOURCE,
+ !browser_window_has_content(bw));
- return NSERROR_OK;
+ ro_toolbar_update_urlsuggest(toolbar);
}
/**
- * Update the interface to reflect start of page loading.
+ * Add a hotlist entry for a browser window.
*
- * \param g window with start of load
+ * \param g The browser window to act on.
*/
-
-static void gui_window_start_throbber(struct gui_window *g)
+static void ro_gui_window_action_add_bookmark(struct gui_window *g)
{
- ro_gui_window_update_toolbar_buttons(g);
- ro_gui_menu_refresh(ro_gui_browser_window_menu);
- if (g->toolbar != NULL)
- ro_toolbar_start_throbbing(g->toolbar);
- g->active = true;
-}
-
+ nsurl *url;
+ if (g == NULL || g->bw == NULL || g->toolbar == NULL ||
+ browser_window_has_content(g->bw) == false)
+ return;
-/**
- * Update the interface to reflect page loading stopped.
- *
- * \param g window with start of load
- */
+ url = browser_window_get_url(g->bw);
-static void gui_window_stop_throbber(struct gui_window *g)
-{
- ro_gui_window_update_toolbar_buttons(g);
- ro_gui_menu_refresh(ro_gui_browser_window_menu);
- if (g->toolbar != NULL)
- ro_toolbar_stop_throbbing(g->toolbar);
- g->active = false;
+ ro_gui_hotlist_add_page(url);
+ ro_toolbar_update_hotlist(g->toolbar);
}
+
/**
- * set favicon
+ * Remove a hotlist entry for a browser window.
+ *
+ * \param g The browser window to act on.
*/
-
-static void gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon)
+static void ro_gui_window_action_remove_bookmark(struct gui_window *g)
{
- if (g == NULL || g->toolbar == NULL)
+ nsurl *url;
+
+ if (g == NULL || g->bw == NULL || g->toolbar == NULL ||
+ browser_window_has_content(g->bw) == false)
return;
- ro_toolbar_set_site_favicon(g->toolbar, icon);
-}
+ url = browser_window_get_url(g->bw);
+ ro_gui_hotlist_remove_page(url);
+}
/**
- * Remove the caret, if present.
+ * Open a local history pane for a browser window.
*
- * \param g window with caret
+ * \param gw The browser window to act on.
*/
-
-static void gui_window_remove_caret(struct gui_window *g)
+static void ro_gui_window_action_local_history(struct gui_window *gw)
{
- wimp_caret caret;
- os_error *error;
+ nserror res;
- error = xwimp_get_caret_position(&caret);
- if (error) {
- LOG("xwimp_get_caret_position: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
+ if ((gw == NULL) || (gw->bw == NULL)) {
return;
}
- if (caret.w != g->window)
- /* we don't have the caret: do nothing */
- return;
+ res = ro_gui_local_history_present(gw->window, gw->bw);
- /* hide caret, but keep input focus */
- gui_window_place_caret(g, -100, -100, 0, NULL);
+ if (res != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(res), 0);
+ }
}
/**
- * Called when the gui_window has new content.
+ * Perform a Navigate Home action on a browser window.
*
- * \param g the gui_window that has new content
+ * \param g The browser window to act on.
*/
-
-static void gui_window_new_content(struct gui_window *g)
+static void ro_gui_window_action_home(struct gui_window *g)
{
- ro_gui_menu_refresh(ro_gui_browser_window_menu);
- ro_gui_window_update_toolbar_buttons(g);
- ro_gui_dialog_close_persistent(g->window);
- ro_toolbar_set_content_favicon(g->toolbar, g);
-}
-
-
-/**
- * Starts drag scrolling of a browser window
- *
- * \param g the window to scroll
- */
+ static const char *addr = NETSURF_HOMEPAGE;
+ nsurl *url;
+ nserror error;
-static bool gui_window_scroll_start(struct gui_window *g)
-{
- wimp_window_info_base info;
- wimp_pointer pointer;
- os_error *error;
- wimp_drag drag;
- int height;
- int width;
+ if (g == NULL || g->bw == NULL)
+ return;
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
+ if (nsoption_charp(homepage_url) != NULL) {
+ addr = nsoption_charp(homepage_url);
}
- info.w = g->window;
- error = xwimp_get_window_info_header_only((wimp_window_info*)&info);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
+ error = nsurl_create(addr, &url);
+ if (error == NSERROR_OK) {
+ error = browser_window_navigate(g->bw,
+ url,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
}
-
- width = info.extent.x1 - info.extent.x0;
- height = info.extent.y1 - info.extent.y0;
-
- drag.type = wimp_DRAG_USER_POINT;
- drag.bbox.x1 = pointer.pos.x + info.xscroll;
- drag.bbox.y0 = pointer.pos.y + info.yscroll;
- drag.bbox.x0 = drag.bbox.x1 - (width - (info.visible.x1 - info.visible.x0));
- drag.bbox.y1 = drag.bbox.y0 + (height - (info.visible.y1 - info.visible.y0));
-
- if (g->toolbar) {
- int tbar_height = ro_toolbar_full_height(g->toolbar);
- drag.bbox.y0 -= tbar_height;
- drag.bbox.y1 -= tbar_height;
+ if (error != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(error), 0);
}
+}
- error = xwimp_drag_box(&drag);
- if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
- }
- ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at,
- NULL, g);
- return true;
+/**
+ * Open a text search dialogue for a browser window.
+ *
+ * \param g The browser window to act on.
+ */
+static void ro_gui_window_action_search(struct gui_window *g)
+{
+ if (g == NULL || g->bw == NULL || !browser_window_can_search(g->bw))
+ return;
+
+ ro_gui_search_prepare(g->bw);
+ ro_gui_dialog_open_persistent(g->window, dialog_search, true);
}
/**
- * Platform-dependent part of starting drag operation.
+ * Open a zoom dialogue for a browser window.
*
- * \param g gui window containing the drag
- * \param type type of drag the core is performing
- * \param rect rectangle to constrain pointer to (relative to drag start coord)
- * \return true iff succesful
+ * \param g The browser window to act on.
*/
-
-static bool gui_window_drag_start(struct gui_window *g, gui_drag_type type,
- const struct rect *rect)
+static void ro_gui_window_action_zoom(struct gui_window *g)
{
- wimp_pointer pointer;
- wimp_drag drag;
+ if (g == NULL)
+ return;
- if (rect != NULL) {
- /* We have a box to constrain the pointer to, for the drag
- * duration */
- os_error *error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
- }
+ ro_gui_dialog_prepare_zoom(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_zoom, true);
+}
- drag.type = wimp_DRAG_USER_POINT;
- drag.bbox.x0 = pointer.pos.x +
- (int)(rect->x0 * 2 * g->scale);
- drag.bbox.y0 = pointer.pos.y +
- (int)(rect->y0 * 2 * g->scale);
- drag.bbox.x1 = pointer.pos.x +
- (int)(rect->x1 * 2 * g->scale);
- drag.bbox.y1 = pointer.pos.y +
- (int)(rect->y1 * 2 * g->scale);
- error = xwimp_drag_box(&drag);
- if (error) {
- LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return false;
- }
- }
+/**
+ * Open a save dialogue for a browser window contents.
+ *
+ * \param g The browser window to act on.
+ * \param save_type The type of save to open.
+ */
+static void
+ro_gui_window_action_save(struct gui_window *g, gui_save_type save_type)
+{
+ struct hlcache_handle *h;
- switch (type) {
- case GDRAGGING_SCROLLBAR:
- /* Dragging a core scrollbar */
- ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at,
- NULL, g);
- break;
+ if (g == NULL || g->bw == NULL || !browser_window_has_content(g->bw))
+ return;
- default:
- /* Not handled here yet */
- break;
- }
+ h = browser_window_get_content(g->bw);
+ if (h == NULL)
+ return;
- return true;
+ ro_gui_save_prepare(save_type, h, NULL, NULL, NULL);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
}
/**
- * Save the specified content as a link.
+ * Open a print dialogue for a browser window.
*
- * \param g The window containing the content
- * \param url The url of the link
- * \param title The title of the link
+ * \param g The browser window to act on.
*/
-static nserror
-gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
+static void ro_gui_window_action_print(struct gui_window *g)
{
- ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, url, title);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
- return NSERROR_OK;
+ if (g != NULL) {
+ ro_gui_print_prepare(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_print, true);
+ }
}
/**
- * Updates a windows extent.
+ * Prepare the page info window for use.
*
- * \param g the gui_window to update
- * \param width the minimum width, or -1 to use window width
- * \param height the minimum height, or -1 to use window height
+ * \param g The GUI window block to use.
*/
-
-void gui_window_set_extent(struct gui_window *g, int width, int height)
+static void ro_gui_window_prepare_pageinfo(struct gui_window *g)
{
- int screen_width;
- int toolbar_height = 0;
- wimp_window_state state;
- os_error *error;
+ struct hlcache_handle *h = browser_window_get_content(g->bw);
+ char icon_buf[20] = "file_xxx";
+ char enc_buf[40];
+ const char *icon = icon_buf;
+ const char *title, *url;
+ lwc_string *mime;
+ const char *enc = "-";
- if (g->toolbar)
- toolbar_height = ro_toolbar_full_height(g->toolbar);
+ assert(h);
- /* get the current state */
- if ((height == -1) || (width == -1)) {
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return;
- }
- if (width == -1)
- width = state.visible.x1 - state.visible.x0;
- if (height == -1) {
- height = state.visible.y1 - state.visible.y0;
- height -= toolbar_height;
+ title = content_get_title(h);
+ if (title == NULL)
+ title = "-";
+ url = nsurl_access(hlcache_handle_get_url(h));
+ if (url == NULL)
+ url = "-";
+ mime = content_get_mime_type(h);
+
+ sprintf(icon_buf, "file_%x", ro_content_filetype(h));
+ if (!ro_gui_wimp_sprite_exists(icon_buf))
+ sprintf(icon_buf, "file_xxx");
+
+ if (content_get_type(h) == CONTENT_HTML) {
+ if (content_get_encoding(h, CONTENT_ENCODING_NORMAL)) {
+ snprintf(enc_buf, sizeof enc_buf, "%s (%s)",
+ content_get_encoding(h, CONTENT_ENCODING_NORMAL),
+ content_get_encoding(h, CONTENT_ENCODING_SOURCE));
+ enc = enc_buf;
+ } else {
+ enc = messages_get("EncodingUnk");
}
}
- /* the top-level framed window is a total pain. to get it to maximise
- * to the top of the screen we need to fake it having a suitably large
- * extent */
- if (browser_window_is_frameset(g->bw)) {
- ro_gui_screen_size(&screen_width, &height);
- if (g->toolbar)
- height -= ro_toolbar_full_height(g->toolbar);
- height -= ro_get_hscroll_height(g->window);
- height -= ro_get_title_height(g->window);
- }
- if (browser_window_has_content(g->bw)) {
- int w, h;
- browser_window_get_extents(g->bw, true, &w, &h);
- width = max(width, w * 2);
- height = max(height, h * 2);
- }
- os_box extent = { 0, -height, width, toolbar_height };
- error = xwimp_set_extent(g->window, &extent);
- if (error) {
- LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return;
- }
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ICON,
+ icon, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TITLE,
+ title, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_URL,
+ url, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ENC,
+ enc, true);
+ ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TYPE,
+ lwc_string_data(mime), true);
+
+ lwc_string_unref(mime);
}
/**
- * Display a menu of options for a form select control.
+ * Open a page info box for a browser window.
*
- * \param g gui window containing form control
- * \param control form control of type GADGET_SELECT
+ * \param g The browser window to act on.
*/
-
-static void gui_window_create_form_select_menu(struct gui_window *g,
- struct form_control *control)
+static void ro_gui_window_action_page_info(struct gui_window *g)
{
- os_error *error;
- wimp_pointer pointer;
+ if (g == NULL || g->bw == NULL ||
+ browser_window_has_content(g->bw) == false)
+ return;
- /* The first time the menu is opened, control bypasses the normal
- * Menu Prepare event and so we prepare here. On any re-opens,
- * ro_gui_window_prepare_form_select_menu() is called from the
- * normal wimp event.
- */
+ ro_gui_window_prepare_pageinfo(g);
+ ro_gui_dialog_open_persistent(g->window, dialog_pageinfo, false);
+}
- if (!ro_gui_window_prepare_form_select_menu(g, control))
- return;
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- ro_gui_menu_destroy();
+/**
+ * Process Mouse_Click events in a toolbar's button bar.
+ *
+ * This does not handle other clicks in a toolbar: these are handled
+ * by the toolbar module itself.
+ *
+ * \param data The GUI window associated with the click.
+ * \param action_type The action type to be handled.
+ * \param action The action to process.
+ */
+static void
+ro_gui_window_toolbar_click(void *data,
+ toolbar_action_type action_type,
+ union toolbar_action action)
+{
+ struct gui_window *g = data;
+ nserror err;
+
+ if (g == NULL)
return;
- }
- gui_form_select_control = control;
- ro_gui_menu_create(gui_form_select_menu,
- pointer.pos.x, pointer.pos.y, g->window);
-}
+ if (action_type == TOOLBAR_ACTION_URL) {
+ switch (action.url) {
+ case TOOLBAR_URL_DRAG_URL:
+ {
+ gui_save_type save_type;
-/*
- * RISC OS Wimp Event Handlers
- */
+ if (!browser_window_has_content(g->bw))
+ break;
+ if (ro_gui_shift_pressed())
+ save_type = GUI_SAVE_LINK_URL;
+ else
+ save_type = GUI_SAVE_LINK_TEXT;
-/**
- * Handle a Redraw_Window_Request for a browser window.
- */
+ ro_gui_drag_save_link(save_type,
+ browser_window_get_url(g->bw),
+ browser_window_get_title(g->bw), g);
+ }
+ break;
-void ro_gui_window_redraw(wimp_draw *redraw)
-{
- osbool more;
- struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(redraw->w);
- os_error *error;
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &ro_plotters
- };
+ case TOOLBAR_URL_SELECT_HOTLIST:
+ ro_gui_window_action_add_bookmark(g);
+ break;
- /* We can't render locked contents. If the browser window is not
- * ready for redraw, do nothing. Else, in the case of buffered
- * rendering we'll show random data. */
- if (!browser_window_redraw_ready(g->bw))
- return;
+ case TOOLBAR_URL_ADJUST_HOTLIST:
+ ro_gui_window_action_remove_bookmark(g);
+ break;
- ro_gui_current_redraw_gui = g;
+ default:
+ break;
+ }
- error = xwimp_redraw_window(redraw, &more);
- if (error) {
- LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
return;
}
- while (more) {
- struct rect clip;
- /* OS's redraw request coordinates are in screen coordinates,
- * with an origin at the bottom left of the screen.
- * Find the coordinate of the top left of the document in terms
- * of OS screen coordinates.
- * NOTE: OS units are 2 per px. */
- ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
- ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;
- /* Convert OS redraw rectangle request coordinates into NetSurf
- * coordinates. NetSurf coordinates have origin at top left of
- * document and units are in px. */
- clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; /* left */
- clip.y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; /* top */
- clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; /* right */
- clip.y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; /* bottom */
+ /* By now, the only valid action left is a button click. If it isn't
+ * one of those, give up.
+ */
- if (ro_gui_current_redraw_gui->option.buffer_everything)
- ro_gui_buffer_open(redraw);
+ if (action_type != TOOLBAR_ACTION_BUTTON)
+ return;
- browser_window_redraw(g->bw, 0, 0, &clip, &ctx);
+ switch (action.button) {
+ case TOOLBAR_BUTTON_BACK:
+ if (g->bw != NULL)
+ browser_window_history_back(g->bw, false);
+ break;
- if (ro_gui_current_redraw_gui->option.buffer_everything)
- ro_gui_buffer_close();
+ case TOOLBAR_BUTTON_BACK_NEW:
+ if (g->bw != NULL)
+ browser_window_history_back(g->bw, true);
+ break;
- /* Check to see if there are more rectangles to draw and
- * get next one */
- error = xwimp_get_rectangle(redraw, &more);
- /* RISC OS 3.7 returns an error here if enough buffer was
- claimed to cause a new dynamic area to be created. It
- doesn't actually stop anything working, so we mask it out
- for now until a better fix is found. This appears to be a
- bug in RISC OS. */
- if (error && !(ro_gui_current_redraw_gui->
- option.buffer_everything &&
- error->errnum == error_WIMP_GET_RECT)) {
- LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- ro_gui_current_redraw_gui = NULL;
- return;
- }
- }
- ro_gui_current_redraw_gui = NULL;
-}
+ case TOOLBAR_BUTTON_FORWARD:
+ if (g->bw != NULL)
+ browser_window_history_forward(g->bw, false);
+ break;
+ case TOOLBAR_BUTTON_FORWARD_NEW:
+ if (g->bw != NULL)
+ browser_window_history_forward(g->bw, true);
+ break;
-/**
- * Set a gui_window's scale
- */
-void ro_gui_window_set_scale(struct gui_window *g, float scale)
-{
- g->scale = scale;
- browser_window_set_scale(g->bw, scale, true);
-}
+ case TOOLBAR_BUTTON_STOP:
+ if (g->bw != NULL)
+ browser_window_stop(g->bw);
+ break;
+ case TOOLBAR_BUTTON_RELOAD:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, false);
+ break;
-/**
- * Open a window using the given wimp_open, handling toolbars and resizing.
- */
+ case TOOLBAR_BUTTON_RELOAD_ALL:
+ if (g->bw != NULL)
+ browser_window_reload(g->bw, true);
+ break;
-void ro_gui_window_open(wimp_open *open)
-{
- struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(open->w);
- int width = open->visible.x1 - open->visible.x0;
- int height = open->visible.y1 - open->visible.y0;
- browser_scrolling h_scroll;
- browser_scrolling v_scroll;
- int toolbar_height = 0;
- float new_scale = 0;
- wimp_window_state state;
- os_error *error;
- wimp_w parent;
- bits linkage;
- bool have_content;
+ case TOOLBAR_BUTTON_HISTORY_LOCAL:
+ ro_gui_window_action_local_history(g);
+ break;
- if (open->next == wimp_TOP && g->iconise_icon >= 0) {
- /* window is no longer iconised, release its sprite number */
- iconise_used[g->iconise_icon] = false;
- g->iconise_icon = -1;
- }
+ case TOOLBAR_BUTTON_HISTORY_GLOBAL:
+ ro_gui_global_history_present();
+ break;
- have_content = browser_window_has_content(g->bw);
+ case TOOLBAR_BUTTON_HOME:
+ ro_gui_window_action_home(g);
+ break;
- /* get the current flags/nesting state */
- state.w = g->window;
- error = xwimp_get_window_state_and_nesting(&state, &parent, &linkage);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- return;
- }
+ case TOOLBAR_BUTTON_SEARCH:
+ ro_gui_window_action_search(g);
+ break;
- /* account for toolbar height, if present */
- if (g->toolbar)
- toolbar_height = ro_toolbar_full_height(g->toolbar);
- height -= toolbar_height;
+ case TOOLBAR_BUTTON_SCALE:
+ ro_gui_window_action_zoom(g);
+ break;
- /* work with the state from now on so we can modify flags */
- state.visible = open->visible;
- state.xscroll = open->xscroll;
- state.yscroll = open->yscroll;
- state.next = open->next;
+ case TOOLBAR_BUTTON_BOOKMARK_OPEN:
+ ro_gui_hotlist_present();
+ break;
- browser_window_get_scrollbar_type(g->bw, &h_scroll, &v_scroll);
+ case TOOLBAR_BUTTON_BOOKMARK_ADD:
+ ro_gui_window_action_add_bookmark(g);
+ break;
- /* handle 'auto' scroll bars' and non-fitting scrollbar removal */
- if ((h_scroll != BW_SCROLLING_NO) && (v_scroll != BW_SCROLLING_NO)) {
- int size;
+ case TOOLBAR_BUTTON_SAVE_SOURCE:
+ ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
+ break;
- /* windows lose scrollbars when containing a frameset */
- bool no_hscroll = false;
- bool no_vscroll = browser_window_is_frameset(g->bw);
+ case TOOLBAR_BUTTON_SAVE_COMPLETE:
+ ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
+ break;
- /* hscroll */
- size = ro_get_hscroll_height(NULL);
- size -= 2; /* 1px border on both sides */
- if (!no_hscroll) {
- if (!(state.flags & wimp_WINDOW_HSCROLL)) {
- height -= size;
- state.visible.y0 += size;
- if (have_content) {
- browser_window_schedule_reformat(g->bw);
- }
- }
- state.flags |= wimp_WINDOW_HSCROLL;
- } else {
- if (state.flags & wimp_WINDOW_HSCROLL) {
- height += size;
- state.visible.y0 -= size;
- if (have_content) {
- browser_window_schedule_reformat(g->bw);
- }
- }
- state.flags &= ~wimp_WINDOW_HSCROLL;
+ case TOOLBAR_BUTTON_PRINT:
+ ro_gui_window_action_print(g);
+ break;
+
+ case TOOLBAR_BUTTON_UP:
+ err = browser_window_navigate_up(g->bw, false);
+ if (err != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(err), NULL);
}
+ break;
- /* vscroll */
- size = ro_get_vscroll_width(NULL);
- size -= 2; /* 1px border on both sides */
- if (!no_vscroll) {
- if (!(state.flags & wimp_WINDOW_VSCROLL)) {
- width -= size;
- state.visible.x1 -= size;
- if (have_content) {
- browser_window_schedule_reformat(g->bw);
- }
- }
- state.flags |= wimp_WINDOW_VSCROLL;
- } else {
- if (state.flags & wimp_WINDOW_VSCROLL) {
- width += size;
- state.visible.x1 += size;
- if (have_content) {
- browser_window_schedule_reformat(g->bw);
- }
- }
- state.flags &= ~wimp_WINDOW_VSCROLL;
+ case TOOLBAR_BUTTON_UP_NEW:
+ err = browser_window_navigate_up(g->bw, true);
+ if (err != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(err), NULL);
}
- }
+ break;
- /* reformat or change extent if necessary */
- if (have_content &&
- (g->old_width != width || g->old_height != height)) {
- /* Ctrl-resize of a top-level window scales the content size */
- if ((g->old_width > 0) && (g->old_width != width) &&
- (ro_gui_ctrl_pressed()))
- new_scale = (g->scale * width) / g->old_width;
- browser_window_schedule_reformat(g->bw);
- }
- if (g->update_extent || g->old_width != width ||
- g->old_height != height) {
- g->old_width = width;
- g->old_height = height;
- g->update_extent = false;
- gui_window_set_extent(g, width, height);
+ default:
+ break;
}
- /* first resize stops any flickering by making the URL window on top */
- ro_gui_url_complete_resize(g->toolbar, PTR_WIMP_OPEN(&state));
+ ro_gui_window_update_toolbar_buttons(g);
+}
- /* Windows containing framesets can only be scrolled via the core, which
- * is implementing frame scrollbars itself. The x and y offsets are
- * therefore fixed.
- */
- if (browser_window_is_frameset(g->bw)) {
- state.xscroll = 0;
- state.yscroll = toolbar_height;
- }
+/**
+ * Launch a new url in the given window.
+ *
+ * \param g gui_window to update
+ * \param url1 url to be launched
+ */
+static void ro_gui_window_launch_url(struct gui_window *g, const char *url1)
+{
+ nserror error;
+ nsurl *url;
- error = xwimp_open_window_nested_with_flags(&state, parent, linkage);
- if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
+ if (url1 == NULL)
return;
- }
- /* update the toolbar */
- if (g->status_bar)
- ro_gui_status_bar_resize(g->status_bar);
- if (g->toolbar) {
- ro_toolbar_process(g->toolbar, -1, false);
- /* second resize updates to the new URL bar width */
- ro_gui_url_complete_resize(g->toolbar, open);
- }
+ ro_gui_url_complete_close();
- /* set the new scale from a ctrl-resize. this must be done at the end as
- * it may cause a frameset recalculation based on the new window size.
- */
- if (new_scale > 0) {
- ro_gui_window_set_scale(g, new_scale);
+ error = nsurl_create(url1, &url);
+ if (error != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(error), 0);
+ } else {
+ ro_gui_window_set_url(g, url);
+
+ browser_window_navigate(g->bw, url,
+ NULL, BW_NAVIGATE_HISTORY,
+ NULL, NULL, NULL);
+ nsurl_unref(url);
}
}
/**
- * Handle wimp closing event
+ * Open a new browser window.
+ *
+ * \param g The browser window to act on.
*/
-
-void ro_gui_window_close(wimp_w w)
+static void ro_gui_window_action_new_window(struct gui_window *g)
{
- struct gui_window *g = (struct gui_window *)ro_gui_wimp_event_get_user_data(w);
- wimp_pointer pointer;
- os_error *error;
- char *temp_name;
- char *filename = NULL;
- struct nsurl *url;
- bool destroy;
+ nserror error;
- error = xwimp_get_pointer_info(&pointer);
- if (error) {
- LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
+ if (g == NULL || g->bw == NULL)
return;
- }
- if (pointer.buttons & wimp_CLICK_ADJUST) {
- destroy = !ro_gui_shift_pressed();
+ error = browser_window_create(BW_CREATE_CLONE,
+ browser_window_get_url(g->bw),
+ NULL, g->bw, NULL);
- url = browser_window_get_url(g->bw);
- if (url != NULL) {
- netsurf_nsurl_to_path(url, &filename);
- }
- if (filename != NULL) {
- temp_name = malloc(strlen(filename) + 32);
- if (temp_name) {
- char *r;
- sprintf(temp_name, "Filer_OpenDir %s",
- filename);
- r = temp_name + strlen(temp_name);
- while (r > temp_name) {
- if (*r == '.') {
- *r = '\0';
- break;
- }
- r--;
- }
- error = xos_cli(temp_name);
- if (error) {
- LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MiscError", error->errmess);
- return;
- }
- free(temp_name);
- }
- free(filename);
- } else {
- /* this is pointless if we are about to close the
- * window */
- if (!destroy && url != NULL)
- browser_window_navigate_up(g->bw, false);
- }
+ if (error != NSERROR_OK) {
+ ro_warn_user(messages_get_errorcode(error), 0);
}
- else
- destroy = true;
-
- if (destroy)
- browser_window_destroy(g->bw);
}
/**
- * Handle Mouse_Click events in a browser window. This should never see
- * Menu clicks, as these will be routed to the menu handlers.
+ * Scroll a browser window.
+ *
+ * the scroll is either via the core or directly using the normal
+ * Wimp_OpenWindow interface.
+ *
+ * Scroll steps are supplied in terms of the (extended) Scroll Event direction
+ * values returned by Wimp_Poll. Special values of 0x7fffffff and 0x80000000
+ * are added to mean "Home" and "End".
*
- * \param *pointer details of mouse click
- * \return true if click handled, false otherwise
+ * \param g The GUI Window to be scrolled.
+ * \param scroll_x The X scroll step to be applied.
+ * \param scroll_y The Y scroll step to be applied.
*/
-
-bool ro_gui_window_click(wimp_pointer *pointer)
+static void
+ro_gui_window_scroll_action(struct gui_window *g,
+ wimp_scroll_direction scroll_x,
+ wimp_scroll_direction scroll_y)
{
- struct gui_window *g;
- os_coord pos;
+ int visible_x, visible_y;
+ int step_x = 0, step_y = 0;
+ int toolbar_y;
+ wimp_window_state state;
+ wimp_pointer pointer;
+ os_error *error;
+ os_coord pos;
+ bool handled = false;
+ struct toolbar *toolbar;
- /* We should never see Menu clicks. */
+ if (g == NULL)
+ return;
- if (pointer->buttons == wimp_CLICK_MENU)
- return false;
+ /* Get the current window, toolbar and pointer details. */
- g = (struct gui_window *) ro_gui_wimp_event_get_user_data(pointer->w);
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ return;
+ }
- /* try to close url-completion */
- ro_gui_url_complete_close();
+ toolbar = ro_toolbar_parent_window_lookup(g->window);
+ assert(g == NULL || g->toolbar == NULL || g->toolbar == toolbar);
- /* set input focus */
- if (pointer->buttons & (wimp_SINGLE_SELECT | wimp_SINGLE_ADJUST))
- gui_window_place_caret(g, -100, -100, 0, NULL);
+ toolbar_y = (toolbar == NULL) ? 0 : ro_toolbar_full_height(toolbar);
- if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
- browser_window_mouse_click(g->bw,
- ro_gui_mouse_click_state(pointer->buttons,
- wimp_BUTTON_DOUBLE_CLICK_DRAG),
- pos.x, pos.y);
+ visible_x = state.visible.x1 - state.visible.x0 - 32;
+ visible_y = state.visible.y1 - state.visible.y0 - 32 - toolbar_y;
- return true;
-}
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return;
+ }
+ /* Turn the scroll requirement from Scroll Event codes into coordinates
+ * that the core can understand.
+ */
-/**
- * Process Key_Pressed events in a browser window.
- *
- * \param *key The wimp keypress block for the event.
- * \return true if the event was handled, else false.
- */
+ switch (scroll_x) {
+ case wimp_SCROLL_PAGE_LEFT:
+ step_x = SCROLL_PAGE_DOWN;
+ break;
+ case wimp_SCROLL_AUTO_LEFT:
+ case wimp_SCROLL_COLUMN_LEFT:
+ step_x = -16;
+ break;
+ case wimp_SCROLL_AUTO_RIGHT:
+ case wimp_SCROLL_COLUMN_RIGHT:
+ step_x = 16;
+ break;
+ case wimp_SCROLL_PAGE_RIGHT:
+ step_x = SCROLL_PAGE_UP;
+ break;
+ case 0x80000000:
+ step_x = SCROLL_BOTTOM;
+ break;
+ case 0x7fffffff:
+ step_x = SCROLL_TOP;
+ break;
+ default:
+ step_x = (visible_x * (scroll_x>>2)) >> 2;
+ break;
+ }
-bool ro_gui_window_keypress(wimp_key *key)
-{
- struct gui_window *g;
- uint32_t c = (uint32_t) key->c;
+ switch (scroll_y) {
+ case wimp_SCROLL_PAGE_UP:
+ step_y = SCROLL_PAGE_UP;
+ break;
+ case wimp_SCROLL_AUTO_UP:
+ case wimp_SCROLL_LINE_UP:
+ step_y = -16;
+ break;
+ case wimp_SCROLL_AUTO_DOWN:
+ case wimp_SCROLL_LINE_DOWN:
+ step_y = 16;
+ break;
+ case wimp_SCROLL_PAGE_DOWN:
+ step_y = SCROLL_PAGE_DOWN;
+ break;
+ case 0x80000000:
+ step_y = SCROLL_BOTTOM;
+ break;
+ case 0x7fffffff:
+ step_y = SCROLL_TOP;
+ break;
+ default:
+ step_y = -((visible_y * (scroll_y>>2)) >> 2);
+ break;
+ }
- g = (struct gui_window *) ro_gui_wimp_event_get_user_data(key->w);
- if (g == NULL)
- return false;
+ /* If no scrolling is required, there's no point trying to do any. */
- /* First send the key to the browser window, eg. form fields. */
+ if (step_x == 0 && step_y == 0)
+ return;
- if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) ||
- (c & IS_WIMP_KEY)) {
- /* Munge control keys into unused control chars */
- /* We can't map onto 1->26 (reserved for ctrl+<qwerty>
- That leaves 27->31 and 128->159 */
- switch (c & ~IS_WIMP_KEY) {
- case wimp_KEY_TAB: c = 9; break;
- case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break;
+ /* If the pointer is over the window being scrolled, then try to get
+ * the core to do the scrolling on the object under the pointer.
+ */
- /* cursor movement keys */
- case wimp_KEY_HOME:
- case wimp_KEY_CONTROL | wimp_KEY_LEFT:
- c = NS_KEY_LINE_START;
+ if (pointer.w == g->window &&
+ ro_gui_window_to_window_pos(g,
+ pointer.pos.x, pointer.pos.y, &pos))
+ handled = browser_window_scroll_at_point(g->bw, pos.x, pos.y,
+ step_x, step_y);
+
+ /* If the core didn't do the scrolling, handle it via the Wimp.
+ * Windows which contain frames can only be scrolled by the core,
+ * because it implements frame scroll bars.
+ */
+
+ if (!handled && (browser_window_is_frameset(g->bw) == false)) {
+ switch (step_x) {
+ case SCROLL_TOP:
+ state.xscroll -= 0x10000000;
break;
- case wimp_KEY_END:
- if (os_version >= RISCOS5)
- c = NS_KEY_LINE_END;
- else
- c = NS_KEY_DELETE_RIGHT;
+ case SCROLL_BOTTOM:
+ state.xscroll += 0x10000000;
break;
- case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = NS_KEY_LINE_END; break;
- case wimp_KEY_CONTROL | wimp_KEY_UP: c = NS_KEY_TEXT_START; break;
- case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = NS_KEY_TEXT_END; break;
- case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = NS_KEY_WORD_LEFT ; break;
- case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = NS_KEY_WORD_RIGHT; break;
- case wimp_KEY_SHIFT | wimp_KEY_UP: c = NS_KEY_PAGE_UP; break;
- case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = NS_KEY_PAGE_DOWN; break;
- case wimp_KEY_LEFT: c = NS_KEY_LEFT; break;
- case wimp_KEY_RIGHT: c = NS_KEY_RIGHT; break;
- case wimp_KEY_UP: c = NS_KEY_UP; break;
- case wimp_KEY_DOWN: c = NS_KEY_DOWN; break;
-
- /* editing */
- case wimp_KEY_CONTROL | wimp_KEY_END:
- c = NS_KEY_DELETE_LINE_END;
+ case SCROLL_PAGE_UP:
+ state.xscroll += visible_x;
break;
- case wimp_KEY_DELETE:
- if (ro_gui_ctrl_pressed())
- c = NS_KEY_DELETE_LINE_START;
- else if (os_version < RISCOS5)
- c = NS_KEY_DELETE_LEFT;
+ case SCROLL_PAGE_DOWN:
+ state.xscroll -= visible_x;
break;
+ default:
+ state.xscroll += 2 * step_x;
+ break;
+ }
- case wimp_KEY_F8:
- c = NS_KEY_UNDO;
+ switch (step_y) {
+ case SCROLL_TOP:
+ state.yscroll += 0x10000000;
break;
- case wimp_KEY_F9:
- c = NS_KEY_REDO;
+ case SCROLL_BOTTOM:
+ state.yscroll -= 0x10000000;
+ break;
+ case SCROLL_PAGE_UP:
+ state.yscroll += visible_y;
+ break;
+ case SCROLL_PAGE_DOWN:
+ state.yscroll -= visible_y;
break;
-
default:
+ state.yscroll -= 2 * step_y;
break;
}
- }
- if (!(c & IS_WIMP_KEY)) {
- if (browser_window_key_press(g->bw, c))
- return true;
+ error = xwimp_open_window((wimp_open *) &state);
+ if (error) {
+ LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+ }
}
-
- return ro_gui_window_handle_local_keypress(g, key, false);
}
/**
- * Callback handler for keypresses within browser window toolbars.
+ * Handle keypresses within the RISC OS GUI
*
- * \param *data Client data, pointing to the GUI Window.
- * \param *key The keypress data.
- * \return true if the keypress was handled; else false.
- */
-
-bool ro_gui_window_toolbar_keypress(void *data, wimp_key *key)
-{
- struct gui_window *g = (struct gui_window *) data;
-
- if (g != NULL)
- return ro_gui_window_handle_local_keypress(g, key, true);
-
- return false;
-}
-
-
-/**
- * Handle keypresses within the RISC OS GUI: this is to be called after the
- * core has been given a chance to act, or on keypresses in the toolbar where
- * the core doesn't get involved.
+ * this is to be called after the core has been given a chance to act,
+ * or on keypresses in the toolbar where the core doesn't get
+ * involved.
*
- * \param *g The gui window to which the keypress applies.
- * \param *key The keypress data.
- * \param is_toolbar true if the keypress is from a toolbar;
- * else false.
- * \return true if the keypress was claimed; else false.
+ * \param *g The gui window to which the keypress applies.
+ * \param *key The keypress data.
+ * \param is_toolbar true if the keypress is from a toolbar else false.
+ * \return true if the keypress was claimed; else false.
*/
-
-bool ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key,
- bool is_toolbar)
+static bool
+ro_gui_window_handle_local_keypress(struct gui_window *g,
+ wimp_key *key,
+ bool is_toolbar)
{
struct browser_window_features cont;
os_error *ro_error;
@@ -2102,18 +1464,643 @@ bool ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key,
/**
- * Prepare the browser window menu for (re-)opening
+ * Callback handler for keypresses within browser window toolbars.
*
- * \param w The window owning the menu.
- * \param i The icon owning the menu.
- * \param *menu The menu about to be opened.
- * \param *pointer Pointer to the relevant wimp event block, or
- * NULL for an Adjust click.
- * \return true if the event was handled; else false.
+ * \param data Client data, pointing to the GUI Window.
+ * \param key The keypress data.
+ * \return true if the keypress was handled; else false.
*/
+static bool ro_gui_window_toolbar_keypress(void *data, wimp_key *key)
+{
+ struct gui_window *g = (struct gui_window *) data;
-bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
- wimp_pointer *pointer)
+ if (g != NULL) {
+ return ro_gui_window_handle_local_keypress(g, key, true);
+ }
+
+ return false;
+}
+
+
+/**
+ * Save a new toolbar button configuration
+ *
+ * used as a callback by the toolbar module when a buttonbar edit has
+ * finished.
+ *
+ * \param data void pointer to the window's gui_window struct
+ * \param config pointer to a malloc()'d button config string.
+ */
+static void ro_gui_window_save_toolbar_buttons(void *data, char *config)
+{
+ nsoption_set_charp(toolbar_browser, config);
+ ro_gui_save_options();
+}
+
+
+/**
+ * toolbar callbacks for a browser window.
+ */
+static const struct toolbar_callbacks ro_gui_window_toolbar_callbacks = {
+ ro_gui_window_update_theme,
+ ro_gui_window_update_toolbar,
+ (void (*)(void *)) ro_gui_window_update_toolbar_buttons,
+ ro_gui_window_toolbar_click,
+ ro_gui_window_toolbar_keypress,
+ ro_gui_window_save_toolbar_buttons
+};
+
+
+/**
+ * Handle wimp closing event
+ *
+ * \param w The window handle the event occoured on
+ */
+static void ro_gui_window_close(wimp_w w)
+{
+ struct gui_window *g;
+ wimp_pointer pointer;
+ os_error *error;
+ char *temp_name;
+ char *filename = NULL;
+ struct nsurl *url;
+ bool destroy;
+
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return;
+ }
+
+ g = (struct gui_window *)ro_gui_wimp_event_get_user_data(w);
+
+ if (pointer.buttons & wimp_CLICK_ADJUST) {
+ destroy = !ro_gui_shift_pressed();
+
+ url = browser_window_get_url(g->bw);
+ if (url != NULL) {
+ netsurf_nsurl_to_path(url, &filename);
+ }
+ if (filename != NULL) {
+ temp_name = malloc(strlen(filename) + 32);
+ if (temp_name) {
+ char *r;
+ sprintf(temp_name, "Filer_OpenDir %s",
+ filename);
+ r = temp_name + strlen(temp_name);
+ while (r > temp_name) {
+ if (*r == '.') {
+ *r = '\0';
+ break;
+ }
+ r--;
+ }
+ error = xos_cli(temp_name);
+ if (error) {
+ LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("MiscError", error->errmess);
+ return;
+ }
+ free(temp_name);
+ }
+ free(filename);
+ } else {
+ /* this is pointless if we are about to close the
+ * window */
+ if (!destroy && url != NULL)
+ browser_window_navigate_up(g->bw, false);
+ }
+ } else {
+ destroy = true;
+ }
+
+ if (destroy) {
+ browser_window_destroy(g->bw);
+ }
+}
+
+
+/**
+ * Handle a Redraw_Window_Request for a browser window.
+ *
+ * \param redraw The redraw event
+ */
+static void ro_gui_window_redraw(wimp_draw *redraw)
+{
+ osbool more;
+ struct gui_window *g;
+ os_error *error;
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &ro_plotters
+ };
+
+ g = (struct gui_window *)ro_gui_wimp_event_get_user_data(redraw->w);
+
+ /* We cannot render locked contents. If the browser window is not
+ * ready for redraw, do nothing. Else, in the case of buffered
+ * rendering we'll show random data. */
+ if (!browser_window_redraw_ready(g->bw)) {
+ return;
+ }
+
+ ro_gui_current_redraw_gui = g;
+
+ error = xwimp_redraw_window(redraw, &more);
+ if (error) {
+ LOG("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return;
+ }
+ while (more) {
+ struct rect clip;
+
+ /* OS's redraw request coordinates are in screen coordinates,
+ * with an origin at the bottom left of the screen.
+ * Find the coordinate of the top left of the document in terms
+ * of OS screen coordinates.
+ * NOTE: OS units are 2 per px. */
+ ro_plot_origin_x = redraw->box.x0 - redraw->xscroll;
+ ro_plot_origin_y = redraw->box.y1 - redraw->yscroll;
+
+ /* Convert OS redraw rectangle request coordinates into NetSurf
+ * coordinates. NetSurf coordinates have origin at top left of
+ * document and units are in px. */
+ clip.x0 = (redraw->clip.x0 - ro_plot_origin_x) / 2; /* left */
+ clip.y0 = (ro_plot_origin_y - redraw->clip.y1) / 2; /* top */
+ clip.x1 = (redraw->clip.x1 - ro_plot_origin_x) / 2; /* right */
+ clip.y1 = (ro_plot_origin_y - redraw->clip.y0) / 2; /* bottom */
+
+ if (ro_gui_current_redraw_gui->option.buffer_everything)
+ ro_gui_buffer_open(redraw);
+
+ browser_window_redraw(g->bw, 0, 0, &clip, &ctx);
+
+ if (ro_gui_current_redraw_gui->option.buffer_everything)
+ ro_gui_buffer_close();
+
+ /* Check to see if there are more rectangles to draw and
+ * get next one */
+ error = xwimp_get_rectangle(redraw, &more);
+ /* RISC OS 3.7 returns an error here if enough buffer was
+ claimed to cause a new dynamic area to be created. It
+ doesn't actually stop anything working, so we mask it out
+ for now until a better fix is found. This appears to be a
+ bug in RISC OS. */
+ if (error && !(ro_gui_current_redraw_gui->
+ option.buffer_everything &&
+ error->errnum == error_WIMP_GET_RECT)) {
+ LOG("xwimp_get_rectangle: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ ro_gui_current_redraw_gui = NULL;
+ return;
+ }
+ }
+ ro_gui_current_redraw_gui = NULL;
+}
+
+
+/**
+ * Process Scroll_Request events in a browser window.
+ *
+ * \param scroll The wimp scroll event data block.
+ */
+static void ro_gui_window_scroll(wimp_scroll *scroll)
+{
+ struct gui_window *g = ro_gui_window_lookup(scroll->w);
+
+ if (g && browser_window_has_content(g->bw) && ro_gui_shift_pressed()) {
+ /* extended scroll request with shift held down; change zoom */
+ float scale, inc;
+
+ if (scroll->ymin & 3)
+ inc = 0.02; /* RO5 sends the msg 5 times;
+ * don't ask me why
+ *
+ * @todo this is liable to break if
+ * HID is configured optimally for
+ * frame scrolling. *5 appears to be
+ * an artifact of non-HID mode scrolling.
+ */
+ else
+ inc = (1 << (ABS(scroll->ymin)>>2)) / 20.0F;
+
+ if (scroll->ymin > 0) {
+ scale = g->scale + inc;
+ if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1])
+ scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1];
+ } else {
+ scale = g->scale - inc;
+ if (scale < scale_snap_to[0])
+ scale = scale_snap_to[0];
+ }
+ if (g->scale != scale)
+ ro_gui_window_set_scale(g, scale);
+ } else if (g != NULL) {
+ ro_gui_window_scroll_action(g, scroll->xmin, scroll->ymin);
+ }
+}
+
+
+/**
+ * Process Pointer Leaving Window events in a browser window.
+ *
+ * These arrive via the termination callback handler from ro_mouse's
+ * mouse tracking.
+ *
+ * \param leaving The wimp pointer leaving event data block.
+ * \param data The GUI window that the pointer is leaving.
+ */
+static void ro_gui_window_track_end(wimp_leaving *leaving, void *data)
+{
+ struct gui_window *g = (struct gui_window *)data;
+
+ if (g != NULL) {
+ gui_window_set_pointer(g, GUI_POINTER_DEFAULT);
+ }
+}
+
+
+/**
+ * Process Pointer Entering Window events in a browser window.
+ *
+ * \param entering The wimp pointer entering event data block.
+ */
+static void ro_gui_window_pointer_entering(wimp_entering *entering)
+{
+ struct gui_window *g = ro_gui_window_lookup(entering->w);
+
+ if (g != NULL) {
+ ro_mouse_track_start(ro_gui_window_track_end,
+ ro_gui_window_mouse_at,
+ g);
+ }
+}
+
+
+/**
+ * Process Key_Pressed events in a browser window.
+ *
+ * \param key The wimp keypress block for the event.
+ * \return true if the event was handled, else false.
+ */
+static bool ro_gui_window_keypress(wimp_key *key)
+{
+ struct gui_window *g;
+ uint32_t c = (uint32_t) key->c;
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(key->w);
+ if (g == NULL) {
+ return false;
+ }
+
+ /* First send the key to the browser window, eg. form fields. */
+
+ if ((unsigned)c < 0x20 ||
+ (0x7f <= c && c <= 0x9f) ||
+ (c & IS_WIMP_KEY)) {
+ /* Munge control keys into unused control chars */
+ /* We can't map onto 1->26 (reserved for ctrl+<qwerty>
+ That leaves 27->31 and 128->159 */
+ switch (c & ~IS_WIMP_KEY) {
+ case wimp_KEY_TAB:
+ c = 9;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_TAB:
+ c = 11;
+ break;
+
+ /* cursor movement keys */
+ case wimp_KEY_HOME:
+ case wimp_KEY_CONTROL | wimp_KEY_LEFT:
+ c = NS_KEY_LINE_START;
+ break;
+
+ case wimp_KEY_END:
+ if (os_version >= RISCOS5) {
+ c = NS_KEY_LINE_END;
+ } else {
+ c = NS_KEY_DELETE_RIGHT;
+ }
+ break;
+
+ case wimp_KEY_CONTROL | wimp_KEY_RIGHT:
+ c = NS_KEY_LINE_END;
+ break;
+
+ case wimp_KEY_CONTROL | wimp_KEY_UP:
+ c = NS_KEY_TEXT_START;
+ break;
+
+ case wimp_KEY_CONTROL | wimp_KEY_DOWN:
+ c = NS_KEY_TEXT_END;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_LEFT:
+ c = NS_KEY_WORD_LEFT ;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_RIGHT:
+ c = NS_KEY_WORD_RIGHT;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_UP:
+ c = NS_KEY_PAGE_UP;
+ break;
+
+ case wimp_KEY_SHIFT | wimp_KEY_DOWN:
+ c = NS_KEY_PAGE_DOWN;
+ break;
+
+ case wimp_KEY_LEFT:
+ c = NS_KEY_LEFT;
+ break;
+
+ case wimp_KEY_RIGHT:
+ c = NS_KEY_RIGHT;
+ break;
+
+ case wimp_KEY_UP:
+ c = NS_KEY_UP;
+ break;
+
+ case wimp_KEY_DOWN:
+ c = NS_KEY_DOWN;
+ break;
+
+ /* editing */
+ case wimp_KEY_CONTROL | wimp_KEY_END:
+ c = NS_KEY_DELETE_LINE_END;
+ break;
+
+ case wimp_KEY_DELETE:
+ if (ro_gui_ctrl_pressed()) {
+ c = NS_KEY_DELETE_LINE_START;
+ } else if (os_version < RISCOS5) {
+ c = NS_KEY_DELETE_LEFT;
+ }
+ break;
+
+ case wimp_KEY_F8:
+ c = NS_KEY_UNDO;
+ break;
+
+ case wimp_KEY_F9:
+ c = NS_KEY_REDO;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!(c & IS_WIMP_KEY)) {
+ if (browser_window_key_press(g->bw, c)) {
+ return true;
+ }
+ }
+
+ return ro_gui_window_handle_local_keypress(g, key, false);
+}
+
+
+/**
+ * Handle Mouse_Click events in a browser window.
+ *
+ * This should never see Menu clicks, as these will be routed to the
+ * menu handlers.
+ *
+ * \param pointer details of mouse click
+ * \return true if click handled, false otherwise
+ */
+static bool ro_gui_window_click(wimp_pointer *pointer)
+{
+ struct gui_window *g;
+ os_coord pos;
+
+ /* We should never see Menu clicks. */
+
+ if (pointer->buttons == wimp_CLICK_MENU) {
+ return false;
+ }
+
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(pointer->w);
+
+ /* try to close url-completion */
+ ro_gui_url_complete_close();
+
+ /* set input focus */
+ if (pointer->buttons & (wimp_SINGLE_SELECT | wimp_SINGLE_ADJUST))
+ gui_window_place_caret(g, -100, -100, 0, NULL);
+
+ if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos)) {
+ browser_window_mouse_click(g->bw,
+ ro_gui_mouse_click_state(pointer->buttons,
+ wimp_BUTTON_DOUBLE_CLICK_DRAG),
+ pos.x, pos.y);
+ }
+
+ return true;
+}
+
+
+/**
+ * Prepare or reprepare a form select menu
+ *
+ * setting up the menu handle globals in the process.
+ *
+ * \param g The RISC OS gui window the menu is in.
+ * \param control The form control needing a menu.
+ * \return true if the menu is OK to be opened; else false.
+ */
+static bool
+ro_gui_window_prepare_form_select_menu(struct gui_window *g,
+ struct form_control *control)
+{
+ unsigned int item, entries;
+ char *text_convert, *temp;
+ struct form_option *option;
+ bool reopen = true;
+ nserror err;
+
+ assert(control);
+
+ /* enumerate the entries */
+ entries = 0;
+ option = form_select_get_option(control, entries);
+ while (option != NULL) {
+ entries++;
+ option = form_select_get_option(control, entries);
+ }
+
+ if (entries == 0) {
+ /* no menu to display */
+ ro_gui_menu_destroy();
+ return false;
+ }
+
+ /* free riscos menu if there already is one */
+ if ((gui_form_select_menu) && (control != gui_form_select_control)) {
+ for (item = 0; ; item++) {
+ free(gui_form_select_menu->entries[item].data.
+ indirected_text.text);
+ if (gui_form_select_menu->entries[item].menu_flags &
+ wimp_MENU_LAST)
+ break;
+ }
+ free(gui_form_select_menu->title_data.indirected_text.text);
+ free(gui_form_select_menu);
+ gui_form_select_menu = 0;
+ }
+
+ /* allocate new riscos menu */
+ if (!gui_form_select_menu) {
+ reopen = false;
+ gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries));
+ if (!gui_form_select_menu) {
+ ro_warn_user("NoMemory", 0);
+ ro_gui_menu_destroy();
+ return false;
+ }
+ err = utf8_to_local_encoding(messages_get("SelectMenu"), 0,
+ &text_convert);
+ if (err != NSERROR_OK) {
+ /* badenc should never happen */
+ assert(err != NSERROR_BAD_ENCODING);
+ LOG("utf8_to_local_encoding failed");
+ ro_warn_user("NoMemory", 0);
+ ro_gui_menu_destroy();
+ return false;
+ }
+ gui_form_select_menu->title_data.indirected_text.text =
+ text_convert;
+ ro_gui_menu_init_structure(gui_form_select_menu, entries);
+ }
+
+ /* initialise menu entries from form control */
+ for (item = 0; item < entries; item++) {
+ option = form_select_get_option(control, item);
+ gui_form_select_menu->entries[item].menu_flags = 0;
+ if (option->selected)
+ gui_form_select_menu->entries[item].menu_flags =
+ wimp_MENU_TICKED;
+ if (!reopen) {
+
+ /* convert spaces to hard spaces to stop things
+ * like 'Go Home' being treated as if 'Home' is a
+ * keyboard shortcut and right aligned in the menu.
+ */
+
+ temp = cnv_space2nbsp(option->text);
+ if (!temp) {
+ LOG("cnv_space2nbsp failed");
+ ro_warn_user("NoMemory", 0);
+ ro_gui_menu_destroy();
+ return false;
+ }
+
+ err = utf8_to_local_encoding(temp,
+ 0, &text_convert);
+ if (err != NSERROR_OK) {
+ /* A bad encoding should never happen,
+ * so assert this */
+ assert(err != NSERROR_BAD_ENCODING);
+ LOG("utf8_to_enc failed");
+ ro_warn_user("NoMemory", 0);
+ ro_gui_menu_destroy();
+ return false;
+ }
+
+ free(temp);
+
+ gui_form_select_menu->entries[item].data.indirected_text.text =
+ text_convert;
+ gui_form_select_menu->entries[item].data.indirected_text.size =
+ strlen(gui_form_select_menu->entries[item].
+ data.indirected_text.text) + 1;
+ }
+ }
+
+ gui_form_select_menu->entries[0].menu_flags |=
+ wimp_MENU_TITLE_INDIRECTED;
+ gui_form_select_menu->entries[item - 1].menu_flags |= wimp_MENU_LAST;
+
+ return true;
+}
+
+
+/**
+ * Return boolean flags to show what RISC OS types we can sensibly convert
+ * the given object into.
+ *
+ * \todo This should probably be somewhere else but in window.c, and
+ * should probably even be done in content_().
+ *
+ * \param h The object to test.
+ * \param export_draw true on exit if a drawfile would be possible.
+ * \param export_sprite true on exit if a sprite would be possible.
+ * \return true if valid data is returned; else false.
+ */
+static bool
+ro_gui_window_content_export_types(struct hlcache_handle *h,
+ bool *export_draw,
+ bool *export_sprite)
+{
+ bool found_type = false;
+
+ if (export_draw != NULL) {
+ *export_draw = false;
+ }
+ if (export_sprite != NULL) {
+ *export_sprite = false;
+ }
+
+ if (h != NULL && content_get_type(h) == CONTENT_IMAGE) {
+ switch (ro_content_native_type(h)) {
+ case osfile_TYPE_SPRITE:
+ /* bitmap types (Sprite export possible) */
+ found_type = true;
+ if (export_sprite != NULL) {
+ *export_sprite = true;
+ }
+ break;
+
+ case osfile_TYPE_DRAW:
+ /* vector types (Draw export possible) */
+ found_type = true;
+ if (export_draw != NULL) {
+ *export_draw = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return found_type;
+}
+
+
+/**
+ * Prepare the browser window menu for (re-)opening
+ *
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param menu The menu about to be opened.
+ * \param pointer Pointer to the relevant wimp event block, or
+ * NULL for an Adjust click.
+ * \return true if the event was handled; else false.
+ */
+static bool
+ro_gui_window_menu_prepare(wimp_w w,
+ wimp_i i,
+ wimp_menu *menu,
+ wimp_pointer *pointer)
{
struct gui_window *g;
struct browser_window *bw;
@@ -2138,13 +2125,13 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
gui_form_select_control);
}
- if (menu != ro_gui_browser_window_menu)
+ if (menu != ro_gui_browser_window_menu) {
return false;
+ }
/* If this is a new opening for the browser window menu (ie. not for a
* toolbar menu), get details of the object under the pointer.
*/
-
if (pointer != NULL && g->window == w) {
ro_gui_url_complete_close();
@@ -2255,13 +2242,14 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_SAVE_URL_TEXT,
current_menu_object == NULL);
- if (current_menu_object != NULL)
+ if (current_menu_object != NULL) {
ro_gui_window_content_export_types(current_menu_object,
&export_draw, &export_sprite);
- else
+ } else {
ro_gui_window_content_export_types(
browser_window_get_content(bw),
&export_draw, &export_sprite);
+ }
ro_gui_menu_set_entry_shaded(menu, BROWSER_OBJECT_EXPORT,
(!have_content && current_menu_object == NULL)
@@ -2319,14 +2307,15 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
/* View Submenu */
ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_FOREGROUND,
- g != NULL && nsoption_bool(foreground_images));
+ g != NULL && nsoption_bool(foreground_images));
ro_gui_menu_set_entry_ticked(menu, BROWSER_IMAGES_BACKGROUND,
- g != NULL && nsoption_bool(background_images));
+ g != NULL && nsoption_bool(background_images));
ro_gui_menu_set_entry_shaded(menu, BROWSER_BUFFER_ANIMS,
g == NULL || g->option.buffer_everything);
- ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ANIMS, g != NULL &&
+ ro_gui_menu_set_entry_ticked(menu, BROWSER_BUFFER_ANIMS,
+ g != NULL &&
(g->option.buffer_animations ||
g->option.buffer_everything));
@@ -2337,16 +2326,16 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
ro_gui_menu_set_entry_shaded(menu, BROWSER_SCALE_VIEW, !have_content);
ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_STAGGER,
- nsoption_int(window_screen_width) == 0);
+ nsoption_int(window_screen_width) == 0);
ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_STAGGER,
- ((nsoption_int(window_screen_width) == 0) ||
- nsoption_bool(window_stagger)));
+ ((nsoption_int(window_screen_width) == 0) ||
+ nsoption_bool(window_stagger)));
ro_gui_menu_set_entry_ticked(menu, BROWSER_WINDOW_COPY,
- nsoption_bool(window_size_clone));
+ nsoption_bool(window_size_clone));
ro_gui_menu_set_entry_shaded(menu, BROWSER_WINDOW_RESET,
- nsoption_int(window_screen_width) == 0);
+ nsoption_int(window_screen_width) == 0);
/* Utilities Submenu */
@@ -2370,199 +2359,72 @@ bool ro_gui_window_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu,
/**
- * Handle submenu warnings for a browser window menu
+ * Process selections from a form select menu, passing them back to the core.
*
- * \param w The window owning the menu.
- * \param i The icon owning the menu.
- * \param *menu The menu to which the warning applies.
- * \param *selection The wimp menu selection data.
- * \param action The selected menu action.
+ * \param g The browser window affected by the menu.
+ * \param selection The menu selection.
*/
-
-void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
- wimp_selection *selection, menu_action action)
+static void
+ro_gui_window_process_form_select_menu(struct gui_window *g,
+ wimp_selection *selection)
{
- struct gui_window *g;
- struct hlcache_handle *h;
- bool export;
-
- if (menu != ro_gui_browser_window_menu)
- return;
-
- g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
- h = browser_window_get_content(g->bw);
-
- switch (action) {
- case BROWSER_PAGE_INFO:
- if (h != NULL)
- ro_gui_window_prepare_pageinfo(g);
- break;
-
- case BROWSER_FIND_TEXT:
- if (h != NULL && (content_get_type(h) == CONTENT_HTML ||
- content_get_type(h) == CONTENT_TEXTPLAIN))
- ro_gui_search_prepare(g->bw);
- break;
-
- case BROWSER_SCALE_VIEW:
- if (h != NULL)
- ro_gui_dialog_prepare_zoom(g);
- break;
-
- case BROWSER_PRINT:
- if (h != NULL)
- ro_gui_print_prepare(g);
- break;
-
- case BROWSER_OBJECT_INFO:
- if (current_menu_object != NULL)
- ro_gui_window_prepare_objectinfo(current_menu_object,
- current_menu_url);
- break;
-
- case BROWSER_OBJECT_SAVE:
- if (current_menu_object != NULL)
- ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
- current_menu_object, NULL, NULL, NULL);
- break;
-
- case BROWSER_SELECTION_SAVE:
- if (browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY)
- ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
- browser_window_get_selection(g->bw),
- NULL, NULL);
- break;
-
- case BROWSER_SAVE_URL_URI:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
- hlcache_handle_get_url(h),
- content_get_title(h));
- break;
-
- case BROWSER_SAVE_URL_URL:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
- hlcache_handle_get_url(h),
- content_get_title(h));
- break;
-
- case BROWSER_SAVE_URL_TEXT:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
- hlcache_handle_get_url(h),
- content_get_title(h));
- break;
-
- case BROWSER_OBJECT_SAVE_URL_URI:
- if (current_menu_object != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
- hlcache_handle_get_url(
- current_menu_object),
- content_get_title(current_menu_object));
- break;
-
- case BROWSER_OBJECT_SAVE_URL_URL:
- if (current_menu_object != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
- hlcache_handle_get_url(
- current_menu_object),
- content_get_title(current_menu_object));
- break;
-
- case BROWSER_OBJECT_SAVE_URL_TEXT:
- if (current_menu_object != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
- hlcache_handle_get_url(
- current_menu_object),
- content_get_title(current_menu_object));
- break;
-
- case BROWSER_SAVE:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_SOURCE, h, NULL, NULL, NULL);
- break;
-
- case BROWSER_SAVE_COMPLETE:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_COMPLETE, h, NULL, NULL, NULL);
- break;
-
- case BROWSER_EXPORT_DRAW:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_DRAW, h, NULL, NULL, NULL);
- break;
-
- case BROWSER_EXPORT_PDF:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_PDF, h, NULL, NULL, NULL);
- break;
-
- case BROWSER_EXPORT_TEXT:
- if (h != NULL)
- ro_gui_save_prepare(GUI_SAVE_TEXT, h, NULL, NULL, NULL);
- break;
-
- case BROWSER_LINK_SAVE_URI:
- if (current_menu_url != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
- current_menu_url, NULL);
- break;
-
- case BROWSER_LINK_SAVE_URL:
- if (current_menu_url != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
- current_menu_url, NULL);
- break;
+ assert(g != NULL);
- case BROWSER_LINK_SAVE_TEXT:
- if (current_menu_url != NULL)
- ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
- current_menu_url, NULL);
- break;
+ if (selection->items[0] >= 0) {
+ form_select_process_selection(gui_form_select_control,
+ selection->items[0]);
+ }
+}
- case BROWSER_OBJECT_EXPORT_SPRITE:
- if (current_menu_object != NULL) {
- ro_gui_window_content_export_types(current_menu_object,
- NULL, &export);
- if (export)
- ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
- current_menu_object,
- NULL, NULL, NULL);
- } else if (h != NULL) {
- ro_gui_window_content_export_types(h, NULL, &export);
+/**
+ * Prepare the object info window for use
+ *
+ * \param object the object for which information is to be displayed
+ * \param target_url corresponding url, if any
+ */
+static void
+ro_gui_window_prepare_objectinfo(struct hlcache_handle *object,
+ nsurl *target_url)
+{
+ char icon_buf[20] = "file_xxx";
+ const char *url;
+ lwc_string *mime;
+ const char *target = "-";
- if (export)
- ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
- h, NULL, NULL, NULL);
- }
- break;
+ sprintf(icon_buf, "file_%.3x",ro_content_filetype(object));
+ if (!ro_gui_wimp_sprite_exists(icon_buf)) {
+ sprintf(icon_buf, "file_xxx");
+ }
- case BROWSER_OBJECT_EXPORT_DRAW:
- if (current_menu_object != NULL) {
- ro_gui_window_content_export_types(current_menu_object,
- &export, NULL);
+ url = nsurl_access(hlcache_handle_get_url(object));
+ if (url == NULL) {
+ url = "-";
+ }
+ mime = content_get_mime_type(object);
- if (export)
- ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
- current_menu_object,
- NULL, NULL, NULL);
- } else if (h != NULL) {
- ro_gui_window_content_export_types(h, &export, NULL);
+ if (target_url != NULL) {
+ target = nsurl_access(target_url);
+ }
- if (export)
- ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
- h, NULL, NULL, NULL);
- }
- break;
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON,
+ icon_buf, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL,
+ url, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET,
+ target, true);
+ ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE,
+ lwc_string_data(mime), true);
- default:
- break;
- }
+ lwc_string_unref(mime);
}
+/**
+ * callback to handle window paste operation
+ *
+ * \param pw context containing browser window
+ */
static void ro_gui_window_paste_cb(void *pw)
{
struct browser_window *bw = pw;
@@ -2574,22 +2436,25 @@ static void ro_gui_window_paste_cb(void *pw)
/**
* Handle selections from a browser window menu
*
- * \param w The window owning the menu.
- * \param i The icon owning the menu.
- * \param *menu The menu from which the selection was made.
- * \param *selection The wimp menu selection data.
- * \param action The selected menu action.
- * \return true if action accepted; else false.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param menu The menu from which the selection was made.
+ * \param selection The wimp menu selection data.
+ * \param action The selected menu action.
+ * \return true if action accepted; else false.
*/
-
-bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
- wimp_selection *selection, menu_action action)
+static bool
+ro_gui_window_menu_select(wimp_w w,
+ wimp_i i,
+ wimp_menu *menu,
+ wimp_selection *selection,
+ menu_action action)
{
- struct gui_window *g;
- struct browser_window *bw;
- struct hlcache_handle *h;
- struct toolbar *toolbar;
- wimp_window_state state;
+ struct gui_window *g;
+ struct browser_window *bw;
+ struct hlcache_handle *h;
+ struct toolbar *toolbar;
+ wimp_window_state state;
nsurl *url;
nserror error = NSERROR_OK;
@@ -2601,7 +2466,6 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
/* If this is a form menu from the core, handle it now and then exit.
* Otherwise, carry on to the main browser window menu.
*/
-
if (menu == gui_form_select_menu && w == g->window) {
ro_gui_window_process_form_select_menu(g, selection);
@@ -2619,10 +2483,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("http://www.netsurf-browser.org/documentation/", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2631,10 +2495,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("http://www.netsurf-browser.org/documentation/guide", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2643,10 +2507,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("http://www.netsurf-browser.org/documentation/info", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2655,10 +2519,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("about:credits", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2667,10 +2531,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
error = nsurl_create("about:licence", &url);
if (error == NSERROR_OK) {
error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
+ url,
+ NULL,
+ NULL,
+ NULL);
nsurl_unref(url);
}
break;
@@ -2680,7 +2544,8 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
ro_gui_interactive_help_start();
nsoption_set_bool(interactive_help, true);
} else {
- nsoption_set_bool(interactive_help, !nsoption_bool(interactive_help));
+ nsoption_set_bool(interactive_help,
+ !nsoption_bool(interactive_help));
}
break;
@@ -2732,9 +2597,10 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
case BROWSER_OBJECT_INFO:
if (current_menu_object != NULL) {
ro_gui_window_prepare_objectinfo(current_menu_object,
- current_menu_url);
+ current_menu_url);
ro_gui_dialog_open_persistent(g->window,
- dialog_objinfo, false);
+ dialog_objinfo,
+ false);
}
break;
case BROWSER_OBJECT_RELOAD:
@@ -2747,50 +2613,62 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
/* link actions */
case BROWSER_LINK_SAVE_URI:
if (current_menu_url != NULL) {
- ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
- current_menu_url, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI,
+ NULL,
+ NULL,
+ current_menu_url,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
case BROWSER_LINK_SAVE_URL:
if (current_menu_url != NULL) {
- ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
- current_menu_url, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL,
+ NULL,
+ NULL,
+ current_menu_url,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
case BROWSER_LINK_SAVE_TEXT:
if (current_menu_url != NULL) {
- ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
- current_menu_url, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT,
+ NULL,
+ NULL,
+ current_menu_url,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
case BROWSER_LINK_DOWNLOAD:
if (current_menu_url != NULL) {
- error = browser_window_navigate(bw,
- current_menu_url,
- browser_window_get_url(bw),
- BW_NAVIGATE_DOWNLOAD,
- NULL,
- NULL,
- NULL);
+ error = browser_window_navigate(
+ bw,
+ current_menu_url,
+ browser_window_get_url(bw),
+ BW_NAVIGATE_DOWNLOAD,
+ NULL,
+ NULL,
+ NULL);
}
break;
case BROWSER_LINK_NEW_WINDOW:
if (current_menu_url != NULL) {
error = browser_window_create(
- BW_CREATE_HISTORY |
- BW_CREATE_CLONE,
- current_menu_url,
- browser_window_get_url(bw),
- bw,
- NULL);
+ BW_CREATE_HISTORY | BW_CREATE_CLONE,
+ current_menu_url,
+ browser_window_get_url(bw),
+ bw,
+ NULL);
}
break;
@@ -2799,24 +2677,36 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
case BROWSER_OBJECT_SAVE:
if (current_menu_object != NULL) {
ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
- current_menu_object, NULL, NULL, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ current_menu_object,
+ NULL,
+ NULL,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
case BROWSER_OBJECT_EXPORT_SPRITE:
if (current_menu_object != NULL) {
ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
- current_menu_object, NULL, NULL, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ current_menu_object,
+ NULL,
+ NULL,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
case BROWSER_OBJECT_EXPORT_DRAW:
if (current_menu_object != NULL) {
ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
- current_menu_object, NULL, NULL, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ current_menu_object,
+ NULL,
+ NULL,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
@@ -2848,10 +2738,13 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
/* selection actions */
case BROWSER_SELECTION_SAVE:
if (h != NULL) {
- ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
+ ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION,
+ NULL,
browser_window_get_selection(bw),
- NULL, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas,
+ NULL,
+ NULL);
+ ro_gui_dialog_open_persistent(g->window,
+ dialog_saveas,
false);
}
break;
@@ -2970,19 +2863,19 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
case TOOLBAR_BUTTONS:
assert(toolbar);
ro_toolbar_set_display_buttons(toolbar,
- !ro_toolbar_get_display_buttons(toolbar));
+ !ro_toolbar_get_display_buttons(toolbar));
break;
case TOOLBAR_ADDRESS_BAR:
assert(toolbar);
ro_toolbar_set_display_url(toolbar,
- !ro_toolbar_get_display_url(toolbar));
+ !ro_toolbar_get_display_url(toolbar));
if (ro_toolbar_get_display_url(toolbar))
ro_toolbar_take_caret(toolbar);
break;
case TOOLBAR_THROBBER:
assert(toolbar);
ro_toolbar_set_display_throbber(toolbar,
- !ro_toolbar_get_display_throbber(toolbar));
+ !ro_toolbar_get_display_throbber(toolbar));
break;
case TOOLBAR_EDIT:
assert(toolbar);
@@ -3002,467 +2895,875 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
/**
- * Handle the closure of a browser window menu
+ * Handle submenu warnings for a browser window menu
*
- * \param w The window owning the menu.
- * \param i The icon owning the menu.
- * \param *menu The menu that is being closed.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param menu The menu to which the warning applies.
+ * \param selection The wimp menu selection data.
+ * \param action The selected menu action.
*/
-
-void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu)
+static void
+ro_gui_window_menu_warning(wimp_w w,
+ wimp_i i,
+ wimp_menu *menu,
+ wimp_selection *selection,
+ menu_action action)
{
- if (menu == ro_gui_browser_window_menu) {
- current_menu_object = NULL;
- current_menu_url = NULL;
- } else if (menu == gui_form_select_menu) {
- gui_form_select_control = NULL;
+ struct gui_window *g;
+ struct hlcache_handle *h;
+ bool export;
+
+ if (menu != ro_gui_browser_window_menu) {
+ return;
}
-}
+ g = (struct gui_window *) ro_gui_wimp_event_get_user_data(w);
+ h = browser_window_get_content(g->bw);
-/**
- * Process Scroll_Request events in a browser window.
- *
- * \param *scroll The wimp scroll event data block.
- */
+ switch (action) {
+ case BROWSER_PAGE_INFO:
+ if (h != NULL) {
+ ro_gui_window_prepare_pageinfo(g);
+ }
+ break;
-void ro_gui_window_scroll(wimp_scroll *scroll)
-{
- struct gui_window *g = ro_gui_window_lookup(scroll->w);
+ case BROWSER_FIND_TEXT:
+ if (h != NULL &&
+ (content_get_type(h) == CONTENT_HTML ||
+ content_get_type(h) == CONTENT_TEXTPLAIN)) {
+ ro_gui_search_prepare(g->bw);
+ }
+ break;
- if (g && browser_window_has_content(g->bw) && ro_gui_shift_pressed()) {
- /* extended scroll request with shift held down; change zoom */
- float scale, inc;
+ case BROWSER_SCALE_VIEW:
+ if (h != NULL) {
+ ro_gui_dialog_prepare_zoom(g);
+ }
+ break;
- if (scroll->ymin & 3)
- inc = 0.02; /* RO5 sends the msg 5 times;
- * don't ask me why
- *
- * @todo this is liable to break if
- * HID is configured optimally for
- * frame scrolling. *5 appears to be
- * an artifact of non-HID mode scrolling.
- */
- else
- inc = (1 << (ABS(scroll->ymin)>>2)) / 20.0F;
+ case BROWSER_PRINT:
+ if (h != NULL) {
+ ro_gui_print_prepare(g);
+ }
+ break;
- if (scroll->ymin > 0) {
- scale = g->scale + inc;
- if (scale > scale_snap_to[SCALE_SNAP_TO_SIZE - 1])
- scale = scale_snap_to[SCALE_SNAP_TO_SIZE - 1];
- } else {
- scale = g->scale - inc;
- if (scale < scale_snap_to[0])
- scale = scale_snap_to[0];
+ case BROWSER_OBJECT_INFO:
+ if (current_menu_object != NULL) {
+ ro_gui_window_prepare_objectinfo(current_menu_object,
+ current_menu_url);
}
- if (g->scale != scale)
- ro_gui_window_set_scale(g, scale);
- } else if (g != NULL) {
- ro_gui_window_scroll_action(g, scroll->xmin, scroll->ymin);
+ break;
+
+ case BROWSER_OBJECT_SAVE:
+ if (current_menu_object != NULL) {
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG,
+ current_menu_object,
+ NULL,
+ NULL,
+ NULL);
+ }
+ break;
+
+ case BROWSER_SELECTION_SAVE:
+ if (browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY)
+ ro_gui_save_prepare(GUI_SAVE_TEXT_SELECTION, NULL,
+ browser_window_get_selection(g->bw),
+ NULL, NULL);
+ break;
+
+ case BROWSER_SAVE_URL_URI:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ hlcache_handle_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_SAVE_URL_URL:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ hlcache_handle_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_SAVE_URL_TEXT:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ hlcache_handle_get_url(h),
+ content_get_title(h));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_URI:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ hlcache_handle_get_url(
+ current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_URL:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ hlcache_handle_get_url(
+ current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_OBJECT_SAVE_URL_TEXT:
+ if (current_menu_object != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ hlcache_handle_get_url(
+ current_menu_object),
+ content_get_title(current_menu_object));
+ break;
+
+ case BROWSER_SAVE:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_SOURCE, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_SAVE_COMPLETE:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_COMPLETE, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_DRAW:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_DRAW, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_PDF:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_PDF, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_EXPORT_TEXT:
+ if (h != NULL)
+ ro_gui_save_prepare(GUI_SAVE_TEXT, h, NULL, NULL, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_URI:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URI, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_URL:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_LINK_SAVE_TEXT:
+ if (current_menu_url != NULL)
+ ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, NULL, NULL,
+ current_menu_url, NULL);
+ break;
+
+ case BROWSER_OBJECT_EXPORT_SPRITE:
+ if (current_menu_object != NULL) {
+ ro_gui_window_content_export_types(current_menu_object,
+ NULL, &export);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object,
+ NULL, NULL, NULL);
+ } else if (h != NULL) {
+ ro_gui_window_content_export_types(h, NULL, &export);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ h, NULL, NULL, NULL);
+ }
+ break;
+
+ case BROWSER_OBJECT_EXPORT_DRAW:
+ if (current_menu_object != NULL) {
+ ro_gui_window_content_export_types(current_menu_object,
+ &export, NULL);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ current_menu_object,
+ NULL, NULL, NULL);
+ } else if (h != NULL) {
+ ro_gui_window_content_export_types(h, &export, NULL);
+
+ if (export)
+ ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE,
+ h, NULL, NULL, NULL);
+ }
+ break;
+
+ default:
+ break;
}
}
+
/**
- * Process Pointer Entering Window events in a browser window.
+ * Handle the closure of a browser window menu
*
- * \param *entering The wimp pointer entering event data block.
+ * \param w The window owning the menu.
+ * \param i The icon owning the menu.
+ * \param menu The menu that is being closed.
*/
-
-static void ro_gui_window_pointer_entering(wimp_entering *entering)
+static void ro_gui_window_menu_close(wimp_w w, wimp_i i, wimp_menu *menu)
{
- struct gui_window *g = ro_gui_window_lookup(entering->w);
-
- if (g != NULL)
- ro_mouse_track_start(ro_gui_window_track_end,
- ro_gui_window_mouse_at, g);
+ if (menu == ro_gui_browser_window_menu) {
+ current_menu_object = NULL;
+ current_menu_url = NULL;
+ } else if (menu == gui_form_select_menu) {
+ gui_form_select_control = NULL;
+ }
}
+
/**
- * Process Pointer Leaving Window events in a browser window. These arrive via
- * the termination callback handler from ro_mouse's mouse tracking.
+ * Clones a browser window's options.
*
- * \param *leaving The wimp pointer leaving event data block.
- * \param *data The GUI window that the pointer is leaving.
+ * \param new_gui the new gui window
+ * \param old_gui the gui window to clone from, or NULL for default
*/
-
-static void ro_gui_window_track_end(wimp_leaving *leaving, void *data)
+static void
+ro_gui_window_clone_options(struct gui_window *new_gui,
+ struct gui_window *old_gui)
{
- struct gui_window *g = (struct gui_window *) data;
+ assert(new_gui);
- if (g != NULL)
- gui_window_set_pointer(g, GUI_POINTER_DEFAULT);
+ /* Clone the basic options
+ */
+ if (!old_gui) {
+ new_gui->option.buffer_animations = nsoption_bool(buffer_animations);
+ new_gui->option.buffer_everything = nsoption_bool(buffer_everything);
+ } else {
+ new_gui->option = old_gui->option;
+ }
+
+ /* Set up the toolbar
+ */
+ if (new_gui->toolbar) {
+ ro_toolbar_set_display_buttons(new_gui->toolbar,
+ nsoption_bool(toolbar_show_buttons));
+ ro_toolbar_set_display_url(new_gui->toolbar,
+ nsoption_bool(toolbar_show_address));
+ ro_toolbar_set_display_throbber(new_gui->toolbar,
+ nsoption_bool(toolbar_show_throbber));
+ if ((old_gui) && (old_gui->toolbar)) {
+ ro_toolbar_set_display_buttons(new_gui->toolbar,
+ ro_toolbar_get_display_buttons(
+ old_gui->toolbar));
+ ro_toolbar_set_display_url(new_gui->toolbar,
+ ro_toolbar_get_display_url(
+ old_gui->toolbar));
+ ro_toolbar_set_display_throbber(new_gui->toolbar,
+ ro_toolbar_get_display_throbber(
+ old_gui->toolbar));
+ ro_toolbar_process(new_gui->toolbar, -1, true);
+ }
+ }
}
/**
- * Scroll a browser window, either via the core or directly using the
- * normal Wimp_OpenWindow interface.
- *
- * Scroll steps are supplied in terms of the (extended) Scroll Event direction
- * values returned by Wimp_Poll. Special values of 0x7fffffff and 0x80000000
- * are added to mean "Home" and "End".
+ * Create and open a new browser window.
*
- * \param *g The GUI Window to be scrolled.
- * \param scroll_x The X scroll step to be applied.
- * \param scroll_y The Y scroll step to be applied.
+ * \param bw bw to create gui_window for
+ * \param existing an existing gui_window, may be NULL
+ * \param flags flags for gui window creation
+ * \return gui window, or NULL on error
*/
-
-void ro_gui_window_scroll_action(struct gui_window *g,
- wimp_scroll_direction scroll_x, wimp_scroll_direction scroll_y)
+static struct gui_window *gui_window_create(struct browser_window *bw,
+ struct gui_window *existing,
+ gui_window_create_flags flags)
{
- int visible_x, visible_y;
- int step_x = 0, step_y = 0;
- int toolbar_y;
- wimp_window_state state;
- wimp_pointer pointer;
- os_error *error;
- os_coord pos;
- bool handled = false;
- struct toolbar *toolbar;
+ int screen_width, screen_height;
+ static int window_count = 2;
+ wimp_window window;
+ wimp_window_state state;
+ os_error *error;
+ bool open_centred = true;
+ struct gui_window *g;
- if (g == NULL)
- return;
+ g = malloc(sizeof *g);
+ if (!g) {
+ ro_warn_user("NoMemory", 0);
+ return 0;
+ }
+ g->bw = bw;
+ g->toolbar = 0;
+ g->status_bar = 0;
+ g->old_width = 0;
+ g->old_height = 0;
+ g->update_extent = true;
+ g->active = false;
+ strcpy(g->title, "NetSurf");
+ g->iconise_icon = -1;
+ g->scale = browser_window_get_scale(bw);
- /* Get the current window, toolbar and pointer details. */
+ /* Set the window position */
+ if (existing != NULL &&
+ flags & GW_CREATE_CLONE &&
+ nsoption_bool(window_size_clone)) {
+ state.w = existing->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ window.visible.x0 = state.visible.x0;
+ window.visible.x1 = state.visible.x1;
+ window.visible.y0 = state.visible.y0 - 48;
+ window.visible.y1 = state.visible.y1 - 48;
+ open_centred = false;
+ } else {
+ int win_width, win_height;
+ ro_gui_screen_size(&screen_width, &screen_height);
- state.w = g->window;
- error = xwimp_get_window_state(&state);
- if (error) {
- LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
- return;
+ /* Check if we have a preferred position */
+ if ((nsoption_int(window_screen_width) != 0) &&
+ (nsoption_int(window_screen_height) != 0)) {
+ win_width = (nsoption_int(window_width) *
+ screen_width) /
+ nsoption_int(window_screen_width);
+ win_height = (nsoption_int(window_height) *
+ screen_height) /
+ nsoption_int(window_screen_height);
+ window.visible.x0 = (nsoption_int(window_x) *
+ screen_width) /
+ nsoption_int(window_screen_width);
+ window.visible.y0 = (nsoption_int(window_y) *
+ screen_height) /
+ nsoption_int(window_screen_height);
+ if (nsoption_bool(window_stagger)) {
+ window.visible.y0 += 96 -
+ (48 * (window_count % 5));
+ }
+ open_centred = false;
+ if (win_width < 100)
+ win_width = 100;
+ if (win_height < 100)
+ win_height = 100;
+ } else {
+
+ /* Base how we define the window height/width
+ on the compile time options set */
+ win_width = screen_width * 3 / 4;
+ if (1600 < win_width)
+ win_width = 1600;
+ win_height = win_width * 3 / 4;
+
+ window.visible.x0 = (screen_width - win_width) / 2;
+ window.visible.y0 = ((screen_height - win_height) / 2) +
+ 96 - (48 * (window_count % 5));
+ }
+ window.visible.x1 = window.visible.x0 + win_width;
+ window.visible.y1 = window.visible.y0 + win_height;
}
- toolbar = ro_toolbar_parent_window_lookup(g->window);
- assert(g == NULL || g->toolbar == NULL || g->toolbar == toolbar);
+ /* General flags for a non-movable, non-resizable, no-title bar window */
+ window.xscroll = 0;
+ window.yscroll = 0;
+ window.next = wimp_TOP;
+ window.flags = wimp_WINDOW_MOVEABLE |
+ wimp_WINDOW_NEW_FORMAT |
+ wimp_WINDOW_VSCROLL |
+ wimp_WINDOW_HSCROLL |
+ wimp_WINDOW_IGNORE_XEXTENT |
+ wimp_WINDOW_IGNORE_YEXTENT |
+ wimp_WINDOW_SCROLL_REPEAT;
+ window.title_fg = wimp_COLOUR_BLACK;
+ window.title_bg = wimp_COLOUR_LIGHT_GREY;
+ window.work_fg = wimp_COLOUR_LIGHT_GREY;
+ window.work_bg = wimp_COLOUR_TRANSPARENT;
+ window.scroll_outer = wimp_COLOUR_DARK_GREY;
+ window.scroll_inner = wimp_COLOUR_MID_LIGHT_GREY;
+ window.highlight_bg = wimp_COLOUR_CREAM;
+ window.extra_flags = wimp_WINDOW_USE_EXTENDED_SCROLL_REQUEST |
+ wimp_WINDOW_GIVE_SHADED_ICON_INFO;
+ window.extent.x0 = 0;
+ window.extent.y0 = -(window.visible.y1 - window.visible.y0);
+ window.extent.x1 = window.visible.x1 - window.visible.x0;
+ window.extent.y1 = 0;
+ window.title_flags = wimp_ICON_TEXT |
+ wimp_ICON_INDIRECTED |
+ wimp_ICON_HCENTRED;
+ window.work_flags = wimp_BUTTON_DOUBLE_CLICK_DRAG <<
+ wimp_ICON_BUTTON_TYPE_SHIFT;
+ window.sprite_area = wimpspriteop_AREA;
+ window.xmin = 1;
+ window.ymin = 1;
+ window.title_data.indirected_text.text = g->title;
+ window.title_data.indirected_text.validation = (char *) -1;
+ window.title_data.indirected_text.size = 255;
+ window.icon_count = 0;
- toolbar_y = (toolbar == NULL) ? 0 : ro_toolbar_full_height(toolbar);
+ /* Add in flags */
+ window.flags |= wimp_WINDOW_SIZE_ICON |
+ wimp_WINDOW_BACK_ICON |
+ wimp_WINDOW_CLOSE_ICON |
+ wimp_WINDOW_TITLE_ICON |
+ wimp_WINDOW_TOGGLE_ICON;
- visible_x = state.visible.x1 - state.visible.x0 - 32;
- visible_y = state.visible.y1 - state.visible.y0 - 32 - toolbar_y;
+ if (open_centred) {
+ int scroll_width = ro_get_vscroll_width(NULL);
+ window.visible.x0 -= scroll_width;
+ }
- error = xwimp_get_pointer_info(&pointer);
+ error = xwimp_create_window(&window, &g->window);
if (error) {
- LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ LOG("xwimp_create_window: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
- return;
+ free(g);
+ return 0;
}
- /* Turn the scroll requirement from Scroll Event codes into coordinates
- * that the core can understand.
- */
+ /* Link into window list */
+ g->prev = 0;
+ g->next = window_list;
+ if (window_list)
+ window_list->prev = g;
+ window_list = g;
+ window_count++;
- switch (scroll_x) {
- case wimp_SCROLL_PAGE_LEFT:
- step_x = SCROLL_PAGE_DOWN;
- break;
- case wimp_SCROLL_AUTO_LEFT:
- case wimp_SCROLL_COLUMN_LEFT:
- step_x = -16;
- break;
- case wimp_SCROLL_AUTO_RIGHT:
- case wimp_SCROLL_COLUMN_RIGHT:
- step_x = 16;
- break;
- case wimp_SCROLL_PAGE_RIGHT:
- step_x = SCROLL_PAGE_UP;
- break;
- case 0x80000000:
- step_x = SCROLL_BOTTOM;
- break;
- case 0x7fffffff:
- step_x = SCROLL_TOP;
- break;
- default:
- step_x = (visible_x * (scroll_x>>2)) >> 2;
- break;
+ /* Add in a toolbar and status bar */
+ g->status_bar = ro_gui_status_bar_create(g->window,
+ nsoption_int(toolbar_status_size));
+ g->toolbar = ro_toolbar_create(NULL, g->window,
+ THEME_STYLE_BROWSER_TOOLBAR, TOOLBAR_FLAGS_NONE,
+ &ro_gui_window_toolbar_callbacks, g,
+ "HelpToolbar");
+ if (g->toolbar != NULL) {
+ ro_toolbar_add_buttons(g->toolbar,
+ brower_toolbar_buttons,
+ nsoption_charp(toolbar_browser));
+ ro_toolbar_add_url(g->toolbar);
+ ro_toolbar_add_throbber(g->toolbar);
+ ro_toolbar_rebuild(g->toolbar);
}
- switch (scroll_y) {
- case wimp_SCROLL_PAGE_UP:
- step_y = SCROLL_PAGE_UP;
- break;
- case wimp_SCROLL_AUTO_UP:
- case wimp_SCROLL_LINE_UP:
- step_y = -16;
- break;
- case wimp_SCROLL_AUTO_DOWN:
- case wimp_SCROLL_LINE_DOWN:
- step_y = 16;
- break;
- case wimp_SCROLL_PAGE_DOWN:
- step_y = SCROLL_PAGE_DOWN;
- break;
- case 0x80000000:
- step_y = SCROLL_BOTTOM;
- break;
- case 0x7fffffff:
- step_y = SCROLL_TOP;
- break;
- default:
- step_y = -((visible_y * (scroll_y>>2)) >> 2);
- break;
- }
+ /* Register event handlers. Do this quickly, as some of the things
+ * that follow will indirectly look up our user data: this MUST
+ * be set first!
+ */
+ ro_gui_wimp_event_set_user_data(g->window, g);
+ ro_gui_wimp_event_register_open_window(g->window,
+ ro_gui_window_open);
+ ro_gui_wimp_event_register_close_window(g->window,
+ ro_gui_window_close);
+ ro_gui_wimp_event_register_redraw_window(g->window,
+ ro_gui_window_redraw);
+ ro_gui_wimp_event_register_scroll_window(g->window,
+ ro_gui_window_scroll);
+ ro_gui_wimp_event_register_pointer_entering_window(g->window,
+ ro_gui_window_pointer_entering);
+ ro_gui_wimp_event_register_keypress(g->window,
+ ro_gui_window_keypress);
+ ro_gui_wimp_event_register_mouse_click(g->window,
+ ro_gui_window_click);
+ ro_gui_wimp_event_register_menu(g->window,
+ ro_gui_browser_window_menu,
+ true, false);
+ ro_gui_wimp_event_register_menu_prepare(g->window,
+ ro_gui_window_menu_prepare);
+ ro_gui_wimp_event_register_menu_selection(g->window,
+ ro_gui_window_menu_select);
+ ro_gui_wimp_event_register_menu_warning(g->window,
+ ro_gui_window_menu_warning);
+ ro_gui_wimp_event_register_menu_close(g->window,
+ ro_gui_window_menu_close);
- /* If no scrolling is required, there's no point trying to do any. */
+ /* Set the window options */
+ ro_gui_window_clone_options(g, existing);
+ ro_gui_window_update_toolbar_buttons(g);
- if (step_x == 0 && step_y == 0)
- return;
+ /* Open the window at the top of the stack */
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return g;
+ }
- /* If the pointer is over the window being scrolled, then try to get
- * the core to do the scrolling on the object under the pointer.
- */
+ state.next = wimp_TOP;
- if (pointer.w == g->window &&
- ro_gui_window_to_window_pos(g,
- pointer.pos.x, pointer.pos.y, &pos))
- handled = browser_window_scroll_at_point(g->bw, pos.x, pos.y,
- step_x, step_y);
+ ro_gui_window_open(PTR_WIMP_OPEN(&state));
- /* If the core didn't do the scrolling, handle it via the Wimp.
- * Windows which contain frames can only be scrolled by the core,
- * because it implements frame scroll bars.
- */
+ /* Claim the caret */
+ if (ro_toolbar_take_caret(g->toolbar)) {
+ ro_gui_url_complete_start(g->toolbar);
+ } else {
+ gui_window_place_caret(g, -100, -100, 0, NULL);
+ }
- if (!handled && (browser_window_is_frameset(g->bw) == false)) {
- switch (step_x) {
- case SCROLL_TOP:
- state.xscroll -= 0x10000000;
- break;
- case SCROLL_BOTTOM:
- state.xscroll += 0x10000000;
- break;
- case SCROLL_PAGE_UP:
- state.xscroll += visible_x;
- break;
- case SCROLL_PAGE_DOWN:
- state.xscroll -= visible_x;
- break;
- default:
- state.xscroll += 2 * step_x;
- break;
- }
+ return g;
+}
- switch (step_y) {
- case SCROLL_TOP:
- state.yscroll += 0x10000000;
- break;
- case SCROLL_BOTTOM:
- state.yscroll -= 0x10000000;
- break;
- case SCROLL_PAGE_UP:
- state.yscroll += visible_y;
- break;
- case SCROLL_PAGE_DOWN:
- state.yscroll -= visible_y;
- break;
- default:
- state.yscroll -= 2 * step_y;
- break;
- }
- error = xwimp_open_window((wimp_open *) &state);
- if (error) {
- LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
+/**
+ * Remove all pending update boxes for a window
+ *
+ * \param g gui_window
+ */
+static void ro_gui_window_remove_update_boxes(struct gui_window *g)
+{
+ struct update_box *cur;
+
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ if (cur->g == g) {
+ cur->g = NULL;
}
}
}
/**
- * Handle Message_DataLoad (file dragged in) for a window.
- *
- * \param g window
- * \param message Message_DataLoad block
- * \return true if the load was processed
+ * Close a browser window and free any related resources.
*
- * If the file was dragged into a form file input, it is used as the value.
+ * \param g gui_window to destroy
*/
-
-bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
+static void gui_window_destroy(struct gui_window *g)
{
os_error *error;
- os_coord pos;
+ wimp_w w;
- /* Ignore directories etc. */
- if (0x1000 <= message->data.data_xfer.file_type)
- return false;
+ assert(g);
- if (!ro_gui_window_to_window_pos(g, message->data.data_xfer.pos.x,
- message->data.data_xfer.pos.y, &pos))
- return false;
+ /* stop any tracking */
+ ro_mouse_kill(g);
- if (browser_window_drop_file_at_point(g->bw, pos.x, pos.y,
- message->data.data_xfer.file_name) == false)
- return false;
+ /* remove from list */
+ if (g->prev)
+ g->prev->next = g->next;
+ else
+ window_list = g->next;
+ if (g->next)
+ g->next->prev = g->prev;
- /* send DataLoadAck */
- message->action = message_DATA_LOAD_ACK;
- message->your_ref = message->my_ref;
- error = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
+ /* destroy toolbar */
+ if (g->toolbar)
+ ro_toolbar_destroy(g->toolbar);
+ if (g->status_bar)
+ ro_gui_status_bar_destroy(g->status_bar);
+
+ w = g->window;
+ ro_gui_url_complete_close();
+ ro_gui_dialog_close_persistent(w);
+ if (current_menu_window == w)
+ ro_gui_menu_destroy();
+ ro_gui_window_remove_update_boxes(g);
+
+ /* delete window */
+ error = xwimp_delete_window(w);
if (error) {
- LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
+ LOG("xwimp_delete_window: 0x%x: %s", error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
}
+ ro_gui_wimp_event_finalise(w);
- return true;
+ free(g);
}
/**
- * Handle pointer movements in a browser window.
+ * Set the title of a browser window.
*
- * \param *pointer new mouse position
- * \param *data browser window that the pointer is in
+ * \param g gui_window to update
+ * \param title new window title, copied
*/
-
-void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data)
+static void gui_window_set_title(struct gui_window *g, const char *title)
{
- os_coord pos;
- struct gui_window *g = (struct gui_window *) data;
+ assert(g);
+ assert(title);
- if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
- browser_window_mouse_track(g->bw,
- ro_gui_mouse_drag_state(pointer->buttons,
- wimp_BUTTON_DOUBLE_CLICK_DRAG),
- pos.x, pos.y);
+ if (g->scale != 1.0) {
+ int scale_disp = g->scale * 100;
+
+ if (ABS((float)scale_disp - g->scale * 100) >= 0.05)
+ snprintf(g->title, sizeof g->title, "%s (%.1f%%)",
+ title, g->scale * 100);
+ else
+ snprintf(g->title, sizeof g->title, "%s (%i%%)",
+ title, scale_disp);
+ } else {
+ strncpy(g->title, title, sizeof g->title);
+ }
+
+ ro_gui_set_window_title(g->window, g->title);
}
/**
- * Window is being iconised. Create a suitable thumbnail sprite
- * (which, sadly, must be in the Wimp sprite pool), and return
- * the sprite name and truncated title to the iconiser
+ * Get the scroll position of a browser window.
*
- * \param g the gui window being iconised
- * \param wi the WindowInfo message from the iconiser
+ * \param g gui_window
+ * \param sx receives x ordinate of point at top-left of window
+ * \param sy receives y ordinate of point at top-left of window
+ * \return true iff successful
*/
+static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
+{
+ wimp_window_state state;
+ os_error *error;
+ int toolbar_height = 0;
+
+ assert(g);
+
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
+ }
-void ro_gui_window_iconise(struct gui_window *g,
- wimp_full_message_window_info *wi)
+ if (g->toolbar)
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
+ *sx = state.xscroll / (2 * g->scale);
+ *sy = -(state.yscroll - toolbar_height) / (2 * g->scale);
+ return true;
+}
+
+
+/**
+ * Set the scroll position of a riscos browser window.
+ *
+ * Scrolls the viewport to ensure the specified rectangle of the
+ * content is shown.
+ *
+ * \param g gui window to scroll
+ * \param rect The rectangle to ensure is shown.
+ * \return NSERROR_OK on success or apropriate error code.
+ */
+static nserror
+gui_window_set_scroll(struct gui_window *g, const struct rect *rect)
{
- /* sadly there is no 'legal' way to get the sprite into
- * the Wimp sprite pool other than via a filing system */
- const char *temp_fname = "Pipe:$._tmpfile";
- struct browser_window *bw = g->bw;
- osspriteop_header *overlay = NULL;
- osspriteop_header *sprite_header;
- struct bitmap *bitmap;
- osspriteop_area *area;
- int width = 34, height = 34;
- struct hlcache_handle *h;
+ wimp_window_state state;
os_error *error;
- int len, id;
+ int toolbar_height = 0;
- assert(bw);
+ assert(g);
- h = browser_window_get_content(bw);
- if (!h) return;
+ state.w = g->window;
+ error = xwimp_get_window_state(&state);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return NSERROR_BAD_PARAMETER;
+ }
- /* if an overlay sprite is defined, locate it and gets its dimensions
- * so that we can produce a thumbnail with the same dimensions */
- if (!ro_gui_wimp_get_sprite("ic_netsfxx", &overlay)) {
- error = xosspriteop_read_sprite_info(osspriteop_PTR,
- (osspriteop_area *)0x100,
- (osspriteop_id)overlay, &width, &height, NULL,
- NULL);
- if (error) {
- LOG("xosspriteop_read_sprite_info: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("MiscError", error->errmess);
- overlay = NULL;
+ if (g->toolbar) {
+ toolbar_height = ro_toolbar_full_height(g->toolbar);
+ }
+
+ if ((rect->x0 == rect->x1) && (rect->y0 == rect->y1)) {
+ /* scroll to top */
+ state.xscroll = rect->x0 * 2 * g->scale;
+ state.yscroll = (-rect->y0 * 2 * g->scale) + toolbar_height;
+ } else {
+ /* scroll area into view with padding */
+ int x0, y0, x1, y1;
+ int cx0, cy0, width, height;
+ int padding_available;
+ int correction;
+
+ x0 = rect->x0 * 2 * g->scale;
+ y0 = rect->y0 * 2 * g->scale;
+ x1 = rect->x1 * 2 * g->scale;
+ y1 = rect->y1 * 2 * g->scale;
+
+ cx0 = state.xscroll;
+ cy0 = -state.yscroll + toolbar_height;
+ width = state.visible.x1 - state.visible.x0;
+ height = state.visible.y1 - state.visible.y0 - toolbar_height;
+
+ /* make sure we're visible */
+ correction = (x1 - cx0 - width);
+ if (correction > 0) {
+ cx0 += correction;
}
- else if (sprite_bpp(overlay) != 8) {
- LOG("overlay sprite is not 8bpp");
- overlay = NULL;
+ correction = (y1 - cy0 - height);
+ if (correction > 0) {
+ cy0 += correction;
+ }
+ if (x0 < cx0) {
+ cx0 = x0;
+ }
+ if (y0 < cy0) {
+ cy0 = y0;
}
- }
- /* create the thumbnail sprite */
- bitmap = riscos_bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE |
- BITMAP_CLEAR_MEMORY);
- if (!bitmap) {
- LOG("Thumbnail initialisation failed.");
- return;
+ /* try to give a SCROLL_VISIBLE_PADDING border of space around us */
+ padding_available = (width - x1 + x0) / 2;
+ if (padding_available > 0) {
+ if (padding_available > SCROLL_VISIBLE_PADDING) {
+ padding_available = SCROLL_VISIBLE_PADDING;
+ }
+ correction = (cx0 + width - x1);
+ if (correction < padding_available) {
+ cx0 += padding_available;
+ }
+ correction = (x0 - cx0);
+ if (correction < padding_available) {
+ cx0 -= padding_available;
+ }
+ }
+ padding_available = (height - y1 + y0) / 2;
+ if (padding_available > 0) {
+ if (padding_available > SCROLL_VISIBLE_PADDING) {
+ padding_available = SCROLL_VISIBLE_PADDING;
+ }
+ correction = (cy0 + height - y1);
+ if (correction < padding_available) {
+ cy0 += padding_available;
+ }
+ correction = (y0 - cy0);
+ if (correction < padding_available) {
+ cy0 -= padding_available;
+ }
+ }
+
+ state.xscroll = cx0;
+ state.yscroll = -cy0 + toolbar_height;
}
- riscos_bitmap_render(bitmap, h);
- if (overlay) {
- riscos_bitmap_overlay_sprite(bitmap, overlay);
+ ro_gui_window_open(PTR_WIMP_OPEN(&state));
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Find the current dimensions of a browser window's content area.
+ *
+ * \param gw gui window to measure
+ * \param width receives width of window
+ * \param height receives height of window
+ * \param scaled whether to return scaled values
+ */
+static nserror
+gui_window_get_dimensions(struct gui_window *gw,
+ int *width, int *height,
+ bool scaled)
+{
+ /* use the cached window sizes */
+ *width = gw->old_width / 2;
+ *height = gw->old_height / 2;
+
+ if (scaled) {
+ *width /= gw->scale;
+ *height /= gw->scale;
}
- area = riscos_bitmap_convert_8bpp(bitmap);
- riscos_bitmap_destroy(bitmap);
- if (!area) {
- LOG("Thumbnail conversion failed.");
- return;
+ return NSERROR_OK;
+}
+
+
+/**
+ * Set the status bar of a browser window.
+ *
+ * \param g gui_window to update
+ * \param text new status text
+ */
+static void riscos_window_set_status(struct gui_window *g, const char *text)
+{
+ if (g->status_bar) {
+ ro_gui_status_bar_set_text(g->status_bar, text);
}
+}
- /* choose a suitable sprite name */
- id = 0;
- while (iconise_used[id])
- if ((unsigned)++id >= NOF_ELEMENTS(iconise_used)) {
- id = iconise_next;
- if ((unsigned)++iconise_next >=
- NOF_ELEMENTS(iconise_used))
- iconise_next = 0;
- break;
- }
- sprite_header = (osspriteop_header *)(area + 1);
- len = sprintf(sprite_header->name, "ic_netsf%.2d", id);
+/**
+ * Update the interface to reflect start of page loading.
+ *
+ * \param g window with start of load
+ */
+static void gui_window_start_throbber(struct gui_window *g)
+{
+ ro_gui_window_update_toolbar_buttons(g);
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ if (g->toolbar != NULL)
+ ro_toolbar_start_throbbing(g->toolbar);
+ g->active = true;
+}
- error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
- area, temp_fname);
- if (error) {
- LOG("xosspriteop_save_sprite_file: 0x%x:%s", error->errnum, error->errmess);
- ro_warn_user("MiscError", error->errmess);
- free(area);
- return;
- }
- error = xwimpspriteop_merge_sprite_file(temp_fname);
- if (error) {
- LOG("xwimpspriteop_merge_sprite_file: 0x%x:%s", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- remove(temp_fname);
- free(area);
+
+/**
+ * Update the interface to reflect page loading stopped.
+ *
+ * \param g window with start of load
+ */
+static void gui_window_stop_throbber(struct gui_window *g)
+{
+ ro_gui_window_update_toolbar_buttons(g);
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ if (g->toolbar != NULL)
+ ro_toolbar_stop_throbbing(g->toolbar);
+ g->active = false;
+}
+
+/**
+ * set favicon
+ */
+static void
+gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon)
+{
+ if (g == NULL || g->toolbar == NULL)
return;
- }
- memcpy(wi->sprite_name, sprite_header->name + 3, len - 2); /* inc NUL */
- strncpy(wi->title, g->title, sizeof(wi->title));
- wi->title[sizeof(wi->title) - 1] = '\0';
+ ro_toolbar_set_site_favicon(g->toolbar, icon);
+}
- if (wimptextop_string_width(wi->title, 0) > 182) {
- /* work around bug in Pinboard where it will fail to display
- * the icon if the text is very wide */
- if (strlen(wi->title) > 10)
- wi->title[10] = '\0'; /* pinboard does this anyway */
- while (wimptextop_string_width(wi->title, 0) > 182)
- wi->title[strlen(wi->title) - 1] = '\0';
- }
- wi->size = sizeof(wimp_full_message_window_info);
- wi->your_ref = wi->my_ref;
- error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)wi,
- wi->sender);
+
+/**
+ * Remove the caret, if present.
+ *
+ * \param g window with caret
+ */
+static void gui_window_remove_caret(struct gui_window *g)
+{
+ wimp_caret caret;
+ os_error *error;
+
+ error = xwimp_get_caret_position(&caret);
if (error) {
- LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
+ LOG("xwimp_get_caret_position: 0x%x: %s",
+ error->errnum, error->errmess);
ro_warn_user("WimpError", error->errmess);
+ return;
}
- else {
- g->iconise_icon = id;
- iconise_used[id] = true;
+
+ if (caret.w == g->window) {
+ /* we have the caret: hide caret, but keep input focus */
+ gui_window_place_caret(g, -100, -100, 0, NULL);
}
+}
- free(area);
+
+/**
+ * Called when the gui_window has new content.
+ *
+ * \param g the gui_window that has new content
+ */
+static void gui_window_new_content(struct gui_window *g)
+{
+ ro_gui_menu_refresh(ro_gui_browser_window_menu);
+ ro_gui_window_update_toolbar_buttons(g);
+ ro_gui_dialog_close_persistent(g->window);
+ ro_toolbar_set_content_favicon(g->toolbar, g);
}
/**
* Completes scrolling of a browser window
*
- * \param *drag The DragEnd event data block.
- * \param *data gui window block pointer.
+ * \param drag The DragEnd event data block.
+ * \param data gui window block pointer.
*/
-
static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data)
{
wimp_pointer pointer;
@@ -3498,612 +3799,703 @@ static void ro_gui_window_scroll_end(wimp_dragged *drag, void *data)
/**
- * Process Mouse_Click events in a toolbar's button bar. This does not handle
- * other clicks in a toolbar: these are handled by the toolbar module itself.
+ * Starts drag scrolling of a browser window
*
- * \param *data The GUI window associated with the click.
- * \param action_type The action type to be handled.
- * \param action The action to process.
+ * \param g the window to scroll
*/
-
-void ro_gui_window_toolbar_click(void *data,
- toolbar_action_type action_type, union toolbar_action action)
+static bool gui_window_scroll_start(struct gui_window *g)
{
- struct gui_window *g = data;
- nserror err;
-
- if (g == NULL)
- return;
-
-
- if (action_type == TOOLBAR_ACTION_URL) {
- switch (action.url) {
- case TOOLBAR_URL_DRAG_URL:
- {
- gui_save_type save_type;
-
- if (!browser_window_has_content(g->bw))
- break;
-
- if (ro_gui_shift_pressed())
- save_type = GUI_SAVE_LINK_URL;
- else
- save_type = GUI_SAVE_LINK_TEXT;
-
- ro_gui_drag_save_link(save_type,
- browser_window_get_url(g->bw),
- browser_window_get_title(g->bw), g);
- }
- break;
-
- case TOOLBAR_URL_SELECT_HOTLIST:
- ro_gui_window_action_add_bookmark(g);
- break;
-
- case TOOLBAR_URL_ADJUST_HOTLIST:
- ro_gui_window_action_remove_bookmark(g);
- break;
-
- default:
- break;
- }
+ wimp_window_info_base info;
+ wimp_pointer pointer;
+ os_error *error;
+ wimp_drag drag;
+ int height;
+ int width;
- return;
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
}
+ info.w = g->window;
+ error = xwimp_get_window_info_header_only((wimp_window_info*)&info);
+ if (error) {
+ LOG("xwimp_get_window_state: 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
+ }
- /* By now, the only valid action left is a button click. If it isn't
- * one of those, give up.
- */
-
- if (action_type != TOOLBAR_ACTION_BUTTON)
- return;
-
- switch (action.button) {
- case TOOLBAR_BUTTON_BACK:
- if (g->bw != NULL)
- browser_window_history_back(g->bw, false);
- break;
-
- case TOOLBAR_BUTTON_BACK_NEW:
- if (g->bw != NULL)
- browser_window_history_back(g->bw, true);
- break;
-
- case TOOLBAR_BUTTON_FORWARD:
- if (g->bw != NULL)
- browser_window_history_forward(g->bw, false);
- break;
-
- case TOOLBAR_BUTTON_FORWARD_NEW:
- if (g->bw != NULL)
- browser_window_history_forward(g->bw, true);
- break;
-
- case TOOLBAR_BUTTON_STOP:
- if (g->bw != NULL)
- browser_window_stop(g->bw);
- break;
-
- case TOOLBAR_BUTTON_RELOAD:
- if (g->bw != NULL)
- browser_window_reload(g->bw, false);
- break;
-
- case TOOLBAR_BUTTON_RELOAD_ALL:
- if (g->bw != NULL)
- browser_window_reload(g->bw, true);
- break;
-
- case TOOLBAR_BUTTON_HISTORY_LOCAL:
- ro_gui_window_action_local_history(g);
- break;
-
- case TOOLBAR_BUTTON_HISTORY_GLOBAL:
- ro_gui_global_history_present();
- break;
+ width = info.extent.x1 - info.extent.x0;
+ height = info.extent.y1 - info.extent.y0;
- case TOOLBAR_BUTTON_HOME:
- ro_gui_window_action_home(g);
- break;
+ drag.type = wimp_DRAG_USER_POINT;
+ drag.bbox.x1 = pointer.pos.x + info.xscroll;
+ drag.bbox.y0 = pointer.pos.y + info.yscroll;
+ drag.bbox.x0 = drag.bbox.x1 - (width - (info.visible.x1 - info.visible.x0));
+ drag.bbox.y1 = drag.bbox.y0 + (height - (info.visible.y1 - info.visible.y0));
- case TOOLBAR_BUTTON_SEARCH:
- ro_gui_window_action_search(g);
- break;
+ if (g->toolbar) {
+ int tbar_height = ro_toolbar_full_height(g->toolbar);
+ drag.bbox.y0 -= tbar_height;
+ drag.bbox.y1 -= tbar_height;
+ }
- case TOOLBAR_BUTTON_SCALE:
- ro_gui_window_action_zoom(g);
- break;
+ error = xwimp_drag_box(&drag);
+ if (error) {
+ LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
+ }
- case TOOLBAR_BUTTON_BOOKMARK_OPEN:
- ro_gui_hotlist_present();
- break;
+ ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at,
+ NULL, g);
+ return true;
+}
- case TOOLBAR_BUTTON_BOOKMARK_ADD:
- ro_gui_window_action_add_bookmark(g);
- break;
- case TOOLBAR_BUTTON_SAVE_SOURCE:
- ro_gui_window_action_save(g, GUI_SAVE_SOURCE);
- break;
+/**
+ * Platform-dependent part of starting drag operation.
+ *
+ * \param g gui window containing the drag
+ * \param type type of drag the core is performing
+ * \param rect rectangle to constrain pointer to (relative to drag start coord)
+ * \return true iff succesful
+ */
+static bool
+gui_window_drag_start(struct gui_window *g,
+ gui_drag_type type,
+ const struct rect *rect)
+{
+ wimp_pointer pointer;
+ wimp_drag drag;
- case TOOLBAR_BUTTON_SAVE_COMPLETE:
- ro_gui_window_action_save(g, GUI_SAVE_COMPLETE);
- break;
+ if (rect != NULL) {
+ /* We have a box to constrain the pointer to, for the drag
+ * duration */
+ os_error *error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
+ }
- case TOOLBAR_BUTTON_PRINT:
- ro_gui_window_action_print(g);
- break;
+ drag.type = wimp_DRAG_USER_POINT;
+ drag.bbox.x0 = pointer.pos.x +
+ (int)(rect->x0 * 2 * g->scale);
+ drag.bbox.y0 = pointer.pos.y +
+ (int)(rect->y0 * 2 * g->scale);
+ drag.bbox.x1 = pointer.pos.x +
+ (int)(rect->x1 * 2 * g->scale);
+ drag.bbox.y1 = pointer.pos.y +
+ (int)(rect->y1 * 2 * g->scale);
- case TOOLBAR_BUTTON_UP:
- err = browser_window_navigate_up(g->bw, false);
- if (err != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(err), NULL);
+ error = xwimp_drag_box(&drag);
+ if (error) {
+ LOG("xwimp_drag_box: 0x%x : %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return false;
}
- break;
+ }
- case TOOLBAR_BUTTON_UP_NEW:
- err = browser_window_navigate_up(g->bw, true);
- if (err != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(err), NULL);
- }
+ switch (type) {
+ case GDRAGGING_SCROLLBAR:
+ /* Dragging a core scrollbar */
+ ro_mouse_drag_start(ro_gui_window_scroll_end, ro_gui_window_mouse_at,
+ NULL, g);
break;
default:
+ /* Not handled here yet */
break;
}
- ro_gui_window_update_toolbar_buttons(g);
+ return true;
}
/**
- * Handle Message_DataLoad (file dragged in) for a toolbar
- *
- * @todo This belongs in the toolbar module, and should be moved there
- * once the module is able to usefully handle its own events.
+ * Save the specified content as a link.
*
- * \param g window
- * \param message Message_DataLoad block
- * \return true if the load was processed
+ * \param g The window containing the content
+ * \param url The url of the link
+ * \param title The title of the link
*/
-
-bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
+static nserror
+gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
{
- if (message->data.data_xfer.file_type == osfile_TYPE_TEXT &&
- ro_gui_window_import_text(g,
- message->data.data_xfer.file_name)) {
- os_error *error;
-
- /* send DataLoadAck */
- message->action = message_DATA_LOAD_ACK;
- message->your_ref = message->my_ref;
- error = xwimp_send_message(wimp_USER_MESSAGE, message,
- message->sender);
- if (error) {
- LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
- ro_warn_user("WimpError", error->errmess);
- }
- return true;
- }
- return false;
+ ro_gui_save_prepare(GUI_SAVE_LINK_URL, NULL, NULL, url, title);
+ ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
+ return NSERROR_OK;
}
-/*
- * Helper code for the Wimp Event Handlers.
- */
-
/**
- * Check if a particular menu handle is a browser window menu
+ * Display a menu of options for a form select control.
*
- * \param *menu The menu in question.
- * \return true if this menu is a browser window menu
+ * \param g gui window containing form control
+ * \param control form control of type GADGET_SELECT
*/
-
-bool ro_gui_window_check_menu(wimp_menu *menu)
+static void
+gui_window_create_form_select_menu(struct gui_window *g,
+ struct form_control *control)
{
- return (ro_gui_browser_window_menu == menu) ? true : false;
-}
-
-
-/**
- * Return boolean flags to show what RISC OS types we can sensibly convert
- * the given object into.
- *
- * \todo This should probably be somewhere else but in window.c, and
- * should probably even be done in content_().
- *
- * \param h The object to test.
- * \param export_draw true on exit if a drawfile would be possible.
- * \param export_sprite true on exit if a sprite would be possible.
- * \return true if valid data is returned; else false.
- */
+ os_error *error;
+ wimp_pointer pointer;
-bool ro_gui_window_content_export_types(struct hlcache_handle *h,
- bool *export_draw, bool *export_sprite)
-{
- bool found_type = false;
+ /* The first time the menu is opened, control bypasses the normal
+ * Menu Prepare event and so we prepare here. On any re-opens,
+ * ro_gui_window_prepare_form_select_menu() is called from the
+ * normal wimp event.
+ */
- if (export_draw != NULL)
- *export_draw = false;
- if (export_sprite != NULL)
- *export_sprite = false;
+ if (!ro_gui_window_prepare_form_select_menu(g, control))
+ return;
- if (h != NULL && content_get_type(h) == CONTENT_IMAGE) {
- switch (ro_content_native_type(h)) {
- case osfile_TYPE_SPRITE:
- /* bitmap types (Sprite export possible) */
- found_type = true;
- if (export_sprite != NULL)
- *export_sprite = true;
- break;
- case osfile_TYPE_DRAW:
- /* vector types (Draw export possible) */
- found_type = true;
- if (export_draw != NULL)
- *export_draw = true;
- break;
- default:
- break;
- }
+ error = xwimp_get_pointer_info(&pointer);
+ if (error) {
+ LOG("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ ro_gui_menu_destroy();
+ return;
}
- return found_type;
+ gui_form_select_control = control;
+ ro_gui_menu_create(gui_form_select_menu,
+ pointer.pos.x, pointer.pos.y, g->window);
}
/**
- * Prepare the page info window for use.
+ * Import text file into window
*
- * \param *g The GUI window block to use.
+ * \param g gui window containing textarea
+ * \param filename pathname of file to be imported
+ * \return true iff successful
*/
-
-void ro_gui_window_prepare_pageinfo(struct gui_window *g)
+static bool
+ro_gui_window_import_text(struct gui_window *g, const char *filename)
{
- struct hlcache_handle *h = browser_window_get_content(g->bw);
- char icon_buf[20] = "file_xxx";
- char enc_buf[40];
- const char *icon = icon_buf;
- const char *title, *url;
- lwc_string *mime;
- const char *enc = "-";
-
- assert(h);
-
- title = content_get_title(h);
- if (title == NULL)
- title = "-";
- url = nsurl_access(hlcache_handle_get_url(h));
- if (url == NULL)
- url = "-";
- mime = content_get_mime_type(h);
-
- sprintf(icon_buf, "file_%x", ro_content_filetype(h));
- if (!ro_gui_wimp_sprite_exists(icon_buf))
- sprintf(icon_buf, "file_xxx");
+ fileswitch_object_type obj_type;
+ os_error *error;
+ char *buf, *utf8_buf, *sp;
+ int size;
+ nserror ret;
+ const char *ep;
+ char *p;
- if (content_get_type(h) == CONTENT_HTML) {
- if (content_get_encoding(h, CONTENT_ENCODING_NORMAL)) {
- snprintf(enc_buf, sizeof enc_buf, "%s (%s)",
- content_get_encoding(h, CONTENT_ENCODING_NORMAL),
- content_get_encoding(h, CONTENT_ENCODING_SOURCE));
- enc = enc_buf;
- } else {
- enc = messages_get("EncodingUnk");
- }
+ error = xosfile_read_stamped(filename, &obj_type, NULL, NULL,
+ &size, NULL, NULL);
+ if (error) {
+ LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess);
+ ro_warn_user("FileError", error->errmess);
+ return true; /* was for us, but it didn't work! */
}
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ICON,
- icon, true);
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TITLE,
- title, true);
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_URL,
- url, true);
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_ENC,
- enc, true);
- ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TYPE,
- lwc_string_data(mime), true);
-
- lwc_string_unref(mime);
-}
-
+ /* Allocate one byte more than needed to ensure that the buffer is
+ * always terminated, regardless of file contents.
+ */
-/**
- * Prepare the object info window for use
- *
- * \param *object the object for which information is to be displayed
- * \param *target_url corresponding url, if any
- */
+ buf = calloc(size + 1, sizeof(char));
+ if (!buf) {
+ ro_warn_user("NoMemory", NULL);
+ return true;
+ }
-void ro_gui_window_prepare_objectinfo(struct hlcache_handle *object, nsurl *target_url)
-{
- char icon_buf[20] = "file_xxx";
- const char *url;
- lwc_string *mime;
- const char *target = "-";
+ error = xosfile_load_stamped(filename, (byte*)buf,
+ NULL, NULL, NULL, NULL, NULL);
- sprintf(icon_buf, "file_%.3x",ro_content_filetype(object));
- if (!ro_gui_wimp_sprite_exists(icon_buf)) {
- sprintf(icon_buf, "file_xxx");
+ if (error) {
+ LOG("xosfile_load_stamped: 0x%x:%s", error->errnum, error->errmess);
+ ro_warn_user("LoadError", error->errmess);
+ free(buf);
+ return true;
}
- url = nsurl_access(hlcache_handle_get_url(object));
- if (url == NULL) {
- url = "-";
+ ret = utf8_from_local_encoding(buf, size, &utf8_buf);
+ if (ret != NSERROR_OK) {
+ /* bad encoding shouldn't happen */
+ assert(ret != NSERROR_BAD_ENCODING);
+ LOG("utf8_from_local_encoding failed");
+ free(buf);
+ ro_warn_user("NoMemory", NULL);
+ return true;
}
- mime = content_get_mime_type(object);
+ size = strlen(utf8_buf);
- if (target_url != NULL) {
- target = nsurl_access(target_url);
- }
+ ep = utf8_buf + size;
+ p = utf8_buf;
- ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON,
- icon_buf, true);
- ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL,
- url, true);
- ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET,
- target, true);
- ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE,
- lwc_string_data(mime), true);
+ /* skip leading whitespace */
+ while (isspace(*p)) p++;
- lwc_string_unref(mime);
-}
+ sp = p;
+ while (*p && *p != '\r' && *p != '\n')
+ p += utf8_next(p, ep - p, 0);
+ *p = '\0';
+ if (p > sp)
+ ro_gui_window_launch_url(g, sp);
+
+ free(buf);
+ free(utf8_buf);
+ return true;
+}
-/*
- * User Actions in the browser window
- */
/**
- * Launch a new url in the given window.
- *
- * \param g gui_window to update
- * \param url1 url to be launched
+ * RISC OS browser window operation table
*/
+static struct gui_window_table window_table = {
+ .create = gui_window_create,
+ .destroy = gui_window_destroy,
+ .invalidate = ro_gui_window_invalidate_area,
+ .get_scroll = gui_window_get_scroll,
+ .set_scroll = gui_window_set_scroll,
+ .get_dimensions = gui_window_get_dimensions,
+ .update_extent = gui_window_update_extent,
-void ro_gui_window_launch_url(struct gui_window *g, const char *url1)
-{
- nserror error;
- nsurl *url;
-
- if (url1 == NULL)
- return;
-
- ro_gui_url_complete_close();
+ .set_title = gui_window_set_title,
+ .set_url = ro_gui_window_set_url,
+ .set_icon = gui_window_set_icon,
+ .set_status = riscos_window_set_status,
+ .set_pointer = gui_window_set_pointer,
+ .place_caret = gui_window_place_caret,
+ .remove_caret = gui_window_remove_caret,
+ .save_link = gui_window_save_link,
+ .drag_start = gui_window_drag_start,
+ .scroll_start = gui_window_scroll_start,
+ .new_content = gui_window_new_content,
+ .start_throbber = gui_window_start_throbber,
+ .stop_throbber = gui_window_stop_throbber,
+ .create_form_select_menu = gui_window_create_form_select_menu,
- error = nsurl_create(url1, &url);
- if (error != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(error), 0);
- } else {
- ro_gui_window_set_url(g, url);
+ /* from save */
+ .drag_save_object = gui_drag_save_object,
+ .drag_save_selection =gui_drag_save_selection,
- browser_window_navigate(g->bw, url,
- NULL, BW_NAVIGATE_HISTORY,
- NULL, NULL, NULL);
- nsurl_unref(url);
- }
-}
+ /* from textselection */
+ .start_selection = gui_start_selection,
+};
+struct gui_window_table *riscos_window_table = &window_table;
-/**
- * Perform a Navigate Home action on a browser window.
- *
- * \param *g The browser window to act on.
- */
-void ro_gui_window_action_home(struct gui_window *g)
+/* exported interface documented in riscos/window.h */
+void ro_gui_window_initialise(void)
{
- static const char *addr = NETSURF_HOMEPAGE;
- nsurl *url;
- nserror error;
-
- if (g == NULL || g->bw == NULL)
- return;
+ /* Build the browser window menu. */
- if (nsoption_charp(homepage_url) != NULL) {
- addr = nsoption_charp(homepage_url);
- }
+ static const struct ns_menu browser_definition = {
+ "NetSurf", {
+ { "Page", BROWSER_PAGE, 0 },
+ { "Page.PageInfo",BROWSER_PAGE_INFO, &dialog_pageinfo },
+ { "Page.Save", BROWSER_SAVE, &dialog_saveas },
+ { "Page.SaveComp", BROWSER_SAVE_COMPLETE, &dialog_saveas },
+ { "Page.Export", NO_ACTION, 0 },
+#ifdef WITH_DRAW_EXPORT
+ { "Page.Export.Draw", BROWSER_EXPORT_DRAW, &dialog_saveas },
+#endif
+#ifdef WITH_PDF_EXPORT
+ { "Page.Export.PDF", BROWSER_EXPORT_PDF, &dialog_saveas },
+#endif
+ { "Page.Export.Text", BROWSER_EXPORT_TEXT, &dialog_saveas },
+ { "Page.SaveURL", NO_ACTION, 0 },
+ { "Page.SaveURL.URI", BROWSER_SAVE_URL_URI, &dialog_saveas },
+ { "Page.SaveURL.URL", BROWSER_SAVE_URL_URL, &dialog_saveas },
+ { "Page.SaveURL.LinkText", BROWSER_SAVE_URL_TEXT, &dialog_saveas },
+ { "_Page.Print", BROWSER_PRINT, &dialog_print },
+ { "Page.NewWindow", BROWSER_NEW_WINDOW, 0 },
+ { "Page.FindText", BROWSER_FIND_TEXT, &dialog_search },
+ { "Page.ViewSrc", BROWSER_VIEW_SOURCE, 0 },
+ { "Object", BROWSER_OBJECT, 0 },
+ { "Object.Object", BROWSER_OBJECT_OBJECT, 0 },
+ { "Object.Object.ObjInfo", BROWSER_OBJECT_INFO, &dialog_objinfo },
+ { "Object.Object.ObjSave", BROWSER_OBJECT_SAVE, &dialog_saveas },
+ { "Object.Object.Export", BROWSER_OBJECT_EXPORT, 0 },
+ { "Object.Object.Export.Sprite", BROWSER_OBJECT_EXPORT_SPRITE, &dialog_saveas },
+#ifdef WITH_DRAW_EXPORT
+ { "Object.Object.Export.ObjDraw", BROWSER_OBJECT_EXPORT_DRAW, &dialog_saveas },
+#endif
+ { "Object.Object.SaveURL", NO_ACTION, 0 },
+ { "Object.Object.SaveURL.URI", BROWSER_OBJECT_SAVE_URL_URI, &dialog_saveas },
+ { "Object.Object.SaveURL.URL", BROWSER_OBJECT_SAVE_URL_URL, &dialog_saveas },
+ { "Object.Object.SaveURL.LinkText", BROWSER_OBJECT_SAVE_URL_TEXT, &dialog_saveas },
+ { "Object.Object.ObjPrint", BROWSER_OBJECT_PRINT, 0 },
+ { "Object.Object.ObjReload", BROWSER_OBJECT_RELOAD, 0 },
+ { "Object.Link", BROWSER_OBJECT_LINK, 0 },
+ { "Object.Link.LinkSave", BROWSER_LINK_SAVE, 0 },
+ { "Object.Link.LinkSave.URI", BROWSER_LINK_SAVE_URI, &dialog_saveas },
+ { "Object.Link.LinkSave.URL", BROWSER_LINK_SAVE_URL, &dialog_saveas },
+ { "Object.Link.LinkSave.LinkText", BROWSER_LINK_SAVE_TEXT, &dialog_saveas },
+ { "_Object.Link.LinkDload", BROWSER_LINK_DOWNLOAD, 0 },
+ { "Object.Link.LinkNew", BROWSER_LINK_NEW_WINDOW, 0 },
+ { "Selection", BROWSER_SELECTION, 0 },
+ { "_Selection.SelSave", BROWSER_SELECTION_SAVE, &dialog_saveas },
+ { "Selection.Copy", BROWSER_SELECTION_COPY, 0 },
+ { "Selection.Cut", BROWSER_SELECTION_CUT, 0 },
+ { "_Selection.Paste", BROWSER_SELECTION_PASTE, 0 },
+ { "Selection.Clear", BROWSER_SELECTION_CLEAR, 0 },
+ { "Selection.SelectAll", BROWSER_SELECTION_ALL, 0 },
+ { "Navigate", NO_ACTION, 0 },
+ { "Navigate.Home", BROWSER_NAVIGATE_HOME, 0 },
+ { "Navigate.Back", BROWSER_NAVIGATE_BACK, 0 },
+ { "Navigate.Forward", BROWSER_NAVIGATE_FORWARD, 0 },
+ { "_Navigate.UpLevel", BROWSER_NAVIGATE_UP, 0 },
+ { "Navigate.Reload", BROWSER_NAVIGATE_RELOAD_ALL, 0 },
+ { "Navigate.Stop", BROWSER_NAVIGATE_STOP, 0 },
+ { "View", NO_ACTION, 0 },
+ { "View.ScaleView", BROWSER_SCALE_VIEW, &dialog_zoom },
+ { "View.Images", NO_ACTION, 0 },
+ { "View.Images.ForeImg", BROWSER_IMAGES_FOREGROUND, 0 },
+ { "View.Images.BackImg", BROWSER_IMAGES_BACKGROUND, 0 },
+ { "View.Toolbars", NO_ACTION, 0 },
+ { "View.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 },
+ { "View.Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 },
+ { "_View.Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 },
+ { "View.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 },
+ { "_View.Render", NO_ACTION, 0 },
+ { "View.Render.RenderAnims", BROWSER_BUFFER_ANIMS, 0 },
+ { "View.Render.RenderAll", BROWSER_BUFFER_ALL, 0 },
+ { "_View.OptDefault", BROWSER_SAVE_VIEW, 0 },
+ { "View.Window", NO_ACTION, 0 },
+ { "View.Window.WindowSave", BROWSER_WINDOW_DEFAULT, 0 },
+ { "View.Window.WindowStagr", BROWSER_WINDOW_STAGGER, 0 },
+ { "_View.Window.WindowSize", BROWSER_WINDOW_COPY, 0 },
+ { "View.Window.WindowReset", BROWSER_WINDOW_RESET, 0 },
+ { "Utilities", NO_ACTION, 0 },
+ { "Utilities.Hotlist", HOTLIST_SHOW, 0 },
+ { "Utilities.Hotlist.HotlistAdd", HOTLIST_ADD_URL, 0 },
+ { "Utilities.Hotlist.HotlistShow", HOTLIST_SHOW, 0 },
+ { "Utilities.History", HISTORY_SHOW_GLOBAL, 0 },
+ { "Utilities.History.HistLocal", HISTORY_SHOW_LOCAL, 0 },
+ { "Utilities.History.HistGlobal", HISTORY_SHOW_GLOBAL, 0 },
+ { "Utilities.Cookies", COOKIES_SHOW, 0 },
+ { "Utilities.Cookies.ShowCookies", COOKIES_SHOW, 0 },
+ { "Utilities.Cookies.DeleteCookies", COOKIES_DELETE, 0 },
+ { "Help", HELP_OPEN_CONTENTS, 0 },
+ { "Help.HelpContent", HELP_OPEN_CONTENTS, 0 },
+ { "Help.HelpGuide", HELP_OPEN_GUIDE, 0 },
+ { "_Help.HelpInfo", HELP_OPEN_INFORMATION, 0 },
+ { "Help.HelpCredits", HELP_OPEN_CREDITS, 0 },
+ { "_Help.HelpLicence", HELP_OPEN_LICENCE, 0 },
+ { "Help.HelpInter", HELP_LAUNCH_INTERACTIVE, 0 },
+ {NULL, 0, 0}
+ }
+ };
+ ro_gui_browser_window_menu =
+ ro_gui_menu_define_menu(&browser_definition);
- error = nsurl_create(addr, &url);
- if (error == NSERROR_OK) {
- error = browser_window_navigate(g->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- if (error != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(error), 0);
- }
}
-/**
- * Open a new browser window.
- *
- * \param *g The browser window to act on.
- */
-
-void ro_gui_window_action_new_window(struct gui_window *g)
+/* exported interface documented in riscos/window.h */
+nserror
+ro_gui_window_invalidate_area(struct gui_window *g, const struct rect *rect)
{
- nserror error;
+ bool use_buffer;
+ int x0, y0, x1, y1;
+ struct update_box *cur;
+ wimp_window_info info;
+ os_error *error;
- if (g == NULL || g->bw == NULL)
- return;
+ assert(g);
- error = browser_window_create(BW_CREATE_CLONE,
- browser_window_get_url(g->bw),
- NULL, g->bw, NULL);
+ if (rect == NULL) {
+ info.w = g->window;
+ error = xwimp_get_window_info_header_only(&info);
+ if (error) {
+ LOG("xwimp_get_window_info_header_only: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return NSERROR_INVALID;
+ }
- if (error != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(error), 0);
+ error = xwimp_force_redraw(g->window,
+ info.extent.x0, info.extent.y0,
+ info.extent.x1, info.extent.y1);
+ if (error) {
+ LOG("xwimp_force_redraw: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ return NSERROR_INVALID;
+ }
+ return NSERROR_OK;
}
-}
+ x0 = floorf(rect->x0 * 2 * g->scale);
+ y0 = -ceilf(rect->y1 * 2 * g->scale);
+ x1 = ceilf(rect->x1 * 2 * g->scale) + 1;
+ y1 = -floorf(rect->y0 * 2 * g->scale) + 1;
+ use_buffer =
+ (g->option.buffer_everything || g->option.buffer_animations);
+
+ /* try to optimise buffered redraws */
+ if (use_buffer) {
+ for (cur = pending_updates; cur != NULL; cur = cur->next) {
+ if ((cur->g != g) || (!cur->use_buffer)) {
+ continue;
+ }
+ if ((((cur->x0 - x1) < MARGIN) ||
+ ((cur->x1 - x0) < MARGIN)) &&
+ (((cur->y0 - y1) < MARGIN) ||
+ ((cur->y1 - y0) < MARGIN))) {
+ cur->x0 = min(cur->x0, x0);
+ cur->y0 = min(cur->y0, y0);
+ cur->x1 = max(cur->x1, x1);
+ cur->y1 = max(cur->y1, y1);
+ return NSERROR_OK;
+ }
+ }
+ }
+ cur = malloc(sizeof(struct update_box));
+ if (!cur) {
+ LOG("No memory for malloc.");
+ return NSERROR_NOMEM;
+ }
+
+ cur->x0 = x0;
+ cur->y0 = y0;
+ cur->x1 = x1;
+ cur->y1 = y1;
+ cur->next = pending_updates;
+ pending_updates = cur;
+ cur->g = g;
+ cur->use_buffer = use_buffer;
+
+ return NSERROR_OK;
+}
-/**
- * Open a local history pane for a browser window.
- *
- * \param g The browser window to act on.
- */
-void ro_gui_window_action_local_history(struct gui_window *gw)
+/* exported function documented in riscos/window.h */
+nserror ro_gui_window_set_url(struct gui_window *g, nsurl *url)
{
- nserror res;
+ size_t idn_url_l;
+ char *idn_url_s = NULL;
- if ((gw == NULL) || (gw->bw == NULL)) {
- return;
- }
+ if (g->toolbar) {
+ if (nsoption_bool(display_decoded_idn) == true) {
+ if (nsurl_get_utf8(url, &idn_url_s, &idn_url_l) != NSERROR_OK)
+ idn_url_s = NULL;
+ }
- res = ro_gui_local_history_present(gw->window, gw->bw);
+ ro_toolbar_set_url(g->toolbar, idn_url_s ? idn_url_s : nsurl_access(url), true, false);
- if (res != NSERROR_OK) {
- ro_warn_user(messages_get_errorcode(res), 0);
+ if (idn_url_s)
+ free(idn_url_s);
+
+ ro_gui_url_complete_start(g->toolbar);
}
-}
+ return NSERROR_OK;
+}
-/**
- * Open a save dialogue for a browser window contents.
- *
- * \param *g The browser window to act on.
- * \param save_type The type of save to open.
- */
-void ro_gui_window_action_save(struct gui_window *g, gui_save_type save_type)
+/* exported interface documented in riscos/window.h */
+void ro_gui_window_set_scale(struct gui_window *g, float scale)
{
- struct hlcache_handle *h;
+ g->scale = scale;
+ browser_window_set_scale(g->bw, scale, true);
+}
- if (g == NULL || g->bw == NULL || !browser_window_has_content(g->bw))
- return;
- h = browser_window_get_content(g->bw);
- if (h == NULL)
- return;
+/* exported interface documented in riscos/window.h */
+bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message)
+{
+ os_error *error;
+ os_coord pos;
- ro_gui_save_prepare(save_type, h, NULL, NULL, NULL);
- ro_gui_dialog_open_persistent(g->window, dialog_saveas, true);
-}
+ /* Ignore directories etc. */
+ if (0x1000 <= message->data.data_xfer.file_type)
+ return false;
+ if (!ro_gui_window_to_window_pos(g, message->data.data_xfer.pos.x,
+ message->data.data_xfer.pos.y, &pos))
+ return false;
-/**
- * Open a text search dialogue for a browser window.
- *
- * \param *g The browser window to act on.
- */
+ if (browser_window_drop_file_at_point(g->bw, pos.x, pos.y,
+ message->data.data_xfer.file_name) == false)
+ return false;
-void ro_gui_window_action_search(struct gui_window *g)
-{
- if (g == NULL || g->bw == NULL || !browser_window_can_search(g->bw))
- return;
+ /* send DataLoadAck */
+ message->action = message_DATA_LOAD_ACK;
+ message->your_ref = message->my_ref;
+ error = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender);
+ if (error) {
+ LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
- ro_gui_search_prepare(g->bw);
- ro_gui_dialog_open_persistent(g->window, dialog_search, true);
+ return true;
}
-/**
- * Open a zoom dialogue for a browser window.
- *
- * \param *g The browser window to act on.
- */
-
-void ro_gui_window_action_zoom(struct gui_window *g)
+/* exported interface documented in riscos/window.h */
+void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data)
{
- if (g == NULL)
- return;
+ os_coord pos;
+ struct gui_window *g = (struct gui_window *) data;
- ro_gui_dialog_prepare_zoom(g);
- ro_gui_dialog_open_persistent(g->window, dialog_zoom, true);
+ if (ro_gui_window_to_window_pos(g, pointer->pos.x, pointer->pos.y, &pos))
+ browser_window_mouse_track(g->bw,
+ ro_gui_mouse_drag_state(pointer->buttons,
+ wimp_BUTTON_DOUBLE_CLICK_DRAG),
+ pos.x, pos.y);
}
-/**
- * Add a hotlist entry for a browser window.
- *
- * \param *g The browser window to act on.
- */
-
-static void ro_gui_window_action_add_bookmark(struct gui_window *g)
+/* exported interface documented in riscos/window.h */
+void
+ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi)
{
- nsurl *url;
+ /* sadly there is no 'legal' way to get the sprite into
+ * the Wimp sprite pool other than via a filing system */
+ const char *temp_fname = "Pipe:$._tmpfile";
+ struct browser_window *bw = g->bw;
+ osspriteop_header *overlay = NULL;
+ osspriteop_header *sprite_header;
+ struct bitmap *bitmap;
+ osspriteop_area *area;
+ int width = 34, height = 34;
+ struct hlcache_handle *h;
+ os_error *error;
+ int len, id;
- if (g == NULL || g->bw == NULL || g->toolbar == NULL ||
- browser_window_has_content(g->bw) == false)
- return;
+ assert(bw);
- url = browser_window_get_url(g->bw);
+ h = browser_window_get_content(bw);
+ if (!h) return;
- ro_gui_hotlist_add_page(url);
- ro_toolbar_update_hotlist(g->toolbar);
-}
+ /* if an overlay sprite is defined, locate it and gets its dimensions
+ * so that we can produce a thumbnail with the same dimensions */
+ if (!ro_gui_wimp_get_sprite("ic_netsfxx", &overlay)) {
+ error = xosspriteop_read_sprite_info(osspriteop_PTR,
+ (osspriteop_area *)0x100,
+ (osspriteop_id)overlay, &width, &height, NULL,
+ NULL);
+ if (error) {
+ LOG("xosspriteop_read_sprite_info: 0x%x: %s",
+ error->errnum, error->errmess);
+ ro_warn_user("MiscError", error->errmess);
+ overlay = NULL;
+ } else if (sprite_bpp(overlay) != 8) {
+ LOG("overlay sprite is not 8bpp");
+ overlay = NULL;
+ }
+ }
+ /* create the thumbnail sprite */
+ bitmap = riscos_bitmap_create(width, height,
+ BITMAP_NEW | BITMAP_OPAQUE | BITMAP_CLEAR_MEMORY);
+ if (!bitmap) {
+ LOG("Thumbnail initialisation failed.");
+ return;
+ }
+ riscos_bitmap_render(bitmap, h);
+ if (overlay) {
+ riscos_bitmap_overlay_sprite(bitmap, overlay);
+ }
+ area = riscos_bitmap_convert_8bpp(bitmap);
+ riscos_bitmap_destroy(bitmap);
+ if (!area) {
+ LOG("Thumbnail conversion failed.");
+ return;
+ }
-/**
- * Remove a hotlist entry for a browser window.
- *
- * \param *g The browser window to act on.
- */
+ /* choose a suitable sprite name */
+ id = 0;
+ while (iconise_used[id])
+ if ((unsigned)++id >= NOF_ELEMENTS(iconise_used)) {
+ id = iconise_next;
+ if ((unsigned)++iconise_next >=
+ NOF_ELEMENTS(iconise_used))
+ iconise_next = 0;
+ break;
+ }
-static void ro_gui_window_action_remove_bookmark(struct gui_window *g)
-{
- nsurl *url;
+ sprite_header = (osspriteop_header *)(area + 1);
+ len = sprintf(sprite_header->name, "ic_netsf%.2d", id);
- if (g == NULL || g->bw == NULL || g->toolbar == NULL ||
- browser_window_has_content(g->bw) == false)
+ error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
+ area, temp_fname);
+ if (error) {
+ LOG("xosspriteop_save_sprite_file: 0x%x:%s", error->errnum, error->errmess);
+ ro_warn_user("MiscError", error->errmess);
+ free(area);
return;
+ }
- url = browser_window_get_url(g->bw);
-
- ro_gui_hotlist_remove_page(url);
-}
+ error = xwimpspriteop_merge_sprite_file(temp_fname);
+ if (error) {
+ LOG("xwimpspriteop_merge_sprite_file: 0x%x:%s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ remove(temp_fname);
+ free(area);
+ return;
+ }
+ memcpy(wi->sprite_name, sprite_header->name + 3, len - 2); /* inc NUL */
+ strncpy(wi->title, g->title, sizeof(wi->title));
+ wi->title[sizeof(wi->title) - 1] = '\0';
-/**
- * Open a print dialogue for a browser window.
- *
- * \param *g The browser window to act on.
- */
+ if (wimptextop_string_width(wi->title, 0) > 182) {
+ /* work around bug in Pinboard where it will fail to display
+ * the icon if the text is very wide */
+ if (strlen(wi->title) > 10)
+ wi->title[10] = '\0'; /* pinboard does this anyway */
+ while (wimptextop_string_width(wi->title, 0) > 182)
+ wi->title[strlen(wi->title) - 1] = '\0';
+ }
-void ro_gui_window_action_print(struct gui_window *g)
-{
- if (g == NULL)
- return;
+ wi->size = sizeof(wimp_full_message_window_info);
+ wi->your_ref = wi->my_ref;
+ error = xwimp_send_message(wimp_USER_MESSAGE, (wimp_message*)wi,
+ wi->sender);
+ if (error) {
+ LOG("xwimp_send_message: 0x%x:%s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ else {
+ g->iconise_icon = id;
+ iconise_used[id] = true;
+ }
- ro_gui_print_prepare(g);
- ro_gui_dialog_open_persistent(g->window, dialog_print, true);
+ free(area);
}
-/**
- * Open a page info box for a browser window.
- *
- * \param *g The browser window to act on.
- */
-
-void ro_gui_window_action_page_info(struct gui_window *g)
+/* exported interface documented in riscos/window.h */
+bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message)
{
- if (g == NULL || g->bw == NULL ||
- browser_window_has_content(g->bw) == false)
- return;
+ if (message->data.data_xfer.file_type == osfile_TYPE_TEXT &&
+ ro_gui_window_import_text(g,
+ message->data.data_xfer.file_name)) {
+ os_error *error;
- ro_gui_window_prepare_pageinfo(g);
- ro_gui_dialog_open_persistent(g->window, dialog_pageinfo, false);
+ /* send DataLoadAck */
+ message->action = message_DATA_LOAD_ACK;
+ message->your_ref = message->my_ref;
+ error = xwimp_send_message(wimp_USER_MESSAGE, message,
+ message->sender);
+ if (error) {
+ LOG("xwimp_send_message: 0x%x: %s\n", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ return true;
+ }
+ return false;
}
-/*
- * Window and Toolbar Redraw and Update
- */
+/* exported interface documented in riscos/window.h */
+bool ro_gui_window_check_menu(wimp_menu *menu)
+{
+ return (ro_gui_browser_window_menu == menu) ? true : false;
+}
-/**
- * Redraws the content for all windows.
- */
+/* exported interface documented in riscos/window.h */
void ro_gui_window_redraw_all(void)
{
struct gui_window *g;
@@ -4113,25 +4505,7 @@ void ro_gui_window_redraw_all(void)
}
-/**
- * Remove all pending update boxes for a window
- *
- * \param g gui_window
- */
-void ro_gui_window_remove_update_boxes(struct gui_window *g)
-{
- struct update_box *cur;
-
- for (cur = pending_updates; cur != NULL; cur = cur->next) {
- if (cur->g == g)
- cur->g = NULL;
- }
-}
-
-
-/**
- * Redraw any pending update boxes.
- */
+/* exported interface documented in riscos/window.h */
void ro_gui_window_update_boxes(void)
{
osbool more;
@@ -4214,10 +4588,7 @@ void ro_gui_window_update_boxes(void)
}
-/**
- * Destroy all browser windows.
- */
-
+/* exported interface documented in riscos/window.h */
void ro_gui_window_quit(void)
{
while (window_list) {
@@ -4229,13 +4600,10 @@ void ro_gui_window_quit(void)
}
-/**
- * Animate the "throbbers" of all browser windows.
- */
-
+/* exported interface documented in riscos/window.h */
void ro_gui_throb(void)
{
- struct gui_window *g;
+ struct gui_window *g;
for (g = window_list; g; g = g->next) {
if (!g->active)
@@ -4246,245 +4614,7 @@ void ro_gui_throb(void)
}
-/**
- * Update the toolbar buttons for a given browser window to reflect the
- * current state of its contents.
- *
- * Note that the parameters to this function are arranged so that it can be
- * supplied to the toolbar module as an button state update callback.
- *
- * \param *g The browser window to update.
- */
-
-void ro_gui_window_update_toolbar_buttons(struct gui_window *g)
-{
- struct browser_window *bw;
- struct toolbar *toolbar;
-
- if (g == NULL || g->toolbar == NULL)
- return;
-
- bw = g->bw;
- toolbar = g->toolbar;
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_RELOAD,
- !browser_window_reload_available(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_STOP,
- !browser_window_stop_available(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_BACK,
- !browser_window_back_available(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_FORWARD,
- !browser_window_forward_available(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_UP,
- !browser_window_up_available(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SEARCH,
- !browser_window_can_search(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SCALE,
- !browser_window_has_content(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_PRINT,
- !browser_window_has_content(bw));
-
- ro_toolbar_set_button_shaded_state(toolbar, TOOLBAR_BUTTON_SAVE_SOURCE,
- !browser_window_has_content(bw));
-
- ro_toolbar_update_urlsuggest(toolbar);
-}
-
-
-/**
- * Update a window to reflect a change in toolbar size: used as a callback by
- * the toolbar module when a toolbar height changes.
- *
- * \param *data void pointer the window's gui_window struct
- */
-
-void ro_gui_window_update_toolbar(void *data)
-{
- struct gui_window *g = (struct gui_window *) data;
-
- if (g != NULL)
- gui_window_update_extent(g);
-}
-
-
-/**
- * Save a new toolbar button configuration: used as a callback by the toolbar
- * module when a buttonbar edit has finished.
- *
- * \param *data void pointer to the window's gui_window struct
- * \param *config pointer to a malloc()'d button config string.
- */
-
-void ro_gui_window_save_toolbar_buttons(void *data, char *config)
-{
- nsoption_set_charp(toolbar_browser, config);
- ro_gui_save_options();
-}
-
-
-/**
- * Update a window and its toolbar to reflect a new theme: used as a callback
- * by the toolbar module when a theme change affects a toolbar.
- *
- * \param *data void pointer to the window's gui_window struct
- * \param ok true if the bar still exists; else false.
- */
-
-void ro_gui_window_update_theme(void *data, bool ok)
-{
- struct gui_window *g = (struct gui_window *) data;
-
- if (g != NULL && g->toolbar != NULL) {
- if (ok) {
- gui_window_update_extent(g);
- } else {
- g->toolbar = NULL;
- }
- }
-}
-
-
-/*
- * General Window Support
- */
-
-/**
- * Import text file into window
- *
- * \param g gui window containing textarea
- * \param filename pathname of file to be imported
- * \return true iff successful
- */
-
-bool ro_gui_window_import_text(struct gui_window *g, const char *filename)
-{
- fileswitch_object_type obj_type;
- os_error *error;
- char *buf, *utf8_buf, *sp;
- int size;
- nserror ret;
- const char *ep;
- char *p;
-
- error = xosfile_read_stamped(filename, &obj_type, NULL, NULL,
- &size, NULL, NULL);
- if (error) {
- LOG("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess);
- ro_warn_user("FileError", error->errmess);
- return true; /* was for us, but it didn't work! */
- }
-
- /* Allocate one byte more than needed to ensure that the buffer is
- * always terminated, regardless of file contents.
- */
-
- buf = calloc(size + 1, sizeof(char));
- if (!buf) {
- ro_warn_user("NoMemory", NULL);
- return true;
- }
-
- error = xosfile_load_stamped(filename, (byte*)buf,
- NULL, NULL, NULL, NULL, NULL);
-
- if (error) {
- LOG("xosfile_load_stamped: 0x%x:%s", error->errnum, error->errmess);
- ro_warn_user("LoadError", error->errmess);
- free(buf);
- return true;
- }
-
- ret = utf8_from_local_encoding(buf, size, &utf8_buf);
- if (ret != NSERROR_OK) {
- /* bad encoding shouldn't happen */
- assert(ret != NSERROR_BAD_ENCODING);
- LOG("utf8_from_local_encoding failed");
- free(buf);
- ro_warn_user("NoMemory", NULL);
- return true;
- }
- size = strlen(utf8_buf);
-
- ep = utf8_buf + size;
- p = utf8_buf;
-
- /* skip leading whitespace */
- while (isspace(*p)) p++;
-
- sp = p;
- while (*p && *p != '\r' && *p != '\n')
- p += utf8_next(p, ep - p, 0);
- *p = '\0';
-
- if (p > sp)
- ro_gui_window_launch_url(g, sp);
-
- free(buf);
- free(utf8_buf);
- return true;
-}
-
-
-/**
- * Clones a browser window's options.
- *
- * \param new_gui the new gui window
- * \param old_gui the gui window to clone from, or NULL for default
- */
-
-void ro_gui_window_clone_options(
- struct gui_window *new_gui,
- struct gui_window *old_gui)
-{
- assert(new_gui);
-
- /* Clone the basic options
- */
- if (!old_gui) {
- new_gui->option.buffer_animations = nsoption_bool(buffer_animations);
- new_gui->option.buffer_everything = nsoption_bool(buffer_everything);
- } else {
- new_gui->option = old_gui->option;
- }
-
- /* Set up the toolbar
- */
- if (new_gui->toolbar) {
- ro_toolbar_set_display_buttons(new_gui->toolbar,
- nsoption_bool(toolbar_show_buttons));
- ro_toolbar_set_display_url(new_gui->toolbar,
- nsoption_bool(toolbar_show_address));
- ro_toolbar_set_display_throbber(new_gui->toolbar,
- nsoption_bool(toolbar_show_throbber));
- if ((old_gui) && (old_gui->toolbar)) {
- ro_toolbar_set_display_buttons(new_gui->toolbar,
- ro_toolbar_get_display_buttons(
- old_gui->toolbar));
- ro_toolbar_set_display_url(new_gui->toolbar,
- ro_toolbar_get_display_url(
- old_gui->toolbar));
- ro_toolbar_set_display_throbber(new_gui->toolbar,
- ro_toolbar_get_display_throbber(
- old_gui->toolbar));
- ro_toolbar_process(new_gui->toolbar, -1, true);
- }
- }
-}
-
-
-/**
- * Makes a browser window's options the default.
- *
- * \param gui The riscos gui window to set default options in.
- */
-
+/* exported interface documented in riscos/window.h */
void ro_gui_window_default_options(struct gui_window *gui)
{
if (gui == NULL)
@@ -4512,179 +4642,20 @@ void ro_gui_window_default_options(struct gui_window *gui)
}
-/*
- * Custom Menu Support
- */
-
-/**
- * Prepare or reprepare a form select menu, setting up the menu handle
- * globals in the process.
- *
- * \param g The RISC OS gui window the menu is in.
- * \param control The form control needing a menu.
- * \return true if the menu is OK to be opened; else false.
- */
-
-bool ro_gui_window_prepare_form_select_menu(struct gui_window *g,
- struct form_control *control)
-{
- unsigned int item, entries;
- char *text_convert, *temp;
- struct form_option *option;
- bool reopen = true;
- nserror err;
-
- assert(control);
-
- /* enumerate the entries */
- entries = 0;
- option = form_select_get_option(control, entries);
- while (option != NULL) {
- entries++;
- option = form_select_get_option(control, entries);
- }
-
- if (entries == 0) {
- /* no menu to display */
- ro_gui_menu_destroy();
- return false;
- }
-
- /* free riscos menu if there already is one */
- if ((gui_form_select_menu) && (control != gui_form_select_control)) {
- for (item = 0; ; item++) {
- free(gui_form_select_menu->entries[item].data.
- indirected_text.text);
- if (gui_form_select_menu->entries[item].menu_flags &
- wimp_MENU_LAST)
- break;
- }
- free(gui_form_select_menu->title_data.indirected_text.text);
- free(gui_form_select_menu);
- gui_form_select_menu = 0;
- }
-
- /* allocate new riscos menu */
- if (!gui_form_select_menu) {
- reopen = false;
- gui_form_select_menu = malloc(wimp_SIZEOF_MENU(entries));
- if (!gui_form_select_menu) {
- ro_warn_user("NoMemory", 0);
- ro_gui_menu_destroy();
- return false;
- }
- err = utf8_to_local_encoding(messages_get("SelectMenu"), 0,
- &text_convert);
- if (err != NSERROR_OK) {
- /* badenc should never happen */
- assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_local_encoding failed");
- ro_warn_user("NoMemory", 0);
- ro_gui_menu_destroy();
- return false;
- }
- gui_form_select_menu->title_data.indirected_text.text =
- text_convert;
- ro_gui_menu_init_structure(gui_form_select_menu, entries);
- }
-
- /* initialise menu entries from form control */
- for (item = 0; item < entries; item++) {
- option = form_select_get_option(control, item);
- gui_form_select_menu->entries[item].menu_flags = 0;
- if (option->selected)
- gui_form_select_menu->entries[item].menu_flags =
- wimp_MENU_TICKED;
- if (!reopen) {
-
- /* convert spaces to hard spaces to stop things
- * like 'Go Home' being treated as if 'Home' is a
- * keyboard shortcut and right aligned in the menu.
- */
-
- temp = cnv_space2nbsp(option->text);
- if (!temp) {
- LOG("cnv_space2nbsp failed");
- ro_warn_user("NoMemory", 0);
- ro_gui_menu_destroy();
- return false;
- }
-
- err = utf8_to_local_encoding(temp,
- 0, &text_convert);
- if (err != NSERROR_OK) {
- /* A bad encoding should never happen,
- * so assert this */
- assert(err != NSERROR_BAD_ENCODING);
- LOG("utf8_to_enc failed");
- ro_warn_user("NoMemory", 0);
- ro_gui_menu_destroy();
- return false;
- }
-
- free(temp);
-
- gui_form_select_menu->entries[item].data.indirected_text.text =
- text_convert;
- gui_form_select_menu->entries[item].data.indirected_text.size =
- strlen(gui_form_select_menu->entries[item].
- data.indirected_text.text) + 1;
- }
- }
-
- gui_form_select_menu->entries[0].menu_flags |=
- wimp_MENU_TITLE_INDIRECTED;
- gui_form_select_menu->entries[item - 1].menu_flags |= wimp_MENU_LAST;
-
- return true;
-}
-
-/**
- * Process selections from a form select menu, passing them back to the core.
- *
- * \param *g The browser window affected by the menu.
- * \param *selection The menu selection.
- */
-
-void ro_gui_window_process_form_select_menu(struct gui_window *g,
- wimp_selection *selection)
-{
- assert(g != NULL);
-
- if (selection->items[0] >= 0)
- form_select_process_selection(gui_form_select_control,
- selection->items[0]);
-}
-
-
-/*
- * Window and Toolbar Lookup
- */
-
-/**
- * Convert a RISC OS window handle to a gui_window.
- *
- * \param window RISC OS window handle.
- * \return A pointer to a riscos gui window if found or NULL.
- */
-
+/* exported interface documented in riscos/window.h */
struct gui_window *ro_gui_window_lookup(wimp_w window)
{
struct gui_window *g;
- for (g = window_list; g; g = g->next)
- if (g->window == window)
+ for (g = window_list; g; g = g->next) {
+ if (g->window == window) {
return g;
+ }
+ }
return NULL;
}
-/**
- * Convert a toolbar RISC OS window handle to a gui_window.
- *
- * \param window RISC OS window handle of a toolbar
- * \return pointer to a structure if found, NULL otherwise
- */
-
+/* exported interface documented in riscos/window.h */
struct gui_window *ro_gui_toolbar_lookup(wimp_w window)
{
struct gui_window *g = NULL;
@@ -4702,22 +4673,9 @@ struct gui_window *ro_gui_toolbar_lookup(wimp_w window)
}
-/*
- * Core to RISC OS Conversions
- */
-
-/**
- * Convert x,y screen co-ordinates into window co-ordinates.
- *
- * \param g gui window
- * \param x x ordinate
- * \param y y ordinate
- * \param pos receives position in window co-ordinatates
- * \return true iff conversion successful
- */
-
-bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
- os_coord *pos)
+/* exported interface documented in riscos/window.h */
+bool
+ro_gui_window_to_window_pos(struct gui_window *g, int x, int y, os_coord *pos)
{
wimp_window_state state;
os_error *error;
@@ -4737,18 +4695,11 @@ bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y,
}
-/**
- * Convert x,y window co-ordinates into screen co-ordinates.
- *
- * \param g gui window
- * \param x x ordinate
- * \param y y ordinate
- * \param pos receives position in screen co-ordinatates
- * \return true iff conversion successful
- */
-
-bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
- os_coord *pos)
+/* exported interface documented in riscos/window.h */
+bool ro_gui_window_to_screen_pos(struct gui_window *g,
+ int x,
+ int y,
+ os_coord *pos)
{
wimp_window_state state;
os_error *error;
@@ -4768,24 +4719,9 @@ bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y,
}
-/*
- * Miscellaneous Functions
- *
- * \TODO -- These items might well belong elsewhere.
- */
-
-/**
- * Returns the state of the mouse buttons and modifiers keys for a
- * mouse action, suitable for passing to the OS-independent
- * browser window/ treeview/ etc code.
- *
- * \param buttons Wimp button state.
- * \param type Wimp work-area/icon type for decoding.
- * \return NetSurf core button state.
- */
-
-browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
- wimp_icon_flags type)
+/* exported interface documented in riscos/window.h */
+enum browser_mouse_state
+ro_gui_mouse_click_state(wimp_mouse_state buttons, wimp_icon_flags type)
{
browser_mouse_state state = 0; /* Blank state with nothing set */
static struct {
@@ -4900,18 +4836,9 @@ browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons,
}
-/**
- * Returns the state of the mouse buttons and modifiers keys whilst
- * dragging, for passing to the OS-independent browser window/ treeview/
- * etc code
- *
- * \param buttons Wimp button state.
- * \param type Wimp work-area/icon type for decoding.
- * \return NetSurf core button state.
- */
-
-browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
- wimp_icon_flags type)
+/* exported interface documented in riscos/window.h */
+browser_mouse_state
+ro_gui_mouse_drag_state(wimp_mouse_state buttons, wimp_icon_flags type)
{
browser_mouse_state state = 0; /* Blank state with nothing set */
@@ -4939,10 +4866,7 @@ browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons,
}
-/**
- * Returns true iff one or more Shift keys is held down
- */
-
+/* exported interface documented in riscos/window.h */
bool ro_gui_shift_pressed(void)
{
int shift = 0;
@@ -4951,10 +4875,7 @@ bool ro_gui_shift_pressed(void)
}
-/**
- * Returns true iff one or more Ctrl keys is held down
- */
-
+/* exported interface documented in riscos/window.h */
bool ro_gui_ctrl_pressed(void)
{
int ctrl = 0;
@@ -4963,10 +4884,7 @@ bool ro_gui_ctrl_pressed(void)
}
-/**
- * Returns true iff one or more Alt keys is held down
- */
-
+/* exported interface documented in riscos/window.h */
bool ro_gui_alt_pressed(void)
{
int alt = 0;
@@ -4974,36 +4892,41 @@ bool ro_gui_alt_pressed(void)
return (alt == 0xff);
}
-static struct gui_window_table window_table = {
- .create = gui_window_create,
- .destroy = gui_window_destroy,
- .invalidate = ro_gui_window_invalidate_area,
- .get_scroll = gui_window_get_scroll,
- .set_scroll = gui_window_set_scroll,
- .get_dimensions = gui_window_get_dimensions,
- .update_extent = gui_window_update_extent,
- .set_title = gui_window_set_title,
- .set_url = ro_gui_window_set_url,
- .set_icon = gui_window_set_icon,
- .set_status = riscos_window_set_status,
- .set_pointer = gui_window_set_pointer,
- .place_caret = gui_window_place_caret,
- .remove_caret = gui_window_remove_caret,
- .save_link = gui_window_save_link,
- .drag_start = gui_window_drag_start,
- .scroll_start = gui_window_scroll_start,
- .new_content = gui_window_new_content,
- .start_throbber = gui_window_start_throbber,
- .stop_throbber = gui_window_stop_throbber,
- .create_form_select_menu = gui_window_create_form_select_menu,
+/* exported interface documented in riscos/window.h */
+void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
+{
+ static gui_pointer_shape curr_pointer = GUI_POINTER_DEFAULT;
+ struct ro_gui_pointer_entry *entry;
+ os_error *error;
- /* from save */
- .drag_save_object = gui_drag_save_object,
- .drag_save_selection =gui_drag_save_selection,
+ if (shape == curr_pointer)
+ return;
- /* from textselection */
- .start_selection = gui_start_selection,
-};
+ assert(shape < sizeof ro_gui_pointer_table /
+ sizeof ro_gui_pointer_table[0]);
-struct gui_window_table *riscos_window_table = &window_table;
+ entry = &ro_gui_pointer_table[shape];
+
+ if (entry->wimp_area) {
+ /* pointer in the Wimp's sprite area */
+ error = xwimpspriteop_set_pointer_shape(entry->sprite_name,
+ 1, entry->xactive, entry->yactive, 0, 0);
+ if (error) {
+ LOG("xwimpspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ } else {
+ /* pointer in our own sprite area */
+ error = xosspriteop_set_pointer_shape(osspriteop_USER_AREA,
+ gui_sprites,
+ (osspriteop_id) entry->sprite_name,
+ 1, entry->xactive, entry->yactive, 0, 0);
+ if (error) {
+ LOG("xosspriteop_set_pointer_shape: 0x%x: %s", error->errnum, error->errmess);
+ ro_warn_user("WimpError", error->errmess);
+ }
+ }
+
+ curr_pointer = shape;
+}
diff --git a/frontends/riscos/window.h b/frontends/riscos/window.h
index 30b0965..0a5bd43 100644
--- a/frontends/riscos/window.h
+++ b/frontends/riscos/window.h
@@ -30,10 +30,21 @@ struct nsurl;
extern struct gui_window_table *riscos_window_table;
+/**
+ * Initialise the browser window module and its menus.
+ */
void ro_gui_window_initialise(void);
+
+/**
+ * Check if a particular menu handle is a browser window menu
+ *
+ * \param menu The menu in question.
+ * \return true if this menu is a browser window menu
+ */
bool ro_gui_window_check_menu(wimp_menu *menu);
+
/**
* Set the contents of a window's address bar.
*
@@ -42,6 +53,7 @@ bool ro_gui_window_check_menu(wimp_menu *menu);
*/
nserror ro_gui_window_set_url(struct gui_window *g, struct nsurl *url);
+
/**
* Cause an area of a window to be invalidated
*
@@ -56,5 +68,186 @@ nserror ro_gui_window_set_url(struct gui_window *g, struct nsurl *url);
*/
nserror ro_gui_window_invalidate_area(struct gui_window *g, const struct rect *rect);
+
+/**
+ * Set a gui_window's scale
+ */
+void ro_gui_window_set_scale(struct gui_window *g, float scale);
+
+
+/**
+ * Handle Message_DataLoad (file dragged in) for a window.
+ *
+ * If the file was dragged into a form file input, it is used as the value.
+ *
+ * \param g window
+ * \param message Message_DataLoad block
+ * \return true if the load was processed
+ */
+bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message);
+
+
+/**
+ * Handle pointer movements in a browser window.
+ *
+ * \param pointer new mouse position
+ * \param data browser window that the pointer is in
+ */
+void ro_gui_window_mouse_at(wimp_pointer *pointer, void *data);
+
+
+/**
+ * Window is being iconised.
+ *
+ * Create a suitable thumbnail sprite (which, sadly, must be in the
+ * Wimp sprite pool), and return the sprite name and truncated title
+ * to the iconiser
+ *
+ * \param g the gui window being iconised
+ * \param wi the WindowInfo message from the iconiser
+ */
+void ro_gui_window_iconise(struct gui_window *g, wimp_full_message_window_info *wi);
+
+
+/**
+ * Handle Message_DataLoad (file dragged in) for a toolbar
+ *
+ * @todo This belongs in the toolbar module, and should be moved there
+ * once the module is able to usefully handle its own events.
+ *
+ * \param g window
+ * \param message Message_DataLoad block
+ * \return true if the load was processed
+ */
+bool ro_gui_toolbar_dataload(struct gui_window *g, wimp_message *message);
+
+
+/**
+ * Redraws the content for all windows.
+ */
+void ro_gui_window_redraw_all(void);
+
+
+/**
+ * Redraw any pending update boxes.
+ */
+void ro_gui_window_update_boxes(void);
+
+
+/**
+ * Destroy all browser windows.
+ */
+void ro_gui_window_quit(void);
+
+
+/**
+ * Close all browser windows
+ *
+ * no need for a separate fn same operation as quit
+*/
+#define ro_gui_window_close_all ro_gui_window_quit
+
+
+/**
+ * Animate the "throbbers" of all browser windows.
+ */
+void ro_gui_throb(void);
+
+/**
+ * Makes a browser window's options the default.
+ *
+ * \param gui The riscos gui window to set default options in.
+ */
+void ro_gui_window_default_options(struct gui_window *gui);
+
+
+/**
+ * Convert a RISC OS window handle to a gui_window.
+ *
+ * \param window RISC OS window handle.
+ * \return A pointer to a riscos gui window if found or NULL.
+ */
+struct gui_window *ro_gui_window_lookup(wimp_w window);
+
+
+/**
+ * Convert a toolbar RISC OS window handle to a gui_window.
+ *
+ * \param window RISC OS window handle of a toolbar
+ * \return pointer to a structure if found, NULL otherwise
+ */
+struct gui_window *ro_gui_toolbar_lookup(wimp_w window);
+
+
+/**
+ * Convert x,y screen co-ordinates into window co-ordinates.
+ *
+ * \param g gui window
+ * \param x x ordinate
+ * \param y y ordinate
+ * \param pos receives position in window co-ordinatates
+ * \return true iff conversion successful
+ */
+bool ro_gui_window_to_window_pos(struct gui_window *g, int x, int y, os_coord *pos);
+
+
+/**
+ * Convert x,y window co-ordinates into screen co-ordinates.
+ *
+ * \param g gui window
+ * \param x x ordinate
+ * \param y y ordinate
+ * \param pos receives position in screen co-ordinatates
+ * \return true iff conversion successful
+ */
+bool ro_gui_window_to_screen_pos(struct gui_window *g, int x, int y, os_coord *pos);
+
+/**
+ * Returns the state of the mouse buttons and modifiers keys for a
+ * mouse action, suitable for passing to the OS-independent
+ * browser window/ treeview/ etc code.
+ *
+ * \param buttons Wimp button state.
+ * \param type Wimp work-area/icon type for decoding.
+ * \return NetSurf core button state.
+ */
+enum browser_mouse_state ro_gui_mouse_click_state(wimp_mouse_state buttons, wimp_icon_flags type);
+
+
+/**
+ * Returns the state of the mouse buttons and modifiers keys whilst
+ * dragging, for passing to the OS-independent browser window/ treeview/
+ * etc code
+ *
+ * \param buttons Wimp button state.
+ * \param type Wimp work-area/icon type for decoding.
+ * \return NetSurf core button state.
+ */
+enum browser_mouse_state ro_gui_mouse_drag_state(wimp_mouse_state buttons, wimp_icon_flags type);
+
+
+/**
+ * Returns true iff one or more Shift keys is held down
+ */
+bool ro_gui_shift_pressed(void);
+
+
+/**
+ * Returns true iff one or more Ctrl keys is held down
+ */
+bool ro_gui_ctrl_pressed(void);
+
+
+/**
+ * Returns true iff one or more Alt keys is held down
+ */
+bool ro_gui_alt_pressed(void);
+
+
+/**
+ * Change mouse pointer shape
+ */
+void gui_window_set_pointer(struct gui_window *g, enum gui_pointer_shape shape);
+
#endif
diff --git a/frontends/windows/cookies.c b/frontends/windows/cookies.c
index c4880fa..b3c56da 100644
--- a/frontends/windows/cookies.c
+++ b/frontends/windows/cookies.c
@@ -136,7 +136,7 @@ static nserror nsw32_cookie_init(HINSTANCE hInstance)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct nsw32_cookie_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/windows/corewindow.c b/frontends/windows/corewindow.c
index adf1c65..3c31c5e 100644
--- a/frontends/windows/corewindow.c
+++ b/frontends/windows/corewindow.c
@@ -211,7 +211,7 @@ nsw32_corewindow_vscroll(struct nsw32_corewindow *nsw32_cw,
NULL,
NULL,
NULL,
- SW_ERASE | SW_INVALIDATE);
+ SW_INVALIDATE);
/**
* /todo win32 corewindow vertical scrolling needs us to
@@ -278,7 +278,7 @@ nsw32_corewindow_hscroll(struct nsw32_corewindow *nsw32_cw,
NULL,
NULL,
NULL,
- SW_ERASE | SW_INVALIDATE);
+ SW_INVALIDATE);
return 0;
}
@@ -286,18 +286,40 @@ nsw32_corewindow_hscroll(struct nsw32_corewindow *nsw32_cw,
static LRESULT
nsw32_corewindow_mousedown(struct nsw32_corewindow *nsw32_cw,
+ HWND hwnd,
int x, int y,
browser_mouse_state button)
{
+ SCROLLINFO si; /* scroll information */
+
+ /* get scroll positions */
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_POS;
+ GetScrollInfo(hwnd, SB_HORZ, &si);
+ x += si.nPos;
+ GetScrollInfo(hwnd, SB_VERT, &si);
+ y += si.nPos;
+
nsw32_cw->mouse(nsw32_cw, button, x, y);
return 0;
}
static LRESULT
nsw32_corewindow_mouseup(struct nsw32_corewindow *nsw32_cw,
+ HWND hwnd,
int x, int y,
browser_mouse_state button)
{
+ SCROLLINFO si; /* scroll information */
+
+ /* get scroll positions */
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_POS;
+ GetScrollInfo(hwnd, SB_HORZ, &si);
+ x += si.nPos;
+ GetScrollInfo(hwnd, SB_VERT, &si);
+ y += si.nPos;
+
nsw32_cw->mouse(nsw32_cw, button, x, y);
return 0;
}
@@ -342,25 +364,25 @@ nsw32_window_corewindow_event_callback(HWND hwnd,
return nsw32_corewindow_hscroll(nsw32_cw, hwnd, wparam);
case WM_LBUTTONDOWN:
- return nsw32_corewindow_mousedown(nsw32_cw,
+ return nsw32_corewindow_mousedown(nsw32_cw, hwnd,
GET_X_LPARAM(lparam),
GET_Y_LPARAM(lparam),
BROWSER_MOUSE_PRESS_1);
case WM_RBUTTONDOWN:
- return nsw32_corewindow_mousedown(nsw32_cw,
+ return nsw32_corewindow_mousedown(nsw32_cw, hwnd,
GET_X_LPARAM(lparam),
GET_Y_LPARAM(lparam),
BROWSER_MOUSE_PRESS_2);
case WM_LBUTTONUP:
- return nsw32_corewindow_mouseup(nsw32_cw,
+ return nsw32_corewindow_mouseup(nsw32_cw, hwnd,
GET_X_LPARAM(lparam),
GET_Y_LPARAM(lparam),
BROWSER_MOUSE_CLICK_1);
case WM_RBUTTONUP:
- return nsw32_corewindow_mouseup(nsw32_cw,
+ return nsw32_corewindow_mouseup(nsw32_cw, hwnd,
GET_X_LPARAM(lparam),
GET_Y_LPARAM(lparam),
BROWSER_MOUSE_CLICK_2);
@@ -393,14 +415,22 @@ nsw32_cw_invalidate_area(struct core_window *cw, const struct rect *rect)
RECT redrawrect;
if (rect != NULL) {
- redrawrectp = &redrawrect;
+ SCROLLINFO si; /* scroll information */
+
+ /* get scroll positions */
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_POS;
+ GetScrollInfo(nsw32_cw->hWnd, SB_HORZ, &si);
+ redrawrect.left = (long)rect->x0 - si.nPos;
+ redrawrect.right = (long)rect->x1 - si.nPos;
- redrawrect.left = (long)rect->x0;
- redrawrect.top = (long)rect->y0;
- redrawrect.right =(long)rect->x1;
- redrawrect.bottom = (long)rect->y1;
+ GetScrollInfo(nsw32_cw->hWnd, SB_VERT, &si);
+ redrawrect.top = (long)rect->y0 - si.nPos;
+ redrawrect.bottom = (long)rect->y1 - si.nPos;
+ redrawrectp = &redrawrect;
}
+
RedrawWindow(nsw32_cw->hWnd,
redrawrectp,
NULL,
@@ -456,7 +486,7 @@ static void
nsw32_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
{
struct nsw32_corewindow *nsw32_cw = (struct nsw32_corewindow *)cw;
- nsw32_cw->drag_staus = ds;
+ nsw32_cw->drag_status = ds;
}
@@ -478,6 +508,7 @@ nsw32_corewindow_init(HINSTANCE hInstance,
/* setup the core window callback table */
nsw32_cw->cb_table = &nsw32_cw_cb_table;
+ nsw32_cw->drag_status = CORE_WINDOW_DRAG_NONE;
/* start with the content area being as small as possible */
nsw32_cw->content_width = -1;
diff --git a/frontends/windows/corewindow.h b/frontends/windows/corewindow.h
index b78c72e..cffae3c 100644
--- a/frontends/windows/corewindow.h
+++ b/frontends/windows/corewindow.h
@@ -38,7 +38,7 @@ struct nsw32_corewindow {
const char *title;
/** drag status set by core */
- core_window_drag_status drag_staus;
+ core_window_drag_status drag_status;
/** table of callbacks for core window operations */
struct core_window_callback_table *cb_table;
diff --git a/frontends/windows/global_history.c b/frontends/windows/global_history.c
index 0ba013b..dcc75ba 100644
--- a/frontends/windows/global_history.c
+++ b/frontends/windows/global_history.c
@@ -126,7 +126,7 @@ static nserror nsw32_global_history_init(HINSTANCE hInstance)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct nsw32_global_history_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/windows/hotlist.c b/frontends/windows/hotlist.c
index 0efe76f..e8dd90b 100644
--- a/frontends/windows/hotlist.c
+++ b/frontends/windows/hotlist.c
@@ -130,7 +130,7 @@ static nserror nsw32_hotlist_init(HINSTANCE hInstance)
return NSERROR_OK;
}
- ncwin = malloc(sizeof(struct nsw32_hotlist_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/frontends/windows/local_history.c b/frontends/windows/local_history.c
index f447423..722d365 100644
--- a/frontends/windows/local_history.c
+++ b/frontends/windows/local_history.c
@@ -111,11 +111,7 @@ nsw32_local_history_draw(struct nsw32_corewindow *nsw32_cw,
lhw = (struct nsw32_local_history_window *)nsw32_cw;
- local_history_redraw(lhw->session,
- r->x0 - scrollx,
- r->y0 - scrolly,
- r,
- &ctx);
+ local_history_redraw(lhw->session, -scrollx, -scrolly, r, &ctx);
return NSERROR_OK;
}
@@ -147,7 +143,7 @@ nsw32_local_history_init(HINSTANCE hInstance,
return res;
}
- ncwin = malloc(sizeof(struct nsw32_local_history_window));
+ ncwin = calloc(1, sizeof(*ncwin));
if (ncwin == NULL) {
return NSERROR_NOMEM;
}
diff --git a/render/html.c b/render/html.c
index 62b7f3e..a573ef5 100644
--- a/render/html.c
+++ b/render/html.c
@@ -706,7 +706,6 @@ dom_default_action_DOMSubtreeModified_cb(struct dom_event *evt, void *pw)
{
dom_event_target *node;
dom_node_type type;
- dom_string *name;
dom_exception exc;
html_content *htmlc = pw;
@@ -722,16 +721,19 @@ dom_default_action_DOMSubtreeModified_cb(struct dom_event *evt, void *pw)
exc = dom_node_get_node_type(node, &type);
if ((exc == DOM_NO_ERR) && (type == DOM_ELEMENT_NODE)) {
/* an element node has been modified */
- exc = dom_node_get_node_name(node, &name);
- if ((exc == DOM_NO_ERR) && (name != NULL)) {
+ dom_html_element_type tag_type;
- if (dom_string_caseless_isequal(name,
- corestring_dom_style)) {
- html_css_update_style(htmlc,
- (dom_node *)node);
- }
+ exc = dom_html_element_get_tag_type(node, &tag_type);
+ if (exc != DOM_NO_ERR) {
+ tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN;
+ }
- dom_string_unref(name);
+ switch (tag_type) {
+ case DOM_HTML_ELEMENT_TYPE_STYLE:
+ html_css_update_style(htmlc, (dom_node *)node);
+ break;
+ default:
+ break;
}
}
dom_node_unref(node);