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))