diff options
author | rlp@chromium.org <rlp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 18:19:08 +0000 |
---|---|---|
committer | rlp@chromium.org <rlp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 18:19:08 +0000 |
commit | 08294a9c6545c8f75e9d7d43eaf05c9f2b3b5ab1 (patch) | |
tree | 6b720c121b6603d447dd53d96c39d412c6910630 /ui/display/chromeos | |
parent | aad29ce82cf8273c5404262998c097c4036a8f4c (diff) | |
download | chromium_src-08294a9c6545c8f75e9d7d43eaf05c9f2b3b5ab1.zip chromium_src-08294a9c6545c8f75e9d7d43eaf05c9f2b3b5ab1.tar.gz chromium_src-08294a9c6545c8f75e9d7d43eaf05c9f2b3b5ab1.tar.bz2 |
Revert 269371 "Move touch CTM from X into Chrome"
Failed compile on Linux Builder
http://build.chromium.org/p/chromium.linux/builders/Linux%20Builder%20%28dbg%29%2832%29/builds/23859/steps/compile/logs/stdio
FAILED: /b/build/goma/gomacc c++ -Wl,-z,now -Wl,-z,relro -Wl,--fatal-warnings -pthread -Wl,-z,noexecstack -fPIC -m32 -Wl,--no-as-needed -Wl,-rpath=\$ORIGIN/lib/ -Wl,-rpath-link=lib/ -o cast_unittests -Wl,--start-group obj/media/base/cast_unittests.run_all_unittests.o obj/media/cast/audio_receiver/cast_unittests.audio_decoder_unittest.o obj/media/cast/audio_receiver/cast_unittests.audio_receiver_unittest.o obj/media/cast/audio_sender/cast_unittests.audio_encoder_unittest.o obj/media/cast/audio_sender/cast_unittests.audio_sender_unittest.o obj/media/cast/congestion_control/cast_unittests.congestion_control_unittest.o obj/media/cast/framer/cast_unittests.cast_message_builder_unittest.o obj/media/cast/framer/cast_unittests.frame_buffer_unittest.o obj/media/cast/framer/cast_unittests.framer_unittest.o obj/media/cast/logging/cast_unittests.encoding_event_subscriber_unittest.o obj/media/cast/logging/cast_unittests.serialize_deserialize_test.o obj/media/cast/logging/cast_unittests.logging_impl_unittest.o obj/media/cast/logging/cast_unittests.logging_raw_unittest.o obj/media/cast/logging/cast_unittests.receiver_time_offset_estimator_impl_unittest.o obj/media/cast/logging/cast_unittests.simple_event_subscriber_unittest.o obj/media/cast/logging/cast_unittests.stats_event_subscriber_unittest.o obj/media/cast/rtcp/cast_unittests.mock_rtcp_receiver_feedback.o obj/media/cast/rtcp/cast_unittests.mock_rtcp_sender_feedback.o obj/media/cast/rtcp/cast_unittests.rtcp_receiver_unittest.o obj/media/cast/rtcp/cast_unittests.rtcp_sender_unittest.o obj/media/cast/rtcp/cast_unittests.rtcp_unittest.o obj/media/cast/rtcp/cast_unittests.receiver_rtcp_event_subscriber_unittest.o obj/media/cast/rtcp/cast_unittests.sender_rtcp_event_subscriber_unittest.o obj/media/cast/rtcp/cast_unittests.test_rtcp_packet_builder.o obj/media/cast/rtp_receiver/cast_unittests.mock_rtp_payload_feedback.o obj/media/cast/rtp_receiver/cast_unittests.receiver_stats_unittest.o obj/media/cast/rtp_receiver/rtp_parser/test/cast_unittests.rtp_packet_builder.o obj/media/cast/rtp_receiver/rtp_parser/cast_unittests.rtp_parser_unittest.o obj/media/cast/test/cast_unittests.end2end_unittest.o obj/media/cast/test/cast_unittests.fake_receiver_time_offset_estimator.o obj/media/cast/test/cast_unittests.fake_single_thread_task_runner.o obj/media/cast/test/cast_unittests.fake_video_encode_accelerator.o obj/media/cast/test/utility/cast_unittests.audio_utility_unittest.o obj/media/cast/test/utility/cast_unittests.barcode_unittest.o obj/media/cast/transport/cast_unittests.cast_transport_sender_impl_unittest.o obj/media/cast/transport/pacing/cast_unittests.mock_paced_packet_sender.o obj/media/cast/transport/pacing/cast_unittests.paced_sender_unittest.o obj/media/cast/transport/rtp_sender/packet_storage/cast_unittests.packet_storage_unittest.o obj/media/cast/transport/rtp_sender/rtp_packetizer/cast_unittests.rtp_packetizer_unittest.o obj/media/cast/transport/rtp_sender/rtp_packetizer/test/cast_unittests.rtp_header_parser.o obj/media/cast/transport/transport/cast_unittests.udp_transport_unittest.o obj/media/cast/video_receiver/cast_unittests.video_decoder_unittest.o obj/media/cast/video_receiver/cast_unittests.video_receiver_unittest.o obj/media/cast/video_sender/cast_unittests.external_video_encoder_unittest.o obj/media/cast/video_sender/cast_unittests.video_encoder_impl_unittest.o obj/media/cast/video_sender/cast_unittests.video_sender_unittest.o obj/media/cast/libcast_base.a obj/media/cast/libcast_receiver.a obj/media/cast/libcast_rtcp.a obj/media/cast/libcast_sender.a obj/media/cast/libcast_test_utility.a obj/media/cast/libcast_transport.a obj/base/libtest_support_base.a obj/testing/libgmock.a obj/testing/libgtest.a obj/media/cast/libcast_logging_proto.a obj/third_party/opus/libopus.a obj/third_party/libvpx/libvpx.a obj/third_party/libvpx/libvpx_asm_offsets_vp8.a obj/third_party/libvpx/libvpx_intrinsics_mmx.a obj/third_party/libvpx/libvpx_intrinsics_sse2.a obj/third_party/libvpx/libvpx_intrinsics_ssse3.a libyuv.a obj/third_party/libjpeg_turbo/libjpeg_turbo.a obj/base/libbase_static.a obj/third_party/libxml/libxml2.a obj/third_party/zlib/libchrome_zlib.a obj/base/third_party/dynamic_annotations/libdynamic_annotations.a lib/libicuuc.so lib/libnet.so lib/libbase.so lib/libgfx_geometry.so lib/libprotobuf_lite.so lib/libshared_memory_support.so lib/libmedia.so lib/libbase_i18n.so lib/libcrcrypto.so -Wl,--end-group -lrt -ldl -lasound
lib//libevents_base.so: undefined reference to `ui::PlatformEventSource::RemovePlatformEventObserver(ui::PlatformEventObserver*)'
lib//libevents_base.so: undefined reference to `ui::PlatformEventSource::GetInstance()'
lib//libevents_base.so: undefined reference to `ui::PlatformEventSource::AddPlatformEventObserver(ui::PlatformEventObserver*)'
collect2: ld returned 1 exit status
ninja: build stopped: subcommand failed.
> Move touch CTM from X into Chrome
>
> Currently we compute the touch CTM in OutputConfigurator
> and push that into X. This CL makes computing the touch CTM
> in DisplayController, and pushing it
> into WindowTreeHostX11. This moves the functionality of
> touch CTM from X into Chrome.
>
> Basically, when there is output configuration change, we
> compute the TouchCTM for each touch device, and push the
> TouchCTM into the WindowTreeHostX11 that is associated
> with the touchscreen. Then when X events reaching root
> window, we use the CTM to map the events coordinate in
> framebuffer space into the root window's coordinate space.
>
>
> BUG=351019, chrome-os-partner:25788
> TEST=tested on Pixel/Clapper with external touch/non-touch displays
> on both extended/mirror mode. Touch events are correctly mapped to
> chrome window or discarded if it is from blank region from letterboxing/pillarboxing mirror mode.
>
> Review URL: https://codereview.chromium.org/191223007
TBR=miletus@chromium.org
Review URL: https://codereview.chromium.org/276013002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269376 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/display/chromeos')
-rw-r--r-- | ui/display/chromeos/display_configurator.cc | 99 | ||||
-rw-r--r-- | ui/display/chromeos/display_configurator.h | 39 | ||||
-rw-r--r-- | ui/display/chromeos/display_configurator_unittest.cc | 61 | ||||
-rw-r--r-- | ui/display/chromeos/ozone/touchscreen_delegate_ozone.cc | 6 | ||||
-rw-r--r-- | ui/display/chromeos/ozone/touchscreen_delegate_ozone.h | 3 | ||||
-rw-r--r-- | ui/display/chromeos/x11/touchscreen_delegate_x11.cc | 50 | ||||
-rw-r--r-- | ui/display/chromeos/x11/touchscreen_delegate_x11.h | 3 |
7 files changed, 255 insertions, 6 deletions
diff --git a/ui/display/chromeos/display_configurator.cc b/ui/display/chromeos/display_configurator.cc index a2281a8..1283b58 100644 --- a/ui/display/chromeos/display_configurator.cc +++ b/ui/display/chromeos/display_configurator.cc @@ -89,6 +89,12 @@ int GetDisplayPower( } // namespace +DisplayConfigurator::CoordinateTransformation::CoordinateTransformation() + : x_scale(1.0), + x_offset(0.0), + y_scale(1.0), + y_offset(0.0) {} + DisplayConfigurator::DisplayState::DisplayState() : display(NULL), touch_device_id(0), @@ -790,8 +796,11 @@ bool DisplayConfigurator::EnterState(MultipleDisplayState display_state, DisplayState* state = &cached_displays_[i]; new_mode[i] = display_power[i] ? state->mirror_mode : NULL; if (state->touch_device_id) { + // CTM needs to be calculated if aspect preserving scaling is used. + // Otherwise, assume it is full screen, and use identity CTM. if (state->mirror_mode != state->display->native_mode() && state->display->is_aspect_preserving_scaling()) { + state->transform = GetMirrorModeCTM(*state); mirrored_display_area_ratio_map_[state->touch_device_id] = GetMirroredDisplayAreaRatio(*state); } @@ -824,6 +833,12 @@ bool DisplayConfigurator::EnterState(MultipleDisplayState display_state, size.set_height(size.height() + (size.height() ? kVerticalGap : 0) + mode_info->size().height()); } + + for (size_t i = 0; i < cached_displays_.size(); ++i) { + DisplayState* state = &cached_displays_[i]; + if (state->touch_device_id) + state->transform = GetExtendedModeCTM(*state, new_origins[i], size); + } break; } } @@ -871,8 +886,13 @@ bool DisplayConfigurator::EnterState(MultipleDisplayState display_state, break; } - if (!configure_succeeded) + if (configure_succeeded) { + if (state.touch_device_id) + touchscreen_delegate_->ConfigureCTM(state.touch_device_id, + state.transform); + } else { all_succeeded = false; + } // If we are trying to set mirror mode and one of the modesets fails, // then the two monitors will be mis-matched. In this case, return @@ -887,7 +907,6 @@ bool DisplayConfigurator::EnterState(MultipleDisplayState display_state, if (all_succeeded) { display_state_ = display_state; power_state_ = power_state; - framebuffer_size_ = size; } return all_succeeded; } @@ -926,6 +945,82 @@ MultipleDisplayState DisplayConfigurator::ChooseDisplayState( return MULTIPLE_DISPLAY_STATE_INVALID; } +DisplayConfigurator::CoordinateTransformation +DisplayConfigurator::GetMirrorModeCTM(const DisplayState& display_state) { + CoordinateTransformation ctm; // Default to identity + const DisplayMode* native_mode_info = display_state.display->native_mode(); + const DisplayMode* mirror_mode_info = display_state.mirror_mode; + + if (!native_mode_info || !mirror_mode_info || + native_mode_info->size().height() == 0 || + mirror_mode_info->size().height() == 0 || + native_mode_info->size().width() == 0 || + mirror_mode_info->size().width() == 0) + return ctm; + + float native_mode_ar = static_cast<float>(native_mode_info->size().width()) / + static_cast<float>(native_mode_info->size().height()); + float mirror_mode_ar = static_cast<float>(mirror_mode_info->size().width()) / + static_cast<float>(mirror_mode_info->size().height()); + + if (mirror_mode_ar > native_mode_ar) { // Letterboxing + ctm.x_scale = 1.0; + ctm.x_offset = 0.0; + ctm.y_scale = mirror_mode_ar / native_mode_ar; + ctm.y_offset = (native_mode_ar / mirror_mode_ar - 1.0) * 0.5; + return ctm; + } + if (native_mode_ar > mirror_mode_ar) { // Pillarboxing + ctm.y_scale = 1.0; + ctm.y_offset = 0.0; + ctm.x_scale = native_mode_ar / mirror_mode_ar; + ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5; + return ctm; + } + + return ctm; // Same aspect ratio - return identity +} + +DisplayConfigurator::CoordinateTransformation +DisplayConfigurator::GetExtendedModeCTM(const DisplayState& display_state, + const gfx::Point& new_origin, + const gfx::Size& framebuffer_size) { + CoordinateTransformation ctm; // Default to identity + const DisplayMode* mode_info = display_state.selected_mode; + DCHECK(mode_info); + if (!mode_info) + return ctm; + // An example of how to calculate the CTM. + // Suppose we have 2 monitors, the first one has size 1366 x 768. + // The second one has size 2560 x 1600 + // The total size of framebuffer is 2560 x 2428 + // where 2428 = 768 + 60 (hidden gap) + 1600 + // and the sceond monitor is translated to Point (0, 828) in the + // framebuffer. + // X will first map input event location to [0, 2560) x [0, 2428), + // then apply CTM on it. + // So to compute CTM, for monitor1, we have + // x_scale = (1366 - 1) / (2560 - 1) + // x_offset = 0 / (2560 - 1) + // y_scale = (768 - 1) / (2428 - 1) + // y_offset = 0 / (2428 -1) + // For Monitor 2, we have + // x_scale = (2560 - 1) / (2560 - 1) + // x_offset = 0 / (2560 - 1) + // y_scale = (1600 - 1) / (2428 - 1) + // y_offset = 828 / (2428 -1) + // See the unittest DisplayConfiguratorTest.CTMForMultiScreens. + ctm.x_scale = static_cast<float>(mode_info->size().width() - 1) / + (framebuffer_size.width() - 1); + ctm.x_offset = + static_cast<float>(new_origin.x()) / (framebuffer_size.width() - 1); + ctm.y_scale = static_cast<float>(mode_info->size().height() - 1) / + (framebuffer_size.height() - 1); + ctm.y_offset = + static_cast<float>(new_origin.y()) / (framebuffer_size.height() - 1); + return ctm; +} + float DisplayConfigurator::GetMirroredDisplayAreaRatio( const DisplayState& display_state) { float area_ratio = 1.0f; diff --git a/ui/display/chromeos/display_configurator.h b/ui/display/chromeos/display_configurator.h index d0c9235..028a902 100644 --- a/ui/display/chromeos/display_configurator.h +++ b/ui/display/chromeos/display_configurator.h @@ -19,7 +19,6 @@ #include "ui/display/display_export.h" #include "ui/display/types/chromeos/native_display_observer.h" #include "ui/display/types/display_constants.h" -#include "ui/gfx/geometry/size.h" namespace gfx { class Point; @@ -37,6 +36,16 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { typedef uint64_t ContentProtectionClientId; static const ContentProtectionClientId kInvalidClientId = 0; + struct CoordinateTransformation { + // Initialized to the identity transformation. + CoordinateTransformation(); + + float x_scale; + float x_offset; + float y_scale; + float y_offset; + }; + struct DisplayState { DisplayState(); @@ -45,6 +54,8 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { // XInput device ID or 0 if this display isn't a touchscreen. int touch_device_id; + CoordinateTransformation transform; + // User-selected mode for the display. const DisplayMode* selected_mode; @@ -106,6 +117,14 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { // If a touchscreen with same resolution as a display's native mode // is detected, its id will be stored in this display. virtual void AssociateTouchscreens(std::vector<DisplayState>* displays) = 0; + + // Configures XInput's Coordinate Transformation Matrix property. + // |touch_device_id| the ID of the touchscreen device to configure. + // |ctm| contains the desired transformation parameters. The offsets + // in it should be normalized so that 1 corresponds to the X or Y axis + // size for the corresponding offset. + virtual void ConfigureCTM(int touch_device_id, + const CoordinateTransformation& ctm) = 0; }; // Helper class used by tests. @@ -152,7 +171,6 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { MultipleDisplayState display_state() const { return display_state_; } chromeos::DisplayPowerState power_state() const { return power_state_; } - const gfx::Size framebuffer_size() const { return framebuffer_size_; } const std::vector<DisplayState>& cached_displays() const { return cached_displays_; } @@ -317,6 +335,21 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { MultipleDisplayState ChooseDisplayState( chromeos::DisplayPowerState power_state) const; + // Computes the relevant transformation for mirror mode. + // |display| is the display on which mirror mode is being applied. + // Returns the transformation or identity if computations fail. + CoordinateTransformation GetMirrorModeCTM(const DisplayState& display); + + // Computes the relevant transformation for extended mode. |display| is the + // display on which extended mode is being applied. |new_origin| is the + // position of the display on the framebuffer. |framebuffer_size| is the + // size of the combined framebuffer. + // Returns the transformation or identity if computations fail. + CoordinateTransformation GetExtendedModeCTM( + const DisplayState& display, + const gfx::Point& new_origin, + const gfx::Size& framebuffer_size); + // Returns the ratio between mirrored mode area and native mode area: // (mirror_mode_width * mirrow_mode_height) / (native_width * native_height) float GetMirroredDisplayAreaRatio(const DisplayState& display); @@ -350,8 +383,6 @@ class DISPLAY_EXPORT DisplayConfigurator : public NativeDisplayObserver { // The current display state. MultipleDisplayState display_state_; - gfx::Size framebuffer_size_; - // The current power state. chromeos::DisplayPowerState power_state_; diff --git a/ui/display/chromeos/display_configurator_unittest.cc b/ui/display/chromeos/display_configurator_unittest.cc index 1835d75..1790d66 100644 --- a/ui/display/chromeos/display_configurator_unittest.cc +++ b/ui/display/chromeos/display_configurator_unittest.cc @@ -82,6 +82,18 @@ std::string GetFramebufferAction(const gfx::Size& size, out2 ? DisplaySnapshotToString(*out2).c_str() : "NULL"); } +// Returns a string describing a TestNativeDisplayDelegate::ConfigureCTM() call. +std::string GetCTMAction( + int device_id, + const DisplayConfigurator::CoordinateTransformation& ctm) { + return base::StringPrintf("ctm(id=%d,transform=(%f,%f,%f,%f))", + device_id, + ctm.x_scale, + ctm.x_offset, + ctm.y_scale, + ctm.y_offset); +} + // Returns a string describing a TestNativeDisplayDelegate::SetHDCPState() call. std::string GetSetHDCPStateAction(const DisplaySnapshot& output, HDCPState state) { @@ -142,6 +154,11 @@ class TestTouchscreenDelegate configure_touchscreens_(false) {} virtual ~TestTouchscreenDelegate() {} + const DisplayConfigurator::CoordinateTransformation& GetCTM( + int touch_device_id) { + return ctms_[touch_device_id]; + } + void set_configure_touchscreens(bool state) { configure_touchscreens_ = state; } @@ -154,12 +171,21 @@ class TestTouchscreenDelegate (*outputs)[i].touch_device_id = i + 1; } } + virtual void ConfigureCTM( + int touch_device_id, + const DisplayConfigurator::CoordinateTransformation& ctm) OVERRIDE { + log_->AppendAction(GetCTMAction(touch_device_id, ctm)); + ctms_[touch_device_id] = ctm; + } private: ActionLogger* log_; // Not owned. bool configure_touchscreens_; + // Most-recently-configured transformation matrices, keyed by touch device ID. + std::map<int, DisplayConfigurator::CoordinateTransformation> ctms_; + DISALLOW_COPY_AND_ASSIGN(TestTouchscreenDelegate); }; @@ -1216,6 +1242,41 @@ TEST_F(DisplayConfiguratorTest, ContentProtectionTwoClients) { log_->GetActionsAndClear()); } +TEST_F(DisplayConfiguratorTest, CTMForMultiScreens) { + touchscreen_delegate_->set_configure_touchscreens(true); + UpdateOutputs(2, false); + configurator_.Init(false); + state_controller_.set_state(MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED); + configurator_.ForceInitialConfigure(0); + + const int kDualHeight = small_mode_.size().height() + + DisplayConfigurator::kVerticalGap + + big_mode_.size().height(); + const int kDualWidth = big_mode_.size().width(); + + DisplayConfigurator::CoordinateTransformation ctm1 = + touchscreen_delegate_->GetCTM(1); + DisplayConfigurator::CoordinateTransformation ctm2 = + touchscreen_delegate_->GetCTM(2); + + EXPECT_EQ(small_mode_.size().height() - 1, + round((kDualHeight - 1) * ctm1.y_scale)); + EXPECT_EQ(0, round((kDualHeight - 1) * ctm1.y_offset)); + + EXPECT_EQ(big_mode_.size().height() - 1, + round((kDualHeight - 1) * ctm2.y_scale)); + EXPECT_EQ(small_mode_.size().height() + DisplayConfigurator::kVerticalGap, + round((kDualHeight - 1) * ctm2.y_offset)); + + EXPECT_EQ(small_mode_.size().width() - 1, + round((kDualWidth - 1) * ctm1.x_scale)); + EXPECT_EQ(0, round((kDualWidth - 1) * ctm1.x_offset)); + + EXPECT_EQ(big_mode_.size().width() - 1, + round((kDualWidth - 1) * ctm2.x_scale)); + EXPECT_EQ(0, round((kDualWidth - 1) * ctm2.x_offset)); +} + TEST_F(DisplayConfiguratorTest, HandleConfigureCrtcFailure) { InitWithSingleOutput(); diff --git a/ui/display/chromeos/ozone/touchscreen_delegate_ozone.cc b/ui/display/chromeos/ozone/touchscreen_delegate_ozone.cc index c302e2d..1705f8b 100644 --- a/ui/display/chromeos/ozone/touchscreen_delegate_ozone.cc +++ b/ui/display/chromeos/ozone/touchscreen_delegate_ozone.cc @@ -15,4 +15,10 @@ void TouchscreenDelegateOzone::AssociateTouchscreens( NOTIMPLEMENTED(); } +void TouchscreenDelegateOzone::ConfigureCTM( + int touch_device_id, + const DisplayConfigurator::CoordinateTransformation& ctm) { + NOTIMPLEMENTED(); +} + } // namespace ui diff --git a/ui/display/chromeos/ozone/touchscreen_delegate_ozone.h b/ui/display/chromeos/ozone/touchscreen_delegate_ozone.h index 7f33a03..729b3cb 100644 --- a/ui/display/chromeos/ozone/touchscreen_delegate_ozone.h +++ b/ui/display/chromeos/ozone/touchscreen_delegate_ozone.h @@ -18,6 +18,9 @@ class TouchscreenDelegateOzone // DisplayConfigurator::TouchscreenDelegate overrides: virtual void AssociateTouchscreens( std::vector<DisplayConfigurator::DisplayState>* outputs) OVERRIDE; + virtual void ConfigureCTM( + int touch_device_id, + const DisplayConfigurator::CoordinateTransformation& ctm) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(TouchscreenDelegateOzone); diff --git a/ui/display/chromeos/x11/touchscreen_delegate_x11.cc b/ui/display/chromeos/x11/touchscreen_delegate_x11.cc index b76d62e..3b69d3a 100644 --- a/ui/display/chromeos/x11/touchscreen_delegate_x11.cc +++ b/ui/display/chromeos/x11/touchscreen_delegate_x11.cc @@ -129,4 +129,54 @@ void TouchscreenDelegateX11::AssociateTouchscreens( XIFreeDeviceInfo(info); } +void TouchscreenDelegateX11::ConfigureCTM( + int touch_device_id, + const DisplayConfigurator::CoordinateTransformation& ctm) { + VLOG(1) << "ConfigureCTM: id=" << touch_device_id << " scale=" << ctm.x_scale + << "x" << ctm.y_scale << " offset=(" << ctm.x_offset << ", " + << ctm.y_offset << ")"; + int ndevices = 0; + XIDeviceInfo* info = XIQueryDevice(display_, touch_device_id, &ndevices); + Atom prop = XInternAtom(display_, "Coordinate Transformation Matrix", False); + Atom float_atom = XInternAtom(display_, "FLOAT", False); + if (ndevices == 1 && prop != None && float_atom != None) { + Atom type; + int format; + unsigned long num_items; + unsigned long bytes_after; + unsigned char* data = NULL; + // Verify that the property exists with correct format, type, etc. + int status = XIGetProperty(display_, + info->deviceid, + prop, + 0, + 0, + False, + AnyPropertyType, + &type, + &format, + &num_items, + &bytes_after, + &data); + if (data) + XFree(data); + if (status == Success && type == float_atom && format == 32) { + float value[3][3] = { + { ctm.x_scale, 0.0, ctm.x_offset }, + { 0.0, ctm.y_scale, ctm.y_offset }, + { 0.0, 0.0, 1.0 } + }; + XIChangeProperty(display_, + info->deviceid, + prop, + type, + format, + PropModeReplace, + reinterpret_cast<unsigned char*>(value), + 9); + } + } + XIFreeDeviceInfo(info); +} + } // namespace ui diff --git a/ui/display/chromeos/x11/touchscreen_delegate_x11.h b/ui/display/chromeos/x11/touchscreen_delegate_x11.h index 7966ddf..434f55f 100644 --- a/ui/display/chromeos/x11/touchscreen_delegate_x11.h +++ b/ui/display/chromeos/x11/touchscreen_delegate_x11.h @@ -20,6 +20,9 @@ class TouchscreenDelegateX11 : public DisplayConfigurator::TouchscreenDelegate { // DisplayConfigurator::TouchscreenDelegate implementation: virtual void AssociateTouchscreens( DisplayConfigurator::DisplayStateList* outputs) OVERRIDE; + virtual void ConfigureCTM( + int touch_device_id, + const DisplayConfigurator::CoordinateTransformation& ctm) OVERRIDE; private: Display* display_; |