Skip to content

Commit

Permalink
Add a simple http/html 'remote control' to the frontend.
Browse files Browse the repository at this point in the history
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
Mark Kendall committed Feb 14, 2011
1 parent 94b71c9 commit 5e5e2dd
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 19 deletions.
103 changes: 84 additions & 19 deletions mythtv/programs/mythfrontend/mythfexml.cpp
Expand Up @@ -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 );
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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();
Expand All @@ -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())
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions mythtv/programs/mythfrontend/mythfexml.h
Expand Up @@ -23,6 +23,7 @@ typedef enum
MFEXML_Action,
MFEXML_ActionList,
MFEXML_ActionListTest,
MFEXML_GetRemote,
} MythFEXMLMethod;

class MythFEXML : public Eventing
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 5e5e2dd

Please sign in to comment.