- add more python stuff
authorFelix Domke <tmbinc@elitedvb.net>
Sun, 9 Jan 2005 16:29:34 +0000 (16:29 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Sun, 9 Jan 2005 16:29:34 +0000 (16:29 +0000)
 - fix some gui/gdi
 - add eslider
 - improve windowstyle

41 files changed:
components.py [new file with mode: 0644]
lib/base/init_num.h
lib/gdi/epoint.h
lib/gdi/erect.cpp
lib/gdi/erect.h
lib/gdi/esize.h
lib/gdi/font.cpp
lib/gdi/grc.cpp
lib/gdi/grc.h
lib/gdi/region.cpp
lib/gui/Makefile.am
lib/gui/ebutton.cpp
lib/gui/ebutton.h
lib/gui/elabel.cpp
lib/gui/eslider.cpp [new file with mode: 0644]
lib/gui/eslider.h [new file with mode: 0644]
lib/gui/ewidget.cpp
lib/gui/ewidget.h
lib/gui/ewidgetdesktop.cpp
lib/gui/ewidgetdesktop.h
lib/gui/ewindow.cpp
lib/gui/ewindow.h
lib/gui/ewindowstyle.cpp
lib/gui/ewindowstyle.h
lib/network/Makefile.am
lib/network/http.cpp [new file with mode: 0644]
lib/network/http.h [new file with mode: 0644]
lib/network/http_dyn.cpp
lib/network/http_dyn.h
lib/network/http_file.cpp
lib/network/http_file.h
lib/network/httpd.cpp
lib/network/httpd.h
lib/network/socket.cpp
lib/network/xmlrpc.h
lib/python/enigma_python.i
lib/service/iservice.h
main/enigma.cpp
mytest.py
screens.py [new file with mode: 0644]
skin.py [new file with mode: 0644]

diff --git a/components.py b/components.py
new file mode 100644 (file)
index 0000000..e66e43b
--- /dev/null
@@ -0,0 +1,149 @@
+from enigma import *
+import time
+
+# some helper classes first:
+class HTMLComponent:
+       def produceHTML(self):
+               return ""
+               
+class HTMLSkin:
+       order = ()
+
+       def __init__(self, order):
+               self.order = order
+
+       def produceHTML(self):
+               res = "<html>\n"
+               for name in self.order:
+                       res += self[name].produceHTML()
+               res += "</html>\n";
+               return res
+
+class GUISkin:
+       data = { }
+       def createGUIScreen(self, parent):
+               for (name, val) in self.items():
+                       self.data[name] = { }
+                       val.GUIcreate(self.data[name], parent, None)
+
+class GUIComponent:
+       """ GUI component """
+
+       def __init__(self):
+               self.notifier = [ ]
+       
+       def GUIcreate(self, priv, parent, skindata):
+               i = self.GUIcreateInstance(self, parent, skindata)
+               priv["instance"] = i
+               print str(self) + " notifier list before " + str(self.notifier)
+               self.notifier.append(i)
+               print str(self) + " notifier list now " + str(self.notifier)
+               if self.notifierAdded:
+                       self.notifierAdded(i)
+
+class VariableText:
+       """VariableText can be used for components which have a variable text, based on any widget with setText call"""
+       
+       def __init__(self):
+               self.message = ""
+       
+       def notifierAdded(self, notifier):
+               notifier.setText(self.message)
+
+       def setText(self, text):
+               if self.message != text:
+                       self.message = text
+                       print self.notifier
+                       for x in self.notifier:
+                               x.setText(self.message)
+
+       def getText(self):
+               return self.message
+
+class VariableValue:
+       """VariableValue can be used for components which have a variable value (like eSlider), based on any widget with setValue call"""
+       
+       def __init__(self):
+               self.value = 0
+       
+       def notifierAdded(self, notifier):
+               notifier.setValue(self.value)
+
+       def setValue(self, value):
+               if self.value != value:
+                       self.value = value
+                       for x in self.notifier:
+                               x.setValue(self.value)
+
+       def getValue(self):
+               return self.value
+
+# now some "real" components:
+
+class Clock(HTMLComponent, GUIComponent, VariableText):
+       def __init__(self):
+               VariableText.__init__(self)
+               GUIComponent.__init__(self)
+               self.doClock()
+
+# "funktionalitaet"    
+       def doClock(self):
+               self.setText("clock: " + time.asctime())
+
+# realisierung als GUI
+       def GUIcreateInstance(self, priv, parent, skindata):
+               g = eLabel(parent)
+               return g
+
+# ...und als HTML:
+       def produceHTML(self):
+               return self.getText()
+
+class Button(HTMLComponent, GUIComponent, VariableText):
+       onClick = {}
+       
+       def __init__(self, text=""):
+               GUIComponent.__init__(self)
+               VariableText.__init__(self)
+               self.setText(text)
+       
+       def click(self):
+               for x in self.onClick:
+                       x()
+
+# html:        
+       def produceHTML(self):
+               return "<input type=\"submit\" text=\"" + self.getText() + "\">\n"
+
+# GUI:
+       def GUIcreateInstance(self, priv, parent, skindata):
+               g = eButton(parent)
+#              g.clicked = [ self.click ]
+               return g
+
+class Header(HTMLComponent, GUIComponent, VariableText):
+
+       def __init__(self, message):
+               GUIComponent.__init__(self)
+               VariableText.__init__(self)
+               self.setText(message)
+       
+       def produceHTML(self):
+               return "<h2>" + self.getText() + "</h2>\n"
+
+       def GUIcreateInstance(self, priv, parent, skindata):
+               g = eLabel(parent)
+               g.setText(self.message)
+               return g
+
+class VolumeBar(HTMLComponent, GUIComponent, VariableValue):
+       
+       def __init__(self):
+               GUIComponent.__init__(self)
+               VariableValue.__init__(self)
+
+       def GUIcreateInstance(self, priv, parent, skindata):
+               g = eSlider(parent)
+               g.setRange(0, 100)
+               return g
+
index a9da0624ad267eddb0ed6f6d26c60b195a1272c1..a9431c6b7e0a6a975f97d467e0286bade651bda4 100644 (file)
@@ -8,6 +8,7 @@ namespace eAutoInitNumbers
        {
                configuration=0,
                lowlevel=configuration+increment,
+               network=lowlevel,
                graphic=lowlevel+increment,
                skin=graphic+increment,
                rc=skin+increment,
index fc5f983670e253c850f7d25e0b4469137889f4d2..d7cdf399876dbda8bceb3ffcc67d20ef33ed7271 100644 (file)
@@ -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 );
@@ -55,25 +55,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); }
 
index a38787977922feb5e94898ee60ac97cac0b6069d..43cefc533fd5dca38fdf8dc9880b13367cc47e34 100644 (file)
@@ -1,5 +1,4 @@
 #include <lib/gdi/erect.h>
-#include <iostream>
 
 /*****************************************************************************
   eRect member functions
index a67d0fb9d57bbc392e59807d97c89436c55a16bd..65fd8d7112655a34ed21b12f4d53ccb87b20c156 100644 (file)
@@ -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); }
 
index d4bd4afb0d6bb1d4c5a6c0f24f490f1b7759eeaa..de0a6ecb5c5bf7112f75b05b0538d3f4cf07da8d 100644 (file)
@@ -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)
 
@@ -52,26 +50,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
  *****************************************************************************/
index ee228576bfb9852bfb495159a46919c35199f44e..f7c62209c3d186d5063482bb1cbffda5696b99e2 100644 (file)
@@ -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;
index 4597034f4ee02218778f299a8fd961aae732603d..cb2a6de99006bff34f2755c9ef60741df3e1582c 100644 (file)
@@ -164,6 +164,17 @@ void gPainter::fill(const eRect &area)
        m_rc->submit(o);
 }
 
+void gPainter::fill(const gRegion &region)
+{
+       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;
index a02068aea2c6cb0f631f14ee9b0c3fc72be69180..d6a3cd70dea21fe3f9279235006f1c80f6cc1ebc 100644 (file)
@@ -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();
        
index f79b403fee784fb7a469fe3e754b908818562960..d75221fe882f6e2794be6555e6c94a29c2eaad8f 100644 (file)
@@ -325,6 +325,8 @@ void gRegion::regionOp(const gRegion &reg1, const gRegion &reg2, 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)
index a686e1cafef8864387bb7c1cce44ac9a522fb033..1b175c9a64da7fdd2813980d68e10cf6c0bb11bb 100644 (file)
@@ -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 
 
index 5c136abd18ae0709557a434dabd97eaee0ea1388..effcf1f66c329601952c7fed539e9ab3907d5e42 100644 (file)
@@ -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;
        }
index 31c9cb3c296c6be8e4c13fd25494fe4dc24cec64..25087077b58fec9aa3ad00478e8663a7442ceda5 100644 (file)
@@ -7,7 +7,7 @@ class eButton: public eLabel
 {
 public:
        eButton(eWidget *parent);
-       Signal0<void> selected;
+//     Signal0<void> selected;
 
        void push();
 protected:
index f133b66142d325e34d5c8a798acf5bf1cf9ecfba..f9dcf31b378a4a94dd609f300d0c60ec6440d58b 100644 (file)
@@ -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 (file)
index 0000000..20b3ab4
--- /dev/null
@@ -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 (file)
index 0000000..5b7b59f
--- /dev/null
@@ -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
index 89fbfe95f59dfa3d79e8a18f863dd9aae83c54c6..3ebac357360bab13b303e9d8fc8c4bb2fca54175 100644 (file)
@@ -3,34 +3,68 @@
 
 extern void dumpRegion(const gRegion &region);
 
-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 &region)
 {
-       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, &region, &painter);
+       if (!region.empty())
+       {
+               painter.resetClip(region);
+               event(evtPaint, &region, &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:
index a551b8a3891d438859846c9af4ceae6d50ba7098..fa8cd8cac1b37d163f93f74541c5943c920713c3 100644 (file)
@@ -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 &region = 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 &region);
+       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
index 10c92b71b6d94176db9b69d0dc32c035a43d0b7c..ff91368081d1b5e234702f1b1da463081a1946cd 100644 (file)
@@ -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 */
index 197693f8bb92e53166c5a0d0cc880450d8bd4c6a..42e6b61e6fa59572e7b7a94b678e1c27a107c927 100644 (file)
@@ -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 &region);
index 1afee2ee88d5ce61d611bbb15794e351328ce794..630a8aa364c0c8141da2472ff50263536273b1fe 100644 (file)
@@ -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;
index 671a00791db0b5e1883bc332d51c1b91fe664342..f5bcd51af72e3930bf394032b8890eafd4c4cdd2 100644 (file)
@@ -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
index 932a31022c45dab5a37be7c1bf85a5caf834ba30..778291c7a351651c06302dadb46bbc89c943f5de 100644 (file)
@@ -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());
+}
index 02f155af7a2bb3adc20fd8aa40d8741024e31e6e..d5da5a34e324342b7731c1bd07bb89349baef658 100644 (file)
@@ -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
index f5efef9a25b0e0515a487498736490021c0ab3b4..f9677a10a02bb3d8fb0ff519787592fafc00b30d 100644 (file)
@@ -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 (file)
index 0000000..dc98a0b
--- /dev/null
@@ -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 (file)
index 0000000..fa2a4fb
--- /dev/null
@@ -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
index eb94d46297e8c34965d6168ea31f7eb3f0509a75..c3a49048febf3bcd77c2d09bd95915ee1e9c8700 100644 (file)
@@ -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;
 }
index d714403bc4826ff8d4dd16c517fad124b528c0ce..6111640963e07acab53fe83ec0f650d6fb29a3ee 100644 (file)
@@ -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
index 2b47d63cc1d9297293cbb804057bf075e58bf34b..6c6abc83a076d0cba3f604f3d0d3ceb48fa4d010 100644 (file)
@@ -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)
index 109dc07e6487d0b7085accbe38dbfb595f645002..6feb562dc239ead509fa30e25ccd425063e72ffa 100644 (file)
@@ -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);
 };
 
index f706ccf82646c7327a536fe051baf0e7cff0947b..c89ad7e3165d71c55c8230716715bef7ef7edd35 100644 (file)
@@ -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)
index 61fe2c75eb8e1463a9a59a9bdad36099b3a3424b..30c3c0324d7e27197bb7c292c9e209f368de05ad 100644 (file)
@@ -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
index 628a128b075146785e5a7c57424c4f26a57d68c8..b2ab7437642568a520391f7ae0846cd766471d97 100644 (file)
@@ -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);
index 5347dbfe56cfd0913aea1637a667d9e40e246fc0..05fd3cca32689853e90a793e12ef12274ec31731 100644 (file)
@@ -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);
index 67244f1075b296884852dd2bcc2fdf4f23b94e25..c9dc42e42dde71b7aaf1aba91b522d7a0bc72e01 100644 (file)
@@ -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
 %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>
+
index a636957474bdacabf62280ead832483503917ffa..766d850eb748d3607b7d10c71e00ad00b7ff4ef6 100644 (file)
@@ -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
 {
index 81391c323bc6ba21af5a91ff66d375434d87d44c..d350f4453530a922de147032f81fa623cbb1a599 100644 (file)
@@ -14,6 +14,7 @@
 #include <lib/gui/ewidget.h>
 #include <lib/gui/ewidgetdesktop.h>
 #include <lib/gui/elabel.h>
+#include <lib/gui/ebutton.h>
 
 #include <lib/gui/ewindow.h>
 
@@ -27,6 +28,11 @@ void object_dump()
        printf("%d items left\n", object_total_remaining);
 }
 #endif
+using namespace std;
+       void print(const string &str, const char *c)
+       {
+               printf("%s (%s)\n", str.c_str(), c);
+       }
 
 void dumpRegion(const gRegion &region)
 {
@@ -47,20 +53,31 @@ void dumpRegion(const gRegion &region)
        }
 }
 
-int main()
+
+class eMain: public eApplication, public Object
+{
+       eInit init;
+public:
+       eMain()
+       {
+               init.setRunlevel(eAutoInitNumbers::main);
+       }
+};
+
+eWidgetDesktop *wdsk;
+
+int main(int argc, char **argv)
 {
 #ifdef OBJECT_DEBUG
        atexit(object_dump);
 #endif
-       eInit init;
-       
-       init.setRunlevel(eAutoInitNumbers::main);
 
-               // gui stuff
-#if 0
+
+#if 1
+       eMain main;
+
        ePtr<gFBDC> my_dc;
        gFBDC::getInstance(my_dc);
-#if 1
 
        gPainter p(my_dc);
        
@@ -71,65 +88,38 @@ int main()
        pal[3] = 0x00ff00;
        
        for (int a=0; a<0x10; ++a)
-               pal[a | 0x10] = (0x111111 * a) | 0xFF;
+               pal[a | 0x10] = 0x111111 * a;
+       for (int a=0; a<0x10; ++a)
+               pal[a | 0x20] = (0x111100 * a) | 0xFF;
+       for (int a=0; a<0x10; ++a)
+               pal[a | 0x30] = (0x110011 * a) | 0xFF00;
+       for (int a=0; a<0x10; ++a)
+               pal[a | 0x40] = (0x001111 * a) | 0xFF0000;
        p.setPalette(pal, 0, 256);
 
        fontRenderClass::getInstance()->AddFont("/dbox2/cdkroot/share/fonts/arial.ttf", "Arial", 100);
 
-#if 0
-       p.resetClip(gRegion(eRect(0, 0, 720, 576)));
-       
-        
-       gRegion c;
-       eDebug("0");
-       int i;
-       
-       c |= eRect(0, 20, 100, 10);
-       c |= eRect(0, 50, 100, 10);
-       c |= eRect(10, 10, 80, 100);
-       
-       c -= eRect(20, 20, 40, 40);
-       
-       p.setForegroundColor(gColor(3));
-       p.fill(eRect(0, 0, 100, 100));
-       p.fill(eRect(200, 0, 100, 100));
-       
-       for (int a=0; a<c.rects.size(); ++a)
-               eDebug("%d %d -> %d %d", c.rects[a].left(), c.rects[a].top(), c.rects[a].right(), c.rects[a].bottom());
-       eDebug("extends: %d %d %d %d", c.extends.left(), c.extends.top(), c.extends.right(), c.extends.bottom());
-       p.setOffset(ePoint(100, 100));
-       p.clip(c);
-
-       p.setBackgroundColor(gColor(1));
-       p.clear();
-       p.setForegroundColor(gColor(2));
-       p.line(ePoint(0, 0), ePoint(220, 190));
-       p.clippop();
-
-       p.setBackgroundColor(gColor(0x1f));
-       p.setForegroundColor(gColor(0x10));
-
-       ePtr<gFont> fnt = new gFont("Arial", 70);
-       p.setFont(fnt);
-       p.renderText(eRect(100, 100, 500, 200), "Hello welt!");
-#else
-
-
        eWidgetDesktop dsk(eSize(720, 576));
+       
+       wdsk = &dsk;
        dsk.setDC(my_dc);
 
-       eWindow *bla = new eWindow(&dsk);
-       
-       bla->move(ePoint(100, 100));
-       bla->resize(eSize(200, 200));
-       bla->show();
+       eWindow *wnd = new eWindow(&dsk);
+       wnd->move(ePoint(100, 100));
+       wnd->resize(eSize(200, 200));
+       wnd->show();
 
-       eLabel *blablub = new eLabel(bla->child());
-       blablub->setText("hello world");
-       blablub->move(ePoint(0, 0));
-       blablub->resize(eSize(400,400));
+       eLabel *label = new eButton(wnd);
+       label->setText("Hello!!");
+       label->move(ePoint(40, 40));
+       label->resize(eSize(100, 40));
 
-#if 0
+       label = new eButton(wnd);
+       label->setText("2nd!!");
+       label->move(ePoint(40, 90));
+       label->resize(eSize(100, 40));
+
+#if 0  
        eWidget *bla2 = new eWidget(0);
        dsk.addRootWidget(bla2, 0);
        
@@ -138,43 +128,44 @@ int main()
        bla2->show();
 #endif
 
-       dsk.recalcClipRegions();
+//     dsk.recalcClipRegions();
+//     dsk.paint();
+//     dsk.invalidate(gRegion(eRect(0, 0, 720, 576)));
 
-//     dumpRegion(bla->m_visible_region);
-//     dumpRegion(bla2->m_visible_region);
-//     dumpRegion(blablub->m_visible_region);
+//     dumpRegion(wnd->m_visible_region);
+//     dumpRegion(label->m_visible_region);
+//     dumpRegion(label->m_visible_region);
        
        eDebug("painting!");
+       
 
-       dsk.invalidate(gRegion(eRect(0, 0, 720, 576)));
-       dsk.paint();
-#endif
-
-#else
-
-       extern void contentTest();
-
-       eDebug("Contenttest");
-       contentTest();
+       ePython python;
+       
+       printf("about to execute TEST :)\n");
+       python.execute("mytest", "test");
 
+       sleep(2);
 #endif
 
-       p.resetClip(gRegion(eRect(0, 0, 720, 576)));
-//     p.clear();
-       sleep(1);
-       
-//     blablub->setText("123");
-//     dumpRegion(blablub->m_visible_region);
-//     dumpRegion(dsk.m_dirty_region);
-       dsk.paint();
-       
+#if 0
 
-#endif
+               // connections mit parametern: geht! :)
+       using namespace std;
+       using namespace SigC;
 
-       ePython python;
        
-       printf("about to execute TEST :)\n");
-       python.execute("mytest", "test");
+       Signal1<void,const string &> printer;
+       int i;
+       for (i=1; i<argc; ++i)
+               printer.connect(bind(slot(print), argv[i]));
+       printer("hello world\n");
+#endif
 
        return 0;
 }
+
+eWidgetDesktop *getDesktop()
+{
+       return wdsk;
+}
+
index 5a9d4c8421c936e1b4121d6190d7eb5c3db58431..723de54d21dea995d17ac4bc8b6991845048b1ff 100644 (file)
--- a/mytest.py
+++ b/mytest.py
 from enigma import *
 
+import sys
+import time
+
+from screens import *
+from skin import applyGUIskin
+
+# A screen is a function which instanciates all components of a screen into a temporary component.
+# Thus, the global stuff is a screen, too.
+# In a screen, components can either be instanciated from the class-tree, cloned (copied) or
+# "linked" from the instance tree.
+# A screen itself lives as the container of the components, so a screen is a component, too.
+
+# we thus have one (static) hierarchy of screens (classes, not instances)
+# and one with the instanciated components itself (both global and dynamic)
+
+def dump(dir, p = ""):
+       if isinstance(dir, dict):
+               for (entry, val) in dir.items():
+                       dump(val, p + "/" + entry)
+       print p + ":" + str(dir.__class__)
+
+# defined components
+components = {}
+
+# do global
+screens["global"](components)
+
+# test our screens
+components["$001"] = screens["testDialog"]()
+components["$002"] = screens["clockDisplay"](components["clock"])
+
+print "*** classes:"
+dump(screens)
+
+print "*** instances:"
+dump(components)
+
+# display
+
+class OutputDevice:
+       def create(self, screen): pass
+
+# display: HTML
+
+class HTMLOutputDevice(OutputDevice):
+       def create(self, comp):
+               print comp.produceHTML()
+
+html = HTMLOutputDevice()
+
+class GUIOutputDevice(OutputDevice):
+       parent = None
+       def create(self, comp):
+               comp.createGUIScreen(self.parent)
+
+
+
 def test():
-       ref = eServiceReference("4097:47:0:0:0:0:0:0:0:0:/sine_60s_100.mp3");
+       desktop = getDesktop()
+       print "desktop: " + str(desktop)
+
+       wnd = eWindow(desktop)
+       print "window " + str(wnd)
+       wnd.setTitle("python")
+       wnd.move(ePoint(300, 100))
+       wnd.resize(eSize(300, 300))
+       wnd.show()
+
+       gui = GUIOutputDevice()
+       gui.parent = wnd
+       gui.create(components["$002"])
+#      for (x,y) in components["$001"].data.items():
+#              print str(x) + " -> " + str(y) + " (" + y["instance"].getText() + ")"
+
+#      print components["$001"].data["okbutton"]["instance"].doClick()
+
+# diese sachen gehoeren in den skin! :)
+       applyGUIskin(components["$002"], None, "clockDialog")
+       
+# das ist dann schon die echte funktionalitaet ;)
+       components["clock"].doClock()
+       components["clock"].doClock()
+
+
+# output as html
+       print "--------------------------------------"
+       html.create(components["$001"])
+       print "--------------------------------------"
+       html.create(components["$002"])
+       print "--------------------------------------"
        
-       sc = eServiceCenterPtr()
-       print sc
        
-       if eServiceCenter.getInstance(sc):
-               print "no eServiceCenter instance!"
-       else:
-               print "now trying to play!"
-               i = iPlayableServicePtr();
-               if sc.play(ref, i):
-                       print "play failed! :("
+# direkter test der GUI aus python:
+#      label1 = eLabel(wnd)
+#      label1.setText("hello world!\nfrom python!")
+#      label1.move(ePoint(10, 10))
+#      label1.resize(eSize(80, 50))
+#
+#      label2 = eLabel(wnd)
+#      label2.setText("the second\nlabel works\nas well!")
+#      label2.move(ePoint(90, 10))
+#      label2.resize(eSize(80, 50))
+#
+#      button = eButton(wnd)
+#      button.setText("OK")
+#      button.move(ePoint(200, 10))
+#      button.resize(eSize(80, 50)) 
+
+       for x in range(200):
+               time.sleep(0.1)
+               components["clock"].doClock()
+               if x > 100:
+                       r = 200 - x
                else:
-                       print "play ruled!"
-                       
-                       p = iPauseableServicePtr()
-                       if (i.getIPausableService(p)):
-                               print "no pause available"
-                       else:
-                               p.pause()
-                               p.unpause()
+                       r = x
+#              components["$002"]["okbutton"].setValue(r)
+               desktop.paint()
+       
+#      
+#      print "delete label1"
+#      del button
+#      del label2
+#      del label1
+#      print "delete wnd"
+#      del wnd
+#      print "bye"
+       
        
        return 0
diff --git a/screens.py b/screens.py
new file mode 100644 (file)
index 0000000..bd0f6fc
--- /dev/null
@@ -0,0 +1,42 @@
+from components import *
+
+# some screens
+def doGlobal(screen):
+       screen["clock"] = Clock()
+
+class Screen(dict, HTMLSkin, GUISkin):
+       """ bla """
+       
+# a test dialog
+class testDialog(Screen):
+       def testDialogClick(self):
+               print "test dialog clicked!"
+               self["title"].setText("bla")
+
+       def __init__(self):
+               HTMLSkin.__init__(self, ("title", "okbutton"))
+               b = Button("ok")
+               b.onClick = [ self.testDialogClick ]
+               self["okbutton"] = b
+               self["title"] = Header("Test Dialog - press ok to leave!")
+
+# a clock display dialog
+class clockDisplay(Screen):
+       def okbutton(self):
+               print "clockDisplay close"
+       
+       def __init__(self, clock):
+               HTMLSkin.__init__(self, ("title", "theClock", "okbutton"))
+               self["theClock"] = clock
+               b = Button("bye")
+               b.onClick = [ self.okbutton ]
+               self["okbutton"] = b
+               #VolumeBar()
+               self["title"] = Header("clock dialog: here you see the current uhrzeit!")
+
+# defined screens
+screens = {
+       "global": doGlobal,
+       "testDialog": testDialog,
+       "clockDisplay": clockDisplay }
+
diff --git a/skin.py b/skin.py
new file mode 100644 (file)
index 0000000..415f341
--- /dev/null
+++ b/skin.py
@@ -0,0 +1,28 @@
+from enigma import *
+import xml.dom.minidom
+
+def dump(x, i=0):
+       print " " * i + str(x)
+       try:
+               for n in x.childNodes:
+                       dump(n, i + 1)
+       except:
+               None
+
+dom = xml.dom.minidom.parseString(
+       "<screen name=\"clockDialog\"> \
+               <widget name=\"okbutton\" position=\"10,10\" size=\"280,40\" /> \
+               <widget name=\"theClock\" position=\"10,60\" size=\"280,50\" /> \
+               <widget name=\"title\" position=\"10,120\" size=\"280,50\" /> \
+       </screen>")
+
+def applyGUIskin(screen, skin, name):
+       dump(dom[screen])
+       screen.data["okbutton"]["instance"].move(ePoint(10, 10))
+       screen.data["okbutton"]["instance"].resize(eSize(280, 40))
+
+       screen.data["theClock"]["instance"].move(ePoint(10, 60))
+       screen.data["theClock"]["instance"].resize(eSize(280, 50))
+
+       screen.data["title"]["instance"].move(ePoint(10, 120))
+       screen.data["title"]["instance"].resize(eSize(280, 50))