Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2446)

Unified Diff: ash/display/display_controller.cc

Issue 191223007: Move touch CTM from X into Chrome (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: add file ui/aura/touch_ctm.h(cc) Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ash/display/display_controller.cc
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc
index 138340037ebd9b0bf24d89358ad230a1862c446e..cd9a59aac0c22edb3089cf7dac45213f19480b2f 100644
--- a/ash/display/display_controller.cc
+++ b/ash/display/display_controller.cc
@@ -29,6 +29,7 @@
#include "ui/aura/client/focus_client.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/root_window_transformer.h"
+#include "ui/aura/touch_ctm.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_property.h"
@@ -133,6 +134,106 @@ void SetDisplayPropertiesOnHostWindow(aura::WindowEventDispatcher* dispatcher,
}
}
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+// This function computes the extended mode TouchCTM for |touch_display|.
+// An example of how to calculate the extended 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),
+// So to compute CTM, for monitor1, we have
+// x_scale = (1366 - 1) / (2560 - 1)
+// x_offset = 0
+// y_scale = (768 - 1) / (2428 - 1)
+// y_offset = 0
+// For Monitor 2, we have
+// x_scale = (2560 - 1) / (2560 - 1)
+// x_offset = 0
+// y_scale = (1600 - 1) / (2428 - 1)
+// y_offset = 828
+// See DisplayControllerTest.TouchCTMExtendedMode for the test.
+aura::TouchCTM GetExtendedModeTouchCTM(
+ const internal::DisplayInfo& touch_display,
+ const internal::DisplayInfo& second_display) {
+ aura::TouchCTM ctm;
+ float width = touch_display.bounds_in_native().width();
+ float height = touch_display.bounds_in_native().height();
+ float origin_x = touch_display.bounds_in_native().origin().x();
+ float origin_y = touch_display.bounds_in_native().origin().y();
+ float framebuffer_width = std::max<int>(
+ width, second_display.bounds_in_native().width());
+ float framebuffer_height =
+ height + chromeos::OutputConfigurator::kVerticalGap +
+ second_display.bounds_in_native().height();
+ ctm.x_scale = (width - 1) / (framebuffer_width - 1);
+ ctm.x_offset = origin_x;
+ ctm.y_scale = (height -1) / (framebuffer_height - 1);
+ ctm.y_offset = origin_y;
+ return ctm;
+}
+
+// This function computes the mirror mode TouchCTM for |touch_display|.
+// When internal monitor is applied a resolution that does not have
+// the same aspect ratio as its native resolution, there would be
+// blank regions in the letterboxing/pillarboxing mode.
+// The TouchCTM will make sure the touch events on the blank region
+// have negative coordinates and touch events within the chrome region
+// have the correct positive coordinates.
+aura::TouchCTM GetMirrorModeTouchCTM(
+ const internal::DisplayInfo& touch_display) {
+ aura::TouchCTM ctm;
+ // For external monitor, assuming no letterboxing or pillarboxing
+ // and just use the default TouchCTM.
+ if (touch_display.id() != gfx::Display::InternalDisplayId())
+ return ctm;
+
+ float mirror_width = touch_display.bounds_in_native().width();
+ float mirror_height = touch_display.bounds_in_native().height();
+ float native_width = 0;
+ float native_height = 0;
+
+ internal::DisplayMode native_mode;
+ std::vector<internal::DisplayMode> modes = touch_display.display_modes();
+ for (size_t i = 0; i < modes.size(); i++) {
+ if (modes[i].native) {
+ native_width = modes[i].size.width();
+ native_height = modes[i].size.height();
+ break;
+ }
+ }
+
+ if (native_height == 0.0 || mirror_height == 0.0 ||
+ native_width == 0.0 || mirror_width == 0.0)
+ return ctm;
+
+ float native_ar = static_cast<float>(native_width) /
+ static_cast<float>(native_height);
+ float mirror_ar = static_cast<float>(mirror_width) /
+ static_cast<float>(mirror_height);
+
+ if (mirror_ar > native_ar) { // Letterboxing
+ ctm.x_scale = 1.0;
+ ctm.x_offset = 0.0;
+ ctm.y_scale = mirror_ar / native_ar;
+ ctm.y_offset = (1.0 / mirror_ar - 1.0 / native_ar) * 0.5 * mirror_width;
+ return ctm;
+ }
+
+ if (native_ar > mirror_ar) { // Pillarboxing
+ ctm.y_scale = 1.0;
+ ctm.y_offset = 0.0;
+ ctm.x_scale = native_ar / mirror_ar;
+ ctm.x_offset = (mirror_ar - native_ar) * 0.5 * mirror_height;
+ return ctm;
+ }
+
+ return ctm; // Same aspect ratio - return identity
+}
+#endif
+
} // namespace
namespace internal {
@@ -281,6 +382,7 @@ void DisplayController::InitPrimaryDisplay() {
GetDisplayManager()->GetPrimaryDisplayCandidate();
primary_display_id = primary_candidate.id();
AddRootWindowForDisplay(primary_candidate);
+ UpdateTouchCTM();
}
void DisplayController::InitSecondaryDisplays() {
@@ -294,6 +396,7 @@ void DisplayController::InitSecondaryDisplays() {
}
}
UpdateHostWindowNames();
+ UpdateTouchCTM();
}
void DisplayController::AddObserver(Observer* observer) {
@@ -701,6 +804,80 @@ void DisplayController::PostDisplayConfigurationChange() {
FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged());
UpdateHostWindowNames();
EnsurePointerInDisplays();
+ UpdateTouchCTM();
+}
+
+void DisplayController::UpdateTouchCTM() {
+#if defined(OS_CHROMEOS) && defined(USE_X11)
+ // Clear all the old TouchCTM on all the root windows.
+ std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
+ for (; it != root_windows_.end(); it++)
+ it->second->GetDispatcher()->host()->ClearTouchCTM();
+
+ ui::OutputState output_state =
+ Shell::GetInstance()->output_configurator()->output_state();
+ if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR ||
+ output_state == ui::OUTPUT_STATE_DUAL_EXTENDED) {
+ DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair();
+ internal::DisplayInfo display1 =
+ GetDisplayManager()->GetDisplayInfo(id_pair.first);
+ internal::DisplayInfo display2 =
+ GetDisplayManager()->GetDisplayInfo(id_pair.second);
+ // For mirror mode, there is one root window shared by two displays.
+ // We add the TouchCTM of the touch display to the only one root window.
+ // For extended mode, there is one root window for each display.
+ // We add the TouchCTM of the touch display to the according root window.
+ if (display1.id() != gfx::Display::kInvalidDisplayID &&
+ display1.touch_device_id() != 0) {
+ std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
+ for (; it != root_windows_.end(); it++) {
+ if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR) {
+ it->second->GetDispatcher()->host()->SetTouchCTM(
+ display1.touch_device_id(),
+ GetMirrorModeTouchCTM(display1));
+ } else if (output_state == ui::OUTPUT_STATE_DUAL_EXTENDED &&
+ it->first == display1.id()) {
+ it->second->GetDispatcher()->host()->SetTouchCTM(
+ display1.touch_device_id(),
+ GetExtendedModeTouchCTM(display1, display2));
+ }
+ }
+ }
+
+ if (display2.id() != gfx::Display::kInvalidDisplayID &&
+ display2.touch_device_id() != 0) {
+ std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
+ for (; it != root_windows_.end(); it++) {
+ if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR) {
+ it->second->GetDispatcher()->host()->SetTouchCTM(
+ display2.touch_device_id(),
+ GetMirrorModeTouchCTM(display2));
+ } else if (output_state == ui::OUTPUT_STATE_DUAL_EXTENDED &&
+ it->first == display2.id()) {
+ it->second->GetDispatcher()->host()->SetTouchCTM(
+ display2.touch_device_id(),
+ GetExtendedModeTouchCTM(display2, display1));
+ }
+ }
+ }
+ } else {
+ // Single display mode. If the display is a touch display, we add a deafult
+ // TouchCTM to the according root window.
+ int64 display_id = GetDisplayManager()->first_display_id();
+ if (display_id != gfx::Display::kInvalidDisplayID) {
+ internal::DisplayInfo display =
+ GetDisplayManager()->GetDisplayInfo(display_id);
+ std::map<int64, aura::Window*>::iterator it = root_windows_.begin();
+ for (; it != root_windows_.end(); it++) {
+ if (it->first == display_id && display.touch_device_id() != 0) {
+ it->second->GetDispatcher()->host()->SetTouchCTM(
+ display.touch_device_id(),
+ aura::TouchCTM());
+ }
+ }
+ }
+ }
+#endif
}
aura::WindowEventDispatcher* DisplayController::AddRootWindowForDisplay(

Powered by Google App Engine
This is Rietveld 408576698