From c80a53ff6ea22aa14d1f9772b310b77ea0da7c42 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 16 May 2004 18:00:00 +0200 Subject: =?UTF-8?q?Version=201.3.7=20-=20Fixed=20a=20memory=20leak=20in=20?= =?UTF-8?q?thread=20handling=20when=20using=20NPTL=20(thanks=20to=20Jon=20?= =?UTF-8?q?Burgess).=20-=20Fixed=20handling=20Setup.RecordDolbyDigital,=20?= =?UTF-8?q?which=20was=20broken=20since=20version=201.1.6.=20-=20Fixed=20h?= =?UTF-8?q?andling=20text=20lengths=20for=20itemized=20EPG=20texts=20(than?= =?UTF-8?q?ks=20to=20Marcel=20Wiesweg).=20-=20Fixed=20the=20help=20for=20L?= =?UTF-8?q?STE=20and=20LSTR=20(was=20broken=20in=201.3.6).=20-=20Improved?= =?UTF-8?q?=20iso8859-7=20fonts=20(thanks=20to=20Dimitrios=20Dimitrakos).?= =?UTF-8?q?=20-=20Added=20some=203-letter=20language=20codes=20(thanks=20t?= =?UTF-8?q?o=20Marcus=20M=C3=B6nnig).=20-=20Added=20language=20code=20hand?= =?UTF-8?q?ling=20to=20the=20subtitling=20descriptor=20in=20'libsi'=20(tha?= =?UTF-8?q?nks=20to=20=20=20Pekka=20Virtanen).=20-=20Moved=20several=20men?= =?UTF-8?q?u=20item=20classes=20from=20menu.c=20to=20menuitems.[hc]=20to?= =?UTF-8?q?=20make=20them=20=20=20available=20for=20plugins.=20-=20The=20e?= =?UTF-8?q?pg2html.pl=20script=20now=20handles=20'|'=20in=20description=20?= =?UTF-8?q?texts.=20-=20The=20new=20setup=20option=20"OSD/Use=20small=20fo?= =?UTF-8?q?nt"=20can=20be=20used=20to=20control=20the=20use=20of=20=20=20t?= =?UTF-8?q?he=20small=20font=20(see=20MANUAL=20for=20details).=20-=20Swapp?= =?UTF-8?q?ed=20osd.[hc]=20and=20osdbase.[hc]=20to=20have=20the=20virtual?= =?UTF-8?q?=20OSD=20base=20class=20named=20cOsd.=20=20=20Plugins=20may=20n?= =?UTF-8?q?eed=20to=20adjust=20their=20#include=20statements.=20-=20Colors?= =?UTF-8?q?=20are=20now=20given=20as=20AARRGGBB=20instead=20of=20AABBGGRR.?= =?UTF-8?q?=20The=20values=20are=20mapped=20to=20=20=20the=20driver's=20(w?= =?UTF-8?q?rong)=20sequence=20in=20dvbosd.c=20(this=20should=20really=20be?= =?UTF-8?q?=20fixed=20in=20the=20=20=20driver,=20together=20with=20the=20e?= =?UTF-8?q?ndian=20problem).=20-=20The=20new=20OSD=20setup=20parameters=20?= =?UTF-8?q?"Left"=20and=20"Top"=20can=20be=20used=20to=20define=20the=20to?= =?UTF-8?q?p=20left=20=20=20corner=20of=20the=20OSD.=20-=20The=20OSD=20siz?= =?UTF-8?q?e=20parameters=20are=20now=20in=20pixel=20(as=20opposed=20to=20?= =?UTF-8?q?formerly=20characters).=20=20=20When=20reading=20a=20'setup.con?= =?UTF-8?q?f'=20file=20from=20an=20older=20version=20of=20VDR,=20the=20OSD?= =?UTF-8?q?width=20=20=20and=20OSDheight=20values=20will=20be=20converted?= =?UTF-8?q?=20to=20pixel=20automatically.=20-=20The=20OSD=20is=20now=20ful?= =?UTF-8?q?ly=20device=20independent.=20See=20the=20comments=20in=20VDR/os?= =?UTF-8?q?d.h=20and=20the=20=20=20description=20in=20PLUGINS.html=20for?= =?UTF-8?q?=20information=20on=20how=20a=20plugin=20can=20implement=20an?= =?UTF-8?q?=20OSD=20=20=20display=20on=20arbitrary=20hardware.=20-=20The?= =?UTF-8?q?=20OSD=20(actually=20its=20cBitmap=20class)=20can=20now=20handl?= =?UTF-8?q?e=20XPM=20files.=20There=20are=20several=20=20=20XPM=20files=20?= =?UTF-8?q?in=20the=20VDR/symbols=20directory=20which=20can=20be=20used=20?= =?UTF-8?q?by=20skins=20(some=20of=20these=20=20=20have=20been=20taken=20f?= =?UTF-8?q?rom=20the=20"elchi"=20patch).=20See=20VDR/skinsttng.c=20for=20e?= =?UTF-8?q?xamples=20on=20how=20=20=20to=20use=20these.=20-=20Due=20to=20t?= =?UTF-8?q?he=20changes=20in=20the=20OSD=20handling=20the=20DEBUG=5FOSD=20?= =?UTF-8?q?option=20for=20a=20textual=20OSD=20=20=20has=20been=20dropped.?= =?UTF-8?q?=20There=20will=20be=20a=20plugin=20that=20implements=20a=20ski?= =?UTF-8?q?n=20with=20this=20=20=20functionality=20later.=20-=20The=20enti?= =?UTF-8?q?re=20OSD=20display=20can=20now=20be=20implemented=20via=20"skin?= =?UTF-8?q?s".=20See=20VDR/skins.[hc],=20=20=20VDR/skinclassic.[hc],=20VDR?= =?UTF-8?q?/skinsttng.[hc]=20and=20PLUGINS.html=20for=20information=20on?= =?UTF-8?q?=20how=20=20=20a=20plugin=20can=20implement=20its=20own=20skin.?= =?UTF-8?q?=20By=20default=20VDR=20comes=20with=20a=20"Classic"=20skin=20?= =?UTF-8?q?=20=20that=20implements=20the=20OSD=20display=20known=20from=20?= =?UTF-8?q?previous=20versions,=20and=20the=20new=20skin=20=20=20named=20"?= =?UTF-8?q?ST:TNG=20Panels",=20which=20is=20also=20the=20default=20skin=20?= =?UTF-8?q?now.=20The=20actual=20skin=20can=20=20=20be=20selected=20throug?= =?UTF-8?q?h=20"Setup/OSD/Skin".=20-=20The=20colors=20used=20in=20a=20skin?= =?UTF-8?q?=20can=20now=20be=20configured=20using=20"themes".=20See=20PLUG?= =?UTF-8?q?INS.html=20=20=20for=20information=20on=20how=20a=20skin=20can?= =?UTF-8?q?=20make=20use=20of=20themes,=20and=20man=20vdr(5)=20for=20the?= =?UTF-8?q?=20=20=20structure=20of=20a=20theme=20file.=20The=20actual=20th?= =?UTF-8?q?eme=20to=20use=20can=20be=20selected=20through=20=20=20"Setup/O?= =?UTF-8?q?SD/Theme".=20-=20Added=20Croatian=20language=20texts=20(thanks?= =?UTF-8?q?=20to=20Drazen=20Dupor).=20=20=20NOTE:=20there=20is=20apparentl?= =?UTF-8?q?y=20a=20problem=20with=20the=20newly=20introduced=20iso8859-2?= =?UTF-8?q?=20font,=20=20=20because=20as=20soon=20as=20Setup/OSD/Language?= =?UTF-8?q?=20is=20set=20to=20Croatian=20(currently=20the=20last=20one=20?= =?UTF-8?q?=20=20in=20the=20list)=20everything=20freezes=20and=20the=20vdr?= =?UTF-8?q?=20processes=20have=20to=20be=20killed=20with=20-9=20=20=20and?= =?UTF-8?q?=20the=20driver=20needs=20to=20be=20reloaded.=20Maybe=20somebod?= =?UTF-8?q?y=20else=20can=20find=20out=20what's=20=20=20going=20wrong=20he?= =?UTF-8?q?re...=20-=20Added=20missing=20NULL=20checks=20when=20accessing?= =?UTF-8?q?=20sectionHandler=20in=20device.c=20(thanks=20to=20=20=20Pekka?= =?UTF-8?q?=20Virtanen).=20-=20Fixed=20setting=20the=20time=20from=20the?= =?UTF-8?q?=20DVB=20data=20stream=20(thanks=20to=20Helmut=20Auer=20for=20?= =?UTF-8?q?=20=20pointing=20out=20a=20frequency/transponder=20handling=20m?= =?UTF-8?q?ixup).=20This=20now=20also=20takes=20the=20=20=20actual=20sourc?= =?UTF-8?q?e=20(sat,=20cable=20etc.)=20into=20account.=20Please=20go=20int?= =?UTF-8?q?o=20"Setup/EPG"=20and=20=20=20set=20the=20"Set=20system=20time"?= =?UTF-8?q?=20and=20"Use=20time=20from=20transponder"=20parameters=20accor?= =?UTF-8?q?dingly=20=20=20(this=20is=20necessary=20even=20if=20you=20have?= =?UTF-8?q?=20already=20set=20them=20before!).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes.c | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 themes.c (limited to 'themes.c') diff --git a/themes.c b/themes.c new file mode 100644 index 0000000..0232822 --- /dev/null +++ b/themes.c @@ -0,0 +1,305 @@ +/* + * themes.c: Color themes used by skins + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: themes.c 1.1 2004/05/16 09:43:14 kls Exp $ + */ + +#include "themes.h" +#include +#include +#include "config.h" +#include "tools.h" + +// --- cTheme ---------------------------------------------------------------- + +cTheme::cTheme(void) +{ + name = strdup("default"); + memset(descriptions, 0, sizeof(descriptions)); + memset(colorNames, 0, sizeof(colorNames)); + memset(colorValues, 0, sizeof(colorValues)); + descriptions[0] = strdup("Default"); +} + +cTheme::~cTheme() +{ + free(name); + for (int i = 0; i < I18nNumLanguages; i++) + free(descriptions[i]); + for (int i = 0; i < MaxThemeColors; i++) + free(colorNames[i]); +} + +bool cTheme::FileNameOk(const char *FileName, bool SetName) +{ + const char *error = NULL; + if (!isempty(FileName)) { + const char *d = strrchr(FileName, '/'); + if (d) + FileName = d + 1; + const char *n = strchr(FileName, '-'); + if (n) { + if (n > FileName) { + if (!strchr(++n, '-')) { + const char *e = strchr(n, '.'); + if (e && strcmp(e, ".theme") == 0) { + if (e - n >= 1) { + // FileName is ok + if (SetName) { + free(name); + name = strndup(n, e - n); + } + } + else + error = "missing theme name"; + } + else + error = "invalid extension"; + } + else + error = "too many '-'"; + } + else + error = "missing skin name"; + } + else + error = "missing '-'"; + } + else + error = "empty"; + if (error) + esyslog("ERROR: invalid theme file name (%s): '%s'", error, FileName); + return !error; +} + +const char *cTheme::Description(void) +{ + char *s = descriptions[Setup.OSDLanguage]; + if (!s) + s = descriptions[0]; + return s ? s : name; +} + +bool cTheme::Load(const char *FileName, bool OnlyDescriptions) +{ + if (!FileNameOk(FileName, true)) + return false; + bool result = false; + if (!OnlyDescriptions) + isyslog("loading %s", FileName); + FILE *f = fopen(FileName, "r"); + if (f) { + int line = 0; + result = true; + char *s; + const char *error = NULL; + while ((s = readline(f)) != NULL) { + line++; + char *p = strchr(s, '#'); + if (p) + *p = 0; + s = stripspace(skipspace(s)); + if (!isempty(s)) { + char *n = s; + char *v = strchr(s, '='); + if (v) { + *v++ = 0; + n = stripspace(skipspace(n)); + v = stripspace(skipspace(v)); + if (strstr(n, "Description") == n) { + int lang = 0; + char *l = strchr(n, '.'); + if (l) + lang = I18nLanguageIndex(++l); + if (lang >= 0) + descriptions[lang] = strdup(v); + else + error = "invalid language code"; + } + else if (!OnlyDescriptions) { + for (int i = 0; i < MaxThemeColors; i++) { + if (colorNames[i]) { + if (strcmp(n, colorNames[i]) == 0) { + char *p = NULL; + errno = 0; + tColor c = strtoul(v, &p, 16); + if (!errno && !*p) + colorValues[i] = c; + else + error = "invalid color value"; + break; + } + } + else { + error = "unknown color name"; + break; + } + } + } + } + else + error = "missing value"; + } + if (error) { + result = false; + break; + } + } + if (!result) + esyslog("ERROR: error in %s, line %d%s%s\n", FileName, line, error ? ": " : "", error ? error : ""); + fclose(f); + } + else + LOG_ERROR_STR(FileName); + return result; +} + +bool cTheme::Save(const char *FileName) +{ + if (!FileNameOk(FileName)) + return false; + bool result = true; + cSafeFile f(FileName); + if (f.Open()) { + for (int i = 0; i < I18nNumLanguages; i++) { + if (descriptions[i]) + fprintf(f, "Description%s%.*s = %s\n", i ? "." : "", 3, i ? I18nLanguageCode(i) : "", descriptions[i]); + } + for (int i = 0; i < MaxThemeColors; i++) { + if (colorNames[i]) + fprintf(f, "%s = %08X\n", colorNames[i], colorValues[i]); + } + if (!f.Close()) + result = false; + } + else + result = false; + return result; +} + +int cTheme::AddColor(const char *Name, tColor Color) +{ + for (int i = 0; i < MaxThemeColors; i++) { + if (colorNames[i]) { + if (strcmp(Name, colorNames[i]) == 0) { + colorValues[i] = Color; + return i; + } + } + else { + colorNames[i] = strdup(Name); + colorValues[i] = Color; + return i; + } + } + return -1; +} + +tColor cTheme::Color(int Subject) +{ + return (Subject >= 0 && Subject < MaxThemeColors) ? colorValues[Subject] : 0; +} + +// --- cThemes --------------------------------------------------------------- + +char *cThemes::themesDirectory = NULL; + +cThemes::cThemes(void) +{ + numThemes = 0; + names = 0; + fileNames = NULL; + descriptions = NULL; +} + +cThemes::~cThemes() +{ + Clear(); +} + +void cThemes::Clear(void) +{ + for (int i = 0; i < numThemes; i++) { + free(names[i]); + free(fileNames[i]); + free(descriptions[i]); + } + free(names); + free(fileNames); + free(descriptions); + numThemes = 0; + names = 0; + fileNames = NULL; + descriptions = NULL; +} + +bool cThemes::Load(const char *SkinName) +{ + Clear(); + if (themesDirectory) { + DIR *d = opendir(themesDirectory); + if (d) { + struct dirent *e; + while ((e = readdir(d)) != NULL) { + if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) { + if (strstr(e->d_name, SkinName) == e->d_name && e->d_name[strlen(SkinName)] == '-') { + const char *FileName = AddDirectory(themesDirectory, e->d_name); + cTheme Theme; + if (Theme.Load(FileName, true)) { + names = (char **)realloc(names, (numThemes + 1) * sizeof(char *)); + names[numThemes] = strdup(Theme.Name()); + fileNames = (char **)realloc(fileNames, (numThemes + 1) * sizeof(char *)); + fileNames[numThemes] = strdup(FileName); + descriptions = (char **)realloc(descriptions, (numThemes + 1) * sizeof(char *)); + descriptions[numThemes] = strdup(Theme.Description()); + numThemes++; + } + } + } + } + closedir(d); + return numThemes > 0; + } + } + return false; +} + +int cThemes::GetThemeIndex(const char *Description) +{ + int index = 0; + for (int i = 0; i < numThemes; i++) { + if (strcmp(descriptions[i], Description) == 0) + return i; + if (strcmp(descriptions[i], "Default") == 0) + index = 1; + } + return index; +} + +void cThemes::SetThemesDirectory(const char *ThemesDirectory) +{ + free(themesDirectory); + themesDirectory = strdup(ThemesDirectory); + MakeDirs(themesDirectory, true); +} + +void cThemes::Load(const char *SkinName, const char *ThemeName, cTheme *Theme) +{ + char *FileName = NULL; + asprintf(&FileName, "%s/%s-%s.theme", themesDirectory, SkinName, ThemeName); + if (access(FileName, F_OK) == 0) // the file exists + Theme->Load(FileName); + free(FileName); +} + +void cThemes::Save(const char *SkinName, cTheme *Theme) +{ + char *FileName = NULL; + asprintf(&FileName, "%s/%s-%s.theme", themesDirectory, SkinName, Theme->Name()); + if (access(FileName, F_OK) != 0) // the file does not exist + Theme->Save(FileName); + free(FileName); +} -- cgit v1.2.3