| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file defines utility functions for X11 (Linux only). This code has been | 5 // This file defines utility functions for X11 (Linux only). This code has been |
| 6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support | 6 // ported from XCB since we can't use XCB on Ubuntu while its 32-bit support |
| 7 // remains woefully incomplete. | 7 // remains woefully incomplete. |
| 8 | 8 |
| 9 #include "ui/base/x/x11_util.h" | 9 #include "ui/base/x/x11_util.h" |
| 10 | 10 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 LOG(ERROR) << "X IO error received (X server probably went away)"; | 89 LOG(ERROR) << "X IO error received (X server probably went away)"; |
| 90 _exit(1); | 90 _exit(1); |
| 91 } | 91 } |
| 92 | 92 |
| 93 // Note: The caller should free the resulting value data. | 93 // Note: The caller should free the resulting value data. |
| 94 bool GetProperty(XID window, const std::string& property_name, long max_length, | 94 bool GetProperty(XID window, const std::string& property_name, long max_length, |
| 95 XAtom* type, int* format, unsigned long* num_items, | 95 XAtom* type, int* format, unsigned long* num_items, |
| 96 unsigned char** property) { | 96 unsigned char** property) { |
| 97 XAtom property_atom = gfx::GetAtom(property_name.c_str()); | 97 XAtom property_atom = gfx::GetAtom(property_name.c_str()); |
| 98 unsigned long remaining_bytes = 0; | 98 unsigned long remaining_bytes = 0; |
| 99 return XGetWindowProperty(gfx::GetXDisplay(), | 99 return XGetWindowProperty(gfx::GetXDisplay(), window, property_atom, |
| 100 window, | 100 0, // offset into property data to read |
| 101 property_atom, | 101 max_length, // max length to get |
| 102 0, // offset into property data to read | 102 X11Constants::False, // deleted |
| 103 max_length, // max length to get | 103 AnyPropertyType, type, format, num_items, |
| 104 False, // deleted | 104 &remaining_bytes, property); |
| 105 AnyPropertyType, | |
| 106 type, | |
| 107 format, | |
| 108 num_items, | |
| 109 &remaining_bytes, | |
| 110 property); | |
| 111 } | 105 } |
| 112 | 106 |
| 113 bool SupportsEWMH() { | 107 bool SupportsEWMH() { |
| 114 static bool supports_ewmh = false; | 108 static bool supports_ewmh = false; |
| 115 static bool supports_ewmh_cached = false; | 109 static bool supports_ewmh_cached = false; |
| 116 if (!supports_ewmh_cached) { | 110 if (!supports_ewmh_cached) { |
| 117 supports_ewmh_cached = true; | 111 supports_ewmh_cached = true; |
| 118 | 112 |
| 119 int wm_window = 0u; | 113 int wm_window = 0u; |
| 120 if (!GetIntProperty(GetX11RootWindow(), | 114 if (!GetIntProperty(GetX11RootWindow(), |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 } | 621 } |
| 628 } | 622 } |
| 629 if (!is_in_shape_rects) | 623 if (!is_in_shape_rects) |
| 630 return false; | 624 return false; |
| 631 } | 625 } |
| 632 return true; | 626 return true; |
| 633 } | 627 } |
| 634 | 628 |
| 635 | 629 |
| 636 bool PropertyExists(XID window, const std::string& property_name) { | 630 bool PropertyExists(XID window, const std::string& property_name) { |
| 637 XAtom type = None; | 631 XAtom type = X11Constants::None; |
| 638 int format = 0; // size in bits of each item in 'property' | 632 int format = 0; // size in bits of each item in 'property' |
| 639 unsigned long num_items = 0; | 633 unsigned long num_items = 0; |
| 640 unsigned char* property = NULL; | 634 unsigned char* property = NULL; |
| 641 | 635 |
| 642 int result = GetProperty(window, property_name, 1, | 636 int result = GetProperty(window, property_name, 1, |
| 643 &type, &format, &num_items, &property); | 637 &type, &format, &num_items, &property); |
| 644 gfx::XScopedPtr<unsigned char> scoped_property(property); | 638 gfx::XScopedPtr<unsigned char> scoped_property(property); |
| 645 if (result != Success) | 639 if (result != X11Constants::Success) |
| 646 return false; | 640 return false; |
| 647 | 641 |
| 648 return num_items > 0; | 642 return num_items > 0; |
| 649 } | 643 } |
| 650 | 644 |
| 651 bool GetRawBytesOfProperty(XID window, | 645 bool GetRawBytesOfProperty(XID window, |
| 652 XAtom property, | 646 XAtom property, |
| 653 scoped_refptr<base::RefCountedMemory>* out_data, | 647 scoped_refptr<base::RefCountedMemory>* out_data, |
| 654 size_t* out_data_items, | 648 size_t* out_data_items, |
| 655 XAtom* out_type) { | 649 XAtom* out_type) { |
| 656 // Retrieve the data from our window. | 650 // Retrieve the data from our window. |
| 657 unsigned long nitems = 0; | 651 unsigned long nitems = 0; |
| 658 unsigned long nbytes = 0; | 652 unsigned long nbytes = 0; |
| 659 XAtom prop_type = None; | 653 XAtom prop_type = X11Constants::None; |
| 660 int prop_format = 0; | 654 int prop_format = 0; |
| 661 unsigned char* property_data = NULL; | 655 unsigned char* property_data = NULL; |
| 662 if (XGetWindowProperty(gfx::GetXDisplay(), window, property, | 656 if (XGetWindowProperty(gfx::GetXDisplay(), window, property, 0, |
| 663 0, 0x1FFFFFFF /* MAXINT32 / 4 */, False, | 657 0x1FFFFFFF /* MAXINT32 / 4 */, X11Constants::False, |
| 664 AnyPropertyType, &prop_type, &prop_format, | 658 AnyPropertyType, &prop_type, &prop_format, &nitems, |
| 665 &nitems, &nbytes, &property_data) != Success) { | 659 &nbytes, &property_data) != X11Constants::Success) { |
| 666 return false; | 660 return false; |
| 667 } | 661 } |
| 668 gfx::XScopedPtr<unsigned char> scoped_property(property_data); | 662 gfx::XScopedPtr<unsigned char> scoped_property(property_data); |
| 669 | 663 |
| 670 if (prop_type == None) | 664 if (prop_type == X11Constants::None) |
| 671 return false; | 665 return false; |
| 672 | 666 |
| 673 size_t bytes = 0; | 667 size_t bytes = 0; |
| 674 // So even though we should theoretically have nbytes (and we can't | 668 // So even though we should theoretically have nbytes (and we can't |
| 675 // pass NULL there), we need to manually calculate the byte length here | 669 // pass NULL there), we need to manually calculate the byte length here |
| 676 // because nbytes always returns zero. | 670 // because nbytes always returns zero. |
| 677 switch (prop_format) { | 671 switch (prop_format) { |
| 678 case 8: | 672 case 8: |
| 679 bytes = nitems; | 673 bytes = nitems; |
| 680 break; | 674 break; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 695 if (out_data_items) | 689 if (out_data_items) |
| 696 *out_data_items = nitems; | 690 *out_data_items = nitems; |
| 697 | 691 |
| 698 if (out_type) | 692 if (out_type) |
| 699 *out_type = prop_type; | 693 *out_type = prop_type; |
| 700 | 694 |
| 701 return true; | 695 return true; |
| 702 } | 696 } |
| 703 | 697 |
| 704 bool GetIntProperty(XID window, const std::string& property_name, int* value) { | 698 bool GetIntProperty(XID window, const std::string& property_name, int* value) { |
| 705 XAtom type = None; | 699 XAtom type = X11Constants::None; |
| 706 int format = 0; // size in bits of each item in 'property' | 700 int format = 0; // size in bits of each item in 'property' |
| 707 unsigned long num_items = 0; | 701 unsigned long num_items = 0; |
| 708 unsigned char* property = NULL; | 702 unsigned char* property = NULL; |
| 709 | 703 |
| 710 int result = GetProperty(window, property_name, 1, | 704 int result = GetProperty(window, property_name, 1, |
| 711 &type, &format, &num_items, &property); | 705 &type, &format, &num_items, &property); |
| 712 gfx::XScopedPtr<unsigned char> scoped_property(property); | 706 gfx::XScopedPtr<unsigned char> scoped_property(property); |
| 713 if (result != Success) | 707 if (result != X11Constants::Success) |
| 714 return false; | 708 return false; |
| 715 | 709 |
| 716 if (format != 32 || num_items != 1) | 710 if (format != 32 || num_items != 1) |
| 717 return false; | 711 return false; |
| 718 | 712 |
| 719 *value = static_cast<int>(*(reinterpret_cast<long*>(property))); | 713 *value = static_cast<int>(*(reinterpret_cast<long*>(property))); |
| 720 return true; | 714 return true; |
| 721 } | 715 } |
| 722 | 716 |
| 723 bool GetXIDProperty(XID window, const std::string& property_name, XID* value) { | 717 bool GetXIDProperty(XID window, const std::string& property_name, XID* value) { |
| 724 XAtom type = None; | 718 XAtom type = X11Constants::None; |
| 725 int format = 0; // size in bits of each item in 'property' | 719 int format = 0; // size in bits of each item in 'property' |
| 726 unsigned long num_items = 0; | 720 unsigned long num_items = 0; |
| 727 unsigned char* property = NULL; | 721 unsigned char* property = NULL; |
| 728 | 722 |
| 729 int result = GetProperty(window, property_name, 1, | 723 int result = GetProperty(window, property_name, 1, |
| 730 &type, &format, &num_items, &property); | 724 &type, &format, &num_items, &property); |
| 731 gfx::XScopedPtr<unsigned char> scoped_property(property); | 725 gfx::XScopedPtr<unsigned char> scoped_property(property); |
| 732 if (result != Success) | 726 if (result != X11Constants::Success) |
| 733 return false; | 727 return false; |
| 734 | 728 |
| 735 if (format != 32 || num_items != 1) | 729 if (format != 32 || num_items != 1) |
| 736 return false; | 730 return false; |
| 737 | 731 |
| 738 *value = *(reinterpret_cast<XID*>(property)); | 732 *value = *(reinterpret_cast<XID*>(property)); |
| 739 return true; | 733 return true; |
| 740 } | 734 } |
| 741 | 735 |
| 742 bool GetIntArrayProperty(XID window, | 736 bool GetIntArrayProperty(XID window, |
| 743 const std::string& property_name, | 737 const std::string& property_name, |
| 744 std::vector<int>* value) { | 738 std::vector<int>* value) { |
| 745 XAtom type = None; | 739 XAtom type = X11Constants::None; |
| 746 int format = 0; // size in bits of each item in 'property' | 740 int format = 0; // size in bits of each item in 'property' |
| 747 unsigned long num_items = 0; | 741 unsigned long num_items = 0; |
| 748 unsigned char* properties = NULL; | 742 unsigned char* properties = NULL; |
| 749 | 743 |
| 750 int result = GetProperty(window, property_name, | 744 int result = GetProperty(window, property_name, |
| 751 (~0L), // (all of them) | 745 (~0L), // (all of them) |
| 752 &type, &format, &num_items, &properties); | 746 &type, &format, &num_items, &properties); |
| 753 gfx::XScopedPtr<unsigned char> scoped_properties(properties); | 747 gfx::XScopedPtr<unsigned char> scoped_properties(properties); |
| 754 if (result != Success) | 748 if (result != X11Constants::Success) |
| 755 return false; | 749 return false; |
| 756 | 750 |
| 757 if (format != 32) | 751 if (format != 32) |
| 758 return false; | 752 return false; |
| 759 | 753 |
| 760 long* int_properties = reinterpret_cast<long*>(properties); | 754 long* int_properties = reinterpret_cast<long*>(properties); |
| 761 value->clear(); | 755 value->clear(); |
| 762 for (unsigned long i = 0; i < num_items; ++i) { | 756 for (unsigned long i = 0; i < num_items; ++i) { |
| 763 value->push_back(static_cast<int>(int_properties[i])); | 757 value->push_back(static_cast<int>(int_properties[i])); |
| 764 } | 758 } |
| 765 return true; | 759 return true; |
| 766 } | 760 } |
| 767 | 761 |
| 768 bool GetAtomArrayProperty(XID window, | 762 bool GetAtomArrayProperty(XID window, |
| 769 const std::string& property_name, | 763 const std::string& property_name, |
| 770 std::vector<XAtom>* value) { | 764 std::vector<XAtom>* value) { |
| 771 XAtom type = None; | 765 XAtom type = X11Constants::None; |
| 772 int format = 0; // size in bits of each item in 'property' | 766 int format = 0; // size in bits of each item in 'property' |
| 773 unsigned long num_items = 0; | 767 unsigned long num_items = 0; |
| 774 unsigned char* properties = NULL; | 768 unsigned char* properties = NULL; |
| 775 | 769 |
| 776 int result = GetProperty(window, property_name, | 770 int result = GetProperty(window, property_name, |
| 777 (~0L), // (all of them) | 771 (~0L), // (all of them) |
| 778 &type, &format, &num_items, &properties); | 772 &type, &format, &num_items, &properties); |
| 779 gfx::XScopedPtr<unsigned char> scoped_properties(properties); | 773 gfx::XScopedPtr<unsigned char> scoped_properties(properties); |
| 780 if (result != Success) | 774 if (result != X11Constants::Success) |
| 781 return false; | 775 return false; |
| 782 | 776 |
| 783 if (type != XA_ATOM) | 777 if (type != XA_ATOM) |
| 784 return false; | 778 return false; |
| 785 | 779 |
| 786 XAtom* atom_properties = reinterpret_cast<XAtom*>(properties); | 780 XAtom* atom_properties = reinterpret_cast<XAtom*>(properties); |
| 787 value->clear(); | 781 value->clear(); |
| 788 value->insert(value->begin(), atom_properties, atom_properties + num_items); | 782 value->insert(value->begin(), atom_properties, atom_properties + num_items); |
| 789 return true; | 783 return true; |
| 790 } | 784 } |
| 791 | 785 |
| 792 bool GetStringProperty( | 786 bool GetStringProperty( |
| 793 XID window, const std::string& property_name, std::string* value) { | 787 XID window, const std::string& property_name, std::string* value) { |
| 794 XAtom type = None; | 788 XAtom type = X11Constants::None; |
| 795 int format = 0; // size in bits of each item in 'property' | 789 int format = 0; // size in bits of each item in 'property' |
| 796 unsigned long num_items = 0; | 790 unsigned long num_items = 0; |
| 797 unsigned char* property = NULL; | 791 unsigned char* property = NULL; |
| 798 | 792 |
| 799 int result = GetProperty(window, property_name, 1024, | 793 int result = GetProperty(window, property_name, 1024, |
| 800 &type, &format, &num_items, &property); | 794 &type, &format, &num_items, &property); |
| 801 gfx::XScopedPtr<unsigned char> scoped_property(property); | 795 gfx::XScopedPtr<unsigned char> scoped_property(property); |
| 802 if (result != Success) | 796 if (result != X11Constants::Success) |
| 803 return false; | 797 return false; |
| 804 | 798 |
| 805 if (format != 8) | 799 if (format != 8) |
| 806 return false; | 800 return false; |
| 807 | 801 |
| 808 value->assign(reinterpret_cast<char*>(property), num_items); | 802 value->assign(reinterpret_cast<char*>(property), num_items); |
| 809 return true; | 803 return true; |
| 810 } | 804 } |
| 811 | 805 |
| 812 bool SetIntProperty(XID window, | 806 bool SetIntProperty(XID window, |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 } | 1036 } |
| 1043 } | 1037 } |
| 1044 | 1038 |
| 1045 bool GetXWindowStack(Window window, std::vector<XID>* windows) { | 1039 bool GetXWindowStack(Window window, std::vector<XID>* windows) { |
| 1046 windows->clear(); | 1040 windows->clear(); |
| 1047 | 1041 |
| 1048 Atom type; | 1042 Atom type; |
| 1049 int format; | 1043 int format; |
| 1050 unsigned long count; | 1044 unsigned long count; |
| 1051 unsigned char *data = NULL; | 1045 unsigned char *data = NULL; |
| 1052 if (GetProperty(window, | 1046 if (GetProperty(window, "_NET_CLIENT_LIST_STACKING", ~0L, &type, &format, |
| 1053 "_NET_CLIENT_LIST_STACKING", | 1047 &count, &data) != X11Constants::Success) { |
| 1054 ~0L, | |
| 1055 &type, | |
| 1056 &format, | |
| 1057 &count, | |
| 1058 &data) != Success) { | |
| 1059 return false; | 1048 return false; |
| 1060 } | 1049 } |
| 1061 gfx::XScopedPtr<unsigned char> scoped_data(data); | 1050 gfx::XScopedPtr<unsigned char> scoped_data(data); |
| 1062 | 1051 |
| 1063 bool result = false; | 1052 bool result = false; |
| 1064 if (type == XA_WINDOW && format == 32 && data && count > 0) { | 1053 if (type == XA_WINDOW && format == 32 && data && count > 0) { |
| 1065 result = true; | 1054 result = true; |
| 1066 XID* stack = reinterpret_cast<XID*>(data); | 1055 XID* stack = reinterpret_cast<XID*>(data); |
| 1067 for (long i = static_cast<long>(count) - 1; i >= 0; i--) | 1056 for (long i = static_cast<long>(count) - 1; i >= 0; i--) |
| 1068 windows->push_back(stack[i]); | 1057 windows->push_back(stack[i]); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 | 1159 |
| 1171 std::string GuessWindowManagerName() { | 1160 std::string GuessWindowManagerName() { |
| 1172 std::string name; | 1161 std::string name; |
| 1173 if (GetWindowManagerName(&name)) | 1162 if (GetWindowManagerName(&name)) |
| 1174 return name; | 1163 return name; |
| 1175 return "Unknown"; | 1164 return "Unknown"; |
| 1176 } | 1165 } |
| 1177 | 1166 |
| 1178 bool IsCompositingManagerPresent() { | 1167 bool IsCompositingManagerPresent() { |
| 1179 static bool is_compositing_manager_present = | 1168 static bool is_compositing_manager_present = |
| 1180 XGetSelectionOwner(gfx::GetXDisplay(), gfx::GetAtom("_NET_WM_CM_S0")) != | 1169 XGetSelectionOwner(gfx::GetXDisplay(), |
| 1181 None; | 1170 gfx::GetAtom("_NET_WM_CM_S0")) != X11Constants::None; |
| 1182 return is_compositing_manager_present; | 1171 return is_compositing_manager_present; |
| 1183 } | 1172 } |
| 1184 | 1173 |
| 1185 void SetDefaultX11ErrorHandlers() { | 1174 void SetDefaultX11ErrorHandlers() { |
| 1186 SetX11ErrorHandlers(NULL, NULL); | 1175 SetX11ErrorHandlers(NULL, NULL); |
| 1187 } | 1176 } |
| 1188 | 1177 |
| 1189 bool IsX11WindowFullScreen(XID window) { | 1178 bool IsX11WindowFullScreen(XID window) { |
| 1190 // If _NET_WM_STATE_FULLSCREEN is in _NET_SUPPORTED, use the presence or | 1179 // If _NET_WM_STATE_FULLSCREEN is in _NET_SUPPORTED, use the presence or |
| 1191 // absence of _NET_WM_STATE_FULLSCREEN in _NET_WM_STATE to determine | 1180 // absence of _NET_WM_STATE_FULLSCREEN in _NET_WM_STATE to determine |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 have_gpu_argb_visual_(false) { | 1363 have_gpu_argb_visual_(false) { |
| 1375 int visuals_len = 0; | 1364 int visuals_len = 0; |
| 1376 XVisualInfo visual_template; | 1365 XVisualInfo visual_template; |
| 1377 visual_template.screen = DefaultScreen(display_); | 1366 visual_template.screen = DefaultScreen(display_); |
| 1378 gfx::XScopedPtr<XVisualInfo[]> visual_list(XGetVisualInfo( | 1367 gfx::XScopedPtr<XVisualInfo[]> visual_list(XGetVisualInfo( |
| 1379 display_, VisualScreenMask, &visual_template, &visuals_len)); | 1368 display_, VisualScreenMask, &visual_template, &visuals_len)); |
| 1380 for (int i = 0; i < visuals_len; ++i) | 1369 for (int i = 0; i < visuals_len; ++i) |
| 1381 visuals_[visual_list[i].visualid].reset(new XVisualData(visual_list[i])); | 1370 visuals_[visual_list[i].visualid].reset(new XVisualData(visual_list[i])); |
| 1382 | 1371 |
| 1383 XAtom NET_WM_CM_S0 = gfx::GetAtom("_NET_WM_CM_S0"); | 1372 XAtom NET_WM_CM_S0 = gfx::GetAtom("_NET_WM_CM_S0"); |
| 1384 using_compositing_wm_ = XGetSelectionOwner(display_, NET_WM_CM_S0) != None; | 1373 using_compositing_wm_ = XGetSelectionOwner(display_, NET_WM_CM_S0) != X11Const
ants::None; |
| 1385 | 1374 |
| 1386 // Choose the opaque visual. | 1375 // Choose the opaque visual. |
| 1387 default_visual_id_ = | 1376 default_visual_id_ = |
| 1388 XVisualIDFromVisual(DefaultVisual(display_, DefaultScreen(display_))); | 1377 XVisualIDFromVisual(DefaultVisual(display_, DefaultScreen(display_))); |
| 1389 system_visual_id_ = default_visual_id_; | 1378 system_visual_id_ = default_visual_id_; |
| 1390 DCHECK(system_visual_id_); | 1379 DCHECK(system_visual_id_); |
| 1391 DCHECK(visuals_.find(system_visual_id_) != visuals_.end()); | 1380 DCHECK(visuals_.find(system_visual_id_) != visuals_.end()); |
| 1392 | 1381 |
| 1393 // Choose the transparent visual. | 1382 // Choose the transparent visual. |
| 1394 for (const auto& pair : visuals_) { | 1383 for (const auto& pair : visuals_) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 visual_info.visual, AllocNone); | 1459 visual_info.visual, AllocNone); |
| 1471 } | 1460 } |
| 1472 return colormap_; | 1461 return colormap_; |
| 1473 } | 1462 } |
| 1474 | 1463 |
| 1475 // ---------------------------------------------------------------------------- | 1464 // ---------------------------------------------------------------------------- |
| 1476 // End of x11_util_internal.h | 1465 // End of x11_util_internal.h |
| 1477 | 1466 |
| 1478 | 1467 |
| 1479 } // namespace ui | 1468 } // namespace ui |
| OLD | NEW |