ScpServer/ScpForm.cs (203 lines of code) (raw):

using System; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; using log4net; using ScpControl; using ScpControl.Bluetooth; using ScpControl.Exceptions; using ScpControl.Shared.Core; using ScpControl.Usb.Ds3; using ScpControl.Usb.Ds4; using ScpControl.Usb.Gamepads; using ScpControl.Utilities; using ScpServer.Properties; namespace ScpServer { public partial class ScpForm : Form { private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly RadioButton[] Pad = new RadioButton[4]; private IntPtr m_BthNotify = IntPtr.Zero; private IntPtr m_Ds3Notify = IntPtr.Zero; private IntPtr m_Ds4Notify = IntPtr.Zero; private IntPtr _genericNotify = IntPtr.Zero; public ScpForm() { InitializeComponent(); AppDomain.CurrentDomain.UnhandledException += (sender, args) => { Log.FatalFormat("An unhandled exception occured: {0}", args.ExceptionObject); }; ThemeUtil.SetTheme(lvDebug); Pad[0] = rbPad_1; Pad[1] = rbPad_2; Pad[2] = rbPad_3; Pad[3] = rbPad_4; } private void Form_Load(object sender, EventArgs e) { Icon = Resources.Scp_All; ScpDevice.RegisterNotify(Handle, UsbDs3.DeviceClassGuid, ref m_Ds3Notify); ScpDevice.RegisterNotify(Handle, UsbDs4.DeviceClassGuid, ref m_Ds4Notify); ScpDevice.RegisterNotify(Handle, BthDongle.DeviceClassGuid, ref m_BthNotify); ScpDevice.RegisterNotify(Handle, UsbGenericGamepad.DeviceClassGuid, ref _genericNotify); Log.DebugFormat("++ {0} [{1}]", Assembly.GetExecutingAssembly().Location, Assembly.GetExecutingAssembly().GetName().Version); tmrUpdate.Enabled = true; btnStart_Click(sender, e); } private void Form_Close(object sender, FormClosingEventArgs e) { rootHub.Close(); if (m_Ds3Notify != IntPtr.Zero) ScpDevice.UnregisterNotify(m_Ds3Notify); if (m_Ds4Notify != IntPtr.Zero) ScpDevice.UnregisterNotify(m_Ds4Notify); if (m_BthNotify != IntPtr.Zero) ScpDevice.UnregisterNotify(m_BthNotify); if (_genericNotify != IntPtr.Zero) ScpDevice.UnregisterNotify(_genericNotify); } private void btnStart_Click(object sender, EventArgs e) { try { if (rootHub.Open() && rootHub.Start()) { btnStart.Enabled = false; btnStop.Enabled = true; } } catch (RootHubAlreadyStartedException rhex) { Log.Fatal(rhex.Message); MessageBox.Show(rhex.Message, "Error starting server", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void btnStop_Click(object sender, EventArgs e) { if (rootHub.Stop()) { btnStart.Enabled = true; btnStop.Enabled = false; } } private void btnClear_Click(object sender, EventArgs e) { lvDebug.Items.Clear(); } private void btnMotor_Click(object sender, EventArgs e) { var Target = (Button) sender; byte Left = 0x00, Right = 0x00; if (Target == btnBoth) { Left = 0xFF; Right = 0xFF; } else if (Target == btnLeft) Left = 0xFF; else if (Target == btnRight) Right = 0xFF; for (var Index = 0; Index < 4; Index++) { if (Pad[Index].Enabled && Pad[Index].Checked) { rootHub.Pads[Index].Rumble(Left, Right); } } } private void btnPair_Click(object sender, EventArgs e) { for (var Index = 0; Index < Pad.Length; Index++) { if (Pad[Index].Checked) { rootHub.Pads[Index].Pair(rootHub.BluetoothHostAddress); break; } } } protected void btnDisconnect_Click(object sender, EventArgs e) { for (var index = 0; index < Pad.Length; index++) { if (Pad[index].Checked) { rootHub.Pads[index].Disconnect(); break; } } } protected void btnSuspend_Click(object sender, EventArgs e) { rootHub.Suspend(); } protected void btnResume_Click(object sender, EventArgs e) { rootHub.Resume(); } protected override void WndProc(ref Message m) { try { if (m.Msg == ScpDevice.WM_DEVICECHANGE) { var type = m.WParam.ToInt32(); switch (type) { case ScpDevice.DBT_DEVICEARRIVAL: case ScpDevice.DBT_DEVICEQUERYREMOVE: case ScpDevice.DBT_DEVICEREMOVECOMPLETE: ScpDevice.DEV_BROADCAST_HDR hdr; hdr = (ScpDevice.DEV_BROADCAST_HDR) Marshal.PtrToStructure(m.LParam, typeof (ScpDevice.DEV_BROADCAST_HDR)); if (hdr.dbch_devicetype == ScpDevice.DBT_DEVTYP_DEVICEINTERFACE) { ScpDevice.DEV_BROADCAST_DEVICEINTERFACE_M deviceInterface; deviceInterface = (ScpDevice.DEV_BROADCAST_DEVICEINTERFACE_M) Marshal.PtrToStructure(m.LParam, typeof (ScpDevice.DEV_BROADCAST_DEVICEINTERFACE_M)); var Class = "{" + new Guid(deviceInterface.dbcc_classguid).ToString().ToUpper() + "}"; var path = new string(deviceInterface.dbcc_name); path = path.Substring(0, path.IndexOf('\0')).ToUpper(); rootHub.Notify((ScpDevice.Notified) type, Class, path); } break; } } } catch (Exception ex) { Log.ErrorFormat("Unexpected error while processing window messages: {0}", ex); } base.WndProc(ref m); } private void tmrUpdate_Tick(object sender, EventArgs e) { bool bSelected = false, bDisconnect = false, bPair = false; lblHost.Text = rootHub.Dongle; lblHost.Enabled = btnStop.Enabled; for (var index = 0; index < Pad.Length; index++) { Pad[index].Text = rootHub.Pads[index].ToString(); Pad[index].Enabled = rootHub.Pads[index].State == DsState.Connected; Pad[index].Checked = Pad[index].Enabled && Pad[index].Checked; bSelected = bSelected || Pad[index].Checked; bDisconnect = bDisconnect || rootHub.Pads[index].Connection == DsConnection.Bluetooth; bPair = bPair || (Pad[index].Checked && rootHub.Pads[index].Connection == DsConnection.Usb && rootHub.BluetoothHostAddress != null && !rootHub.BluetoothHostAddress.Equals(rootHub.Pads[index].HostAddress)); } btnBoth.Enabled = btnLeft.Enabled = btnRight.Enabled = btnOff.Enabled = bSelected && btnStop.Enabled; btnPair.Enabled = bPair && bSelected && btnStop.Enabled && rootHub.Pairable; btnClear.Enabled = lvDebug.Items.Count > 0; } private void lvDebug_Enter(object sender, EventArgs e) { ThemeUtil.UpdateFocus(lvDebug.Handle); } private void Button_Enter(object sender, EventArgs e) { ThemeUtil.UpdateFocus(((Button) sender).Handle); } } }