diff options
Diffstat (limited to 'src/platform/wayland/surface.c')
| -rw-r--r-- | src/platform/wayland/surface.c | 119 |
1 files changed, 77 insertions, 42 deletions
diff --git a/src/platform/wayland/surface.c b/src/platform/wayland/surface.c index 2e85e2b..31096f4 100644 --- a/src/platform/wayland/surface.c +++ b/src/platform/wayland/surface.c @@ -52,7 +52,7 @@ static void display_lose(struct wayland_display *c) surface_fail(w); } display_leave(c); - yasl_display_notify_event(&c->base, YASL_EVENT_DISPLAY_LOST); + yasl_private_display_notify_event(&c->base, YASL_PRIVATE_EVENT_DISPLAY_LOST); } void surface_fail(struct wayland_surface *w) @@ -60,7 +60,7 @@ void surface_fail(struct wayland_surface *w) if (w->closed) return; w->closed = true; - yasl_surface_notify_close(&w->base); + yasl_private_surface_notify_close(&w->base); } static int display_ready(int fd, short revents, void *ud) @@ -80,7 +80,7 @@ static int display_ready(int fd, short revents, void *ud) if (revents & POLLOUT) { if (wl_display_flush(c->wl) >= 0) { if (c->loop && c->watch > 0) - yasl_loop_set_fd_events(c->loop, c->watch, POLLIN); + yasl_private_loop_set_fd_events(c->loop, c->watch, POLLIN); } else if (errno != EAGAIN) { display_lose(c); } @@ -113,7 +113,7 @@ static bool display_arm(struct wayland_display *c) events |= POLLOUT; } if (c->loop && c->watch > 0) - yasl_loop_set_fd_events(c->loop, c->watch, events); + yasl_private_loop_set_fd_events(c->loop, c->watch, events); return had_pending; } @@ -154,7 +154,7 @@ int wayland_display_dispatch_timeout(struct wayland_display *c, int timeout_ms) int n = 0; if (c->loop) { - n = yasl_loop_step(c->loop, timeout_ms); + n = yasl_private_loop_step(c->loop, timeout_ms); } if (c->reading) { @@ -190,7 +190,7 @@ void wayland_display_flush(struct wayland_display *c) static void display_free(struct wayland_display *c) { conn_drag_end(c); - if (c->loop && c->watch > 0) yasl_loop_del_fd(c->loop, c->watch); + if (c->loop && c->watch > 0) yasl_private_loop_del_fd(c->loop, c->watch); if (c->wl) display_cancel_read(c); while (c->seats) seat_destroy(c->seats); @@ -217,9 +217,12 @@ static void display_free(struct wayland_display *c) if (c->shm) wl_shm_destroy(c->shm); if (c->compositor) wl_compositor_destroy(c->compositor); if (c->registry) wl_registry_destroy(c->registry); +#if YASL_HAS_EGL + if (c->egl_initialized) eglTerminate(c->egl_display); +#endif if (c->wl) wl_display_disconnect(c->wl); if (c->owns_loop && c->loop) { - yasl_loop_destroy(c->loop); + yasl_private_loop_destroy(c->loop); c->loop = NULL; c->base.loop = NULL; } @@ -227,13 +230,13 @@ static void display_free(struct wayland_display *c) free(c); } -struct wayland_display *wayland_display_open(struct yasl_loop *loop, const struct yasl_display_spec *spec) +struct wayland_display *wayland_display_open(struct yasl_private_loop *loop, const struct yasl_private_display_spec *spec) { struct wayland_display *c = calloc(1, sizeof(*c)); if (!c) return NULL; - c->base.ops = &yasl_wayland_backend; + c->base.ops = &yasl_private_wayland_backend; if (!loop) { - c->loop = yasl_loop_create(); + c->loop = yasl_private_loop_create(); c->owns_loop = true; } else { c->loop = loop; @@ -241,7 +244,7 @@ struct wayland_display *wayland_display_open(struct yasl_loop *loop, const struc c->base.loop = c->loop; if (!c->loop) goto err; if (spec) { - c->base.callbacks = spec->cbs ? *spec->cbs : (struct yasl_display_cbs){0}; + c->base.callbacks = spec->cbs ? *spec->cbs : (struct yasl_private_display_cbs){0}; c->cbs = &c->base.callbacks; c->ud = spec->ud; if (spec->app_id) c->app_id = strdup(spec->app_id); @@ -251,6 +254,13 @@ struct wayland_display *wayland_display_open(struct yasl_loop *loop, const struc c->wl = c->xkb_ctx ? wl_display_connect(NULL) : NULL; if (!c->wl) goto err; c->base.native_handle = c->wl; +#if YASL_HAS_EGL + c->egl_display = eglGetDisplay((EGLNativeDisplayType)c->wl); + if (c->egl_display != EGL_NO_DISPLAY) { + EGLint major = 0, minor = 0; + c->egl_initialized = eglInitialize(c->egl_display, &major, &minor) == EGL_TRUE; + } +#endif c->registry = wl_display_get_registry(c->wl); if (!c->registry) goto err; @@ -260,7 +270,7 @@ struct wayland_display *wayland_display_open(struct yasl_loop *loop, const struc surface_init_cursor(c); if (c->loop) { - c->watch = yasl_loop_add_fd(c->loop, wl_display_get_fd(c->wl), POLLIN, display_ready, c); + c->watch = yasl_private_loop_add_fd(c->loop, wl_display_get_fd(c->wl), POLLIN, display_ready, c); if (c->watch <= 0) { c->watch = 0; goto err; } } if (display_input_init(c) < 0) @@ -282,16 +292,18 @@ void wayland_display_close(struct wayland_display *c) 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; + uint32_t caps = YASL_PRIVATE_CAP_POPUPS | YASL_PRIVATE_CAP_CSD | + YASL_PRIVATE_CAP_FRAME_PACING | YASL_PRIVATE_CAP_NATIVE_GRAPHICS; + if (c->tablet_mgr) caps |= YASL_PRIVATE_CAP_TABLET; + if (c->text_input_mgr) caps |= YASL_PRIVATE_CAP_TEXT_INPUT; 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; + caps |= YASL_PRIVATE_CAP_DRAG; if (c->toplevel_drag_mgr) - caps |= YASL_CAP_DRAG_CARRY; + caps |= YASL_PRIVATE_CAP_DRAG_CARRY; if (c->primary_selection_mgr) - caps |= YASL_CAP_PRIMARY_SELECTION; + caps |= YASL_PRIVATE_CAP_PRIMARY_SELECTION; return caps; } @@ -321,15 +333,18 @@ static void conn_unlink(struct wayland_surface *w) } -static bool spec_valid(const struct yasl_window_spec *spec) +static bool spec_valid(const struct yasl_private_window_spec *spec) { size_t bytes; - return spec && spec->size.x > 0 && spec->size.y > 0 && - buffer_size(spec->size.x, spec->size.y, &bytes); + if (!spec || spec->size.x <= 0 || spec->size.y <= 0) + return false; + return spec->external_gpu && !(spec->flags & YASL_PRIVATE_SURFACE_CPU) + ? spec->size.x <= INT32_MAX && spec->size.y <= INT32_MAX + : buffer_size(spec->size.x, spec->size.y, &bytes); } struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display *c, - const struct yasl_window_spec *spec, void *graphics_device) + const struct yasl_private_window_spec *spec, void *graphics_device) { (void)graphics_device; if (!c || c->lost || !spec_valid(spec)) @@ -340,28 +355,35 @@ struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display * if (!w) return NULL; c->depth++; conn_link(c, w); - w->base.state = YASL_STATE_CSD; + w->base.state = YASL_PRIVATE_STATE_CSD; + w->base.creation_flags = spec->flags; + w->base.presenter = (spec->external_gpu && !(spec->flags & YASL_PRIVATE_SURFACE_CPU)) + ? YASL_PRIVATE_PRESENTER_NONE : YASL_PRIVATE_PRESENTER_CPU; wayland_surface_set_callbacks(w, NULL, NULL); - w->cursor = YASL_CURSOR_TEXT; + w->cursor = YASL_PRIVATE_CURSOR_TEXT; w->req_width = width; w->req_height = height; w->logical_width = width; w->logical_height = height; - w->scale_120 = YASL_SCALE_UNIT; - w->pending_scale_120 = YASL_SCALE_UNIT; + w->scale_120 = YASL_PRIVATE_SCALE_UNIT; + w->pending_scale_120 = YASL_PRIVATE_SCALE_UNIT; w->scale_factor = 1.0; w->size_pending = true; w->clock.refresh_ns = c->outputs && c->outputs->refresh_ns - ? c->outputs->refresh_ns : YASL_REFRESH_DEFAULT_NS; + ? c->outputs->refresh_ns : YASL_PRIVATE_REFRESH_DEFAULT_NS; w->surface = wl_compositor_create_surface(c->compositor); if (!w->surface) goto err; w->base.native_handle = w->surface; - w->base.size = (struct yasl_vector2i){width, height}; - w->base.scale_120 = YASL_SCALE_UNIT; + w->base.size = (struct yasl_private_vector2i){width, height}; + w->base.scale_120 = YASL_PRIVATE_SCALE_UNIT; wl_surface_set_user_data(w->surface, w); if (surface_init_scaling(w) < 0) goto err; if (surface_init_shell(w, spec->title) < 0) goto err; + if (spec->flags & YASL_PRIVATE_SURFACE_FIXED_SIZE) { + xdg_toplevel_set_min_size(w->toplevel, width, height); + xdg_toplevel_set_max_size(w->toplevel, width, height); + } w->opaque = spec->fullscreen; if (spec->fullscreen) xdg_toplevel_set_fullscreen(w->toplevel, NULL); @@ -389,10 +411,10 @@ err: return NULL; } -void wayland_surface_set_callbacks(struct wayland_surface *w, const struct yasl_window_cbs *cbs, void *ud) +void wayland_surface_set_callbacks(struct wayland_surface *w, const struct yasl_private_window_cbs *cbs, void *ud) { if (w && !w->closed) { - w->base.callbacks = cbs ? *cbs : (struct yasl_window_cbs){0}; + w->base.callbacks = cbs ? *cbs : (struct yasl_private_window_cbs){0}; w->base.ud = ud; w->cbs = &w->base.callbacks; w->ud = ud; @@ -410,6 +432,15 @@ void wayland_surface_destroy(struct wayland_surface *w) free(w->ime_commit); free(w->ime_shown); if (w->tearing_control) wp_tearing_control_v1_destroy(w->tearing_control); +#if YASL_HAS_EGL + if (w->egl_context) { + if (eglGetCurrentContext() == w->egl_context) + eglMakeCurrent(w->conn->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(w->conn->egl_display, w->egl_context); + } + if (w->egl_surface) eglDestroySurface(w->conn->egl_display, w->egl_surface); + if (w->egl_window) wl_egl_window_destroy(w->egl_window); +#endif if (w->fifo) wp_fifo_v1_destroy(w->fifo); if (w->commit_timer) wp_commit_timer_v1_destroy(w->commit_timer); surface_feedback_destroy(w); @@ -427,7 +458,7 @@ void wayland_surface_destroy(struct wayland_surface *w) } struct wayland_display *c = w->conn; conn_unlink(w); - static const struct yasl_window_cbs no_callbacks = {0}; + static const struct yasl_private_window_cbs no_callbacks = {0}; *w = (struct wayland_surface){ .base = w->base, .conn_next = w->conn_next, @@ -446,16 +477,20 @@ void wayland_surface_destroy(struct wayland_surface *w) void wayland_surface_schedule_redraw(struct wayland_surface *w) { if (!w || w->closed) return; + if (w->base.presenter != YASL_PRIVATE_PRESENTER_CPU) { + yasl_private_surface_notify_refresh(&w->base); + return; + } w->want_draw = true; if (w->conn && w->conn->loop) - yasl_loop_kick(w->conn->loop); + yasl_private_loop_kick(w->conn->loop); } -struct yasl_geometry wayland_surface_geometry(const struct wayland_surface *w) +struct yasl_private_geometry wayland_surface_geometry(const struct wayland_surface *w) { - return (struct yasl_geometry){ - .size = w ? (struct yasl_vector2i){w->width, w->height} : (struct yasl_vector2i){0}, - .scale_120 = w ? w->scale_120 : YASL_SCALE_UNIT, + return (struct yasl_private_geometry){ + .size = w ? (struct yasl_private_vector2i){w->width, w->height} : (struct yasl_private_vector2i){0}, + .scale_120 = w ? w->scale_120 : YASL_PRIVATE_SCALE_UNIT, }; } @@ -473,23 +508,23 @@ bool wayland_surface_start_interactive_move(struct wayland_surface *s) return true; } -bool wayland_surface_start_interactive_resize(struct wayland_surface *s, enum yasl_resize_edge edge) +bool wayland_surface_start_interactive_resize(struct wayland_surface *s, enum yasl_private_resize_edge edge) { - if (!s || !s->toplevel || !s->conn || edge == YASL_EDGE_NONE) return false; + if (!s || !s->toplevel || !s->conn || edge == YASL_PRIVATE_EDGE_NONE) return false; 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; } -bool wayland_surface_show_window_menu(struct wayland_surface *s, struct yasl_vector2i pos) +bool wayland_surface_show_window_menu(struct wayland_surface *s, struct yasl_private_vector2i pos) { if (!s || !s->toplevel || !s->conn) return false; 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; + uint32_t scale = s->scale_120 ? s->scale_120 : YASL_PRIVATE_SCALE_UNIT; xdg_toplevel_show_window_menu(s->toplevel, seat->proxy, seat->press_serial, - yasl_scale_to_logical(pos.x, scale), - yasl_scale_to_logical(pos.y, scale)); + yasl_private_scale_to_logical(pos.x, scale), + yasl_private_scale_to_logical(pos.y, scale)); return true; } |
