Merge lp:~andreas-pokorny/mir/evdev-input-platform into lp:mir
- evdev-input-platform
- Merge into development-branch
Status: | Work in progress |
---|---|
Proposed branch: | lp:~andreas-pokorny/mir/evdev-input-platform |
Merge into: | lp:mir |
Diff against target: |
3273 lines (+2839/-12) 54 files modified
include/platform/mir/input/device_capability.h (+50/-0) include/platform/mir/input/input_device.h (+60/-0) include/platform/mir/input/input_device_registry.h (+49/-0) include/platform/mir/input/input_event_handler_register.h (+80/-0) include/platform/mir/input/input_report.h (+8/-4) include/platform/mir/input/input_sink.h (+43/-0) include/platform/mir/input/platform.h (+128/-0) platform-ABI-sha1sums (+7/-0) server-ABI-sha1sums (+7/-0) src/CMakeLists.txt (+4/-0) src/include/common/mir/find_best.h (+67/-0) src/include/common/mir/flags.h (+118/-0) src/platform/CMakeLists.txt (+2/-0) src/platforms/CMakeLists.txt (+13/-0) src/platforms/evdev/CMakeLists.txt (+24/-0) src/platforms/evdev/android_device_provider.cpp (+48/-0) src/platforms/evdev/android_device_provider.h (+42/-0) src/platforms/evdev/evdev_device_detection.cpp (+163/-0) src/platforms/evdev/evdev_device_detection.h (+35/-0) src/platforms/evdev/evdev_input_device_factory.cpp (+58/-0) src/platforms/evdev/evdev_input_device_factory.h (+52/-0) src/platforms/evdev/input_device_factory.h (+50/-0) src/platforms/evdev/input_device_provider.h (+59/-0) src/platforms/evdev/libinput_device_provider.cpp (+67/-0) src/platforms/evdev/libinput_device_provider.h (+42/-0) src/platforms/evdev/platform.cpp (+179/-0) src/platforms/evdev/platform.h (+69/-0) src/platforms/input-platform-symbols.map (+7/-0) src/server/report/logging/input_report.cpp (+18/-0) src/server/report/logging/input_report.h (+4/-0) src/server/report/lttng/input_report.cpp (+10/-0) src/server/report/lttng/input_report.h (+3/-0) src/server/report/lttng/input_report_tp.h (+19/-1) src/server/report/null/input_report.cpp (+8/-0) src/server/report/null/input_report.h (+3/-0) tests/include/mir_test_doubles/mock_input_device_registry.h (+46/-0) tests/include/mir_test_doubles/mock_input_event_handler_register.h (+62/-0) tests/include/mir_test_framework/executable_path.h (+2/-0) tests/mir_test_framework/CMakeLists.txt (+6/-0) tests/mir_test_framework/executable_path.cpp (+27/-0) tests/mir_test_framework/udev_recordings/joystick-detection.ioctl (+25/-0) tests/mir_test_framework/udev_recordings/joystick-detection.umockdev (+351/-0) tests/mir_test_framework/udev_recordings/mt-screen-detection.ioctl (+28/-0) tests/mir_test_framework/udev_recordings/mt-screen-detection.umockdev (+44/-0) tests/mir_test_framework/udev_recordings/synaptics-touchpad.ioctl (+0/-7) tests/unit-tests/CMakeLists.txt (+2/-0) tests/unit-tests/input/CMakeLists.txt (+1/-0) tests/unit-tests/input/evdev/CMakeLists.txt (+13/-0) tests/unit-tests/input/evdev/test_android_device_provider.cpp (+83/-0) tests/unit-tests/input/evdev/test_evdev_device_detection.cpp (+86/-0) tests/unit-tests/input/evdev/test_evdev_input_device_factory.cpp (+106/-0) tests/unit-tests/input/evdev/test_libinput_device_provider.cpp (+82/-0) tests/unit-tests/input/evdev/test_platform.cpp (+207/-0) tests/unit-tests/test_find_best.cpp (+72/-0) |
To merge this branch: | bzr merge lp:~andreas-pokorny/mir/evdev-input-platform |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | Needs Fixing | ||
Cemil Azizoglu (community) | Needs Resubmitting | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Robert Carr (community) | Needs Information | ||
Kevin DuBois (community) | Abstain | ||
Review via email: mp+243806@code.launchpad.net |
Commit message
Adds the first pieces of the evdev input platform.
Those include platform interfaces for dealing with added and removed devices, and sending input events into the system. Evdev device detection to decide which code base should be used for handling the event stream. The decision is made between the android input code already existing in mir and libinput. Many of the added tests make use of recorded umockdev files. This commit fixes empty ioctl return values from the recorded synaptic touch pad and adds a multi touch screen and a joystick to the devices.
The evdev input platform is not installed until the input parts of libmirserver are changed to make use of it.
Description of the change
This change adds the basic interfaces for having input platforms, and implements the framework for an evdev input platform. Several parts are still left out, and the input platform is not yet loaded by the DefaultServerCo
Relevant Interfaces:
* mir::input::Plaform - the entry point for the server to deal with a input platform
* mir::input:
* mir::input:
* mir::input:
* mir::input:
Those three interfaces above are part of the input mocking/stubbing story for acceptance testing the server or possible shells.
Follow up steps:
* libinput integration through the LibInputDeviceP
lp:~andreas-pokorny/mir/libinput-integration)
* similar integration of the EventHub/
* Smaller cleanup of EventHub and InputReader
- 2106. By Andreas Pokorny
-
typos
- 2107. By Andreas Pokorny
-
typo
- 2108. By Andreas Pokorny
-
renamed Multiplexer to InputEventHandl
erRegister - 2109. By Andreas Pokorny
-
last round of method renamings
Andreas Pokorny (andreas-pokorny) wrote : | # |
>
> 364 +extern "C" typedef std::unique_
> 153 + // add devie info here..
> typos
>
> 264 + std::initialize
> Fds should be mir::Fd to better manage the lifetime of the FD.
>
> 145 +class InputDevice
> class name doesnt make sense to me for what the group of functions is doing,
> but this might be a side effect of the "Multiplexer" naming comment.
>
> 349 + * The \a input_device_
> changes using the MainLoop \a loop.
> 350 + */
> 351 + virtual void start_monitor_
> std::shared_
> Does the comment need updating? MainLoop doesn't seem related
done - is the new naming good enough?
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
Here's a preliminary review. I'll have to re-review at some point more thoroughly.
33 +enum class DeviceClass : uint32_t
34 +{
35 + unknown = 0,
36 + cursor = 1<<1,
37 + keyboard = 1<<2,
38 + touchpad = 1<<3,
39 + touchscreen = 1<<4,
40 + gamepad = 1<<5,
41 + joystick = 1<<6,
42 + switch_ = 1<<7, // better name needed
43 + multitouch = 1<<8, // multitouch capable
44 + alpha_numeric = 1<<9 // enough keys for text entry
45 +};
This class is a bit strange in the sense that it includes both device class (keyboard, joystick, etc) and capability (multitouch, alpha_numeric, etc) entries. Not sure if it might cause problems later.
-------
161 + virtual void stop(InputEvent
Does this implicitly unregister the sink?
-------
279 + * \param owner a distinct value to identify the caller
perhaps s/distinct/unique? There are other instances.
-------
368 + * openning new device and register them at the servers InputDeviceRegi
s/openning/opening, s/servers/server's
-------
569 + return Priority:
Do we really support all the devices except touchpad under Android, or is this supposed to be "Priority:
-------
754 +
755 +
superfluous blank line.
-------
1123 + return Priority:
Ditto for libinput. According to the code we support everything but joystick, touchscreen and gamepad.
-------
1318 +void mie::Platform:
1319 +{
1320 +}
Should we at least print a warning?
-------
1459 +
1460 +
superfluous blank lines.
Kevin DuBois (kdub) wrote : | # |
Typos/names look addressed, still these though:
>
> 64 +++ include/
> this is the same interface as
> src/client/
>
> 264 + std::initialize
> Fds should be mir::Fd to better manage the lifetime of the FD.
Andreas Pokorny (andreas-pokorny) wrote : | # |
> Typos/names look addressed, still these though:
> >
> > 64 +++ include/
> > this is the same interface as
> > src/client/
We paused our discussion with unifying both interfaces to a single mir::EventSink vs mir::input:
> >
> > 264 + std::initialize
> > Fds should be mir::Fd to better manage the lifetime of the FD.
I would like to do that, but I implement that interface with our glib MainLoop implementation which currently does not use mir::Fd. On the caller/libinput side I could just keep the mir::Fd to not close the fd before the libinput context falls out of scope, but on the callee side I would need to do additional tracking to fulfill that interface.
Can we settle with doing that in a separate MP?
- 2110. By Andreas Pokorny
-
reverted some additional white space noise. Adopted the naming and ABI settings from lp:~raof/mir/server-platfrom-probing.
Because of that the integration test now also loads the library from file system instead of statically linked
Andreas Pokorny (andreas-pokorny) wrote : | # |
> Here's a preliminary review. I'll have to re-review at some point more
> thoroughly.
>
> 33 +enum class DeviceClass : uint32_t
> 34 +{
> 35 + unknown = 0,
> 36 + cursor = 1<<1,
> 37 + keyboard = 1<<2,
> 38 + touchpad = 1<<3,
> 39 + touchscreen = 1<<4,
> 40 + gamepad = 1<<5,
> 41 + joystick = 1<<6,
> 42 + switch_ = 1<<7, // better name needed
> 43 + multitouch = 1<<8, // multitouch capable
> 44 + alpha_numeric = 1<<9 // enough keys for text entry
> 45 +};
>
> This class is a bit strange in the sense that it includes both device class
> (keyboard, joystick, etc) and capability (multitouch, alpha_numeric, etc)
> entries. Not sure if it might cause problems later.
I took those value from android, they are supposed to replace the device detection code that currently lives inside eventhub.cpp. Maybe splitting those entries makes them more reasonable?
> -------
> 161 + virtual void stop(InputEvent
>
> Does this implicitly unregister the sink?
it expects the callee to no longer use the sink.
> -------
> 279 + * \param owner a distinct value to identify the caller
>
> perhaps s/distinct/unique? There are other instances.
> -------
> 368 + * openning new device and register them at the servers
> InputDeviceRegi
>
> s/openning/opening, s/servers/server's
> -------
> 569 + return Priority:
>
> Do we really support all the devices except touchpad under Android, or is this
> supposed to be "Priority:
Thats the impression i took from the input mappers. MirEvent on the other hand isnt that complete, which MirEvent-2 hopefully resolves.
> -------
> 754 +
> 755 +
>
> superfluous blank line.
> -------
> 1123 + return Priority:
>
> Ditto for libinput. According to the code we support everything but joystick,
> touchscreen and gamepad.
After you pointed that out I reconsidered and took a more conservative approach. The event model inside libinput only supports those cursor/
> -------
> 1318 +void mie::Platform:
> 1319 +{
> 1320 +}
>
> Should we at least print a warning?
I am not sure yet about the semantics of that udev event.
Kevin DuBois (kdub) wrote : | # |
> > Typos/names look addressed, still these though:
> > >
> > > 64 +++ include/
> > > this is the same interface as
> > > src/client/
>
> We paused our discussion with unifying both interfaces to a single
> mir::EventSink vs mir::input:
Abstaining until we figure out why we need the 3rd interface named EventSink in the codebase :)
> > > 264 + std::initialize
> > > Fds should be mir::Fd to better manage the lifetime of the FD.
>
> I would like to do that, but I implement that interface with our glib MainLoop
> implementation which currently does not use mir::Fd. On the caller/libinput
> side I could just keep the mir::Fd to not close the fd before the libinput
> context falls out of scope, but on the callee side I would need to do
> additional tracking to fulfill that interface.
>
> Can we settle with doing that in a separate MP?
sure, although a comment or wishlist-bug would help us remember to do it later
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2110
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Robert Carr (robertcarr) wrote : | # |
InputEventHandl
I'm a little surprised by InputDevice:
Andreas Pokorny (andreas-pokorny) wrote : | # |
> InputEventHandl
> InputDevice::start, what is an event sink vs. an event handler? perhaps
> PollProvider or something would be a better name.
But does it provide polling just because there might be epoll underneath?
It is an interface to register handlers for specific events - those events are currently: there is something to read at fd, and I just woke up (because you requested it)
> I'm a little surprised by InputDevice:
> since afaict we mostly use the opposite pattern. How did you arrive at this
> design?
Passing that via the contructor and that means through the creation method of the factory would have worked too. I found the approach presented here works similar and is more explicit since now the expectations of what an implementation should behave and use are connected to its interface. That is : use that interface to handle wakeups, provide the events through that interface...
- 2111. By Andreas Pokorny
-
merged lp:mir
- 2112. By Andreas Pokorny
-
Add input_ to the platform ABI
Otherwise it collides with the graphics platform symbols. Additional this change extracts a find_best algorithm and adds two reports.
- 2113. By Andreas Pokorny
-
* New upstream release 0.10.0 (https:/
/launchpad. net/mir/ +milestone/ 0.10.0)
- Enhancements:
. Added support for Android HWC 1.3 devices.
. Reduced build dependencies.
. Client API: Added version macros.
. demo-shell: Added desktop zoom feature (Super + mouse wheel).
. TODO - more
- ABI summary: Servers need rebuilding, but clients do not;
. Mirclient ABI unchanged at 8
. Mircommon ABI unchanged at 3
. Mirplatform ABI bumped to 5
. Mirserver ABI bumped to 28
- Bug fixes:
. TODO - fill this in just before release
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2113
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Robert Carr (robertcarr) wrote : | # |
I'm having trouble reviewing this since as it stands the bits aren't wired together...it would be nice if there were some minimum feature that could be come up with to make a test...or if we could come up with a testing input platform to replace usage of FakeEventHub...the requirements on such a platform may be able to prove the interfaces are sound.
Nonetheless mental model is starting to come together and ill try and finish review tomorrow.
- 2114. By Andreas Pokorny
-
merge lp:mir
- 2115. By Andreas Pokorny
-
moved evdev platform to platforms
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2114
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2115
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2116. By Andreas Pokorny
-
[ Daniel van Vugt ]
. Plumbing/preparation to support external displays on Android devices.
. Began work on automatic driver probing, to intelligently choose the
best driver for you.
. Demo shell (mir_proving_server) : Added desktop zoom feature using
Supermouse wheel.
. Demo renamed: mir_demo_server_ shell -> mir_proving_server
. Other demo servers merged into -> mir_demo_server
. Wider support for display buffer pixel formats in the mesa driver, for
wider hardware support.
. Performance: On mesa/desktop at least; only hold compositor buffers
for the duration of the render, instead of the duration of the frame.
Following this change the compositor report can now finally report
render time instead of frame time.
. Mir now starts reliably when a TV is connected by HDMI, and up to
4K resolution (2160p) is known to work.
. Plenty more enhancements logged in the bugs list below.
. [regression] Mir servers (since 0.9) randomly crash in malloc due to
heap corruption (LP: #1401488)
. USCmouse cursor on AMD graphics is drawing incorrectly
(LP: #1391975)
. Mir fails to start when a TV is connected by HDMI
[std::exception::what: Invalid or inconsistent display configuration]
(LP: #1395405)
. Input/event driven clients may freeze indefinitely (LP: #1396006)
. Mir server crashes with "std::exception::what: Failed to get front
buffer object" when trying to fullscreen a surface (LP: #1398296)
. Switching windows with a Trusted Prompt Session active loses the
trusted prompt session (LP: #1355173)
. CI test failure in multiple tests (LP: #1401364)
. dh_install: usr/bin/mir_demo_ server exists in debian/tmp but is not
installed to anywhere (LP: #1401365)
. [regression] demo-shell: Instead of moving surfaces they now fly
off-screen (LP: #1403702)
. [regression] Binaries are no longer runnable on other machines (or in
other directories) (LP: #1406073)
. [i865] unity-system-compositor fails to start: Failed to choose ARGB
EGL config (LP: #1212753)
. Mir's compositor holds buffers (blocking clients) for the duration of
the frame, even when not necessary. (LP: #1264934)
. Screen goes blank (black) briefly during display config changes which
don't affect the display mode (LP: #1274359)
. [enhancement] There should be a quit signal sent to sessions instead
of killing them directly (LP: #1304257)
. MirMotionEvent.action needs stronger typing (to MirMotionAction etc)
(LP: #1311699)
. CompositorReport as used by DefaultDisplayBufferCompositor can't
measure render time (LP: #1350716)
. Full screen (bypassed) surfaces (e.g. GLMark2Test) are missing frames
and appear to freeze or judder with swap interval 0 (LP: #1379685)
. Trusted prompts need to be part of the lifecycle (LP: #1384950)
. [testfail] BasicThreadPool.recycles_ threads in CI (LP: #1391488)
. acceptance_tests are too chatty (LP: #1394221)
. mir_connection_create_ surface callback is sometimes called twice on
error (LP: #1394873)
. File descriptor leaks in tests using UsingStubClientPlatform
(LP: #1395762)
. DisplayLayout resizes a surface to 1x1 if you ask it to fullscreen a
surface that's partially offscreen (LP: #1398294)
. Surfaces can consume input events before they're visible.
(LP: #1400218)
. dpkg-shlibdeps: Lots of warnings about libmirplatformstub.so
(LP: #1401373)
. Leaks in death tests can cause subsequent tests in the same process to
fail (LP: #1402160)
. [regression] lintian: E: mir-demos: binary-or-shlib- defines- rpath ...
(LP: #1406098)
. [regression] Mir utils can't run from the build tree any more
(LP: #1407557)
. fd reception code is not exeception-safe when unexpected numbers of
fds are received (LP: #1394362)
. Mir reports vertical refresh rates slightly inaccurately (LP: #1407558)
. [Enhancement] Add an API to lock surface orientation (LP: #1382209)
. Bootloop with system language Turkish on the Nexus 4 (LP: #1398984)
. Remove the implicit assumption that there every surface can be mapped
to an input handle. (LP: #1216727)
. When revealing hidden surfaces wait for them to become exposed before
sending events which we expect them to receive (LP: #1407783)
[ Ubuntu daily release ]
New rebuild forced
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2116
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2117. By Andreas Pokorny
-
* New upstream release 0.11.0 (https:/
/launchpad. net/mir/ +milestone/ 0.11.0)
- Enhancements:
. Lots more major plumbing in the Android code, on the path to supporting
external displays.
. Performance: Use optimally efficient fragment shading when possible.
. Performance: (Desktop) Composite using double buffering instead of
triple to reduce visible lag.
. TODO fill me in more
- ABI summary: Servers (will?) need rebuilding, but clients do not;
. Mirclient ABI unchanged at 8
. Mircommon ABI unchanged at 3
. Mirplatform ABI bumped to 6
. Mirserver ABI unchanged at 28 (expect 29 before release)
- Bug fixes:
. TODO fill me in at release - 2118. By Andreas Pokorny
-
borrowed path resolution functions from lp:server-platform-probing.
input-evdev is as an intermediate step only installed with mir-test-tools - 2119. By Andreas Pokorny
-
deactivating keyboard support for now - in later mps this would interfere
with cross-device modifier handling, which is currently burried inside EventHub
and needs lifting to a more central location.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2119
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2120. By Andreas Pokorny
-
install evdev recordings for integration tests
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2120
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 2121. By Andreas Pokorny
-
install to install
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2121
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2122. By Andreas Pokorny
-
reame EventSink to the more specific InputSink
- 2123. By Andreas Pokorny
-
add flags template and rename DeviceClass enumeration
- 2124. By Andreas Pokorny
-
merge lp:mir
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2124
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 2125. By Andreas Pokorny
-
Temporary move the evdev platform test to unit-tests until we have a better solution for running umockdev tests
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2125
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 2126. By Andreas Pokorny
-
do not install evdev platform yet
- 2127. By Andreas Pokorny
-
merge sha1sums conflicts
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2127
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
I am having a bit of a problem since this branch is not called from anywhere.
It'd be much less overwhelming to understand and review if some plumbing were introduced
first with a stub/fake input platform/devices, along with some acceptance tests, separating out
the android and libinput bits to subsequent followup branches.
The organization of the files/directories is very sensible and I think it'd be quite simple
to do that at this point since not very many people have reviewed it yet.
Daniel van Vugt (vanvugt) wrote : | # |
Please kill mir::Flags :)
It will confuse debuggers and developers alike if you force invalid enum values into a variable. A set of bits is just an int. For a better example see:
http://
Andreas Pokorny (andreas-pokorny) wrote : | # |
> Please kill mir::Flags :)
>
> It will confuse debuggers and developers alike if you force invalid enum
> values into a variable. A set of bits is just an int. For a better example
> see:
> http://
> branch/
There is no force involved an no invalid enums.
Chris Halse Rogers (raof) wrote : | # |
I like the idea of mir::Flags; a set of flags is *not* just an int, because an int will be able to represent lots of invalid values (unless you have 32 separate flags, I guess).
I'm not sure if mir::Flags, as it currently stands, is worth it. I tried using it in add-dispatchable, and it doesn't handle some common idioms. It's also not clear to me how to improve it to support that, other than going the whole hog and doing class generation with a MIR_DEFINE_FLAGS() macro (which I'd gladly use, but am not volunteering to write ☺).
Daniel van Vugt (vanvugt) wrote : | # |
Oh I see you're using std::underlying
Daniel van Vugt (vanvugt) wrote : | # |
It might also help to remove "uint32_t":
36 +enum class DeviceCapability : uint32_t
A simple "enum DeviceCapability" will work.
Andreas Pokorny (andreas-pokorny) wrote : | # |
> Oh I see you're using std::underlying
> kind of integer and allow you to remove the casts. If it doesn't then you can
> still change value_type to "unsigned int" and remove the casts.
The casts inside Flags iteself are needed because it has to support both scoped and non-scoped enums. For scoped those are absolutely necessary and behave as intended. With c++11 enums can be forward declared since the standard now defines the underlying type to default to int32_t (iirc) - and allows manual specification in forward declaration (only for scoped..). Additionally the trait was added to resolve manually specified underlying types. I am sorry there is nothing to fix there.... just to add but more on that on monday i guess.
Unmerged revisions
- 2127. By Andreas Pokorny
-
merge sha1sums conflicts
- 2126. By Andreas Pokorny
-
do not install evdev platform yet
- 2125. By Andreas Pokorny
-
Temporary move the evdev platform test to unit-tests until we have a better solution for running umockdev tests
- 2124. By Andreas Pokorny
-
merge lp:mir
- 2123. By Andreas Pokorny
-
add flags template and rename DeviceClass enumeration
- 2122. By Andreas Pokorny
-
reame EventSink to the more specific InputSink
- 2121. By Andreas Pokorny
-
install to install
- 2120. By Andreas Pokorny
-
install evdev recordings for integration tests
- 2119. By Andreas Pokorny
-
deactivating keyboard support for now - in later mps this would interfere
with cross-device modifier handling, which is currently burried inside EventHub
and needs lifting to a more central location. - 2118. By Andreas Pokorny
-
borrowed path resolution functions from lp:server-platform-probing.
input-evdev is as an intermediate step only installed with mir-test-tools
Preview Diff
1 | === added directory 'include/platform/mir/input' |
2 | === added file 'include/platform/mir/input/device_capability.h' |
3 | --- include/platform/mir/input/device_capability.h 1970-01-01 00:00:00 +0000 |
4 | +++ include/platform/mir/input/device_capability.h 2015-01-21 10:33:12 +0000 |
5 | @@ -0,0 +1,50 @@ |
6 | +/* |
7 | + * Copyright © 2014 Canonical Ltd. |
8 | + * |
9 | + * This program is free software: you can redistribute it and/or modify it |
10 | + * under the terms of the GNU Lesser General Public License version 3, |
11 | + * as published by the Free Software Foundation. |
12 | + * |
13 | + * This program is distributed in the hope that it will be useful, |
14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | + * GNU Lesser General Public License for more details. |
17 | + * |
18 | + * You should have received a copy of the GNU Lesser General Public License |
19 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | + * |
21 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
22 | + */ |
23 | + |
24 | +#ifndef MIR_INPUT_DEVICE_CAPABILITY_H_ |
25 | +#define MIR_INPUT_DEVICE_CAPABILITY_H_ |
26 | + |
27 | +#include "mir/flags.h" |
28 | + |
29 | +#include <cstdint> |
30 | + |
31 | +namespace mir |
32 | +{ |
33 | +namespace input |
34 | +{ |
35 | + |
36 | +enum class DeviceCapability : uint32_t |
37 | +{ |
38 | + unknown = 0, |
39 | + pointer = 1<<1, |
40 | + keyboard = 1<<2, |
41 | + touchpad = 1<<3, |
42 | + touchscreen = 1<<4, |
43 | + gamepad = 1<<5, |
44 | + joystick = 1<<6, |
45 | + switch_ = 1<<7, |
46 | + multitouch = 1<<8, // multitouch capable |
47 | + alpha_numeric = 1<<9 // enough keys for text entry |
48 | +}; |
49 | + |
50 | +using DeviceCapabilities = mir::Flags<DeviceCapability>; |
51 | + |
52 | +} |
53 | +} |
54 | + |
55 | +#endif |
56 | |
57 | === added file 'include/platform/mir/input/input_device.h' |
58 | --- include/platform/mir/input/input_device.h 1970-01-01 00:00:00 +0000 |
59 | +++ include/platform/mir/input/input_device.h 2015-01-21 10:33:12 +0000 |
60 | @@ -0,0 +1,60 @@ |
61 | +/* |
62 | + * Copyright © 2014 Canonical Ltd. |
63 | + * |
64 | + * This program is free software: you can redistribute it and/or modify it |
65 | + * under the terms of the GNU Lesser General Public License version 3, |
66 | + * as published by the Free Software Foundation. |
67 | + * |
68 | + * This program is distributed in the hope that it will be useful, |
69 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
70 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
71 | + * GNU Lesser General Public License for more details. |
72 | + * |
73 | + * You should have received a copy of the GNU Lesser General Public License |
74 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
75 | + * |
76 | + * Authored by: |
77 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
78 | + */ |
79 | + |
80 | +#ifndef MIR_INPUT_INPUT_DEVICE_H_ |
81 | +#define MIR_INPUT_INPUT_DEVICE_H_ |
82 | + |
83 | +#include <memory> |
84 | + |
85 | +namespace mir |
86 | +{ |
87 | +namespace input |
88 | +{ |
89 | +class InputEventHandlerRegister; |
90 | +class InputSink; |
91 | + |
92 | +/** |
93 | + * Represents an input device. |
94 | + */ |
95 | +class InputDevice |
96 | +{ |
97 | +public: |
98 | + InputDevice() = default; |
99 | + virtual ~InputDevice() = default; |
100 | + |
101 | + /*! |
102 | + * Allow the input device to provide its input events to the given InputSink |
103 | + */ |
104 | + virtual void start(InputEventHandlerRegister& registry, InputSink& destination) = 0; |
105 | + /*! |
106 | + * Stop the input device from sending input events, to the InputSink. |
107 | + */ |
108 | + virtual void stop(InputEventHandlerRegister& registry) = 0; |
109 | + |
110 | + // TODO methods to query device description |
111 | +protected: |
112 | + InputDevice(InputDevice const&) = delete; |
113 | + InputDevice& operator=(InputDevice const&) = delete; |
114 | +}; |
115 | + |
116 | +} |
117 | +} |
118 | + |
119 | +#endif |
120 | + |
121 | |
122 | === added file 'include/platform/mir/input/input_device_registry.h' |
123 | --- include/platform/mir/input/input_device_registry.h 1970-01-01 00:00:00 +0000 |
124 | +++ include/platform/mir/input/input_device_registry.h 2015-01-21 10:33:12 +0000 |
125 | @@ -0,0 +1,49 @@ |
126 | +/* |
127 | + * Copyright © 2014 Canonical Ltd. |
128 | + * |
129 | + * This program is free software: you can redistribute it and/or modify it |
130 | + * under the terms of the GNU Lesser General Public License version 3, |
131 | + * as published by the Free Software Foundation. |
132 | + * |
133 | + * This program is distributed in the hope that it will be useful, |
134 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
135 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
136 | + * GNU Lesser General Public License for more details. |
137 | + * |
138 | + * You should have received a copy of the GNU Lesser General Public License |
139 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
140 | + * |
141 | + * Authored by: |
142 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
143 | + */ |
144 | + |
145 | +#ifndef MIR_INPUT_INPUT_DEVICE_REGISTRY_H_ |
146 | +#define MIR_INPUT_INPUT_DEVICE_REGISTRY_H_ |
147 | + |
148 | +#include <memory> |
149 | + |
150 | +namespace mir |
151 | +{ |
152 | +namespace input |
153 | +{ |
154 | +class InputDevice; |
155 | + |
156 | +class InputDeviceRegistry |
157 | +{ |
158 | +public: |
159 | + InputDeviceRegistry() = default; |
160 | + virtual ~InputDeviceRegistry() = default; |
161 | + |
162 | + virtual void add_device(std::shared_ptr<InputDevice> const& device) = 0; |
163 | + virtual void remove_device(std::shared_ptr<InputDevice> const& device) = 0; |
164 | +protected: |
165 | + InputDeviceRegistry(InputDeviceRegistry const&) = delete; |
166 | + InputDeviceRegistry& operator=(InputDeviceRegistry const&) = delete; |
167 | + |
168 | +}; |
169 | + |
170 | +} |
171 | +} |
172 | + |
173 | +#endif |
174 | + |
175 | |
176 | === added file 'include/platform/mir/input/input_event_handler_register.h' |
177 | --- include/platform/mir/input/input_event_handler_register.h 1970-01-01 00:00:00 +0000 |
178 | +++ include/platform/mir/input/input_event_handler_register.h 2015-01-21 10:33:12 +0000 |
179 | @@ -0,0 +1,80 @@ |
180 | +/* |
181 | + * Copyright © 2014 Canonical Ltd. |
182 | + * |
183 | + * This program is free software: you can redistribute it and/or modify it |
184 | + * under the terms of the GNU Lesser General Public License version 3, |
185 | + * as published by the Free Software Foundation. |
186 | + * |
187 | + * This program is distributed in the hope that it will be useful, |
188 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
189 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
190 | + * GNU Lesser General Public License for more details. |
191 | + * |
192 | + * You should have received a copy of the GNU Lesser General Public License |
193 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
194 | + * |
195 | + * Authored by: |
196 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
197 | + */ |
198 | + |
199 | +#ifndef MIR_INPUT_INPUT_EVENT_HANDLER_REGISTER_H_ |
200 | +#define MIR_INPUT_INPUT_EVENT_HANDLER_REGISTER_H_ |
201 | + |
202 | +#include <functional> |
203 | +#include <initializer_list> |
204 | + |
205 | +namespace mir |
206 | +{ |
207 | +namespace input |
208 | +{ |
209 | + |
210 | +/** |
211 | + * InputEventHandler Register shall be used register handlers for different |
212 | + * input event or input device sources. All handlers are guaranteed to be executed in the same |
213 | + * thread. |
214 | + */ |
215 | +class InputEventHandlerRegister |
216 | +{ |
217 | +public: |
218 | + InputEventHandlerRegister() = default; |
219 | + |
220 | + /** |
221 | + * Registers a read handler for the given set of fds. |
222 | + * |
223 | + * This call does not transfer ownership of the file descriptors |
224 | + * in \a fds. The caller is still responsible to close when necessary. |
225 | + * |
226 | + * \param owner a distinct value to identify the caller |
227 | + */ |
228 | + virtual void register_fd_handler( |
229 | + std::initializer_list<int> fds, |
230 | + void const* owner, |
231 | + std::function<void(int)> const&& handler) = 0; |
232 | + |
233 | + /** |
234 | + * Unregisters the file descriptors and read handlers associated with \a |
235 | + * owner. |
236 | + * |
237 | + * \param owner a distinct value to identify the caller |
238 | + */ |
239 | + virtual void unregister_fd_handler(void const* owner) = 0; |
240 | + |
241 | + /** |
242 | + * Wakes the thread to execute the given \a handler once. |
243 | + * |
244 | + * This method should be used when no file descriptor is available to |
245 | + * indicate available input events or device changes. |
246 | + */ |
247 | + virtual void register_handler(std::function<void()> const&& handler) = 0; |
248 | + |
249 | +protected: |
250 | + virtual ~InputEventHandlerRegister() = default; |
251 | + InputEventHandlerRegister(InputEventHandlerRegister const&) = delete; |
252 | + InputEventHandlerRegister& operator=(InputEventHandlerRegister const&) = delete; |
253 | + |
254 | +}; |
255 | +} |
256 | +} |
257 | + |
258 | +#endif |
259 | + |
260 | |
261 | === renamed file 'src/include/server/mir/input/input_report.h' => 'include/platform/mir/input/input_report.h' |
262 | --- src/include/server/mir/input/input_report.h 2015-01-14 06:39:13 +0000 |
263 | +++ include/platform/mir/input/input_report.h 2015-01-21 10:33:12 +0000 |
264 | @@ -1,16 +1,16 @@ |
265 | /* |
266 | - * Copyright © 2013 Canonical Ltd. |
267 | + * Copyright © 2013-2014 Canonical Ltd. |
268 | * |
269 | * This program is free software: you can redistribute it and/or modify it |
270 | - * under the terms of the GNU General Public License version 3, |
271 | + * under the terms of the GNU Lesser General Public License version 3, |
272 | * as published by the Free Software Foundation. |
273 | * |
274 | * This program is distributed in the hope that it will be useful, |
275 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
276 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
277 | - * GNU General Public License for more details. |
278 | + * GNU Lesser General Public License for more details. |
279 | * |
280 | - * You should have received a copy of the GNU General Public License |
281 | + * You should have received a copy of the GNU Lesser General Public License |
282 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
283 | * |
284 | * Authored by: Alan Griffiths <alan@octopull.co.uk> |
285 | @@ -32,6 +32,10 @@ |
286 | public: |
287 | virtual ~InputReport() = default; |
288 | |
289 | + virtual void open_input_device(char const* device_node) = 0; |
290 | + |
291 | + virtual void failure_opening_input_device(char const* device_node) = 0; |
292 | + |
293 | virtual void received_event_from_kernel(int64_t when, int type, int code, int value) = 0; |
294 | |
295 | virtual void published_key_event(int dest_fd, uint32_t seq_id, int64_t event_time) = 0; |
296 | |
297 | === added file 'include/platform/mir/input/input_sink.h' |
298 | --- include/platform/mir/input/input_sink.h 1970-01-01 00:00:00 +0000 |
299 | +++ include/platform/mir/input/input_sink.h 2015-01-21 10:33:12 +0000 |
300 | @@ -0,0 +1,43 @@ |
301 | +/* |
302 | + * Copyright © 2014 Canonical Ltd. |
303 | + * |
304 | + * This program is free software: you can redistribute it and/or modify it |
305 | + * under the terms of the GNU Lesser General Public License version 3, |
306 | + * as published by the Free Software Foundation. |
307 | + * |
308 | + * This program is distributed in the hope that it will be useful, |
309 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
310 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
311 | + * GNU Lesser General Public License for more details. |
312 | + * |
313 | + * You should have received a copy of the GNU Lesser General Public License |
314 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
315 | + * |
316 | + * Authored by: |
317 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
318 | + */ |
319 | + |
320 | +#ifndef MIR_INPUT_INPUT_SINK_H_ |
321 | +#define MIR_INPUT_INPUT_SINK_H_ |
322 | + |
323 | +#include "mir_toolkit/event.h" |
324 | + |
325 | +namespace mir |
326 | +{ |
327 | +namespace input |
328 | +{ |
329 | +class InputSink |
330 | +{ |
331 | +public: |
332 | + InputSink() = default; |
333 | + virtual ~InputSink() = default; |
334 | + // TODO change to the new mir input event |
335 | + virtual void handle_input(MirEvent const& event) = 0; |
336 | +private: |
337 | + InputSink(InputSink const&) = delete; |
338 | + InputSink& operator=(InputSink const&) = delete; |
339 | +}; |
340 | +} |
341 | +} |
342 | + |
343 | +#endif |
344 | |
345 | === added file 'include/platform/mir/input/platform.h' |
346 | --- include/platform/mir/input/platform.h 1970-01-01 00:00:00 +0000 |
347 | +++ include/platform/mir/input/platform.h 2015-01-21 10:33:12 +0000 |
348 | @@ -0,0 +1,128 @@ |
349 | +/* |
350 | + * Copyright © 2014 Canonical Ltd. |
351 | + * |
352 | + * This program is free software: you can redistribute it and/or modify it |
353 | + * under the terms of the GNU Lesser General Public License version 3, |
354 | + * as published by the Free Software Foundation. |
355 | + * |
356 | + * This program is distributed in the hope that it will be useful, |
357 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
358 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
359 | + * GNU Lesser General Public License for more details. |
360 | + * |
361 | + * You should have received a copy of the GNU Lesser General Public License |
362 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
363 | + * |
364 | + * Authored by: |
365 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
366 | + */ |
367 | + |
368 | +#ifndef MIR_INPUT_PLATFORM_H_ |
369 | +#define MIR_INPUT_PLATFORM_H_ |
370 | + |
371 | +#include <mir/options/option.h> |
372 | + |
373 | +#include <boost/program_options/options_description.hpp> |
374 | + |
375 | +#include <memory> |
376 | + |
377 | +namespace mir |
378 | +{ |
379 | +class EmergencyCleanupRegistry; |
380 | + |
381 | +namespace input |
382 | +{ |
383 | +class InputEventHandlerRegister; |
384 | +class InputDevice; |
385 | +class InputReport; |
386 | +class InputDeviceRegistry; |
387 | + |
388 | +enum class PlatformPriority : uint32_t |
389 | +{ |
390 | + unsupported = 0, |
391 | + supported = 128, |
392 | + best = 256, |
393 | +}; |
394 | + |
395 | +/** |
396 | + * Input Platform is used to discover and access available input devices. |
397 | + * |
398 | + * A platform implementation is supposed to handle device occurance events by |
399 | + * opening new device and register them at the server's InputDeviceRegistry. |
400 | + * Likewise the InputDeviceRegistry shall be informed about removed input devices. |
401 | + * |
402 | + * The actual processing of events is controlled through the mir::input::InputDevice interface. |
403 | + */ |
404 | +class Platform |
405 | +{ |
406 | +public: |
407 | + Platform() = default; |
408 | + virtual ~Platform() = default; |
409 | + |
410 | + /*! |
411 | + * Request the platform to start monitoring for devices. |
412 | + * |
413 | + * \param input_device_registry should be informed about available input devices |
414 | + * \param trigger_registry should be used to register event sources that may indicate a changes of the available devices |
415 | + */ |
416 | + virtual void start(InputEventHandlerRegister& trigger_registry, std::shared_ptr<InputDeviceRegistry> const& input_device_registry) = 0; |
417 | + /*! |
418 | + * Request the platform to stop monitoring for devices. |
419 | + */ |
420 | + virtual void stop(InputEventHandlerRegister& trigger_registry) = 0; |
421 | + |
422 | +private: |
423 | + Platform(Platform const&) = delete; |
424 | + Platform& operator=(Platform const&) = delete; |
425 | +}; |
426 | + |
427 | +extern "C" typedef std::unique_ptr<Platform>(*CreatePlatform)( |
428 | + std::shared_ptr<options::Option> const& options, |
429 | + std::shared_ptr<EmergencyCleanupRegistry> const& emergency_cleanup_registry, |
430 | + std::shared_ptr<InputReport> const& report); |
431 | +/** |
432 | + * Function used to initialize an input platform. |
433 | + * |
434 | + * \param [in] options options to use for this platform |
435 | + * \param [in] emergency_cleanup_registry object to register emergency shutdown handlers with |
436 | + * \param [in] report the object to use to report interesting events from the input subsystem |
437 | + * |
438 | + * This factory function needs to be implemented by each platform. |
439 | + * |
440 | + * \ingroup platform_enablement |
441 | + */ |
442 | +extern "C" std::unique_ptr<Platform> create_input_platform( |
443 | + std::shared_ptr<options::Option> const& options, |
444 | + std::shared_ptr<EmergencyCleanupRegistry> const& emergency_cleanup_registry, |
445 | + std::shared_ptr<InputReport> const& report); |
446 | +extern "C" typedef void(*AddPlatformOptions)( |
447 | + boost::program_options::options_description& config); |
448 | +/** |
449 | + * Function used to add additional configuration options |
450 | + * |
451 | + * \param [in] config program option description that the platform may extend |
452 | + * |
453 | + * This function needs to be implemented by each platform. |
454 | + * |
455 | + * \ingroup platform_enablement |
456 | + */ |
457 | +extern "C" void add_input_platform_options( |
458 | + boost::program_options::options_description& config); |
459 | +extern "C" typedef PlatformPriority(*ProbePlatform)( |
460 | + options::Option const& options); |
461 | +/** |
462 | + * probe_platform should indicate whether the platform is able to work within |
463 | + * the current environment. |
464 | + * |
465 | + * \param [in] options program options of the mir server |
466 | + * |
467 | + * This function needs to be implemented by each platform. |
468 | + * |
469 | + * \ingroup platform_enablement |
470 | + */ |
471 | +extern "C" PlatformPriority probe_input_platform( |
472 | + options::Option const& options); |
473 | +} |
474 | +} |
475 | + |
476 | +#endif // MIR_INPUT_PLATFORM_H_ |
477 | |
478 | === modified file 'platform-ABI-sha1sums' |
479 | --- platform-ABI-sha1sums 2015-01-20 03:21:20 +0000 |
480 | +++ platform-ABI-sha1sums 2015-01-21 10:33:12 +0000 |
481 | @@ -54,4 +54,11 @@ |
482 | 1b77fb3290af00dc7d1c11dcc5388972dacb9ec3 include/platform/mir/graphics/platform_ipc_package.h |
483 | f0db0484b8ccc9091e73c80a2a200cb436b48bfb include/platform/mir/graphics/platform_operation_message.h |
484 | f18876766861e5d4f5ca999dbd176fe1fc520594 include/platform/mir/graphics/renderable.h |
485 | +ab9801389eba1c35fcfb021fca667279244c26ac include/platform/mir/input/device_capability.h |
486 | +12ff36cfe9fd3e99614e9e315845a63156d2798a include/platform/mir/input/input_device.h |
487 | +4f17d5e7b69448ececbc07dee3653a1f0f4dfc89 include/platform/mir/input/input_device_registry.h |
488 | +b59d7132b9f4360ef4cf5af4ed0255c00f897dc7 include/platform/mir/input/input_event_handler_register.h |
489 | +4e502d4a5fdff4ed1a65ba1f0183113f787285ab include/platform/mir/input/input_report.h |
490 | +00a7d63dcd22107590497b57877c1893eed24d32 include/platform/mir/input/input_sink.h |
491 | +897648fdf3531bd57830454f8e9c775a6b53aa0d include/platform/mir/input/platform.h |
492 | b45f14082c4f8b29efaa1b13de795dcb29deb738 include/platform/mir/options/option.h |
493 | |
494 | === modified file 'server-ABI-sha1sums' |
495 | --- server-ABI-sha1sums 2015-01-21 08:38:18 +0000 |
496 | +++ server-ABI-sha1sums 2015-01-21 10:33:12 +0000 |
497 | @@ -54,6 +54,13 @@ |
498 | 1b77fb3290af00dc7d1c11dcc5388972dacb9ec3 include/platform/mir/graphics/platform_ipc_package.h |
499 | f0db0484b8ccc9091e73c80a2a200cb436b48bfb include/platform/mir/graphics/platform_operation_message.h |
500 | f18876766861e5d4f5ca999dbd176fe1fc520594 include/platform/mir/graphics/renderable.h |
501 | +ab9801389eba1c35fcfb021fca667279244c26ac include/platform/mir/input/device_capability.h |
502 | +12ff36cfe9fd3e99614e9e315845a63156d2798a include/platform/mir/input/input_device.h |
503 | +4f17d5e7b69448ececbc07dee3653a1f0f4dfc89 include/platform/mir/input/input_device_registry.h |
504 | +b59d7132b9f4360ef4cf5af4ed0255c00f897dc7 include/platform/mir/input/input_event_handler_register.h |
505 | +4e502d4a5fdff4ed1a65ba1f0183113f787285ab include/platform/mir/input/input_report.h |
506 | +00a7d63dcd22107590497b57877c1893eed24d32 include/platform/mir/input/input_sink.h |
507 | +897648fdf3531bd57830454f8e9c775a6b53aa0d include/platform/mir/input/platform.h |
508 | b45f14082c4f8b29efaa1b13de795dcb29deb738 include/platform/mir/options/option.h |
509 | f4030e400baf8baa9c38e7c6ec6b4a5ad7134aeb include/server/mir/compositor/compositor.h |
510 | a9f284ba4b05d58fd3eeb628d1f56fe4ac188526 include/server/mir/compositor/compositor_id.h |
511 | |
512 | === modified file 'src/CMakeLists.txt' |
513 | --- src/CMakeLists.txt 2015-01-14 06:39:13 +0000 |
514 | +++ src/CMakeLists.txt 2015-01-21 10:33:12 +0000 |
515 | @@ -2,6 +2,8 @@ |
516 | # and the platform implementations. |
517 | set(MIRPLATFORM_ABI 6) |
518 | |
519 | +set(MIR_SERVER_INPUT_PLATFORM_VERSION "MIR_INPUT_PLATFORM_1") |
520 | + |
521 | set(PLATFORM_DRIVER platform${MIRPLATFORM_ABI}driver) |
522 | set(MIR_PLATFORM_DRIVER mir${PLATFORM_DRIVER}) |
523 | set(MIR_PLATFORM_DRIVER_BINARY lib${MIR_PLATFORM_DRIVER}.so |
524 | @@ -40,4 +42,6 @@ |
525 | set(MIR_PLATFORM_REFERENCES ${MIR_PLATFORM_REFERENCES} PARENT_SCOPE) |
526 | set(MIR_COMMON_OBJECTS ${MIR_COMMON_OBJECTS} PARENT_SCOPE) |
527 | set(MIR_COMMON_REFERENCES ${MIR_COMMON_REFERENCES} PARENT_SCOPE) |
528 | +set(MIR_SERVER_INPUT_PLATFORM_VERSION ${MIR_SERVER_INPUT_PLATFORM_VERSION} PARENT_SCOPE) |
529 | set(MIR_CLIENT_PLATFORM_PATH ${MIR_CLIENT_PLATFORM_PATH} PARENT_SCOPE) |
530 | +set(MIR_SERVER_PLATFORM_PATH ${MIR_SERVER_PLATFORM_PATH} PARENT_SCOPE) |
531 | |
532 | === added file 'src/include/common/mir/find_best.h' |
533 | --- src/include/common/mir/find_best.h 1970-01-01 00:00:00 +0000 |
534 | +++ src/include/common/mir/find_best.h 2015-01-21 10:33:12 +0000 |
535 | @@ -0,0 +1,67 @@ |
536 | +/* |
537 | + * Copyright © 2014 Canonical Ltd. |
538 | + * |
539 | + * This program is free software: you can redistribute it and/or modify it |
540 | + * under the terms of the GNU Lesser General Public License version 3, |
541 | + * as published by the Free Software Foundation. |
542 | + * |
543 | + * This program is distributed in the hope that it will be useful, |
544 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
545 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
546 | + * GNU Lesser General Public License for more details. |
547 | + * |
548 | + * You should have received a copy of the GNU Lesser General Public License |
549 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
550 | + * |
551 | + * Authored by: Andeas Pokorny <andreas.pokorny@canonical.com> |
552 | + */ |
553 | + |
554 | +#ifndef MIR_FIND_BEST_H_ |
555 | +#define MIR_FIND_BEST_H_ |
556 | + |
557 | +#include <functional> |
558 | + |
559 | +namespace mir |
560 | +{ |
561 | + |
562 | +struct Greater // replace in favor of std::greater<> when we switch to c++14 |
563 | +{ |
564 | + template<typename T> |
565 | + bool operator()(T const& l, T const& r) const |
566 | + { |
567 | + return l > r; |
568 | + } |
569 | +}; |
570 | + |
571 | +/** |
572 | + * \brief Range based algorithm to find the best suited item. |
573 | + * |
574 | + * Use this instead of std::max_element or std::min_element, when |
575 | + * the comparision involves a costly test, as it caches the test result |
576 | + * of the individual best candidate. To acchieve that the predicate is |
577 | + * split in a predicate and a transformation. |
578 | + */ |
579 | +template<typename Container, typename Transform, typename Predicate = Greater> |
580 | +auto find_best(Container const& items, Transform const& transform, |
581 | + decltype(transform(*items.begin())) const& initial_best, |
582 | + Predicate const& pred = Greater{}) |
583 | +-> decltype(begin(items)) |
584 | +{ |
585 | + auto current_best_it = end(items); |
586 | + auto current_best = initial_best; |
587 | + for (auto it = begin(items), e = end(items); |
588 | + it != e; ++it) |
589 | + { |
590 | + auto item_transformed = transform(*it); |
591 | + |
592 | + if (pred(item_transformed, current_best)) |
593 | + { |
594 | + current_best = item_transformed; |
595 | + current_best_it = it; |
596 | + } |
597 | + } |
598 | + return current_best_it; |
599 | +} |
600 | +} |
601 | + |
602 | +#endif |
603 | |
604 | === added file 'src/include/common/mir/flags.h' |
605 | --- src/include/common/mir/flags.h 1970-01-01 00:00:00 +0000 |
606 | +++ src/include/common/mir/flags.h 2015-01-21 10:33:12 +0000 |
607 | @@ -0,0 +1,118 @@ |
608 | +/* |
609 | + * Copyright © 2015 Canonical Ltd. |
610 | + * |
611 | + * This program is free software: you can redistribute it and/or modify it |
612 | + * under the terms of the GNU Lesser General Public License version 3, |
613 | + * as published by the Free Software Foundation. |
614 | + * |
615 | + * This program is distributed in the hope that it will be useful, |
616 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
617 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
618 | + * GNU Lesser General Public License for more details. |
619 | + * |
620 | + * You should have received a copy of the GNU Lesser General Public License |
621 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
622 | + * |
623 | + * Authored By: Andreas Pokorny <andreas.pokorny@canonical.com> |
624 | + */ |
625 | + |
626 | +#ifndef MIR_FLAGS_H_ |
627 | +#define MIR_FLAGS_H_ |
628 | + |
629 | +#include <type_traits> |
630 | + |
631 | +namespace mir |
632 | +{ |
633 | + |
634 | +/*! |
635 | + * Treat an enumeration, scoped and unscoped, like a set of flags |
636 | + */ |
637 | +template<typename Enum> |
638 | +struct Flags |
639 | +{ |
640 | + using value_type = typename std::underlying_type<Enum>::type; |
641 | + value_type value; |
642 | + |
643 | + explicit constexpr Flags(value_type value = 0) noexcept |
644 | + : value{value} {} |
645 | + constexpr Flags(Enum value) noexcept |
646 | + : value{static_cast<value_type>(value)} {} |
647 | + |
648 | + constexpr Flags<Enum> operator|(Flags<Enum> other) const noexcept |
649 | + { |
650 | + return Flags<Enum>(value|other.value); |
651 | + } |
652 | + |
653 | + constexpr Flags<Enum> operator&(Flags<Enum> other) const noexcept |
654 | + { |
655 | + return Flags<Enum>(value & other.value); |
656 | + } |
657 | + |
658 | +#ifdef __clang__ |
659 | +#pragma clang diagnostic push |
660 | +#pragma clang diagnostic ignored "-Wconstexpr-not-const" |
661 | +#endif |
662 | + constexpr Flags<Enum>& operator|=(Flags<Enum> other) noexcept |
663 | + { |
664 | + return value |= other.value, *this; |
665 | + } |
666 | + |
667 | + constexpr Flags<Enum> operator&=(Flags<Enum> other) noexcept |
668 | + { |
669 | + return value &= other.value, *this; |
670 | + } |
671 | +#ifdef __clang__ |
672 | +#pragma clang diagnostic pop |
673 | +#endif |
674 | + |
675 | + constexpr bool operator==(Flags<Enum> other) const noexcept |
676 | + { |
677 | + return value == other.value; |
678 | + } |
679 | +}; |
680 | + |
681 | +template<typename Enum> |
682 | +constexpr Flags<Enum> operator|(Flags<Enum> flags, Enum e) noexcept |
683 | +{ |
684 | + return Flags<Enum>(flags.value | static_cast<decltype(flags.value)>(e)); |
685 | +} |
686 | + |
687 | +template<typename Enum> |
688 | +constexpr Flags<Enum> operator|(Enum e, Flags<Enum> flags) noexcept |
689 | +{ |
690 | + return Flags<Enum>(flags.value | static_cast<decltype(flags.value)>(e)); |
691 | +} |
692 | + |
693 | +template<typename Enum> |
694 | +constexpr Enum operator&(Enum e, Flags<Enum> flags) noexcept |
695 | +{ |
696 | + return static_cast<Enum>(flags.value & static_cast<decltype(flags.value)>(e)); |
697 | +} |
698 | + |
699 | +template<typename Enum> |
700 | +constexpr Enum operator&(Flags<Enum> flags, Enum e) noexcept |
701 | +{ |
702 | + return static_cast<Enum>(flags.value & static_cast<decltype(flags.value)>(e)); |
703 | +} |
704 | + |
705 | +template<typename Enum> |
706 | +constexpr bool operator==(Flags<Enum> flags, Enum e) noexcept |
707 | +{ |
708 | + return e == static_cast<Enum>(flags.value); |
709 | +} |
710 | + |
711 | +template<typename Enum> |
712 | +constexpr bool operator==(Enum e, Flags<Enum> flags) noexcept |
713 | +{ |
714 | + return e == static_cast<Enum>(flags.value); |
715 | +} |
716 | + |
717 | +template<typename Enum> |
718 | +constexpr bool contains(Flags<Enum> flags, Enum e) noexcept |
719 | +{ |
720 | + return e == static_cast<Enum>(flags.value & static_cast<decltype(flags.value)>(e)); |
721 | +} |
722 | + |
723 | +} |
724 | + |
725 | +#endif |
726 | |
727 | === modified file 'src/platform/CMakeLists.txt' |
728 | --- src/platform/CMakeLists.txt 2015-01-14 06:39:13 +0000 |
729 | +++ src/platform/CMakeLists.txt 2015-01-21 10:33:12 +0000 |
730 | @@ -44,6 +44,8 @@ |
731 | |
732 | install(TARGETS mirplatform LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) |
733 | |
734 | +add_definitions(-DMIR_SERVER_INPUT_PLATFORM_VERSION="${MIR_SERVER_INPUT_PLATFORM_VERSION}") |
735 | + |
736 | add_subdirectory(graphics/) |
737 | add_subdirectory(options) |
738 | add_subdirectory(fatal) |
739 | |
740 | === modified file 'src/platforms/CMakeLists.txt' |
741 | --- src/platforms/CMakeLists.txt 2014-12-12 17:56:20 +0000 |
742 | +++ src/platforms/CMakeLists.txt 2015-01-21 10:33:12 +0000 |
743 | @@ -1,3 +1,11 @@ |
744 | +set(MIR_SERVER_PLATFORM_PATH |
745 | + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/mir/server-platform |
746 | +) |
747 | +set(MIR_SERVER_PLATFORM_PATH |
748 | + ${MIR_SERVER_PLATFORM_PATH} |
749 | + PARENT_SCOPE |
750 | +) |
751 | + |
752 | include_directories( |
753 | ${PROJECT_SOURCE_DIR}/include/platform |
754 | ) |
755 | @@ -9,6 +17,7 @@ |
756 | ) |
757 | |
758 | set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map) |
759 | +set(input_platform_symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/input-platform-symbols.map) |
760 | |
761 | if (MIR_BUILD_PLATFORM_MESA) |
762 | add_subdirectory(mesa/) |
763 | @@ -17,3 +26,7 @@ |
764 | if (MIR_BUILD_PLATFORM_ANDROID) |
765 | add_subdirectory(android/) |
766 | endif() |
767 | + |
768 | +add_definitions(-DMIR_SERVER_INPUT_PLATFORM_VERSION="${MIR_SERVER_INPUT_PLATFORM_VERSION}") |
769 | + |
770 | +add_subdirectory(evdev/) |
771 | |
772 | === added directory 'src/platforms/evdev' |
773 | === added file 'src/platforms/evdev/CMakeLists.txt' |
774 | --- src/platforms/evdev/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
775 | +++ src/platforms/evdev/CMakeLists.txt 2015-01-21 10:33:12 +0000 |
776 | @@ -0,0 +1,24 @@ |
777 | +add_library(mirplatforminputevdevobjects OBJECT |
778 | + android_device_provider.cpp |
779 | + evdev_device_detection.cpp |
780 | + evdev_input_device_factory.cpp |
781 | + libinput_device_provider.cpp |
782 | + ) |
783 | + |
784 | +add_library(mirplatforminputevdev SHARED |
785 | + platform.cpp |
786 | + $<TARGET_OBJECTS:mirplatforminputevdevobjects> |
787 | +) |
788 | + |
789 | +set_target_properties( |
790 | + mirplatforminputevdev PROPERTIES |
791 | + OUTPUT_NAME input-evdev |
792 | + LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}/server-modules |
793 | + PREFIX "" |
794 | + LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${input_platform_symbol_map}" |
795 | +) |
796 | + |
797 | +target_link_libraries(mirplatforminputevdev |
798 | + mirplatform |
799 | + ${Boost_PROGRAM_OPTIONS_LIBRARY} |
800 | +) |
801 | |
802 | === added file 'src/platforms/evdev/android_device_provider.cpp' |
803 | --- src/platforms/evdev/android_device_provider.cpp 1970-01-01 00:00:00 +0000 |
804 | +++ src/platforms/evdev/android_device_provider.cpp 2015-01-21 10:33:12 +0000 |
805 | @@ -0,0 +1,48 @@ |
806 | +/* |
807 | + * Copyright © 2014 Canonical Ltd. |
808 | + * |
809 | + * This program is free software: you can redistribute it and/or modify it |
810 | + * under the terms of the GNU Lesser General Public License version 3, |
811 | + * as published by the Free Software Foundation. |
812 | + * |
813 | + * This program is distributed in the hope that it will be useful, |
814 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
815 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
816 | + * GNU Lesser General Public License for more details. |
817 | + * |
818 | + * You should have received a copy of the GNU Lesser General Public License |
819 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
820 | + * |
821 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
822 | + */ |
823 | + |
824 | +#include "android_device_provider.h" |
825 | +#include "evdev_device_detection.h" |
826 | + |
827 | +#include "mir/input/device_capability.h" |
828 | +#include "mir/input/input_device.h" |
829 | + |
830 | +namespace mi = mir::input; |
831 | +namespace mie = mi::evdev; |
832 | + |
833 | +mie::Priority mie::AndroidDeviceProvider::probe_device(char const* device) const |
834 | +{ |
835 | + auto device_caps = detect_device_capabilities(device); |
836 | + |
837 | + if (contains(device_caps, DeviceCapability::touchscreen)) |
838 | + return Priority::best; |
839 | + |
840 | + if (contains(device_caps, DeviceCapability::touchpad)) |
841 | + return Priority::unsupported; |
842 | + |
843 | + if (device_caps == DeviceCapability::unknown) |
844 | + return Priority::unsupported; |
845 | + |
846 | + return Priority::supported; |
847 | +} |
848 | + |
849 | +std::unique_ptr<mi::InputDevice> mie::AndroidDeviceProvider::create_device(char const* /*device*/) const |
850 | +{ |
851 | + return std::unique_ptr<mi::InputDevice>(); |
852 | +} |
853 | + |
854 | |
855 | === added file 'src/platforms/evdev/android_device_provider.h' |
856 | --- src/platforms/evdev/android_device_provider.h 1970-01-01 00:00:00 +0000 |
857 | +++ src/platforms/evdev/android_device_provider.h 2015-01-21 10:33:12 +0000 |
858 | @@ -0,0 +1,42 @@ |
859 | +/* |
860 | + * Copyright © 2014 Canonical Ltd. |
861 | + * |
862 | + * This program is free software: you can redistribute it and/or modify it |
863 | + * under the terms of the GNU Lesser General Public License version 3, |
864 | + * as published by the Free Software Foundation. |
865 | + * |
866 | + * This program is distributed in the hope that it will be useful, |
867 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
868 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
869 | + * GNU Lesser General Public License for more details. |
870 | + * |
871 | + * You should have received a copy of the GNU Lesser General Public License |
872 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
873 | + * |
874 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
875 | + */ |
876 | + |
877 | +#ifndef MIR_INPUT_EVDEV_ANDROID_DEVICE_PROVIDER_H_ |
878 | +#define MIR_INPUT_EVDEV_ANDROID_DEVICE_PROVIDER_H_ |
879 | + |
880 | +#include "input_device_provider.h" |
881 | + |
882 | +namespace mir |
883 | +{ |
884 | +namespace input |
885 | +{ |
886 | +namespace evdev |
887 | +{ |
888 | + |
889 | +class AndroidDeviceProvider : public InputDeviceProvider |
890 | +{ |
891 | +public: |
892 | + Priority probe_device(char const* path) const override; |
893 | + std::unique_ptr<InputDevice> create_device(char const* path) const override; |
894 | +}; |
895 | + |
896 | +} |
897 | +} |
898 | +} |
899 | + |
900 | +#endif // MIR_INPUT_EVDEV_ANDROID_DEVICE_PROVIDER_H_ |
901 | |
902 | === added file 'src/platforms/evdev/evdev_device_detection.cpp' |
903 | --- src/platforms/evdev/evdev_device_detection.cpp 1970-01-01 00:00:00 +0000 |
904 | +++ src/platforms/evdev/evdev_device_detection.cpp 2015-01-21 10:33:12 +0000 |
905 | @@ -0,0 +1,163 @@ |
906 | +/* |
907 | + * Copyright © 2014 Canonical Ltd. |
908 | + * |
909 | + * This program is free software: you can redistribute it and/or modify it |
910 | + * under the terms of the GNU Lesser General Public License version 3, |
911 | + * as published by the Free Software Foundation. |
912 | + * |
913 | + * This program is distributed in the hope that it will be useful, |
914 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
915 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
916 | + * GNU Lesser General Public License for more details. |
917 | + * |
918 | + * You should have received a copy of the GNU Lesser General Public License |
919 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
920 | + * |
921 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
922 | + */ |
923 | + |
924 | +#include "evdev_device_detection.h" |
925 | +#include "mir/fd.h" |
926 | + |
927 | +#include <boost/exception/errinfo_errno.hpp> |
928 | +#include <boost/exception/errinfo_file_name.hpp> |
929 | +#include <boost/throw_exception.hpp> |
930 | + |
931 | +#include <linux/input.h> |
932 | + |
933 | +#include <sys/types.h> |
934 | +#include <sys/stat.h> |
935 | +#include <fcntl.h> |
936 | + |
937 | +#include <cstring> |
938 | +#include <system_error> |
939 | + |
940 | +namespace mi = mir::input; |
941 | +namespace mie = mi::evdev; |
942 | + |
943 | +namespace |
944 | +{ |
945 | + |
946 | +struct DeviceInfo |
947 | +{ |
948 | + uint8_t key_bit_mask[(KEY_MAX+1)/8]; |
949 | + uint8_t abs_bit_mask[(ABS_MAX+1)/8]; |
950 | + uint8_t rel_bit_mask[(REL_MAX+1)/8]; |
951 | + uint8_t sw_bit_mask[(SW_MAX+1)/8]; |
952 | + uint8_t property_bit_mask[(INPUT_PROP_MAX+1)/8]; |
953 | +}; |
954 | + |
955 | +void fill_device_info(DeviceInfo& info, int fd) |
956 | +{ |
957 | + std::memset(&info, 0, sizeof info); |
958 | + |
959 | + auto const get_bitmask = [&](int bit, size_t size, uint8_t* buf) -> void |
960 | + { |
961 | + if(ioctl(fd, EVIOCGBIT(bit, size), buf) < 1) |
962 | + BOOST_THROW_EXCEPTION( |
963 | + std::system_error(std::error_code(errno, std::system_category()), |
964 | + "Failed to query input device")); |
965 | + }; |
966 | + get_bitmask(EV_KEY, sizeof info.key_bit_mask, info.key_bit_mask); |
967 | + get_bitmask(EV_REL, sizeof info.rel_bit_mask, info.rel_bit_mask); |
968 | + get_bitmask(EV_ABS, sizeof info.abs_bit_mask, info.abs_bit_mask); |
969 | + get_bitmask(EV_SW, sizeof info.sw_bit_mask, info.sw_bit_mask); |
970 | + |
971 | + if (ioctl(fd, EVIOCGPROP(sizeof info.property_bit_mask), info.property_bit_mask) < 1) |
972 | + BOOST_THROW_EXCEPTION( |
973 | + std::system_error(std::error_code(errno, std::system_category()), |
974 | + "Failed to query devices properties")); |
975 | + |
976 | +} |
977 | + |
978 | +constexpr size_t index_of_bit(size_t bit) |
979 | +{ |
980 | + return (bit + 7) / 8; |
981 | +} |
982 | +inline bool get_bit(uint8_t const* array, size_t bit) |
983 | +{ |
984 | + return array[bit/8] & (1<<(bit%8)); |
985 | +} |
986 | + |
987 | +inline size_t get_num_bits(uint8_t const* array, std::initializer_list<size_t> bits) |
988 | +{ |
989 | + size_t ret = 0; |
990 | + for( auto const bit : bits) |
991 | + ret += get_bit(array, bit); |
992 | + return ret; |
993 | +} |
994 | + |
995 | +mi::DeviceCapabilities evaluate_device_capabilities(DeviceInfo const& info) |
996 | +{ |
997 | + mi::DeviceCapabilities caps; |
998 | + |
999 | + auto const contains_non_zero = [](uint8_t const* array, int first, int last) -> bool |
1000 | + { |
1001 | + return std::any_of(array + first, array + last, [](uint8_t item) { return item!=0;}); |
1002 | + }; |
1003 | + |
1004 | + bool const has_keys = contains_non_zero(info.key_bit_mask, 0, index_of_bit(BTN_MISC)) |
1005 | + || contains_non_zero(info.key_bit_mask, index_of_bit(KEY_OK), sizeof info.key_bit_mask); |
1006 | + |
1007 | + bool const has_gamepad_buttons = |
1008 | + contains_non_zero(info.key_bit_mask, index_of_bit(BTN_MISC), index_of_bit(BTN_MOUSE)) |
1009 | + || contains_non_zero(info.key_bit_mask, index_of_bit(BTN_JOYSTICK), index_of_bit(BTN_DIGI)); |
1010 | + |
1011 | + bool const has_coordinates = get_bit(info.abs_bit_mask, ABS_X) && |
1012 | + get_bit(info.abs_bit_mask, ABS_Y); |
1013 | + |
1014 | + bool const has_mt_coordinates = get_bit(info.abs_bit_mask, ABS_MT_POSITION_X) && |
1015 | + get_bit(info.abs_bit_mask, ABS_MT_POSITION_Y); |
1016 | + |
1017 | + bool const is_direct = get_bit(info.property_bit_mask, INPUT_PROP_DIRECT); |
1018 | + |
1019 | + bool const finger_but_no_pen = get_bit(info.key_bit_mask, BTN_TOOL_FINGER) |
1020 | + && !get_bit(info.key_bit_mask, BTN_TOOL_PEN); |
1021 | + |
1022 | + bool const has_touch = get_bit(info.key_bit_mask, BTN_TOUCH); |
1023 | + |
1024 | + bool const has_joystick_axis = 0 < get_num_bits( |
1025 | + info.abs_bit_mask, {ABS_Z, |
1026 | + ABS_RX, ABS_RY, ABS_RZ, |
1027 | + ABS_THROTTLE, ABS_RUDDER, ABS_WHEEL, ABS_GAS, ABS_BRAKE, |
1028 | + ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y, ABS_HAT2X, ABS_HAT2Y, ABS_HAT3X, ABS_HAT3Y, |
1029 | + ABS_TILT_X, ABS_TILT_Y |
1030 | + }); |
1031 | + |
1032 | + if (has_keys || has_gamepad_buttons) |
1033 | + caps = caps | mi::DeviceCapability::keyboard; |
1034 | + |
1035 | + if (get_bit(info.key_bit_mask, BTN_MOUSE) && get_bit(info.rel_bit_mask, REL_X) && get_bit(info.rel_bit_mask, REL_Y)) |
1036 | + caps = caps | mi::DeviceCapability::pointer; |
1037 | + |
1038 | + if (finger_but_no_pen && !is_direct && (has_coordinates|| has_mt_coordinates)) |
1039 | + caps = caps | mi::DeviceCapability::touchpad; |
1040 | + else if (has_touch && ((has_mt_coordinates && !has_gamepad_buttons) |
1041 | + || has_coordinates)) |
1042 | + caps = caps | mi::DeviceCapability::touchscreen; |
1043 | + |
1044 | + if (has_joystick_axis || (!has_touch && has_coordinates)) |
1045 | + caps = caps | mi::DeviceCapability::joystick; |
1046 | + |
1047 | + if (has_gamepad_buttons) |
1048 | + caps = caps | mi::DeviceCapability::gamepad; |
1049 | + |
1050 | + return caps; |
1051 | +} |
1052 | + |
1053 | +} |
1054 | + |
1055 | +mi::DeviceCapabilities mie::detect_device_capabilities(char const* device) |
1056 | +{ |
1057 | + mir::Fd input_device(::open(device, O_RDONLY|O_NONBLOCK)); |
1058 | + if (input_device < 0) |
1059 | + BOOST_THROW_EXCEPTION( |
1060 | + std::system_error(std::error_code(errno, std::system_category()), |
1061 | + "Failed to open input device")); |
1062 | + |
1063 | + DeviceInfo info; |
1064 | + |
1065 | + fill_device_info(info, input_device); |
1066 | + return evaluate_device_capabilities(info); |
1067 | +} |
1068 | + |
1069 | |
1070 | === added file 'src/platforms/evdev/evdev_device_detection.h' |
1071 | --- src/platforms/evdev/evdev_device_detection.h 1970-01-01 00:00:00 +0000 |
1072 | +++ src/platforms/evdev/evdev_device_detection.h 2015-01-21 10:33:12 +0000 |
1073 | @@ -0,0 +1,35 @@ |
1074 | +/* |
1075 | + * Copyright © 2014 Canonical Ltd. |
1076 | + * |
1077 | + * This program is free software: you can redistribute it and/or modify it |
1078 | + * under the terms of the GNU Lesser General Public License version 3, |
1079 | + * as published by the Free Software Foundation. |
1080 | + * |
1081 | + * This program is distributed in the hope that it will be useful, |
1082 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1083 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1084 | + * GNU Lesser General Public License for more details. |
1085 | + * |
1086 | + * You should have received a copy of the GNU Lesser General Public License |
1087 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1088 | + * |
1089 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
1090 | + */ |
1091 | + |
1092 | +#ifndef MIR_INPUT_EVDEV_DEVICE_DETECTION_H_ |
1093 | +#define MIR_INPUT_EVDEV_DEVICE_DETECTION_H_ |
1094 | + |
1095 | +#include "mir/input/device_capability.h" |
1096 | + |
1097 | +namespace mir |
1098 | +{ |
1099 | +namespace input |
1100 | +{ |
1101 | +namespace evdev |
1102 | +{ |
1103 | +input::DeviceCapabilities detect_device_capabilities(char const* device); |
1104 | +} |
1105 | +} |
1106 | +} |
1107 | + |
1108 | +#endif |
1109 | |
1110 | === added file 'src/platforms/evdev/evdev_input_device_factory.cpp' |
1111 | --- src/platforms/evdev/evdev_input_device_factory.cpp 1970-01-01 00:00:00 +0000 |
1112 | +++ src/platforms/evdev/evdev_input_device_factory.cpp 2015-01-21 10:33:12 +0000 |
1113 | @@ -0,0 +1,58 @@ |
1114 | +/* |
1115 | + * Copyright © 2013-2014 Canonical Ltd. |
1116 | + * |
1117 | + * This program is free software: you can redistribute it and/or modify |
1118 | + * it under the terms of the GNU Lesser General Public License version 3 as |
1119 | + * published by the Free Software Foundation. |
1120 | + * |
1121 | + * This program is distributed in the hope that it will be useful, |
1122 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1123 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1124 | + * GNU Lesser General Public License for more details. |
1125 | + * |
1126 | + * You should have received a copy of the GNU Lesser General Public License |
1127 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1128 | + * |
1129 | + * Authored by: Christopher Halse Rogers <christopher.halse.rogers@canonical.com> |
1130 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
1131 | + */ |
1132 | + |
1133 | +#include "evdev_input_device_factory.h" |
1134 | +#include "input_device_provider.h" |
1135 | + |
1136 | +#include "mir/find_best.h" |
1137 | +#include "mir/input/input_device.h" |
1138 | + |
1139 | +#include <stdexcept> |
1140 | + |
1141 | +namespace mi = mir::input; |
1142 | +namespace mie = mi::evdev; |
1143 | + |
1144 | +mie::EvdevInputDeviceFactory::EvdevInputDeviceFactory(std::initializer_list<std::shared_ptr<mie::InputDeviceProvider>> providers) |
1145 | + : providers(providers) |
1146 | +{ |
1147 | +} |
1148 | + |
1149 | +std::unique_ptr<mi::InputDevice> mie::EvdevInputDeviceFactory::create_device(char const* device) |
1150 | +{ |
1151 | + auto best_provider = find_best( |
1152 | + providers, |
1153 | + [device](std::shared_ptr<InputDeviceProvider> const& provider) -> Priority |
1154 | + { |
1155 | + try |
1156 | + { |
1157 | + return provider->probe_device(device); |
1158 | + } |
1159 | + catch(...) |
1160 | + { |
1161 | + return Priority::unsupported; |
1162 | + } |
1163 | + }, |
1164 | + Priority::unsupported |
1165 | + ); |
1166 | + |
1167 | + if (best_provider != end(providers)) |
1168 | + return std::move((*best_provider)->create_device(device)); |
1169 | + |
1170 | + throw std::runtime_error("Failed to open input device"); |
1171 | +} |
1172 | |
1173 | === added file 'src/platforms/evdev/evdev_input_device_factory.h' |
1174 | --- src/platforms/evdev/evdev_input_device_factory.h 1970-01-01 00:00:00 +0000 |
1175 | +++ src/platforms/evdev/evdev_input_device_factory.h 2015-01-21 10:33:12 +0000 |
1176 | @@ -0,0 +1,52 @@ |
1177 | +/* |
1178 | + * Copyright © 2013-2014 Canonical Ltd. |
1179 | + * |
1180 | + * This program is free software: you can redistribute it and/or modify it |
1181 | + * under the terms of the GNU Lesser General Public License version 3, |
1182 | + * as published by the Free Software Foundation. |
1183 | + * |
1184 | + * This program is distributed in the hope that it will be useful, |
1185 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1186 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1187 | + * GNU Lesser General Public License for more details. |
1188 | + * |
1189 | + * You should have received a copy of the GNU Lesser General Public License |
1190 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1191 | + * |
1192 | + * Authored by: Christopher Halse Rogers <christopher.halse.rogers@canonical.com> |
1193 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
1194 | + */ |
1195 | + |
1196 | +#ifndef MIR_INPUT_EVDEV_EVDEV_INPUT_DEVICE_FACTORY_H_ |
1197 | +#define MIR_INPUT_EVDEV_EVDEV_INPUT_DEVICE_FACTORY_H_ |
1198 | + |
1199 | +#include "input_device_factory.h" |
1200 | + |
1201 | +#include <memory> |
1202 | +#include <vector> |
1203 | +#include <initializer_list> |
1204 | + |
1205 | +namespace mir |
1206 | +{ |
1207 | +namespace input |
1208 | +{ |
1209 | +namespace evdev |
1210 | +{ |
1211 | +class InputDeviceProvider; |
1212 | + |
1213 | +class EvdevInputDeviceFactory : public InputDeviceFactory |
1214 | +{ |
1215 | +public: |
1216 | + EvdevInputDeviceFactory(std::initializer_list<std::shared_ptr<InputDeviceProvider>> providers); |
1217 | + |
1218 | + std::unique_ptr<InputDevice> create_device(char const* devcie_node) override; |
1219 | + |
1220 | +private: |
1221 | + std::vector<std::shared_ptr<InputDeviceProvider>> providers; |
1222 | +}; |
1223 | + |
1224 | +} |
1225 | +} |
1226 | +} // namespace mir |
1227 | + |
1228 | +#endif // MIR_INPUT_EVDEV_INPUT_DEVICE_FACTORY_H_ |
1229 | |
1230 | === added file 'src/platforms/evdev/input_device_factory.h' |
1231 | --- src/platforms/evdev/input_device_factory.h 1970-01-01 00:00:00 +0000 |
1232 | +++ src/platforms/evdev/input_device_factory.h 2015-01-21 10:33:12 +0000 |
1233 | @@ -0,0 +1,50 @@ |
1234 | +/* |
1235 | + * Copyright © 2013-2014 Canonical Ltd. |
1236 | + * |
1237 | + * This program is free software: you can redistribute it and/or modify it |
1238 | + * under the terms of the GNU Lesser General Public License version 3, |
1239 | + * as published by the Free Software Foundation. |
1240 | + * |
1241 | + * This program is distributed in the hope that it will be useful, |
1242 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1243 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1244 | + * GNU Lesser General Public License for more details. |
1245 | + * |
1246 | + * You should have received a copy of the GNU Lesser General Public License |
1247 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1248 | + * |
1249 | + * Authored by: Christopher Halse Rogers <christopher.halse.rogers@canonical.com> |
1250 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
1251 | + */ |
1252 | + |
1253 | +#ifndef MIR_INPUT_INPUT_DEVICE_FACTORY_H_ |
1254 | +#define MIR_INPUT_INPUT_DEVICE_FACTORY_H_ |
1255 | + |
1256 | +#include <memory> |
1257 | + |
1258 | +namespace mir |
1259 | +{ |
1260 | +namespace input |
1261 | +{ |
1262 | +class InputDevice; |
1263 | +namespace evdev |
1264 | +{ |
1265 | + |
1266 | +class InputDeviceFactory |
1267 | +{ |
1268 | +public: |
1269 | + InputDeviceFactory() = default; |
1270 | + virtual ~InputDeviceFactory() = default; |
1271 | + |
1272 | + virtual std::unique_ptr<InputDevice> create_device(char const* device_node) = 0; |
1273 | + |
1274 | +protected: |
1275 | + InputDeviceFactory(InputDeviceFactory const&) = delete; |
1276 | + InputDeviceFactory& operator=(InputDeviceFactory const&) = delete; |
1277 | +}; |
1278 | + |
1279 | +} |
1280 | +} |
1281 | +} // namespace mir |
1282 | + |
1283 | +#endif // MIR_INPUT_INPUT_DEVICE_FACTORY_H_ |
1284 | |
1285 | === added file 'src/platforms/evdev/input_device_provider.h' |
1286 | --- src/platforms/evdev/input_device_provider.h 1970-01-01 00:00:00 +0000 |
1287 | +++ src/platforms/evdev/input_device_provider.h 2015-01-21 10:33:12 +0000 |
1288 | @@ -0,0 +1,59 @@ |
1289 | +/* |
1290 | + * Copyright © 2013-2014 Canonical Ltd. |
1291 | + * |
1292 | + * This program is free software: you can redistribute it and/or modify it |
1293 | + * under the terms of the GNU Lesser General Public License version 3, |
1294 | + * as published by the Free Software Foundation. |
1295 | + * |
1296 | + * This program is distributed in the hope that it will be useful, |
1297 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1298 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1299 | + * GNU Lesser General Public License for more details. |
1300 | + * |
1301 | + * You should have received a copy of the GNU Lesser General Public License |
1302 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1303 | + * |
1304 | + * Authored by: Christopher Halse Rogers <christopher.halse.rogers@canonical.com> |
1305 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
1306 | + */ |
1307 | + |
1308 | +#ifndef MIR_INPUT_EVDEV_INPUT_DEVICE_PROVIDER_H_ |
1309 | +#define MIR_INPUT_EVDEV_INPUT_DEVICE_PROVIDER_H_ |
1310 | + |
1311 | +#include <memory> |
1312 | + |
1313 | +namespace mir |
1314 | +{ |
1315 | +namespace input |
1316 | +{ |
1317 | +class InputDevice; |
1318 | + |
1319 | +namespace evdev |
1320 | +{ |
1321 | + |
1322 | +enum class Priority : uint32_t |
1323 | +{ |
1324 | + unsupported = 0, |
1325 | + supported = 100, |
1326 | + best = 255, |
1327 | +}; |
1328 | + |
1329 | +class InputDeviceProvider |
1330 | +{ |
1331 | +public: |
1332 | + InputDeviceProvider() = default; |
1333 | + virtual ~InputDeviceProvider() = default; |
1334 | + |
1335 | + virtual Priority probe_device(char const* node) const = 0; |
1336 | + virtual std::unique_ptr<InputDevice> create_device(char const* node) const = 0; |
1337 | + |
1338 | +protected: |
1339 | + InputDeviceProvider(InputDeviceProvider const& cp) = delete; |
1340 | + InputDeviceProvider& operator=(InputDeviceProvider const& cp) = delete; |
1341 | +}; |
1342 | + |
1343 | +} |
1344 | +} |
1345 | +} // namespace mir |
1346 | + |
1347 | +#endif // MIR_INPUT_EVDEV_INPUT_DEVICE_PROVIDER_H_ |
1348 | |
1349 | === added file 'src/platforms/evdev/libinput_device_provider.cpp' |
1350 | --- src/platforms/evdev/libinput_device_provider.cpp 1970-01-01 00:00:00 +0000 |
1351 | +++ src/platforms/evdev/libinput_device_provider.cpp 2015-01-21 10:33:12 +0000 |
1352 | @@ -0,0 +1,67 @@ |
1353 | +/* |
1354 | + * Copyright © 2014 Canonical Ltd. |
1355 | + * |
1356 | + * This program is free software: you can redistribute it and/or modify it |
1357 | + * under the terms of the GNU Lesser General Public License version 3, |
1358 | + * as published by the Free Software Foundation. |
1359 | + * |
1360 | + * This program is distributed in the hope that it will be useful, |
1361 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1362 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1363 | + * GNU Lesser General Public License for more details. |
1364 | + * |
1365 | + * You should have received a copy of the GNU Lesser General Public License |
1366 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1367 | + * |
1368 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
1369 | + */ |
1370 | + |
1371 | +#include "libinput_device_provider.h" |
1372 | +#include "evdev_device_detection.h" |
1373 | + |
1374 | +#include "mir/input/input_device.h" |
1375 | +#include "mir/input/device_capability.h" |
1376 | + |
1377 | +#include <sys/types.h> |
1378 | +#include <sys/stat.h> |
1379 | +#include <fcntl.h> |
1380 | +#include <unistd.h> |
1381 | +#include <stdexcept> |
1382 | + |
1383 | +namespace mi = mir::input; |
1384 | +namespace mie = mi::evdev; |
1385 | + |
1386 | +mie::Priority mie::LibInputDeviceProvider::probe_device(char const* device) const |
1387 | +{ |
1388 | + auto device_caps = detect_device_capabilities(device); |
1389 | + |
1390 | + if (contains(device_caps, DeviceCapability::joystick)) |
1391 | + return Priority::unsupported; |
1392 | + |
1393 | + if (contains(device_caps, DeviceCapability::gamepad)) |
1394 | + return Priority::unsupported; |
1395 | + |
1396 | + if (contains(device_caps, DeviceCapability::touchscreen)) |
1397 | + return Priority::unsupported; |
1398 | + |
1399 | + if (contains(device_caps, DeviceCapability::touchpad)) |
1400 | + return Priority::best; |
1401 | + |
1402 | + if (device_caps == DeviceCapability::unknown) |
1403 | + return Priority::unsupported; |
1404 | + |
1405 | + if (contains(device_caps, DeviceCapability::pointer)) |
1406 | + return Priority::supported; |
1407 | + |
1408 | + if (contains(device_caps, DeviceCapability::keyboard)) |
1409 | + return Priority::unsupported; |
1410 | + |
1411 | + return Priority::unsupported; |
1412 | +} |
1413 | + |
1414 | +std::unique_ptr<mi::InputDevice> mie::LibInputDeviceProvider::create_device(char const* device) const |
1415 | +{ |
1416 | + (void)device; |
1417 | + return std::unique_ptr<mi::InputDevice>(); |
1418 | +} |
1419 | + |
1420 | |
1421 | === added file 'src/platforms/evdev/libinput_device_provider.h' |
1422 | --- src/platforms/evdev/libinput_device_provider.h 1970-01-01 00:00:00 +0000 |
1423 | +++ src/platforms/evdev/libinput_device_provider.h 2015-01-21 10:33:12 +0000 |
1424 | @@ -0,0 +1,42 @@ |
1425 | +/* |
1426 | + * Copyright © 2014 Canonical Ltd. |
1427 | + * |
1428 | + * This program is free software: you can redistribute it and/or modify it |
1429 | + * under the terms of the GNU Lesser General Public License version 3, |
1430 | + * as published by the Free Software Foundation. |
1431 | + * |
1432 | + * This program is distributed in the hope that it will be useful, |
1433 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1434 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1435 | + * GNU Lesser General Public License for more details. |
1436 | + * |
1437 | + * You should have received a copy of the GNU Lesser General Public License |
1438 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1439 | + * |
1440 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
1441 | + */ |
1442 | + |
1443 | +#ifndef MIR_INPUT_EVDEV_LIBINPUT_DEVICE_PROVIDER_H_ |
1444 | +#define MIR_INPUT_EVDEV_LIBINPUT_DEVICE_PROVIDER_H_ |
1445 | + |
1446 | +#include "input_device_provider.h" |
1447 | + |
1448 | +namespace mir |
1449 | +{ |
1450 | +namespace input |
1451 | +{ |
1452 | +namespace evdev |
1453 | +{ |
1454 | + |
1455 | +class LibInputDeviceProvider : public InputDeviceProvider |
1456 | +{ |
1457 | +public: |
1458 | + Priority probe_device(char const* device) const override; |
1459 | + std::unique_ptr<InputDevice> create_device(char const* device) const override; |
1460 | +}; |
1461 | + |
1462 | +} |
1463 | +} |
1464 | +} |
1465 | + |
1466 | +#endif // MIR_INPUT_LIBINPUT_INPUT_DEVICE_PROVIDER_H_ |
1467 | |
1468 | === added file 'src/platforms/evdev/platform.cpp' |
1469 | --- src/platforms/evdev/platform.cpp 1970-01-01 00:00:00 +0000 |
1470 | +++ src/platforms/evdev/platform.cpp 2015-01-21 10:33:12 +0000 |
1471 | @@ -0,0 +1,179 @@ |
1472 | +/* |
1473 | + * Copyright © 2014 Canonical Ltd. |
1474 | + * |
1475 | + * This program is free software: you can redistribute it and/or modify it |
1476 | + * under the terms of the GNU Lesser General Public License version 3, |
1477 | + * as published by the Free Software Foundation. |
1478 | + * |
1479 | + * This program is distributed in the hope that it will be useful, |
1480 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1481 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1482 | + * GNU Lesser General Public License for more details. |
1483 | + * |
1484 | + * You should have received a copy of the GNU Lesser General Public License |
1485 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1486 | + * |
1487 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
1488 | + */ |
1489 | + |
1490 | +#include "platform.h" |
1491 | +#include "evdev_input_device_factory.h" |
1492 | +#include "android_device_provider.h" |
1493 | +#include "libinput_device_provider.h" |
1494 | +#include "mir/udev/wrapper.h" |
1495 | + |
1496 | +#include "mir/input/input_event_handler_register.h" |
1497 | +#include "mir/input/input_device_registry.h" |
1498 | +#include "mir/input/input_device.h" |
1499 | +#include "mir/input/input_report.h" |
1500 | + |
1501 | +namespace mi = mir::input; |
1502 | +namespace mo = mir::options; |
1503 | +namespace mu = mir::udev; |
1504 | +namespace mie = mi::evdev; |
1505 | + |
1506 | +namespace |
1507 | +{ |
1508 | +char const* const host_socket_opt = "host-socket"; |
1509 | +} |
1510 | + |
1511 | +mie::Platform::Platform(std::shared_ptr<InputReport> const& report, |
1512 | + std::unique_ptr<udev::Context> udev_context, |
1513 | + std::unique_ptr<udev::Monitor> monitor, |
1514 | + std::shared_ptr<mie::InputDeviceFactory> const& factory) : |
1515 | + report(report), |
1516 | + udev_context(std::move(udev_context)), |
1517 | + monitor(std::move(monitor)), |
1518 | + input_device_factory(factory) |
1519 | +{ |
1520 | + this->monitor->filter_by_subsystem("input"); |
1521 | + this->monitor->enable(); |
1522 | +} |
1523 | + |
1524 | +void mie::Platform::start(mi::InputEventHandlerRegister& execution, std::shared_ptr<InputDeviceRegistry> const& input_device_registry) |
1525 | +{ |
1526 | + this->input_device_registry = input_device_registry; |
1527 | + |
1528 | + execution.register_fd_handler( |
1529 | + {monitor->fd()}, |
1530 | + this, |
1531 | + [this](int /*fd*/) |
1532 | + { |
1533 | + monitor->process_events( |
1534 | + [this](mu::Monitor::EventType event, mu::Device const& dev) |
1535 | + { |
1536 | + if (!dev.devnode()) |
1537 | + return; |
1538 | + if (event == mu::Monitor::ADDED) |
1539 | + device_added(dev); |
1540 | + if (event == mu::Monitor::REMOVED) |
1541 | + device_removed(dev); |
1542 | + if (event == mu::Monitor::CHANGED) |
1543 | + device_changed(dev); |
1544 | + } |
1545 | + ); |
1546 | + }); |
1547 | + |
1548 | + execution.register_handler([this](){ scan_for_devices();}); |
1549 | +} |
1550 | + |
1551 | +void mie::Platform::scan_for_devices() |
1552 | +{ |
1553 | + mu::Enumerator input_enumerator{udev_context}; |
1554 | + input_enumerator.match_subsystem("input"); |
1555 | + input_enumerator.scan_devices(); |
1556 | + |
1557 | + for (auto& device : input_enumerator) |
1558 | + { |
1559 | + if (device.devnode() != nullptr) |
1560 | + device_added(device); |
1561 | + } |
1562 | +} |
1563 | + |
1564 | +void mie::Platform::device_added(mu::Device const& dev) |
1565 | +{ |
1566 | + if (end(devices) != find_device(dev.devnode())) |
1567 | + return; |
1568 | + |
1569 | + std::shared_ptr<mi::InputDevice> input_dev; |
1570 | + |
1571 | + try |
1572 | + { |
1573 | + input_dev = input_device_factory->create_device(dev.devnode()); |
1574 | + report->open_input_device(dev.devnode()); |
1575 | + input_device_registry->add_device(input_dev); |
1576 | + devices.emplace_back(dev.devnode(), input_dev); |
1577 | + } catch(...) |
1578 | + { |
1579 | + report->failure_opening_input_device(dev.devnode()); |
1580 | + } |
1581 | + |
1582 | +} |
1583 | + |
1584 | +void mie::Platform::device_removed(mu::Device const& dev) |
1585 | +{ |
1586 | + auto known_device_pos = find_device(dev.devnode()); |
1587 | + |
1588 | + if (known_device_pos == end(devices)) |
1589 | + return; |
1590 | + |
1591 | + input_device_registry->remove_device(known_device_pos->second); |
1592 | + devices.erase(known_device_pos); |
1593 | +} |
1594 | + |
1595 | + |
1596 | +auto mie::Platform::find_device(char const* devnode) -> decltype(devices)::iterator |
1597 | +{ |
1598 | + return std::find_if( |
1599 | + begin(devices), |
1600 | + end(devices), |
1601 | + [devnode](decltype(devices)::value_type const& item) |
1602 | + { |
1603 | + return devnode == item.first; |
1604 | + } |
1605 | + ); |
1606 | +} |
1607 | + |
1608 | +void mie::Platform::device_changed(mu::Device const& /*dev*/) |
1609 | +{ |
1610 | +} |
1611 | + |
1612 | +void mie::Platform::stop(mi::InputEventHandlerRegister& execution) |
1613 | +{ |
1614 | + execution.unregister_fd_handler(this); |
1615 | +} |
1616 | + |
1617 | +extern "C" std::unique_ptr<mi::Platform> create_input_platform( |
1618 | + std::shared_ptr<mo::Option> const& /*options*/, |
1619 | + std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/, |
1620 | + std::shared_ptr<mi::InputReport> const& report) |
1621 | +{ |
1622 | + std::unique_ptr<mu::Context> ctx{new mu::Context}; |
1623 | + std::unique_ptr<mu::Monitor> monitor{new mu::Monitor(*ctx.get())}; |
1624 | + std::initializer_list<std::shared_ptr<mie::InputDeviceProvider>> providers = |
1625 | + {std::make_shared<mie::AndroidDeviceProvider>(), std::make_shared<mie::LibInputDeviceProvider>()}; |
1626 | + return std::unique_ptr<mie::Platform>( |
1627 | + new mie::Platform( |
1628 | + report, |
1629 | + std::move(ctx), |
1630 | + std::move(monitor), |
1631 | + std::make_shared<mie::EvdevInputDeviceFactory>(providers)) |
1632 | + ); |
1633 | +} |
1634 | + |
1635 | + |
1636 | +extern "C" void add_input_platform_options( |
1637 | + boost::program_options::options_description& /*config*/) |
1638 | +{ |
1639 | + // no options to add yet |
1640 | +} |
1641 | + |
1642 | +extern "C" mi::PlatformPriority probe_input_platform( |
1643 | + mo::Option const& options) |
1644 | +{ |
1645 | + if (options.is_set(host_socket_opt)) |
1646 | + { |
1647 | + return mi::PlatformPriority::unsupported; |
1648 | + } |
1649 | + return mi::PlatformPriority::supported; |
1650 | +} |
1651 | |
1652 | === added file 'src/platforms/evdev/platform.h' |
1653 | --- src/platforms/evdev/platform.h 1970-01-01 00:00:00 +0000 |
1654 | +++ src/platforms/evdev/platform.h 2015-01-21 10:33:12 +0000 |
1655 | @@ -0,0 +1,69 @@ |
1656 | +/* |
1657 | + * Copyright © 2014 Canonical Ltd. |
1658 | + * |
1659 | + * This program is free software: you can redistribute it and/or modify it |
1660 | + * under the terms of the GNU Lesser General Public License version 3, |
1661 | + * as published by the Free Software Foundation. |
1662 | + * |
1663 | + * This program is distributed in the hope that it will be useful, |
1664 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1665 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1666 | + * GNU Lesser General Public License for more details. |
1667 | + * |
1668 | + * You should have received a copy of the GNU Lesser General Public License |
1669 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1670 | + * |
1671 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
1672 | + */ |
1673 | + |
1674 | +#ifndef MIR_INPUT_EVDEV_PLATFORM_H_ |
1675 | +#define MIR_INPUT_EVDEV_PLATFORM_H_ |
1676 | + |
1677 | +#include "mir/input/platform.h" |
1678 | +#include <vector> |
1679 | + |
1680 | +namespace mir |
1681 | +{ |
1682 | +namespace udev |
1683 | +{ |
1684 | +class Device; |
1685 | +class Monitor; |
1686 | +class Context; |
1687 | +} |
1688 | +namespace input |
1689 | +{ |
1690 | +class InputDeviceInfo; |
1691 | +namespace evdev |
1692 | +{ |
1693 | +class InputDeviceFactory; |
1694 | + |
1695 | +class Platform : public input::Platform |
1696 | +{ |
1697 | +public: |
1698 | + Platform(std::shared_ptr<InputReport> const& report, |
1699 | + std::unique_ptr<udev::Context> udev_context, |
1700 | + std::unique_ptr<udev::Monitor> monitor, |
1701 | + std::shared_ptr<InputDeviceFactory> const& factory); |
1702 | + void start(InputEventHandlerRegister& loop, std::shared_ptr<InputDeviceRegistry> const& input_device_registry) override; |
1703 | + void stop(InputEventHandlerRegister& loop) override; |
1704 | + |
1705 | +private: |
1706 | + void scan_for_devices(); |
1707 | + void device_added(udev::Device const& dev); |
1708 | + void device_removed(udev::Device const& dev); |
1709 | + void device_changed(udev::Device const& dev); |
1710 | + std::shared_ptr<InputReport> const report; |
1711 | + std::shared_ptr<udev::Context> udev_context; |
1712 | + std::unique_ptr<udev::Monitor> monitor; |
1713 | + std::shared_ptr<InputDeviceRegistry> input_device_registry; |
1714 | + std::shared_ptr<InputDeviceFactory> input_device_factory; |
1715 | + |
1716 | + std::vector<std::pair<std::string,std::shared_ptr<InputDevice>>> devices; |
1717 | + auto find_device(char const* devnode) -> decltype(devices)::iterator; |
1718 | +}; |
1719 | + |
1720 | +} |
1721 | +} |
1722 | +} |
1723 | + |
1724 | +#endif |
1725 | |
1726 | === added file 'src/platforms/input-platform-symbols.map' |
1727 | --- src/platforms/input-platform-symbols.map 1970-01-01 00:00:00 +0000 |
1728 | +++ src/platforms/input-platform-symbols.map 2015-01-21 10:33:12 +0000 |
1729 | @@ -0,0 +1,7 @@ |
1730 | +MIR_INPUT_PLATFORM_1 { |
1731 | + global: |
1732 | + add_input_platform_options; |
1733 | + create_input_platform; |
1734 | + probe_input_platform; |
1735 | + local: *; |
1736 | +}; |
1737 | |
1738 | === modified file 'src/server/report/logging/input_report.cpp' |
1739 | --- src/server/report/logging/input_report.cpp 2015-01-14 06:39:13 +0000 |
1740 | +++ src/server/report/logging/input_report.cpp 2015-01-21 10:33:12 +0000 |
1741 | @@ -107,6 +107,24 @@ |
1742 | return s; |
1743 | } |
1744 | |
1745 | +void mrl::InputReport::open_input_device(char const* device) |
1746 | +{ |
1747 | + std::stringstream ss; |
1748 | + |
1749 | + ss << "Opened input device: " << device; |
1750 | + |
1751 | + logger->log(ml::Severity::informational, ss.str(), component()); |
1752 | +} |
1753 | + |
1754 | +void mrl::InputReport::failure_opening_input_device(char const* device) |
1755 | +{ |
1756 | + std::stringstream ss; |
1757 | + |
1758 | + ss << "Failed to open input device: " << device; |
1759 | + |
1760 | + logger->log(ml::Severity::error, ss.str(), component()); |
1761 | +} |
1762 | + |
1763 | void mrl::InputReport::received_event_from_kernel(int64_t when, int type, int code, int value) |
1764 | { |
1765 | std::stringstream ss; |
1766 | |
1767 | === modified file 'src/server/report/logging/input_report.h' |
1768 | --- src/server/report/logging/input_report.h 2014-03-06 06:05:17 +0000 |
1769 | +++ src/server/report/logging/input_report.h 2015-01-21 10:33:12 +0000 |
1770 | @@ -40,6 +40,10 @@ |
1771 | InputReport(std::shared_ptr<mir::logging::Logger> const& logger); |
1772 | virtual ~InputReport() noexcept(true) = default; |
1773 | |
1774 | + void open_input_device(char const* device_node) override; |
1775 | + |
1776 | + void failure_opening_input_device(char const* device_node) override; |
1777 | + |
1778 | void received_event_from_kernel(int64_t when, int type, int code, int value); |
1779 | |
1780 | void published_key_event(int dest_fd, uint32_t seq_id, int64_t event_time); |
1781 | |
1782 | === modified file 'src/server/report/lttng/input_report.cpp' |
1783 | --- src/server/report/lttng/input_report.cpp 2014-03-06 06:05:17 +0000 |
1784 | +++ src/server/report/lttng/input_report.cpp 2015-01-21 10:33:12 +0000 |
1785 | @@ -24,6 +24,16 @@ |
1786 | #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE |
1787 | #include "input_report_tp.h" |
1788 | |
1789 | +void mir::report::lttng::InputReport::open_input_device(char const* device) |
1790 | +{ |
1791 | + mir_tracepoint(mir_server_input, opened_input_device, device); |
1792 | +} |
1793 | + |
1794 | +void mir::report::lttng::InputReport::failure_opening_input_device(char const* device) |
1795 | +{ |
1796 | + mir_tracepoint(mir_server_input, failure_opening_input_device, device); |
1797 | +} |
1798 | + |
1799 | void mir::report::lttng::InputReport::received_event_from_kernel(int64_t when, int type, int code, int value) |
1800 | { |
1801 | mir_tracepoint(mir_server_input, received_event_from_kernel, when, type, code, value); |
1802 | |
1803 | === modified file 'src/server/report/lttng/input_report.h' |
1804 | --- src/server/report/lttng/input_report.h 2014-03-06 06:05:17 +0000 |
1805 | +++ src/server/report/lttng/input_report.h 2015-01-21 10:33:12 +0000 |
1806 | @@ -36,6 +36,9 @@ |
1807 | InputReport() = default; |
1808 | virtual ~InputReport() noexcept(true) = default; |
1809 | |
1810 | + void open_input_device(char const* device_node) override; |
1811 | + void failure_opening_input_device(char const* device_node) override; |
1812 | + |
1813 | void received_event_from_kernel(int64_t when, int type, int code, int value) override; |
1814 | |
1815 | void published_key_event(int dest_fd, uint32_t seq_id, int64_t event_time) override; |
1816 | |
1817 | === modified file 'src/server/report/lttng/input_report_tp.h' |
1818 | --- src/server/report/lttng/input_report_tp.h 2015-01-14 06:39:13 +0000 |
1819 | +++ src/server/report/lttng/input_report_tp.h 2015-01-21 10:33:12 +0000 |
1820 | @@ -71,6 +71,24 @@ |
1821 | ) |
1822 | ) |
1823 | |
1824 | -#endif /* MIR_LTTNG_DISPLAY_REPORT_TP_H_ */ |
1825 | +TRACEPOINT_EVENT( |
1826 | + mir_server_input, |
1827 | + opened_input_device, |
1828 | + TP_ARGS(char const*, device), |
1829 | + TP_FIELDS( |
1830 | + ctf_string(device, device) |
1831 | + ) |
1832 | +) |
1833 | + |
1834 | +TRACEPOINT_EVENT( |
1835 | + mir_server_input, |
1836 | + failure_opening_input_device, |
1837 | + TP_ARGS(char const*, device), |
1838 | + TP_FIELDS( |
1839 | + ctf_string(device, device) |
1840 | + ) |
1841 | +) |
1842 | + |
1843 | +#endif /* MIR_LTTNG_INPUT_REPORT_TP_H_ */ |
1844 | |
1845 | #include <lttng/tracepoint-event.h> |
1846 | |
1847 | === modified file 'src/server/report/null/input_report.cpp' |
1848 | --- src/server/report/null/input_report.cpp 2014-03-06 06:05:17 +0000 |
1849 | +++ src/server/report/null/input_report.cpp 2015-01-21 10:33:12 +0000 |
1850 | @@ -20,6 +20,14 @@ |
1851 | |
1852 | namespace mrn = mir::report::null; |
1853 | |
1854 | +void mrn::InputReport::open_input_device(char const* /* device */) |
1855 | +{ |
1856 | +} |
1857 | + |
1858 | +void mrn::InputReport::failure_opening_input_device(char const* /* device */) |
1859 | +{ |
1860 | +} |
1861 | + |
1862 | void mrn::InputReport::received_event_from_kernel(int64_t /* when */, int /* type */, int /* code */, int /* value */) |
1863 | { |
1864 | } |
1865 | |
1866 | === modified file 'src/server/report/null/input_report.h' |
1867 | --- src/server/report/null/input_report.h 2014-03-06 06:05:17 +0000 |
1868 | +++ src/server/report/null/input_report.h 2015-01-21 10:33:12 +0000 |
1869 | @@ -35,6 +35,9 @@ |
1870 | InputReport() = default; |
1871 | virtual ~InputReport() noexcept(true) = default; |
1872 | |
1873 | + void open_input_device(char const* device_node) override; |
1874 | + void failure_opening_input_device(char const* device_node) override; |
1875 | + |
1876 | void received_event_from_kernel(int64_t when, int type, int code, int value); |
1877 | |
1878 | void published_key_event(int dest_fd, uint32_t seq_id, int64_t event_time); |
1879 | |
1880 | === added file 'tests/include/mir_test_doubles/mock_input_device_registry.h' |
1881 | --- tests/include/mir_test_doubles/mock_input_device_registry.h 1970-01-01 00:00:00 +0000 |
1882 | +++ tests/include/mir_test_doubles/mock_input_device_registry.h 2015-01-21 10:33:12 +0000 |
1883 | @@ -0,0 +1,46 @@ |
1884 | +/* |
1885 | + * Copyright © 2014 Canonical Ltd. |
1886 | + * |
1887 | + * This program is free software: you can redistribute it and/or modify it |
1888 | + * under the terms of the GNU General Public License version 3, |
1889 | + * as published by the Free Software Foundation. |
1890 | + * |
1891 | + * This program is distributed in the hope that it will be useful, |
1892 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1893 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1894 | + * GNU General Public License for more details. |
1895 | + * |
1896 | + * You should have received a copy of the GNU General Public License |
1897 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1898 | + * |
1899 | + * Authored by: |
1900 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
1901 | + */ |
1902 | + |
1903 | +#ifndef MIR_INPUT_MOCK_INPUT_DEVICE_REGISTRY_H_ |
1904 | +#define MIR_INPUT_MOCK_INPUT_DEVICE_REGISTRY_H_ |
1905 | + |
1906 | +#include "mir/input/input_device_registry.h" |
1907 | + |
1908 | +#include <gmock/gmock.h> |
1909 | + |
1910 | +namespace mir |
1911 | +{ |
1912 | +namespace test |
1913 | +{ |
1914 | +namespace doubles |
1915 | +{ |
1916 | + |
1917 | +class MockInputDeviceRegistry : public input::InputDeviceRegistry |
1918 | +{ |
1919 | +public: |
1920 | + MOCK_METHOD1(add_device, void(std::shared_ptr<input::InputDevice> const& device)); |
1921 | + MOCK_METHOD1(remove_device, void(std::shared_ptr<input::InputDevice> const& device)); |
1922 | +}; |
1923 | + |
1924 | +} |
1925 | +} |
1926 | +} |
1927 | + |
1928 | +#endif |
1929 | + |
1930 | |
1931 | === added file 'tests/include/mir_test_doubles/mock_input_event_handler_register.h' |
1932 | --- tests/include/mir_test_doubles/mock_input_event_handler_register.h 1970-01-01 00:00:00 +0000 |
1933 | +++ tests/include/mir_test_doubles/mock_input_event_handler_register.h 2015-01-21 10:33:12 +0000 |
1934 | @@ -0,0 +1,62 @@ |
1935 | +/* |
1936 | + * Copyright © 2014 Canonical Ltd. |
1937 | + * |
1938 | + * This program is free software: you can redistribute it and/or modify it |
1939 | + * under the terms of the GNU General Public License version 3, |
1940 | + * as published by the Free Software Foundation. |
1941 | + * |
1942 | + * This program is distributed in the hope that it will be useful, |
1943 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1944 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1945 | + * GNU General Public License for more details. |
1946 | + * |
1947 | + * You should have received a copy of the GNU General Public License |
1948 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1949 | + * |
1950 | + * Authored by: |
1951 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
1952 | + */ |
1953 | + |
1954 | +#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_MULTIPLEXER_H_ |
1955 | +#define MIR_TEST_DOUBLES_MOCK_INPUT_MULTIPLEXER_H_ |
1956 | + |
1957 | +#include "mir/input/input_event_handler_register.h" |
1958 | + |
1959 | +#include <gmock/gmock.h> |
1960 | + |
1961 | +namespace mir |
1962 | +{ |
1963 | +namespace test |
1964 | +{ |
1965 | +namespace doubles |
1966 | +{ |
1967 | + |
1968 | +class MockInputEventHandlerRegister : public input::InputEventHandlerRegister |
1969 | +{ |
1970 | +public: |
1971 | + void register_fd_handler( |
1972 | + std::initializer_list<int> fds, |
1973 | + void const* owner, |
1974 | + std::function<void(int)> const&& handler) override |
1975 | + { |
1976 | + register_fd_handler_(fds, owner, handler); |
1977 | + } |
1978 | + MOCK_METHOD3(register_fd_handler_, void( |
1979 | + std::initializer_list<int> fds, |
1980 | + void const* owner, |
1981 | + std::function<void(int)> const& handler)); |
1982 | + |
1983 | + MOCK_METHOD1(unregister_fd_handler, void(void const* owner)); |
1984 | + void register_handler(std::function<void()> const&& handler) override |
1985 | + { |
1986 | + register_handler_(handler); |
1987 | + } |
1988 | + MOCK_METHOD1(register_handler_, void(std::function<void()> const& handler)); |
1989 | +}; |
1990 | + |
1991 | +} |
1992 | +} |
1993 | +} |
1994 | + |
1995 | +#endif |
1996 | + |
1997 | |
1998 | === modified file 'tests/include/mir_test_framework/executable_path.h' |
1999 | --- tests/include/mir_test_framework/executable_path.h 2015-01-14 06:39:13 +0000 |
2000 | +++ tests/include/mir_test_framework/executable_path.h 2015-01-21 10:33:12 +0000 |
2001 | @@ -26,5 +26,7 @@ |
2002 | std::string executable_path(); |
2003 | |
2004 | std::string library_path(); |
2005 | +std::string server_platform(std::string const& name); |
2006 | +std::string client_platform(std::string const& name); |
2007 | } |
2008 | #endif /* MIR_TEST_FRAMEWORK_EXECUTABLE_PATH_H_ */ |
2009 | |
2010 | === modified file 'tests/mir_test_framework/CMakeLists.txt' |
2011 | --- tests/mir_test_framework/CMakeLists.txt 2015-01-14 06:39:13 +0000 |
2012 | +++ tests/mir_test_framework/CMakeLists.txt 2015-01-21 10:33:12 +0000 |
2013 | @@ -11,6 +11,11 @@ |
2014 | ${ANDROID_HEADERS_INCLUDE_DIRS} |
2015 | ) |
2016 | |
2017 | +add_definitions( |
2018 | + -DMIR_CLIENT_PLATFORM_PATH="${MIR_CLIENT_PLATFORM_PATH}" |
2019 | + -DMIR_SERVER_PLATFORM_PATH="${MIR_SERVER_PLATFORM_PATH}" |
2020 | + ) |
2021 | + |
2022 | set( |
2023 | TEST_FRAMEWORK_SRCS |
2024 | |
2025 | @@ -99,6 +104,7 @@ |
2026 | ${CMAKE_CURRENT_SOURCE_DIR}/udev_recordings ${CMAKE_BINARY_DIR}/bin/udev_recordings |
2027 | COMMENT "Copying umockdev recordings to build dir..." |
2028 | ) |
2029 | + |
2030 | add_custom_command(TARGET mir-test-framework POST_BUILD |
2031 | COMMAND ${CMAKE_COMMAND} -E copy_directory |
2032 | ${CMAKE_CURRENT_SOURCE_DIR}/testing-cursor-theme ${CMAKE_BINARY_DIR}/bin/testing-cursor-theme |
2033 | |
2034 | === modified file 'tests/mir_test_framework/executable_path.cpp' |
2035 | --- tests/mir_test_framework/executable_path.cpp 2015-01-14 06:39:13 +0000 |
2036 | +++ tests/mir_test_framework/executable_path.cpp 2015-01-21 10:33:12 +0000 |
2037 | @@ -24,6 +24,7 @@ |
2038 | #include <stdexcept> |
2039 | #include <boost/throw_exception.hpp> |
2040 | #include <boost/exception/errinfo_errno.hpp> |
2041 | +#include <boost/filesystem.hpp> |
2042 | |
2043 | std::string mir_test_framework::executable_path() |
2044 | { |
2045 | @@ -43,3 +44,29 @@ |
2046 | { |
2047 | return executable_path() + "/../lib"; |
2048 | } |
2049 | + |
2050 | +std::string mir_test_framework::server_platform(std::string const& name) |
2051 | +{ |
2052 | + for (auto const& option : |
2053 | + {library_path() + "/server-modules/", library_path() + "/server-platform/", std::string(MIR_SERVER_PLATFORM_PATH) + '/'}) |
2054 | + { |
2055 | + auto path_to_test = option + name; |
2056 | + if (boost::filesystem::exists(path_to_test)) |
2057 | + return path_to_test; |
2058 | + } |
2059 | + |
2060 | + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find server platform in standard search locations")); |
2061 | +} |
2062 | + |
2063 | +std::string mir_test_framework::client_platform(std::string const& name) |
2064 | +{ |
2065 | + for (auto const& option : |
2066 | + {library_path() + "/client-modules/", library_path() + "/client-platform/", std::string(MIR_CLIENT_PLATFORM_PATH) + '/'}) |
2067 | + { |
2068 | + auto path_to_test = option + name; |
2069 | + if (boost::filesystem::exists(path_to_test)) |
2070 | + return path_to_test; |
2071 | + } |
2072 | + |
2073 | + BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find server platform in standard search locations")); |
2074 | +} |
2075 | |
2076 | === added file 'tests/mir_test_framework/udev_recordings/joystick-detection.ioctl' |
2077 | --- tests/mir_test_framework/udev_recordings/joystick-detection.ioctl 1970-01-01 00:00:00 +0000 |
2078 | +++ tests/mir_test_framework/udev_recordings/joystick-detection.ioctl 2015-01-21 10:33:12 +0000 |
2079 | @@ -0,0 +1,25 @@ |
2080 | +@DEV /dev/input/event13 |
2081 | +EVIOCGBIT(1) 96 000000000000000000000000000000000000000000000000000000000000000000000000FF0F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2082 | +EVIOCGBIT(2) 2 0000 |
2083 | +EVIOCGBIT(3) 8 6300030000000000 |
2084 | +EVIOCGBIT(5) 2 0000 |
2085 | +EVIOCGBIT(17) 2 0000 |
2086 | +EVIOCGBIT(21) 16 00000000000000000000000000000000 |
2087 | +EVIOCGPROP(0) 4 00000000 |
2088 | +EVIOCGBIT(0) 8 0B00000000000000 |
2089 | +EVIOCGNAME(0) 29 4C6F676974656368204C6F6769746563682045787472656D65203344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2090 | +EVIOCGPHYS(0) 26 7573622D303030303A30303A31342E302D322F696E70757430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2091 | +EVIOCGUNIQ(0) 1 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2092 | +EVIOCGID 0 03006D0415C21001 |
2093 | +EVIOCGVERSION 0 01000100 |
2094 | +EVIOCGBIT(4) 8 1000000000000000 |
2095 | +EVIOCGBIT(18) 8 0000000000000000 |
2096 | +EVIOCGKEY(0) 96 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2097 | +EVIOCGLED(0) 8 0000000000000000 |
2098 | +EVIOCGSW(0) 8 0000000000000000 |
2099 | +EVIOCGABS 0 FC01000000000000FF030000030000003F00000000000000 |
2100 | +EVIOCGABS(1) 0 FC01000000000000FF030000030000003F00000000000000 |
2101 | +EVIOCGABS(5) 0 8000000000000000FF000000000000000F00000000000000 |
2102 | +EVIOCGABS(6) 0 0000000000000000FF000000000000000F00000000000000 |
2103 | +EVIOCGABS(16) 0 00000000FFFFFFFF01000000000000000000000000000000 |
2104 | +EVIOCGABS(17) 0 00000000FFFFFFFF01000000000000000000000000000000 |
2105 | |
2106 | === added file 'tests/mir_test_framework/udev_recordings/joystick-detection.umockdev' |
2107 | --- tests/mir_test_framework/udev_recordings/joystick-detection.umockdev 1970-01-01 00:00:00 +0000 |
2108 | +++ tests/mir_test_framework/udev_recordings/joystick-detection.umockdev 2015-01-21 10:33:12 +0000 |
2109 | @@ -0,0 +1,351 @@ |
2110 | +P: /devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/0003:046D:C215.0016/input/input258/event13 |
2111 | +N: input/event13 |
2112 | +S: input/by-id/usb-Logitech_Logitech_Extreme_3D-event-joystick |
2113 | +S: input/by-path/pci-0000:00:14.0-usb-0:2:1.0-event-joystick |
2114 | +E: DEVLINKS=/dev/input/by-id/usb-Logitech_Logitech_Extreme_3D-event-joystick /dev/input/by-path/pci-0000:00:14.0-usb-0:2:1.0-event-joystick |
2115 | +E: DEVNAME=/dev/input/event13 |
2116 | +E: ID_BUS=usb |
2117 | +E: ID_FOR_SEAT=input-pci-0000_00_14_0-usb-0_2_1_0 |
2118 | +E: ID_INPUT=1 |
2119 | +E: ID_INPUT_JOYSTICK=1 |
2120 | +E: ID_MODEL=Logitech_Extreme_3D |
2121 | +E: ID_MODEL_ENC=Logitech\x20Extreme\x203D |
2122 | +E: ID_MODEL_ID=c215 |
2123 | +E: ID_PATH=pci-0000:00:14.0-usb-0:2:1.0 |
2124 | +E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_1_0 |
2125 | +E: ID_REVISION=0204 |
2126 | +E: ID_SERIAL=Logitech_Logitech_Extreme_3D |
2127 | +E: ID_TYPE=hid |
2128 | +E: ID_USB_DRIVER=usbhid |
2129 | +E: ID_USB_INTERFACES=:030000: |
2130 | +E: ID_USB_INTERFACE_NUM=00 |
2131 | +E: ID_VENDOR=Logitech |
2132 | +E: ID_VENDOR_ENC=Logitech |
2133 | +E: ID_VENDOR_ID=046d |
2134 | +E: MAJOR=13 |
2135 | +E: MINOR=77 |
2136 | +E: SUBSYSTEM=input |
2137 | +E: TAGS=:seat:uaccess: |
2138 | +A: dev=13:77 |
2139 | +L: device=../../input258 |
2140 | +A: power/async=disabled |
2141 | +A: power/control=auto |
2142 | +A: power/runtime_active_kids=0 |
2143 | +A: power/runtime_active_time=0 |
2144 | +A: power/runtime_enabled=disabled |
2145 | +A: power/runtime_status=unsupported |
2146 | +A: power/runtime_suspended_time=0 |
2147 | +A: power/runtime_usage=0 |
2148 | + |
2149 | +P: /devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/0003:046D:C215.0016/input/input258 |
2150 | +E: ABS=30063 |
2151 | +E: EV=1b |
2152 | +E: ID_BUS=usb |
2153 | +E: ID_FOR_SEAT=input-pci-0000_00_14_0-usb-0_2_1_0 |
2154 | +E: ID_INPUT=1 |
2155 | +E: ID_INPUT_JOYSTICK=1 |
2156 | +E: ID_MODEL=Logitech_Extreme_3D |
2157 | +E: ID_MODEL_ENC=Logitech\x20Extreme\x203D |
2158 | +E: ID_MODEL_ID=c215 |
2159 | +E: ID_PATH=pci-0000:00:14.0-usb-0:2:1.0 |
2160 | +E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_2_1_0 |
2161 | +E: ID_REVISION=0204 |
2162 | +E: ID_SERIAL=Logitech_Logitech_Extreme_3D |
2163 | +E: ID_TYPE=hid |
2164 | +E: ID_USB_DRIVER=usbhid |
2165 | +E: ID_USB_INTERFACES=:030000: |
2166 | +E: ID_USB_INTERFACE_NUM=00 |
2167 | +E: ID_VENDOR=Logitech |
2168 | +E: ID_VENDOR_ENC=Logitech |
2169 | +E: ID_VENDOR_ID=046d |
2170 | +E: KEY=fff00000000 0 0 0 0 |
2171 | +E: MODALIAS=input:b0003v046DpC215e0110-e0,1,3,4,k120,121,122,123,124,125,126,127,128,129,12A,12B,ra0,1,5,6,10,11,m4,lsfw |
2172 | +E: MSC=10 |
2173 | +E: NAME="Logitech Logitech Extreme 3D" |
2174 | +E: PHYS="usb-0000:00:14.0-2/input0" |
2175 | +E: PRODUCT=3/46d/c215/110 |
2176 | +E: PROP=0 |
2177 | +E: SUBSYSTEM=input |
2178 | +E: TAGS=:seat: |
2179 | +E: UNIQ="" |
2180 | +A: capabilities/abs=30063 |
2181 | +A: capabilities/ev=1b |
2182 | +A: capabilities/ff=0 |
2183 | +A: capabilities/key=fff00000000 0 0 0 0 |
2184 | +A: capabilities/led=0 |
2185 | +A: capabilities/msc=10 |
2186 | +A: capabilities/rel=0 |
2187 | +A: capabilities/snd=0 |
2188 | +A: capabilities/sw=0 |
2189 | +L: device=../../../0003:046D:C215.0016 |
2190 | +A: id/bustype=0003 |
2191 | +A: id/product=c215 |
2192 | +A: id/vendor=046d |
2193 | +A: id/version=0110 |
2194 | +A: modalias=input:b0003v046DpC215e0110-e0,1,3,4,k120,121,122,123,124,125,126,127,128,129,12A,12B,ra0,1,5,6,10,11,m4,lsfw |
2195 | +A: name=Logitech Logitech Extreme 3D |
2196 | +A: phys=usb-0000:00:14.0-2/input0 |
2197 | +A: power/async=disabled |
2198 | +A: power/control=auto |
2199 | +A: power/runtime_active_kids=0 |
2200 | +A: power/runtime_active_time=0 |
2201 | +A: power/runtime_enabled=disabled |
2202 | +A: power/runtime_status=unsupported |
2203 | +A: power/runtime_suspended_time=0 |
2204 | +A: power/runtime_usage=0 |
2205 | +A: properties=0 |
2206 | +A: uniq= |
2207 | + |
2208 | +P: /devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/0003:046D:C215.0016 |
2209 | +E: DRIVER=logitech |
2210 | +E: HID_ID=0003:0000046D:0000C215 |
2211 | +E: HID_NAME=Logitech Logitech Extreme 3D |
2212 | +E: HID_PHYS=usb-0000:00:14.0-2/input0 |
2213 | +E: MODALIAS=hid:b0003g0000v0000046Dp0000C215 |
2214 | +E: SUBSYSTEM=hid |
2215 | +E: UPOWER_VENDOR=Logitech, Inc. |
2216 | +L: driver=../../../../../../../bus/hid/drivers/logitech |
2217 | +A: modalias=hid:b0003g0000v0000046Dp0000C215 |
2218 | +A: power/async=disabled |
2219 | +A: power/control=auto |
2220 | +A: power/runtime_active_kids=0 |
2221 | +A: power/runtime_active_time=0 |
2222 | +A: power/runtime_enabled=disabled |
2223 | +A: power/runtime_status=unsupported |
2224 | +A: power/runtime_suspended_time=0 |
2225 | +A: power/runtime_usage=0 |
2226 | +H: report_descriptor=05010904A101A1029502750A150026FF03350046FF03093009318102750495012507463B01661400093981426500750826FF0046FF0009358102A495087501250145010509190129088102B409368102950475012501450105091909290C810295048101C0A1029504750826FF0046FF000600FF0901B102C0C0 |
2227 | + |
2228 | +P: /devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0 |
2229 | +E: DEVTYPE=usb_interface |
2230 | +E: DRIVER=usbhid |
2231 | +E: ID_MODEL_FROM_DATABASE=Extreme 3D Pro |
2232 | +E: ID_VENDOR_FROM_DATABASE=Logitech, Inc. |
2233 | +E: INTERFACE=3/0/0 |
2234 | +E: MODALIAS=usb:v046DpC215d0204dc00dsc00dp00ic03isc00ip00in00 |
2235 | +E: PRODUCT=46d/c215/204 |
2236 | +E: SUBSYSTEM=usb |
2237 | +E: TYPE=0/0/0 |
2238 | +A: bAlternateSetting= 0 |
2239 | +A: bInterfaceClass=03 |
2240 | +A: bInterfaceNumber=00 |
2241 | +A: bInterfaceProtocol=00 |
2242 | +A: bInterfaceSubClass=00 |
2243 | +A: bNumEndpoints=01 |
2244 | +L: driver=../../../../../../bus/usb/drivers/usbhid |
2245 | +A: modalias=usb:v046DpC215d0204dc00dsc00dp00ic03isc00ip00in00 |
2246 | +A: power/async=enabled |
2247 | +A: power/runtime_active_kids=0 |
2248 | +A: power/runtime_enabled=enabled |
2249 | +A: power/runtime_status=suspended |
2250 | +A: power/runtime_usage=0 |
2251 | +A: supports_autosuspend=1 |
2252 | + |
2253 | +P: /devices/pci0000:00/0000:00:14.0/usb3/3-2 |
2254 | +N: bus/usb/003/043=12011001000000086D0415C204020102000109022200010100800F090400000103000000092110012101227A000705810307000A |
2255 | +E: BUSNUM=003 |
2256 | +E: DEVNAME=/dev/bus/usb/003/043 |
2257 | +E: DEVNUM=043 |
2258 | +E: DEVTYPE=usb_device |
2259 | +E: DRIVER=usb |
2260 | +E: ID_BUS=usb |
2261 | +E: ID_MODEL=Logitech_Extreme_3D |
2262 | +E: ID_MODEL_ENC=Logitech\x20Extreme\x203D |
2263 | +E: ID_MODEL_FROM_DATABASE=Extreme 3D Pro |
2264 | +E: ID_MODEL_ID=c215 |
2265 | +E: ID_REVISION=0204 |
2266 | +E: ID_SERIAL=Logitech_Logitech_Extreme_3D |
2267 | +E: ID_USB_INTERFACES=:030000: |
2268 | +E: ID_VENDOR=Logitech |
2269 | +E: ID_VENDOR_ENC=Logitech |
2270 | +E: ID_VENDOR_FROM_DATABASE=Logitech, Inc. |
2271 | +E: ID_VENDOR_ID=046d |
2272 | +E: MAJOR=189 |
2273 | +E: MINOR=298 |
2274 | +E: PRODUCT=46d/c215/204 |
2275 | +E: SUBSYSTEM=usb |
2276 | +E: TYPE=0/0/0 |
2277 | +E: UPOWER_VENDOR=Logitech, Inc. |
2278 | +A: authorized=1 |
2279 | +A: avoid_reset_quirk=0 |
2280 | +A: bConfigurationValue=1 |
2281 | +A: bDeviceClass=00 |
2282 | +A: bDeviceProtocol=00 |
2283 | +A: bDeviceSubClass=00 |
2284 | +A: bMaxPacketSize0=8 |
2285 | +A: bMaxPower=30mA |
2286 | +A: bNumConfigurations=1 |
2287 | +A: bNumInterfaces= 1 |
2288 | +A: bcdDevice=0204 |
2289 | +A: bmAttributes=80 |
2290 | +A: busnum=3 |
2291 | +A: configuration= |
2292 | +H: descriptors=12011001000000086D0415C204020102000109022200010100800F090400000103000000092110012101227A000705810307000A |
2293 | +A: dev=189:298 |
2294 | +A: devnum=43 |
2295 | +A: devpath=2 |
2296 | +L: driver=../../../../../bus/usb/drivers/usb |
2297 | +A: idProduct=c215 |
2298 | +A: idVendor=046d |
2299 | +A: ltm_capable=no |
2300 | +A: manufacturer=Logitech |
2301 | +A: maxchild=0 |
2302 | +L: port=../3-0:1.0/usb3-port2 |
2303 | +A: power/active_duration=1287064 |
2304 | +A: power/async=enabled |
2305 | +A: power/autosuspend=2 |
2306 | +A: power/autosuspend_delay_ms=2000 |
2307 | +A: power/connected_duration=1287064 |
2308 | +A: power/control=on |
2309 | +A: power/level=on |
2310 | +A: power/persist=1 |
2311 | +A: power/runtime_active_kids=0 |
2312 | +A: power/runtime_active_time=1286764 |
2313 | +A: power/runtime_enabled=forbidden |
2314 | +A: power/runtime_status=active |
2315 | +A: power/runtime_suspended_time=0 |
2316 | +A: power/runtime_usage=1 |
2317 | +A: product=Logitech Extreme 3D |
2318 | +A: quirks=0x0 |
2319 | +A: removable=unknown |
2320 | +A: speed=1.5 |
2321 | +A: urbnum=24 |
2322 | +A: version= 1.10 |
2323 | + |
2324 | +P: /devices/pci0000:00/0000:00:14.0/usb3 |
2325 | +N: bus/usb/003/001=12010002090001406B1D020016030302010109021900010100E0000904000001090000000705810304000C |
2326 | +E: BUSNUM=003 |
2327 | +E: DEVNAME=/dev/bus/usb/003/001 |
2328 | +E: DEVNUM=001 |
2329 | +E: DEVTYPE=usb_device |
2330 | +E: DRIVER=usb |
2331 | +E: ID_BUS=usb |
2332 | +E: ID_FOR_SEAT=usb-pci-0000_00_14_0 |
2333 | +E: ID_MODEL=xHCI_Host_Controller |
2334 | +E: ID_MODEL_ENC=xHCI\x20Host\x20Controller |
2335 | +E: ID_MODEL_FROM_DATABASE=2.0 root hub |
2336 | +E: ID_MODEL_ID=0002 |
2337 | +E: ID_PATH=pci-0000:00:14.0 |
2338 | +E: ID_PATH_TAG=pci-0000_00_14_0 |
2339 | +E: ID_REVISION=0316 |
2340 | +E: ID_SERIAL=Linux_3.16.0-24-generic_xhci_hcd_xHCI_Host_Controller_0000:00:14.0 |
2341 | +E: ID_SERIAL_SHORT=0000:00:14.0 |
2342 | +E: ID_USB_INTERFACES=:090000: |
2343 | +E: ID_VENDOR=Linux_3.16.0-24-generic_xhci_hcd |
2344 | +E: ID_VENDOR_ENC=Linux\x203.16.0-24-generic\x20xhci_hcd |
2345 | +E: ID_VENDOR_FROM_DATABASE=Linux Foundation |
2346 | +E: ID_VENDOR_ID=1d6b |
2347 | +E: MAJOR=189 |
2348 | +E: MINOR=256 |
2349 | +E: PRODUCT=1d6b/2/316 |
2350 | +E: SUBSYSTEM=usb |
2351 | +E: TAGS=:seat: |
2352 | +E: TYPE=9/0/1 |
2353 | +A: authorized=1 |
2354 | +A: authorized_default=1 |
2355 | +A: avoid_reset_quirk=0 |
2356 | +A: bConfigurationValue=1 |
2357 | +A: bDeviceClass=09 |
2358 | +A: bDeviceProtocol=01 |
2359 | +A: bDeviceSubClass=00 |
2360 | +A: bMaxPacketSize0=64 |
2361 | +A: bMaxPower=0mA |
2362 | +A: bNumConfigurations=1 |
2363 | +A: bNumInterfaces= 1 |
2364 | +A: bcdDevice=0316 |
2365 | +A: bmAttributes=e0 |
2366 | +A: busnum=3 |
2367 | +A: configuration= |
2368 | +H: descriptors=12010002090001406B1D020016030302010109021900010100E0000904000001090000000705810304000C |
2369 | +A: dev=189:256 |
2370 | +A: devnum=1 |
2371 | +A: devpath=0 |
2372 | +L: driver=../../../../bus/usb/drivers/usb |
2373 | +A: idProduct=0002 |
2374 | +A: idVendor=1d6b |
2375 | +A: ltm_capable=no |
2376 | +A: manufacturer=Linux 3.16.0-24-generic xhci_hcd |
2377 | +A: maxchild=14 |
2378 | +A: power/active_duration=471394472 |
2379 | +A: power/async=enabled |
2380 | +A: power/autosuspend=0 |
2381 | +A: power/autosuspend_delay_ms=0 |
2382 | +A: power/connected_duration=493735372 |
2383 | +A: power/control=auto |
2384 | +A: power/level=auto |
2385 | +A: power/runtime_active_kids=3 |
2386 | +A: power/runtime_active_time=466119148 |
2387 | +A: power/runtime_enabled=enabled |
2388 | +A: power/runtime_status=active |
2389 | +A: power/runtime_suspended_time=22335316 |
2390 | +A: power/runtime_usage=0 |
2391 | +A: power/wakeup=disabled |
2392 | +A: power/wakeup_abort_count= |
2393 | +A: power/wakeup_active= |
2394 | +A: power/wakeup_active_count= |
2395 | +A: power/wakeup_count= |
2396 | +A: power/wakeup_expire_count= |
2397 | +A: power/wakeup_last_time_ms= |
2398 | +A: power/wakeup_max_time_ms= |
2399 | +A: power/wakeup_total_time_ms= |
2400 | +A: product=xHCI Host Controller |
2401 | +A: quirks=0x0 |
2402 | +A: removable=unknown |
2403 | +A: serial=0000:00:14.0 |
2404 | +A: speed=480 |
2405 | +A: urbnum=1514 |
2406 | +A: version= 2.00 |
2407 | + |
2408 | +P: /devices/pci0000:00/0000:00:14.0 |
2409 | +E: DRIVER=xhci_hcd |
2410 | +E: ID_MODEL_FROM_DATABASE=8 Series/C220 Series Chipset Family USB xHCI |
2411 | +E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller |
2412 | +E: ID_PCI_INTERFACE_FROM_DATABASE=XHCI |
2413 | +E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller |
2414 | +E: ID_VENDOR_FROM_DATABASE=Intel Corporation |
2415 | +E: MODALIAS=pci:v00008086d00008C31sv00001558sd00007410bc0Csc03i30 |
2416 | +E: PCI_CLASS=C0330 |
2417 | +E: PCI_ID=8086:8C31 |
2418 | +E: PCI_SLOT_NAME=0000:00:14.0 |
2419 | +E: PCI_SUBSYS_ID=1558:7410 |
2420 | +E: SUBSYSTEM=pci |
2421 | +A: broken_parity_status=0 |
2422 | +A: class=0x0c0330 |
2423 | +H: config=8680318C060490020530030C000000000400E2F7000000000000000000000000000000000000000000000000581510740000000070000000000000000B010000FD01368089C60F8000000000000000009F6E8807000000000000000000000000302000000000000000000000000000000180C2C108000000000000000000000005008700F802E0FE000000000000000000000000000000000000000000000000400100000000000000000000000000000F000100000000000000000000000000030420C0030C3000030C300000000000FF3F0000FF3F00003F0000003F000000A0000000D03C000000000000D8D8D8080000000000000000B10F060800000000 |
2424 | +A: consistent_dma_mask_bits=64 |
2425 | +A: d3cold_allowed=1 |
2426 | +A: device=0x8c31 |
2427 | +A: dma_mask_bits=64 |
2428 | +L: driver=../../../bus/pci/drivers/xhci_hcd |
2429 | +A: driver_override=(null) |
2430 | +A: enabled=1 |
2431 | +A: irq=42 |
2432 | +A: local_cpulist=0-7 |
2433 | +A: local_cpus=00000000,00000000,00000000,00000000,00000000,00000000,00000000,000000ff |
2434 | +A: modalias=pci:v00008086d00008C31sv00001558sd00007410bc0Csc03i30 |
2435 | +A: msi_bus= |
2436 | +A: msi_irqs/42=msi |
2437 | +A: numa_node=-1 |
2438 | +A: pools=poolinfo - 0.1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 0 0 128 0\nbuffer-32 0 0 32 0\nxHCI 1KB stream ctx arrays 0 0 1024 0\nxHCI 256 byte stream ctx arrays 0 0 256 0\nxHCI input/output contexts 7 11 2112 11\nxHCI ring segments 82 152 1024 38\nbuffer-2048 0 38 2048 19\nbuffer-512 0 16 512 2\nbuffer-128 3 32 128 1\nbuffer-32 0 0 32 0 |
2439 | +A: power/async=enabled |
2440 | +A: power/control=on |
2441 | +A: power/runtime_active_kids=1 |
2442 | +A: power/runtime_active_time=493735800 |
2443 | +A: power/runtime_enabled=forbidden |
2444 | +A: power/runtime_status=active |
2445 | +A: power/runtime_suspended_time=0 |
2446 | +A: power/runtime_usage=1 |
2447 | +A: power/wakeup=enabled |
2448 | +A: power/wakeup_abort_count=0 |
2449 | +A: power/wakeup_active=0 |
2450 | +A: power/wakeup_active_count=0 |
2451 | +A: power/wakeup_count=0 |
2452 | +A: power/wakeup_expire_count=0 |
2453 | +A: power/wakeup_last_time_ms=1534 |
2454 | +A: power/wakeup_max_time_ms=0 |
2455 | +A: power/wakeup_total_time_ms=0 |
2456 | +A: resource=0x00000000f7e20000 0x00000000f7e2ffff 0x0000000000140204\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000 |
2457 | +A: subsystem_device=0x7410 |
2458 | +A: subsystem_vendor=0x1558 |
2459 | +A: vendor=0x8086 |
2460 | + |
2461 | |
2462 | === added file 'tests/mir_test_framework/udev_recordings/mt-screen-detection.ioctl' |
2463 | --- tests/mir_test_framework/udev_recordings/mt-screen-detection.ioctl 1970-01-01 00:00:00 +0000 |
2464 | +++ tests/mir_test_framework/udev_recordings/mt-screen-detection.ioctl 2015-01-21 10:33:12 +0000 |
2465 | @@ -0,0 +1,28 @@ |
2466 | +@DEV /dev/input/event4 |
2467 | +EVIOCGBIT(1) 96 000000000000000000000000000010000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2468 | +EVIOCGBIT(2) 2 0000 |
2469 | +EVIOCGBIT(3) 8 0300000100006306 |
2470 | +EVIOCGBIT(5) 2 0000 |
2471 | +EVIOCGBIT(17) 2 0000 |
2472 | +EVIOCGBIT(21) 16 00000000000000000000000000000000 |
2473 | +EVIOCGPROP(0) 8 02000000 |
2474 | +EVIOCGBIT(0) 8 0B00000000000000 |
2475 | +EVIOCGNAME(0) 8 6D746B2D747064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2476 | +EVIOCGID 0 0000000000000000 |
2477 | +EVIOCGPHYS(0) 0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2478 | +EVIOCGUNIQ(0) 0 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2479 | +EVIOCGVERSION 0 01000100 |
2480 | +EVIOCGBIT(4) 8 0000000000000000 |
2481 | +EVIOCGBIT(18) 8 0000000000000000 |
2482 | +EVIOCGKEY(0) 96 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2483 | +EVIOCGLED(0) 4 00000000 |
2484 | +EVIOCGSW(0) 4 00000000 |
2485 | +EVIOCGABS 0 00000000000000001C02000000000000000000001C020000 |
2486 | +EVIOCGABS(1) 0 0000000000000000C00300000000000000000000C0030000 |
2487 | +EVIOCGABS(24) 0 0000000000000000FF000000000000000000000000000000 |
2488 | +EVIOCGABS(48) 0 000000000000000064000000000000000000000000000000 |
2489 | +EVIOCGABS(49) 0 000000000000000064000000000000000000000000000000 |
2490 | +EVIOCGABS(53) 0 00000000000000001C020000000000000000000000000000 |
2491 | +EVIOCGABS(54) 0 0000000000000000C0030000000000000000000000000000 |
2492 | +EVIOCGABS(57) 0 000000000000000000000000000000000000000000000000 |
2493 | +EVIOCGABS(58) 0 0000000000000000FF000000000000000000000000000000 |
2494 | |
2495 | === added file 'tests/mir_test_framework/udev_recordings/mt-screen-detection.umockdev' |
2496 | --- tests/mir_test_framework/udev_recordings/mt-screen-detection.umockdev 1970-01-01 00:00:00 +0000 |
2497 | +++ tests/mir_test_framework/udev_recordings/mt-screen-detection.umockdev 2015-01-21 10:33:12 +0000 |
2498 | @@ -0,0 +1,44 @@ |
2499 | +P: /devices/virtual/input/input4/event4 |
2500 | +N: input/event4 |
2501 | +E: DEVNAME=/dev/input/event4 |
2502 | +E: ID_INPUT=1 |
2503 | +E: ID_INPUT_KEY=1 |
2504 | +E: ID_INPUT_TOUCHSCREEN=1 |
2505 | +E: MAJOR=13 |
2506 | +E: MINOR=68 |
2507 | +E: SUBSYSTEM=input |
2508 | +A: dev=13:68 |
2509 | +L: device=../../input4 |
2510 | + |
2511 | +P: /devices/virtual/input/input4 |
2512 | +E: ABS=6630000 1000003 |
2513 | +E: EV=b |
2514 | +E: ID_INPUT=1 |
2515 | +E: ID_INPUT_KEY=1 |
2516 | +E: ID_INPUT_TOUCHSCREEN=1 |
2517 | +E: KEY=400 0 0 0 0 0 0 100000 0 0 0 |
2518 | +E: MODALIAS=input:b0000v0000p0000e0000-e0,1,3,k74,14A,ra0,1,18,30,31,35,36,39,3A,mlsfw |
2519 | +E: NAME="mtk-tpd" |
2520 | +E: PRODUCT=0/0/0/0 |
2521 | +E: PROP=2 |
2522 | +E: SUBSYSTEM=input |
2523 | +E: TAGS=:seat: |
2524 | +A: capabilities/abs=6630000 1000003 |
2525 | +A: capabilities/ev=b |
2526 | +A: capabilities/ff=0 |
2527 | +A: capabilities/key=400 0 0 0 0 0 0 100000 0 0 0 |
2528 | +A: capabilities/led=0 |
2529 | +A: capabilities/msc=0 |
2530 | +A: capabilities/rel=0 |
2531 | +A: capabilities/snd=0 |
2532 | +A: capabilities/sw=0 |
2533 | +A: id/bustype=0000 |
2534 | +A: id/product=0000 |
2535 | +A: id/vendor=0000 |
2536 | +A: id/version=0000 |
2537 | +A: modalias=input:b0000v0000p0000e0000-e0,1,3,k74,14A,ra0,1,18,30,31,35,36,39,3A,mlsfw |
2538 | +A: name=mtk-tpd |
2539 | +A: phys= |
2540 | +A: properties=2 |
2541 | +A: uniq= |
2542 | + |
2543 | |
2544 | === modified file 'tests/mir_test_framework/udev_recordings/synaptics-touchpad.ioctl' |
2545 | --- tests/mir_test_framework/udev_recordings/synaptics-touchpad.ioctl 2014-02-17 03:46:06 +0000 |
2546 | +++ tests/mir_test_framework/udev_recordings/synaptics-touchpad.ioctl 2015-01-21 10:33:12 +0000 |
2547 | @@ -19,11 +19,4 @@ |
2548 | EVIOCGNAME(0) 27 53796E50532F322053796E61707469637320546F756368506164000000000000200B00A8A37F0000C8A59DC6A37F0000C00800A8A37F0000C00407B8A37F0000F0DF950100000000F53326C8A37F00 |
2549 | EVIOCGPHYS(0) 22 697361303036302F736572696F322F696E707574300068506164000000000000200B00A8A37F0000C8A59DC6A37F0000C00800A8A37F0000C00407B8A37F0000F0DF950100000000F53326C8A37F00 |
2550 | EVIOCGNAME(0) 18 48444120496E74656C20504348204D6963007574300068506164000000000000200B00CC1C7F0000C81563E91C7F0000C00800CC1C7F0000C074CCDA1C7F0000307F170200000000F5A3EBEA1C7F00 |
2551 | -EVIOCGID 0 0000000000000000 |
2552 | EVIOCGPHYS(0) 5 414C5341006E74656C20504348204D6963007574300068506164000000000000200B00CC1C7F0000C81563E91C7F0000C00800CC1C7F0000C074CCDA1C7F0000307F170200000000F5A3EBEA1C7F00 |
2553 | -EVIOCGBIT(1) 96 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
2554 | -EVIOCGBIT(3) 8 0000000000000000 |
2555 | -EVIOCGBIT(5) 2 1000 |
2556 | -EVIOCGPROP(0) 4 00000000 |
2557 | -EVIOCGNAME(0) 27 53796E50532F322053796E61707469637320546F756368506164000000000000200B00E8217F0000C885F704227F0000C00800E8217F0000C0E460F6217F0000303FF40100000000F5138006227F00 |
2558 | -EVIOCGPHYS(0) 22 697361303036302F736572696F322F696E707574300068506164000000000000200B00E8217F0000C885F704227F0000C00800E8217F0000C0E460F6217F0000303FF40100000000F5138006227F00 |
2559 | |
2560 | === modified file 'tests/unit-tests/CMakeLists.txt' |
2561 | --- tests/unit-tests/CMakeLists.txt 2015-01-14 06:39:13 +0000 |
2562 | +++ tests/unit-tests/CMakeLists.txt 2015-01-21 10:33:12 +0000 |
2563 | @@ -12,6 +12,7 @@ |
2564 | add_definitions( |
2565 | -DTEST_RECORDINGS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/input_recordings/" |
2566 | -DMIR_CLIENT_DRIVER_BINARY="${MIR_CLIENT_DRIVER_BINARY}" |
2567 | + -DMIR_SERVER_INPUT_PLATFORM_VERSION="${MIR_SERVER_INPUT_PLATFORM_VERSION}" |
2568 | ) |
2569 | |
2570 | include_directories(${DRM_INCLUDE_DIRS} ${GBM_INCLUDE_DIRS} ${UMOCKDEV_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}) |
2571 | @@ -36,6 +37,7 @@ |
2572 | test_thread_safe_list.cpp |
2573 | test_fatal.cpp |
2574 | test_fd.cpp |
2575 | + test_find_best.cpp |
2576 | test_shared_library_prober.cpp |
2577 | ) |
2578 | |
2579 | |
2580 | === modified file 'tests/unit-tests/input/CMakeLists.txt' |
2581 | --- tests/unit-tests/input/CMakeLists.txt 2015-01-14 06:39:13 +0000 |
2582 | +++ tests/unit-tests/input/CMakeLists.txt 2015-01-21 10:33:12 +0000 |
2583 | @@ -1,4 +1,5 @@ |
2584 | add_subdirectory(android) |
2585 | +add_subdirectory(evdev) |
2586 | |
2587 | list(APPEND UNIT_TEST_SOURCES |
2588 | ${CMAKE_CURRENT_SOURCE_DIR}/test_event_filter_chain.cpp |
2589 | |
2590 | === added directory 'tests/unit-tests/input/evdev' |
2591 | === added file 'tests/unit-tests/input/evdev/CMakeLists.txt' |
2592 | --- tests/unit-tests/input/evdev/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
2593 | +++ tests/unit-tests/input/evdev/CMakeLists.txt 2015-01-21 10:33:12 +0000 |
2594 | @@ -0,0 +1,13 @@ |
2595 | +list(APPEND UNIT_TEST_SOURCES |
2596 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_android_device_provider.cpp |
2597 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_evdev_device_detection.cpp |
2598 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_evdev_input_device_factory.cpp |
2599 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_libinput_device_provider.cpp |
2600 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_platform.cpp |
2601 | + $<TARGET_OBJECTS:mirplatforminputevdevobjects> |
2602 | +) |
2603 | + |
2604 | +set( |
2605 | + UNIT_TEST_SOURCES |
2606 | + ${UNIT_TEST_SOURCES} |
2607 | + PARENT_SCOPE) |
2608 | |
2609 | === added file 'tests/unit-tests/input/evdev/test_android_device_provider.cpp' |
2610 | --- tests/unit-tests/input/evdev/test_android_device_provider.cpp 1970-01-01 00:00:00 +0000 |
2611 | +++ tests/unit-tests/input/evdev/test_android_device_provider.cpp 2015-01-21 10:33:12 +0000 |
2612 | @@ -0,0 +1,83 @@ |
2613 | +/* |
2614 | + * Copyright © 2014 Canonical Ltd. |
2615 | + * |
2616 | + * This program is free software: you can redistribute it and/or modify it |
2617 | + * under the terms of the GNU General Public License version 3, |
2618 | + * as published by the Free Software Foundation. |
2619 | + * |
2620 | + * This program is distributed in the hope that it will be useful, |
2621 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2622 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2623 | + * GNU General Public License for more details. |
2624 | + * |
2625 | + * You should have received a copy of the GNU General Public License |
2626 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2627 | + * |
2628 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
2629 | + */ |
2630 | + |
2631 | +#include "src/platforms/evdev/android_device_provider.h" |
2632 | +#include "mir_test_framework/udev_environment.h" |
2633 | + |
2634 | +#include <gmock/gmock.h> |
2635 | +#include <gtest/gtest.h> |
2636 | + |
2637 | +namespace mi = mir::input; |
2638 | +namespace mie = mi::evdev; |
2639 | +namespace mtf = mir_test_framework; |
2640 | + |
2641 | +struct AndroidStack : public ::testing::TestWithParam<std::tuple<char const*, char const*, mie::Priority>> |
2642 | +{ |
2643 | + mtf::UdevEnvironment env; |
2644 | +}; |
2645 | + |
2646 | +TEST_P(AndroidStack, device_probing_yields_expected_priority) |
2647 | +{ |
2648 | + using namespace testing; |
2649 | + auto const& param = GetParam(); |
2650 | + env.add_standard_device(std::get<0>(param)); |
2651 | + mie::AndroidDeviceProvider provider; |
2652 | + |
2653 | + EXPECT_THAT(provider.probe_device(std::get<1>(param)), Eq(std::get<2>(param))); |
2654 | +} |
2655 | + |
2656 | +INSTANTIATE_TEST_CASE_P(InputDeviceProviderTest, |
2657 | + AndroidStack, |
2658 | + ::testing::Values( |
2659 | + std::make_tuple( |
2660 | + "synaptics-touchpad", |
2661 | + "/dev/input/event12", |
2662 | + mie::Priority::unsupported |
2663 | + ), |
2664 | + std::make_tuple( |
2665 | + "bluetooth-magic-trackpad", |
2666 | + "/dev/input/event13", |
2667 | + mie::Priority::unsupported |
2668 | + ), |
2669 | + std::make_tuple( |
2670 | + "mt-screen-detection", |
2671 | + "/dev/input/event4", |
2672 | + mie::Priority::best |
2673 | + ), |
2674 | + std::make_tuple( |
2675 | + "joystick-detection", |
2676 | + "/dev/input/event13", |
2677 | + mie::Priority::supported |
2678 | + ), |
2679 | + std::make_tuple( |
2680 | + "usb-mouse", |
2681 | + "/dev/input/event13", |
2682 | + mie::Priority::supported |
2683 | + ), |
2684 | + std::make_tuple( |
2685 | + "usb-keyboard", |
2686 | + "/dev/input/event14", |
2687 | + mie::Priority::supported |
2688 | + ), |
2689 | + std::make_tuple( |
2690 | + "laptop-keyboard", |
2691 | + "/dev/input/event4", |
2692 | + mie::Priority::supported |
2693 | + ) |
2694 | + )); |
2695 | + |
2696 | |
2697 | === added file 'tests/unit-tests/input/evdev/test_evdev_device_detection.cpp' |
2698 | --- tests/unit-tests/input/evdev/test_evdev_device_detection.cpp 1970-01-01 00:00:00 +0000 |
2699 | +++ tests/unit-tests/input/evdev/test_evdev_device_detection.cpp 2015-01-21 10:33:12 +0000 |
2700 | @@ -0,0 +1,86 @@ |
2701 | +/* |
2702 | + * Copyright © 2014 Canonical Ltd. |
2703 | + * |
2704 | + * This program is free software: you can redistribute it and/or modify it |
2705 | + * under the terms of the GNU General Public License version 3, |
2706 | + * as published by the Free Software Foundation. |
2707 | + * |
2708 | + * This program is distributed in the hope that it will be useful, |
2709 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2710 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2711 | + * GNU General Public License for more details. |
2712 | + * |
2713 | + * You should have received a copy of the GNU General Public License |
2714 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2715 | + * |
2716 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
2717 | + */ |
2718 | + |
2719 | +#include "src/platforms/evdev/evdev_device_detection.h" |
2720 | +#include "mir/input/device_capability.h" |
2721 | + |
2722 | +#include "mir_test_framework/udev_environment.h" |
2723 | + |
2724 | +#include <gtest/gtest.h> |
2725 | +#include <tuple> |
2726 | + |
2727 | +namespace mtf = mir_test_framework; |
2728 | +namespace mi = mir::input; |
2729 | +namespace mie = mi::evdev; |
2730 | + |
2731 | +struct EvdevDeviceDetection : public ::testing::TestWithParam<std::tuple<char const*, char const*, mi::DeviceCapabilities>> |
2732 | +{ |
2733 | + mtf::UdevEnvironment env; |
2734 | +}; |
2735 | + |
2736 | +TEST_P(EvdevDeviceDetection, evaluates_expected_input_class) |
2737 | +{ |
2738 | + using namespace testing; |
2739 | + auto const& param = GetParam(); |
2740 | + env.add_standard_device(std::get<0>(param)); |
2741 | + EXPECT_THAT(mie::detect_device_capabilities((std::get<1>(param))),Eq(std::get<2>(param))); |
2742 | +} |
2743 | + |
2744 | +INSTANTIATE_TEST_CASE_P(InputDeviceCapabilityDetection, |
2745 | + EvdevDeviceDetection, |
2746 | + ::testing::Values( |
2747 | + std::make_tuple( |
2748 | + "synaptics-touchpad", |
2749 | + "/dev/input/event12", |
2750 | + mi::DeviceCapability::touchpad |
2751 | + ), |
2752 | + std::make_tuple( |
2753 | + "laptop-keyboard", |
2754 | + "/dev/input/event4", |
2755 | + mi::DeviceCapability::keyboard |
2756 | + ), |
2757 | + std::make_tuple( |
2758 | + "usb-keyboard", |
2759 | + "/dev/input/event14", |
2760 | + mi::DeviceCapability::keyboard |
2761 | + ), |
2762 | + std::make_tuple( |
2763 | + "usb-mouse", |
2764 | + "/dev/input/event13", |
2765 | + mi::DeviceCapability::pointer |
2766 | + ), |
2767 | + std::make_tuple( |
2768 | + "bluetooth-magic-trackpad", |
2769 | + "/dev/input/event13", |
2770 | + mi::DeviceCapability::touchpad |
2771 | + ), |
2772 | + std::make_tuple( |
2773 | + "mt-screen-detection", // device also reports available keys.. |
2774 | + "/dev/input/event4", |
2775 | + mi::DeviceCapabilities{mi::DeviceCapability::touchscreen}| |
2776 | + mi::DeviceCapability::keyboard |
2777 | + ), |
2778 | + std::make_tuple( |
2779 | + "joystick-detection", |
2780 | + "/dev/input/event13", |
2781 | + mi::DeviceCapabilities{mi::DeviceCapability::joystick}| |
2782 | + mi::DeviceCapability::gamepad| |
2783 | + mi::DeviceCapability::keyboard |
2784 | + ) |
2785 | + )); |
2786 | + |
2787 | |
2788 | === added file 'tests/unit-tests/input/evdev/test_evdev_input_device_factory.cpp' |
2789 | --- tests/unit-tests/input/evdev/test_evdev_input_device_factory.cpp 1970-01-01 00:00:00 +0000 |
2790 | +++ tests/unit-tests/input/evdev/test_evdev_input_device_factory.cpp 2015-01-21 10:33:12 +0000 |
2791 | @@ -0,0 +1,106 @@ |
2792 | +/* |
2793 | + * Copyright © 2014 Canonical Ltd. |
2794 | + * |
2795 | + * This program is free software: you can redistribute it and/or modify |
2796 | + * it under the terms of the GNU General Public License version 3 as |
2797 | + * published by the Free Software Foundation. |
2798 | + * |
2799 | + * This program is distributed in the hope that it will be useful, |
2800 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2801 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2802 | + * GNU General Public License for more details. |
2803 | + * |
2804 | + * You should have received a copy of the GNU General Public License |
2805 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2806 | + * |
2807 | + * Authored by: Christopher Halse Rogers <christopher.halse.rogers@canonical.com> |
2808 | + * Andreas Pokorny <andreas.pokorny@canonical.com> |
2809 | + */ |
2810 | + |
2811 | +#include "src/platforms/evdev/evdev_input_device_factory.h" |
2812 | +#include "src/platforms/evdev/input_device_provider.h" |
2813 | + |
2814 | +#include "mir/input/input_device.h" |
2815 | + |
2816 | +#include <mir_test/gmock_fixes.h> |
2817 | +#include <gtest/gtest.h> |
2818 | + |
2819 | +#include <stdexcept> |
2820 | + |
2821 | +namespace mi = mir::input; |
2822 | +namespace mie = mi::evdev; |
2823 | + |
2824 | +namespace |
2825 | +{ |
2826 | + |
2827 | +class MockInputDeviceProvider : public mie::InputDeviceProvider |
2828 | +{ |
2829 | +public: |
2830 | + MOCK_CONST_METHOD1(probe_device, mie::Priority(const char* node)); |
2831 | + MOCK_CONST_METHOD1(create_device, std::unique_ptr<mi::InputDevice>(const char* node)); |
2832 | +}; |
2833 | + |
2834 | +} |
2835 | + |
2836 | +TEST(EvdevInputDeviceFactory, probes_all_providers) |
2837 | +{ |
2838 | + using namespace testing; |
2839 | + auto a = std::make_shared<MockInputDeviceProvider>(); |
2840 | + auto b = std::make_shared<MockInputDeviceProvider>(); |
2841 | + |
2842 | + EXPECT_CALL(*a, probe_device(_)) |
2843 | + .WillOnce(Return(mie::Priority::unsupported)); |
2844 | + EXPECT_CALL(*b, probe_device(_)) |
2845 | + .WillOnce(Return(mie::Priority::unsupported)); |
2846 | + |
2847 | + mie::EvdevInputDeviceFactory factory({a, b}); |
2848 | + |
2849 | + EXPECT_THROW( |
2850 | + { |
2851 | + factory.create_device("stub_dev"); |
2852 | + }, std::runtime_error); |
2853 | +} |
2854 | + |
2855 | +TEST(EvdevInputDeviceFactory, creates_device_on_supported_provider) |
2856 | +{ |
2857 | + using namespace testing; |
2858 | + auto a = std::make_shared<MockInputDeviceProvider>(); |
2859 | + auto b = std::make_shared<MockInputDeviceProvider>(); |
2860 | + |
2861 | + EXPECT_CALL(*a, probe_device(_)) |
2862 | + .WillOnce(Return(mie::Priority::unsupported)); |
2863 | + EXPECT_CALL(*b, probe_device(_)) |
2864 | + .WillOnce(Return(mie::Priority::supported)); |
2865 | + EXPECT_CALL(*b, create_device(_)); |
2866 | + EXPECT_CALL(*a, create_device(_)) |
2867 | + .Times(0); |
2868 | + |
2869 | + mie::EvdevInputDeviceFactory factory({a, b}); |
2870 | + |
2871 | + factory.create_device("stub_dev"); |
2872 | +} |
2873 | + |
2874 | +TEST(EvdevInputDeviceFactory, preferes_creating_on_better_provider) |
2875 | +{ |
2876 | + using namespace testing; |
2877 | + auto a = std::make_shared<MockInputDeviceProvider>(); |
2878 | + auto b = std::make_shared<MockInputDeviceProvider>(); |
2879 | + |
2880 | + EXPECT_CALL(*a, probe_device(_)) |
2881 | + .Times(2) |
2882 | + .WillRepeatedly(Return(mie::Priority::best)); |
2883 | + EXPECT_CALL(*b, probe_device(_)) |
2884 | + .Times(2) |
2885 | + .WillRepeatedly(Return(mie::Priority::supported)); |
2886 | + EXPECT_CALL(*a, create_device(_)) |
2887 | + .Times(2); |
2888 | + EXPECT_CALL(*b, create_device(_)) |
2889 | + .Times(0); |
2890 | + |
2891 | + mie::EvdevInputDeviceFactory factory_one({a, b}); |
2892 | + mie::EvdevInputDeviceFactory factory_two({b, a}); |
2893 | + |
2894 | + factory_one.create_device("stub_dev1"); |
2895 | + factory_two.create_device("stub_dev2"); |
2896 | +} |
2897 | + |
2898 | |
2899 | === added file 'tests/unit-tests/input/evdev/test_libinput_device_provider.cpp' |
2900 | --- tests/unit-tests/input/evdev/test_libinput_device_provider.cpp 1970-01-01 00:00:00 +0000 |
2901 | +++ tests/unit-tests/input/evdev/test_libinput_device_provider.cpp 2015-01-21 10:33:12 +0000 |
2902 | @@ -0,0 +1,82 @@ |
2903 | +/* |
2904 | + * Copyright © 2014 Canonical Ltd. |
2905 | + * |
2906 | + * This program is free software: you can redistribute it and/or modify it |
2907 | + * under the terms of the GNU General Public License version 3, |
2908 | + * as published by the Free Software Foundation. |
2909 | + * |
2910 | + * This program is distributed in the hope that it will be useful, |
2911 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2912 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2913 | + * GNU General Public License for more details. |
2914 | + * |
2915 | + * You should have received a copy of the GNU General Public License |
2916 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2917 | + * |
2918 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
2919 | + */ |
2920 | + |
2921 | +#include "src/platforms/evdev/libinput_device_provider.h" |
2922 | +#include "mir_test_framework/udev_environment.h" |
2923 | + |
2924 | +#include <gmock/gmock.h> |
2925 | +#include <gtest/gtest.h> |
2926 | + |
2927 | +namespace mi = mir::input; |
2928 | +namespace mie = mi::evdev; |
2929 | +namespace mtf = mir_test_framework; |
2930 | + |
2931 | +struct LibInput : public ::testing::TestWithParam<std::tuple<char const*, char const*, mie::Priority>> |
2932 | +{ |
2933 | + mtf::UdevEnvironment env; |
2934 | +}; |
2935 | + |
2936 | +TEST_P(LibInput, device_probing_yields_expected_priority) |
2937 | +{ |
2938 | + using namespace testing; |
2939 | + auto const& param = GetParam(); |
2940 | + env.add_standard_device(std::get<0>(param)); |
2941 | + mie::LibInputDeviceProvider provider; |
2942 | + |
2943 | + EXPECT_THAT(provider.probe_device(std::get<1>(param)), Eq(std::get<2>(param))); |
2944 | +} |
2945 | + |
2946 | +INSTANTIATE_TEST_CASE_P(InputDeviceProviderTest, |
2947 | + LibInput, |
2948 | + ::testing::Values( |
2949 | + std::make_tuple( |
2950 | + "synaptics-touchpad", |
2951 | + "/dev/input/event12", |
2952 | + mie::Priority::best |
2953 | + ), |
2954 | + std::make_tuple( |
2955 | + "bluetooth-magic-trackpad", |
2956 | + "/dev/input/event13", |
2957 | + mie::Priority::best |
2958 | + ), |
2959 | + std::make_tuple( |
2960 | + "mt-screen-detection", |
2961 | + "/dev/input/event4", |
2962 | + mie::Priority::unsupported |
2963 | + ), |
2964 | + std::make_tuple( |
2965 | + "joystick-detection", |
2966 | + "/dev/input/event13", |
2967 | + mie::Priority::unsupported |
2968 | + ), |
2969 | + std::make_tuple( |
2970 | + "usb-mouse", |
2971 | + "/dev/input/event13", |
2972 | + mie::Priority::supported |
2973 | + ), |
2974 | + std::make_tuple( |
2975 | + "usb-keyboard", |
2976 | + "/dev/input/event14", |
2977 | + mie::Priority::unsupported |
2978 | + ), |
2979 | + std::make_tuple( |
2980 | + "laptop-keyboard", |
2981 | + "/dev/input/event4", |
2982 | + mie::Priority::unsupported |
2983 | + ) |
2984 | + )); |
2985 | |
2986 | === added file 'tests/unit-tests/input/evdev/test_platform.cpp' |
2987 | --- tests/unit-tests/input/evdev/test_platform.cpp 1970-01-01 00:00:00 +0000 |
2988 | +++ tests/unit-tests/input/evdev/test_platform.cpp 2015-01-21 10:33:12 +0000 |
2989 | @@ -0,0 +1,207 @@ |
2990 | +/* |
2991 | + * Copyright © 2014 Canonical Ltd. |
2992 | + * |
2993 | + * This program is free software: you can redistribute it and/or modify |
2994 | + * it under the terms of the GNU General Public License version 3 as |
2995 | + * published by the Free Software Foundation. |
2996 | + * |
2997 | + * This program is distributed in the hope that it will be useful, |
2998 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2999 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3000 | + * GNU General Public License for more details. |
3001 | + * |
3002 | + * You should have received a copy of the GNU General Public License |
3003 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3004 | + * |
3005 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
3006 | + */ |
3007 | + |
3008 | +#include "src/platforms/evdev/platform.h" |
3009 | +#include "src/server/report/null_report_factory.h" |
3010 | +#include "src/platforms/evdev/input_device_factory.h" |
3011 | + |
3012 | +#include "mir/input/input_device.h" |
3013 | +#include "mir/udev/wrapper.h" |
3014 | +#include "mir/shared_library.h" |
3015 | + |
3016 | +#include "mir_test_doubles/mock_main_loop.h" |
3017 | +#include "mir_test_doubles/mock_input_device_registry.h" |
3018 | +#include "mir_test_doubles/mock_input_event_handler_register.h" |
3019 | +#include "mir_test_framework/udev_environment.h" |
3020 | +#include "mir_test_framework/executable_path.h" |
3021 | + |
3022 | +#include <thread> |
3023 | +#include <chrono> |
3024 | +#include <unistd.h> |
3025 | +#include <fcntl.h> |
3026 | + |
3027 | +#include <gmock/gmock.h> |
3028 | + |
3029 | +namespace mi = mir::input; |
3030 | +namespace mie = mi::evdev; |
3031 | +namespace mr = mir::report; |
3032 | +namespace mtd = mir::test::doubles; |
3033 | +namespace mtf = mir_test_framework; |
3034 | + |
3035 | +namespace |
3036 | +{ |
3037 | + |
3038 | +struct EvdevPlatformBase |
3039 | +{ |
3040 | +public: |
3041 | + EvdevPlatformBase() |
3042 | + : platform_lib(mtf::server_platform("input-evdev.so")), |
3043 | + platform(platform_lib.load_function<mi::CreatePlatform>("create_input_platform", MIR_SERVER_INPUT_PLATFORM_VERSION) |
3044 | + ( |
3045 | + std::shared_ptr<mir::options::Option>(), |
3046 | + std::shared_ptr<mir::EmergencyCleanupRegistry>(), |
3047 | + mr::null_input_report() |
3048 | + )) |
3049 | + { |
3050 | + } |
3051 | + mir::SharedLibrary platform_lib; |
3052 | + mtf::UdevEnvironment env; // has to be created before platform |
3053 | + std::unique_ptr<mi::Platform> platform; |
3054 | + ::testing::NiceMock<mtd::MockInputEventHandlerRegister> mock_event_handler_register; |
3055 | + std::shared_ptr<::testing::NiceMock<mtd::MockInputDeviceRegistry>> mock_registry = |
3056 | + std::make_shared<::testing::NiceMock<mtd::MockInputDeviceRegistry>>(); |
3057 | +}; |
3058 | + |
3059 | +struct EvdevPlatform : ::testing::Test, EvdevPlatformBase |
3060 | +{ |
3061 | +}; |
3062 | + |
3063 | +struct EvdevPlatformDeviceEvents : ::testing::TestWithParam<char const*>, EvdevPlatformBase |
3064 | +{ |
3065 | + EvdevPlatformDeviceEvents() |
3066 | + : ::testing::TestWithParam<char const*>(), EvdevPlatformBase() |
3067 | + { |
3068 | + using namespace ::testing; |
3069 | + ON_CALL(mock_event_handler_register, register_fd_handler_(_,_,_)) |
3070 | + .WillByDefault(Invoke( |
3071 | + [this](std::initializer_list<int> fd_list, void const*, std::function<void(int)> const& handler) |
3072 | + { |
3073 | + int fd = *fd_list.begin(); |
3074 | + fd_callbacks.push_back([=]() { handler(fd); }); |
3075 | + })); |
3076 | + ON_CALL(mock_event_handler_register, register_handler_(_)) |
3077 | + .WillByDefault(Invoke( |
3078 | + [this](std::function<void()> const& action) |
3079 | + { |
3080 | + actions.push_back(action); |
3081 | + })); |
3082 | + } |
3083 | + |
3084 | + void remove_device() |
3085 | + { |
3086 | + mir::udev::Enumerator devices{std::make_shared<mir::udev::Context>()}; |
3087 | + devices.scan_devices(); |
3088 | + |
3089 | + for (auto& device : devices) |
3090 | + { |
3091 | + /* |
3092 | + * Remove just the device providing dev/input/event* |
3093 | + * If we remove more, it's possible that we'll remove the parent of the |
3094 | + * /dev/input device, and umockdev will not generate a remove event |
3095 | + * in that case. |
3096 | + */ |
3097 | + if (device.devnode() && (std::string(device.devnode()).find("input/event") != std::string::npos)) |
3098 | + { |
3099 | + env.remove_device((std::string("/sys") + device.devpath()).c_str()); |
3100 | + } |
3101 | + } |
3102 | + } |
3103 | + |
3104 | + void process_pending_actions() |
3105 | + { |
3106 | + decltype(actions) actions_to_execute; |
3107 | + std::swap(actions, actions_to_execute); |
3108 | + |
3109 | + for(auto const& action : actions_to_execute) |
3110 | + action(); |
3111 | + } |
3112 | + |
3113 | + void process_pending_fd_callbacks() |
3114 | + { |
3115 | + decltype(actions) actions_to_execute; |
3116 | + |
3117 | + actions_to_execute = fd_callbacks; |
3118 | + |
3119 | + for(auto const& action : actions_to_execute) |
3120 | + action(); |
3121 | + } |
3122 | + |
3123 | + void process_pending() |
3124 | + { |
3125 | + process_pending_actions(); |
3126 | + process_pending_fd_callbacks(); |
3127 | + } |
3128 | + |
3129 | + std::vector<std::function<void()>> fd_callbacks; |
3130 | + std::vector<std::function<void()>> actions; |
3131 | +}; |
3132 | + |
3133 | +} |
3134 | + |
3135 | +TEST_F(EvdevPlatform, registers_to_event_handler_register_on_start) |
3136 | +{ |
3137 | + using namespace ::testing; |
3138 | + EXPECT_CALL(mock_event_handler_register, register_fd_handler_(_,_,_)); |
3139 | + platform->start(mock_event_handler_register, mock_registry); |
3140 | +} |
3141 | + |
3142 | +TEST_F(EvdevPlatform, unregisters_to_event_handler_register_on_stop) |
3143 | +{ |
3144 | + using namespace ::testing; |
3145 | + EXPECT_CALL(mock_event_handler_register, unregister_fd_handler(_)); |
3146 | + platform->stop(mock_event_handler_register); |
3147 | +} |
3148 | + |
3149 | +TEST_P(EvdevPlatformDeviceEvents, finds_device_on_start) |
3150 | +{ |
3151 | + using namespace ::testing; |
3152 | + env.add_standard_device(GetParam()); |
3153 | + |
3154 | + EXPECT_CALL(*mock_registry, add_device(_)).Times(1); |
3155 | + platform->start(mock_event_handler_register, mock_registry); |
3156 | + |
3157 | + process_pending(); |
3158 | +} |
3159 | + |
3160 | +TEST_P(EvdevPlatformDeviceEvents, adds_device_on_hotplug) |
3161 | +{ |
3162 | + using namespace ::testing; |
3163 | + EXPECT_CALL(*mock_registry, add_device(_)).Times(1); |
3164 | + platform->start(mock_event_handler_register, mock_registry); |
3165 | + process_pending(); |
3166 | + |
3167 | + env.add_standard_device(GetParam()); |
3168 | + |
3169 | + process_pending(); |
3170 | +} |
3171 | + |
3172 | +TEST_P(EvdevPlatformDeviceEvents, removes_device_on_hotplug) |
3173 | +{ |
3174 | + using namespace ::testing; |
3175 | + EXPECT_CALL(*mock_registry, add_device(_)).Times(1); |
3176 | + EXPECT_CALL(*mock_registry, remove_device(_)).Times(1); |
3177 | + platform->start(mock_event_handler_register, mock_registry); |
3178 | + env.add_standard_device(GetParam()); |
3179 | + |
3180 | + process_pending(); |
3181 | + |
3182 | + remove_device(); |
3183 | + |
3184 | + process_pending(); |
3185 | +} |
3186 | + |
3187 | +INSTANTIATE_TEST_CASE_P(EvdevPlatformHotplugging, |
3188 | + EvdevPlatformDeviceEvents, |
3189 | + ::testing::Values("synaptics-touchpad", |
3190 | + "usb-keyboard", |
3191 | + "usb-mouse", |
3192 | + "laptop-keyboard", |
3193 | + "bluetooth-magic-trackpad", |
3194 | + "joystick-detection", |
3195 | + "mt-screen-detection" |
3196 | + )); |
3197 | |
3198 | === added file 'tests/unit-tests/test_find_best.cpp' |
3199 | --- tests/unit-tests/test_find_best.cpp 1970-01-01 00:00:00 +0000 |
3200 | +++ tests/unit-tests/test_find_best.cpp 2015-01-21 10:33:12 +0000 |
3201 | @@ -0,0 +1,72 @@ |
3202 | +/* |
3203 | + * Copyright © 2014 Canonical Ltd. |
3204 | + * |
3205 | + * This program is free software: you can redistribute it and/or modify it |
3206 | + * under the terms of the GNU General Public License version 3, |
3207 | + * as published by the Free Software Foundation. |
3208 | + * |
3209 | + * This program is distributed in the hope that it will be useful, |
3210 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3211 | + * MERCHANTABILITY or FITNESS FOR AStructure PARTICULAR PURPOSE. See the |
3212 | + * GNU General Public License for more details. |
3213 | + * |
3214 | + * You should have received a copy of the GNU General Public License |
3215 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3216 | + * |
3217 | + * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com> |
3218 | + */ |
3219 | + |
3220 | +#include "mir/find_best.h" |
3221 | +#include <gtest/gtest.h> |
3222 | + |
3223 | +#include <initializer_list> |
3224 | + |
3225 | +namespace |
3226 | +{ |
3227 | +struct AStructure |
3228 | +{ |
3229 | + int value; |
3230 | +}; |
3231 | + |
3232 | +int trivial_transform(AStructure const& a) |
3233 | +{ |
3234 | + return a.value; |
3235 | +} |
3236 | +} |
3237 | + |
3238 | +TEST(FindBest, returns_end_iterator_on_empty) |
3239 | +{ |
3240 | + using namespace testing; |
3241 | + std::initializer_list<::AStructure> empty{}; |
3242 | + EXPECT_THAT(mir::find_best(empty, trivial_transform, 0), Eq(end(empty))); |
3243 | +} |
3244 | + |
3245 | +TEST(FindBest, returns_best_element) |
3246 | +{ |
3247 | + using namespace testing; |
3248 | + std::vector<::AStructure> values{{123}, {23}, {500}, {42}}; |
3249 | + EXPECT_THAT(mir::find_best(values, trivial_transform, 0)->value, Eq(500)); |
3250 | +} |
3251 | + |
3252 | +TEST(FindBest, returns_end_when_initial_is_best) |
3253 | +{ |
3254 | + using namespace testing; |
3255 | + std::vector<::AStructure> values{{123}, {23}, {500}, {42}}; |
3256 | + EXPECT_THAT(mir::find_best(values, trivial_transform, 501), Eq(end(values))); |
3257 | +} |
3258 | + |
3259 | +TEST(FindBest, calls_transformation_only_n_times) |
3260 | +{ |
3261 | + using namespace testing; |
3262 | + std::vector<::AStructure> values{{123}, {23}, {500}, {42}}; |
3263 | + int transform_count = 0; |
3264 | + mir::find_best(values, [&transform_count](::AStructure const& item) { ++transform_count; return item.value; }, 0); |
3265 | + EXPECT_THAT(transform_count, Eq(values.size())); |
3266 | +} |
3267 | + |
3268 | +TEST(FindBest, different_predicates_can_be_used) |
3269 | +{ |
3270 | + using namespace testing; |
3271 | + std::vector<::AStructure> values{{123}, {23}, {500}, {42}}; |
3272 | + EXPECT_THAT(mir::find_best(values, trivial_transform, 500, std::less<int>())->value, Eq(23)); |
3273 | +} |
64 +++ include/ platform/ mir/input/ event_sink. h event_sink. h
this is the same interface as
src/client/
364 +extern "C" typedef std::unique_ ptr<Platform> (*CreatePlatofr m)(
153 + // add devie info here..
typos
264 + std::initialize r_list< int> fds,
Fds should be mir::Fd to better manage the lifetime of the FD.
145 +class InputDevice
class name doesnt make sense to me for what the group of functions is doing, but this might be a side effect of the "Multiplexer" naming comment.
349 + * The \a input_device_ registry should be informed about input device changes using the MainLoop \a loop. devices( Multiplexer& loop, std::shared_ ptr<InputDevice Registry> const& input_device_ registry) = 0;
350 + */
351 + virtual void start_monitor_
Does the comment need updating? MainLoop doesn't seem related