8 #include <lib/gdi/grc.h>
9 #include <lib/gdi/font.h>
10 #include <lib/base/init.h>
11 #include <lib/base/init_num.h>
14 void *gRC::thread_wrapper(void *ptr)
16 return ((gRC*)ptr)->thread();
22 gRC::gRC(): rp(0), wp(0)
24 ,m_notify_pump(eApp, 0)
26 ,m_notify_pump(eApp, 1)
31 CONNECT(m_notify_pump.recv_msg, gRC::recv_notify);
33 pthread_mutex_init(&mutex, 0);
34 pthread_cond_init(&cond, 0);
35 int res = pthread_create(&the_thread, 0, thread_wrapper, this);
37 eFatal("RC thread couldn't be created");
39 eDebug("RC thread created successfully");
50 o.opcode=gOpcode::shutdown;
53 eDebug("waiting for gRC thread shutdown");
54 pthread_join(the_thread, 0);
55 eDebug("gRC thread has finished");
59 void gRC::submit(const gOpcode &o)
64 pthread_mutex_lock(&mutex);
73 pthread_mutex_unlock(&mutex);
77 //printf("render buffer full...\n");
79 usleep(1000); // wait 1 msec
88 if (o.opcode==gOpcode::flush||o.opcode==gOpcode::shutdown||o.opcode==gOpcode::notify)
90 pthread_cond_signal(&cond); // wakeup gdi thread
91 pthread_mutex_unlock(&mutex);
112 gOpcode& o(queue[rp]);
113 if (o.opcode==gOpcode::shutdown)
115 else if (o.opcode==gOpcode::notify)
128 m_notify_pump.send(1);
131 pthread_cond_wait(&cond, &mutex);
141 void gRC::recv_notify(const int &i)
146 gRC *gRC::getInstance()
151 static int gPainter_instances;
153 gPainter::gPainter(gDC *dc, eRect rect): m_dc(dc), m_rc(gRC::getInstance())
155 // ASSERT(!gPainter_instances);
156 gPainter_instances++;
160 gPainter::~gPainter()
163 gPainter_instances--;
166 void gPainter::setBackgroundColor(const gColor &color)
169 o.opcode = gOpcode::setBackgroundColor;
170 o.dc = m_dc.grabRef();
171 o.parm.setColor = new gOpcode::para::psetColor;
172 o.parm.setColor->color = color;
177 void gPainter::setForegroundColor(const gColor &color)
180 o.opcode = gOpcode::setForegroundColor;
181 o.dc = m_dc.grabRef();
182 o.parm.setColor = new gOpcode::para::psetColor;
183 o.parm.setColor->color = color;
188 void gPainter::setBackgroundColor(const gRGB &color)
191 o.opcode = gOpcode::setBackgroundColorRGB;
192 o.dc = m_dc.grabRef();
193 o.parm.setColorRGB = new gOpcode::para::psetColorRGB;
194 o.parm.setColorRGB->color = color;
199 void gPainter::setForegroundColor(const gRGB &color)
202 o.opcode = gOpcode::setForegroundColorRGB;
203 o.dc = m_dc.grabRef();
204 o.parm.setColorRGB = new gOpcode::para::psetColorRGB;
205 o.parm.setColorRGB->color = color;
210 void gPainter::setFont(gFont *font)
213 o.opcode = gOpcode::setFont;
214 o.dc = m_dc.grabRef();
216 o.parm.setFont = new gOpcode::para::psetFont;
217 o.parm.setFont->font = font;
222 void gPainter::renderText(const eRect &pos, const std::string &string, int flags)
225 o.opcode=gOpcode::renderText;
226 o.dc = m_dc.grabRef();
227 o.parm.renderText = new gOpcode::para::prenderText;
228 o.parm.renderText->area = pos;
229 o.parm.renderText->text = string;
230 o.parm.renderText->flags = flags;
234 void gPainter::renderPara(eTextPara *para, ePoint offset)
237 o.opcode=gOpcode::renderPara;
238 o.dc = m_dc.grabRef();
239 o.parm.renderPara = new gOpcode::para::prenderPara;
240 o.parm.renderPara->offset = offset;
243 o.parm.renderPara->textpara = para;
247 void gPainter::fill(const eRect &area)
250 o.opcode=gOpcode::fill;
252 o.dc = m_dc.grabRef();
253 o.parm.fill = new gOpcode::para::pfillRect;
254 o.parm.fill->area = area;
258 void gPainter::fill(const gRegion ®ion)
261 o.opcode=gOpcode::fillRegion;
263 o.dc = m_dc.grabRef();
264 o.parm.fillRegion = new gOpcode::para::pfillRegion;
265 o.parm.fillRegion->region = region;
269 void gPainter::clear()
272 o.opcode=gOpcode::clear;
273 o.dc = m_dc.grabRef();
274 o.parm.fill = new gOpcode::para::pfillRect;
275 o.parm.fill->area = eRect();
279 void gPainter::blit(gPixmap *pixmap, ePoint pos, const eRect &clip, int flags)
285 o.opcode=gOpcode::blit;
286 o.dc = m_dc.grabRef();
288 o.parm.blit = new gOpcode::para::pblit;
289 o.parm.blit->pixmap = pixmap;
290 o.parm.blit->position = pos;
291 o.parm.blit->clip = clip;
292 o.parm.blit->flags=flags;
297 void gPainter::setPalette(gRGB *colors, int start, int len)
300 o.opcode=gOpcode::setPalette;
301 o.dc = m_dc.grabRef();
302 gPalette *p=new gPalette;
304 o.parm.setPalette = new gOpcode::para::psetPalette;
305 p->data=new gRGB[len];
307 memcpy(p->data, colors, len*sizeof(gRGB));
310 o.parm.setPalette->palette = p;
314 void gPainter::setPalette(gPixmap *source)
317 setPalette(source->surface->clut.data, source->surface->clut.start, source->surface->clut.colors);
320 void gPainter::mergePalette(gPixmap *target)
323 o.opcode = gOpcode::mergePalette;
324 o.dc = m_dc.grabRef();
326 o.parm.mergePalette = new gOpcode::para::pmergePalette;
327 o.parm.mergePalette->target = target;
331 void gPainter::line(ePoint start, ePoint end)
334 o.opcode=gOpcode::line;
335 o.dc = m_dc.grabRef();
336 o.parm.line = new gOpcode::para::pline;
337 o.parm.line->start = start;
338 o.parm.line->end = end;
342 void gPainter::setOffset(ePoint val)
345 o.opcode=gOpcode::setOffset;
346 o.dc = m_dc.grabRef();
347 o.parm.setOffset = new gOpcode::para::psetOffset;
348 o.parm.setOffset->rel = 0;
349 o.parm.setOffset->value = val;
353 void gPainter::moveOffset(ePoint rel)
356 o.opcode=gOpcode::setOffset;
357 o.dc = m_dc.grabRef();
358 o.parm.setOffset = new gOpcode::para::psetOffset;
359 o.parm.setOffset->rel = 1;
360 o.parm.setOffset->value = rel;
364 void gPainter::resetOffset()
367 o.opcode=gOpcode::setOffset;
368 o.dc = m_dc.grabRef();
369 o.parm.setOffset = new gOpcode::para::psetOffset;
370 o.parm.setOffset->rel = 0;
371 o.parm.setOffset->value = ePoint(0, 0);
375 void gPainter::resetClip(const gRegion ®ion)
378 o.opcode = gOpcode::setClip;
379 o.dc = m_dc.grabRef();
380 o.parm.clip = new gOpcode::para::psetClip;
381 o.parm.clip->region = region;
385 void gPainter::clip(const gRegion ®ion)
388 o.opcode = gOpcode::addClip;
389 o.dc = m_dc.grabRef();
390 o.parm.clip = new gOpcode::para::psetClip;
391 o.parm.clip->region = region;
395 void gPainter::clippop()
398 o.opcode = gOpcode::popClip;
399 o.dc = m_dc.grabRef();
403 void gPainter::flush()
406 o.opcode = gOpcode::flush;
407 o.dc = m_dc.grabRef();
411 void gPainter::waitVSync()
414 o.opcode = gOpcode::waitVSync;
415 o.dc = m_dc.grabRef();
419 void gPainter::flip()
422 o.opcode = gOpcode::flip;
423 o.dc = m_dc.grabRef();
427 void gPainter::notify()
430 o.opcode = gOpcode::notify;
431 o.dc = m_dc.grabRef();
438 o.opcode = gOpcode::flush;
439 o.dc = m_dc.grabRef();
447 gDC::gDC(gPixmap *pixmap): m_pixmap(pixmap)
455 void gDC::exec(gOpcode *o)
459 case gOpcode::setBackgroundColor:
460 m_background_color = o->parm.setColor->color;
461 delete o->parm.setColor;
463 case gOpcode::setForegroundColor:
464 m_foreground_color = o->parm.setColor->color;
465 delete o->parm.setColor;
467 case gOpcode::setBackgroundColorRGB:
468 m_background_color = m_pixmap->surface->clut.findColor(o->parm.setColorRGB->color);
469 delete o->parm.setColorRGB;
471 case gOpcode::setForegroundColorRGB:
472 m_foreground_color = m_pixmap->surface->clut.findColor(o->parm.setColorRGB->color);
473 delete o->parm.setColorRGB;
475 case gOpcode::setFont:
476 m_current_font = o->parm.setFont->font;
477 o->parm.setFont->font->Release();
478 delete o->parm.setFont;
480 case gOpcode::renderText:
482 ePtr<eTextPara> para = new eTextPara(o->parm.renderText->area);
483 int flags = o->parm.renderText->flags;
484 assert(m_current_font);
485 para->setFont(m_current_font);
486 para->renderString(o->parm.renderText->text, (flags & gPainter::RT_WRAP) ? RS_WRAP : 0);
488 if (flags & gPainter::RT_HALIGN_RIGHT)
489 para->realign(eTextPara::dirRight);
490 else if (flags & gPainter::RT_HALIGN_CENTER)
491 para->realign(eTextPara::dirCenter);
492 else if (flags & gPainter::RT_HALIGN_BLOCK)
493 para->realign(eTextPara::dirBlock);
495 ePoint offset = m_current_offset;
497 if (o->parm.renderText->flags & gPainter::RT_VALIGN_CENTER)
499 eRect bbox = para->getBoundBox();
500 int vcentered_top = o->parm.renderText->area.top() + ((o->parm.renderText->area.height() - bbox.height()) / 2);
501 int correction = vcentered_top - bbox.top();
502 offset += ePoint(0, correction);
504 para->blit(*this, offset, getRGB(m_background_color), getRGB(m_foreground_color));
505 delete o->parm.renderText;
508 case gOpcode::renderPara:
510 o->parm.renderPara->textpara->blit(*this, o->parm.renderPara->offset + m_current_offset, getRGB(m_background_color), getRGB(m_foreground_color));
511 o->parm.renderPara->textpara->Release();
512 delete o->parm.renderPara;
517 eRect area = o->parm.fill->area;
518 area.moveBy(m_current_offset);
519 gRegion clip = m_current_clip & area;
520 m_pixmap->fill(clip, m_foreground_color);
524 case gOpcode::fillRegion:
526 o->parm.fillRegion->region.moveBy(m_current_offset);
527 gRegion clip = m_current_clip & o->parm.fillRegion->region;
528 m_pixmap->fill(clip, m_foreground_color);
529 delete o->parm.fillRegion;
533 m_pixmap->fill(m_current_clip, m_background_color);
539 // this code should be checked again but i'm too tired now
541 o->parm.blit->position += m_current_offset;
543 if (o->parm.blit->clip.valid())
545 o->parm.blit->clip.moveBy(m_current_offset);
546 clip.intersect(gRegion(o->parm.blit->clip), m_current_clip);
548 clip = m_current_clip;
550 m_pixmap->blit(*o->parm.blit->pixmap, o->parm.blit->position, clip, o->parm.blit->flags);
551 o->parm.blit->pixmap->Release();
555 case gOpcode::setPalette:
556 if (o->parm.setPalette->palette->start > m_pixmap->surface->clut.colors)
557 o->parm.setPalette->palette->start = m_pixmap->surface->clut.colors;
558 if (o->parm.setPalette->palette->colors > (m_pixmap->surface->clut.colors-o->parm.setPalette->palette->start))
559 o->parm.setPalette->palette->colors = m_pixmap->surface->clut.colors-o->parm.setPalette->palette->start;
560 if (o->parm.setPalette->palette->colors)
561 memcpy(m_pixmap->surface->clut.data+o->parm.setPalette->palette->start, o->parm.setPalette->palette->data, o->parm.setPalette->palette->colors*sizeof(gRGB));
563 delete[] o->parm.setPalette->palette->data;
564 delete o->parm.setPalette->palette;
565 delete o->parm.setPalette;
567 case gOpcode::mergePalette:
568 m_pixmap->mergePalette(*o->parm.mergePalette->target);
569 o->parm.mergePalette->target->Release();
570 delete o->parm.mergePalette;
574 ePoint start = o->parm.line->start + m_current_offset, end = o->parm.line->end + m_current_offset;
575 m_pixmap->line(m_current_clip, start, end, m_foreground_color);
579 case gOpcode::addClip:
580 m_clip_stack.push(m_current_clip);
581 o->parm.clip->region.moveBy(m_current_offset);
582 m_current_clip &= o->parm.clip->region;
585 case gOpcode::setClip:
586 o->parm.clip->region.moveBy(m_current_offset);
587 m_current_clip = o->parm.clip->region & eRect(ePoint(0, 0), m_pixmap->size());
590 case gOpcode::popClip:
591 if (!m_clip_stack.empty())
593 m_current_clip = m_clip_stack.top();
597 case gOpcode::setOffset:
598 if (o->parm.setOffset->rel)
599 m_current_offset += o->parm.setOffset->value;
601 m_current_offset = o->parm.setOffset->value;
602 delete o->parm.setOffset;
604 case gOpcode::waitVSync:
611 eFatal("illegal opcode %d. expect memory leak!", o->opcode);
615 gRGB gDC::getRGB(gColor col)
617 if ((!m_pixmap) || (!m_pixmap->surface->clut.data))
618 return gRGB(col, col, col);
621 eFatal("bla transp");
622 return gRGB(0, 0, 0, 0xFF);
624 return m_pixmap->surface->clut.data[col];
629 eAutoInitPtr<gRC> init_grc(eAutoInitNumbers::graphic, "gRC");