diff options
| -rw-r--r-- | examples/tablet.c | 19 | ||||
| -rw-r--r-- | src/platform/cocoa/api.h | 7 | ||||
| -rw-r--r-- | src/platform/cocoa/window.m | 56 | ||||
| -rw-r--r-- | src/platform/wayland/api.h | 5 | ||||
| -rw-r--r-- | src/platform/wayland/backend.c | 14 | ||||
| -rw-r--r-- | src/platform/wayland/buffer.c | 14 | ||||
| -rw-r--r-- | src/platform/wayland/clipboard.c | 51 | ||||
| -rw-r--r-- | src/platform/wayland/drag.c | 10 | ||||
| -rw-r--r-- | src/platform/wayland/ime.c | 8 | ||||
| -rw-r--r-- | src/platform/wayland/internal.h | 15 | ||||
| -rw-r--r-- | src/platform/wayland/keyboard.c | 44 | ||||
| -rw-r--r-- | src/platform/wayland/pointer.c | 38 | ||||
| -rw-r--r-- | src/platform/wayland/popup.c | 6 | ||||
| -rw-r--r-- | src/platform/wayland/surface.c | 38 | ||||
| -rw-r--r-- | src/platform/x11/window.c | 39 | ||||
| -rw-r--r-- | tests/common/test_tablet_example.c | 37 | ||||
| -rw-r--r-- | tests/wayland/test_clipboard.c | 2 | ||||
| -rw-r--r-- | tests/x11/test_tablet_native.c | 15 |
18 files changed, 155 insertions, 263 deletions
diff --git a/examples/tablet.c b/examples/tablet.c index 256d8f8..8a1af7e 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -43,16 +43,6 @@ static const char *device_name(enum yasl_pointer_device device) } } -static bool is_pen(enum yasl_pointer_device device) -{ - return device == YASL_PTR_DEV_PEN || device == YASL_PTR_DEV_ERASER; -} - -static double scale(const struct app *app) -{ - return (double)app->geometry.scale_120 / YASL_SCALE_UNIT; -} - static void cancel_stroke(struct app *app) { app->down = app->previous = app->visible = false; @@ -94,7 +84,9 @@ static void clear_canvas(struct app *app) static double brush_radius(const struct app *app) { - return scale(app) * (is_pen(app->pointer.device) ? + return ((double)app->geometry.scale_120 / YASL_SCALE_UNIT) * + ((app->pointer.device == YASL_PTR_DEV_PEN || + app->pointer.device == YASL_PTR_DEV_ERASER) ? 2 + 24 * ((double)app->pointer.pen.pressure / 65535) : 6); } @@ -121,7 +113,8 @@ static void stroke(struct app *app) double radius = brush_radius(app); /* Leaving the canvas breaks the line so re-entry cannot bridge the UI. */ if (x < 0 || x >= app->geometry.size.x || - y < HEADER * scale(app) || y >= app->geometry.size.y) { + y < HEADER * ((double)app->geometry.scale_120 / YASL_SCALE_UNIT) || + y >= app->geometry.size.y) { app->previous = false; return; } @@ -234,7 +227,7 @@ static void draw(struct yasl_surface *surface, struct yasl_frame *frame, void *u } struct yasl_framebuffer *fb = &frame->target; memcpy(fb->pixels, app->canvas, (size_t)geometry.size.x * geometry.size.y * sizeof(uint32_t)); - double dpi = scale(app); + double dpi = (double)app->geometry.scale_120 / YASL_SCALE_UNIT; rect(fb, 0, 0, fb->size.x, (int)lround(HEADER * dpi), PANEL); char line[128]; snprintf(line, sizeof(line), "YASL TABLET / %s / %s / %s", backend_name(app->backend), diff --git a/src/platform/cocoa/api.h b/src/platform/cocoa/api.h index 802a039..89b71f3 100644 --- a/src/platform/cocoa/api.h +++ b/src/platform/cocoa/api.h @@ -15,25 +15,20 @@ int cocoa_display_modifiers(const struct cocoa_display *d); void cocoa_display_copy(struct cocoa_display *d, enum yasl_selection sel, const char *text); void cocoa_display_paste(struct cocoa_display *d, enum yasl_selection sel, struct cocoa_surface *target); bool cocoa_display_drag_start(struct cocoa_display *d, struct cocoa_surface *origin, const struct yasl_drag_image *image, const struct yasl_drag_listener *l, void *ud); -void cocoa_display_drag_cancel(struct cocoa_display *d); struct cocoa_surface *cocoa_surface_create_toplevel(struct cocoa_display *d, const struct yasl_window_spec *spec, void *graphics_device); struct cocoa_surface *cocoa_surface_create_popup(struct cocoa_surface *parent, const struct yasl_popup_spec *spec); bool cocoa_surface_popup_reposition(struct cocoa_surface *popup, const struct yasl_popup_spec *spec); void cocoa_surface_destroy(struct cocoa_surface *s); -struct cocoa_display *cocoa_surface_display(const struct cocoa_surface *s); void cocoa_surface_set_callbacks(struct cocoa_surface *s, const struct yasl_window_cbs *cbs, void *ud); void cocoa_surface_set_title(struct cocoa_surface *s, const char *title); void cocoa_surface_schedule_redraw(struct cocoa_surface *s); bool cocoa_surface_present(struct cocoa_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage); bool cocoa_surface_input_poll(struct cocoa_surface *s, struct yasl_input_event *ev); struct yasl_geometry cocoa_surface_geometry(const struct cocoa_surface *s); -uint32_t cocoa_surface_state(const struct cocoa_surface *s); struct yasl_timing cocoa_surface_timing(const struct cocoa_surface *s); -uint64_t cocoa_surface_frame_time_ns(struct cocoa_surface *s, uint64_t now); void cocoa_surface_set_cursor(struct cocoa_surface *s, enum yasl_cursor cursor); void cocoa_surface_set_background_color(struct cocoa_surface *s, uint32_t bg); -const char *cocoa_surface_ime_preedit(const struct cocoa_surface *s); bool cocoa_surface_ime_preedit_cursor(const struct cocoa_surface *s, int *begin, int *end); void cocoa_surface_set_ime_caret(struct cocoa_surface *s, struct yasl_rect2i caret); bool cocoa_surface_start_interactive_move(struct cocoa_surface *s); @@ -41,7 +36,5 @@ bool cocoa_surface_start_interactive_resize(struct cocoa_surface *s, enum yasl_r bool cocoa_surface_show_window_menu(struct cocoa_surface *s, struct yasl_vector2i pos); bool cocoa_surface_drag_carry(struct cocoa_surface *s, struct yasl_vector2i offset); bool cocoa_surface_place_under_pointer(struct cocoa_surface *s, struct yasl_vector2i at); -void *cocoa_display_get_native_handle(struct cocoa_display *d); -void *cocoa_surface_get_native_handle(struct cocoa_surface *s); #endif diff --git a/src/platform/cocoa/window.m b/src/platform/cocoa/window.m index 3c8519a..dc6175d 100644 --- a/src/platform/cocoa/window.m +++ b/src/platform/cocoa/window.m @@ -1487,11 +1487,6 @@ void cocoa_surface_destroy(struct cocoa_surface *w) yasl_loop_kick(darwin_ctx.loop); } -struct cocoa_display *cocoa_surface_display(const struct cocoa_surface *w) -{ - return w ? &darwin_ctx : NULL; -} - void cocoa_surface_set_title(struct cocoa_surface *w, const char *title) { if (!w || w->closed || !title) return; @@ -1540,11 +1535,6 @@ void cocoa_surface_set_ime_caret(struct cocoa_surface *w, struct yasl_rect2i car if (w) w->ime_caret = caret; } -const char *cocoa_surface_ime_preedit(const struct cocoa_surface *w) -{ - return w ? w->preedit : NULL; -} - bool cocoa_surface_ime_preedit_cursor(const struct cocoa_surface *w, int *begin, int *end) { (void)w; (void)begin; (void)end; @@ -1878,11 +1868,6 @@ bool cocoa_display_drag_start(struct cocoa_display *d, struct cocoa_surface *ori return true; } -void cocoa_display_drag_cancel(struct cocoa_display *d) -{ - drag_end(d, YASL_DRAG_CANCELLED); -} - bool cocoa_surface_drag_carry(struct cocoa_surface *w, struct yasl_vector2i offset) { if (!w || w->closed || !darwin_ctx.drag.active) @@ -1909,18 +1894,6 @@ bool cocoa_surface_show_window_menu(struct cocoa_surface *s, struct yasl_vector2 return false; } -void *cocoa_display_get_native_handle(struct cocoa_display *d) -{ - return d ? (void *)NSApp : NULL; -} - -void *cocoa_surface_get_native_handle(struct cocoa_surface *s) -{ - return s ? (void *)s->window : NULL; -} - - - void cocoa_surface_set_callbacks(struct cocoa_surface *w, const struct yasl_window_cbs *cbs, void *ud) { @@ -1946,11 +1919,6 @@ bool cocoa_surface_input_poll(struct cocoa_surface *w, struct yasl_input_event * return true; } -uint32_t cocoa_surface_state(const struct cocoa_surface *w) -{ - return w ? w->state : 0; -} - struct yasl_timing cocoa_surface_timing(const struct cocoa_surface *w) { struct yasl_timing timing = {0}; @@ -1965,11 +1933,6 @@ struct yasl_timing cocoa_surface_timing(const struct cocoa_surface *w) return timing; } -uint64_t cocoa_surface_frame_time_ns(struct cocoa_surface *w, uint64_t now) -{ - return w ? yasl_clock_frame_timestamp_ns(&w->clock, now) : now; -} - static struct yasl_display *impl_display_open(struct yasl_loop *loop, const struct yasl_display_spec *spec) { struct cocoa_display *result = cocoa_display_open(loop, spec); @@ -2018,7 +1981,7 @@ static bool impl_display_drag_start(struct yasl_display *d, struct yasl_surface static void impl_display_drag_cancel(struct yasl_display *d) { - cocoa_display_drag_cancel((struct cocoa_display *)d); + drag_end((struct cocoa_display *)d, YASL_DRAG_CANCELLED); } static struct yasl_surface *impl_surface_create_toplevel(struct yasl_display *d, @@ -2046,8 +2009,7 @@ static void impl_surface_destroy(struct yasl_surface *s) static struct yasl_display *impl_surface_display(const struct yasl_surface *s) { - struct cocoa_display *result = cocoa_surface_display((const struct cocoa_surface *)s); - return result ? &result->base : NULL; + return s ? &darwin_ctx.base : NULL; } static void impl_surface_set_callbacks(struct yasl_surface *s, const struct yasl_window_cbs *cbs, void *ud) @@ -2082,7 +2044,8 @@ static struct yasl_geometry impl_surface_geometry(const struct yasl_surface *s) static uint32_t impl_surface_state(const struct yasl_surface *s) { - return cocoa_surface_state((const struct cocoa_surface *)s); + const struct cocoa_surface *w = (const struct cocoa_surface *)s; + return w ? w->state : 0; } static struct yasl_timing impl_surface_timing(const struct yasl_surface *s) @@ -2092,7 +2055,8 @@ static struct yasl_timing impl_surface_timing(const struct yasl_surface *s) static uint64_t impl_surface_frame_time_ns(struct yasl_surface *s, uint64_t now) { - return cocoa_surface_frame_time_ns((struct cocoa_surface *)s, now); + struct cocoa_surface *w = (struct cocoa_surface *)s; + return w ? yasl_clock_frame_timestamp_ns(&w->clock, now) : now; } static void impl_surface_set_cursor(struct yasl_surface *s, enum yasl_cursor cursor) @@ -2107,7 +2071,8 @@ static void impl_surface_set_background_color(struct yasl_surface *s, uint32_t b static const char *impl_surface_ime_preedit(const struct yasl_surface *s) { - return cocoa_surface_ime_preedit((const struct cocoa_surface *)s); + const struct cocoa_surface *w = (const struct cocoa_surface *)s; + return w ? w->preedit : NULL; } static bool impl_surface_ime_preedit_cursor(const struct yasl_surface *s, int *begin, int *end) @@ -2147,12 +2112,13 @@ static bool impl_surface_place_under_pointer(struct yasl_surface *s, struct yasl static void *impl_display_get_native_handle(struct yasl_display *d) { - return cocoa_display_get_native_handle((struct cocoa_display *)d); + return d ? (void *)NSApp : NULL; } static void *impl_surface_get_native_handle(struct yasl_surface *s) { - return cocoa_surface_get_native_handle((struct cocoa_surface *)s); + struct cocoa_surface *w = (struct cocoa_surface *)s; + return w ? (void *)w->window : NULL; } static bool impl_surface_get_native_frame(struct yasl_surface *s, diff --git a/src/platform/wayland/api.h b/src/platform/wayland/api.h index c3e5676..04a6bf1 100644 --- a/src/platform/wayland/api.h +++ b/src/platform/wayland/api.h @@ -22,7 +22,6 @@ struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display * struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *parent, const struct yasl_popup_spec *spec); bool wayland_surface_popup_reposition(struct wayland_surface *popup, const struct yasl_popup_spec *spec); void wayland_surface_destroy(struct wayland_surface *s); -struct wayland_display *wayland_surface_display(const struct wayland_surface *s); void wayland_surface_set_callbacks(struct wayland_surface *s, const struct yasl_window_cbs *cbs, void *ud); void wayland_surface_set_title(struct wayland_surface *s, const char *title); void wayland_surface_schedule_redraw(struct wayland_surface *s); @@ -31,10 +30,8 @@ bool wayland_surface_input_poll(struct wayland_surface *s, struct yasl_input_eve struct yasl_geometry wayland_surface_geometry(const struct wayland_surface *s); uint32_t wayland_surface_state(const struct wayland_surface *s); struct yasl_timing wayland_surface_timing(const struct wayland_surface *s); -uint64_t wayland_surface_frame_time_ns(struct wayland_surface *s, uint64_t now); void wayland_surface_set_cursor(struct wayland_surface *s, enum yasl_cursor cursor); void wayland_surface_set_background_color(struct wayland_surface *s, uint32_t bg); -const char *wayland_surface_ime_preedit(const struct wayland_surface *s); bool wayland_surface_ime_preedit_cursor(const struct wayland_surface *s, int *begin, int *end); void wayland_surface_set_ime_caret(struct wayland_surface *s, struct yasl_rect2i caret); bool wayland_surface_start_interactive_move(struct wayland_surface *s); @@ -42,7 +39,5 @@ bool wayland_surface_start_interactive_resize(struct wayland_surface *s, enum ya bool wayland_surface_show_window_menu(struct wayland_surface *s, struct yasl_vector2i pos); bool wayland_surface_drag_carry(struct wayland_surface *s, struct yasl_vector2i offset); bool wayland_surface_place_under_pointer(struct wayland_surface *s, struct yasl_vector2i at); -void *wayland_display_get_native_handle(struct wayland_display *d); -void *wayland_surface_get_native_handle(struct wayland_surface *s); #endif diff --git a/src/platform/wayland/backend.c b/src/platform/wayland/backend.c index c0c7c83..3eada38 100644 --- a/src/platform/wayland/backend.c +++ b/src/platform/wayland/backend.c @@ -76,7 +76,8 @@ static void impl_surface_destroy(struct yasl_surface *s) static struct yasl_display *impl_surface_display(const struct yasl_surface *s) { - struct wayland_display *result = wayland_surface_display((const struct wayland_surface *)s); + const struct wayland_surface *w = (const struct wayland_surface *)s; + struct wayland_display *result = w ? w->conn : NULL; return result ? &result->base : NULL; } @@ -122,7 +123,7 @@ static struct yasl_timing impl_surface_timing(const struct yasl_surface *s) static uint64_t impl_surface_frame_time_ns(struct yasl_surface *s, uint64_t now) { - return wayland_surface_frame_time_ns((struct wayland_surface *)s, now); + return yasl_clock_frame_timestamp_ns(&((struct wayland_surface *)s)->clock, now); } static void impl_surface_set_cursor(struct yasl_surface *s, enum yasl_cursor cursor) @@ -137,7 +138,8 @@ static void impl_surface_set_background_color(struct yasl_surface *s, uint32_t b static const char *impl_surface_ime_preedit(const struct yasl_surface *s) { - return wayland_surface_ime_preedit((const struct wayland_surface *)s); + const struct wayland_surface *w = (const struct wayland_surface *)s; + return w ? w->ime_shown : NULL; } static bool impl_surface_ime_preedit_cursor(const struct yasl_surface *s, int *begin, int *end) @@ -177,12 +179,14 @@ static bool impl_surface_place_under_pointer(struct yasl_surface *s, struct yasl static void *impl_display_get_native_handle(struct yasl_display *d) { - return wayland_display_get_native_handle((struct wayland_display *)d); + struct wayland_display *w = (struct wayland_display *)d; + return w ? w->wl : NULL; } static void *impl_surface_get_native_handle(struct yasl_surface *s) { - return wayland_surface_get_native_handle((struct wayland_surface *)s); + struct wayland_surface *w = (struct wayland_surface *)s; + return w ? w->surface : NULL; } const struct yasl_backend_ops yasl_wayland_backend = { diff --git a/src/platform/wayland/buffer.c b/src/platform/wayland/buffer.c index 142f85f..f4243d1 100644 --- a/src/platform/wayland/buffer.c +++ b/src/platform/wayland/buffer.c @@ -26,11 +26,6 @@ int device_px(int logical, uint32_t scale_120) return px > 0 && px <= INT_MAX ? (int)px : -1; } -int logical_px_ceil(int device, uint32_t scale_120) -{ - return (int)(((int64_t)device * YASL_SCALE_UNIT + scale_120 - 1) / scale_120); -} - bool buffer_size(int width, int height, size_t *bytes) { if (width <= 0 || height <= 0 || width > INT32_MAX / 4 || @@ -206,7 +201,9 @@ void surface_follow_outputs(struct wayland_surface *w) { uint32_t refresh = 0; int32_t max_scale = 0; - bool need_scale = !w->frac_scale && !surface_gets_preferred_scale(w->surface); + bool need_scale = !w->frac_scale && + wl_proxy_get_version((struct wl_proxy *)w->surface) < + WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION; for (const struct wl_conn_output *o = w->conn->outputs; o; o = o->next) { if (o->mask & w->outputs) { @@ -564,8 +561,3 @@ struct yasl_timing wayland_surface_timing(const struct wayland_surface *w) yasl_clock_resize_stats(&w->clock, &t.resize); return t; } - -uint64_t wayland_surface_frame_time_ns(struct wayland_surface *w, uint64_t now) -{ - return yasl_clock_frame_timestamp_ns(&w->clock, now); -} diff --git a/src/platform/wayland/clipboard.c b/src/platform/wayland/clipboard.c index a6922c4..24dee97 100644 --- a/src/platform/wayland/clipboard.c +++ b/src/platform/wayland/clipboard.c @@ -71,11 +71,6 @@ static void drag_event(struct clipboard *c, enum yasl_drag_event ev, c->drag_ud); } -static bool offer_droppable(const struct offer *o) -{ - return o && !o->tab && (o->uri_list || o->mime); -} - static void drop_event(struct clipboard *c, enum yasl_drop_event ev) { if (c->drop && c->drag_surface) @@ -103,27 +98,22 @@ static void transfer_end(struct transfer *t, bool complete) free(t); } -static void transfer_destroy(struct transfer *t) -{ - transfer_end(t, false); -} - static int transfer_io(int fd, short events, void *ud) { struct transfer *t = ud; - if (events & (POLLERR | POLLNVAL)) { transfer_destroy(t); return 0; } + if (events & (POLLERR | POLLNVAL)) { transfer_end(t, false); return 0; } if (t->sending) { ssize_t n = write(fd, t->text + t->offset, t->len - t->offset); if (n > 0) t->offset += (size_t)n; if (t->offset == t->len || n == 0 || - (n < 0 && errno != EAGAIN && errno != EINTR)) transfer_destroy(t); + (n < 0 && errno != EAGAIN && errno != EINTR)) transfer_end(t, false); } else { if (t->capacity - t->len < 4096) { size_t capacity = t->capacity ? t->capacity * 2 : 8192; if (capacity > CLIPBOARD_TEXT_MAX) capacity = CLIPBOARD_TEXT_MAX; - if (capacity <= t->len) { transfer_destroy(t); return 0; } + if (capacity <= t->len) { transfer_end(t, false); return 0; } char *text = realloc(t->text, capacity); - if (!text) { transfer_destroy(t); return 0; } + if (!text) { transfer_end(t, false); return 0; } t->text = text; t->capacity = capacity; } @@ -136,7 +126,7 @@ static int transfer_io(int fd, short events, void *ud) t->owner->receive(t->text ? t->text : "", t->len, t->uri_list, t->drop_surface, t->owner->ud); transfer_end(t, valid); - } else if (errno != EAGAIN && errno != EINTR) transfer_destroy(t); + } else if (errno != EAGAIN && errno != EINTR) transfer_end(t, false); } return 0; } @@ -160,11 +150,6 @@ static struct transfer *start_transfer_text(struct clipboard *c, int fd, bool se return t; } -static struct transfer *start_transfer(struct clipboard *c, int fd, bool sending, bool uri_list) -{ - return start_transfer_text(c, fd, sending, uri_list, c->text); -} - static const char *match_text_mime(const char *mime) { if (unlikely(!mime)) return NULL; @@ -274,7 +259,7 @@ static void drag_offer_enter(void *ud, struct wl_data_device *device, uint32_t s c->drag_surface = surface; if (o && o->tab) drag_event(c, YASL_DRAG_OVER, x, y); - else if (offer_droppable(o)) + else if (o && !o->tab && (o->uri_list || o->mime)) drop_event(c, YASL_DROP_OVER); } } @@ -284,7 +269,8 @@ static void drag_offer_clear(void *ud, struct wl_data_device *device) struct clipboard *c = ud; if (c->drag_offer && c->drag_offer->tab) drag_event(c, YASL_DRAG_LEAVE, c->drag_x, c->drag_y); - else if (offer_droppable(c->drag_offer)) + else if (c->drag_offer && !c->drag_offer->tab && + (c->drag_offer->uri_list || c->drag_offer->mime)) drop_event(c, YASL_DROP_LEAVE); free_offer(c->drag_offer); c->drag_offer = NULL; @@ -298,7 +284,8 @@ static void drag_motion(void *ud, struct wl_data_device *device, uint32_t time, c->drag_y = y; if (c->drag_offer && c->drag_offer->tab) drag_event(c, YASL_DRAG_OVER, x, y); - else if (offer_droppable(c->drag_offer)) + else if (c->drag_offer && !c->drag_offer->tab && + (c->drag_offer->uri_list || c->drag_offer->mime)) drop_event(c, YASL_DROP_OVER); } static void drag_drop(void *ud, struct wl_data_device *device) @@ -313,13 +300,13 @@ static void drag_drop(void *ud, struct wl_data_device *device) drag_event(c, YASL_DRAG_DROP, c->drag_x, c->drag_y); if (v3) wl_data_offer_finish(o->proxy); - } else if (offer_droppable(o)) { + } else if (o && !o->tab && (o->uri_list || o->mime)) { drop_event(c, YASL_DROP_LEAVE); int fds[2]; if (pipe2(fds, O_CLOEXEC) == 0) { wl_data_offer_receive(o->proxy, o->uri_list ? "text/uri-list" : o->mime, fds[1]); close(fds[1]); - struct transfer *t = start_transfer(c, fds[0], false, o->uri_list); + struct transfer *t = start_transfer_text(c, fds[0], false, o->uri_list, c->text); if (t) { t->drop = o; t->drop_surface = c->drag_surface; @@ -337,7 +324,11 @@ static const struct wl_data_device_listener device_listener = { }; static void source_target(void *ud, struct wl_data_source *s, const char *mime) { (void)ud; (void)s; (void)mime; } static void source_send(void *ud, struct wl_data_source *s, const char *mime, int32_t fd) -{ (void)s; (void)mime; start_transfer(ud, fd, true, false); } +{ + struct clipboard *c = ud; + (void)s; (void)mime; + start_transfer_text(c, fd, true, false, c->text); +} static void source_cancelled(void *ud, struct wl_data_source *s) { struct clipboard *c = ud; @@ -560,7 +551,7 @@ void clipboard_paste(struct clipboard *c, struct wl_surface *target) if (pipe2(fds, O_CLOEXEC) < 0) return; wl_data_offer_receive(c->selection->proxy, c->selection->mime, fds[1]); close(fds[1]); - struct transfer *t = start_transfer(c, fds[0], false, false); + struct transfer *t = start_transfer_text(c, fds[0], false, false, c->text); if (t) t->drop_surface = target; wl_display_flush(c->display); } @@ -593,7 +584,7 @@ void clipboard_paste_primary(struct clipboard *c, struct wl_surface *target) zwp_primary_selection_offer_v1_receive(c->primary_selection->proxy, c->primary_selection->mime, fds[1]); close(fds[1]); - struct transfer *t = start_transfer(c, fds[0], false, false); + struct transfer *t = start_transfer_text(c, fds[0], false, false, c->text); if (t) t->drop_surface = target; wl_display_flush(c->display); return; @@ -605,7 +596,7 @@ void clipboard_forget_surface(struct clipboard *c, struct wl_surface *surface) if (!c || !surface) return; for (struct transfer *t = c->transfers, *next; t; t = next) { next = t->next; - if (t->drop_surface == surface) transfer_destroy(t); + if (t->drop_surface == surface) transfer_end(t, false); } if (c->drag_surface == surface) c->drag_surface = NULL; } @@ -614,7 +605,7 @@ void clipboard_destroy(struct clipboard *c) { if (!c) return; while (c->transfers) - transfer_destroy(c->transfers); + transfer_end(c->transfers, false); free_offer(c->selection); clear_pending_offers(c); free_offer(c->drag_offer); diff --git a/src/platform/wayland/drag.c b/src/platform/wayland/drag.c index 989dbb6..2cfd432 100644 --- a/src/platform/wayland/drag.c +++ b/src/platform/wayland/drag.c @@ -139,7 +139,7 @@ static const struct wl_data_source_listener source_listener = { static struct seat *drag_seat(struct wayland_display *c, struct wayland_surface *origin) { struct wayland_surface *root = surface_root(origin); - struct seat *active = conn_active_seat(c); + struct seat *active = c->active_seat ? c->active_seat : c->seats; if (active && active->press_serial && surface_root(active->press_surface) == root) return active; @@ -225,7 +225,9 @@ static struct yasl_vector2i drag_device_pos(const struct wayland_surface *w, dou void conn_drop_target(struct wayland_display *c, enum yasl_drop_event ev, struct wl_surface *on, double x, double y) { - struct wayland_surface *w = conn_surface_for(c, on); + (void)c; + struct wayland_surface *w = on ? + (struct wayland_surface *)wl_surface_get_user_data(on) : NULL; if (!w || w->parent || !w->cbs->drop) return; w->cbs->drop(&w->base, ev, drag_device_pos(w, x, y), w->ud); @@ -234,7 +236,9 @@ void conn_drop_target(struct wayland_display *c, enum yasl_drop_event ev, void conn_drag_target(struct wayland_display *c, enum yasl_drag_event ev, struct wl_surface *on, double x, double y) { - struct wayland_surface *w = conn_surface_for(c, on); + (void)c; + struct wayland_surface *w = on ? + (struct wayland_surface *)wl_surface_get_user_data(on) : NULL; if (!w || w->parent || !w->cbs->drag) return; w->cbs->drag(&w->base, ev, drag_device_pos(w, x, y), w->ud); diff --git a/src/platform/wayland/ime.c b/src/platform/wayland/ime.c index bd9375b..440b234 100644 --- a/src/platform/wayland/ime.c +++ b/src/platform/wayland/ime.c @@ -38,11 +38,6 @@ void ime_send_caret(struct wayland_surface *w) zwp_text_input_v3_commit(seat->text_input); } -const char *wayland_surface_ime_preedit(const struct wayland_surface *w) -{ - return w ? w->ime_shown : NULL; -} - bool wayland_surface_ime_preedit_cursor(const struct wayland_surface *w, int *begin, int *end) { if (!w || !w->ime_shown || w->ime_shown_begin < 0) @@ -65,7 +60,8 @@ static void text_input_enter(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) { struct seat *s = data; - struct wayland_surface *w = surface_root(conn_surface_for(s->conn, surface)); + struct wayland_surface *w = surface_root(surface ? + (struct wayland_surface *)wl_surface_get_user_data(surface) : NULL); s->ime_focus = w; if (!w) return; zwp_text_input_v3_enable(text_input); diff --git a/src/platform/wayland/internal.h b/src/platform/wayland/internal.h index 51f51eb..f777674 100644 --- a/src/platform/wayland/internal.h +++ b/src/platform/wayland/internal.h @@ -334,7 +334,6 @@ int buffer_pick_free_index(const struct buffer *bufs, int cur); int buffer_prepare(struct wayland_surface *w, struct buffer *b, int width, int height, const struct wl_buffer_listener *listener); int apply_pending_geometry(struct wayland_surface *w); -int logical_px_ceil(int device, uint32_t scale_120); static inline void wl_damage_list(struct wl_surface *s, const struct yasl_damage_list *d) { @@ -351,12 +350,6 @@ static inline void wl_damage_list(struct wl_surface *s, const struct yasl_damage void surface_update_opaque_region(struct wayland_surface *w); int surface_init_scaling(struct wayland_surface *w); -static inline bool surface_gets_preferred_scale(struct wl_surface *s) -{ - return wl_proxy_get_version((struct wl_proxy *)s) >= - WL_SURFACE_PREFERRED_BUFFER_SCALE_SINCE_VERSION; -} - uint64_t conn_output_mask(const struct wayland_display *c, const struct wl_output *proxy); uint32_t conn_output_scale_120(const struct wayland_display *c, uint64_t outputs); void conn_destroy_outputs(struct wayland_display *c); @@ -365,15 +358,8 @@ uint64_t conn_pres_to_mono(const struct wayland_display *c, uint64_t ns); uint64_t conn_mono_to_pres(const struct wayland_display *c, uint64_t ns); void surface_draw_frame(struct wayland_surface *w); void surface_fail(struct wayland_surface *w); -void display_enter(struct wayland_display *c); void display_leave(struct wayland_display *c); -static inline struct wayland_surface *conn_surface_for(struct wayland_display *c, struct wl_surface *s) -{ - (void)c; - return s ? (struct wayland_surface *)wl_surface_get_user_data(s) : NULL; -} - static inline struct wayland_surface *surface_root(struct wayland_surface *w) { while (w && w->parent) @@ -391,7 +377,6 @@ void seat_bind(struct wayland_display *c, struct wl_registry *registry, uint32_t name, uint32_t version); bool seat_remove(struct wayland_display *c, uint32_t name); void seat_destroy(struct seat *s); -struct seat *conn_active_seat(const struct wayland_display *c); void seat_note_input(struct seat *s, uint32_t serial); void seat_forget_surface(struct seat *s, struct wayland_surface *w); void seat_clipboard_ensure(struct seat *s); diff --git a/src/platform/wayland/keyboard.c b/src/platform/wayland/keyboard.c index 86c8f07..0913079 100644 --- a/src/platform/wayland/keyboard.c +++ b/src/platform/wayland/keyboard.c @@ -41,11 +41,6 @@ static const char *const input_mod_names[5] = { XKB_MOD_NAME_CAPS }; -static bool mod_active(const struct seat *s, const char *name) -{ - return xkb_state_mod_name_is_active(s->xkb_state, name, XKB_STATE_MODS_EFFECTIVE) > 0; -} - static void resolve_input_mod_masks(struct seat *s) { memset(s->input_mod_masks, 0, sizeof(s->input_mod_masks)); @@ -150,7 +145,8 @@ static void keyboard_enter(void *data, struct wl_keyboard *keyboard, { (void)keyboard; (void)serial; (void)keys; struct seat *s = data; - struct wayland_surface *w = surface_root(conn_surface_for(s->conn, surface)); + struct wayland_surface *w = surface_root(surface ? + (struct wayland_surface *)wl_surface_get_user_data(surface) : NULL); bool same_window = w && w == s->focus_leaving; if (same_window) s->focus_leaving = NULL; @@ -204,7 +200,9 @@ static unsigned input_modifiers(struct seat *s) xkb_mod_mask_t reported = 0; for (unsigned i = 0; i < 5; i++) { xkb_mod_mask_t mask = s->input_mod_masks[i]; - if (mask && (mask & ~reported) && mod_active(s, input_mod_names[i])) { + if (mask && (mask & ~reported) && + xkb_state_mod_name_is_active(s->xkb_state, input_mod_names[i], + XKB_STATE_MODS_EFFECTIVE) > 0) { mods |= 1u << i; reported |= mask; } @@ -402,31 +400,33 @@ int keyboard_repeat_init(struct seat *s) return 0; } -static bool mod_index_active(const struct seat *s, xkb_mod_index_t mod) -{ - return mod != XKB_MOD_INVALID && - xkb_state_mod_index_is_active(s->xkb_state, mod, - XKB_STATE_MODS_EFFECTIVE) > 0; -} - int seat_modifiers(const struct seat *s) { if (unlikely(!s || !s->xkb_state)) return 0; - return (mod_index_active(s, s->mod_shift) * YASL_MOD_SHIFT) | - (mod_index_active(s, s->mod_alt) * YASL_MOD_ALT) | - (mod_index_active(s, s->mod_ctrl) * YASL_MOD_CTRL) | - (mod_index_active(s, s->mod_super) * YASL_MOD_SUPER) | - (mod_active(s, XKB_MOD_NAME_CAPS) * YASL_MOD_CAPS); + return ((s->mod_shift != XKB_MOD_INVALID && + xkb_state_mod_index_is_active(s->xkb_state, s->mod_shift, + XKB_STATE_MODS_EFFECTIVE) > 0) * YASL_MOD_SHIFT) | + ((s->mod_alt != XKB_MOD_INVALID && + xkb_state_mod_index_is_active(s->xkb_state, s->mod_alt, + XKB_STATE_MODS_EFFECTIVE) > 0) * YASL_MOD_ALT) | + ((s->mod_ctrl != XKB_MOD_INVALID && + xkb_state_mod_index_is_active(s->xkb_state, s->mod_ctrl, + XKB_STATE_MODS_EFFECTIVE) > 0) * YASL_MOD_CTRL) | + ((s->mod_super != XKB_MOD_INVALID && + xkb_state_mod_index_is_active(s->xkb_state, s->mod_super, + XKB_STATE_MODS_EFFECTIVE) > 0) * YASL_MOD_SUPER) | + ((xkb_state_mod_name_is_active(s->xkb_state, XKB_MOD_NAME_CAPS, + XKB_STATE_MODS_EFFECTIVE) > 0) * YASL_MOD_CAPS); } int wayland_display_modifiers(const struct wayland_display *c) { - return c ? seat_modifiers(conn_active_seat(c)) : 0; + return c ? seat_modifiers(c->active_seat ? c->active_seat : c->seats) : 0; } void wayland_display_copy(struct wayland_display *c, enum yasl_selection sel, const char *text) { - struct seat *s = c ? conn_active_seat(c) : NULL; + struct seat *s = c ? (c->active_seat ? c->active_seat : c->seats) : NULL; if (!s || !s->clipboard) return; if (sel == YASL_PRIMARY) @@ -437,7 +437,7 @@ void wayland_display_copy(struct wayland_display *c, enum yasl_selection sel, co void wayland_display_paste(struct wayland_display *c, enum yasl_selection sel, struct wayland_surface *target) { - struct seat *s = c ? conn_active_seat(c) : NULL; + struct seat *s = c ? (c->active_seat ? c->active_seat : c->seats) : NULL; if (!s || !s->clipboard) return; if (!target || target->closed) return; diff --git a/src/platform/wayland/pointer.c b/src/platform/wayland/pointer.c index 90b7ecc..4652849 100644 --- a/src/platform/wayland/pointer.c +++ b/src/platform/wayland/pointer.c @@ -25,17 +25,12 @@ struct tablet_pad { struct zwp_tablet_pad_v2 *proxy; }; -static inline int device_px_round(double v) -{ - return (int)lrint(v); -} - static struct yasl_vector2i device_from_fixed(const struct wayland_surface *w, wl_fixed_t x, wl_fixed_t y) { return (struct yasl_vector2i){ - .x = device_px_round(wl_fixed_to_double(x) * w->scale_factor), - .y = device_px_round(wl_fixed_to_double(y) * w->scale_factor), + .x = (int)lrint(wl_fixed_to_double(x) * w->scale_factor), + .y = (int)lrint(wl_fixed_to_double(y) * w->scale_factor), }; } @@ -85,11 +80,6 @@ void seat_note_input(struct seat *s, uint32_t serial) s->conn->active_seat = s; } -struct seat *conn_active_seat(const struct wayland_display *c) -{ - return c->active_seat ? c->active_seat : c->seats; -} - static void push_mouse(struct seat *s, struct wayland_surface *w, struct yasl_mouse_event ev) { ev.mods = (unsigned)seat_modifiers(s); @@ -174,9 +164,12 @@ static void set_cursor_theme_fallback(struct seat *s, struct wayland_surface *w, int theme_scale = c->cursor_theme_scale; if (s->cursor_viewport) { + uint32_t scale_120 = (uint32_t)theme_scale * YASL_SCALE_UNIT; wp_viewport_set_destination(s->cursor_viewport, - logical_px_ceil((int)img->width, (uint32_t)theme_scale * YASL_SCALE_UNIT), - logical_px_ceil((int)img->height, (uint32_t)theme_scale * YASL_SCALE_UNIT)); + (int)(((int64_t)(int)img->width * YASL_SCALE_UNIT + scale_120 - 1) / + scale_120), + (int)(((int64_t)(int)img->height * YASL_SCALE_UNIT + scale_120 - 1) / + scale_120)); } else { if (img->width % (uint32_t)theme_scale || img->height % (uint32_t)theme_scale) theme_scale = 1; @@ -324,7 +317,8 @@ static void pointer_enter(void *data, struct wl_pointer *pointer, { (void)pointer; struct seat *s = data; - struct wayland_surface *w = conn_surface_for(s->conn, surface); + struct wayland_surface *w = surface ? + (struct wayland_surface *)wl_surface_get_user_data(surface) : NULL; s->pointer_focus = w; if (!w) return; s->pointer_pos = device_from_fixed(w, surface_x, surface_y); @@ -522,7 +516,7 @@ static struct yasl_vector2i touch_pos(const struct touch_point *p) { double scale = p->surface->scale_factor; return (struct yasl_vector2i){ - .x = device_px_round(p->x * scale), .y = device_px_round(p->y * scale), + .x = (int)lrint(p->x * scale), .y = (int)lrint(p->y * scale), }; } @@ -543,7 +537,8 @@ static void touch_down(void *data, struct wl_touch *touch, { (void)touch; (void)time; struct seat *s = data; - struct wayland_surface *w = conn_surface_for(s->conn, surface); + struct wayland_surface *w = surface ? + (struct wayland_surface *)wl_surface_get_user_data(surface) : NULL; if (!w || touch_find(s, id)) return; struct touch_point *p = NULL; for (int i = 0; i < SEAT_TOUCH_POINTS && !p; i++) @@ -678,7 +673,8 @@ static void tablet_tool_proximity_in(void *data, (void)tool; (void)tablet; struct tablet_tool *t = data; struct seat *s = t->seat; - struct wayland_surface *w = conn_surface_for(s->conn, surface); + struct wayland_surface *w = surface ? + (struct wayland_surface *)wl_surface_get_user_data(surface) : NULL; s->tablet_focus = w; s->tool = t; s->tool_buttons = 0; @@ -984,9 +980,9 @@ static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = { static void clipboard_received(const char *text, size_t len, bool uri_list, struct wl_surface *on, void *ud) { - struct seat *s = ud; - struct wayland_display *c = s->conn; - struct wayland_surface *w = conn_surface_for(c, on); + (void)ud; + struct wayland_surface *w = on ? + (struct wayland_surface *)wl_surface_get_user_data(on) : NULL; if (uri_list) w = surface_root(w); if (!w || w->closed) return; struct yasl_input_event ev = { diff --git a/src/platform/wayland/popup.c b/src/platform/wayland/popup.c index 3a85435..fd415c9 100644 --- a/src/platform/wayland/popup.c +++ b/src/platform/wayland/popup.c @@ -41,8 +41,8 @@ static bool popup_apply_spec(struct wayland_surface *w, const struct yasl_popup_ { uint32_t scale = w->parent->scale_120; struct yasl_vector2i logical = { - .x = logical_px_ceil(spec->size.x, scale), - .y = logical_px_ceil(spec->size.y, scale), + .x = (int)(((int64_t)spec->size.x * YASL_SCALE_UNIT + scale - 1) / scale), + .y = (int)(((int64_t)spec->size.y * YASL_SCALE_UNIT + scale - 1) / scale), }; int width = device_px(logical.x, scale); int height = device_px(logical.y, scale); @@ -128,7 +128,7 @@ struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *par const struct yasl_popup_spec *spec) { struct wayland_display *c = parent ? parent->conn : NULL; - struct seat *seat = c ? conn_active_seat(c) : NULL; + struct seat *seat = c ? (c->active_seat ? c->active_seat : c->seats) : NULL; if (!c || c->lost || parent->closed || !parent->xdg_surface || !seat || !seat->input_serial || !popup_spec_valid(parent, spec)) return NULL; diff --git a/src/platform/wayland/surface.c b/src/platform/wayland/surface.c index 1820642..7daa679 100644 --- a/src/platform/wayland/surface.c +++ b/src/platform/wayland/surface.c @@ -26,11 +26,6 @@ static void report_display_error(struct wayland_display *c) fprintf(stderr, "[yasl] display error %d\n", err); } -void display_enter(struct wayland_display *c) -{ - c->depth++; -} - void display_leave(struct wayland_display *c) { if (--c->depth > 0) @@ -50,7 +45,7 @@ static void display_lose(struct wayland_display *c) c->lost = true; report_display_error(c); display_cancel_read(c); - display_enter(c); + c->depth++; for (struct wayland_surface *w = c->surfaces, *next; w; w = next) { next = w->conn_next; surface_fail(w); @@ -75,7 +70,7 @@ static int display_ready(int fd, short revents, void *ud) struct wayland_display *c = ud; if (c->lost) return 0; - display_enter(c); + c->depth++; if (c->reading) { c->reading = false; if (!(revents & POLLIN)) @@ -140,7 +135,7 @@ int wayland_display_dispatch_timeout(struct wayland_display *c, int timeout_ms) if (!c || c->lost) return -1; - display_enter(c); + c->depth++; if (wl_display_dispatch_pending(c->wl) < 0) { display_lose(c); @@ -181,7 +176,7 @@ void wayland_display_flush(struct wayland_display *c) { if (!c || c->lost) return; - display_enter(c); + c->depth++; for (struct wayland_surface *w = c->surfaces, *next; w; w = next) { next = w->conn_next; surface_draw_frame(w); @@ -286,7 +281,7 @@ uint32_t wayland_display_caps(const struct wayland_display *c) if (!c) return 0; uint32_t caps = YASL_CAP_POPUPS | YASL_CAP_CSD | YASL_CAP_FRAME_PACING; if (c->tablet_mgr) caps |= YASL_CAP_TABLET; - struct seat *s = conn_active_seat(c); + struct seat *s = c->active_seat ? c->active_seat : c->seats; const struct wl_data_device *device = s ? clipboard_data_device(s->clipboard) : NULL; if (device && wl_data_device_get_version((struct wl_data_device *)device) >= 3) caps |= YASL_CAP_DRAG; @@ -338,7 +333,7 @@ struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display * display_cancel_read(c); struct wayland_surface *w = calloc(1, sizeof(*w)); if (!w) return NULL; - display_enter(c); + c->depth++; conn_link(c, w); wayland_surface_set_callbacks(w, NULL, NULL); w->cursor = YASL_CURSOR_TEXT; @@ -440,11 +435,6 @@ void wayland_surface_destroy(struct wayland_surface *w) } } -struct wayland_display *wayland_surface_display(const struct wayland_surface *w) -{ - return w ? w->conn : NULL; -} - void wayland_surface_schedule_redraw(struct wayland_surface *w) { if (!w || w->closed) return; @@ -469,7 +459,7 @@ void wayland_surface_set_background_color(struct wayland_surface *w, uint32_t bg bool wayland_surface_start_interactive_move(struct wayland_surface *s) { if (!s || !s->toplevel || !s->conn) return false; - struct seat *seat = conn_active_seat(s->conn); + struct seat *seat = s->conn->active_seat ? s->conn->active_seat : s->conn->seats; if (!seat || !seat->proxy || !seat->press_serial) return false; xdg_toplevel_move(s->toplevel, seat->proxy, seat->press_serial); return true; @@ -478,7 +468,7 @@ bool wayland_surface_start_interactive_move(struct wayland_surface *s) bool wayland_surface_start_interactive_resize(struct wayland_surface *s, enum yasl_resize_edge edge) { if (!s || !s->toplevel || !s->conn || edge == YASL_EDGE_NONE) return false; - struct seat *seat = conn_active_seat(s->conn); + struct seat *seat = s->conn->active_seat ? s->conn->active_seat : s->conn->seats; if (!seat || !seat->proxy || !seat->press_serial) return false; xdg_toplevel_resize(s->toplevel, seat->proxy, seat->press_serial, (uint32_t)edge); return true; @@ -487,7 +477,7 @@ bool wayland_surface_start_interactive_resize(struct wayland_surface *s, enum ya bool wayland_surface_show_window_menu(struct wayland_surface *s, struct yasl_vector2i pos) { if (!s || !s->toplevel || !s->conn) return false; - struct seat *seat = conn_active_seat(s->conn); + struct seat *seat = s->conn->active_seat ? s->conn->active_seat : s->conn->seats; if (!seat || !seat->proxy || !seat->press_serial) return false; uint32_t scale = s->scale_120 ? s->scale_120 : YASL_SCALE_UNIT; xdg_toplevel_show_window_menu(s->toplevel, seat->proxy, seat->press_serial, @@ -495,13 +485,3 @@ bool wayland_surface_show_window_menu(struct wayland_surface *s, struct yasl_vec yasl_scale_to_logical(pos.y, scale)); return true; } - -void *wayland_display_get_native_handle(struct wayland_display *d) -{ - return d ? d->wl : NULL; -} - -void *wayland_surface_get_native_handle(struct wayland_surface *s) -{ - return s ? s->surface : NULL; -} diff --git a/src/platform/x11/window.c b/src/platform/x11/window.c index 7891fff..347b4c2 100644 --- a/src/platform/x11/window.c +++ b/src/platform/x11/window.c @@ -145,11 +145,6 @@ struct x11_display { } pending_drop; }; -static struct x11_display *display_of(const struct yasl_surface *s) -{ - return (struct x11_display *)s->display; -} - static bool place(struct yasl_surface *base, struct yasl_vector2i at); static void drag_end(struct x11_display *d, enum yasl_drag_end how); static void drag_cancel(struct yasl_display *base); @@ -368,7 +363,7 @@ static int pointer_button(unsigned button) static void xi_pointer_event(struct x11_surface *s, const XIDeviceEvent *ev) { - struct x11_display *d = display_of(&s->base); + struct x11_display *d = (struct x11_display *)s->base.display; struct x11_pointer *p = pointer_for(d, ev->sourceid); struct yasl_mouse_event mouse = { .pos = {yasl_scale_to_device(ev->event_x, YASL_SCALE_UNIT), @@ -472,7 +467,7 @@ static bool resize(struct x11_surface *s, struct yasl_vector2i size) (size_t)size.x > SIZE_MAX / sizeof(uint32_t) / (size_t)size.y) return false; if (s->image && size.x == s->size.x && size.y == s->size.y) return true; - struct x11_display *d = display_of(&s->base); + struct x11_display *d = (struct x11_display *)s->base.display; if (!d->native) { s->size = size; s->want_draw = true; @@ -580,7 +575,7 @@ static void surface_destroy(struct yasl_surface *base) { struct x11_surface *s = (struct x11_surface *)base; if (s->destroyed) return; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; if (d->drag.active) { if (d->drag.origin == s || d->drag.carried == s) drag_end(d, YASL_DRAG_CANCELLED); @@ -639,7 +634,7 @@ static void set_title(struct yasl_surface *base, const char *title) { struct x11_surface *s = (struct x11_surface *)base; if (s->destroyed || !title) return; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; XStoreName(d->native, s->window, title); XChangeProperty(d->native, s->window, d->net_name, d->utf8, 8, PropModeReplace, (const unsigned char *)title, (int)strlen(title)); @@ -648,7 +643,7 @@ static void set_title(struct yasl_surface *base, const char *title) static void net_message(struct x11_surface *s, Atom type, long a, long b, long c, long e, long f) { - struct x11_display *d = display_of(&s->base); + struct x11_display *d = (struct x11_display *)s->base.display; XEvent event = {0}; event.xclient = (XClientMessageEvent){ .type = ClientMessage, .display = d->native, .window = s->window, @@ -808,7 +803,7 @@ static struct yasl_surface *surface_create_popup(struct yasl_surface *parent_bas struct x11_surface *parent = (struct x11_surface *)parent_base; if (!parent || parent->destroyed || !popup_spec_valid(parent, spec)) return NULL; - struct x11_display *d = display_of(parent_base); + struct x11_display *d = (struct x11_display *)parent_base->display; struct x11_surface *s = calloc(1, sizeof(*s)); if (!s) return NULL; s->base.display = parent_base->display; @@ -874,7 +869,7 @@ static bool surface_popup_reposition(struct yasl_surface *popup_base, if (!s || s->destroyed || !s->is_popup || !s->parent || s->parent->destroyed || !popup_spec_valid(s->parent, spec)) return false; - struct x11_display *d = display_of(popup_base); + struct x11_display *d = (struct x11_display *)popup_base->display; if (spec->size.x != s->size.x || spec->size.y != s->size.y) { if (!resize(s, spec->size)) return false; @@ -893,7 +888,7 @@ static bool surface_popup_reposition(struct yasl_surface *popup_base, static void update_state(struct x11_surface *s) { - struct x11_display *d = display_of(&s->base); + struct x11_display *d = (struct x11_display *)s->base.display; Atom actual; int format; unsigned long count, left; @@ -1117,7 +1112,7 @@ static void refresh_keyboard(struct x11_display *d) static void key_event(struct x11_surface *s, XKeyEvent *key, bool repeat) { - struct x11_display *d = display_of(&s->base); + struct x11_display *d = (struct x11_display *)s->base.display; d->mods = modifiers(key->state); unsigned clean_state = key->state & ~(Mod2Mask | LockMask); KeySym sym = NoSymbol, base = NoSymbol, shifted = NoSymbol; @@ -1431,7 +1426,7 @@ static bool present(struct yasl_surface *base, const struct yasl_framebuffer *fb if (s->destroyed || !s->drawing || s->presented || !fb || !damage || fb->pixels != s->pixels || fb->size.x != s->size.x || fb->size.y != s->size.y || damage->n < -1 || damage->n > YASL_DAMAGE_MAX) return false; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; XImage *im = s->image; if (s->shm_active) { if (damage->n == -1) @@ -1740,7 +1735,7 @@ static void schedule_redraw(struct yasl_surface *base) struct x11_surface *s = (struct x11_surface *)base; if (!s->destroyed) { s->want_draw = true; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; if (d && d->loop) yasl_loop_kick(d->loop); } @@ -1779,7 +1774,7 @@ static void cursor(struct yasl_surface *base, enum yasl_cursor cursor) XC_sb_h_double_arrow, XC_sb_v_double_arrow}; struct x11_surface *s = (struct x11_surface *)base; if (s->destroyed || (unsigned)cursor > YASL_CURSOR_HIDDEN) return; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; if (!d->native) return; if (!d->cursors[cursor]) { @@ -1800,7 +1795,7 @@ static void cursor(struct yasl_surface *base, enum yasl_cursor cursor) static bool place(struct yasl_surface *base, struct yasl_vector2i at) { struct x11_surface *s = (struct x11_surface *)base; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; Window root, child; int root_x, root_y, x, y; unsigned mask; @@ -1925,7 +1920,7 @@ static void drag_cancel(struct yasl_display *base) static bool drag_carry(struct yasl_surface *base, struct yasl_vector2i offset) { - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; if (!d || !d->drag.active) return false; if (d->drag.icon_window && d->native) { @@ -1944,7 +1939,7 @@ static bool drag_carry(struct yasl_surface *base, struct yasl_vector2i offset) static bool interactive_move(struct yasl_surface *base) { struct x11_surface *s = (struct x11_surface *)base; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; Window root, child; int rx, ry, x, y; unsigned mask; @@ -1958,7 +1953,7 @@ static bool interactive_move(struct yasl_surface *base) static bool interactive_resize(struct yasl_surface *base, enum yasl_resize_edge edge) { struct x11_surface *s = (struct x11_surface *)base; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; Window root, child; int rx, ry, x, y; unsigned mask; @@ -1986,7 +1981,7 @@ static bool interactive_resize(struct yasl_surface *base, enum yasl_resize_edge static bool show_window_menu(struct yasl_surface *base, struct yasl_vector2i pos) { struct x11_surface *s = (struct x11_surface *)base; - struct x11_display *d = display_of(base); + struct x11_display *d = (struct x11_display *)base->display; if (s->destroyed || !d->native) return false; Atom atom = XInternAtom(d->native, "_GTK_SHOW_WINDOW_MENU", False); net_message(s, atom, s->window, pos.x, pos.y, 0, 0); diff --git a/tests/common/test_tablet_example.c b/tests/common/test_tablet_example.c index 1658174..15dde9c 100644 --- a/tests/common/test_tablet_example.c +++ b/tests/common/test_tablet_example.c @@ -11,43 +11,48 @@ static void pointer(struct app *app, enum yasl_pointer_kind kind, input(app, &event); } -static uint32_t pixel(const struct app *app, int x, int y) -{ - return app->canvas[(size_t)y * app->geometry.size.x + x]; -} - int main(void) { struct app app = {0}; assert(resize_canvas(&app, (struct yasl_geometry){{400, 300}, 120})); pointer(&app, YASL_PTR_MOTION, YASL_PTR_DEV_PEN, 3, 80, 160, 65535); - assert(pixel(&app, 80, 160) == PAPER); /* Hover never paints. */ + /* Hover never paints. */ + assert(app.canvas[(size_t)160 * app.geometry.size.x + 80] == PAPER); pointer(&app, YASL_PTR_PRESS, YASL_PTR_DEV_PEN, 2, 80, 160, 65535); - assert(!app.down && pixel(&app, 80, 160) == PAPER); /* Side button isn't the tip. */ + /* Side button isn't the tip. */ + assert(!app.down && + app.canvas[(size_t)160 * app.geometry.size.x + 80] == PAPER); pointer(&app, YASL_PTR_PRESS, YASL_PTR_DEV_PEN, 0, 80, 160, 0); - assert(app.down && pixel(&app, 80, 160) == INK && pixel(&app, 90, 160) == PAPER); + assert(app.down && + app.canvas[(size_t)160 * app.geometry.size.x + 80] == INK && + app.canvas[(size_t)160 * app.geometry.size.x + 90] == PAPER); pointer(&app, YASL_PTR_MOTION, YASL_PTR_DEV_PEN, 0, 80, 160, 65535); - assert(pixel(&app, 100, 160) == INK); /* Stationary pressure widens brush. */ + /* Stationary pressure widens brush. */ + assert(app.canvas[(size_t)160 * app.geometry.size.x + 100] == INK); pointer(&app, YASL_PTR_MOTION, YASL_PTR_DEV_PEN, 0, 180, 160, 20000); - assert(pixel(&app, 130, 160) == INK); /* Segments are continuous. */ + /* Segments are continuous. */ + assert(app.canvas[(size_t)160 * app.geometry.size.x + 130] == INK); pointer(&app, YASL_PTR_RELEASE, YASL_PTR_DEV_PEN, 0, 180, 160, 0); pointer(&app, YASL_PTR_MOTION, YASL_PTR_DEV_PEN, 3, 250, 160, 65535); - assert(!app.down && pixel(&app, 250, 160) == PAPER); + assert(!app.down && app.canvas[(size_t)160 * app.geometry.size.x + 250] == PAPER); pointer(&app, YASL_PTR_PRESS, YASL_PTR_DEV_ERASER, 0, 80, 160, 65535); - assert(pixel(&app, 80, 160) == PAPER && pixel(&app, 130, 160) == INK); + assert(app.canvas[(size_t)160 * app.geometry.size.x + 80] == PAPER && + app.canvas[(size_t)160 * app.geometry.size.x + 130] == INK); struct yasl_input_event reset = {.kind = YASL_INPUT_RESET}; input(&app, &reset); pointer(&app, YASL_PTR_MOTION, YASL_PTR_DEV_ERASER, 0, 130, 160, 65535); - assert(!app.down && pixel(&app, 130, 160) == INK); + assert(!app.down && app.canvas[(size_t)160 * app.geometry.size.x + 130] == INK); pointer(&app, YASL_PTR_PRESS, YASL_PTR_DEV_MOUSE, 0, 300, 200, 0); - assert(pixel(&app, 300, 200) == INK); + assert(app.canvas[(size_t)200 * app.geometry.size.x + 300] == INK); struct yasl_input_event blur = {.kind = YASL_INPUT_FOCUS, .focus.focused = false}; input(&app, &blur); assert(!app.down); assert(resize_canvas(&app, (struct yasl_geometry){{800, 600}, 240})); - assert(pixel(&app, 600, 400) == INK && !app.previous); /* DPI preserves logical drawing. */ + /* DPI preserves logical drawing. */ + assert(app.canvas[(size_t)400 * app.geometry.size.x + 600] == INK && + !app.previous); clear_canvas(&app); - assert(pixel(&app, 600, 400) == PAPER); + assert(app.canvas[(size_t)400 * app.geometry.size.x + 600] == PAPER); free(app.canvas); return 0; } diff --git a/tests/wayland/test_clipboard.c b/tests/wayland/test_clipboard.c index 825564e..ff84209 100644 --- a/tests/wayland/test_clipboard.c +++ b/tests/wayland/test_clipboard.c @@ -30,7 +30,7 @@ int main(void) received = (struct received){0}; int fds[2]; assert(pipe(fds) == 0); - assert(start_transfer(&c, fds[0], false, false)); + assert(start_transfer_text(&c, fds[0], false, false, c.text)); assert(write(fds[1], cases[i].bytes, cases[i].len) == (ssize_t)cases[i].len); close(fds[1]); for (int steps = 0; c.transfers && steps < 10; steps++) diff --git a/tests/x11/test_tablet_native.c b/tests/x11/test_tablet_native.c index 6e7eeb4..f12ec7f 100644 --- a/tests/x11/test_tablet_native.c +++ b/tests/x11/test_tablet_native.c @@ -75,11 +75,6 @@ static void pump(int fd, struct yasl_display *display, struct yasl_surface *surf assert(!app->failed); } -static uint32_t canvas_pixel(struct app *app, int x, int y) -{ - return app->canvas[(size_t)y * app->geometry.size.x + x]; -} - static void set_eraser_property(Display *display) { int count = 0; @@ -134,20 +129,21 @@ int main(int argc, char **argv) pump(pen_fd, display, surface, &app); assert(app.visible && !app.down && app.pointer.device == YASL_PTR_DEV_PEN); assert(app.pointer.pos.x == 150 && app.pointer.pos.y == 200); - assert(canvas_pixel(&app, 150, 200) == PAPER); + assert(app.canvas[(size_t)200 * app.geometry.size.x + 150] == PAPER); xf86ITEventButton button = {.header = {sizeof(button), XF86IT_EVENT_BUTTON}, .is_absolute = 1, .button = 1, .is_press = 1, .valuators = motion.valuators}; button.valuators.valuators[4] = 250; /* Driver pressure range is 0..1000. */ send_all(pen_fd, &button, sizeof(button)); pump(pen_fd, display, surface, &app); assert(app.down && app.pointer.pen.pressure == 16384); - assert(canvas_pixel(&app, 150, 200) == INK && canvas_pixel(&app, 170, 200) == PAPER); + assert(app.canvas[(size_t)200 * app.geometry.size.x + 150] == INK && + app.canvas[(size_t)200 * app.geometry.size.x + 170] == PAPER); motion.valuators.mask[0] = 1 << 4; /* No position change. */ motion.valuators.valuators[4] = 1000; send_all(pen_fd, &motion, sizeof(motion)); pump(pen_fd, display, surface, &app); assert(app.down && app.pointer.pen.pressure == 65535); - assert(canvas_pixel(&app, 170, 200) == INK); + assert(app.canvas[(size_t)200 * app.geometry.size.x + 170] == INK); /* Check the actual window's pixels too, after the example presents. */ XImage *image = XGetImage(x, window, 170, 200, 1, 1, AllPlanes, ZPixmap); assert(image && (XGetPixel(image, 0, 0) & 0xffffff) == (INK & 0xffffff)); @@ -165,7 +161,8 @@ int main(int argc, char **argv) send_all(eraser_fd, &button, sizeof(button)); pump(eraser_fd, display, surface, &app); assert(app.down && app.pointer.device == YASL_PTR_DEV_ERASER && app.pointer.pen.pressure == 65535); - assert(canvas_pixel(&app, 150, 200) == PAPER && canvas_pixel(&app, 170, 200) == PAPER); + assert(app.canvas[(size_t)200 * app.geometry.size.x + 150] == PAPER && + app.canvas[(size_t)200 * app.geometry.size.x + 170] == PAPER); button.is_press = 0; send_all(eraser_fd, &button, sizeof(button)); pump(eraser_fd, display, surface, &app); |
