From: l4check Date: Tue, 7 Sep 2010 15:13:06 +0000 (+0000) Subject: update X-Git-Url: https://rtime.felk.cvut.cz/gitweb/l4.git/commitdiff_plain/135c5638bee2bc8765ec4f36b1b4b1e650255096 update git-svn-id: http://svn.tudos.org/repos/oc/tudos/trunk@20 d050ee49-bd90-4346-b210-929a50b99cfc --- diff --git a/kernel/fiasco/src/drivers/amd64/reset-amd64.cpp b/kernel/fiasco/src/drivers/amd64/reset-amd64.cpp index 9b075f683..5ab684e01 100644 --- a/kernel/fiasco/src/drivers/amd64/reset-amd64.cpp +++ b/kernel/fiasco/src/drivers/amd64/reset-amd64.cpp @@ -1,17 +1,3 @@ -IMPLEMENTATION[amd64 && vmx]: - -static void -virt_off() -{ - asm volatile("vmxoff"); -} - -IMPLEMENTATION[amd64 && !vmx]: - -static void -virt_off() -{} - IMPLEMENTATION[amd64]: #include "io.h" @@ -21,8 +7,6 @@ IMPLEMENTATION[amd64]: void __attribute__ ((noreturn)) pc_reset() { - virt_off(); - // i8042: store the next byte at port 0x60 as command byte while (Io::in8 (0x64) & 0x2) ; diff --git a/kernel/fiasco/src/drivers/ia32/reset-ia32.cpp b/kernel/fiasco/src/drivers/ia32/reset-ia32.cpp index d0509e4d7..ba73aaf1a 100644 --- a/kernel/fiasco/src/drivers/ia32/reset-ia32.cpp +++ b/kernel/fiasco/src/drivers/ia32/reset-ia32.cpp @@ -1,17 +1,3 @@ -IMPLEMENTATION[ia32 && vmx]: - -static void -virt_off() -{ - asm volatile("vmxoff"); -} - -IMPLEMENTATION[ia32 && !vmx]: - -static void -virt_off() -{} - IMPLEMENTATION[ia32]: #include "io.h" @@ -21,8 +7,6 @@ IMPLEMENTATION[ia32]: void __attribute__ ((noreturn)) pc_reset() { - virt_off(); - // i8042: store the next byte at port 0x60 as command byte while (Io::in8 (0x64) & 0x2) ; diff --git a/kernel/fiasco/src/kern/ia32/vmx.cpp b/kernel/fiasco/src/kern/ia32/vmx.cpp index c81544759..762308c1c 100644 --- a/kernel/fiasco/src/kern/ia32/vmx.cpp +++ b/kernel/fiasco/src/kern/ia32/vmx.cpp @@ -373,6 +373,11 @@ Vmx::vmwrite(Mword field, T value) asm volatile("vmwrite %0, %1" : : "r" ((Unsigned64)value >> 32), "r" (field + 1)); } +static void vmxoff(void) +{ + asm volatile("vmxoff"); +} + PUBLIC Vmx::Vmx(unsigned cpu) : _vmx_enabled(false), _has_vpid(false) @@ -456,6 +461,8 @@ Vmx::Vmx(unsigned cpu) asm volatile("vmxon %0" : :"m"(_vmxon_base_pa):); _vmx_enabled = true; + atexit(vmxoff); + printf("VMX: initialized\n"); Mword eflags; diff --git a/l4/pkg/mag-gfx/include/canvas b/l4/pkg/mag-gfx/include/canvas index 5165be253..d203e9d44 100644 --- a/l4/pkg/mag-gfx/include/canvas +++ b/l4/pkg/mag-gfx/include/canvas @@ -44,6 +44,7 @@ public: virtual void draw_box(Rect const &rect, Rgba32::Color color) = 0; virtual void draw_string(Point const &pos, Font const *f, Rgba32::Color color, char const *str, unsigned len = -1) = 0; virtual void draw_texture(Texture const *src, Rgb32::Color mix_color, Point const &pos, Mix_mode mode) = 0; + virtual void draw_texture_scaled(Texture const *src, Area const &size, Rgb32::Color mix_color, Point const &pos, Mix_mode mode) = 0; virtual void *buffer() const = 0; virtual void buffer(void *buffer) = 0; diff --git a/l4/pkg/mag-gfx/include/geometry b/l4/pkg/mag-gfx/include/geometry index 4c97e0537..5f57ef1c4 100644 --- a/l4/pkg/mag-gfx/include/geometry +++ b/l4/pkg/mag-gfx/include/geometry @@ -13,14 +13,19 @@ namespace Mag_gfx { -template< typename R > -class Vector_2d +class Vector_2d_base { protected: int _x, _y; + Vector_2d_base(int x, int y) : _x(x), _y(y) {} +}; +template< typename R > +class Vector_2d : public Vector_2d_base +{ public: - Vector_2d(int x, int y) : _x(x), _y(y) {} + Vector_2d(int x, int y) : Vector_2d_base(x, y) {} + explicit Vector_2d(Vector_2d_base const &o) : Vector_2d_base(o) {} // Point() : _x(-1), _y(-1) {} //int x() const { return _x; } @@ -71,6 +76,8 @@ public: Point(int x, int y) : B(x, y) {} Point() : B(-1, -1) {} + explicit Point(Vector_2d_base const &o) : B(o) {} + int x() const { return _x; } int y() const { return _y; } diff --git a/l4/pkg/mag-gfx/include/mem_canvas b/l4/pkg/mag-gfx/include/mem_canvas index b26ae66de..4fb514205 100644 --- a/l4/pkg/mag-gfx/include/mem_canvas +++ b/l4/pkg/mag-gfx/include/mem_canvas @@ -43,123 +43,16 @@ public: private: template< typename CT > - void _draw_box(char *dst_line, int _w, int h, CT color, int a) - { - Color const c = color_conv(color); - for (; h--; dst_line += _bpl) - { - int w; - Pixel *dst = reinterpret_cast(dst_line); - for (w = _w; w--; dst++) - if (!CT::A::Size) - *dst = c; - else - *dst = Color::Traits::mix(*dst, c, a); - } - } + void _draw_box(char *dst_line, int _w, int h, CT color, int a); template< typename CT > void __draw_string(Point const &p, Font const *font, typename CT::Color color, - char const *_str, unsigned len) - { - enum { Alphas = CT::A::Size }; - const unsigned char *str = (const unsigned char *)_str; - int x = p.x(), y = p.y(); - - if (!str || !font) - return; - - unsigned char const *src = font->img; - int d, h = font->str_h(_str); - - /* check top clipping */ - if ((d = _clip.y1() - y) > 0) - { - src += d * font->w; - y += d; - h -= d; - } - - /* check bottom clipping */ - if ((d = y + h - 1 - _clip.y2()) > 0) - h -= d; - - if (h < 1) - return; - - /* skip hidden glyphs */ - for ( ; *str && len && (x + font->wtab[*str] < _clip.x1()); --len) - x += font->wtab[*str++]; - - int x_start = x; - - char *dst = _pixels + y * _bpl; - Color pix = color_conv(color); - int alpha = 255; - if (Alphas) - alpha = color.a() << (8 - Alphas); - - /* draw glyphs */ - for ( ; *str && len && (x <= _clip.x2()); ++str, --len) - { - int w = font->wtab[*str]; - int start = std::max(0, _clip.x1() - x); - int end = std::min(w - 1, _clip.x2() - x); - char *d = dst + x * sizeof(Pixel); - unsigned char const *s = src + font->otab[*str]; - - for (int j = 0; j < h; ++j, s += font->w, d += _bpl) - for (int i = start; i <= end; ++i) - if (s[i]) - { - Pixel *p = reinterpret_cast(d) + i; - *p = Pixel_traits::mix(*p, pix, (alpha * s[i]) >> 8); - } - - x += w; - } - - flush_pixels(Rect(Point(x_start, y), Area(x - x_start + 1, h))); - } + char const *_str, unsigned len); bool _draw_alpha_texture(Texture const *texture, Pixel const *src, char *dst, int offset, - int h, int w, int src_w) - { - typedef typename Pixel_traits::Pixel Pixel; - bool xa = !Pixel_traits::A::Size && texture->extra_alpha(); - if (!xa && !Pixel_traits::A::Size) - return false; - - unsigned char const *ab; - if (xa) - ab = texture->alpha_buffer() + offset; - - for (int j = h; j--; src += src_w, dst += _bpl) - { - Pixel *dp = reinterpret_cast(dst); - Pixel const *s = src; - unsigned char const *sab = ab; - - for (int i = w; i--; ++s, ++dp) - { - int alpha; - if (!xa) - alpha = Color(*s).a() << (8 - Pixel_traits::A::Size); - else - alpha = *sab++; - - if (alpha < 255) - *dp = Pixel_traits::mix(*dp, *s, alpha); - else if (alpha > 0) - *dp = *s; - } - if (xa) - ab += src_w; - } - return true; - } + int h, int w, int src_w); public: void draw_box(Rect const &rect, Rgba32::Color color) @@ -188,61 +81,370 @@ public: } void draw_texture(Mag_gfx::Texture const *texture, Rgb32::Color mix_color, - Point const &pos, Mix_mode mode) - { - Rect const clipped = _clip & Rect(pos, texture->size()); + Point const &pos, Mix_mode mode); - if (!clipped.valid()) - return; + void draw_texture_scaled(Mag_gfx::Texture const *texture, Area const &size, + Rgb32::Color mix_color, Point const &pos, + Mix_mode mode); - int src_w = texture->size().w(); - Texture const *txt; - txt = static_cast const *>(texture); - Pixel const *src = txt->pixels() - + (clipped.y1() - pos.y()) * src_w - + clipped.x1() - pos.x(); - - char *dst = _pixels + clipped.y1() * _bpl + clipped.x1() * sizeof(Pixel); - char *d; - - int i, j; - Pixel const *s; - Color mix_pixel = color_conv(mix_color); - - switch (mode) - { - case Alpha: - if (_draw_alpha_texture(txt, src, dst, - (clipped.y1() - pos.y()) * src_w + clipped.x1() - pos.x(), - clipped.h(), clipped.w(), src_w)) - break; - // Fall through to solid! - case Solid: -// for (j = clipped.h(); j--; src += src_w, dst += _bpl) -// for (i = clipped.w(), s = src, d = dst; i--; ++s, d += sizeof(Pixel)) -// *reinterpret_cast(d) = *s; - Blit::blit(src, src_w * sizeof(Pixel), - dst, _bpl, clipped.w() * sizeof(Pixel), clipped.h()); - break; +}; - case Mixed: - mix_pixel = color_50(mix_pixel); - for (j = clipped.h(); j--; src += src_w, dst += _bpl) - for (i = clipped.w(), s = src, d = dst; i--; ++s, d += sizeof(Pixel)) - *reinterpret_cast(d) = color_50(Color(*s)) + mix_pixel; - break; - case Masked: - for (j = clipped.h(); j--; src += src_w, dst += _bpl) - for (i = clipped.w(), s = src, d = dst; i--; ++s, d += sizeof(Pixel)) - if (s->v()) - *reinterpret_cast(d) = *s; +template< typename PT> +template< typename CT > +void +Canvas::_draw_box(char *dst_line, int _w, int h, CT color, int a) +{ + Color const c = color_conv(color); + for (; h--; dst_line += _bpl) + { + int w; + Pixel *dst = reinterpret_cast(dst_line); + for (w = _w; w--; dst++) + if (!CT::A::Size) + *dst = c; + else + *dst = Color::Traits::mix(*dst, c, a); + } +} + +template< typename PT> +template< typename CT > +void +Canvas::__draw_string(Point const &p, Font const *font, + typename CT::Color color, + char const *_str, unsigned len) +{ + enum { Alphas = CT::A::Size }; + const unsigned char *str = (const unsigned char *)_str; + int x = p.x(), y = p.y(); + + if (!str || !font) + return; + + unsigned char const *src = font->img; + int d, h = font->str_h(_str); + + /* check top clipping */ + if ((d = _clip.y1() - y) > 0) + { + src += d * font->w; + y += d; + h -= d; + } + + /* check bottom clipping */ + if ((d = y + h - 1 - _clip.y2()) > 0) + h -= d; + + if (h < 1) + return; + + /* skip hidden glyphs */ + for ( ; *str && len && (x + font->wtab[*str] < _clip.x1()); --len) + x += font->wtab[*str++]; + + int x_start = x; + + char *dst = _pixels + y * _bpl; + Color pix = color_conv(color); + int alpha = 255; + if (Alphas) + alpha = color.a() << (8 - Alphas); + + /* draw glyphs */ + for ( ; *str && len && (x <= _clip.x2()); ++str, --len) + { + int w = font->wtab[*str]; + int start = std::max(0, _clip.x1() - x); + int end = std::min(w - 1, _clip.x2() - x); + char *d = dst + x * sizeof(Pixel); + unsigned char const *s = src + font->otab[*str]; + + for (int j = 0; j < h; ++j, s += font->w, d += _bpl) + for (int i = start; i <= end; ++i) + if (s[i]) + { + Pixel *p = reinterpret_cast(d) + i; + *p = Pixel_traits::mix(*p, pix, (alpha * s[i]) >> 8); + } + + x += w; + } + + flush_pixels(Rect(Point(x_start, y), Area(x - x_start + 1, h))); +} + +template +bool +Canvas::_draw_alpha_texture(Texture const *texture, + Pixel const *src, char *dst, int offset, + int h, int w, int src_w) +{ + typedef typename Pixel_traits::Pixel Pixel; + bool xa = !Pixel_traits::A::Size && texture->extra_alpha(); + if (!xa && !Pixel_traits::A::Size) + return false; + + unsigned char const *ab; + if (xa) + ab = texture->alpha_buffer() + offset; + + for (int j = h; j--; src += src_w, dst += _bpl) + { + Pixel *dp = reinterpret_cast(dst); + Pixel const *s = src; + unsigned char const *sab = ab; + + for (int i = w; i--; ++s, ++dp) + { + int alpha; + if (!xa) + alpha = Color(*s).a() << (8 - Pixel_traits::A::Size); + else + alpha = *sab++; + + if (alpha < 255) + *dp = Pixel_traits::mix(*dp, *s, alpha); + else if (alpha > 0) + *dp = *s; + } + if (xa) + ab += src_w; + } + return true; +} + +template +void +Canvas::draw_texture(Mag_gfx::Texture const *texture, + Rgb32::Color mix_color, Point const &pos, + Mix_mode mode) +{ + Rect const clipped = _clip & Rect(pos, texture->size()); + + if (!clipped.valid()) + return; + + int src_w = texture->size().w(); + Texture const *txt; + txt = static_cast const *>(texture); + Pixel const *src = txt->pixels() + + (clipped.y1() - pos.y()) * src_w + + clipped.x1() - pos.x(); + + char *dst = _pixels + clipped.y1() * _bpl + clipped.x1() * sizeof(Pixel); + char *d; + + int i, j; + Pixel const *s; + Color mix_pixel = color_conv(mix_color); + + switch (mode) + { + case Alpha: + if (_draw_alpha_texture(txt, src, dst, + (clipped.y1() - pos.y()) * src_w + clipped.x1() - pos.x(), + clipped.h(), clipped.w(), src_w)) break; + // Fall through to solid! + case Solid: + // for (j = clipped.h(); j--; src += src_w, dst += _bpl) + // for (i = clipped.w(), s = src, d = dst; i--; ++s, d += sizeof(Pixel)) + // *reinterpret_cast(d) = *s; + Blit::blit(src, src_w * sizeof(Pixel), + dst, _bpl, clipped.w() * sizeof(Pixel), clipped.h()); + break; + + case Mixed: + mix_pixel = color_50(mix_pixel); + for (j = clipped.h(); j--; src += src_w, dst += _bpl) + for (i = clipped.w(), s = src, d = dst; i--; ++s, d += sizeof(Pixel)) + *reinterpret_cast(d) = color_50(Color(*s)) + mix_pixel; + break; + + case Masked: + for (j = clipped.h(); j--; src += src_w, dst += _bpl) + for (i = clipped.w(), s = src, d = dst; i--; ++s, d += sizeof(Pixel)) + if (s->v()) + *reinterpret_cast(d) = *s; + break; } - flush_pixels(clipped); - } + flush_pixels(clipped); +} + +template< typename Pixel, typename Op > +inline +void +draw_loop(Area const &area, unsigned const *cb, unsigned const *rb, + unsigned bpl, + char const *src, char *dst, Op const &op) +{ + char const *s; + char *d; + int i, j; + for (j = area.h(); j--; dst += bpl) + for (i = area.w(), s = src + rb[j], d = dst; i--; d += sizeof(Pixel)) + op(reinterpret_cast(d), reinterpret_cast(s + cb[i])); +} + + +namespace { +static inline void +calc_xscale_buffer(unsigned dx, unsigned dy, unsigned s, unsigned w, unsigned sbpp, unsigned *sb) +{ + int f = dx / 2; + unsigned y = 0; + unsigned x = 0; + + for (x = 0; x < s; ++x) + { + f = f - dy; + if (f < 0) + { + y += sbpp; + f = f + dx; + } + } + + for (x = w; x--;) + { + f = f - dy; + sb[x] = y; + if (f < 0) + { + y += sbpp; + f = f + dx; + } + } +} + +static inline void +calc_yscale_buffer(unsigned dx, unsigned dy, unsigned s, unsigned w, unsigned sbpp, unsigned *sb) +{ + int f = dx / 2; + unsigned y = 0; + unsigned x = 0; + unsigned xv = 0; + + for (x = 0; y < s && x < dx; ++x) + { + f = f - dy; + if (f < 0) + { + f = f + dx; + if (y >= s) + break; + ++y; + } + xv += sbpp; + } + + y = w - 1; + sb[y] = xv; + + if (!y) + return; + + for (;x < dx; ++x) + { + f = f - dy; + if (f < 0) + { + f = f + dx; + --y; + sb[y] = xv; + if (y == 0) + return; + } + xv += sbpp; + } +} + +template< typename Pixel > +struct Solid_copy +{ void operator () (Pixel *d, Pixel const *s) const { *d = *s; } }; + +template< typename Pixel, typename Color > +struct Mix_50_copy +{ + Color mix_pixel; + Mix_50_copy(Rgb32::Color mix_color) + : mix_pixel(color_conv(mix_color)) + {} + void operator () (Pixel *d, Pixel const *s) const + { *d = color_50(Color(*s)) + mix_pixel; } }; +template< typename Pixel > +struct Masked_copy +{ + void operator () (Pixel *d, Pixel const *s) const + { + if (s->v()) *d = *s; + } +}; +} + +template +void +Canvas::draw_texture_scaled(Mag_gfx::Texture const *texture, + Area const &size, + Rgb32::Color mix_color, Point const &pos, + Mix_mode mode) +{ + Rect const clipped = _clip & Rect(pos, size); //texture->size()); + + if (!clipped.valid()) + return; + + Point tl_offs = clipped.p1() - pos; + unsigned *col_buf = (unsigned*)alloca(sizeof(unsigned) * clipped.w()); + unsigned *row_buf = (unsigned*)alloca(sizeof(unsigned) * clipped.h()); + + Area ts = texture->size(); + + if (size.w() > ts.w()) + calc_xscale_buffer(size.w(), ts.w(), tl_offs.x(), clipped.w(), sizeof(Pixel), col_buf); + else + calc_yscale_buffer(ts.w(), size.w(), tl_offs.x(), clipped.w(), sizeof(Pixel), col_buf); + + if (size.h() > ts.h()) + calc_xscale_buffer(size.h(), ts.h(), tl_offs.y(), clipped.h(), ts.w() * sizeof(Pixel), row_buf); + else + calc_yscale_buffer(ts.h(), size.h(), tl_offs.y(), clipped.h(), ts.w() * sizeof(Pixel), row_buf); + + char const *src = (char const *)texture->pixels(); + char *dst = _pixels + clipped.y1() * _bpl + clipped.x1() * sizeof(Pixel); + + Mix_50_copy mix_copy(mix_color); + + switch (mode) + { + case Alpha: +#if 0 + if (_draw_alpha_texture(txt, src, dst, + (clipped.y1() - pos.y()) * src_w + clipped.x1() - pos.x(), + clipped.h(), clipped.w(), src_w)) + break; +#endif + // Fall through to solid! + case Solid: + draw_loop(clipped.area(), col_buf, row_buf, _bpl, src, dst, Solid_copy()); + break; + + case Mixed: + draw_loop(clipped.area(), col_buf, row_buf, _bpl, src, dst, mix_copy); + break; + + case Masked: + draw_loop(clipped.area(), col_buf, row_buf, _bpl, src, dst, Masked_copy()); + break; + } + + flush_pixels(clipped); +} + }} diff --git a/l4/pkg/mag-gfx/include/mem_texture b/l4/pkg/mag-gfx/include/mem_texture index bbd572eca..b8588eed7 100644 --- a/l4/pkg/mag-gfx/include/mem_texture +++ b/l4/pkg/mag-gfx/include/mem_texture @@ -118,6 +118,54 @@ public: } } } + + void blit_line(void const *_src, Pixel_info const *st, int line, unsigned *offset_buffer) + { + Pixel *dst = pixels(); + + if (line >= size().h()) + return; + + dst += size().w() * line; + + char const *src = (char const *)_src; + + if (st == type()) + { + for (int i = 0; i < size().w(); ++i, ++dst) + *dst = *(Pixel const *)(src + offset_buffer[i]); + + if (extra_alpha()) + memset(alpha_buffer() + size().w() * line, ~0, size().w()); + } + else + { +#if 0 + printf("texture convert: %dx%d %d(%d):%d(%d):%d(%d):%d(%d) -> %dx%d %d(%d):%d(%d):%d(%d):%d(%d)\n", + (int)o->size().w(), (int)o->size().h(), + (int)o->type()->r.si, (int)o->type()->r.sh, + (int)o->type()->g.si, (int)o->type()->g.sh, + (int)o->type()->b.si, (int)o->type()->b.sh, + (int)o->type()->a.si, (int)o->type()->a.sh, + (int)size().w(), (int)size().h(), + (int)type()->r.si, (int)type()->r.sh, + (int)type()->g.si, (int)type()->g.sh, + (int)type()->b.si, (int)type()->b.sh, + (int)type()->a.si, (int)type()->a.sh); +#endif + unsigned char *ab = alpha_buffer(); + bool const xa = ab; + ab += size().w() * line; + + for (int y = 0; y < size().w(); y++) + { + Mag_gfx::Pixel_info::Color c = st->get(src + offset_buffer[y]); + dst[y] = Color(c); + if (xa) + ab[y] = c.a >> 8; + } + } + } }; }} diff --git a/l4/pkg/mag-gfx/include/texture b/l4/pkg/mag-gfx/include/texture index 3f48e1529..7ea3205e9 100644 --- a/l4/pkg/mag-gfx/include/texture +++ b/l4/pkg/mag-gfx/include/texture @@ -35,6 +35,7 @@ public: void pixels(void *pixels) { _pixels = pixels; } virtual void blit(Texture const *src, int start_line = 0) = 0; + virtual void blit_line(void const *src, Pixel_info const *st, int line, unsigned *offset_buffer) = 0; bool extra_alpha() const { return _extra_alpha; } virtual ~Texture() {} diff --git a/l4/pkg/scout-gfx/include/doc/link b/l4/pkg/scout-gfx/include/doc/link index a529c5bb3..8a48ee7ee 100644 --- a/l4/pkg/scout-gfx/include/doc/link +++ b/l4/pkg/scout-gfx/include/doc/link @@ -75,7 +75,7 @@ public: /** * Event handler interface */ - void handle_event(Event const &e); + Widget *handle_event(Event const &e); void mfocus(int flag); diff --git a/l4/pkg/scout-gfx/include/doc/navbar b/l4/pkg/scout-gfx/include/doc/navbar index cffbabf14..dff768b98 100644 --- a/l4/pkg/scout-gfx/include/doc/navbar +++ b/l4/pkg/scout-gfx/include/doc/navbar @@ -43,18 +43,19 @@ private: /** * Event handler interface */ - void handle(Event const &ev) + bool handle(Event const &ev) { if (ev.type != Event::PRESS || !_navbar) - return; + return true; Scout_gfx::Browser *b = _navbar->browser(); if (!b || !_dst) - return; + return true; _navbar->curr(0); b->go_to(_dst); _navbar->fade_to(100, 2); + return true; } }; diff --git a/l4/pkg/scout-gfx/include/event b/l4/pkg/scout-gfx/include/event index 78c004c13..7496d61b3 100644 --- a/l4/pkg/scout-gfx/include/event +++ b/l4/pkg/scout-gfx/include/event @@ -84,7 +84,7 @@ public: /** * Handle event */ - virtual void handle(Event const &e) = 0; + virtual bool handle(Event const &e) = 0; }; diff --git a/l4/pkg/scout-gfx/include/layout b/l4/pkg/scout-gfx/include/layout index 5e38537b6..ac1106817 100644 --- a/l4/pkg/scout-gfx/include/layout +++ b/l4/pkg/scout-gfx/include/layout @@ -20,7 +20,8 @@ private: int _spacing; public: - Layout() : _margin(0), _spacing(0) {} + int _dbg; + Layout() : _margin(0), _spacing(0), _dbg(0) {} virtual ~Layout() {} int margin() const { return _margin; } diff --git a/l4/pkg/scout-gfx/include/layout_item b/l4/pkg/scout-gfx/include/layout_item index f58619b59..3da2ec9c6 100644 --- a/l4/pkg/scout-gfx/include/layout_item +++ b/l4/pkg/scout-gfx/include/layout_item @@ -26,7 +26,26 @@ using Mag_gfx::Orientations; class Widget; class Layout; -class Layout_item +class Layout_item_iface +{ +public: + virtual Area preferred_size() const = 0; + virtual Area min_size() const = 0; + virtual Area max_size() const = 0; + + virtual Orientations expanding() const = 0; + virtual bool empty() const = 0; + + virtual bool has_height_for_width() const = 0; + virtual int height_for_width(int) const = 0; + virtual int min_height_for_width(int) const = 0; + + virtual ~Layout_item_iface() = 0; +}; + +inline Layout_item_iface::~Layout_item_iface() {} + +class Layout_item : public virtual Layout_item_iface { private: Layout_item *_parent; @@ -38,15 +57,6 @@ public: Layout_item *parent_layout_item() const { return _parent; } void set_parent_layout_item(Layout_item *p) { _parent = p; } - virtual Area preferred_size() const = 0; - virtual Area min_size() const = 0; - virtual Area max_size() const = 0; - - virtual Orientations expanding() const = 0; - virtual bool empty() const = 0; - virtual bool has_height_for_width() const { return false; } - virtual int height_for_width(int) const { return -1; } - virtual int min_height_for_width(int) const { return -1; } virtual void set_geometry(Rect const &) = 0; virtual Rect geometry() const = 0; @@ -65,6 +75,10 @@ public: Rect aligned_rect(Rect const &); Area aligned_max_size() const; void aligned_set_geometry(Rect const &); + + virtual bool has_height_for_width() const { return false; } + virtual int height_for_width(int) const { return -1; } + virtual int min_height_for_width(int) const { return -1; } }; diff --git a/l4/pkg/scout-gfx/include/loadbar b/l4/pkg/scout-gfx/include/loadbar index e032bffd2..8d737fe2d 100644 --- a/l4/pkg/scout-gfx/include/loadbar +++ b/l4/pkg/scout-gfx/include/loadbar @@ -49,11 +49,13 @@ public: /** * Event handler interface */ - void handle(Event const &ev) + bool handle(Event const &ev) { if (ev.type == Event::PRESS || ev.type == Event::MOTION) if (_listener && ev.key_cnt > 0) _listener->loadbar_changed(_lb, ev.m.x()); + + return true; } }; diff --git a/l4/pkg/scout-gfx/include/scrollbar b/l4/pkg/scout-gfx/include/scrollbar index bc4158a25..361a0bb36 100644 --- a/l4/pkg/scout-gfx/include/scrollbar +++ b/l4/pkg/scout-gfx/include/scrollbar @@ -77,7 +77,7 @@ private: /** * Event handler interface */ - void handle(Event const &ev); + bool handle(Event const &ev); /** * Tick interface @@ -106,7 +106,7 @@ private: /** * Event handler interface */ - void handle(Event const &ev); + bool handle(Event const &ev); }; Icon *_uparrow; diff --git a/l4/pkg/scout-gfx/include/user_state b/l4/pkg/scout-gfx/include/user_state index 4c80a480d..09fa96daf 100644 --- a/l4/pkg/scout-gfx/include/user_state +++ b/l4/pkg/scout-gfx/include/user_state @@ -28,7 +28,6 @@ private: // Widget *_dst; /* current link destination */ Widget *_active; /* currently activated element */ Point _am; - Point _m; /* current mouse position */ Point _v; /* current view offset */ /** @@ -48,13 +47,13 @@ public: /** * Accessor functions */ - Point m() const { return _m; } + //Point m() const { return _m; } //Point v() const { return _v; } /** * Apply input event to mouse focus state */ - void handle_event(Event const &ev); + Widget *handle_event(Event const &ev); /******************** ** Parent element ** diff --git a/l4/pkg/scout-gfx/include/widget b/l4/pkg/scout-gfx/include/widget index 372542736..7d44c9413 100644 --- a/l4/pkg/scout-gfx/include/widget +++ b/l4/pkg/scout-gfx/include/widget @@ -56,6 +56,11 @@ public: Area size() const { return _size; } Point pos() const { return _pos; } Rect geometry() const { return Rect(_pos, _size); } + void set_geometry(Rect const &g) + { + _pos = g.p1(); + _size = g.area(); + } inline Point map_to_parent(Point const &po, Widget *p = 0) const; @@ -120,10 +125,11 @@ public: /** * Handle user input or timer event */ - virtual void handle_event(Event const &ev) + virtual Widget *handle_event(Event const &ev) { - if (_evh) - _evh->handle(ev); + if (_evh && _evh->handle(ev)) + return this; + return 0; } }; diff --git a/l4/pkg/scout-gfx/include/window b/l4/pkg/scout-gfx/include/window index 5e944aed4..9ac780105 100644 --- a/l4/pkg/scout-gfx/include/window +++ b/l4/pkg/scout-gfx/include/window @@ -1,3 +1,4 @@ +// vi:ft=cpp /* * (c) 2010 Alexander Warg * economic rights: Technische Universität Dresden (Germany) @@ -6,7 +7,6 @@ * GNU General Public License 2. * Please see the COPYING-GPL-2 file for details. */ -// vi:ft=cpp #pragma once @@ -41,6 +41,9 @@ private: View *_view; Area _max_sz; + Widget *_mfocus; + Widget *_active; + Point _active_pos; protected: Area _min_sz; @@ -64,21 +67,22 @@ public: if (h > 0) s.h(std::max(s.h(), h)); - child_layout()->set_geometry(Rect(Point(0,0), s)); + child_layout()->set_geometry(Rect(Point(0, 0), s)); _size = s; } Orientations expanding() const { return Orientations(); } bool empty() const { return false; } - void set_geometry(Rect const &r) + void set_geometry(Rect const &r, bool force) { bool need_redraw = false; Area s = r.area().min(max_size()); - if (child_layout() && s != _size) + if (child_layout() && (force || s != _size)) { _size = s; + child_layout()->set_geometry(Rect(s)); child_invalidate(); need_redraw = true; } @@ -90,6 +94,9 @@ public: _pos = ng.p1(); _size = ng.area(); } + void set_geometry(Rect const &r) + { set_geometry(r, false); } + Rect geometry() const { return Rect(_pos, _size); } Window(View *view, Area const &max_sz) @@ -134,6 +141,10 @@ public: Parent_widget::draw(c, p); } + Widget *handle_event(Event const &ev); + +private: + void _assign_mfocus(Widget *e, int force = 0); }; @@ -156,10 +167,10 @@ public: /** * Event handler interface */ - void handle(Scout_gfx::Event const &ev) + bool handle(Scout_gfx::Event const &ev) { if (ev.key_cnt == 0) - return; + return false; /* first click starts dragging */ if ((ev.type == Scout_gfx::Event::PRESS) && (ev.key_cnt == 1)) @@ -171,12 +182,13 @@ public: /* check if mouse was moved */ if (ev.m == _cm) - return; + return true; /* remember current mouse position */ _cm = ev.m; do_drag(); + return true; } virtual ~Drag_event_handler() {} diff --git a/l4/pkg/scout-gfx/lib/Make.rules b/l4/pkg/scout-gfx/lib/Make.rules index 4c70ae6ce..ce28d0cb7 100644 --- a/l4/pkg/scout-gfx/lib/Make.rules +++ b/l4/pkg/scout-gfx/lib/Make.rules @@ -13,7 +13,8 @@ SRC_CC = tick.cc png_image.cc \ doc/verbatim.cc \ loadbar.cc \ redraw_manager.cc \ - grid_layout.cc + grid_layout.cc \ + window.cc SRC_BIN = vera16.tff \ verai16.tff \ diff --git a/l4/pkg/scout-gfx/lib/box_layout.cc b/l4/pkg/scout-gfx/lib/box_layout.cc index 0ffadbbd7..7cb7810a3 100644 --- a/l4/pkg/scout-gfx/lib/box_layout.cc +++ b/l4/pkg/scout-gfx/lib/box_layout.cc @@ -13,6 +13,8 @@ #include "layout_internal.h" #include +#include + namespace Scout_gfx { class Box_layout_p : public Box_layout @@ -220,12 +222,16 @@ Box_layout_p::min_height_for_width(int w) const void Box_layout_p::set_geometry(Rect const &r) { + if (_dbg) + printf("BL[%p] set_geometry(%d,%d - %d,%d)\n", this, r.x1(), r.y1(), r.x2(), r.y2()); if (r == geometry() && !_d.need_refresh) return; if (_d.need_refresh) setup_geometry(); + if (_dbg) + printf("BL[%p] set_geometry(ms=%d,%d\n", this, min_size().w(), min_size().h()); do_set_geometry(r.grow(-margin())); } diff --git a/l4/pkg/scout-gfx/lib/doc/link.cc b/l4/pkg/scout-gfx/lib/doc/link.cc index e9d85a111..2c66d58e7 100644 --- a/l4/pkg/scout-gfx/lib/doc/link.cc +++ b/l4/pkg/scout-gfx/lib/doc/link.cc @@ -25,16 +25,19 @@ Link_token::browser() const } -void Link_token::handle_event(Event const &e) +Widget * +Link_token::handle_event(Event const &e) { - Token::handle_event(e); + Widget *r = Token::handle_event(e); if (e.type != Event::PRESS) - return; + return r; /* make browser to follow link */ Browser *b = browser(); if (b && _dst) b->go_to(_dst); + + return this; } diff --git a/l4/pkg/scout-gfx/lib/scrollbar.cc b/l4/pkg/scout-gfx/lib/scrollbar.cc index 7c7a4c5a0..3070b39a9 100644 --- a/l4/pkg/scout-gfx/lib/scrollbar.cc +++ b/l4/pkg/scout-gfx/lib/scrollbar.cc @@ -28,7 +28,7 @@ namespace Scout_gfx { /** * Event handler interface */ -void +bool Scrollbar::Arrow_event_handler::handle(Event const &ev) { /* start movement with zero speed */ @@ -54,6 +54,8 @@ Scrollbar::Arrow_event_handler::handle(Event const &ev) _accel = 64; _dst_speed = 0; } + + return true; } /** @@ -101,7 +103,7 @@ Scrollbar::Arrow_event_handler::on_tick() /** * Event handler interface */ -void +bool Scrollbar::Slider_event_handler::handle(Event const &ev) { @@ -131,6 +133,8 @@ Scrollbar::Slider_event_handler::handle(Event const &ev) _sb->slider_pos(_op + _cm - _om); _sb->notify_listener(); } + + return true; } diff --git a/l4/pkg/scout-gfx/lib/user_state.cc b/l4/pkg/scout-gfx/lib/user_state.cc index f58c1c22a..d555f3be9 100644 --- a/l4/pkg/scout-gfx/lib/user_state.cc +++ b/l4/pkg/scout-gfx/lib/user_state.cc @@ -44,22 +44,17 @@ void User_state::_assign_mfocus(Widget *e, int force ) #endif } -void User_state::handle_event(Event const &ev) +Widget * +User_state::handle_event(Event const &ev) { Parent_widget::handle_event(ev); + if (_active) - { - Event re = ev; - re.m -= _am; - _active->handle_event(re); - } + _active->handle_event(ev); + Widget *e = 0; if (ev.type != 4) - - /* find element under the mouse cursor */ - _m = ev.m; - - Widget *e = find(_m); + e = find_child(ev.m); if (e == this) e = 0; @@ -71,15 +66,8 @@ void User_state::handle_event(Event const &ev) if (ev.key_cnt != 1 || !e) break; - { - Event re = ev; - _am = e->map_to_parent(Point(0,0)); - re.m -= _am; - - _active = e; - _active->handle_event(re); - } - + _active = e; + _active->handle_event(ev); _assign_mfocus(e, 1); break; @@ -93,28 +81,17 @@ void User_state::handle_event(Event const &ev) break; case Event::WHEEL: - if (Widget *x = find_child(_m)) - { - Event re = ev; - re.m = x->map_from_parent(ev.m); - x->handle_event(re); - } - break; case Event::MOTION: if (!_active && e) - { - Event re = ev; - re.m = e->map_from_parent(ev.m); - e->handle_event(re); - } + e->handle_event(ev); if (ev.key_cnt == 0) _assign_mfocus(e); break; default: - break; } + return this; } } diff --git a/l4/pkg/scout-gfx/lib/window.cc b/l4/pkg/scout-gfx/lib/window.cc new file mode 100644 index 000000000..21bee9ede --- /dev/null +++ b/l4/pkg/scout-gfx/lib/window.cc @@ -0,0 +1,123 @@ +/* + * (c) 2010 Alexander Warg + * economic rights: Technische Universität Dresden (Germany) + * + * This file is part of TUD:OS and distributed under the terms of the + * GNU General Public License 2. + * Please see the COPYING-GPL-2 file for details. + */ +#include + +namespace Scout_gfx { + +void +Window::_assign_mfocus(Widget *e, int force) +{ + /* return if mouse focus did not change */ + if (!force && e == _mfocus) + return; + + /* tell old mouse focus to release focus */ + if (_mfocus) + _mfocus->mfocus(0); + + /* assign new current mouse focus */ + _mfocus = e; + + /* notify new mouse focus */ + if (_mfocus) + _mfocus->mfocus(1); + +#if 0 + /* determine new current link destination */ + Widget *old_dst = _dst; + Link_token *lt; + if (_mfocus && (lt = dynamic_cast(_mfocus))) + { + _dst = lt->dst(); + } + else + _dst = 0; + /* nofify element tree about new link destination */ + if (_dst != old_dst) + _root->curr_link_destination(_dst); +#endif +} + +Widget * +Window::handle_event(Event const &ev) +{ + Parent_widget::handle_event(ev); + if (_active) + { + Event re = ev; + re.m -= _active_pos; + _active->handle_event(re); + } + + Widget *e = 0; + if (ev.type != 4) + e = find(ev.m); + + if (e == this) + e = 0; + + switch (ev.type) + { + + case Event::PRESS: + if (ev.key_cnt != 1 || !e) + break; + + { + _active_pos = e->map_to_parent(Point(0,0)); + _active = e; + + Event re = ev; + re.m -= _active_pos; + _active->handle_event(re); + } + + _assign_mfocus(e, 1); + + break; + + case Event::RELEASE: + if (ev.key_cnt == 0) + { + _active = 0; + _assign_mfocus(e); + } + break; + + case Event::WHEEL: +#if 0 + if (Widget *x = find_child(m)) + { + Event re = ev; + re.m = x->map_from_parent(ev.m); + x->handle_event(re); + } + break; +#endif + case Event::MOTION: + if (!_active && e) + { + Event re = ev; + re.m = e->map_from_parent(ev.m); + e->handle_event(re); + } + + if (ev.key_cnt == 0) + _assign_mfocus(e); + break; + + default: + + break; + } + + return this; +} +} + diff --git a/l4/pkg/scout/lib/src/panel.h b/l4/pkg/scout/lib/src/panel.h index e16d43d7e..83d995f9f 100644 --- a/l4/pkg/scout/lib/src/panel.h +++ b/l4/pkg/scout/lib/src/panel.h @@ -170,8 +170,8 @@ protected: /** * Event handler interface */ - void handle(Scout_gfx::Event const &ev) - { b->handle_event(ev); } + bool handle(Scout_gfx::Event const &ev) + { return b->handle_event(ev); } }; Ev_proxy _ev_proxy; @@ -208,11 +208,11 @@ public: /** * Event handler interface */ - void handle(Scout_gfx::Event const &ev) + bool handle(Scout_gfx::Event const &ev) { /* start movement with zero speed */ if ((ev.type != Scout_gfx::Event::PRESS) || (ev.key_cnt != 1)) - return; + return true; /* no flashing by default */ int flash = (_b->*_f)(); @@ -225,6 +225,8 @@ public: _fader->step(4); _fader->curr(190); } + + return true; } };