From ddc6bde14ef20069c65a933cde3a677959f607cb Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Wed, 2 Nov 2022 18:46:22 -0400 Subject: Fix dmabuf-feedback event ordering --- src/handlers.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/handlers.c b/src/handlers.c index e7ea460..8db31eb 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -1560,27 +1560,22 @@ void do_zwp_linux_dmabuf_feedback_v1_evt_done(struct context *ctx) /* Inject messages for filtered tranche parameters here */ size_t m = 0; for (size_t i = 0; i < obj->tranche_count; i++) { - ctx->message[m] = obj->base.obj_id; - - size_t w = 0; - uint16_t *fmts = (uint16_t *)&ctx->message[m + 3]; + bool empty = true; for (size_t j = 0; j < obj->tranches[i].tranche_size; j++) { uint16_t idx = obj->tranches[i].tranche[j]; if (dmabuf_format_permitted(ctx, obj->table[idx].format, obj->table[idx].modifier)) { - fmts[w++] = idx; + empty = false; + break; } } - if (w == 0) { + + if (empty) { /* discard tranche, has no entries */ continue; } - size_t s = 3 + ((w + 1) / 2); - ctx->message[m + 1] = message_header_2( - 4 * (uint32_t)s, 5); // tranche_formats - ctx->message[m + 2] = (uint32_t)(2 * w); - m += s; + size_t s; s = 3 + ((sizeof(dev_t) + 3) / 4); ctx->message[m] = obj->base.obj_id; @@ -1597,6 +1592,22 @@ void do_zwp_linux_dmabuf_feedback_v1_evt_done(struct context *ctx) ctx->message[m + 2] = obj->tranches[i].flags; m += s; + size_t w = 0; + uint16_t *fmts = (uint16_t *)&ctx->message[m + 3]; + for (size_t j = 0; j < obj->tranches[i].tranche_size; j++) { + uint16_t idx = obj->tranches[i].tranche[j]; + if (dmabuf_format_permitted(ctx, obj->table[idx].format, + obj->table[idx].modifier)) { + fmts[w++] = idx; + } + } + s = 3 + ((w + 1) / 2); + ctx->message[m] = obj->base.obj_id; + ctx->message[m + 1] = message_header_2( + 4 * (uint32_t)s, 5); // tranche_formats + ctx->message[m + 2] = (uint32_t)(2 * w); + m += s; + s = 2; ctx->message[m] = obj->base.obj_id; ctx->message[m + 1] = message_header_2( -- cgit v1.2.3 From 669ae3da0c7200392bd7c0513eeae6ec48708a2c Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sat, 5 Nov 2022 22:35:38 -0400 Subject: Update issue filing guidelines --- README.md | 52 +++++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 5ec7c00..5cda76d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ serializes changes to shared memory buffers over a single socket. This makes application forwarding similar to `ssh -X` [1] feasible. [0] [https://wayland.freedesktop.org/](https://wayland.freedesktop.org/) -[1] [https://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-to-run-graphics-applications-remotely](https://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-to-run-graphics-applications-remotely) +[1] [https://wiki.archlinux.org/title/OpenSSH#X11_forwarding](https://wiki.archlinux.org/title/OpenSSH#X11_forwarding) ## Usage @@ -65,35 +65,36 @@ Optional dependencies: [0] [https://mesonbuild.com/](https://mesonbuild.com/) [1] [https://git.sr.ht/~sircmpwn/scdoc](https://git.sr.ht/~sircmpwn/scdoc) -## Status +## Reporting issues -This program is now relatively stable, with no large changes to the -command line interface or wire format expected. Features like video -encoding, multiplanar and tiled DMABUFs, and support for newer Wayland -protocols are less well tested and more likely to break between minor -versions. +Waypipe is developed at [0]; file bug reports or submit patches here. -Waypipe is developed at [1]; file bug reports or submit patches here. +In general, if a program does not work properly under Waypipe, it is a bug +worth reporting. If possible, before doing so ensure both computers are using +the most recently released version of Waypipe (or are built from git master). -The wire format most recently changed with version 0.7.0, and is not -compatible with earlier versions of Waypipe. Both the client and -server sides of a connection must have a feature in order for it to work; -for example, if the local copy of Waypipe was built without LZ4 support, -and the remote copy has the `--compress lz4` option set, the connection -may fail at some point. +A workaround that may help for some programs using OpenGL or Vulkan is to +run Waypipe with the `--no-gpu` flag, which may force them to use software +rendering and shared memory buffers. (Please still file a bug.) -Any of the following may make waypipe crash with an error message. If -it segfaults, file a bug report! +Some programs may require specific environment variable settings or command +line flags to run remotely; a few examples are given in the man page[1]. -* Different local/client and remote/server versions or capabilities -* Differing byte orders -* Applications using unexpected protocols that pass file descriptors; file - bug reports for these +Useful information for bug reports includes: -[0] [https://mstoeckl.com/notes/gsoc/blog.html](https://mstoeckl.com/notes/gsoc/blog.html) -[1] [https://gitlab.freedesktop.org/mstoeckl/waypipe/](https://gitlab.freedesktop.org/mstoeckl/waypipe/) +* If a Waypipe process has crashed on either end of the connection, + a full stack trace, with debug symbols. (In gdb, `bt full`). +* If the program uses OpenGL or Vulkan, the graphics cards and drivers on + both computers. +* The output of `waypipe --version` on both ends of the connection +* Logs when Waypipe is run with the `--debug` flag, or when the program + is run with the environment variable setting `WAYLAND_DEBUG=1`. +* Screenshots of any visual glitches. -## Limitations +[0] [https://gitlab.freedesktop.org/mstoeckl/waypipe/](https://gitlab.freedesktop.org/mstoeckl/waypipe/) +[1] [https://gitlab.freedesktop.org/mstoeckl/waypipe/-/blob/master/waypipe.scd](https://gitlab.freedesktop.org/mstoeckl/waypipe/-/blob/master/waypipe.scd) + +## Technical Limitations Waypipe does not have a full view of the Wayland protocol. It includes a compiled form of the base protocol and several extension protocols, but is not @@ -127,3 +128,8 @@ each buffer that is used by a window surface. Since surfaces typically rotate between a small number of buffers, a video encoded window will appear to flicker as it switches rapidly between the underlying buffers, each of whose video streams has different encoding artifacts. + +The `zwp_linux_explicit_synchronization_v1` Wayland protocol is currently not +supported. + +Waypipe does not work between computers that use different byte orders. -- cgit v1.2.3 From cc09a5c68d6bb350c1e66245f2f7cb04d4dc4b93 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Fri, 25 Nov 2022 19:57:23 -0500 Subject: Avoid acquiring controlling terminal Waypipe never has a reason to do this, so ensure it can't even accidentally happen by adding O_NOCTTY. --- src/dmabuf.c | 2 +- src/server.c | 5 +++-- src/waypipe.c | 2 +- test/common.c | 2 +- test/fuzz_hook_det.c | 3 ++- test/fuzz_hook_ext.c | 3 ++- test/fuzz_hook_int.c | 3 ++- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/dmabuf.c b/src/dmabuf.c index 7b8126e..b3718be 100644 --- a/src/dmabuf.c +++ b/src/dmabuf.c @@ -120,7 +120,7 @@ int init_render_data(struct render_data *data) const char *card = data->drm_node_path ? data->drm_node_path : "/dev/dri/renderD128"; - int drm_fd = open(card, O_RDWR | O_CLOEXEC); + int drm_fd = open(card, O_RDWR | O_CLOEXEC | O_NOCTTY); if (drm_fd == -1) { wp_error("Failed to open drm fd for %s: %s", card, strerror(errno)); diff --git a/src/server.c b/src/server.c index 1deef89..8723d7e 100644 --- a/src/server.c +++ b/src/server.c @@ -87,7 +87,7 @@ static void fill_random_key(struct connection_token *token) token->key[1] += 1 + (uint32_t)tp.tv_sec; token->key[2] += 2 + (uint32_t)tp.tv_nsec; - int devrand = open("/dev/urandom", O_RDONLY); + int devrand = open("/dev/urandom", O_RDONLY | O_NOCTTY); if (devrand != -1) { uint32_t tmp[3]; errno = 0; @@ -737,7 +737,8 @@ int run_server(int cwd_fd, struct socket_path socket_path, /* To prevent getting POLLHUP spam after the first user * closes this pipe, open both read and write ends of * the named pipe */ - control_pipe = open(control_path, O_RDWR | O_NONBLOCK); + control_pipe = open(control_path, + O_RDWR | O_NONBLOCK | O_NOCTTY); if (control_pipe == -1) { wp_error("Failed to open created FIFO for reading: %s", control_path, strerror(errno)); diff --git a/src/waypipe.c b/src/waypipe.c index adbe048..afbfde8 100644 --- a/src/waypipe.c +++ b/src/waypipe.c @@ -292,7 +292,7 @@ static int run_recon(const char *control_path, const char *recon_path) control_path, (int)len, 108); return EXIT_FAILURE; } - int cfd = open(control_path, O_WRONLY); + int cfd = open(control_path, O_WRONLY | O_NOCTTY); if (cfd == -1) { fprintf(stderr, "Failed to open control pipe at \"%s\"\n", control_path); diff --git a/test/common.c b/test/common.c index 44924e7..ec1c8d3 100644 --- a/test/common.c +++ b/test/common.c @@ -39,7 +39,7 @@ uint64_t local_time_offset = 0; void *read_file_into_mem(const char *path, size_t *len) { - int fd = open(path, O_RDONLY); + int fd = open(path, O_RDONLY | O_NOCTTY); if (fd == -1) { fprintf(stderr, "Failed to open '%s'", path); return NULL; diff --git a/test/fuzz_hook_det.c b/test/fuzz_hook_det.c index a9443d2..b3d47b6 100644 --- a/test/fuzz_hook_det.c +++ b/test/fuzz_hook_det.c @@ -89,7 +89,8 @@ int main(int argc, char **argv) uint32_t fsize = data[cursor++]; if (fsize == 0) { /* 'copy' sink */ - new_fileno = open("/dev/null", O_WRONLY); + new_fileno = open("/dev/null", + O_WRONLY | O_NOCTTY); if (new_fileno == -1) { wp_error("Failed to open /dev/null"); } diff --git a/test/fuzz_hook_ext.c b/test/fuzz_hook_ext.c index a53f08f..aea177b 100644 --- a/test/fuzz_hook_ext.c +++ b/test/fuzz_hook_ext.c @@ -133,7 +133,8 @@ int main(int argc, char **argv) uint32_t fsize = data[cursor++]; if (fsize == 0) { /* 'copy' sink */ - new_fileno = open("/dev/null", O_WRONLY); + new_fileno = open("/dev/null", + O_WRONLY | O_NOCTTY); if (new_fileno == -1) { wp_error("Failed to open /dev/null"); } diff --git a/test/fuzz_hook_int.c b/test/fuzz_hook_int.c index 53ac711..f3058b3 100644 --- a/test/fuzz_hook_int.c +++ b/test/fuzz_hook_int.c @@ -131,7 +131,8 @@ int main(int argc, char **argv) uint32_t fsize = data[cursor++]; if (fsize == 0) { /* 'copy' sink */ - new_fileno = open("/dev/null", O_WRONLY); + new_fileno = open("/dev/null", + O_WRONLY | O_NOCTTY); if (new_fileno == -1) { wp_error("Failed to open /dev/null"); } -- cgit v1.2.3 From d731037211b834840adf10d2cafb4f1eb072679b Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sat, 28 Jan 2023 21:07:54 -0500 Subject: Provide dmabuf main device from opened drm fd --- src/handlers.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/handlers.c b/src/handlers.c index 8db31eb..6c789ee 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -1666,6 +1667,7 @@ void do_zwp_linux_dmabuf_feedback_v1_evt_format_table( void do_zwp_linux_dmabuf_feedback_v1_evt_main_device(struct context *ctx, uint32_t device_count, const uint8_t *device_val) { + struct obj_zwp_linux_dmabuf_feedback *obj = (struct obj_zwp_linux_dmabuf_feedback *)ctx->obj; if ((size_t)device_count != sizeof(dev_t)) { @@ -1673,7 +1675,20 @@ void do_zwp_linux_dmabuf_feedback_v1_evt_main_device(struct context *ctx, (size_t)device_count, sizeof(dev_t)); return; } - memcpy(&obj->main_device, device_val, sizeof(dev_t)); + + if (ctx->on_display_side) { + memcpy(&obj->main_device, device_val, sizeof(dev_t)); + } else { + // adopt the main device from the render fd being used + struct stat fsdata; + memset(&fsdata, 0, sizeof(fsdata)); + int ret = fstat(ctx->g->render.drm_fd, &fsdata); + if (ret == -1) { + wp_error("Failed to get render device info"); + return; + } + obj->main_device = fsdata.st_rdev; + } /* todo: add support for changing render devices in waypipe */ } @@ -1681,7 +1696,7 @@ void do_zwp_linux_dmabuf_feedback_v1_evt_tranche_done(struct context *ctx) { struct obj_zwp_linux_dmabuf_feedback *obj = (struct obj_zwp_linux_dmabuf_feedback *)ctx->obj; - if (obj->main_device != obj->current_device) { + if (obj->main_device != obj->current_device && ctx->on_display_side) { /* Filter out/ignore all tranches for anything but the main * device. */ return; -- cgit v1.2.3 From 6e3034620c4bcb0357728cc607dfae3344e4895c Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sat, 4 Feb 2023 11:05:36 -0500 Subject: Allow --drm-node option in ssh and client modes --- src/waypipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/waypipe.c b/src/waypipe.c index afbfde8..9e30f92 100644 --- a/src/waypipe.c +++ b/src/waypipe.c @@ -430,7 +430,7 @@ static const struct arg_permissions arg_permissions[] = { {ARG_VERSION, MODE_FAIL}, {ARG_ALLOW_TILED, MODE_SSH | MODE_CLIENT | MODE_SERVER}, {ARG_UNLINK, MODE_SERVER}, - {ARG_DRMNODE, MODE_SERVER}, + {ARG_DRMNODE, MODE_SSH | MODE_CLIENT | MODE_SERVER}, {ARG_REMOTENODE, MODE_SSH}, {ARG_WAYPIPE_BINARY, MODE_SSH}, {ARG_LOGIN_SHELL, MODE_SERVER}, -- cgit v1.2.3 From 028f11df79f8f68c4a6c93829a28cae0391ca4a5 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Fri, 10 Mar 2023 20:56:44 -0500 Subject: Fix a crash with ffmpeg 6.0 --- src/video.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/video.c b/src/video.c index 2fe019a..4ca6d14 100644 --- a/src/video.c +++ b/src/video.c @@ -375,12 +375,11 @@ static int setup_vaapi_pipeline(struct shadow_fd *sfd, struct render_data *rd, static void cleanup_vaapi_pipeline(struct shadow_fd *sfd) { - if (!sfd->video_context) { - return; - } - if (!sfd->video_context->hw_device_ctx) { + if (!sfd->video_va_surface && !sfd->video_va_context && + !sfd->video_va_pipeline) { return; } + AVHWDeviceContext *vwdc = (AVHWDeviceContext *) sfd->video_context->hw_device_ctx->data; -- cgit v1.2.3 From 7a174f16f4a4da396529c5de66eb010eaeef86e5 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sat, 11 Mar 2023 09:05:40 -0500 Subject: Bump version --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index d53e7d8..b907ac1 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project( 'warning_level=3', 'werror=true', ], - version: '0.8.4', + version: '0.8.5', ) # DEFAULT_SOURCE implies POSIX_C_SOURCE 200809L + extras like CMSG_LEN -- cgit v1.2.3 From 7066e82a3706aaaec9b02eba746c7f6f99d237e5 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Thu, 23 Mar 2023 20:23:11 -0400 Subject: Avoid duplicate video encode setup --- src/video.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/video.c b/src/video.c index 4ca6d14..ff77fcb 100644 --- a/src/video.c +++ b/src/video.c @@ -852,6 +852,12 @@ fail_alignment: int setup_video_encode(struct shadow_fd *sfd, struct render_data *rd) { + if (sfd->video_context) { + wp_error("Video context already set up for sfd RID=%d", + sfd->remote_id); + return -1; + } + bool has_hw = init_hwcontext(rd) == 0; /* Attempt hardware encoding, and if it doesn't succeed, fall back * to software encoding */ -- cgit v1.2.3 From 7cf6271a90d889dca5b73759ea698f180903431c Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sat, 25 Mar 2023 10:11:49 -0400 Subject: Log when metadata messages received --- src/mainloop.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mainloop.c b/src/mainloop.c index 181319c..843de05 100644 --- a/src/mainloop.c +++ b/src/mainloop.c @@ -271,7 +271,7 @@ static int interpret_chanmsg(struct chan_msg_state *cmsg, } } else if (type == WMSG_RESTART) { struct wmsg_restart *ackm = (struct wmsg_restart *)packet; - wp_debug("Received restart message: remote last saw ack %d (we last recvd %d, acked %d)", + wp_debug("Received WMSG_RESTART: remote last saw ack %d (we last recvd %d, acked %d)", ackm->last_ack_received, cxs->last_received_msgno, cxs->last_acked_msgno); @@ -279,6 +279,8 @@ static int interpret_chanmsg(struct chan_msg_state *cmsg, return 0; } else if (type == WMSG_ACK_NBLOCKS) { struct wmsg_ack *ackm = (struct wmsg_ack *)packet; + wp_debug("Received WMSG_ACK_NBLOCKS: remote recvd %u", + ackm->messages_received); if (msgno_gt(ackm->messages_received, cxs->last_received_msgno)) { cxs->last_confirmed_msgno = ackm->messages_received; @@ -301,6 +303,7 @@ static int interpret_chanmsg(struct chan_msg_state *cmsg, const int32_t *fds = &((const int32_t *)packet)[1]; int nfds = (int)((unpadded_size - sizeof(uint32_t)) / sizeof(int32_t)); + wp_debug("Received WMSG_INJECT_RIDS with %d fds", nfds); if (buf_ensure_size(nfds, sizeof(int), &cmsg->transf_fds.size, (void **)&cmsg->transf_fds.data) == -1) { @@ -333,6 +336,8 @@ static int interpret_chanmsg(struct chan_msg_state *cmsg, * guaranteed that all file descriptors provided will be used by * the messages. This makes fd handling more complicated. */ int protosize = (int)(unpadded_size - sizeof(uint32_t)); + wp_debug("Received WMSG_PROTOCOL with %d bytes of messages", + protosize); // TODO: have message editing routines ensure size, so // that this limit can be tighter if (buf_ensure_size(protosize + 1024, 1, -- cgit v1.2.3 From 60fb837e91ed50e7d490cbcd564d8b57b4bf78b5 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sat, 25 Mar 2023 10:12:07 -0400 Subject: Move acknowledgement logic to separate function --- src/mainloop.c | 149 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 75 insertions(+), 74 deletions(-) diff --git a/src/mainloop.c b/src/mainloop.c index 843de05..4f14379 100644 --- a/src/mainloop.c +++ b/src/mainloop.c @@ -692,6 +692,80 @@ static int partial_write_transfer(int chanfd, struct transfer_queue *td, return 0; } +static int inject_acknowledge( + struct way_msg_state *wmsg, struct cross_state *cxs) +{ + if (transfer_ensure_size(&wmsg->transfers, wmsg->transfers.end + 1) == + -1) { + wp_error("Failed to allocate space for ack message transfer"); + return -1; + } + /* To avoid infinite regress, receive acknowledgement + * messages do not themselves increase the message counters. */ + uint32_t ack_msgno; + if (wmsg->transfers.start == wmsg->transfers.end) { + ack_msgno = wmsg->transfers.last_msgno; + } else { + ack_msgno = wmsg->transfers.meta[wmsg->transfers.start].msgno; + } + + /* This is the next point where messages can be changed */ + int next_slot = (wmsg->transfers.partial_write_amt > 0) + ? wmsg->transfers.start + 1 + : wmsg->transfers.start; + struct wmsg_ack *not_in_prog_msg = NULL; + struct wmsg_ack *queued_msg = NULL; + for (size_t i = 0; i < 2; i++) { + if (wmsg->transfers.partial_write_amt > 0 && + wmsg->transfers.vecs[wmsg->transfers.start] + .iov_base == + &wmsg->ack_msgs[i]) { + not_in_prog_msg = &wmsg->ack_msgs[1 - i]; + } + if (next_slot < wmsg->transfers.end && + wmsg->transfers.vecs[next_slot].iov_base == + &wmsg->ack_msgs[i]) { + queued_msg = &wmsg->ack_msgs[i]; + } + } + + if (!queued_msg) { + /* Insert a message--which is not partially written-- + * in the next available slot, pushing forward other + * messages */ + if (!not_in_prog_msg) { + queued_msg = &wmsg->ack_msgs[0]; + } else { + queued_msg = not_in_prog_msg; + } + + if (next_slot < wmsg->transfers.end) { + size_t nmoved = (size_t)(wmsg->transfers.end - + next_slot); + memmove(wmsg->transfers.vecs + next_slot + 1, + wmsg->transfers.vecs + next_slot, + sizeof(*wmsg->transfers.vecs) * nmoved); + memmove(wmsg->transfers.meta + next_slot + 1, + wmsg->transfers.meta + next_slot, + sizeof(*wmsg->transfers.meta) * nmoved); + } + wmsg->transfers.vecs[next_slot].iov_len = + sizeof(struct wmsg_ack); + wmsg->transfers.vecs[next_slot].iov_base = queued_msg; + wmsg->transfers.meta[next_slot].msgno = ack_msgno; + wmsg->transfers.meta[next_slot].static_alloc = true; + wmsg->transfers.end++; + } + + /* Modify the message which is now next up in the transfer + * queue */ + queued_msg->size_and_type = transfer_header( + sizeof(struct wmsg_ack), WMSG_ACK_NBLOCKS); + queued_msg->messages_received = cxs->last_received_msgno; + cxs->last_acked_msgno = cxs->last_received_msgno; + return 0; +} + static int advance_waymsg_chanwrite(struct way_msg_state *wmsg, struct cross_state *cxs, struct globals *g, int chanfd, bool display_side) @@ -706,80 +780,7 @@ static int advance_waymsg_chanwrite(struct way_msg_state *wmsg, /* Acknowledge the other side's transfers as soon as possible */ if (cxs->last_acked_msgno != cxs->last_received_msgno) { - if (transfer_ensure_size(&wmsg->transfers, - wmsg->transfers.end + 1) == -1) { - wp_error("Failed to allocate space for ack message transfer"); - goto ackmsg_fail; - } - /* To avoid infinite regress, receive acknowledgement - * messages do not themselves increase the message counters. */ - uint32_t ack_msgno; - if (wmsg->transfers.start == wmsg->transfers.end) { - ack_msgno = wmsg->transfers.last_msgno; - } else { - ack_msgno = wmsg->transfers.meta[wmsg->transfers.start] - .msgno; - } - - /* This is the next point where messages can be changed */ - int next_slot = (wmsg->transfers.partial_write_amt > 0) - ? wmsg->transfers.start + 1 - : wmsg->transfers.start; - struct wmsg_ack *not_in_prog_msg = NULL; - struct wmsg_ack *queued_msg = NULL; - for (size_t i = 0; i < 2; i++) { - if (wmsg->transfers.partial_write_amt > 0 && - wmsg->transfers.vecs[wmsg->transfers.start] - .iov_base == - &wmsg->ack_msgs[i]) { - not_in_prog_msg = &wmsg->ack_msgs[1 - i]; - } - if (next_slot < wmsg->transfers.end && - wmsg->transfers.vecs[next_slot].iov_base == - &wmsg->ack_msgs[i]) { - queued_msg = &wmsg->ack_msgs[i]; - } - } - - if (!queued_msg) { - /* Insert a message--which is not partially written-- - * in the next available slot, pushing forward other - * messages */ - if (!not_in_prog_msg) { - queued_msg = &wmsg->ack_msgs[0]; - } else { - queued_msg = not_in_prog_msg; - } - - if (next_slot < wmsg->transfers.end) { - size_t nmoved = (size_t)(wmsg->transfers.end - - next_slot); - memmove(wmsg->transfers.vecs + next_slot + 1, - wmsg->transfers.vecs + - next_slot, - sizeof(*wmsg->transfers.vecs) * - nmoved); - memmove(wmsg->transfers.meta + next_slot + 1, - wmsg->transfers.meta + - next_slot, - sizeof(*wmsg->transfers.meta) * - nmoved); - } - wmsg->transfers.vecs[next_slot].iov_len = - sizeof(struct wmsg_ack); - wmsg->transfers.vecs[next_slot].iov_base = queued_msg; - wmsg->transfers.meta[next_slot].msgno = ack_msgno; - wmsg->transfers.meta[next_slot].static_alloc = true; - wmsg->transfers.end++; - } - - /* Modify the message which is now next up in the transfer - * queue */ - queued_msg->size_and_type = transfer_header( - sizeof(struct wmsg_ack), WMSG_ACK_NBLOCKS); - queued_msg->messages_received = cxs->last_received_msgno; - cxs->last_acked_msgno = cxs->last_received_msgno; - ackmsg_fail:; + (void)inject_acknowledge(wmsg, cxs); } int ret = partial_write_transfer(chanfd, &wmsg->transfers, -- cgit v1.2.3 From 9070c4c527c906cb186588ca410d92d2f7f3c7ba Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sat, 25 Mar 2023 10:29:26 -0400 Subject: Fix a memory leak This was introduced by a0f6bfa191f55b99e4ff68dd0063aa0c0e12dcbd incorrectly checking when to increase the value of cxs->last_confirmed_msgno. As a result, one of the two Waypipe processes would leak all the messages sent to the other process. --- src/mainloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainloop.c b/src/mainloop.c index 4f14379..a91a197 100644 --- a/src/mainloop.c +++ b/src/mainloop.c @@ -282,7 +282,7 @@ static int interpret_chanmsg(struct chan_msg_state *cmsg, wp_debug("Received WMSG_ACK_NBLOCKS: remote recvd %u", ackm->messages_received); if (msgno_gt(ackm->messages_received, - cxs->last_received_msgno)) { + cxs->last_confirmed_msgno)) { cxs->last_confirmed_msgno = ackm->messages_received; } return 0; -- cgit v1.2.3 From 4e6cde7f1e58adc1a9d721c638a01291777bf5d1 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sun, 26 Mar 2023 14:02:27 -0400 Subject: Disable CI --- .gitlab-ci.yml | 75 ---------------------- .gitlab-ci/debian-install.sh | 15 ----- .gitlab-ci/debian32-install.sh | 17 ----- .gitlab-ci/debian32.yml | 141 ----------------------------------------- 4 files changed, 248 deletions(-) delete mode 100644 .gitlab-ci.yml delete mode 100644 .gitlab-ci/debian-install.sh delete mode 100644 .gitlab-ci/debian32-install.sh delete mode 100644 .gitlab-ci/debian32.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 631e69d..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,75 +0,0 @@ - -variables: - UPSTREAM_REPO: mstoeckl/waypipe - - DEBIAN_TAG: '2019-06-25.1' - DEBIAN_VERSION: buster - DEBIAN_EXEC: 'bash .gitlab-ci/debian-install.sh' - DEBIAN_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG - - DEBIAN32_TAG: 'deb32-2019-07-04.2' - DEBIAN32_VERSION: buster - DEBIAN32_EXEC: 'bash .gitlab-ci/debian32-install.sh' - DEBIAN32_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/debian/$DEBIAN32_VERSION:$DEBIAN32_TAG - -include: - - project: 'wayland/ci-templates' - ref: 96912c7331cbc6da41fbf22c4217aa541176f063 - file: '/templates/debian.yml' - - project: 'mstoeckl/waypipe' - file: '/.gitlab-ci/debian32.yml' - ref: master - -stages: - - container_prep - - build - -debian_container_prep: - extends: .debian@container-ifnot-exists - stage: container_prep - -debian32_container_prep: - extends: .debian32@container-ifnot-exists - stage: container_prep - -.build-debian-all: - stage: build - script: - - export PATH=~/.local/bin:$PATH - - cd "$BUILDDIR" - - meson --prefix="$PREFIX" -Dwerror=true .. - - ninja -k0 - - ninja install - - ninja test - - ninja clean - artifacts: - name: waypipe-$CI_COMMIT_SHA-$CI_JOB_ID - when: always - paths: - - b-*/meson-logs - - b-*/run - - p-* - -debian-build: - before_script: - - export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)" - - export BUILD_ID="$CI_COMMIT_SHA-$CI_JOB_ID" - - export PREFIX="$(pwd)/p-$BUILD_ID" - - export BUILDDIR="$(pwd)/b-$BUILD_ID" - - mkdir "$BUILDDIR" "$PREFIX" - - export CC=gcc - extends: .build-debian-all - image: $DEBIAN_CONTAINER_IMAGE - -debian32-build: - before_script: - - export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)" - - export BUILD_ID="$CI_COMMIT_SHA-$CI_JOB_ID" - - export PREFIX="$(pwd)/p-$BUILD_ID" - - export BUILDDIR="$(pwd)/b-$BUILD_ID" - - mkdir "$BUILDDIR" "$PREFIX" - - export CC=/usr/bin/gcc-8 - - export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig/ - extends: .build-debian-all - image: $DEBIAN32_CONTAINER_IMAGE - diff --git a/.gitlab-ci/debian-install.sh b/.gitlab-ci/debian-install.sh deleted file mode 100644 index 03287d3..0000000 --- a/.gitlab-ci/debian-install.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -set -e -o xtrace - -apt-get update -apt-get -y --no-install-recommends install \ - build-essential git automake autoconf libtool pkg-config libexpat1-dev \ - libffi-dev libxml2-dev mesa-common-dev libglu1-mesa-dev libegl1-mesa-dev \ - libgles2-mesa-dev libwayland-dev libudev-dev libgbm-dev libxkbcommon-dev \ - libvpx-dev libva-dev curl python3-pip python3-setuptools ninja-build weston \ - liblz4-dev libzstd-dev wayland-protocols libavcodec-dev libavutil-dev \ - libswscale-dev - -pip3 install --user git+https://github.com/mesonbuild/meson.git@0.47 - diff --git a/.gitlab-ci/debian32-install.sh b/.gitlab-ci/debian32-install.sh deleted file mode 100644 index 00fc7ea..0000000 --- a/.gitlab-ci/debian32-install.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -e -o xtrace - -dpkg --print-foreign-architectures -dpkg --add-architecture i386 - -apt-get update - -# Actual package dependencies -apt-get -y --no-install-recommends install wayland-protocols:i386 pkg-config:i386 libwayland-dev:i386 libgbm-dev:i386 liblz4-dev:i386 libzstd-dev:i386 libavcodec-dev:i386 libavutil-dev:i386 libswscale-dev:i386 weston:i386 libdrm-dev:i386 -apt-get -y --no-install-recommends install gcc-8-multilib:i386 gcc-8:i386 make:i386 - -# Build scripts, architecture doesn't matter -apt-get -y --no-install-recommends install git python3-pip python3-wheel python3-setuptools ninja-build scdoc -pip3 install --user git+https://github.com/mesonbuild/meson.git@0.47 - diff --git a/.gitlab-ci/debian32.yml b/.gitlab-ci/debian32.yml deleted file mode 100644 index 6e250b9..0000000 --- a/.gitlab-ci/debian32.yml +++ /dev/null @@ -1,141 +0,0 @@ -# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0: - -# This template will create a debian image based on the following variables: -# -# - DEBIAN_VERSION: the debian version (stretch, sid, etc...) -# - DEBIAN_DEBS: if set, list of packages that needs to be installed -# - DEBIAN_EXEC: if set, this command will be run once the packages have -# been installed -# - UPSTREAM_REPO: the upstream project on this gitlab instance where we might -# find the given tag (for example: `wayland/weston`) -# - DEBIAN_TAG: tag to copy the image from the upstream registry. If the -# tag does not exist, create a new build and tag it -# -# The resulting image will be pushed in the local registry, under: -# $CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG -# -# Two flavors of templates are available: -# - `.debian32@container-build`: this will force rebuild a new container -# and tag it with $DEBIAN_TAG without checks -# - `.debian32@container-ifnot-exists`: this will rebuild a new container -# only if $DEBIAN_TAG is not available in the local registry or -# in the $UPSTREAM_REPO registry - -# we can not reuse exported variables in after_script, -# so have a common definition -.debian32_vars: &distro_vars | - # exporting templates variables - # https://gitlab.com/gitlab-com/support-forum/issues/4349 - export BUILDAH_FORMAT=docker - # The '32' version should run multilib - export DISTRO=debian - export DISTRO_TAG=$DEBIAN32_TAG - export DISTRO_VERSION=$DEBIAN32_VERSION - export DISTRO_EXEC=$DEBIAN32_EXEC - - -# Do not use this template directly, you can not reuse the produced image -# as it is tagged with $CI_JOB_ID -..debian32@container-template: - image: $CI_REGISTRY/wayland/ci-templates/buildah:latest - stage: build - before_script: - # log in to the registry - - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - - *distro_vars - - script: - - *distro_vars - - echo Building $DISTRO/$DISTRO_VERSION:$DISTRO_TAG from $DISTRO:$DISTRO_VERSION - # initial set up: take the base image, update it and install the packages - - buildcntr=$(buildah from $DISTRO:$DISTRO_VERSION) - - buildmnt=$(buildah mount $buildcntr) - - buildah run $buildcntr cat /etc/apt/sources.list - - echo 'path-exclude=/usr/share/doc/*' > $buildmnt/etc/dpkg/dpkg.cfg.d/99-exclude-cruft - - echo 'path-exclude=/usr/share/locale/*' >> $buildmnt/etc/dpkg/dpkg.cfg.d/99-exclude-cruft - - echo 'path-exclude=/usr/share/man/*' >> $buildmnt/etc/dpkg/dpkg.cfg.d/99-exclude-cruft - - echo 'APT::Install-Recommends "false";' > $buildmnt/etc/apt/apt.conf - - echo '#!/bin/sh' > $buildmnt/usr/sbin/policy-rc.d - - echo 'exit 101' >> $buildmnt/usr/sbin/policy-rc.d - - chmod +x $buildmnt/usr/sbin/policy-rc.d - - - buildah run $buildcntr env DEBIAN_FRONTEND=noninteractive apt-get update - - buildah run $buildcntr env DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade - - if [[ x"$DEBIAN_DEBS" != x"" ]] ; - then - buildah run $buildcntr env DEBIAN_FRONTEND=noninteractive apt-get -y install $DEBIAN_DEBS ; - fi - - # check if there is an optional post install script and run it - - if [[ x"$DISTRO_EXEC" != x"" ]] ; - then - echo Running $DISTRO_EXEC ; - set -x ; - mkdir $buildmnt/tmp/clone ; - pushd $buildmnt/tmp/clone ; - git init ; - git remote add origin $CI_REPOSITORY_URL ; - git fetch --depth 1 origin $CI_COMMIT_SHA ; - git checkout FETCH_HEAD > /dev/null; - buildah config --workingdir /tmp/clone $buildcntr ; - buildah run $buildcntr bash -c "set -x ; $DISTRO_EXEC" ; - popd ; - rm -rf $buildmnt/tmp/clone ; - set +x ; - fi - - # do not store the packages database, it's pointless - - buildah run $buildcntr env DEBIAN_FRONTEND=noninteractive apt-get clean - - rm -f $buildmnt/var/lib/apt/lists/*.lz4 - - # set up the working directory - - buildah config --workingdir /app $buildcntr - # umount the container, not required, but, heh - - buildah unmount $buildcntr - # tag the current container - - buildah commit $buildcntr $CI_REGISTRY_IMAGE/$DISTRO/$DISTRO_VERSION:$CI_JOB_ID - # clean up the working container - - buildah rm $buildcntr - - # push the container image to the registry - # There is a bug when pushing 2 tags in the same repo with the same base: - # this may fail. Just retry it after. - - podman push $CI_REGISTRY_IMAGE/$DISTRO/$DISTRO_VERSION:$CI_JOB_ID || true - - sleep 2 - - podman push $CI_REGISTRY_IMAGE/$DISTRO/$DISTRO_VERSION:$CI_JOB_ID - - # mark the current stage as successed, to get the result in after_script - - touch .success - - -.debian32@container-build: - extends: ..debian32@container-template - after_script: - # if we did not build, or if there was a failure, exit - # (the exit status does not matter here) - - if [[ ! -e .success ]] ; - then - exit 0; - fi - - - *distro_vars - - - skopeo copy docker://$CI_REGISTRY_IMAGE/$DISTRO/$DISTRO_VERSION:$CI_JOB_ID - docker://$CI_REGISTRY_IMAGE/$DISTRO/$DISTRO_VERSION:$DISTRO_TAG - - -.debian32@container-ifnot-exists: - extends: .debian32@container-build - before_script: - # log in to the registry - - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - - *distro_vars - - # check if our image is already in the current registry - - skopeo inspect docker://$CI_REGISTRY_IMAGE/$DISTRO/$DISTRO_VERSION:$DISTRO_TAG > /dev/null && exit 0 || true - - # copy the original image into the current project registry namespace - - skopeo copy docker://$CI_REGISTRY/$UPSTREAM_REPO/$DISTRO/$DISTRO_VERSION:$DISTRO_TAG - docker://$CI_REGISTRY_IMAGE/$DISTRO/$DISTRO_VERSION:$DISTRO_TAG && exit 0 || true -- cgit v1.2.3 From c31b65770cea2084cb50593f6a85fb21ef9f22f2 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Wed, 29 Mar 2023 18:59:08 -0400 Subject: Optimize minimal build by default --- minimal_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minimal_build.sh b/minimal_build.sh index a1ea2eb..0cab19e 100755 --- a/minimal_build.sh +++ b/minimal_build.sh @@ -18,7 +18,7 @@ python3 ../protocols/symgen.py header ../protocols/function_list.txt protocols.h echo '#define WAYPIPE_VERSION "minimal"' > config-waypipe.h echo "Compiling..." -gcc -D_DEFAULT_SOURCE -I. -I../protocols/ -lpthread -o waypipe protocols.c \ +gcc -D_DEFAULT_SOURCE -Os -I. -I../protocols/ -lpthread -o waypipe protocols.c \ ../src/bench.c ../src/client.c ../src/dmabuf.c ../src/handlers.c \ ../src/interval.c ../src/kernel.c ../src/mainloop.c ../src/parsing.c \ ../src/platform.c ../src/server.c ../src/shadow.c ../src/util.c \ -- cgit v1.2.3 From aba20719cc4661b59e86020a1ec8a6ee37a35c24 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Wed, 29 Mar 2023 18:59:58 -0400 Subject: Update core Wayland protocol file and shm formats Note: the version with updated shm formats has not yet been released, but as updates to the wl_shm format list just pull values from libdrm, it is very unlikely that libwayland will conflict. --- protocols/wayland.xml | 223 +++++++++++++++++++++++++++++++++++++++++--------- src/handlers.c | 22 +++++ 2 files changed, 207 insertions(+), 38 deletions(-) diff --git a/protocols/wayland.xml b/protocols/wayland.xml index 784d971..a7def4d 100644 --- a/protocols/wayland.xml +++ b/protocols/wayland.xml @@ -177,6 +177,9 @@ Clients can handle the 'done' event to get notified when the related request is done. + + Note, because wl_callback objects are created from multiple independent + factory interfaces, the wl_callback interface is frozen at version 1. @@ -187,7 +190,7 @@ - + A compositor. This object is a singleton global. The compositor is in charge of combining the contents of multiple @@ -258,6 +261,12 @@ for the pool from the file descriptor passed when the pool was created, but using the new size. This request can only be used to make the pool bigger. + + This request only changes the amount of bytes that are mmapped + by the server and does not touch the file corresponding to the + file descriptor passed at creation time. It is the client's + responsibility to ensure that the file is at least as big as + the new pool size. @@ -271,8 +280,8 @@ Clients can create wl_shm_pool objects using the create_pool request. - At connection setup time, the wl_shm object emits one or more - format events to inform clients about the valid pixel formats + On binding the wl_shm object one or more format events + are emitted to inform clients about the valid pixel formats that can be used for buffers. @@ -410,6 +419,21 @@ + + + + + + + + + + + + + + + @@ -447,6 +471,9 @@ If the buffer uses a format that has an alpha channel, the alpha channel is assumed to be premultiplied in the color channels unless otherwise specified. + + Note, because wl_buffer objects are created from multiple independent + factory interfaces, the wl_buffer interface is frozen at version 1. @@ -618,8 +645,9 @@ This event indicates the actions offered by the data source. It - will be sent right after wl_data_device.enter, or anytime the source - side changes its offered actions through wl_data_source.set_actions. + will be sent immediately after creating the wl_data_offer object, + or anytime the source side changes its offered actions through + wl_data_source.set_actions. @@ -861,11 +889,8 @@ a drag-and-drop icon. If the icon surface already has another role, it raises a protocol error. - The current and pending input regions of the icon wl_surface are - cleared, and wl_surface.set_input_region is ignored until the - wl_surface is no longer used as the icon surface. When the use - as an icon ends, the current and pending input regions become - undefined, and the wl_surface is unmapped. + The input region is ignored for wl_surfaces with the role of a + drag-and-drop icon. @@ -890,7 +915,7 @@ which will subsequently be used in either the data_device.enter event (for drag-and-drop) or the data_device.selection event (for selections). Immediately - following the data_device_data_offer event, the new data_offer + following the data_device.data_offer event, the new data_offer object will send out data_offer.offer events to describe the mime types it offers. @@ -1051,7 +1076,8 @@ a basic surface. Note! This protocol is deprecated and not intended for production use. - For desktop-style user interfaces, use xdg_shell. + For desktop-style user interfaces, use xdg_shell. Compositors and clients + should not implement this interface. @@ -1345,7 +1371,7 @@ - + A surface is a rectangular area that may be displayed on zero or more outputs, and shown any number of times at the compositor's @@ -1377,8 +1403,9 @@ that this request gives a role to a wl_surface. Often, this request also creates a new protocol object that represents the role and adds additional functionality to wl_surface. When a - client wants to destroy a wl_surface, they must destroy this 'role - object' before the wl_surface. + client wants to destroy a wl_surface, they must destroy this role + object before the wl_surface, otherwise a defunct_role_object error is + sent. Destroying the role object does not remove the role from the wl_surface, but it may stop the wl_surface from "playing the role". @@ -1398,6 +1425,8 @@ + @@ -1426,8 +1455,9 @@ When the bound wl_surface version is 5 or higher, passing any non-zero x or y is a protocol violation, and will result in an - 'invalid_offset' error being raised. To achieve equivalent semantics, - use wl_surface.offset. + 'invalid_offset' error being raised. The x and y arguments are ignored + and do not change the pending state. To achieve equivalent semantics, + use wl_surface.offset. Surface contents are double-buffered state, see wl_surface.commit. @@ -1779,9 +1809,37 @@ + + + + + + This event indicates the preferred buffer scale for this surface. It is + sent whenever the compositor's preference changes. + + It is intended that scaling aware clients use this event to scale their + content and use wl_surface.set_buffer_scale to indicate the scale they + have rendered with. This allows clients to supply a higher detail + buffer. + + + + + + + This event indicates the preferred buffer transform for this surface. + It is sent whenever the compositor's preference changes. + + It is intended that transform aware clients use this event to apply the + transform to their content and use wl_surface.set_buffer_transform to + indicate the transform they have rendered with. + + + - + A seat is a group of keyboards, pointer and touch devices. This object is published as a global during start up, or when such a @@ -1914,7 +1972,7 @@ - + The wl_pointer interface represents one or more input devices, such as mice, which control the pointer location and pointer_focus @@ -1958,11 +2016,9 @@ pointer surface to this request with new values for hotspot_x and hotspot_y. - The current and pending input regions of the wl_surface are - cleared, and wl_surface.set_input_region is ignored until the - wl_surface is no longer used as the cursor. When the use as a - cursor ends, the current and pending input regions become - undefined, and the wl_surface is unmapped. + The input region is ignored for wl_surfaces with the role of + a cursor. When the use as a cursor ends, the wl_surface is + unmapped. The serial parameter must match the latest wl_pointer.enter serial number sent to the client. Otherwise the request will be @@ -2214,6 +2270,9 @@ This event carries the axis value of the wl_pointer.axis event in discrete steps (e.g. mouse wheel clicks). + This event is deprecated with wl_pointer version 8 - this event is not + sent to clients supporting version 8 or later. + This event does not occur on its own, it is coupled with a wl_pointer.axis event that represents this axis value on a continuous scale. The protocol guarantees that each axis_discrete @@ -2221,7 +2280,8 @@ axis number within the same wl_pointer.frame. Note that the protocol allows for other events to occur between the axis_discrete and its coupled axis event, including other axis_discrete or axis - events. + events. A wl_pointer.frame must not contain more than one axis_discrete + event per axis type. This event is optional; continuous scrolling devices like two-finger scrolling on touchpads do not have discrete @@ -2239,9 +2299,93 @@ + + + + Discrete high-resolution scroll information. + + This event carries high-resolution wheel scroll information, + with each multiple of 120 representing one logical scroll step + (a wheel detent). For example, an axis_value120 of 30 is one quarter of + a logical scroll step in the positive direction, a value120 of + -240 are two logical scroll steps in the negative direction within the + same hardware event. + Clients that rely on discrete scrolling should accumulate the + value120 to multiples of 120 before processing the event. + + The value120 must not be zero. + + This event replaces the wl_pointer.axis_discrete event in clients + supporting wl_pointer version 8 or later. + + Where a wl_pointer.axis_source event occurs in the same + wl_pointer.frame, the axis source applies to this event. + + The order of wl_pointer.axis_value120 and wl_pointer.axis_source is + not guaranteed. + + + + + + + + + + This specifies the direction of the physical motion that caused a + wl_pointer.axis event, relative to the wl_pointer.axis direction. + + + + + + + + Relative directional information of the entity causing the axis + motion. + + For a wl_pointer.axis event, the wl_pointer.axis_relative_direction + event specifies the movement direction of the entity causing the + wl_pointer.axis event. For example: + - if a user's fingers on a touchpad move down and this + causes a wl_pointer.axis vertical_scroll down event, the physical + direction is 'identical' + - if a user's fingers on a touchpad move down and this causes a + wl_pointer.axis vertical_scroll up scroll up event ('natural + scrolling'), the physical direction is 'inverted'. + + A client may use this information to adjust scroll motion of + components. Specifically, enabling natural scrolling causes the + content to change direction compared to traditional scrolling. + Some widgets like volume control sliders should usually match the + physical direction regardless of whether natural scrolling is + active. This event enables clients to match the scroll direction of + a widget to the physical direction. + + This event does not occur on its own, it is coupled with a + wl_pointer.axis event that represents this axis value. + The protocol guarantees that each axis_relative_direction event is + always followed by exactly one axis event with the same + axis number within the same wl_pointer.frame. Note that the protocol + allows for other events to occur between the axis_relative_direction + and its coupled axis event. + + The axis number is identical to the axis number in the associated + axis event. + + The order of wl_pointer.axis_relative_direction, + wl_pointer.axis_discrete and wl_pointer.axis_source is not + guaranteed. + + + + - + The wl_keyboard interface represents one or more keyboards associated with a seat. @@ -2255,7 +2399,7 @@ + summary="libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode"/> @@ -2368,7 +2512,7 @@ - + The wl_touch interface represents a touchscreen associated with a seat. @@ -2822,6 +2966,8 @@ + @@ -2831,14 +2977,18 @@ plain wl_surface into a sub-surface. The to-be sub-surface must not already have another role, and it - must not have an existing wl_subsurface object. Otherwise a protocol - error is raised. + must not have an existing wl_subsurface object. Otherwise the + bad_surface protocol error is raised. Adding sub-surfaces to a parent is a double-buffered operation on the parent (see wl_surface.commit). The effect of adding a sub-surface becomes visible on the next time the state of the parent surface is applied. + The parent surface must not be one of the child surface's descendants, + and the parent must be different from the child surface, otherwise the + bad_parent protocol error is raised. + This request modifies the behaviour of wl_surface.commit request on the sub-surface, see the documentation on wl_subsurface interface. @@ -2893,12 +3043,10 @@ synchronized mode, and then assume that all its child and grand-child sub-surfaces are synchronized, too, without explicitly setting them. - If the wl_surface associated with the wl_subsurface is destroyed, the - wl_subsurface object becomes inert. Note, that destroying either object - takes effect immediately. If you need to synchronize the removal - of a sub-surface to the parent surface update, unmap the sub-surface - first by attaching a NULL wl_buffer, update parent, and then destroy - the sub-surface. + Destroying a sub-surface takes effect immediately. If you need to + synchronize the removal of a sub-surface to the parent surface update, + unmap the sub-surface first by attaching a NULL wl_buffer, update parent, + and then destroy the sub-surface. If the parent wl_surface object is destroyed, the sub-surface is unmapped. @@ -2909,8 +3057,7 @@ The sub-surface interface is removed from the wl_surface object that was turned into a sub-surface with a wl_subcompositor.get_subsurface request. The wl_surface's association - to the parent is deleted, and the wl_surface loses its role as - a sub-surface. The wl_surface is unmapped immediately. + to the parent is deleted. The wl_surface is unmapped immediately. diff --git a/src/handlers.c b/src/handlers.c index 6c789ee..9c32a92 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -618,6 +618,28 @@ int get_shm_bytes_per_pixel(uint32_t format) case WL_SHM_FORMAT_ARGB16161616: case WL_SHM_FORMAT_ABGR16161616: return 8; + // todo: adjust API to handle bit packed formats + case WL_SHM_FORMAT_C1: + case WL_SHM_FORMAT_C2: + case WL_SHM_FORMAT_C4: + case WL_SHM_FORMAT_D1: + case WL_SHM_FORMAT_D2: + case WL_SHM_FORMAT_D4: + goto planar; + case WL_SHM_FORMAT_D8: + return 1; + case WL_SHM_FORMAT_R1: + case WL_SHM_FORMAT_R2: + case WL_SHM_FORMAT_R4: + goto planar; + case WL_SHM_FORMAT_R10: + case WL_SHM_FORMAT_R12: + return 2; + case WL_SHM_FORMAT_AVUY8888: + case WL_SHM_FORMAT_XVUY8888: + return 4; + case WL_SHM_FORMAT_P030: + goto planar; default: wp_error("Unidentified WL_SHM format %x", format); return -1; -- cgit v1.2.3 From fca09a120df3d5b6cbe8f0e3e188c8a0ad9277cf Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sun, 2 Apr 2023 19:52:17 -0400 Subject: Handle pipe poll errors by closing pipe --- src/shadow.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/shadow.c b/src/shadow.c index df60c4a..a1e67f9 100644 --- a/src/shadow.c +++ b/src/shadow.c @@ -2311,6 +2311,16 @@ void mark_pipe_object_statuses( if (pfds[i].revents & POLLOUT) { sfd->pipe.writable = true; } + if (pfds[i].revents & POLLERR) { + wp_debug("Pipe poll returned POLLERR for .pipe_fd=%d, closing", + lfd); + if (sfd->pipe.can_read) { + pipe_close_read(sfd); + } + if (sfd->pipe.can_write) { + pipe_close_write(sfd); + } + } } } -- cgit v1.2.3 From 033d0e7eb613f1ddfe104d07079a81b8d4e02dac Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sat, 8 Apr 2023 08:41:55 -0400 Subject: Bump version --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index b907ac1..64cee09 100644 --- a/meson.build +++ b/meson.build @@ -8,7 +8,7 @@ project( 'warning_level=3', 'werror=true', ], - version: '0.8.5', + version: '0.8.6', ) # DEFAULT_SOURCE implies POSIX_C_SOURCE 200809L + extras like CMSG_LEN -- cgit v1.2.3