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:
Norman Feske 2013-12-28 22:29:30 +01:00 committed by Christian Helmuth
parent 765053ea94
commit 8c8d53777f
35 changed files with 1112 additions and 785 deletions

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@
#include <nitpicker_view/capability.h>
namespace Nitpicker {
using namespace Genode;
using Genode::size_t;
struct Session;
}

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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()];
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) { }
/**

View File

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