annotate src/sys/x11/settings.cc @ 385:aa38b904de4f

http: fix incorrect type in curl_easy_setopt hahaha
author Paper <paper@tflc.us>
date Thu, 06 Nov 2025 08:58:05 -0500
parents 5eaafed6c10b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 #include "sys/x11/settings.h"
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
2 #include "core/byte_stream.h"
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
3
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
4 #include <array>
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
5 #include <cassert>
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
6 #include <climits>
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
7 #include <cstdint>
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
8 #include <cstring>
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
9 #include <map>
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
10 #include <memory>
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
11 #include <optional>
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
12 #include <string_view>
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
13
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
14 #include <xcb/xcb.h>
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
15
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
16 #include "fmt/core.h"
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
17
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
18 namespace x11 {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
19
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
20 bool SettingsItem::VerifyType()
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
21 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
22 switch (type) {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
23 case SettingsItem::TypeInt:
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
24 case SettingsItem::TypeStr:
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
25 case SettingsItem::TypeRgba: return true;
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
26 default: return false;
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
27 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
28 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
29
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
30 /* -------------------------------------------------------------------------- */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
31 /* xsettings parser */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
32
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
33 static constexpr std::size_t GetPadding(std::size_t length, std::size_t increment)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
34 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
35 /* ripped from xsettingsd */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
36 return (increment - (length % increment)) % increment;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
37 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
38
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
39 class Parser {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
40 public:
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
41 Parser(std::uint8_t *bytes, std::size_t size);
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
42
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
43 bool ParseHeader(void);
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
44 std::optional<SettingsItem> ParseNextItem(void);
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
45
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
46 std::uint32_t GetTotalItems(void);
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
47
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
48 private:
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
49 enum ByteOrder {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
50 LSBFirst = 0,
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
51 MSBFirst = 1,
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
52 };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
53
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
54 ByteStream stream;
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
55
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
56 /* parsed in the constructor */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
57 std::uint32_t serial_ = 0;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
58 std::uint32_t total_items_ = 0;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
59 };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
60
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
61 std::uint32_t Parser::GetTotalItems(void)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
62 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
63 return total_items_;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
64 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
65
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
66 Parser::Parser(std::uint8_t *bytes, std::size_t size) : stream(bytes, size)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
67 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
68 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
69
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
70 bool Parser::ParseHeader(void)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
71 {
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
72 std::uint8_t byte_order;
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
73 if (!stream.ReadBinary<std::uint8_t>(byte_order))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
74 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
75
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
76 switch (byte_order) {
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
77 case MSBFirst: stream.SetEndianness(ByteStream::ByteOrder::Big); break;
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
78 case LSBFirst: stream.SetEndianness(ByteStream::ByteOrder::Little); break;
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
79 default: return false; /* errr */
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
80 }
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
81
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
82 stream.Advance(3);
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
83
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
84 if (!stream.ReadInt<std::uint32_t>(serial_))
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
85 return false;
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
86
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
87 if (!stream.ReadInt<std::uint32_t>(total_items_))
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
88 return false;
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
89
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
90 return true;
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
91 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
92
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
93 std::optional<SettingsItem> Parser::ParseNextItem(void)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
94 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
95 SettingsItem item;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
96
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
97 /* read one byte */
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
98 if (!stream.ReadInt<std::uint8_t>(item.type))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
99 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
100
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
101 if (!item.VerifyType())
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
102 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
103
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
104 /* skip padding */
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
105 if (!stream.Advance(1))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
106 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
107
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
108 /* parse the name */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
109 std::uint16_t name_size;
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
110 if (!stream.ReadInt<std::uint16_t>(name_size))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
111 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
112
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
113 if (!stream.ReadString(item.name, name_size))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
114 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
115
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
116 /* padding */
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
117 if (!stream.Advance(GetPadding(name_size, 4)))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
118 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
119
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
120 if (!stream.ReadInt<std::uint32_t>(item.serial))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
121 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
122
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
123 switch (item.type) {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
124 case SettingsItem::TypeInt: {
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
125 if (!stream.ReadInt<std::int32_t>(item.data.integer))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
126 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
127
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
128 break;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
129 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
130 case SettingsItem::TypeStr: {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131 std::uint32_t size;
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
132 if (!stream.ReadInt<std::uint32_t>(size))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
134
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
135 if (!stream.ReadString(item.data.string, size))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
136 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
137
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
138 /* don't fail if advancing fails on this padding,
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
139 * because this causes parsing to fail for strings
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
140 * at the end of the data */
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
141 stream.Advance(GetPadding(size, 4));
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
142
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
143 break;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
144 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
145 case SettingsItem::TypeRgba: {
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
146 /* it's actually RBGA, but whatever. */
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
147 if (!stream.ReadInt<std::uint16_t>(item.data.rgba.red) ||
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
148 !stream.ReadInt<std::uint16_t>(item.data.rgba.blue) ||
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
149 !stream.ReadInt<std::uint16_t>(item.data.rgba.green) ||
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
150 !stream.ReadInt<std::uint16_t>(item.data.rgba.alpha))
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
151 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
152
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
153 break;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
154 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
155 default:
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
156 /* can't do anything now, can we? */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
157 return std::nullopt;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
158 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
159
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
160 return item;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
161 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
162
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
163 /* ------------------------------------------------------------------------- */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
164 /* real X11 code */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
165
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
166 template<typename T>
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
167 struct MallocDestructor {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
168 void operator()(T *t) const { std::free(t); };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
169 };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
170
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
171 struct XcbConnectionDestructor {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
172 void operator()(xcb_connection_t *conn) const { ::xcb_disconnect(conn); };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
173 };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
174
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
175 template<typename T>
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
176 using MallocPtr = std::unique_ptr<T, MallocDestructor<T>>;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
177
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
178 using XcbConnectionPtr = std::unique_ptr<xcb_connection_t, XcbConnectionDestructor>;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
179
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
180 /* RAII is nice */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
181 struct XcbGrabber {
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
182 XcbGrabber(::xcb_connection_t *conn)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
183 {
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
184 ::xcb_grab_server(conn);
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
185 conn_ = conn;
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
186 }
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
187 ~XcbGrabber() { ::xcb_ungrab_server(conn_); }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
188
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
189 private:
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
190 ::xcb_connection_t *conn_;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
191 };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
192
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
193 static ::xcb_window_t GetSelectionOwner(::xcb_connection_t *conn, ::xcb_atom_t selection)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
194 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
195 ::xcb_window_t owner = XCB_NONE;
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
196 MallocPtr<::xcb_get_selection_owner_reply_t> reply(
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
197 ::xcb_get_selection_owner_reply(conn, ::xcb_get_selection_owner(conn, selection), nullptr));
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
198
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
199 if (reply)
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
200 owner = reply->owner;
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
201
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
202 return owner;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
203 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
204
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
205 static bool GetRawSettingsData(std::vector<uint8_t> &bytes)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
206 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
207 int screen;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
208
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
209 XcbConnectionPtr conn(::xcb_connect(nullptr, &screen));
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
210 if (::xcb_connection_has_error(conn.get()))
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
211 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
212
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
213 /* get our needed atoms, available as atoms[Atom] */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
214 enum Atom {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
215 XSETTINGS_SCREEN, /* _XSETTINGS_S[N] */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
216 XSETTINGS_SETTINGS, /* _XSETTINGS_SETTINGS */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
217 };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
218
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
219 std::map<Atom, ::xcb_atom_t> atoms;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
220 {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
221 std::map<Atom, std::string> names = {
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
222 {XSETTINGS_SCREEN, fmt::format("_XSETTINGS_S{}", screen)},
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
223 {XSETTINGS_SETTINGS, "_XSETTINGS_SETTINGS"},
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
224 };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
225
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
226 std::map<Atom, ::xcb_intern_atom_cookie_t> atom_cookies;
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
227 for (const auto &name : names)
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
228 atom_cookies[name.first] = ::xcb_intern_atom(conn.get(), false, name.second.size(), name.second.data());
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
229
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
230 for (const auto &cookie : atom_cookies) {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
231 MallocPtr<::xcb_intern_atom_reply_t> reply(::xcb_intern_atom_reply(conn.get(), cookie.second, nullptr));
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
232 if (!reply || reply->atom == XCB_NONE)
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
233 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
234
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
235 atoms[cookie.first] = reply->atom;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
236 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
237 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
238
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
239 MallocPtr<xcb_get_property_reply_t> reply;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
240 {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
241 /* grab the X server as *required* by xsettings docs */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
242 const XcbGrabber grabber(conn.get());
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
243
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
244 ::xcb_window_t win = GetSelectionOwner(conn.get(), atoms[XSETTINGS_SCREEN]);
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
245 if (win == XCB_NONE)
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
246 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
247
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
248 reply.reset(::xcb_get_property_reply(
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
249 conn.get(), ::xcb_get_property(conn.get(), 0, win, atoms[XSETTINGS_SETTINGS], XCB_ATOM_ANY, 0L, UINT_MAX),
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
250 nullptr));
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
251 };
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
252 if (!reply)
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
253 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
254
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
255 uint8_t *data = reinterpret_cast<uint8_t *>(xcb_get_property_value(reply.get()));
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
256 int size = xcb_get_property_value_length(reply.get());
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
257 if (size < 0)
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
258 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
259
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
260 bytes.assign(data, data + size);
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
261
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
262 return true;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
263 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
264
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
265 /* ------------------------------------------------------------------------- */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
266 /* now for the actual all-important public API stringing all this together */
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
267
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
268 bool GetSettings(std::vector<SettingsItem> &settings)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
269 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
270 std::vector<std::uint8_t> xsettings_raw;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
271 if (!GetRawSettingsData(xsettings_raw))
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
272 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
273
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
274 Parser parser(xsettings_raw.data(), xsettings_raw.size());
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
275 if (!parser.ParseHeader())
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
276 return false;
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
277
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
278 std::uint32_t total = parser.GetTotalItems();
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
279
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
280 while (total--) {
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
281 std::optional<SettingsItem> opt_item = parser.ParseNextItem();
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
282 if (!opt_item)
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
283 break;
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
284
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
285 settings.push_back(opt_item.value());
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
286 }
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
287
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
288 return true;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
289 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
290
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
291 bool FindSetting(const std::string &name, SettingsItem &setting)
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
292 {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
293 std::vector<std::uint8_t> xsettings_raw;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
294 if (!GetRawSettingsData(xsettings_raw))
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
295 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
296
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
297 Parser parser(xsettings_raw.data(), xsettings_raw.size());
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
298 if (!parser.ParseHeader())
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
299 return false;
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
300
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
301 std::uint32_t total = parser.GetTotalItems();
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
302
364
99c961c91809 core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents: 354
diff changeset
303 while (total--) {
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
304 std::optional<SettingsItem> opt_item = parser.ParseNextItem();
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
305 if (!opt_item)
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
306 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
307
379
5eaafed6c10b *: clang-format
Paper <paper@tflc.us>
parents: 364
diff changeset
308 SettingsItem &item = opt_item.value();
351
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
309 if (item.name == name) {
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
310 setting = item;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
311 return true;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
312 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
313 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
314
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
315 return false;
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
316 }
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
317
c844f8bb87ce gui/theme: add xsettings backend
Paper <paper@paper.us.eu.org>
parents:
diff changeset
318 } // namespace x11