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:
parent
8c8d53777f
commit
3394be9464
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -0,0 +1,3 @@
|
|||
SRC_CC = sky_texture_painter.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/scout_gfx
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
#include "elements.h"
|
||||
#include "launcher_config.h"
|
||||
|
||||
using namespace Scout;
|
||||
|
||||
/************************
|
||||
** Launcher interface **
|
||||
************************/
|
||||
|
||||
void Launcher::launch()
|
||||
{
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 = "";
|
||||
|
|
@ -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_ */
|
|
@ -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>;
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
@ -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>;
|
|
@ -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>;
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
|
||||
Genode Demonstration
|
||||
|
||||
Norman Feske
|
||||
|
||||
[image setup]
|
||||
|
||||
Introduction
|
||||
############
|
||||
|
|
@ -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>;
|
|
@ -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_ */
|
|
@ -14,6 +14,8 @@
|
|||
#include "elements.h"
|
||||
#include "styles.h"
|
||||
|
||||
using namespace Scout;
|
||||
|
||||
Document *create_document()
|
||||
{
|
||||
Document *doc = new Document();
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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_ */
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
#include "elements.h"
|
||||
|
||||
class History
|
||||
namespace Scout { class History; }
|
||||
|
||||
|
||||
class Scout::History
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -108,5 +111,4 @@ class History
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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 (§ion_font, default_color, 0);
|
||||
static Style subsection_style (&subsection_font, default_color, 0);
|
||||
static Style navbar_style (&default_font, Color(0, 0, 0, 127), 0);
|
||||
|
||||
#endif /* _STYLES_H_ */
|
|
@ -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
|
|
@ -22,6 +22,7 @@ static Launchpad launchpad(Genode::env()->ram_session()->quota());
|
|||
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Scout;
|
||||
|
||||
|
||||
/**********************************************
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
|
@ -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);
|
||||
}
|
|
@ -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_ */
|
|
@ -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>;
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
@ -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_ */
|
|
@ -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 (§ion_font, default_color, 0);
|
||||
static Style subsection_style (&subsection_font, default_color, 0);
|
||||
static Style navbar_style (&default_font, Color(0, 0, 0, 127), 0);
|
||||
}
|
||||
|
||||
#endif /* _STYLES_H_ */
|
|
@ -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 \
|
|
@ -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) */
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
@ -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>;
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
||||
/***********************************************
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue