#include "xineCommon.h"
#include "xineOsd.h"
#include "xineDevice.h"
#include "xineLib.h"
namespace PluginXine
{
#if APIVERSNUM < 10307
bool cXineOsd::OpenWindow(cWindow *Window)
{
cMutexLock 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)
{
cMutexLock osdLock(&m_osdMutex);
m_xineLib.CommitWindow(this, Window);
}
void cXineOsd::ShowWindow(cWindow *Window)
{
cMutexLock osdLock(&m_osdMutex);
m_windowVisible[ Window->Handle() ] = true;
m_xineLib.ShowWindow(this, Window);
}
void cXineOsd::HideWindow(cWindow *Window, bool Hide)
{
cMutexLock osdLock(&m_osdMutex);
m_windowVisible[ Window->Handle() ] = !Hide;
m_xineLib.HideWindow(this, Window, Hide);
}
void cXineOsd::MoveWindow(cWindow *Window, int x, int y)
{
cMutexLock osdLock(&m_osdMutex);
m_xineLib.MoveWindow(this, Window, x, y);
}
void cXineOsd::CloseWindow(cWindow *Window)
{
cMutexLock 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 */)
{
cMutexLock 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;
for (int i = 0; i < MAXNUMWINDOWS; i++)
m_xineLib.SendWindow(maxOsdWidth, maxOsdHeight, this, i, GetBitmap(i), videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY, dontOptimize);
#endif
m_xineLib.execFuncOsdFlush();
}
#if APIVERSNUM < 10509
cXineOsd::cXineOsd(cXineDevice &xineDevice, int x, int y)
#else
cXineOsd::cXineOsd(cXineDevice &xineDevice, 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)
{
//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
cMutexLock osdLock(&m_osdMutex);
if (Active())
SetActive(false);
#endif
}
void cXineOsd::HideOsd()
{
cMutexLock 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
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
&& 16 != a.bpp)
{
return oeBppNotSupported;
}
}
return oeOk;
}
eOsdError cXineOsd::SetAreas(const tArea *Areas, int NumAreas)
{
cMutexLock osdLock(&m_osdMutex);
return cOsd::SetAreas(Areas, NumAreas);
}
void cXineOsd::SaveRegion(int x1, int y1, int x2, int y2)
{
cMutexLock osdLock(&m_osdMutex);
cOsd::SaveRegion(x1, y1, x2, y2);
}
void cXineOsd::RestoreRegion(void)
{
cMutexLock osdLock(&m_osdMutex);
cOsd::RestoreRegion();
}
eOsdError cXineOsd::SetPalette(const cPalette &Palette, int Area)
{
cMutexLock osdLock(&m_osdMutex);
return cOsd::SetPalette(Palette, Area);
}
void cXineOsd::DrawPixel(int x, int y, tColor Color)
{
cMutexLock 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 */)
{
cMutexLock 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 */)
{
cMutexLock 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 */)
{
cMutexLock 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::DrawBitmapHor(int x, int y, int w, const cBitmap &Bitmap)
{
#ifdef VDR_HAS_TRUECOLOR_OSD
cMutexLock osdLock(&m_osdMutex);
cOsd::DrawBitmapHor(x, y, w, Bitmap);
#endif
}
void cXineOsd::DrawBitmapVert(int x, int y, int h, const cBitmap &Bitmap)
{
#ifdef VDR_HAS_TRUECOLOR_OSD
cMutexLock osdLock(&m_osdMutex);
cOsd::DrawBitmapVert(x, y, h, Bitmap);
#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 */)
{
cMutexLock osdLock(&m_osdMutex);
cOsd::DrawText(x, y, s, ColorFg, ColorBg, Font, Width, Height, Alignment);
}
void cXineOsd::DrawImage(u_int imageId, int x, int y, bool blend, int horRepeat /* = 1 */, int vertRepeat /* = 1 */)
{
#ifdef VDR_HAS_TRUECOLOR_OSD
cMutexLock osdLock(&m_osdMutex);
cOsd::DrawImage(imageId, x, y, blend, horRepeat, vertRepeat);
#endif
}
void cXineOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
{
cMutexLock osdLock(&m_osdMutex);
cOsd::DrawRectangle(x1, y1, x2, y2, Color);
}
void cXineOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color, int alphaGradH, int alphaGradV, int alphaGradStepH, int alphaGradStepV)
{
#ifdef VDR_HAS_TRUECOLOR_OSD
cMutexLock osdLock(&m_osdMutex);
cOsd::DrawRectangle(x1, y1, x2, y2, Color, alphaGradH, alphaGradV, alphaGradStepH, alphaGradStepV);
#endif
}
void cXineOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants /* = 0 */)
{
cMutexLock 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)
{
cMutexLock osdLock(&m_osdMutex);
cOsd::DrawSlope(x1, y1, x2, y2, Color, Type);
}
void cXineOsd::SetImagePath(u_int imageId, char const *path)
{
#ifdef VDR_HAS_TRUECOLOR_OSD
cMutexLock osdLock(&m_osdMutex);
cOsd::SetImagePath(imageId, path);
#endif
}
void cXineOsd::Flush(void)
{
// ::fprintf(stderr, "Flush ---: %s\n", ::ctime(&(const time_t &)::time(0)));
cMutexLock 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;
}
for (int i = 0; i < MAXNUMWINDOWS; i++)
m_xineLib.SendWindow(maxOsdWidth, maxOsdHeight, this, i, GetBitmap(i), videoLeft, videoTop, videoWidth, videoHeight, videoZoomX, videoZoomY);
m_xineLib.execFuncOsdFlush();
}
void cXineOsd::GetMaxOsdSize(int &maxOsdWidth, int &maxOsdHeight)
{
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;
}
}
void cXineOsd::SetActive(bool On)
{
#if APIVERSNUM >= 10509
cMutexLock 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
}
cXineOsdProvider::cXineOsdProvider(cXineDevice &xineDevice)
: cOsdProvider()
, m_xineDevice(xineDevice)
{
}
#if APIVERSNUM < 10509
cOsd *cXineOsdProvider::CreateOsd(int Left, int Top)
{
return m_xineDevice.NewOsd(Left, Top);
}
#else
cOsd *cXineOsdProvider::CreateOsd(int Left, int Top, uint Level)
{
if (Level == 10) { Left += (1920 - 720) / 2; Top += (1080 - 576); }
return m_xineDevice.NewOsd(Left, Top, Level);
}
cOsd *cXineOsdProvider::CreateTrueColorOsd(int Left, int Top, uint Level)
{
if (Level == 10) { Left += (1920 - 720) / 2; Top += (1080 - 576); }
return m_xineDevice.NewOsd(Left, Top, Level, true);
}
#endif
#endif
};