mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-26 15:02:50 +02:00
add display support for osmio4k+
use --enable-lcd as configure option
Origin commit data
------------------
Branch: ni/coolstream
Commit: e2b7f4c6c1
Author: TangoCash <eric@loxat.de>
Date: 2022-10-09 (Sun, 09 Oct 2022)
------------------
This commit was generated by Migit
This commit is contained in:
25
configure.ac
25
configure.ac
@@ -186,6 +186,30 @@ AC_ARG_ENABLE(lcd4linux,
|
||||
AC_DEFINE(ENABLE_LCD4LINUX, 1, [enable LCD4Linux support]))
|
||||
AM_CONDITIONAL(ENABLE_LCD4LINUX, test "$enable_lcd4linux" = "yes")
|
||||
|
||||
# lcd
|
||||
AC_ARG_ENABLE(lcd,
|
||||
AS_HELP_STRING(--enable-lcd,include lcd support),
|
||||
,[enable_lcd=no])
|
||||
AM_CONDITIONAL(ENABLE_LCD,test "$enable_lcd" = "yes")
|
||||
|
||||
if test "$enable_lcd" = "yes"; then
|
||||
AC_DEFINE(ENABLE_LCD,1,[include lcd support])
|
||||
fi
|
||||
|
||||
# lcd update
|
||||
AM_CONDITIONAL(LCD_UPDATE,test "$enable_lcd_update" = "yes")
|
||||
|
||||
if test "$enable_lcd" = "yes"; then
|
||||
AC_DEFINE(LCD_UPDATE,1,[include lcd update support])
|
||||
fi
|
||||
|
||||
# lcdapi
|
||||
AM_CONDITIONAL(ENABLE_LCDAPI,test "$enable_lcd" = "yes")
|
||||
|
||||
if test "$enable_lcd" = "yes"; then
|
||||
AC_DEFINE(ENABLE_LCDAPI,1,[include lcd api support])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(graphlcd,
|
||||
AS_HELP_STRING([--enable-graphlcd], [enable GraphLCD support @<:@default=no@:>@]),
|
||||
AC_DEFINE(ENABLE_GRAPHLCD, 1, [enable GraphLCD support]))
|
||||
@@ -476,6 +500,7 @@ lib/connection/Makefile
|
||||
lib/hardware/coolstream/Makefile
|
||||
lib/jsoncpp/Makefile
|
||||
lib/libconfigfile/Makefile
|
||||
lib/liblcddisplay/Makefile
|
||||
lib/libdvbsub/Makefile
|
||||
lib/libeventserver/Makefile
|
||||
lib/libiw/Makefile
|
||||
|
@@ -18,6 +18,11 @@ SUBDIRS += \
|
||||
libupnpclient
|
||||
endif
|
||||
|
||||
if ENABLE_LCD
|
||||
SUBDIRS += \
|
||||
liblcddisplay
|
||||
endif
|
||||
|
||||
if BOXTYPE_CST
|
||||
SUBDIRS += \
|
||||
hardware/coolstream
|
||||
|
19
lib/liblcddisplay/Makefile.am
Normal file
19
lib/liblcddisplay/Makefile.am
Normal file
@@ -0,0 +1,19 @@
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/system \
|
||||
-I$(top_srcdir)/src/zapit/include \
|
||||
-I$(top_srcdir)/lib/connection \
|
||||
-I$(top_srcdir)/lib/libconfigfile \
|
||||
-I$(top_srcdir)/lib/libeventserver
|
||||
|
||||
AM_CPPFLAGS += -fno-rtti -fno-exceptions
|
||||
|
||||
noinst_LIBRARIES = liblcddisplay.a
|
||||
|
||||
liblcddisplay_a_SOURCES = lcddisplay.cpp fontrenderer.cpp
|
||||
|
||||
AM_CXXFLAGS = \
|
||||
@FREETYPE_CFLAGS@
|
371
lib/liblcddisplay/fontrenderer.cpp
Normal file
371
lib/liblcddisplay/fontrenderer.cpp
Normal file
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
$Header$
|
||||
|
||||
LCD-Daemon - DBoxII-Project
|
||||
|
||||
Copyright (C) 2001 Steffen Hehn 'McClean'
|
||||
Copyright (C) 2003 thegoodguy
|
||||
baseroutines by tmbinc
|
||||
|
||||
|
||||
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 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.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "fontrenderer.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <system/debug.h>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
/* tested with freetype 2.3.9, and 2.1.4 */
|
||||
#if FREETYPE_MAJOR >= 2 && FREETYPE_MINOR >= 3
|
||||
#define FT_NEW_CACHE_API
|
||||
#endif
|
||||
|
||||
// fribidi
|
||||
#if 0// defined (ENABLE_FRIBIDI)
|
||||
#include <fribidi/fribidi.h>
|
||||
#endif
|
||||
|
||||
FT_Error LcdFontRenderClass::myFTC_Face_Requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *aface)
|
||||
{
|
||||
return ((LcdFontRenderClass *)request_data)->FTC_Face_Requester(face_id, aface);
|
||||
}
|
||||
|
||||
|
||||
LcdFontRenderClass::LcdFontRenderClass(CLCDDisplay *fb)
|
||||
{
|
||||
framebuffer = fb;
|
||||
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::LcdFontRenderClass: initializing core...\n");
|
||||
|
||||
fflush(stdout);
|
||||
if (FT_Init_FreeType(&library))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::LcdFontRenderClass: failed.\n");
|
||||
return;
|
||||
}
|
||||
dprintf(DEBUG_NORMAL, "\n");
|
||||
font = 0;
|
||||
pthread_mutex_init(&render_mutex, NULL);
|
||||
}
|
||||
|
||||
LcdFontRenderClass::~LcdFontRenderClass()
|
||||
{
|
||||
FTC_Manager_Done(cacheManager);
|
||||
FT_Done_FreeType(library);
|
||||
}
|
||||
|
||||
void LcdFontRenderClass::InitFontCache()
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::InitFontCache: Intializing font cache...\n");
|
||||
|
||||
fflush(stdout);
|
||||
if (FTC_Manager_New(library, 3, 0, 0, myFTC_Face_Requester, this, &cacheManager))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::InitFontCache: manager failed!\n");
|
||||
return;
|
||||
}
|
||||
if (!cacheManager)
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::InitFontCache: error.\n");
|
||||
return;
|
||||
}
|
||||
if (FTC_SBitCache_New(cacheManager, &sbitsCache))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::InitFontCache: sbit failed!\n");
|
||||
return;
|
||||
}
|
||||
if (FTC_ImageCache_New(cacheManager, &imageCache))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::InitFontCache: imagecache failed!\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
FT_Error LcdFontRenderClass::FTC_Face_Requester(FTC_FaceID face_id, FT_Face *aface)
|
||||
{
|
||||
fontListEntry *font = (fontListEntry *)face_id;
|
||||
if (!font)
|
||||
return -1;
|
||||
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::FTC_Face_Requester: FTC_Face_Requester (%s/%s)\n", font->family, font->style);
|
||||
|
||||
int error;
|
||||
if ((error = FT_New_Face(library, font->filename, 0, aface)))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::FTC_Face_Requester: failed: %i\n", error);
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FTC_FaceID LcdFontRenderClass::getFaceID(const char *family, const char *style)
|
||||
{
|
||||
for (fontListEntry *f = font; f; f = f->next)
|
||||
{
|
||||
if ((!strcmp(f->family, family)) && (!strcmp(f->style, style)))
|
||||
return (FTC_FaceID)f;
|
||||
}
|
||||
for (fontListEntry *f = font; f; f = f->next)
|
||||
{
|
||||
if (!strcmp(f->family, family))
|
||||
return (FTC_FaceID)f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef FT_NEW_CACHE_API
|
||||
FT_Error LcdFontRenderClass::getGlyphBitmap(FTC_ImageType font, FT_ULong glyph_index, FTC_SBit *sbit)
|
||||
{
|
||||
return FTC_SBitCache_Lookup(sbitsCache, font, glyph_index, sbit, NULL);
|
||||
}
|
||||
#else
|
||||
FT_Error LcdFontRenderClass::getGlyphBitmap(FTC_Image_Desc *font, FT_ULong glyph_index, FTC_SBit *sbit)
|
||||
{
|
||||
return FTC_SBit_Cache_Lookup(sbitsCache, font, glyph_index, sbit);
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *LcdFontRenderClass::AddFont(const char *const filename)
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::AddFont: adding font %s...\n", filename);
|
||||
|
||||
fflush(stdout);
|
||||
int error;
|
||||
fontListEntry *n;
|
||||
|
||||
FT_Face face;
|
||||
if ((error = FT_New_Face(library, filename, 0, &face)))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::AddFont: failed: %i\n", error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n = new fontListEntry;
|
||||
|
||||
n->filename = strdup(filename);
|
||||
n->family = strdup(face->family_name);
|
||||
n->style = strdup(face->style_name);
|
||||
FT_Done_Face(face);
|
||||
|
||||
n->next = font;
|
||||
dprintf(DEBUG_NORMAL, "LcdFontRenderClass::AddFont: OK (%s/%s)\n", n->family, n->style);
|
||||
font = n;
|
||||
|
||||
return n->style;
|
||||
}
|
||||
|
||||
LcdFontRenderClass::fontListEntry::~fontListEntry()
|
||||
{
|
||||
free(filename);
|
||||
free(family);
|
||||
free(style);
|
||||
}
|
||||
|
||||
LcdFont *LcdFontRenderClass::getFont(const char *family, const char *style, int size)
|
||||
{
|
||||
FTC_FaceID id = getFaceID(family, style);
|
||||
if (!id)
|
||||
return 0;
|
||||
return new LcdFont(framebuffer, this, id, size);
|
||||
}
|
||||
|
||||
LcdFont::LcdFont(CLCDDisplay *fb, LcdFontRenderClass *render, FTC_FaceID faceid, int isize)
|
||||
{
|
||||
framebuffer = fb;
|
||||
renderer = render;
|
||||
#ifdef FT_NEW_CACHE_API
|
||||
font.face_id = faceid;
|
||||
font.width = isize;
|
||||
font.height = isize;
|
||||
font.flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_MONOCHROME;
|
||||
#else
|
||||
font.font.face_id = faceid;
|
||||
font.font.pix_width = isize;
|
||||
font.font.pix_height = isize;
|
||||
font.image_type = ftc_image_mono;
|
||||
font.image_type |= ftc_image_flag_autohinted;
|
||||
#endif
|
||||
}
|
||||
|
||||
FT_Error LcdFont::getGlyphBitmap(FT_ULong glyph_index, FTC_SBit *sbit)
|
||||
{
|
||||
return renderer->getGlyphBitmap(&font, glyph_index, sbit);
|
||||
}
|
||||
|
||||
extern int UTF8ToUnicode(const char *&text, const bool utf8_encoded); //defined in src/driver/fontrenderer.cpp
|
||||
#if 0 //defined (ENABLE_FRIBIDI)
|
||||
std::string fribidiShapeChar(const char *text, const bool utf8_encoded);
|
||||
#endif
|
||||
|
||||
void LcdFont::RenderString(int x, int y, const int width, const char *text, const int color, const int selected, const bool utf8_encoded)
|
||||
{
|
||||
int err;
|
||||
pthread_mutex_lock(&renderer->render_mutex);
|
||||
|
||||
// fribidi
|
||||
#if 0// defined (ENABLE_FRIBIDI)
|
||||
std::string Text = fribidiShapeChar(text, utf8_encoded);
|
||||
text = Text.c_str();
|
||||
#endif
|
||||
|
||||
#ifdef FT_NEW_CACHE_API
|
||||
FTC_ScalerRec scaler;
|
||||
|
||||
scaler.face_id = font.face_id;
|
||||
scaler.width = font.width;
|
||||
scaler.height = font.height;
|
||||
scaler.pixel = true;
|
||||
|
||||
if ((err = FTC_Manager_LookupSize(renderer->cacheManager, &scaler, &size)) != 0)
|
||||
#else
|
||||
if ((err = FTC_Manager_Lookup_Size(renderer->cacheManager, &font.font, &face, &size)) != 0)
|
||||
#endif
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFont::RenderString: FTC_Manager_Lookup_Size failed! (%d)\n", err);
|
||||
pthread_mutex_unlock(&renderer->render_mutex);
|
||||
return;
|
||||
}
|
||||
int left = x, step_y = (size->metrics.height >> 6) * 3 / 4 + 4;
|
||||
|
||||
int pos = 0;
|
||||
for (; *text; text++)
|
||||
{
|
||||
pos++;
|
||||
FTC_SBit glyph;
|
||||
//if ((x + size->metrics.x_ppem > (left+width)) || (*text=='\n'))
|
||||
if (x + size->metrics.x_ppem > (left + width))
|
||||
{
|
||||
//width clip
|
||||
break;
|
||||
}
|
||||
if (*text == '\n')
|
||||
{
|
||||
x = left;
|
||||
y += step_y;
|
||||
}
|
||||
|
||||
int unicode_value = UTF8ToUnicode(text, utf8_encoded);
|
||||
|
||||
if (unicode_value == -1)
|
||||
break;
|
||||
|
||||
#ifdef FT_NEW_CACHE_API
|
||||
int index = FT_Get_Char_Index(size->face, unicode_value);
|
||||
#else
|
||||
int index = FT_Get_Char_Index(face, unicode_value);
|
||||
#endif
|
||||
|
||||
if (!index)
|
||||
continue;
|
||||
if (getGlyphBitmap(index, &glyph))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFont::RenderString: failed to get glyph bitmap.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
int rx = x + glyph->left;
|
||||
int ry = y - glyph->top;
|
||||
if (pos == selected)
|
||||
{
|
||||
framebuffer->draw_fill_rect(x - 2, y - glyph->height - 2, x + glyph->width + 2, y + 2, CLCDDisplay::PIXEL_INV);
|
||||
}
|
||||
|
||||
for (int ay = 0; ay < glyph->height; ay++)
|
||||
{
|
||||
int ax = 0;
|
||||
int w = glyph->width;
|
||||
int xpos = rx;
|
||||
for (; ax < w; ax++)
|
||||
{
|
||||
unsigned char c = glyph->buffer[ay * abs(glyph->pitch) + (ax >> 3)];
|
||||
if ((c >> (7 - (ax & 7))) & 1)
|
||||
framebuffer->draw_point(xpos, ry, color);
|
||||
xpos ++;
|
||||
}
|
||||
ry++;
|
||||
}
|
||||
|
||||
x += glyph->xadvance + 1;
|
||||
}
|
||||
pthread_mutex_unlock(&renderer->render_mutex);
|
||||
}
|
||||
|
||||
int LcdFont::getRenderWidth(const char *text, const bool utf8_encoded)
|
||||
{
|
||||
pthread_mutex_lock(&renderer->render_mutex);
|
||||
|
||||
// fribidi
|
||||
#if 0// defined (ENABLE_FRIBIDI)
|
||||
std::string Text = fribidiShapeChar(text, utf8_encoded);
|
||||
text = Text.c_str();
|
||||
#endif
|
||||
|
||||
FT_Error err;
|
||||
#ifdef FT_NEW_CACHE_API
|
||||
FTC_ScalerRec scaler;
|
||||
scaler.face_id = font.face_id;
|
||||
scaler.width = font.width;
|
||||
scaler.height = font.height;
|
||||
scaler.pixel = true;
|
||||
|
||||
err = FTC_Manager_LookupSize(renderer->cacheManager, &scaler, &size);
|
||||
#else
|
||||
err = FTC_Manager_Lookup_Size(renderer->cacheManager, &font.font, &face, &size);
|
||||
#endif
|
||||
if (err != 0)
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFont::getRenderWidth: FTC_Manager_Lookup_Size failed! (0x%x)\n", err);
|
||||
pthread_mutex_unlock(&renderer->render_mutex);
|
||||
return -1;
|
||||
}
|
||||
int x = 0;
|
||||
for (; *text; text++)
|
||||
{
|
||||
FTC_SBit glyph;
|
||||
|
||||
int unicode_value = UTF8ToUnicode(text, utf8_encoded);
|
||||
|
||||
if (unicode_value == -1)
|
||||
break;
|
||||
|
||||
#ifdef FT_NEW_CACHE_API
|
||||
int index = FT_Get_Char_Index(size->face, unicode_value);
|
||||
#else
|
||||
int index = FT_Get_Char_Index(face, unicode_value);
|
||||
#endif
|
||||
|
||||
if (!index)
|
||||
continue;
|
||||
if (getGlyphBitmap(index, &glyph))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "LcdFont::getRenderWidth: failed to get glyph bitmap.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
x += glyph->xadvance + 1;
|
||||
}
|
||||
pthread_mutex_unlock(&renderer->render_mutex);
|
||||
return x;
|
||||
}
|
106
lib/liblcddisplay/fontrenderer.h
Normal file
106
lib/liblcddisplay/fontrenderer.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
$Header$
|
||||
|
||||
LCD-Daemon - DBoxII-Project
|
||||
|
||||
Copyright (C) 2001 Steffen Hehn 'McClean'
|
||||
baseroutines by tmbinc
|
||||
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 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.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __LCDFONTRENDERER__
|
||||
#define __LCDFONTRENDERER__
|
||||
|
||||
#include "lcddisplay.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_CACHE_H
|
||||
#include FT_CACHE_IMAGE_H
|
||||
#include FT_CACHE_SMALL_BITMAPS_H
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
class LcdFontRenderClass;
|
||||
class LcdFont
|
||||
{
|
||||
CLCDDisplay *framebuffer;
|
||||
#if FREETYPE_MAJOR >= 2 && FREETYPE_MINOR >= 3
|
||||
FTC_ImageTypeRec font;
|
||||
#else
|
||||
FTC_Image_Desc font;
|
||||
FT_Face face;
|
||||
#endif
|
||||
LcdFontRenderClass *renderer;
|
||||
FT_Size size;
|
||||
|
||||
FT_Error getGlyphBitmap(FT_ULong glyph_index, FTC_SBit *sbit);
|
||||
|
||||
public:
|
||||
void RenderString(int x, int y, int width, const char *text, int color, int selected = 0, const bool utf8_encoded = false);
|
||||
|
||||
int getRenderWidth(const char *text, const bool utf8_encoded = false);
|
||||
|
||||
LcdFont(CLCDDisplay *fb, LcdFontRenderClass *render, FTC_FaceID faceid, int isize);
|
||||
~LcdFont() {}
|
||||
};
|
||||
|
||||
class LcdFontRenderClass
|
||||
{
|
||||
CLCDDisplay *framebuffer;
|
||||
|
||||
struct fontListEntry
|
||||
{
|
||||
char *filename, *style, *family;
|
||||
fontListEntry *next;
|
||||
~fontListEntry();
|
||||
} *font;
|
||||
|
||||
FT_Library library;
|
||||
FTC_Manager cacheManager; /* the cache manager */
|
||||
FTC_ImageCache imageCache; /* the glyph image cache */
|
||||
FTC_SBitCache sbitsCache; /* the glyph small bitmaps cache */
|
||||
|
||||
FTC_FaceID getFaceID(const char *family, const char *style);
|
||||
#if FREETYPE_MAJOR >= 2 && FREETYPE_MINOR >= 3
|
||||
FT_Error getGlyphBitmap(FTC_ImageType font, FT_ULong glyph_index, FTC_SBit *sbit);
|
||||
#else
|
||||
FT_Error getGlyphBitmap(FTC_Image_Desc *font, FT_ULong glyph_index, FTC_SBit *sbit);
|
||||
#endif
|
||||
|
||||
public:
|
||||
pthread_mutex_t render_mutex;
|
||||
const char *AddFont(const char *const filename);
|
||||
void InitFontCache();
|
||||
|
||||
FT_Error FTC_Face_Requester(FTC_FaceID face_id, FT_Face *aface);
|
||||
|
||||
static FT_Error myFTC_Face_Requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *aface);
|
||||
|
||||
//FT_Face getFace(const char *family, const char *style);
|
||||
LcdFont *getFont(const char *family, const char *style, int size);
|
||||
LcdFontRenderClass(CLCDDisplay *fb);
|
||||
~LcdFontRenderClass();
|
||||
|
||||
friend class LcdFont;
|
||||
};
|
||||
|
||||
#endif /* __LCDFONTRENDERER__ */
|
950
lib/liblcddisplay/lcddisplay.cpp
Normal file
950
lib/liblcddisplay/lcddisplay.cpp
Normal file
@@ -0,0 +1,950 @@
|
||||
/*
|
||||
LCD-Daemon - DBoxII-Project
|
||||
|
||||
Copyright (C) 2001 Steffen Hehn 'McClean'
|
||||
baseroutines by Shadow_
|
||||
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 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.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "lcddisplay.h"
|
||||
|
||||
#include <png.h>
|
||||
|
||||
#include <stdint.h> /* uint8_t */
|
||||
#include <fcntl.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <byteswap.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
#error "no BYTE_ORDER defined!"
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b)(((a)<(b)) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b)(((a)<(b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
void CLCDDisplay::setSize(int w, int h, int b)
|
||||
{
|
||||
xres = w;
|
||||
yres = h;
|
||||
bpp = 8;
|
||||
bypp = 1;
|
||||
surface_bpp = b;
|
||||
|
||||
real_offset = 0;
|
||||
real_yres = yres;
|
||||
if (yres == 32)
|
||||
real_offset = 16;
|
||||
if (yres < 64)
|
||||
yres = 48;
|
||||
|
||||
switch (surface_bpp)
|
||||
{
|
||||
case 8:
|
||||
surface_bypp = 1;
|
||||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
surface_bypp = 2;
|
||||
break;
|
||||
case 24: // never use 24bit mode
|
||||
case 32:
|
||||
surface_bypp = 4;
|
||||
break;
|
||||
default:
|
||||
surface_bypp = (bpp + 7) / 8;
|
||||
}
|
||||
|
||||
surface_stride = xres * surface_bypp;
|
||||
surface_buffer_size = xres * yres * surface_bypp;
|
||||
surface_data = new unsigned char[surface_buffer_size];
|
||||
memset(surface_data, 0, surface_buffer_size);
|
||||
|
||||
printf("[CLCDDisplay] %s surface buffer %p %d bytes, stride %d\n", __FUNCTION__, surface_data, surface_buffer_size, surface_stride);
|
||||
|
||||
_stride = xres * bypp;
|
||||
raw_buffer_size = xres * yres * bypp;
|
||||
_buffer = new unsigned char[raw_buffer_size];
|
||||
memset(_buffer, 0, raw_buffer_size);
|
||||
|
||||
printf("[CLCDDisplay] %s lcd buffer %p %d bytes, stride %d, type %d\n", __FUNCTION__, _buffer, raw_buffer_size, _stride, is_oled);
|
||||
}
|
||||
|
||||
CLCDDisplay::CLCDDisplay()
|
||||
{
|
||||
paused = 0;
|
||||
available = false;
|
||||
|
||||
raw_buffer_size = 0;
|
||||
xres = 132;
|
||||
yres = 32;
|
||||
bpp = 8;
|
||||
|
||||
flipped = false;
|
||||
inverted = 0;
|
||||
is_oled = 0;
|
||||
last_brightness = 0;
|
||||
|
||||
//open device
|
||||
fd = open("/dev/dbox/oled0", O_RDWR);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
xres = 128;
|
||||
if (!access("/proc/stb/lcd/oled_brightness", W_OK) || !access("/proc/stb/fp/oled_brightness", W_OK))
|
||||
is_oled = 2;
|
||||
fd = open(LCD_DEVICE, O_RDWR);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("found OLED display!\n");
|
||||
is_oled = 1;
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("couldn't open LCD - load lcd.ko!\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = LCD_MODE_BIN;
|
||||
ioctl(fd, LCD_IOCTL_ASC_MODE, &i);
|
||||
|
||||
FILE *f = fopen("/proc/stb/lcd/xres", "r");
|
||||
if (f)
|
||||
{
|
||||
int tmp;
|
||||
if (fscanf(f, "%x", &tmp) == 1)
|
||||
xres = tmp;
|
||||
fclose(f);
|
||||
f = fopen("/proc/stb/lcd/yres", "r");
|
||||
if (f)
|
||||
{
|
||||
if (fscanf(f, "%x", &tmp) == 1)
|
||||
yres = tmp;
|
||||
fclose(f);
|
||||
f = fopen("/proc/stb/lcd/bpp", "r");
|
||||
if (f)
|
||||
{
|
||||
if (fscanf(f, "%x", &tmp) == 1)
|
||||
bpp = tmp;
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
is_oled = 3;
|
||||
}
|
||||
}
|
||||
|
||||
setSize(xres, yres, bpp);
|
||||
|
||||
available = true;
|
||||
iconBasePath = "";
|
||||
}
|
||||
|
||||
//e2
|
||||
void CLCDDisplay::setInverted(unsigned char inv)
|
||||
{
|
||||
inverted = inv;
|
||||
update();
|
||||
}
|
||||
|
||||
void CLCDDisplay::setFlipped(bool onoff)
|
||||
{
|
||||
flipped = onoff;
|
||||
update();
|
||||
}
|
||||
|
||||
int CLCDDisplay::setLCDContrast(int contrast)
|
||||
{
|
||||
return(0);
|
||||
|
||||
int fp;
|
||||
|
||||
fp = open("/dev/dbox/fp0", O_RDWR);
|
||||
|
||||
if (fp < 0)
|
||||
fp = open("/dev/dbox/lcd0", O_RDWR);
|
||||
if (fp < 0)
|
||||
{
|
||||
printf("[LCD] can't open /dev/dbox/fp0(%m)\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ioctl(fd, LCD_IOCTL_SRV, &contrast) < 0)
|
||||
{
|
||||
printf("[LCD] can't set lcd contrast(%m)\n");
|
||||
}
|
||||
close(fp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int CLCDDisplay::setLCDBrightness(int brightness)
|
||||
{
|
||||
printf("setLCDBrightness %d\n", brightness);
|
||||
|
||||
FILE *f = fopen("/proc/stb/lcd/oled_brightness", "w");
|
||||
if (!f)
|
||||
f = fopen("/proc/stb/fp/oled_brightness", "w");
|
||||
if (f)
|
||||
{
|
||||
if (fprintf(f, "%d", brightness) == 0)
|
||||
printf("write /proc/stb/lcd/oled_brightness failed!! (%m)\n");
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
int fp;
|
||||
if ((fp = open("/dev/dbox/fp0", O_RDWR)) < 0)
|
||||
{
|
||||
printf("[LCD] can't open /dev/dbox/fp0\n");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ioctl(fp, FP_IOCTL_LCD_DIMM, &brightness) < 0)
|
||||
printf("[LCD] can't set lcd brightness (%m)\n");
|
||||
close(fp);
|
||||
}
|
||||
|
||||
if (brightness == 0)
|
||||
{
|
||||
memset(_buffer, inverted, raw_buffer_size);
|
||||
update();
|
||||
}
|
||||
|
||||
last_brightness = brightness;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
bool CLCDDisplay::isAvailable()
|
||||
{
|
||||
return available;
|
||||
}
|
||||
|
||||
CLCDDisplay::~CLCDDisplay()
|
||||
{
|
||||
delete [] _buffer;
|
||||
|
||||
if (fd >= 0)
|
||||
{
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void CLCDDisplay::pause()
|
||||
{
|
||||
paused = 1;
|
||||
}
|
||||
|
||||
void CLCDDisplay::resume()
|
||||
{
|
||||
//clear the display
|
||||
if (ioctl(fd, LCD_IOCTL_CLEAR) < 0)
|
||||
printf("[lcddisplay] LCD_IOCTL_CLEAR failed (%m)\n");
|
||||
|
||||
//graphic (binary) mode
|
||||
int i = LCD_MODE_BIN;
|
||||
if (ioctl(fd, LCD_IOCTL_ASC_MODE, &i) < 0)
|
||||
printf("[lcddisplay] LCD_IOCTL_ASC_MODE failed (%m)\n");
|
||||
//
|
||||
|
||||
paused = 0;
|
||||
}
|
||||
|
||||
void CLCDDisplay::convert_data()
|
||||
{
|
||||
#ifndef PLATFORM_GENERIC
|
||||
unsigned int x, y, z;
|
||||
char tmp;
|
||||
|
||||
#if 0
|
||||
unsigned int height = yres;
|
||||
unsigned int width = xres;
|
||||
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
for (y = 0; y < (height / 8); y++)
|
||||
{
|
||||
tmp = 0;
|
||||
|
||||
for (z = 0; z < 8; z++)
|
||||
if (_buffer[(y * 8 + z) * width + x] == LCD_PIXEL_ON)
|
||||
tmp |= (1 << z);
|
||||
|
||||
lcd[y][x] = tmp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void CLCDDisplay::update()
|
||||
{
|
||||
#ifndef PLATFORM_GENERIC
|
||||
if ((fd >= 0) && (last_brightness > 0))
|
||||
{
|
||||
for (unsigned int y = 0; y < yres; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < xres; x++)
|
||||
{
|
||||
surface_fill_rect(x, y, x + 1, y + 1, _buffer[y * xres + x]);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_oled == 0 || is_oled == 2)
|
||||
{
|
||||
unsigned int height = yres;
|
||||
unsigned int width = xres;
|
||||
|
||||
|
||||
unsigned char raw[132 * 8];
|
||||
int x, y, yy;
|
||||
|
||||
memset(raw, 0x00, 132 * 8);
|
||||
|
||||
for (y = 0; y < 8; y++)
|
||||
{
|
||||
// display has only 128 but buffer must be 132
|
||||
for (x = 0; x < 128; x++)
|
||||
{
|
||||
int pix = 0;
|
||||
for (yy = 0; yy < 8; yy++)
|
||||
{
|
||||
pix |= (surface_data[(y * 8 + yy) * width + x] >= 108) << yy;
|
||||
}
|
||||
|
||||
if (flipped)
|
||||
{
|
||||
/* 8 pixels per byte, swap bits */
|
||||
#define BIT_SWAP(a) ((((a << 7)&0x80) + ((a << 5)&0x40) + ((a << 3)&0x20) + ((a << 1)&0x10) + ((a >> 1)&0x08) + ((a >> 3)&0x04) + ((a >> 5)&0x02) + ((a >> 7)&0x01))&0xff)
|
||||
raw[(7 - y) * 132 + (132 - 1 - x - 2)] = BIT_SWAP(pix ^ inverted);
|
||||
}
|
||||
else
|
||||
{
|
||||
raw[y * 132 + x + 2] = pix ^ inverted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write(fd, raw, 132 * 8);
|
||||
|
||||
}
|
||||
else if (is_oled == 3)
|
||||
{
|
||||
/* for now, only support flipping / inverting for 8bpp displays */
|
||||
if ((flipped || inverted) && surface_stride == xres)
|
||||
{
|
||||
unsigned int height = yres;
|
||||
unsigned int width = xres;
|
||||
unsigned char raw[surface_stride * height];
|
||||
|
||||
for (unsigned int y = 0; y < height; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < width; x++)
|
||||
{
|
||||
if (flipped)
|
||||
{
|
||||
/* 8bpp, no bit swapping */
|
||||
raw[(height - 1 - y) * width + (width - 1 - x)] = surface_data[y * width + x] ^ inverted;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw[y * width + x] = surface_data[y * width + x] ^ inverted;
|
||||
}
|
||||
}
|
||||
}
|
||||
write(fd, raw, surface_stride * height);
|
||||
}
|
||||
else
|
||||
{
|
||||
//write(fd, surface_data, surface_stride * yres);
|
||||
//
|
||||
#ifdef PLATFORM_GIGABLUE
|
||||
unsigned char gb_buffer[surface_stride * yres];
|
||||
for (int offset = 0; offset < surface_stride * yres; offset += 2)
|
||||
{
|
||||
gb_buffer[offset] = (surface_data[offset] & 0x1F) | ((surface_data[offset + 1] << 3) & 0xE0);
|
||||
gb_buffer[offset + 1] = ((surface_data[offset + 1] >> 5) & 0x03) | ((surface_data[offset] >> 3) & 0x1C) | ((_buffer[offset + 1] << 5) & 0x60);
|
||||
}
|
||||
write(fd, gb_buffer, surface_stride * yres);
|
||||
#else
|
||||
write(fd, surface_data + surface_stride * real_offset, surface_stride * real_yres);
|
||||
#endif
|
||||
//
|
||||
}
|
||||
}
|
||||
else /* is_oled == 1 */
|
||||
{
|
||||
unsigned char raw[64 * 64];
|
||||
int x, y;
|
||||
memset(raw, 0, 64 * 64);
|
||||
|
||||
for (y = 0; y < 64; y++)
|
||||
{
|
||||
int pix = 0;
|
||||
for (x = 0; x < 128 / 2; x++)
|
||||
{
|
||||
pix = (surface_data[y * 132 + x * 2 + 2] & 0xF0) | (surface_data[y * 132 + x * 2 + 1 + 2] >> 4);
|
||||
if (inverted)
|
||||
pix = 0xFF - pix;
|
||||
if (flipped)
|
||||
{
|
||||
/* device seems to be 4bpp, swap nibbles */
|
||||
unsigned char byte;
|
||||
byte = (pix >> 4) & 0x0f;
|
||||
byte |= (pix << 4) & 0xf0;
|
||||
raw[(63 - y) * 64 + (63 - x)] = byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
raw[y * 64 + x] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
write(fd, raw, 64 * 64);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CLCDDisplay::surface_fill_rect(int area_left, int area_top, int area_right, int area_bottom, int color)
|
||||
{
|
||||
int area_width = area_right - area_left;
|
||||
int area_height = area_bottom - area_top;
|
||||
|
||||
if (surface_bpp == 8)
|
||||
{
|
||||
for (int y = area_top; y < area_bottom; y++)
|
||||
memset(((uint8_t *)surface_data) + y * surface_stride + area_left, color, area_width);
|
||||
}
|
||||
else if (surface_bpp == 16)
|
||||
{
|
||||
uint32_t icol;
|
||||
|
||||
#if 0
|
||||
if (surface_clut.data && color < surface_clut.colors)
|
||||
icol = (surface_clut.data[color].a << 24) | (surface_clut.data[color].r << 16) | (surface_clut.data[color].g << 8) | (surface_clut.data[color].b);
|
||||
else
|
||||
#endif
|
||||
icol = 0x10101 * color;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
uint16_t col = bswap_16(((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19);
|
||||
#else
|
||||
uint16_t col = ((icol & 0xFF) >> 3) << 11 | ((icol & 0xFF00) >> 10) << 5 | (icol & 0xFF0000) >> 19;
|
||||
#endif
|
||||
for (int y = area_top; y < area_bottom; y++)
|
||||
{
|
||||
uint16_t *dst = (uint16_t *)(((uint8_t *)surface_data) + y * surface_stride + area_left * surface_bypp);
|
||||
int x = area_width;
|
||||
while (x--)
|
||||
*dst++ = col;
|
||||
}
|
||||
}
|
||||
else if (surface_bpp == 32)
|
||||
{
|
||||
uint32_t col;
|
||||
|
||||
#if 0
|
||||
if (surface_clut.data && color < surface_clut.colors)
|
||||
col = (surface_clut.data[color].a << 24) | (surface_clut.data[color].r << 16) | (surface_clut.data[color].g << 8) | (surface_clut.data[color].b);
|
||||
else
|
||||
#endif
|
||||
col = 0x10101 * color;
|
||||
|
||||
col ^= 0xFF000000;
|
||||
|
||||
#if 0
|
||||
if (surface_data_phys && gAccel::getInstance())
|
||||
if (!gAccel::getInstance()->fill(surface, area, col))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
for (int y = area_top; y < area_bottom; y++)
|
||||
{
|
||||
uint32_t *dst = (uint32_t *)(((uint8_t *)surface_data) + y * surface_stride + area_left * surface_bypp);
|
||||
int x = area_width;
|
||||
while (x--)
|
||||
*dst++ = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLCDDisplay::draw_point(const int x, const int y, const int state)
|
||||
{
|
||||
if ((x < 0) || (x >= xres) || (y < 0) || (y >= yres))
|
||||
return;
|
||||
|
||||
if (state == LCD_PIXEL_INV)
|
||||
_buffer[y * xres + x] ^= 1;
|
||||
else
|
||||
_buffer[y * xres + x] = state;
|
||||
}
|
||||
|
||||
/*
|
||||
* draw_line
|
||||
*
|
||||
* args:
|
||||
* x1 StartCol
|
||||
* y1 StartRow
|
||||
* x2 EndCol
|
||||
* y1 EndRow
|
||||
* state LCD_PIXEL_OFF/LCD_PIXEL_ON/LCD_PIXEL_INV
|
||||
*
|
||||
*/
|
||||
void CLCDDisplay::draw_line(const int x1, const int y1, const int x2, const int y2, const int state)
|
||||
{
|
||||
int dx = abs(x1 - x2);
|
||||
int dy = abs(y1 - y2);
|
||||
int x;
|
||||
int y;
|
||||
int End;
|
||||
int step;
|
||||
|
||||
if (dx > dy)
|
||||
{
|
||||
int p = 2 * dy - dx;
|
||||
int twoDy = 2 * dy;
|
||||
int twoDyDx = 2 * (dy - dx);
|
||||
|
||||
if (x1 > x2)
|
||||
{
|
||||
x = x2;
|
||||
y = y2;
|
||||
End = x1;
|
||||
step = y1 < y2 ? -1 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x1;
|
||||
y = y1;
|
||||
End = x2;
|
||||
step = y2 < y1 ? -1 : 1;
|
||||
}
|
||||
|
||||
draw_point(x, y, state);
|
||||
|
||||
while (x < End)
|
||||
{
|
||||
x++;
|
||||
if (p < 0)
|
||||
p += twoDy;
|
||||
else
|
||||
{
|
||||
y += step;
|
||||
p += twoDyDx;
|
||||
}
|
||||
draw_point(x, y, state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int p = 2 * dx - dy;
|
||||
int twoDx = 2 * dx;
|
||||
int twoDxDy = 2 * (dx - dy);
|
||||
|
||||
if (y1 > y2)
|
||||
{
|
||||
x = x2;
|
||||
y = y2;
|
||||
End = y1;
|
||||
step = x1 < x2 ? -1 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x1;
|
||||
y = y1;
|
||||
End = y2;
|
||||
step = x2 < x1 ? -1 : 1;
|
||||
}
|
||||
|
||||
draw_point(x, y, state);
|
||||
|
||||
while (y < End)
|
||||
{
|
||||
y++;
|
||||
if (p < 0)
|
||||
p += twoDx;
|
||||
else
|
||||
{
|
||||
x += step;
|
||||
p += twoDxDy;
|
||||
}
|
||||
draw_point(x, y, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLCDDisplay::draw_fill_rect(int left, int top, int right, int bottom, int state)
|
||||
{
|
||||
int x, y;
|
||||
for (x = left + 1; x < right; x++)
|
||||
{
|
||||
for (y = top + 1; y < bottom; y++)
|
||||
{
|
||||
draw_point(x, y, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLCDDisplay::draw_rectangle(int left, int top, int right, int bottom, int linestate, int fillstate)
|
||||
{
|
||||
// coordinate checking in draw_pixel (-> you can draw lines only
|
||||
// partly on screen)
|
||||
|
||||
draw_line(left, top, right, top, linestate);
|
||||
draw_line(left, top, left, bottom, linestate);
|
||||
draw_line(right, top, right, bottom, linestate);
|
||||
draw_line(left, bottom, right, bottom, linestate);
|
||||
draw_fill_rect(left, top, right, bottom, fillstate);
|
||||
}
|
||||
|
||||
void CLCDDisplay::draw_polygon(int num_vertices, int *vertices, int state)
|
||||
{
|
||||
// coordinate checking in draw_pixel (-> you can draw polygons only
|
||||
// partly on screen)
|
||||
|
||||
int i;
|
||||
for (i = 0; i < num_vertices - 1; i++)
|
||||
{
|
||||
draw_line(vertices[(i << 1) + 0],
|
||||
vertices[(i << 1) + 1],
|
||||
vertices[(i << 1) + 2],
|
||||
vertices[(i << 1) + 3],
|
||||
state);
|
||||
}
|
||||
|
||||
draw_line(vertices[0],
|
||||
vertices[1],
|
||||
vertices[(num_vertices << 1) - 2],
|
||||
vertices[(num_vertices << 1) - 1],
|
||||
state);
|
||||
}
|
||||
|
||||
struct rawHeader
|
||||
{
|
||||
uint8_t width_lo;
|
||||
uint8_t width_hi;
|
||||
uint8_t height_lo;
|
||||
uint8_t height_hi;
|
||||
uint8_t transp;
|
||||
} __attribute__((packed));
|
||||
|
||||
bool CLCDDisplay::paintIcon(std::string filename, int x, int y, bool invert)
|
||||
{
|
||||
struct rawHeader header;
|
||||
uint16_t stride;
|
||||
uint16_t height;
|
||||
unsigned char *pixpos;
|
||||
|
||||
int _fd;
|
||||
filename = iconBasePath + filename;
|
||||
|
||||
_fd = open(filename.c_str(), O_RDONLY);
|
||||
|
||||
if (_fd == -1)
|
||||
{
|
||||
printf("\nerror while loading icon: %s\n\n", filename.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
read(_fd, &header, sizeof(struct rawHeader));
|
||||
|
||||
stride = ((header.width_hi << 8) | header.width_lo) >> 1;
|
||||
height = (header.height_hi << 8) | header.height_lo;
|
||||
|
||||
unsigned char pixbuf[200];
|
||||
while (height-- > 0)
|
||||
{
|
||||
read(fd, &pixbuf, stride);
|
||||
pixpos = (unsigned char *) &pixbuf;
|
||||
for (int count2 = 0; count2 < stride; count2++)
|
||||
{
|
||||
unsigned char compressed = *pixpos;
|
||||
|
||||
draw_point(x + (count2 << 1), y, ((((compressed & 0xf0) >> 4) != header.transp) ^ invert) ? PIXEL_ON : PIXEL_OFF);
|
||||
draw_point(x + (count2 << 1) + 1, y, (((compressed & 0x0f) != header.transp) ^ invert) ? PIXEL_ON : PIXEL_OFF);
|
||||
|
||||
pixpos++;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
|
||||
close(_fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CLCDDisplay::clear_screen()
|
||||
{
|
||||
memset(_buffer, 0, raw_buffer_size);
|
||||
}
|
||||
|
||||
void CLCDDisplay::dump_screen(raw_display_t *screen)
|
||||
{
|
||||
memmove(*screen, _buffer, raw_buffer_size);
|
||||
}
|
||||
|
||||
void CLCDDisplay::load_screen_element(const raw_lcd_element_t *element, int left, int top)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
//if (element->buffer)
|
||||
// for (i = 0; i < element->header.height; i++)
|
||||
// memmove(_buffer+((top+i) * xres)+left, element->buffer+(i * element->header.width), element->header.width);
|
||||
//
|
||||
if ((element->buffer) && (element->header.height <= yres - top))
|
||||
for (i = 0; i < min(element->header.height, yres - top); i++)
|
||||
memmove(_buffer + ((top + i) * xres) + left, element->buffer + (i * element->header.width), min(element->header.width, xres - left));
|
||||
//
|
||||
}
|
||||
|
||||
void CLCDDisplay::load_screen(const raw_display_t *const screen)
|
||||
{
|
||||
raw_lcd_element_t element;
|
||||
element.buffer_size = raw_buffer_size;
|
||||
element.buffer = *screen;
|
||||
element.header.width = xres;
|
||||
element.header.height = yres;
|
||||
load_screen_element(&element, 0, 0);
|
||||
}
|
||||
|
||||
bool CLCDDisplay::load_png_element(const char *const filename, raw_lcd_element_t *element)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
unsigned int i;
|
||||
unsigned int pass;
|
||||
unsigned int number_passes;
|
||||
int bit_depth;
|
||||
int color_type;
|
||||
int interlace_type;
|
||||
png_uint_32 width;
|
||||
png_uint_32 height;
|
||||
png_byte *fbptr;
|
||||
FILE *fh;
|
||||
bool ret_value = false;
|
||||
|
||||
if ((fh = fopen(filename, "rb")))
|
||||
{
|
||||
if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
|
||||
{
|
||||
if (!(info_ptr = png_create_info_struct(png_ptr)))
|
||||
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
|
||||
else
|
||||
{
|
||||
#if (PNG_LIBPNG_VER < 10500)
|
||||
if (!(setjmp(png_ptr->jmpbuf)))
|
||||
#else
|
||||
if (!setjmp(png_jmpbuf(png_ptr)))
|
||||
#endif
|
||||
{
|
||||
unsigned int lcd_height = yres;
|
||||
unsigned int lcd_width = xres;
|
||||
|
||||
png_init_io(png_ptr, fh);
|
||||
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
|
||||
|
||||
if (
|
||||
((color_type == PNG_COLOR_TYPE_PALETTE) ||
|
||||
((color_type & PNG_COLOR_MASK_COLOR) == PNG_COLOR_TYPE_GRAY)) &&
|
||||
(bit_depth <= 8) &&
|
||||
(width <= lcd_width) &&
|
||||
(height <= lcd_height)
|
||||
)
|
||||
{
|
||||
printf("[CLCDDisplay] %s %s %dx%dx%d, type %d\n", __FUNCTION__, filename, width, height, bit_depth, color_type);
|
||||
element->header.width = width;
|
||||
element->header.height = height;
|
||||
element->header.bpp = bit_depth;
|
||||
if (!element->buffer)
|
||||
{
|
||||
element->buffer_size = width * height;
|
||||
element->buffer = new unsigned char[element->buffer_size];
|
||||
lcd_width = width;
|
||||
lcd_height = height;
|
||||
}
|
||||
|
||||
memset(element->buffer, 0, element->buffer_size);
|
||||
|
||||
png_set_packing(png_ptr); /* expand to 1 byte blocks */
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_expand(png_ptr);
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand(png_ptr);
|
||||
|
||||
if (color_type & PNG_COLOR_MASK_COLOR)
|
||||
#if (PNG_LIBPNG_VER < 10200)
|
||||
png_set_rgb_to_gray(png_ptr);
|
||||
#else
|
||||
png_set_rgb_to_gray(png_ptr, 1, NULL, NULL);
|
||||
#endif
|
||||
|
||||
number_passes = png_set_interlace_handling(png_ptr);
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
if (width == png_get_rowbytes(png_ptr, info_ptr))
|
||||
{
|
||||
ret_value = true;
|
||||
|
||||
for (pass = 0; pass < number_passes; pass++)
|
||||
{
|
||||
fbptr = (png_byte *)element->buffer;
|
||||
for (i = 0; i < element->header.height; i++)
|
||||
{
|
||||
//fbptr = row_pointers[i];
|
||||
//png_read_rows(png_ptr, &fbptr, NULL, 1);
|
||||
|
||||
png_read_row(png_ptr, fbptr, NULL);
|
||||
/* if the PNG is smaller, than the display width... */
|
||||
if (width < lcd_width) /* clear the area right of the PNG */
|
||||
memset(fbptr + width, 0, lcd_width - width);
|
||||
fbptr += lcd_width;
|
||||
}
|
||||
}
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
|
||||
}
|
||||
}
|
||||
fclose(fh);
|
||||
}
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
bool CLCDDisplay::load_png(const char *const filename)
|
||||
{
|
||||
raw_lcd_element_t element;
|
||||
element.buffer_size = raw_buffer_size;
|
||||
element.buffer = _buffer;
|
||||
return load_png_element(filename, &element);
|
||||
}
|
||||
|
||||
bool CLCDDisplay::dump_png_element(const char *const filename, raw_lcd_element_t *element)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
unsigned int i;
|
||||
png_byte *fbptr;
|
||||
FILE *fp;
|
||||
bool ret_value = false;
|
||||
|
||||
/* create file */
|
||||
fp = fopen(filename, "wb");
|
||||
if (!fp)
|
||||
printf("[CLCDDisplay] File %s could not be opened for writing\n", filename);
|
||||
else
|
||||
{
|
||||
/* initialize stuff */
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
if (!png_ptr)
|
||||
printf("[CLCDDisplay] png_create_write_struct failed\n");
|
||||
else
|
||||
{
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
printf("[CLCDDisplay] png_create_info_struct failed\n");
|
||||
else
|
||||
{
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
printf("[CLCDDisplay] Error during init_io\n");
|
||||
else
|
||||
{
|
||||
unsigned int lcd_height = yres;
|
||||
unsigned int lcd_width = xres;
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
|
||||
/* write header */
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
printf("[CLCDDisplay] Error during writing header\n");
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, element->header.width, element->header.height,
|
||||
element->header.bpp, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
|
||||
/* write bytes */
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
printf("[CLCDDisplay] Error during writing bytes\n");
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
ret_value = true;
|
||||
|
||||
fbptr = (png_byte *)element->buffer;
|
||||
for (i = 0; i < element->header.height; i++)
|
||||
{
|
||||
png_write_row(png_ptr, fbptr);
|
||||
fbptr += lcd_width;
|
||||
}
|
||||
|
||||
/* end write */
|
||||
if (setjmp(png_jmpbuf(png_ptr)))
|
||||
{
|
||||
printf("[CLCDDisplay] Error during end of write\n");
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
png_write_end(png_ptr, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
bool CLCDDisplay::dump_png(const char *const filename)
|
||||
{
|
||||
raw_lcd_element_t element;
|
||||
element.buffer_size = raw_buffer_size;
|
||||
element.buffer = _buffer;
|
||||
element.header.width = xres;
|
||||
element.header.height = yres;
|
||||
element.header.bpp = 8;
|
||||
return dump_png_element(filename, &element);
|
||||
}
|
148
lib/liblcddisplay/lcddisplay.h
Normal file
148
lib/liblcddisplay/lcddisplay.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
LCD-Daemon - DBoxII-Project
|
||||
|
||||
Copyright (C) 2001 Steffen Hehn 'McClean'
|
||||
baseroutines by Shadow_
|
||||
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 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.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __lcddisplay__
|
||||
#define __lcddisplay__
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h> /* uint8_t */
|
||||
|
||||
#define LCD_DEVICE "/dev/dbox/lcd0"
|
||||
|
||||
#define LCD_PIXEL_OFF 0x00
|
||||
#define LCD_PIXEL_ON 0xff
|
||||
#define LCD_PIXEL_INV 0x1000000
|
||||
|
||||
// ioctls
|
||||
|
||||
#define LCD_IOCTL_CLEAR (26)
|
||||
|
||||
#define FP_IOCTL_LCD_DIMM 3
|
||||
|
||||
#ifndef LCD_IOCTL_ASC_MODE
|
||||
#define LCDSET 0x1000
|
||||
#define LCD_IOCTL_ASC_MODE (21|LCDSET)
|
||||
#define LCD_MODE_ASC 0
|
||||
#define LCD_MODE_BIN 1
|
||||
#endif
|
||||
|
||||
#ifndef LCD_IOCTL_SRV
|
||||
#define LCDSET 0x1000
|
||||
#define LCD_IOCTL_SRV (10|LCDSET)
|
||||
#endif
|
||||
|
||||
typedef unsigned char *raw_display_t;
|
||||
|
||||
struct raw_lcd_element_header_t
|
||||
{
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint8_t bpp;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct raw_lcd_element_t
|
||||
{
|
||||
raw_lcd_element_header_t header;
|
||||
int buffer_size;
|
||||
raw_display_t buffer;
|
||||
};
|
||||
|
||||
class CLCDDisplay
|
||||
{
|
||||
private:
|
||||
int fd, paused;
|
||||
std::string iconBasePath;
|
||||
bool available;
|
||||
|
||||
unsigned char inverted;
|
||||
bool flipped;
|
||||
int is_oled; //1=oled, 2=lcd, 3=???
|
||||
int last_brightness;
|
||||
|
||||
raw_display_t _buffer;
|
||||
int _stride;
|
||||
raw_display_t surface_data;
|
||||
int surface_stride;
|
||||
int surface_bpp, surface_bypp;
|
||||
int surface_buffer_size;
|
||||
int real_offset;
|
||||
int real_yres;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
PIXEL_ON = LCD_PIXEL_ON,
|
||||
PIXEL_OFF = LCD_PIXEL_OFF,
|
||||
PIXEL_INV = LCD_PIXEL_INV
|
||||
};
|
||||
|
||||
CLCDDisplay();
|
||||
~CLCDDisplay();
|
||||
|
||||
void pause();
|
||||
void resume();
|
||||
|
||||
void convert_data();
|
||||
void setIconBasePath(std::string bp)
|
||||
{
|
||||
iconBasePath = bp;
|
||||
};
|
||||
bool isAvailable();
|
||||
|
||||
void update();
|
||||
|
||||
void surface_fill_rect(int area_left, int area_top, int area_right, int area_bottom, int color);
|
||||
void draw_point(const int x, const int y, const int state);
|
||||
void draw_line(const int x1, const int y1, const int x2, const int y2, const int state);
|
||||
void draw_fill_rect(int left, int top, int right, int bottom, int state);
|
||||
void draw_rectangle(int left, int top, int right, int bottom, int linestate, int fillstate);
|
||||
void draw_polygon(int num_vertices, int *vertices, int state);
|
||||
|
||||
bool paintIcon(std::string filename, int x, int y, bool invert);
|
||||
void clear_screen();
|
||||
void dump_screen(raw_display_t *screen);
|
||||
void load_screen_element(const raw_lcd_element_t *element, int left, int top);
|
||||
void load_screen(const raw_display_t *const screen);
|
||||
bool dump_png_element(const char *const filename, raw_lcd_element_t *element);
|
||||
bool dump_png(const char *const filename);
|
||||
bool load_png_element(const char *const filename, raw_lcd_element_t *element);
|
||||
bool load_png(const char *const filename);
|
||||
|
||||
void setSize(int w, int h, int b);
|
||||
int setLCDContrast(int contrast);
|
||||
int setLCDBrightness(int brightness);
|
||||
void setInverted(unsigned char);
|
||||
void setFlipped(bool);
|
||||
bool isOled() const
|
||||
{
|
||||
return !!is_oled;
|
||||
}
|
||||
int raw_buffer_size;
|
||||
int xres, yres, bpp;
|
||||
int bypp;
|
||||
};
|
||||
|
||||
#endif
|
@@ -127,6 +127,11 @@ neutrino_LDADD = \
|
||||
-lrt -lpthread \
|
||||
-lz
|
||||
|
||||
# LCD display
|
||||
if ENABLE_LCD
|
||||
neutrino_LDADD += $(top_builddir)/lib/liblcddisplay/liblcddisplay.a
|
||||
endif
|
||||
|
||||
if ENABLE_GRAPHLCD
|
||||
neutrino_LDADD += \
|
||||
driver/glcd/libneutrino_driver_glcd.a \
|
||||
|
@@ -51,6 +51,10 @@ libneutrino_driver_a_SOURCES = \
|
||||
streamts.cpp \
|
||||
volume.cpp
|
||||
|
||||
if ENABLE_LCD
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/lib/liblcddisplay
|
||||
endif
|
||||
|
||||
if ENABLE_LCD4LINUX
|
||||
libneutrino_driver_a_SOURCES += \
|
||||
lcd4l.cpp
|
||||
@@ -76,11 +80,18 @@ libneutrino_driver_a_SOURCES += \
|
||||
simple_display.cpp
|
||||
endif
|
||||
if BOXTYPE_ARMBOX
|
||||
if ENABLE_LCD
|
||||
libneutrino_driver_a_SOURCES += \
|
||||
fb_accel_arm.cpp \
|
||||
lcdd.cpp
|
||||
else
|
||||
libneutrino_driver_a_SOURCES += \
|
||||
fb_accel.cpp \
|
||||
fb_accel_arm.cpp \
|
||||
simple_display.cpp
|
||||
endif
|
||||
endif
|
||||
|
||||
if BOXTYPE_MIPSBOX
|
||||
libneutrino_driver_a_SOURCES += \
|
||||
fb_accel_mips.cpp \
|
||||
|
@@ -3,8 +3,13 @@
|
||||
#include <driver/vfd.h>
|
||||
#endif
|
||||
#if HAVE_GENERIC_HARDWARE || HAVE_ARM_HARDWARE || HAVE_MIPS_HARDWARE
|
||||
#if BOXMODEL_OSMIO4KPLUS
|
||||
#include <driver/lcdd.h>
|
||||
#define CVFD CLCD
|
||||
#else
|
||||
#include <driver/simple_display.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef ENABLE_GRAPHLCD
|
||||
#include <driver/glcd/glcd.h>
|
||||
#endif
|
||||
|
961
src/driver/lcdd.cpp
Normal file
961
src/driver/lcdd.cpp
Normal file
@@ -0,0 +1,961 @@
|
||||
/*
|
||||
$Id: lcdd.cpp 2013/10/12 mohousch Exp $
|
||||
|
||||
LCD-Daemon - DBoxII-Project
|
||||
|
||||
Copyright (C) 2001 Steffen Hehn 'McClean'
|
||||
Homepage: http://dbox.cyberphoria.org/
|
||||
|
||||
Copyright (C) 2008 Novell, Inc. Author: Stefan Seyfried
|
||||
(C) 2009 Stefan Seyfried
|
||||
(C) 2022 TangoCash
|
||||
|
||||
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 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.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <driver/lcdd.h>
|
||||
|
||||
#include <global.h>
|
||||
#include <neutrino.h>
|
||||
#include <system/settings.h>
|
||||
#include <system/debug.h>
|
||||
#include <system/helpers.h>
|
||||
#include <system/proc_tools.h>
|
||||
|
||||
#include <liblcddisplay/lcddisplay.h>
|
||||
#include <gui/widget/icons.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <zapit/zapit.h>
|
||||
#include <eitd/sectionsd.h>
|
||||
|
||||
#include <daemonc/remotecontrol.h>
|
||||
|
||||
extern CRemoteControl *g_RemoteControl; /* neutrino.cpp */
|
||||
|
||||
/* from edvbstring.cpp */
|
||||
static bool is_UTF8(const std::string &string)
|
||||
{
|
||||
unsigned int len = string.size();
|
||||
|
||||
for (unsigned int i = 0; i < len; ++i)
|
||||
{
|
||||
if (!(string[i] & 0x80)) // normal ASCII
|
||||
continue;
|
||||
|
||||
if ((string[i] & 0xE0) == 0xC0) // one char following.
|
||||
{
|
||||
// first, length check:
|
||||
if (i + 1 >= len)
|
||||
return false; // certainly NOT utf-8
|
||||
|
||||
i++;
|
||||
|
||||
if ((string[i] & 0xC0) != 0x80)
|
||||
return false; // no, not UTF-8.
|
||||
}
|
||||
else if ((string[i] & 0xF0) == 0xE0)
|
||||
{
|
||||
if ((i + 1) >= len)
|
||||
return false;
|
||||
|
||||
i++;
|
||||
|
||||
if ((string[i] & 0xC0) != 0x80)
|
||||
return false;
|
||||
|
||||
i++;
|
||||
|
||||
if ((string[i] & 0xC0) != 0x80)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true; // can be UTF8 (or pure ASCII, at least no non-UTF-8 8bit characters)
|
||||
}
|
||||
|
||||
CLCD::CLCD()
|
||||
: configfile('\t')
|
||||
{
|
||||
muted = false;
|
||||
percentOver = 0;
|
||||
volume = 0;
|
||||
timeout_cnt = 0;
|
||||
icon_dolby = false;
|
||||
has_lcd = true;
|
||||
is4digits = false;
|
||||
clearClock = 0;
|
||||
fheight_s = 8;
|
||||
fheight_t = 12;
|
||||
fheight_r = 16;
|
||||
fheight_b = 10;
|
||||
lcd_width = g_info.hw_caps->display_xres;
|
||||
lcd_height = g_info.hw_caps->display_yres;
|
||||
}
|
||||
|
||||
CLCD::~CLCD()
|
||||
{
|
||||
}
|
||||
|
||||
CLCD *CLCD::getInstance()
|
||||
{
|
||||
static CLCD *lcdd = NULL;
|
||||
|
||||
if (lcdd == NULL)
|
||||
{
|
||||
lcdd = new CLCD();
|
||||
}
|
||||
|
||||
return lcdd;
|
||||
}
|
||||
|
||||
void CLCD::count_down()
|
||||
{
|
||||
if (timeout_cnt > 0)
|
||||
{
|
||||
timeout_cnt--;
|
||||
|
||||
if (timeout_cnt == 0)
|
||||
{
|
||||
setlcdparameter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLCD::wake_up()
|
||||
{
|
||||
if (atoi(g_settings.lcd_setting_dim_time.c_str()) > 0)
|
||||
{
|
||||
timeout_cnt = atoi(g_settings.lcd_setting_dim_time.c_str());
|
||||
setlcdparameter();
|
||||
}
|
||||
}
|
||||
|
||||
void *CLCD::TimeThread(void *)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
sleep(1);
|
||||
struct stat buf;
|
||||
|
||||
if (stat("/tmp/lcd.locked", &buf) == -1)
|
||||
{
|
||||
CLCD::getInstance()->showTime();
|
||||
CLCD::getInstance()->count_down();
|
||||
}
|
||||
else
|
||||
CLCD::getInstance()->wake_up();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CLCD::init(const char *fontfile, const char *fontname, const char *fontfile2, const char *fontname2, const char *fontfile3, const char *fontname3)
|
||||
{
|
||||
if (!lcdInit(fontfile, fontname, fontfile2, fontname2, fontfile3, fontname3))
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "CLCD::init: LCD-Init failed!\n");
|
||||
has_lcd = false;
|
||||
}
|
||||
|
||||
if (pthread_create(&thrTime, NULL, TimeThread, NULL) != 0)
|
||||
{
|
||||
perror("CLCD::init: pthread_create(TimeThread)");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
bool CLCD::lcdInit(const char *fontfile, const char *fontname, const char *fontfile2, const char *fontname2, const char *fontfile3, const char *fontname3)
|
||||
{
|
||||
fontRenderer = new LcdFontRenderClass(&display);
|
||||
const char *style_name = fontRenderer->AddFont(fontfile);
|
||||
const char *style_name2;
|
||||
const char *style_name3;
|
||||
const char *style_name4;
|
||||
|
||||
if (fontfile2 != NULL)
|
||||
style_name2 = fontRenderer->AddFont(fontfile2);
|
||||
else
|
||||
{
|
||||
style_name2 = style_name;
|
||||
fontname2 = fontname;
|
||||
}
|
||||
|
||||
if (fontfile3 != NULL)
|
||||
style_name3 = fontRenderer->AddFont(fontfile3);
|
||||
else
|
||||
{
|
||||
style_name3 = style_name;
|
||||
fontname3 = fontname;
|
||||
}
|
||||
|
||||
style_name4 = style_name;
|
||||
fontRenderer->InitFontCache();
|
||||
fonts.time = fontRenderer->getFont(fontname, style_name, fheight_t);
|
||||
time_size = fonts.time->getRenderWidth("88:88") + 4;
|
||||
fonts.small = fontRenderer->getFont(fontname2, style_name2, fheight_s);
|
||||
fonts.regular = fontRenderer->getFont(fontname3, style_name3, fheight_r);
|
||||
fonts.big = fontRenderer->getFont(fontname, style_name4, fheight_b);
|
||||
setAutoDimm(g_settings.lcd_setting[SNeutrinoSettings::LCD_AUTODIMM]);
|
||||
|
||||
if (!display.isAvailable())
|
||||
{
|
||||
dprintf(DEBUG_NORMAL, "CLCD::lcdInit: exit...(no lcd-support)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
setMode(MODE_TVRADIO);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CLCD::displayUpdate()
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if (stat("/tmp/lcd.locked", &buf) == -1)
|
||||
{
|
||||
display.update();
|
||||
}
|
||||
}
|
||||
|
||||
void CLCD::setlcdparameter(int dimm, const int contrast, const int power, const int inverse, const int bias)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
if (!display.isAvailable())
|
||||
return;
|
||||
|
||||
int fd;
|
||||
|
||||
if (power == 0)
|
||||
dimm = 0;
|
||||
|
||||
// dimm
|
||||
display.setLCDBrightness(dimm);
|
||||
// contrast
|
||||
display.setLCDContrast(contrast);
|
||||
|
||||
// power ???
|
||||
|
||||
//reverse
|
||||
if (inverse)
|
||||
display.setInverted(CLCDDisplay::PIXEL_ON);
|
||||
else
|
||||
display.setInverted(CLCDDisplay::PIXEL_OFF);
|
||||
}
|
||||
|
||||
void CLCD::setlcdparameter(void)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
last_toggle_state_power = g_settings.lcd_setting[SNeutrinoSettings::LCD_POWER];
|
||||
int dim_time = atoi(g_settings.lcd_setting_dim_time);
|
||||
int dim_brightness = g_settings.lcd_setting_dim_brightness;
|
||||
bool timeouted = (dim_time > 0) && (timeout_cnt == 0);
|
||||
int brightness, power = 0;
|
||||
|
||||
if (timeouted)
|
||||
brightness = dim_brightness;
|
||||
else
|
||||
brightness = g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS];
|
||||
|
||||
if (last_toggle_state_power && (!timeouted || dim_brightness > 0))
|
||||
power = 1;
|
||||
|
||||
if (mode == MODE_STANDBY)
|
||||
brightness = g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS];
|
||||
|
||||
setlcdparameter(brightness,
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_CONTRAST],
|
||||
power,
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_INVERSE],
|
||||
0 /*g_settings.lcd_setting[SNeutrinoSettings::LCD_BIAS]*/);
|
||||
}
|
||||
|
||||
static std::string removeLeadingSpaces(const std::string &text)
|
||||
{
|
||||
int pos = text.find_first_not_of(" ");
|
||||
|
||||
if (pos != -1)
|
||||
return text.substr(pos);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static std::string splitString(const std::string &text, const int maxwidth, LcdFont *font, bool dumb, bool utf8)
|
||||
{
|
||||
int pos;
|
||||
std::string tmp = removeLeadingSpaces(text);
|
||||
|
||||
if (font->getRenderWidth(tmp.c_str(), utf8) > maxwidth)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (dumb)
|
||||
tmp = tmp.substr(0, tmp.length() - 1);
|
||||
else
|
||||
{
|
||||
pos = tmp.find_last_of("[ .-]+"); // TODO characters might be UTF-encoded!
|
||||
|
||||
if (pos != -1)
|
||||
tmp = tmp.substr(0, pos);
|
||||
else // does not fit -> fall back to dumb split
|
||||
tmp = tmp.substr(0, tmp.length() - 1);
|
||||
}
|
||||
}
|
||||
while (font->getRenderWidth(tmp.c_str(), utf8) > maxwidth);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int getProgress()
|
||||
{
|
||||
int Progress = CLCD::getInstance()->percentOver;
|
||||
t_channel_id channel_id = 0;
|
||||
uint64_t ID = CNeutrinoApp::getInstance()->getMode();
|
||||
|
||||
if (ID == NeutrinoModes::mode_tv || ID == NeutrinoModes::mode_webtv || ID == NeutrinoModes::mode_radio || ID == NeutrinoModes::mode_webradio)
|
||||
{
|
||||
CZapitChannel *channel = CZapit::getInstance()->GetCurrentChannel();
|
||||
|
||||
if (channel)
|
||||
channel_id = channel->getEpgID();
|
||||
|
||||
CSectionsdClient::CurrentNextInfo CurrentNext;
|
||||
CEitManager::getInstance()->getCurrentNextServiceKey(channel_id, CurrentNext);
|
||||
|
||||
if (CurrentNext.flags & CSectionsdClient::epgflags::has_current)
|
||||
{
|
||||
time_t cur_duration = CurrentNext.current_zeit.dauer;
|
||||
time_t cur_start_time = CurrentNext.current_zeit.startzeit;
|
||||
|
||||
if ((cur_duration > 0) && (cur_duration < 86400))
|
||||
{
|
||||
Progress = 100 * (time(NULL) - cur_start_time) / cur_duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Progress;
|
||||
}
|
||||
|
||||
void CLCD::showTextScreen(const std::string &big, const std::string &small, const bool perform_wakeup, const bool centered)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
bool big_utf8 = false;
|
||||
bool small_utf8 = false;
|
||||
std::string cname[2];
|
||||
std::string event[2];
|
||||
int namelines = 0, maxnamelines = 1;
|
||||
|
||||
if (!big.empty())
|
||||
{
|
||||
bool dumb = false;
|
||||
big_utf8 = is_UTF8(big);
|
||||
|
||||
while (true)
|
||||
{
|
||||
namelines = 0;
|
||||
std::string title = big;
|
||||
|
||||
do // first try "intelligent" splitting
|
||||
{
|
||||
cname[namelines] = splitString(title, lcd_width, (small.empty()) ? fonts.regular : fonts.big, dumb, big_utf8);
|
||||
title = removeLeadingSpaces(title.substr(cname[namelines].length()));
|
||||
namelines++;
|
||||
}
|
||||
while (title.length() > 0 && namelines < maxnamelines);
|
||||
|
||||
if (title.length() == 0)
|
||||
break;
|
||||
|
||||
dumb = !dumb; // retry with dumb splitting;
|
||||
|
||||
if (!dumb) // second retry -> get out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!small.empty())
|
||||
{
|
||||
bool dumb = false;
|
||||
small_utf8 = is_UTF8(small);
|
||||
|
||||
while (true)
|
||||
{
|
||||
namelines = 0;
|
||||
std::string title = small;
|
||||
|
||||
do // first try "intelligent" splitting
|
||||
{
|
||||
event[namelines] = splitString(title, lcd_width, fonts.small, dumb, small_utf8);
|
||||
title = removeLeadingSpaces(title.substr(event[namelines].length()));
|
||||
namelines++;
|
||||
}
|
||||
while (title.length() > 0 && namelines < maxnamelines);
|
||||
|
||||
if (title.length() == 0)
|
||||
break;
|
||||
|
||||
dumb = !dumb; // retry with dumb splitting;
|
||||
|
||||
if (!dumb) // second retry -> get out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
int t_h = lcd_height - (fheight_t + 2);
|
||||
|
||||
if (!showclock)
|
||||
t_h = lcd_height;
|
||||
|
||||
display.draw_fill_rect(-1, 0, lcd_width, t_h, CLCDDisplay::PIXEL_OFF);
|
||||
//
|
||||
int xb = 1;
|
||||
int xs = 1;
|
||||
int yb = (t_h - fheight_r) / 2 + fheight_r - 2;
|
||||
int ys = 0;
|
||||
|
||||
if (!small.empty())
|
||||
{
|
||||
yb = 1 + fheight_b - 3;
|
||||
ys = yb + fheight_s + 1;
|
||||
}
|
||||
|
||||
int wb = (small.empty()) ? fonts.regular->getRenderWidth(cname[0].c_str(), big_utf8) : fonts.big->getRenderWidth(cname[0].c_str(), big_utf8);
|
||||
int ws = fonts.time->getRenderWidth(event[0].c_str(), small_utf8);
|
||||
|
||||
if (centered)
|
||||
{
|
||||
xb = (lcd_width - wb) / 2;
|
||||
xs = (lcd_width - ws) / 2;
|
||||
}
|
||||
|
||||
if (!small.empty())
|
||||
{
|
||||
fonts.big->RenderString(xb, yb, lcd_width, cname[0].c_str(), CLCDDisplay::PIXEL_ON, 0, big_utf8);
|
||||
fonts.small->RenderString(xs, ys, lcd_width, event[0].c_str(), CLCDDisplay::PIXEL_ON, 0, small_utf8);
|
||||
}
|
||||
else
|
||||
fonts.regular->RenderString(xb, yb, lcd_width, cname[0].c_str(), CLCDDisplay::PIXEL_ON, 0, big_utf8);
|
||||
|
||||
if (perform_wakeup)
|
||||
wake_up();
|
||||
|
||||
displayUpdate();
|
||||
}
|
||||
|
||||
void CLCD::showServicename(const std::string name, const bool perform_wakeup)
|
||||
{
|
||||
printf("CLCD::showServicename '%s' epg: '%s'\n", name.c_str(), epg_title.c_str());
|
||||
|
||||
if (!name.empty())
|
||||
servicename = name;
|
||||
|
||||
if (mode != MODE_TVRADIO)
|
||||
return;
|
||||
|
||||
showTextScreen(servicename, epg_title, perform_wakeup, true);
|
||||
return;
|
||||
}
|
||||
|
||||
void CLCD::setEPGTitle(const std::string title)
|
||||
{
|
||||
if (title == epg_title)
|
||||
{
|
||||
//fprintf(stderr,"CLCD::setEPGTitle: not changed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
epg_title = title;
|
||||
showServicename("", false);
|
||||
}
|
||||
|
||||
void CLCD::setMovieInfo(const AUDIOMODES playmode, const std::string big, const std::string small, const bool centered)
|
||||
{
|
||||
movie_playmode = playmode;
|
||||
movie_big = big;
|
||||
movie_small = small;
|
||||
movie_centered = centered;
|
||||
|
||||
if (mode != MODE_MOVIE)
|
||||
return;
|
||||
|
||||
//showAudioPlayMode(movie_playmode);
|
||||
showTextScreen(movie_big, "", true, movie_centered);
|
||||
}
|
||||
|
||||
void CLCD::setMovieAudio(const bool is_ac3)
|
||||
{
|
||||
movie_is_ac3 = is_ac3;
|
||||
|
||||
if (mode != MODE_MOVIE)
|
||||
return;
|
||||
|
||||
showPercentOver(percentOver, true, MODE_MOVIE);
|
||||
}
|
||||
|
||||
void CLCD::showTime()
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
if (showclock)
|
||||
{
|
||||
char timestr[21];
|
||||
struct timeval tm;
|
||||
struct tm *t;
|
||||
invert = !invert;
|
||||
gettimeofday(&tm, NULL);
|
||||
t = localtime(&tm.tv_sec);
|
||||
|
||||
if (mode == MODE_STANDBY)
|
||||
{
|
||||
display.clear_screen(); // clear lcd
|
||||
//ShowNewClock(&display, t->tm_hour, t->tm_min, t->tm_sec, t->tm_wday, t->tm_mday, t->tm_mon, CNeutrinoApp::getInstance()->recordingstatus);
|
||||
|
||||
if (!invert)
|
||||
strftime((char *) ×tr, 20, "%H:%M:%S\n%d.%m.%y", t);
|
||||
else
|
||||
strftime((char *) ×tr, 20, "%H.%M:%S\n%d.%m.%y", t);
|
||||
|
||||
display.draw_fill_rect(0, 0, lcd_width, lcd_height, CLCDDisplay::PIXEL_OFF);
|
||||
fonts.time->RenderString(lcd_width / 4, lcd_height / 2, lcd_width, timestr, CLCDDisplay::PIXEL_ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CNeutrinoApp::getInstance()->recordingstatus && clearClock == 1)
|
||||
{
|
||||
if (!invert)
|
||||
strftime((char *) ×tr, 20, "%H:%M", t);
|
||||
else
|
||||
strftime((char *) ×tr, 20, "%H.%M", t);
|
||||
|
||||
clearClock = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!invert)
|
||||
strftime((char *) ×tr, 20, "%H:%M", t);
|
||||
else
|
||||
strftime((char *) ×tr, 20, "%H.%M", t);
|
||||
|
||||
clearClock = 1;
|
||||
}
|
||||
|
||||
display.draw_fill_rect(lcd_width - time_size - 1, lcd_height - 12, lcd_width, lcd_height, clearClock ? CLCDDisplay::PIXEL_OFF : CLCDDisplay::PIXEL_ON);
|
||||
fonts.time->RenderString(lcd_width - 4 - fonts.time->getRenderWidth(timestr), lcd_height - 2, time_size, timestr, clearClock ? CLCDDisplay::PIXEL_ON : CLCDDisplay::PIXEL_OFF);
|
||||
showPercentOver(getProgress(), true);
|
||||
}
|
||||
|
||||
displayUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void CLCD::showRCLock(int duration)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
}
|
||||
|
||||
void CLCD::showVolume(const char vol, const bool perform_update)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
volume = vol;
|
||||
showTextScreen(servicename, "Volume", true, true);
|
||||
showPercentOver(vol, true);
|
||||
//showTextScreen(servicename, "", true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
void CLCD::showPercentOver(const unsigned char perc, const bool perform_update, const MODES m)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
int left, top, width, height = 6;
|
||||
percentOver = perc;
|
||||
|
||||
if (!showclock)
|
||||
return;
|
||||
|
||||
left = 2;
|
||||
top = lcd_height - height - 1 - 2;
|
||||
width = lcd_width - left - 4 - time_size;
|
||||
display.draw_rectangle(left - 2, top - 2, left + width + 2, top + height + 1, CLCDDisplay::PIXEL_ON, CLCDDisplay::PIXEL_OFF);
|
||||
|
||||
if (perc == (unsigned char) -1)
|
||||
{
|
||||
display.draw_line(left, top, left + width, top + height - 1, CLCDDisplay::PIXEL_ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
int dp;
|
||||
|
||||
if (perc == (unsigned char) -2)
|
||||
dp = width + 1;
|
||||
else
|
||||
dp = perc * (width + 1) / 100;
|
||||
|
||||
display.draw_fill_rect(left - 1, top - 1, left + dp, top + height, CLCDDisplay::PIXEL_ON);
|
||||
|
||||
if (perc == (unsigned char) -2)
|
||||
{
|
||||
// draw a "+" to show that the event is overdue
|
||||
display.draw_line(left + width - 2, top + 1, left + width - 2, top + height - 2, CLCDDisplay::PIXEL_OFF);
|
||||
display.draw_line(left + width - 1, top + (height / 2), left + width - 3, top + (height / 2), CLCDDisplay::PIXEL_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (perform_update)
|
||||
displayUpdate();
|
||||
}
|
||||
|
||||
void CLCD::showMenuText(const int position, const char *text, const int highlight, const bool utf_encoded)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
showTextScreen(text, "", true, true);
|
||||
}
|
||||
|
||||
void CLCD::showAudioTrack(const std::string &artist, const std::string &title, const std::string &album)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
}
|
||||
|
||||
void CLCD::showAudioPlayMode(AUDIOMODES m)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
display.draw_fill_rect(-1, 51, 10, 62, CLCDDisplay::PIXEL_OFF);
|
||||
|
||||
switch (m)
|
||||
{
|
||||
case AUDIO_MODE_PLAY:
|
||||
{
|
||||
int x = 3, y = 53;
|
||||
display.draw_line(x, y, x, y + 8, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 1, y + 1, x + 1, y + 7, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 2, y + 2, x + 2, y + 6, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 3, y + 3, x + 3, y + 5, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 4, y + 4, x + 4, y + 4, CLCDDisplay::PIXEL_ON);
|
||||
break;
|
||||
}
|
||||
|
||||
case AUDIO_MODE_STOP:
|
||||
display.draw_fill_rect(1, 53, 8, 61, CLCDDisplay::PIXEL_ON);
|
||||
break;
|
||||
|
||||
case AUDIO_MODE_PAUSE:
|
||||
display.draw_line(1, 54, 1, 60, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(2, 54, 2, 60, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(6, 54, 6, 60, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(7, 54, 7, 60, CLCDDisplay::PIXEL_ON);
|
||||
break;
|
||||
|
||||
case AUDIO_MODE_FF:
|
||||
{
|
||||
int x = 2, y = 55;
|
||||
display.draw_line(x, y, x, y + 4, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 1, y + 1, x + 1, y + 3, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 2, y + 2, x + 2, y + 2, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 3, y, x + 3, y + 4, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 4, y + 1, x + 4, y + 3, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 5, y + 2, x + 5, y + 2, CLCDDisplay::PIXEL_ON);
|
||||
}
|
||||
break;
|
||||
|
||||
case AUDIO_MODE_REV:
|
||||
{
|
||||
int x = 2, y = 55;
|
||||
display.draw_line(x, y + 2, x, y + 2, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 1, y + 1, x + 1, y + 3, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 2, y, x + 2, y + 4, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 3, y + 2, x + 3, y + 2, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 4, y + 1, x + 4, y + 3, CLCDDisplay::PIXEL_ON);
|
||||
display.draw_line(x + 5, y, x + 5, y + 4, CLCDDisplay::PIXEL_ON);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
wake_up();
|
||||
displayUpdate();
|
||||
}
|
||||
|
||||
void CLCD::showAudioProgress(const char perc, bool isMuted)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
if (mode == MODE_AUDIO)
|
||||
{
|
||||
display.draw_fill_rect(11, 53, 73, 61, CLCDDisplay::PIXEL_OFF);
|
||||
int dp = int(perc / 100.0 * 61.0 + 12.0);
|
||||
display.draw_fill_rect(11, 54, dp, 60, CLCDDisplay::PIXEL_ON);
|
||||
|
||||
if (isMuted)
|
||||
{
|
||||
if (dp > 12)
|
||||
{
|
||||
display.draw_line(12, 56, dp - 1, 56, CLCDDisplay::PIXEL_OFF);
|
||||
display.draw_line(12, 58, dp - 1, 58, CLCDDisplay::PIXEL_OFF);
|
||||
}
|
||||
else
|
||||
display.draw_line(12, 55, 72, 59, CLCDDisplay::PIXEL_ON);
|
||||
}
|
||||
|
||||
displayUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void CLCD::setMode(const MODES m, const char *const title)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
mode = m;
|
||||
menutitle = title;
|
||||
setlcdparameter();
|
||||
|
||||
switch (m)
|
||||
{
|
||||
case MODE_TVRADIO:
|
||||
case MODE_WEBTV:
|
||||
display.clear_screen(); // clear lcd
|
||||
showclock = true;
|
||||
showServicename(servicename);
|
||||
showTime(); /* "showclock = true;" implies that "showTime();" does a "displayUpdate();" */
|
||||
break;
|
||||
|
||||
case MODE_MOVIE:
|
||||
display.clear_screen(); // clear lcd
|
||||
showclock = false;
|
||||
setMovieInfo(movie_playmode, movie_big, movie_small, movie_centered);
|
||||
break;
|
||||
|
||||
case MODE_AUDIO:
|
||||
{
|
||||
display.clear_screen(); // clear lcd
|
||||
showAudioPlayMode(AUDIO_MODE_STOP);
|
||||
showVolume(volume, false);
|
||||
showclock = true;
|
||||
showTime(); /* "showclock = true;" implies that "showTime();" does a "displayUpdate();" */
|
||||
break;
|
||||
}
|
||||
|
||||
case MODE_AVINPUT:
|
||||
display.clear_screen(); // clear lcd
|
||||
showVolume(volume, false);
|
||||
showclock = true;
|
||||
showTime(); /* "showclock = true;" implies that "showTime();" does a "displayUpdate();" */
|
||||
break;
|
||||
|
||||
case MODE_MENU_UTF8:
|
||||
showclock = false;
|
||||
display.clear_screen(); // clear lcd
|
||||
displayUpdate();
|
||||
break;
|
||||
|
||||
case MODE_SHUTDOWN:
|
||||
showclock = false;
|
||||
display.clear_screen(); // clear lcd
|
||||
displayUpdate();
|
||||
break;
|
||||
|
||||
case MODE_STANDBY:
|
||||
showclock = true;
|
||||
showTime(); /* "showclock = true;" implies that "showTime();" does a "displayUpdate();" */
|
||||
/* "showTime()" clears the whole lcd in MODE_STANDBY */
|
||||
break;
|
||||
}
|
||||
|
||||
wake_up();
|
||||
}
|
||||
|
||||
|
||||
void CLCD::setBrightness(int bright)
|
||||
{
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS] = bright;
|
||||
setlcdparameter();
|
||||
}
|
||||
|
||||
int CLCD::getBrightness()
|
||||
{
|
||||
return g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS];
|
||||
}
|
||||
|
||||
void CLCD::setBrightnessStandby(int bright)
|
||||
{
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] = bright;
|
||||
setlcdparameter();
|
||||
}
|
||||
|
||||
int CLCD::getBrightnessStandby()
|
||||
{
|
||||
return g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS];
|
||||
}
|
||||
|
||||
void CLCD::setContrast(int contrast)
|
||||
{
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_CONTRAST] = contrast;
|
||||
setlcdparameter();
|
||||
}
|
||||
|
||||
int CLCD::getContrast()
|
||||
{
|
||||
return g_settings.lcd_setting[SNeutrinoSettings::LCD_CONTRAST];
|
||||
}
|
||||
|
||||
void CLCD::setScrollMode(int scroll_repeats)
|
||||
{
|
||||
printf("CLCD::%s scroll_repeats:%d\n", __func__, scroll_repeats);
|
||||
}
|
||||
|
||||
void CLCD::setPower(int power)
|
||||
{
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_POWER] = power;
|
||||
setlcdparameter();
|
||||
}
|
||||
|
||||
int CLCD::getPower()
|
||||
{
|
||||
return g_settings.lcd_setting[SNeutrinoSettings::LCD_POWER];
|
||||
}
|
||||
|
||||
void CLCD::togglePower(void)
|
||||
{
|
||||
last_toggle_state_power = 1 - last_toggle_state_power;
|
||||
setlcdparameter((mode == MODE_STANDBY) ? g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] : g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS],
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_CONTRAST],
|
||||
last_toggle_state_power,
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_INVERSE],
|
||||
0 /*g_settings.lcd_setting[SNeutrinoSettings::LCD_BIAS]*/);
|
||||
}
|
||||
|
||||
void CLCD::setInverse(int inverse)
|
||||
{
|
||||
g_settings.lcd_setting[SNeutrinoSettings::LCD_INVERSE] = inverse;
|
||||
setlcdparameter();
|
||||
}
|
||||
|
||||
int CLCD::getInverse()
|
||||
{
|
||||
return g_settings.lcd_setting[SNeutrinoSettings::LCD_INVERSE];
|
||||
}
|
||||
|
||||
void CLCD::setAutoDimm(int /*autodimm*/)
|
||||
{
|
||||
}
|
||||
|
||||
int CLCD::getAutoDimm()
|
||||
{
|
||||
return g_settings.lcd_setting[SNeutrinoSettings::LCD_AUTODIMM];
|
||||
}
|
||||
|
||||
void CLCD::setMuted(bool mu)
|
||||
{
|
||||
muted = mu;
|
||||
showVolume(volume);
|
||||
}
|
||||
|
||||
void CLCD::resume()
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
display.resume();
|
||||
}
|
||||
|
||||
void CLCD::pause()
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
display.pause();
|
||||
}
|
||||
|
||||
void CLCD::UpdateIcons()
|
||||
{
|
||||
}
|
||||
|
||||
void CLCD::ShowIcon(vfd_icon icon, bool show)
|
||||
{
|
||||
}
|
||||
|
||||
void CLCD::ShowIcon(fp_icon i, bool on)
|
||||
{
|
||||
vfd_icon icon = (vfd_icon) i;
|
||||
ShowIcon(icon, on);
|
||||
}
|
||||
|
||||
void CLCD::Lock()
|
||||
{
|
||||
}
|
||||
|
||||
void CLCD::Unlock()
|
||||
{
|
||||
}
|
||||
|
||||
void CLCD::Clear()
|
||||
{
|
||||
if (!has_lcd)
|
||||
return;
|
||||
|
||||
if (mode == MODE_SHUTDOWN)
|
||||
{
|
||||
display.clear_screen(); // clear lcd
|
||||
displayUpdate();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool CLCD::ShowPng(char *filename)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return false;
|
||||
|
||||
return display.load_png(filename);
|
||||
}
|
||||
|
||||
bool CLCD::DumpPng(char *filename)
|
||||
{
|
||||
if (!has_lcd)
|
||||
return false;
|
||||
|
||||
return display.dump_png(filename);
|
||||
}
|
313
src/driver/lcdd.h
Normal file
313
src/driver/lcdd.h
Normal file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
$Id: lcdd.h 2013/10/12 mohousch Exp $
|
||||
|
||||
LCD-Daemon - 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 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.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef __lcdd__
|
||||
#define __lcdd__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef LCD_UPDATE
|
||||
// TODO Why is USE_FILE_OFFSET64 not defined, if file.h is included here????
|
||||
#ifndef __USE_FILE_OFFSET64
|
||||
#define __USE_FILE_OFFSET64 1
|
||||
#endif
|
||||
#include <driver/file.h>
|
||||
#endif // LCD_UPDATE
|
||||
|
||||
#include <configfile.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <liblcddisplay/fontrenderer.h>
|
||||
|
||||
#define LCDDIR_VAR CONFIGDIR "/icons/lcdd"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VFD_ICON_BAR8 = 0x00000004,
|
||||
VFD_ICON_BAR7 = 0x00000008,
|
||||
VFD_ICON_BAR6 = 0x00000010,
|
||||
VFD_ICON_BAR5 = 0x00000020,
|
||||
VFD_ICON_BAR4 = 0x00000040,
|
||||
VFD_ICON_BAR3 = 0x00000080,
|
||||
VFD_ICON_BAR2 = 0x00000100,
|
||||
VFD_ICON_BAR1 = 0x00000200,
|
||||
VFD_ICON_FRAME = 0x00000400,
|
||||
VFD_ICON_HDD = 0x00000800,
|
||||
VFD_ICON_MUTE = 0x00001000,
|
||||
VFD_ICON_DOLBY = 0x00002000,
|
||||
VFD_ICON_POWER = 0x00004000,
|
||||
VFD_ICON_TIMESHIFT = 0x00008000,
|
||||
VFD_ICON_SIGNAL = 0x00010000,
|
||||
VFD_ICON_TV = 0x00020000,
|
||||
VFD_ICON_RADIO = 0x00040000,
|
||||
VFD_ICON_HD = 0x01000001,
|
||||
VFD_ICON_1080P = 0x02000001,
|
||||
VFD_ICON_1080I = 0x03000001,
|
||||
VFD_ICON_720P = 0x04000001,
|
||||
VFD_ICON_480P = 0x05000001,
|
||||
VFD_ICON_480I = 0x06000001,
|
||||
VFD_ICON_USB = 0x07000001,
|
||||
VFD_ICON_MP3 = 0x08000001,
|
||||
VFD_ICON_PLAY = 0x09000001,
|
||||
VFD_ICON_COL1 = 0x09000002,
|
||||
VFD_ICON_PAUSE = 0x0A000001,
|
||||
VFD_ICON_CAM1 = 0x0B000001,
|
||||
VFD_ICON_COL2 = 0x0B000002,
|
||||
VFD_ICON_CAM2 = 0x0C000001,
|
||||
VFD_ICON_CLOCK,
|
||||
VFD_ICON_FR,
|
||||
VFD_ICON_FF,
|
||||
VFD_ICON_DD,
|
||||
VFD_ICON_SCRAMBLED,
|
||||
VFD_ICON_LOCK
|
||||
} vfd_icon;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FP_ICON_BAR8 = 0x00000004,
|
||||
FP_ICON_BAR7 = 0x00000008,
|
||||
FP_ICON_BAR6 = 0x00000010,
|
||||
FP_ICON_BAR5 = 0x00000020,
|
||||
FP_ICON_BAR4 = 0x00000040,
|
||||
FP_ICON_BAR3 = 0x00000080,
|
||||
FP_ICON_BAR2 = 0x00000100,
|
||||
FP_ICON_BAR1 = 0x00000200,
|
||||
FP_ICON_FRAME = 0x00000400,
|
||||
FP_ICON_HDD = 0x00000800,
|
||||
FP_ICON_MUTE = 0x00001000,
|
||||
FP_ICON_DOLBY = 0x00002000,
|
||||
FP_ICON_POWER = 0x00004000,
|
||||
FP_ICON_TIMESHIFT = 0x00008000,
|
||||
FP_ICON_SIGNAL = 0x00010000,
|
||||
FP_ICON_TV = 0x00020000,
|
||||
FP_ICON_RADIO = 0x00040000,
|
||||
FP_ICON_HD = 0x01000001,
|
||||
FP_ICON_1080P = 0x02000001,
|
||||
FP_ICON_1080I = 0x03000001,
|
||||
FP_ICON_720P = 0x04000001,
|
||||
FP_ICON_480P = 0x05000001,
|
||||
FP_ICON_480I = 0x06000001,
|
||||
FP_ICON_USB = 0x07000001,
|
||||
FP_ICON_MP3 = 0x08000001,
|
||||
FP_ICON_PLAY = 0x09000001,
|
||||
FP_ICON_COL1 = 0x09000002,
|
||||
FP_ICON_PAUSE = 0x0A000001,
|
||||
FP_ICON_CAM1 = 0x0B000001,
|
||||
FP_ICON_COL2 = 0x0B000002,
|
||||
FP_ICON_CAM2 = 0x0C000001,
|
||||
FP_ICON_CLOCK,
|
||||
FP_ICON_FR,
|
||||
FP_ICON_FF,
|
||||
FP_ICON_DD,
|
||||
FP_ICON_SCRAMBLED,
|
||||
FP_ICON_LOCK
|
||||
} fp_icon;
|
||||
|
||||
class CLCDPainter;
|
||||
class LcdFontRenderClass;
|
||||
|
||||
class CLCD
|
||||
{
|
||||
public:
|
||||
|
||||
enum MODES
|
||||
{
|
||||
MODE_TVRADIO,
|
||||
MODE_AVINPUT,
|
||||
MODE_SHUTDOWN,
|
||||
MODE_STANDBY,
|
||||
MODE_MENU_UTF8,
|
||||
MODE_AUDIO,
|
||||
MODE_MOVIE,
|
||||
MODE_PIC,
|
||||
MODE_WEBTV
|
||||
};
|
||||
enum AUDIOMODES
|
||||
{
|
||||
AUDIO_MODE_PLAY,
|
||||
AUDIO_MODE_STOP,
|
||||
AUDIO_MODE_FF,
|
||||
AUDIO_MODE_PAUSE,
|
||||
AUDIO_MODE_REV
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
class FontsDef
|
||||
{
|
||||
public:
|
||||
LcdFont *regular;
|
||||
LcdFont *time;
|
||||
LcdFont *big;
|
||||
LcdFont *small;
|
||||
};
|
||||
|
||||
CLCDDisplay display;
|
||||
LcdFontRenderClass *fontRenderer;
|
||||
FontsDef fonts;
|
||||
int fheight_r, fheight_t, fheight_b, fheight_s;
|
||||
int time_size;
|
||||
|
||||
MODES mode;
|
||||
AUDIOMODES movie_playmode;
|
||||
|
||||
std::string servicename;
|
||||
std::string epg_title;
|
||||
std::string movie_big;
|
||||
std::string movie_small;
|
||||
std::string menutitle;
|
||||
char volume;
|
||||
bool muted;
|
||||
bool showclock;
|
||||
bool movie_centered;
|
||||
bool movie_is_ac3;
|
||||
bool icon_dolby;
|
||||
CConfigFile configfile;
|
||||
pthread_t thrTime;
|
||||
int last_toggle_state_power;
|
||||
int clearClock;
|
||||
unsigned int timeout_cnt;
|
||||
bool invert = false;
|
||||
|
||||
unsigned int lcd_width;
|
||||
unsigned int lcd_height;
|
||||
|
||||
void count_down();
|
||||
|
||||
static void *TimeThread(void *);
|
||||
bool lcdInit(const char *fontfile1, const char *fontname1,
|
||||
const char *fontfile2 = NULL, const char *fontname2 = NULL,
|
||||
const char *fontfile3 = NULL, const char *fontname3 = NULL);
|
||||
void setlcdparameter(int dimm, int contrast, int power, int inverse, int bias);
|
||||
void displayUpdate();
|
||||
void showTextScreen(const std::string &big, const std::string &small, bool perform_wakeup, bool centered = false);
|
||||
|
||||
public:
|
||||
CLCD();
|
||||
~CLCD();
|
||||
|
||||
bool has_lcd;
|
||||
bool is4digits;
|
||||
void wake_up();
|
||||
void setled(void)
|
||||
{
|
||||
return;
|
||||
};
|
||||
void setlcdparameter(void);
|
||||
|
||||
static CLCD *getInstance();
|
||||
void init(const char *fontfile, const char *fontname,
|
||||
const char *fontfile2 = NULL, const char *fontname2 = NULL,
|
||||
const char *fontfile3 = NULL, const char *fontname3 = NULL);
|
||||
|
||||
void setMode(const MODES m, const char *const title = "");
|
||||
MODES getMode()
|
||||
{
|
||||
return mode;
|
||||
};
|
||||
|
||||
void showServicename(const std::string name, const bool perform_wakeup = true); // UTF-8
|
||||
void setEPGTitle(const std::string title);
|
||||
void setMovieInfo(const AUDIOMODES playmode, const std::string big, const std::string small, const bool centered = false);
|
||||
void setMovieAudio(const bool is_ac3);
|
||||
std::string getMenutitle()
|
||||
{
|
||||
return menutitle;
|
||||
};
|
||||
void showTime();
|
||||
/** blocks for duration seconds */
|
||||
void showRCLock(int duration = 2);
|
||||
void showVolume(const char vol, const bool perform_update = true);
|
||||
void showPercentOver(const unsigned char perc, const bool perform_update = true, const MODES m = MODE_TVRADIO);
|
||||
void showMenuText(const int position, const char *text, const int highlight = -1, const bool utf_encoded = false);
|
||||
void showAudioTrack(const std::string &artist, const std::string &title, const std::string &album);
|
||||
void showAudioPlayMode(AUDIOMODES m = AUDIO_MODE_PLAY);
|
||||
void showAudioProgress(const char perc, bool isMuted = false);
|
||||
void setBrightness(int);
|
||||
void setBacklight(int) { return;};
|
||||
int getBrightness();
|
||||
|
||||
void setBrightnessStandby(int);
|
||||
int getBrightnessStandby();
|
||||
|
||||
void setScrollMode(int scroll_repeats);
|
||||
|
||||
void setContrast(int);
|
||||
int getContrast();
|
||||
|
||||
void setPower(int);
|
||||
int getPower();
|
||||
|
||||
void togglePower(void);
|
||||
|
||||
void setInverse(int);
|
||||
int getInverse();
|
||||
|
||||
void setAutoDimm(int);
|
||||
int getAutoDimm();
|
||||
void setBrightnessDeepStandby(int)
|
||||
{
|
||||
return ;
|
||||
};
|
||||
int getBrightnessDeepStandby()
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
void repaintIcons()
|
||||
{
|
||||
return;
|
||||
};
|
||||
void setMuted(bool);
|
||||
|
||||
void resume();
|
||||
void pause();
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
void Clear();
|
||||
void UpdateIcons();
|
||||
void ShowIcon(fp_icon icon, bool show);
|
||||
void ShowIcon(vfd_icon icon, bool show);
|
||||
void ShowText(const char *s)
|
||||
{
|
||||
showServicename(std::string(s));
|
||||
};
|
||||
void LCDshowText(int /*pos*/)
|
||||
{
|
||||
return ;
|
||||
};
|
||||
|
||||
bool ShowPng(char *filename);
|
||||
bool DumpPng(char *filename);
|
||||
|
||||
unsigned char percentOver;
|
||||
};
|
||||
|
||||
#endif
|
@@ -166,6 +166,16 @@ int CVfdSetup::showSetup()
|
||||
}
|
||||
|
||||
CMenuOptionChooser *oj;
|
||||
#ifdef ENABLE_LCD
|
||||
#if 0
|
||||
// option power
|
||||
oj = new CMenuOptionChooser("Power LCD"/*LOCALE_LCDMENU_POWER*/, &g_settings.lcd_setting[SNeutrinoSettings::LCD_POWER], OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, new CLCDNotifier(), CRCInput::RC_nokey);
|
||||
vfds->addItem(oj);
|
||||
#endif
|
||||
// option invert
|
||||
oj = new CMenuOptionChooser("Invert LCD"/*LOCALE_LCDMENU_INVERSE*/, &g_settings.lcd_setting[SNeutrinoSettings::LCD_INVERSE], OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, new CLCDNotifier(), CRCInput::RC_nokey);
|
||||
vfds->addItem(oj);
|
||||
#endif
|
||||
if (g_info.hw_caps->display_has_statusline)
|
||||
{
|
||||
// status line options
|
||||
@@ -174,6 +184,7 @@ int CVfdSetup::showSetup()
|
||||
vfds->addItem(oj);
|
||||
}
|
||||
|
||||
#ifndef ENABLE_LCD
|
||||
// info line options
|
||||
oj = new CMenuOptionChooser(LOCALE_LCD_INFO_LINE, &g_settings.lcd_info_line, LCD_INFO_OPTIONS, LCD_INFO_OPTION_COUNT, vfd_enabled);
|
||||
oj->setHint("", LOCALE_MENU_HINT_VFD_INFOLINE);
|
||||
@@ -200,6 +211,7 @@ int CVfdSetup::showSetup()
|
||||
oj = new CMenuOptionChooser(LOCALE_LCDMENU_NOTIFY_RCLOCK, &g_settings.lcd_notify_rclock, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, vfd_enabled);
|
||||
oj->setHint("", LOCALE_MENU_HINT_VFD_NOTIFY_RCLOCK);
|
||||
vfds->addItem(oj);
|
||||
#endif // ENABLE_LCD
|
||||
}
|
||||
|
||||
if (g_info.hw_caps->display_type == HW_DISPLAY_LED_NUM)
|
||||
@@ -273,25 +285,41 @@ int CVfdSetup::showBrightnessSetup()
|
||||
brightnessstandby = CVFD::getInstance()->getBrightnessStandby();
|
||||
brightnessdeepstandby = CVFD::getInstance()->getBrightnessDeepStandby();
|
||||
|
||||
#ifdef ENABLE_LCD
|
||||
nc = new CMenuOptionNumberChooser(LOCALE_LCDCONTROLER_BRIGHTNESS, &brightness, true, 0, 255, this, CRCInput::RC_nokey, NULL, 0, 0, NONEXISTANT_LOCALE, true);
|
||||
#else
|
||||
nc = new CMenuOptionNumberChooser(LOCALE_LCDCONTROLER_BRIGHTNESS, &brightness, true, 0, 15, this, CRCInput::RC_nokey, NULL, 0, 0, NONEXISTANT_LOCALE, true);
|
||||
#endif
|
||||
nc->setHint("", LOCALE_MENU_HINT_VFD_BRIGHTNESS);
|
||||
nc->setActivateObserver(this);
|
||||
mn_widget->addItem(nc);
|
||||
|
||||
#ifdef ENABLE_LCD
|
||||
nc = new CMenuOptionNumberChooser(LOCALE_LCDCONTROLER_BRIGHTNESSSTANDBY, &brightnessstandby, true, 0, 255, this, CRCInput::RC_nokey, NULL, 0, 0, NONEXISTANT_LOCALE, true);
|
||||
#else
|
||||
nc = new CMenuOptionNumberChooser(LOCALE_LCDCONTROLER_BRIGHTNESSSTANDBY, &brightnessstandby, true, 0, 15, this, CRCInput::RC_nokey, NULL, 0, 0, NONEXISTANT_LOCALE, true);
|
||||
#endif
|
||||
nc->setHint("", LOCALE_MENU_HINT_VFD_BRIGHTNESSSTANDBY);
|
||||
nc->setActivateObserver(this);
|
||||
mn_widget->addItem(nc);
|
||||
|
||||
if (g_info.hw_caps->display_can_deepstandby)
|
||||
{
|
||||
#ifdef ENABLE_LCD
|
||||
nc = new CMenuOptionNumberChooser(LOCALE_LCDCONTROLER_BRIGHTNESSDEEPSTANDBY, &brightnessdeepstandby, true, 0, 255, this, CRCInput::RC_nokey, NULL, 0, 0, NONEXISTANT_LOCALE, true);
|
||||
#else
|
||||
nc = new CMenuOptionNumberChooser(LOCALE_LCDCONTROLER_BRIGHTNESSDEEPSTANDBY, &brightnessdeepstandby, true, 0, 15, this, CRCInput::RC_nokey, NULL, 0, 0, NONEXISTANT_LOCALE, true);
|
||||
#endif
|
||||
nc->setHint("", LOCALE_MENU_HINT_VFD_BRIGHTNESSDEEPSTANDBY);
|
||||
nc->setActivateObserver(this);
|
||||
mn_widget->addItem(nc);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LCD
|
||||
nc = new CMenuOptionNumberChooser(LOCALE_LCDMENU_DIM_BRIGHTNESS, &g_settings.lcd_setting_dim_brightness, true, -1, 255, NULL, CRCInput::RC_nokey, NULL, 0, -1, LOCALE_OPTIONS_OFF, true);
|
||||
#else
|
||||
nc = new CMenuOptionNumberChooser(LOCALE_LCDMENU_DIM_BRIGHTNESS, &g_settings.lcd_setting_dim_brightness, vfd_enabled, -1, 15, NULL, CRCInput::RC_nokey, NULL, 0, -1, LOCALE_OPTIONS_OFF, true);
|
||||
#endif
|
||||
nc->setHint("", LOCALE_MENU_HINT_VFD_BRIGHTNESSDIM);
|
||||
nc->setActivateObserver(this);
|
||||
mn_widget->addItem(nc);
|
||||
@@ -385,10 +413,12 @@ bool CVfdSetup::changeNotify(const neutrino_locale_t OptionName, void * /* data
|
||||
{
|
||||
CVFD::getInstance()->setled();
|
||||
}
|
||||
#ifndef ENABLE_LCD
|
||||
else if (ARE_LOCALES_EQUAL(OptionName, LOCALE_LEDCONTROLER_BACKLIGHT_TV))
|
||||
{
|
||||
CVFD::getInstance()->setBacklight(g_settings.backlight_tv);
|
||||
}
|
||||
#endif
|
||||
else if (ARE_LOCALES_EQUAL(OptionName, LOCALE_LCDMENU_SCROLL) || ARE_LOCALES_EQUAL(OptionName, LOCALE_LCDMENU_SCROLL_REPEATS))
|
||||
{
|
||||
CVFD::getInstance()->setScrollMode(g_settings.lcd_scroll);
|
||||
@@ -425,3 +455,21 @@ void CVfdSetup::activateNotify(const neutrino_locale_t OptionName)
|
||||
CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_LCD
|
||||
// lcd notifier
|
||||
bool CLCDNotifier::changeNotify(const neutrino_locale_t, void * Data)
|
||||
{
|
||||
int state = *(int *)Data;
|
||||
|
||||
dprintf(DEBUG_NORMAL, "CLCDNotifier: state: %d\n", state);
|
||||
#if 0
|
||||
CVFD::getInstance()->setPower(state);
|
||||
#else
|
||||
CVFD::getInstance()->setPower(1);
|
||||
#endif
|
||||
CVFD::getInstance()->setlcdparameter();
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@@ -59,4 +59,13 @@ class CVfdSetup : public CMenuTarget, CChangeObserver, CActivateObserver
|
||||
int exec(CMenuTarget *parent, const std::string &actionKey);
|
||||
};
|
||||
|
||||
#ifdef ENABLE_LCD
|
||||
// lcd notifier
|
||||
class CLCDNotifier : public CChangeObserver
|
||||
{
|
||||
public:
|
||||
bool changeNotify(const neutrino_locale_t, void *Data);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user