Remove orbital screenshooter and gamma-control
These are undocumented, outdated protocols that have a better wlr-protocols equivalent.
This commit is contained in:
		
							parent
							
								
									abddd7b4db
								
							
						
					
					
						commit
						3dec88e455
					
				|  | @ -53,10 +53,6 @@ examples = { | |||
| 		'src': ['output-layout.c', 'cat.c'], | ||||
| 		'dep': [wlroots], | ||||
| 	}, | ||||
| 	'screenshot': { | ||||
| 		'src': 'screenshot.c', | ||||
| 		'dep': [wayland_client, wlr_protos, rt], | ||||
| 	}, | ||||
| 	'idle': { | ||||
| 		'src': 'idle.c', | ||||
| 		'dep': [wayland_client, wlr_protos, threads], | ||||
|  |  | |||
|  | @ -1,237 +0,0 @@ | |||
| /*
 | ||||
|  * Copyright © 2008 Kristian Høgsberg | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
|  * to deal in the Software without restriction, including without limitation | ||||
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||||
|  * and/or sell copies of the Software, and to permit persons to whom the | ||||
|  * Software is furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice (including the next | ||||
|  * paragraph) shall be included in all copies or substantial portions of the | ||||
|  * Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | ||||
|  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
|  * DEALINGS IN THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #define _POSIX_C_SOURCE 200112L | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <limits.h> | ||||
| #include <stdbool.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/param.h> | ||||
| #include <sys/wait.h> | ||||
| #include <unistd.h> | ||||
| #include <wayland-client.h> | ||||
| #include "screenshooter-client-protocol.h" | ||||
| 
 | ||||
| static struct wl_shm *shm = NULL; | ||||
| static struct orbital_screenshooter *screenshooter = NULL; | ||||
| static struct wl_list output_list; | ||||
| static bool buffer_copy_done; | ||||
| 
 | ||||
| struct screenshooter_output { | ||||
| 	struct wl_output *output; | ||||
| 	int width, height; | ||||
| 	struct wl_list link; | ||||
| }; | ||||
| 
 | ||||
| static void output_handle_geometry(void *data, struct wl_output *wl_output, | ||||
| 		int x, int y, int physical_width, int physical_height, int subpixel, | ||||
| 		const char *make, const char *model, int transform) { | ||||
| 	// No-op
 | ||||
| } | ||||
| 
 | ||||
| static void output_handle_mode(void *data, struct wl_output *wl_output, | ||||
| 		uint32_t flags, int width, int height, int refresh) { | ||||
| 	struct screenshooter_output *output = wl_output_get_user_data(wl_output); | ||||
| 
 | ||||
| 	if (wl_output == output->output && (flags & WL_OUTPUT_MODE_CURRENT)) { | ||||
| 		output->width = width; | ||||
| 		output->height = height; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void output_handle_done(void *data, struct wl_output *wl_output) { | ||||
| 	// No-op
 | ||||
| } | ||||
| 
 | ||||
| static const struct wl_output_listener output_listener = { | ||||
| 	.geometry = output_handle_geometry, | ||||
| 	.mode = output_handle_mode, | ||||
| 	.done = output_handle_done, | ||||
| }; | ||||
| 
 | ||||
| static void screenshot_done(void *data, struct orbital_screenshot *screenshot) { | ||||
| 	buffer_copy_done = true; | ||||
| } | ||||
| 
 | ||||
| static const struct orbital_screenshot_listener screenshot_listener = { | ||||
| 	.done = screenshot_done, | ||||
| }; | ||||
| 
 | ||||
| static void handle_global(void *data, struct wl_registry *registry, | ||||
| 		uint32_t name, const char *interface, uint32_t version) { | ||||
| 	static struct screenshooter_output *output; | ||||
| 
 | ||||
| 	if (strcmp(interface, "wl_output") == 0) { | ||||
| 		output = calloc(1, sizeof(*output)); | ||||
| 		output->output = wl_registry_bind(registry, name, &wl_output_interface, | ||||
| 			1); | ||||
| 		wl_list_insert(&output_list, &output->link); | ||||
| 		wl_output_add_listener(output->output, &output_listener, output); | ||||
| 	} else if (strcmp(interface, "wl_shm") == 0) { | ||||
| 		shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); | ||||
| 	} else if (strcmp(interface, "orbital_screenshooter") == 0) { | ||||
| 		screenshooter = wl_registry_bind(registry, name, | ||||
| 			&orbital_screenshooter_interface, 1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void handle_global_remove(void *data, struct wl_registry *registry, | ||||
| 		uint32_t name) { | ||||
| 	// Who cares?
 | ||||
| } | ||||
| 
 | ||||
| static const struct wl_registry_listener registry_listener = { | ||||
| 	.global = handle_global, | ||||
| 	.global_remove = handle_global_remove, | ||||
| }; | ||||
| 
 | ||||
| static struct wl_buffer *create_shm_buffer(int width, int height, | ||||
| 		void **data_out) { | ||||
| 	int stride = width * 4; | ||||
| 	int size = stride * height; | ||||
| 
 | ||||
| 	const char shm_name[] = "/wlroots-screenshot"; | ||||
| 	int fd = shm_open(shm_name, O_RDWR | O_CREAT | O_EXCL, 0); | ||||
| 	if (fd < 0) { | ||||
| 		fprintf(stderr, "shm_open failed\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	shm_unlink(shm_name); | ||||
| 
 | ||||
| 	int ret; | ||||
| 	while ((ret = ftruncate(fd, size)) == EINTR) { | ||||
| 		// No-op
 | ||||
| 	} | ||||
| 	if (ret < 0) { | ||||
| 		close(fd); | ||||
| 		fprintf(stderr, "ftruncate failed\n"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||||
| 	if (data == MAP_FAILED) { | ||||
| 		fprintf(stderr, "mmap failed: %m\n"); | ||||
| 		close(fd); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size); | ||||
| 	close(fd); | ||||
| 	struct wl_buffer *buffer = wl_shm_pool_create_buffer(pool, 0, width, height, | ||||
| 		stride, WL_SHM_FORMAT_XRGB8888); | ||||
| 	wl_shm_pool_destroy(pool); | ||||
| 
 | ||||
| 	*data_out = data; | ||||
| 
 | ||||
| 	return buffer; | ||||
| } | ||||
| 
 | ||||
| static void write_image(const char *filename, int width, int height, | ||||
| 		void *data) { | ||||
| 	char size[10 + 1 + 10 + 2 + 1]; // int32_t are max 10 digits
 | ||||
| 	sprintf(size, "%dx%d+0", width, height); | ||||
| 
 | ||||
| 	int fd[2]; | ||||
| 	if (pipe(fd) != 0) { | ||||
| 		fprintf(stderr, "cannot create pipe: %s\n", strerror(errno)); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	pid_t child = fork(); | ||||
| 	if (child < 0) { | ||||
| 		fprintf(stderr, "fork() failed\n"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} else if (child != 0) { | ||||
| 		close(fd[0]); | ||||
| 		if (write(fd[1], data, 4 * width * height) < 0) { | ||||
| 			fprintf(stderr, "write() failed: %s\n", strerror(errno)); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 		close(fd[1]); | ||||
| 		waitpid(child, NULL, 0); | ||||
| 	} else { | ||||
| 		close(fd[1]); | ||||
| 		if (dup2(fd[0], 0) != 0) { | ||||
| 			fprintf(stderr, "cannot dup the pipe\n"); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 		close(fd[0]); | ||||
| 		// We requested WL_SHM_FORMAT_XRGB8888 in little endian, so that's BGRA
 | ||||
| 		// in big endian.
 | ||||
| 		execlp("convert", "convert", "-depth", "8", "-size", size, "bgra:-", | ||||
| 			"-alpha", "opaque", filename, NULL); | ||||
| 		fprintf(stderr, "cannot execute convert\n"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) { | ||||
| 	struct wl_display * display = wl_display_connect(NULL); | ||||
| 	if (display == NULL) { | ||||
| 		fprintf(stderr, "failed to create display: %m\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	wl_list_init(&output_list); | ||||
| 	struct wl_registry *registry = wl_display_get_registry(display); | ||||
| 	wl_registry_add_listener(registry, ®istry_listener, NULL); | ||||
| 	wl_display_dispatch(display); | ||||
| 	wl_display_roundtrip(display); | ||||
| 
 | ||||
| 	if (screenshooter == NULL) { | ||||
| 		fprintf(stderr, "display doesn't support screenshooter\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	int i = 0; | ||||
| 	struct screenshooter_output *output; | ||||
| 	wl_list_for_each(output, &output_list, link) { | ||||
| 		void *data = NULL; | ||||
| 		struct wl_buffer *buffer = | ||||
| 			create_shm_buffer(output->width, output->height, &data); | ||||
| 		if (buffer == NULL) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 		struct orbital_screenshot *screenshot = orbital_screenshooter_shoot( | ||||
| 			screenshooter, output->output, buffer); | ||||
| 		orbital_screenshot_add_listener(screenshot, &screenshot_listener, | ||||
| 			screenshot); | ||||
| 		buffer_copy_done = false; | ||||
| 		while (!buffer_copy_done) { | ||||
| 			wl_display_roundtrip(display); | ||||
| 		} | ||||
| 
 | ||||
| 		char filename[24 + 10]; // int32_t are max 10 digits
 | ||||
| 		snprintf(filename, sizeof(filename), "wayland-screenshot-%d.png", i); | ||||
| 
 | ||||
| 		write_image(filename, output->width, output->height, data); | ||||
| 		wl_buffer_destroy(buffer); | ||||
| 		++i; | ||||
| 	} | ||||
| 
 | ||||
| 	return EXIT_SUCCESS; | ||||
| } | ||||
|  | @ -6,7 +6,6 @@ | |||
| #include <wlr/types/wlr_compositor.h> | ||||
| #include <wlr/types/wlr_foreign_toplevel_management_v1.h> | ||||
| #include <wlr/types/wlr_gamma_control_v1.h> | ||||
| #include <wlr/types/wlr_gamma_control.h> | ||||
| #include <wlr/types/wlr_gtk_primary_selection.h> | ||||
| #include <wlr/types/wlr_idle_inhibit_v1.h> | ||||
| #include <wlr/types/wlr_idle.h> | ||||
|  | @ -21,7 +20,6 @@ | |||
| #include <wlr/types/wlr_presentation_time.h> | ||||
| #include <wlr/types/wlr_relative_pointer_v1.h> | ||||
| #include <wlr/types/wlr_screencopy_v1.h> | ||||
| #include <wlr/types/wlr_screenshooter.h> | ||||
| #include <wlr/types/wlr_text_input_v3.h> | ||||
| #include <wlr/types/wlr_virtual_keyboard_v1.h> | ||||
| #include <wlr/types/wlr_xcursor_manager.h> | ||||
|  | @ -47,9 +45,7 @@ struct roots_desktop { | |||
| 	struct wlr_compositor *compositor; | ||||
| 	struct wlr_xdg_shell_v6 *xdg_shell_v6; | ||||
| 	struct wlr_xdg_shell *xdg_shell; | ||||
| 	struct wlr_gamma_control_manager *gamma_control_manager; | ||||
| 	struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1; | ||||
| 	struct wlr_screenshooter *screenshooter; | ||||
| 	struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager_v1; | ||||
| 	struct wlr_server_decoration_manager *server_decoration_manager; | ||||
| 	struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager; | ||||
|  |  | |||
|  | @ -9,7 +9,6 @@ install_headers( | |||
| 	'wlr_foreign_toplevel_management_v1.h', | ||||
| 	'wlr_fullscreen_shell_v1.h', | ||||
| 	'wlr_gamma_control_v1.h', | ||||
| 	'wlr_gamma_control.h', | ||||
| 	'wlr_gtk_primary_selection.h', | ||||
| 	'wlr_idle_inhibit_v1.h', | ||||
| 	'wlr_idle.h', | ||||
|  | @ -34,7 +33,6 @@ install_headers( | |||
| 	'wlr_region.h', | ||||
| 	'wlr_relative_pointer_v1.h', | ||||
| 	'wlr_screencopy_v1.h', | ||||
| 	'wlr_screenshooter.h', | ||||
| 	'wlr_seat.h', | ||||
| 	'wlr_server_decoration.h', | ||||
| 	'wlr_surface.h', | ||||
|  |  | |||
|  | @ -1,46 +0,0 @@ | |||
| /*
 | ||||
|  * This an unstable interface of wlroots. No guarantees are made regarding the | ||||
|  * future consistency of this API. | ||||
|  */ | ||||
| #ifndef WLR_USE_UNSTABLE | ||||
| #error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" | ||||
| #endif | ||||
| 
 | ||||
| #ifndef WLR_TYPES_WLR_GAMMA_CONTROL_H | ||||
| #define WLR_TYPES_WLR_GAMMA_CONTROL_H | ||||
| 
 | ||||
| #include <wayland-server.h> | ||||
| 
 | ||||
| struct wlr_gamma_control_manager { | ||||
| 	struct wl_global *global; | ||||
| 	struct wl_list controls; // wlr_gamma_control::link
 | ||||
| 
 | ||||
| 	struct wl_listener display_destroy; | ||||
| 
 | ||||
| 	struct { | ||||
| 		struct wl_signal destroy; | ||||
| 	} events; | ||||
| 
 | ||||
| 	void *data; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_gamma_control { | ||||
| 	struct wl_resource *resource; | ||||
| 	struct wlr_output *output; | ||||
| 	struct wl_list link; | ||||
| 
 | ||||
| 	struct wl_listener output_destroy_listener; | ||||
| 
 | ||||
| 	struct { | ||||
| 		struct wl_signal destroy; | ||||
| 	} events; | ||||
| 
 | ||||
| 	void* data; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_gamma_control_manager *wlr_gamma_control_manager_create( | ||||
| 	struct wl_display *display); | ||||
| void wlr_gamma_control_manager_destroy( | ||||
| 	struct wlr_gamma_control_manager *gamma_control_manager); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -1,49 +0,0 @@ | |||
| /*
 | ||||
|  * This protocol is obsolete and will be removed in a future version. The | ||||
|  * recommended replacement is wlr-screencopy. | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * This an unstable interface of wlroots. No guarantees are made regarding the | ||||
|  * future consistency of this API. | ||||
|  */ | ||||
| #ifndef WLR_USE_UNSTABLE | ||||
| #error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" | ||||
| #endif | ||||
| 
 | ||||
| #ifndef WLR_TYPES_WLR_SCREENSHOOTER_H | ||||
| #define WLR_TYPES_WLR_SCREENSHOOTER_H | ||||
| 
 | ||||
| #include <wayland-server.h> | ||||
| 
 | ||||
| /**
 | ||||
|  * A very basic screenshooter interrface which implements the Orbital protocol. | ||||
|  */ | ||||
| struct wlr_screenshooter { | ||||
| 	struct wl_global *global; | ||||
| 	struct wl_list screenshots; // wlr_screenshot::link
 | ||||
| 
 | ||||
| 	struct wl_listener display_destroy; | ||||
| 
 | ||||
| 	struct { | ||||
| 		struct wl_signal destroy; | ||||
| 	} events; | ||||
| 
 | ||||
| 	void *data; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_screenshot { | ||||
| 	struct wl_resource *resource; | ||||
| 	struct wl_resource *output_resource; | ||||
| 	struct wl_list link; | ||||
| 
 | ||||
| 	struct wlr_output *output; | ||||
| 	struct wlr_screenshooter *screenshooter; | ||||
| 
 | ||||
| 	void* data; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_screenshooter *wlr_screenshooter_create(struct wl_display *display); | ||||
| void wlr_screenshooter_destroy(struct wlr_screenshooter *screenshooter); | ||||
| 
 | ||||
| #endif | ||||
|  | @ -1,57 +0,0 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <protocol name="gamma_control"> | ||||
| 
 | ||||
|     <copyright> | ||||
|         Copyright © 2015 Giulio camuffo | ||||
| 
 | ||||
|         Permission to use, copy, modify, distribute, and sell this | ||||
|         software and its documentation for any purpose is hereby granted | ||||
|         without fee, provided that the above copyright notice appear in | ||||
|         all copies and that both that copyright notice and this permission | ||||
|         notice appear in supporting documentation, and that the name of | ||||
|         the copyright holders not be used in advertising or publicity | ||||
|         pertaining to distribution of the software without specific, | ||||
|         written prior permission.  The copyright holders make no | ||||
|         representations about the suitability of this software for any | ||||
|         purpose.  It is provided "as is" without express or implied | ||||
|         warranty. | ||||
| 
 | ||||
|         THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS | ||||
|         SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||
|         FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||||
|         SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|         WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||||
|         AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | ||||
|         ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||||
|         THIS SOFTWARE. | ||||
|     </copyright> | ||||
| 
 | ||||
|     <interface name="gamma_control_manager" version="1"> | ||||
|         <request name="destroy" type="destructor"/> | ||||
| 
 | ||||
|         <request name="get_gamma_control"> | ||||
|             <arg name="id" type="new_id" interface="gamma_control"/> | ||||
|             <arg name="output" type="object" interface="wl_output"/> | ||||
|         </request> | ||||
|     </interface> | ||||
| 
 | ||||
|     <interface name="gamma_control" version="1"> | ||||
|         <enum name="error"> | ||||
|             <entry name="invalid_gamma" value="0"/> | ||||
|         </enum> | ||||
| 
 | ||||
|         <request name="destroy" type="destructor"/> | ||||
| 
 | ||||
|         <request name="set_gamma"> | ||||
|             <arg name="red" type="array"/> | ||||
|             <arg name="green" type="array"/> | ||||
|             <arg name="blue" type="array"/> | ||||
|         </request> | ||||
| 
 | ||||
|         <request name="reset_gamma"/> | ||||
| 
 | ||||
|         <event name="gamma_size"> | ||||
|             <arg name="size" type="uint"/> | ||||
|         </event> | ||||
|     </interface> | ||||
| </protocol> | ||||
|  | @ -25,11 +25,9 @@ protocols = [ | |||
| 	[wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml'], | ||||
| 	[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'], | ||||
| 	[wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'], | ||||
| 	'gamma-control.xml', | ||||
| 	'gtk-primary-selection.xml', | ||||
| 	'idle.xml', | ||||
| 	'input-method-unstable-v2.xml', | ||||
| 	'screenshooter.xml', | ||||
| 	'server-decoration.xml', | ||||
| 	'virtual-keyboard-unstable-v1.xml', | ||||
| 	'wlr-data-control-unstable-v1.xml', | ||||
|  | @ -52,7 +50,6 @@ client_protocols = [ | |||
| 	[wl_protocol_dir, 'unstable/xdg-shell/xdg-shell-unstable-v6.xml'], | ||||
| 	'idle.xml', | ||||
| 	'input-method-unstable-v2.xml', | ||||
| 	'screenshooter.xml', | ||||
| 	'wlr-export-dmabuf-unstable-v1.xml', | ||||
| 	'wlr-foreign-toplevel-management-unstable-v1.xml', | ||||
| 	'wlr-gamma-control-unstable-v1.xml', | ||||
|  |  | |||
|  | @ -1,16 +0,0 @@ | |||
| <protocol name="orbital_screenshooter"> | ||||
| 
 | ||||
|     <interface name="orbital_screenshooter" version="1"> | ||||
|         <request name="shoot"> | ||||
|             <arg name="id" type="new_id" interface="orbital_screenshot"/> | ||||
|             <arg name="output" type="object" interface="wl_output"/> | ||||
|             <arg name="buffer" type="object" interface="wl_buffer"/> | ||||
|         </request> | ||||
|     </interface> | ||||
| 
 | ||||
|     <interface name="orbital_screenshot" version="1"> | ||||
|         <event name="done"> | ||||
|         </event> | ||||
|     </interface> | ||||
| 
 | ||||
| </protocol> | ||||
|  | @ -10,7 +10,6 @@ | |||
| #include <wlr/types/wlr_data_control_v1.h> | ||||
| #include <wlr/types/wlr_export_dmabuf_v1.h> | ||||
| #include <wlr/types/wlr_gamma_control_v1.h> | ||||
| #include <wlr/types/wlr_gamma_control.h> | ||||
| #include <wlr/types/wlr_gtk_primary_selection.h> | ||||
| #include <wlr/types/wlr_idle_inhibit_v1.h> | ||||
| #include <wlr/types/wlr_idle.h> | ||||
|  | @ -379,11 +378,8 @@ struct roots_desktop *desktop_create(struct roots_server *server, | |||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	desktop->gamma_control_manager = wlr_gamma_control_manager_create( | ||||
| 		server->wl_display); | ||||
| 	desktop->gamma_control_manager_v1 = wlr_gamma_control_manager_v1_create( | ||||
| 		server->wl_display); | ||||
| 	desktop->screenshooter = wlr_screenshooter_create(server->wl_display); | ||||
| 	desktop->export_dmabuf_manager_v1 = | ||||
| 		wlr_export_dmabuf_manager_v1_create(server->wl_display); | ||||
| 	desktop->server_decoration_manager = | ||||
|  |  | |||
|  | @ -32,7 +32,6 @@ lib_wlr_types = static_library( | |||
| 		'wlr_foreign_toplevel_management_v1.c', | ||||
| 		'wlr_fullscreen_shell_v1.c', | ||||
| 		'wlr_gamma_control_v1.c', | ||||
| 		'wlr_gamma_control.c', | ||||
| 		'wlr_gtk_primary_selection.c', | ||||
| 		'wlr_idle_inhibit_v1.c', | ||||
| 		'wlr_idle.c', | ||||
|  | @ -57,7 +56,6 @@ lib_wlr_types = static_library( | |||
| 		'wlr_region.c', | ||||
| 		'wlr_relative_pointer_v1.c', | ||||
| 		'wlr_screencopy_v1.c', | ||||
| 		'wlr_screenshooter.c', | ||||
| 		'wlr_server_decoration.c', | ||||
| 		'wlr_surface.c', | ||||
| 		'wlr_switch.c', | ||||
|  |  | |||
|  | @ -1,197 +0,0 @@ | |||
| #include <assert.h> | ||||
| #include <stdlib.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/types/wlr_gamma_control.h> | ||||
| #include <wlr/types/wlr_output.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include "gamma-control-protocol.h" | ||||
| #include "util/signal.h" | ||||
| 
 | ||||
| static void resource_destroy(struct wl_client *client, | ||||
| 		struct wl_resource *resource) { | ||||
| 	wl_resource_destroy(resource); | ||||
| } | ||||
| 
 | ||||
| static void gamma_control_destroy(struct wlr_gamma_control *gamma_control) { | ||||
| 	if (gamma_control == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 	wlr_signal_emit_safe(&gamma_control->events.destroy, gamma_control); | ||||
| 	wl_list_remove(&gamma_control->output_destroy_listener.link); | ||||
| 	wl_resource_set_user_data(gamma_control->resource, NULL); | ||||
| 	wl_list_remove(&gamma_control->link); | ||||
| 	free(gamma_control); | ||||
| } | ||||
| 
 | ||||
| static const struct gamma_control_interface gamma_control_impl; | ||||
| 
 | ||||
| static struct wlr_gamma_control *gamma_control_from_resource( | ||||
| 		struct wl_resource *resource) { | ||||
| 	assert(wl_resource_instance_of(resource, &gamma_control_interface, | ||||
| 		&gamma_control_impl)); | ||||
| 	return wl_resource_get_user_data(resource); | ||||
| } | ||||
| 
 | ||||
| static void gamma_control_destroy_resource(struct wl_resource *resource) { | ||||
| 	struct wlr_gamma_control *gamma_control = | ||||
| 		gamma_control_from_resource(resource); | ||||
| 	gamma_control_destroy(gamma_control); | ||||
| } | ||||
| 
 | ||||
| static void gamma_control_handle_output_destroy(struct wl_listener *listener, | ||||
| 		void *data) { | ||||
| 	struct wlr_gamma_control *gamma_control = | ||||
| 		wl_container_of(listener, gamma_control, output_destroy_listener); | ||||
| 	gamma_control_destroy(gamma_control); | ||||
| } | ||||
| 
 | ||||
| static void gamma_control_set_gamma(struct wl_client *client, | ||||
| 		struct wl_resource *gamma_control_resource, struct wl_array *red, | ||||
| 		struct wl_array *green, struct wl_array *blue) { | ||||
| 	struct wlr_gamma_control *gamma_control = | ||||
| 		gamma_control_from_resource(gamma_control_resource); | ||||
| 
 | ||||
| 	if (gamma_control == NULL) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (red->size != green->size || red->size != blue->size) { | ||||
| 		wl_resource_post_error(gamma_control_resource, | ||||
| 			GAMMA_CONTROL_ERROR_INVALID_GAMMA, | ||||
| 			"The gamma ramps don't have the same size"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	uint32_t size = red->size / sizeof(uint16_t); | ||||
| 	uint16_t *r = (uint16_t *)red->data; | ||||
| 	uint16_t *g = (uint16_t *)green->data; | ||||
| 	uint16_t *b = (uint16_t *)blue->data; | ||||
| 
 | ||||
| 	wlr_output_set_gamma(gamma_control->output, size, r, g, b); | ||||
| } | ||||
| 
 | ||||
| static void gamma_control_reset_gamma(struct wl_client *client, | ||||
| 		struct wl_resource *gamma_control_resource) { | ||||
| 	// TODO
 | ||||
| } | ||||
| 
 | ||||
| static const struct gamma_control_interface gamma_control_impl = { | ||||
| 	.destroy = resource_destroy, | ||||
| 	.set_gamma = gamma_control_set_gamma, | ||||
| 	.reset_gamma = gamma_control_reset_gamma, | ||||
| }; | ||||
| 
 | ||||
| static const struct gamma_control_manager_interface gamma_control_manager_impl; | ||||
| 
 | ||||
| static struct wlr_gamma_control_manager *gamma_control_manager_from_resource( | ||||
| 		struct wl_resource *resource) { | ||||
| 	assert(wl_resource_instance_of(resource, &gamma_control_manager_interface, | ||||
| 		&gamma_control_manager_impl)); | ||||
| 	return wl_resource_get_user_data(resource); | ||||
| } | ||||
| 
 | ||||
| static void gamma_control_manager_get_gamma_control(struct wl_client *client, | ||||
| 		struct wl_resource *gamma_control_manager_resource, uint32_t id, | ||||
| 		struct wl_resource *output_resource) { | ||||
| 	struct wlr_gamma_control_manager *manager = | ||||
| 		gamma_control_manager_from_resource(gamma_control_manager_resource); | ||||
| 	struct wlr_output *output = wlr_output_from_resource(output_resource); | ||||
| 
 | ||||
| 	struct wlr_gamma_control *gamma_control = | ||||
| 		calloc(1, sizeof(struct wlr_gamma_control)); | ||||
| 	if (gamma_control == NULL) { | ||||
| 		wl_client_post_no_memory(client); | ||||
| 		return; | ||||
| 	} | ||||
| 	gamma_control->output = output; | ||||
| 
 | ||||
| 	int version = wl_resource_get_version(gamma_control_manager_resource); | ||||
| 	gamma_control->resource = wl_resource_create(client, | ||||
| 		&gamma_control_interface, version, id); | ||||
| 	if (gamma_control->resource == NULL) { | ||||
| 		free(gamma_control); | ||||
| 		wl_client_post_no_memory(client); | ||||
| 		return; | ||||
| 	} | ||||
| 	wlr_log(WLR_DEBUG, "new gamma_control %p (res %p)", gamma_control, | ||||
| 		gamma_control->resource); | ||||
| 	wl_resource_set_implementation(gamma_control->resource, | ||||
| 		&gamma_control_impl, gamma_control, gamma_control_destroy_resource); | ||||
| 
 | ||||
| 	wl_signal_init(&gamma_control->events.destroy); | ||||
| 
 | ||||
| 	wl_signal_add(&output->events.destroy, | ||||
| 		&gamma_control->output_destroy_listener); | ||||
| 	gamma_control->output_destroy_listener.notify = | ||||
| 		gamma_control_handle_output_destroy; | ||||
| 
 | ||||
| 	wl_list_insert(&manager->controls, &gamma_control->link); | ||||
| 
 | ||||
| 	gamma_control_send_gamma_size(gamma_control->resource, | ||||
| 		wlr_output_get_gamma_size(output)); | ||||
| } | ||||
| 
 | ||||
| static const struct gamma_control_manager_interface gamma_control_manager_impl = { | ||||
| 	.get_gamma_control = gamma_control_manager_get_gamma_control, | ||||
| }; | ||||
| 
 | ||||
| static void gamma_control_manager_bind(struct wl_client *client, void *data, | ||||
| 		uint32_t version, uint32_t id) { | ||||
| 	struct wlr_gamma_control_manager *manager = data; | ||||
| 	assert(client && manager); | ||||
| 
 | ||||
| 	struct wl_resource *resource = wl_resource_create(client, | ||||
| 		&gamma_control_manager_interface, version, id); | ||||
| 	if (resource == NULL) { | ||||
| 		wl_client_post_no_memory(client); | ||||
| 		return; | ||||
| 	} | ||||
| 	wl_resource_set_implementation(resource, &gamma_control_manager_impl, | ||||
| 		manager, NULL); | ||||
| } | ||||
| 
 | ||||
| void wlr_gamma_control_manager_destroy( | ||||
| 		struct wlr_gamma_control_manager *manager) { | ||||
| 	if (!manager) { | ||||
| 		return; | ||||
| 	} | ||||
| 	struct wlr_gamma_control *gamma_control, *tmp; | ||||
| 	wl_list_for_each_safe(gamma_control, tmp, &manager->controls, link) { | ||||
| 		gamma_control_destroy(gamma_control); | ||||
| 	} | ||||
| 	wlr_signal_emit_safe(&manager->events.destroy, manager); | ||||
| 	wl_list_remove(&manager->display_destroy.link); | ||||
| 	wl_global_destroy(manager->global); | ||||
| 	free(manager); | ||||
| } | ||||
| 
 | ||||
| static void handle_display_destroy(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_gamma_control_manager *manager = | ||||
| 		wl_container_of(listener, manager, display_destroy); | ||||
| 	wlr_gamma_control_manager_destroy(manager); | ||||
| } | ||||
| 
 | ||||
| struct wlr_gamma_control_manager *wlr_gamma_control_manager_create( | ||||
| 		struct wl_display *display) { | ||||
| 	struct wlr_gamma_control_manager *manager = | ||||
| 		calloc(1, sizeof(struct wlr_gamma_control_manager)); | ||||
| 	if (!manager) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	struct wl_global *global = wl_global_create(display, | ||||
| 		&gamma_control_manager_interface, 1, manager, | ||||
| 		gamma_control_manager_bind); | ||||
| 	if (!global) { | ||||
| 		free(manager); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	manager->global = global; | ||||
| 
 | ||||
| 	wl_signal_init(&manager->events.destroy); | ||||
| 	wl_list_init(&manager->controls); | ||||
| 
 | ||||
| 	manager->display_destroy.notify = handle_display_destroy; | ||||
| 	wl_display_add_destroy_listener(display, &manager->display_destroy); | ||||
| 
 | ||||
| 	return manager; | ||||
| } | ||||
|  | @ -1,217 +0,0 @@ | |||
| #include <assert.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <wayland-server.h> | ||||
| #include <wlr/backend.h> | ||||
| #include <wlr/render/wlr_renderer.h> | ||||
| #include <wlr/types/wlr_output.h> | ||||
| #include <wlr/types/wlr_screenshooter.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include "screenshooter-protocol.h" | ||||
| #include "util/signal.h" | ||||
| 
 | ||||
| static struct wlr_screenshot *screenshot_from_resource( | ||||
| 		struct wl_resource *resource) { | ||||
| 	assert(wl_resource_instance_of(resource, &orbital_screenshot_interface, | ||||
| 		NULL)); | ||||
| 	return wl_resource_get_user_data(resource); | ||||
| } | ||||
| 
 | ||||
| struct screenshot_state { | ||||
| 	struct wl_shm_buffer *shm_buffer; | ||||
| 	struct wlr_screenshot *screenshot; | ||||
| 	struct wl_listener frame_listener; | ||||
| }; | ||||
| 
 | ||||
| static void screenshot_destroy(struct wlr_screenshot *screenshot) { | ||||
| 	wl_list_remove(&screenshot->link); | ||||
| 	wl_resource_set_user_data(screenshot->resource, NULL); | ||||
| 	free(screenshot); | ||||
| } | ||||
| 
 | ||||
| static void handle_screenshot_resource_destroy( | ||||
| 		struct wl_resource *screenshot_resource) { | ||||
| 	struct wlr_screenshot *screenshot = | ||||
| 		screenshot_from_resource(screenshot_resource); | ||||
| 	if (screenshot != NULL) { | ||||
| 		screenshot_destroy(screenshot); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void output_handle_frame(struct wl_listener *listener, void *_data) { | ||||
| 	struct screenshot_state *state = wl_container_of(listener, state, | ||||
| 		frame_listener); | ||||
| 	struct wlr_output *output = state->screenshot->output; | ||||
| 	struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); | ||||
| 	struct wl_shm_buffer *shm_buffer = state->shm_buffer; | ||||
| 
 | ||||
| 	if (!(output->pending.committed & WLR_OUTPUT_STATE_BUFFER)) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	enum wl_shm_format format = wl_shm_buffer_get_format(shm_buffer); | ||||
| 	int32_t width = wl_shm_buffer_get_width(shm_buffer); | ||||
| 	int32_t height = wl_shm_buffer_get_height(shm_buffer); | ||||
| 	int32_t stride = wl_shm_buffer_get_stride(shm_buffer); | ||||
| 	wl_shm_buffer_begin_access(shm_buffer); | ||||
| 	void *data = wl_shm_buffer_get_data(shm_buffer); | ||||
| 	bool ok = wlr_renderer_read_pixels(renderer, format, NULL, stride, | ||||
| 		width, height, 0, 0, 0, 0, data); | ||||
| 	wl_shm_buffer_end_access(shm_buffer); | ||||
| 
 | ||||
| 	if (!ok) { | ||||
| 		wlr_log(WLR_ERROR, "Cannot read pixels"); | ||||
| 		goto cleanup; | ||||
| 	} | ||||
| 
 | ||||
| 	orbital_screenshot_send_done(state->screenshot->resource); | ||||
| 
 | ||||
| cleanup: | ||||
| 	wl_list_remove(&listener->link); | ||||
| 	free(state); | ||||
| } | ||||
| 
 | ||||
| static const struct orbital_screenshooter_interface screenshooter_impl; | ||||
| 
 | ||||
| static struct wlr_screenshooter *screenshooter_from_resource( | ||||
| 		struct wl_resource *resource) { | ||||
| 	assert(wl_resource_instance_of(resource, &orbital_screenshooter_interface, | ||||
| 		&screenshooter_impl)); | ||||
| 	return wl_resource_get_user_data(resource); | ||||
| } | ||||
| 
 | ||||
| static void screenshooter_shoot(struct wl_client *client, | ||||
| 		struct wl_resource *screenshooter_resource, uint32_t id, | ||||
| 		struct wl_resource *output_resource, | ||||
| 		struct wl_resource *buffer_resource) { | ||||
| 	struct wlr_screenshooter *screenshooter = | ||||
| 		screenshooter_from_resource(screenshooter_resource); | ||||
| 	struct wlr_output *output = wlr_output_from_resource(output_resource); | ||||
| 
 | ||||
| 	struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); | ||||
| 	if (renderer == NULL) { | ||||
| 		wlr_log(WLR_ERROR, "Backend doesn't have a renderer"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(buffer_resource); | ||||
| 	if (shm_buffer == NULL) { | ||||
| 		wlr_log(WLR_ERROR, "Invalid buffer: not a shared memory buffer"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	int32_t width = wl_shm_buffer_get_width(shm_buffer); | ||||
| 	int32_t height = wl_shm_buffer_get_height(shm_buffer); | ||||
| 	if (width < output->width || height < output->height) { | ||||
| 		wlr_log(WLR_ERROR, "Invalid buffer: too small"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	uint32_t format = wl_shm_buffer_get_format(shm_buffer); | ||||
| 	if (!wlr_renderer_format_supported(renderer, format)) { | ||||
| 		wlr_log(WLR_ERROR, "Invalid buffer: unsupported format"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wlr_screenshot *screenshot = | ||||
| 		calloc(1, sizeof(struct wlr_screenshot)); | ||||
| 	if (!screenshot) { | ||||
| 		wl_resource_post_no_memory(screenshooter_resource); | ||||
| 		return; | ||||
| 	} | ||||
| 	screenshot->output_resource = output_resource; | ||||
| 	screenshot->output = output; | ||||
| 	screenshot->screenshooter = screenshooter; | ||||
| 	screenshot->resource = wl_resource_create(client, | ||||
| 		&orbital_screenshot_interface, | ||||
| 		wl_resource_get_version(screenshooter_resource), id); | ||||
| 	if (screenshot->resource == NULL) { | ||||
| 		free(screenshot); | ||||
| 		wl_resource_post_no_memory(screenshooter_resource); | ||||
| 		return; | ||||
| 	} | ||||
| 	wl_resource_set_implementation(screenshot->resource, NULL, screenshot, | ||||
| 		handle_screenshot_resource_destroy); | ||||
| 	wl_list_insert(&screenshooter->screenshots, &screenshot->link); | ||||
| 
 | ||||
| 	wlr_log(WLR_DEBUG, "new screenshot %p (res %p)", screenshot, | ||||
| 		screenshot->resource); | ||||
| 
 | ||||
| 	struct screenshot_state *state = calloc(1, sizeof(struct screenshot_state)); | ||||
| 	if (!state) { | ||||
| 		wl_resource_destroy(screenshot->resource); | ||||
| 		free(screenshot); | ||||
| 		wl_resource_post_no_memory(screenshooter_resource); | ||||
| 		return; | ||||
| 	} | ||||
| 	state->shm_buffer = shm_buffer; | ||||
| 	state->screenshot = screenshot; | ||||
| 	state->frame_listener.notify = output_handle_frame; | ||||
| 	wl_signal_add(&output->events.precommit, &state->frame_listener); | ||||
| 
 | ||||
| 	// Schedule a buffer commit
 | ||||
| 	output->needs_frame = true; | ||||
| 	wlr_output_schedule_frame(output); | ||||
| } | ||||
| 
 | ||||
| static const struct orbital_screenshooter_interface screenshooter_impl = { | ||||
| 	.shoot = screenshooter_shoot, | ||||
| }; | ||||
| 
 | ||||
| static void screenshooter_bind(struct wl_client *wl_client, void *data, | ||||
| 		uint32_t version, uint32_t id) { | ||||
| 	struct wlr_screenshooter *screenshooter = data; | ||||
| 	assert(wl_client && screenshooter); | ||||
| 
 | ||||
| 	struct wl_resource *wl_resource = wl_resource_create(wl_client, | ||||
| 		&orbital_screenshooter_interface, version, id); | ||||
| 	if (wl_resource == NULL) { | ||||
| 		wl_client_post_no_memory(wl_client); | ||||
| 		return; | ||||
| 	} | ||||
| 	wl_resource_set_implementation(wl_resource, &screenshooter_impl, | ||||
| 		screenshooter, NULL); | ||||
| } | ||||
| 
 | ||||
| void wlr_screenshooter_destroy(struct wlr_screenshooter *screenshooter) { | ||||
| 	if (!screenshooter) { | ||||
| 		return; | ||||
| 	} | ||||
| 	wl_list_remove(&screenshooter->display_destroy.link); | ||||
| 	struct wlr_screenshot *screenshot, *tmp; | ||||
| 	wl_list_for_each_safe(screenshot, tmp, &screenshooter->screenshots, link) { | ||||
| 		screenshot_destroy(screenshot); | ||||
| 	} | ||||
| 	wlr_signal_emit_safe(&screenshooter->events.destroy, screenshooter); | ||||
| 	wl_global_destroy(screenshooter->global); | ||||
| 	free(screenshooter); | ||||
| } | ||||
| 
 | ||||
| static void handle_display_destroy(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_screenshooter *screenshooter = | ||||
| 		wl_container_of(listener, screenshooter, display_destroy); | ||||
| 	wlr_screenshooter_destroy(screenshooter); | ||||
| } | ||||
| 
 | ||||
| struct wlr_screenshooter *wlr_screenshooter_create(struct wl_display *display) { | ||||
| 	struct wlr_screenshooter *screenshooter = | ||||
| 		calloc(1, sizeof(struct wlr_screenshooter)); | ||||
| 	if (!screenshooter) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	wl_list_init(&screenshooter->screenshots); | ||||
| 	wl_signal_init(&screenshooter->events.destroy); | ||||
| 
 | ||||
| 	screenshooter->display_destroy.notify = handle_display_destroy; | ||||
| 	wl_display_add_destroy_listener(display, &screenshooter->display_destroy); | ||||
| 
 | ||||
| 	screenshooter->global = wl_global_create(display, | ||||
| 		&orbital_screenshooter_interface, 1, screenshooter, screenshooter_bind); | ||||
| 	if (screenshooter->global == NULL) { | ||||
| 		free(screenshooter); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	return screenshooter; | ||||
| } | ||||
		Loading…
	
		Reference in New Issue