From 2b64c52a2ff51e6bae6cc693d95c513d1d163da4 Mon Sep 17 00:00:00 2001 From: Michael Liebmann Date: Mon, 13 May 2013 06:31:02 +0200 Subject: [PATCH] Rework handling muteicon - Integrated for monitoring the mute icon into the frame buffer class. If the icon is overwritten by an element, it is restored from the framebuffer. Signed-off-by: Thilo Graf Origin commit data ------------------ Commit: https://github.com/neutrino-images/ni-neutrino/commit/1049b337bb98d7e02e3982086bbcb4e0f6d12d71 Author: Michael Liebmann Date: 2013-05-13 (Mon, 13 May 2013) Origin message was: ------------------ * Rework handling muteicon - Integrated for monitoring the mute icon into the frame buffer class. If the icon is overwritten by an element, it is restored from the framebuffer. Signed-off-by: Thilo Graf --- src/driver/fontrenderer.cpp | 3 + src/driver/framebuffer.cpp | 135 +++++++++++++++++++++++++++++++++--- src/driver/framebuffer.h | 66 +++++++++++++++--- src/gui/audiomute.cpp | 47 +++++++++++-- src/gui/audiomute.h | 3 + 5 files changed, 228 insertions(+), 26 deletions(-) diff --git a/src/driver/fontrenderer.cpp b/src/driver/fontrenderer.cpp index f0d0220db..b92accfa7 100644 --- a/src/driver/fontrenderer.cpp +++ b/src/driver/fontrenderer.cpp @@ -372,6 +372,8 @@ void Font::RenderString(int x, int y, const int width, const char *text, const u if (!frameBuffer->getActive()) return; + frameBuffer->checkFbArea(x, y, width, height, true); + pthread_mutex_lock( &renderer->render_mutex ); FT_Error err = FTC_Manager_LookupSize(renderer->cacheManager, &scaler, &size); @@ -620,6 +622,7 @@ void Font::RenderString(int x, int y, const int width, const char *text, const u } //printf("RenderStat: %d %d %d \n", renderer->cacheManager->num_nodes, renderer->cacheManager->num_bytes, renderer->cacheManager->max_bytes); pthread_mutex_unlock( &renderer->render_mutex ); + frameBuffer->checkFbArea(x, y, width, height, false); } void Font::RenderString(int x, int y, const int width, const std::string & text, const unsigned char color, const int boxheight, const bool utf8_encoded) diff --git a/src/driver/framebuffer.cpp b/src/driver/framebuffer.cpp index 15c99a2e9..fdac73996 100644 --- a/src/driver/framebuffer.cpp +++ b/src/driver/framebuffer.cpp @@ -4,21 +4,27 @@ Copyright (C) 2001 Steffen Hehn 'McClean' 2003 thegoodguy + mute icon handling from tuxbox project + Copyright (C) 2009 Stefan Seyfried + mute icon & info clock handling + Copyright (C) 2013 M. Liebmann (micha-bbg) + License: GPL - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H @@ -38,6 +44,7 @@ #include +#include #include #include #include @@ -196,6 +203,9 @@ CFrameBuffer::CFrameBuffer() memset(green, 0, 256*sizeof(__u16)); memset(blue, 0, 256*sizeof(__u16)); memset(trans, 0, 256*sizeof(__u16)); + fbAreaActiv = false; + fb_no_check = false; + do_paint_mute_icon = true; } CFrameBuffer* CFrameBuffer::getInstance() @@ -402,6 +412,8 @@ CFrameBuffer::~CFrameBuffer() } close(fd); close(tty); + + v_fbarea.clear(); } int CFrameBuffer::getFileHandle() const @@ -651,12 +663,16 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int printf("paintBoxRel: radius %d, start x %d y %d end x %d y %d\n", radius, x, y, x+dx, y+dy); return; } + + checkFbArea(x, y, dx, dy, true); + #if defined(FB_HW_ACCELERATION) fb_fillrect fillrect; fillrect.color = col; fillrect.rop = ROP_COPY; #elif defined(USE_NEVIS_GXA) - OpenThreads::ScopedLock m_lock(mutex); + if (!fb_no_check) + OpenThreads::ScopedLock m_lock(mutex); /* solid fill with background color */ unsigned int cmd = GXA_CMD_BLT | GXA_CMD_NOT_TEXT | GXA_SRC_BMP_SEL(7) | GXA_DST_BMP_SEL(2) | GXA_PARAM_COUNT(2) | GXA_CMD_NOT_ALPHA; _write_gxa(gxa_base, GXA_BG_COLOR_REG, (unsigned int) col); /* setup the drawing color */ @@ -805,6 +821,7 @@ void CFrameBuffer::paintBoxRel(const int x, const int y, const int dx, const int */ add_gxa_sync_marker(); #endif + checkFbArea(x, y, dx, dy, false); } void CFrameBuffer::paintVLineRelInternal(int x, int y, int dy, const fb_pixel_t col) @@ -1069,9 +1086,11 @@ _display: if (h != 0) yy += (h - height) / 2; + checkFbArea(x, yy, width, height, true); if (paintBg) paintBoxRel(x, yy, width, height, colBg); blit2FB(data, width, height, x, yy, 0, 0, true); + checkFbArea(x, yy, width, height, false); return true; } @@ -1475,6 +1494,7 @@ void CFrameBuffer::paintBackgroundBoxRel(int x, int y, int dx, int dy) if (!getActive()) return; + checkFbArea(x, y, dx, dy, true); if(!useBackgroundPaint) { paintBoxRel(x, y, dx, dy, backgroundColor); @@ -1490,6 +1510,7 @@ void CFrameBuffer::paintBackgroundBoxRel(int x, int y, int dx, int dy) bkpos += BACKGROUNDIMAGEWIDTH; } } + checkFbArea(x, y, dx, dy, false); } void CFrameBuffer::paintBackground() @@ -1497,6 +1518,7 @@ void CFrameBuffer::paintBackground() if (!getActive()) return; + checkFbArea(0, 0, xRes, yRes, true); if (useBackgroundPaint && (background != NULL)) { for (int i = 0; i < 576; i++) @@ -1506,6 +1528,7 @@ void CFrameBuffer::paintBackground() { paintBoxRel(0, 0, xRes, yRes, backgroundColor); } + checkFbArea(0, 0, xRes, yRes, false); } void CFrameBuffer::SaveScreen(int x, int y, int dx, int dy, fb_pixel_t * const memp) @@ -1513,6 +1536,7 @@ void CFrameBuffer::SaveScreen(int x, int y, int dx, int dy, fb_pixel_t * const m if (!getActive()) return; + checkFbArea(x, y, dx, dy, true); uint8_t * pos = ((uint8_t *)getFrameBufferPointer()) + x * sizeof(fb_pixel_t) + stride * y; fb_pixel_t * bkpos = memp; for (int count = 0; count < dy; count++) { @@ -1536,6 +1560,7 @@ void CFrameBuffer::SaveScreen(int x, int y, int dx, int dy, fb_pixel_t * const m bkpos += dx; } #endif + checkFbArea(x, y, dx, dy, false); } @@ -1544,6 +1569,7 @@ void CFrameBuffer::RestoreScreen(int x, int y, int dx, int dy, fb_pixel_t * cons if (!getActive()) return; + checkFbArea(x, y, dx, dy, true); uint8_t * fbpos = ((uint8_t *)getFrameBufferPointer()) + x * sizeof(fb_pixel_t) + stride * y; fb_pixel_t * bkpos = memp; for (int count = 0; count < dy; count++) @@ -1552,6 +1578,7 @@ void CFrameBuffer::RestoreScreen(int x, int y, int dx, int dy, fb_pixel_t * cons fbpos += stride; bkpos += dx; } + checkFbArea(x, y, dx, dy, false); } #if 0 //never used @@ -1768,3 +1795,91 @@ void CFrameBuffer::displayRGB(unsigned char *rgbbuff, int x_size, int y_size, in blit2FB(fbbuff, x_size, y_size, x_offs, y_offs, x_pan, y_pan); cs_free_uncached(fbbuff); } + +// ## AudioMute / Clock ###################################### + +void CFrameBuffer::setFbArea(int element, int _x, int _y, int _dx, int _dy) +{ + if (_x == 0 && _y == 0 && _dx == 0 && _dy == 0) { + // delete area + for (fbarea_iterator_t it = v_fbarea.begin(); it != v_fbarea.end(); ++it) { + if (it->element == element) { + v_fbarea.erase(it); + break; + } + } + if (v_fbarea.empty()) { + fbAreaActiv = false; + } + } + else { + // change area + bool found = false; + for (unsigned int i = 0; i < v_fbarea.size(); i++) { + if (v_fbarea[i].element == element) { + v_fbarea[i].x = _x; + v_fbarea[i].y = _y; + v_fbarea[i].dx = _dx; + v_fbarea[i].dy = _dy; + found = true; + break; + } + } + // set new area + if (!found) { + fb_area_t area; + area.x = _x; + area.y = _y; + area.dx = _dx; + area.dy = _dy; + area.element = element; + v_fbarea.push_back(area); + } + fbAreaActiv = true; + } +} + +int CFrameBuffer::checkFbAreaElement(int _x, int _y, int _dx, int _dy, fb_area_t *area) +{ + if (fb_no_check) + return FB_PAINTAREA_MATCH_NO; + + if (_y > area->y + area->dy) + return FB_PAINTAREA_MATCH_NO; + if (_x + _dx < area->x) + return FB_PAINTAREA_MATCH_NO; + if (_x > area->x + area->dx) + return FB_PAINTAREA_MATCH_NO; + if (_y + _dy < area->y) + return FB_PAINTAREA_MATCH_NO; + return FB_PAINTAREA_MATCH_OK; +} + +bool CFrameBuffer::_checkFbArea(int _x, int _y, int _dx, int _dy, bool prev) +{ + if (v_fbarea.empty()) + return true; + + for (unsigned int i = 0; i < v_fbarea.size(); i++) { + int ret = checkFbAreaElement(_x, _y, _dx, _dy, &v_fbarea[i]); + if (ret == FB_PAINTAREA_MATCH_OK) { + switch (v_fbarea[i].element) { + case FB_PAINTAREA_MUTEICON1: + if (!do_paint_mute_icon) + break; +// waitForIdle(); + fb_no_check = true; + if (prev) + CAudioMute::getInstance()->hide(true); + else + CAudioMute::getInstance()->paint(); + fb_no_check = false; + break; + default: + break; + } + } + } + + return true; +} diff --git a/src/driver/framebuffer.h b/src/driver/framebuffer.h index dbe42cf52..27218ac7f 100644 --- a/src/driver/framebuffer.h +++ b/src/driver/framebuffer.h @@ -2,23 +2,23 @@ Neutrino-GUI - DBoxII-Project Copyright (C) 2001 Steffen Hehn 'McClean' - Homepage: http://dbox.cyberphoria.org/ License: GPL - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. */ @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -243,6 +244,51 @@ class CFrameBuffer }; void SetTransparent(int t){ m_transparent = t; } void SetTransparentDefault(){ m_transparent = m_transparent_default; } + +// ## AudioMute / Clock ###################################### + private: + enum { + FB_PAINTAREA_MATCH_NO, + FB_PAINTAREA_MATCH_OK + }; + + typedef struct fb_area_t + { + int x; + int y; + int dx; + int dy; + int element; + } fb_area_struct_t; + + bool fbAreaActiv; + typedef std::vector v_fbarea_t; + typedef v_fbarea_t::iterator fbarea_iterator_t; + v_fbarea_t v_fbarea; + bool fb_no_check; + bool do_paint_mute_icon; + + bool _checkFbArea(int _x, int _y, int _dx, int _dy, bool prev); + int checkFbAreaElement(int _x, int _y, int _dx, int _dy, fb_area_t *area); + + public: + enum { + FB_PAINTAREA_INFOCLOCK, + FB_PAINTAREA_MUTEICON1, + FB_PAINTAREA_MUTEICON2, + + FB_PAINTAREA_MAX + }; + +#if defined(FB_HW_ACCELERATION) + inline bool checkFbArea(int, int, int, int, bool) { return true; } +#else + inline bool checkFbArea(int _x, int _y, int _dx, int _dy, bool prev) { return (fbAreaActiv && !fb_no_check) ? _checkFbArea(_x, _y, _dx, _dy, prev) : true; } +#endif + + void setFbArea(int element, int _x=0, int _y=0, int _dx=0, int _dy=0); + void fbNoCheck(bool noCheck) { fb_no_check = noCheck; } + void doPaintMuteIcon(bool mode) { do_paint_mute_icon = mode; } }; #endif diff --git a/src/gui/audiomute.cpp b/src/gui/audiomute.cpp index 0cb46bc5a..fa22f6714 100644 --- a/src/gui/audiomute.cpp +++ b/src/gui/audiomute.cpp @@ -36,7 +36,9 @@ CAudioMute::CAudioMute():CComponentsPicture(0, 0, 0, 0, NEUTRINO_ICON_BUTTON_MUTE) { - y_old = -1; + y_old = -1; + paint_bg = false; + do_paint_mute_icon = true; CVolumeHelper::getInstance()->refresh(); CVolumeHelper::getInstance()->getMuteIconDimensions(&x, &y, &width, &height); } @@ -60,20 +62,53 @@ void CAudioMute::AudioMute(int newValue, bool isEvent) if( isEvent && ( neutrino->getMode() != CNeutrinoApp::mode_scart ) && ( neutrino->getMode() != CNeutrinoApp::mode_audio) && ( neutrino->getMode() != CNeutrinoApp::mode_pic)) { + CFrameBuffer *framebuffer = CFrameBuffer::getInstance(); CVolumeHelper::getInstance()->getMuteIconDimensions(&x, &y, &width, &height); if ((y_old != y)) { - this->hide(); + if (do_paint_mute_icon) + { + framebuffer->fbNoCheck(true); + this->hide(true); + framebuffer->fbNoCheck(false); + } + framebuffer->setFbArea(CFrameBuffer::FB_PAINTAREA_MUTEICON1); y_old = y; } if ((g_settings.mode_clock) && (doInit)) CInfoClock::getInstance()->ClearDisplay(); - if (newValue) - this->paint(); - else - this->hide(); + framebuffer->fbNoCheck(true); + if (newValue) { + if (do_paint_mute_icon) + this->paint(); + framebuffer->setFbArea(CFrameBuffer::FB_PAINTAREA_MUTEICON1, this->getXPos(), this->getYPos(), this->getWidth(), this->getHeight()); + } + else { + if (do_paint_mute_icon) + this->hide(true); + framebuffer->setFbArea(CFrameBuffer::FB_PAINTAREA_MUTEICON1); + } + framebuffer->fbNoCheck(false); if (doInit) CVolumeHelper::getInstance()->refresh(); } } + +void CAudioMute::enableMuteIcon(bool enable) +{ + CNeutrinoApp *neutrino = CNeutrinoApp::getInstance(); + CFrameBuffer *framebuffer = CFrameBuffer::getInstance(); + if (enable) { + framebuffer->doPaintMuteIcon(true); + do_paint_mute_icon = true; + if (neutrino->isMuted()) + this->paint(); + } + else { + if (neutrino->isMuted()) + this->hide(true); + framebuffer->doPaintMuteIcon(false); + do_paint_mute_icon = false; + } +} diff --git a/src/gui/audiomute.h b/src/gui/audiomute.h index 18dfcc8f5..406483f18 100644 --- a/src/gui/audiomute.h +++ b/src/gui/audiomute.h @@ -33,6 +33,7 @@ class CAudioMute : public CComponentsPicture { private: int y_old; + bool do_paint_mute_icon; public: @@ -41,6 +42,8 @@ class CAudioMute : public CComponentsPicture static CAudioMute* getInstance(); void AudioMute(int newValue, bool isEvent= false); + void doPaintMuteIcon(bool mode) { do_paint_mute_icon = mode; } + void enableMuteIcon(bool enable); }; #endif // __CAUDIOMUTE__