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 <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
| 8 #include <X11/Xcursor/Xcursor.h> | 8 #include <X11/Xcursor/Xcursor.h> |
| 9 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
| 10 #include <X11/cursorfont.h> | 10 #include <X11/cursorfont.h> |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "ui/base/cursor/cursor.h" | 26 #include "ui/base/cursor/cursor.h" |
| 27 #include "ui/base/keycodes/keyboard_codes.h" | 27 #include "ui/base/keycodes/keyboard_codes.h" |
| 28 #include "ui/base/resource/resource_bundle.h" | 28 #include "ui/base/resource/resource_bundle.h" |
| 29 #include "ui/base/touch/touch_factory.h" | 29 #include "ui/base/touch/touch_factory.h" |
| 30 #include "ui/base/view_prop.h" | 30 #include "ui/base/view_prop.h" |
| 31 #include "ui/base/x/x11_atom_cache.h" | 31 #include "ui/base/x/x11_atom_cache.h" |
| 32 #include "ui/base/x/x11_util.h" | 32 #include "ui/base/x/x11_util.h" |
| 33 #include "ui/compositor/layer.h" | 33 #include "ui/compositor/layer.h" |
| 34 #include "ui/gfx/codec/png_codec.h" | 34 #include "ui/gfx/codec/png_codec.h" |
| 35 #include "ui/gfx/image/image.h" | 35 #include "ui/gfx/image/image.h" |
| 36 #include "ui/gfx/image/image_skia.h" | |
| 36 | 37 |
| 37 using ui::X11AtomCache; | 38 using ui::X11AtomCache; |
| 38 using std::max; | 39 using std::max; |
| 39 using std::min; | 40 using std::min; |
| 40 | 41 |
| 41 namespace aura { | 42 namespace aura { |
| 42 | 43 |
| 43 namespace { | 44 namespace { |
| 44 | 45 |
| 45 // Standard Linux mouse buttons for going back and forward. | 46 // Standard Linux mouse buttons for going back and forward. |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 return false; | 290 return false; |
| 290 } | 291 } |
| 291 } | 292 } |
| 292 | 293 |
| 293 } // namespace | 294 } // namespace |
| 294 | 295 |
| 295 // A utility class that provides X Cursor for NativeCursors for which we have | 296 // A utility class that provides X Cursor for NativeCursors for which we have |
| 296 // image resources. | 297 // image resources. |
| 297 class RootWindowHostLinux::ImageCursors { | 298 class RootWindowHostLinux::ImageCursors { |
| 298 public: | 299 public: |
| 299 ImageCursors() { | 300 ImageCursors() : scale_factor_(0.0) { |
| 300 LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP); | 301 } |
| 301 LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY); | 302 |
| 303 void Reload(float scale_factor) { | |
| 304 if (scale_factor_ == scale_factor) | |
| 305 return; | |
| 306 scale_factor_ = scale_factor; | |
| 307 UnloadAll(); | |
| 308 // The cursor's hot points are defined in chromeos's | |
| 309 // src/platforms/assets/cursors/*.cfg files. | |
| 310 LoadImageCursor(ui::kCursorNull, IDR_AURA_CURSOR_PTR, 9, 5); | |
| 311 LoadImageCursor(ui::kCursorPointer, IDR_AURA_CURSOR_PTR, 9, 5); | |
| 312 LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP, 9, 5); | |
| 313 LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY, 9, 5); | |
| 314 LoadImageCursor(ui::kCursorHand, IDR_AURA_CURSOR_HAND, 9, 4); | |
| 315 LoadImageCursor(ui::kCursorMove, IDR_AURA_CURSOR_MOVE, 12, 12); | |
| 316 LoadImageCursor(ui::kCursorNorthEastResize, | |
| 317 IDR_AURA_CURSOR_NORTH_EAST_RESIZE, 12, 11); | |
| 318 LoadImageCursor(ui::kCursorSouthWestResize, | |
| 319 IDR_AURA_CURSOR_SOUTH_WEST_RESIZE, 12, 11); | |
| 320 LoadImageCursor(ui::kCursorSouthEastResize, | |
| 321 IDR_AURA_CURSOR_SOUTH_EAST_RESIZE, 11, 11); | |
| 322 LoadImageCursor(ui::kCursorNorthWestResize, | |
| 323 IDR_AURA_CURSOR_NORTH_WEST_RESIZE, 11, 11); | |
| 324 LoadImageCursor(ui::kCursorNorthResize, | |
| 325 IDR_AURA_CURSOR_NORTH_RESIZE, 11, 10); | |
| 326 LoadImageCursor(ui::kCursorSouthResize, | |
| 327 IDR_AURA_CURSOR_SOUTH_RESIZE, 11, 10); | |
| 328 LoadImageCursor(ui::kCursorEastResize, IDR_AURA_CURSOR_EAST_RESIZE, 11, 11); | |
| 329 LoadImageCursor(ui::kCursorWestResize, IDR_AURA_CURSOR_WEST_RESIZE, 11, 11); | |
| 330 LoadImageCursor(ui::kCursorIBeam, IDR_AURA_CURSOR_IBEAM, 12, 11); | |
| 331 | |
| 302 // TODO (varunjain): add more cursors once we have assets. | 332 // TODO (varunjain): add more cursors once we have assets. |
| 303 } | 333 } |
| 304 | 334 |
| 305 ~ImageCursors() { | 335 ~ImageCursors() { |
| 336 UnloadAll(); | |
| 337 } | |
| 338 | |
| 339 void UnloadAll() { | |
| 306 std::map<int, Cursor>::const_iterator it; | 340 std::map<int, Cursor>::const_iterator it; |
| 307 for (it = cursors_.begin(); it != cursors_.end(); ++it) | 341 for (it = cursors_.begin(); it != cursors_.end(); ++it) |
| 308 ui::UnrefCustomXCursor(it->second); | 342 ui::UnrefCustomXCursor(it->second); |
| 309 } | 343 } |
| 310 | 344 |
| 311 // Returns true if we have an image resource loaded for the |native_cursor|. | 345 // Returns true if we have an image resource loaded for the |native_cursor|. |
| 312 bool IsImageCursor(gfx::NativeCursor native_cursor) { | 346 bool IsImageCursor(gfx::NativeCursor native_cursor) { |
| 313 return cursors_.find(native_cursor.native_type()) != cursors_.end(); | 347 return cursors_.find(native_cursor.native_type()) != cursors_.end(); |
| 314 } | 348 } |
| 315 | 349 |
| 316 // Gets the X Cursor corresponding to the |native_cursor|. | 350 // Gets the X Cursor corresponding to the |native_cursor|. |
| 317 ::Cursor ImageCursorFromNative(gfx::NativeCursor native_cursor) { | 351 ::Cursor ImageCursorFromNative(gfx::NativeCursor native_cursor) { |
| 318 DCHECK(cursors_.find(native_cursor.native_type()) != cursors_.end()); | 352 DCHECK(cursors_.find(native_cursor.native_type()) != cursors_.end()); |
| 319 return cursors_[native_cursor.native_type()]; | 353 return cursors_[native_cursor.native_type()]; |
| 320 } | 354 } |
| 321 | 355 |
| 322 private: | 356 private: |
| 323 // Creates an X Cursor from an image resource and puts it in the cursor map. | 357 // Creates an X Cursor from an image resource and puts it in the cursor map. |
| 324 void LoadImageCursor(int id, int resource_id) { | 358 void LoadImageCursor(int id, int resource_id, int hot_x, int hot_y) { |
| 325 const SkBitmap* bitmap = | 359 const gfx::ImageSkia* image = |
| 326 ui::ResourceBundle::GetSharedInstance().GetImageNamed( | 360 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); |
| 327 resource_id).ToSkBitmap(); | 361 float actual_scale = 0; |
| 328 | 362 const SkBitmap& bitmap = image->GetBitmapForScale(scale_factor_, |
|
sky
2012/05/22 19:49:12
nit: you have two spaces here.
oshima
2012/05/22 19:53:08
oops, fixed. Thanks
| |
| 329 XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap, gfx::Point(0, 0)); | 363 scale_factor_, |
| 330 cursors_[id] = ui::CreateReffedCustomXCursor(image); | 364 &actual_scale); |
| 365 // We never use scaled cursor, but the following DCHECK fails | |
| 366 // because the method above coputes the actual scale from the image | |
| 367 // size instead of obtaining from the resource data, and the some | |
| 368 // of cursors are indeed not 2x size of the 2x images. | |
| 369 // TODO(oshima): Fix this and enable the following DCHECK. | |
| 370 // DCHECK_EQ(actual_scale, scale_factor_); | |
| 371 XcursorImage* x_image = | |
| 372 ui::SkBitmapToXcursorImage(&bitmap, gfx::Point(0, 0)); | |
| 373 x_image->xhot = hot_x * actual_scale; | |
| 374 x_image->yhot = hot_y * actual_scale; | |
| 375 cursors_[id] = ui::CreateReffedCustomXCursor(x_image); | |
| 331 // |bitmap| is owned by the resource bundle. So we do not need to free it. | 376 // |bitmap| is owned by the resource bundle. So we do not need to free it. |
| 332 } | 377 } |
| 333 | 378 |
| 334 // A map to hold all image cursors. It maps the cursor ID to the X Cursor. | 379 // A map to hold all image cursors. It maps the cursor ID to the X Cursor. |
| 335 std::map<int, Cursor> cursors_; | 380 std::map<int, Cursor> cursors_; |
| 336 | 381 |
| 382 float scale_factor_; | |
| 383 | |
| 337 DISALLOW_COPY_AND_ASSIGN(ImageCursors); | 384 DISALLOW_COPY_AND_ASSIGN(ImageCursors); |
| 338 }; | 385 }; |
| 339 | 386 |
| 340 RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) | 387 RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds) |
| 341 : root_window_(NULL), | 388 : root_window_(NULL), |
| 342 xdisplay_(base::MessagePumpX::GetDefaultXDisplay()), | 389 xdisplay_(base::MessagePumpX::GetDefaultXDisplay()), |
| 343 xwindow_(0), | 390 xwindow_(0), |
| 344 x_root_window_(DefaultRootWindow(xdisplay_)), | 391 x_root_window_(DefaultRootWindow(xdisplay_)), |
| 345 current_cursor_(ui::kCursorNull), | 392 current_cursor_(ui::kCursorNull), |
| 346 cursor_shown_(true), | 393 cursor_shown_(true), |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 633 MouseEvent mouseev(xev); | 680 MouseEvent mouseev(xev); |
| 634 root_window_->DispatchMouseEvent(&mouseev); | 681 root_window_->DispatchMouseEvent(&mouseev); |
| 635 break; | 682 break; |
| 636 } | 683 } |
| 637 } | 684 } |
| 638 return true; | 685 return true; |
| 639 } | 686 } |
| 640 | 687 |
| 641 void RootWindowHostLinux::SetRootWindow(RootWindow* root_window) { | 688 void RootWindowHostLinux::SetRootWindow(RootWindow* root_window) { |
| 642 root_window_ = root_window; | 689 root_window_ = root_window; |
| 690 // The device scale factor is now accessible, so load cursors now. | |
| 691 image_cursors_->Reload(root_window_->layer()->device_scale_factor()); | |
| 643 } | 692 } |
| 644 | 693 |
| 645 RootWindow* RootWindowHostLinux::GetRootWindow() { | 694 RootWindow* RootWindowHostLinux::GetRootWindow() { |
| 646 return root_window_; | 695 return root_window_; |
| 647 } | 696 } |
| 648 | 697 |
| 649 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { | 698 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { |
| 650 return xwindow_; | 699 return xwindow_; |
| 651 } | 700 } |
| 652 | 701 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 865 root_window_->ConvertPointToNativeScreen(&point); | 914 root_window_->ConvertPointToNativeScreen(&point); |
| 866 xevent.xmotion.x_root = point.x(); | 915 xevent.xmotion.x_root = point.x(); |
| 867 xevent.xmotion.y_root = point.y(); | 916 xevent.xmotion.y_root = point.y(); |
| 868 } | 917 } |
| 869 default: | 918 default: |
| 870 break; | 919 break; |
| 871 } | 920 } |
| 872 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); | 921 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); |
| 873 } | 922 } |
| 874 | 923 |
| 924 void RootWindowHostLinux::OnDeviceScaleFactorChanged( | |
| 925 float device_scale_factor) { | |
| 926 image_cursors_->Reload(device_scale_factor); | |
| 927 } | |
| 928 | |
| 875 bool RootWindowHostLinux::IsWindowManagerPresent() { | 929 bool RootWindowHostLinux::IsWindowManagerPresent() { |
| 876 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership | 930 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
| 877 // of WM_Sn selections (where n is a screen number). | 931 // of WM_Sn selections (where n is a screen number). |
| 878 return XGetSelectionOwner( | 932 return XGetSelectionOwner( |
| 879 xdisplay_, | 933 xdisplay_, |
| 880 X11AtomCache::GetInstance()->GetAtom(ui::ATOM_WM_S0)) != None; | 934 X11AtomCache::GetInstance()->GetAtom(ui::ATOM_WM_S0)) != None; |
| 881 } | 935 } |
| 882 | 936 |
| 883 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { | 937 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
| 884 ::Cursor xcursor = | 938 ::Cursor xcursor = |
| 885 image_cursors_->IsImageCursor(cursor) ? | 939 image_cursors_->IsImageCursor(cursor) ? |
| 886 image_cursors_->ImageCursorFromNative(cursor) : | 940 image_cursors_->ImageCursorFromNative(cursor) : |
| 887 cursor == ui::kCursorNone ? | 941 (cursor == ui::kCursorNone ? invisible_cursor_ : |
| 888 invisible_cursor_ : | 942 (cursor == ui::kCursorCustom ? cursor.platform() : |
| 889 cursor == ui::kCursorCustom ? | 943 ui::GetXCursor(CursorShapeFromNative(cursor)))); |
| 890 cursor.platform() : | |
| 891 ui::GetXCursor(CursorShapeFromNative(cursor)); | |
| 892 XDefineCursor(xdisplay_, xwindow_, xcursor); | 944 XDefineCursor(xdisplay_, xwindow_, xcursor); |
| 893 } | 945 } |
| 894 | 946 |
| 895 // static | 947 // static |
| 896 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { | 948 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) { |
| 897 return new RootWindowHostLinux(bounds); | 949 return new RootWindowHostLinux(bounds); |
| 898 } | 950 } |
| 899 | 951 |
| 900 // static | 952 // static |
| 901 RootWindowHost* RootWindowHost::GetForAcceleratedWidget( | 953 RootWindowHost* RootWindowHost::GetForAcceleratedWidget( |
| 902 gfx::AcceleratedWidget accelerated_widget) { | 954 gfx::AcceleratedWidget accelerated_widget) { |
| 903 return reinterpret_cast<RootWindowHost*>( | 955 return reinterpret_cast<RootWindowHost*>( |
| 904 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); | 956 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); |
| 905 } | 957 } |
| 906 | 958 |
| 907 // static | 959 // static |
| 908 gfx::Size RootWindowHost::GetNativeScreenSize() { | 960 gfx::Size RootWindowHost::GetNativeScreenSize() { |
| 909 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); | 961 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); |
| 910 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 962 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
| 911 } | 963 } |
| 912 | 964 |
| 913 } // namespace aura | 965 } // namespace aura |
| OLD | NEW |