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