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

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

Issue 396813004: Make selection_owner.h not include Xlib.h for consistency. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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') | no next file » | 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 13 matching lines...) Expand all
24 kAtomPair, 24 kAtomPair,
25 kMultiple, 25 kMultiple,
26 kSaveTargets, 26 kSaveTargets,
27 kTargets, 27 kTargets,
28 NULL 28 NULL
29 }; 29 };
30 30
31 // Gets the value of an atom pair array property. On success, true is returned 31 // Gets the value of an atom pair array property. On success, true is returned
32 // and the value is stored in |value|. 32 // and the value is stored in |value|.
33 bool GetAtomPairArrayProperty(XID window, 33 bool GetAtomPairArrayProperty(XID window,
34 Atom property, 34 XAtom property,
35 std::vector<std::pair<Atom,Atom> >* value) { 35 std::vector<std::pair<XAtom,XAtom> >* value) {
36 Atom type = None; 36 XAtom type = None;
37 int format = 0; // size in bits of each item in 'property' 37 int format = 0; // size in bits of each item in 'property'
38 unsigned long num_items = 0; 38 unsigned long num_items = 0;
39 unsigned char* properties = NULL; 39 unsigned char* properties = NULL;
40 unsigned long remaining_bytes = 0; 40 unsigned long remaining_bytes = 0;
41 41
42 int result = XGetWindowProperty(gfx::GetXDisplay(), 42 int result = XGetWindowProperty(gfx::GetXDisplay(),
43 window, 43 window,
44 property, 44 property,
45 0, // offset into property data to 45 0, // offset into property data to
46 // read 46 // read
47 (~0L), // entire array 47 (~0L), // entire array
48 False, // deleted 48 False, // deleted
49 AnyPropertyType, 49 AnyPropertyType,
50 &type, 50 &type,
51 &format, 51 &format,
52 &num_items, 52 &num_items,
53 &remaining_bytes, 53 &remaining_bytes,
54 &properties); 54 &properties);
55 55
56 if (result != Success) 56 if (result != Success)
57 return false; 57 return false;
58 58
59 // GTK does not require |type| to be kAtomPair. 59 // GTK does not require |type| to be kAtomPair.
60 if (format != 32 || num_items % 2 != 0) { 60 if (format != 32 || num_items % 2 != 0) {
61 XFree(properties); 61 XFree(properties);
62 return false; 62 return false;
63 } 63 }
64 64
65 Atom* atom_properties = reinterpret_cast<Atom*>(properties); 65 XAtom* atom_properties = reinterpret_cast<XAtom*>(properties);
66 value->clear(); 66 value->clear();
67 for (size_t i = 0; i < num_items; i+=2) 67 for (size_t i = 0; i < num_items; i+=2)
68 value->push_back(std::make_pair(atom_properties[i], atom_properties[i+1])); 68 value->push_back(std::make_pair(atom_properties[i], atom_properties[i+1]));
69 XFree(properties); 69 XFree(properties);
70 return true; 70 return true;
71 } 71 }
72 72
73 } // namespace 73 } // namespace
74 74
75 SelectionOwner::SelectionOwner(Display* x_display, 75 SelectionOwner::SelectionOwner(XDisplay* x_display,
76 Window x_window, 76 XID x_window,
77 Atom selection_name) 77 XAtom selection_name)
78 : x_display_(x_display), 78 : x_display_(x_display),
79 x_window_(x_window), 79 x_window_(x_window),
80 selection_name_(selection_name), 80 selection_name_(selection_name),
81 atom_cache_(x_display_, kAtomsToCache) { 81 atom_cache_(x_display_, kAtomsToCache) {
82 } 82 }
83 83
84 SelectionOwner::~SelectionOwner() { 84 SelectionOwner::~SelectionOwner() {
85 // If we are the selection owner, we need to release the selection so we 85 // If we are the selection owner, we need to release the selection so we
86 // don't receive further events. However, we don't call ClearSelectionOwner() 86 // don't receive further events. However, we don't call ClearSelectionOwner()
87 // because we don't want to do this indiscriminately. 87 // because we don't want to do this indiscriminately.
88 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) 88 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_)
89 XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime); 89 XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime);
90 } 90 }
91 91
92 void SelectionOwner::RetrieveTargets(std::vector<Atom>* targets) { 92 void SelectionOwner::RetrieveTargets(std::vector<XAtom>* targets) {
93 for (SelectionFormatMap::const_iterator it = format_map_.begin(); 93 for (SelectionFormatMap::const_iterator it = format_map_.begin();
94 it != format_map_.end(); ++it) { 94 it != format_map_.end(); ++it) {
95 targets->push_back(it->first); 95 targets->push_back(it->first);
96 } 96 }
97 } 97 }
98 98
99 void SelectionOwner::TakeOwnershipOfSelection( 99 void SelectionOwner::TakeOwnershipOfSelection(
100 const SelectionFormatMap& data) { 100 const SelectionFormatMap& data) {
101 XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime); 101 XSetSelectionOwner(x_display_, selection_name_, x_window_, CurrentTime);
102 102
103 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) { 103 if (XGetSelectionOwner(x_display_, selection_name_) == x_window_) {
104 // The X server agrees that we are the selection owner. Commit our data. 104 // The X server agrees that we are the selection owner. Commit our data.
105 format_map_ = data; 105 format_map_ = data;
106 } 106 }
107 } 107 }
108 108
109 void SelectionOwner::ClearSelectionOwner() { 109 void SelectionOwner::ClearSelectionOwner() {
110 XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime); 110 XSetSelectionOwner(x_display_, selection_name_, None, CurrentTime);
111 format_map_ = SelectionFormatMap(); 111 format_map_ = SelectionFormatMap();
112 } 112 }
113 113
114 void SelectionOwner::OnSelectionRequest(const XSelectionRequestEvent& event) { 114 void SelectionOwner::OnSelectionRequest(const XEvent& event) {
115 XID requestor = event.xselectionrequest.requestor;
116 XAtom requested_target = event.xselectionrequest.target;
117 XAtom requested_property = event.xselectionrequest.property;
118
115 // Incrementally build our selection. By default this is a refusal, and we'll 119 // Incrementally build our selection. By default this is a refusal, and we'll
116 // override the parts indicating success in the different cases. 120 // override the parts indicating success in the different cases.
117 XEvent reply; 121 XEvent reply;
118 reply.xselection.type = SelectionNotify; 122 reply.xselection.type = SelectionNotify;
119 reply.xselection.requestor = event.requestor; 123 reply.xselection.requestor = requestor;
120 reply.xselection.selection = event.selection; 124 reply.xselection.selection = event.xselectionrequest.selection;
121 reply.xselection.target = event.target; 125 reply.xselection.target = requested_target;
122 reply.xselection.property = None; // Indicates failure 126 reply.xselection.property = None; // Indicates failure
123 reply.xselection.time = event.time; 127 reply.xselection.time = event.xselectionrequest.time;
124 128
125 if (event.target == atom_cache_.GetAtom(kMultiple)) { 129 if (requested_target == atom_cache_.GetAtom(kMultiple)) {
126 // The contents of |event.property| should be a list of 130 // The contents of |requested_property| should be a list of
127 // <target,property> pairs. 131 // <target,property> pairs.
128 std::vector<std::pair<Atom,Atom> > conversions; 132 std::vector<std::pair<XAtom,XAtom> > conversions;
129 if (GetAtomPairArrayProperty(event.requestor, 133 if (GetAtomPairArrayProperty(requestor,
130 event.property, 134 requested_property,
131 &conversions)) { 135 &conversions)) {
132 std::vector<Atom> conversion_results; 136 std::vector<XAtom> conversion_results;
133 for (size_t i = 0; i < conversions.size(); ++i) { 137 for (size_t i = 0; i < conversions.size(); ++i) {
134 bool conversion_successful = ProcessTarget(conversions[i].first, 138 bool conversion_successful = ProcessTarget(conversions[i].first,
135 event.requestor, 139 requestor,
136 conversions[i].second); 140 conversions[i].second);
137 conversion_results.push_back(conversions[i].first); 141 conversion_results.push_back(conversions[i].first);
138 conversion_results.push_back( 142 conversion_results.push_back(
139 conversion_successful ? conversions[i].second : None); 143 conversion_successful ? conversions[i].second : None);
140 } 144 }
141 145
142 // Set the property to indicate which conversions succeeded. This matches 146 // Set the property to indicate which conversions succeeded. This matches
143 // what GTK does. 147 // what GTK does.
144 XChangeProperty( 148 XChangeProperty(
145 x_display_, 149 x_display_,
146 event.requestor, 150 requestor,
147 event.property, 151 requested_property,
148 atom_cache_.GetAtom(kAtomPair), 152 atom_cache_.GetAtom(kAtomPair),
149 32, 153 32,
150 PropModeReplace, 154 PropModeReplace,
151 reinterpret_cast<const unsigned char*>(&conversion_results.front()), 155 reinterpret_cast<const unsigned char*>(&conversion_results.front()),
152 conversion_results.size()); 156 conversion_results.size());
153 157
154 reply.xselection.property = event.property; 158 reply.xselection.property = requested_property;
155 } 159 }
156 } else { 160 } else {
157 if (ProcessTarget(event.target, event.requestor, event.property)) 161 if (ProcessTarget(requested_target, requestor, requested_property))
158 reply.xselection.property = event.property; 162 reply.xselection.property = requested_property;
159 } 163 }
160 164
161 // Send off the reply. 165 // Send off the reply.
162 XSendEvent(x_display_, event.requestor, False, 0, &reply); 166 XSendEvent(x_display_, requestor, False, 0, &reply);
163 } 167 }
164 168
165 void SelectionOwner::OnSelectionClear(const XSelectionClearEvent& event) { 169 void SelectionOwner::OnSelectionClear(const XEvent& event) {
166 DLOG(ERROR) << "SelectionClear"; 170 DLOG(ERROR) << "SelectionClear";
167 171
168 // TODO(erg): If we receive a SelectionClear event while we're handling data, 172 // TODO(erg): If we receive a SelectionClear event while we're handling data,
169 // we need to delay clearing. 173 // we need to delay clearing.
170 } 174 }
171 175
172 bool SelectionOwner::ProcessTarget(Atom target, 176 bool SelectionOwner::ProcessTarget(XAtom target,
173 ::Window requestor, 177 XID requestor,
174 ::Atom property) { 178 XAtom property) {
175 Atom multiple_atom = atom_cache_.GetAtom(kMultiple); 179 XAtom multiple_atom = atom_cache_.GetAtom(kMultiple);
176 Atom save_targets_atom = atom_cache_.GetAtom(kSaveTargets); 180 XAtom save_targets_atom = atom_cache_.GetAtom(kSaveTargets);
177 Atom targets_atom = atom_cache_.GetAtom(kTargets); 181 XAtom targets_atom = atom_cache_.GetAtom(kTargets);
178 182
179 if (target == multiple_atom || target == save_targets_atom) 183 if (target == multiple_atom || target == save_targets_atom)
180 return false; 184 return false;
181 185
182 if (target == targets_atom) { 186 if (target == targets_atom) {
183 // We have been asked for TARGETS. Send an atom array back with the data 187 // We have been asked for TARGETS. Send an atom array back with the data
184 // types we support. 188 // types we support.
185 std::vector<Atom> targets; 189 std::vector<XAtom> targets;
186 targets.push_back(targets_atom); 190 targets.push_back(targets_atom);
187 targets.push_back(save_targets_atom); 191 targets.push_back(save_targets_atom);
188 targets.push_back(multiple_atom); 192 targets.push_back(multiple_atom);
189 RetrieveTargets(&targets); 193 RetrieveTargets(&targets);
190 194
191 XChangeProperty(x_display_, requestor, property, XA_ATOM, 32, 195 XChangeProperty(x_display_, requestor, property, XA_ATOM, 32,
192 PropModeReplace, 196 PropModeReplace,
193 reinterpret_cast<unsigned char*>(&targets.front()), 197 reinterpret_cast<unsigned char*>(&targets.front()),
194 targets.size()); 198 targets.size());
195 return true; 199 return true;
196 } else { 200 } else {
197 // Try to find the data type in map. 201 // Try to find the data type in map.
198 SelectionFormatMap::const_iterator it = format_map_.find(target); 202 SelectionFormatMap::const_iterator it = format_map_.find(target);
199 if (it != format_map_.end()) { 203 if (it != format_map_.end()) {
200 XChangeProperty(x_display_, requestor, property, target, 8, 204 XChangeProperty(x_display_, requestor, property, target, 8,
201 PropModeReplace, 205 PropModeReplace,
202 const_cast<unsigned char*>( 206 const_cast<unsigned char*>(
203 reinterpret_cast<const unsigned char*>( 207 reinterpret_cast<const unsigned char*>(
204 it->second->front())), 208 it->second->front())),
205 it->second->size()); 209 it->second->size());
206 return true; 210 return true;
207 } 211 }
208 // I would put error logging here, but GTK ignores TARGETS and spams us 212 // I would put error logging here, but GTK ignores TARGETS and spams us
209 // looking for its own internal types. 213 // looking for its own internal types.
210 } 214 }
211 return false; 215 return false;
212 } 216 }
213 217
214 } // namespace ui 218 } // namespace ui
215
OLDNEW
« no previous file with comments | « ui/base/x/selection_owner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698