#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 #if APIVERSNUM >= 10733 // scale to the size and position stored by the last call to cDevice::CanScaleVideo m_xineDevice.ScaleVideo(m_xineDevice.GetScaleRect()); #else #ifdef SET_VIDEO_WINDOW m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, vidWin, dontOptimize); #endif #endif // APIVERSNUM >= 10733 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); #if APIVERSNUM >= 10733 // scale to the size and position stored by the last call to cDevice::CanScaleVideo m_xineDevice.ScaleVideo(m_xineDevice.GetScaleRect()); #else #ifdef SET_VIDEO_WINDOW m_xineLib.SetVideoWindow(maxOsdWidth, maxOsdHeight, vidWin); #endif #endif // APIVERSUM >= 10733 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 = dynamic_cast(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()); #if APIVERSNUM >= 20110 DestroyPixmap(pm); #else delete pm; #endif } } 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 };