add hd51; mostly ported from TangoCash's neutrino-mp

Origin commit data
------------------
Branch: ni/coolstream
Commit: 6fe5d269af
Author: vanhofen <vanhofen@gmx.de>
Date: 2017-10-05 (Thu, 05 Oct 2017)

Origin message was:
------------------
- add hd51; mostly ported from TangoCash's neutrino-mp

------------------
No further description and justification available within origin commit message!

------------------
This commit was generated by Migit
This commit is contained in:
vanhofen
2017-10-05 12:52:53 +02:00
committed by Thilo Graf
parent 809cbf7a4c
commit 6bca93d258
30 changed files with 2528 additions and 227 deletions

View File

@@ -82,6 +82,11 @@ libneutrino_driver_a_SOURCES += \
fb_accel_glfb.cpp \
simple_display.cpp
endif
if BOXTYPE_ARMBOX
libneutrino_driver_a_SOURCES += \
fb_accel.cpp \
simple_display.cpp
endif
if USE_STB_HAL
AM_CPPFLAGS += \
@DIRECTFB_CFLAGS@

View File

@@ -2,6 +2,6 @@
#if HAVE_COOL_HARDWARE
#include <driver/vfd.h>
#endif
#if HAVE_TRIPLEDRAGON || HAVE_SPARK_HARDWARE || HAVE_AZBOX_HARDWARE || HAVE_GENERIC_HARDWARE
#if HAVE_TRIPLEDRAGON || HAVE_SPARK_HARDWARE || HAVE_AZBOX_HARDWARE || HAVE_GENERIC_HARDWARE || HAVE_ARM_HARDWARE
#include <driver/lcdd.h>
#endif

View File

@@ -51,8 +51,6 @@
#include <daemonc/remotecontrol.h>
extern CRemoteControl * g_RemoteControl; /* neutrino.cpp */
/* we get edvbstring.h included via from src/system/settings.h */
#if 0
/* from edvbstring.cpp */
static bool isUTF8(const std::string &string)
{
@@ -84,7 +82,6 @@ static bool isUTF8(const std::string &string)
}
return true; // can be UTF8 (or pure ASCII, at least no non-UTF-8 8bit characters)
}
#endif
CLCD::CLCD()
{
@@ -145,9 +142,8 @@ void CLCD::count_down() {
}
void CLCD::wake_up() {
int tmp = atoi(g_settings.lcd_setting_dim_time.c_str());
if (tmp > 0) {
timeout_cnt = (unsigned int)tmp;
if (atoi(g_settings.lcd_setting_dim_time) > 0) {
timeout_cnt = atoi(g_settings.lcd_setting_dim_time);
setlcdparameter();
}
}
@@ -155,8 +151,8 @@ void CLCD::wake_up() {
#ifndef BOXMODEL_DM500
void* CLCD::TimeThread(void *p)
{
set_threadname("lcd:time");
((CLCD *)p)->thread_started = true;
set_threadname("lcd:time");
while (((CLCD *)p)->thread_started)
{
sleep(1);
@@ -392,7 +388,7 @@ void CLCD::setlcdparameter(int /*dimm*/, const int contrast, const int /*power*/
void CLCD::setlcdparameter(void)
{
last_toggle_state_power = g_settings.lcd_setting[SNeutrinoSettings::LCD_POWER];
int dim_time = atoi(g_settings.lcd_setting_dim_time.c_str());
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;
@@ -716,13 +712,11 @@ void CLCD::showVolume(const char vol, const bool perform_update)
wake_up();
}
void CLCD::showPercentOver(const unsigned char perc, const bool perform_update, const MODES /*m*/)
void CLCD::showPercentOver(const unsigned char perc, const bool perform_update, const MODES m)
{
/*
if (mode != m)
printf("CLCD::showPercentOver: mode (%d) != m (%d), please report\n", (int)mode, (int)m);
// return;
*/
return;
int left, top, width, height = 5;
bool draw = true;
percentOver = perc;
@@ -905,14 +899,13 @@ void CLCD::showAudioPlayMode(AUDIOMODES m)
displayUpdate();
}
void CLCD::showAudioProgress(const char perc) //, bool isMuted)
void CLCD::showAudioProgress(const char perc, bool isMuted)
{
if (mode == MODE_AUDIO)
{
display.draw_fill_rect (11,53,73,61, CLCDDisplay::PIXEL_OFF);
int dp = perc * 61 / 100 + 12;
display.draw_fill_rect (11,54,dp,60, CLCDDisplay::PIXEL_ON);
#if 0
if(isMuted)
{
if(dp > 12)
@@ -923,7 +916,6 @@ void CLCD::showAudioProgress(const char perc) //, bool isMuted)
else
display.draw_line (12,55,72,59, CLCDDisplay::PIXEL_ON);
}
#endif
displayUpdate();
}
}

View File

@@ -60,10 +60,51 @@ typedef enum
FP_ICON_PAUSE = 0x0A000001,
FP_ICON_CAM1 = 0x0B000001,
FP_ICON_COL2 = 0x0B000002,
FP_ICON_CAM2 = 0x0C000001
FP_ICON_CAM2 = 0x0C000001,
FP_ICON_CLOCK,
FP_ICON_FR,
FP_ICON_FF,
FP_ICON_DD,
FP_ICON_LOCK
} fp_icon;
#define CVFD CLCD
typedef enum
{
SPARK_PLAY_FASTBACKWARD = 1,
SPARK_PLAY = 3,
SPARK_PLAY_FASTFORWARD = 5,
SPARK_PAUSE = 6,
SPARK_REC1 = 7,
SPARK_MUTE = 8,
SPARK_CYCLE = 9,
SPARK_DD = 10,
SPARK_CA = 11,
SPARK_CI= 12,
SPARK_USB = 13,
SPARK_DOUBLESCREEN = 14,
SPARK_HDD_A8 = 16,
SPARK_HDD_A7 = 17,
SPARK_HDD_A6 = 18,
SPARK_HDD_A5 = 19,
SPARK_HDD_A4 = 20,
SPARK_HDD_A3 = 21,
SPARK_HDD_FULL = 22,
SPARK_HDD_A2 = 23,
SPARK_HDD_A1 = 24,
SPARK_MP3 = 25,
SPARK_AC3 = 26,
SPARK_TVMODE_LOG = 27,
SPARK_AUDIO = 28,
SPARK_HDD = 30,
SPARK_CLOCK = 33,
SPARK_TER = 37,
SPARK_SAT = 42,
SPARK_TIMESHIFT = 43,
SPARK_CAB = 45,
SPARK_ALL = 46
} spark_icon;
#ifdef LCD_UPDATE
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -116,6 +157,7 @@ class CLCD
private:
#ifdef HAVE_TRIPLEDRAGON
class FontsDef
{
@@ -173,7 +215,14 @@ class CLCD
static void *TimeThread(void *);
pthread_t thrTime;
bool thread_running;
int last_toggle_state_power;
int brightness;
unsigned int timeout_cnt;
unsigned int switch_name_time_cnt;
void setlcdparameter(int dimm, int power);
void count_down();
#endif
public:
bool has_lcd;
void wake_up();
@@ -191,6 +240,7 @@ class CLCD
void setHddUsage(int perc);
void showServicename(const std::string name, const bool clear_epg = false);
std::string getServicename(void) { return servicename; }
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);
@@ -203,7 +253,7 @@ class CLCD
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);
void showAudioProgress(const char perc, bool isMuted = false);
void setBrightness(int);
int getBrightness();
@@ -225,7 +275,7 @@ class CLCD
int getAutoDimm();
void setBrightnessDeepStandby(int) { return ; };
int getBrightnessDeepStandby() { return 0; };
void repaintIcons() { return; };
void setMuted(bool);
void resume();
@@ -234,6 +284,10 @@ class CLCD
void Lock();
void Unlock();
void Clear();
void SetIcons(int icon, bool show);
void UpdateIcons();
void ShowDiskLevel();
void Reset() {};
void ShowIcon(fp_icon icon, bool show);
void ShowText(const char *s) { showServicename(std::string(s), true); };
~CLCD();

View File

@@ -386,8 +386,11 @@ bool CMovieInfo::parseXmlTree(std::string &_text, MI_MOVIE_INFO *movie_info)
}
}
}
//printf("MOVIE INFO: apid %d type %d name %s selected %d\n", audio_pids.AudioPid, audio_pids.atype, audio_pids.AudioPidName.c_str(), audio_pids.selected);
movie_info->audioPids.push_back(audio_pids);
//printf("MOVIE INFO: apid %d type %d name %s selected %d\n", audio_pids.AudioPid, audio_pids.atype, audio_pids.epgAudioPidName.c_str(), audio_pids.selected);
unsigned int j, asize = movie_info->audioPids.size();
for (j = 0; j < asize && audio_pids.AudioPid != movie_info->audioPids[j].AudioPid; j++);
if (j == asize)
movie_info->audioPids.push_back(audio_pids);
}
/* parse bookmarks */
GET_XML_DATA_INT(text, pos, MI_XML_TAG_BOOKMARK_START, movie_info->bookmarks.start)
@@ -487,6 +490,57 @@ bool CMovieInfo::addNewBookmark(MI_MOVIE_INFO * movie_info, MI_BOOKMARK & new_bo
}
void CMovieInfo::clearMovieInfo(MI_MOVIE_INFO * movie_info)
{
//TRACE("[mi]->clearMovieInfo \r\n");
tm timePlay;
timePlay.tm_hour = 0;
timePlay.tm_min = 0;
timePlay.tm_sec = 0;
timePlay.tm_year = 100;
timePlay.tm_mday = 0;
timePlay.tm_mon = 1;
movie_info->file.Name = "";
movie_info->file.Size = 0; // Megabytes
movie_info->file.Time = mktime(&timePlay);
movie_info->dateOfLastPlay = mktime(&timePlay); // (date, month, year)
movie_info->dirItNr = 0; //
movie_info->genreMajor = 0; //genreMajor;
movie_info->genreMinor = 0; //genreMinor;
movie_info->length = 0; // (minutes)
movie_info->quality = 0; // (3 stars: classics, 2 stars: very good, 1 star: good, 0 stars: OK)
movie_info->productionDate = 0; // (Year) years since 1900
movie_info->parentalLockAge = 0; // MI_PARENTAL_LOCKAGE (0,6,12,16,18)
movie_info->channelId = 0;
movie_info->epgId = 0;
movie_info->mode = 0;
movie_info->VideoPid = 0;
movie_info->VideoType = 0;
movie_info->VtxtPid = 0;
movie_info->audioPids.clear();
movie_info->productionCountry = "";
movie_info->epgTitle = "";
movie_info->epgInfo1 = ""; //epgInfo1
movie_info->epgInfo2 = ""; //epgInfo2
movie_info->channelName = "";
movie_info->serieName = ""; // (name e.g. 'StarWars)
movie_info->bookmarks.end = 0;
movie_info->bookmarks.start = 0;
movie_info->bookmarks.lastPlayStop = 0;
for (int i = 0; i < MI_MOVIE_BOOK_USER_MAX; i++) {
movie_info->bookmarks.user[i].pos = 0;
movie_info->bookmarks.user[i].length = 0;
movie_info->bookmarks.user[i].name = "";
}
movie_info->tfile.clear();
movie_info->ytdate.clear();
movie_info->ytid.clear();
}
void MI_MOVIE_INFO::clear(void)
{
tm timePlay;

View File

@@ -177,6 +177,7 @@ class CMovieInfo
bool encodeMovieInfoXml(std::string *extMessage, MI_MOVIE_INFO *movie_info); // encode the movie_info structure to xml string
bool saveMovieInfo(MI_MOVIE_INFO &movie_info, CFile *file = NULL ); // encode the movie_info structure to xml and save it to the given .xml filename. If there is no filename, the filename (ts) from movie_info is converted to xml and used instead
bool addNewBookmark(MI_MOVIE_INFO *movie_info, MI_BOOKMARK &new_bookmark); // add a new bookmark to the given movie info. If there is no space false is returned
void clearMovieInfo(MI_MOVIE_INFO *movie_info); // clear infos completly
private: // Functions
bool parseXmlTree(std::string &text, MI_MOVIE_INFO *movie_info);

View File

@@ -54,6 +54,7 @@ extern "C" {
extern cVideo *videoDecoder;
#if HAVE_COOL_HARDWARE
/* constructor, defaults is empty fname and CScreenShot::FORMAT_JPG format */
CScreenShot::CScreenShot(const std::string fname, screenshot_format_t fmt)
{
@@ -147,6 +148,7 @@ bool CScreenShot::GetData()
#endif
if (videoDecoder->getBlank())
get_video = false;
#ifdef BOXMODEL_CS_HD2
if (extra_osd && !get_video) {
uint32_t memSize = xres * yres * sizeof(fb_pixel_t) * 2;
@@ -161,7 +163,7 @@ bool CScreenShot::GetData()
}
else
#endif
#ifdef SCREENSHOT
#if 1 // to enable after libcs/drivers update
res = videoDecoder->GetScreenImage(pixel_data, xres, yres, get_video, get_osd, scale_to_video);
#endif
@@ -317,7 +319,11 @@ bool CScreenShot::SavePng()
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL);
info_ptr = png_create_info_struct(png_ptr);
#if (PNG_LIBPNG_VER < 10500)
if (setjmp(png_ptr->jmpbuf))
#else
if (setjmp(png_jmpbuf(png_ptr)))
#endif
{
printf("CScreenShot::SavePng: %s save error\n", filename.c_str());
png_destroy_write_struct(&png_ptr, &info_ptr);
@@ -524,3 +530,529 @@ void CScreenShot::MakeFileName(const t_channel_id channel_id)
printf("CScreenShot::MakeFileName: [%s]\n", fname);
filename = std::string(fname);
}
#else //HAVE_COOL_HARDWARE
/* constructor, defaults is empty fname and CScreenShot::FORMAT_JPG format */
CScreenShot::CScreenShot(const std::string fname, screenshot_format_t fmt)
{
format = fmt;
filename = fname;
pixel_data = NULL;
fd = NULL;
xres = 0;
yres = 0;
extra_osd = false;
scs_thread = 0;
pthread_mutex_init(&thread_mutex, NULL);
pthread_mutex_init(&getData_mutex, NULL);
get_video = g_settings.screenshot_video;
get_osd = g_settings.screenshot_mode;
scale_to_video = g_settings.screenshot_scale;
}
CScreenShot::~CScreenShot()
{
pthread_mutex_destroy(&thread_mutex);
pthread_mutex_destroy(&getData_mutex);
// printf("[CScreenShot::%s:%d] thread: %p\n", __func__, __LINE__, this);
}
#ifdef BOXMODEL_CS_HD2
bool CScreenShot::mergeOsdScreen(uint32_t dx, uint32_t dy, fb_pixel_t* osdData)
{
uint8_t* d = (uint8_t *)pixel_data;
fb_pixel_t* d2;
for (uint32_t count = 0; count < dy; count++ ) {
fb_pixel_t *pixpos = (fb_pixel_t*)&osdData[count*dx];
d2 = (fb_pixel_t*)d;
for (uint32_t count2 = 0; count2 < dx; count2++ ) {
//don't paint backgroundcolor (*pixpos = 0x00000000)
if (*pixpos) {
fb_pixel_t pix = *pixpos;
if ((pix & 0xff000000) == 0xff000000)
*d2 = (pix & 0x00ffffff);
else {
uint8_t *in = (uint8_t *)(pixpos);
uint8_t *out = (uint8_t *)d2;
int a = in[3];
*out = (*out + ((*in - *out) * a) / 256);
in++; out++;
*out = (*out + ((*in - *out) * a) / 256);
in++; out++;
*out = (*out + ((*in - *out) * a) / 256);
}
}
d2++;
pixpos++;
}
d += dx*sizeof(fb_pixel_t);
}
return true;
}
#endif
/* try to get video frame data in ARGB format, restore GXA state */
bool CScreenShot::GetData()
{
#ifdef BOXMODEL_CS_HD2
/* Workaround for broken osd screenshot with new fb driver and 1280x720 resolution */
CFrameBuffer* frameBuffer = CFrameBuffer::getInstance();
fb_pixel_t* screenBuf = NULL;
uint32_t _xres = 0, _yres = 0;
if (frameBuffer->fullHdAvailable() && (frameBuffer->getScreenWidth(true) == 1280)) {
_xres = xres = 1280;
_yres = yres = 720;
get_osd = false;
extra_osd = true;
screenBuf = new fb_pixel_t[_xres*_yres*sizeof(fb_pixel_t)];
if (screenBuf == NULL) {
printf("[CScreenShot::%s:%d] memory error\n", __func__, __LINE__);
return false;
}
printf("\n[CScreenShot::%s:%d] Read osd screen...", __func__, __LINE__);
frameBuffer->SaveScreen(0, 0, _xres, _yres, screenBuf);
printf(" done.\n");
}
#endif
bool res = false;
pthread_mutex_lock(&getData_mutex);
#ifdef BOXMODEL_CS_HD1
CFrameBuffer::getInstance()->setActive(false);
#endif
if (videoDecoder->getBlank())
get_video = false;
#ifdef BOXMODEL_CS_HD2
if (extra_osd && !get_video) {
uint32_t memSize = xres * yres * sizeof(fb_pixel_t) * 2;
pixel_data = (uint8_t*)cs_malloc_uncached(memSize);
if (pixel_data == NULL) {
printf("[CScreenShot::%s:%d] memory error\n", __func__, __LINE__);
pthread_mutex_unlock(&getData_mutex);
return false;
}
memset(pixel_data, 0, memSize);
res = true;
}
else
#endif
#if 1 // to enable after libcs/drivers update
res = videoDecoder->GetScreenImage(pixel_data, xres, yres, get_video, get_osd, scale_to_video);
#endif
#ifdef BOXMODEL_CS_HD1
/* sort of hack. GXA used to transfer/convert live image to RGB,
* so setup GXA back */
CFrameBuffer::getInstance()->setupGXA();
CFrameBuffer::getInstance()->add_gxa_sync_marker();
CFrameBuffer::getInstance()->setActive(true);
#endif
pthread_mutex_unlock(&getData_mutex);
if (!res) {
printf("[CScreenShot::%s:%d] GetScreenImage failed\n", __func__, __LINE__);
return false;
}
#ifdef BOXMODEL_CS_HD2
if (extra_osd && screenBuf) {
printf("[CScreenShot::%s:%d] Merge osd screen to screenshot...", __func__, __LINE__);
mergeOsdScreen(_xres, _yres, screenBuf);
delete[] screenBuf;
printf(" done.\n \n");
}
#endif
printf("[CScreenShot::%s:%d] data: %p %d x %d\n", __func__, __LINE__, pixel_data, xres, yres);
return true;
}
bool CScreenShot::startThread()
{
if (!scs_thread) {
void *ptr = static_cast<void*>(this);
int res = pthread_create(&scs_thread, NULL, initThread, ptr);
if (res != 0) {
printf("[CScreenShot::%s:%d] ERROR! pthread_create\n", __func__, __LINE__);
return false;
}
pthread_detach(scs_thread);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
}
return true;
}
void* CScreenShot::initThread(void *arg)
{
CScreenShot *scs = static_cast<CScreenShot*>(arg);
pthread_cleanup_push(cleanupThread, scs);
// printf("[CScreenShot::%s:%d] thread: %p\n", __func__, __LINE__, scs);
scs->runThread();
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_exit(0);
pthread_cleanup_pop(0);
return 0;
}
/* thread function to save data asynchroniosly. delete itself after saving */
void CScreenShot::runThread()
{
pthread_mutex_lock(&thread_mutex);
printf("[CScreenShot::%s:%d] save to %s format %d\n", __func__, __LINE__, filename.c_str(), format);
bool ret = SaveFile();
printf("[CScreenShot::%s:%d] %s finished: %d\n", __func__, __LINE__, filename.c_str(), ret);
pthread_mutex_unlock(&thread_mutex);
}
void CScreenShot::cleanupThread(void *arg)
{
CScreenShot *scs = static_cast<CScreenShot*>(arg);
// printf("[CScreenShot::%s:%d] thread: %p\n", __func__, __LINE__, scs);
delete scs;
}
// printf("[CScreenShot::%s:%d] thread: %p\n", __func__, __LINE__, scs);
delete scs;
}
/* start ::run in new thread to save file in selected format */
#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE
bool CScreenShot::Start(const std::string custom_cmd)
{
std::string cmd = "/bin/grab ";
if (get_osd && !get_video)
cmd += "-o ";
else if (!get_osd && get_video)
cmd += "-v ";
switch (format) {
case FORMAT_PNG:
cmd += "-p ";
break;
case FORMAT_JPG:
cmd += "-j 100";
break;
default:
;
}
if (!scale_to_video)
cmd += " -d";
if (xres) {
char tmp[10];
snprintf(tmp, sizeof(tmp), "%d", xres);
cmd += "-w " + std::string(tmp);
}
if (!custom_cmd.empty())
cmd = "/bin/grab " + custom_cmd;
cmd += " '";
cmd += filename;
cmd += "'";
fprintf(stderr, "running: %s\n", cmd.c_str());
system(cmd.c_str());
return true;
}
#else
/* start ::run in new thread to save file in selected format */
bool CScreenShot::Start()
{
set_threadname("n:screenshot");
bool ret = false;
if (GetData())
ret = startThread();
else
delete this;
return ret;
}
#endif
/* save file in sync mode, return true if save ok, or false */
bool CScreenShot::StartSync()
{
bool ret = false;
printf("[CScreenShot::%s:%d] save to %s format %d\n", __func__, __LINE__, filename.c_str(), format);
if (GetData())
ret = SaveFile();
printf("[CScreenShot::%s:%d] %s finished: %d\n", __func__, __LINE__, filename.c_str(), ret);
return ret;
}
/* save file in selected format, free data received from video decoder */
bool CScreenShot::SaveFile()
{
bool ret = true;
switch (format) {
case FORMAT_PNG:
ret = SavePng();
break;
default:
printf("CScreenShot::SaveFile unsupported format %d, using jpeg\n", format);
/* fall through */
case FORMAT_JPG:
ret = SaveJpg();
break;
case FORMAT_BMP:
ret = SaveBmp();
break;
}
cs_free_uncached((void *) pixel_data);
return ret;
}
/* try to open file, return true if success, or false */
bool CScreenShot::OpenFile()
{
fd = fopen(filename.c_str(), "w");
if (!fd) {
printf("CScreenShot::OpenFile: failed to open %s\n", filename.c_str());
return false;
}
return true;
}
/* save screenshot in png format, return true if success, or false */
bool CScreenShot::SavePng()
{
png_bytep *row_pointers;
png_structp png_ptr;
png_infop info_ptr;
TIMER_START();
if(!OpenFile())
return false;
row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * yres);
if (!row_pointers) {
printf("CScreenShot::SavePng: malloc error\n");
fclose(fd);
return false;
}
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL);
info_ptr = png_create_info_struct(png_ptr);
#if (PNG_LIBPNG_VER < 10500)
if (setjmp(png_ptr->jmpbuf))
#else
if (setjmp(png_jmpbuf(png_ptr)))
#endif
{
printf("CScreenShot::SavePng: %s save error\n", filename.c_str());
png_destroy_write_struct(&png_ptr, &info_ptr);
free(row_pointers);
fclose(fd);
return false;
}
png_init_io(png_ptr, fd);
int y;
for (y=0; y<yres; y++) {
row_pointers[y] = pixel_data + (y*xres*4);
}
png_set_IHDR(png_ptr, info_ptr, xres, yres, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
//png_set_filter (png_ptr, 0, PNG_FILTER_NONE);
png_set_compression_level(png_ptr, Z_BEST_SPEED);
png_set_bgr(png_ptr);
#ifdef BOXMODEL_CS_HD2
png_set_invert_alpha(png_ptr);
#endif
png_write_info(png_ptr, info_ptr);
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
free(row_pointers);
fclose(fd);
TIMER_STOP(("[CScreenShot::SavePng] " + filename).c_str());
return true;
}
#define SWAP(x,y) { x ^= y; y ^= x; x ^= y; }
/* from libjpg example.c */
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
void my_error_exit (j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr) cinfo->err;
/* Always display the message. */
/* We could postpone this until after returning, if we chose. */
(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
/* save screenshot in jpg format, return true if success, or false */
bool CScreenShot::SaveJpg()
{
int quality = 90;
TIMER_START();
if(!OpenFile())
return false;
for (int y = 0; y < yres; y++) {
int xres1 = y*xres*3;
int xres2 = xres1+2;
for (int x = 0; x < xres; x++) {
int x2 = x*3;
memmove(pixel_data + x2 + xres1, pixel_data + x*4 + y*xres*4, 3);
SWAP(pixel_data[x2 + xres1], pixel_data[x2 + xres2]);
}
}
struct jpeg_compress_struct cinfo;
struct my_error_mgr jerr;
JSAMPROW row_pointer[1];
unsigned int row_stride;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
printf("CScreenShot::SaveJpg: %s save error\n", filename.c_str());
jpeg_destroy_compress(&cinfo);
fclose(fd);
return false;
}
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, fd);
cinfo.image_width = xres;
cinfo.image_height = yres;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
cinfo.dct_method = JDCT_IFAST;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
row_stride = xres * 3;
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = & pixel_data[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
fclose(fd);
TIMER_STOP(("[CScreenShot::SaveJpg] " + filename).c_str());
return true;
}
/* save screenshot in bmp format, return true if success, or false */
bool CScreenShot::SaveBmp()
{
TIMER_START();
if(!OpenFile())
return false;
unsigned char hdr[14 + 40];
unsigned int i = 0;
#define PUT32(x) hdr[i++] = ((x)&0xFF); hdr[i++] = (((x)>>8)&0xFF); hdr[i++] = (((x)>>16)&0xFF); hdr[i++] = (((x)>>24)&0xFF);
#define PUT16(x) hdr[i++] = ((x)&0xFF); hdr[i++] = (((x)>>8)&0xFF);
#define PUT8(x) hdr[i++] = ((x)&0xFF);
PUT8('B'); PUT8('M');
PUT32((((xres * yres) * 3 + 3) &~ 3) + 14 + 40);
PUT16(0); PUT16(0); PUT32(14 + 40);
PUT32(40); PUT32(xres); PUT32(yres);
PUT16(1);
PUT16(4*8); // bits
PUT32(0); PUT32(0); PUT32(0); PUT32(0); PUT32(0); PUT32(0);
#undef PUT32
#undef PUT16
#undef PUT8
fwrite(hdr, 1, i, fd);
int y;
for (y=yres-1; y>=0 ; y-=1) {
fwrite(pixel_data+(y*xres*4),xres*4,1,fd);
}
fclose(fd);
TIMER_STOP(("[CScreenShot::SaveBmp] " + filename).c_str());
return true;
}
/*
* create filename member from channel name and its current EPG data,
* with added date and time including msecs and suffix for selected format
*/
void CScreenShot::MakeFileName(const t_channel_id channel_id)
{
char fname[512]; // UTF-8
std::string channel_name;
CEPGData epgData;
unsigned int pos = 0;
snprintf(fname, sizeof(fname), "%s/", g_settings.screenshot_dir.c_str());
pos = strlen(fname);
channel_name = CServiceManager::getInstance()->GetServiceName(channel_id);
if (!(channel_name.empty())) {
strcpy(&(fname[pos]), UTF8_TO_FILESYSTEM_ENCODING(channel_name.c_str()));
ZapitTools::replace_char(&fname[pos]);
strcat(fname, "_");
}
pos = strlen(fname);
if(CEitManager::getInstance()->getActualEPGServiceKey(channel_id, &epgData)) {
CShortEPGData epgdata;
if(CEitManager::getInstance()->getEPGidShort(epgData.eventID, &epgdata)) {
if (!(epgdata.title.empty())) {
strcpy(&(fname[pos]), epgdata.title.c_str());
ZapitTools::replace_char(&fname[pos]);
}
}
}
pos = strlen(fname);
struct timeval tv;
gettimeofday(&tv, NULL);
strftime(&(fname[pos]), sizeof(fname) - pos - 1, "_%Y%m%d_%H%M%S", localtime(&tv.tv_sec));
pos = strlen(fname);
snprintf(&(fname[pos]), sizeof(fname) - pos - 1, "_%03d", (int) tv.tv_usec/1000);
switch (format) {
case FORMAT_PNG:
strcat(fname, ".png");
break;
default:
printf("CScreenShot::MakeFileName unsupported format %d, using jpeg\n", format);
/* fall through */
case FORMAT_JPG:
strcat(fname, ".jpg");
break;
case FORMAT_BMP:
strcat(fname, ".bmp");
break;
}
printf("CScreenShot::MakeFileName: [%s]\n", fname);
filename = std::string(fname);
}
#endif // HAVE_COOL_HARDWARE

View File

@@ -44,6 +44,7 @@ class CScreenShot
bool get_osd;
bool get_video;
bool scale_to_video;
#if !HAVE_SPARK_HARDWARE && !HAVE_DUCKBOX_HARDWARE
FILE *fd;
pthread_t scs_thread;
pthread_mutex_t thread_mutex;
@@ -61,6 +62,7 @@ class CScreenShot
static void* initThread(void *arg);
void runThread();
static void cleanupThread(void *arg);
#endif
#ifdef BOXMODEL_CS_HD2
bool mergeOsdScreen(uint32_t dx, uint32_t dy, fb_pixel_t* osdData);
@@ -75,7 +77,11 @@ class CScreenShot
void EnableVideo(bool enable) { get_video = enable; }
void EnableOSD(bool enable) { get_osd = enable; }
void ScaleToVideo(bool enable) { scale_to_video = enable; }
#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE
bool Start(const std::string custom_cmd = "");
#else
bool Start();
#endif
bool StartSync();
};

View File

@@ -25,6 +25,8 @@
#endif
#include <driver/lcdd.h>
#include <driver/framebuffer.h>
#include <system/set_threadname.h>
#include <global.h>
#include <neutrino.h>
@@ -33,19 +35,53 @@
#include <unistd.h>
//#include <math.h>
#include <sys/stat.h>
#if HAVE_SPARK_HARDWARE
#include <aotom_main.h>
#define DISPLAY_DEV "/dev/vfd"
#include <zapit/zapit.h>
#include <system/helpers.h>
static bool usb_icon = false;
static bool timer_icon = false;
#endif
#if HAVE_AZBOX_HARDWARE
#define DISPLAY_DEV "/proc/vfd"
#define LED_DEV "/proc/led"
#endif
#if HAVE_GENERIC_HARDWARE
#define DISPLAY_DEV "/dev/null"
static bool usb_icon = false;
static bool timer_icon = false;
#endif
#include <system/set_threadname.h>
#if HAVE_ARM_HARDWARE
#define DISPLAY_DEV "/dev/dbox/oled0"
#include <zapit/zapit.h>
#include <system/helpers.h>
static bool usb_icon = false;
static bool timer_icon = false;
static int proc_put(const char *path, bool state)
{
int ret, ret2;
int pfd = open(path, O_WRONLY);
char *value;
if (state)
value="1";
else
value="0";
if (pfd < 0)
return pfd;
ret = write(pfd, value, 1);
ret2 = close(pfd);
if (ret2 < 0)
return ret2;
return ret;
}
#else
static int proc_put(const char *path, bool state) {}
#endif
static char volume = 0;
//static char percent = 0;
@@ -121,8 +157,16 @@ printf("%s '%s'\n", __func__, s);
CLCD::CLCD()
{
/* do not show menu in neutrino... */
has_lcd = false;
/* do not show menu in neutrino...,at Line Display true, because there is th GLCD Menu */
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT)
{
has_lcd = true;
mode = MODE_TVRADIO;
switch_name_time_cnt = 0;
timeout_cnt = 0;
} else
has_lcd = false;
servicename = "";
thread_running = false;
}
@@ -147,6 +191,18 @@ CLCD* CLCD::getInstance()
void CLCD::wake_up()
{
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
if (atoi(g_settings.lcd_setting_dim_time.c_str()) > 0) {
timeout_cnt = atoi(g_settings.lcd_setting_dim_time.c_str());
g_settings.lcd_setting_dim_brightness > -1 ?
setBrightness(g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS]) : setPower(1);
}
else
setPower(1);
if(g_settings.lcd_info_line){
switch_name_time_cnt = g_settings.timing[SNeutrinoSettings::TIMING_INFOBAR] + 10;
}
}
}
void* CLCD::TimeThread(void *)
@@ -154,7 +210,25 @@ void* CLCD::TimeThread(void *)
set_threadname("n:boxdisplay"); /* to not confuse with TV display */
while (CLCD::getInstance()->thread_running) {
sleep(1);
CLCD::getInstance()->showTime();
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
struct stat buf;
if (stat("/tmp/vfd.locked", &buf) == -1) {
CLCD::getInstance()->showTime();
CLCD::getInstance()->count_down();
} else
CLCD::getInstance()->wake_up();
} else
CLCD::getInstance()->showTime();
#if 0
/* hack, just if we missed the blit() somewhere
* this will update the framebuffer once per second */
if (getenv("SPARK_NOBLIT") == NULL) {
CFrameBuffer *fb = CFrameBuffer::getInstance();
/* plugin start locks the framebuffer... */
if (!fb->Locked())
fb->blit();
}
#endif
}
return NULL;
}
@@ -172,6 +246,11 @@ void CLCD::init(const char *, const char *, const char *, const char *, const ch
void CLCD::setlcdparameter(void)
{
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
last_toggle_state_power = g_settings.lcd_setting[SNeutrinoSettings::LCD_POWER];
setlcdparameter((mode == MODE_STANDBY) ? g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] : (mode == MODE_SHUTDOWN) ? g_settings.lcd_setting[SNeutrinoSettings::LCD_DEEPSTANDBY_BRIGHTNESS] : g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS],
last_toggle_state_power);
}
}
void CLCD::showServicename(std::string name, bool)
@@ -179,10 +258,10 @@ void CLCD::showServicename(std::string name, bool)
if (g_info.hw_caps->display_type == HW_DISPLAY_LED_NUM)
return;
servicename = name;
if (mode != MODE_TVRADIO)
if (mode != MODE_TVRADIO && mode != MODE_AUDIO)
return;
replace_umlauts(servicename);
strncpy(display_text, servicename.c_str(), sizeof(display_text) - 1);
replace_umlauts(name);
strncpy(display_text, name.c_str(), sizeof(display_text) - 1);
display_text[sizeof(display_text) - 1] = '\0';
upd_display = true;
}
@@ -197,7 +276,7 @@ void CLCD::setled(int red, int green)
if (fd < 0)
return;
// printf("%s red:%d green:%d\n", __func__, red, green);
printf("%s red:%d green:%d\n", __func__, red, green);
for (i = 0; i < 2; i++)
{
@@ -307,9 +386,14 @@ void CLCD::showTime(bool force)
blink = !blink;
if (led_g)
green = blink;
if (led_r || led_g)
setled(red, green);
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
if (led_r)
SetIcons(SPARK_REC1, red);
if (led_g)
SetIcons(SPARK_PLAY, green);
} else
if (led_r || led_g)
setled(red, green);
}
void CLCD::showRCLock(int)
@@ -332,10 +416,15 @@ void CLCD::showVolume(const char vol, const bool update)
volume = 100;
if (muted)
{
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT)
SetIcons(SPARK_MUTE, 1);
strcpy(s, mutestr[type]);
else
} else {
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT)
SetIcons(SPARK_MUTE, 0);
sprintf(s, vol_fmt[type], volume);
}
display(s);
vol_active = true;
}
@@ -355,18 +444,18 @@ void CLCD::showMenuText(const int, const char *text, const int, const bool)
upd_display = true;
}
void CLCD::showAudioTrack(const std::string &, const std::string & /*title*/, const std::string &)
void CLCD::showAudioTrack(const std::string &, const std::string & title, const std::string &)
{
if (mode != MODE_AUDIO)
return;
// ShowText(title.c_str());
ShowText(title.c_str());
}
void CLCD::showAudioPlayMode(AUDIOMODES)
{
}
void CLCD::showAudioProgress(const char)
void CLCD::showAudioProgress(const char, bool)
{
}
@@ -376,7 +465,10 @@ void CLCD::setMode(const MODES m, const char * const)
switch (m) {
case MODE_TVRADIO:
setled(0, 0);
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT)
SetIcons(SPARK_CYCLE, 0);
else
setled(0, 0);
showclock = true;
power = true;
if (g_info.hw_caps->display_type != HW_DISPLAY_LED_NUM) {
@@ -388,11 +480,13 @@ void CLCD::setMode(const MODES m, const char * const)
break;
case MODE_SHUTDOWN:
showclock = false;
showTime();
Clear();
break;
case MODE_STANDBY:
setled(0, 1);
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT)
SetIcons(SPARK_CYCLE, 1);
else
setled(0, 1);
showclock = true;
showTime(true);
break;
@@ -402,22 +496,80 @@ void CLCD::setMode(const MODES m, const char * const)
}
}
void CLCD::setBrightness(int)
void CLCD::setBrightness(int dimm)
{
#if HAVE_SPARK_HARDWARE
switch(dimm) {
case 15:
case 14: dimm = 7; break;
case 13:
case 12: dimm = 6; break;
case 11:
case 10: dimm = 5; break;
case 9:
case 8: dimm = 4; break;
case 7:
case 6: dimm = 3; break;
case 5:
case 4: dimm = 2; break;
case 3:
case 2: dimm = 1; break;
case 1:
case 0: dimm = 0; break;
}
struct aotom_ioctl_data d;
if (dimm < 0 || dimm > 7)
return;
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
int fd = dev_open();
if (fd < 0)
return;
d.u.brightness.level = dimm;
if (ioctl(fd, VFDBRIGHTNESS, &d) < 0)
fprintf(stderr, "[neutrino] %s set brightness VFDBRIGHTNESS: %m\n", __func__);
close(fd);
}
#elif HAVE_ARM_HARDWARE
std::string value = to_string(255/15*dimm);
int pfd = open("/proc/stb/lcd/oled_brightness", O_WRONLY);
if (pfd)
write(pfd, value.c_str(), value.length());
close(pfd);
#endif
}
int CLCD::getBrightness()
{
return 0;
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
if(g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS] > 15)
g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS] = 15;
return g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS];
} else
return 0;
}
void CLCD::setBrightnessStandby(int)
void CLCD::setBrightnessStandby(int bright)
{
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] = bright;
setlcdparameter();
}
}
int CLCD::getBrightnessStandby()
{
return 0;
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
if(g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] > 15)
g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] = 15;
return g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS];
} else
return 0;
}
void CLCD::setPower(int)
@@ -426,7 +578,10 @@ void CLCD::setPower(int)
int CLCD::getPower()
{
return 0;
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT)
return g_settings.lcd_setting[SNeutrinoSettings::LCD_POWER];
else
return 0;
}
void CLCD::togglePower(void)
@@ -436,6 +591,11 @@ void CLCD::togglePower(void)
Clear();
else
showTime(true);
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
last_toggle_state_power = 1 - last_toggle_state_power;
setlcdparameter((mode == MODE_STANDBY) ? g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] : (mode == MODE_SHUTDOWN) ? g_settings.lcd_setting[SNeutrinoSettings::LCD_DEEPSTANDBY_BRIGHTNESS] : g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS],
last_toggle_state_power);
}
}
void CLCD::setMuted(bool mu)
@@ -471,6 +631,10 @@ void CLCD::Clear()
if(ret < 0)
perror("[neutrino] spark_led Clear() VFDDISPLAYCLR");
close(fd);
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
SetIcons(SPARK_ALL, false);
SetIcons(SPARK_CLOCK, timer_icon);
}
servicename.clear();
printf("spark_led:%s\n", __func__);
}
@@ -481,17 +645,186 @@ void CLCD::Clear()
}
#endif
void CLCD::count_down() {
if (timeout_cnt > 0) {
timeout_cnt--;
if (timeout_cnt == 0 ) {
if (g_settings.lcd_setting_dim_brightness > -1) {
// save lcd brightness, setBrightness() changes global setting
int b = g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS];
setBrightness(g_settings.lcd_setting_dim_brightness);
g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS] = b;
} else {
setPower(0);
}
}
}
if (g_settings.lcd_info_line && switch_name_time_cnt > 0) {
switch_name_time_cnt--;
if (switch_name_time_cnt == 0) {
if (g_settings.lcd_setting_dim_brightness > -1) {
CLCD::getInstance()->showTime(true);
}
}
}
}
void CLCD::setlcdparameter(int dimm, const int power)
{
if(dimm < 0)
dimm = 0;
else if(dimm > 15)
dimm = 15;
if(!power)
dimm = 0;
if(brightness == dimm)
return;
brightness = dimm;
printf("CLCD::setlcdparameter dimm %d power %d\n", dimm, power);
setBrightness(dimm);
}
void CLCD::SetIcons(int icon, bool on)
{
#if HAVE_SPARK_HARDWARE
struct aotom_ioctl_data d;
d.u.icon.icon_nr = icon;
if (on == true)
d.u.icon.on = 1;
else
d.u.icon.on = 0;
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
int fd = dev_open();
if (fd < 0)
return;
if (ioctl(fd, VFDICONDISPLAYONOFF, &d) <0)
perror("[neutrino] SetIcons() VFDICONDISPLAYONOFF");
close(fd);
}
#else
//nothing
#endif
}
void CLCD::ShowDiskLevel()
{
#if !HAVE_GENERIC_HARDWARE && !HAVE_ARM_HARDWARE
int hdd_icons[9] ={24, 23, 21, 20, 19, 18, 17, 16, 22};
int percent, digits, i, j;
uint64_t t, u;
if (get_fs_usage(g_settings.network_nfs_recordingdir.c_str(), t, u))
{
SetIcons(SPARK_HDD, true);
percent = (int)((u * 1000ULL) / t + 60);
digits = percent / 125;
if (percent > 1050)
digits = 9;
//printf("HDD Fuell = %d Digits = %d\n", percent, digits);
if (digits > 0)
{
for (i=0; i<digits; i++)
SetIcons(hdd_icons[i], true);
for (j=i; j < 9; j++)
SetIcons(hdd_icons[j], false);
}
}
else
{
SetIcons(SPARK_HDD, false);
}
#endif
}
void CLCD::UpdateIcons()
{
#if HAVE_SPARK_HARDWARE
CFrontend *aktFE = CFEManager::getInstance()->getLiveFE();
SetIcons(SPARK_SAT, aktFE->isSat(aktFE->getCurrentDeliverySystem()));
SetIcons(SPARK_CAB, aktFE->isCable(aktFE->getCurrentDeliverySystem()));
SetIcons(SPARK_TER, aktFE->isTerr(aktFE->getCurrentDeliverySystem()));
ShowDiskLevel();
SetIcons(SPARK_USB, usb_icon);
#endif
#if HAVE_SPARK_HARDWARE || HAVE_ARM_HARDWARE
CZapitChannel * chan = CZapit::getInstance()->GetCurrentChannel();
if (chan)
{
ShowIcon(FP_ICON_HD,chan->isHD());
ShowIcon(FP_ICON_LOCK,!chan->camap.empty());
if (chan->getAudioChannel() != NULL)
{
ShowIcon(FP_ICON_DD, chan->getAudioChannel()->audioChannelType == CZapitAudioChannel::AC3);
SetIcons(SPARK_MP3, chan->getAudioChannel()->audioChannelType == CZapitAudioChannel::MPEG);
}
}
#endif
}
void CLCD::ShowIcon(fp_icon i, bool on)
{
switch (i)
{
case FP_ICON_CAM1:
led_r = on;
setled(led_r, -1); /* switch instant on / switch off if disabling */
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
SetIcons(SPARK_REC1, on);
proc_put("/proc/stb/lcd/symbol_recording",on);}
else
setled(led_r, -1); /* switch instant on / switch off if disabling */
break;
case FP_ICON_PLAY:
led_g = on;
setled(-1, led_g);
if (g_info.hw_caps->display_type == HW_DISPLAY_LINE_TEXT) {
SetIcons(SPARK_PLAY, on);
proc_put("/proc/stb/lcd/symbol_playback",on);}
else
setled(-1, led_g);
break;
case FP_ICON_USB:
usb_icon = on;
SetIcons(SPARK_USB, on);
proc_put("/proc/stb/lcd/symbol_usb",on);
break;
case FP_ICON_HDD:
SetIcons(SPARK_HDD, on);
proc_put("/proc/stb/lcd/symbol_hdd",on);
break;
case FP_ICON_PAUSE:
SetIcons(SPARK_PAUSE, on);
break;
case FP_ICON_FF:
SetIcons(SPARK_PLAY_FASTFORWARD, on);
break;
case FP_ICON_FR:
SetIcons(SPARK_PLAY_FASTBACKWARD, on);
break;
case FP_ICON_DD:
SetIcons(SPARK_DD, on);
SetIcons(SPARK_AC3, on);
break;
case FP_ICON_LOCK:
SetIcons(SPARK_CA, on);
proc_put("/proc/stb/lcd/symbol_scrambled",on);
break;
case FP_ICON_RADIO:
SetIcons(SPARK_AUDIO, on);
break;
case FP_ICON_TV:
SetIcons(SPARK_TVMODE_LOG, on);
proc_put("/proc/stb/lcd/symbol_tv",on);
break;
case FP_ICON_HD:
SetIcons(SPARK_DOUBLESCREEN, on);
break;
case FP_ICON_CLOCK:
timer_icon = on;
SetIcons(SPARK_CLOCK, on);
proc_put("/proc/stb/lcd/symbol_timeshift",on);
break;
default:
break;

View File

@@ -47,8 +47,222 @@
#include <cs_api.h>
extern CRemoteControl * g_RemoteControl; /* neutrino.cpp */
#ifdef HAVE_DUCKBOX_HARDWARE
#include <zapit/zapit.h>
#include <stropts.h>
#define VFD_DEVICE "/dev/vfd"
#if defined (BOXMODEL_OCTAGON1008) || defined (BOXMODEL_TF7700)
#define VFDLENGTH 8
#elif defined (BOXMODEL_FORTIS_HDBOX) || defined (BOXMODEL_ATEVIO7500)
#define VFDLENGTH 12
#elif defined (BOXMODEL_HS7810A) || defined (BOXMODEL_HS7119) || defined (BOXMODEL_HS7819) || defined (BOXMODEL_CUBEREVO_250HD) || defined (BOXMODEL_IPBOX55)
#define VFDLENGTH 4
#elif defined (BOXMODEL_HS7110)
#define VFDLENGTH 0
#elif defined (BOXMODEL_IPBOX9900) || defined (BOXMODEL_IPBOX99)
#define VFDLENGTH 14
#else
#define VFDLENGTH 16
#endif
#define SCROLL_TIME 100000
bool invert = false;
bool blocked = false;
int blocked_counter = 0;
int file_vfd = -1;
bool active_icon[16] = { false };
pthread_t vfd_scrollText;
struct vfd_ioctl_data {
unsigned char start;
unsigned char data[64];
unsigned char length;
};
static void write_to_vfd(unsigned int DevType, struct vfd_ioctl_data * data, bool force = false)
{
int file_closed = 0;
if (blocked) {
if (file_vfd > -1) {
blocked_counter++;
usleep(SCROLL_TIME);
} else {
blocked = false;
}
}
if (blocked_counter > 10) {
force = true;
blocked_counter = 0;
}
// printf("[CVFD] - blocked_counter=%i, blocked=%i, force=%i\n", blocked, blocked_counter, force);
if (force || !blocked) {
if (blocked) {
if (file_vfd > -1) {
file_closed = close(file_vfd);
file_vfd = -1;
}
}
blocked = true;
if (file_vfd == -1)
file_vfd = open (VFD_DEVICE, O_RDWR);
if (file_vfd > -1) {
ioctl(file_vfd, DevType, data);
ioctl(file_vfd, I_FLUSH, FLUSHRW);
file_closed = close(file_vfd);
file_vfd = -1;
}
blocked = false;
blocked_counter = 0;
}
}
#if defined (BOXMODEL_UFS910) || defined (BOXMODEL_UFS922)
static void writeCG (unsigned char adress, unsigned char pixeldata[5])
{
struct vfd_ioctl_data data;
data.start = adress & 0x07;
data.data[0] = pixeldata[0];
data.data[1] = pixeldata[1];
data.data[2] = pixeldata[2];
data.data[3] = pixeldata[3];
data.data[4] = pixeldata[4];
data.length = 5;
write_to_vfd(VFDWRITECGRAM, &data);
return;
}
#endif
static void ShowNormalText(char * str, bool fromScrollThread = false)
{
if (blocked)
{
printf("[CVFD] - blocked\n");
usleep(SCROLL_TIME);
}
int ws = 0; // needed whitespace for centering
struct vfd_ioctl_data data;
if (!fromScrollThread)
{
if(vfd_scrollText != 0)
{
pthread_cancel(vfd_scrollText);
pthread_join(vfd_scrollText, NULL);
vfd_scrollText = 0;
}
}
if ((strlen(str) > VFDLENGTH && !fromScrollThread) && (g_settings.lcd_vfd_scroll >= 1))
{
CVFD::getInstance()->ShowScrollText(str);
return;
}
if (strlen(str) < VFDLENGTH && VFDLENGTH > 7) // do not center on small displays
ws = (VFDLENGTH-strlen(str))/2;
else
ws = 0;
memset(data.data, ' ', 63);
if (!fromScrollThread)
{
memcpy (data.data+ws, str, VFDLENGTH-ws);
data.start = 0;
if ((strlen(str) % 2) == 1 && VFDLENGTH > 7) // do not center on small displays
data.length = VFDLENGTH-ws-1;
else
data.length = VFDLENGTH-ws;
}
else
{
memcpy ( data.data, str, VFDLENGTH);
data.start = 0;
data.length = VFDLENGTH;
}
write_to_vfd(VFDDISPLAYCHARS, &data);
return;
}
void CVFD::ShowScrollText(char *str)
{
printf("CVFD::ShowScrollText: [%s]\n", str);
if (blocked)
{
printf("[CVFD] - blocked\n");
usleep(SCROLL_TIME);
}
//stop scrolltextthread
if(vfd_scrollText != 0)
{
pthread_cancel(vfd_scrollText);
pthread_join(vfd_scrollText, NULL);
vfd_scrollText = 0;
scrollstr = (char *)"";
}
//scroll text thread
scrollstr = str;
pthread_create(&vfd_scrollText, NULL, ThreadScrollText, (void *)scrollstr);
}
void* CVFD::ThreadScrollText(void * arg)
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
int i;
char *str = (char *)arg;
int len = strlen(str);
char out[VFDLENGTH+1];
char buf[VFDLENGTH+65];
memset(out, 0, VFDLENGTH+1);
int retries = g_settings.lcd_vfd_scroll;
if (len > VFDLENGTH)
{
printf("CVFD::ThreadScrollText: [%s], length %d\n", str, len);
memset(buf, ' ', (len + VFDLENGTH));
memcpy(buf, str, len);
while(retries--)
{
// usleep(SCROLL_TIME);
for (i = 0; i <= (len-1); i++)
{
// scroll text until end
memcpy(out, buf+i, VFDLENGTH);
ShowNormalText(out,true);
usleep(SCROLL_TIME);
}
}
}
memcpy(out, str, VFDLENGTH); // display first VFDLENGTH chars after scrolling
ShowNormalText(out,true);
pthread_exit(0);
return NULL;
}
#endif
CVFD::CVFD()
{
text[0] = 0;
g_str[0] = 0;
clearClock = 0;
mode = MODE_TVRADIO;
switch_name_time_cnt = 0;
timeout_cnt = 0;
service_number = -1;
#ifdef VFD_UPDATE
m_fileList = NULL;
m_fileListPos = 0;
@@ -64,12 +278,16 @@ CVFD::CVFD()
has_lcd = true;
has_led_segment = false;
#if !HAVE_DUCKBOX_HARDWARE
fd = open("/dev/display", O_RDONLY);
if(fd < 0) {
perror("/dev/display");
has_lcd = false;
has_led_segment = false;
}
#else
fd = 1;
#endif
#ifdef BOXMODEL_CS_HD2
if (fd >= 0) {
@@ -103,21 +321,16 @@ CVFD::CVFD()
support_text = true;
support_numbers = true;
#endif
text.clear();
clearClock = 0;
mode = MODE_TVRADIO;
switch_name_time_cnt = 0;
timeout_cnt = 0;
service_number = -1;
}
CVFD::~CVFD()
{
#if !HAVE_DUCKBOX_HARDWARE
if(fd > 0){
close(fd);
fd = -1;
}
#endif
}
CVFD* CVFD::getInstance()
@@ -154,7 +367,7 @@ void CVFD::count_down() {
}
void CVFD::wake_up() {
if(fd < 0) return;
if(fd < 0) return;
if (atoi(g_settings.lcd_setting_dim_time.c_str()) > 0) {
timeout_cnt = atoi(g_settings.lcd_setting_dim_time.c_str());
@@ -166,6 +379,9 @@ void CVFD::wake_up() {
if(g_settings.lcd_info_line){
switch_name_time_cnt = g_settings.timing[SNeutrinoSettings::TIMING_INFOBAR] + 10;
}
#if defined (BOXMODEL_OCTAGON1008)
ShowIcon(ICON_COLON2, false);
#endif
}
@@ -214,9 +430,68 @@ void CVFD::setlcdparameter(int dimm, const int power)
brightness = dimm;
printf("CVFD::setlcdparameter dimm %d power %d\n", dimm, power);
#if !HAVE_DUCKBOX_HARDWARE
int ret = ioctl(fd, IOC_FP_SET_BRIGHT, dimm);
if(ret < 0)
perror("IOC_FP_SET_BRIGHT");
#else
// Brightness
struct vfd_ioctl_data data;
#if !defined (BOXMODEL_HS7810A) && !defined (BOXMODEL_HS7119) && !defined (BOXMODEL_HS7819)
memset(&data, 0, sizeof(struct vfd_ioctl_data));
data.start = brightness & 0x07;
data.length = 0;
write_to_vfd(VFDBRIGHTNESS, &data);
#endif
#if defined (BOXMODEL_FORTIS_HDBOX) || defined (BOXMODEL_ATEVIO7500)
usleep(100000);
memset(&data, 0, sizeof(struct vfd_ioctl_data));
data.start = 0;
data.length = 5;
if (power) {
data.data[0] = 0x01; // red led
}
else
{
data.data[0] = 0xf2; // cross plus blue led
}
data.start = 0;
data.data[4] = 0; // off
data.length = 5;
write_to_vfd(VFDPWRLED, &data);
usleep(100000);
memset(&data, 0, sizeof(struct vfd_ioctl_data));
data.start = 0;
data.length = 5;
if (power) {
data.data[0] = 0xf2; // cross plus blue led
}
else
{
data.data[0] = 0x01; // red led
}
data.start = 0;
data.data[4] = brightness*2;
data.length = 5;
write_to_vfd(VFDPWRLED, &data);
#elif defined (BOXMODEL_HS7810A) || defined (BOXMODEL_HS7819)
memset(&data, 0, sizeof(struct vfd_ioctl_data));
data.start = 0;
data.data[0] = 0x02; // logo
data.data[4] = (brightness & 0x07);
data.length = 5;
write_to_vfd(VFDPWRLED, &data);
#elif !defined (BOXMODEL_UFS912) && !defined (BOXMODEL_UFS913) && !defined (BOXMODEL_OCTAGON1008)
// Power on/off
if (power) {
data.start = 0x01;
} else {
data.start = 0x00;
}
data.length = 0;
write_to_vfd(VFDDISPLAYWRITEONOFF, &data, true);
#endif
#endif
}
void CVFD::setlcdparameter(void)
@@ -227,6 +502,7 @@ void CVFD::setlcdparameter(void)
last_toggle_state_power);
}
#if !HAVE_DUCKBOX_HARDWARE
void CVFD::setled(int led1, int led2)
{
int ret = -1;
@@ -324,6 +600,7 @@ void CVFD::setled(void)
}
setled(led1, led2);
}
#endif
void CVFD::showServicename(const std::string & name, int number) // UTF-8
{
@@ -367,6 +644,24 @@ void CVFD::showTime(bool force)
if(force || ( switch_name_time_cnt == 0 && ((hour != t->tm_hour) || (minute != t->tm_min))) ) {
hour = t->tm_hour;
minute = t->tm_min;
#if !defined (BOXMODEL_HS7810A) && !defined (BOXMODEL_HS7819)
#if defined (BOXMODEL_OCTAGON1008)
ShowIcon(ICON_COLON2, true);
#elif defined (BOXMODEL_OCTAGON1008) || defined (BOXMODEL_HS7119) || defined (BOXMODEL_CUBEREVO_250HD)
strftime(timestr, 5, "%H%M", t);
#else
strftime(timestr, 6, "%H:%M", t);
#endif
ShowText(timestr);
#else //HS7810A or HS7819, string should not scroll
strftime(timestr, 6, "%H:%M", t);
struct vfd_ioctl_data data;
memset(data.data, ' ', 6);
memcpy (data.data, timestr, 6);
data.start = 0;
data.length = 5;
write_to_vfd(VFDDISPLAYCHARS, &data);
#endif
if (support_text) {
strftime(timestr, 20, "%H:%M", t);
ShowText(timestr);
@@ -386,24 +681,44 @@ void CVFD::showTime(bool force)
clearClock = 0;
if(has_lcd)
ShowIcon(FP_ICON_CAM1, false);
#if !HAVE_DUCKBOX_HARDWARE
setled(false);//off
#endif
} else {
clearClock = 1;
if(has_lcd)
ShowIcon(FP_ICON_CAM1, true);
#if !HAVE_DUCKBOX_HARDWARE
setled(true);//on
#endif
}
} else if(clearClock || (recstatus != tmp_recstatus)) { // in case icon ON after record stopped
clearClock = 0;
if(has_lcd)
ShowIcon(FP_ICON_CAM1, false);
#if !HAVE_DUCKBOX_HARDWARE
setled();
#endif
}
recstatus = tmp_recstatus;
}
#if HAVE_DUCKBOX_HARDWARE
void CVFD::UpdateIcons()
{
CZapitChannel * chan = CZapit::getInstance()->GetCurrentChannel();
if (chan)
{
ShowIcon(FP_ICON_HD,chan->isHD());
ShowIcon(FP_ICON_LOCK,!chan->camap.empty());
if (chan->getAudioChannel() != NULL)
ShowIcon(FP_ICON_DD, chan->getAudioChannel()->audioChannelType == CZapitAudioChannel::AC3);
}
}
#endif
void CVFD::showRCLock(int duration)
{
if (!has_lcd || !g_settings.lcd_notify_rclock)
@@ -435,8 +750,75 @@ void CVFD::showVolume(const char vol, const bool force_update)
if (g_settings.lcd_setting[SNeutrinoSettings::LCD_SHOW_VOLUME] == 1) {
wake_up();
#if HAVE_DUCKBOX_HARDWARE
int pp = (int) round((double) vol / (double) 2);
if(oldpp != pp)
{
#if defined (BOXMODEL_UFS910) || defined (BOXMODEL_UFS922)
int i;
unsigned char speaker[5] = {0x1C, 0x1C, 0x1C, 0x3E, 0x7F}; // speaker symbol
writeCG(0, speaker);
int j = pp / 5;
// v-lines 0-5 = {0x10,0x11,0x12,0x13,0x14,0x15}
char c0[1] = {0x5F};
char c1[1] = {0x11};
char c2[1] = {0x12};
char c3[1] = {0x13};
char c4[1] = {0x14};
char c5[1] = {0x15};
char VolumeBar[17];
memset (VolumeBar, 0, sizeof(VolumeBar));
char act[2] = {0x01, 0x20};
strncat(VolumeBar, act, 2);
for(i=1; i <= j; i++)
{
strncat(VolumeBar, c5, 1);
}
i = pp % 5;
switch (i)
{
case 1:
strncat(VolumeBar, c1, 1);
break;
case 2:
strncat(VolumeBar, c2, 1);
break;
case 3:
strncat(VolumeBar, c3, 1);
break;
case 4:
strncat(VolumeBar, c4, 1);
break;
}
//dprintf(DEBUG_DEBUG,"CVFD::showVolume: vol %d - pp %d - fullblocks %d - mod %d - %s\n", vol, pp, j, i, VolumeBar);
if (strlen(VolumeBar) < 12) {
for (int a=strlen(VolumeBar); a < 12; a++)
strncat(VolumeBar, c0, 1);
}
ShowText(VolumeBar);
#elif defined (BOXMODEL_TF7700)
char vol_chr[64] = "";
snprintf(vol_chr, sizeof(vol_chr)-1, "VOL: %d%%", (int)vol);
ShowText(vol_chr);
#elif defined (BOXMODEL_OCTAGON1008)
char vol_chr[64] = "";
snprintf(vol_chr, sizeof(vol_chr)-1, "VOL=%3d", (int)vol);
ShowText(vol_chr);
#elif defined (BOXMODEL_HS7119) || defined (BOXMODEL_HS7810A) || defined (BOXMODEL_HS7819) || defined (BOXMODEL_CUBEREVO_250HD) || defined (BOXMODEL_IPBOX55)
char vol_chr[64] = "";
snprintf(vol_chr, sizeof(vol_chr)-1, "v%3d", (int)vol);
ShowText(vol_chr);
#elif defined (BOXMODEL_FORTIS_HDBOX) || defined (BOXMODEL_ATEVIO7500) || defined (BOXMODEL_UFS912) || defined (BOXMODEL_UFS913) || defined (BOXMODEL_CUBEREVO) || defined (BOXMODEL_CUBEREVO_MINI) || defined (BOXMODEL_CUBEREVO_MINI2) || defined (BOXMODEL_CUBEREVO_2000HD) || defined (BOXMODEL_CUBEREVO_3000HD) || defined (BOXMODEL_IPBOX9900) || defined (BOXMODEL_IPBOX99)
char vol_chr[64] = "";
snprintf(vol_chr, sizeof(vol_chr)-1, "Volume: %d%%", (int)vol);
ShowText(vol_chr);
#endif
oldpp = pp;
}
#else
ShowIcon(FP_ICON_FRAME, true);
int pp = (vol * 8 + 50) / 100;
int pp = (int) round((double) vol * (double) 8 / (double) 100);
if(pp > 8) pp = 8;
if(force_update || oldpp != pp) {
@@ -453,11 +835,15 @@ printf("CVFD::showVolume: %d, bar %d\n", (int) vol, pp);
}
oldpp = pp;
}
#endif
}
}
void CVFD::showPercentOver(const unsigned char perc, const bool /*perform_update*/, const MODES origin)
{
#if HAVE_DUCKBOX_HARDWARE
return;
#else
static int ppold = 0;
if(!has_lcd) return;
@@ -477,7 +863,7 @@ void CVFD::showPercentOver(const unsigned char perc, const bool /*perform_update
if(perc == 255)
pp = 0;
else
pp = (perc * 8 + 50) / 100;
pp = (int) round((double) perc * (double) 8 / (double) 100);
if(pp > 8) pp = 8;
if(pp != ppold) {
@@ -495,6 +881,7 @@ void CVFD::showPercentOver(const unsigned char perc, const bool /*perform_update
ppold = pp;
}
}
#endif
}
void CVFD::showMenuText(const int /*position*/, const char * ptext, const int /*highlight*/, const bool /*utf_encoded*/)
@@ -533,18 +920,38 @@ void CVFD::showAudioPlayMode(AUDIOMODES m)
case AUDIO_MODE_PLAY:
ShowIcon(FP_ICON_PLAY, true);
ShowIcon(FP_ICON_PAUSE, false);
#ifdef HAVE_DUCKBOX_HARDWARE
ShowIcon(FP_ICON_FF, false);
ShowIcon(FP_ICON_FR, false);
#endif
break;
case AUDIO_MODE_STOP:
ShowIcon(FP_ICON_PLAY, false);
ShowIcon(FP_ICON_PAUSE, false);
#ifdef HAVE_DUCKBOX_HARDWARE
ShowIcon(FP_ICON_FF, false);
ShowIcon(FP_ICON_FR, false);
#endif
break;
case AUDIO_MODE_PAUSE:
ShowIcon(FP_ICON_PLAY, false);
ShowIcon(FP_ICON_PAUSE, true);
#ifdef HAVE_DUCKBOX_HARDWARE
ShowIcon(FP_ICON_FF, false);
ShowIcon(FP_ICON_FR, false);
#endif
break;
case AUDIO_MODE_FF:
#ifdef HAVE_DUCKBOX_HARDWARE
ShowIcon(FP_ICON_FF, true);
ShowIcon(FP_ICON_FR, false);
#endif
break;
case AUDIO_MODE_REV:
#ifdef HAVE_DUCKBOX_HARDWARE
ShowIcon(FP_ICON_FF, false);
ShowIcon(FP_ICON_FR, true);
#endif
break;
}
wake_up();
@@ -632,6 +1039,11 @@ void CVFD::setMode(const MODES m, const char * const title)
ShowIcon(FP_ICON_COL1, true);
ShowIcon(FP_ICON_COL2, true);
#endif
#if ! HAVE_COOL_HARDWARE
ClearIcons();
#endif
ShowIcon(FP_ICON_USB, false);
ShowIcon(FP_ICON_HDD, false);
showclock = true;
showTime(true); /* "showclock = true;" implies that "showTime();" does a "displayUpdate();" */
/* "showTime()" clears the whole lcd in MODE_STANDBY */
@@ -659,7 +1071,9 @@ void CVFD::setMode(const MODES m, const char * const title)
#endif // VFD_UPDATE
}
wake_up();
#if !HAVE_DUCKBOX_HARDWARE
setled();
#endif
}
void CVFD::setBrightness(int bright)
@@ -673,8 +1087,13 @@ void CVFD::setBrightness(int bright)
int CVFD::getBrightness()
{
//FIXME for old neutrino.conf
#if defined (BOXMODEL_OCTAGON1008) || defined (BOXMODEL_FORTIS_HDBOX) || defined (BOXMODEL_ATEVIO7500)
if(g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS] > 7)
g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS] = 7;
#else
if(g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS] > 15)
g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS] = 15;
#endif
return g_settings.lcd_setting[SNeutrinoSettings::LCD_BRIGHTNESS];
}
@@ -690,8 +1109,13 @@ void CVFD::setBrightnessStandby(int bright)
int CVFD::getBrightnessStandby()
{
//FIXME for old neutrino.conf
#if defined (BOXMODEL_OCTAGON1008) || defined (BOXMODEL_FORTIS_HDBOX) || defined (BOXMODEL_ATEVIO7500)
if(g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] > 7)
g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] = 7;
#else
if(g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] > 15)
g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS] = 15;
#endif
return g_settings.lcd_setting[SNeutrinoSettings::LCD_STANDBY_BRIGHTNESS];
}
@@ -706,8 +1130,13 @@ void CVFD::setBrightnessDeepStandby(int bright)
int CVFD::getBrightnessDeepStandby()
{
//FIXME for old neutrino.conf
#if defined (BOXMODEL_OCTAGON1008) || defined (BOXMODEL_FORTIS_HDBOX) || defined (BOXMODEL_ATEVIO7500)
if(g_settings.lcd_setting[SNeutrinoSettings::LCD_DEEPSTANDBY_BRIGHTNESS] > 7)
g_settings.lcd_setting[SNeutrinoSettings::LCD_DEEPSTANDBY_BRIGHTNESS] = 7;
#else
if(g_settings.lcd_setting[SNeutrinoSettings::LCD_DEEPSTANDBY_BRIGHTNESS] > 15)
g_settings.lcd_setting[SNeutrinoSettings::LCD_DEEPSTANDBY_BRIGHTNESS] = 15;
#endif
return g_settings.lcd_setting[SNeutrinoSettings::LCD_DEEPSTANDBY_BRIGHTNESS];
}
@@ -765,39 +1194,122 @@ void CVFD::Unlock()
void CVFD::Clear()
{
if(fd < 0) return;
#if !HAVE_DUCKBOX_HARDWARE
int ret = ioctl(fd, IOC_FP_CLEAR_ALL, 0);
if(ret < 0)
perror("IOC_FP_SET_TEXT");
else
text.clear();
text[0] = 0;
#else
#if defined (BOXMODEL_HS7810A) || defined (BOXMODEL_HS7119) || defined (BOXMODEL_HS7819) || defined (BOXMODEL_CUBEREVO_250HD) || defined (BOXMODEL_IPBOX55)
ShowText(" ");
#elif defined (BOXMODEL_OCTAGON1008) || defined (BOXMODEL_TF7700)
ShowText(" ");
#elif defined (BOXMODEL_FORTIS_HDBOX) || defined (BOXMODEL_ATEVIO7500)
ShowText(" ");
#elif defined (BOXMODEL_IPBOX9900) || defined (BOXMODEL_IPBOX99)
ShowText(" ");
#elif !defined (BOXMODEL_HS7110)
ShowText(" ");
#endif
#endif
}
void CVFD::ShowIcon(fp_icon icon, bool show)
{
#if !HAVE_DUCKBOX_HARDWARE
if(!has_lcd || fd < 0) return;
//printf("CVFD::ShowIcon %s %x\n", show ? "show" : "hide", (int) icon);
int ret = ioctl(fd, show ? IOC_FP_SET_ICON : IOC_FP_CLEAR_ICON, icon);
if(ret < 0)
perror(show ? "IOC_FP_SET_ICON" : "IOC_FP_CLEAR_ICON");
#else
#if defined (BOXMODEL_ATEVIO7500) || defined (BOXMODEL_HS7110) || defined (BOXMODEL_HS7810A) || defined (BOXMODEL_HS7119) || defined (BOXMODEL_HS7819)
return;
#endif
if (icon == 0)
return;
if (active_icon[icon & 0x0F] == show)
return;
else
active_icon[icon & 0x0F] = show;
//printf("CVFD::ShowIcon %s %x\n", show ? "show" : "hide", (int) icon);
struct vfd_ioctl_data data;
memset(&data, 0, sizeof(struct vfd_ioctl_data));
data.start = 0x00;
data.data[0] = icon;
data.data[4] = show;
data.length = 5;
write_to_vfd(VFDICONDISPLAYONOFF, &data);
return;
#endif
}
#ifdef HAVE_DUCKBOX_HARDWARE
void CVFD::ClearIcons()
{
#if defined (BOXMODEL_ATEVIO7500) || defined (BOXMODEL_HS7110) || defined (BOXMODEL_HS7810A) || defined (BOXMODEL_HS7119) || defined (BOXMODEL_HS7819)
return;
#endif
for (int id = 0x10; id < FP_ICON_MAX; id++) {
#if defined (BOXMODEL_OCTAGON1008)
if (id != FP_ICON_USB && id != FP_ICON_HDD)
#elif defined(BOXMODEL_FORTIS_HDBOX) || defined (BOXMODEL_TF7700)
if (id != FP_ICON_USB)
#else
if (id != 0x10 && id != 0x12)
#endif
ShowIcon((fp_icon)id, false);
}
return;
}
void CVFD::ShowText(const char * str)
{
memset(g_str, 0, sizeof(g_str));
memcpy(g_str, str, sizeof(g_str)-1);
int i = strlen(str);
if (i > 63) {
g_str[60] = '.';
g_str[61] = '.';
g_str[62] = '.';
g_str[63] = '\0';
i = 63;
}
ShowNormalText(g_str, false);
}
void CVFD::repaintIcons()
{
char * model = g_info.hw_caps->boxname;
if(strstr(model, "ufs912") || strstr(model, "ufs913"))
{
bool tmp_icon[16] = {false};
printf("VFD repaint icons boxmodel: %s\n", model);
for (int i = 0x10; i < FP_ICON_MAX; i++)
{
tmp_icon[i & 0x0F] = active_icon[i & 0x0F];
active_icon[i & 0x0F] = false;
ShowIcon((fp_icon)i, tmp_icon[i & 0x0F]);
}
}
}
#else
void CVFD::ShowText(const char * str)
{
if (fd < 0 || !support_text)
return;
char flags[2] = { FP_FLAG_ALIGN_LEFT, 0 };
if (! str) {
printf("CVFD::ShowText: str is NULL!\n");
return;
}
if (g_settings.lcd_scroll && ((int)strlen(str) > g_info.hw_caps->display_xres))
if (g_settings.lcd_scroll)
flags[0] |= FP_FLAG_SCROLL_ON | FP_FLAG_SCROLL_SIO | FP_FLAG_SCROLL_DELAY;
std::string txt = std::string(flags) + str;
txt = trim(txt);
printf("CVFD::ShowText: [0x%02x][%s]\n", flags[0], txt.c_str() + 1);
printf("CVFD::ShowText: [%s]\n", txt.c_str() + 1);
size_t len = txt.length();
if (txt == text || len > 255)
@@ -810,6 +1322,7 @@ void CVFD::ShowText(const char * str)
perror("IOC_FP_SET_TEXT");
}
}
#endif
void CVFD::ShowNumber(int number)
{

View File

@@ -82,6 +82,7 @@ class CVFD
MODES mode;
std::string servicename;
char *scrollstr;
int service_number;
bool support_text;
bool support_numbers;
@@ -90,13 +91,17 @@ class CVFD
bool muted;
bool showclock;
pthread_t thrTime;
#if HAVE_DUCKBOX_HARDWARE
pthread_t thread_start_loop;
#endif
int last_toggle_state_power;
bool clearClock;
unsigned int timeout_cnt;
unsigned int switch_name_time_cnt;
unsigned int switch_name_time_cnt;
int fd;
int brightness;
std::string text;
char g_str[64];
void count_down();
@@ -104,23 +109,29 @@ class CVFD
static void* TimeThread(void*);
void setlcdparameter(int dimm, int power);
#if !HAVE_DUCKBOX_HARDWARE
void setled(int led1, int led2);
#endif
public:
~CVFD();
bool has_lcd;
bool has_led_segment;
void setlcdparameter(void);
#if !HAVE_DUCKBOX_HARDWARE
void setled(void);
void setled(bool on_off);
void setBacklight(bool on_off);
#else
void setBacklight(bool /*on_off*/) { };
#endif
static CVFD* getInstance();
void init(const char * fontfile, const char * fontname);
void setMode(const MODES m, const char * const title = "");
void showServicename(const std::string & name, int number = -1); // UTF-8
void setEPGTitle(const std::string) { return; };
void setEPGTitle(const std::string) { return; }
void showTime(bool force = false);
/** blocks for duration seconds */
void showRCLock(int duration = 2);
@@ -154,10 +165,18 @@ class CVFD
void Unlock();
void Clear();
void ShowIcon(fp_icon icon, bool show);
#if HAVE_DUCKBOX_HARDWARE
void repaintIcons();
void UpdateIcons();
void ShowScrollText(char * str);
static void* ThreadScrollText(void * arg);
void ClearIcons();
#endif
void ShowText(const char *str);
void ShowNumber(int number);
void wake_up();
MODES getMode(void) { return mode; };
std::string getServicename(void) { return servicename; }
#ifdef LCD_UPDATE
private:
CFileList* m_fileList;