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

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: 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/x11_util.h" 32 #include "ui/base/x/x11_util.h"
34 #include "ui/compositor/layer.h" 33 #include "ui/compositor/layer.h"
35 #include "ui/gfx/codec/png_codec.h" 34 #include "ui/gfx/codec/png_codec.h"
36 #include "ui/gfx/image/image.h"
37 #include "ui/gfx/image/image_skia.h"
38 #include "ui/gfx/screen.h" 35 #include "ui/gfx/screen.h"
39 36
40 using std::max; 37 using std::max;
41 using std::min; 38 using std::min;
42 39
43 namespace aura { 40 namespace aura {
44 41
45 namespace { 42 namespace {
46 43
47 // Standard Linux mouse buttons for going back and forward. 44 // Standard Linux mouse buttons for going back and forward.
48 const int kBackMouseButton = 8; 45 const int kBackMouseButton = 8;
49 const int kForwardMouseButton = 9; 46 const int kForwardMouseButton = 9;
50 47
51 const int kAnimatedCursorFrameDelayMs = 25;
52
53 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__"; 48 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__";
54 49
55 const char* kAtomsToCache[] = { 50 const char* kAtomsToCache[] = {
56 "WM_DELETE_WINDOW", 51 "WM_DELETE_WINDOW",
57 "_NET_WM_PING", 52 "_NET_WM_PING",
58 "_NET_WM_PID", 53 "_NET_WM_PID",
59 "WM_S0", 54 "WM_S0",
60 NULL 55 NULL
61 }; 56 };
62 57
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 CHECK_EQ(slave_event.buttons.mask_len, xievent->buttons.mask_len); 99 CHECK_EQ(slave_event.buttons.mask_len, xievent->buttons.mask_len);
105 CHECK_EQ(slave_event.valuators.mask_len, xievent->valuators.mask_len); 100 CHECK_EQ(slave_event.valuators.mask_len, xievent->valuators.mask_len);
106 CHECK_EQ(slave_event.mods.base, xievent->mods.base); 101 CHECK_EQ(slave_event.mods.base, xievent->mods.base);
107 CHECK_EQ(slave_event.mods.latched, xievent->mods.latched); 102 CHECK_EQ(slave_event.mods.latched, xievent->mods.latched);
108 CHECK_EQ(slave_event.mods.locked, xievent->mods.locked); 103 CHECK_EQ(slave_event.mods.locked, xievent->mods.locked);
109 CHECK_EQ(slave_event.mods.effective, xievent->mods.effective); 104 CHECK_EQ(slave_event.mods.effective, xievent->mods.effective);
110 } 105 }
111 #endif // defined(USE_XI2_MT) && !defined(NDEBUG) 106 #endif // defined(USE_XI2_MT) && !defined(NDEBUG)
112 } 107 }
113 108
114 // Returns X font cursor shape from an Aura cursor.
115 int CursorShapeFromNative(gfx::NativeCursor native_cursor) {
116 switch (native_cursor.native_type()) {
117 case ui::kCursorMiddlePanning:
118 return XC_fleur;
119 case ui::kCursorEastPanning:
120 return XC_sb_right_arrow;
121 case ui::kCursorNorthPanning:
122 return XC_sb_up_arrow;
123 case ui::kCursorNorthEastPanning:
124 return XC_top_right_corner;
125 case ui::kCursorNorthWestPanning:
126 return XC_top_left_corner;
127 case ui::kCursorSouthPanning:
128 return XC_sb_down_arrow;
129 case ui::kCursorSouthEastPanning:
130 return XC_bottom_right_corner;
131 case ui::kCursorSouthWestPanning:
132 return XC_bottom_left_corner;
133 case ui::kCursorWestPanning:
134 return XC_sb_left_arrow;
135 case ui::kCursorNone:
136 // TODO(jamescook): Need cursors for these. crbug.com/111650
137 return XC_left_ptr;
138
139 case ui::kCursorNull:
140 case ui::kCursorPointer:
141 case ui::kCursorNoDrop:
142 case ui::kCursorNotAllowed:
143 case ui::kCursorCopy:
144 case ui::kCursorMove:
145 case ui::kCursorEastResize:
146 case ui::kCursorNorthResize:
147 case ui::kCursorSouthResize:
148 case ui::kCursorWestResize:
149 case ui::kCursorNorthEastResize:
150 case ui::kCursorNorthWestResize:
151 case ui::kCursorSouthWestResize:
152 case ui::kCursorSouthEastResize:
153 case ui::kCursorIBeam:
154 case ui::kCursorAlias:
155 case ui::kCursorCell:
156 case ui::kCursorContextMenu:
157 case ui::kCursorCross:
158 case ui::kCursorHelp:
159 case ui::kCursorWait:
160 case ui::kCursorNorthSouthResize:
161 case ui::kCursorEastWestResize:
162 case ui::kCursorNorthEastSouthWestResize:
163 case ui::kCursorNorthWestSouthEastResize:
164 case ui::kCursorProgress:
165 case ui::kCursorColumnResize:
166 case ui::kCursorRowResize:
167 case ui::kCursorVerticalText:
168 case ui::kCursorZoomIn:
169 case ui::kCursorZoomOut:
170 case ui::kCursorGrab:
171 case ui::kCursorGrabbing:
172 NOTREACHED() << "Cursor (" << native_cursor.native_type() << ") should "
173 << "have an image asset.";
174 return XC_left_ptr;
175 case ui::kCursorCustom:
176 NOTREACHED();
177 return XC_left_ptr;
178 }
179 NOTREACHED();
180 return XC_left_ptr;
181 }
182
183 // Coalesce all pending motion events that are at the top of the queue, and 109 // Coalesce all pending motion events that are at the top of the queue, and
184 // return the number eliminated, storing the last one in |last_event|. 110 // return the number eliminated, storing the last one in |last_event|.
185 int CoalescePendingXIMotionEvents(const XEvent* xev, XEvent* last_event) { 111 int CoalescePendingXIMotionEvents(const XEvent* xev, XEvent* last_event) {
186 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); 112 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
187 int num_coalesed = 0; 113 int num_coalesed = 0;
188 Display* display = xev->xany.display; 114 Display* display = xev->xany.display;
189 115
190 while (XPending(display)) { 116 while (XPending(display)) {
191 XEvent next_event; 117 XEvent next_event;
192 XPeekEvent(display, &next_event); 118 XPeekEvent(display, &next_event);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 case ui::VKEY_OEM_MINUS: 204 case ui::VKEY_OEM_MINUS:
279 case ui::VKEY_OEM_PERIOD: 205 case ui::VKEY_OEM_PERIOD:
280 return true; 206 return true;
281 default: 207 default:
282 return false; 208 return false;
283 } 209 }
284 } 210 }
285 211
286 } // namespace 212 } // namespace
287 213
288 // A utility class that provides X Cursor for NativeCursors for which we have
289 // image resources.
290 class RootWindowHostLinux::ImageCursors {
291 public:
292 ImageCursors() : scale_factor_(0.0) {
293 }
294
295 void Reload(float scale_factor) {
296 if (scale_factor_ == scale_factor)
297 return;
298 scale_factor_ = scale_factor;
299 UnloadAll();
300 // The cursor's hot points are defined in chromeos cursor images at:
301 // http://folder/kuscher/projects/Chrome_OS/Pointers/focuspoint
302 LoadImageCursor(ui::kCursorNull, IDR_AURA_CURSOR_PTR,
303 gfx::Point(4, 4), gfx::Point(8, 9));
304 LoadImageCursor(ui::kCursorPointer, IDR_AURA_CURSOR_PTR,
305 gfx::Point(4, 4), gfx::Point(8, 9));
306 LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP,
307 gfx::Point(4, 4), gfx::Point(8, 9));
308 LoadImageCursor(ui::kCursorNotAllowed, IDR_AURA_CURSOR_NO_DROP,
309 gfx::Point(4, 4), gfx::Point(8, 9));
310 LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY,
311 gfx::Point(4, 4), gfx::Point(8, 9));
312 LoadImageCursor(ui::kCursorHand, IDR_AURA_CURSOR_HAND,
313 gfx::Point(9, 4), gfx::Point(19, 8));
314 LoadImageCursor(ui::kCursorMove, IDR_AURA_CURSOR_MOVE,
315 gfx::Point(11, 11), gfx::Point(23, 23));
316 LoadImageCursor(ui::kCursorNorthEastResize,
317 IDR_AURA_CURSOR_NORTH_EAST_RESIZE,
318 gfx::Point(12, 11), gfx::Point(25, 23));
319 LoadImageCursor(ui::kCursorSouthWestResize,
320 IDR_AURA_CURSOR_SOUTH_WEST_RESIZE,
321 gfx::Point(12, 11), gfx::Point(25, 23));
322 LoadImageCursor(ui::kCursorSouthEastResize,
323 IDR_AURA_CURSOR_SOUTH_EAST_RESIZE,
324 gfx::Point(11, 11), gfx::Point(24, 23));
325 LoadImageCursor(ui::kCursorNorthWestResize,
326 IDR_AURA_CURSOR_NORTH_WEST_RESIZE,
327 gfx::Point(11, 11), gfx::Point(24, 23));
328 LoadImageCursor(ui::kCursorNorthResize, IDR_AURA_CURSOR_NORTH_RESIZE,
329 gfx::Point(11, 12), gfx::Point(23, 23));
330 LoadImageCursor(ui::kCursorSouthResize, IDR_AURA_CURSOR_SOUTH_RESIZE,
331 gfx::Point(11, 12), gfx::Point(23, 23));
332 LoadImageCursor(ui::kCursorEastResize, IDR_AURA_CURSOR_EAST_RESIZE,
333 gfx::Point(12, 11), gfx::Point(25, 23));
334 LoadImageCursor(ui::kCursorWestResize, IDR_AURA_CURSOR_WEST_RESIZE,
335 gfx::Point(12, 11), gfx::Point(25, 23));
336 LoadImageCursor(ui::kCursorIBeam, IDR_AURA_CURSOR_IBEAM,
337 gfx::Point(12, 12), gfx::Point(24, 25));
338 LoadImageCursor(ui::kCursorAlias, IDR_AURA_CURSOR_ALIAS,
339 gfx::Point(8, 6), gfx::Point(15, 11));
340 LoadImageCursor(ui::kCursorCell, IDR_AURA_CURSOR_CELL,
341 gfx::Point(11, 11), gfx::Point(24, 23));
342 LoadImageCursor(ui::kCursorContextMenu, IDR_AURA_CURSOR_CONTEXT_MENU,
343 gfx::Point(4, 4), gfx::Point(8, 9));
344 LoadImageCursor(ui::kCursorCross, IDR_AURA_CURSOR_CROSSHAIR,
345 gfx::Point(12, 12), gfx::Point(25, 23));
346 LoadImageCursor(ui::kCursorHelp, IDR_AURA_CURSOR_HELP,
347 gfx::Point(4, 4), gfx::Point(8, 9));
348 LoadImageCursor(ui::kCursorVerticalText, IDR_AURA_CURSOR_XTERM_HORIZ,
349 gfx::Point(12, 11), gfx::Point(26, 23));
350 LoadImageCursor(ui::kCursorZoomIn, IDR_AURA_CURSOR_ZOOM_IN,
351 gfx::Point(10, 10), gfx::Point(20, 20));
352 LoadImageCursor(ui::kCursorZoomOut, IDR_AURA_CURSOR_ZOOM_OUT,
353 gfx::Point(10, 10), gfx::Point(20, 20));
354 LoadImageCursor(ui::kCursorRowResize, IDR_AURA_CURSOR_ROW_RESIZE,
355 gfx::Point(11, 12), gfx::Point(23, 23));
356 LoadImageCursor(ui::kCursorColumnResize, IDR_AURA_CURSOR_COL_RESIZE,
357 gfx::Point(12, 11), gfx::Point(25, 23));
358 LoadImageCursor(ui::kCursorEastWestResize, IDR_AURA_CURSOR_EAST_WEST_RESIZE,
359 gfx::Point(12, 11), gfx::Point(25, 23));
360 LoadImageCursor(ui::kCursorNorthSouthResize,
361 IDR_AURA_CURSOR_NORTH_SOUTH_RESIZE,
362 gfx::Point(11, 12), gfx::Point(23, 23));
363 LoadImageCursor(ui::kCursorNorthEastSouthWestResize,
364 IDR_AURA_CURSOR_NORTH_EAST_SOUTH_WEST_RESIZE,
365 gfx::Point(12, 11), gfx::Point(25, 23));
366 LoadImageCursor(ui::kCursorNorthWestSouthEastResize,
367 IDR_AURA_CURSOR_NORTH_WEST_SOUTH_EAST_RESIZE,
368 gfx::Point(11, 11), gfx::Point(24, 23));
369 LoadImageCursor(ui::kCursorGrab, IDR_AURA_CURSOR_GRAB,
370 gfx::Point(8, 5), gfx::Point(16, 10));
371 LoadImageCursor(ui::kCursorGrabbing, IDR_AURA_CURSOR_GRABBING,
372 gfx::Point(9, 9), gfx::Point(18, 18));
373 LoadAnimatedCursor(ui::kCursorWait, IDR_THROBBER, 7, 7);
374 LoadAnimatedCursor(ui::kCursorProgress, IDR_THROBBER, 7, 7);
375 }
376
377 ~ImageCursors() {
378 UnloadAll();
379 }
380
381 void UnloadAll() {
382 for (std::map<int, Cursor>::const_iterator it = cursors_.begin();
383 it != cursors_.end(); ++it)
384 ui::UnrefCustomXCursor(it->second);
385
386 // Free animated cursors and images.
387 for (AnimatedCursorMap::iterator it = animated_cursors_.begin();
388 it != animated_cursors_.end(); ++it) {
389 XcursorImagesDestroy(it->second.second); // also frees individual frames.
390 XFreeCursor(ui::GetXDisplay(), it->second.first);
391 }
392 }
393
394 // Returns true if we have an image resource loaded for the |native_cursor|.
395 bool IsImageCursor(gfx::NativeCursor native_cursor) {
396 int type = native_cursor.native_type();
397 return cursors_.find(type) != cursors_.end() ||
398 animated_cursors_.find(type) != animated_cursors_.end();
399 }
400
401 // Gets the X Cursor corresponding to the |native_cursor|.
402 ::Cursor ImageCursorFromNative(gfx::NativeCursor native_cursor) {
403 int type = native_cursor.native_type();
404 if (animated_cursors_.find(type) != animated_cursors_.end())
405 return animated_cursors_[type].first;
406 DCHECK(cursors_.find(type) != cursors_.end());
407 return cursors_[type];
408 }
409
410 private:
411 // Creates an X Cursor from an image resource and puts it in the cursor map.
412 void LoadImageCursor(int id,
413 int resource_id,
414 const gfx::Point& hot_1x,
415 const gfx::Point& hot_2x) {
416 const gfx::ImageSkia* image =
417 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
418 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
419 ui::GetScaleFactorFromScale(scale_factor_));
420 const gfx::Point& hot = (scale_factor_ == 1) ? hot_1x : hot_2x;
421 XcursorImage* x_image =
422 ui::SkBitmapToXcursorImage(&image_rep.sk_bitmap(), hot);
423 cursors_[id] = ui::CreateReffedCustomXCursor(x_image);
424 // |bitmap| is owned by the resource bundle. So we do not need to free it.
425 }
426
427 // Creates an animated X Cursor from an image resource and puts it in the
428 // cursor map. The image is assumed to be a concatenation of animation frames.
429 // Also, each frame is assumed to be square (width == height)
430 void LoadAnimatedCursor(int id, int resource_id, int hot_x, int hot_y) {
431 const gfx::ImageSkia* image =
432 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
433 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
434 ui::GetScaleFactorFromScale(scale_factor_));
435 const SkBitmap bitmap = image_rep.sk_bitmap();
436 DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
437 int frame_width = bitmap.height();
438 int frame_height = frame_width;
439 int total_width = bitmap.width();
440 DCHECK_EQ(total_width % frame_width, 0);
441 int frame_count = total_width / frame_width;
442 DCHECK_GT(frame_count, 0);
443 XcursorImages* x_images = XcursorImagesCreate(frame_count);
444 x_images->nimage = frame_count;
445 bitmap.lockPixels();
446 unsigned int* pixels = bitmap.getAddr32(0, 0);
447 // Create each frame.
448 for (int i = 0; i < frame_count; ++i) {
449 XcursorImage* x_image = XcursorImageCreate(frame_width, frame_height);
450 for (int j = 0; j < frame_height; ++j) {
451 // Copy j'th row of i'th frame.
452 memcpy(x_image->pixels + j * frame_width,
453 pixels + i * frame_width + j * total_width,
454 frame_width * 4);
455 }
456 x_image->xhot = hot_x * scale_factor_;
457 x_image->yhot = hot_y * scale_factor_;
458 x_image->delay = kAnimatedCursorFrameDelayMs;
459 x_images->images[i] = x_image;
460 }
461 bitmap.unlockPixels();
462
463 animated_cursors_[id] = std::make_pair(
464 XcursorImagesLoadCursor(ui::GetXDisplay(), x_images), x_images);
465 // |bitmap| is owned by the resource bundle. So we do not need to free it.
466 }
467
468 // A map to hold all image cursors. It maps the cursor ID to the X Cursor.
469 std::map<int, Cursor> cursors_;
470
471 // A map to hold all animated cursors. It maps the cursor ID to the pair of
472 // the X Cursor and the corresponding XcursorImages. We need a pointer to the
473 // images so that we can free them on destruction.
474 typedef std::map<int, std::pair<Cursor, XcursorImages*> > AnimatedCursorMap;
475 AnimatedCursorMap animated_cursors_;
476
477 float scale_factor_;
478
479 DISALLOW_COPY_AND_ASSIGN(ImageCursors);
480 };
481
482 RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate, 214 RootWindowHostLinux::RootWindowHostLinux(RootWindowHostDelegate* delegate,
483 const gfx::Rect& bounds) 215 const gfx::Rect& bounds)
484 : delegate_(delegate), 216 : delegate_(delegate),
485 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), 217 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
486 xwindow_(0), 218 xwindow_(0),
487 x_root_window_(DefaultRootWindow(xdisplay_)), 219 x_root_window_(DefaultRootWindow(xdisplay_)),
488 current_cursor_(ui::kCursorNull), 220 current_cursor_(ui::kCursorNull),
489 window_mapped_(false), 221 window_mapped_(false),
490 cursor_shown_(true), 222 cursor_shown_(true),
491 bounds_(bounds), 223 bounds_(bounds),
492 focus_when_shown_(false), 224 focus_when_shown_(false),
493 pointer_barriers_(NULL), 225 pointer_barriers_(NULL),
494 image_cursors_(new ImageCursors),
495 atom_cache_(xdisplay_, kAtomsToCache) { 226 atom_cache_(xdisplay_, kAtomsToCache) {
496 XSetWindowAttributes swa; 227 XSetWindowAttributes swa;
497 memset(&swa, 0, sizeof(swa)); 228 memset(&swa, 0, sizeof(swa));
498 swa.background_pixmap = None; 229 swa.background_pixmap = None;
499 xwindow_ = XCreateWindow( 230 xwindow_ = XCreateWindow(
500 xdisplay_, x_root_window_, 231 xdisplay_, x_root_window_,
501 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 232 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
502 0, // border width 233 0, // border width
503 CopyFromParent, // depth 234 CopyFromParent, // depth
504 InputOutput, 235 InputOutput,
505 CopyFromParent, // visual 236 CopyFromParent, // visual
506 CWBackPixmap, 237 CWBackPixmap,
507 &swa); 238 &swa);
508 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_); 239 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
509 240
510 prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this)); 241 prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this));
511 242
512 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | 243 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
513 KeyPressMask | KeyReleaseMask | 244 KeyPressMask | KeyReleaseMask |
514 EnterWindowMask | LeaveWindowMask | 245 EnterWindowMask | LeaveWindowMask |
515 ExposureMask | VisibilityChangeMask | 246 ExposureMask | VisibilityChangeMask |
516 StructureNotifyMask | PropertyChangeMask | 247 StructureNotifyMask | PropertyChangeMask |
517 PointerMotionMask; 248 PointerMotionMask;
518 XSelectInput(xdisplay_, xwindow_, event_mask); 249 XSelectInput(xdisplay_, xwindow_, event_mask);
519 XFlush(xdisplay_); 250 XFlush(xdisplay_);
520 251
521 if (base::MessagePumpForUI::HasXInput2()) 252 if (base::MessagePumpForUI::HasXInput2())
522 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); 253 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
523 254
524 // Initialize invisible cursor.
525 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
526 XColor black;
527 black.red = black.green = black.blue = 0;
528 Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_,
529 nodata, 8, 8);
530 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank,
531 &black, &black, 0, 0);
532 XFreePixmap(xdisplay_, blank);
533
534 if (RootWindow::hide_host_cursor())
535 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_);
536
537 // TODO(erg): We currently only request window deletion events. We also 255 // TODO(erg): We currently only request window deletion events. We also
538 // should listen for activation events and anything else that GTK+ listens 256 // should listen for activation events and anything else that GTK+ listens
539 // for, and do something useful. 257 // for, and do something useful.
540 ::Atom protocols[2]; 258 ::Atom protocols[2];
541 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW"); 259 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
542 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING"); 260 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
543 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); 261 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
544 262
545 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with 263 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
546 // the desktop environment. 264 // the desktop environment.
(...skipping 19 matching lines...) Expand all
566 XRRSelectInput(xdisplay_, x_root_window_, 284 XRRSelectInput(xdisplay_, x_root_window_,
567 RRScreenChangeNotifyMask | RROutputChangeNotifyMask); 285 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
568 } 286 }
569 287
570 RootWindowHostLinux::~RootWindowHostLinux() { 288 RootWindowHostLinux::~RootWindowHostLinux() {
571 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); 289 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
572 290
573 UnConfineCursor(); 291 UnConfineCursor();
574 292
575 XDestroyWindow(xdisplay_, xwindow_); 293 XDestroyWindow(xdisplay_, xwindow_);
576
577 // Clears XCursorCache.
578 ui::GetXCursor(ui::kCursorClearXCursorCache);
579
580 XFreeCursor(xdisplay_, invisible_cursor_);
581 } 294 }
582 295
583 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { 296 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
584 XEvent* xev = event; 297 XEvent* xev = event;
585 298
586 CheckXEventForConsistency(xev); 299 CheckXEventForConsistency(xev);
587 300
588 switch (xev->type) { 301 switch (xev->type) {
589 case Expose: 302 case Expose:
590 delegate_->AsRootWindow()->ScheduleFullDraw(); 303 delegate_->AsRootWindow()->ScheduleFullDraw();
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 513
801 RootWindow* RootWindowHostLinux::GetRootWindow() { 514 RootWindow* RootWindowHostLinux::GetRootWindow() {
802 return delegate_->AsRootWindow(); 515 return delegate_->AsRootWindow();
803 } 516 }
804 517
805 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { 518 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() {
806 return xwindow_; 519 return xwindow_;
807 } 520 }
808 521
809 void RootWindowHostLinux::Show() { 522 void RootWindowHostLinux::Show() {
810 // The device scale factor is now accessible, so load cursors now.
811 image_cursors_->Reload(delegate_->GetDeviceScaleFactor());
812
813 if (!window_mapped_) { 523 if (!window_mapped_) {
814 // Before we map the window, set size hints. Otherwise, some window managers 524 // Before we map the window, set size hints. Otherwise, some window managers
815 // will ignore toplevel XMoveWindow commands. 525 // will ignore toplevel XMoveWindow commands.
816 XSizeHints size_hints; 526 XSizeHints size_hints;
817 size_hints.flags = PPosition; 527 size_hints.flags = PPosition;
818 size_hints.x = bounds_.x(); 528 size_hints.x = bounds_.x();
819 size_hints.y = bounds_.y(); 529 size_hints.y = bounds_.y();
820 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); 530 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
821 531
822 XMapWindow(xdisplay_, xwindow_); 532 XMapWindow(xdisplay_, xwindow_);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 current_cursor_ = cursor; 601 current_cursor_ = cursor;
892 602
893 if (cursor_shown_) 603 if (cursor_shown_)
894 SetCursorInternal(cursor); 604 SetCursorInternal(cursor);
895 } 605 }
896 606
897 void RootWindowHostLinux::ShowCursor(bool show) { 607 void RootWindowHostLinux::ShowCursor(bool show) {
898 if (show == cursor_shown_) 608 if (show == cursor_shown_)
899 return; 609 return;
900 cursor_shown_ = show; 610 cursor_shown_ = show;
901 SetCursorInternal(show ? current_cursor_ : ui::kCursorNone); 611 client::CursorClient* cursor_client =
612 client::GetCursorClient(GetRootWindow());
613 if (cursor_client)
614 cursor_client->SetCursor(show ? current_cursor_ : ui::kCursorNone);
902 } 615 }
903 616
904 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) { 617 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) {
905 ::Window root_return, child_return; 618 ::Window root_return, child_return;
906 int root_x_return, root_y_return, win_x_return, win_y_return; 619 int root_x_return, root_y_return, win_x_return, win_y_return;
907 unsigned int mask_return; 620 unsigned int mask_return;
908 XQueryPointer(xdisplay_, 621 XQueryPointer(xdisplay_,
909 xwindow_, 622 xwindow_,
910 &root_return, 623 &root_return,
911 &child_return, 624 &child_return,
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 xevent.xmotion.y_root = point.y(); 771 xevent.xmotion.y_root = point.y();
1059 } 772 }
1060 default: 773 default:
1061 break; 774 break;
1062 } 775 }
1063 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); 776 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent);
1064 } 777 }
1065 778
1066 void RootWindowHostLinux::OnDeviceScaleFactorChanged( 779 void RootWindowHostLinux::OnDeviceScaleFactorChanged(
1067 float device_scale_factor) { 780 float device_scale_factor) {
1068 image_cursors_->Reload(device_scale_factor);
1069 } 781 }
1070 782
1071 bool RootWindowHostLinux::IsWindowManagerPresent() { 783 bool RootWindowHostLinux::IsWindowManagerPresent() {
1072 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership 784 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
1073 // of WM_Sn selections (where n is a screen number). 785 // of WM_Sn selections (where n is a screen number).
1074 return XGetSelectionOwner( 786 return XGetSelectionOwner(
1075 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; 787 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
1076 } 788 }
1077 789
1078 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { 790 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) {
1079 // At times the cursor on the RootWindow is set before it is displayed. So 791 XDefineCursor(xdisplay_, xwindow_, cursor.platform());
1080 // make sure the image-cursors are initialized properly before setting it.
1081 image_cursors_->Reload(delegate_->GetDeviceScaleFactor());
1082
1083 ::Cursor xcursor;
1084 if (image_cursors_->IsImageCursor(cursor))
1085 xcursor = image_cursors_->ImageCursorFromNative(cursor);
1086 else if (cursor == ui::kCursorNone)
1087 xcursor = invisible_cursor_;
1088 else if (cursor == ui::kCursorCustom)
1089 xcursor = cursor.platform();
1090 else if (delegate_->GetDeviceScaleFactor() == 1.0)
1091 xcursor = ui::GetXCursor(CursorShapeFromNative(cursor));
1092 else
1093 xcursor = image_cursors_->ImageCursorFromNative(ui::kCursorPointer);
1094 XDefineCursor(xdisplay_, xwindow_, xcursor);
1095 } 792 }
1096 793
1097 // static 794 // static
1098 RootWindowHost* RootWindowHost::Create(RootWindowHostDelegate* delegate, 795 RootWindowHost* RootWindowHost::Create(RootWindowHostDelegate* delegate,
1099 const gfx::Rect& bounds) { 796 const gfx::Rect& bounds) {
1100 return new RootWindowHostLinux(delegate, bounds); 797 return new RootWindowHostLinux(delegate, bounds);
1101 } 798 }
1102 799
1103 // static 800 // static
1104 RootWindowHost* RootWindowHost::GetForAcceleratedWidget( 801 RootWindowHost* RootWindowHost::GetForAcceleratedWidget(
1105 gfx::AcceleratedWidget accelerated_widget) { 802 gfx::AcceleratedWidget accelerated_widget) {
1106 return reinterpret_cast<RootWindowHost*>( 803 return reinterpret_cast<RootWindowHost*>(
1107 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); 804 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey));
1108 } 805 }
1109 806
1110 // static 807 // static
1111 gfx::Size RootWindowHost::GetNativeScreenSize() { 808 gfx::Size RootWindowHost::GetNativeScreenSize() {
1112 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); 809 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay();
1113 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 810 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
1114 } 811 }
1115 812
1116 } // namespace aura 813 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698