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'.
This commit is contained in:
Norman Feske 2013-12-30 01:21:53 +01:00 committed by Christian Helmuth
parent 8c8d53777f
commit 3394be9464
85 changed files with 4175 additions and 4495 deletions

View File

@ -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 <base/env.h>
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_ */

216
demo/include/scout/canvas.h Normal file
View File

@ -0,0 +1,216 @@
/*
* \brief Generic interface of graphics backend and chunky template
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 <scout/texture_allocator.h>
#include <os/pixel_rgba.h>
#include <util/color.h>
#include <util/dither_matrix.h>
#include <nitpicker_gfx/texture_painter.h>
#include <nitpicker_gfx/text_painter.h>
#include <nitpicker_gfx/box_painter.h>
#include <scout_gfx/icon_painter.h>
#include <scout_gfx/sky_texture_painter.h>
#include <scout_gfx/horizontal_shadow_painter.h>
#include <scout_gfx/refracted_icon_painter.h>
namespace Scout {
using Genode::Color;
using Genode::Pixel_rgba;
typedef Text_painter::Font Font;
struct Canvas_base;
template <typename PT> 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<short> 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 <os/pixel_rgb565.h>
#include <base/env.h>
namespace Genode {
template <>
inline void
Texture<Pixel_rgb565>::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 <typename PT>
class Scout::Canvas : public Canvas_base
{
private:
Genode::Surface<PT> _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<Texture<PT> 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<short> 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<Texture<PT> &>(tmp),
static_cast<Texture<PT> const &>(foreground),
detail, filter_backbuf);
}
void draw_texture(Point pos, Texture_base const &texture_base)
{
Texture<PT> const &texture = static_cast<Texture<PT> 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<PT>(pixel, alpha, size);
}
virtual void free_texture(Texture_base *texture_base)
{
using namespace Genode;
Texture<PT> *texture = static_cast<Texture<PT> *>(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<PT> *texture = static_cast<Texture<PT> *>(texture_base);
texture->rgba(rgba, len, y);
}
};
#endif /* _INCLUDE__SCOUT__CANVAS_H_ */

View File

@ -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 <scout/event.h>
#include <scout/canvas.h>
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 <typename FUNC>
inline void for_each_sibling(FUNC func);
};
#endif /* _INCLUDE__SCOUT__ELEMENT_H_ */

View File

@ -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 <scout/types.h>
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_ */

View File

@ -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 <scout/misc_math.h>
#include <scout/tick.h>
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_ */

View File

@ -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 <scout/event.h>
#include <scout/canvas.h>
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_ */

View File

@ -0,0 +1,24 @@
/*
* \brief Misc math functions used here and there
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 <util/misc_math.h>
namespace Scout {
using Genode::min;
using Genode::max;
}
#endif /* _INCLUDE__SCOUT__MISC_MATH_H_ */

View File

@ -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 <nitpicker_session/connection.h>
#include <nitpicker_view/client.h>
#include <os/pixel_rgb565.h>
/* Scout includes */
#include <scout/graphics_backend.h>
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 <typename PT>
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<PT> canvas_0(_base<PT>(0), max_size);
static Canvas<PT> canvas_1(_base<PT>(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<PT>( _back_idx());
PT *dst = _base<PT>(_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_ */

View File

@ -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 <scout/element.h>
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 <typename FUNC>
void for_each_child(FUNC func)
{
for (Element *e = _first; e; e = e->next)
func(*e);
}
};
template <typename FUNC>
void Scout::Element::for_each_sibling(FUNC func)
{
if (parent())
parent()->for_each_child(func);
}
#endif /* _INCLUDE__SCOUT__PARENT_ELEMENT_H_ */

View File

@ -0,0 +1,200 @@
/*
* \brief Platform abstraction
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*
* 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 <base/env.h>
#include <base/semaphore.h>
#include <timer_session/connection.h>
#include <input_session/input_session.h>
#include <input/event.h>
#include <scout/event.h>
#include <scout/canvas.h>
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_ */

View File

@ -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 <base/printf.h>
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_ */

View File

@ -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 <util/string.h>
namespace Scout {
using Genode::strlen;
using Genode::memset;
using Genode::memcpy;
}
#endif /* _INCLUDE__SCOUT__STRING_H_ */

View File

@ -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 <os/texture.h>
#include <scout/types.h>
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_ */

View File

@ -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_ */

View File

@ -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 <util/geometry.h>
namespace Scout {
typedef Genode::Point<> Point;
typedef Genode::Area<> Area;
typedef Genode::Rect<> Rect;
}
#endif /* _INCLUDE__SCOUT__TYPES_H_ */

View File

@ -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 <scout/window.h>
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<Link_token *>(_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_ */

297
demo/include/scout/window.h Normal file
View File

@ -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 <scout/misc_math.h>
#include <scout/parent_element.h>
#include <scout/platform.h>
#include <scout/graphics_backend.h>
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_ */

View File

@ -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 <os/surface.h>
struct Horizontal_shadow_painter
{
typedef Genode::Surface_base::Rect Rect;
template <typename PT>
static inline void paint(Genode::Surface<PT> &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_ */

View File

@ -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 <os/texture.h>
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 <typename PT>
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 <typename PT>
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 <typename PT>
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 <typename PT>
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 <typename PT>
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 <typename PT>
static inline void paint(Genode::Surface<PT> &surface, Rect rect,
Genode::Texture<PT> 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_ */

View File

@ -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_ */

View File

@ -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 <util/misc_math.h>
#include <util/string.h>
#include <os/texture.h>
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 <typename DT>
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 <typename PT, typename DT>
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 <typename PT>
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 <typename PT>
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 <typename PT>
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 <typename PT, typename DT>
static inline void paint(Genode::Surface<PT> &surface,
Point pos,
Distmap<DT> const &distmap,
Genode::Texture<PT> &tmp,
Genode::Texture<PT> 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<PT, DT>(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_ */

View File

@ -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 <os/surface.h>
#include <util/color.h>
struct Sky_texture_painter
{
typedef Genode::Surface_base::Area Area;
typedef Genode::Surface_base::Rect Rect;
typedef Genode::Color Color;
template <typename PT>
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 <typename PT>
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 <typename PT, unsigned TW, unsigned TH>
class Static_sky_texture : public Sky_texture<PT>
{
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<PT>::_mix_channel;
using Sky_texture<PT>::_brew_texture;
using Sky_texture<PT>::_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<PT>(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 <typename PT>
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 <typename PT>
static inline void paint(Genode::Surface<PT> &surface, int py,
Sky_texture_base const &texture_base,
bool detail)
{
PT *addr = surface.addr();
if (!addr) return;
Sky_texture<PT> const &texture = static_cast<Sky_texture<PT> 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_ */

3
demo/lib/mk/scout_gfx.mk Normal file
View File

@ -0,0 +1,3 @@
SRC_CC = sky_texture_painter.cc
vpath %.cc $(REP_DIR)/src/lib/scout_gfx

View File

@ -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 \

View File

@ -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 <typename PT>
class Child_entry : public Parent_element, public Genode::List<Child_entry<PT> >::Element
class Child_entry : public Scout::Parent_element,
public Genode::List<Child_entry<PT> >::Element
{
private:
@ -67,13 +70,13 @@ class Child_entry : public Parent_element, public Genode::List<Child_entry<PT> >
enum { _PADX = 10 }; /* horizontal padding */
enum { _NAME_LEN = 64 }; /* max length of child name */
Block _block;
Scout::Block _block;
Kbyte_loadbar<PT> _loadbar;
char _name[_NAME_LEN];
Fade_icon<PT, _IW, _IH> _kill_icon;
Fade_icon<PT, _IW, _IH> _fold_icon;
Scout::Fade_icon<PT, _IW, _IH> _kill_icon;
Scout::Fade_icon<PT, _IW, _IH> _fold_icon;
Kill_event_handler _kill_event_handler;
@ -85,11 +88,11 @@ class Child_entry : public Parent_element, public Genode::List<Child_entry<PT> >
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<Child_entry<PT> >
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<Child_entry<PT> >
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);
}
};

View File

@ -18,15 +18,15 @@
#include "launcher_config.h"
template <typename PT>
class Launch_entry : public Parent_element, public Loadbar_listener
class Launch_entry : public Scout::Parent_element, public Loadbar_listener
{
private:
Block _block;
Kbyte_loadbar<PT> _loadbar;
Launcher_config _config;
Launcher _launcher;
int _lh; /* launch entry height */
Scout::Block _block;
Kbyte_loadbar<PT> _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);
}
};

View File

@ -15,10 +15,8 @@
#include "elements.h"
#include "launcher_config.h"
using namespace Scout;
/************************
** Launcher interface **
************************/
void Launcher::launch()
{

View File

@ -11,10 +11,14 @@
* under the terms of the GNU General Public License version 2.
*/
#include "miscmath.h"
#include <scout/misc_math.h>
#include "launchpad_window.h"
#include "styles.h"
using namespace Scout;
/****************************
** External graphics data **
****************************/
@ -31,13 +35,12 @@ extern unsigned char TITLEBAR_RGBA[];
********************************/
template <typename PT>
Launchpad_window<PT>::Launchpad_window(Platform *pf,
Redraw_manager *redraw,
int max_w, int max_h,
Launchpad_window<PT>::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<PT>::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<PT>::Launchpad_window(Platform *pf,
template <typename PT>
void Launchpad_window<PT>::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<PT>::ypos_sb(int ypos, int update_scrollbar)
*************************/
template <typename PT>
void Launchpad_window<PT>::format(int w, int h)
void Launchpad_window<PT>::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<PT>::handle_scroll(int view_pos)
ypos_sb(-view_pos, 0);
}
#include "canvas_rgb565.h"
template class Launchpad_window<Pixel_rgb565>;
template class Launchpad_window<Genode::Pixel_rgb565>;

View File

@ -14,13 +14,14 @@
#ifndef _LAUNCHPAD_WINDOW_H_
#define _LAUNCHPAD_WINDOW_H_
#include <scout/platform.h>
#include <scout/window.h>
#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 <base/printf.h>
template <typename PT>
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<PT> _titlebar;
Sky_texture<PT, 512, 512> _texture;
Fade_icon<PT, 32, 32> _sizer;
Scrollbar<PT> _scrollbar;
Genode::List<Child_entry<PT> > _child_entry_list;
Docview _docview;
Spacer _spacer;
Document _document;
Scout::Titlebar<PT> _titlebar;
Scout::Sky_texture<PT, 512, 512> _texture;
Scout::Fade_icon<PT, 32, 32> _sizer;
Scout::Scrollbar<PT> _scrollbar;
Genode::List<Child_entry<PT> > _child_entry_list;
Scout::Docview _docview;
Scout::Spacer _spacer;
Scout::Document _document;
Section<PT> _info_section;
Section<PT> _launch_section;
Section<PT> _kiddy_section;
Section<PT> _info_section;
Section<PT> _launch_section;
Section<PT> _kiddy_section;
Status_entry<PT> _status_entry;
Status_entry<PT> _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();
}
};

View File

@ -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 <typename PT>
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<PT, _LW, _LH> _cover;
Fade_icon<PT, _LW, _LH> _bar;
Scout::Fade_icon<PT, _LW, _LH> _cover;
Scout::Fade_icon<PT, _LW, _LH> _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<PT>
public:
Kbyte_loadbar(Loadbar_listener *listener, Font *font = 0):
Kbyte_loadbar(Loadbar_listener *listener, Scout::Font *font = 0):
Loadbar<PT>(listener, font)
{
_label[0] = 0;

View File

@ -11,15 +11,15 @@
* under the terms of the GNU General Public License version 2.
*/
#include <scout/platform.h>
#include <scout/tick.h>
#include <scout/user_state.h>
#include <scout/printf.h>
#include <scout/nitpicker_graphics_backend.h>
#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 <base/env.h>
#include <init/child_config.h>
@ -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<Pixel_rgb565> canvas;
canvas.init(static_cast<Pixel_rgb565 *>(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<Pixel_rgb565>
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;
}

View File

@ -18,29 +18,30 @@
template <typename PT>
class Section : public Parent_element
class Section : public Scout::Parent_element
{
private:
enum { _SH = 8 }; /* shadow height */
enum { _STH = 20 }; /* shadow height */
Horizontal_shadow<PT, 40> _bg;
Horizontal_shadow<PT, 160> _shadow;
const char *_txt;
int _txt_w, _txt_h;
int _txt_len;
Font *_font;
int _r_add;
Scout::Horizontal_shadow<PT, 40> _bg;
Scout::Horizontal_shadow<PT, 160> _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));
}
};

View File

@ -17,11 +17,11 @@
#include "loadbar.h"
template <typename PT>
class Status_entry : public Parent_element
class Status_entry : public Scout::Parent_element
{
private:
Block _block;
Scout::Block _block;
Kbyte_loadbar<PT> _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); }

View File

@ -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)

View File

@ -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 = "";

View File

@ -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_ */

View File

@ -13,9 +13,13 @@
* under the terms of the GNU General Public License version 2.
*/
#include "miscmath.h"
#include <scout_gfx/random.h>
#include <scout/misc_math.h>
#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 <typename PT>
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 <typename PT>
Browser_window<PT>::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<PT>::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<PT>::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<PT>::Browser_window(Document *initial_content,
template <typename PT>
void Browser_window<PT>::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 <typename PT>
void Browser_window<PT>::_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 <typename PT>
void Browser_window<PT>::format(int w, int h)
void Browser_window<PT>::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<PT>::handle_scroll(int view_pos)
ypos_sb(-view_pos, 0);
}
#include "canvas_rgb565.h"
template class Browser_window<Pixel_rgb565>;
template class Browser_window<Genode::Pixel_rgb565>;

View File

@ -14,22 +14,24 @@
#ifndef _BROWSER_WINDOW_H_
#define _BROWSER_WINDOW_H_
#include <scout/platform.h>
#include <scout/window.h>
#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 <typename PT> class Browser_window; }
template <typename PT>
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);
}
};

View File

@ -1,184 +0,0 @@
/*
* \brief Implementation of refracted icons
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*
* 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 <typename PT>
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 <typename PT>
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 <typename PT, typename DT>
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 <typename PT>
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 <typename PT, typename DT>
void Refracted_icon<PT, DT>::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 <typename PT, typename DT>
void Refracted_icon<PT, DT>::draw(Canvas *c, int x, int y)
{
PT *addr = static_cast<PT *>(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<PT, DT>(_backbuf, _distmap, _distmap_w, _distmap_h,
_fg, _fg_alpha, addr, c->w(), curr_w);
}
}
#include "canvas_rgb565.h"
template class Refracted_icon<Pixel_rgb565, short>;

View File

@ -1,363 +0,0 @@
/*
* \brief Sky texture element for the use as background
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*
* 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 <typename PT>
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 <typename PT>
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 <typename PT>
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 <typename PT, int TW, int TH>
Sky_texture<PT, TW, TH>::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 <typename PT, int TW, int TH>
void Sky_texture<PT, TW, TH>::draw(Canvas *c, int px, int py)
{
PT *addr = static_cast<PT *>(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<Pixel_rgb565, 512, 512>;

View File

@ -1,11 +0,0 @@
Genode Demonstration
Norman Feske
[image setup]
Introduction
############

View File

@ -1,474 +0,0 @@
/*
* \brief GUI elements
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 <typename PT, int INTENSITY>
void Horizontal_shadow<PT, INTENSITY>::draw(Canvas *c, int x, int y)
{
PT *addr = static_cast<PT *>(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 <typename PT, int W, int H>
Icon<PT, W, H>::Icon()
{
memset(_pixel, 0, sizeof(_pixel));
memset(_alpha, 0, sizeof(_alpha));
memset(_shadow, 0, sizeof(_shadow));
_icon_alpha = 255;
}
template <typename PT, int W, int H>
void Icon<PT, W, H>::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 <typename PT, int W, int H>
void Icon<PT, W, H>::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 <typename PT>
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 <typename PT>
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 <typename PT>
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 <typename PT>
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 <typename PT>
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 <typename PT, int W, int H>
void Icon<PT, W, H>::draw(Canvas *c, int x, int y)
{
PT *addr = static_cast<PT *>(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 <typename PT, int W, int H>
Element *Icon<PT, W, H>::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<Pixel_rgb565, 40>;
template class Horizontal_shadow<Pixel_rgb565, 160>;
template class Icon<Pixel_rgb565, 16, 16>;
template class Icon<Pixel_rgb565, 32, 32>;
template class Icon<Pixel_rgb565, 64, 64>;

View File

@ -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_ */

View File

@ -14,6 +14,8 @@
#include "elements.h"
#include "styles.h"
using namespace Scout;
Document *create_document()
{
Document *doc = new Document();

View File

@ -11,10 +11,13 @@
* under the terms of the GNU General Public License version 2.
*/
#include "miscmath.h"
#include <scout/misc_math.h>
#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<Browser *>(e);
/* let browser follow link */
if (b && _dst) b->go_to(_dst);
}

View File

@ -0,0 +1,590 @@
/*
* \brief Document structure elements
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 <scout/parent_element.h>
#include <scout/printf.h>
#include <scout/string.h>
#include <scout/fader.h>
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<Link_token *>(&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_ */

View File

@ -18,13 +18,15 @@
#ifndef _FADE_ICON_H_
#define _FADE_ICON_H_
#include "miscmath.h"
#include <scout/misc_math.h>
#include <scout/fader.h>
#include "widgets.h"
#include "fader.h"
namespace Scout { template <typename PT, int W, int H> class Fade_icon; }
template <typename PT, int W, int H>
class Fade_icon : public Fader, public Icon<PT, W, H>
class Scout::Fade_icon : public Fader, public Icon<PT, W, H>
{
private:
@ -64,7 +66,7 @@ class Fade_icon : public Fader, public Icon<PT, W, H>
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<PT, W,H>::alpha(_curr_value);
return 1;
@ -76,7 +78,7 @@ class Fade_icon : public Fader, public Icon<PT, W, H>
void alpha(int alpha)
{
_curr_value = alpha;
::Icon<PT, W, H>::alpha(alpha);
Icon<PT, W, H>::alpha(alpha);
}
/**

View File

@ -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 <base/env.h>
#include <base/thread.h>
#include <base/printf.h>
#include <base/lock.h>
#include <nitpicker_session/connection.h>
#include <timer_session/connection.h>
#include <nitpicker_view/client.h>
#include <input/event.h>
#include <base/semaphore.h>
#include <blit/blit.h>
#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);
}

View File

@ -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;
}

View File

@ -16,7 +16,10 @@
#include "elements.h"
class History
namespace Scout { class History; }
class Scout::History
{
private:
@ -108,5 +111,4 @@ class History
}
};
#endif

View File

@ -1,325 +0,0 @@
/*
* \brief Generic interface of graphics backend and chunky template
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 <typename ST, int R_MASK, int R_SHIFT,
int G_MASK, int G_SHIFT,
int B_MASK, int B_SHIFT,
int A_MASK, int A_SHIFT>
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 <typename PT>
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<PT *>(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_ */

View File

@ -1,239 +0,0 @@
/*
* \brief Template specializations for the RGB565 pixel format
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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<unsigned short, 0xf800, 8, 0x07e0, 3, 0x001f, -3, 0, 0> 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<Pixel_rgb565> 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_rgb565*>(texture);
}
template <>
inline void Canvas_rgb565::set_rgba_texture(Canvas::Texture *dst,
unsigned char *rgba, int len, int y)
{
(static_cast<Texture_rgb565*>(dst))->rgba(rgba, len, y);
}
template <>
inline void Canvas_rgb565::draw_texture(Texture *src_texture, int x1, int y1)
{
Texture_rgb565 *src = static_cast<Texture_rgb565*>(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_ */

View File

@ -1,52 +0,0 @@
/*
* \brief Color representation
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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_ */

View File

@ -1,815 +0,0 @@
/*
* \brief Document structure elements
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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_ */

View File

@ -1,62 +0,0 @@
/*
* \brief Font representation
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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_ */

View File

@ -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 <base/env.h>
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

View File

@ -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 <util/string.h>
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

View File

@ -1,35 +0,0 @@
/*
* \brief Misc math functions used here and there
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 <typename T> static inline T min(T a, T b) { return a < b ? a : b; }
template <typename T> 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_ */

View File

@ -1,164 +0,0 @@
/*
* \brief Platform abstraction
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*
* 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_ */

View File

@ -1,150 +0,0 @@
/*
* \brief Simplistic redraw manager featuring redraw merging
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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_ */

View File

@ -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 <base/fixed_stdint.h>
typedef Genode::int32_t scout_int32_t;
#endif /* _SCOUT_TYPES_H_ */

View File

@ -1,53 +0,0 @@
/*
* \brief Document styles
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 (&section_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_ */

View File

@ -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

View File

@ -22,6 +22,7 @@ static Launchpad launchpad(Genode::env()->ram_session()->quota());
using namespace Genode;
using namespace Scout;
/**********************************************

View File

@ -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 <dataspace/capability.h>
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_ */

View File

@ -11,32 +11,28 @@
* under the terms of the GNU General Public License version 2.
*/
/**
* Local includes
*/
#include <scout/platform.h>
#include <scout/tick.h>
#include <scout/user_state.h>
#include <scout/nitpicker_graphics_backend.h>
#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<Pixel_rgb565> canvas;
canvas.init(static_cast<Pixel_rgb565 *>(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<Pixel_rgb565> 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<Pixel_rgb565, 32, 32> 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;
}

View File

@ -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<Browser *>(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;

View File

@ -13,9 +13,12 @@
#include <png.h>
#include "miscmath.h"
#include <scout/misc_math.h>
#include <scout/alloc.h>
#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);
}

View File

@ -14,14 +14,19 @@
#ifndef _REFRACTED_ICON_H_
#define _REFRACTED_ICON_H_
#include <scout_gfx/random.h>
#include "widgets.h"
namespace Scout { template <typename PT, typename DT> class Refracted_icon; }
/**
* \param PT pixel type (must be Pixel_rgba compatible)
* \param DT distortion map entry type
*/
template <typename PT, typename DT>
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<short>
distmap(_distmap, Area(_distmap_w, _distmap_h));
Texture<PT> tmp(_backbuf, 0, Area(_distmap_w, _distmap_h));
Texture<PT> 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_ */

View File

@ -11,8 +11,11 @@
* under the terms of the GNU General Public License version 2.
*/
#include <scout/tick.h>
#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<PT>::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<PT>::Scrollbar()
template <typename PT>
int Scrollbar<PT>::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 <typename PT>
int Scrollbar<PT>::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<PT>::slider_pos()
template <typename PT>
void Scrollbar<PT>::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<PT>::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<PT>::notify_listener()
***********************/
template <typename PT>
void Scrollbar<PT>::geometry(int x, int y, int w, int h)
void Scrollbar<PT>::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<PT>::geometry(int x, int y, int w, int h)
template <typename PT>
Element *Scrollbar<PT>::find(int x, int y)
Element *Scrollbar<PT>::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<Pixel_rgb565>;
template class Scrollbar<Genode::Pixel_rgb565>;

View File

@ -17,8 +17,13 @@
#include "widgets.h"
#include "fade_icon.h"
namespace Scout {
class Scrollbar_listener;
template <typename PT> class Scrollbar;
}
class Scrollbar_listener
class Scout::Scrollbar_listener
{
public:
@ -32,7 +37,7 @@ class Scrollbar_listener
template <typename PT>
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);
};

View File

@ -14,7 +14,12 @@
#ifndef _SKY_TEXTURE_H_
#define _SKY_TEXTURE_H_
#include <scout_gfx/sky_texture_painter.h>
#include "widgets.h"
#include "config.h"
namespace Scout { template <typename, int, int> class Sky_texture; }
/**
@ -23,21 +28,19 @@
* \param TH tile height
*/
template <typename PT, int TW, int TH>
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<PT, TW, TH> _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_ */

View File

@ -0,0 +1,54 @@
/*
* \brief Document styles
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 (&section_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_ */

View File

@ -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 \

View File

@ -11,8 +11,11 @@
* under the terms of the GNU General Public License version 2.
*/
#include "tick.h"
#include "printf.h"
#include <scout/tick.h>
#include <scout/printf.h>
using namespace Scout;
static Tick *head = 0; /* head of tick list */
static Tick::time now = 0; /* recent time (updated by handle function) */

View File

@ -19,15 +19,13 @@
#define TITLE_TFF _binary_vera18_tff_start
extern char TITLE_TFF[];
namespace Scout { template <typename PT> class Titlebar; }
/***************
** Title bar **
***************/
static Font title_font(TITLE_TFF);
static Scout::Font title_font(TITLE_TFF);
template <typename PT>
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);
}
};

View File

@ -0,0 +1,206 @@
/*
* \brief GUI elements
* \date 2005-10-24
* \author Norman Feske <norman.feske@genode-labs.com>
*/
/*
* 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 <scout/misc_math.h>
#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 <typename PT, int INTENSITY>
void Horizontal_shadow<PT, INTENSITY>::draw(Canvas_base &canvas, Point abs_position)
{
canvas.draw_horizontal_shadow(Rect(abs_position + _position, _size), INTENSITY);
}
/**********
** Icon **
**********/
template <typename PT, int W, int H>
Icon<PT, W, H>::Icon()
{
memset(_pixel, 0, sizeof(_pixel));
memset(_alpha, 0, sizeof(_alpha));
memset(_shadow, 0, sizeof(_shadow));
_icon_alpha = 255;
}
template <typename PT, int W, int H>
void Icon<PT, W, H>::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 <typename PT, int W, int H>
void Icon<PT, W, H>::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 <typename PT, int W, int H>
void Icon<PT, W, H>::draw(Canvas_base &canvas, Point abs_position)
{
Texture<PT> texture(_pixel[0], _alpha[0], Area(W, H));
canvas.draw_icon(Rect(abs_position + _position, _size), texture, _icon_alpha);
}
template <typename PT, int W, int H>
Element *Icon<PT, W, H>::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<Genode::Pixel_rgb565, 40>;
template class Horizontal_shadow<Genode::Pixel_rgb565, 160>;
template class Icon<Genode::Pixel_rgb565, 16, 16>;
template class Icon<Genode::Pixel_rgb565, 32, 32>;
template class Icon<Genode::Pixel_rgb565, 64, 64>;

View File

@ -16,15 +16,19 @@
#include "elements.h"
class Texture : public Element { };
namespace Scout {
class Docview;
template <typename, int> class Horizontal_shadow;
class Generic_icon;
template <typename, int, int> 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 <typename PT, int INTENSITY>
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 <typename PT, int W, int H>
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);
};

View File

@ -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 <scout_gfx/random.h>
#include <scout_gfx/sky_texture_painter.h>
/**
* 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);
}

View File

@ -14,7 +14,8 @@
#ifndef _FRAMEBUFFER_WINDOW_H_
#define _FRAMEBUFFER_WINDOW_H_
#include "window.h"
#include <scout/window.h>
#include "titlebar.h"
#include "sky_texture.h"
#include "fade_icon.h"
@ -27,7 +28,7 @@ extern unsigned char SIZER_RGBA[];
template <typename PT>
class Framebuffer_window : public Window
class Framebuffer_window : public Scout::Window
{
private:
@ -39,29 +40,34 @@ class Framebuffer_window : public Window
/**
* Widgets
*/
Titlebar<PT> _titlebar;
Sky_texture<PT, 512, 512> _bg_texture;
int _bg_offset;
Fade_icon<PT, 32, 32> _sizer;
Element *_content;
bool _config_alpha;
bool _config_resize_handle;
bool _config_decoration;
Scout::Titlebar<PT> _titlebar;
Scout::Sky_texture<PT, 512, 512> _bg_texture;
int _bg_offset;
Scout::Fade_icon<PT, 32, 32> _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);
};
};

View File

@ -15,44 +15,42 @@
#include <base/signal.h>
#include <cap_session/connection.h>
#include <os/config.h>
#include <scout/user_state.h>
#include <scout/nitpicker_graphics_backend.h>
#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<Pixel_rgb565> *_fb_win;
int _bg_offset;
Framebuffer_window<Scout::Pixel_rgb565> *_fb_win;
int _bg_offset;
public:
/**
* Constructor
*/
Background_animator(Framebuffer_window<Pixel_rgb565> *fb_win):
Background_animator(Framebuffer_window<Scout::Pixel_rgb565> *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<Input_handler,
private:
Platform &_pf;
User_state &_user_state;
Framebuffer_window<Pixel_rgb565> &_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<Genode::Pixel_rgb565> &_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<Pixel_rgb565> &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<Genode::Pixel_rgb565> &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_object<Input_handler,
else
_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());
Scout::Tick::handle(_pf.timer_ticks());
/* check for configuration changes */
if (_sig_rec.pending()) {
_sig_rec.wait_for_signal();
config()->reload();
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<Input_handler,
_curr_time = _pf.timer_ticks();
if (!_pf.event_pending() && ((_curr_time - _old_time > 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_object<Input_handler,
*/
int main(int argc, char **argv)
{
if (native_startup(argc, argv)) return -1;
using namespace Scout;
try { read_config(); } catch (...) { }
/*
* Register signal handler for config changes
*/
static Signal_receiver sig_rec;
static Signal_context sig_ctx;
static Genode::Signal_receiver sig_rec;
static Genode::Signal_context sig_ctx;
try { config()->sigh(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<Pixel_rgb565> canvas;
canvas.init(static_cast<Pixel_rgb565 *>(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<Pixel_rgb565>
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> input_handler_cap = ep.manage(&input_handler);
sig_rec);
Genode::Capability<Input_handler> 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<Input_handler::Rpc_handle_input>(ev);
} while (ev.type != Event::QUIT);
if (ev.type == Event::QUIT)
break;
}
return 0;
}

View File

@ -16,11 +16,15 @@
#include <base/rpc_server.h>
#include <framebuffer_session/framebuffer_session.h>
#include <input/component.h>
#include <nitpicker_gfx/texture_painter.h>
#include <os/pixel_rgb565.h>
#include "canvas_rgb565.h"
#include "services.h"
typedef Genode::Texture<Genode::Pixel_rgb565> 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<Genode::Pixel_rgb565> 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<Pixel_rgb565>()),
ds(Genode::env()->ram_session(), w*h*sizeof(Genode::Pixel_rgb565)),
pixel(ds.local_addr<Genode::Pixel_rgb565>()),
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; }
/***********************************************

View File

@ -15,11 +15,11 @@
#define _SERVICES_H_
#include <base/rpc_server.h>
#include <scout/canvas.h>
#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();

View File

@ -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

View File

@ -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;
};