Index: dxr3device.c
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3device.c,v
retrieving revision 1.2.2.18
diff -u -r1.2.2.18 dxr3device.c
--- dxr3device.c	19 Apr 2005 18:19:37 -0000	1.2.2.18
+++ dxr3device.c	16 May 2005 17:52:24 -0000
@@ -508,7 +508,7 @@
 
 // ==================================
 // get spudecoder
-cSpuDecoder *cDxr3Device::GetSpuDecoder(void)
+cDxr3SpuDecoder *cDxr3Device::GetSpuDecoder(void)
 {
     if (!m_spuDecoder && IsPrimaryDevice())
     {
Index: dxr3device.h
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3device.h,v
retrieving revision 1.1.2.10
diff -u -r1.1.2.10 dxr3device.h
--- dxr3device.h	19 Apr 2005 18:19:34 -0000	1.1.2.10
+++ dxr3device.h	16 May 2005 17:52:24 -0000
@@ -70,7 +70,7 @@
     virtual void SetVolumeDevice(int Volume);
 
     // osd
-    virtual cSpuDecoder *GetSpuDecoder();
+    virtual cDxr3SpuDecoder *GetSpuDecoder();
 #if VDRVERSNUM < 10307
     virtual cOsdBase* NewOsd(int x, int y);
 #endif
Index: dxr3osd_subpicture.c
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3osd_subpicture.c,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 dxr3osd_subpicture.c
--- dxr3osd_subpicture.c	21 Apr 2005 21:40:06 -0000	1.1.2.11
+++ dxr3osd_subpicture.c	16 May 2005 17:52:24 -0000
@@ -1,4 +1,5 @@
 #include "dxr3osd_subpicture.h"
+#include "dxr3device.h"
 
 // Enables some time measure debugging code
 // (taken from the osdteletext plugin, thanks folks)
@@ -45,6 +46,8 @@
 #else
     last = time_ms() - FLUSHRATE;
 #endif
+    if(cDxr3Device::InstanceP())
+	cDxr3Device::InstanceP()->GetSpuDecoder()->Disable();
     Spu = &cSPUEncoder::Instance();
 
     //Clears the OSD screen image
@@ -60,6 +63,8 @@
 #if VDRVERSNUM >= 10318
     delete last;
 #endif
+    if(cDxr3Device::InstanceP())
+	cDxr3Device::InstanceP()->GetSpuDecoder()->Enable();
 }
 
 // ==================================
Index: dxr3spudecoder.c
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3spudecoder.c,v
retrieving revision 1.1.2.10
diff -u -r1.1.2.10 dxr3spudecoder.c
--- dxr3spudecoder.c	24 Apr 2005 16:09:08 -0000	1.1.2.10
+++ dxr3spudecoder.c	16 May 2005 17:52:24 -0000
@@ -3,9 +3,6 @@
  *
  * Copyright (C) 2004 Christian Gmeiner
  *
- * Orginal:
- *    Copyright (C) 2001.2002 Andreas Schultz <aschultz@warp10.net>
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  * as published by the Free Software Foundation; either version 2.1
@@ -22,261 +19,16 @@
  *
  */
 
-#include <assert.h>
-#include <string.h>
-#include <inttypes.h>
-#include <math.h>
-
 #include "dxr3spudecoder.h"
-#include "dxr3interface.h"
-#include "dxr3tools.h"
-#include "dxr3log.h"
-
-// ==================================
-#define CMD_SPU_MENU            0x00
-#define CMD_SPU_SHOW            0x01
-#define CMD_SPU_HIDE            0x02
-#define CMD_SPU_SET_PALETTE     0x03
-#define CMD_SPU_SET_ALPHA       0x04
-#define CMD_SPU_SET_SIZE        0x05
-#define CMD_SPU_SET_PXD_OFFSET  0x06
-#define CMD_SPU_CHG_COLCON      0x07
-#define CMD_SPU_EOF             0xff
-
-#define spuU32(i) ((spu[i] << 8) + spu[i+1])
-
-
-/*
- * cDxr3Spubitmap:
- *
- * this is a bitmap of the full screen and two palettes
- * the normal palette for the background and the highlight palette
- *
- * Inputs:
- *  - a SPU rle encoded image on creation, which will be decoded into
- *    the full screen indexed bitmap
- *
- * Output:
- *  - a minimal sized cDxr3SpuBitmap a given palette, the indexed bitmap
- *    will be scanned to get the smallest possible resulting bitmap considering
- *    transparencies
- */
-
-// ==================================
-void cDxr3SpuPalette::setPalette(const uint32_t * pal)
-{
-    for (int i = 0; i < 16; i++)
-	palette[i] = Tools::YUV2Rgb(pal[i]);
-}
-
-// ==================================
-#define setMin(a, b) if (a > b) a = b
-#define setMax(a, b) if (a < b) a = b
-
-#define spuXres 720
-#define spuYres 576
-
-#define revRect(r1, r2) { r1.x1 = r2.x2; r1.y1 = r2.y2; r1.x2 = r2.x1; r1.y2 = r2.y1; }
-
-// ==================================
-cDxr3SpuBitmap::cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd,
-			       uint8_t * eodd, uint8_t * feven,
-			       uint8_t * eeven)
-{
-    if (size.x1 < 0 || size.y1 < 0 || size.x2 >= spuXres || size.y2 >= spuYres)
-	throw;
-
-    bmpsize = size;
-    revRect(minsize[0], size);
-    revRect(minsize[1], size);
-    revRect(minsize[2], size);
-    revRect(minsize[3], size);
-
-    if (!(bmp = new uint8_t[spuXres * spuYres * sizeof(uint8_t)]))
-	throw;
-
-    memset(bmp, 0, spuXres * spuYres * sizeof(uint8_t));
-    putFieldData(0, fodd, eodd);
-    putFieldData(1, feven, eeven);
-}
-
-// ==================================
-cDxr3SpuBitmap::~cDxr3SpuBitmap()
-{
-    delete[]bmp;
-}
-
-// ==================================
-cBitmap *cDxr3SpuBitmap::getBitmap(const aDxr3SpuPalDescr paldescr,
-				   const cDxr3SpuPalette & pal,
-				   sDxr3SpuRect & size) const
-{
-    int h = size.height();
-    int w = size.width();
-
-    if (size.y1 + h >= spuYres)
-    {
-	h = spuYres - size.y1 - 1;
-    }
-    if (size.x1 + w >= spuXres)
-    {
-	w = spuXres - size.x1 - 1;
-    }
-
-    if (w & 0x03)
-    {
-	w += 4 - (w & 0x03);
-    }
-
-    cBitmap *ret = new cBitmap(w, h, 2);
-
-    // set the palette
-    for (int i = 0; i < 4; i++)
-    {
-	uint32_t color = pal.getColor(paldescr[i].index, paldescr[i].trans);
-	ret->SetColor(i, (tColor) color);
-    }
-
-    // set the content
-    for (int yp = 0; yp < h; yp++)
-    {
-	for (int xp = 0; xp < w; xp++)
-	{
-	    uint8_t idx = bmp[(size.y1 + yp) * spuXres + size.x1 + xp];
-	    ret->SetIndex(xp, yp, idx);
-	}
-    }
-    return ret;
-}
-
-// ==================================
-// find the minimum non-transparent area
-bool cDxr3SpuBitmap::getMinSize(const aDxr3SpuPalDescr paldescr,
-				sDxr3SpuRect & size) const
-{
-    bool ret = false;
-    for (int i = 0; i < 4; i++)
-    {
-	if (paldescr[i].trans != 0)
-	{
-	    if (!ret)
-	    {
-		size = minsize[i];
-	    }
-	    else
-	    {
-		setMin(size.x1, minsize[i].x1);
-		setMin(size.y1, minsize[i].y1);
-		setMax(size.x2, minsize[i].x2);
-		setMax(size.y2, minsize[i].y2);
-	    }
-	    ret = true;
-	}
-    }
-    /*
-    if (ret && cDxr3ConfigData::Instance().GetDebug())
-    {
-	cLog::Instance() << "cDxr3SpuBitmap::getMinSize: ("
-			 << size.x1 ", " << size.y1 << ") x ("
-			 << size.x2 << ", " << size.y2 << ")\n";
-    }
-    */
-    if (size.x1 > size.x2 || size.y1 > size.y2)
-	return false;
-    return ret;
-}
-
-// ==================================
-void cDxr3SpuBitmap::putPixel(int xp, int yp, int len, uint8_t colorid)
-{
-    memset(bmp + spuXres * yp + xp, colorid, len);
-    setMin(minsize[colorid].x1, xp);
-    setMin(minsize[colorid].y1, yp);
-    setMax(minsize[colorid].x2, xp + len - 1);
-    setMax(minsize[colorid].y2, yp + len - 1);
-}
-
-// ==================================
-static uint8_t getBits(uint8_t * &data, uint8_t & bitf)
-{
-    uint8_t ret = *data;
-    if (bitf)
-    {
-	ret >>= 4;
-    }
-    else
-    {
-	data++;
-    }
-
-    bitf ^= 1;
-
-    return (ret & 0xf);
-}
-
-// ==================================
-void cDxr3SpuBitmap::putFieldData(int field, uint8_t * data, uint8_t * endp)
-{
-    int xp = bmpsize.x1;
-    int yp = bmpsize.y1 + field;
-    uint8_t bitf = 1;
-
-    while (data < endp)
-    {
-	uint16_t vlc = getBits(data, bitf);
-	if (vlc < 0x0004)
-	{
-	    vlc = (vlc << 4) | getBits(data, bitf);
-	    if (vlc < 0x0010)
-	    {
-		vlc = (vlc << 4) | getBits(data, bitf);
-		if (vlc < 0x0040)
-		{
-		    vlc = (vlc << 4) | getBits(data, bitf);
-		}
-	    }
-	}
-
-	uint8_t color = vlc & 0x03;
-	int len = vlc >> 2;
-
-	// if len == 0 -> end sequence - fill to end of line
-	len = len ? len : bmpsize.x2 - xp + 1;
-	putPixel(xp, yp, len, color);
-	xp += len;
-
-	if (xp > bmpsize.x2)
-	{
-	    // nextLine
-	    if (!bitf)
-		data++;
-	    bitf = 1;
-	    xp = bmpsize.x1;
-	    yp += 2;
-	    if (yp > bmpsize.y2)
-		return;
-	}
-    }
-}
 
 // ==================================
 // ! constructor
-cDxr3SpuDecoder::cDxr3SpuDecoder()
-{
-    clean = true;
-    scaleMode = eSpuNormal;
-    spu = NULL;
-    osd = NULL;
-    spubmp = NULL;
-    allowedShow = true;
-}
-
-// ==================================
-cDxr3SpuDecoder::~cDxr3SpuDecoder()
+cDxr3SpuDecoder::cDxr3SpuDecoder() :
+    m_Interface(cDxr3Interface::Instance()), m_visible(false)
 {
-    delete spubmp;
-    delete spu;
-    delete osd;
+    m_ScaleMode = eSpuNormal;
+    enabled = true;
+    highlight = false;
 }
 
 // ==================================
@@ -287,389 +39,140 @@
 void cDxr3SpuDecoder::processSPU(uint32_t pts, uint8_t * buf)
 #endif
 {
-    setTime(pts);
-
-    if (cDxr3ConfigData::Instance().GetDebug())
+    // size are the first two bits of buf
+    // size = (buf[0] << 8) + buf[1]
+    cMutexLock MutexLock(&mutex);
+    if (enabled)
     {
-	cLog::Instance() << "cDxr3SpuDecoder::processSPU: SPU pushData: pts: "
-			 << pts << "\n";
+	m_Interface.WriteSpu(buf, (buf[0] << 8) + buf[1]);
+	m_Interface.SetSpuPts(pts);
     }
-
-    delete spubmp;
-    spubmp = NULL;
-    delete[]spu;
-    spu = buf;
-    spupts = pts;
-
-    DCSQ_offset = cmdOffs();
-    prev_DCSQ_offset = 0;
-
-    clean = true;
-#if VDRVERSNUM >= 10318
-    allowedShow = AllowedShow;
-#endif
 }
 
 // ==================================
 // ! get scalemode
 cSpuDecoder::eScaleMode cDxr3SpuDecoder::getScaleMode(void)
 {
-    return scaleMode;
+    return m_ScaleMode;
 }
 
 // ==================================
-// ! set scalemode
+// ! set scalemode - not needed
 void cDxr3SpuDecoder::setScaleMode(cSpuDecoder::eScaleMode ScaleMode)
 {
-    scaleMode = ScaleMode;
+    m_ScaleMode = ScaleMode;
 }
 
 // ==================================
-// ! send palette to dxr3
+// ! memo palette
 void cDxr3SpuDecoder::setPalette(uint32_t * pal)
 {
-    palette.setPalette(pal);
-}
-
-// ==================================
-// ! send highlight to dxr3
-void cDxr3SpuDecoder::setHighlight(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette)
-{
-    aDxr3SpuPalDescr pld;
-    for (int i = 0; i < 4; i++)
+    for (int i = 0; i < 16; i++)
     {
-	pld[i].index = 0xf & (palette >> (16 + 4 * i));
-	pld[i].trans = 0xf & (palette >> (4 * i));
+	palette[i] = pal[i];
     }
-
-    bool ne = hlpsize.x1 != sx || hlpsize.y1 != sy ||
-	hlpsize.x2 != ex || hlpsize.y2 != ey ||
-	pld[0] != hlpDescr[0] || pld[1] != hlpDescr[1] ||
-	pld[2] != hlpDescr[2] || pld[3] != hlpDescr[3];
-
-    if (ne)
+    cMutexLock MutexLock(&mutex);
+    if (enabled)
     {
-	if (cDxr3ConfigData::Instance().GetDebug())
-	{
-	    cLog::Instance() << "cDxr3SpuDecoder::setHighlight: " << sx
-			     << ", " << sy << ", " << ex << ", " << ey << "\n";
-	}
-
-	hlpsize.x1 = sx;
-	hlpsize.y1 = sy;
-	hlpsize.x2 = ex;
-	hlpsize.y2 = ey;
-	memcpy(hlpDescr, pld, sizeof(aDxr3SpuPalDescr));
-	highlight = true;
-	clean = false;
+	doPalette();
     }
 }
 
 // ==================================
-// ! clear highlight
-void cDxr3SpuDecoder::clearHighlight()
+// ! send palette to dxr3
+void cDxr3SpuDecoder::doPalette(void)
 {
-    clean &= !highlight;
-    highlight = false;
-    hlpsize.x1 = -1;
-    hlpsize.y1 = -1;
-    hlpsize.x2 = -1;
-    hlpsize.y2 = -1;
+    m_Interface.SetPalette(palette);
 }
 
 // ==================================
-int cDxr3SpuDecoder::ScaleYcoord(int value)
+// ! send highlight to dxr3
+void cDxr3SpuDecoder::setHighlight(uint16_t sx, uint16_t sy,
+				   uint16_t ex, uint16_t ey, uint32_t palette)
 {
-    if (scaleMode == eSpuLetterBox)
+    highlight = true;
+    hlsx = sx;
+    hlsy = sy;
+    hlex = ex;
+    hley = ey;
+    hlpalette = palette;
+    cMutexLock MutexLock(&mutex);
+    if (enabled)
     {
-	int offset =
-	    cDevice::PrimaryDevice()->GetVideoSystem() == vsPAL ? 72 : 60;
-	return lround((value * 3.0) / 4.0) + offset;
+	doHighlight();
     }
-    return value;
 }
 
 // ==================================
-int cDxr3SpuDecoder::ScaleYres(int value)
+// ! clear highlight
+void cDxr3SpuDecoder::clearHighlight(void)
 {
-    if (scaleMode == eSpuLetterBox)
+    highlight = false;
+    cMutexLock MutexLock(&mutex);
+    if (enabled)
     {
-	return lround((value * 3.0) / 4.0);
+	doHighlight();
     }
-    return value;
-}
-
-// ==================================
-void cDxr3SpuDecoder::DrawBmp(sDxr3SpuRect & size, cBitmap * bmp)
-{
-    int x2 = size.x2;
-    while ((x2 - size.x1 + 1) & 0x03)
-	x2++;
-    tArea Area = { size.x1, size.y1, x2, size.y2, 2 };
-    osd->SetAreas(&Area, 1);
-    if (x2 > size.x2)
-	osd->DrawRectangle(size.x2 + 1, size.y1, x2, size.y2, clrTransparent);
-    osd->DrawBitmap(size.x1, size.y1, *bmp);
-    delete bmp;
 }
 
-// ==================================
-// ! draw nav, subtitles, ...
-void cDxr3SpuDecoder::Draw()
+void cDxr3SpuDecoder::doHighlight(void)
 {
-    Hide();
-
-    if (!spubmp)
-    {
-	return;
-    }
-
-    cBitmap *fg = NULL;
-    cBitmap *bg = NULL;
-    sDxr3SpuRect bgsize;
-    sDxr3SpuRect hlsize;
-
-    hlsize.x1 = hlpsize.x1;
-    hlsize.y1 = ScaleYcoord(hlpsize.y1);
-    hlsize.x2 = hlpsize.x2;
-    hlsize.y2 = ScaleYcoord(hlpsize.y2);
-
     if (highlight)
     {
-	fg = spubmp->getBitmap(hlpDescr, palette, hlsize);
+	m_Interface.SetButton(hlsx, hlsy, hlex, hley, hlpalette);
     }
-
-    if (spubmp->getMinSize(palDescr, bgsize))
+    else
     {
-	bg = spubmp->getBitmap(palDescr, palette, bgsize);
-	if (scaleMode == eSpuLetterBox)
-	{
-	    // the coordinates have to be modified for letterbox
-	    int y1 = ScaleYres(bgsize.y1) + bgsize.height();
-	    bgsize.y2 = y1 + bgsize.height();
-	    bgsize.y1 = y1;
-	}
+	m_Interface.ClearButton();
     }
 
-    if (bg || fg)
-    {
-	if (osd == NULL)
-	    if ((osd = cOsdProvider::NewOsd(0, 0)) == NULL)
-	    {
-		if (cDxr3ConfigData::Instance().GetDebug())
-		{
-		    cLog::Instance() << "cDxr3SpuDecoder::Draw: New OSD faild!\n";
-		}
-		dsyslog("NewOsd failed\n");
-		return;
-	    }
-
-	if (fg)
-	{
-	    DrawBmp(hlsize, fg);
-	}
-
-	if (bg)
-	{
-	    DrawBmp(bgsize, bg);
-	}
-
-	osd->Flush();
-    }
-
-    clean = true;
+}
+// ==================================
+// ! draw nav, subtitles, ...
+void cDxr3SpuDecoder::Draw(void)
+{
+    m_visible = true;
 }
 
 // ==================================
 // ! hide nav, subtitles, ...
-void cDxr3SpuDecoder::Hide()
+void cDxr3SpuDecoder::Hide(void)
 {
-    delete osd;
-    osd = NULL;
+    m_visible = false;
 }
 
 // ==================================
 // ! clear highlight and osd
-void cDxr3SpuDecoder::Empty()
+void cDxr3SpuDecoder::Empty(void)
 {
-    Hide();
-
-    delete spubmp;
-    spubmp = NULL;
-
-    delete[]spu;
-    spu = NULL;
-
-    clearHighlight();
-    clean = true;
+    m_Interface.ClearOsd();
 }
 
 // ==================================
 // ! set pts
 int cDxr3SpuDecoder::setTime(uint32_t pts)
 {
-    if (!spu)
-    {
-	return 0;
-    }
-
-    if (spu && !clean)
-    {
-	Draw();
-    }
+    m_Interface.SetSpuPts(pts);
+    return (pts == 0) ? 0 : 1;
+}
 
-    while (DCSQ_offset != prev_DCSQ_offset)
-    {
-	// Display Control Sequences
-	int i = DCSQ_offset;
-	state = spNONE;
-
-	uint32_t exec_time = spupts + spuU32(i) * 1024;
-	if ((pts != 0) && (exec_time > pts))
-	{
-	    return 0;
-	}
-
-	if (pts != 0)
-	{
-	    uint16_t feven = 0;
-	    uint16_t fodd = 0;
-
-	    i += 2;
-
-	    prev_DCSQ_offset = DCSQ_offset;
-	    DCSQ_offset = spuU32(i);
-	    i += 2;
-
-	    while (spu[i] != CMD_SPU_EOF)
-	    {
-		// Command Sequence
-		switch (spu[i])
-		{
-		case CMD_SPU_SHOW:
-		    // show subpicture
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: show subpicture\n";
-		    }
-		    state = spSHOW;
-		    i++;
-		    break;
-
-		case CMD_SPU_HIDE:
-		    // hide subpicture
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: hide subpicture\n";
-		    }
-		    state = spHIDE;
-		    i++;
-		    break;
-
-		case CMD_SPU_SET_PALETTE:
-		    // CLUT
-		    palDescr[0].index = spu[i + 2] & 0xf;
-		    palDescr[1].index = spu[i + 2] >> 4;
-		    palDescr[2].index = spu[i + 1] & 0xf;
-		    palDescr[3].index = spu[i + 1] >> 4;
-		    i += 3;
-		    break;
-
-		case CMD_SPU_SET_ALPHA:
-		    // transparency palette
-		    palDescr[0].trans = spu[i + 2] & 0xf;
-		    palDescr[1].trans = spu[i + 2] >> 4;
-		    palDescr[2].trans = spu[i + 1] & 0xf;
-		    palDescr[3].trans = spu[i + 1] >> 4;
-		    i += 3;
-		    break;
-
-		case CMD_SPU_SET_SIZE:
-		    // image coordinates
-		    size.x1 = (spu[i + 1] << 4) | (spu[i + 2] >> 4);
-		    size.x2 = ((spu[i + 2] & 0x0f) << 8) | spu[i + 3];
-
-		    size.y1 = (spu[i + 4] << 4) | (spu[i + 5] >> 4);
-		    size.y2 = ((spu[i + 5] & 0x0f) << 8) | spu[i + 6];
-
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: ("
-					 << size.x1 << ", " << size.y1
-					 << ") x (" << size.x2 << ", "
-					 << size.y2 <<")\n";
-		    }
-		    i += 7;
-		    break;
-
-		case CMD_SPU_SET_PXD_OFFSET:
-		    // image 1 / image 2 offsets
-		    fodd = spuU32(i + 1);
-		    feven = spuU32(i + 3);
-
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: odd = "
-					 << fodd << " even = " << feven
-					 << "\n";
-		    }
-		    i += 5;
-		    break;
-
-		case CMD_SPU_CHG_COLCON:
-		{
-		    int size = spuU32(i + 1);
-		    i += 1 + size;
-		}
-		break;
-
-		case CMD_SPU_MENU:
-		    if (cDxr3ConfigData::Instance().GetDebug())
-		    {
-			cLog::Instance() << "cDxr3SpuDecoder::setTime: spu menu\n";
-		    }
-		    state = spMENU;
-
-		    i++;
-		    break;
-
-		default:
-		    esyslog("invalid sequence in control header (%.2x)\n",
-			    spu[i]);
-		    assert(0);
-		    i++;
-		    break;
-		}
-	    }
-	    if (fodd != 0 && feven != 0)
-	    {
-		delete spubmp;
-		spubmp = new cDxr3SpuBitmap(size, spu + fodd, spu + feven,
-					    spu + feven, spu + cmdOffs());
-	    }
-	}
-	else if (!clean)
-	{
-	    state = spSHOW;
-	}
-
-	if ((state == spSHOW && allowedShow) || state == spMENU)
-	{
-	    Draw();
-	}
-
-	if (state == spHIDE)
-	{
-	    Hide();
-	}
-
-	if (pts == 0)
-	{
-	    return 0;
-	}
-    }
+// ==================================
+// ! disable spu decoder (osd in use)
+void cDxr3SpuDecoder::Disable(void)
+{
+    cMutexLock MutexLock(&mutex);
+    enabled = false;
+    m_Interface.ClearButton();
+}
 
-    return 1;
+// ==================================
+// ! re-enable spu decoder (osd no longer in use)
+void cDxr3SpuDecoder::Enable(void)
+{
+    cMutexLock MutexLock(&mutex);
+    enabled = true;
+    doPalette();
+    doHighlight();
 }
 
 // Local variables:
Index: dxr3spudecoder.h
===================================================================
RCS file: /cvsroot/dxr3plugin/dxr3/dxr3spudecoder.h,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 dxr3spudecoder.h
--- dxr3spudecoder.h	21 Apr 2005 15:57:02 -0000	1.1.2.9
+++ dxr3spudecoder.h	16 May 2005 17:52:24 -0000
@@ -23,81 +23,21 @@
 #define _DXR3SPUDECODER_H_
 
 #include "dxr3vdrincludes.h"
-#include <inttypes.h>
-
-// ==================================
-typedef struct sDxr3SpuPalDescr
-{
-    uint8_t index;
-    uint8_t trans;
-
-    bool operator != (const sDxr3SpuPalDescr pd) const
-    {
-	return index != pd.index && trans != pd.trans;
-    };
-} aDxr3SpuPalDescr[4];
-
-// ==================================
-struct sDxr3SpuRect
-{
-    int x1, y1;
-    int x2, y2;
-
-    int width()
-    {
-	return x2 - x1 + 1;
-    };
-
-    int height()
-    {
-	return y2 - y1 + 1;
-    };
-
-    bool operator != (const sDxr3SpuRect r) const
-    {
-	return r.x1 != x1 || r.y1 != y1 || r.x2 != x2 || r.y2 != y2;
-    };
-};
-
-// ==================================
-class cDxr3SpuPalette
-{
-private:
-    uint32_t palette[16];
-
-public:
-    void setPalette(const uint32_t * pal);
-    uint32_t getColor(uint8_t idx, uint8_t trans) const;
-};
-
-// ==================================
-class cDxr3SpuBitmap
-{
-private:
-    sDxr3SpuRect bmpsize;
-    sDxr3SpuRect minsize[4];
-    uint8_t *bmp;
-
-    void putPixel(int xp, int yp, int len, uint8_t colorid);
-    void putFieldData(int field, uint8_t * data, uint8_t * endp);
-
-public:
-    cDxr3SpuBitmap(sDxr3SpuRect size, uint8_t * fodd, uint8_t * eodd,
-		   uint8_t * feven, uint8_t * eeven);
-    ~cDxr3SpuBitmap();
-
-    bool getMinSize(const aDxr3SpuPalDescr paldescr,
-		    sDxr3SpuRect & size) const;
-    cBitmap *getBitmap(const aDxr3SpuPalDescr paldescr,
-		       const cDxr3SpuPalette & pal, sDxr3SpuRect & size) const;
-};
+#include "dxr3interface.h"
 
 // ==================================
+//! spu decoder
+/*!
+  cDxr3SpuDecoder is used to show DVD
+  navigation and subtitles.
+  We make here use of the DVD-Functions
+  of the dxr3 driver/card.
+*/
 class cDxr3SpuDecoder : public cSpuDecoder
 {
 public:
     cDxr3SpuDecoder();
-    ~cDxr3SpuDecoder();
+    ~cDxr3SpuDecoder() {}
 
     int setTime(uint32_t pts);
 
@@ -108,80 +48,34 @@
 		      uint32_t palette);
     void clearHighlight();
     void Empty();
-#if VDRVERSNUM >= 10318
-    void processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow);
-#else
-    void processSPU(uint32_t pts, uint8_t * buf);
-#endif
-
-#if VDRVERSNUM >= 10311
     void Hide();
     void Draw();
     bool IsVisible()
     {
-	return osd != NULL;
+	return m_visible;
     }
+    void Disable();
+    void Enable();
+#if VDRVERSNUM >= 10318
+    void processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow);
+#else
+    void processSPU(uint32_t pts, uint8_t * buf);
 #endif
 
 private:
-    cOsd * osd;
-
-    // processing state
-    uint8_t *spu;
-    uint32_t spupts;
-    bool clean;
-    bool ready;
-    bool allowedShow;
-
-    enum spFlag
-    {
-	spNONE,
-	spHIDE,
-	spSHOW,
-	spMENU
-    };
-    spFlag state;
-
-    cSpuDecoder::eScaleMode scaleMode;
-
-    // highligh area
+    cDxr3Interface& m_Interface;///< interface to dxr3 driver
+    bool m_visible;		///< is anything visible (nav, osd, subtitles)
+    cMutex mutex;
+    bool enabled;
+    uint32_t palette[16];
     bool highlight;
-    sDxr3SpuRect hlpsize;
-    aDxr3SpuPalDescr hlpDescr;
-
-    // palette
-    cDxr3SpuPalette palette;
-
-    // spu info's
-    sDxr3SpuRect size;
-    aDxr3SpuPalDescr palDescr;
-
-    uint16_t DCSQ_offset;
-    uint16_t prev_DCSQ_offset;
-
-    cDxr3SpuBitmap *spubmp;
-
-    int cmdOffs()
-    {
-	return ((spu[2] << 8) | spu[3]);
-    }
-    int spuSize()
-    {
-	return ((spu[0] << 8) | spu[1]);
-    }
-
-    int ScaleYcoord(int value);
-    int ScaleYres(int value);
-    void DrawBmp(sDxr3SpuRect & size, cBitmap * bmp);
+    uint16_t hlsx, hlsy, hlex, hley;
+    uint32_t hlpalette;
+    eScaleMode m_ScaleMode;
+    void doHighlight();
+    void doPalette();
 };
 
-// ==================================
-inline uint32_t cDxr3SpuPalette::getColor(uint8_t idx, uint8_t trans) const
-{
-    uint8_t t = trans == 0x0f ? 0xff : trans << 4;
-    return palette[idx] | (t << 24);
-}
-
 #endif /*_DXR3SPUDECODER_H_*/
 
 // Local variables:
