diff --git a/src/driver/framebuffer_spark.cpp b/src/driver/framebuffer_spark.cpp index 6a67cb415..0b53538ed 100644 --- a/src/driver/framebuffer_spark.cpp +++ b/src/driver/framebuffer_spark.cpp @@ -1509,14 +1509,42 @@ void CFrameBuffer::displayRGB(unsigned char *rgbbuff, int x_size, int y_size, in void CFrameBuffer::blitRect(int x, int y, int width, int height, unsigned long color) { //printf ("[fb - blitRect]: x=%d, y=%d, width=%d, height=%d\n", x, y, width, height); - if (width == 0 || height == 0) + if (width <= 0 || height <= 0) return; - if (x + width > (int)xRes) { + /* maybe we should just return instead of fixing this up... */ + if (x < 0) { + fprintf(stderr, "[neutrino] fb::%s: x < 0 (%d)\n", __func__, x); + width += x; + if (width <= 0) + return; + x = 0; + } + + if (y < 0) { + fprintf(stderr, "[neutrino] fb::%s: y < 0 (%d)\n", __func__, y); + height += y; + if (height <= 0) + return; + y = 0; + } + + int right = x + width; + int bottom = y + height; + + if (right > (int)xRes) { + if (x >= (int)xRes) { + fprintf(stderr, "[neutrino] fb::%s: x >= xRes (%d > %d)\n", __func__, x, xRes); + return; + } fprintf(stderr, "[neutrino] fb::%s: x + w > xRes! (%d+%d > %d)\n", __func__, x, width, xRes); width = xRes - x; } - if (y + height > (int)yRes) { + if (bottom > (int)yRes) { + if (y >= (int)yRes) { + fprintf(stderr, "[neutrino] fb::%s: y >= yRes (%d > %d)\n", __func__, y, yRes); + return; + } fprintf(stderr, "[neutrino] fb::%s: y + h > yRes! (%d+%d > %d)\n", __func__, y, height, yRes); height = yRes - y; } @@ -1530,8 +1558,8 @@ void CFrameBuffer::blitRect(int x, int y, int width, int height, unsigned long c bltData.dst_left = x; bltData.dst_top = y; - bltData.dst_right = x + width; - bltData.dst_bottom = y + height; + bltData.dst_right = right; + bltData.dst_bottom = bottom; bltData.dstFormat = SURF_ARGB8888; bltData.srcFormat = SURF_ARGB8888; diff --git a/src/driver/simple_display.cpp b/src/driver/simple_display.cpp index 5f87a59a1..144abd363 100644 --- a/src/driver/simple_display.cpp +++ b/src/driver/simple_display.cpp @@ -117,8 +117,12 @@ void* CLCD::TimeThread(void *) CLCD::getInstance()->showTime(); /* hack, just if we missed the blit() somewhere * this will update the framebuffer once per second */ - if (getenv("SPARK_NOBLIT") == NULL) - CFrameBuffer::getInstance()->blit(); + if (getenv("SPARK_NOBLIT") == NULL) { + CFrameBuffer *fb = CFrameBuffer::getInstance(); + /* plugin start locks the framebuffer... */ + if (!fb->Locked()) + fb->blit(); + } } return NULL; } diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index cc92e4374..2ded78448 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -299,6 +299,7 @@ int CChannelList::doChannelMenu(void) static int old_selected = 0; char cnt[5]; bool enabled = true; + bool unlocked = true; if(g_settings.minimode) return 0; @@ -315,14 +316,21 @@ int CChannelList::doChannelMenu(void) menu->enableSaveScreen(true); CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select); + /* Allow bouquet manipulation only if the bouquet is unlocked. Without this, + * a channel could be added/removed to/from an unlocked bouquet and so made + * accessible. */ + if (g_settings.parentallock_prompt == PARENTALLOCK_PROMPT_CHANGETOLOCKED && + chanlist[selected]->bAlwaysLocked != g_settings.parentallock_defaultlocked) + unlocked = (chanlist[selected]->last_unlocked_time + 3600 > time_monotonic()); + snprintf(cnt, sizeof(cnt), "%d", i); - menu->addItem(new CMenuForwarder(LOCALE_BOUQUETEDITOR_DELETE, enabled, NULL, selector, cnt, CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED), old_selected == i++); + menu->addItem(new CMenuForwarder(LOCALE_BOUQUETEDITOR_DELETE, enabled && unlocked, NULL, selector, cnt, CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED), old_selected == i++); snprintf(cnt, sizeof(cnt), "%d", i); - menu->addItem(new CMenuForwarder(LOCALE_BOUQUETEDITOR_MOVE, enabled, NULL, selector, cnt, CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN), old_selected == i++); + menu->addItem(new CMenuForwarder(LOCALE_BOUQUETEDITOR_MOVE, enabled && unlocked, NULL, selector, cnt, CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN), old_selected == i++); snprintf(cnt, sizeof(cnt), "%d", i); - menu->addItem(new CMenuForwarder(LOCALE_EXTRA_ADD_TO_BOUQUET, true, NULL, selector, cnt, CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW), old_selected == i++); + menu->addItem(new CMenuForwarder(LOCALE_EXTRA_ADD_TO_BOUQUET, unlocked, NULL, selector, cnt, CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW), old_selected == i++); snprintf(cnt, sizeof(cnt), "%d", i); - menu->addItem(new CMenuForwarder(LOCALE_FAVORITES_MENUEADD, true, NULL, selector, cnt, CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE), old_selected == i++); + menu->addItem(new CMenuForwarder(LOCALE_FAVORITES_MENUEADD, unlocked, NULL, selector, cnt, CRCInput::RC_blue, NEUTRINO_ICON_BUTTON_BLUE), old_selected == i++); snprintf(cnt, sizeof(cnt), "%d", i); bool reset_enabled = chanlist[selected]->flags & CZapitChannel::NEW; menu->addItem(new CMenuForwarder(LOCALE_CHANNELLIST_RESET_FLAGS, reset_enabled, NULL, selector, cnt, CRCInput::convertDigitToKey(0)), old_selected == i++); diff --git a/src/gui/plugins.cpp b/src/gui/plugins.cpp index cedd41df5..e17204137 100644 --- a/src/gui/plugins.cpp +++ b/src/gui/plugins.cpp @@ -589,10 +589,13 @@ void CPlugins::startPlugin(int number,int /*param*/) #else g_RCInput->clearRCMsg(); g_RCInput->stopInput(); + /* stop automatic updates etc. */ + frameBuffer->Lock(); //frameBuffer->setMode(720, 576, 8 * sizeof(fb_pixel_t)); printf("Starting %s\n", plugin_list[number].pluginfile.c_str()); mysystem((char *) plugin_list[number].pluginfile.c_str(), NULL, NULL); //frameBuffer->setMode(720, 576, 8 * sizeof(fb_pixel_t)); + frameBuffer->Unlock(); frameBuffer->paintBackground(); g_RCInput->restartInput(); g_RCInput->clearRCMsg(); diff --git a/src/gui/scan.cpp b/src/gui/scan.cpp index 3d46ddfd0..f1e9a0fbd 100644 --- a/src/gui/scan.cpp +++ b/src/gui/scan.cpp @@ -427,6 +427,8 @@ int CScanTs::handleMsg(neutrino_msg_t msg, neutrino_msg_data_t data) delete (unsigned char*) data; break; } + /* almost all messages paint something, so blit here */ + frameBuffer->blit(); return msg; } diff --git a/src/gui/widget/hintboxext.cpp b/src/gui/widget/hintboxext.cpp index 8ec02ca89..813323e3b 100644 --- a/src/gui/widget/hintboxext.cpp +++ b/src/gui/widget/hintboxext.cpp @@ -43,8 +43,6 @@ #include -#define HINTBOXEXT_MAX_HEIGHT 420 - CHintBoxExt::CHintBoxExt(const neutrino_locale_t Caption, const char * const Text, const int Width, const char * const Icon) { m_message = strdup(Text); @@ -61,6 +59,7 @@ CHintBoxExt::CHintBoxExt(const neutrino_locale_t Caption, const char * const Tex m_lines.push_back(oneLine); begin = strtok(NULL, "\n"); } + m_bbheight = 0; init(Caption, Width, Icon); } @@ -69,6 +68,7 @@ CHintBoxExt::CHintBoxExt(const neutrino_locale_t Caption, ContentLines& lines, c { m_message = NULL; m_lines = lines; + m_bbheight = 0; init(Caption, Width, Icon); } @@ -115,6 +115,8 @@ void CHintBoxExt::init(const neutrino_locale_t Caption, const int Width, const c int line = 0; int maxWidth = m_width > 0 ? m_width : 0; int maxOverallHeight = 0; + int screenheight = CFrameBuffer::getInstance()->getScreenHeight() * 9 / 10 - m_bbheight; + m_startEntryOfPage.clear(); m_startEntryOfPage.push_back(0); for (ContentLines::iterator it = m_lines.begin(); it!=m_lines.end(); ++it) { @@ -133,7 +135,7 @@ void CHintBoxExt::init(const neutrino_locale_t Caption, const int Width, const c if (lineWidth > maxWidth) maxWidth = lineWidth; m_height += maxHeight; - if (m_height > HINTBOXEXT_MAX_HEIGHT || pagebreak) { + if (m_height > screenheight || pagebreak) { if (m_height-maxHeight > maxOverallHeight) maxOverallHeight = m_height - maxHeight; m_height = m_theight + m_fheight + maxHeight; @@ -216,11 +218,10 @@ void CHintBoxExt::paint(bool toround) return; } - CFrameBuffer* frameBuffer = CFrameBuffer::getInstance(); - m_window = new CFBWindow(frameBuffer->getScreenX() + ((frameBuffer->getScreenWidth() - m_width ) >> 1), - frameBuffer->getScreenY() + ((frameBuffer->getScreenHeight() - m_height) >> 2), - m_width + SHADOW_OFFSET, - m_height + SHADOW_OFFSET); + m_window = new CFBWindow(getScreenStartX(m_width + SHADOW_OFFSET), + getScreenStartY(m_height + SHADOW_OFFSET), + m_width + SHADOW_OFFSET, + m_height + SHADOW_OFFSET); refresh(toround); } diff --git a/src/gui/widget/hintboxext.h b/src/gui/widget/hintboxext.h index 64dc907c9..2472d17f6 100644 --- a/src/gui/widget/hintboxext.h +++ b/src/gui/widget/hintboxext.h @@ -55,6 +55,7 @@ class CHintBoxExt int m_width; int m_height; + int m_bbheight; /* a button bar at the bottom? */ int textStartX; int m_fheight; diff --git a/src/gui/widget/menue.cpp b/src/gui/widget/menue.cpp index 4f72749b2..aa9f8d4d0 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -843,7 +843,7 @@ void CMenuWidget::calcSize() full_width = width+sb_width+SHADOW_OFFSET; full_height = height+RADIUS_LARGE-2+SHADOW_OFFSET; - setMenuPos(width - sb_width); + setMenuPos(full_width); } void CMenuWidget::paint() @@ -890,7 +890,7 @@ void CMenuWidget::setMenuPos(const int& menu_width) { case MENU_POS_CENTER: x = offx + scr_x + ((scr_w - mn_width ) >> 1 ); - y = offy + scr_y + ((scr_h - height) >> 1 ); + y = offy + scr_y + ((scr_h - full_height) >> 1 ); break; case MENU_POS_TOP_LEFT: @@ -900,17 +900,17 @@ void CMenuWidget::setMenuPos(const int& menu_width) case MENU_POS_TOP_RIGHT: y = offy + scr_y + 10; - x = offx + scr_x + scr_w - mn_width - 10; + x = /*offx +*/ scr_x + scr_w - mn_width - 10; break; case MENU_POS_BOTTOM_LEFT: - y = offy + scr_y + scr_h - height - 10; + y = /*offy +*/ scr_y + scr_h - full_height - 10; x = offx + scr_x + 10; break; case MENU_POS_BOTTOM_RIGHT: - y = offy + scr_y + scr_h - height - 10; - x = offx + scr_x + scr_w - mn_width - 10; + y = /*offy +*/ scr_y + scr_h - full_height - 10; + x = /*offx +*/ scr_x + scr_w - mn_width - 10; break; } } diff --git a/src/gui/widget/messagebox.cpp b/src/gui/widget/messagebox.cpp index 9e8bddfbf..c845161a7 100644 --- a/src/gui/widget/messagebox.cpp +++ b/src/gui/widget/messagebox.cpp @@ -65,8 +65,7 @@ void CMessageBox::Init(const CMessageBox::result_ Default, const uint32_t ShowBu } fh = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight(); b_height = std::max(fh, ih) + 8 + (RADIUS_LARGE / 2); - bb_height = b_height + fh/2 + ButtonSpacing; - m_height += bb_height; + m_bbheight = b_height + fh/2 + ButtonSpacing; result = Default; b_width = getButtonWidth(); if (ShowButtons & CMessageBox::mbBtnAlignCenter1) @@ -101,10 +100,14 @@ void CMessageBox::Init(const CMessageBox::result_ Default, const uint32_t ShowBu ButtonDistance = ButtonSpacing; bb_width = b_width * ButtonCount + ButtonDistance * (ButtonCount - 1); if(bb_width > m_width) - m_width = bb_width; + m_width = bb_width; /* FIXME: what if bigger than screen area? */ else if (mbBtnAlign == CMessageBox::mbBtnAlignCenter1) ButtonDistance = (m_width - b_width * ButtonCount) / (ButtonCount + 1); + + /* this is ugly: re-init (CHintBoxExt) to recalculate the number of lines and pages */ + init(m_caption, m_width, m_iconfile == "" ? NULL : m_iconfile.c_str()); + m_height += m_bbheight; } void CMessageBox::returnDefaultValueOnTimeout(bool returnDefault) @@ -138,9 +141,9 @@ void CMessageBox::paintButtons() else if (mbBtnAlign == CMessageBox::mbBtnAlignRight) xpos = m_width - bb_width - ButtonSpacing; - int ypos = (m_height - bb_height) + fh/2; + int ypos = (m_height - m_bbheight) + fh/2; - m_window->paintBoxRel(0, m_height - bb_height, m_width, bb_height, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); + m_window->paintBoxRel(0, m_height - m_bbheight, m_width, m_bbheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); i = 0; if (showbuttons & mbYes) { diff --git a/src/gui/widget/messagebox.h b/src/gui/widget/messagebox.h index 67e063e0a..ea8a65e26 100644 --- a/src/gui/widget/messagebox.h +++ b/src/gui/widget/messagebox.h @@ -56,7 +56,7 @@ class CMessageBox : public CHintBoxExt int mbBtnAlign; int ButtonSpacing, ButtonDistance; int fh, i_maxw; - int b_height, b_width, bb_height, bb_width; + int b_height, b_width, bb_width; int ButtonCount; void paintButtons();