diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | css/styles.css | 62 | ||||
-rw-r--r-- | osd_status.cpp | 167 | ||||
-rw-r--r-- | osd_status.h | 84 | ||||
-rw-r--r-- | pages/Makefile | 2 | ||||
-rw-r--r-- | pages/osd.ecpp | 26 | ||||
-rw-r--r-- | pages/remote.ecpp | 207 |
7 files changed, 503 insertions, 47 deletions
@@ -73,7 +73,7 @@ VERSIONSUFFIX = gen_version_suffix.h PLUGINOBJS := $(PLUGIN).o thread.o tntconfig.o setup.o i18n.o timers.o \ tools.o recman.o tasks.o status.o epg_events.o epgsearch.o \ grab.o md5.o filecache.o livefeatures.o preload.o timerconflict.o \ - users.o + users.o osd_status.o PLUGINSRCS := $(patsubst %.o,%.cpp,$(PLUGINOBJS)) WEB_LIB_PAGES := libpages.a diff --git a/css/styles.css b/css/styles.css index cef24b3..d32e935 100644 --- a/css/styles.css +++ b/css/styles.css @@ -1065,6 +1065,68 @@ div.screenshot img { height: 320px; } + +/* ############################## + # Remote page - OSD + ############################## +*/ + +#osd { + background-color:black; + color:white; + height: 320px; + width: 569px; +} +.osd { + padding: 5px 0px 5px 10px; + position:relative; +} +.osd div { + margin:0px; + tab-size:4; + font-family: "Courier New", Courier, monospace; +} +.osdMessage { + position:absolute; + overflow:auto; + top:250px; + max-height: 100px; + min-height:20px; + width: 510px; + background-color:yellow; + color:black; + padding:10px; + border:2px solid red; +} +.osdText, .osdItems { + overflow:auto; + overflow-x:hidden; + height: 267px; + width: 555px; + margin:5px 0px !important; +} +.osdItem, .osdTitle { + cursor:pointer; + white-space: nowrap; +} +.osdItem.selected { + background-color:#cccccc; + color:#000000; +} +.osdButtons {} +.osdButtons div { + float:left; + margin-right:5px; + padding:2px; + width:130px; + text-align: center; + cursor:pointer; +} +.osdButtonGreen {background-color:green} +.osdButtonYellow {background-color:yellow;color:black} +.osdButtonBlue {background-color:blue} +.osdButtonRed {background-color:red} + /* ############################## # Error widget diff --git a/osd_status.cpp b/osd_status.cpp new file mode 100644 index 0000000..a6791ab --- /dev/null +++ b/osd_status.cpp @@ -0,0 +1,167 @@ +#include <string> +#include <sstream> +#include "osd_status.h" + +namespace vdrlive { + +OsdStatusMonitor::OsdStatusMonitor():title(),message(),red(),green(),yellow(),blue(),text(),selected(-1),lastUpdate(0){ + memset(&tabs, 0, sizeof(tabs)); +} +OsdStatusMonitor::~OsdStatusMonitor() { + OsdClear(); +} + +void OsdStatusMonitor::OsdClear() { + title = message = text = ""; + red = green = yellow = blue = ""; + items.Clear(); + selected = -1; + memset(&tabs, 0, sizeof(tabs)); + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdTitle(const char *Title) { + title = Title ? Title : ""; + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdStatusMessage(const char *Message) { + message = Message ? Message : ""; + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue) { + red = Red ? Red :""; + green = Green ? Green : ""; + yellow = Yellow ? Yellow : ""; + blue = Blue ? Blue : ""; + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdItem(const char *Text, int Index) { + const char* tab; + const char* colStart = Text; + for (int col = 0; col < MaxTabs && + (tab = strchr(colStart, '\t')); col++) { + int width = tab - colStart + 1; + if (width > tabs[col]) + tabs[col] = width; + colStart = colStart + width; + } + items.Add(new cLiveOsdItem(Text)); + lastUpdate= clock(); +} + +void OsdStatusMonitor::OsdCurrentItem(const char *Text) { + int i = -1; + int best = -1; + int dist = items.Count(); + cLiveOsdItem * currentItem = NULL; + cLiveOsdItem *bestItem = NULL; + for (cLiveOsdItem *item = items.First(); item; item = items.Next(item)) { + if (++i == selected) + currentItem = item; + if ( item->Text().compare(Text) == 0) { + if (abs(i - selected) < dist) { + // best match is the one closest to previous position + best = i; + bestItem= item; + dist = abs(i - selected); + } + else if (selected < 0) { + // previous position unknown - take first match + best = i; + bestItem= item; + break; + } + else { + // we already have a better match, so we're done + break; + } + } + } + if (best >= 0) { + // found matching item + selected = best; + bestItem->Select(true); + if (currentItem && currentItem != bestItem){ + currentItem->Select(false); + lastUpdate= clock(); + } + } + else if (currentItem) { + // no match: the same item is still selected but its text changed + currentItem->Update(Text); + lastUpdate= clock(); + } +} + +void OsdStatusMonitor::OsdTextItem(const char *Text, bool Scroll) { + if (Text) { + text = Text; + //text= text.replace( text.begin(), text.end(), '\n', '|'); + } + else { + text = ""; + } + lastUpdate= clock(); +} +std::string const OsdStatusMonitor::GetTitleHtml() {return !title.empty() ? "<div class=\"osdTitle\">" + EncodeHtml(title) + "</div>" : "";} +std::string const OsdStatusMonitor::GetMessageHtml() {return !message.empty() ? "<div class=\"osdMessage\">" + EncodeHtml(message) + "</div>" : "";} +std::string const OsdStatusMonitor::GetRedHtml() {return !red.empty() ? "<div class=\"osdButtonRed\">" + EncodeHtml(red) + "</div>" : "";} +std::string const OsdStatusMonitor::GetGreenHtml() {return !green.empty() ? "<div class=\"osdButtonGreen\">" + EncodeHtml(green) + "</div>" : "";} +std::string const OsdStatusMonitor::GetYellowHtml() {return !yellow.empty() ? "<div class=\"osdButtonYellow\">" + EncodeHtml(yellow) + "</div>" : "";} +std::string const OsdStatusMonitor::GetBlueHtml() {return !blue.empty() ? "<div class=\"osdButtonBlue\">" + EncodeHtml(blue) + "</div>" : "";} +std::string const OsdStatusMonitor::GetTextHtml() {return !text.empty() ? "<div class=\"osdText\">" + EncodeHtml(text) + "</div>" : "";} +std::string const OsdStatusMonitor::GetButtonsHtml() { + std::string buffer= GetRedHtml() + GetGreenHtml() + GetYellowHtml() + GetBlueHtml(); + return !buffer.empty() ? "<div class=\"osdButtons\">" + buffer + "</div>" : ""; +} + +std::string const OsdStatusMonitor::GetItemsHtml(void){ + std::string buffer= ""; + for (cLiveOsdItem *item = items.First(); item; item = items.Next(item)) { + buffer += "<div class=\"osdItem"; + if (item->isSelected()) + buffer += " selected"; + buffer += "\">"; + buffer += EncodeHtml(item->Text()); + buffer += "</div>"; + } + return !buffer.empty() ? "<div class=\"osdItems\">" + buffer + "</div>" : ""; +} +std::string const OsdStatusMonitor::GetHtml(){ + std::stringstream mystream; + mystream << lastUpdate; + return "<div class=\"osd\" data-time=\"" + mystream.str() + "\">" + GetTitleHtml() + GetItemsHtml() + GetTextHtml() + GetMessageHtml() + GetButtonsHtml() + "</div>"; +} + +std::string const OsdStatusMonitor::EncodeHtml(const std::string& html) { + std::ostringstream result; + std::string::const_iterator i; + for (i = html.begin(); i != html.end(); ++i) { + if (*i >= 128) + result << "&#" << static_cast<int>(*i) << ";"; + else if (*i == '<') + result << "<"; + else if (*i == '>') + result << ">"; + else if (*i == '&') + result << "&"; + else if (*i == '"') + result << """; + else + result << static_cast<char>(*i); // Copy untranslated + } + return result.str(); +} + + + +OsdStatusMonitor& LiveOsdStatusMonitor() +{ + static OsdStatusMonitor instance; + return instance; +} + +} // namespace vdrlive diff --git a/osd_status.h b/osd_status.h new file mode 100644 index 0000000..f84b1ef --- /dev/null +++ b/osd_status.h @@ -0,0 +1,84 @@ +#ifndef VDR_LIVE_OSD_STATUS_H +#define VDR_LIVE_OSD_STATUS_H + +#include <string> +#include <vdr/status.h> +#include <time.h> + +namespace vdrlive { + +class cLiveOsdItem: public cListObject { + private: + std::string text; + bool selected; + public: + std::string Text() const { return text; } + int isSelected() const {return selected;} + void Select(const bool doSelect) { selected= doSelect; }; + void Update(const char* Text) { text = Text ? Text : ""; }; + cLiveOsdItem(const char* Text):text(),selected(false) { text = Text ? Text : ""; }; + ~cLiveOsdItem() { } +}; + +class OsdStatusMonitor: public cStatus +{ + friend OsdStatusMonitor& LiveOsdStatusMonitor(); +public: + enum { MaxTabs = 6 }; +private: + OsdStatusMonitor(); + OsdStatusMonitor( OsdStatusMonitor const& ); + + std::string title; + std::string message; + std::string red; + std::string green; + std::string yellow; + std::string blue; + std::string text; + int selected; + cList<cLiveOsdItem> items; + unsigned short tabs[MaxTabs]; + clock_t lastUpdate; + +protected: +// static void append(char *&tail, char type, const char *src, int max); +public: + + std::string const GetTitle() const {return title;} + std::string const GetMessage() const {return message;} + std::string const GetRed() const {return red;} + std::string const GetGreen() const {return green;} + std::string const GetYellow() const {return yellow;} + std::string const GetBlue() const {return blue;} + std::string const GetText() const {return text;} + + virtual std::string const GetHtml(); + virtual std::string const GetTitleHtml(); + virtual std::string const GetMessageHtml(); + virtual std::string const GetRedHtml(); + virtual std::string const GetGreenHtml(); + virtual std::string const GetYellowHtml(); + virtual std::string const GetBlueHtml(); + virtual std::string const GetTextHtml(); + virtual std::string const GetButtonsHtml(); + virtual std::string const GetItemsHtml(); + + virtual void OsdClear(); + virtual void OsdTitle(const char *Title); + virtual void OsdStatusMessage(const char *Message); + virtual void OsdHelpKeys(const char *Red, const char *Green, const char *Yellow, const char *Blue); + virtual void OsdTextItem(const char *Text, bool Scroll); + virtual void OsdItem(const char *Text, int Index); + virtual void OsdCurrentItem(const char *Text); + + virtual ~OsdStatusMonitor(); + + std::string const EncodeHtml(const std::string& html); +}; + +OsdStatusMonitor& LiveOsdStatusMonitor(); + +} // namespace vdrlive + +#endif // VDR_LIVE_STATUS_H diff --git a/pages/Makefile b/pages/Makefile index 1e56731..cfe482c 100644 --- a/pages/Makefile +++ b/pages/Makefile @@ -15,7 +15,7 @@ OBJS := menu.o recordings.o schedule.o multischedule.o screenshot.o \ searchepg.o login.o ibox.o xmlresponse.o play_recording.o \ pause_recording.o stop_recording.o ffw_recording.o \ rwd_recording.o setup.o content.o epginfo.o timerconflicts.o \ - recstream.o users.o edit_user.o edit_recording.o + recstream.o users.o edit_user.o edit_recording.o osd.o SRCS := $(patsubst %.o,%.cpp,$(OBJS)) ESRCS := $(patsubst %.o,%.ecpp,$(OBJS)) diff --git a/pages/osd.ecpp b/pages/osd.ecpp new file mode 100644 index 0000000..b7cf24a --- /dev/null +++ b/pages/osd.ecpp @@ -0,0 +1,26 @@ +<%pre> +#include <locale> +#include <vdr/i18n.h> +#include <vdr/keys.h> +#include <vdr/device.h> +#include "grab.h" +#include "setup.h" +#include "tools.h" +#include "users.h" +#include "osd_status.h" + +using namespace std; +using namespace vdrlive; + +</%pre><?xml version="1.0" encoding="utf-8"?> +<%session scope="global"> +bool logged_in(false); +</%session> +<%request scope="page"> +</%request> +<%cpp> +if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); +reply.setContentType( "application/xml" ); + +reply.out() << LiveOsdStatusMonitor().GetHtml(); +</%cpp> diff --git a/pages/remote.ecpp b/pages/remote.ecpp index 8dc4703..d76b208 100644 --- a/pages/remote.ecpp +++ b/pages/remote.ecpp @@ -74,12 +74,60 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <& pageelems.stylesheets &> <& pageelems.ajax_js &> <script type="text/javascript"><!-- - var newImg = new Image(); + var newImg = null; var imgsrc = ""; + var osdAjax = null; + var osdTimeout = -1; var interval = -1; + var clkTimer; + + function changeScreenContent(){ + var screenCon= document.getElementsByName('screenCon'); + for ( var i=0; i < screenCon.length; i++){ + if (screenCon[i].id == 'screenCon_grab'){ + if (screenCon[i].checked){ + newImg = new Image(); + StreamLoad(); + ChangeInterval(); + StreamLoad(); + document.images.vdrlive.style.display= ''; + } else { + window.clearInterval(interval); + document.images.vdrlive.style.display= 'none'; + newImg = null; + } + } else if (screenCon[i].id == 'screenCon_osd'){ + if (screenCon[i].checked){ + osdAjax= new Ajax('osd.xml', {method: 'get'}); + osdAjax.lastUpd= -1; + osdAjax.addEvent('onComplete', function(text,xmlDoc){ + try{ + var upd= parseInt(xmlDoc.firstChild.getAttribute("data-time"),10); + if ( osdAjax.lastUpd != upd ){ + $('osd').empty().setHTML(text); + osdAjax.lastUpd = upd; + $$('#screenshot .osdItems')[0].scrollTop= $$('#screenshot .selected')[0].offsetTop - 40; + } + } catch (e) {} + window.clearInterval(osdTimeout); + osdTimeout= window.setTimeout("OSDLoad()",1000); + }); + $('osd').style.display= ''; + + OSDLoad() + } else { + $('osd').style.display= 'none'; + osdAjax= null; + } + } + } + + } function StreamLoad() { + if (!newImg) + return; uniq = new Date(); uniq = uniq.getTime(); document.images.vdrlive.src=newImg.src; @@ -88,11 +136,24 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); function StreamInit() { - imgsrc = document.images.vdrlive.src; - uniq = new Date(); - uniq = uniq.getTime(); - newImg.src=imgsrc+"?"+uniq; - interval = window.setInterval("StreamLoad()", 1000); + document.getElementsByName('screenCon')[0].checked= true; + if (document.images.vdrlive) + imgsrc = document.images.vdrlive.src; + FillIntervals(); + changeScreenContent(); + $('osd').addEvents({ + 'click': function(ev){ + $clear(clkTimer); + clkTimer = (function(){ + handleOSD(ev.target, false); + }).delay(200, this); + }, + 'dblclick': function(ev){ + $clear(clkTimer); + handleOSD(ev.target, true); + } + }); + } function ChangeInterval() @@ -103,14 +164,66 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); interval = window.setInterval("StreamLoad()", timeout); } - function KeyPress(keycode) + function OSDLoad(){ + if (osdAjax) + osdAjax.request(); + } + function handleOSD(elem, doEnter){ + switch (elem.className){ + case 'osdButtonRed': + return KeyPress(<$ kRed $>); + case 'osdButtonGreen': + return KeyPress(<$ kGreen $>); + case 'osdButtonYellow': + return KeyPress(<$ kYellow $>); + case 'osdButtonBlue': + return KeyPress(<$ kBlue $>); + case 'osdTitle': + return KeyPress(<$ kBack $>); + case 'osdItem': + var hits= 0, + cur= elem, + keycode= <$ kDown $>; + while (cur && cur.className.indexOf('selected') == -1 ){ + cur= cur.previousSibling; + hits++; + }; + if ( !cur){ + hits= 0; + cur= elem; + keycode= <$ kUp $>; + while (cur && cur.className.indexOf('selected') == -1 ){ + cur= cur.nextSibling; + hits++; + }; + } + for(;hits > 0; hits--) + KeyPress(keycode, true); + if ( !doEnter){ + OSDLoad(); + return false; + } + case 'osdItem selected': + return KeyPress(<$ kOk $>); + } + return true; + } + + function KeyPress(keycode,DonotLoadOSD) { - LiveSimpleAjaxRequest('keypress.xml', 'keycode', keycode); +// LiveSimpleAjaxRequest('keypress.xml', 'keycode', keycode); + var req = new Ajax('keypress.xml', { method : 'post'}); + if (!DonotLoadOSD && osdAjax) + req.addEvent('onComplete', OSDLoad); + req.request('keycode=' + keycode + '&async=1'); + return false; } function FillIntervals() { var element = document.getElementsByName('interval').item(0); + if (!element) + return; var items = new Array(1000, 2000, 5000); element.options.length = items.length; for (i = 0; i < items.length; ++i) { @@ -123,50 +236,49 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); //--></script> % reply.sout().imbue(locale()); </head> - <body onload="StreamInit(); FillIntervals();"> + <body onload="StreamInit();"> <& pageelems.logo &> <& menu active="remote" component=("remote.remote_actions")> <div class="inhalt"> - <div class="screenshot"> -<{ if (!LiveGrabImageManager().CanGrab()) { }> - bloek -<{ } else { }> - <img src="screenshot.jpg" name="vdrlive" /><br /> + <div class="screenshot" id="screenshot"> +<{ if (LiveGrabImageManager().CanGrab()) { }> + <img src="screenshot.jpg" name="vdrlive" /> <{ } }> + <div id="osd"></div> </div> <div> <img src="<$ LiveSetup().GetThemedLink("img", "remotecontrol.jpg") $>" width="162" height="378" border="0" usemap="#remote" alt="" /> <map name="remote"> - <area href="#" shape="circle" coords="37,36,10" alt="Power" onclick="KeyPress(<$ kPower $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="27,60,59,75" alt="1" onclick="KeyPress(<$ k1 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="64,59,98,75" alt="2" onclick="KeyPress(<$ k2 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="103,59,137,75" alt="3" onclick="KeyPress(<$ k3 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="25,82,60,98" alt="4" onclick="KeyPress(<$ k4 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="65,82,98,99" alt="5" onclick="KeyPress(<$ k5 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="103,83,137,99" alt="6" onclick="KeyPress(<$ k6 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="26,106,60,121" alt="7" onclick="KeyPress(<$ k7 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="65,105,97,121" alt="8" onclick="KeyPress(<$ k8 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="104,106,137,122" alt="9" onclick="KeyPress(<$ k9 $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="66,128,98,144" alt="0" onclick="KeyPress(<$ k0 $>)" nohref="nohref" alt="" /> - <area href="#" shape="circle" coords="37,157,13" alt="Vol+" onclick="KeyPress(<$ kVolUp $>)" nohref="nohref" alt="" /> - <area href="#" shape="circle" coords="37,190,13" alt="Vol-" onclick="KeyPress(<$ kVolDn $>)" nohref="nohref" alt="" /> - <area href="#" shape="circle" coords="125,157,13" alt="P+" onclick="KeyPress(<$ kChanUp $>)" nohref="nohref" alt="" /> - <area href="#" shape="circle" coords="125,190,13" alt="P-" onclick="KeyPress(<$ kChanDn $>)" nohref="nohref" alt="" /> - <area href="#" shape="circle" coords="81,174,8" alt="Mute" onclick="KeyPress(<$ kMute $>)" nohref="nohref" alt="" /> - <area href="#" shape="circle" coords="81,202,11" alt="Record" onclick="KeyPress(<$ kRecord $>)" nohref="nohref" alt="" /> - <area href="#" shape="poly" coords="39,215,29,227,30,235,39,236,51,222,49,215,43,213" alt="Menu" onclick="KeyPress(<$ kMenu $>)" nohref="nohref" alt="" /> - <area href="#" shape="poly" coords="119,213,127,219,135,230,132,235,127,236,119,231,114,223,113,215" alt="Exit" onclick="KeyPress(<$ kBack $>)" nohref="nohref" alt="" /> - <area href="#" shape="poly" coords="33,289,31,298,43,310,51,308,54,300,41,287" alt="Subtitles" onclick="KeyPress(<$ kSubtitles $>)" nohref="nohref" alt="" /> - <area href="#" shape="poly" coords="131,289,133,298,122,310,112,308,110,300,122,287" alt="Audio" onclick="KeyPress(<$ kAudio $>)" nohref="nohref" alt="" /> - <area href="#" shape="poly" coords="58,230,70,223,82,223,91,223,105,231,96,240,87,237,78,236,69,240,66,241,58,232" alt="Up" onclick="KeyPress(<$ kUp $>)" nohref="nohref" alt="" /> - <area href="#" shape="poly" coords="111,237,119,249,121,259,119,275,113,285,109,284,101,276,104,270,107,260,106,253,101,245" alt="Right" onclick="KeyPress(<$ kRight $>)" nohref="nohref" alt="" /> - <area href="#" shape="poly" coords="66,281,75,285,86,285,95,281,106,291,100,295,87,300,73,300,58,291,57,289,58,289" alt="Down" onclick="KeyPress(<$ kDown $>)" nohref="nohref" alt="" /> - <area href="#" shape="poly" coords="51,236,61,245,56,256,57,266,61,277,52,285,47,278,42,264,43,252,49,240" alt="Left" onclick="KeyPress(<$ kLeft $>)" nohref="nohref" alt="" /> - <area href="#" shape="circle" coords="81,261,17" alt="Ok" onclick="KeyPress(<$ kOk $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="25,324,52,339" alt="Red" onclick="KeyPress(<$ kRed $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="53,324,81,339" alt="Green" onclick="KeyPress(<$ kGreen $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="83,324,109,339" alt="Yellow" onclick="KeyPress(<$ kYellow $>)" nohref="nohref" alt="" /> - <area href="#" shape="rect" coords="110,324,137,339" alt="Blue" onclick="KeyPress(<$ kBlue $>)" nohref="nohref" alt="" /> + <area href="#" shape="circle" coords="37,36,10" alt="Power" onclick="return KeyPress(<$ kPower $>)" /> + <area href="#" shape="rect" coords="27,60,59,75" alt="1" onclick="return KeyPress(<$ k1 $>)" /> + <area href="#" shape="rect" coords="64,59,98,75" alt="2" onclick="return KeyPress(<$ k2 $>)" /> + <area href="#" shape="rect" coords="103,59,137,75" alt="3" onclick="return KeyPress(<$ k3 $>)" /> + <area href="#" shape="rect" coords="25,82,60,98" alt="4" onclick="return KeyPress(<$ k4 $>)" /> + <area href="#" shape="rect" coords="65,82,98,99" alt="5" onclick="return KeyPress(<$ k5 $>)" /> + <area href="#" shape="rect" coords="103,83,137,99" alt="6" onclick="return KeyPress(<$ k6 $>)" /> + <area href="#" shape="rect" coords="26,106,60,121" alt="7" onclick="return KeyPress(<$ k7 $>)" /> + <area href="#" shape="rect" coords="65,105,97,121" alt="8" onclick="return KeyPress(<$ k8 $>)" /> + <area href="#" shape="rect" coords="104,106,137,122" alt="9" onclick="return KeyPress(<$ k9 $>)" /> + <area href="#" shape="rect" coords="66,128,98,144" alt="0" onclick="return KeyPress(<$ k0 $>)" /> + <area href="#" shape="circle" coords="37,157,13" alt="Vol+" onclick="return KeyPress(<$ kVolUp $>)" /> + <area href="#" shape="circle" coords="37,190,13" alt="Vol-" onclick="return KeyPress(<$ kVolDn $>)" /> + <area href="#" shape="circle" coords="125,157,13" alt="P+" onclick="return KeyPress(<$ kChanUp $>)" /> + <area href="#" shape="circle" coords="125,190,13" alt="P-" onclick="return KeyPress(<$ kChanDn $>)" /> + <area href="#" shape="circle" coords="81,174,8" alt="Mute" onclick="return KeyPress(<$ kMute $>)" /> + <area href="#" shape="circle" coords="81,202,11" alt="Record" onclick="return KeyPress(<$ kRecord $>)" /> + <area href="#" shape="poly" coords="39,215,29,227,30,235,39,236,51,222,49,215,43,213" alt="Menu" onclick="return KeyPress(<$ kMenu $>)" /> + <area href="#" shape="poly" coords="119,213,127,219,135,230,132,235,127,236,119,231,114,223,113,215" alt="Exit" onclick="return KeyPress(<$ kBack $>)" /> + <area href="#" shape="poly" coords="33,289,31,298,43,310,51,308,54,300,41,287" alt="Subtitles" onclick="return KeyPress(<$ kSubtitles $>)" /> + <area href="#" shape="poly" coords="131,289,133,298,122,310,112,308,110,300,122,287" alt="Audio" onclick="return KeyPress(<$ kAudio $>)" /> + <area href="#" shape="poly" coords="58,230,70,223,82,223,91,223,105,231,96,240,87,237,78,236,69,240,66,241,58,232" alt="Up" onclick="return KeyPress(<$ kUp $>)" /> + <area href="#" shape="poly" coords="111,237,119,249,121,259,119,275,113,285,109,284,101,276,104,270,107,260,106,253,101,245" alt="Right" onclick="return KeyPress(<$ kRight $>)" /> + <area href="#" shape="poly" coords="66,281,75,285,86,285,95,281,106,291,100,295,87,300,73,300,58,291,57,289,58,289" alt="Down" onclick="return KeyPress(<$ kDown $>)" /> + <area href="#" shape="poly" coords="51,236,61,245,56,256,57,266,61,277,52,285,47,278,42,264,43,252,49,240" alt="Left" onclick="return KeyPress(<$ kLeft $>)" /> + <area href="#" shape="circle" coords="81,261,17" alt="Ok" onclick="return KeyPress(<$ kOk $>)" /> + <area href="#" shape="rect" coords="25,324,52,339" alt="Red" onclick="return KeyPress(<$ kRed $>)" /> + <area href="#" shape="rect" coords="53,324,81,339" alt="Green" onclick="return KeyPress(<$ kGreen $>)" /> + <area href="#" shape="rect" coords="83,324,109,339" alt="Yellow" onclick="return KeyPress(<$ kYellow $>)" /> + <area href="#" shape="rect" coords="110,324,137,339" alt="Blue" onclick="return KeyPress(<$ kBlue $>)" /> </map> </div> </div> @@ -175,5 +287,10 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); <%include>page_exit.eh</%include> <%def remote_actions> -<$ tr("Snapshot interval") $>: <select name="interval" onchange="ChangeInterval()"></select> <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &> +<b><$ tr("Selection") $></b>: +<{ if ( LiveGrabImageManager().CanGrab()) { }> + <input type="radio" name="screenCon" id="screenCon_grab" onchange="changeScreenContent()"/> <label for="screenCon_grab"><$ tr("Snapshot interval") $>:</label> <select name="interval" onchange="ChangeInterval()"></select> <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &> - +<{ } }> + <input type="radio" name="screenCon" id="screenCon_osd" onchange="changeScreenContent()" /> <label for="screenCon_osd">OSD</label> - + <input type="radio" name="screenCon" id="screenCon_none" onchange="changeScreenContent()" /> <label for="screenCon_osd"><$ tr("Stop") $></label> </%def> |