void gDC::incrementSpinner() { ASSERT(m_spinner_saved); static int blub; blub++; #if 0 int i; for (i = 0; i < 5; ++i) { int x = i * 20 + m_spinner_pos.left(); int y = m_spinner_pos.top(); int col = ((blub - i) * 30) % 256; m_pixmap->fill(eRect(x, y, 10, 10), gRGB(col, col, col)); } #endif m_spinner_temp->blit(*m_spinner_saved, eRect(0, 0, 0, 0), eRect(ePoint(0, 0), m_spinner_pos.size())); if (m_spinner_pic[m_spinner_i]) m_spinner_temp->blit(*m_spinner_pic[m_spinner_i], eRect(0, 0, 0, 0), eRect(ePoint(0, 0), m_spinner_pos.size()), gPixmap::blitAlphaTest); m_pixmap->blit(*m_spinner_temp, eRect(m_spinner_pos.topLeft(), eSize()), gRegion(m_spinner_pos), 0); m_spinner_i++; m_spinner_i %= m_spinner_num; }
static void clearRegionHelper(gPainter &painter, eListboxStyle *local_style, const ePoint &offset, ePyObject &pbackColor, bool cursorValid, bool clear=true) { if (pbackColor) { unsigned int color = PyInt_AsUnsignedLongMask(pbackColor); painter.setBackgroundColor(gRGB(color)); } else if (local_style) { if (local_style && local_style->m_background_color_set) painter.setBackgroundColor(local_style->m_background_color); if (local_style->m_background && cursorValid) { if (local_style->m_transparent_background) painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHATEST); else painter.blit(local_style->m_background, offset, eRect(), 0); return; } else if (local_style->m_transparent_background) return; } if (clear) painter.clear(); }
eSubtitleWidget::eSubtitleWidget(eWidget *parent) : eWidget(parent), m_hide_subtitles_timer(eTimer::create(eApp)) { setBackgroundColor(gRGB(0,0,0,255)); m_page_ok = 0; m_dvb_page_ok = 0; m_pango_page_ok = 0; CONNECT(m_hide_subtitles_timer->timeout, eSubtitleWidget::clearPage); }
void eWidgetDesktop::setBackgroundColor(gRGB col) { setBackgroundColor(&m_screen, col); if (m_comp_mode == cmBuffered) for (ePtrList<eWidget>::iterator i(m_root.begin()); i != m_root.end(); ++i) { for (int l = 0; l < MAX_LAYER; ++l) if (i->m_comp_buffer[l]) setBackgroundColor(i->m_comp_buffer[l], l ? gRGB(0, 0, 0, 0) : col); /* all layers above 0 will have a transparent background */ } }
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); ePtr<eServiceEvent> evt; bool serviceAvail = true; #ifndef FORCE_SERVICEAVAIL 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; } #endif 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; ePtr<gPixmap> piconPixmap; if (e == celServiceName) { //picon stuff if (isPlayable && PyCallable_Check(m_GetPiconNameFunc)) { 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()) loadPNG(piconPixmap, piconFilename.c_str()); } Py_DECREF(pRet); } } xoffs = xoffset; tmp.setWidth(((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? tmp.width() : 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 == -1 || (!piconPixmap && !m_column_width)) ? bbox.width() : 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) and (m_column_width || piconPixmap)) { 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; 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(); } } //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(*m_cursor)) { 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(); } } } } 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); 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 upload the crash log " << crashlog_name << " to www.vuplus-community.net\n" "Your STB will restart 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 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; std::string crashlog_name; std::ostringstream os; os << "/media/hdd/enigma2_crash_"; os << time(0); 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/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); XmlGenerator xml(f); xml.open("openpli"); 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"); 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/vumodel", F_OK) != -1) { xml.stringFromFile("stbmodel", "/proc/stb/info/vumodel"); } else if (access("/proc/stb/info/model", F_OK) != -1) { xml.stringFromFile("stbmodel", "/proc/stb/info/model"); } xml.cDataFromCmd("kernelversion", "uname -a"); xml.stringFromFile("kernelcmdline", "/proc/cmdline"); xml.stringFromFile("nimsockets", "/proc/bus/nim_sockets"); xml.cDataFromFile("imageversion", "/etc/image-version"); xml.cDataFromFile("imageissue", "/etc/issue.net"); 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(0x008000)); 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 send the logfile " << crashlog_name << " to " << 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); }
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); #define PB_BorderWidth 2 #define PB_Height 6 int paintProgress = 0; /* if non zero draw a progress this size and shorten event string width with it */ 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 (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 for (int e = 0; e != celElements; ++e) { if (m_element_font[e]) { int flags=gPainter::RT_VALIGN_CENTER; int yoffs = 0; int xoffs = xoffset; eRect &area = m_element_position[e]; std::string text = "<n/a>"; xoffset=0; switch (e) { case celServiceNumber: { if (m_cursor->flags & eServiceReference::isMarker && !(m_cursor->flags & eServiceReference::isNumberedMarker)) continue; if (area.width() <= 0) continue; // no point in going on if we won't paint anything char bla[10]; /* how we can do this better? :) */ int markers_before=0; { list::iterator tmp=m_cursor; while(tmp != m_list.begin()) { --tmp; if (tmp->flags & eServiceReference::isMarker && !(tmp->flags & eServiceReference::isNumberedMarker)) ++markers_before; } } sprintf(bla, "%d", m_numberoffset + m_cursor_number + 1 - markers_before); text = bla; flags|=gPainter::RT_HALIGN_RIGHT; break; } case celServiceName: { if (service_info) service_info->getName(*m_cursor, text); break; } case celServiceInfo: { if ( isPlayable && !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)); } if (paintProgress) area.setWidth(area.width() - paintProgress - 2*PB_BorderWidth - 2 ); /* create space for the progress bar */ } else continue; break; } } eRect tmp = area; tmp.setWidth(tmp.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 new_left = area.left() + bbox.width() + 8 + xoffs; m_element_position[celServiceInfo].setLeft(new_left); m_element_position[celServiceInfo].setTop(area.top()); m_element_position[celServiceInfo].setWidth(m_itemsize.width() - new_left); m_element_position[celServiceInfo].setHeight(area.height()); } 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(); int vcentered_top = (area.height() - bbox.height()) / 2; yoffs = vcentered_top - bbox.top(); } painter.renderPara(para, offset+ePoint(xoffs, yoffs)); } else if (e == celServiceTypePixmap || e == celFolderPixmap || e == celMarkerPixmap) { int orbpos = m_cursor->getUnsignedData(4) >> 16; ePtr<gPixmap> &pixmap = (e == celFolderPixmap) ? m_pixmaps[picFolder] : (e == celMarkerPixmap) ? m_pixmaps[picMarker] : (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; if (pixmap) { eSize pixmap_size = pixmap->size(); int p = celServiceInfo; if (e == celFolderPixmap) p = celServiceName; else if (e == celMarkerPixmap) p = celServiceNumber; eRect area = m_element_position[p]; int correction = (area.height() - pixmap_size.height()) / 2; if (isPlayable) { if (e != celServiceTypePixmap) continue; m_element_position[celServiceInfo] = area; m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + 8); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - 8); } else if (m_cursor->flags & eServiceReference::isDirectory) { if (e != celFolderPixmap) continue; xoffset = pixmap_size.width() + 8; } else if (m_cursor->flags & eServiceReference::isMarker) { if (e != celMarkerPixmap) continue; } else eFatal("unknown service type in listboxservice"); area.moveBy(offset); painter.clip(area); painter.blit(pixmap, offset+ePoint(area.left(), correction), area, gPainter::BT_ALPHATEST); painter.clippop(); } } else if (e == celServiceEventProgressbar) { eRect area = m_element_position[celServiceEventProgressbar]; if (area.width() > 0 && isPlayable) { // we schedule it to paint it as last element.. so we dont need to reset fore/background color paintProgress = area.width(); // nopli xoffset = area.width() + 10; } } }
void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected) { gRegion itemregion(eRect(offset, m_itemsize)); eListboxStyle *local_style = 0; eRect sel_clip(m_selection_clip); bool cursorValid = this->cursorValid(); gRGB border_color; int border_size = 0; if (sel_clip.valid()) sel_clip.moveBy(offset); /* get local listbox style, if present */ if (m_listbox) { local_style = m_listbox->getLocalStyle(); border_size = local_style->m_border_size; border_color = local_style->m_border_color; } painter.clip(itemregion); clearRegion(painter, style, local_style, ePyObject(), ePyObject(), ePyObject(), ePyObject(), selected, itemregion, sel_clip, offset, cursorValid); ePyObject items, buildfunc_ret; if (m_list && cursorValid) { /* a multicontent list can be used in two ways: either each item is a list of (TYPE,...)-tuples, or there is a template defined, which is a list of (TYPE,...)-tuples, and the list is an unformatted tuple. The template then references items from the list. */ items = PyList_GET_ITEM(m_list, m_cursor); // borrowed reference! if (m_buildFunc) { if (PyCallable_Check(m_buildFunc)) // when we have a buildFunc then call it { if (PyTuple_Check(items)) buildfunc_ret = items = PyObject_CallObject(m_buildFunc, items); else eDebug("[eListboxPythonMultiContent] items is no tuple"); } else eDebug("[eListboxPythonMultiContent] buildfunc is not callable"); } if (!items) { eDebug("[eListboxPythonMultiContent] error getting item %d", m_cursor); goto error_out; } if (!m_template) { if (!PyList_Check(items)) { eDebug("[eListboxPythonMultiContent] list entry %d is not a list (non-templated)", m_cursor); goto error_out; } } else { if (!PyTuple_Check(items)) { eDebug("[eListboxPythonMultiContent] list entry %d is not a tuple (templated)", m_cursor); goto error_out; } } ePyObject data; /* if we have a template, use the template for the actual formatting. we will later detect that "data" is present, and refer to that, instead of the immediate value. */ int start = 1; if (m_template) { data = items; items = m_template; start = 0; } int size = PyList_Size(items); for (int i = start; i < size; ++i) { ePyObject item = PyList_GET_ITEM(items, i); // borrowed reference! if (!item) { eDebug("[eListboxPythonMultiContent] ?"); goto error_out; } if (!PyTuple_Check(item)) { eDebug("[eListboxPythonMultiContent] did not receive a tuple."); goto error_out; } int size = PyTuple_Size(item); if (!size) { eDebug("[eListboxPythonMultiContent] receive empty tuple."); goto error_out; } int type = PyInt_AsLong(PyTuple_GET_ITEM(item, 0)); switch (type) { case TYPE_TEXT: // text { /* (0, x, y, width, height, fnt, flags, "bla" [, color, colorSelected, backColor, backColorSelected, borderWidth, borderColor] ) */ ePyObject px = PyTuple_GET_ITEM(item, 1), py = PyTuple_GET_ITEM(item, 2), pwidth = PyTuple_GET_ITEM(item, 3), pheight = PyTuple_GET_ITEM(item, 4), pfnt = PyTuple_GET_ITEM(item, 5), pflags = PyTuple_GET_ITEM(item, 6), pstring = PyTuple_GET_ITEM(item, 7), pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, pborderWidth, pborderColor; if (!(px && py && pwidth && pheight && pfnt && pflags && pstring)) { eDebug("[eListboxPythonMultiContent] received too small tuple (must be (TYPE_TEXT, x, y, width, height, fnt, flags, string [, color, backColor, backColorSelected, borderWidth, borderColor])"); goto error_out; } if (size > 8) pforeColor = lookupColor(PyTuple_GET_ITEM(item, 8), data); if (size > 9) pforeColorSelected = lookupColor(PyTuple_GET_ITEM(item, 9), data); if (size > 10) pbackColor = lookupColor(PyTuple_GET_ITEM(item, 10), data); if (size > 11) pbackColorSelected = lookupColor(PyTuple_GET_ITEM(item, 11), data); if (size > 12) { pborderWidth = PyTuple_GET_ITEM(item, 12); if (pborderWidth == Py_None) pborderWidth=ePyObject(); } if (size > 13) pborderColor = lookupColor(PyTuple_GET_ITEM(item, 13), data); if (PyInt_Check(pstring) && data) /* if the string is in fact a number, it refers to the 'data' list. */ pstring = PyTuple_GetItem(data, PyInt_AsLong(pstring)); /* don't do anything if we have 'None' as string */ if (pstring == Py_None) continue; const char *string = (PyString_Check(pstring)) ? PyString_AsString(pstring) : "<not-a-string>"; int x = PyInt_AsLong(px) + offset.x(); int y = PyInt_AsLong(py) + offset.y(); int width = PyInt_AsLong(pwidth); int height = PyInt_AsLong(pheight); int flags = PyInt_AsLong(pflags); int fnt = PyInt_AsLong(pfnt); int bwidth = pborderWidth ? PyInt_AsLong(pborderWidth) : 0; if (m_font.find(fnt) == m_font.end()) { eDebug("[eListboxPythonMultiContent] specified font %d was not found!", fnt); goto error_out; } eRect rect(x+bwidth, y+bwidth, width-bwidth*2, height-bwidth*2); painter.clip(rect); { gRegion rc(rect); bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor); clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear); } painter.setFont(m_font[fnt]); painter.renderText(rect, string, flags, border_color, border_size); painter.clippop(); // draw border if (bwidth) { eRect rect(eRect(x, y, width, height)); painter.clip(rect); if (pborderColor) { unsigned int color = PyInt_AsUnsignedLongMask(pborderColor); painter.setForegroundColor(gRGB(color)); } rect.setRect(x, y, width, bwidth); painter.fill(rect); rect.setRect(x, y+bwidth, bwidth, height-bwidth); painter.fill(rect); rect.setRect(x+bwidth, y+height-bwidth, width-bwidth, bwidth); painter.fill(rect); rect.setRect(x+width-bwidth, y+bwidth, bwidth, height-bwidth); painter.fill(rect); painter.clippop(); } break; } case TYPE_PROGRESS_PIXMAP: // Progress /* (1, x, y, width, height, filled_percent, pixmap [, borderWidth, foreColor, foreColorSelected, backColor, backColorSelected] ) */ case TYPE_PROGRESS: // Progress { /* (1, x, y, width, height, filled_percent [, borderWidth, foreColor, foreColorSelected, backColor, backColorSelected] ) */ ePyObject px = PyTuple_GET_ITEM(item, 1), py = PyTuple_GET_ITEM(item, 2), pwidth = PyTuple_GET_ITEM(item, 3), pheight = PyTuple_GET_ITEM(item, 4), pfilled_perc = PyTuple_GET_ITEM(item, 5), ppixmap, pborderWidth, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected; int idx = 6; if (type == TYPE_PROGRESS) { if (!(px && py && pwidth && pheight && pfilled_perc)) { eDebug("[eListboxPythonMultiContent] received too small tuple (must be (TYPE_PROGRESS, x, y, width, height, filled percent [,border width, foreColor, backColor, backColorSelected]))"); goto error_out; } } else { ppixmap = PyTuple_GET_ITEM(item, idx++); if (ppixmap == Py_None) continue; if (!(px && py && pwidth && pheight && pfilled_perc, ppixmap)) { eDebug("[eListboxPythonMultiContent] received too small tuple (must be (TYPE_PROGRESS_PIXMAP, x, y, width, height, filled percent, pixmap, [,border width, foreColor, backColor, backColorSelected]))"); goto error_out; } } if (size > idx) { pborderWidth = PyTuple_GET_ITEM(item, idx++); if (pborderWidth == Py_None) pborderWidth = ePyObject(); } if (size > idx) { pforeColor = PyTuple_GET_ITEM(item, idx++); if (pforeColor == Py_None) pforeColor = ePyObject(); } if (size > idx) { pforeColorSelected = PyTuple_GET_ITEM(item, idx++); if (pforeColorSelected == Py_None) pforeColorSelected=ePyObject(); } if (size > idx) { pbackColor = PyTuple_GET_ITEM(item, idx++); if (pbackColor == Py_None) pbackColor=ePyObject(); } if (size > idx) { pbackColorSelected = PyTuple_GET_ITEM(item, idx++); if (pbackColorSelected == Py_None) pbackColorSelected=ePyObject(); } int x = PyInt_AsLong(px) + offset.x(); int y = PyInt_AsLong(py) + offset.y(); int width = PyInt_AsLong(pwidth); int height = PyInt_AsLong(pheight); int filled = PyInt_AsLong(pfilled_perc); if ((filled < 0) && data) /* if the string is in a negative number, it refers to the 'data' list. */ filled = PyInt_AsLong(PyTuple_GetItem(data, -filled)); /* don't do anything if percent out of range */ if ((filled < 0) || (filled > 100)) continue; int bwidth = pborderWidth ? PyInt_AsLong(pborderWidth) : 2; eRect rect(x, y, width, height); painter.clip(rect); { gRegion rc(rect); bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor); clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear); } // border if (bwidth) { rect.setRect(x, y, width, bwidth); painter.fill(rect); rect.setRect(x, y+bwidth, bwidth, height-bwidth); painter.fill(rect); rect.setRect(x+bwidth, y+height-bwidth, width-bwidth, bwidth); painter.fill(rect); rect.setRect(x+width-bwidth, y+bwidth, bwidth, height-bwidth); painter.fill(rect); } rect.setRect(x+bwidth, y+bwidth, (width-bwidth*2) * filled / 100, height-bwidth*2); // progress if (ppixmap) { ePtr<gPixmap> pixmap; if (PyInt_Check(ppixmap) && data) /* if the pixmap is in fact a number, it refers to the data list */ ppixmap = PyTuple_GetItem(data, PyInt_AsLong(ppixmap)); if (SwigFromPython(pixmap, ppixmap)) { eDebug("[eListboxPythonMultiContent] (Pixmap) get pixmap failed"); painter.clippop(); continue; } painter.blit(pixmap, rect.topLeft(), rect, 0); } else painter.fill(rect); painter.clippop(); break; } case TYPE_PIXMAP_ALPHABLEND: case TYPE_PIXMAP_ALPHATEST: case TYPE_PIXMAP: // pixmap { /* (2, x, y, width, height, pixmap [, backColor, backColorSelected] ) */ ePyObject px = PyTuple_GET_ITEM(item, 1), py = PyTuple_GET_ITEM(item, 2), pwidth = PyTuple_GET_ITEM(item, 3), pheight = PyTuple_GET_ITEM(item, 4), ppixmap = PyTuple_GET_ITEM(item, 5), pbackColor, pbackColorSelected; if (!(px && py && pwidth && pheight && ppixmap)) { eDebug("[eListboxPythonMultiContent] received too small tuple (must be (TYPE_PIXMAP, x, y, width, height, pixmap [, backColor, backColorSelected] ))"); goto error_out; } if (PyInt_Check(ppixmap) && data) /* if the pixemap is in fact a number, it refers to the 'data' list. */ ppixmap = PyTuple_GetItem(data, PyInt_AsLong(ppixmap)); /* don't do anything if we have 'None' as pixmap */ if (ppixmap == Py_None) continue; int x = PyInt_AsLong(px) + offset.x(); int y = PyInt_AsLong(py) + offset.y(); int width = PyInt_AsLong(pwidth); int height = PyInt_AsLong(pheight); int flags = 0; ePtr<gPixmap> pixmap; if (SwigFromPython(pixmap, ppixmap)) { eDebug("[eListboxPythonMultiContent] (Pixmap) get pixmap failed"); goto error_out; } if (size > 6) pbackColor = lookupColor(PyTuple_GET_ITEM(item, 6), data); if (size > 7) pbackColorSelected = lookupColor(PyTuple_GET_ITEM(item, 7), data); if (size > 8) flags = PyInt_AsLong(PyTuple_GET_ITEM(item, 8)); eRect rect(x, y, width, height); painter.clip(rect); { gRegion rc(rect); bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor); clearRegion(painter, style, local_style, ePyObject(), ePyObject(), pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear); } flags |= (type == TYPE_PIXMAP_ALPHATEST) ? gPainter::BT_ALPHATEST : (type == TYPE_PIXMAP_ALPHABLEND) ? gPainter::BT_ALPHABLEND : 0; if (flags & gPainter::BT_SCALE) painter.blitScale(pixmap, rect, rect, flags); else painter.blit(pixmap, rect.topLeft(), rect, flags); painter.clippop(); break; } default: eWarning("[eListboxPythonMultiContent] received unknown type (%d)", type); goto error_out; } } } if (selected && !sel_clip.valid() && (!local_style || !local_style->m_selection)) style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry); error_out: if (buildfunc_ret) Py_DECREF(buildfunc_ret); painter.clippop(); }
void eSubtitleWidget::setPage(const ePangoSubtitlePage &p) { int elements, element, startY, width, height, size_per_element; int lowerborder; bool rewrap_enabled; bool colourise_dialogs_enabled; m_pango_page = p; m_pango_page_ok = 1; invalidate(m_visible_region); // invalidate old visible regions m_visible_region.rects.clear(); rewrap_enabled = eConfigManager::getConfigBoolValue("config.subtitles.subtitle_rewrap"); colourise_dialogs_enabled = eConfigManager::getConfigBoolValue("config.subtitles.colourise_dialogs"); lowerborder = eConfigManager::getConfigIntValue("config.subtitles.subtitle_position", 50); elements = m_pango_page.m_elements.size(); if(rewrap_enabled | colourise_dialogs_enabled) { size_t ix, colourise_dialogs_current = 0; std::vector<std::string> colourise_dialogs_colours; std::string replacement; bool alignment_center = eConfigManager::getConfigValue("config.subtitles.subtitle_alignment") == "center"; if(colourise_dialogs_enabled) { colourise_dialogs_colours.push_back((std::string)gRGB(0xff, 0xff, 0x00)); // yellow colourise_dialogs_colours.push_back((std::string)gRGB(0x00, 0xff, 0xff)); // cyan colourise_dialogs_colours.push_back((std::string)gRGB(0xff, 0x00, 0xff)); // magenta colourise_dialogs_colours.push_back((std::string)gRGB(0x00, 0xff, 0x00)); // green colourise_dialogs_colours.push_back((std::string)gRGB(0xff, 0xaa, 0xaa)); // light red colourise_dialogs_colours.push_back((std::string)gRGB(0xaa, 0xaa, 0xff)); // light blue } for (element = 0; element < elements; element++) { std::string& line = m_pango_page.m_elements[element].m_pango_line; for (ix = 0; ix < line.length(); ix++) { if(rewrap_enabled && !line.compare(ix, 1, "\n")) line.replace(ix, 1, " "); if(colourise_dialogs_enabled && !line.compare(ix, 2, "- ")) { /* workaround for rendering fault when colouring is enabled, rewrap is off and alignment is center */ replacement = std::string((!rewrap_enabled && alignment_center) ? " " : "") + colourise_dialogs_colours.at(colourise_dialogs_current); line.replace(ix, 2, replacement); colourise_dialogs_current++; if(colourise_dialogs_current >= colourise_dialogs_colours.size()) colourise_dialogs_current = 0; } } } } if (elements > 1) startY = size().height() / 2; else startY = size().height() / 3 * 2; width = size().width() - startX * 2; height = size().height() - startY; if (elements != 0) size_per_element = height / elements; else size_per_element = height; for (element = 0; element < elements; element++) { eRect& area = m_pango_page.m_elements[element].m_area; area.setLeft(startX); area.setTop(size_per_element * element + startY - lowerborder); area.setWidth(width); area.setHeight(size_per_element); m_visible_region |= area; } m_hide_subtitles_timer->start(m_pango_page.m_timeout, true); invalidate(m_visible_region); // invalidate new regions }
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, ">", ">"); bool yellow_color = eConfigManager::getConfigBoolValue("config.subtitles.pango_subtitles_yellow"); 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 bsodFatal(const char *component) { char logfile[128]; sprintf(logfile, "/media/hdd/enigma2_crash_%u.log", (unsigned int)time(0)); FILE *f = fopen(logfile, "wb"); std::string lines = getLogBuffer(); /* find python-tracebacks, and extract " File "-strings */ size_t start = 0; char crash_emailaddr[256] = CRASH_EMAILADDR; char crash_component[256] = "enigma2"; if (component) snprintf(crash_component, 256, 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; if (end - start >= (256 - strlen(INFOFILE))) continue; char filename[256]; snprintf(filename, 256, "%s%s", lines.substr(start, end - start).c_str(), INFOFILE); FILE *cf = fopen(filename, "r"); if (cf) { fgets(crash_emailaddr, sizeof crash_emailaddr, cf); if (*crash_emailaddr && crash_emailaddr[strlen(crash_emailaddr)-1] == '\n') crash_emailaddr[strlen(crash_emailaddr)-1] = 0; fgets(crash_component, sizeof crash_component, cf); if (*crash_component && crash_component[strlen(crash_component)-1] == '\n') crash_component[strlen(crash_component)-1] = 0; fclose(cf); } } } if (f) { time_t t = time(0); fprintf(f, "enigma2 crashed on %s", ctime(&t)); #ifdef ENIGMA2_CHECKOUT_TAG fprintf(f, "enigma2 CVS TAG: " ENIGMA2_CHECKOUT_TAG "\n"); #else fprintf(f, "enigma2 compiled on " __DATE__ "\n"); #endif #ifdef ENIGMA2_CHECKOUT_ROOT fprintf(f, "enigma2 checked out from " ENIGMA2_CHECKOUT_ROOT "\n"); #endif fprintf(f, "please email this file to %s\n", crash_emailaddr); std::string buffer = getLogBuffer(); fwrite(buffer.c_str(), buffer.size(), 1, f); fclose(f); char cmd[256]; sprintf(cmd, "find /usr/lib/enigma2/python/ -name \"*.py\" | xargs md5sum >> %s", logfile); system(cmd); } #ifdef WITH_SDL ePtr<gSDLDC> my_dc; gSDLDC::getInstance(my_dc); #else ePtr<gFBDC> my_dc; gFBDC::getInstance(my_dc); #endif { gPainter p(my_dc); p.resetOffset(); p.resetClip(eRect(ePoint(0, 0), my_dc->size())); #ifdef ENIGMA2_CHECKOUT_TAG if (ENIGMA2_CHECKOUT_TAG[0] == 'T') /* tagged checkout (release) */ p.setBackgroundColor(gRGB(0x0000C0)); else if (ENIGMA2_CHECKOUT_TAG[0] == 'D') /* dated checkout (daily experimental build) */ { srand(time(0)); int r = rand(); unsigned int col = 0; if (r & 1) col |= 0x800000; if (r & 2) col |= 0x008000; if (r & 4) col |= 0x0000c0; p.setBackgroundColor(gRGB(col)); } #else p.setBackgroundColor(gRGB(0x008000)); #endif p.setForegroundColor(gRGB(0xFFFFFF)); ePtr<gFont> font = new gFont("Regular", 20); p.setFont(font); p.clear(); eRect usable_area = eRect(100, 70, my_dc->size().width() - 150, 100); char text[512]; snprintf(text, 512, "We are really sorry. Your Dreambox encountered " "a software problem, and needs to be restarted. " "Please send the logfile created in /hdd/ to %s.\n" "Your Dreambox restarts in 10 seconds!\n" "Component: %s", crash_emailaddr, crash_component); p.renderText(usable_area, text, gPainter::RT_WRAP|gPainter::RT_HALIGN_LEFT); usable_area = eRect(100, 170, my_dc->size().width() - 180, my_dc->size().height() - 20); int i; size_t 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", 14); p.setFont(font); p.renderText(usable_area, lines.substr(start), gPainter::RT_HALIGN_LEFT); sleep(10); } raise(SIGKILL); }
int main(int argc, char **argv) { #ifdef MEMLEAK_CHECK atexit(DumpUnfreed); #endif #ifdef OBJECT_DEBUG atexit(object_dump); #endif gst_init(&argc, &argv); for (int i = 0; i < argc; i++) { if (!(strcmp(argv[i], "--debug-no-color")) or !(strcmp(argv[i], "--nc"))) { logOutputColors = 0; } } m_erroroutput = new eErrorOutput(); m_erroroutput->run(); // 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(" - 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 Premium Mini detected"); } else if(strcmp(line, "ini-2000sv\n") == 0) { eDebug("Miraclebox Premium Mini+ detected"); } else if(strcmp(line, "ini-8000sv\n") == 0) { eDebug("Miraclebox Premium Ultra detected"); } else if(strcmp(line, "7000S\n") == 0) { eDebug("Miraclebox Premium Micro detected"); } else if(strcmp(line, "7005S\n") == 0) { eDebug("Miraclebox Premium Micro v2 detected"); } else if(strcmp(line, "g300\n") == 0) { eDebug("Miraclebox Premium Twin+ 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, "sleep 5;reboot -f"); } fclose(infile); } std::string active_skin = getConfigCurrentSpinner("config.skin.primary_skin"); 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/%s/wait%d.png", active_skin.c_str(), 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!", 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(); 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("(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(); } m_erroroutput = NULL; return exit_code; }
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); } }
void bsodFatal(const char *component) { /* show no more than one bsod while shutting down/crashing */ if (bsodhandled) return; bsodhandled = true; std::ostringstream os; os << getConfigString("config.crash.debug_path", "/home/root/logs/"); os << "enigma2_crash_"; os << time(0); os << ".log"; FILE *f = fopen(os.str().c_str(), "wb"); 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(); } } } if (f) { time_t t = time(0); struct tm tm; char tm_str[32]; bool detailedCrash = getConfigBool("config.crash.details", true); localtime_r(&t, &tm); strftime(tm_str, sizeof(tm_str), "%a %b %_d %T %Y", &tm); XmlGenerator xml(f); xml.open("openvix"); 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"); xml.string("skin", getConfigString("config.skin.primary_skin", "Default Skin")); xml.string("sourcedate", enigma2_date); 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/vumodel", F_OK) != -1) { xml.stringFromFile("stbmodel", "/proc/stb/info/vumodel"); } else if (access("/proc/stb/info/model", F_OK) != -1) { xml.stringFromFile("stbmodel", "/proc/stb/info/model"); } xml.cDataFromCmd("kernelversion", "uname -a"); xml.stringFromFile("kernelcmdline", "/proc/cmdline"); xml.stringFromFile("nimsockets", "/proc/bus/nim_sockets"); if (!getConfigBool("config.plugins.crashlogautosubmit.sendAnonCrashlog", true)) { xml.cDataFromFile("stbca", "/proc/stb/info/ca"); xml.cDataFromFile("enigma2settings", eEnv::resolve("${sysconfdir}/enigma2/settings"), ".password="******"config.plugins.crashlogautosubmit.addNetwork", false)) { xml.cDataFromFile("networkinterfaces", "/etc/network/interfaces"); xml.cDataFromFile("dns", "/etc/resolv.conf"); xml.cDataFromFile("defaultgateway", "/etc/default_gw"); } if (getConfigBool("config.plugins.crashlogautosubmit.addWlan", false)) xml.cDataFromFile("wpasupplicant", "/etc/wpa_supplicant.conf"); xml.cDataFromFile("imageversion", "/etc/image-version"); xml.cDataFromFile("imageissue", "/etc/issue.net"); xml.close(); if (detailedCrash) { xml.open("software"); xml.cDataFromCmd("enigma2software", "opkg list-installed 'enigma2*'"); if(access("/proc/stb/info/boxtype", F_OK) != -1) { xml.cDataFromCmd("xtrendsoftware", "opkg list-installed 'et-*'"); } else if (access("/proc/stb/info/vumodel", F_OK) != -1) { xml.cDataFromCmd("vuplussoftware", "opkg list-installed 'vuplus*'"); } else if (access("/proc/stb/info/model", F_OK) != -1) { xml.cDataFromCmd("dreamboxsoftware", "opkg list-installed 'dream*'"); } 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(0x010000)); p.setForegroundColor(gRGB(0xFFFFFF)); ePtr<gFont> font = new gFont("Regular", 20); p.setFont(font); p.clear(); eRect usable_area = eRect(100, 70, my_dc->size().width() - 150, 100); std::string text("We are really sorry. Your receiver encountered " "a software problem, and needs to be restarted. " "Please send the logfile created in /hdd/ to " + crash_emailaddr + ".\n" "Your receiver restarts in 10 seconds!\n" "Component: " + crash_component); p.renderText(usable_area, text.c_str(), gPainter::RT_WRAP|gPainter::RT_HALIGN_LEFT); usable_area = eRect(100, 170, my_dc->size().width() - 180, my_dc->size().height() - 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", 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 main(int argc, char **argv) { #ifdef MEMLEAK_CHECK atexit(DumpUnfreed); #endif #ifdef OBJECT_DEBUG atexit(object_dump); #endif #ifndef ENABLE_LIBEPLAYER3 gst_init(&argc, &argv); #endif // 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(); CheckPrintkLevel(); 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); #ifdef HAVE_GRAPHLCD dsk_lcd.setStyleID(my_lcd_dc->size().width() == 320 ? 1 : 2); #else dsk_lcd.setStyleID(my_lcd_dc->size().width() == 96 ? 2 : 1); #endif /* 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("[MAIN] Loading spinners..."); { unsigned int i = 0; bool def = false; const char *path = "${sysconfdir}/enigma2"; #define MAX_SPINNER 64 ePtr<gPixmap> wait[MAX_SPINNER]; while(i < MAX_SPINNER) { char filename[64]; std::string rfilename; snprintf(filename, sizeof(filename), "%s/spinner/wait%d.png", path, i + 1); rfilename = eEnv::resolve(filename); loadPNG(wait[i], rfilename.c_str()); if (!wait[i]) { if (!i) { if (def) eDebug("[MAIN] failed to load %s! (%m)", rfilename.c_str()); else { def = true; path = "${datadir}/enigma2/skin_default"; continue; } } else eDebug("[MAIN] found %d spinner!", i); break; } i++; } 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); #ifdef ENABLE_SIGC2 eRCInput::getInstance()->keyEvent.connect(sigc::ptr_fun(keyEvent)); #else eRCInput::getInstance()->keyEvent.connect(slot(keyEvent)); #endif #if defined(__sh__) // initialise the vfd class evfd * vfd = new evfd; vfd->init(); delete vfd; #endif 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; }
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(eSize(720, 576)); eWidgetDesktop dsk(eSize(1280, 720)); 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); // python.execute("mytest", "__main__"); python.execFile(eEnv::resolve("${libdir}/enigma2/python/mytest.py").c_str()); extern void setFullsize(); // definend in lib/gui/evideo.cpp setFullsize(); 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; }
int eInput::event(int event, void *data, void *data2) { switch (event) { case evtPaint: { gPainter &painter = *(gPainter*)data2; ePtr<eWindowStyle> style; getStyle(style); eWidget::event(event, data, data2); ePtr<eTextPara> para = new eTextPara(eRect(0, 0, size().width(), size().height())); std::string text; int cursor = -1; if (m_content) m_content->getDisplay(text, cursor); eDebug("cursor is %d", cursor); para->setFont(m_font); para->renderString(text.empty()?0:text.c_str(), 0); int glyphs = para->size(); if (m_have_focus) { if (m_mode && cursor < glyphs) { /* in overwrite mode, when not at end of line, invert the current cursor position. */ para->setGlyphFlag(cursor, GS_INVERT); eRect bbox = para->getGlyphBBox(cursor); bbox = eRect(bbox.left(), 0, bbox.width(), size().height()); painter.fill(bbox); } else { /* otherwise, insert small cursor */ eRect bbox; if (cursor < glyphs) { bbox = para->getGlyphBBox(cursor); bbox = eRect(bbox.left()-1, 0, 2, size().height()); } else if (cursor) { bbox = para->getGlyphBBox(cursor - 1); bbox = eRect(bbox.right(), 0, 2, size().height()); } else { bbox = eRect(0, 0, 2, size().height()); } painter.fill(bbox); } } painter.renderPara(para, ePoint(0, 0)); return 0; } case evtAction: if (isVisible()) { if ((long)data == ASCII_ACTIONS) { if ((long)data2 == gotAsciiCode) { if (m_content) { extern int getPrevAsciiCode(); // defined in enigma.cpp return m_content->haveKey(getPrevAsciiCode(), m_mode); } } } else if ((long)data == INPUT_ACTIONS) { switch((long)data2) { case moveLeft: if (m_content) m_content->moveCursor(eInputContent::dirLeft); break; case moveRight: if (m_content) m_content->moveCursor(eInputContent::dirRight); break; case moveHome: if (m_content) m_content->moveCursor(eInputContent::dirHome); break; case moveEnd: if (m_content) m_content->moveCursor(eInputContent::dirEnd); break; case deleteForward: if (m_content) m_content->deleteChar(eInputContent::deleteForward); break; case deleteBackward: if (m_content) m_content->deleteChar(eInputContent::deleteBackward); break; case toggleOverwrite: setOverwriteMode(!m_mode); break; case accept: changed(); mayKillFocus(); } return 1; } } return 0; case evtKey: { long key = (long)data; long flags = (long)data2; if (m_content && !(flags & 1)) // only make/repeat, no break return m_content->haveKey(key, m_mode); break; } case evtFocusGot: { eDebug("focus got in %p", this); ePtr<eActionMap> ptr; eActionMap::getInstance(ptr); ptr->bindAction("InputActions", 0, INPUT_ACTIONS, this); ptr->bindAction("AsciiActions", 0, ASCII_ACTIONS, this); m_have_focus = 1; eRCInput::getInstance()->setKeyboardMode(eRCInput::kmAscii); // fixme. we should use a style for this. setBackgroundColor(gRGB(64, 64, 128)); invalidate(); break; } case evtFocusLost: { eDebug("focus lostin %p", this); ePtr<eActionMap> ptr; eActionMap::getInstance(ptr); ptr->unbindAction(this, INPUT_ACTIONS); ptr->unbindAction(this, ASCII_ACTIONS); m_have_focus = 0; if (m_content) m_content->validate(); eRCInput::getInstance()->setKeyboardMode(eRCInput::kmNone); clearBackgroundColor(); invalidate(); break; } default: break; } return eWidget::event(event, data, data2); }
void eSubtitleWidget::setPage(const eDVBTeletextSubtitlePage &p) { eDVBTeletextSubtitlePage newpage = p; m_page = p; m_page.clear(); m_page_ok = 1; invalidate(m_visible_region); // invalidate old visible regions m_visible_region.rects.clear(); unsigned int elements = newpage.m_elements.size(); if (elements) { int width = size().width() - startX * 2; std::string configvalue; bool original_position = eConfigManager::getConfigBoolValue("config.subtitles.ttx_subtitle_original_position"); bool rewrap = eConfigManager::getConfigBoolValue("config.subtitles.subtitle_rewrap"); int color_mode = eConfigManager::getConfigIntValue("config.subtitles.ttx_subtitle_colors", 1); gRGB color; bool original_colors = false; switch (color_mode) { case 0: /* use original teletext colors */ color = newpage.m_elements[0].m_color; original_colors = true; break; default: case 1: /* white */ color = gRGB(255, 255, 255); break; case 2: /* yellow */ color = gRGB(255, 255, 0); break; } if (!original_position) { int height = size().height() / 3; int lowerborder = eConfigManager::getConfigIntValue("config.subtitles.subtitle_position", 50); int line = newpage.m_elements[0].m_source_line; /* create a new page with just one text element */ m_page.m_elements.push_back(eDVBTeletextSubtitlePageElement(color, "", 0)); for (unsigned int i = 0; i < elements; ++i) { if (!m_page.m_elements[0].m_text.empty()) m_page.m_elements[0].m_text += " "; if (original_colors && color != newpage.m_elements[i].m_color) { color = newpage.m_elements[i].m_color; m_page.m_elements[0].m_text += (std::string)color; } if (line != newpage.m_elements[i].m_source_line) { line = newpage.m_elements[i].m_source_line; if (!rewrap) m_page.m_elements[0].m_text += "\\n"; } m_page.m_elements[0].m_text += newpage.m_elements[i].m_text; } eRect &area = m_page.m_elements[0].m_area; area.setLeft((size().width() - width) / 2); area.setTop(size().height() - height - lowerborder); area.setWidth(width); area.setHeight(height); m_visible_region |= area; } else { int size_per_element = (size().height() - 25) / 24; int line = newpage.m_elements[0].m_source_line; int currentelement = 0; m_page.m_elements.push_back(eDVBTeletextSubtitlePageElement(color, "", line)); for (unsigned int i = 0; i < elements; ++i) { if (!m_page.m_elements[currentelement].m_text.empty()) m_page.m_elements[currentelement].m_text += " "; if (original_colors && color != newpage.m_elements[i].m_color) { color = newpage.m_elements[i].m_color; m_page.m_elements[currentelement].m_text += (std::string)color; } if (line != newpage.m_elements[i].m_source_line) { line = newpage.m_elements[i].m_source_line; m_page.m_elements.push_back(eDVBTeletextSubtitlePageElement(color, "", line)); currentelement++; } m_page.m_elements[currentelement].m_text += newpage.m_elements[i].m_text; } for (unsigned int i = 0; i < m_page.m_elements.size(); i++) { eRect &area = m_page.m_elements[i].m_area; area.setLeft(startX); area.setTop(size_per_element * m_page.m_elements[i].m_source_line); area.setWidth(width); area.setHeight(size_per_element * 2); //teletext subtitles are double height only even lines are used m_visible_region |= area; } } } m_hide_subtitles_timer->start(7500, true); invalidate(m_visible_region); // invalidate new regions }
void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected) { ePtr<gFont> fnt; painter.clip(eRect(offset, m_itemsize)); style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal); bool validitem = (m_list && cursorValid()); eListboxStyle *local_style = 0; bool cursorValid = this->cursorValid(); gRGB border_color; int border_size = 0; /* get local listbox style, if present */ if (m_listbox) local_style = m_listbox->getLocalStyle(); if (local_style) { border_size = local_style->m_border_size; border_color = local_style->m_border_color; fnt = local_style->m_font; 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 (!fnt) fnt = new gFont("Regular", 20); /* if we have no transparent background */ if (!local_style || !local_style->m_transparent_background) { /* blit background picture, if available (otherwise, clear only) */ if (local_style && local_style->m_background && cursorValid) { if (validitem) painter.blit(local_style->m_background, offset, eRect(), 0); } else painter.clear(); } else { if (local_style->m_background && cursorValid) { if (validitem) painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHATEST); } else if (selected && !local_style->m_selection) painter.clear(); } if (validitem) { int gray = 0; ePyObject item = PyList_GET_ITEM(m_list, m_cursor); // borrowed reference! painter.setFont(fnt); /* the user can supply tuples, in this case the first one will be displayed. */ if (PyTuple_Check(item)) { if (PyTuple_Size(item) == 1) gray = 1; item = PyTuple_GET_ITEM(item, 0); } if (selected && local_style && local_style->m_selection) painter.blit(local_style->m_selection, offset, eRect(), gPainter::BT_ALPHATEST); if (item == Py_None) { /* seperator */ int half_height = m_itemsize.height() / 2; painter.fill(eRect(offset.x() + half_height, offset.y() + half_height - 2, m_itemsize.width() - m_itemsize.height(), 4)); } else { const char *string = PyString_Check(item) ? PyString_AsString(item) : "<not-a-string>"; ePoint text_offset = offset; if (gray) painter.setForegroundColor(gRGB(0x808080)); int flags = 0; if (local_style) { text_offset += local_style->m_text_offset; if (local_style->m_valign == eListboxStyle::alignTop) flags |= gPainter::RT_VALIGN_TOP; else if (local_style->m_valign == eListboxStyle::alignCenter) flags |= gPainter::RT_VALIGN_CENTER; else if (local_style->m_valign == eListboxStyle::alignBottom) flags |= gPainter::RT_VALIGN_BOTTOM; if (local_style->m_halign == eListboxStyle::alignLeft) flags |= gPainter::RT_HALIGN_LEFT; else if (local_style->m_halign == eListboxStyle::alignCenter) flags |= gPainter::RT_HALIGN_CENTER; else if (local_style->m_halign == eListboxStyle::alignRight) flags |= gPainter::RT_HALIGN_RIGHT; else if (local_style->m_halign == eListboxStyle::alignBlock) flags |= gPainter::RT_HALIGN_BLOCK; } painter.renderText(eRect(text_offset, m_itemsize), string, flags, border_color, border_size); } if (selected && (!local_style || !local_style->m_selection)) style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry); } painter.clippop(); }
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); 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 (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(tmp.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(); m_element_position[celServiceInfo].setLeft(area.left() + bbox.width() + 8 + xoffs); m_element_position[celServiceInfo].setTop(area.top()); m_element_position[celServiceInfo].setWidth(area.width() - (bbox.width() + 8 + xoffs)); m_element_position[celServiceInfo].setHeight(area.height()); if (m_servicetype_icon_mode && isPlayable) { 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]; int correction = (area.height() - pixmap_size.height()) / 2; m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + 8); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - 8); if (m_servicetype_icon_mode == 1) { area = m_element_position[celServiceName]; xoffs += pixmap_size.width() + 8; } area.moveBy(offset); painter.clip(area); painter.blit(pixmap, offset+ePoint(area.left(), 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) ||
int main(int argc, char **argv) { #ifdef MEMLEAK_CHECK atexit(DumpUnfreed); #endif #ifdef OBJECT_DEBUG atexit(object_dump); #endif #ifdef HAVE_GSTREAMER gst_init(&argc, &argv); #endif // set pythonpath if unset setenv("PYTHONPATH", LIBDIR "/enigma2/python", 0); printf("PYTHONPATH: %s\n", getenv("PYTHONPATH")); bsodLogInit(); ePython python; eMain main; #if 1 #ifdef WITH_SDL ePtr<gSDLDC> my_dc; gSDLDC::getInstance(my_dc); #else ePtr<gFBDC> my_dc; gFBDC::getInstance(my_dc); int double_buffer = my_dc->haveDoubleBuffering(); #endif 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(eSize(720, 576)); eWidgetDesktop dsk_lcd(eSize(132, 64)); dsk.setStyleID(0); dsk_lcd.setStyleID(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); ePtr<gPixmap> m_pm; loadPNG(m_pm, DATADIR "/enigma2/skin_default/pal.png"); if (!m_pm) { eFatal("pal.png not found!"); } else dsk.setPalette(*m_pm); 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[strlen(DATADIR) + 41]; sprintf(filename, DATADIR "/enigma2/skin_default/spinner/wait%d.png", i + 1); loadPNG(wait[i], filename); if (!wait[i]) { if (!i) eDebug("failed to load %s! (%m)", filename); 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)); #if defined(__sh__) evfd * vfd = new evfd; vfd->init(); delete vfd; #endif printf("executing main\n"); bsodCatchSignals(); setIoPrio(IOPRIO_CLASS_BE, 3); // python.execute("mytest", "__main__"); python.execFile("/usr/lib/enigma2/python/mytest.py"); 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(0, 0, 132, 64)); p.clear(); } return exit_code; }