diff --git a/metadata/input-device.xml b/metadata/input-device.xml
index 63ed6769b..54a8f45f4 100644
--- a/metadata/input-device.xml
+++ b/metadata/input-device.xml
@@ -5,5 +5,8 @@
+
diff --git a/src/core/seat/input-manager.cpp b/src/core/seat/input-manager.cpp
index e007fc4fc..1c81a414a 100644
--- a/src/core/seat/input-manager.cpp
+++ b/src/core/seat/input-manager.cpp
@@ -55,6 +55,40 @@ void wf::input_manager_t::handle_new_input(wlr_input_device *dev)
configure_input_devices();
}
+void wf::input_manager_t::calibrate_touch_device(wlr_input_device *dev, std::string const & cal)
+{
+ if (!wlr_input_device_is_libinput(dev) || (dev->type != WLR_INPUT_DEVICE_TOUCH))
+ {
+ return;
+ }
+
+ float m[6];
+ auto libinput_dev = wlr_libinput_get_device_handle(dev);
+ if (sscanf(cal.c_str(), "%f %f %f %f %f %f",
+ &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) == 6)
+ {
+ enum libinput_config_status status;
+
+ status = libinput_device_config_calibration_set_matrix(libinput_dev, m);
+ if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
+ {
+ LOGE("Failed to apply calibration for ", nonull(dev->name));
+ LOGE(" ", m[0], " ", m[1], " ", m[2], " ", m[3], " ", m[4], " ", m[5]);
+ } else
+ {
+ LOGI("Calibrated input device successfully: ", nonull(dev->name));
+ LOGI(" ", m[0], " ", m[1], " ", m[2], " ", m[3], " ", m[4], " ", m[5]);
+ }
+ } else
+ {
+ LOGE("Incorrect calibration configuration for ", nonull(dev->name));
+ LOGI("Setting default matrix calibration: ");
+ libinput_device_config_calibration_get_default_matrix(libinput_dev, m);
+ LOGI(" ", m[0], " ", m[1], " ", m[2], " ", m[3], " ", m[4], " ", m[5]);
+ libinput_device_config_calibration_set_matrix(libinput_dev, m);
+ }
+}
+
void wf::input_manager_t::configure_input_device(wlr_input_device *dev)
{
auto cursor = wf::get_core().get_wlr_cursor();
@@ -78,6 +112,12 @@ void wf::input_manager_t::configure_input_device(wlr_input_device *dev)
}
}
+ auto cal = section->get_option("calibration")->get_value_str();
+ if (!cal.empty())
+ {
+ calibrate_touch_device(dev, cal);
+ }
+
auto wo = wf::get_core().output_layout->find_output(mapped_output);
if (wo)
{
diff --git a/src/core/seat/input-manager.hpp b/src/core/seat/input-manager.hpp
index a0b899b78..b79ddde01 100644
--- a/src/core/seat/input-manager.hpp
+++ b/src/core/seat/input-manager.hpp
@@ -49,6 +49,12 @@ class input_manager_t
*/
void configure_input_devices();
+ /**
+ * Calibrate a touch device with a matrix. This function does nothing
+ * if called with a device that is not a touch device.
+ */
+ void calibrate_touch_device(wlr_input_device *dev, std::string const & cal);
+
input_manager_t();
~input_manager_t() = default;