diff options
author | Drew DeVault <sir@cmpwn.com> | 2016-12-28 02:04:51 -0500 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2016-12-28 02:04:51 -0500 |
commit | aab360bf2f357be65dab90c41af1a684e967925d (patch) | |
tree | aa2f006992d4ba68a4a7f536c279f173af6f4e24 | |
parent | Fix user-set LD_LIBRARY_PATH (diff) | |
download | sway-aab360bf2f357be65dab90c41af1a684e967925d.tar.gz sway-aab360bf2f357be65dab90c41af1a684e967925d.tar.zst sway-aab360bf2f357be65dab90c41af1a684e967925d.zip |
Add redshift support
-rw-r--r-- | protocols/CMakeLists.txt | 6 | ||||
-rw-r--r-- | protocols/gamma-control.xml | 57 | ||||
-rw-r--r-- | sway/extensions.c | 155 |
3 files changed, 179 insertions, 39 deletions
diff --git a/protocols/CMakeLists.txt b/protocols/CMakeLists.txt index ff0a2e4d..a9b459ab 100644 --- a/protocols/CMakeLists.txt +++ b/protocols/CMakeLists.txt | |||
@@ -22,12 +22,18 @@ WAYLAND_ADD_PROTOCOL_SERVER(proto-server-swaylock | |||
22 | swaylock | 22 | swaylock |
23 | ) | 23 | ) |
24 | 24 | ||
25 | WAYLAND_ADD_PROTOCOL_SERVER(proto-server-gamma-control | ||
26 | gamma-control.xml | ||
27 | gamma-control | ||
28 | ) | ||
29 | |||
25 | add_library(sway-protocols STATIC | 30 | add_library(sway-protocols STATIC |
26 | ${proto-client-xdg-shell} | 31 | ${proto-client-xdg-shell} |
27 | ${proto-client-desktop-shell} | 32 | ${proto-client-desktop-shell} |
28 | ${proto-server-desktop-shell} | 33 | ${proto-server-desktop-shell} |
29 | ${proto-client-swaylock} | 34 | ${proto-client-swaylock} |
30 | ${proto-server-swaylock} | 35 | ${proto-server-swaylock} |
36 | ${proto-server-gamma-control} | ||
31 | ) | 37 | ) |
32 | 38 | ||
33 | set(PROTOCOLS_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/protocols PARENT_SCOPE) | 39 | set(PROTOCOLS_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/protocols PARENT_SCOPE) |
diff --git a/protocols/gamma-control.xml b/protocols/gamma-control.xml new file mode 100644 index 00000000..e6e33265 --- /dev/null +++ b/protocols/gamma-control.xml | |||
@@ -0,0 +1,57 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <protocol name="gamma_control"> | ||
3 | |||
4 | <copyright> | ||
5 | Copyright © 2015 Giulio camuffo | ||
6 | |||
7 | Permission to use, copy, modify, distribute, and sell this | ||
8 | software and its documentation for any purpose is hereby granted | ||
9 | without fee, provided that the above copyright notice appear in | ||
10 | all copies and that both that copyright notice and this permission | ||
11 | notice appear in supporting documentation, and that the name of | ||
12 | the copyright holders not be used in advertising or publicity | ||
13 | pertaining to distribution of the software without specific, | ||
14 | written prior permission. The copyright holders make no | ||
15 | representations about the suitability of this software for any | ||
16 | purpose. It is provided "as is" without express or implied | ||
17 | warranty. | ||
18 | |||
19 | THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | ||
20 | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
21 | FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
22 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
23 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||
24 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | ||
25 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||
26 | THIS SOFTWARE. | ||
27 | </copyright> | ||
28 | |||
29 | <interface name="gamma_control_manager" version="1"> | ||
30 | <request name="destroy" type="destructor"/> | ||
31 | |||
32 | <request name="get_gamma_control"> | ||
33 | <arg name="id" type="new_id" interface="gamma_control"/> | ||
34 | <arg name="output" type="object" interface="wl_output"/> | ||
35 | </request> | ||
36 | </interface> | ||
37 | |||
38 | <interface name="gamma_control" version="1"> | ||
39 | <enum name="error"> | ||
40 | <entry name="invalid_gamma" value="0"/> | ||
41 | </enum> | ||
42 | |||
43 | <request name="destroy" type="destructor"/> | ||
44 | |||
45 | <request name="set_gamma"> | ||
46 | <arg name="red" type="array"/> | ||
47 | <arg name="green" type="array"/> | ||
48 | <arg name="blue" type="array"/> | ||
49 | </request> | ||
50 | |||
51 | <request name="reset_gamma"/> | ||
52 | |||
53 | <event name="gamma_size"> | ||
54 | <arg name="size" type="uint"/> | ||
55 | </event> | ||
56 | </interface> | ||
57 | </protocol> | ||
diff --git a/sway/extensions.c b/sway/extensions.c index 5fee7d38..15d2f971 100644 --- a/sway/extensions.c +++ b/sway/extensions.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <wlc/wlc-render.h> | 4 | #include <wlc/wlc-render.h> |
5 | #include "wayland-desktop-shell-server-protocol.h" | 5 | #include "wayland-desktop-shell-server-protocol.h" |
6 | #include "wayland-swaylock-server-protocol.h" | 6 | #include "wayland-swaylock-server-protocol.h" |
7 | #include "wayland-gamma-control-server-protocol.h" | ||
7 | #include "sway/layout.h" | 8 | #include "sway/layout.h" |
8 | #include "sway/input_state.h" | 9 | #include "sway/input_state.h" |
9 | #include "sway/extensions.h" | 10 | #include "sway/extensions.h" |
@@ -140,6 +141,52 @@ static void desktop_unlock(struct wl_client *client, struct wl_resource *resourc | |||
140 | sway_log(L_ERROR, "desktop_unlock is not currently supported"); | 141 | sway_log(L_ERROR, "desktop_unlock is not currently supported"); |
141 | } | 142 | } |
142 | 143 | ||
144 | static void set_grab_surface(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface) { | ||
145 | sway_log(L_ERROR, "desktop_set_grab_surface is not currently supported"); | ||
146 | } | ||
147 | |||
148 | static void desktop_ready(struct wl_client *client, struct wl_resource *resource) { | ||
149 | // nop | ||
150 | } | ||
151 | |||
152 | static void set_panel_position(struct wl_client *client, struct wl_resource *resource, uint32_t position) { | ||
153 | pid_t pid; | ||
154 | wl_client_get_credentials(client, &pid, NULL, NULL); | ||
155 | if (!(get_feature_policy(pid) & FEATURE_PANEL)) { | ||
156 | sway_log(L_INFO, "Denying panel feature to %d", pid); | ||
157 | return; | ||
158 | } | ||
159 | struct panel_config *config = find_or_create_panel_config(resource); | ||
160 | sway_log(L_DEBUG, "Panel position for wl_resource %p changed %d => %d", resource, config->panel_position, position); | ||
161 | config->panel_position = position; | ||
162 | arrange_windows(&root_container, -1, -1); | ||
163 | } | ||
164 | |||
165 | static struct desktop_shell_interface desktop_shell_implementation = { | ||
166 | .set_background = set_background, | ||
167 | .set_panel = set_panel, | ||
168 | .set_lock_surface = desktop_set_lock_surface, | ||
169 | .unlock = desktop_unlock, | ||
170 | .set_grab_surface = set_grab_surface, | ||
171 | .desktop_ready = desktop_ready, | ||
172 | .set_panel_position = set_panel_position | ||
173 | }; | ||
174 | |||
175 | static void desktop_shell_bind(struct wl_client *client, void *data, | ||
176 | unsigned int version, unsigned int id) { | ||
177 | if (version > 3) { | ||
178 | // Unsupported version | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | struct wl_resource *resource = wl_resource_create(client, &desktop_shell_interface, version, id); | ||
183 | if (!resource) { | ||
184 | wl_client_post_no_memory(client); | ||
185 | } | ||
186 | |||
187 | wl_resource_set_implementation(resource, &desktop_shell_implementation, NULL, NULL); | ||
188 | } | ||
189 | |||
143 | static void set_lock_surface(struct wl_client *client, struct wl_resource *resource, | 190 | static void set_lock_surface(struct wl_client *client, struct wl_resource *resource, |
144 | struct wl_resource *_output, struct wl_resource *surface) { | 191 | struct wl_resource *_output, struct wl_resource *surface) { |
145 | pid_t pid; | 192 | pid_t pid; |
@@ -179,70 +226,98 @@ static void unlock(struct wl_client *client, struct wl_resource *resource) { | |||
179 | // This isn't really necessary, we just unlock when the client exits. | 226 | // This isn't really necessary, we just unlock when the client exits. |
180 | } | 227 | } |
181 | 228 | ||
182 | static void set_grab_surface(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface) { | ||
183 | sway_log(L_ERROR, "desktop_set_grab_surface is not currently supported"); | ||
184 | } | ||
185 | |||
186 | static void desktop_ready(struct wl_client *client, struct wl_resource *resource) { | ||
187 | // nop | ||
188 | } | ||
189 | |||
190 | static void set_panel_position(struct wl_client *client, struct wl_resource *resource, uint32_t position) { | ||
191 | pid_t pid; | ||
192 | wl_client_get_credentials(client, &pid, NULL, NULL); | ||
193 | if (!(get_feature_policy(pid) & FEATURE_PANEL)) { | ||
194 | sway_log(L_INFO, "Denying panel feature to %d", pid); | ||
195 | return; | ||
196 | } | ||
197 | struct panel_config *config = find_or_create_panel_config(resource); | ||
198 | sway_log(L_DEBUG, "Panel position for wl_resource %p changed %d => %d", resource, config->panel_position, position); | ||
199 | config->panel_position = position; | ||
200 | arrange_windows(&root_container, -1, -1); | ||
201 | } | ||
202 | |||
203 | static struct desktop_shell_interface desktop_shell_implementation = { | ||
204 | .set_background = set_background, | ||
205 | .set_panel = set_panel, | ||
206 | .set_lock_surface = desktop_set_lock_surface, | ||
207 | .unlock = desktop_unlock, | ||
208 | .set_grab_surface = set_grab_surface, | ||
209 | .desktop_ready = desktop_ready, | ||
210 | .set_panel_position = set_panel_position | ||
211 | }; | ||
212 | |||
213 | static struct lock_interface swaylock_implementation = { | 229 | static struct lock_interface swaylock_implementation = { |
214 | .set_lock_surface = set_lock_surface, | 230 | .set_lock_surface = set_lock_surface, |
215 | .unlock = unlock | 231 | .unlock = unlock |
216 | }; | 232 | }; |
217 | 233 | ||
218 | static void desktop_shell_bind(struct wl_client *client, void *data, | 234 | static void swaylock_bind(struct wl_client *client, void *data, |
219 | unsigned int version, unsigned int id) { | 235 | unsigned int version, unsigned int id) { |
220 | if (version > 3) { | 236 | if (version > 1) { |
221 | // Unsupported version | 237 | // Unsupported version |
222 | return; | 238 | return; |
223 | } | 239 | } |
224 | 240 | ||
225 | struct wl_resource *resource = wl_resource_create(client, &desktop_shell_interface, version, id); | 241 | struct wl_resource *resource = wl_resource_create(client, &lock_interface, version, id); |
226 | if (!resource) { | 242 | if (!resource) { |
227 | wl_client_post_no_memory(client); | 243 | wl_client_post_no_memory(client); |
228 | } | 244 | } |
229 | 245 | ||
230 | wl_resource_set_implementation(resource, &desktop_shell_implementation, NULL, NULL); | 246 | wl_resource_set_implementation(resource, &swaylock_implementation, NULL, NULL); |
231 | } | 247 | } |
232 | 248 | ||
233 | static void swaylock_bind(struct wl_client *client, void *data, | 249 | static void gamma_control_destroy(struct wl_client *client, struct wl_resource *res) { |
234 | unsigned int version, unsigned int id) { | 250 | wl_resource_destroy(res); |
251 | } | ||
252 | |||
253 | static void gamma_control_set_gamma(struct wl_client *client, | ||
254 | struct wl_resource *res, struct wl_array *red, | ||
255 | struct wl_array *green, struct wl_array *blue) { | ||
256 | if (red->size != green->size || red->size != blue->size) { | ||
257 | wl_resource_post_error(res, GAMMA_CONTROL_ERROR_INVALID_GAMMA, | ||
258 | "The gamma ramps don't have the same size"); | ||
259 | return; | ||
260 | } | ||
261 | uint16_t *r = (uint16_t *)red->data; | ||
262 | uint16_t *g = (uint16_t *)green->data; | ||
263 | uint16_t *b = (uint16_t *)blue->data; | ||
264 | wlc_handle output = wlc_handle_from_wl_output_resource( | ||
265 | wl_resource_get_user_data(res)); | ||
266 | if (!output) { | ||
267 | return; | ||
268 | } | ||
269 | sway_log(L_DEBUG, "Setting gamma for output"); | ||
270 | wlc_output_set_gamma(output, red->size / sizeof(uint16_t), r, g, b); | ||
271 | } | ||
272 | |||
273 | static void gamma_control_reset_gamma(struct wl_client *client, | ||
274 | struct wl_resource *resource) { | ||
275 | // This space intentionally left blank | ||
276 | } | ||
277 | |||
278 | static struct gamma_control_interface gamma_control_implementation = { | ||
279 | .destroy = gamma_control_destroy, | ||
280 | .set_gamma = gamma_control_set_gamma, | ||
281 | .reset_gamma = gamma_control_reset_gamma | ||
282 | }; | ||
283 | |||
284 | static void gamma_control_manager_destroy(struct wl_client *client, | ||
285 | struct wl_resource *res) { | ||
286 | wl_resource_destroy(res); | ||
287 | } | ||
288 | |||
289 | static void gamma_control_manager_get(struct wl_client *client, | ||
290 | struct wl_resource *res, uint32_t id, struct wl_resource *_output) { | ||
291 | struct wl_resource *manager_res = wl_resource_create(client, | ||
292 | &gamma_control_interface, wl_resource_get_version(res), id); | ||
293 | wlc_handle output = wlc_handle_from_wl_output_resource(_output); | ||
294 | if (!output) { | ||
295 | return; | ||
296 | } | ||
297 | wl_resource_set_implementation(manager_res, &gamma_control_implementation, | ||
298 | _output, NULL); | ||
299 | gamma_control_send_gamma_size(manager_res, wlc_output_get_gamma_size(output)); | ||
300 | } | ||
301 | |||
302 | static struct gamma_control_manager_interface gamma_manager_implementation = { | ||
303 | .destroy = gamma_control_manager_destroy, | ||
304 | .get_gamma_control = gamma_control_manager_get | ||
305 | }; | ||
306 | |||
307 | static void gamma_control_manager_bind(struct wl_client *client, void *data, | ||
308 | unsigned int version, unsigned int fd) { | ||
235 | if (version > 1) { | 309 | if (version > 1) { |
236 | // Unsupported version | 310 | // Unsupported version |
237 | return; | 311 | return; |
238 | } | 312 | } |
239 | 313 | ||
240 | struct wl_resource *resource = wl_resource_create(client, &lock_interface, version, id); | 314 | struct wl_resource *resource = wl_resource_create(client, |
315 | &gamma_control_manager_interface, version, fd); | ||
241 | if (!resource) { | 316 | if (!resource) { |
242 | wl_client_post_no_memory(client); | 317 | wl_client_post_no_memory(client); |
243 | } | 318 | } |
244 | 319 | ||
245 | wl_resource_set_implementation(resource, &swaylock_implementation, NULL, NULL); | 320 | wl_resource_set_implementation(resource, &gamma_manager_implementation, NULL, NULL); |
246 | } | 321 | } |
247 | 322 | ||
248 | void register_extensions(void) { | 323 | void register_extensions(void) { |
@@ -252,4 +327,6 @@ void register_extensions(void) { | |||
252 | desktop_shell.lock_surfaces = create_list(); | 327 | desktop_shell.lock_surfaces = create_list(); |
253 | desktop_shell.is_locked = false; | 328 | desktop_shell.is_locked = false; |
254 | wl_global_create(wlc_get_wl_display(), &lock_interface, 1, NULL, swaylock_bind); | 329 | wl_global_create(wlc_get_wl_display(), &lock_interface, 1, NULL, swaylock_bind); |
330 | wl_global_create(wlc_get_wl_display(), &gamma_control_manager_interface, 1, | ||
331 | NULL, gamma_control_manager_bind); | ||
255 | } | 332 | } |