Index: ui/base/x/x11_util.cc |
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc |
index 4d061953cc14bda873c56d7583dfc02119574ee2..1ac4513e7d713c41251843123c3b2eb45f4800d9 100644 |
--- a/ui/base/x/x11_util.cc |
+++ b/ui/base/x/x11_util.cc |
@@ -761,6 +761,62 @@ bool PropertyExists(XID window, const std::string& property_name) { |
return num_items > 0; |
} |
+bool GetRawBytesOfProperty(XID window, |
+ Atom property, |
+ unsigned char** out_data, |
+ size_t* out_data_bytes, |
+ size_t* out_data_items, |
+ Atom* out_type) { |
+ // Retrieve the data from our window. |
+ unsigned long nitems = 0; |
+ unsigned long nbytes = 0; |
+ Atom prop_type = None; |
+ int prop_format = 0; |
+ unsigned char* property_data = NULL; |
+ if (XGetWindowProperty(GetXDisplay(), window, property, |
+ 0, 0x1FFFFFFF /* MAXINT32 / 4 */, False, |
+ AnyPropertyType, &prop_type, &prop_format, |
+ &nitems, &nbytes, &property_data) != Success) { |
+ return false; |
+ } |
+ |
+ if (prop_type == None) |
+ return false; |
+ |
+ if (out_data) |
+ *out_data = property_data; |
+ else |
+ XFree(property_data); |
+ |
+ if (out_data_bytes) { |
+ // So even though we should theoretically have nbytes (and we can't |
+ // pass NULL there), we need to manually calculate the byte length here |
+ // because nbytes always returns zero. |
+ switch (prop_format) { |
+ case 8: |
+ *out_data_bytes = nitems; |
+ break; |
+ case 16: |
+ *out_data_bytes = sizeof(short) * nitems; |
+ break; |
+ case 32: |
+ *out_data_bytes = sizeof(long) * nitems; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+ } |
+ |
+ if (out_data_items) |
+ *out_data_items = nitems; |
+ |
+ if (out_type) |
+ *out_type = prop_type; |
+ |
+ return true; |
+} |
+ |
bool GetIntProperty(XID window, const std::string& property_name, int* value) { |
Atom type = None; |
int format = 0; // size in bits of each item in 'property' |
@@ -782,6 +838,27 @@ bool GetIntProperty(XID window, const std::string& property_name, int* value) { |
return true; |
} |
+bool GetXIDProperty(XID window, const std::string& property_name, XID* value) { |
+ Atom type = None; |
+ int format = 0; // size in bits of each item in 'property' |
+ unsigned long num_items = 0; |
+ unsigned char* property = NULL; |
+ |
+ int result = GetProperty(window, property_name, 1, |
+ &type, &format, &num_items, &property); |
+ if (result != Success) |
+ return false; |
+ |
+ if (format != 32 || num_items != 1) { |
+ XFree(property); |
+ return false; |
+ } |
+ |
+ *value = *(reinterpret_cast<XID*>(property)); |
+ XFree(property); |
+ return true; |
+} |
+ |
bool GetIntArrayProperty(XID window, |
const std::string& property_name, |
std::vector<int>* value) { |
@@ -892,6 +969,32 @@ bool SetIntArrayProperty(XID window, |
return gdk_error_trap_pop() == 0; |
} |
+bool SetAtomArrayProperty(XID window, |
+ const std::string& name, |
+ const std::string& type, |
+ const std::vector<Atom>& value) { |
+ DCHECK(!value.empty()); |
+ Atom name_atom = GetAtom(name.c_str()); |
+ Atom type_atom = GetAtom(type.c_str()); |
+ |
+ // XChangeProperty() expects values of type 32 to be longs. |
+ scoped_ptr<Atom[]> data(new Atom[value.size()]); |
+ for (size_t i = 0; i < value.size(); ++i) |
+ data[i] = value[i]; |
+ |
+ gdk_error_trap_push(); |
+ XChangeProperty(ui::GetXDisplay(), |
+ window, |
+ name_atom, |
+ type_atom, |
+ 32, // size in bits of items in 'value' |
+ PropModeReplace, |
+ reinterpret_cast<const unsigned char*>(data.get()), |
+ value.size()); // num items |
+ XSync(ui::GetXDisplay(), False); |
+ return gdk_error_trap_pop() == 0; |
+} |
+ |
Atom GetAtom(const char* name) { |
#if defined(TOOLKIT_GTK) |
return gdk_x11_get_xatom_by_name_for_display( |