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 |