| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/base/x/selection_owner.h" | 5 #include "ui/base/x/selection_owner.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
| 9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "ui/base/x/selection_utils.h" | 12 #include "ui/base/x/selection_utils.h" |
| 13 #include "ui/base/x/x11_foreign_window_manager.h" | 13 #include "ui/base/x/x11_foreign_window_manager.h" |
| 14 #include "ui/base/x/x11_util.h" | 14 #include "ui/base/x/x11_util.h" |
| 15 #include "ui/events/platform/x11/x11_event_source.h" |
| 15 | 16 |
| 16 namespace ui { | 17 namespace ui { |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 const char kAtomPair[] = "ATOM_PAIR"; | 21 const char kAtomPair[] = "ATOM_PAIR"; |
| 21 const char kIncr[] = "INCR"; | 22 const char kIncr[] = "INCR"; |
| 22 const char kMultiple[] = "MULTIPLE"; | 23 const char kMultiple[] = "MULTIPLE"; |
| 23 const char kSaveTargets[] = "SAVE_TARGETS"; | 24 const char kSaveTargets[] = "SAVE_TARGETS"; |
| 24 const char kTargets[] = "TARGETS"; | 25 const char kTargets[] = "TARGETS"; |
| 26 const char kTimestamp[] = "TIMESTAMP"; |
| 25 | 27 |
| 26 const char* kAtomsToCache[] = { | 28 const char* kAtomsToCache[] = {kAtomPair, kIncr, kMultiple, kSaveTargets, |
| 27 kAtomPair, | 29 kTargets, kTimestamp, NULL}; |
| 28 kIncr, | |
| 29 kMultiple, | |
| 30 kSaveTargets, | |
| 31 kTargets, | |
| 32 NULL | |
| 33 }; | |
| 34 | 30 |
| 35 // The period of |incremental_transfer_abort_timer_|. Arbitrary but must be <= | 31 // The period of |incremental_transfer_abort_timer_|. Arbitrary but must be <= |
| 36 // than kIncrementalTransferTimeoutMs. | 32 // than kIncrementalTransferTimeoutMs. |
| 37 const int kTimerPeriodMs = 1000; | 33 const int kTimerPeriodMs = 1000; |
| 38 | 34 |
| 39 // The amount of time to wait for the selection requestor to process the data | 35 // The amount of time to wait for the selection requestor to process the data |
| 40 // sent by the selection owner before aborting an incremental data transfer. | 36 // sent by the selection owner before aborting an incremental data transfer. |
| 41 const int kIncrementalTransferTimeoutMs = 10000; | 37 const int kIncrementalTransferTimeoutMs = 10000; |
| 42 | 38 |
| 43 static_assert(kTimerPeriodMs <= kIncrementalTransferTimeoutMs, | 39 static_assert(kTimerPeriodMs <= kIncrementalTransferTimeoutMs, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 | 111 |
| 116 void SelectionOwner::RetrieveTargets(std::vector<XAtom>* targets) { | 112 void SelectionOwner::RetrieveTargets(std::vector<XAtom>* targets) { |
| 117 for (SelectionFormatMap::const_iterator it = format_map_.begin(); | 113 for (SelectionFormatMap::const_iterator it = format_map_.begin(); |
| 118 it != format_map_.end(); ++it) { | 114 it != format_map_.end(); ++it) { |
| 119 targets->push_back(it->first); | 115 targets->push_back(it->first); |
| 120 } | 116 } |
| 121 } | 117 } |
| 122 | 118 |
| 123 void SelectionOwner::TakeOwnershipOfSelection( | 119 void SelectionOwner::TakeOwnershipOfSelection( |
| 124 const SelectionFormatMap& data) { | 120 const SelectionFormatMap& data) { |
| 125 XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime); | 121 // Note that we don't just use CurrentTime, since we need to return an actual |
| 122 // timestamp for the TIMESTAMP target later. |
| 123 acquired_selection_timestamp_ = |
| 124 X11EventSource::GetInstance()->last_seen_server_time(); |
| 125 XSetSelectionOwner(x_display_, selection_name_, x_window_, |
| 126 acquired_selection_timestamp_); |
| 126 | 127 |
| 127 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) { | 128 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) { |
| 128 // The X server agrees that we are the selection owner. Commit our data. | 129 // The X server agrees that we are the selection owner. Commit our data. |
| 129 format_map_ = data; | 130 format_map_ = data; |
| 130 } | 131 } |
| 131 } | 132 } |
| 132 | 133 |
| 133 void SelectionOwner::ClearSelectionOwner() { | 134 void SelectionOwner::ClearSelectionOwner() { |
| 134 XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime); | 135 XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime); |
| 135 format_map_ = SelectionFormatMap(); | 136 format_map_ = SelectionFormatMap(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 if (!it->data.get()) | 213 if (!it->data.get()) |
| 213 CompleteIncrementalTransfer(it); | 214 CompleteIncrementalTransfer(it); |
| 214 } | 215 } |
| 215 | 216 |
| 216 bool SelectionOwner::ProcessTarget(XAtom target, | 217 bool SelectionOwner::ProcessTarget(XAtom target, |
| 217 XID requestor, | 218 XID requestor, |
| 218 XAtom property) { | 219 XAtom property) { |
| 219 XAtom multiple_atom = atom_cache_.GetAtom(kMultiple); | 220 XAtom multiple_atom = atom_cache_.GetAtom(kMultiple); |
| 220 XAtom save_targets_atom = atom_cache_.GetAtom(kSaveTargets); | 221 XAtom save_targets_atom = atom_cache_.GetAtom(kSaveTargets); |
| 221 XAtom targets_atom = atom_cache_.GetAtom(kTargets); | 222 XAtom targets_atom = atom_cache_.GetAtom(kTargets); |
| 223 XAtom timestamp_atom = atom_cache_.GetAtom(kTimestamp); |
| 222 | 224 |
| 223 if (target == multiple_atom || target == save_targets_atom) | 225 if (target == multiple_atom || target == save_targets_atom) |
| 224 return false; | 226 return false; |
| 225 | 227 |
| 226 if (target == targets_atom) { | 228 if (target == timestamp_atom) { |
| 229 XChangeProperty( |
| 230 x_display_, requestor, property, XA_INTEGER, 32, PropModeReplace, |
| 231 reinterpret_cast<unsigned char*>(&acquired_selection_timestamp_), 1); |
| 232 return true; |
| 233 } else if (target == targets_atom) { |
| 227 // We have been asked for TARGETS. Send an atom array back with the data | 234 // We have been asked for TARGETS. Send an atom array back with the data |
| 228 // types we support. | 235 // types we support. |
| 229 std::vector<XAtom> targets; | 236 std::vector<XAtom> targets; |
| 237 targets.push_back(timestamp_atom); |
| 230 targets.push_back(targets_atom); | 238 targets.push_back(targets_atom); |
| 231 targets.push_back(save_targets_atom); | 239 targets.push_back(save_targets_atom); |
| 232 targets.push_back(multiple_atom); | 240 targets.push_back(multiple_atom); |
| 233 RetrieveTargets(&targets); | 241 RetrieveTargets(&targets); |
| 234 | 242 |
| 235 XChangeProperty(x_display_, requestor, property, XA_ATOM, 32, | 243 XChangeProperty(x_display_, requestor, property, XA_ATOM, 32, |
| 236 PropModeReplace, | 244 PropModeReplace, |
| 237 reinterpret_cast<unsigned char*>(&targets.front()), | 245 reinterpret_cast<unsigned char*>(&targets.front()), |
| 238 targets.size()); | 246 targets.size()); |
| 239 return true; | 247 return true; |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 foreign_window_manager_id(foreign_window_manager_id) { | 384 foreign_window_manager_id(foreign_window_manager_id) { |
| 377 } | 385 } |
| 378 | 386 |
| 379 SelectionOwner::IncrementalTransfer::IncrementalTransfer( | 387 SelectionOwner::IncrementalTransfer::IncrementalTransfer( |
| 380 const IncrementalTransfer& other) = default; | 388 const IncrementalTransfer& other) = default; |
| 381 | 389 |
| 382 SelectionOwner::IncrementalTransfer::~IncrementalTransfer() { | 390 SelectionOwner::IncrementalTransfer::~IncrementalTransfer() { |
| 383 } | 391 } |
| 384 | 392 |
| 385 } // namespace ui | 393 } // namespace ui |
| OLD | NEW |