yes! ich habs kaputt gemacht! (doesn't compile anymore, doesn't work anymore,
[enigma2.git] / lib / gdi / grc.cpp
1 // for debugging use:
2 // #define SYNC_PAINT
3 #include <unistd.h>
4 #ifndef SYNC_PAINT
5 #include <pthread.h>
6 #endif
7
8 #include <lib/gdi/grc.h>
9 #include <lib/gdi/font.h>
10 #include <lib/gdi/lcd.h>
11 #include <lib/base/init.h>
12 #include <lib/base/init_num.h>
13
14 #define MAXSIZE 1024
15
16 #ifndef SYNC_PAINT
17 void *gRC::thread_wrapper(void *ptr)
18 {
19         nice(3);
20         return ((gRC*)ptr)->thread();
21 }
22 #endif
23
24 gRC *gRC::instance=0;
25
26 gRC::gRC(): queue(2048), queuelock(MAXSIZE)
27 {
28         ASSERT(!instance);
29         instance=this;
30         queuelock.lock(MAXSIZE);
31 #ifndef SYNC_PAINT
32         eDebug(pthread_create(&the_thread, 0, thread_wrapper, this)?"RC thread couldn't be created":"RC thread createted successfully");
33 #endif
34 }
35
36 gRC::~gRC()
37 {
38         fbClass::getInstance()->lock();
39 #ifndef DISABLE_LCD
40         eDBoxLCD::getInstance()->lock();
41 #endif
42         instance=0;
43
44         gOpcode o;
45         o.opcode=gOpcode::shutdown;
46         submit(o);
47         eDebug("waiting for gRC thread shutdown");
48         pthread_join(the_thread, 0);
49         eDebug("gRC thread has finished");
50 }
51
52 void *gRC::thread()
53 {
54 #ifndef SYNC_PAINT
55         while (1)
56 #else
57         while (queue.size())
58 #endif
59         {
60                 queuelock.lock(1);
61                 gOpcode& o(queue.current());
62                 if (o.opcode==gOpcode::shutdown)
63                         break;
64                 o.dc->exec(&o);
65                 o.dc->Release();
66                 queue.dequeue();
67         }
68 #ifndef SYNC_PAINT
69         pthread_exit(0);
70 #endif
71         return 0;
72 }
73
74 gRC *gRC::getInstance()
75 {
76         return instance;
77 }
78
79 static int gPainter_instances;
80
81 gPainter::gPainter(gDC *dc, eRect rect): m_dc(dc), m_rc(gRC::getInstance())
82 {
83 //      ASSERT(!gPainter_instances);
84         gPainter_instances++;
85         begin(rect);
86 }
87
88 gPainter::~gPainter()
89 {
90         end();
91         gPainter_instances--;
92 }
93
94 void gPainter::setBackgroundColor(const gColor &color)
95 {
96         gOpcode o;
97         o.opcode = gOpcode::setBackgroundColor;
98         o.dc = m_dc.grabRef();
99         o.parm.setColor = new gOpcode::para::psetColor;
100         o.parm.setColor->color = color;
101         
102         m_rc->submit(o);
103 }
104
105 void gPainter::setForegroundColor(const gColor &color)
106 {
107         gOpcode o;
108         o.opcode = gOpcode::setForegroundColor;
109         o.dc = m_dc.grabRef();
110         o.parm.setColor = new gOpcode::para::psetColor;
111         o.parm.setColor->color = color;
112         
113         m_rc->submit(o);
114 }
115
116 void gPainter::setFont(gFont *font)
117 {
118         gOpcode o;
119         o.opcode = gOpcode::setFont;
120         o.dc = m_dc.grabRef();
121         font->AddRef();
122         o.parm.setFont = new gOpcode::para::psetFont;
123         o.parm.setFont->font = font;
124         
125         m_rc->submit(o);
126 }
127
128 void gPainter::renderText(const eRect &pos, const std::string &string, int flags)
129 {
130         gOpcode o;
131         o.opcode=gOpcode::renderText;
132         o.dc = m_dc.grabRef();
133         o.parm.renderText = new gOpcode::para::prenderText;
134         o.parm.renderText->area = pos;
135         o.parm.renderText->text = string;
136         o.parm.renderText->flags = flags;
137         m_rc->submit(o);
138 }
139
140 void gPainter::renderPara(eTextPara *para, ePoint offset)
141 {
142         gOpcode o;
143         o.opcode=gOpcode::renderPara;
144         o.dc = m_dc.grabRef();
145         o.parm.renderPara = new gOpcode::para::prenderPara;
146         o.parm.renderPara->offset = offset;
147
148         para->AddRef();
149         o.parm.renderPara->textpara = para;
150         m_rc->submit(o);
151 }
152
153 void gPainter::fill(const eRect &area)
154 {
155         gOpcode o;
156         o.opcode=gOpcode::fill;
157
158         o.dc = m_dc.grabRef();
159         o.parm.fill = new gOpcode::para::pfillRect;
160         o.parm.fill->area = area;
161         m_rc->submit(o);
162 }
163
164 void gPainter::clear()
165 {
166         gOpcode o;
167         o.opcode=gOpcode::clear;
168         o.dc = m_dc.grabRef();
169         o.parm.fill = new gOpcode::para::pfillRect;
170         o.parm.fill->area = eRect();
171         m_rc->submit(o);
172 }
173
174 void gPainter::blit(gPixmap *pixmap, ePoint pos, gRegion *clip, int flags)
175 {
176         gOpcode o;
177
178         o.opcode=gOpcode::blit;
179         o.dc = m_dc.grabRef();
180         pixmap->AddRef();
181         o.parm.blit  = new gOpcode::para::pblit;
182         o.parm.blit->pixmap = pixmap;
183         o.parm.blit->position = pos;
184         clip->AddRef();
185         o.parm.blit->clip = clip;
186         o.flags=flags;
187         m_rc->submit(o);
188 }
189
190
191 void gPainter::setPalette(gRGB *colors, int start, int len)
192 {
193         gOpcode o;
194         o.opcode=gOpcode::setPalette;
195         o.dc = m_dc.grabRef();
196         gPalette *p=new gPalette;
197         
198         p->data=new gRGB[len];
199         memcpy(p->data, colors, len*sizeof(gRGB));
200         p->start=start;
201         p->colors=len;
202         o.parm.setPalette->palette = p;
203         m_rc->submit(o);
204 }
205
206 void gPainter::mergePalette(gPixmap *target)
207 {
208         gOpcode o;
209         o.opcode=gOpcode::mergePalette;
210         o.dc = m_dc.grabRef();
211         target->AddRef();
212         o.parm.mergePalette->target = target;
213         m_rc->submit(o);
214 }
215
216 void gPainter::line(ePoint start, ePoint end)
217 {
218         gOpcode o;
219         o.opcode=gOpcode::line;
220         o.dc = m_dc.grabRef();
221         o.parm.line = new gOpcode::para::pline;
222         o.parm.line->start = start;
223         o.parm.line->end = end;
224         m_rc->submit(o);
225 }
226
227 void gPainter::setLogicalZero(ePoint val)
228 {
229         gOpcode o;
230         o.opcode=gOpcode::setOffset;
231         o.dc = m_dc.grabRef();
232         o.parm.setOffset = new gOpcode::para::psetOffset;
233         o.parm.setOffset->rel = 0;
234         o.parm.setOffset->value = val;
235         m_rc->submit(o);
236 }
237
238 void gPainter::moveLogicalZero(ePoint rel)
239 {
240         gOpcode o;
241         o.opcode=gOpcode::moveOffset;
242         o.dc = m_dc.grabRef();
243         o.parm.setOffset = new gOpcode::para::psetOffset;
244         o.parm.setOffset->rel = 1;
245         o.parm.setOffset->value = rel;
246         m_rc->submit(o);
247 }
248
249 void gPainter::resetLogicalZero()
250 {
251         gOpcode o;
252         o.opcode=gOpcode::moveOffset;
253         o.dc = m_dc.grabRef();
254         o.parm.setOffset = new gOpcode::para::psetOffset;
255         o.parm.setOffset->value = ePoint(0, 0);
256         m_rc->submit(o);
257 }
258
259 void gPainter::clip(const gRegion &region)
260 {
261         gOpcode o;
262         o.opcode = gOpcode::addClip;
263         o.dc = m_dc.grabRef();
264         o.parm.clip = new gOpcode::para::psetClip;
265         o.parm.clip->region = new gRegion(region);
266         o.parm.clip->region->AddRef();
267         m_rc->submit(o);
268 }
269
270 void gPainter::clippop()
271 {
272         gOpcode o;
273         o.opcode = gOpcode::popClip;
274         o.dc = m_dc.grabRef();
275         m_rc->submit(o);
276 }
277
278 void gPainter::flush()
279 {
280 }
281
282 void gPainter::end()
283 {
284 }
285
286 gDC::gDC()
287 {
288 }
289
290 gDC::gDC(gPixmap *pixmap): m_pixmap(pixmap)
291 {
292 }
293
294 gDC::~gDC()
295 {
296 }
297
298 void gDC::exec(gOpcode *o)
299 {
300 #if 0
301         switch(o->opcode)
302         {
303         case gOpcode::renderText:
304         {
305                 ePtr<eTextPara> para = new eTextPara(o->parm.renderText.area);
306                 para->setFont(m_current_font);
307                 para->renderString(*o->parm.renderText.text, o->parm.renderText.flags);
308                 para->blit(*this, ePoint(0, 0), m_foregroundColor, m_backgroundColor);
309                 delete o->parm.renderText->text;
310                 break;
311         }
312         case gOpcode::renderPara:
313         {
314                 o->parm.renderPara.textpara->blit(*this, o->parm.renderPara.offset, m_foregroundColor, m_backgroundColor);
315                 o->parm.renderPara.textpara.Release();
316                 break;
317         }
318         case gOpcode::fill:
319                 m_pixmap->fill(o->parm.fill.area, m_foregroundColor);
320                 delete o->parm.fill;
321                 break;
322         case gOpcode::blit:
323         {
324                 gRegion clip;
325                 if (o->parm.blit.clip)
326                 {
327                         clip.intersect(o->parm.blit.clip, clip);
328                         o->parm.blit.clip->Release();
329                 } else
330                         clip = m_current_clip;
331                 pixmap->blit(*o->parm.blit.pixmap, o->parm.blit.pos, clip, o->parm.blit.flags);
332                 o->parm.blit.pixmap->Release();
333                 break;
334         }
335         case gOpcode::setPalette:
336 #if 0
337                 if (o->parm.setPalette->palette->start>pixmap->surface->clut.colors)
338                         o->parm.setPalette->palette->start=pixmap->surface->clut.colors;
339                 if (o->parm.setPalette->palette->colors>(pixmap->surface->clut.colors-o->parm.setPalette->palette->start))
340                         o->parm.setPalette->palette->colors=pixmap->surface->clut.colors-o->parm.setPalette->palette->start;
341                 if (o->parm.setPalette->palette->colors)
342                         memcpy(pixmap->surface->clut.data+o->parm.setPalette->palette->start, o->parm.setPalette->palette->data, o->parm.setPalette->palette->colors*sizeof(gRGB));
343                 delete[] o->parm.setPalette->palette->data;
344                 delete o->parm.setPalette->palette;
345                 delete o->parm.setPalette;
346 #endif
347                 break;
348         case gOpcode::mergePalette:
349 #if 0
350                 pixmap->mergePalette(*o->parm.blit->pixmap);
351                 o->parm.blit->pixmap->unlock();
352                 delete o->parm.blit;
353 #endif
354                 break;
355         case gOpcode::line:
356 #if 0
357                 pixmap->line(o->parm.line->start, o->parm.line->end, o->parm.line->color);
358                 delete o->parm.line;
359 #endif
360                 break;
361         case gOpcode::setBackgroundColor:
362                 m_backgroundColor = o->parm.setColor.color;
363                 break;
364         case gOpcode::setForegroundColor:
365                 m_foregroundColor = o->parm.setColor.color;
366                 break;
367         case gOpcode::clip:
368                 break;
369         default:
370                 eFatal("illegal opcode %d. expect memory leak!", o->opcode);
371         }
372 #endif
373 }
374
375 gRGB gDC::getRGB(gColor col)
376 {
377         if ((!m_pixmap) || (!m_pixmap->surface->clut.data))
378                 return gRGB(col, col, col);
379         if (col<0)
380         {
381                 eFatal("bla transp");
382                 return gRGB(0, 0, 0, 0xFF);
383         }
384         return m_pixmap->surface->clut.data[col];
385 }
386
387 DEFINE_REF(gDC);
388
389 eAutoInitP0<gRC> init_grc(eAutoInitNumbers::graphic, "gRC");