Mir

Merge lp:~andreas-pokorny/mir/contact-info-as-extension into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 4159
Proposed branch: lp:~andreas-pokorny/mir/contact-info-as-extension
Merge into: lp:mir
Diff against target: 153 lines (+74/-10)
3 files modified
src/platforms/evdev/libinput_device.cpp (+65/-4)
src/platforms/evdev/libinput_device.h (+3/-0)
tests/mir_test_doubles/mock_libinput.cpp (+6/-6)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/contact-info-as-extension
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Daniel van Vugt Approve
Review via email: mp+323410@code.launchpad.net

Commit message

Allow the evdev platform to run on non-Ubuntu systems.

The Ubuntu version of libinput provides additional symbols, allowing to
access touch information. This is an intermediate solution until the
patch to libinput gets accepted upstream.

Description of the change

This loads the touch contact functions via dlsym - so evdev platform will compile and run on fedora or debian.

This is only meant as an intermediate step until the change in libinput gets upstreamed.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Sounds like a plan...

(1) This is a bit weird though:
  dladdr(dlsym(nullptr, "main"), &exec_info);
Why not use dlsym(RTLD_DEFAULT, "libinput_event_touch_get_major_transformed") to search the current process instead? You shouldn't need the Dl_info either... Just search for the functions using RTLD_DEFAULT.
  Alternatively, just provide a raw implementation of the relevant functions, and check to see if there is a (second) system-provided version to use by searching RTLD_NEXT.

(2) Why would the fallback touch_major and touch_minor functions return different values?

review: Needs Fixing
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

> Sounds like a plan...
>
> (1) This is a bit weird though:
> dladdr(dlsym(nullptr, "main"), &exec_info);
> Why not use dlsym(RTLD_DEFAULT, "libinput_event_touch_get_major_transformed")
> to search the current process instead? You shouldn't need the Dl_info
> either... Just search for the functions using RTLD_DEFAULT.
> Alternatively, just provide a raw implementation of the relevant functions,
> and check to see if there is a (second) system-provided version to use by
> searching RTLD_NEXT.

Hmm ok I have not thought about that. I think the latter would fail because of mock_libinput.cpp. Will try the former now..

> (2) Why would the fallback touch_major and touch_minor functions return
> different values?

Usually the larger diameter is returned via major and the small diameter with touch minor.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

OK, thanks.

I don't think the template function is necessary but it's not so important. I would have just made a lookup table:

typedef void (*FunPtr)();
static const struct
{
    char const* name;
    FunPtr* ptr;
} fun[] =
{
    {"libinput_event_touch_get_major_transformed", (FunPtr*)&get_touch_major},
    ...
};

And then loop through the array, indirectly filling out the pointed-to function pointers.

review: Approve
Revision history for this message
Mir CI Bot (mir-ci-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/platforms/evdev/libinput_device.cpp'
--- src/platforms/evdev/libinput_device.cpp 2017-03-14 02:26:28 +0000
+++ src/platforms/evdev/libinput_device.cpp 2017-05-01 16:20:55 +0000
@@ -38,6 +38,7 @@
3838
39#include <libinput.h>39#include <libinput.h>
40#include <linux/input.h> // only used to get constants for input reports40#include <linux/input.h> // only used to get constants for input reports
41#include <dlfcn.h>
4142
42#include <boost/exception/diagnostic_information.hpp>43#include <boost/exception/diagnostic_information.hpp>
43#include <cstring>44#include <cstring>
@@ -50,8 +51,68 @@
50namespace mie = mi::evdev;51namespace mie = mi::evdev;
51using namespace std::literals::chrono_literals;52using namespace std::literals::chrono_literals;
5253
54namespace
55{
56double touch_major(libinput_event_touch*, uint32_t, uint32_t)
57{
58 return 8;
59}
60double touch_minor(libinput_event_touch*, uint32_t, uint32_t)
61{
62 return 6;
63}
64double pressure(libinput_event_touch*)
65{
66 return 0.8;
67}
68double orientation(libinput_event_touch*)
69{
70 return 0;
71}
72
73template<typename T> auto load_function(char const* sym)
74{
75 T result{};
76 dlerror();
77 (void*&)result = dlsym(RTLD_DEFAULT, sym);
78 char const *error = dlerror();
79
80 if (error)
81 throw std::runtime_error(error);
82 if (!result)
83 throw std::runtime_error("no valid function address");
84
85 return result;
86}
87}
88
89struct mie::LibInputDevice::ContactExtension
90{
91 ContactExtension()
92 {
93 constexpr const char touch_major_sym[] = "libinput_event_touch_get_major_transformed";
94 constexpr const char touch_minor_sym[] = "libinput_event_touch_get_minor_transformed";
95 constexpr const char orientation_sym[] = "libinput_event_touch_get_orientation";
96 constexpr const char pressure_sym[] = "libinput_event_touch_get_pressure";
97
98 try
99 {
100 get_touch_major = load_function<decltype(&touch_major)>(touch_major_sym);
101 get_touch_minor = load_function<decltype(&touch_minor)>(touch_minor_sym);
102 get_orientation = load_function<decltype(&orientation)>(orientation_sym);
103 get_pressure = load_function<decltype(&pressure)>(pressure_sym);
104 }
105 catch(...) {}
106 }
107
108 decltype(&touch_major) get_touch_major{&touch_major};
109 decltype(&touch_minor) get_touch_minor{&touch_minor};
110 decltype(&pressure) get_pressure{&pressure};
111 decltype(&orientation) get_orientation{&orientation};
112};
113
53mie::LibInputDevice::LibInputDevice(std::shared_ptr<mi::InputReport> const& report, LibInputDevicePtr dev)114mie::LibInputDevice::LibInputDevice(std::shared_ptr<mi::InputReport> const& report, LibInputDevicePtr dev)
54 : report{report}, pointer_pos{0, 0}, button_state{0}115 : contact_extension{std::make_unique<ContactExtension>()}, report{report}, pointer_pos{0, 0}, button_state{0}
55{116{
56 add_device_of_group(std::move(dev));117 add_device_of_group(std::move(dev));
57}118}
@@ -300,11 +361,11 @@
300 uint32_t height = info.output_size.height.as_int();361 uint32_t height = info.output_size.height.as_int();
301362
302 data.action = action;363 data.action = action;
303 data.pressure = libinput_event_touch_get_pressure(touch);
304 data.x = libinput_event_touch_get_x_transformed(touch, width);364 data.x = libinput_event_touch_get_x_transformed(touch, width);
305 data.y = libinput_event_touch_get_y_transformed(touch, height);365 data.y = libinput_event_touch_get_y_transformed(touch, height);
306 data.major = libinput_event_touch_get_major_transformed(touch, width, height);366 data.major = contact_extension->get_touch_major(touch, width, height);
307 data.minor = libinput_event_touch_get_minor_transformed(touch, width, height);367 data.minor = contact_extension->get_touch_minor(touch, width, height);
368 data.pressure = contact_extension->get_pressure(touch);
308369
309 info.transform_to_scene(data.x, data.y);370 info.transform_to_scene(data.x, data.y);
310}371}
311372
=== modified file 'src/platforms/evdev/libinput_device.h'
--- src/platforms/evdev/libinput_device.h 2017-03-20 11:46:27 +0000
+++ src/platforms/evdev/libinput_device.h 2017-05-01 16:20:55 +0000
@@ -81,6 +81,9 @@
81 bool is_output_active() const;81 bool is_output_active() const;
82 OutputInfo get_output_info() const;82 OutputInfo get_output_info() const;
8383
84 struct ContactExtension;
85 std::unique_ptr<ContactExtension> contact_extension;
86
84 std::shared_ptr<InputReport> report;87 std::shared_ptr<InputReport> report;
85 std::vector<LibInputDevicePtr> devices;88 std::vector<LibInputDevicePtr> devices;
8689
8790
=== modified file 'tests/mir_test_doubles/mock_libinput.cpp'
--- tests/mir_test_doubles/mock_libinput.cpp 2017-03-14 02:26:28 +0000
+++ tests/mir_test_doubles/mock_libinput.cpp 2017-05-01 16:20:55 +0000
@@ -278,32 +278,32 @@
278 return global_libinput->libinput_event_touch_get_y_transformed(event, height);278 return global_libinput->libinput_event_touch_get_y_transformed(event, height);
279}279}
280280
281double libinput_event_touch_get_major(libinput_event_touch* event)281extern "C" double libinput_event_touch_get_major(libinput_event_touch* event)
282{282{
283 return global_libinput->libinput_event_touch_get_major(event);283 return global_libinput->libinput_event_touch_get_major(event);
284}284}
285285
286double libinput_event_touch_get_minor(libinput_event_touch* event)286extern "C" double libinput_event_touch_get_minor(libinput_event_touch* event)
287{287{
288 return global_libinput->libinput_event_touch_get_minor(event);288 return global_libinput->libinput_event_touch_get_minor(event);
289}289}
290290
291double libinput_event_touch_get_major_transformed(libinput_event_touch* event, uint32_t width, uint32_t height)291extern "C" double libinput_event_touch_get_major_transformed(libinput_event_touch* event, uint32_t width, uint32_t height)
292{292{
293 return global_libinput->libinput_event_touch_get_major_transformed(event, width, height);293 return global_libinput->libinput_event_touch_get_major_transformed(event, width, height);
294}294}
295295
296double libinput_event_touch_get_minor_transformed(libinput_event_touch* event, uint32_t width, uint32_t height)296extern "C" double libinput_event_touch_get_minor_transformed(libinput_event_touch* event, uint32_t width, uint32_t height)
297{297{
298 return global_libinput->libinput_event_touch_get_minor_transformed(event, width, height);298 return global_libinput->libinput_event_touch_get_minor_transformed(event, width, height);
299}299}
300300
301double libinput_event_touch_get_pressure(libinput_event_touch* event)301extern "C" double libinput_event_touch_get_pressure(libinput_event_touch* event)
302{302{
303 return global_libinput->libinput_event_touch_get_pressure(event);303 return global_libinput->libinput_event_touch_get_pressure(event);
304}304}
305305
306double libinput_event_touch_get_orientation(libinput_event_touch* event)306extern "C" double libinput_event_touch_get_orientation(libinput_event_touch* event)
307{307{
308 return global_libinput->libinput_event_touch_get_orientation(event);308 return global_libinput->libinput_event_touch_get_orientation(event);
309}309}

Subscribers

People subscribed via source and target branches