diff options
author | Drew DeVault <sir@cmpwn.com> | 2016-02-08 07:40:41 -0500 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2016-02-08 07:40:41 -0500 |
commit | 91d6113d4ad15e38308a795313da92b0ec249bcf (patch) | |
tree | 6f0227ce0465b90443355672f9fabb58ccbe5ca8 /sway | |
parent | be6455b295ed5e4ac6c6a3dc756d154c3c908e19 (diff) | |
parent | 6f7cbf2eaca42c12af9bd4a8c3cc36dc6b180517 (diff) |
Merge pull request #488 from mikkeloscar/get-pixels
Replace deprecated function wlc_output_get_pixels.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/handlers.c | 7 | ||||
-rw-r--r-- | sway/ipc-server.c | 74 |
2 files changed, 63 insertions, 18 deletions
diff --git a/sway/handlers.c b/sway/handlers.c index bb0c68e8..d3fbdc0f 100644 --- a/sway/handlers.c +++ b/sway/handlers.c @@ -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) { 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); @@ -675,7 +679,8 @@ struct wlc_interface interface = { .resolution = handle_output_resolution_change, .focus = handle_output_focused, .render = { - .pre = handle_output_pre_render + .pre = handle_output_pre_render, + .post = handle_output_post_render } }, .view = { diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 63a6d703..a63026c6 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -5,7 +5,7 @@ #include <sys/socket.h> #include <sys/un.h> #include <stdbool.h> -#include <wlc/wlc.h> +#include <wlc/wlc-render.h> #include <unistd.h> #include <stdlib.h> #include <sys/ioctl.h> @@ -38,6 +38,13 @@ struct ipc_client { 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); int ipc_handle_connection(int 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); 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); } @@ -231,21 +239,49 @@ bool output_by_name_test(swayc_t *view, void *data) { return !strcmp(name, view->name); } -bool get_pixels_callback(const struct wlc_size *size, uint8_t *rgba, void *arg) { - struct ipc_client *client = (struct ipc_client *)arg; - char response_header[9]; - memset(response_header, 0, sizeof(response_header)); - response_header[0] = 1; - uint32_t *_size = (uint32_t *)(response_header + 1); - _size[0] = size->w; - _size[1] = size->h; - size_t len = sizeof(response_header) + (size->w * size->h * 4); - char *payload = malloc(len); - memcpy(payload, response_header, sizeof(response_header)); - memcpy(payload + sizeof(response_header), rgba, len - sizeof(response_header)); - ipc_send_reply(client, payload, len); - free(payload); - return false; +void ipc_get_pixels(wlc_handle output) { + 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]; + 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; + uint32_t *_size = (uint32_t *)(response_header + 1); + _size[0] = g_out.size.w; + _size[1] = g_out.size.h; + size_t len = sizeof(response_header) + (g_out.size.w * g_out.size.h * 4); + memcpy(data, response_header, sizeof(response_header)); + ipc_send_reply(req->client, data, len); + free(data); + // free the request since it has been handled + free(req); + } + + // 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) { @@ -394,7 +430,11 @@ void ipc_client_handle_command(struct ipc_client *client) { ipc_send_reply(client, response_header, sizeof(response_header)); 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; } case IPC_GET_BAR_CONFIG: |