From ff1d56adc362419aea63153328f7e5381fd3a63b Mon Sep 17 00:00:00 2001 From: Marten Richter Date: Mon, 22 Dec 2014 19:47:53 +0100 Subject: [PATCH] Added Vector based OSD for windows (Vista and later) --- audioplayer.cc | 2 +- boxstack.cc | 2 +- boxx.cc | 26 + boxx.h | 4 +- command.cc | 8 +- defines.h | 13 +- message.cc | 3 +- message.h | 5 +- osdopenvg.cc | 36 +- osdopenvg.h | 5 +- osdvector.cc | 22 +- osdvector.h | 48 +- osdwinpixel.cc | 12 + osdwinpixel.h | 4 + osdwinvector.cc | 1435 ++++++++++++++++++++++++++++++++++++++ osdwinvector.h | 150 ++++ player.cc | 10 +- playerliveradio.cc | 8 +- playerlivetv.cc | 12 +- playermedia.cc | 6 +- playerradio.cc | 4 +- surfacevector.cc | 100 ++- teletextdecodervbiebu.cc | 4 +- threadwin.h | 1 - udp.cc | 2 +- vaudioselector.cc | 26 +- vchannellist.cc | 12 +- vchannelselect.cc | 4 +- vcolourtuner.cc | 4 +- vconnect.cc | 2 +- vepg.cc | 21 +- vepglistadvanced.cc | 26 +- vepgsettimer.cc | 14 +- vepgsummary.cc | 14 +- videowin.cc | 10 +- vompreswin.h | 1 + vompwin.rc | 11 + vopts.cc | 8 +- vpicturebanner.cc | 4 +- vquestion.cc | 12 +- vradiorec.cc | 8 +- vrecmove.cc | 10 +- vrecording.cc | 31 +- vrecordinglist.cc | 10 +- vrecordingmenu.cc | 10 +- vserverselect.cc | 6 +- vsleeptimer.cc | 6 +- vtimeredit.cc | 4 +- vtimerlist.cc | 8 +- vvideolivetv.cc | 44 +- vvideorec.cc | 54 +- vvideorec.h | 2 + vwelcome.cc | 8 +- windowsosd.cc | 142 +++- windowsosd.h | 18 +- winmain.cc | 11 +- wpictureview.cc | 23 + wpictureview.h | 1 + wselectlist.cc | 2 +- 59 files changed, 2192 insertions(+), 297 deletions(-) create mode 100644 osdwinvector.cc create mode 100644 osdwinvector.h diff --git a/audioplayer.cc b/audioplayer.cc index f0930c1..c1b2b30 100644 --- a/audioplayer.cc +++ b/audioplayer.cc @@ -295,7 +295,7 @@ void AudioPlayer::sendFrontendMessage(ULONG para) threadUnlock(); m->from = this; m->message = Message::PLAYER_EVENT; - m->parameter = para; + m->parameter.num = para; Command::getInstance()->postMessageFromOuterSpace(m); } diff --git a/boxstack.cc b/boxstack.cc index 55ffa00..3187a5c 100644 --- a/boxstack.cc +++ b/boxstack.cc @@ -588,7 +588,7 @@ void BoxStack::processMessage(Message* m) } case Message::ADD_VIEW: // currently not used by anything but it might come in useful again { - Boxx* toAdd = (Boxx*)m->parameter; + Boxx* toAdd = (Boxx*)m->parameter.num; add(toAdd); toAdd->draw(); update(toAdd); diff --git a/boxx.cc b/boxx.cc index 0e2687f..e775ea8 100644 --- a/boxx.cc +++ b/boxx.cc @@ -572,3 +572,29 @@ Surface* Boxx::getSurface() if (parent) return parent->getSurface(); return surface; } + +bool Boxx::mouseMove(int x, int y) +{ + if ((x >= area.x) && (x= area.y) && (y < area.y2())) + { + return true; + } + else + { + return false; + } +} + +bool Boxx::mouseLBDOWN(int x, int y) +{ + if ((x >= area.x) && (x= area.y) && (y < area.y2())) + { + return true; + } + else + { + return false; + } +} diff --git a/boxx.h b/boxx.h index e6dbce1..15248f6 100644 --- a/boxx.h +++ b/boxx.h @@ -63,8 +63,8 @@ class Boxx virtual void preDelete() {} virtual int handleCommand(int x) { return 0; } virtual void processMessage(Message* m) {} - virtual bool mouseMove(int x, int y) { return false; } - virtual bool mouseLBDOWN(int x, int y) { return false; } + virtual bool mouseMove(int x, int y); + virtual bool mouseLBDOWN(int x, int y); virtual bool mouseAndroidScroll(int x, int y,int sx, int sy) { return false; } virtual void deactivateAllControls() {} diff --git a/command.cc b/command.cc index e81c6f0..24cd815 100644 --- a/command.cc +++ b/command.cc @@ -433,7 +433,7 @@ void Command::processMessage(Message* m) } case Message::UDP_BUTTON: { - handleCommand(m->parameter); + handleCommand(m->parameter.num); break; } case Message::CHANGE_LANGUAGE: @@ -469,16 +469,16 @@ void Command::processMessage(Message* m) //Log::getInstance()->log("Command", Log::DEBUG, "TVMedia NEW_PICTURE"); OsdVector *osdv=dynamic_cast(Osd::getInstance()); if (osdv) { - osdv->informPicture(m->tag,m->parameter); + osdv->informPicture(m->tag,m->parameter.handle); } } break; case Message::NEW_PICTURE_STATIC: { - //Log::getInstance()->log("Command", Log::DEBUG, "TVMedia NEW_PICTURE %x %x",m->tag,m->parameter); + //Log::getInstance()->log("Command", Log::DEBUG, "TVMedia NEW_PICTURE %x %x",m->tag,m->parameter.num); OsdVector *osdv=dynamic_cast(Osd::getInstance()); if (osdv) { - osdv->informPicture(((unsigned long long)m->tag)<<32LL,m->parameter); + osdv->informPicture(((unsigned long long)m->tag)<<32LL,m->parameter.handle); } } break; diff --git a/defines.h b/defines.h index beb9146..6d12315 100644 --- a/defines.h +++ b/defines.h @@ -39,13 +39,23 @@ long long getTimeMS(); int getClockRealTime(struct timespec *tp); +//#define WINDOWS_LEGACY #ifdef WIN32 - #define Surface_TYPE SurfaceWin + #define Thread_TYPE ThreadWin #define ThreadID_TYPE unsigned int + #define VectorHandle void* +#ifndef WINDOWS_LEGACY + #define Osd_TYPE OsdWinVector + #define Surface_TYPE SurfaceVector + #define GRADIENT_DRAWING + #define ADVANCED_MENUES // This is for special HD versions of our menus +#else #define Osd_TYPE OsdWinPixel + #define Surface_TYPE SurfaceWin +#endif #define RemoteStartDev ""//No devices passed @@ -131,6 +141,7 @@ int getClockRealTime(struct timespec *tp); #define HANDLE_VT_SWITCHING #define GRADIENT_DRAWING #define ADVANCED_MENUES // This is for special HD versions of our menus + #define VectorHandle unsigned int #define PICTURE_DECODER_MAGICK #define PICTURE_DECODER_OMX diff --git a/message.cc b/message.cc index 84edad1..94c65f1 100644 --- a/message.cc +++ b/message.cc @@ -25,6 +25,7 @@ Message::Message() from = NULL; to = NULL; message = 0; - parameter = 0; + parameter.num = 0; + parameter.handle = 0; tag = 0; } diff --git a/message.h b/message.h index b153b7b..799e505 100644 --- a/message.h +++ b/message.h @@ -42,7 +42,10 @@ class Message void* from; void* to; ULONG message; - ULONG parameter; + union { + ULONG num; + VectorHandle handle; + } parameter; ULONG tag; // use this for identifying which object / question is being replied to const static ULONG QUESTION_YES = 1; diff --git a/osdopenvg.cc b/osdopenvg.cc index e59fb79..90f0d37 100644 --- a/osdopenvg.cc +++ b/osdopenvg.cc @@ -1098,7 +1098,7 @@ void OsdOpenVG::executeDrawCommand(SVGCommand & command) } break; } } -int imcount=0;// this is debug code and should not go into release +//int imcount=0;// this is debug code and should not go into release unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) { switch (command.task){ @@ -1108,8 +1108,8 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) return 0; } break; - case OVGdestroyImageRef: {imcount--; - Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Destroy %x %d",command.param1,imcount); + case OVGdestroyImageRef: {//imcount--; + //Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia Draw Image Destroy %x %d",command.param1,imcount); vgDestroyImage((VGImage)command.param1); return 0; } break; @@ -1118,7 +1118,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) vgDestroyPaint((VGPaint)command.param1); return 0; } break; - case OVGcreateImagePalette: {imcount++; + case OVGcreateImagePalette: {//imcount++; VGImage input=vgCreateImage(VG_A_8,command.param1, command.param2, VG_IMAGE_QUALITY_NONANTIALIASED| VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER); @@ -1141,7 +1141,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) return handle; } break; - case OVGcreateMonoBitmap: {imcount++; + case OVGcreateMonoBitmap: {//imcount++; VGImage handle=vgCreateImage(VG_A_1,command.param1, command.param2, VG_IMAGE_QUALITY_FASTER); //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono %d %d %x %d",command.param1,command.param2,vgGetError(),handle); @@ -1188,7 +1188,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create file %d %d %x %d",command.param1,command.param2,vgGetError(),handle); return handle; } break;*/ - case OVGcreateImageMemory: {imcount++; + case OVGcreateImageMemory: {//imcount++; PictureInfo *info = (PictureInfo*) command.data; VGImage handle; Log::getInstance()->log("OSD", Log::DEBUG, "TVMedia OVGcreateImageMemory %d",imcount); @@ -1217,7 +1217,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) delete info; } break; - case OVGcreateEGLImage: {imcount++; + case OVGcreateEGLImage: {//imcount++; PictureInfo *info = (PictureInfo*) command.data; VGImage handle; @@ -1243,7 +1243,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) Message* m = new Message(); m->from=this; m->to=Command::getInstance(); - m->parameter = info->handle; + m->parameter.handle = info->handle; if (!static_image) { m->message=Message::NEW_PICTURE; m->tag = info->lindex; @@ -1314,10 +1314,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command) return handle; } break; - case OVGimageUploadLine: { - vgImageSubData((VGImage)command.param1,command.data,0,VG_sARGB_8888,0,command.param2,command.param3,1); - return 0; - } break; + } } @@ -1405,18 +1402,7 @@ unsigned int OsdOpenVG::putOpenVGCommand(OpenVGCommand& comm,bool wait) return 0; } -void OsdOpenVG::imageUploadLine(ImageIndex index,unsigned int j,unsigned int width,void *data) -{ - vgImageSubData((VGImage)index,data,0,VG_sARGB_8888,0,j,width,1); - struct OpenVGCommand comm; - comm.task=OVGimageUploadLine; - comm.param1=index; - comm.param2=j; - comm.param3=width; - comm.data=data; - putOpenVGCommand(comm,true); -} void OsdOpenVG::destroyImageRef(ImageIndex index) { @@ -1494,7 +1480,7 @@ ImageIndex OsdOpenVG::createImagePalette(int width,int height,const unsigned cha return putOpenVGCommand(comm,true); } -void OsdOpenVG::destroyStyleRef(unsigned int index) +void OsdOpenVG::destroyStyleRef(VectorHandle index) { struct OpenVGCommand comm; comm.task=OVGdestroyPaint; @@ -1502,7 +1488,7 @@ void OsdOpenVG::destroyStyleRef(unsigned int index) putOpenVGCommand(comm,false); } -unsigned int OsdOpenVG::createStyleRef(const DrawStyle &c) +VectorHandle OsdOpenVG::createStyleRef(const DrawStyle &c) { unsigned int col=c.rgba(); struct OpenVGCommand comm; diff --git a/osdopenvg.h b/osdopenvg.h index efcb2ea..2367cbe 100644 --- a/osdopenvg.h +++ b/osdopenvg.h @@ -93,7 +93,6 @@ class OsdOpenVG : public OsdVector, public Thread_TYPE, public EGLPictureCreator float getFontHeight(); float getCharWidth(wchar_t c); - void imageUploadLine(ImageIndex index,unsigned int j,unsigned int width,void *data); int getFontNames(const char *** names,const char *** names_keys); @@ -113,8 +112,8 @@ protected: ImageIndex createMonoBitmap(void *base,int width,int height); ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data); void createPicture(struct PictureInfo& pict_inf); - void destroyStyleRef(unsigned int index); - unsigned int createStyleRef(const DrawStyle &c); + void destroyStyleRef(VectorHandle index); + VectorHandle createStyleRef(const DrawStyle &c); bool getStaticImageData(unsigned int static_id, UCHAR **userdata, ULONG *length); void drawSetTrans(SurfaceCommands & sc); diff --git a/osdvector.cc b/osdvector.cc index 9d25beb..3c1812f 100644 --- a/osdvector.cc +++ b/osdvector.cc @@ -482,12 +482,12 @@ void OsdVector::cleanupOrphanedRefs() } - map::iterator sitty=styles.begin(); + map::iterator sitty = styles.begin(); while (sitty!=styles.end()) { - map::iterator curitty=styles_ref.find((*sitty).second); + map::iterator curitty = styles_ref.find((*sitty).second); int count=(*curitty).second; if (count==0) { - unsigned int ref=(*curitty).first; + VectorHandle ref = (*curitty).first; styles.erase(sitty++); styles_ref.erase(curitty++); styles_lastit_valid=styles_ref_lastit_valid=false; @@ -510,21 +510,21 @@ int OsdVector::getImageRef(ImageIndex index) surfaces_mutex.Unlock(); } -void OsdVector::incStyleRef(unsigned int index) +void OsdVector::incStyleRef(VectorHandle index) { if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) { styles_ref_lastit_valid=false; styles_ref_lastit=styles_ref.find(index); } if (styles_ref_lastit==styles_ref.end()) { - styles_ref_lastit=styles_ref.insert(std::pair(index,1)).first; + styles_ref_lastit = styles_ref.insert(std::pair(index, 1)).first; } else { (*styles_ref_lastit).second++; } styles_ref_lastit_valid=true; } -void OsdVector::removeStyleRef(unsigned int index) +void OsdVector::removeStyleRef(VectorHandle index) { if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) { styles_ref_lastit_valid=false; @@ -536,10 +536,10 @@ void OsdVector::removeStyleRef(unsigned int index) } } -unsigned int OsdVector::getStyleRef(const DrawStyle &c) +VectorHandle OsdVector::getStyleRef(const DrawStyle &c) { surfaces_mutex.Lock(); - unsigned int style_handle=0; + VectorHandle style_handle = 0; if (!styles_lastit_valid || (*styles_lastit).first!=c) { styles_lastit_valid=false; styles_lastit=styles.find(c); @@ -550,7 +550,7 @@ unsigned int OsdVector::getStyleRef(const DrawStyle &c) surfaces_mutex.Unlock(); style_handle=createStyleRef(c); surfaces_mutex.Lock(); - styles_lastit=styles.insert(std::pair(c,style_handle)).first; + styles_lastit = styles.insert(std::pair(c, style_handle)).first; } else { style_handle=(*styles_lastit).second; @@ -576,7 +576,7 @@ unsigned int OsdVector::getStyleRef(const DrawStyle &c) -int OsdVector::getStyleRef(unsigned int index) +int OsdVector::getStyleRef(VectorHandle index) { if (!styles_ref_lastit_valid || (*styles_ref_lastit).first!=index) { styles_ref_lastit_valid=false; @@ -672,7 +672,7 @@ void OsdVector::informPicture(LoadIndex index, ImageIndex imageIndex) if (itty==loadindex_ref.end() || (*itty).second == 0) { // we do not want the picture anymore . Really... // fill images_ref in to not irritate the garbage collector - if (images_ref.find(index)==images_ref.end()) { + if (images_ref.find(image_index)==images_ref.end()) { images_ref[image_index]=0; } } else { diff --git a/osdvector.h b/osdvector.h index fe097e4..5bb45de 100644 --- a/osdvector.h +++ b/osdvector.h @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + #ifndef OSDVECTOR_H #define OSDVECTOR_H #include "osd.h" @@ -60,7 +61,7 @@ enum Corner{ TopLeftLimited }; -typedef unsigned int ImageIndex; +typedef VectorHandle ImageIndex; typedef unsigned long long LoadIndex; class SVGCommand @@ -69,10 +70,11 @@ public: SVGCommand() { instr=DrawNoop; - x=y=w=h=reference=0; + x=y=w=h=0; + reference = NULL; }; - inline static SVGCommand PaintPath(float ix, float iy,float iw,float ih,PathIndex path,unsigned int ref) + inline static SVGCommand PaintPath(float ix, float iy, float iw, float ih, PathIndex path, VectorHandle ref) { SVGCommand nc; nc.instr=DrawPath; @@ -85,7 +87,7 @@ public: return nc; }; - inline static SVGCommand PaintImageLoading(LoadIndex load_in,float ix, float iy,float iw,float ih,unsigned int ref, Corner corner=TopLeft) + inline static SVGCommand PaintImageLoading(LoadIndex load_in, float ix, float iy, float iw, float ih, VectorHandle ref, Corner corner = TopLeft) { SVGCommand nc; nc.instr=DrawImageLoading; @@ -99,7 +101,7 @@ public: return nc; }; - inline static SVGCommand PaintImage(float ix, float iy,float iw,float ih,ImageIndex image_in,unsigned int ref, Corner corner=TopLeft) + inline static SVGCommand PaintImage(float ix, float iy, float iw, float ih, ImageIndex image_in, VectorHandle ref, Corner corner = TopLeft) { SVGCommand nc; nc.instr=DrawImage; @@ -142,7 +144,7 @@ public: }; - inline static void PaintGlyph(SVGCommand& nc, float ix, float iy,wchar_t char_in,unsigned int ref) + inline static void PaintGlyph(SVGCommand& nc, float ix, float iy, wchar_t char_in, VectorHandle ref) { nc.instr=DrawGlyph; nc.x=ix; @@ -166,7 +168,7 @@ public: return ((x+w) loadindex_ref; map tvmedias_load; map tvmedias_load_inv; @@ -379,19 +377,19 @@ protected: - void incStyleRef(unsigned int index); - int getStyleRef(unsigned int index); - virtual void destroyStyleRef(unsigned int index)=0; + void incStyleRef(VectorHandle index); + int getStyleRef(VectorHandle index); + virtual void destroyStyleRef(VectorHandle index) = 0; - map styles; - map styles_ref; - map::iterator styles_lastit; + map styles; + map styles_ref; + map::iterator styles_lastit; bool styles_lastit_valid; - map::iterator styles_ref_lastit; + map::iterator styles_ref_lastit; bool styles_ref_lastit_valid; - virtual unsigned int createStyleRef(const DrawStyle &c)=0; + virtual VectorHandle createStyleRef(const DrawStyle &c) = 0; void dereferenceSVGCommand(std::vector& commands ); void referenceSVGCommand(std::vector& commands ); @@ -417,4 +415,4 @@ protected: -#endif +#endif \ No newline at end of file diff --git a/osdwinpixel.cc b/osdwinpixel.cc index a57a8a3..d7da2bc 100644 --- a/osdwinpixel.cc +++ b/osdwinpixel.cc @@ -17,7 +17,9 @@ along with VOMP; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "defines.h" +#ifndef GRADIENT_DRAWING #include "osdwinpixel.h" #include "mtd.h" @@ -81,6 +83,7 @@ int OsdWinPixel::shutdown() { if (!initted) return 0; initted = 0; + stopRenderLoop(); shutdownDirect3D9Objects(); Gdiplus::GdiplusShutdown(gdiptoken); @@ -110,4 +113,13 @@ void OsdWinPixel::lostRecreateObjects() screen->display(); } +void OsdWinPixel::getTextureCoordinates(FLOAT*x, FLOAT*y) +{ + Video* video = Video::getInstance(); + FLOAT texx = ((float)video->getScreenWidth()) / 1024.f; + FLOAT texy = ((float)video->getScreenHeight()) / 1024.f; + *x = texx; + *y = texy; +} +#endif diff --git a/osdwinpixel.h b/osdwinpixel.h index 042f38f..863813c 100644 --- a/osdwinpixel.h +++ b/osdwinpixel.h @@ -47,11 +47,15 @@ class OsdWinPixel : public Osd, public WindowsOsd Surface * createNewSurface(); + + protected: LPDIRECT3DTEXTURE9 getNextOsdTexture(); void lostDestroyObjects(); void lostRecreateObjects(); + void getTextureCoordinates(FLOAT*, FLOAT*); + ULONG_PTR gdiptoken; Gdiplus::GdiplusStartupInput gdipstartup; diff --git a/osdwinvector.cc b/osdwinvector.cc new file mode 100644 index 0000000..87b4002 --- /dev/null +++ b/osdwinvector.cc @@ -0,0 +1,1435 @@ +/* + Copyright 2014 Marten Richter + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + + +#include "osdwinvector.h" +#include "mtd.h" +#include "videowin.h" +#include "surfacewin.h" + + +#include "message.h" +#include "command.h" + +#include "teletxt/txtfont.h" + +#include + +#define OSD_BUFFER_WIDTH 1280 +#define OSD_BUFFER_HEIGHT 720 + +#include "staticartwork.h" + +#define EXTERNALPICTURE(name, fname, fileextension) #name, + +char *ext_pict_name[] { + "None", + EXTERNAL_PICTS +}; + +#undef EXTERNALPICTURE + + +class WICPictDecoder : public OsdVector::PictureDecoder { +public: + WICPictDecoder(OsdVector::PictureReader* treader, OsdWinVector *posd); + virtual ~WICPictDecoder(); + + unsigned char *decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem); + + bool getDecodedPicture(struct OsdVector::PictureInfo& pict_inf); + + void freeReference(void * ref); + +protected: + OsdVector::PictureInfo pictInf; + bool pictInfValid; + IWICImagingFactory *wicfactory; + OsdWinVector * osd; +}; + +WICPictDecoder::WICPictDecoder(OsdVector::PictureReader* treader, OsdWinVector *posd) : OsdVector::PictureDecoder(treader) +{ + pictInfValid = false; + osd = posd; + HRESULT hres = CoCreateInstance(CLSID_WICImagingFactory, + NULL,CLSCTX_INPROC_SERVER, + IID_IWICImagingFactory, (void**)&wicfactory); + + +} + +WICPictDecoder::~WICPictDecoder() +{ + wicfactory->Release(); +} + +unsigned char * WICPictDecoder::decodePicture(LoadIndex index, unsigned char * buffer, unsigned int length, bool freemem) +{ + if (pictInfValid) return buffer; // does support only one image at a Time; + + IWICStream * stream = NULL; + IWICBitmapDecoder *decoder = NULL; + IWICBitmapFrameDecode *source = NULL; + IWICFormatConverter *converter = NULL; + + HRESULT hres; + + hres = wicfactory->CreateStream(&stream); + + if (hres != S_OK) + { + + Log::getInstance()->log("WICDecoder", Log::DEBUG, "Could not create stream %d", hres); + return buffer; + } + hres = stream->InitializeFromMemory(buffer, length); + + if (hres != S_OK) + { + Log::getInstance()->log("WICDecoder", Log::DEBUG, "Could not initialize from memory %d", hres); + stream->Release(); + return buffer; + } + + + hres = wicfactory->CreateDecoderFromStream(stream, NULL, WICDecodeMetadataCacheOnLoad, &decoder); + if (hres != S_OK) + { + + Log::getInstance()->log("WICDecoder", Log::DEBUG, "Could not create decoder %d", hres); + stream->Release(); + return buffer; + } + + hres = decoder->GetFrame(0, &source); + if (hres != S_OK) + { + + Log::getInstance()->log("WICDecoder", Log::DEBUG, "Could not get source %d", hres); + decoder->Release(); + stream->Release(); + return buffer; + } + + hres = wicfactory->CreateFormatConverter(&converter); + if (hres != S_OK) + { + + Log::getInstance()->log("WICDecoder", Log::DEBUG, "Could not get source %d", hres); + source->Release(); + decoder->Release(); + stream->Release(); + return buffer; + } + + hres= converter->Initialize(source, GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, NULL, 0.f, WICBitmapPaletteTypeMedianCut); + if (hres != S_OK) + { + + Log::getInstance()->log("WICDecoder", Log::DEBUG, "Could not initialise converter %d", hres); + converter->Release(); + source->Release(); + decoder->Release(); + stream->Release(); + return buffer; + } + + ID2D1RenderTarget * rt=osd->LockOsdDrawing(); + + + ID2D1Bitmap* bitmap; + hres = rt->CreateBitmapFromWicBitmap(converter, NULL, &bitmap); + if (hres == S_OK) { + D2D1_SIZE_F size = bitmap->GetSize(); + pictInf.reference = (void*)bitmap; + pictInf.width = size.width; + pictInf.height = size.height; + pictInf.image = bitmap; + pictInf.decoder = this; + pictInf.type = OsdVector::PictureInfo::D2DBitmap; + pictInf.lindex = index; + pictInfValid = true; + if (freemem) { + free(buffer); + } + } + + osd->UnlockOsdDrawing(); + + converter->Release(); + source->Release(); + decoder->Release(); + stream->Release(); + + if (pictInfValid) return NULL; + else return buffer; +} + +void WICPictDecoder::freeReference(void * ref) +{ + ID2D1Bitmap* bitmap = (ID2D1Bitmap*)ref; + if (ref) bitmap->Release(); +} + +bool WICPictDecoder::getDecodedPicture(struct OsdVector::PictureInfo& pict_inf) +{ + if (!pictInfValid) return false; + pict_inf = pictInf; + pictInfValid = false; + return true; +} + + +//This is stuff for rendering the OSD + +OsdWinVector::OsdWinVector() +{ + d3ddevice10 = NULL; + d2dfactory = NULL; + currentosd_render.surf9 = NULL; + currentosd_render.surf10 = NULL; + currentosd_render.query9 = NULL; + currentosd_render.query10 = NULL; + currentosd_render.surfdxgi = NULL; + currentosd_render.sharedhandle = NULL; + currentosd_render.rendtarget2D = NULL; + currentosd_backbuffer = currentosd_backbuffer; + aspect_correction = 1.; + is_direct_write_initted = false; + dwritefac = NULL; + font = NULL; + fontface = NULL; + fontaspect_corr = 1.f; + dpix = dpiy = 72.f; + + + ttchar_end.atlas = 0; + ttchar_end.position = 0; + ttbrush = NULL; + + const wchar_t *fontname = L"Arial"; + cur_fontname = (wchar_t*)malloc(2*wcslen(fontname) + 2); + wcscpy(cur_fontname, fontname); + + WICPictDecoder * wicdecode = new WICPictDecoder(&reader, this); + reader.addDecoder(wicdecode); + +} + +OsdWinVector::~OsdWinVector() +{ + if (cur_fontname) free(cur_fontname); + + if (initted) + { + shutdown(); + if (dwritefac) dwritefac->Release(); + if (!fontnames.size()) { + vector::iterator itty = fontnames.begin(); + while (itty != fontnames.end()) { + free((void*)*itty); + + itty++; + } + } + /*if (!fontnames_keys.size()) { + vector::iterator itty = fontnames_keys.begin(); + while (itty != fontnames_keys.end()) { + free((void*)*itty); + + itty++; + } + }*/ + if (font) font->Release(); + if (fontface) fontface->Release(); + } +} + + + +int OsdWinVector::init(void* device) +{ + if (initted) return 0; + reader.init(); + + if (!createDirect3D9Objects()) return 0; + + // then create the Device + + if (D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_9_1, + D3D10_1_SDK_VERSION, &d3ddevice10) != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D10 device!"); + return 0; + } + + if (d3ddevice10->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgidevice) != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not query Dxgi device!"); + return 0; + } + + if (D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, __uuidof(ID2D1Factory),(void**) &d2dfactory) != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct2dfactory"); + return 0; + } + + + + queuemutex.Lock(); + + HRESULT hres; + DXGI_SURFACE_DESC surf_desc; + surf_desc.Width = OSD_BUFFER_WIDTH; + surf_desc.Height = OSD_BUFFER_HEIGHT; + surf_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + surf_desc.SampleDesc.Count = 1; + surf_desc.SampleDesc.Quality = 0; + + + + D2D1_RENDER_TARGET_PROPERTIES rt_prop; + rt_prop.dpiX = rt_prop.dpiY = 0; + rt_prop.pixelFormat = D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED); + rt_prop.minLevel = D2D1_FEATURE_LEVEL_9; + rt_prop.type = D2D1_RENDER_TARGET_TYPE_HARDWARE; + rt_prop.usage = D2D1_RENDER_TARGET_USAGE_NONE; + + for (int i = 0; i < 3; i++) { + SurfaceInfo surfinfo; + surfinfo.surf9 = NULL; + surfinfo.surf10 = NULL; + surfinfo.query9 = NULL; + surfinfo.query10 = NULL; + surfinfo.surfdxgi = NULL; + surfinfo.sharedhandle = NULL; + surfinfo.rendtarget2D = NULL; + + + hres = d3ddevice->CreateTexture(OSD_BUFFER_WIDTH, OSD_BUFFER_HEIGHT, 1, D3DUSAGE_RENDERTARGET, /*D3DFMT_A8R8G8B8*/D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, &surfinfo.surf9, &surfinfo.sharedhandle); + if (hres != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Texture for Direct3D9 !"); + queuemutex.Unlock(); + return 0; + } + + hres = d3ddevice->CreateQuery(D3DQUERYTYPE_EVENT, &surfinfo.query9); + if (hres != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Query for Direct3D9 !"); + queuemutex.Unlock(); + return 0; + } + + DXGI_SHARED_RESOURCE dxgi_res; + dxgi_res.Handle = surfinfo.sharedhandle; + + ID3D10Resource * tempres = NULL; + hres = d3ddevice10->OpenSharedResource(surfinfo.sharedhandle, __uuidof(ID3D10Resource), (void**)&tempres); + if (hres != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not open resourcee for Direct3D10 !"); + queuemutex.Unlock(); + return 0; + } + + hres = tempres->QueryInterface(__uuidof(ID3D10Texture2D), (void**)&surfinfo.surf10); + if (hres != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not query surface for Direct3D10 !"); + queuemutex.Unlock(); + return 0; + } + tempres->Release(); + + + hres = surfinfo.surf10->QueryInterface(__uuidof(IDXGISurface), (void**)&surfinfo.surfdxgi); + if (hres != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not query surface for DXGI !"); + queuemutex.Unlock(); + return 0; + } + + hres = d2dfactory->CreateDxgiSurfaceRenderTarget(surfinfo.surfdxgi, &rt_prop, &surfinfo.rendtarget2D); + if (hres != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create render target!"); + queuemutex.Unlock(); + return 0; + } + + surfinfo.rendtarget2D->GetDpi(&dpix, &dpiy); + + if (i == 0) { + surfinfo.rendtarget2D->CreateSolidColorBrush(D2D1::ColorF(0xFFFFFFFF, 1.f), &ttbrush); + } + + D3D10_QUERY_DESC qdesc; + qdesc.Query = D3D10_QUERY_EVENT; + qdesc.MiscFlags = 0; + + hres = d3ddevice10->CreateQuery(&qdesc, &surfinfo.query10); + if (hres != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Query for Direct2D Direct3D10 !"); + queuemutex.Unlock(); + return 0; + } + allsurfs.push_back(surfinfo); + d3dtod2d.push(surfinfo); + } + aspect_correction = ((float)OSD_BUFFER_HEIGHT) / 576.f / (((float)OSD_BUFFER_WIDTH) / 720.f); + + + queuemutex.Unlock(); + + initPaths(); + + loadFont(false); + + initted = 1; // must set this here or create surface won't work + + startRenderLoop(); + + return 1; +} + + +int OsdWinVector::shutdown() +{ + if (!initted) return 0; + initted = 0; + stopRenderLoop(); + reader.shutdown(); + destroyPaths(); + + + queuemutex.Lock(); + if (currentosd_render.surf9) { + currentosd_render.surf9 = NULL; + } + + if (currentosd_backbuffer.surf9) { + currentosd_backbuffer.surf9 = NULL; + } + + + + for (int i = 0; i < tt_atlas.size(); i++) + { + tt_atlas[i]->Release(); + } + tt_atlas.clear(); + tt_font_chars.clear(); + ttbrush->Release(); + ttbrush = NULL; + + while (allsurfs.size()) { + SurfaceInfo surfinfo = allsurfs.front(); + allsurfs.pop_front(); + if (surfinfo.rendtarget2D) { + ID2D1RenderTarget *temp = surfinfo.rendtarget2D; + surfinfo.rendtarget2D = NULL; + temp->Release(); + } + + if (surfinfo.surf9) { + LPDIRECT3DTEXTURE9 temp = surfinfo.surf9; + surfinfo.surf9 = NULL; + temp->Release(); + } + + if (surfinfo.query9) { + IDirect3DQuery9* temp = surfinfo.query9; + surfinfo.query9 = NULL; + temp->Release(); + } + + if (surfinfo.surf10) { + ID3D10Texture2D * temp = surfinfo.surf10; + surfinfo.surf10 = NULL; + temp->Release(); + } + + if (surfinfo.surfdxgi) { + IDXGISurface *temp = surfinfo.surfdxgi; + surfinfo.surfdxgi = NULL; + temp->Release(); + } + if (surfinfo.query10) { + ID3D10Query* temp = surfinfo.query10; + surfinfo.query10 = NULL; + temp->Release(); + } + } + + while (d3dtod2d.size()) d3dtod2d.pop(); + while (d2dtod3d.size()) d2dtod3d.pop(); + + queuemutex.Unlock(); + + + + if (d2dfactory) { + ID2D1Factory *temp = d2dfactory; + d2dfactory = NULL; + temp->Release(); + } + + if (d3ddevice10) { + ID3D10Device *temp = d3ddevice10; + d3ddevice10 = NULL; + temp->Release(); + } + + shutdownDirect3D9Objects(); + + + return 1; +} + + +void OsdWinVector::initPaths() +{ + ID2D1PathGeometry *current = NULL; + ID2D1GeometrySink *currentsink = NULL; + + d2dfactory->CreatePathGeometry(¤t); + current->Open(¤tsink); + currentsink->BeginFigure(D2D1::Point2F(0, 0), D2D1_FIGURE_BEGIN_HOLLOW); + + currentsink->AddLine(D2D1::Point2F(1.f, 0)); + + currentsink->EndFigure(D2D1_FIGURE_END_OPEN); + // HorzLine + std_paths[PIHorzLine] = current; + + current = NULL; + currentsink->Close(); + currentsink->Release(); + currentsink=NULL; + + d2dfactory->CreatePathGeometry(¤t); + current->Open(¤tsink); + currentsink->BeginFigure(D2D1::Point2F(0, 0), D2D1_FIGURE_BEGIN_HOLLOW); + + currentsink->AddLine(D2D1::Point2F(0, 1.f)); + currentsink->EndFigure(D2D1_FIGURE_END_OPEN); + + // VertLine + std_paths[PIVertLine] = current; + + current = NULL; + currentsink->Close(); + currentsink->Release(); + currentsink = NULL; + + d2dfactory->CreatePathGeometry(¤t); + current->Open(¤tsink); + currentsink->BeginFigure(D2D1::Point2F(0, 0), D2D1_FIGURE_BEGIN_FILLED); + + currentsink->AddLine(D2D1::Point2F(1, 0)); + currentsink->AddLine(D2D1::Point2F(1, 1)); + currentsink->AddLine(D2D1::Point2F(0, 1)); + currentsink->EndFigure(D2D1_FIGURE_END_CLOSED); + // Rectabgle + std_paths[PIRectangle] = current; + + current = NULL; + currentsink->Close(); + currentsink->Release(); + currentsink = NULL; + + d2dfactory->CreatePathGeometry(¤t); + current->Open(¤tsink); + currentsink->BeginFigure(D2D1::Point2F(0, 0.f), D2D1_FIGURE_BEGIN_FILLED); + + currentsink->AddArc(D2D1::ArcSegment( + D2D1::Point2F(0, 0.f), + D2D1::SizeF(1.f, 1.f), + 0.0f, + D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, + D2D1_ARC_SIZE_LARGE)); + + currentsink->EndFigure(D2D1_FIGURE_END_CLOSED); + + + // Point + std_paths[PIPoint] = current; + + current = NULL; + currentsink->Close(); + currentsink->Release(); + currentsink = NULL; + +} + +void OsdWinVector::destroyPaths() +{ + std_paths[PIHorzLine]->Release(); + std_paths[PIVertLine]->Release(); + std_paths[PIRectangle]->Release(); + std_paths[PIPoint]->Release(); + +} + + + +int OsdWinVector::loadFont(bool newfont) +{ + HRESULT hres; + if (!is_direct_write_initted) + { + + hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), + (IUnknown**)(&dwritefac)); + if (hres != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create DirectWrite Factory!"); + return 0; + } + + is_direct_write_initted = true; + } + + if (fontnames.size()) + { + fontnames.clear(); + } + + IDWriteFontCollection * fontcol = NULL; + if (dwritefac->GetSystemFontCollection(&fontcol) != S_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not get System Font Collection!"); + return 0; + } + UINT num_font = fontcol->GetFontFamilyCount(); + for (UINT i = 0; i < num_font; i++) { + IDWriteFontFamily * family=NULL; + if (fontcol->GetFontFamily(i, &family)!=S_OK) continue; + IDWriteLocalizedStrings* fam_name=NULL; + if (family->GetFamilyNames(&fam_name) != S_OK) { + family->Release(); + continue; + } + UINT32 id = 0; + BOOL exist = false; + if (fam_name->FindLocaleName(L"en-us", &id, &exist) == S_OK) { + if (!exist) id = 0; + UINT32 strlen=0; + fam_name->GetStringLength(id, &strlen); + wchar_t * stringbuf = new wchar_t[strlen + 1]; + + fam_name->GetString(id, stringbuf, strlen+1); + + int strlenutf8 = WideCharToMultiByte(CP_UTF8, 0, stringbuf, -1, + NULL, 0, 0, NULL); + char *stringbufutf8 = new char[strlenutf8 + 1]; + WideCharToMultiByte(CP_UTF8, 0, stringbuf, -1, + stringbufutf8, strlenutf8+1, 0, NULL); + + + if (wcscmp(cur_fontname, stringbuf) == 0) { + IDWriteFont* new_font; + if (family->GetFirstMatchingFont(DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &new_font) == S_OK) { + IDWriteFontFace *newfontface = NULL; + new_font->CreateFontFace(&newfontface); + + IDWriteFont* temp_font = font; + IDWriteFontFace* temp_fontface = fontface; + font = new_font; + fontface = newfontface; + + if (temp_font) temp_font->Release(); + if (temp_fontface) temp_fontface->Release(); + } + } + + delete[] stringbuf; + fontnames.push_back(stringbufutf8); + } + fam_name->Release(); + family->Release(); + } + fontcol->Release(); + + if (font) { + DWRITE_FONT_METRICS metrics; + font->GetMetrics(&metrics); + fontheight = ((float)( metrics.ascent + metrics.descent + metrics.lineGap))*13.f + / ((float)metrics.designUnitsPerEm) / 576.f * ((float)OSD_BUFFER_HEIGHT)/72.f*dpiy; + fontzero = ((float)(metrics.ascent))*13.f + / ((float)metrics.designUnitsPerEm) / 576.f * ((float)OSD_BUFFER_HEIGHT) / 72.f*dpiy; + + fontaspect_corr = ((float)OSD_BUFFER_HEIGHT) / ((float)OSD_BUFFER_WIDTH) * 720.f / 576.f; + + + for (UINT32 i = 0; i<256; i++) { + DWRITE_GLYPH_METRICS glyph_metrics; + UINT16 glyph_index; + fontface->GetGlyphIndices(&i, 1, &glyph_index); + HRESULT hres=fontface->GetDesignGlyphMetrics(&glyph_index, 1, &glyph_metrics, FALSE); + + if (hres == S_OK) { + byte_char_width[i] = ((float)glyph_metrics.advanceWidth)*13.f + / ((float)metrics.designUnitsPerEm) *fontaspect_corr / 72.f*dpix; + } + else { + byte_char_width[i] = 0.f; + } + } + + + + + } + + + return 1; +} + + +OsdWinVector::TTIndex OsdWinVector::loadTTchar(cTeletextChar c) +{ + /* map tt_font_chars; + vector tt_atlas; + TTIndex ttchar_end;*/ + + + unsigned int glyph_index = c.getGlyphIndex(); + map::iterator glypos = tt_font_chars.find(glyph_index); + if (glypos != tt_font_chars.end()) + { + return (*glypos).second; + } + TTIndex our_index = ttchar_end; + + unsigned int buffer[10]; + unsigned int * charmap = GetFontChar(c, buffer); + if (!charmap) { //invalid char + our_index.atlas = our_index.position = 0; + return our_index; + } + + + + // Now we have to determine, if the atlas is already created + if (our_index.atlas == tt_atlas.size()) { + //Now we have to create the atlas + ID2D1Bitmap * atlas = NULL; + D2D1_SIZE_U size; + size.height = 120; + size.width = 120; + D2D1_BITMAP_PROPERTIES bitmap_prop; + bitmap_prop.dpiX = dpix; + bitmap_prop.dpiY = dpiy; + bitmap_prop.pixelFormat.format = DXGI_FORMAT_A8_UNORM; + bitmap_prop.pixelFormat.alphaMode = D2D1_ALPHA_MODE_STRAIGHT; + + HRESULT hres = currentosd_backbuffer.rendtarget2D->CreateBitmap(size, bitmap_prop, &atlas); + + if (hres != S_OK) { + Log::getInstance()->log("OsdWinVector", Log::DEBUG, "CreateBitmap for atlas failed %d", hres); + atlas = NULL; + our_index.atlas = our_index.position = 0; + return our_index; + } + tt_atlas.push_back(atlas); + + } + + unsigned char buffer_final[120]; + for (int i = 0; i<10; i++) { + for (int j = 0; j < 12; j++) { + buffer_final[i*12+j] = ((charmap[i] >> (16-j)) & 1)? 0xFF: 0x00; + } + } + + D2D1_RECT_U dst_rect = { (our_index.position % 10)*12, + (our_index.position /10) *10, + (our_index.position % 10+1)*12, + (our_index.position / 10+1)*10, + }; + + HRESULT hres=tt_atlas[our_index.atlas]->CopyFromMemory(&dst_rect, buffer_final, 12); + + if (hres != S_OK) { + Log::getInstance()->log("OsdWinVector", Log::DEBUG, "CopyFromMemory for atlas failed %d", hres); + our_index.atlas = our_index.position = 0; + return our_index; + } + + tt_font_chars[glyph_index] = our_index; + ttchar_end.position++; + if (ttchar_end.position == 120) { + ttchar_end.position = 0; + ttchar_end.atlas++; + } + return our_index; + +} + +int OsdWinVector::getFontNames(const char *** names, const char *** names_keys) +{ + *names = (const char**)&(fontnames[0]); + *names_keys = (const char**)&(fontnames/*_keys*/[0]); + return fontnames.size(); +} + +void OsdWinVector::setFont(const char * fontname) { + + wchar_t * wfontname= new wchar_t[strlen(fontname)+1]; + + MultiByteToWideChar(CP_UTF8, 0, fontname, -1, + wfontname, strlen(fontname) + 1); + + if (wcscmp(wfontname, cur_fontname)) { + // new font! + if (cur_fontname) free(cur_fontname); + cur_fontname = (wchar_t*)malloc(2*wcslen(wfontname) + 2); + wcscpy(cur_fontname, wfontname); + loadFont(true); + + } + + + delete[] wfontname; + +} + + + +void OsdWinVector::drawSetTrans(SurfaceCommands & sc) +{ + D2D1::Matrix3x2F trans = D2D1::Matrix3x2F::Identity(); + + trans = trans*D2D1::Matrix3x2F::Scale(((float)OSD_BUFFER_WIDTH) / 720.f, ((float)OSD_BUFFER_HEIGHT) / 576.f); + trans=D2D1::Matrix3x2F::Translation(0.f + sc.x, sc.y)*trans; + + currentosd_backbuffer.rendtarget2D->SetTransform(trans); + + clip_shift_x = sc.x; + clip_shift_y = sc.y; +} + +void OsdWinVector::executeDrawCommand(SVGCommand & command) +{ + D2D1::Matrix3x2F save_matrix; + D2D1::Matrix3x2F save_matrix2; + + + switch (command.instr) { + case DrawPath: { + currentosd_backbuffer.rendtarget2D->GetTransform(&save_matrix); + + D2D1::Matrix3x2F matrix; + matrix = + D2D1::Matrix3x2F::Scale(command.w, command.h)*D2D1::Matrix3x2F::Translation(command.x, command.y)*save_matrix; + currentosd_backbuffer.rendtarget2D->SetTransform(matrix); + currentosd_backbuffer.rendtarget2D->FillGeometry(std_paths[command.target.path_index], + (ID2D1Brush*)command.reference); + + currentosd_backbuffer.rendtarget2D->SetTransform(save_matrix); + + } break; + case DrawImage: { + currentosd_backbuffer.rendtarget2D->GetTransform(&save_matrix); + ID2D1Bitmap * bitmap = (ID2D1Bitmap*)command.target.image; + if (!bitmap) return; + D2D1_SIZE_F size=bitmap->GetSize(); + + D2D1::Matrix3x2F matrix; + + + if (command.reference) { //special behaviour for bw images they act as a mask on the current paint + matrix = + D2D1::Matrix3x2F::Scale(1.f*aspect_correction, 1.f) + *D2D1::Matrix3x2F::Translation(command.x, command.y)*save_matrix; + } + else { + + float scalex = command.w / size.width; + float scaley = command.h / size.height; + float tx = command.x; + float ty = command.y; + if (command.corner == TopLeftLimited) { + if (scalex != 0.f && scaley != 0.f) { + float imageaspect = size.width / size.height; + float boxaspect = command.w / command.h / aspect_correction; + if (imageaspect > boxaspect) { + scaley = 0.f; + ty += (command.h - size.height * scalex / aspect_correction)*0.5f; + } + else { + scalex = 0.f; + tx += (command.w - size.width * scaley*aspect_correction)*0.5f; + } + + } + + } + if (scalex == 0.f && scaley == 0.f) { + scalex = aspect_correction; + scaley = 1.f; + } + else if (scalex == 0.f) { + scalex = scaley*aspect_correction; + } + else if (scaley == 0.f) { + scaley = scalex / aspect_correction; + } + + + if (command.corner == BottomRight || command.corner == BottomLeft || command.corner == BottomMiddle) + { + ty -= size.height * scaley; + } + + if (command.corner == BottomRight || command.corner == TopRight) + { + tx -= size.width * scalex; + } + + if (command.corner == BottomMiddle || command.corner == TopMiddle) + { + tx -= size.width * scalex *0.5f; + } + + matrix = + D2D1::Matrix3x2F::Scale(scalex, scaley)*D2D1::Matrix3x2F::Translation(tx, ty)*save_matrix; + + + } + + currentosd_backbuffer.rendtarget2D->SetTransform(matrix); + + if (command.reference) { + currentosd_backbuffer.rendtarget2D->FillOpacityMask(bitmap, (ID2D1Brush*)command.reference, D2D1_OPACITY_MASK_CONTENT_GRAPHICS); + + } + else + { + currentosd_backbuffer.rendtarget2D->DrawBitmap(bitmap); + } + + + + + currentosd_backbuffer.rendtarget2D->SetTransform(save_matrix); + + + } break; + case DrawGlyph: { + currentosd_backbuffer.rendtarget2D->GetTransform(&save_matrix); + + D2D1::Matrix3x2F matrix; + matrix = D2D1::Matrix3x2F::Scale(fontaspect_corr, 1.f)* + D2D1::Matrix3x2F::Translation(command.x, command.y + fontzero)*save_matrix; + currentosd_backbuffer.rendtarget2D->SetTransform(matrix); + UINT32 tchar = command.target.textchar; + UINT16 glyphindex; + DWRITE_GLYPH_RUN glyph_run; + glyph_run.fontEmSize = 13.f / (74.f / 96.f); + glyph_run.fontFace=fontface; + glyph_run.glyphCount=1; + glyph_run.glyphIndices = &glyphindex; + + fontface->GetGlyphIndices(&tchar, 1, &glyphindex); + + FLOAT zero = 0.f; + DWRITE_GLYPH_OFFSET zero2 = { 0.f, 0.f }; + glyph_run.glyphAdvances=&zero; + glyph_run.glyphOffsets=&zero2; + glyph_run.isSideways=false; + glyph_run.bidiLevel=0; + D2D1_POINT_2F pos = { 0.f, 0.f }; + + currentosd_backbuffer.rendtarget2D->DrawGlyphRun(pos, &glyph_run, + (ID2D1Brush*)command.reference); + currentosd_backbuffer.rendtarget2D->SetTransform(save_matrix); + + } break; + case DrawTTchar:{ + cTeletextChar tchar; + tchar.setInternal(command.target.ttchar); + currentosd_backbuffer.rendtarget2D->GetTransform(&save_matrix); + + enumTeletextColor ttforegcolour = tchar.GetFGColor(); + enumTeletextColor ttbackgcolour = tchar.GetBGColor(); + if (tchar.GetBoxedOut()) { + ttforegcolour = ttcTransparent; + ttbackgcolour = ttcTransparent; + } + D2D1::Matrix3x2F matrix; + matrix = D2D1::Matrix3x2F::Scale(1.5f+0.05f, 2.f) + *D2D1::Matrix3x2F::Translation(command.x + command.w*11.85f*1.4f, command.y + command.h*19.75f) + *save_matrix; + + currentosd_backbuffer.rendtarget2D->SetTransform(matrix); + + + Colour color = Surface::enumTeletextColorToCoulour(ttbackgcolour); + + ttbrush->SetColor(D2D1::ColorF(color.rgba(), ((float)color.alpha) / 255.f)); + + cTeletextChar filled; + filled.setInternal(0x187f); + TTIndex glyph_index = loadTTchar(filled); + + { + D2D1_RECT_F src_rect = { (glyph_index.position % 10)*12.f, + (glyph_index.position / 10) *10.f, + (glyph_index.position % 10 + 1)*12.f, + (glyph_index.position / 10 + 1)*10.f, + }; + + + currentosd_backbuffer.rendtarget2D->FillOpacityMask(tt_atlas[glyph_index.atlas], ttbrush, D2D1_OPACITY_MASK_CONTENT_GRAPHICS, + NULL, &src_rect); + } + + color = Surface::enumTeletextColorToCoulour(ttforegcolour); + ttbrush->SetColor(D2D1::ColorF(color.rgba(), ((float)color.alpha) / 255.f)); + + + glyph_index = loadTTchar(tchar); + + { + D2D1_RECT_F src_rect = { (glyph_index.position % 10)*12.f, + (glyph_index.position / 10) *10.f, + (glyph_index.position % 10 + 1)*12.f, + (glyph_index.position / 10 + 1)*10.f, + }; + + + currentosd_backbuffer.rendtarget2D->FillOpacityMask(tt_atlas[glyph_index.atlas], ttbrush, D2D1_OPACITY_MASK_CONTENT_GRAPHICS, + NULL, &src_rect); + } + + + currentosd_backbuffer.rendtarget2D->SetTransform(save_matrix); + + + }break; + case DrawClipping: { + currentosd_backbuffer.rendtarget2D->GetTransform(&save_matrix); + currentosd_backbuffer.rendtarget2D->SetTransform(D2D1::IdentityMatrix()); + + D2D1_RECT_F coords = { ((command.x + clip_shift_x)*((float)OSD_BUFFER_WIDTH) / 720.f), + (( command.y + clip_shift_y )*((float)OSD_BUFFER_HEIGHT) / 576.f), + ((command.x + clip_shift_x+command.w - 1.f)*((float)OSD_BUFFER_WIDTH) / 720.f), + (command.y + clip_shift_y+(command.h - 1.f)*((float)OSD_BUFFER_HEIGHT) / 576.f) }; + if (command.w == 0.f && command.h == 0.f) { + while (num_clips > 0) { + num_clips--; + currentosd_backbuffer.rendtarget2D->PopAxisAlignedClip(); + } + } else { + num_clips++; + currentosd_backbuffer.rendtarget2D->PushAxisAlignedClip(coords, D2D1_ANTIALIAS_MODE_ALIASED); + + } + currentosd_backbuffer.rendtarget2D->SetTransform(save_matrix); + } break; + } +} + +float OsdWinVector::getFontHeight() +{ + return fontheight; +} +float OsdWinVector::getCharWidth(wchar_t c) +{ + if (c<256) return byte_char_width[c]; + if (!font) return 13.f; + DWRITE_FONT_METRICS metrics; + font->GetMetrics(&metrics); + + + DWRITE_GLYPH_METRICS glyph_metrics; + UINT16 glyph_index; + UINT32 tchar = c; + fontface->GetGlyphIndices(&tchar, 1, &glyph_index); + fontface->GetDesignGlyphMetrics(&glyph_index, 1, &glyph_metrics, FALSE); + + return ((float)glyph_metrics.advanceWidth)*13.f + / ((float)metrics.designUnitsPerEm) *fontaspect_corr / 72.f*dpiy; + + +} + +void OsdWinVector::getScreenSize(int &width, int &height) +{ + width = OSD_BUFFER_WIDTH; + height = OSD_BUFFER_HEIGHT; +} + +void OsdWinVector::getRealScreenSize(int &width, int &height) +{ + width = BACKBUFFER_WIDTH; + height = BACKBUFFER_HEIGHT; +} + +bool OsdWinVector::screenShot(void *buffer, int width, int height, bool osd /*include osd*/) +{ + //screen->screenShot(fileName); + return false; +} + +LPDIRECT3DTEXTURE9 OsdWinVector::getNextOsdTexture() +{ + queuemutex.Lock(); + if (d2dtod3d.size()) + { + SurfaceInfo surfinfo = d2dtod3d.front(); + //Now we have to check, if the resource is ready, or busy somewhere else + // if (surfinfo.query10->GetData(NULL, 0, D3D10_ASYNC_GETDATA_DONOTFLUSH) == S_OK) { + //the surface is ready + if (currentosd_render.surf9) { + currentosd_render.query9->Issue(D3DISSUE_END); //mark the end of the 9 api access + d3dtod2d.push(currentosd_render); + } + currentosd_render = surfinfo; + d2dtod3d.pop(); + //} + } + queuemutex.Unlock(); + + return currentosd_render.surf9; +} + +void OsdWinVector::updateOsd() +{ + + queuemutex.Lock(); + if (d3dtod2d.size()) + { + currentosd_backbuffer = d3dtod2d.front(); + //Now we have to check, if the resource is ready, or busy somewhere else + if (currentosd_backbuffer.query9->GetData(NULL, 0, 0) == S_OK) { + + + //queuemutex.Unlock(); + currentosd_backbuffer.query10->Begin(); + + currentosd_backbuffer.rendtarget2D->BeginDraw(); + currentosd_backbuffer.rendtarget2D->Clear(D2D1::ColorF(0.f, 0.f, 0.f, 0.0f)); + currentosd_backbuffer.rendtarget2D->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); + + num_clips = 0; + // We can draw here + drawSurfaces(); + while (num_clips>0) { + currentosd_backbuffer.rendtarget2D->PopAxisAlignedClip(); + num_clips--; + } + + currentosd_backbuffer.rendtarget2D->EndDraw(); + currentosd_backbuffer.rendtarget2D->Flush(); + d3ddevice10->Flush(); + currentosd_backbuffer.query10->End(); + + //queuemutex.Lock(); + d3dtod2d.pop(); + d2dtod3d.push(currentosd_backbuffer); + + } + + } + + queuemutex.Unlock(); + +} + +ID2D1RenderTarget * OsdWinVector::LockOsdDrawing() +{ + queuemutex.Lock(); + if (d3dtod2d.size()) + { + currentosd_backbuffer=d3dtod2d.front(); + return currentosd_backbuffer.rendtarget2D; + } + queuemutex.Unlock(); + + int loop = 0; + while (loop < 100) { + queuemutex.Lock(); + if (d3dtod2d.size()) + { + currentosd_backbuffer = d3dtod2d.front(); + return currentosd_backbuffer.rendtarget2D; + } + queuemutex.Unlock(); + + MILLISLEEP(100); + loop++; + } + + currentosd_backbuffer.surf10 = NULL; + currentosd_backbuffer.surf9 = NULL; + return NULL; + +} +void OsdWinVector::UnlockOsdDrawing() +{ + queuemutex.Unlock(); +} + +void OsdWinVector::lostDestroyObjects() +{ + +} + +void OsdWinVector::lostRecreateObjects() +{ + +} + + +void OsdWinVector::getTextureCoordinates(FLOAT* x, FLOAT* y) +{ + *x = 1.f; + *y = 1.f; +} + + + + +void OsdWinVector::destroyImageRef(ImageIndex index) +{ + ID2D1Bitmap* bitmap = (ID2D1Bitmap*)index; + if (bitmap) bitmap->Release(); +} + + +bool OsdWinVector::getStaticImageData(unsigned int static_id, UCHAR **userdata, ULONG *length) +{ + if (sa_MAX>static_id) { + HRSRC hrc = FindResource(GetModuleHandle(NULL), ext_pict_name[static_id], RT_RCDATA); + *length = SizeofResource(GetModuleHandle(NULL), hrc); + *userdata = (UCHAR*) LockResource(LoadResource(GetModuleHandle(NULL), hrc)); + + return true; + } + + *userdata = NULL; + *length = 0; + return false; + +} + +void OsdWinVector::createPicture(struct PictureInfo& pict_inf) +{ + + Log::getInstance()->log("OsdWinVector", Log::DEBUG, "TVMedia Create Picture %d", pict_inf.type); + if (pict_inf.type == PictureInfo::D2DBitmap) { + bool static_image = true; + if (pict_inf.lindex & 0xffffffff) static_image = false; + + Message* m = new Message(); + // We have a pictures! send a message to ourself, to switch to gui thread + m->from = this; + m->to = Command::getInstance(); + m->parameter.handle = pict_inf.reference; + if (!static_image) { + m->message = Message::NEW_PICTURE; + m->tag = pict_inf.lindex; + } + else { + m->message = Message::NEW_PICTURE_STATIC; + m->tag = pict_inf.lindex >> 32LL; + } + Command::getInstance()->postMessageFromOuterSpace(m); // inform command about new picture + + } else { + pict_inf.decoder->freeReference(pict_inf.reference); + } + +} + + +ImageIndex OsdWinVector::createMonoBitmap(void *base, int width, int height) +{ + // First we have to convert it to 8 bit alpha, we could use WIC but actually writing this code is not hard to port from base class + + LockOsdDrawing(); + + int x, y; + unsigned char *basechar = (unsigned char*) base; + unsigned int bytesIn, bitsIn; + int widthBytes = width / 8; + + unsigned char *alphamem = (unsigned char*)malloc(width*height); + unsigned char *alphamemrun = alphamem; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + bytesIn = (y * widthBytes) + (int)(x / 8); + bitsIn = x % 8; + (*alphamemrun) = ((basechar[bytesIn] >> (7 - bitsIn)) & 0x01) ? 0xFF : 0x00; + alphamemrun++; + } + } + D2D1_SIZE_U size; + size.height = height; + size.width = width; + D2D1_BITMAP_PROPERTIES bitmap_prop; + bitmap_prop.dpiX = dpix; + bitmap_prop.dpiY = dpiy; + bitmap_prop.pixelFormat.format = DXGI_FORMAT_A8_UNORM; + bitmap_prop.pixelFormat.alphaMode = D2D1_ALPHA_MODE_STRAIGHT; + + ID2D1Bitmap *bitmap = NULL; + + HRESULT hres = currentosd_backbuffer.rendtarget2D->CreateBitmap(size, alphamem, width, bitmap_prop, &bitmap); + + if (hres != S_OK) { + Log::getInstance()->log("OsdWinVector", Log::DEBUG, "CreateBitmap failed %d", hres); + bitmap = NULL; + } + + free(alphamem); + + UnlockOsdDrawing(); + + return (void*)bitmap; + +} + +ImageIndex OsdWinVector::createImagePalette(int width, int height, const unsigned char *image_data, const unsigned int*palette_data) +{ + // First we have to convert it to 32 bit RGBA, we could use WIC but actually writing this code is not hard to port from base class + + LockOsdDrawing(); + + int x, y; + UINT32 *mem = (UINT32*)malloc(width*height*sizeof(UINT32)); + UINT32 *memrun = mem; + const unsigned char* image_run = image_data; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + + (*memrun) = palette_data[(*image_run)]; + memrun++; + image_run++; + } + } + D2D1_SIZE_U size; + size.height = height; + size.width = width; + D2D1_BITMAP_PROPERTIES bitmap_prop; + bitmap_prop.dpiX = dpix; + bitmap_prop.dpiY = dpiy; + bitmap_prop.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; + bitmap_prop.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + + ID2D1Bitmap *bitmap = NULL; + + HRESULT hres = currentosd_backbuffer.rendtarget2D->CreateBitmap(size, mem, width*sizeof(UINT32), bitmap_prop, &bitmap); + + if (hres != S_OK) { + Log::getInstance()->log("OsdWinVector", Log::DEBUG, "CreateBitmap failed %d", hres); + bitmap = NULL; + } + + free(mem); + + UnlockOsdDrawing(); + + return (void*)bitmap; + +} + +void OsdWinVector::destroyStyleRef(VectorHandle index) +{ + if (!initted) return; + ID2D1Brush *brush = (ID2D1Brush*)(index); + brush->Release(); + +} + +VectorHandle OsdWinVector::createStyleRef(const DrawStyle &c) +{ + LockOsdDrawing(); + + switch (c.ft) { + case DrawStyle::Color: { + ID2D1SolidColorBrush * newbrush=NULL; + currentosd_backbuffer.rendtarget2D->CreateSolidColorBrush( + D2D1::ColorF(c.rgba(),((float)c.alpha)/255.f), + &newbrush); + UnlockOsdDrawing(); + return newbrush; + } break; + case DrawStyle::GradientLinear: + case DrawStyle::GradientRadial: { + D2D1_GRADIENT_STOP grad_stop[5]; + grad_stop[0].color = D2D1::ColorF(c.rgba()); + grad_stop[0].position = 0.0f; + + for (int i = 0; i < (c.num_colors - 1); i++) { + grad_stop[i + 1].color = D2D1::ColorF(c.grad_col[i].rgba(), ((float)c.grad_col[i].alpha) / 255.f); + grad_stop[i + 1].position = c.grad_pos[i]; + } + grad_stop[c.num_colors].color = D2D1::ColorF(c.grad_col[c.num_colors - 1].rgba(), ((float)c.grad_col[c.num_colors - 1].alpha) / 255.f); + grad_stop[c.num_colors].position = 1.f; + + ID2D1GradientStopCollection *gradstopobj; + + currentosd_backbuffer.rendtarget2D->CreateGradientStopCollection( + grad_stop, + c.num_colors+1, + D2D1_GAMMA_2_2, + D2D1_EXTEND_MODE_CLAMP, + &gradstopobj + ); + + if (c.ft == DrawStyle::GradientLinear) { + ID2D1LinearGradientBrush * newbrush=NULL; + currentosd_backbuffer.rendtarget2D->CreateLinearGradientBrush( + D2D1::LinearGradientBrushProperties( + D2D1::Point2F(c.x1, c.y1), + D2D1::Point2F(c.x2, c.y2)), + gradstopobj, + &newbrush + ); + gradstopobj->Release(); + UnlockOsdDrawing(); + return newbrush; + } + if (c.ft == DrawStyle::GradientRadial) { + ID2D1RadialGradientBrush * newbrush = NULL; + currentosd_backbuffer.rendtarget2D->CreateRadialGradientBrush( + D2D1::RadialGradientBrushProperties( + D2D1::Point2F(c.x1, c.y1), + D2D1::Point2F(c.x2, c.y2),c.r,c.r), + gradstopobj, + &newbrush + ); + gradstopobj->Release(); + UnlockOsdDrawing(); + return newbrush; + } + + } break; + }; + + UnlockOsdDrawing(); + return NULL; + +} + + diff --git a/osdwinvector.h b/osdwinvector.h new file mode 100644 index 0000000..a4b49fb --- /dev/null +++ b/osdwinvector.h @@ -0,0 +1,150 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef OSDWINVECTOR_H +#define OSDWINVECTOR_H + +#include + +#include "osdvector.h" +#include "defines.h" +#include "log.h" +#include "windowsosd.h" +#include "mutex.h" +#include +#include +#include +#include +#include + + + + +class OsdWinVector : public OsdVector, public WindowsOsd +{ + friend class WICPictDecoder; + public: + OsdWinVector(); + ~OsdWinVector(); + + int init(void* device); + int shutdown(); + + int isInitialized() { return initted; } + + void getScreenSize(int &width, int &height); + void getRealScreenSize(int &width, int &height); + + float getFontHeight(); + float getCharWidth(wchar_t c); + + bool screenShot(void *buffer, int width, int height, bool osd /*include osd*/); + + int getFontNames(const char *** names, const char *** names_keys); + + void setFont(const char * fontname); + + float getPixelAspect() { return aspect_correction; }; + +protected: + LPDIRECT3DTEXTURE9 getNextOsdTexture(); + void lostDestroyObjects(); + void lostRecreateObjects(); + void updateOsd(); + void getTextureCoordinates(FLOAT*, FLOAT*); + + /*osd vector implementation*/ + void destroyImageRef(ImageIndex index); + ImageIndex createMonoBitmap(void *base, int width, int height); + ImageIndex createImagePalette(int width, int height, const unsigned char *image_data, const unsigned int*palette_data); + void createPicture(struct PictureInfo& pict_inf); + void destroyStyleRef(VectorHandle index); + VectorHandle createStyleRef(const DrawStyle &c); + bool getStaticImageData(unsigned int static_id, UCHAR **userdata, ULONG *length); + + + int loadFont(bool fontchange); + + map font_exp_x; + vector fontnames; + //vector fontnames_keys; + wchar_t * cur_fontname; + bool is_direct_write_initted; + IDWriteFactory* dwritefac; + IDWriteFont* font; + IDWriteFontFace* fontface; + float fontheight; + float fontzero; + float fontaspect_corr; + + struct TTIndex { + unsigned char atlas; + unsigned char position; + }; + + TTIndex loadTTchar(cTeletextChar c); + + map tt_font_chars; + vector tt_atlas; + TTIndex ttchar_end; + ID2D1SolidColorBrush *ttbrush; + + + void executeDrawCommand(SVGCommand & command); + void drawSetTrans(SurfaceCommands & sc); + + typedef struct { + LPDIRECT3DTEXTURE9 surf9; + IDirect3DQuery9 * query9; + ID3D10Texture2D *surf10; + IDXGISurface * surfdxgi; + ID2D1RenderTarget *rendtarget2D; + ID3D10Query * query10; + HANDLE sharedhandle; + } SurfaceInfo; + + std::queue d2dtod3d; + std::queue d3dtod2d; + std::list allsurfs; + SurfaceInfo currentosd_render; + SurfaceInfo currentosd_backbuffer; + ID2D1RenderTarget * LockOsdDrawing(); + void UnlockOsdDrawing(); + + Mutex queuemutex; + + void initPaths(); + void destroyPaths(); + ID2D1PathGeometry *std_paths[PIPoint + 1]; + + ID3D10Device1 * d3ddevice10; + ID2D1Factory *d2dfactory; + IDXGIDevice * dxgidevice; + float aspect_correction; + float dpix, dpiy; + + int clip_shift_x; + int clip_shift_y; + + int num_clips; + +}; + +#endif diff --git a/player.cc b/player.cc index 671a4ef..e965a2c 100644 --- a/player.cc +++ b/player.cc @@ -966,7 +966,7 @@ void Player::doConnectionLost() m->to = messageReceiver; m->from = this; m->message = Message::PLAYER_EVENT; - m->parameter = Player::CONNECTION_LOST; + m->parameter.num = Player::CONNECTION_LOST; messageQueue->postMessage(m); } @@ -995,7 +995,7 @@ void Player::call(void* caller) m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = Player::ASPECT43; + m->parameter.num = Player::ASPECT43; messageQueue->postMessageFromOuterSpace(m); } else if (dxCurrentAspect == Demuxer::ASPECT_16_9) @@ -1007,7 +1007,7 @@ void Player::call(void* caller) m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = Player::ASPECT169; + m->parameter.num = Player::ASPECT169; messageQueue->postMessageFromOuterSpace(m); } else @@ -1053,7 +1053,7 @@ void Player::threadMethod() m->to = messageReceiver; m->from = this; m->message = Message::PLAYER_EVENT; - m->parameter = STOP_PLAYBACK; + m->parameter.num = STOP_PLAYBACK; logger->log("Player", Log::DEBUG, "Posting message to %p...", messageQueue); messageQueue->postMessage(m); logger->log("Player", Log::DEBUG, "Message posted..."); @@ -1189,7 +1189,7 @@ void Player::threadFeedPlay() m->to = messageReceiver; m->from = this; m->message = Message::PLAYER_EVENT; - m->parameter = Player::STOP_PLAYBACK; + m->parameter.num = Player::STOP_PLAYBACK; logger->log("Player", Log::DEBUG, "Posting message to %p...", messageQueue); messageQueue->postMessage(m); } diff --git a/playerliveradio.cc b/playerliveradio.cc index 2782302..233c55c 100644 --- a/playerliveradio.cc +++ b/playerliveradio.cc @@ -175,7 +175,7 @@ void PlayerLiveRadio::streamReceive(ULONG flag, void* data, ULONG len) m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveRadio::STREAM_END; + m->parameter.num = PlayerLiveRadio::STREAM_END; messageQueue->postMessageFromOuterSpace(m); } @@ -348,7 +348,7 @@ bool PlayerLiveRadio::checkError() m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveRadio::CONNECTION_LOST; + m->parameter.num = PlayerLiveRadio::CONNECTION_LOST; messageQueue->postMessageFromOuterSpace(m); return true; @@ -451,7 +451,7 @@ void PlayerLiveRadio::threadMethod() m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveRadio::STREAM_END; + m->parameter.num = PlayerLiveRadio::STREAM_END; messageQueue->postMessageFromOuterSpace(m); } } @@ -483,7 +483,7 @@ void PlayerLiveRadio::threadMethod() m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveRadio::PREBUFFERING; + m->parameter.num = PlayerLiveRadio::PREBUFFERING; m->tag = percentDone; messageQueue->postMessageFromOuterSpace(m); diff --git a/playerlivetv.cc b/playerlivetv.cc index e44ae56..7d0c708 100644 --- a/playerlivetv.cc +++ b/playerlivetv.cc @@ -250,7 +250,7 @@ void PlayerLiveTV::call(void* caller) m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveTV::ASPECT43; + m->parameter.num = PlayerLiveTV::ASPECT43; messageQueue->postMessageFromOuterSpace(m); } else if (dxCurrentAspect == Demuxer::ASPECT_16_9) @@ -269,7 +269,7 @@ void PlayerLiveTV::call(void* caller) m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveTV::ASPECT169; + m->parameter.num = PlayerLiveTV::ASPECT169; messageQueue->postMessageFromOuterSpace(m); } else @@ -308,7 +308,7 @@ void PlayerLiveTV::streamReceive(ULONG flag, void* data, ULONG len) m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveTV::STREAM_END; + m->parameter.num = PlayerLiveTV::STREAM_END; messageQueue->postMessageFromOuterSpace(m); } @@ -652,7 +652,7 @@ bool PlayerLiveTV::checkError() m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveTV::CONNECTION_LOST; + m->parameter.num = PlayerLiveTV::CONNECTION_LOST; messageQueue->postMessageFromOuterSpace(m); return true; @@ -812,7 +812,7 @@ void PlayerLiveTV::threadMethod() m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveTV::STREAM_END; + m->parameter.num = PlayerLiveTV::STREAM_END; messageQueue->postMessageFromOuterSpace(m); } } @@ -849,7 +849,7 @@ void PlayerLiveTV::threadMethod() m->from = this; m->to = messageReceiver; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerLiveTV::PREBUFFERING; + m->parameter.num = PlayerLiveTV::PREBUFFERING; m->tag = percentDone; messageQueue->postMessageFromOuterSpace(m); diff --git a/playermedia.cc b/playermedia.cc index 8c79329..3919ba8 100644 --- a/playermedia.cc +++ b/playermedia.cc @@ -332,7 +332,7 @@ void PlayerMedia::sendFrontendMessage(ULONG para) threadUnlock(); m->from = this; m->message = Message::PLAYER_EVENT; - m->parameter = para; + m->parameter.num = para; Command::getInstance()->postMessageFromOuterSpace(m); } @@ -669,7 +669,7 @@ void PlayerMedia::call(void* caller) m->from = this; m->to = frontend; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerMedia::ASPECT43; + m->parameter.num = PlayerMedia::ASPECT43; Command::getInstance()->postMessageFromOuterSpace(m); } else if (dxCurrentAspect == Demuxer::ASPECT_16_9) @@ -681,7 +681,7 @@ void PlayerMedia::call(void* caller) m->from = this; m->to = frontend; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerMedia::ASPECT169; + m->parameter.num = PlayerMedia::ASPECT169; Command::getInstance()->postMessageFromOuterSpace(m); } else diff --git a/playerradio.cc b/playerradio.cc index 6d5d6b3..24cc1c8 100644 --- a/playerradio.cc +++ b/playerradio.cc @@ -457,7 +457,7 @@ void PlayerRadio::doConnectionLost() m->to = messageReceiver; m->from = this; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerRadio::CONNECTION_LOST; + m->parameter.num = PlayerRadio::CONNECTION_LOST; messageQueue->postMessage(m); } @@ -578,7 +578,7 @@ void PlayerRadio::threadFeedPlay() m->to = messageReceiver; m->from = this; m->message = Message::PLAYER_EVENT; - m->parameter = PlayerRadio::STOP_PLAYBACK; + m->parameter.num = PlayerRadio::STOP_PLAYBACK; logger->log("PlayerRadio", Log::DEBUG, "Posting message to %p...", messageQueue); messageQueue->postMessage(m); } diff --git a/surfacevector.cc b/surfacevector.cc index 8167128..a511353 100644 --- a/surfacevector.cc +++ b/surfacevector.cc @@ -69,20 +69,22 @@ int SurfaceVector::drawText(const char* text, int x, int y, int width, const Dra { float shift=0.; const char *run=text; - mbstate_t state; - wchar_t tempo; - size_t num_bytes=1; size_t length=strlen(text); - memset((void*)&state,0,sizeof(state)); + command_mutex.Lock(); - num_bytes=mbrtowc(&tempo, run, length, &state); - unsigned int ref=osd->getStyleRef(c); + + VectorHandle ref=osd->getStyleRef(c); float *charwidtharray=osd->getCharWidthArray(); - int commands_size=commands.size(); int chars=0; commands.resize(commands_size+strlen(text)); +#ifndef WIN32 + num_bytes=mbrtowc(&tempo, run, length, &state); + mbstate_t state; + wchar_t tempo; + size_t num_bytes = 1; + memset((void*)&state,0,sizeof(state)); while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0) { @@ -100,6 +102,22 @@ int SurfaceVector::drawText(const char* text, int x, int y, int width, const Dra } num_bytes=mbrtowc(&tempo, run, length, &state); } + +#else + wchar_t* temptext = new wchar_t[length + 1]; + int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1, + temptext, length + 1)-1; + for (int i = 0; i < real_length; i++) { + SVGCommand::PaintGlyph(commands[commands_size + chars], x + shift, y, temptext[i], ref); + chars++; + + float cur_shift = charwidtharray[temptext[i] & 0xFF]; + if (temptext[i] && 0xFFFFFF00) cur_shift = osd->getCharWidth(temptext[i]); + shift += cur_shift; + } + delete[] temptext; +#endif + commands.resize(commands_size+chars); command_mutex.Unlock(); return 1; @@ -109,12 +127,13 @@ int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c { float shift=0.; const char *run=text; + size_t length=strlen(text); + +#ifndef WIN32 mbstate_t state; wchar_t tempo[1]; - size_t num_bytes=1; - size_t length=strlen(text); + size_t num_bytes = 1; memset((void*)&state,0,sizeof(state)); - num_bytes=mbrtowc(tempo, run, length, &state); while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0) { @@ -123,6 +142,15 @@ int SurfaceVector::drawTextRJ(const char* text, int x, int y, const DrawStyle& c run += num_bytes; num_bytes=mbrtowc(tempo, run, length, &state); } +#else + wchar_t* temptext=new wchar_t[length+1]; + int real_length=MultiByteToWideChar(CP_UTF8, 0, text, -1, + temptext, length+ 1)-1; + for (int i = 0; i < real_length; i++) { + shift += osd->getCharWidth(temptext[i]); + } + delete[] temptext; +#endif return drawText(text, x-shift, y, c); } @@ -130,12 +158,13 @@ int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyl { float shift=0; const char *run=text; + size_t length=strlen(text); + +#ifndef WIN32 mbstate_t state; wchar_t tempo[1]; - size_t num_bytes=1; - size_t length=strlen(text); + size_t num_bytes = 1; memset((void*)&state,0,sizeof(state)); - num_bytes=mbrtowc(tempo, run, length, &state); while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0) { @@ -144,6 +173,16 @@ int SurfaceVector::drawTextCentre(const char* text, int x, int y, const DrawStyl run += num_bytes; num_bytes=mbrtowc(tempo, run, length, &state); } +#else + wchar_t* temptext = new wchar_t[length + 1]; + int real_length = MultiByteToWideChar(CP_UTF8, 0, text, -1, + temptext, length + 1)-1; + for (int i = 0; i < real_length; i++) { + shift += osd->getCharWidth(temptext[i]); + } + delete[] temptext; +#endif + return drawText(text, x-shift/2., y, c); } @@ -217,7 +256,7 @@ int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& { command_mutex.Lock(); removeCommands(x,y,width,height); // remove commands below the box - unsigned int ref=osd->getStyleRef(c); + VectorHandle ref=osd->getStyleRef(c); commands.push_back(SVGCommand::PaintPath(x,y,width,height,PIRectangle,ref)); command_mutex.Unlock(); return 1; @@ -226,14 +265,14 @@ int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle& void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c) { command_mutex.Lock(); - unsigned int ref=osd->getStyleRef(c); + VectorHandle ref = osd->getStyleRef(c); commands.push_back(SVGCommand::PaintPath(x1,y,x2-x1,1,PIHorzLine,ref)); command_mutex.Unlock(); } void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){ command_mutex.Lock(); - unsigned int ref=osd->getStyleRef(c); + VectorHandle ref = osd->getStyleRef(c); commands.push_back(SVGCommand::PaintPath(x,y1,1,y2-y1,PIVertLine,ref)); command_mutex.Unlock(); } @@ -272,7 +311,7 @@ void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegio void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){ if (!fastdraw) command_mutex.Lock(); - unsigned int ref=osd->getStyleRef(c); + VectorHandle ref = osd->getStyleRef(c); commands.push_back(SVGCommand::PaintPath(x,y,1,1,PIPoint,ref)); if (!fastdraw) command_mutex.Unlock(); } @@ -280,7 +319,7 @@ void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int hei { command_mutex.Lock(); ImageIndex image=osd->getMonoBitmapRef(base,width,height); - unsigned int ref=osd->getStyleRef(nextColour); + VectorHandle ref = osd->getStyleRef(nextColour); removeCommands(dx,dy,width,height); commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref)); command_mutex.Unlock(); @@ -293,9 +332,16 @@ int SurfaceVector::removeCommands(float x,float y,float width,float height) vector::iterator itty=commands.begin(); vector::iterator remstart; bool remove=false; + float cx, cy, cw, ch; + cx = cy = 0.f; + cw = swidth; + ch = sheight; + bool clipping_erases = false; while (itty!=commands.end()) { - if ((*itty).Test(x,y,width,height) && (*itty).instr != DrawClipping) { + if ((clipping_erases // test if clipping helps + || (*itty).Test(x,y,width,height) ) + && (*itty).instr != DrawClipping) { //Log::getInstance()->log("OSD", Log::DEBUG, "Remove command %d %g %g %g %g %d %d",(*itty).instr, //(*itty).x,(*itty).y,(*itty).w,(*itty).h,(*itty).reference,(*itty).target.image); osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff @@ -307,7 +353,21 @@ int SurfaceVector::removeCommands(float x,float y,float width,float height) remstart=itty; remove=true; } - } else { + } else { + if ((*itty).instr == DrawClipping) { + if ((*itty).w == 0.f && (*itty).h == 0.f) { + cx = cy = 0.f; + cw = swidth; + ch = sheight; + + } else { + cx = (*itty).x; + cy = (*itty).y; + cw = (*itty).w; + ch = (*itty).h; + } + clipping_erases = (cx >= x) && (cy >= y) && ((cx + cw) <= (x + width)) && ((cy + ch) <= (y + height)); + } if (remove) { itty=commands.erase(remstart,itty); remove=false; diff --git a/teletextdecodervbiebu.cc b/teletextdecodervbiebu.cc index 4053aee..0083469 100644 --- a/teletextdecodervbiebu.cc +++ b/teletextdecodervbiebu.cc @@ -819,14 +819,14 @@ void TeletextDecoderVBIEBU::RenderTeletextCode(bool renderfirstlineonly) { m->message = Message::TELETEXTUPDATE; m->to = txtview; m->from = this; - m->parameter = 0; + m->parameter.num = 0; Command::getInstance()->postMessageFromOuterSpace(m); } else if (firstlineupdate==10) { Message* m= new Message(); m->message = Message::TELETEXTUPDATEFIRSTLINE; m->to = txtview; m->from = this; - m->parameter = 0; + m->parameter.num = 0; Command::getInstance()->postMessageFromOuterSpace(m); firstlineupdate=0; } else firstlineupdate++; diff --git a/threadwin.h b/threadwin.h index 3c4903f..4d6901d 100644 --- a/threadwin.h +++ b/threadwin.h @@ -22,7 +22,6 @@ #define THREADWIN_H -#define _WIN32_WINNT 0x501 #include #include typedef struct timespec diff --git a/udp.cc b/udp.cc index 0a775ea..f0d5e74 100644 --- a/udp.cc +++ b/udp.cc @@ -120,7 +120,7 @@ void UDP::processRequest(UCHAR* data, int length) Message *m = new Message(); m->to = commandMessageQueue; m->message = Message::UDP_BUTTON; - m->parameter = command; + m->parameter.num = command; commandMessageQueue->postMessage(m); } diff --git a/vaudioselector.cc b/vaudioselector.cc index 4ed9c87..eed93ec 100644 --- a/vaudioselector.cc +++ b/vaudioselector.cc @@ -454,10 +454,10 @@ void VAudioSelector::draw() drawText(tr("Audio"), 45, 5, DrawStyle::LIGHTTEXT); if (subtitles) { drawText(tr("Subtitles"), 45+200, 5, DrawStyle::LIGHTTEXT); + ssl.setBackgroundColour(backgroundColour); ssl.draw(); } - asl.setBackgroundColour(backgroundColour); asl.draw(); @@ -485,7 +485,7 @@ int VAudioSelector::handleCommand(int command) m->from = this; m->to = parent; m->message = Message::SUBTITLE_CHANGE_CHANNEL; - m->parameter = (((AudioSubtitleChannel*)ssl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)ssl.getCurrentOptionData())->type &0xFF)<<16 ; + m->parameter.num = (((AudioSubtitleChannel*)ssl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)ssl.getCurrentOptionData())->type &0xFF)<<16 ; Command::getInstance()->postMessageNoLock(m); } else { asl.up(); @@ -495,7 +495,7 @@ int VAudioSelector::handleCommand(int command) m->from = this; m->to = parent; m->message = Message::AUDIO_CHANGE_CHANNEL; - m->parameter = (((AudioSubtitleChannel*)asl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)asl.getCurrentOptionData())->type &0xFF)<<16 ; + m->parameter.num = (((AudioSubtitleChannel*)asl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)asl.getCurrentOptionData())->type &0xFF)<<16 ; Command::getInstance()->postMessageNoLock(m); } @@ -512,7 +512,7 @@ int VAudioSelector::handleCommand(int command) m->from = this; m->to = parent; m->message = Message::SUBTITLE_CHANGE_CHANNEL; - m->parameter = (((AudioSubtitleChannel*)ssl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)ssl.getCurrentOptionData())->type &0xFF)<<16 + m->parameter.num = (((AudioSubtitleChannel*)ssl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)ssl.getCurrentOptionData())->type &0xFF)<<16 |(((AudioSubtitleChannel*)asl.getCurrentOptionData())->streamtype &0xFF)<<24 ; Command::getInstance()->postMessageNoLock(m); } else { @@ -523,7 +523,7 @@ int VAudioSelector::handleCommand(int command) m->from = this; m->to = parent; m->message = Message::AUDIO_CHANGE_CHANNEL; - m->parameter = (((AudioSubtitleChannel*)asl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)asl.getCurrentOptionData())->type &0xFF)<<16 + m->parameter.num = (((AudioSubtitleChannel*)asl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)asl.getCurrentOptionData())->type &0xFF)<<16 |(((AudioSubtitleChannel*)asl.getCurrentOptionData())->streamtype &0xFF)<<24 ; Command::getInstance()->postMessageNoLock(m); } @@ -568,7 +568,7 @@ void VAudioSelector::processMessage(Message* m) UINT lastsel=asl.getCurrentOption(); - if (((m->parameter>>16)-getScreenX()) < 200 && asl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (((m->parameter.num>>16)-getScreenX()) < 200 && asl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { editsubtitles=false; ssl.setDarkSelOption(true); @@ -582,7 +582,7 @@ void VAudioSelector::processMessage(Message* m) m2->from = this; m2->to = parent; m2->message = Message::AUDIO_CHANGE_CHANNEL; - m2->parameter = (((AudioSubtitleChannel*)asl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)asl.getCurrentOptionData())->type &0xFF)<<16 ; + m2->parameter.num = (((AudioSubtitleChannel*)asl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)asl.getCurrentOptionData())->type &0xFF)<<16 ; Command::getInstance()->postMessageNoLock(m2); } return; @@ -590,7 +590,7 @@ void VAudioSelector::processMessage(Message* m) } lastsel=ssl.getCurrentOption(); - if (ssl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (ssl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { editsubtitles=true; ssl.setDarkSelOption(false); @@ -604,7 +604,7 @@ void VAudioSelector::processMessage(Message* m) m2->from = this; m2->to = parent; m2->message = Message::SUBTITLE_CHANGE_CHANNEL; - m2->parameter = (((AudioSubtitleChannel*)ssl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)ssl.getCurrentOptionData())->type &0xFF)<<16 ; + m2->parameter.num = (((AudioSubtitleChannel*)ssl.getCurrentOptionData())->pestype &0xFFFF)|(((AudioSubtitleChannel*)ssl.getCurrentOptionData())->type &0xFF)<<16 ; Command::getInstance()->postMessageNoLock(m2); } return; @@ -612,7 +612,7 @@ void VAudioSelector::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (asl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (asl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { editsubtitles=false; ssl.setDarkSelOption(true); @@ -621,7 +621,7 @@ void VAudioSelector::processMessage(Message* m) ssl.draw(); BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press } - else if (ssl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + else if (ssl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { editsubtitles=true; ssl.setDarkSelOption(false); @@ -632,8 +632,8 @@ void VAudioSelector::processMessage(Message* m) } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press diff --git a/vchannellist.cc b/vchannellist.cc index 8d6573d..d16d7cf 100644 --- a/vchannellist.cc +++ b/vchannellist.cc @@ -264,7 +264,7 @@ void VChannelList::processMessage(Message* m) { /* if (m->message == Message::MOUSE_MOVE) { if (sl.mouseAndroidScroll((m->tag >> 16),(m->tag & 0xFFFF), - (m->parameter >> 16),(m->parameter & 0xFFFF))) { + (m->parameter.num >> 16),(m->parameter.num & 0xFFFF))) { sl.draw(); doShowingBar(); boxstack->update(this); @@ -272,7 +272,7 @@ void VChannelList::processMessage(Message* m) } else */if (m->message == Message::MOUSE_MOVE) { - if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { quickUpdate(); boxstack->update(this); @@ -280,14 +280,14 @@ void VChannelList::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { boxstack->handleCommand(Remote::OK); //simulate OK press } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { boxstack->handleCommand(Remote::BACK); //simulate cancel press @@ -299,7 +299,7 @@ void VChannelList::processMessage(Message* m) Channel* chan = NULL; for (UINT i = 0; i < chanList->size(); i++) { - if ((*chanList)[i]->number == m->parameter) + if ((*chanList)[i]->number == m->parameter.num) { chan = (*chanList)[i]; break; diff --git a/vchannelselect.cc b/vchannelselect.cc index 8871008..12128ea 100644 --- a/vchannelselect.cc +++ b/vchannelselect.cc @@ -109,11 +109,11 @@ void VChannelSelect::changeChannel(bool which) m->from = this; m->to = parent; m->message = Message::CHANNEL_CHANGE; - m->parameter = 0; + m->parameter.num = 0; for(i = numGot - 1; i >= 0; i--) { - m->parameter += input[i] * (ULONG)pow(10., i); + m->parameter.num += input[i] * (ULONG)pow(10., i); } if (which) diff --git a/vcolourtuner.cc b/vcolourtuner.cc index bab815a..7f77428 100644 --- a/vcolourtuner.cc +++ b/vcolourtuner.cc @@ -233,8 +233,8 @@ void VColourTuner::processMessage(Message* m) else if (m->message == Message::MOUSE_LBDOWN) { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press diff --git a/vconnect.cc b/vconnect.cc index 50a0469..910fa46 100644 --- a/vconnect.cc +++ b/vconnect.cc @@ -204,7 +204,7 @@ void VConnect::processMessage(Message* m) { if (m->message == Message::SERVER_SELECTED) { - selectedServer = m->parameter; + selectedServer = m->parameter.num; threadSignal(); } } diff --git a/vepg.cc b/vepg.cc index 9779265..94624f6 100644 --- a/vepg.cc +++ b/vepg.cc @@ -89,7 +89,7 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ChannelList* tchanList) int screenheighthalf=Video::getInstance()->getScreenHeight()/2; // summaryLines = ((float)screenheighthalf)/((float)fontHeight))-1; // summaryLowerPadding = screenheighthalf-summaryLines*(fontHeight); - gridRows = (screenheighthalf-fontHeight*3-40)/fontHeight; + gridRows = (screenheighthalf-fontHeight*3-50)/fontHeight; // initialise variables and pointers @@ -123,6 +123,7 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ChannelList* tchanList) progTitle.setBackgroundColour(DrawStyle::TITLEBARBACKGROUND); progTitle.setTextPos(xpos, ypos); progTitle.setGap(4); + progTitle.setParaMode(false); add(&progTitle); // progInfo.setSurface(surface); @@ -138,6 +139,7 @@ VEpg::VEpg(void* tparent, UINT tcurrentChannelIndex, ChannelList* tchanList) chanName.setPosition(screenwidthhalf, screenheighthalf - 2*fontHeight); DrawStyle t1(0, 0, 0, 90); chanName.setBackgroundColour(t1); + chanName.setParaMode(false); add(&chanName); // create area to display list of channels @@ -233,6 +235,7 @@ void VEpg::setInfo(Event* event) strftime(timeString, 7, "%H:%M ", btime); // and format it as hh:mm - #endif strcat(title, timeString); // put it in our buffer + strcat(title, event->title); // then add the programme title progTitle.setText(title); // sput this sring in our text box length = strlen(event->description); @@ -449,7 +452,7 @@ int VEpg::handleCommand(int command) m->from = this; m->to = parent; m->message = Message::CHANNEL_CHANGE; - m->parameter = (*chanList)[currentChannelIndex]->number; + m->parameter.num = (*chanList)[currentChannelIndex]->number; Command::getInstance()->postMessageNoLock(m); } @@ -477,7 +480,7 @@ int VEpg::handleCommand(int command) m->from = this; m->to = parent; m->message = Message::CHANNEL_CHANGE; - m->parameter = (*chanList)[currentChannelIndex]->number; + m->parameter.num = (*chanList)[currentChannelIndex]->number; Command::getInstance()->postMessageNoLock(m); } @@ -498,7 +501,7 @@ int VEpg::handleCommand(int command) m->from = this; m->to = parent; m->message = Message::CHANNEL_CHANGE; - m->parameter = (*chanList)[currentChannelIndex]->number; + m->parameter.num = (*chanList)[currentChannelIndex]->number; Command::getInstance()->postMessageNoLock(m); } @@ -767,7 +770,7 @@ void VEpg::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (chanListbox.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (chanListbox.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { drawData(); boxstack->update(this); @@ -775,15 +778,15 @@ void VEpg::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (chanListbox.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (chanListbox.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { boxstack->handleCommand(Remote::OK); //simulate OK press } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); int keyx = chanListbox.getRootBoxOffsetX(); int keyy = chanListbox.getRootBoxOffsetY() + chanListbox.getHeight() + 2; @@ -796,7 +799,7 @@ void VEpg::processMessage(Message* m) boxstack->handleCommand(Remote::RED); } else if (x>=(keyx+72) && y>=(keyy+ getFontHeight() + 8) &&x<=(keyx+72+104) &&y<=(keyy+8+2*getFontHeight() + 2)) - { + { boxstack->handleCommand(Remote::GREEN); } else if (x>=(keyx+180) && y>=(keyy+4) &&x<=(keyx+180+104) &&y<=(keyy+4+getFontHeight() + 2)) diff --git a/vepglistadvanced.cc b/vepglistadvanced.cc index 38a2555..0ac6b92 100644 --- a/vepglistadvanced.cc +++ b/vepglistadvanced.cc @@ -269,7 +269,7 @@ void VEpgListAdvanced::doSwitch() m->from = this; m->to = videolive; m->message = Message::CHANNEL_CHANGE; - m->parameter = channelNumber; + m->parameter.num = channelNumber; m->tag = 0; Command::getInstance()->postMessageNoLock(m); } @@ -863,7 +863,7 @@ void VEpgListAdvanced::processMessage(Message* m) if (m->message == Message::MOUSE_MOVE) { - if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { quickUpdate(); boxstack->update(this); @@ -871,15 +871,31 @@ void VEpgListAdvanced::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { boxstack->handleCommand(Remote::OK); //simulate OK press } + else if (boxRed.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) + { + boxstack->handleCommand(Remote::RED); + } + else if (boxGreen.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) + { + boxstack->handleCommand(Remote::GREEN); + } + else if (boxYellow.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) + { + boxstack->handleCommand(Remote::GREEN); + } + else if (boxBlue.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) + { + boxstack->handleCommand(Remote::GREEN); + } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { boxstack->handleCommand(Remote::BACK); //simulate cancel press diff --git a/vepgsettimer.cc b/vepgsettimer.cc index b48fe5e..582ce68 100644 --- a/vepgsettimer.cc +++ b/vepgsettimer.cc @@ -278,7 +278,7 @@ void VEpgSetTimer::doit() Message* m = new Message(); m->message = Message::ADD_VIEW; m->to = boxstack; - m->parameter = (ULONG)vi; + m->parameter.num = (ULONG)vi; Command::getInstance()->postMessageNoLock(m); } @@ -286,14 +286,14 @@ void VEpgSetTimer::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (buttonYes.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (buttonYes.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { buttonNo.setActive(0); selectedOption = YES; draw(); boxstack->update(this); } - else if (buttonNo.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + else if (buttonNo.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { buttonYes.setActive(0); selectedOption = NO; @@ -303,19 +303,19 @@ void VEpgSetTimer::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (buttonYes.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (buttonYes.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { boxstack->handleCommand(Remote::OK); //simulate OK press } - else if (buttonNo.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + else if (buttonNo.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { boxstack->handleCommand(Remote::OK); //simulate OK press } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { boxstack->handleCommand(Remote::BACK); //simulate cancel press diff --git a/vepgsummary.cc b/vepgsummary.cc index 84531e7..b60aa32 100644 --- a/vepgsummary.cc +++ b/vepgsummary.cc @@ -207,7 +207,7 @@ void VEpgSummary::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (tabbar.mouseMove((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY())) + if (tabbar.mouseMove((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) { BoxStack::getInstance()->update(this); } @@ -215,8 +215,8 @@ void VEpgSummary::processMessage(Message* m) else if (m->message == Message::MOUSE_LBDOWN) { int cancel = true; - int x = (m->parameter >> 16) - getScreenX(); - int y = (m->parameter & 0xFFFF) - getScreenY(); + int x = (m->parameter.num >> 16) - getScreenX(); + int y = (m->parameter.num & 0xFFFF) - getScreenY(); if ((boxRed.getX() <= x) && (boxRed.getX() + (int)boxRed.getWidth() >= x) && (boxRed.getY() <= y) && (boxRed.getY() + (int)boxRed.getHeight() >= y)) { @@ -225,7 +225,7 @@ void VEpgSummary::processMessage(Message* m) } - if (cancel && tabbar.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY())) + if (cancel && tabbar.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) { BoxStack::getInstance()->update(this); cancel = false; @@ -233,8 +233,8 @@ void VEpgSummary::processMessage(Message* m) if (cancel) { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press @@ -243,7 +243,7 @@ void VEpgSummary::processMessage(Message* m) } else if (m->message == Message::MOUSE_SCROLL) { if (tabbar.mouseAndroidScroll((m->tag >> 16) - getScreenX(), (m->tag & 0xFFFF) - getScreenY(), - (short)(m->parameter >> 16), (short)(m->parameter & 0xFFFF))) + (short)(m->parameter.num >> 16), (short)(m->parameter.num & 0xFFFF))) { BoxStack::getInstance()->update(this); return; diff --git a/videowin.cc b/videowin.cc index b6da2bb..93637c3 100644 --- a/videowin.cc +++ b/videowin.cc @@ -26,6 +26,7 @@ #include "dsallocator.h" #include "vdr.h" #include "windowsosd.h" +#include "osdwinvector.h" #include "audiowin.h" #include "wwinvideofilter.h" #include "wwinvideoh264filter.h" @@ -93,7 +94,6 @@ VideoWin::VideoWin() - } VideoWin::~VideoWin() @@ -146,7 +146,13 @@ int VideoWin::setTVsize(UCHAR ttvsize) int VideoWin::setDefaultAspect() { - return setAspectRatio(Video::ASPECT4X3,parx,pary); + Osd *osd = Osd::getInstance(); + if (dynamic_cast(osd)) { + return setAspectRatio(Video::ASPECT16X9, parx, pary); + } + else { + return setAspectRatio(Video::ASPECT4X3, parx, pary); + } } int VideoWin::shutdown() diff --git a/vompreswin.h b/vompreswin.h index 9d8071f..8cffeaa 100644 --- a/vompreswin.h +++ b/vompreswin.h @@ -24,6 +24,7 @@ #include #include +#include "defines.h" #define VOMPACCELERATOR 1 #define VOMPMENU 2 #define VOMP_FULL_SCREEN 101 diff --git a/vompwin.rc b/vompwin.rc index a5af354..e97ff35 100644 --- a/vompwin.rc +++ b/vompwin.rc @@ -40,9 +40,20 @@ BEGIN VK_RETURN, VOMP_FULL_SCREEN, VIRTKEY, ALT, NOINVERT END +#ifdef WINDOWS_LEGACY /vdr.jpg RCDATA other\vdr.jpg /wallpaperNTSC.jpg RCDATA other\wallpaperNTSC.jpg /wallpaperPAL.jpg RCDATA other\wallpaperPAL.jpg +#else +#include "staticartwork.h" + +#define EXTERNALPICTURE(name, fname, fileextension) name RCDATA other\\##fname.##fileextension + +EXTERNAL_PICTS + +#undef EXTERNALPICTURE + +#endif VOMPMENU MENU BEGIN diff --git a/vopts.cc b/vopts.cc index a415e7d..00d8919 100644 --- a/vopts.cc +++ b/vopts.cc @@ -517,8 +517,8 @@ void VOpts::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (tabbar.mouseMove(x,y)) { BoxStack::getInstance()->update(this); @@ -527,8 +527,8 @@ void VOpts::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (tabbar.mouseLBDOWN(x,y)) { BoxStack::getInstance()->update(this); diff --git a/vpicturebanner.cc b/vpicturebanner.cc index c1ceef6..d89ce4b 100644 --- a/vpicturebanner.cc +++ b/vpicturebanner.cc @@ -105,8 +105,8 @@ void VPictureBanner::processMessage(Message* m) else if (m->message == Message::MOUSE_LBDOWN) { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press diff --git a/vquestion.cc b/vquestion.cc index 5dca6c4..307df44 100644 --- a/vquestion.cc +++ b/vquestion.cc @@ -127,14 +127,14 @@ void VQuestion::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (buttonYes.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (buttonYes.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { buttonNo.setActive(0); selectedOption = YES; draw(); BoxStack::getInstance()->update(this); } - else if (buttonNo.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + else if (buttonNo.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { buttonYes.setActive(0); selectedOption = NO; @@ -144,19 +144,19 @@ void VQuestion::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (buttonYes.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (buttonYes.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press } - else if (buttonNo.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + else if (buttonNo.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press diff --git a/vradiorec.cc b/vradiorec.cc index 1dc28a7..5575b63 100644 --- a/vradiorec.cc +++ b/vradiorec.cc @@ -167,7 +167,7 @@ void VRadioRec::go() m = new Message(); m->message = Message::ADD_VIEW; m->to = boxstack; - m->parameter = (ULONG)vi; + m->parameter.num = (ULONG)vi; Command::getInstance()->postMessageNoLock(m); } } @@ -267,8 +267,8 @@ void VRadioRec::processMessage(Message* m) { if (m->message == Message::MOUSE_LBDOWN) { - int x=(m->parameter>>16)-(int)getScreenX(); - int y=(m->parameter&0xFFFF)-(int)getScreenY(); + int x=(m->parameter.num>>16)-(int)getScreenX(); + int y=(m->parameter.num&0xFFFF)-(int)getScreenY(); if (!barShowing) { boxstack->handleCommand(Remote::OK); //simulate rok press @@ -302,7 +302,7 @@ void VRadioRec::processMessage(Message* m) Log::getInstance()->log("VRadioRec", Log::DEBUG, "Message received"); - switch(m->parameter) + switch(m->parameter.num) { case Player::CONNECTION_LOST: // connection lost detected { diff --git a/vrecmove.cc b/vrecmove.cc index 61f132c..caa28ea 100644 --- a/vrecmove.cc +++ b/vrecmove.cc @@ -130,7 +130,7 @@ int VRecMove::handleCommand(int command) Message* m = new Message(); m->message = Message::MOVE_RECORDING; m->to = parent; - m->parameter = sl.getCurrentOptionData(); + m->parameter.num = sl.getCurrentOptionData(); Command::getInstance()->postMessageNoLock(m); return 4; @@ -148,7 +148,7 @@ void VRecMove::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { sl.draw(); BoxStack::getInstance()->update(this); @@ -156,15 +156,15 @@ void VRecMove::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press diff --git a/vrecording.cc b/vrecording.cc index 47ac22e..5f99d8a 100644 --- a/vrecording.cc +++ b/vrecording.cc @@ -45,6 +45,7 @@ VRecording::VRecording(RecMan* trecman, Recording* trec) rec = trec; recman = trecman; buttons = true; + selected = RESUME; Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName()); rec->loadRecInfo(); @@ -138,7 +139,7 @@ VRecording::VRecording(RecMan* trecman, Recording* trec) add(&button[i]); } - selected = RESUME; + button[selected].setActive(1); tabbar.activateFocus(false); } @@ -173,8 +174,8 @@ void VRecording::draw() if (poster.height) { // float aspect=((float)poster.height)/((float)poster.width)/Osd::getInstance()->getPixelAspect(); drawTVMedia(poster.info,buttonRegion.x, - buttonRegion.y+buttonRegion.h, - buttonRegion.w,/*buttonRegion.w*aspect*/0.f); + tabbar.getY2()-3, + buttonRegion.w,/*buttonRegion.w*aspect*/0.f,BottomLeft); } } @@ -191,6 +192,7 @@ int VRecording::handleCommand(int command) case Remote::DF_UP: case Remote::UP: { + tabbar.activateFocus(false); moveCursor(LEFT); return 2; } @@ -198,6 +200,7 @@ int VRecording::handleCommand(int command) case Remote::DF_DOWN: case Remote::DOWN: { + tabbar.activateFocus(false); moveCursor(RIGHT); return 2; } @@ -327,18 +330,20 @@ void VRecording::processMessage(Message* m) { for (int i = PLAY; i < last; i++) { - if (button[i].mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (button[i].mouseMove((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) { for (int j = PLAY; j < last; j++) button[j].setActive(0); button[i].setActive(1); + tabbar.activateFocus(false); + buttons = true; selected=i; draw(); BoxStack::getInstance()->update(this); break; } } - if (tabbar.mouseMove((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY())) + if (tabbar.mouseMove((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) { BoxStack::getInstance()->update(this); return; @@ -347,7 +352,7 @@ void VRecording::processMessage(Message* m) else if (m->message == Message::MOUSE_SCROLL) { if (tabbar.mouseAndroidScroll((m->tag >> 16) - getScreenX(), (m->tag & 0xFFFF) - getScreenY(), - (short)(m->parameter >> 16), (short) (m->parameter & 0xFFFF))) + (short)(m->parameter.num >> 16), (short) (m->parameter.num & 0xFFFF))) { BoxStack::getInstance()->update(this); return; @@ -358,23 +363,27 @@ void VRecording::processMessage(Message* m) int cancel = true; for (int i = PLAY; i < last; i++) { - if (button[i].mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (button[i].mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press + buttons = true; cancel = false; break; } } - if (cancel && tabbar.mouseLBDOWN((m->parameter >> 16) - getScreenX(), (m->parameter & 0xFFFF) - getScreenY())) + if (cancel && tabbar.mouseLBDOWN((m->parameter.num >> 16) - getScreenX(), (m->parameter.num & 0xFFFF) - getScreenY())) { + buttons = false; + button[selected].setActive(0); + BoxStack::getInstance()->update(this); cancel = false; } if (cancel) { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press @@ -410,7 +419,7 @@ void VRecording::processMessage(Message* m) m2->from = this; m2->to = vRecList; m2->message = Message::MOVE_RECORDING; - m2->parameter = m->parameter; + m2->parameter.num = m->parameter.num; Command::getInstance()->postMessageNoLock(m2); } } diff --git a/vrecordinglist.cc b/vrecordinglist.cc index 71f53a5..b99b991 100644 --- a/vrecordinglist.cc +++ b/vrecordinglist.cc @@ -57,7 +57,7 @@ void VRecordingList::processMessage(Message* m) if (m->message == Message::MOUSE_MOVE) { - if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { quickUpdate(); boxstack->update(this); @@ -65,15 +65,15 @@ void VRecordingList::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { boxstack->handleCommand(Remote::OK); //simulate OK press } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { boxstack->handleCommand(Remote::BACK); //simulate cancel press @@ -88,7 +88,7 @@ void VRecordingList::processMessage(Message* m) else if (m->message == Message::MOVE_RECORDING) { Log::getInstance()->log("VRecordingList", Log::DEBUG, "Doing move recording"); - doMoveRecording((Directory*)m->parameter); + doMoveRecording((Directory*)m->parameter.num); } else if (m->message == Message::PLAY_SELECTED_RECORDING) { diff --git a/vrecordingmenu.cc b/vrecordingmenu.cc index d78c9ef..3cccca7 100644 --- a/vrecordingmenu.cc +++ b/vrecordingmenu.cc @@ -197,7 +197,7 @@ void VRecordingMenu::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { sl.draw(); BoxStack::getInstance()->update(this); @@ -205,15 +205,15 @@ void VRecordingMenu::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press @@ -249,7 +249,7 @@ void VRecordingMenu::processMessage(Message* m) m2->from = this; m2->to = vRecList; m2->message = Message::MOVE_RECORDING; - m2->parameter = m->parameter; + m2->parameter.num = m->parameter.num; Command::getInstance()->postMessageNoLock(m2); } } diff --git a/vserverselect.cc b/vserverselect.cc index f1922be..d6219d2 100644 --- a/vserverselect.cc +++ b/vserverselect.cc @@ -98,7 +98,7 @@ int VServerSelect::handleCommand(int command) Message* m = new Message(); // Question/Answer mech. Better being messages m->to = replyTo; m->message = Message::SERVER_SELECTED; - m->parameter = sl.getCurrentOption(); + m->parameter.num = sl.getCurrentOption(); Command::getInstance()->postMessageNoLock(m); return 4; } @@ -111,7 +111,7 @@ void VServerSelect::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { sl.draw(); BoxStack::getInstance()->update(this); @@ -119,7 +119,7 @@ void VServerSelect::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press } diff --git a/vsleeptimer.cc b/vsleeptimer.cc index 964ac26..4b3df05 100644 --- a/vsleeptimer.cc +++ b/vsleeptimer.cc @@ -166,8 +166,8 @@ void Sleeptimer::threadMethod() free(temp); Message* m1 = new Message(); m1->message = Message::ADD_VIEW; - m1->to = BoxStack::getInstance(); - m1->parameter = (ULONG)count; + m1->to = BoxStack::getInstance(); + m1->parameter.num = (ULONG)count; Command::getInstance()->postMessageNoLock(m1); } MILLISLEEP(1000); @@ -179,7 +179,7 @@ void Sleeptimer::threadMethod() m2->message = Message::UDP_BUTTON; m2->to = Command::getInstance(); m2->from = this; - m2->parameter = 61; + m2->parameter.num = 61; Command::getInstance()->postMessageFromOuterSpace(m2); shutdown(); } diff --git a/vtimeredit.cc b/vtimeredit.cc index 1e03d2e..313f8cc 100644 --- a/vtimeredit.cc +++ b/vtimeredit.cc @@ -240,8 +240,8 @@ void VTimerEdit::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (buttonBack.mouseMove(x,y)) { selectedButton=0; buttonDelete.setActive(false); diff --git a/vtimerlist.cc b/vtimerlist.cc index fa20d32..2ecaf3f 100644 --- a/vtimerlist.cc +++ b/vtimerlist.cc @@ -321,7 +321,7 @@ void VTimerList::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { quickUpdate(); BoxStack::getInstance()->update(this); @@ -329,15 +329,15 @@ void VTimerList::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { BoxStack::getInstance()->handleCommand(Remote::OK); //simulate OK press } else { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-getScreenX(); - int y=(m->parameter&0xFFFF)-getScreenY(); + int x=(m->parameter.num>>16)-getScreenX(); + int y=(m->parameter.num&0xFFFF)-getScreenY(); if (x<0 || y <0 || x>(int)getWidth() || y>(int)getHeight()) { BoxStack::getInstance()->handleCommand(Remote::BACK); //simulate cancel press diff --git a/vvideolivetv.cc b/vvideolivetv.cc index e788024..552c853 100644 --- a/vvideolivetv.cc +++ b/vvideolivetv.cc @@ -140,7 +140,7 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V } osdposterbanner.setPosition(20,20); - osdposterbanner.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //osdposterbanner.setBackgroundColour(DrawStyle::OSDBACKGROUND); osdposterbanner.setSize(video->getScreenWidth()*4/10,video->getScreenHeight()*4/10); osdposterbanner.setVisible(false); add(&osdposterbanner); @@ -156,7 +156,7 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V int channellogomove=0; int boxdiff=166; if (osdv) { - osdChannelLogo.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //osdChannelLogo.setBackgroundColour(DrawStyle::OSDBACKGROUND); osdChannelLogo.setPosition(30,5); osdChannelLogo.setSize(60,60); osdChannelLogo.setTVMedia(info, WTVMedia::ZoomVertical); @@ -166,17 +166,17 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V } - clock.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //clock.setBackgroundColour(DrawStyle::OSDBACKGROUND); clock.setPosition(osd.getWidth() - 100, 4); clock.setSize(90, 30); osd.add(&clock); - osdChanNum.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //osdChanNum.setBackgroundColour(DrawStyle::OSDBACKGROUND); osdChanNum.setPosition(60+channellogomove, 4); osdChanNum.setSize((numberWidth*10) + 22, getFontHeight()+5); // 10 px = width of number chars in font osd.add(&osdChanNum); - osdChanName.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //osdChanName.setBackgroundColour(DrawStyle::OSDBACKGROUND); osdChanName.setPosition(osdChanNum.getX2() + 10, 4); osdChanName.setSize(300, 30); osd.add(&osdChanName); @@ -201,7 +201,7 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V boxBlue.setSize(18, 16); osd.add(&boxBlue); - textRed.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //textRed.setBackgroundColour(DrawStyle::OSDBACKGROUND); textRed.setPosition(boxRed.getX2(), 98); textRed.setSize(boxGreen.getX() - boxRed.getX2(), 30); textRed.setText(tr("Summary")); @@ -209,26 +209,26 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V if (streamType == VDR::VIDEO) { - textGreen.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //textGreen.setBackgroundColour(DrawStyle::OSDBACKGROUND); textGreen.setPosition(boxGreen.getX2(), 98); textGreen.setSize(boxYellow.getX() - boxGreen.getX2(), 30); textGreen.setText(tr("Audio")); osd.add(&textGreen); } - textYellow.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //textYellow.setBackgroundColour(DrawStyle::OSDBACKGROUND); textYellow.setPosition(boxYellow.getX2(), 98); textYellow.setSize(boxBlue.getX() - boxYellow.getX2(), 30); textYellow.setText(tr("Teletext")); osd.add(&textYellow); - textBlue.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //textBlue.setBackgroundColour(DrawStyle::OSDBACKGROUND); textBlue.setPosition(boxBlue.getX2(), 98); textBlue.setSize(osd.getX2() - boxBlue.getX2(), 30); textBlue.setText(tr("EPG")); osd.add(&textBlue); - sl.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //sl.setBackgroundColour(DrawStyle::OSDBACKGROUND); sl.setPosition(90, 36); sl.setSize(480, 58); osd.add(&sl); @@ -278,7 +278,7 @@ VVideoLiveTV::VVideoLiveTV(ChannelList* tchanList, ULONG initialChannelNumber, V } - textUnavailable.setBackgroundColour(DrawStyle::OSDBACKGROUND); + //textUnavailable.setBackgroundColour(DrawStyle::OSDBACKGROUND); textUnavailable.setPosition(60, 30); textUnavailable.setSize(osd.getWidth() - 120, 30); textUnavailable.setText(tr("Channel Unavailable")); @@ -880,7 +880,7 @@ void VVideoLiveTV::timercall(int ref) Message* m = new Message(); m->message = Message::CHANNEL_CHANGE; m->to = this; - m->parameter = newChannel; + m->parameter.num = newChannel; m->tag = 1; // signal to call displayOSD(); Command::getInstance()->postMessageFromOuterSpace(m); Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Timer Call 1 key end."); @@ -1028,8 +1028,8 @@ void VVideoLiveTV::processMessage(Message* m) if (m->message == Message::MOUSE_LBDOWN) { //check if press is outside this view! then simulate cancel - int x=(m->parameter>>16)-osd.getScreenX(); - int y=(m->parameter&0xFFFF)-osd.getScreenY(); + int x = (m->parameter.num >> 16) - osd.getScreenX(); + int y = (m->parameter.num & 0xFFFF) - osd.getScreenY(); if (osd.getVisible()) { if ((boxRed.getX()<=x) && (boxRed.getX()+(int)boxRed.getWidth()>=x ) && @@ -1054,7 +1054,7 @@ void VVideoLiveTV::processMessage(Message* m) } else if (m->message == Message::CHANNEL_CHANGE) { - channelChange(NUMBER, m->parameter); + channelChange(NUMBER, m->parameter.num); osdChannelIndex = currentChannelIndex; if (m->tag == 1) displayOSD(true); } @@ -1068,18 +1068,18 @@ void VVideoLiveTV::processMessage(Message* m) } else if (m->message == Message::AUDIO_CHANGE_CHANNEL) { - Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change audio channel to %x", m->parameter); - player->setAudioChannel((m->parameter & 0xFFFF),(m->parameter & 0xFF0000)>>16,(m->parameter & 0xFF000000)>>24); + Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change audio channel to %x", m->parameter.num); + player->setAudioChannel((m->parameter.num & 0xFFFF), (m->parameter.num & 0xFF0000) >> 16, (m->parameter.num & 0xFF000000) >> 24); } else if (m->message == Message::SUBTITLE_CHANGE_CHANNEL) { if (streamType !=VDR::VIDEO) return; - Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change subtitle channel to %x", m->parameter); - int type=((m->parameter & 0xFF0000)>>16); + Log::getInstance()->log("VVideoLiveTV", Log::DEBUG, "Received change subtitle channel to %x", m->parameter.num); + int type=((m->parameter.num & 0xFF0000)>>16); switch (type) { case 0x10: { //dvbsubtitle if (streamType == VDR::VIDEO){ - player->setSubtitleChannel((m->parameter & 0xFFFF)); + player->setSubtitleChannel((m->parameter.num & 0xFFFF)); (static_cast(player))->turnSubtitlesOn(true); VTeletextView *vtxt=((PlayerLiveTV*)player)->getTeletextDecoder()->getTeletxtView(); if (vtxt && vtxt->isInSubtitleMode()) { @@ -1099,7 +1099,7 @@ void VVideoLiveTV::processMessage(Message* m) case 0x11: { //videotext (static_cast(player))->turnSubtitlesOn(false); doTeletext(true); - ((PlayerLiveTV*)player)->getTeletextDecoder()->setPage((m->parameter & 0xFFFF)); + ((PlayerLiveTV*)player)->getTeletextDecoder()->setPage((m->parameter.num & 0xFFFF)); } break; }; if (vas) { @@ -1112,7 +1112,7 @@ void VVideoLiveTV::processMessage(Message* m) } else if (m->message == Message::PLAYER_EVENT) { - switch(m->parameter) + switch (m->parameter.num) { case PlayerLiveTV::CONNECTION_LOST: // connection lost detected { diff --git a/vvideorec.cc b/vvideorec.cc index 1aee6d4..3cc7c9d 100644 --- a/vvideorec.cc +++ b/vvideorec.cc @@ -137,6 +137,8 @@ VVideoRec::VVideoRec(Recording* rec, bool ish264) vdisplay.y=0; vdisplay.width=0; vdisplay.height=0; + + lastbar = -1; } void VVideoRec::preDelete() @@ -221,7 +223,7 @@ void VVideoRec::go(bool resume) m = new Message(); m->message = Message::ADD_VIEW; m->to = boxstack; - m->parameter = (ULONG)vi; + m->parameter.num = (ULONG)vi; Command::getInstance()->postMessageNoLock(m); } } @@ -454,8 +456,8 @@ void VVideoRec::processMessage(Message* m) if (m->message == Message::MOUSE_LBDOWN) { - UINT x = (m->parameter>>16) - getScreenX(); - UINT y = (m->parameter&0xFFFF) - getScreenY(); + UINT x = (m->parameter.num>>16) - getScreenX(); + UINT y = (m->parameter.num&0xFFFF) - getScreenY(); if (!barShowing) { @@ -523,7 +525,7 @@ void VVideoRec::processMessage(Message* m) else if (m->from == player) { if (m->message != Message::PLAYER_EVENT) return; - switch(m->parameter) + switch(m->parameter.num) { case Player::CONNECTION_LOST: // connection lost detected { @@ -573,16 +575,16 @@ void VVideoRec::processMessage(Message* m) } else if (m->message == Message::AUDIO_CHANGE_CHANNEL) { - Log::getInstance()->log("VVideoRec", Log::DEBUG, "Received change audio channel to %i", m->parameter); - player->setAudioChannel(m->parameter&0xFFFF,(m->parameter&0xFF0000)>> 16,(m->parameter&0xFF000000)>> 24 ); + Log::getInstance()->log("VVideoRec", Log::DEBUG, "Received change audio channel to %i", m->parameter.num); + player->setAudioChannel(m->parameter.num&0xFFFF,(m->parameter.num&0xFF0000)>> 16,(m->parameter.num&0xFF000000)>> 24 ); } else if (m->message == Message::SUBTITLE_CHANGE_CHANNEL) { - Log::getInstance()->log("VVideoRec", Log::DEBUG, "Received change subtitle channel to %i", m->parameter); - int type=((m->parameter & 0xFF0000)>>16); + Log::getInstance()->log("VVideoRec", Log::DEBUG, "Received change subtitle channel to %i", m->parameter.num); + int type=((m->parameter.num & 0xFF0000)>>16); switch (type) { case 0x10: { //dvbsubtitle - player->setSubtitleChannel((m->parameter & 0xFFFF)); + player->setSubtitleChannel((m->parameter.num & 0xFFFF)); player->turnSubtitlesOn(true); VTeletextView *vtxt=((Player*)player)->getTeletextDecoder()->getTeletxtView(); if (vtxt && vtxt->isInSubtitleMode()) { @@ -601,7 +603,7 @@ void VVideoRec::processMessage(Message* m) case 0x11: { //videotext player->turnSubtitlesOn(false); doTeletext(); - ((Player*)player)->getTeletextDecoder()->setPage((m->parameter & 0xFFFF)); + ((Player*)player)->getTeletextDecoder()->setPage((m->parameter.num & 0xFFFF)); } break; }; if (vas) { @@ -791,12 +793,20 @@ void VVideoRec::doAudioSelector() boxstack->update(vas); } -void VVideoRec::doBar(int action) +void VVideoRec::doBar(int action_in) { if (player->isSubtitlesOn()) clearOSD(); // remove dvbsubtitles player->tellSubtitlesOSDVisible(true); barShowing = true; + int action = action_in; + if (action == -1) { + action = lastbar; + } + else { + lastbar = action; + } + rectangle(barRegion, barBlue); /* Work out what to display - choices: @@ -857,15 +867,17 @@ void VVideoRec::doBar(int action) boxstack->update(this, &barRegion); - timers->cancelTimer(this, 1); + if (action_in != -1) { + timers->cancelTimer(this, 1); - if ((playerState == Player::S_FFWD) || (playerState == Player::S_FBWD)) barScanHold = true; - else barScanHold = false; + if ((playerState == Player::S_FFWD) || (playerState == Player::S_FBWD)) barScanHold = true; + else barScanHold = false; - if (!barGenHold && !barScanHold && !barVasHold) timers->setTimerD(this, 1, 4); + if (!barGenHold && !barScanHold && !barVasHold) timers->setTimerD(this, 1, 4); - timers->setTimerD(this, 2, 0, 200000000); + timers->setTimerD(this, 2, 0, 200000000); + } } void VVideoRec::timercall(int clientReference) @@ -882,9 +894,12 @@ void VVideoRec::timercall(int clientReference) { // Update clock if (!barShowing) break; +#ifndef GRADIENT_DRAWING drawBarClocks(); boxstack->update(this, &barRegion); - +#else + doBar(-1); +#endif timers->setTimerD(this, 2, 0, 200000000); break; } @@ -930,7 +945,9 @@ void VVideoRec::drawBarClocks() // Draw RTC // Blank the area first +#ifndef GRADIENT_DRAWING rectangle(barRegion.x + 624, barRegion.y + 12, 60, 30, barBlue); +#endif char timeString[20]; time_t t; time(&t); @@ -939,8 +956,9 @@ void VVideoRec::drawBarClocks() drawText(timeString, barRegion.x + 624, barRegion.y + 12, DrawStyle::LIGHTTEXT); // Draw clocks - +#ifndef GRADIENT_DRAWING rectangle(clocksRegion, barBlue); +#endif ULONG currentFrameNum = player->getCurrentFrameNum(); ULONG lengthFrames; diff --git a/vvideorec.h b/vvideorec.h index 6620c20..66d0121 100644 --- a/vvideorec.h +++ b/vvideorec.h @@ -105,6 +105,8 @@ class VVideoRec : public Boxx, public TimerReceiver, public OSDReceiver UINT startMargin; UINT endMargin; + + int lastbar; #ifdef PAL_WSS Wwss wss; Region wssRegion; diff --git a/vwelcome.cc b/vwelcome.cc index 6168bef..733a47d 100644 --- a/vwelcome.cc +++ b/vwelcome.cc @@ -61,7 +61,7 @@ VWelcome::VWelcome() setPosition(130, 140); } #else - setSize(460, 240); + setSize(460, 280); createBuffer(); setPosition(140, 150); #endif @@ -93,7 +93,7 @@ VWelcome::VWelcome() sl.addColumn(0); sl.addColumn(25); sl.setLinesPerOption(1.5f); - sl.setSize(200, 200); + sl.setSize(200, 230); #else sl.setSize(200, 160); #endif @@ -396,7 +396,7 @@ void VWelcome::processMessage(Message* m) { if (m->message == Message::MOUSE_MOVE) { - if (sl.mouseMove((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseMove((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { sl.draw(); boxstack->update(this); @@ -404,7 +404,7 @@ void VWelcome::processMessage(Message* m) } else if (m->message == Message::MOUSE_LBDOWN) { - if (sl.mouseLBDOWN((m->parameter>>16)-getScreenX(),(m->parameter&0xFFFF)-getScreenY())) + if (sl.mouseLBDOWN((m->parameter.num>>16)-getScreenX(),(m->parameter.num&0xFFFF)-getScreenY())) { boxstack->handleCommand(Remote::OK); //simulate OK press } diff --git a/windowsosd.cc b/windowsosd.cc index 86ec942..e01668f 100644 --- a/windowsosd.cc +++ b/windowsosd.cc @@ -24,9 +24,8 @@ #include "video.h" #include "videowin.h" #include "log.h" +#include "colour.h" -#define BACKBUFFER_WIDTH 1920 -#define BACKBUFFER_HEIGHT 1080 typedef HRESULT(__stdcall *FCT_DXVA2CreateDirect3DDeviceManager9)(UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager); typedef HRESULT(__stdcall *FCT_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample); @@ -120,12 +119,22 @@ int WindowsOsd::createDirect3D9Objects() { Video* video = Video::getInstance(); //First Create Direct 3D Object +#ifdef WINDOWS_LEGACY d3d = Direct3DCreate9(D3D_SDK_VERSION); if (!d3d) { Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 object!"); return 0; } +#else + HRESULT err = Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d); + if (err != S_OK) + { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9Ex object! %d",err); + return 0; + } +#endif + // then create the Device D3DPRESENT_PARAMETERS d3dparas; ZeroMemory(&d3dparas, sizeof(d3dparas)); @@ -133,11 +142,19 @@ int WindowsOsd::createDirect3D9Objects() d3dparas.BackBufferHeight = BACKBUFFER_HEIGHT; d3dparas.Windowed = TRUE; d3dparas.SwapEffect = D3DSWAPEFFECT_COPY; +#ifdef WINDOWS_LEGACY if (d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dparas, &d3ddevice) != D3D_OK) { Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 device!"); return 0; } +#else + if (d3d->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dparas, NULL, &d3ddevice) != D3D_OK) { + Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 device!"); + return 0; + } +#endif d3ddevice->GetRenderTarget(0, &d3drtsurf); /* @@ -193,6 +210,11 @@ void WindowsOsd::startRenderLoop() threadStart(); } +void WindowsOsd::stopRenderLoop() +{ + threadStop(); +} + void WindowsOsd::shutdownDirect3D9Objects() { threadStop(); @@ -298,8 +320,9 @@ void WindowsOsd::Render() if (external_driving) { DWORD time1 = timeGetTime(); //Updates the Menue if ((time1 - lastrendertime)>200) {//5 fps for OSD updates are enough, avoids tearing + updateOsd(); InternalRendering(NULL); - lastrendertime = timeGetTime(); + lastosdrendertime = lastrendertime = timeGetTime(); } else { //Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads @@ -308,8 +331,9 @@ void WindowsOsd::Render() else { DWORD time1 = timeGetTime(); if ((time1 - lastrendertime)>50) {//10 fps for OSD updates are enough, avoids tearing + updateOsd(); InternalRendering(NULL); - lastrendertime = timeGetTime(); + lastosdrendertime = lastrendertime = timeGetTime(); } else { //Sleep(5); @@ -325,6 +349,10 @@ void WindowsOsd::RenderDS(LPDIRECT3DSURFACE9 present){ InternalRendering(present); lastrendertime = timeGetTime(); } + if ((lastrendertime - lastosdrendertime) > 50) { + updateOsd(); + lastosdrendertime = timeGetTime(); + } } @@ -393,6 +421,25 @@ void WindowsOsd::InternalRendering(LPDIRECT3DSURFACE9 present){ D3DSURFACE_DESC targetdesc; targetsurf->GetDesc(&targetdesc); + d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + LPDIRECT3DVERTEXBUFFER9 vb2 = NULL; + vb2 = InitBackgroundVertexBuffer(targetdesc.Width, targetdesc.Height); + if (d3ddevice->BeginScene() == D3D_OK) { + d3ddevice->SetStreamSource(0, vb2, 0, sizeof(OSDVERTEX)); + d3ddevice->SetFVF(D3DFVF_OSDVERTEX); + d3ddevice->SetTexture(0, NULL); + + d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3ddevice->SetRenderState(D3DRS_LIGHTING, FALSE); + + d3ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); + d3ddevice->EndScene(); + } + + vb2->Release(); + if (external_driving) { //Copy video to Backbuffer if (present != NULL) { @@ -442,7 +489,8 @@ void WindowsOsd::InternalRendering(LPDIRECT3DSURFACE9 present){ destrect.bottom += destrect.top; break; } - d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + + D3DSURFACE_DESC surf_desc; present->GetDesc(&surf_desc);//for chop sides RECT sourcerect = { 0, 0, surf_desc.Width, surf_desc.Height }; @@ -457,18 +505,16 @@ void WindowsOsd::InternalRendering(LPDIRECT3DSURFACE9 present){ } } - else { - VideoWin* video = (VideoWin*)Video::getInstance(); - //Clear Background - if (!video->isVideoOn()) d3ddevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); - } - LPDIRECT3DVERTEXBUFFER9 vb = NULL; - vb = InitVertexBuffer(targetdesc.Width, targetdesc.Height); + + LPDIRECT3DVERTEXBUFFER9 vb1 = NULL; + vb1 = InitVertexBuffer(targetdesc.Width, targetdesc.Height); + //Drawing the OSD if (d3ddevice->BeginScene() == D3D_OK) { - d3ddevice->SetStreamSource(0, vb, 0, sizeof(OSDVERTEX)); + d3ddevice->SetStreamSource(0, vb1, 0, sizeof(OSDVERTEX)); d3ddevice->SetFVF(D3DFVF_OSDVERTEX); + d3ddevice->SetTexture(0, NULL); LPDIRECT3DTEXTURE9 osdtex = getNextOsdTexture(); d3ddevice->SetTexture(0, osdtex); //d3ddevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); @@ -505,7 +551,7 @@ void WindowsOsd::InternalRendering(LPDIRECT3DSURFACE9 present){ } - vb->Release(); + vb1->Release(); EndPainting(); @@ -558,10 +604,12 @@ bool WindowsOsd::DoLost(){ LPDIRECT3DVERTEXBUFFER9 WindowsOsd::InitVertexBuffer(DWORD width, DWORD height) { LPDIRECT3DVERTEXBUFFER9 ret = NULL; - Video* video = Video::getInstance(); - FLOAT texx = ((float)video->getScreenWidth()) / 1024.f; - FLOAT texy = ((float)video->getScreenHeight()) / 1024.f; + FLOAT texx; + FLOAT texy; + getTextureCoordinates(&texx, &texy); + D3DCOLOR osdcolor = D3DCOLOR_RGBA(255, 255, 255, 255); + OSDVERTEX osdvertices[4]; osdvertices[0].c = osdcolor; osdvertices[0].x = 0.f - 0.5f; osdvertices[0].y = 0.f - 0.5f; @@ -591,7 +639,65 @@ LPDIRECT3DVERTEXBUFFER9 WindowsOsd::InitVertexBuffer(DWORD width, DWORD height) osdvertices[3].u = 0.f; osdvertices[3].v = texy; - if (d3ddevice->CreateVertexBuffer(4 * sizeof(OSDVERTEX), 0, D3DFVF_OSDVERTEX, D3DPOOL_MANAGED, + if (d3ddevice->CreateVertexBuffer(4 * sizeof(OSDVERTEX), 0, D3DFVF_OSDVERTEX, D3DPOOL_DEFAULT, + &ret, NULL) != D3D_OK) { + return NULL; + } + void *pvertex = NULL; + if (ret->Lock(0, sizeof(osdvertices), &pvertex, 0) != D3D_OK) { + return NULL; + } + memcpy(pvertex, osdvertices, sizeof(osdvertices)); + ret->Unlock(); + return ret; +} + +LPDIRECT3DVERTEXBUFFER9 WindowsOsd::InitBackgroundVertexBuffer(DWORD width, DWORD height) +{ + LPDIRECT3DVERTEXBUFFER9 ret = NULL; + FLOAT texx; + FLOAT texy; + getTextureCoordinates(&texx, &texy); + + DrawStyle bg = DrawStyle::WALLPAPER; + if (bg.ft != DrawStyle::GradientLinear) { + bg.grad_col[0] = bg; + } + + + OSDVERTEX osdvertices[4]; + osdvertices[0].c = D3DCOLOR_RGBA(bg.red,bg.green,bg.blue,0xff); + osdvertices[0].x = 0.f - 0.5f; + osdvertices[0].y = 0.f - 0.5f; + osdvertices[0].z = 0.5f; + osdvertices[0].rhw = 1.f; + osdvertices[0].u = 0.f; + osdvertices[0].v = 0.f; + osdvertices[1].c = D3DCOLOR_RGBA(bg.red, bg.green, bg.blue, 0xff); + osdvertices[1].x = ((float)width) - 0.5f; + osdvertices[1].y = 0.f - 0.5f; + osdvertices[1].z = 0.5f; + osdvertices[1].u = texx; + osdvertices[1].v = 0.f; + osdvertices[1].rhw = 1.f; + osdvertices[2].c = D3DCOLOR_RGBA(bg.grad_col[0].red, bg.grad_col[0].green, + bg.grad_col[0].blue, 0xff); + osdvertices[2].x = ((float)width) - 0.5f; + osdvertices[2].y = ((float)height) - 0.5f; + osdvertices[2].z = 0.5f; + osdvertices[2].rhw = 1.f; + osdvertices[2].u = texx; + osdvertices[2].v = texy; + osdvertices[3].c = D3DCOLOR_RGBA(bg.grad_col[0].red, bg.grad_col[0].green, + bg.grad_col[0].blue, 0xff); + osdvertices[3].x = 0.f - 0.5f; + osdvertices[3].y = ((float)height) - 0.5f; + osdvertices[3].z = 0.5f; + osdvertices[3].rhw = 1.f; + osdvertices[3].u = 0.f; + osdvertices[3].v = texy; + + if (d3ddevice->CreateVertexBuffer(4 * sizeof(OSDVERTEX), 0, D3DFVF_OSDVERTEX, D3DPOOL_DEFAULT, &ret, NULL) != D3D_OK) { return NULL; } diff --git a/windowsosd.h b/windowsosd.h index 5f1e81e..ec93f7c 100644 --- a/windowsosd.h +++ b/windowsosd.h @@ -26,6 +26,9 @@ #include #include "threadwin.h" +#define BACKBUFFER_WIDTH 1920 +#define BACKBUFFER_HEIGHT 1080 + class DsAllocator; struct OSDVERTEX @@ -85,25 +88,35 @@ protected: int createDirect3D9Objects(); void shutdownDirect3D9Objects(); void startRenderLoop(); + void stopRenderLoop(); void InternalRendering(LPDIRECT3DSURFACE9 present); bool DoLost(); virtual void lostDestroyObjects()=0; virtual void lostRecreateObjects()=0; + virtual void getTextureCoordinates(FLOAT*, FLOAT*)=0; + + virtual void updateOsd() {}; + void LockDevice(); void UnlockDevice(); virtual LPDIRECT3DTEXTURE9 getNextOsdTexture()=0; LPDIRECT3DVERTEXBUFFER9 InitVertexBuffer(DWORD width, DWORD height); - OSDVERTEX osdvertices[4]; + LPDIRECT3DVERTEXBUFFER9 InitBackgroundVertexBuffer(DWORD width, DWORD height); + bool evrsupported; EVR_state evrstate; D3DTEXTUREFILTERTYPE filter_type; - +#ifdef WINDOWS_LEGACY LPDIRECT3D9 d3d; LPDIRECT3DDEVICE9 d3ddevice; +#else + LPDIRECT3D9EX d3d; + LPDIRECT3DDEVICE9EX d3ddevice; +#endif LPDIRECT3DSWAPCHAIN9 swappy; LPDIRECT3DSURFACE9 swapsurf; LPDIRECT3DSURFACE9 d3drtsurf; @@ -118,6 +131,7 @@ protected: HANDLE d3dmutex; HANDLE event; DWORD lastrendertime; + DWORD lastosdrendertime; HWND window; }; diff --git a/winmain.cc b/winmain.cc index be754e5..651b83f 100644 --- a/winmain.cc +++ b/winmain.cc @@ -39,10 +39,10 @@ #include "audiowin.h" #include "vdr.h" #include "windowsosd.h" -#ifndef GRADIENT_DRAWING +#ifdef WINDOWS_LEGACY #include "osdwinpixel.h" #else - +#include "osdwinvector.h" #endif #include "boxstack.h" #include "command.h" @@ -279,6 +279,7 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd WSACleanup(); return 0; } + video->setDefaultAspect(); success = audio->init(Audio::MPEG2_PES); if (success) @@ -700,7 +701,7 @@ LONG FAR PASCAL WindowProc(HWND wind, UINT msg, WPARAM wparam, LPARAM lparam) mousemes->message=Message::MOUSE_MOVE; mousemes->from=NULL; mousemes->to=BoxStack::getInstance(); - mousemes->parameter=(mpos.x & 0xFFFF)<< 16| (mpos.y & 0xFFFF); + mousemes->parameter.num=(mpos.x & 0xFFFF)<< 16| (mpos.y & 0xFFFF); mousemes->tag=0; //command->postMessageFromOuterSpace(mousemes); command->postMessageIfNotBusy(mousemes); @@ -733,7 +734,7 @@ LONG FAR PASCAL WindowProc(HWND wind, UINT msg, WPARAM wparam, LPARAM lparam) mousemes->message=Message::MOUSE_LBDOWN; mousemes->from=NULL; mousemes->to=BoxStack::getInstance(); - mousemes->parameter=(mpos.x & 0xFFFF)<< 16| (mpos.y & 0xFFFF); + mousemes->parameter.num=(mpos.x & 0xFFFF)<< 16| (mpos.y & 0xFFFF); mousemes->tag=0; command->postMessageFromOuterSpace(mousemes); } @@ -746,7 +747,7 @@ LONG FAR PASCAL WindowProc(HWND wind, UINT msg, WPARAM wparam, LPARAM lparam) mousemes->message = Message::MOUSE_SCROLL; mousemes->from = NULL; mousemes->to = BoxStack::getInstance(); - mousemes->parameter = (0 & 0xFFFF) << 16 | (GET_WHEEL_DELTA_WPARAM(wparam) &0xFFFF); + mousemes->parameter.num = (0 & 0xFFFF) << 16 | (GET_WHEEL_DELTA_WPARAM(wparam) &0xFFFF); mousemes->tag = (mpos.x & 0xFFFF) << 16 | (mpos.y & 0xFFFF); command->postMessageFromOuterSpace(mousemes); } diff --git a/wpictureview.cc b/wpictureview.cc index 5418a2d..55a81f2 100644 --- a/wpictureview.cc +++ b/wpictureview.cc @@ -190,6 +190,29 @@ int WPictureView::handleCommand(int command) return 0; } + +bool WPictureView::mouseAndroidScroll(int x, int y, int sx, int sy) +{ + if ((x - getRootBoxOffsetX()) >= 0 && (y - getRootBoxOffsetY()) >= 0 + && (x - getRootBoxOffsetX()) <= (int)area.w && (y - getRootBoxOffsetY()) <= (int)area.h) + { + int change = -sy / 120; + if (change < 0) { + int rel_change = min(cur_scroll_line, -change); + cur_scroll_line -= rel_change; + rem_scroll_line += rel_change; + } + else if (change > 0) { + int rel_change = min(rem_scroll_line, change); + cur_scroll_line += rel_change; + rem_scroll_line -= rel_change; + } + return true; + } + return false; + +} + WActorGallery::WActorGallery(Actors& actors) { Actors::iterator itty=actors.begin(); diff --git a/wpictureview.h b/wpictureview.h index 272299a..04a32c7 100644 --- a/wpictureview.h +++ b/wpictureview.h @@ -43,6 +43,7 @@ class WPictureView : public Boxx // if added as a pane int handleCommand(int command); + bool mouseAndroidScroll(int x, int y, int sx, int sy); protected: class Picture { diff --git a/wselectlist.cc b/wselectlist.cc index 94bfc63..5d41ea0 100644 --- a/wselectlist.cc +++ b/wselectlist.cc @@ -320,7 +320,7 @@ bool WSelectList::mouseLBDOWN(int x, int y) int WSelectList::getMouseLine(int x,int y) { int fontHeight = getFontHeight(); - int ySeperation = fontHeight + gap; + int ySeperation = fontHeight * linesPerOption + gap; if (y<0) return -1; if (x<0 || x>(int)area.w) return -1; -- 2.39.2