VirtualComputer/VirtualComputerSender/Computer.cs
2016-03-19 23:36:10 +01:00

218 lines
8.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using VirtualBox;
namespace VirtualComputerSender //Copyright © NorbiPeti 2015-2016
{
public class Computer
{ //Self-note: Don't add/edit public members
private VirtualBoxClass vbox;
private Session session;
public Computer()
{
vbox = new VirtualBoxClass();
session = new Session();
}
public void Start()
{
var machine = (IMachine)vbox.Machines.GetValue(0);
//if (machine.State == MachineState.MachineState_PoweredOff) //2016.02.09.
//{
var progress = machine.LaunchVMProcess(session, "headless", "");
progress.WaitForCompletion(100000);
//}
//else if (machine.State == MachineState.MachineState_Paused || machine.State == MachineState.MachineState_Running)
//machine.LockMachine(session, LockType.LockType_Write); //2016.02.09.
var fb = new MCFrameBuffer(session.Console.Display);
Screen = fb.Screen; //fb.Screen is assigned on object creation
session.Console.Display.AttachFramebuffer(0, fb);
session.Console.Display.SetSeamlessMode(0);
}
public bool PowerButton()
{
if (session.State != SessionState.SessionState_Locked || session.Machine == null)
{
Start();
return true;
}
else
{
session.Console.PowerButton();
if (session.State != SessionState.SessionState_Locked)
Screen = null;
return false;
}
}
public void PowerOff()
{
if (session.State == SessionState.SessionState_Locked)
{
session.Console.PowerDown().WaitForCompletion(10000);
Screen = null;
}
}
public void Reset()
{
if (session.State == SessionState.SessionState_Locked)
session.Console.Reset();
}
//private Color[,] Screen;
//private byte[][][] Screen;
private volatile int[] Screen; //<-- volatile: 2016.02.20.
/*public byte[][][] GetScreen()
{
return Screen;
}*/
/*public byte GetScreenPixelColor(int x, int y, int rgb)
{
return Screen[x][y][rgb];
}*/
public int[] GetScreenPixelColors()
{
if (Screen == null)
{
Screen = new int[640 * 480];
for (int i = 0; i < Screen.Length; i++)
Screen[i] = Color.Black.ToArgb();
}
return Screen; //TO!DO: Pass events to plugin
}
[DllImport("user32.dll")]
static extern uint MapVirtualKey(uint uCode, uint uMapType); //2016.02.10.
const uint MAPVK_VK_TO_VSC = 0x00;
const uint MAPVK_VSC_TO_VK = 0x01;
const uint MAPVK_VK_TO_CHAR = 0x02;
const uint MAPVK_VSC_TO_VK_EX = 0x03;
const uint MAPVK_VK_TO_VSC_EX = 0x04;
/*private bool Shift = false;
private bool Ctrl = false;
private bool Alt = false;*/
public void PressKey(string key, short durationorstate) //durationstate: 2016.02.22.
{
if (session.State == SessionState.SessionState_Locked)
{
//session.Console.Keyboard.ReleaseKeys();
int code = 0;
if (key == "testall")
{
int x = 0;
session.Console.Keyboard.PutScancodes(new int[128].Select(i => x++).ToArray());
return;
}
//switch (key.ToLower()[0])
//switch(key.ToLower())
//{
//case 'a':
//code = 65;
//code = 31; //2016.02.09.
//code = 1 | (int)Keys.A; //2016.02.09.
//code = 128 | (int)Keys.A; //2016.02.10.
//code = BitConverter.ToInt32(new byte[4] { (byte)Keys.A, 0x00, 0x00, 0x01 }, 0);
//code = 0x41;
//code = (int)MapVirtualKey(0x41, MAPVK_VK_TO_VSC); //SUCCESS - 2016.02.10.
//Virtual key code taken from Kennedy.ManagedHooks project
//Release key scan code concept taken from VirtualBox source code (KeyboardImpl.cpp:putCAD())
//+128
code = (int)MapVirtualKey((uint)(VirtualKeys)Enum.Parse(typeof(VirtualKeys), key, true), MAPVK_VK_TO_VSC); //2016.02.11.
int codeShift = (int)MapVirtualKey((uint)VirtualKeys.ShiftLeft, MAPVK_VK_TO_VSC); //2016.02.22.
int codeCtrl = (int)MapVirtualKey((uint)VirtualKeys.ControlLeft, MAPVK_VK_TO_VSC); //2016.02.22.
int codeAlt = (int)MapVirtualKey((uint)VirtualKeys.AltLeft, MAPVK_VK_TO_VSC); //2016.02.22.
//Console.WriteLine("Key: " + key + " - Code: " + code); //2016.02.11.
/*bool release = true; //2016.02.11.
if ((key.ToLower() == "shiftleft" || key.ToLower() == "shiftright"))
{ //2016.02.11.
if (!Shift)
{
Shift = true;
release = false;
}
else
Shift = false;
}
else if ((key.ToLower() == "controlleft" || key.ToLower() == "controlright"))
{ //2016.02.11.
if (!Ctrl)
{
Ctrl = true;
release = false;
}
else
Ctrl = false;
}
else if ((key.ToLower() == "altleft" || key.ToLower() == "altright"))
{ //2016.02.11.
if (!Alt)
{
Alt = true;
release = false;
}
else
Alt = false;
}*/
//break;
//default:
//break;
//}
//Console.WriteLine("Code. " + code);
if (durationorstate != -2) //<-- 2016.02.22.
session.Console.Keyboard.PutScancode(code);
//if (release)
if (durationorstate == 0 || durationorstate == -2) //<-- 2016.02.22.
session.Console.Keyboard.PutScancodes(new int[] { code + 128, codeCtrl + 128, codeShift + 128, codeAlt + 128 }); //2016.02.11. - Shift, etc.: 2016.02.22.
if (durationorstate > 0)
{ //2016.02.22.
Timer t = new Timer();
t.Tick += delegate
{
session.Console.Keyboard.PutScancode(code + 128);
t.Stop();
};
t.Interval = durationorstate;
t.Start();
}
}
}
//public void UpdateMouse(int x, int y, int z, int w, int mbs) //MouseButtonState --> int: 2016.02.12.
public void UpdateMouse(int x, int y, int z, int w, string mbs) //int --> string: 2016.02.22.
{
if (session.State != SessionState.SessionState_Locked)
return; //2016.02.27.
int state = 0; //<-- 2016.02.22.
if (mbs.Length > 0) //<-- 2016.02.22.
state = (int)(MouseBS)Enum.Parse(typeof(MouseBS), mbs, true);
session.Console.Mouse.PutMouseEvent(x, y, z, w, state);
}
public void FixScreen()
{
session.Console.Display.SetSeamlessMode(0);
session.Console.Display.SetVideoModeHint(0, 1, 0, 0, 0, 640, 480, 32);
}
~Computer()
{ //2016.02.09.
if (session.State == SessionState.SessionState_Locked)
//session.Machine.SaveState().WaitForCompletion(10000);
session.Machine.SaveState(); //2016.02.20.
}
}
}