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

Side by Side Diff: ui/aura/root_window_host_linux.cc

Issue 10919135: Move ash specific cursor code to CursorManager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/aura/root_window_host_linux.h ('k') | ui/aura/root_window_host_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/cursorfont.h> 7 #include <X11/cursorfont.h>
8 #include <X11/extensions/Xfixes.h> 8 #include <X11/extensions/Xfixes.h>
9 #include <X11/extensions/XInput2.h> 9 #include <X11/extensions/XInput2.h>
10 #include <X11/extensions/Xrandr.h> 10 #include <X11/extensions/Xrandr.h>
11 #include <X11/Xatom.h> 11 #include <X11/Xatom.h>
12 #include <X11/Xcursor/Xcursor.h> 12 #include <X11/Xcursor/Xcursor.h>
13 #include <X11/Xlib.h> 13 #include <X11/Xlib.h>
14 #include <algorithm> 14 #include <algorithm>
15 15
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/message_pump_aurax11.h" 17 #include "base/message_pump_aurax11.h"
18 #include "base/stl_util.h" 18 #include "base/stl_util.h"
19 #include "base/stringprintf.h" 19 #include "base/stringprintf.h"
20 #include "grit/ui_resources.h"
21 #include "ui/aura/client/capture_client.h" 20 #include "ui/aura/client/capture_client.h"
21 #include "ui/aura/client/cursor_client.h"
22 #include "ui/aura/client/screen_position_client.h" 22 #include "ui/aura/client/screen_position_client.h"
23 #include "ui/aura/client/user_action_client.h" 23 #include "ui/aura/client/user_action_client.h"
24 #include "ui/aura/env.h" 24 #include "ui/aura/env.h"
25 #include "ui/aura/root_window.h" 25 #include "ui/aura/root_window.h"
26 #include "ui/base/cursor/cursor.h" 26 #include "ui/base/cursor/cursor.h"
27 #include "ui/base/events/event.h" 27 #include "ui/base/events/event.h"
28 #include "ui/base/keycodes/keyboard_codes.h" 28 #include "ui/base/keycodes/keyboard_codes.h"
29 #include "ui/base/resource/resource_bundle.h"
30 #include "ui/base/touch/touch_factory.h" 29 #include "ui/base/touch/touch_factory.h"
31 #include "ui/base/ui_base_switches.h" 30 #include "ui/base/ui_base_switches.h"
32 #include "ui/base/view_prop.h" 31 #include "ui/base/view_prop.h"
33 #include "ui/base/x/valuators.h" 32 #include "ui/base/x/valuators.h"
34 #include "ui/base/x/x11_util.h" 33 #include "ui/base/x/x11_util.h"
35 #include "ui/compositor/layer.h" 34 #include "ui/compositor/layer.h"
36 #include "ui/gfx/codec/png_codec.h" 35 #include "ui/gfx/codec/png_codec.h"
37 #include "ui/gfx/image/image.h"
38 #include "ui/gfx/image/image_skia.h"
39 #include "ui/gfx/screen.h" 36 #include "ui/gfx/screen.h"
40 37
41 using std::max; 38 using std::max;
42 using std::min; 39 using std::min;
43 40
44 namespace aura { 41 namespace aura {
45 42
46 namespace { 43 namespace {
47 44
48 // Standard Linux mouse buttons for going back and forward. 45 // Standard Linux mouse buttons for going back and forward.
49 const int kBackMouseButton = 8; 46 const int kBackMouseButton = 8;
50 const int kForwardMouseButton = 9; 47 const int kForwardMouseButton = 9;
51 48
52 const int kAnimatedCursorFrameDelayMs = 25;
53
54 // These are the same values that are used to calibrate touch events in 49 // These are the same values that are used to calibrate touch events in
55 // |CalibrateTouchCoordinates| (in ui/base/x/events_x.cc). 50 // |CalibrateTouchCoordinates| (in ui/base/x/events_x.cc).
56 // TODO(sad|skuhne): Remove the duplication of values (http://crbug.com/147605) 51 // TODO(sad|skuhne): Remove the duplication of values (http://crbug.com/147605)
57 const int kXRootWindowPaddingLeft = 40; 52 const int kXRootWindowPaddingLeft = 40;
58 const int kXRootWindowPaddingRight = 40; 53 const int kXRootWindowPaddingRight = 40;
59 const int kXRootWindowPaddingBottom = 30; 54 const int kXRootWindowPaddingBottom = 30;
60 const int kXRootWindowPaddingTop = 0; 55 const int kXRootWindowPaddingTop = 0;
61 56
62 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__"; 57 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__";
63 58
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 CHECK_EQ(slave_event.buttons.mask_len, xievent->buttons.mask_len); 108 CHECK_EQ(slave_event.buttons.mask_len, xievent->buttons.mask_len);
114 CHECK_EQ(slave_event.valuators.mask_len, xievent->valuators.mask_len); 109 CHECK_EQ(slave_event.valuators.mask_len, xievent->valuators.mask_len);
115 CHECK_EQ(slave_event.mods.base, xievent->mods.base); 110 CHECK_EQ(slave_event.mods.base, xievent->mods.base);
116 CHECK_EQ(slave_event.mods.latched, xievent->mods.latched); 111 CHECK_EQ(slave_event.mods.latched, xievent->mods.latched);
117 CHECK_EQ(slave_event.mods.locked, xievent->mods.locked); 112 CHECK_EQ(slave_event.mods.locked, xievent->mods.locked);
118 CHECK_EQ(slave_event.mods.effective, xievent->mods.effective); 113 CHECK_EQ(slave_event.mods.effective, xievent->mods.effective);
119 } 114 }
120 #endif // defined(USE_XI2_MT) && !defined(NDEBUG) 115 #endif // defined(USE_XI2_MT) && !defined(NDEBUG)
121 } 116 }
122 117
123 // Returns X font cursor shape from an Aura cursor.
124 int CursorShapeFromNative(gfx::NativeCursor native_cursor) {
125 switch (native_cursor.native_type()) {
126 case ui::kCursorMiddlePanning:
127 return XC_fleur;
128 case ui::kCursorEastPanning:
129 return XC_sb_right_arrow;
130 case ui::kCursorNorthPanning:
131 return XC_sb_up_arrow;
132 case ui::kCursorNorthEastPanning:
133 return XC_top_right_corner;
134 case ui::kCursorNorthWestPanning:
135 return XC_top_left_corner;
136 case ui::kCursorSouthPanning:
137 return XC_sb_down_arrow;
138 case ui::kCursorSouthEastPanning:
139 return XC_bottom_right_corner;
140 case ui::kCursorSouthWestPanning:
141 return XC_bottom_left_corner;
142 case ui::kCursorWestPanning:
143 return XC_sb_left_arrow;
144 case ui::kCursorNone:
145 // TODO(jamescook): Need cursors for these. crbug.com/111650
146 return XC_left_ptr;
147
148 case ui::kCursorNull:
149 case ui::kCursorPointer:
150 case ui::kCursorNoDrop:
151 case ui::kCursorNotAllowed:
152 case ui::kCursorCopy:
153 case ui::kCursorMove:
154 case ui::kCursorEastResize:
155 case ui::kCursorNorthResize:
156 case ui::kCursorSouthResize:
157 case ui::kCursorWestResize:
158 case ui::kCursorNorthEastResize:
159 case ui::kCursorNorthWestResize:
160 case ui::kCursorSouthWestResize:
161 case ui::kCursorSouthEastResize:
162 case ui::kCursorIBeam:
163 case ui::kCursorAlias:
164 case ui::kCursorCell:
165 case ui::kCursorContextMenu:
166 case ui::kCursorCross:
167 case ui::kCursorHelp:
168 case ui::kCursorWait:
169 case ui::kCursorNorthSouthResize:
170 case ui::kCursorEastWestResize:
171 case ui::kCursorNorthEastSouthWestResize:
172 case ui::kCursorNorthWestSouthEastResize:
173 case ui::kCursorProgress:
174 case ui::kCursorColumnResize:
175 case ui::kCursorRowResize:
176 case ui::kCursorVerticalText:
177 case ui::kCursorZoomIn:
178 case ui::kCursorZoomOut:
179 case ui::kCursorGrab:
180 case ui::kCursorGrabbing:
181 NOTREACHED() << "Cursor (" << native_cursor.native_type() << ") should "
182 << "have an image asset.";
183 return XC_left_ptr;
184 case ui::kCursorCustom:
185 NOTREACHED();
186 return XC_left_ptr;
187 }
188 NOTREACHED();
189 return XC_left_ptr;
190 }
191
192 // Coalesce all pending motion events (touch or mouse) that are at the top of 118 // Coalesce all pending motion events (touch or mouse) that are at the top of
193 // the queue, and return the number eliminated, storing the last one in 119 // the queue, and return the number eliminated, storing the last one in
194 // |last_event|. 120 // |last_event|.
195 int CoalescePendingMotionEvents(const XEvent* xev, XEvent* last_event) { 121 int CoalescePendingMotionEvents(const XEvent* xev, XEvent* last_event) {
196 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); 122 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
197 int num_coalesed = 0; 123 int num_coalesed = 0;
198 Display* display = xev->xany.display; 124 Display* display = xev->xany.display;
199 int event_type = xev->xgeneric.evtype; 125 int event_type = xev->xgeneric.evtype;
200 126
201 #if defined(USE_XI2_MT) 127 #if defined(USE_XI2_MT)
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 case ui::VKEY_OEM_MINUS: 269 case ui::VKEY_OEM_MINUS:
344 case ui::VKEY_OEM_PERIOD: 270 case ui::VKEY_OEM_PERIOD:
345 return true; 271 return true;
346 default: 272 default:
347 return false; 273 return false;
348 } 274 }
349 } 275 }
350 276
351 } // namespace 277 } // namespace
352 278
353 // A utility class that provides X Cursor for NativeCursors for which we have
354 // image resources.
355 class RootWindowHostLinux::ImageCursors {
356 public:
357 ImageCursors() : scale_factor_(0.0) {
358 }
359
360 void Reload(float scale_factor) {
361 if (scale_factor_ == scale_factor)
362 return;
363 scale_factor_ = scale_factor;
364 UnloadAll();
365 // The cursor's hot points are defined in chromeos cursor images at:
366 // http://folder/kuscher/projects/Chrome_OS/Pointers/focuspoint
367 LoadImageCursor(ui::kCursorNull, IDR_AURA_CURSOR_PTR,
368 gfx::Point(4, 4), gfx::Point(8, 9));
369 LoadImageCursor(ui::kCursorPointer, IDR_AURA_CURSOR_PTR,
370 gfx::Point(4, 4), gfx::Point(8, 9));
371 LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP,
372 gfx::Point(4, 4), gfx::Point(8, 9));
373 LoadImageCursor(ui::kCursorNotAllowed, IDR_AURA_CURSOR_NO_DROP,
374 gfx::Point(4, 4), gfx::Point(8, 9));
375 LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY,
376 gfx::Point(4, 4), gfx::Point(8, 9));
377 LoadImageCursor(ui::kCursorHand, IDR_AURA_CURSOR_HAND,
378 gfx::Point(9, 4), gfx::Point(19, 8));
379 LoadImageCursor(ui::kCursorMove, IDR_AURA_CURSOR_MOVE,
380 gfx::Point(11, 11), gfx::Point(23, 23));
381 LoadImageCursor(ui::kCursorNorthEastResize,
382 IDR_AURA_CURSOR_NORTH_EAST_RESIZE,
383 gfx::Point(12, 11), gfx::Point(25, 23));
384 LoadImageCursor(ui::kCursorSouthWestResize,
385 IDR_AURA_CURSOR_SOUTH_WEST_RESIZE,
386 gfx::Point(12, 11), gfx::Point(25, 23));
387 LoadImageCursor(ui::kCursorSouthEastResize,
388 IDR_AURA_CURSOR_SOUTH_EAST_RESIZE,
389 gfx::Point(11, 11), gfx::Point(24, 23));
390 LoadImageCursor(ui::kCursorNorthWestResize,
391 IDR_AURA_CURSOR_NORTH_WEST_RESIZE,
392 gfx::Point(11, 11), gfx::Point(24, 23));
393 LoadImageCursor(ui::kCursorNorthResize, IDR_AURA_CURSOR_NORTH_RESIZE,
394 gfx::Point(11, 12), gfx::Point(23, 23));
395 LoadImageCursor(ui::kCursorSouthResize, IDR_AURA_CURSOR_SOUTH_RESIZE,
396 gfx::Point(11, 12), gfx::Point(23, 23));
397 LoadImageCursor(ui::kCursorEastResize, IDR_AURA_CURSOR_EAST_RESIZE,
398 gfx::Point(12, 11), gfx::Point(25, 23));
399 LoadImageCursor(ui::kCursorWestResize, IDR_AURA_CURSOR_WEST_RESIZE,
400 gfx::Point(12, 11), gfx::Point(25, 23));
401 LoadImageCursor(ui::kCursorIBeam, IDR_AURA_CURSOR_IBEAM,
402 gfx::Point(12, 12), gfx::Point(24, 25));
403 LoadImageCursor(ui::kCursorAlias, IDR_AURA_CURSOR_ALIAS,
404 gfx::Point(8, 6), gfx::Point(15, 11));
405 LoadImageCursor(ui::kCursorCell, IDR_AURA_CURSOR_CELL,
406 gfx::Point(11, 11), gfx::Point(24, 23));
407 LoadImageCursor(ui::kCursorContextMenu, IDR_AURA_CURSOR_CONTEXT_MENU,
408 gfx::Point(4, 4), gfx::Point(8, 9));
409 LoadImageCursor(ui::kCursorCross, IDR_AURA_CURSOR_CROSSHAIR,
410 gfx::Point(12, 12), gfx::Point(25, 23));
411 LoadImageCursor(ui::kCursorHelp, IDR_AURA_CURSOR_HELP,
412 gfx::Point(4, 4), gfx::Point(8, 9));
413 LoadImageCursor(ui::kCursorVerticalText, IDR_AURA_CURSOR_XTERM_HORIZ,
414 gfx::Point(12, 11), gfx::Point(26, 23));
415 LoadImageCursor(ui::kCursorZoomIn, IDR_AURA_CURSOR_ZOOM_IN,
416 gfx::Point(10, 10), gfx::Point(20, 20));
417 LoadImageCursor(ui::kCursorZoomOut, IDR_AURA_CURSOR_ZOOM_OUT,
418 gfx::Point(10, 10), gfx::Point(20, 20));
419 LoadImageCursor(ui::kCursorRowResize, IDR_AURA_CURSOR_ROW_RESIZE,
420 gfx::Point(11, 12), gfx::Point(23, 23));
421 LoadImageCursor(ui::kCursorColumnResize, IDR_AURA_CURSOR_COL_RESIZE,
422 gfx::Point(12, 11), gfx::Point(25, 23));
423 LoadImageCursor(ui::kCursorEastWestResize, IDR_AURA_CURSOR_EAST_WEST_RESIZE,
424 gfx::Point(12, 11), gfx::Point(25, 23));
425 LoadImageCursor(ui::kCursorNorthSouthResize,
426 IDR_AURA_CURSOR_NORTH_SOUTH_RESIZE,
427 gfx::Point(11, 12), gfx::Point(23, 23));
428 LoadImageCursor(ui::kCursorNorthEastSouthWestResize,
429 IDR_AURA_CURSOR_NORTH_EAST_SOUTH_WEST_RESIZE,
430 gfx::Point(12, 11), gfx::Point(25, 23));
431 LoadImageCursor(ui::kCursorNorthWestSouthEastResize,
432 IDR_AURA_CURSOR_NORTH_WEST_SOUTH_EAST_RESIZE,
433 gfx::Point(11, 11), gfx::Point(24, 23));
434 LoadImageCursor(ui::kCursorGrab, IDR_AURA_CURSOR_GRAB,
435 gfx::Point(8, 5), gfx::Point(16, 10));
436 LoadImageCursor(ui::kCursorGrabbing, IDR_AURA_CURSOR_GRABBING,
437 gfx::Point(9, 9), gfx::Point(18, 18));
438 LoadAnimatedCursor(ui::kCursorWait, IDR_THROBBER, 7, 7);
439 LoadAnimatedCursor(ui::kCursorProgress, IDR_THROBBER, 7, 7);
440 }
441
442 ~ImageCursors() {
443 UnloadAll();
444 }
445
446 void UnloadAll() {
447 for (std::map<int, Cursor>::const_iterator it = cursors_.begin();
448 it != cursors_.end(); ++it)
449 ui::UnrefCustomXCursor(it->second);
450
451 // Free animated cursors and images.
452 for (AnimatedCursorMap::iterator it = animated_cursors_.begin();
453 it != animated_cursors_.end(); ++it) {
454 XcursorImagesDestroy(it->second.second); // also frees individual frames.
455 XFreeCursor(ui::GetXDisplay(), it->second.first);
456 }
457 }
458
459 // Returns true if we have an image resource loaded for the |native_cursor|.
460 bool IsImageCursor(gfx::NativeCursor native_cursor) {
461 int type = native_cursor.native_type();
462 return cursors_.find(type) != cursors_.end() ||
463 animated_cursors_.find(type) != animated_cursors_.end();
464 }
465
466 // Gets the X Cursor corresponding to the |native_cursor|.
467 ::Cursor ImageCursorFromNative(gfx::NativeCursor native_cursor) {
468 int type = native_cursor.native_type();
469 if (animated_cursors_.find(type) != animated_cursors_.end())
470 return animated_cursors_[type].first;
471 DCHECK(cursors_.find(type) != cursors_.end());
472 return cursors_[type];
473 }
474
475 private:
476 // Creates an X Cursor from an image resource and puts it in the cursor map.
477 void LoadImageCursor(int id,
478 int resource_id,
479 const gfx::Point& hot_1x,
480 const gfx::Point& hot_2x) {
481 const gfx::ImageSkia* image =
482 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
483 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
484 ui::GetScaleFactorFromScale(scale_factor_));
485 const gfx::Point& hot = (scale_factor_ == 1) ? hot_1x : hot_2x;
486 XcursorImage* x_image =
487 ui::SkBitmapToXcursorImage(&image_rep.sk_bitmap(), hot);
488 cursors_[id] = ui::CreateReffedCustomXCursor(x_image);
489 // |bitmap| is owned by the resource bundle. So we do not need to free it.
490 }
491
492 // Creates an animated X Cursor from an image resource and puts it in the
493 // cursor map. The image is assumed to be a concatenation of animation frames.
494 // Also, each frame is assumed to be square (width == height)
495 void LoadAnimatedCursor(int id, int resource_id, int hot_x, int hot_y) {
496 const gfx::ImageSkia* image =
497 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
498 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
499 ui::GetScaleFactorFromScale(scale_factor_));
500 const SkBitmap bitmap = image_rep.sk_bitmap();
501 DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
502 int frame_width = bitmap.height();
503 int frame_height = frame_width;
504 int total_width = bitmap.width();
505 DCHECK_EQ(total_width % frame_width, 0);
506 int frame_count = total_width / frame_width;
507 DCHECK_GT(frame_count, 0);
508 XcursorImages* x_images = XcursorImagesCreate(frame_count);
509 x_images->nimage = frame_count;
510 bitmap.lockPixels();
511 unsigned int* pixels = bitmap.getAddr32(0, 0);
512 // Create each frame.
513 for (int i = 0; i < frame_count; ++i) {
514 XcursorImage* x_image = XcursorImageCreate(frame_width, frame_height);
515 for (int j = 0; j < frame_height; ++j) {
516 // Copy j'th row of i'th frame.
517 memcpy(x_image->pixels + j * frame_width,
518 pixels + i * frame_width + j * total_width,
519 frame_width * 4);
520 }
521 x_image->xhot = hot_x * scale_factor_;
522 x_image->yhot = hot_y * scale_factor_;
523 x_image->delay = kAnimatedCursorFrameDelayMs;
524 x_images->images[i] = x_image;
525 }
526 bitmap.unlockPixels();
527
528 animated_cursors_[id] = std::make_pair(
529 XcursorImagesLoadCursor(ui::GetXDisplay(), x_images), x_images);
530 // |bitmap| is owned by the resource bundle. So we do not need to free it.
531 }
532
533 // A map to hold all image cursors. It maps the cursor ID to the X Cursor.
534 std::map<int, Cursor> cursors_;
535
536 // A map to hold all animated cursors. It maps the cursor ID to the pair of
537 // the X Cursor and the corresponding XcursorImages. We need a pointer to the
538 // images so that we can free them on destruction.
539 typedef std::map<int, std::pair<Cursor, XcursorImages*> > AnimatedCursorMap;
540 AnimatedCursorMap animated_cursors_;
541
542 float scale_factor_;
543
544 DISALLOW_COPY_AND_ASSIGN(ImageCursors);
545 };
546
547 RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate, 279 RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate,
548 const gfx::Rect& bounds) 280 const gfx::Rect& bounds)
549 : delegate_(delegate), 281 : delegate_(delegate),
550 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), 282 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
551 xwindow_(0), 283 xwindow_(0),
552 x_root_window_(DefaultRootWindow(xdisplay_)), 284 x_root_window_(DefaultRootWindow(xdisplay_)),
553 current_cursor_(ui::kCursorNull), 285 current_cursor_(ui::kCursorNull),
554 window_mapped_(false), 286 window_mapped_(false),
555 cursor_shown_(true), 287 cursor_shown_(true),
556 bounds_(bounds), 288 bounds_(bounds),
557 focus_when_shown_(false), 289 focus_when_shown_(false),
558 pointer_barriers_(NULL), 290 pointer_barriers_(NULL),
559 image_cursors_(new ImageCursors),
560 atom_cache_(xdisplay_, kAtomsToCache) { 291 atom_cache_(xdisplay_, kAtomsToCache) {
561 XSetWindowAttributes swa; 292 XSetWindowAttributes swa;
562 memset(&swa, 0, sizeof(swa)); 293 memset(&swa, 0, sizeof(swa));
563 swa.background_pixmap = None; 294 swa.background_pixmap = None;
564 xwindow_ = XCreateWindow( 295 xwindow_ = XCreateWindow(
565 xdisplay_, x_root_window_, 296 xdisplay_, x_root_window_,
566 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 297 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
567 0, // border width 298 0, // border width
568 CopyFromParent, // depth 299 CopyFromParent, // depth
569 InputOutput, 300 InputOutput,
(...skipping 17 matching lines...) Expand all
587 if (base::MessagePumpForUI::HasXInput2()) 318 if (base::MessagePumpForUI::HasXInput2())
588 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); 319 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
589 320
590 SelectEventsForRootWindow(); 321 SelectEventsForRootWindow();
591 322
592 // Get the initial size of the X root window. 323 // Get the initial size of the X root window.
593 XWindowAttributes attrs; 324 XWindowAttributes attrs;
594 XGetWindowAttributes(xdisplay_, x_root_window_, &attrs); 325 XGetWindowAttributes(xdisplay_, x_root_window_, &attrs);
595 x_root_bounds_.SetRect(attrs.x, attrs.y, attrs.width, attrs.height); 326 x_root_bounds_.SetRect(attrs.x, attrs.y, attrs.width, attrs.height);
596 327
597 // Initialize invisible cursor. 328 invisible_cursor_ = ui::CreateInvisibleCursor();
598 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
599 XColor black;
600 black.red = black.green = black.blue = 0;
601 Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_,
602 nodata, 8, 8);
603 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank,
604 &black, &black, 0, 0);
605 XFreePixmap(xdisplay_, blank);
606
607 if (RootWindow::hide_host_cursor())
608 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_);
609 329
610 // TODO(erg): We currently only request window deletion events. We also 330 // TODO(erg): We currently only request window deletion events. We also
611 // should listen for activation events and anything else that GTK+ listens 331 // should listen for activation events and anything else that GTK+ listens
612 // for, and do something useful. 332 // for, and do something useful.
613 ::Atom protocols[2]; 333 ::Atom protocols[2];
614 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW"); 334 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
615 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING"); 335 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
616 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); 336 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
617 337
618 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with 338 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
(...skipping 22 matching lines...) Expand all
641 } 361 }
642 362
643 RootWindowHostLinux::~RootWindowHostLinux() { 363 RootWindowHostLinux::~RootWindowHostLinux() {
644 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this); 364 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this);
645 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); 365 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
646 366
647 UnConfineCursor(); 367 UnConfineCursor();
648 368
649 XDestroyWindow(xdisplay_, xwindow_); 369 XDestroyWindow(xdisplay_, xwindow_);
650 370
651 // Clears XCursorCache.
652 ui::GetXCursor(ui::kCursorClearXCursorCache);
653
654 XFreeCursor(xdisplay_, invisible_cursor_); 371 XFreeCursor(xdisplay_, invisible_cursor_);
655 } 372 }
656 373
657 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { 374 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
658 XEvent* xev = event; 375 XEvent* xev = event;
659 376
660 CheckXEventForConsistency(xev); 377 CheckXEventForConsistency(xev);
661 378
662 switch (xev->type) { 379 switch (xev->type) {
380 case EnterNotify: {
381 ui::MouseEvent mouseenter_event(xev);
382 delegate_->OnHostMouseEvent(&mouseenter_event);
383 break;
384 }
663 case Expose: 385 case Expose:
664 delegate_->AsRootWindow()->ScheduleFullDraw(); 386 delegate_->AsRootWindow()->ScheduleFullDraw();
665 break; 387 break;
666 case KeyPress: { 388 case KeyPress: {
667 ui::KeyEvent keydown_event(xev, false); 389 ui::KeyEvent keydown_event(xev, false);
668 delegate_->OnHostKeyEvent(&keydown_event); 390 delegate_->OnHostKeyEvent(&keydown_event);
669 break; 391 break;
670 } 392 }
671 case KeyRelease: { 393 case KeyRelease: {
672 ui::KeyEvent keyup_event(xev, false); 394 ui::KeyEvent keyup_event(xev, false);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 622
901 RootWindow* RootWindowHostLinux::GetRootWindow() { 623 RootWindow* RootWindowHostLinux::GetRootWindow() {
902 return delegate_->AsRootWindow(); 624 return delegate_->AsRootWindow();
903 } 625 }
904 626
905 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { 627 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() {
906 return xwindow_; 628 return xwindow_;
907 } 629 }
908 630
909 void RootWindowHostLinux::Show() { 631 void RootWindowHostLinux::Show() {
910 // The device scale factor is now accessible, so load cursors now.
911 image_cursors_->Reload(delegate_->GetDeviceScaleFactor());
912
913 if (!window_mapped_) { 632 if (!window_mapped_) {
914 // Before we map the window, set size hints. Otherwise, some window managers 633 // Before we map the window, set size hints. Otherwise, some window managers
915 // will ignore toplevel XMoveWindow commands. 634 // will ignore toplevel XMoveWindow commands.
916 XSizeHints size_hints; 635 XSizeHints size_hints;
917 size_hints.flags = PPosition; 636 size_hints.flags = PPosition;
918 size_hints.x = bounds_.x(); 637 size_hints.x = bounds_.x();
919 size_hints.y = bounds_.y(); 638 size_hints.y = bounds_.y();
920 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); 639 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
921 640
922 XMapWindow(xdisplay_, xwindow_); 641 XMapWindow(xdisplay_, xwindow_);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 current_cursor_ = cursor; 710 current_cursor_ = cursor;
992 711
993 if (cursor_shown_) 712 if (cursor_shown_)
994 SetCursorInternal(cursor); 713 SetCursorInternal(cursor);
995 } 714 }
996 715
997 void RootWindowHostLinux::ShowCursor(bool show) { 716 void RootWindowHostLinux::ShowCursor(bool show) {
998 if (show == cursor_shown_) 717 if (show == cursor_shown_)
999 return; 718 return;
1000 cursor_shown_ = show; 719 cursor_shown_ = show;
1001 SetCursorInternal(show ? current_cursor_ : ui::kCursorNone); 720 SetCursorInternal(show ? current_cursor_ : invisible_cursor_);
1002 } 721 }
1003 722
1004 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) { 723 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) {
1005 ::Window root_return, child_return; 724 ::Window root_return, child_return;
1006 int root_x_return, root_y_return, win_x_return, win_y_return; 725 int root_x_return, root_y_return, win_x_return, win_y_return;
1007 unsigned int mask_return; 726 unsigned int mask_return;
1008 XQueryPointer(xdisplay_, 727 XQueryPointer(xdisplay_,
1009 xwindow_, 728 xwindow_,
1010 &root_return, 729 &root_return,
1011 &child_return, 730 &child_return,
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 xevent.xmotion.y_root = point.y(); 877 xevent.xmotion.y_root = point.y();
1159 } 878 }
1160 default: 879 default:
1161 break; 880 break;
1162 } 881 }
1163 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); 882 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent);
1164 } 883 }
1165 884
1166 void RootWindowHostLinux::OnDeviceScaleFactorChanged( 885 void RootWindowHostLinux::OnDeviceScaleFactorChanged(
1167 float device_scale_factor) { 886 float device_scale_factor) {
1168 image_cursors_->Reload(device_scale_factor);
1169 } 887 }
1170 888
1171 void RootWindowHostLinux::PrepareForShutdown() { 889 void RootWindowHostLinux::PrepareForShutdown() {
1172 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); 890 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
1173 } 891 }
1174 892
1175 bool RootWindowHostLinux::IsWindowManagerPresent() { 893 bool RootWindowHostLinux::IsWindowManagerPresent() {
1176 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership 894 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
1177 // of WM_Sn selections (where n is a screen number). 895 // of WM_Sn selections (where n is a screen number).
1178 return XGetSelectionOwner( 896 return XGetSelectionOwner(
1179 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; 897 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
1180 } 898 }
1181 899
1182 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { 900 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) {
1183 // At times the cursor on the RootWindow is set before it is displayed. So 901 XDefineCursor(xdisplay_, xwindow_, cursor.platform());
1184 // make sure the image-cursors are initialized properly before setting it.
1185 image_cursors_->Reload(delegate_->GetDeviceScaleFactor());
1186
1187 ::Cursor xcursor;
1188 if (image_cursors_->IsImageCursor(cursor))
1189 xcursor = image_cursors_->ImageCursorFromNative(cursor);
1190 else if (cursor == ui::kCursorNone)
1191 xcursor = invisible_cursor_;
1192 else if (cursor == ui::kCursorCustom)
1193 xcursor = cursor.platform();
1194 else if (delegate_->GetDeviceScaleFactor() == 1.0)
1195 xcursor = ui::GetXCursor(CursorShapeFromNative(cursor));
1196 else
1197 xcursor = image_cursors_->ImageCursorFromNative(ui::kCursorPointer);
1198 XDefineCursor(xdisplay_, xwindow_, xcursor);
1199 } 902 }
1200 903
1201 // static 904 // static
1202 RootWindowHost* RootWindowHost::Create(RootWindowHostDelegate* delegate, 905 RootWindowHost* RootWindowHost::Create(RootWindowHostDelegate* delegate,
1203 const gfx::Rect& bounds) { 906 const gfx::Rect& bounds) {
1204 return new RootWindowHostLinux(delegate, bounds); 907 return new RootWindowHostLinux(delegate, bounds);
1205 } 908 }
1206 909
1207 // static 910 // static
1208 RootWindowHost* RootWindowHost::GetForAcceleratedWidget( 911 RootWindowHost* RootWindowHost::GetForAcceleratedWidget(
1209 gfx::AcceleratedWidget accelerated_widget) { 912 gfx::AcceleratedWidget accelerated_widget) {
1210 return reinterpret_cast<RootWindowHost*>( 913 return reinterpret_cast<RootWindowHost*>(
1211 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); 914 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey));
1212 } 915 }
1213 916
1214 // static 917 // static
1215 gfx::Size RootWindowHost::GetNativeScreenSize() { 918 gfx::Size RootWindowHost::GetNativeScreenSize() {
1216 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); 919 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay();
1217 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 920 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
1218 } 921 }
1219 922
1220 } // namespace aura 923 } // namespace aura
OLDNEW
« no previous file with comments | « ui/aura/root_window_host_linux.h ('k') | ui/aura/root_window_host_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698