trunk 20080912
[gitenigma.git] / lib / gdi / grc.cpp
blob347269126b1df54167065bf30931f251e045c681
1 #include <unistd.h>
2 #include <pthread.h>
3 #include <lib/gdi/grc.h>
4 #include <lib/gdi/font.h>
5 #include <lib/gdi/lcd.h>
6 #include <lib/system/init.h>
7 #include <lib/system/init_num.h>
9 void *gRC::thread_wrapper(void *ptr)
11 // nice(1); //3
12 return ((gRC*)ptr)->thread();
15 gRC *gRC::instance=0;
17 gRC::gRC()
19 ASSERT(!instance);
20 instance=this;
21 pthread_mutex_init(&mutex, 0);
22 pthread_cond_init(&cond, 0);
23 rp=wp=0;
24 eDebug(pthread_create(&the_thread, 0, thread_wrapper, this)?"RC thread couldn't be created":"RC thread createted successfully");
27 gRC::~gRC()
29 fbClass::getInstance()->lock();
30 #ifndef DISABLE_LCD
31 eDBoxLCD::getInstance()->lock();
32 #endif
33 instance=0;
34 gOpcode o;
35 o.dc=0;
36 o.opcode=gOpcode::shutdown;
37 submit(o);
38 eDebug("waiting for gRC thread shutdown");
39 pthread_join(the_thread, 0);
40 eDebug("gRC thread has finished");
41 pthread_mutex_destroy(&mutex);
42 pthread_cond_destroy(&cond);
45 void *gRC::thread()
47 while (1)
49 pthread_mutex_lock(&mutex);
50 if ( rp != wp )
52 gOpcode o(queue[rp++]);
53 if ( rp == MAXSIZE )
54 rp=0;
55 pthread_mutex_unlock(&mutex);
56 if (o.opcode==gOpcode::shutdown)
57 break;
58 o.dc->exec(&o);
60 else
62 pthread_cond_wait(&cond, &mutex);
63 pthread_mutex_unlock(&mutex);
66 pthread_exit(0);
67 return 0;
70 gRC &gRC::getInstance()
72 return *instance;
75 static int gPainter_instances;
77 gPainter::gPainter(gDC &dc, eRect rect): dc(dc), rc(gRC::getInstance()), foregroundColor(0), backgroundColor(0)
79 if (rect.isNull())
80 rect=eRect(ePoint(0, 0), dc.getSize());
81 // ASSERT(!gPainter_instances);
82 gPainter_instances++;
83 begin(rect);
86 gPainter::~gPainter()
88 end();
89 gPainter_instances--;
92 void gPainter::begin(const eRect &rect)
94 if ( dc.islocked() )
95 return;
96 gOpcode o;
97 dc.lock();
98 o.dc=&dc;
99 o.opcode=gOpcode::begin;
100 o.parm.begin=new gOpcode::para::pbegin(rect);
101 // cliparea=std::stack<eRect, std::list<eRect> >();
102 cliparea=std::stack<eRect>();
103 cliparea.push(rect);
104 setLogicalZero(cliparea.top().topLeft());
105 rc.submit(o);
108 void gPainter::setBackgroundColor(const gColor &color)
110 backgroundColor=color;
113 void gPainter::setForegroundColor(const gColor &color)
115 foregroundColor=color;
118 void gPainter::setFont(const gFont &mfont)
120 font=mfont;
123 void gPainter::renderText(const eRect &pos, const std::string &string, int flags)
125 if ( dc.islocked() )
126 return;
127 eRect area=pos;
128 area.moveBy(logicalZero.x(), logicalZero.y());
130 gOpcode o;
131 o.dc=&dc;
132 o.opcode=gOpcode::renderText;
133 o.parm.renderText=new gOpcode::para::prenderText(font, area, string, dc.getRGB(foregroundColor), dc.getRGB(backgroundColor));
134 o.flags=flags;
135 rc.submit(o);
138 void gPainter::renderPara(eTextPara &para, ePoint offset)
140 if ( dc.islocked() )
141 return;
142 gOpcode o;
143 o.dc=&dc;
144 o.opcode=gOpcode::renderPara;
145 o.parm.renderPara=new gOpcode::para::prenderPara(logicalZero+offset, para.grab(), dc.getRGB(foregroundColor), dc.getRGB(backgroundColor));
146 rc.submit(o);
149 void gPainter::fill(const eRect &area)
151 if ( dc.islocked() )
152 return;
153 gOpcode o;
154 o.dc=&dc;
155 o.opcode=gOpcode::fill;
156 eRect a=area;
157 a.moveBy(logicalZero.x(), logicalZero.y());
158 a&=cliparea.top();
160 o.parm.fill=new gOpcode::para::pfill(a, foregroundColor);
161 rc.submit(o);
164 void gPainter::clear()
166 if ( dc.islocked() )
167 return;
168 gOpcode o;
169 o.dc=&dc;
170 o.opcode=gOpcode::fill;
171 o.parm.fill=new gOpcode::para::pfill(cliparea.top(), backgroundColor);
172 rc.submit(o);
175 void gPainter::setPalette(gRGB *colors, int start, int len)
177 if ( dc.islocked() )
178 return;
179 gOpcode o;
180 o.dc=&dc;
181 o.opcode=gOpcode::setPalette;
182 gPalette *p=new gPalette;
184 p->data=new gRGB[len];
185 memcpy(p->data, colors, len*sizeof(gRGB));
186 p->start=start;
187 p->colors=len;
188 o.parm.setPalette=new gOpcode::para::psetPalette(p);
189 rc.submit(o);
192 void gPainter::mergePalette(gPixmap &target)
194 if ( dc.islocked() )
195 return;
196 gOpcode o;
197 o.dc=&dc;
198 o.opcode=gOpcode::mergePalette;
199 o.parm.mergePalette=new gOpcode::para::pmergePalette(target.lock());
200 rc.submit(o);
203 void gPainter::line(ePoint start, ePoint end)
205 if ( dc.islocked() )
206 return;
207 gOpcode o;
208 o.dc=&dc;
209 o.opcode=gOpcode::line;
210 o.parm.line=new gOpcode::para::pline(start+logicalZero, end+logicalZero, foregroundColor);
211 rc.submit(o);
214 void gPainter::setLogicalZero(ePoint rel)
216 logicalZero=rel;
219 void gPainter::moveLogicalZero(ePoint rel)
221 logicalZero+=rel;
224 void gPainter::resetLogicalZero()
226 logicalZero.setX(0);
227 logicalZero.setY(0);
230 void gPainter::clip(eRect clip)
232 if ( dc.islocked() )
233 return;
234 gOpcode o;
235 o.dc=&dc;
236 o.opcode=gOpcode::clip;
237 clip.moveBy(logicalZero.x(), logicalZero.y());
238 cliparea.push(cliparea.top()&clip);
239 o.parm.clip=new gOpcode::para::pclip(cliparea.top());
241 rc.submit(o);
244 void gPainter::clippop()
246 if ( dc.islocked() )
247 return;
248 ASSERT (cliparea.size()>1);
249 gOpcode o;
250 o.dc=&dc;
251 o.opcode=gOpcode::clip;
252 cliparea.pop();
253 o.parm.clip=new gOpcode::para::pclip(cliparea.top());
254 rc.submit(o);
257 void gPainter::flush()
259 if ( dc.islocked() )
260 return;
261 gOpcode o;
262 o.dc=&dc;
263 o.opcode=gOpcode::flush;
264 rc.submit(o);
267 void gPainter::end()
269 gOpcode o;
270 o.dc=&dc;
271 o.opcode=gOpcode::end;
272 rc.submit(o);
275 gDC::~gDC()
279 gPixmapDC::gPixmapDC(): pixmap(0)
283 gPixmapDC::gPixmapDC(gPixmap *pixmap): pixmap(pixmap)
287 gPixmapDC::~gPixmapDC()
289 dclock.lock();
292 void gPixmapDC::exec(gOpcode *o)
294 switch(o->opcode)
296 case gOpcode::begin:
297 clip=o->parm.begin->area;
298 delete o->parm.begin;
299 break;
300 case gOpcode::renderText:
302 eTextPara *para=new eTextPara(o->parm.renderText->area);
303 para->setFont(o->parm.renderText->font);
304 para->renderString(o->parm.renderText->text, o->flags);
305 para->blit(*this, ePoint(0, 0), o->parm.renderText->backgroundColor, o->parm.renderText->foregroundColor);
306 para->destroy();
307 if (o->parm.renderText->text)
308 free(o->parm.renderText->text);
309 delete o->parm.renderText;
310 break;
312 case gOpcode::renderPara:
314 o->parm.renderPara->textpara->blit(*this, o->parm.renderPara->offset, o->parm.renderPara->backgroundColor, o->parm.renderPara->foregroundColor);
315 o->parm.renderPara->textpara->destroy();
316 delete o->parm.renderPara;
317 break;
319 case gOpcode::fill:
320 pixmap->fill(o->parm.fill->area, o->parm.fill->color);
321 delete o->parm.fill;
322 break;
323 case gOpcode::blit:
325 if (o->parm.blit->clip.isNull())
326 o->parm.blit->clip=clip;
327 else
328 o->parm.blit->clip&=clip;
329 pixmap->blit(*o->parm.blit->pixmap, o->parm.blit->position, o->parm.blit->clip, o->flags);
330 o->parm.blit->pixmap->unlock();
331 delete o->parm.blit;
332 break;
334 case gOpcode::setPalette:
335 if (o->parm.setPalette->palette->start>pixmap->clut.colors)
336 o->parm.setPalette->palette->start=pixmap->clut.colors;
337 if (o->parm.setPalette->palette->colors>(pixmap->clut.colors-o->parm.setPalette->palette->start))
338 o->parm.setPalette->palette->colors=pixmap->clut.colors-o->parm.setPalette->palette->start;
339 if (o->parm.setPalette->palette->colors)
340 memcpy(pixmap->clut.data+o->parm.setPalette->palette->start, o->parm.setPalette->palette->data, o->parm.setPalette->palette->colors*sizeof(gRGB));
341 delete[] o->parm.setPalette->palette->data;
342 delete o->parm.setPalette->palette;
343 delete o->parm.setPalette;
344 break;
345 case gOpcode::mergePalette:
346 pixmap->mergePalette(*o->parm.blit->pixmap);
347 o->parm.blit->pixmap->unlock();
348 delete o->parm.blit;
349 break;
350 case gOpcode::line:
351 pixmap->line(o->parm.line->start, o->parm.line->end, o->parm.line->color);
352 delete o->parm.line;
353 break;
354 case gOpcode::clip:
355 clip=o->parm.clip->clip;
356 delete o->parm.clip;
357 break;
358 case gOpcode::end:
359 unlock();
360 case gOpcode::flush:
361 break;
362 default:
363 eFatal("illegal opcode %d. expect memory leak!", o->opcode);
367 gRGB gPixmapDC::getRGB(gColor col)
369 if ((!pixmap) || (!pixmap->clut.data))
370 return gRGB(col, col, col);
371 if (col<0)
373 eFatal("bla transp");
374 return gRGB(0, 0, 0, 0xFF);
376 return pixmap->clut.data[col];
379 eAutoInitP0<gRC> init_grc(eAutoInitNumbers::graphic, "gRC");