diff --git a/TabletDriverService/CommandHandler.Filters.cpp b/TabletDriverService/CommandHandler.Filters.cpp
index 1cc755a..050878c 100644
--- a/TabletDriverService/CommandHandler.Filters.cpp
+++ b/TabletDriverService/CommandHandler.Filters.cpp
@@ -330,6 +330,30 @@ void CommandHandler::CreateFilterCommands() {
}));
+ // Command: ButtonFix, ButtonFix
+ //
+ // Sets ButtonFix filter parameters
+ //
+ AddAlias("ButtonFix", "ButtonFixAdd");
+ AddCommand(new Command("ButtonFixAdd", [&](CommandLine* cmd) {
+
+ // Tablet valid?
+ if (!ExecuteCommand("TabletValid")) return false;
+
+ std::string stringValue = cmd->GetStringLower(0, "");
+
+ // Off / False
+ if (stringValue == "off" || stringValue == "false") {
+ tablet->buttonFix.isEnabled = false;
+ LOG_INFO("Button Fix = off\n");
+ }
+ else {
+ tablet->buttonFix.isEnabled = true;
+ LOG_INFO("Button Fix = on\n");
+ }
+ return true;
+ }));
+
//
// Command: FilterTimerInterval, TimerInterval, Interval
diff --git a/TabletDriverService/Tablet.cpp b/TabletDriverService/Tablet.cpp
index 8533b09..4cfadcd 100644
--- a/TabletDriverService/Tablet.cpp
+++ b/TabletDriverService/Tablet.cpp
@@ -59,9 +59,10 @@ Tablet::Tablet() {
filterTimedCount = 3;
// Report filters
- filterReport[0] = &antiSmoothing;
- filterReport[1] = &noiseFilter;
- filterReportCount = 2;
+ filterReport[0] = &buttonFix;
+ filterReport[1] = &antiSmoothing;
+ filterReport[2] = &noiseFilter;
+ filterReportCount = 3;
// Tablet connection open
isOpen = false;
diff --git a/TabletDriverService/Tablet.h b/TabletDriverService/Tablet.h
index 6af8e74..5648495 100644
--- a/TabletDriverService/Tablet.h
+++ b/TabletDriverService/Tablet.h
@@ -17,6 +17,7 @@
#include "TabletFilterNoiseReduction.h"
#include "TabletFilterAntiSmoothing.h"
#include "TabletFilterPeak.h"
+#include "TabletFilterButtonFix.h"
#include "TabletMeasurement.h"
#include "DataFormatter.h"
@@ -164,6 +165,7 @@ class Tablet {
TabletFilterNoiseReduction noiseFilter;
TabletFilterAntiSmoothing antiSmoothing;
TabletFilterGravity gravityFilter;
+ TabletFilterButtonFix buttonFix;
// Timed filters
TabletFilter *filterTimed[10];
diff --git a/TabletDriverService/TabletDriverService.vcxproj b/TabletDriverService/TabletDriverService.vcxproj
index c4523c7..0dc7035 100644
--- a/TabletDriverService/TabletDriverService.vcxproj
+++ b/TabletDriverService/TabletDriverService.vcxproj
@@ -190,6 +190,7 @@
+
@@ -239,6 +240,7 @@
+
diff --git a/TabletDriverService/TabletDriverService.vcxproj.filters b/TabletDriverService/TabletDriverService.vcxproj.filters
index f1aa145..55afb2b 100644
--- a/TabletDriverService/TabletDriverService.vcxproj.filters
+++ b/TabletDriverService/TabletDriverService.vcxproj.filters
@@ -144,6 +144,9 @@
Header Files
+
+ Header Files
+
@@ -289,6 +292,9 @@
Source Files
+
+
+ Source Files
diff --git a/TabletDriverService/TabletFilterButtonFix.cpp b/TabletDriverService/TabletFilterButtonFix.cpp
new file mode 100644
index 0000000..8c9b56d
--- /dev/null
+++ b/TabletDriverService/TabletFilterButtonFix.cpp
@@ -0,0 +1,72 @@
+#include "precompiled.h"
+#include "TabletFilterButtonFix.h"
+
+
+#define LOG_MODULE "ButtonFix"
+#include "Logger.h"
+
+
+//
+// Constructor
+//
+TabletFilterButtonFix::TabletFilterButtonFix() {
+ ignoreInvalidReports = 0;
+ outputPosition = &outputState.position;
+}
+
+//
+// Destructor
+//
+TabletFilterButtonFix::~TabletFilterButtonFix() {
+}
+
+
+//
+// Set target
+//
+void TabletFilterButtonFix::SetTarget(TabletState* tabletState) {
+ latestTarget.Set(tabletState->position);
+ memcpy(&this->tabletState, tabletState, sizeof(TabletState));
+ memcpy(&outputState, tabletState, sizeof(TabletState));
+}
+
+
+//
+// Update filter
+//
+void TabletFilterButtonFix::Update() {
+ //
+ // Invalid position data detection.
+ // Some tablets do send invalid/broken data when buttons are released
+ //
+
+ if (tabletState.buttons <= 1 && oldTabletState.buttons > 1 && ignoreInvalidReports == 0) {
+ //LOG_INFO("RELEASE\n");
+ tabletState.pressure = oldTabletState.pressure;
+ tabletState.inputPressure = oldTabletState.inputPressure;
+ if (oldTabletState.buttons == 5 || oldTabletState.buttons == 3)
+ tabletState.buttons = 1;
+ ignoreInvalidReports = 2;
+ oldTarget.Set(latestTarget);
+ memcpy(&this->oldTabletState, &this->tabletState, sizeof(TabletState));
+ return;
+ }
+ else if (oldTabletState.buttons <= 1 && tabletState.buttons > 1 && ignoreInvalidReports == 0) {
+ //LOG_INFO("PRESS\n");
+ oldTabletState.buttons = tabletState.buttons;
+ ignoreInvalidReports = 2;
+ }
+ if (ignoreInvalidReports == 0) {
+ // Update old values
+ oldTarget.Set(latestTarget);
+ memcpy(&this->oldTabletState, &this->tabletState, sizeof(TabletState));
+ }
+ else {
+ oldTabletState.time = tabletState.time;
+ tabletState = oldTabletState;
+ // TODO: extrapolate a new coordinate
+ outputPosition->Set(oldTarget);
+ ignoreInvalidReports--;
+ }
+}
+
diff --git a/TabletDriverService/TabletFilterButtonFix.h b/TabletDriverService/TabletFilterButtonFix.h
new file mode 100644
index 0000000..8c4e2df
--- /dev/null
+++ b/TabletDriverService/TabletFilterButtonFix.h
@@ -0,0 +1,23 @@
+#pragma once
+#include "TabletFilter.h"
+
+class TabletFilterButtonFix : public TabletFilter {
+private:
+ int ignoreInvalidReports;
+
+public:
+ Vector2D latestTarget;
+ Vector2D oldTarget;
+ Vector2D* outputPosition;
+
+ TabletState tabletState;
+ TabletState oldTabletState;
+
+ void SetTarget(TabletState* tabletState);
+ void Update();
+
+ TabletFilterButtonFix();
+ ~TabletFilterButtonFix();
+
+};
+