int eSubtitleWidget::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { ePtr<eWindowStyle> style; gPainter &painter = *(gPainter*)data2; getStyle(style); eWidget::event(event, data, data2); std::string configvalue; int rt_halignment_flag; configvalue = eConfigManager::getConfigValue("config.subtitles.subtitle_alignment"); if (configvalue == "right") rt_halignment_flag = gPainter::RT_HALIGN_RIGHT; else if (configvalue == "left") rt_halignment_flag = gPainter::RT_HALIGN_LEFT; else rt_halignment_flag = gPainter::RT_HALIGN_CENTER; int borderwidth = eConfigManager::getConfigIntValue("config.subtitles.subtitle_borderwidth", 2); int fontsize = eConfigManager::getConfigIntValue("config.subtitles.subtitle_fontsize", 34); if (m_pixmap) { eRect r = m_pixmap_dest; r.scale(size().width(), 720, size().height(), 576); painter.blitScale(m_pixmap, r); } else if (m_page_ok) { unsigned int elements = m_page.m_elements.size(); subtitleStyles[Subtitle_TTX].font->pointSize=fontsize; painter.setFont(subtitleStyles[Subtitle_TTX].font); for (unsigned int i = 0; i < elements; ++i) { eDVBTeletextSubtitlePageElement &element = m_page.m_elements[i]; if (!element.m_text.empty()) { eRect &area = element.m_area; if (!subtitleStyles[Subtitle_TTX].have_foreground_color) painter.setForegroundColor(element.m_color); else painter.setForegroundColor(subtitleStyles[Subtitle_TTX].foreground_color); painter.renderText(area, element.m_text, gPainter::RT_WRAP|gPainter::RT_VALIGN_BOTTOM|rt_halignment_flag, subtitleStyles[Subtitle_TTX].border_color, borderwidth); } } } else if (m_pango_page_ok) { int elements = m_pango_page.m_elements.size(); subfont_t face; for (int i=0; i<elements; ++i) { face = Subtitle_Regular; ePangoSubtitlePageElement &element = m_pango_page.m_elements[i]; std::string text = element.m_pango_line; text = replace_all(text, "'", "'"); text = replace_all(text, """, "\""); text = replace_all(text, "&", "&"); text = replace_all(text, "<", "<"); text = replace_all(text, ">", ">"); switch (eConfigManager::getConfigIntValue("config.subtitles.pango_subtitle_colors", 1)) { default: case 0: /* use yellow for italic, cyan for bold and green for underscore */ text = replace_all(text, "<i>", (std::string) gRGB(255,255,0)); text = replace_all(text, "<b>", (std::string) gRGB(0,255,255)); text = replace_all(text, "<u>", (std::string) gRGB(0,255,0)); text = replace_all(text, "</i>", (std::string) gRGB(255,255,255)); text = replace_all(text, "</b>", (std::string) gRGB(255,255,255)); text = replace_all(text, "</u>", (std::string) gRGB(255,255,255)); break; case 2: /* yellow */ text = (std::string) gRGB(255, 255, 0) + text; case 1: /* remove italic, bold, underscore */ text = replace_all(text, "<i>", ""); text = replace_all(text, "<b>", ""); text = replace_all(text, "<u>", ""); text = replace_all(text, "</i>", ""); text = replace_all(text, "</b>", ""); text = replace_all(text, "</u>", ""); break; } subtitleStyles[face].font->pointSize=fontsize; painter.setFont(subtitleStyles[face].font); eRect &area = element.m_area; if ( !subtitleStyles[face].have_foreground_color && element.m_have_color ) painter.setForegroundColor(element.m_color); else painter.setForegroundColor(subtitleStyles[face].foreground_color); painter.renderText(area, text, gPainter::RT_WRAP|gPainter::RT_VALIGN_BOTTOM|rt_halignment_flag, subtitleStyles[face].border_color, borderwidth); } } else if (m_dvb_page_ok) { for (std::list<eDVBSubtitleRegion>::iterator it(m_dvb_page.m_regions.begin()); it != m_dvb_page.m_regions.end(); ++it) { eRect r = eRect(it->m_position, it->m_pixmap->size()); r.scale(size().width(), m_dvb_page.m_display_size.width(), size().height(), m_dvb_page.m_display_size.height()); painter.blitScale(it->m_pixmap, r); } } return 0; } default: return eWidget::event(event, data, data2); } }
void bsodFatal(const char *component) { /* show no more than one bsod while shutting down/crashing */ if (bsodhandled) return; bsodhandled = true; std::string lines = getLogBuffer(); /* find python-tracebacks, and extract " File "-strings */ size_t start = 0; std::string crash_emailaddr = CRASH_EMAILADDR; std::string crash_component = "enigma2"; if (component) crash_component = component; else { while ((start = lines.find("\n File \"", start)) != std::string::npos) { start += 9; size_t end = lines.find("\"", start); if (end == std::string::npos) break; end = lines.rfind("/", end); /* skip a potential prefix to the path */ unsigned int path_prefix = lines.find("/usr/", start); if (path_prefix != std::string::npos && path_prefix < end) start = path_prefix; if (end == std::string::npos) break; std::string filename(lines.substr(start, end - start) + INFOFILE); std::ifstream in(filename.c_str()); if (in.good()) { std::getline(in, crash_emailaddr) && std::getline(in, crash_component); in.close(); } } } FILE *f; const char* crashlog_name; std::ostringstream os; os << "/media/hdd/enigma2_crash_"; os << time(0); os << ".log"; crashlog_name = os.str().c_str(); f = fopen(crashlog_name, "wb"); if (f == NULL) { /* No hardisk. If there is a crash log in /home/root, leave it * alone because we may be in a crash loop and writing this file * all night long may damage the flash. Also, usually the first * crash log is the most interesting one. */ crashlog_name = "/home/root/enigma2_crash.log"; if ((access(crashlog_name, F_OK) == 0) || ((f = fopen(crashlog_name, "wb")) == NULL)) { /* Re-write the same file in /tmp/ because it's expected to * be in RAM. So the first crash log will end up in /home * and the last in /tmp */ crashlog_name = "/tmp/enigma2_crash.log"; f = fopen(crashlog_name, "wb"); } } if (f) { time_t t = time(0); struct tm tm; char tm_str[32]; localtime_r(&t, &tm); strftime(tm_str, sizeof(tm_str), "%a %b %_d %T %Y", &tm); XmlGenerator xml(f); xml.open("openMips"); xml.open("enigma2"); xml.string("crashdate", tm_str); xml.string("compiledate", __DATE__); xml.string("contactemail", crash_emailaddr); xml.comment("Please email this crashlog to above address. Check all sections to remove any sensitive private data!"); xml.string("skin", getConfigString("config.skin.primary_skin", "Default Skin")); xml.string("sourcedate", enigma2_date); xml.string("branch", enigma2_branch); xml.string("rev", enigma2_rev); xml.string("version", PACKAGE_VERSION); xml.close(); xml.open("image"); if(access("/proc/stb/info/boxtype", F_OK) != -1) { xml.stringFromFile("stbmodel", "/proc/stb/info/boxtype"); } else if (access("/proc/stb/info/model", F_OK) != -1) { xml.stringFromFile("stbmodel", "/proc/stb/info/model"); } xml.cDataFromFile("imageversion", "/etc/image-version"); xml.cDataFromCmd("kernelversion", "uname -a"); xml.stringFromFile("kernelcmdline", "/proc/cmdline"); xml.cDataFromCmd("memory", "free -l"); xml.cDataFromCmd("filesystems", "df -h"); xml.cDataFromCmd("mounts", "mount"); xml.cDataFromCmd("nimsockets", "cat /proc/bus/nim_sockets"); xml.cDataFromCmd("networkifconfig", "ifconfig"); xml.cDataFromFile("networkinterfaces", "/etc/network/interfaces"); xml.cDataFromFile("dns", "/etc/resolv.conf"); xml.cDataFromFile("defaultgateway", "/etc/default_gw"); xml.close(); xml.open("settings"); xml.cDataFromCmd("enigma2settings", "cat /etc/enigma2/settings"); xml.close(); xml.open("software"); xml.cDataFromCmd("enigma2software", "opkg list-installed 'enigma2*'"); xml.cDataFromCmd("gstreamersoftware", "opkg list-installed 'gst*'"); xml.close(); xml.open("crashlogs"); xml.cDataFromString("enigma2crashlog", getLogBuffer()); xml.close(); xml.close(); fclose(f); } ePtr<gMainDC> my_dc; gMainDC::getInstance(my_dc); gPainter p(my_dc); p.resetOffset(); p.resetClip(eRect(ePoint(0, 0), my_dc->size())); p.setBackgroundColor(gRGB(0x27408B)); p.setForegroundColor(gRGB(0xFFFFFF)); int hd = my_dc->size().width() == 1920; ePtr<gFont> font = new gFont("Regular", hd ? 30 : 20); p.setFont(font); p.clear(); eRect usable_area = eRect(hd ? 30 : 100, hd ? 30 : 70, my_dc->size().width() - (hd ? 60 : 150), hd ? 150 : 100); os.str(""); os.clear(); os << "We are really sorry. Your STB encountered " "a software problem, and needs to be restarted.\n" "Please attach " << crashlog_name << " " << crash_emailaddr << ".\n" "Your STB restarts in 10 seconds!\n" "Component: " << crash_component; p.renderText(usable_area, os.str().c_str(), gPainter::RT_WRAP|gPainter::RT_HALIGN_LEFT); usable_area = eRect(hd ? 30 : 100, hd ? 180 : 170, my_dc->size().width() - (hd ? 60 : 180), my_dc->size().height() - (hd ? 30 : 20)); int i; start = std::string::npos + 1; for (i=0; i<20; ++i) { start = lines.rfind('\n', start - 1); if (start == std::string::npos) { start = 0; break; } } font = new gFont("Regular", hd ? 21 : 14); p.setFont(font); p.renderText(usable_area, lines.substr(start), gPainter::RT_HALIGN_LEFT); sleep(10); /* * When 'component' is NULL, we are called because of a python exception. * In that case, we'd prefer to to a clean shutdown of the C++ objects, * and this should be safe, because the crash did not occur in the * C++ part. * However, when we got here for some other reason, a segfault probably, * we prefer to stop immediately instead of performing a clean shutdown. * We'd risk destroying things with every additional instruction we're * executing here. */ if (component) raise(SIGKILL); }
int ePositionGauge::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { ePtr<eWindowStyle> style; gPainter &painter = *(gPainter*)data2; eSize s(size()); getStyle(style); eWidget::event(evtPaint, data, data2); style->setStyle(painter, eWindowStyle::styleLabel); // TODO - own style // painter.fill(eRect(0, 10, s.width(), s.height()-20)); pts_t in = 0, out = 0; int xm, xm_last = -1; std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); while (1) { if (i == m_cue_entries.end()) out = m_length; else { if (i->what == 0) /* in */ { in = i++->where; continue; } else if (i->what == 1) /* out */ out = i++->where; else /* mark or last */ { xm = scale(i->where); if (i->what == 2) { painter.setForegroundColor(gRGB(0xFF8080)); if (xm - 2 < xm_last) /* Make sure last is not overdrawn */ painter.fill(eRect(xm_last, 0, 2 + xm - xm_last, s.height())); else painter.fill(eRect(xm - 2, 0, 4, s.height())); } else if (i->what == 3) { painter.setForegroundColor(gRGB(0x80FF80)); painter.fill(eRect(xm - 1, 0, 3, s.height())); xm_last = xm + 2; } i++; continue; } } if (m_have_foreground_color) { painter.setForegroundColor(gRGB(m_foreground_color)); int xi = scale(in), xo = scale(out); painter.fill(eRect(xi, (s.height()-4) / 2, xo-xi, 4)); } in = m_length; if (i == m_cue_entries.end()) break; } // painter.setForegroundColor(gRGB(0x00000000)); if (m_have_foreground_color) { painter.setForegroundColor(gRGB(0x225b7395)); painter.fill(eRect(s.width() - 2, 2, s.width() - 1, s.height() - 4)); painter.fill(eRect(0, 2, 2, s.height() - 4)); } #if 0 // border if (m_have_border_color) painter.setForegroundColor(m_border_color); painter.fill(eRect(0, 0, s.width(), m_border_width)); painter.fill(eRect(0, m_border_width, m_border_width, s.height()-m_border_width)); painter.fill(eRect(m_border_width, s.height()-m_border_width, s.width()-m_border_width, m_border_width)); painter.fill(eRect(s.width()-m_border_width, m_border_width, m_border_width, s.height()-m_border_width)); #endif return 0; } case evtChangedPosition: return 0; default: return eWidget::event(event, data, data2); } }
int main(int argc, char **argv) { #ifdef MEMLEAK_CHECK atexit(DumpUnfreed); #endif #ifdef OBJECT_DEBUG atexit(object_dump); #endif gst_init(&argc, &argv); // set pythonpath if unset setenv("PYTHONPATH", eEnv::resolve("${libdir}/enigma2/python").c_str(), 0); printf("PYTHONPATH: %s\n", getenv("PYTHONPATH")); bsodLogInit(); ePython python; eMain main; #if 1 ePtr<gMainDC> my_dc; gMainDC::getInstance(my_dc); //int double_buffer = my_dc->haveDoubleBuffering(); ePtr<gLCDDC> my_lcd_dc; gLCDDC::getInstance(my_lcd_dc); /* ok, this is currently hardcoded for arabic. */ /* some characters are wrong in the regular font, force them to use the replacement font */ for (int i = 0x60c; i <= 0x66d; ++i) eTextPara::forceReplacementGlyph(i); eTextPara::forceReplacementGlyph(0xfdf2); for (int i = 0xfe80; i < 0xff00; ++i) eTextPara::forceReplacementGlyph(i); eWidgetDesktop dsk(my_dc->size()); eWidgetDesktop dsk_lcd(my_lcd_dc->size()); dsk.setStyleID(0); dsk_lcd.setStyleID(my_lcd_dc->size().width() == 96 ? 2 : 1); /* if (double_buffer) { eDebug(" - double buffering found, enable buffered graphics mode."); dsk.setCompositionMode(eWidgetDesktop::cmBuffered); } */ wdsk = &dsk; lcddsk = &dsk_lcd; dsk.setDC(my_dc); dsk_lcd.setDC(my_lcd_dc); dsk.setBackgroundColor(gRGB(0,0,0,0xFF)); #endif /* redrawing is done in an idle-timer, so we have to set the context */ dsk.setRedrawTask(main); dsk_lcd.setRedrawTask(main); eDebug("Loading spinners..."); { int i; #define MAX_SPINNER 64 ePtr<gPixmap> wait[MAX_SPINNER]; for (i=0; i<MAX_SPINNER; ++i) { char filename[64]; std::string rfilename; snprintf(filename, sizeof(filename), "${datadir}/enigma2/skin_default/spinner/wait%d.png", i + 1); rfilename = eEnv::resolve(filename); loadPNG(wait[i], rfilename.c_str()); if (!wait[i]) { if (!i) eDebug("failed to load %s! (%m)", rfilename.c_str()); else eDebug("found %d spinner!\n", i); break; } } if (i) my_dc->setSpinner(eRect(ePoint(100, 100), wait[0]->size()), wait, i); else my_dc->setSpinner(eRect(100, 100, 0, 0), wait, 1); } gRC::getInstance()->setSpinnerDC(my_dc); eRCInput::getInstance()->keyEvent.connect(slot(keyEvent)); printf("executing main\n"); bsodCatchSignals(); setIoPrio(IOPRIO_CLASS_BE, 3); /* start at full size */ eVideoWidget::setFullsize(true); // python.execute("mytest", "__main__"); python.execFile(eEnv::resolve("${libdir}/enigma2/python/mytest.py").c_str()); /* restore both decoders to full size */ eVideoWidget::setFullsize(true); if (exit_code == 5) /* python crash */ { eDebug("(exit code 5)"); bsodFatal(0); } dsk.paint(); dsk_lcd.paint(); { gPainter p(my_lcd_dc); p.resetClip(eRect(ePoint(0, 0), my_lcd_dc->size())); p.clear(); p.flush(); } return exit_code; }
void eProgress::redrawWidget(gPainter *target, const eRect &area) { switch (direction) { case 0: { int range = size.width() - border * 2; if (sliderPixmap) range -= sliderPixmap->x; int st = start * range / 100; if (st < 0) st = 0; if (st > range) st = range; int dh = perc * range / 100; if (dh < 0) dh = 0; if ((dh + st) > range) dh = range - st; if (pixmap) { target->blit(*pixmap, ePoint(0, 0), eRect(0, 0, border + dh + st, size.height()), gPixmap::blitAlphaTest); } if (sliderPixmap) { int x = border + st + dh; int y = (size.height() - sliderPixmap->y) / 2; if (x < 0) x = 0; if (y < 0) y = 0; if (x > size.width() - sliderPixmap->x) x = size.width() - sliderPixmap->x; if (y > size.height() - sliderPixmap->y) y = size.height() - sliderPixmap->y; target->blit(*sliderPixmap, ePoint(x, y), area, gPixmap::blitAlphaTest); } else { if (left >= 0) { target->setForegroundColor(left); target->fill(eRect(border + st, border, dh, size.height() - border * 2)); } target->setForegroundColor(right); target->fill(eRect(border + dh + st, border, size.width() - border * 2 - dh - st, size.height() - border * 2)); if (st) { target->fill(eRect(border, border, st, size.height() - border * 2)); } } break; } case 1: { int range = size.height() - border * 2; if (sliderPixmap) range -= sliderPixmap->y; int st = start * range / 100; if (st < 0) st = 0; if (st > range) st = range; int dh = perc * range / 100; if (dh < 0) dh = 0; if ((dh + st) > range) dh = range - st; if (pixmap) { target->blit(*pixmap, ePoint(0, 0), eRect(0, 0, size.width(), border + dh + st), gPixmap::blitAlphaTest); } if (sliderPixmap) { int x = (size.width() - sliderPixmap->x) / 2; int y = border + st + dh; if (x < 0) x = 0; if (y < 0) y = 0; if (x > size.width() - sliderPixmap->x) x = size.width() - sliderPixmap->x; if (y > size.height() - sliderPixmap->y) y = size.height() - sliderPixmap->y; target->blit(*sliderPixmap, ePoint(x, y), area, gPixmap::blitAlphaTest); } else { if (left >= 0) { target->setForegroundColor(left); target->fill(eRect(border, border+st, size.width() - border * 2, dh)); } target->setForegroundColor(right); target->fill(eRect(border, border+dh+st, size.width() - border * 2, size.height() - border * 2 - dh - st)); if (st) { target->fill(eRect(border, border, size.width() - border * 2, st)); } } break; } } if (border) { /* draw border */ target->setForegroundColor(getForegroundColor()); target->fill(eRect(0, 0, size.width(), border)); target->fill(eRect(0, border, border, size.height() - border)); target->fill(eRect(border, size.height() - border, size.width() - border, border)); target->fill(eRect(size.width() - border, border, border, size.height() - border)); } }
int eSubtitleWidget::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { ePtr<eWindowStyle> style; gPainter &painter = *(gPainter*)data2; getStyle(style); eWidget::event(event, data, data2); std::string configvalue; int rt_halignment_flag; if (ePythonConfigQuery::getConfigValue("config.subtitles.subtitle_alignment", configvalue)) configvalue = "center"; if (configvalue == "center") rt_halignment_flag = gPainter::RT_HALIGN_CENTER; else if (configvalue == "left") rt_halignment_flag = gPainter::RT_HALIGN_LEFT; else rt_halignment_flag = gPainter::RT_HALIGN_RIGHT; int borderwidth = 2; if (!ePythonConfigQuery::getConfigValue("config.subtitles.subtitle_borderwidth", configvalue)) { borderwidth = atoi(configvalue.c_str()); } int fontsize = 34; if (!ePythonConfigQuery::getConfigValue("config.subtitles.subtitle_fontsize", configvalue)) { fontsize = atoi(configvalue.c_str()); } if (m_pixmap) { eRect r = m_pixmap_dest; r.scale(size().width(), 720, size().height(), 576); painter.blitScale(m_pixmap, r); } else if (m_page_ok) { unsigned int elements = m_page.m_elements.size(); subtitleStyles[Subtitle_TTX].font->pointSize=fontsize; painter.setFont(subtitleStyles[Subtitle_TTX].font); for (unsigned int i = 0; i < elements; ++i) { eDVBTeletextSubtitlePageElement &element = m_page.m_elements[i]; if (!element.m_text.empty()) { eRect &area = element.m_area; if (!subtitleStyles[Subtitle_TTX].have_foreground_color) painter.setForegroundColor(element.m_color); else painter.setForegroundColor(subtitleStyles[Subtitle_TTX].foreground_color); painter.renderText(area, element.m_text, gPainter::RT_WRAP|gPainter::RT_VALIGN_BOTTOM|rt_halignment_flag, subtitleStyles[Subtitle_TTX].border_color, borderwidth); } } } else if (m_pango_page_ok) { int elements = m_pango_page.m_elements.size(); subfont_t face; for (int i=0; i<elements; ++i) { face = Subtitle_Regular; ePangoSubtitlePageElement &element = m_pango_page.m_elements[i]; std::string text = element.m_pango_line; text = replace_all(text, "'", "'"); text = replace_all(text, """, "\""); text = replace_all(text, "&", "&"); text = replace_all(text, "<", "<"); text = replace_all(text, ">", ">"); bool yellow_color = (ePythonConfigQuery::getConfigValue("config.subtitles.pango_subtitles_yellow", configvalue) >= 0 && configvalue == "True"); if (yellow_color) text = (std::string) gRGB(255,255,0) + text; text = replace_all(text, "<i>", yellow_color ? "" : (std::string) gRGB(0,255,255)); text = replace_all(text, "<b>", yellow_color ? "" : (std::string) gRGB(255,255,0)); text = replace_all(text, "</i>", yellow_color ? "" : (std::string) gRGB(255,255,255)); text = replace_all(text, "</b>", yellow_color ? "" : (std::string) gRGB(255,255,255)); subtitleStyles[face].font->pointSize=fontsize; painter.setFont(subtitleStyles[face].font); eRect &area = element.m_area; if ( !subtitleStyles[face].have_foreground_color && element.m_have_color ) painter.setForegroundColor(element.m_color); else painter.setForegroundColor(subtitleStyles[face].foreground_color); painter.renderText(area, text, gPainter::RT_WRAP|gPainter::RT_VALIGN_BOTTOM|rt_halignment_flag, subtitleStyles[face].border_color, borderwidth); } } else if (m_dvb_page_ok) { for (std::list<eDVBSubtitleRegion>::iterator it(m_dvb_page.m_regions.begin()); it != m_dvb_page.m_regions.end(); ++it) { eRect r = eRect(it->m_position, it->m_pixmap->size()); r.scale(size().width(), m_dvb_page.m_display_size.width(), size().height(), m_dvb_page.m_display_size.height()); painter.blitScale(it->m_pixmap, r); } } return 0; } default: return eWidget::event(event, data, data2); } }
void gDC::exec(const gOpcode *o) { switch (o->opcode) { case gOpcode::setBackgroundColor: m_background_color = o->parm.setColor->color; m_background_color_rgb = getRGB(m_background_color); delete o->parm.setColor; break; case gOpcode::setForegroundColor: m_foreground_color = o->parm.setColor->color; m_background_color_rgb = getRGB(m_foreground_color); delete o->parm.setColor; break; case gOpcode::setBackgroundColorRGB: if (m_pixmap->needClut()) m_background_color = m_pixmap->surface->clut.findColor(o->parm.setColorRGB->color); m_background_color_rgb = o->parm.setColorRGB->color; delete o->parm.setColorRGB; break; case gOpcode::setForegroundColorRGB: if (m_pixmap->needClut()) m_foreground_color = m_pixmap->surface->clut.findColor(o->parm.setColorRGB->color); m_foreground_color_rgb = o->parm.setColorRGB->color; delete o->parm.setColorRGB; break; case gOpcode::setFont: m_current_font = o->parm.setFont->font; o->parm.setFont->font->Release(); delete o->parm.setFont; break; case gOpcode::renderText: { ePtr<eTextPara> para = new eTextPara(o->parm.renderText->area); int flags = o->parm.renderText->flags; ASSERT(m_current_font); para->setFont(m_current_font); para->renderString(o->parm.renderText->text, (flags & gPainter::RT_WRAP) ? RS_WRAP : 0); if (o->parm.renderText->text) free(o->parm.renderText->text); if (flags & gPainter::RT_HALIGN_RIGHT) para->realign(eTextPara::dirRight); else if (flags & gPainter::RT_HALIGN_CENTER) para->realign(eTextPara::dirCenter); else if (flags & gPainter::RT_HALIGN_BLOCK) para->realign(eTextPara::dirBlock); ePoint offset = m_current_offset; if (o->parm.renderText->flags & gPainter::RT_VALIGN_CENTER) { eRect bbox = para->getBoundBox(); int vcentered_top = o->parm.renderText->area.top() + ((o->parm.renderText->area.height() - bbox.height()) / 2); int correction = vcentered_top - bbox.top(); offset += ePoint(0, correction); } para->blit(*this, offset, m_background_color_rgb, m_foreground_color_rgb); delete o->parm.renderText; break; } case gOpcode::renderPara: { o->parm.renderPara->textpara->blit(*this, o->parm.renderPara->offset + m_current_offset, m_background_color_rgb, m_foreground_color_rgb); o->parm.renderPara->textpara->Release(); delete o->parm.renderPara; break; } case gOpcode::fill: { eRect area = o->parm.fill->area; area.moveBy(m_current_offset); gRegion clip = m_current_clip & area; if (m_pixmap->needClut()) m_pixmap->fill(clip, m_foreground_color); else m_pixmap->fill(clip, m_foreground_color_rgb); 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; if (m_pixmap->needClut()) m_pixmap->fill(clip, m_foreground_color); else m_pixmap->fill(clip, m_foreground_color_rgb); delete o->parm.fillRegion; break; } case gOpcode::clear: if (m_pixmap->needClut()) m_pixmap->fill(m_current_clip, m_background_color); else m_pixmap->fill(m_current_clip, m_background_color_rgb); delete o->parm.fill; break; case gOpcode::blit: { gRegion clip; // this code should be checked again but i'm too tired now o->parm.blit->position.moveBy(m_current_offset); if (o->parm.blit->clip.valid()) { o->parm.blit->clip.moveBy(m_current_offset); clip.intersect(gRegion(o->parm.blit->clip), m_current_clip); } else clip = m_current_clip; m_pixmap->blit(*o->parm.blit->pixmap, o->parm.blit->position, clip, o->parm.blit->flags); o->parm.blit->pixmap->Release(); delete o->parm.blit; break; } case gOpcode::setPalette: if (o->parm.setPalette->palette->start > m_pixmap->surface->clut.colors) o->parm.setPalette->palette->start = m_pixmap->surface->clut.colors; if (o->parm.setPalette->palette->colors > (m_pixmap->surface->clut.colors-o->parm.setPalette->palette->start)) o->parm.setPalette->palette->colors = m_pixmap->surface->clut.colors-o->parm.setPalette->palette->start; if (o->parm.setPalette->palette->colors) memcpy(m_pixmap->surface->clut.data+o->parm.setPalette->palette->start, o->parm.setPalette->palette->data, o->parm.setPalette->palette->colors*sizeof(gRGB)); delete[] o->parm.setPalette->palette->data; delete o->parm.setPalette->palette; delete o->parm.setPalette; break; case gOpcode::mergePalette: m_pixmap->mergePalette(*o->parm.mergePalette->target); o->parm.mergePalette->target->Release(); delete o->parm.mergePalette; break; case gOpcode::line: { ePoint start = o->parm.line->start + m_current_offset, end = o->parm.line->end + m_current_offset; m_pixmap->line(m_current_clip, start, end, m_foreground_color); delete o->parm.line; break; } case gOpcode::addClip: m_clip_stack.push(m_current_clip); o->parm.clip->region.moveBy(m_current_offset); m_current_clip &= o->parm.clip->region; delete o->parm.clip; break; case gOpcode::setClip: o->parm.clip->region.moveBy(m_current_offset); m_current_clip = o->parm.clip->region & eRect(ePoint(0, 0), m_pixmap->size()); delete o->parm.clip; break; case gOpcode::popClip: if (!m_clip_stack.empty()) { m_current_clip = m_clip_stack.top(); m_clip_stack.pop(); } break; case gOpcode::setOffset: if (o->parm.setOffset->rel) m_current_offset += o->parm.setOffset->value; else m_current_offset = o->parm.setOffset->value; delete o->parm.setOffset; break; case gOpcode::waitVSync: break; case gOpcode::flip: break; case gOpcode::flush: break; case gOpcode::enableSpinner: enableSpinner(); break; case gOpcode::disableSpinner: disableSpinner(); break; case gOpcode::incrementSpinner: incrementSpinner(); break; default: eFatal("illegal opcode %d. expect memory leak!", o->opcode); } }
int eSlider::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { ePtr<eWindowStyle> style; eSize s(size()); getStyle(style); /* paint background */ eWidget::event(evtPaint, data, data2); gPainter &painter = *(gPainter*)data2; style->setStyle(painter, eWindowStyle::styleLabel); // TODO - own style if (!m_pixmap) painter.fill(m_currently_filled); else painter.blit(m_pixmap, ePoint(0, 0), m_currently_filled.extends, isTransparent() ? gPainter::BT_ALPHATEST : 0); // border if (m_have_border_color) painter.setForegroundColor(m_border_color); painter.fill(eRect(0, 0, s.width(), m_border_width)); painter.fill(eRect(0, m_border_width, m_border_width, s.height()-m_border_width)); painter.fill(eRect(m_border_width, s.height()-m_border_width, s.width()-m_border_width, m_border_width)); painter.fill(eRect(s.width()-m_border_width, m_border_width, m_border_width, s.height()-m_border_width)); return 0; } case evtChangedSlider: { int num_pix = 0, start_pix = 0; gRegion old_currently_filled = m_currently_filled; int pixsize = (m_orientation == orHorizontal) ? size().width() : size().height(); if (m_min < m_max) { int val_range = m_max - m_min; num_pix = (pixsize * (m_value - m_start) + val_range - 1) / val_range; /* properly round up */ start_pix = (pixsize * m_start + val_range - 1) / val_range; if (m_orientation_swapped) start_pix = pixsize - num_pix - start_pix; } if (start_pix < 0) { num_pix += start_pix; start_pix = 0; } if (num_pix < 0) num_pix = 0; if (m_orientation == orHorizontal) m_currently_filled = eRect(start_pix, 0, num_pix, pixsize); else m_currently_filled = eRect(0, start_pix, pixsize, num_pix); // 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 eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected) { painter.clip(eRect(offset, m_itemsize)); int marked = 0; if (m_current_marked && selected) marked = 2; else if (cursorValid() && isMarked(*m_cursor)) { if (selected) marked = 2; else marked = 1; } else style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal); eListboxStyle *local_style = 0; /* get local listbox style, if present */ if (m_listbox) local_style = m_listbox->getLocalStyle(); if (marked == 1) // marked { style.setStyle(painter, eWindowStyle::styleListboxMarked); if (m_color_set[markedForeground]) painter.setForegroundColor(m_color[markedForeground]); if (m_color_set[markedBackground]) painter.setBackgroundColor(m_color[markedBackground]); } else if (marked == 2) // marked and selected { style.setStyle(painter, eWindowStyle::styleListboxMarkedAndSelected); if (m_color_set[markedForegroundSelected]) painter.setForegroundColor(m_color[markedForegroundSelected]); if (m_color_set[markedBackgroundSelected]) painter.setBackgroundColor(m_color[markedBackgroundSelected]); } else if (local_style) { if (selected) { /* if we have a local background color set, use that. */ if (local_style->m_background_color_selected_set) painter.setBackgroundColor(local_style->m_background_color_selected); /* same for foreground */ if (local_style->m_foreground_color_selected_set) painter.setForegroundColor(local_style->m_foreground_color_selected); } else { /* if we have a local background color set, use that. */ if (local_style->m_background_color_set) painter.setBackgroundColor(local_style->m_background_color); /* same for foreground */ if (local_style->m_foreground_color_set) painter.setForegroundColor(local_style->m_foreground_color); } } if (!local_style || !local_style->m_transparent_background) /* if we have no transparent background */ { /* blit background picture, if available (otherwise, clear only) */ if (local_style && local_style->m_background) painter.blit(local_style->m_background, offset, eRect(), 0); else painter.clear(); } else { if (local_style->m_background) painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHATEST); else if (selected && !local_style->m_selection) painter.clear(); } if (cursorValid()) { /* get service information */ ePtr<iStaticServiceInformation> service_info; m_service_center->info(*m_cursor, service_info); eServiceReference ref = *m_cursor; bool isMarker = ref.flags & eServiceReference::isMarker; bool isPlayable = !(ref.flags & eServiceReference::isDirectory || isMarker); bool isRecorded = m_record_indicator_mode && isPlayable && checkServiceIsRecorded(ref); ePtr<eServiceEvent> evt; bool serviceAvail = true; if (!marked && isPlayable && service_info && m_is_playable_ignore.valid() && !service_info->isPlayable(*m_cursor, m_is_playable_ignore)) { if (m_color_set[serviceNotAvail]) painter.setForegroundColor(m_color[serviceNotAvail]); else painter.setForegroundColor(gRGB(0xbbbbbb)); serviceAvail = false; } if (m_record_indicator_mode == 3 && isRecorded) { if (m_color_set[serviceRecorded]) painter.setForegroundColor(m_color[serviceRecorded]); else painter.setForegroundColor(gRGB(0xb40431)); } if (selected && local_style && local_style->m_selection) painter.blit(local_style->m_selection, offset, eRect(), gPainter::BT_ALPHATEST); int xoffset=0; // used as offset when painting the folder/marker symbol or the serviceevent progress time_t now = time(0); for (int e = 0; e != celServiceTypePixmap; ++e) { if (m_element_font[e]) { int flags=gPainter::RT_VALIGN_CENTER; int yoffs = 0; eRect &area = m_element_position[e]; std::string text = "<n/a>"; switch (e) { case celServiceNumber: { if (area.width() <= 0) continue; // no point in going on if we won't paint anything if( m_cursor->getChannelNum() == 0 ) continue; char buffer[15]; snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); text = buffer; flags|=gPainter::RT_HALIGN_RIGHT; break; } case celServiceName: { if (service_info) service_info->getName(*m_cursor, text); break; } case celServiceInfo: { if ( isPlayable && service_info && !service_info->getEvent(*m_cursor, evt) ) { std::string name = evt->getEventName(); if (name.empty()) continue; text = evt->getEventName(); if (serviceAvail) { if (!selected && m_color_set[eventForeground]) painter.setForegroundColor(m_color[eventForeground]); else if (selected && m_color_set[eventForegroundSelected]) painter.setForegroundColor(m_color[eventForegroundSelected]); else painter.setForegroundColor(gRGB(0xe7b53f)); } break; } continue; } case celServiceEventProgressbar: { if (area.width() > 0 && isPlayable && service_info && !service_info->getEvent(*m_cursor, evt)) { char buffer[15]; snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - evt->getBeginTime()) / evt->getDuration())); text = buffer; flags|=gPainter::RT_HALIGN_RIGHT; break; } continue; } } eRect tmp = area; int xoffs = 0; if (e == celServiceName) { xoffs = xoffset; tmp.setWidth(((!isPlayable || !m_column_width) ? tmp.width() : m_column_width < 0 ? area.width() / 2 : m_column_width) - xoffs); } eTextPara *para = new eTextPara(tmp); para->setFont(m_element_font[e]); para->renderString(text.c_str()); if (e == celServiceName) { eRect bbox = para->getBoundBox(); int servicenameWidth = ((!isPlayable || !m_column_width) ? bbox.width() : m_column_width < 0 ? area.width() / 2 : m_column_width); m_element_position[celServiceInfo].setLeft(area.left() + servicenameWidth + 8 + xoffs); m_element_position[celServiceInfo].setTop(area.top()); m_element_position[celServiceInfo].setWidth(area.width() - (servicenameWidth + 8 + xoffs)); m_element_position[celServiceInfo].setHeight(area.height()); if (isPlayable) { //picon stuff if (PyCallable_Check(m_GetPiconNameFunc)) { eRect area = m_element_position[celServiceInfo]; /* PIcons are usually about 100:60. Make it a * bit wider in case the icons are diffently * shaped, and to add a bit of margin between * icon and text. */ const int iconWidth = area.height() * 9 / 5; m_element_position[celServiceInfo].setLeft(area.left() + iconWidth); m_element_position[celServiceInfo].setWidth(area.width() - iconWidth); area = m_element_position[celServiceName]; xoffs += iconWidth; ePyObject pArgs = PyTuple_New(1); PyTuple_SET_ITEM(pArgs, 0, PyString_FromString(ref.toString().c_str())); ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); Py_DECREF(pArgs); if (pRet) { if (PyString_Check(pRet)) { std::string piconFilename = PyString_AS_STRING(pRet); if (!piconFilename.empty()) { ePtr<gPixmap> piconPixmap; loadPNG(piconPixmap, piconFilename.c_str()); if (piconPixmap) { area.moveBy(offset); painter.clip(area); painter.blitScale(piconPixmap, eRect(area.left(), area.top(), iconWidth, area.height()), area, gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO); painter.clippop(); } } } Py_DECREF(pRet); } } //service type marker stuff if (m_servicetype_icon_mode) { int orbpos = m_cursor->getUnsignedData(4) >> 16; const char *filename = ref.path.c_str(); ePtr<gPixmap> &pixmap = (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : (strstr(filename, "://")) ? m_pixmaps[picStream] : (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; if (pixmap) { eSize pixmap_size = pixmap->size(); eRect area = m_element_position[celServiceInfo]; m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + 8); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - 8); int offs = 0; if (m_servicetype_icon_mode == 1) { area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + 8; } else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) offs = offs + m_pixmaps[picCrypto]->size().width() + 8; int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); painter.clip(area); painter.blit(pixmap, ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHATEST); painter.clippop(); } } //crypto icon stuff if (m_crypto_icon_mode && m_pixmaps[picCrypto]) { eSize pixmap_size = m_pixmaps[picCrypto]->size(); eRect area = m_element_position[celServiceInfo]; int offs = 0; if (m_crypto_icon_mode == 1) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + 8); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - 8); area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + 8; } int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); if (service_info->isCrypted()) { if (m_crypto_icon_mode == 2) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + 8); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - 8); } painter.clip(area); painter.blit(m_pixmaps[picCrypto], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHATEST); painter.clippop(); } } //record icon stuff if (isRecorded && m_record_indicator_mode < 3 && m_pixmaps[picRecord]) { eSize pixmap_size = m_pixmaps[picRecord]->size(); eRect area = m_element_position[celServiceInfo]; int offs = 0; if (m_record_indicator_mode == 1) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + 8); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - 8); area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + 8; } int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); if (m_record_indicator_mode == 2) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + 8); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - 8); } painter.clip(area); painter.blit(m_pixmaps[picRecord], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHATEST); painter.clippop(); } } } if (flags & gPainter::RT_HALIGN_RIGHT) para->realign(eTextPara::dirRight); else if (flags & gPainter::RT_HALIGN_CENTER) para->realign(eTextPara::dirCenter); else if (flags & gPainter::RT_HALIGN_BLOCK) para->realign(eTextPara::dirBlock); if (flags & gPainter::RT_VALIGN_CENTER) { eRect bbox = para->getBoundBox(); yoffs = (area.height() - bbox.height()) / 2 - bbox.top(); } painter.renderPara(para, offset+ePoint(xoffs, yoffs)); } else if ((e == celFolderPixmap && m_cursor->flags & eServiceReference::isDirectory) || (e == celMarkerPixmap && m_cursor->flags & eServiceReference::isMarker && !(m_cursor->flags & eServiceReference::isNumberedMarker))) { ePtr<gPixmap> &pixmap = (e == celFolderPixmap) ? m_pixmaps[picFolder] : m_pixmaps[picMarker]; if (pixmap) { eSize pixmap_size = pixmap->size(); eRect area = m_element_position[e == celFolderPixmap ? celServiceName: celServiceNumber]; int correction = (area.height() - pixmap_size.height()) / 2; if (e == celFolderPixmap) xoffset = pixmap_size.width() + 8; area.moveBy(offset); painter.clip(area); painter.blit(pixmap, ePoint(area.left(), offset.y() + correction), area, gPainter::BT_ALPHATEST); painter.clippop(); } } }
void bsodFatal(const char *component) { /* show no more than one bsod while shutting down/crashing */ if (bsodhandled) return; bsodhandled = true; if (!component) component = "Enigma2"; /* Retrieve current ringbuffer state */ const char* logp1; unsigned int logs1; const char* logp2; unsigned int logs2; retrieveLogBuffer(&logp1, &logs1, &logp2, &logs2); FILE *f; std::string crashlog_name; std::ostringstream os; time_t t = time(0); struct tm tm; char tm_str[32]; localtime_r(&t, &tm); strftime(tm_str, sizeof(tm_str), "%Y-%m-%d_%H-%M-%S", &tm); os << getConfigString("config.crash.debug_path", "/home/root/logs/"); os << "Enigma2_crash_"; os << tm_str; os << ".log"; crashlog_name = os.str(); f = fopen(crashlog_name.c_str(), "wb"); if (f == NULL) { /* No hardisk. If there is a crash log in /home/root, leave it * alone because we may be in a crash loop and writing this file * all night long may damage the flash. Also, usually the first * crash log is the most interesting one. */ crashlog_name = "/home/root/logs/Enigma2_crash.log"; if ((access(crashlog_name.c_str(), F_OK) == 0) || ((f = fopen(crashlog_name.c_str(), "wb")) == NULL)) { /* Re-write the same file in /tmp/ because it's expected to * be in RAM. So the first crash log will end up in /home * and the last in /tmp */ crashlog_name = "/tmp/Enigma2_crash.log"; f = fopen(crashlog_name.c_str(), "wb"); } } if (f) { time_t t = time(0); struct tm tm; char tm_str[32]; localtime_r(&t, &tm); strftime(tm_str, sizeof(tm_str), "%a %b %_d %T %Y", &tm); fprintf(f, "OpenBh Enigma2 Crashlog\n\n" "Crashdate = %s\n\n" "%s\n" "Compiled = %s\n" "Skin = %s\n" "Component = %s\n\n" "Kernel CMDline = %s\n" "Nim Sockets = %s\n", tm_str, stringFromFile("/etc/image-version").c_str(), __DATE__, getConfigString("config.skin.primary_skin", "Default Skin").c_str(), component, stringFromFile("/proc/cmdline").c_str(), stringFromFile("/proc/bus/nim_sockets").c_str() ); /* dump the log ringbuffer */ fprintf(f, "\n\n"); if (logp1) fwrite(logp1, 1, logs1, f); if (logp2) fwrite(logp2, 1, logs2, f); /* dump the kernel log */ getKlog(f); fclose(f); } ePtr<gMainDC> my_dc; gMainDC::getInstance(my_dc); gPainter p(my_dc); p.resetOffset(); p.resetClip(eRect(ePoint(0, 0), my_dc->size())); p.setBackgroundColor(gRGB(0x010000)); p.setForegroundColor(gRGB(0xFFFFFF)); int hd = my_dc->size().width() == 1920; ePtr<gFont> font = new gFont("Regular", hd ? 30 : 20); p.setFont(font); p.clear(); eRect usable_area = eRect(hd ? 30 : 100, hd ? 30 : 70, my_dc->size().width() - (hd ? 60 : 150), hd ? 150 : 100); os.str(""); os.clear(); os << "We are really sorry. Your receiver encountered " "a software problem, and needs to be restarted.\n" "Please send the logfile " << crashlog_name << " to " << crash_emailaddr << ".\n" "Your STB restarts in 10 seconds!\n" "Component: " << component; p.renderText(usable_area, os.str().c_str(), gPainter::RT_WRAP|gPainter::RT_HALIGN_LEFT); std::string logtail; int lines = 20; if (logp2) { unsigned int size = logs2; while (size) { const char* r = (const char*)memrchr(logp2, '\n', size); if (r) { size = r - logp2; --lines; if (!lines) { logtail = std::string(r, logs2 - size); break; } } else { logtail = std::string(logp2, logs2); break; } } } if (lines && logp1) { unsigned int size = logs1; while (size) { const char* r = (const char*)memrchr(logp1, '\n', size); if (r) { --lines; size = r - logp1; if (!lines) { logtail += std::string(r, logs1 - size); break; } } else { logtail += std::string(logp1, logs1); break; } } } if (!logtail.empty()) { font = new gFont("Regular", hd ? 21 : 14); p.setFont(font); usable_area = eRect(hd ? 30 : 100, hd ? 180 : 170, my_dc->size().width() - (hd ? 60 : 180), my_dc->size().height() - (hd ? 30 : 20)); p.renderText(usable_area, logtail, gPainter::RT_HALIGN_LEFT); } sleep(10); /* * When 'component' is NULL, we are called because of a python exception. * In that case, we'd prefer to to a clean shutdown of the C++ objects, * and this should be safe, because the crash did not occur in the * C++ part. * However, when we got here for some other reason, a segfault probably, * we prefer to stop immediately instead of performing a clean shutdown. * We'd risk destroying things with every additional instruction we're * executing here. */ if (component) raise(SIGKILL); }
void eListbox::moveSelection(long dir) { /* refuse to do anything without a valid list. */ if (!m_content) return; /* if our list does not have one entry, don't do anything. */ if (!m_items_per_page) return; /* we need the old top/sel to see what we have to redraw */ int oldtop = m_top; int oldsel = m_selected; /* first, move cursor */ switch (dir) { case moveUp: { m_content->cursorMove(-1); if (m_enabled_wrap_around && oldsel == m_content->cursorGet()) // must wrap around ? moveToEnd(); break; } case moveDown: m_content->cursorMove(1); /* ok - we could have reached the end. So we do wrap around. */ if (!m_content->cursorValid()) { if (m_enabled_wrap_around) { m_top = 0; m_content->cursorHome(); } else m_content->cursorMove(-1); } break; case pageUp: if (m_content->cursorGet() >= m_items_per_page) { m_content->cursorMove(-m_items_per_page); m_top -= m_items_per_page; if (m_top < 0) m_top = 0; } else { m_top = 0; m_content->cursorHome(); } break; case moveTop: m_content->cursorHome(); m_top = 0; /* align with top, speeds up process */ break; case pageDown: m_content->cursorMove(m_items_per_page); if (m_content->cursorValid()) break; /* fall through */ case moveEnd: moveToEnd(); break; case justCheck: break; } if (m_content->cursorValid() && !m_content->currentCursorSelectable()) { /* ok, our cursor position is valid (i.e. in list), but not selectable. */ /* when moving up, continue until we found a valid position. */ if ((dir == moveUp) || (dir == pageDown)) { while (m_content->cursorGet()) { m_content->cursorMove(-1); if (m_content->currentCursorSelectable()) { break; } } } else { /* else move down */ while (m_content->cursorValid()) { m_content->cursorMove(+1); if (m_content->currentCursorSelectable()) { break; } } if (!m_content->cursorValid()) m_content->cursorMove(-1); } if (!m_content->currentCursorSelectable()) m_content->cursorSet(oldsel); } /* note that we could be on an invalid cursor position, but we don't care. this only happens on empty lists, and should have almost no side effects. */ /* now, look wether the current selection is out of screen */ m_selected = m_content->cursorGet(); while (m_selected < m_top) { m_top -= m_items_per_page; if (m_top < 0) m_top = 0; } while (m_selected >= m_top + m_items_per_page) /* m_top should be always valid here as it's selected */ m_top += m_items_per_page; if (oldsel != m_selected) /* emit */ selectionChanged(); updateScrollBar(); if (m_top != oldtop) invalidate(); else if (m_selected != oldsel) { /* redraw the old and newly selected */ gRegion inv = eRect(0, m_itemheight * (m_selected-m_top), size().width(), m_itemheight); inv |= eRect(0, m_itemheight * (oldsel-m_top), size().width(), m_itemheight); invalidate(inv); } }
int eListbox::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { ePtr<eWindowStyle> style; if (!m_content) return eWidget::event(event, data, data2); ASSERT(m_content); getStyle(style); if (!m_content) return 0; gPainter &painter = *(gPainter*)data2; m_content->cursorSave(); m_content->cursorMove(m_top - m_selected); gRegion entryrect = eRect(0, 0, size().width(), m_itemheight); const gRegion &paint_region = *(gRegion*)data; for (int y = 0, i = 0; i <= m_items_per_page; y += m_itemheight, ++i) { gRegion entry_clip_rect = paint_region & entryrect; if (!entry_clip_rect.empty()) m_content->paint(painter, *style, ePoint(0, y), m_selected == m_content->cursorGet() && m_content->size() && m_selection_enabled); /* (we could clip with entry_clip_rect, but this shouldn't change the behavior of any well behaving content, so it would just degrade performance without any gain.) */ m_content->cursorMove(+1); entryrect.moveBy(ePoint(0, m_itemheight)); } // clear/repaint empty/unused space between scrollbar and listboxentrys if (m_scrollbar && m_scrollbar->isVisible()) { style->setStyle(painter, eWindowStyle::styleListboxNormal); painter.clip(eRect(m_scrollbar->position() - ePoint(5,0), eSize(5,m_scrollbar->size().height()))); painter.clear(); painter.clippop(); } m_content->cursorRestore(); return 0; } case evtChangedSize: recalcSize(); return eWidget::event(event, data, data2); case evtAction: if (isVisible()) { moveSelection((long)data2); return 1; } return 0; default: return eWidget::event(event, data, data2); } }
void eLabel::redrawWidget(gPainter *target, const eRect &rc) { /* eDebug("decoStr = %s, text=%s, name=%s, %p left = %d, top = %d, width=%d, height = %d", strDeco?strDeco.c_str():"no", text?text.c_str():"no" , name?name.c_str():"no", this, this->getPosition().x(), this->getPosition().y(), this->getSize().width(), this->getSize().height() ); eDebug("renderContext left = %d, top = %d, width = %d, height = %d", rc.left(), rc.top(), rc.width(), rc.height() );*/ target->clip( rc ); eRect area=clientrect; /* eDebug("area left = %d, top = %d, width = %d, height = %d", area.left(), area.top(), area.width(), area.height() );*/ if (deco_selected && have_focus) { deco_selected.drawDecoration(target, ePoint(width(), height())); area=crect_selected; } else if (deco) { deco.drawDecoration(target, ePoint(width(), height())); area=crect; } target->clippop(); target->clip( area ); if (shortcutPixmap) { //area.setWidth(area.width()-area.height()); area.setX(area.height()); } if (text.length()) { if ( area.size().height() < size.height() || area.size().width() < size.width() ) { // then deco is drawed eSize s=area.size(); validate( &s ); } else validate(); if (flags & flagVCenter) yOffs = ( (area.height() - para->getBoundBox().height() ) / 2 + 0) - para->getBoundBox().top(); else yOffs = 0; eWidget *w; if ((blitFlags & BF_ALPHATEST) && (transparentBackgroundColor >= 0)) { w=this; target->setBackgroundColor(transparentBackgroundColor); } else { w=getNonTransparentBackground(); target->setBackgroundColor(w->getBackgroundColor()); } target->setFont(font); target->renderPara(*para, ePoint( area.left(), area.top()+yOffs) ); } if (pixmap) { // eDebug("blit pixmap area left=%d, top=%d, right=%d, bottom=%d", rc.left(), rc.top(), rc.right(), rc.bottom() ); // eDebug("pixmap_pos x = %d, y = %d, xsize=%d, ysize=%d", pixmap_position.x(), pixmap_position.y(), pixmap->x, pixmap->y ); if (flags & flagVCenter) pixmap_position.setY(area.top()+(area.height() - pixmap->y)/2); if (align == eTextPara::dirCenter) pixmap_position.setX(area.left()+(area.width() - pixmap->x)/2); target->blit(*pixmap, shortcutPixmap?pixmap_position+ePoint( area.left(), 0):pixmap_position, area, /*(blitFlags & BF_ALPHATEST) ?*/ gPixmap::blitAlphaTest/* : 0*/); } if (shortcutPixmap) target->blit(*shortcutPixmap, ePoint((area.height()-shortcutPixmap->x)/2, area.top()+(area.height()-shortcutPixmap->y)/2), eRect(), gPixmap::blitAlphaTest); target->clippop(); }
void eWidgetDesktop::resize(eSize size) { m_screen.m_dirty_region = gRegion(eRect(ePoint(0, 0), size)); m_screen.m_screen_size = size; }
void *gRC::thread() { int need_notify = 0; #ifndef SYNC_PAINT while (1) { #else while (rp != wp) { #endif #ifndef SYNC_PAINT pthread_mutex_lock(&mutex); #endif if ( rp != wp ) { /* make sure the spinner is not displayed when we something is painted */ disableSpinner(); gOpcode o(queue[rp++]); if ( rp == MAXSIZE ) rp=0; #ifndef SYNC_PAINT pthread_mutex_unlock(&mutex); #endif if (o.opcode==gOpcode::shutdown) break; else if (o.opcode==gOpcode::notify) need_notify = 1; else if (o.opcode==gOpcode::setCompositing) { m_compositing = o.parm.setCompositing; m_compositing->Release(); } else if(o.dc) { o.dc->exec(&o); // o.dc is a gDC* filled with grabref... so we must release it here o.dc->Release(); } } else { if (need_notify) { need_notify = 0; m_notify_pump.send(1); } #ifndef SYNC_PAINT while(rp == wp) { /* when the main thread is non-idle for a too long time without any display output, we want to display a spinner. */ struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); if (m_spinner_enabled) { timeout.tv_nsec += 100*1000*1000; /* yes, this is required. */ if (timeout.tv_nsec > 1000*1000*1000) { timeout.tv_nsec -= 1000*1000*1000; timeout.tv_sec++; } } else timeout.tv_sec += 2; int idle = 1; if (pthread_cond_timedwait(&cond, &mutex, &timeout) == ETIMEDOUT) { if (eApp && !eApp->isIdle()) { int idle_count = eApp->idleCount(); if (idle_count == m_prev_idle_count) idle = 0; else m_prev_idle_count = idle_count; } } if (!idle) { if (!m_spinner_enabled) eDebug("main thread is non-idle! display spinner!"); enableSpinner(); } else disableSpinner(); } pthread_mutex_unlock(&mutex); #endif } } #ifndef SYNC_PAINT pthread_exit(0); #endif return 0; } void gRC::recv_notify(const int &i) { notify(); } gRC *gRC::getInstance() { return instance; } void gRC::enableSpinner() { if (!m_spinner_dc) { eDebug("no spinner DC!"); return; } gOpcode o; o.opcode = m_spinner_enabled ? gOpcode::incrementSpinner : gOpcode::enableSpinner; m_spinner_dc->exec(&o); m_spinner_enabled = 1; o.opcode = gOpcode::flush; m_spinner_dc->exec(&o); } void gRC::disableSpinner() { if (!m_spinner_enabled) return; if (!m_spinner_dc) { eDebug("no spinner DC!"); return; } m_spinner_enabled = 0; gOpcode o; o.opcode = gOpcode::disableSpinner; m_spinner_dc->exec(&o); o.opcode = gOpcode::flush; m_spinner_dc->exec(&o); } static int gPainter_instances; gPainter::gPainter(gDC *dc, eRect rect): m_dc(dc), m_rc(gRC::getInstance()) { // ASSERT(!gPainter_instances); gPainter_instances++; // begin(rect); } gPainter::~gPainter() { end(); gPainter_instances--; } void gPainter::setBackgroundColor(const gColor &color) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setBackgroundColor; o.dc = m_dc.grabRef(); o.parm.setColor = new gOpcode::para::psetColor; o.parm.setColor->color = color; m_rc->submit(o); } void gPainter::setForegroundColor(const gColor &color) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setForegroundColor; o.dc = m_dc.grabRef(); o.parm.setColor = new gOpcode::para::psetColor; o.parm.setColor->color = color; m_rc->submit(o); } void gPainter::setBackgroundColor(const gRGB &color) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setBackgroundColorRGB; o.dc = m_dc.grabRef(); o.parm.setColorRGB = new gOpcode::para::psetColorRGB; o.parm.setColorRGB->color = color; m_rc->submit(o); } void gPainter::setForegroundColor(const gRGB &color) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setForegroundColorRGB; o.dc = m_dc.grabRef(); o.parm.setColorRGB = new gOpcode::para::psetColorRGB; o.parm.setColorRGB->color = color; m_rc->submit(o); } void gPainter::setFont(gFont *font) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode = gOpcode::setFont; o.dc = m_dc.grabRef(); font->AddRef(); o.parm.setFont = new gOpcode::para::psetFont; o.parm.setFont->font = font; m_rc->submit(o); } void gPainter::renderText(const eRect &pos, const std::string &string, int flags) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode=gOpcode::renderText; o.dc = m_dc.grabRef(); o.parm.renderText = new gOpcode::para::prenderText; o.parm.renderText->area = pos; o.parm.renderText->text = string.empty()?0:strdup(string.c_str()); o.parm.renderText->flags = flags; m_rc->submit(o); } void gPainter::renderPara(eTextPara *para, ePoint offset) { if ( m_dc->islocked() ) return; ASSERT(para); gOpcode o; o.opcode=gOpcode::renderPara; o.dc = m_dc.grabRef(); o.parm.renderPara = new gOpcode::para::prenderPara; o.parm.renderPara->offset = offset; para->AddRef(); o.parm.renderPara->textpara = para; m_rc->submit(o); } void gPainter::fill(const eRect &area) { if ( m_dc->islocked() ) return; gOpcode o; o.opcode=gOpcode::fill; o.dc = m_dc.grabRef(); o.parm.fill = new gOpcode::para::pfillRect; o.parm.fill->area = area; m_rc->submit(o); } void gPainter::fill(const gRegion ®ion) { if ( m_dc->islocked() ) return; 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() { if ( m_dc->islocked() ) return; gOpcode o; o.opcode=gOpcode::clear; o.dc = m_dc.grabRef(); o.parm.fill = new gOpcode::para::pfillRect; o.parm.fill->area = eRect(); m_rc->submit(o); } void gPainter::blit(gPixmap *pixmap, ePoint pos, const eRect &clip, int flags) { blitScale(pixmap, eRect(pos, eSize()), clip, flags, 0); }
void eWidgetDesktop::recalcClipRegions(eWidget *root) { if (m_comp_mode == cmImmediate) { gRegion background_before = m_screen.m_background_region; m_screen.m_background_region = gRegion(eRect(ePoint(0, 0), m_screen.m_screen_size)); for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i) { if (!(i->m_vis & eWidget::wVisShow)) { clearVisibility(i); continue; } gRegion visible_before = i->m_visible_with_childs; calcWidgetClipRegion(*i, m_screen.m_background_region); gRegion redraw = (i->m_visible_with_childs - visible_before) | (visible_before - i->m_visible_with_childs); redraw.moveBy(i->position()); invalidate(redraw); } gRegion redraw = (background_before - m_screen.m_background_region) | (m_screen.m_background_region - background_before); invalidate(redraw); } else if (m_comp_mode == cmBuffered) { if (!root->m_vis & eWidget::wVisShow) { clearVisibility(root); for (int i = 0; i < MAX_LAYER; ++i) removeBufferForWidget(root, i); return; } for (int i = 0; i < MAX_LAYER; ++i) { eWidgetDesktopCompBuffer *comp = root->m_comp_buffer[i]; /* TODO: layers might not be required to have the screen size, for memory reasons. */ if ((i == 0 && !comp) || (comp && (root->size() != comp->m_screen_size))) createBufferForWidget(root, 0); comp = root->m_comp_buffer[i]; /* it might have changed. */ if (!comp) continue; /* WAIT, don't we need to invalidate,whatever */ /* CHECKME: don't we need to recalculate everything? after all, our buffer has changed and is likely to be cleared */ gRegion visible_before = root->m_visible_with_childs; comp->m_background_region = gRegion(eRect(comp->m_position, comp->m_screen_size)); gRegion visible_new = root->m_visible_with_childs - visible_before; gRegion visible_lost = visible_before - root->m_visible_with_childs; visible_new.moveBy(root->position()); visible_lost.moveBy(root->position()); invalidate(visible_new, root, i); invalidate(visible_lost, root, i); calcWidgetClipRegion(root, comp->m_background_region); } } }
int main(int argc, char **argv) { #ifdef MEMLEAK_CHECK atexit(DumpUnfreed); #endif #ifdef OBJECT_DEBUG atexit(object_dump); #endif gst_init(&argc, &argv); // set pythonpath if unset setenv("PYTHONPATH", eEnv::resolve("${libdir}/enigma2/python").c_str(), 0); printf("PYTHONPATH: %s\n", getenv("PYTHONPATH")); printf("DVB_API_VERSION %d DVB_API_VERSION_MINOR %d\n", DVB_API_VERSION, DVB_API_VERSION_MINOR); bsodLogInit(); ePython python; eMain main; #if 1 ePtr<gMainDC> my_dc; gMainDC::getInstance(my_dc); //int double_buffer = my_dc->haveDoubleBuffering(); ePtr<gLCDDC> my_lcd_dc; gLCDDC::getInstance(my_lcd_dc); /* ok, this is currently hardcoded for arabic. */ /* some characters are wrong in the regular font, force them to use the replacement font */ for (int i = 0x60c; i <= 0x66d; ++i) eTextPara::forceReplacementGlyph(i); eTextPara::forceReplacementGlyph(0xfdf2); for (int i = 0xfe80; i < 0xff00; ++i) eTextPara::forceReplacementGlyph(i); eWidgetDesktop dsk(my_dc->size()); eWidgetDesktop dsk_lcd(my_lcd_dc->size()); dsk.setStyleID(0); dsk_lcd.setStyleID(my_lcd_dc->size().width() == 96 ? 2 : 1); /* if (double_buffer) { eDebug("[MAIN] - double buffering found, enable buffered graphics mode."); dsk.setCompositionMode(eWidgetDesktop::cmBuffered); } */ wdsk = &dsk; lcddsk = &dsk_lcd; dsk.setDC(my_dc); dsk_lcd.setDC(my_lcd_dc); dsk.setBackgroundColor(gRGB(0,0,0,0xFF)); #endif /* redrawing is done in an idle-timer, so we have to set the context */ dsk.setRedrawTask(main); dsk_lcd.setRedrawTask(main); eDebug("Checking box..."); FILE *infile; char line[100]; char command[64]; if((infile = fopen("/proc/stb/info/boxtype", "r")) != NULL) { fgets(line, sizeof(line), infile); if(strcmp(line, "ini-5000sv\n") == 0) { eDebug("Miraclebox Premium Twin detected"); } else if(strcmp(line, "ini-1000sv\n") == 0) { eDebug("Miraclebox PremiumMini detected"); } else if(strcmp(line, "ini-2000sv\n") == 0) { eDebug("Miraclebox Premium Mini Plus detected"); } else if(strcmp(line, "ini-8000sv\n") == 0) { eDebug("Miraclebox Premium Ultra detected"); } else if(strcmp(line, "g300\n") == 0) { eDebug("Miraclebox Premium XXXXX detected"); } else if(strcmp(line, "7000S\n") == 0) { eDebug("Miraclebox Premium Micro detected"); } else { eDebug("Wrong HW, this image can be only run on Miraclbox Premium Series"); sprintf(command, "showiframe /usr/share/enigma2/box.mvi > /dev/null"); system(command); sprintf(command, "flash_erase /dev/mtd/2 0 0"); system(command); sprintf(command, "flash_erase /dev/mtd/4 0 0"); system(command); sprintf(command, "flash_erase /dev/mtd/3 0 0"); system(command); sprintf(command, "sleep 5;reboot -f"); } fclose(infile); } eDebug("[MAIN] Loading spinners..."); { int i; #define MAX_SPINNER 64 ePtr<gPixmap> wait[MAX_SPINNER]; for (i=0; i<MAX_SPINNER; ++i) { char filename[64]; std::string rfilename; snprintf(filename, sizeof(filename), "${datadir}/enigma2/skin_default/spinner/wait%d.png", i + 1); rfilename = eEnv::resolve(filename); loadPNG(wait[i], rfilename.c_str()); if (!wait[i]) { if (!i) eDebug("[MAIN] failed to load %s: %m", rfilename.c_str()); else eDebug("[MAIN] found %d spinner!\n", i); break; } } if (i) my_dc->setSpinner(eRect(ePoint(100, 100), wait[0]->size()), wait, i); else my_dc->setSpinner(eRect(100, 100, 0, 0), wait, 1); } gRC::getInstance()->setSpinnerDC(my_dc); eRCInput::getInstance()->keyEvent.connect(slot(keyEvent)); printf("[MAIN] executing main\n"); bsodCatchSignals(); catchTermSignal(); setIoPrio(IOPRIO_CLASS_BE, 3); /* start at full size */ eVideoWidget::setFullsize(true); // python.execute("mytest", "__main__"); python.execFile(eEnv::resolve("${libdir}/enigma2/python/mytest.py").c_str()); /* restore both decoders to full size */ eVideoWidget::setFullsize(true); if (exit_code == 5) /* python crash */ { eDebug("[MAIN] (exit code 5)"); bsodFatal(0); } dsk.paint(); dsk_lcd.paint(); { gPainter p(my_lcd_dc); p.resetClip(eRect(ePoint(0, 0), my_lcd_dc->size())); p.clear(); p.flush(); } return exit_code; }