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

Side by Side Diff: ui/base/x/selection_owner.cc

Issue 17029020: linux_aura: Redo how memory is handled in clipboard/drag code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes for sky; ptal Created 7 years, 6 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
« no previous file with comments | « ui/base/x/selection_owner.h ('k') | ui/base/x/selection_requestor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 #include <X11/Xatom.h> 8 #include <X11/Xatom.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 22 matching lines...) Expand all
33 selection_name_(selection_name), 33 selection_name_(selection_name),
34 atom_cache_(x_display_, kAtomsToCache) { 34 atom_cache_(x_display_, kAtomsToCache) {
35 } 35 }
36 36
37 SelectionOwner::~SelectionOwner() { 37 SelectionOwner::~SelectionOwner() {
38 Clear(); 38 Clear();
39 } 39 }
40 40
41 void SelectionOwner::RetrieveTargets(std::vector<Atom>* targets) { 41 void SelectionOwner::RetrieveTargets(std::vector<Atom>* targets) {
42 targets->clear(); 42 targets->clear();
43 for (SelectionFormatMap::const_iterator it = selection_data_->begin(); 43 for (SelectionFormatMap::const_iterator it = format_map_.begin();
44 it != selection_data_->end(); ++it) { 44 it != format_map_.end(); ++it) {
45 targets->push_back(it->first); 45 targets->push_back(it->first);
46 } 46 }
47 } 47 }
48 48
49 void SelectionOwner::TakeOwnershipOfSelection( 49 void SelectionOwner::TakeOwnershipOfSelection(
50 scoped_ptr<SelectionFormatMap> data) { 50 const SelectionFormatMap& data) {
51 XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime); 51 XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime);
52 52
53 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) { 53 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) {
54 // The X server agrees that we are the selection owner. Commit our data. 54 // The X server agrees that we are the selection owner. Commit our data.
55 selection_data_ = data.Pass(); 55 format_map_ = data;
56 } 56 }
57 } 57 }
58 58
59 void SelectionOwner::Clear() { 59 void SelectionOwner::Clear() {
60 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) 60 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_)
61 XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime); 61 XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime);
62 62
63 selection_data_.reset(); 63 format_map_ = SelectionFormatMap();
64 } 64 }
65 65
66 void SelectionOwner::OnSelectionRequest(const XSelectionRequestEvent& event) { 66 void SelectionOwner::OnSelectionRequest(const XSelectionRequestEvent& event) {
67 // Incrementally build our selection. By default this is a refusal, and we'll 67 // Incrementally build our selection. By default this is a refusal, and we'll
68 // override the parts indicating success in the different cases. 68 // override the parts indicating success in the different cases.
69 XEvent reply; 69 XEvent reply;
70 reply.xselection.type = SelectionNotify; 70 reply.xselection.type = SelectionNotify;
71 reply.xselection.requestor = event.requestor; 71 reply.xselection.requestor = event.requestor;
72 reply.xselection.selection = event.selection; 72 reply.xselection.selection = event.selection;
73 reply.xselection.target = event.target; 73 reply.xselection.target = event.target;
74 reply.xselection.property = None; // Indicates failure 74 reply.xselection.property = None; // Indicates failure
75 reply.xselection.time = event.time; 75 reply.xselection.time = event.time;
76 76
77 // Get the proper selection. 77 // Get the proper selection.
78 if (selection_data_.get()) { 78 Atom targets_atom = atom_cache_.GetAtom(kTargets);
79 Atom targets_atom = atom_cache_.GetAtom(kTargets); 79 if (event.target == targets_atom) {
80 if (event.target == targets_atom) { 80 // We have been asked for TARGETS. Send an atom array back with the data
81 // We have been asked for TARGETS. Send an atom array back with the data 81 // types we support.
82 // types we support. 82 std::vector<Atom> targets;
83 std::vector<Atom> targets; 83 targets.push_back(targets_atom);
84 targets.push_back(targets_atom); 84 RetrieveTargets(&targets);
85 RetrieveTargets(&targets);
86 85
87 XChangeProperty(x_display_, event.requestor, event.property, XA_ATOM, 32, 86 XChangeProperty(x_display_, event.requestor, event.property, XA_ATOM, 32,
87 PropModeReplace,
88 reinterpret_cast<unsigned char*>(&targets.front()),
89 targets.size());
90 reply.xselection.property = event.property;
91 } else if (event.target == atom_cache_.GetAtom(kMultiple)) {
92 // TODO(erg): Theoretically, the spec claims I'm supposed to handle the
93 // MULTIPLE case, but I haven't seen it in the wild yet.
94 NOTIMPLEMENTED();
95 } else {
96 // Try to find the data type in map.
97 SelectionFormatMap::const_iterator it =
98 format_map_.find(event.target);
99 if (it != format_map_.end()) {
100 XChangeProperty(x_display_, event.requestor, event.property,
101 event.target, 8,
88 PropModeReplace, 102 PropModeReplace,
89 reinterpret_cast<unsigned char*>(&targets.front()), 103 const_cast<unsigned char*>(
90 targets.size()); 104 reinterpret_cast<const unsigned char*>(
105 it->second->front())),
106 it->second->size());
91 reply.xselection.property = event.property; 107 reply.xselection.property = event.property;
92 } else if (event.target == atom_cache_.GetAtom(kMultiple)) {
93 // TODO(erg): Theoretically, the spec claims I'm supposed to handle the
94 // MULTIPLE case, but I haven't seen it in the wild yet.
95 NOTIMPLEMENTED();
96 } else {
97 // Try to find the data type in map.
98 SelectionFormatMap::const_iterator it =
99 selection_data_->find(event.target);
100 if (it != selection_data_->end()) {
101 XChangeProperty(x_display_, event.requestor, event.property,
102 event.target, 8,
103 PropModeReplace,
104 reinterpret_cast<unsigned char*>(it->second.first),
105 it->second.second);
106 reply.xselection.property = event.property;
107 }
108 // I would put error logging here, but GTK ignores TARGETS and spams us
109 // looking for its own internal types.
110 } 108 }
111 } else { 109 // I would put error logging here, but GTK ignores TARGETS and spams us
112 DLOG(ERROR) << "XWindow " << x_window_ << " received a SelectionRequest " 110 // looking for its own internal types.
113 << "message when we don't have data to offer.";
114 } 111 }
115 112
116 // Send off the reply. 113 // Send off the reply.
117 XSendEvent(x_display_, event.requestor, False, 0, &reply); 114 XSendEvent(x_display_, event.requestor, False, 0, &reply);
118 } 115 }
119 116
120 void SelectionOwner::OnSelectionClear(const XSelectionClearEvent& event) { 117 void SelectionOwner::OnSelectionClear(const XSelectionClearEvent& event) {
121 DLOG(ERROR) << "SelectionClear"; 118 DLOG(ERROR) << "SelectionClear";
122 119
123 // TODO(erg): If we receive a SelectionClear event while we're handling data, 120 // TODO(erg): If we receive a SelectionClear event while we're handling data,
124 // we need to delay clearing. 121 // we need to delay clearing.
125 } 122 }
126 123
127 } // namespace ui 124 } // namespace ui
128 125
OLDNEW
« no previous file with comments | « ui/base/x/selection_owner.h ('k') | ui/base/x/selection_requestor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698