OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/base/x/x11_window_manager.h" |
| 6 |
| 7 #include <stddef.h> |
| 8 #include <X11/Xlib.h> |
| 9 #include <X11/Xlib-xcb.h> |
| 10 #include <xcb/xcb.h> |
| 11 |
| 12 #include "base/compiler_specific.h" |
| 13 #include "base/memory/singleton.h" |
| 14 |
| 15 namespace ui { |
| 16 |
| 17 // static |
| 18 XWindowManager* XWindowManager::GetInstance() { |
| 19 return base::Singleton<XWindowManager>::get(); |
| 20 } |
| 21 |
| 22 void XWindowManager::SelectEvents(XID xid, uint32_t event_mask) { |
| 23 BeforeMaskChanged(xid); |
| 24 MultiMask& mask = mask_map_[xid]; |
| 25 mask.AddMask(event_mask); |
| 26 AfterMaskChanged(xid); |
| 27 } |
| 28 |
| 29 void XWindowManager::DeselectEvents(XID xid, uint32_t event_mask) { |
| 30 DCHECK(mask_map_.find(xid) != mask_map_.end()); |
| 31 BeforeMaskChanged(xid); |
| 32 MultiMask& mask = mask_map_[xid]; |
| 33 mask.RemoveMask(event_mask); |
| 34 AfterMaskChanged(xid); |
| 35 } |
| 36 |
| 37 XWindowManager::XWindowManager() {} |
| 38 XWindowManager::~XWindowManager() {} |
| 39 |
| 40 void XWindowManager::BeforeMaskChanged(XID xid) { |
| 41 old_mask_ = mask_map_[xid].ToMask(); |
| 42 } |
| 43 |
| 44 void XWindowManager::AfterMaskChanged(XID xid) { |
| 45 uint32_t new_mask = mask_map_[xid].ToMask(); |
| 46 if (new_mask == old_mask_) |
| 47 return; |
| 48 |
| 49 XDisplay* display = gfx::GetXDisplay(); |
| 50 xcb_connection_t* connection = XGetXCBConnection(display); |
| 51 auto cookie = xcb_change_window_attributes(connection, xid, XCB_CW_EVENT_MASK, |
| 52 &new_mask); |
| 53 // Window |xid| may already be destroyed at this point, so the |
| 54 // change_attributes request may give a BadWindow error. In this case, just |
| 55 // ignore the error. |
| 56 xcb_discard_reply(connection, cookie.sequence); |
| 57 |
| 58 if (new_mask == NoEventMask) |
| 59 mask_map_.erase(xid); |
| 60 } |
| 61 |
| 62 XWindowManager::MultiMask::MultiMask() { |
| 63 for (int i = 0; i < kMaskSize; i++) |
| 64 mask_bits[i] = 0; |
| 65 } |
| 66 |
| 67 XWindowManager::MultiMask::~MultiMask() {} |
| 68 |
| 69 void XWindowManager::MultiMask::AddMask(uint32_t mask) { |
| 70 for (int i = 0; i < kMaskSize; i++) { |
| 71 if (mask & (1 << i)) |
| 72 mask_bits[i]++; |
| 73 } |
| 74 } |
| 75 |
| 76 void XWindowManager::MultiMask::RemoveMask(uint32_t mask) { |
| 77 for (int i = 0; i < kMaskSize; i++) { |
| 78 if (mask & (1 << i)) |
| 79 DCHECK(mask_bits[i]); |
| 80 mask_bits[i]--; |
| 81 } |
| 82 } |
| 83 |
| 84 uint32_t XWindowManager::MultiMask::ToMask() const { |
| 85 uint32_t mask = NoEventMask; |
| 86 for (int i = 0; i < kMaskSize; i++) { |
| 87 if (mask_bits[i]) |
| 88 mask |= (1 << i); |
| 89 } |
| 90 return mask; |
| 91 } |
| 92 |
| 93 } // namespace ui |
OLD | NEW |