File vdr-1.7.29-menuselection.patch of Package vdr

diff -Nru vdr-1.7.29-vanilla/osdbase.c vdr-1.7.29-menuselection/osdbase.c
--- vdr-1.7.29-vanilla/osdbase.c	2012-07-17 22:37:09.000000000 +0300
+++ vdr-1.7.29-menuselection/osdbase.c	2012-07-17 22:44:15.000000000 +0300
@@ -77,6 +77,7 @@
 {
   isMenu = true;
   digit = 0;
+  key_nr = -1;
   hasHotkeys = false;
   displayMenuItems = 0;
   title = NULL;
@@ -126,7 +127,7 @@
         digit = -1; // prevents automatic hotkeys - input already has them
      if (digit >= 0) {
         digit++;
-        buffer = cString::sprintf(" %c %s", (digit < 10) ? '0' + digit : ' ' , s);
+        buffer = cString::sprintf(" %2d%s %s", digit, (digit > 9) ? "" : " ", s);
         s = buffer;
         }
      }
@@ -472,20 +473,60 @@
      }
 }
 
+#define MENUKEY_TIMEOUT 1500
+
 eOSState cOsdMenu::HotKey(eKeys Key)
 {
-  for (cOsdItem *item = First(); item; item = Next(item)) {
+  bool match = false;
+  bool highlight = false;
+  int  item_nr;
+  int  i;
+
+  if (Key == kNone) {
+     if (lastActivity.TimedOut())
+        Key = kOk;
+     else
+        return osContinue;
+     }
+  else
+     lastActivity.Set(MENUKEY_TIMEOUT);
+  for (cOsdItem *item = Last(); item; item = Prev(item)) {
       const char *s = item->Text();
-      if (s && (s = skipspace(s)) != NULL) {
-         if (*s == Key - k1 + '1') {
+      i = 0;
+      item_nr = 0;
+      if (s && (s = skipspace(s)) != '\0' && '0' <= s[i] && s[i] <= '9') {
+         do {
+            item_nr = item_nr * 10 + (s[i] - '0');
+            }
+         while ( !((s[++i] == '\t')||(s[i] == ' ')) && (s[i] != '\0') && ('0' <= s[i]) && (s[i] <= '9'));
+         if ((Key == kOk) && (item_nr == key_nr)) {
             current = item->Index();
             RefreshCurrent();
             Display();
             cRemote::Put(kOk, true);
+            key_nr = -1;
             break;
             }
+         else if (Key != kOk) {
+            if (!highlight && (item_nr == (Key - k0))) {
+               highlight = true;
+               current = item->Index();
+               }
+            if (!match && (key_nr == -1) && ((item_nr / 10) == (Key - k0))) {
+               match = true;
+               key_nr = (Key - k0);
+               }
+            else if (((key_nr == -1) && (item_nr == (Key - k0))) || (!match && (key_nr >= 0) && (item_nr == (10 * key_nr + Key - k0)))) {
+               current = item->Index();
+               cRemote::Put(kOk, true);
+               key_nr = -1;
+               break;
+               }
+            }
          }
       }
+  if ((!match) && (Key != kNone))
+     key_nr = -1;
   return osContinue;
 }
 
@@ -524,8 +565,8 @@
         }
      }
   switch (int(Key)) {
-    case k0:      return osUnknown;
-    case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown;
+    case kNone:
+    case k0...k9: return hasHotkeys ? HotKey(Key) : osUnknown;
     case kUp|k_Repeat:
     case kUp:   CursorUp();   break;
     case kDown|k_Repeat:
diff -Nru vdr-1.7.29-vanilla/osdbase.h vdr-1.7.29-menuselection/osdbase.h
--- vdr-1.7.29-vanilla/osdbase.h	2012-07-17 22:37:09.000000000 +0300
+++ vdr-1.7.29-menuselection/osdbase.h	2012-07-17 22:44:15.000000000 +0300
@@ -97,6 +97,8 @@
   char *status;
   int digit;
   bool hasHotkeys;
+  int key_nr;
+  cTimeMs lastActivity;
   void DisplayHelp(bool Force = false);
 protected:
   void SetDisplayMenu(void);
openSUSE Build Service is sponsored by