Merge pull request #904 from IceStormNG/asus-mouse-support

Asus mouse fixes
This commit is contained in:
Serge
2023-07-26 21:09:30 +02:00
committed by GitHub
3 changed files with 99 additions and 25 deletions

View File

@@ -51,8 +51,6 @@ namespace GHelper
Shown += AsusMouseSettings_Shown; Shown += AsusMouseSettings_Shown;
FormClosing += AsusMouseSettings_FormClosing; FormClosing += AsusMouseSettings_FormClosing;
mouse.Disconnect += Mouse_Disconnect;
mouse.BatteryUpdated += Mouse_BatteryUpdated;
comboProfile.DropDownClosed += ComboProfile_DropDownClosed; comboProfile.DropDownClosed += ComboProfile_DropDownClosed;
sliderDPI.ValueChanged += SliderDPI_ValueChanged; sliderDPI.ValueChanged += SliderDPI_ValueChanged;
@@ -83,19 +81,40 @@ namespace GHelper
comboBoxAutoPowerOff.DropDownClosed += ComboBoxAutoPowerOff_DropDownClosed; comboBoxAutoPowerOff.DropDownClosed += ComboBoxAutoPowerOff_DropDownClosed;
InitMouseCapabilities(); InitMouseCapabilities();
RefreshMouseData(); Logger.WriteLine(mouse.GetDisplayName() + " (GUI): Initialized capabilities. Synchronizing mouse data");
Task task = Task.Run((Action)RefreshMouseData);
} }
private void AsusMouseSettings_FormClosing(object? sender, FormClosingEventArgs e) private void AsusMouseSettings_FormClosing(object? sender, FormClosingEventArgs e)
{ {
mouse.BatteryUpdated -= Mouse_BatteryUpdated; mouse.BatteryUpdated -= Mouse_BatteryUpdated;
mouse.Disconnect -= Mouse_Disconnect; mouse.Disconnect -= Mouse_Disconnect;
mouse.MouseReadyChanged -= Mouse_MouseReadyChanged;
}
private void Mouse_MouseReadyChanged(object? sender, EventArgs e)
{
if (!mouse.IsDeviceReady)
{
this.Invoke(delegate
{
if (Disposing || IsDisposed)
{
return;
}
Close();
});
}
} }
private void Mouse_BatteryUpdated(object? sender, EventArgs e) private void Mouse_BatteryUpdated(object? sender, EventArgs e)
{ {
this.Invoke(delegate this.Invoke(delegate
{ {
if (Disposing || IsDisposed)
{
return;
}
VisualizeBatteryState(); VisualizeBatteryState();
}); });
@@ -104,7 +123,7 @@ namespace GHelper
private void ComboProfile_DropDownClosed(object? sender, EventArgs e) private void ComboProfile_DropDownClosed(object? sender, EventArgs e)
{ {
mouse.SetProfile(comboProfile.SelectedIndex); mouse.SetProfile(comboProfile.SelectedIndex);
RefreshMouseData(); Task task = Task.Run((Action)RefreshMouseData);
} }
private void ComboBoxPollingRate_DropDownClosed(object? sender, EventArgs e) private void ComboBoxPollingRate_DropDownClosed(object? sender, EventArgs e)
@@ -194,6 +213,11 @@ namespace GHelper
private void ComboBoxLightingMode_DropDownClosed(object? sender, EventArgs e) private void ComboBoxLightingMode_DropDownClosed(object? sender, EventArgs e)
{ {
if (!mouse.HasRGB())
{
return;
}
LightingMode lm = supportedLightingModes[comboBoxLightingMode.SelectedIndex]; LightingMode lm = supportedLightingModes[comboBoxLightingMode.SelectedIndex];
LightingSetting? ls = mouse.LightingSetting; LightingSetting? ls = mouse.LightingSetting;
@@ -308,6 +332,10 @@ namespace GHelper
//Mouse disconnected. Bye bye. //Mouse disconnected. Bye bye.
this.Invoke(delegate this.Invoke(delegate
{ {
if (Disposing || IsDisposed)
{
return;
}
this.Close(); this.Close();
}); });
@@ -316,8 +344,11 @@ namespace GHelper
private void RefreshMouseData() private void RefreshMouseData()
{ {
mouse.SynchronizeDevice(); mouse.SynchronizeDevice();
Logger.WriteLine(mouse.GetDisplayName() + " (GUI): Mouse data synchronized");
if (!mouse.IsDeviceReady) if (!mouse.IsDeviceReady)
{ {
Logger.WriteLine(mouse.GetDisplayName() + " (GUI): Mouse is not ready. Closing view.");
this.Invoke(delegate this.Invoke(delegate
{ {
this.Close(); this.Close();
@@ -325,9 +356,11 @@ namespace GHelper
return; return;
} }
this.Invoke(delegate
VisualizeMouseSettings(); {
VisualizeBatteryState(); VisualizeMouseSettings();
VisualizeBatteryState();
});
} }
private void InitMouseCapabilities() private void InitMouseCapabilities()
@@ -586,20 +619,24 @@ namespace GHelper
private void VisualizeDPIButtons() private void VisualizeDPIButtons()
{ {
if (mouse.HasDPIColors()) for (int i = 0; i < mouse.DPIProfileCount() && i < 4; ++i)
{ {
for (int i = 0; i < mouse.DPIProfileCount() && i < 4; ++i) AsusMouseDPI dpi = mouse.DpiSettings[i];
if (dpi is null)
{ {
AsusMouseDPI dpi = mouse.DpiSettings[i]; continue;
dpiButtons[i].Image = ControlHelper.TintImage(Properties.Resources.lighting_dot_24, dpi.Color);
dpiButtons[i].Activated = (mouse.DpiProfile - 1) == i;
dpiButtons[i].BorderColor = dpi.Color;
dpiButtons[i].Text = "DPI " + (i + 1) + "\n" + dpi.DPI;
} }
if (mouse.HasDPIColors())
{
dpiButtons[i].Image = ControlHelper.TintImage(Properties.Resources.lighting_dot_24, dpi.Color);
dpiButtons[i].BorderColor = dpi.Color;
}
dpiButtons[i].Activated = (mouse.DpiProfile - 1) == i;
dpiButtons[i].Text = "DPI " + (i + 1) + "\n" + dpi.DPI;
} }
} }
private void VisualizeCurrentDPIProfile() private void VisualizeCurrentDPIProfile()
{ {
AsusMouseDPI dpi = mouse.DpiSettings[mouse.DpiProfile - 1]; AsusMouseDPI dpi = mouse.DpiSettings[mouse.DpiProfile - 1];
@@ -620,11 +657,16 @@ namespace GHelper
} }
Left = Program.settingsForm.Left - Width - 5; Left = Program.settingsForm.Left - Width - 5;
mouse.Disconnect += Mouse_Disconnect;
mouse.BatteryUpdated += Mouse_BatteryUpdated;
mouse.MouseReadyChanged += Mouse_MouseReadyChanged;
} }
private void ButtonSync_Click(object sender, EventArgs e) private void ButtonSync_Click(object sender, EventArgs e)
{ {
RefreshMouseData(); Task task = Task.Run((Action)RefreshMouseData);
} }
} }
} }

View File

@@ -102,15 +102,32 @@ namespace GHelper.Peripherals.Mouse
public abstract class AsusMouse : Device, IPeripheral public abstract class AsusMouse : Device, IPeripheral
{ {
private static string[] POLLING_RATES = { "125 Hz", "250 Hz", "500 Hz", "1000 Hz", "2000 Hz", "4000 Hz", "8000 Hz", "16000 Hz" }; private static string[] POLLING_RATES = { "125 Hz", "250 Hz", "500 Hz", "1000 Hz", "2000 Hz", "4000 Hz", "8000 Hz", "16000 Hz" };
internal const bool PACKET_LOGGER_ALWAYS_ON = false;
internal const int ASUS_MOUSE_PACKET_SIZE = 65; internal const int ASUS_MOUSE_PACKET_SIZE = 65;
public event EventHandler? Disconnect; public event EventHandler? Disconnect;
public event EventHandler? BatteryUpdated; public event EventHandler? BatteryUpdated;
public event EventHandler? MouseReadyChanged;
private readonly string path; private readonly string path;
public bool IsDeviceReady { get; protected set; } public bool IsDeviceReady { get; protected set; }
private void SetDeviceReady(bool ready)
{
bool notify = false;
if (IsDeviceReady != ready)
{
notify = true;
}
IsDeviceReady = ready;
if (MouseReadyChanged is not null && notify)
{
MouseReadyChanged(this, EventArgs.Empty);
}
}
public bool Wireless { get; protected set; } public bool Wireless { get; protected set; }
public int Battery { get; protected set; } public int Battery { get; protected set; }
public bool Charging { get; protected set; } public bool Charging { get; protected set; }
@@ -161,6 +178,7 @@ namespace GHelper.Peripherals.Mouse
public override void Dispose() public override void Dispose()
{ {
Logger.WriteLine(GetDisplayName() + ": Disposing");
HidSharp.DeviceList.Local.Changed -= Device_Changed; HidSharp.DeviceList.Local.Changed -= Device_Changed;
base.Dispose(); base.Dispose();
} }
@@ -200,6 +218,7 @@ namespace GHelper.Peripherals.Mouse
protected virtual void OnDisconnect() protected virtual void OnDisconnect()
{ {
Logger.WriteLine(GetDisplayName() + ": OnDisconnect()");
if (Disconnect is not null) if (Disconnect is not null)
{ {
Disconnect(this, EventArgs.Empty); Disconnect(this, EventArgs.Empty);
@@ -212,7 +231,7 @@ namespace GHelper.Peripherals.Mouse
return true; return true;
#else #else
return AppConfig.Get("usb_packet_logger") == 1; return AppConfig.Get("usb_packet_logger") == 1 || PACKET_LOGGER_ALWAYS_ON;
#endif #endif
} }
@@ -269,10 +288,10 @@ namespace GHelper.Peripherals.Mouse
{ {
//Likely only the dongle connected and the mouse is either sleeping or turned off. //Likely only the dongle connected and the mouse is either sleeping or turned off.
//The mouse will not respond with proper data, but empty responses at this point //The mouse will not respond with proper data, but empty responses at this point
IsDeviceReady = false; SetDeviceReady(false);
return; return;
} }
IsDeviceReady = true; SetDeviceReady(true);
ReadProfile(); ReadProfile();
ReadDPI(); ReadDPI();
@@ -378,7 +397,13 @@ namespace GHelper.Peripherals.Mouse
Charging = ParseChargingState(response); Charging = ParseChargingState(response);
//If the device goes to standby it will not report battery state anymore. //If the device goes to standby it will not report battery state anymore.
IsDeviceReady = Battery > 0; SetDeviceReady(Battery > 0);
if (!IsDeviceReady)
{
Logger.WriteLine(GetDisplayName() + ": Device gone");
return;
}
Logger.WriteLine(GetDisplayName() + ": Got Battery Percentage " + Battery + "% - Charging:" + Charging); Logger.WriteLine(GetDisplayName() + ": Got Battery Percentage " + Battery + "% - Charging:" + Charging);
@@ -400,7 +425,9 @@ namespace GHelper.Peripherals.Mouse
if (HasLowBatteryWarning() || HasAutoPowerOff()) if (HasLowBatteryWarning() || HasAutoPowerOff())
{ {
Logger.WriteLine(GetDisplayName() + ": Got Auto Power Off: " + PowerOffSetting + " - Low Battery Warnning at: " + LowBatteryWarning + "%"); string pos = HasAutoPowerOff() ? PowerOffSetting.ToString() : "Not Supported";
string lbw = HasLowBatteryWarning() ? LowBatteryWarning.ToString() : "Not Supported";
Logger.WriteLine(GetDisplayName() + ": Got Auto Power Off: " + pos + " - Low Battery Warnning at: " + lbw + "%");
} }
} }
@@ -683,6 +710,11 @@ namespace GHelper.Peripherals.Mouse
} }
protected virtual byte[] GetChangeDPIProfilePacket(int profile) protected virtual byte[] GetChangeDPIProfilePacket(int profile)
{
return new byte[] { 0x00, 0x51, 0x31, 0x0A, 0x00, (byte)profile };
}
protected virtual byte[] GetChangeDPIProfilePacket2(int profile)
{ {
return new byte[] { 0x00, 0x51, 0x31, 0x09, 0x00, (byte)profile }; return new byte[] { 0x00, 0x51, 0x31, 0x09, 0x00, (byte)profile };
} }
@@ -703,6 +735,8 @@ namespace GHelper.Peripherals.Mouse
//The first DPI profile is 1 //The first DPI profile is 1
WriteForResponse(GetChangeDPIProfilePacket(profile)); WriteForResponse(GetChangeDPIProfilePacket(profile));
//For whatever reason that is required or the mouse will not store the change and reverts once you power it off.
WriteForResponse(GetChangeDPIProfilePacket2(profile));
FlushSettings(); FlushSettings();
Logger.WriteLine(GetDisplayName() + ": DPI Profile set to " + profile); Logger.WriteLine(GetDisplayName() + ": DPI Profile set to " + profile);

View File

@@ -1096,13 +1096,11 @@ namespace GHelper
{ {
b.Text = m.GetDisplayName() + "\n" + m.Battery + "%" b.Text = m.GetDisplayName() + "\n" + m.Battery + "%"
+ (m.Charging ? "(" + Properties.Strings.Charging + ")" : ""); + (m.Charging ? "(" + Properties.Strings.Charging + ")" : "");
b.Enabled = true;
} }
else else
{ {
//Mouse is either not connected or in standby //Mouse is either not connected or in standby
b.Text = m.GetDisplayName() + "\n(" + Properties.Strings.NotConnected + ")"; b.Text = m.GetDisplayName() + "\n(" + Properties.Strings.NotConnected + ")";
b.Enabled = false;
} }
switch (m.DeviceType()) switch (m.DeviceType())
@@ -1144,7 +1142,7 @@ namespace GHelper
if (iph.DeviceType() == PeripheralType.Mouse) if (iph.DeviceType() == PeripheralType.Mouse)
{ {
AsusMouse? am = iph as AsusMouse; AsusMouse? am = iph as AsusMouse;
if (am is null) if (am is null || !am.IsDeviceReady)
{ {
//Should not happen if all device classes are implemented correctly. But better safe than sorry. //Should not happen if all device classes are implemented correctly. But better safe than sorry.
return; return;