Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/aura/root_window_host_linux.h" | 5 #include "ui/aura/root_window_host_linux.h" |
| 6 | 6 |
| 7 #include <strings.h> | |
| 7 #include <X11/cursorfont.h> | 8 #include <X11/cursorfont.h> |
| 8 #include <X11/extensions/Xfixes.h> | 9 #include <X11/extensions/Xfixes.h> |
| 9 #include <X11/extensions/XInput2.h> | 10 #include <X11/extensions/XInput2.h> |
| 10 #include <X11/extensions/Xrandr.h> | 11 #include <X11/extensions/Xrandr.h> |
| 11 #include <X11/Xatom.h> | 12 #include <X11/Xatom.h> |
| 12 #include <X11/Xcursor/Xcursor.h> | 13 #include <X11/Xcursor/Xcursor.h> |
| 13 #include <X11/Xlib.h> | 14 #include <X11/Xlib.h> |
| 15 | |
| 14 #include <algorithm> | 16 #include <algorithm> |
| 15 | 17 |
| 16 #include "base/command_line.h" | 18 #include "base/command_line.h" |
| 17 #include "base/message_loop.h" | 19 #include "base/message_loop.h" |
| 18 #include "base/message_pump_aurax11.h" | 20 #include "base/message_pump_aurax11.h" |
| 19 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
| 20 #include "base/stringprintf.h" | 22 #include "base/stringprintf.h" |
| 23 #include "third_party/skia/include/core/SkBitmap.h" | |
| 24 #include "third_party/skia/include/core/SkCanvas.h" | |
| 21 #include "ui/aura/client/capture_client.h" | 25 #include "ui/aura/client/capture_client.h" |
| 22 #include "ui/aura/client/cursor_client.h" | 26 #include "ui/aura/client/cursor_client.h" |
| 23 #include "ui/aura/client/screen_position_client.h" | 27 #include "ui/aura/client/screen_position_client.h" |
| 24 #include "ui/aura/client/user_action_client.h" | 28 #include "ui/aura/client/user_action_client.h" |
| 25 #include "ui/aura/env.h" | 29 #include "ui/aura/env.h" |
| 26 #include "ui/aura/root_window.h" | 30 #include "ui/aura/root_window.h" |
| 27 #include "ui/base/cursor/cursor.h" | 31 #include "ui/base/cursor/cursor.h" |
| 28 #include "ui/base/events/event.h" | 32 #include "ui/base/events/event.h" |
| 29 #include "ui/base/keycodes/keyboard_codes.h" | 33 #include "ui/base/keycodes/keyboard_codes.h" |
| 30 #include "ui/base/touch/touch_factory.h" | 34 #include "ui/base/touch/touch_factory.h" |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 } | 429 } |
| 426 | 430 |
| 427 ui::MouseEvent mouseev(xev); | 431 ui::MouseEvent mouseev(xev); |
| 428 TranslateAndDispatchMouseEvent(&mouseev); | 432 TranslateAndDispatchMouseEvent(&mouseev); |
| 429 break; | 433 break; |
| 430 } | 434 } |
| 431 } | 435 } |
| 432 return true; | 436 return true; |
| 433 } | 437 } |
| 434 | 438 |
| 435 bool RootWindowHostLinux::DispatchEventForRootWindow( | |
| 436 const base::NativeEvent& event) { | |
| 437 switch (event->type) { | |
| 438 case ConfigureNotify: | |
| 439 DCHECK_EQ(x_root_window_, event->xconfigure.event); | |
| 440 x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y, | |
| 441 event->xconfigure.width, event->xconfigure.height); | |
| 442 break; | |
| 443 | |
| 444 case GenericEvent: | |
| 445 DispatchXI2Event(event); | |
| 446 break; | |
| 447 } | |
| 448 | |
| 449 return true; | |
| 450 } | |
| 451 | |
| 452 void RootWindowHostLinux::DispatchXI2Event(const base::NativeEvent& event) { | |
| 453 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | |
| 454 XEvent* xev = event; | |
| 455 if (!factory->ShouldProcessXI2Event(xev)) | |
| 456 return; | |
| 457 | |
| 458 ui::EventType type = ui::EventTypeFromNative(xev); | |
| 459 XEvent last_event; | |
| 460 int num_coalesced = 0; | |
| 461 | |
| 462 switch (type) { | |
| 463 case ui::ET_TOUCH_MOVED: | |
| 464 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); | |
| 465 if (num_coalesced > 0) | |
| 466 xev = &last_event; | |
| 467 // fallthrough | |
| 468 case ui::ET_TOUCH_PRESSED: | |
| 469 case ui::ET_TOUCH_RELEASED: { | |
| 470 ui::TouchEvent touchev(xev); | |
| 471 #if defined(OS_CHROMEOS) | |
| 472 // X maps the touch-surface to the size of the X root-window. In | |
| 473 // multi-monitor setup, the X root-window size is a combination of | |
| 474 // both the monitor sizes. So it is necessary to remap the location of | |
| 475 // the event from the X root-window to the X host-window for the aura | |
| 476 // root-window. | |
| 477 if (base::chromeos::IsRunningOnChromeOS()) { | |
| 478 touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size()); | |
| 479 if (!bounds_.Contains(touchev.location())) { | |
| 480 // This might still be in the bezel region. | |
| 481 gfx::Rect expanded(bounds_); | |
| 482 expanded.Inset(-kXRootWindowPaddingLeft, | |
| 483 -kXRootWindowPaddingTop, | |
| 484 -kXRootWindowPaddingRight, | |
| 485 -kXRootWindowPaddingBottom); | |
| 486 if (!expanded.Contains(touchev.location())) | |
| 487 break; | |
| 488 } | |
| 489 } | |
| 490 #endif // defined(OS_CHROMEOS) | |
| 491 delegate_->OnHostTouchEvent(&touchev); | |
| 492 break; | |
| 493 } | |
| 494 case ui::ET_MOUSE_MOVED: | |
| 495 case ui::ET_MOUSE_DRAGGED: | |
| 496 case ui::ET_MOUSE_PRESSED: | |
| 497 case ui::ET_MOUSE_RELEASED: | |
| 498 case ui::ET_MOUSE_ENTERED: | |
| 499 case ui::ET_MOUSE_EXITED: { | |
| 500 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { | |
| 501 // If this is a motion event, we want to coalesce all pending motion | |
| 502 // events that are at the top of the queue. | |
| 503 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); | |
| 504 if (num_coalesced > 0) | |
| 505 xev = &last_event; | |
| 506 } else if (type == ui::ET_MOUSE_PRESSED) { | |
| 507 XIDeviceEvent* xievent = | |
| 508 static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
| 509 int button = xievent->detail; | |
| 510 if (button == kBackMouseButton || button == kForwardMouseButton) { | |
| 511 client::UserActionClient* gesture_client = | |
| 512 client::GetUserActionClient(delegate_->AsRootWindow()); | |
| 513 if (gesture_client) { | |
| 514 bool reverse_direction = | |
| 515 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); | |
| 516 gesture_client->OnUserAction( | |
| 517 (button == kBackMouseButton && !reverse_direction) || | |
| 518 (button == kForwardMouseButton && reverse_direction) ? | |
| 519 client::UserActionClient::BACK : | |
| 520 client::UserActionClient::FORWARD); | |
| 521 } | |
| 522 break; | |
| 523 } | |
| 524 } | |
| 525 ui::MouseEvent mouseev(xev); | |
| 526 TranslateAndDispatchMouseEvent(&mouseev); | |
| 527 break; | |
| 528 } | |
| 529 case ui::ET_MOUSEWHEEL: { | |
| 530 ui::MouseWheelEvent mouseev(xev); | |
| 531 TranslateAndDispatchMouseEvent(&mouseev); | |
| 532 break; | |
| 533 } | |
| 534 case ui::ET_SCROLL_FLING_START: | |
| 535 case ui::ET_SCROLL_FLING_CANCEL: | |
| 536 case ui::ET_SCROLL: { | |
| 537 ui::ScrollEvent scrollev(xev); | |
| 538 delegate_->OnHostScrollEvent(&scrollev); | |
| 539 break; | |
| 540 } | |
| 541 case ui::ET_UNKNOWN: | |
| 542 break; | |
| 543 default: | |
| 544 NOTREACHED(); | |
| 545 } | |
| 546 | |
| 547 // If we coalesced an event we need to free its cookie. | |
| 548 if (num_coalesced > 0) | |
| 549 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | |
| 550 } | |
| 551 | |
| 552 void RootWindowHostLinux::SetDelegate(RootWindowHostDelegate* delegate) { | 439 void RootWindowHostLinux::SetDelegate(RootWindowHostDelegate* delegate) { |
| 553 delegate_ = delegate; | 440 delegate_ = delegate; |
| 554 } | 441 } |
| 555 | 442 |
| 556 RootWindow* RootWindowHostLinux::GetRootWindow() { | 443 RootWindow* RootWindowHostLinux::GetRootWindow() { |
| 557 return delegate_->AsRootWindow(); | 444 return delegate_->AsRootWindow(); |
| 558 } | 445 } |
| 559 | 446 |
| 560 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { | 447 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { |
| 561 return xwindow_; | 448 return xwindow_; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 734 static const char* k_NET_WM_USER_TIME = "_NET_WM_USER_TIME"; | 621 static const char* k_NET_WM_USER_TIME = "_NET_WM_USER_TIME"; |
| 735 focus_when_shown_ = focus_when_shown; | 622 focus_when_shown_ = focus_when_shown; |
| 736 if (IsWindowManagerPresent() && !focus_when_shown_) { | 623 if (IsWindowManagerPresent() && !focus_when_shown_) { |
| 737 ui::SetIntProperty(xwindow_, | 624 ui::SetIntProperty(xwindow_, |
| 738 k_NET_WM_USER_TIME, | 625 k_NET_WM_USER_TIME, |
| 739 k_NET_WM_USER_TIME, | 626 k_NET_WM_USER_TIME, |
| 740 0); | 627 0); |
| 741 } | 628 } |
| 742 } | 629 } |
| 743 | 630 |
| 631 bool RootWindowHostLinux::CopyAreaToSkCanvas(const gfx::Rect& source_bounds, | |
| 632 const gfx::Point& dest_offset, | |
| 633 SkCanvas* canvas) { | |
| 634 scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(source_bounds)); | |
| 635 if (!scoped_image.get()) | |
| 636 return false; | |
| 637 | |
| 638 XImage* image = scoped_image->get(); | |
| 639 DCHECK(image); | |
| 640 | |
| 641 if (image->bits_per_pixel == 32) { | |
| 642 // Set the alpha channel before copying to the canvas. Otherwise, areas of | |
| 643 // the framebuffer that were cleared by ply-image rather than being obscured | |
| 644 // by an image during boot may end up transparent. | |
| 645 // TODO(derat|marcheu): Remove this if/when ply-image has been updated to | |
| 646 // set the framebuffer's alpha channel regardless of whether the device | |
| 647 // claims to support alpha or not. | |
| 648 for (int i = 0; i < image->width * image->height * 4; i += 4) | |
| 649 image->data[i + 3] = 0xff; | |
| 650 | |
| 651 SkBitmap bitmap; | |
| 652 bitmap.setConfig(SkBitmap::kARGB_8888_Config, | |
| 653 image->width, image->height, | |
| 654 image->bytes_per_line); | |
| 655 bitmap.setPixels(image->data); | |
| 656 SkCanvas::Config8888 config = | |
| 657 (image->byte_order == LSBFirst) ? | |
| 658 SkCanvas::kBGRA_Unpremul_Config8888 : | |
| 659 SkCanvas::kRGBA_Unpremul_Config8888; | |
| 660 canvas->writePixels(bitmap, dest_offset.x(), dest_offset.y(), config); | |
| 661 } else if (image->bits_per_pixel == 24) { | |
| 662 NOTIMPLEMENTED() << "Unsupported bits-per-pixel " << image->bits_per_pixel; | |
| 663 return false; | |
| 664 } | |
| 665 | |
| 666 return true; | |
| 667 } | |
| 668 | |
| 744 bool RootWindowHostLinux::GrabSnapshot( | 669 bool RootWindowHostLinux::GrabSnapshot( |
| 745 const gfx::Rect& snapshot_bounds, | 670 const gfx::Rect& snapshot_bounds, |
| 746 std::vector<unsigned char>* png_representation) { | 671 std::vector<unsigned char>* png_representation) { |
| 747 ui::XScopedImage image(XGetImage( | 672 scoped_ptr<ui::XScopedImage> scoped_image(GetXImage(snapshot_bounds)); |
| 748 xdisplay_, xwindow_, | 673 if (!scoped_image.get()) |
| 749 snapshot_bounds.x(), snapshot_bounds.y(), | 674 return false; |
| 750 snapshot_bounds.width(), snapshot_bounds.height(), | |
| 751 AllPlanes, ZPixmap)); | |
| 752 | 675 |
| 753 if (!image.get()) { | 676 XImage* image = scoped_image->get(); |
| 754 LOG(ERROR) << "XGetImage failed"; | 677 DCHECK(image); |
| 755 return false; | |
| 756 } | |
| 757 | 678 |
| 758 gfx::PNGCodec::ColorFormat color_format; | 679 gfx::PNGCodec::ColorFormat color_format; |
| 759 | 680 |
| 760 if (image->bits_per_pixel == 32) { | 681 if (image->bits_per_pixel == 32) { |
| 761 color_format = (image->byte_order == LSBFirst) ? | 682 color_format = (image->byte_order == LSBFirst) ? |
| 762 gfx::PNGCodec::FORMAT_BGRA : gfx::PNGCodec::FORMAT_RGBA; | 683 gfx::PNGCodec::FORMAT_BGRA : gfx::PNGCodec::FORMAT_RGBA; |
| 763 } else if (image->bits_per_pixel == 24) { | 684 } else if (image->bits_per_pixel == 24) { |
| 764 // PNGCodec accepts FORMAT_RGB for 3 bytes per pixel: | 685 // PNGCodec accepts FORMAT_RGB for 3 bytes per pixel: |
| 765 color_format = gfx::PNGCodec::FORMAT_RGB; | 686 color_format = gfx::PNGCodec::FORMAT_RGB; |
| 766 if (image->byte_order == LSBFirst) { | 687 if (image->byte_order == LSBFirst) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 820 } | 741 } |
| 821 | 742 |
| 822 void RootWindowHostLinux::OnDeviceScaleFactorChanged( | 743 void RootWindowHostLinux::OnDeviceScaleFactorChanged( |
| 823 float device_scale_factor) { | 744 float device_scale_factor) { |
| 824 } | 745 } |
| 825 | 746 |
| 826 void RootWindowHostLinux::PrepareForShutdown() { | 747 void RootWindowHostLinux::PrepareForShutdown() { |
| 827 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); | 748 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); |
| 828 } | 749 } |
| 829 | 750 |
| 751 bool RootWindowHostLinux::DispatchEventForRootWindow( | |
|
Daniel Erat
2012/10/26 00:41:15
sorry, moved this code without any changes to it t
| |
| 752 const base::NativeEvent& event) { | |
| 753 switch (event->type) { | |
| 754 case ConfigureNotify: | |
| 755 DCHECK_EQ(x_root_window_, event->xconfigure.event); | |
| 756 x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y, | |
| 757 event->xconfigure.width, event->xconfigure.height); | |
| 758 break; | |
| 759 | |
| 760 case GenericEvent: | |
| 761 DispatchXI2Event(event); | |
| 762 break; | |
| 763 } | |
| 764 | |
| 765 return true; | |
| 766 } | |
| 767 | |
| 768 void RootWindowHostLinux::DispatchXI2Event(const base::NativeEvent& event) { | |
| 769 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | |
| 770 XEvent* xev = event; | |
| 771 if (!factory->ShouldProcessXI2Event(xev)) | |
| 772 return; | |
| 773 | |
| 774 ui::EventType type = ui::EventTypeFromNative(xev); | |
| 775 XEvent last_event; | |
| 776 int num_coalesced = 0; | |
| 777 | |
| 778 switch (type) { | |
| 779 case ui::ET_TOUCH_MOVED: | |
| 780 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); | |
| 781 if (num_coalesced > 0) | |
| 782 xev = &last_event; | |
| 783 // fallthrough | |
| 784 case ui::ET_TOUCH_PRESSED: | |
| 785 case ui::ET_TOUCH_RELEASED: { | |
| 786 ui::TouchEvent touchev(xev); | |
| 787 #if defined(OS_CHROMEOS) | |
| 788 // X maps the touch-surface to the size of the X root-window. In | |
| 789 // multi-monitor setup, the X root-window size is a combination of | |
| 790 // both the monitor sizes. So it is necessary to remap the location of | |
| 791 // the event from the X root-window to the X host-window for the aura | |
| 792 // root-window. | |
| 793 if (base::chromeos::IsRunningOnChromeOS()) { | |
| 794 touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size()); | |
| 795 if (!bounds_.Contains(touchev.location())) { | |
| 796 // This might still be in the bezel region. | |
| 797 gfx::Rect expanded(bounds_); | |
| 798 expanded.Inset(-kXRootWindowPaddingLeft, | |
| 799 -kXRootWindowPaddingTop, | |
| 800 -kXRootWindowPaddingRight, | |
| 801 -kXRootWindowPaddingBottom); | |
| 802 if (!expanded.Contains(touchev.location())) | |
| 803 break; | |
| 804 } | |
| 805 } | |
| 806 #endif // defined(OS_CHROMEOS) | |
| 807 delegate_->OnHostTouchEvent(&touchev); | |
| 808 break; | |
| 809 } | |
| 810 case ui::ET_MOUSE_MOVED: | |
| 811 case ui::ET_MOUSE_DRAGGED: | |
| 812 case ui::ET_MOUSE_PRESSED: | |
| 813 case ui::ET_MOUSE_RELEASED: | |
| 814 case ui::ET_MOUSE_ENTERED: | |
| 815 case ui::ET_MOUSE_EXITED: { | |
| 816 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { | |
| 817 // If this is a motion event, we want to coalesce all pending motion | |
| 818 // events that are at the top of the queue. | |
| 819 num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event); | |
| 820 if (num_coalesced > 0) | |
| 821 xev = &last_event; | |
| 822 } else if (type == ui::ET_MOUSE_PRESSED) { | |
| 823 XIDeviceEvent* xievent = | |
| 824 static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
| 825 int button = xievent->detail; | |
| 826 if (button == kBackMouseButton || button == kForwardMouseButton) { | |
| 827 client::UserActionClient* gesture_client = | |
| 828 client::GetUserActionClient(delegate_->AsRootWindow()); | |
| 829 if (gesture_client) { | |
| 830 bool reverse_direction = | |
| 831 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); | |
| 832 gesture_client->OnUserAction( | |
| 833 (button == kBackMouseButton && !reverse_direction) || | |
| 834 (button == kForwardMouseButton && reverse_direction) ? | |
| 835 client::UserActionClient::BACK : | |
| 836 client::UserActionClient::FORWARD); | |
| 837 } | |
| 838 break; | |
| 839 } | |
| 840 } | |
| 841 ui::MouseEvent mouseev(xev); | |
| 842 TranslateAndDispatchMouseEvent(&mouseev); | |
| 843 break; | |
| 844 } | |
| 845 case ui::ET_MOUSEWHEEL: { | |
| 846 ui::MouseWheelEvent mouseev(xev); | |
| 847 TranslateAndDispatchMouseEvent(&mouseev); | |
| 848 break; | |
| 849 } | |
| 850 case ui::ET_SCROLL_FLING_START: | |
| 851 case ui::ET_SCROLL_FLING_CANCEL: | |
| 852 case ui::ET_SCROLL: { | |
| 853 ui::ScrollEvent scrollev(xev); | |
| 854 delegate_->OnHostScrollEvent(&scrollev); | |
| 855 break; | |
| 856 } | |
| 857 case ui::ET_UNKNOWN: | |
| 858 break; | |
| 859 default: | |
| 860 NOTREACHED(); | |
| 861 } | |
| 862 | |
| 863 // If we coalesced an event we need to free its cookie. | |
| 864 if (num_coalesced > 0) | |
| 865 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | |
| 866 } | |
| 867 | |
| 830 bool RootWindowHostLinux::IsWindowManagerPresent() { | 868 bool RootWindowHostLinux::IsWindowManagerPresent() { |
| 831 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership | 869 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
| 832 // of WM_Sn selections (where n is a screen number). | 870 // of WM_Sn selections (where n is a screen number). |
| 833 return XGetSelectionOwner( | 871 return XGetSelectionOwner( |
| 834 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; | 872 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; |
| 835 } | 873 } |
| 836 | 874 |
| 837 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { | 875 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
| 838 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | 876 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); |
| 839 } | 877 } |
| 840 | 878 |
| 841 void RootWindowHostLinux::TranslateAndDispatchMouseEvent( | 879 void RootWindowHostLinux::TranslateAndDispatchMouseEvent( |
| 842 ui::MouseEvent* event) { | 880 ui::MouseEvent* event) { |
| 843 RootWindow* root = GetRootWindow(); | 881 RootWindow* root = GetRootWindow(); |
| 844 client::ScreenPositionClient* screen_position_client = | 882 client::ScreenPositionClient* screen_position_client = |
| 845 GetScreenPositionClient(root); | 883 GetScreenPositionClient(root); |
| 846 if (screen_position_client && !bounds_.Contains(event->location())) { | 884 if (screen_position_client && !bounds_.Contains(event->location())) { |
| 847 gfx::Point location(event->location()); | 885 gfx::Point location(event->location()); |
| 848 screen_position_client->ConvertNativePointToScreen(root, &location); | 886 screen_position_client->ConvertNativePointToScreen(root, &location); |
| 849 screen_position_client->ConvertPointFromScreen(root, &location); | 887 screen_position_client->ConvertPointFromScreen(root, &location); |
| 850 // |delegate_|'s OnHoustMouseEvent expects native coordinates relative to | 888 // |delegate_|'s OnHoustMouseEvent expects native coordinates relative to |
| 851 // root. | 889 // root. |
| 852 location = ui::ConvertPointToPixel(root->layer(), location); | 890 location = ui::ConvertPointToPixel(root->layer(), location); |
| 853 event->set_location(location); | 891 event->set_location(location); |
| 854 event->set_root_location(location); | 892 event->set_root_location(location); |
| 855 } | 893 } |
| 856 delegate_->OnHostMouseEvent(event); | 894 delegate_->OnHostMouseEvent(event); |
| 857 } | 895 } |
| 858 | 896 |
| 897 scoped_ptr<ui::XScopedImage> RootWindowHostLinux::GetXImage( | |
| 898 const gfx::Rect& snapshot_bounds) { | |
| 899 scoped_ptr<ui::XScopedImage> image(new ui::XScopedImage( | |
| 900 XGetImage(xdisplay_, xwindow_, | |
| 901 snapshot_bounds.x(), snapshot_bounds.y(), | |
| 902 snapshot_bounds.width(), snapshot_bounds.height(), | |
| 903 AllPlanes, ZPixmap))); | |
| 904 if (!image->get()) { | |
| 905 LOG(ERROR) << "XGetImage failed"; | |
| 906 image.reset(); | |
| 907 } | |
| 908 return image.Pass(); | |
| 909 } | |
| 910 | |
| 859 // static | 911 // static |
| 860 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { | 912 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { |
| 861 return new RootWindowHostLinux(bounds); | 913 return new RootWindowHostLinux(bounds); |
| 862 } | 914 } |
| 863 | 915 |
| 864 // static | 916 // static |
| 865 gfx::Size RootWindowHost::GetNativeScreenSize() { | 917 gfx::Size RootWindowHost::GetNativeScreenSize() { |
| 866 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 918 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); |
| 867 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 919 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
| 868 } | 920 } |
| 869 | 921 |
| 870 } // namespace aura | 922 } // namespace aura |
| OLD | NEW |