diff options
Diffstat (limited to 'lib')
36 files changed, 536 insertions, 142 deletions
diff --git a/lib/base/init_num.h b/lib/base/init_num.h index a9da0624..a9431c6b 100644 --- a/lib/base/init_num.h +++ b/lib/base/init_num.h @@ -8,6 +8,7 @@ namespace eAutoInitNumbers { configuration=0, lowlevel=configuration+increment, + network=lowlevel, graphic=lowlevel+increment, skin=graphic+increment, rc=skin+increment, diff --git a/lib/gdi/epoint.h b/lib/gdi/epoint.h index fc5f9836..d7cdf399 100644 --- a/lib/gdi/epoint.h +++ b/lib/gdi/epoint.h @@ -1,8 +1,6 @@ #ifndef EPOINT_H #define EPOINT_H -#include <iostream> - #ifndef ABS #define ABS(x) ( x>0 ? x : -x ) #endif @@ -35,7 +33,9 @@ public: friend inline bool operator==( const ePoint &, const ePoint & ); friend inline bool operator!=( const ePoint &, const ePoint & ); friend inline ePoint operator+( const ePoint &, const ePoint & ); + friend inline ePoint operator+( const ePoint &, const eSize & ); friend inline ePoint operator-( const ePoint &, const ePoint & ); + friend inline ePoint operator-( const ePoint &, const eSize & ); friend inline ePoint operator*( const ePoint &, int ); friend inline ePoint operator*( int, const ePoint & ); friend inline ePoint operator*( const ePoint &, double ); @@ -56,25 +56,6 @@ inline int ePoint::manhattanLength() const /***************************************************************************** - ePoint stream functions - *****************************************************************************/ -namespace std -{ - inline ostream &operator<<( ostream & s, const ePoint & p ) - { - s << p.x() << p.y(); - return s; - } - - inline istream &operator>>( istream & s, ePoint & p ) - { - s >> p.rx() >> p.ry(); - return s; - } -} - - -/***************************************************************************** ePoint inline functions *****************************************************************************/ @@ -129,6 +110,12 @@ inline ePoint operator+( const ePoint &p1, const ePoint &p2 ) inline ePoint operator-( const ePoint &p1, const ePoint &p2 ) { return ePoint(p1.xp-p2.xp, p1.yp-p2.yp); } +inline ePoint operator+( const ePoint &p1, const eSize &p2 ) +{ return ePoint(p1.xp+p2.width(), p1.yp+p2.height()); } + +inline ePoint operator-( const ePoint &p1, const eSize &p2 ) +{ return ePoint(p1.xp-p2.width(), p1.yp-p2.height()); } + inline ePoint operator*( const ePoint &p, int c ) { return ePoint(p.xp*c, p.yp*c); } diff --git a/lib/gdi/erect.cpp b/lib/gdi/erect.cpp index a3878797..43cefc53 100644 --- a/lib/gdi/erect.cpp +++ b/lib/gdi/erect.cpp @@ -1,5 +1,4 @@ #include <lib/gdi/erect.h> -#include <iostream> /***************************************************************************** eRect member functions diff --git a/lib/gdi/erect.h b/lib/gdi/erect.h index a67d0fb9..65fd8d71 100644 --- a/lib/gdi/erect.h +++ b/lib/gdi/erect.h @@ -52,6 +52,18 @@ public: ePoint bottomRight() const; ePoint topRight() const; ePoint bottomLeft() const; + + /* the sole intention of these functions + is to allow painting frames without + messing around with the coordinates. + they point to the last pixel included + in the rectangle (which means that 1 is + subtracted from the right and bottom + coordinates */ + ePoint topLeft1() const; + ePoint bottomRight1() const; + ePoint topRight1() const; + ePoint bottomLeft1() const; ePoint center() const; void rect( int *x, int *y, int *w, int *h ) const; @@ -196,6 +208,18 @@ inline ePoint eRect::topRight() const inline ePoint eRect::bottomLeft() const { return ePoint(x1, y2); } +inline ePoint eRect::topLeft1() const +{ return ePoint(x1, y1); } + +inline ePoint eRect::bottomRight1() const +{ return ePoint(x2-1, y2-1); } + +inline ePoint eRect::topRight1() const +{ return ePoint(x2-1, y1); } + +inline ePoint eRect::bottomLeft1() const +{ return ePoint(x1, y2-1); } + inline ePoint eRect::center() const { return ePoint((x1+x2)/2, (y1+y2)/2); } diff --git a/lib/gdi/esize.h b/lib/gdi/esize.h index d4bd4afb..de0a6ecb 100644 --- a/lib/gdi/esize.h +++ b/lib/gdi/esize.h @@ -1,8 +1,6 @@ #ifndef ESIZE_H #define ESIZE_H -#include <iostream> - #define MIN(a,b) (a < b ? a : b) #define MAX(a,b) (a > b ? a : b) @@ -53,26 +51,6 @@ private: /***************************************************************************** - eSize stream functions - *****************************************************************************/ - -namespace std -{ - inline ostream &operator<<( ostream &s, const eSize &sz ) - { - s << sz.width() << sz.height(); - return s; - } - - inline istream &operator>>( istream &s, eSize &sz ) - { - s >> sz.rwidth() >> sz.rheight(); - return s; - } -} - - -/***************************************************************************** eSize inline functions *****************************************************************************/ diff --git a/lib/gdi/font.cpp b/lib/gdi/font.cpp index ee228576..f7c62209 100644 --- a/lib/gdi/font.cpp +++ b/lib/gdi/font.cpp @@ -63,9 +63,9 @@ static gLookup &getColor(const gPalette &pal, const gRGB &start, const gRGB &end eDebug("[FONT] creating new font color cache entry %02x%02x%02x%02x .. %02x%02x%02x%02x", start.a, start.r, start.g, start.b, end.a, end.r, end.g, end.b); n.build(16, pal, start, end); -/* for (int i=0; i<16; i++) + for (int i=0; i<16; i++) eDebugNoNewLine("%02x|%02x%02x%02x%02x ", (int)n.lookup[i], pal.data[n.lookup[i]].a, pal.data[n.lookup[i]].r, pal.data[n.lookup[i]].g, pal.data[n.lookup[i]].b); - eDebug("");*/ + eDebug(""); return n; } @@ -675,6 +675,7 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons continue; int rx=i->x+glyph_bitmap->left + offset.x(); int ry=i->y-glyph_bitmap->top + offset.y(); + __u8 *d=(__u8*)(surface->data)+buffer_stride*ry+rx*surface->bypp; __u8 *s=glyph_bitmap->buffer; register int sx=glyph_bitmap->width; @@ -706,6 +707,7 @@ void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, cons { register __u8 *td=d; register int ax; + for (ax=0; ax<sx; ax++) { register int b=(*s++)>>4; diff --git a/lib/gdi/grc.cpp b/lib/gdi/grc.cpp index 4597034f..cb2a6de9 100644 --- a/lib/gdi/grc.cpp +++ b/lib/gdi/grc.cpp @@ -164,6 +164,17 @@ void gPainter::fill(const eRect &area) m_rc->submit(o); } +void gPainter::fill(const gRegion ®ion) +{ + gOpcode o; + o.opcode=gOpcode::fillRegion; + + o.dc = m_dc.grabRef(); + o.parm.fillRegion = new gOpcode::para::pfillRegion; + o.parm.fillRegion->region = region; + m_rc->submit(o); +} + void gPainter::clear() { gOpcode o; @@ -332,13 +343,13 @@ void gDC::exec(gOpcode *o) assert(m_current_font); para->setFont(m_current_font); para->renderString(o->parm.renderText->text, o->parm.renderText->flags); - para->blit(*this, m_current_offset, getRGB(m_foreground_color), getRGB(m_background_color)); + para->blit(*this, m_current_offset, getRGB(m_background_color), getRGB(m_foreground_color)); delete o->parm.renderText; break; } case gOpcode::renderPara: { - o->parm.renderPara->textpara->blit(*this, o->parm.renderPara->offset + m_current_offset, getRGB(m_foreground_color), getRGB(m_background_color)); + o->parm.renderPara->textpara->blit(*this, o->parm.renderPara->offset + m_current_offset, getRGB(m_background_color), getRGB(m_foreground_color)); o->parm.renderPara->textpara->Release(); delete o->parm.renderPara; break; @@ -352,6 +363,14 @@ void gDC::exec(gOpcode *o) delete o->parm.fill; break; } + case gOpcode::fillRegion: + { + o->parm.fillRegion->region.moveBy(m_current_offset); + gRegion clip = m_current_clip & o->parm.fillRegion->region; + m_pixmap->fill(clip, m_foreground_color); + delete o->parm.fillRegion; + break; + } case gOpcode::clear: m_pixmap->fill(m_current_clip, m_background_color); delete o->parm.fill; diff --git a/lib/gdi/grc.h b/lib/gdi/grc.h index a02068ae..d6a3cd70 100644 --- a/lib/gdi/grc.h +++ b/lib/gdi/grc.h @@ -29,7 +29,7 @@ struct gOpcode renderPara, setFont, - fill, clear, + fill, fillRegion, clear, blit, setPalette, @@ -55,6 +55,11 @@ struct gOpcode eRect area; } *fill; + struct pfillRegion + { + gRegion region; + } *fillRegion; + struct prenderText { eRect area; @@ -173,6 +178,7 @@ public: void renderPara(eTextPara *para, ePoint offset=ePoint(0, 0)); void fill(const eRect &area); + void fill(const gRegion &area); void clear(); diff --git a/lib/gdi/region.cpp b/lib/gdi/region.cpp index f79b403f..d75221fe 100644 --- a/lib/gdi/region.cpp +++ b/lib/gdi/region.cpp @@ -325,6 +325,8 @@ void gRegion::regionOp(const gRegion ®1, const gRegion ®2, int opcode, int for (unsigned int a = 0; a<rects.size(); ++a) extends = extends | rects[a]; + if (!extends.valid()) + extends = eRect::emptyRect(); } void gRegion::intersect(const gRegion &r1, const gRegion &r2) diff --git a/lib/gui/Makefile.am b/lib/gui/Makefile.am index a686e1ca..1b175c9a 100644 --- a/lib/gui/Makefile.am +++ b/lib/gui/Makefile.am @@ -5,5 +5,5 @@ INCLUDES = \ noinst_LIBRARIES = libenigma_gui.a libenigma_gui_a_SOURCES = \ - ebutton.cpp elabel.cpp ewidget.cpp ewidgetdesktop.cpp ewindow.cpp ewindowstyle.cpp + ebutton.cpp elabel.cpp eslider.cpp ewidget.cpp ewidgetdesktop.cpp ewindow.cpp ewindowstyle.cpp diff --git a/lib/gui/ebutton.cpp b/lib/gui/ebutton.cpp index 5c136abd..effcf1f6 100644 --- a/lib/gui/ebutton.cpp +++ b/lib/gui/ebutton.cpp @@ -6,13 +6,25 @@ eButton::eButton(eWidget *parent): eLabel(parent) void eButton::push() { - selected(); +// selected(); } int eButton::event(int event, void *data, void *data2) { switch (event) { + case evtPaint: + { + gPainter &painter = *(gPainter*)data2; + ePtr<eWindowStyle> style; + + getStyle(style); + + eLabel::event(event, data, data2); + style->drawButtonFrame(painter, eRect(ePoint(0, 0), size())); + + return 0; + } default: break; } diff --git a/lib/gui/ebutton.h b/lib/gui/ebutton.h index 31c9cb3c..25087077 100644 --- a/lib/gui/ebutton.h +++ b/lib/gui/ebutton.h @@ -7,7 +7,7 @@ class eButton: public eLabel { public: eButton(eWidget *parent); - Signal0<void> selected; +// Signal0<void> selected; void push(); protected: diff --git a/lib/gui/elabel.cpp b/lib/gui/elabel.cpp index f133b661..f9dcf31b 100644 --- a/lib/gui/elabel.cpp +++ b/lib/gui/elabel.cpp @@ -11,15 +11,18 @@ int eLabel::event(int event, void *data, void *data2) { case evtPaint: { + ePtr<eWindowStyle> style; + + getStyle(style); + + eWidget::event(event, data, data2); + gPainter &painter = *(gPainter*)data2; - ePtr<gFont> fnt = new gFont("Arial", 70); + ePtr<gFont> fnt = new gFont("Arial", 14); painter.setFont(fnt); - painter.setBackgroundColor(gColor(0x10)); - painter.setForegroundColor(gColor(0x1f)); - painter.clear(); - painter.setBackgroundColor(gColor(0x1f)); - painter.setForegroundColor(gColor(0x10)); + style->setForegroundStyle(painter); painter.renderText(eRect(0, 0, size().width(), size().height()), m_text); + return 0; } case evtChangedText: diff --git a/lib/gui/eslider.cpp b/lib/gui/eslider.cpp new file mode 100644 index 00000000..20b3ab47 --- /dev/null +++ b/lib/gui/eslider.cpp @@ -0,0 +1,56 @@ +#include <lib/gui/eslider.h> + +eSlider::eSlider(eWidget *parent): eWidget(parent) +{ +} + +int eSlider::event(int event, void *data, void *data2) +{ + switch (event) + { + case evtPaint: + { + ePtr<eWindowStyle> style; + gPainter &painter = *(gPainter*)data2; + + + getStyle(style); + style->paintBackground(painter, ePoint(0, 0), size()); + style->setForegroundStyle(painter); + painter.fill(m_currently_filled); + + return 0; + } + case evtChangedSlider: + { + + int num_pix = 0; + if (m_min < m_max) + num_pix = size().width() * m_value / (m_max - m_min); + gRegion old_currently_filled = m_currently_filled; + m_currently_filled = eRect(0, 0, num_pix, size().height()); + + // redraw what *was* filled before and now isn't. + invalidate(m_currently_filled - old_currently_filled); + // redraw what wasn't filled before and is now. + invalidate(old_currently_filled - m_currently_filled); + + return 0; + } + default: + return eWidget::event(event, data, data2); + } +} + +void eSlider::setValue(int value) +{ + m_value = value; + event(evtChangedSlider); +} + +void eSlider::setRange(int min, int max) +{ + m_min = min; + m_max = max; + event(evtChangedSlider); +} diff --git a/lib/gui/eslider.h b/lib/gui/eslider.h new file mode 100644 index 00000000..5b7b59f0 --- /dev/null +++ b/lib/gui/eslider.h @@ -0,0 +1,24 @@ +#ifndef __lib_gui_eslider_h +#define __lib_gui_eslider_h + +#include <lib/gui/ewidget.h> + +class eSlider: public eWidget +{ +public: + eSlider(eWidget *parent); + void setValue(int val); + void setRange(int min, int max); +protected: + int event(int event, void *data=0, void *data2=0); +private: + enum eSliderEvent + { + evtChangedSlider = evtUserWidget + }; + int m_min, m_max, m_value; + + gRegion m_currently_filled; +}; + +#endif diff --git a/lib/gui/ewidget.cpp b/lib/gui/ewidget.cpp index 89fbfe95..3ebac357 100644 --- a/lib/gui/ewidget.cpp +++ b/lib/gui/ewidget.cpp @@ -3,34 +3,68 @@ extern void dumpRegion(const gRegion ®ion); -eWidget::eWidget(eWidget *parent): m_parent(parent) +eWidget::eWidget(eWidget *parent): m_parent(parent ? parent->child() : 0) { m_vis = 0; m_desktop = 0; - if (parent) + if (m_parent) m_vis = wVisShow; - if (parent) - parent->m_childs.push_back(this); + if (m_parent) + { + m_parent->m_childs.push_back(this); + m_parent->getStyle(m_style); + } } void eWidget::move(ePoint pos) { + if (m_position == pos) + return; + m_position = pos; + /* we invalidate before and after the move to + cause a correct redraw. The area which is + included both before and after isn't redrawn + twice because a invalidate doesn't immediately + redraws the region. */ + invalidate(); event(evtChangedPosition); + recalcClipRegionsWhenVisible(); + invalidate(); } void eWidget::resize(eSize size) { + /* same strategy as with move: we first check if + the size changed at all, and if it did, we + invalidate both the old and new area. + TODO: check if either the old or new area + fits into the other completely, and invalidate + only once. */ + eSize old_size = m_size; event(evtWillChangeSize, &size); + if (old_size == m_size) + return; + + invalidate(); event(evtChangedSize); + recalcClipRegionsWhenVisible(); + invalidate(); } void eWidget::invalidate(const gRegion ®ion) { - gRegion res = /* region & */ m_visible_with_childs; + /* we determine the area to redraw, and re-position this + area to the absolute position, and then call the + desktop's invalidate() with that, which adds this + area into the dirty region. */ + gRegion res = m_visible_with_childs; + if (region.valid()) + res &= region; + if (res.empty()) return; @@ -103,10 +137,14 @@ void eWidget::destruct() eWidget::~eWidget() { + if (m_parent) + m_parent->m_childs.remove(this); + /* destroy all childs */ ePtrList<eWidget>::iterator i(m_childs.begin()); while (i != m_childs.end()) { + (*i)->m_parent = 0; delete *i; i = m_childs.erase(i); } @@ -129,24 +167,45 @@ void eWidget::doPaint(gPainter &painter, const gRegion &r) /* check if there's anything for us to paint */ region &= m_visible_region; - painter.resetClip(region); - event(evtPaint, ®ion, &painter); + if (!region.empty()) + { + painter.resetClip(region); + event(evtPaint, ®ion, &painter); + } painter.moveOffset(-position()); } +void eWidget::recalcClipRegionsWhenVisible() +{ + eWidget *t = this; + do + { + if (!(t->m_vis & wVisShow)) + break; + if (t->m_desktop) + { + t->m_desktop->recalcClipRegions(); + break; + } + t = t->m_parent; + assert(t); + } while(1); +} + int eWidget::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { - static int counter = 0x18; gPainter &painter = *(gPainter*)data2; -// eDebug("eWidget::evtPaint %d", counter); + +// eDebug("eWidget::evtPaint"); // dumpRegion(*(gRegion*)data); - painter.setBackgroundColor(gColor(++counter)); - painter.clear(); + ePtr<eWindowStyle> style; + if (!getStyle(style)) + style->paintBackground(painter, ePoint(0, 0), size()); break; } case evtKey: diff --git a/lib/gui/ewidget.h b/lib/gui/ewidget.h index a551b8a3..fa8cd8ca 100644 --- a/lib/gui/ewidget.h +++ b/lib/gui/ewidget.h @@ -3,6 +3,9 @@ #include <lib/gdi/grc.h> /* for gRegion */ #include <lib/base/eptrlist.h> /* for eSmartPtrList */ +#include <lib/gui/ewindowstyle.h> /* for eWindowStyle */ + +class eWindowStyle; class eWidget { @@ -17,11 +20,21 @@ public: eSize size() const { return m_size; } void invalidate(const gRegion ®ion = gRegion::invalidRegion()); + + /* the window were to attach childs to. Normally, this + is "this", but it can be overridden in case a widget + has a "client area", which is implemented as a child + widget. eWindow overrides this, for example. */ + virtual eWidget *child() { return this; } void show(); void hide(); void destruct(); + + int getStyle(ePtr<eWindowStyle> &style) { if (!m_style) return 1; style = m_style; return 0; } + void setStyle(eWindowStyle *style) { m_style = style; } + private: eWidgetDesktop *m_desktop; @@ -33,12 +46,14 @@ private: int m_vis; ePtrList<eWidget> m_childs; - eWidget *m_parent; ePoint m_position; eSize m_size; + eWidget *m_parent; + ePtr<eWindowStyle> m_style; void doPaint(gPainter &painter, const gRegion ®ion); + void recalcClipRegionsWhenVisible(); protected: virtual ~eWidget(); public: @@ -63,4 +78,6 @@ public: virtual int event(int event, void *data = 0, void *data2 = 0); }; +extern eWidgetDesktop *getDesktop(); + #endif diff --git a/lib/gui/ewidgetdesktop.cpp b/lib/gui/ewidgetdesktop.cpp index 10c92b71..ff913680 100644 --- a/lib/gui/ewidgetdesktop.cpp +++ b/lib/gui/ewidgetdesktop.cpp @@ -11,6 +11,11 @@ void eWidgetDesktop::addRootWidget(eWidget *root, int top) root->m_desktop = this; } +void eWidgetDesktop::removeRootWidget(eWidget *root) +{ + m_root.remove(root); +} + void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible) { /* start with our clip region, clipped with the parent's */ diff --git a/lib/gui/ewidgetdesktop.h b/lib/gui/ewidgetdesktop.h index 197693f8..42e6b61e 100644 --- a/lib/gui/ewidgetdesktop.h +++ b/lib/gui/ewidgetdesktop.h @@ -16,6 +16,7 @@ public: eWidgetDesktop(eSize screen); ~eWidgetDesktop(); void addRootWidget(eWidget *root, int top); + void removeRootWidget(eWidget *root); void recalcClipRegions(); void invalidate(const gRegion ®ion); diff --git a/lib/gui/ewindow.cpp b/lib/gui/ewindow.cpp index 1afee2ee..630a8aa3 100644 --- a/lib/gui/ewindow.cpp +++ b/lib/gui/ewindow.cpp @@ -5,10 +5,18 @@ eWindow::eWindow(eWidgetDesktop *desktop): eWidget(0) { + setStyle(new eWindowStyleSimple()); + + /* we are the parent for the child window. */ + /* as we are in the constructor, this is thread safe. */ + m_child = this; m_child = new eWidget(this); desktop->addRootWidget(this, 0); - - m_style = new eWindowStyleSimple(); +} + +eWindow::~eWindow() +{ + getDesktop()->removeRootWidget(this); } void eWindow::setTitle(const std::string &string) @@ -25,18 +33,25 @@ int eWindow::event(int event, void *data, void *data2) { case evtWillChangeSize: { - const eSize &new_size = *static_cast<eSize*>(data); - eDebug("eWindow::evtWillChangeSize to %d %d", new_size.width(), new_size.height()); - if (m_style) - m_style->handleNewSize(this, new_size); + ePtr<eWindowStyle> style; + if (!getStyle(style)) + { + const eSize &new_size = *static_cast<eSize*>(data); + eDebug("eWindow::evtWillChangeSize to %d %d", new_size.width(), new_size.height()); + style->handleNewSize(this, new_size); + } break; } case evtPaint: { - gPainter &painter = *static_cast<gPainter*>(data2); - painter.setBackgroundColor(gColor(0x18)); - painter.clear(); - break; + ePtr<eWindowStyle> style; + if (!getStyle(style)) + { + gPainter &painter = *static_cast<gPainter*>(data2); + style->paintWindowDecoration(this, painter, m_title); + } else + eDebug("no style :("); + return 0; } default: break; diff --git a/lib/gui/ewindow.h b/lib/gui/ewindow.h index 671a0079..f5bcd51a 100644 --- a/lib/gui/ewindow.h +++ b/lib/gui/ewindow.h @@ -11,6 +11,7 @@ class eWindow: public eWidget friend class eWindowStyle; public: eWindow(eWidgetDesktop *desktop); + ~eWindow(); void setTitle(const std::string &string); eWidget *child() { return m_child; } protected: @@ -22,7 +23,6 @@ protected: private: std::string m_title; eWidget *m_child; - ePtr<eWindowStyle> m_style; }; #endif diff --git a/lib/gui/ewindowstyle.cpp b/lib/gui/ewindowstyle.cpp index 932a3102..778291c7 100644 --- a/lib/gui/ewindowstyle.cpp +++ b/lib/gui/ewindowstyle.cpp @@ -3,11 +3,23 @@ #include <lib/gui/ewindow.h> #include <lib/gui/ewindowstyle.h> + +eWindowStyle::~eWindowStyle() {} + DEFINE_REF(eWindowStyleSimple); eWindowStyleSimple::eWindowStyleSimple() { - m_border_left = m_border_right = m_border_top = m_border_bottom = 10; + m_border_left = m_border_right = m_border_bottom = 1; + m_border_top = 30; + + m_fnt = new gFont("Arial", 25); + + m_border_color_tl = gColor(0x14); + m_border_color_br = gColor(0x1c); + m_title_color_back = gColor(0x20); + m_title_color = gColor(0x2f); + m_background_color = gColor(0x18); } void eWindowStyleSimple::handleNewSize(eWindow *wnd, const eSize &size) @@ -21,3 +33,42 @@ void eWindowStyleSimple::handleNewSize(eWindow *wnd, const eSize &size) child->move(ePoint(m_border_left, m_border_top)); child->resize(eSize(size.width() - m_border_left - m_border_right, size.height() - m_border_top - m_border_bottom)); } + +void eWindowStyleSimple::paintWindowDecoration(eWindow *wnd, gPainter &painter, const std::string &title) +{ + painter.setBackgroundColor(m_title_color_back); + painter.setForegroundColor(m_title_color); + painter.clear(); + painter.setFont(m_fnt); + painter.renderText(eRect(1, 1, wnd->size().width() - 2, m_border_top - 2), title); + + eRect frame(ePoint(0, 0), wnd->size()); + painter.setForegroundColor(m_border_color_tl); + painter.line(frame.topLeft1(), frame.topRight1()); + painter.line(frame.topRight1(), frame.bottomRight1()); + painter.setForegroundColor(m_border_color_br); + painter.line(frame.bottomRight1(), frame.bottomLeft1()); + painter.line(frame.bottomLeft1(), frame.topLeft1()); +} + +void eWindowStyleSimple::paintBackground(gPainter &painter, const ePoint &offset, const eSize &size) +{ + eDebug("eWindowStyleSimple::paintBackground"); + painter.setBackgroundColor(m_background_color); + painter.clear(); +} + +void eWindowStyleSimple::setForegroundStyle(gPainter &painter) +{ + painter.setForegroundColor(gColor(0x1F)); +} + +void eWindowStyleSimple::drawButtonFrame(gPainter &painter, const eRect &frame) +{ + painter.setForegroundColor(m_border_color_tl); + painter.line(frame.topLeft1(), frame.topRight1()); + painter.line(frame.topRight1(), frame.bottomRight1()); + painter.setForegroundColor(m_border_color_br); + painter.line(frame.bottomRight1(), frame.bottomLeft1()); + painter.line(frame.bottomLeft1(), frame.topLeft1()); +} diff --git a/lib/gui/ewindowstyle.h b/lib/gui/ewindowstyle.h index 02f155af..d5da5a34 100644 --- a/lib/gui/ewindowstyle.h +++ b/lib/gui/ewindowstyle.h @@ -3,6 +3,7 @@ class eWindow; class eSize; +class gFont; #include <lib/base/object.h> @@ -10,15 +11,28 @@ class eWindowStyle: public iObject { public: virtual void handleNewSize(eWindow *wnd, const eSize &size) = 0; + virtual void paintWindowDecoration(eWindow *wnd, gPainter &painter, const std::string &title) = 0; + virtual void paintBackground(gPainter &painter, const ePoint &offset, const eSize &size) = 0; + virtual void setForegroundStyle(gPainter &painter) = 0; + virtual void drawButtonFrame(gPainter &painter, const eRect &frame) = 0; + virtual ~eWindowStyle() = 0; }; class eWindowStyleSimple: public eWindowStyle { DECLARE_REF; +private: + ePtr<gFont> m_fnt; + gColor m_border_color_tl, m_border_color_br, m_title_color_back, m_title_color, m_background_color; + + int m_border_top, m_border_left, m_border_right, m_border_bottom; public: eWindowStyleSimple(); void handleNewSize(eWindow *wnd, const eSize &size); - int m_border_top, m_border_left, m_border_right, m_border_bottom; + void paintWindowDecoration(eWindow *wnd, gPainter &painter, const std::string &title); + void paintBackground(gPainter &painter, const ePoint &offset, const eSize &size); + void setForegroundStyle(gPainter &painter); + void drawButtonFrame(gPainter &painter, const eRect &frame); }; #endif diff --git a/lib/network/Makefile.am b/lib/network/Makefile.am index f5efef9a..f9677a10 100644 --- a/lib/network/Makefile.am +++ b/lib/network/Makefile.am @@ -4,6 +4,6 @@ INCLUDES = \ noinst_LIBRARIES = libenigma_network.a libenigma_network_a_SOURCES = \ - http_dyn.cpp http_file.cpp httpd.cpp serversocket.cpp socket.cpp + httpd.cpp http_dyn.cpp http_file.cpp http.cpp serversocket.cpp socket.cpp # xmlrpc.cpp diff --git a/lib/network/http.cpp b/lib/network/http.cpp new file mode 100644 index 00000000..dc98a0bd --- /dev/null +++ b/lib/network/http.cpp @@ -0,0 +1,33 @@ +#include <lib/base/init_num.h> +#include <lib/base/init.h> +#include <lib/network/http.h> + +eHTTPServer *eHTTPServer::m_instance; + +RESULT eHTTPServer::getDynResolver(eHTTPDynPathResolverPtr &ptr) +{ + ptr = m_dyn; + if (!m_dyn) + return -1; + return 0; +} + +RESULT eHTTPServer::getFileResolver(eHTTPFilePathResolverPtr &ptr) +{ + ptr = m_file; + if (!m_file) + return -1; + return 0; +} + +eHTTPServer::eHTTPServer(): m_httpd(8080, eApp) +{ + m_instance = this; + m_dyn = new eHTTPDynPathResolver(); + m_file = new eHTTPFilePathResolver(); + + m_httpd.addResolver(m_dyn); + m_httpd.addResolver(m_file); +} + +eAutoInitP0<eHTTPServer> init_eHTTPServer(eAutoInitNumbers::network, "main http server"); diff --git a/lib/network/http.h b/lib/network/http.h new file mode 100644 index 00000000..fa2a4fba --- /dev/null +++ b/lib/network/http.h @@ -0,0 +1,28 @@ +#ifndef __http_h +#define __http_h + +#include <lib/network/httpd.h> +#include <lib/network/http_file.h> +#include <lib/network/http_dyn.h> + +class eHTTPDynPathResolver; +class eHTTPFilePathResolver; + +typedef ePtr<eHTTPDynPathResolver> eHTTPDynPathResolverPtr; +typedef ePtr<eHTTPFilePathResolver> eHTTPFilePathResolverPtr; + +class eHTTPServer +{ + eHTTPD m_httpd; + static eHTTPServer *m_instance; + eHTTPDynPathResolverPtr m_dyn; + eHTTPFilePathResolverPtr m_file; +public: + RESULT getDynResolver(eHTTPDynPathResolverPtr &ptr); + RESULT getFileResolver(eHTTPFilePathResolverPtr &ptr); + + eHTTPServer(); + static eHTTPServer *getInstance() { return m_instance; } +}; + +#endif diff --git a/lib/network/http_dyn.cpp b/lib/network/http_dyn.cpp index eb94d462..c3a49048 100644 --- a/lib/network/http_dyn.cpp +++ b/lib/network/http_dyn.cpp @@ -1,5 +1,6 @@ #include <lib/network/http_dyn.h> +DEFINE_REF(eHTTPDyn); eHTTPDyn::eHTTPDyn(eHTTPConnection *c, std::string result): eHTTPDataSource(c), result(result) { wptr=0; @@ -29,9 +30,11 @@ int eHTTPDyn::doWrite(int hm) return (size > wptr) ? 1 : -1; } +DEFINE_REF(eHTTPDynPathResolver); +DEFINE_REF(eHTTPDynPathResolver::eHTTPDynEntry); + eHTTPDynPathResolver::eHTTPDynPathResolver() { -#warning autodelete removed } void eHTTPDynPathResolver::addDyn(std::string request, std::string path, std::string (*function)(std::string, std::string, std::string, eHTTPConnection*)) @@ -39,7 +42,7 @@ void eHTTPDynPathResolver::addDyn(std::string request, std::string path, std::st dyn.push_back(new eHTTPDynEntry(request, path, function)); } -eHTTPDataSource *eHTTPDynPathResolver::getDataSource(std::string request, std::string path, eHTTPConnection *conn) +RESULT eHTTPDynPathResolver::getDataSource(eHTTPDataSourcePtr &ptr, std::string request, std::string path, eHTTPConnection *conn) { std::string p, opt; if (path.find('?')!=std::string::npos) @@ -51,16 +54,21 @@ eHTTPDataSource *eHTTPDynPathResolver::getDataSource(std::string request, std::s p=path; opt=""; } - for (ePtrList<eHTTPDynEntry>::iterator i(dyn); i != dyn.end(); ++i) + for (eSmartPtrList<eHTTPDynEntry>::iterator i(dyn); i != dyn.end(); ++i) if ((i->path==p) && (i->request==request)) { conn->code=-1; std::string s=i->function(request, path, opt, conn); if (!s.empty()) - return new eHTTPDyn(conn, s); + { + ptr = new eHTTPDyn(conn, s); + return 0; + } - return new eHTTPError(conn, 500); + ptr = new eHTTPError(conn, 500); + return 0; } - return 0; + ptr = 0; + return -1; } diff --git a/lib/network/http_dyn.h b/lib/network/http_dyn.h index d714403b..61116409 100644 --- a/lib/network/http_dyn.h +++ b/lib/network/http_dyn.h @@ -5,6 +5,8 @@ class eHTTPDyn: public eHTTPDataSource { + DECLARE_REF; +private: std::string result; int wptr, size; public: @@ -13,10 +15,14 @@ public: int doWrite(int); }; -class eHTTPDynPathResolver: public eHTTPPathResolver +class eHTTPDynPathResolver: public iHTTPPathResolver { + DECLARE_REF; +private: struct eHTTPDynEntry { + DECLARE_REF; + public: std::string request, path; std::string (*function)(std::string request, std::string path, std::string opt, eHTTPConnection *content); @@ -24,11 +30,11 @@ class eHTTPDynPathResolver: public eHTTPPathResolver { } }; - ePtrList<eHTTPDynEntry> dyn; + eSmartPtrList<eHTTPDynEntry> dyn; public: void addDyn(std::string request, std::string path, std::string (*function)(std::string, std::string, std::string, eHTTPConnection *conn)); eHTTPDynPathResolver(); - eHTTPDataSource *getDataSource(std::string request, std::string path, eHTTPConnection *conn); + RESULT getDataSource(eHTTPDataSourcePtr &ptr, std::string request, std::string path, eHTTPConnection *conn); }; #endif diff --git a/lib/network/http_file.cpp b/lib/network/http_file.cpp index 2b47d63c..6c6abc83 100644 --- a/lib/network/http_file.cpp +++ b/lib/network/http_file.cpp @@ -6,6 +6,8 @@ #include <shadow.h> #include <pwd.h> +DEFINE_REF(eHTTPFile); + eHTTPFile::eHTTPFile(eHTTPConnection *c, int _fd, int method, const char *mime): eHTTPDataSource(c), method(method) { fd=_fd; @@ -58,7 +60,6 @@ eHTTPFile::~eHTTPFile() eHTTPFilePathResolver::eHTTPFilePathResolver() { -#warning autodelete removed } @@ -138,7 +139,9 @@ static int checkAuth(const std::string cauth) return 0; } -eHTTPDataSource *eHTTPFilePathResolver::getDataSource(std::string request, std::string path, eHTTPConnection *conn) +DEFINE_REF(eHTTPFilePathResolver); + +RESULT eHTTPFilePathResolver::getDataSource(eHTTPDataSourcePtr &ptr, std::string request, std::string path, eHTTPConnection *conn) { int method; eDebug("request = %s, path = %s", request.c_str(), path.c_str()); @@ -147,9 +150,15 @@ eHTTPDataSource *eHTTPFilePathResolver::getDataSource(std::string request, std:: else if (request == "PUT") method=eHTTPFile::methodPUT; else - return new eHTTPError(conn, 405); // method not allowed + { + ptr = new eHTTPError(conn, 405); // method not allowed + return 0; + } if (path.find("../")!=std::string::npos) // evil hax0r - return new eHTTPError(conn, 403); + { + ptr = new eHTTPError(conn, 403); + return 0; + } if (path[0] != '/') // prepend '/' path.insert(0,"/"); if (path[path.length()-1]=='/') @@ -171,7 +180,8 @@ eHTTPDataSource *eHTTPFilePathResolver::getDataSource(std::string request, std:: if ((i == conn->remote_header.end()) || checkAuth(i->second)) { conn->local_header["WWW-Authenticate"]="Basic realm=\"dreambox\""; - return new eHTTPError(conn, 401); // auth req'ed + ptr = new eHTTPError(conn, 401); // auth req'ed + return 0; } } @@ -215,7 +225,10 @@ eHTTPDataSource *eHTTPFilePathResolver::getDataSource(std::string request, std:: break; } } - return data; + if (!data) + return -1; + ptr = data; + return 0; } void eHTTPFilePathResolver::addTranslation(std::string path, std::string root, int authorized) diff --git a/lib/network/http_file.h b/lib/network/http_file.h index 109dc07e..6feb562d 100644 --- a/lib/network/http_file.h +++ b/lib/network/http_file.h @@ -5,6 +5,8 @@ class eHTTPFile: public eHTTPDataSource { + DECLARE_REF; +private: int fd, size; const char *mime; int method; @@ -16,8 +18,10 @@ public: void haveData(void *data, int len); }; -class eHTTPFilePathResolver: public eHTTPPathResolver +class eHTTPFilePathResolver: public iHTTPPathResolver { + DECLARE_REF; +public: struct eHTTPFilePath { std::string path; @@ -30,7 +34,7 @@ class eHTTPFilePathResolver: public eHTTPPathResolver ePtrList<eHTTPFilePath> translate; public: eHTTPFilePathResolver(); - eHTTPDataSource *getDataSource(std::string request, std::string path, eHTTPConnection *conn); + RESULT getDataSource(eHTTPDataSourcePtr &ptr, std::string request, std::string path, eHTTPConnection *conn); void addTranslation(std::string path, std::string root, int auth); }; diff --git a/lib/network/httpd.cpp b/lib/network/httpd.cpp index f706ccf8..c89ad7e3 100644 --- a/lib/network/httpd.cpp +++ b/lib/network/httpd.cpp @@ -2,12 +2,16 @@ #include <lib/network/httpd.h> #include <sys/socket.h> +#include <lib/base/smartptr.h> #include <lib/base/estring.h> #include <error.h> #include <errno.h> #include <time.h> #include <ctype.h> +#include <lib/network/http_dyn.h> +#include <lib/network/http_file.h> + eHTTPDataSource::eHTTPDataSource(eHTTPConnection *c): connection(c) { } @@ -25,6 +29,8 @@ int eHTTPDataSource::doWrite(int) return 0; } +DEFINE_REF(eHTTPError); + eHTTPError::eHTTPError(eHTTPConnection *c, int errcode): eHTTPDataSource(c), errcode(errcode) { std::string error="unknown error"; @@ -71,6 +77,7 @@ eHTTPConnection::eHTTPConnection(int socket, int issocket, eHTTPD *parent, int p void eHTTPConnection::destruct() { + eDebug("destruct, this %p!", this); gotHangup(); delete this; } @@ -108,11 +115,7 @@ void eHTTPConnection::gotHangup() { if (data && remotestate == stateData) data->haveData(0, 0); - if (data) - { - delete data; - data=0; - } + data = 0; transferDone(0); localstate=stateWait; @@ -345,10 +348,8 @@ int eHTTPConnection::processLocalState() #endif if (persistent) { - if (data) - delete data; - data=0; - localstate=stateWait; + data = 0; + localstate = stateWait; } else close(); // bye, bye, remote return 1; @@ -401,8 +402,7 @@ int eHTTPConnection::processRemoteState() del[1]=line.find(" ", del[0]+1); if (del[0]==-1) { - if (data) - delete data; + data = 0; eDebug("request buggy"); httpversion="HTTP/1.0"; data=new eHTTPError(this, 400); @@ -490,20 +490,17 @@ int eHTTPConnection::processRemoteState() if (parent) { - for (ePtrList<eHTTPPathResolver>::iterator i(parent->resolver); i != parent->resolver.end(); ++i) - { - if ((data=i->getDataSource(request, requestpath, this))) + for (eSmartPtrList<iHTTPPathResolver>::iterator i(parent->resolver); i != parent->resolver.end(); ++i) + if (!(i->getDataSource(data, request, requestpath, this))) break; - } localstate=stateResponse; // can be overridden by dataSource } else data=createDataSource(this); if (!data) { - if (data) - delete data; - data=new eHTTPError(this, 404); + data = 0; + data = new eHTTPError(this, 404); } if (content_length || // if content-length is set, we have content @@ -600,11 +597,7 @@ int eHTTPConnection::getLine(std::string &line) void eHTTPConnection::gotError(int err) { - if (data) - { - delete data; - data=0; - } + data = 0; transferDone(err); delete this; } @@ -615,15 +608,13 @@ eHTTPD::eHTTPD(int port, eMainloop *ml): eServerSocket(port, ml), ml(ml) eDebug("[NET] httpd server FAILED on port %d", port); else eDebug("[NET] httpd server started on port %d", port); -#warning resolver autodelete removed } eHTTPConnection::~eHTTPConnection() { + eDebug("HTTP connection destruct"); if ((!persistent) && (state()!=Idle)) eWarning("~eHTTPConnection, status still %d", state()); - if (data) - delete data; } void eHTTPD::newConnection(int socket) diff --git a/lib/network/httpd.h b/lib/network/httpd.h index 61fe2c75..30c3c032 100644 --- a/lib/network/httpd.h +++ b/lib/network/httpd.h @@ -4,6 +4,7 @@ #include <asm/types.h> #include <map> +#include <lib/base/object.h> #include <lib/base/eptrlist.h> #include <lib/base/ebase.h> #include <string> @@ -15,14 +16,17 @@ class eHTTPConnection; class eHTTPDataSource; class eHTTPD; -class eHTTPPathResolver +class eHTTPDataSource; +typedef ePtr<eHTTPDataSource> eHTTPDataSourcePtr; + +class iHTTPPathResolver: public iObject { public: - virtual ~eHTTPPathResolver() {}; - virtual eHTTPDataSource *getDataSource(std::string request, std::string path, eHTTPConnection *conn)=0; + virtual ~iHTTPPathResolver() {}; + virtual RESULT getDataSource(eHTTPDataSourcePtr &source, std::string request, std::string path, eHTTPConnection *conn)=0; }; -class eHTTPDataSource +class eHTTPDataSource: public iObject { protected: eHTTPConnection *connection; @@ -33,8 +37,12 @@ public: virtual int doWrite(int bytes); // number of written bytes, -1 for "no more" }; +typedef ePtr<eHTTPDataSource> eHTTPDataSourcePtr; + class eHTTPError: public eHTTPDataSource { + DECLARE_REF; +private: int errcode; public: eHTTPError(eHTTPConnection *c, int errcode); @@ -53,7 +61,7 @@ class eHTTPConnection: public eSocket int processRemoteState(); void writeString(const char *data); - eHTTPDataSource *data; + eHTTPDataSourcePtr data; eHTTPD *parent; int buffersize; @@ -110,14 +118,14 @@ public: class eHTTPD: public eServerSocket { friend class eHTTPConnection; - ePtrList<eHTTPPathResolver> resolver; + eSmartPtrList<iHTTPPathResolver> resolver; eMainloop *ml; public: eHTTPD(int port, eMainloop *ml); void newConnection(int socket); - void addResolver(eHTTPPathResolver *r) { resolver.push_back(r); } - void removeResolver(eHTTPPathResolver *r) { resolver.remove(r); } + void addResolver(iHTTPPathResolver *r) { resolver.push_back(r); } + void removeResolver(iHTTPPathResolver *r) { resolver.remove(r); } }; #endif diff --git a/lib/network/socket.cpp b/lib/network/socket.cpp index 628a128b..b2ab7437 100644 --- a/lib/network/socket.cpp +++ b/lib/network/socket.cpp @@ -269,6 +269,7 @@ int eSocket::connectToHost(std::string hostname, int port) eSocket::eSocket(eMainloop *ml): readbuffer(32768), writebuffer(32768), rsn(0) { + ASSERT(ml); int s=socket(AF_INET, SOCK_STREAM, 0); #if 0 eDebug("[SOCKET]: initalized socket %d", socketdesc); diff --git a/lib/network/xmlrpc.h b/lib/network/xmlrpc.h index 5347dbfe..05fd3cca 100644 --- a/lib/network/xmlrpc.h +++ b/lib/network/xmlrpc.h @@ -69,8 +69,9 @@ void xmlrpc_addMethod(std::string methodName, int (*)(std::vector<eXMLRPCVariant void xmlrpc_fault(ePtrList<eXMLRPCVariant> &res, int faultCode, std::string faultString); int xmlrpc_checkArgs(std::string args, std::vector<eXMLRPCVariant>&, ePtrList<eXMLRPCVariant> &res); -class eHTTPXMLRPCResolver: public eHTTPPathResolver +class eHTTPXMLRPCResolver: public iHTTPPathResolver { + DECLARE_REF; public: eHTTPXMLRPCResolver(); eHTTPDataSource *getDataSource(std::string request, std::string path, eHTTPConnection *conn); diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 67244f10..c9dc42e4 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -6,6 +6,13 @@ #include <lib/base/econfig.h> #include <lib/service/iservice.h> #include <lib/service/service.h> + +#include <lib/gui/ewidget.h> +#include <lib/gui/elabel.h> +#include <lib/gui/ebutton.h> +#include <lib/gui/ewindow.h> +#include <lib/gui/ewidgetdesktop.h> +#include <lib/gui/eslider.h> %} #define DEBUG @@ -17,7 +24,15 @@ %include <lib/service/iservice.h> %include <lib/service/service.h> %template(eServiceCenterPtr) ePtr<eServiceCenter>; -%template(iPlayableServicePtr) ePtr<iPlayableService>; -%template(iPauseableServicePtr) ePtr<iPauseableService>; -%template(iRecordableServicePtr) ePtr<iRecordableService>; -%template(iListableServicePtr) ePtr<iListableService>; + +%include <lib/gdi/epoint.h> +%include <lib/gdi/erect.h> +%include <lib/gdi/esize.h> +%include <lib/gdi/region.h> +%include <lib/gui/ewidget.h> +%include <lib/gui/elabel.h> +%include <lib/gui/ebutton.h> +%include <lib/gui/ewindow.h> +%include <lib/gui/eslider.h> +%include <lib/gui/ewidgetdesktop.h> + diff --git a/lib/service/iservice.h b/lib/service/iservice.h index a6369574..766d850e 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -6,6 +6,14 @@ #include <connection.h> #include <list> +#ifdef SWIG +#define TEMPLATE_TYPEDEF(x, y) \ +%template(y) x; \ +typedef x y +#else +#define TEMPLATE_TYPEDEF(x, y) typedef x y +#endif + class eServiceReference { public: @@ -167,7 +175,7 @@ public: virtual RESULT getIServiceInformation(ePtr<iServiceInformation> &ptr)=0; }; -typedef ePtr<iPlayableService> iPlayableServicePtr; +TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr); class iRecordableService: public iObject { @@ -178,13 +186,16 @@ public: typedef ePtr<iRecordableService> iRecordableServicePtr; +// TEMPLATE_TYPEDEF(std::list<eServiceReference>, eServiceReferenceList); +typedef std::list<eServiceReference> eServiceReferenceList; + class iListableService: public iObject { public: virtual RESULT getContent(std::list<eServiceReference> &list)=0; }; -typedef ePtr<iListableService> iListableServicePtr; +TEMPLATE_TYPEDEF(ePtr<iListableService>, iListableServicePtr); class iServiceHandler: public iObject { |
