commit:     9d46db8a3ad5348d8e029770bdf99f11fe56e2f3
Author:     Martin Dummer <martin.dummer <AT> gmx <DOT> net>
AuthorDate: Sat Feb  7 12:33:46 2026 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Feb 11 07:47:54 2026 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=9d46db8a

media-video/vdr: add 2.7.9

Signed-off-by: Martin Dummer <martin.dummer <AT> gmx.net>
Part-of: https://github.com/gentoo/gentoo/pull/45665
Closes: https://github.com/gentoo/gentoo/pull/45665
Signed-off-by: Sam James <sam <AT> gentoo.org>

 media-video/vdr/Manifest                        |   4 +
 media-video/vdr/files/vdr-2.7.9_pinplugin.patch | 430 ++++++++++++++++++++++++
 media-video/vdr/vdr-2.7.9.ebuild                | 198 +++++++++++
 3 files changed, 632 insertions(+)

diff --git a/media-video/vdr/Manifest b/media-video/vdr/Manifest
index 69d88a33a5f3..609aecf4e9e1 100644
--- a/media-video/vdr/Manifest
+++ b/media-video/vdr/Manifest
@@ -4,4 +4,8 @@ DIST vdr-2.7.7.tbz2 960454 BLAKE2B 
ce4961fb40fc62ead50cb7a39f2a539b5c08fdce494d9
 DIST vdr-2.7.7_naludump.patch 20054 BLAKE2B 
4c326c71b60d7d46cb5c846be7c415d41bde01920b28dc102e8f0f85dd59e1d489c5e042a5c35e131e5aebac042a58dfd49f584d1efb0362446111e8a2c347b1
 SHA512 
c6d467ad37cfd34eef6da83506140b563269b16a06fecf40b6d61b0c75b8019b353d3c740766b65f0a656770b185f51eec6bb08760c03ba9aba275c7846d6a79
 DIST vdr-2.7.7_patch-for-permashift.patch 15401 BLAKE2B 
c73a0b66745cbb3b97d7678e4f5597cf8be1b5153126967fa8d16ad2ee1db070ad521688d00d291392f83f7309de8210f8a170026db9f9cf90f3b39d90c75db7
 SHA512 
11fc1c2599687dcf774253295e3ce9bc7ef890c5e40102d183242b59d228ff0828151d5b40e6c6015f1140f077f24e32373dee15eeb972fe89aee40bf3d4589c
 DIST vdr-2.7.7_ttxtsubs_v2.patch 38346 BLAKE2B 
8244793a77fadfe0aed84fbb1e2bb24abd45dde37c81a4b788c515231f860d79c84a0ede0509d3b599b7408d2d0909365d5b26c09fa62569e762e2981c3cb587
 SHA512 
4f8b9a92bea821f93bae5dec9aaea6a678b4599eb73e5b9574a656d3a893dad7103478c118d1424b754384e317b7e6820aa16e9c7c0a486285cd52be27a1facc
+DIST vdr-2.7.9.tbz2 968743 BLAKE2B 
b8e372feec7c54a47adcb57f6ca0df8e09f4432ba34f29571d88176687247a54a598e1eec876d4703d59a3aaf8a98e8c59b7dfebdadbd4a4dd027fef3088e796
 SHA512 
87b1c900dd8cbbc82346f6ebaf2e157de3504f04d0231a53810768a42cef94391bd15b677bdfb003a481eac3e40b0b155ff7f64930e7bc1cb701c3824c94ac27
+DIST vdr-2.7.9_naludump.patch 21820 BLAKE2B 
cbd844652040992294c8abbc682212d83c1c95c434983975ceffab2793352688dfd67113634666a5110d3e8e62221f640018b063d68e0a12699934b7aa607758
 SHA512 
70be1f8ff42d59c2bbf11974251aa214a74aad6ea522e96a15356b45dcb4f7bea61749ca81dd9eeffd7bb23385be35649a5ecd229cc62d6436956901fb5decad
+DIST vdr-2.7.9_patch-for-permashift.patch 15401 BLAKE2B 
c73a0b66745cbb3b97d7678e4f5597cf8be1b5153126967fa8d16ad2ee1db070ad521688d00d291392f83f7309de8210f8a170026db9f9cf90f3b39d90c75db7
 SHA512 
11fc1c2599687dcf774253295e3ce9bc7ef890c5e40102d183242b59d228ff0828151d5b40e6c6015f1140f077f24e32373dee15eeb972fe89aee40bf3d4589c
+DIST vdr-2.7.9_ttxtsubs_v2.patch 38346 BLAKE2B 
8244793a77fadfe0aed84fbb1e2bb24abd45dde37c81a4b788c515231f860d79c84a0ede0509d3b599b7408d2d0909365d5b26c09fa62569e762e2981c3cb587
 SHA512 
4f8b9a92bea821f93bae5dec9aaea6a678b4599eb73e5b9574a656d3a893dad7103478c118d1424b754384e317b7e6820aa16e9c7c0a486285cd52be27a1facc
 DIST vdr-menuorg-2.3.x.diff 8852 BLAKE2B 
19b98d51a69f52ecda5500f51ef1741a8397953b20c490055eab0393da5f56ff9598c3e1e8ed8b915f5877e08deeb9ba7a9ef8d9356ad3a1fa12e3778869174a
 SHA512 
7b41c3a529858a4953a57f21619ea01864e140cc1755ee0b03caf1c4de41e80c3f805653502bc8d39d02a4dfcddf720acd4a8c8bd91f4871eef31d86e8e915c0

diff --git a/media-video/vdr/files/vdr-2.7.9_pinplugin.patch 
b/media-video/vdr/files/vdr-2.7.9_pinplugin.patch
new file mode 100644
index 000000000000..d04a75cb1a18
--- /dev/null
+++ b/media-video/vdr/files/vdr-2.7.9_pinplugin.patch
@@ -0,0 +1,430 @@
+diff '--color=auto' -Naur a/device.c b/device.c
+--- a/device.c 2026-01-21 21:19:59.000000000 +0100
++++ b/device.c 2026-01-25 19:23:09.240333805 +0100
+@@ -857,6 +857,7 @@
+      const cChannel *Channel;
+      while ((Channel = Channels->GetByNumber(n, Direction)) != NULL) {
+            // try only channels which are currently available
++           if (!cStatus::MsgChannelProtected(0, Channel))      // PIN PATCH
+            if (GetDevice(Channel, LIVEPRIORITY, true, true))
+               break;
+            n = Channel->Number() + Direction;
+@@ -878,6 +879,12 @@
+ 
+ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
+ {
++  // I hope 'LiveView = false' indicates a channel switch for recording, // 
PIN PATCH
++  // I really don't know, but it works ...                               // 
PIN PATCH
++
++  if (LiveView && cStatus::MsgChannelProtected(this, Channel))           // 
PIN PATCH
++     return scrNotAvailable;                                             // 
PIN PATCH
++
+   cMutexLock MutexLock(&mutexChannel); // to avoid a race between SVDRP CHAN 
and HasProgramme()
+   cStatus::MsgChannelSwitch(this, 0, LiveView);
+ 
+diff '--color=auto' -Naur a/menu.c b/menu.c
+--- a/menu.c   2026-01-21 21:19:59.000000000 +0100
++++ b/menu.c   2026-01-25 19:36:45.321964680 +0100
+@@ -1037,6 +1037,18 @@
+      Add(new cMenuEditBitItem( tr("VPS"),          &data.flags, tfVps));
+      Add(new cMenuEditIntItem( tr("Priority"),     &data.priority, 0, 
MAXPRIORITY));
+      Add(new cMenuEditIntItem( tr("Lifetime"),     &data.lifetime, 0, 
MAXLIFETIME));
++
++     // PIN PATCH
++     if (cOsd::pinValid || !data.fskProtection) Add(new 
cMenuEditBoolItem(tr("Childlock"),&data.fskProtection));
++     else {
++        char* buf = 0;
++        int res = 0;
++        res = asprintf(&buf, "%s\t%s", tr("Childlock"), data.fskProtection ? 
tr("yes") : tr("no"));
++        if (res < 0) ; // memory problems :o
++        Add(new cOsdItem(buf));
++        free(buf);
++        }
++
+      Add(file = new cMenuEditStrItem( tr("File"),   data.file, 
sizeof(data.file)));
+      SetFirstDayItem();
+      SetPatternItem(true);
+@@ -3195,7 +3207,8 @@
+                       }
+                    }
+                }
+-            if (*Item->Text() && !LastDir) {
++            if (*Item->Text() && !LastDir
++                && (!cStatus::MsgReplayProtected(Item->Recording(), 
Item->Name(), base, Item->IsDirectory(), true))) { // PIN PATCH
+                Add(Item);
+                LastItem = Item;
+                if (Item->IsDirectory())
+@@ -3275,6 +3288,9 @@
+ {
+   cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
+   if (ri) {
++     if (cStatus::MsgReplayProtected(ri->Recording(), ri->Name(), base,
++                                     ri->IsDirectory()) == true)    // PIN 
PATCH
++        return osContinue;
+      if (ri->IsDirectory())
+         Open();
+      else {
+@@ -4697,28 +4713,32 @@
+ 
+   // Basic menu items:
+ 
+-  Add(new cOsdItem(hk(tr("Schedule")),   osSchedule));
+-  Add(new cOsdItem(hk(tr("Channels")),   osChannels));
+-  Add(new cOsdItem(hk(tr("Timers")),     osTimers));
+-  Add(new cOsdItem(hk(tr("Recordings")), osRecordings));
++  // PIN PATCH
++  if (!cStatus::MsgMenuItemProtected("Schedule", true))   Add(new 
cOsdItem(hk(tr("Schedule")),   osSchedule));
++  if (!cStatus::MsgMenuItemProtected("Channels", true))   Add(new 
cOsdItem(hk(tr("Channels")),   osChannels));
++  if (!cStatus::MsgMenuItemProtected("Timers", true))     Add(new 
cOsdItem(hk(tr("Timers")),     osTimers));
++  if (!cStatus::MsgMenuItemProtected("Recordings", true)) Add(new 
cOsdItem(hk(tr("Recordings")), osRecordings));
+ 
+   // Plugins:
+ 
+   for (int i = 0; ; i++) {
+       cPlugin *p = cPluginManager::GetPlugin(i);
+       if (p) {
++         if (!cStatus::MsgPluginProtected(p, true)) {          // PIN PATCH
+          const char *item = p->MainMenuEntry();
+          if (item)
+             Add(new cMenuPluginItem(hk(item), i));
+          }
++      }
+       else
+          break;
+       }
+ 
+   // More basic menu items:
+ 
+-  Add(new cOsdItem(hk(tr("Setup")),      osSetup));
++  if (!cStatus::MsgMenuItemProtected("Setup", true)) Add(new 
cOsdItem(hk(tr("Setup")), osSetup));  // PIN PATCH
+   if (Commands.Count())
++     if (!cStatus::MsgMenuItemProtected("Commands", true))     // PIN PATCH
+      Add(new cOsdItem(hk(tr("Button$Commands")),  osCommands));
+ 
+   Update(true);
+@@ -4791,6 +4811,14 @@
+   eOSState state = cOsdMenu::ProcessKey(Key);
+   HadSubMenu |= HasSubMenu();
+ 
++  // > PIN PATCH
++  cOsdItem* item = Get(Current());
++
++  if (item && item->Text() && state != osContinue && state != osUnknown && 
state != osBack)
++     if (cStatus::MsgMenuItemProtected(item->Text()))
++        return osContinue;
++  // PIN PATCH <
++
+   switch (state) {
+     case osSchedule:   return AddSubMenu(new cMenuSchedule);
+     case osChannels:   return AddSubMenu(new cMenuChannels);
+@@ -4817,6 +4845,7 @@
+                          if (item) {
+                             cPlugin *p = 
cPluginManager::GetPlugin(item->PluginIndex());
+                             if (p) {
++                            if (!cStatus::MsgPluginProtected(p)) {  // PIN 
PATCH
+                                cOsdObject *menu = p->MainMenuAction();
+                                if (menu) {
+                                   if (menu->IsMenu())
+@@ -4828,6 +4857,7 @@
+                                   }
+                                }
+                             }
++                         }
+                          state = osEnd;
+                        }
+                        break;
+@@ -5008,6 +5038,7 @@
+            Channel = Direction > 0 ? Channels->Next(Channel) : 
Channels->Prev(Channel);
+            if (!Channel && Setup.ChannelsWrap)
+               Channel = Direction > 0 ? Channels->First() : Channels->Last();
++           if (!cStatus::MsgChannelProtected(0, Channel))                   
// PIN PATCH
+            if (Channel && !Channel->GroupSep() && cDevice::GetDevice(Channel, 
LIVEPRIORITY, true, true))
+               return Channel;
+            }
+@@ -5689,6 +5720,7 @@
+            for (int i = 0; i < MAXRECORDCONTROLS; i++) {
+                if (!RecordControls[i]) {
+                   RecordControls[i] = new cRecordControl(device, Timers, 
Timer, Pause);
++                  cStatus::MsgRecordingFile(RecordControls[i]->FileName());  
// PIN PATCH
+                   return RecordControls[i]->Process(time(NULL));
+                   }
+                }
+diff '--color=auto' -Naur a/osd.c b/osd.c
+--- a/osd.c    2026-01-21 21:19:59.000000000 +0100
++++ b/osd.c    2026-01-25 19:23:09.244333798 +0100
+@@ -1907,6 +1907,7 @@
+ cSize cOsd::maxPixmapSize(INT_MAX, INT_MAX);
+ cVector<cOsd *> cOsd::Osds;
+ cMutex cOsd::mutex;
++bool cOsd::pinValid = false;   // PIN PATCH
+ 
+ cOsd::cOsd(int Left, int Top, uint Level)
+ {
+diff '--color=auto' -Naur a/osd.h b/osd.h
+--- a/osd.h    2026-01-21 21:19:59.000000000 +0100
++++ b/osd.h    2026-01-25 19:23:09.244333798 +0100
+@@ -994,6 +994,7 @@
+        ///<
+        ///< If a plugin uses a derived cPixmap implementation, it needs to 
use that
+        ///< type instead of cPixmapMemory.
++  static bool pinValid;   // PIN PATCH
+   };
+ 
+ #define MAXOSDIMAGES 64
+diff '--color=auto' -Naur a/status.c b/status.c
+--- a/status.c 2026-01-21 21:19:59.000000000 +0100
++++ b/status.c 2026-01-25 19:23:09.244333798 +0100
+@@ -143,3 +143,55 @@
+   for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
+       sm->OsdProgramme(PresentTime, PresentTitle, PresentSubtitle, 
FollowingTime, FollowingTitle, FollowingSubtitle);
+ }
++
++bool cStatus::MsgChannelProtected(const cDevice* Device, const cChannel* 
Channel)     // PIN PATCH
++{
++  for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++      if (sm->ChannelProtected(Device, Channel) == true)
++       return true;
++
++  return false;
++}
++
++bool cStatus::MsgReplayProtected(const cRecording* Recording, const char* 
Name,
++                                 const char* Base, bool isDirectory, int 
menuView)    // PIN PATCH
++{
++  for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++     if (sm->ReplayProtected(Recording, Name, Base, isDirectory, menuView) == 
true)
++         return true;
++      return false;
++}
++
++void cStatus::MsgRecordingFile(const char* FileName)
++{
++  for (cStatus *sm = statusMonitors.First(); sm; sm = 
statusMonitors.Next(sm))   // PIN PATCH
++      sm->RecordingFile(FileName);
++}
++
++void cStatus::MsgTimerCreation(cTimer* Timer, const cEvent *Event)
++{
++  for (cStatus *sm = statusMonitors.First(); sm; sm = 
statusMonitors.Next(sm))   // PIN PATCH
++     sm->TimerCreation(Timer, Event);
++}
++
++bool cStatus::MsgPluginProtected(cPlugin* Plugin, int menuView)               
   // PIN PATCH
++{
++  for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++     if (sm->PluginProtected(Plugin, menuView) == true)
++         return true;
++      return false;
++}
++
++void cStatus::MsgUserAction(const eKeys key)                                  
   // PIN PATCH
++{
++  for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++     sm->UserAction(key);
++}
++
++bool cStatus::MsgMenuItemProtected(const char* Name, int menuView)            
   // PIN PATCH
++{
++  for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
++     if (sm->MenuItemProtected(Name, menuView) == true)
++         return true;
++      return false;
++}
+diff '--color=auto' -Naur a/status.h b/status.h
+--- a/status.h 2026-01-21 21:19:59.000000000 +0100
++++ b/status.h 2026-01-25 19:23:09.244333798 +0100
+@@ -15,6 +15,7 @@
+ #include "player.h"
+ #include "skins.h"
+ #include "tools.h"
++#include "plugin.h"
+ 
+ // Several member functions of the following classes are called with a 
pointer to
+ // an object from a global list (cTimer, cChannel, cRecording or cEvent). In 
these
+@@ -105,6 +106,22 @@
+                // The OSD displays the single line Text with the current 
channel information.
+   virtual void OsdProgramme(time_t PresentTime, const char *PresentTitle, 
const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, 
const char *FollowingSubtitle) {}
+                // The OSD displays the given programme information.
++  virtual bool ChannelProtected(const cDevice *Device, const cChannel* 
Channel)  { return false; }         // PIN PATCH
++               // Checks if a channel is protected.
++  virtual bool ReplayProtected(const cRecording* Recording, const char* Name,
++                               const char* Base, bool isDirectory, int 
menuView = false) { return false; } // PIN PATCH
++               // Checks if a recording is protected.
++  virtual void RecordingFile(const char* FileName) {}                         
                             // PIN PATCH
++               // The given DVB device has started recording to FileName. 
FileName is the name of the
++               // recording directory
++  virtual void TimerCreation(cTimer* Timer, const cEvent *Event) {}           
                             // PIN PATCH
++               // The given timer is created
++  virtual bool PluginProtected(cPlugin* Plugin, int menuView = false)  { 
return false; }                   // PIN PATCH
++               // Checks if a plugin is protected.
++  virtual void UserAction(const eKeys key) {}                                 
                             // PIN PATCH
++               // report user action
++  virtual bool MenuItemProtected(const char* Name, int menuView = false)  { 
return false; }                // PIN PATCH
++
+ public:
+   cStatus(void);
+   virtual ~cStatus() override;
+@@ -130,6 +147,14 @@
+   static void MsgOsdTextItem(const char *Text,  bool Scroll = false);
+   static void MsgOsdChannel(const char *Text);
+   static void MsgOsdProgramme(time_t PresentTime, const char *PresentTitle, 
const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, 
const char *FollowingSubtitle);
++  static bool MsgChannelProtected(const cDevice* Device, const cChannel* 
Channel);                 // PIN PATCH
++  static bool MsgReplayProtected(const cRecording* Recording, const char* 
Name,
++                                 const char* Base, bool isDirectory, int 
menuView = false);        // PIN PATCH
++  static void MsgRecordingFile(const char* FileName);                         
                     // PIN PATCH
++  static void MsgTimerCreation(cTimer* Timer, const cEvent *Event);           
                     // PIN PATCH
++  static bool MsgPluginProtected(cPlugin* Plugin, int menuView = false);      
                     // PIN PATCH
++  static void MsgUserAction(const eKeys key);                                 
                     // PIN PATCH
++  static bool MsgMenuItemProtected(const char* Name, int menuView = false);   
                     // PIN PATCH
+   };
+ 
+ #endif //__STATUS_H
+diff '--color=auto' -Naur a/timers.c b/timers.c
+--- a/timers.c 2026-01-21 21:19:59.000000000 +0100
++++ b/timers.c 2026-01-25 19:23:09.244333798 +0100
+@@ -85,6 +85,7 @@
+      stop -= 2400;
+   priority = Pause ? Setup.PausePriority : Setup.DefaultPriority;
+   lifetime = Pause ? Setup.PauseLifetime : Setup.DefaultLifetime;
++  fskProtection = 0;                                        // PIN PATCH
+   if (Instant && channel)
+      snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", 
*Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name());
+ }
+@@ -220,11 +221,13 @@
+      stop -= 2400;
+   priority = PatternTimer ? PatternTimer->Priority() : Setup.DefaultPriority;
+   lifetime = PatternTimer ? PatternTimer->Lifetime() : Setup.DefaultLifetime;
++  fskProtection = 0;                                        // PIN PATCH
+   if (!FileName)
+      FileName = Event->Title();
+   if (!isempty(FileName))
+      Utf8Strn0Cpy(file, FileName, sizeof(file));
+   SetEvent(Event);
++  cStatus::MsgTimerCreation(this, Event);                   // PIN PATCH
+ }
+ 
+ cTimer::cTimer(const cTimer &Timer)
+@@ -263,6 +266,7 @@
+      stop         = Timer.stop;
+      priority     = Timer.priority;
+      lifetime     = Timer.lifetime;
++     fskProtection = Timer.fskProtection;    // PIN PATCH
+      vpsNotRunning = 0;
+      vpsActive    = false;
+      strncpy(pattern, Timer.pattern, sizeof(pattern));
+@@ -496,6 +500,7 @@
+         result = false;
+         }
+      }
++  fskProtection = aux && strstr(aux, 
"<pin-plugin><protected>yes</protected></pin-plugin>");  // PIN PATCH
+   free(channelbuffer);
+   free(daybuffer);
+   free(filebuffer);
+@@ -1163,6 +1168,36 @@
+   Matches(); // refresh start and end time
+ }
+ 
++void cTimer::SetFskProtection(int aFlag)      // PIN PATCH
++{
++   char* p;
++   char* tmp = 0;
++   int res = 0;
++
++   fskProtection = aFlag;
++
++   if (fskProtection && (!aux || !strstr(aux, 
"<pin-plugin><protected>yes</protected></pin-plugin>")))
++   {
++      // add protection info to aux
++
++      if (aux) { tmp = strdup(aux); free(aux); }
++      res = asprintf(&aux, 
"%s<pin-plugin><protected>yes</protected></pin-plugin>", tmp ? tmp : "");
++   }
++   else if (!fskProtection && aux && (p = strstr(aux, 
"<pin-plugin><protected>yes</protected></pin-plugin>")))
++   {
++      // remove protection info from aux
++
++      res = asprintf(&tmp, "%.*s%s", (int)(p-aux), aux, 
p+strlen("<pin-plugin><protected>yes</protected></pin-plugin>"));
++      free(aux);
++      aux = strdup(tmp);
++   }
++
++   if (res < 0) ; // memory problems :o
++
++   if (tmp)
++      free(tmp);
++}
++
+ // --- cTimers ---------------------------------------------------------------
+ 
+ cTimers cTimers::timers;
+diff '--color=auto' -Naur a/timers.h b/timers.h
+--- a/timers.h 2026-01-21 21:19:59.000000000 +0100
++++ b/timers.h 2026-01-25 19:23:09.244333798 +0100
+@@ -48,6 +48,7 @@
+   int start;          ///< the start and stop time of this timer as given by 
the user,
+   int stop;           ///< in the form hhmm, with hh (00..23) and mm (00..59) 
added as hh*100+mm
+   int priority;
++  int fskProtection;                                               // PIN 
PATCH
+   int lifetime;
+   mutable char pattern[NAME_MAX * 2 + 1]; // same size as 'file', to be able 
to initially fill 'pattern' with 'file' in the 'Edit timer' menu
+   mutable char file[NAME_MAX * 2 + 1]; // *2 to be able to hold 'title' and 
'episode', which can each be up to 255 characters long
+@@ -73,6 +74,7 @@
+   int Start(void) const { return start; }
+   int Stop(void) const { return stop; }
+   int Priority(void) const { return priority; }
++  int FskProtection(void) const { return fskProtection; }          // PIN 
PATCH
+   int Lifetime(void) const { return lifetime; }
+   const char *Pattern(void) const { return pattern; }
+   const char *File(void) const { return file; }
+@@ -151,6 +153,7 @@
+   void SetRemote(const char *Remote);
+   void SetDeferred(int Seconds);
+   void SetFlags(uint Flags);
++  void SetFskProtection(int aFlag);                                // PIN 
PATCH
+   void ClrFlags(uint Flags);
+   void InvFlags(uint Flags);
+   bool HasFlags(uint Flags) const;
+diff '--color=auto' -Naur a/vdr.c b/vdr.c
+--- a/vdr.c    2026-01-21 21:19:59.000000000 +0100
++++ b/vdr.c    2026-01-25 19:23:09.248333791 +0100
+@@ -72,6 +72,7 @@
+ #include "tools.h"
+ #include "transfer.h"
+ #include "videodir.h"
++#include "status.h"     // PIN PATCH
+ 
+ #define MINCHANNELWAIT        10 // seconds to wait between failed channel 
switchings
+ #define ACTIVITYTIMEOUT       60 // seconds before starting housekeeping
+@@ -1218,6 +1219,7 @@
+         if (!Menu)
+            Interact = Control = cControl::Control(ControlMutexLock);
+         if (ISREALKEY(key)) {
++           cStatus::MsgUserAction(key);           // PIN PATCH
+            EITScanner.Activity();
+            // Cancel shutdown countdown:
+            if (ShutdownHandler.countdown)
+@@ -1290,10 +1292,12 @@
+                      Control->Hide();
+                   cPlugin *plugin = cPluginManager::GetPlugin(PluginName);
+                   if (plugin) {
++                     if (!cStatus::MsgPluginProtected(plugin)) {  // PIN PATCH
+                      Menu = plugin->MainMenuAction();
+                      if (Menu)
+                         Menu->Show();
+                      }
++                  }
+                   else
+                      esyslog("ERROR: unknown plugin '%s'", PluginName);
+                   }
+@@ -1513,9 +1517,11 @@
+              case kPlay:
+                   if (cReplayControl::LastReplayed()) {
+                      Control = NULL;
++                     if (cStatus::MsgReplayProtected(0, 
cReplayControl::LastReplayed(), 0, false) == false) {  // PIN PATCH
+                      cControl::Shutdown();
+                      cControl::Launch(new cReplayControl);
+                      }
++                  }
+                   else
+                      DirectMainFunction(osRecordings); // no last viewed 
recording, so enter the Recordings menu
+                   break;

diff --git a/media-video/vdr/vdr-2.7.9.ebuild b/media-video/vdr/vdr-2.7.9.ebuild
new file mode 100644
index 000000000000..6e7b6f29d03e
--- /dev/null
+++ b/media-video/vdr/vdr-2.7.9.ebuild
@@ -0,0 +1,198 @@
+# Copyright 2021-2026 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit flag-o-matic strip-linguas toolchain-funcs user-info
+
+DESCRIPTION="Video Disk Recorder - turns a pc into a powerful set top box for 
DVB"
+HOMEPAGE="https://www.tvdr.de/";
+SRC_URI="https://git.tvdr.de/?p=vdr.git;a=snapshot;h=refs/tags/${PV};sf=tbz2 
-> ${P}.tbz2
+       menuorg? ( 
https://github.com/vdr-projects/vdr-plugin-menuorg/raw/master/vdr-patch/vdr-menuorg-2.3.x.diff
 )
+       naludump? ( https://md11.it.cx/download/${PN}/${P}_naludump.patch )
+       permashift? ( 
https://md11.it.cx/download/${PN}/${P}_patch-for-permashift.patch )
+       ttxtsubs? ( https://md11.it.cx/download/${PN}/${P}_ttxtsubs_v2.patch )"
+
+LICENSE="GPL-2+"
+SLOT="0/11" # config.h: APIVERSION "11"
+KEYWORDS="~amd64 ~arm ~arm64 ~ppc ~x86"
+IUSE="bidi debug demoplugins keyboard menuorg naludump permashift pinplugin 
systemd ttxtsubs verbose"
+
+COMMON_DEPEND="
+       acct-group/vdr
+       acct-user/vdr
+       media-libs/fontconfig
+       media-libs/freetype
+       media-libs/libjpeg-turbo:=
+       sys-libs/libcap"
+DEPEND="${COMMON_DEPEND}
+       sys-kernel/linux-headers"
+RDEPEND="${COMMON_DEPEND}
+       dev-lang/perl
+       media-tv/gentoo-vdr-scripts
+       media-fonts/corefonts
+       bidi? ( dev-libs/fribidi )
+       systemd? ( sys-apps/systemd )"
+BDEPEND="
+       sys-devel/gettext
+       virtual/pkgconfig"
+
+REQUIRED_USE="permashift? ( !naludump !pinplugin )"
+
+CONF_DIR="/etc/vdr"
+CAP_FILE="${S}/capabilities.sh"
+CAPS="# Capabilities of the vdr-executable for use by startscript etc."
+
+pkg_setup() {
+       use debug && append-flags -g
+
+       PLUGIN_LIBDIR="/usr/$(get_libdir)/vdr/plugins"
+       VIDEO_DIR="$(egethome vdr)/video"
+
+       tc-export CC CXX AR
+}
+
+add_cap() {
+       local arg
+       for arg; do
+               CAPS="${CAPS}\n${arg}=1"
+       done
+}
+
+lang_po() {
+       LING_PO=$( ls "${S}"/po | sed -e "s:.po::g" | cut -d_ -f1 | tr \\\012 ' 
' )
+}
+
+src_prepare() {
+       # apply maintenance-patches
+       ebegin "Changing paths for gentoo"
+
+       local DVBDIR=/usr/include
+       local i
+       for i in ${DVB_HEADER_PATH} /usr/include/v4l-dvb-hg /usr/include; do
+               [[ -d ${i} ]] || continue
+               if [[ -f ${i}/linux/dvb/dmx.h ]]; then
+                       einfo "Found DVB header files in ${i}"
+                       DVBDIR=${i}
+                       break
+               fi
+       done
+
+       # checking for s2api headers
+       local api_version
+       api_version=$(awk -F' ' '/define DVB_API_VERSION / {print $3}' 
"${DVBDIR}"/linux/dvb/version.h)
+       api_version=${api_version}*$(awk -F' ' '/define DVB_API_VERSION_MINOR / 
{print $3}' "${DVBDIR}"/linux/dvb/version.h)
+
+       if [[ ${api_version:-0} -lt 5*3 ]]; then
+               eerror "DVB header files do not contain s2api support or too 
old for ${P}"
+               eerror "You cannot compile VDR against old dvb-header"
+               die "DVB headers too old"
+       fi
+
+       cat > Make.config <<-EOT || die "cannot write to Make.config"
+               #
+               # Generated by ebuild ${PF}
+               #
+               PREFIX                  = /usr
+               DVBDIR                  = ${DVBDIR}
+               PLUGINLIBDIR    = ${PLUGIN_LIBDIR}
+               CONFDIR                 = ${CONF_DIR}
+               ARGSDIR                 = \$(CONFDIR)/conf.d
+               VIDEODIR                = ${VIDEO_DIR}
+               LOCDIR                  = \$(PREFIX)/share/locale
+               INCDIR                  = \$(PREFIX)/include
+
+               DEFINES                 += -DCONFDIR=\"\$(CONFDIR)\"
+               INCLUDES                += -I\$(DVBDIR)
+
+               # >=vdr-1.7.36-r1; parameter only used for compiletime on vdr
+               # PLUGINLIBDIR (plugin Makefile old) = LIBDIR (plugin Makefile 
new)
+               LIBDIR                  = ${PLUGIN_LIBDIR}
+               PCDIR                   = /usr/$(get_libdir)/pkgconfig
+
+       EOT
+       eend 0
+
+       eapply "${FILESDIR}/vdr-2.6.6_gentoo.patch"
+       use demoplugins || eapply "${FILESDIR}/vdr-2.4_remove_plugins.patch"
+       eapply "${FILESDIR}/${PN}-2.4.6_makefile-variables.patch"
+
+       # fix clang/LLVM compile
+       eapply "${FILESDIR}/${PN}-2.4.6_clang.patch"
+
+       use naludump && eapply "${DISTDIR}/${P}_naludump.patch"
+       use permashift && eapply "${DISTDIR}/${P}_patch-for-permashift.patch"
+       use pinplugin && eapply "${FILESDIR}/${P}_pinplugin.patch"
+       use ttxtsubs && eapply "${DISTDIR}/${P}_ttxtsubs_v2.patch"
+       use menuorg && eapply "${DISTDIR}/vdr-menuorg-2.3.x.diff"
+
+       add_cap CAP_UTF8 \
+               CAP_IRCTRL_RUNTIME_PARAM \
+               CAP_VFAT_RUNTIME_PARAM \
+               CAP_CHUID \
+               CAP_SHUTDOWN_AUTO_RETRY
+
+       echo -e ${CAPS} > "${CAP_FILE}" || die "cannot write to CAP_FILE"
+
+       # LINGUAS support
+       einfo "\n \t VDR supports the LINGUAS values"
+
+       lang_po
+
+       einfo "\t Please set one of this values in your sytem make.conf"
+       einfo "\t LINGUAS=\"${LING_PO}\"\n"
+
+       if [[ -z ${LINGUAS} ]]; then
+               einfo "\n \t No values in LINGUAS="
+               einfo "\t You will get only english text on OSD \n"
+       fi
+
+       strip-linguas ${LING_PO} en
+
+       default
+}
+
+src_configure() {
+       # support languages, written from right to left
+       export "BIDI=$(usex bidi 1 0)"
+       # systemd notification support
+       export "SDNOTIFY=$(usex systemd 1 0)"
+       # with/without keyboard
+       export "USE_KBD=$(usex keyboard 1 0)"
+       # detailed compile output for debug
+       export "VERBOSE=$(usex verbose 1 0)"
+}
+
+src_install() {
+       # trick the makefile to not create a VIDEODIR by supplying it with an
+       # existing directory
+       emake VIDEODIR="/" DESTDIR="${ED}" install
+
+       keepdir "${PLUGIN_LIBDIR}"
+
+       # backup for plugins they don't be able to create this dir
+       keepdir "${CONF_DIR}/plugins"
+
+       local HTML_DOCS=( *.html )
+       local DOCS=( MANUAL INSTALL README* HISTORY CONTRIBUTORS UPDATE-2* )
+       einstalldocs
+
+       insinto /usr/share/vdr
+       doins "${CAP_FILE}"
+
+       fowners vdr:vdr "${CONF_DIR}" -R
+}
+
+pkg_postinst() {
+       elog "Please read the /usr/share/doc/${PF}/UPDATE-2.4"
+       elog "for major changes in this version\n"
+
+       elog "It is a good idea to run vdrplugin-rebuild now.\n"
+
+       elog "To get nice symbols in OSD we recommend to install"
+       elog "\t1. emerge media-fonts/vdrsymbols-ttf"
+       elog "\t2. select font VDRSymbolsSans in Setup\n"
+
+       elog "To get an idea how to proceed now, have a look at our vdr-guide:"
+       elog "\thttps://wiki.gentoo.org/wiki/VDR";
+}

Reply via email to