mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 00:24:51 +00:00
Generalization of nitpicker's graphics backend
This patch re-arranges nitpicker's graphics backend in a more modular and expandable way. Generalized versions of the 'Canvas', 'Chunky_canvas', and 'Pixel_*' classes have been moved to 'os/include/util/' and 'os/include/os'. The only remaining parts that are specific to nitpicker's needs are a few drawing functions, each located in a distinct header at 'os/include/nitpicker_gfx/'.
This commit is contained in:
parent
765053ea94
commit
8c8d53777f
@ -24,18 +24,24 @@
|
||||
#include <nitpicker_view/client.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <input/event.h>
|
||||
#include <os/pixel_rgb565.h>
|
||||
|
||||
/*
|
||||
* Nitpicker's graphics backend
|
||||
*/
|
||||
#include <nitpicker_gfx/chunky_canvas.h>
|
||||
#include <nitpicker_gfx/pixel_rgb565.h>
|
||||
#include <nitpicker_gfx/font.h>
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
#include <nitpicker_gfx/box_painter.h>
|
||||
|
||||
|
||||
enum { LOG_W = 80 }; /* number of visible characters per line */
|
||||
enum { LOG_H = 25 }; /* number of lines of log window */
|
||||
|
||||
typedef Text_painter::Font Font;
|
||||
typedef Genode::Surface_base::Point Point;
|
||||
typedef Genode::Surface_base::Area Area;
|
||||
typedef Genode::Surface_base::Rect Rect;
|
||||
typedef Genode::Color Color;
|
||||
|
||||
|
||||
/*
|
||||
* Font initialization
|
||||
@ -44,6 +50,47 @@ extern char _binary_mono_tff_start;
|
||||
Font default_font(&_binary_mono_tff_start);
|
||||
|
||||
|
||||
/**
|
||||
* Pixel-type-independent interface to graphics backend
|
||||
*/
|
||||
struct Canvas_base
|
||||
{
|
||||
virtual void draw_string(Point p, Font const &font, Color color,
|
||||
char const *sstr) = 0;
|
||||
|
||||
virtual void draw_box(Rect rect, Color color) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pixel-type-specific graphics backend
|
||||
*/
|
||||
template <typename PT>
|
||||
class Canvas : public Canvas_base
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Surface<PT> _surface;
|
||||
|
||||
public:
|
||||
|
||||
Canvas(PT *base, Area size) : _surface(base, size) { }
|
||||
|
||||
void clip(Rect rect) { _surface.clip(rect); }
|
||||
|
||||
void draw_string(Point p, Font const &font, Color color,
|
||||
char const *sstr)
|
||||
{
|
||||
Text_painter::paint(_surface, p, font, color, sstr);
|
||||
}
|
||||
|
||||
void draw_box(Rect rect, Color color)
|
||||
{
|
||||
Box_painter::paint(_surface, rect, color);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Log_entry
|
||||
{
|
||||
private:
|
||||
@ -90,7 +137,7 @@ class Log_entry
|
||||
* marks a transition of output from one session to another. This
|
||||
* information is used to separate sessions visually.
|
||||
*/
|
||||
void draw(Canvas *canvas, int y, int new_section = false)
|
||||
void draw(Canvas_base &canvas, int y, int new_section = false)
|
||||
{
|
||||
Color label_fgcol = Color(Genode::min(255, _color.r + 200),
|
||||
Genode::min(255, _color.g + 200),
|
||||
@ -103,23 +150,19 @@ class Log_entry
|
||||
int label_w = default_font.str_w(_label);
|
||||
int label_h = default_font.str_h(_label);
|
||||
|
||||
typedef Canvas::Rect Rect;
|
||||
typedef Canvas::Area Area;
|
||||
typedef Canvas::Point Point;
|
||||
|
||||
if (new_section) {
|
||||
canvas->draw_box(Rect(Point(1, y), Area(label_w + 2, label_h - 1)), label_bgcol);
|
||||
canvas->draw_string(Point(1, y - 1), default_font, label_fgcol, _label);
|
||||
canvas->draw_box(Rect(Point(1, y + label_h - 1), Area(label_w + 2, 1)), Color(0, 0, 0));
|
||||
canvas->draw_box(Rect(Point(label_w + 2, y), Area(1, label_h - 1)), _color);
|
||||
canvas->draw_box(Rect(Point(label_w + 3, y), Area(1, label_h - 1)), Color(0, 0, 0));
|
||||
canvas->draw_box(Rect(Point(label_w + 4, y), Area(1000, label_h)), text_bgcol);
|
||||
canvas->draw_box(Rect(Point(label_w + 4, y), Area(1000, 1)), Color(0, 0, 0));
|
||||
canvas.draw_box(Rect(Point(1, y), Area(label_w + 2, label_h - 1)), label_bgcol);
|
||||
canvas.draw_string(Point(1, y - 1), default_font, label_fgcol, _label);
|
||||
canvas.draw_box(Rect(Point(1, y + label_h - 1), Area(label_w + 2, 1)), Color(0, 0, 0));
|
||||
canvas.draw_box(Rect(Point(label_w + 2, y), Area(1, label_h - 1)), _color);
|
||||
canvas.draw_box(Rect(Point(label_w + 3, y), Area(1, label_h - 1)), Color(0, 0, 0));
|
||||
canvas.draw_box(Rect(Point(label_w + 4, y), Area(1000, label_h)), text_bgcol);
|
||||
canvas.draw_box(Rect(Point(label_w + 4, y), Area(1000, 1)), Color(0, 0, 0));
|
||||
} else
|
||||
canvas->draw_box(Rect(Point(1, y), Area(1000, label_h)), text_bgcol);
|
||||
canvas.draw_box(Rect(Point(1, y), Area(1000, label_h)), text_bgcol);
|
||||
|
||||
/* draw log text */
|
||||
canvas->draw_string(Point(label_w + 6, y), default_font, text_fgcol, _text);
|
||||
canvas.draw_string(Point(label_w + 6, y), default_font, text_fgcol, _text);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,7 +177,7 @@ class Log_window
|
||||
{
|
||||
private:
|
||||
|
||||
Canvas *_canvas; /* graphics backend */
|
||||
Canvas_base &_canvas;
|
||||
Log_entry _entries[LOG_H]; /* log entries */
|
||||
int _dst_entry; /* destination entry for next write */
|
||||
int _view_pos; /* current view port on the entry array */
|
||||
@ -148,8 +191,9 @@ class Log_window
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Log_window(Canvas *canvas):
|
||||
_canvas(canvas), _dst_entry(0), _view_pos(0), _dirty(true) { }
|
||||
Log_window(Canvas_base &canvas)
|
||||
: _canvas(canvas), _dst_entry(0), _view_pos(0), _dirty(true)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Write log entry
|
||||
@ -366,22 +410,19 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
|
||||
|
||||
typedef Canvas::Point Point;
|
||||
typedef Canvas::Area Area;
|
||||
typedef Canvas::Rect Rect;
|
||||
|
||||
/* create log window */
|
||||
void *addr = env()->rm_session()->attach(nitpicker.framebuffer()->dataspace());
|
||||
static Chunky_canvas<Pixel_rgb565> canvas((Pixel_rgb565 *)addr,
|
||||
Area(log_win_w, log_win_h));
|
||||
static Log_window log_window(&canvas);
|
||||
|
||||
static Canvas<Pixel_rgb565> canvas((Pixel_rgb565 *)addr,
|
||||
::Area(log_win_w, log_win_h));
|
||||
static Log_window log_window(canvas);
|
||||
|
||||
/*
|
||||
* We clip a border of one pixel off the canvas. This way, the
|
||||
* border remains unaffected by the drawing operations and
|
||||
* acts as an outline for the log window.
|
||||
*/
|
||||
canvas.clip(Rect(Point(1, 1), Area(log_win_w - 2, log_win_h - 2)));
|
||||
canvas.clip(::Rect(::Point(1, 1), ::Area(log_win_w - 2, log_win_h - 2)));
|
||||
|
||||
/* create view for log window */
|
||||
Log_view log_view(&nitpicker, 20, 20, log_win_w, log_win_h);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <input/event.h>
|
||||
#include <os/config.h>
|
||||
#include <util/color.h>
|
||||
#include <os/pixel_rgb565.h>
|
||||
|
||||
/* terminal includes */
|
||||
#include <terminal/decoder.h>
|
||||
@ -34,8 +35,11 @@
|
||||
#include <terminal_session/terminal_session.h>
|
||||
|
||||
/* nitpicker graphic back end */
|
||||
#include <nitpicker_gfx/font.h>
|
||||
#include <nitpicker_gfx/pixel_rgb565.h>
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
|
||||
|
||||
using Genode::Pixel_rgb565;
|
||||
typedef Text_painter::Font Font;
|
||||
|
||||
|
||||
static bool const verbose = false;
|
||||
|
@ -1,3 +0,0 @@
|
||||
This directory contains the very simplistic graphics back end
|
||||
used by Nitpicker. It is placed at this public location to make
|
||||
it directly usable by other applications than Nitpicker.
|
58
os/include/nitpicker_gfx/box_painter.h
Normal file
58
os/include/nitpicker_gfx/box_painter.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief Functor for drawing filled boxes into a surface
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__NITPICKER_GFX__BOX_PAINTER_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__BOX_PAINTER_H_
|
||||
|
||||
#include <os/surface.h>
|
||||
|
||||
|
||||
struct Box_painter
|
||||
{
|
||||
typedef Genode::Surface_base::Rect Rect;
|
||||
|
||||
/**
|
||||
* Draw filled box
|
||||
*
|
||||
* \param rect position and size of box
|
||||
* \param color drawing color
|
||||
*/
|
||||
template <typename PT>
|
||||
static inline void paint(Genode::Surface<PT> &surface,
|
||||
Rect rect,
|
||||
Genode::Color color)
|
||||
{
|
||||
Rect clipped = Rect::intersect(surface.clip(), rect);
|
||||
|
||||
if (!clipped.valid()) return;
|
||||
|
||||
PT pix(color.r, color.g, color.b);
|
||||
PT *dst, *dst_line = surface.addr() + surface.size().w()*clipped.y1() + clipped.x1();
|
||||
|
||||
int const alpha = color.a;
|
||||
|
||||
if (color.is_opaque())
|
||||
for (int w, h = clipped.h() ; h--; dst_line += surface.size().w())
|
||||
for (dst = dst_line, w = clipped.w(); w--; dst++)
|
||||
*dst = pix;
|
||||
|
||||
else if (!color.is_transparent())
|
||||
for (int w, h = clipped.h() ; h--; dst_line += surface.size().w())
|
||||
for (dst = dst_line, w = clipped.w(); w--; dst++)
|
||||
*dst = PT::mix(*dst, pix, alpha);
|
||||
|
||||
surface.flush_pixels(clipped);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__BOX_PAINTER_H_ */
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* \brief Generic interface of graphics backend
|
||||
* \date 2006-08-04
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__NITPICKER_GFX__CANVAS_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__CANVAS_H_
|
||||
|
||||
#include <util/geometry.h>
|
||||
#include <util/color.h>
|
||||
|
||||
#include <nitpicker_gfx/font.h>
|
||||
|
||||
|
||||
class Texture : public Genode::Area<>
|
||||
{
|
||||
public:
|
||||
|
||||
Texture(Area<> size): Area<>(size) { }
|
||||
|
||||
virtual ~Texture() { }
|
||||
|
||||
/**
|
||||
* Return pointer to alpha values, or 0 if no alpha channel exists
|
||||
*/
|
||||
virtual unsigned char const *alpha() const { return 0; }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* A canvas is a rectangular surface to which drawing operations can be
|
||||
* applied. All coordinates are specified in pixels. The coordinate origin
|
||||
* is the top-left corner of the canvas.
|
||||
*/
|
||||
class Canvas
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Genode::Point<> Point;
|
||||
typedef Genode::Area<> Area;
|
||||
typedef Genode::Rect<> Rect;
|
||||
typedef Genode::Color Color;
|
||||
|
||||
protected:
|
||||
|
||||
Rect _clip; /* clipping area */
|
||||
Area _size; /* boundaries of canvas */
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Canvas(Area size) : _clip(Point(0, 0), size), _size(size) { }
|
||||
|
||||
/**
|
||||
* Register canvas area as to be flushed
|
||||
*
|
||||
* This function is called by the graphics primitives when
|
||||
* canvas regions are changed.
|
||||
*/
|
||||
virtual void _flush_pixels(Rect) { }
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Modes for drawing textures
|
||||
*
|
||||
* The solid mode is used for normal operation in Nitpicker's
|
||||
* flat mode and corresponds to plain pixel blitting. The
|
||||
* masked mode allows us to tint texture with a specified
|
||||
* mixing color. This feature is used by the X-Ray and Kill
|
||||
* mode. The masked mode leaves all pixels untouched for
|
||||
* which the corresponding texture pixel equals the mask key
|
||||
* color (we use black). We use this mode for painting
|
||||
* the mouse cursor.
|
||||
*/
|
||||
enum Mode {
|
||||
SOLID = 0, /* draw texture pixel */
|
||||
MIXED = 1, /* mix texture pixel and color 1:1 */
|
||||
MASKED = 2, /* skip pixels with mask color */
|
||||
};
|
||||
|
||||
virtual ~Canvas() { }
|
||||
|
||||
/**
|
||||
* Define/request clipping rectangle
|
||||
*/
|
||||
void clip(Rect clip) {
|
||||
_clip = Rect::intersect(Rect(Point(0, 0), _size), clip); }
|
||||
|
||||
Rect clip() const { return _clip; }
|
||||
bool clip_valid() const { return _clip.valid(); }
|
||||
|
||||
/**
|
||||
* Return dimension of canvas in pixels
|
||||
*/
|
||||
Area size() const { return _size; }
|
||||
|
||||
/**
|
||||
* Draw filled box
|
||||
*
|
||||
* \param rect position and size of box.
|
||||
* \param color drawing color.
|
||||
*/
|
||||
virtual void draw_box(Rect rect, Color color) = 0;
|
||||
|
||||
/**
|
||||
* Draw string
|
||||
*/
|
||||
virtual void draw_string(Point position, Font const &font, Color color,
|
||||
const char *str) = 0;
|
||||
|
||||
/**
|
||||
* Draw texture
|
||||
*/
|
||||
virtual void draw_texture(Texture const &src, Color mix_color, Point position,
|
||||
Mode mode, bool allow_alpha = true) = 0;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__CANVAS_H_ */
|
@ -1,202 +0,0 @@
|
||||
/*
|
||||
* \brief Canvas storing each pixel in one storage unit in a linear buffer
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__NITPICKER_GFX__CHUNKY_CANVAS_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__CHUNKY_CANVAS_H_
|
||||
|
||||
#include <blit/blit.h>
|
||||
#include "canvas.h"
|
||||
|
||||
|
||||
template <typename PT>
|
||||
class Chunky_texture : public Texture
|
||||
{
|
||||
private:
|
||||
|
||||
PT const *_pixels;
|
||||
unsigned char const *_alpha;
|
||||
|
||||
public:
|
||||
|
||||
Chunky_texture(PT const *pixels, unsigned char const *alpha, Area size)
|
||||
: Texture(size), _pixels(pixels), _alpha(alpha) { }
|
||||
|
||||
PT const *pixels() const { return _pixels; }
|
||||
|
||||
unsigned char const *alpha() const { return _alpha; }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* \param PT pixel type
|
||||
*/
|
||||
template <typename PT>
|
||||
class Chunky_canvas : public Canvas
|
||||
{
|
||||
protected:
|
||||
|
||||
PT *_addr; /* base address of pixel buffer */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Chunky_canvas(PT *addr, Area size): Canvas(size), _addr(addr) { }
|
||||
|
||||
|
||||
/****************************************
|
||||
** Implementation of Canvas interface **
|
||||
****************************************/
|
||||
|
||||
void draw_box(Rect rect, Color color)
|
||||
{
|
||||
Rect clipped = Rect::intersect(_clip, rect);
|
||||
|
||||
if (!clipped.valid()) return;
|
||||
|
||||
PT pix(color.r, color.g, color.b);
|
||||
PT *dst, *dst_line = _addr + _size.w()*clipped.y1() + clipped.x1();
|
||||
|
||||
for (int w, h = clipped.h() ; h--; dst_line += _size.w())
|
||||
for (dst = dst_line, w = clipped.w(); w--; dst++)
|
||||
*dst = pix;
|
||||
|
||||
_flush_pixels(clipped);
|
||||
}
|
||||
|
||||
void draw_string(Point p, Font const &font, Color color, char const *sstr)
|
||||
{
|
||||
unsigned char const *str = (unsigned char const *)sstr;
|
||||
int x = p.x(), y = p.y();
|
||||
|
||||
unsigned char const *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 && (x + font.wtab[*str] < _clip.x1()); )
|
||||
x += font.wtab[*str++];
|
||||
|
||||
int x_start = x;
|
||||
|
||||
PT *dst = _addr + y*_size.w();
|
||||
PT pix(color.r, color.g, color.b);
|
||||
|
||||
/* draw glyphs */
|
||||
for ( ; *str && (x <= _clip.x2()); str++) {
|
||||
|
||||
int w = font.wtab[*str];
|
||||
int start = Genode::max(0, _clip.x1() - x);
|
||||
int end = Genode::min(w - 1, _clip.x2() - x);
|
||||
PT *d = dst + x;
|
||||
unsigned char const *s = src + font.otab[*str];
|
||||
|
||||
for (int j = 0; j < h; j++, s += font.img_w, d += _size.w())
|
||||
for (int i = start; i <= end; i++)
|
||||
if (s[i]) d[i] = pix;
|
||||
|
||||
x += w;
|
||||
}
|
||||
|
||||
_flush_pixels(Rect(Point(x_start, y), Area(x - x_start + 1, h)));
|
||||
}
|
||||
|
||||
void draw_texture(Texture const &texture, Color mix_color, Point position,
|
||||
Mode mode, bool allow_alpha)
|
||||
{
|
||||
Rect clipped = Rect::intersect(Rect(position, texture), _clip);
|
||||
|
||||
if (!clipped.valid()) return;
|
||||
|
||||
int const src_w = texture.w();
|
||||
int const dst_w = _size.w();
|
||||
|
||||
Chunky_texture<PT> const &tex = static_cast<Chunky_texture<PT> const &>(texture);
|
||||
|
||||
/* calculate offset of first texture pixel to copy */
|
||||
unsigned long tex_start_offset = (clipped.y1() - position.y())*src_w
|
||||
+ clipped.x1() - position.x();
|
||||
|
||||
/* start address of source pixels */
|
||||
PT const *src = tex.pixels() + tex_start_offset;
|
||||
|
||||
/* start address of source alpha values */
|
||||
unsigned char const *alpha = tex.alpha() + tex_start_offset;
|
||||
|
||||
/* start address of destination pixels */
|
||||
PT *dst = _addr + clipped.y1()*dst_w + clipped.x1();
|
||||
|
||||
PT mix_pixel(mix_color.r, mix_color.g, mix_color.b);
|
||||
|
||||
int i, j;
|
||||
PT const *s;
|
||||
PT *d;
|
||||
unsigned char const *a;
|
||||
|
||||
switch (mode) {
|
||||
|
||||
case SOLID:
|
||||
|
||||
/*
|
||||
* If the texture has no alpha channel, we can use
|
||||
* a plain pixel blit.
|
||||
*/
|
||||
if (tex.alpha() == 0 || !allow_alpha) {
|
||||
blit(src, src_w*sizeof(PT),
|
||||
dst, dst_w*sizeof(PT),
|
||||
clipped.w()*sizeof(PT), clipped.h());
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy texture with alpha blending
|
||||
*/
|
||||
for (j = clipped.h(); j--; src += src_w, alpha += src_w, dst += dst_w)
|
||||
for (i = clipped.w(), s = src, a = alpha, d = dst; i--; s++, d++, a++)
|
||||
if (*a)
|
||||
*d = PT::mix(*d, *s, *a);
|
||||
break;
|
||||
|
||||
case MIXED:
|
||||
|
||||
for (j = clipped.h(); j--; src += src_w, dst += dst_w)
|
||||
for (i = clipped.w(), s = src, d = dst; i--; s++, d++)
|
||||
*d = PT::avr(mix_pixel, *s);
|
||||
break;
|
||||
|
||||
case MASKED:
|
||||
|
||||
for (j = clipped.h(); j--; src += src_w, dst += dst_w)
|
||||
for (i = clipped.w(), s = src, d = dst; i--; s++, d++)
|
||||
if (s->pixel) *d = *s;
|
||||
break;
|
||||
}
|
||||
|
||||
_flush_pixels(clipped);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__CHUNKY_CANVAS_H_ */
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* \brief Font representation
|
||||
* \date 2005-10-24
|
||||
* \author Norman Feske
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__NITPICKER_GFX__FONT_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__FONT_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
class Font
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Genode::int32_t int32_t;
|
||||
|
||||
public:
|
||||
|
||||
unsigned char const *img; /* font image */
|
||||
int const img_w, img_h; /* size of font image */
|
||||
int32_t const *otab; /* offset table */
|
||||
int32_t const *wtab; /* width table */
|
||||
|
||||
/**
|
||||
* Construct font from a TFF data block
|
||||
*/
|
||||
Font(const char *tff)
|
||||
:
|
||||
img((unsigned char *)(tff + 2056)),
|
||||
|
||||
img_w(*((int32_t *)(tff + 2048))),
|
||||
img_h(*((int32_t *)(tff + 2052))),
|
||||
|
||||
otab((int32_t *)(tff)),
|
||||
wtab((int32_t *)(tff + 1024))
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Calculate width of string when printed with the font
|
||||
*/
|
||||
int str_w(const char *sstr) const
|
||||
{
|
||||
const unsigned char *str = (const unsigned char *)sstr;
|
||||
int res = 0;
|
||||
for (; str && *str; str++) res += wtab[*str];
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate height of string when printed with the font
|
||||
*/
|
||||
int str_h(const char *str) const { return img_h; }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__FONT_H_ */
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* \brief Generic pixel representation
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__NITPICKER_GFX__PIXEL_RGB_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__PIXEL_RGB_H_
|
||||
|
||||
/*
|
||||
* \param ST storage type of one pixel
|
||||
*/
|
||||
template <typename ST, int R_MASK, int R_SHIFT,
|
||||
int G_MASK, int G_SHIFT,
|
||||
int B_MASK, int B_SHIFT>
|
||||
class Pixel_rgb
|
||||
{
|
||||
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;
|
||||
|
||||
ST pixel;
|
||||
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
Pixel_rgb() {}
|
||||
|
||||
Pixel_rgb(int red, int green, int blue):
|
||||
pixel((_shift(red, r_shift) & r_mask)
|
||||
| (_shift(green, g_shift) & g_mask)
|
||||
| (_shift(blue, b_shift) & b_mask)) { }
|
||||
|
||||
/**
|
||||
* Compute average color value of two pixels
|
||||
*/
|
||||
static inline Pixel_rgb avr(Pixel_rgb p1, Pixel_rgb p2);
|
||||
|
||||
/**
|
||||
* Multiply pixel with alpha value
|
||||
*/
|
||||
static inline Pixel_rgb blend(Pixel_rgb pixel, int alpha);
|
||||
|
||||
/**
|
||||
* Mix two pixels at the ratio specified as alpha
|
||||
*/
|
||||
static inline Pixel_rgb mix(Pixel_rgb p1, Pixel_rgb p2, int alpha);
|
||||
|
||||
/**
|
||||
* Return alpha value of pixel
|
||||
*/
|
||||
int alpha();
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__PIXEL_RGB_H_ */
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* \brief Template specializations for the RGB565 pixel format
|
||||
* \date 2006-08-04
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__NITPICKER_GFX__PIXEL_RGB565_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__PIXEL_RGB565_H_
|
||||
|
||||
#include "pixel_rgb.h"
|
||||
|
||||
typedef Pixel_rgb<unsigned short, 0xf800, 8, 0x07e0, 3, 0x001f, -3> Pixel_rgb565;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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_rgb 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;
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__PIXEL_RGB565_H_ */
|
133
os/include/nitpicker_gfx/text_painter.h
Normal file
133
os/include/nitpicker_gfx/text_painter.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* \brief Functor for drawing text into a surface
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__NITPICKER_GFX__TEXT_PAINTER_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__TEXT_PAINTER_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
#include <os/surface.h>
|
||||
|
||||
|
||||
struct Text_painter
|
||||
{
|
||||
class Font
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Genode::int32_t int32_t;
|
||||
typedef Genode::size_t size_t;
|
||||
|
||||
public:
|
||||
|
||||
unsigned char const *img; /* font image */
|
||||
int const img_w, img_h; /* size of font image */
|
||||
int32_t const *otab; /* offset table */
|
||||
int32_t const *wtab; /* width table */
|
||||
|
||||
/**
|
||||
* Construct font from a TFF data block
|
||||
*/
|
||||
Font(const char *tff)
|
||||
:
|
||||
img((unsigned char *)(tff + 2056)),
|
||||
|
||||
img_w(*((int32_t *)(tff + 2048))),
|
||||
img_h(*((int32_t *)(tff + 2052))),
|
||||
|
||||
otab((int32_t *)(tff)),
|
||||
wtab((int32_t *)(tff + 1024))
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Calculate width of string when printed with the font
|
||||
*/
|
||||
int str_w(const char *sstr, size_t len = ~0UL) const
|
||||
{
|
||||
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, size_t len = ~0UL) const { return img_h; }
|
||||
};
|
||||
|
||||
|
||||
typedef Genode::Surface_base::Point Point;
|
||||
typedef Genode::Surface_base::Area Area;
|
||||
typedef Genode::Surface_base::Rect Rect;
|
||||
|
||||
|
||||
template <typename PT>
|
||||
static inline void paint(Genode::Surface<PT> &surface,
|
||||
Point p,
|
||||
Font const &font,
|
||||
Genode::Color color,
|
||||
char const *sstr)
|
||||
{
|
||||
unsigned char const *str = (unsigned char const *)sstr;
|
||||
int x = p.x(), y = p.y();
|
||||
|
||||
unsigned char const *src = font.img;
|
||||
int d, h = font.img_h;
|
||||
|
||||
/* check top clipping */
|
||||
if ((d = surface.clip().y1() - y) > 0) {
|
||||
src += d*font.img_w;
|
||||
y += d;
|
||||
h -= d;
|
||||
}
|
||||
|
||||
/* check bottom clipping */
|
||||
if ((d = y + h -1 - surface.clip().y2()) > 0)
|
||||
h -= d;
|
||||
|
||||
if (h < 1) return;
|
||||
|
||||
/* skip hidden glyphs */
|
||||
for ( ; *str && (x + font.wtab[*str] < surface.clip().x1()); )
|
||||
x += font.wtab[*str++];
|
||||
|
||||
int const x_start = x;
|
||||
|
||||
PT *dst = surface.addr() + y*surface.size().w();
|
||||
|
||||
PT const pix(color.r, color.g, color.b);
|
||||
int const alpha = color.a;
|
||||
|
||||
/* draw glyphs */
|
||||
for ( ; *str && (x <= surface.clip().x2()); str++) {
|
||||
|
||||
int const w = font.wtab[*str];
|
||||
int const start = Genode::max(0, surface.clip().x1() - x);
|
||||
int const end = Genode::min(w - 1, surface.clip().x2() - x);
|
||||
|
||||
PT *d = dst + x;
|
||||
unsigned char const *s = src + font.otab[*str];
|
||||
|
||||
for (int j = 0; j < h; j++, s += font.img_w, d += surface.size().w())
|
||||
for (int i = start; i <= end; i++)
|
||||
if (s[i])
|
||||
d[i] = (s[i] == 255 && alpha == 255)
|
||||
? pix : PT::mix(d[i], pix, (alpha*s[i]) >> 8);
|
||||
x += w;
|
||||
}
|
||||
|
||||
surface.flush_pixels(Rect(Point(x_start, y), Area(x - x_start + 1, h)));
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__TEXT_PAINTER_H_ */
|
125
os/include/nitpicker_gfx/texture_painter.h
Normal file
125
os/include/nitpicker_gfx/texture_painter.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* \brief Functor for painting textures on a surface
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__NITPICKER_GFX__TEXTURE_PAINTER_H_
|
||||
#define _INCLUDE__NITPICKER_GFX__TEXTURE_PAINTER_H_
|
||||
|
||||
#include <blit/blit.h>
|
||||
#include <os/texture.h>
|
||||
|
||||
|
||||
struct Texture_painter
|
||||
{
|
||||
/*
|
||||
* Modes for drawing textures
|
||||
*
|
||||
* The solid mode is used for normal operation in Nitpicker's
|
||||
* flat mode and corresponds to plain pixel blitting. The
|
||||
* masked mode allows us to tint texture with a specified
|
||||
* mixing color. This feature is used by the X-Ray and Kill
|
||||
* mode. The masked mode leaves all pixels untouched for
|
||||
* which the corresponding texture pixel equals the mask key
|
||||
* color (we use black). We use this mode for painting
|
||||
* the mouse cursor.
|
||||
*/
|
||||
enum Mode {
|
||||
SOLID = 0, /* draw texture pixel */
|
||||
MIXED = 1, /* mix texture pixel and color 1:1 */
|
||||
MASKED = 2, /* skip pixels with mask color */
|
||||
};
|
||||
|
||||
|
||||
typedef Genode::Surface_base::Point Point;
|
||||
typedef Genode::Surface_base::Rect Rect;
|
||||
|
||||
|
||||
template <typename PT>
|
||||
static inline void paint(Genode::Surface<PT> &surface,
|
||||
Genode::Texture<PT> const &texture,
|
||||
Genode::Color mix_color,
|
||||
Point position,
|
||||
Mode mode,
|
||||
bool allow_alpha)
|
||||
{
|
||||
Rect clipped = Rect::intersect(Rect(position, texture.size()),
|
||||
surface.clip());
|
||||
|
||||
if (!clipped.valid()) return;
|
||||
|
||||
int const src_w = texture.size().w();
|
||||
int const dst_w = surface.size().w();
|
||||
|
||||
/* calculate offset of first texture pixel to copy */
|
||||
unsigned long tex_start_offset = (clipped.y1() - position.y())*src_w
|
||||
+ clipped.x1() - position.x();
|
||||
|
||||
/* start address of source pixels */
|
||||
PT const *src = texture.pixel() + tex_start_offset;
|
||||
|
||||
/* start address of source alpha values */
|
||||
unsigned char const *alpha = texture.alpha() + tex_start_offset;
|
||||
|
||||
/* start address of destination pixels */
|
||||
PT *dst = surface.addr() + clipped.y1()*dst_w + clipped.x1();
|
||||
|
||||
PT const mix_pixel(mix_color.r, mix_color.g, mix_color.b);
|
||||
|
||||
int i, j;
|
||||
PT const *s;
|
||||
PT *d;
|
||||
unsigned char const *a;
|
||||
|
||||
switch (mode) {
|
||||
|
||||
case SOLID:
|
||||
|
||||
/*
|
||||
* If the texture has no alpha channel, we can use
|
||||
* a plain pixel blit.
|
||||
*/
|
||||
if (texture.alpha() == 0 || !allow_alpha) {
|
||||
blit(src, src_w*sizeof(PT),
|
||||
dst, dst_w*sizeof(PT),
|
||||
clipped.w()*sizeof(PT), clipped.h());
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy texture with alpha blending
|
||||
*/
|
||||
for (j = clipped.h(); j--; src += src_w, alpha += src_w, dst += dst_w)
|
||||
for (i = clipped.w(), s = src, a = alpha, d = dst; i--; s++, d++, a++)
|
||||
if (*a)
|
||||
*d = PT::mix(*d, *s, *a);
|
||||
break;
|
||||
|
||||
case MIXED:
|
||||
|
||||
for (j = clipped.h(); j--; src += src_w, dst += dst_w)
|
||||
for (i = clipped.w(), s = src, d = dst; i--; s++, d++)
|
||||
*d = PT::avr(mix_pixel, *s);
|
||||
break;
|
||||
|
||||
case MASKED:
|
||||
|
||||
for (j = clipped.h(); j--; src += src_w, dst += dst_w)
|
||||
for (i = clipped.w(), s = src, d = dst; i--; s++, d++)
|
||||
if (s->pixel) *d = *s;
|
||||
break;
|
||||
}
|
||||
|
||||
surface.flush_pixels(clipped);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NITPICKER_GFX__TEXTURE_PAINTER_H_ */
|
@ -20,7 +20,7 @@
|
||||
namespace Nitpicker { struct Session_client; }
|
||||
|
||||
|
||||
struct Nitpicker::Session_client : public Rpc_client<Session>
|
||||
struct Nitpicker::Session_client : public Genode::Rpc_client<Session>
|
||||
{
|
||||
explicit Session_client(Session_capability session)
|
||||
: Rpc_client<Session>(session) { }
|
||||
|
@ -43,6 +43,7 @@ class Nitpicker::Connection : public Genode::Connection<Session>,
|
||||
/*
|
||||
* Declare ram-quota donation
|
||||
*/
|
||||
using Genode::Arg_string;
|
||||
enum { SESSION_METADATA = 20*1024 };
|
||||
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
|
||||
|
||||
@ -74,10 +75,10 @@ class Nitpicker::Connection : public Genode::Connection<Session>,
|
||||
char argbuf[ARGBUF_SIZE];
|
||||
argbuf[0] = 0;
|
||||
|
||||
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota",
|
||||
ram_quota(mode, use_alpha));
|
||||
Genode::Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota",
|
||||
ram_quota(mode, use_alpha));
|
||||
|
||||
env()->parent()->upgrade(cap(), argbuf);
|
||||
Genode::env()->parent()->upgrade(cap(), argbuf);
|
||||
Session_client::buffer(mode, use_alpha);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <nitpicker_view/capability.h>
|
||||
|
||||
namespace Nitpicker {
|
||||
using namespace Genode;
|
||||
using Genode::size_t;
|
||||
struct Session;
|
||||
}
|
||||
|
||||
|
61
os/include/os/pixel_rgb565.h
Normal file
61
os/include/os/pixel_rgb565.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* \brief Template specializations for the RGB565 pixel format
|
||||
* \date 2006-08-04
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__OS__PIXEL_RGB565_H_
|
||||
#define _INCLUDE__OS__PIXEL_RGB565_H_
|
||||
|
||||
#include <os/pixel_rgba.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
typedef Pixel_rgba<unsigned short, Surface_base::RGB565,
|
||||
0xf800, 8, 0x07e0, 3, 0x001f, -3, 0, 0>
|
||||
Pixel_rgb565;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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_rgb565 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;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__OS__PIXEL_RGB565_H_ */
|
113
os/include/os/pixel_rgba.h
Normal file
113
os/include/os/pixel_rgba.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* \brief Generic pixel representation
|
||||
* \author Norman Feske
|
||||
* \date 2006-08-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__OS__PIXEL_RGBA_H_
|
||||
#define _INCLUDE__OS__PIXEL_RGBA_H_
|
||||
|
||||
#include <os/surface.h>
|
||||
|
||||
namespace Genode {
|
||||
template <typename ST, Genode::Surface_base::Pixel_format FORMAT,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* \param ST storage type of one pixel
|
||||
* \param FORMAT pixel format
|
||||
*/
|
||||
template <typename ST, Genode::Surface_base::Pixel_format FORMAT,
|
||||
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 Genode::Pixel_rgba
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Shift left with positive or negative shift value
|
||||
*/
|
||||
static 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) :
|
||||
pixel((_shift(red, r_shift) & r_mask)
|
||||
| (_shift(green, g_shift) & g_mask)
|
||||
| (_shift(blue, b_shift) & b_mask)) { }
|
||||
|
||||
static Surface_base::Pixel_format format() { return FORMAT; }
|
||||
|
||||
/**
|
||||
* 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() const { return _shift(pixel & r_mask, -r_shift); }
|
||||
inline int g() const { return _shift(pixel & g_mask, -g_shift); }
|
||||
inline int b() const { return _shift(pixel & b_mask, -b_shift); }
|
||||
|
||||
/**
|
||||
* Compute average color value of two pixels
|
||||
*/
|
||||
static inline Pixel_rgba avr(Pixel_rgba p1, Pixel_rgba p2);
|
||||
|
||||
/**
|
||||
* 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 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)); }
|
||||
|
||||
/**
|
||||
* Return alpha value of pixel
|
||||
*/
|
||||
int alpha();
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* _INCLUDE__OS__PIXEL_RGBA_H_ */
|
122
os/include/os/surface.h
Normal file
122
os/include/os/surface.h
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* \brief Generic interface to a graphics backend
|
||||
* \date 2006-08-04
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__OS__SURFACE_H_
|
||||
#define _INCLUDE__OS__SURFACE_H_
|
||||
|
||||
#include <util/geometry.h>
|
||||
#include <util/color.h>
|
||||
|
||||
namespace Genode {
|
||||
class Surface_base;
|
||||
template <typename> class Surface;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A surface is a rectangular space to which drawing operations can be
|
||||
* applied. All coordinates are specified in pixels. The coordinate origin
|
||||
* is the top-left corner of the surface.
|
||||
*/
|
||||
class Genode::Surface_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Genode::Point<> Point;
|
||||
typedef Genode::Area<> Area;
|
||||
typedef Genode::Rect<> Rect;
|
||||
typedef Genode::Color Color;
|
||||
|
||||
enum Pixel_format { UNKNOWN, RGB565 };
|
||||
|
||||
struct Flusher
|
||||
{
|
||||
virtual void flush_pixels(Rect rect) = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
Rect _clip; /* clipping area */
|
||||
Area _size; /* boundaries of surface */
|
||||
Pixel_format _format;
|
||||
Flusher *_flusher;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Surface_base(Area size, Pixel_format format)
|
||||
: _clip(Point(0, 0), size), _size(size), _format(format), _flusher(0) { }
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Surface_base() { }
|
||||
|
||||
/**
|
||||
* Register part of surface to be flushed
|
||||
*
|
||||
* This function is called by graphics primitives when surface regions
|
||||
* are changed.
|
||||
*/
|
||||
void flush_pixels(Rect rect)
|
||||
{
|
||||
if (_flusher)
|
||||
_flusher->flush_pixels(rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register pixel flusher
|
||||
*/
|
||||
void flusher(Flusher *flusher) { _flusher = flusher; }
|
||||
|
||||
/**
|
||||
* Define/request clipping rectangle
|
||||
*/
|
||||
void clip(Rect clip) {
|
||||
_clip = Rect::intersect(Rect(Point(0, 0), _size), clip); }
|
||||
|
||||
Rect clip() const { return _clip; }
|
||||
bool clip_valid() const { return _clip.valid(); }
|
||||
|
||||
Pixel_format pixel_format() const { return _format; }
|
||||
|
||||
/**
|
||||
* Return dimension of surface in pixels
|
||||
*/
|
||||
Area size() const { return _size; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Surface that stores each pixel in one storage unit in a linear buffer
|
||||
*
|
||||
* \param PT pixel type
|
||||
*/
|
||||
template <typename PT>
|
||||
class Genode::Surface : public Surface_base
|
||||
{
|
||||
protected:
|
||||
|
||||
PT *_addr; /* base address of pixel buffer */
|
||||
|
||||
public:
|
||||
|
||||
PT *addr() { return _addr; }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Surface(PT *addr, Area size)
|
||||
: Surface_base(size, PT::format()), _addr(addr) { }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__OS__SURFACE_H_ */
|
63
os/include/os/texture.h
Normal file
63
os/include/os/texture.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* \brief Texture representation
|
||||
* \author Norman Feske
|
||||
* \date 2013-12-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__OS__TEXTURE_H_
|
||||
#define _INCLUDE__OS__TEXTURE_H_
|
||||
|
||||
#include <os/surface.h>
|
||||
|
||||
namespace Genode {
|
||||
class Texture_base;
|
||||
template <typename PT> class Texture;
|
||||
}
|
||||
|
||||
|
||||
class Genode::Texture_base
|
||||
{
|
||||
private:
|
||||
|
||||
Surface_base::Area _size;
|
||||
|
||||
public:
|
||||
|
||||
Texture_base(Surface_base::Area size) : _size(size) { }
|
||||
|
||||
Surface_base::Area size() const { return _size; }
|
||||
};
|
||||
|
||||
|
||||
template <typename PT>
|
||||
class Genode::Texture : public Texture_base
|
||||
{
|
||||
private:
|
||||
|
||||
PT *_pixel;
|
||||
unsigned char *_alpha;
|
||||
|
||||
public:
|
||||
|
||||
Texture(PT *pixel, unsigned char *alpha, Surface_base::Area size)
|
||||
: Texture_base(size), _pixel(pixel), _alpha(alpha) { }
|
||||
|
||||
PT *pixel() { return _pixel; }
|
||||
PT const *pixel() const { return _pixel; }
|
||||
unsigned char *alpha() { return _alpha; }
|
||||
unsigned char const *alpha() const { return _alpha; }
|
||||
|
||||
/**
|
||||
* Import rgba data line into texture
|
||||
*/
|
||||
void rgba(unsigned char const *rgba, unsigned len, int y);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__OS__TEXTURE_H_ */
|
@ -26,10 +26,15 @@ namespace Genode {
|
||||
|
||||
struct Genode::Color
|
||||
{
|
||||
int r, g, b;
|
||||
int r, g, b, a;
|
||||
|
||||
Color(int red, int green, int blue): r(red), g(green), b(blue) { }
|
||||
Color(): r(0), g(0), b(0) { }
|
||||
bool is_opaque() const { return a == 255; }
|
||||
bool is_transparent() const { return a == 0; }
|
||||
|
||||
Color(int red, int green, int blue, int alpha = 255)
|
||||
: r(red), g(green), b(blue), a(alpha) { }
|
||||
|
||||
Color(): r(0), g(0), b(0), a(0) { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,23 +14,25 @@
|
||||
#ifndef _BACKGROUND_H_
|
||||
#define _BACKGROUND_H_
|
||||
|
||||
#include <nitpicker_gfx/box_painter.h>
|
||||
|
||||
#include "view.h"
|
||||
#include "clip_guard.h"
|
||||
|
||||
struct Background : private Texture, Session, View
|
||||
struct Background : private Texture_base, Session, View
|
||||
{
|
||||
Genode::Color color;
|
||||
Color color;
|
||||
|
||||
/*
|
||||
* The background uses no texture. Therefore
|
||||
* we can pass a null pointer as texture argument
|
||||
* to the Session constructor.
|
||||
*/
|
||||
Background(Canvas::Area size)
|
||||
Background(Area size)
|
||||
:
|
||||
Texture(Area(0, 0)), Session(Genode::Session_label(""), 0, false),
|
||||
Texture_base(Area(0, 0)), Session(Genode::Session_label(""), 0, false),
|
||||
View(*this, View::NOT_STAY_TOP, View::NOT_TRANSPARENT,
|
||||
View::BACKGROUND, Canvas::Rect(Canvas::Point(0, 0), size)),
|
||||
View::BACKGROUND, Rect(Point(0, 0), size)),
|
||||
color(25, 37, 50)
|
||||
{ }
|
||||
|
||||
@ -47,9 +49,9 @@ struct Background : private Texture, Session, View
|
||||
********************/
|
||||
|
||||
int frame_size(Mode const &mode) const { return 0; }
|
||||
void frame(Canvas &canvas, Mode const &mode) { }
|
||||
void frame(Canvas_base &canvas, Mode const &mode) { }
|
||||
|
||||
void draw(Canvas &canvas, Mode const &mode) const
|
||||
void draw(Canvas_base &canvas, Mode const &mode) const
|
||||
{
|
||||
Clip_guard clip_guard(canvas, *this);
|
||||
canvas.draw_box(*this, color);
|
||||
|
102
os/src/server/nitpicker/canvas.h
Normal file
102
os/src/server/nitpicker/canvas.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* \brief Graphics backend used by nitpicker
|
||||
* \author Norman Feske
|
||||
* \date 2013-12-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _CANVAS_H_
|
||||
#define _CANVAS_H_
|
||||
|
||||
#include <nitpicker_gfx/box_painter.h>
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
#include <nitpicker_gfx/texture_painter.h>
|
||||
|
||||
typedef Genode::Surface_base::Area Area;
|
||||
typedef Genode::Surface_base::Point Point;
|
||||
typedef Genode::Surface_base::Rect Rect;
|
||||
typedef Genode::Color Color;
|
||||
|
||||
using Genode::Texture_base;
|
||||
using Genode::Texture;
|
||||
|
||||
|
||||
/**
|
||||
* Pixel-type-independent interface of nitpicker's graphics backend
|
||||
*/
|
||||
struct Canvas_base
|
||||
{
|
||||
virtual Area size() const = 0;
|
||||
|
||||
virtual Rect clip() const = 0;
|
||||
|
||||
virtual void clip(Rect) = 0;
|
||||
|
||||
virtual void flush_pixels(Rect) = 0;
|
||||
|
||||
virtual void draw_box(Rect, Color) = 0;
|
||||
|
||||
virtual void draw_texture(Point, Texture_base const &, Texture_painter::Mode,
|
||||
Color mix_color, bool allow_alpha) = 0;
|
||||
|
||||
virtual void draw_text(Point, Text_painter::Font const &, Color,
|
||||
char const *string) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pixel-type-specific implementation of nitpicker's graphics backend
|
||||
*/
|
||||
template <typename PT>
|
||||
class Canvas : public Canvas_base, public Genode::Surface_base::Flusher
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Surface<PT> _surface;
|
||||
|
||||
public:
|
||||
|
||||
Canvas(PT *base, Area size) : _surface(base, size)
|
||||
{
|
||||
_surface.flusher(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of Surface_base::Flusher interface
|
||||
*/
|
||||
void flush_pixels(Rect) { }
|
||||
|
||||
Area size() const { return _surface.size(); }
|
||||
|
||||
Rect clip() const { return _surface.clip(); }
|
||||
|
||||
void clip(Rect rect) { _surface.clip(rect); }
|
||||
|
||||
void draw_box(Rect rect, Color color)
|
||||
{
|
||||
Box_painter::paint(_surface, rect, color);
|
||||
}
|
||||
|
||||
void draw_texture(Point pos, Texture_base const &texture_base,
|
||||
Texture_painter::Mode mode, Color mix_color,
|
||||
bool allow_alpha)
|
||||
{
|
||||
Texture<PT> const &texture = static_cast<Texture<PT> const &>(texture_base);
|
||||
Texture_painter::paint(_surface, texture, mix_color, pos, mode,
|
||||
allow_alpha);
|
||||
}
|
||||
|
||||
void draw_text(Point pos, Text_painter::Font const &font,
|
||||
Color color, char const *string)
|
||||
{
|
||||
Text_painter::paint(_surface, pos, font, color, string);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _CANVAS_H_ */
|
@ -14,26 +14,32 @@
|
||||
#ifndef _CHUNKY_MENUBAR_
|
||||
#define _CHUNKY_MENUBAR_
|
||||
|
||||
#include <nitpicker_gfx/chunky_canvas.h>
|
||||
#include <nitpicker_gfx/box_painter.h>
|
||||
#include <nitpicker_gfx/texture_painter.h>
|
||||
|
||||
#include "menubar.h"
|
||||
|
||||
template <typename PT>
|
||||
class Chunky_menubar : public Chunky_texture<PT>,
|
||||
public Session, public Menubar
|
||||
class Chunky_menubar : public Texture<PT>,
|
||||
public Session,
|
||||
public Menubar,
|
||||
public View
|
||||
{
|
||||
private:
|
||||
|
||||
Chunky_canvas<PT> _chunky_canvas;
|
||||
Canvas<PT> _canvas;
|
||||
|
||||
public:
|
||||
|
||||
Chunky_menubar(PT *pixels, Canvas::Area size)
|
||||
Chunky_menubar(PT *pixels, Area size)
|
||||
:
|
||||
Chunky_texture<PT>(pixels, 0, size),
|
||||
Texture<PT>(pixels, 0, size),
|
||||
Session(Genode::Session_label(""), 0, false),
|
||||
Menubar(_chunky_canvas, size, *this), _chunky_canvas(pixels, size)
|
||||
View(*this, View::STAY_TOP, View::NOT_TRANSPARENT,
|
||||
View::NOT_BACKGROUND, Rect(Point(0, 0), size)),
|
||||
_canvas(pixels, size)
|
||||
{
|
||||
Session::texture(this);
|
||||
Session::texture(this, false);
|
||||
}
|
||||
|
||||
|
||||
@ -49,13 +55,47 @@ class Chunky_menubar : public Chunky_texture<PT>,
|
||||
********************/
|
||||
|
||||
int frame_size(Mode const &mode) const { return 0; }
|
||||
void frame(Canvas &canvas, Mode const &mode) { }
|
||||
void draw(Canvas const &canvas, Mode const &mode)
|
||||
void frame(Canvas_base &canvas, Mode const &mode) { }
|
||||
void draw(Canvas_base &canvas, Mode const &mode)
|
||||
{
|
||||
Clip_guard clip_guard(canvas, *this);
|
||||
|
||||
/* draw menubar content */
|
||||
canvas.draw_texture(*this, BLACK, p1(), Canvas::SOLID);
|
||||
canvas.draw_texture(p1(), *this, Texture_painter::SOLID, BLACK, false);
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** Menubar interface **
|
||||
***********************/
|
||||
|
||||
void state(Mode const &mode, char const *session_label,
|
||||
char const *view_title, Color session_color)
|
||||
{
|
||||
/* choose base color dependent on the Nitpicker state */
|
||||
int r = (mode.kill()) ? 200 : (mode.xray()) ? session_color.r : (session_color.r + 100) >> 1;
|
||||
int g = (mode.kill()) ? 70 : (mode.xray()) ? session_color.g : (session_color.g + 100) >> 1;
|
||||
int b = (mode.kill()) ? 70 : (mode.xray()) ? session_color.b : (session_color.b + 100) >> 1;
|
||||
|
||||
/* highlight first line with slightly brighter color */
|
||||
_canvas.draw_box(Rect(Point(0, 0), Area(View::w(), 1)),
|
||||
Color(r + (r / 2), g + (g / 2), b + (b / 2)));
|
||||
|
||||
/* draw slightly shaded background */
|
||||
for (unsigned i = 1; i < View::h() - 1; i++) {
|
||||
r -= r > 3 ? 4 : 0;
|
||||
g -= g > 3 ? 4 : 0;
|
||||
b -= b > 4 ? 4 : 0;
|
||||
_canvas.draw_box(Rect(Point(0, i), Area(View::w(), 1)), Color(r, g, b));
|
||||
}
|
||||
|
||||
/* draw last line darker */
|
||||
_canvas.draw_box(Rect(Point(0, View::h() - 1), Area(View::w(), 1)),
|
||||
Color(r / 4, g / 4, b / 4));
|
||||
|
||||
/* draw label */
|
||||
draw_label(_canvas, center(label_size(session_label, view_title)),
|
||||
session_label, WHITE, view_title, session_color);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -28,24 +28,24 @@
|
||||
#ifndef _CLIP_GUARD_H_
|
||||
#define _CLIP_GUARD_H_
|
||||
|
||||
#include <nitpicker_gfx/canvas.h>
|
||||
#include "canvas.h"
|
||||
|
||||
class Clip_guard
|
||||
{
|
||||
private:
|
||||
|
||||
Canvas &_canvas;
|
||||
Canvas_base &_canvas;
|
||||
|
||||
Canvas::Rect const _orig_clip_rect;
|
||||
Rect const _orig_clip_rect;
|
||||
|
||||
public:
|
||||
|
||||
Clip_guard(Canvas &canvas, Canvas::Rect new_clip_rect)
|
||||
Clip_guard(Canvas_base &canvas, Rect new_clip_rect)
|
||||
:
|
||||
_canvas(canvas),
|
||||
_orig_clip_rect(_canvas.clip())
|
||||
{
|
||||
_canvas.clip(Canvas::Rect::intersect(_orig_clip_rect, new_clip_rect));
|
||||
_canvas.clip(Rect::intersect(_orig_clip_rect, new_clip_rect));
|
||||
}
|
||||
|
||||
~Clip_guard() { _canvas.clip(_orig_clip_rect); }
|
||||
|
@ -14,7 +14,9 @@
|
||||
#ifndef _DRAW_LABEL_H_
|
||||
#define _DRAW_LABEL_H_
|
||||
|
||||
extern Font default_font;
|
||||
#include "canvas.h"
|
||||
|
||||
extern Text_painter::Font default_font;
|
||||
|
||||
/*
|
||||
* Gap between session label and view title in pixels
|
||||
@ -24,12 +26,12 @@ enum { LABEL_GAP = 5 };
|
||||
/**
|
||||
* Draw black outline of string
|
||||
*/
|
||||
inline void draw_string_outline(Canvas &canvas, Canvas::Point pos, const char *s)
|
||||
inline void draw_string_outline(Canvas_base &canvas, Point pos, char const *s)
|
||||
{
|
||||
for (int j = -1; j <= 1; j++)
|
||||
for (int i = -1; i <= 1; i++)
|
||||
if (i || j)
|
||||
canvas.draw_string(pos + Canvas::Point(i, j), default_font, BLACK, s);
|
||||
canvas.draw_text(pos + Point(i, j), default_font, BLACK, s);
|
||||
}
|
||||
|
||||
|
||||
@ -39,8 +41,8 @@ inline void draw_string_outline(Canvas &canvas, Canvas::Point pos, const char *s
|
||||
* \param sl session label string
|
||||
* \param vt view title string
|
||||
*/
|
||||
inline Canvas::Area label_size(const char *sl, const char *vt) {
|
||||
return Canvas::Area(default_font.str_w(sl) + LABEL_GAP + default_font.str_w(vt) + 2,
|
||||
inline Area label_size(const char *sl, const char *vt) {
|
||||
return Area(default_font.str_w(sl) + LABEL_GAP + default_font.str_w(vt) + 2,
|
||||
default_font.str_h(sl) + 2); }
|
||||
|
||||
|
||||
@ -52,19 +54,19 @@ inline Canvas::Area label_size(const char *sl, const char *vt) {
|
||||
* policy. In contrast, the view title can individually be defined by the
|
||||
* application.
|
||||
*/
|
||||
static void draw_label(Canvas &canvas, Canvas::Point pos,
|
||||
const char *session_label, Genode::Color session_label_color,
|
||||
const char *view_title, Genode::Color view_title_color)
|
||||
static inline void draw_label(Canvas_base &canvas, Point pos,
|
||||
char const *session_label, Color session_label_color,
|
||||
char const *view_title, Color view_title_color)
|
||||
{
|
||||
pos = pos + Canvas::Point(1, 1);
|
||||
pos = pos + Point(1, 1);
|
||||
|
||||
draw_string_outline(canvas, pos, session_label);
|
||||
canvas.draw_string(pos, default_font, session_label_color, session_label);
|
||||
canvas.draw_text(pos, default_font, session_label_color, session_label);
|
||||
|
||||
pos = pos + Canvas::Point(default_font.str_w(session_label) + LABEL_GAP, 0);
|
||||
pos = pos + Point(default_font.str_w(session_label) + LABEL_GAP, 0);
|
||||
|
||||
draw_string_outline(canvas, pos, view_title);
|
||||
canvas.draw_string(pos, default_font, view_title_color, view_title);
|
||||
canvas.draw_text(pos, default_font, view_title_color, view_title);
|
||||
}
|
||||
|
||||
#endif /* _DRAW_LABEL_H_ */
|
||||
|
@ -27,8 +27,8 @@
|
||||
#include <nitpicker_view/nitpicker_view.h>
|
||||
#include <nitpicker_session/nitpicker_session.h>
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <nitpicker_gfx/pixel_rgb565.h>
|
||||
#include <util/color.h>
|
||||
#include <os/pixel_rgb565.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <os/server.h>
|
||||
|
||||
@ -40,18 +40,31 @@
|
||||
#include "mouse_cursor.h"
|
||||
#include "chunky_menubar.h"
|
||||
|
||||
namespace Input { using namespace Genode; }
|
||||
namespace Input { class Session_component; }
|
||||
namespace Framebuffer { using namespace Genode; }
|
||||
namespace Framebuffer { class Session_component; }
|
||||
|
||||
namespace Nitpicker {
|
||||
using namespace Genode;
|
||||
class Session_component;
|
||||
template <typename> class Root;
|
||||
struct Main;
|
||||
}
|
||||
|
||||
using Genode::size_t;
|
||||
using Genode::Allocator;
|
||||
using Genode::Rpc_entrypoint;
|
||||
using Genode::List;
|
||||
using Genode::Pixel_rgb565;
|
||||
using Genode::strcmp;
|
||||
using Genode::config;
|
||||
using Genode::env;
|
||||
using Genode::Arg_string;
|
||||
using Genode::Object_pool;
|
||||
using Genode::Dataspace_capability;
|
||||
using Genode::Session_label;
|
||||
using Genode::Signal_transmitter;
|
||||
using Genode::Signal_context_capability;
|
||||
using Genode::Signal_rpc_member;
|
||||
using Genode::Attached_ram_dataspace;
|
||||
|
||||
|
||||
/***************
|
||||
** Utilities **
|
||||
@ -62,46 +75,49 @@ namespace Nitpicker {
|
||||
*/
|
||||
extern char _binary_default_tff_start;
|
||||
|
||||
Font default_font(&_binary_default_tff_start);
|
||||
Text_painter::Font default_font(&_binary_default_tff_start);
|
||||
|
||||
|
||||
class Flush_merger
|
||||
{
|
||||
private:
|
||||
|
||||
Canvas::Rect _to_be_flushed = { Canvas::Point(), Canvas::Area() };
|
||||
Rect _to_be_flushed = { Point(), Area() };
|
||||
|
||||
public:
|
||||
|
||||
bool defer = false;
|
||||
|
||||
Canvas::Rect to_be_flushed() const { return _to_be_flushed; }
|
||||
Rect to_be_flushed() const { return _to_be_flushed; }
|
||||
|
||||
void merge(Canvas::Rect rect)
|
||||
void merge(Rect rect)
|
||||
{
|
||||
if (_to_be_flushed.valid())
|
||||
_to_be_flushed = Canvas::Rect::compound(_to_be_flushed, rect);
|
||||
_to_be_flushed = Rect::compound(_to_be_flushed, rect);
|
||||
else
|
||||
_to_be_flushed = rect;
|
||||
}
|
||||
|
||||
void reset() { _to_be_flushed = Canvas::Rect(Canvas::Point(), Canvas::Area()); }
|
||||
void reset() { _to_be_flushed = Rect(Point(), Area()); }
|
||||
};
|
||||
|
||||
|
||||
template <typename PT>
|
||||
class Screen : public Chunky_canvas<PT>, public Flush_merger
|
||||
class Screen : public Canvas<PT>, public Flush_merger
|
||||
{
|
||||
protected:
|
||||
|
||||
virtual void _flush_pixels(Canvas::Rect rect) { merge(rect); }
|
||||
/**
|
||||
* Surface_base::Flusher interface
|
||||
*/
|
||||
void flush_pixels(Rect rect) { merge(rect); }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Screen(PT *base, Canvas::Area size) : Chunky_canvas<PT>(base, size) { }
|
||||
Screen(PT *base, Area size) : Canvas<PT>(base, size) { }
|
||||
};
|
||||
|
||||
|
||||
@ -109,7 +125,7 @@ class Buffer
|
||||
{
|
||||
private:
|
||||
|
||||
Canvas::Area _size;
|
||||
Area _size;
|
||||
Framebuffer::Mode::Format _format;
|
||||
Genode::Attached_ram_dataspace _ram_ds;
|
||||
|
||||
@ -121,17 +137,17 @@ class Buffer
|
||||
* \throw Ram_session::Alloc_failed
|
||||
* \throw Rm_session::Attach_failed
|
||||
*/
|
||||
Buffer(Canvas::Area size, Framebuffer::Mode::Format format, Genode::size_t bytes)
|
||||
Buffer(Area size, Framebuffer::Mode::Format format, Genode::size_t bytes)
|
||||
:
|
||||
_size(size), _format(format),
|
||||
_ram_ds(Genode::env()->ram_session(), bytes)
|
||||
_ram_ds(env()->ram_session(), bytes)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Accessors
|
||||
*/
|
||||
Genode::Ram_dataspace_capability ds_cap() const { return _ram_ds.cap(); }
|
||||
Canvas::Area size() const { return _size; }
|
||||
Area size() const { return _size; }
|
||||
Framebuffer::Mode::Format format() const { return _format; }
|
||||
void *local_addr() const { return _ram_ds.local_addr<void>(); }
|
||||
};
|
||||
@ -150,7 +166,8 @@ struct Buffer_provider
|
||||
|
||||
|
||||
template <typename PT>
|
||||
class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT>
|
||||
class Chunky_dataspace_texture : public Buffer,
|
||||
public Texture<PT>
|
||||
{
|
||||
private:
|
||||
|
||||
@ -160,7 +177,7 @@ class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT>
|
||||
/**
|
||||
* Return base address of alpha channel or 0 if no alpha channel exists
|
||||
*/
|
||||
unsigned char *_alpha_base(Canvas::Area size, bool use_alpha)
|
||||
unsigned char *_alpha_base(Area size, bool use_alpha)
|
||||
{
|
||||
if (!use_alpha) return 0;
|
||||
|
||||
@ -173,13 +190,13 @@ class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Chunky_dataspace_texture(Canvas::Area size, bool use_alpha)
|
||||
Chunky_dataspace_texture(Area size, bool use_alpha)
|
||||
:
|
||||
Buffer(size, _format(), calc_num_bytes(size, use_alpha)),
|
||||
Chunky_texture<PT>((PT *)local_addr(),
|
||||
_alpha_base(size, use_alpha), size) { }
|
||||
Texture<PT>((PT *)local_addr(),
|
||||
_alpha_base(size, use_alpha), size) { }
|
||||
|
||||
static Genode::size_t calc_num_bytes(Canvas::Area size, bool use_alpha)
|
||||
static Genode::size_t calc_num_bytes(Area size, bool use_alpha)
|
||||
{
|
||||
/*
|
||||
* If using an alpha channel, the alpha buffer follows the
|
||||
@ -193,11 +210,13 @@ class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT>
|
||||
|
||||
unsigned char *input_mask_buffer()
|
||||
{
|
||||
if (!Chunky_texture<PT>::alpha()) return 0;
|
||||
if (!Texture<PT>::alpha()) return 0;
|
||||
|
||||
Area const size = Texture<PT>::size();
|
||||
|
||||
/* input-mask values come right after the alpha values */
|
||||
return (unsigned char *)local_addr() + calc_num_bytes(*this, false)
|
||||
+ Texture::w()*Texture::h();
|
||||
return (unsigned char *)local_addr() + calc_num_bytes(size, false)
|
||||
+ size.count();
|
||||
}
|
||||
};
|
||||
|
||||
@ -213,7 +232,7 @@ class Input::Session_component : public Genode::Rpc_object<Session>
|
||||
enum { MAX_EVENTS = 200 };
|
||||
|
||||
static size_t ev_ds_size() {
|
||||
return align_addr(MAX_EVENTS*sizeof(Event), 12); }
|
||||
return Genode::align_addr(MAX_EVENTS*sizeof(Event), 12); }
|
||||
|
||||
private:
|
||||
|
||||
@ -335,7 +354,7 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
_buffer = _buffer_provider.realloc_buffer(_mode, _alpha);
|
||||
|
||||
return _buffer ? _buffer->ds_cap() : Ram_dataspace_capability();
|
||||
return _buffer ? _buffer->ds_cap() : Genode::Ram_dataspace_capability();
|
||||
}
|
||||
|
||||
void release() { }
|
||||
@ -353,12 +372,11 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
||||
void refresh(int x, int y, int w, int h)
|
||||
{
|
||||
_view_stack.update_session_views(_session,
|
||||
Canvas::Rect(Canvas::Point(x, y),
|
||||
Canvas::Area(w, h)));
|
||||
Rect(Point(x, y), Area(w, h)));
|
||||
|
||||
/* flush dirty pixels to physical frame buffer */
|
||||
if (_flush_merger.defer == false) {
|
||||
Canvas::Rect r = _flush_merger.to_be_flushed();
|
||||
Rect r = _flush_merger.to_be_flushed();
|
||||
_framebuffer.refresh(r.x1(), r.y1(), r.w(), r.h());
|
||||
_flush_merger.reset();
|
||||
}
|
||||
@ -388,7 +406,7 @@ class View_component : public Genode::List<View_component>::Element,
|
||||
_view_stack(view_stack),
|
||||
_view(session,
|
||||
session.stay_top() ? ::View::STAY_TOP : ::View::NOT_STAY_TOP,
|
||||
::View::NOT_TRANSPARENT, ::View::NOT_BACKGROUND, Canvas::Rect()),
|
||||
::View::NOT_TRANSPARENT, ::View::NOT_BACKGROUND, Rect()),
|
||||
_ep(ep) { }
|
||||
|
||||
::View &view() { return _view; }
|
||||
@ -404,16 +422,13 @@ class View_component : public Genode::List<View_component>::Element,
|
||||
/* transpose y position by vertical session offset */
|
||||
y += _view.session().v_offset();
|
||||
|
||||
_view_stack.viewport(_view, Canvas::Rect(Canvas::Point(x, y),
|
||||
Canvas::Area(w, h)),
|
||||
Canvas::Point(buf_x, buf_y), redraw);
|
||||
_view_stack.viewport(_view, Rect(Point(x, y), Area(w, h)),
|
||||
Point(buf_x, buf_y), redraw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stack(Nitpicker::View_capability neighbor_cap, bool behind, bool redraw)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Object_pool<View_component>::Guard nvc(_ep.lookup_and_lock(neighbor_cap));
|
||||
|
||||
::View *neighbor_view = nvc ? &nvc->view() : 0;
|
||||
@ -440,7 +455,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||
{
|
||||
private:
|
||||
|
||||
Allocator_guard _buffer_alloc;
|
||||
Genode::Allocator_guard _buffer_alloc;
|
||||
|
||||
Framebuffer::Session &_framebuffer;
|
||||
|
||||
@ -480,7 +495,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||
Chunky_dataspace_texture<PT> const *cdt =
|
||||
static_cast<Chunky_dataspace_texture<PT> const *>(::Session::texture());
|
||||
|
||||
::Session::texture(0);
|
||||
::Session::texture(0, false);
|
||||
::Session::input_mask(0);
|
||||
|
||||
destroy(&_buffer_alloc, const_cast<Chunky_dataspace_texture<PT> *>(cdt));
|
||||
@ -549,7 +564,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||
*/
|
||||
if (e.ax() || e.ay())
|
||||
e = Event(e.type(), e.code(), e.ax(),
|
||||
max(0, e.ay() - v_offset()), e.rx(), e.ry());
|
||||
Genode::max(0, e.ay() - v_offset()), e.rx(), e.ry());
|
||||
|
||||
_input_session_component.submit(&e);
|
||||
}
|
||||
@ -639,7 +654,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||
{
|
||||
_release_buffer();
|
||||
|
||||
Canvas::Area const size(mode.width(), mode.height());
|
||||
Area const size(mode.width(), mode.height());
|
||||
|
||||
typedef Pixel_rgb565 PT;
|
||||
|
||||
@ -655,7 +670,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
|
||||
return 0;
|
||||
}
|
||||
|
||||
::Session::texture(texture);
|
||||
::Session::texture(texture, use_alpha);
|
||||
::Session::input_mask(texture->input_mask_buffer());
|
||||
|
||||
return texture;
|
||||
@ -769,7 +784,7 @@ struct Nitpicker::Main
|
||||
|
||||
void *fb_base = env()->rm_session()->attach(fb_ds_cap);
|
||||
|
||||
Screen<PT> screen = { (PT *)fb_base, Canvas::Area(mode.width(), mode.height()) };
|
||||
Screen<PT> screen = { (PT *)fb_base, Area(mode.width(), mode.height()) };
|
||||
|
||||
/*
|
||||
* Menu bar
|
||||
@ -778,7 +793,7 @@ struct Nitpicker::Main
|
||||
|
||||
PT *menubar_pixels = (PT *)env()->heap()->alloc(sizeof(PT)*mode.width()*16);
|
||||
|
||||
Chunky_menubar<PT> menubar = { menubar_pixels, Canvas::Area(mode.width(), MENUBAR_HEIGHT) };
|
||||
Chunky_menubar<PT> menubar = { menubar_pixels, Area(mode.width(), MENUBAR_HEIGHT) };
|
||||
|
||||
/*
|
||||
* User-input policy
|
||||
@ -792,16 +807,16 @@ struct Nitpicker::Main
|
||||
/*
|
||||
* Create view stack with default elements
|
||||
*/
|
||||
Canvas::Area mouse_size { big_mouse.w, big_mouse.h };
|
||||
Mouse_cursor<PT> mouse_cursor { (PT *)&big_mouse.pixels[0][0],
|
||||
mouse_size, user_state };
|
||||
Area mouse_size { big_mouse.w, big_mouse.h };
|
||||
Mouse_cursor<PT const> mouse_cursor { (PT const *)&big_mouse.pixels[0][0],
|
||||
mouse_size, user_state };
|
||||
|
||||
Background background = { screen.size() };
|
||||
|
||||
/*
|
||||
* Initialize Nitpicker root interface
|
||||
*/
|
||||
Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() };
|
||||
Genode::Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() };
|
||||
|
||||
Root<PT> np_root = { session_list, global_keys, ep.rpc_ep(),
|
||||
user_state, sliced_heap, screen,
|
||||
@ -861,23 +876,23 @@ void Nitpicker::Main::handle_input(unsigned)
|
||||
return;
|
||||
|
||||
do {
|
||||
Canvas::Point const old_mouse_pos = user_state.mouse_pos();
|
||||
Point const old_mouse_pos = user_state.mouse_pos();
|
||||
|
||||
/* handle batch of pending events */
|
||||
if (input.is_pending())
|
||||
import_input_events(ev_buf, input.flush(), user_state);
|
||||
|
||||
Canvas::Point const new_mouse_pos = user_state.mouse_pos();
|
||||
Point const new_mouse_pos = user_state.mouse_pos();
|
||||
|
||||
/* update mouse cursor */
|
||||
if (old_mouse_pos != new_mouse_pos)
|
||||
user_state.viewport(mouse_cursor,
|
||||
Canvas::Rect(new_mouse_pos, mouse_size),
|
||||
Canvas::Point(), true);
|
||||
Rect(new_mouse_pos, mouse_size),
|
||||
Point(), true);
|
||||
|
||||
/* flush dirty pixels to physical frame buffer */
|
||||
if (screen.defer == false) {
|
||||
Canvas::Rect const r = screen.to_be_flushed();
|
||||
Rect const r = screen.to_be_flushed();
|
||||
if (r.valid())
|
||||
framebuffer.refresh(r.x1(), r.y1(), r.w(), r.h());
|
||||
screen.reset();
|
||||
|
@ -18,56 +18,16 @@
|
||||
#include "draw_label.h"
|
||||
#include "mode.h"
|
||||
|
||||
class Menubar : public View
|
||||
|
||||
struct Menubar
|
||||
{
|
||||
private:
|
||||
virtual ~Menubar() { }
|
||||
|
||||
Canvas &_canvas;
|
||||
|
||||
protected:
|
||||
|
||||
Menubar(Canvas &canvas, Canvas::Area size, Session &session)
|
||||
:
|
||||
View(session, View::STAY_TOP, View::NOT_TRANSPARENT,
|
||||
View::NOT_BACKGROUND, Canvas::Rect(Canvas::Point(0, 0), size)),
|
||||
_canvas(canvas)
|
||||
{ }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Set state that is displayed in the trusted menubar
|
||||
*/
|
||||
void state(Mode const &mode, const char *session_label,
|
||||
const char *view_title, Genode::Color session_color)
|
||||
{
|
||||
/* choose base color dependent on the Nitpicker state */
|
||||
int r = (mode.kill()) ? 200 : (mode.xray()) ? session_color.r : (session_color.r + 100) >> 1;
|
||||
int g = (mode.kill()) ? 70 : (mode.xray()) ? session_color.g : (session_color.g + 100) >> 1;
|
||||
int b = (mode.kill()) ? 70 : (mode.xray()) ? session_color.b : (session_color.b + 100) >> 1;
|
||||
|
||||
/* highlight first line with slightly brighter color */
|
||||
_canvas.draw_box(Canvas::Rect(Canvas::Point(0, 0), Canvas::Area(w(), 1)),
|
||||
Genode::Color(r + (r / 2), g + (g / 2), b + (b / 2)));
|
||||
|
||||
/* draw slightly shaded background */
|
||||
for (unsigned i = 1; i < h() - 1; i++) {
|
||||
r -= r > 3 ? 4 : 0;
|
||||
g -= g > 3 ? 4 : 0;
|
||||
b -= b > 4 ? 4 : 0;
|
||||
_canvas.draw_box(Canvas::Rect(Canvas::Point(0, i),
|
||||
Canvas::Area(w(), 1)),
|
||||
Genode::Color(r, g, b));
|
||||
}
|
||||
|
||||
/* draw last line darker */
|
||||
_canvas.draw_box(Canvas::Rect(Canvas::Point(0, h() - 1), Canvas::Area(w(), 1)),
|
||||
Genode::Color(r / 4, g / 4, b / 4));
|
||||
|
||||
/* draw label */
|
||||
draw_label(_canvas, center(label_size(session_label, view_title)),
|
||||
session_label, WHITE, view_title, session_color);
|
||||
}
|
||||
/**
|
||||
* Set state that is displayed in the trusted menubar
|
||||
*/
|
||||
virtual void state(Mode const &mode, char const *session_label,
|
||||
char const *view_title, Genode::Color session_color) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -17,13 +17,14 @@
|
||||
#ifndef _MOUSE_CURSOR_H_
|
||||
#define _MOUSE_CURSOR_H_
|
||||
|
||||
#include <nitpicker_gfx/chunky_canvas.h>
|
||||
#include <nitpicker_gfx/texture_painter.h>
|
||||
|
||||
#include "view.h"
|
||||
#include "session.h"
|
||||
|
||||
template <typename PT>
|
||||
class Mouse_cursor : public Chunky_texture<PT>, public Session, public View
|
||||
class Mouse_cursor : public Texture<PT>,
|
||||
public Session, public View
|
||||
{
|
||||
private:
|
||||
|
||||
@ -34,12 +35,12 @@ class Mouse_cursor : public Chunky_texture<PT>, public Session, public View
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Mouse_cursor(PT const *pixels, Canvas::Area size, View_stack const &view_stack)
|
||||
Mouse_cursor(PT const *pixels, Area size, View_stack const &view_stack)
|
||||
:
|
||||
Chunky_texture<PT>(pixels, 0, size),
|
||||
Texture<PT>(pixels, 0, size),
|
||||
Session(Genode::Session_label(""), 0, false),
|
||||
View(*this, View::STAY_TOP, View::TRANSPARENT, View::NOT_BACKGROUND,
|
||||
Canvas::Rect()),
|
||||
Rect()),
|
||||
_view_stack(view_stack)
|
||||
{ }
|
||||
|
||||
@ -61,9 +62,9 @@ class Mouse_cursor : public Chunky_texture<PT>, public Session, public View
|
||||
|
||||
int frame_size(Mode const &mode) const { return 0; }
|
||||
|
||||
void frame(Canvas &canvas, Mode const &mode) const { }
|
||||
void frame(Canvas_base &canvas, Mode const &mode) const { }
|
||||
|
||||
void draw(Canvas &canvas, Mode const &mode) const
|
||||
void draw(Canvas_base &canvas, Mode const &mode) const
|
||||
{
|
||||
Clip_guard clip_guard(canvas, *this);
|
||||
|
||||
@ -71,7 +72,7 @@ class Mouse_cursor : public Chunky_texture<PT>, public Session, public View
|
||||
_view_stack.draw_rec(view_stack_next(), 0, 0, *this);
|
||||
|
||||
/* draw mouse cursor */
|
||||
canvas.draw_texture(*this, BLACK, p1(), Canvas::MASKED);
|
||||
canvas.draw_texture(p1(), *this, Texture_painter::MASKED, BLACK, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -17,13 +17,12 @@
|
||||
/* Genode includes */
|
||||
#include <util/list.h>
|
||||
#include <util/string.h>
|
||||
#include <nitpicker_gfx/canvas.h>
|
||||
#include <os/session_policy.h>
|
||||
|
||||
/* local includes */
|
||||
#include "color.h"
|
||||
#include "canvas.h"
|
||||
|
||||
class Texture;
|
||||
class View;
|
||||
class Session;
|
||||
|
||||
@ -36,11 +35,12 @@ class Session : public Session_list::Element
|
||||
private:
|
||||
|
||||
Genode::Session_label const _label;
|
||||
Genode::Color _color;
|
||||
Texture const *_texture;
|
||||
Color _color;
|
||||
Texture_base const *_texture = { 0 };
|
||||
bool _uses_alpha = { false };
|
||||
View *_background = 0;
|
||||
int _v_offset;
|
||||
unsigned char const *_input_mask;
|
||||
unsigned char const *_input_mask = { 0 };
|
||||
bool const _stay_top;
|
||||
|
||||
public:
|
||||
@ -54,8 +54,7 @@ class Session : public Session_list::Element
|
||||
*/
|
||||
Session(Genode::Session_label const &label, int v_offset, bool stay_top)
|
||||
:
|
||||
_label(label), _texture(0), _v_offset(v_offset),
|
||||
_input_mask(0), _stay_top(stay_top)
|
||||
_label(label), _v_offset(v_offset), _stay_top(stay_top)
|
||||
{ }
|
||||
|
||||
virtual ~Session() { }
|
||||
@ -64,9 +63,13 @@ class Session : public Session_list::Element
|
||||
|
||||
Genode::Session_label const &label() const { return _label; }
|
||||
|
||||
Texture const *texture() const { return _texture; }
|
||||
Texture_base const *texture() const { return _texture; }
|
||||
|
||||
void texture(Texture const *texture) { _texture = texture; }
|
||||
void texture(Texture_base const *texture, bool uses_alpha)
|
||||
{
|
||||
_texture = texture;
|
||||
_uses_alpha = uses_alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set input mask buffer
|
||||
@ -82,7 +85,7 @@ class Session : public Session_list::Element
|
||||
*/
|
||||
void input_mask(unsigned char const *mask) { _input_mask = mask; }
|
||||
|
||||
Genode::Color color() const { return _color; }
|
||||
Color color() const { return _color; }
|
||||
|
||||
View *background() const { return _background; }
|
||||
|
||||
@ -93,7 +96,7 @@ class Session : public Session_list::Element
|
||||
/**
|
||||
* Return true if session uses an alpha channel
|
||||
*/
|
||||
bool uses_alpha() const { return _texture ? _texture->alpha() : 0; }
|
||||
bool uses_alpha() const { return _texture && _uses_alpha; }
|
||||
|
||||
/**
|
||||
* Return vertical offset of session
|
||||
@ -103,16 +106,16 @@ class Session : public Session_list::Element
|
||||
/**
|
||||
* Return input mask value at specified buffer position
|
||||
*/
|
||||
unsigned char input_mask_at(Canvas::Point p) const
|
||||
unsigned char input_mask_at(Point p) const
|
||||
{
|
||||
if (!_input_mask || !_texture) return 0;
|
||||
|
||||
/* check boundaries */
|
||||
if ((unsigned)p.x() >= _texture->w()
|
||||
|| (unsigned)p.y() >= _texture->h())
|
||||
if ((unsigned)p.x() >= _texture->size().w()
|
||||
|| (unsigned)p.y() >= _texture->size().h())
|
||||
return 0;
|
||||
|
||||
return _input_mask[p.y()*_texture->w() + p.x()];
|
||||
return _input_mask[p.y()*_texture->size().w() + p.x()];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,7 +35,7 @@ static inline bool _mouse_button(Keycode keycode) {
|
||||
** User state interface **
|
||||
**************************/
|
||||
|
||||
User_state::User_state(Global_keys &global_keys, Canvas &canvas, Menubar &menubar)
|
||||
User_state::User_state(Global_keys &global_keys, Canvas_base &canvas, Menubar &menubar)
|
||||
:
|
||||
View_stack(canvas, *this), _global_keys(global_keys), _key_cnt(0),
|
||||
_menubar(menubar), _pointed_view(0), _input_receiver(0),
|
||||
@ -74,7 +74,7 @@ void User_state::handle_event(Input::Event ev)
|
||||
/* create the mangled event */
|
||||
ev = Input::Event(type, keycode, ax, ay, rx, ry);
|
||||
|
||||
_mouse_pos = Canvas::Point(ax, ay);
|
||||
_mouse_pos = Point(ax, ay);
|
||||
|
||||
/* count keys */
|
||||
if (type == Event::PRESS) _key_cnt++;
|
||||
|
@ -18,8 +18,6 @@
|
||||
#ifndef _USER_STATE_H_
|
||||
#define _USER_STATE_H_
|
||||
|
||||
#include <nitpicker_gfx/canvas.h>
|
||||
|
||||
#include "mode.h"
|
||||
#include "menubar.h"
|
||||
#include "view_stack.h"
|
||||
@ -51,7 +49,7 @@ class User_state : public Mode, public View_stack
|
||||
/*
|
||||
* Current mouse cursor position
|
||||
*/
|
||||
Canvas::Point _mouse_pos;
|
||||
Point _mouse_pos;
|
||||
|
||||
/*
|
||||
* Currently pointed-at view
|
||||
@ -73,7 +71,7 @@ class User_state : public Mode, public View_stack
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
User_state(Global_keys &global_keys, Canvas &canvas, Menubar &menubar);
|
||||
User_state(Global_keys &, Canvas_base &, Menubar &);
|
||||
|
||||
/**
|
||||
* Handle input event
|
||||
@ -86,7 +84,7 @@ class User_state : public Mode, public View_stack
|
||||
/**
|
||||
* Accessors
|
||||
*/
|
||||
Canvas::Point mouse_pos() { return _mouse_pos; }
|
||||
Point mouse_pos() { return _mouse_pos; }
|
||||
|
||||
/**
|
||||
* Mode interface
|
||||
|
@ -12,6 +12,10 @@
|
||||
*/
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <os/pixel_rgb565.h>
|
||||
|
||||
#include <nitpicker_gfx/texture_painter.h>
|
||||
#include <nitpicker_gfx/box_painter.h>
|
||||
|
||||
#include "view.h"
|
||||
#include "clip_guard.h"
|
||||
@ -26,19 +30,21 @@
|
||||
/**
|
||||
* Draw rectangle
|
||||
*/
|
||||
static void draw_rect(Canvas &canvas, int x, int y, int w, int h, Genode::Color color)
|
||||
static void draw_rect(Canvas_base &canvas, int x, int y, int w, int h,
|
||||
Color color)
|
||||
{
|
||||
canvas.draw_box(Canvas::Rect(Canvas::Point(x, y), Canvas::Area(w, 1)), color);
|
||||
canvas.draw_box(Canvas::Rect(Canvas::Point(x, y), Canvas::Area(1, h)), color);
|
||||
canvas.draw_box(Canvas::Rect(Canvas::Point(x + w - 1, y), Canvas::Area(1, h)), color);
|
||||
canvas.draw_box(Canvas::Rect(Canvas::Point(x, y + h - 1), Canvas::Area(w, 1)), color);
|
||||
canvas.draw_box(Rect(Point(x, y), Area(w, 1)), color);
|
||||
canvas.draw_box(Rect(Point(x, y), Area(1, h)), color);
|
||||
canvas.draw_box(Rect(Point(x + w - 1, y), Area(1, h)), color);
|
||||
canvas.draw_box(Rect(Point(x, y + h - 1), Area(w, 1)), color);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw outlined frame with black outline color
|
||||
*/
|
||||
static void draw_frame(Canvas &canvas, Canvas::Rect r, Genode::Color color, int frame_size)
|
||||
static void draw_frame(Canvas_base &canvas, Rect r, Color color,
|
||||
int frame_size)
|
||||
{
|
||||
/* draw frame around the view */
|
||||
int d = frame_size;
|
||||
@ -58,11 +64,11 @@ void View::title(const char *title)
|
||||
Genode::strncpy(_title, title, TITLE_LEN);
|
||||
|
||||
/* calculate label size, the position is defined by the view stack */
|
||||
_label_rect = Canvas::Rect(Canvas::Point(0, 0), label_size(_session.label().string(), _title));
|
||||
_label_rect = Rect(Point(0, 0), label_size(_session.label().string(), _title));
|
||||
}
|
||||
|
||||
|
||||
void View::frame(Canvas &canvas, Mode const &mode) const
|
||||
void View::frame(Canvas_base &canvas, Mode const &mode) const
|
||||
{
|
||||
/* do not draw frame in flat mode */
|
||||
if (mode.flat()) return;
|
||||
@ -71,20 +77,20 @@ void View::frame(Canvas &canvas, Mode const &mode) const
|
||||
}
|
||||
|
||||
|
||||
void View::draw(Canvas &canvas, Mode const &mode) const
|
||||
void View::draw(Canvas_base &canvas, Mode const &mode) const
|
||||
{
|
||||
/* is this the currently focused view? */
|
||||
bool const view_is_focused = mode.focused_view()
|
||||
&& mode.focused_view()->belongs_to(_session);
|
||||
|
||||
Genode::Color const frame_color = _session.color();
|
||||
Color const frame_color = _session.color();
|
||||
|
||||
/*
|
||||
* Use dimming in x-ray and kill mode, but do not dim the focused view in
|
||||
* x-ray mode.
|
||||
*/
|
||||
Canvas::Mode const op = mode.flat() || (mode.xray() && view_is_focused)
|
||||
? Canvas::SOLID : Canvas::MIXED;
|
||||
Texture_painter::Mode const op = mode.flat() || (mode.xray() && view_is_focused)
|
||||
? Texture_painter::SOLID : Texture_painter::MIXED;
|
||||
|
||||
/*
|
||||
* The view content and label should never overdraw the
|
||||
@ -98,23 +104,24 @@ void View::draw(Canvas &canvas, Mode const &mode) const
|
||||
* If the clipping area shrinked to zero, we do not process drawing
|
||||
* operations.
|
||||
*/
|
||||
if (!canvas.clip_valid() || !&_session) return;
|
||||
if (!canvas.clip().valid() || !&_session) return;
|
||||
|
||||
/* allow alpha blending only in flat mode */
|
||||
bool allow_alpha = mode.flat();
|
||||
|
||||
/* draw view content */
|
||||
Genode::Color const mix_color = mode.kill() ? KILL_COLOR
|
||||
: Genode::Color(_session.color().r >> 1,
|
||||
_session.color().g >> 1,
|
||||
_session.color().b >> 1);
|
||||
Color const mix_color = mode.kill() ? KILL_COLOR
|
||||
: Color(_session.color().r >> 1,
|
||||
_session.color().g >> 1,
|
||||
_session.color().b >> 1);
|
||||
|
||||
if (_session.texture())
|
||||
canvas.draw_texture(*_session.texture(), mix_color, _buffer_off + p1(),
|
||||
op, allow_alpha);
|
||||
canvas.draw_texture(_buffer_off + p1(), *_session.texture(), op,
|
||||
mix_color, allow_alpha);
|
||||
|
||||
if (mode.flat()) return;
|
||||
|
||||
/* draw label */
|
||||
draw_label(canvas, _label_rect.p1(), _session.label().string(), WHITE, _title, frame_color);
|
||||
draw_label(canvas, _label_rect.p1(), _session.label().string(), WHITE,
|
||||
_title, frame_color);
|
||||
}
|
||||
|
@ -17,8 +17,6 @@
|
||||
#include <util/string.h>
|
||||
#include <util/list.h>
|
||||
|
||||
#include <nitpicker_gfx/canvas.h>
|
||||
|
||||
#include "mode.h"
|
||||
#include "session.h"
|
||||
|
||||
@ -37,7 +35,7 @@ struct View_stack_elem : Genode::List<View_stack_elem>::Element { };
|
||||
|
||||
class View : public Same_buffer_list_elem,
|
||||
public View_stack_elem,
|
||||
public Canvas::Rect
|
||||
public Rect
|
||||
{
|
||||
public:
|
||||
|
||||
@ -53,10 +51,10 @@ class View : public Same_buffer_list_elem,
|
||||
Transparent const _transparent; /* background is partly visible */
|
||||
Background _background; /* view is a background view */
|
||||
|
||||
Canvas::Rect _label_rect; /* position and size of label */
|
||||
Canvas::Point _buffer_off; /* offset to the visible buffer area */
|
||||
Session &_session; /* session that created the view */
|
||||
char _title[TITLE_LEN];
|
||||
Rect _label_rect; /* position and size of label */
|
||||
Point _buffer_off; /* offset to the visible buffer area */
|
||||
Session &_session; /* session that created the view */
|
||||
char _title[TITLE_LEN];
|
||||
|
||||
public:
|
||||
|
||||
@ -84,12 +82,12 @@ class View : public Same_buffer_list_elem,
|
||||
/**
|
||||
* Draw view-surrounding frame on canvas
|
||||
*/
|
||||
virtual void frame(Canvas &canvas, Mode const &mode) const;
|
||||
virtual void frame(Canvas_base &canvas, Mode const &mode) const;
|
||||
|
||||
/**
|
||||
* Draw view on canvas
|
||||
*/
|
||||
virtual void draw(Canvas &canvas, Mode const &mode) const;
|
||||
virtual void draw(Canvas_base &canvas, Mode const &mode) const;
|
||||
|
||||
/**
|
||||
* Set view title
|
||||
@ -126,19 +124,18 @@ class View : public Same_buffer_list_elem,
|
||||
bool background() const { return _background; }
|
||||
Rect label_rect() const { return _label_rect; }
|
||||
bool uses_alpha() const { return _session.uses_alpha(); }
|
||||
|
||||
Canvas::Point buffer_off() const { return _buffer_off; }
|
||||
Point buffer_off() const { return _buffer_off; }
|
||||
|
||||
char const *title() const { return _title; }
|
||||
|
||||
void buffer_off(Canvas::Point buffer_off) { _buffer_off = buffer_off; }
|
||||
void buffer_off(Point buffer_off) { _buffer_off = buffer_off; }
|
||||
|
||||
void label_pos(Canvas::Point pos) { _label_rect = Rect(pos, _label_rect.area()); }
|
||||
void label_pos(Point pos) { _label_rect = Rect(pos, _label_rect.area()); }
|
||||
|
||||
/**
|
||||
* Return true if input at screen position 'p' refers to the view
|
||||
*/
|
||||
bool input_response_at(Canvas::Point p, Mode const &mode) const
|
||||
bool input_response_at(Point p, Mode const &mode) const
|
||||
{
|
||||
/* check if point lies outside view geometry */
|
||||
if ((p.x() < x1()) || (p.x() > x2())
|
||||
|
@ -63,15 +63,15 @@ VIEW *View_stack::_next_view(VIEW *view) const
|
||||
}
|
||||
|
||||
|
||||
Canvas::Rect View_stack::_outline(View const &view) const
|
||||
Rect View_stack::_outline(View const &view) const
|
||||
{
|
||||
if (_mode.flat()) return view;
|
||||
|
||||
/* request thickness of view frame */
|
||||
int const frame_size = view.frame_size(_mode);
|
||||
|
||||
return Canvas::Rect(Canvas::Point(view.x1() - frame_size, view.y1() - frame_size),
|
||||
Canvas::Point(view.x2() + frame_size, view.y2() + frame_size));
|
||||
return Rect(Point(view.x1() - frame_size, view.y1() - frame_size),
|
||||
Point(view.x2() + frame_size, view.y2() + frame_size));
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define _VIEW_STACK_H_
|
||||
|
||||
#include "view.h"
|
||||
#include "canvas.h"
|
||||
|
||||
class Session;
|
||||
|
||||
@ -22,11 +23,7 @@ class View_stack
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Canvas::Point Point;
|
||||
typedef Canvas::Area Area;
|
||||
typedef Canvas::Rect Rect;
|
||||
|
||||
Canvas &_canvas;
|
||||
Canvas_base &_canvas;
|
||||
Mode &_mode;
|
||||
Genode::List<View_stack_elem> _views;
|
||||
View *_default_background;
|
||||
@ -38,7 +35,7 @@ class View_stack
|
||||
* active Nitpicker mode. In non-flat modes, we incorporate the
|
||||
* surrounding frame.
|
||||
*/
|
||||
Canvas::Rect _outline(View const &view) const;
|
||||
Rect _outline(View const &view) const;
|
||||
|
||||
/**
|
||||
* Return top-most view of the view stack
|
||||
@ -74,7 +71,7 @@ class View_stack
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
View_stack(Canvas &canvas, Mode &mode) :
|
||||
View_stack(Canvas_base &canvas, Mode &mode) :
|
||||
_canvas(canvas), _mode(mode), _default_background(0) { }
|
||||
|
||||
/**
|
||||
|
@ -28,16 +28,17 @@
|
||||
#include <util/register.h>
|
||||
|
||||
/* nitpicker graphics backend */
|
||||
#include <nitpicker_gfx/chunky_canvas.h>
|
||||
#include <nitpicker_gfx/pixel_rgb565.h>
|
||||
#include <nitpicker_gfx/font.h>
|
||||
|
||||
extern char _binary_mono_tff_start;
|
||||
Font default_font(&_binary_mono_tff_start);
|
||||
|
||||
#include <os/pixel_rgb565.h>
|
||||
#include <nitpicker_gfx/text_painter.h>
|
||||
|
||||
using Genode::env;
|
||||
using Genode::Dataspace_client;
|
||||
using Genode::Surface;
|
||||
using Genode::Pixel_rgb565;
|
||||
typedef Text_painter::Font Font;
|
||||
|
||||
extern char _binary_mono_tff_start;
|
||||
Font default_font(&_binary_mono_tff_start);
|
||||
|
||||
bool fb_active = true;
|
||||
|
||||
@ -214,9 +215,9 @@ void Vancouver_console::entry()
|
||||
|
||||
_pixels = env()->rm_session()->attach(framebuffer->dataspace());
|
||||
|
||||
Chunky_canvas<Pixel_rgb565> canvas((Pixel_rgb565 *) _pixels,
|
||||
Canvas::Area(_fb_mode.width(),
|
||||
_fb_mode.height()));
|
||||
Surface<Pixel_rgb565> surface((Pixel_rgb565 *) _pixels,
|
||||
Genode::Surface_base::Area(_fb_mode.width(),
|
||||
_fb_mode.height()));
|
||||
|
||||
/*
|
||||
* Handle input events
|
||||
@ -244,7 +245,7 @@ void Vancouver_console::entry()
|
||||
else checksum2 = 0;
|
||||
for (int j=0; j<25; j++) {
|
||||
for (int i=0; i<80; i++) {
|
||||
Canvas::Point where(i*8, j*15);
|
||||
Genode::Surface_base::Point where(i*8, j*15);
|
||||
char character = *((char *) (_guest_fb +(_regs->offset << 1) +j*80*2+i*2));
|
||||
char colorvalue = *((char *) (_guest_fb+(_regs->offset << 1)+j*80*2+i*2+1));
|
||||
char buffer[2]; buffer[0] = character; buffer[1] = 0;
|
||||
@ -255,7 +256,7 @@ void Vancouver_console::entry()
|
||||
((fg & 0x2) >> 1)*127+lum, /* G+luminosity */
|
||||
(fg & 0x1)*127+lum /* B+luminosity */);
|
||||
|
||||
canvas.draw_string(where, default_font, color, buffer);
|
||||
Text_painter::paint(surface, where, default_font, color, buffer);
|
||||
|
||||
/* Checksum for comparing */
|
||||
if (cmp_even) checksum1 += character;
|
||||
|
Loading…
x
Reference in New Issue
Block a user