Permalink
Browse files

Add a simple http/html 'remote control' to the frontend.

To test, point your browser at http://frontend-ip:6547/MythFE/GetRemote

This is probably nothing more than a proof of concept at the moment and
has certain limitations around translations and responsiveness on
smartphone interfaces (well, on my iPhone anyway!).

It should hopefully prove useful as an inspiration for others to get
busy with some more interesting versions and as a test interface into
the frontend for those trying to debug lirc or other input issues.
  • Loading branch information...
1 parent 94b71c9 commit 5e5e2dde0f87af8731c1b3c985324a1b709da116 Mark Kendall committed Feb 14, 2011
Showing with 86 additions and 19 deletions.
  1. +84 −19 mythtv/programs/mythfrontend/mythfexml.cpp
  2. +2 −0 mythtv/programs/mythfrontend/mythfexml.h
@@ -63,6 +63,7 @@ MythFEXMLMethod MythFEXML::GetMethod(const QString &sURI)
if (sURI == "SendAction") return MFEXML_Action;
if (sURI == "GetActionList") return MFEXML_ActionList;
if (sURI == "GetActionTest") return MFEXML_ActionListTest;
+ if (sURI == "GetRemote") return MFEXML_GetRemote;
return( MFEXML_Unknown );
}
@@ -102,6 +103,9 @@ bool MythFEXML::ProcessRequest( HttpWorkerThread *pThread, HTTPRequest *pRequest
case MFEXML_ActionListTest:
GetActionListTest(pRequest);
break;
+ case MFEXML_GetRemote:
+ GetRemote(pRequest);
+ break;
default:
UPnp::FormatErrorResponse(pRequest, UPnPResult_InvalidAction);
}
@@ -178,6 +182,27 @@ void MythFEXML::SendAction(HTTPRequest *pRequest)
qApp->postEvent(window, (QEvent*)ke);
}
+static const QString PROCESS_ACTION =
+ " <script type =\"text/javascript\">\n"
+ " function postaction(action) {\n"
+ " var myForm = document.createElement(\"form\");\n"
+ " myForm.method =\"Post\";\n"
+ " myForm.action =\"SendAction?\";\n"
+ " myForm.target =\"post_target\";\n"
+ " var myInput = document.createElement(\"input\");\n"
+ " myInput.setAttribute(\"name\", \"action\");\n"
+ " myInput.setAttribute(\"value\", action);\n"
+ " myForm.appendChild(myInput);\n"
+ " document.body.appendChild(myForm);\n"
+ " myForm.submit();\n"
+ " document.body.removeChild(myForm);\n"
+ " }\n"
+ " </script>\n";
+
+static const QString HIDDEN_IFRAME =
+ " <iframe id=\"hidden_target\" name=\"post_target\" src=\"\""
+ " style=\"width:0;height:0;border:0px solid #fff;\"></iframe>\n";
+
void MythFEXML::GetActionListTest(HTTPRequest *pRequest)
{
InitActions();
@@ -186,25 +211,8 @@ void MythFEXML::GetActionListTest(HTTPRequest *pRequest)
pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000";
pRequest->m_response <<
- "<html>\n"
- " <script type =\"text/javascript\">\n"
- " function postaction(action) {\n"
- " var myForm = document.createElement(\"form\");\n"
- " myForm.method =\"Post\";\n"
- " myForm.action =\"SendAction?\";\n"
- " myForm.target =\"post_target\";\n"
- " var myInput = document.createElement(\"input\");\n"
- " myInput.setAttribute(\"name\", \"action\");\n"
- " myInput.setAttribute(\"value\", action);\n"
- " myForm.appendChild(myInput);\n"
- " document.body.appendChild(myForm);\n"
- " myForm.submit();\n"
- " document.body.removeChild(myForm);\n"
- " }\n"
- " </script>\n"
- " <body>\n"
- " <iframe id=\"hidden_target\" name=\"post_target\" src=\"\""
- " style=\"width:0;height:0;border:0px solid #fff;\"></iframe>\n";
+ "<html>\n" << PROCESS_ACTION <<
+ " <body>\n" << HIDDEN_IFRAME;
QHashIterator<QString,QStringList> contexts(m_actionDescriptions);
while (contexts.hasNext())
@@ -260,6 +268,63 @@ void MythFEXML::GetActionList(HTTPRequest *pRequest)
pRequest->m_response << "</mythactions>";
}
+#define BUTTON(action,desc) \
+ QString(" <input class=\"bigb\" type=\"button\" value=\"%1\" onClick=\"postaction('%2');\"></input>\r\n").arg(action).arg(desc)
+
+void MythFEXML::GetRemote(HTTPRequest *pRequest)
+{
+ InitActions();
+
+ pRequest->m_eResponseType = ResponseTypeHTML;
+ pRequest->m_mapRespHeaders[ "Cache-Control" ] = "no-cache=\"Ext\", max-age = 5000";
+
+ pRequest->m_response <<
+ "<html>\n" << PROCESS_ACTION <<
+ " <style type=\"text/css\" title=\"Default\" media=\"all\">\r\n"
+ " <!--\r\n"
+ " body {\r\n"
+ " margin: 0px;\r\n"
+ " width : 310px;\r\n"
+ " }\r\n"
+ " -->\r\n"
+ " .bigb {\r\n"
+ " width : 100px;\r\n"
+ " height: 50px;\r\n"
+ " margin: 0px;\r\n"
+ " text-align: center;\r\n"
+ " }\r\n"
+ " </style>\r\n"
+ " <title>MythFrontend Control</title>\r\n" <<
+ " <body>\n" << HIDDEN_IFRAME;
+
+ pRequest->m_response <<
+ " <div>\r\n" <<
+ BUTTON("1","1") << BUTTON("2","2") << BUTTON("3","3") <<
+ " </div>\r\n" <<
+ " <div>\r\n" <<
+ BUTTON("4","4") << BUTTON("5","5") << BUTTON("6","6") <<
+ " </div>\r\n" <<
+ " <div>\r\n" <<
+ BUTTON("7","7") << BUTTON("8","8") << BUTTON("9","9") <<
+ " </div>\r\n" <<
+ " <div>\r\n" <<
+ BUTTON("MENU","MENU") << BUTTON("0","0") << BUTTON("INFO","INFO") <<
+ " </div>\r\n" <<
+ " <div>\r\n" <<
+ BUTTON("Back","ESCAPE") << BUTTON("^","UP") << BUTTON("MUTE","MUTE") <<
+ " </div>\r\n" <<
+ " <div>\r\n" <<
+ BUTTON("<","LEFT") << BUTTON("Enter","SELECT") << BUTTON(">","RIGHT") <<
+ " </div>\r\n" <<
+ " <div>\r\n" <<
+ BUTTON("<<","JUMPRWND") << BUTTON("v","DOWN") << BUTTON(">>","JUMPFFWD") <<
+ " </div>\r\n";
+
+ pRequest->m_response <<
+ " </body>\n"
+ "</html>\n";
+}
+
void MythFEXML::InitActions(void)
{
static bool initialised = false;
@@ -23,6 +23,7 @@ typedef enum
MFEXML_Action,
MFEXML_ActionList,
MFEXML_ActionListTest,
+ MFEXML_GetRemote,
} MythFEXMLMethod;
class MythFEXML : public Eventing
@@ -53,6 +54,7 @@ class MythFEXML : public Eventing
void SendAction ( HTTPRequest *pRequest );
void GetActionList ( HTTPRequest *pRequest );
void GetActionListTest( HTTPRequest *pRequest );
+ void GetRemote ( HTTPRequest *pRequest );
void InitActions ( void );
public:

0 comments on commit 5e5e2dd

Please sign in to comment.