diff options
Diffstat (limited to 'xineOsd.c')
-rw-r--r-- | xineOsd.c | 674 |
1 files changed, 674 insertions, 0 deletions
diff --git a/xineOsd.c b/xineOsd.c new file mode 100644 index 0000000..38ba2e7 --- /dev/null +++ b/xineOsd.c @@ -0,0 +1,674 @@ + +#include "xineCommon.h" + +#include "xineOsd.h" +#include "xineDevice.h" +#include "xineLib.h" + + + +namespace PluginXine +{ +#if APIVERSNUM < 10307 + + bool cXineOsd::OpenWindow(cWindow *Window) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + + m_windowVisible[ Window->Handle() ] = false; + + int maxOsdWidth, maxOsdHeight; + GetMaxOsdSize(maxOsdWidth, maxOsdHeight); + + return m_xineLib.OpenWindow(this, Window, maxOsdWidth, maxOsdHeight); + } + + void cXineOsd::CommitWindow(cWindow *Window) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + + m_xineLib.CommitWindow(this, Window); + } + + void cXineOsd::ShowWindow(cWindow *Window) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + + m_windowVisible[ Window->Handle() ] = true; + + m_xineLib.ShowWindow(this, Window); + } + + void cXineOsd::HideWindow(cWindow *Window, bool Hide) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + + m_windowVisible[ Window->Handle() ] = !Hide; + + m_xineLib.HideWindow(this, Window, Hide); + } + + void cXineOsd::MoveWindow(cWindow *Window, int x, int y) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + + m_xineLib.MoveWindow(this, Window, x, y); + } + + void cXineOsd::CloseWindow(cWindow *Window) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + + m_windowVisible[ Window->Handle() ] = false; + + m_xineLib.CloseWindow(this, Window); + } + +#endif + + + static int vl = -1, vt = -1, vw = -1, vh = -1, zx = -1, zy = -1; + + + void cXineOsd::ReshowCurrentOsd(const bool dontOptimize, const int frameLeft /* = -1 */, const int frameTop /* = -1 */, const int frameWidth /* = -1 */, const int frameHeight /* = -1 */, const int frameZoomX /* = -1 */, const int frameZoomY /* = -1 */) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + + int maxOsdWidth, maxOsdHeight; + GetMaxOsdSize(maxOsdWidth, maxOsdHeight); + +#if APIVERSNUM < 10307 + + (void)vl; + (void)vt; + (void)vw; + (void)vh; + (void)zx; + (void)zy; + + for (int i = 0; i < NumWindows(); i++) + { + cWindow *const window = GetWindowNr(i); + if (!window) + continue; + + if (dontOptimize) + m_xineLib.OpenWindow(this, window, maxOsdWidth, maxOsdHeight); + + m_xineLib.CommitWindow(this, window, !dontOptimize); + + if (m_windowVisible[ i ]) + Show(window->Handle()); + else + Hide(window->Handle()); + } + +#else + +#ifdef SET_VIDEO_WINDOW + + m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, vidWin, dontOptimize); + +#endif + + int videoLeft = frameLeft; + int videoTop = frameTop; + int videoWidth = frameWidth; + int videoHeight = frameHeight; + int videoZoomX = frameZoomX; + int videoZoomY = frameZoomY; + + if (frameLeft < 0 + || frameTop < 0 + || frameWidth < 0 + || frameHeight < 0 + || frameZoomX < 0 + || frameZoomY < 0) + { + m_xineLib.execFuncVideoSize(videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY); + } + +// ::fprintf(stderr, "frame: %d x %d, %d x %d\n", videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY); + + vl = videoLeft; + vt = videoTop; + vw = videoWidth; + vh = videoHeight; + zx = videoZoomX; + zy = videoZoomY; + + callSendWindow(maxOsdWidth, maxOsdHeight, videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY, dontOptimize); +#endif + + m_xineLib.execFuncOsdFlush(); + } + +#if APIVERSNUM < 10509 + cXineOsd::cXineOsd(cXineDevice &xineDevice, int w, int h, int x, int y) +#else + cXineOsd::cXineOsd(cXineDevice &xineDevice, int w, int h, int x, int y, uint Level) +#endif +#if APIVERSNUM < 10307 + : cOsdBase(x, y) +#elif APIVERSNUM < 10509 + : cOsd(x, y) +#else + : cOsd(x, y, Level) +#endif + , m_xineDevice(xineDevice) + , m_xineLib(xineDevice.m_xineLib) + , m_osdMutex(xineDevice.m_osdMutex) + , m_extentWidth(w) + , m_extentHeight(h) +#if APIVERSNUM >= 10717 + , m_pRawOsd(0) +#endif + { +//static int cnt = 0; +//fprintf(stderr, "x: %d, y: %d, cnt: %d\n", x, y, cnt); +// if (x == 58 && y == 46 && cnt++ == 5) { char cmd[500]; sprintf(cmd, "ddd /soft/vdr-" APIVERSION "/bin/vdr %d", getpid()); system(cmd); sleep(10); } //should never happen! + +#if APIVERSNUM < 10307 + ::memset(m_windowVisible, 0, sizeof (m_windowVisible)); +#endif + } + + cXineOsd::~cXineOsd() + { +#if APIVERSNUM < 10509 + HideOsd(); +#else + cXineOsdMutexLock osdLock(&m_osdMutex); + + if (Active()) + SetActive(false); +#endif +#if APIVERSNUM >= 10717 + delete m_pRawOsd; +#endif + } + + void cXineOsd::HideOsd() + { + cXineOsdMutexLock osdLock(&m_osdMutex); + +#if APIVERSNUM < 10307 + + for (int i = 0; i < MAXNUMWINDOWS; i++) + m_xineLib.CloseWindow(this, i); + +#else + + int maxOsdWidth, maxOsdHeight; + GetMaxOsdSize(maxOsdWidth, maxOsdHeight); + + tArea defaultWindow; + defaultWindow.x1 = 0; + defaultWindow.y1 = 0; + defaultWindow.x2 = 0; + defaultWindow.y2 = 0; + defaultWindow.bpp = 0; + + m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, defaultWindow); + + for (int i = 0; i < MAXNUMWINDOWS; i++) + m_xineLib.SendWindow(maxOsdWidth, maxOsdHeight, this, i); + +#endif + + m_xineDevice.OnFreeOsd(this); + + m_xineLib.execFuncOsdFlush(); + +// m_xineLib.execFuncGrabImage("/tmp/grab.jpg", true, 50, 1000, 1000); + } + +#if APIVERSNUM >= 10307 + + void cXineOsd::SetActive(bool On) + { +#if APIVERSNUM >= 10509 + + cXineOsdMutexLock osdLock(&m_osdMutex); + + if (On == Active()) + return; + + cOsd::SetActive(On); + + if (!m_xineDevice.ChangeCurrentOsd(this, On)) + return; + + if (On) + m_xineLib.ReshowCurrentOSD(); + else + HideOsd(); + +#endif + } + +#endif + +#if APIVERSNUM >= 10717 + + cPixmap *cXineOsd::CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort /* = cRect::Null */) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + return cOsd::CreatePixmap(Layer, ViewPort, DrawPort); + } + + void cXineOsd::DestroyPixmap(cPixmap *Pixmap) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DestroyPixmap(Pixmap); + } + + void cXineOsd::DrawImage(const cPoint &Point, const cImage &Image) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawImage(Point, Image); + } + + void cXineOsd::DrawImage(const cPoint &Point, int ImageHandle) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawImage(Point, ImageHandle); + } + +#endif + +#if APIVERSNUM >= 10307 + + eOsdError cXineOsd::CanHandleAreas(const tArea *Areas, int NumAreas) + { +// fprintf(stderr, "cXineOsd::CanHandleAreas(%p, %d)\n", Areas, NumAreas); + + const eOsdError retVal = cOsd::CanHandleAreas(Areas, NumAreas); + if (oeOk != retVal) + return retVal; + + for (int i = 0; i < NumAreas; i++) + { + const tArea &a = Areas[ i ]; +/* + fprintf(stderr, "Areas[ %d ]: (%d,%d)-(%d,%d)@%d\n" + , i + , a.x1 + , a.y1 + , a.x2 + , a.y2 + , a.bpp); +*/ + assert(a.x1 <= a.x2); + assert(a.y1 <= a.y2); + + if (1 != a.bpp + && 2 != a.bpp + && 4 != a.bpp + && 8 != a.bpp +#if APIVERSNUM >= 10717 + && (32 != a.bpp || !m_xineDevice.SupportsTrueColorOSD()) +#endif + ) + { + return oeBppNotSupported; + } + } + + return oeOk; + } + + eOsdError cXineOsd::SetAreas(const tArea *Areas, int NumAreas) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + return cOsd::SetAreas(Areas, NumAreas); + } + + void cXineOsd::SaveRegion(int x1, int y1, int x2, int y2) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::SaveRegion(x1, y1, x2, y2); + } + + void cXineOsd::RestoreRegion(void) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::RestoreRegion(); + } + + eOsdError cXineOsd::SetPalette(const cPalette &Palette, int Area) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + return cOsd::SetPalette(Palette, Area); + } + + void cXineOsd::DrawPixel(int x, int y, tColor Color) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawPixel(x, y, Color); + } + +#if APIVERSNUM < 10327 + void cXineOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg /* = 0 */, tColor ColorBg /* = 0 */) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawBitmap(x, y, Bitmap, ColorFg, ColorBg); +// fprintf(stderr, "drawbitmap\n"); + } +#elif APIVERSNUM < 10344 + void cXineOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg /* = 0 */, tColor ColorBg /* = 0 */, bool ReplacePalette /* = false */) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawBitmap(x, y, Bitmap, ColorFg, ColorBg, ReplacePalette); +// fprintf(stderr, "drawbitmap\n"); + } +#else + void cXineOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg /* = 0 */, tColor ColorBg /* = 0 */, bool ReplacePalette /* = false */, bool Overlay /* = false */) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawBitmap(x, y, Bitmap, ColorFg, ColorBg, ReplacePalette, Overlay); +// fprintf(stderr, "drawbitmap: (%d x %d) at (%d, %d) in (%d x %d)\n", Bitmap.Width(), Bitmap.Height(), x, y, Width(), Height()); + } +#endif + + void cXineOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width /* = 0 */, int Height /* = 0 */, int Alignment /* = taDefault */) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawText(x, y, s, ColorFg, ColorBg, Font, Width, Height, Alignment); + } + + void cXineOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawRectangle(x1, y1, x2, y2, Color); + } + + void cXineOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants /* = 0 */) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawEllipse(x1, y1, x2, y2, Color, Quadrants); + } + + void cXineOsd::DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type) + { + cXineOsdMutexLock osdLock(&m_osdMutex); + cOsd::DrawSlope(x1, y1, x2, y2, Color, Type); + } + + void cXineOsd::Flush(void) + { +// ::fprintf(stderr, "Flush ---: %s\n", ::ctime(&(const time_t &)::time(0))); + cXineOsdMutexLock osdLock(&m_osdMutex); +// ::fprintf(stderr, "Flush +++: %s\n", ::ctime(&(const time_t &)::time(0))); +#if APIVERSNUM >= 10509 + if (!Active()) + return; +#endif +// static int cnt = 0; +// fprintf(stderr, "cXineOsd::Flush() %d\n", cnt++); + + int maxOsdWidth, maxOsdHeight; + GetMaxOsdSize(maxOsdWidth, maxOsdHeight); + +#ifdef SET_VIDEO_WINDOW + + m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, vidWin); + +#endif + + int videoLeft = -1; + int videoTop = -1; + int videoWidth = -1; + int videoHeight = -1; + int videoZoomX = -1; + int videoZoomY = -1; + + m_xineLib.execFuncVideoSize(videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY); + + if (videoLeft < 0) videoLeft = 0; + if (videoTop < 0) videoTop = 0; + if (videoZoomX < 0) videoZoomX = 100; + if (videoZoomY < 0) videoZoomY = 100; + + if (vl != videoLeft + || vt != videoTop + || vw != videoWidth + || vh != videoHeight + || zx != videoZoomX + || zy != videoZoomY) + { + xfprintf(stderr, "frame: (%d, %d)-(%d, %d), zoom: (%.2lf, %.2lf)\n", videoLeft, videoTop, videoWidth, videoHeight, videoZoomX / 100.0, videoZoomY / 100.0); +// ::fprintf(stderr, "video: %d x %d, %d x %d @ %d %% x %d %%\n", videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY); + + vl = videoLeft; + vt = videoTop; + vw = videoWidth; + vh = videoHeight; + zx = videoZoomX; + zy = videoZoomY; + } + + callSendWindow(maxOsdWidth, maxOsdHeight, videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY); + + m_xineLib.execFuncOsdFlush(); + } + + void cXineOsd::callSendWindow(const int maxOsdWidth, const int maxOsdHeight, const int videoLeft, const int videoTop, const int videoWidth, const int videoHeight, const int videoZoomX, const int videoZoomY, const bool dontOptimize /* = false */) + { +#if APIVERSNUM >= 10717 +bool head = false; + if (IsTrueColor()) + { + if (m_pRawOsd) + { + if (m_pRawOsd->DrawPort().Width() != Width() + || m_pRawOsd->DrawPort().Height() != Height()) + { + delete m_pRawOsd; + m_pRawOsd = 0; + } + } + + if (!m_pRawOsd) + { + m_pRawOsd = new cPixmapMemory(0, cRect(0, 0, Width(), Height())); + m_pRawOsd->Clear(); +if (!head) +{ + head = true; +// fprintf(stderr, "OSD: -c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c\n"); +} + } + + while (cPixmapMemory *pm = RenderPixmaps()) + { +if (!head) +{ + head = true; +// fprintf(stderr, "OSD: --------------------------------------------------\n"); +} +/* + fprintf(stderr, "OSD: X: %4d, Y: %4d, W: %4d, H: %4d, X: %4d, Y: %4d, W: %4d, H: %4d\n" +, pm->ViewPort().X() +, pm->ViewPort().Y() +, pm->ViewPort().Width() +, pm->ViewPort().Height() +, pm->DrawPort().X() +, pm->DrawPort().Y() +, pm->DrawPort().Width() +, pm->DrawPort().Height() +); +*/ + m_pRawOsd->Copy(pm, pm->DrawPort().Shifted(-pm->DrawPort().Point()), pm->ViewPort().Point()); + delete pm; + } + } + else if (m_pRawOsd) + { + delete m_pRawOsd; + m_pRawOsd = 0; +/* +if (head) + fprintf(stderr, "OSD: =d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d=d\n"); +*/ + } + + if (m_pRawOsd) + { + cXinePixmapMemoryAdapter adapter(m_pRawOsd); +/* +cXineAdapter *bm = adapter; +int x0, y0, x1, y1; +bool d = bm->Dirty(x0, y0, x1, y1); +if (head) + fprintf(stderr, d ? "OSD: x: %4d, y: %4d, w: %4d, h: %4d, x0: %4d, y0: %4d, x1: %4d, y1: %4d\n" : "OSD: x: %4d, y: %4d, w: %4d, h: %4d\n" +, bm->X0() +, bm->Y0() +, bm->Width() +, bm->Height() +, x0 +, y0 +, x1 +, y1 +); +*/ + m_xineLib.SendWindow(maxOsdWidth, maxOsdHeight, this, 0, adapter, videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY, dontOptimize); + + for (int i = 1; i < MAXNUMWINDOWS; i++) + m_xineLib.SendWindow(maxOsdWidth, maxOsdHeight, this, i); +/* +if (head) + fprintf(stderr, "OSD: ==================================================\n"); +*/ + } + else +#endif + { + for (int i = 0; i < MAXNUMWINDOWS; i++) + { + cXineBitmapAdapter adapter(GetBitmap(i)); + m_xineLib.SendWindow(maxOsdWidth, maxOsdHeight, this, i, adapter, videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY, dontOptimize); + } + } + } + + void cXineOsd::GetMaxOsdSize(int &maxOsdWidth, int &maxOsdHeight) + { + maxOsdWidth = m_extentWidth; + maxOsdHeight = m_extentHeight; + return; +/* + maxOsdWidth = 0; + maxOsdHeight = 0; + + for (int i = 0; i < MAXNUMWINDOWS; i++) + { + cBitmap *const p = GetBitmap(i); + if (!p) + continue; + + int w = Left() + p->X0() + p->Width(); + int h = Top() + p->Y0() + p->Height(); + + if (maxOsdWidth < w) + maxOsdWidth = w; + + if (maxOsdHeight < h) + maxOsdHeight = h; + } +//fprintf(stderr, "GetMaxOsdSize(%d, %d)\n", maxOsdWidth, maxOsdHeight); +#if APIVERSNUM >= 10707 + if (maxOsdWidth <= m_xineDevice.Settings().OsdExtentParams().GetOsdExtentWidth() + && maxOsdHeight <= m_xineDevice.Settings().OsdExtentParams().GetOsdExtentHeight()) + { + maxOsdWidth = m_xineDevice.Settings().OsdExtentParams().GetOsdExtentWidth(); + maxOsdHeight = m_xineDevice.Settings().OsdExtentParams().GetOsdExtentHeight(); + } + else +#endif + if (maxOsdWidth > 1920 || maxOsdHeight > 1080) + { + if (maxOsdWidth < 1920) + maxOsdWidth = 1920; + + if (maxOsdHeight < 1080) + maxOsdHeight = 1080; + } + else if (maxOsdWidth > 1280 || maxOsdHeight > 720) + { + maxOsdWidth = 1920; + maxOsdHeight = 1080; + } + else if (maxOsdWidth > 720 || maxOsdHeight > 576) + { + maxOsdWidth = 1280; + maxOsdHeight = 720; + } + else + { + maxOsdWidth = 720; + maxOsdHeight = 576; + } +*/ + } + + + + cXineOsdMutexLock::cXineOsdMutexLock(cMutex *const pOsdMutex) + : m_pOsdLock(0) +#if APIVERSNUM >= 10717 + , m_pPixmapMutexLock(0) +#endif + { +#if APIVERSNUM >= 10717 + m_pPixmapMutexLock = new cPixmapMutexLock; +#endif + m_pOsdLock = new cMutexLock(pOsdMutex); + } + + cXineOsdMutexLock::~cXineOsdMutexLock() + { + delete m_pOsdLock; + +#if APIVERSNUM >= 10717 + delete m_pPixmapMutexLock; +#endif + } + + + + cXineOsdProvider::cXineOsdProvider(cXineDevice &xineDevice) + : cOsdProvider() + , m_xineDevice(xineDevice) + { + } + +#if APIVERSNUM < 10509 + cOsd *cXineOsdProvider::CreateOsd(int Left, int Top) + { + return m_xineDevice.NewOsd(0, 0, Left, Top); + } +#else + cOsd *cXineOsdProvider::CreateOsd(int Left, int Top, uint Level) + { + return m_xineDevice.NewOsd(0, 0, Left, Top, Level); + } + + cOsd *cXineOsdProvider::CreateOsd(int ExtentWidth, int ExtentHeight, int Left, int Top, uint Level) + { + return m_xineDevice.NewOsd(ExtentWidth, ExtentHeight, Left, Top, Level); + } +#endif + +#if APIVERSNUM >= 10717 + bool cXineOsdProvider::ProvidesTrueColor() + { + return true; + } +#endif + +#endif + + + +}; |