From 3394be946496d955cb177a2ad69e89e1d9263b57 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 30 Dec 2013 01:21:53 +0100 Subject: [PATCH] Clean up scout widgets This patch integrate the scout widgets with Genode's new API headers 'util/geometry.h', 'os/surface.h' and 'os/texture.h'. Thereby, we get almost rid of the platform-abstraction shim that was never used anyway. Furthermore, it extracts the parts that are worth reusing from the scout implementation to the public location 'demo/include/scout'. --- demo/include/scout/alloc.h | 35 + demo/include/scout/canvas.h | 216 +++++ demo/include/scout/element.h | 212 +++++ .../scout/include => include/scout}/event.h | 46 +- .../scout/include => include/scout}/fader.h | 15 +- demo/include/scout/graphics_backend.h | 51 ++ demo/include/scout/misc_math.h | 24 + .../scout/nitpicker_graphics_backend.h | 158 ++++ demo/include/scout/parent_element.h | 95 ++ demo/include/scout/platform.h | 200 +++++ .../include/genode => include/scout}/printf.h | 19 +- demo/include/scout/string.h | 25 + demo/include/scout/texture_allocator.h | 42 + .../scout/include => include/scout}/tick.h | 12 +- demo/include/scout/types.h | 25 + .../include => include/scout}/user_state.h | 69 +- demo/include/scout/window.h | 297 +++++++ .../scout_gfx/horizontal_shadow_painter.h | 77 ++ demo/include/scout_gfx/icon_painter.h | 270 ++++++ demo/include/scout_gfx/random.h | 31 + .../scout_gfx/refracted_icon_painter.h | 170 ++++ demo/include/scout_gfx/sky_texture_painter.h | 264 ++++++ demo/lib/mk/scout_gfx.mk | 3 + demo/lib/mk/scout_widgets.mk | 21 +- demo/src/app/launchpad/child_entry.h | 44 +- demo/src/app/launchpad/launch_entry.h | 43 +- demo/src/app/launchpad/launcher.cc | 4 +- demo/src/app/launchpad/launchpad_window.cc | 70 +- demo/src/app/launchpad/launchpad_window.h | 61 +- demo/src/app/launchpad/loadbar.h | 79 +- demo/src/app/launchpad/main.cc | 83 +- demo/src/app/launchpad/section.h | 58 +- demo/src/app/launchpad/status_entry.h | 28 +- demo/src/app/launchpad/target.mk | 4 +- demo/src/app/scout/{common => }/about.cc | 7 +- demo/src/app/scout/{include => }/browser.h | 13 +- .../app/scout/{common => }/browser_window.cc | 101 ++- .../app/scout/{include => }/browser_window.h | 45 +- demo/src/app/scout/common/refracted_icon.cc | 184 ---- demo/src/app/scout/common/sky_texture.cc | 363 -------- demo/src/app/scout/common/test.txt | 11 - demo/src/app/scout/common/widgets.cc | 474 ---------- demo/src/app/scout/{include => }/config.h | 5 +- demo/src/app/scout/{common => }/doc.cc | 2 + demo/src/app/scout/{common => }/elements.cc | 200 ++--- demo/src/app/scout/elements.h | 590 +++++++++++++ demo/src/app/scout/{include => }/fade_icon.h | 12 +- demo/src/app/scout/genode/platform_genode.cc | 382 -------- demo/src/app/scout/genode/startup.cc | 17 - demo/src/app/scout/{include => }/history.h | 6 +- demo/src/app/scout/include/canvas.h | 325 ------- demo/src/app/scout/include/canvas_rgb565.h | 239 ----- demo/src/app/scout/include/color.h | 52 -- demo/src/app/scout/include/elements.h | 815 ------------------ demo/src/app/scout/include/font.h | 62 -- demo/src/app/scout/include/genode/alloc.h | 30 - demo/src/app/scout/include/genode/string.h | 28 - demo/src/app/scout/include/miscmath.h | 35 - demo/src/app/scout/include/platform.h | 164 ---- demo/src/app/scout/include/redraw_manager.h | 150 ---- demo/src/app/scout/include/scout_types.h | 21 - demo/src/app/scout/include/styles.h | 53 -- demo/src/app/scout/include/window.h | 222 ----- demo/src/app/scout/{genode => }/launcher.cc | 1 + .../{include/genode => }/launcher_config.h | 10 +- demo/src/app/scout/{common => }/main.cc | 105 ++- demo/src/app/scout/{common => }/navbar.cc | 70 +- demo/src/app/scout/{common => }/png_image.cc | 37 +- .../app/scout/{include => }/refracted_icon.h | 51 +- demo/src/app/scout/{common => }/scrollbar.cc | 43 +- demo/src/app/scout/{include => }/scrollbar.h | 13 +- .../src/app/scout/{include => }/sky_texture.h | 21 +- demo/src/app/scout/styles.h | 54 ++ demo/src/app/scout/{genode => }/target.mk | 6 +- demo/src/app/scout/{common => }/tick.cc | 7 +- demo/src/app/scout/{include => }/titlebar.h | 27 +- demo/src/app/scout/widgets.cc | 206 +++++ demo/src/app/scout/{include => }/widgets.h | 53 +- demo/src/lib/scout_gfx/sky_texture_painter.cc | 172 ++++ .../liquid_framebuffer/framebuffer_window.h | 119 +-- demo/src/server/liquid_framebuffer/main.cc | 137 ++- .../src/server/liquid_framebuffer/services.cc | 67 +- demo/src/server/liquid_framebuffer/services.h | 4 +- demo/src/server/liquid_framebuffer/target.mk | 3 +- demo/src/server/nitlog/main.cc | 5 +- 85 files changed, 4175 insertions(+), 4495 deletions(-) create mode 100644 demo/include/scout/alloc.h create mode 100644 demo/include/scout/canvas.h create mode 100644 demo/include/scout/element.h rename demo/{src/app/scout/include => include/scout}/event.h (63%) rename demo/{src/app/scout/include => include/scout}/fader.h (84%) create mode 100644 demo/include/scout/graphics_backend.h create mode 100644 demo/include/scout/misc_math.h create mode 100644 demo/include/scout/nitpicker_graphics_backend.h create mode 100644 demo/include/scout/parent_element.h create mode 100644 demo/include/scout/platform.h rename demo/{src/app/scout/include/genode => include/scout}/printf.h (52%) create mode 100644 demo/include/scout/string.h create mode 100644 demo/include/scout/texture_allocator.h rename demo/{src/app/scout/include => include/scout}/tick.h (90%) create mode 100644 demo/include/scout/types.h rename demo/{src/app/scout/include => include/scout}/user_state.h (64%) create mode 100644 demo/include/scout/window.h create mode 100644 demo/include/scout_gfx/horizontal_shadow_painter.h create mode 100644 demo/include/scout_gfx/icon_painter.h create mode 100644 demo/include/scout_gfx/random.h create mode 100644 demo/include/scout_gfx/refracted_icon_painter.h create mode 100644 demo/include/scout_gfx/sky_texture_painter.h create mode 100644 demo/lib/mk/scout_gfx.mk rename demo/src/app/scout/{common => }/about.cc (98%) rename demo/src/app/scout/{include => }/browser.h (94%) rename demo/src/app/scout/{common => }/browser_window.cc (77%) rename demo/src/app/scout/{include => }/browser_window.h (79%) delete mode 100644 demo/src/app/scout/common/refracted_icon.cc delete mode 100644 demo/src/app/scout/common/sky_texture.cc delete mode 100644 demo/src/app/scout/common/test.txt delete mode 100644 demo/src/app/scout/common/widgets.cc rename demo/src/app/scout/{include => }/config.h (92%) rename demo/src/app/scout/{common => }/doc.cc (99%) rename demo/src/app/scout/{common => }/elements.cc (52%) create mode 100644 demo/src/app/scout/elements.h rename demo/src/app/scout/{include => }/fade_icon.h (85%) delete mode 100644 demo/src/app/scout/genode/platform_genode.cc delete mode 100644 demo/src/app/scout/genode/startup.cc rename demo/src/app/scout/{include => }/history.h (97%) delete mode 100644 demo/src/app/scout/include/canvas.h delete mode 100644 demo/src/app/scout/include/canvas_rgb565.h delete mode 100644 demo/src/app/scout/include/color.h delete mode 100644 demo/src/app/scout/include/elements.h delete mode 100644 demo/src/app/scout/include/font.h delete mode 100644 demo/src/app/scout/include/genode/alloc.h delete mode 100644 demo/src/app/scout/include/genode/string.h delete mode 100644 demo/src/app/scout/include/miscmath.h delete mode 100644 demo/src/app/scout/include/platform.h delete mode 100644 demo/src/app/scout/include/redraw_manager.h delete mode 100644 demo/src/app/scout/include/scout_types.h delete mode 100644 demo/src/app/scout/include/styles.h delete mode 100644 demo/src/app/scout/include/window.h rename demo/src/app/scout/{genode => }/launcher.cc (99%) rename demo/src/app/scout/{include/genode => }/launcher_config.h (80%) rename demo/src/app/scout/{common => }/main.cc (53%) rename demo/src/app/scout/{common => }/navbar.cc (60%) rename demo/src/app/scout/{common => }/png_image.cc (76%) rename demo/src/app/scout/{include => }/refracted_icon.h (54%) rename demo/src/app/scout/{common => }/scrollbar.cc (86%) rename demo/src/app/scout/{include => }/scrollbar.h (90%) rename demo/src/app/scout/{include => }/sky_texture.h (58%) create mode 100644 demo/src/app/scout/styles.h rename demo/src/app/scout/{genode => }/target.mk (85%) rename demo/src/app/scout/{common => }/tick.cc (97%) rename demo/src/app/scout/{include => }/titlebar.h (61%) create mode 100644 demo/src/app/scout/widgets.cc rename demo/src/app/scout/{include => }/widgets.h (74%) create mode 100644 demo/src/lib/scout_gfx/sky_texture_painter.cc diff --git a/demo/include/scout/alloc.h b/demo/include/scout/alloc.h new file mode 100644 index 000000000..e5885940e --- /dev/null +++ b/demo/include/scout/alloc.h @@ -0,0 +1,35 @@ +/* + * \brief Malloc/free wrappers for Genode + * \date 2008-07-24 + * \author Norman Feske + */ + +/* + * Copyright (C) 2008-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__ALLOC_H_ +#define _INCLUDE__SCOUT__ALLOC_H_ + +#include + +namespace Scout { + + static inline void *malloc(unsigned long size) + { + return Genode::env()->heap()->alloc(size); + } + + static inline void free(void *addr) + { + /* + * FIXME: We expect the heap to know the size of the + * block and thus, just specify zero as size. + */ + Genode::env()->heap()->free(addr, 0); } +} + +#endif /* _INCLUDE__SCOUT__ALLOC_H_ */ diff --git a/demo/include/scout/canvas.h b/demo/include/scout/canvas.h new file mode 100644 index 000000000..0b7110311 --- /dev/null +++ b/demo/include/scout/canvas.h @@ -0,0 +1,216 @@ +/* + * \brief Generic interface of graphics backend and chunky template + * \date 2005-10-24 + * \author Norman Feske + */ + +/* + * Copyright (C) 2005-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__CANVAS_H_ +#define _INCLUDE__SCOUT__CANVAS_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace Scout { + using Genode::Color; + using Genode::Pixel_rgba; + + typedef Text_painter::Font Font; + + struct Canvas_base; + template class Canvas; +} + + +struct Scout::Canvas_base : Texture_allocator +{ + virtual ~Canvas_base() { } + + virtual Area size() const = 0; + + virtual Rect clip() const = 0; + + virtual void clip(Rect rect) = 0; + + virtual void draw_box(int x, int y, int w, int h, Color c) = 0; + + virtual void draw_string(int x, int y, Font *font, Color color, + char const *str, int len) = 0; + + virtual void draw_horizontal_shadow(Rect rect, int intensity) = 0; + + virtual void draw_icon(Rect, Texture_base const &, unsigned alpha) = 0; + + virtual void draw_sky_texture(int py, + Sky_texture_painter::Sky_texture_base const &, + bool detail) = 0; + + virtual void draw_refracted_icon(Point pos, + Scout::Refracted_icon_painter::Distmap const &distmap, + Texture_base &tmp, Texture_base const &foreground, + bool detail, bool filter_backbuf) = 0; + + virtual void draw_texture(Point pos, Texture_base const &texture) = 0; +}; + + +#include +#include + + +namespace Genode { + + template <> + inline void + Texture::rgba(unsigned char const *rgba, unsigned len, int y) + { + if (len > size().w()) len = size().w(); + if (y < 0 || y >= (int)size().h()) return; + + Genode::Pixel_rgb565 *dst_pixel = pixel() + y*size().w(); + unsigned char *dst_alpha = alpha() ? alpha() + y*size().w() : 0; + + Genode::Dither_matrix::Row dither_row = Dither_matrix::row(y); + + for (unsigned i = 0; i < len; i++) { + + int v = dither_row.value(i) >> 5; + int r = *rgba++ + v; + int g = *rgba++ + v; + int b = *rgba++ + v; + int a = *rgba++ + v; + + using Genode::min; + dst_pixel[i].rgba(min(r, 255), min(g, 255), min(b, 255)); + + if (dst_alpha) + dst_alpha[i] = min(a, 255); + } + } +} + + +template +class Scout::Canvas : public Canvas_base +{ + private: + + Genode::Surface _surface; + + public: + + Canvas(PT *base, Area size) : _surface(base, size) { } + + Area size() const { return _surface.size(); } + + Rect clip() const { return _surface.clip(); } + + void clip(Rect rect) { _surface.clip(rect); } + + void draw_string(int x, int y, Font *font, Color color, char const *str, int len) + { + char buf[len + 1]; + Genode::strncpy(buf, str, len + 1); + Text_painter::paint(_surface, Point(x, y), *font, color, buf); + } + + void draw_box(int x, int y, int w, int h, Color c) + { + Box_painter::paint(_surface, Rect(Point(x, y), Area(w, h)), c); + } + + void draw_horizontal_shadow(Rect rect, int intensity) + { + Horizontal_shadow_painter::paint(_surface, rect, intensity); + } + + void draw_icon(Rect rect, Texture_base const &icon, unsigned alpha) + { + Icon_painter::paint(_surface, rect, + static_cast const &>(icon), alpha); + } + + void draw_sky_texture(int py, + Sky_texture_painter::Sky_texture_base const &texture, + bool detail) + { + Sky_texture_painter::paint(_surface, py, texture, detail); + } + + void draw_refracted_icon(Point pos, + Scout::Refracted_icon_painter::Distmap const &distmap, + Texture_base &tmp, Texture_base const &foreground, + bool detail, bool filter_backbuf) + { + using namespace Scout; + Refracted_icon_painter::paint(_surface, pos, distmap, + static_cast &>(tmp), + static_cast const &>(foreground), + detail, filter_backbuf); + } + + void draw_texture(Point pos, Texture_base const &texture_base) + { + Texture const &texture = static_cast const &>(texture_base); + + Texture_painter::paint(_surface, texture, Color(0, 0, 0), pos, + Texture_painter::SOLID, true); + } + + Texture_base *alloc_texture(Area size, bool has_alpha) + { + using namespace Genode; + + PT *pixel = (PT *)env()->heap()->alloc(size.count()*sizeof(PT)); + + unsigned char *alpha = 0; + + if (has_alpha) + alpha = (unsigned char *)env()->heap()->alloc(size.count()); + + return new (env()->heap()) Genode::Texture(pixel, alpha, size); + } + + virtual void free_texture(Texture_base *texture_base) + { + using namespace Genode; + + Texture *texture = static_cast *>(texture_base); + + size_t const num_pixels = texture->size().count(); + + if (texture->alpha()) + env()->heap()->free(texture->alpha(), num_pixels); + + env()->heap()->free(texture->pixel(), sizeof(PT)*num_pixels); + + destroy(env()->heap(), texture); + } + + virtual void set_rgba_texture(Texture_base *texture_base, + unsigned char const *rgba, + unsigned len, int y) + { + Texture *texture = static_cast *>(texture_base); + + texture->rgba(rgba, len, y); + } +}; + +#endif /* _INCLUDE__SCOUT__CANVAS_H_ */ diff --git a/demo/include/scout/element.h b/demo/include/scout/element.h new file mode 100644 index 000000000..59f2d4578 --- /dev/null +++ b/demo/include/scout/element.h @@ -0,0 +1,212 @@ +/* + * \brief Scout GUI element + * \author Norman Feske + * \date 2006-08-30 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__ELEMENT_H_ +#define _INCLUDE__SCOUT__ELEMENT_H_ + +#include +#include + +namespace Scout { + class Element; + class Parent_element; +} + + +class Scout::Element +{ + protected: + + Point _position; /* relative position managed by parent */ + Area _size; /* size managed by parent */ + Area _min_size; /* min size managed by element */ + Parent_element *_parent; /* parent in element hierarchy */ + Event_handler *_evh; /* event handler object */ + struct { + int mfocus : 1; /* element has mouse focus */ + int selected : 1; /* element has selected state */ + int takes_focus : 1; /* element highlights mouse focus */ + int chapter : 1; /* display element as single page */ + int findable : 1; /* regard element in find function */ + int bottom : 1; /* place element to the bottom */ + } _flags; + + public: + + Element mutable *next = { 0 }; /* managed by parent */ + + /** + * Constructor + */ + Element() : _parent(0), _evh(0) + { + _flags.mfocus = _flags.selected = 0; + _flags.takes_focus = 0; + _flags.chapter = 0; + _flags.findable = 1; + _flags.bottom = 0; + } + + /** + * Destructor + */ + virtual ~Element(); + + /** + * Accessor functionse + */ + Point position() const { return _position; } + Area size() const { return _size; } + Area min_size() const { return _min_size; } + bool is_bottom() const { return _flags.bottom; } + + void findable(int flag) { _flags.findable = flag; } + + /** + * Set geometry of the element + * + * This function should only be called by the immediate parent + * element. + */ + virtual void geometry(Rect rect) + { + _position = rect.p1(); + _size = rect.area(); + } + + /** + * Set/reset the mouse focus + */ + virtual void mfocus(int flag) + { + if ((_flags.mfocus == flag) || !_flags.takes_focus) return; + _flags.mfocus = flag; + refresh(); + } + + /** + * Define/request parent of an element + */ + void parent(Parent_element *parent) { _parent = parent; } + Parent_element *parent() { return _parent; } + + bool has_parent(Parent_element const *parent) const { return parent == _parent; } + + /** + * Define event handler object + */ + void event_handler(Event_handler *evh) { _evh = evh; } + + /** + * Check if element is completely clipped and draw it otherwise + */ + void try_draw(Canvas_base &canvas, Point abs_position) + { + Rect const abs_rect = Rect(abs_position + _position, _size); + + /* check if element is completely outside the clipping area */ + if (!Rect::intersect(canvas.clip(), abs_rect).valid()) + return; + + /* call actual drawing function */ + draw(canvas, abs_position); + } + + /** + * Format element and all child elements to specified width + */ + virtual void format_fixed_width(int w) { } + + /** + * Format element and all child elements to specified width and height + */ + virtual void format_fixed_size(Area size) { } + + /** + * Draw function + * + * This function must not be called directly. + * Instead, the function try_draw should be called. + */ + virtual void draw(Canvas_base &, Point) { } + + /** + * Find top-most element at specified position + * + * The default implementation can be used for elements without + * children. It just the element position and size against the + * specified position. + */ + virtual Element *find(Point); + + /** + * Find the back-most element at specified y position + * + * This function is used to query a document element at + * the current scroll position of the window. This way, + * we can adjust the y position to the right value + * when we browse the history. + */ + virtual Element *find_by_y(int y); + + /** + * Request absolute position of an element + */ + Point abs_position() const; + + /** + * Update area of an element on screen + * + * We propagate the redraw request through the element hierarchy to + * the parent. The root parent should overwrite this function with + * a function that performs the actual redraw. + */ + virtual void redraw_area(int x, int y, int w, int h); + + /** + * Trigger the refresh of an element on screen + */ + void refresh() { redraw_area(0, 0, _size.w(), _size.h()); } + + /** + * Handle user input or timer event + */ + void handle_event(Event &ev) { if (_evh) _evh->handle(ev); } + + /** + * Request the chapter in which the element lives + */ + Element *chapter(); + + /** + * Fill image cache for element + */ + virtual void fill_cache(Canvas_base &) { } + + /** + * Flush image cache for element + */ + virtual void flush_cache(Canvas_base &) { } + + /** + * Execute function for each sibling including the element itself + * + * The functor FUNC takes a reference to the element as argument. + * + * This function template is implemented in 'scout/parent_element.h'. + */ + template + inline void for_each_sibling(FUNC func); +}; + +#endif /* _INCLUDE__SCOUT__ELEMENT_H_ */ diff --git a/demo/src/app/scout/include/event.h b/demo/include/scout/event.h similarity index 63% rename from demo/src/app/scout/include/event.h rename to demo/include/scout/event.h index 9e7230282..b94fc0fe5 100644 --- a/demo/src/app/scout/include/event.h +++ b/demo/include/scout/event.h @@ -11,16 +11,23 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _EVENT_H_ -#define _EVENT_H_ +#ifndef _INCLUDE__SCOUT__EVENT_H_ +#define _INCLUDE__SCOUT__EVENT_H_ + +#include + +namespace Scout { + class Event; + class Event_handler; +} + /** * Event structure * - * This event structure covers timer events as - * well as user input events. + * This event structure covers timer events as well as user input events. */ -class Event +class Scout::Event { public: @@ -39,34 +46,28 @@ class Event RELEASE = 3, /* button/key released */ TIMER = 4, /* timer event */ QUIT = 5, /* quit application */ - REFRESH = 6, /* refresh screen */ - WHEEL = 7, /* mouse wheel */ + WHEEL = 6, /* mouse wheel */ }; - ev_type type; - int mx, my; /* mouse position */ - int wx, wy; /* wheel */ - int code; /* key code */ + ev_type type; + Point mouse_position; + Point wheel_movement; + int code; /* key code */ /** * Assign new event information to event structure */ inline void assign(ev_type new_type, int new_mx, int new_my, int new_code) { - type = new_type; - mx = new_mx; - my = new_my; - wx = 0; - wy = 0; - code = new_code; + type = new_type; + mouse_position = Point(new_mx, new_my); + wheel_movement = Point(0, 0); + code = new_code; } }; -/** - * Event handler - */ -class Event_handler +class Scout::Event_handler { public: @@ -78,5 +79,4 @@ class Event_handler virtual void handle(Event &e) = 0; }; - -#endif /* _EVENT_H_ */ +#endif /* _INCLUDE__SCOUT__EVENT_H_ */ diff --git a/demo/src/app/scout/include/fader.h b/demo/include/scout/fader.h similarity index 84% rename from demo/src/app/scout/include/fader.h rename to demo/include/scout/fader.h index 207f5d3cd..00d9c0c0a 100644 --- a/demo/src/app/scout/include/fader.h +++ b/demo/include/scout/fader.h @@ -11,16 +11,19 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _FADER_H_ -#define _FADER_H_ +#ifndef _INCLUDE__SCOUT__FADER_H_ +#define _INCLUDE__SCOUT__FADER_H_ + +#include +#include + +namespace Scout { class Fader; } -#include "miscmath.h" -#include "tick.h" /** * Class that manages the fading of a derived class. */ -class Fader : public Tick +class Scout::Fader : public Tick { protected: @@ -75,4 +78,4 @@ class Fader : public Tick }; -#endif /* _FADER_H_ */ +#endif /* _INCLUDE__SCOUT__FADER_H_ */ diff --git a/demo/include/scout/graphics_backend.h b/demo/include/scout/graphics_backend.h new file mode 100644 index 000000000..6faedc2a4 --- /dev/null +++ b/demo/include/scout/graphics_backend.h @@ -0,0 +1,51 @@ +/* + * \brief Graphics backend interface + * \date 2013-12-30 + * \author Norman Feske + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__GRAPHICS_BACKEND_H_ +#define _INCLUDE__SCOUT__GRAPHICS_BACKEND_H_ + +#include +#include + +namespace Scout { struct Graphics_backend; } + + +/* + * We use two buffers, a foreground buffer that is displayed on screen and a + * back buffer. While the foreground buffer must contain valid data all the + * time, the back buffer can be used to prepare pixel data. For example, + * drawing multiple pixel layers with alpha channel must be done in the back + * buffer to avoid artifacts on the screen. + */ +struct Scout::Graphics_backend +{ + virtual Canvas_base &front() = 0; + + virtual Canvas_base &back() = 0; + + virtual void copy_back_to_front(Rect rect) = 0; + + virtual void swap_back_and_front() = 0; + + /* + * XXX todo mode-change notification + */ + + virtual void position(Point p) = 0; + + virtual void bring_to_front() = 0; + + virtual void view_area(Area area) = 0; +}; + +#endif /* _INCLUDE__SCOUT__GRAPHICS_BACKEND_H_ */ diff --git a/demo/include/scout/misc_math.h b/demo/include/scout/misc_math.h new file mode 100644 index 000000000..1f7b725ad --- /dev/null +++ b/demo/include/scout/misc_math.h @@ -0,0 +1,24 @@ +/* + * \brief Misc math functions used here and there + * \date 2005-10-24 + * \author Norman Feske + */ + +/* + * Copyright (C) 2005-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__MISC_MATH_H_ +#define _INCLUDE__SCOUT__MISC_MATH_H_ + +#include + +namespace Scout { + using Genode::min; + using Genode::max; +} + +#endif /* _INCLUDE__SCOUT__MISC_MATH_H_ */ diff --git a/demo/include/scout/nitpicker_graphics_backend.h b/demo/include/scout/nitpicker_graphics_backend.h new file mode 100644 index 000000000..0964aa583 --- /dev/null +++ b/demo/include/scout/nitpicker_graphics_backend.h @@ -0,0 +1,158 @@ +/* + * \brief Nitpicker-based graphics backend for scout + * \date 2013-12-30 + * \author Norman Feske + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__NITPICKER_GRAPHICS_BACKEND_H_ +#define _INCLUDE__SCOUT__NITPICKER_GRAPHICS_BACKEND_H_ + +/* Genode includes */ +#include +#include +#include + +/* Scout includes */ +#include + + +namespace Scout { + using Genode::Pixel_rgb565; + class Nitpicker_graphics_backend; +} + + +class Scout::Nitpicker_graphics_backend : public Graphics_backend +{ + private: + + Nitpicker::Connection &_nitpicker; + + Genode::Dataspace_capability _init_fb_ds(Area max_size) + { + _nitpicker.buffer(Framebuffer::Mode(max_size.w(), max_size.h()*2, + Framebuffer::Mode::RGB565), false); + return _nitpicker.framebuffer()->dataspace(); + } + + Area _max_size; + + Genode::Dataspace_capability _fb_ds = { _init_fb_ds(_max_size) }; + + void *_map_fb_ds() + { + return Genode::env()->rm_session()->attach(_fb_ds); + } + + void *_fb_local_base = { _map_fb_ds() }; + + Point _position; + Area _view_size; + Nitpicker::View_client _view; + Canvas_base *_canvas[2]; + bool _flip_state = { false }; + + void _update_viewport() + { + _view.viewport(_position.x(), _position.y(), + _view_size.w(), _view_size.h(), + 0, + _flip_state ? -_max_size.h() : 0, + true); + } + + void _refresh_view(Rect rect) + { + int const y_offset = _flip_state ? _max_size.h() : 0; + _nitpicker.framebuffer()->refresh(rect.x1(), rect.y1() + y_offset, + rect.w(), rect.h()); + } + + template + PT *_base(unsigned idx) + { + return (PT *)_fb_local_base + idx*_max_size.count(); + } + + unsigned _front_idx() const { return _flip_state ? 1 : 0; } + unsigned _back_idx() const { return _flip_state ? 0 : 1; } + + public: + + Nitpicker_graphics_backend(Nitpicker::Connection &nitpicker, + Area max_size, Point position, Area view_size) + : + _nitpicker(nitpicker), + _max_size(max_size), + _position(position), + _view_size(view_size), + _view(_nitpicker.create_view()) + { + bring_to_front(); + + typedef Genode::Pixel_rgb565 PT; + static Canvas canvas_0(_base(0), max_size); + static Canvas canvas_1(_base(1), max_size); + + _canvas[0] = &canvas_0; + _canvas[1] = &canvas_1; + } + + + /******************************** + ** Graphics_backend interface ** + ********************************/ + + Canvas_base &front() { return *_canvas[_front_idx()]; } + Canvas_base &back() { return *_canvas[ _back_idx()]; } + + void copy_back_to_front(Rect rect) + { + + typedef Genode::Pixel_rgb565 PT; + + PT const *src = _base( _back_idx()); + PT *dst = _base(_front_idx()); + + unsigned long const offset = rect.y1()*_max_size.w() + rect.x1(); + + src += offset; + dst += offset; + + blit(src, sizeof(PT)*_max_size.w(), + dst, sizeof(PT)*_max_size.w(), sizeof(PT)*rect.w(), rect.h()); + + _refresh_view(rect); + } + + void swap_back_and_front() + { + _flip_state = !_flip_state; + _update_viewport(); + } + + void position(Point p) + { + _position = p; + _update_viewport(); + } + + void bring_to_front() + { + _view.stack(Nitpicker::View_capability(), true, true); + } + + void view_area(Area area) + { + _view_size = area; + } +}; + +#endif /* _INCLUDE__SCOUT__NITPICKER_GRAPHICS_BACKEND_H_ */ diff --git a/demo/include/scout/parent_element.h b/demo/include/scout/parent_element.h new file mode 100644 index 000000000..d2984bee0 --- /dev/null +++ b/demo/include/scout/parent_element.h @@ -0,0 +1,95 @@ +/* + * \brief Scout GUI parent element + * \author Norman Feske + * \date 2006-08-30 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__PARENT_ELEMENT_H_ +#define _INCLUDE__SCOUT__PARENT_ELEMENT_H_ + +#include + +namespace Scout { + class Element; + class Parent_element; +} + +class Scout::Parent_element : public Element +{ + protected: + + Element *_first; + Element *_last; + + /** + * Format child element by a given width an horizontal offset + */ + int _format_children(int x, int w); + + public: + + /** + * Constructor + */ + Parent_element() { _first = _last = 0; } + + /** + * Adopt a child element + */ + void append(Element *e); + + /** + * Release child element from parent element + */ + void remove(Element const *e); + + /** + * Dispose references to the specified element + * + * The element is not necessarily an immediate child but some element + * of the element-subtree. This function gets propagated to the root + * parent (e.g., user state manager), which can reset the mouse focus + * of the focused element vanishes. + */ + virtual void forget(Element const *e); + + /** + * Element interface + */ + void draw(Canvas_base &, Point); + Element *find(Point); + Element *find_by_y(int); + void fill_cache(Canvas_base &); + void flush_cache(Canvas_base &); + void geometry(Rect); + + /** + * Execute function on each child + * + * The functor FUNC takes a reference to the element as argument. + */ + template + void for_each_child(FUNC func) + { + for (Element *e = _first; e; e = e->next) + func(*e); + } +}; + + +template +void Scout::Element::for_each_sibling(FUNC func) +{ + if (parent()) + parent()->for_each_child(func); +} + + +#endif /* _INCLUDE__SCOUT__PARENT_ELEMENT_H_ */ diff --git a/demo/include/scout/platform.h b/demo/include/scout/platform.h new file mode 100644 index 000000000..45c21ca7f --- /dev/null +++ b/demo/include/scout/platform.h @@ -0,0 +1,200 @@ +/* + * \brief Platform abstraction + * \date 2005-10-24 + * \author Norman Feske + * + * This interface specifies the target-platform-specific functions. + */ + +/* + * Copyright (C) 2005-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__PLATFORM_H_ +#define _INCLUDE__SCOUT__PLATFORM_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace Scout { + + typedef Genode::Point<> Point; + typedef Genode::Area<> Area; + typedef Genode::Rect<> Rect; + + class Platform; +} + + +inline void *operator new(Genode::size_t size) +{ + using Genode::env; + void *addr = env()->heap()->alloc(size); + if (!addr) { + PERR("env()->heap() has consumed %zd", env()->heap()->consumed()); + PERR("env()->ram_session()->quota = %zd", env()->ram_session()->quota()); + throw Genode::Allocator::Out_of_memory(); + } + return addr; +} + + +class Scout::Platform +{ + private: + + /***************** + ** Event queue ** + *****************/ + + class Event_queue + { + private: + + static const int queue_size = 1024; + + int _head; + int _tail; + Genode::Semaphore _sem; + Genode::Lock _head_lock; /* synchronize add */ + + Event _queue[queue_size]; + + public: + + /** + * Constructor + */ + Event_queue(): _head(0), _tail(0) + { + Genode::memset(_queue, 0, sizeof(_queue)); + } + + void add(Event ev) + { + Genode::Lock::Guard lock_guard(_head_lock); + + if ((_head + 1)%queue_size != _tail) { + + _queue[_head] = ev; + _head = (_head + 1)%queue_size; + _sem.up(); + } + } + + Event get() + { + _sem.down(); + Event ev = _queue[_tail]; + _tail = (_tail + 1)%queue_size; + return ev; + } + + int pending() const { return _head != _tail; } + + } _event_queue; + + /****************** + ** Timer thread ** + ******************/ + + class Timer_thread : public Genode::Thread<4096> + { + private: + + Timer::Connection _timer; + Input::Session &_input; + Input::Event *_ev_buf = { Genode::env()->rm_session()->attach(_input.dataspace()) }; + Event_queue &_event_queue; + int _mx, _my; + unsigned long _ticks = { 0 }; + + void _import_events() + { + if (_input.is_pending() == false) return; + + for (int i = 0, num = _input.flush(); i < num; i++) + { + Event ev; + Input::Event e = _ev_buf[i]; + + if (e.type() == Input::Event::RELEASE + || e.type() == Input::Event::PRESS) { + _mx = e.ax(); + _my = e.ay(); + ev.assign(e.type() == Input::Event::PRESS ? Event::PRESS : Event::RELEASE, + e.ax(), e.ay(), e.code()); + _event_queue.add(ev); + } + + if (e.type() == Input::Event::MOTION) { + _mx = e.ax(); + _my = e.ay(); + ev.assign(Event::MOTION, e.ax(), e.ay(), e.code()); + _event_queue.add(ev); + } + } + } + + public: + + /** + * Constructor + * + * Start thread immediately on construction. + */ + Timer_thread(Input::Session &input, Event_queue &event_queue) + : Thread("timer"), _input(input), _event_queue(event_queue) + { start(); } + + void entry() + { + while (1) { + Event ev; + ev.assign(Event::TIMER, _mx, _my, 0); + _event_queue.add(ev); + + _import_events(); + + _timer.msleep(10); + _ticks += 10; + } + } + + unsigned long ticks() const { return _ticks; } + } _timer_thread; + + public: + + Platform(Input::Session &input) : _timer_thread(input, _event_queue) { } + + /** + * Get timer ticks in miilliseconds + */ + unsigned long timer_ticks() const { return _timer_thread.ticks(); } + + /** + * Return true if an event is pending + */ + bool event_pending() const { return _event_queue.pending(); } + + /** + * Request event + * + * \param e destination where to store event information. + * + * If there is no event pending, this function blocks + * until there is an event to deliver. + */ + Event get_event() { return _event_queue.get(); } +}; + +#endif /* _INCLUDE__SCOUT__PLATFORM_H_ */ diff --git a/demo/src/app/scout/include/genode/printf.h b/demo/include/scout/printf.h similarity index 52% rename from demo/src/app/scout/include/genode/printf.h rename to demo/include/scout/printf.h index 45a95a79a..d1b15eb62 100644 --- a/demo/src/app/scout/include/genode/printf.h +++ b/demo/include/scout/printf.h @@ -1,5 +1,5 @@ /* - * \brief Printf wrappers for Genode + * \brief Printf wrapper for Genode * \date 2008-07-24 * \author Norman Feske */ @@ -11,20 +11,11 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _GENODE_PRINTF_H_ -#define _GENODE_PRINTF_H_ +#ifndef _INCLUDE__SCOUT__PRINTF_H_ +#define _INCLUDE__SCOUT__PRINTF_H_ #include -inline int printf(const char *format, ...) -{ - va_list list; - va_start(list, format); +namespace Scout { using Genode::printf; } - Genode::vprintf(format, list); - - va_end(list); - return 0; -} - -#endif +#endif /* _INCLUDE__SCOUT__PRINTF_H_ */ diff --git a/demo/include/scout/string.h b/demo/include/scout/string.h new file mode 100644 index 000000000..59bc91655 --- /dev/null +++ b/demo/include/scout/string.h @@ -0,0 +1,25 @@ +/* + * \brief String function wrappers for Genode + * \date 2008-07-24 + * \author Norman Feske + */ + +/* + * Copyright (C) 2008-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__STRING_H_ +#define _INCLUDE__SCOUT__STRING_H_ + +#include + +namespace Scout { + using Genode::strlen; + using Genode::memset; + using Genode::memcpy; +} + +#endif /* _INCLUDE__SCOUT__STRING_H_ */ diff --git a/demo/include/scout/texture_allocator.h b/demo/include/scout/texture_allocator.h new file mode 100644 index 000000000..5c7b75980 --- /dev/null +++ b/demo/include/scout/texture_allocator.h @@ -0,0 +1,42 @@ +/* + * \brief Generic interface of texture allocator + * \date 2013-12-31 + * \author Norman Feske + */ + +/* + * Copyright (C) 2005-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__TEXTURE_ALLOCATOR_H_ +#define _INCLUDE__SCOUT__TEXTURE_ALLOCATOR_H_ + +#include +#include + + +namespace Scout { + struct Texture_allocator; + + using Genode::Texture; + using Genode::Texture_base; + + struct Texture_allocator; +} + + +struct Scout::Texture_allocator +{ + virtual Texture_base *alloc_texture(Area size, bool alpha) = 0; + + virtual void free_texture(Texture_base *) = 0; + + virtual void set_rgba_texture(Texture_base *texture, + unsigned char const *rgba, + unsigned len, int y) = 0; +}; + +#endif /* _INCLUDE__SCOUT__TEXTURE_ALLOCATOR_H_ */ diff --git a/demo/src/app/scout/include/tick.h b/demo/include/scout/tick.h similarity index 90% rename from demo/src/app/scout/include/tick.h rename to demo/include/scout/tick.h index da090cad2..e6d22e07a 100644 --- a/demo/src/app/scout/include/tick.h +++ b/demo/include/scout/tick.h @@ -11,11 +11,13 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _TICK_H_ -#define _TICK_H_ +#ifndef _INCLUDE__SCOUT__TICK_H_ +#define _INCLUDE__SCOUT__TICK_H_ -class Tick; -class Tick +namespace Scout { class Tick; } + + +class Scout::Tick { public: @@ -84,4 +86,4 @@ class Tick }; -#endif /* _TICK_H_ */ +#endif /* _INCLUDE__SCOUT__TICK_H_ */ diff --git a/demo/include/scout/types.h b/demo/include/scout/types.h new file mode 100644 index 000000000..241024755 --- /dev/null +++ b/demo/include/scout/types.h @@ -0,0 +1,25 @@ +/* + * \brief Basic types used by scout widgets + * \date 2013-12-31 + * \author Norman Feske + */ + +/* + * Copyright (C) 2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__TYPES_H_ +#define _INCLUDE__SCOUT__TYPES_H_ + +#include + +namespace Scout { + typedef Genode::Point<> Point; + typedef Genode::Area<> Area; + typedef Genode::Rect<> Rect; +} + +#endif /* _INCLUDE__SCOUT__TYPES_H_ */ diff --git a/demo/src/app/scout/include/user_state.h b/demo/include/scout/user_state.h similarity index 64% rename from demo/src/app/scout/include/user_state.h rename to demo/include/scout/user_state.h index 22fc196f0..5bc2ead9f 100644 --- a/demo/src/app/scout/include/user_state.h +++ b/demo/include/scout/user_state.h @@ -11,25 +11,26 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _USER_STATE_H_ -#define _USER_STATE_H_ +#ifndef _INCLUDE__SCOUT__USER_STATE_H_ +#define _INCLUDE__SCOUT__USER_STATE_H_ -#include "window.h" -#include "elements.h" +#include + +namespace Scout { class User_state; } -class User_state : public Parent_element +class Scout::User_state : public Parent_element { private: + Element *_mfocus; /* element that owns the current mouse focus */ + Element *_active; /* currently activated element */ Window *_window; Element *_root; /* root of element tree */ - Element *_mfocus; /* element that owns the current mouse focus */ - Element *_dst; /* current link destination */ - Element *_active; /* currently activated element */ int _key_cnt; /* number of currently pressed keys */ - int _mx, _my; /* current mouse position */ - int _vx, _vy; /* current view offset */ + + Point _mouse_position; + Point _view_position; /** * Assign new mouse focus element @@ -47,18 +48,6 @@ class User_state : public Parent_element /* notify new mouse focus */ if (_mfocus) _mfocus->mfocus(1); - - /* determine new current link destination */ - Element *old_dst = _dst; - if (_mfocus && _mfocus->is_link()) { - Link_token *l = static_cast(_mfocus); - _dst = l->dst(); - } else - _dst = 0; - - /* nofify element tree about new link destination */ - if (_dst != old_dst) - _root->curr_link_destination(_dst); } public: @@ -67,30 +56,23 @@ class User_state : public Parent_element * Constructor */ User_state(Window *window, Element *root, int vx, int vy) - { - _mfocus = _dst = _active = 0; - _window = window; - _root = root; - _key_cnt = 0; - _vx = vx; - _vy = vy; - } + : + _mfocus(0), _active(0), _window(window), _root(root), + _key_cnt(0), _view_position(Point(vx, vy)) + { } /** * Accessor functions */ - int mx() { return _mx; } - int my() { return _my; } - int vx() { return _vx; } - int vy() { return _vy; } + Point mouse_position() const { return _mouse_position; } + Point view_position() const { return _view_position; } /** * Update the current view offset */ void update_view_offset() { - _vx = _window->view_x(); - _vy = _window->view_y(); + _view_position = Point(_window->view_x(), _window->view_y()); } /** @@ -107,9 +89,9 @@ class User_state : public Parent_element _active->handle_event(ev); /* find element under the mouse cursor */ - _mx = ev.mx; - _my = ev.my; - Element *e = _root->find(_mx, _my); + _mouse_position = ev.mouse_position; + + Element *e = _root->find(_mouse_position); switch (ev.type) { @@ -123,7 +105,7 @@ class User_state : public Parent_element update_view_offset(); - _assign_mfocus(_root->find(ev.mx, ev.my), 1); + _assign_mfocus(_root->find(ev.mouse_position), 1); break; @@ -146,7 +128,7 @@ class User_state : public Parent_element case Event::WHEEL: if (_key_cnt == 0) - _window->ypos(_window->ypos() + 23 * ev.my); + _window->ypos(_window->ypos() + 23 * ev.mouse_position.y()); break; default: @@ -160,12 +142,11 @@ class User_state : public Parent_element ** Parent element ** ********************/ - void forget(Element *e) + void forget(Element const *e) { if (_mfocus == e) _mfocus = 0; - if (_dst == e) _dst = 0; if (_active == e) _active = 0; } }; -#endif /* _USER_STATE_H_ */ +#endif /* _INCLUDE__SCOUT__USER_STATE_H_ */ diff --git a/demo/include/scout/window.h b/demo/include/scout/window.h new file mode 100644 index 000000000..23d49dfdd --- /dev/null +++ b/demo/include/scout/window.h @@ -0,0 +1,297 @@ +/* + * \brief Window interface + * \author Norman Feske + * \date 2006-08-30 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT__WINDOW_H_ +#define _INCLUDE__SCOUT__WINDOW_H_ + +#include +#include +#include +#include + +namespace Scout { + class Window; + class Drag_event_handler; + class Sizer_event_handler; + class Mover_event_handler; +} + + +class Scout::Window : public Parent_element +{ + private: + + Graphics_backend &_gfx_backend; + Rect _dirty; + Area _max_size; + Point _view_position; + int _request_cnt; /* nb of requests since last process */ + bool const _scout_quirk; /* enable redraw quirk for scout */ + + public: + + Window(Graphics_backend &gfx_backend, Point position, Area size, + Area max_size, bool scout_quirk) + : + _gfx_backend(gfx_backend), _max_size(max_size), _request_cnt(0), + _scout_quirk(scout_quirk) + { + /* init element attributes */ + _view_position = position; + _size = size; + } + + virtual ~Window() { } + + /** + * Return current window position + */ + int view_x() const { return _view_position.x(); } + int view_y() const { return _view_position.y(); } + int view_w() const { return _size.w(); } + int view_h() const { return _size.h(); } + + Area max_size() const { return _max_size; } + + /** + * Bring window to front + */ + virtual void top() { _gfx_backend.bring_to_front(); } + + /** + * Move window to new position + */ + virtual void vpos(int x, int y) + { + _view_position = Point(x, y); + _gfx_backend.position(_view_position); + } + + /** + * Define vertical scroll offset + */ + virtual void ypos(int ypos) { } + virtual int ypos() { return 0; } + + /** + * Format window + */ + virtual void format(Area size) + { + _gfx_backend.view_area(size); + } + + /** + * Element interface + * + * This function just collects the specified regions to be redrawn but + * does not perform any immediate drawing operation. The actual drawing + * must be initiated by calling the process_redraw function. + */ + void redraw_area(int x, int y, int w, int h) + { + /* + * Scout redraw quirk + * + * Quick fix to avoid artifacts at the icon bar. The icon bar must + * always be drawn completely because of the interaction of the + * different layers. + */ + if (_scout_quirk && y < 64 + 32) { + h = max(h + y, 64 + 32); + w = _size.w(); + x = 0; + y = 0; + } + + Rect rect(Point(x, y), Area(w, h)); + + /* first request since last process operation */ + if (_request_cnt == 0) { + _dirty = rect; + + /* merge subsequencing requests */ + } else { + _dirty = Rect::compound(_dirty, rect); + } + + _request_cnt++; + } + + /** + * Process redrawing operations + */ + void process_redraw() + { + if (_request_cnt == 0) return; + + /* get actual drawing area (clipped against canvas dimensions) */ + int x1 = max(0, _dirty.x1()); + int y1 = max(0, _dirty.y1()); + int x2 = min((int)_size.w() - 1, _dirty.x2()); + int y2 = min((int)_size.h() - 1, _dirty.y2()); + + if (x1 > x2 || y1 > y2) return; + + Canvas_base &canvas = _gfx_backend.back(); + canvas.clip(Rect(Point(x1, y1), Area(x2 - x1 + 1, y2 - y1 + 1))); + + /* draw into back buffer */ + try_draw(canvas, Point(0, 0)); + + /* + * If we draw the whole area, we can flip the front + * and back buffers instead of copying pixels from the + * back to the front buffer. + */ + + /* detemine if the whole area must be drawn */ + if (x1 == 0 && x2 == (int)_size.w() - 1 + && y1 == 0 && y2 == (int)_size.h() - 1) { + + /* flip back end front buffers */ + _gfx_backend.swap_back_and_front(); + + } else { + _gfx_backend.copy_back_to_front(Rect(Point(x1, y1), + Area(x2 - x1 + 1, y2 - y1 + 1))); + } + + /* reset request state */ + _request_cnt = 0; + } +}; + + +/******************** + ** Event handlers ** + ********************/ + +class Scout::Drag_event_handler : public Event_handler +{ + protected: + + int _key_cnt; /* number of curr. pressed keys */ + Point _current_mouse_position; + Point _old_mouse_position; + + virtual void start_drag() = 0; + virtual void do_drag() = 0; + + public: + + /** + * Constructor + */ + Drag_event_handler() { _key_cnt = 0; } + + /** + * Event handler interface + */ + void handle(Event &ev) + { + if (ev.type == Event::PRESS) _key_cnt++; + if (ev.type == Event::RELEASE) _key_cnt--; + + if (_key_cnt == 0) return; + + /* first click starts dragging */ + if ((ev.type == Event::PRESS) && (_key_cnt == 1)) { + _current_mouse_position = _old_mouse_position = ev.mouse_position; + start_drag(); + } + + /* check if mouse was moved */ + if ((ev.mouse_position.x() == _current_mouse_position.x()) + && (ev.mouse_position.y() == _current_mouse_position.y())) + return; + + /* remember current mouse position */ + _current_mouse_position = ev.mouse_position; + + do_drag(); + } +}; + + +class Scout::Sizer_event_handler : public Drag_event_handler +{ + protected: + + Window *_window; + int _obw, _obh; /* original window size */ + + /** + * Event handler interface + */ + void start_drag() + { + _obw = _window->view_w(); + _obh = _window->view_h(); + } + + void do_drag() + { + /* calculate new window size */ + int nbw = _obw + _current_mouse_position.x() - _old_mouse_position.x(); + int nbh = _obh + _current_mouse_position.y() - _old_mouse_position.y(); + + _window->format(Area(nbw, nbh)); + } + + public: + + /** + * Constructor + */ + Sizer_event_handler(Window *window) + { + _window = window; + } +}; + + +class Scout::Mover_event_handler : public Drag_event_handler +{ + protected: + + Window *_window; + int _obx, _oby; /* original launchpad position */ + + void start_drag() + { + _obx = _window->view_x(); + _oby = _window->view_y(); + _window->top(); + } + + void do_drag() + { + int nbx = _obx + _current_mouse_position.x() - _old_mouse_position.x(); + int nby = _oby + _current_mouse_position.y() - _old_mouse_position.y(); + + _window->vpos(nbx, nby); + } + + public: + + /** + * Constructor + */ + Mover_event_handler(Window *window) + { + _window = window; + } +}; + +#endif /* _INCLUDE__SCOUT__WINDOW_H_ */ diff --git a/demo/include/scout_gfx/horizontal_shadow_painter.h b/demo/include/scout_gfx/horizontal_shadow_painter.h new file mode 100644 index 000000000..1c6179ece --- /dev/null +++ b/demo/include/scout_gfx/horizontal_shadow_painter.h @@ -0,0 +1,77 @@ +/* + * \brief Functor for drawing a horizonatal shadow onto a surface + * \author Norman Feske + * \date 2005-10-24 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT_GFX__HORIZONTAL_SHADOW_PAINTER_H_ +#define _INCLUDE__SCOUT_GFX__HORIZONTAL_SHADOW_PAINTER_H_ + +#include + +struct Horizontal_shadow_painter +{ + typedef Genode::Surface_base::Rect Rect; + + template + static inline void paint(Genode::Surface &surface, Rect rect, + int intensity) + { + PT *addr = surface.addr(); + + if (!addr) return; + + const int cx1 = surface.clip().x1(); + const int cy1 = surface.clip().y1(); + const int cx2 = surface.clip().x2(); + const int cy2 = surface.clip().y2(); + + int x = rect.x1(); + int y = rect.y1(); + int w = rect.w(); + int h = rect.h(); + + int curr_a = intensity; + int step = rect.h() ? (curr_a/rect.h()) : 0; + + if (x < cx1) { + w -= cx1 - x; + x = cx1; + } + + if (y < cy1) { + h -= cy1 - y; + curr_a -= (cy1 - y)*step; + y = cy1; + } + + if (w > cx2 - x + 1) + w = cx2 - x + 1; + + if (h > cy2 - y + 1) + h = cy2 - y + 1; + + addr += surface.size().w()*y + x; + + PT shadow_color(0,0,0); + + for (int j = 0; j < h; j++, addr += surface.size().w()) { + + PT *d = addr; + + for (int i = 0; i < w; i++, d++) + *d = PT::mix(*d, shadow_color, curr_a); + + curr_a -= step; + } + } +}; + +#endif /* _INCLUDE__SCOUT_GFX__HORIZONTAL_SHADOW_PAINTER_H_ */ diff --git a/demo/include/scout_gfx/icon_painter.h b/demo/include/scout_gfx/icon_painter.h new file mode 100644 index 000000000..f64b139d2 --- /dev/null +++ b/demo/include/scout_gfx/icon_painter.h @@ -0,0 +1,270 @@ +/* + * \brief Functor for drawing an icon onto a surface + * \author Norman Feske + * \date 2005-10-24 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT_GFX__ICON_PAINTER_H_ +#define _INCLUDE__SCOUT_GFX__ICON_PAINTER_H_ + +#include + +class Icon_painter +{ + private: + + /* + * An Icon has the following layout: + * + * P1---+--------+----+ + * | cs | hs | cs | top row + * +----P2-------+----+ + * | | | | + * | vs | | vs | mid row + * | | | | + * +----+--------P3---+ + * | cs | hs | cs | low row + * +------------------P4 + * + * cs ... corner slice + * hs ... horizontal slice + * vs ... vertical slice + */ + + + /** + * Copy pixel with alpha + */ + template + static inline void _transfer_pixel(PT const &src, int src_a, int alpha, PT *dst) + { + if (src_a) { + int register a = (src_a * alpha)>>8; + if (a) *dst = PT::mix(*dst, src, a); + } + } + + + /** + * Draw corner slice + */ + template + static void _draw_cslice(PT const *src, unsigned char const *src_a, + unsigned src_pitch, int alpha, PT *dst, + unsigned dst_pitch, int w, int h) + { + for (int j = 0; j < h; j++) { + + PT const *s = src; + unsigned char const *sa = src_a; + PT *d = dst; + + for (int i = 0; i < w; i++, s++, sa++, d++) + _transfer_pixel(*s, *sa, alpha, d); + + src += src_pitch, src_a += src_pitch, dst += dst_pitch; + } + } + + + /** + * Draw horizontal slice + */ + template + static void _draw_hslice(PT const *src, unsigned char const *src_a, + int src_pitch, int alpha, PT *dst, + int dst_pitch, int w, int h) + { + for (int j = 0; j < h; j++) { + + PT s = *src; + int sa = *src_a; + PT *d = dst; + + for (int i = 0; i < w; i++, d++) + _transfer_pixel(s, sa, alpha, d); + + src += src_pitch, src_a += src_pitch, dst += dst_pitch; + } + } + + + /** + * Draw vertical slice + */ + template + static void _draw_vslice(PT const *src, unsigned char const *src_a, + int src_pitch, int alpha, PT *dst, + int dst_pitch, int w, int h) + { + for (int i = 0; i < w; i++) { + + PT s = *src; + int sa = *src_a; + PT *d = dst; + + for (int j = 0; j < h; j++, d += dst_pitch) + _transfer_pixel(s, sa, alpha, d); + + src += 1, src_a += 1, dst += 1; + } + } + + + /** + * Draw center slice + */ + template + static void _draw_center(PT const *src, unsigned char const *src_a, + int src_pitch, int alpha, PT *dst, + int dst_pitch, int w, int h) + { + PT s = *src; + int sa = *src_a; + + for (int j = 0; j < h; j++, dst += dst_pitch) { + + PT *d = dst; + + for (int i = 0; i < w; i++, d++) + _transfer_pixel(s, sa, alpha, d); + } + } + + + /** + * Clip rectangle against clipping region + * + * The out parameters are the resulting x/y offsets and the + * visible width and height. + * + * \return 1 if rectangle intersects with clipping region, + * 0 otherwise + */ + static inline int _clip(int px1, int py1, int px2, int py2, + int cx1, int cy1, int cx2, int cy2, + int *out_x, int *out_y, int *out_w, int *out_h) + { + /* determine intersection of rectangle and clipping region */ + int x1 = Genode::max(px1, cx1); + int y1 = Genode::max(py1, cy1); + int x2 = Genode::min(px2, cx2); + int y2 = Genode::min(py2, cy2); + + *out_w = x2 - x1 + 1; + *out_h = y2 - y1 + 1; + *out_x = x1 - px1; + *out_y = y1 - py1; + + return (*out_w > 0) && (*out_h > 0); + } + + public: + + typedef Genode::Surface_base::Area Area; + typedef Genode::Surface_base::Rect Rect; + + + template + static inline void paint(Genode::Surface &surface, Rect rect, + Genode::Texture const &icon, unsigned alpha) + { + PT *addr = surface.addr(); + + if (!addr || (alpha == 0)) return; + + int const cx1 = surface.clip().x1(); + int const cy1 = surface.clip().y1(); + int const cx2 = surface.clip().x2(); + int const cy2 = surface.clip().y2(); + + unsigned const icon_w = icon.size().w(), + icon_h = icon.size().h(); + + /* determine point positions */ + int const x1 = rect.x1(); + int const y1 = rect.y1(); + int const x4 = x1 + rect.w() - 1; + int const y4 = y1 + rect.h() - 1; + int const x2 = x1 + icon_w/2; + int const y2 = y1 + icon_h/2; + int const x3 = Genode::max(x4 - (int)icon_w/2, x2); + int const y3 = Genode::max(y4 - (int)icon_h/2, y2); + + int const tx1 = 0; + int const ty1 = 0; + int const tx4 = icon_w - 1; + int const ty4 = icon_h - 1; + int const tx2 = icon_w/2; + int const ty2 = icon_h/2; + int const tx3 = Genode::max(tx4 - (int)icon_w/2, tx2); + int const ty3 = Genode::max(ty4 - (int)icon_h/2, ty2); + + PT const *src = icon.pixel() + icon_w*ty1; + unsigned char const *src_a = icon.alpha() + icon_w*ty1; + int dx, dy, w, h; + + /* + * top row + */ + + if (_clip(x1, y1, x2 - 1, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_cslice(src + tx1 + dy*icon_w + dx, src_a + tx1 + dy*icon_w + dx, icon_w, alpha, + addr + (y1 + dy)*surface.size().w() + x1 + dx, surface.size().w(), w, h); + + if (_clip(x2, y1, x3 - 1, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_hslice(src + tx2 + dy*icon_w + dx, src_a + tx2 + dy*icon_w + dx, icon_w, alpha, + addr + (y1 + dy)*surface.size().w() + x2 + dx, surface.size().w(), w, h); + + if (_clip(x3, y1, x4, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_cslice(src + tx3 + dy*icon_w + dx, src_a + tx3 + dy*icon_w + dx, icon_w, alpha, + addr + (y1 + dy)*surface.size().w() + x3 + dx, surface.size().w(), w, h); + + /* + * mid row + */ + + src = icon.pixel() + icon_w*ty2; + src_a = icon.alpha() + icon_w*ty2; + + if (_clip(x1, y2, x2 - 1, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_vslice(src + tx1 + dx, src_a + tx1 + dx, icon_w, alpha, + addr + (y2 + dy)*surface.size().w() + x1 + dx, surface.size().w(), w, h); + + if (_clip(x2, y2, x3 - 1, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_center(src + tx2, src_a + tx2, icon_w, alpha, + addr + (y2 + dy)*surface.size().w() + x2 + dx, surface.size().w(), w, h); + + if (_clip(x3, y2, x4, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_vslice(src + tx3 + dx, src_a + tx3 + dx, icon_w, alpha, + addr + (y2 + dy)*surface.size().w() + x3 + dx, surface.size().w(), w, h); + + /* + * low row + */ + + src = icon.pixel() + icon_w*ty3; + src_a = icon.alpha() + icon_w*ty3; + + if (_clip(x1, y3, x2 - 1, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_cslice(src + tx1 + dy*icon_w + dx, src_a + tx1 + dy*icon_w + dx, icon_w, alpha, + addr + (y3 + dy)*surface.size().w() + x1 + dx, surface.size().w(), w, h); + + if (_clip(x2, y3, x3 - 1, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_hslice(src + tx2 + dy*icon_w + dx, src_a + tx2 + dy*icon_w + dx, icon_w, alpha, + addr + (y3 + dy)*surface.size().w() + x2 + dx, surface.size().w(), w, h); + + if (_clip(x3, y3, x4, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) + _draw_cslice(src + tx3 + dy*icon_w + dx, src_a + tx3 + dy*icon_w + dx, icon_w, alpha, + addr + (y3 + dy)*surface.size().w() + x3 + dx, surface.size().w(), w, h); + } +}; + +#endif /* _INCLUDE__SCOUT_GFX__ICON_PAINTER_H_ */ diff --git a/demo/include/scout_gfx/random.h b/demo/include/scout_gfx/random.h new file mode 100644 index 000000000..389435e1f --- /dev/null +++ b/demo/include/scout_gfx/random.h @@ -0,0 +1,31 @@ +/* + * \brief Pseudo random-number generator + * \date 2005-10-24 + * \author Norman Feske + */ + +/* + * Copyright (C) 2005-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT_GFX__RANDOM_H_ +#define _INCLUDE__SCOUT_GFX__RANDOM_H_ + +namespace Scout { + + /** + * Produce pseudo random values + */ + static inline int random() + { + static unsigned int seed = 93186752; + const unsigned int a = 1588635695, q = 2, r = 1117695901; + seed = a*(seed % q) - r*(seed / q); + return seed; + } +} + +#endif /* _INCLUDE__SCOUT_GFX__RANDOM_H_ */ diff --git a/demo/include/scout_gfx/refracted_icon_painter.h b/demo/include/scout_gfx/refracted_icon_painter.h new file mode 100644 index 000000000..3a332d83a --- /dev/null +++ b/demo/include/scout_gfx/refracted_icon_painter.h @@ -0,0 +1,170 @@ +/* + * \brief Functor for drawing a refracted icon onto a surface + * \author Norman Feske + * \date 2005-10-24 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT_GFX__REFRACTED_ICON_PAINTER_H_ +#define _INCLUDE__SCOUT_GFX__REFRACTED_ICON_PAINTER_H_ + +#include +#include +#include + +namespace Scout { struct Refracted_icon_painter; } + +/* + * NOTE: There is no support for clipping. + * Use this code with caution! + */ +struct Scout::Refracted_icon_painter +{ + typedef Genode::Surface_base::Point Point; + typedef Genode::Surface_base::Area Area; + typedef Genode::Surface_base::Rect Rect; + + + template + class Distmap + { + private: + + Area _size; + DT const *_base; + + public: + + Distmap(DT *base, Area size) : _size(size), _base(base) { } + + Area size() const { return _size; } + DT const *base() const { return _base; } + }; + + + /** + * Copy and distort back-buffer pixels to front buffer + */ + template + static void distort(PT const *src, DT const *distmap, + int distmap_w, int distmap_h, + PT const *fg, unsigned char const *alpha, + PT *dst, int dst_w, int width) + { + int line_offset = (distmap_w>>1) - width; + width <<= 1; + + for (int j = 0; j < distmap_h; j += 2, dst += dst_w) { + + PT *d = dst; + + for (int i = 0; i < width; i += 2, src += 2, distmap += 2) { + + /* fetch distorted pixel from back buffer */ + PT v = PT::avr(src[distmap[0]], + src[distmap[1] + 1], + src[distmap[distmap_w] + distmap_w], + src[distmap[distmap_w + 1] + distmap_w + 1]); + + /* mix back-buffer pixel with foreground */ + *d++ = PT::mix(v, *fg++, *alpha++); + } + + fg += line_offset; + alpha += line_offset; + src += line_offset*2 + distmap_w; /* skip one line in back buffer */ + distmap += line_offset*2 + distmap_w; /* skip one line in distmap */ + } + } + + + /** + * Copy back-buffer pixels to front buffer + */ + template + static void copy(PT const *src, int src_w, PT *dst, int dst_w, int w, int h) + { + for (int j = 0; j < h; j ++, src += src_w, dst += dst_w) + Genode::memcpy(dst, src, w*sizeof(PT)); + } + + + /** + * Backup original (background) pixel data into back buffer + */ + template + static void filter_src_to_backbuf(PT const *src, int src_w, + PT *dst, int dst_w, int dst_h, int width) + { + for (int j = 0; j < (dst_h>>1); j++, src += src_w, dst += 2*dst_w) { + for (int i = 0; i < width; i++) { + dst[2*i] = src[i]; + dst[2*i + 1] = PT::avr(src[i], src[i + 1]); + dst[2*i + dst_w] = PT::avr(src[i], src[i + src_w]); + dst[2*i + dst_w + 1] = PT::avr(dst[2*i + dst_w], dst[2*i + 1]); + } + } + } + + + /** + * Backup original (background) pixel data into back buffer + */ + template + static void copy_src_to_backbuf(PT *src, int src_w, + PT *dst, int dst_w, int dst_h, int width) + { + for (int j = 0; j < (dst_h>>1); j++, src += src_w, dst += 2*dst_w) + for (int i = 0; i < width; i++) + dst[2*i] = dst[2*i + 1] = dst[2*i + dst_w] = dst[2*i + dst_w + 1] = src[i]; + } + + + /* + * The distmap and tmp textures must be dimensioned with twice the height + * and width of the foreground. + */ + template + static inline void paint(Genode::Surface &surface, + Point pos, + Distmap
const &distmap, + Genode::Texture &tmp, + Genode::Texture const &foreground, + bool detail, + bool filter_backbuf) + { + PT *dst = surface.addr() + surface.size().w()*(pos.y()) + pos.x(); + + Rect const clipped = Rect::intersect(surface.clip(), Rect(pos, foreground.size())); + + if (detail == false) { + copy(foreground.pixel(), foreground.size().w(), + dst, surface.size().w(), clipped.w(), foreground.size().h()); + return; + } + + /* backup old canvas pixels */ + if (filter_backbuf) + filter_src_to_backbuf(dst, surface.size().w(), tmp.pixel(), + tmp.size().w(), tmp.size().h(), + foreground.size().w()); + else + copy_src_to_backbuf(dst, surface.size().w(), + tmp.pixel(), tmp.size().w(), + tmp.size().h(), foreground.size().w()); + + /* draw distorted pixels back to canvas */ + distort(tmp.pixel(), + distmap.base(), distmap.size().w(), distmap.size().h(), + foreground.pixel(), foreground.alpha(), + dst, surface.size().w(), clipped.w()); + } +}; + +#endif /* _INCLUDE__SCOUT_GFX__REFRACTED_ICON_PAINTER_H_ */ diff --git a/demo/include/scout_gfx/sky_texture_painter.h b/demo/include/scout_gfx/sky_texture_painter.h new file mode 100644 index 000000000..0a6f4acf7 --- /dev/null +++ b/demo/include/scout_gfx/sky_texture_painter.h @@ -0,0 +1,264 @@ +/* + * \brief Functor for drawing a sky texture into a surface + * \author Norman Feske + * \date 2005-10-24 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__SCOUT_GFX__SKY_TEXTURE_PAINTER_H_ +#define _INCLUDE__SCOUT_GFX__SKY_TEXTURE_PAINTER_H_ + +#include +#include + + +struct Sky_texture_painter +{ + typedef Genode::Surface_base::Area Area; + typedef Genode::Surface_base::Rect Rect; + typedef Genode::Color Color; + + + template + static void _compose(PT *dst, int dst_w, int dst_h, int x_start, int x_end, + short const src1[], int src1_y, + short const src2[], int src2_y, + short const src3[], int src3_y, int src_w, int src_h, + PT const coltab[]) + { + for (int k = 0; k <= x_end; k += src_w) { + + int x_offset = Genode::max(0, x_start - k); + int x_max = Genode::min(x_end - k, src_w - 1); + + for (int j = 0; j < dst_h; j++) { + + short const *s1 = src1 + x_offset + ((src1_y + j)%src_h)*src_w; + short const *s2 = src2 + x_offset + ((src2_y + j)%src_h)*src_w; + short const *s3 = src3 + x_offset + ((src3_y + j)%src_h)*src_w; + PT *d = dst + x_offset + j*dst_w + k; + + for (int i = x_offset; i <= x_max; i++) + *d++ = coltab[*s1++ + *s2++ + *s3++]; + } + } + } + + + class Sky_texture_base + { + protected: + + static void _brew_texture(short tmp[], short tmp2[], short dst[], int w, int h, + int lf_start, int lf_end, int lf_incr, int lf_mul, + int hf_val, int hf_mul); + + /** + * Multiply buffer values with 24:8 fixpoint value + */ + static void _multiply_buf(short dst[], int len, int factor) + { + for (int i = 0; i < len; i++) + dst[i] = (dst[i]*factor)>>8; + } + + static inline int _mix_channel(int value1, int value2, int alpha) + { + return (value1*(255 - alpha) + value2*alpha)>>8; + } + }; + + + template + class Sky_texture : public Sky_texture_base + { + private: + + Area _size; + + public: + + Sky_texture(Area size) : _size(size) { } + + virtual PT const *fallback() const = 0; + virtual short const *buf(unsigned i) const = 0; + virtual PT const *coltab() const = 0; + + Area size() const { return _size; } + }; + + + /* + * The texture is composed of four generated 4-bit maps based on bicubic + * interpolation of some noise at different frequencies. At runtime, we + * overlay (add their values) the generated map and use the result as index + * of a color table. + */ + template + class Static_sky_texture : public Sky_texture + { + private: + + short _bufs[3][TH][TW]; + short _buf[TH][TW]; + short _tmp[TH][TW]; + PT _coltab[16*16*16]; + PT _fallback[TH][TW]; /* fallback texture */ + + using Sky_texture::_mix_channel; + using Sky_texture::_brew_texture; + using Sky_texture::_multiply_buf; + + public: + + /** + * Create 3D color table + */ + static void _create_coltab(PT *dst, Color c0, Color c1, Color c2, Color bg) + { + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j++) + for (int k = 0; k < 16; k++) { + + int r = bg.r; + int g = bg.g; + int b = bg.b; + + r = _mix_channel(r, c2.r, k*16); + g = _mix_channel(g, c2.g, k*16); + b = _mix_channel(b, c2.b, k*16); + + r = _mix_channel(r, c1.r, j*16); + g = _mix_channel(g, c1.g, j*16); + b = _mix_channel(b, c1.b, j*16); + + r = _mix_channel(r, c0.r, i*8); + g = _mix_channel(g, c0.g, i*8); + b = _mix_channel(b, c0.b, i*8); + + int v = (((i ^ j ^ k)<<1) & 0xff) + 128 + 64; + + r = (r + v)>>1; + g = (g + v)>>1; + b = (b + v)>>1; + + v = 180; + r = (v*r + (255 - v)*255)>>8; + g = (v*g + (255 - v)*255)>>8; + b = (v*b + (255 - v)*255)>>8; + + dst[(k<<8) + (j<<4) + i].rgba(r, g, b); + } + } + + + + /** + * Constructor + */ + Static_sky_texture() + : + Sky_texture(Area(TW, TH)) + { + /* create nice-looking textures */ + _brew_texture(_tmp[0], _buf[0], _bufs[0][0], TW, TH, 3, 7, 1, 30, 30, 10); + _brew_texture(_tmp[0], _buf[0], _bufs[1][0], TW, TH, 3, 16, 3, 50, 40, 30); + _brew_texture(_tmp[0], _buf[0], _bufs[2][0], TW, TH, 5, 40, 11, 70, 0, 0); + + /* shift texture 1 to bits 4 to 7 */ + _multiply_buf(_bufs[1][0], TW*TH, 16*256); + + /* shift texture 2 to bits 8 to 11 */ + _multiply_buf(_bufs[2][0], TW*TH, 16*16*256); + + /* create color table */ + _create_coltab(_coltab, Color(255, 255, 255), + Color( 0, 0, 0), + Color(255, 255, 255), + Color( 80, 88, 112)); + + /* create fallback texture */ + _compose(_fallback[0], TW, TH, 0, TW - 1, + _bufs[0][0], 0, _bufs[1][0], 0, _bufs[2][0], 0, + TW, TH, _coltab); + } + + PT const *fallback() const { return _fallback[0]; } + + short const *buf(unsigned i) const + { + if (i >= 3) + return 0; + + return _bufs[i][0]; + } + + PT const *coltab() const { return _coltab; } + }; + + + template + static void _copy(PT *dst, int dst_w, int dst_h, int x_start, int x_end, + PT const *src, int src_y, int src_w, int src_h) + { + for (int k = 0; k <= x_end; k += src_w) { + + int x_offset = Genode::max(0, x_start - k); + int x_max = Genode::min(x_end - k, src_w - 1); + + for (int j = 0; j < dst_h; j++) { + + PT const *s = src + x_offset + ((src_y + j)%src_h)*src_w; + PT *d = dst + x_offset + j*dst_w + k; + + if (x_max - x_offset >= 0) + Genode::memcpy(d, s, (x_max - x_offset + 1)*sizeof(PT)); + } + } + } + + + template + static inline void paint(Genode::Surface &surface, int py, + Sky_texture_base const &texture_base, + bool detail) + { + PT *addr = surface.addr(); + + if (!addr) return; + + Sky_texture const &texture = static_cast const &>(texture_base); + + int cx1 = surface.clip().x1(); + int cy1 = surface.clip().y1(); + int cx2 = surface.clip().x2(); + int cy2 = surface.clip().y2(); + + int v = -py; + int y0 = cy1 + v; + int y1 = cy1 + (( (5*v)/16)%texture.size().h()); + int y2 = cy1 + (((11*v)/16)%texture.size().h()); + + addr += cy1*surface.size().w(); + + if (detail == false) { + _copy(addr, surface.size().w(), cy2 - cy1 + 1, cx1, cx2, + texture.fallback(), cy1 - py, texture.size().w(), texture.size().h()); + return; + } + + _compose(addr, surface.size().w(), cy2 - cy1 + 1, cx1, cx2, + texture.buf(0), y0, texture.buf(1), y1, texture.buf(2), y2, + texture.size().w(), texture.size().h(), texture.coltab()); + + surface.flush_pixels(surface.clip()); + } +}; + +#endif /* _INCLUDE__SCOUT_GFX__SKY_TEXTURE_PAINTER_H_ */ diff --git a/demo/lib/mk/scout_gfx.mk b/demo/lib/mk/scout_gfx.mk new file mode 100644 index 000000000..14cf3d77b --- /dev/null +++ b/demo/lib/mk/scout_gfx.mk @@ -0,0 +1,3 @@ +SRC_CC = sky_texture_painter.cc + +vpath %.cc $(REP_DIR)/src/lib/scout_gfx diff --git a/demo/lib/mk/scout_widgets.mk b/demo/lib/mk/scout_widgets.mk index 4126d6eea..04191e2fa 100644 --- a/demo/lib/mk/scout_widgets.mk +++ b/demo/lib/mk/scout_widgets.mk @@ -1,23 +1,12 @@ -LIBS = base blit - -SRC_CC = sky_texture.cc startup.cc \ - elements.cc widgets.cc \ - tick.cc scrollbar.cc \ - refracted_icon.cc - -SRC_CC += platform_genode.cc +LIBS = base blit scout_gfx +SRC_CC = tick.cc elements.cc widgets.cc scrollbar.cc SCOUT_DIR = $(REP_DIR)/src/app/scout -INC_DIR += $(SCOUT_DIR)/include \ - $(SCOUT_DIR)/include/genode - -vpath % $(SCOUT_DIR)/data -vpath %.cc $(SCOUT_DIR)/common -vpath startup.cc $(SCOUT_DIR)/genode -vpath launcher.cc $(SCOUT_DIR)/genode -vpath platform_genode.cc $(SCOUT_DIR)/genode +INC_DIR += $(SCOUT_DIR)/include +vpath % $(SCOUT_DIR)/data +vpath %.cc $(SCOUT_DIR) SRC_TFF = vera16.tff \ verai16.tff \ diff --git a/demo/src/app/launchpad/child_entry.h b/demo/src/app/launchpad/child_entry.h index 3cb08893b..27256bf84 100644 --- a/demo/src/app/launchpad/child_entry.h +++ b/demo/src/app/launchpad/child_entry.h @@ -28,7 +28,7 @@ extern unsigned char OPENED_ICON_RGBA[]; extern unsigned char CLOSED_ICON_RGBA[]; -class Kill_event_handler : public Event_handler +class Kill_event_handler : public Scout::Event_handler { private: @@ -43,10 +43,12 @@ class Kill_event_handler : public Event_handler /** * Event handler interface */ - void handle(Event &ev) + void handle(Scout::Event &ev) { static int key_cnt; + using Scout::Event; + if (ev.type == Event::PRESS) key_cnt++; if (ev.type == Event::RELEASE) key_cnt--; @@ -57,7 +59,8 @@ class Kill_event_handler : public Event_handler template -class Child_entry : public Parent_element, public Genode::List >::Element +class Child_entry : public Scout::Parent_element, + public Genode::List >::Element { private: @@ -67,13 +70,13 @@ class Child_entry : public Parent_element, public Genode::List > enum { _PADX = 10 }; /* horizontal padding */ enum { _NAME_LEN = 64 }; /* max length of child name */ - Block _block; + Scout::Block _block; Kbyte_loadbar _loadbar; char _name[_NAME_LEN]; - Fade_icon _kill_icon; - Fade_icon _fold_icon; + Scout::Fade_icon _kill_icon; + Scout::Fade_icon _fold_icon; Kill_event_handler _kill_event_handler; @@ -85,11 +88,11 @@ class Child_entry : public Parent_element, public Genode::List > Child_entry(const char *name, int quota_kb, int max_quota_kb, Launchpad *launchpad, Launchpad_child *launchpad_child) : - _block(Block::RIGHT), _loadbar(0, &label_font), + _block(Scout::Block::RIGHT), _loadbar(0, &Scout::label_font), _kill_event_handler(launchpad, launchpad_child) { Genode::strncpy(_name, name, sizeof(_name)); - _block.append_plaintext(_name, &plain_style); + _block.append_plaintext(_name, &Scout::plain_style); _loadbar.max_value(max_quota_kb); _loadbar.value(quota_kb); @@ -108,7 +111,7 @@ class Child_entry : public Parent_element, public Genode::List > append(&_kill_icon); append(&_fold_icon); - _min_w = _PTW + 100; + _min_size = Scout::Area(_PTW + 100, _min_size.h()); } @@ -124,22 +127,25 @@ class Child_entry : public Parent_element, public Genode::List > void format_fixed_width(int w) { + using namespace Scout; + _block.format_fixed_width(_PTW); - int bh = _block.min_h(); - int iy = max(0, (bh - _loadbar.min_h())/2); + int bh = _block.min_size().h(); + int iy = max(0U, (bh - _loadbar.min_size().h())/2); - _fold_icon.geometry(0, iy, _IW, _IH); - _kill_icon.geometry(w - _IW - 8, iy, _IW, _IH); + _fold_icon.geometry(Rect(Point(0, iy), Area(_IW, _IH))); + _kill_icon.geometry(Rect(Point(w - _IW - 8, iy), Area(_IW, _IH))); - _block.geometry(max(10, _PTW - _block.min_w()), - max(0, (bh - _block.min_h())/2), - min((int)_PTW, _block.min_w()), bh); + _block.geometry(Rect(Point(max(10, _PTW - (int)_block.min_size().w()), + max(0, (bh - (int)_block.min_size().h())/2)), + Area(min((int)_PTW, + (int)_block.min_size().w()), bh))); int lw = w - 2*_PADX - _PTW - _IW; _loadbar.format_fixed_width(lw); - _loadbar.geometry(_PADX + _PTW, iy, lw, 16); - _min_h = bh; - _min_w = w; + _loadbar.geometry(Rect(Point(_PADX + _PTW, iy), Area(lw, 16))); + + _min_size = Scout::Area(w, bh); } }; diff --git a/demo/src/app/launchpad/launch_entry.h b/demo/src/app/launchpad/launch_entry.h index 0408fe17d..8e0ef5f83 100644 --- a/demo/src/app/launchpad/launch_entry.h +++ b/demo/src/app/launchpad/launch_entry.h @@ -18,15 +18,15 @@ #include "launcher_config.h" template -class Launch_entry : public Parent_element, public Loadbar_listener +class Launch_entry : public Scout::Parent_element, public Loadbar_listener { private: - Block _block; - Kbyte_loadbar _loadbar; - Launcher_config _config; - Launcher _launcher; - int _lh; /* launch entry height */ + Scout::Block _block; + Kbyte_loadbar _loadbar; + Scout::Launcher_config _config; + Scout::Launcher _launcher; + int _lh; /* launch entry height */ enum { _PTW = 100 }; /* program text width */ enum { _PADX = 10 }; /* program text width */ @@ -40,16 +40,19 @@ class Launch_entry : public Parent_element, public Loadbar_listener Launch_entry(const char *prg_name, int initial_quota, int max_quota, Launchpad *launchpad, Genode::Dataspace_capability config_ds) - : _block(Block::RIGHT), _loadbar(this, &label_font), _config(config_ds), - _launcher(prg_name, launchpad, 1024 * initial_quota, &_config) + : + _block(Scout::Block::RIGHT), _loadbar(this, &Scout::label_font), + _config(config_ds), + _launcher(prg_name, launchpad, 1024 * initial_quota, &_config) { - _block.append_launchertext(prg_name, &link_style, &_launcher); + _block.append_launchertext(prg_name, &Scout::link_style, &_launcher); _loadbar.max_value(max_quota); _loadbar.value(initial_quota); append(&_loadbar); append(&_block); - _min_w = _PTW + 100; + + _min_size = Scout::Area(_PTW + 100, _min_size.h()); } @@ -59,7 +62,7 @@ class Launch_entry : public Parent_element, public Loadbar_listener void loadbar_changed(int mx) { - int value = _loadbar.value_by_xpos(mx - _loadbar.abs_x()); + int value = _loadbar.value_by_xpos(mx - _loadbar.abs_position().x()); _loadbar.value(value); _loadbar.refresh(); _launcher.quota(1024 * (unsigned long)value); @@ -72,18 +75,20 @@ class Launch_entry : public Parent_element, public Loadbar_listener void format_fixed_width(int w) { + using namespace Scout; + _block.format_fixed_width(_PTW); - _lh = _block.min_h(); - _block.geometry(max(10, _PTW - _block.min_w()), - max(0, (_lh - _block.min_h())/2), - min((int)_PTW, _block.min_w()), _lh); + _lh = _block.min_size().h(); + _block.geometry(Rect(Point(max(10U, _PTW - _block.min_size().w()), + max(0U, (_lh - _block.min_size().h())/2)), + Area(min((unsigned)_PTW, _block.min_size().w()), _lh))); int lw = max(0, w - 2*_PADX - _PTW - _PADR); - int ly = max(0, (_lh - _loadbar.min_h())/2); + int ly = max(0U, (_lh - _loadbar.min_size().h())/2); _loadbar.format_fixed_width(lw); - _loadbar.geometry(_PADX + _PTW, ly, lw, 16); - _min_h = _lh; - _min_w = w; + _loadbar.geometry(Rect(Point(_PADX + _PTW, ly), Area(lw, 16))); + + _min_size = Scout::Area(w, _lh); } }; diff --git a/demo/src/app/launchpad/launcher.cc b/demo/src/app/launchpad/launcher.cc index 15266fd0d..1e31e1089 100644 --- a/demo/src/app/launchpad/launcher.cc +++ b/demo/src/app/launchpad/launcher.cc @@ -15,10 +15,8 @@ #include "elements.h" #include "launcher_config.h" +using namespace Scout; -/************************ - ** Launcher interface ** - ************************/ void Launcher::launch() { diff --git a/demo/src/app/launchpad/launchpad_window.cc b/demo/src/app/launchpad/launchpad_window.cc index 4ed2984af..ed4b25808 100644 --- a/demo/src/app/launchpad/launchpad_window.cc +++ b/demo/src/app/launchpad/launchpad_window.cc @@ -11,10 +11,14 @@ * under the terms of the GNU General Public License version 2. */ -#include "miscmath.h" +#include + #include "launchpad_window.h" #include "styles.h" +using namespace Scout; + + /**************************** ** External graphics data ** ****************************/ @@ -31,13 +35,12 @@ extern unsigned char TITLEBAR_RGBA[]; ********************************/ template -Launchpad_window::Launchpad_window(Platform *pf, - Redraw_manager *redraw, - int max_w, int max_h, +Launchpad_window::Launchpad_window(Graphics_backend &gfx_backend, + Point position, Area size, Area max_size, unsigned long initial_quota) : Launchpad(initial_quota), - Window(pf, redraw, max_w, max_h), + Window(gfx_backend, position, size, max_size, false), _docview(0), _spacer(1, _TH), _info_section("Status", &subsection_font), @@ -55,8 +58,7 @@ Launchpad_window::Launchpad_window(Platform *pf, _titlebar.text("Launchpad"); _titlebar.event_handler(new Mover_event_handler(this)); - _min_w = 200; - _min_h = 200; + _min_size = Scout::Area(200, 200); _status_entry.max_value(initial_quota / 1024); @@ -81,15 +83,15 @@ Launchpad_window::Launchpad_window(Platform *pf, template void Launchpad_window::ypos_sb(int ypos, int update_scrollbar) { - if (ypos < -_docview.h() + _h) - ypos = -_docview.h() + _h; + if (ypos < -(int)(_docview.size().h() + _size.h())) + ypos = -_docview.size().h() + _size.h(); _ypos = ypos <= 0 ? ypos : 0; - _docview.geometry(_docview.x(), _ypos, _docview.w(), _docview.h()); + _docview.geometry(Rect(Point(_docview.position().x(), _ypos), _docview.size())); if (update_scrollbar) - _scrollbar.view(_docview.h(), _h, -_ypos); + _scrollbar.view(_docview.size().h(), _size.h(), -_ypos); refresh(); } @@ -100,54 +102,57 @@ void Launchpad_window::ypos_sb(int ypos, int update_scrollbar) *************************/ template -void Launchpad_window::format(int w, int h) +void Launchpad_window::format(Scout::Area size) { /* limit window size to valid values */ - w = (w < _min_w) ? _min_w : w; - h = (h < _min_h) ? _min_h : h; - w = (w > max_w()) ? max_w() : w; - h = (h > max_h()) ? max_h() : h; + unsigned w = size.w(); + unsigned h = size.h(); + + w = max(w, min_size().w()); + h = max(h, min_size().h()); + w = min(w, max_size().w()); + h = min(h, max_size().h()); /* determine old scrollbar visibility */ - int old_sb_visibility = (_docview.min_h() > _h); + int old_sb_visibility = (_docview.min_size().h() > _size.h()); /* assign new size to window */ - _w = w; - _h = h; + _size = Scout::Area(w, h); /* format document */ - _docview.format_fixed_width(_w); + _docview.format_fixed_width(_size.w()); /* format titlebar */ - _titlebar.format_fixed_width(_w); + _titlebar.format_fixed_width(_size.w()); /* determine new scrollbar visibility */ - int new_sb_visibility = (_docview.min_h() > _h); + int new_sb_visibility = (_docview.min_size().h() > _size.h()); /* reformat docview on change of scrollbar visibility */ if (old_sb_visibility ^ new_sb_visibility) { - _docview.right_pad(new_sb_visibility ? _scrollbar.min_w() : 0); - _docview.format_fixed_width(_w); + _docview.right_pad(new_sb_visibility ? _scrollbar.min_size().w() : 0); + _docview.format_fixed_width(_size.w()); } /* position docview */ - _docview.geometry(0, _ypos, _docview.min_w(), max(_docview.min_h(), _h)); + _docview.geometry(Rect(Point(0, _ypos), + Area(_docview.min_size().w(), + max(_docview.min_size().h(), _size.h())))); /* start at top */ int y = 0; /* position titlebar */ - _titlebar.geometry(y, 0, _w, _TH); + _titlebar.geometry(Rect(Point(y, 0), Area(_size.w(), _TH))); y += _TH; - _scrollbar.geometry(w - _scrollbar.min_w() - _SB_XPAD, y + _SB_YPAD, - _scrollbar.min_w(), h - y - _SB_YPAD*2 - 8); + _scrollbar.geometry(Rect(Point(w - _scrollbar.min_size().w() - _SB_XPAD, y + _SB_YPAD), + Area(_scrollbar.min_size().w(), h - y - _SB_YPAD*2 - 8))); - _sizer.geometry(_w - 32, _h - 32, 32, 32); + _sizer.geometry(Rect(Point(_size.w() - 32, _size.h() - 32), Area(32, 32))); - pf()->view_geometry(pf()->vx(), pf()->vy(), _w, _h); - redraw()->size(_w, _h); + Window::format(_size); ypos(_ypos); refresh(); } @@ -169,5 +174,4 @@ void Launchpad_window::handle_scroll(int view_pos) ypos_sb(-view_pos, 0); } -#include "canvas_rgb565.h" -template class Launchpad_window; +template class Launchpad_window; diff --git a/demo/src/app/launchpad/launchpad_window.h b/demo/src/app/launchpad/launchpad_window.h index b010981cc..b59ee8c41 100644 --- a/demo/src/app/launchpad/launchpad_window.h +++ b/demo/src/app/launchpad/launchpad_window.h @@ -14,13 +14,14 @@ #ifndef _LAUNCHPAD_WINDOW_H_ #define _LAUNCHPAD_WINDOW_H_ +#include +#include + #include "elements.h" #include "widgets.h" #include "sky_texture.h" #include "scrollbar.h" #include "fade_icon.h" -#include "platform.h" -#include "window.h" #include "titlebar.h" #include "launch_entry.h" @@ -32,9 +33,9 @@ #include template -class Launchpad_window : public Scrollbar_listener, +class Launchpad_window : public Scout::Scrollbar_listener, public Launchpad, - public Window + public Scout::Window { private: @@ -50,20 +51,20 @@ class Launchpad_window : public Scrollbar_listener, /** * Widgets */ - Titlebar _titlebar; - Sky_texture _texture; - Fade_icon _sizer; - Scrollbar _scrollbar; - Genode::List > _child_entry_list; - Docview _docview; - Spacer _spacer; - Document _document; + Scout::Titlebar _titlebar; + Scout::Sky_texture _texture; + Scout::Fade_icon _sizer; + Scout::Scrollbar _scrollbar; + Genode::List > _child_entry_list; + Scout::Docview _docview; + Scout::Spacer _spacer; + Scout::Document _document; - Section _info_section; - Section _launch_section; - Section _kiddy_section; + Section _info_section; + Section _launch_section; + Section _kiddy_section; - Status_entry _status_entry; + Status_entry _status_entry; public: @@ -72,9 +73,9 @@ class Launchpad_window : public Scrollbar_listener, * * \param initial_quota maximum value of quota displays */ - Launchpad_window(Platform *pf, - Redraw_manager *redraw, int max_w, int max_h, - unsigned long inital_quota); + Launchpad_window(Scout::Graphics_backend &gfx_backend, + Scout::Point position, Scout::Area size, + Scout::Area max_size, unsigned long inital_quota); /** * Define vertical scroll offset of document @@ -87,22 +88,24 @@ class Launchpad_window : public Scrollbar_listener, /** * Window interface */ - void format(int w, int h); + void format(Scout::Area); void ypos(int ypos) { ypos_sb(ypos, 1); } /** * Element interface */ - void draw(Canvas *c, int x, int y) + void draw(Scout::Canvas_base &canvas, Scout::Point abs_position) { - ::Parent_element::draw(c, x, y); + using namespace Scout; + + Parent_element::draw(canvas, abs_position); /* border */ - Color col(0, 0, 0); - c->draw_box(0, 0, _w, 1, col); - c->draw_box(0, _h - 1, _w, 1, col); - c->draw_box(0, 1, 1, _h - 2, col); - c->draw_box(_w - 1, 1, 1, _h - 2, col); + Color color(0, 0, 0); + canvas.draw_box(0, 0, _size.w(), 1, color); + canvas.draw_box(0, _size.h() - 1, _size.w(), 1, color); + canvas.draw_box(0, 1, 1, _size.h() - 2, color); + canvas.draw_box(_size.w() - 1, 1, 1, _size.h() - 2, color); }; /** @@ -143,7 +146,7 @@ class Launchpad_window : public Scrollbar_listener, this, launchpad_child); _child_entry_list.insert(ce); _kiddy_section.append(ce); - format(_w, _h); + format(_size); refresh(); } @@ -163,7 +166,7 @@ class Launchpad_window : public Scrollbar_listener, _child_entry_list.remove(ce); _kiddy_section.forget(ce); destroy(alloc, ce); - format(_w, _h); + format(_size); refresh(); } }; diff --git a/demo/src/app/launchpad/loadbar.h b/demo/src/app/launchpad/loadbar.h index 00f91480c..ec3c5a4ca 100644 --- a/demo/src/app/launchpad/loadbar.h +++ b/demo/src/app/launchpad/loadbar.h @@ -39,7 +39,7 @@ class Loadbar_listener }; -class Loadbar_event_handler : public Event_handler +class Loadbar_event_handler : public Scout::Event_handler { private: @@ -53,22 +53,23 @@ class Loadbar_event_handler : public Event_handler /** * Event handler interface */ - void handle(Event &ev) + void handle(Scout::Event &ev) { static int key_cnt; + using Scout::Event; if (ev.type == Event::PRESS) key_cnt++; if (ev.type == Event::RELEASE) key_cnt--; if (ev.type == Event::PRESS || ev.type == Event::MOTION) if (_listener && key_cnt > 0) - _listener->loadbar_changed(ev.mx); + _listener->loadbar_changed(ev.mouse_position.x()); } }; template -class Loadbar : public Parent_element +class Loadbar : public Scout::Parent_element { private: @@ -79,8 +80,8 @@ class Loadbar : public Parent_element bool _active; - Fade_icon _cover; - Fade_icon _bar; + Scout::Fade_icon _cover; + Scout::Fade_icon _bar; Loadbar_event_handler _ev_handler; @@ -89,26 +90,31 @@ class Loadbar : public Parent_element const char *_txt; int _txt_w, _txt_h, _txt_len; - Font *_font; + Scout::Font *_font; void _update_bar_geometry(int w) { + using namespace Scout; + int max_w = w - _LW; int bar_w = (_value * max_w) / _max_value; bar_w += _LW; - _bar.geometry(_bar.x(), _bar.y(), bar_w, _LH); + _bar.geometry(Rect(Point(_bar.position().x(), _bar.position().y()), + Area(bar_w, _LH))); } public: - Loadbar(Loadbar_listener *listener = 0, Font *font = 0): + Loadbar(Loadbar_listener *listener = 0, Scout::Font *font = 0): _active(listener ? true : false), _ev_handler(listener), _value(0), _max_value(100), _txt(""), _txt_w(0), _txt_h(0), _txt_len(0), _font(font) { - _min_h = _LH; + using namespace Scout; + + _min_size = Area(_min_size.w(), _LH); _cover.rgba(LOADBAR_RGBA); _cover.alpha(100); _cover.focus_alpha(150); @@ -127,16 +133,16 @@ class Loadbar : public Parent_element int value_by_xpos(int xpos) { xpos -= _LW/2; - int max_w = _w - _LW; - return max(min((_max_value * xpos) / max_w, _max_value), 0); + int max_w = _size.w() - _LW; + return Scout::max(Scout::min((_max_value * xpos) / max_w, _max_value), 0); } int value() { return _value; } void value(int value) { - _value = max(min(value, _max_value), 0); - _update_bar_geometry(_w); + _value = Scout::max(Scout::min(value, _max_value), 0); + _update_bar_geometry(_size.w()); } int max_value() { return _max_value; } @@ -144,16 +150,16 @@ class Loadbar : public Parent_element void max_value(int max_value) { _max_value = max_value; - _update_bar_geometry(_w); + _update_bar_geometry(_size.w()); } void txt(const char *txt) { if (!_font) return; _txt = txt; - _txt_w = _font->str_w(_txt, strlen(_txt)); - _txt_h = _font->str_h(_txt, strlen(_txt)); - _txt_len = strlen(_txt); + _txt_w = _font->str_w(_txt, Scout::strlen(_txt)); + _txt_h = _font->str_h(_txt, Scout::strlen(_txt)); + _txt_len = Scout::strlen(_txt); } /** @@ -161,34 +167,37 @@ class Loadbar : public Parent_element */ void format_fixed_width(int w) { - _cover.geometry(0, 0, w, _LH); + using namespace Scout; + _cover.geometry(Rect(Point(0, 0), Area(w, _LH))); _update_bar_geometry(w); - _min_w = w; + _min_size = Scout::Area(w, _min_size.h()); } - void draw(Canvas *c, int x, int y) + void draw(Scout::Canvas_base &canvas, Scout::Point abs_position) { - Parent_element::draw(c, x, y); + Parent_element::draw(canvas, abs_position); if (!_font) return; - int txt_x = x + _x + max((_w - _txt_w)/2, 8); - int txt_y = y + _y + max((_h - _txt_h)/2, 0) - 1; + using namespace Scout; + + int txt_x = abs_position.x() + _position.x() + max((_size.w() - _txt_w)/2, 8UL); + int txt_y = abs_position.y() + _position.y() + max((_size.h() - _txt_h)/2, 0UL) - 1; /* shrink clipping area to text area (limit too long label) */ - int cx1 = c->clip_x1(), cy1 = c->clip_y1(); - int cx2 = c->clip_x2(), cy2 = c->clip_y2(); - int nx1 = max(cx1, _x + x); - int ny1 = max(cy1, _y + y); - int nx2 = min(cx2, nx1 + _w - 8); - int ny2 = min(cy2, ny1 + _h); - c->clip(nx1, ny1, nx2 - nx1 + 1, ny2 - ny1 + 1); + int cx1 = canvas.clip().x1(), cy1 = canvas.clip().y1(); + int cx2 = canvas.clip().x2(), cy2 = canvas.clip().y2(); + int nx1 = max(cx1, _position.x() + abs_position.x()); + int ny1 = max(cy1, _position.y() + abs_position.y()); + int nx2 = min(cx2, nx1 + (int)_size.w() - 8); + int ny2 = min(cy2, ny1 + (int)_size.h()); + canvas.clip(Rect(Point(nx1, ny1), Area(nx2 - nx1 + 1, ny2 - ny1 + 1))); - c->draw_string(txt_x , txt_y+1, _font, Color(0,0,0,150), _txt, strlen(_txt)); - c->draw_string(txt_x , txt_y, _font, Color(255,255,255,230), _txt, strlen(_txt)); + canvas.draw_string(txt_x , txt_y+1, _font, Color(0,0,0,150), _txt, strlen(_txt)); + canvas.draw_string(txt_x , txt_y, _font, Color(255,255,255,230), _txt, strlen(_txt)); /* reset clipping */ - c->clip(cx1, cy1, cx2 - cx1 + 1, cy2 - cy1 + 1); + canvas.clip(Rect(Point(cx1, cy1), Area(cx2 - cx1 + 1, cy2 - cy1 + 1))); } void mfocus(int flag) @@ -231,7 +240,7 @@ class Kbyte_loadbar : public Loadbar public: - Kbyte_loadbar(Loadbar_listener *listener, Font *font = 0): + Kbyte_loadbar(Loadbar_listener *listener, Scout::Font *font = 0): Loadbar(listener, font) { _label[0] = 0; diff --git a/demo/src/app/launchpad/main.cc b/demo/src/app/launchpad/main.cc index 4968cfd69..74c5e7ae5 100644 --- a/demo/src/app/launchpad/main.cc +++ b/demo/src/app/launchpad/main.cc @@ -11,15 +11,15 @@ * under the terms of the GNU General Public License version 2. */ +#include +#include +#include +#include +#include + #include "config.h" #include "elements.h" -#include "platform.h" -#include "canvas_rgb565.h" -#include "tick.h" -#include "redraw_manager.h" -#include "user_state.h" #include "launchpad_window.h" -#include "printf.h" #include #include @@ -29,21 +29,18 @@ /** * Runtime configuration */ -namespace Config -{ +namespace Scout { namespace Config { int iconbar_detail = 1; int background_detail = 1; int mouse_cursor = 1; int browser_attr = 0; -} - -extern int native_startup(int, char **); +} } /** * Facility to keep the available quota display up-to-date */ -class Avail_quota_update : public Tick +class Avail_quota_update : public Scout::Tick { private: @@ -104,7 +101,7 @@ static void process_config(Launchpad *launchpad) enum { MAX_NAME_LEN = 128 }; char *filename = (char *)env()->heap()->alloc(MAX_NAME_LEN); if (!filename) { - ::printf("Error: Out of memory while processing configuration\n"); + printf("Error: Out of memory while processing configuration\n"); return; } filename_attr.value(filename, MAX_NAME_LEN); @@ -148,13 +145,13 @@ static void process_config(Launchpad *launchpad) launcher_cnt++; } catch (...) { - ::printf("Warning: Launcher entry %d is malformed.\n", + printf("Warning: Launcher entry %d is malformed.\n", launcher_cnt + 1); } else { char buf[32]; node.type_name(buf, sizeof(buf)); - ::printf("Warning: Ignoring unsupported tag <%s>.\n", buf); + printf("Warning: Ignoring unsupported tag <%s>.\n", buf); } } } @@ -175,9 +172,7 @@ static long read_int_attr_from_config(const char *attr, long default_value) */ int main(int argc, char **argv) { - using namespace Genode; - - if (native_startup(argc, argv)) return -1; + using namespace Scout; /* look for dynamic linker */ try { @@ -185,29 +180,26 @@ int main(int argc, char **argv) Genode::Process::dynamic_linker(rom.dataspace()); } catch (...) { } + static Nitpicker::Connection nitpicker; + static Platform pf(*nitpicker.input()); + long initial_x = read_int_attr_from_config("xpos", 550); long initial_y = read_int_attr_from_config("ypos", 150); long initial_w = read_int_attr_from_config("width", 400); long initial_h = read_int_attr_from_config("height", 400); - /* init platform */ - static Platform pf(initial_x, initial_y, initial_w, initial_h, 400); + Area const max_size (530, 620); + Point const initial_position(initial_x, initial_y); + Area const initial_size (initial_w, initial_h); - /* init canvas */ - static Chunky_canvas canvas; - canvas.init(static_cast(pf.buf_adr()), - pf.scr_w()*pf.scr_h()); - canvas.set_size(pf.scr_w(), pf.scr_h()); - canvas.clip(0, 0, pf.scr_w(), pf.scr_h()); - - /* init redraw manager */ - static Redraw_manager redraw(&canvas, &pf, pf.vw(), pf.vh()); + static Nitpicker_graphics_backend + graphics_backend(nitpicker, max_size, initial_position, initial_size); /* create instance of launchpad window */ static Launchpad_window launchpad( - &pf, &redraw, pf.scr_w(), pf.scr_h(), - env()->ram_session()->avail() + graphics_backend, initial_position, initial_size, max_size, + Genode::env()->ram_session()->avail() ); /* request config file from ROM service */ @@ -218,37 +210,28 @@ int main(int argc, char **argv) Avail_quota_update avail_quota_update(&launchpad); /* create user state manager */ - static User_state user_state(&launchpad, &launchpad, pf.vx(), pf.vy()); + static User_state user_state(&launchpad, &launchpad, + initial_position.x(), initial_position.y()); - /* assign launchpad window as root element to redraw manager */ - redraw.root(&launchpad); - - pf.view_geometry(pf.vx(), pf.vy(), pf.vw(), pf.vh()); launchpad.parent(&user_state); - launchpad.format(pf.vw(), pf.vh()); + launchpad.format(initial_size); launchpad.ypos(0); Genode::printf("--- entering main loop ---\n"); /* enter main loop */ - Event ev; unsigned long curr_time, old_time; curr_time = old_time = pf.timer_ticks(); - do { - pf.get_event(&ev); + for (;;) { + Event ev = pf.get_event(); launchpad.gui_lock.lock(); - if (ev.type != Event::WHEEL) { - ev.mx -= user_state.vx(); - ev.my -= user_state.vy(); - } + if (ev.type != Event::WHEEL) + ev.mouse_position = ev.mouse_position - user_state.view_position(); user_state.handle_event(ev); - if (ev.type == Event::REFRESH) - pf.scr_update(0, 0, pf.scr_w(), pf.scr_h()); - if (ev.type == Event::TIMER) Tick::handle(pf.timer_ticks()); @@ -256,12 +239,14 @@ int main(int argc, char **argv) curr_time = pf.timer_ticks(); if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) { old_time = curr_time; - redraw.process(); + launchpad.process_redraw(); } launchpad.gui_lock.unlock(); - } while (ev.type != Event::QUIT); + if (ev.type == Event::QUIT) + break; + } return 0; } diff --git a/demo/src/app/launchpad/section.h b/demo/src/app/launchpad/section.h index a7234dc7f..751acf5d3 100644 --- a/demo/src/app/launchpad/section.h +++ b/demo/src/app/launchpad/section.h @@ -18,29 +18,30 @@ template -class Section : public Parent_element +class Section : public Scout::Parent_element { private: enum { _SH = 8 }; /* shadow height */ enum { _STH = 20 }; /* shadow height */ - Horizontal_shadow _bg; - Horizontal_shadow _shadow; - const char *_txt; - int _txt_w, _txt_h; - int _txt_len; - Font *_font; - int _r_add; + Scout::Horizontal_shadow _bg; + Scout::Horizontal_shadow _shadow; + + char const *_txt; + int _txt_w, _txt_h; + int _txt_len; + Scout::Font *_font; + int _r_add; public: - Section(const char *txt, Font *font) + Section(const char *txt, Scout::Font *font) : _bg(_STH), _shadow(_SH), _txt(txt), _font(font), _r_add(100) { - _txt_w = font->str_w(_txt, strlen(_txt)); - _txt_h = font->str_h(_txt, strlen(_txt)); - _txt_len = strlen(_txt); + _txt_w = font->str_w(_txt, Scout::strlen(_txt)); + _txt_h = font->str_h(_txt, Scout::strlen(_txt)); + _txt_len = Scout::strlen(_txt); append(&_bg); append(&_shadow); } @@ -50,23 +51,34 @@ class Section : public Parent_element */ void format_fixed_width(int w) { - _min_h = _format_children(0, w) + _SH/2; - _min_w = w; + using namespace Scout; - _bg.geometry(_bg.x(), _bg.y(), _bg.w() + _r_add, _bg.h()); - _shadow.geometry(_shadow.x(), _shadow.y(), _shadow.w() + _r_add, _shadow.h()); + _min_size = Area(w, _format_children(0, w) + _SH/2); + + _bg.geometry(Rect(_bg.position(), + Area(_bg.size().w() + _r_add, _bg.size().h()))); + + _shadow.geometry(Rect(_shadow.position(), + Area(_shadow.size().w() + _r_add, + _shadow.size().h()))); } - void draw(Canvas *c, int x, int y) + void draw(Scout::Canvas_base &canvas, Scout::Point abs_position) { - c->draw_box(x + _x, y + _y + 1, _w + _r_add, _txt_h - 1, Color(240,240,240,130)); + using namespace Scout; - int _txt_x = x + _x + max((_w - _txt_w)/2, 8); - int _txt_y = y + _y + max((_STH - _SH - _txt_h)/2, 0) - 1; + canvas.draw_box(abs_position.x() + _position.x(), + abs_position.y() + _position.y() + 1, + _size.w() + _r_add, _txt_h - 1, Color(240,240,240,130)); - Parent_element::draw(c, x, y); - c->draw_string(_txt_x , _txt_y, _font, Color(0,0,0,150), _txt, strlen(_txt)); - c->draw_box(x + _x, y + _y, _w + _r_add, 1, Color(0,0,0,64)); + int _txt_x = abs_position.x() + _position.x() + max((_size.w() - _txt_w)/2, 8UL); + int _txt_y = abs_position.y() + _position.y() + max((_STH - _SH - _txt_h)/2, 0) - 1; + + Parent_element::draw(canvas, abs_position); + + canvas.draw_string(_txt_x , _txt_y, _font, Color(0,0,0,150), _txt, strlen(_txt)); + canvas.draw_box(abs_position.x() + _position.x(), abs_position.y() + _position.y(), + _size.w() + _r_add, 1, Color(0,0,0,64)); } }; diff --git a/demo/src/app/launchpad/status_entry.h b/demo/src/app/launchpad/status_entry.h index 442d1c262..4b2ba56ac 100644 --- a/demo/src/app/launchpad/status_entry.h +++ b/demo/src/app/launchpad/status_entry.h @@ -17,11 +17,11 @@ #include "loadbar.h" template -class Status_entry : public Parent_element +class Status_entry : public Scout::Parent_element { private: - Block _block; + Scout::Block _block; Kbyte_loadbar _loadbar; int _lh; /* launch entry height */ @@ -35,9 +35,9 @@ class Status_entry : public Parent_element * Constructor */ Status_entry(const char *label) - : _block(Block::RIGHT), _loadbar(0, &label_font) + : _block(Scout::Block::RIGHT), _loadbar(0, &Scout::label_font) { - _block.append_plaintext(label, &plain_style); + _block.append_plaintext(label, &Scout::plain_style); _loadbar.max_value(20*1024); _loadbar.value(3*1024); @@ -45,23 +45,25 @@ class Status_entry : public Parent_element append(&_loadbar); append(&_block); - _min_w = _PTW + 100; + _min_size = Scout::Area(_PTW + 100, _min_size.h()); } void format_fixed_width(int w) { + using namespace Scout; + _block.format_fixed_width(_PTW); - _lh = _block.min_h(); - _block.geometry(max(10, _PTW - _block.min_w()), - max(0, (_lh - _block.min_h())/2), - min((int)_PTW, _block.min_w()), _lh); + _lh = _block.min_size().h(); + _block.geometry(Rect(Point(max(10U, _PTW - _block.min_size().w()), + max(0U, (_lh - _block.min_size().h())/2)), + Area(min((unsigned)_PTW, _block.min_size().w()), _lh))); int lw = max(0, w - 2*_PADX - _PTW - _PADR); - int ly = max(0, (_lh - _loadbar.min_h())/2); + int ly = max(0U, (_lh - _loadbar.min_size().h())/2); _loadbar.format_fixed_width(lw); - _loadbar.geometry(_PADX + _PTW, ly, lw, 16); - _min_h = _lh; - _min_w = w; + _loadbar.geometry(Rect(Point(_PADX + _PTW, ly), Area(lw, 16))); + + _min_size = Scout::Area(w, _lh); } void value(int value) { _loadbar.value(value); } diff --git a/demo/src/app/launchpad/target.mk b/demo/src/app/launchpad/target.mk index 0b54bd086..4cecb63cf 100644 --- a/demo/src/app/launchpad/target.mk +++ b/demo/src/app/launchpad/target.mk @@ -6,6 +6,4 @@ SRC_CC = launchpad_window.cc \ SCOUT_DIR = $(REP_DIR)/src/app/scout -INC_DIR = $(PRG_DIR) \ - $(SCOUT_DIR)/include \ - $(SCOUT_DIR)/include/genode +INC_DIR = $(PRG_DIR) $(SCOUT_DIR) diff --git a/demo/src/app/scout/common/about.cc b/demo/src/app/scout/about.cc similarity index 98% rename from demo/src/app/scout/common/about.cc rename to demo/src/app/scout/about.cc index e3ce5f1ab..b1b7cbf53 100644 --- a/demo/src/app/scout/common/about.cc +++ b/demo/src/app/scout/about.cc @@ -14,8 +14,13 @@ #include "elements.h" #include "styles.h" -Document *create_about() +namespace Scout { Document *create_about(); } + + +Scout::Document *Scout::create_about() { + using namespace Scout; + Document *doc = new Document(); doc->title = ""; diff --git a/demo/src/app/scout/include/browser.h b/demo/src/app/scout/browser.h similarity index 94% rename from demo/src/app/scout/include/browser.h rename to demo/src/app/scout/browser.h index 46f297f83..6626d5a68 100644 --- a/demo/src/app/scout/include/browser.h +++ b/demo/src/app/scout/browser.h @@ -17,10 +17,13 @@ #include "elements.h" #include "history.h" +namespace Scout { + extern Document *create_about(); + class Browser; +} -extern Document *create_about(); -class Browser +class Scout::Browser { protected: @@ -74,7 +77,7 @@ class Browser /** * Format browser window */ - virtual void format(int w, int h) { } + virtual void format(Area) { } /** * Travel backward in history @@ -123,10 +126,9 @@ class Browser _content(new_content); ypos(0); - ypos(_ypos - anchor->abs_y() + _voffset); + ypos(_ypos - anchor->abs_position().y() + _voffset); if (new_content) { - new_content->curr_link_destination(0); new_content->refresh(); } } @@ -158,5 +160,4 @@ class Browser int go_about() { go_to(_about); return 1; } }; - #endif /* _BROWSER_H_ */ diff --git a/demo/src/app/scout/common/browser_window.cc b/demo/src/app/scout/browser_window.cc similarity index 77% rename from demo/src/app/scout/common/browser_window.cc rename to demo/src/app/scout/browser_window.cc index 0637fdcfe..5b838aeda 100644 --- a/demo/src/app/scout/common/browser_window.cc +++ b/demo/src/app/scout/browser_window.cc @@ -13,9 +13,13 @@ * under the terms of the GNU General Public License version 2. */ -#include "miscmath.h" +#include +#include + #include "browser_window.h" +using namespace Scout; + /**************************** ** External graphics data ** @@ -109,7 +113,7 @@ static void extract_rgba(const unsigned char *src, int w, int h, ** Event handlers ** ********************/ -class Iconbar_event_handler : public Event_handler +class Iconbar_event_handler : public Scout::Event_handler { private: @@ -185,7 +189,7 @@ class Iconbar_event_handler : public Event_handler template -class Browser_sizer_event_handler : public Sizer_event_handler +class Browser_sizer_event_handler : public Scout::Sizer_event_handler { private: @@ -226,10 +230,12 @@ class Browser_sizer_event_handler : public Sizer_event_handler template Browser_window::Browser_window(Document *initial_content, - Platform *pf, - Redraw_manager *redraw, - int max_w, int max_h, int attr) -: Browser(_IH + _TH), Window(pf, redraw, max_w, max_h) + Graphics_backend &gfx_backend, + Point position, Area size, + Area max_size, int attr) +: + Browser(_IH + _TH), Window(gfx_backend, position, size, max_size, true), + _gfx_backend(gfx_backend) { /* init attributes */ _ypos = 0; @@ -280,6 +286,7 @@ Browser_window::Browser_window(Document *initial_content, /* * NOTE: The panel height must be the same as the icon height. */ + using Scout::random; for (int j = 0; j < _PANEL_H; j++) for (int i = 0; i < _PANEL_W; i++) { _panel_fg [j][i] = _icon_fg [ICON_INDEX][j][i&0x1]; @@ -303,8 +310,7 @@ Browser_window::Browser_window(Document *initial_content, _titlebar.text(_document->title); _titlebar.event_handler(new Mover_event_handler(this)); - _min_w = _NUM_ICONS*_IW; - _min_h = _IH + 250; + _min_size = Scout::Area(_NUM_ICONS*_IW, _IH + 250); /* adopt widgets as child elements */ append(&_docview); @@ -330,15 +336,16 @@ Browser_window::Browser_window(Document *initial_content, template void Browser_window::ypos_sb(int ypos, int update_scrollbar) { - if (ypos < -_docview.h() + _h) - ypos = -_docview.h() + _h; + if (ypos < -(int)_docview.size().h() + (int)_size.h()) + ypos = -(int)_docview.size().h() + (int)_size.h(); _ypos = ypos <= 0 ? ypos : 0; - _docview.geometry(_docview.x(), _ypos, _docview.w(), _docview.h()); + _docview.geometry(Rect(Point(_docview.position().x(), _ypos), + Area(_docview.size().w(), _docview.size().h()))); if (update_scrollbar) - _scrollbar.view(_docview.h(), _h, -_ypos); + _scrollbar.view(_docview.size().h(), _size.h(), -_ypos); refresh(); } @@ -359,80 +366,85 @@ template void Browser_window::_content(Element *content) { if (!content || (content == _docview.content())) return; - content->fill_cache(redraw()->canvas()); + + content->fill_cache(_gfx_backend.front()); _docview.content(content); - format(_w, _h); + format(_size); _ypos = 0; } template -void Browser_window::format(int w, int h) +void Browser_window::format(Area size) { + unsigned w = size.w(); + unsigned h = size.h(); + /* limit browser window size to valid values */ - w = (w < _min_w) ? _min_w : w; - h = (h < _min_h) ? _min_h : h; - w = (w > max_w()) ? max_w() : w; - h = (h > max_h()) ? max_h() : h; + w = max(w, min_size().w()); + h = max(h, min_size().h()); + w = min(w, max_size().w()); + h = min(h, max_size().h()); /* determine old scrollbar visibility */ - int old_sb_visibility = (_docview.min_h() > _h); + int old_sb_visibility = (_docview.min_size().h() > _size.h()); /* assign new size to browser window */ - _w = w; - _h = h; + _size = Scout::Area(w, h); /* format document */ - _docview.format_fixed_width(_w); + _docview.format_fixed_width(_size.w()); /* format titlebar */ - _titlebar.format_fixed_width(_w); + _titlebar.format_fixed_width(_size.w()); /* determine new scrollbar visibility */ - int new_sb_visibility = (_docview.min_h() > _h); + int new_sb_visibility = (_docview.min_size().h() > _size.h()); /* reformat docview on change of scrollbar visibility */ if (old_sb_visibility ^ new_sb_visibility) { - _docview.right_pad(new_sb_visibility ? _scrollbar.min_w() : 0); - _docview.format_fixed_width(_w); + _docview.right_pad(new_sb_visibility ? _scrollbar.min_size().w() : 0); + _docview.format_fixed_width(_size.w()); } /* position docview */ - _docview.geometry(0, _ypos, _docview.min_w(), max(_docview.min_h(), _h)); + _docview.geometry(Rect(Point(0, _ypos), + Area(_docview.min_size().w(), + max(_docview.min_size().h(), _size.h())))); /* start at top */ int y = 0; /* position titlebar */ if (_attr & ATTR_TITLEBAR) { - _titlebar.geometry(y, 0, _w, _TH); + _titlebar.geometry(Rect(Point(y, 0), Area(_size.w(), _TH))); y += _TH; } /* position icons */ for (int i = 0; i <= ICON_INDEX; i++) { - _icon[i].geometry(i*_IW, y, _IW, _IH); - _glow_icon[i].geometry(i*_IW, y, _IW, _IH); + _icon[i].geometry(Rect(Point(i*_IW, y), Area(_IW, _IH))); + _glow_icon[i].geometry(Rect(Point(i*_IW, y), Area(_IW, _IH))); } - _icon[ICON_ABOUT].geometry(_w - _IW, y, _IW, _IH); - _glow_icon[ICON_ABOUT].geometry(_w - _IW, y, _IW, _IH); + _icon[ICON_ABOUT].geometry(Rect(Point(_size.w() - _IW, y), Area(_IW, _IH))); + _glow_icon[ICON_ABOUT].geometry(Rect(Point(_size.w() - _IW, y), Area(_IW, _IH))); /* the panel is the space between the left icon set and the right about icon */ - int panel_x = _icon[ICON_INDEX].x() + _IW; - _panel.geometry(panel_x, y, _icon[ICON_ABOUT].x() - panel_x, _IH); + int panel_x = _icon[ICON_INDEX].position().x() + _IW; + _panel.geometry(Rect(Point(panel_x, y), + Area(_icon[ICON_ABOUT].position().x() - panel_x, _IH))); y += _IH; - _scrollbar.geometry(w - _scrollbar.min_w() - _SB_XPAD, y + _SB_YPAD, - _scrollbar.min_w(), h - y - _SB_YPAD*2 - - (_attr & ATTR_SIZER ? 8 : 0)); - _shadow.geometry(0, y, _w, 10); + _scrollbar.geometry(Rect(Point(w - _scrollbar.min_size().w() - _SB_XPAD, y + _SB_YPAD), + Area(_scrollbar.min_size().w(), + h - y - _SB_YPAD*2 - (_attr & ATTR_SIZER ? 8 : 0)))); + _shadow.geometry(Rect(Point(0, y), Area(_size.w(), 10))); if (_attr & ATTR_SIZER) - _sizer.geometry(_w - 32, _h - 32, 32, 32); + _sizer.geometry(Rect(Point(_size.w() - 32, _size.h() - 32), Area(32, 32))); - pf()->view_geometry(pf()->vx(), pf()->vy(), _w, _h); - redraw()->size(_w, _h); + Window::format(_size); } @@ -456,5 +468,4 @@ void Browser_window::handle_scroll(int view_pos) ypos_sb(-view_pos, 0); } -#include "canvas_rgb565.h" -template class Browser_window; +template class Browser_window; diff --git a/demo/src/app/scout/include/browser_window.h b/demo/src/app/scout/browser_window.h similarity index 79% rename from demo/src/app/scout/include/browser_window.h rename to demo/src/app/scout/browser_window.h index b868c97f3..28194848f 100644 --- a/demo/src/app/scout/include/browser_window.h +++ b/demo/src/app/scout/browser_window.h @@ -14,22 +14,24 @@ #ifndef _BROWSER_WINDOW_H_ #define _BROWSER_WINDOW_H_ +#include +#include + #include "elements.h" #include "widgets.h" #include "sky_texture.h" #include "refracted_icon.h" #include "scrollbar.h" -#include "platform.h" -#include "redraw_manager.h" #include "browser.h" -#include "window.h" #include "titlebar.h" +namespace Scout { template class Browser_window; } + template -class Browser_window : public Scrollbar_listener, - public Browser, - public Window +class Scout::Browser_window : public Scrollbar_listener, + public Browser, + public Window { enum { ICON_HOME = 0, @@ -61,6 +63,11 @@ class Browser_window : public Scrollbar_listener, */ int _attr; /* attribute mask */ + /** + * Remember graphics backend used as texture allocator + */ + Graphics_backend &_gfx_backend; + /** * Widgets */ @@ -102,15 +109,9 @@ class Browser_window : public Scrollbar_listener, /** * Constructor - * - * \param scr_adr base address of screen buffer - * \param scr_w width of screen buffer - * \param scr_h height of screen buffer - * \param doc initial content - * \param w, h initial size of the browser window */ - Browser_window(Document *content, Platform *pf, - Redraw_manager *redraw, int max_w, int max_h, + Browser_window(Document *content, Graphics_backend &gfx_backend, + Point position, Area size, Area max_size, int attr = ATTR_SIZER | ATTR_TITLEBAR); /** @@ -129,7 +130,7 @@ class Browser_window : public Scrollbar_listener, /** * Browser interface */ - void format(int w, int h); + void format(Area); void ypos(int ypos) { ypos_sb(ypos, 1); } Anchor *curr_anchor(); Browser *browser() { return this; } @@ -137,16 +138,16 @@ class Browser_window : public Scrollbar_listener, /** * Element interface */ - void draw(Canvas *c, int x, int y) + void draw(Canvas_base &canvas, Point abs_position) { - ::Parent_element::draw(c, x, y); + Parent_element::draw(canvas, abs_position); if (_attr & ATTR_BORDER) { - Color col(0, 0, 0); - c->draw_box(0, 0, _w, 1, col); - c->draw_box(0, _h - 1, _w, 1, col); - c->draw_box(0, 1, 1, _h - 2, col); - c->draw_box(_w - 1, 1, 1, _h - 2, col); + Color color(0, 0, 0); + canvas.draw_box(0, 0, _size.w(), 1, color); + canvas.draw_box(0, _size.h() - 1, _size.w(), 1, color); + canvas.draw_box(0, 1, 1, _size.h() - 2, color); + canvas.draw_box(_size.w() - 1, 1, 1, _size.h() - 2, color); } }; diff --git a/demo/src/app/scout/common/refracted_icon.cc b/demo/src/app/scout/common/refracted_icon.cc deleted file mode 100644 index bf7df6e34..000000000 --- a/demo/src/app/scout/common/refracted_icon.cc +++ /dev/null @@ -1,184 +0,0 @@ -/* - * \brief Implementation of refracted icons - * \date 2005-10-24 - * \author Norman Feske - * - * A refracted icon is a icon that refracts its background - * using a distortion map. - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#include "config.h" -#include "miscmath.h" -#include "refracted_icon.h" - - -/*************** - ** Utilities ** - ***************/ - -/** - * Backup original (background) pixel data into back buffer - */ -template -static void filter_src_to_backbuf(PT *src, int src_w, - PT *dst, int dst_w, int dst_h, int width) -{ - for (int j = 0; j < (dst_h>>1); j++, src += src_w, dst += 2*dst_w) { - for (int i = 0; i < width; i++) { - dst[2*i] = src[i]; - dst[2*i + 1] = PT::avr(src[i], src[i + 1]); - dst[2*i + dst_w] = PT::avr(src[i], src[i + src_w]); - dst[2*i + dst_w + 1] = PT::avr(dst[2*i + dst_w], dst[2*i + 1]); - } - } -} - - -/** - * Backup original (background) pixel data into back buffer - */ -template -static void copy_src_to_backbuf(PT *src, int src_w, - PT *dst, int dst_w, int dst_h, int width) -{ - for (int j = 0; j < (dst_h>>1); j++, src += src_w, dst += 2*dst_w) - for (int i = 0; i < width; i++) - dst[2*i] = dst[2*i + 1] = dst[2*i + dst_w] = dst[2*i + dst_w + 1] = src[i]; -} - - -/** - * Copy and distort back-buffer pixels to front buffer - */ -template -void distort(PT src[], DT distmap[], int distmap_w, int distmap_h, - PT fg[], unsigned char alpha[], - PT dst[], int dst_w, int width) -{ - int line_offset = (distmap_w>>1) - width; - width <<= 1; - - for (int j = 0; j < distmap_h; j += 2, dst += dst_w) { - - PT *d = dst; - - for (int i = 0; i < width; i += 2, src += 2, distmap += 2) { - - /* fetch distorted pixel from back buffer */ - PT v = PT::avr(src[distmap[0]], - src[distmap[1] + 1], - src[distmap[distmap_w] + distmap_w], - src[distmap[distmap_w + 1] + distmap_w + 1]); - - /* mix back-buffer pixel with foreground */ - *d++ = PT::mix(v, *fg++, *alpha++); - } - - fg += line_offset; - alpha += line_offset; - src += line_offset*2 + distmap_w; /* skip one line in back buffer */ - distmap += line_offset*2 + distmap_w; /* skip one line in distmap */ - } -} - - -/** - * Copy and distort back-buffer pixels to front buffer - */ -template -void copy(PT src[], int src_w, PT dst[], int dst_w, int w, int h) -{ - for (int j = 0; j < h; j ++, src += src_w, dst += dst_w) - memcpy(dst, src, w*sizeof(PT)); -} - - -/****************************** - ** Refracted icon interface ** - ******************************/ - -template -void Refracted_icon::scratch(int jitter) -{ - PT ref_color = _fg[0]; - for (int j = 0; j < _distmap_h; j++) for (int i = 0; i < _distmap_w; i++) { - - int fg_offset = (j>>1)*(_distmap_w>>1) + (i>>1); - - int dr = _fg[fg_offset].r() - ref_color.r(); - int dg = _fg[fg_offset].g() - ref_color.g(); - int db = _fg[fg_offset].b() - ref_color.b(); - - if (dr < 0) dr = -dr; - if (dg < 0) dg = -dg; - if (db < 0) db = -db; - - static const int limit = 20; - if (dr > limit || dg > limit || db > limit) continue; - - int dx, dy; - - do { - dx = jitter ? ((random()%jitter) - (jitter>>1)) : 0; - dy = jitter ? ((random()%jitter) - (jitter>>1)) : 0; - } while ((dx < -i) || (dx > _distmap_w - 2 - i) - || (dy < -j) || (dy > _distmap_h - 2 - j)); - - _distmap[j*_distmap_w + i] += dy*_distmap_w + dx; - } -} - - -/*********************** - ** Element interface ** - ***********************/ - -template -void Refracted_icon::draw(Canvas *c, int x, int y) -{ - PT *addr = static_cast(c->addr()); - - if (!addr || !_backbuf || !_fg || !_fg_alpha) return; - - /* - * NOTE: There is no support for clipping. - * Use this code with caution! - */ - - addr += c->w()*(y + _y) + x + _x; - - int fg_w = _distmap_w>>1; - - for (int i = 0; i < _w; i += fg_w, addr += fg_w) { - - int curr_w = min(fg_w, _w - i); - - if (Config::iconbar_detail == 0) { - copy(_fg, _distmap_w>>1, addr, c->w(), curr_w, _distmap_h>>1); - continue; - } - - /* backup old canvas pixels */ - if (_filter_backbuf) - filter_src_to_backbuf(addr, c->w(), _backbuf, _distmap_w, - _distmap_h, fg_w); - else - copy_src_to_backbuf(addr, c->w(), _backbuf, _distmap_w, - _distmap_h, fg_w); - - /* draw distorted pixels back to canvas */ - distort(_backbuf, _distmap, _distmap_w, _distmap_h, - _fg, _fg_alpha, addr, c->w(), curr_w); - } -} - - -#include "canvas_rgb565.h" -template class Refracted_icon; diff --git a/demo/src/app/scout/common/sky_texture.cc b/demo/src/app/scout/common/sky_texture.cc deleted file mode 100644 index e8e8c980a..000000000 --- a/demo/src/app/scout/common/sky_texture.cc +++ /dev/null @@ -1,363 +0,0 @@ -/* - * \brief Sky texture element for the use as background - * \date 2005-10-24 - * \author Norman Feske - * - * At initialization time, we generate four 4-bit maps based on - * bicubic interpolation of some noise at different frequencies. - * At runtime, we overlay (add their values) the generated map - * and use the result as index of a color table. - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#include "config.h" -#include "miscmath.h" -#include "sky_texture.h" - - -/*********************** - ** Texture generator ** - ***********************/ - -/** - * Calculate fractional part of texture position for a given coordinate - */ -static inline int calc_u(int x, int w, int texture_w) -{ - return ((texture_w*x<<8)/w) & 0xff; -} - - -/** - * Kubic interpolation - * - * \param u relative position between x1 and x2 (0..255) - */ -static inline int filter(int x0, int x1, int x2, int x3, int u) -{ - static int cached_u = -1; - static int k0, k1, k2, k3; - - /* - * Do not recompute coefficients when called - * with the same subsequencing u values. - */ - if (u != cached_u) { - - int v = 255 - u; - int uuu = (u*u*u)>>16; - int vvv = (v*v*v)>>16; - int uu = (u*u)>>8; - int vv = (v*v)>>8; - - k0 = vvv/6; - k3 = uuu/6; - k1 = k3*3 - uu + (4<<8)/6; - k2 = k0*3 - vv + (4<<8)/6; - - cached_u = u; - } - - return (x0*k0 + x1*k1 + x2*k2 + x3*k3)>>8; -} - - -/** - * Determine texture position by given position in image - */ -static inline int get_idx(int x, int w, int texture_w, int offset) -{ - return (offset + texture_w + (texture_w*x)/w) % texture_w; -} - - -/** - * Generate sky texture based on bicubic interpolation of some noise - */ -static void gen_buf(short tmp[], int noise_w, int noise_h, - short dst[], int dst_w, int dst_h) -{ - /* generate noise */ - for (int i = 0; i < noise_h; i++) for (int j = 0; j < noise_w; j++) - dst[i*dst_w + j] = random()%256 - 128; - - /* interpolate horizontally */ - for (int j = dst_w - 1; j >= 0; j--) { - - int x0_idx = get_idx(j, dst_w, noise_w, -1); - int x1_idx = get_idx(j, dst_w, noise_w, 0); - int x2_idx = get_idx(j, dst_w, noise_w, 1); - int x3_idx = get_idx(j, dst_w, noise_w, 2); - int u = calc_u(j, dst_w, noise_w); - - for (int i = 0; i < noise_h; i++) { - - int x0 = dst[i*dst_w + x0_idx]; - int x1 = dst[i*dst_w + x1_idx]; - int x2 = dst[i*dst_w + x2_idx]; - int x3 = dst[i*dst_w + x3_idx]; - - tmp[i*dst_w + j] = filter(x0, x1, x2, x3, u); - } - } - - /* vertical interpolation */ - for (int i = dst_h - 1; i >= 0; i--) { - - int y0_idx = get_idx(i, dst_h, noise_h, -1)*dst_w; - int y1_idx = get_idx(i, dst_h, noise_h, 0)*dst_w; - int y2_idx = get_idx(i, dst_h, noise_h, 1)*dst_w; - int y3_idx = get_idx(i, dst_h, noise_h, 2)*dst_w; - int u = calc_u(i, dst_h, noise_h); - - for (int j = 0; j < dst_w; j++) { - - int y0 = tmp[y0_idx + j]; - int y1 = tmp[y1_idx + j]; - int y2 = tmp[y2_idx + j]; - int y3 = tmp[y3_idx + j]; - - dst[i*dst_w + j] = filter(y0, y1, y2, y3, u); - } - } -} - - -/** - * Normalize buffer values to specified maximum - */ -static void normalize_buf(short dst[], int len, int amp) -{ - int min = 0x7ffffff, max = 0; - - for (int i = 0; i < len; i++) { - if (dst[i] < min) min = dst[i]; - if (dst[i] > max) max = dst[i]; - } - - if (max == min) return; - - for (int i = 0; i < len; i++) - dst[i] = (amp*(dst[i] - min))/(max - min); -} - - -/** - * Multiply buffer values with 24:8 fixpoint value - */ -static void multiply_buf(short dst[], int len, int factor) -{ - for (int i = 0; i < len; i++) - dst[i] = (dst[i]*factor)>>8; -} - - -/** - * Add each pair of values of two buffers - */ -static void add_bufs(short src1[], short src2[], short dst[], int len) -{ - for (int i = 0; i < len; i++) - dst[i] = src1[i] + src2[i]; -} - - -/** - * We combine (add) multiple low-frequency textures with one high-frequency - * texture to get nice shapes. - */ -static void brew_texture(short tmp[], short tmp2[], short dst[], int w, int h, - int lf_start, int lf_end, int lf_incr, int lf_mul, - int hf_val, int hf_mul) -{ - for (int i = lf_start; i < lf_end; i += lf_incr) { - gen_buf(tmp, i, i, tmp2, w, h); - multiply_buf(tmp2, w*h, (lf_mul - i)*32); - add_bufs(tmp2, dst, dst, w*h); - } - if (hf_val) { - gen_buf(tmp, hf_val, hf_val, tmp2, w, h); - multiply_buf(tmp2, w*h, hf_mul*32); - add_bufs(tmp2, dst, dst, w*h); - } - - /* normalize texture to use four bits */ - normalize_buf(dst, w*h, 15); -} - - -/*************************** - ** Color table generator ** - ***************************/ - -static inline int mix_channel(int value1, int value2, int alpha) -{ - return (value1*(255 - alpha) + value2*alpha)>>8; -} - - -/** - * Create 3D color table - */ -template -static void create_coltab(PT *dst, Color c0, Color c1, Color c2, Color bg) -{ - for (int i = 0; i < 16; i++) - for (int j = 0; j < 16; j++) - for (int k = 0; k < 16; k++) { - - int r = bg.r; - int g = bg.g; - int b = bg.b; - - r = mix_channel(r, c2.r, k*16); - g = mix_channel(g, c2.g, k*16); - b = mix_channel(b, c2.b, k*16); - - r = mix_channel(r, c1.r, j*16); - g = mix_channel(g, c1.g, j*16); - b = mix_channel(b, c1.b, j*16); - - r = mix_channel(r, c0.r, i*8); - g = mix_channel(g, c0.g, i*8); - b = mix_channel(b, c0.b, i*8); - - int v = (((i ^ j ^ k)<<1) & 0xff) + 128 + 64; - - r = (r + v)>>1; - g = (g + v)>>1; - b = (b + v)>>1; - -// r = g = b = min(255, 50 + ((i*j*128 + j*k*128 + k*i*128)>>8)); - - v = 180; - r = (v*r + (255 - v)*255)>>8; - g = (v*g + (255 - v)*255)>>8; - b = (v*b + (255 - v)*255)>>8; - - dst[(k<<8) + (j<<4) + i].rgba(r, g, b); - } -} - - -template -static void compose(PT *dst, int dst_w, int dst_h, int x_start, int x_end, - short src1[], int src1_y, - short src2[], int src2_y, - short src3[], int src3_y, int src_w, int src_h, - PT coltab[]) -{ - for (int k = 0; k <= x_end; k += src_w) { - - int x_offset = max(0, x_start - k); - int x_max = min(x_end - k, src_w - 1); - - for (int j = 0; j < dst_h; j++) { - - short *s1 = src1 + x_offset + ((src1_y + j)%src_h)*src_w; - short *s2 = src2 + x_offset + ((src2_y + j)%src_h)*src_w; - short *s3 = src3 + x_offset + ((src3_y + j)%src_h)*src_w; - PT *d = dst + x_offset + j*dst_w + k; - - for (int i = x_offset; i <= x_max; i++) - *d++ = coltab[*s1++ + *s2++ + *s3++]; - } - } -} - - -template -static void copy(PT *dst, int dst_w, int dst_h, int x_start, int x_end, - PT *src, int src_y, int src_w, int src_h) -{ - for (int k = 0; k <= x_end; k += src_w) { - - int x_offset = max(0, x_start - k); - int x_max = min(x_end - k, src_w - 1); - - for (int j = 0; j < dst_h; j++) { - - PT *s = src + x_offset + ((src_y + j)%src_h)*src_w; - PT *d = dst + x_offset + j*dst_w + k; - - if (x_max - x_offset >= 0) - memcpy(d, s, (x_max - x_offset + 1)*sizeof(PT)); - } - } -} - - -/***************** - ** Constructor ** - *****************/ - -template -Sky_texture::Sky_texture() -{ - /* create nice-looking textures */ - brew_texture(_tmp[0], _buf[0], _bufs[0][0], TW, TH, 3, 7, 1, 30, 30, 10); - brew_texture(_tmp[0], _buf[0], _bufs[1][0], TW, TH, 3, 16, 3, 50, 40, 30); - brew_texture(_tmp[0], _buf[0], _bufs[2][0], TW, TH, 5, 40, 11, 70, 0, 0); - - /* shift texture 1 to bits 4 to 7 */ - multiply_buf(_bufs[1][0], TW*TH, 16*256); - - /* shift texture 2 to bits 8 to 11 */ - multiply_buf(_bufs[2][0], TW*TH, 16*16*256); - - /* create color table */ - create_coltab(_coltab, Color(255, 255, 255), - Color( 0, 0, 0), - Color(255, 255, 255), - Color( 80, 88, 112)); - - /* create fallback texture */ - compose(_fallback[0], TW, TH, 0, TW - 1, - _bufs[0][0], 0, _bufs[1][0], 0, _bufs[2][0], 0, - TW, TH, _coltab); -} - - -/***************************************** - ** Implementation of Element interface ** - *****************************************/ - -template -void Sky_texture::draw(Canvas *c, int px, int py) -{ - PT *addr = static_cast(c->addr()); - - if (!addr) return; - - int cx1 = c->clip_x1(); - int cy1 = c->clip_y1(); - int cx2 = c->clip_x2(); - int cy2 = c->clip_y2(); - - int v = -py; - int y0 = cy1 + v; - int y1 = cy1 + (( (5*v)/16)%TH); - int y2 = cy1 + (((11*v)/16)%TH); - - addr += cy1*c->w(); - - if (Config::background_detail == 0) { - copy(addr, c->w(), cy2 - cy1 + 1, cx1, cx2, - _fallback[0], cy1 - py, TW, TH); - return; - } - - compose(addr, c->w(), cy2 - cy1 + 1, cx1, cx2, - _bufs[0][0], y0, _bufs[1][0], y1, _bufs[2][0], y2, - TW, TH, _coltab); -} - - -#include "canvas_rgb565.h" -template class Sky_texture; diff --git a/demo/src/app/scout/common/test.txt b/demo/src/app/scout/common/test.txt deleted file mode 100644 index d9e491ae6..000000000 --- a/demo/src/app/scout/common/test.txt +++ /dev/null @@ -1,11 +0,0 @@ - - - Genode Demonstration - - Norman Feske - -[image setup] - -Introduction -############ - diff --git a/demo/src/app/scout/common/widgets.cc b/demo/src/app/scout/common/widgets.cc deleted file mode 100644 index c53103a4d..000000000 --- a/demo/src/app/scout/common/widgets.cc +++ /dev/null @@ -1,474 +0,0 @@ -/* - * \brief GUI elements - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#include "miscmath.h" -#include "widgets.h" - - -/************* - ** Docview ** - *************/ - -void Docview::format_fixed_width(int w) -{ - _min_w = _min_h = 0; - - if (_cont) { - _cont->format_fixed_width(w - 2*_padx - _right_pad); - _min_w = w; - _min_h = _voffset + _cont->min_h(); - } - - if (_bg) - _bg->geometry(0, 0, _min_w, _min_h); -} - - -void Docview::draw(Canvas *c, int x, int y) -{ - if (_bg) _bg->draw(c, _x + x, _y + y); - if (_cont) _cont->draw(c, _x + x, _y + y); -} - - -Element *Docview::find(int x, int y) -{ - if (!Element::find(x, y)) return 0; - Element *res = _cont ? _cont->find(x - _x, y - _y) : 0; - return res ? res : this; -} - - -void Docview::geometry(int x, int y, int w, int h) -{ - ::Element::geometry(x, y, w, h); - - if (_cont) _cont->geometry(_padx, _voffset, _cont->min_w(), h - _voffset); -} - - -/*********************** - ** Horizontal shadow ** - ***********************/ - -template -void Horizontal_shadow::draw(Canvas *c, int x, int y) -{ - PT *addr = static_cast(c->addr()); - - if (!addr) return; - - const int cx1 = c->clip_x1(); - const int cy1 = c->clip_y1(); - const int cx2 = c->clip_x2(); - const int cy2 = c->clip_y2(); - - x += _x; - y += _y; - int w = _w; - int h = _h; - - int curr_a = INTENSITY; - int step = _h ? (curr_a/_h) : 0; - - if (x < cx1) { - w -= cx1 - x; - x = cx1; - } - - if (y < cy1) { - h -= cy1 - y; - curr_a -= (cy1 - y)*step; - y = cy1; - } - - if (w > cx2 - x + 1) - w = cx2 - x + 1; - - if (h > cy2 - y + 1) - h = cy2 - y + 1; - - addr += c->w()*y + x; - - PT shadow_color(0,0,0); - - for (int j = 0; j < h; j++, addr += c->w()) { - - PT *d = addr; - - for (int i = 0; i < w; i++, d++) - *d = PT::mix(*d, shadow_color, curr_a); - - curr_a -= step; - } -} - - -/********** - ** Icon ** - **********/ - -template -Icon::Icon() -{ - memset(_pixel, 0, sizeof(_pixel)); - memset(_alpha, 0, sizeof(_alpha)); - memset(_shadow, 0, sizeof(_shadow)); - _icon_alpha = 255; -} - - -template -void Icon::rgba(unsigned char *src, int vshift, int shadow) -{ - /* convert rgba values to pixel type and alpha channel */ - for (int j = 0; j < H; j++) - for (int i = 0; i < W; i++, src += 4) { - _pixel[j][i].rgba(src[0], src[1], src[2]); - _alpha[j][i] = src[3]; - } - - /* handle special case of no shadow */ - if (shadow == 0) return; - - /* generate shadow shape from blurred alpha channel */ - for (int j = 1; j < H - 4; j++) - for (int i = 1; i < W - 2; i++) { - int v = 0; - for (int k = -1; k <= 1; k++) - for (int l = -1; l <=1; l++) - v += _alpha[(j + k + H)%H][(i + l + W)%W]; - - _shadow[j + 3][i] = v>>shadow; - } - - /* shift vertically */ - if (vshift > 0) - for (int j = H - 1; j >= vshift; j--) - for (int i = 0; i < W; i++) { - _pixel[j][i] = _pixel[j - vshift][i]; - _alpha[j][i] = _alpha[j - vshift][i]; - } - - /* apply shadow to pixels */ - PT shcol(0, 0, 0); - for (int j = 0; j < H; j++) - for (int i = 0; i < W; i++) { - _pixel[j][i] = PT::mix(shcol, _pixel[j][i], _alpha[j][i]); - _alpha[j][i] = min(255, _alpha[j][i] + _shadow[j][i]); - } -} - - -static inline void blur(unsigned char *src, unsigned char *dst, int w, int h) -{ - const int kernel = 3; - int scale = (kernel*2 + 1)*(kernel*2 + 1); - - scale = (scale*210)>>8; - for (int j = kernel; j < h - kernel; j++) - for (int i = kernel; i < w - kernel; i++) { - int v = 0; - for (int k = -kernel; k <= kernel; k++) - for (int l = -kernel; l <= kernel; l++) - v += src[w*(j + k) + (i + l)]; - - dst[w*j + i] = min(v/scale, 255); - } -} - - -template -void Icon::glow(unsigned char *src, Color c) -{ - /* extract shape from alpha channel of rgba source image */ - for (int j = 0; j < H; j++) - for (int i = 0; i < W; i++, src += 4) - _alpha[j][i] = src[3] ? 255 : 0; - - for (int i = 0; i < 2; i++) { - blur(_alpha[0], _shadow[0], W, H); - blur(_shadow[0], _alpha[0], W, H); - } - - /* assign pixels and alpha */ - PT s(c.r, c.g, c.b); - for (int j = 0; j < H; j++) - for (int i = 0; i < W; i++, src += 4) - _pixel[j][i] = s; -} - - -/* - * An Icon has the following layout: - * - * P1---+--------+----+ - * | cs | hs | cs | top row - * +----P2-------+----+ - * | | | | - * | vs | | vs | mid row - * | | | | - * +----+--------P3---+ - * | cs | hs | cs | low row - * +------------------P4 - * - * cs ... corner slice - * hs ... horizontal slice - * vs ... vertical slice - */ - - -/** - * Copy pixel with alpha - */ -template -static inline void transfer_pixel(PT &src, int src_a, int alpha, PT *dst) -{ - if (src_a) { - int register a = (src_a * alpha)>>8; - if (a) *dst = PT::mix(*dst, src, a); - } -} - - -/** - * Draw corner slice - */ -template -static void draw_cslice(PT *src, unsigned char *src_a, int src_pitch, int alpha, - PT *dst, int dst_pitch, int w, int h) -{ - for (int j = 0; j < h; j++) { - - PT *s = src; - unsigned char *sa = src_a; - PT *d = dst; - - for (int i = 0; i < w; i++, s++, sa++, d++) - transfer_pixel(*s, *sa, alpha, d); - - src += src_pitch, src_a += src_pitch, dst += dst_pitch; - } -} - - -/** - * Draw horizontal slice - */ -template -static void draw_hslice(PT *src, unsigned char *src_a, int src_pitch, int alpha, - PT *dst, int dst_pitch, int w, int h) -{ - for (int j = 0; j < h; j++) { - - PT s = *src; - int sa = *src_a; - PT *d = dst; - - for (int i = 0; i < w; i++, d++) - transfer_pixel(s, sa, alpha, d); - - src += src_pitch, src_a += src_pitch, dst += dst_pitch; - } -} - - -/** - * Draw vertical slice - */ -template -static void draw_vslice(PT *src, unsigned char *src_a, int src_pitch, int alpha, - PT *dst, int dst_pitch, int w, int h) -{ - for (int i = 0; i < w; i++) { - - PT s = *src; - int sa = *src_a; - PT *d = dst; - - for (int j = 0; j < h; j++, d += dst_pitch) - transfer_pixel(s, sa, alpha, d); - - src += 1, src_a += 1, dst += 1; - } -} - - -/** - * Draw center slice - */ -template -static void draw_center(PT *src, unsigned char *src_a, int src_pitch, int alpha, - PT *dst, int dst_pitch, int w, int h) -{ - PT s = *src; - int sa = *src_a; - - for (int j = 0; j < h; j++, dst += dst_pitch) { - - PT *d = dst; - - for (int i = 0; i < w; i++, d++) - transfer_pixel(s, sa, alpha, d); - } -} - - -/** - * Clip rectangle against clipping region - * - * The out parameters are the resulting x/y offsets and the - * visible width and height. - * - * \return 1 if rectangle intersects with clipping region, - * 0 otherwise - */ -static inline int clip(int px1, int py1, int px2, int py2, - int cx1, int cy1, int cx2, int cy2, - int *out_x, int *out_y, int *out_w, int *out_h) -{ - /* determine intersection of rectangle and clipping region */ - int x1 = max(px1, cx1); - int y1 = max(py1, cy1); - int x2 = min(px2, cx2); - int y2 = min(py2, cy2); - - *out_w = x2 - x1 + 1; - *out_h = y2 - y1 + 1; - *out_x = x1 - px1; - *out_y = y1 - py1; - - return (*out_w > 0) && (*out_h > 0); -} - - -template -void Icon::draw(Canvas *c, int x, int y) -{ - PT *addr = static_cast(c->addr()); - - if (!addr || (_icon_alpha == 0)) return; - - const int cx1 = c->clip_x1(); - const int cy1 = c->clip_y1(); - const int cx2 = c->clip_x2(); - const int cy2 = c->clip_y2(); - - /* determine point positions */ - const int x1 = x + _x; - const int y1 = y + _y; - const int x4 = x1 + _w - 1; - const int y4 = y1 + _h - 1; - const int x2 = x1 + W/2; - const int y2 = y1 + H/2; - const int x3 = max(x4 - W/2, x2); - const int y3 = max(y4 - H/2, y2); - - const int tx1 = 0; - const int ty1 = 0; - const int tx4 = W - 1; - const int ty4 = H - 1; - const int tx2 = W/2; - const int ty2 = H/2; - const int tx3 = max(tx4 - W/2, tx2); - const int ty3 = max(ty4 - H/2, ty2); - - PT *src = _pixel[0] + W*ty1; - unsigned char *src_a = _alpha[0] + W*ty1; - int dx, dy, w, h; - - /* - * top row - */ - - if (clip(x1, y1, x2 - 1, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_cslice(src + tx1 + dy*W + dx, src_a + tx1 + dy*W + dx, W, _icon_alpha, - addr + (y1 + dy)*c->w() + x1 + dx, c->w(), w, h); - - if (clip(x2, y1, x3 - 1, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_hslice(src + tx2 + dy*W + dx, src_a + tx2 + dy*W + dx, W, _icon_alpha, - addr + (y1 + dy)*c->w() + x2 + dx, c->w(), w, h); - - if (clip(x3, y1, x4, y2 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_cslice(src + tx3 + dy*W + dx, src_a + tx3 + dy*W + dx, W, _icon_alpha, - addr + (y1 + dy)*c->w() + x3 + dx, c->w(), w, h); - - /* - * mid row - */ - - src = _pixel[0] + W*ty2; - src_a = _alpha[0] + W*ty2; - - if (clip(x1, y2, x2 - 1, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_vslice(src + tx1 + dx, src_a + tx1 + dx, W, _icon_alpha, - addr + (y2 + dy)*c->w() + x1 + dx, c->w(), w, h); - - if (clip(x2, y2, x3 - 1, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_center(src + tx2, src_a + tx2, W, _icon_alpha, - addr + (y2 + dy)*c->w() + x2 + dx, c->w(), w, h); - - if (clip(x3, y2, x4, y3 - 1, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_vslice(src + tx3 + dx, src_a + tx3 + dx, W, _icon_alpha, - addr + (y2 + dy)*c->w() + x3 + dx, c->w(), w, h); - - /* - * low row - */ - - src = _pixel[0] + W*ty3; - src_a = _alpha[0] + W*ty3; - - if (clip(x1, y3, x2 - 1, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_cslice(src + tx1 + dy*W + dx, src_a + tx1 + dy*W + dx, W, _icon_alpha, - addr + (y3 + dy)*c->w() + x1 + dx, c->w(), w, h); - - if (clip(x2, y3, x3 - 1, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_hslice(src + tx2 + dy*W + dx, src_a + tx2 + dy*W + dx, W, _icon_alpha, - addr + (y3 + dy)*c->w() + x2 + dx, c->w(), w, h); - - if (clip(x3, y3, x4, y4, cx1, cy1, cx2, cy2, &dx, &dy, &w, &h)) - draw_cslice(src + tx3 + dy*W + dx, src_a + tx3 + dy*W + dx, W, _icon_alpha, - addr + (y3 + dy)*c->w() + x3 + dx, c->w(), w, h); -} - - -template -Element *Icon::find(int x, int y) -{ - if (!Element::find(x, y)) return 0; - - x -= _x; - y -= _y; - - /* check icon boundaries (the height is flexible) */ - if ((x < 0) || (x >= W) || (y < 0) || (y >= _h)) return 0; - - /* upper part of the icon */ - if (y <= H/2) return _alpha[y][x] ? this : 0; - - /* lower part of the icon */ - if (y > _h - H/2) return _alpha[y - _h + H][x] ? this : 0; - - /* middle part of the icon */ - if (_alpha[H/2][x]) return this; - - return 0; -} - -#include "canvas_rgb565.h" -template class Horizontal_shadow; -template class Horizontal_shadow; -template class Icon; -template class Icon; -template class Icon; diff --git a/demo/src/app/scout/include/config.h b/demo/src/app/scout/config.h similarity index 92% rename from demo/src/app/scout/include/config.h rename to demo/src/app/scout/config.h index 3578e247f..4aad14e6f 100644 --- a/demo/src/app/scout/include/config.h +++ b/demo/src/app/scout/config.h @@ -14,13 +14,12 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -namespace Config -{ +namespace Scout { namespace Config { extern int iconbar_detail; extern int background_detail; extern int mouse_cursor; extern int browser_attr; -}; +} } #endif /* _CONFIG_H_ */ diff --git a/demo/src/app/scout/common/doc.cc b/demo/src/app/scout/doc.cc similarity index 99% rename from demo/src/app/scout/common/doc.cc rename to demo/src/app/scout/doc.cc index c69aacbce..d08afda6f 100644 --- a/demo/src/app/scout/common/doc.cc +++ b/demo/src/app/scout/doc.cc @@ -14,6 +14,8 @@ #include "elements.h" #include "styles.h" +using namespace Scout; + Document *create_document() { Document *doc = new Document(); diff --git a/demo/src/app/scout/common/elements.cc b/demo/src/app/scout/elements.cc similarity index 52% rename from demo/src/app/scout/common/elements.cc rename to demo/src/app/scout/elements.cc index 7f942ee1d..02b4c9449 100644 --- a/demo/src/app/scout/common/elements.cc +++ b/demo/src/app/scout/elements.cc @@ -11,10 +11,13 @@ * under the terms of the GNU General Public License version 2. */ -#include "miscmath.h" +#include + #include "elements.h" #include "browser.h" +using namespace Scout; + /************* ** Element ** @@ -29,14 +32,14 @@ Element::~Element() void Element::redraw_area(int x, int y, int w, int h) { - x += _x; - y += _y; + x += _position.x(); + y += _position.y(); /* intersect specified area with element geometry */ - int x1 = max(x, _x); - int y1 = max(y, _y); - int x2 = min(x + w - 1, _x + _w - 1); - int y2 = min(y + h - 1, _y + _h - 1); + int x1 = max(x, _position.x()); + int y1 = max(y, _position.y()); + int x2 = min(x + w - 1, _position.x() + (int)_size.w() - 1); + int y2 = min(y + h - 1, _position.y() + (int)_size.h() - 1); if (x1 > x2 || y1 > y2) return; @@ -46,10 +49,10 @@ void Element::redraw_area(int x, int y, int w, int h) } -Element *Element::find(int x, int y) +Element *Element::find(Point position) { - if (x >= _x && x < _x + _w - && y >= _y && y < _y + _h + if (position.x() >= _position.x() && position.x() < _position.x() + (int)_size.w() + && position.y() >= _position.y() && position.y() < _position.y() + (int)_size.h() && _flags.findable) return this; @@ -59,12 +62,14 @@ Element *Element::find(int x, int y) Element *Element::find_by_y(int y) { - return (y >= _y && y < _y + _h) ? this : 0; + return (y >= _position.y() && y < _position.y() + (int)_size.h()) ? this : 0; } -int Element::abs_x() { return _x + (_parent ? _parent->abs_x() : 0); } -int Element::abs_y() { return _y + (_parent ? _parent->abs_y() : 0); } +Point Element::abs_position() const +{ + return _position + (_parent ? _parent->abs_position() : Point(0, 0)); +} Element *Element::chapter() @@ -74,12 +79,6 @@ Element *Element::chapter() } -Browser *Element::browser() -{ - return _parent ? _parent->browser() : 0; -} - - /******************** ** Parent element ** ********************/ @@ -97,7 +96,7 @@ void Parent_element::append(Element *e) } -void Parent_element::remove(Element *e) +void Parent_element::remove(Element const *e) { if (e == _first) _first = e->next; @@ -124,12 +123,13 @@ void Parent_element::remove(Element *e) } -void Parent_element::forget(Element *e) +void Parent_element::forget(Element const *e) { - if (e->parent() == this) + if (e->has_parent(this)) remove(e); - _parent->forget(e); + if (_parent) + _parent->forget(e); } @@ -141,35 +141,34 @@ int Parent_element::_format_children(int x, int w) for (Element *e = _first; e; e = e->next) { e->format_fixed_width(w); - e->geometry(x, y, e->min_w(), e->min_h()); - y += e->min_h(); + e->geometry(Rect(Point(x, y), e->min_size())); + y += e->min_size().h(); } return y; } -void Parent_element::draw(Canvas *c, int x, int y) +void Parent_element::draw(Canvas_base &canvas, Point abs_position) { for (Element *e = _first; e; e = e->next) - e->try_draw(c, _x + x, _y + y); + e->try_draw(canvas, abs_position + _position); } -Element *Parent_element::find(int x, int y) +Element *Parent_element::find(Point position) { /* check if position is outside the parent element */ - if (x < _x || x >= _x + _w - || y < _y || y >= _y + _h) + if (position.x() < _position.x() || position.x() >= _position.x() + (int)_size.w() + || position.y() < _position.y() || position.y() >= _position.y() + (int)_size.h()) return 0; - x -= _x; - y -= _y; + position = position - _position; /* check children */ Element *ret = this; for (Element *e = _first; e; e = e->next) { - Element *res = e->find(x, y); + Element *res = e->find(position); if (res) ret = res; } @@ -180,10 +179,10 @@ Element *Parent_element::find(int x, int y) Element *Parent_element::find_by_y(int y) { /* check if position is outside the parent element */ - if (y < _y || y >= _y + _h) + if (y < _position.y() || y >= _position.y() + (int)_size.h()) return 0; - y -= _y; + y -= _position.y(); /* check children */ for (Element *e = _first; e; e = e->next) { @@ -195,31 +194,26 @@ Element *Parent_element::find_by_y(int y) } -void Parent_element::geometry(int x, int y, int w, int h) +void Parent_element::geometry(Rect rect) { - ::Element::geometry(x, y, w, h); + ::Element::geometry(rect); if (!_last || !_last->is_bottom()) return; - _last->geometry(_last->x(), h - _last->h(), _last->w(), _last->h()); + _last->geometry(Rect(Point(_last->position().x(), + rect.h() - _last->size().h()), _last->size())); } -void Parent_element::fill_cache(Canvas *c) +void Parent_element::fill_cache(Canvas_base &canvas) { - for (Element *e = _first; e; e = e->next) e->fill_cache(c); + for (Element *e = _first; e; e = e->next) e->fill_cache(canvas); } -void Parent_element::flush_cache(Canvas *c) +void Parent_element::flush_cache(Canvas_base &canvas) { - for (Element *e = _first; e; e = e->next) e->flush_cache(c); -} - - -void Parent_element::curr_link_destination(Element *dst) -{ - for (Element *e = _first; e; e = e->next) e->curr_link_destination(dst); + for (Element *e = _first; e; e = e->next) e->flush_cache(canvas); } @@ -237,27 +231,28 @@ Token::Token(Style *style, const char *str, int len) _outline = Color(0, 0, 0, 0); if (!_style) return; - _min_w = _style->font->str_w(str, len) + _style->font->str_w(" ", 1); - _min_h = _style->font->str_h(str, len); + _min_size = Area(_style->font->str_w(str, len) + _style->font->str_w(" ", 1), + _style->font->str_h(str, len)); } -void Token::draw(Canvas *c, int x, int y) +void Token::draw(Canvas_base &canvas, Point abs_position) { if (!_style) return; if (_style->attr & Style::ATTR_BOLD) - _outline.rgba(_col.r, _col.g, _col.b, 32); + _outline = Color(_col.r, _col.g, _col.b, 32); - x++; y++; + abs_position = abs_position + Point(1, 1); if (_outline.a) for (int i = -1; i <= 1; i++) for (int j = -1; j <= 1; j++) - c->draw_string(_x + x +i , _y + y +j, _style->font, _outline, _str, _len); + canvas.draw_string(_position.x() + abs_position.x() + i, + _position.y() + abs_position.y() + j, + _style->font, _outline, _str, _len); - c->draw_string(_x + x, _y + y, _style->font, _col, _str, _len); - - if (_flags.link) - c->draw_box(_x + x, _y + y + _h - 1, _w, 1, Color(0,0,255)); + canvas.draw_string(_position.x() + abs_position.x(), + _position.y() + abs_position.y(), + _style->font, _col, _str, _len); } @@ -302,29 +297,29 @@ void Block::append_text(const char *str, Style *style, void Block::format_fixed_width(int w) { int x = 0, y = 0; - int line_max_h = 0; - int max_w = 0; + unsigned line_max_h = 0; + unsigned max_w = 0; for (Element *e = _first; e; e = e->next) { /* wrap at the end of the line */ - if (x + e->min_w() >= w) { + if (x + (int)e->min_size().w() >= w) { x = _second_indent; y += line_max_h; line_max_h = 0; } /* position element */ - if (max_w < x + e->min_w()) - max_w = x + e->min_w(); + if (max_w < x + e->min_size().w()) + max_w = x + e->min_size().w(); - e->geometry(x, y, e->min_w(), e->min_h()); + e->geometry(Rect(Point(x, y), e->min_size())); /* determine token with the biggest height of the line */ - if (line_max_h < e->min_h()) - line_max_h = e->min_h(); + if (line_max_h < e->min_size().h()) + line_max_h = e->min_size().h(); - x += e->min_w(); + x += e->min_size().w(); } /* @@ -336,30 +331,30 @@ void Block::format_fixed_width(int w) for (Element *line = _first; line; ) { Element *e; - int cy = line->y(); /* y position of current line */ - int max_x; /* rightmost position */ + int cy = line->position().y(); /* y position of current line */ + int max_x; /* rightmost position */ /* determine free space at the end of the line */ - for (max_x = 0, e = line; e && (e->y() == cy); e = e->next) - max_x = max(max_x, e->x() + e->w() - 1); + for (max_x = 0, e = line; e && (e->position().y() == cy); e = e->next) + max_x = max(max_x, e->position().x() + (int)e->size().w() - 1); /* indent elements of the line according to the alignment */ int dx = 0; - if (_align == CENTER) dx = max(0, (max_w - max_x)/2); - if (_align == RIGHT) dx = max(0, max_w - max_x); - for (e = line; e && (e->y() == cy); e = e->next) - e->geometry(e->x() + dx, e->y(), e->w(), e->h()); + if (_align == CENTER) dx = max(0UL, (max_w - max_x)/2); + if (_align == RIGHT) dx = max(0UL, max_w - max_x); + for (e = line; e && (e->position().y() == cy); e = e->next) + e->geometry(Rect(Point(e->position().x() + dx, e->position().y()), + e->size())); /* find first element of next line */ - for (; line && (line->y() == cy); line = line->next); + for (; line && (line->position().y() == cy); line = line->next); } } /* line break at the end of the last line */ if (line_max_h) y += line_max_h; - _min_h = y + 5; - _min_w = max_w; + _min_size = Area(max_w, y + 5); } @@ -369,20 +364,21 @@ void Block::format_fixed_width(int w) void Center::format_fixed_width(int w) { - _min_h = _format_children(0, w); + _min_size = Area(_min_size.w(), _format_children(0, w)); /* determine highest min with of children */ - int highest_min_w = 0; + unsigned highest_min_w = 0; for (Element *e = _first; e; e = e->next) - if (highest_min_w < e->min_w()) - highest_min_w = e->min_w(); + if (highest_min_w < e->min_size().w()) + highest_min_w = e->min_size().w(); - int dx = (w - highest_min_w)>>1; - _min_w = max(w, highest_min_w); + unsigned dx = (w - highest_min_w)>>1; + + _min_size = Area(max((unsigned)w, highest_min_w), _min_size.h()); /* move children to center */ for (Element *e = _first; e; e = e->next) - e->geometry(dx, e->y(), e->w(), e->h()); + e->geometry(Rect(Point(dx, e->position().y()), e->size())); } @@ -390,18 +386,23 @@ void Center::format_fixed_width(int w) ** Verbatim ** **************/ -void Verbatim::draw(Canvas *c, int x, int y) +void Verbatim::draw(Canvas_base &canvas, Point abs_position) { static const int pad = 5; - c->draw_box(_x + x + pad, _y + y + pad, _w - 2*pad, _h - 2*pad, bgcol); + canvas.draw_box(_position.x() + abs_position.x() + pad, + _position.y() + abs_position.x() + pad, + _size.w() - 2*pad, _size.h() - 2*pad, bgcol); - int cx1 = c->clip_x1(), cy1 = c->clip_y1(); - int cx2 = c->clip_x2(), cy2 = c->clip_y2(); + int cx1 = canvas.clip().x1(), cy1 = canvas.clip().y1(); + int cx2 = canvas.clip().x2(), cy2 = canvas.clip().y2(); - c->clip(_x + x + pad, _y + y + pad, _w - 2*pad, _h - 2*pad); - Parent_element::draw(c, x, y); - c->clip(cx1, cy1, cx2 - cx1 + 1, cy2 - cy1 + 1); + canvas.clip(Rect(Point(_position.x() + abs_position.x() + pad, + _position.y() + abs_position.y() + pad), + Area(_size.w() - 2*pad, _size.h() - 2*pad))); + Parent_element::draw(canvas, abs_position); + + canvas.clip(Rect(Point(cx1, cy1), Area(cx2 - cx1 + 1, cy2 - cy1 + 1))); } @@ -412,13 +413,12 @@ void Verbatim::format_fixed_width(int w) for (Element *e = _first; e; e = e->next) { /* position element */ - e->geometry(10, y, e->min_w(), e->min_h()); + e->geometry(Rect(Point(10, y), e->min_size())); - y += e->min_h(); + y += e->min_size().h(); } - _min_h = y + 10; - _min_w = w; + _min_size = Area(w, y + 10); } @@ -430,8 +430,12 @@ void Link_token::handle(Event &e) { if (e.type != Event::PRESS) return; - /* make browser to follow link */ - Browser *b = browser(); + /* lookup browser, in which the link token resides */ + Browser *b = 0; + for (Element *e = this; e && !b; e = e->parent()) + b = dynamic_cast(e); + + /* let browser follow link */ if (b && _dst) b->go_to(_dst); } diff --git a/demo/src/app/scout/elements.h b/demo/src/app/scout/elements.h new file mode 100644 index 000000000..380190714 --- /dev/null +++ b/demo/src/app/scout/elements.h @@ -0,0 +1,590 @@ +/* + * \brief Document structure elements + * \date 2005-10-24 + * \author Norman Feske + */ + +/* + * Copyright (C) 2005-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _ELEMENTS_H_ +#define _ELEMENTS_H_ + +#include +#include +#include +#include + +namespace Scout { + class Style; + class Browser; + class Token; + class Link; + class Link_token; + class Launcher_config; + class Launcher; + class Launcher_link_token; + class Block; + class Center; + class Png_image; + class Chapter; + class Document; + class Spacer; + class Verbatim; + class Item; + class Generic_icon; + class Navbar; + + /** + * Link anchor + * + * An anchor marks a location within a document that can be addressed by a + * link. + */ + typedef Element Anchor; +} + + +/** + * Textual style + * + * A style describes the font, color and accentuations of tokens. + */ +class Scout::Style +{ + public: + + enum { + ATTR_BOLD = 0x1, + }; + + Font *font; + Color color; + int attr; + + Style(Font *f, Color c, int a) + { + font = f; + color = c; + attr = a; + } +}; + + +/** + * String token + * + * A Token is a group of characters that are handled as an atomic text unit. + * Line wrapping is performed at the granularity of tokens. + */ +class Scout::Token : public Element +{ + protected: + + const char *_str; /* start of string */ + int _len; /* length of string */ + Style *_style; /* textual style */ + Color _col; /* current text color */ + Color _outline; /* outline color */ + + public: + + /** + * Constructor + */ + Token(Style *style, const char *str, int len); + + /** + * Element interface + */ + void draw(Canvas_base &, Point); + void refresh() { redraw_area(-1, 0, _size.w() + 1, _size.h()); } +}; + + +/** + * Link that references an anchor within the document + */ +class Scout::Link +{ + protected: + + Anchor *_dst; /* link destination */ + + public: + + /** + * Constructor + */ + explicit Link(Anchor *dst) { _dst = dst; } + + /** + * Accessor function + */ + Anchor *dst() { return _dst; } +}; + + +/** + * Textual link + */ +class Scout::Link_token : public Token, public Link, public Event_handler, + public Fader +{ + private: + + enum { _MAX_ALPHA = 50 }; + + public: + + /** + * Constructor + */ + Link_token(Style *style, const char *str, int len, Anchor *dst) + : Token(style, str, len), Link(dst) + { + _flags.takes_focus = 1; + _curr_value = 0; + event_handler(this); + } + + /** + * Element interface + */ + void draw(Canvas_base &canvas, Point abs_position) + { + _outline = Color(_style->color.r, + _style->color.g, + _style->color.b, _curr_value); + + Token::draw(canvas, abs_position); + + canvas.draw_box(_position.x() + abs_position.x(), + _position.y() + abs_position.y() + _size.h() - 1, + _size.w(), 1, Color(0,0,255)); + } + + void mfocus(int flag) + { + /* + * highlight link of all siblings that point to the same link. + */ + if (_dst) { + Element const *dst = _dst; + for_each_sibling([dst, flag] (Element &e) { + Link_token *l = dynamic_cast(&e); + if (l && l->has_destination(dst)) + l->highlight_link(flag); + }); + } + + Token::mfocus(flag); + } + + void highlight_link(bool flag) + { + if (flag && _curr_value != _MAX_ALPHA) + fade_to(_MAX_ALPHA, 50); + + if (!flag && _curr_value != 0) + fade_to(0, 2); + } + + bool has_destination(Element const *e) { return e == _dst; } + + /** + * Event handler interface + */ + void handle(Event &e); + + /** + * Tick interface + */ + int on_tick() + { + /* call on_tick function of the fader */ + if (Fader::on_tick() == 0) return 0; + + refresh(); + return 1; + } +}; + + +class Launchpad; + + +class Scout::Launcher : public Anchor +{ + private: + + const char *_prg_name; /* null-terminated name of the program */ + int _active; + int _exec_once; + Launchpad *_launchpad; + unsigned long _quota; + Launcher_config *_config; + + public: + + /** + * Constructors + */ + Launcher(const char *prg_name, int exec_once = 0, + unsigned long quota = 0, Launcher_config *config = 0) : + _prg_name(prg_name), _active(1), + _exec_once(exec_once), _quota(quota), _config(config) { } + + Launcher(const char *prg_name, Launchpad *launchpad, + unsigned long quota, Launcher_config *config = 0) : + _prg_name(prg_name), _launchpad(launchpad), _quota(quota), + _config(config) { } + + int active() { return _active; } + + const char *prg_name() { return _prg_name; } + + void quota(unsigned long quota) { _quota = quota; } + + unsigned long quota() { return _quota; } + + Launcher_config *config() { return _config; } + + /** + * Launch program + */ + void launch(); +}; + + +/** + * Executable launcher link + * + * This is a special link that enables us to start external applications. + */ +class Scout::Launcher_link_token : public Link_token +{ + public: + + /** + * Constructor + */ + Launcher_link_token(Style *style, const char *str, int len, Launcher *l) + : Link_token(style, str, len, l) { } + + /** + * Event handler interface + */ + void handle(Event &e); +}; + + +/** + * Text block + * + * A block is a group of tokens that form a paragraph. A block layouts its + * tokens while using line wrapping. + */ +class Scout::Block : public Parent_element +{ + public: + + enum Alignment { LEFT, CENTER, RIGHT }; + enum Text_type { PLAIN, LINK, LAUNCHER }; + + private: + + int _second_indent; /* indentation of second line */ + Alignment _align; /* text alignment */ + + /** + * Append text to block + */ + void append_text(const char *str, Style *style, Text_type, + Anchor *a, Launcher *l); + + public: + + /** + * Constructors + */ + explicit Block(int second_indent = 0) + { + _align = LEFT; + _second_indent = second_indent; + } + + explicit Block(Alignment align) + { + _align = align; + _second_indent = 0; + } + + /** + * Define alignment of text + */ + void align(Alignment); + + /** + * Append a string of space-separated words + */ + void append_plaintext(const char *str, Style *style) + { + append_text(str, style, PLAIN, 0, 0); + } + + /** + * Append a string of space-separated words a link + * + * \param dst anchor that defines the link destination + */ + void append_linktext(const char *str, Style *style, Anchor *a) + { + append_text(str, style, LINK, a, 0); + } + + /** + * Append a string of space-separated words a launcher-link + */ + void append_launchertext(const char *str, Style *style, Launcher *l) + { + append_text(str, style, LAUNCHER, 0, l); + } + + /** + * Element interface + */ + void format_fixed_width(int w); +}; + + +/** + * Horizontally centered content + */ +class Scout::Center : public Parent_element +{ + public: + + /** + * Constructor + */ + explicit Center(Element *content = 0) + { + if (content) append(content); + } + + /** + * Element interface + */ + void format_fixed_width(int w); +}; + + +/** + * PNG Image + */ +class Scout::Png_image : public Element +{ + private: + + void *_png_data; + Texture_base *_texture; + + public: + + /** + * Constructor + */ + explicit Png_image(void *png_data) + { + _png_data = png_data; + _texture = 0; + } + + /** + * Accessor functions + */ + inline void *png_data() { return _png_data; } + + /** + * Element interface + */ + void fill_cache(Canvas_base &); + void flush_cache(Canvas_base &); + void draw(Canvas_base &, Point); +}; + + +/** + * Document + */ +class Scout::Document : public Parent_element +{ + public: + + Chapter *toc; /* table of contents */ + const char *title; /* document title */ + + /** + * Constructor + */ + Document() + { + toc = 0; title = ""; _flags.chapter = 1; + } + + /** + * Element interface + */ + void format_fixed_width(int w) + { + _min_size = Area(w, _format_children(0, w)); + } +}; + + +/** + * Chapter + */ +class Scout::Chapter : public Document { }; + + +/** + * Spacer + * + * A spacer is a place holder that consumes some screen space. It is used for + * tweaking the layout of the document. + */ +struct Scout::Spacer : Element +{ + Spacer(int w, int h) { _min_size = _size = Area(w, h); } +}; + + +/** + * Verbatim text block + * + * A verbatim text block consists of a number of preformatted text lines. + * The text is printed in a monospaced font and the whole verbatim area + * has a shaded background. + */ +class Scout::Verbatim : public Parent_element +{ + public: + + Color bgcol; + + /** + * Constructor + */ + explicit Verbatim(Color bg) { bgcol = bg; } + + /** + * Append verbatim text line + */ + void append_textline(const char *str, Style *style) + { + append(new Token(style, str, strlen(str))); + } + + /** + * Element interface + */ + void draw(Canvas_base &, Point); + void format_fixed_width(int); +}; + + +/** + * An iten consists of a item tag and a list of blocks + */ +class Scout::Item : public Parent_element +{ + public: + + int _tag_ident; + const char *_tag; + Style *_style; + + /** + * Constructor + */ + Item(Style *style, const char *str, int ident) + { + _style = style; + _tag = str; + _tag_ident = ident; + } + + /** + * Element interface + */ + void format_fixed_width(int w) + { + _min_size = Area(w, _format_children(_tag_ident, w - _tag_ident)); + } + + void draw(Canvas_base &canvas, Point abs_position) + { + canvas.draw_string(_position.x() + abs_position.x(), + _position.y() + abs_position.y(), + _style->font, _style->color, _tag, 255); + Parent_element::draw(canvas, abs_position); + } +}; + + +/** + * Document navigation bar + */ +class Scout::Navbar : public Parent_element, public Fader +{ + private: + + Block *_next_title; + Block *_prev_title; + + Anchor *_next_anchor; + Anchor *_prev_anchor; + + public: + + /** + * These pointers must be initialized such that they + * point to valid Icon widgets that are used as graphics + * for the navigation bar. + */ + static Generic_icon *next_icon; + static Generic_icon *prev_icon; + static Generic_icon *nbox_icon; + static Generic_icon *pbox_icon; + + /** + * Constructor + */ + Navbar(); + + /** + * Define link to next and previous chapter + */ + void next_link(const char *title, Anchor *dst); + void prev_link(const char *title, Anchor *dst); + + /** + * Element interface + */ + void format_fixed_width(int); + void draw(Canvas_base &, Point); + Element *find(Point); + + /** + * Tick interface + */ + int on_tick(); +}; + +#endif /* _ELEMENTS_H_ */ diff --git a/demo/src/app/scout/include/fade_icon.h b/demo/src/app/scout/fade_icon.h similarity index 85% rename from demo/src/app/scout/include/fade_icon.h rename to demo/src/app/scout/fade_icon.h index 2c445cc92..d083107cd 100644 --- a/demo/src/app/scout/include/fade_icon.h +++ b/demo/src/app/scout/fade_icon.h @@ -18,13 +18,15 @@ #ifndef _FADE_ICON_H_ #define _FADE_ICON_H_ -#include "miscmath.h" +#include +#include #include "widgets.h" -#include "fader.h" + +namespace Scout { template class Fade_icon; } template -class Fade_icon : public Fader, public Icon +class Scout::Fade_icon : public Fader, public Icon { private: @@ -64,7 +66,7 @@ class Fade_icon : public Fader, public Icon int on_tick() { /* call on_tick function of the fader */ - if (::Fader::on_tick() == 0) return 0; + if (Fader::on_tick() == 0) return 0; Icon::alpha(_curr_value); return 1; @@ -76,7 +78,7 @@ class Fade_icon : public Fader, public Icon void alpha(int alpha) { _curr_value = alpha; - ::Icon::alpha(alpha); + Icon::alpha(alpha); } /** diff --git a/demo/src/app/scout/genode/platform_genode.cc b/demo/src/app/scout/genode/platform_genode.cc deleted file mode 100644 index 2fb14d1d7..000000000 --- a/demo/src/app/scout/genode/platform_genode.cc +++ /dev/null @@ -1,382 +0,0 @@ -/* - * \brief Main program of Genode version of Scout - * \author Norman Feske - * \date 2006-08-28 - */ - -/* - * Copyright (C) 2006-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "platform.h" -#include "config.h" - -static int _scr_w; -static int _scr_h; -static Framebuffer::Mode::Format _scr_format; -static Input::Event *_ev_buf; -static char *_scr_adr; -static char *_buf_adr; -static int _mx, _my; -static int _flip_state; /* visible buffer (0..first, 1..second) */ - -static Nitpicker::Connection *_nitpicker; -static Timer::Session *_timer; -static unsigned long _timer_tick; -static int _init_flag; -static bool _view_initialized; -static int _vx, _vy, _vw, _vh, _vbx, _vby; /* view geometry */ - - -/** - * Create view and bring it to front - * - * This function is executed once during the construction of the static - * 'View_client' object in the 'view' function. - */ -static Nitpicker::View_capability create_and_top_view() -{ - Nitpicker::View_capability cap = _nitpicker->create_view(); - Nitpicker::View_client(cap).stack(Nitpicker::View_capability(), true, true); - Nitpicker::View_client(cap).viewport(_vx - _vbx, _vy - _vby, _vw, _vh, - _vbx, _flip_state ? _vby - _scr_h : _vby, true); - return cap; -} - - -/** - * Return Nitpicker view for the application - * - * On the first call of this function, the view gets created as static object. - * All subsequent calls just return the pointer to this object. - */ -static Nitpicker::View *view() -{ - static Nitpicker::View_client view(create_and_top_view()); - _view_initialized = true; - return &view; -} - - -using namespace Genode; - - -void *operator new(size_t size) -{ - void *addr = env()->heap()->alloc(size); - if (!addr) { - PERR("env()->heap() has consumed %zd", env()->heap()->consumed()); - PERR("env()->ram_session()->quota = %zd", env()->ram_session()->quota()); - throw Genode::Allocator::Out_of_memory(); - } - return addr; -} - - -/***************** - ** Event queue ** - *****************/ - -class Eventqueue -{ - private: - - static const int queue_size = 1024; - - int _head; - int _tail; - Semaphore _sem; - Genode::Lock _head_lock; /* synchronize add */ - - Event _queue[queue_size]; - - public: - - /** - * Constructor - */ - Eventqueue(): _head(0), _tail(0) - { - memset(_queue, 0, sizeof(_queue)); - } - - void add(Event *ev) - { - Lock::Guard lock_guard(_head_lock); - - if ((_head + 1)%queue_size != _tail) { - - _queue[_head] = *ev; - _head = (_head + 1)%queue_size; - _sem.up(); - } - } - - void get(Event *dst_ev) - { - _sem.down(); - *dst_ev = _queue[_tail]; - _tail = (_tail + 1)%queue_size; - } - - int pending() { return _head != _tail; } - -} _evqueue; - - -/****************** - ** Timer thread ** - ******************/ - -class Timer_thread : public Thread<4096> -{ - private: - - void _import_events() - { - if (_nitpicker->input()->is_pending() == false) return; - - for (int i = 0, num = _nitpicker->input()->flush(); i < num; i++) - { - Event ev; - Input::Event e = _ev_buf[i]; - - if (e.type() == Input::Event::RELEASE - || e.type() == Input::Event::PRESS) { - _mx = e.ax(); - _my = e.ay(); - ev.assign(e.type() == Input::Event::PRESS ? Event::PRESS : Event::RELEASE, - e.ax(), e.ay(), e.code()); - _evqueue.add(&ev); - } - - if (e.type() == Input::Event::MOTION) { - _mx = e.ax(); - _my = e.ay(); - ev.assign(Event::MOTION, e.ax(), e.ay(), e.code()); - _evqueue.add(&ev); - } - } - } - - public: - - /** - * Constructor - * - * Start thread immediately on construction. - */ - Timer_thread() : Thread("timer") { start(); } - - void entry() - { - while (1) { - Event ev; - ev.assign(Event::TIMER, _mx, _my, 0); - _evqueue.add(&ev); - - _import_events(); - - _timer->msleep(10); - _timer_tick += 10; - } - } -}; - - -/************************ - ** Platform interface ** - ************************/ - -/** - * Initialization - */ -Platform::Platform(unsigned vx, unsigned vy, unsigned vw, unsigned vh, - unsigned max_vw, unsigned max_vh) -: _max_vw(max_vw), _max_vh(max_vh) -{ - _vx = vx, _vy = vy, _vw = vw, _vh = vh, _vbx = 0, _vby = 0; - - Config::mouse_cursor = 0; - Config::browser_attr = 7; - - /* - * Allocate a nitpicker buffer double as high as the physical screen to - * use the upper/lower halves for double-buffering. - */ - _nitpicker = new (env()->heap()) Nitpicker::Connection; - Framebuffer::Mode const query_mode = _nitpicker->mode(); - _scr_w = query_mode.width(); - _scr_h = query_mode.height(); - _scr_format = query_mode.format(); - - if (_max_vw) _scr_w = min(_max_vw, _scr_w); - if (_max_vh) _scr_h = min(_max_vh, _scr_h); - - _nitpicker->buffer(Framebuffer::Mode(_scr_w, _scr_h*2, _scr_format), false); - - static Timer::Connection timer; - _timer = &timer; - - Framebuffer::Mode const used_mode = _nitpicker->framebuffer()->mode(); - - /* - * We use the upper half the allocated nitpicker buffer for '_scr_adr' - * and the lower half for '_buf_adr'. - */ - _scr_adr = env()->rm_session()->attach(_nitpicker->framebuffer()->dataspace()); - _buf_adr = (char *)_scr_adr + _scr_w*_scr_h*used_mode.bytes_per_pixel(); - _ev_buf = env()->rm_session()->attach(_nitpicker->input()->dataspace()); - - new (env()->heap()) Timer_thread(); - - /* mark platform as successfully initialized */ - _init_flag = 1; -} - - -/** - * Platform information - */ -int Platform::initialized() { return _init_flag; } -void *Platform::scr_adr() { return _scr_adr; } -void *Platform::buf_adr() { return _buf_adr; } -int Platform::scr_w() { return _scr_w; } -int Platform::scr_h() { return _scr_h; } - - -/** - * Return pixel format used by the platform - */ -Platform::pixel_format Platform::scr_pixel_format() { return RGB565; } - - -/** - * Exchange foreground and back buffers - */ -void Platform::flip_buf_scr() -{ - char *tmp = _buf_adr; - _buf_adr = _scr_adr; - _scr_adr = tmp; - _flip_state ^= 1; - - /* enable new foreground buffer by configuring the view port */ - view_geometry(_vx, _vy, _vw, _vh, false, _vbx, _vby); -} - - -/** - * Copy background buffer pixels to foreground buffer - */ -void Platform::copy_buf_to_scr(int x, int y, int w, int h) -{ - Genode::size_t bpp = Framebuffer::Mode::bytes_per_pixel(_scr_format); - - /* copy background buffer to foreground buffer */ - int len = w*bpp; - int linelen = _scr_w*bpp; - - char *src = _buf_adr + (y*_scr_w + x)*bpp; - char *dst = _scr_adr + (y*_scr_w + x)*bpp; - - blit(src, linelen, dst, linelen, len, h); -// for (int j = 0; j < h; j++, dst += linelen, src += linelen) -// memcpy(dst, src, len); -} - - -/** - * Flush pixels of specified area - */ -void Platform::scr_update(int x, int y, int w, int h) -{ - if (w <= 0 || h <= 0) return; - - if (_flip_state) y += _scr_h; - - /* - * Initialize Nitpicker view - * - * We defer the initialization of the Nitpicker view to the occurrence of - * the first refresh to avoid artifacts during the startup of the program. - * Previous version used to create the view some time before calling - * 'refresh' for the first time. During that time, moving the mouse over - * the designated view area resulted in parts of the buffer to become - * visible. - */ - view(); - - /* refresh part of the buffer */ - _nitpicker->framebuffer()->refresh(x, y, w, h); -} - - -void Platform::top_view() -{ - if (_view_initialized) - view()->stack(Nitpicker::View_capability(), true, true); -} - - -/** - * Report view geometry changes to Nitpicker. - */ -void Platform::view_geometry(int x, int y, int w, int h, int do_redraw, - int buf_x, int buf_y) -{ - _vx = x; _vy = y; _vw = w; _vh = h; _vbx = buf_x, _vby = buf_y; - if (_view_initialized) - view()->viewport(_vx - _vbx, _vy - _vby, _vw, _vh, - _vbx, - _flip_state ? _vby - _scr_h : _vby, do_redraw); -} - - -int Platform::vx() { return _vx; } -int Platform::vy() { return _vy; } -int Platform::vw() { return _vw; } -int Platform::vh() { return _vh; } -int Platform::vbx() { return _vbx; } -int Platform::vby() { return _vby; } - - -/** - * Provide timer tick information - */ -unsigned long Platform::timer_ticks() -{ - return _timer_tick; -} - - -/** - * Check if an event is pending - */ -int Platform::event_pending() -{ - return _evqueue.pending(); -} - - -/** - * Wait for an event, Zzz...zz.. - */ -void Platform::get_event(Event *out_e) -{ - _evqueue.get(out_e); -} diff --git a/demo/src/app/scout/genode/startup.cc b/demo/src/app/scout/genode/startup.cc deleted file mode 100644 index efacb6b43..000000000 --- a/demo/src/app/scout/genode/startup.cc +++ /dev/null @@ -1,17 +0,0 @@ -/* - * \brief Scout native startup code for Genode - * \date 2006-08-28 - * \author Norman Feske - */ - -/* - * Copyright (C) 2006-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -int native_startup(int argc, char **argv) -{ - return 0; -} diff --git a/demo/src/app/scout/include/history.h b/demo/src/app/scout/history.h similarity index 97% rename from demo/src/app/scout/include/history.h rename to demo/src/app/scout/history.h index 1c1b9a3b4..3fcbde136 100644 --- a/demo/src/app/scout/include/history.h +++ b/demo/src/app/scout/history.h @@ -16,7 +16,10 @@ #include "elements.h" -class History +namespace Scout { class History; } + + +class Scout::History { private: @@ -108,5 +111,4 @@ class History } }; - #endif diff --git a/demo/src/app/scout/include/canvas.h b/demo/src/app/scout/include/canvas.h deleted file mode 100644 index 13f601de7..000000000 --- a/demo/src/app/scout/include/canvas.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - * \brief Generic interface of graphics backend and chunky template - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CANVAS_H_ -#define _CANVAS_H_ - -#include "color.h" -#include "font.h" - - -class Canvas -{ - protected: - - int _clip_x1, _clip_y1; /* left-top of clipping area */ - int _clip_x2, _clip_y2; /* right-bottom of clipping area */ - - int _w, _h; /* current size of canvas */ - int _capacity; /* max number of pixels */ - - public: - - virtual ~Canvas() { } - - /** - * Define clipping rectangle - */ - void clip(int x, int y, unsigned w, unsigned h) - { - /* calculate left-top and right-bottom points of clipping rectangle */ - _clip_x1 = x; - _clip_y1 = y; - _clip_x2 = x + w - 1; - _clip_y2 = y + h - 1; - - /* check against canvas boundaries */ - if (_clip_x1 < 0) _clip_x1 = 0; - if (_clip_y1 < 0) _clip_y1 = 0; - if (w > 0 && _clip_x2 > _w - 1) _clip_x2 = _w - 1; - if (h > 0 && _clip_y2 > _h - 1) _clip_y2 = _h - 1; - } - - /** - * Request clipping rectangle - */ - int clip_x1() { return _clip_x1; } - int clip_y1() { return _clip_y1; } - int clip_x2() { return _clip_x2; } - int clip_y2() { return _clip_y2; } - - int w() { return _w; } - int h() { return _h; } - - /** - * Set logical size of canvas - */ - int set_size(int w, int h) - { - if (w*h > _capacity) return -1; - _w = w; - _h = h; - clip(0, 0, w - 1, h - 1); - return 0; - } - - /** - * Draw filled box - */ - virtual void draw_box(int x, int y, int w, int h, Color c) = 0; - - /** - * Draw string - */ - virtual void draw_string(int x, int y, Font *font, Color color, const char *str, int len) = 0; - - /** - * Return base address - */ - virtual void *addr() = 0; - - /** - * Define base address of pixel data - */ - virtual void addr(void *) = 0; - - /** - * Anonymous texture struct - */ - class Texture {}; - - /** - * Allocate texture container - */ - virtual Texture *alloc_texture(int w, int h) = 0; - - /** - * Free texture container - */ - virtual void free_texture(Texture *texture) = 0; - - /** - * Assign rgba values to texture line - */ - virtual void set_rgba_texture(Texture *dst, unsigned char *rgba, int len, int y) = 0; - - /** - * Draw texture - */ - virtual void draw_texture(Texture *src, int x, int y) { } -}; - - -template -class Pixel_rgba -{ - private: - - /** - * Shift left with positive or negative shift value - */ - inline int shift(int value, int shift) - { - return shift > 0 ? value << shift : value >> -shift; - } - - public: - - static const int r_mask = R_MASK, r_shift = R_SHIFT; - static const int g_mask = G_MASK, g_shift = G_SHIFT; - static const int b_mask = B_MASK, b_shift = B_SHIFT; - static const int a_mask = A_MASK, a_shift = A_SHIFT; - - ST pixel; - - /** - * Constructors - */ - Pixel_rgba() {} - - Pixel_rgba(int red, int green, int blue, int alpha = 255) - { - rgba(red, green, blue, alpha); - } - - /** - * Assign new rgba values - */ - void rgba(int red, int green, int blue, int alpha = 255) - { - pixel = (shift(red, r_shift) & r_mask) - | (shift(green, g_shift) & g_mask) - | (shift(blue, b_shift) & b_mask) - | (shift(alpha, a_shift) & a_mask); - } - - inline int r() { return shift(pixel & r_mask, -r_shift); } - inline int g() { return shift(pixel & g_mask, -g_shift); } - inline int b() { return shift(pixel & b_mask, -b_shift); } - - /** - * Multiply pixel with alpha value - */ - static inline Pixel_rgba blend(Pixel_rgba pixel, int alpha); - - /** - * Mix two pixels at the ratio specified as alpha - */ - static inline Pixel_rgba mix(Pixel_rgba p1, Pixel_rgba p2, int alpha); - - /** - * Compute average color value of two pixels - */ - static inline Pixel_rgba avr(Pixel_rgba p1, Pixel_rgba p2); - - /** - * Compute average color value of four pixels - */ - static inline Pixel_rgba avr(Pixel_rgba p1, Pixel_rgba p2, - Pixel_rgba p3, Pixel_rgba p4) - { - return avr(avr(p1, p2), avr(p3, p4)); - } -} __attribute__((packed)); - - -template -class Chunky_canvas : public Canvas -{ - protected: - - PT *_addr; /* base address of pixel buffer */ - - /** - * Utilities - */ - static inline int min(int a, int b) { return a < b ? a : b; } - static inline int max(int a, int b) { return a > b ? a : b; } - - public: - - /** - * Initialize canvas - */ - void init(PT *addr, long capacity) - { - _addr = addr; - _capacity = capacity; - _w = _h = 0; - _clip_x1 = _clip_y1 = 0; - _clip_x2 = _clip_y2 = 0; - } - - - /**************************************** - ** Implementation of Canvas interface ** - ****************************************/ - - void draw_box(int x1, int y1, int w, int h, Color color) - { - int x2 = x1 + w - 1; - int y2 = y1 + h - 1; - - /* check clipping */ - if (x1 < _clip_x1) x1 = _clip_x1; - if (y1 < _clip_y1) y1 = _clip_y1; - if (x2 > _clip_x2) x2 = _clip_x2; - if (y2 > _clip_y2) y2 = _clip_y2; - - if ((x1 > x2) || (y1 > y2)) return; - - PT pix(color.r, color.g, color.b); - PT *dst, *dst_line = _addr + _w*y1 + x1; - - int alpha = color.a; - - /* - * ??? - * - * Why can dst not be declared in the head of the inner for loop? - * Can I use the = operator for initializing a Pixel with a Color? - * - * ??? - */ - - if (alpha == Color::OPAQUE) - for (h = y2 - y1 + 1; h--; dst_line += _w) - for (dst = dst_line, w = x2 - x1 + 1; w--; dst++) - *dst = pix; - - else if (alpha != Color::TRANSPARENT) - for (h = y2 - y1 + 1; h--; dst_line += _w) - for (dst = dst_line, w = x2 - x1 + 1; w--; dst++) - *dst = PT::mix(*dst, pix, alpha); - } - - void draw_string(int x, int y, Font *font, Color color, const char *sstr, int len) - { - const unsigned char *str = (const unsigned char *)sstr; - - if (!str || !font) return; - - unsigned char *src = font->img; - int d, h = font->img_h; - - /* check top clipping */ - if ((d = _clip_y1 - y) > 0) { - src += d*font->img_w; - y += d; - h -= d; - } - - /* check bottom clipping */ - if ((d = y + h -1 - _clip_y2) > 0) - h -= d; - - if (h < 1) return; - - /* skip hidden glyphs */ - for ( ; *str && len && (x + font->wtab[*str] < _clip_x1); len--) - x += font->wtab[*str++]; - - PT *dst = _addr + y*_w; - PT pix(color.r, color.g, color.b); - int alpha = color.a; - - /* draw glyphs */ - for ( ; *str && len && (x <= _clip_x2); str++, len--) { - - int w = font->wtab[*str]; - int start = max(0, _clip_x1 - x); - int end = min(w - 1, _clip_x2 - x); - PT *d = dst + x; - unsigned char *s = src + font->otab[*str]; - - for (int j = 0; j < h; j++, s += font->img_w, d += _w) - for (int i = start; i <= end; i++) - if (s[i]) d[i] = PT::mix(d[i], pix, (alpha*s[i]) >> 8); - - x += w; - } - } - - void *addr() { return _addr; } - void addr(void *addr) { _addr = static_cast(addr); } - - Texture *alloc_texture(int w, int h); - void free_texture(Texture *texture); - void set_rgba_texture(Texture *dst, unsigned char *rgba, int len, int y); - void draw_texture(Texture *src, int x, int y); -}; - -#endif /* _CANVAS_H_ */ diff --git a/demo/src/app/scout/include/canvas_rgb565.h b/demo/src/app/scout/include/canvas_rgb565.h deleted file mode 100644 index 2d960b6ac..000000000 --- a/demo/src/app/scout/include/canvas_rgb565.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - * \brief Template specializations for the RGB565 pixel format - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CANVAS_RGB565_H_ -#define _CANVAS_RGB565_H_ - -#include "miscmath.h" -#include "canvas.h" -#include "alloc.h" - -typedef Pixel_rgba Pixel_rgb565; - - -template <> -inline Pixel_rgb565 Pixel_rgb565::blend(Pixel_rgb565 src, int alpha) -{ - Pixel_rgb565 res; - res.pixel = ((((alpha >> 3) * (src.pixel & 0xf81f)) >> 5) & 0xf81f) - | ((( alpha * (src.pixel & 0x07c0)) >> 8) & 0x07c0); - return res; -} - - -template <> -inline Pixel_rgb565 Pixel_rgb565::mix(Pixel_rgb565 p1, Pixel_rgb565 p2, int alpha) -{ - Pixel_rgba res; - - /* - * We substract the alpha from 264 instead of 255 to - * compensate the brightness loss caused by the rounding - * error of the blend function when having only 5 bits - * per channel. - */ - res.pixel = blend(p1, 264 - alpha).pixel + blend(p2, alpha).pixel; - return res; -} - - -template <> -inline Pixel_rgb565 Pixel_rgb565::avr(Pixel_rgb565 p1, Pixel_rgb565 p2) -{ - Pixel_rgb565 res; - res.pixel = ((p1.pixel&0xf7df)>>1) + ((p2.pixel&0xf7df)>>1); - return res; -} - - -static const int dither_size = 16; -static const int dither_mask = dither_size - 1; - -static const int dither_matrix[dither_size][dither_size] = { - { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, - { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, - { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, - { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, - { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, - { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, - { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, - { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, - { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, - { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, - { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, - { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, - { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, - { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, - { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, - { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } -}; - - -typedef Chunky_canvas Canvas_rgb565; - - -class Texture_rgb565 : public Canvas::Texture -{ - private: - - int _w, _h; /* size of texture */ - unsigned char *_alpha; /* alpha channel */ - Pixel_rgb565 *_pixel; /* pixel data */ - bool _preallocated; - - public: - - /** - * Constructor - */ - Texture_rgb565(int w, int h) - : - _w(w), _h(h), - _alpha((unsigned char *)scout_malloc(w*h)), - _pixel((Pixel_rgb565 *)scout_malloc(w*h*sizeof(Pixel_rgb565))), - _preallocated(false) - { } - - Texture_rgb565(Pixel_rgb565 *pixel, unsigned char *alpha, int w, int h): - _w(w), _h(h), _alpha(alpha), _pixel(pixel), _preallocated(true) { } - - /** - * Destructor - */ - ~Texture_rgb565() - { - if (!_preallocated) { - scout_free(_alpha); - scout_free(_pixel); - } - _w = _h = 0; - } - - /** - * Accessor functions - */ - inline unsigned char *alpha() { return _alpha; } - inline Pixel_rgb565 *pixel() { return _pixel; } - inline int w() { return _w; } - inline int h() { return _h; } - - /** - * Convert rgba data line to texture - */ - void rgba(unsigned char *rgba, int len, int y) - { - if (len > _w) len = _w; - if (y < 0 || y >= _h) return; - - int const *dm = dither_matrix[y & dither_mask]; - - Pixel_rgb565 *dst_pixel = _pixel + y*_w; - unsigned char *dst_alpha = _alpha + y*_w; - - for (int i = 0; i < len; i++) { - - int v = dm[i & dither_mask] >> 5; - int r = *rgba++ + v; - int g = *rgba++ + v; - int b = *rgba++ + v; - int a = *rgba++ + v; - - dst_pixel[i].rgba(min(r, 255), min(g, 255), min(b, 255)); - dst_alpha[i] = min(a, 255); - } - } -}; - - -template <> -inline Canvas::Texture *Canvas_rgb565::alloc_texture(int w, int h) -{ - return new Texture_rgb565(w, h); -} - - -template <> -inline void Canvas_rgb565::free_texture(Canvas::Texture *texture) -{ - if (texture) delete static_cast(texture); -} - - -template <> -inline void Canvas_rgb565::set_rgba_texture(Canvas::Texture *dst, - unsigned char *rgba, int len, int y) -{ - (static_cast(dst))->rgba(rgba, len, y); -} - - -template <> -inline void Canvas_rgb565::draw_texture(Texture *src_texture, int x1, int y1) -{ - Texture_rgb565 *src = static_cast(src_texture); - unsigned char *src_alpha = src->alpha(); - Pixel_rgb565 *src_pixel = src->pixel(); - - int x2 = x1 + src->w() - 1; - int y2 = y1 + src->h() - 1; - - /* right clipping */ - if (x2 > _clip_x2) - x2 = _clip_x2; - - /* bottom clipping */ - if (y2 > _clip_y2) - y2 = _clip_y2; - - /* left clipping */ - if (x1 < _clip_x1) { - src_alpha += _clip_x1 - x1; - src_pixel += _clip_x1 - x1; - x1 = _clip_x1; - } - - /* top clipping */ - if (y1 < _clip_y1) { - int offset = (_clip_y1 - y1)*src->w(); - src_alpha += offset; - src_pixel += offset; - y1 = _clip_y1; - } - - /* check if there is anything left */ - if (x1 > x2 || y1 > y2) return; - - int w = x2 - x1 + 1; - int h = y2 - y1 + 1; - - Pixel_rgb565 *dst_pixel = _addr + y1*_w + x1; - - for (int j = 0; j < h; j++) { - - Pixel_rgb565 *sp = src_pixel; - unsigned char *sa = src_alpha; - Pixel_rgb565 *d = dst_pixel; - - /* copy texture line */ - for (int i = 0; i < w; i++, sp++, sa++, d++) - *d = Pixel_rgb565::mix(*d, *sp, *sa); - - /* add line offsets to source texture and destination */ - src_pixel += src->w(); - src_alpha += src->w(); - dst_pixel += _w; - } -} - - -#endif /* _CANVAS_RGB565_ */ diff --git a/demo/src/app/scout/include/color.h b/demo/src/app/scout/include/color.h deleted file mode 100644 index f1cb2cbbc..000000000 --- a/demo/src/app/scout/include/color.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * \brief Color representation - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _COLOR_H_ -#define _COLOR_H_ - - -class Color -{ - public: - - enum { - TRANSPARENT = 0, - OPAQUE = 255 - }; - - int r, g, b, a; - - /** - * Constructors - */ - Color(int red, int green, int blue, int alpha = 255) - { - rgba(red, green, blue, alpha); - } - - Color() { rgba(0, 0, 0); } - - /** - * Convenience function: Assign rgba values - */ - inline void rgba(int red, int green, int blue, int alpha = 255) - { - r = red; - g = green; - b = blue; - a = alpha; - } -}; - - -#endif /* _COLOR_H_ */ diff --git a/demo/src/app/scout/include/elements.h b/demo/src/app/scout/include/elements.h deleted file mode 100644 index 0ef131f82..000000000 --- a/demo/src/app/scout/include/elements.h +++ /dev/null @@ -1,815 +0,0 @@ -/* - * \brief Document structure elements - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _ELEMENTS_H_ -#define _ELEMENTS_H_ - -#include "printf.h" -#include "string.h" -#include "canvas.h" -#include "event.h" -#include "color.h" -#include "fader.h" -#include "font.h" - - -/** - * Textual style - * - * A style describes the font, color and accentuations of tokens. - */ -class Style -{ - public: - - enum { - ATTR_BOLD = 0x1, - }; - - Font *font; - Color color; - int attr; - - Style(Font *f, Color c, int a) - { - font = f; - color = c; - attr = a; - } -}; - - -class Parent_element; -class Browser; - -class Element -{ - protected: - - int _x, _y; /* relative position managed by parent */ - int _w, _h; /* size managed by parent */ - int _min_w, _min_h; /* min size managed by element */ - Parent_element *_parent; /* parent in element hierarchy */ - Event_handler *_evh; /* event handler object */ - struct { - int mfocus : 1; /* element has mouse focus */ - int selected : 1; /* element has selected state */ - int takes_focus : 1; /* element highlights mouse focus */ - int link : 1; /* element is a link */ - int chapter : 1; /* display element as single page */ - int findable : 1; /* regard element in find function */ - int bottom : 1; /* place element to the bottom */ - } _flags; - - public: - - Element *next; /* managed by parent */ - - /** - * Constructor - */ - Element() - { - next = 0; - _parent = 0; - _min_w = 0; - _min_h = 0; - _x = _y = 0; - _w = _h = 0; - _evh = 0; - _flags.mfocus = _flags.selected = 0; - _flags.takes_focus = _flags.link = 0; - _flags.chapter = 0; - _flags.findable = 1; - _flags.bottom = 0; - } - - /** - * Destructor - */ - virtual ~Element(); - - /** - * Accessor functionse - */ - inline int min_w() { return _min_w; } - inline int min_h() { return _min_h; } - inline int x() { return _x; } - inline int y() { return _y; } - inline int w() { return _w; } - inline int h() { return _h; } - inline int is_link() { return _flags.link; } - inline int is_bottom() { return _flags.bottom; } - - inline void findable(int flag) { _flags.findable = flag; } - - /** - * Set geometry of the element - * - * This function should only be called by the immediate parent - * element. - */ - virtual void geometry(int x, int y, int w, int h) - { - _x = x; _y = y; _w = w; _h = h; - } - - /** - * Set/reset the mouse focus - */ - virtual void mfocus(int flag) - { - if ((_flags.mfocus == flag) || !_flags.takes_focus) return; - _flags.mfocus = flag; - refresh(); - } - - /** - * Define/request parent of an element - */ - inline void parent(Parent_element *parent) { _parent = parent; } - inline Parent_element *parent() { return _parent; } - - /** - * Define event handler object - */ - inline void event_handler(Event_handler *evh) { _evh = evh; } - - /** - * Check if element is completely clipped and draw it otherwise - */ - inline void try_draw(Canvas *c, int x, int y) - { - /* check if element is completely outside the clipping area */ - if ((_x + x > c->clip_x2()) || (_x + x + _w - 1 < c->clip_x1()) - || (_y + y > c->clip_y2()) || (_y + y + _h - 1 < c->clip_y1())) - return; - - /* call actual drawing function */ - draw(c, x, y); - } - - /** - * Format element and all child elements to specified width - */ - virtual void format_fixed_width(int w) { } - - /** - * Format element and all child elements to specified width and height - */ - virtual void format_fixed_size(int w, int h) { } - - /** - * Draw function - * - * This function must not be called directly. - * Instead, the function try_draw should be called. - */ - virtual void draw(Canvas *c, int x, int y) { } - - /** - * Find top-most element at specified position - * - * The default implementation can be used for elements without - * children. It just the element position and size against the - * specified position. - */ - virtual Element *find(int x, int y); - - /** - * Find the back-most element at specified y position - * - * This function is used to query a document element at - * the current scroll position of the window. This way, - * we can adjust the y position to the right value - * when we browse the history. - */ - virtual Element *find_by_y(int y); - - /** - * Request absolute position of an element - */ - int abs_x(); - int abs_y(); - - /** - * Update area of an element on screen - * - * We propagate the redraw request through the element hierarchy to - * the parent. The root parent should overwrite this function with - * a function that performs the actual redraw. - */ - virtual void redraw_area(int x, int y, int w, int h); - - /** - * Trigger the refresh of an element on screen - */ - inline void refresh() { redraw_area(0, 0, _w, _h); } - - /** - * Handle user input or timer event - */ - inline void handle_event(Event &ev) { if (_evh) _evh->handle(ev); } - - /** - * Request the chapter in which the element lives - */ - Element *chapter(); - - /** - * Request the browser in which the element lives - */ - virtual Browser *browser(); - - /** - * Fill image cache for element - */ - virtual void fill_cache(Canvas *c) { } - - /** - * Flush image cache for element - */ - virtual void flush_cache(Canvas *c) { } - - /** - * Propagate current link destination - * - * Elements that reference the specified link destination - * should give feedback. Other elements should ignore this - * function. - */ - virtual void curr_link_destination(Element *e) { } -}; - - -class Parent_element : public Element -{ - protected: - - Element *_first; - Element *_last; - - /** - * Format child element by a given width an horizontal offset - */ - int _format_children(int x, int w); - - public: - - /** - * Constructor - */ - Parent_element() { _first = _last = 0; } - - /** - * Adopt a child element - */ - void append(Element *e); - - /** - * Release child element from parent element - */ - void remove(Element *e); - - /** - * Dispose references to the specified element - * - * The element is not necessarily an immediate child but some element - * of the element-subtree. This function gets propagated to the root - * parent (e.g., user state manager), which can reset the mouse focus - * of the focused element vanishes. - */ - virtual void forget(Element *e); - - /** - * Element interface - */ - void draw(Canvas *c, int x, int y); - Element *find(int x, int y); - Element *find_by_y(int y); - void fill_cache(Canvas *c); - void flush_cache(Canvas *c); - void curr_link_destination(Element *e); - void geometry(int x, int y, int w, int h); -}; - - -/** - * String token - * - * A Token is a group of characters that are handled as an atomic text unit. - * Line wrapping is performed at the granularity of tokens. - */ -class Token : public Element -{ - protected: - - const char *_str; /* start of string */ - int _len; /* length of string */ - Style *_style; /* textual style */ - Color _col; /* current text color */ - Color _outline; /* outline color */ - - public: - - /** - * Constructor - */ - Token(Style *style, const char *str, int len); - - /** - * Element interface - */ - void draw(Canvas *c, int x, int y); - inline void refresh() { redraw_area(-1, 0, _w + 1, _h); } -}; - - -/** - * Link anchor - * - * An anchor marks a location within a document that can be addressed by a - * link. - */ -typedef Element Anchor; - - -/** - * Link that references an anchor within the document - */ -class Link -{ - protected: - - Anchor *_dst; /* link destination */ - - public: - - /** - * Constructor - */ - explicit Link(Anchor *dst) { _dst = dst; } - - /** - * Accessor function - */ - Anchor *dst() { return _dst; } -}; - - -/** - * Textual link - */ -class Link_token : public Token, public Link, public Event_handler, public Fader -{ - private: - - enum { _MAX_ALPHA = 50 }; - - public: - - /** - * Constructor - */ - Link_token(Style *style, const char *str, int len, Anchor *dst) - : Token(style, str, len), Link(dst) - { - _flags.takes_focus = 1; - _flags.link = 1; - _curr_value = 0; - event_handler(this); - } - - /** - * Element interface - */ - void draw(Canvas *c, int x, int y) - { - _outline.rgba(_style->color.r, - _style->color.g, - _style->color.b, _curr_value); - - ::Token::draw(c, x, y); - } - - void curr_link_destination(Element *dst) - { - if (dst == _dst && _curr_value != _MAX_ALPHA) - fade_to(_MAX_ALPHA, 50); - - if (dst != _dst && _curr_value != 0) - fade_to(0, 2); - } - - /** - * Event handler interface - */ - void handle(Event &e); - - /** - * Tick interface - */ - int on_tick() - { - /* call on_tick function of the fader */ - if (::Fader::on_tick() == 0) return 0; - - refresh(); - return 1; - } -}; - - -class Launchpad; -class Launcher_config; -class Launcher : public Anchor -{ - private: - - const char *_prg_name; /* null-terminated name of the program */ - int _active; - int _exec_once; - Launchpad *_launchpad; - unsigned long _quota; - Launcher_config *_config; - - public: - - /** - * Constructors - */ - Launcher(const char *prg_name, int exec_once = 0, - unsigned long quota = 0, Launcher_config *config = 0) : - _prg_name(prg_name), _active(1), - _exec_once(exec_once), _quota(quota), _config(config) { } - - Launcher(const char *prg_name, Launchpad *launchpad, - unsigned long quota, Launcher_config *config = 0) : - _prg_name(prg_name), _launchpad(launchpad), _quota(quota), - _config(config) { } - - int active() { return _active; } - - const char *prg_name() { return _prg_name; } - - void quota(unsigned long quota) { _quota = quota; } - - unsigned long quota() { return _quota; } - - Launcher_config *config() { return _config; } - - /** - * Launch program - */ - void launch(); -}; - - -/** - * Executable launcher link - * - * This is a special link that enables us to start external applications. - */ -class Launcher_link_token : public Link_token -{ - public: - - /** - * Constructor - */ - Launcher_link_token(Style *style, const char *str, int len, Launcher *l) - : Link_token(style, str, len, l) { } - - /** - * Event handler interface - */ - void handle(Event &e); -}; - - -/** - * Text block - * - * A block is a group of tokens that form a paragraph. A block layouts its - * tokens while using line wrapping. - */ -class Block : public Parent_element -{ - public: - - enum Alignment { LEFT, CENTER, RIGHT }; - enum Text_type { PLAIN, LINK, LAUNCHER }; - - private: - - int _second_indent; /* indentation of second line */ - Alignment _align; /* text alignment */ - - /** - * Append text to block - */ - void append_text(const char *str, Style *style, Text_type, - Anchor *a, Launcher *l); - - public: - - /** - * Constructors - */ - explicit Block(int second_indent = 0) - { - _align = LEFT; - _second_indent = second_indent; - } - - explicit Block(Alignment align) - { - _align = align; - _second_indent = 0; - } - - /** - * Define alignment of text - */ - void align(Alignment); - - /** - * Append a string of space-separated words - */ - void append_plaintext(const char *str, Style *style) - { - append_text(str, style, PLAIN, 0, 0); - } - - /** - * Append a string of space-separated words a link - * - * \param dst anchor that defines the link destination - */ - void append_linktext(const char *str, Style *style, Anchor *a) - { - append_text(str, style, LINK, a, 0); - } - - /** - * Append a string of space-separated words a launcher-link - */ - void append_launchertext(const char *str, Style *style, Launcher *l) - { - append_text(str, style, LAUNCHER, 0, l); - } - - /** - * Element interface - */ - void format_fixed_width(int w); -}; - - -/** - * Horizontally centered content - */ -class Center : public Parent_element -{ - public: - - /** - * Constructor - */ - explicit Center(Element *content = 0) - { - if (content) append(content); - } - - /** - * Element interface - */ - void format_fixed_width(int w); -}; - - -/** - * PNG Image - */ -class Png_image : public Element -{ - private: - - void *_png_data; - Canvas::Texture *_texture; - - public: - - /** - * Constructor - */ - explicit Png_image(void *png_data) - { - _png_data = png_data; - _texture = 0; - } - - /** - * Accessor functions - */ - inline void *png_data() { return _png_data; } - - /** - * Element interface - */ - void fill_cache(Canvas *c); - void flush_cache(Canvas *c); - void draw(Canvas *c, int x, int y); -}; - - -/** - * Document - */ -class Chapter; -class Document : public Parent_element -{ - public: - - Chapter *toc; /* table of contents */ - const char *title; /* document title */ - - /** - * Constructor - */ - Document() - { - toc = 0; title = ""; _flags.chapter = 1; - } - - /** - * Element interface - */ - void format_fixed_width(int w) - { - _min_h = _format_children(0, w); - _min_w = w; - } -}; - - -/** - * Chapter - */ -class Chapter : public Document { }; - - -/** - * Spacer - * - * A spacer is a place holder that consumes some screen space. It is used for - * tweaking the layout of the document. - */ -class Spacer : public Element -{ - public: - - /** - * Constructor - */ - Spacer(int w, int h) - { - _min_w = _w = w; - _min_h = _h = h; - } -}; - - -/** - * Verbatim text block - * - * A verbatim text block consists of a number of preformatted text lines. - * The text is printed in a monospaced font and the whole verbatim area - * has a shaded background. - */ -class Verbatim : public Parent_element -{ - public: - - Color bgcol; - - /** - * Constructor - */ - explicit Verbatim(Color bg) { bgcol = bg; } - - /** - * Append verbatim text line - */ - void append_textline(const char *str, Style *style) - { - append(new Token(style, str, strlen(str))); - } - - /** - * Element interface - */ - void draw(Canvas *c, int x, int y); - void format_fixed_width(int w); -}; - - -/** - * An iten consists of a item tag and a list of blocks - */ -class Item : public Parent_element -{ - public: - - int _tag_ident; - const char *_tag; - Style *_style; - - /** - * Constructor - */ - Item(Style *style, const char *str, int ident) - { - _style = style; - _tag = str; - _tag_ident = ident; - } - - /** - * Element interface - */ - void format_fixed_width(int w) - { - _min_h = _format_children(_tag_ident, w - _tag_ident); - _min_w = w; - } - - void draw(Canvas *c, int x, int y) - { - c->draw_string(_x + x, _y + y, _style->font, _style->color, _tag, 255); - Parent_element::draw(c, x, y); - } -}; - - -/** - * Document navigation bar - */ -class Generic_icon; -class Navbar : public Parent_element, public Fader -{ - private: - - Block *_next_title; - Block *_prev_title; - - Anchor *_next_anchor; - Anchor *_prev_anchor; - - public: - - /** - * These pointers must be initialized such that they - * point to valid Icon widgets that are used as graphics - * for the navigation bar. - */ - static Generic_icon *next_icon; - static Generic_icon *prev_icon; - static Generic_icon *nbox_icon; - static Generic_icon *pbox_icon; - - /** - * Constructor - */ - Navbar(); - - /** - * Define link to next and previous chapter - */ - void next_link(const char *title, Anchor *dst); - void prev_link(const char *title, Anchor *dst); - - /** - * Element interface - */ - void format_fixed_width(int w); - void draw(Canvas *c, int x, int y); - Element *find(int x, int y); - - /** - * Tick interface - */ - int on_tick(); -}; - -#endif /* _ELEMENTS_H_ */ diff --git a/demo/src/app/scout/include/font.h b/demo/src/app/scout/include/font.h deleted file mode 100644 index bc4e4b00f..000000000 --- a/demo/src/app/scout/include/font.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * \brief Font representation - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _FONT_H_ -#define _FONT_H_ - -#include "scout_types.h" - -class Font -{ - private: - - typedef scout_int32_t int32_t; - - public: - - unsigned char *img; /* font image */ - int img_w, img_h; /* size of font image */ - int32_t *wtab; /* width table */ - int32_t *otab; /* offset table */ - - /** - * Construct font from a TFF data block - */ - explicit Font(const char *tff) - { - otab = (int32_t *)(tff); - wtab = (int32_t *)(tff + 1024); - img_w = *((int32_t *)(tff + 2048)); - img_h = *((int32_t *)(tff + 2052)); - img = (unsigned char *)(tff + 2056); - } - - /** - * Calculate width of string when printed with the font - */ - int str_w(const char *sstr, int len) - { - const unsigned char *str = (const unsigned char *)sstr; - int res = 0; - for (; str && *str && len; len--, str++) res += wtab[*str]; - return res; - } - - /** - * Calculate height of string when printed with the font - */ - int str_h(const char *str, int len) { return img_h; } -}; - - -#endif /* _FONT_H_ */ diff --git a/demo/src/app/scout/include/genode/alloc.h b/demo/src/app/scout/include/genode/alloc.h deleted file mode 100644 index 9f18ca71f..000000000 --- a/demo/src/app/scout/include/genode/alloc.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * \brief Malloc/free wrappers for Genode - * \date 2008-07-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2008-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _GENODE_ALLOC_H_ -#define _GENODE_ALLOC_H_ - -#include - -static inline void *scout_malloc(unsigned long size) { - return Genode::env()->heap()->alloc(size); } - -static inline void scout_free(void *addr) { - - /* - * FIXME: We expect the heap to know the size of the - * block and thus, just specify zero as size. - */ - Genode::env()->heap()->free(addr, 0); } - -#endif diff --git a/demo/src/app/scout/include/genode/string.h b/demo/src/app/scout/include/genode/string.h deleted file mode 100644 index fcbba95e0..000000000 --- a/demo/src/app/scout/include/genode/string.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * \brief String function wrappers for Genode - * \date 2008-07-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2008-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _GENODE_STRING_H_ -#define _GENODE_STRING_H_ - -#include - -inline Genode::size_t strlen(const char *s) -{ return Genode::strlen(s); } - -inline void *memset(void *s, int c, Genode::size_t n) -{ return Genode::memset(s, c, n); } - -inline void *memcpy(void *dest, const void *src, Genode::size_t n) { -return Genode::memcpy(dest, src, n); } - -#endif diff --git a/demo/src/app/scout/include/miscmath.h b/demo/src/app/scout/include/miscmath.h deleted file mode 100644 index 36b5e517e..000000000 --- a/demo/src/app/scout/include/miscmath.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * \brief Misc math functions used here and there - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _MISCMATH_H_ -#define _MISCMATH_H_ - -/** - * Calc min/max of two numbers - */ -template static inline T min(T a, T b) { return a < b ? a : b; } -template static inline T max(T a, T b) { return a > b ? a : b; } - - -/** - * Produce pseudo random values - */ -static inline int random(void) -{ - static unsigned int seed = 93186752; - const unsigned int a = 1588635695, q = 2, r = 1117695901; - seed = a*(seed % q) - r*(seed / q); - return seed; -} - -#endif /* _MISCMATH_H_ */ diff --git a/demo/src/app/scout/include/platform.h b/demo/src/app/scout/include/platform.h deleted file mode 100644 index c86835c6a..000000000 --- a/demo/src/app/scout/include/platform.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * \brief Platform abstraction - * \date 2005-10-24 - * \author Norman Feske - * - * This interface specifies the target-platform-specific functions. - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _PLATFORM_H_ -#define _PLATFORM_H_ - -#include "event.h" - -/* - * We use two buffers, a foreground buffer that is displayed on screen and a - * back buffer. While the foreground buffer must contain valid data all the - * time, the back buffer can be used to prepare pixel data. For example, - * drawing multiple pixel layers with alpha channel must be done in the back - * buffer to avoid artifacts on the screen. - */ -class Screen_update -{ - public: - - virtual ~Screen_update() { } - - /** - * Request screen base address - */ - virtual void *scr_adr() = 0; - - /** - * Request back buffer address - */ - virtual void *buf_adr() { return scr_adr(); } - - /** - * Flip fore and back buffers - */ - virtual void flip_buf_scr() { } - - /** - * Copy background buffer to foreground - */ - virtual void copy_buf_to_scr(int x, int y, int w, int h) { } - - /** - * Flush pixels of specified screen area - */ - virtual void scr_update(int x, int y, int w, int h) = 0; -}; - - -class Platform : public Screen_update -{ - private: - - int _max_vw, _max_vh; /* maximum view size */ - - public: - - enum pixel_format { - UNDEFINED = 0, - RGB565 = 1, - }; - - /** - * Constructor - initialize platform - * - * \param vx,vy initial view position - * \param vw,vw initial view width and height - * \param max_vw maximum view width - * - * When using the default value for 'max_vw', the window's - * max width will correspond to the screen size. - */ - Platform(unsigned vx, unsigned vy, unsigned vw, unsigned vh, - unsigned max_vw = 0, unsigned max_vh = 0); - - /** - * Check initialization state of the platform - * - * \retval 1 platform was successfully initialized - * \retval 0 platform initialization failed - */ - int initialized(); - - /** - * Request screen width and height - */ - int scr_w(); - int scr_h(); - - /** - * Request pixel format - */ - pixel_format scr_pixel_format(); - - /** - * Define geometry of viewport on screen - * - * The specified area is relative to the screen - * of the platform. - */ - void view_geometry(int x, int y, int w, int h, int do_redraw = 0, - int buf_x = 0, int buf_y = 0); - - /** - * Bring Scouts view ontop - */ - void top_view(); - - /** - * View geometry accessor functions - */ - int vx(); - int vy(); - int vw(); - int vh(); - int vbx(); - int vby(); - - /** - * Get timer ticks in miilliseconds - */ - unsigned long timer_ticks(); - - /** - * Request if an event is pending - * - * \retval 1 event is pending - * \retval 0 no event pending - */ - int event_pending(); - - /** - * Request event - * - * \param e destination where to store event information. - * - * If there is no event pending, this function blocks - * until there is an event to deliver. - */ - void get_event(Event *out_e); - - /** - * Screen update interface - */ - void *scr_adr(); - void *buf_adr(); - void flip_buf_scr(); - void copy_buf_to_scr(int x, int y, int w, int h); - void scr_update(int x, int y, int w, int h); - -}; - -#endif /* _PLATFORM_H_ */ diff --git a/demo/src/app/scout/include/redraw_manager.h b/demo/src/app/scout/include/redraw_manager.h deleted file mode 100644 index dd8eb04b3..000000000 --- a/demo/src/app/scout/include/redraw_manager.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * \brief Simplistic redraw manager featuring redraw merging - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _REDRAW_MANAGER_H_ -#define _REDRAW_MANAGER_H_ - -#include "elements.h" - -class Redraw_manager -{ - private: - - int _x1, _y1; /* upper left pixel of dirty area */ - int _x2, _y2; /* lower right pixel of dirty area */ - int _cnt; /* nb of requests since last process */ - Element *_root; /* root element for drawing */ - Canvas *_canvas; /* graphics backend */ - Screen_update *_scr_update; /* flushing pixels in backend */ - int _w, _h; /* current size of output window */ - bool _scout_quirk; /* enable redraw quirk for scout */ - - public: - - /** - * Constructor - */ - Redraw_manager(Canvas *canvas, Screen_update *scr_update, int w, int h, - bool scout_quirk = false) - : - _cnt(0), _root(0), _canvas(canvas), _scr_update(scr_update), _w(w), _h(h), - _scout_quirk(scout_quirk) - { } - - /** - * Accessor functions - */ - inline Canvas *canvas() { return _canvas; } - - /** - * Define root element for issueing drawing operations - */ - inline void root(Element *root) { _root = root; } - - /** - * Collect redraw requests - */ - void request(int x, int y, int w, int h) - { - /* - * Scout redraw quirk - * - * Quick fix to avoid artifacts at the icon bar. - * The icon bar must always be drawn completely - * because of the interaction of the different - * layers. - */ - if (_scout_quirk && y < 64 + 32) { - h = max(h + y, 64 + 32); - w = _w; - x = 0; - y = 0; - } - - /* first request since last process operation */ - if (_cnt == 0) { - _x1 = x; _x2 = x + w - 1; - _y1 = y; _y2 = y + h - 1; - - /* merge subsequencing requests */ - } else { - _x1 = min(_x1, x); _x2 = max(_x2, x + w - 1); - _y1 = min(_y1, y); _y2 = max(_y2, y + h - 1); - } - _cnt++; - } - - /** - * Define size of visible redraw window - */ - void size(int w, int h) - { - if (w > _canvas->w()) - w = _canvas->w(); - - if (h > _canvas->h()) - h = _canvas->h(); - - _w = w; _h = h; - } - - /** - * Process redrawing operations - */ - void process() - { - if (_cnt == 0 || !_canvas || !_root) return; - - /* get actual drawing area (clipped against canvas dimensions) */ - int x1 = max(0, _x1); - int y1 = max(0, _y1); - int x2 = min(_w - 1, _x2); - int y2 = min(_h - 1, _y2); - - if (x1 > x2 || y1 > y2) return; - - _canvas->clip(x1, y1, x2 - x1 + 1, y2 - y1 + 1); - - /* draw browser window into back buffer */ - _root->try_draw(_canvas, 0, 0); - - /* - * If we draw the whole area, we can flip the front - * and back buffers instead of copying pixels from the - * back to the front buffer. - */ - - /* detemine if the whole area must be drawn */ - if (x1 == 0 && x2 == _root->w() - 1 - && y1 == 0 && y2 == _root->h() - 1) { - - /* flip back end front buffers */ - _scr_update->flip_buf_scr(); - - /* apply future drawing operations on new back buffer */ - _canvas->addr(_scr_update->buf_adr()); - - } else - _scr_update->copy_buf_to_scr(x1, y1, x2 - x1 + 1, y2 - y1 + 1); - - /* give notification about changed canvas area */ - if (_scr_update) - _scr_update->scr_update(x1, y1, x2 - x1 + 1, y2 - y1 + 1); - - /* reset request state */ - _cnt = 0; - } -}; - - -#endif /* _REDRAW_MANAGER_H_ */ diff --git a/demo/src/app/scout/include/scout_types.h b/demo/src/app/scout/include/scout_types.h deleted file mode 100644 index 0c7fa7a36..000000000 --- a/demo/src/app/scout/include/scout_types.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * \brief Platform-dependent definition of fixed-size integer types - * \author Norman Feske - * \date 2009-04-15 - */ - -/* - * Copyright (C) 2009-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _SCOUT_TYPES_H_ -#define _SCOUT_TYPES_H_ - -#include - -typedef Genode::int32_t scout_int32_t; - -#endif /* _SCOUT_TYPES_H_ */ diff --git a/demo/src/app/scout/include/styles.h b/demo/src/app/scout/include/styles.h deleted file mode 100644 index 1e16a3cdb..000000000 --- a/demo/src/app/scout/include/styles.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * \brief Document styles - * \date 2005-10-24 - * \author Norman Feske - */ - -/* - * Copyright (C) 2005-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _STYLES_H_ -#define _STYLES_H_ - -extern char _binary_mono16_tff_start[]; -extern char _binary_verabi10_tff_start[]; -extern char _binary_vera16_tff_start[]; -extern char _binary_verai16_tff_start[]; -extern char _binary_vera18_tff_start[]; -//extern char _binary_cour14_tff_start[]; -//extern char _binary_newy14_tff_start[]; -//extern char _binary_helv14_tff_start[]; -extern char _binary_vera20_tff_start[]; -extern char _binary_vera24_tff_start[]; - -//Font default_font (&_binary_helv14_tff_start[0]); -static Font label_font (&_binary_verabi10_tff_start[0]); -static Font default_font (&_binary_vera16_tff_start[0]); -static Font italic_font (&_binary_verai16_tff_start[0]); -static Font mono_font (&_binary_mono16_tff_start[0]); -static Font chapter_font (&_binary_vera24_tff_start[0]); -static Font section_font (&_binary_vera20_tff_start[0]); -static Font subsection_font (&_binary_vera18_tff_start[0]); - -static Color default_color (0, 0, 0); -static Color text_color (20, 20, 20); -static Color verbatim_bgcol (0, 0, 0, 26); - -static Style plain_style (&default_font, text_color, 0); -static Style bold_style (&default_font, text_color, Style::ATTR_BOLD); -static Style mono_style (&mono_font, text_color, 0); -static Style italic_style (&italic_font, text_color, 0); - -static Style link_style (&default_font, Color(0, 0, 255), 0); - -static Style chapter_style (&chapter_font, default_color, 0); -static Style section_style (§ion_font, default_color, 0); -static Style subsection_style (&subsection_font, default_color, 0); -static Style navbar_style (&default_font, Color(0, 0, 0, 127), 0); - -#endif /* _STYLES_H_ */ diff --git a/demo/src/app/scout/include/window.h b/demo/src/app/scout/include/window.h deleted file mode 100644 index 383fdd8b9..000000000 --- a/demo/src/app/scout/include/window.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * \brief Window interface - * \author Norman Feske - * \date 2006-08-30 - */ - -/* - * Copyright (C) 2006-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _WINDOW_H_ -#define _WINDOW_H_ - -#include "elements.h" -#include "platform.h" -#include "redraw_manager.h" - - -/********************** - ** Window interface ** - **********************/ - -class Window : public Parent_element -{ - private: - - Platform *_pf; - int _max_w; /* max width of window */ - int _max_h; /* max height of window */ - Redraw_manager *_redraw; /* redraw manager */ - - public: - - Window(Platform *pf, Redraw_manager *redraw, int max_w, int max_h) - : - _pf(pf), _max_w(max_w), _max_h(max_h), _redraw(redraw) - { - /* init element attributes */ - _x = _y = 0; - _w = pf->vw(); - _h = pf->vh(); - } - - virtual ~Window() { } - - /** - * Return current window position - */ - virtual int view_x() { return _pf->vx(); } - virtual int view_y() { return _pf->vy(); } - virtual int view_w() { return _pf->vw(); } - virtual int view_h() { return _pf->vh(); } - - /** - * Accessors - */ - Platform *pf() { return _pf; } - int max_w() { return _max_w; } - int max_h() { return _max_h; } - Redraw_manager *redraw() { return _redraw; } - - /** - * Bring window to front - */ - virtual void top() { _pf->top_view(); } - - /** - * Move window to new position - */ - virtual void vpos(int x, int y) { - _pf->view_geometry(x, y, _pf->vw(), _pf->vh(), 1, _pf->vbx(), _pf->vby()); } - - /** - * Define vertical scroll offset - */ - virtual void ypos(int ypos) { } - virtual int ypos() { return 0; } - - /** - * Format window - */ - virtual void format(int w, int h) { } - - /** - * Element interface - * - * This function just collects the specified regions to be - * redrawn but does not perform any immediate drawing - * operation. The actual drawing must be initiated by - * calling the process_redraw function. - */ - void redraw_area(int x, int y, int w, int h) { - _redraw->request(x, y, w, h); } -}; - - -/******************** - ** Event handlers ** - ********************/ - -class Drag_event_handler : public Event_handler -{ - protected: - - int _key_cnt; /* number of curr. pressed keys */ - int _cmx, _cmy; /* original mouse position */ - int _omx, _omy; /* current mouse positon */ - - virtual void start_drag() = 0; - virtual void do_drag() = 0; - - public: - - /** - * Constructor - */ - Drag_event_handler() { _key_cnt = 0; } - - /** - * Event handler interface - */ - void handle(Event &ev) - { - if (ev.type == Event::PRESS) _key_cnt++; - if (ev.type == Event::RELEASE) _key_cnt--; - - if (_key_cnt == 0) return; - - /* first click starts dragging */ - if ((ev.type == Event::PRESS) && (_key_cnt == 1)) { - _cmx = _omx = ev.mx; - _cmy = _omy = ev.my; - start_drag(); - } - - /* check if mouse was moved */ - if ((ev.mx == _cmx) && (ev.my == _cmy)) return; - - /* remember current mouse position */ - _cmx = ev.mx; - _cmy = ev.my; - - do_drag(); - } -}; - - -class Sizer_event_handler : public Drag_event_handler -{ - protected: - - Window *_window; - int _obw, _obh; /* original window size */ - - /** - * Event handler interface - */ - void start_drag() - { - _obw = _window->view_w(); - _obh = _window->view_h(); - } - - void do_drag() - { - /* calculate new window size */ - int nbw = _obw + _cmx - _omx; - int nbh = _obh + _cmy - _omy; - - _window->format(nbw, nbh); - } - - public: - - /** - * Constructor - */ - Sizer_event_handler(Window *window) - { - _window = window; - } -}; - - -class Mover_event_handler : public Drag_event_handler -{ - protected: - - Window *_window; - int _obx, _oby; /* original launchpad position */ - - void start_drag() - { - _obx = _window->view_x(); - _oby = _window->view_y(); - _window->top(); - } - - void do_drag() - { - int nbx = _obx + _cmx - _omx; - int nby = _oby + _cmy - _omy; - - _window->vpos(nbx, nby); - } - - public: - - /** - * Constructor - */ - Mover_event_handler(Window *window) - { - _window = window; - } -}; - - -#endif diff --git a/demo/src/app/scout/genode/launcher.cc b/demo/src/app/scout/launcher.cc similarity index 99% rename from demo/src/app/scout/genode/launcher.cc rename to demo/src/app/scout/launcher.cc index 1dbcaf2b5..01b204ecd 100644 --- a/demo/src/app/scout/genode/launcher.cc +++ b/demo/src/app/scout/launcher.cc @@ -22,6 +22,7 @@ static Launchpad launchpad(Genode::env()->ram_session()->quota()); using namespace Genode; +using namespace Scout; /********************************************** diff --git a/demo/src/app/scout/include/genode/launcher_config.h b/demo/src/app/scout/launcher_config.h similarity index 80% rename from demo/src/app/scout/include/genode/launcher_config.h rename to demo/src/app/scout/launcher_config.h index d3d6462dd..06b025207 100644 --- a/demo/src/app/scout/include/genode/launcher_config.h +++ b/demo/src/app/scout/launcher_config.h @@ -13,12 +13,14 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _SCOUT__GENODE__LAUNCHER_CONFIG__ -#define _SCOUT__GENODE__LAUNCHER_CONFIG__ +#ifndef _LAUNCHER_CONFIG_ +#define _LAUNCHER_CONFIG_ #include -class Launcher_config +namespace Scout { class Launcher_config; } + +class Scout::Launcher_config { private: @@ -35,4 +37,4 @@ class Launcher_config Genode::Dataspace_capability config_ds() { return _config_ds; } }; -#endif /* _SCOUT__GENODE__LAUNCHER_CONFIG__ */ +#endif /* _LAUNCHER_CONFIG_ */ diff --git a/demo/src/app/scout/common/main.cc b/demo/src/app/scout/main.cc similarity index 53% rename from demo/src/app/scout/common/main.cc rename to demo/src/app/scout/main.cc index 947f8f066..aa26dab9f 100644 --- a/demo/src/app/scout/common/main.cc +++ b/demo/src/app/scout/main.cc @@ -11,32 +11,28 @@ * under the terms of the GNU General Public License version 2. */ -/** - * Local includes - */ +#include +#include +#include +#include + #include "config.h" #include "elements.h" -#include "platform.h" -#include "canvas_rgb565.h" #include "fade_icon.h" -#include "tick.h" -#include "redraw_manager.h" -#include "user_state.h" #include "browser_window.h" -extern Document *create_document(); +extern Scout::Document *create_document(); /** * Runtime configuration */ -namespace Config -{ +namespace Scout { namespace Config { int iconbar_detail = 1; int background_detail = 1; int mouse_cursor = 1; int browser_attr = 0; -} +} } #define POINTER_RGBA _binary_pointer_rgba_start @@ -48,7 +44,8 @@ extern unsigned char NAV_NEXT_RGBA[]; extern unsigned char NAV_PREV_RGBA[]; static unsigned char *navicons_rgba[] = { NAV_NEXT_RGBA, NAV_PREV_RGBA }; -static Generic_icon **navicons[] = { &Navbar::next_icon, &Navbar::prev_icon }; +static Scout::Generic_icon **navicons[] = { &Scout::Navbar::next_icon, + &Scout::Navbar::prev_icon }; extern int native_startup(int, char **); @@ -58,10 +55,20 @@ extern int native_startup(int, char **); */ int main(int argc, char **argv) { - if (native_startup(argc, argv)) return -1; + using namespace Scout; - /* init platform */ - static Platform pf(256, 80, 530, 620); + static Nitpicker::Connection nitpicker; + static Platform pf(*nitpicker.input()); + + Area const max_size(530, 620); + Point const initial_position(256, 80); + Area const initial_size(530, 400); + + Config::mouse_cursor = 0; + Config::browser_attr = 7; + + static Nitpicker_graphics_backend + graphics_backend(nitpicker, max_size, initial_position, initial_size); /* initialize icons for navigation bar */ for (unsigned int i = 0; i < sizeof(navicons)/sizeof(void *); i++) { @@ -73,31 +80,22 @@ int main(int argc, char **argv) static Document *doc = create_document(); - /* init canvas */ - static Chunky_canvas canvas; - canvas.init(static_cast(pf.buf_adr()), - pf.scr_w()*pf.scr_h()); - canvas.set_size(pf.scr_w(), pf.scr_h()); - canvas.clip(0, 0, pf.scr_w(), pf.scr_h()); - - /* init redraw manager */ - static Redraw_manager redraw(&canvas, &pf, pf.vw(), pf.vh(), true); - /* create instance of browser window */ static Browser_window browser ( - doc, /* initial document */ - &pf, /* platform */ - &redraw, /* redraw manager object */ - pf.scr_w(), pf.scr_h(), /* max size of window */ + doc, + graphics_backend, + initial_position, + initial_size, + max_size, Config::browser_attr ); /* initialize mouse cursor */ - int mx = 0, my = 0; + Point mouse_position; static Icon mcursor; if (Config::mouse_cursor) { - mcursor.geometry(mx, my, 32, 32); + mcursor.geometry(Rect(mouse_position, Area(32, 32))); mcursor.rgba(POINTER_RGBA); mcursor.alpha(255); mcursor.findable(0); @@ -105,43 +103,38 @@ int main(int argc, char **argv) } /* create user state manager */ - static User_state user_state(&browser, &browser, pf.vx(), pf.vy()); - - /* assign browser as root element to redraw manager */ - redraw.root(&browser); - + static User_state user_state(&browser, &browser, + initial_position.x(), initial_position.y()); browser.ypos(0); /* enter main loop */ - Event ev; unsigned long curr_time, old_time; curr_time = old_time = pf.timer_ticks(); - do { - pf.get_event(&ev); + for (;;) { + Event ev = pf.get_event(); if (ev.type != Event::WHEEL) { - ev.mx -= user_state.vx(); - ev.my -= user_state.vy(); + ev.mouse_position = ev.mouse_position - user_state.view_position(); /* update mouse cursor */ - if (Config::mouse_cursor && (ev.mx != mx || ev.my != my)) { - int x1 = min(ev.mx, mx); - int y1 = min(ev.my, my); - int x2 = max(ev.mx + mcursor.w() - 1, mx + mcursor.w() - 1); - int y2 = max(ev.my + mcursor.h() - 1, my + mcursor.h() - 1); + if (Config::mouse_cursor && (ev.mouse_position.x() != mouse_position.x() + || ev.mouse_position.y() != mouse_position.y())) { + int x1 = min(ev.mouse_position.x(), mouse_position.x()); + int y1 = min(ev.mouse_position.y(), mouse_position.y()); + int x2 = max(ev.mouse_position.x() + mcursor.size().w() - 1, + mouse_position.x() + mcursor.size().w() - 1); + int y2 = max(ev.mouse_position.y() + mcursor.size().h() - 1, + mouse_position.y() + mcursor.size().h() - 1); - mcursor.geometry(ev.mx, ev.my, mcursor.w(), mcursor.h()); - redraw.request(x1, y1, x2 - x1 + 1, y2 - y1 + 1); + mcursor.geometry(Rect(ev.mouse_position, mcursor.size())); + browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1); - mx = ev.mx; my = ev.my; + mouse_position = ev.mouse_position; } } user_state.handle_event(ev); - if (ev.type == Event::REFRESH) - pf.scr_update(0, 0, pf.scr_w(), pf.scr_h()); - if (ev.type == Event::TIMER) Tick::handle(pf.timer_ticks()); @@ -149,10 +142,12 @@ int main(int argc, char **argv) curr_time = pf.timer_ticks(); if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) { old_time = curr_time; - redraw.process(); + browser.process_redraw(); } - } while (ev.type != Event::QUIT); + if (ev.type == Event::QUIT) + break; + } return 0; } diff --git a/demo/src/app/scout/common/navbar.cc b/demo/src/app/scout/navbar.cc similarity index 60% rename from demo/src/app/scout/common/navbar.cc rename to demo/src/app/scout/navbar.cc index 33c47dca5..5b247dd2a 100644 --- a/demo/src/app/scout/common/navbar.cc +++ b/demo/src/app/scout/navbar.cc @@ -13,10 +13,11 @@ #include "elements.h" #include "widgets.h" -#include "canvas_rgb565.h" #include "styles.h" #include "browser.h" +using namespace Scout; + /** * Configuration @@ -61,7 +62,11 @@ class Linkicon_event_handler : public Event_handler { if (ev.type != Event::PRESS || !_navbar) return; - Browser *b = _navbar->browser(); + /* lookup browser, in which the link token resides */ + Browser *b = 0; + for (Element *e = _navbar; e && !b; e = e->parent()) + b = dynamic_cast(e); + if (!b || !_dst) return; _navbar->curr(0); @@ -117,12 +122,12 @@ void Navbar::format_fixed_width(int w) if (_prev_title) _prev_title->format_fixed_width(text_w); /* determine right-alignment offset for right label */ - int next_dx = _next_title ? text_w - _next_title->min_w() : 0; + int next_dx = _next_title ? text_w - _next_title->min_size().w() : 0; /* determine bounding box of navbar */ - int h = ARROW_H; - if (_next_title) h = max(h, _next_title->min_h()); - if (_prev_title) h = max(h, _prev_title->min_h()); + unsigned h = ARROW_H; + if (_next_title) h = max(h, _next_title->min_size().h()); + if (_prev_title) h = max(h, _prev_title->min_size().h()); h += 16; /* assign icons to this navbar instance */ @@ -137,52 +142,55 @@ void Navbar::format_fixed_width(int w) /* place icons */ int ypos = (h - ARROW_H)/2; - next_icon->geometry(w - 64, ypos, ARROW_W, ARROW_H); - prev_icon->geometry(0, ypos, ARROW_W, ARROW_H); + next_icon->geometry(Rect(Point(w - 64, ypos), Area(ARROW_W, ARROW_H))); + prev_icon->geometry(Rect(Point(0, ypos), Area(ARROW_W, ARROW_H))); /* place labels */ if (_next_title) { - ypos = (h - _next_title->min_h())/2 + 1; - _next_title->geometry(w/2 + padx + next_dx, ypos, text_w, _next_title->min_h()); + ypos = (h - _next_title->min_size().h())/2 + 1; + _next_title->geometry(Rect(Point(w/2 + padx + next_dx, ypos), + Area(text_w, _next_title->min_size().h()))); } if (_prev_title) { - ypos = (h - _prev_title->min_h())/2 + 1; - _prev_title->geometry(ARROW_W, ypos, text_w, _prev_title->min_h()); + ypos = (h - _prev_title->min_size().h())/2 + 1; + _prev_title->geometry(Rect(Point(ARROW_W, ypos), + Area(text_w, _prev_title->min_size().h()))); } - _min_w = w; - _min_h = h; + _min_size = Scout::Area(w, h); } -void Navbar::draw(Canvas *c, int x, int y) +void Navbar::draw(Canvas_base &canvas, Point abs_position) { - int cx1 = c->clip_x1(), cy1 = c->clip_y1(); - int cx2 = c->clip_x2(), cy2 = c->clip_y2(); + int cx1 = canvas.clip().x1(), cy1 = canvas.clip().y1(); + int cx2 = canvas.clip().x2(), cy2 = canvas.clip().y2(); /* shrink clipping area to text area (cut too long words) */ - int nx1 = max(cx1, _x + x + ARROW_W); - int ny1 = max(cy1, _y + y); - int nx2 = min(cx2, nx1 + _w - 2*ARROW_W); - int ny2 = min(cy2, ny1 + _h); + int nx1 = max(cx1, _position.x() + abs_position.x() + ARROW_W); + int ny1 = max(cy1, _position.y() + abs_position.y()); + int nx2 = min(cx2, nx1 + (int)_size.w() - 2*ARROW_W); + int ny2 = min(cy2, ny1 + (int)_size.h()); - c->clip(nx1, ny1, nx2 - nx1 + 1, ny2 - ny1 + 1); - Parent_element::draw(c, x, y); - c->clip(cx1, cy1, cx2 - cx1 + 1, cy2 - cy1 + 1); + canvas.clip(Rect(Point(nx1, ny1), Area(nx2 - nx1 + 1, ny2 - ny1 + 1))); + Parent_element::draw(canvas, abs_position); + canvas.clip(Rect(Point(cx1, cy1), Area(cx2 - cx1 + 1, cy2 - cy1 + 1))); - if (_prev_title) prev_icon->draw(c, _x + x, _y + y); - if (_next_title) next_icon->draw(c, _x + x, _y + y); + if (_prev_title) prev_icon->draw(canvas, abs_position + _position); + if (_next_title) next_icon->draw(canvas, abs_position + _position); } -Element *Navbar::find(int x, int y) +Element *Navbar::find(Point position) { Element *res; - if (_prev_title && (res = prev_icon->find(x - _x, y - _y))) return res; - if (_next_title && (res = next_icon->find(x - _x, y - _y))) return res; + position = position - _position; - return ::Parent_element::find(x, y); + if (_prev_title && (res = prev_icon->find(position))) return res; + if (_next_title && (res = next_icon->find(position))) return res; + + return Parent_element::find(position); } @@ -193,7 +201,7 @@ int Navbar::on_tick() prev_icon->alpha(_curr_value); next_icon->alpha(_curr_value); - navbar_style.color.rgba(0, 0, 0, _curr_value); + navbar_style.color = Color(0, 0, 0, _curr_value); refresh(); return 1; diff --git a/demo/src/app/scout/common/png_image.cc b/demo/src/app/scout/png_image.cc similarity index 76% rename from demo/src/app/scout/common/png_image.cc rename to demo/src/app/scout/png_image.cc index f8ef2d2af..846a82c9a 100644 --- a/demo/src/app/scout/common/png_image.cc +++ b/demo/src/app/scout/png_image.cc @@ -13,9 +13,12 @@ #include -#include "miscmath.h" +#include +#include + #include "elements.h" -#include "alloc.h" + +using namespace Scout; class Png_stream @@ -36,7 +39,7 @@ class Png_stream */ void read(char *dst, int len) { - memcpy(dst, _addr, len); + Scout::memcpy(dst, _addr, len); _addr += len; } }; @@ -67,7 +70,7 @@ extern "C" int l4libpng_fread(void *buf, int size, int nmemb, void *stream) ** Element interface ** ***********************/ -void Png_image::fill_cache(Canvas *c) +void Png_image::fill_cache(Canvas_base &canvas) { if (_texture) return; @@ -92,9 +95,9 @@ void Png_image::fill_cache(Canvas *c) png_uint_32 w, h; png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL); - _min_w = w; - _min_h = h; - printf("png is %d x %d, depth=%d\n", _min_w, _min_h, bit_depth); + + _min_size = Scout::Area(w, h); + printf("png is %d x %d, depth=%d\n", _min_size.w(), _min_size.h(), bit_depth); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); @@ -108,7 +111,7 @@ void Png_image::fill_cache(Canvas *c) if (bit_depth < 8) png_set_packing(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); - _texture = c->alloc_texture(_min_w, _min_h); + _texture = canvas.alloc_texture(_min_size, true); /* allocate buffer for decoding a row */ static png_byte *row_ptr; @@ -117,32 +120,32 @@ void Png_image::fill_cache(Canvas *c) int needed_row_size = png_get_rowbytes(png_ptr, info_ptr)*8; if (curr_row_size < needed_row_size) { - if (row_ptr) scout_free(row_ptr); - row_ptr = (png_byte *)scout_malloc(needed_row_size); + if (row_ptr) Scout::free(row_ptr); + row_ptr = (png_byte *)Scout::malloc(needed_row_size); curr_row_size = needed_row_size; } /* fill texture */ - for (int j = 0; j < _min_h; j++) { + for (unsigned j = 0; j < _min_size.h(); j++) { png_read_row(png_ptr, row_ptr, NULL); - c->set_rgba_texture(_texture, (unsigned char *)row_ptr, _min_w, j); + canvas.set_rgba_texture(_texture, (unsigned char *)row_ptr, _min_size.w(), j); } } -void Png_image::flush_cache(Canvas *c) +void Png_image::flush_cache(Canvas_base &canvas) { - c->free_texture(_texture); + canvas.free_texture(_texture); _texture = 0; } -void Png_image::draw(Canvas *c, int x, int y) +void Png_image::draw(Canvas_base &canvas, Point abs_position) { /* if texture is not ready, try to initialize it */ - if (!_texture) fill_cache(c); + if (!_texture) fill_cache(canvas); /* draw texture */ if (_texture) - c->draw_texture(_texture, x + _x, y + _y); + canvas.draw_texture(abs_position + _position, *_texture); } diff --git a/demo/src/app/scout/include/refracted_icon.h b/demo/src/app/scout/refracted_icon.h similarity index 54% rename from demo/src/app/scout/include/refracted_icon.h rename to demo/src/app/scout/refracted_icon.h index ea107f6b6..9332189a2 100644 --- a/demo/src/app/scout/include/refracted_icon.h +++ b/demo/src/app/scout/refracted_icon.h @@ -14,14 +14,19 @@ #ifndef _REFRACTED_ICON_H_ #define _REFRACTED_ICON_H_ +#include + #include "widgets.h" +namespace Scout { template class Refracted_icon; } + + /** * \param PT pixel type (must be Pixel_rgba compatible) * \param DT distortion map entry type */ template -class Refracted_icon : public Element +class Scout::Refracted_icon : public Element { private: @@ -48,7 +53,36 @@ class Refracted_icon : public Element /** * Scratch refraction map */ - void scratch(int jitter); + void scratch(int jitter) + { + PT ref_color = _fg[0]; + for (int j = 0; j < _distmap_h; j++) for (int i = 0; i < _distmap_w; i++) { + + int fg_offset = (j>>1)*(_distmap_w>>1) + (i>>1); + + int dr = _fg[fg_offset].r() - ref_color.r(); + int dg = _fg[fg_offset].g() - ref_color.g(); + int db = _fg[fg_offset].b() - ref_color.b(); + + if (dr < 0) dr = -dr; + if (dg < 0) dg = -dg; + if (db < 0) db = -db; + + static const int limit = 20; + if (dr > limit || dg > limit || db > limit) continue; + + int dx, dy; + + do { + using Scout::random; + dx = jitter ? ((random()%jitter) - (jitter>>1)) : 0; + dy = jitter ? ((random()%jitter) - (jitter>>1)) : 0; + } while ((dx < -i) || (dx > _distmap_w - 2 - i) + || (dy < -j) || (dy > _distmap_h - 2 - j)); + + _distmap[j*_distmap_w + i] += dy*_distmap_w + dx; + } + } /** * Define distortion map for the icon @@ -69,8 +103,17 @@ class Refracted_icon : public Element _fg_alpha = fg_alpha; } - void draw(Canvas *c, int px, int py); + void draw(Canvas_base &canvas, Point abs_position) + { + Scout::Refracted_icon_painter::Distmap + distmap(_distmap, Area(_distmap_w, _distmap_h)); + + Texture tmp(_backbuf, 0, Area(_distmap_w, _distmap_h)); + Texture fg(_fg, _fg_alpha, Area(_distmap_w/2, _distmap_h/2)); + + canvas.draw_refracted_icon(_position + abs_position, distmap, tmp, fg, + Config::iconbar_detail, _filter_backbuf); + } }; - #endif /* _REFRACTED_H_ */ diff --git a/demo/src/app/scout/common/scrollbar.cc b/demo/src/app/scout/scrollbar.cc similarity index 86% rename from demo/src/app/scout/common/scrollbar.cc rename to demo/src/app/scout/scrollbar.cc index 41f2a772f..d04a7a5fd 100644 --- a/demo/src/app/scout/common/scrollbar.cc +++ b/demo/src/app/scout/scrollbar.cc @@ -11,8 +11,11 @@ * under the terms of the GNU General Public License version 2. */ +#include + #include "scrollbar.h" -#include "tick.h" + +using namespace Scout; #define SLIDER_RGBA _binary_slider_rgba_start #define UPARROW_RGBA _binary_uparrow_rgba_start @@ -179,7 +182,7 @@ class Slider_event_handler : public Event_handler _icon->rgba(_rgba, 1, 3); _icon->refresh(); - orig_my = curr_my = ev.my; + orig_my = curr_my = ev.mouse_position.y(); orig_slider_pos = _sb->slider_pos(); } @@ -190,8 +193,8 @@ class Slider_event_handler : public Event_handler _icon->refresh(); } - if (key_cnt && (ev.my != curr_my)) { - curr_my = ev.my; + if (key_cnt && (ev.mouse_position.y() != curr_my)) { + curr_my = ev.mouse_position.y(); _sb->slider_pos(orig_slider_pos + curr_my - orig_my); _sb->notify_listener(); } @@ -219,8 +222,7 @@ Scrollbar::Scrollbar() append(&_dnarrow); append(&_slider); - _min_w = sb_elem_w; - _min_h = sb_elem_h*3; + _min_size = Area(sb_elem_w, sb_elem_h*3); _real_size = 100; _view_size = 100; @@ -238,7 +240,7 @@ Scrollbar::Scrollbar() template int Scrollbar::slider_size() { - return max(sb_elem_h, ((_h - sb_elem_h*2)*_view_size)/_real_size); + return max((unsigned)sb_elem_h, ((_size.h() - sb_elem_h*2)*_view_size)/_real_size); } @@ -246,7 +248,7 @@ template int Scrollbar::slider_pos() { int real_range = _real_size - _view_size; - int slider_range = _h - sb_elem_h*2 - slider_size(); + int slider_range = _size.h() - sb_elem_h*2 - slider_size(); int pos = real_range ? (slider_range*_view_pos)/real_range : 0; return pos + sb_elem_h; @@ -256,12 +258,12 @@ int Scrollbar::slider_pos() template void Scrollbar::slider_pos(int pos) { - int slider_bg_h = _h - sb_elem_h*2; + int slider_bg_h = _size.h() - sb_elem_h*2; _view_pos = ((pos - sb_elem_h)*_real_size)/slider_bg_h; _view_pos = max(0, min(_view_pos, _real_size - _view_size)); - _slider.geometry(0, slider_pos(), sb_elem_w, slider_size()); + _slider.geometry(Rect(Point(0, slider_pos()), Area(sb_elem_w, slider_size()))); } @@ -272,7 +274,7 @@ void Scrollbar::view(int real_size, int view_size, int view_pos) _view_size = min(view_size, real_size); _view_pos = max(0, min(view_pos, _real_size - _view_size)); - geometry(_x, _y, _w, _h); + geometry(Rect(_position, _size)); } @@ -289,16 +291,18 @@ void Scrollbar::notify_listener() ***********************/ template -void Scrollbar::geometry(int x, int y, int w, int h) +void Scrollbar::geometry(Rect rect) { - Element::geometry(x, y, w, h); + Element::geometry(rect); int new_visibility = _visible(); if (new_visibility) { - _uparrow.geometry(0, 0, sb_elem_w, sb_elem_h); - _dnarrow.geometry(0, h - sb_elem_h, sb_elem_w, sb_elem_h); - _slider. geometry(0, slider_pos(), sb_elem_w, slider_size()); + _uparrow.geometry(Rect(Point(0, 0), Area(sb_elem_w, sb_elem_h))); + _dnarrow.geometry(Rect(Point(0, rect.h() - sb_elem_h), + Area(sb_elem_w, sb_elem_h))); + _slider. geometry(Rect(Point(0, slider_pos()), + Area(sb_elem_w, slider_size()))); } if (_visibility ^ new_visibility) { @@ -314,14 +318,13 @@ void Scrollbar::geometry(int x, int y, int w, int h) template -Element *Scrollbar::find(int x, int y) +Element *Scrollbar::find(Point position) { if (_visibility) - return Parent_element::find(x, y); + return Parent_element::find(position); return 0; } -#include "canvas_rgb565.h" -template class Scrollbar; +template class Scrollbar; diff --git a/demo/src/app/scout/include/scrollbar.h b/demo/src/app/scout/scrollbar.h similarity index 90% rename from demo/src/app/scout/include/scrollbar.h rename to demo/src/app/scout/scrollbar.h index 60c8e5631..4fe891eed 100644 --- a/demo/src/app/scout/include/scrollbar.h +++ b/demo/src/app/scout/scrollbar.h @@ -17,8 +17,13 @@ #include "widgets.h" #include "fade_icon.h" +namespace Scout { + class Scrollbar_listener; + template class Scrollbar; +} -class Scrollbar_listener + +class Scout::Scrollbar_listener { public: @@ -32,7 +37,7 @@ class Scrollbar_listener template -class Scrollbar : public Parent_element +class Scout::Scrollbar : public Parent_element { public: @@ -94,12 +99,12 @@ class Scrollbar : public Parent_element /** * Set geometry of scrollbar and layout scrollbar elements */ - void geometry(int x, int y, int w, int h); + void geometry(Rect); /** * Element interface */ - Element *find(int x, int y); + Element *find(Point); }; diff --git a/demo/src/app/scout/include/sky_texture.h b/demo/src/app/scout/sky_texture.h similarity index 58% rename from demo/src/app/scout/include/sky_texture.h rename to demo/src/app/scout/sky_texture.h index 49bf45b1f..882c67fe3 100644 --- a/demo/src/app/scout/include/sky_texture.h +++ b/demo/src/app/scout/sky_texture.h @@ -14,7 +14,12 @@ #ifndef _SKY_TEXTURE_H_ #define _SKY_TEXTURE_H_ +#include + #include "widgets.h" +#include "config.h" + +namespace Scout { template class Sky_texture; } /** @@ -23,21 +28,19 @@ * \param TH tile height */ template -class Sky_texture : public Texture +class Scout::Sky_texture : public Element { private: - short _bufs[3][TH][TW]; - short _buf[TH][TW]; - short _tmp[TH][TW]; - PT _coltab[16*16*16]; - PT _fallback[TH][TW]; /* fallback texture */ + Sky_texture_painter::Static_sky_texture _sky_texture; public: - Sky_texture(); - - void draw(Canvas *c, int px, int py); + void draw(Canvas_base &canvas, Point abs_position) + { + canvas.draw_sky_texture(abs_position.y(), _sky_texture, + Config::background_detail); + } }; #endif /* _SKY_TEXTURE_H_ */ diff --git a/demo/src/app/scout/styles.h b/demo/src/app/scout/styles.h new file mode 100644 index 000000000..56ed9c964 --- /dev/null +++ b/demo/src/app/scout/styles.h @@ -0,0 +1,54 @@ +/* + * \brief Document styles + * \date 2005-10-24 + * \author Norman Feske + */ + +/* + * Copyright (C) 2005-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _STYLES_H_ +#define _STYLES_H_ + +#include "elements.h" + +extern char _binary_mono16_tff_start[]; +extern char _binary_verabi10_tff_start[]; +extern char _binary_vera16_tff_start[]; +extern char _binary_verai16_tff_start[]; +extern char _binary_vera18_tff_start[]; +extern char _binary_vera20_tff_start[]; +extern char _binary_vera24_tff_start[]; + +namespace Scout { + + static Font label_font (&_binary_verabi10_tff_start[0]); + static Font default_font (&_binary_vera16_tff_start[0]); + static Font italic_font (&_binary_verai16_tff_start[0]); + static Font mono_font (&_binary_mono16_tff_start[0]); + static Font chapter_font (&_binary_vera24_tff_start[0]); + static Font section_font (&_binary_vera20_tff_start[0]); + static Font subsection_font (&_binary_vera18_tff_start[0]); + + static Color default_color (0, 0, 0); + static Color text_color (20, 20, 20); + static Color verbatim_bgcol (0, 0, 0, 26); + + static Style plain_style (&default_font, text_color, 0); + static Style bold_style (&default_font, text_color, Style::ATTR_BOLD); + static Style mono_style (&mono_font, text_color, 0); + static Style italic_style (&italic_font, text_color, 0); + + static Style link_style (&default_font, Color(0, 0, 255), 0); + + static Style chapter_style (&chapter_font, default_color, 0); + static Style section_style (§ion_font, default_color, 0); + static Style subsection_style (&subsection_font, default_color, 0); + static Style navbar_style (&default_font, Color(0, 0, 0, 127), 0); +} + +#endif /* _STYLES_H_ */ diff --git a/demo/src/app/scout/genode/target.mk b/demo/src/app/scout/target.mk similarity index 85% rename from demo/src/app/scout/genode/target.mk rename to demo/src/app/scout/target.mk index 3955624fd..ae9286507 100644 --- a/demo/src/app/scout/genode/target.mk +++ b/demo/src/app/scout/target.mk @@ -7,10 +7,8 @@ SRC_CC = main.cc doc.cc \ CC_OPT += -DPNG_USER_CONFIG -INC_DIR = $(PRG_DIR)/../include $(PRG_DIR)/../include/genode - -vpath % $(PRG_DIR)/../data -vpath %.cc $(PRG_DIR)/../common +vpath % $(PRG_DIR)/data +vpath %.cc $(PRG_DIR) SRC_BIN += cover.rgba \ forward.rgba \ diff --git a/demo/src/app/scout/common/tick.cc b/demo/src/app/scout/tick.cc similarity index 97% rename from demo/src/app/scout/common/tick.cc rename to demo/src/app/scout/tick.cc index 05b3cc173..22e173a00 100644 --- a/demo/src/app/scout/common/tick.cc +++ b/demo/src/app/scout/tick.cc @@ -11,8 +11,11 @@ * under the terms of the GNU General Public License version 2. */ -#include "tick.h" -#include "printf.h" +#include +#include + +using namespace Scout; + static Tick *head = 0; /* head of tick list */ static Tick::time now = 0; /* recent time (updated by handle function) */ diff --git a/demo/src/app/scout/include/titlebar.h b/demo/src/app/scout/titlebar.h similarity index 61% rename from demo/src/app/scout/include/titlebar.h rename to demo/src/app/scout/titlebar.h index ffbcbce72..46339102b 100644 --- a/demo/src/app/scout/include/titlebar.h +++ b/demo/src/app/scout/titlebar.h @@ -19,15 +19,13 @@ #define TITLE_TFF _binary_vera18_tff_start extern char TITLE_TFF[]; +namespace Scout { template class Titlebar; } -/*************** - ** Title bar ** - ***************/ -static Font title_font(TITLE_TFF); +static Scout::Font title_font(TITLE_TFF); template -class Titlebar : public Parent_element +class Scout::Titlebar : public Parent_element { private: @@ -71,20 +69,21 @@ class Titlebar : public Parent_element void format_fixed_width(int w) { - _min_w = w; - _min_h = 32; - _fg.geometry(0, 0, _min_w, _min_h); + _min_size = Area(w, 32); + _fg.geometry(Rect(Point(0, 0), _min_size)); } - void draw(Canvas *c, int x, int y) + void draw(Canvas_base &canvas, Point abs_position) { const int b = 180, a = 200; - c->draw_box(x + _x, y + _y, _w, _h, Color(b, b, b, a)); + canvas.draw_box(abs_position.x() + _position.x(), + abs_position.y() + _position.y(), + _size.w(), _size.h(), Color(b, b, b, a)); - int _txt_x = x + _x + max((_w - _txt_w)/2, 8); - int _txt_y = y + _y + max((_h - _txt_h)/2, 0) - 1; - c->draw_string(_txt_x , _txt_y, &title_font, Color(0,0,0,200), _txt, strlen(_txt)); - ::Parent_element::draw(c, x, y); + int _txt_x = abs_position.x() + _position.x() + max((_size.w() - _txt_w)/2, 8UL); + int _txt_y = abs_position.y() + _position.y() + max((_size.h() - _txt_h)/2, 0UL) - 1; + canvas.draw_string(_txt_x , _txt_y, &title_font, Color(0,0,0,200), _txt, strlen(_txt)); + Parent_element::draw(canvas, abs_position); } }; diff --git a/demo/src/app/scout/widgets.cc b/demo/src/app/scout/widgets.cc new file mode 100644 index 000000000..426fbf01b --- /dev/null +++ b/demo/src/app/scout/widgets.cc @@ -0,0 +1,206 @@ +/* + * \brief GUI elements + * \date 2005-10-24 + * \author Norman Feske + */ + +/* + * Copyright (C) 2005-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +#include "widgets.h" + +using namespace Scout; + + +/************* + ** Docview ** + *************/ + +void Docview::format_fixed_width(int w) +{ + _min_size = Area(0, 0); + + if (_cont) { + _cont->format_fixed_width(w - 2*_padx - _right_pad); + _min_size = Area(w, _voffset + _cont->min_size().h()); + } + + if (_bg) + _bg->geometry(Rect(Point(0, 0), _min_size)); +} + + +void Docview::draw(Canvas_base &canvas, Point abs_position) +{ + if (_bg) _bg->draw(canvas, _position + abs_position); + if (_cont) _cont->draw(canvas, _position + abs_position); +} + + +Element *Docview::find(Point position) +{ + if (!Element::find(position)) return 0; + Element *res = _cont ? _cont->find(position - _position) : 0; + return res ? res : this; +} + + +void Docview::geometry(Rect rect) +{ + Element::geometry(rect); + + if (_cont) + _cont->geometry(Rect(Point(_padx, _voffset), + Area(_cont->min_size().w(), rect.h() - _voffset))); +} + + +/*********************** + ** Horizontal shadow ** + ***********************/ + +template +void Horizontal_shadow::draw(Canvas_base &canvas, Point abs_position) +{ + canvas.draw_horizontal_shadow(Rect(abs_position + _position, _size), INTENSITY); +} + + +/********** + ** Icon ** + **********/ + +template +Icon::Icon() +{ + memset(_pixel, 0, sizeof(_pixel)); + memset(_alpha, 0, sizeof(_alpha)); + memset(_shadow, 0, sizeof(_shadow)); + _icon_alpha = 255; +} + + +template +void Icon::rgba(unsigned char *src, int vshift, int shadow) +{ + /* convert rgba values to pixel type and alpha channel */ + for (int j = 0; j < H; j++) + for (int i = 0; i < W; i++, src += 4) { + _pixel[j][i].rgba(src[0], src[1], src[2]); + _alpha[j][i] = src[3]; + } + + /* handle special case of no shadow */ + if (shadow == 0) return; + + /* generate shadow shape from blurred alpha channel */ + for (int j = 1; j < H - 4; j++) + for (int i = 1; i < W - 2; i++) { + int v = 0; + for (int k = -1; k <= 1; k++) + for (int l = -1; l <=1; l++) + v += _alpha[(j + k + H)%H][(i + l + W)%W]; + + _shadow[j + 3][i] = v>>shadow; + } + + /* shift vertically */ + if (vshift > 0) + for (int j = H - 1; j >= vshift; j--) + for (int i = 0; i < W; i++) { + _pixel[j][i] = _pixel[j - vshift][i]; + _alpha[j][i] = _alpha[j - vshift][i]; + } + + /* apply shadow to pixels */ + PT shcol(0, 0, 0); + for (int j = 0; j < H; j++) + for (int i = 0; i < W; i++) { + _pixel[j][i] = PT::mix(shcol, _pixel[j][i], _alpha[j][i]); + _alpha[j][i] = min(255, _alpha[j][i] + _shadow[j][i]); + } +} + + +static inline void blur(unsigned char *src, unsigned char *dst, int w, int h) +{ + const int kernel = 3; + int scale = (kernel*2 + 1)*(kernel*2 + 1); + + scale = (scale*210)>>8; + for (int j = kernel; j < h - kernel; j++) + for (int i = kernel; i < w - kernel; i++) { + int v = 0; + for (int k = -kernel; k <= kernel; k++) + for (int l = -kernel; l <= kernel; l++) + v += src[w*(j + k) + (i + l)]; + + dst[w*j + i] = min(v/scale, 255); + } +} + + +template +void Icon::glow(unsigned char *src, Color c) +{ + /* extract shape from alpha channel of rgba source image */ + for (int j = 0; j < H; j++) + for (int i = 0; i < W; i++, src += 4) + _alpha[j][i] = src[3] ? 255 : 0; + + for (int i = 0; i < 2; i++) { + blur(_alpha[0], _shadow[0], W, H); + blur(_shadow[0], _alpha[0], W, H); + } + + /* assign pixels and alpha */ + PT s(c.r, c.g, c.b); + for (int j = 0; j < H; j++) + for (int i = 0; i < W; i++, src += 4) + _pixel[j][i] = s; +} + + +template +void Icon::draw(Canvas_base &canvas, Point abs_position) +{ + Texture texture(_pixel[0], _alpha[0], Area(W, H)); + canvas.draw_icon(Rect(abs_position + _position, _size), texture, _icon_alpha); +} + + +template +Element *Icon::find(Point position) +{ + if (!Element::find(position)) return 0; + + position = position - _position; + + /* check icon boundaries (the height is flexible) */ + if ((position.x() < 0) || (position.x() >= W) + || (position.y() < 0) || (position.y() >= (int)_size.h())) return 0; + + /* upper part of the icon */ + if (position.y() <= H/2) return _alpha[position.y()][position.x()] ? this : 0; + + /* lower part of the icon */ + if (position.y() > (int)_size.h() - H/2) + return _alpha[position.y() - _size.h() + H][position.x()] ? this : 0; + + /* middle part of the icon */ + if (_alpha[H/2][position.x()]) return this; + + return 0; +} + +template class Horizontal_shadow; +template class Horizontal_shadow; +template class Icon; +template class Icon; +template class Icon; diff --git a/demo/src/app/scout/include/widgets.h b/demo/src/app/scout/widgets.h similarity index 74% rename from demo/src/app/scout/include/widgets.h rename to demo/src/app/scout/widgets.h index e28a316a3..4f906dd4d 100644 --- a/demo/src/app/scout/include/widgets.h +++ b/demo/src/app/scout/widgets.h @@ -16,15 +16,19 @@ #include "elements.h" - -class Texture : public Element { }; +namespace Scout { + class Docview; + template class Horizontal_shadow; + class Generic_icon; + template class Icon; +} -class Docview : public Parent_element +class Scout::Docview : public Parent_element { private: - Texture *_bg; + Element *_bg; Element *_cont; int _voffset; int _right_pad; @@ -35,7 +39,7 @@ class Docview : public Parent_element /** * Constructor */ - explicit Docview(int padx = 7): + explicit Docview(int padx = 7) : _bg(0), _cont(0), _voffset(0), _right_pad(0), _padx(padx) { } /** @@ -58,7 +62,7 @@ class Docview : public Parent_element /** * Define background texture */ - inline void texture(Texture *bg) { _bg = bg; } + inline void texture(Element *bg) { _bg = bg; } /** * Define right padding @@ -68,30 +72,31 @@ class Docview : public Parent_element /** * Element interface */ - void format_fixed_width(int w); - void draw(Canvas *c, int x, int y); - Element *find(int x, int y); - void geometry(int x, int y, int w, int h); + void format_fixed_width(int); + void draw(Canvas_base &, Point); + Element *find(Point); + void geometry(Rect); }; template -class Horizontal_shadow : public Element +struct Scout::Horizontal_shadow : Element { - public: + explicit Horizontal_shadow(int height = 8) + { + _min_size = Area(0, height); + } - explicit Horizontal_shadow(int height = 8) { _min_h = height; } - - /** - * Element interface - */ - void draw(Canvas *c, int x, int y); - Element *find(int x, int y) { return 0; } - void format_fixed_width(int w) { _min_w = w; } + /** + * Element interface + */ + void draw(Canvas_base &, Point); + Element *find(Point) { return 0; } + void format_fixed_width(int w) { _min_size = Area(w, _min_size.h()); } }; -class Generic_icon : public Element +class Scout::Generic_icon : public Element { public: @@ -108,7 +113,7 @@ class Generic_icon : public Element template -class Icon : public Generic_icon +class Scout::Icon : public Generic_icon { private: @@ -157,8 +162,8 @@ class Icon : public Generic_icon /** * Element interface */ - void draw(Canvas *c, int x, int y); - Element *find(int x, int y); + void draw(Canvas_base &, Point); + Element *find(Point); }; diff --git a/demo/src/lib/scout_gfx/sky_texture_painter.cc b/demo/src/lib/scout_gfx/sky_texture_painter.cc new file mode 100644 index 000000000..6ffa8b96d --- /dev/null +++ b/demo/src/lib/scout_gfx/sky_texture_painter.cc @@ -0,0 +1,172 @@ +/* + * \brief Functor for drawing a sky texture into a surface + * \author Norman Feske + * \date 2005-10-24 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include + +/** + * Calculate fractional part of texture position for a given coordinate + */ +static inline int calc_u(int x, int w, int texture_w) +{ + return ((texture_w*x<<8)/w) & 0xff; +} + + +/** + * Cubic interpolation + * + * \param u relative position between x1 and x2 (0..255) + */ +static inline int filter(int x0, int x1, int x2, int x3, int u) +{ + static int cached_u = -1; + static int k0, k1, k2, k3; + + /* + * Do not recompute coefficients when called + * with the same subsequencing u values. + */ + if (u != cached_u) { + + int v = 255 - u; + int uuu = (u*u*u)>>16; + int vvv = (v*v*v)>>16; + int uu = (u*u)>>8; + int vv = (v*v)>>8; + + k0 = vvv/6; + k3 = uuu/6; + k1 = k3*3 - uu + (4<<8)/6; + k2 = k0*3 - vv + (4<<8)/6; + + cached_u = u; + } + + return (x0*k0 + x1*k1 + x2*k2 + x3*k3)>>8; +} + + +/** + * Determine texture position by given position in image + */ +static inline int get_idx(int x, int w, int texture_w, int offset) +{ + return (offset + texture_w + (texture_w*x)/w) % texture_w; +} + + +/** + * Generate sky texture based on bicubic interpolation of some noise + */ +static void gen_buf(short tmp[], int noise_w, int noise_h, + short dst[], int dst_w, int dst_h) +{ + /* generate noise */ + for (int i = 0; i < noise_h; i++) for (int j = 0; j < noise_w; j++) + dst[i*dst_w + j] = Scout::random()%256 - 128; + + /* interpolate horizontally */ + for (int j = dst_w - 1; j >= 0; j--) { + + int x0_idx = get_idx(j, dst_w, noise_w, -1); + int x1_idx = get_idx(j, dst_w, noise_w, 0); + int x2_idx = get_idx(j, dst_w, noise_w, 1); + int x3_idx = get_idx(j, dst_w, noise_w, 2); + int u = calc_u(j, dst_w, noise_w); + + for (int i = 0; i < noise_h; i++) { + + int x0 = dst[i*dst_w + x0_idx]; + int x1 = dst[i*dst_w + x1_idx]; + int x2 = dst[i*dst_w + x2_idx]; + int x3 = dst[i*dst_w + x3_idx]; + + tmp[i*dst_w + j] = filter(x0, x1, x2, x3, u); + } + } + + /* vertical interpolation */ + for (int i = dst_h - 1; i >= 0; i--) { + + int y0_idx = get_idx(i, dst_h, noise_h, -1)*dst_w; + int y1_idx = get_idx(i, dst_h, noise_h, 0)*dst_w; + int y2_idx = get_idx(i, dst_h, noise_h, 1)*dst_w; + int y3_idx = get_idx(i, dst_h, noise_h, 2)*dst_w; + int u = calc_u(i, dst_h, noise_h); + + for (int j = 0; j < dst_w; j++) { + + int y0 = tmp[y0_idx + j]; + int y1 = tmp[y1_idx + j]; + int y2 = tmp[y2_idx + j]; + int y3 = tmp[y3_idx + j]; + + dst[i*dst_w + j] = filter(y0, y1, y2, y3, u); + } + } +} +/** + * Normalize buffer values to specified maximum + */ +static void normalize_buf(short dst[], int len, int amp) +{ + int min = 0x7ffffff, max = 0; + + for (int i = 0; i < len; i++) { + if (dst[i] < min) min = dst[i]; + if (dst[i] > max) max = dst[i]; + } + + if (max == min) return; + + for (int i = 0; i < len; i++) + dst[i] = (amp*(dst[i] - min))/(max - min); +} + + +/** + * Add each pair of values of two buffers + */ +static void add_bufs(short src1[], short src2[], short dst[], int len) +{ + for (int i = 0; i < len; i++) + dst[i] = src1[i] + src2[i]; +} + +/** + * We combine (add) multiple low-frequency textures with one high-frequency + * texture to get nice shapes. + */ +void Sky_texture_painter::Sky_texture_base::_brew_texture +( + short tmp[], short tmp2[], short dst[], int w, int h, + int lf_start, int lf_end, int lf_incr, int lf_mul, + int hf_val, int hf_mul +) +{ + for (int i = lf_start; i < lf_end; i += lf_incr) { + gen_buf(tmp, i, i, tmp2, w, h); + _multiply_buf(tmp2, w*h, (lf_mul - i)*32); + add_bufs(tmp2, dst, dst, w*h); + } + if (hf_val) { + gen_buf(tmp, hf_val, hf_val, tmp2, w, h); + _multiply_buf(tmp2, w*h, hf_mul*32); + add_bufs(tmp2, dst, dst, w*h); + } + + /* normalize texture to use four bits */ + normalize_buf(dst, w*h, 15); +} + diff --git a/demo/src/server/liquid_framebuffer/framebuffer_window.h b/demo/src/server/liquid_framebuffer/framebuffer_window.h index 2f2f4e908..993314ad7 100644 --- a/demo/src/server/liquid_framebuffer/framebuffer_window.h +++ b/demo/src/server/liquid_framebuffer/framebuffer_window.h @@ -14,7 +14,8 @@ #ifndef _FRAMEBUFFER_WINDOW_H_ #define _FRAMEBUFFER_WINDOW_H_ -#include "window.h" +#include + #include "titlebar.h" #include "sky_texture.h" #include "fade_icon.h" @@ -27,7 +28,7 @@ extern unsigned char SIZER_RGBA[]; template -class Framebuffer_window : public Window +class Framebuffer_window : public Scout::Window { private: @@ -39,29 +40,34 @@ class Framebuffer_window : public Window /** * Widgets */ - Titlebar _titlebar; - Sky_texture _bg_texture; - int _bg_offset; - Fade_icon _sizer; - Element *_content; - bool _config_alpha; - bool _config_resize_handle; - bool _config_decoration; + Scout::Titlebar _titlebar; + Scout::Sky_texture _bg_texture; + int _bg_offset; + Scout::Fade_icon _sizer; + Scout::Element *_content; + bool _config_alpha; + bool _config_resize_handle; + bool _config_decoration; public: /** * Constructor */ - Framebuffer_window(Platform *pf, - Redraw_manager *redraw, - Element *content, - const char *name, - bool config_alpha, - bool config_resize_handle, - bool config_decoration) + Framebuffer_window(Scout::Graphics_backend &gfx_backend, + Scout::Element *content, + Scout::Point position, + Scout::Area size, + Scout::Area max_size, + char const *name, + bool config_alpha, + bool config_resize_handle, + bool config_decoration) : - Window(pf, redraw, content->min_w() + 2, content->min_h() + 1 + _TH), + Scout::Window(gfx_backend, position, + Scout::Area(content->min_size().w() + 2, + content->min_size().h() + 1 + _TH), + max_size, false), _bg_offset(0), _content(content), _config_alpha(config_alpha), _config_resize_handle(config_resize_handle), _config_decoration(config_decoration) @@ -69,11 +75,11 @@ class Framebuffer_window : public Window /* titlebar */ _titlebar.rgba(TITLEBAR_RGBA); _titlebar.text(name); - _titlebar.event_handler(new Mover_event_handler(this)); + _titlebar.event_handler(new Scout::Mover_event_handler(this)); /* resize handle */ _sizer.rgba(SIZER_RGBA); - _sizer.event_handler(new Sizer_event_handler(this)); + _sizer.event_handler(new Scout::Sizer_event_handler(this)); _sizer.alpha(100); if (config_decoration) @@ -84,8 +90,9 @@ class Framebuffer_window : public Window if (config_resize_handle) append(&_sizer); - _min_w = 1 + 32 + 1; /* left border + resize handle + right border */ - _min_h = _TH + 32 + 1; /* title bar + resize handle + bottom border */ + unsigned const BORDER = 1, TITLE = _TH, RESIZER = 32; + _min_size = Scout::Area(BORDER + RESIZER + BORDER, + BORDER + TITLE + RESIZER + BORDER); } /** @@ -131,7 +138,7 @@ class Framebuffer_window : public Window void vpos(int x, int y) { Window::vpos(x, y); - format(_w, _h); + format(_size); } /** @@ -140,43 +147,47 @@ class Framebuffer_window : public Window void content_geometry(int x, int y, int w, int h) { Window::vpos(x, y); - format(w + 2, h + 1 + _TH); + format(Scout::Area(w + 2, h + 1 + _TH)); } /** * Window interface */ - void format(int w, int h) + void format(Scout::Area size) { + using namespace Scout; + + unsigned w = size.w(); + unsigned h = size.h(); + /* limit window size to valid values */ - w = (w < _min_w) ? _min_w : w; - h = (h < _min_h) ? _min_h : h; - w = (w > max_w()) ? max_w() : w; - h = (h > max_h()) ? max_h() : h; - _w = w; - _h = h; + w = max(w, min_size().w()); + h = max(h, min_size().h()); + w = min(w, max_size().w()); + h = min(h, max_size().h()); + + _size = Scout::Area(w, h); int y = 0; _titlebar.format_fixed_width(w); - _titlebar.geometry(1, y, _titlebar.min_w(), _titlebar.min_h()); - y += _titlebar.min_h(); + _titlebar.geometry(Rect(Point(1, y), + Area(_titlebar.min_size().w(), + _titlebar.min_size().h()))); + y += _titlebar.min_size().h(); - int const content_h = (h > y + 1) ? (h - y - 1) : 0; + int const content_h = ((int)h > y + 1) ? (h - y - 1) : 0; int const content_w = w - 2; - _content->format_fixed_size(content_w, content_h); - _content->geometry(1, y, content_w, content_h); + _content->format_fixed_size(Area(content_w, content_h)); + _content->geometry(Rect(Point(1, y), Area(content_w, content_h))); - _sizer.geometry(_w - 32, _h - 32, 32, 32); - - pf()->top_view(); + _sizer.geometry(Rect(Point(_size.w() - 32, _size.h() - 32), Area(32, 32))); if (_config_decoration) - pf()->view_geometry(pf()->vx(), pf()->vy(), _w, _h); + Window::format(_size); else - pf()->view_geometry(pf()->vx(), pf()->vy(), - _w - 2, _h - 1 - _TH, false, -1, -_TH); - redraw()->size(_w, _h); + Window::format(Area(_size.w() - 2, _size.h() - 1 - _TH)); + refresh(); } @@ -188,20 +199,22 @@ class Framebuffer_window : public Window /** * Element interface */ - void draw(Canvas *c, int x, int y) + void draw(Scout::Canvas_base &canvas, Scout::Point abs_position) { - if (_config_alpha) - _bg_texture.draw(c, 0, - _bg_offset); + using namespace Scout; - ::Parent_element::draw(c, x, y); + if (_config_alpha) + _bg_texture.draw(canvas, Point(0, - _bg_offset)); + + Parent_element::draw(canvas, abs_position); /* border */ - Color col(0, 0, 0); - c->draw_box(0, 0, _w, 1, col); - c->draw_box(0, _TH, _w, 1, col); - c->draw_box(0, _h - 1, _w, 1, col); - c->draw_box(0, 1, 1, _h - 2, col); - c->draw_box(_w - 1, 1, 1, _h - 2, col); + Color color(0, 0, 0); + canvas.draw_box(0, 0, _size.w(), 1, color); + canvas.draw_box(0, _TH, _size.w(), 1, color); + canvas.draw_box(0, _size.h() - 1, _size.w(), 1, color); + canvas.draw_box(0, 1, 1, _size.h() - 2, color); + canvas.draw_box(_size.w() - 1, 1, 1, _size.h() - 2, color); }; }; diff --git a/demo/src/server/liquid_framebuffer/main.cc b/demo/src/server/liquid_framebuffer/main.cc index 6c02eef05..954fad1e9 100644 --- a/demo/src/server/liquid_framebuffer/main.cc +++ b/demo/src/server/liquid_framebuffer/main.cc @@ -15,44 +15,42 @@ #include #include #include +#include +#include #include "framebuffer_window.h" -#include "canvas_rgb565.h" -#include "user_state.h" #include "services.h" -using namespace Genode; /** * Runtime configuration */ -namespace Config +namespace Scout { namespace Config { int iconbar_detail = 1; int background_detail = 1; int mouse_cursor = 1; int browser_attr = 0; -} +} } -void Launcher::launch() { } - -extern int native_startup(int, char **); +void Scout::Launcher::launch() { } -class Background_animator : public Tick +class Background_animator : public Scout::Tick { private: - Framebuffer_window *_fb_win; - int _bg_offset; + Framebuffer_window *_fb_win; + + int _bg_offset; public: /** * Constructor */ - Background_animator(Framebuffer_window *fb_win): + Background_animator(Framebuffer_window *fb_win): _fb_win(fb_win), _bg_offset(0) { schedule(20); } @@ -171,7 +169,7 @@ static void read_config() struct Input_handler { - GENODE_RPC(Rpc_handle_input, void, handle, Event&); + GENODE_RPC(Rpc_handle_input, void, handle, Scout::Event&); GENODE_RPC_INTERFACE(Rpc_handle_input); }; @@ -182,35 +180,33 @@ class Input_handler_component : public Genode::Rpc_object &_fb_win; - Redraw_manager &_redraw; - Signal_receiver &_sig_rec; - unsigned long _curr_time, _old_time; + Scout::Platform &_pf; + Scout::User_state &_user_state; + Framebuffer_window &_fb_win; + Genode::Signal_receiver &_sig_rec; + unsigned long _curr_time, _old_time; public: - Input_handler_component(Platform &pf, - User_state &user_state, - Framebuffer_window &fb_win, - Redraw_manager &redraw, - Signal_receiver &sig_rec) - : _pf(pf), - _user_state(user_state), - _fb_win(fb_win), - _redraw(redraw), - _sig_rec(sig_rec) + Input_handler_component(Scout::Platform &pf, + Scout::User_state &user_state, + Framebuffer_window &fb_win, + Genode::Signal_receiver &sig_rec) + : + _pf(pf), + _user_state(user_state), + _fb_win(fb_win), + _sig_rec(sig_rec) { _curr_time = _old_time = _pf.timer_ticks(); } - void handle(Event &ev) + void handle(Scout::Event &ev) { - if (ev.type != Event::WHEEL) { - ev.mx -= _user_state.vx(); - ev.my -= _user_state.vy(); - } + using Scout::Event; + + if (ev.type != Event::WHEEL) + ev.mouse_position = ev.mouse_position - _user_state.view_position(); /* direct all keyboard events to the window content */ if ((ev.type == Event::PRESS || ev.type == Event::RELEASE) @@ -219,15 +215,12 @@ class Input_handler_component : public Genode::Rpc_objectreload(); + Genode::config()->reload(); /* keep the current values by default */ config_fb_x = _fb_win.view_x(); config_fb_y = _fb_win.view_y(); @@ -249,7 +242,7 @@ class Input_handler_component : public Genode::Rpc_object 20) || (_curr_time < _old_time))) { _old_time = _curr_time; - _redraw.process(); + _fb_win.process_redraw(); } } }; @@ -260,44 +253,41 @@ class Input_handler_component : public Genode::Rpc_objectsigh(sig_rec.manage(&sig_ctx)); } catch (...) { } + try { Genode::config()->sigh(sig_rec.manage(&sig_ctx)); } catch (...) { } /* heuristic for allocating the double-buffer backing store */ enum { WINBORDER_WIDTH = 10, WINBORDER_HEIGHT = 40 }; /* init platform */ - static Platform pf(config_fb_x, config_fb_y, - config_fb_width + WINBORDER_WIDTH, - config_fb_height + WINBORDER_HEIGHT, - config_fb_width + WINBORDER_WIDTH, - config_fb_height + WINBORDER_HEIGHT); + static Nitpicker::Connection nitpicker; + static Platform pf(*nitpicker.input()); + + Area const max_size(config_fb_width + WINBORDER_WIDTH, + config_fb_height + WINBORDER_HEIGHT); + Point const initial_position(config_fb_x, config_fb_y); + Area const initial_size = max_size; + + static Nitpicker_graphics_backend + graphics_backend(nitpicker, max_size, initial_position, initial_size); /* initialize our window content */ init_window_content(config_fb_width, config_fb_height, config_alpha); - /* init canvas */ - static Chunky_canvas canvas; - canvas.init(static_cast(pf.buf_adr()), - pf.scr_w()*pf.scr_h()); - canvas.set_size(pf.scr_w(), pf.scr_h()); - canvas.clip(0, 0, pf.scr_w(), pf.scr_h()); - - /* init redraw manager */ - static Redraw_manager redraw(&canvas, &pf, pf.vw(), pf.vh()); - /* create instance of browser window */ static Framebuffer_window - fb_win(&pf, &redraw, window_content(), config_title, config_alpha, + fb_win(graphics_backend, window_content(), + initial_position, initial_size, max_size, + config_title, config_alpha, config_resize_handle, config_decoration); if (config_animate) { @@ -305,34 +295,33 @@ int main(int argc, char **argv) } /* create user state manager */ - static User_state user_state(&fb_win, &fb_win, pf.vx(), pf.vy()); - - /* assign framebuffer window as root element to redraw manager */ - redraw.root(&fb_win); - + static User_state user_state(&fb_win, &fb_win, + initial_position.x(), initial_position.y()); fb_win.parent(&user_state); fb_win.content_geometry(config_fb_x, config_fb_y, config_fb_width, config_fb_height); /* initialize server entry point */ - enum { STACK_SIZE = 2*1024*sizeof(addr_t) }; - static Cap_connection cap; - static Rpc_entrypoint ep(&cap, STACK_SIZE, "liquid_fb_ep"); + enum { STACK_SIZE = 2*1024*sizeof(Genode::addr_t) }; + static Genode::Cap_connection cap; + static Genode::Rpc_entrypoint ep(&cap, STACK_SIZE, "liquid_fb_ep"); /* initialize public services */ init_services(ep); /* create local input handler service */ static Input_handler_component input_handler(pf, user_state, fb_win, - redraw, sig_rec); - Capability input_handler_cap = ep.manage(&input_handler); + sig_rec); + Genode::Capability input_handler_cap = ep.manage(&input_handler); /* enter main loop */ - Event ev; - do { - pf.get_event(&ev); + for (;;) { + Event ev = pf.get_event(); input_handler_cap.call(ev); - } while (ev.type != Event::QUIT); + + if (ev.type == Event::QUIT) + break; + } return 0; } diff --git a/demo/src/server/liquid_framebuffer/services.cc b/demo/src/server/liquid_framebuffer/services.cc index 28d9ac78f..540796330 100644 --- a/demo/src/server/liquid_framebuffer/services.cc +++ b/demo/src/server/liquid_framebuffer/services.cc @@ -16,11 +16,15 @@ #include #include #include +#include +#include -#include "canvas_rgb565.h" #include "services.h" +typedef Genode::Texture Texture_rgb565; + + /***************** ** Event queue ** *****************/ @@ -43,7 +47,7 @@ class Event_queue */ Event_queue(): _head(0), _tail(0) { - memset(_queue, 0, sizeof(_queue)); + Scout::memset(_queue, 0, sizeof(_queue)); } void post(Input::Event ev) @@ -81,28 +85,30 @@ namespace Input { } -class Window_content : public Element +class Window_content : public Scout::Element { private: - class Content_event_handler : public Event_handler + class Content_event_handler : public Scout::Event_handler { private: - Event_queue *_ev_queue; - int _omx, _omy; - Element *_element; + Event_queue *_ev_queue; + Scout::Point _old_mouse_position; + Element *_element; public: - Content_event_handler(Event_queue *ev_queue, Element *element) + Content_event_handler(Event_queue *ev_queue, + Scout::Element *element) : _ev_queue(ev_queue), _element(element) { } - void handle(Event &ev) + void handle(Scout::Event &ev) { - int mx = ev.mx - _element->abs_x(); - int my = ev.my - _element->abs_y(); + using namespace Scout; + + Point mouse_position = ev.mouse_position - _element->abs_position(); int code = 0; @@ -117,28 +123,30 @@ class Window_content : public Element : Input::Event::INVALID; if (type != Input::Event::INVALID) - _ev_queue->post(Input::Event(type, code, mx, my, mx - _omx, my - _omy)); + _ev_queue->post(Input::Event(type, code, mouse_position.x(), + mouse_position.y(), + mouse_position.x() - _old_mouse_position.x(), + mouse_position.y() - _old_mouse_position.y())); - _omx = mx; - _omy = my; + _old_mouse_position = mouse_position; } }; struct Fb_texture { - unsigned w, h; - Genode::Attached_ram_dataspace ds; - Pixel_rgb565 *pixel; - unsigned char *alpha; - Texture_rgb565 texture; + unsigned w, h; + Genode::Attached_ram_dataspace ds; + Genode::Pixel_rgb565 *pixel; + unsigned char *alpha; + Genode::Texture texture; Fb_texture(unsigned w, unsigned h, bool config_alpha) : w(w), h(h), - ds(Genode::env()->ram_session(), w*h*sizeof(Pixel_rgb565)), - pixel(ds.local_addr()), + ds(Genode::env()->ram_session(), w*h*sizeof(Genode::Pixel_rgb565)), + pixel(ds.local_addr()), alpha((unsigned char *)Genode::env()->heap()->alloc(w*h)), - texture(pixel, alpha, w, h) + texture(pixel, alpha, Scout::Area(w, h)) { int alpha_min = config_alpha ? 0 : 255; @@ -152,7 +160,7 @@ class Window_content : public Element if (v & 0x100) a = 255 - a; - a += (dither_matrix[y % dither_size][x % dither_size] - 127) >> 4; + a += (Genode::Dither_matrix::value(x, y) - 127) >> 4; alpha[y*w + x] = Genode::max(alpha_min, Genode::min(a, 255)); } @@ -183,8 +191,7 @@ class Window_content : public Element _new_w(fb_w), _new_h(fb_h), _wait_for_refresh(false) { - _min_w = _fb->w; - _min_h = _fb->h; + _min_size = Scout::Area(_fb->w, _fb->h); event_handler(&_ev_handler); } @@ -229,15 +236,15 @@ class Window_content : public Element /** * Element interface */ - void draw(Canvas *c, int x, int y) + void draw(Scout::Canvas_base &canvas, Scout::Point abs_position) { if (!_wait_for_refresh) - c->draw_texture(&_fb->texture, _x + x, _y + y); + canvas.draw_texture(abs_position + _position, _fb->texture); } - void format_fixed_size(int w, int h) + void format_fixed_size(Scout::Area size) { - _new_w = w, _new_h = h; + _new_w = size.w(), _new_h = size.h(); /* notify framebuffer client about mode change */ if (_mode_sigh.valid()) @@ -248,7 +255,7 @@ class Window_content : public Element static Window_content *_window_content; -Element *window_content() { return _window_content; } +Scout::Element *window_content() { return _window_content; } /*********************************************** diff --git a/demo/src/server/liquid_framebuffer/services.h b/demo/src/server/liquid_framebuffer/services.h index 8141e8d4b..77ed310fe 100644 --- a/demo/src/server/liquid_framebuffer/services.h +++ b/demo/src/server/liquid_framebuffer/services.h @@ -15,11 +15,11 @@ #define _SERVICES_H_ #include +#include -#include "canvas.h" #include "elements.h" -extern Element *window_content(); +extern Scout::Element *window_content(); extern void init_window_content(unsigned fb_w, unsigned fb_h, bool config_alpha); extern void init_services(Genode::Rpc_entrypoint &ep); extern void lock_window_content(); diff --git a/demo/src/server/liquid_framebuffer/target.mk b/demo/src/server/liquid_framebuffer/target.mk index 8ed86f1e2..abb0a602d 100644 --- a/demo/src/server/liquid_framebuffer/target.mk +++ b/demo/src/server/liquid_framebuffer/target.mk @@ -1,6 +1,5 @@ TARGET = liquid_fb LIBS = scout_widgets config SRC_CC = main.cc services.cc -INC_DIR += $(REP_DIR)/src/app/scout/include \ - $(REP_DIR)/src/app/scout/include/genode \ +INC_DIR += $(REP_DIR)/src/app/scout \ $(REP_DIR)/src/server/framebuffer/sdl diff --git a/demo/src/server/nitlog/main.cc b/demo/src/server/nitlog/main.cc index 6e8dfe77b..48a9b6dea 100644 --- a/demo/src/server/nitlog/main.cc +++ b/demo/src/server/nitlog/main.cc @@ -55,10 +55,9 @@ Font default_font(&_binary_mono_tff_start); */ struct Canvas_base { - virtual void draw_string(Point p, Font const &font, Color color, - char const *sstr) = 0; + virtual void draw_string(Point, Font const &, Color, char const *) = 0; - virtual void draw_box(Rect rect, Color color) = 0; + virtual void draw_box(Rect, Color) = 0; };