Mercurial > hg > vboxdotnet
diff VBoxFrontend/Display.cs @ 0:e1ec7bf71313
Initial commit
author | Ivo Smits |
---|---|
date | Wed, 04 May 2011 00:59:43 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VBoxFrontend/Display.cs Wed May 04 00:59:43 2011 +0200 @@ -0,0 +1,243 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Threading; +using VirtualBox; + +namespace ConsoleApplication1 { + public partial class Display : Form { + public Framebuffer Framebuffer { get; private set; } + public IConsole VMConsole { get; private set; } + private Point MouseLocation = new Point(0, 0); + private VBoxEventListener EventListener = new VBoxEventListener(); + private VBoxKeyboardHelper Keyboard; + private Size RequestedClientSize = new Size(0, 0); + private IProgress WaitingForProgress = null; + private Boolean InitialPaused = true; + + public Display(IConsole console, Framebuffer fb) { + VMConsole = console; + Framebuffer = fb; + Keyboard = new VBoxKeyboardHelper(VMConsole.Keyboard); + InitializeComponent(); + Framebuffer.BufferChanged += Framebuffer_BufferChanged; + Framebuffer.Update += Framebuffer_Update; + DisplayBox.Image = Framebuffer.Bitmap; + EventListener.HandleEvent += EventListener_HandleEvent; + EventListener.RegisterSource(VMConsole.EventSource, VBoxEventType.VBoxEventType_Any); + this.MouseWheel += Display_MouseEvent; + } + + private void Display_Load(object sender, EventArgs e) { + ClientSize = RequestedClientSize = new Size(800, 600); + if (ProgramRun.VBoxXPCOM != null) COMEventTimer.Enabled = true; + Framebuffer.WinId = Handle.ToInt64(); + } + + private void EventListener_HandleEvent(Object sender, VBoxEventArgs ea) { + IEvent aEvent = ea.Event; + switch (aEvent.Type) { + case VBoxEventType.VBoxEventType_OnCanShowWindow: { + ICanShowWindowEvent e = (ICanShowWindowEvent)aEvent; + } break; + case VBoxEventType.VBoxEventType_OnEventSourceChanged: + break; + case VBoxEventType.VBoxEventType_OnStateChanged: { + IStateChangedEvent e = (IStateChangedEvent)aEvent; + Console.WriteLine("New state: {0}", e.State); + switch (e.State) { + case MachineState.MachineState_Paused: + if (InitialPaused) { + InitialPaused = false; + ThreadPool.QueueUserWorkItem(delegate(Object state) { + VMConsole.Resume(); + }); + } + break; + case MachineState.MachineState_Running: + ThreadPool.QueueUserWorkItem(delegate(Object state) { + try { + if (VMConsole.Mouse.AbsoluteSupported == 0 && VMConsole.Mouse.RelativeSupported != 0) { + Console.WriteLine("Reset mouse position to {0}", MouseLocation); + //MouseLocation = new Point(0, 0); + VMConsole.Mouse.PutMouseEvent(-(int)Framebuffer.Width, -(int)Framebuffer.Height, 0, 0, 0); + VMConsole.Mouse.PutMouseEvent(MouseLocation.X, MouseLocation.Y, 0, 0, 0); + } + } catch (Exception ex) { + Console.WriteLine(ex.ToString()); + } + try { + VMConsole.Display.InvalidateAndUpdate(); + } catch (Exception ex) { + Console.WriteLine(ex.ToString()); + } + }); + break; + case MachineState.MachineState_Aborted: + case MachineState.MachineState_PoweredOff: + case MachineState.MachineState_Saved: + if (IsHandleCreated) Invoke((MethodInvoker)delegate() { Close(); }); + break; + } + } break; + case VBoxEventType.VBoxEventType_OnShowWindow: { + IShowWindowEvent e = (IShowWindowEvent)aEvent; + e.WinId = Handle.ToInt64(); + } break; + case VBoxEventType.VBoxEventType_OnKeyboardLedsChanged: { + IKeyboardLedsChangedEvent e = (IKeyboardLedsChangedEvent)aEvent; + Console.WriteLine("Keyboard leds: Numlock={0} Capslock={1} Scrolllock={2}", e.NumLock, e.CapsLock, e.ScrollLock); + } break; + case VBoxEventType.VBoxEventType_OnMouseCapabilityChanged: { + IMouseCapabilityChangedEvent e = (IMouseCapabilityChangedEvent)aEvent; + Console.WriteLine("MouseCapabilityChanged NeedsHostCursor={0} SupportsAbsolute={1} SupportsRelative={2}", e.NeedsHostCursor, e.SupportsAbsolute, e.SupportsRelative); + } break; + case VBoxEventType.VBoxEventType_OnMousePointerShapeChanged: { + IMousePointerShapeChangedEvent e = (IMousePointerShapeChangedEvent)aEvent; + } break; + case VBoxEventType.VBoxEventType_OnAdditionsStateChanged: { + IAdditionsStateChangedEvent e = (IAdditionsStateChangedEvent)aEvent; + } break; + } + } + + private void COMEventTimer_Tick(object sender, EventArgs e) { + ProgramRun.VBoxXPCOM.EventQueue.ProcessPendingEvents(); + } + + private void Display_Resize(object sender, EventArgs e) { + if (RequestedClientSize.Equals(ClientSize)) return; + if (VMConsole.State != MachineState.MachineState_Running) return; + VMConsole.Display.SetVideoModeHint((uint)DisplayBox.Width, (uint)DisplayBox.Height, 0, 0); + } + + private void Framebuffer_BufferChanged(Object sender, EventArgs e) { + DisplayBox.Invoke((MethodInvoker)delegate() { + Framebuffer fb = (Framebuffer)sender; + DisplayBox.Image = fb.Bitmap; + if (fb.Width > Screen.FromControl(this).WorkingArea.Width || fb.Height > Screen.FromControl(this).WorkingArea.Height) return; + ClientSize = RequestedClientSize = new Size((int)fb.Width + ClientSize.Width - DisplayBox.Width, (int)fb.Height + ClientSize.Height - DisplayBox.Height); + }); + } + + private void Framebuffer_Update(Object sender, FramebufferUpdateEventArgs e) { + DisplayBox.Invoke((MethodInvoker)delegate() { + DisplayBox.Invalidate(e.Rectangle); + }); + } + + private void Display_MouseEvent(object sender, MouseEventArgs e) { + IMouse mouse = VMConsole.Mouse; + MouseButtonState mbs = (MouseButtonState)0; + if ((e.Button & MouseButtons.Left) == MouseButtons.Left) mbs |= MouseButtonState.MouseButtonState_LeftButton; + if ((e.Button & MouseButtons.Right) == MouseButtons.Right) mbs |= MouseButtonState.MouseButtonState_RightButton; + if ((e.Button & MouseButtons.Middle) == MouseButtons.Middle) mbs |= MouseButtonState.MouseButtonState_MiddleButton; + if ((e.Button & MouseButtons.XButton1) == MouseButtons.XButton1) mbs |= MouseButtonState.MouseButtonState_XButton1; + if ((e.Button & MouseButtons.XButton2) == MouseButtons.XButton2) mbs |= MouseButtonState.MouseButtonState_XButton2; + try { + //Console.WriteLine("Mouse {0} Scroll {1} Buttons {2}", e.Location, e.Delta, mbs); + if (mouse.AbsoluteSupported != 0) { + mouse.PutMouseEventAbsolute(e.X + 1, e.Y + 1, -e.Delta / 120, 0, (int)mbs); + } else if (mouse.RelativeSupported != 0) { + mouse.PutMouseEvent(e.X - MouseLocation.X, e.Y - MouseLocation.Y, -e.Delta / 120, 0, (int)mbs); + } + MouseLocation = e.Location; + } catch (Exception ex) { + Console.WriteLine("MouseEventHandler Exception: {0}", ex.ToString()); + } + } + + private void Display_KeyDown(object sender, KeyEventArgs e) { + Keyboard.SendKeyCode(e.KeyCode, true); + } + + private void Display_KeyUp(object sender, KeyEventArgs e) { + Keyboard.SendKeyCode(e.KeyCode, false); + } + + private void pauseToolStripMenuItem_Click(object sender, EventArgs e) { + try { + VMConsole.Pause(); + statusLabel.Text = "Paused"; + statusLabel.Visible = true; + } catch (Exception ex) { + MessageBox.Show(ex.ToString()); + } + } + + private void resumeToolStripMenuItem_Click(object sender, EventArgs e) { + try { + VMConsole.Resume(); + if (statusLabel.Text == "Paused") statusLabel.Visible = false; + } catch (Exception ex) { + MessageBox.Show(ex.ToString()); + } + } + + private void savestateToolStripMenuItem_Click(object sender, EventArgs e) { + try { + MonitorUntilCompleted(VMConsole.SaveState()); + } catch (Exception ex) { + MessageBox.Show(ex.ToString()); + } + } + + private void aCPIPowerButtonToolStripMenuItem_Click(object sender, EventArgs e) { + try { + VMConsole.PowerButton(); + } catch (Exception ex) { + MessageBox.Show(ex.ToString()); + } + } + + private void powerdownToolStripMenuItem_Click(object sender, EventArgs e) { + try { + MonitorUntilCompleted(VMConsole.PowerDown()); + } catch (Exception ex) { + MessageBox.Show(ex.ToString()); + } + } + + private void resetToolStripMenuItem_Click(object sender, EventArgs e) { + try { + VMConsole.Reset(); + } catch (Exception ex) { + MessageBox.Show(ex.ToString()); + } + } + + public void MonitorUntilCompleted(IProgress p) { + WaitingForProgress = p; + statusLabel.Visible = true; + statusLabel.Text = "Busy..."; + ProgressWatcher.Enabled = true; + } + + private void ProgressWatcher_Tick(object sender, EventArgs e) { + IProgress p = WaitingForProgress; + if (p == null) { + ProgressWatcher.Enabled = false; + statusLabel.Visible = false; + } else { + if (p.Canceled == 0 && p.Completed == 0) { + statusLabel.Text = "Busy " + p.Percent + "%..."; + } else if (p.Canceled != 0) { + WaitingForProgress = null; + statusLabel.Text = "Operation aborted"; + } else if (p.Completed != 0) { + WaitingForProgress = null; + if (p.ErrorInfo == null || p.ErrorInfo.ResultCode == 0) { + statusLabel.Text = "Operation completed"; + } else { + statusLabel.Text = "Operation failed"; + MessageBox.Show(p.ErrorInfo.Text, "Operation failed"); + if (p.Cancelable != 0) p.Cancel(); + } + } + } + } + } +} \ No newline at end of file