fix return value
[enigma2.git] / lib / gdi / grc.h
1 #ifndef __grc_h
2 #define __grc_h
3
4 /*
5         gPainter ist die high-level version. die highlevel daten werden zu low level opcodes ueber
6         die gRC-queue geschickt und landen beim gDC der hardwarespezifisch ist, meist aber auf einen
7         gPixmap aufsetzt (und damit unbeschleunigt ist).
8 */
9
10 #include <pthread.h>
11 #include <stack>
12 #include <list>
13
14 #include <lib/base/estring.h>
15 #include <lib/base/ringbuffer.h>
16 #include <lib/gdi/erect.h>
17 #include <lib/base/elock.h>
18 #include <lib/gdi/gpixmap.h>
19
20
21 class eTextPara;
22
23 class gDC;
24 struct gOpcode
25 {
26         enum Opcode
27         {
28                 begin,
29                 
30                 renderText,
31                 renderPara,
32                 
33                 fill,
34                 blit,
35
36                 setPalette,
37                 mergePalette,
38                 
39                 line,
40                 
41                 clip,
42                 
43                 flush,
44                 end,
45                 
46                 shutdown
47         } opcode;
48
49         union para
50         {
51                 struct pbegin
52                 {
53                         eRect area;
54                         pbegin(const eRect &area): area(area) { }
55                 } *begin;
56                 
57                 struct pfill
58                 {
59                         eRect area;
60                         gColor color;
61                         pfill(const eRect &area, gColor color): area(area), color(color) { }
62                 } *fill;
63
64                 struct prenderText
65                 {
66                         gFont font;
67                         eRect area;
68                         eString text;
69                         gRGB foregroundColor, backgroundColor;
70                         prenderText(const gFont &font, const eRect &area, const eString &text, const gRGB &foregroundColor, const gRGB &backgroundColor):
71                                 font(font), area(area), text(text), foregroundColor(foregroundColor), backgroundColor(backgroundColor) { }
72                 } *renderText;
73
74                 struct prenderPara
75                 {
76                         ePoint offset;
77                         eTextPara *textpara;
78                         gRGB foregroundColor, backgroundColor;
79                         prenderPara(const ePoint &offset, eTextPara *textpara, const gRGB &foregroundColor, const gRGB &backgroundColor)
80                                 : offset(offset), textpara(textpara), foregroundColor(foregroundColor), backgroundColor(backgroundColor) { }
81                 } *renderPara;
82
83                 struct psetPalette
84                 {
85                         gPalette *palette;
86                         psetPalette(gPalette *palette): palette(palette) { }
87                 } *setPalette;
88                 
89                 struct pblit
90                 {
91                         ePtr<gPixmap> pixmap;
92                         ePoint position;
93                         eRect clip;
94                         pblit(gPixmap *pixmap, const ePoint &position, const eRect &clip)
95                                 : pixmap(pixmap), position(position), clip(clip) { }
96                 } *blit;
97
98                 struct pmergePalette
99                 {
100                         ePtr<gPixmap> target;
101                         pmergePalette(gPixmap *target): target(target) { }
102                 } *mergePalette;
103                 
104                 struct pline
105                 {
106                         ePoint start, end;
107                         gColor color;
108                         pline(const ePoint &start, const ePoint &end, gColor color): start(start), end(end), color(color) { }
109                 } *line;
110
111                 struct pclip
112                 {
113                         eRect clip;
114                         pclip(const eRect &clip): clip(clip) { }
115                 } *clip;
116         } parm;
117
118         int flags;
119         
120         gDC *dc;
121 };
122
123 class gRC
124 {
125         static gRC *instance;
126         
127         static void *thread_wrapper(void *ptr);
128         pthread_t the_thread;
129         void *thread();
130         
131         eLock queuelock;
132         
133         queueRingBuffer<gOpcode> queue;
134 public:
135         gRC();
136         virtual ~gRC();
137
138         void submit(const gOpcode &o)
139         {
140                 static int collected=0;
141                 queue.enqueue(o);
142                 collected++;
143                 if (o.opcode==gOpcode::end)
144                 {
145                         queuelock.unlock(collected);
146 #ifdef SYNC_PAINT
147                         thread();
148 #endif
149                         collected=0;
150                 }
151         }
152
153         static gRC &getInstance();
154 };
155
156 class gPainter
157 {
158         gDC &dc;
159         gRC &rc;
160         friend class gRC;
161
162         gOpcode *beginptr;
163                         /* paint states */      
164 //      std::stack<eRect, std::list<eRect> > cliparea;
165         std::stack<eRect> cliparea;
166         gFont font;
167         gColor foregroundColor, backgroundColor;
168         ePoint logicalZero;
169         void begin(const eRect &rect);
170         void end();
171 public:
172         gPainter(gDC &dc, eRect rect=eRect());
173         virtual ~gPainter();
174
175         void setBackgroundColor(const gColor &color);
176         void setForegroundColor(const gColor &color);
177
178         void setFont(const gFont &font);
179         void renderText(const eRect &position, const std::string &string, int flags=0);
180         void renderPara(eTextPara &para, ePoint offset=ePoint(0, 0));
181
182         void fill(const eRect &area);
183         
184         void clear();
185         
186         void gPainter::blit(gPixmap *pixmap, ePoint pos, eRect clip=eRect(), int flags=0)
187         {
188                 gOpcode o;
189                 o.dc=&dc;
190                 o.opcode=gOpcode::blit;
191                 pos+=logicalZero;
192                 clip.moveBy(logicalZero.x(), logicalZero.y());
193                 o.parm.blit=new gOpcode::para::pblit(pixmap, pos, clip);
194                 o.flags=flags;
195                 rc.submit(o);
196         }
197
198         void setPalette(gRGB *colors, int start=0, int len=256);
199         void mergePalette(gPixmap *target);
200         
201         void line(ePoint start, ePoint end);
202
203         void setLogicalZero(ePoint abs);
204         void moveLogicalZero(ePoint rel);
205         void resetLogicalZero();
206         
207         void clip(eRect clip);
208         void clippop();
209
210         void flush();
211 };
212
213 class gDC
214 {
215 protected:
216         eLock dclock;
217 public:
218         virtual void exec(gOpcode *opcode)=0;
219         virtual RESULT getPixmap(ePtr<gPixmap> &)=0;
220         virtual eSize getSize()=0;
221         virtual const eRect &getClip()=0;
222         virtual gRGB getRGB(gColor col)=0;
223         virtual ~gDC();
224         void lock() { dclock.lock(1); }
225         void unlock() { dclock.unlock(1); }
226 };
227
228 class gPixmapDC: public gDC
229 {
230 protected:
231         ePtr<gPixmap> pixmap;
232         eRect clip;
233
234         void exec(gOpcode *opcode);
235         gPixmapDC();
236 public:
237         gPixmapDC(gPixmap *pixmap);
238         virtual ~gPixmapDC();
239         RESULT getPixmap(ePtr<gPixmap> &ptr) { ptr = pixmap; return 0; }
240         gRGB getRGB(gColor col);
241         const eRect &getClip() { return clip; }
242         virtual eSize getSize() { return eSize(pixmap->x, pixmap->y); }
243 };
244
245 #endif