diff options
-rw-r--r-- | CONTRIBUTORS | 12 | ||||
-rw-r--r-- | HISTORY | 31 | ||||
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | MANUAL | 8 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | PLUGINS/src/skincurses/HISTORY | 4 | ||||
-rw-r--r-- | PLUGINS/src/skincurses/Makefile | 4 | ||||
-rw-r--r-- | PLUGINS/src/skincurses/skincurses.c | 26 | ||||
-rw-r--r-- | config.c | 20 | ||||
-rw-r--r-- | config.h | 10 | ||||
-rw-r--r-- | device.c | 4 | ||||
-rw-r--r-- | font.c | 103 | ||||
-rw-r--r-- | font.h | 28 | ||||
-rw-r--r-- | i18n.c | 29 | ||||
-rw-r--r-- | libsi/si.c | 94 | ||||
-rw-r--r-- | menu.c | 39 | ||||
-rw-r--r-- | osd.c | 14 | ||||
-rw-r--r-- | osd.h | 13 | ||||
-rw-r--r-- | recording.c | 39 | ||||
-rw-r--r-- | recording.h | 4 | ||||
-rw-r--r-- | skinclassic.c | 36 | ||||
-rw-r--r-- | skinsttng.c | 34 | ||||
-rw-r--r-- | thread.c | 8 | ||||
-rw-r--r-- | timers.c | 8 | ||||
-rw-r--r-- | tools.c | 74 | ||||
-rw-r--r-- | tools.h | 52 | ||||
-rw-r--r-- | vdr.c | 33 |
27 files changed, 497 insertions, 238 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 471a6bc..e676a4f 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -886,6 +886,7 @@ Ludwig Nussel <ludwig.nussel@web.de> for removing the LOCK_THREAD from the LIRC thread for making the Makefile patch friendlier for a patch that was used for implementing setting the user id + for pointing out that the canonical spelling of codesets is with '-' Thomas Koch <tom@harhar.net> for his support in keeping the Premiere World channels up to date in 'channels.conf' @@ -1012,6 +1013,7 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi> for adding --remove-destination to the 'cp' command for binaries in the Makefiles of the plugins for increasing the maximum number of DVB devices to 8 + for suggesting to change the parameter "OSD font" to "Default font" in "Setup/OSD" Ralf Klueber <ralf.klueber@vodafone.com> for reporting a bug in cutting a recording if there is only a single editing mark @@ -1495,6 +1497,7 @@ Udo Richter <udo_richter@gmx.de> up at a particular time for making the HUP signal force a restart of VDR for fixing a race condition with signal handlers at program exit + for fixing handling detached processes in SystemExec() Sven Kreiensen <svenk@kammer.uni-hannover.de> for his help in keeping 'channels.conf.terr' up to date @@ -1739,6 +1742,7 @@ Thomas Günther <tom1@toms-cafe.de> for suggesting to extend the version number reported with the '-V' option to also show the current APIVERSION for fixing i18n characters for the Hungarian texts + for implementing using nl_langinfo(CODESET) to determine the local codeset to use David Woodhouse <dwmw2@infradead.org> for his help in replacing the get/put_unaligned() macros from asm/unaligned.h with @@ -1841,6 +1845,7 @@ Christian Wieninger <cwieninger@gmx.de> from the "Schedule" menu in case it starts withing the next two minutes for reporting a problem with a format string in recording.c on 64bit systems for reporting a problem with the device selection in case of timer conflicts + for a patch that fixed part of a crash in i18n character set conversion Thiemo Gehrke <tgehrke@reel-multimedia.com> for suggesting to add a setup option to turn off the automatic timeout of the @@ -1921,6 +1926,7 @@ Alexander Hans <cleditor@arcor.de> to be drawn with a transparent background for reporting that the "'1' for encrypted radio channels" part in the description of the VPID in vdr.5 is obsolete + for a patch that was used to implement storing the channel name in info.vdr Daniel Karsubka <dkar@gmx.de> for suggesting to write the epg.data file when VDR exits @@ -1947,6 +1953,7 @@ Christoph Haubrich <christoph1.haubrich@arcor.de> for reporting that the log message "deleting plugin: ..." is irritating when calling "vdr --help" for fixing cDevice::ToggleMute() + for suggestions that led to implementing cOsd::SetOsdPosition() etc. Pekka Mauno <pekka.mauno@iki.fi> for fixing cSchedule::GetFollowingEvent() in case there is currently no present @@ -2021,6 +2028,7 @@ Anssi Hannula <anssi.hannula@gmail.com> for improving handling Transfer Mode devices when selecting a device to receive for fixing handling frequencies in NitFilter::Process() for making non-primary devices in Transfer mode be also used for recording + for code and hints on how to use 'fontconfig' to determine which fonts to use Antti Hartikainen <ami+vdr@ah.fi> for updating 'S13E' in 'sources.conf' @@ -2087,3 +2095,7 @@ Krzysztof Parma <krzycho@zoz.wodzislaw.pl> Alexander Riedel <alexander-riedel@t-online.de> for a patch that was used as a base to implement support for Freetype fonts and UTF-8 handling + for a patch that fixed part of a crash in i18n character set conversion + +Jose Alberto Reguero <jareguero@telefonica.net> + for a patch that fixed part of a crash in i18n character set conversion @@ -5229,3 +5229,34 @@ Video Disk Recorder Revision History - Improved editing strings that are too long to fit into the editable area. - Changes to the OSD settings in the "Setup/OSD" menu now immediately take effect when the "Ok" key is pressed. + +2007-06-17: Version 1.5.4 + +- Increased APIVERSION (forgot to do that in 1.5.2 and 1.5.3). +- Fixed a crash in i18n character set conversion (thanks to Alexander Riedel, + Jose Alberto Reguero and Christian Wieninger for patches that cured part of + the problem). +- Adjusted the 'skincurses' plugin to UTF-8 handling. +- Using nl_langinfo(CODESET) to determine the local codeset to use (thanks to + Thomas Günther). The codeset names in 'libsi/si.c' have been changed to the + canonical spelling with '-' (thanks to Ludwig Nussel for pointing this out). +- Modified handling invalid characters in VFAT mode. +- Replaced strn0cpy() with Utf8Strn0Cpy() where necessary. +- Now using 'fontconfig' to determine which fonts to use (thanks to Anssi Hannula + for code and hints on how to do this). +- If no fonts are installed, VDR now uses a dummy font that doesn't actually draw + any text, and logs an error message. +- The new function cFont::CreateFont() can be used by plugins to create and use + fonts of their own, independent of VDR's standard fonts. +- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). +- Changed the parameter "OSD font" to "Default font" in "Setup/OSD" (suggested + by Rolf Ahrenberg). +- Fixed handling detached processes in SystemExec() (thanks to Udo Richter). +- The info.vdr file now also stores the name of the channel, and the new function + cRecordingInfo::ChannelName() returns this information if available (based on + a patch from Alexander Hans). +- The new function cOsd::SetOsdPosition() can be used to dynamically change the + position and size of the OSD (based on a request from Christoph Haubrich). + Plugins that implement skins should no longer use Setup.OSDWidth etc. directly, + but should rather use cOsd::OsdWidth() etc. instead. + Currently a change to the OSD position will only apply to newly opened OSDs. @@ -22,6 +22,7 @@ to work properly. You will also need to install the following libraries, as well as their "devel" packages to get the necessary header files for compiling VDR: + fontconfig freetype2 libcap libjpeg @@ -29,9 +30,6 @@ You will also need to install the following libraries, as well as their If the "capability" module is not compiled into your kernel, you may need to do "modprobe capability" before running VDR. -When running VDR, the Freetype fonts must be installed in the directory -/usr/share/fonts/truetype. - After extracting the package, change into the VDR directory and type 'make'. This should produce an executable file named 'vdr', which can be run after the DVB driver has been @@ -509,10 +509,10 @@ Version 1.4 utilize these. If either of these conditions is not met, rendering will be done without anti-aliasing. - OSD font name = arialbd.ttf - Small font name = arial.ttf - Fixed font name = courbd.ttf - The file names of the various fonts to use. + Default font = Sans Serif:Bold + Small font = Sans Serif + Fixed font = Courier:Bold + The names of the various fonts to use. OSD font size = 22 Small font size = 18 @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.100 2007/05/28 11:22:42 kls Exp $ +# $Id: Makefile 1.101 2007/06/16 10:48:59 kls Exp $ .DELETE_ON_ERROR: @@ -17,7 +17,7 @@ CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual LSIDIR = ./libsi MANDIR = /usr/local/man BINDIR = /usr/local/bin -LIBS = -ljpeg -lpthread -ldl -lcap -lfreetype +LIBS = -ljpeg -lpthread -ldl -lcap -lfreetype -lfontconfig INCLUDES = -I/usr/include/freetype2 PLUGINDIR= ./PLUGINS diff --git a/PLUGINS/src/skincurses/HISTORY b/PLUGINS/src/skincurses/HISTORY index 96ff93c..3204f20 100644 --- a/PLUGINS/src/skincurses/HISTORY +++ b/PLUGINS/src/skincurses/HISTORY @@ -39,3 +39,7 @@ VDR Plugin 'skincurses' Revision History 2006-09-10: Version 0.0.8 - The size of the OSD is now adjusted to the size of the console window. + +2007-06-15: Version 0.1.0 + +- Implemented UTF-8 handling. diff --git a/PLUGINS/src/skincurses/Makefile b/PLUGINS/src/skincurses/Makefile index 4f83614..a52f409 100644 --- a/PLUGINS/src/skincurses/Makefile +++ b/PLUGINS/src/skincurses/Makefile @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile 1.7 2006/09/09 12:38:35 kls Exp $ +# $Id: Makefile 1.8 2007/06/10 16:19:08 kls Exp $ # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -66,7 +66,7 @@ $(DEPFILE): Makefile all: libvdr-$(PLUGIN).so libvdr-$(PLUGIN).so: $(OBJS) - $(CXX) $(CXXFLAGS) -shared $(OBJS) -lncurses -o $@ + $(CXX) $(CXXFLAGS) -shared $(OBJS) -lncursesw -o $@ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) dist: clean diff --git a/PLUGINS/src/skincurses/skincurses.c b/PLUGINS/src/skincurses/skincurses.c index 243ddce..33fe194 100644 --- a/PLUGINS/src/skincurses/skincurses.c +++ b/PLUGINS/src/skincurses/skincurses.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: skincurses.c 1.11 2006/09/10 14:23:55 kls Exp $ + * $Id: skincurses.c 1.13 2007/06/16 09:05:04 kls Exp $ */ #include <ncurses.h> @@ -11,7 +11,7 @@ #include <vdr/plugin.h> #include <vdr/skins.h> -static const char *VERSION = "0.0.8"; +static const char *VERSION = "0.1.0"; static const char *DESCRIPTION = "A text only skin"; static const char *MAINMENUENTRY = NULL; @@ -19,12 +19,10 @@ static const char *MAINMENUENTRY = NULL; class cCursesFont : public cFont { public: - cCursesFont(void): cFont(NULL) {} - virtual int Width(unsigned char c) const { return 1; } - virtual int Width(const char *s) const { return s ? strlen(s) : 0; } - virtual int Height(unsigned char c) const { return 1; } - virtual int Height(const char *s) const { return 1; } + virtual int Width(uint c) const { return 1; } + virtual int Width(const char *s) const { return s ? Utf8StrLen(s) : 0; } virtual int Height(void) const { return 1; } + virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {} }; static const cCursesFont Font; @@ -135,6 +133,8 @@ void cCursesOsd::RestoreRegion(void) void cCursesOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment) { + if (!s) + return; int w = Font->Width(s); int h = Font->Height(); if (Width || Height) { @@ -253,7 +253,7 @@ void cSkinCursesDisplayChannel::Flush(void) { if (!message) { cString date = DayDateTime(); - osd->DrawText(OsdWidth - strlen(date), 0, date, clrWhite, clrBackground, &Font); + osd->DrawText(OsdWidth - Utf8StrLen(date), 0, date, clrWhite, clrBackground, &Font); } osd->Flush(); } @@ -388,7 +388,7 @@ void cSkinCursesDisplayMenu::SetEvent(const cEvent *Event) if (Event->Vps() && Event->Vps() != Event->StartTime()) { char *buffer; asprintf(&buffer, " VPS: %s", *Event->GetVpsString()); - osd->DrawText(OsdWidth - strlen(buffer), y, buffer, clrBlack, clrYellow, &Font); + osd->DrawText(OsdWidth - Utf8StrLen(buffer), y, buffer, clrBlack, clrYellow, &Font); free(buffer); } y += ts.Height(); @@ -443,7 +443,7 @@ void cSkinCursesDisplayMenu::SetText(const char *Text, bool FixedFont) void cSkinCursesDisplayMenu::Flush(void) { cString date = DayDateTime(); - osd->DrawText(OsdWidth - strlen(date) - 2, 0, date, clrBlack, clrCyan, &Font); + osd->DrawText(OsdWidth - Utf8StrLen(date) - 2, 0, date, clrBlack, clrCyan, &Font); osd->Flush(); } @@ -508,12 +508,12 @@ void cSkinCursesDisplayReplay::SetProgress(int Current, int Total) void cSkinCursesDisplayReplay::SetCurrent(const char *Current) { - osd->DrawText(0, 2, Current, clrWhite, clrBackground, &Font, strlen(Current) + 3); + osd->DrawText(0, 2, Current, clrWhite, clrBackground, &Font, Utf8StrLen(Current) + 3); } void cSkinCursesDisplayReplay::SetTotal(const char *Total) { - osd->DrawText(OsdWidth - strlen(Total), 2, Total, clrWhite, clrBackground, &Font); + osd->DrawText(OsdWidth - Utf8StrLen(Total), 2, Total, clrWhite, clrBackground, &Font); } void cSkinCursesDisplayReplay::SetJump(const char *Jump) @@ -569,7 +569,7 @@ void cSkinCursesDisplayVolume::SetVolume(int Current, int Total, bool Mute) } else { const char *Prompt = tr("Volume "); - int l = strlen(Prompt); + int l = Utf8StrLen(Prompt); int p = (OsdWidth - l) * Current / Total; osd->DrawText(0, 0, Prompt, clrGreen, clrBackground, &Font); osd->DrawRectangle(l, 0, l + p - 1, 0, clrGreen); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.151 2007/06/02 11:21:40 kls Exp $ + * $Id: config.c 1.153 2007/06/17 11:54:54 kls Exp $ */ #include "config.h" @@ -265,9 +265,9 @@ cSetup::cSetup(void) OSDMessageTime = 1; UseSmallFont = 1; AntiAlias = 1; - strcpy(FontOsd, "arialbd.ttf"); - strcpy(FontSml, "arial.ttf"); - strcpy(FontFix, "courbd.ttf"); + strcpy(FontOsd, DefaultFontOsd); + strcpy(FontSml, DefaultFontSml); + strcpy(FontFix, DefaultFontFix); FontOsdSize = 22; FontSmlSize = 18; FontFixSize = 20; @@ -385,8 +385,8 @@ bool cSetup::ParseLanguages(const char *Value, int *Values) bool cSetup::Parse(const char *Name, const char *Value) { if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value); - else if (!strcasecmp(Name, "OSDSkin")) strn0cpy(OSDSkin, Value, MaxSkinName); - else if (!strcasecmp(Name, "OSDTheme")) strn0cpy(OSDTheme, Value, MaxThemeName); + else if (!strcasecmp(Name, "OSDSkin")) Utf8Strn0Cpy(OSDSkin, Value, MaxSkinName); + else if (!strcasecmp(Name, "OSDTheme")) Utf8Strn0Cpy(OSDTheme, Value, MaxThemeName); else if (!strcasecmp(Name, "PrimaryDVB")) PrimaryDVB = atoi(Value); else if (!strcasecmp(Name, "ShowInfoOnChSwitch")) ShowInfoOnChSwitch = atoi(Value); else if (!strcasecmp(Name, "TimeoutRequChInfo")) TimeoutRequChInfo = atoi(Value); @@ -394,7 +394,7 @@ bool cSetup::Parse(const char *Name, const char *Value) else if (!strcasecmp(Name, "MenuScrollWrap")) MenuScrollWrap = atoi(Value); else if (!strcasecmp(Name, "MenuKeyCloses")) MenuKeyCloses = atoi(Value); else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value); - else if (!strcasecmp(Name, "NameInstantRecord")) strn0cpy(NameInstantRecord, Value, MaxFileName); + else if (!strcasecmp(Name, "NameInstantRecord")) Utf8Strn0Cpy(NameInstantRecord, Value, MaxFileName); else if (!strcasecmp(Name, "InstantRecordTime")) InstantRecordTime = atoi(Value); else if (!strcasecmp(Name, "LnbSLOF")) LnbSLOF = atoi(Value); else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value); @@ -435,9 +435,9 @@ bool cSetup::Parse(const char *Name, const char *Value) else if (!strcasecmp(Name, "OSDMessageTime")) OSDMessageTime = atoi(Value); else if (!strcasecmp(Name, "UseSmallFont")) UseSmallFont = atoi(Value); else if (!strcasecmp(Name, "AntiAlias")) AntiAlias = atoi(Value); - else if (!strcasecmp(Name, "FontOsd")) strn0cpy(FontOsd, Value, MAXFONTNAME); - else if (!strcasecmp(Name, "FontSml")) strn0cpy(FontSml, Value, MAXFONTNAME); - else if (!strcasecmp(Name, "FontFix")) strn0cpy(FontFix, Value, MAXFONTNAME); + else if (!strcasecmp(Name, "FontOsd")) Utf8Strn0Cpy(FontOsd, Value, MAXFONTNAME); + else if (!strcasecmp(Name, "FontSml")) Utf8Strn0Cpy(FontSml, Value, MAXFONTNAME); + else if (!strcasecmp(Name, "FontFix")) Utf8Strn0Cpy(FontFix, Value, MAXFONTNAME); else if (!strcasecmp(Name, "FontOsdSize")) FontOsdSize = atoi(Value); else if (!strcasecmp(Name, "FontSmlSize")) FontSmlSize = atoi(Value); else if (!strcasecmp(Name, "FontFixSize")) FontFixSize = atoi(Value); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.290 2007/06/02 11:22:17 kls Exp $ + * $Id: config.h 1.291 2007/06/13 06:38:33 kls Exp $ */ #ifndef __CONFIG_H @@ -22,13 +22,13 @@ // VDR's own version number: -#define VDRVERSION "1.5.3" -#define VDRVERSNUM 10503 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.5.4" +#define VDRVERSNUM 10504 // Version * 10000 + Major * 100 + Minor // The plugin API's version number: -#define APIVERSION "1.5.1" -#define APIVERSNUM 10501 // Version * 10000 + Major * 100 + Minor +#define APIVERSION "1.5.4" +#define APIVERSNUM 10504 // Version * 10000 + Major * 100 + Minor // When loading plugins, VDR searches them by their APIVERSION, which // may be smaller than VDRVERSION in case there have been no changes to @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.140 2007/04/30 09:34:00 kls Exp $ + * $Id: device.c 1.141 2007/06/16 09:31:32 kls Exp $ */ #include "device.h" @@ -859,7 +859,7 @@ bool cDevice::SetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const c if (Language) strn0cpy(availableTracks[t].language, Language, sizeof(availableTracks[t].language)); if (Description) - strn0cpy(availableTracks[t].description, Description, sizeof(availableTracks[t].description)); + Utf8Strn0Cpy(availableTracks[t].description, Description, sizeof(availableTracks[t].description)); if (Id) { availableTracks[t].id = Id; // setting 'id' last to avoid the need for extensive locking int numAudioTracks = NumAudioTracks(); @@ -4,17 +4,22 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: font.c 1.15 2007/06/09 14:41:27 kls Exp $ + * $Id: font.c 1.19 2007/06/17 12:13:49 kls Exp $ */ #include "font.h" #include <ctype.h> +#include <fontconfig/fontconfig.h> #include <ft2build.h> #include FT_FREETYPE_H #include "config.h" #include "osd.h" #include "tools.h" +const char *DefaultFontOsd = "Sans Serif:Bold"; +const char *DefaultFontSml = "Sans Serif"; +const char *DefaultFontFix = "Courier:Bold"; + // --- cFreetypeFont --------------------------------------------------------- #define KERNING_UNKNOWN (-10000) @@ -22,7 +27,7 @@ struct tKerning { uint prevSym; int kerning; - tKerning(uint PrevSym, int Kerning) { prevSym = PrevSym; kerning = Kerning; } + tKerning(uint PrevSym, int Kerning = 0) { prevSym = PrevSym; kerning = Kerning; } }; class cGlyph : public cListObject { @@ -286,14 +291,29 @@ void cFreetypeFont::DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColo } } +// --- cDummyFont ------------------------------------------------------------ + +// A dummy font, in case there are no fonts installed: + +class cDummyFont : public cFont { +public: + virtual int Width(uint c) const { return 10; } + virtual int Width(const char *s) const { return 50; } + virtual int Height(void) const { return 20; } + virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {} + }; + // --- cFont ----------------------------------------------------------------- cFont *cFont::fonts[eDvbFontSize] = { NULL }; void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight) { + cFont *f = CreateFont(Name, CharHeight); + if (!f || !f->Height()) + f = new cDummyFont; delete fonts[Font]; - fonts[Font] = new cFreetypeFont(*Name == '/' ? Name : *AddDirectory(FONTDIR, Name), CharHeight); + fonts[Font] = f; } const cFont *cFont::GetFont(eDvbFont Font) @@ -304,14 +324,85 @@ const cFont *cFont::GetFont(eDvbFont Font) Font = fontSml; if (!fonts[Font]) { switch (Font) { - case fontOsd: SetFont(Font, AddDirectory(FONTDIR, Setup.FontOsd), Setup.FontOsdSize); break; - case fontSml: SetFont(Font, AddDirectory(FONTDIR, Setup.FontSml), Setup.FontSmlSize); break; - case fontFix: SetFont(Font, AddDirectory(FONTDIR, Setup.FontFix), Setup.FontFixSize); break; + case fontOsd: SetFont(Font, Setup.FontOsd, Setup.FontOsdSize); break; + case fontSml: SetFont(Font, Setup.FontSml, Setup.FontSmlSize); break; + case fontFix: SetFont(Font, Setup.FontFix, Setup.FontFixSize); break; } } return fonts[Font]; } +cFont *cFont::CreateFont(const char *Name, int CharHeight) +{ + cString fn = GetFontFileName(Name); + if (*fn) + return new cFreetypeFont(fn, CharHeight); + return NULL; +} + +bool cFont::GetAvailableFontNames(cStringList *FontNames, bool Monospaced) +{ + if (!FontNames->Size()) { + FcInit(); + FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL); + FcPattern *pat = FcPatternCreate(); + FcPatternAddBool(pat, FC_SCALABLE, FcTrue); + if (Monospaced) + FcPatternAddInteger(pat, FC_SPACING, FC_MONO); + FcFontSet* fontset = FcFontList(NULL, pat, os); + for (int i = 0; i < fontset->nfont; i++) { + char *s = (char *)FcNameUnparse(fontset->fonts[i]); + if (s) { + // Strip i18n stuff: + char *p = strchr(s, ','); + if (p) + *p = 0; + // Make it user presentable: + s = strreplace(s, "\\", ""); // '-' is escaped + s = strreplace(s, "style=", ""); + FontNames->Append(s); // takes ownership of s + } + } + FcFontSetDestroy(fontset); + FcPatternDestroy(pat); + FcObjectSetDestroy(os); + FcFini(); + FontNames->Sort(); + } + return FontNames->Size() > 0; +} + +cString cFont::GetFontFileName(const char *FontName) +{ + cString FontFileName; + if (FontName) { + char *fn = strdup(FontName); + fn = strreplace(fn, ":", ":style="); + fn = strreplace(fn, "-", "\\-"); + FcInit(); + FcPattern *pat = FcNameParse((FcChar8 *)fn); + FcPatternAddBool(pat, FC_SCALABLE, FcTrue); + FcConfigSubstitute(NULL, pat, FcMatchPattern); + FcDefaultSubstitute(pat); + FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, NULL); + for (int i = 0; i < fontset->nfont; i++) { + FcBool scalable; + FcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, &scalable); + if (scalable) { + FcChar8 *s = NULL; + FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &s); + FontFileName = (char *)s; + break; + } + } + FcFontSetDestroy(fontset); + FcPatternDestroy(pat); + free(fn); + FcFini(); + } + return FontFileName; +} + // --- cTextWrapper ---------------------------------------------------------- cTextWrapper::cTextWrapper(void) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: font.h 1.16 2007/06/10 12:58:54 kls Exp $ + * $Id: font.h 1.19 2007/06/17 12:11:31 kls Exp $ */ #ifndef __FONT_H @@ -12,10 +12,10 @@ #include <stdint.h> #include <stdlib.h> +#include "tools.h" #define MAXFONTNAME 64 #define MAXFONTSIZE 64 -#define FONTDIR "/usr/share/fonts/truetype" enum eDvbFont { fontOsd, @@ -28,6 +28,10 @@ class cBitmap; typedef uint32_t tColor; // see also osd.h typedef uint8_t tIndex; +extern const char *DefaultFontOsd; +extern const char *DefaultFontSml; +extern const char *DefaultFontFix; + class cFont { private: static cFont *fonts[]; @@ -45,14 +49,30 @@ public: ///< Draws the given text into the Bitmap at position (x, y) with the given colors. ///< The text will not exceed the given Width (if > 0), and will end with a complete character. static void SetFont(eDvbFont Font, const char *Name, int CharHeight); - ///< Sets the given Font to use the font data from the file Name and make its characters - ///< CharHeight pixels high. + ///< Sets the given Font to use the font data according to Name (see CreateFont()) + ///< and make its characters CharHeight pixels high. static const cFont *GetFont(eDvbFont Font); ///< Gets the given Font, which was previously set by a call to SetFont(). ///< If no SetFont() call has been made, the font as defined in the setup is returned. ///< The caller must not use the returned font outside the scope in which ///< it was retrieved by the call to GetFont(), because a call to SetFont() ///< may delete an existing font. + static cFont *CreateFont(const char *Name, int CharHeight); + ///< Creates a new font object with the given Name and makes its characters + ///< CharHeight pixels high. Name is of the form "Family:Style", for instance + ///< "Verdana:Bold Italic" or "Times New Roman". See GetAvailableFontNames() + ///< for how to get a list of all available font names. + ///< If the requested font can't be created, NULL is returned. + ///< The caller must delete the font when it is no longer needed. + static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced = false); + ///< Queries the font configuration for a list of available font names, + ///< which is returned in FontNames. If Monospaced is true, only + ///< monospaced fonts will be returned. The resulting font names are + ///< in a format that can be used with GetFontFileName() to get the name + ///< of the actual font file. + ///< Returns true if any font names were found. + static cString GetFontFileName(const char *FontName); + ///< Retruns the actual font file name for the given FontName. }; class cTextWrapper { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.294 2007/06/09 08:44:54 kls Exp $ + * $Id: i18n.c 1.297 2007/06/17 12:31:02 kls Exp $ * * Translations provided by: * @@ -3563,7 +3563,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO "",// TODO - "",// TODO + "Käytä antialiasointia", "",// TODO "",// TODO "",// TODO @@ -3578,15 +3578,15 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO }, - { "Setup.OSD$OSD font name", - "OSD Schriftart", - "",// TODO + { "Setup.OSD$Default font", + "Standard-Schriftart", "",// TODO "",// TODO "",// TODO "",// TODO "",// TODO "",// TODO + "Oletuskirjasintyyppi", "",// TODO "",// TODO "",// TODO @@ -3601,7 +3601,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO }, - { "Setup.OSD$Small font name", + { "Setup.OSD$Small font", "Kleine Schriftart", "",// TODO "",// TODO @@ -3609,7 +3609,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO "",// TODO - "",// TODO + "Pienikirjasintyyppi", "",// TODO "",// TODO "",// TODO @@ -3624,7 +3624,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO }, - { "Setup.OSD$Fixed font name", + { "Setup.OSD$Fixed font", "Festbreiten-Schriftart", "",// TODO "",// TODO @@ -3632,7 +3632,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO "",// TODO - "",// TODO + "Tasavälinen kirjasintyyppi", "",// TODO "",// TODO "",// TODO @@ -3655,7 +3655,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO "",// TODO - "",// TODO + "Oletuskirjasintyypin koko (px)", "",// TODO "",// TODO "",// TODO @@ -3678,7 +3678,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO "",// TODO - "",// TODO + "Pienen kirjasintyypin koko (px)", "",// TODO "",// TODO "",// TODO @@ -3701,7 +3701,7 @@ const tI18nPhrase Phrases[] = { "",// TODO "",// TODO "",// TODO - "",// TODO + "Tasavälisen kirjasintyypin koko (px)", "",// TODO "",// TODO "",// TODO @@ -6820,7 +6820,7 @@ static const char *ConvertPhrase(const tI18nPhrase *Original, tI18nPhrase **Conv *Converted = new tI18nPhrase[NumPhrases + 1]; memset(*Converted, 0, sizeof(tI18nPhrase) * (NumPhrases + 1)); } - if (!(*Converted)[NrPhrase][NrLanguage]) { + if (!(*Converted)[NrPhrase][NrLanguage] && Original[NrPhrase][NrLanguage]) { cCharSetConv csc(Phrases[1][NrLanguage], cCharSetConv::SystemCharacterTable()); (*Converted)[NrPhrase][NrLanguage] = strdup(csc.Convert(Original[NrPhrase][NrLanguage])); } @@ -6851,7 +6851,8 @@ const char *I18nTranslate(const char *s, const char *Plugin) return t; } } - p = Phrases; + p = OriginalPhrases = Phrases; + ConvertedPhrases = &Converted; } esyslog("%s%sno translation found for '%s' in language %d (%s)", Plugin ? Plugin : "", Plugin ? ": " : "", s, Setup.OSDLanguage, Phrases[0][Setup.OSDLanguage]); } @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.c 1.20 2007/06/10 09:31:34 kls Exp $ + * $Id: si.c 1.21 2007/06/15 13:08:31 kls Exp $ * * ***************************************************************************/ @@ -250,59 +250,59 @@ char *String::getText(char *buffer, char *shortVersion, int sizeBuffer, int size } static const char *CharacterTables1[] = { - NULL, // 0x00 - "ISO8859-5", // 0x01 - "ISO8859-6", // 0x02 - "ISO8859-7", // 0x03 - "ISO8859-8", // 0x04 - "ISO8859-9", // 0x05 - "ISO8859-10", // 0x06 - "ISO8859-11", // 0x07 - "ISO8859-12", // 0x08 - "ISO8859-13", // 0x09 - "ISO8859-14", // 0x0A - "ISO8859-15", // 0x0B - NULL, // 0x0C - NULL, // 0x0D - NULL, // 0x0E - NULL, // 0x0F - NULL, // 0x10 - "UTF16", // 0x11 - "EUC-KR", // 0x12 - "GB2312", // 0x13 - "GBK", // 0x14 - "UTF8", // 0x15 - NULL, // 0x16 - NULL, // 0x17 - NULL, // 0x18 - NULL, // 0x19 - NULL, // 0x1A - NULL, // 0x1B - NULL, // 0x1C - NULL, // 0x1D - NULL, // 0x1E - NULL, // 0x1F + NULL, // 0x00 + "ISO-8859-5", // 0x01 + "ISO-8859-6", // 0x02 + "ISO-8859-7", // 0x03 + "ISO-8859-8", // 0x04 + "ISO-8859-9", // 0x05 + "ISO-8859-10", // 0x06 + "ISO-8859-11", // 0x07 + "ISO-8859-12", // 0x08 + "ISO-8859-13", // 0x09 + "ISO-8859-14", // 0x0A + "ISO-8859-15", // 0x0B + NULL, // 0x0C + NULL, // 0x0D + NULL, // 0x0E + NULL, // 0x0F + NULL, // 0x10 + "UTF-16", // 0x11 + "EUC-KR", // 0x12 + "GB2312", // 0x13 + "GBK", // 0x14 + "UTF-8", // 0x15 + NULL, // 0x16 + NULL, // 0x17 + NULL, // 0x18 + NULL, // 0x19 + NULL, // 0x1A + NULL, // 0x1B + NULL, // 0x1C + NULL, // 0x1D + NULL, // 0x1E + NULL, // 0x1F }; #define SingleByteLimit 0x0B static const char *CharacterTables2[] = { NULL, // 0x00 - "ISO8859-1", // 0x01 - "ISO8859-2", // 0x02 - "ISO8859-3", // 0x03 - "ISO8859-4", // 0x04 - "ISO8859-5", // 0x05 - "ISO8859-6", // 0x06 - "ISO8859-7", // 0x07 - "ISO8859-8", // 0x08 - "ISO8859-9", // 0x09 - "ISO8859-10", // 0x0A - "ISO8859-11", // 0x0B + "ISO-8859-1", // 0x01 + "ISO-8859-2", // 0x02 + "ISO-8859-3", // 0x03 + "ISO-8859-4", // 0x04 + "ISO-8859-5", // 0x05 + "ISO-8859-6", // 0x06 + "ISO-8859-7", // 0x07 + "ISO-8859-8", // 0x08 + "ISO-8859-9", // 0x09 + "ISO-8859-10", // 0x0A + "ISO-8859-11", // 0x0B NULL, // 0x0C - "ISO8859-13", // 0x0D - "ISO8859-14", // 0x0E - "ISO8859-15", // 0x0F + "ISO-8859-13", // 0x0D + "ISO-8859-14", // 0x0E + "ISO-8859-15", // 0x0F }; #define NumEntries(Table) (sizeof(Table) / sizeof(char *)) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.451 2007/06/09 14:36:46 kls Exp $ + * $Id: menu.c 1.455 2007/06/17 12:33:01 kls Exp $ */ #include "menu.h" @@ -2160,7 +2160,7 @@ private: cThemes themes; int originalThemeIndex; int themeIndex; - cFileNameList fontNames; + cStringList fontOsdNames, fontSmlNames, fontFixNames; int fontOsdIndex, fontSmlIndex, fontFixIndex; virtual void Set(void); public: @@ -2176,12 +2176,15 @@ cMenuSetupOSD::cMenuSetupOSD(void) skinDescriptions = new const char*[numSkins]; themes.Load(Skins.Current()->Name()); themeIndex = originalThemeIndex = Skins.Current()->Theme() ? themes.GetThemeIndex(Skins.Current()->Theme()->Description()) : 0; - fontNames.Load(FONTDIR); - if (fontNames.Size()) { - fontOsdIndex = max(0, fontNames.Find(Setup.FontOsd)); - fontSmlIndex = max(0, fontNames.Find(Setup.FontSml)); - fontFixIndex = max(0, fontNames.Find(Setup.FontFix)); - } + cFont::GetAvailableFontNames(&fontOsdNames); + cFont::GetAvailableFontNames(&fontSmlNames); + cFont::GetAvailableFontNames(&fontFixNames, true); + fontOsdNames.Insert(strdup(DefaultFontOsd)); + fontSmlNames.Insert(strdup(DefaultFontSml)); + fontFixNames.Insert(strdup(DefaultFontFix)); + fontOsdIndex = max(0, fontOsdNames.Find(Setup.FontOsd)); + fontSmlIndex = max(0, fontSmlNames.Find(Setup.FontSml)); + fontFixIndex = max(0, fontFixNames.Find(Setup.FontFix)); Set(); } @@ -2211,11 +2214,9 @@ void cMenuSetupOSD::Set(void) Add(new cMenuEditIntItem( tr("Setup.OSD$Message time (s)"), &data.OSDMessageTime, 1, 60)); Add(new cMenuEditStraItem(tr("Setup.OSD$Use small font"), &data.UseSmallFont, 3, useSmallFontTexts)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Anti-alias"), &data.AntiAlias)); - if (fontNames.Size()) { - Add(new cMenuEditStraItem(tr("Setup.OSD$OSD font name"), &fontOsdIndex, fontNames.Size(), &fontNames[0])); - Add(new cMenuEditStraItem(tr("Setup.OSD$Small font name"), &fontSmlIndex, fontNames.Size(), &fontNames[0])); - Add(new cMenuEditStraItem(tr("Setup.OSD$Fixed font name"), &fontFixIndex, fontNames.Size(), &fontNames[0])); - } + Add(new cMenuEditStraItem(tr("Setup.OSD$Default font"), &fontOsdIndex, fontOsdNames.Size(), &fontOsdNames[0])); + Add(new cMenuEditStraItem(tr("Setup.OSD$Small font"), &fontSmlIndex, fontSmlNames.Size(), &fontSmlNames[0])); + Add(new cMenuEditStraItem(tr("Setup.OSD$Fixed font"), &fontFixIndex, fontFixNames.Size(), &fontFixNames[0])); Add(new cMenuEditIntItem( tr("Setup.OSD$OSD font size (pixel)"), &data.FontOsdSize, 10, MAXFONTSIZE)); Add(new cMenuEditIntItem( tr("Setup.OSD$Small font size (pixel)"),&data.FontSmlSize, 10, MAXFONTSIZE)); Add(new cMenuEditIntItem( tr("Setup.OSD$Fixed font size (pixel)"),&data.FontFixSize, 10, MAXFONTSIZE)); @@ -2239,14 +2240,14 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys Key) if (skinIndex != originalSkinIndex) { cSkin *Skin = Skins.Get(skinIndex); if (Skin) { - strn0cpy(data.OSDSkin, Skin->Name(), sizeof(data.OSDSkin)); + Utf8Strn0Cpy(data.OSDSkin, Skin->Name(), sizeof(data.OSDSkin)); Skins.SetCurrent(Skin->Name()); ModifiedApperance = true; } } if (themes.NumThemes() && Skins.Current()->Theme()) { Skins.Current()->Theme()->Load(themes.FileName(themeIndex)); - strn0cpy(data.OSDTheme, themes.Name(themeIndex), sizeof(data.OSDTheme)); + Utf8Strn0Cpy(data.OSDTheme, themes.Name(themeIndex), sizeof(data.OSDTheme)); ModifiedApperance |= themeIndex != originalThemeIndex; } if (data.OSDLeft != Setup.OSDLeft || data.OSDTop != Setup.OSDTop || data.OSDWidth != Setup.OSDWidth || data.OSDHeight != Setup.OSDHeight) { @@ -2255,11 +2256,9 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys Key) } if (data.UseSmallFont != Setup.UseSmallFont || data.AntiAlias != Setup.AntiAlias) ModifiedApperance = true; - if (fontNames.Size()) { - strn0cpy(data.FontOsd, fontNames[fontOsdIndex], sizeof(data.FontOsd)); - strn0cpy(data.FontSml, fontNames[fontSmlIndex], sizeof(data.FontSml)); - strn0cpy(data.FontFix, fontNames[fontFixIndex], sizeof(data.FontFix)); - } + Utf8Strn0Cpy(data.FontOsd, fontOsdNames[fontOsdIndex], sizeof(data.FontOsd)); + Utf8Strn0Cpy(data.FontSml, fontSmlNames[fontSmlIndex], sizeof(data.FontSml)); + Utf8Strn0Cpy(data.FontFix, fontFixNames[fontFixIndex], sizeof(data.FontFix)); if (strcmp(data.FontOsd, Setup.FontOsd) || data.FontOsdSize != Setup.FontOsdSize) { cFont::SetFont(fontOsd, data.FontOsd, data.FontOsdSize); ModifiedApperance = true; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.69 2007/06/10 12:16:36 kls Exp $ + * $Id: osd.c 1.70 2007/06/17 13:54:34 kls Exp $ */ #include "osd.h" @@ -642,6 +642,10 @@ const tIndex *cBitmap::Data(int x, int y) // --- cOsd ------------------------------------------------------------------ +int cOsd::osdLeft = 0; +int cOsd::osdTop = 0; +int cOsd::osdWidth = 0; +int cOsd::osdHeight = 0; int cOsd::isOpen = 0; cOsd::cOsd(int Left, int Top) @@ -664,6 +668,14 @@ cOsd::~cOsd() isOpen--; } +void cOsd::SetOsdPostion(int Left, int Top, int Width, int Height) +{ + osdLeft = Left; + osdTop = Top; + osdWidth = Width; + osdHeight = Height; +} + void cOsd::SetAntiAliasGranularity(uint FixedColors, uint BlendColors) { for (int i = 0; i < numBitmaps; i++) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.h 1.54 2007/06/10 12:15:52 kls Exp $ + * $Id: osd.h 1.55 2007/06/17 13:59:22 kls Exp $ */ #ifndef __OSD_H @@ -13,6 +13,7 @@ #include <limits.h> #include <stdio.h> #include <stdint.h> +#include "config.h" #include "font.h" #define MAXNUMCOLORS 256 @@ -245,6 +246,7 @@ struct tArea { class cOsd { friend class cOsdProvider; private: + static int osdLeft, osdTop, osdWidth, osdHeight; static int isOpen; cBitmap *savedRegion; cBitmap *bitmaps[MAXOSDAREAS]; @@ -270,6 +272,15 @@ protected: public: virtual ~cOsd(); ///< Shuts down the OSD. + static int OsdLeft(void) { return osdLeft ? osdLeft : Setup.OSDLeft; } + static int OsdTop(void) { return osdTop ? osdTop : Setup.OSDTop; } + static int OsdWidth(void) { return osdWidth ? osdWidth : Setup.OSDWidth; } + static int OsdHeight(void) { return osdHeight ? osdHeight : Setup.OSDHeight; } + static void SetOsdPostion(int Left, int Top, int Width, int Height); + ///< Sets the position and size of the OSD to the given values. + ///< This may be useful for plugins that determine the scaling of the + ///< video image and need to scale the OSD accordingly to fit on the + ///< screen. static int IsOpen(void) { return isOpen; } int Left(void) { return left; } int Top(void) { return top; } diff --git a/recording.c b/recording.c index 5298de3..22bb955 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.151 2006/10/07 12:46:22 kls Exp $ + * $Id: recording.c 1.154 2007/06/17 13:10:12 kls Exp $ */ #include "recording.h" @@ -262,6 +262,7 @@ void cResumeFile::Delete(void) cRecordingInfo::cRecordingInfo(const cChannel *Channel, const cEvent *Event) { channelID = Channel ? Channel->GetChannelID() : tChannelID::InvalidID; + channelName = Channel ? strdup(Channel->Name()) : NULL; ownEvent = Event ? NULL : new cEvent(0); event = ownEvent ? ownEvent : Event; aux = NULL; @@ -304,6 +305,7 @@ cRecordingInfo::~cRecordingInfo() { delete ownEvent; free(aux); + free(channelName); } void cRecordingInfo::SetData(const char *Title, const char *ShortText, const char *Description) @@ -334,8 +336,11 @@ bool cRecordingInfo::Read(FILE *f) switch (*s) { case 'C': { char *p = strchr(t, ' '); - if (p) + if (p) { + free(channelName); + asprintf(&channelName, "%s", compactspace(p)); *p = 0; // strips optional channel name + } if (*t) channelID = tChannelID::FromString(t); } @@ -375,7 +380,7 @@ bool cRecordingInfo::Read(FILE *f) bool cRecordingInfo::Write(FILE *f, const char *Prefix) const { if (channelID.Valid()) - fprintf(f, "%sC %s\n", Prefix, *channelID.ToString()); + fprintf(f, "%sC %s%s%s\n", Prefix, *channelID.ToString(), channelName ? " " : "", channelName ? channelName : ""); event->Dump(f, Prefix, true); if (aux) fprintf(f, "%s@ %s\n", Prefix, aux); @@ -406,34 +411,14 @@ char *ExchangeChars(char *s, bool ToFileSystem) // The VFAT file system can't handle all characters, so we // have to take extra efforts to encode/decode them: if (ToFileSystem) { + const char *InvalidChars = "\"\\/:*?|<>#"; switch (*p) { - // characters that can be used "as is": - case '!': - case '@': - case '$': - case '%': - case '&': - case '(': - case ')': - case '+': - case ',': - case '-': - case ';': - case '=': - case '0' ... '9': - case 'a' ... 'z': - case 'A' ... 'Z': - case 'ä': case 'Ä': - case 'ö': case 'Ö': - case 'ü': case 'Ü': - case 'ß': - break; // characters that can be mapped to other characters: case ' ': *p = '_'; break; case '~': *p = '/'; break; // characters that have to be encoded: default: - if (*p != '.' || !*(p + 1) || *(p + 1) == '~') { // Windows can't handle '.' at the end of directory names + if (strchr(InvalidChars, *p) || *p == '.' && (!*(p + 1) || *(p + 1) == '~')) { // Windows can't handle '.' at the end of file/directory names int l = p - s; s = (char *)realloc(s, strlen(s) + 10); p = s + l; @@ -450,7 +435,7 @@ char *ExchangeChars(char *s, bool ToFileSystem) // mapped characters: case '_': *p = ' '; break; case '/': *p = '~'; break; - // encodes characters: + // encoded characters: case '#': { if (strlen(p) > 2) { char buf[3]; @@ -500,7 +485,7 @@ cRecording::cRecording(cTimer *Timer, const cEvent *Event) Subtitle = " "; else if (strlen(Subtitle) > MAX_SUBTITLE_LENGTH) { // let's make sure the Subtitle doesn't produce too long a file name: - strn0cpy(SubtitleBuffer, Subtitle, MAX_SUBTITLE_LENGTH); + Utf8Strn0Cpy(SubtitleBuffer, Subtitle, MAX_SUBTITLE_LENGTH); Subtitle = SubtitleBuffer; } char *macroTITLE = strstr(Timer->File(), TIMERMACRO_TITLE); diff --git a/recording.h b/recording.h index f9db505..045bb24 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 1.56 2006/12/01 15:06:07 kls Exp $ + * $Id: recording.h 1.57 2007/06/17 12:53:05 kls Exp $ */ #ifndef __RECORDING_H @@ -42,6 +42,7 @@ class cRecordingInfo { friend class cRecording; private: tChannelID channelID; + char *channelName; const cEvent *event; cEvent *ownEvent; char *aux; @@ -51,6 +52,7 @@ private: public: ~cRecordingInfo(); tChannelID ChannelID(void) const { return channelID; } + const char *ChannelName(void) const { return channelName; } const char *Title(void) const { return event->Title(); } const char *ShortText(void) const { return event->ShortText(); } const char *Description(void) const { return event->Description(); } diff --git a/skinclassic.c b/skinclassic.c index b3395a6..14be9d6 100644 --- a/skinclassic.c +++ b/skinclassic.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: skinclassic.c 1.16 2007/06/10 12:42:02 kls Exp $ + * $Id: skinclassic.c 1.17 2007/06/17 13:53:09 kls Exp $ */ #include "skinclassic.h" @@ -92,13 +92,13 @@ cSkinClassicDisplayChannel::cSkinClassicDisplayChannel(bool WithInfo) const cFont *font = cFont::GetFont(fontOsd); lineHeight = font->Height(); message = false; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - Lines * lineHeight)); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - Lines * lineHeight)); timeWidth = font->Width("00:00") + 4; - tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, Lines * lineHeight - 1, 8 } }; + tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, Lines * lineHeight - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); else { - tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, Lines * lineHeight - 1, 4 } }; + tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, Lines * lineHeight - 1, 4 } }; osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); } osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, Theme.Color(clrBackground)); @@ -187,14 +187,14 @@ cSkinClassicDisplayMenu::cSkinClassicDisplayMenu(void) const cFont *font = cFont::GetFont(fontOsd); lineHeight = font->Height(); x0 = 0; - x1 = Setup.OSDWidth; + x1 = cOsd::OsdWidth(); y0 = 0; y1 = lineHeight; y2 = y1 + lineHeight; - y5 = Setup.OSDHeight; + y5 = cOsd::OsdHeight(); y4 = y5 - lineHeight; y3 = y4 - lineHeight; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop()); tArea Areas[] = { { x0, y0, x1 - 1, y5 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -426,12 +426,12 @@ cSkinClassicDisplayReplay::cSkinClassicDisplayReplay(bool ModeOnly) int lineHeight = font->Height(); lastCurrentWidth = 0; x0 = 0; - x1 = Setup.OSDWidth; + x1 = cOsd::OsdWidth(); y0 = 0; y1 = lineHeight; y2 = 2 * lineHeight; y3 = 3 * lineHeight; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y3); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y3); tArea Areas[] = { { x0, y0, x1 - 1, y3 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -526,12 +526,12 @@ cSkinClassicDisplayVolume::cSkinClassicDisplayVolume(void) { const cFont *font = cFont::GetFont(fontOsd); int lineHeight = font->Height(); - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - lineHeight); - tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 8 } }; + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - lineHeight); + tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, lineHeight - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); else { - tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 4 } }; + tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, lineHeight - 1, 4 } }; osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); } } @@ -591,7 +591,7 @@ cSkinClassicDisplayTracks::cSkinClassicDisplayTracks(const char *Title, int NumT ItemsWidth = max(ItemsWidth, font->Width(Tracks[i])); ItemsWidth += 10; x0 = 0; - x1 = Setup.OSDWidth; + x1 = cOsd::OsdWidth(); int d = x1 - x0; if (d > ItemsWidth) { d = (d - ItemsWidth) & ~0x07; // must be multiple of 8 @@ -600,7 +600,7 @@ cSkinClassicDisplayTracks::cSkinClassicDisplayTracks(const char *Title, int NumT y0 = 0; y1 = lineHeight; y2 = y1 + NumTracks * lineHeight; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y2); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y2); tArea Areas[] = { { x0, y0, x1 - 1, y2 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -663,12 +663,12 @@ cSkinClassicDisplayMessage::cSkinClassicDisplayMessage(void) { const cFont *font = cFont::GetFont(fontOsd); int lineHeight = font->Height(); - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - lineHeight); - tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 8 } }; + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - lineHeight); + tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, lineHeight - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); else { - tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 2 } }; + tArea Areas[] = { { 0, 0, cOsd::OsdWidth() - 1, lineHeight - 1, 2 } }; osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); } } @@ -681,7 +681,7 @@ cSkinClassicDisplayMessage::~cSkinClassicDisplayMessage() void cSkinClassicDisplayMessage::SetMessage(eMessageType Type, const char *Text) { const cFont *font = cFont::GetFont(fontOsd); - osd->DrawText(0, 0, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, Setup.OSDWidth, 0, taCenter); + osd->DrawText(0, 0, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), font, cOsd::OsdWidth(), 0, taCenter); } void cSkinClassicDisplayMessage::Flush(void) diff --git a/skinsttng.c b/skinsttng.c index e359c13..4f576a7 100644 --- a/skinsttng.c +++ b/skinsttng.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: skinsttng.c 1.20 2007/06/10 12:40:43 kls Exp $ + * $Id: skinsttng.c 1.21 2007/06/17 13:51:56 kls Exp $ */ // Star Trek: The Next Generation® is a registered trademark of Paramount Pictures @@ -163,7 +163,7 @@ cSkinSTTNGDisplayChannel::cSkinSTTNGDisplayChannel(bool WithInfo) x1 = x0 + font->Width("00:00") + 4; x2 = x1 + Roundness; x3 = x2 + Gap; - x7 = Setup.OSDWidth; + x7 = cOsd::OsdWidth(); x6 = x7 - lineHeight / 2; x5 = x6 - lineHeight / 2; x4 = x5 - Gap; @@ -177,7 +177,7 @@ cSkinSTTNGDisplayChannel::cSkinSTTNGDisplayChannel(bool WithInfo) y7 = y6 + cFont::GetFont(fontSml)->Height(); int yt = (y0 + y1) / 2; int yb = (y6 + y7) / 2; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - y7)); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - y7)); tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -209,13 +209,13 @@ cSkinSTTNGDisplayChannel::cSkinSTTNGDisplayChannel(bool WithInfo) x1 = lineHeight / 2; x2 = lineHeight; x3 = x2 + Gap; - x7 = Setup.OSDWidth; + x7 = cOsd::OsdWidth(); x6 = x7 - lineHeight / 2; x5 = x6 - lineHeight / 2; x4 = x5 - Gap; y0 = 0; y1 = lineHeight; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - y1)); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - y1)); tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -374,7 +374,7 @@ cSkinSTTNGDisplayMenu::cSkinSTTNGDisplayMenu(void) x1 = lineHeight / 2; x3 = (x1 + Roundness + Gap + 7) & ~0x07; // must be multiple of 8 x2 = x3 - Gap; - x7 = Setup.OSDWidth; + x7 = cOsd::OsdWidth(); x6 = x7 - lineHeight / 2; x4 = (x6 - lineHeight / 2 - Gap) & ~0x07; // must be multiple of 8 x5 = x4 + Gap; @@ -382,13 +382,13 @@ cSkinSTTNGDisplayMenu::cSkinSTTNGDisplayMenu(void) y1 = lineHeight; y2 = y1 + Roundness; y3 = y2 + Gap; - y7 = Setup.OSDHeight; + y7 = cOsd::OsdHeight(); y6 = y7 - cFont::GetFont(fontSml)->Height(); y5 = y6 - Roundness; y4 = y5 - Gap; int yt = (y0 + y1) / 2; int yb = (y6 + y7) / 2; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop()); tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -703,7 +703,7 @@ cSkinSTTNGDisplayReplay::cSkinSTTNGDisplayReplay(bool ModeOnly) x1 = max(SymbolWidth, bm.Width()); x2 = x1 + Roundness; x3 = x2 + Gap; - x7 = Setup.OSDWidth; + x7 = cOsd::OsdWidth(); x6 = x7 - lineHeight / 2; x5 = x6 - lineHeight / 2; x4 = x5 - Gap; @@ -717,7 +717,7 @@ cSkinSTTNGDisplayReplay::cSkinSTTNGDisplayReplay(bool ModeOnly) y7 = y6 + font->Height(); int yt = (y0 + y1) / 2; int yb = (y6 + y7) / 2; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y7); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y7); tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -845,13 +845,13 @@ cSkinSTTNGDisplayVolume::cSkinSTTNGDisplayVolume(void) x1 = lineHeight / 2; x2 = lineHeight; x3 = x2 + Gap; - x7 = Setup.OSDWidth; + x7 = cOsd::OsdWidth(); x6 = x7 - lineHeight / 2; x5 = x6 - lineHeight / 2; x4 = x5 - Gap; y0 = 0; y1 = lineHeight; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y1); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1); tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -943,7 +943,7 @@ cSkinSTTNGDisplayTracks::cSkinSTTNGDisplayTracks(const char *Title, int NumTrack x1 = lineHeight / 2; x3 = (x1 + Roundness + Gap + 7) & ~0x07; // must be multiple of 8 x2 = x3 - Gap; - x7 = Setup.OSDWidth; + x7 = cOsd::OsdWidth(); x6 = x7 - lineHeight / 2; x4 = (x6 - lineHeight / 2 - Gap) & ~0x07; // must be multiple of 8 x5 = x4 + Gap; @@ -959,14 +959,14 @@ cSkinSTTNGDisplayTracks::cSkinSTTNGDisplayTracks(const char *Title, int NumTrack y1 = lineHeight; y2 = y1 + Roundness; y3 = y2 + Gap; - // limit to Setup.OSDHeight? - what if height is too big??? + // limit to cOsd::OsdHeight()? - what if height is too big??? y4 = y3 + NumTracks * lineHeight + 2 * Roundness; y5 = y4 + Gap; y6 = y5 + Roundness; y7 = y6 + cFont::GetFont(fontSml)->Height(); int yt = (y0 + y1) / 2; int yb = (y6 + y7) / 2; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y7); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y7); tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -1087,13 +1087,13 @@ cSkinSTTNGDisplayMessage::cSkinSTTNGDisplayMessage(void) x1 = lineHeight / 2; x2 = lineHeight; x3 = x2 + Gap; - x7 = Setup.OSDWidth; + x7 = cOsd::OsdWidth(); x6 = x7 - lineHeight / 2; x5 = x6 - lineHeight / 2; x4 = x5 - Gap; y0 = 0; y1 = lineHeight; - osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y1); + osd = cOsdProvider::NewOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1); tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } }; if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk) osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea)); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.c 1.60 2007/02/24 16:13:33 kls Exp $ + * $Id: thread.c 1.61 2007/06/17 12:43:40 kls Exp $ */ #include "thread.h" @@ -12,6 +12,7 @@ #include <linux/unistd.h> #include <malloc.h> #include <stdarg.h> +#include <stdlib.h> #include <sys/resource.h> #include <sys/syscall.h> #include <sys/time.h> @@ -507,7 +508,7 @@ int SystemExec(const char *Command, bool Detached) if (pid > 0) { // parent process int status = 0; - if (!Detached && waitpid(pid, &status, 0) < 0) { + if (waitpid(pid, &status, 0) < 0) { LOG_ERROR; return -1; } @@ -515,6 +516,9 @@ int SystemExec(const char *Command, bool Detached) } else { // child process if (Detached) { + // Fork again and let first child die - grandchild stays alive without parent + if (fork() > 0) + exit(0); // Start a new session pid_t sid = setsid(); if (sid < 0) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.c 1.66 2007/06/03 13:48:57 kls Exp $ + * $Id: timers.c 1.67 2007/06/16 10:41:21 kls Exp $ */ #include "timers.h" @@ -78,7 +78,7 @@ cTimer::cTimer(const cEvent *Event) *file = 0; const char *Title = Event->Title(); if (!isempty(Title)) - strn0cpy(file, Event->Title(), sizeof(file)); + Utf8Strn0Cpy(file, Event->Title(), sizeof(file)); aux = NULL; event = NULL; // let SetEvent() be called to get a log message } @@ -286,7 +286,7 @@ bool cTimer::Parse(const char *s) } //TODO add more plausibility checks result = ParseDay(daybuffer, day, weekdays); - strn0cpy(file, filebuffer, MaxFileName); + Utf8Strn0Cpy(file, filebuffer, MaxFileName); strreplace(file, '|', ':'); if (isnumber(channelbuffer)) channel = Channels.GetByNumber(atoi(channelbuffer)); @@ -358,7 +358,7 @@ time_t cTimer::SetTime(time_t t, int SecondsFromMidnight) char *cTimer::SetFile(const char *File) { if (!isempty(File)) - strn0cpy(file, File, sizeof(file)); + Utf8Strn0Cpy(file, File, sizeof(file)); return file; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.123 2007/06/09 14:21:21 kls Exp $ + * $Id: tools.c 1.129 2007/06/17 11:02:34 kls Exp $ */ #include "tools.h" @@ -649,6 +649,37 @@ int Utf8SymChars(const char *s, int Symbols) return n; } +int Utf8StrLen(const char *s) +{ + if (cCharSetConv::SystemCharacterTable()) + return strlen(s); + int n = 0; + while (*s) { + s += Utf8CharLen(s); + n++; + } + return n; +} + +char *Utf8Strn0Cpy(char *Dest, const char *Src, int n) +{ + if (cCharSetConv::SystemCharacterTable()) + return strn0cpy(Dest, Src, n); + char *d = Dest; + while (*Src) { + int sl = Utf8CharLen(Src); + n -= sl; + if (n > 0) { + while (sl--) + *d++ = *Src++; + } + else + break; + } + *d = 0; + return Dest; +} + int Utf8ToArray(const char *s, uint *a, int Size) { int n = 0; @@ -720,7 +751,7 @@ void cCharSetConv::SetSystemCharacterTable(const char *CharacterTable) { free(systemCharacterTable); systemCharacterTable = NULL; - if (!strcasestr(CharacterTable, "UTF")) { + if (!strcasestr(CharacterTable, "UTF-8")) { // Set up a map for the character values 128...255: char buf[129]; for (int i = 0; i < 128; i++) @@ -741,7 +772,7 @@ void cCharSetConv::SetSystemCharacterTable(const char *CharacterTable) const char *cCharSetConv::Convert(const char *From, char *To, size_t ToLength) { - if (cd != (iconv_t)-1) { + if (cd != (iconv_t)-1 && From && *From) { char *FromPtr = (char *)From; size_t FromLength = strlen(From); char *ToPtr = To; @@ -1105,21 +1136,39 @@ struct dirent *cReadDir::Next(void) return directory && readdir_r(directory, &u.d, &result) == 0 ? result : NULL; } -// --- cFileNameList --------------------------------------------------------- +// --- cStringList ----------------------------------------------------------- -cFileNameList::cFileNameList(const char *Directory) +cStringList::~cStringList() { - Load(Directory); + Clear(); } -cFileNameList::~cFileNameList() +int cStringList::Find(const char *s) const +{ + for (int i = 0; i < Size(); i++) { + if (!strcmp(s, At(i))) + return i; + } + return -1; +} + +void cStringList::Clear(void) { for (int i = 0; i < Size(); i++) free(At(i)); } +// --- cFileNameList --------------------------------------------------------- + +// TODO better GetFileNames(const char *Directory, cStringList *List)? +cFileNameList::cFileNameList(const char *Directory) +{ + Load(Directory); +} + bool cFileNameList::Load(const char *Directory) { + Clear(); if (Directory) { cReadDir d(Directory); struct dirent *e; @@ -1128,7 +1177,7 @@ bool cFileNameList::Load(const char *Directory) if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) Append(strdup(e->d_name)); } - Sort(CompareStrings); + Sort(); return true; } else @@ -1137,15 +1186,6 @@ bool cFileNameList::Load(const char *Directory) return false; } -int cFileNameList::Find(const char *FileName) -{ - for (int i = 0; i < Size(); i++) { - if (!strcmp(FileName, At(i))) - return i; - } - return -1; -} - // --- cFile ----------------------------------------------------------------- bool cFile::files[FD_SETSIZE] = { false }; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.98 2007/06/10 08:46:23 kls Exp $ + * $Id: tools.h 1.102 2007/06/17 11:00:20 kls Exp $ */ #ifndef __TOOLS_H @@ -92,7 +92,15 @@ int Utf8CharSet(uint c, char *s = NULL); ///< is given, only the number of bytes is returned and nothing is copied. int Utf8SymChars(const char *s, int Symbols); ///< Returns the number of character bytes at the beginning of the given - ///< string that form at most the given number of UTF-8 Symbols. + ///< string that form at most the given number of UTF-8 symbols. +int Utf8StrLen(const char *s); + ///< Returns the number of UTF-8 symbols formed by the given string of + ///< character bytes. +char *Utf8Strn0Cpy(char *Dest, const char *Src, int n); + ///< Copies at most n character bytes from Src to Dst, making sure that the + ///< resulting copy ends with a complete UTF-8 symbol. The copy is guaranteed + ///< to be zero terminated. + ///< Returns a pointer to Dest. int Utf8ToArray(const char *s, uint *a, int Size); ///< Converts the given character bytes (including the terminating 0) into an ///< array of UTF-8 symbols of the given Size. Returns the number of symbols @@ -394,7 +402,17 @@ private: mutable int allocated; mutable int size; mutable T *data; - void Realloc(int NewAllocated) const { data = (T *)realloc(data, (allocated = NewAllocated) * sizeof(T)); } + cVector(const cVector &Vector) {} // don't copy... + cVector &operator=(const cVector &Vector) { return *this; } // ...or assign this! + void Realloc(int Index) const + { + if (++Index > allocated) { + data = (T *)realloc(data, Index * sizeof(T)); + for (int i = allocated; i < Index; i++) + data[i] = T(0); + allocated = Index; + } + } public: cVector(int Allocated = 10) { @@ -406,8 +424,9 @@ public: virtual ~cVector() { free(data); } T& At(int Index) const { + Realloc(Index); if (Index >= size) - Realloc(size = Index + 1); + size = Index + 1; return data[Index]; } const T& operator[](int Index) const @@ -419,12 +438,24 @@ public: return At(Index); } int Size(void) const { return size; } + virtual void Insert(T Data, int Before = 0) + { + if (Before < size) { + Realloc(size); + memmove(&data[Before + 1], &data[Before], (size - Before) * sizeof(T)); + size++; + data[Before] = Data; + } + else + Append(Data); + } virtual void Append(T Data) { if (size >= allocated) Realloc(allocated * 4 / 2); // increase size by 50% data[size++] = Data; } + virtual void Clear(void) {} void Sort(__compar_fn_t Compare) { qsort(data, size, sizeof(T), Compare); @@ -436,12 +467,19 @@ inline int CompareStrings(const void *a, const void *b) return strcmp(*(const char **)a, *(const char **)b); } -class cFileNameList : public cVector<char *> { +class cStringList : public cVector<char *> { +public: + cStringList(int Allocated = 10): cVector<char *>(Allocated) {} + virtual ~cStringList(); + int Find(const char *s) const; + void Sort(void) { cVector<char *>::Sort(CompareStrings); } + virtual void Clear(void); + }; + +class cFileNameList : public cStringList { public: cFileNameList(const char *Directory = NULL); - virtual ~cFileNameList(); bool Load(const char *Directory); - int Find(const char *FileName); }; class cHashObject : public cListObject { @@ -22,11 +22,12 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.291 2007/06/09 12:33:53 kls Exp $ + * $Id: vdr.c 1.293 2007/06/17 11:23:08 kls Exp $ */ #include <getopt.h> #include <grp.h> +#include <langinfo.h> #include <locale.h> #include <pwd.h> #include <signal.h> @@ -493,18 +494,22 @@ int main(int argc, char *argv[]) // Set the system character table: - char *LangEnv = setlocale(LC_CTYPE, ""); - if (!LangEnv) - LangEnv = getenv("LANG"); // last resort in case locale stuff isn't installed - if (LangEnv) { - char *CodeSet = strchr(LangEnv, '.'); - if (CodeSet) { - CodeSet++; // skip the dot - bool known = SI::SetSystemCharacterTable(CodeSet); - isyslog("codeset is '%s' - %s", CodeSet, known ? "known" : "unknown"); - cCharSetConv::SetSystemCharacterTable(CodeSet); + char *CodeSet = NULL; + if (setlocale(LC_CTYPE, "")) + CodeSet = nl_langinfo(CODESET); + else { + char *LangEnv = getenv("LANG"); // last resort in case locale stuff isn't installed + if (LangEnv) { + CodeSet = strchr(LangEnv, '.'); + if (CodeSet) + CodeSet++; // skip the dot } } + if (CodeSet) { + bool known = SI::SetSystemCharacterTable(CodeSet); + isyslog("codeset is '%s' - %s", CodeSet, known ? "known" : "unknown"); + cCharSetConv::SetSystemCharacterTable(CodeSet); + } // Main program loop variables - need to be here to have them initialized before any EXIT(): @@ -545,6 +550,12 @@ int main(int argc, char *argv[]) )) EXIT(2); + if (!*cFont::GetFontFileName(Setup.FontOsd)) { + const char *msg = "no fonts available - OSD will not show any text!"; + fprintf(stderr, "vdr: %s\n", msg); + esyslog("ERROR: %s", msg); + } + // Recordings: Recordings.Update(); |