1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
7 #include "tools/icc_detect/icc_detect.h"
17 #include <QApplication>
26 constexpr char kIccProfileAtomName[] = "_ICC_PROFILE";
27 constexpr uint32_t kMaxIccProfileSize = 1 << 24;
30 void operator()(void* const p) const { std::free(p); }
33 using XcbUniquePtr = std::unique_ptr<T, FreeDeleter>;
37 QByteArray GetMonitorIccProfile(const QWidget* const widget) {
40 qGuiApp->nativeInterface<QNativeInterface::QX11Application>();
41 if (qX11App == nullptr) {
44 xcb_connection_t* const connection = qX11App->connection();
45 if (connection == nullptr) {
49 const int screenNumber = DefaultScreen(qX11App->display());
51 const xcb_intern_atom_cookie_t atomRequest =
52 xcb_intern_atom(connection, /*only_if_exists=*/1,
53 sizeof kIccProfileAtomName - 1, kIccProfileAtomName);
54 const XcbUniquePtr<xcb_intern_atom_reply_t> atomReply(
55 xcb_intern_atom_reply(connection, atomRequest, nullptr));
56 if (atomReply == nullptr) {
59 const xcb_atom_t iccProfileAtom = atomReply->atom;
61 const xcb_screen_t* screen = nullptr;
63 for (xcb_screen_iterator_t it =
64 xcb_setup_roots_iterator(xcb_get_setup(connection));
65 it.rem; xcb_screen_next(&it)) {
66 if (i == screenNumber) {
72 if (screen == nullptr) {
75 const xcb_get_property_cookie_t profileRequest = xcb_get_property(
76 connection, /*_delete=*/0, screen->root, iccProfileAtom,
77 XCB_GET_PROPERTY_TYPE_ANY, /*long_offset=*/0, kMaxIccProfileSize);
78 const XcbUniquePtr<xcb_get_property_reply_t> profile(
79 xcb_get_property_reply(connection, profileRequest, nullptr));
80 if (profile == nullptr || profile->bytes_after > 0) {
85 reinterpret_cast<const char*>(xcb_get_property_value(profile.get())),
86 xcb_get_property_value_length(profile.get()));