| 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_requestor.h" | 5 #include "ui/base/x/selection_requestor.h" |
| 6 | 6 |
| 7 #include "base/message_pump_aurax11.h" | 7 #include "base/message_pump_aurax11.h" |
| 8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
| 9 #include "ui/base/x/selection_utils.h" | 9 #include "ui/base/x/selection_utils.h" |
| 10 #include "ui/base/x/x11_util.h" |
| 10 | 11 |
| 11 namespace ui { | 12 namespace ui { |
| 12 | 13 |
| 13 namespace { | 14 namespace { |
| 14 | 15 |
| 15 const char kChromeSelection[] = "CHROME_SELECTION"; | 16 const char kChromeSelection[] = "CHROME_SELECTION"; |
| 16 | 17 |
| 17 const char* kAtomsToCache[] = { | 18 const char* kAtomsToCache[] = { |
| 18 kChromeSelection, | 19 kChromeSelection, |
| 19 NULL | 20 NULL |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 current_target_ = target; | 61 current_target_ = target; |
| 61 in_nested_loop_ = true; | 62 in_nested_loop_ = true; |
| 62 quit_closure_ = run_loop.QuitClosure(); | 63 quit_closure_ = run_loop.QuitClosure(); |
| 63 run_loop.Run(); | 64 run_loop.Run(); |
| 64 in_nested_loop_ = false; | 65 in_nested_loop_ = false; |
| 65 current_target_ = None; | 66 current_target_ = None; |
| 66 | 67 |
| 67 if (returned_property_ != property_to_set) | 68 if (returned_property_ != property_to_set) |
| 68 return false; | 69 return false; |
| 69 | 70 |
| 70 // Retrieve the data from our window. | 71 return ui::GetRawBytesOfProperty(x_window_, returned_property_, |
| 71 unsigned long nitems = 0; | 72 out_data, out_data_bytes, out_data_items, |
| 72 unsigned long nbytes = 0; | 73 out_type); |
| 73 Atom prop_type = None; | |
| 74 int prop_format = 0; | |
| 75 unsigned char* property_data = NULL; | |
| 76 if (XGetWindowProperty(x_display_, | |
| 77 x_window_, | |
| 78 returned_property_, | |
| 79 0, 0x1FFFFFFF /* MAXINT32 / 4 */, False, | |
| 80 AnyPropertyType, &prop_type, &prop_format, | |
| 81 &nitems, &nbytes, &property_data) != Success) { | |
| 82 return false; | |
| 83 } | |
| 84 | |
| 85 if (prop_type == None) | |
| 86 return false; | |
| 87 | |
| 88 if (out_data) | |
| 89 *out_data = property_data; | |
| 90 | |
| 91 if (out_data_bytes) { | |
| 92 // So even though we should theoretically have nbytes (and we can't | |
| 93 // pass NULL there), we need to manually calculate the byte length here | |
| 94 // because nbytes always returns zero. | |
| 95 switch (prop_format) { | |
| 96 case 8: | |
| 97 *out_data_bytes = nitems; | |
| 98 break; | |
| 99 case 16: | |
| 100 *out_data_bytes = sizeof(short) * nitems; | |
| 101 break; | |
| 102 case 32: | |
| 103 *out_data_bytes = sizeof(long) * nitems; | |
| 104 break; | |
| 105 default: | |
| 106 NOTREACHED(); | |
| 107 break; | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 if (out_data_items) | |
| 112 *out_data_items = nitems; | |
| 113 | |
| 114 if (out_type) | |
| 115 *out_type = prop_type; | |
| 116 | |
| 117 return true; | |
| 118 } | 74 } |
| 119 | 75 |
| 120 scoped_ptr<SelectionData> SelectionRequestor::RequestAndWaitForTypes( | 76 scoped_ptr<SelectionData> SelectionRequestor::RequestAndWaitForTypes( |
| 121 const std::vector< ::Atom>& types) { | 77 const std::vector< ::Atom>& types) { |
| 122 for (std::vector< ::Atom>::const_iterator it = types.begin(); | 78 for (std::vector< ::Atom>::const_iterator it = types.begin(); |
| 123 it != types.end(); ++it) { | 79 it != types.end(); ++it) { |
| 124 unsigned char* data = NULL; | 80 unsigned char* data = NULL; |
| 125 size_t data_bytes = 0; | 81 size_t data_bytes = 0; |
| 126 ::Atom type = None; | 82 ::Atom type = None; |
| 127 if (PerformBlockingConvertSelection(*it, | 83 if (PerformBlockingConvertSelection(*it, |
| 128 &data, | 84 &data, |
| 129 &data_bytes, | 85 &data_bytes, |
| 130 NULL, | 86 NULL, |
| 131 &type) && | 87 &type) && |
| 132 type == *it) { | 88 type == *it) { |
| 133 scoped_ptr<SelectionData> data_out(new SelectionData(x_display_)); | 89 scoped_ptr<SelectionData> data_out(new SelectionData); |
| 134 data_out->Set(type, (char*)data, data_bytes, true); | 90 data_out->Set(type, (char*)data, data_bytes, true); |
| 135 return data_out.Pass(); | 91 return data_out.Pass(); |
| 136 } | 92 } |
| 137 } | 93 } |
| 138 | 94 |
| 139 return scoped_ptr<SelectionData>(); | 95 return scoped_ptr<SelectionData>(); |
| 140 } | 96 } |
| 141 | 97 |
| 142 void SelectionRequestor::OnSelectionNotify(const XSelectionEvent& event) { | 98 void SelectionRequestor::OnSelectionNotify(const XSelectionEvent& event) { |
| 143 if (!in_nested_loop_) { | 99 if (!in_nested_loop_) { |
| 144 // This shouldn't happen; we're not waiting on the X server for data, but | 100 // This shouldn't happen; we're not waiting on the X server for data, but |
| 145 // any client can send any message... | 101 // any client can send any message... |
| 146 return; | 102 return; |
| 147 } | 103 } |
| 148 | 104 |
| 149 if (selection_name_ == event.selection && | 105 if (selection_name_ == event.selection && |
| 150 current_target_ == event.target) { | 106 current_target_ == event.target) { |
| 151 returned_property_ = event.property; | 107 returned_property_ = event.property; |
| 152 } else { | 108 } else { |
| 153 // I am assuming that if some other client sent us a message after we've | 109 // I am assuming that if some other client sent us a message after we've |
| 154 // asked for data, but it's malformed, we should just treat as if they sent | 110 // asked for data, but it's malformed, we should just treat as if they sent |
| 155 // us an error message. | 111 // us an error message. |
| 156 returned_property_ = None; | 112 returned_property_ = None; |
| 157 } | 113 } |
| 158 | 114 |
| 159 quit_closure_.Run(); | 115 quit_closure_.Run(); |
| 160 } | 116 } |
| 161 | 117 |
| 162 } // namespace ui | 118 } // namespace ui |
| OLD | NEW |