[vdr] [patch] OSD language settings stored as language code (was: i18n.c sorted)

Lucian Muresan lucianm at users.sourceforge.net
Mon Nov 28 11:55:02 CET 2005


Hi,

Klaus Schmidinger wrote:
> Markus Hahn wrote:
> 
>>Hi there, 
>>now I sorted the languages as mentioned
>>in the last i18n thread. 
>>It looks realy tidy now. 
> 
> 
> Well, if you want this to go into the official VDR source
> then you should do this based on the latest version ;-)
> 
> Also, this will break the OSD language selection for many users,
> but then again this should have been stored a a three letter
> code, anyway, so this might be a good opportunity tu justify
> this break...

Attached is patch that basically does 2 things:
 1. stores OSD language selection as a 3-letter language code;
 2. unties the present hard-wired number of OSD languages to be the same
as the number of *content* languages defined in vdr.

Let me detail a bit...
- Backwards compatibility: As the order of languages (and thus, the
mapping to the indices used until now) hasn't changed, and is dictated
by the Phrases array, OSD language setting still operates internally
with the language index, plugins are not affected by this change (apart
from those reading setup.conf directly, like vdr-burn for it's external
scripts for example, but that can be easily adapted). The only thing
that is visible after using this patch is that on the first start of
VDR, the default language is used (English).
- At present, this patch uses the 3-letter language code used for EPG
and audio languages (and the number of codes and languages also is the
same defined for audio and epg), but if for example, in the future,
external language files would be used, this code could be something
else, and the change to that new scheme would also just have VDR present
itself in the default language in *that* new language system. For
example, if gettext would be used, then the code needed for setlocale
(LC_ALL, "de_DE at euro") would be stored as the OSD language selection.

Lucian

P.S. regarding gettext i18n, yes, I worked on it and because an i18n
system with external language files needs to be flexible with respect to
number of languages, the separation of OSD languages from content
languages, as well as storing the OSD language selection as a string is
benefic to this. BTW, gettext i18n is working well (just the non-cached
implementation ready yet), and I'll soon post a patch for those interested.
-------------- next part --------------
diff -Naur vdr-1.3.37_orig/config.c vdr-1.3.37/config.c
--- vdr-1.3.37_orig/config.c	2005-09-09 17:08:59.000000000 +0200
+++ vdr-1.3.37/config.c	2005-11-28 10:18:25.520000000 +0100
@@ -401,9 +401,41 @@
   return true;
 }
 
+void cSetup::StoreOsdLanguage(const char *Name, int & IdxVal, const char * const *OsdLangVals)
+{
+  char * valuestring = NULL;
+  if (OsdLangVals[IdxVal][3] == ',') {
+    // if it's the 3-letter code which might be followed by
+    // a comma and another 3-letter code, just store the first code
+    char buff[4];
+    strncpy(buff, OsdLangVals[IdxVal], 3);
+    buff[3] = '\0';
+    valuestring = strdup(buff);
+  }
+  else {
+    // it's either a single code, or in a possible future gettext version,
+    // the locale, which could be longer, like 'de_DE at euro'
+    valuestring = strdup(OsdLangVals[IdxVal]);
+  }
+  Store(Name, valuestring);
+}
+
+bool cSetup::ParseOsdLanguage(const char *Value, int & IdxVal, int NumOsdLangs, const char * const *OsdLangVals)
+{
+  for(int i = 0; i < NumOsdLangs; i++) {
+    if (strcmp(Value, OsdLangVals[i]) == 0 || // first compare the strings on their whole length
+        (OsdLangVals[i][3] == ',' &&          // one more chance, maybe we're still using the 3-letter codes
+          strncmp(Value, OsdLangVals[i], strlen(Value)) == 0) ) {
+      IdxVal = i;
+      return true;
+    }
+  }
+  return false;
+}
+
 bool cSetup::Parse(const char *Name, const char *Value)
 {
-  if      (!strcasecmp(Name, "OSDLanguage"))         OSDLanguage        = atoi(Value);
+  if      (!strcasecmp(Name, "OSDLanguage"))         return ParseOsdLanguage(Value, OSDLanguage, I18nNumOsdLangs, I18nOsdLangCodes());
   else if (!strcasecmp(Name, "OSDSkin"))             strn0cpy(OSDSkin, Value, MaxSkinName);
   else if (!strcasecmp(Name, "OSDTheme"))            strn0cpy(OSDTheme, Value, MaxThemeName);
   else if (!strcasecmp(Name, "PrimaryDVB"))          PrimaryDVB         = atoi(Value);
@@ -468,7 +500,7 @@
 
 bool cSetup::Save(void)
 {
-  Store("OSDLanguage",        OSDLanguage);
+  StoreOsdLanguage("OSDLanguage", OSDLanguage, I18nOsdLangCodes());
   Store("OSDSkin",            OSDSkin);
   Store("OSDTheme",           OSDTheme);
   Store("PrimaryDVB",         PrimaryDVB);
diff -Naur vdr-1.3.37_orig/config.h vdr-1.3.37/config.h
--- vdr-1.3.37_orig/config.h	2005-11-11 14:22:02.000000000 +0100
+++ vdr-1.3.37/config.h	2005-11-28 10:14:26.330000000 +0100
@@ -202,6 +202,8 @@
   cSetupLine *Get(const char *Name, const char *Plugin = NULL);
   void Store(const char *Name, const char *Value, const char *Plugin = NULL, bool AllowMultiple = false);
   void Store(const char *Name, int Value, const char *Plugin = NULL);
+  void StoreOsdLanguage(const char *Name, int & IdxVal, const char * const *OsdLangVals);
+  bool ParseOsdLanguage(const char *Value, int & IdxVal, int NumOsdLangs, const char * const *OsdLangVals);
 public:
   // Also adjust cMenuSetup (menu.c) when adding parameters here!
   int __BeginData__;
diff -Naur vdr-1.3.37_orig/i18n.c vdr-1.3.37/i18n.c
--- vdr-1.3.37_orig/i18n.c	2005-11-04 15:36:27.000000000 +0100
+++ vdr-1.3.37/i18n.c	2005-11-28 10:22:19.060000000 +0100
@@ -5520,6 +5520,12 @@
 
 cI18nList I18nList;
 
+// number of OSD languages, for now identical with I18nNumLanguages,
+// but with external OSD language files, the number could become different
+// from the number of defined content languages
+int I18nNumOsdLangs = I18nNumLanguages;
+
+
 // ---
 
 void I18nRegister(const tI18nPhrase * const Phrases, const char *Plugin)
@@ -5563,6 +5569,27 @@
   return &Phrases[1][0];
 }
 
+const char * const * I18nOsdLangCodes(void)
+{
+  // for now, similar to I18nLanguageCode(int Index), but could use different identifiers,
+  //like 'de_DE at euro' in the future
+  return &Phrases[2][0];
+}
+
+const char * const * I18nOsdLanguages(void)
+{
+  // for now, identical with I18nLanguages(), but the size of this array could be different
+  // in the future, with external OSD languages
+  return &Phrases[0][0];
+}
+
+int I18nOsdLanguageIndex(const char *Code)
+{
+  // for now, identical with I18nLanguageIndex(const char *Code), but the size and
+  // identifiers in this array could be different in the future, with external OSD languages
+  return I18nLanguageIndex(Code);
+}
+
 const char *I18nLanguageCode(int Index)
 {
   return 0 <= Index && Index < I18nNumLanguages ? Phrases[2][Index] : NULL;
diff -Naur vdr-1.3.37_orig/i18n.h vdr-1.3.37/i18n.h
--- vdr-1.3.37_orig/i18n.h	2005-09-09 16:50:35.000000000 +0200
+++ vdr-1.3.37/i18n.h	2005-11-28 10:14:26.350000000 +0100
@@ -13,6 +13,7 @@
 #include <stdio.h>
 
 const int I18nNumLanguages = 20;
+extern int I18nNumOsdLangs;
 
 typedef const char *tI18nPhrase[I18nNumLanguages];
 
@@ -22,6 +23,9 @@
 
 const char * const * I18nLanguages(void);
 const char * const * I18nCharSets(void);
+const char * const * I18nOsdLangCodes(void);
+const char * const * I18nOsdLanguages(void);
+int I18nOsdLanguageIndex(const char *Code);
 const char *I18nLanguageCode(int Index);
 int I18nLanguageIndex(const char *Code);
 const char *I18nNormalizeLanguageCode(const char *Code);
diff -Naur vdr-1.3.37_orig/menu.c vdr-1.3.37/menu.c
--- vdr-1.3.37_orig/menu.c	2005-11-05 18:29:22.000000000 +0100
+++ vdr-1.3.37/menu.c	2005-11-28 10:14:26.350000000 +0100
@@ -1863,7 +1863,7 @@
   useSmallFontTexts[2] = tr("always");
   Clear();
   SetSection(tr("OSD"));
-  Add(new cMenuEditStraItem(tr("Setup.OSD$Language"),               &data.OSDLanguage, I18nNumLanguages, I18nLanguages()));
+  Add(new cMenuEditStraItem(tr("Setup.OSD$Language"),               &data.OSDLanguage, I18nNumOsdLangs, I18nOsdLanguages()));
   Add(new cMenuEditStraItem(tr("Setup.OSD$Skin"),                   &skinIndex, numSkins, skinDescriptions));
   if (themes.NumThemes())
   Add(new cMenuEditStraItem(tr("Setup.OSD$Theme"),                  &themeIndex, themes.NumThemes(), themes.Descriptions()));
diff -Naur vdr-1.3.37_orig/themes.c vdr-1.3.37/themes.c
--- vdr-1.3.37_orig/themes.c	2005-11-04 15:19:54.000000000 +0100
+++ vdr-1.3.37/themes.c	2005-11-28 10:14:26.350000000 +0100
@@ -114,7 +114,7 @@
                     int lang = 0;
                     char *l = strchr(n, '.');
                     if (l)
-                       lang = I18nLanguageIndex(++l);
+                       lang = I18nOsdLanguageIndex(++l);
                     if (lang >= 0) {
                        free(descriptions[lang]);
                        descriptions[lang] = strdup(v);
@@ -167,9 +167,9 @@
   bool result = true;
   cSafeFile f(FileName);
   if (f.Open()) {
-     for (int i = 0; i < I18nNumLanguages; i++) {
+     for (int i = 0; i < I18nNumOsdLangs; i++) {
          if (descriptions[i])
-            fprintf(f, "Description%s%.*s = %s\n", i ? "." : "", 3, i ? I18nLanguageCode(i) : "", descriptions[i]);
+            fprintf(f, "Description%s%.*s = %s\n", i ? "." : "", 3, i ? I18nOsdLangCodes()[i] : "", descriptions[i]);
          }
      for (int i = 0; i < MaxThemeColors; i++) {
          if (colorNames[i])


More information about the vdr mailing list