| 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 "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "ui/base/x/selection_utils.h" | 13 #include "ui/base/x/selection_utils.h" |
| 14 #include "ui/base/x/x11_util.h" | |
| 15 #include "ui/base/x/x11_window_event_manager.h" | 14 #include "ui/base/x/x11_window_event_manager.h" |
| 16 #include "ui/events/platform/x11/x11_event_source.h" | 15 #include "ui/events/platform/x11/x11_event_source.h" |
| 16 #include "ui/gfx/x/x11_atom_cache.h" |
| 17 | 17 |
| 18 namespace ui { | 18 namespace ui { |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 const char kAtomPair[] = "ATOM_PAIR"; | 22 const char kAtomPair[] = "ATOM_PAIR"; |
| 23 const char kIncr[] = "INCR"; | 23 const char kIncr[] = "INCR"; |
| 24 const char kMultiple[] = "MULTIPLE"; | 24 const char kMultiple[] = "MULTIPLE"; |
| 25 const char kSaveTargets[] = "SAVE_TARGETS"; | 25 const char kSaveTargets[] = "SAVE_TARGETS"; |
| 26 const char kTargets[] = "TARGETS"; | 26 const char kTargets[] = "TARGETS"; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 // Incrementally build our selection. By default this is a refusal, and we'll | 137 // Incrementally build our selection. By default this is a refusal, and we'll |
| 138 // override the parts indicating success in the different cases. | 138 // override the parts indicating success in the different cases. |
| 139 XEvent reply; | 139 XEvent reply; |
| 140 reply.xselection.type = SelectionNotify; | 140 reply.xselection.type = SelectionNotify; |
| 141 reply.xselection.requestor = requestor; | 141 reply.xselection.requestor = requestor; |
| 142 reply.xselection.selection = event.xselectionrequest.selection; | 142 reply.xselection.selection = event.xselectionrequest.selection; |
| 143 reply.xselection.target = requested_target; | 143 reply.xselection.target = requested_target; |
| 144 reply.xselection.property = None; // Indicates failure | 144 reply.xselection.property = None; // Indicates failure |
| 145 reply.xselection.time = event.xselectionrequest.time; | 145 reply.xselection.time = event.xselectionrequest.time; |
| 146 | 146 |
| 147 if (requested_target == GetAtom(kMultiple)) { | 147 if (requested_target == gfx::GetAtom(kMultiple)) { |
| 148 // The contents of |requested_property| should be a list of | 148 // The contents of |requested_property| should be a list of |
| 149 // <target,property> pairs. | 149 // <target,property> pairs. |
| 150 std::vector<std::pair<XAtom,XAtom> > conversions; | 150 std::vector<std::pair<XAtom,XAtom> > conversions; |
| 151 if (GetAtomPairArrayProperty(requestor, | 151 if (GetAtomPairArrayProperty(requestor, |
| 152 requested_property, | 152 requested_property, |
| 153 &conversions)) { | 153 &conversions)) { |
| 154 std::vector<XAtom> conversion_results; | 154 std::vector<XAtom> conversion_results; |
| 155 for (size_t i = 0; i < conversions.size(); ++i) { | 155 for (size_t i = 0; i < conversions.size(); ++i) { |
| 156 bool conversion_successful = ProcessTarget(conversions[i].first, | 156 bool conversion_successful = ProcessTarget(conversions[i].first, |
| 157 requestor, | 157 requestor, |
| 158 conversions[i].second); | 158 conversions[i].second); |
| 159 conversion_results.push_back(conversions[i].first); | 159 conversion_results.push_back(conversions[i].first); |
| 160 conversion_results.push_back( | 160 conversion_results.push_back( |
| 161 conversion_successful ? conversions[i].second : None); | 161 conversion_successful ? conversions[i].second : None); |
| 162 } | 162 } |
| 163 | 163 |
| 164 // Set the property to indicate which conversions succeeded. This matches | 164 // Set the property to indicate which conversions succeeded. This matches |
| 165 // what GTK does. | 165 // what GTK does. |
| 166 XChangeProperty( | 166 XChangeProperty( |
| 167 x_display_, requestor, requested_property, GetAtom(kAtomPair), 32, | 167 x_display_, requestor, requested_property, gfx::GetAtom(kAtomPair), |
| 168 PropModeReplace, | 168 32, PropModeReplace, |
| 169 reinterpret_cast<const unsigned char*>(&conversion_results.front()), | 169 reinterpret_cast<const unsigned char*>(&conversion_results.front()), |
| 170 conversion_results.size()); | 170 conversion_results.size()); |
| 171 | 171 |
| 172 reply.xselection.property = requested_property; | 172 reply.xselection.property = requested_property; |
| 173 } | 173 } |
| 174 } else { | 174 } else { |
| 175 if (ProcessTarget(requested_target, requestor, requested_property)) | 175 if (ProcessTarget(requested_target, requestor, requested_property)) |
| 176 reply.xselection.property = requested_property; | 176 reply.xselection.property = requested_property; |
| 177 } | 177 } |
| 178 | 178 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 199 return; | 199 return; |
| 200 | 200 |
| 201 ProcessIncrementalTransfer(&(*it)); | 201 ProcessIncrementalTransfer(&(*it)); |
| 202 if (!it->data.get()) | 202 if (!it->data.get()) |
| 203 CompleteIncrementalTransfer(it); | 203 CompleteIncrementalTransfer(it); |
| 204 } | 204 } |
| 205 | 205 |
| 206 bool SelectionOwner::ProcessTarget(XAtom target, | 206 bool SelectionOwner::ProcessTarget(XAtom target, |
| 207 XID requestor, | 207 XID requestor, |
| 208 XAtom property) { | 208 XAtom property) { |
| 209 XAtom multiple_atom = GetAtom(kMultiple); | 209 XAtom multiple_atom = gfx::GetAtom(kMultiple); |
| 210 XAtom save_targets_atom = GetAtom(kSaveTargets); | 210 XAtom save_targets_atom = gfx::GetAtom(kSaveTargets); |
| 211 XAtom targets_atom = GetAtom(kTargets); | 211 XAtom targets_atom = gfx::GetAtom(kTargets); |
| 212 XAtom timestamp_atom = GetAtom(kTimestamp); | 212 XAtom timestamp_atom = gfx::GetAtom(kTimestamp); |
| 213 | 213 |
| 214 if (target == multiple_atom || target == save_targets_atom) | 214 if (target == multiple_atom || target == save_targets_atom) |
| 215 return false; | 215 return false; |
| 216 | 216 |
| 217 if (target == timestamp_atom) { | 217 if (target == timestamp_atom) { |
| 218 XChangeProperty( | 218 XChangeProperty( |
| 219 x_display_, requestor, property, XA_INTEGER, 32, PropModeReplace, | 219 x_display_, requestor, property, XA_INTEGER, 32, PropModeReplace, |
| 220 reinterpret_cast<unsigned char*>(&acquired_selection_timestamp_), 1); | 220 reinterpret_cast<unsigned char*>(&acquired_selection_timestamp_), 1); |
| 221 return true; | 221 return true; |
| 222 } | 222 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 239 } | 239 } |
| 240 | 240 |
| 241 // Try to find the data type in map. | 241 // Try to find the data type in map. |
| 242 SelectionFormatMap::const_iterator it = format_map_.find(target); | 242 SelectionFormatMap::const_iterator it = format_map_.find(target); |
| 243 if (it != format_map_.end()) { | 243 if (it != format_map_.end()) { |
| 244 if (it->second->size() > max_request_size_) { | 244 if (it->second->size() > max_request_size_) { |
| 245 // We must send the data back in several chunks due to a limitation in | 245 // We must send the data back in several chunks due to a limitation in |
| 246 // the size of X requests. Notify the selection requestor that the data | 246 // the size of X requests. Notify the selection requestor that the data |
| 247 // will be sent incrementally by returning data of type "INCR". | 247 // will be sent incrementally by returning data of type "INCR". |
| 248 long length = it->second->size(); | 248 long length = it->second->size(); |
| 249 XChangeProperty(x_display_, requestor, property, GetAtom(kIncr), 32, | 249 XChangeProperty(x_display_, requestor, property, gfx::GetAtom(kIncr), 32, |
| 250 PropModeReplace, | 250 PropModeReplace, |
| 251 reinterpret_cast<unsigned char*>(&length), 1); | 251 reinterpret_cast<unsigned char*>(&length), 1); |
| 252 | 252 |
| 253 // Wait for the selection requestor to indicate that it has processed | 253 // Wait for the selection requestor to indicate that it has processed |
| 254 // the selection result before sending the first chunk of data. The | 254 // the selection result before sending the first chunk of data. The |
| 255 // selection requestor indicates this by deleting |property|. | 255 // selection requestor indicates this by deleting |property|. |
| 256 base::TimeTicks timeout = | 256 base::TimeTicks timeout = |
| 257 base::TimeTicks::Now() + | 257 base::TimeTicks::Now() + |
| 258 base::TimeDelta::FromMilliseconds(kIncrementalTransferTimeoutMs); | 258 base::TimeDelta::FromMilliseconds(kIncrementalTransferTimeoutMs); |
| 259 incremental_transfers_.push_back(IncrementalTransfer( | 259 incremental_transfers_.push_back(IncrementalTransfer( |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 SelectionOwner::IncrementalTransfer::IncrementalTransfer( | 364 SelectionOwner::IncrementalTransfer::IncrementalTransfer( |
| 365 IncrementalTransfer&& other) = default; | 365 IncrementalTransfer&& other) = default; |
| 366 | 366 |
| 367 SelectionOwner::IncrementalTransfer& SelectionOwner::IncrementalTransfer:: | 367 SelectionOwner::IncrementalTransfer& SelectionOwner::IncrementalTransfer:: |
| 368 operator=(IncrementalTransfer&&) = default; | 368 operator=(IncrementalTransfer&&) = default; |
| 369 | 369 |
| 370 SelectionOwner::IncrementalTransfer::~IncrementalTransfer() { | 370 SelectionOwner::IncrementalTransfer::~IncrementalTransfer() { |
| 371 } | 371 } |
| 372 | 372 |
| 373 } // namespace ui | 373 } // namespace ui |
| OLD | NEW |