From: <an...@us...> - 2007-11-30 16:57:38
|
Revision: 1113 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=1113&view=rev Author: and-81 Date: 2007-11-30 08:37:26 -0800 (Fri, 30 Nov 2007) Log Message: ----------- Modified Paths: -------------- trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.Designer.cs trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.cs trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs trunk/plugins/IR Server Suite/Applications/Virtual Remote/Virtual Remote.csproj trunk/plugins/IR Server Suite/Documentation/Virtual Remote/index.html trunk/plugins/IR Server Suite/Documentation/new.html Added Paths: ----------- trunk/plugins/IR Server Suite/Applications/Virtual Remote/Skins/web.html trunk/plugins/IR Server Suite/Applications/Virtual Remote/WebServer.cs Modified: trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.Designer.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.Designer.cs 2007-11-30 16:14:57 UTC (rev 1112) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.Designer.cs 2007-11-30 16:37:26 UTC (rev 1113) @@ -50,13 +50,13 @@ this.contextMenuStrip.Name = "contextMenuStrip"; this.contextMenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System; this.contextMenuStrip.ShowImageMargin = false; - this.contextMenuStrip.Size = new System.Drawing.Size(156, 97); + this.contextMenuStrip.Size = new System.Drawing.Size(156, 95); // // toolStripComboBoxSkin // this.toolStripComboBoxSkin.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.toolStripComboBoxSkin.Name = "toolStripComboBoxSkin"; - this.toolStripComboBoxSkin.Size = new System.Drawing.Size(120, 23); + this.toolStripComboBoxSkin.Size = new System.Drawing.Size(120, 21); this.toolStripComboBoxSkin.ToolTipText = "Select a custom skin"; this.toolStripComboBoxSkin.SelectedIndexChanged += new System.EventHandler(this.toolStripComboBoxSkin_SelectedIndexChanged); // @@ -108,7 +108,6 @@ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; - this.MinimizeBox = false; this.Name = "MainForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.Text = "Virtual Remote"; Modified: trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.cs 2007-11-30 16:14:57 UTC (rev 1112) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/MainForm.cs 2007-11-30 16:37:26 UTC (rev 1113) @@ -23,8 +23,6 @@ #region Variables - RemoteButton []_buttons; - //Thread _updateThread; #endregion Variables @@ -57,31 +55,18 @@ if (e.Button != MouseButtons.Left) return; - if (_buttons == null) - return; - - foreach (RemoteButton button in _buttons) - { - if (e.Y >= button.Top && - e.Y < button.Top + button.Height && - e.X >= button.Left && - e.X <= button.Left + button.Width) - { - ButtonPress(button.Code); - break; - } - } + Program.ProcessClick(e.X, e.Y); } private void MainForm_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.None) return; - foreach (RemoteButton button in _buttons) + foreach (RemoteButton button in Program.Buttons) { if (button.Shortcut == e.KeyCode) { - ButtonPress(button.Code); + Program.ButtonPress(button.Code); break; } } @@ -123,7 +108,7 @@ buttons.Add(temp); } - _buttons = (RemoteButton[])buttons.ToArray(typeof(RemoteButton)); + Program.Buttons = (RemoteButton[])buttons.ToArray(typeof(RemoteButton)); return true; } @@ -185,15 +170,6 @@ } } - static void ButtonPress(string keyCode) - { - if (!Program.Registered) - return; - - IrssMessage message = new IrssMessage(MessageType.ForwardRemoteEvent, MessageFlags.Notify, keyCode); - Program.SendMessage(message); - } - void SetLabel() { while (true) Modified: trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs 2007-11-30 16:14:57 UTC (rev 1112) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/Program.cs 2007-11-30 16:37:26 UTC (rev 1113) @@ -25,6 +25,7 @@ #region Constants const string DefaultSkin = "MCE"; + const int DefaultWebPort = 2481; static readonly string ConfigurationFile = Common.FolderAppData + "Virtual Remote\\Virtual Remote.xml"; @@ -42,6 +43,12 @@ static string _remoteSkin; + static RemoteButton[] _buttons; + + static WebServer _webServer; + + static int _webPort; + #endregion Variables #region Properties @@ -68,6 +75,12 @@ set { _remoteSkin = value; } } + internal static RemoteButton[] Buttons + { + get { return _buttons; } + set { _buttons = value; } + } + #endregion Properties /// <summary> @@ -181,8 +194,15 @@ } if (clientStarted) + { + _webServer = new WebServer(_webPort); + _webServer.Run(); + Application.Run(new MainForm()); + _webServer.Stop(); + } + SaveSettings(); } @@ -220,13 +240,11 @@ _installFolder = "."; } + XmlDocument doc = new XmlDocument(); + try { - XmlDocument doc = new XmlDocument(); doc.Load(ConfigurationFile); - - _serverHost = doc.DocumentElement.Attributes["ServerHost"].Value; - _remoteSkin = doc.DocumentElement.Attributes["RemoteSkin"].Value; } catch (Exception ex) { @@ -234,7 +252,14 @@ _serverHost = "localhost"; _remoteSkin = DefaultSkin; + _webPort = DefaultWebPort; + + return; } + + try { _serverHost = doc.DocumentElement.Attributes["ServerHost"].Value; } catch { _serverHost = "localhost"; } + try { _remoteSkin = doc.DocumentElement.Attributes["RemoteSkin"].Value; } catch { _remoteSkin = DefaultSkin; } + try { _webPort = int.Parse(doc.DocumentElement.Attributes["WebPort"].Value); } catch { _webPort = DefaultWebPort; } } static void SaveSettings() { @@ -250,6 +275,7 @@ writer.WriteAttributeString("ServerHost", _serverHost); writer.WriteAttributeString("RemoteSkin", _remoteSkin); + writer.WriteAttributeString("WebPort", _webPort.ToString()); writer.WriteEndElement(); // </settings> writer.WriteEndDocument(); @@ -319,8 +345,37 @@ _client = null; } - internal static void SendMessage(IrssMessage message) + internal static bool ProcessClick(int x, int y) { + if (_buttons != null) + { + foreach (RemoteButton button in _buttons) + { + if (y >= button.Top && + y < button.Top + button.Height && + x >= button.Left && + x <= button.Left + button.Width) + { + ButtonPress(button.Code); + return true; + } + } + } + + return false; + } + + internal static void ButtonPress(string keyCode) + { + if (!_registered) + return; + + IrssMessage message = new IrssMessage(MessageType.ForwardRemoteEvent, MessageFlags.Notify, keyCode); + SendMessage(message); + } + + static void SendMessage(IrssMessage message) + { if (message == null) throw new ArgumentNullException("message"); Added: trunk/plugins/IR Server Suite/Applications/Virtual Remote/Skins/web.html =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/Skins/web.html (rev 0) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/Skins/web.html 2007-11-30 16:37:26 UTC (rev 1113) @@ -0,0 +1,7 @@ +<HEAD> +<TITLE>Virtual Remote</TITLE> +</HEAD> + +<BODY STYLE="margin: 0;"> +<IMG SRC="REMOTE_SKIN" BORDER="0" USEMAP="#REMOTE_MAP"> +</BODY> Modified: trunk/plugins/IR Server Suite/Applications/Virtual Remote/Virtual Remote.csproj =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/Virtual Remote.csproj 2007-11-30 16:14:57 UTC (rev 1112) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/Virtual Remote.csproj 2007-11-30 16:37:26 UTC (rev 1113) @@ -59,6 +59,7 @@ <Reference Include="System" /> <Reference Include="System.Data" /> <Reference Include="System.Drawing" /> + <Reference Include="System.Web" /> <Reference Include="System.Windows.Forms" /> <Reference Include="System.Xml" /> </ItemGroup> @@ -76,6 +77,7 @@ <DependentUpon>MainForm.cs</DependentUpon> </EmbeddedResource> <Compile Include="RemoteButton.cs" /> + <Compile Include="WebServer.cs" /> </ItemGroup> <ItemGroup> <Content Include="Icon.ico" /> @@ -95,6 +97,7 @@ </Content> <Content Include="Skins\MCE.xml"> </Content> + <Content Include="Skins\web.html" /> <Content Include="Skins\Xbox Blue Plasma.png"> </Content> <Content Include="Skins\Xbox Orange.png"> Added: trunk/plugins/IR Server Suite/Applications/Virtual Remote/WebServer.cs =================================================================== --- trunk/plugins/IR Server Suite/Applications/Virtual Remote/WebServer.cs (rev 0) +++ trunk/plugins/IR Server Suite/Applications/Virtual Remote/WebServer.cs 2007-11-30 16:37:26 UTC (rev 1113) @@ -0,0 +1,279 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Text; +using System.Threading; +using System.Web; + +namespace VirtualRemote +{ + + /// <summary> + /// Provides a Web front-end to the Virtual Remote. + /// </summary> + public class WebServer + { + + #region Constants + + const string ServerName = "Virtual Remote"; + + const string ButtonClickPrefix = "click?"; + + #endregion Constants + + #region Variables + + int _serverPort; + + Socket _serverSocket; + NetworkStream _networkStream; + TextReader _networkReader; + + Thread _runningThread; + + #endregion Variables + + #region Constructor + + /// <summary> + /// Initializes a new instance of the <see cref="WebServer"/> class. + /// </summary> + /// <param name="port">The port to serve on.</param> + public WebServer(int port) + { + _serverPort = port; + } + + #endregion Constructor + + #region Public Methods + + /// <summary> + /// Runs the Web Server. + /// </summary> + public void Run() + { + if (_runningThread != null) + _runningThread.Abort(); + + _runningThread = new Thread(new ThreadStart(RunThread)); + _runningThread.IsBackground = true; + _runningThread.Start(); + } + + /// <summary> + /// Stops the Web Server. + /// </summary> + public void Stop() + { + if (_runningThread != null) + { + try + { + _runningThread.Abort(); + } + finally + { + _runningThread = null; + } + } + } + + #endregion Public Methods + + #region Implementation + + void RunThread() + { + try + { + _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + IPEndPoint ipe = new IPEndPoint(IPAddress.Any, _serverPort); + _serverSocket.Bind(ipe); + + while (true) + { + Socket socket = AcceptConnection(); + string command = HttpUtility.UrlDecode(GetCommand()); + + if (command.StartsWith("GET", StringComparison.OrdinalIgnoreCase)) + { + string commandElement = GetCommandElement(command); + DoGet(commandElement); + } + + _networkStream.Flush(); + _networkStream.Close(); + } + + } + finally + { + _serverSocket.Close(); + } + } + + string CreateImageMap() + { + StringBuilder imageMap = new StringBuilder(); + imageMap.AppendLine("<MAP NAME=\"REMOTE_MAP\">"); + + foreach (RemoteButton button in Program.Buttons) + { + string area = String.Format( + "<AREA SHAPE=\"rect\" COORDS=\"{0},{1},{2},{3}\" TITLE=\"{4}\" HREF=\"{5}{6}\">", + button.Left, button.Top, button.Left + button.Width, button.Top + button.Height, + button.Name, + ButtonClickPrefix, button.Code); + + imageMap.AppendLine(area); + } + + imageMap.AppendLine("<AREA SHAPE=\"default\" NOHREF>"); + imageMap.AppendLine("</MAP>"); + + return imageMap.ToString(); + } + + void DoGet(string argument) + { + string url = GetUrl(argument); + + if (url.StartsWith("/")) + url = url.Substring(1); + + if (url.Length == 0) + url = "INDEX.HTML"; + + if (url.StartsWith(ButtonClickPrefix, StringComparison.OrdinalIgnoreCase)) + { + string command = url.Substring(ButtonClickPrefix.Length); + + Program.ButtonPress(command); + + url = "INDEX.HTML"; + } + + switch (url.ToUpperInvariant()) + { + case "INDEX.HTML": + SendOK("text/html; charset=utf-8"); + SendString("<HTML>"); + SendFile(String.Format("{0}\\Skins\\web.html", Program.InstallFolder)); + SendString(CreateImageMap()); + SendString("</HTML>"); + break; + + case "REMOTE_SKIN": + SendOK("image/png"); + SendFile(String.Format("{0}\\Skins\\{1}.png", Program.InstallFolder, Program.RemoteSkin)); + break; + + default: + SendError(404, "File Not Found"); + break; + } + } + + string GetUrl(string argument) + { + StringBuilder outputString = new StringBuilder(); + + for (int index = 0; index < argument.Length; index++) + { + char curChar = argument[index]; + + if (Char.IsWhiteSpace(curChar)) + break; + + outputString.Append(curChar); + } + + return outputString.ToString(); + } + + Socket AcceptConnection() + { + + _serverSocket.Listen(1); + Socket socket = _serverSocket.Accept(); + + _networkStream = new NetworkStream(socket, FileAccess.ReadWrite, true); + _networkReader = new StreamReader(_networkStream); + IPEndPoint ep = (IPEndPoint)socket.RemoteEndPoint; + + return socket; + } + + string GetCommand() + { + string buf; + string command = String.Empty; + bool first = true; + + while ((buf = _networkReader.ReadLine()) != null && buf.Length > 0) + { + if (first) + { + command = buf; + first = false; + } + } + + return command; + } + + string GetCommandElement(string command) + { + string[] commandElements = command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + return commandElements[1]; + } + + void SendFile(string path) + { + byte[] buffer = new byte[2048]; + + int byteCount; + using (FileStream fileStream = File.OpenRead(path)) + { + while ((byteCount = fileStream.Read(buffer, 0, buffer.Length)) > 0) + { + _networkStream.Write(buffer, 0, byteCount); + } + } + } + + void SendString(string message, params object[] args) + { + string output = String.Format(message, args); + + byte[] outputBytes = Encoding.ASCII.GetBytes(output); + + _networkStream.Write(outputBytes, 0, outputBytes.Length); + } + + void SendError(int errorNumber, string errorString) + { + SendString("HTTP/1.1 {0} {1}\r\n", errorNumber, errorString); + SendString("Date:{0}\r\n", DateTime.Now); + SendString("Server:{0}\r\n", ServerName); + SendString("Content-Type: text/html; charset=utf-8\r\n"); + SendString("Connection: close\r\n"); + } + + void SendOK(string contentType) + { + SendString("HTTP/1.1 200 OK\r\n"); + SendString("Date:{0}\r\n", DateTime.Now); + SendString("Server:{0}\r\n", ServerName); + SendString("Content-Type: {0}\r\n\r\n", contentType); + } + + #endregion Implementation + + } + +} Modified: trunk/plugins/IR Server Suite/Documentation/Virtual Remote/index.html =================================================================== --- trunk/plugins/IR Server Suite/Documentation/Virtual Remote/index.html 2007-11-30 16:14:57 UTC (rev 1112) +++ trunk/plugins/IR Server Suite/Documentation/Virtual Remote/index.html 2007-11-30 16:37:26 UTC (rev 1113) @@ -12,6 +12,8 @@ <P>Right-Click in the Virtual Remote window to bring up the program menu to change the server address, change the skin, or to quit the program.</P> +<P>Virtual Remote is also accessible through it's own web interface. Connect to the computer Virtual Remote is running on through port 2481 to use the Virtual Remote Web Interface.</P> + <P>Virtual Remote can also be used from the command line to simulate button presses.</P> <P>Command line parameters:<BR> Modified: trunk/plugins/IR Server Suite/Documentation/new.html =================================================================== --- trunk/plugins/IR Server Suite/Documentation/new.html 2007-11-30 16:14:57 UTC (rev 1112) +++ trunk/plugins/IR Server Suite/Documentation/new.html 2007-11-30 16:37:26 UTC (rev 1113) @@ -23,6 +23,7 @@ <LI>Added some new macro commands (HTTP requests, beep sound, wave file playback).</LI> <LI>Commands (including macros) now execute on separate threads. In the past calling a macro for example would block the caller until it finished, now the caller can continue while the macro executes independantly. Note that this will cause a subtle change in flow control, but shouldn't effect anyone.</LI> <LI>Added support for Girder 3.x plugins, still experimental at this stage. Expect to see improvements in this area, like multiple Girder plugins active at the same time.</LI> +<LI>Virtual Remote now has a built in web server accessible on port 2481.</LI> </UL></P> <BR> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |