OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/desktop_host.h" | 5 #include "ui/aura/desktop_host.h" |
6 | 6 |
7 #include <X11/cursorfont.h> | 7 #include <X11/cursorfont.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 | 9 |
10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. | 10 // Get rid of a macro from Xlib.h that conflicts with Aura's RootWindow class. |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
234 // DesktopHost Overrides. | 234 // DesktopHost Overrides. |
235 virtual void SetDesktop(Desktop* desktop) OVERRIDE; | 235 virtual void SetDesktop(Desktop* desktop) OVERRIDE; |
236 virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; | 236 virtual gfx::AcceleratedWidget GetAcceleratedWidget() OVERRIDE; |
237 virtual void Show() OVERRIDE; | 237 virtual void Show() OVERRIDE; |
238 virtual void ToggleFullScreen() OVERRIDE; | 238 virtual void ToggleFullScreen() OVERRIDE; |
239 virtual gfx::Size GetSize() const OVERRIDE; | 239 virtual gfx::Size GetSize() const OVERRIDE; |
240 virtual void SetSize(const gfx::Size& size) OVERRIDE; | 240 virtual void SetSize(const gfx::Size& size) OVERRIDE; |
241 virtual void SetCursor(gfx::NativeCursor cursor_type) OVERRIDE; | 241 virtual void SetCursor(gfx::NativeCursor cursor_type) OVERRIDE; |
242 virtual gfx::Point QueryMouseLocation() OVERRIDE; | 242 virtual gfx::Point QueryMouseLocation() OVERRIDE; |
243 virtual void PostNativeEvent(const base::NativeEvent& event) OVERRIDE; | 243 virtual void PostNativeEvent(const base::NativeEvent& event) OVERRIDE; |
244 virtual void ConvertPointToNativeScreen(gfx::Point* point) const OVERRIDE; | |
244 | 245 |
245 // Returns true if there's an X window manager present... in most cases. Some | 246 // Returns true if there's an X window manager present... in most cases. Some |
246 // window managers (notably, ion3) don't implement enough of ICCCM for us to | 247 // window managers (notably, ion3) don't implement enough of ICCCM for us to |
247 // detect that they're there. | 248 // detect that they're there. |
248 bool IsWindowManagerPresent(); | 249 bool IsWindowManagerPresent(); |
249 | 250 |
250 Desktop* desktop_; | 251 Desktop* desktop_; |
251 | 252 |
252 // The display and the native X window hosting the desktop. | 253 // The display and the native X window hosting the desktop. |
253 Display* xdisplay_; | 254 Display* xdisplay_; |
254 ::Window xwindow_; | 255 ::Window xwindow_; |
255 | 256 |
256 // Current Aura cursor. | 257 // Current Aura cursor. |
257 gfx::NativeCursor current_cursor_; | 258 gfx::NativeCursor current_cursor_; |
258 | 259 |
259 // The size of |xwindow_|. | 260 // The bounds of |xwindow_|. |
260 gfx::Size size_; | 261 gfx::Rect bounds_; |
261 | 262 |
262 DISALLOW_COPY_AND_ASSIGN(DesktopHostLinux); | 263 DISALLOW_COPY_AND_ASSIGN(DesktopHostLinux); |
263 }; | 264 }; |
264 | 265 |
265 DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) | 266 DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) |
266 : desktop_(NULL), | 267 : desktop_(NULL), |
267 xdisplay_(base::MessagePumpX::GetDefaultXDisplay()), | 268 xdisplay_(base::MessagePumpX::GetDefaultXDisplay()), |
268 xwindow_(0), | 269 xwindow_(0), |
269 current_cursor_(aura::kCursorNull), | 270 current_cursor_(aura::kCursorNull), |
270 size_(bounds.size()) { | 271 bounds_(bounds) { |
271 xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_), | 272 xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_), |
272 bounds.x(), bounds.y(), | 273 bounds.x(), bounds.y(), |
273 bounds.width(), bounds.height(), | 274 bounds.width(), bounds.height(), |
274 0, 0, 0); | 275 0, 0, 0); |
275 | 276 |
276 long event_mask = ButtonPressMask | ButtonReleaseMask | | 277 long event_mask = ButtonPressMask | ButtonReleaseMask | |
277 KeyPressMask | KeyReleaseMask | | 278 KeyPressMask | KeyReleaseMask | |
278 ExposureMask | VisibilityChangeMask | | 279 ExposureMask | VisibilityChangeMask | |
279 StructureNotifyMask | PropertyChangeMask | | 280 StructureNotifyMask | PropertyChangeMask | |
280 PointerMotionMask; | 281 PointerMotionMask; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 break; | 325 break; |
325 } | 326 } |
326 case ConfigureNotify: { | 327 case ConfigureNotify: { |
327 DCHECK_EQ(xdisplay_, xev->xconfigure.display); | 328 DCHECK_EQ(xdisplay_, xev->xconfigure.display); |
328 DCHECK_EQ(xwindow_, xev->xconfigure.window); | 329 DCHECK_EQ(xwindow_, xev->xconfigure.window); |
329 DCHECK_EQ(xwindow_, xev->xconfigure.event); | 330 DCHECK_EQ(xwindow_, xev->xconfigure.event); |
330 | 331 |
331 // It's possible that the X window may be resized by some other means than | 332 // It's possible that the X window may be resized by some other means than |
332 // from within aura (e.g. the X window manager can change the size). Make | 333 // from within aura (e.g. the X window manager can change the size). Make |
333 // sure the desktop size is maintained properly. | 334 // sure the desktop size is maintained properly. |
334 gfx::Size size(xev->xconfigure.width, xev->xconfigure.height); | 335 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, |
335 if (size_ != size) { | 336 xev->xconfigure.width, xev->xconfigure.height); |
336 size_ = size; | 337 bool size_changed = bounds_.size() != bounds.size(); |
337 desktop_->OnHostResized(size); | 338 bounds_ = bounds; |
338 } | 339 if (size_changed) |
340 desktop_->OnHostResized(bounds.size()); | |
339 handled = true; | 341 handled = true; |
340 break; | 342 break; |
341 } | 343 } |
342 case GenericEvent: { | 344 case GenericEvent: { |
343 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | 345 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
344 if (!factory->ShouldProcessXI2Event(xev)) | 346 if (!factory->ShouldProcessXI2Event(xev)) |
345 break; | 347 break; |
346 | 348 |
347 // If this is a motion event we want to coalesce all pending motion | 349 // If this is a motion event we want to coalesce all pending motion |
348 // events that are at the top of the queue. | 350 // events that are at the top of the queue. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 | 432 |
431 void DesktopHostLinux::Show() { | 433 void DesktopHostLinux::Show() { |
432 XMapWindow(xdisplay_, xwindow_); | 434 XMapWindow(xdisplay_, xwindow_); |
433 } | 435 } |
434 | 436 |
435 void DesktopHostLinux::ToggleFullScreen() { | 437 void DesktopHostLinux::ToggleFullScreen() { |
436 NOTIMPLEMENTED(); | 438 NOTIMPLEMENTED(); |
437 } | 439 } |
438 | 440 |
439 gfx::Size DesktopHostLinux::GetSize() const { | 441 gfx::Size DesktopHostLinux::GetSize() const { |
440 return size_; | 442 return bounds_.size(); |
441 } | 443 } |
442 | 444 |
443 void DesktopHostLinux::SetSize(const gfx::Size& size) { | 445 void DesktopHostLinux::SetSize(const gfx::Size& size) { |
444 if (size == size_) | 446 if (size == bounds_.size()) |
445 return; | 447 return; |
446 | 448 |
447 XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); | 449 XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); |
448 | 450 |
449 // Assume that the resize will go through as requested, which should be the | 451 // Assume that the resize will go through as requested, which should be the |
450 // case if we're running without a window manager. If there's a window | 452 // case if we're running without a window manager. If there's a window |
451 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a | 453 // manager, it can modify or ignore the request, but (per ICCCM) we'll get a |
452 // (possibly synthetic) ConfigureNotify about the actual size and correct | 454 // (possibly synthetic) ConfigureNotify about the actual size and correct |
453 // |size_| later. | 455 // |bounds_| later. |
454 size_ = size; | 456 bounds_.set_size(size); |
455 desktop_->OnHostResized(size); | 457 desktop_->OnHostResized(size); |
456 } | 458 } |
457 | 459 |
458 void DesktopHostLinux::SetCursor(gfx::NativeCursor cursor) { | 460 void DesktopHostLinux::SetCursor(gfx::NativeCursor cursor) { |
459 if (current_cursor_ == cursor) | 461 if (current_cursor_ == cursor) |
460 return; | 462 return; |
461 current_cursor_ = cursor; | 463 current_cursor_ = cursor; |
462 // Custom web cursors are handled directly. | 464 // Custom web cursors are handled directly. |
463 if (cursor == kCursorCustom) | 465 if (cursor == kCursorCustom) |
464 return; | 466 return; |
465 int cursor_shape = CursorShapeFromNative(cursor); | 467 int cursor_shape = CursorShapeFromNative(cursor); |
466 ::Cursor xcursor = ui::GetXCursor(cursor_shape); | 468 ::Cursor xcursor = ui::GetXCursor(cursor_shape); |
467 XDefineCursor(xdisplay_, xwindow_, xcursor); | 469 XDefineCursor(xdisplay_, xwindow_, xcursor); |
468 } | 470 } |
469 | 471 |
470 gfx::Point DesktopHostLinux::QueryMouseLocation() { | 472 gfx::Point DesktopHostLinux::QueryMouseLocation() { |
471 ::Window root_return, child_return; | 473 ::Window root_return, child_return; |
472 int root_x_return, root_y_return, win_x_return, win_y_return; | 474 int root_x_return, root_y_return, win_x_return, win_y_return; |
473 unsigned int mask_return; | 475 unsigned int mask_return; |
474 XQueryPointer(xdisplay_, | 476 XQueryPointer(xdisplay_, |
475 xwindow_, | 477 xwindow_, |
476 &root_return, | 478 &root_return, |
477 &child_return, | 479 &child_return, |
478 &root_x_return, &root_y_return, | 480 &root_x_return, &root_y_return, |
479 &win_x_return, &win_y_return, | 481 &win_x_return, &win_y_return, |
480 &mask_return); | 482 &mask_return); |
481 return gfx::Point(max(0, min(size_.width(), win_x_return)), | 483 return gfx::Point(max(0, min(bounds_.width(), win_x_return)), |
482 max(0, min(size_.height(), win_y_return))); | 484 max(0, min(bounds_.height(), win_y_return))); |
485 } | |
486 | |
487 void DesktopHostLinux::ConvertPointToNativeScreen(gfx::Point* point) const { | |
488 point->Offset(bounds_.x(), bounds_.y()); | |
483 } | 489 } |
484 | 490 |
485 void DesktopHostLinux::PostNativeEvent(const base::NativeEvent& native_event) { | 491 void DesktopHostLinux::PostNativeEvent(const base::NativeEvent& native_event) { |
492 const long kInputEventMask = KeyReleaseMask | KeyPressMask | | |
493 PointerMotionMask | ButtonPressMask | ButtonReleaseMask; | |
486 DCHECK(xwindow_); | 494 DCHECK(xwindow_); |
487 DCHECK(xdisplay_); | 495 DCHECK(xdisplay_); |
488 XEvent xevent = *native_event; | 496 XEvent xevent = *native_event; |
489 xevent.xany.display = xdisplay_; | 497 xevent.xany.display = xdisplay_; |
490 xevent.xany.window = xwindow_; | 498 xevent.xany.window = xwindow_; |
491 ::XPutBackEvent(xdisplay_, &xevent); | 499 |
500 switch (xevent.type) { | |
501 case MotionNotify: | |
502 case KeyPress: | |
503 case KeyRelease: | |
504 case ButtonPress: | |
505 case ButtonRelease: { | |
Daniel Erat
2011/11/22 00:25:32
i know that we don't do anything with them (now),
oshima
2011/11/22 01:36:10
Because X's Enter/Leave notify doesn't trigger aur
Daniel Erat
2011/11/22 01:46:14
They could get added to aura later, and things wou
oshima
2011/11/22 03:02:09
I just couldn't imagine how this will be needed. O
| |
506 xevent.xmotion.root = DefaultRootWindow(xdisplay_); | |
Daniel Erat
2011/11/22 00:25:32
maybe add a comment mentioning that you're choosin
oshima
2011/11/22 01:36:10
Done.
| |
507 xevent.xmotion.time = CurrentTime; | |
508 | |
509 gfx::Point point(xevent.xmotion.x, xevent.xmotion.y); | |
510 ConvertPointToNativeScreen(&point); | |
511 xevent.xmotion.x_root = point.x(); | |
512 xevent.xmotion.y_root = point.y(); | |
513 } | |
514 default: | |
515 break; | |
516 } | |
517 ::XSendEvent(xdisplay_, xwindow_, False, kInputEventMask, &xevent); | |
Daniel Erat
2011/11/22 00:25:32
nit: "::" seems unnecessary here; this function na
oshima
2011/11/22 01:36:10
Done.
| |
492 } | 518 } |
493 | 519 |
494 bool DesktopHostLinux::IsWindowManagerPresent() { | 520 bool DesktopHostLinux::IsWindowManagerPresent() { |
495 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership | 521 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
496 // of WM_Sn selections (where n is a screen number). | 522 // of WM_Sn selections (where n is a screen number). |
497 ::Atom wm_s0_atom = XInternAtom(xdisplay_, "WM_S0", False); | 523 ::Atom wm_s0_atom = XInternAtom(xdisplay_, "WM_S0", False); |
498 return XGetSelectionOwner(xdisplay_, wm_s0_atom) != None; | 524 return XGetSelectionOwner(xdisplay_, wm_s0_atom) != None; |
499 } | 525 } |
500 | 526 |
501 } // namespace | 527 } // namespace |
502 | 528 |
503 // static | 529 // static |
504 DesktopHost* DesktopHost::Create(const gfx::Rect& bounds) { | 530 DesktopHost* DesktopHost::Create(const gfx::Rect& bounds) { |
505 return new DesktopHostLinux(bounds); | 531 return new DesktopHostLinux(bounds); |
506 } | 532 } |
507 | 533 |
508 // static | 534 // static |
509 gfx::Size DesktopHost::GetNativeDisplaySize() { | 535 gfx::Size DesktopHost::GetNativeDisplaySize() { |
510 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); | 536 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); |
511 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 537 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
512 } | 538 } |
513 | 539 |
514 } // namespace aura | 540 } // namespace aura |
OLD | NEW |