diff --git a/data/keymap.xml b/data/keymap.xml
index cdfe3e178e..aaded682c3 100644
--- a/data/keymap.xml
+++ b/data/keymap.xml
@@ -387,7 +387,6 @@
@@ -600,7 +599,7 @@
diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp
index 583626c63e..629895f22c 100644
--- a/lib/dvb/db.cpp
+++ b/lib/dvb/db.cpp
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
/*
* Copyright (C) 2017 Marcus Metzler
@@ -222,15 +221,6 @@ bool eDVBService::isCrypted()
int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
{
- eServiceReferenceDVB sRelayOrigSref;
- ePtr refCur;
- eNavigation::getInstance()->getCurrentService(refCur);
- ePtr tmp_info;
- refCur->info(tmp_info);
- std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref);
- eServiceReferenceDVB currentlyPlaying = eServiceReferenceDVB(ref_s);
- bool res = currentlyPlaying.getSROriginal(sRelayOrigSref);
-
ePtr res_mgr;
bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false);
@@ -238,19 +228,13 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc
eDebug("[eDVBService] isPlayble... no res manager!!");
else
{
- eDVBChannelID chid, chid_ignore, chid_ignore_sr;
+ eDVBChannelID chid, chid_ignore;
int system;
((const eServiceReferenceDVB&)ref).getChannelID(chid);
((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
- if (res) {
- sRelayOrigSref.getChannelID(chid_ignore_sr);
- } else {
- chid_ignore_sr = eDVBChannelID();
- }
-
- if (res_mgr->canAllocateChannel(chid, chid_ignore, chid_ignore_sr, system, simulate))
+ if (res_mgr->canAllocateChannel(chid, chid_ignore, system, simulate))
{
bool use_ci_assignment = eConfigManager::getConfigBoolValue("config.misc.use_ci_assignment", false);
if (use_ci_assignment)
diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp
index 217a8ad5f7..4fd569af16 100644
--- a/lib/dvb/dvb.cpp
+++ b/lib/dvb/dvb.cpp
@@ -3,6 +3,7 @@
#include
#include
+#include
#include
#include
#include
@@ -1434,7 +1435,7 @@ int tuner_type_channel_default(ePtr &channellist, const eDVBCha
return 0;
}
-int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, const eDVBChannelID& ignoresr, int &system, bool simulate)
+int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, int &system, bool simulate)
{
std::list &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
int ret = 0;
@@ -1442,9 +1443,8 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons
if (!simulate && m_cached_channel)
{
eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
- if(channelid==cache_chan->getChannelID()) {
+ if(channelid==cache_chan->getChannelID())
return tuner_type_channel_default(m_list, channelid, system);
- }
}
/* first, check if a channel is already existing. */
@@ -1466,7 +1466,6 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons
std::vector fcc_decremented_fe_usecounts;
std::map fcc_chids;
int apply_to_ignore = 0;
- int apply_to_ignoresr = 0;
if (!eFCCServiceManager::getFCCChannelID(fcc_chids))
{
for (std::map::iterator i(fcc_chids.begin()); i != fcc_chids.end(); ++i)
@@ -1513,18 +1512,6 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons
}
}
- // For stream relayed channel make a check is it in the available channels and if it is ignore it
- if (ignoresr) {
- for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
- {
- if (i->m_channel_id == ignoresr)
- {
- apply_to_ignoresr = 1;
- break;
- }
- }
- }
-
for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
{
eSmartPtrList &frontends = simulate ? m_simulate_frontend : m_frontend;
@@ -1538,7 +1525,6 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons
// or 2 when the cached channel is not equal to the compared channel
int check_usecount = channel == &(*m_cached_channel) ? 1 : 0;
check_usecount += (apply_to_ignore+1) * 2; // one is used in eDVBServicePMTHandler and another is used in eDVBScan.
- check_usecount += apply_to_ignoresr;
//eDebug("[eDVBResourceManager] canAllocateChannel channel->getUseCount() : %d , check_usecount : %d (cached : %d)", channel->getUseCount(), check_usecount, channel == &(*m_cached_channel));
if (channel->getUseCount() == check_usecount) // channel only used once..(except fcc)
{
diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h
index 2243268d39..d523c0ff96 100644
--- a/lib/dvb/dvb.h
+++ b/lib/dvb/dvb.h
@@ -179,6 +179,7 @@ class eDVBResourceManager: public iObject, public sigc::trackable
ePtr m_list;
ePtr m_sec;
static eDVBResourceManager *instance;
+
friend class eDVBChannel;
friend class eFBCTunerManager;
ePtr m_fbcmng;
@@ -215,7 +216,7 @@ class eDVBResourceManager: public iObject, public sigc::trackable
};
RESULT connectChannelAdded(const sigc::slot &channelAdded, ePtr &connection);
- int canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore, const eDVBChannelID& ignoresr, int &system, bool simulate=false);
+ int canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore, int &system, bool simulate=false);
/* allocate channel... */
RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel, bool simulate=false);
diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp
index 3d89cb3730..d759fa4937 100644
--- a/lib/dvb/pmt.cpp
+++ b/lib/dvb/pmt.cpp
@@ -28,9 +28,15 @@
#include
#define PACK_VERSION(major,minor,micro) (((major) << 16) + ((minor) << 8) + (micro))
+#define UNPACK_VERSION(version,major,minor,micro) { \
+ major = (version)&0xff; \
+ minor = (version>>8)&0xff; \
+ micro = (version>>16)&0xff; \
+}
eDVBServicePMTHandler::eDVBServicePMTHandler()
- :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF), m_no_pat_entry_delay(eTimer::create())
+ :m_last_channel_state(-1), m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF),
+ m_no_pat_entry_delay(eTimer::create()), m_have_cached_program(false)
{
m_use_decode_demux = 0;
m_pmt_pid = -1;
@@ -524,7 +530,7 @@ PyObject *eDVBServicePMTHandler::getHbbTVApplications()
int eDVBServicePMTHandler::getProgramInfo(program &program)
{
- ePtr > ptr;
+// ePtr > ptr;
int cached_apid_ac3 = -1;
int cached_apid_ac4 = -1;
int cached_apid_ddp = -1;
@@ -1127,7 +1133,7 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, ePtr &s
if (isStreamRelay) {
sRelayOrigSref.getChannelID(chid);
res = m_resourceManager->allocateChannel(chid, m_sr_channel, simulate);
- }
+ }
if (m_sr_channel) {
diff --git a/lib/gdi/Makefile.inc b/lib/gdi/Makefile.inc
index 4a3f49fe9d..3644a8aee6 100644
--- a/lib/gdi/Makefile.inc
+++ b/lib/gdi/Makefile.inc
@@ -6,6 +6,7 @@ gdi_libenigma_gdi_a_SOURCES = \
gdi/accel.cpp \
gdi/bcm.cpp \
gdi/compositing.cpp \
+ gdi/drawing.cpp \
gdi/epng.cpp \
gdi/erect.cpp \
gdi/fb.cpp \
@@ -27,6 +28,7 @@ gdiincludedir = $(pkgincludedir)/lib/gdi
gdiinclude_HEADERS = \
gdi/accel.h \
gdi/compositing.h \
+ gdi/drawing.h \
gdi/epng.h \
gdi/epoint.h \
gdi/erect.h \
diff --git a/lib/gdi/drawing.cpp b/lib/gdi/drawing.cpp
new file mode 100644
index 0000000000..aa97f6ce69
--- /dev/null
+++ b/lib/gdi/drawing.cpp
@@ -0,0 +1,2043 @@
+/*
+Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
+
+Copyright (c) 2023-2024 openATV
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+1. Non-Commercial Use: You may not use the Software or any derivative works
+ for commercial purposes without obtaining explicit permission from the
+ copyright holder.
+2. Share Alike: If you distribute or publicly perform the Software or any
+ derivative works, you must do so under the same license terms, and you
+ must make the source code of any derivative works available to the
+ public.
+3. Attribution: You must give appropriate credit to the original author(s)
+ of the Software by including a prominent notice in your derivative works.
+THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE,
+ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more details about the CC BY-NC-SA 4.0 License, please visit:
+https://creativecommons.org/licenses/by-nc-sa/4.0/
+*/
+
+#include
+#include
+
+uint32_t *createGradientBuffer3(int graSize, const std::vector &colors)
+{
+ uint32_t *gradientBuf = (uint32_t *)malloc(graSize * sizeof(uint32_t));
+
+ uint32_t start_col = colors.at(0).argb();
+ uint32_t mid_col = colors.at(1).argb();
+ uint32_t end_col = colors.at(2).argb();
+
+ start_col ^= 0xFF000000;
+ mid_col ^= 0xFF000000;
+ end_col ^= 0xFF000000;
+
+ uint8_t start_a = (uint8_t)((start_col & 0xFF000000) >> 24);
+ uint8_t start_r = (uint8_t)((start_col & 0x00FF0000) >> 16);
+ uint8_t start_g = (uint8_t)((start_col & 0x0000FF00) >> 8);
+ uint8_t start_b = (uint8_t)(start_col & 0x000000FF);
+
+ uint8_t mid_a = (uint8_t)((mid_col & 0xFF000000) >> 24);
+ uint8_t mid_r = (uint8_t)((mid_col & 0x00FF0000) >> 16);
+ uint8_t mid_g = (uint8_t)((mid_col & 0x0000FF00) >> 8);
+ uint8_t mid_b = (uint8_t)(mid_col & 0x000000FF);
+
+ uint8_t end_a = (uint8_t)((end_col & 0xFF000000) >> 24);
+ uint8_t end_r = (uint8_t)((end_col & 0x00FF0000) >> 16);
+ uint8_t end_g = (uint8_t)((end_col & 0x0000FF00) >> 8);
+ uint8_t end_b = (uint8_t)(end_col & 0x000000FF);
+
+ float steps = (float)graSize;
+ float aStep1 = (float)(mid_a - start_a) / (steps / 2);
+ float rStep1 = (float)(mid_r - start_r) / (steps / 2);
+ float gStep1 = (float)(mid_g - start_g) / (steps / 2);
+ float bStep1 = (float)(mid_b - start_b) / (steps / 2);
+
+ float aStep2 = (float)(end_a - mid_a) / (steps / 2);
+ float rStep2 = (float)(end_r - mid_r) / (steps / 2);
+ float gStep2 = (float)(end_g - mid_g) / (steps / 2);
+ float bStep2 = (float)(end_b - mid_b) / (steps / 2);
+
+ if (gradientBuf != NULL)
+ {
+ for (int x = 0; x < graSize; x++)
+ {
+ uint8_t a, r, g, b;
+ if (x < graSize / 2)
+ {
+ a = (uint8_t)(start_a + aStep1 * x);
+ r = (uint8_t)(start_r + rStep1 * x);
+ g = (uint8_t)(start_g + gStep1 * x);
+ b = (uint8_t)(start_b + bStep1 * x);
+ }
+ else
+ {
+ a = (uint8_t)(mid_a + aStep2 * (x - graSize / 2));
+ r = (uint8_t)(mid_r + rStep2 * (x - graSize / 2));
+ g = (uint8_t)(mid_g + gStep2 * (x - graSize / 2));
+ b = (uint8_t)(mid_b + bStep2 * (x - graSize / 2));
+ }
+ gradientBuf[x] = (((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b);
+ }
+ }
+ return gradientBuf;
+}
+
+uint32_t *createGradientBuffer2(int graSize, const gRGB &startColor, const gRGB &endColor)
+{
+ uint32_t *gradientBuf = (uint32_t *)malloc(graSize * sizeof(uint32_t));
+
+ uint32_t start_col = startColor.argb();
+ start_col ^= 0xFF000000;
+
+ uint32_t end_col = endColor.argb();
+ end_col ^= 0xFF000000;
+
+ uint8_t start_a = (uint8_t)((start_col & 0xFF000000) >> 24);
+ uint8_t start_r = (uint8_t)((start_col & 0x00FF0000) >> 16);
+ uint8_t start_g = (uint8_t)((start_col & 0x0000FF00) >> 8);
+ uint8_t start_b = (uint8_t)(start_col & 0x000000FF);
+
+ uint8_t end_a = (uint8_t)((end_col & 0xFF000000) >> 24);
+ uint8_t end_r = (uint8_t)((end_col & 0x00FF0000) >> 16);
+ uint8_t end_g = (uint8_t)((end_col & 0x0000FF00) >> 8);
+ uint8_t end_b = (uint8_t)(end_col & 0x000000FF);
+
+ float steps = (float)graSize;
+ float aStep = (float)(end_a - start_a) / steps;
+ float rStep = (float)(end_r - start_r) / steps;
+ float gStep = (float)(end_g - start_g) / steps;
+ float bStep = (float)(end_b - start_b) / steps;
+
+ if (gradientBuf != nullptr)
+ {
+ for (int x = 0; x < graSize; x++)
+ {
+ uint8_t a = (uint8_t)(start_a + aStep * x);
+ uint8_t r = (uint8_t)(start_r + rStep * x);
+ uint8_t g = (uint8_t)(start_g + gStep * x);
+ uint8_t b = (uint8_t)(start_b + bStep * x);
+ gradientBuf[x] = ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | (uint32_t)b;
+ }
+ }
+ return gradientBuf;
+}
+
+static void blendPixelRounded(uint32_t *dst, const uint32_t *src, const double alpha)
+{
+ if (!((*src) & 0xFF000000))
+ return;
+
+ uint8_t r = (*src >> 24) & 0xFF;
+ uint8_t g = (*src >> 16) & 0xFF;
+ uint8_t b = (*src >> 8) & 0xFF;
+ uint8_t a = (*src >> 0) & 0xFF;
+
+ // Apply alpha blending
+ uint8_t newR = r * alpha;
+ uint8_t newG = g * alpha;
+ uint8_t newB = b * alpha;
+ uint8_t newA = a * alpha;
+
+ // Combine the new color with the existing pixel color using alpha blending
+ uint8_t oldR = (*dst >> 24) & 0xFF;
+ uint8_t oldG = (*dst >> 16) & 0xFF;
+ uint8_t oldB = (*dst >> 8) & 0xFF;
+ uint8_t oldA = (*dst >> 0) & 0xFF;
+
+ uint8_t finalR = newR + oldR * (1 - alpha);
+ uint8_t finalG = newG + oldG * (1 - alpha);
+ uint8_t finalB = newB + oldB * (1 - alpha);
+ uint8_t finalA = newA + oldA * (1 - alpha);
+
+ *dst = (finalR << 24) | (finalG << 16) | (finalB << 8) | finalA;
+}
+
+void drawAngleTl(gUnmanagedSurface *surface, const uint32_t *src, const eRect &area, uint8_t direction, const eRect &cornerRect, const CornerData &cornerData)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *dst = (uint32_t *)(((uint8_t *)surface->data) + y * surface->stride + rLeft * surface->bypp);
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ const uint32_t *s = src + (direction == 1 ? yInOriginalArea : xInOriginalArea);
+ *dst = *s;
+ ++dst;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ const uint32_t *s = src + (direction == 1 ? yInOriginalArea : xInOriginalArea);
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, s, alpha);
+ }
+ ++dst;
+ }
+ }
+}
+
+void drawAngleTr(gUnmanagedSurface *surface, const uint32_t *src, const eRect &area, uint8_t direction, const eRect &cornerRect, const CornerData &cornerData)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *dst = (uint32_t *)(((uint8_t *)surface->data) + y * surface->stride + rLeft * surface->bypp);
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ const uint32_t *s = src + (direction == 1 ? yInOriginalArea : xInOriginalArea);
+ *dst = *s;
+ ++dst;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ const uint32_t *s = src + (direction == 1 ? yInOriginalArea : xInOriginalArea);
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, s, alpha);
+ }
+ ++dst;
+ }
+ }
+}
+
+void drawAngleBl(gUnmanagedSurface *surface, const uint32_t *src, const eRect &area, uint8_t direction, const eRect &cornerRect, const CornerData &cornerData)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *dst = (uint32_t *)(((uint8_t *)surface->data) + y * surface->stride + rLeft * surface->bypp);
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ const uint32_t *s = src + (direction == 1 ? yInOriginalArea : xInOriginalArea);
+ *dst = *s;
+ ++dst;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ const uint32_t *s = src + (direction == 1 ? yInOriginalArea : xInOriginalArea);
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, s, alpha);
+ }
+ ++dst;
+ }
+ }
+}
+
+void drawAngleBr(gUnmanagedSurface *surface, const uint32_t *src, const eRect &area, uint8_t direction, const eRect &cornerRect, const CornerData &cornerData)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *dst = (uint32_t *)(((uint8_t *)surface->data) + y * surface->stride + rLeft * surface->bypp);
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ const uint32_t *s = src + (direction == 1 ? yInOriginalArea : xInOriginalArea);
+ *dst = *s;
+ ++dst;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ const uint32_t *s = src + (direction == 1 ? yInOriginalArea : xInOriginalArea);
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, s, alpha);
+ }
+ ++dst;
+ }
+ }
+}
+
+void drawAngle32Tl(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint32_t *srcptr = (uint32_t *)pixmap.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (rLeft - aLeft) + (rTop - aTop) * pixmap.surface->stride / 4;
+ dstptr += rLeft + rTop * surface->stride / 4;
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ if (!((*src) & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = *src++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ gRGB *gSrc = (gRGB *)src;
+ gRGB *gDst = (gRGB *)dst;
+ gDst->b += (((gSrc->b - gDst->b) * gSrc->a) >> 8);
+ gDst->g += (((gSrc->g - gDst->g) * gSrc->a) >> 8);
+ gDst->r += (((gSrc->r - gDst->r) * gSrc->a) >> 8);
+ gDst->a += (((0xFF - gDst->a) * gSrc->a) >> 8);
+ src++;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ *dst++ = *src++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+}
+
+void drawAngle32Tr(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint32_t *srcptr = (uint32_t *)pixmap.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (rLeft - aLeft) + (rTop - aTop) * pixmap.surface->stride / 4;
+ dstptr += rLeft + rTop * surface->stride / 4;
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ if (!((*src) & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = *src++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ gRGB *gSrc = (gRGB *)src;
+ gRGB *gDst = (gRGB *)dst;
+ gDst->b += (((gSrc->b - gDst->b) * gSrc->a) >> 8);
+ gDst->g += (((gSrc->g - gDst->g) * gSrc->a) >> 8);
+ gDst->r += (((gSrc->r - gDst->r) * gSrc->a) >> 8);
+ gDst->a += (((0xFF - gDst->a) * gSrc->a) >> 8);
+ src++;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ *dst++ = *src++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+}
+
+void drawAngle32Bl(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint32_t *srcptr = (uint32_t *)pixmap.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (rLeft - aLeft) + (rTop - aTop) * pixmap.surface->stride / 4;
+ dstptr += rLeft + rTop * surface->stride / 4;
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ if (!((*src) & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = *src++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ gRGB *gSrc = (gRGB *)src;
+ gRGB *gDst = (gRGB *)dst;
+ gDst->b += (((gSrc->b - gDst->b) * gSrc->a) >> 8);
+ gDst->g += (((gSrc->g - gDst->g) * gSrc->a) >> 8);
+ gDst->r += (((gSrc->r - gDst->r) * gSrc->a) >> 8);
+ gDst->a += (((0xFF - gDst->a) * gSrc->a) >> 8);
+ src++;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ *dst++ = *src++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+}
+
+void drawAngle32Br(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint32_t *srcptr = (uint32_t *)pixmap.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (rLeft - aLeft) + (rTop - aTop) * pixmap.surface->stride / 4;
+ dstptr += rLeft + rTop * surface->stride / 4;
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ if (!((*src) & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = *src++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ gRGB *gSrc = (gRGB *)src;
+ gRGB *gDst = (gRGB *)dst;
+ gDst->b += (((gSrc->b - gDst->b) * gSrc->a) >> 8);
+ gDst->g += (((gSrc->g - gDst->g) * gSrc->a) >> 8);
+ gDst->r += (((gSrc->r - gDst->r) * gSrc->a) >> 8);
+ gDst->a += (((0xFF - gDst->a) * gSrc->a) >> 8);
+ src++;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; y++)
+ {
+ int yInOriginalArea = y - aTop;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = rLeft; x < rRight; x++)
+ {
+ int xInOriginalArea = x - aLeft;
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ *dst++ = *src++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr = (uint32_t *)((uint8_t *)srcptr + pixmap.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+}
+
+void drawAngle32ScaledTl(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int src_bypp = pixmap.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = pixmap.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)pixmap.size().width() / (float)area.width();
+ const float scaleY = (float)pixmap.size().height() / (float)area.height();
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ if (*src & 0x80000000)
+ *dst = *src;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ const gRGB *src = (gRGB *)(src_row + src_x * src_bypp);
+ gRGB *gDst = (gRGB *)dst;
+ gDst->b += (((src->b - gDst->b) * src->a) >> 8);
+ gDst->g += (((src->g - gDst->g) * src->a) >> 8);
+ gDst->r += (((src->r - gDst->r) * src->a) >> 8);
+ gDst->a += (((0xFF - gDst->a) * src->a) >> 8);
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ *dst = *src;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+}
+
+void drawAngle32ScaledTr(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int src_bypp = pixmap.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = pixmap.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)pixmap.size().width() / (float)area.width();
+ const float scaleY = (float)pixmap.size().height() / (float)area.height();
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ if (*src & 0x80000000)
+ *dst = *src;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ const gRGB *src = (gRGB *)(src_row + src_x * src_bypp);
+ gRGB *gDst = (gRGB *)dst;
+ gDst->b += (((src->b - gDst->b) * src->a) >> 8);
+ gDst->g += (((src->g - gDst->g) * src->a) >> 8);
+ gDst->r += (((src->r - gDst->r) * src->a) >> 8);
+ gDst->a += (((0xFF - gDst->a) * src->a) >> 8);
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ *dst = *src;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+}
+
+void drawAngle32ScaledBl(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int src_bypp = pixmap.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = pixmap.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)pixmap.size().width() / (float)area.width();
+ const float scaleY = (float)pixmap.size().height() / (float)area.height();
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ if (*src & 0x80000000)
+ *dst = *src;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ const gRGB *src = (gRGB *)(src_row + src_x * src_bypp);
+ gRGB *gDst = (gRGB *)dst;
+ gDst->b += (((src->b - gDst->b) * src->a) >> 8);
+ gDst->g += (((src->g - gDst->g) * src->a) >> 8);
+ gDst->r += (((src->r - gDst->r) * src->a) >> 8);
+ gDst->a += (((0xFF - gDst->a) * src->a) >> 8);
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ *dst = *src;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+}
+
+void drawAngle32ScaledBr(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int src_bypp = pixmap.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = pixmap.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)pixmap.size().width() / (float)area.width();
+ const float scaleY = (float)pixmap.size().height() / (float)area.height();
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ if (*src & 0x80000000)
+ *dst = *src;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ const gRGB *src = (gRGB *)(src_row + src_x * src_bypp);
+ gRGB *gDst = (gRGB *)dst;
+ gDst->b += (((src->b - gDst->b) * src->a) >> 8);
+ gDst->g += (((src->g - gDst->g) * src->a) >> 8);
+ gDst->r += (((src->r - gDst->r) * src->a) >> 8);
+ gDst->a += (((0xFF - gDst->a) * src->a) >> 8);
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ *dst = *src;
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, src, alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+}
+
+void drawAngle8Tl(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const uint8_t *srcptr = (uint8_t *)pixmap.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (cornerRect.left() - area.left()) + (cornerRect.top() - area.top()) * pixmap.surface->stride;
+ dstptr += cornerRect.left() + cornerRect.top() * surface->stride / 4;
+ for (int y = cornerRect.top(); y < cornerRect.bottom(); y++)
+ {
+ int yInOriginalArea = y - area.top();
+ const uint8_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = cornerRect.left(); x < cornerRect.right(); x++)
+ {
+ int xInOriginalArea = x - area.left();
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ if (!(pal[*src] & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = pal[*src++];
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ gRGB *gDst = (gRGB *)dst;
+ gDst->alpha_blend(pal[*src++]);
+ dst++;
+ }
+ else
+ *dst++ = pal[*src++];
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr += pixmap.surface->stride;
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+}
+
+void drawAngle8Tr(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const uint8_t *srcptr = (uint8_t *)pixmap.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (cornerRect.left() - area.left()) + (cornerRect.top() - area.top()) * pixmap.surface->stride;
+ dstptr += cornerRect.left() + cornerRect.top() * surface->stride / 4;
+ for (int y = cornerRect.top(); y < cornerRect.bottom(); y++)
+ {
+ int yInOriginalArea = y - area.top();
+ const uint8_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = cornerRect.left(); x < cornerRect.right(); x++)
+ {
+ int xInOriginalArea = x - area.left();
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ if (!(pal[*src] & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = pal[*src++];
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ gRGB *gDst = (gRGB *)dst;
+ gDst->alpha_blend(pal[*src++]);
+ dst++;
+ }
+ else
+ *dst++ = pal[*src++];
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr += pixmap.surface->stride;
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+}
+
+void drawAngle8Bl(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const uint8_t *srcptr = (uint8_t *)pixmap.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (cornerRect.left() - area.left()) + (cornerRect.top() - area.top()) * pixmap.surface->stride;
+ dstptr += cornerRect.left() + cornerRect.top() * surface->stride / 4;
+ for (int y = cornerRect.top(); y < cornerRect.bottom(); y++)
+ {
+ int yInOriginalArea = y - area.top();
+ const uint8_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = cornerRect.left(); x < cornerRect.right(); x++)
+ {
+ int xInOriginalArea = x - area.left();
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ if (!(pal[*src] & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = pal[*src++];
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ gRGB *gDst = (gRGB *)dst;
+ gDst->alpha_blend(pal[*src++]);
+ dst++;
+ }
+ else
+ *dst++ = pal[*src++];
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr += pixmap.surface->stride;
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+}
+
+void drawAngle8Br(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const uint8_t *srcptr = (uint8_t *)pixmap.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (cornerRect.left() - area.left()) + (cornerRect.top() - area.top()) * pixmap.surface->stride;
+ dstptr += cornerRect.left() + cornerRect.top() * surface->stride / 4;
+ for (int y = cornerRect.top(); y < cornerRect.bottom(); y++)
+ {
+ int yInOriginalArea = y - area.top();
+ const uint8_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ for (int x = cornerRect.left(); x < cornerRect.right(); x++)
+ {
+ int xInOriginalArea = x - area.left();
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ if (!(pal[*src] & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = pal[*src++];
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ gRGB *gDst = (gRGB *)dst;
+ gDst->alpha_blend(pal[*src++]);
+ dst++;
+ }
+ else
+ *dst++ = pal[*src++];
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ ++dst;
+ ++src;
+ }
+ srcptr += pixmap.surface->stride;
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+}
+
+void drawAngle8ScaledTl(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int src_bypp = pixmap.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = pixmap.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)pixmap.size().width() / (float)area.width();
+ const float scaleY = (float)pixmap.size().height() / (float)area.height();
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ if (pal[*src] & 0x80000000)
+ *dst = pal[*src];
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ gRGB *gDst = (gRGB *)dst;
+ gDst->alpha_blend(pal[*src]);
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = cornerData.topLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = cornerData.topLeftCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topLeftCornerDRadius)
+ {
+ *dst = pal[*src];
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+}
+
+void drawAngle8ScaledTr(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int src_bypp = pixmap.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = pixmap.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)pixmap.size().width() / (float)area.width();
+ const float scaleY = (float)pixmap.size().height() / (float)area.height();
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ if (pal[*src] & 0x80000000)
+ *dst = pal[*src];
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ gRGB *gDst = (gRGB *)dst;
+ gDst->alpha_blend(pal[*src]);
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = xInOriginalArea - cornerData.w_topRightCornerRadius;
+ dy = cornerData.topRightCornerRadius - yInOriginalArea - 1 + cornerData.borderWidth;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.topRightCornerDRadius)
+ {
+ *dst = pal[*src];
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.topRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+}
+
+void drawAngle8ScaledBl(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int src_bypp = pixmap.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = pixmap.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)pixmap.size().width() / (float)area.width();
+ const float scaleY = (float)pixmap.size().height() / (float)area.height();
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ if (pal[*src] & 0x80000000)
+ *dst = pal[*src];
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ gRGB *gDst = (gRGB *)dst;
+ gDst->alpha_blend(pal[*src]);
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = cornerData.bottomLeftCornerRadius - xInOriginalArea - 1 + cornerData.borderWidth;
+ dy = yInOriginalArea - cornerData.h_bottomLeftCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomLeftCornerDRadius)
+ {
+ *dst = pal[*src];
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomLeftCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+}
+
+void drawAngle8ScaledBr(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag)
+{
+ double alpha = 1.0;
+ int dx = 0, dy = 0, squared_dst = 0;
+ const std::unordered_map &radiusData = cornerData.RadiusData;
+ const int src_bypp = pixmap.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = pixmap.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)pixmap.size().width() / (float)area.width();
+ const float scaleY = (float)pixmap.size().height() / (float)area.height();
+ const int aLeft = area.left();
+ const int aTop = area.top();
+ const int rLeft = cornerRect.left();
+ const int rRight = cornerRect.right();
+ const int rTop = cornerRect.top();
+ const int rBottom = cornerRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & gPixmap::blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ if (pal[*src] & 0x80000000)
+ *dst = pal[*src];
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & gPixmap::blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ gRGB *gDst = (gRGB *)dst;
+ gDst->alpha_blend(pal[*src]);
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)pixmap.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+ int yInOriginalArea = y - aTop;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int xInOriginalArea = x - aLeft;
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dx = xInOriginalArea - cornerData.w_bottomRightCornerRadius;
+ dy = yInOriginalArea - cornerData.h_bottomRightCornerRadius;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= cornerData.bottomRightCornerDRadius)
+ {
+ *dst = pal[*src];
+ dst++;
+ continue;
+ }
+ else if (squared_dst < cornerData.bottomRightCornerSRadius)
+ {
+ alpha = radiusData.at(squared_dst);
+ blendPixelRounded(dst, &pal[*src], alpha);
+ }
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+}
diff --git a/lib/gdi/drawing.h b/lib/gdi/drawing.h
new file mode 100644
index 0000000000..fa42fda503
--- /dev/null
+++ b/lib/gdi/drawing.h
@@ -0,0 +1,67 @@
+/*
+Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
+
+Copyright (c) 2023-2024 openATV
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+1. Non-Commercial Use: You may not use the Software or any derivative works
+ for commercial purposes without obtaining explicit permission from the
+ copyright holder.
+2. Share Alike: If you distribute or publicly perform the Software or any
+ derivative works, you must do so under the same license terms, and you
+ must make the source code of any derivative works available to the
+ public.
+3. Attribution: You must give appropriate credit to the original author(s)
+ of the Software by including a prominent notice in your derivative works.
+THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE,
+ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more details about the CC BY-NC-SA 4.0 License, please visit:
+https://creativecommons.org/licenses/by-nc-sa/4.0/
+*/
+
+#ifndef __drawing__
+#define __drawing__
+
+#include "gpixmap.h"
+#include
+
+void duplicate_32fc(uint32_t *out, const uint32_t in, size_t size);
+uint32_t *createGradientBuffer2(int graSize, const gRGB &startColor, const gRGB &endColor);
+uint32_t *createGradientBuffer3(int graSize, const std::vector &colors);
+void drawAngleTl(gUnmanagedSurface *surface, const uint32_t *src, const eRect &area, uint8_t direction, const eRect &cornerRect, const CornerData &cornerData);
+void drawAngleTr(gUnmanagedSurface *surface, const uint32_t *src, const eRect &area, uint8_t direction, const eRect &cornerRect, const CornerData &cornerData);
+void drawAngleBl(gUnmanagedSurface *surface, const uint32_t *src, const eRect &area, uint8_t direction, const eRect &cornerRect, const CornerData &cornerData);
+void drawAngleBr(gUnmanagedSurface *surface, const uint32_t *src, const eRect &area, uint8_t direction, const eRect &cornerRect, const CornerData &cornerData);
+
+void drawAngle32Tl(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle32Tr(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle32Bl(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle32Br(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+
+void drawAngle32ScaledTl(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle32ScaledTr(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle32ScaledBl(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle32ScaledBr(gUnmanagedSurface *surface, const gPixmap &pixmap, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+
+void drawAngle8Tl(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle8Tr(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle8Bl(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle8Br(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+
+void drawAngle8ScaledTl(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle8ScaledTr(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle8ScaledBl(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+void drawAngle8ScaledBr(gUnmanagedSurface *surface, const gPixmap &pixmap, const uint32_t *pal, const eRect &area, const eRect &cornerRect, const CornerData &cornerData, int flag);
+
+#endif
\ No newline at end of file
diff --git a/lib/gdi/epng.cpp b/lib/gdi/epng.cpp
index b1e1ff8772..ea5ae57687 100644
--- a/lib/gdi/epng.cpp
+++ b/lib/gdi/epng.cpp
@@ -368,7 +368,7 @@ static int savePNGto(FILE *fp, gPixmap *pixmap)
return 0;
}
-int loadSVG(ePtr &result, const char *filename, int cached, int width, int height, float scale, int keepAspect)
+int loadSVG(ePtr &result, const char *filename, int cached, int width, int height, float scale, int keepAspect, int align)
{
result = nullptr;
int size = 0;
@@ -388,6 +388,8 @@ int loadSVG(ePtr &result, const char *filename, int cached, int width,
NSVGrasterizer *rast = nullptr;
double xscale = 1.0;
double yscale = 1.0;
+ double tx = 0.0;
+ double ty = 0.0;
image = nsvgParseFromFile(filename, "px", 96.0);
if (image == nullptr)
@@ -412,8 +414,11 @@ int loadSVG(ePtr &result, const char *filename, int cached, int width,
double scale = std::min(widthScale, heightScale);
yscale = scale;
xscale = scale;
- width = (int)(image->width * xscale);
- height = (int)(image->height * scale);
+ int new_width = (int)(image->width * xscale);
+ int new_height = (int)(image->height * scale);
+ if (align == 2) tx = width - new_width; // Right alignment
+ else if (align == 4) tx = (int)(((double)(width - new_width))/2); // Center alignment
+ ty = (int)(((double)(height - new_height))/2);
} else {
if (height > 0)
yscale = ((double) height) / image->height;
@@ -456,7 +461,7 @@ int loadSVG(ePtr &result, const char *filename, int cached, int width,
eDebug("[ePNG] loadSVG %s %dx%d from %dx%d", filename, width, height, (int)image->width, (int)image->height);
// Rasterizes SVG image, returns RGBA image (non-premultiplied alpha)
- nsvgRasterizeFull(rast, image, 0, 0, xscale, yscale, (unsigned char*)result->surface->data, width, height, width * 4, 1);
+ nsvgRasterizeFull(rast, image, tx, ty, xscale, yscale, (unsigned char*)result->surface->data, width, height, width * 4, 1);
if (cached)
PixmapCache::Set(cachefile, result);
diff --git a/lib/gdi/epng.h b/lib/gdi/epng.h
index 39bda350b1..2b1ff6d4b5 100644
--- a/lib/gdi/epng.h
+++ b/lib/gdi/epng.h
@@ -6,7 +6,7 @@
SWIG_VOID(int) loadPNG(ePtr &SWIG_OUTPUT, const char *filename, int accel = 0, int cached = 1);
SWIG_VOID(int) loadJPG(ePtr &SWIG_OUTPUT, const char *filename, int cached = 0);
SWIG_VOID(int) loadJPG(ePtr &SWIG_OUTPUT, const char *filename, ePtr alpha, int cached = 0);
-SWIG_VOID(int) loadSVG(ePtr &SWIG_OUTPUT, const char *filename, int cached = 1, int width = 0, int height = 0, float scale = 0, int keepAspect = 0);
+SWIG_VOID(int) loadSVG(ePtr &SWIG_OUTPUT, const char *filename, int cached = 1, int width = 0, int height = 0, float scale = 0, int keepAspect = 0, int align = 0);
int loadImage(ePtr &result, const char *filename, int accel = 0, int width = 0, int height = 0);
int savePNG(const char *filename, gPixmap *pixmap);
diff --git a/lib/gdi/gpixmap.cpp b/lib/gdi/gpixmap.cpp
index 8c66546e42..322b386b0b 100644
--- a/lib/gdi/gpixmap.cpp
+++ b/lib/gdi/gpixmap.cpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include
#ifdef __GLIBC__
@@ -455,18 +456,1192 @@ static void convert_palette(uint32_t* pal, const gPalette& clut)
#define FIX 0x10000
-void gPixmap::blit(const gPixmap &src, const eRect &_pos, const gRegion &clip, int flag)
+void gPixmap::drawRectangle(const gRegion ®ion, const eRect &area, const gRGB &backgroundColor, const gRGB &borderColor, int borderWidth, const std::vector &gradientColors, uint8_t direction, int radius, uint8_t edges, bool alphablend, int gradientFullSize)
+{
+ if (surface->bpp < 32)
+ {
+ eWarning("[gPixmap] couldn't rgbfill %d bpp", surface->bpp);
+ return;
+ }
+
+ const uint8_t GRADIENT_VERTICAL = 1;
+ uint32_t backColor = backgroundColor.argb();
+ backColor ^= 0xFF000000;
+ uint32_t borderCol = borderColor.argb();
+ borderCol ^= 0xFF000000;
+ uint32_t *gradientBuf = nullptr;
+
+ const int gradientSize = (gradientFullSize) ? gradientFullSize : (direction == GRADIENT_VERTICAL) ? area.height() : area.width();
+
+ if(!direction)
+ gradientBuf = createGradientBuffer2(gradientSize, backgroundColor, backgroundColor);
+ else if(gradientColors.at(1) == gradientColors.at(2))
+ gradientBuf = createGradientBuffer2(gradientSize, gradientColors.at(0), gradientColors.at(1));
+ else
+ gradientBuf = createGradientBuffer3(gradientSize, gradientColors);
+
+ CornerData cornerData(radius, edges, area.width(), area.height(), borderWidth, borderCol);
+
+ for (unsigned int i = 0; i < region.rects.size(); ++i)
+ {
+ eRect reg = area;
+ reg &= region.rects[i];
+
+ if (reg.empty())
+ continue;
+
+ int corners = 0;
+ eRect cornerRect;
+
+ if (cornerData.topLeftCornerRadius)
+ {
+ cornerRect = eRect(area.left(), area.top(), cornerData.topLeftCornerRadius, cornerData.topLeftCornerRadius);
+ cornerRect &= region.rects[i];
+ if (!cornerRect.empty())
+ {
+ corners += 1;
+ drawAngleTl(surface, gradientBuf, area, direction, cornerRect, cornerData);
+ }
+ }
+ if (cornerData.topRightCornerRadius)
+ {
+ cornerRect = eRect(area.right() - cornerData.topRightCornerRadius, area.top(), cornerData.topRightCornerRadius, cornerData.topRightCornerRadius);
+ cornerRect &= region.rects[i];
+ if (!cornerRect.empty())
+ {
+ corners += 2;
+ drawAngleTr(surface, gradientBuf, area, direction, cornerRect, cornerData);
+ }
+ }
+ if (cornerData.bottomLeftCornerRadius)
+ {
+ cornerRect = eRect(area.left(), area.bottom() - cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius);
+ cornerRect &= region.rects[i];
+ if (!cornerRect.empty())
+ {
+ corners += 4;
+ drawAngleBl(surface, gradientBuf, area, direction, cornerRect, cornerData);
+ }
+ }
+
+ if (cornerData.bottomRightCornerRadius)
+ {
+ cornerRect = eRect(area.right() - cornerData.bottomRightCornerRadius, area.bottom() - cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius);
+ cornerRect &= region.rects[i];
+ if (!cornerRect.empty())
+ {
+ corners += 8;
+ drawAngleBr(surface, gradientBuf, area, direction, cornerRect, cornerData);
+ }
+ }
+
+ if (cornerData.isCircle)
+ continue;
+
+ const int bottom = MAX(cornerData.bottomRightCornerRadius, cornerData.bottomLeftCornerRadius);
+ const int top = MAX(cornerData.topRightCornerRadius, cornerData.topLeftCornerRadius);
+
+ int topw = area.width();
+ int topl = area.left();
+ int bottomw = area.width();
+ int bottoml = area.left();
+
+ if (corners & 1)
+ {
+ topw -= cornerData.topLeftCornerRadius;
+ topl += cornerData.topLeftCornerRadius;
+ }
+ if (corners & 2)
+ topw -= cornerData.topRightCornerRadius;
+
+ if (corners & 4)
+ {
+ bottomw -= cornerData.bottomLeftCornerRadius;
+ bottoml += cornerData.bottomLeftCornerRadius;
+ }
+ if (corners & 8)
+ bottomw -= cornerData.bottomRightCornerRadius;
+
+ eRect topRect = eRect(topl, area.top(), topw, top);
+ topRect &= region.rects[i];
+
+ eRect bottomRect = eRect(bottoml, area.bottom() - bottom, bottomw, bottom);
+ bottomRect &= region.rects[i];
+
+ eRect mRect = eRect(area.left(), area.top() + top, area.width(), area.height() - top - bottom);
+ mRect &= region.rects[i];
+ const int blendRatio = 12;
+ if (!mRect.empty())
+ {
+ if (alphablend && !cornerData.radiusSet)
+ {
+ for (int y = mRect.top(); y < mRect.bottom(); y++)
+ {
+ uint32_t *dstptr = (uint32_t *)(((uint8_t *)surface->data) + y * surface->stride + mRect.left() * surface->bypp);
+ uint32_t *gradientBuf2 = gradientBuf + mRect.left() - area.left();
+ int width = mRect.width();
+ gRGB *src = (gRGB *)gradientBuf2;
+ gRGB *dst = (gRGB *)dstptr;
+ while (width >= blendRatio)
+ {
+ for (int i = 0; i < blendRatio; ++i)
+ {
+ dst[i].b += (((src->b - dst[i].b) * src->a) >> 8);
+ dst[i].g += (((src->g - dst[i].g) * src->a) >> 8);
+ dst[i].r += (((src->r - dst[i].r) * src->a) >> 8);
+ dst[i].a += (((0xFF - dst[i].a) * src->a) >> 8);
+ }
+
+ dst += blendRatio;
+ src += blendRatio;
+ width -= blendRatio;
+ }
+
+ while (width > 0)
+ {
+ dst->b += (((src->b - dst->b) * src->a) >> 8);
+ dst->g += (((src->g - dst->g) * src->a) >> 8);
+ dst->r += (((src->r - dst->r) * src->a) >> 8);
+ dst->a += (((0xFF - dst->a) * src->a) >> 8);
+
+ ++dst;
+ ++src;
+ --width;
+ }
+ }
+ }
+ else
+ {
+ int linesize = mRect.width() * surface->bypp;
+ for (int y = mRect.top(); y < mRect.bottom(); y++)
+ {
+ uint32_t *dst = (uint32_t *)(((uint8_t *)surface->data) + y * surface->stride + mRect.left() * surface->bypp);
+ uint32_t *gradientBuf2 = gradientBuf + mRect.left() - area.left();
+ std::memcpy(dst, gradientBuf2, linesize);
+ }
+ } // if blitAlphaBlend
+ } // if center
+
+ if (top && !topRect.empty())
+ {
+ int linesize = topRect.width() * surface->bypp;
+ for (int y = topRect.top(); y < topRect.bottom(); y++)
+ {
+ uint32_t *dst = (uint32_t *)(((uint8_t *)surface->data) + y * surface->stride + topRect.left() * surface->bypp);
+ uint32_t *gradientBuf2 = gradientBuf + topRect.left() - area.left();
+ std::memcpy(dst, gradientBuf2, linesize);
+ }
+ } // if top
+
+ if (bottom && !bottomRect.empty())
+ {
+ int linesize = bottomRect.width() * surface->bypp;
+ for (int y = bottomRect.top(); y < bottomRect.bottom(); y++)
+ {
+ uint32_t *dst = (uint32_t *)(((uint8_t *)surface->data) + y * surface->stride + bottomRect.left() * surface->bypp);
+ uint32_t *gradientBuf2 = gradientBuf + bottomRect.left() - area.left();
+ std::memcpy(dst, gradientBuf2, linesize);
+ }
+ }
+
+ } // for region
+
+ if (gradientBuf)
+ free(gradientBuf);
+}
+
+void gPixmap::blitRounded32Bit(const gPixmap &src, const eRect &pos, const eRect &clip, int cornerRadius, int edges, int flag)
+{
+ CornerData cornerData(cornerRadius, edges, pos.width(), pos.height(), 0, 0xFF000000);
+ int corners = 0;
+ eRect cornerRect;
+ if (cornerData.topLeftCornerRadius)
+ {
+ cornerRect = eRect(pos.left(), pos.top(), cornerData.topLeftCornerRadius, cornerData.topLeftCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 1;
+ drawAngle32Tl(surface, src, pos, cornerRect, cornerData, flag);
+ }
+ }
+ if (cornerData.topRightCornerRadius)
+ {
+ cornerRect = eRect(pos.right() - cornerData.topRightCornerRadius, pos.top(), cornerData.topRightCornerRadius, cornerData.topRightCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 2;
+ drawAngle32Tr(surface, src, pos, cornerRect, cornerData, flag);
+ }
+ }
+ if (cornerData.bottomLeftCornerRadius)
+ {
+ cornerRect = eRect(pos.left(), pos.bottom() - cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 4;
+ drawAngle32Bl(surface, src, pos, cornerRect, cornerData, flag);
+ }
+ }
+
+ if (cornerData.bottomRightCornerRadius)
+ {
+ cornerRect = eRect(pos.right() - cornerData.bottomRightCornerRadius, pos.bottom() - cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 8;
+ drawAngle32Br(surface, src, pos, cornerRect, cornerData, flag);
+ }
+ }
+
+ if (cornerData.isCircle)
+ return;
+
+ const int bottom = MAX(cornerData.bottomRightCornerRadius, cornerData.bottomLeftCornerRadius);
+ const int top = MAX(cornerData.topRightCornerRadius, cornerData.topLeftCornerRadius);
+
+ int topw = pos.width();
+ int topl = pos.left();
+ int bottomw = pos.width();
+ int bottoml = pos.left();
+
+ if (corners & 1)
+ {
+ topw -= cornerData.topLeftCornerRadius;
+ topl += cornerData.topLeftCornerRadius;
+ }
+ if (corners & 2)
+ topw -= cornerData.topRightCornerRadius;
+
+ if (corners & 4)
+ {
+ bottomw -= cornerData.bottomLeftCornerRadius;
+ bottoml += cornerData.bottomLeftCornerRadius;
+ }
+ if (corners & 8)
+ bottomw -= cornerData.bottomRightCornerRadius;
+
+ eRect topRect = eRect(topl, pos.top(), topw, top);
+ topRect &= clip;
+
+ eRect bottomRect = eRect(bottoml, pos.bottom() - bottom, bottomw, bottom);
+ bottomRect &= clip;
+
+ eRect mRect = eRect(pos.left(), pos.top() + top, pos.width(), pos.height() - top - bottom);
+ mRect &= clip;
+
+ const int aLeft = pos.left();
+ const int aTop = pos.top();
+
+ if (!mRect.empty())
+ {
+ const int rLeft = mRect.left();
+ const int rTop = mRect.top();
+ const int rBottom = mRect.bottom();
+ const int rWidth = mRect.width();
+ int linesize = rWidth * surface->bypp;
+ uint32_t *srcptr = (uint32_t *)src.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (rLeft - aLeft) + (rTop - aTop) * src.surface->stride / 4;
+ dstptr += rLeft + rTop * surface->stride / 4;
+ for (int y = rTop; y < rBottom; y++)
+ {
+ if (flag & blitAlphaTest)
+ {
+ int width = rWidth;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ while (width--)
+ {
+ if (!((*src) & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = *src++;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ int width = rWidth;
+ gRGB *src = (gRGB *)srcptr;
+ gRGB *dst = (gRGB *)dstptr;
+
+ while (width--) {
+ dst->b += (((src->b - dst->b) * src->a) >> 8);
+ dst->g += (((src->g - dst->g) * src->a) >> 8);
+ dst->r += (((src->r - dst->r) * src->a) >> 8);
+ dst->a += (((0xFF - dst->a) * src->a) >> 8);
+ ++src;
+ ++dst;
+ }
+ }
+ else
+ std::memcpy(dstptr, srcptr, linesize);
+ srcptr = (uint32_t *)((uint8_t *)srcptr + src.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ if (top && !topRect.empty())
+ {
+ const int rLeft = topRect.left();
+ const int rTop = topRect.top();
+ const int rBottom = topRect.bottom();
+ const int rWidth = topRect.width();
+ int linesize = rWidth * surface->bypp;
+ uint32_t *srcptr = (uint32_t *)src.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (rLeft - aLeft) + (rTop - aTop) * src.surface->stride / 4;
+ dstptr += rLeft + rTop * surface->stride / 4;
+ for (int y = rTop; y < rBottom; y++)
+ {
+ if (flag & blitAlphaTest)
+ {
+ int width = rWidth;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ while (width--)
+ {
+ if (!((*src) & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = *src++;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ int width = rWidth;
+ gRGB *src = (gRGB *)srcptr;
+ gRGB *dst = (gRGB *)dstptr;
+
+ while (width--) {
+ dst->b += (((src->b - dst->b) * src->a) >> 8);
+ dst->g += (((src->g - dst->g) * src->a) >> 8);
+ dst->r += (((src->r - dst->r) * src->a) >> 8);
+ dst->a += (((0xFF - dst->a) * src->a) >> 8);
+ ++src;
+ ++dst;
+ }
+ }
+ else
+ std::memcpy(dstptr, srcptr, linesize);
+ srcptr = (uint32_t *)((uint8_t *)srcptr + src.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+
+ if (bottom && !bottomRect.empty())
+ {
+ const int rLeft = bottomRect.left();
+ const int rTop = bottomRect.top();
+ const int rBottom = bottomRect.bottom();
+ const int rWidth = bottomRect.width();
+ int linesize = rWidth * surface->bypp;
+ uint32_t *srcptr = (uint32_t *)src.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (rLeft - aLeft) + (rTop - aTop) * src.surface->stride / 4;
+ dstptr += rLeft + rTop * surface->stride / 4;
+ for (int y = rTop; y < rBottom; y++)
+ {
+ if (flag & blitAlphaTest)
+ {
+ int width = rWidth;
+ uint32_t *src = srcptr;
+ uint32_t *dst = dstptr;
+
+ while (width--)
+ {
+ if (!((*src) & 0xFF000000))
+ {
+ src++;
+ dst++;
+ }
+ else
+ *dst++ = *src++;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ int width = rWidth;
+ gRGB *src = (gRGB *)srcptr;
+ gRGB *dst = (gRGB *)dstptr;
+
+ while (width--) {
+ dst->b += (((src->b - dst->b) * src->a) >> 8);
+ dst->g += (((src->g - dst->g) * src->a) >> 8);
+ dst->r += (((src->r - dst->r) * src->a) >> 8);
+ dst->a += (((0xFF - dst->a) * src->a) >> 8);
+ ++src;
+ ++dst;
+ }
+ }
+ else
+ std::memcpy(dstptr, srcptr, linesize);
+ srcptr = (uint32_t *)((uint8_t *)srcptr + src.surface->stride);
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+}
+
+void gPixmap::blitRounded32BitScaled(const gPixmap &src, const eRect &pos, const eRect &clip, int cornerRadius, int edges, int flag)
+{
+ CornerData cornerData(cornerRadius, edges, pos.width(), pos.height(), 0, 0xFF000000);
+ int corners = 0;
+ eRect cornerRect;
+ if (cornerData.topLeftCornerRadius)
+ {
+ cornerRect = eRect(pos.left(), pos.top(), cornerData.topLeftCornerRadius, cornerData.topLeftCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 1;
+ drawAngle32ScaledTl(surface, src, pos, cornerRect, cornerData, flag);
+ }
+ }
+ if (cornerData.topRightCornerRadius)
+ {
+ cornerRect = eRect(pos.right() - cornerData.topRightCornerRadius, pos.top(), cornerData.topRightCornerRadius, cornerData.topRightCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 2;
+ drawAngle32ScaledTr(surface, src, pos, cornerRect, cornerData, flag);
+ }
+ }
+ if (cornerData.bottomLeftCornerRadius)
+ {
+ cornerRect = eRect(pos.left(), pos.bottom() - cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 4;
+ drawAngle32ScaledBl(surface, src, pos, cornerRect, cornerData, flag);
+ }
+ }
+
+ if (cornerData.bottomRightCornerRadius)
+ {
+ cornerRect = eRect(pos.right() - cornerData.bottomRightCornerRadius, pos.bottom() - cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 8;
+ drawAngle32ScaledBr(surface, src, pos, cornerRect, cornerData, flag);
+ }
+ }
+
+ if (cornerData.isCircle)
+ return;
+
+ const int bottom = MAX(cornerData.bottomRightCornerRadius, cornerData.bottomLeftCornerRadius);
+ const int top = MAX(cornerData.topRightCornerRadius, cornerData.topLeftCornerRadius);
+
+ int topw = pos.width();
+ int topl = pos.left();
+ int bottomw = pos.width();
+ int bottoml = pos.left();
+
+ if (corners & 1)
+ {
+ topw -= cornerData.topLeftCornerRadius;
+ topl += cornerData.topLeftCornerRadius;
+ }
+ if (corners & 2)
+ topw -= cornerData.topRightCornerRadius;
+
+ if (corners & 4)
+ {
+ bottomw -= cornerData.bottomLeftCornerRadius;
+ bottoml += cornerData.bottomLeftCornerRadius;
+ }
+ if (corners & 8)
+ bottomw -= cornerData.bottomRightCornerRadius;
+
+ eRect topRect = eRect(topl, pos.top(), topw, top);
+ topRect &= clip;
+
+ eRect bottomRect = eRect(bottoml, pos.bottom() - bottom, bottomw, bottom);
+ bottomRect &= clip;
+
+ eRect mRect = eRect(pos.left(), pos.top() + top, pos.width(), pos.height() - top - bottom);
+ mRect &= clip;
+
+ const int src_bypp = src.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = src.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)src.size().width() / (float)pos.width();
+ const float scaleY = (float)src.size().height() / (float)pos.height();
+ const int aLeft = pos.left();
+ const int aTop = pos.top();
+
+ if (!mRect.empty())
+ {
+ const int rLeft = mRect.left();
+ const int rRight = mRect.right();
+ const int rTop = mRect.top();
+ const int rBottom = mRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+ if (flag & blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ if (*src & 0x80000000)
+ *dst = *src;
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ gRGB *dst = (gRGB *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const gRGB *src = (gRGB *)(src_row + src_x * src_bypp);
+ dst->b += (((src->b - dst->b) * src->a) >> 8);
+ dst->g += (((src->g - dst->g) * src->a) >> 8);
+ dst->r += (((src->r - dst->r) * src->a) >> 8);
+ dst->a += (((0xFF - dst->a) * src->a) >> 8);
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ *dst++ = *src;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ }
+ if (top && !topRect.empty())
+ {
+ const int rLeft = topRect.left();
+ const int rRight = topRect.right();
+ const int rTop = topRect.top();
+ const int rBottom = topRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ if (*src & 0x80000000)
+ *dst = *src;
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ gRGB *dst = (gRGB *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const gRGB *src = (gRGB *)(src_row + src_x * src_bypp);
+ dst->b += (((src->b - dst->b) * src->a) >> 8);
+ dst->g += (((src->g - dst->g) * src->a) >> 8);
+ dst->r += (((src->r - dst->r) * src->a) >> 8);
+ dst->a += (((0xFF - dst->a) * src->a) >> 8);
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ *dst = *src;
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ }
+ if (bottom && !bottomRect.empty())
+ {
+ const int rLeft = bottomRect.left();
+ const int rRight = bottomRect.right();
+ const int rTop = bottomRect.top();
+ const int rBottom = bottomRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ if (*src & 0x80000000)
+ *dst = *src;
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ gRGB *dst = (gRGB *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const gRGB *src = (gRGB *)(src_row + src_x * src_bypp);
+ dst->b += (((src->b - dst->b) * src->a) >> 8);
+ dst->g += (((src->g - dst->g) * src->a) >> 8);
+ dst->r += (((src->r - dst->r) * src->a) >> 8);
+ dst->a += (((0xFF - dst->a) * src->a) >> 8);
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint32_t *src = (const uint32_t *)(src_row + src_x * src_bypp);
+ *dst = *src;
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ }
+}
+
+void gPixmap::blitRounded8Bit(const gPixmap &src, const eRect &pos, const eRect &clip, int cornerRadius, int edges, int flag)
+{
+
+ int corners = 0;
+ uint32_t pal[256];
+ convert_palette(pal, src.surface->clut);
+ CornerData cornerData(cornerRadius, edges, pos.width(), pos.height(), 0, 0xFF000000);
+ eRect cornerRect;
+ if (cornerData.topLeftCornerRadius)
+ {
+ cornerRect = eRect(pos.left(), pos.top(), cornerData.topLeftCornerRadius, cornerData.topLeftCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 1;
+ drawAngle8Tl(surface, src, pal, pos, cornerRect, cornerData, flag);
+ }
+ }
+ if (cornerData.topRightCornerRadius)
+ {
+ cornerRect = eRect(pos.right() - cornerData.topRightCornerRadius, pos.top(), cornerData.topRightCornerRadius, cornerData.topRightCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 2;
+ drawAngle8Tr(surface, src, pal, pos, cornerRect, cornerData, flag);
+ }
+ }
+ if (cornerData.bottomLeftCornerRadius)
+ {
+ cornerRect = eRect(pos.left(), pos.bottom() - cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 4;
+ drawAngle8Bl(surface, src, pal, pos, cornerRect, cornerData, flag);
+ }
+ }
+
+ if (cornerData.bottomRightCornerRadius)
+ {
+ cornerRect = eRect(pos.right() - cornerData.bottomRightCornerRadius, pos.bottom() - cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 8;
+ drawAngle8Br(surface, src, pal, pos, cornerRect, cornerData, flag);
+ }
+ }
+
+ if (cornerData.isCircle)
+ return;
+
+ const int bottom = MAX(cornerData.bottomRightCornerRadius, cornerData.bottomLeftCornerRadius);
+ const int top = MAX(cornerData.topRightCornerRadius, cornerData.topLeftCornerRadius);
+
+ int topw = pos.width();
+ int topl = pos.left();
+ int bottomw = pos.width();
+ int bottoml = pos.left();
+
+ if (corners & 1)
+ {
+ topw -= cornerData.topLeftCornerRadius;
+ topl += cornerData.topLeftCornerRadius;
+ }
+ if (corners & 2)
+ topw -= cornerData.topRightCornerRadius;
+
+ if (corners & 4)
+ {
+ bottomw -= cornerData.bottomLeftCornerRadius;
+ bottoml += cornerData.bottomLeftCornerRadius;
+ }
+ if (corners & 8)
+ bottomw -= cornerData.bottomRightCornerRadius;
+
+ eRect topRect = eRect(topl, pos.top(), topw, top);
+ topRect &= clip;
+
+ eRect bottomRect = eRect(bottoml, pos.bottom() - bottom, bottomw, bottom);
+ bottomRect &= clip;
+
+ eRect mRect = eRect(pos.left(), pos.top() + top, pos.width(), pos.height() - top - bottom);
+ mRect &= clip;
+
+ if (!mRect.empty())
+ {
+ const uint8_t *srcptr = (uint8_t *)src.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (mRect.left() - pos.left()) + (mRect.top() - pos.top()) * src.surface->stride;
+ dstptr += mRect.left() + mRect.top() * surface->stride / 4;
+ for (int y = mRect.bottom(); y > mRect.top(); --y)
+ {
+ if (flag & blitAlphaTest)
+ {
+ blit_8i_to_32_at((uint32_t *)dstptr, srcptr, pal, mRect.width());
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ blit_8i_to_32_ab((gRGB *)dstptr, srcptr, (const gRGB *)pal, mRect.width());
+ }
+ else
+ blit_8i_to_32((uint32_t *)dstptr, srcptr, pal, mRect.width());
+ srcptr += src.surface->stride;
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+ if (top && !topRect.empty())
+ {
+ const uint8_t *srcptr = (uint8_t *)src.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (topRect.left() - pos.left()) + (topRect.top() - pos.top()) * src.surface->stride;
+ dstptr += topRect.left() + topRect.top() * surface->stride / 4;
+ for (int y = topRect.top(); y < topRect.bottom(); y++)
+ {
+ if (flag & blitAlphaTest)
+ {
+ blit_8i_to_32_at((uint32_t *)dstptr, srcptr, pal, topRect.width());
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ blit_8i_to_32_ab((gRGB *)dstptr, srcptr, (const gRGB *)pal, topRect.width());
+ }
+ else
+ blit_8i_to_32((uint32_t *)dstptr, srcptr, pal, topRect.width());
+ srcptr += src.surface->stride;
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+
+ if (bottom && !bottomRect.empty())
+ {
+ const uint8_t *srcptr = (uint8_t *)src.surface->data;
+ uint32_t *dstptr = (uint32_t *)surface->data;
+
+ srcptr += (bottomRect.left() - pos.left()) + (bottomRect.top() - pos.top()) * src.surface->stride;
+ dstptr += bottomRect.left() + (bottomRect.top()) * surface->stride / 4;
+ for (int y = (bottomRect.top() - pos.top()); y < (bottomRect.top() - pos.top() + bottom); y++)
+ {
+ if (flag & blitAlphaTest)
+ {
+ blit_8i_to_32_at((uint32_t *)dstptr, srcptr, pal, bottomRect.width());
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ blit_8i_to_32_ab((gRGB *)dstptr, srcptr, (const gRGB *)pal, bottomRect.width());
+ }
+ else
+ blit_8i_to_32((uint32_t *)dstptr, srcptr, pal, bottomRect.width());
+ srcptr += src.surface->stride;
+ dstptr = (uint32_t *)((uint8_t *)dstptr + surface->stride);
+ }
+ }
+}
+
+void gPixmap::blitRounded8BitScaled(const gPixmap &src, const eRect &pos, const eRect &clip, int cornerRadius, int edges, int flag)
+{
+ int corners = 0;
+ uint32_t pal[256];
+ convert_palette(pal, src.surface->clut);
+ CornerData cornerData(cornerRadius, edges, pos.width(), pos.height(), 0, 0xFF000000);
+ eRect cornerRect;
+
+ if (cornerData.topLeftCornerRadius)
+ {
+ cornerRect = eRect(pos.left(), pos.top(), cornerData.topLeftCornerRadius, cornerData.topLeftCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 1;
+ drawAngle8ScaledTl(surface, src, pal, pos, cornerRect, cornerData, flag);
+ }
+ }
+ if (cornerData.topRightCornerRadius)
+ {
+ cornerRect = eRect(pos.right() - cornerData.topRightCornerRadius, pos.top(), cornerData.topRightCornerRadius, cornerData.topRightCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 2;
+ drawAngle8ScaledTr(surface, src, pal, pos, cornerRect, cornerData, flag);
+ }
+ }
+ if (cornerData.bottomLeftCornerRadius)
+ {
+ cornerRect = eRect(pos.left(), pos.bottom() - cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius, cornerData.bottomLeftCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 4;
+ drawAngle8ScaledBl(surface, src, pal, pos, cornerRect, cornerData, flag);
+ }
+ }
+
+ if (cornerData.bottomRightCornerRadius)
+ {
+ cornerRect = eRect(pos.right() - cornerData.bottomRightCornerRadius, pos.bottom() - cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius, cornerData.bottomRightCornerRadius);
+ cornerRect &= clip;
+ if (!cornerRect.empty())
+ {
+ corners += 8;
+ drawAngle8ScaledBr(surface, src, pal, pos, cornerRect, cornerData, flag);
+ }
+ }
+
+ if (cornerData.isCircle)
+ return;
+
+ const int bottom = MAX(cornerData.bottomRightCornerRadius, cornerData.bottomLeftCornerRadius);
+ const int top = MAX(cornerData.topRightCornerRadius, cornerData.topLeftCornerRadius);
+
+ int topw = pos.width();
+ int topl = pos.left();
+ int bottomw = pos.width();
+ int bottoml = pos.left();
+
+ if (corners & 1)
+ {
+ topw -= cornerData.topLeftCornerRadius;
+ topl += cornerData.topLeftCornerRadius;
+ }
+ if (corners & 2)
+ topw -= cornerData.topRightCornerRadius;
+
+ if (corners & 4)
+ {
+ bottomw -= cornerData.bottomLeftCornerRadius;
+ bottoml += cornerData.bottomLeftCornerRadius;
+ }
+ if (corners & 8)
+ bottomw -= cornerData.bottomRightCornerRadius;
+
+ eRect topRect = eRect(topl, pos.top(), topw, top);
+ topRect &= clip;
+
+ eRect bottomRect = eRect(bottoml, pos.bottom() - bottom, bottomw, bottom);
+ bottomRect &= clip;
+
+ eRect mRect = eRect(pos.left(), pos.top() + top, pos.width(), pos.height() - top - bottom);
+ mRect &= clip;
+
+ const int src_bypp = src.surface->bypp;
+ const int dst_bypp = surface->bypp;
+ const int src_stride = src.surface->stride;
+ const int dst_stride = surface->stride;
+ const float scaleX = (float)src.size().width() / (float)pos.width();
+ const float scaleY = (float)src.size().height() / (float)pos.height();
+ const int aLeft = pos.left();
+ const int aTop = pos.top();
+
+ if (!mRect.empty())
+ {
+ const int rLeft = mRect.left();
+ const int rRight = mRect.right();
+ const int rTop = mRect.top();
+ const int rBottom = mRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+ if (flag & blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ if (pal[*src] & 0x80000000)
+ *dst = pal[*src];
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ gRGB *dst = (gRGB *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dst->alpha_blend(pal[*src]);
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ *dst = pal[*src];
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ }
+ if (top && !topRect.empty())
+ {
+ const int rLeft = topRect.left();
+ const int rRight = topRect.right();
+ const int rTop = topRect.top();
+ const int rBottom = topRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ if (pal[*src] & 0x80000000)
+ *dst = pal[*src];
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ gRGB *dst = (gRGB *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dst->alpha_blend(pal[*src]);
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ *dst = pal[*src];
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ }
+ if (bottom && !bottomRect.empty())
+ {
+ const int rLeft = bottomRect.left();
+ const int rRight = bottomRect.right();
+ const int rTop = bottomRect.top();
+ const int rBottom = bottomRect.bottom();
+ uint8_t *dst_row = (uint8_t *)surface->data + rLeft * dst_bypp + rTop * dst_stride;
+
+ if (flag & blitAlphaTest)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ if (pal[*src] & 0x80000000)
+ *dst = pal[*src];
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else if (flag & blitAlphaBlend)
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ gRGB *dst = (gRGB *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ dst->alpha_blend(pal[*src]);
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ else
+ {
+ for (int y = rTop; y < rBottom; ++y)
+ {
+ int src_y = (int)((y - aTop) * scaleY);
+ const uint8_t *src_row = (const uint8_t *)src.surface->data + src_y * src_stride;
+ uint32_t *dst = (uint32_t *)dst_row;
+
+ for (int x = rLeft; x < rRight; ++x)
+ {
+ int src_x = (int)((x - aLeft) * scaleX);
+ const uint8_t *src = src_row + src_x * src_bypp;
+ *dst = pal[*src];
+ dst++;
+ }
+ dst_row += dst_stride;
+ }
+ }
+ }
+}
+
+void gPixmap::blit(const gPixmap &src, const eRect &_pos, const gRegion &clip, int cornerRadius, int edges, int flag)
{
bool accel = (surface->data_phys && src.surface->data_phys);
bool accumulate = accel && (gAccel::getInstance()->accumulate() >= 0);
int accelerationthreshold = GFX_SURFACE_BLIT_ACCELERATION_THRESHOLD;
-// eDebug("[gPixmap] blit: -> %d,%d+%d,%d -> %d,%d+%d,%d, flags=0x%x, accel=%d",
-// _pos.x(), _pos.y(), _pos.width(), _pos.height(),
-// clip.extends.x(), clip.extends.y(), clip.extends.width(), clip.extends.height(),
-// flag, accel);
eRect pos = _pos;
-// eDebug("[gPixmap] source size: %d %d", src.size().width(), src.size().height());
+ // eDebug("[gPixmap] source size: %d %d", src.size().width(), src.size().height());
int scale_x = FIX, scale_y = FIX;
@@ -569,15 +1744,33 @@ void gPixmap::blit(const gPixmap &src, const eRect &_pos, const gRegion &clip, i
eRect srcarea = area;
srcarea.moveBy(-pos.x(), -pos.y());
-// eDebug("[gPixmap] srcarea before scale: %d %d %d %d",
-// srcarea.x(), srcarea.y(), srcarea.width(), srcarea.height());
+ // eDebug("[gPixmap] srcarea before scale: %d %d %d %d",
+ // srcarea.x(), srcarea.y(), srcarea.width(), srcarea.height());
if (flag & blitScale)
srcarea = eRect(srcarea.x() * FIX / scale_x, srcarea.y() * FIX / scale_y, srcarea.width() * FIX / scale_x, srcarea.height() * FIX / scale_y);
-// eDebug("[gPixmap] srcarea after scale: %d %d %d %d",
-// srcarea.x(), srcarea.y(), srcarea.width(), srcarea.height());
+ // eDebug("[gPixmap] srcarea after scale: %d %d %d %d",
+ // srcarea.x(), srcarea.y(), srcarea.width(), srcarea.height());
+ if (cornerRadius && surface->bpp == 32)
+ {
+ if (src.surface->bpp == 32)
+ {
+ if (flag & blitScale)
+ blitRounded32BitScaled(src, pos, clip.rects[i], cornerRadius, edges, flag);
+ else
+ blitRounded32Bit(src, pos, clip.rects[i], cornerRadius, edges, flag);
+ }
+ else
+ {
+ if (flag & blitScale)
+ blitRounded8BitScaled(src, pos, clip.rects[i], cornerRadius, edges, flag);
+ else
+ blitRounded8Bit(src, pos, clip.rects[i], cornerRadius, edges, flag);
+ }
+ continue;
+ }
if (accel)
{
if (srcarea.surface() * src.surface->bypp < accelerationthreshold)
@@ -729,7 +1922,8 @@ void gPixmap::blit(const gPixmap &src, const eRect &_pos, const gRegion &clip, i
gRGB *dst = (gRGB*)dstptr;
for (int x = 0; x < width; ++x)
{
- dst->alpha_blend(src_row_ptr[(x * src_width) / width]);
+ const gRGB &src_pixel = src_row_ptr[(x * src_width) / width];
+ dst->alpha_blend(src_pixel);
++dst;
}
dstptr += surface->stride;
diff --git a/lib/gdi/gpixmap.h b/lib/gdi/gpixmap.h
index 8a1a07e9e7..112ce2e3e4 100644
--- a/lib/gdi/gpixmap.h
+++ b/lib/gdi/gpixmap.h
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
struct gRGB
{
@@ -164,6 +165,7 @@ struct gUnmanagedSurface
gPalette clut;
void *data;
int data_phys;
+ bool transparent = true;
gUnmanagedSurface();
gUnmanagedSurface(int width, int height, int bpp);
@@ -202,6 +204,14 @@ class gPixmap: public iObject
blitVAlignBottom = 128
};
+ enum
+ {
+ RADIUS_TOP_LEFT = 1,
+ RADIUS_TOP_RIGHT = 2,
+ RADIUS_BOTTOM_LEFT = 4,
+ RADIUS_BOTTOM_RIGHT = 8,
+ };
+
enum {
accelNever = -1,
accelAuto = 0,
@@ -228,13 +238,140 @@ class gPixmap: public iObject
void fill(const gRegion &clip, const gColor &color);
void fill(const gRegion &clip, const gRGB &color);
- void blit(const gPixmap &src, const eRect &pos, const gRegion &clip, int flags=0);
+ void blit(const gPixmap &src, const eRect &pos, const gRegion &clip, int cornerRadius, int edges, int flags=0);
+
+ void blitRounded32Bit(const gPixmap &src, const eRect &pos, const eRect &clip, int cornerRadius, int edges, int flag);
+ void blitRounded32BitScaled(const gPixmap &src, const eRect &pos, const eRect &clip, int cornerRadius, int edges, int flag);
+ void blitRounded8Bit(const gPixmap &src, const eRect &pos, const eRect &clip, int cornerRadius, int edges, int flag);
+ void blitRounded8BitScaled(const gPixmap &src, const eRect &pos, const eRect &clip, int cornerRadius, int edges, int flag);
void mergePalette(const gPixmap &target);
void line(const gRegion &clip, ePoint start, ePoint end, gColor color);
void line(const gRegion &clip, ePoint start, ePoint end, gRGB color);
void line(const gRegion &clip, ePoint start, ePoint end, unsigned int color);
+
+ void drawRectangle(const gRegion ®ion, const eRect &area, const gRGB &backgroundColor, const gRGB &borderColor, int borderWidth, const std::vector &gradientColors, uint8_t direction, int radius, uint8_t edges, bool alphablend, int gradientFullSize = 0);
};
SWIG_TEMPLATE_TYPEDEF(ePtr, gPixmapPtr);
+
+#ifndef SWIG
+struct CornerData
+{
+ int width;
+ int height;
+ int topLeftCornerRadius;
+ int topLeftCornerSRadius;
+ int topLeftCornerDRadius;
+ int topRightCornerRadius;
+ int topRightCornerSRadius;
+ int topRightCornerDRadius;
+ int bottomLeftCornerRadius;
+ int bottomLeftCornerSRadius;
+ int bottomLeftCornerDRadius;
+ int bottomRightCornerRadius;
+ int bottomRightCornerSRadius;
+ int bottomRightCornerDRadius;
+ int borderWidth;
+ int cornerRadius;
+ int w_topRightCornerRadius;
+ int h_bottomLeftCornerRadius;
+ int w_bottomRightCornerRadius;
+ int h_bottomRightCornerRadius;
+ uint32_t borderCol;
+
+ bool radiusSet = false;
+ bool isCircle = false;
+
+ std::unordered_map RadiusData;
+
+ CornerData(int radius, uint8_t edges, int h, int w, int bw, uint32_t borderColor)
+ {
+ cornerRadius = checkRadiusValue(radius, h, w);
+ radiusSet = cornerRadius > 0;
+ topLeftCornerRadius = (gPixmap::RADIUS_TOP_LEFT & edges) ? cornerRadius: 0;
+ topRightCornerRadius = (gPixmap::RADIUS_TOP_RIGHT & edges) ? cornerRadius: 0;
+ bottomLeftCornerRadius = (gPixmap::RADIUS_BOTTOM_LEFT & edges) ? cornerRadius: 0;
+ bottomRightCornerRadius = (gPixmap::RADIUS_BOTTOM_RIGHT & edges) ? cornerRadius: 0;
+ topLeftCornerSRadius = topLeftCornerRadius * topLeftCornerRadius;
+ topLeftCornerDRadius = (topLeftCornerRadius - 1) * (topLeftCornerRadius - 1);
+ topRightCornerSRadius = topRightCornerRadius * topRightCornerRadius;
+ topRightCornerDRadius = (topRightCornerRadius - 1) * (topRightCornerRadius - 1);
+ bottomLeftCornerSRadius = bottomLeftCornerRadius * bottomLeftCornerRadius;
+ bottomLeftCornerDRadius = (bottomLeftCornerRadius - 1) * (bottomLeftCornerRadius - 1);
+ bottomRightCornerSRadius = bottomRightCornerRadius * bottomRightCornerRadius;
+ bottomRightCornerDRadius = (bottomRightCornerRadius - 1) * (bottomRightCornerRadius - 1);
+ width = h;
+ height = w;
+ borderWidth = bw;
+ borderCol = borderColor;
+
+ w_topRightCornerRadius = w - topRightCornerRadius;
+ if(width > height)
+ w_topRightCornerRadius += (width - height);
+ else if (height > width)
+ w_topRightCornerRadius -= (height - width);
+
+ h_bottomLeftCornerRadius = h - bottomLeftCornerRadius;
+ if(width > height)
+ h_bottomLeftCornerRadius -= (width - height);
+ else if (height > width)
+ h_bottomLeftCornerRadius += (height - width);
+
+ w_bottomRightCornerRadius = w - bottomRightCornerRadius;
+ if(width > height)
+ w_bottomRightCornerRadius += (width - height);
+ else if (height > width)
+ w_bottomRightCornerRadius -= (height - width);
+
+ h_bottomRightCornerRadius = h - bottomRightCornerRadius;
+ if(width > height)
+ h_bottomRightCornerRadius -= (width - height);
+ else if (height > width)
+ h_bottomRightCornerRadius += (height - width);
+
+ isCircle = ((edges == 15) && (width == height) && (cornerRadius == width / 2));
+ caclCornerAlpha();
+ }
+
+ int checkRadiusValue(int r, const int w, const int h)
+ {
+ int minDimension = (w < h) ? w : h;
+ if (r > minDimension / 2) {
+ r = minDimension / 2;
+ }
+ return r;
+ }
+
+ void caclCornerAlpha()
+ {
+ int dx = 0, dy = 0, squared_dst = 0;
+ double alpha = 0.0, distance = 0.0;
+ int r = cornerRadius;
+ for (int y = 0; y < r; y++)
+ {
+ for (int x = 0; x < r; x++)
+ {
+ dx = r - x - 1;
+ dy = r - y - 1;
+ squared_dst = dx * dx + dy * dy;
+ if (squared_dst <= (r - 1) * (r - 1))
+ continue;
+ else if (squared_dst >= r * r)
+ continue;
+ else
+ {
+ if (RadiusData.find(squared_dst) == RadiusData.end())
+ {
+ distance = sqrt(squared_dst);
+ alpha = (r - distance);
+ RadiusData[squared_dst] = alpha;
+ }
+ }
+ }
+ }
+ }
+};
+#endif
+
#endif
diff --git a/lib/gdi/grc.cpp b/lib/gdi/grc.cpp
index 97ec65c75b..c51a43bcb9 100644
--- a/lib/gdi/grc.cpp
+++ b/lib/gdi/grc.cpp
@@ -1,25 +1,31 @@
#include
+#include
#include
#include
#include
#include
+#ifdef USE_LIBVUGLES2
+#include
+#endif
+
#ifndef SYNC_PAINT
void *gRC::thread_wrapper(void *ptr)
{
- return ((gRC*)ptr)->thread();
+ return ((gRC *)ptr)->thread();
}
#endif
-gRC *gRC::instance=0;
+gRC *gRC::instance = 0;
-gRC::gRC(): rp(0), wp(0)
+gRC::gRC() : rp(0), wp(0)
#ifdef SYNC_PAINT
,m_notify_pump(eApp, 0)
#else
,m_notify_pump(eApp, 1)
#endif
-,m_spinner_enabled(0), m_spinneronoff(1), m_prev_idle_count(0)
+ ,
+ m_spinner_enabled(0), m_spinneronoff(1), m_prev_idle_count(0) // NOSONAR
{
ASSERT(!instance);
instance=this;
@@ -32,65 +38,80 @@ gRC::gRC(): rp(0), wp(0)
pthread_cond_init(&cond, 0);
pthread_attr_t attr;
pthread_attr_init(&attr);
- if (pthread_attr_setstacksize(&attr, 2048*1024) != 0)
- eDebug("[gRC] pthread_attr_setstacksize failed");
+ if (pthread_attr_setstacksize(&attr, 2048 * 1024) != 0)
+ eDebug("[gRC] Error: pthread_attr_setstacksize failed!");
int res = pthread_create(&the_thread, &attr, thread_wrapper, this);
pthread_attr_destroy(&attr);
if (res)
- eFatal("[gRC] thread couldn't be created");
+ eFatal("[gRC] Error: Thread couldn't be created!");
else
- eDebug("[gRC] thread created successfully");
+ eDebug("[gRC] Thread created successfully.");
#endif
}
+#ifdef CONFIG_ION
+void gRC::lock()
+{
+#ifndef SYNC_PAINT
+ pthread_mutex_lock(&mutex);
+#endif
+}
+
+void gRC::unlock()
+{
+#ifndef SYNC_PAINT
+ pthread_mutex_unlock(&mutex);
+#endif
+}
+#endif
+
DEFINE_REF(gRC);
gRC::~gRC()
{
- instance=0;
-
+ instance = 0;
gOpcode o;
- o.opcode=gOpcode::shutdown;
+ o.opcode = gOpcode::shutdown;
submit(o);
#ifndef SYNC_PAINT
- eDebug("[gRC] waiting for gRC thread shutdown");
+ eDebug("[gRC] Waiting for gRC thread shutdown.");
pthread_join(the_thread, 0);
- eDebug("[gRC] thread has finished");
+ eDebug("[gRC] Thread has finished.");
#endif
}
void gRC::submit(const gOpcode &o)
{
- while(1)
+ while (1)
{
#ifndef SYNC_PAINT
pthread_mutex_lock(&mutex);
#endif
- int tmp=wp+1;
- if ( tmp == MAXSIZE )
- tmp=0;
- if ( tmp == rp )
+ int tmp = wp + 1;
+ if (tmp == MAXSIZE)
+ tmp = 0;
+ if (tmp == rp)
{
#ifndef SYNC_PAINT
- pthread_cond_signal(&cond); // wakeup gdi thread
+ pthread_cond_signal(&cond); // wakeup gdi thread
pthread_mutex_unlock(&mutex);
#else
thread();
#endif
- //eDebug("[gRC] render buffer full...");
- //fflush(stdout);
- usleep(1000); // wait 1 msec
+ // eDebug("[gRC] Render buffer full.");
+ // fflush(stdout);
+ usleep(1000); // wait 1 msec
continue;
}
- int free=rp-wp;
- if ( free <= 0 )
- free+=MAXSIZE;
- queue[wp++]=o;
- if ( wp == MAXSIZE )
+ int free = rp - wp;
+ if (free <= 0)
+ free += MAXSIZE;
+ queue[wp++] = o;
+ if (wp == MAXSIZE)
wp = 0;
- if (o.opcode==gOpcode::flush||o.opcode==gOpcode::shutdown||o.opcode==gOpcode::notify)
+ if (o.opcode == gOpcode::flush || o.opcode == gOpcode::shutdown || o.opcode == gOpcode::notify)
#ifndef SYNC_PAINT
- pthread_cond_signal(&cond); // wakeup gdi thread
+ pthread_cond_signal(&cond); // wakeup gdi thread
pthread_mutex_unlock(&mutex);
#else
thread(); // paint
@@ -102,6 +123,13 @@ void gRC::submit(const gOpcode &o)
void *gRC::thread()
{
int need_notify = 0;
+#ifdef USE_LIBVUGLES2
+ if (gles_open())
+ {
+ gles_state_open();
+ gles_viewport(720, 576, 720 * 4);
+ }
+#endif
#ifndef SYNC_PAINT
while (1)
{
@@ -112,26 +140,27 @@ void *gRC::thread()
#ifndef SYNC_PAINT
pthread_mutex_lock(&mutex);
#endif
- if ( rp != wp )
+ if (rp != wp)
{
- /* make sure the spinner is not displayed when something is painted */
+ /* make sure the spinner is not displayed when something is painted */
disableSpinner();
gOpcode o(queue[rp++]);
- if ( rp == MAXSIZE )
- rp=0;
+ if (rp == MAXSIZE)
+ rp = 0;
#ifndef SYNC_PAINT
pthread_mutex_unlock(&mutex);
#endif
- if (o.opcode==gOpcode::shutdown)
+ if (o.opcode == gOpcode::shutdown)
break;
- else if (o.opcode==gOpcode::notify)
+ else if (o.opcode == gOpcode::notify)
need_notify = 1;
- else if (o.opcode==gOpcode::setCompositing)
+ else if (o.opcode == gOpcode::setCompositing)
{
m_compositing = o.parm.setCompositing;
m_compositing->Release();
- } else if(o.dc)
+ }
+ else if (o.dc)
{
o.dc->exec(&o);
// o.dc is a gDC* filled with grabref... so we must release it here
@@ -146,21 +175,21 @@ void *gRC::thread()
m_notify_pump.send(1);
}
#ifndef SYNC_PAINT
- while(rp == wp)
+ 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 = {};
+ /* 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;
+ timeout.tv_nsec += 100 * 1000 * 1000;
/* yes, this is required. */
- if (timeout.tv_nsec > 1000*1000*1000)
+ if (timeout.tv_nsec > 1000 * 1000 * 1000)
{
- timeout.tv_nsec -= 1000*1000*1000;
+ timeout.tv_nsec -= 1000 * 1000 * 1000;
timeout.tv_sec++;
}
}
@@ -184,9 +213,14 @@ void *gRC::thread()
if (!idle)
{
if (!m_spinner_enabled)
- eDebug("[gRC] main thread is non-idle! display spinner!");
+ {
+ eDebug("[gRC] Warning: Main thread is busy, displaying spinner!");
+ std::ofstream dummy("/tmp/doPythonStackTrace");
+ dummy.close();
+ }
enableSpinner();
- } else
+ }
+ else
disableSpinner();
}
pthread_mutex_unlock(&mutex);
@@ -213,7 +247,7 @@ void gRC::enableSpinner()
{
if (!m_spinner_dc)
{
- eDebug("[gRC] enabelSpinner: no spinner DC!");
+ eDebug("[gRC] enableSpinner Error: No spinner DC!");
return;
}
@@ -235,7 +269,7 @@ void gRC::disableSpinner()
if (!m_spinner_dc)
{
- eDebug("[gRC] disableSpinner: no spinner DC!");
+ eDebug("[gRC] disableSpinner Error: No spinner DC!");
return;
}
@@ -250,11 +284,11 @@ void gRC::disableSpinner()
static int gPainter_instances;
-gPainter::gPainter(gDC *dc, eRect rect): m_dc(dc), m_rc(gRC::getInstance())
+gPainter::gPainter(gDC *dc, eRect rect) : m_dc(dc), m_rc(gRC::getInstance())
{
-// ASSERT(!gPainter_instances);
+ // ASSERT(!gPainter_instances);
gPainter_instances++;
-// begin(rect);
+ // begin(rect);
}
gPainter::~gPainter()
@@ -265,7 +299,7 @@ gPainter::~gPainter()
void gPainter::setBackgroundColor(const gColor &color)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::setBackgroundColor;
@@ -278,7 +312,7 @@ void gPainter::setBackgroundColor(const gColor &color)
void gPainter::setForegroundColor(const gColor &color)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::setForegroundColor;
@@ -291,7 +325,7 @@ void gPainter::setForegroundColor(const gColor &color)
void gPainter::setBackgroundColor(const gRGB &color)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::setBackgroundColorRGB;
@@ -304,7 +338,7 @@ void gPainter::setBackgroundColor(const gRGB &color)
void gPainter::setForegroundColor(const gRGB &color)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::setForegroundColorRGB;
@@ -315,9 +349,50 @@ void gPainter::setForegroundColor(const gRGB &color)
m_rc->submit(o);
}
+void gPainter::setGradient(const std::vector &colors, uint8_t orientation, bool alphablend, int fullSize)
+{
+ if (m_dc->islocked())
+ return;
+ gOpcode o;
+ o.opcode = gOpcode::setGradient;
+ o.dc = m_dc.grabRef();
+ o.parm.gradient = new gOpcode::para::pgradient;
+ o.parm.gradient->colors = colors;
+ o.parm.gradient->orientation = orientation;
+ o.parm.gradient->alphablend = alphablend;
+ o.parm.gradient->fullSize = fullSize;
+ m_rc->submit(o);
+}
+
+void gPainter::setRadius(int radius, uint8_t edges)
+{
+ if (m_dc->islocked())
+ return;
+ gOpcode o;
+ o.opcode = gOpcode::setRadius;
+ o.dc = m_dc.grabRef();
+ o.parm.radius = new gOpcode::para::pradius;
+ o.parm.radius->radius = radius;
+ o.parm.radius->edges = edges;
+ m_rc->submit(o);
+}
+
+void gPainter::setBorder(const gRGB &borderColor, int width)
+{
+ if (m_dc->islocked())
+ return;
+ gOpcode o;
+ o.opcode = gOpcode::setBorder;
+ o.dc = m_dc.grabRef();
+ o.parm.border = new gOpcode::para::pborder;
+ o.parm.border->color = borderColor;
+ o.parm.border->width = width;
+ m_rc->submit(o);
+}
+
void gPainter::setFont(gFont *font)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::setFont;
@@ -329,13 +404,14 @@ void gPainter::setFont(gFont *font)
m_rc->submit(o);
}
-void gPainter::renderText(const eRect &pos, const std::string &string, int flags, gRGB bordercolor, int border)
+void gPainter::renderText(const eRect &pos, const std::string &string, int flags, gRGB bordercolor, int border, int markedpos, int *offset)
{
- if (string.empty()) return;
- if ( m_dc->islocked() )
+ if (string.empty())
+ return;
+ if (m_dc->islocked())
return;
gOpcode o;
- o.opcode=gOpcode::renderText;
+ o.opcode = gOpcode::renderText;
o.dc = m_dc.grabRef();
o.parm.renderText = new gOpcode::para::prenderText;
o.parm.renderText->area = pos;
@@ -348,26 +424,26 @@ void gPainter::renderText(const eRect &pos, const std::string &string, int flags
void gPainter::renderPara(eTextPara *para, ePoint offset)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
ASSERT(para);
gOpcode o;
- o.opcode=gOpcode::renderPara;
+ o.opcode = gOpcode::renderPara;
o.dc = m_dc.grabRef();
o.parm.renderPara = new gOpcode::para::prenderPara;
o.parm.renderPara->offset = offset;
- para->AddRef();
+ para->AddRef();
o.parm.renderPara->textpara = para;
m_rc->submit(o);
}
void gPainter::fill(const eRect &area)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
- o.opcode=gOpcode::fill;
+ o.opcode = gOpcode::fill;
o.dc = m_dc.grabRef();
o.parm.fill = new gOpcode::para::pfillRect;
@@ -377,10 +453,10 @@ void gPainter::fill(const eRect &area)
void gPainter::fill(const gRegion ®ion)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
- o.opcode=gOpcode::fillRegion;
+ o.opcode = gOpcode::fillRegion;
o.dc = m_dc.grabRef();
o.parm.fillRegion = new gOpcode::para::pfillRegion;
@@ -390,10 +466,10 @@ void gPainter::fill(const gRegion ®ion)
void gPainter::clear()
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
- o.opcode=gOpcode::clear;
+ o.opcode = gOpcode::clear;
o.dc = m_dc.grabRef();
o.parm.fill = new gOpcode::para::pfillRect;
o.parm.fill->area = eRect();
@@ -412,16 +488,16 @@ void gPainter::blit(gPixmap *pixmap, ePoint pos, const eRect &clip, int flags)
void gPainter::blit(gPixmap *pixmap, const eRect &pos, const eRect &clip, int flags)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
ASSERT(pixmap);
- o.opcode=gOpcode::blit;
+ o.opcode = gOpcode::blit;
o.dc = m_dc.grabRef();
pixmap->AddRef();
- o.parm.blit = new gOpcode::para::pblit;
+ o.parm.blit = new gOpcode::para::pblit;
o.parm.blit->pixmap = pixmap;
o.parm.blit->clip = clip;
o.parm.blit->flags = flags;
@@ -429,24 +505,35 @@ void gPainter::blit(gPixmap *pixmap, const eRect &pos, const eRect &clip, int fl
m_rc->submit(o);
}
+void gPainter::drawRectangle(const eRect &area) {
+ if ( m_dc->islocked() )
+ return;
+ gOpcode o;
+ o.opcode=gOpcode::rectangle;
+ o.dc = m_dc.grabRef();
+ o.parm.rectangle = new gOpcode::para::prectangle;
+ o.parm.rectangle->area = area;
+ m_rc->submit(o);
+}
+
void gPainter::setPalette(gRGB *colors, int start, int len)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
if (len <= 0)
return;
ASSERT(colors);
gOpcode o;
- o.opcode=gOpcode::setPalette;
+ o.opcode = gOpcode::setPalette;
o.dc = m_dc.grabRef();
- gPalette *p=new gPalette;
+ gPalette *p = new gPalette;
o.parm.setPalette = new gOpcode::para::psetPalette;
- p->data=new gRGB[static_cast(len)];
+ p->data = new gRGB[static_cast(len)];
- memcpy(static_cast(p->data), colors, len*sizeof(gRGB));
- p->start=start;
- p->colors=len;
+ memcpy(static_cast(p->data), colors, len * sizeof(gRGB));
+ p->start = start;
+ p->colors = len;
o.parm.setPalette->palette = p;
m_rc->submit(o);
}
@@ -459,7 +546,7 @@ void gPainter::setPalette(gPixmap *source)
void gPainter::mergePalette(gPixmap *target)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
ASSERT(target);
gOpcode o;
@@ -473,10 +560,10 @@ void gPainter::mergePalette(gPixmap *target)
void gPainter::line(ePoint start, ePoint end)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
- o.opcode=gOpcode::line;
+ o.opcode = gOpcode::line;
o.dc = m_dc.grabRef();
o.parm.line = new gOpcode::para::pline;
o.parm.line->start = start;
@@ -486,10 +573,10 @@ void gPainter::line(ePoint start, ePoint end)
void gPainter::setOffset(ePoint val)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
- o.opcode=gOpcode::setOffset;
+ o.opcode = gOpcode::setOffset;
o.dc = m_dc.grabRef();
o.parm.setOffset = new gOpcode::para::psetOffset;
o.parm.setOffset->rel = 0;
@@ -499,10 +586,10 @@ void gPainter::setOffset(ePoint val)
void gPainter::moveOffset(ePoint rel)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
- o.opcode=gOpcode::setOffset;
+ o.opcode = gOpcode::setOffset;
o.dc = m_dc.grabRef();
o.parm.setOffset = new gOpcode::para::psetOffset;
o.parm.setOffset->rel = 1;
@@ -512,10 +599,10 @@ void gPainter::moveOffset(ePoint rel)
void gPainter::resetOffset()
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
- o.opcode=gOpcode::setOffset;
+ o.opcode = gOpcode::setOffset;
o.dc = m_dc.grabRef();
o.parm.setOffset = new gOpcode::para::psetOffset;
o.parm.setOffset->rel = 0;
@@ -525,7 +612,7 @@ void gPainter::resetOffset()
void gPainter::resetClip(const gRegion ®ion)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::setClip;
@@ -537,7 +624,7 @@ void gPainter::resetClip(const gRegion ®ion)
void gPainter::clip(const gRegion ®ion)
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::addClip;
@@ -549,7 +636,7 @@ void gPainter::clip(const gRegion ®ion)
void gPainter::clippop()
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::popClip;
@@ -559,7 +646,7 @@ void gPainter::clippop()
void gPainter::waitVSync()
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::waitVSync;
@@ -569,7 +656,7 @@ void gPainter::waitVSync()
void gPainter::flip()
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::flip;
@@ -579,7 +666,7 @@ void gPainter::flip()
void gPainter::notify()
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::notify;
@@ -599,7 +686,7 @@ void gPainter::setCompositing(gCompositingData *comp)
void gPainter::flush()
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
return;
gOpcode o;
o.opcode = gOpcode::flush;
@@ -609,16 +696,85 @@ void gPainter::flush()
void gPainter::end()
{
- if ( m_dc->islocked() )
+ if (m_dc->islocked())
+ return;
+}
+
+void gPainter::sendShow(ePoint point, eSize size)
+{
+ if (m_dc->islocked())
+ return;
+ gOpcode o;
+ o.opcode = gOpcode::sendShow;
+ o.dc = m_dc.grabRef();
+ o.parm.setShowHideInfo = new gOpcode::para::psetShowHideInfo;
+ o.parm.setShowHideInfo->point = point;
+ o.parm.setShowHideInfo->size = size;
+ m_rc->submit(o);
+}
+
+void gPainter::sendHide(ePoint point, eSize size)
+{
+ if (m_dc->islocked())
+ return;
+ gOpcode o;
+ o.opcode = gOpcode::sendHide;
+ o.dc = m_dc.grabRef();
+ o.parm.setShowHideInfo = new gOpcode::para::psetShowHideInfo;
+ o.parm.setShowHideInfo->point = point;
+ o.parm.setShowHideInfo->size = size;
+ m_rc->submit(o);
+}
+#ifdef USE_LIBVUGLES2
+void gPainter::sendShowItem(long dir, ePoint point, eSize size)
+{
+ if (m_dc->islocked())
+ return;
+ gOpcode o;
+ o.opcode = gOpcode::sendShowItem;
+ o.dc = m_dc.grabRef();
+ o.parm.setShowItemInfo = new gOpcode::para::psetShowItemInfo;
+ o.parm.setShowItemInfo->dir = dir;
+ o.parm.setShowItemInfo->point = point;
+ o.parm.setShowItemInfo->size = size;
+ m_rc->submit(o);
+}
+void gPainter::setFlush(bool val)
+{
+ if (m_dc->islocked())
return;
+ gOpcode o;
+ o.opcode = gOpcode::setFlush;
+ o.dc = m_dc.grabRef();
+ o.parm.setFlush = new gOpcode::para::psetFlush;
+ o.parm.setFlush->enable = val;
+ m_rc->submit(o);
+}
+void gPainter::setView(eSize size)
+{
+ if (m_dc->islocked())
+ return;
+ gOpcode o;
+ o.opcode = gOpcode::setView;
+ o.dc = m_dc.grabRef();
+ o.parm.setViewInfo = new gOpcode::para::psetViewInfo;
+ o.parm.setViewInfo->size = size;
+ m_rc->submit(o);
}
+#endif
gDC::gDC()
{
m_spinner_pic = 0;
+ m_border_width = 0;
+ m_radius = 0;
+ m_radius_edges = 0;
+ m_gradient_orientation = 0;
+ m_gradient_alphablend = false;
+ m_gradient_fullSize = 0;
}
-gDC::gDC(gPixmap *pixmap): m_pixmap(pixmap)
+gDC::gDC(gPixmap *pixmap) : m_pixmap(pixmap)
{
m_spinner_pic = 0;
}
@@ -659,13 +815,59 @@ void gDC::exec(const gOpcode *o)
o->parm.setFont->font->Release();
delete o->parm.setFont;
break;
+ case gOpcode::setGradient:
+ m_gradient_colors = o->parm.gradient->colors;
+ m_gradient_orientation = o->parm.gradient->orientation;
+ m_gradient_alphablend = o->parm.gradient->alphablend;
+ m_gradient_fullSize = o->parm.gradient->fullSize;
+ delete o->parm.gradient;
+ break;
+ case gOpcode::setRadius:
+ m_radius = o->parm.radius->radius;
+ m_radius_edges = o->parm.radius->edges;
+ delete o->parm.radius;
+ break;
+ case gOpcode::setBorder:
+ m_border_color = o->parm.border->color;
+ m_border_width = o->parm.border->width;
+ delete o->parm.border;
+ break;
case gOpcode::renderText:
{
ePtr para = new eTextPara(o->parm.renderText->area);
int flags = o->parm.renderText->flags;
ASSERT(m_current_font);
para->setFont(m_current_font);
+
+ if (flags & gPainter::RT_ELLIPSIS)
+ {
+ if (flags & gPainter::RT_WRAP) // Remove wrap
+ flags -= gPainter::RT_WRAP;
+ std::string text = o->parm.renderText->text;
+ text += u8"…";
+
+ eTextPara testpara(o->parm.renderText->area);
+ testpara.setFont(m_current_font);
+ testpara.renderString(text.c_str(), 0);
+ int bw = testpara.getBoundBox().width();
+ int w = o->parm.renderText->area.width();
+ if (bw > w) // Available space not fit
+ {
+ float pers = (float)w / (float)bw;
+ text = o->parm.renderText->text;
+ int ns = text.size() * pers;
+ if ((int)text.size() > ns)
+ {
+ text.resize(ns);
+ text += u8"…";
+ }
+ if (o->parm.renderText->text)
+ free(o->parm.renderText->text);
+ o->parm.renderText->text = strdup(text.c_str());
+ }
+ }
para->renderString(o->parm.renderText->text, (flags & gPainter::RT_WRAP) ? RS_WRAP : 0, o->parm.renderText->border);
+
if (o->parm.renderText->text)
free(o->parm.renderText->text);
if (flags & gPainter::RT_HALIGN_LEFT)
@@ -750,7 +952,7 @@ void gDC::exec(const gOpcode *o)
case gOpcode::blit:
{
gRegion clip;
- // this code should be checked again but i'm too tired now
+ // this code should be checked again but i'm too tired now
o->parm.blit->position.moveBy(m_current_offset);
@@ -758,21 +960,39 @@ void gDC::exec(const gOpcode *o)
{
o->parm.blit->clip.moveBy(m_current_offset);
clip.intersect(gRegion(o->parm.blit->clip), m_current_clip);
- } else
+ }
+ else
clip = m_current_clip;
-
- m_pixmap->blit(*o->parm.blit->pixmap, o->parm.blit->position, clip, o->parm.blit->flags);
+ if (!o->parm.blit->pixmap->surface->transparent)
+ o->parm.blit->flags &=~(gPixmap::blitAlphaTest|gPixmap::blitAlphaBlend);
+ m_pixmap->blit(*o->parm.blit->pixmap, o->parm.blit->position, clip, m_radius, m_radius_edges, o->parm.blit->flags);
+ m_radius = 0;
+ m_radius_edges = 0;
o->parm.blit->pixmap->Release();
delete o->parm.blit;
break;
}
+ case gOpcode::rectangle:
+ {
+ o->parm.rectangle->area.moveBy(m_current_offset);
+ gRegion clip = m_current_clip & o->parm.rectangle->area;
+ m_pixmap->drawRectangle(clip, o->parm.rectangle->area, m_background_color_rgb, m_border_color, m_border_width, m_gradient_colors, m_gradient_orientation, m_radius, m_radius_edges, m_gradient_alphablend, m_gradient_fullSize);
+ m_border_width = 0;
+ m_radius = 0;
+ m_radius_edges = 0;
+ m_gradient_orientation = 0;
+ m_gradient_fullSize = 0;
+ m_gradient_alphablend = false;
+ delete o->parm.rectangle;
+ 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 > (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(static_cast(m_pixmap->surface->clut.data+o->parm.setPalette->palette->start), o->parm.setPalette->palette->data, o->parm.setPalette->palette->colors*sizeof(gRGB));
+ memcpy(static_cast(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;
@@ -815,7 +1035,7 @@ void gDC::exec(const gOpcode *o)
if (o->parm.setOffset->rel)
m_current_offset += o->parm.setOffset->value;
else
- m_current_offset = o->parm.setOffset->value;
+ m_current_offset = o->parm.setOffset->value;
delete o->parm.setOffset;
break;
case gOpcode::waitVSync:
@@ -824,6 +1044,18 @@ void gDC::exec(const gOpcode *o)
break;
case gOpcode::flush:
break;
+ case gOpcode::sendShow:
+ break;
+ case gOpcode::sendHide:
+ break;
+#ifdef USE_LIBVUGLES2
+ case gOpcode::sendShowItem:
+ break;
+ case gOpcode::setFlush:
+ break;
+ case gOpcode::setView:
+ break;
+#endif
case gOpcode::enableSpinner:
enableSpinner();
break;
@@ -834,7 +1066,7 @@ void gDC::exec(const gOpcode *o)
incrementSpinner();
break;
default:
- eFatal("[gDC] illegal opcode %d. expect memory leak!", o->opcode);
+ eFatal("[gRC] gDC Error: Illegal opcode %d, expect memory leak!", o->opcode);
}
}
@@ -842,9 +1074,9 @@ gRGB gDC::getRGB(gColor col)
{
if ((!m_pixmap) || (!m_pixmap->surface->clut.data))
return gRGB(col, col, col);
- if (col<0)
+ if (col < 0)
{
- eFatal("[gDC] getRGB transp");
+ eFatal("[gRC] gDC Error: getRGB transp!");
return gRGB(0, 0, 0, 0xFF);
}
return m_pixmap->surface->clut.data[col];
@@ -854,8 +1086,8 @@ void gDC::enableSpinner()
{
ASSERT(m_spinner_saved);
- /* save the background to restore it later. We need to negative position because we want to blit from the middle of the screen. */
- m_spinner_saved->blit(*m_pixmap, eRect(-m_spinner_pos.topLeft(), eSize()), gRegion(eRect(ePoint(0, 0), m_spinner_saved->size())), 0);
+ /* save the background to restore it later. We need to negative position because we want to blit from the middle of the screen. */
+ m_spinner_saved->blit(*m_pixmap, eRect(-m_spinner_pos.topLeft(), eSize()), gRegion(eRect(ePoint(0, 0), m_spinner_saved->size())), 0, 0 ,0);
incrementSpinner();
}
@@ -864,8 +1096,8 @@ void gDC::disableSpinner()
{
ASSERT(m_spinner_saved);
- /* restore background */
- m_pixmap->blit(*m_spinner_saved, eRect(m_spinner_pos.topLeft(), eSize()), gRegion(m_spinner_pos), 0);
+ /* restore background */
+ m_pixmap->blit(*m_spinner_saved, eRect(m_spinner_pos.topLeft(), eSize()), gRegion(m_spinner_pos), 0, 0, 0);
}
void gDC::incrementSpinner()
@@ -889,12 +1121,12 @@ void gDC::incrementSpinner()
}
#endif
- m_spinner_temp->blit(*m_spinner_saved, eRect(0, 0, 0, 0), eRect(ePoint(0, 0), m_spinner_pos.size()));
+ m_spinner_temp->blit(*m_spinner_saved, eRect(0, 0, 0, 0), eRect(ePoint(0, 0), m_spinner_pos.size()), 0, 0, 0);
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::blitAlphaBlend);
+ m_spinner_temp->blit(*m_spinner_pic[m_spinner_i], eRect(0, 0, 0, 0), eRect(ePoint(0, 0), m_spinner_pos.size()), 0, 0, gPixmap::blitAlphaBlend);
- m_pixmap->blit(*m_spinner_temp, eRect(m_spinner_pos.topLeft(), eSize()), gRegion(m_spinner_pos), 0);
+ m_pixmap->blit(*m_spinner_temp, eRect(m_spinner_pos.topLeft(), eSize()), gRegion(m_spinner_pos), 0, 0, 0);
m_spinner_i++;
m_spinner_i %= m_spinner_num;
}
diff --git a/lib/gdi/grc.h b/lib/gdi/grc.h
index 071e04599d..2c218c5616 100644
--- a/lib/gdi/grc.h
+++ b/lib/gdi/grc.h
@@ -8,12 +8,13 @@
*/
// for debugging use:
-//#define SYNC_PAINT
+// #define SYNC_PAINT
#undef SYNC_PAINT
#include
#include
#include
+#include
#include
#include
@@ -35,8 +36,12 @@ struct gOpcode
renderPara,
setFont,
- fill, fillRegion, clear,
+ fill,
+ fillRegion,
+ clear,
blit,
+ gradient,
+ rectangle,
setPalette,
mergePalette,
@@ -49,9 +54,15 @@ struct gOpcode
setBackgroundColorRGB,
setForegroundColorRGB,
+ setGradient,
+ setRadius,
+ setBorder,
+
setOffset,
- setClip, addClip, popClip,
+ setClip,
+ addClip,
+ popClip,
flush,
@@ -59,11 +70,20 @@ struct gOpcode
flip,
notify,
- enableSpinner, disableSpinner, incrementSpinner,
+ enableSpinner,
+ disableSpinner,
+ incrementSpinner,
shutdown,
setCompositing,
+ sendShow,
+ sendHide,
+#ifdef USE_LIBVUGLES2
+ sendShowItem,
+ setFlush,
+ setView,
+#endif
} opcode;
gDC *dc;
@@ -86,6 +106,9 @@ struct gOpcode
int flags;
int border;
gRGB bordercolor;
+ int markedpos;
+ int scrollpos;
+ int *offset;
} *renderText;
struct prenderPara
@@ -112,6 +135,31 @@ struct gOpcode
eRect clip;
} *blit;
+ struct pgradient
+ {
+ std::vector colors;
+ uint8_t orientation;
+ bool alphablend;
+ int fullSize;
+ } *gradient;
+
+ struct pradius
+ {
+ int radius;
+ uint8_t edges;
+ } *radius;
+
+ struct pborder
+ {
+ gRGB color;
+ int width;
+ } *border;
+
+ struct prectangle
+ {
+ eRect area;
+ } *rectangle;
+
struct pmergePalette
{
gPixmap *target;
@@ -144,13 +192,37 @@ struct gOpcode
} *setOffset;
gCompositingData *setCompositing;
+
+ struct psetShowHideInfo
+ {
+ ePoint point;
+ eSize size;
+ } *setShowHideInfo;
+#ifdef USE_LIBVUGLES2
+ struct psetShowItemInfo
+ {
+ long dir;
+ ePoint point;
+ eSize size;
+ } *setShowItemInfo;
+
+ struct psetFlush
+ {
+ bool enable;
+ } *setFlush;
+
+ struct psetViewInfo
+ {
+ eSize size;
+ } *setViewInfo;
+#endif
} parm;
};
#define MAXSIZE 2048
- /* gRC is the singleton which controls the fifo and dispatches commands */
-class gRC: public iObject, public sigc::trackable
+/* gRC is the singleton which controls the fifo and dispatches commands */
+class gRC : public iObject, public sigc::trackable
{
DECLARE_REF(gRC);
friend class gPainter;
@@ -181,6 +253,7 @@ class gRC: public iObject, public sigc::trackable
ePtr m_compositing;
int m_prev_idle_count;
+
public:
gRC();
virtual ~gRC();
@@ -195,7 +268,7 @@ class gRC: public iObject, public sigc::trackable
static gRC *getInstance();
};
- /* gPainter is the user frontend, which in turn sends commands through gRC */
+/* gPainter is the user frontend, which in turn sends commands through gRC */
class gPainter
{
ePtr m_dc;
@@ -205,8 +278,9 @@ class gPainter
gOpcode *beginptr;
void begin(const eRect &rect);
void end();
+
public:
- gPainter(gDC *dc, eRect rect=eRect());
+ gPainter(gDC *dc, eRect rect = eRect());
virtual ~gPainter();
void setBackgroundColor(const gColor &color);
@@ -215,26 +289,32 @@ class gPainter
void setBackgroundColor(const gRGB &color);
void setForegroundColor(const gRGB &color);
+ void setBorder(const gRGB &borderColor, int width);
+ void setGradient(const std::vector &colors, uint8_t orientation, bool alphablend, int fullSize = 0);
+ void setRadius(int radius, uint8_t edges);
+
void setFont(gFont *font);
- /* flags only THESE: */
+ /* flags only THESE: */
enum
{
- // todo, make mask. you cannot align both right AND center AND block ;)
- RT_HALIGN_BIDI = 0, /* default */
+ // todo, make mask. you cannot align both right AND center AND block ;)
+ RT_HALIGN_BIDI = 0, /* default */
RT_HALIGN_LEFT = 1,
RT_HALIGN_RIGHT = 2,
RT_HALIGN_CENTER = 4,
RT_HALIGN_BLOCK = 8,
- RT_VALIGN_TOP = 0, /* default */
+ RT_VALIGN_TOP = 0, /* default */
RT_VALIGN_CENTER = 16,
RT_VALIGN_BOTTOM = 32,
- RT_WRAP = 64
+ RT_WRAP = 64,
+ RT_ELLIPSIS = 128,
+ RT_BLEND = 256
};
- void renderText(const eRect &position, const std::string &string, int flags=0, gRGB bordercolor=gRGB(), int border=0);
+ void renderText(const eRect &position, const std::string &string, int flags = 0, gRGB bordercolor = gRGB(), int border = 0, int markedpos = -1, int *offset = 0);
- void renderPara(eTextPara *para, ePoint offset=ePoint(0, 0));
+ void renderPara(eTextPara *para, ePoint offset = ePoint(0, 0));
void fill(const eRect &area);
void fill(const gRegion &area);
@@ -254,11 +334,20 @@ class gPainter
BT_VALIGN_BOTTOM = 128
};
+ enum
+ {
+ GRADIENT_OFF = 0,
+ GRADIENT_VERTICAL = 1,
+ GRADIENT_HORIZONTAL = 2
+ };
+
void blitScale(gPixmap *pixmap, const eRect &pos, const eRect &clip=eRect(), int flags=0, int aflags = BT_SCALE);
void blit(gPixmap *pixmap, ePoint pos, const eRect &clip=eRect(), int flags=0);
void blit(gPixmap *pixmap, const eRect &pos, const eRect &clip=eRect(), int flags=0);
- void setPalette(gRGB *colors, int start=0, int len=256);
+ void drawRectangle(const eRect &area);
+
+ void setPalette(gRGB *colors, int start = 0, int len = 256);
void setPalette(gPixmap *source);
void mergePalette(gPixmap *target);
@@ -278,11 +367,19 @@ class gPainter
void setCompositing(gCompositingData *comp);
void flush();
+ void sendShow(ePoint point, eSize size);
+ void sendHide(ePoint point, eSize size);
+#ifdef USE_LIBVUGLES2
+ void sendShowItem(long dir, ePoint point, eSize size);
+ void setFlush(bool val);
+ void setView(eSize size);
+#endif
};
-class gDC: public iObject
+class gDC : public iObject
{
DECLARE_REF(gDC);
+
protected:
ePtr m_pixmap;
@@ -291,6 +388,17 @@ class gDC: public iObject
ePtr m_current_font;
ePoint m_current_offset;
+ std::vector m_gradient_colors;
+ uint8_t m_gradient_orientation;
+ bool m_gradient_alphablend;
+ int m_gradient_fullSize;
+
+ int m_radius;
+ uint8_t m_radius_edges;
+
+ gRGB m_border_color;
+ int m_border_width;
+
std::stack m_clip_stack;
gRegion m_current_clip;
@@ -298,13 +406,18 @@ class gDC: public iObject
ePtr *m_spinner_pic;
eRect m_spinner_pos;
int m_spinner_num, m_spinner_i;
+
public:
virtual void exec(const gOpcode *opcode);
gDC(gPixmap *pixmap);
gDC();
virtual ~gDC();
gRegion &getClip() { return m_current_clip; }
- int getPixmap(ePtr &pm) { pm = m_pixmap; return 0; }
+ int getPixmap(ePtr &pm)
+ {
+ pm = m_pixmap;
+ return 0;
+ }
gRGB getRGB(gColor col);
virtual eSize size() { return m_pixmap->size(); }
virtual int islocked() const { return 0; }
diff --git a/lib/gui/elistbox.cpp b/lib/gui/elistbox.cpp
index f4bfa666b7..a8096fe63b 100644
--- a/lib/gui/elistbox.cpp
+++ b/lib/gui/elistbox.cpp
@@ -3,6 +3,9 @@
#include
#include
+int eListbox::defaultItemRadius[2] = {0,0};
+int eListbox::defaultItemRadiusEdges[2] = {0,0};
+
eListbox::eListbox(eWidget *parent) :
eWidget(parent), m_scrollbar_mode(showNever), m_prev_scrollbar_page(-1),
m_content_changed(false), m_enabled_wrap_around(false), m_scrollbar_width(10), m_scrollbar_height(10),
@@ -12,6 +15,14 @@ eListbox::eListbox(eWidget *parent) :
memset(static_cast(&m_style), 0, sizeof(m_style));
m_style.m_text_offset = ePoint(1,1);
+ for (int x = 0; x < 2; x++)
+ {
+ if (eListbox::defaultItemRadius[x] && eListbox::defaultItemRadiusEdges[x])
+ setItemCornerRadiusInternal(eListbox::defaultItemRadius[x], eListbox::defaultItemRadiusEdges[x], x);
+ else
+ setItemCornerRadiusInternal(0, 0, x);
+ }
+
allowNativeKeys(true);
}
@@ -513,6 +524,25 @@ int eListbox::event(int event, void *data, void *data2)
gRegion entryrect = m_orientation == orVertical ? eRect(0, 0, size().width(), m_itemheight) : eRect(0, 0, m_itemwidth, size().height());
const gRegion &paint_region = *(gRegion*)data;
+ if (!isTransparent())
+ {
+ int cornerRadius = getCornerRadius();
+ int cornerRadiusEdges = getCornerRadiusEdges();
+ painter.clip(paint_region);
+ style->setStyle(painter, eWindowStyle::styleListboxNormal);
+ if (m_style.m_background_color_set)
+ painter.setBackgroundColor(m_style.m_background_color);
+
+ if (cornerRadius && cornerRadiusEdges)
+ {
+ painter.setRadius(cornerRadius, cornerRadiusEdges);
+ painter.drawRectangle(eRect(ePoint(0, 0), size()));
+ }
+ else
+ painter.clear();
+ painter.clippop();
+ }
+
int xoffset = 0;
int yoffset = 0;
if (m_scrollbar && m_scrollbar_mode == showLeft)
@@ -950,3 +980,22 @@ struct eListboxStyle *eListbox::getLocalStyle(void)
m_style.m_transparent_background = isTransparent();
return &m_style;
}
+
+void eListbox::setItemCornerRadiusInternal(int radius, int edges, int index)
+{
+ m_style.m_itemCornerRadius[index] = radius;
+ m_style.m_itemCornerRadiusEdges[index] = edges;
+}
+
+void eListbox::setItemCornerRadius(int radius, int edges)
+{
+ for (int x = 0; x < 2; x++)
+ {
+ setItemCornerRadiusInternal(radius, edges, x);
+ }
+}
+
+void eListbox::setItemCornerRadiusSelected(int radius, int edges)
+{
+ setItemCornerRadiusInternal(radius, edges, 1);
+}
diff --git a/lib/gui/elistbox.h b/lib/gui/elistbox.h
index 1eb6b3d39b..afe42443a9 100644
--- a/lib/gui/elistbox.h
+++ b/lib/gui/elistbox.h
@@ -89,6 +89,16 @@ struct eListboxStyle
int m_valign, m_halign, m_border_size, m_sliderborder_size, m_scrollbarsliderborder_size;
ePtr m_font, m_secondfont;
ePoint m_text_offset;
+ int m_itemCornerRadius[2];
+ int m_itemCornerRadiusEdges[2];
+ int cornerRadius(int mode)
+ {
+ return m_itemCornerRadius[mode];
+ }
+ int cornerRadiusEdges(int mode)
+ {
+ return m_itemCornerRadiusEdges[mode];
+ }
};
#endif
@@ -179,6 +189,20 @@ class eListbox: public eWidget
int getScrollbarHeight() { return m_scrollbar_height; }
int getMaxItemTextWidth() { return m_content->getMaxItemTextWidth(); }
+ void setItemCornerRadius(int radius, int edges);
+ void setItemCornerRadiusSelected(int radius, int edges);
+
+ static void setDefaultItemRadius(int radius, int radiusEdges)
+ {
+ defaultItemRadius[0] = radius;
+ defaultItemRadiusEdges[0] = radiusEdges;
+ }
+ static void setDefaultItemRadiusSelected(int radius, int radiusEdges)
+ {
+ defaultItemRadius[1] = radius;
+ defaultItemRadiusEdges[1] = radiusEdges;
+ }
+
#ifndef SWIG
struct eListboxStyle *getLocalStyle(void);
@@ -210,6 +234,7 @@ class eListbox: public eWidget
int m_orientation;
int m_items_per_page;
int m_selection_enabled;
+ void setItemCornerRadiusInternal(int radius, int edges, int index);
bool m_native_keys_bound;
@@ -217,6 +242,8 @@ class eListbox: public eWidget
eSlider *m_scrollbar;
eListboxStyle m_style;
ePtr m_scrollbarpixmap, m_scrollbarbackgroundpixmap;
+ static int defaultItemRadius[2];
+ static int defaultItemRadiusEdges[2];
#endif
};
diff --git a/lib/gui/elistboxcontent.cpp b/lib/gui/elistboxcontent.cpp
index f3b2121294..52c88657a7 100644
--- a/lib/gui/elistboxcontent.cpp
+++ b/lib/gui/elistboxcontent.cpp
@@ -3,10 +3,7 @@
#include
#include
#include
-#include
-
-using namespace std;
-
+#include
/*
The basic idea is to have an interface which gives all relevant list
processing functions, and can be used by the listbox to browse trough
@@ -182,13 +179,16 @@ int eListboxPythonStringContent::getMaxItemTextWidth()
void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
{
ePtr fnt;
- painter.clip(eRect(offset, m_itemsize));
+ eRect itemRect(offset, m_itemsize);
+ painter.clip(itemRect);
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;
+ int radius = 0;
+ int edges = 0;
/* get local listbox style, if present */
if (m_listbox)
@@ -198,6 +198,8 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style,
{
border_size = local_style->m_border_size;
border_color = local_style->m_border_color;
+ radius = local_style->cornerRadius(selected ? 1:0);
+ edges = local_style->cornerRadiusEdges(selected ? 1:0);
fnt = local_style->m_font;
if (selected)
{
@@ -232,6 +234,12 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style,
if (validitem) painter.blit(local_style->m_background, ePoint(offset.x() + (m_itemsize.width() - local_style->m_background->size().width()) / 2, offset.y()), eRect(), 0);
}
}
+ else if (local_style && !local_style->m_background && cursorValid && radius)
+ {
+ if(radius)
+ painter.setRadius(radius, edges);
+ painter.drawRectangle(itemRect);
+ }
else
painter.clear();
} else
@@ -244,7 +252,7 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style,
if (validitem) painter.blit(local_style->m_background, ePoint(offset.x() + (m_itemsize.width() - local_style->m_background->size().width()) / 2, offset.y()), eRect(), gPainter::BT_ALPHATEST);
}
}
- else if (selected && !local_style->m_selection)
+ else if (selected && !local_style->m_selection && cursorValid && !radius && !local_style->m_background)
painter.clear();
}
@@ -273,8 +281,13 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style,
else
painter.blit(local_style->m_selection, ePoint(offset.x() + (m_itemsize.width() - local_style->m_selection->size().width()) / 2, offset.y()), eRect(), gPainter::BT_ALPHATEST);
}
+ else if (selected && local_style && radius && !local_style->m_selection) {
+ if(radius)
+ painter.setRadius(radius, edges);
+ painter.drawRectangle(itemRect);
+ }
- if (!item || item == Py_None)
+ if (item == Py_None)
{
/* seperator */
if (isverticallb)
@@ -291,13 +304,15 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style,
{
const char *string = PyUnicode_Check(item) ? PyUnicode_AsUTF8(item) : "";
ePoint text_offset = offset;
+ ePoint style_text_offset = ePoint(0, 0);
if (gray)
painter.setForegroundColor(gRGB(0x808080));
int flags = 0;
if (local_style)
{
- text_offset += local_style->m_text_offset;
+ style_text_offset = local_style->m_text_offset;
+ text_offset += style_text_offset;
if (local_style->m_valign == eListboxStyle::alignTop)
flags |= gPainter::RT_VALIGN_TOP;
@@ -316,7 +331,8 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style,
flags |= gPainter::RT_HALIGN_BLOCK;
}
- painter.renderText(eRect(text_offset, m_itemsize), string, flags, border_color, border_size);
+ // Here we have to compensate the local style text offset from both sides
+ painter.renderText(eRect(text_offset.x(), text_offset.y(), m_itemsize.width() - style_text_offset.x()*2, m_itemsize.height() - style_text_offset.y()*2), string, flags, border_color, border_size);
}
}
@@ -402,6 +418,8 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
bool cursorValid = this->cursorValid();
gRGB border_color;
int border_size = 0;
+ int radius = 0;
+ int edges = 0;
painter.clip(itemrect);
style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
@@ -416,6 +434,8 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
border_color = local_style->m_border_color;
fnt = local_style->m_font;
fnt2 = local_style->m_secondfont;
+ radius = local_style->cornerRadius(selected ? 1:0);
+ edges = local_style->cornerRadiusEdges(selected ? 1:0);
if (selected)
{
/* if we have a local background color set, use that. */
@@ -445,11 +465,18 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
/* if we have no transparent background */
{
/* blit background picture, if available (otherwise, clear only) */
- if (local_style && local_style->m_background && cursorValid)
+ if (local_style && local_style->m_background && cursorValid) {
if (m_listbox && m_listbox->getOrientation() == 1)
painter.blit(local_style->m_background, ePoint(offset.x(), offset.y() + (m_itemsize.height() - local_style->m_background->size().height()) / 2), eRect(), 0);
else
painter.blit(local_style->m_background, ePoint(offset.x() + (m_itemsize.width() - local_style->m_background->size().width()) / 2, offset.y()), eRect(), 0);
+ }
+ else if (local_style && !local_style->m_background && cursorValid && radius)
+ {
+ if(radius)
+ painter.setRadius(radius, edges);
+ painter.drawRectangle(itemrect);
+ }
else
painter.clear();
} else
@@ -459,7 +486,7 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
painter.blit(local_style->m_background, ePoint(offset.x(), offset.y() + (m_itemsize.height() - local_style->m_background->size().height()) / 2), eRect(), gPainter::BT_ALPHATEST);
else
painter.blit(local_style->m_background, ePoint(offset.x() + (m_itemsize.width() - local_style->m_background->size().width()) / 2, offset.y()), eRect(), gPainter::BT_ALPHATEST);
- else if (selected && !local_style->m_selection)
+ else if (selected && !local_style->m_selection && !radius)
painter.clear();
}
@@ -479,6 +506,10 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
painter.blit(local_style->m_selection, ePoint(offset.x(), offset.y() + (m_itemsize.height() - local_style->m_selection->size().height()) / 2), eRect(), gPainter::BT_ALPHATEST);
else
painter.blit(local_style->m_selection, ePoint(offset.x() + (m_itemsize.width() - local_style->m_selection->size().width()) / 2, offset.y()), eRect(), gPainter::BT_ALPHATEST);
+ } else if (selected && radius && !local_style->m_selection) {
+ if(radius)
+ painter.setRadius(radius, edges);
+ painter.drawRectangle(itemrect);
}
/* the first tuple element is a string for the left side.
the second one will be called, and the result shall be an tuple.
@@ -863,7 +894,6 @@ static void clearRegion(gPainter &painter, eWindowStyle &style, eListboxStyle *l
static ePyObject lookupColor(ePyObject color, ePyObject data)
{
-//TODO check the logic, something is wrong in this function
if (color == Py_None)
return ePyObject();
@@ -1000,7 +1030,8 @@ int eListboxPythonMultiContent::getMaxItemTextWidth()
void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
{
- gRegion itemregion(eRect(offset, m_itemsize));
+ eRect itemRect = eRect(offset, m_itemsize);
+ gRegion itemregion(itemRect);
eListboxStyle *local_style = 0;
eRect sel_clip(m_selection_clip);
bool cursorValid = this->cursorValid();
@@ -1021,7 +1052,27 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
}
painter.clip(itemregion);
- clearRegion(painter, style, local_style, ePyObject(), ePyObject(), ePyObject(), ePyObject(), selected, itemregion, sel_clip, offset, m_itemsize, cursorValid, true, isverticallb);
+
+ if(local_style) {
+ int mode = (selected) ? 1:0;
+ int radius = local_style->cornerRadius(mode);
+ int edges = local_style->cornerRadiusEdges(mode);
+ if (radius) {
+ gRGB color = style.getColor(selected ? eWindowStyleSkinned::colListboxSelectedBackground : eWindowStyleSkinned::colListboxBackground);;
+ if (selected && local_style->m_background_color_selected_set)
+ color = local_style->m_background_color_selected;
+ if (!selected && local_style->m_background_color_set)
+ color = local_style->m_background_color;
+
+ painter.setRadius(radius, edges);
+ painter.setBackgroundColor(gRGB(color));
+ painter.drawRectangle(itemRect);
+ }
+ else
+ clearRegion(painter, style, local_style, ePyObject(), ePyObject(), ePyObject(), ePyObject(), selected, itemregion, sel_clip, offset, m_itemsize, cursorValid, true, isverticallb);
+ }
+ else
+ clearRegion(painter, style, local_style, ePyObject(), ePyObject(), ePyObject(), ePyObject(), selected, itemregion, sel_clip, offset, m_itemsize, cursorValid, true, isverticallb);
// Draw frame here so to be under the content
if (selected && !sel_clip.valid() && (!local_style || !local_style->m_selection) && (!local_style || !local_style->m_border_set))
@@ -1128,7 +1179,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
pfnt = PyTuple_GET_ITEM(item, 5),
pflags = PyTuple_GET_ITEM(item, 6),
pstring = PyTuple_GET_ITEM(item, 7),
- pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, pborderWidth, pborderColor;
+ pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, pborderWidth, pborderColor, pCornerRadius, pCornerEdges;
if (!(px && py && pwidth && pheight && pfnt && pflags && pstring))
{
@@ -1151,17 +1202,23 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
if (size > 12)
{
pborderWidth = PyTuple_GET_ITEM(item, 12);
- if (!pborderWidth || pborderWidth == Py_None)
+ if (pborderWidth == Py_None)
pborderWidth=ePyObject();
}
if (size > 13)
pborderColor = lookupColor(PyTuple_GET_ITEM(item, 13), data);
+ if (size > 14)
+ pCornerRadius = PyTuple_GET_ITEM(item, 14);
+
+ if (size > 15)
+ pCornerEdges = PyTuple_GET_ITEM(item, 15);
+
if (PyLong_Check(pstring) && data) /* if the string is in fact a number, it refers to the 'data' list. */
pstring = PyTuple_GetItem(data, PyLong_AsLong(pstring));
/* don't do anything if we have 'None' as string */
- if (!pstring || pstring == Py_None)
+ if (pstring == Py_None)
continue;
const char *string = (PyUnicode_Check(pstring)) ? PyUnicode_AsUTF8(pstring) : "";
@@ -1173,6 +1230,11 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
int fnt = PyLong_AsLong(pfnt);
int bwidth = pborderWidth ? PyLong_AsLong(pborderWidth) : 0;
+ int cornerRadius = pCornerRadius ? PyLong_AsLong(pCornerRadius) : 0;
+ int cornerEdges = pCornerEdges ? PyLong_AsLong(pCornerEdges) : 0;
+ if (cornerRadius || cornerEdges)
+ bwidth = 0; // border not supported for rounded edges
+
if (m_font.find(fnt) == m_font.end())
{
eDebug("[eListboxPythonMultiContent] specified font %d was not found!", fnt);
@@ -1183,9 +1245,21 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
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, m_itemsize, cursorValid, mustClear, isverticallb);
+ if(cornerRadius && (pbackColor || pbackColorSelected))
+ {
+ if(selected && !pbackColorSelected)
+ pbackColorSelected = pbackColor;
+ unsigned int color = PyLong_AsUnsignedLongMask(selected ? pbackColorSelected : pbackColor);
+ painter.setBackgroundColor(gRGB(color));
+ painter.setRadius(cornerRadius, cornerEdges);
+ painter.drawRectangle(itemRect);
+ }
+ else
+ {
+ gRegion rc(rect);
+ bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor);
+ clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, m_itemsize, cursorValid, mustClear, isverticallb);
+ }
}
painter.setFont(m_font[fnt]);
@@ -1193,7 +1267,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
painter.clippop();
// draw border
- if (bwidth)
+ if (bwidth && cornerRadius == 0)
{
eRect rect(eRect(x, y, width, height));
painter.clip(rect);
@@ -1246,7 +1320,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
else
{
ppixmap = PyTuple_GET_ITEM(item, idx++);
- if (!ppixmap || ppixmap == Py_None)
+ if (ppixmap == Py_None)
continue;
if (!(px && py && pwidth && pheight && pfilled_perc, ppixmap))
{
@@ -1258,31 +1332,31 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
if (size > idx)
{
pborderWidth = PyTuple_GET_ITEM(item, idx++);
- if (!pborderWidth || pborderWidth == Py_None)
+ if (pborderWidth == Py_None)
pborderWidth = ePyObject();
}
if (size > idx)
{
pforeColor = PyTuple_GET_ITEM(item, idx++);
- if (!pforeColor || pforeColor == Py_None)
+ if (pforeColor == Py_None)
pforeColor = ePyObject();
}
if (size > idx)
{
pforeColorSelected = PyTuple_GET_ITEM(item, idx++);
- if (!pforeColorSelected || pforeColorSelected == Py_None)
+ if (pforeColorSelected == Py_None)
pforeColorSelected=ePyObject();
}
if (size > idx)
{
pbackColor = PyTuple_GET_ITEM(item, idx++);
- if (!pbackColor || pbackColor == Py_None)
+ if (pbackColor == Py_None)
pbackColor=ePyObject();
}
if (size > idx)
{
pbackColorSelected = PyTuple_GET_ITEM(item, idx++);
- if (!pbackColorSelected || pbackColorSelected == Py_None)
+ if (pbackColorSelected == Py_None)
pbackColorSelected=ePyObject();
}
@@ -1373,7 +1447,7 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
ppixmap = PyTuple_GetItem(data, PyLong_AsLong(ppixmap));
/* don't do anything if we have 'None' as pixmap */
- if (!ppixmap || ppixmap == Py_None)
+ if (ppixmap == Py_None)
continue;
int x = PyLong_AsLong(px) + offset.x();
@@ -1381,6 +1455,8 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
int width = PyLong_AsLong(pwidth);
int height = PyLong_AsLong(pheight);
int flags = 0;
+ int radius = 0;
+ int edges = 0;
ePtr pixmap;
if (SwigFromPython(pixmap, ppixmap))
{
@@ -1397,6 +1473,12 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
if (size > 8)
flags = PyLong_AsLong(PyTuple_GET_ITEM(item, 8));
+ if (size > 9)
+ radius = PyLong_AsLong(PyTuple_GET_ITEM(item, 9));
+
+ if (size > 10)
+ edges = PyLong_AsLong(PyTuple_GET_ITEM(item, 10));
+
eRect rect(x, y, width, height);
painter.clip(rect);
@@ -1406,6 +1488,8 @@ void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, c
clearRegion(painter, style, local_style, ePyObject(), ePyObject(), pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, m_itemsize, cursorValid, mustClear, isverticallb);
}
flags |= (type == TYPE_PIXMAP_ALPHATEST) ? gPainter::BT_ALPHATEST : (type == TYPE_PIXMAP_ALPHABLEND) ? gPainter::BT_ALPHABLEND : 0;
+ if(radius && edges)
+ painter.setRadius(radius, edges);
painter.blit(pixmap, rect, rect, flags);
painter.clippop();
break;
diff --git a/lib/gui/elistboxcontent.h b/lib/gui/elistboxcontent.h
index e4929bd16a..25f0031bc7 100644
--- a/lib/gui/elistboxcontent.h
+++ b/lib/gui/elistboxcontent.h
@@ -110,6 +110,8 @@ class eListboxPythonMultiContent: public eListboxPythonStringContent
#define RT_VALIGN_CENTER 16
#define RT_VALIGN_BOTTOM 32
#define RT_WRAP 64
+#define RT_ELLIPSIS 128
+#define RT_BLEND 256
#define BT_ALPHATEST 1
#define BT_ALPHABLEND 2
#define BT_SCALE 4
@@ -122,6 +124,17 @@ class eListboxPythonMultiContent: public eListboxPythonStringContent
#define BT_VALIGN_CENTER 64
#define BT_VALIGN_BOTTOM 128
#define BT_ALIGN_CENTER BT_HALIGN_CENTER | BT_VALIGN_CENTER
+
+#define RADIUS_TOP_LEFT 1
+#define RADIUS_TOP_RIGHT 2
+#define RADIUS_TOP 3
+#define RADIUS_BOTTOM_LEFT 4
+#define RADIUS_BOTTOM_RIGHT 8
+#define RADIUS_BOTTOM 12
+#define RADIUS_LEFT 5
+#define RADIUS_RIGHT 10
+#define RADIUS_ALL RADIUS_TOP | RADIUS_BOTTOM
+
#endif // SWIG
#endif
diff --git a/lib/gui/eslider.cpp b/lib/gui/eslider.cpp
index 73d8cf3220..1f370cb4c6 100644
--- a/lib/gui/eslider.cpp
+++ b/lib/gui/eslider.cpp
@@ -1,7 +1,7 @@
#include
eSlider::eSlider(eWidget *parent)
- :eWidget(parent), m_have_border_color(false), m_have_foreground_color(false),
+ :eWidget(parent), m_have_border_color(false), m_have_foreground_color(false), m_have_background_color(false),
m_have_sliderborder_color(false), m_have_sliderforeground_color(false), m_have_sliderborder_width(false),
m_min(0), m_max(0), m_value(0), m_start(0), m_orientation(orHorizontal), m_orientation_swapped(0),
m_border_width(0), m_sliderborder_width(0)
@@ -55,6 +55,13 @@ void eSlider::setForegroundColor(const gRGB &color)
invalidate();
}
+void eSlider::setBackgroundColor(const gRGB &col)
+{
+ m_background_color = col;
+ m_have_background_color = true;
+ invalidate();
+}
+
void eSlider::setSliderBorderWidth(int pixel)
{
m_sliderborder_width = pixel;
@@ -108,45 +115,101 @@ int eSlider::event(int event, void *data, void *data2)
eSize s(size());
getStyle(style);
- /* paint background */
- eWidget::event(evtPaint, data, data2);
+ /* paint background */
+ int cornerRadius = getCornerRadius();
+ if(!cornerRadius) // don't call eWidget paint if radius or gradient
+ eWidget::event(evtPaint, data, data2);
gPainter &painter = *(gPainter*)data2;
- style->setStyle(painter, eWindowStyle::styleLabel); // TODO - own style
+ bool drawborder = m_border_width;
+
if (m_backgroundpixmap)
{
- painter.blit(m_backgroundpixmap, ePoint(0, 0), eRect(), isTransparent() ? gPainter::BT_ALPHATEST : 0);
+ if (cornerRadius)
+ painter.setRadius(cornerRadius, getCornerRadiusEdges());
+ painter.blit(m_backgroundpixmap, ePoint(0, 0), eRect(), isTransparent() ? gPainter::BT_ALPHABLEND : 0);
+ } else if(m_have_background_color && !cornerRadius) {
+ painter.setBackgroundColor(m_background_color);
+ painter.clear();
}
- if (!m_pixmap)
+ if(cornerRadius)
{
- if (m_have_sliderforeground_color)
- painter.setForegroundColor(m_sliderforeground_color);
- else if (m_have_foreground_color)
- painter.setForegroundColor(m_foreground_color);
- painter.fill(m_currently_filled);
+ if(m_have_background_color) {
+ painter.setBackgroundColor(m_background_color);
+ }
+ painter.setRadius(cornerRadius, getCornerRadiusEdges());
+
+ if (drawborder)
+ {
+ if (m_have_border_color)
+ painter.setBackgroundColor(m_border_color);
+ else
+ {
+ gRGB color = style->getColor(eWindowStyle::styleLabel);
+ painter.setBackgroundColor(color);
+ }
+ painter.drawRectangle(eRect(ePoint(0, 0), size()));
+ painter.setBackgroundColor((m_have_background_color) ? m_background_color : gRGB(0, 0, 0));
+ painter.setRadius(cornerRadius, getCornerRadiusEdges());
+ painter.drawRectangle(eRect(m_border_width, m_border_width, size().width() - m_border_width * 2, size().height() - m_border_width * 2));
+ drawborder = false;
+ }
+ else {
+ painter.drawRectangle(eRect(ePoint(0, 0), size()));
+ }
}
- else
- painter.blit(m_pixmap, ePoint(0, 0), m_currently_filled.extends, isTransparent() ? gPainter::BT_ALPHATEST : 0);
-// border
+ style->setStyle(painter, eWindowStyle::styleLabel); // TODO - own style
- if (m_have_sliderborder_color)
- painter.setForegroundColor(m_sliderborder_color);
- else if (m_have_border_color)
- painter.setForegroundColor(m_border_color);
+ if (!m_pixmap)
+ {
+ if (cornerRadius)
+ {
+ if (m_have_foreground_color)
+ painter.setBackgroundColor(m_foreground_color);
+ painter.setRadius(cornerRadius, getCornerRadiusEdges());
+ eRect rect = eRect(m_currently_filled.extends);
+ if (m_orientation == orHorizontal)
+ rect.setHeight(size().height()-m_border_width*2);
+ else
+ rect.setWidth(size().width()-m_border_width*2);
+ painter.drawRectangle(rect);
+ }
+ else {
+ if (m_have_sliderforeground_color)
+ painter.setForegroundColor(m_sliderforeground_color);
+ else if (m_have_foreground_color)
+ painter.setForegroundColor(m_foreground_color);
+
+ painter.fill(m_currently_filled);
+ }
+ }
+ else {
- int border_width;
- if(m_have_sliderborder_width)
- border_width = m_sliderborder_width;
- else
- border_width = m_border_width;
- painter.fill(eRect(0, 0, s.width(), border_width));
- painter.fill(eRect(0, border_width, border_width, s.height() - border_width));
- painter.fill(eRect(border_width, s.height() - border_width, s.width() - border_width, border_width));
- painter.fill(eRect(s.width() - border_width, border_width, border_width, s.height() - border_width));
+ if (cornerRadius)
+ painter.setRadius(cornerRadius, getCornerRadiusEdges());
+ painter.blit(m_pixmap, ePoint(0, 0), m_currently_filled.extends, isTransparent() ? gPainter::BT_ALPHABLEND : 0);
+ }
+ // border
+ if(drawborder) {
+ if (m_have_sliderborder_color)
+ painter.setForegroundColor(m_sliderborder_color);
+ else if (m_have_border_color)
+ painter.setForegroundColor(m_border_color);
+
+ int border_width;
+ if(m_have_sliderborder_width)
+ border_width = m_sliderborder_width;
+ else
+ border_width = m_border_width;
+ painter.fill(eRect(0, 0, s.width(), border_width));
+ painter.fill(eRect(0, border_width, border_width, s.height() - border_width));
+ painter.fill(eRect(border_width, s.height() - border_width, s.width() - border_width, border_width));
+ painter.fill(eRect(s.width() - border_width, border_width, border_width, s.height() - border_width));
+ }
return 0;
}
@@ -177,14 +240,24 @@ int eSlider::event(int event, void *data, void *data2)
num_pix = 0;
if (m_orientation == orHorizontal)
- m_currently_filled = eRect(start_pix, 0, num_pix, pixsize);
+ m_currently_filled = eRect(start_pix + m_border_width, m_border_width, num_pix, pixsize);
else
- m_currently_filled = eRect(0, start_pix, pixsize, num_pix);
+ m_currently_filled = eRect(m_border_width, start_pix + m_border_width, pixsize, num_pix);
+
+ const int cornerRadius = getCornerRadius();
+ if (cornerRadius)
+ {
+ invalidate(old_currently_filled);
+ invalidate(m_currently_filled);
+ }
+ else
+ {
// redraw what *was* filled before and now isn't.
- invalidate(m_currently_filled - old_currently_filled);
+ invalidate(m_currently_filled - old_currently_filled);
// redraw what wasn't filled before and is now.
- invalidate(old_currently_filled - m_currently_filled);
+ invalidate(old_currently_filled - m_currently_filled);
+ }
return 0;
}
diff --git a/lib/gui/eslider.h b/lib/gui/eslider.h
index 867843615c..ee25df8951 100644
--- a/lib/gui/eslider.h
+++ b/lib/gui/eslider.h
@@ -15,6 +15,7 @@ class eSlider: public eWidget
void setBorderWidth(int pixel);
void setBorderColor(const gRGB &color);
void setForegroundColor(const gRGB &color);
+ void setBackgroundColor(const gRGB &col) override;
void setPixmap(gPixmap *pixmap);
void setPixmap(ePtr &pixmap);
void setBackgroundPixmap(gPixmap *pixmap);
@@ -34,14 +35,14 @@ class eSlider: public eWidget
{
evtChangedSlider = evtUserWidget
};
- bool m_have_border_color, m_have_foreground_color;
+ bool m_have_border_color, m_have_foreground_color, m_have_background_color;
bool m_have_sliderborder_color, m_have_sliderforeground_color, m_have_sliderborder_width;
int m_min, m_max, m_value, m_start, m_orientation, m_orientation_swapped, m_border_width, m_sliderborder_width;
ePtr m_pixmap, m_backgroundpixmap;
ePtr m_scrollbarslidepixmap, m_scrollbarslidebackgroundpixmap;
gRegion m_currently_filled;
- gRGB m_border_color, m_foreground_color;
+ gRGB m_border_color, m_foreground_color, m_background_color;
gRGB m_sliderborder_color, m_sliderforeground_color;
};
diff --git a/lib/gui/ewidget.cpp b/lib/gui/ewidget.cpp
index 48211b2382..ba54e5224c 100644
--- a/lib/gui/ewidget.cpp
+++ b/lib/gui/ewidget.cpp
@@ -23,6 +23,10 @@ eWidget::eWidget(eWidget *parent): m_animation(this), m_parent(parent ? parent->
m_current_focus = 0;
m_focus_owner = 0;
m_notify_child_on_position_change = 1;
+ m_cornerRadius = 0;
+ m_cornerRadiusEdges = 0;
+ m_have_border_color = false;
+ m_border_width = 0;
}
void eWidget::move(ePoint pos)
@@ -354,15 +358,51 @@ int eWidget::event(int event, void *data, void *data2)
// dumpRegion(*(gRegion*)data);
if (!isTransparent())
{
- if (!m_have_background_color)
+ bool drawborder = (m_have_border_color && m_border_width);
+
+ if (m_have_background_color)
+ painter.setBackgroundColor(m_background_color);
+ const int r = getCornerRadius();
+
+ if (r)
{
- ePtr style;
- if (!getStyle(style))
- style->paintBackground(painter, ePoint(0, 0), size());
- } else
+ if (r)
+ painter.setRadius(r, m_cornerRadiusEdges);
+ if (r && drawborder)
+ {
+ painter.setBackgroundColor(m_border_color);
+ painter.drawRectangle(eRect(ePoint(0, 0), size()));
+ if (r)
+ painter.setRadius(r, m_cornerRadiusEdges);
+ painter.setBackgroundColor(m_have_background_color ? m_background_color : gRGB(0, 0, 0));
+ painter.drawRectangle(eRect(m_border_width, m_border_width, size().width() - m_border_width * 2, size().height() - m_border_width * 2));
+ drawborder = false;
+ }
+ else
+ painter.drawRectangle(eRect(ePoint(0, 0), size()));
+ }
+ else
{
- painter.setBackgroundColor(m_background_color);
- painter.clear();
+ if (!m_have_background_color)
+ {
+ ePtr style;
+ if (!getStyle(style))
+ style->paintBackground(painter, ePoint(0, 0), size());
+ }
+ else
+ {
+ //painter.setBackgroundColor(m_background_color);
+ painter.clear();
+ }
+ }
+ if (drawborder)
+ {
+ painter.setForegroundColor(m_border_color);
+ eSize s(size());
+ 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));
}
} else
{
@@ -415,3 +455,39 @@ void eWidget::notifyShowHide()
for (ePtrList::iterator i(m_childs.begin()); i != m_childs.end(); ++i)
i->notifyShowHide();
}
+
+void eWidget::setCornerRadius(int radius, int edges)
+{
+ m_cornerRadius = radius;
+ m_cornerRadiusEdges = edges;
+ invalidate();
+}
+
+void eWidget::setBorderWidth(int pixel)
+{
+ m_border_width = pixel;
+ invalidate();
+}
+
+void eWidget::setBorderColor(const gRGB &color)
+{
+ m_border_color = color;
+ m_have_border_color = true;
+ invalidate();
+}
+
+int eWidget::getCornerRadius()
+{
+ int r = m_cornerRadius;
+ if(r) {
+ const int w = m_size.width();
+ const int h = m_size.height();
+ if(w && h) {
+ int minDimension = (w < h) ? w : h;
+ if (r > minDimension / 2) {
+ r = minDimension / 2;
+ }
+ }
+ }
+ return r;
+}
diff --git a/lib/gui/ewidget.h b/lib/gui/ewidget.h
index a0ad46b3be..67aedb5269 100644
--- a/lib/gui/ewidget.h
+++ b/lib/gui/ewidget.h
@@ -45,9 +45,15 @@ class eWidget
SWIG_VOID(int) getStyle(ePtr &SWIG_NAMED_OUTPUT(style)) { if (!m_style) return 1; style = m_style; return 0; }
void setStyle(eWindowStyle *style) { m_style = style; }
- void setBackgroundColor(const gRGB &col);
+ virtual void setBackgroundColor(const gRGB &col);
void clearBackgroundColor();
+ void setBorderWidth(int pixel);
+ void setBorderColor(const gRGB &color);
+
+ void setWidgetBorderWidth(int pixel) { setBorderWidth(pixel); }
+ void setWidgetBorderColor(const gRGB &color) { setBorderColor(color); }
+
void setZPosition(int z);
void setTransparent(int transp);
@@ -97,6 +103,19 @@ class eWidget
int m_z_position;
int m_lowered;
int m_notify_child_on_position_change;
+
+ bool m_gradient_set;
+ bool m_gradient_alphablend;
+ int m_gradient_direction;
+ gRGB m_gradient_startcolor, m_gradient_endcolor;
+
+ bool m_have_border_color;
+ int m_border_width;
+ gRGB m_border_color;
+
+ int m_cornerRadius;
+ int m_cornerRadiusEdges;
+
protected:
void mayKillFocus();
public:
@@ -132,6 +151,23 @@ class eWidget
void setPositionNotifyChild(int n) { m_notify_child_on_position_change = 1; }
void notifyShowHide();
+
+ void setCornerRadius(int radius, int edges);
+ int getCornerRadiusEdges() {return m_cornerRadiusEdges;}
+ int getCornerRadius();
+
+ enum
+ {
+ RADIUS_TOP_LEFT = 1,
+ RADIUS_TOP_RIGHT = 2,
+ RADIUS_TOP = 3,
+ RADIUS_BOTTOM_LEFT = 4,
+ RADIUS_BOTTOM_RIGHT = 8,
+ RADIUS_BOTTOM = 12,
+ RADIUS_LEFT = 5,
+ RADIUS_RIGHT = 10,
+ RADIUS_ALL = 15,
+ };
};
extern eWidgetDesktop *getDesktop(int which);
diff --git a/lib/gui/ewidgetdesktop.cpp b/lib/gui/ewidgetdesktop.cpp
index 50097af7b0..e51ac596d3 100644
--- a/lib/gui/ewidgetdesktop.cpp
+++ b/lib/gui/ewidgetdesktop.cpp
@@ -59,7 +59,7 @@ int eWidgetDesktop::movedWidget(eWidget *root)
return 0; /* native move ok */
}
-void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible)
+void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible, bool parent)
{
/* start with our clip region, clipped with the parent's */
if (widget->m_vis & eWidget::wVisShow)
@@ -68,7 +68,7 @@ void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visib
widget->m_visible_region.moveBy(widget->position());
widget->m_visible_region &= parent_visible; // in parent space!
- if (!widget->isTransparent())
+ if (!widget->isTransparent() && (widget->m_cornerRadius == 0 || parent))
/* remove everything this widget will contain from parent's visible list, unless widget is transparent. */
parent_visible -= widget->m_visible_region; // will remove child regions too!
@@ -87,7 +87,7 @@ void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visib
if (i != widget->m_childs.end())
{
if (i->m_vis & eWidget::wVisShow)
- calcWidgetClipRegion(*i, widget->m_visible_region);
+ calcWidgetClipRegion(*i, widget->m_visible_region, false);
else
clearVisibility(*i);
}
diff --git a/lib/gui/ewidgetdesktop.h b/lib/gui/ewidgetdesktop.h
index 9897a1f0dc..58073e1f93 100644
--- a/lib/gui/ewidgetdesktop.h
+++ b/lib/gui/ewidgetdesktop.h
@@ -78,7 +78,7 @@ class eWidgetDesktop: public sigc::trackable
void setMargins(const eRect& value) { m_margins = value; }
private:
ePtrList m_root;
- void calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible);
+ void calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible, bool parent = true);
void paintBackground(eWidgetDesktopCompBuffer *comp);
eMainloop *m_mainloop;
diff --git a/lib/gui/ewindow.cpp b/lib/gui/ewindow.cpp
index ff29b209a8..0af29da312 100644
--- a/lib/gui/ewindow.cpp
+++ b/lib/gui/ewindow.cpp
@@ -114,3 +114,9 @@ int eWindow::event(int event, void *data, void *data2)
return eWidget::event(event, data, data2);
}
+void eWindow::setCornerRadius(int radius, int edges)
+{
+ /* set corner radius for child, too */
+ eWidget::setCornerRadius(radius, edges);
+ m_child->setCornerRadius(radius, edges);
+}
\ No newline at end of file
diff --git a/lib/gui/ewindow.h b/lib/gui/ewindow.h
index 8ce34d233d..3e94d29cd3 100644
--- a/lib/gui/ewindow.h
+++ b/lib/gui/ewindow.h
@@ -21,6 +21,7 @@ class eWindow: public eWidget
};
void setBackgroundColor(const gRGB &col);
+ void setCornerRadius(int radius, int edges);
void setFlag(int flags);
void clearFlag(int flags);
diff --git a/lib/gui/ewindowstyle.cpp b/lib/gui/ewindowstyle.cpp
index 9392592dcb..0c4a681f96 100644
--- a/lib/gui/ewindowstyle.cpp
+++ b/lib/gui/ewindowstyle.cpp
@@ -127,6 +127,11 @@ void eWindowStyleSimple::setStyle(gPainter &painter, int what)
}
}
+gRGB eWindowStyleSimple::getColor(int what)
+{
+ return nullptr;
+}
+
void eWindowStyleSimple::drawFrame(gPainter &painter, const eRect &frame, int what)
{
gColor c1, c2;
diff --git a/lib/gui/ewindowstyle.h b/lib/gui/ewindowstyle.h
index 919dd15cd3..b09d489f3b 100644
--- a/lib/gui/ewindowstyle.h
+++ b/lib/gui/ewindowstyle.h
@@ -48,6 +48,7 @@ class eWindowStyle: public eWindowStyle_ENUMS, public iObject
virtual void setStyle(gPainter &painter, int what) = 0;
virtual void drawFrame(gPainter &painter, const eRect &frame, int type) = 0;
virtual RESULT getFont(int what, ePtr &font) = 0;
+ virtual gRGB getColor(int what) = 0;
#endif
virtual ~eWindowStyle() = 0;
};
@@ -98,6 +99,7 @@ class eWindowStyleSimple: public eWindowStyle
void setStyle(gPainter &painter, int what);
void drawFrame(gPainter &painter, const eRect &frame, int what);
RESULT getFont(int what, ePtr &font);
+ gRGB getColor(int what);
};
#endif
diff --git a/lib/gui/ewindowstyleskinned.cpp b/lib/gui/ewindowstyleskinned.cpp
index ae47311a6d..d07259f749 100644
--- a/lib/gui/ewindowstyleskinned.cpp
+++ b/lib/gui/ewindowstyleskinned.cpp
@@ -268,6 +268,13 @@ void eWindowStyleSkinned::setColor(int what, const gRGB &col)
m_color[what] = col;
}
+gRGB eWindowStyleSkinned::getColor(int what)
+{
+ if ((what < colMax) && (what >= 0))
+ return m_color[what];
+ return nullptr;
+}
+
void eWindowStyleSkinned::setTitleOffset(const eSize &offset)
{
m_title_offset = offset;
diff --git a/lib/gui/ewindowstyleskinned.h b/lib/gui/ewindowstyleskinned.h
index a6cdb891dd..707b9a0640 100644
--- a/lib/gui/ewindowstyleskinned.h
+++ b/lib/gui/ewindowstyleskinned.h
@@ -73,6 +73,7 @@ class eWindowStyleSkinned: public eWindowStyle
};
void setColor(int what, const gRGB &back);
+ gRGB getColor(int what);
void setTitleOffset(const eSize &offset);
void setTitleFont(gFont *fnt);
diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py
index 3e048e47d7..41b933926b 100644
--- a/lib/python/Components/AVSwitch.py
+++ b/lib/python/Components/AVSwitch.py
@@ -1,9 +1,10 @@
from Components.config import config, ConfigSlider, ConfigSelection, ConfigYesNo, ConfigEnableDisable, ConfigSubsection, ConfigBoolean, ConfigSelectionNumber, ConfigNothing, NoSave
from enigma import eAVSwitch, eDVBVolumecontrol, getDesktop
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
import os
from boxbranding import getBoxType, getMachineBuild
+iAVSwitch = None # will be initialized later, allows to import name 'iAVSwitch' from 'Components.AVSwitch'
class AVSwitch:
def setInput(self, input):
@@ -72,11 +73,11 @@ def InitAVSwitch():
colorformat_choices = {"cvbs": "CVBS"}
# when YUV, Scart or S-Video is not support by HW, don't let the user select it
- if SystemInfo["HasYPbPr"]:
+ if BoxInfo.getItem("HasYPbPr"):
colorformat_choices["yuv"] = "YPbPr"
- if SystemInfo["HasScart"]:
+ if BoxInfo.getItem("HasScart"):
colorformat_choices["rgb"] = "RGB"
- if SystemInfo["HasSVideo"]:
+ if BoxInfo.getItem("HasSVideo"):
colorformat_choices["svideo"] = "S-Video"
config.av.colorformat = ConfigSelection(choices=colorformat_choices, default="cvbs")
@@ -171,7 +172,7 @@ def setWSS(configElement):
config.av.wss.addNotifier(setWSS)
iAVSwitch.setInput("ENCODER") # init on startup
- SystemInfo["ScartSwitch"] = eAVSwitch.getInstance().haveScartSwitch()
+ BoxInfo.setItem("ScartSwitch", eAVSwitch.getInstance().haveScartSwitch())
def ch(node):
return node, pnD.get(node, node)
@@ -212,13 +213,13 @@ def readChoices(procx, choices, default):
default = choiceslist[0]
return (choices, default)
- if SystemInfo["HasMultichannelPCM"]:
+ if BoxInfo.getItem("HasMultichannelPCM"):
def setMultichannelPCM(configElement):
- open(SystemInfo["HasMultichannelPCM"], "w").write(configElement.value and "enable" or "disable")
+ open(BoxInfo.getItem("HasMultichannelPCM"), "w").write(configElement.value and "enable" or "disable")
config.av.multichannel_pcm = ConfigYesNo(default=False)
config.av.multichannel_pcm.addNotifier(setMultichannelPCM)
- if SystemInfo["CanDownmixAC3"]:
+ if BoxInfo.getItem("CanDownmixAC3"):
def setAC3Downmix(configElement):
open("/proc/stb/audio/ac3", "w").write(configElement.value)
choices = [(ch("downmix")), (ch("passthrough"))]
@@ -229,7 +230,7 @@ def setAC3Downmix(configElement):
config.av.downmix_ac3 = ConfigSelection(choices=choices, default=default)
config.av.downmix_ac3.addNotifier(setAC3Downmix)
- if SystemInfo["CanAC3Transcode"]:
+ if BoxInfo.getItem("CanAC3Transcode"):
def setAC3plusTranscode(configElement):
open("/proc/stb/audio/ac3plus", "w").write(configElement.value)
choices = [(ch("use_hdmi_caps")), (ch("force_ac3"))]
@@ -240,7 +241,7 @@ def setAC3plusTranscode(configElement):
config.av.transcodeac3plus = ConfigSelection(choices=choices, default=default)
config.av.transcodeac3plus.addNotifier(setAC3plusTranscode)
- if SystemInfo["CanDownmixDTS"]:
+ if BoxInfo.getItem("CanDownmixDTS"):
def setDTSDownmix(configElement):
open("/proc/stb/audio/dts", "w").write(configElement.value)
choices = [(ch("downmix")), (ch("passthrough"))]
@@ -251,7 +252,7 @@ def setDTSDownmix(configElement):
config.av.downmix_dts = ConfigSelection(choices=choices, default=default)
config.av.downmix_dts.addNotifier(setDTSDownmix)
- if SystemInfo["CanDTSHD"]:
+ if BoxInfo.getItem("CanDTSHD"):
def setDTSHD(configElement):
open("/proc/stb/audio/dtshd", "w").write(configElement.value)
choices = [(ch("downmix")), (ch("force_dts")), (ch("use_hdmi_caps")), (ch("multichannel")), (ch("hdmi_best"))]
@@ -262,7 +263,7 @@ def setDTSHD(configElement):
config.av.dtshd = ConfigSelection(choices=choices, default=default)
config.av.dtshd.addNotifier(setDTSHD)
- if SystemInfo["CanDownmixAAC"]:
+ if BoxInfo.getItem("CanDownmixAAC"):
def setAACDownmix(configElement):
open("/proc/stb/audio/aac", "w").write(configElement.value)
choices = [(ch("downmix")), (ch("passthrough"))]
@@ -273,7 +274,7 @@ def setAACDownmix(configElement):
config.av.downmix_aac = ConfigSelection(choices=choices, default=default)
config.av.downmix_aac.addNotifier(setAACDownmix)
- if SystemInfo["CanDownmixAACPlus"]:
+ if BoxInfo.getItem("CanDownmixAACPlus"):
def setAACDownmixPlus(configElement):
open("/proc/stb/audio/aacplus", "w").write(configElement.value)
choices = [(ch("downmix")), (ch("passthrough")), (ch("multichannel")), (ch("force_ac3")), (ch("force_dts")), (ch("use_hdmi_cacenter")), (ch("wide")), (ch("extrawide"))]
@@ -284,7 +285,7 @@ def setAACDownmixPlus(configElement):
config.av.downmix_aacplus = ConfigSelection(choices=choices, default=default)
config.av.downmix_aacplus.addNotifier(setAACDownmixPlus)
- if SystemInfo["CanAACTranscode"]:
+ if BoxInfo.getItem("CanAACTranscode"):
def setAACTranscode(configElement):
open("/proc/stb/audio/aac_transcode", "w").write(configElement.value)
choices = [(ch("off")), (ch("ac3")), (ch("dts"))]
@@ -295,7 +296,7 @@ def setAACTranscode(configElement):
config.av.transcodeaac = ConfigSelection(choices=choices, default=default)
config.av.transcodeaac.addNotifier(setAACTranscode)
- if SystemInfo["CanWMAPRO"]:
+ if BoxInfo.getItem("CanWMAPRO"):
def setWMAPRO(configElement):
open("/proc/stb/audio/wmapro", "w").write(configElement.value)
choices = [(ch("downmix")), (ch("passthrough")), (ch("multichannel")), (ch("hdmi_best"))]
@@ -306,7 +307,7 @@ def setWMAPRO(configElement):
config.av.wmapro = ConfigSelection(choices=choices, default=default)
config.av.wmapro.addNotifier(setWMAPRO)
- if SystemInfo["CanBTAudio"]:
+ if BoxInfo.getItem("CanBTAudio"):
def setBTAudio(configElement):
open("/proc/stb/audio/btaudio", "w").write(configElement.value)
choices = [(ch("off")), (ch("on"))]
@@ -317,28 +318,28 @@ def setBTAudio(configElement):
config.av.btaudio = ConfigSelection(choices=choices, default="off")
config.av.btaudio.addNotifier(setBTAudio)
- if SystemInfo["CanBTAudioDelay"]:
+ if BoxInfo.getItem("CanBTAudioDelay"):
def setBTAudioDelay(configElement):
try:
- with open(SystemInfo["CanBTAudioDelay"], "w") as fd:
+ with open(BoxInfo.getItem("CanBTAudioDelay"), "w") as fd:
fd.write(format(configElement.value * 90, "x"))
except:
- SystemInfo["CanBTAudioDelay"] = False
+ BoxInfo.setItem("CanBTAudioDelay", False)
config.av.btaudiodelay = ConfigSelectionNumber(-1000, 1000, 5, default=0)
config.av.btaudiodelay.addNotifier(setBTAudioDelay)
try:
- SystemInfo["CanChangeOsdAlpha"] = open("/proc/stb/video/alpha", "r") and True or False
+ BoxInfo.setItem("CanChangeOsdAlpha", open("/proc/stb/video/alpha", "r") and True or False)
except:
- SystemInfo["CanChangeOsdAlpha"] = False
+ BoxInfo.setItem("CanChangeOsdAlpha", False)
- if SystemInfo["CanChangeOsdAlpha"]:
+ if BoxInfo.getItem("CanChangeOsdAlpha"):
def setAlpha(configElement):
open("/proc/stb/video/alpha", "w").write(str(configElement.value))
config.av.osd_alpha = ConfigSlider(default=255, limits=(0, 255))
config.av.osd_alpha.addNotifier(setAlpha)
- if SystemInfo["HasScaler_sharpness"]:
+ if BoxInfo.getItem("HasScaler_sharpness"):
def setScaler_sharpness(configElement):
try:
open("/proc/stb/vmpeg/0/pep_scaler_sharpness", "w").write("%0.8X" % int(configElement.value))
@@ -354,9 +355,9 @@ def setScaler_sharpness(configElement):
else:
config.av.scaler_sharpness = NoSave(ConfigNothing())
- if SystemInfo["HasAutoVolume"]:
+ if BoxInfo.getItem("HasAutoVolume"):
def setAutoVolume(configElement):
- open(SystemInfo["HasAutoVolume"], "w").write(configElement.value)
+ open(BoxInfo.getItem("HasAutoVolume"), "w").write(configElement.value)
choices = [(ch("none")), (ch("hdmi")), (ch("spdif")), (ch("dac"))]
default = "none"
f = "/proc/stb/audio/avl_choices"
@@ -365,15 +366,15 @@ def setAutoVolume(configElement):
config.av.autovolume = ConfigSelection(choices=choices, default=default)
config.av.autovolume.addNotifier(setAutoVolume)
- if SystemInfo["HasAutoVolumeLevel"]:
+ if BoxInfo.getItem("HasAutoVolumeLevel"):
def setAutoVolumeLevel(configElement):
- open(SystemInfo["HasAutoVolumeLevel"], "w").write(configElement.value and "enabled" or "disabled")
+ open(BoxInfo.getItem("HasAutoVolumeLevel"), "w").write(configElement.value and "enabled" or "disabled")
config.av.autovolumelevel = ConfigYesNo(default=False)
config.av.autovolumelevel.addNotifier(setAutoVolumeLevel)
- if SystemInfo["Has3DSurround"]:
+ if BoxInfo.getItem("Has3DSurround"):
def set3DSurround(configElement):
- open(SystemInfo["Has3DSurround"], "w").write(configElement.value)
+ open(BoxInfo.getItem("Has3DSurround"), "w").write(configElement.value)
choices = [(ch("none")), (ch("hdmi")), (ch("spdif")), (ch("dac"))]
default = "none"
f = "/proc/stb/audio/3d_surround_choices"
@@ -382,15 +383,15 @@ def set3DSurround(configElement):
config.av.surround_3d = ConfigSelection(choices=choices, default=default)
config.av.surround_3d.addNotifier(set3DSurround)
- if SystemInfo["Has3DSpeaker"]:
+ if BoxInfo.getItem("Has3DSpeaker"):
def set3DSpeaker(configElement):
- open(SystemInfo["Has3DSpeaker"], "w").write(configElement.value)
+ open(BoxInfo.getItem("Has3DSpeaker"), "w").write(configElement.value)
config.av.speaker_3d = ConfigSelection(default="center", choices=[("center", _("center")), ("wide", _("wide")), ("extrawide", _("extra wide"))])
config.av.speaker_3d.addNotifier(set3DSpeaker)
- if SystemInfo["Has3DSurroundSpeaker"]:
+ if BoxInfo.getItem("Has3DSurroundSpeaker"):
def set3DSurroundSpeaker(configElement):
- open(SystemInfo["Has3DSurroundSpeaker"], "w").write(configElement.value)
+ open(BoxInfo.getItem("Has3DSurroundSpeaker"), "w").write(configElement.value)
choices = [(ch("center")), (ch("wide")), (ch("extrawide"))]
default = "center"
f = "/proc/stb/audio/3dsurround_choices"
@@ -399,15 +400,15 @@ def set3DSurroundSpeaker(configElement):
config.av.surround_3d_speaker = ConfigSelection(choices=choices, default=default)
config.av.surround_3d_speaker.addNotifier(set3DSurroundSpeaker)
- if SystemInfo["Has3DSurroundSoftLimiter"]:
+ if BoxInfo.getItem("Has3DSurroundSoftLimiter"):
def set3DSurroundSoftLimiter(configElement):
- open(SystemInfo["Has3DSurroundSoftLimiter"], "w").write(configElement.value and "enabled" or "disabled")
+ open(BoxInfo.getItem("Has3DSurroundSoftLimiter"), "w").write(configElement.value and "enabled" or "disabled")
config.av.surround_softlimiter_3d = ConfigYesNo(default=False)
config.av.surround_softlimiter_3d.addNotifier(set3DSurroundSoftLimiter)
- if SystemInfo["HDMIAudioSource"]:
+ if BoxInfo.getItem("HDMIAudioSource"):
def setHDMIAudioSource(configElement):
- open(SystemInfo["HDMIAudioSource"], "w").write(configElement.value)
+ open(BoxInfo.getItem("HDMIAudioSource"), "w").write(configElement.value)
config.av.hdmi_audio_source = ConfigSelection(default="pcm", choices=[("pcm", "PCM"), ("spdif", "SPDIF")])
config.av.hdmi_audio_source.addNotifier(setHDMIAudioSource)
@@ -416,16 +417,16 @@ def setVolumeStepsize(configElement):
config.av.volume_stepsize = ConfigSelectionNumber(1, 10, 1, default=5)
config.av.volume_stepsize.addNotifier(setVolumeStepsize)
- if SystemInfo["HasBypassEdidChecking"]:
+ if BoxInfo.getItem("HasBypassEdidChecking"):
def setHasBypassEdidChecking(configElement):
- open(SystemInfo["HasBypassEdidChecking"], "w").write("00000001" if configElement.value else "00000000")
+ open(BoxInfo.getItem("HasBypassEdidChecking"), "w").write("00000001" if configElement.value else "00000000")
config.av.bypassEdidChecking = ConfigYesNo(default=False)
config.av.bypassEdidChecking.addNotifier(setHasBypassEdidChecking)
- if SystemInfo["HasColorspace"]:
+ if BoxInfo.getItem("HasColorspace"):
def setHaveColorspace(configElement):
- open(SystemInfo["HasColorspace"], "w").write(configElement.value)
- if SystemInfo["HasColorspaceSimple"]:
+ open(BoxInfo.getItem("HasColorspace"), "w").write(configElement.value)
+ if BoxInfo.getItem("HasColorspaceSimple"):
choices = [("Edid(Auto)", "auto"), ("Hdmi_Rgb", "RGB"), ("444", "YCbCr 4:4:4"), ("422", "YCbCr 4:2:2"), ("420", "YCbCr 4:2:0")]
default = "Edid(Auto)"
else:
@@ -437,9 +438,9 @@ def setHaveColorspace(configElement):
config.av.hdmicolorspace = ConfigSelection(choices=choices, default=default)
config.av.hdmicolorspace.addNotifier(setHaveColorspace)
- if SystemInfo["HasColordepth"]:
+ if BoxInfo.getItem("HasColordepth"):
def setHaveColordepth(configElement):
- open(SystemInfo["HasColordepth"], "w").write(configElement.value)
+ open(BoxInfo.getItem("HasColordepth"), "w").write(configElement.value)
choices = [("auto", "auto"), ("8bit", "8bit"), ("10bit", "10bit"), ("12bit", "12bit")]
default = "auto"
f = "/proc/stb/video/hdmi_colordepth_choices"
@@ -448,15 +449,15 @@ def setHaveColordepth(configElement):
config.av.hdmicolordepth = ConfigSelection(choices=choices, default=default)
config.av.hdmicolordepth.addNotifier(setHaveColordepth)
- if SystemInfo["HasHDMIpreemphasis"]:
+ if BoxInfo.getItem("HasHDMIpreemphasis"):
def setHDMIpreemphasis(configElement):
- open(SystemInfo["HasHDMIpreemphasis"], "w").write("on" if configElement.value else "off")
+ open(BoxInfo.getItem("HasHDMIpreemphasis"), "w").write("on" if configElement.value else "off")
config.av.hdmipreemphasis = ConfigYesNo(default=False)
config.av.hdmipreemphasis.addNotifier(setHDMIpreemphasis)
- if SystemInfo["HasColorimetry"]:
+ if BoxInfo.getItem("HasColorimetry"):
def setColorimetry(configElement):
- open(SystemInfo["HasColorimetry"], "w").write(configElement.value)
+ open(BoxInfo.getItem("HasColorimetry"), "w").write(configElement.value)
choices = [("auto", "auto"), ("bt2020ncl", "BT 2020 NCL"), ("bt2020cl", "BT 2020 CL"), ("bt709", "BT 709")]
default = "auto"
f = "/proc/stb/video/hdmi_colorimetry_choices"
@@ -465,13 +466,13 @@ def setColorimetry(configElement):
config.av.hdmicolorimetry = ConfigSelection(choices=choices, default=default)
config.av.hdmicolorimetry.addNotifier(setColorimetry)
- if SystemInfo["HasHdrType"]:
+ if BoxInfo.getItem("HasHdrType"):
def setHdmiHdrType(configElement):
- open(SystemInfo["HasHdrType"], "w").write(configElement.value)
+ open(BoxInfo.getItem("HasHdrType"), "w").write(configElement.value)
config.av.hdmihdrtype = ConfigSelection(default="auto", choices={"auto": _("auto"), "none": "SDR", "hdr10": "HDR10", "hlg": "HLG", "dolby": "Dolby Vision"})
config.av.hdmihdrtype.addNotifier(setHdmiHdrType)
- if SystemInfo["HDRSupport"]:
+ if BoxInfo.getItem("HDRSupport"):
def setHlgSupport(configElement):
open("/proc/stb/hdmi/hlg_support", "w").write(configElement.value)
config.av.hlg_support = ConfigSelection(default="auto(EDID)", choices=[("auto(EDID)", _("controlled by HDMI")), ("yes", _("force enabled")), ("no", _("force disabled"))])
diff --git a/lib/python/Components/Addons/GUIAddon.py b/lib/python/Components/Addons/GUIAddon.py
index 0a7c72fa3e..4ca287a615 100644
--- a/lib/python/Components/Addons/GUIAddon.py
+++ b/lib/python/Components/Addons/GUIAddon.py
@@ -9,7 +9,10 @@ def __init__(self):
def connectRelatedElement(self, relatedElementName, container):
relatedElementNames = relatedElementName.split(",")
if len(relatedElementNames) == 1:
- self.source = container[relatedElementName]
+ if relatedElementName == "session":
+ self.source = container.session
+ else:
+ self.source = container[relatedElementName]
elif len(relatedElementNames) > 1:
for x in relatedElementNames:
if x in container:
diff --git a/lib/python/Components/Addons/Makefile.am b/lib/python/Components/Addons/Makefile.am
index cbbe711834..83aed18963 100644
--- a/lib/python/Components/Addons/Makefile.am
+++ b/lib/python/Components/Addons/Makefile.am
@@ -5,4 +5,5 @@ install_PYTHON = \
Pager.py \
ButtonSequence.py \
ColorButtonsSequence.py \
- ScreenHeader.py
+ ScreenHeader.py \
+ ServiceInfoBar.py
diff --git a/lib/python/Components/Addons/Pager.py b/lib/python/Components/Addons/Pager.py
index 15cbb52a5e..405a2b4aa4 100644
--- a/lib/python/Components/Addons/Pager.py
+++ b/lib/python/Components/Addons/Pager.py
@@ -33,19 +33,26 @@ def __init__(self):
def onContainerShown(self):
# disable listboxes default scrollbars
if hasattr(self.source, "instance") and hasattr(self.source.instance, "setScrollbarMode"):
- self.source.instance.setScrollbarMode(2)
+ self.source.instance.setScrollbarMode(eListbox.showNever)
- if hasattr(self.source, "onSelectionChanged"):
- if self.initPager not in self.source.onSelectionChanged:
- self.source.onSelectionChanged.append(self.initPager)
- elif hasattr(self.source, "onSelChanged"):
- if self.initPager not in self.source.onSelChanged:
- self.source.onSelChanged.append(self.initPager)
+ if self.source and hasattr(self.source, "onVisibilityChange"):
+ self.source.onVisibilityChange.append(self.onSourceVisibleChanged)
+
+ onSelectionChanged = x if (x := getattr(self.source, "onSelectionChanged", None)) is not None else getattr(self.source, "onSelChanged", None)
+
+ if isinstance(onSelectionChanged, list) and self.initPager not in onSelectionChanged:
+ onSelectionChanged.append(self.initPager)
self.initPager()
GUI_WIDGET = eListbox
+ def onSourceVisibleChanged(self, visible):
+ if visible:
+ self.show()
+ else:
+ self.hide()
+
def buildEntry(self, currentPage, pageCount):
width = self.l.getItemSize().width()
height = self.l.getItemSize().height()
diff --git a/lib/python/Components/Addons/ServiceInfoBar.py b/lib/python/Components/Addons/ServiceInfoBar.py
new file mode 100644
index 0000000000..bbd33560fe
--- /dev/null
+++ b/lib/python/Components/Addons/ServiceInfoBar.py
@@ -0,0 +1,333 @@
+from Components.Addons.GUIAddon import GUIAddon
+
+from enigma import eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER, iPlayableService, iRecordableService, eServiceReference, iServiceInformation, gFont, RT_HALIGN_LEFT, RT_VALIGN_CENTER, RT_VALIGN_TOP, RT_HALIGN_CENTER, eTimer, getDesktop, eSize, eStreamServer
+
+from skin import parseScale, applySkinFactor, parseColor, parseFont
+
+from Components.MultiContent import MultiContentEntryPixmapAlphaBlend, MultiContentEntryText
+from Components.ServiceEventTracker import ServiceEventTracker
+from Components.Converter.ServiceInfo import getVideoHeight
+from Components.Converter.VAudioInfo import StdAudioDesc
+from Components.Converter.PliExtraInfo import createCurrentCaidLabel
+from Components.Label import Label
+from Components.Sources.StreamService import StreamServiceList
+
+from Components.config import config
+
+from Screens.InfoBarGenerics import hasActiveSubservicesForCurrentChannel
+
+from Tools.Directories import resolveFilename, SCOPE_GUISKIN
+from Tools.LoadPixmap import LoadPixmap
+
+import NavigationInstance
+
+
+class ServiceInfoBar(GUIAddon):
+ def __init__(self):
+ GUIAddon.__init__(self)
+ self.nav = NavigationInstance.instance
+ self.nav.record_event.append(self.gotRecordEvent)
+ self.refreshCryptoInfo = eTimer()
+ self.refreshCryptoInfo.callback.append(self.checkCrypto_update)
+ self.refreshAddon = eTimer()
+ self.refreshAddon.callback.append(self.updateAddon)
+ self.elements = []
+ self.l = eListboxPythonMultiContent() # noqa: E741
+ self.l.setBuildFunc(self.buildEntry)
+ self.l.setItemHeight(36)
+ self.l.setItemWidth(36)
+ self.spacing = applySkinFactor(10)
+ self.orientations = {"orHorizontal": eListbox.orHorizontal, "orVertical": eListbox.orVertical}
+ self.orientation = eListbox.orHorizontal
+ self.alignment = "left"
+ self.pixmaps = {}
+ self.pixmapsDisabled = {}
+ self.separatorLineColor = 0xC0C0C0
+ self.foreColor = 0xFFFFFF
+ self.separatorLineThickness = 0
+ self.autoresizeMode = "auto" # possible values: auto, fixed, condensed
+ self.font = gFont("Regular", 18)
+ self.__event_tracker = None
+ self.current_crypto = "---"
+ self.textRenderer = Label("")
+ self.permanentIcons = []
+ self.records_running = 0
+ self.streamServer = eStreamServer.getInstance()
+ self.currentServiceSource = None
+
+ def onContainerShown(self):
+ self.textRenderer.GUIcreate(self.relatedScreen.instance)
+ self.l.setItemHeight(self.instance.size().height())
+ self.l.setItemWidth(self.instance.size().width())
+ self.updateAddon()
+ if not self.__event_tracker:
+ self.__event_tracker = ServiceEventTracker(screen=self.relatedScreen,
+ eventmap={
+ iPlayableService.evStart: self.scheduleAddonUpdate,
+ iPlayableService.evEnd: self.scheduleAddonUpdate,
+ iPlayableService.evUpdatedInfo: self.scheduleAddonUpdate,
+ iPlayableService.evVideoSizeChanged: self.updateAddon,
+ iPlayableService.evHBBTVInfo: self.scheduleAddonUpdate,
+ iPlayableService.evNewProgramInfo: self.scheduleAddonUpdate,
+ iPlayableService.evCuesheetChanged: self.scheduleAddonUpdate,
+ }
+ )
+ self.currentServiceSource = self.source.screen["CurrentService"]
+ if self.currentServiceSource and self.updateAddon not in self.currentServiceSource.onManualNewService:
+ self.currentServiceSource.onManualNewService.append(self.scheduleAddonUpdate)
+
+ def destroy(self):
+ self.nav.record_event.remove(self.gotRecordEvent)
+ self.refreshCryptoInfo.stop()
+ self.refreshAddon.stop()
+ self.refreshCryptoInfo.callback.remove(self.checkCrypto_update)
+ self.refreshAddon.callback.remove(self.updateAddon)
+ GUIAddon.destroy(self)
+
+ GUI_WIDGET = eListbox
+
+ def remove_doubles(self, a_list):
+ duplicate = None
+ for item in a_list:
+ if duplicate != item:
+ duplicate = item
+ yield item
+
+ def gotRecordEvent(self, service, event):
+ prev_records = self.records_running
+ if event in (iRecordableService.evEnd, iRecordableService.evStart, None):
+ recs = self.nav.getRecordings()
+ self.records_running = len(recs)
+ if self.records_running != prev_records:
+ self.updateAddon()
+
+ def scheduleAddonUpdate(self):
+ self.refreshAddon.stop()
+ self.refreshAddon.start(350)
+
+ def checkCrypto_update(self):
+ if NavigationInstance.instance is not None:
+ service = NavigationInstance.instance.getCurrentService()
+ info = service and service.info()
+ if info:
+ new_crypto = createCurrentCaidLabel(info)
+ if new_crypto != self.current_crypto:
+ self.current_crypto = new_crypto
+ self.updateAddon()
+
+ def updateAddon(self):
+ self.refreshAddon.stop()
+
+ filteredElements = []
+
+ for x in self.elements:
+ enabledKey = self.detectVisible(x) if x != "separator" else "separator"
+ if enabledKey:
+ filteredElements.append(enabledKey)
+ elif self.autoresizeMode in ["auto", "fixed"] or x in self.permanentIcons:
+ filteredElements.append(x + "!")
+
+ filteredElements = list(self.remove_doubles(filteredElements))
+
+ if filteredElements[-1] == "separator" and len(filteredElements) > 1 and filteredElements[len(filteredElements) - 2] != "currentCrypto":
+ del filteredElements[-1]
+
+ l_list = []
+ l_list.append((filteredElements,))
+ self.l.setList(l_list)
+
+ def detectVisible(self, key):
+ if self.nav is not None:
+ service = self.nav.getCurrentService()
+ info = service and service.info()
+ isRef = isinstance(service, eServiceReference)
+ #self.current_info = info
+ if not info:
+ return None
+ video_height = None
+ video_aspect = None
+ video_height = getVideoHeight(info)
+ if key == "videoRes":
+ if video_height >= 720 and video_height < 1500:
+ return "IS_HD"
+ elif video_height >= 1500:
+ return "IS_4K"
+ else:
+ return "IS_SD"
+ elif key == "txt":
+ tpid = info.getInfo(iServiceInformation.sTXTPID)
+ if tpid > 0 and tpid < 100000:
+ return key
+ elif key == "dolby" and not isRef:
+ audio = service.audioTracks()
+ if audio:
+ n = audio.getNumberOfTracks()
+ idx = 0
+ while idx < n:
+ i = audio.getTrackInfo(idx)
+ description = StdAudioDesc(i.getDescription())
+ if description and description.split()[0] in ("AC4", "AAC+", "AC3", "AC3+", "Dolby", "DTS", "DTS-HD", "HE-AAC", "IPCM", "LPCM", "WMA Pro"):
+ return key
+ idx += 1
+ elif key == "crypt" and not isRef:
+ if info.getInfo(iServiceInformation.sIsCrypted) == 1:
+ return key
+ elif key == "audiotrack" and not isRef:
+ audio = service.audioTracks()
+ if bool(audio) and audio.getNumberOfTracks() > 1:
+ return key
+ elif key == "subtitletrack" and not isRef:
+ subtitle = service and service.subtitle()
+ subtitlelist = subtitle and subtitle.getSubtitleList()
+ if subtitlelist and len(subtitlelist) > 0:
+ return key
+ elif key == "hbbtv" and not isRef:
+ if info.getInfoString(iServiceInformation.sHBBTVUrl) != "":
+ return key
+ elif key == "subservices" and not isRef:
+ if hasActiveSubservicesForCurrentChannel(service):
+ return key
+ elif key == "stream" and not isRef:
+ if self.streamServer is None:
+ return None
+ if service.streamed() is not None and ((self.streamServer.getConnectedClients() or StreamServiceList) and True or False):
+ return key
+ elif key == "currentCrypto":
+ if not isRef:
+ self.current_crypto = createCurrentCaidLabel(info)
+ self.refreshCryptoInfo.start(1000)
+ return key
+ elif key == "record":
+ self.gotRecordEvent(None, None)
+ if self.records_running > 0:
+ return key
+ elif key == "gamma" and not isRef:
+ if info.getInfo(iServiceInformation.sGamma) == 1:
+ return "IS_HDR"
+ if info.getInfo(iServiceInformation.sGamma) == 2:
+ return "IS_HDR10"
+ if info.getInfo(iServiceInformation.sGamma) == 3:
+ return "IS_HLG"
+ return None
+
+ def buildEntry(self, sequence):
+ xPos = self.instance.size().width() if self.alignment == "right" else 0
+ yPos = 0
+
+ res = [None]
+
+ for x in sequence:
+ enabledKey = x
+ isOn = True
+ if x[-1] == "!":
+ enabledKey = enabledKey.rstrip("!")
+ isOn = False
+
+ pic = None
+ if isOn:
+ if enabledKey in self.pixmaps:
+ pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[enabledKey]))
+ else:
+ if enabledKey == "videoRes":
+ enabledKey = "IS_HD"
+ if enabledKey in self.pixmaps:
+ pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[enabledKey]))
+ if enabledKey in self.pixmapsDisabled:
+ pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmapsDisabled[enabledKey]))
+
+ if enabledKey != "separator" and enabledKey != "currentCrypto":
+ if pic:
+ pixd_size = pic.size()
+ pixd_width = pixd_size.width()
+ pixd_height = pixd_size.height()
+ pic_x_pos = (xPos - pixd_width) if self.alignment == "right" else xPos
+ pic_y_pos = yPos + (self.instance.size().height() - pixd_height) // 2
+ res.append(MultiContentEntryPixmapAlphaBlend(
+ pos=(pic_x_pos, pic_y_pos),
+ size=(pixd_width, pixd_height),
+ png=pic,
+ backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER))
+ if self.alignment == "right":
+ xPos -= pixd_width + self.spacing
+ else:
+ xPos += pixd_width + self.spacing
+ else:
+ if enabledKey == "separator":
+ res.append(MultiContentEntryText(
+ pos=(xPos - self.separatorLineThickness, yPos), size=(self.separatorLineThickness, self.instance.size().height()),
+ font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER,
+ text="",
+ color=self.separatorLineColor, color_sel=self.separatorLineColor,
+ backcolor=self.separatorLineColor, backcolor_sel=self.separatorLineColor))
+ if self.alignment == "right":
+ xPos -= self.separatorLineThickness + self.spacing
+ else:
+ xPos += self.separatorLineThickness + self.spacing
+ else:
+ textWidth = self._calcTextWidth(self.current_crypto, font=self.font, size=eSize(self.getDesktopWith() // 3, 0))
+ res.append(MultiContentEntryText(
+ pos=(xPos - textWidth, yPos - 2), size=(textWidth, self.instance.size().height()),
+ font=0, flags=RT_HALIGN_CENTER | RT_VALIGN_TOP,
+ text=self.current_crypto,
+ color=self.foreColor, color_sel=self.foreColor,
+ backcolor=None, backcolor_sel=None))
+ if self.alignment == "right":
+ xPos -= textWidth + self.spacing
+ else:
+ xPos += textWidth + self.spacing
+ return res
+
+ def getDesktopWith(self):
+ return getDesktop(0).size().width()
+
+ def _calcTextWidth(self, text, font=None, size=None):
+ if size:
+ self.textRenderer.instance.resize(size)
+ if font:
+ self.textRenderer.instance.setFont(font)
+ self.textRenderer.text = text
+ return self.textRenderer.instance.calculateSize().width()
+
+ def postWidgetCreate(self, instance):
+ instance.setSelectionEnable(False)
+ instance.setContent(self.l)
+ instance.allowNativeKeys(False)
+
+ def applySkin(self, desktop, parent):
+ attribs = []
+ for (attrib, value) in self.skinAttributes[:]:
+ if attrib == "pixmaps":
+ self.pixmaps = dict(item.split(':') for item in value.split(','))
+ if attrib == "pixmapsDisabled":
+ self.pixmapsDisabled = dict(item.split(':') for item in value.split(','))
+ elif attrib == "spacing":
+ self.spacing = parseScale(value)
+ elif attrib == "alignment":
+ self.alignment = value
+ elif attrib == "orientation":
+ self.orientation = self.orientations.get(value, self.orientations["orHorizontal"])
+ if self.orientation == eListbox.orHorizontal:
+ self.instance.setOrientation(eListbox.orVertical)
+ self.l.setOrientation(eListbox.orVertical)
+ else:
+ self.instance.setOrientation(eListbox.orHorizontal)
+ self.l.setOrientation(eListbox.orHorizontal)
+ elif attrib == "elements":
+ self.elements = value.split(",")
+ elif attrib == "separatorLineColor":
+ self.foreColor = parseColor(value).argb()
+ elif attrib == "separatorLineThickness":
+ self.separatorLineThickness = parseScale(value)
+ elif attrib == "autoresizeMode":
+ self.autoresizeMode = value
+ elif attrib == "font":
+ self.font = parseFont(value, ((1, 1), (1, 1)))
+ elif attrib == "foregroundColor":
+ self.foreColor = parseColor(value).argb()
+ elif attrib == "permanent":
+ self.permanentIcons = value.split(",")
+ else:
+ attribs.append((attrib, value))
+ self.skinAttributes = attribs
+ self.l.setFont(0, self.font)
+ return GUIAddon.applySkin(self, desktop, parent)
diff --git a/lib/python/Components/Converter/CryptoInfo.py b/lib/python/Components/Converter/CryptoInfo.py
index 09f2af7136..688f772235 100644
--- a/lib/python/Components/Converter/CryptoInfo.py
+++ b/lib/python/Components/Converter/CryptoInfo.py
@@ -77,15 +77,15 @@ def getText(self):
textvalue = "%s - %s (Caid: %s, Prov: %s,)" % (source, caid, caid, prov)
#new oscam ecm.info with port parametr
elif reader != "" and source == "net" and port != "":
- textvalue = "%s - Caid: %s, Prov: %s, Reader: %s, %s (%s:%s) - %s" % (source, caid, prov, reader, protocol, server, port, ecm_time.replace('msec','ms'))
+ textvalue = "%s - Caid: %s, Prov: %s, Reader: %s, %s (%s:%s@%s) - %s" % (source, caid, prov, reader, protocol, server, port, hops, ecm_time.replace('msec', 'ms'))
elif reader != "" and source == "net":
- textvalue = "%s - Caid: %s, Prov: %s, Reader: %s, %s (%s) - %s" % (source, caid, prov, reader, protocol, server, ecm_time.replace('msec','ms'))
+ textvalue = "%s - Caid: %s, Prov: %s, Reader: %s, %s (%s@%s) - %s" % (source, caid, prov, reader, protocol, server, hops, ecm_time.replace('msec', 'ms'))
elif reader != "" and source != "net":
- textvalue = "%s - Caid: %s, Prov: %s, Reader: %s, %s (local) - %s" % (source, caid, prov, reader, protocol, ecm_time.replace('msec','ms'))
+ textvalue = "%s - Caid: %s, Prov: %s, Reader: %s, %s (local) - %s" % (source, caid, prov, reader, protocol, ecm_time.replace('msec', 'ms'))
elif server == "" and port == "" and protocol != "":
- textvalue = "%s - Caid: %s, Prov: %s, %s - %s" % (source, caid, prov, protocol, ecm_time.replace('msec','ms'))
+ textvalue = "%s - Caid: %s, Prov: %s, %s - %s" % (source, caid, prov, protocol, ecm_time.replace('msec', 'ms'))
elif server == "" and port == "" and protocol == "":
- textvalue = "%s - Caid: %s - %s, Prov: %s" % (source, prov, caid, ecm_time.replace('msec','ms'))
+ textvalue = "%s - Caid: %s - %s, Prov: %s" % (source, prov, caid, ecm_time.replace('msec', 'ms'))
else:
try:
textvalue = "%s - Caid: %s, Prov: %s, %s (%s:%s) - %s" % (source, caid, prov, protocol, server, port, ecm_time.replace('msec','ms'))
diff --git a/lib/python/Components/Converter/EventName.py b/lib/python/Components/Converter/EventName.py
index acc0dc7f38..31519ca797 100644
--- a/lib/python/Components/Converter/EventName.py
+++ b/lib/python/Components/Converter/EventName.py
@@ -22,6 +22,7 @@ class EventName(Converter):
PDCTIMESHORT = 12
ISRUNNINGSTATUS = 13
FORMAT_STRING = 14
+ RAWRATING = 15
def __init__(self, type):
Converter.__init__(self, type)
@@ -56,6 +57,8 @@ def __init__(self, type):
self.type = self.PDCTIMESHORT
elif type == "IsRunningStatus":
self.type = self.ISRUNNINGSTATUS
+ elif type == "RawRating":
+ self.type = self.RAWRATING
else:
self.type = self.NAME
@@ -159,6 +162,10 @@ def getText(self):
return _("reserved for future use")
return _("undefined")
return ""
+ elif self.type == self.RAWRATING:
+ rating = event.getParentalData()
+ if rating:
+ return "%d" % rating.getRating()
elif self.type == self.FORMAT_STRING:
begin = event.getBeginTime()
end = begin + event.getDuration()
diff --git a/lib/python/Components/Converter/HddState.py b/lib/python/Components/Converter/HddState.py
index 418927d77c..23c9cc59ac 100644
--- a/lib/python/Components/Converter/HddState.py
+++ b/lib/python/Components/Converter/HddState.py
@@ -2,7 +2,7 @@
from Components.Element import cached
from Components.Harddisk import harddiskmanager
from Components.config import config
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from skin import parameters
from enigma import eTimer
@@ -100,8 +100,8 @@ def updateHddState(self, force=False):
string = _("Disk state: ") + string
self.state_text = string
if prev_state != self.isActive or force:
- if SystemInfo["LCDsymbol_hdd"]:
- open(SystemInfo["LCDsymbol_hdd"], "w").write(self.isActive and "1" or "0")
+ if BoxInfo.getItem("LCDsymbol_hdd"):
+ open(BoxInfo.getItem("LCDsymbol_hdd"), "w").write(self.isActive and "1" or "0")
self.changed((self.CHANGED_ALL,))
def setStandbyTime(self, cfgElem):
diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py
index 1828a8547c..2915cab192 100644
--- a/lib/python/Components/Converter/PliExtraInfo.py
+++ b/lib/python/Components/Converter/PliExtraInfo.py
@@ -63,6 +63,31 @@ def addspace(text):
text += " "
return text
+def getCryptoInfo(info):
+ ecmdata = GetEcmInfo()
+ if info and info.getInfo(iServiceInformation.sIsCrypted) == 1:
+ data = ecmdata.getEcmData()
+ current_source = data[0]
+ current_caid = data[1]
+ current_provid = data[2]
+ current_ecmpid = data[3]
+ else:
+ current_source = ""
+ current_caid = "0"
+ current_provid = "0"
+ current_ecmpid = "0"
+ return current_source, current_caid, current_provid, current_ecmpid
+
+def createCurrentCaidLabel(info):
+ current_source, current_caid, current_provid, current_ecmpid = getCryptoInfo(info)
+ res = "---"
+ if not pathExists("/tmp/ecm.info"):
+ return "FTA"
+ for caid_entry in caid_data:
+ if int(caid_entry[0], 16) <= int(current_caid, 16) <= int(caid_entry[1], 16):
+ res = caid_entry[4]
+ return res
+
class PliExtraInfo(Poll, Converter):
def __init__(self, type):
@@ -145,7 +170,7 @@ def createCryptoBar(self, info):
res += "\c%08x" % colors[3] # white (this acts like a color "reset" for following strings
return res
-
+
def createCurrentCaidLabel(self):
res = ""
if not pathExists("/tmp/ecm.info"):
@@ -325,7 +350,7 @@ def getText(self):
return addspace(self.createCryptoBar(info)) + self.createCryptoSpecial(info)
else:
return addspace(self.createCryptoBar(info)) + addspace(self.current_source) + self.createCryptoSpecial(info)
-
+
if self.type == "CurrentCrypto":
self.getCryptoInfo(info)
return self.createCurrentCaidLabel()
diff --git a/lib/python/Components/Converter/RotorPosition.py b/lib/python/Components/Converter/RotorPosition.py
index a9f15fa737..1390e4e340 100644
--- a/lib/python/Components/Converter/RotorPosition.py
+++ b/lib/python/Components/Converter/RotorPosition.py
@@ -4,7 +4,7 @@
from Components.config import config
from Tools.Transponder import orbpos
from Components.NimManager import nimmanager
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from enigma import eDVBSatelliteEquipmentControl
@@ -23,7 +23,7 @@ def __init__(self, type):
@cached
def getText(self):
value = config.misc.showrotorposition.value
- if SystemInfo["isRotorTuner"] and value != "no":
+ if BoxInfo.getItem("isRotorTuner") and value != "no":
if value.isdigit():
nim_text = nimmanager.rotorLastPositionForNim(int(value), number=False)
if nim_text == _("undefined"):
diff --git a/lib/python/Components/Converter/ServiceInfo.py b/lib/python/Components/Converter/ServiceInfo.py
index 1294736f48..28ca54a728 100644
--- a/lib/python/Components/Converter/ServiceInfo.py
+++ b/lib/python/Components/Converter/ServiceInfo.py
@@ -47,6 +47,9 @@ def StdAudioDesc(description):
description = description.replace(orig, repl)
return description
+def getVideoHeight(info):
+ return info.getInfo(iServiceInformation.sVideoHeight)
+
class ServiceInfo(Converter):
HAS_TELETEXT = 0
diff --git a/lib/python/Components/Converter/ServiceName.py b/lib/python/Components/Converter/ServiceName.py
index aade14d4dc..7cac15f5fb 100644
--- a/lib/python/Components/Converter/ServiceName.py
+++ b/lib/python/Components/Converter/ServiceName.py
@@ -13,7 +13,8 @@ class ServiceName(Converter):
REFERENCE = 2
EDITREFERENCE = 3
NUMBER = 4
- FORMAT_STRING = 5
+ STREAM_URL = 5
+ FORMAT_STRING = 6
def __init__(self, type):
Converter.__init__(self, type)
@@ -31,6 +32,8 @@ def __init__(self, type):
self.type = self.EDITREFERENCE
elif type == "Number":
self.type = self.NUMBER
+ elif type == "StreamUrl":
+ self.type = self.STREAM_URL
else:
self.type = self.NAME
@@ -59,6 +62,17 @@ def getText(self):
elif self.type == self.NUMBER:
numservice = self.source.serviceref
return self.getNumber(numservice, info)
+ elif self.type == self.STREAM_URL:
+ srpart = "//%s:%s/" % (config.misc.softcam_streamrelay_url.getHTML(), config.misc.softcam_streamrelay_port.value)
+ if not ref:
+ refstr = info.getInfoString(iServiceInformation.sServiceref)
+ path = refstr and eServiceReference(refstr).getPath()
+ if not path.startswith("//") and path.find(srpart) == -1:
+ return path
+ else:
+ return ""
+ path = ref.getPath()
+ return "" if path.startswith("//") and path.find(srpart) == -1 else path
elif self.type == self.FORMAT_STRING:
name = self.getName(ref, info)
numservice = hasattr(self.source, "serviceref") and self.source.serviceref
diff --git a/lib/python/Components/Harddisk.py b/lib/python/Components/Harddisk.py
index a115f3ac70..88d6b13b7f 100644
--- a/lib/python/Components/Harddisk.py
+++ b/lib/python/Components/Harddisk.py
@@ -2,7 +2,7 @@
import os
import time
from Tools.CList import CList
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.Console import Console
from Tools.HardwareInfo import HardwareInfo
from boxbranding import getMachineBuild
@@ -844,8 +844,8 @@ def addHotplugPartition(self, device, physdev=None):
l = len(device)
if l and (not device[l - 1].isdigit() or (device.startswith('mmcblk') and not re.search(r"mmcblk\dp\d+", device))):
self.hdd.append(Harddisk(device, removable))
- sorted(self.hdd)
- SystemInfo["Harddisk"] = True
+ self.hdd.sort()
+ BoxInfo.setItem("Harddisk", True)
return error, blacklisted, removable, is_cdrom, partitions, medium_found
def addHotplugAudiocd(self, device, physdev=None):
@@ -864,7 +864,7 @@ def addHotplugAudiocd(self, device, physdev=None):
p = Partition(mountpoint="/media/audiocd", description=description, force_mounted=True, device=device)
self.partitions.append(p)
self.on_partition_list_change("add", p)
- SystemInfo["Harddisk"] = False
+ BoxInfo.setItem("Harddisk", False)
return error, blacklisted, removable, is_cdrom, partitions, medium_found
def removeHotplugPartition(self, device):
@@ -880,7 +880,7 @@ def removeHotplugPartition(self, device):
hdd.stop()
self.hdd.remove(hdd)
break
- SystemInfo["Harddisk"] = len(self.hdd) > 0
+ BoxInfo.setItem("Harddisk", len(self.hdd) > 0)
def HDDCount(self):
return len(self.hdd)
@@ -1088,4 +1088,4 @@ def internalHDDNotSleeping(external=False):
return state
-SystemInfo["ext4"] = isFileSystemSupported("ext4")
+BoxInfo.setItem("ext4", isFileSystemSupported("ext4"))
diff --git a/lib/python/Components/ImportChannels.py b/lib/python/Components/ImportChannels.py
index 57d59117d6..369278d742 100644
--- a/lib/python/Components/ImportChannels.py
+++ b/lib/python/Components/ImportChannels.py
@@ -86,8 +86,6 @@ def getTerrestrialRegion(self, settings):
def ImportGetFilelist(self, remote=False, *files):
result = []
for _file in files:
- # determine the type of bouquet file
- _type = 1 if _file.endswith('.tv') else 2
# read the contents of the file
try:
if remote:
@@ -95,8 +93,7 @@ def ImportGetFilelist(self, remote=False, *files):
content = self.getUrl("%s/file?file=%s/%s" % (self.url, e2path, quote(_file))).readlines()
except Exception as e:
print("[Import Channels] Exception: %s" % str(e))
- self.ImportChannelsDone(False, _("ERROR downloading file %s/%s") % (e2path, _file))
- return
+ continue
else:
with open('%s/%s' % (e2path, _file), 'r') as f:
content = f.readlines()
@@ -107,12 +104,12 @@ def ImportGetFilelist(self, remote=False, *files):
# check the contents for more bouquet files
for line in content:
- # check if it contains another bouquet reference
- r = re.match('#SERVICE 1:7:%d:0:0:0:0:0:0:0:FROM BOUQUET "(.*)" ORDER BY bouquet' % _type, line)
+# print ("[Import Channels] %s" % line)
+ # check if it contains another bouquet reference, first tv type then radio type
+ r = re.match('#SERVICE 1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "(.*)" ORDER BY bouquet', line) or re.match('#SERVICE 1:7:2:0:0:0:0:0:0:0:FROM BOUQUET "(.*)" ORDER BY bouquet', line)
if r:
# recurse
result.extend(self.ImportGetFilelist(remote, r.group(1)))
-
# add add the file itself
result.append(_file)
diff --git a/lib/python/Components/InputDevice.py b/lib/python/Components/InputDevice.py
index 3f371034ca..b3e6ddd7c0 100644
--- a/lib/python/Components/InputDevice.py
+++ b/lib/python/Components/InputDevice.py
@@ -1,4 +1,5 @@
from os import listdir, open as os_open, close as os_close, write as os_write, O_RDWR, O_NONBLOCK
+from Components.SystemInfo import BoxInfo
from fcntl import ioctl
from boxbranding import getBoxType, getBrandOEM
import struct
@@ -204,7 +205,7 @@ def setupConfigEntries(self, device):
class RcTypeControl:
def __init__(self):
- if pathExists('/proc/stb/ir/rc/type') and getBrandOEM() not in ('gigablue', 'odin', 'ini', 'entwopia', 'tripledot'):
+ if BoxInfo.getItem("RcTypeChangable") and pathExists('/proc/stb/info/boxtype'):
self.isSupported = True
if config.plugins.remotecontroltype.rctype.value != 0:
diff --git a/lib/python/Components/Lcd.py b/lib/python/Components/Lcd.py
index 287b69abc0..952e0784a4 100644
--- a/lib/python/Components/Lcd.py
+++ b/lib/python/Components/Lcd.py
@@ -1,8 +1,8 @@
from __future__ import division
from Components.config import config, ConfigSubsection, ConfigSlider, ConfigYesNo, ConfigNothing, ConfigSelection
from enigma import eDBoxLCD
-from Components.SystemInfo import SystemInfo
from Tools.Directories import fileExists
+from Components.SystemInfo import BoxInfo
from Screens.InfoBar import InfoBar
from Screens.Screen import Screen
@@ -68,7 +68,7 @@ def InitLcd():
else:
detected = eDBoxLCD.getInstance() and eDBoxLCD.getInstance().detected()
- SystemInfo["Display"] = detected
+ BoxInfo.setItem("Display", detected)
config.lcd = ConfigSubsection()
if fileExists("/proc/stb/lcd/mode"):
@@ -78,7 +78,7 @@ def InitLcd():
else:
can_lcdmodechecking = False
- SystemInfo["LCDMiniTV"] = can_lcdmodechecking
+ BoxInfo.setItem("LCDMiniTV", can_lcdmodechecking)
if detected:
ilcd = LCD()
@@ -165,50 +165,50 @@ def setLCDflipped(configElement):
config.lcd.flip = ConfigYesNo(default=False)
config.lcd.flip.addNotifier(setLCDflipped)
- if SystemInfo["LedPowerColor"]:
+ if BoxInfo.getItem("LedPowerColor"):
def setLedPowerColor(configElement):
- open(SystemInfo["LedPowerColor"], "w").write(configElement.value)
+ open(BoxInfo.getItem("LedPowerColor"), "w").write(configElement.value)
config.lcd.ledpowercolor = ConfigSelection(default="1", choices=[("0", _("off")), ("1", _("blue")), ("2", _("red")), ("3", _("violet"))])
config.lcd.ledpowercolor.addNotifier(setLedPowerColor)
- if SystemInfo["LedStandbyColor"]:
+ if BoxInfo.getItem("LedStandbyColor"):
def setLedStandbyColor(configElement):
- open(SystemInfo["LedStandbyColor"], "w").write(configElement.value)
+ open(BoxInfo.getItem("LedStandbyColor"), "w").write(configElement.value)
config.lcd.ledstandbycolor = ConfigSelection(default="3", choices=[("0", _("off")), ("1", _("blue")), ("2", _("red")), ("3", _("violet"))])
config.lcd.ledstandbycolor.addNotifier(setLedStandbyColor)
- if SystemInfo["LedSuspendColor"]:
+ if BoxInfo.getItem("LedSuspendColor"):
def setLedSuspendColor(configElement):
- open(SystemInfo["LedSuspendColor"], "w").write(configElement.value)
+ open(BoxInfo.getItem("LedSuspendColor"), "w").write(configElement.value)
config.lcd.ledsuspendcolor = ConfigSelection(default="2", choices=[("0", _("off")), ("1", _("blue")), ("2", _("red")), ("3", _("violet"))])
config.lcd.ledsuspendcolor.addNotifier(setLedSuspendColor)
- if SystemInfo["Power4x7On"]:
+ if BoxInfo.getItem("Power4x7On"):
def setPower4x7On(configElement):
- open(SystemInfo["Power4x7On"], "w").write(configElement.value)
+ open(BoxInfo.getItem("Power4x7On"), "w").write(configElement.value)
config.lcd.power4x7on = ConfigSelection(default="on", choices=[("off", _("Off")), ("on", _("On"))])
config.lcd.power4x7on.addNotifier(setPower4x7On)
- if SystemInfo["Power4x7Standby"]:
+ if BoxInfo.getItem("Power4x7Standby"):
def setPower4x7Standby(configElement):
- open(SystemInfo["Power4x7Standby"], "w").write(configElement.value)
+ open(BoxInfo.getItem("Power4x7Standby"), "w").write(configElement.value)
config.lcd.power4x7standby = ConfigSelection(default="on", choices=[("off", _("Off")), ("on", _("On"))])
config.lcd.power4x7standby.addNotifier(setPower4x7Standby)
- if SystemInfo["Power4x7Suspend"]:
+ if BoxInfo.getItem("Power4x7Suspend"):
def setPower4x7Suspend(configElement):
- open(SystemInfo["Power4x7Suspend"], "w").write(configElement.value)
+ open(BoxInfo.getItem("Power4x7Suspend"), "w").write(configElement.value)
config.lcd.power4x7suspend = ConfigSelection(default="off", choices=[("off", _("Off")), ("on", _("On"))])
config.lcd.power4x7suspend.addNotifier(setPower4x7Suspend)
- if SystemInfo["LcdLiveTV"]:
+ if BoxInfo.getItem("LcdLiveTV"):
def lcdLiveTvChanged(configElement):
setLCDLiveTv(configElement.value)
configElement.save()
config.lcd.showTv = ConfigYesNo(default=False)
config.lcd.showTv.addNotifier(lcdLiveTvChanged)
- if "live_enable" in SystemInfo["LcdLiveTV"]:
+ if "live_enable" in BoxInfo.getItem("LcdLiveTV"):
config.misc.standbyCounter.addNotifier(standbyCounterChangedLCDLiveTV, initial_call=False)
else:
def doNothing():
@@ -223,10 +223,10 @@ def doNothing():
def setLCDLiveTv(value):
- if "live_enable" in SystemInfo["LcdLiveTV"]:
- open(SystemInfo["LcdLiveTV"], "w").write(value and "enable" or "disable")
+ if "live_enable" in BoxInfo.getItem("LcdLiveTV"):
+ open(BoxInfo.getItem("LcdLiveTV"), "w").write(value and "enable" or "disable")
else:
- open(SystemInfo["LcdLiveTV"], "w").write(value and "0" or "1")
+ open(BoxInfo.getItem("LcdLiveTV"), "w").write(value and "0" or "1")
if not value:
try:
InfoBarInstance = InfoBar.instance
diff --git a/lib/python/Components/NimManager.py b/lib/python/Components/NimManager.py
index b06c1a4d06..eb230a0ba6 100644
--- a/lib/python/Components/NimManager.py
+++ b/lib/python/Components/NimManager.py
@@ -1,7 +1,6 @@
import os
-from .SystemInfo import SystemInfo
-from Tools.HardwareInfo import HardwareInfo
+from Components.SystemInfo import BoxInfo
from Tools.BoundFunction import boundFunction
from .config import config, ConfigSubsection, ConfigSelection, ConfigFloat, ConfigSatlist, ConfigYesNo, ConfigInteger, ConfigSubList, ConfigNothing, ConfigSubDict, ConfigOnOff, ConfigDateTime, ConfigText
@@ -116,7 +115,7 @@ def linkInternally(self, slotid):
def linkNIMs(self, sec, nim1, nim2):
print("[SecConfigure] link tuner", nim1, "to tuner", nim2)
- if (nim2 == nim1 - 1) or HardwareInfo().get_device_model() == "vusolo2":
+ if (nim2 == nim1 - 1):
self.linkInternally(nim1)
sec.setTunerLinked(nim1, nim2)
@@ -941,17 +940,12 @@ def enumerateNIMs(self):
if "i2c" not in entry:
entry["i2c"] = None
if "has_outputs" not in entry:
- entry["has_outputs"] = entry["name"] in SystemInfo["HasPhysicalLoopthrough"] # "Has_Outputs: yes" not in /proc/bus/nim_sockets NIM, but the physical loopthrough exist
+ entry["has_outputs"] = entry["name"] in BoxInfo.getItem("HasPhysicalLoopthrough") # "Has_Outputs: yes" not in /proc/bus/nim_sockets NIM, but the physical loopthrough exist
entry["internally_connectable"] = None
if "frontend_device" in entry: # check if internally connectable
if os.path.exists("/proc/stb/frontend/%d/rf_switch" % entry["frontend_device"]) and (not id or entries[id]["name"] == entries[id - 1]["name"]):
- if HardwareInfo().get_device_model() == "vusolo2":
- if not id:
- entry["internally_connectable"] = 1
- elif id:
+ if id:
entry["internally_connectable"] = entry["frontend_device"] - 1
- if HardwareInfo().get_device_model() == "vuduo2" and entry["i2c"] != entries[id - 1]["i2c"]:
- entry["internally_connectable"] = None
else:
entry["frontend_device"] = None
if "multi_type" not in entry:
@@ -962,7 +956,7 @@ def enumerateNIMs(self):
entry["supports_blind_scan"] = False
entry["fbc"] = [0, 0, 0] # not fbc
- if entry["name"] and ("fbc" in entry["name"].lower() or (entry["name"] in SystemInfo["HasFBCtuner"] and entry["frontend_device"] is not None and os.access("/proc/stb/frontend/%d/fbc_id" % entry["frontend_device"], os.F_OK))):
+ if entry["name"] and ("fbc" in entry["name"].lower() or (entry["name"] in BoxInfo.getItem("HasFBCtuner") and entry["frontend_device"] is not None and os.access("/proc/stb/frontend/%d/fbc_id" % entry["frontend_device"], os.F_OK))):
fbc_number += 1
if fbc_number <= (entry["type"] and "DVB-C" in entry["type"] and 1 or 2):
entry["fbc"] = [1, fbc_number, fbc_tuner] # fbc root
@@ -1319,7 +1313,6 @@ def InitSecParams():
def InitNimManager(nimmgr, update_slots=None):
update_slots = [] if update_slots is None else update_slots
- hw = HardwareInfo()
if not hasattr(config, "Nims"):
InitSecParams()
@@ -1422,7 +1415,7 @@ def unicableProductChanged(manufacturer, lnb_or_matrix, configEntry):
productparameters = [p for p in [list(m) for m in unicable_xml.find(lnb_or_matrix) if m.get("name") == manufacturer][0] if p.get("name") == configEntry.value][0]
section.bootuptime = ConfigInteger(default=int(productparameters.get("bootuptime", 1000)), limits=(0, 9999))
section.bootuptime.save_forced = True
- section.powerinserter = ConfigYesNo(default=SystemInfo["FbcTunerPowerAlwaysOn"])
+ section.powerinserter = ConfigYesNo(default=BoxInfo.getItem("FbcTunerPowerAlwaysOn"))
section.powerinserter.save_forced = True
section.powerinserter.addNotifier(setPowerInserter)
srcfrequencylist = productparameters.get("scrs").split(",")
@@ -1458,7 +1451,7 @@ def formatChanged(configEntry):
section.scrList.addNotifier(boundFunction(userScrListChanged, srcfrequencyList))
section.bootuptime = ConfigInteger(default=1000, limits=(0, 9999))
section.bootuptime.save_forced = True
- section.powerinserter = ConfigYesNo(default=SystemInfo["FbcTunerPowerAlwaysOn"])
+ section.powerinserter = ConfigYesNo(default=BoxInfo.getItem("FbcTunerPowerAlwaysOn"))
section.powerinserter.save_forced = True
section.powerinserter.addNotifier(setPowerInserter)
@@ -1605,7 +1598,7 @@ def createSatConfig(nim, slot_id):
nim.turningspeedH = ConfigFloat(default=[2, 3], limits=[(0, 9), (0, 9)])
nim.turningspeedV = ConfigFloat(default=[1, 7], limits=[(0, 9), (0, 9)])
nim.powerMeasurement = ConfigYesNo(True)
- nim.powerThreshold = ConfigInteger(default=hw.get_device_name() == "dm8000" and 15 or 50, limits=(0, 100))
+ nim.powerThreshold = ConfigInteger(50, limits=(0, 100))
nim.turningSpeed = ConfigSelection(turning_speed_choices, "fast")
btime = datetime(1970, 1, 1, 7, 0)
nim.fastTurningBegin = ConfigDateTime(default=mktime(btime.timetuple()), formatstring=_("%H:%M"), increment=900)
diff --git a/lib/python/Components/RFmod.py b/lib/python/Components/RFmod.py
index 90882e3682..a664260624 100644
--- a/lib/python/Components/RFmod.py
+++ b/lib/python/Components/RFmod.py
@@ -1,6 +1,6 @@
from Components.config import config, ConfigSelection, ConfigSubsection, ConfigOnOff, ConfigSlider, ConfigNothing
from enigma import eRFmod
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
# CHECK ME.
RFMOD_CHANNEL_MIN = 21
@@ -32,7 +32,7 @@ def setFinetune(self, value):
def InitRFmod():
detected = eRFmod.getInstance().detected()
- SystemInfo["RfModulator"] = detected
+ BoxInfo.setItem("RfModulator", detected)
config.rfmod = ConfigSubsection()
if detected:
config.rfmod.enable = ConfigOnOff(default=False)
diff --git a/lib/python/Components/Renderer/CiModuleControl.py b/lib/python/Components/Renderer/CiModuleControl.py
index 3190e62123..4a9ad888c7 100644
--- a/lib/python/Components/Renderer/CiModuleControl.py
+++ b/lib/python/Components/Renderer/CiModuleControl.py
@@ -1,7 +1,7 @@
from Components.Renderer.Renderer import Renderer
from enigma import eDVBCI_UI, eLabel, iPlayableService
from skin import parameters
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.VariableText import VariableText
from os import popen
@@ -34,7 +34,7 @@ def ciModuleStateChanged(self, slot):
def changed(self, what):
if what == True or what[0] == self.CHANGED_SPECIFIC and what[1] == iPlayableService.evStart:
string = ""
- NUM_CI = SystemInfo["CommonInterface"]
+ NUM_CI = BoxInfo.getItem("CommonInterface")
if NUM_CI and NUM_CI > 0:
if self.eDVBCIUIInstance:
for slot in range(NUM_CI):
diff --git a/lib/python/Components/Renderer/Makefile.am b/lib/python/Components/Renderer/Makefile.am
index fc716ecaf4..9d9d710e3e 100644
--- a/lib/python/Components/Renderer/Makefile.am
+++ b/lib/python/Components/Renderer/Makefile.am
@@ -4,4 +4,4 @@ install_PYTHON = \
__init__.py Label.py Progress.py Listbox.py Renderer.py RunningText.py Pixmap.py PiconX.py OMMetrixWeatherWidget.py \
FixedLabel.py PositionGauge.py Canvas.py CiModuleControl.py OMaClockLcd.py Picon.py Pig.py PiconLCD.py \
FrontpanelLed.py ChannelNumber.py VideoSize.py Volume2Text.py NextEpgInfo.py NextEvents.py OMNextEvent.py Cover.py GaugeRender.py pstrRndr.py \
- AudioIcon.py VolumeText.py
+ AudioIcon.py VolumeText.py RatingIcon.py
diff --git a/lib/python/Components/Renderer/PiconLCD.py b/lib/python/Components/Renderer/PiconLCD.py
index ef66dfe6c4..f89a47c227 100644
--- a/lib/python/Components/Renderer/PiconLCD.py
+++ b/lib/python/Components/Renderer/PiconLCD.py
@@ -117,7 +117,7 @@ def __init__(self):
self.piconsize = (0, 0)
self.pngname = ""
self.lastPath = None
- if getBoxType() in ('vuultimo', 'et10000', 'mutant2400', 'xpeedlx3', 'quadbox2400', 'sezammarvel', 'atemionemesis', 'mbultra', 'beyonwizt4', 'dm7020hd', 'dm7080') and not SystemInfo["grautec"]:
+ if getBoxType() in ('vuultimo', 'et10000', 'mutant2400', 'xpeedlx3', 'quadbox2400', 'sezammarvel', 'atemionemesis', 'mbultra', 'beyonwizt4', 'dm7020hd', 'dm7080') and not BoxInfo.getItem("grautec"):
pngname = findLcdPicon("lcd_picon_default")
else:
pngname = findLcdPicon("picon_default")
diff --git a/lib/python/Components/Renderer/RatingIcon.py b/lib/python/Components/Renderer/RatingIcon.py
new file mode 100644
index 0000000000..e4a1289e8c
--- /dev/null
+++ b/lib/python/Components/Renderer/RatingIcon.py
@@ -0,0 +1,48 @@
+from Components.Renderer.Renderer import Renderer
+from Tools.Directories import SCOPE_GUISKIN, resolveFilename
+
+from enigma import ePixmap
+
+
+class RatingIcon(Renderer):
+ def __init__(self):
+ Renderer.__init__(self)
+ self.small = 0
+
+ GUI_WIDGET = ePixmap
+
+ def postWidgetCreate(self, instance):
+ self.changed((self.CHANGED_DEFAULT,))
+
+ def applySkin(self, desktop, parent):
+ attribs = self.skinAttributes[:]
+ for (attrib, value) in self.skinAttributes:
+ if attrib == "small":
+ if value == "1":
+ self.small = 1
+ self.skinAttributes = attribs
+ rc = Renderer.applySkin(self, desktop, parent)
+ self.changed((self.CHANGED_DEFAULT,))
+ return rc
+
+ def changed(self, what):
+ if self.source and hasattr(self.source, "text") and self.instance:
+ if what[0] == self.CHANGED_CLEAR:
+ self.instance.setPixmap(None)
+ else:
+ if self.source.text:
+ age = int(self.source.text.replace("+", ""))
+ if age == 0:
+ self.instance.setPixmap(None)
+ self.instance.hide()
+ return
+ if age <= 15:
+ age += 3
+
+ pngEnding = "ratings/%d%s.png" % (age, "_s" if self.small else "" )
+ print(pngEnding)
+ pngname = resolveFilename(SCOPE_GUISKIN, pngEnding)
+ self.instance.setPixmapFromFile(pngname)
+ self.instance.show()
+ else:
+ self.instance.setPixmap(None)
diff --git a/lib/python/Components/SelectionList.py b/lib/python/Components/SelectionList.py
index 0e31343e2f..b3a7e265c3 100644
--- a/lib/python/Components/SelectionList.py
+++ b/lib/python/Components/SelectionList.py
@@ -5,8 +5,8 @@
from skin import applySkinFactor, fonts, parameters
-def SelectionEntryComponent(description, value, index, selected):
- dx, dy, dw, dh = parameters.get("SelectionListDescr", applySkinFactor(25, 3, 650, 30))
+def SelectionEntryComponent(description, value, index, selected, selectionListDescr=parameters.get("SelectionListDescr", applySkinFactor(25, 3, 650, 30))):
+ dx, dy, dw, dh = selectionListDescr
res = [
(description, value, index, selected),
(eListboxPythonMultiContent.TYPE_TEXT, dx, dy, dw, dh, 0, RT_HALIGN_LEFT, description)
@@ -26,16 +26,17 @@ def __init__(self, list=None, enableWrapAround=False):
font = fonts.get("SelectionList", applySkinFactor("Regular", 20, 30))
self.l.setFont(0, gFont(font[0], font[1]))
self.l.setItemHeight(font[2])
+ self.selectionListDescr = parameters.get("SelectionListDescr", applySkinFactor(25, 3, 650, 30))
def addSelection(self, description, value, index, selected=True):
- self.list.append(SelectionEntryComponent(description, value, index, selected))
+ self.list.append(SelectionEntryComponent(description, value, index, selected, self.selectionListDescr))
self.setList(self.list)
def toggleSelection(self):
if len(self.list):
idx = self.getSelectedIndex()
item = self.list[idx][0]
- self.list[idx] = SelectionEntryComponent(item[0], item[1], item[2], not item[3])
+ self.list[idx] = SelectionEntryComponent(item[0], item[1], item[2], not item[3], self.selectionListDescr)
self.setList(self.list)
def getSelectionsList(self):
@@ -44,7 +45,7 @@ def getSelectionsList(self):
def toggleAllSelection(self):
for idx, item in enumerate(self.list):
item = self.list[idx][0]
- self.list[idx] = SelectionEntryComponent(item[0], item[1], item[2], not item[3])
+ self.list[idx] = SelectionEntryComponent(item[0], item[1], item[2], not item[3], self.selectionListDescr)
self.setList(self.list)
def removeSelection(self, item):
@@ -58,7 +59,7 @@ def toggleItemSelection(self, item):
for idx, i in enumerate(self.list):
if i[0][0:3] == item[0:3]:
item = self.list[idx][0]
- self.list[idx] = SelectionEntryComponent(item[0], item[1], item[2], not item[3])
+ self.list[idx] = SelectionEntryComponent(item[0], item[1], item[2], not item[3], self.selectionListDescr)
self.setList(self.list)
return
@@ -70,3 +71,23 @@ def sort(self, sortType=False, flag=False):
# 3 - selected
self.list.sort(key=lambda x: x[0][sortType], reverse=flag)
self.setList(self.list)
+
+ def applySkin(self, desktop, parent):
+
+ def selectionListDescr(value):
+ self.selectionListDescr = list(map(int, value.split(",")))
+
+ for (attrib, value) in self.skinAttributes[:]:
+ try:
+ locals().get(attrib)(value)
+ except:
+ pass
+ else:
+ self.skinAttributes.remove((attrib, value))
+
+ # recreate the list with the new parameters parsed from skin
+ for x in range(len(self.list)):
+ description, value, index, selected = self.list[x][0]
+ self.list[x] = SelectionEntryComponent(description, value, index, selected, self.selectionListDescr)
+ self.setList(self.list)
+ return MenuList.applySkin(self, desktop, parent)
diff --git a/lib/python/Components/Sources/CurrentService.py b/lib/python/Components/Sources/CurrentService.py
index a95293f5b3..f5ae4c7b64 100644
--- a/lib/python/Components/Sources/CurrentService.py
+++ b/lib/python/Components/Sources/CurrentService.py
@@ -1,5 +1,5 @@
from Components.PerServiceDisplay import PerServiceBase
-from enigma import iPlayableService
+from enigma import iPlayableService, iPlayableService
from Components.Sources.Source import Source
from Components.Element import cached
import NavigationInstance
@@ -23,13 +23,18 @@ def __init__(self, navcore):
iPlayableService.evHBBTVInfo: self.serviceEvent
}, with_event=True)
self.navcore = navcore
+ self.srv = None
+ self.info = None
+ self.onManualNewService = []
def serviceEvent(self, event):
+ self.srv = None
+ self.info = None
self.changed((self.CHANGED_SPECIFIC, event))
@cached
def getCurrentService(self):
- return self.navcore.getCurrentService()
+ return self.srv or self.navcore.getCurrentService()
def getCurrentServiceReference(self):
return self.navcore.getCurrentlyPlayingServiceReference()
@@ -39,11 +44,25 @@ def getCurrentServiceReference(self):
@cached
def getCurrentServiceRef(self):
if NavigationInstance.instance is not None:
- return NavigationInstance.instance.getCurrentlyPlayingServiceOrGroup()
+ return self.srv or NavigationInstance.instance.getCurrentlyPlayingServiceOrGroup()
return None
serviceref = property(getCurrentServiceRef)
+ def newService(self, ref):
+ if ref and isinstance(ref, bool):
+ self.srv = None
+ elif ref:
+ self.srv = ref
+ self.info = eServiceCenter.getInstance().info(ref)
+ else:
+ self.srv = ref
+
+ for x in self.onManualNewService:
+ x()
+
+ self.changed((self.CHANGED_SPECIFIC, iPlayableService.evStart))
+
def destroy(self):
PerServiceBase.destroy(self)
Source.destroy(self)
diff --git a/lib/python/Components/Sources/RecordState.py b/lib/python/Components/Sources/RecordState.py
index 155b3832a2..c92a233c49 100644
--- a/lib/python/Components/Sources/RecordState.py
+++ b/lib/python/Components/Sources/RecordState.py
@@ -1,7 +1,7 @@
from Components.Sources.Source import Source
from Components.Element import cached
from enigma import iRecordableService
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
class RecordState(Source):
@@ -16,8 +16,8 @@ def gotRecordEvent(self, service, event):
prev_records = self.records_running
if event in (iRecordableService.evEnd, iRecordableService.evStart, None):
recs = self.session.nav.getRecordings()
- if SystemInfo["LCDsymbol_circle_recording"]:
- open(SystemInfo["LCDsymbol_circle_recording"], "w").write(recs and "1" or "0")
+ if BoxInfo.getItem("LCDsymbol_circle_recording"):
+ open(BoxInfo.getItem("LCDsymbol_circle_recording"), "w").write(recs and "1" or "0")
self.records_running = len(recs)
if self.records_running != prev_records:
self.changed((self.CHANGED_ALL,))
diff --git a/lib/python/Components/Sources/StreamService.py b/lib/python/Components/Sources/StreamService.py
index 0f67db3a26..a506b9acf5 100644
--- a/lib/python/Components/Sources/StreamService.py
+++ b/lib/python/Components/Sources/StreamService.py
@@ -1,6 +1,6 @@
from Components.Sources.Source import Source
from Components.Element import cached
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from enigma import eServiceReference
StreamServiceList = []
@@ -37,7 +37,7 @@ def execBegin(self):
print("[StreamService] has no service ref set")
return
print("[StreamService]e execBegin", self.ref.toString())
- if SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"]:
+ if BoxInfo.getItem("CanNotDoSimultaneousTranscodeAndPIP"):
from Screens.InfoBar import InfoBar
if InfoBar.instance and hasattr(InfoBar.instance.session, 'pipshown') and InfoBar.instance.session.pipshown:
hasattr(InfoBar.instance, "showPiP") and InfoBar.instance.showPiP()
diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py
index 1573bcd1db..3545405872 100644
--- a/lib/python/Components/SystemInfo.py
+++ b/lib/python/Components/SystemInfo.py
@@ -141,132 +141,132 @@ def getBootdevice():
#This line makes the new BoxInfo backwards compatible with SystemInfo without duplicating the dictionary.
SystemInfo = BoxInfo.boxInfo
from Tools.Multiboot import getMultibootStartupDevice, getMultibootslots # This import needs to be here to avoid a SystemInfo load loop!
-SystemInfo["HasRootSubdir"] = False # This needs to be here so it can be reset by getMultibootslots!
-SystemInfo["RecoveryMode"] = False or fileCheck("/proc/stb/fp/boot_mode") # This needs to be here so it can be reset by getMultibootslots!
-
-model = BoxInfo.getItem("machine")
-
-
-SystemInfo["InDebugMode"] = eGetEnigmaDebugLvl() >= 4
-SystemInfo["CommonInterface"] = model in ("h9combo", "h9combose", "h10", "pulse4kmini") and 1 or eDVBCIInterfaces.getInstance().getNumOfSlots()
-SystemInfo["CommonInterfaceCIDelay"] = fileCheck("/proc/stb/tsmux/rmx_delay")
-for cislot in list(range(0, SystemInfo["CommonInterface"])):
- SystemInfo["CI%dSupportsHighBitrates" % cislot] = fileCheck("/proc/stb/tsmux/ci%d_tsclk" % cislot)
- SystemInfo["CI%dRelevantPidsRoutingSupport" % cislot] = fileCheck("/proc/stb/tsmux/ci%d_relevant_pids_routing" % cislot)
-
-SystemInfo["NumVideoDecoders"] = getNumVideoDecoders()
-SystemInfo["PIPAvailable"] = SystemInfo["NumVideoDecoders"] > 1
-SystemInfo["CanMeasureFrontendInputPower"] = eDVBResourceManager.getInstance().canMeasureFrontendInputPower()
-SystemInfo["12V_Output"] = Misc_Options.getInstance().detected_12V_output()
-SystemInfo["ZapMode"] = fileCheck("/proc/stb/video/zapmode") or fileCheck("/proc/stb/video/zapping_mode")
-SystemInfo["NumFrontpanelLEDs"] = countFrontpanelLEDs()
-SystemInfo["FrontpanelDisplay"] = fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0")
-SystemInfo["LCDsymbol_circle_recording"] = fileCheck("/proc/stb/lcd/symbol_circle") or model in ("hd51", "vs1500") and fileCheck("/proc/stb/lcd/symbol_recording")
-SystemInfo["LCDsymbol_timeshift"] = fileCheck("/proc/stb/lcd/symbol_timeshift")
-SystemInfo["LCDshow_symbols"] = (model.startswith("et9") or model in ("hd51", "vs1500")) and fileCheck("/proc/stb/lcd/show_symbols")
-SystemInfo["LCDsymbol_hdd"] = model in ("hd51", "vs1500") and fileCheck("/proc/stb/lcd/symbol_hdd")
-SystemInfo["FrontpanelDisplayGrayscale"] = fileExists("/dev/dbox/oled0")
-SystemInfo["DeepstandbySupport"] = model != "dm800"
-SystemInfo["OledDisplay"] = fileExists(resolveFilename(SCOPE_SKIN, 'display/lcd_skin/skin_lcd_default.xml'))
-SystemInfo["GBWOL"] = fileExists("/usr/bin/gigablue_wol")
-SystemInfo["Fan"] = fileCheck("/proc/stb/fp/fan")
-SystemInfo["FanPWM"] = SystemInfo["Fan"] and fileCheck("/proc/stb/fp/fan_pwm")
-SystemInfo["PowerLED"] = fileCheck("/proc/stb/power/powerled") or model in ("gbue4k", "gbquad4k") and fileCheck("/proc/stb/fp/led1_pattern")
-SystemInfo["StandbyLED"] = fileCheck("/proc/stb/power/standbyled") or model in ("gbue4k", "gbquad4k") and fileCheck("/proc/stb/fp/led0_pattern")
-SystemInfo["SuspendLED"] = fileCheck("/proc/stb/power/suspendled") or fileCheck("/proc/stb/fp/enable_led")
-SystemInfo["Display"] = SystemInfo["FrontpanelDisplay"] or SystemInfo["StandbyLED"]
-SystemInfo["LedPowerColor"] = fileCheck("/proc/stb/fp/ledpowercolor")
-SystemInfo["LedStandbyColor"] = fileCheck("/proc/stb/fp/ledstandbycolor")
-SystemInfo["LedSuspendColor"] = fileCheck("/proc/stb/fp/ledsuspendledcolor")
-SystemInfo["Power4x7On"] = fileCheck("/proc/stb/fp/power4x7on")
-SystemInfo["Power4x7Standby"] = fileCheck("/proc/stb/fp/power4x7standby")
-SystemInfo["Power4x7Suspend"] = fileCheck("/proc/stb/fp/power4x7suspend")
-SystemInfo["PowerOffDisplay"] = model not in "formuler1" and fileCheck("/proc/stb/power/vfd") or fileCheck("/proc/stb/lcd/vfd")
-SystemInfo["WakeOnLAN"] = not model.startswith("et8000") and fileCheck("/proc/stb/power/wol") or fileCheck("/proc/stb/fp/wol")
-SystemInfo["HasExternalPIP"] = not (model.startswith("et9") or model in ("e4hd",)) and fileCheck("/proc/stb/vmpeg/1/external")
-SystemInfo["VideoDestinationConfigurable"] = fileExists("/proc/stb/vmpeg/0/dst_left")
-SystemInfo["hasPIPVisibleProc"] = fileCheck("/proc/stb/vmpeg/1/visible")
-SystemInfo["VFD_scroll_repeats"] = fileCheck("/proc/stb/lcd/scroll_repeats")
-SystemInfo["VFD_scroll_delay"] = fileCheck("/proc/stb/lcd/scroll_delay")
-SystemInfo["VFD_initial_scroll_delay"] = fileCheck("/proc/stb/lcd/initial_scroll_delay")
-SystemInfo["VFD_final_scroll_delay"] = fileCheck("/proc/stb/lcd/final_scroll_delay")
-SystemInfo["hasTuners"] = getHasTuners() or isPluginInstalled("SatipClient")
-
-SystemInfo["hasGBIpboxClient"] = isPluginInstalled("GBIpboxClient")
-
-#if model in ('gbquadplus', ):
-# SystemInfo["WakeOnLAN"] = False
-#else:
-SystemInfo["WakeOnLAN"] = fileCheck("/proc/stb/fp/wol")
-
-SystemInfo["LcdLiveTV"] = fileCheck("/proc/stb/fb/sd_detach") or fileCheck("/proc/stb/lcd/live_enable")
-SystemInfo["LcdLiveTVMode"] = fileCheck("/proc/stb/lcd/mode")
-SystemInfo["LcdLiveDecoder"] = fileCheck("/proc/stb/lcd/live_decoder")
-SystemInfo["Bootvideo"] = fileCheck("/usr/bin/bootvideo")
-SystemInfo["FastChannelChange"] = False
-SystemInfo["3DMode"] = fileCheck("/proc/stb/fb/3dmode") or fileCheck("/proc/stb/fb/primary/3d")
-SystemInfo["3DZNorm"] = fileCheck("/proc/stb/fb/znorm") or fileCheck("/proc/stb/fb/primary/zoffset")
-SystemInfo["Blindscan_t2_available"] = fileCheck("/proc/stb/info/vumodel") and model.startswith("vu")
-SystemInfo["RcTypeChangable"] = not (model.startswith("et8500") or model.startswith("et7")) and pathExists("/proc/stb/ir/rc/type")
-SystemInfo["HasFullHDSkinSupport"] = model not in ("et4000", "et5000", "sh1", "hd500c", "hd1100", "xp1000", "lc")
-SystemInfo["HasBypassEdidChecking"] = fileCheck("/proc/stb/hdmi/bypass_edid_checking")
-SystemInfo["hasKexec"] = fileHas("/proc/cmdline", "kexec=1")
-SystemInfo["canKexec"] = not SystemInfo["hasKexec"] and fileExists("/usr/bin/kernel_auto.bin") and fileExists("/usr/bin/STARTUP.cpio.gz") and (model in ("vuduo4k", "vuduo4kse") and ["mmcblk0p9", "mmcblk0p6"] or model in ("vusolo4k", "vuultimo4k", "vuuno4k", "vuuno4kse") and ["mmcblk0p4", "mmcblk0p1"] or model == "vuzero4k" and ["mmcblk0p7", "mmcblk0p4"])
-SystemInfo["MultibootStartupDevice"] = getMultibootStartupDevice()
-SystemInfo["canMode12"] = "%s_4.boxmode" % model in cmdline and cmdline["%s_4.boxmode" % model] in ("1", "12") and "192M"
-SystemInfo["canMultiBoot"] = getMultibootslots()
-SystemInfo["HasMMC"] = fileHas("/proc/cmdline", "root=/dev/mmcblk") or SystemInfo["canMultiBoot"] and fileHas("/proc/cmdline", "root=/dev/sda")
-SystemInfo["HasColorspace"] = fileCheck("/proc/stb/video/hdmi_colorspace")
-SystemInfo["HasColorspaceSimple"] = SystemInfo["HasColorspace"] and SystemInfo["HasMMC"] and SystemInfo["Blindscan_t2_available"]
-SystemInfo["HasTranscoding"] = pathExists("/proc/stb/encoder/0") or fileCheck("/dev/bcm_enc0")
-SystemInfo["HasH265Encoder"] = fileHas("/proc/stb/encoder/0/vcodec_choices", "h265")
-SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"] = model in ("vusolo4k", "gbquad4k", "gbue4k")
-SystemInfo["HasColordepth"] = fileCheck("/proc/stb/video/hdmi_colordepth")
-SystemInfo["HasFrontDisplayPicon"] = model in ("et8500", "vusolo4k", "vuuno4kse", "vuduo4k", "vuduo4kse", "vuultimo4k", "gbquad4k", "gbue4k")
-SystemInfo["Has24hz"] = fileCheck("/proc/stb/video/videomode_24hz")
-SystemInfo["Has2160p"] = fileHas("/proc/stb/video/videomode_preferred", "2160p50")
-SystemInfo["HasHDMIpreemphasis"] = fileCheck("/proc/stb/hdmi/preemphasis")
-SystemInfo["HasColorimetry"] = fileCheck("/proc/stb/video/hdmi_colorimetry")
-SystemInfo["HasHdrType"] = fileCheck("/proc/stb/video/hdmi_hdrtype")
-SystemInfo["HasScaler_sharpness"] = pathExists("/proc/stb/vmpeg/0/pep_scaler_sharpness")
-SystemInfo["HasHDMIin"] = BoxInfo.getItem("dmifhdin") or BoxInfo.getItem("hdmihdin")
-SystemInfo["HasHDMI-CEC"] = BoxInfo.getItem("hdmi") and isPluginInstalled("HdmiCEC") and (fileExists("/dev/cec0") or fileExists("/dev/hdmi_cec") or fileExists("/dev/misc/hdmi_cec0"))
-SystemInfo["HasYPbPr"] = model in ("dm8000", "et5000", "et6000", "et6500", "et9000", "et9200", "et9500", "et10000", "formuler1", "mbtwinplus", "spycat", "vusolo", "vuduo", "vuduo2", "vuultimo") or getMachineBuild() in ('gb7356', 'gb7325') or model in ('gbultraue', 'gbultraueh', 'gb800ueplus', 'gb800seplus')
-SystemInfo["HasScart"] = model in ("dm8000", "et4000", "et6500", "et8000", "et9000", "et9200", "et9500", "et10000", "formuler1", "hd1100", "hd1200", "hd1265", "hd2400", "vusolo", "vusolo2", "vuduo", "vuduo2", "vuultimo", "vuuno", "xp1000") or getMachineBuild() in ('gb7325', )
-SystemInfo["HasSVideo"] = model in ("dm8000")
-SystemInfo["HasComposite"] = model not in ("i55", "gbquad4k", "gbue4k", "hd1500", "osnino", "osninoplus", "purehd", "purehdse", "revo4k", "vusolo4k", "vuzero4k", "vuduo4k", "vuduo4kse", "vuuno4k", "vuuno4kse", "vuultimo4k")
-SystemInfo["hasXcoreVFD"] = model in ("osmega", "spycat4k", "spycat4kmini", "spycat4kcombo") and fileCheck("/sys/module/brcmstb_%s/parameters/pt6302_cgram" % model)
-SystemInfo["HasOfflineDecoding"] = model not in ("osmini", "osminiplus", "et7000mini", "et11000", "mbmicro", "mbtwinplus", "mbmicrov2", "et7000", "et8500")
-SystemInfo["canDualBoot"] = fileExists("/dev/block/by-name/flag")
-SystemInfo["canFlashWithOfgwrite"] = not (model.startswith("dm"))
-SystemInfo["HDRSupport"] = fileExists("/proc/stb/hdmi/hlg_support_choices") and fileCheck("/proc/stb/hdmi/hlg_support")
-SystemInfo["CanProc"] = SystemInfo["HasMMC"] and not SystemInfo["Blindscan_t2_available"]
-SystemInfo["HasMultichannelPCM"] = fileCheck("/proc/stb/audio/multichannel_pcm")
-SystemInfo["HasAutoVolume"] = fileExists("/proc/stb/audio/avl_choices") and fileCheck("/proc/stb/audio/avl")
-SystemInfo["HasAutoVolumeLevel"] = fileExists("/proc/stb/audio/autovolumelevel_choices") and fileCheck("/proc/stb/audio/autovolumelevel")
-SystemInfo["Has3DSurround"] = fileExists("/proc/stb/audio/3d_surround_choices") and fileCheck("/proc/stb/audio/3d_surround")
-SystemInfo["Has3DSpeaker"] = fileExists("/proc/stb/audio/3d_surround_speaker_position_choices") and fileCheck("/proc/stb/audio/3d_surround_speaker_position")
-SystemInfo["Has3DSurroundSpeaker"] = fileExists("/proc/stb/audio/3dsurround_choices") and fileCheck("/proc/stb/audio/3dsurround")
-SystemInfo["Has3DSurroundSoftLimiter"] = fileExists("/proc/stb/audio/3dsurround_softlimiter_choices") and fileCheck("/proc/stb/audio/3dsurround_softlimiter")
-SystemInfo["HasHDMI-In"] = model in ('gbquad4k', )
-SystemInfo["CanDownmixAC3"] = fileHas("/proc/stb/audio/ac3_choices", "downmix")
-SystemInfo["CanDownmixDTS"] = fileHas("/proc/stb/audio/dts_choices", "downmix")
-SystemInfo["CanDownmixAAC"] = fileHas("/proc/stb/audio/aac_choices", "downmix")
-SystemInfo["HDMIAudioSource"] = fileCheck("/proc/stb/hdmi/audio_source")
-SystemInfo["HAScmdline"] = fileCheck("/boot/cmdline.txt")
-SystemInfo["HasSDmmc"] = SystemInfo["canMultiBoot"] and "sd" in SystemInfo["canMultiBoot"][2] and "mmcblk" in getMachineMtdRoot()
-SystemInfo["canRecovery"] = getMachineBuild() in ('gbmv200',) and ('usb_update.bin', 'none')
-SystemInfo["CanAC3Transcode"] = fileHas("/proc/stb/audio/ac3plus_choices", "force_ac3")
-SystemInfo["CanDTSHD"] = fileHas("/proc/stb/audio/dtshd_choices", "downmix")
-SystemInfo["CanDownmixAACPlus"] = fileHas("/proc/stb/audio/aacplus_choices", "downmix")
-SystemInfo["CanAACTranscode"] = fileHas("/proc/stb/audio/aac_transcode_choices", "off")
-SystemInfo["CanWMAPRO"] = fileHas("/proc/stb/audio/wmapro_choices", "downmix")
-SystemInfo["CanBTAudio"] = fileHas("/proc/stb/audio/btaudio_choices", "off")
-SystemInfo["CanBTAudioDelay"] = fileCheck("/proc/stb/audio/btaudio_delay") or fileCheck("/proc/stb/audio/btaudio_delay_pcm")
-SystemInfo["BootDevice"] = getBootdevice()
-SystemInfo["FbcTunerPowerAlwaysOn"] = model in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse")
-SystemInfo["HasPhysicalLoopthrough"] = ["Vuplus DVB-S NIM(AVL2108)", "GIGA DVB-S2 NIM (Internal)"]
-SystemInfo["HasFBCtuner"] = ["Vuplus DVB-C NIM(BCM3158)", "Vuplus DVB-C NIM(BCM3148)", "Vuplus DVB-S NIM(7376 FBC)", "Vuplus DVB-S NIM(45308X FBC)", "Vuplus DVB-S NIM(45208 FBC)", "DVB-S2 NIM(45208 FBC)", "DVB-S2X NIM(45308X FBC)", "DVB-S2 NIM(45308 FBC)", "DVB-C NIM(3128 FBC)", "BCM45208", "BCM45308X", "BCM3158"]
-SystemInfo["HasHiSi"] = pathExists("/proc/hisi")
-SystemInfo["FCCactive"] = False
-SystemInfo["Autoresolution_proc_videomode"] = model in ("gbue4k", "gbquad4k") and "/proc/stb/video/videomode_50hz" or "/proc/stb/video/videomode"
+BoxInfo.setItem("HasRootSubdir", False) # This needs to be here so it can be reset by getMultibootslots!
+BoxInfo.setItem("RecoveryMode", False or fileCheck("/proc/stb/fp/boot_mode")) # This needs to be here so it can be reset by getMultibootslots!
+
+
+def setBoxInfoItems():
+ model = BoxInfo.getItem("machine")
+ BoxInfo.setItem("InDebugMode", eGetEnigmaDebugLvl() >= 4)
+ BoxInfo.setItem("CommonInterface", model in ("h9combo", "h9combose", "h10", "pulse4kmini") and 1 or eDVBCIInterfaces.getInstance().getNumOfSlots())
+ BoxInfo.setItem("CommonInterfaceCIDelay", fileCheck("/proc/stb/tsmux/rmx_delay"))
+ for cislot in range(0, BoxInfo.getItem("CommonInterface")):
+ BoxInfo.setItem("CI%dSupportsHighBitrates" % cislot, fileCheck("/proc/stb/tsmux/ci%d_tsclk" % cislot))
+ BoxInfo.setItem("CI%dRelevantPidsRoutingSupport" % cislot, fileCheck("/proc/stb/tsmux/ci%d_relevant_pids_routing" % cislot))
+
+ BoxInfo.setItem("NumVideoDecoders", getNumVideoDecoders())
+ BoxInfo.setItem("PIPAvailable", BoxInfo.getItem("NumVideoDecoders") > 1)
+ BoxInfo.setItem("CanMeasureFrontendInputPower", eDVBResourceManager.getInstance().canMeasureFrontendInputPower())
+ BoxInfo.setItem("12V_Output", Misc_Options.getInstance().detected_12V_output())
+ BoxInfo.setItem("ZapMode", fileCheck("/proc/stb/video/zapmode") or fileCheck("/proc/stb/video/zapping_mode"))
+ BoxInfo.setItem("NumFrontpanelLEDs", countFrontpanelLEDs())
+ BoxInfo.setItem("FrontpanelDisplay", fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0"))
+ BoxInfo.setItem("LCDsymbol_circle_recording", fileCheck("/proc/stb/lcd/symbol_circle") or model in ("hd51", "vs1500") and fileCheck("/proc/stb/lcd/symbol_recording"))
+ BoxInfo.setItem("LCDsymbol_timeshift", fileCheck("/proc/stb/lcd/symbol_timeshift"))
+ BoxInfo.setItem("LCDshow_symbols", (model.startswith("et9") or model in ("hd51", "vs1500")) and fileCheck("/proc/stb/lcd/show_symbols"))
+ BoxInfo.setItem("LCDsymbol_hdd", model in ("hd51", "vs1500") and fileCheck("/proc/stb/lcd/symbol_hdd"))
+ BoxInfo.setItem("FrontpanelDisplayGrayscale", fileExists("/dev/dbox/oled0"))
+ BoxInfo.setItem("DeepstandbySupport", model != "dm800")
+ BoxInfo.setItem("OledDisplay", fileExists(resolveFilename(SCOPE_SKIN, 'display/lcd_skin/skin_lcd_default.xml')))
+ BoxInfo.setItem("GBWOL", fileExists("/usr/bin/gigablue_wol"))
+ BoxInfo.setItem("Fan", fileCheck("/proc/stb/fp/fan"))
+ BoxInfo.setItem("FanPWM", BoxInfo.getItem("Fan") and fileCheck("/proc/stb/fp/fan_pwm"))
+ BoxInfo.setItem("PowerLED", fileCheck("/proc/stb/power/powerled") or model in ("gbue4k", "gbquad4k") and fileCheck("/proc/stb/fp/led1_pattern"))
+ BoxInfo.setItem("StandbyLED", fileCheck("/proc/stb/power/standbyled") or model in ("gbue4k", "gbquad4k") and fileCheck("/proc/stb/fp/led0_pattern"))
+ BoxInfo.setItem("SuspendLED", fileCheck("/proc/stb/power/suspendled") or fileCheck("/proc/stb/fp/enable_led"))
+ BoxInfo.setItem("Display", BoxInfo.getItem("FrontpanelDisplay") or BoxInfo.getItem("StandbyLED"))
+ BoxInfo.setItem("LedPowerColor", fileCheck("/proc/stb/fp/ledpowercolor"))
+ BoxInfo.setItem("LedStandbyColor", fileCheck("/proc/stb/fp/ledstandbycolor"))
+ BoxInfo.setItem("LedSuspendColor", fileCheck("/proc/stb/fp/ledsuspendledcolor"))
+ BoxInfo.setItem("Power4x7On", fileCheck("/proc/stb/fp/power4x7on"))
+ BoxInfo.setItem("Power4x7Standby", fileCheck("/proc/stb/fp/power4x7standby"))
+ BoxInfo.setItem("Power4x7Suspend", fileCheck("/proc/stb/fp/power4x7suspend"))
+ BoxInfo.setItem("PowerOffDisplay", model not in "formuler1" and fileCheck("/proc/stb/power/vfd") or fileCheck("/proc/stb/lcd/vfd"))
+ BoxInfo.setItem("WakeOnLAN", not model.startswith("et8000") and fileCheck("/proc/stb/power/wol") or fileCheck("/proc/stb/fp/wol"))
+ BoxInfo.setItem("HasExternalPIP", not (model.startswith("et9") or model in ("e4hd",)) and fileCheck("/proc/stb/vmpeg/1/external"))
+ BoxInfo.setItem("VideoDestinationConfigurable", fileExists("/proc/stb/vmpeg/0/dst_left"))
+ BoxInfo.setItem("hasPIPVisibleProc", fileCheck("/proc/stb/vmpeg/1/visible"))
+ BoxInfo.setItem("VFD_scroll_repeats", fileCheck("/proc/stb/lcd/scroll_repeats"))
+ BoxInfo.setItem("VFD_scroll_delay", fileCheck("/proc/stb/lcd/scroll_delay"))
+ BoxInfo.setItem("VFD_initial_scroll_delay", fileCheck("/proc/stb/lcd/initial_scroll_delay"))
+ BoxInfo.setItem("VFD_final_scroll_delay", fileCheck("/proc/stb/lcd/final_scroll_delay"))
+ BoxInfo.setItem("hasTuners", getHasTuners() or isPluginInstalled("SatipClient"))
+
+ BoxInfo.setItem("hasGBIpboxClient", isPluginInstalled("GBIpboxClient"))
+
+ BoxInfo.setItem("WakeOnLAN", fileCheck("/proc/stb/fp/wol"))
+
+ BoxInfo.setItem("LcdLiveTV", fileCheck("/proc/stb/fb/sd_detach") or fileCheck("/proc/stb/lcd/live_enable"))
+ BoxInfo.setItem("LcdLiveTVMode", fileCheck("/proc/stb/lcd/mode"))
+ BoxInfo.setItem("LcdLiveDecoder", fileCheck("/proc/stb/lcd/live_decoder"))
+ BoxInfo.setItem("Bootvideo", fileCheck("/usr/bin/bootvideo"))
+ BoxInfo.setItem("FastChannelChange", False)
+ BoxInfo.setItem("3DMode", fileCheck("/proc/stb/fb/3dmode") or fileCheck("/proc/stb/fb/primary/3d"))
+ BoxInfo.setItem("3DZNorm", fileCheck("/proc/stb/fb/znorm") or fileCheck("/proc/stb/fb/primary/zoffset"))
+ BoxInfo.setItem("Blindscan_t2_available", fileCheck("/proc/stb/info/vumodel") and model.startswith("vu"))
+ BoxInfo.setItem("RcTypeChangable", not (model.startswith("et8500") or model.startswith("et7")) and pathExists("/proc/stb/ir/rc/type"))
+ BoxInfo.setItem("HasFullHDSkinSupport", model not in ("et4000", "et5000", "sh1", "hd500c", "hd1100", "xp1000", "lc"))
+ BoxInfo.setItem("HasBypassEdidChecking", fileCheck("/proc/stb/hdmi/bypass_edid_checking"))
+ BoxInfo.setItem("hasKexec", fileHas("/proc/cmdline", "kexec=1"))
+ BoxInfo.setItem("canKexec", not BoxInfo.getItem("hasKexec") and fileExists("/usr/bin/kernel_auto.bin") and fileExists("/usr/bin/STARTUP.cpio.gz") and (model in ("vuduo4k", "vuduo4kse") and ["mmcblk0p9", "mmcblk0p6"] or model in ("vusolo4k", "vuultimo4k", "vuuno4k", "vuuno4kse") and ["mmcblk0p4", "mmcblk0p1"] or model == "vuzero4k" and ["mmcblk0p7", "mmcblk0p4"]))
+ BoxInfo.setItem("MultibootStartupDevice", getMultibootStartupDevice())
+ BoxInfo.setItem("canMode12", "%s_4.boxmode" % model in cmdline and cmdline["%s_4.boxmode" % model] in ("1", "12") and "192M")
+ BoxInfo.setItem("canMultiBoot", getMultibootslots())
+ BoxInfo.setItem("HasMMC", "root" in cmdline and cmdline["root"].startswith("/dev/mmcblk") or BoxInfo.getItem("canMultiBoot") and fileHas("/proc/cmdline", "root=/dev/sda"))
+ BoxInfo.setItem("HasColorspace", fileCheck("/proc/stb/video/hdmi_colorspace"))
+ BoxInfo.setItem("HasColorspaceSimple", BoxInfo.getItem("HasColorspace") and BoxInfo.getItem("HasMMC") and BoxInfo.getItem("Blindscan_t2_available"))
+ BoxInfo.setItem("HasTranscoding", pathExists("/proc/stb/encoder/0") or fileCheck("/dev/bcm_enc0"))
+ BoxInfo.setItem("HasH265Encoder", fileHas("/proc/stb/encoder/0/vcodec_choices", "h265"))
+ BoxInfo.setItem("CanNotDoSimultaneousTranscodeAndPIP", model in ("vusolo4k", "gbquad4k", "gbue4k"))
+ BoxInfo.setItem("HasColordepth", fileCheck("/proc/stb/video/hdmi_colordepth"))
+ BoxInfo.setItem("HasFrontDisplayPicon", model in ("et8500", "vusolo4k", "vuuno4kse", "vuduo4k", "vuduo4kse", "vuultimo4k", "gbquad4k", "gbue4k"))
+ BoxInfo.setItem("Has24hz", fileCheck("/proc/stb/video/videomode_24hz"))
+ BoxInfo.setItem("Has2160p", fileHas("/proc/stb/video/videomode_preferred", "2160p50"))
+ BoxInfo.setItem("HasHDMIpreemphasis", fileCheck("/proc/stb/hdmi/preemphasis"))
+ BoxInfo.setItem("HasColorimetry", fileCheck("/proc/stb/video/hdmi_colorimetry"))
+ BoxInfo.setItem("HasHdrType", fileCheck("/proc/stb/video/hdmi_hdrtype"))
+ BoxInfo.setItem("HasScaler_sharpness", pathExists("/proc/stb/vmpeg/0/pep_scaler_sharpness"))
+ BoxInfo.setItem("HasHDMIin", BoxInfo.getItem("dmifhdin") or BoxInfo.getItem("hdmihdin"))
+ BoxInfo.setItem("HasHDMI-CEC", BoxInfo.getItem("hdmi") and isPluginInstalled("HdmiCEC") and (fileExists("/dev/cec0") or fileExists("/dev/hdmi_cec") or fileExists("/dev/misc/hdmi_cec0")))
+ BoxInfo.setItem("HasYPbPr", model in ("dm8000", "et5000", "et6000", "et6500", "et9000", "et9200", "et9500", "et10000", "formuler1", "mbtwinplus", "spycat", "vusolo", "vuduo", "vuduo2", "vuultimo") or getMachineBuild() in ('gb7356', 'gb7325') or model in ('gbultraue', 'gbultraueh', 'gb800ueplus', 'gb800seplus'))
+ BoxInfo.setItem("HasScart", model in ("dm8000", "et4000", "et6500", "et8000", "et9000", "et9200", "et9500", "et10000", "formuler1", "hd1100", "hd1200", "hd1265", "hd2400", "vusolo", "vusolo2", "vuduo", "vuduo2", "vuultimo", "vuuno", "xp1000") or getMachineBuild() in ('gb7325', ))
+ BoxInfo.setItem("HasSVideo", model in ("dm8000"))
+ BoxInfo.setItem("HasComposite", model not in ("i55", "gbquad4k", "gbue4k", "hd1500", "osnino", "osninoplus", "purehd", "purehdse", "revo4k", "vusolo4k", "vuzero4k", "vuduo4k", "vuduo4kse", "vuuno4k", "vuuno4kse", "vuultimo4k"))
+ BoxInfo.setItem("hasXcoreVFD", model in ("osmega", "spycat4k", "spycat4kmini", "spycat4kcombo") and fileCheck("/sys/module/brcmstb_%s/parameters/pt6302_cgram" % model))
+ BoxInfo.setItem("HasOfflineDecoding", model not in ("osmini", "osminiplus", "et7000mini", "et11000", "mbmicro", "mbtwinplus", "mbmicrov2", "et7000", "et8500"))
+ BoxInfo.setItem("canDualBoot", fileExists("/dev/block/by-name/flag"))
+ BoxInfo.setItem("canFlashWithOfgwrite", not (model.startswith("dm")))
+ BoxInfo.setItem("HDRSupport", fileExists("/proc/stb/hdmi/hlg_support_choices") and fileCheck("/proc/stb/hdmi/hlg_support"))
+ BoxInfo.setItem("CanProc", BoxInfo.getItem("HasMMC") and not BoxInfo.getItem("Blindscan_t2_available"))
+ BoxInfo.setItem("HasMultichannelPCM", fileCheck("/proc/stb/audio/multichannel_pcm"))
+ BoxInfo.setItem("HasAutoVolume", fileExists("/proc/stb/audio/avl_choices") and fileCheck("/proc/stb/audio/avl"))
+ BoxInfo.setItem("HasAutoVolumeLevel", fileExists("/proc/stb/audio/autovolumelevel_choices") and fileCheck("/proc/stb/audio/autovolumelevel"))
+ BoxInfo.setItem("Has3DSurround", fileExists("/proc/stb/audio/3d_surround_choices") and fileCheck("/proc/stb/audio/3d_surround"))
+ BoxInfo.setItem("Has3DSpeaker", fileExists("/proc/stb/audio/3d_surround_speaker_position_choices") and fileCheck("/proc/stb/audio/3d_surround_speaker_position"))
+ BoxInfo.setItem("Has3DSurroundSpeaker", fileExists("/proc/stb/audio/3dsurround_choices") and fileCheck("/proc/stb/audio/3dsurround"))
+ BoxInfo.setItem("Has3DSurroundSoftLimiter", fileExists("/proc/stb/audio/3dsurround_softlimiter_choices") and fileCheck("/proc/stb/audio/3dsurround_softlimiter"))
+ BoxInfo.setItem("HasHDMI-In", model in ('gbquad4k', ))
+ BoxInfo.setItem("CanDownmixAC3", fileHas("/proc/stb/audio/ac3_choices", "downmix"))
+ BoxInfo.setItem("CanDownmixDTS", fileHas("/proc/stb/audio/dts_choices", "downmix"))
+ BoxInfo.setItem("CanDownmixAAC", fileHas("/proc/stb/audio/aac_choices", "downmix"))
+ BoxInfo.setItem("HDMIAudioSource", fileCheck("/proc/stb/hdmi/audio_source"))
+ BoxInfo.setItem("HAScmdline", fileCheck("/boot/cmdline.txt"))
+ BoxInfo.setItem("HasSDmmc", BoxInfo.getItem("canMultiBoot") and "sd" in BoxInfo.getItem("canMultiBoot")[2] and "mmcblk" in getMachineMtdRoot())
+ BoxInfo.setItem("canRecovery", getMachineBuild() in ('gbmv200',) and ('usb_update.bin', 'none'))
+ BoxInfo.setItem("CanAC3Transcode", fileHas("/proc/stb/audio/ac3plus_choices", "force_ac3"))
+ BoxInfo.setItem("CanDTSHD", fileHas("/proc/stb/audio/dtshd_choices", "downmix"))
+ BoxInfo.setItem("CanDownmixAACPlus", fileHas("/proc/stb/audio/aacplus_choices", "downmix"))
+ BoxInfo.setItem("CanAACTranscode", fileHas("/proc/stb/audio/aac_transcode_choices", "off"))
+ BoxInfo.setItem("CanWMAPRO", fileHas("/proc/stb/audio/wmapro_choices", "downmix"))
+ BoxInfo.setItem("CanBTAudio", fileHas("/proc/stb/audio/btaudio_choices", "off"))
+ BoxInfo.setItem("CanBTAudioDelay", fileCheck("/proc/stb/audio/btaudio_delay") or fileCheck("/proc/stb/audio/btaudio_delay_pcm"))
+ BoxInfo.setItem("BootDevice", getBootdevice())
+ BoxInfo.setItem("FbcTunerPowerAlwaysOn", model in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse"))
+ BoxInfo.setItem("HasPhysicalLoopthrough", ["Vuplus DVB-S NIM(AVL2108)", "GIGA DVB-S2 NIM (Internal)"])
+ BoxInfo.setItem("HasFBCtuner", ["Vuplus DVB-C NIM(BCM3158)", "Vuplus DVB-C NIM(BCM3148)", "Vuplus DVB-S NIM(7376 FBC)", "Vuplus DVB-S NIM(45308X FBC)", "Vuplus DVB-S NIM(45208 FBC)", "DVB-S2 NIM(45208 FBC)", "DVB-S2X NIM(45308X FBC)", "DVB-S2 NIM(45308 FBC)", "DVB-C NIM(3128 FBC)", "BCM45208", "BCM45308X", "BCM3158"])
+ BoxInfo.setItem("HasHiSi", pathExists("/proc/hisi"))
+ BoxInfo.setItem("FCCactive", False)
+ BoxInfo.setItem("Autoresolution_proc_videomode", model in ("gbue4k", "gbquad4k") and "/proc/stb/video/videomode_50hz" or "/proc/stb/video/videomode")
+
+
+setBoxInfoItems()
diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py
index 1b71d7da1a..b45d365872 100644
--- a/lib/python/Components/UsageConfig.py
+++ b/lib/python/Components/UsageConfig.py
@@ -7,8 +7,7 @@
from Components.NimManager import nimmanager
from Components.Renderer.FrontpanelLed import ledPatterns, PATTERN_ON, PATTERN_OFF, PATTERN_BLINK
from Components.ServiceList import refreshServiceList, redrawServiceList
-from Components.SystemInfo import SystemInfo
-
+from Components.SystemInfo import BoxInfo
import os
import time
@@ -204,8 +203,8 @@ def alternativeNumberModeChange(configElement):
config.usage.poweroff_day[i] = ConfigEnableDisable(default=False)
config.usage.poweroff_time[i] = ConfigClock(default=((1 * 60 + 0) * 60))
- choicelist = [("0", _("Disabled"))]
- for i in list(range(3600, 21601, 3600)):
+ choicelist = [("0", _("Disabled")), ("1800", _("Standby in ") + _("half an hour"))]
+ for i in range(3600, 21601, 3600):
h = abs(i / 3600)
h = ngettext("%d hour", "%d hours", h) % h
choicelist.append((str(i), _("Standby in ") + h))
@@ -374,98 +373,98 @@ def PreferredTunerChanged(configElement):
config.usage.show_eit_nownext = ConfigYesNo(default=True)
config.usage.show_vcr_scart = ConfigYesNo(default=False)
config.usage.show_update_disclaimer = ConfigYesNo(default=True)
- config.usage.pic_resolution = ConfigSelection(default=None, choices=[(None, _("Same resolution as skin")), ("(720, 576)", "720x576"), ("(1280, 720)", "1280x720"), ("(1920, 1080)", "1920x1080")][:SystemInfo["HasFullHDSkinSupport"] and 4 or 3])
+ config.usage.pic_resolution = ConfigSelection(default=None, choices=[(None, _("Same resolution as skin")), ("(720, 576)", "720x576"), ("(1280, 720)", "1280x720"), ("(1920, 1080)", "1920x1080")][:BoxInfo.getItem("HasFullHDSkinSupport") and 4 or 3])
- if SystemInfo["Bootvideo"]:
+ if BoxInfo.getItem("Bootvideo"):
config.usage.show_bootvideo = ConfigYesNo(default=False)
- if SystemInfo["Fan"]:
+ if BoxInfo.getItem("Fan"):
choicelist = [('off', _("Off")), ('on', _("On")), ('auto', _("Auto"))]
if os.path.exists("/proc/stb/fp/fan_choices"):
choicelist = [x for x in choicelist if x[0] in open("/proc/stb/fp/fan_choices", "r").read().strip().split(" ")]
config.usage.fan = ConfigSelection(choicelist)
def fanChanged(configElement):
- open(SystemInfo["Fan"], "w").write(configElement.value)
+ open(BoxInfo.getItem("Fan"), "w").write(configElement.value)
config.usage.fan.addNotifier(fanChanged)
- if SystemInfo["FanPWM"]:
+ if BoxInfo.getItem("FanPWM"):
def fanSpeedChanged(configElement):
- open(SystemInfo["FanPWM"], "w").write(hex(configElement.value)[2:])
+ open(BoxInfo.getItem("FanPWM"), "w").write(hex(configElement.value)[2:])
config.usage.fanspeed = ConfigSlider(default=127, increment=8, limits=(0, 255))
config.usage.fanspeed.addNotifier(fanSpeedChanged)
- if SystemInfo["PowerLED"]:
+ if BoxInfo.getItem("PowerLED"):
def powerLEDChanged(configElement):
- if "fp" in SystemInfo["PowerLED"]:
- open(SystemInfo["PowerLED"], "w").write(configElement.value and "1" or "0")
- patterns = [PATTERN_ON, PATTERN_ON, PATTERN_OFF, PATTERN_OFF] if configElement.value else [PATTERN_OFF, PATTERN_OFF, PATTERN_OFF, PATTERN_OFF]
+ if "fp" in BoxInfo.getItem("PowerLED"):
+ open(BoxInfo.getItem("PowerLED"), "w").write(configElement.value and "1" or "0")
+ patterns = [PATTERN_ON, PATTERN_ON, PATTERN_OFF, PATTERN_ON] if configElement.value else [PATTERN_OFF, PATTERN_OFF, PATTERN_OFF, PATTERN_OFF]
ledPatterns.setLedPatterns(1, patterns)
else:
- open(SystemInfo["PowerLED"], "w").write(configElement.value and "on" or "off")
+ open(BoxInfo.getItem("PowerLED"), "w").write(configElement.value and "on" or "off")
config.usage.powerLED = ConfigYesNo(default=True)
config.usage.powerLED.addNotifier(powerLEDChanged)
- if SystemInfo["StandbyLED"]:
+ if BoxInfo.getItem("StandbyLED"):
def standbyLEDChanged(configElement):
- if "fp" in SystemInfo["StandbyLED"]:
+ if "fp" in BoxInfo.getItem("StandbyLED"):
patterns = [PATTERN_OFF, PATTERN_BLINK, PATTERN_ON, PATTERN_BLINK] if configElement.value else [PATTERN_OFF, PATTERN_OFF, PATTERN_OFF, PATTERN_OFF]
ledPatterns.setLedPatterns(0, patterns)
else:
- open(SystemInfo["StandbyLED"], "w").write(configElement.value and "on" or "off")
+ open(BoxInfo.getItem("StandbyLED"), "w").write(configElement.value and "on" or "off")
config.usage.standbyLED = ConfigYesNo(default=True)
config.usage.standbyLED.addNotifier(standbyLEDChanged)
- if SystemInfo["SuspendLED"]:
+ if BoxInfo.getItem("SuspendLED"):
def suspendLEDChanged(configElement):
- if "fp" in SystemInfo["SuspendLED"]:
- open(SystemInfo["SuspendLED"], "w").write(configElement.value and "1" or "0")
+ if "fp" in BoxInfo.getItem("SuspendLED"):
+ open(BoxInfo.getItem("SuspendLED"), "w").write(configElement.value and "1" or "0")
else:
- open(SystemInfo["SuspendLED"], "w").write(configElement.value and "on" or "off")
+ open(BoxInfo.getItem("SuspendLED"), "w").write(configElement.value and "on" or "off")
config.usage.suspendLED = ConfigYesNo(default=True)
config.usage.suspendLED.addNotifier(suspendLEDChanged)
- if SystemInfo["PowerOffDisplay"]:
+ if BoxInfo.getItem("PowerOffDisplay"):
def powerOffDisplayChanged(configElement):
- open(SystemInfo["PowerOffDisplay"], "w").write(configElement.value and "1" or "0")
+ open(BoxInfo.getItem("PowerOffDisplay"), "w").write(configElement.value and "1" or "0")
config.usage.powerOffDisplay = ConfigYesNo(default=True)
config.usage.powerOffDisplay.addNotifier(powerOffDisplayChanged)
- if SystemInfo["LCDshow_symbols"]:
+ if BoxInfo.getItem("LCDshow_symbols"):
def lcdShowSymbols(configElement):
- open(SystemInfo["LCDshow_symbols"], "w").write(configElement.value and "1" or "0")
+ open(BoxInfo.getItem("LCDshow_symbols"), "w").write(configElement.value and "1" or "0")
config.usage.lcd_show_symbols = ConfigYesNo(default=True)
config.usage.lcd_show_symbols.addNotifier(lcdShowSymbols)
config.network = ConfigSubsection()
- if SystemInfo["WakeOnLAN"]:
- f = open(SystemInfo["WakeOnLAN"], "r")
+ if BoxInfo.getItem("WakeOnLAN"):
+ f = open(BoxInfo.getItem("WakeOnLAN"), "r")
status = f.read().strip()
f.close()
def wakeOnLANChanged(configElement):
if status in ("enable", "disable"):
- open(SystemInfo["WakeOnLAN"], "w").write(configElement.value and "enable" or "disable")
+ open(BoxInfo.getItem("WakeOnLAN"), "w").write(configElement.value and "enable" or "disable")
else:
- open(SystemInfo["WakeOnLAN"], "w").write(configElement.value and "on" or "off")
+ open(BoxInfo.getItem("WakeOnLAN"), "w").write(configElement.value and "on" or "off")
config.network.wol = ConfigYesNo(default=False)
config.network.wol.addNotifier(wakeOnLANChanged)
- if SystemInfo["hasXcoreVFD"]:
+ if BoxInfo.getItem("hasXcoreVFD"):
def set12to8characterVFD(configElement):
- open(SystemInfo["hasXcoreVFD"], "w").write(not configElement.value and "1" or "0")
+ open(BoxInfo.getItem("hasXcoreVFD"), "w").write(not configElement.value and "1" or "0")
config.usage.toggle12to8characterVFD = ConfigYesNo(default=False)
config.usage.toggle12to8characterVFD.addNotifier(set12to8characterVFD)
- if SystemInfo["LcdLiveTVMode"]:
+ if BoxInfo.getItem("LcdLiveTVMode"):
def setLcdLiveTVMode(configElement):
- open(SystemInfo["LcdLiveTVMode"], "w").write(configElement.value)
- config.usage.LcdLiveTVMode = ConfigSelection(default="0", choices=[str(x) for x in list(range(0, 9))])
+ open(BoxInfo.getItem("LcdLiveTVMode"), "w").write(configElement.value)
+ config.usage.LcdLiveTVMode = ConfigSelection(default="0", choices=[str(x) for x in range(0, 9)])
config.usage.LcdLiveTVMode.addNotifier(setLcdLiveTVMode)
- if SystemInfo["LcdLiveDecoder"]:
+ if BoxInfo.getItem("LcdLiveDecoder"):
def setLcdLiveDecoder(configElement):
- open(SystemInfo["LcdLiveDecoder"], "w").write(configElement.value)
- config.usage.LcdLiveDecoder = ConfigSelection(default="0", choices=[str(x) for x in list(range(0, 4))])
+ open(BoxInfo.getItem("LcdLiveDecoder"), "w").write(configElement.value)
+ config.usage.LcdLiveDecoder = ConfigSelection(default="0", choices=[str(x) for x in range(0, 4)])
config.usage.LcdLiveDecoder.addNotifier(setLcdLiveDecoder)
config.usage.boolean_graphic = ConfigSelection(default="true", choices={"false": _("no"), "true": _("yes"), "only_bool": _("yes, but not in multi selections")})
@@ -563,7 +562,7 @@ def setHDDStandby(configElement):
hdd[1].setIdleTime(int(configElement.value))
config.usage.hdd_standby.addNotifier(setHDDStandby, immediate_feedback=False)
- if SystemInfo["12V_Output"]:
+ if BoxInfo.getItem("12V_Output"):
def set12VOutput(configElement):
Misc_Options.getInstance().set_12V_output(configElement.value == "on" and 1 or 0)
config.usage.output_12V.addNotifier(set12VOutput, immediate_feedback=False)
@@ -645,90 +644,90 @@ def updateEraseFlags(el):
("3", _("Everywhere"))])
config.misc.erase_flags.addNotifier(updateEraseFlags, immediate_feedback=False)
- if SystemInfo["ZapMode"]:
+ if BoxInfo.getItem("ZapMode"):
def setZapmode(el):
- open(SystemInfo["ZapMode"], "w").write(el.value)
+ open(BoxInfo.getItem("ZapMode"), "w").write(el.value)
config.misc.zapmode = ConfigSelection(default="mute", choices=[
("mute", _("Black screen")), ("hold", _("Hold screen")), ("mutetilllock", _("Black screen till locked")), ("holdtilllock", _("Hold till locked"))])
config.misc.zapmode.addNotifier(setZapmode, immediate_feedback=False)
- if SystemInfo["VFD_scroll_repeats"]:
+ if BoxInfo.getItem("VFD_scroll_repeats"):
def scroll_repeats(el):
- open(SystemInfo["VFD_scroll_repeats"], "w").write(el.value)
+ open(BoxInfo.getItem("VFD_scroll_repeats"), "w").write(el.value)
choicelist = []
for i in list(range(1, 11, 1)):
choicelist.append((str(i)))
config.usage.vfd_scroll_repeats = ConfigSelection(default="3", choices=choicelist)
config.usage.vfd_scroll_repeats.addNotifier(scroll_repeats, immediate_feedback=False)
- if SystemInfo["VFD_scroll_delay"]:
+ if BoxInfo.getItem("VFD_scroll_delay"):
def scroll_delay(el):
- open(SystemInfo["VFD_scroll_delay"], "w").write(el.value)
+ open(BoxInfo.getItem("VFD_scroll_delay"), "w").write(el.value)
choicelist = []
for i in list(range(0, 1001, 50)):
choicelist.append((str(i)))
config.usage.vfd_scroll_delay = ConfigSelection(default="150", choices=choicelist)
config.usage.vfd_scroll_delay.addNotifier(scroll_delay, immediate_feedback=False)
- if SystemInfo["VFD_initial_scroll_delay"]:
+ if BoxInfo.getItem("VFD_initial_scroll_delay"):
def initial_scroll_delay(el):
- open(SystemInfo["VFD_initial_scroll_delay"], "w").write(el.value)
+ open(BoxInfo.getItem("VFD_initial_scroll_delay"), "w").write(el.value)
choicelist = []
for i in list(range(0, 20001, 500)):
choicelist.append((str(i)))
config.usage.vfd_initial_scroll_delay = ConfigSelection(default="1000", choices=choicelist)
config.usage.vfd_initial_scroll_delay.addNotifier(initial_scroll_delay, immediate_feedback=False)
- if SystemInfo["VFD_final_scroll_delay"]:
+ if BoxInfo.getItem("VFD_final_scroll_delay"):
def final_scroll_delay(el):
- open(SystemInfo["VFD_final_scroll_delay"], "w").write(el.value)
+ open(BoxInfo.getItem("VFD_final_scroll_delay"), "w").write(el.value)
choicelist = []
for i in list(range(0, 20001, 500)):
choicelist.append((str(i)))
config.usage.vfd_final_scroll_delay = ConfigSelection(default="1000", choices=choicelist)
config.usage.vfd_final_scroll_delay.addNotifier(final_scroll_delay, immediate_feedback=False)
- if SystemInfo["HasBypassEdidChecking"]:
+ if BoxInfo.getItem("HasBypassEdidChecking"):
def setHasBypassEdidChecking(configElement):
- open(SystemInfo["HasBypassEdidChecking"], "w").write("00000001" if configElement.value else "00000000")
+ open(BoxInfo.getItem("HasBypassEdidChecking"), "w").write("00000001" if configElement.value else "00000000")
config.av.bypassEdidChecking = ConfigYesNo(default=False)
config.av.bypassEdidChecking.addNotifier(setHasBypassEdidChecking)
- if SystemInfo["HasColorspace"]:
+ if BoxInfo.getItem("HasColorspace"):
def setHaveColorspace(configElement):
- open(SystemInfo["HasColorspace"], "w").write(configElement.value)
- if SystemInfo["HasColorspaceSimple"]:
+ open(BoxInfo.getItem("HasColorspace"), "w").write(configElement.value)
+ if BoxInfo.getItem("HasColorspaceSimple"):
config.av.hdmicolorspace = ConfigSelection(default="Edid(Auto)", choices={"Edid(Auto)": _("auto"), "Hdmi_Rgb": "RGB", "444": "YCbCr 4:4:4", "422": "YCbCr 4:2:2", "420": "YCbCr 4:2:0"})
else:
# config.av.hdmicolorspace = ConfigSelection(default="auto", choices={"auto": _("auto"), "rgb": "RGB", "420": "4:2:0", "422": "4:2:2", "444": "4:4:4"})
config.av.hdmicolorspace = ConfigSelection(default="Edid(Auto)", choices={"Edid(Auto)": _("Auto"), "Hdmi_Rgb": _("RGB"), "Itu_R_BT_709": _("Itu_R_BT_709"), "Unknown": _("Unknown")})
config.av.hdmicolorspace.addNotifier(setHaveColorspace)
- if SystemInfo["HasColordepth"]:
+ if BoxInfo.getItem("HasColordepth"):
def setHaveColordepth(configElement):
- open(SystemInfo["HasColordepth"], "w").write(configElement.value)
+ open(BoxInfo.getItem("HasColordepth"), "w").write(configElement.value)
config.av.hdmicolordepth = ConfigSelection(default="auto", choices={"auto": _("auto"), "8bit": "8bit", "10bit": "10bit", "12bit": "12bit"})
config.av.hdmicolordepth.addNotifier(setHaveColordepth)
- if SystemInfo["HasHDMIpreemphasis"]:
+ if BoxInfo.getItem("HasHDMIpreemphasis"):
def setHDMIpreemphasis(configElement):
- open(SystemInfo["HasHDMIpreemphasis"], "w").write("on" if configElement.value else "off")
+ open(BoxInfo.getItem("HasHDMIpreemphasis"), "w").write("on" if configElement.value else "off")
config.av.hdmipreemphasis = ConfigYesNo(default=False)
config.av.hdmipreemphasis.addNotifier(setHDMIpreemphasis)
- if SystemInfo["HasColorimetry"]:
+ if BoxInfo.getItem("HasColorimetry"):
def setColorimetry(configElement):
- open(SystemInfo["HasColorimetry"], "w").write(configElement.value)
+ open(BoxInfo.getItem("HasColorimetry"), "w").write(configElement.value)
config.av.hdmicolorimetry = ConfigSelection(default="auto", choices=[("auto", _("auto")), ("bt2020ncl", "BT 2020 NCL"), ("bt2020cl", "BT 2020 CL"), ("bt709", "BT 709")])
config.av.hdmicolorimetry.addNotifier(setColorimetry)
- if SystemInfo["HasHdrType"]:
+ if BoxInfo.getItem("HasHdrType"):
def setHdmiHdrType(configElement):
- open(SystemInfo["HasHdrType"], "w").write(configElement.value)
+ open(BoxInfo.getItem("HasHdrType"), "w").write(configElement.value)
config.av.hdmihdrtype = ConfigSelection(default="auto", choices={"auto": _("auto"), "none": "SDR", "hdr10": "HDR10", "hlg": "HLG", "dolby": "Dolby Vision"})
config.av.hdmihdrtype.addNotifier(setHdmiHdrType)
- if SystemInfo["HDRSupport"]:
+ if BoxInfo.getItem("HDRSupport"):
def setHlgSupport(configElement):
open("/proc/stb/hdmi/hlg_support", "w").write(configElement.value)
config.av.hlg_support = ConfigSelection(default="auto(EDID)",
@@ -1006,7 +1005,7 @@ def showrotorpositionChoicesUpdate(update=False):
config.misc.showrotorposition = ConfigSelection(default="no", choices=choiceslist)
else:
config.misc.showrotorposition.setChoices(choiceslist, "no")
- SystemInfo["isRotorTuner"] = count > 0
+ BoxInfo.setItem("isRotorTuner", count > 0)
def preferredTunerChoicesUpdate(update=False):
@@ -1075,10 +1074,10 @@ def preferredTunerChoicesUpdate(update=False):
else:
config.usage.recording_frontend_priority_atsc.setChoices(atsc_nims, "-2")
- SystemInfo["DVB-S_priority_tuner_available"] = len(dvbs_nims) > 3 and any(len(i) > 2 for i in (dvbt_nims, dvbc_nims, atsc_nims))
- SystemInfo["DVB-T_priority_tuner_available"] = len(dvbt_nims) > 3 and any(len(i) > 2 for i in (dvbs_nims, dvbc_nims, atsc_nims))
- SystemInfo["DVB-C_priority_tuner_available"] = len(dvbc_nims) > 3 and any(len(i) > 2 for i in (dvbs_nims, dvbt_nims, atsc_nims))
- SystemInfo["ATSC_priority_tuner_available"] = len(atsc_nims) > 3 and any(len(i) > 2 for i in (dvbs_nims, dvbc_nims, dvbt_nims))
+ BoxInfo.setItem("DVB-S_priority_tuner_available", len(dvbs_nims) > 3 and any(len(i) > 2 for i in (dvbt_nims, dvbc_nims, atsc_nims)))
+ BoxInfo.setItem("DVB-T_priority_tuner_available", len(dvbt_nims) > 3 and any(len(i) > 2 for i in (dvbs_nims, dvbc_nims, atsc_nims)))
+ BoxInfo.setItem("DVB-C_priority_tuner_available", len(dvbc_nims) > 3 and any(len(i) > 2 for i in (dvbs_nims, dvbt_nims, atsc_nims)))
+ BoxInfo.setItem("ATSC_priority_tuner_available", len(atsc_nims) > 3 and any(len(i) > 2 for i in (dvbs_nims, dvbc_nims, dvbt_nims)))
def dropEPGNewLines(text):
diff --git a/lib/python/Components/VfdSymbols.py b/lib/python/Components/VfdSymbols.py
index d04f7fd3eb..47cc96a9f1 100644
--- a/lib/python/Components/VfdSymbols.py
+++ b/lib/python/Components/VfdSymbols.py
@@ -5,7 +5,7 @@
from Tools.Directories import fileExists
from Components.ParentalControl import parentalControl
from Components.ServiceEventTracker import ServiceEventTracker
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from boxbranding import getBoxType
POLLTIME = 5 # seconds
@@ -150,7 +150,7 @@ def PlaySymbol(self):
if not fileExists("/proc/stb/lcd/symbol_play "):
return
- if SystemInfo["SeekStatePlay"]:
+ if BoxInfo.getItem("SeekStatePlay"):
open("/proc/stb/lcd/symbol_play ", "w").write("1")
else:
open("/proc/stb/lcd/symbol_play ", "w").write("0")
diff --git a/lib/python/Components/Wol.py b/lib/python/Components/Wol.py
index e8c79380ec..9c581facb6 100644
--- a/lib/python/Components/Wol.py
+++ b/lib/python/Components/Wol.py
@@ -1,5 +1,5 @@
from Components.config import config, ConfigSelection, ConfigNothing
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Tools.Directories import fileExists
from boxbranding import getBoxType
@@ -17,7 +17,7 @@ def setWolState(self, value):
def Init():
- if SystemInfo["WakeOnLAN"] and getBoxType() in ('gbquadplus', 'quadbox2400'):
+ if BoxInfo.getItem("WakeOnLAN") and getBoxType() in ('gbquadplus', 'quadbox2400'):
def setWOLmode(value):
iwol.setWolState(config.network.wol.value)
iwol = WOL()
diff --git a/lib/python/Components/config.py b/lib/python/Components/config.py
index b6f43f23dc..84ad0444f0 100644
--- a/lib/python/Components/config.py
+++ b/lib/python/Components/config.py
@@ -746,7 +746,7 @@ def saveSingle(self, v):
return str(v)
def fromstring(self, value):
- ret = [int(x) for x in value.split(self.seperator)]
+ ret = [int(float(x)) for x in value.split(self.seperator)]
return ret + [int(x[0]) for x in self.limits[len(ret):]]
def onDeselect(self, session):
diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py
index 8039c2eaae..b958759e98 100644
--- a/lib/python/Navigation.py
+++ b/lib/python/Navigation.py
@@ -1,7 +1,7 @@
from enigma import eServiceCenter, eServiceReference, eTimer, pNavigation, getBestPlayableServiceReference, iPlayableService, setPreferredTuner, eStreamServer, iRecordableServicePtr
from Components.ImportChannels import ImportChannels
from Components.ParentalControl import parentalControl
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.config import config, configfile
from Components.PluginComponent import plugins
from Plugins.Plugin import PluginDescriptor
@@ -218,11 +218,10 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust
else:
playref = ref
if self.pnav:
- if SystemInfo["FCCactive"] and not self.pnav.playService(playref):
- self.currentlyPlayingServiceReference = playref
- self.currentlyPlayingServiceOrGroup = ref
- return 0
- self.pnav.stopService()
+ if not BoxInfo.getItem("FCCactive"):
+ self.pnav.stopService()
+ else:
+ self.skipServiceReferenceReset = True
self.currentlyPlayingServiceReference = playref
playref = streamrelay.streamrelayChecker(playref)
self.currentlyPlayingServiceOrGroup = ref
@@ -231,30 +230,30 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust
if InfoBarInstance and InfoBarInstance.servicelist.servicelist.setCurrent(ref, adjust):
self.currentlyPlayingServiceOrGroup = InfoBarInstance.servicelist.servicelist.getCurrent()
setPriorityFrontend = False
- if SystemInfo["DVB-T_priority_tuner_available"] or SystemInfo["DVB-C_priority_tuner_available"] or SystemInfo["DVB-S_priority_tuner_available"] or SystemInfo["ATSC_priority_tuner_available"]:
+ if BoxInfo.getItem("DVB-T_priority_tuner_available") or BoxInfo.getItem("DVB-C_priority_tuner_available") or BoxInfo.getItem("DVB-S_priority_tuner_available") or BoxInfo.getItem("ATSC_priority_tuner_available"):
str_service = playref.toString()
if '%3a//' not in str_service and not str_service.rsplit(":", 1)[1].startswith("/"):
type_service = playref.getUnsignedData(4) >> 16
if type_service == 0xEEEE:
- if SystemInfo["DVB-T_priority_tuner_available"] and config.usage.frontend_priority_dvbt.value != "-2":
+ if BoxInfo.getItem("DVB-T_priority_tuner_available") and config.usage.frontend_priority_dvbt.value != "-2":
if config.usage.frontend_priority_dvbt.value != config.usage.frontend_priority.value:
setPreferredTuner(int(config.usage.frontend_priority_dvbt.value))
setPriorityFrontend = True
- if SystemInfo["ATSC_priority_tuner_available"] and config.usage.frontend_priority_atsc.value != "-2":
+ if BoxInfo.getItem("ATSC_priority_tuner_available") and config.usage.frontend_priority_atsc.value != "-2":
if config.usage.frontend_priority_atsc.value != config.usage.frontend_priority.value:
setPreferredTuner(int(config.usage.frontend_priority_atsc.value))
setPriorityFrontend = True
elif type_service == 0xFFFF:
- if SystemInfo["DVB-C_priority_tuner_available"] and config.usage.frontend_priority_dvbc.value != "-2":
+ if BoxInfo.getItem("DVB-C_priority_tuner_available") and config.usage.frontend_priority_dvbc.value != "-2":
if config.usage.frontend_priority_dvbc.value != config.usage.frontend_priority.value:
setPreferredTuner(int(config.usage.frontend_priority_dvbc.value))
setPriorityFrontend = True
- if SystemInfo["ATSC_priority_tuner_available"] and config.usage.frontend_priority_atsc.value != "-2":
+ if BoxInfo.getItem("ATSC_priority_tuner_available") and config.usage.frontend_priority_atsc.value != "-2":
if config.usage.frontend_priority_atsc.value != config.usage.frontend_priority.value:
setPreferredTuner(int(config.usage.frontend_priority_atsc.value))
setPriorityFrontend = True
else:
- if SystemInfo["DVB-S_priority_tuner_available"] and config.usage.frontend_priority_dvbs.value != "-2":
+ if BoxInfo.getItem("DVB-S_priority_tuner_available") and config.usage.frontend_priority_dvbs.value != "-2":
if config.usage.frontend_priority_dvbs.value != config.usage.frontend_priority.value:
setPreferredTuner(int(config.usage.frontend_priority_dvbs.value))
setPriorityFrontend = True
diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
index 90ed9df22e..5bfe1a341c 100644
--- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
+++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py
@@ -20,7 +20,7 @@
from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS
from Components.AVSwitch import AVSwitch
from Components.config import config
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Tools.Directories import fileExists, resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_CURRENT_SKIN
from Tools.BoundFunction import boundFunction
from .settings import MediaPlayerSettings
@@ -265,7 +265,7 @@ def action(self, contexts, action):
if InfoBar.instance is not None:
self.servicelist = InfoBar.instance.servicelist
if self.servicelist and hasattr(self.servicelist, 'dopipzap'):
- self.pipZapAvailable = SystemInfo.get("NumVideoDecoders", 1) > 1
+ self.pipZapAvailable = BoxInfo.getItem("NumVideoDecoders", 1) > 1
def prevBouquetHelpText(self):
if not self.shown and self.isPiPzap():
diff --git a/lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/plugin.py b/lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/plugin.py
index 87167d43ed..04138a7430 100644
--- a/lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/CommonInterfaceAssignment/plugin.py
@@ -11,7 +11,7 @@
from Components.Label import Label
from Components.SelectionList import SelectionList
from Components.MenuList import MenuList
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from ServiceReference import ServiceReference
from Plugins.Plugin import PluginDescriptor
from xml.etree.ElementTree import parse
@@ -47,7 +47,7 @@ def __init__(self, session, args=0):
"cancel": self.close
}, -1)
- NUM_CI = SystemInfo["CommonInterface"]
+ NUM_CI = BoxInfo.getItem("CommonInterface")
print("[CI_Wizzard] FOUND %d CI Slots " % NUM_CI)
@@ -681,7 +681,7 @@ def find_in_list(list, search, listpos=0):
def isModule():
- NUM_CI = SystemInfo["CommonInterface"]
+ NUM_CI = BoxInfo.getItem("CommonInterface")
if NUM_CI and NUM_CI > 0:
for slot in list(range(NUM_CI)):
state = eDVBCI_UI.getInstance().getState(slot)
diff --git a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py
index d2f3c32150..5df22c60c3 100644
--- a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py
@@ -9,7 +9,7 @@
from Components.ActionMap import ActionMap
from Components.Sources.StaticText import StaticText
from Components.ServiceEventTracker import ServiceEventTracker
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from enigma import iPlayableService, eTimer, eServiceReference, iRecordableService
import os
import glob
@@ -87,7 +87,7 @@ def __init__(self, session):
self.__event_tracker = None
self.onClose = []
self.changeEventTracker()
- SystemInfo["FCCactive"] = self.fccSetupActivate
+ BoxInfo.setItem("FCCactive", self.fccSetupActivate)
# from Screens.PictureInPicture import on_pip_start_stop
# on_pip_start_stop.append(self.FCCForceStopforPIP)
@@ -179,7 +179,7 @@ def FCCSetupChanged(self):
if fcc_changed:
self.fccmgr.setFCCEnable(int(self.fccSetupActivate))
- SystemInfo["FCCactive"] = self.fccSetupActivate
+ BoxInfo.setItem("FCCactive", self.fccSetupActivate)
curPlaying = self.session.nav.getCurrentlyPlayingServiceReference()
if curPlaying:
self.session.nav.stopService()
diff --git a/lib/python/Plugins/SystemPlugins/OSD3DSetup/plugin.py b/lib/python/Plugins/SystemPlugins/OSD3DSetup/plugin.py
index c7e0936043..4e95d37a21 100644
--- a/lib/python/Plugins/SystemPlugins/OSD3DSetup/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/OSD3DSetup/plugin.py
@@ -3,7 +3,7 @@
from Components.Label import Label
from Components.ConfigList import ConfigListScreen
from Components.ServiceEventTracker import ServiceEventTracker
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.config import config, ConfigSubsection, ConfigInteger, ConfigSelection, ConfigSlider
from enigma import iPlayableService, iServiceInformation, eServiceCenter, eServiceReference, eDVBDB
@@ -80,17 +80,11 @@ def keyCancel(self):
def applySettings(mode=config.plugins.OSD3DSetup.mode.value, znorm=int(config.plugins.OSD3DSetup.znorm.value)):
global previous, isDedicated3D
mode = isDedicated3D and mode == "auto" and "sidebyside" or mode
- mode == "3dmode" in SystemInfo["3DMode"] and mode or mode == 'sidebyside' and 'sbs' or mode == 'topandbottom' and 'tab' or 'off'
+ mode == "3dmode" in BoxInfo.getItem("3DMode") and mode or mode == 'sidebyside' and 'sbs' or mode == 'topandbottom' and 'tab' or 'off'
if previous != (mode, znorm):
try:
- if mode == 'sidebyside':
- mode = 'sbs'
- elif mode == 'topandbottom':
- mode = 'tab'
- else:
- mode = 'off'
- open(PROC_GB_3DMODE, "w").write(mode)
- open(PROC_GB_ZNORM, "w").write('%d' % znorm)
+ open(BoxInfo.getItem("3DMode"), "w").write(mode)
+ open(BoxInfo.getItem("3DZNorm"), "w").write('%d' % znorm)
previous = (mode, znorm)
except:
return
@@ -145,7 +139,7 @@ def autostart(reason, **kwargs):
def Plugins(**kwargs):
- if SystemInfo["3DMode"]:
+ if BoxInfo.getItem("3DMode"):
from Plugins.Plugin import PluginDescriptor
return [PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART], fnc=autostart),
PluginDescriptor(name=_("OSD 3D setup"), description=_("Adjust 3D settings"), where=PluginDescriptor.WHERE_MENU, fnc=startSetup)]
diff --git a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
index 97551d4611..4d33332c1b 100644
--- a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
@@ -9,7 +9,7 @@
from Components.ActionMap import ActionMap
from Components.NimManager import nimmanager, getConfigSatlist
from Components.config import config, ConfigSelection
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.TuneTest import Tuner
from Tools.Transponder import getChannelNumber, channel2frequency
from Tools.BoundFunction import boundFunction
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageBackup.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageBackup.py
index 8b67c2778f..e1e913cd9d 100644
--- a/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageBackup.py
+++ b/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageBackup.py
@@ -1,7 +1,7 @@
from enigma import getEnigmaVersionString
from Screens.Screen import Screen
from Components.Sources.StaticText import StaticText
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.Label import Label
from Components.ActionMap import ActionMap
from Components.About import about
@@ -86,11 +86,11 @@ def ImageList(self, imagedict):
if imagedict:
for x in sorted(imagedict.keys()):
if imagedict[x]["imagename"] != _("Empty slot"):
- if x == 1 and currentimageslot == 1 and SystemInfo["canRecovery"]:
+ if x == 1 and currentimageslot == 1 and BoxInfo.getItem("canRecovery"):
_list.append(ChoiceEntryComponent('', (_("slot%s - %s as USB Recovery") % (x, imagedict[x]["imagename"]), x, True)))
_list.append(ChoiceEntryComponent('', ((_("slot%s - %s (current image)") if x == currentimageslot else _("slot%s - %s")) % (x, imagedict[x]["imagename"]), x, False)))
else:
- if SystemInfo["canRecovery"]:
+ if BoxInfo.getItem("canRecovery"):
_list.append(ChoiceEntryComponent('', (_("internal flash: %s %s as USB Recovery") % (getImageDistro(), getImageVersion()), "x", True)))
_list.append(ChoiceEntryComponent('', (_("internal flash: %s %s ") % (getImageDistro(), getImageVersion()), "x", False)))
self["config"].setList(_list)
@@ -153,19 +153,19 @@ def doFullBackup(self, answer):
self.IMAGEDISTRO = getImageDistro()
self.DISTROVERSION = getImageVersion()
- if SystemInfo["canRecovery"]:
- self.EMMCIMG = SystemInfo["canRecovery"][0]
- self.MTDBOOT = SystemInfo["canRecovery"][1]
+ if BoxInfo.getItem("canRecovery"):
+ self.EMMCIMG = BoxInfo.getItem("canRecovery")[0]
+ self.MTDBOOT = BoxInfo.getItem("canRecovery")[1]
else:
self.EMMCIMG = "none"
self.MTDBOOT = "none"
self.getImageList = self.saveImageList
- if SystemInfo["canMultiBoot"]:
- self.MTDKERNEL = SystemInfo["canMultiBoot"][self.SLOT]["kernel"].split('/')[2]
- self.MTDROOTFS = SystemInfo["canMultiBoot"][self.SLOT]["device"].split('/')[2]
- if SystemInfo["HasRootSubdir"]:
- self.ROOTFSSUBDIR = SystemInfo["canMultiBoot"][self.SLOT]['rootsubdir']
+ if BoxInfo.getItem("canMultiBoot"):
+ self.MTDKERNEL = BoxInfo.getItem("canMultiBoot")[self.SLOT]["kernel"].split('/')[2]
+ self.MTDROOTFS = BoxInfo.getItem("canMultiBoot")[self.SLOT]["device"].split('/')[2]
+ if BoxInfo.getItem("HasRootSubdir"):
+ self.ROOTFSSUBDIR = BoxInfo.getItem("canMultiBoot")[self.SLOT]['rootsubdir']
else:
self.MTDKERNEL = getMachineMtdKernel()
self.MTDROOTFS = getMachineMtdRoot()
@@ -228,14 +228,14 @@ def doFullBackup(self, answer):
## PREPARING THE BUILDING ENVIRONMENT
os.system("rm -rf %s" % self.WORKDIR)
- self.backuproot = "/tmp/bi/RootSubdir/" if SystemInfo["HasRootSubdir"] else "/tmp/bi/root"
+ self.backuproot = "/tmp/bi/RootSubdir/" if BoxInfo.getItem("HasRootSubdir") else "/tmp/bi/root"
if not os.path.exists(self.WORKDIR):
os.makedirs(self.WORKDIR)
if not os.path.exists(self.backuproot):
os.makedirs(self.backuproot)
os.system("sync")
- if SystemInfo["canMultiBoot"]:
- if SystemInfo["HasRootSubdir"]:
+ if BoxInfo.getItem("canMultiBoot"):
+ if BoxInfo.getItem("HasRootSubdir"):
os.system("mount /dev/%s /tmp/bi/RootSubdir" % self.MTDROOTFS)
self.backuproot = self.backuproot + self.ROOTFSSUBDIR
else:
@@ -343,8 +343,8 @@ def doFullBackup(self, answer):
cmdlist.append("umount %s/userdata" % (self.WORKDIR))
cmdlist.append('echo "' + _("Create:") + " kerneldump" + '"')
- if SystemInfo["canMultiBoot"] or self.MTDKERNEL.startswith('mmcblk0'):
- if SystemInfo["hasKexec"]:
+ if BoxInfo.getItem("canMultiBoot") or self.MTDKERNEL.startswith('mmcblk0'):
+ if BoxInfo.getItem("hasKexec"):
cmdlist.append("cp /%s %s/%s" % (self.MTDKERNEL, self.WORKDIR, self.KERNELBIN))
else:
cmdlist.append("dd if=/dev/%s of=%s/%s" % (self.MTDKERNEL, self.WORKDIR, self.KERNELBIN))
@@ -490,7 +490,7 @@ def doFullBackupCB(self):
os.system('mv %s/rootfs.tar.bz2 %s/rootfs.tar.bz2' % (self.WORKDIR, self.MAINDEST))
else:
os.system('mv %s/root.%s %s/%s' % (self.WORKDIR, self.ROOTFSTYPE, self.MAINDEST, self.ROOTFSBIN))
- if SystemInfo["canMultiBoot"] or self.MTDKERNEL.startswith('mmcblk0'):
+ if BoxInfo.getItem("canMultiBoot") or self.MTDKERNEL.startswith('mmcblk0'):
os.system('mv %s/%s %s/%s' % (self.WORKDIR, self.KERNELBIN, self.MAINDEST, self.KERNELBIN))
else:
os.system('mv %s/vmlinux.gz %s/%s' % (self.WORKDIR, self.MAINDEST, self.KERNELBIN))
@@ -507,7 +507,7 @@ def doFullBackupCB(self):
cmdlist.append('echo "This file forces a reboot after the update." > %s/reboot.update' % self.MAINDEST)
elif self.MODEL in ("vuzero", "vusolose", "vuuno4k", "vuzero4k"):
cmdlist.append('echo "This file forces the update." > %s/force.update' % self.MAINDEST)
- elif SystemInfo["HasRootSubdir"]:
+ elif BoxInfo.getItem("HasRootSubdir"):
cmdlist.append('echo "Rename the unforce_%s.txt to force_%s.txt and move it to the root of your usb-stick" > %s/force_%s_READ.ME' % (self.MACHINEBUILD, self.MACHINEBUILD, self.MAINDEST, self.MACHINEBUILD))
cmdlist.append('echo "When you enter the recovery menu then it will force to install the image in the linux1 selection" >> %s/force_%s_READ.ME' % (self.MAINDEST, self.MACHINEBUILD))
else:
@@ -549,9 +549,9 @@ def doFullBackupCB(self):
cmdlist.append('cp -f /usr/share/fastboot.bin %s/fastboot.bin' % (self.MAINDESTROOT))
cmdlist.append('cp -f /usr/share/bootargs.bin %s/bootargs.bin' % (self.MAINDESTROOT))
- if SystemInfo["canRecovery"] and self.RECOVERY:
+ if BoxInfo.getItem("canRecovery") and self.RECOVERY:
cmdlist.append('7za a -r -bt -bd %s/%s-%s-%s-backup-%s_recovery_emmc.zip %s/*' % (self.DIRECTORY, self.IMAGEDISTRO, self.DISTROVERSION, self.MODEL, self.DATE, self.MAINDESTROOT))
- elif SystemInfo["HasRootSubdir"]:
+ elif BoxInfo.getItem("HasRootSubdir"):
cmdlist.append('echo "rename this file to "force" to force an update without confirmation" > %s/unforce_%s.txt' % (self.MAINDESTROOT, self.MACHINEBUILD))
cmdlist.append('7za a -r -bt -bd %s/%s-%s-%s-backup-%s_mmc.zip %s/*' % (self.DIRECTORY, self.IMAGEDISTRO, self.DISTROVERSION, self.MODEL, self.DATE, self.MAINDESTROOT))
else:
@@ -573,7 +573,7 @@ def doFullBackupCB(self):
print("[Image Backup] %s file not found" % (self.KERNELBIN))
file_found = False
- if SystemInfo["canMultiBoot"] and not self.RECOVERY and not SystemInfo["HasRootSubdir"]:
+ if BoxInfo.getItem("canMultiBoot") and not self.RECOVERY and not BoxInfo.getItem("HasRootSubdir"):
cmdlist.append('echo "_________________________________________________\n"')
cmdlist.append('echo "' + _("Multiboot Image created on: %s/%s-%s-%s-backup-%s_usb.zip") % (self.DIRECTORY, self.IMAGEDISTRO, self.DISTROVERSION, self.MODEL, self.DATE) + '"')
cmdlist.append('echo "_________________________________________________"')
@@ -585,9 +585,9 @@ def doFullBackupCB(self):
elif file_found:
cmdlist.append('echo "_________________________________________________\n"')
- if SystemInfo["canRecovery"] and self.RECOVERY:
+ if BoxInfo.getItem("canRecovery") and self.RECOVERY:
cmdlist.append('echo "' + _("Image created on: %s/%s-%s-%s-backup-%s_recovery_emmc.zip") % (self.DIRECTORY, self.IMAGEDISTRO, self.DISTROVERSION, self.MODEL, self.DATE) + '"')
- elif SystemInfo["HasRootSubdir"]:
+ elif BoxInfo.getItem("HasRootSubdir"):
cmdlist.append('echo "' + _("Image created on: %s/%s-%s-%s-backup-%s_mmc.zip") % (self.DIRECTORY, self.IMAGEDISTRO, self.DISTROVERSION, self.MODEL, self.DATE) + '"')
else:
cmdlist.append('echo "' + _("Image created on: %s/%s-%s-%s-backup-%s_usb.zip") % (self.DIRECTORY, self.IMAGEDISTRO, self.DISTROVERSION, self.MODEL, self.DATE) + '"')
@@ -608,7 +608,7 @@ def doFullBackupCB(self):
cmdlist.append('echo " "')
cmdlist.append("rm -rf %s/build_%s" % (self.DIRECTORY, self.MODEL))
- if SystemInfo["HasRootSubdir"]:
+ if BoxInfo.getItem("HasRootSubdir"):
cmdlist.append("umount /tmp/bi/RootSubdir")
cmdlist.append("rmdir /tmp/bi/RootSubdir")
else:
diff --git a/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py b/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py
index a2afabfd74..5b5f3db1ad 100644
--- a/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py
+++ b/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py
@@ -4,7 +4,7 @@
from Components.Sources.CanvasSource import CanvasSource
from Components.ActionMap import ActionMap, NumberActionMap
from Components.Console import Console
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS
from enigma import gFont, getDesktop, gMainDC, eSize, RT_HALIGN_RIGHT, RT_WRAP
@@ -379,12 +379,12 @@ def testpic_gamma(self):
c.flush()
def testpic_overscan(self):
- self.next = SystemInfo["HasFullHDSkinSupport"] and self.testpic_fullhd or self.testpic_pixels
+ self.next = BoxInfo.getItem("HasFullHDSkinSupport") and self.testpic_fullhd or self.testpic_pixels
self.hide()
self.session.openWithCallback(self.testpicCallback, OverscanTestScreen)
def testpic_fullhd(self):
- if SystemInfo["HasFullHDSkinSupport"]:
+ if BoxInfo.getItem("HasFullHDSkinSupport"):
self.next = self.hasUHD and self.testpic_uhd or self.testpic_pixels
self.hide()
self.session.openWithCallback(self.testpicCallback, FullHDTestScreen)
diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py
index cfb6d0af11..f12bc3cdeb 100644
--- a/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py
+++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py
@@ -1,5 +1,5 @@
from Components.config import config, ConfigSelection, ConfigSubDict, ConfigYesNo
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Tools.CList import CList
from Tools.HardwareInfo import HardwareInfo
import os
@@ -73,13 +73,13 @@ class VideoHardware:
"1280x768": {60: "1280x768"},
"640x480": {60: "640x480"}}
- if SystemInfo["HasScart"]:
+ if BoxInfo.getItem("HasScart"):
modes["Scart"] = ["PAL", "NTSC", "Multi"]
- elif SystemInfo["HasComposite"]:
+ elif BoxInfo.getItem("HasComposite"):
modes["RCA"] = ["576i", "PAL", "NTSC", "Multi"]
- if SystemInfo["HasYPbPr"]:
+ if BoxInfo.getItem("HasYPbPr"):
modes["YPbPr"] = ["720p", "1080i", "576p", "480p", "576i", "480i"]
- if SystemInfo["Has2160p"]:
+ if BoxInfo.getItem("Has2160p"):
modes["DVI"] = ["720p", "1080p", "2160p", "1080i", "576p", "480p", "576i", "480i"]
else:
modes["DVI"] = ["720p", "1080p", "2160p", "2160p30", "1080i", "576p", "480p", "576i", "480i"]
@@ -221,7 +221,7 @@ def setMode(self, port, mode, rate, force=None):
except IOError:
print("[VideoHardware] writing initial videomode to /etc/videomode failed.")
- if SystemInfo["Has24hz"]:
+ if BoxInfo.getItem("Has24hz"):
try:
open("/proc/stb/video/videomode_24hz", "w").write(mode_24)
except IOError:
@@ -295,12 +295,12 @@ def createConfig(self, *args):
ratelist = []
for rate in rates:
if rate == "auto":
- if SystemInfo["Has24hz"]:
+ if BoxInfo.getItem("Has24hz"):
ratelist.append((rate, mode == "2160p30" and "auto (25Hz/30Hz/24Hz)" or "auto (50Hz/60Hz/24Hz)"))
else:
ratelist.append((rate, rate == "multi" and (mode == "2160p30" and "multi (25Hz/30Hz)" or "multi (50Hz/60Hz)") or rate))
config.av.videorate[mode] = ConfigSelection(choices=ratelist)
- config.av.videoport = ConfigSelection(choices=lst)
+ config.av.videoport = ConfigSelection(default="DVI", choices=lst)
def setConfiguredMode(self):
port = config.av.videoport.value
diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py
index 5d42e1bbfa..b0ced516dd 100644
--- a/lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py
+++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py
@@ -6,7 +6,7 @@
from Components.Pixmap import Pixmap
from Components.config import config, ConfigBoolean, configfile
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Tools.Directories import resolveFilename, SCOPE_PLUGINS
from Tools.HardwareInfo import HardwareInfo
@@ -152,7 +152,7 @@ def modeSelect(self, mode):
ratesList = self.listRates(mode)
print("[VideoWizard] ratesList:", ratesList)
if self.port == "DVI" and mode in ("720p", "1080i", "1080p", "2160p", "2160p30"):
- if SystemInfo["Has24hz"]:
+ if BoxInfo.getItem("Has24hz"):
self.rate = "auto"
self.hw.setMode(port=self.port, mode=mode, rate="auto")
else:
@@ -170,7 +170,7 @@ def listRates(self, querymode=None):
print("[VideoWizard] mode:", mode)
if mode[0] == querymode:
for rate in mode[1]:
- if rate in ("auto") and not SystemInfo["Has24hz"]:
+ if rate in ("auto") and not BoxInfo.getItem("Has24hz"):
continue
if self.port == "DVI-PC":
print("[VideoWizard] rate:", rate)
diff --git a/lib/python/Plugins/SystemPlugins/Videomode/plugin.py b/lib/python/Plugins/SystemPlugins/Videomode/plugin.py
index 7773d202f9..fed750052f 100644
--- a/lib/python/Plugins/SystemPlugins/Videomode/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/Videomode/plugin.py
@@ -1,6 +1,6 @@
from Screens.Screen import Screen
from Plugins.Plugin import PluginDescriptor
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.ConfigList import ConfigListScreen
from Components.config import config, ConfigBoolean, ConfigNothing
from Components.Label import Label
@@ -88,19 +88,19 @@ def createSetup(self):
if config.av.videoport.value == "DVI":
if level >= 1:
self.list.append((_("Allow unsupported modes"), config.av.edid_override, _("When selected this allows video modes to be selected even if they are not reported as supported.")))
- if SystemInfo["HasBypassEdidChecking"]:
+ if BoxInfo.getItem("HasBypassEdidChecking"):
self.list.append((_("Bypass HDMI EDID checking"), config.av.bypassEdidChecking, _("Configure if the HDMI EDID checking should be bypassed as this might solve issue with some TVs.")))
- if SystemInfo["HasColorspace"]:
+ if BoxInfo.getItem("HasColorspace"):
self.list.append((_("HDMI Colorspace"), config.av.hdmicolorspace, _("This option allows you to configure the Colorspace from Auto to RGB")))
- if SystemInfo["HasColordepth"]:
+ if BoxInfo.getItem("HasColordepth"):
self.list.append((_("HDMI Colordepth"), config.av.hdmicolordepth, _("This option allows you to configure the Colordepth for UHD")))
- if SystemInfo["HasColorimetry"]:
+ if BoxInfo.getItem("HasColorimetry"):
self.list.append((_("HDMI Colorimetry"), config.av.hdmicolorimetry, _("This option allows you to configure the Colorimetry for HDR.")))
- if SystemInfo["HasHdrType"]:
+ if BoxInfo.getItem("HasHdrType"):
self.list.append((_("HDMI HDR Type"), config.av.hdmihdrtype, _("This option allows you to configure the HDR type.")))
- if SystemInfo["HasHDMIpreemphasis"]:
+ if BoxInfo.getItem("HasHDMIpreemphasis"):
self.list.append((_("Use HDMI pre-emphasis"), config.av.hdmipreemphasis, _("This option can be useful for long HDMI cables.")))
- if SystemInfo["HDRSupport"]:
+ if BoxInfo.getItem("HDRSupport"):
self.list.append((_("HLG support"), config.av.hlg_support, _("This option allows you to force the HLG modes for UHD")))
self.list.append((_("HDR10 support"), config.av.hdr10_support, _("This option allows you to force the HDR10 modes for UHD")))
self.list.append((_("Allow 12bit"), config.av.allow_12bit, _("This option allows you to enable or disable the 12 bit color mode")))
@@ -110,10 +110,10 @@ def createSetup(self):
self.list.append((_("Color format"), config.av.colorformat, _("Configure which color format should be used on the SCART output.")))
if level >= 1:
self.list.append((_("WSS on 4:3"), config.av.wss, _("When enabled, content with an aspect ratio of 4:3 will be stretched to fit the screen.")))
- if SystemInfo["ScartSwitch"]:
+ if BoxInfo.getItem("ScartSwitch"):
self.list.append((_("Auto scart switching"), config.av.vcrswitch, _("When enabled, your receiver will detect activity on the VCR SCART input.")))
- if SystemInfo["CanChangeOsdAlpha"]:
+ if BoxInfo.getItem("CanChangeOsdAlpha"):
self.list.append((_("OSD transparency"), config.av.osd_alpha, _("Configure the transparency of the OSD.")))
if not isinstance(config.av.scaler_sharpness, ConfigNothing):
@@ -217,41 +217,41 @@ def createSetup(self):
self.list = []
if level >= 1:
self.list.append((_("Audio volume step size"), config.av.volume_stepsize, _("Configure the general audio volume step size (limit 1-10).")))
- if SystemInfo["CanDownmixAC3"]:
+ if BoxInfo.getItem("CanDownmixAC3"):
self.list.append((_("AC3 downmix"), config.av.downmix_ac3, _("Configure whether multi channel sound tracks should be downmixed to stereo.")))
- if SystemInfo["CanDownmixDTS"]:
+ if BoxInfo.getItem("CanDownmixDTS"):
self.list.append((_("DTS downmix"), config.av.downmix_dts, _("Configure whether multi channel sound tracks should be downmixed to stereo.")))
- if SystemInfo["CanDownmixAAC"]:
+ if BoxInfo.getItem("CanDownmixAAC"):
self.list.append((_("AAC downmix"), config.av.downmix_aac, _("Configure whether multi channel sound tracks should be downmixed to stereo.")))
- if SystemInfo["CanDownmixAACPlus"]:
+ if BoxInfo.getItem("CanDownmixAACPlus"):
self.list.append((_("AAC+ downmix"), config.av.downmix_aacplus, _("Choose whether multi channel aac+ sound tracks should be downmixed to stereo.")))
- if SystemInfo["CanAC3Transcode"]:
+ if BoxInfo.getItem("CanAC3Transcode"):
self.list.append((_("AC3 transcoding"), config.av.transcodeac3plus, _("Choose whether AC3 sound tracks should be transcoded.")))
- if SystemInfo["CanAACTranscode"]:
+ if BoxInfo.getItem("CanAACTranscode"):
self.list.append((_("AAC transcoding"), config.av.transcodeaac, _("Choose whether AAC sound tracks should be transcoded.")))
- if SystemInfo["CanDTSHD"]:
+ if BoxInfo.getItem("CanDTSHD"):
self.list.append((_("DTS-HD(HR/MA) downmix"), config.av.dtshd, _("Choose whether multi channel DTS-HD(HR/MA) sound tracks should be downmixed or transcoded.")))
- if SystemInfo["CanWMAPRO"]:
+ if BoxInfo.getItem("CanWMAPRO"):
self.list.append((_("WMA Pro downmix"), config.av.wmapro, _("Choose whether WMA Pro sound tracks should be downmixed.")))
- if SystemInfo["HasMultichannelPCM"]:
+ if BoxInfo.getItem("HasMultichannelPCM"):
self.list.append((_("Multichannel PCM"), config.av.multichannel_pcm, _("Configure whether multi channel PCM sound should be enabled.")))
self.list.extend((
(_("General AC3 delay"), config.av.generalAC3delay, _("Configure the general audio delay of Dolby Digital sound tracks.")),
(_("General PCM delay"), config.av.generalPCMdelay, _("Configure the general audio delay of stereo sound tracks."))
))
- if SystemInfo["CanBTAudio"]:
+ if BoxInfo.getItem("CanBTAudio"):
self.list.append((_("Enable bluetooth audio"), config.av.btaudio, _("This option allows you to switch audio to bluetooth speakers.")))
- if SystemInfo["CanBTAudioDelay"] and config.av.btaudio.value != "off":
+ if BoxInfo.getItem("CanBTAudioDelay") and config.av.btaudio.value != "off":
self.list.append((_("General bluetooth audio delay"), config.av.btaudiodelay, _("This option configures the general audio delay for bluetooth speakers.")))
- if SystemInfo["HasAutoVolume"] or SystemInfo["HasAutoVolumeLevel"]:
- self.list.append((_("Audio auto volume level"), SystemInfo["HasAutoVolume"] and config.av.autovolume or config.av.autovolumelevel, _("This option allows you can to set the auto volume level.")))
- if SystemInfo["Has3DSurround"]:
+ if BoxInfo.getItem("HasAutoVolume") or BoxInfo.getItem("HasAutoVolumeLevel"):
+ self.list.append((_("Audio auto volume level"), BoxInfo.getItem("HasAutoVolume") and config.av.autovolume or config.av.autovolumelevel, _("This option allows you can to set the auto volume level.")))
+ if BoxInfo.getItem("Has3DSurround"):
self.list.append((_("3D surround"), config.av.surround_3d, _("This option allows you to enable 3D surround sound.")))
- if SystemInfo["Has3DSpeaker"] and config.av.surround_3d.value != "none":
+ if BoxInfo.getItem("Has3DSpeaker") and config.av.surround_3d.value != "none":
self.list.append((_("3D surround speaker position"), config.av.speaker_3d, _("This option allows you to change the virtuell loadspeaker position.")))
- if SystemInfo["Has3DSurroundSpeaker"]:
+ if BoxInfo.getItem("Has3DSurroundSpeaker"):
self.list.append((_("3D surround speaker position"), config.av.surround_3d_speaker, _("This option allows you to disable or change the virtuell loadspeaker position.")))
- if SystemInfo["Has3DSurroundSoftLimiter"] and config.av.surround_3d_speaker.value != "disabled":
+ if BoxInfo.getItem("Has3DSurroundSoftLimiter") and config.av.surround_3d_speaker.value != "disabled":
self.list.append((_("3D surround softlimiter"), config.av.surround_softlimiter_3d, _("This option allows you to enable 3D surround softlimiter.")))
self["config"].list = self.list
diff --git a/lib/python/RecordTimer.py b/lib/python/RecordTimer.py
index 1faceb4813..dfdb8bb4c8 100644
--- a/lib/python/RecordTimer.py
+++ b/lib/python/RecordTimer.py
@@ -3,7 +3,7 @@
from Components.config import config
from Components.UsageConfig import defaultMoviePath
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.TimerSanityCheck import TimerSanityCheck
from Screens.MessageBox import MessageBox
@@ -195,27 +195,27 @@ def __init__(self, serviceref, begin, end, name, description, eit, disabled=Fals
self.external = self.external_prev = False
self.setAdvancedPriorityFrontend = None
self.background_zap = None
- if SystemInfo["DVB-T_priority_tuner_available"] or SystemInfo["DVB-C_priority_tuner_available"] or SystemInfo["DVB-S_priority_tuner_available"] or SystemInfo["ATSC_priority_tuner_available"]:
+ if BoxInfo.getItem("DVB-T_priority_tuner_available") or BoxInfo.getItem("DVB-C_priority_tuner_available") or BoxInfo.getItem("DVB-S_priority_tuner_available") or BoxInfo.getItem("ATSC_priority_tuner_available"):
rec_ref = self.service_ref and self.service_ref.ref
str_service = rec_ref and rec_ref.toString()
if str_service and '%3a//' not in str_service and not str_service.rsplit(":", 1)[1].startswith("/"):
type_service = rec_ref.getUnsignedData(4) >> 16
if type_service == 0xEEEE:
- if SystemInfo["DVB-T_priority_tuner_available"] and config.usage.recording_frontend_priority_dvbt.value != "-2":
+ if BoxInfo.getItem("DVB-T_priority_tuner_available") and config.usage.recording_frontend_priority_dvbt.value != "-2":
if config.usage.recording_frontend_priority_dvbt.value != config.usage.frontend_priority.value:
self.setAdvancedPriorityFrontend = config.usage.recording_frontend_priority_dvbt.value
- if SystemInfo["ATSC_priority_tuner_available"] and config.usage.recording_frontend_priority_atsc.value != "-2":
+ if BoxInfo.getItem("ATSC_priority_tuner_available") and config.usage.recording_frontend_priority_atsc.value != "-2":
if config.usage.recording_frontend_priority_atsc.value != config.usage.frontend_priority.value:
self.setAdvancedPriorityFrontend = config.usage.recording_frontend_priority_atsc.value
elif type_service == 0xFFFF:
- if SystemInfo["DVB-C_priority_tuner_available"] and config.usage.recording_frontend_priority_dvbc.value != "-2":
+ if BoxInfo.getItem("DVB-C_priority_tuner_available") and config.usage.recording_frontend_priority_dvbc.value != "-2":
if config.usage.recording_frontend_priority_dvbc.value != config.usage.frontend_priority.value:
self.setAdvancedPriorityFrontend = config.usage.recording_frontend_priority_dvbc.value
- if SystemInfo["ATSC_priority_tuner_available"] and config.usage.recording_frontend_priority_atsc.value != "-2":
+ if BoxInfo.getItem("ATSC_priority_tuner_available") and config.usage.recording_frontend_priority_atsc.value != "-2":
if config.usage.recording_frontend_priority_atsc.value != config.usage.frontend_priority.value:
self.setAdvancedPriorityFrontend = config.usage.recording_frontend_priority_atsc.value
else:
- if SystemInfo["DVB-S_priority_tuner_available"] and config.usage.recording_frontend_priority_dvbs.value != "-2":
+ if BoxInfo.getItem("DVB-S_priority_tuner_available") and config.usage.recording_frontend_priority_dvbs.value != "-2":
if config.usage.recording_frontend_priority_dvbs.value != config.usage.frontend_priority.value:
self.setAdvancedPriorityFrontend = config.usage.recording_frontend_priority_dvbs.value
self.needChangePriorityFrontend = self.setAdvancedPriorityFrontend is not None or config.usage.recording_frontend_priority.value != "-2" and config.usage.recording_frontend_priority.value != config.usage.frontend_priority.value
@@ -382,7 +382,7 @@ def do_backoff(self):
self.log(10, "backoff: retry in %d seconds" % self.backoff)
def sendactivesource(self):
- if SystemInfo["HasHDMI-CEC"] and config.hdmicec.enabled.value and config.hdmicec.sourceactive_zaptimers.value:
+ if BoxInfo.getItem("HasHDMI-CEC") and config.hdmicec.enabled.value and config.hdmicec.sourceactive_zaptimers.value:
import Components.HdmiCec
Components.HdmiCec.hdmi_cec.sendMessage(0, "sourceactive")
print("[TIMER] sourceactive was send")
@@ -490,7 +490,7 @@ def activate(self):
RecordTimerEntry.setWasInStandby()
notify = config.usage.show_message_when_recording_starts.value and self.InfoBarInstance and self.InfoBarInstance.execing
cur_ref = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
- pip_zap = self.pipzap or (cur_ref and cur_ref.getPath() and '%3a//' not in cur_ref.toString() and SystemInfo["PIPAvailable"])
+ pip_zap = self.pipzap or (cur_ref and cur_ref.getPath() and '%3a//' not in cur_ref.toString() and BoxInfo.getItem("PIPAvailable"))
if pip_zap:
cur_ref_group = NavigationInstance.instance.getCurrentlyPlayingServiceOrGroup()
if cur_ref_group and cur_ref_group != self.service_ref.ref and self.InfoBarInstance and hasattr(self.InfoBarInstance.session, 'pipshown') and not Components.ParentalControl.parentalControl.isProtected(self.service_ref.ref):
diff --git a/lib/python/Screens/About.py b/lib/python/Screens/About.py
index e171d5f615..90c9746323 100644
--- a/lib/python/Screens/About.py
+++ b/lib/python/Screens/About.py
@@ -13,7 +13,7 @@
from Components.Pixmap import MultiPixmap
from Components.Network import iNetwork
-from Components.SystemInfo import SystemInfo, BoxInfo
+from Components.SystemInfo import BoxInfo
from Components.Label import Label
from Components.ProgressBar import ProgressBar
@@ -171,7 +171,7 @@ def strip_non_ascii(boltversion):
AboutText += hddinfo
AboutText += '\n\n' + _("Uptime") + ": " + about.getBoxUptime()
- if SystemInfo["HasHDMI-CEC"] and config.hdmicec.enabled.value:
+ if BoxInfo.getItem("HasHDMI-CEC") and config.hdmicec.enabled.value:
address = config.hdmicec.fixed_physical_address.value if config.hdmicec.fixed_physical_address.value != "0.0.0.0" else _("not set")
AboutText += "\n\n" + _("HDMI-CEC address") + ": " + address
@@ -836,7 +836,12 @@ def run_console(self):
self["AboutScrollLabel"].setText("")
self.setTitle("%s - %s" % (_("Troubleshoot"), self.titles[self.commandIndex]))
command = self.commands[self.commandIndex]
- if command.startswith("cat "):
+ if command == "boxinfo":
+ text = ""
+ for item in BoxInfo.getItemsList():
+ text += '%s = %s %s%s' % (item, str(BoxInfo.getItem(item)), type(BoxInfo.getItem(item)), " [immutable]\n" if item in BoxInfo.getEnigmaInfoList() else "\n")
+ self["AboutScrollLabel"].setText(text)
+ elif command.startswith("cat "):
try:
self["AboutScrollLabel"].setText(open(command[4:], "r").read())
except:
@@ -863,8 +868,8 @@ def getLogFilesList(self):
return [x for x in sorted(glob.glob("/mnt/hdd/*.log"), key=lambda x: os.path.isfile(x) and os.path.getmtime(x))] + (os.path.isfile(home_root) and [home_root] or []) + (os.path.isfile(tmp) and [tmp] or [])
def updateOptions(self):
- self.titles = ["dmesg", "ifconfig", "df", "top", "ps", "messages"]
- self.commands = ["dmesg", "ifconfig", "df -h", "top -n 1", "ps -l", "cat /var/volatile/log/messages"]
+ self.titles = ["dmesg", "ifconfig", "df", "top", "ps", "messages", "enigma info", "BoxInfo"]
+ self.commands = ["dmesg", "ifconfig", "df -h", "top -n 1", "ps -l", "cat /var/volatile/log/messages", "cat /usr/lib/enigma.info", "boxinfo"]
install_log = "/home/root/autoinstall.log"
if os.path.isfile(install_log):
self.titles.append("%s" % install_log)
diff --git a/lib/python/Screens/AudioSelection.py b/lib/python/Screens/AudioSelection.py
index 1f3f6d0188..a7bae2f379 100644
--- a/lib/python/Screens/AudioSelection.py
+++ b/lib/python/Screens/AudioSelection.py
@@ -10,7 +10,7 @@
from Components.Label import Label
from Components.Sources.List import List
from Components.Sources.Boolean import Boolean
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.VolumeControl import VolumeControl
from Components.UsageConfig import originalAudioTracks, visuallyImpairedCommentary
from Components.Converter.ServiceInfo import StdAudioDesc
@@ -99,15 +99,15 @@ def fillList(self, arg=None):
service = self.session.nav.getCurrentService()
self.audioTracks = audio = service and service.audioTracks()
track_num = audio and audio.getNumberOfTracks() or 0
- if SystemInfo["CanDownmixAC3"] and track_num > 0 and config.usage.setup_level.index >= 1:
+ if BoxInfo.getItem("CanDownmixAC3") and track_num > 0 and config.usage.setup_level.index >= 1:
downmix_ac3_value = config.av.downmix_ac3.value
if downmix_ac3_value in ("downmix", "passthrough"):
self.settings.downmix = ConfigSelection(choices=[("downmix", _("Downmix")), ("passthrough", _("Passthrough"))], default=downmix_ac3_value)
self.settings.downmix.addNotifier(self.changeAC3Downmix, initial_call=False)
extra_text = " - AC3"
- if SystemInfo["CanDownmixDTS"]:
+ if BoxInfo.getItem("CanDownmixDTS"):
extra_text += ",DTS"
- if SystemInfo["CanDownmixAAC"]:
+ if BoxInfo.getItem("CanDownmixAAC"):
extra_text += ",AAC"
conflist.append((_("Multi channel downmix") + extra_text, self.settings.downmix))
self["key_red"].setBoolean(True)
@@ -269,10 +269,10 @@ def getSubtitleList(self):
def changeAC3Downmix(self, configElement):
config.av.downmix_ac3.value = configElement.value
config.av.downmix_ac3.save()
- if SystemInfo["CanDownmixDTS"]:
+ if BoxInfo.getItem("CanDownmixDTS"):
config.av.downmix_dts.value = configElement.value
config.av.downmix_dts.save()
- if SystemInfo["CanDownmixAAC"]:
+ if BoxInfo.getItem("CanDownmixAAC"):
config.av.downmix_aac.value = configElement.value
config.av.downmix_aac.save()
diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py
index e32401fbe4..c673359e23 100644
--- a/lib/python/Screens/ChannelSelection.py
+++ b/lib/python/Screens/ChannelSelection.py
@@ -6,6 +6,10 @@
from Screens.ScreenSaver import InfoBarScreenSaver
import Components.ParentalControl
from Components.Button import Button
+from Components.ConfigList import ConfigListScreen
+from Components.Label import Label
+from Components.Sources.Boolean import Boolean
+from Components.Pixmap import Pixmap
from Components.ServiceList import ServiceList, refreshServiceList
from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
from Components.MenuList import MenuList
@@ -13,7 +17,7 @@
profile("ChannelSelection.py 1")
from Screens.EpgSelection import EPGSelection
from enigma import eServiceReference, eEPGCache, eServiceCenter, eRCInput, eTimer, eDVBDB, iPlayableService, iServiceInformation, getPrevAsciiCode
-from Components.config import config, configfile, ConfigSubsection, ConfigText, ConfigYesNo
+from Components.config import config, configfile, ConfigSubsection, ConfigText, ConfigYesNo, ConfigSelection, ConfigText
from Tools.NumericalTextInput import NumericalTextInput
profile("ChannelSelection.py 2")
from Components.NimManager import nimmanager
@@ -26,7 +30,7 @@
from Components.Input import Input
profile("ChannelSelection.py 3")
from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.Sources.StaticText import StaticText
from Screens.InputBox import PinInput
from Screens.VirtualKeyBoard import VirtualKeyBoard
@@ -54,6 +58,68 @@
FLAG_CENTER_DVB_SUBS = 2048 #define in lib/dvb/idvb.h as dxNewFound = 64 and dxIsDedicated3D = 128
+class InsertService(ConfigListScreen, Screen):
+ def __init__(self, session):
+ Screen.__init__(self, session)
+ self.skinName = ["Setup"]
+ ConfigListScreen.__init__(self, [], session=session, on_change=self.changedEntry)
+
+ self["actions2"] = ActionMap(["SetupActions"],
+ {
+ "ok": self.run,
+ "cancel": boundFunction(self.close, None),
+ "save": self.run,
+ }, -2)
+
+ self["key_red"] = StaticText(_("Exit"))
+ self["key_green"] = StaticText(_("Save"))
+
+ self["description"] = Label("")
+ self["VKeyIcon"] = Boolean(False)
+ self["HelpWindow"] = Pixmap()
+ self["HelpWindow"].hide()
+
+ self.createConfig()
+ self.changedEntry()
+
+ def createConfig(self):
+ choices = [("Select Service", _("Select Service"))]
+ if BoxInfo.getItem("HasHDMIin"):
+ choices = [("HDMI-in", _("HDMI-In"))]
+ choices.append(("IPTV stream", _("Enter URL")))
+ self.servicetype = ConfigSelection(choices=choices)
+ self.streamtype = ConfigSelection(["1", "4097", "5001", "5002"])
+ self.streamurl = ConfigText("http://some_url_to_stream")
+ self.servicename = ConfigText("default_name")
+
+ def createSetup(self):
+ self.list = []
+ self.list.append((_("Service Type"), self.servicetype, _("Select service type")))
+ if self.servicetype.value != "Select Service":
+ if self.servicetype.value != "HDMI-in":
+ self.list.append((_("Stream Type"), self.streamtype, _("Select stream type")))
+ self.list.append((_("Stream URL"), self.streamurl, _("Select stream URL")))
+ self.list.append((_("Service Name"), self.servicename, _("Select service name")))
+ self["config"].list = self.list
+
+ def changedEntry(self):
+ if self.servicetype.value == "HDMI-in":
+ self.servicerefstring = '8192:0:1:0:0:0:0:0:0:0::%s' % self.servicename.value
+ else:
+ self.servicerefstring = '%s:0:1:0:0:0:0:0:0:0:%s:%s' % (self.streamtype.value, self.streamurl.value.replace(':', '%3a'), self.servicename.value)
+ Screen.setTitle(self, '%s [%s]' % (_("Insert Service"), self.servicerefstring))
+ self.createSetup()
+
+ def run(self):
+ if self.servicetype.value == "Select Service":
+ self.session.openWithCallback(self.channelSelectionCallback, SimpleChannelSelection, _("Select channel"))
+ else:
+ self.close(eServiceReference(self.servicerefstring))
+
+ def channelSelectionCallback(self, *args):
+ if len(args):
+ self.close(args[0])
+
def getStreamRelayRef(sref):
try:
if "http" in sref:
@@ -156,6 +222,7 @@ def __init__(self, session, csel):
"1": self.unhideParentalServices,
"2": self.renameEntry,
"3": self.findCurrentlyPlayed,
+ "4": self.insertEntry,
"5": self.addServiceToBouquetOrAlternative,
"6": self.toggleMoveModeSelect,
"8": self.removeEntry
@@ -169,7 +236,7 @@ def __init__(self, session, csel):
current_root = csel.getRoot()
current_sel_path = current.getPath()
current_sel_flags = current.flags
- inBouquetRootList = current_root and 'FROM BOUQUET "bouquets.' in current_root.getPath() #FIXME HACK
+ self.inBouquetRootList = current_root and 'FROM BOUQUET "bouquets.' in current_root.getPath() #FIXME HACK
inAlternativeList = current_root and 'FROM BOUQUET "alternatives' in current_root.getPath()
self.inBouquet = csel.getMutableList() is not None
haveBouquets = config.usage.multibouquet.value
@@ -180,7 +247,7 @@ def __init__(self, session, csel):
if not (current_sel_path or current_sel_flags & (eServiceReference.isDirectory | eServiceReference.isMarker)) or current_sel_flags & eServiceReference.isGroup:
append_when_current_valid(current, menu, (_("Show transponder info"), self.showServiceInformations), level=2)
if csel.bouquet_mark_edit == OFF and not csel.entry_marked:
- if not inBouquetRootList:
+ if not self.inBouquetRootList:
isPlayable = not (current_sel_flags & (eServiceReference.isMarker | eServiceReference.isDirectory))
if isPlayable:
for p in plugins.getPlugins(PluginDescriptor.WHERE_CHANNEL_CONTEXT_MENU):
@@ -199,7 +266,7 @@ def __init__(self, session, csel):
append_when_current_valid(current, menu, (_("Remove from parental protection"), boundFunction(self.removeParentalProtection, current)), level=0)
if self.parentalControl.blacklist and config.ParentalControl.hideBlacklist.value and not self.parentalControl.sessionPinCached and config.ParentalControl.storeservicepin.value != "never":
append_when_current_valid(current, menu, (_("Unhide parental control services"), self.unhideParentalServices), level=0, key="1")
- if SystemInfo["3DMode"] and isPluginInstalled("OSD3DSetup"):
+ if BoxInfo.getItem("3DMode") and isPluginInstalled("OSD3DSetup"):
if eDVBDB.getInstance().getFlag(eServiceReference(current.toString())) & FLAG_IS_DEDICATED_3D:
append_when_current_valid(current, menu, (_("Unmark service as dedicated 3D service"), self.removeDedicated3DFlag), level=0)
else:
@@ -235,7 +302,7 @@ def __init__(self, session, csel):
if not self.inBouquet:
append_when_current_valid(current, menu, (_("Add service to favourites"), self.addServiceToBouquetSelected), level=0, key="5")
self.addFunction = self.addServiceToBouquetSelected
- if SystemInfo["PIPAvailable"]:
+ if BoxInfo.getItem("PIPAvailable"):
self.PiPAvailable = True
if self.csel.dopipzap:
append_when_current_valid(current, menu, (_("Play in main window"), self.playMain), level=0, key="red")
@@ -261,6 +328,8 @@ def __init__(self, session, csel):
if not inAlternativeList:
append_when_current_valid(current, menu, (_("Remove entry"), self.removeEntry), level=0, key="8")
self.removeFunction = self.removeCurrentService
+ if config.usage.setup_level.index >= 2:
+ menu.append(ChoiceEntryComponent("4", (_("Insert entry"), self.insertService)))
if current_root and ("flags == %d" % (FLAG_SERVICE_NEW_FOUND)) in current_root.getPath():
append_when_current_valid(current, menu, (_("Remove new found flag"), self.removeNewFoundFlag), level=0)
else:
@@ -271,13 +340,19 @@ def __init__(self, session, csel):
append_when_current_valid(current, menu, (_("Add bouquet to parental protection"), boundFunction(self.addParentalProtection, current)), level=0)
else:
append_when_current_valid(current, menu, (_("Remove bouquet from parental protection"), boundFunction(self.removeParentalProtection, current)), level=0)
- menu.append(ChoiceEntryComponent("dummy", (_("Add bouquet"), self.showBouquetInputBox)))
+ menu.append(ChoiceEntryComponent("4", (_("Add bouquet"), self.showBouquetInputBox)))
append_when_current_valid(current, menu, (_("Rename entry"), self.renameEntry), level=0, key="2")
append_when_current_valid(current, menu, (_("Remove entry"), self.removeEntry), level=0, key="8")
self.removeFunction = self.removeBouquet
if removed_userbouquets_available():
append_when_current_valid(current, menu, (_("Purge deleted user bouquets"), self.purgeDeletedBouquets), level=0)
append_when_current_valid(current, menu, (_("Restore deleted user bouquets"), self.restoreDeletedBouquets), level=0)
+ if('FROM BOUQUET' in current.toString()):
+ if Screens.InfoBar.InfoBar.instance.checkBouquets(current):
+ append_when_current_valid(current, menu, (_("Unpin Userbouquet"), self.toggleBouquet), level=2)
+ else:
+ append_when_current_valid(current, menu, (_("Pin Userbouquet"), self.toggleBouquet), level=2)
+ append_when_current_valid(current, menu, (_("Reload services/bouquets list"), self.reloadServicesBouquets), level=2)
if self.inBouquet: # current list is editable?
if csel.bouquet_mark_edit == OFF:
if csel.movemode:
@@ -287,7 +362,7 @@ def __init__(self, session, csel):
if csel.entry_marked and not inAlternativeList:
append_when_current_valid(current, menu, (_("Remove entry"), self.removeEntry), level=0, key="8")
self.removeFunction = self.removeCurrentService
- if not csel.entry_marked and not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
+ if not csel.entry_marked and not self.inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
if current.type != -1:
menu.append(ChoiceEntryComponent("dummy", (_("Add marker"), self.showMarkerInputBox)))
if not csel.movemode:
@@ -321,6 +396,12 @@ def __init__(self, session, csel):
menu.append(ChoiceEntryComponent("menu", (_("Configuration"), self.openSetup)))
self["menu"] = ChoiceList(menu)
+ def insertEntry(self):
+ if self.inBouquetRootList:
+ self.showBouquetInputBox()
+ else:
+ self.insertService()
+
def set3DMode(self, value):
playingref = self.session.nav.getCurrentlyPlayingServiceReference()
if config.plugins.OSD3DSetup.mode.value == "auto" and (playingref and playingref == self.csel.getCurrentSelection()):
@@ -344,6 +425,10 @@ def toggleVBI(self):
Screens.InfoBar.InfoBar.instance.showHideVBI()
self.close()
+ def toggleBouquet(self):
+ Screens.InfoBar.InfoBar.instance.ToggleBouquet(self.csel.getCurrentSelection().toString().split('"')[1])
+ self.close()
+
def toggleStreamrelay(self):
from Screens.InfoBarGenerics import streamrelay
streamrelay.toggle(self.session.nav, self.csel.getCurrentSelection())
@@ -386,6 +471,14 @@ def getCurrentSelectionName(self):
return name
return ""
+ def insertService(self):
+ self.session.openWithCallback(self.insertServiceCallback, InsertService)
+
+ def insertServiceCallback(self, answer):
+ if answer:
+ self.csel.insertService(answer)
+ self.close()
+
def removeEntry(self):
currentPlayingService = (hasattr(self.csel, "dopipzap") and self.csel.dopipzap) and self.session.pip.getCurrentService() or self.session.nav.getCurrentlyPlayingServiceOrGroup()
if self.removeFunction and self.csel.servicelist.getCurrent() and self.csel.servicelist.getCurrent().valid() and (self.csel.servicelist.getCurrent() != currentPlayingService):
@@ -481,8 +574,7 @@ def showServiceInformations(self):
current = self.session.nav.getCurrentlyPlayingServiceReference()
else:
current = eServiceReference(GetWithAlternative(current.toString()))
- self.session.open(ServiceInfo, current)
- self.close()
+ self.session.openWithCallback(self.close, ServiceInfo, current)
def setStartupService(self):
self.session.openWithCallback(self.setStartupServiceCallback, MessageBox, _("Set startup service"), list=[(_("Only on startup"), "startup"), (_("Also on standby"), "standby")])
@@ -987,6 +1079,15 @@ def renameEntryCallback(self, name):
if not self.servicelist.atEnd():
self.servicelist.moveUp()
+ def insertService(self, serviceref):
+ current = self.servicelist.getCurrent()
+ mutableList = self.getMutableList()
+ if mutableList:
+ if not mutableList.addService(serviceref, current):
+ mutableList.flushChanges()
+ self.servicelist.addService(serviceref, True)
+ self.servicelist.resetRoot()
+
def addMarker(self, name):
current = self.servicelist.getCurrent()
mutableList = self.getMutableList()
@@ -1969,6 +2070,7 @@ def __init__(self, session):
"ok": self.channelSelected,
"keyRadio": self.doRadioButton,
"keyTV": self.doTVButton,
+ "toggleTvRadio": self.toggleTVRadio,
})
self.__event_tracker = ServiceEventTracker(screen=self, eventmap={
@@ -2076,6 +2178,12 @@ def setModeRadio(self):
self.setRadioMode()
self.setMode()
+ def toggleTVRadio(self):
+ if self.mode == MODE_TV:
+ self.doRadioButton()
+ else:
+ self.doTVButton()
+
def __onCreate(self):
if config.usage.e1like_radio_mode.value:
if config.servicelist.lastmode.value == "tv":
@@ -2649,6 +2757,7 @@ def __init__(self, session, title, currentBouquet=False, returnBouquet=False, se
"ok": self.channelSelected,
"keyRadio": self.setModeRadio,
"keyTV": self.setModeTv,
+ "toggleTvRadio": self.toggleTVRadio,
})
self.bouquet_mark_edit = OFF
if isinstance(title, str):
@@ -2695,5 +2804,11 @@ def setModeRadio(self):
self.setRadioMode()
self.showFavourites()
+ def toggleTVRadio(self):
+ if self.mode == MODE_TV :
+ self.setModeRadio()
+ else:
+ self.setModeTv()
+
def getMutableList(self, root=None):
return None
diff --git a/lib/python/Screens/Ci.py b/lib/python/Screens/Ci.py
index 0595cf21fc..a0304ddcb2 100644
--- a/lib/python/Screens/Ci.py
+++ b/lib/python/Screens/Ci.py
@@ -5,13 +5,14 @@
from Components.Label import Label
from Components.Pixmap import Pixmap
from Components.Sources.StaticText import StaticText
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.config import config, ConfigSubsection, ConfigSelection, ConfigSubList, KEY_LEFT, KEY_RIGHT, KEY_0, ConfigNothing, ConfigPIN, \
ConfigYesNo, NoSave
from Screens.MessageBox import MessageBox
from Tools.BoundFunction import boundFunction
-from enigma import eTimer, eDVBCI_UI, eDVBCIInterfaces
+from enigma import eTimer, eDVBCI_UI
+from os.path import exists
from Screens.Screen import Screen
forceNotShowCiMessages = False
@@ -22,34 +23,40 @@ def setCIBitrate(configElement):
def setdvbCiDelay(configElement):
- open(SystemInfo["CommonInterfaceCIDelay"], "w").write(configElement.value)
+ open(BoxInfo.getItem("CommonInterfaceCIDelay"), "w").write(configElement.value)
configElement.save()
def setRelevantPidsRouting(configElement):
- open(SystemInfo["CI%dRelevantPidsRoutingSupport" % configElement.slotid], "w").write("yes" if configElement.value else "no")
+ open(BoxInfo.getItem("CI%dRelevantPidsRoutingSupport" % configElement.slotid), "w").write("yes" if configElement.value else "no")
def InitCiConfig():
config.ci = ConfigSubList()
config.cimisc = ConfigSubsection()
- if SystemInfo["CommonInterface"]:
- for slot in list(range(SystemInfo["CommonInterface"])):
+ if BoxInfo.getItem("CommonInterface"):
+ for slot in range(BoxInfo.getItem("CommonInterface")):
config.ci.append(ConfigSubsection())
config.ci[slot].canDescrambleMultipleServices = ConfigSelection(choices=[("auto", _("auto")), ("no", _("no")), ("yes", _("yes"))], default="auto")
config.ci[slot].use_static_pin = ConfigYesNo(default=True)
config.ci[slot].static_pin = ConfigPIN(default=0)
config.ci[slot].show_ci_messages = ConfigYesNo(default=True)
- if SystemInfo["CI%dSupportsHighBitrates" % slot]:
- config.ci[slot].canHandleHighBitrates = ConfigYesNo(default=True)
- config.ci[slot].canHandleHighBitrates.slotid = slot
- config.ci[slot].canHandleHighBitrates.addNotifier(setCIBitrate)
- if SystemInfo["CI%dRelevantPidsRoutingSupport" % slot]:
+ if BoxInfo.getItem("CI%dSupportsHighBitrates" % slot):
+ highBitrateChoices = [("normal", _("normal")), ("high", _("high"))]
+ if exists("/proc/stb/tsmux/ci%d_tsclk_choices" % slot):
+ with open("/proc/stb/tsmux/ci%d_tsclk_choices" % slot) as fd:
+ choices = fd.read()
+ if "extra_high" in choices:
+ highBitrateChoices.append(("extra_high", _("extra high")))
+ config.ci[slot].highBitrate = ConfigSelection(default="high", choices=highBitrateChoices)
+ config.ci[slot].highBitrate.slotid = slot
+ config.ci[slot].highBitrate.addNotifier(setCIBitrate)
+ if BoxInfo.getItem("CI%dRelevantPidsRoutingSupport" % slot):
config.ci[slot].relevantPidsRouting = ConfigYesNo(default=False)
config.ci[slot].relevantPidsRouting.slotid = slot
config.ci[slot].relevantPidsRouting.addNotifier(setRelevantPidsRouting)
- if SystemInfo["CommonInterfaceCIDelay"]:
- config.cimisc.dvbCiDelay = ConfigSelection(default="256", choices=[("16"), ("32"), ("64"), ("128"), ("256")])
+ if BoxInfo.getItem("CommonInterfaceCIDelay"):
+ config.cimisc.dvbCiDelay = ConfigSelection(default="256", choices=[("16", "16"), ("32", "32"), ("64", "64"), ("128", "128"), ("256", "256")])
config.cimisc.dvbCiDelay.addNotifier(setdvbCiDelay)
@@ -383,7 +390,7 @@ def __init__(self, session):
self.state = {}
self.list = []
self.slot = 0
- for slot in list(range(SystemInfo["CommonInterface"])):
+ for slot in range(BoxInfo.getItem("CommonInterface")):
state = eDVBCI_UI.getInstance().getState(slot)
if state != -1:
self.slot += 1
@@ -445,11 +452,11 @@ def appendEntries(self, slot, state):
self.list.append((_("Reset persistent PIN code"), ConfigNothing(), 6, slot))
self.list.append((_("Show CI messages"), config.ci[slot].show_ci_messages, 3, slot))
self.list.append((_("Multiple service support"), config.ci[slot].canDescrambleMultipleServices, 3, slot))
- if SystemInfo["CI%dSupportsHighBitrates" % slot]:
- self.list.append((_("High bitrate support"), config.ci[slot].canHandleHighBitrates, 3, slot))
- if SystemInfo["CI%dRelevantPidsRoutingSupport" % slot]:
+ if BoxInfo.getItem("CI%dSupportsHighBitrates" % slot):
+ self.list.append((_("High bitrate support"), config.ci[slot].highBitrate, 3, slot))
+ if BoxInfo.getItem("CI%dRelevantPidsRoutingSupport" % slot):
self.list.append((_("PID Filtering"), config.ci[slot].relevantPidsRouting, 3, slot))
- if SystemInfo["CommonInterfaceCIDelay"]:
+ if BoxInfo.getItem("CommonInterfaceCIDelay"):
self.list.append((_("DVB CI Delay"), config.cimisc.dvbCiDelay, 3, slot))
def updateState(self, slot):
@@ -515,7 +522,7 @@ def cancelCB(self, value):
pass
def cancel(self):
- for slot in list(range(SystemInfo["CommonInterface"])):
+ for slot in range(BoxInfo.getItem("CommonInterface")):
state = eDVBCI_UI.getInstance().getState(slot)
if state != -1:
CiHandler.unregisterCIMessageHandler(slot)
diff --git a/lib/python/Screens/Dish.py b/lib/python/Screens/Dish.py
index 72f5019fa3..8f962fc40c 100644
--- a/lib/python/Screens/Dish.py
+++ b/lib/python/Screens/Dish.py
@@ -8,7 +8,7 @@
from Components.ServiceEventTracker import ServiceEventTracker
from enigma import eDVBSatelliteEquipmentControl, eTimer, iPlayableService, eServiceCenter, iServiceInformation
from Components.NimManager import nimmanager
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.Sources.FrontendStatus import FrontendStatus
INVALID_POSITION = 9999
@@ -127,7 +127,7 @@ def __onHide(self):
def __serviceStarted(self):
if self.__state == self.STATE_SHOWN:
self.hide()
- if SystemInfo["isRotorTuner"] and self.showdish:
+ if BoxInfo.getItem("isRotorTuner") and self.showdish:
service = self.session.nav.getCurrentService()
info = service and service.info()
data = info and info.getInfoObject(iServiceInformation.sTransponderData)
@@ -302,7 +302,7 @@ def updateRotorMovingState(self):
if self.__state == self.STATE_HIDDEN:
self.rotorTimer.stop()
self.moving_timeout = 0
- if config.usage.showdish.value and SystemInfo["isRotorTuner"]:
+ if config.usage.showdish.value and BoxInfo.getItem("isRotorTuner"):
self.show()
if self.cur_orbpos != INVALID_POSITION and self.cur_orbpos != config.misc.lastrotorposition.value:
config.misc.lastrotorposition.value = self.cur_orbpos
@@ -329,7 +329,7 @@ def turnTimerLoop(self):
def startPiPService(self, ref=None):
if self.__state == self.STATE_SHOWN:
self.__toHide()
- if ref and SystemInfo["isRotorTuner"]:
+ if ref and BoxInfo.getItem("isRotorTuner"):
info = eServiceCenter.getInstance().info(ref)
data = info and info.getInfoObject(ref, iServiceInformation.sTransponderData)
if not data or data == -1:
diff --git a/lib/python/Screens/FlashImage.py b/lib/python/Screens/FlashImage.py
index d81ddeaa31..678bce81df 100644
--- a/lib/python/Screens/FlashImage.py
+++ b/lib/python/Screens/FlashImage.py
@@ -10,7 +10,7 @@
from Components.Label import Label
from Components.Pixmap import Pixmap
from Components.ProgressBar import ProgressBar
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Plugins.SystemPlugins.SoftwareManager.BackupRestore import BackupScreen, RestoreScreen, getBackupFilename, getBackupPath
from Tools.BoundFunction import boundFunction
from Tools.Directories import resolveFilename, SCOPE_PLUGINS, fileExists, pathExists, fileHas
@@ -52,7 +52,7 @@ def __init__(self, session, *args):
self.setTitle(_("Select image"))
self["key_red"] = StaticText(_("Cancel"))
self["key_green"] = StaticText()
- self["key_yellow"] = StaticText(_("Initialize Multiboot")) if SystemInfo["canKexec"] else StaticText()
+ self["key_yellow"] = StaticText(_("Initialize Multiboot")) if BoxInfo.getItem("canKexec") else StaticText()
self["key_blue"] = StaticText()
self["description"] = Label()
self["list"] = ChoiceList(list=[ChoiceEntryComponent('', ((_("Retrieving image list - Please wait...")), "Waiter"))])
@@ -201,7 +201,7 @@ def keyYellow(self):
self.getImagesList()
except:
self.session.open(MessageBox, _("Cannot delete downloaded image"), MessageBox.TYPE_ERROR, timeout=3)
- elif SystemInfo["canKexec"]:
+ elif BoxInfo.getItem("canKexec"):
self.session.open(KexecInit)
def otherImages(self):
@@ -218,7 +218,7 @@ def otherImagesCallback(self, image):
def selectionChanged(self):
currentSelected = self["list"].l.getCurrentSelection()
if "://" in currentSelected[0][1] or currentSelected[0][1] in ["Expander", "Waiter"]:
- self["key_yellow"].setText(_("Initialize Multiboot") if SystemInfo["canKexec"] else "")
+ self["key_yellow"].setText(_("Initialize Multiboot") if BoxInfo.getItem("canKexec") else "")
else:
self["key_yellow"].setText(_("Delete image"))
if currentSelected[0][1] == "Waiter":
@@ -288,12 +288,12 @@ def confirmation(self):
self.message = _("%s\nDo you still want to flash image\n%s?") % (self.reasons, self.imagename)
else:
self.message = _("Do you want to flash image\n%s?") % self.imagename
- if SystemInfo["canMultiBoot"]:
+ if BoxInfo.getItem("canMultiBoot"):
self.message = _("Where do you want to flash image\n%s to?") % self.imagename
imagesList = getImagelist()
currentimageslot = getCurrentImage()
choices = []
- slotdict = {k: v for k, v in SystemInfo["canMultiBoot"].items() if not v['device'].startswith('/dev/sda')}
+ slotdict = {k: v for k, v in BoxInfo.getItem("canMultiBoot").items() if not v['device'].startswith('/dev/sda')}
for x in range(1, len(slotdict) + 1):
choices.append(((_("slot%s - %s (current image)") if x == currentimageslot else _("slot%s - %s")) % (x, imagesList[x]['imagename']), (x, "with backup") if getImageDistro() in self.imagename else (x, "without backup")))
if "://" in self.source:
@@ -309,7 +309,7 @@ def confirmation(self):
def checkMedia(self, retval):
if retval:
- if SystemInfo["canMultiBoot"]:
+ if BoxInfo.getItem("canMultiBoot"):
global multibootslot
multibootslot = retval[0]
self.onlyDownload = retval[1] == "only download"
@@ -430,7 +430,7 @@ def findimagefiles(path):
return checkimagefiles(files) and path
imagefiles = findimagefiles(self.unzippedimage)
if imagefiles:
- if SystemInfo["canMultiBoot"]:
+ if BoxInfo.getItem("canMultiBoot"):
global multibootslot
command = "/usr/bin/ofgwrite -k -r -m%s '%s'" % (multibootslot, imagefiles)
else:
@@ -444,7 +444,7 @@ def FlashimageDone(self, data, retval, extra_args):
self.containerofgwrite = None
if retval == 0:
self["header"].setText(_("Flashing image successful"))
- if SystemInfo["canMultiBoot"]:
+ if BoxInfo.getItem("canMultiBoot"):
self.restore()
self["info"].setText(_("%s\nPress ok for multiboot selection\nPress exit to close") % self.imagename)
else:
@@ -470,9 +470,9 @@ def restore(self):
# mount point
self.tmp_dir = tempfile.mkdtemp(prefix="MultibootSelection")
# Actual data directory (differs in case of rootsubdir)
- self.image_dir = os.sep.join(filter(None, [self.tmp_dir, SystemInfo["canMultiBoot"][multibootslot].get('rootsubdir', '')]))
+ self.image_dir = os.sep.join(filter(None, [self.tmp_dir, BoxInfo.getItem("canMultiBoot")[multibootslot].get('rootsubdir', '')]))
if os.path.exists("/media/hdd/images/config/settings"):
- Console().ePopen('mount %s %s' % (SystemInfo["canMultiBoot"][multibootslot]['device'], self.tmp_dir))
+ Console().ePopen('mount %s %s' % (BoxInfo.getItem("canMultiBoot")[multibootslot]['device'], self.tmp_dir))
self.restore_settings(self.tmp_dir, self.image_dir)
def restore_settings(self, tmpdir, image_dir):
@@ -622,7 +622,7 @@ def __init__(self, session, *args):
self.blue = False
self.currentimageslot = getCurrentImage()
self.tmp_dir = tempfile.mkdtemp(prefix="MultibootSelection")
- Console().ePopen('mount %s %s' % (SystemInfo["MultibootStartupDevice"], self.tmp_dir))
+ Console().ePopen('mount %s %s' % (BoxInfo.getItem("MultibootStartupDevice"), self.tmp_dir))
self.getImagesList()
def cancel(self, value=None):
@@ -646,7 +646,7 @@ def getImagesList(self):
if imagesList[x]["imagename"] == _("Deleted image"):
self.deletedImagesExists = True
elif imagesList[x]["imagename"] != _("Empty slot"):
- if SystemInfo["canMode12"]:
+ if BoxInfo.getItem("canMode12"):
list.insert(index, ChoiceEntryComponent('', ((_("slot%s - %s mode 1 (current image)") if x == self.currentimageslot and mode != 12 else _("slot%s - %s mode 1")) % (x, imagesList[x]['imagename']), (x, 1))))
list12.insert(index, ChoiceEntryComponent('', ((_("slot%s - %s mode 12 (current image)") if x == self.currentimageslot and mode == 12 else _("slot%s - %s mode 12")) % (x, imagesList[x]['imagename']), (x, 12))))
else:
@@ -659,16 +659,21 @@ def getImagesList(self):
list = sorted(list) if config.usage.multiboot_order.value else list
if os.path.isfile(os.path.join(self.tmp_dir, "STARTUP_RECOVERY")):
- recovery_text = _("Boot to Recovery menu")
- if SystemInfo["hasKexec"]:
- recovery_text = _("Boot to Recovery image - slot0 %s") % (fileHas("/proc/cmdline", "rootsubdir=linuxrootfs0") and _("(current)") or "")
+ if BoxInfo.getItem("hasKexec"):
+ recovery_booted = fileHas("/proc/cmdline", "rootsubdir=linuxrootfs0")
self["description"].setText(_("Attention - forced loading recovery image!\nCreate an empty STARTUP_RECOVERY file at the root of your HDD/USB drive and hold the Power button for more than 12 seconds for reboot receiver!"))
- list.append(ChoiceEntryComponent('', (recovery_text, "Recovery")))
+ list.append(ChoiceEntryComponent('', (_("Boot to Recovery image - slot0 %s") % (recovery_booted and _("(current image)") or ""), "Recovery")))
+ else:
+ list.append(ChoiceEntryComponent('', (_("Boot to Recovery menu"), "Recovery")))
if os.path.isfile(os.path.join(self.tmp_dir, "STARTUP_ANDROID")):
list.append(ChoiceEntryComponent('', ((_("Boot to Android image")), "Android")))
if not list:
list.append(ChoiceEntryComponent('', ((_("No images found")), "Waiter")))
self["list"].setList(list)
+ for index, slot in enumerate(list):
+ if type(slot[0][1]) is tuple and self.currentimageslot == slot[0][1][0] and (not BoxInfo.getItem("canMode12") or mode == slot[0][1][1]) or BoxInfo.getItem("hasKexec") and slot[0][1] == "Recovery" and recovery_booted:
+ self["list"].moveToIndex(index)
+ break
self.selectionChanged()
def deleteImage(self):
@@ -702,15 +707,15 @@ def doReboot(self, answer):
shutil.copyfile(os.path.join(self.tmp_dir, "STARTUP_RECOVERY"), os.path.join(self.tmp_dir, "STARTUP"))
elif slot == "Android":
shutil.copyfile(os.path.join(self.tmp_dir, "STARTUP_ANDROID"), os.path.join(self.tmp_dir, "STARTUP"))
- elif SystemInfo["canMultiBoot"][slot[0]]['startupfile']:
- if SystemInfo["canMode12"]:
- startupfile = os.path.join(self.tmp_dir, "%s_%s" % (SystemInfo["canMultiBoot"][slot[0]]['startupfile'].rsplit('_', 1)[0], slot[1]))
+ elif BoxInfo.getItem("canMultiBoot")[slot[0]]['startupfile']:
+ if BoxInfo.getItem("canMode12"):
+ startupfile = os.path.join(self.tmp_dir, "%s_%s" % (BoxInfo.getItem("canMultiBoot")[slot[0]]['startupfile'].rsplit('_', 1)[0], slot[1]))
else:
- startupfile = os.path.join(self.tmp_dir, "%s" % SystemInfo["canMultiBoot"][slot[0]]['startupfile'])
- if SystemInfo["canDualBoot"]:
+ startupfile = os.path.join(self.tmp_dir, "%s" % BoxInfo.getItem("canMultiBoot")[slot[0]]['startupfile'])
+ if BoxInfo.getItem("canDualBoot"):
with open('/dev/block/by-name/flag', 'wb') as f:
f.write(struct.pack("B", int(slot[0])))
- startupfile = os.path.join("/boot", "%s" % SystemInfo["canMultiBoot"][slot[0]]['startupfile'])
+ startupfile = os.path.join("/boot", "%s" % BoxInfo.getItem("canMultiBoot")[slot[0]]['startupfile'])
shutil.copyfile(startupfile, os.path.join("/boot", "STARTUP"))
else:
shutil.copyfile(startupfile, os.path.join(self.tmp_dir, "STARTUP"))
@@ -719,7 +724,7 @@ def doReboot(self, answer):
if slot[1] == 1:
startupFileContents = "boot emmcflash0.kernel%s 'root=/dev/mmcblk0p%s rw rootwait %s_4.boxmode=1'\n" % (slot[0], slot[0] * 2 + 1, model)
else:
- startupFileContents = "boot emmcflash0.kernel%s 'brcm_cma=520M@248M brcm_cma=%s@768M root=/dev/mmcblk0p%s rw rootwait %s_4.boxmode=12'\n" % (slot[0], SystemInfo["canMode12"], slot[0] * 2 + 1, model)
+ startupFileContents = "boot emmcflash0.kernel%s 'brcm_cma=520M@248M brcm_cma=%s@768M root=/dev/mmcblk0p%s rw rootwait %s_4.boxmode=12'\n" % (slot[0], BoxInfo.getItem("canMode12"), slot[0] * 2 + 1, model)
open(os.path.join(self.tmp_dir, "STARTUP"), 'w').write(startupFileContents)
self.cancel(2)
@@ -753,7 +758,7 @@ def __init__(self, session, *args):
def RootInit(self):
self["actions"].setEnabled(False) # This function takes time so disable the ActionMap to avoid responding to multiple button presses
if self.kexec_files:
- modelMtdRootKernel = SystemInfo["canKexec"]
+ modelMtdRootKernel = BoxInfo.getItem("canKexec")
self.setTitle(_("Kexec MultiBoot Initialisation - will reboot after 10 seconds."))
self["description"].setText(_("Kexec MultiBoot Initialisation in progress!\n\nWill reboot after restoring any eMMC slots.\nThis can take from 1 -> 5 minutes per slot."))
open("/STARTUP", 'w').write("kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % modelMtdRootKernel[0])
diff --git a/lib/python/Screens/Hotkey.py b/lib/python/Screens/Hotkey.py
index 0a7068b925..e3586f1f41 100644
--- a/lib/python/Screens/Hotkey.py
+++ b/lib/python/Screens/Hotkey.py
@@ -1,7 +1,7 @@
from Components.ActionMap import ActionMap, HelpableActionMap, NumberActionMap
from Components.Sources.StaticText import StaticText
from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.config import config, ConfigSubsection, ConfigText, ConfigYesNo
from Components.PluginComponent import plugins
from Screens.Console import Console
@@ -50,7 +50,7 @@ class hotkey:
("Radio", "radio", ""),
("Radio" + " " + _("long"), "radio_long", ""),
("TV", "showTv", ""),
- ("TV" + " " + _("long"), "showTv_long", SystemInfo["LcdLiveTV"] and "Infobar/ToggleLCDLiveTV" or ""),
+ ("TV" + " " + _("long"), "showTv_long", BoxInfo.getItem("LcdLiveTV") and "Infobar/ToggleLCDLiveTV" or ""),
("Teletext", "text", ""),
("Help", "displayHelp", ""),
("Help" + " " + _("long"), "displayHelp_long", ""),
@@ -198,19 +198,19 @@ def getHotkeyFunctions():
hotkey.functions.append((_("Toggle infoBar"), "Infobar/toggleShow", "InfoBar"))
hotkey.functions.append((_("Toggle videomode"), "Infobar/ToggleVideoMode", "InfoBar"))
hotkey.functions.append((_("Toggle subtitles show/hide"), "Infobar/toggleSubtitleShown", "InfoBar"))
- if SystemInfo["PIPAvailable"]:
+ if BoxInfo.getItem("PIPAvailable"):
hotkey.functions.append((_("Show PiP"), "Infobar/showPiP", "InfoBar"))
hotkey.functions.append((_("Swap PiP"), "Infobar/swapPiP", "InfoBar"))
hotkey.functions.append((_("Move PiP"), "Infobar/movePiP", "InfoBar"))
hotkey.functions.append((_("Toggle PiPzap"), "Infobar/togglePipzap", "InfoBar"))
hotkey.functions.append((_("Activate HbbTV (Redbutton)"), "Infobar/activateRedButton", "InfoBar"))
- if SystemInfo["HasHDMI-In"]:
+ if BoxInfo.getItem("HasHDMIin"):
hotkey.functions.append((_("Toggle HDMI In"), "Infobar/HDMIIn", "InfoBar"))
- if SystemInfo["LcdLiveTV"]:
+ if BoxInfo.getItem("LcdLiveTV"):
hotkey.functions.append((_("Toggle LCD LiveTV"), "Infobar/ToggleLCDLiveTV", "InfoBar"))
hotkey.functions.append((_("Toggle dashed flickering line for this service"), "Infobar/ToggleHideVBI", "InfoBar"))
hotkey.functions.append((_("Do nothing"), "Void", "InfoBar"))
- if SystemInfo["HasHDMI-CEC"]:
+ if BoxInfo.getItem("HasHDMI-CEC"):
hotkey.functions.append((_("HDMI-CEC Source Active"), "Infobar/SourceActiveHdmiCec", "InfoBar"))
hotkey.functions.append((_("HDMI-CEC Source Inactive"), "Infobar/SourceInactiveHdmiCec", "InfoBar"))
hotkey.functions.append((_("HotKey Setup"), "Module/Screens.Hotkey/HotkeySetup", "Setup"))
@@ -243,7 +243,7 @@ def getHotkeyFunctions():
hotkey.functions.append((_("Language"), "Module/Screens.LanguageSelection/LanguageSelection", "Setup"))
hotkey.functions.append((_("Skin setup"), "Module/Screens.SkinSelector/SkinSelector", "Setup"))
hotkey.functions.append((_("Memory Info"), "Module/Screens.About/MemoryInfo", "Setup"))
- if SystemInfo["canMultiBoot"]:
+ if BoxInfo.getItem("canMultiBoot"):
hotkey.functions.append((_("Multiboot image selector"), "Module/Screens.FlashImage/MultibootSelection", "Setup"))
if os.path.isdir("/etc/ppanels"):
for x in [x for x in os.listdir("/etc/ppanels") if x.endswith(".xml")]:
diff --git a/lib/python/Screens/InfoBar.py b/lib/python/Screens/InfoBar.py
index b8fbfe44d7..88e175ec22 100644
--- a/lib/python/Screens/InfoBar.py
+++ b/lib/python/Screens/InfoBar.py
@@ -169,7 +169,7 @@ def showMediaPlayer(self):
class MoviePlayer(InfoBarBase, InfoBarShowHide, InfoBarMenu, InfoBarSeek, InfoBarShowMovies, InfoBarInstantRecord, InfoBarVmodeButton, InfoBarLongKeyDetection,
InfoBarAudioSelection, HelpableScreen, InfoBarNotifications, InfoBarServiceNotifications, InfoBarPVRState,
InfoBarCueSheetSupport, InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, Screen, InfoBarTeletextPlugin,
- InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarPlugins, InfoBarPiP, InfoBarHDMI, InfoBarHotkey):
+ InfoBarServiceErrorPopupSupport, InfoBarExtensions, InfoBarPlugins, InfoBarPiP, InfoBarHDMI, InfoBarHotkey, InfoBarJobman):
ENABLE_RESUME_SUPPORT = True
ALLOW_SUSPEND = True
@@ -192,6 +192,11 @@ def __init__(self, session, service, slist=None, lastservice=None, infobar=None)
"right": self.right
}, prio=-2)
+ self["InstantExtensionsActions"] = HelpableActionMap(self, ["InfobarExtensions"],
+ {
+ "extensions": (self.showExtensionSelection, _("Show extensions...")),
+ }, 1) # lower priority
+
self["state"] = Label()
self["speed"] = Label()
self["statusicon"] = MultiPixmap()
@@ -204,7 +209,7 @@ def __init__(self, session, service, slist=None, lastservice=None, infobar=None)
InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, \
InfoBarMoviePlayerSummarySupport, InfoBarSubtitleSupport, \
InfoBarTeletextPlugin, InfoBarServiceErrorPopupSupport, InfoBarExtensions, \
- InfoBarPlugins, InfoBarPiP, InfoBarHotkey:
+ InfoBarPlugins, InfoBarPiP, InfoBarHotkey, InfoBarJobman:
x.__init__(self)
self.servicelist = slist
@@ -532,6 +537,8 @@ def showMovies(self):
def movieSelected(self, service):
if service is not None:
+ if self.cur_service and self.cur_service != service:
+ setResumePoint(self.session)
self.cur_service = service
self.is_closing = False
self.session.nav.playService(service)
diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py
index b611047878..84408786b5 100644
--- a/lib/python/Screens/InfoBarGenerics.py
+++ b/lib/python/Screens/InfoBarGenerics.py
@@ -4,7 +4,7 @@
from Components.ActionMap import ActionMap, HelpableActionMap
from Components.ActionMap import NumberActionMap
-from Components.Harddisk import harddiskmanager
+from Components.Harddisk import harddiskmanager, findMountPoint
from Components.Input import Input
from Components.Label import Label
from Components.MovieList import AUDIO_EXTENSIONS, MOVIE_EXTENSIONS, DVD_EXTENSIONS
@@ -13,7 +13,7 @@
from Components.ServiceList import refreshServiceList
from Components.Sources.Boolean import Boolean
from Components.config import config, ConfigBoolean, ConfigClock
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.UsageConfig import preferredInstantRecordPath, defaultMoviePath
from Components.VolumeControl import VolumeControl
from Components.Sources.StaticText import StaticText
@@ -79,18 +79,19 @@ def setResumePoint(session):
if not pos[0]:
key = ref.toString()
lru = int(time())
- l = seek.getLength()
- if l:
- l = l[1]
+ sl = seek.getLength()
+ if sl:
+ sl = sl[1]
else:
- l = None
- resumePointCache[key] = [lru, pos[1], l]
- if len(resumePointCache) > 50:
- candidate = key
- for k, v in list(resumePointCache.items()):
- if v[0] < lru:
- candidate = k
- del resumePointCache[candidate]
+ sl = None
+ resumePointCache[key] = [lru, pos[1], sl]
+ for k, v in list(resumePointCache.items()):
+ if v[0] < lru:
+ candidate = k
+ filepath = os.path.realpath(candidate.split(':')[-1])
+ mountpoint = findMountPoint(filepath)
+ if os.path.ismount(mountpoint) and not os.path.exists(filepath):
+ del resumePointCache[candidate]
if lru - resumePointCacheLast > 3600:
saveResumePoints()
@@ -124,33 +125,44 @@ def saveResumePoints():
pickle.dump(resumePointCache, f, pickle.HIGHEST_PROTOCOL)
f.close()
except Exception as ex:
- print("[InfoBar] Failed to write resumepoints:", ex)
+ print("[saveResumePoints] Failed to write resumepoints:", ex)
resumePointCacheLast = int(time())
def loadResumePoints():
try:
- _file = open('/etc/enigma2/resumepoints.pkl', 'rb')
- PickleFile = pickle.load(_file)
- _file.close()
- return PickleFile
+ f = open('/etc/enigma2/resumepoints.pkl', 'rb')
+ pickleFile = pickle.load(f)
+ f.close()
+ return pickleFile
except Exception as ex:
- print("[InfoBar] Failed to load resumepoints:", ex)
+ print("[loadResumePoints] Failed to load resumepoints:", ex)
return {}
+def updateResumePointCache():
+ global resumePointCache
+ resumePointCache = loadResumePoints()
+
+
resumePointCache = loadResumePoints()
resumePointCacheLast = int(time())
class whitelist:
+ FILENAME_VBI = "/etc/enigma2/whitelist_vbi"
vbi = []
+ FILENAME_BOUQUETS = "/etc/enigma2/whitelist_bouquets"
+ bouquets = []
def reload_whitelist_vbi():
- whitelist.vbi = [line.strip() for line in open('/etc/enigma2/whitelist_vbi', 'r').readlines()] if os.path.isfile('/etc/enigma2/whitelist_vbi') else []
+ whitelist.vbi = [line.strip() for line in open(whitelist.FILENAME_VBI, 'r').readlines()] if os.path.isfile(whitelist.FILENAME_VBI) else []
+def reload_whitelist_bouquets():
+ whitelist.bouquets = [line.strip() for line in open(whitelist.FILENAME_BOUQUETS, 'r').readlines()] if os.path.isfile(whitelist.FILENAME_BOUQUETS) else []
reload_whitelist_vbi()
+reload_whitelist_bouquets()
class InfoBarStreamRelay:
@@ -578,6 +590,12 @@ def checkHideVBI(self, service=None):
return ".hidevbi." in servicepath.lower()
return service and service.toString() in whitelist.vbi
+ def checkBouquets(self, bouquet):
+ try:
+ return bouquet.toString().split('"')[1] in whitelist.bouquets
+ except:
+ return
+
def checkStreamrelay(self, service):
return streamrelay.checkService(service)
@@ -595,9 +613,17 @@ def ToggleHideVBI(self, service=None):
whitelist.vbi.remove(service)
else:
whitelist.vbi.append(service)
- open('/etc/enigma2/whitelist_vbi', 'w').write('\n'.join(whitelist.vbi))
+ open(whitelist.FILENAME_VBI, 'w').write('\n'.join(whitelist.vbi))
self.showHideVBI()
+ def ToggleBouquet(self, bouquet):
+ if bouquet in whitelist.bouquets:
+ whitelist.bouquets.remove(bouquet)
+ else:
+ whitelist.bouquets.append(bouquet)
+ open(whitelist.FILENAME_BOUQUETS, 'w').write('\n'.join(whitelist.bouquets))
+
+
class BufferIndicator(Screen):
def __init__(self, session):
Screen.__init__(self, session)
@@ -1129,7 +1155,7 @@ def mainMenu(self):
self.session.openWithCallback(self.mainMenuClosed, MainMenu, menu)
def showHDMiRecordSetup(self):
- if SystemInfo["HasHDMI-In"]:
+ if BoxInfo.getItem("HasHDMI-In"):
self.session.openWithCallback(self.mainMenuClosed, Setup, 'HDMIRecord')
def mainMenuClosed(self, *val):
@@ -2280,8 +2306,8 @@ def __seekableStatusChanged(self):
self.restartSubtitle()
def setLCDsymbolTimeshift(self):
- if SystemInfo["LCDsymbol_timeshift"]:
- open(SystemInfo["LCDsymbol_timeshift"], "w").write(self.timeshiftEnabled() and "1" or "0")
+ if BoxInfo.getItem("LCDsymbol_timeshift"):
+ open(BoxInfo.getItem("LCDsymbol_timeshift"), "w").write(self.timeshiftEnabled() and "1" or "0")
def __serviceStarted(self):
self.pvrStateDialog.hide()
@@ -2428,7 +2454,7 @@ class InfoBarExtensions:
def __init__(self):
self.list = []
- # self.addExtension((lambda: _("Softcam Setup"), self.openSoftcamSetup, lambda: config.misc.softcam_setup.extension_menu.value and SystemInfo["HasSoftcamInstalled"]), "1")
+ # self.addExtension((lambda: _("Softcam Setup"), self.openSoftcamSetup, lambda: config.misc.softcam_setup.extension_menu.value and BoxInfo.getItem("HasSoftcamInstalled")), "1")
self.addExtension((lambda: _("Manually import from fallback tuner"), self.importChannels, lambda: config.usage.remote_fallback_extension_menu.value and config.usage.remote_fallback_import.value))
self["InstantExtensionsActions"] = HelpableActionMap(self, ["InfobarExtensions"],
{
@@ -2564,7 +2590,7 @@ def __init__(self):
self.lastPiPService = None
- if SystemInfo["PIPAvailable"]:
+ if BoxInfo.getItem("PIPAvailable"):
self["PiPActions"] = HelpableActionMap(self, ["InfobarPiPActions"],
{
"activatePiP": (self.activePiP, self.activePiPName),
@@ -2629,7 +2655,7 @@ def showPiP(self):
if lastPiPServiceTimeout:
self.lastPiPServiceTimeoutTimer.startLongTimer(lastPiPServiceTimeout)
del self.session.pip
- if SystemInfo["LCDMiniTV"]:
+ if BoxInfo.getItem("LCDMiniTV"):
if config.lcd.modepip.value >= "1":
f = open("/proc/stb/lcd/mode", "w")
f.write(config.lcd.modeminitv.value)
@@ -2644,7 +2670,7 @@ def showPiP(self):
if self.session.pip.playService(newservice):
self.session.pipshown = True
self.session.pip.servicePath = slist and slist.getCurrentServicePath()
- if SystemInfo["LCDMiniTV"]:
+ if BoxInfo.getItem("LCDMiniTV"):
if config.lcd.modepip.value >= "1":
f = open("/proc/stb/lcd/mode", "w")
f.write(config.lcd.modepip.value)
@@ -3949,7 +3975,7 @@ def __init__(self):
self.hdmi_enabled_full = False
self.hdmi_enabled_pip = False
- if SystemInfo["HasHDMI-In"]:
+ if BoxInfo.getItem("HasHDMI-In"):
if not self.hdmi_enabled_full:
self.addExtension((self.getHDMIInFullScreen, self.HDMIInFull, lambda: True), "blue")
if not self.hdmi_enabled_pip:
diff --git a/lib/python/Screens/Menu.py b/lib/python/Screens/Menu.py
index 9e30587faa..c1c673c30b 100644
--- a/lib/python/Screens/Menu.py
+++ b/lib/python/Screens/Menu.py
@@ -8,7 +8,7 @@
from Components.config import configfile
from Components.PluginComponent import plugins
from Components.config import config, ConfigDictionarySet, NoSave
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Tools.BoundFunction import boundFunction
from skin import parameters, menus, menuicons
from Plugins.Plugin import PluginDescriptor
@@ -81,9 +81,9 @@ def addMenu(self, destList, node, parent=None):
requires = node.get("requires")
if requires:
if requires[0] == '!':
- if SystemInfo.get(requires[1:], False):
+ if BoxInfo.getItem(requires[1:], False):
return
- elif not SystemInfo.get(requires, False):
+ elif not BoxInfo.getItem(requires, False):
return
MenuTitle = _(node.get("text", "??"))
entryID = node.get("entryID", "undefined")
@@ -115,9 +115,9 @@ def addItem(self, destList, node, parent=None):
requires = node.get("requires")
if requires:
if requires[0] == '!':
- if SystemInfo.get(requires[1:], False):
+ if BoxInfo.getItem(requires[1:], False):
return
- elif not SystemInfo.get(requires, False):
+ elif not BoxInfo.getItem(requires, False):
return
conditional = node.get("conditional")
if conditional and not eval(conditional):
diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py
index 7dab7e9902..dcc35c4838 100644
--- a/lib/python/Screens/NetworkSetup.py
+++ b/lib/python/Screens/NetworkSetup.py
@@ -540,7 +540,7 @@ def createConfig(self):
self.secondaryDNS = NoSave(ConfigIP(default=nameserver[1]))
def createSetup(self, element=None):
- if SystemInfo["WakeOnLAN"]:
+ if BoxInfo.getItem("WakeOnLAN"):
self.wolstartvalue = config.network.wol.value
self.list = [(_("Use interface"), self.activateInterfaceEntry)]
if self.activateInterfaceEntry.value:
@@ -555,7 +555,7 @@ def createSetup(self, element=None):
self.list.append((_('Gateway'), self.gatewayConfigEntry))
havewol = False
- if SystemInfo["WakeOnLAN"] and getBoxType() in ('gbquadplus', 'quadbox2400'):
+ if BoxInfo.getItem("WakeOnLAN") and getBoxType() in ('gbquadplus', 'quadbox2400'):
havewol = True
if havewol and self.iface == 'eth0':
self.list.append((_('Enable Wake On LAN'), config.network.wol))
@@ -737,7 +737,7 @@ def ConfigfinishedCB(self, data):
def keyCancelConfirm(self, result):
if not result:
return
- if SystemInfo["WakeOnLAN"]:
+ if BoxInfo.getItem("WakeOnLAN"):
config.network.wol.setValue(self.wolstartvalue)
if not self.oldInterfaceState:
iNetwork.deactivateInterface(self.iface, self.keyCancelCB)
@@ -746,7 +746,7 @@ def keyCancelConfirm(self, result):
def keyCancel(self):
self.hideInputHelp()
- if self["config"].isChanged() or (SystemInfo["WakeOnLAN"] and self.wolstartvalue != config.network.wol.value):
+ if self["config"].isChanged() or (BoxInfo.getItem("WakeOnLAN") and self.wolstartvalue != config.network.wol.value):
self.session.openWithCallback(self.keyCancelConfirm, MessageBox, _("Really close without saving settings?"), default=False)
else:
self.close('cancel')
diff --git a/lib/python/Screens/PiPSetup.py b/lib/python/Screens/PiPSetup.py
index ff85d59d38..934f8bf452 100644
--- a/lib/python/Screens/PiPSetup.py
+++ b/lib/python/Screens/PiPSetup.py
@@ -1,16 +1,16 @@
from Screens.Screen import Screen
from Components.ActionMap import NumberActionMap
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.Label import Label
from Components.config import config
# this is not so great.
MAX_X = 720
MAX_Y = 576
-MAX_W = MAX_X * 3 / 4
-MAX_H = MAX_Y * 3 / 4
-MIN_W = MAX_X / 8
-MIN_H = MAX_Y / 8
+MAX_W = MAX_X * 3 // 4
+MAX_H = MAX_Y * 3 // 4
+MIN_W = MAX_X // 8
+MIN_H = MAX_Y // 8
def clip(val, min, max):
@@ -38,7 +38,7 @@ def __init__(self, session, pip):
self.resize = 100
self.helptext = _("Please use direction keys to move the PiP window.\nPress Bouquet +/- to resize the window.\nPress OK to go back to the TV mode or EXIT to cancel the moving.")
- if SystemInfo["VideoDestinationConfigurable"] or SystemInfo["HasExternalPIP"]:
+ if BoxInfo.getItem("VideoDestinationConfigurable") or BoxInfo.getItem("HasExternalPIP"):
self.helptext += "\n" + _("Press '0' to toggle PiP mode")
self.modetext = _("Current mode: %s \n")
diff --git a/lib/python/Screens/PictureInPicture.py b/lib/python/Screens/PictureInPicture.py
index 9210510969..4d5fc6a66b 100644
--- a/lib/python/Screens/PictureInPicture.py
+++ b/lib/python/Screens/PictureInPicture.py
@@ -1,7 +1,7 @@
from Screens.Screen import Screen
from Screens.Dish import Dishpip
from enigma import ePoint, eSize, eRect, eServiceCenter, getBestPlayableServiceReference, eServiceReference, eTimer
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.VideoWindow import VideoWindow
from Components.Sources.StreamService import StreamServiceList
from Components.config import config, ConfigPosition, ConfigSelection
@@ -18,8 +18,8 @@
def timedStopPipPigMode():
from Screens.InfoBar import InfoBar
if InfoBar.instance and InfoBar.instance.session:
- if SystemInfo["hasPIPVisibleProc"]:
- open(SystemInfo["hasPIPVisibleProc"], "w").write("1")
+ if BoxInfo.getItem("hasPIPVisibleProc"):
+ open(BoxInfo.getItem("hasPIPVisibleProc"), "w").write("1")
elif hasattr(InfoBar.instance.session, "pip"):
InfoBar.instance.session.pip.relocate()
global PipPigModeEnabled
@@ -36,8 +36,8 @@ def PipPigMode(value):
PipPigModeTimer.stop()
global PipPigModeEnabled
if not PipPigModeEnabled:
- if SystemInfo["hasPIPVisibleProc"]:
- open(SystemInfo["hasPIPVisibleProc"], "w").write("0")
+ if BoxInfo.getItem("hasPIPVisibleProc"):
+ open(BoxInfo.getItem("hasPIPVisibleProc"), "w").write("0")
else:
import skin
x, y, w, h = skin.parameters.get("PipHidePosition", (0, 0, 8, 8))
@@ -68,12 +68,12 @@ def __init__(self, session):
self.currentServiceReference = None
self.choicelist = [("standard", _("Standard"))]
- if SystemInfo["VideoDestinationConfigurable"]:
+ if BoxInfo.getItem("VideoDestinationConfigurable"):
self.choicelist.append(("cascade", _("Cascade PiP")))
self.choicelist.append(("split", _("Splitscreen")))
self.choicelist.append(("byside", _("Side by side")))
self.choicelist.append(("bigpig", _("Big PiP")))
- if SystemInfo["HasExternalPIP"]:
+ if BoxInfo.getItem("HasExternalPIP"):
self.choicelist.append(("external", _("External PiP")))
if not pip_config_initialized:
@@ -166,12 +166,12 @@ def resize(self, w, h):
self.setSizePosMainWindow()
def setSizePosMainWindow(self, x=0, y=0, w=0, h=0):
- if SystemInfo["VideoDestinationConfigurable"]:
+ if BoxInfo.getItem("VideoDestinationConfigurable"):
self["video"].instance.setFullScreenPosition(eRect(x, y, w, h))
def setExternalPiP(self, onoff):
- if SystemInfo["HasExternalPIP"]:
- open(SystemInfo["HasExternalPIP"], "w").write(onoff and "on" or "off")
+ if BoxInfo.getItem("HasExternalPIP"):
+ open(BoxInfo.getItem("HasExternalPIP"), "w").write(onoff and "on" or "off")
def active(self):
self.pipActive.show()
@@ -207,7 +207,7 @@ def playService(self, service):
from Screens.InfoBarGenerics import streamrelay
ref = streamrelay.streamrelayChecker(self.resolveAlternatePipService(service))
if ref:
- if SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"] and StreamServiceList:
+ if BoxInfo.getItem("CanNotDoSimultaneousTranscodeAndPIP") and StreamServiceList:
self.pipservice = None
self.currentService = None
self.currentServiceReference = None
diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py
index eebec06a6f..e6fec06c70 100644
--- a/lib/python/Screens/Satconfig.py
+++ b/lib/python/Screens/Satconfig.py
@@ -1,7 +1,7 @@
from __future__ import division
from enigma import eDVBDB, getLinkedSlotID, eDVBResourceManager
from Screens.Screen import Screen
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.ActionMap import ActionMap
from Components.ConfigList import ConfigListScreen
from Components.NimManager import nimmanager
@@ -54,7 +54,7 @@ def createPositionerSetup(self, list):
list.append((" ", nim.longitudeOrientation, _("Enter if you are in the east or west hemisphere.")))
list.append((self.indent % _("Latitude"), nim.latitude, _("Enter your current latitude. This is the number of degrees you are from the equator as a decimal.")))
list.append((" ", nim.latitudeOrientation, _("Enter if you are north or south of the equator.")))
- if SystemInfo["CanMeasureFrontendInputPower"]:
+ if BoxInfo.getItem("CanMeasureFrontendInputPower"):
self.advancedPowerMeasurement = (self.indent % _("Use power measurement"), nim.powerMeasurement, _("Power management. Consult your receiver's manual for more information."))
list.append(self.advancedPowerMeasurement)
if nim.powerMeasurement.value:
@@ -420,7 +420,7 @@ def fillListWithAdvancedSatEntrys(self, Sat):
self.list.append((self.indent % "LOF/L", currLnb.lofl, _("Consult your SCR device spec sheet for this information.")))
self.list.append((self.indent % "LOF/H", currLnb.lofh, _("Consult your SCR device spec sheet for this information.")))
self.list.append((self.indent % _("Threshold"), currLnb.threshold, _("Consult your SCR device spec sheet for this information.")))
- if not SystemInfo["FbcTunerPowerAlwaysOn"] or not self.nim.isFBCTuner():
+ if not BoxInfo.getItem("FbcTunerPowerAlwaysOn") or not self.nim.isFBCTuner():
self.list.append(self.externallyPowered)
if not currLnb.powerinserter.value:
self.list.append((self.indent % _("Bootup time"), currLnb.bootuptime, _("Consult your SCR device spec sheet for this information.")))
@@ -434,7 +434,7 @@ def fillListWithAdvancedSatEntrys(self, Sat):
if currLnb.positions.value > 1:
self.list.append(self.advancedPosition)
self.list.append(self.advancedSCR)
- if not SystemInfo["FbcTunerPowerAlwaysOn"] or not self.nim.isFBCTuner():
+ if not BoxInfo.getItem("FbcTunerPowerAlwaysOn") or not self.nim.isFBCTuner():
self.list.append(self.externallyPowered)
choices = []
connectable = nimmanager.canConnectTo(self.slotid)
@@ -488,7 +488,7 @@ def fillListWithAdvancedSatEntrys(self, Sat):
self.list.append((self.indent % _("DiSEqC 1.1 repeats"), currLnb.diseqcRepeats, _("If using multiple uncommitted switches the DiSEqC commands must be sent multiple times. Set to the number of uncommitted switches in the chain minus one.")))
self.list.append((self.indent % _("Sequence repeat"), currLnb.sequenceRepeat, _("Set sequence repeats if your aerial system requires this. Normally if the aerial system has been configured correctly sequence repeats will not be necessary. If yours does, recheck you have command order set correctly.")))
if currLnb.diseqcMode.value == "1_2":
- if SystemInfo["CanMeasureFrontendInputPower"]:
+ if BoxInfo.getItem("CanMeasureFrontendInputPower"):
self.advancedPowerMeasurement = (self.indent % _("Use power measurement"), currLnb.powerMeasurement, _("Power management. Consult your receiver's manual for more information."))
self.list.append(self.advancedPowerMeasurement)
if currLnb.powerMeasurement.value:
diff --git a/lib/python/Screens/ScanSetup.py b/lib/python/Screens/ScanSetup.py
index 1ec838c649..93fa69aaf7 100644
--- a/lib/python/Screens/ScanSetup.py
+++ b/lib/python/Screens/ScanSetup.py
@@ -4,7 +4,7 @@
from Components.config import config, ConfigSubsection, ConfigSelection, ConfigYesNo, ConfigInteger, ConfigSlider, ConfigEnableDisable, ConfigFloat
from Components.ActionMap import NumberActionMap, ActionMap
from Components.Sources.StaticText import StaticText
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.ConfigList import ConfigListScreen
from Components.NimManager import nimmanager, getConfigSatlist
from Components.Label import Label
@@ -613,7 +613,7 @@ def startTerrestrialTransponderSearch(self, nim_idx, region):
def terrestrialTransponderSearch(self, freq, bandWidth):
self.terrestrial_search_data = ""
cmd = "%s --freq %d --bw %d --bus %d --ds 2" % (self.terrestrial_search_binName, freq, bandWidth, self.terrestrial_search_bus)
- if SystemInfo["Blindscan_t2_available"] and self.terrestrial_search_enable_5v:
+ if BoxInfo.getItem("Blindscan_t2_available") and self.terrestrial_search_enable_5v:
cmd += " --feid %d --5v %d" % (self.terrestrial_search_feid, self.terrestrial_search_enable_5v)
print("SCAN CMD : ", cmd)
self.terrestrial_search_container.execute(cmd)
@@ -856,7 +856,7 @@ def createSetup(self):
if nimmanager.getNimName(nim.slot).startswith("Sundtek"):
self.TerrestrialCompleteEntry = (_('Scan options'), self.scan_ter_complete_type)
self.list.append(self.TerrestrialCompleteEntry)
- elif SystemInfo["Blindscan_t2_available"] and nim.isCompatible("DVB-T2") and len(self.terrestrialTransponderGetCmd(nim.slot)):
+ elif BoxInfo.getItem("Blindscan_t2_available") and nim.isCompatible("DVB-T2") and len(self.terrestrialTransponderGetCmd(nim.slot)):
self.list.append((_('Blindscan'), self.scan_terrestrial_binary_scan))
if self.TerrestrialCompleteEntry is None or self.scan_ter_complete_type.value == "extended":
if nim.canBeCompatible("DVB-T2"):
@@ -1489,7 +1489,7 @@ def keyGoCheckTimeshiftCallback(self, answer):
elif self.scan_typeterrestrial.value == "complete":
if nimmanager.getNimName(nim.slot).startswith("Sundtek") and self.scan_ter_complete_type.value == "all":
action = SEARCH_TERRESTRIAL2_TRANSPONDERS
- elif SystemInfo["Blindscan_t2_available"] and self.scan_terrestrial_binary_scan.value and nim.isCompatible("DVB-T2") and len(self.terrestrialTransponderGetCmd(nim.slot)):
+ elif BoxInfo.getItem("Blindscan_t2_available") and self.scan_terrestrial_binary_scan.value and nim.isCompatible("DVB-T2") and len(self.terrestrialTransponderGetCmd(nim.slot)):
action = SEARCH_TERRESTRIAL2_TRANSPONDERS
else:
getInitialTerrestrialTransponderList(tlist, self.TerrestrialRegion.description[self.TerrestrialRegion.value], int(self.scan_ter.system.value))
@@ -1793,7 +1793,7 @@ def __init__(self, session):
if need_scan:
nims_to_scan.append(nim)
- if nim.isCompatible("DVB-T2") and SystemInfo["Blindscan_t2_available"] and len(self.terrestrialTransponderGetCmd(nim.slot)):
+ if nim.isCompatible("DVB-T2") and BoxInfo.getItem("Blindscan_t2_available") and len(self.terrestrialTransponderGetCmd(nim.slot)):
self.t2_nim_found = True
# we save the config elements to use them on keyGo
@@ -1868,7 +1868,7 @@ def buildTransponderList(self): # this method is called multiple times because o
action = SEARCH_CABLE_TRANSPONDERS
networkid = config.Nims[nim.slot].cable.scan_networkid.value
if nim.isCompatible("DVB-T"):
- if SystemInfo["Blindscan_t2_available"] and self.scan_terrestrial_binary_scan.value and nim.isCompatible("DVB-T2") and len(self.terrestrialTransponderGetCmd(nim.slot)):
+ if BoxInfo.getItem("Blindscan_t2_available") and self.scan_terrestrial_binary_scan.value and nim.isCompatible("DVB-T2") and len(self.terrestrialTransponderGetCmd(nim.slot)):
action = SEARCH_TERRESTRIAL2_TRANSPONDERS
else:
getInitialTerrestrialTransponderList(tlist, nimmanager.getTerrestrialDescription(nim.slot))
diff --git a/lib/python/Screens/SessionGlobals.py b/lib/python/Screens/SessionGlobals.py
index b438505c8e..921862f76c 100644
--- a/lib/python/Screens/SessionGlobals.py
+++ b/lib/python/Screens/SessionGlobals.py
@@ -24,9 +24,9 @@ def __init__(self, session):
self["RecordState"] = RecordState(session)
self["Standby"] = Boolean(fixed=False)
- from Components.SystemInfo import SystemInfo
+ from Components.SystemInfo import BoxInfo
- nr_leds = SystemInfo.get("NumFrontpanelLEDs", 0)
+ nr_leds = BoxInfo.getItem("NumFrontpanelLEDs", 0)
if nr_leds > 0:
combine = Combine(func=lambda s: {(False, False): 0, (False, True): 1, (True, False): 2, (True, True): 3}[(s[0].boolean, s[1].boolean)])
diff --git a/lib/python/Screens/Setup.py b/lib/python/Screens/Setup.py
index 415e4e0bb0..6cf2df6805 100644
--- a/lib/python/Screens/Setup.py
+++ b/lib/python/Screens/Setup.py
@@ -2,7 +2,7 @@
from Components.ActionMap import NumberActionMap
from Components.config import config, ConfigNothing, ConfigText, ConfigPassword
from Components.Label import Label
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.ConfigList import ConfigListScreen
from Components.Pixmap import Pixmap
from Components.Sources.StaticText import StaticText
@@ -166,10 +166,10 @@ def addItems(self, listItems, parentNode):
requires = x.get("requires")
if requires:
- if requires[0] == '!':
- if SystemInfo.get(requires[1:], False):
+ if requires.startswith('!'):
+ if BoxInfo.getItem(requires[1:], False):
continue
- elif not SystemInfo.get(requires, False):
+ elif not BoxInfo.getItem(requires, False):
continue
conditional = x.get("conditional")
if conditional and not eval(conditional):
diff --git a/lib/python/Screens/Standby.py b/lib/python/Screens/Standby.py
index 8b78f642b5..46912e6ebf 100644
--- a/lib/python/Screens/Standby.py
+++ b/lib/python/Screens/Standby.py
@@ -9,7 +9,7 @@
from Components.AVSwitch import AVSwitch
from Components.Console import Console
from Components.ImportChannels import ImportChannels
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.Sources.StreamService import StreamServiceList
from boxbranding import getMachineBrand, getMachineName, getBoxType
from Components.Task import job_manager
@@ -92,7 +92,7 @@ def __init__(self, session, StandbyCounterIncrease=True):
self.setMute()
# set LCDminiTV off
- if SystemInfo["Display"] and SystemInfo["LCDMiniTV"]:
+ if BoxInfo.getItem("Display") and BoxInfo.getItem("LCDMiniTV"):
setLCDModeMinitTV("0")
self.paused_service = self.paused_action = False
@@ -123,7 +123,7 @@ def __init__(self, session, StandbyCounterIncrease=True):
del self.session.pip
self.session.pipshown = False
- if SystemInfo["ScartSwitch"]:
+ if BoxInfo.getItem("ScartSwitch"):
self.avswitch.setInput("SCART")
else:
self.avswitch.setInput("AUX")
@@ -365,7 +365,7 @@ def close(self, value):
if not inStandby:
if os.path.exists("/usr/script/standby_enter.sh"):
Console().ePopen("/usr/script/standby_enter.sh")
- if SystemInfo["HasHDMI-CEC"] and config.hdmicec.enabled.value and ((config.hdmicec.control_tv_standby.value and config.hdmicec.next_boxes_detect.value) or config.hdmicec.handle_deepstandby_events.value != "no"):
+ if BoxInfo.getItem("HasHDMI-CEC") and config.hdmicec.enabled.value and ((config.hdmicec.control_tv_standby.value and config.hdmicec.next_boxes_detect.value) or config.hdmicec.handle_deepstandby_events.value != "no"):
if config.hdmicec.control_tv_standby.value and config.hdmicec.next_boxes_detect.value:
import Components.HdmiCec
Components.HdmiCec.hdmi_cec.secondBoxActive()
diff --git a/lib/python/Screens/TaskView.py b/lib/python/Screens/TaskView.py
index a63c930e7b..5394ac9c37 100644
--- a/lib/python/Screens/TaskView.py
+++ b/lib/python/Screens/TaskView.py
@@ -3,7 +3,7 @@
from Components.ConfigList import ConfigListScreen
from Components.Sources.Progress import Progress
from Components.Sources.StaticText import StaticText
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.Task import job_manager
from Screens.InfoBarGenerics import InfoBarNotifications
from Tools import Notifications
@@ -57,7 +57,7 @@ def __init__(self, session, job, parent=None, cancelable=True, backgroundable=Tr
}, -2)
self.settings = ConfigSubsection()
- if SystemInfo["DeepstandbySupport"]:
+ if BoxInfo.getItem("DeepstandbySupport"):
shutdownString = _("go to deep standby")
else:
shutdownString = _("shut down")
diff --git a/lib/python/Screens/TimerEntry.py b/lib/python/Screens/TimerEntry.py
index bd0874d465..b71113aed1 100644
--- a/lib/python/Screens/TimerEntry.py
+++ b/lib/python/Screens/TimerEntry.py
@@ -8,7 +8,7 @@
from Components.Sources.StaticText import StaticText
from Components.Label import Label
from Components.NimManager import nimmanager
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.UsageConfig import defaultMoviePath
from Screens.MovieSelection import getPreferredTagEditor
from Screens.LocationBox import MovieLocationBox
@@ -108,7 +108,7 @@ def createConfig(self, currlocation=None, locations=[]):
self.timerentry_justplay = ConfigSelection(choices=[
("zap", _("zap")), ("record", _("record")), ("zap+record", _("zap and record"))],
default={0: "record", 1: "zap", 2: "zap+record"}[justplay + 2 * always_zap])
- if SystemInfo["DeepstandbySupport"]:
+ if BoxInfo.getItem("DeepstandbySupport"):
shutdownString = _("go to deep standby")
choicelist = [("always", _("always")), ("from_standby", _("only from standby")), ("from_deep_standby", _("only from deep standby")), ("never", _("never"))]
else:
@@ -213,7 +213,7 @@ def createSetup(self, widget):
self.entryZapWakeup = (_("Wakeup receiver for start timer"), self.timerentry_zapwakeup)
if self.timerentry_justplay.value == "zap":
self.list.append(self.entryZapWakeup)
- if SystemInfo["PIPAvailable"]:
+ if BoxInfo.getItem("PIPAvailable"):
self.list.append((_("Use as PiP if possible"), self.timerentry_pipzap))
self.list.append(self.entryShowEndTime)
self["key_blue"].setText(_("Wakeup type"))
diff --git a/lib/python/Tools/CIHelper.py b/lib/python/Tools/CIHelper.py
index 233ef20933..8b2bd03182 100644
--- a/lib/python/Tools/CIHelper.py
+++ b/lib/python/Tools/CIHelper.py
@@ -1,6 +1,6 @@
from xml.etree.ElementTree import parse
from enigma import eDVBCIInterfaces, eDVBCI_UI, eEnv, eServiceCenter, eServiceReference, getBestPlayableServiceReference, iRecordableService
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.config import config
import NavigationInstance
import os
@@ -16,7 +16,7 @@ class CIHelper:
CI_MULTIDESCRAMBLE_MODULES = ("AlphaCrypt", "M7 CAM701 Multi-2")
def parse_ci_assignment(self):
- NUM_CI = SystemInfo["CommonInterface"]
+ NUM_CI = BoxInfo.getItem("CommonInterface")
if NUM_CI and NUM_CI > 0:
self.CI_ASSIGNMENT_LIST = []
@@ -157,7 +157,7 @@ def forceUpdateMultiDescramble(self, configElement):
def canMultiDescramble(self, ci):
if self.CI_MULTIDESCRAMBLE is None:
- NUM_CI = SystemInfo["CommonInterface"]
+ NUM_CI = BoxInfo.getItem("CommonInterface")
if NUM_CI and NUM_CI > 0:
self.CI_MULTIDESCRAMBLE = []
for slot in range(NUM_CI):
diff --git a/lib/python/Tools/LoadPixmap.py b/lib/python/Tools/LoadPixmap.py
index 86383ad1ab..fa884efd0b 100644
--- a/lib/python/Tools/LoadPixmap.py
+++ b/lib/python/Tools/LoadPixmap.py
@@ -1,10 +1,10 @@
-from enigma import loadPNG, loadJPG, loadSVG
+from enigma import loadPNG, loadJPG, loadSVG, RT_HALIGN_CENTER
# If cached is not supplied, LoadPixmap defaults to caching PNGs and not caching JPGs
# Split alpha channel JPGs are never cached as the C++ layer's caching is based on
# a single file per image in the cache
-def LoadPixmap(path, desktop=None, cached=None, width=0, height=0, scaletoFit=0):
+def LoadPixmap(path, desktop=None, cached=None, width=0, height=0, scaletoFit=0, align=RT_HALIGN_CENTER):
if path[-4:] == ".png":
# cache unless caller explicity requests to not cache
ptr = loadPNG(path, 0, 0 if not cached else 1)
@@ -15,7 +15,7 @@ def LoadPixmap(path, desktop=None, cached=None, width=0, height=0, scaletoFit=0)
from skin import parameters, getSkinFactor # imported here to avoid circular import
autoscale = int(parameters.get("AutoscaleSVG", -1)) # skin_default only == -1, disabled == 0 or enabled == 1
scale = height == 0 and (autoscale == -1 and "/skin_default/" in path or autoscale == 1) and getSkinFactor() or 0
- ptr = loadSVG(path, 0 if cached is False else 1, width, height, scale, scaletoFit)
+ ptr = loadSVG(path, 0 if cached is False else 1, width, height, scale, scaletoFit, align)
elif path[-1:] == ".":
# caching mechanism isn't suitable for multi file images, so it's explicitly disabled
alpha = loadPNG(path + "a.png", 0, 0)
diff --git a/lib/python/Tools/Multiboot.py b/lib/python/Tools/Multiboot.py
index cd32805bd6..867f54c4f6 100644
--- a/lib/python/Tools/Multiboot.py
+++ b/lib/python/Tools/Multiboot.py
@@ -1,4 +1,4 @@
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Components.Console import Console
from Tools.Directories import fileHas, fileExists
import os
@@ -12,7 +12,7 @@ class tmp:
def getMultibootStartupDevice():
tmp.dir = tempfile.mkdtemp(prefix="Multiboot")
- if SystemInfo["hasKexec"]: # kexec kernel multiboot
+ if BoxInfo.getItem("hasKexec"): # kexec kernel multiboot
bootList = ("/dev/mmcblk0p4", "/dev/mmcblk0p7", "/dev/mmcblk0p9")
else: #legacy multiboot
bootList = ("/dev/mmcblk0p1", "/dev/mmcblk1p1", "/dev/mmcblk0p3", "/dev/mmcblk0p4", "/dev/mtdblock2", "/dev/block/by-name/bootoptions")
@@ -37,11 +37,10 @@ def getparam(line, param):
def getMultibootslots():
bootslots = {}
mode12found = False
- if SystemInfo["MultibootStartupDevice"]:
+ if BoxInfo.getItem("MultibootStartupDevice"):
for _file in glob.glob(os.path.join(tmp.dir, 'STARTUP_*')):
if "STARTUP_RECOVERY" in _file:
- SystemInfo["RecoveryMode"] = True
- print("[multiboot] [getMultibootslots] RecoveryMode is set to:%s" % SystemInfo["RecoveryMode"])
+ BoxInfo.setItem("RecoveryMode", True)
if 'MODE_' in _file:
mode12found = True
slotnumber = _file.rsplit('_', 3)[1]
@@ -65,7 +64,7 @@ def getMultibootslots():
else:
slot["kernel"] = "%sp%s" % (device.split("p")[0], int(device.split("p")[1]) - 1)
if 'rootsubdir' in line:
- SystemInfo["HasRootSubdir"] = True
+ BoxInfo.setItem("HasRootSubdir", True)
slot['rootsubdir'] = getparam(line, 'rootsubdir')
slot["kernel"] = getparam(line, "kernel")
break
@@ -74,7 +73,7 @@ def getMultibootslots():
Console().ePopen('umount %s' % tmp.dir)
if not os.path.ismount(tmp.dir):
os.rmdir(tmp.dir)
- if not mode12found and SystemInfo["canMode12"]:
+ if not mode12found and BoxInfo.getItem("canMode12"):
#the boot device has ancient content and does not contain the correct STARTUP files
for slot in range(1, 5):
bootslots[slot] = {'device': '/dev/mmcblk0p%s' % (slot * 2 + 1), 'startupfile': None}
@@ -83,8 +82,8 @@ def getMultibootslots():
def getCurrentImage():
- if SystemInfo["canMultiBoot"]:
- if SystemInfo["hasKexec"]: # kexec kernel multiboot
+ if BoxInfo.getItem("canMultiBoot"):
+ if BoxInfo.getItem("hasKexec"): # kexec kernel multiboot
rootsubdir = [x for x in open('/sys/firmware/devicetree/base/chosen/bootargs', 'r').read().split() if x.startswith("rootsubdir")]
char = "/" if "/" in rootsubdir[0] else "="
return int(rootsubdir[0].rsplit(char, 1)[1][11:])
@@ -94,19 +93,19 @@ def getCurrentImage():
return int(slot[0])
else:
device = getparam(open('/sys/firmware/devicetree/base/chosen/bootargs', 'r').read(), 'root')
- for slot in SystemInfo["canMultiBoot"].keys():
- if SystemInfo["canMultiBoot"][slot]['device'] == device:
+ for slot in BoxInfo.getItem("canMultiBoot").keys():
+ if BoxInfo.getItem("canMultiBoot")[slot]['device'] == device:
return slot
def getCurrentImageMode():
- return bool(SystemInfo["canMultiBoot"]) and SystemInfo["canMode12"] and int(open('/sys/firmware/devicetree/base/chosen/bootargs', 'r').read().replace('\0', '').split('=')[-1])
+ return bool(BoxInfo.getItem("canMultiBoot")) and BoxInfo.getItem("canMode12") and int(open('/sys/firmware/devicetree/base/chosen/bootargs', 'r').read().replace('\0', '').split('=')[-1])
def deleteImage(slot):
tmp.dir = tempfile.mkdtemp(prefix="Multiboot")
- Console().ePopen('mount %s %s' % (SystemInfo["canMultiBoot"][slot]['device'], tmp.dir))
- enigma2binaryfile = os.path.join(os.sep.join(filter(None, [tmp.dir, SystemInfo["canMultiBoot"][slot].get('rootsubdir', '')])), 'usr/bin/enigma2')
+ Console().ePopen('mount %s %s' % (BoxInfo.getItem("canMultiBoot")[slot]['device'], tmp.dir))
+ enigma2binaryfile = os.path.join(os.sep.join(filter(None, [tmp.dir, BoxInfo.getItem("canMultiBoot")[slot].get('rootsubdir', '')])), 'usr/bin/enigma2')
if os.path.exists(enigma2binaryfile):
os.rename(enigma2binaryfile, '%s.bak' % enigma2binaryfile)
Console().ePopen('umount %s' % tmp.dir)
@@ -115,10 +114,10 @@ def deleteImage(slot):
def restoreImages():
- for slot in SystemInfo["canMultiBoot"]:
+ for slot in BoxInfo.getItem("canMultiBoot"):
tmp.dir = tempfile.mkdtemp(prefix="Multiboot")
- Console().ePopen('mount %s %s' % (SystemInfo["canMultiBoot"][slot]['device'], tmp.dir))
- enigma2binaryfile = os.path.join(os.sep.join(filter(None, [tmp.dir, SystemInfo["canMultiBoot"][slot].get('rootsubdir', '')])), 'usr/bin/enigma2')
+ Console().ePopen('mount %s %s' % (BoxInfo.getItem("canMultiBoot")[slot]['device'], tmp.dir))
+ enigma2binaryfile = os.path.join(os.sep.join(filter(None, [tmp.dir, BoxInfo.getItem("canMultiBoot")[slot].get('rootsubdir', '')])), 'usr/bin/enigma2')
if os.path.exists('%s.bak' % enigma2binaryfile):
os.rename('%s.bak' % enigma2binaryfile, enigma2binaryfile)
Console().ePopen('umount %s' % tmp.dir)
@@ -138,14 +137,14 @@ def getUUIDtoSD(UUID): # returns None on failure
def getImagelist():
imagelist = {}
- if SystemInfo["canMultiBoot"]:
+ if BoxInfo.getItem("canMultiBoot"):
tmp.dir = tempfile.mkdtemp(prefix="Multiboot")
- for slot in sorted(SystemInfo["canMultiBoot"].keys()):
- if SystemInfo["canMultiBoot"][slot]['device'] == 'ubi0:ubifs':
- Console().ePopen('mount -t ubifs %s %s' % (SystemInfo["canMultiBoot"][slot]['device'], tmp.dir))
+ for slot in sorted(BoxInfo.getItem("canMultiBoot").keys()):
+ if BoxInfo.getItem("canMultiBoot")[slot]['device'] == 'ubi0:ubifs':
+ Console().ePopen('mount -t ubifs %s %s' % (BoxInfo.getItem("canMultiBoot")[slot]['device'], tmp.dir))
else:
- Console().ePopen('mount %s %s' % (SystemInfo["canMultiBoot"][slot]['device'], tmp.dir))
- imagedir = os.sep.join(filter(None, [tmp.dir, SystemInfo["canMultiBoot"][slot].get('rootsubdir', '')]))
+ Console().ePopen('mount %s %s' % (BoxInfo.getItem("canMultiBoot")[slot]['device'], tmp.dir))
+ imagedir = os.sep.join(filter(None, [tmp.dir, BoxInfo.getItem("canMultiBoot")[slot].get('rootsubdir', '')]))
if os.path.isfile(os.path.join(imagedir, 'usr/bin/enigma2')):
try:
from datetime import datetime
diff --git a/lib/python/skin.py b/lib/python/skin.py
index ed0114d3f0..5de2a815a3 100644
--- a/lib/python/skin.py
+++ b/lib/python/skin.py
@@ -1,19 +1,19 @@
import errno
import xml.etree.ElementTree
-from enigma import addFont, eLabel, ePixmap, ePoint, eRect, eSize, eWindow, eWindowStyleManager, eWindowStyleSkinned, getDesktop, gFont, getFontFaces, gRGB, BT_ALPHATEST, BT_ALPHABLEND
+from enigma import addFont, eLabel, ePixmap, ePoint, eRect, eSize, eWidget, eWindow, eWindowStyleManager, eWindowStyleSkinned, getDesktop, gFont, getFontFaces, gRGB, BT_ALPHATEST, BT_ALPHABLEND
from os.path import basename, dirname, isfile
from Components.config import ConfigSubsection, ConfigText, config
from Components.RcModel import rc_model
from Components.Sources.Source import ObsoleteSource
-from Components.SystemInfo import SystemInfo
+from Components.SystemInfo import BoxInfo
from Tools.Directories import SCOPE_CONFIG, SCOPE_CURRENT_LCDSKIN, SCOPE_CURRENT_SKIN, SCOPE_FONTS, SCOPE_SKIN, SCOPE_SKIN_IMAGE, resolveFilename
from Tools.Import import my_import
from Tools.LoadPixmap import LoadPixmap
DEFAULT_SKIN = "GigabluePaxV2/skin.xml"
-# DEFAULT_SKIN = SystemInfo["HasFullHDSkinSupport"] and "PLi-FullNightHD/skin.xml" or "PLi-HD/skin.xml" # SD hardware is no longer supported by the default skin.
+# DEFAULT_SKIN = BoxInfo.getItem("HasFullHDSkinSupport") and "PLi-FullNightHD/skin.xml" or "PLi-HD/skin.xml" # SD hardware is no longer supported by the default skin.
EMERGENCY_SKIN = "skin_default/skin.xml"
EMERGENCY_NAME = "Stone II"
DEFAULT_DISPLAY_SKIN = "lcd_skin/skin_lcd_default.xml" if isfile(resolveFilename(SCOPE_SKIN, "display/lcd_skin/skin_lcd_default.xml")) else "skin_default/skin_display.xml"
@@ -330,6 +330,26 @@ def parseValuePair(s, scale, object=None, desktop=None, size=None):
def parsePosition(s, scale, object=None, desktop=None, size=None):
return ePoint(*parseValuePair(s, scale, object, desktop, size))
+def parseRadius(value):
+ data = [x.strip() for x in value.split(";")]
+ if len(data) == 2:
+ edges = [x.strip() for x in data[1].split(",")]
+ edgesMask = {
+ "topLeft": eWidget.RADIUS_TOP_LEFT,
+ "topRight": eWidget.RADIUS_TOP_RIGHT,
+ "top": eWidget.RADIUS_TOP,
+ "bottomLeft": eWidget.RADIUS_BOTTOM_LEFT,
+ "bottomRight": eWidget.RADIUS_BOTTOM_RIGHT,
+ "bottom": eWidget.RADIUS_BOTTOM,
+ "left": eWidget.RADIUS_LEFT,
+ "right": eWidget.RADIUS_RIGHT,
+ }
+ edgeValue = 0
+ for e in edges:
+ edgeValue += edgesMask.get(e, 0)
+ return int(data[0]), edgeValue
+ else:
+ return int(data[0]), eWidget.RADIUS_ALL
def parseSize(s, scale, object=None, desktop=None):
return eSize(*[max(0, x) for x in parseValuePair(s, scale, object, desktop)])
@@ -513,6 +533,12 @@ def font(self, value):
def secondfont(self, value):
self.guiObject.setSecondFont(parseFont(value, self.scaleTuple))
+
+ def widgetBorderColor(self, value):
+ self.guiObject.setWidgetBorderColor(parseColor(value))
+
+ def widgetBorderWidth(self, value):
+ self.guiObject.setWidgetBorderWidth(parseScale(value))
def zPosition(self, value):
self.guiObject.setZPosition(int(value))
@@ -523,6 +549,14 @@ def itemHeight(self, value):
def itemWidth(self, value):
self.guiObject.setItemWidth(parseScale(value))
+ def itemCornerRadius(self, value):
+ radius, edgeValue = parseRadius(value)
+ self.guiObject.setItemCornerRadius(radius, edgeValue)
+
+ def itemCornerRadiusSelected(self, value):
+ radius, edgeValue = parseRadius(value)
+ self.guiObject.setItemCornerRadiusSelected(radius, edgeValue)
+
def pixmap(self, value):
if value.endswith(".svg"): # if graphic is svg force alphatest to "blend"
self.guiObject.setAlphatest(BT_ALPHABLEND)
@@ -654,6 +688,10 @@ def borderColor(self, value):
def borderWidth(self, value):
self.guiObject.setBorderWidth(parseScale(value))
+
+ def cornerRadius(self, value):
+ radius, edgeValue = parseRadius(value)
+ self.guiObject.setCornerRadius(radius, edgeValue)
def scrollbarSliderBorderWidth(self, value):
self.guiObject.setScrollbarSliderBorderWidth(parseScale(value))
diff --git a/lib/service/iservice.h b/lib/service/iservice.h
index 605e967a17..25ff85f2a5 100644
--- a/lib/service/iservice.h
+++ b/lib/service/iservice.h
@@ -168,7 +168,7 @@ class eServiceReference
std::string toCompareString() const;
bool operator==(const eServiceReference &c) const
{
- if (type != c.type)
+ if (!c || type != c.type)
return 0;
return (memcmp(data, c.data, sizeof(int)*8)==0) && (path == c.path);
}
@@ -178,6 +178,8 @@ class eServiceReference
}
bool operator<(const eServiceReference &c) const
{
+ if (!c) return 0;
+
if (type < c.type)
return 1;
diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp
index f67cfdf4b3..a3eed7ce53 100644
--- a/lib/service/listboxservice.cpp
+++ b/lib/service/listboxservice.cpp
@@ -715,11 +715,19 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const
style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
eListboxStyle *local_style = 0;
+ eRect itemRect = eRect(offset, m_itemsize);
+ int radius = 0;
+ int edges = 0;
/* get local listbox style, if present */
if (m_listbox)
local_style = m_listbox->getLocalStyle();
+ if (local_style) {
+ radius = local_style->cornerRadius(selected ? 1:0);
+ edges = local_style->cornerRadiusEdges(selected ? 1:0);
+ }
+
if (marked == 1) // marked
{
style.setStyle(painter, eWindowStyle::styleListboxMarked);
@@ -764,13 +772,19 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const
/* 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 if (local_style && !local_style->m_background && radius)
+ {
+ if(radius)
+ painter.setRadius(radius, edges);
+ painter.drawRectangle(itemRect);
+ }
else
painter.clear();
} else
{
if (local_style->m_background)
painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHABLEND);
- else if (selected && !local_style->m_selection && !local_style->m_selection_large)
+ else if (selected && !local_style->m_selection && !local_style->m_selection_large && !radius)
painter.clear();
}
@@ -784,8 +798,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const
}
// Draw the frame for selected item here so to be under the content
- if (selected && (!local_style || (!local_style->m_selection && !local_style->m_selection_large)))
- style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
+ if (selected && (!local_style || (!local_style->m_selection && !local_style->m_selection_large)) && !radius)
+ style.drawFrame(painter, itemRect, eWindowStyle::frameListboxEntry);
eServiceReference ref = *m_cursor;
std::string orig_ref_str = ref.toString();
diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp
index ea45a71237..9765134cb4 100644
--- a/lib/service/servicedvb.cpp
+++ b/lib/service/servicedvb.cpp
@@ -106,7 +106,7 @@ int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const
int system;
((const eServiceReferenceDVB&)ref).getChannelID(chid);
((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
- return res_mgr->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system);
+ return res_mgr->canAllocateChannel(chid, chid_ignore, system);
}
return 0;
}
@@ -251,7 +251,7 @@ int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref
};
int system;
((const eServiceReferenceDVB&)*it).getChannelID(chid);
- int tmp = res->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system, simulate);
+ int tmp = res->canAllocateChannel(chid, chid_ignore, system, simulate);
if (prio_order == 127) // ignore dvb-type priority, try all alternatives one-by-one
{
if (((tmp > 0) || (!it->path.empty())))
@@ -403,7 +403,7 @@ int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
/* check if cached data is still valid */
if (m_parser.m_data_ok && (s.st_size == m_parser.m_filesize) && (m_parser.m_length))
- return m_parser.m_length / 90000;
+ return (int)(m_parser.m_length / 90000);
/* open again, this time with stream info */
if (tstools.openFile(ref.path.c_str()))
@@ -423,7 +423,7 @@ int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
m_parser.m_length = len;
m_parser.m_filesize = s.st_size;
m_parser.updateMeta(ref.path);
- return m_parser.m_length / 90000;
+ return (int)(m_parser.m_length / 90000);
}
int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
@@ -638,7 +638,9 @@ RESULT eDVBPVRServiceOfflineOperations::reindex()
int result;
/* Release global interpreter lock */
Py_BEGIN_ALLOW_THREADS;
- result = reindex_work(m_ref.path.c_str());
+ {
+ result = reindex_work(m_ref.path.c_str());
+ }
Py_END_ALLOW_THREADS;
return result;
}
@@ -2038,20 +2040,8 @@ std::string eDVBServicePlay::getInfoString(int w)
switch (w)
{
case sProvider:
- {
if (!m_dvb_service) return "";
- std::string prov = m_dvb_service->m_provider_name;
- if (prov.empty()) {
- eServiceReferenceDVB sRelayOrigSref;
- bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(sRelayOrigSref);
- if (res) {
- ePtr sRelayServiceOrigSref;
- eDVBDB::getInstance()->getService(sRelayOrigSref, sRelayServiceOrigSref);
- return sRelayServiceOrigSref->m_provider_name;
- }
- }
- return prov;
- }
+ return m_dvb_service->m_provider_name;
case sServiceref:
return m_reference.toString();
case sHBBTVUrl:
@@ -2240,8 +2230,8 @@ int eDVBServicePlay::selectAudioStream(int i)
int rdsPid = apid;
- /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
- if (!(m_timeshift_active || m_decoder_index || m_have_video_pid || !m_is_primary))
+ /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
+ if (!(m_is_pvr || m_timeshift_active || m_decoder_index || m_have_video_pid || !m_is_primary))
{
int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
if (different_pid)
@@ -2404,8 +2394,7 @@ bool eDVBServiceBase::tryFallbackTuner(eServiceReferenceDVB &service, bool &is_s
return false;
service.getChannelID(chid); // this sets chid
eServiceReferenceDVB().getChannelID(chid_ignore); // this sets chid_ignore
-
- if(res_mgr->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system)) // this sets system
+ if(res_mgr->canAllocateChannel(chid, chid_ignore, system)) // this sets system
return false;
if (eConfigManager::getConfigBoolValue("config.usage.remote_fallback_alternative", false) && !(system == iDVBFrontend::feSatellite))