comparison VBoxFrontend/Display.cs @ 0:e1ec7bf71313

Initial commit
author Ivo Smits
date Wed, 04 May 2011 00:59:43 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e1ec7bf71313
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Text;
6 using System.Windows.Forms;
7 using System.Threading;
8 using VirtualBox;
9
10 namespace ConsoleApplication1 {
11 public partial class Display : Form {
12 public Framebuffer Framebuffer { get; private set; }
13 public IConsole VMConsole { get; private set; }
14 private Point MouseLocation = new Point(0, 0);
15 private VBoxEventListener EventListener = new VBoxEventListener();
16 private VBoxKeyboardHelper Keyboard;
17 private Size RequestedClientSize = new Size(0, 0);
18 private IProgress WaitingForProgress = null;
19 private Boolean InitialPaused = true;
20
21 public Display(IConsole console, Framebuffer fb) {
22 VMConsole = console;
23 Framebuffer = fb;
24 Keyboard = new VBoxKeyboardHelper(VMConsole.Keyboard);
25 InitializeComponent();
26 Framebuffer.BufferChanged += Framebuffer_BufferChanged;
27 Framebuffer.Update += Framebuffer_Update;
28 DisplayBox.Image = Framebuffer.Bitmap;
29 EventListener.HandleEvent += EventListener_HandleEvent;
30 EventListener.RegisterSource(VMConsole.EventSource, VBoxEventType.VBoxEventType_Any);
31 this.MouseWheel += Display_MouseEvent;
32 }
33
34 private void Display_Load(object sender, EventArgs e) {
35 ClientSize = RequestedClientSize = new Size(800, 600);
36 if (ProgramRun.VBoxXPCOM != null) COMEventTimer.Enabled = true;
37 Framebuffer.WinId = Handle.ToInt64();
38 }
39
40 private void EventListener_HandleEvent(Object sender, VBoxEventArgs ea) {
41 IEvent aEvent = ea.Event;
42 switch (aEvent.Type) {
43 case VBoxEventType.VBoxEventType_OnCanShowWindow: {
44 ICanShowWindowEvent e = (ICanShowWindowEvent)aEvent;
45 } break;
46 case VBoxEventType.VBoxEventType_OnEventSourceChanged:
47 break;
48 case VBoxEventType.VBoxEventType_OnStateChanged: {
49 IStateChangedEvent e = (IStateChangedEvent)aEvent;
50 Console.WriteLine("New state: {0}", e.State);
51 switch (e.State) {
52 case MachineState.MachineState_Paused:
53 if (InitialPaused) {
54 InitialPaused = false;
55 ThreadPool.QueueUserWorkItem(delegate(Object state) {
56 VMConsole.Resume();
57 });
58 }
59 break;
60 case MachineState.MachineState_Running:
61 ThreadPool.QueueUserWorkItem(delegate(Object state) {
62 try {
63 if (VMConsole.Mouse.AbsoluteSupported == 0 && VMConsole.Mouse.RelativeSupported != 0) {
64 Console.WriteLine("Reset mouse position to {0}", MouseLocation);
65 //MouseLocation = new Point(0, 0);
66 VMConsole.Mouse.PutMouseEvent(-(int)Framebuffer.Width, -(int)Framebuffer.Height, 0, 0, 0);
67 VMConsole.Mouse.PutMouseEvent(MouseLocation.X, MouseLocation.Y, 0, 0, 0);
68 }
69 } catch (Exception ex) {
70 Console.WriteLine(ex.ToString());
71 }
72 try {
73 VMConsole.Display.InvalidateAndUpdate();
74 } catch (Exception ex) {
75 Console.WriteLine(ex.ToString());
76 }
77 });
78 break;
79 case MachineState.MachineState_Aborted:
80 case MachineState.MachineState_PoweredOff:
81 case MachineState.MachineState_Saved:
82 if (IsHandleCreated) Invoke((MethodInvoker)delegate() { Close(); });
83 break;
84 }
85 } break;
86 case VBoxEventType.VBoxEventType_OnShowWindow: {
87 IShowWindowEvent e = (IShowWindowEvent)aEvent;
88 e.WinId = Handle.ToInt64();
89 } break;
90 case VBoxEventType.VBoxEventType_OnKeyboardLedsChanged: {
91 IKeyboardLedsChangedEvent e = (IKeyboardLedsChangedEvent)aEvent;
92 Console.WriteLine("Keyboard leds: Numlock={0} Capslock={1} Scrolllock={2}", e.NumLock, e.CapsLock, e.ScrollLock);
93 } break;
94 case VBoxEventType.VBoxEventType_OnMouseCapabilityChanged: {
95 IMouseCapabilityChangedEvent e = (IMouseCapabilityChangedEvent)aEvent;
96 Console.WriteLine("MouseCapabilityChanged NeedsHostCursor={0} SupportsAbsolute={1} SupportsRelative={2}", e.NeedsHostCursor, e.SupportsAbsolute, e.SupportsRelative);
97 } break;
98 case VBoxEventType.VBoxEventType_OnMousePointerShapeChanged: {
99 IMousePointerShapeChangedEvent e = (IMousePointerShapeChangedEvent)aEvent;
100 } break;
101 case VBoxEventType.VBoxEventType_OnAdditionsStateChanged: {
102 IAdditionsStateChangedEvent e = (IAdditionsStateChangedEvent)aEvent;
103 } break;
104 }
105 }
106
107 private void COMEventTimer_Tick(object sender, EventArgs e) {
108 ProgramRun.VBoxXPCOM.EventQueue.ProcessPendingEvents();
109 }
110
111 private void Display_Resize(object sender, EventArgs e) {
112 if (RequestedClientSize.Equals(ClientSize)) return;
113 if (VMConsole.State != MachineState.MachineState_Running) return;
114 VMConsole.Display.SetVideoModeHint((uint)DisplayBox.Width, (uint)DisplayBox.Height, 0, 0);
115 }
116
117 private void Framebuffer_BufferChanged(Object sender, EventArgs e) {
118 DisplayBox.Invoke((MethodInvoker)delegate() {
119 Framebuffer fb = (Framebuffer)sender;
120 DisplayBox.Image = fb.Bitmap;
121 if (fb.Width > Screen.FromControl(this).WorkingArea.Width || fb.Height > Screen.FromControl(this).WorkingArea.Height) return;
122 ClientSize = RequestedClientSize = new Size((int)fb.Width + ClientSize.Width - DisplayBox.Width, (int)fb.Height + ClientSize.Height - DisplayBox.Height);
123 });
124 }
125
126 private void Framebuffer_Update(Object sender, FramebufferUpdateEventArgs e) {
127 DisplayBox.Invoke((MethodInvoker)delegate() {
128 DisplayBox.Invalidate(e.Rectangle);
129 });
130 }
131
132 private void Display_MouseEvent(object sender, MouseEventArgs e) {
133 IMouse mouse = VMConsole.Mouse;
134 MouseButtonState mbs = (MouseButtonState)0;
135 if ((e.Button & MouseButtons.Left) == MouseButtons.Left) mbs |= MouseButtonState.MouseButtonState_LeftButton;
136 if ((e.Button & MouseButtons.Right) == MouseButtons.Right) mbs |= MouseButtonState.MouseButtonState_RightButton;
137 if ((e.Button & MouseButtons.Middle) == MouseButtons.Middle) mbs |= MouseButtonState.MouseButtonState_MiddleButton;
138 if ((e.Button & MouseButtons.XButton1) == MouseButtons.XButton1) mbs |= MouseButtonState.MouseButtonState_XButton1;
139 if ((e.Button & MouseButtons.XButton2) == MouseButtons.XButton2) mbs |= MouseButtonState.MouseButtonState_XButton2;
140 try {
141 //Console.WriteLine("Mouse {0} Scroll {1} Buttons {2}", e.Location, e.Delta, mbs);
142 if (mouse.AbsoluteSupported != 0) {
143 mouse.PutMouseEventAbsolute(e.X + 1, e.Y + 1, -e.Delta / 120, 0, (int)mbs);
144 } else if (mouse.RelativeSupported != 0) {
145 mouse.PutMouseEvent(e.X - MouseLocation.X, e.Y - MouseLocation.Y, -e.Delta / 120, 0, (int)mbs);
146 }
147 MouseLocation = e.Location;
148 } catch (Exception ex) {
149 Console.WriteLine("MouseEventHandler Exception: {0}", ex.ToString());
150 }
151 }
152
153 private void Display_KeyDown(object sender, KeyEventArgs e) {
154 Keyboard.SendKeyCode(e.KeyCode, true);
155 }
156
157 private void Display_KeyUp(object sender, KeyEventArgs e) {
158 Keyboard.SendKeyCode(e.KeyCode, false);
159 }
160
161 private void pauseToolStripMenuItem_Click(object sender, EventArgs e) {
162 try {
163 VMConsole.Pause();
164 statusLabel.Text = "Paused";
165 statusLabel.Visible = true;
166 } catch (Exception ex) {
167 MessageBox.Show(ex.ToString());
168 }
169 }
170
171 private void resumeToolStripMenuItem_Click(object sender, EventArgs e) {
172 try {
173 VMConsole.Resume();
174 if (statusLabel.Text == "Paused") statusLabel.Visible = false;
175 } catch (Exception ex) {
176 MessageBox.Show(ex.ToString());
177 }
178 }
179
180 private void savestateToolStripMenuItem_Click(object sender, EventArgs e) {
181 try {
182 MonitorUntilCompleted(VMConsole.SaveState());
183 } catch (Exception ex) {
184 MessageBox.Show(ex.ToString());
185 }
186 }
187
188 private void aCPIPowerButtonToolStripMenuItem_Click(object sender, EventArgs e) {
189 try {
190 VMConsole.PowerButton();
191 } catch (Exception ex) {
192 MessageBox.Show(ex.ToString());
193 }
194 }
195
196 private void powerdownToolStripMenuItem_Click(object sender, EventArgs e) {
197 try {
198 MonitorUntilCompleted(VMConsole.PowerDown());
199 } catch (Exception ex) {
200 MessageBox.Show(ex.ToString());
201 }
202 }
203
204 private void resetToolStripMenuItem_Click(object sender, EventArgs e) {
205 try {
206 VMConsole.Reset();
207 } catch (Exception ex) {
208 MessageBox.Show(ex.ToString());
209 }
210 }
211
212 public void MonitorUntilCompleted(IProgress p) {
213 WaitingForProgress = p;
214 statusLabel.Visible = true;
215 statusLabel.Text = "Busy...";
216 ProgressWatcher.Enabled = true;
217 }
218
219 private void ProgressWatcher_Tick(object sender, EventArgs e) {
220 IProgress p = WaitingForProgress;
221 if (p == null) {
222 ProgressWatcher.Enabled = false;
223 statusLabel.Visible = false;
224 } else {
225 if (p.Canceled == 0 && p.Completed == 0) {
226 statusLabel.Text = "Busy " + p.Percent + "%...";
227 } else if (p.Canceled != 0) {
228 WaitingForProgress = null;
229 statusLabel.Text = "Operation aborted";
230 } else if (p.Completed != 0) {
231 WaitingForProgress = null;
232 if (p.ErrorInfo == null || p.ErrorInfo.ResultCode == 0) {
233 statusLabel.Text = "Operation completed";
234 } else {
235 statusLabel.Text = "Operation failed";
236 MessageBox.Show(p.ErrorInfo.Text, "Operation failed");
237 if (p.Cancelable != 0) p.Cancel();
238 }
239 }
240 }
241 }
242 }
243 }