Beispiel #1
0
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, "&apos;", "'");
				text = replace_all(text, "&quot;", "\"");
				text = replace_all(text, "&amp;", "&");
				text = replace_all(text, "&lt", "<");
				text = replace_all(text, "&gt", ">");

				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);
	}
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
	}
}
Beispiel #4
0
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;
}
Beispiel #5
0
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));
	}
}
Beispiel #6
0
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, "&apos;", "'");
				text = replace_all(text, "&quot;", "\"");
				text = replace_all(text, "&amp;", "&");
				text = replace_all(text, "&lt", "<");
				text = replace_all(text, "&gt", ">");

				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);
	}
}
Beispiel #7
0
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);
	}
}
Beispiel #8
0
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();
				}
			}
		}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
	}
}
Beispiel #12
0
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);
	}
}
Beispiel #13
0
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();
}
Beispiel #14
0
void eWidgetDesktop::resize(eSize size)
{
	m_screen.m_dirty_region = gRegion(eRect(ePoint(0, 0), size));
	m_screen.m_screen_size = size;
}
Beispiel #15
0
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 &region)
{
	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);
}
Beispiel #16
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;
}