Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] [PATCH] backport of 'gaps' in the channel numbering to vdr-1.0.4



Hello @ll,
personally I was extremely happy when with vdr-1.1.14 the feature of 'gaps'
in the channel numbering was intorduced. I was eagerly awaiting the vdr-1.2
production release. But that has not happend so far. As long as file formats
are subject to change I'll stay with 1.0.4 for production purposes.

Therefore I backported this feature to vdr-1.0.4
I consider this release 'beta' as I certainly did not test everything that
might be affected by the change. But it has run flawlessly for me the last
couple of days.

@Carsten
epg2timers does not support the feature of 'gaps' in the channel numbering
:-(

@Andy
The patch does apply to the AIO-10.9. rather cleanly (IIRC 4 rejects out of
which 3 are trivial)

The below patch is desigend for the vanilla vdr-1.0.4:
----- snip -----
diff -upb vdr-1.0.4.orig/config.c vdr-1.0.4.ch-patch/config.c
--- vdr-1.0.4.orig/config.c	Sun May  5 11:07:42 2002
+++ vdr-1.0.4.ch-patch/config.c	Fri Jan 24 22:55:15 2003
@@ -188,6 +188,7 @@ char *cChannel::buffer = NULL;
 cChannel::cChannel(void)
 {
   *name = 0;
+  number       = 0;
 }
 
 cChannel::cChannel(const cChannel *Channel)
@@ -217,8 +218,12 @@ const char *cChannel::ToText(cChannel *C
      strreplace(s, ':', '|');
      }
   delete buffer;
-  if (Channel->groupSep)
+  if (Channel->groupSep) {
+     if (Channel->number)
+        asprintf(&buffer, ":@%d %s\n", Channel->number, s);
+     else
      asprintf(&buffer, ":%s\n", s);
+     }
   else {
      char apidbuf[32];
      char *q = apidbuf;
@@ -244,14 +249,18 @@ bool cChannel::Parse(const char *s)
 {
   char *buffer = NULL;
   if (*s == ':') {
-     if (*++s) {
-        strn0cpy(name, s, MaxChannelName);
-        name[strlen(name) - 1] = 0; // strip the '\n'
         groupSep = true;
-        number = 0;
+     if (*++s == '@' && *++s) {
+        char *p = NULL;
+        errno = 0;
+        int n = strtol(s, &p, 10);
+        if (!errno && p != s && n > 0) {
+           number = n;
+           s = p;
         }
-     else
-        return false;
+        }
+     strn0cpy(name, skipspace(s), MaxChannelName);
+     name[strlen(name) - 1] = 0; // strip the '\n'
      }
   else {
      groupSep = false;
@@ -779,7 +788,7 @@ bool cChannels::Load(const char *FileNam
 int cChannels::GetNextGroup(int Idx)
 {
   cChannel *channel = Get(++Idx);
-  while (channel && !channel->groupSep)
+  while (channel && !(channel->groupSep && *channel->name))
         channel = Get(++Idx);
   return channel ? Idx : -1;
 }
@@ -787,7 +796,7 @@ int cChannels::GetNextGroup(int Idx)
 int cChannels::GetPrevGroup(int Idx)
 {
   cChannel *channel = Get(--Idx);
-  while (channel && !channel->groupSep)
+  while (channel && !(channel->groupSep && *channel->name))
         channel = Get(--Idx);
   return channel ? Idx : -1;
 }
@@ -802,34 +811,38 @@ int cChannels::GetNextNormal(int Idx)
 
 void cChannels::ReNumber( void )
 {
-  int Number = 0;
-  cChannel *ch = (cChannel *)First();
-  while (ch) {
-        if (!ch->groupSep)
-           ch->number = ++Number;
-        ch = (cChannel *)ch->Next();
+  int Number = 1;
+  for (cChannel *channel = First(); channel; channel = Next(channel)) {
+      if (channel->GroupSep()) {
+         if (channel->Number() > Number)
+            Number = channel->Number();
+         }
+      else
+         channel->SetNumber(Number++);
         }
-  maxNumber = Number;
+  maxNumber = Number - 1;
 }
 
-cChannel *cChannels::GetByNumber(int Number)
+cChannel *cChannels::GetByNumber(int Number, int SkipGap)
 {
-  cChannel *channel = (cChannel *)First();
-  while (channel) {
-        if (!channel->groupSep && channel->number == Number)
+  cChannel *previous = NULL;
+  for (cChannel *channel = First(); channel; channel = Next(channel)) {
+      if (!channel->GroupSep()) {
+         if (channel->Number() == Number)
            return channel;
-        channel = (cChannel *)channel->Next();
+         else if (SkipGap && channel->Number() > Number)
+            return SkipGap > 0 ? channel : previous;
+         previous = channel;
+         }
         }
   return NULL;
 }
 
 cChannel *cChannels::GetByServiceID(unsigned short ServiceId)
 {
-  cChannel *channel = (cChannel *)First();
-  while (channel) {
-        if (!channel->groupSep && channel->pnr == ServiceId)
+  for (cChannel *channel = First(); channel; channel = Next(channel)) {
+      if (!channel->GroupSep() && channel->Sid() == ServiceId)
            return channel;
-        channel = (cChannel *)channel->Next();
         }
   return NULL;
 }
@@ -840,9 +853,9 @@ bool cChannels::SwitchTo(int Number, cDv
   return channel && channel->Switch(DvbApi);
 }
 
-const char *cChannels::GetChannelNameByNumber(int Number)
+const char *cChannels::GetChannelNameByNumber(int Number, int SkipGap)
 {
-  cChannel *channel = GetByNumber(Number);
+  cChannel *channel = GetByNumber(Number, SkipGap);
   return channel ? channel->name : NULL;
 }
 
diff -upb vdr-1.0.4.orig/config.h vdr-1.0.4.ch-patch/config.h
--- vdr-1.0.4.orig/config.h	Mon Jun 10 17:54:14 2002
+++ vdr-1.0.4.ch-patch/config.h	Thu Jan 23 02:06:53 2003
@@ -111,8 +111,13 @@ public:
   int tpid;
   int ca;
   int pnr;
+  int sid;
   int number;    // Sequence number assigned on load
   bool groupSep;
+  int Sid(void) const { return sid; }
+  int Number(void) const { return number; }
+  void SetNumber(int Number) { number = Number; }
+  bool GroupSep(void) const { return groupSep; }
   cChannel(void);
   cChannel(const cChannel *Channel);
   const char *ToText(void);
@@ -290,9 +295,9 @@ public:
   int GetPrevGroup(int Idx);   // Get previous channel group
   int GetNextNormal(int Idx);  // Get next normal channel (not group)
   void ReNumber(void);         // Recalculate 'number' based on channel
type
-  cChannel *GetByNumber(int Number);
+  cChannel *GetByNumber(int Number, int SkipGap = 0);
   cChannel *GetByServiceID(unsigned short ServiceId);
-  const char *GetChannelNameByNumber(int Number);
+  const char *GetChannelNameByNumber(int Number, int SkipGap = 0);
   bool SwitchTo(int Number, cDvbApi *DvbApi = NULL);
   int MaxNumber(void) { return maxNumber; }
   };
Common subdirectories: vdr-1.0.4.orig/libdtv and vdr-1.0.4.ch-patch/libdtv
diff -upb vdr-1.0.4.orig/menu.c vdr-1.0.4.ch-patch/menu.c
--- vdr-1.0.4.orig/menu.c	Wed May  1 16:54:10 2002
+++ vdr-1.0.4.ch-patch/menu.c	Mon Jan 27 23:47:16 2003
@@ -154,6 +154,7 @@ protected:
   virtual void Set(void);
 public:
   cMenuEditChanItem(const char *Name, int *Value);
+  virtual eOSState ProcessKey(eKeys Key);
   };
 
 cMenuEditChanItem::cMenuEditChanItem(const char *Name, int *Value)
@@ -173,6 +174,28 @@ void cMenuEditChanItem::Set(void)
   SetValue(buf);
 }
 
+eOSState cMenuEditChanItem::ProcessKey(eKeys Key)
+{
+  int delta = 1;
+
+  switch (Key) {
+    case kLeft|k_Repeat:
+    case kLeft:  delta = -1;
+    case kRight|k_Repeat:
+    case kRight:
+                 {
+                   cChannel *channel = Channels.GetByNumber(*value + delta,
delta);
+                   if (channel) {
+                      *value = channel->Number();
+                      Set();
+                      }
+                 }
+                 break;
+    default : return cMenuEditIntItem::ProcessKey(Key);
+    }
+  return osContinue;
+}
+
 // --- cMenuEditTranItem
-----------------------------------------------------
 
 class cMenuEditTranItem : public cMenuEditChanItem {
@@ -889,6 +912,7 @@ cMenuChannels::cMenuChannels(void)
   int curr = ((channel = Channels.GetByNumber(cDvbApi::CurrentChannel()))
!= NULL) ? channel->Index() : -1;
 
   while ((channel = Channels.Get(i)) != NULL) {
+     if (strlen(channel->name))
         Add(new cMenuChannelItem(i, channel), i == curr);
         i++;
         }
@@ -1210,7 +1234,12 @@ eOSState cMenuEditTimer::ProcessKey(eKey
 
   if (state == osUnknown) {
      switch (Key) {
-       case kOk:     if (!*data.file)
+       case kOk:     {
+                     if (!Channels.GetChannelNameByNumber(data.channel)) {
+                        Interface->Error(tr("*** Invalid Channel ***"));
+                        break;
+                        }
+                     if (!*data.file)
                         strcpy(data.file,
Channels.GetChannelNameByNumber(data.channel));
                      if (timer && memcmp(timer, &data, sizeof(data)) != 0)
{
                         *timer = data;
@@ -1219,6 +1248,7 @@ eOSState cMenuEditTimer::ProcessKey(eKey
                         Timers.Save();
                         isyslog(LOG_INFO, "timer %d modified (%s)",
timer->Index() + 1, timer->active ? "active" : "inactive");
                         }
+                     }
                      return osBack;
        case kRed:
        case kGreen:
@@ -2550,18 +2580,24 @@ cDisplayChannel::~cDisplayChannel()
 
 void cDisplayChannel::DisplayChannel(const cChannel *Channel)
 {
-  if (Channel && Channel->number > 0)
-     Interface->DisplayChannelNumber(Channel->number);
   int BufSize = Width() + 1;
   char buffer[BufSize];
-  if (Channel && Channel->number > 0)
+  if (Channel) {
+     if (Channel->number > 0)
      snprintf(buffer, BufSize, "%d%s  %s", Channel->number, number ? "-" :
"", Channel->name);
+     else if (Channel->name)
+        snprintf(buffer, BufSize, "%s", Channel->name);
+     }
+  else if (number)
+     snprintf(buffer, BufSize, "%d-", number);
   else
-     snprintf(buffer, BufSize, "%s", Channel ? Channel->name : tr("***
Invalid Channel ***"));
+     snprintf(buffer, BufSize, "%s", tr("*** Invalid Channel ***"));
   Interface->Fill(0, 0, Setup.OSDwidth, 1, clrBackground);
   Interface->Write(0, 0, buffer);
   const char *date = DayDateTime();
   Interface->Write(-strlen(date), 0, date);
+  if (Channel && Channel->number > 0)
+     Interface->DisplayChannelNumber(Channel->number);
 }
 
 void cDisplayChannel::DisplayInfo(void)
@@ -2637,10 +2673,6 @@ eOSState cDisplayChannel::ProcessKey(eKe
                cChannel *channel = Channels.GetByNumber(number);
                DisplayChannel(channel);
                lastTime = time_ms();
-               if (!channel) {
-                  number = -1;
-                  lastTime += 1000;
-                  }
                }
             }
          break;
@@ -2676,6 +2708,12 @@ eOSState cDisplayChannel::ProcessKey(eKe
          if (number && time_ms() - lastTime > DIRECTCHANNELTIMEOUT) {
             if (number > 0 && !Channels.SwitchTo(number))
                number = -1;
+            if (!Channels.GetByNumber(number)) {
+               number = 0;
+               DisplayChannel(NULL);
+               lastTime = time_ms();
+               return osContinue;
+               }
             return osEnd;
             }
          break;
Only in vdr-1.0.4.ch-patch: menu.c.fast
Only in vdr-1.0.4.ch-patch: menu.c.fast2
Only in vdr-1.0.4.ch-patch: menu.c.fast3
diff -upb vdr-1.0.4.orig/svdrp.c vdr-1.0.4.ch-patch/svdrp.c
--- vdr-1.0.4.orig/svdrp.c	Sat Mar 23 17:17:39 2002
+++ vdr-1.0.4.ch-patch/svdrp.c	Fri Nov 29 23:58:46 2002
@@ -402,7 +402,7 @@ void cSVDRP::CmdCHAN(const char *Option)
      else {
         int i = 1;
         cChannel *channel;
-        while ((channel = Channels.GetByNumber(i)) != NULL) {
+        while ((channel = Channels.GetByNumber(i,1)) != NULL) {
               if (strcasecmp(channel->name, Option) == 0) {
                  n = i;
                  break;
@@ -623,7 +623,7 @@ void cSVDRP::CmdLSTC(const char *Option)
         int i = 1;
         cChannel *next = NULL;
         while (i <= Channels.MaxNumber()) {
-              cChannel *channel = Channels.GetByNumber(i);
+              cChannel *channel = Channels.GetByNumber(i,1);
               if (channel) {
                  if (strcasestr(channel->name, Option)) {
                     if (next)
@@ -645,7 +645,7 @@ void cSVDRP::CmdLSTC(const char *Option)
      }
   else if (Channels.MaxNumber() >= 1) {
      for (int i = 1; i <= Channels.MaxNumber(); i++) {
-         cChannel *channel = Channels.GetByNumber(i);
+         cChannel *channel = Channels.GetByNumber(i,1);
         if (channel)
            Reply(i < Channels.MaxNumber() ? -250 : 250, "%d %s",
channel->number, channel->ToText());
         else
Only in vdr-1.0.4.ch-patch: testvdr
diff -upb vdr-1.0.4.orig/tools.h vdr-1.0.4.ch-patch/tools.h
--- vdr-1.0.4.orig/tools.h	Sun Feb 17 13:57:44 2002
+++ vdr-1.0.4.ch-patch/tools.h	Mon Dec  9 22:45:11 2002
@@ -10,7 +10,7 @@
 #ifndef __TOOLS_H
 #define __TOOLS_H
 
-//#include <errno.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
diff -upb vdr-1.0.4.orig/vdr.c vdr-1.0.4.ch-patch/vdr.c
--- vdr-1.0.4.orig/vdr.c	Fri Apr 26 14:15:30 2002
+++ vdr-1.0.4.ch-patch/vdr.c	Thu Jan 23 00:22:36 2003
@@ -447,7 +447,7 @@ int main(int argc, char *argv[])
                  case kDown|k_Repeat:
                  case kDown: {
                       int n = cDvbApi::CurrentChannel() + (NORMALKEY(key)
== kUp ? 1 : -1);
-                      cChannel *channel = Channels.GetByNumber(n);
+                      cChannel *channel = Channels.GetByNumber(n,
(NORMALKEY(key) == kUp ? 1 : -1));
                       if (channel)
                          channel->Switch();
                       break;

----- snip -----

CU,
Christian.


-- 
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe vdr" as subject.



Home | Main Index | Thread Index