mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Replace deprecated function wlc_output_get_pixels.
This makes IPC GET_PIXELS use the new `wlc_pixels_read` call instead of the deprecated `wlc_output_get_pixels`. The old version worked by passing a callback function to wlc which would grab the pixels and send them to the IPC client. The new version works by maintaining a list of clients who have requested the pixels of some output and then grap and send the pixels in the output_post_render hook of the `wlc_interface`.
This commit is contained in:
		
							parent
							
								
									be6455b295
								
							
						
					
					
						commit
						6f7cbf2eac
					
				
					 3 changed files with 70 additions and 18 deletions
				
			
		| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
#ifndef _SWAY_IPC_SERVER_H
 | 
					#ifndef _SWAY_IPC_SERVER_H
 | 
				
			||||||
#define _SWAY_IPC_SERVER_H
 | 
					#define _SWAY_IPC_SERVER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <wlc/wlc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "container.h"
 | 
					#include "container.h"
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#include "ipc.h"
 | 
					#include "ipc.h"
 | 
				
			||||||
| 
						 | 
					@ -27,4 +29,9 @@ void ipc_event_modifier(uint32_t modifier, const char *state);
 | 
				
			||||||
void ipc_event_binding_keyboard(struct sway_binding *sb);
 | 
					void ipc_event_binding_keyboard(struct sway_binding *sb);
 | 
				
			||||||
const char *swayc_type_string(enum swayc_types type);
 | 
					const char *swayc_type_string(enum swayc_types type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Send pixel data to registered clients.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void ipc_get_pixels(wlc_handle output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,6 +150,10 @@ static void handle_output_pre_render(wlc_handle output) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_output_post_render(wlc_handle output) {
 | 
				
			||||||
 | 
						ipc_get_pixels(output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
 | 
					static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
 | 
				
			||||||
	sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
 | 
						sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
 | 
				
			||||||
	swayc_t *c = swayc_by_handle(output);
 | 
						swayc_t *c = swayc_by_handle(output);
 | 
				
			||||||
| 
						 | 
					@ -675,7 +679,8 @@ struct wlc_interface interface = {
 | 
				
			||||||
		.resolution = handle_output_resolution_change,
 | 
							.resolution = handle_output_resolution_change,
 | 
				
			||||||
		.focus = handle_output_focused,
 | 
							.focus = handle_output_focused,
 | 
				
			||||||
		.render = {
 | 
							.render = {
 | 
				
			||||||
			.pre = handle_output_pre_render
 | 
								.pre = handle_output_pre_render,
 | 
				
			||||||
 | 
								.post = handle_output_post_render
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	.view = {
 | 
						.view = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <sys/un.h>
 | 
					#include <sys/un.h>
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <wlc/wlc.h>
 | 
					#include <wlc/wlc-render.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <sys/ioctl.h>
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,13 @@ struct ipc_client {
 | 
				
			||||||
	enum ipc_command_type subscribed_events;
 | 
						enum ipc_command_type subscribed_events;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static list_t *ipc_get_pixel_requests = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct get_pixels_request {
 | 
				
			||||||
 | 
						struct ipc_client *client;
 | 
				
			||||||
 | 
						wlc_handle output;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sockaddr_un *ipc_user_sockaddr(void);
 | 
					struct sockaddr_un *ipc_user_sockaddr(void);
 | 
				
			||||||
int ipc_handle_connection(int fd, uint32_t mask, void *data);
 | 
					int ipc_handle_connection(int fd, uint32_t mask, void *data);
 | 
				
			||||||
int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
 | 
					int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
 | 
				
			||||||
| 
						 | 
					@ -75,6 +82,7 @@ void ipc_init(void) {
 | 
				
			||||||
	setenv("SWAYSOCK", ipc_sockaddr->sun_path, 1);
 | 
						setenv("SWAYSOCK", ipc_sockaddr->sun_path, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ipc_client_list = create_list();
 | 
						ipc_client_list = create_list();
 | 
				
			||||||
 | 
						ipc_get_pixel_requests = create_list();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ipc_event_source = wlc_event_loop_add_fd(ipc_socket, WLC_EVENT_READABLE, ipc_handle_connection, NULL);
 | 
						ipc_event_source = wlc_event_loop_add_fd(ipc_socket, WLC_EVENT_READABLE, ipc_handle_connection, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -231,21 +239,49 @@ bool output_by_name_test(swayc_t *view, void *data) {
 | 
				
			||||||
	return !strcmp(name, view->name);
 | 
						return !strcmp(name, view->name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool get_pixels_callback(const struct wlc_size *size, uint8_t *rgba, void *arg) {
 | 
					void ipc_get_pixels(wlc_handle output) {
 | 
				
			||||||
	struct ipc_client *client = (struct ipc_client *)arg;
 | 
						if (ipc_get_pixel_requests->length == 0) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_t *unhandled = create_list();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct get_pixels_request *req;
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						for (i = 0; i < ipc_get_pixel_requests->length; ++i) {
 | 
				
			||||||
 | 
							req = ipc_get_pixel_requests->items[i];
 | 
				
			||||||
 | 
							if (req->output != output) {
 | 
				
			||||||
 | 
								list_add(unhandled, req);
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const struct wlc_size *size = wlc_output_get_resolution(req->output);
 | 
				
			||||||
 | 
							struct wlc_geometry g = {
 | 
				
			||||||
 | 
								.size = *size,
 | 
				
			||||||
 | 
								.origin = { 0, 0 },
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							struct wlc_geometry g_out;
 | 
				
			||||||
		char response_header[9];
 | 
							char response_header[9];
 | 
				
			||||||
		memset(response_header, 0, sizeof(response_header));
 | 
							memset(response_header, 0, sizeof(response_header));
 | 
				
			||||||
 | 
							char *data = malloc(sizeof(response_header) + size->w * size->h * 4);
 | 
				
			||||||
 | 
							wlc_pixels_read(WLC_RGBA8888, &g, &g_out, data + sizeof(response_header));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		response_header[0] = 1;
 | 
							response_header[0] = 1;
 | 
				
			||||||
		uint32_t *_size = (uint32_t *)(response_header + 1);
 | 
							uint32_t *_size = (uint32_t *)(response_header + 1);
 | 
				
			||||||
	_size[0] = size->w;
 | 
							_size[0] = g_out.size.w;
 | 
				
			||||||
	_size[1] = size->h;
 | 
							_size[1] = g_out.size.h;
 | 
				
			||||||
	size_t len = sizeof(response_header) + (size->w * size->h * 4);
 | 
							size_t len = sizeof(response_header) + (g_out.size.w * g_out.size.h * 4);
 | 
				
			||||||
	char *payload = malloc(len);
 | 
							memcpy(data, response_header, sizeof(response_header));
 | 
				
			||||||
	memcpy(payload, response_header, sizeof(response_header));
 | 
							ipc_send_reply(req->client, data, len);
 | 
				
			||||||
	memcpy(payload + sizeof(response_header), rgba, len - sizeof(response_header));
 | 
							free(data);
 | 
				
			||||||
	ipc_send_reply(client, payload, len);
 | 
							// free the request since it has been handled
 | 
				
			||||||
	free(payload);
 | 
							free(req);
 | 
				
			||||||
	return false;
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// free old list of pixel requests and set new list to all unhandled
 | 
				
			||||||
 | 
						// requests (request for another output).
 | 
				
			||||||
 | 
						list_free(ipc_get_pixel_requests);
 | 
				
			||||||
 | 
						ipc_get_pixel_requests = unhandled;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ipc_client_handle_command(struct ipc_client *client) {
 | 
					void ipc_client_handle_command(struct ipc_client *client) {
 | 
				
			||||||
| 
						 | 
					@ -394,7 +430,11 @@ void ipc_client_handle_command(struct ipc_client *client) {
 | 
				
			||||||
			ipc_send_reply(client, response_header, sizeof(response_header));
 | 
								ipc_send_reply(client, response_header, sizeof(response_header));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		wlc_output_get_pixels(output->handle, get_pixels_callback, client);
 | 
							struct get_pixels_request *req = malloc(sizeof(struct get_pixels_request));
 | 
				
			||||||
 | 
							req->client = client;
 | 
				
			||||||
 | 
							req->output = output->handle;
 | 
				
			||||||
 | 
							list_add(ipc_get_pixel_requests, req);
 | 
				
			||||||
 | 
							wlc_output_schedule_render(output->handle);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	case IPC_GET_BAR_CONFIG:
 | 
						case IPC_GET_BAR_CONFIG:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue