diff -Naur ./vdr-plugin-osdteletext/menu.c ./osdteletext/menu.c
--- ./vdr-plugin-osdteletext/menu.c	2009-12-08 11:00:50.852622497 +0100
+++ ./osdteletext/menu.c	2009-12-08 11:57:51.401372371 +0100
@@ -19,6 +19,10 @@
 #include "setup.h"
 #include "txtrecv.h"
 
+// begin workaround for #include "tables.h"
+extern unsigned char unhamtab[];
+// end workaround
+
 #define GET_HUNDREDS(x) ( ( (x) - ((x)%256) ) /256 )
 #define GET_TENS(x)  ( (( (x) - ((x)%16) )%256 ) /16 )
 #define GET_ONES(x)   ( (x)%16 )
@@ -60,6 +64,11 @@
    pageBeforeNumberInput=currentPage;
    lastActivity=time(NULL);
    inactivityTimeout=-1;
+   flofNavigation=false;
+   for (int i = 0; i < 4; i++) {
+     flofPage[i]=0x100;
+     flofSubPage[i]=0;
+   }
 }
 
 
@@ -257,6 +266,7 @@
 }
 
 void TeletextBrowser::ExecuteAction(eTeletextAction e) {
+         int flofIndex = 0;
          switch (e) {
             case Zoom:
                if (selectingChannel) {
@@ -313,6 +323,30 @@
             case DarkScreen:
                ChangeBackground();
                break;
+            case FLOFBlue:
+               flofIndex++;
+            case FLOFYellow:
+               flofIndex++;
+            case FLOFGreen:
+               flofIndex++;
+            case FLOFRed:
+               if (flofNavigation){
+			      if (selectingChannel) {
+                     selectingChannel=false;
+                     Display::ClearMessage();
+                  }
+                  if (cursorPos != 0) {
+                     SetNumber(-3);
+                  }
+			      SetPreviousPage(currentPage, currentSubPage, flofPage[flofIndex]);
+			   
+			      currentPage=flofPage[flofIndex];
+			      cursorPos=0;
+			      currentSubPage=flofSubPage[flofIndex];
+			      Display::ShowUpperHalf();
+			      ShowPage();
+		       }
+			   break;
             default:
                //In osdteletext.c, numbers are thought to be decimal, the setup page
                //entries will display them in this way. It is a lot easier to do the
@@ -571,7 +605,7 @@
 //this is taken and adapted from the teletext plugin since it uses its data
 bool TeletextBrowser::DecodePage() {
    // Load the page and decodes it
-   unsigned char cache[40*24+12];
+   unsigned char cache[40*26+12];
    StorageHandle fd;
    // Take a look if there is a xxx-00 page
    if (currentSubPage==0) {
@@ -596,6 +630,7 @@
       ShowPageNumber();
       UpdateClock();
       Display::ReleaseFlush();
+      UpdateFLOFPages(cache);
    } else {
       // page doesn't exist
       currentSubPage--;
@@ -614,6 +649,40 @@
 
 
 
+
+void TeletextBrowser::UpdateFLOFPages(unsigned char *cache) {
+   // update FLOF link pages, see http://pdc.ro.nu/teletext.html
+   // Have a look at the Link Control Byte
+   unsigned char *h=cache + 12 + 25*40 + 37;
+   unsigned char lcb;
+   lcb = unhamtab[*h] & 0x0f; 
+
+   if (!(lcb & 0x08)){
+      flofNavigation=false;
+      return;
+   }
+   else
+      flofNavigation=true;
+   
+   unsigned short c[3];
+   int mag, mag8, subno;
+   unsigned char *z = cache + 12 + 25*40 + 1;
+
+   for (int i=0;i!=4;i++) {
+      for (int j=0;j!=3;j++) {
+         // z = 12 + 25*40 + 1 + i*6 + j*2
+         c[j] = unhamtab[*z++] & 0x0f;
+         c[j] |= (unhamtab[*z++] & 0x0f) << 4;
+      }
+      mag = ((c[1] >> 7) | ((c[2] >> 6) << 1)) ^ (currentPage >> 8);
+      mag8 = mag ?: 8;
+      flofPage[i] = c[0] | (mag8 << 8);
+      subno = (c[1] | (c[2] << 8)) & 0x3f7f;
+      flofSubPage[i] = (subno != 0x3f7f) ? subno : 0;
+   }   
+
+ }
+
 int TeletextBrowser::PageCheckSum() {
    int retSum=0;
    StorageHandle fd;
@@ -621,7 +690,7 @@
    CheckFirstSubPage(currentSubPage);
    
    if ((fd=storage->openForReading(PageID(channel, currentPage, currentSubPage), false)) ) {
-      uchar cache[960];
+      uchar cache[1040];
       storage->read(cache, 12, fd); //skip
       storage->read(cache, sizeof(cache), fd);
       storage->close(fd);
diff -Naur ./vdr-plugin-osdteletext/menu.h ./osdteletext/menu.h
--- ./vdr-plugin-osdteletext/menu.h	2009-12-08 11:00:50.852622497 +0100
+++ ./osdteletext/menu.h	2009-12-07 19:58:11.000000000 +0100
@@ -35,6 +35,7 @@
    void ShowPage();
    void UpdateClock();
    bool DecodePage();
+   void UpdateFLOFPages(unsigned char *cache);
    void ChangePageRelative(Direction direction);
    void ChangeSubPageRelative(Direction direction);
    bool CheckPage();
@@ -47,7 +48,7 @@
    void ExecuteAction(eTeletextAction e);
    int nextValidPageNumber(int start, Direction direction);
    char fileName[PATH_MAX];
-   char page[40][24];
+   char page[40][25];
    int cursorPos;
    eTeletextAction TranslateKey(eKeys Key);
    bool pageFound;
@@ -67,6 +68,9 @@
    static tChannelID channel;
    static int currentChannelNumber;
    static TeletextBrowser* self;
+   bool flofNavigation;
+   int flofPage[4];
+   int flofSubPage[4];
    Storage *storage;
 private:
    void ChangeBackground();
diff -Naur ./vdr-plugin-osdteletext/osdteletext.c ./osdteletext/osdteletext.c
--- ./vdr-plugin-osdteletext/osdteletext.c	2009-12-08 11:00:50.852622497 +0100
+++ ./osdteletext/osdteletext.c	2009-12-07 19:57:18.000000000 +0100
@@ -217,6 +217,10 @@
       tr("Change channel"),
       tr("Switch background"),
       //tr("Suspend receiving"),
+      tr("FLOF Red"),
+      tr("FLOF Green"),
+      tr("FLOF Yellow"),
+      tr("FLOF Blue"),
       tr("Jump to...")
    };
    
diff -Naur ./vdr-plugin-osdteletext/setup.h ./osdteletext/setup.h
--- ./vdr-plugin-osdteletext/setup.h	2009-12-08 11:00:50.852622497 +0100
+++ ./osdteletext/setup.h	2009-12-07 19:57:50.000000000 +0100
@@ -16,7 +16,9 @@
 //TeletextBrowser::TranslateKey and 
 //the constants in cPluginTeletextosd::initTexts
 enum eTeletextAction { Zoom, HalfPage, SwitchChannel,
-                       DarkScreen, /*SuspendReceiving,*/ LastAction }; //and 100-899 => jump to page
+                       DarkScreen, /*SuspendReceiving,*/ 
+					   FLOFRed, FLOFGreen, FLOFYellow, FLOFBlue,
+					   LastAction }; //and 100-899 => jump to page
 
 enum ActionKeys {
 ActionKeyRed,
diff -Naur ./vdr-plugin-osdteletext/txtrecv.c ./osdteletext/txtrecv.c
--- ./vdr-plugin-osdteletext/txtrecv.c	2009-12-08 11:00:50.852622497 +0100
+++ ./osdteletext/txtrecv.c	2009-12-08 11:50:45.852299698 +0100
@@ -177,7 +177,7 @@
    failedFreeSpace=false;
 }
 
-#define TELETEXT_PAGESIZE 972
+#define TELETEXT_PAGESIZE 1052
 
 LegacyStorage::LegacyStorage(int maxMB) {
    fsBlockSize=1;
@@ -438,7 +438,7 @@
 cTelePage::cTelePage(PageID t_page, uchar t_flags, uchar t_lang,int t_mag, Storage *s)
   : mag(t_mag), flags(t_flags), lang(t_lang), page(t_page), storage(s)
 {
-   memset(pagebuf,' ',26*40);
+   memset(pagebuf,0,26*40);
 }
 
 cTelePage::~cTelePage() {
@@ -462,7 +462,7 @@
       buf=lang; storage->write(&buf,1,fd);
       buf=0x00; storage->write(&buf,1,fd);
       buf=0x00; storage->write(&buf,1,fd);
-      storage->write(pagebuf,24*40,fd);
+      storage->write(pagebuf,26*40,fd);
       storage->close(fd);
    }
 }
@@ -645,6 +645,7 @@
    uchar *ptr;
    uchar flags,lang;
 
+   flags = 0x00;
    hdr = unham16 (&TXT_buf[0x8]);
    mag = hdr & 0x07;
    mag8 = mag ?: 8;
@@ -687,11 +688,20 @@
       TxtPage->SetLine((int)line,(uchar *)ptr);
       break;
       }
-   case 1 ... 25: 
+   case 1 ... 24: 
       {
       if (TxtPage) TxtPage->SetLine((int)line,(uchar *)ptr); 
       break;
       }
+   case 25:
+        // overwrite row 0, but only if not in subtitle mode
+        if (TxtPage && !(flags & 0x30)) TxtPage->SetLine((int)0,(uchar *)ptr);
+        break;
+   case 27:
+        // we only want 27/0, see http://pdc.ro.nu/teletext.html
+        if (TxtPage && !(unham16(ptr) & 0x0f)) TxtPage->SetLine((int)25,(uchar *)ptr);
+          
+        break;
    /*case 23: 
       {
       SaveAndDeleteTxtPage();
diff -Naur ./vdr-plugin-osdteletext/txtrender.c ./osdteletext/txtrender.c
--- ./vdr-plugin-osdteletext/txtrender.c	2009-12-08 11:00:50.852622497 +0100
+++ ./osdteletext/txtrender.c	2009-12-08 11:14:13.682622864 +0100
@@ -285,7 +285,7 @@
     // Reserved for later use:
     // enumCharsets FirstG2=GetG2Charset(LocalG0CodePage);
     
-    for (y=0;y<24;(EmptyNextLine?y+=2:y++)) {
+    for (y=0;y<25;(EmptyNextLine?y+=2:y++)) {
         // Start of line: Set start of line defaults
         
         // Hold Mosaics mode: Remember last mosaic char/charset 
@@ -410,7 +410,7 @@
             }
             
             // Handle double-height and double-width extremes
-            if (y>=23) {
+            if (y>=24) {
                 if (Size==sizeDoubleHeight) Size=sizeNormal;
                 if (Size==sizeDoubleSize) Size=sizeDoubleWidth;
             }
@@ -429,7 +429,7 @@
                 case sizeNormal:
                     // Normal sized
                     SetChar(x,y,c2);
-                    if (EmptyNextLine && y<23) {
+                    if (EmptyNextLine && y<24) {
                         // Clean up next line
                         SetChar(x,y+1,c2.ToChar(' ').ToCharset(FirstG0));
                     }
@@ -438,7 +438,7 @@
                     // Double width
                     SetChar(x,y,c2.ToDblWidth(dblw_Left));
                     SetChar(x+1,y,c2.ToDblWidth(dblw_Right));
-                    if (EmptyNextLine && y<23) {
+                    if (EmptyNextLine && y<24) {						
                         // Clean up next line
                         SetChar(x  ,y+1,c2.ToChar(' ').ToCharset(FirstG0));
                         SetChar(x+1,y+1,c2.ToChar(' ').ToCharset(FirstG0));
@@ -525,7 +525,7 @@
             }
         } // end for x
     } // end for y
-    
+    /*
     for (x=0;x<40;x++) {
         // Clean out last line
         cTeletextChar c;
@@ -537,7 +537,8 @@
             c.SetBoxedOut(true);    
         }
         SetChar(x,24,c);
-    }       
+    }     
+	*/
 }
 
 
