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

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: fix tests and 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
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 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__"; 49 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__";
55 50
56 const char* kAtomsToCache[] = { 51 const char* kAtomsToCache[] = {
57 "WM_DELETE_WINDOW", 52 "WM_DELETE_WINDOW",
58 "_NET_WM_PING", 53 "_NET_WM_PING",
59 "_NET_WM_PID", 54 "_NET_WM_PID",
60 "WM_S0", 55 "WM_S0",
61 NULL 56 NULL
62 }; 57 };
63 58
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 CHECK_EQ(slave_event.buttons.mask_len, xievent->buttons.mask_len); 100 CHECK_EQ(slave_event.buttons.mask_len, xievent->buttons.mask_len);
106 CHECK_EQ(slave_event.valuators.mask_len, xievent->valuators.mask_len); 101 CHECK_EQ(slave_event.valuators.mask_len, xievent->valuators.mask_len);
107 CHECK_EQ(slave_event.mods.base, xievent->mods.base); 102 CHECK_EQ(slave_event.mods.base, xievent->mods.base);
108 CHECK_EQ(slave_event.mods.latched, xievent->mods.latched); 103 CHECK_EQ(slave_event.mods.latched, xievent->mods.latched);
109 CHECK_EQ(slave_event.mods.locked, xievent->mods.locked); 104 CHECK_EQ(slave_event.mods.locked, xievent->mods.locked);
110 CHECK_EQ(slave_event.mods.effective, xievent->mods.effective); 105 CHECK_EQ(slave_event.mods.effective, xievent->mods.effective);
111 } 106 }
112 #endif // defined(USE_XI2_MT) && !defined(NDEBUG) 107 #endif // defined(USE_XI2_MT) && !defined(NDEBUG)
113 } 108 }
114 109
115 // Returns X font cursor shape from an Aura cursor.
116 int CursorShapeFromNative(gfx::NativeCursor native_cursor) {
117 switch (native_cursor.native_type()) {
118 case ui::kCursorMiddlePanning:
119 return XC_fleur;
120 case ui::kCursorEastPanning:
121 return XC_sb_right_arrow;
122 case ui::kCursorNorthPanning:
123 return XC_sb_up_arrow;
124 case ui::kCursorNorthEastPanning:
125 return XC_top_right_corner;
126 case ui::kCursorNorthWestPanning:
127 return XC_top_left_corner;
128 case ui::kCursorSouthPanning:
129 return XC_sb_down_arrow;
130 case ui::kCursorSouthEastPanning:
131 return XC_bottom_right_corner;
132 case ui::kCursorSouthWestPanning:
133 return XC_bottom_left_corner;
134 case ui::kCursorWestPanning:
135 return XC_sb_left_arrow;
136 case ui::kCursorNone:
137 // TODO(jamescook): Need cursors for these. crbug.com/111650
138 return XC_left_ptr;
139
140 case ui::kCursorNull:
141 case ui::kCursorPointer:
142 case ui::kCursorNoDrop:
143 case ui::kCursorNotAllowed:
144 case ui::kCursorCopy:
145 case ui::kCursorMove:
146 case ui::kCursorEastResize:
147 case ui::kCursorNorthResize:
148 case ui::kCursorSouthResize:
149 case ui::kCursorWestResize:
150 case ui::kCursorNorthEastResize:
151 case ui::kCursorNorthWestResize:
152 case ui::kCursorSouthWestResize:
153 case ui::kCursorSouthEastResize:
154 case ui::kCursorIBeam:
155 case ui::kCursorAlias:
156 case ui::kCursorCell:
157 case ui::kCursorContextMenu:
158 case ui::kCursorCross:
159 case ui::kCursorHelp:
160 case ui::kCursorWait:
161 case ui::kCursorNorthSouthResize:
162 case ui::kCursorEastWestResize:
163 case ui::kCursorNorthEastSouthWestResize:
164 case ui::kCursorNorthWestSouthEastResize:
165 case ui::kCursorProgress:
166 case ui::kCursorColumnResize:
167 case ui::kCursorRowResize:
168 case ui::kCursorVerticalText:
169 case ui::kCursorZoomIn:
170 case ui::kCursorZoomOut:
171 case ui::kCursorGrab:
172 case ui::kCursorGrabbing:
173 NOTREACHED() << "Cursor (" << native_cursor.native_type() << ") should "
174 << "have an image asset.";
175 return XC_left_ptr;
176 case ui::kCursorCustom:
177 NOTREACHED();
178 return XC_left_ptr;
179 }
180 NOTREACHED();
181 return XC_left_ptr;
182 }
183
184 // Coalesce all pending motion events (touch or mouse) that are at the top of 110 // Coalesce all pending motion events (touch or mouse) that are at the top of
185 // the queue, and return the number eliminated, storing the last one in 111 // the queue, and return the number eliminated, storing the last one in
186 // |last_event|. 112 // |last_event|.
187 int CoalescePendingMotionEvents(const XEvent* xev, XEvent* last_event) { 113 int CoalescePendingMotionEvents(const XEvent* xev, XEvent* last_event) {
188 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); 114 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
189 int num_coalesed = 0; 115 int num_coalesed = 0;
190 Display* display = xev->xany.display; 116 Display* display = xev->xany.display;
191 int event_type = xev->xgeneric.evtype; 117 int event_type = xev->xgeneric.evtype;
192 118
193 #if defined(USE_XI2_MT) 119 #if defined(USE_XI2_MT)
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 case ui::VKEY_OEM_MINUS: 229 case ui::VKEY_OEM_MINUS:
304 case ui::VKEY_OEM_PERIOD: 230 case ui::VKEY_OEM_PERIOD:
305 return true; 231 return true;
306 default: 232 default:
307 return false; 233 return false;
308 } 234 }
309 } 235 }
310 236
311 } // namespace 237 } // namespace
312 238
313 // A utility class that provides X Cursor for NativeCursors for which we have
314 // image resources.
315 class RootWindowHostLinux::ImageCursors {
316 public:
317 ImageCursors() : scale_factor_(0.0) {
318 }
319
320 void Reload(float scale_factor) {
321 if (scale_factor_ == scale_factor)
322 return;
323 scale_factor_ = scale_factor;
324 UnloadAll();
325 // The cursor's hot points are defined in chromeos cursor images at:
326 // http://folder/kuscher/projects/Chrome_OS/Pointers/focuspoint
327 LoadImageCursor(ui::kCursorNull, IDR_AURA_CURSOR_PTR,
328 gfx::Point(4, 4), gfx::Point(8, 9));
329 LoadImageCursor(ui::kCursorPointer, IDR_AURA_CURSOR_PTR,
330 gfx::Point(4, 4), gfx::Point(8, 9));
331 LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP,
332 gfx::Point(4, 4), gfx::Point(8, 9));
333 LoadImageCursor(ui::kCursorNotAllowed, IDR_AURA_CURSOR_NO_DROP,
334 gfx::Point(4, 4), gfx::Point(8, 9));
335 LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY,
336 gfx::Point(4, 4), gfx::Point(8, 9));
337 LoadImageCursor(ui::kCursorHand, IDR_AURA_CURSOR_HAND,
338 gfx::Point(9, 4), gfx::Point(19, 8));
339 LoadImageCursor(ui::kCursorMove, IDR_AURA_CURSOR_MOVE,
340 gfx::Point(11, 11), gfx::Point(23, 23));
341 LoadImageCursor(ui::kCursorNorthEastResize,
342 IDR_AURA_CURSOR_NORTH_EAST_RESIZE,
343 gfx::Point(12, 11), gfx::Point(25, 23));
344 LoadImageCursor(ui::kCursorSouthWestResize,
345 IDR_AURA_CURSOR_SOUTH_WEST_RESIZE,
346 gfx::Point(12, 11), gfx::Point(25, 23));
347 LoadImageCursor(ui::kCursorSouthEastResize,
348 IDR_AURA_CURSOR_SOUTH_EAST_RESIZE,
349 gfx::Point(11, 11), gfx::Point(24, 23));
350 LoadImageCursor(ui::kCursorNorthWestResize,
351 IDR_AURA_CURSOR_NORTH_WEST_RESIZE,
352 gfx::Point(11, 11), gfx::Point(24, 23));
353 LoadImageCursor(ui::kCursorNorthResize, IDR_AURA_CURSOR_NORTH_RESIZE,
354 gfx::Point(11, 12), gfx::Point(23, 23));
355 LoadImageCursor(ui::kCursorSouthResize, IDR_AURA_CURSOR_SOUTH_RESIZE,
356 gfx::Point(11, 12), gfx::Point(23, 23));
357 LoadImageCursor(ui::kCursorEastResize, IDR_AURA_CURSOR_EAST_RESIZE,
358 gfx::Point(12, 11), gfx::Point(25, 23));
359 LoadImageCursor(ui::kCursorWestResize, IDR_AURA_CURSOR_WEST_RESIZE,
360 gfx::Point(12, 11), gfx::Point(25, 23));
361 LoadImageCursor(ui::kCursorIBeam, IDR_AURA_CURSOR_IBEAM,
362 gfx::Point(12, 12), gfx::Point(24, 25));
363 LoadImageCursor(ui::kCursorAlias, IDR_AURA_CURSOR_ALIAS,
364 gfx::Point(8, 6), gfx::Point(15, 11));
365 LoadImageCursor(ui::kCursorCell, IDR_AURA_CURSOR_CELL,
366 gfx::Point(11, 11), gfx::Point(24, 23));
367 LoadImageCursor(ui::kCursorContextMenu, IDR_AURA_CURSOR_CONTEXT_MENU,
368 gfx::Point(4, 4), gfx::Point(8, 9));
369 LoadImageCursor(ui::kCursorCross, IDR_AURA_CURSOR_CROSSHAIR,
370 gfx::Point(12, 12), gfx::Point(25, 23));
371 LoadImageCursor(ui::kCursorHelp, IDR_AURA_CURSOR_HELP,
372 gfx::Point(4, 4), gfx::Point(8, 9));
373 LoadImageCursor(ui::kCursorVerticalText, IDR_AURA_CURSOR_XTERM_HORIZ,
374 gfx::Point(12, 11), gfx::Point(26, 23));
375 LoadImageCursor(ui::kCursorZoomIn, IDR_AURA_CURSOR_ZOOM_IN,
376 gfx::Point(10, 10), gfx::Point(20, 20));
377 LoadImageCursor(ui::kCursorZoomOut, IDR_AURA_CURSOR_ZOOM_OUT,
378 gfx::Point(10, 10), gfx::Point(20, 20));
379 LoadImageCursor(ui::kCursorRowResize, IDR_AURA_CURSOR_ROW_RESIZE,
380 gfx::Point(11, 12), gfx::Point(23, 23));
381 LoadImageCursor(ui::kCursorColumnResize, IDR_AURA_CURSOR_COL_RESIZE,
382 gfx::Point(12, 11), gfx::Point(25, 23));
383 LoadImageCursor(ui::kCursorEastWestResize, IDR_AURA_CURSOR_EAST_WEST_RESIZE,
384 gfx::Point(12, 11), gfx::Point(25, 23));
385 LoadImageCursor(ui::kCursorNorthSouthResize,
386 IDR_AURA_CURSOR_NORTH_SOUTH_RESIZE,
387 gfx::Point(11, 12), gfx::Point(23, 23));
388 LoadImageCursor(ui::kCursorNorthEastSouthWestResize,
389 IDR_AURA_CURSOR_NORTH_EAST_SOUTH_WEST_RESIZE,
390 gfx::Point(12, 11), gfx::Point(25, 23));
391 LoadImageCursor(ui::kCursorNorthWestSouthEastResize,
392 IDR_AURA_CURSOR_NORTH_WEST_SOUTH_EAST_RESIZE,
393 gfx::Point(11, 11), gfx::Point(24, 23));
394 LoadImageCursor(ui::kCursorGrab, IDR_AURA_CURSOR_GRAB,
395 gfx::Point(8, 5), gfx::Point(16, 10));
396 LoadImageCursor(ui::kCursorGrabbing, IDR_AURA_CURSOR_GRABBING,
397 gfx::Point(9, 9), gfx::Point(18, 18));
398 LoadAnimatedCursor(ui::kCursorWait, IDR_THROBBER, 7, 7);
399 LoadAnimatedCursor(ui::kCursorProgress, IDR_THROBBER, 7, 7);
400 }
401
402 ~ImageCursors() {
403 UnloadAll();
404 }
405
406 void UnloadAll() {
407 for (std::map<int, Cursor>::const_iterator it = cursors_.begin();
408 it != cursors_.end(); ++it)
409 ui::UnrefCustomXCursor(it->second);
410
411 // Free animated cursors and images.
412 for (AnimatedCursorMap::iterator it = animated_cursors_.begin();
413 it != animated_cursors_.end(); ++it) {
414 XcursorImagesDestroy(it->second.second); // also frees individual frames.
415 XFreeCursor(ui::GetXDisplay(), it->second.first);
416 }
417 }
418
419 // Returns true if we have an image resource loaded for the |native_cursor|.
420 bool IsImageCursor(gfx::NativeCursor native_cursor) {
421 int type = native_cursor.native_type();
422 return cursors_.find(type) != cursors_.end() ||
423 animated_cursors_.find(type) != animated_cursors_.end();
424 }
425
426 // Gets the X Cursor corresponding to the |native_cursor|.
427 ::Cursor ImageCursorFromNative(gfx::NativeCursor native_cursor) {
428 int type = native_cursor.native_type();
429 if (animated_cursors_.find(type) != animated_cursors_.end())
430 return animated_cursors_[type].first;
431 DCHECK(cursors_.find(type) != cursors_.end());
432 return cursors_[type];
433 }
434
435 private:
436 // Creates an X Cursor from an image resource and puts it in the cursor map.
437 void LoadImageCursor(int id,
438 int resource_id,
439 const gfx::Point& hot_1x,
440 const gfx::Point& hot_2x) {
441 const gfx::ImageSkia* image =
442 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
443 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
444 ui::GetScaleFactorFromScale(scale_factor_));
445 const gfx::Point& hot = (scale_factor_ == 1) ? hot_1x : hot_2x;
446 XcursorImage* x_image =
447 ui::SkBitmapToXcursorImage(&image_rep.sk_bitmap(), hot);
448 cursors_[id] = ui::CreateReffedCustomXCursor(x_image);
449 // |bitmap| is owned by the resource bundle. So we do not need to free it.
450 }
451
452 // Creates an animated X Cursor from an image resource and puts it in the
453 // cursor map. The image is assumed to be a concatenation of animation frames.
454 // Also, each frame is assumed to be square (width == height)
455 void LoadAnimatedCursor(int id, int resource_id, int hot_x, int hot_y) {
456 const gfx::ImageSkia* image =
457 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
458 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
459 ui::GetScaleFactorFromScale(scale_factor_));
460 const SkBitmap bitmap = image_rep.sk_bitmap();
461 DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
462 int frame_width = bitmap.height();
463 int frame_height = frame_width;
464 int total_width = bitmap.width();
465 DCHECK_EQ(total_width % frame_width, 0);
466 int frame_count = total_width / frame_width;
467 DCHECK_GT(frame_count, 0);
468 XcursorImages* x_images = XcursorImagesCreate(frame_count);
469 x_images->nimage = frame_count;
470 bitmap.lockPixels();
471 unsigned int* pixels = bitmap.getAddr32(0, 0);
472 // Create each frame.
473 for (int i = 0; i < frame_count; ++i) {
474 XcursorImage* x_image = XcursorImageCreate(frame_width, frame_height);
475 for (int j = 0; j < frame_height; ++j) {
476 // Copy j'th row of i'th frame.
477 memcpy(x_image->pixels + j * frame_width,
478 pixels + i * frame_width + j * total_width,
479 frame_width * 4);
480 }
481 x_image->xhot = hot_x * scale_factor_;
482 x_image->yhot = hot_y * scale_factor_;
483 x_image->delay = kAnimatedCursorFrameDelayMs;
484 x_images->images[i] = x_image;
485 }
486 bitmap.unlockPixels();
487
488 animated_cursors_[id] = std::make_pair(
489 XcursorImagesLoadCursor(ui::GetXDisplay(), x_images), x_images);
490 // |bitmap| is owned by the resource bundle. So we do not need to free it.
491 }
492
493 // A map to hold all image cursors. It maps the cursor ID to the X Cursor.
494 std::map<int, Cursor> cursors_;
495
496 // A map to hold all animated cursors. It maps the cursor ID to the pair of
497 // the X Cursor and the corresponding XcursorImages. We need a pointer to the
498 // images so that we can free them on destruction.
499 typedef std::map<int, std::pair<Cursor, XcursorImages*> > AnimatedCursorMap;
500 AnimatedCursorMap animated_cursors_;
501
502 float scale_factor_;
503
504 DISALLOW_COPY_AND_ASSIGN(ImageCursors);
505 };
506
507 RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate, 239 RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate,
508 const gfx::Rect& bounds) 240 const gfx::Rect& bounds)
509 : delegate_(delegate), 241 : delegate_(delegate),
510 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), 242 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
511 xwindow_(0), 243 xwindow_(0),
512 x_root_window_(DefaultRootWindow(xdisplay_)), 244 x_root_window_(DefaultRootWindow(xdisplay_)),
513 current_cursor_(ui::kCursorNull), 245 current_cursor_(ui::kCursorNull),
514 window_mapped_(false), 246 window_mapped_(false),
515 cursor_shown_(true), 247 cursor_shown_(true),
516 bounds_(bounds), 248 bounds_(bounds),
517 focus_when_shown_(false), 249 focus_when_shown_(false),
518 pointer_barriers_(NULL), 250 pointer_barriers_(NULL),
519 image_cursors_(new ImageCursors),
520 atom_cache_(xdisplay_, kAtomsToCache) { 251 atom_cache_(xdisplay_, kAtomsToCache) {
521 XSetWindowAttributes swa; 252 XSetWindowAttributes swa;
522 memset(&swa, 0, sizeof(swa)); 253 memset(&swa, 0, sizeof(swa));
523 swa.background_pixmap = None; 254 swa.background_pixmap = None;
524 xwindow_ = XCreateWindow( 255 xwindow_ = XCreateWindow(
525 xdisplay_, x_root_window_, 256 xdisplay_, x_root_window_,
526 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 257 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
527 0, // border width 258 0, // border width
528 CopyFromParent, // depth 259 CopyFromParent, // depth
529 InputOutput, 260 InputOutput,
530 CopyFromParent, // visual 261 CopyFromParent, // visual
531 CWBackPixmap, 262 CWBackPixmap,
532 &swa); 263 &swa);
533 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_); 264 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
534 265
535 prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this)); 266 prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this));
536 267
537 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | 268 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
538 KeyPressMask | KeyReleaseMask | 269 KeyPressMask | KeyReleaseMask |
539 EnterWindowMask | LeaveWindowMask | 270 EnterWindowMask | LeaveWindowMask |
540 ExposureMask | VisibilityChangeMask | 271 ExposureMask | VisibilityChangeMask |
541 StructureNotifyMask | PropertyChangeMask | 272 StructureNotifyMask | PropertyChangeMask |
542 PointerMotionMask; 273 PointerMotionMask;
543 XSelectInput(xdisplay_, xwindow_, event_mask); 274 XSelectInput(xdisplay_, xwindow_, event_mask);
544 XFlush(xdisplay_); 275 XFlush(xdisplay_);
545 276
546 if (base::MessagePumpForUI::HasXInput2()) 277 if (base::MessagePumpForUI::HasXInput2())
547 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); 278 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
548 279
549 // Initialize invisible cursor. 280 invisible_cursor_ = ui::CreateInvisibleCursor();
550 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
551 XColor black;
552 black.red = black.green = black.blue = 0;
553 Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_,
554 nodata, 8, 8);
555 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank,
556 &black, &black, 0, 0);
557 XFreePixmap(xdisplay_, blank);
558
559 if (RootWindow::hide_host_cursor())
560 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_);
561 281
562 // TODO(erg): We currently only request window deletion events. We also 282 // TODO(erg): We currently only request window deletion events. We also
563 // should listen for activation events and anything else that GTK+ listens 283 // should listen for activation events and anything else that GTK+ listens
564 // for, and do something useful. 284 // for, and do something useful.
565 ::Atom protocols[2]; 285 ::Atom protocols[2];
566 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW"); 286 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
567 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING"); 287 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
568 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); 288 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
569 289
570 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with 290 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
(...skipping 21 matching lines...) Expand all
592 RRScreenChangeNotifyMask | RROutputChangeNotifyMask); 312 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
593 } 313 }
594 314
595 RootWindowHostLinux::~RootWindowHostLinux() { 315 RootWindowHostLinux::~RootWindowHostLinux() {
596 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); 316 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
597 317
598 UnConfineCursor(); 318 UnConfineCursor();
599 319
600 XDestroyWindow(xdisplay_, xwindow_); 320 XDestroyWindow(xdisplay_, xwindow_);
601 321
602 // Clears XCursorCache.
603 ui::GetXCursor(ui::kCursorClearXCursorCache);
604
605 XFreeCursor(xdisplay_, invisible_cursor_); 322 XFreeCursor(xdisplay_, invisible_cursor_);
606 } 323 }
607 324
608 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { 325 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
609 XEvent* xev = event; 326 XEvent* xev = event;
610 327
611 CheckXEventForConsistency(xev); 328 CheckXEventForConsistency(xev);
612 329
613 switch (xev->type) { 330 switch (xev->type) {
331 case EnterNotify: {
332 ui::MouseEvent mouseenter_event(xev);
333 delegate_->OnHostMouseEvent(&mouseenter_event);
334 break;
335 }
614 case Expose: 336 case Expose:
615 delegate_->AsRootWindow()->ScheduleFullDraw(); 337 delegate_->AsRootWindow()->ScheduleFullDraw();
616 break; 338 break;
617 case KeyPress: { 339 case KeyPress: {
618 ui::KeyEvent keydown_event(xev, false); 340 ui::KeyEvent keydown_event(xev, false);
619 delegate_->OnHostKeyEvent(&keydown_event); 341 delegate_->OnHostKeyEvent(&keydown_event);
620 break; 342 break;
621 } 343 }
622 case KeyRelease: { 344 case KeyRelease: {
623 ui::KeyEvent keyup_event(xev, false); 345 ui::KeyEvent keyup_event(xev, false);
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 551
830 RootWindow* RootWindowHostLinux::GetRootWindow() { 552 RootWindow* RootWindowHostLinux::GetRootWindow() {
831 return delegate_->AsRootWindow(); 553 return delegate_->AsRootWindow();
832 } 554 }
833 555
834 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { 556 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() {
835 return xwindow_; 557 return xwindow_;
836 } 558 }
837 559
838 void RootWindowHostLinux::Show() { 560 void RootWindowHostLinux::Show() {
839 // The device scale factor is now accessible, so load cursors now.
840 image_cursors_->Reload(delegate_->GetDeviceScaleFactor());
841
842 if (!window_mapped_) { 561 if (!window_mapped_) {
843 // Before we map the window, set size hints. Otherwise, some window managers 562 // Before we map the window, set size hints. Otherwise, some window managers
844 // will ignore toplevel XMoveWindow commands. 563 // will ignore toplevel XMoveWindow commands.
845 XSizeHints size_hints; 564 XSizeHints size_hints;
846 size_hints.flags = PPosition; 565 size_hints.flags = PPosition;
847 size_hints.x = bounds_.x(); 566 size_hints.x = bounds_.x();
848 size_hints.y = bounds_.y(); 567 size_hints.y = bounds_.y();
849 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); 568 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
850 569
851 XMapWindow(xdisplay_, xwindow_); 570 XMapWindow(xdisplay_, xwindow_);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 current_cursor_ = cursor; 639 current_cursor_ = cursor;
921 640
922 if (cursor_shown_) 641 if (cursor_shown_)
923 SetCursorInternal(cursor); 642 SetCursorInternal(cursor);
924 } 643 }
925 644
926 void RootWindowHostLinux::ShowCursor(bool show) { 645 void RootWindowHostLinux::ShowCursor(bool show) {
927 if (show == cursor_shown_) 646 if (show == cursor_shown_)
928 return; 647 return;
929 cursor_shown_ = show; 648 cursor_shown_ = show;
930 SetCursorInternal(show ? current_cursor_ : ui::kCursorNone); 649 SetCursorInternal(show ? current_cursor_ : invisible_cursor_);
931 } 650 }
932 651
933 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) { 652 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) {
934 ::Window root_return, child_return; 653 ::Window root_return, child_return;
935 int root_x_return, root_y_return, win_x_return, win_y_return; 654 int root_x_return, root_y_return, win_x_return, win_y_return;
936 unsigned int mask_return; 655 unsigned int mask_return;
937 XQueryPointer(xdisplay_, 656 XQueryPointer(xdisplay_,
938 xwindow_, 657 xwindow_,
939 &root_return, 658 &root_return,
940 &child_return, 659 &child_return,
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 xevent.xmotion.y_root = point.y(); 806 xevent.xmotion.y_root = point.y();
1088 } 807 }
1089 default: 808 default:
1090 break; 809 break;
1091 } 810 }
1092 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); 811 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent);
1093 } 812 }
1094 813
1095 void RootWindowHostLinux::OnDeviceScaleFactorChanged( 814 void RootWindowHostLinux::OnDeviceScaleFactorChanged(
1096 float device_scale_factor) { 815 float device_scale_factor) {
1097 image_cursors_->Reload(device_scale_factor);
1098 } 816 }
1099 817
1100 bool RootWindowHostLinux::IsWindowManagerPresent() { 818 bool RootWindowHostLinux::IsWindowManagerPresent() {
1101 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership 819 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
1102 // of WM_Sn selections (where n is a screen number). 820 // of WM_Sn selections (where n is a screen number).
1103 return XGetSelectionOwner( 821 return XGetSelectionOwner(
1104 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; 822 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
1105 } 823 }
1106 824
1107 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { 825 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) {
1108 // At times the cursor on the RootWindow is set before it is displayed. So 826 XDefineCursor(xdisplay_, xwindow_, cursor.platform());
1109 // make sure the image-cursors are initialized properly before setting it.
1110 image_cursors_->Reload(delegate_->GetDeviceScaleFactor());
1111
1112 ::Cursor xcursor;
1113 if (image_cursors_->IsImageCursor(cursor))
1114 xcursor = image_cursors_->ImageCursorFromNative(cursor);
1115 else if (cursor == ui::kCursorNone)
1116 xcursor = invisible_cursor_;
1117 else if (cursor == ui::kCursorCustom)
1118 xcursor = cursor.platform();
1119 else if (delegate_->GetDeviceScaleFactor() == 1.0)
1120 xcursor = ui::GetXCursor(CursorShapeFromNative(cursor));
1121 else
1122 xcursor = image_cursors_->ImageCursorFromNative(ui::kCursorPointer);
1123 XDefineCursor(xdisplay_, xwindow_, xcursor);
1124 } 827 }
1125 828
1126 // static 829 // static
1127 RootWindowHost* RootWindowHost::Create(RootWindowHostDelegate* delegate, 830 RootWindowHost* RootWindowHost::Create(RootWindowHostDelegate* delegate,
1128 const gfx::Rect& bounds) { 831 const gfx::Rect& bounds) {
1129 return new RootWindowHostLinux(delegate, bounds); 832 return new RootWindowHostLinux(delegate, bounds);
1130 } 833 }
1131 834
1132 // static 835 // static
1133 RootWindowHost* RootWindowHost::GetForAcceleratedWidget( 836 RootWindowHost* RootWindowHost::GetForAcceleratedWidget(
1134 gfx::AcceleratedWidget accelerated_widget) { 837 gfx::AcceleratedWidget accelerated_widget) {
1135 return reinterpret_cast<RootWindowHost*>( 838 return reinterpret_cast<RootWindowHost*>(
1136 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); 839 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey));
1137 } 840 }
1138 841
1139 // static 842 // static
1140 gfx::Size RootWindowHost::GetNativeScreenSize() { 843 gfx::Size RootWindowHost::GetNativeScreenSize() {
1141 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); 844 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay();
1142 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 845 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
1143 } 846 }
1144 847
1145 } // namespace aura 848 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698