mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-21 06:46:46 -04:00
Merge upstream
This commit is contained in:
commit
c673b684a0
203 changed files with 6752 additions and 4861 deletions
|
|
@ -23,14 +23,14 @@ sources:
|
|||
tasks:
|
||||
- setup: |
|
||||
cd wlroots
|
||||
CC=gcc meson build-gcc --fatal-meson-warnings --default-library=both -Dauto_features=enabled --prefix /usr
|
||||
CC=gcc meson build-gcc --fatal-meson-warnings --default-library=both -Dauto_features=enabled --prefix /usr -Db_sanitize=address,undefined
|
||||
CC=clang meson build-clang --fatal-meson-warnings -Dauto_features=enabled
|
||||
- gcc: |
|
||||
cd wlroots/build-gcc
|
||||
ninja
|
||||
sudo ninja install
|
||||
cd ../tinywl
|
||||
make
|
||||
CFLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" make
|
||||
- clang: |
|
||||
cd wlroots/build-clang
|
||||
ninja
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ charset = utf-8
|
|||
trim_trailing_whitespace = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
max_line_length = 80
|
||||
|
||||
[*.xml]
|
||||
indent_style = space
|
||||
|
|
|
|||
|
|
@ -186,16 +186,23 @@ all of the characters, and replace any invalid characters with an underscore.
|
|||
|
||||
### Construction/Destruction Functions
|
||||
|
||||
For functions that are responsible for constructing and destructing an object,
|
||||
they should be written as a pair of one of two forms:
|
||||
* `init`/`finish`: These initialize/deinitialize a type, but are **NOT**
|
||||
responsible for allocating it. They should accept a pointer to some
|
||||
pre-allocated memory (e.g. a member of a struct).
|
||||
* `create`/`destroy`: These also initialize/deinitialize, but will return a
|
||||
pointer to a `malloc`ed chunk of memory, and will `free` it in `destroy`.
|
||||
Functions that are responsible for constructing objects should take one of the
|
||||
two following forms:
|
||||
|
||||
A destruction function should always be able to accept a NULL pointer or a
|
||||
zeroed value and exit cleanly; this simplifies error handling a lot.
|
||||
* `init`: for functions which accept a pointer to a pre-allocated object (e.g.
|
||||
a member of a struct) and initialize it.
|
||||
* `create`: for functions which allocate the memory for an object, initialize
|
||||
it, and return a pointer.
|
||||
|
||||
Likewise, functions that are responsible for destructing objects should take
|
||||
one of the two following forms:
|
||||
|
||||
* `finish`: for functions which accept a pointer to an object and deinitialize
|
||||
it. Such functions should always be able to accept an already deinitialized
|
||||
object.
|
||||
* `destroy`: for functions which accept a pointer to an object, deinitialize
|
||||
it, and free the memory. Such functions should always be able to accept a NULL
|
||||
pointer.
|
||||
|
||||
### Error Codes
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,8 @@ to implement yourself.
|
|||
Check out our [wiki] to get started with wlroots. Join our IRC channel:
|
||||
[#sway-devel on Libera Chat].
|
||||
|
||||
wlroots is developed under the direction of the [sway] project. A variety of
|
||||
[wrapper libraries] are available for using it with your favorite programming
|
||||
language.
|
||||
A variety of [wrapper libraries] are available for using it with your favorite
|
||||
programming language.
|
||||
|
||||
## Building
|
||||
|
||||
|
|
@ -77,7 +76,6 @@ See [CONTRIBUTING.md].
|
|||
[Wayland]: https://wayland.freedesktop.org/
|
||||
[wiki]: https://gitlab.freedesktop.org/wlroots/wlroots/-/wikis/Getting-started
|
||||
[#sway-devel on Libera Chat]: https://web.libera.chat/gamja/?channels=#sway-devel
|
||||
[Sway]: https://github.com/swaywm/sway
|
||||
[wrapper libraries]: https://github.com/search?q=topic%3Abindings+org%3Aswaywm&type=Repositories
|
||||
[wrapper libraries]: https://gitlab.freedesktop.org/wlroots/wlroots/-/wikis/Projects-which-use-wlroots#wrapper-libraries
|
||||
[libseat]: https://git.sr.ht/~kennylevinsen/seatd
|
||||
[CONTRIBUTING.md]: https://gitlab.freedesktop.org/wlroots/wlroots/-/blob/master/CONTRIBUTING.md
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include <wlr/backend/headless.h>
|
||||
#include <wlr/backend/interface.h>
|
||||
#include <wlr/backend/multi.h>
|
||||
#include <wlr/backend/noop.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/backend/wayland.h>
|
||||
#include <wlr/config.h>
|
||||
|
|
@ -22,6 +21,7 @@
|
|||
|
||||
#if WLR_HAS_DRM_BACKEND
|
||||
#include <wlr/backend/drm.h>
|
||||
#include "backend/drm/monitor.h"
|
||||
#endif
|
||||
|
||||
#if WLR_HAS_LIBINPUT_BACKEND
|
||||
|
|
@ -45,10 +45,6 @@ void wlr_backend_init(struct wlr_backend *backend,
|
|||
|
||||
void wlr_backend_finish(struct wlr_backend *backend) {
|
||||
wlr_signal_emit_safe(&backend->events.destroy, backend);
|
||||
wlr_allocator_destroy(backend->allocator);
|
||||
if (backend->has_own_renderer) {
|
||||
wlr_renderer_destroy(backend->renderer);
|
||||
}
|
||||
}
|
||||
|
||||
bool wlr_backend_start(struct wlr_backend *backend) {
|
||||
|
|
@ -70,36 +66,6 @@ void wlr_backend_destroy(struct wlr_backend *backend) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool backend_create_renderer(struct wlr_backend *backend) {
|
||||
if (backend->renderer != NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
backend->renderer = wlr_renderer_autocreate(backend);
|
||||
if (backend->renderer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
backend->has_own_renderer = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend) {
|
||||
if (backend->impl->get_renderer) {
|
||||
return backend->impl->get_renderer(backend);
|
||||
}
|
||||
if (backend_get_buffer_caps(backend) != 0) {
|
||||
// If the backend is capable of presenting buffers, automatically create
|
||||
// the renderer if necessary.
|
||||
if (!backend_create_renderer(backend)) {
|
||||
wlr_log(WLR_ERROR, "Failed to create backend renderer");
|
||||
return NULL;
|
||||
}
|
||||
return backend->renderer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend) {
|
||||
if (backend->impl->get_session) {
|
||||
return backend->impl->get_session(backend);
|
||||
|
|
@ -175,23 +141,6 @@ uint32_t backend_get_buffer_caps(struct wlr_backend *backend) {
|
|||
return backend->impl->get_buffer_caps(backend);
|
||||
}
|
||||
|
||||
struct wlr_allocator *backend_get_allocator(struct wlr_backend *backend) {
|
||||
if (backend->allocator != NULL) {
|
||||
return backend->allocator;
|
||||
}
|
||||
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(backend);
|
||||
if (renderer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
backend->allocator = wlr_allocator_autocreate(backend, renderer);
|
||||
if (backend->allocator == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to create backend allocator");
|
||||
}
|
||||
return backend->allocator;
|
||||
}
|
||||
|
||||
static size_t parse_outputs_env(const char *name) {
|
||||
const char *outputs_str = getenv(name);
|
||||
if (outputs_str == NULL) {
|
||||
|
|
@ -208,21 +157,6 @@ static size_t parse_outputs_env(const char *name) {
|
|||
return outputs;
|
||||
}
|
||||
|
||||
static struct wlr_backend *ensure_backend_renderer_and_allocator(
|
||||
struct wlr_backend *backend) {
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(backend);
|
||||
if (renderer == NULL) {
|
||||
wlr_backend_destroy(backend);
|
||||
return NULL;
|
||||
}
|
||||
struct wlr_allocator *allocator = backend_get_allocator(backend);
|
||||
if (allocator == NULL) {
|
||||
wlr_backend_destroy(backend);
|
||||
return NULL;
|
||||
}
|
||||
return backend;
|
||||
}
|
||||
|
||||
static struct wlr_backend *attempt_wl_backend(struct wl_display *display) {
|
||||
struct wlr_backend *backend = wlr_wl_backend_create(display, NULL);
|
||||
if (backend == NULL) {
|
||||
|
|
@ -234,7 +168,7 @@ static struct wlr_backend *attempt_wl_backend(struct wl_display *display) {
|
|||
wlr_wl_output_create(backend);
|
||||
}
|
||||
|
||||
return ensure_backend_renderer_and_allocator(backend);
|
||||
return backend;
|
||||
}
|
||||
|
||||
#if WLR_HAS_X11_BACKEND
|
||||
|
|
@ -250,7 +184,7 @@ static struct wlr_backend *attempt_x11_backend(struct wl_display *display,
|
|||
wlr_x11_output_create(backend);
|
||||
}
|
||||
|
||||
return ensure_backend_renderer_and_allocator(backend);
|
||||
return backend;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -266,20 +200,6 @@ static struct wlr_backend *attempt_headless_backend(
|
|||
wlr_headless_add_output(backend, 1280, 720);
|
||||
}
|
||||
|
||||
return ensure_backend_renderer_and_allocator(backend);
|
||||
}
|
||||
|
||||
static struct wlr_backend *attempt_noop_backend(struct wl_display *display) {
|
||||
struct wlr_backend *backend = wlr_noop_backend_create(display);
|
||||
if (backend == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t outputs = parse_outputs_env("WLR_NOOP_OUTPUTS");
|
||||
for (size_t i = 0; i < outputs; ++i) {
|
||||
wlr_noop_add_output(backend);
|
||||
}
|
||||
|
||||
return backend;
|
||||
}
|
||||
|
||||
|
|
@ -320,50 +240,48 @@ static struct wlr_backend *attempt_drm_backend(struct wl_display *display,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return ensure_backend_renderer_and_allocator(primary_drm);
|
||||
return primary_drm;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct wlr_backend *attempt_backend_by_name(struct wl_display *display,
|
||||
struct wlr_backend *backend, struct wlr_session **session,
|
||||
const char *name) {
|
||||
static bool attempt_backend_by_name(struct wl_display *display,
|
||||
struct wlr_multi_backend *multi, char *name) {
|
||||
struct wlr_backend *backend = NULL;
|
||||
if (strcmp(name, "wayland") == 0) {
|
||||
return attempt_wl_backend(display);
|
||||
backend = attempt_wl_backend(display);
|
||||
#if WLR_HAS_X11_BACKEND
|
||||
} else if (strcmp(name, "x11") == 0) {
|
||||
return attempt_x11_backend(display, NULL);
|
||||
backend = attempt_x11_backend(display, NULL);
|
||||
#endif
|
||||
} else if (strcmp(name, "headless") == 0) {
|
||||
return attempt_headless_backend(display);
|
||||
} else if (strcmp(name, "noop") == 0) {
|
||||
return attempt_noop_backend(display);
|
||||
backend = attempt_headless_backend(display);
|
||||
} else if (strcmp(name, "drm") == 0 || strcmp(name, "libinput") == 0) {
|
||||
// DRM and libinput need a session
|
||||
if (!*session) {
|
||||
*session = session_create_and_wait(display);
|
||||
if (!*session) {
|
||||
if (multi->session == NULL) {
|
||||
multi->session = session_create_and_wait(display);
|
||||
if (multi->session == NULL) {
|
||||
wlr_log(WLR_ERROR, "failed to start a session");
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(name, "libinput") == 0) {
|
||||
#if WLR_HAS_LIBINPUT_BACKEND
|
||||
return wlr_libinput_backend_create(display, *session);
|
||||
#else
|
||||
return NULL;
|
||||
backend = wlr_libinput_backend_create(display, multi->session);
|
||||
#endif
|
||||
} else {
|
||||
#if WLR_HAS_DRM_BACKEND
|
||||
return attempt_drm_backend(display, backend, *session);
|
||||
#else
|
||||
return NULL;
|
||||
// attempt_drm_backend adds the multi drm backends itself
|
||||
return attempt_drm_backend(display, &multi->backend,
|
||||
multi->session) != NULL;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "unrecognized backend '%s'", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
wlr_log(WLR_ERROR, "unrecognized backend '%s'", name);
|
||||
return NULL;
|
||||
return wlr_multi_backend_add(&multi->backend, backend);
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
|
||||
|
|
@ -389,17 +307,7 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
|
|||
char *saveptr;
|
||||
char *name = strtok_r(names, ",", &saveptr);
|
||||
while (name != NULL) {
|
||||
struct wlr_backend *subbackend = attempt_backend_by_name(display,
|
||||
backend, &multi->session, name);
|
||||
if (subbackend == NULL) {
|
||||
wlr_log(WLR_ERROR, "failed to start backend '%s'", name);
|
||||
wlr_session_destroy(multi->session);
|
||||
wlr_backend_destroy(backend);
|
||||
free(names);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!wlr_multi_backend_add(backend, subbackend)) {
|
||||
if (!attempt_backend_by_name(display, multi, name)) {
|
||||
wlr_log(WLR_ERROR, "failed to add backend '%s'", name);
|
||||
wlr_session_destroy(multi->session);
|
||||
wlr_backend_destroy(backend);
|
||||
|
|
@ -456,6 +364,19 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
|
|||
return NULL;
|
||||
}
|
||||
wlr_multi_backend_add(backend, libinput);
|
||||
#else
|
||||
const char *no_devs = getenv("WLR_LIBINPUT_NO_DEVICES");
|
||||
if (no_devs && strcmp(no_devs, "1") == 0) {
|
||||
wlr_log(WLR_INFO, "WLR_LIBINPUT_NO_DEVICES is set, "
|
||||
"starting without libinput backend");
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "libinput support is not compiled in, "
|
||||
"refusing to start");
|
||||
wlr_log(WLR_ERROR, "Set WLR_LIBINPUT_NO_DEVICES=1 to suppress this check");
|
||||
wlr_session_destroy(multi->session);
|
||||
wlr_backend_destroy(backend);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WLR_HAS_DRM_BACKEND
|
||||
|
|
@ -468,6 +389,8 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
drm_backend_monitor_create(backend, primary_drm, multi->session);
|
||||
|
||||
return backend;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -133,12 +133,15 @@ static void handle_dev_change(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: add and handle lease uevents
|
||||
switch (change->type) {
|
||||
case WLR_DEVICE_HOTPLUG:;
|
||||
case WLR_DEVICE_HOTPLUG:
|
||||
wlr_log(WLR_DEBUG, "Received hotplug event for %s", drm->name);
|
||||
scan_drm_connectors(drm, &change->hotplug);
|
||||
break;
|
||||
case WLR_DEVICE_LEASE:
|
||||
wlr_log(WLR_DEBUG, "Received lease event for %s", drm->name);
|
||||
scan_drm_leases(drm);
|
||||
break;
|
||||
default:
|
||||
wlr_log(WLR_DEBUG, "Received unknown change event for %s", drm->name);
|
||||
}
|
||||
|
|
@ -232,10 +235,6 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
|||
}
|
||||
|
||||
if (drm->parent) {
|
||||
// Ensure we use the same renderer as the parent backend
|
||||
drm->backend.renderer = wlr_backend_get_renderer(&drm->parent->backend);
|
||||
assert(drm->backend.renderer != NULL);
|
||||
|
||||
if (!init_drm_renderer(drm, &drm->mgpu_renderer)) {
|
||||
wlr_log(WLR_ERROR, "Failed to initialize renderer");
|
||||
goto error_resources;
|
||||
|
|
|
|||
|
|
@ -118,9 +118,15 @@ static bool add_plane(struct wlr_drm_backend *drm,
|
|||
p->id = drm_plane->plane_id;
|
||||
p->props = *props;
|
||||
|
||||
for (size_t j = 0; j < drm_plane->count_formats; ++j) {
|
||||
wlr_drm_format_set_add(&p->formats, drm_plane->formats[j],
|
||||
DRM_FORMAT_MOD_INVALID);
|
||||
for (size_t i = 0; i < drm_plane->count_formats; ++i) {
|
||||
// Force a LINEAR layout for the cursor if the driver doesn't support
|
||||
// modifiers
|
||||
wlr_drm_format_set_add(&p->formats, drm_plane->formats[i],
|
||||
DRM_FORMAT_MOD_LINEAR);
|
||||
if (type != DRM_PLANE_TYPE_CURSOR) {
|
||||
wlr_drm_format_set_add(&p->formats, drm_plane->formats[i],
|
||||
DRM_FORMAT_MOD_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
if (p->props.in_formats && drm->addfb2_modifiers) {
|
||||
|
|
@ -136,27 +142,12 @@ static bool add_plane(struct wlr_drm_backend *drm,
|
|||
goto error;
|
||||
}
|
||||
|
||||
struct drm_format_modifier_blob *data = blob->data;
|
||||
uint32_t *fmts = (uint32_t *)((char *)data + data->formats_offset);
|
||||
struct drm_format_modifier *mods = (struct drm_format_modifier *)
|
||||
((char *)data + data->modifiers_offset);
|
||||
for (uint32_t i = 0; i < data->count_modifiers; ++i) {
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
if (mods[i].formats & ((uint64_t)1 << j)) {
|
||||
wlr_drm_format_set_add(&p->formats,
|
||||
fmts[j + mods[i].offset], mods[i].modifier);
|
||||
}
|
||||
}
|
||||
drmModeFormatModifierIterator iter = {0};
|
||||
while (drmModeFormatModifierBlobIterNext(blob, &iter)) {
|
||||
wlr_drm_format_set_add(&p->formats, iter.fmt, iter.mod);
|
||||
}
|
||||
|
||||
drmModeFreePropertyBlob(blob);
|
||||
} else if (type == DRM_PLANE_TYPE_CURSOR) {
|
||||
// Force a LINEAR layout for the cursor if the driver doesn't support
|
||||
// modifiers
|
||||
for (size_t i = 0; i < p->formats.len; ++i) {
|
||||
wlr_drm_format_set_add(&p->formats, p->formats.formats[i]->format,
|
||||
DRM_FORMAT_MOD_LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
|
@ -1300,8 +1291,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
|||
wlr_output_init(&wlr_conn->output, &drm->backend, &output_impl,
|
||||
drm->display);
|
||||
|
||||
memcpy(wlr_conn->output.name, wlr_conn->name,
|
||||
sizeof(wlr_conn->output.name));
|
||||
wlr_output_set_name(&wlr_conn->output, wlr_conn->name);
|
||||
|
||||
wlr_conn->output.phys_width = drm_conn->mmWidth;
|
||||
wlr_conn->output.phys_height = drm_conn->mmHeight;
|
||||
|
|
@ -1431,6 +1421,36 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
|||
}
|
||||
}
|
||||
|
||||
void scan_drm_leases(struct wlr_drm_backend *drm) {
|
||||
drmModeLesseeListRes *list = drmModeListLessees(drm->fd);
|
||||
if (list == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "drmModeListLessees failed");
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_drm_connector *conn;
|
||||
wl_list_for_each(conn, &drm->outputs, link) {
|
||||
if (conn->lease == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < list->count; i++) {
|
||||
if (list->lessees[i] == conn->lease->lessee_id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
wlr_log(WLR_DEBUG, "DRM lease %"PRIu32" has been terminated",
|
||||
conn->lease->lessee_id);
|
||||
drm_lease_destroy(conn->lease);
|
||||
}
|
||||
}
|
||||
|
||||
drmFree(list);
|
||||
}
|
||||
|
||||
static int mhz_to_nsec(int mhz) {
|
||||
return 1000000000000LL / mhz;
|
||||
}
|
||||
|
|
@ -1560,17 +1580,13 @@ int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend) {
|
|||
return fd;
|
||||
}
|
||||
|
||||
/* TODO: make the function return a `wlr_drm_lease` to provide a destroy event
|
||||
* that can be fired when the kernel notifies us through uevent that the lease
|
||||
* has been destroyed
|
||||
*/
|
||||
int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
||||
uint32_t *lessee_id) {
|
||||
struct wlr_drm_lease *wlr_drm_create_lease(struct wlr_output **outputs,
|
||||
size_t n_outputs, int *lease_fd_ptr) {
|
||||
assert(outputs);
|
||||
|
||||
if (n_outputs == 0) {
|
||||
wlr_log(WLR_ERROR, "Can't lease 0 outputs");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_drm_backend *drm =
|
||||
|
|
@ -1581,11 +1597,11 @@ int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
|||
for (size_t i = 0; i < n_outputs; ++i) {
|
||||
struct wlr_drm_connector *conn =
|
||||
get_drm_connector_from_output(outputs[i]);
|
||||
assert(conn->lessee_id == 0);
|
||||
assert(conn->lease == NULL);
|
||||
|
||||
if (conn->backend != drm) {
|
||||
wlr_log(WLR_ERROR, "Can't lease output from different backends");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
objects[n_objects++] = conn->id;
|
||||
|
|
@ -1593,7 +1609,7 @@ int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
|||
|
||||
if (!conn->crtc) {
|
||||
wlr_log(WLR_ERROR, "Connector has no CRTC");
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
objects[n_objects++] = conn->crtc->id;
|
||||
|
|
@ -1610,50 +1626,63 @@ int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
|||
|
||||
assert(n_objects != 0);
|
||||
|
||||
wlr_log(WLR_DEBUG, "Issuing DRM lease with the %d objects", n_objects);
|
||||
int lease_fd = drmModeCreateLease(drm->fd, objects, n_objects, 0,
|
||||
lessee_id);
|
||||
if (lease_fd < 0) {
|
||||
return lease_fd;
|
||||
struct wlr_drm_lease *lease = calloc(1, sizeof(*lease));
|
||||
if (lease == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Issued DRM lease %"PRIu32, *lessee_id);
|
||||
lease->backend = drm;
|
||||
wl_signal_init(&lease->events.destroy);
|
||||
|
||||
wlr_log(WLR_DEBUG, "Issuing DRM lease with %d objects", n_objects);
|
||||
int lease_fd = drmModeCreateLease(drm->fd, objects, n_objects, 0,
|
||||
&lease->lessee_id);
|
||||
if (lease_fd < 0) {
|
||||
free(lease);
|
||||
return NULL;
|
||||
}
|
||||
*lease_fd_ptr = lease_fd;
|
||||
|
||||
wlr_log(WLR_DEBUG, "Issued DRM lease %"PRIu32, lease->lessee_id);
|
||||
for (size_t i = 0; i < n_outputs; ++i) {
|
||||
struct wlr_drm_connector *conn =
|
||||
get_drm_connector_from_output(outputs[i]);
|
||||
conn->lessee_id = *lessee_id;
|
||||
conn->crtc->lessee_id = *lessee_id;
|
||||
conn->lease = lease;
|
||||
conn->crtc->lease = lease;
|
||||
}
|
||||
|
||||
return lease_fd;
|
||||
return lease;
|
||||
}
|
||||
|
||||
bool wlr_drm_backend_terminate_lease(struct wlr_backend *backend,
|
||||
uint32_t lessee_id) {
|
||||
wlr_log(WLR_DEBUG, "Terminating DRM lease %d", lessee_id);
|
||||
void wlr_drm_lease_terminate(struct wlr_drm_lease *lease) {
|
||||
struct wlr_drm_backend *drm = lease->backend;
|
||||
|
||||
assert(backend);
|
||||
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
|
||||
|
||||
int r = drmModeRevokeLease(drm->fd, lessee_id);
|
||||
if (r < 0) {
|
||||
wlr_log_errno(WLR_DEBUG, "Failed to terminate lease");
|
||||
wlr_log(WLR_DEBUG, "Terminating DRM lease %d", lease->lessee_id);
|
||||
int ret = drmModeRevokeLease(drm->fd, lease->lessee_id);
|
||||
if (ret < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to terminate lease");
|
||||
}
|
||||
|
||||
drm_lease_destroy(lease);
|
||||
}
|
||||
|
||||
void drm_lease_destroy(struct wlr_drm_lease *lease) {
|
||||
struct wlr_drm_backend *drm = lease->backend;
|
||||
|
||||
wlr_signal_emit_safe(&lease->events.destroy, NULL);
|
||||
|
||||
struct wlr_drm_connector *conn;
|
||||
wl_list_for_each(conn, &drm->outputs, link) {
|
||||
if (conn->lessee_id == lessee_id) {
|
||||
conn->lessee_id = 0;
|
||||
/* Will be re-initialized in scan_drm_connectors */
|
||||
if (conn->lease == lease) {
|
||||
conn->lease = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < drm->num_crtcs; ++i) {
|
||||
if (drm->crtcs[i].lessee_id == lessee_id) {
|
||||
drm->crtcs[i].lessee_id = 0;
|
||||
if (drm->crtcs[i].lease == lease) {
|
||||
drm->crtcs[i].lease = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return r >= 0;
|
||||
free(lease);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,9 +151,13 @@ static bool legacy_crtc_commit(struct wlr_drm_connector *conn,
|
|||
|
||||
int ret = drmModeSetCursor(drm->fd, crtc->id, cursor_handle,
|
||||
cursor_width, cursor_height);
|
||||
close_bo_handle(drm->fd, cursor_handle);
|
||||
int set_cursor_errno = errno;
|
||||
if (drmCloseBufferHandle(drm->fd, cursor_handle) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmCloseBufferHandle failed");
|
||||
}
|
||||
if (ret != 0) {
|
||||
wlr_drm_conn_log_errno(conn, WLR_DEBUG, "drmModeSetCursor failed");
|
||||
wlr_drm_conn_log(conn, WLR_DEBUG, "drmModeSetCursor failed: %s",
|
||||
strerror(set_cursor_errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ wlr_files += files(
|
|||
'cvt.c',
|
||||
'drm.c',
|
||||
'legacy.c',
|
||||
'monitor.c',
|
||||
'properties.c',
|
||||
'renderer.c',
|
||||
'util.c',
|
||||
|
|
|
|||
94
backend/drm/monitor.c
Normal file
94
backend/drm/monitor.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#include <wlr/util/log.h>
|
||||
#include <stdlib.h>
|
||||
#include "backend/drm/monitor.h"
|
||||
#include "backend/multi.h"
|
||||
#include "backend/session/session.h"
|
||||
|
||||
static void drm_backend_monitor_destroy(struct wlr_drm_backend_monitor* monitor) {
|
||||
wl_list_remove(&monitor->session_add_drm_card.link);
|
||||
wl_list_remove(&monitor->session_destroy.link);
|
||||
wl_list_remove(&monitor->primary_drm_destroy.link);
|
||||
wl_list_remove(&monitor->multi_destroy.link);
|
||||
free(monitor);
|
||||
}
|
||||
|
||||
static void handle_add_drm_card(struct wl_listener *listener, void *data) {
|
||||
struct wlr_session_add_event *event = data;
|
||||
struct wlr_drm_backend_monitor *backend_monitor =
|
||||
wl_container_of(listener, backend_monitor, session_add_drm_card);
|
||||
|
||||
struct wlr_device *dev =
|
||||
session_open_if_kms(backend_monitor->session, event->path);
|
||||
if (!dev) {
|
||||
wlr_log(WLR_ERROR, "Unable to open %s as DRM device", event->path);
|
||||
return;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Creating DRM backend for %s after hotplug", event->path);
|
||||
struct wlr_backend *child_drm = wlr_drm_backend_create(
|
||||
backend_monitor->session->display, backend_monitor->session,
|
||||
dev, backend_monitor->primary_drm);
|
||||
if (!child_drm) {
|
||||
wlr_log(WLR_ERROR, "Failed to create DRM backend after hotplug");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wlr_multi_backend_add(backend_monitor->multi, child_drm)) {
|
||||
wlr_log(WLR_ERROR, "Failed to add new drm backend to multi backend");
|
||||
wlr_backend_destroy(child_drm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wlr_backend_start(child_drm)) {
|
||||
wlr_log(WLR_ERROR, "Failed to start new child DRM backend");
|
||||
wlr_backend_destroy(child_drm);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_session_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend_monitor *backend_monitor =
|
||||
wl_container_of(listener, backend_monitor, session_destroy);
|
||||
drm_backend_monitor_destroy(backend_monitor);
|
||||
}
|
||||
|
||||
static void handle_primary_drm_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend_monitor *backend_monitor =
|
||||
wl_container_of(listener, backend_monitor, primary_drm_destroy);
|
||||
drm_backend_monitor_destroy(backend_monitor);
|
||||
}
|
||||
|
||||
static void handle_multi_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_backend_monitor *backend_monitor =
|
||||
wl_container_of(listener, backend_monitor, multi_destroy);
|
||||
drm_backend_monitor_destroy(backend_monitor);
|
||||
}
|
||||
|
||||
struct wlr_drm_backend_monitor *drm_backend_monitor_create(
|
||||
struct wlr_backend *multi,
|
||||
struct wlr_backend *primary_drm,
|
||||
struct wlr_session *session) {
|
||||
struct wlr_drm_backend_monitor *monitor =
|
||||
calloc(1, sizeof(struct wlr_drm_backend_monitor));
|
||||
if (!monitor) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
monitor->multi = multi;
|
||||
monitor->primary_drm = primary_drm;
|
||||
monitor->session = session;
|
||||
|
||||
monitor->session_add_drm_card.notify = handle_add_drm_card;
|
||||
wl_signal_add(&session->events.add_drm_card, &monitor->session_add_drm_card);
|
||||
|
||||
monitor->session_destroy.notify = handle_session_destroy;
|
||||
wl_signal_add(&session->events.destroy, &monitor->session_destroy);
|
||||
|
||||
monitor->primary_drm_destroy.notify = handle_primary_drm_destroy;
|
||||
wl_signal_add(&primary_drm->events.destroy, &monitor->primary_drm_destroy);
|
||||
|
||||
monitor->multi_destroy.notify = handle_multi_destroy;
|
||||
wl_signal_add(&multi->events.destroy, &monitor->multi_destroy);
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ struct wlr_drm_format *drm_plane_pick_render_format(
|
|||
const struct wlr_drm_format_set *plane_formats = &plane->formats;
|
||||
|
||||
uint32_t fmt = DRM_FORMAT_ARGB8888;
|
||||
if (!wlr_drm_format_set_has(&plane->formats, fmt, DRM_FORMAT_MOD_INVALID)) {
|
||||
if (!wlr_drm_format_set_get(&plane->formats, fmt)) {
|
||||
const struct wlr_pixel_format_info *format_info =
|
||||
drm_get_pixel_format_info(fmt);
|
||||
assert(format_info != NULL &&
|
||||
|
|
@ -220,6 +220,13 @@ static uint32_t get_fb_for_bo(struct wlr_drm_backend *drm,
|
|||
wlr_log_errno(WLR_DEBUG, "drmModeAddFB2WithModifiers failed");
|
||||
}
|
||||
} else {
|
||||
if (dmabuf->modifier != DRM_FORMAT_MOD_INVALID &&
|
||||
dmabuf->modifier != DRM_FORMAT_MOD_LINEAR) {
|
||||
wlr_log(WLR_ERROR, "Cannot import DRM framebuffer with explicit "
|
||||
"modifier 0x%"PRIX64, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = drmModeAddFB2(drm->fd, dmabuf->width, dmabuf->height,
|
||||
dmabuf->format, handles, dmabuf->stride, dmabuf->offset, &id, 0);
|
||||
if (ret != 0 && dmabuf->format == DRM_FORMAT_ARGB8888 &&
|
||||
|
|
@ -264,30 +271,62 @@ static void close_all_bo_handles(struct wlr_drm_backend *drm,
|
|||
continue;
|
||||
}
|
||||
|
||||
close_bo_handle(drm->fd, handles[i]);
|
||||
if (drmCloseBufferHandle(drm->fd, handles[i]) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmCloseBufferHandle failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void drm_poisoned_fb_handle_destroy(struct wlr_addon *addon) {
|
||||
wlr_addon_finish(addon);
|
||||
free(addon);
|
||||
}
|
||||
|
||||
static const struct wlr_addon_interface poisoned_fb_addon_impl = {
|
||||
.name = "wlr_drm_poisoned_fb",
|
||||
.destroy = drm_poisoned_fb_handle_destroy,
|
||||
};
|
||||
|
||||
static bool is_buffer_poisoned(struct wlr_drm_backend *drm,
|
||||
struct wlr_buffer *buf) {
|
||||
return wlr_addon_find(&buf->addons, drm, &poisoned_fb_addon_impl) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the buffer as "poisoned", ie. it cannot be imported into KMS. This
|
||||
* allows us to avoid repeatedly trying to import it when it's not
|
||||
* scanout-capable.
|
||||
*/
|
||||
static void poison_buffer(struct wlr_drm_backend *drm,
|
||||
struct wlr_buffer *buf) {
|
||||
struct wlr_addon *addon = calloc(1, sizeof(*addon));
|
||||
if (addon == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return;
|
||||
}
|
||||
wlr_addon_init(addon, &buf->addons, drm, &poisoned_fb_addon_impl);
|
||||
wlr_log(WLR_DEBUG, "Poisoning buffer");
|
||||
}
|
||||
|
||||
static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm,
|
||||
struct wlr_buffer *buf, const struct wlr_drm_format_set *formats) {
|
||||
struct wlr_dmabuf_attributes attribs;
|
||||
if (!wlr_buffer_get_dmabuf(buf, &attribs)) {
|
||||
wlr_log(WLR_DEBUG, "Failed to get DMA-BUF from buffer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (is_buffer_poisoned(drm, buf)) {
|
||||
wlr_log(WLR_DEBUG, "Buffer is poisoned");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_drm_fb *fb = calloc(1, sizeof(*fb));
|
||||
if (!fb) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_dmabuf_attributes attribs;
|
||||
if (!wlr_buffer_get_dmabuf(buf, &attribs)) {
|
||||
wlr_log(WLR_DEBUG, "Failed to get DMA-BUF from buffer");
|
||||
goto error_get_dmabuf;
|
||||
}
|
||||
|
||||
if (attribs.flags != 0) {
|
||||
wlr_log(WLR_DEBUG, "Buffer with DMA-BUF flags 0x%"PRIX32" cannot be "
|
||||
"scanned out", attribs.flags);
|
||||
goto error_get_dmabuf;
|
||||
}
|
||||
|
||||
if (formats && !wlr_drm_format_set_has(formats, attribs.format,
|
||||
attribs.modifier)) {
|
||||
// The format isn't supported by the plane. Try stripping the alpha
|
||||
|
|
@ -301,7 +340,7 @@ static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm,
|
|||
wlr_log(WLR_DEBUG, "Buffer format 0x%"PRIX32" with modifier "
|
||||
"0x%"PRIX64" cannot be scanned out",
|
||||
attribs.format, attribs.modifier);
|
||||
goto error_get_dmabuf;
|
||||
goto error_fb;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,6 +356,7 @@ static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm,
|
|||
fb->id = get_fb_for_bo(drm, &attribs, handles);
|
||||
if (!fb->id) {
|
||||
wlr_log(WLR_DEBUG, "Failed to import BO in KMS");
|
||||
poison_buffer(drm, buf);
|
||||
goto error_bo_handle;
|
||||
}
|
||||
|
||||
|
|
@ -332,7 +372,7 @@ static struct wlr_drm_fb *drm_fb_create(struct wlr_drm_backend *drm,
|
|||
|
||||
error_bo_handle:
|
||||
close_all_bo_handles(drm, handles);
|
||||
error_get_dmabuf:
|
||||
error_fb:
|
||||
free(fb);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,14 +355,3 @@ size_t match_obj(size_t num_objs, const uint32_t objs[static restrict num_objs],
|
|||
match_obj_(&st, 0, 0, 0, 0);
|
||||
return st.score;
|
||||
}
|
||||
|
||||
void close_bo_handle(int drm_fd, uint32_t handle) {
|
||||
if (handle == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct drm_gem_close args = { .handle = handle };
|
||||
if (drmIoctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &args) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmIoctl(GEM_CLOSE) failed");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,8 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <assert.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <xf86drm.h>
|
||||
#include "backend/headless.h"
|
||||
#include "render/drm_format_set.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
struct wlr_headless_backend *headless_backend_from_backend(
|
||||
|
|
@ -32,13 +24,6 @@ static bool backend_start(struct wlr_backend *wlr_backend) {
|
|||
&output->wlr_output);
|
||||
}
|
||||
|
||||
struct wlr_headless_input_device *input_device;
|
||||
wl_list_for_each(input_device, &backend->input_devices,
|
||||
wlr_input_device.link) {
|
||||
wlr_signal_emit_safe(&backend->backend.events.new_input,
|
||||
&input_device->wlr_input_device);
|
||||
}
|
||||
|
||||
backend->started = true;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -51,42 +36,17 @@ static void backend_destroy(struct wlr_backend *wlr_backend) {
|
|||
}
|
||||
|
||||
wl_list_remove(&backend->display_destroy.link);
|
||||
wl_list_remove(&backend->parent_renderer_destroy.link);
|
||||
|
||||
struct wlr_headless_output *output, *output_tmp;
|
||||
wl_list_for_each_safe(output, output_tmp, &backend->outputs, link) {
|
||||
wlr_output_destroy(&output->wlr_output);
|
||||
}
|
||||
|
||||
struct wlr_headless_input_device *input_device, *input_device_tmp;
|
||||
wl_list_for_each_safe(input_device, input_device_tmp,
|
||||
&backend->input_devices, wlr_input_device.link) {
|
||||
wlr_input_device_destroy(&input_device->wlr_input_device);
|
||||
}
|
||||
|
||||
wlr_backend_finish(wlr_backend);
|
||||
|
||||
close(backend->drm_fd);
|
||||
free(backend);
|
||||
}
|
||||
|
||||
static struct wlr_renderer *backend_get_renderer(
|
||||
struct wlr_backend *wlr_backend) {
|
||||
struct wlr_headless_backend *backend =
|
||||
headless_backend_from_backend(wlr_backend);
|
||||
if (backend->parent_renderer != NULL) {
|
||||
return backend->parent_renderer;
|
||||
} else {
|
||||
return wlr_backend->renderer;
|
||||
}
|
||||
}
|
||||
|
||||
static int backend_get_drm_fd(struct wlr_backend *wlr_backend) {
|
||||
struct wlr_headless_backend *backend =
|
||||
headless_backend_from_backend(wlr_backend);
|
||||
return backend->drm_fd;
|
||||
}
|
||||
|
||||
static uint32_t get_buffer_caps(struct wlr_backend *wlr_backend) {
|
||||
return WLR_BUFFER_CAP_DATA_PTR
|
||||
| WLR_BUFFER_CAP_DMABUF
|
||||
|
|
@ -96,8 +56,6 @@ static uint32_t get_buffer_caps(struct wlr_backend *wlr_backend) {
|
|||
static const struct wlr_backend_impl backend_impl = {
|
||||
.start = backend_start,
|
||||
.destroy = backend_destroy,
|
||||
.get_renderer = backend_get_renderer,
|
||||
.get_drm_fd = backend_get_drm_fd,
|
||||
.get_buffer_caps = get_buffer_caps,
|
||||
};
|
||||
|
||||
|
|
@ -107,86 +65,6 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
|||
backend_destroy(&backend->backend);
|
||||
}
|
||||
|
||||
static void handle_renderer_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_headless_backend *backend =
|
||||
wl_container_of(listener, backend, parent_renderer_destroy);
|
||||
backend_destroy(&backend->backend);
|
||||
}
|
||||
|
||||
static bool backend_init(struct wlr_headless_backend *backend,
|
||||
struct wl_display *display, struct wlr_renderer *renderer) {
|
||||
wlr_backend_init(&backend->backend, &backend_impl);
|
||||
|
||||
backend->display = display;
|
||||
wl_list_init(&backend->outputs);
|
||||
wl_list_init(&backend->input_devices);
|
||||
wl_list_init(&backend->parent_renderer_destroy.link);
|
||||
|
||||
if (renderer == NULL) {
|
||||
renderer = wlr_renderer_autocreate(&backend->backend);
|
||||
if (!renderer) {
|
||||
wlr_log(WLR_ERROR, "Failed to create renderer");
|
||||
return false;
|
||||
}
|
||||
backend->backend.renderer = renderer;
|
||||
} else {
|
||||
backend->parent_renderer = renderer;
|
||||
backend->parent_renderer_destroy.notify = handle_renderer_destroy;
|
||||
wl_signal_add(&renderer->events.destroy, &backend->parent_renderer_destroy);
|
||||
}
|
||||
|
||||
backend->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &backend->display_destroy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int open_drm_render_node(void) {
|
||||
uint32_t flags = 0;
|
||||
int devices_len = drmGetDevices2(flags, NULL, 0);
|
||||
if (devices_len < 0) {
|
||||
wlr_log(WLR_ERROR, "drmGetDevices2 failed: %s", strerror(-devices_len));
|
||||
return -1;
|
||||
}
|
||||
drmDevice **devices = calloc(devices_len, sizeof(drmDevice *));
|
||||
if (devices == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
return -1;
|
||||
}
|
||||
devices_len = drmGetDevices2(flags, devices, devices_len);
|
||||
if (devices_len < 0) {
|
||||
free(devices);
|
||||
wlr_log(WLR_ERROR, "drmGetDevices2 failed: %s", strerror(-devices_len));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fd = -1;
|
||||
for (int i = 0; i < devices_len; i++) {
|
||||
drmDevice *dev = devices[i];
|
||||
if (dev->available_nodes & (1 << DRM_NODE_RENDER)) {
|
||||
const char *name = dev->nodes[DRM_NODE_RENDER];
|
||||
wlr_log(WLR_DEBUG, "Opening DRM render node '%s'", name);
|
||||
fd = open(name, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to open '%s'", name);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to find any DRM render node");
|
||||
}
|
||||
|
||||
out:
|
||||
for (int i = 0; i < devices_len; i++) {
|
||||
drmFreeDevice(&devices[i]);
|
||||
}
|
||||
free(devices);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_headless_backend_create(struct wl_display *display) {
|
||||
wlr_log(WLR_INFO, "Creating headless backend");
|
||||
|
||||
|
|
@ -197,55 +75,15 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
backend->drm_fd = open_drm_render_node();
|
||||
if (backend->drm_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to open DRM render node");
|
||||
}
|
||||
wlr_backend_init(&backend->backend, &backend_impl);
|
||||
|
||||
if (!backend_init(backend, display, NULL)) {
|
||||
goto error_init;
|
||||
}
|
||||
backend->display = display;
|
||||
wl_list_init(&backend->outputs);
|
||||
|
||||
backend->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &backend->display_destroy);
|
||||
|
||||
return &backend->backend;
|
||||
|
||||
error_init:
|
||||
close(backend->drm_fd);
|
||||
free(backend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_headless_backend_create_with_renderer(
|
||||
struct wl_display *display, struct wlr_renderer *renderer) {
|
||||
wlr_log(WLR_INFO, "Creating headless backend with parent renderer");
|
||||
|
||||
struct wlr_headless_backend *backend =
|
||||
calloc(1, sizeof(struct wlr_headless_backend));
|
||||
if (!backend) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate wlr_headless_backend");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int drm_fd = wlr_renderer_get_drm_fd(renderer);
|
||||
if (drm_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to get DRM device FD from parent renderer");
|
||||
backend->drm_fd = -1;
|
||||
} else {
|
||||
backend->drm_fd = fcntl(drm_fd, F_DUPFD_CLOEXEC, 0);
|
||||
if (backend->drm_fd < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (!backend_init(backend, display, renderer)) {
|
||||
goto error_init;
|
||||
}
|
||||
|
||||
return &backend->backend;
|
||||
|
||||
error_init:
|
||||
close(backend->drm_fd);
|
||||
free(backend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool wlr_backend_is_headless(struct wlr_backend *backend) {
|
||||
|
|
|
|||
|
|
@ -1,99 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/interfaces/wlr_tablet_pad.h>
|
||||
#include <wlr/interfaces/wlr_tablet_tool.h>
|
||||
#include <wlr/interfaces/wlr_touch.h>
|
||||
#include <wlr/interfaces/wlr_switch.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/headless.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
static const struct wlr_input_device_impl input_device_impl = { 0 };
|
||||
|
||||
bool wlr_input_device_is_headless(struct wlr_input_device *wlr_dev) {
|
||||
return wlr_dev->impl == &input_device_impl;
|
||||
}
|
||||
|
||||
struct wlr_input_device *wlr_headless_add_input_device(
|
||||
struct wlr_backend *wlr_backend, enum wlr_input_device_type type) {
|
||||
struct wlr_headless_backend *backend =
|
||||
headless_backend_from_backend(wlr_backend);
|
||||
|
||||
struct wlr_headless_input_device *device =
|
||||
calloc(1, sizeof(struct wlr_headless_input_device));
|
||||
if (device == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
device->backend = backend;
|
||||
|
||||
int vendor = 0;
|
||||
int product = 0;
|
||||
const char *name = "headless";
|
||||
struct wlr_input_device *wlr_device = &device->wlr_input_device;
|
||||
wlr_input_device_init(wlr_device, type, &input_device_impl, name, vendor,
|
||||
product);
|
||||
|
||||
switch (type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
wlr_device->keyboard = calloc(1, sizeof(struct wlr_keyboard));
|
||||
if (wlr_device->keyboard == NULL) {
|
||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_keyboard");
|
||||
goto error;
|
||||
}
|
||||
wlr_keyboard_init(wlr_device->keyboard, NULL);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
wlr_device->pointer = calloc(1, sizeof(struct wlr_pointer));
|
||||
if (wlr_device->pointer == NULL) {
|
||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_pointer");
|
||||
goto error;
|
||||
}
|
||||
wlr_pointer_init(wlr_device->pointer, NULL);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
wlr_device->touch = calloc(1, sizeof(struct wlr_touch));
|
||||
if (wlr_device->touch == NULL) {
|
||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_touch");
|
||||
goto error;
|
||||
}
|
||||
wlr_touch_init(wlr_device->touch, NULL);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
wlr_device->tablet = calloc(1, sizeof(struct wlr_tablet));
|
||||
if (wlr_device->tablet == NULL) {
|
||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_tablet");
|
||||
goto error;
|
||||
}
|
||||
wlr_tablet_init(wlr_device->tablet, NULL);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
wlr_device->tablet_pad = calloc(1, sizeof(struct wlr_tablet_pad));
|
||||
if (wlr_device->tablet_pad == NULL) {
|
||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_tablet_pad");
|
||||
goto error;
|
||||
}
|
||||
wlr_tablet_pad_init(wlr_device->tablet_pad, NULL);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
wlr_device->switch_device = calloc(1, sizeof(struct wlr_switch));
|
||||
if (wlr_device->switch_device == NULL) {
|
||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_switch");
|
||||
goto error;
|
||||
}
|
||||
wlr_switch_init(wlr_device->switch_device, NULL);
|
||||
}
|
||||
|
||||
wl_list_insert(&backend->input_devices, &wlr_device->link);
|
||||
|
||||
if (backend->started) {
|
||||
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_device);
|
||||
}
|
||||
|
||||
return wlr_device;
|
||||
error:
|
||||
free(device);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
wlr_files += files(
|
||||
'backend.c',
|
||||
'input_device.c',
|
||||
'output.c',
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/headless.h"
|
||||
#include "util/signal.h"
|
||||
|
|
@ -117,12 +116,14 @@ struct wlr_output *wlr_headless_add_output(struct wlr_backend *wlr_backend,
|
|||
output_set_custom_mode(output, width, height, 0);
|
||||
strncpy(wlr_output->make, "headless", sizeof(wlr_output->make));
|
||||
strncpy(wlr_output->model, "headless", sizeof(wlr_output->model));
|
||||
snprintf(wlr_output->name, sizeof(wlr_output->name), "HEADLESS-%zd",
|
||||
++backend->last_output_num);
|
||||
|
||||
char name[64];
|
||||
snprintf(name, sizeof(name), "HEADLESS-%zu", ++backend->last_output_num);
|
||||
wlr_output_set_name(wlr_output, name);
|
||||
|
||||
char description[128];
|
||||
snprintf(description, sizeof(description),
|
||||
"Headless output %zd", backend->last_output_num);
|
||||
"Headless output %zu", backend->last_output_num);
|
||||
wlr_output_set_description(wlr_output, description);
|
||||
|
||||
struct wl_event_loop *ev = wl_display_get_event_loop(backend->display);
|
||||
|
|
|
|||
|
|
@ -143,9 +143,9 @@ static void backend_destroy(struct wlr_backend *wlr_backend) {
|
|||
|
||||
struct wl_list **wlr_devices_ptr;
|
||||
wl_array_for_each(wlr_devices_ptr, &backend->wlr_device_lists) {
|
||||
struct wlr_input_device *wlr_dev, *next;
|
||||
wl_list_for_each_safe(wlr_dev, next, *wlr_devices_ptr, link) {
|
||||
wlr_input_device_destroy(wlr_dev);
|
||||
struct wlr_libinput_input_device *dev, *tmp;
|
||||
wl_list_for_each_safe(dev, tmp, *wlr_devices_ptr, link) {
|
||||
destroy_libinput_input_device(dev);
|
||||
}
|
||||
free(*wlr_devices_ptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,11 @@
|
|||
#include <stdlib.h>
|
||||
#include <wayland-util.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/libinput.h"
|
||||
#include "util/array.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
static struct wlr_libinput_input_device *get_libinput_device_from_device(
|
||||
struct wlr_input_device *wlr_dev) {
|
||||
assert(wlr_input_device_is_libinput(wlr_dev));
|
||||
return (struct wlr_libinput_input_device *)wlr_dev;
|
||||
}
|
||||
|
||||
struct wlr_input_device *get_appropriate_device(
|
||||
enum wlr_input_device_type desired_type,
|
||||
struct libinput_device *libinput_dev) {
|
||||
|
|
@ -23,33 +16,36 @@ struct wlr_input_device *get_appropriate_device(
|
|||
if (!wlr_devices) {
|
||||
return NULL;
|
||||
}
|
||||
struct wlr_input_device *dev;
|
||||
struct wlr_libinput_input_device *dev;
|
||||
wl_list_for_each(dev, wlr_devices, link) {
|
||||
if (dev->type == desired_type) {
|
||||
return dev;
|
||||
if (dev->wlr_input_device.type == desired_type) {
|
||||
return &dev->wlr_input_device;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void input_device_destroy(struct wlr_input_device *wlr_dev) {
|
||||
struct wlr_libinput_input_device *dev =
|
||||
get_libinput_device_from_device(wlr_dev);
|
||||
void destroy_libinput_input_device(struct wlr_libinput_input_device *dev)
|
||||
{
|
||||
/**
|
||||
* TODO remove the redundant wlr_input_device from wlr_libinput_input_device
|
||||
* wlr_libinput_input_device::wlr_input_device is not owned by its input
|
||||
* device type, which means we have 2 wlr_input_device to cleanup
|
||||
*/
|
||||
if (dev->wlr_input_device._device) {
|
||||
wlr_input_device_destroy(&dev->wlr_input_device);
|
||||
}
|
||||
wlr_input_device_finish(&dev->wlr_input_device);
|
||||
|
||||
libinput_device_unref(dev->handle);
|
||||
wl_list_remove(&dev->wlr_input_device.link);
|
||||
wl_list_remove(&dev->link);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static const struct wlr_input_device_impl input_device_impl = {
|
||||
.destroy = input_device_destroy,
|
||||
};
|
||||
|
||||
static struct wlr_input_device *allocate_device(
|
||||
struct wlr_libinput_backend *backend,
|
||||
struct libinput_device *libinput_dev, struct wl_list *wlr_devices,
|
||||
enum wlr_input_device_type type) {
|
||||
int vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||
int product = libinput_device_get_id_product(libinput_dev);
|
||||
const char *name = libinput_device_get_name(libinput_dev);
|
||||
struct wlr_libinput_input_device *dev =
|
||||
calloc(1, sizeof(struct wlr_libinput_input_device));
|
||||
|
|
@ -63,16 +59,32 @@ static struct wlr_input_device *allocate_device(
|
|||
if (output_name != NULL) {
|
||||
wlr_dev->output_name = strdup(output_name);
|
||||
}
|
||||
wl_list_insert(wlr_devices, &wlr_dev->link);
|
||||
wl_list_insert(wlr_devices, &dev->link);
|
||||
dev->handle = libinput_dev;
|
||||
libinput_device_ref(libinput_dev);
|
||||
wlr_input_device_init(wlr_dev, type, &input_device_impl,
|
||||
name, vendor, product);
|
||||
wlr_input_device_init(wlr_dev, type, name);
|
||||
wlr_dev->vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||
wlr_dev->product = libinput_device_get_id_product(libinput_dev);
|
||||
return wlr_dev;
|
||||
}
|
||||
|
||||
bool wlr_input_device_is_libinput(struct wlr_input_device *wlr_dev) {
|
||||
return wlr_dev->impl == &input_device_impl;
|
||||
switch (wlr_dev->type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
return wlr_dev->keyboard->impl == &libinput_keyboard_impl;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
return wlr_dev->pointer->impl == &libinput_pointer_impl;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
return wlr_dev->touch->impl == &libinput_touch_impl;
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
return wlr_dev->tablet->impl == &libinput_tablet_impl;
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
return wlr_dev->tablet_pad->impl == &libinput_tablet_pad_impl;
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
return wlr_dev->switch_device->impl == &libinput_switch_impl;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_device_added(struct wlr_libinput_backend *backend,
|
||||
|
|
@ -198,7 +210,7 @@ static void handle_device_added(struct wlr_libinput_backend *backend,
|
|||
|
||||
fail:
|
||||
wlr_log(WLR_ERROR, "Could not allocate new device");
|
||||
struct wlr_input_device *dev, *tmp_dev;
|
||||
struct wlr_libinput_input_device *dev, *tmp_dev;
|
||||
wl_list_for_each_safe(dev, tmp_dev, wlr_devices, link) {
|
||||
free(dev);
|
||||
}
|
||||
|
|
@ -215,9 +227,9 @@ static void handle_device_removed(struct wlr_libinput_backend *backend,
|
|||
if (!wlr_devices) {
|
||||
return;
|
||||
}
|
||||
struct wlr_input_device *dev, *tmp_dev;
|
||||
struct wlr_libinput_input_device *dev, *tmp_dev;
|
||||
wl_list_for_each_safe(dev, tmp_dev, wlr_devices, link) {
|
||||
wlr_input_device_destroy(dev);
|
||||
destroy_libinput_input_device(dev);
|
||||
}
|
||||
size_t i = 0;
|
||||
struct wl_list **ptr;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#include <libinput.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/libinput.h"
|
||||
|
|
@ -12,11 +11,9 @@ struct wlr_libinput_keyboard {
|
|||
struct libinput_device *libinput_dev;
|
||||
};
|
||||
|
||||
static const struct wlr_keyboard_impl impl;
|
||||
|
||||
static struct wlr_libinput_keyboard *get_libinput_keyboard_from_keyboard(
|
||||
struct wlr_keyboard *wlr_kb) {
|
||||
assert(wlr_kb->impl == &impl);
|
||||
assert(wlr_kb->impl == &libinput_keyboard_impl);
|
||||
return (struct wlr_libinput_keyboard *)wlr_kb;
|
||||
}
|
||||
|
||||
|
|
@ -33,7 +30,7 @@ static void keyboard_destroy(struct wlr_keyboard *wlr_kb) {
|
|||
free(kb);
|
||||
}
|
||||
|
||||
static const struct wlr_keyboard_impl impl = {
|
||||
const struct wlr_keyboard_impl libinput_keyboard_impl = {
|
||||
.destroy = keyboard_destroy,
|
||||
.led_update = keyboard_set_leds
|
||||
};
|
||||
|
|
@ -49,7 +46,10 @@ struct wlr_keyboard *create_libinput_keyboard(
|
|||
libinput_device_ref(libinput_dev);
|
||||
libinput_device_led_update(libinput_dev, 0);
|
||||
struct wlr_keyboard *wlr_kb = &kb->wlr_keyboard;
|
||||
wlr_keyboard_init(wlr_kb, &impl);
|
||||
const char *name = libinput_device_get_name(libinput_dev);
|
||||
wlr_keyboard_init(wlr_kb, &libinput_keyboard_impl, name);
|
||||
wlr_kb->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||
wlr_kb->base.product = libinput_device_get_id_product(libinput_dev);
|
||||
return wlr_kb;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
#include <libinput.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/libinput.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
const struct wlr_pointer_impl libinput_pointer_impl = {0};
|
||||
|
||||
struct wlr_pointer *create_libinput_pointer(
|
||||
struct libinput_device *libinput_dev) {
|
||||
assert(libinput_dev);
|
||||
|
|
@ -16,7 +17,10 @@ struct wlr_pointer *create_libinput_pointer(
|
|||
wlr_log(WLR_ERROR, "Unable to allocate wlr_pointer");
|
||||
return NULL;
|
||||
}
|
||||
wlr_pointer_init(wlr_pointer, NULL);
|
||||
const char *name = libinput_device_get_name(libinput_dev);
|
||||
wlr_pointer_init(wlr_pointer, &libinput_pointer_impl, name);
|
||||
wlr_pointer->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||
wlr_pointer->base.product = libinput_device_get_id_product(libinput_dev);
|
||||
return wlr_pointer;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include "backend/libinput.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
const struct wlr_switch_impl libinput_switch_impl;
|
||||
|
||||
struct wlr_switch *create_libinput_switch(
|
||||
struct libinput_device *libinput_dev) {
|
||||
assert(libinput_dev);
|
||||
|
|
@ -16,8 +18,11 @@ struct wlr_switch *create_libinput_switch(
|
|||
wlr_log(WLR_ERROR, "Unable to allocate wlr_switch");
|
||||
return NULL;
|
||||
}
|
||||
wlr_switch_init(wlr_switch, NULL);
|
||||
wlr_log(WLR_DEBUG, "Created switch for device %s", libinput_device_get_name(libinput_dev));
|
||||
const char *name = libinput_device_get_name(libinput_dev);
|
||||
wlr_switch_init(wlr_switch, &libinput_switch_impl, name);
|
||||
wlr_log(WLR_DEBUG, "Created switch for device %s", name);
|
||||
wlr_switch->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||
wlr_switch->base.product = libinput_device_get_id_product(libinput_dev);
|
||||
return wlr_switch;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad,
|
|||
wl_list_insert(&pad->groups, &group->link);
|
||||
}
|
||||
|
||||
const struct wlr_tablet_pad_impl libinput_tablet_pad_impl;
|
||||
|
||||
struct wlr_tablet_pad *create_libinput_tablet_pad(
|
||||
struct libinput_device *libinput_dev) {
|
||||
assert(libinput_dev);
|
||||
|
|
@ -75,7 +77,10 @@ struct wlr_tablet_pad *create_libinput_tablet_pad(
|
|||
wlr_log(WLR_ERROR, "Unable to allocate wlr_tablet_pad");
|
||||
return NULL;
|
||||
}
|
||||
wlr_tablet_pad_init(wlr_tablet_pad, NULL);
|
||||
const char *name = libinput_device_get_name(libinput_dev);
|
||||
wlr_tablet_pad_init(wlr_tablet_pad, &libinput_tablet_pad_impl, name);
|
||||
wlr_tablet_pad->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||
wlr_tablet_pad->base.product = libinput_device_get_id_product(libinput_dev);
|
||||
|
||||
wlr_tablet_pad->button_count =
|
||||
libinput_device_tablet_pad_get_num_buttons(libinput_dev);
|
||||
|
|
|
|||
|
|
@ -14,10 +14,8 @@
|
|||
#include "util/array.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
static const struct wlr_tablet_impl tablet_impl;
|
||||
|
||||
static bool tablet_is_libinput(struct wlr_tablet *tablet) {
|
||||
return tablet->impl == &tablet_impl;
|
||||
return tablet->impl == &libinput_tablet_impl;
|
||||
}
|
||||
|
||||
struct wlr_libinput_tablet_tool {
|
||||
|
|
@ -42,7 +40,6 @@ static void destroy_tool(struct wlr_libinput_tablet_tool *tool) {
|
|||
free(tool);
|
||||
}
|
||||
|
||||
|
||||
static void destroy_tablet(struct wlr_tablet *wlr_tablet) {
|
||||
assert(tablet_is_libinput(wlr_tablet));
|
||||
struct wlr_libinput_tablet *tablet =
|
||||
|
|
@ -60,7 +57,7 @@ static void destroy_tablet(struct wlr_tablet *wlr_tablet) {
|
|||
free(tablet);
|
||||
}
|
||||
|
||||
static const struct wlr_tablet_impl tablet_impl = {
|
||||
const struct wlr_tablet_impl libinput_tablet_impl = {
|
||||
.destroy = destroy_tablet,
|
||||
};
|
||||
|
||||
|
|
@ -75,7 +72,11 @@ struct wlr_tablet *create_libinput_tablet(
|
|||
}
|
||||
|
||||
struct wlr_tablet *wlr_tablet = &libinput_tablet->wlr_tablet;
|
||||
wlr_tablet_init(wlr_tablet, &tablet_impl);
|
||||
const char *name = libinput_device_get_name(libinput_dev);
|
||||
|
||||
wlr_tablet_init(wlr_tablet, &libinput_tablet_impl, name);
|
||||
wlr_tablet->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||
wlr_tablet->base.product = libinput_device_get_id_product(libinput_dev);
|
||||
|
||||
struct udev_device *udev = libinput_device_get_udev_device(libinput_dev);
|
||||
char **dst = wl_array_add(&wlr_tablet->paths, sizeof(char *));
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include "backend/libinput.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
const struct wlr_touch_impl libinput_touch_impl;
|
||||
|
||||
struct wlr_touch *create_libinput_touch(
|
||||
struct libinput_device *libinput_dev) {
|
||||
assert(libinput_dev);
|
||||
|
|
@ -16,7 +18,10 @@ struct wlr_touch *create_libinput_touch(
|
|||
wlr_log(WLR_ERROR, "Unable to allocate wlr_touch");
|
||||
return NULL;
|
||||
}
|
||||
wlr_touch_init(wlr_touch, NULL);
|
||||
const char *name = libinput_device_get_name(libinput_dev);
|
||||
wlr_touch_init(wlr_touch, &libinput_touch_impl, name);
|
||||
wlr_touch->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||
wlr_touch->base.product = libinput_device_get_id_product(libinput_dev);
|
||||
return wlr_touch;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ endforeach
|
|||
|
||||
subdir('multi')
|
||||
subdir('wayland')
|
||||
subdir('noop')
|
||||
subdir('headless')
|
||||
|
||||
subdir('session')
|
||||
|
|
|
|||
|
|
@ -64,20 +64,6 @@ static void multi_backend_destroy(struct wlr_backend *wlr_backend) {
|
|||
free(backend);
|
||||
}
|
||||
|
||||
static struct wlr_renderer *multi_backend_get_renderer(
|
||||
struct wlr_backend *backend) {
|
||||
struct wlr_multi_backend *multi = multi_backend_from_backend(backend);
|
||||
|
||||
struct subbackend_state *sub;
|
||||
wl_list_for_each(sub, &multi->backends, link) {
|
||||
struct wlr_renderer *rend = wlr_backend_get_renderer(sub->backend);
|
||||
if (rend != NULL) {
|
||||
return rend;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct wlr_session *multi_backend_get_session(
|
||||
struct wlr_backend *_backend) {
|
||||
struct wlr_multi_backend *backend = multi_backend_from_backend(_backend);
|
||||
|
|
@ -136,7 +122,6 @@ static uint32_t multi_backend_get_buffer_caps(struct wlr_backend *backend) {
|
|||
static const struct wlr_backend_impl backend_impl = {
|
||||
.start = multi_backend_start,
|
||||
.destroy = multi_backend_destroy,
|
||||
.get_renderer = multi_backend_get_renderer,
|
||||
.get_session = multi_backend_get_session,
|
||||
.get_presentation_clock = multi_backend_get_presentation_clock,
|
||||
.get_drm_fd = multi_backend_get_drm_fd,
|
||||
|
|
@ -204,6 +189,9 @@ static struct subbackend_state *multi_backend_get_subbackend(struct wlr_multi_ba
|
|||
|
||||
bool wlr_multi_backend_add(struct wlr_backend *_multi,
|
||||
struct wlr_backend *backend) {
|
||||
assert(_multi && backend);
|
||||
assert(_multi != backend);
|
||||
|
||||
struct wlr_multi_backend *multi = multi_backend_from_backend(_multi);
|
||||
|
||||
if (multi_backend_get_subbackend(multi, backend)) {
|
||||
|
|
@ -211,15 +199,6 @@ bool wlr_multi_backend_add(struct wlr_backend *_multi,
|
|||
return true;
|
||||
}
|
||||
|
||||
struct wlr_renderer *multi_renderer =
|
||||
multi_backend_get_renderer(&multi->backend);
|
||||
struct wlr_renderer *backend_renderer = wlr_backend_get_renderer(backend);
|
||||
if (multi_renderer != NULL && backend_renderer != NULL && multi_renderer != backend_renderer) {
|
||||
wlr_log(WLR_ERROR, "Could not add backend: multiple renderers at the "
|
||||
"same time aren't supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct subbackend_state *sub = calloc(1, sizeof(struct subbackend_state));
|
||||
if (sub == NULL) {
|
||||
wlr_log(WLR_ERROR, "Could not add backend: allocation failed");
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/noop.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
struct wlr_noop_backend *noop_backend_from_backend(
|
||||
struct wlr_backend *wlr_backend) {
|
||||
assert(wlr_backend_is_noop(wlr_backend));
|
||||
return (struct wlr_noop_backend *)wlr_backend;
|
||||
}
|
||||
|
||||
static bool backend_start(struct wlr_backend *wlr_backend) {
|
||||
struct wlr_noop_backend *backend = noop_backend_from_backend(wlr_backend);
|
||||
wlr_log(WLR_INFO, "Starting noop backend");
|
||||
|
||||
struct wlr_noop_output *output;
|
||||
wl_list_for_each(output, &backend->outputs, link) {
|
||||
wlr_output_update_enabled(&output->wlr_output, true);
|
||||
wlr_signal_emit_safe(&backend->backend.events.new_output,
|
||||
&output->wlr_output);
|
||||
}
|
||||
|
||||
backend->started = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void backend_destroy(struct wlr_backend *wlr_backend) {
|
||||
struct wlr_noop_backend *backend = noop_backend_from_backend(wlr_backend);
|
||||
if (!wlr_backend) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_noop_output *output, *output_tmp;
|
||||
wl_list_for_each_safe(output, output_tmp, &backend->outputs, link) {
|
||||
wlr_output_destroy(&output->wlr_output);
|
||||
}
|
||||
|
||||
wlr_backend_finish(wlr_backend);
|
||||
|
||||
wl_list_remove(&backend->display_destroy.link);
|
||||
|
||||
free(backend);
|
||||
}
|
||||
|
||||
static const struct wlr_backend_impl backend_impl = {
|
||||
.start = backend_start,
|
||||
.destroy = backend_destroy,
|
||||
};
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_noop_backend *noop =
|
||||
wl_container_of(listener, noop, display_destroy);
|
||||
backend_destroy(&noop->backend);
|
||||
}
|
||||
|
||||
struct wlr_backend *wlr_noop_backend_create(struct wl_display *display) {
|
||||
wlr_log(WLR_INFO, "Creating noop backend");
|
||||
|
||||
struct wlr_noop_backend *backend =
|
||||
calloc(1, sizeof(struct wlr_noop_backend));
|
||||
if (!backend) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate wlr_noop_backend");
|
||||
return NULL;
|
||||
}
|
||||
wlr_backend_init(&backend->backend, &backend_impl);
|
||||
backend->display = display;
|
||||
wl_list_init(&backend->outputs);
|
||||
|
||||
backend->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &backend->display_destroy);
|
||||
|
||||
return &backend->backend;
|
||||
}
|
||||
|
||||
bool wlr_backend_is_noop(struct wlr_backend *backend) {
|
||||
return backend->impl == &backend_impl;
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
wlr_files += files(
|
||||
'backend.c',
|
||||
'output.c',
|
||||
)
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/noop.h"
|
||||
#include "util/signal.h"
|
||||
|
||||
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
||||
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
|
||||
WLR_OUTPUT_STATE_MODE;
|
||||
|
||||
static struct wlr_noop_output *noop_output_from_output(
|
||||
struct wlr_output *wlr_output) {
|
||||
assert(wlr_output_is_noop(wlr_output));
|
||||
return (struct wlr_noop_output *)wlr_output;
|
||||
}
|
||||
|
||||
static bool output_commit(struct wlr_output *wlr_output) {
|
||||
uint32_t unsupported =
|
||||
wlr_output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
|
||||
if (unsupported != 0) {
|
||||
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
||||
unsupported);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
|
||||
assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
|
||||
wlr_output_update_custom_mode(wlr_output,
|
||||
wlr_output->pending.custom_mode.width,
|
||||
wlr_output->pending.custom_mode.height,
|
||||
wlr_output->pending.custom_mode.refresh);
|
||||
}
|
||||
|
||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void output_destroy(struct wlr_output *wlr_output) {
|
||||
struct wlr_noop_output *output =
|
||||
noop_output_from_output(wlr_output);
|
||||
|
||||
wl_list_remove(&output->link);
|
||||
|
||||
free(output);
|
||||
}
|
||||
|
||||
static const struct wlr_output_impl output_impl = {
|
||||
.destroy = output_destroy,
|
||||
.commit = output_commit,
|
||||
};
|
||||
|
||||
bool wlr_output_is_noop(struct wlr_output *wlr_output) {
|
||||
return wlr_output->impl == &output_impl;
|
||||
}
|
||||
|
||||
struct wlr_output *wlr_noop_add_output(struct wlr_backend *wlr_backend) {
|
||||
struct wlr_noop_backend *backend = noop_backend_from_backend(wlr_backend);
|
||||
|
||||
struct wlr_noop_output *output = calloc(1, sizeof(struct wlr_noop_output));
|
||||
if (output == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate wlr_noop_output");
|
||||
return NULL;
|
||||
}
|
||||
output->backend = backend;
|
||||
wlr_output_init(&output->wlr_output, &backend->backend, &output_impl,
|
||||
backend->display);
|
||||
struct wlr_output *wlr_output = &output->wlr_output;
|
||||
|
||||
strncpy(wlr_output->make, "noop", sizeof(wlr_output->make));
|
||||
strncpy(wlr_output->model, "noop", sizeof(wlr_output->model));
|
||||
snprintf(wlr_output->name, sizeof(wlr_output->name), "NOOP-%zd",
|
||||
++backend->last_output_num);
|
||||
|
||||
wl_list_insert(&backend->outputs, &output->link);
|
||||
|
||||
if (backend->started) {
|
||||
wlr_output_update_enabled(wlr_output, true);
|
||||
wlr_signal_emit_safe(&backend->backend.events.new_output, wlr_output);
|
||||
}
|
||||
|
||||
return wlr_output;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
libseat = dependency('libseat',
|
||||
version: '>=0.2.0',
|
||||
fallback: ['seatd', 'libseat'],
|
||||
fallback: 'seatd',
|
||||
default_options: ['server=disabled', 'man-pages=disabled'],
|
||||
)
|
||||
wlr_files += files('session.c')
|
||||
|
|
|
|||
|
|
@ -157,6 +157,14 @@ static void read_udev_change_event(struct wlr_device_change_event *event,
|
|||
if (prop != NULL) {
|
||||
hotplug->prop_id = strtoul(prop, NULL, 10);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const char *lease = udev_device_get_property_value(udev_dev, "LEASE");
|
||||
if (lease != NULL && strcmp(lease, "1") == 0) {
|
||||
event->type = WLR_DEVICE_LEASE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -362,7 +370,7 @@ bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) {
|
|||
|
||||
/* Tests if 'path' is KMS compatible by trying to open it. Returns the opened
|
||||
* device on success. */
|
||||
static struct wlr_device *open_if_kms(struct wlr_session *restrict session,
|
||||
struct wlr_device *session_open_if_kms(struct wlr_session *restrict session,
|
||||
const char *restrict path) {
|
||||
if (!path) {
|
||||
return NULL;
|
||||
|
|
@ -398,7 +406,7 @@ static ssize_t explicit_find_gpus(struct wlr_session *session,
|
|||
break;
|
||||
}
|
||||
|
||||
ret[i] = open_if_kms(session, ptr);
|
||||
ret[i] = session_open_if_kms(session, ptr);
|
||||
if (!ret[i]) {
|
||||
wlr_log(WLR_ERROR, "Unable to open %s as DRM device", ptr);
|
||||
} else {
|
||||
|
|
@ -534,7 +542,7 @@ ssize_t wlr_session_find_gpus(struct wlr_session *session,
|
|||
}
|
||||
|
||||
struct wlr_device *wlr_dev =
|
||||
open_if_kms(session, udev_device_get_devnode(dev));
|
||||
session_open_if_kms(session, udev_device_get_devnode(dev));
|
||||
if (!wlr_dev) {
|
||||
udev_device_unref(dev);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
|
|
@ -11,7 +13,6 @@
|
|||
#include <xf86drm.h>
|
||||
|
||||
#include <wlr/backend/interface.h>
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
|
|
@ -30,6 +31,21 @@
|
|||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
#include "relative-pointer-unstable-v1-client-protocol.h"
|
||||
|
||||
struct wlr_wl_linux_dmabuf_feedback_v1 {
|
||||
struct wlr_wl_backend *backend;
|
||||
dev_t main_device_id;
|
||||
struct wlr_wl_linux_dmabuf_v1_table_entry *format_table;
|
||||
size_t format_table_size;
|
||||
|
||||
dev_t tranche_target_device_id;
|
||||
};
|
||||
|
||||
struct wlr_wl_linux_dmabuf_v1_table_entry {
|
||||
uint32_t format;
|
||||
uint32_t pad; /* unused */
|
||||
uint64_t modifier;
|
||||
};
|
||||
|
||||
struct wlr_wl_backend *get_wl_backend_from_backend(struct wlr_backend *backend) {
|
||||
assert(wlr_backend_is_wl(backend));
|
||||
return (struct wlr_wl_backend *)backend;
|
||||
|
|
@ -75,6 +91,16 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = {
|
|||
xdg_wm_base_handle_ping,
|
||||
};
|
||||
|
||||
static void presentation_handle_clock_id(void *data,
|
||||
struct wp_presentation *presentation, uint32_t clock) {
|
||||
struct wlr_wl_backend *wl = data;
|
||||
wl->presentation_clock = clock;
|
||||
}
|
||||
|
||||
static const struct wp_presentation_listener presentation_listener = {
|
||||
.clock_id = presentation_handle_clock_id,
|
||||
};
|
||||
|
||||
static void linux_dmabuf_v1_handle_format(void *data,
|
||||
struct zwp_linux_dmabuf_v1 *linux_dmabuf_v1, uint32_t format) {
|
||||
// Note, this event is deprecated
|
||||
|
|
@ -98,6 +124,119 @@ static const struct zwp_linux_dmabuf_v1_listener linux_dmabuf_v1_listener = {
|
|||
.modifier = linux_dmabuf_v1_handle_modifier,
|
||||
};
|
||||
|
||||
static void linux_dmabuf_feedback_v1_handle_done(void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback) {
|
||||
// This space is intentionally left blank
|
||||
}
|
||||
|
||||
static void linux_dmabuf_feedback_v1_handle_format_table(void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback, int fd, uint32_t size) {
|
||||
struct wlr_wl_linux_dmabuf_feedback_v1 *feedback_data = data;
|
||||
|
||||
feedback_data->format_table = NULL;
|
||||
|
||||
void *table_data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (table_data == MAP_FAILED) {
|
||||
wlr_log_errno(WLR_ERROR, "failed to mmap DMA-BUF format table");
|
||||
} else {
|
||||
feedback_data->format_table = table_data;
|
||||
feedback_data->format_table_size = size;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void linux_dmabuf_feedback_v1_handle_main_device(void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||
struct wl_array *dev_id_arr) {
|
||||
struct wlr_wl_linux_dmabuf_feedback_v1 *feedback_data = data;
|
||||
|
||||
dev_t dev_id;
|
||||
assert(dev_id_arr->size == sizeof(dev_id));
|
||||
memcpy(&dev_id, dev_id_arr->data, sizeof(dev_id));
|
||||
|
||||
feedback_data->main_device_id = dev_id;
|
||||
|
||||
drmDevice *device = NULL;
|
||||
if (drmGetDeviceFromDevId(dev_id, 0, &device) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmGetDeviceFromDevId failed");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *name = NULL;
|
||||
if (device->available_nodes & (1 << DRM_NODE_RENDER)) {
|
||||
name = device->nodes[DRM_NODE_RENDER];
|
||||
} else {
|
||||
// Likely a split display/render setup. Pick the primary node and hope
|
||||
// Mesa will open the right render node under-the-hood.
|
||||
assert(device->available_nodes & (1 << DRM_NODE_PRIMARY));
|
||||
name = device->nodes[DRM_NODE_PRIMARY];
|
||||
wlr_log(WLR_DEBUG, "DRM device %s has no render node, "
|
||||
"falling back to primary node", name);
|
||||
}
|
||||
|
||||
feedback_data->backend->drm_render_name = strdup(name);
|
||||
|
||||
drmFreeDevice(&device);
|
||||
}
|
||||
|
||||
static void linux_dmabuf_feedback_v1_handle_tranche_done(void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback) {
|
||||
struct wlr_wl_linux_dmabuf_feedback_v1 *feedback_data = data;
|
||||
feedback_data->tranche_target_device_id = 0;
|
||||
}
|
||||
|
||||
static void linux_dmabuf_feedback_v1_handle_tranche_target_device(void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||
struct wl_array *dev_id_arr) {
|
||||
struct wlr_wl_linux_dmabuf_feedback_v1 *feedback_data = data;
|
||||
|
||||
dev_t dev_id;
|
||||
assert(dev_id_arr->size == sizeof(dev_id));
|
||||
memcpy(&dev_id, dev_id_arr->data, sizeof(dev_id));
|
||||
|
||||
feedback_data->tranche_target_device_id = dev_id;
|
||||
}
|
||||
|
||||
static void linux_dmabuf_feedback_v1_handle_tranche_formats(void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback,
|
||||
struct wl_array *indices_arr) {
|
||||
struct wlr_wl_linux_dmabuf_feedback_v1 *feedback_data = data;
|
||||
|
||||
if (feedback_data->format_table == NULL) {
|
||||
return;
|
||||
}
|
||||
if (feedback_data->tranche_target_device_id != feedback_data->main_device_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t table_cap = feedback_data->format_table_size /
|
||||
sizeof(struct wlr_wl_linux_dmabuf_v1_table_entry);
|
||||
uint16_t *index_ptr;
|
||||
wl_array_for_each(index_ptr, indices_arr) {
|
||||
assert(*index_ptr < table_cap);
|
||||
const struct wlr_wl_linux_dmabuf_v1_table_entry *entry =
|
||||
&feedback_data->format_table[*index_ptr];
|
||||
wlr_drm_format_set_add(&feedback_data->backend->linux_dmabuf_v1_formats,
|
||||
entry->format, entry->modifier);
|
||||
}
|
||||
}
|
||||
|
||||
static void linux_dmabuf_feedback_v1_handle_tranche_flags(void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *feedback, uint32_t flags) {
|
||||
// TODO: handle SCANOUT flag
|
||||
}
|
||||
|
||||
static const struct zwp_linux_dmabuf_feedback_v1_listener
|
||||
linux_dmabuf_feedback_v1_listener = {
|
||||
.done = linux_dmabuf_feedback_v1_handle_done,
|
||||
.format_table = linux_dmabuf_feedback_v1_handle_format_table,
|
||||
.main_device = linux_dmabuf_feedback_v1_handle_main_device,
|
||||
.tranche_done = linux_dmabuf_feedback_v1_handle_tranche_done,
|
||||
.tranche_target_device = linux_dmabuf_feedback_v1_handle_tranche_target_device,
|
||||
.tranche_formats = linux_dmabuf_feedback_v1_handle_tranche_formats,
|
||||
.tranche_flags = linux_dmabuf_feedback_v1_handle_tranche_flags,
|
||||
};
|
||||
|
||||
static bool device_has_name(const drmDevice *device, const char *name) {
|
||||
for (size_t i = 0; i < DRM_NODE_MAX; i++) {
|
||||
if (!(device->available_nodes & (1 << i))) {
|
||||
|
|
@ -162,8 +301,6 @@ static char *get_render_name(const char *name) {
|
|||
static void legacy_drm_handle_device(void *data, struct wl_drm *drm,
|
||||
const char *name) {
|
||||
struct wlr_wl_backend *wl = data;
|
||||
|
||||
// TODO: get FD from linux-dmabuf hints instead
|
||||
wl->drm_render_name = get_render_name(name);
|
||||
}
|
||||
|
||||
|
|
@ -227,13 +364,15 @@ static void registry_global(void *data, struct wl_registry *registry,
|
|||
} else if (strcmp(iface, wp_presentation_interface.name) == 0) {
|
||||
wl->presentation = wl_registry_bind(registry, name,
|
||||
&wp_presentation_interface, 1);
|
||||
wp_presentation_add_listener(wl->presentation,
|
||||
&presentation_listener, wl);
|
||||
} else if (strcmp(iface, zwp_tablet_manager_v2_interface.name) == 0) {
|
||||
wl->tablet_manager = wl_registry_bind(registry, name,
|
||||
&zwp_tablet_manager_v2_interface, 1);
|
||||
} else if (strcmp(iface, zwp_linux_dmabuf_v1_interface.name) == 0 &&
|
||||
version >= 3) {
|
||||
wl->zwp_linux_dmabuf_v1 = wl_registry_bind(registry, name,
|
||||
&zwp_linux_dmabuf_v1_interface, 3);
|
||||
&zwp_linux_dmabuf_v1_interface, version >= 4 ? 4 : version);
|
||||
zwp_linux_dmabuf_v1_add_listener(wl->zwp_linux_dmabuf_v1,
|
||||
&linux_dmabuf_v1_listener, wl);
|
||||
} else if (strcmp(iface, zwp_relative_pointer_manager_v1_interface.name) == 0) {
|
||||
|
|
@ -302,9 +441,9 @@ static void backend_destroy(struct wlr_backend *backend) {
|
|||
wlr_output_destroy(&output->wlr_output);
|
||||
}
|
||||
|
||||
struct wlr_input_device *input_device, *tmp_input_device;
|
||||
struct wlr_wl_input_device *input_device, *tmp_input_device;
|
||||
wl_list_for_each_safe(input_device, tmp_input_device, &wl->devices, link) {
|
||||
wlr_input_device_destroy(input_device);
|
||||
destroy_wl_input_device(input_device);
|
||||
}
|
||||
|
||||
struct wlr_wl_buffer *buffer, *tmp_buffer;
|
||||
|
|
@ -352,6 +491,11 @@ static void backend_destroy(struct wlr_backend *backend) {
|
|||
free(wl);
|
||||
}
|
||||
|
||||
static clockid_t backend_get_presentation_clock(struct wlr_backend *backend) {
|
||||
struct wlr_wl_backend *wl = get_wl_backend_from_backend(backend);
|
||||
return wl->presentation_clock;
|
||||
}
|
||||
|
||||
static int backend_get_drm_fd(struct wlr_backend *backend) {
|
||||
struct wlr_wl_backend *wl = get_wl_backend_from_backend(backend);
|
||||
return wl->drm_fd;
|
||||
|
|
@ -366,6 +510,7 @@ static uint32_t get_buffer_caps(struct wlr_backend *backend) {
|
|||
static const struct wlr_backend_impl backend_impl = {
|
||||
.start = backend_start,
|
||||
.destroy = backend_destroy,
|
||||
.get_presentation_clock = backend_get_presentation_clock,
|
||||
.get_drm_fd = backend_get_drm_fd,
|
||||
.get_buffer_caps = get_buffer_caps,
|
||||
};
|
||||
|
|
@ -397,6 +542,7 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display,
|
|||
wl_list_init(&wl->outputs);
|
||||
wl_list_init(&wl->seats);
|
||||
wl_list_init(&wl->buffers);
|
||||
wl->presentation_clock = CLOCK_MONOTONIC;
|
||||
|
||||
wl->remote_display = wl_display_connect(remote);
|
||||
if (!wl->remote_display) {
|
||||
|
|
@ -409,10 +555,9 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display,
|
|||
wlr_log_errno(WLR_ERROR, "Could not obtain reference to remote registry");
|
||||
goto error_display;
|
||||
}
|
||||
|
||||
wl_registry_add_listener(wl->registry, ®istry_listener, wl);
|
||||
|
||||
wl_display_roundtrip(wl->remote_display); // get globals
|
||||
wl_display_roundtrip(wl->remote_display); // get linux-dmabuf formats
|
||||
|
||||
if (!wl->compositor) {
|
||||
wlr_log(WLR_ERROR,
|
||||
|
|
@ -425,6 +570,35 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display,
|
|||
goto error_registry;
|
||||
}
|
||||
|
||||
struct zwp_linux_dmabuf_feedback_v1 *linux_dmabuf_feedback_v1 = NULL;
|
||||
struct wlr_wl_linux_dmabuf_feedback_v1 feedback_data = { .backend = wl };
|
||||
if (wl->zwp_linux_dmabuf_v1 != NULL &&
|
||||
zwp_linux_dmabuf_v1_get_version(wl->zwp_linux_dmabuf_v1) >=
|
||||
ZWP_LINUX_DMABUF_V1_GET_DEFAULT_FEEDBACK_SINCE_VERSION) {
|
||||
linux_dmabuf_feedback_v1 =
|
||||
zwp_linux_dmabuf_v1_get_default_feedback(wl->zwp_linux_dmabuf_v1);
|
||||
if (linux_dmabuf_feedback_v1 == NULL) {
|
||||
wlr_log(WLR_ERROR, "Allocation failed");
|
||||
goto error_registry;
|
||||
}
|
||||
zwp_linux_dmabuf_feedback_v1_add_listener(linux_dmabuf_feedback_v1,
|
||||
&linux_dmabuf_feedback_v1_listener, &feedback_data);
|
||||
|
||||
if (wl->legacy_drm != NULL) {
|
||||
wl_drm_destroy(wl->legacy_drm);
|
||||
wl->legacy_drm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
wl_display_roundtrip(wl->remote_display); // get linux-dmabuf formats
|
||||
|
||||
if (feedback_data.format_table != NULL) {
|
||||
munmap(feedback_data.format_table, feedback_data.format_table_size);
|
||||
}
|
||||
if (linux_dmabuf_feedback_v1 != NULL) {
|
||||
zwp_linux_dmabuf_feedback_v1_destroy(linux_dmabuf_feedback_v1);
|
||||
}
|
||||
|
||||
struct wl_event_loop *loop = wl_display_get_event_loop(wl->local_display);
|
||||
int fd = wl_display_get_fd(wl->remote_display);
|
||||
wl->remote_display_src = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
wayland_client = dependency('wayland-client',
|
||||
fallback: 'wayland',
|
||||
default_options: wayland_project_options,
|
||||
)
|
||||
wlr_deps += wayland_client
|
||||
|
||||
wlr_files += files(
|
||||
'backend.c',
|
||||
'output.c',
|
||||
|
|
|
|||
|
|
@ -166,18 +166,8 @@ static struct wl_buffer *import_dmabuf(struct wlr_wl_backend *wl,
|
|||
dmabuf->offset[i], dmabuf->stride[i], modifier_hi, modifier_lo);
|
||||
}
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (dmabuf->flags & WLR_DMABUF_ATTRIBUTES_FLAGS_Y_INVERT) {
|
||||
flags |= ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT;
|
||||
}
|
||||
if (dmabuf->flags & WLR_DMABUF_ATTRIBUTES_FLAGS_INTERLACED) {
|
||||
flags |= ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED;
|
||||
}
|
||||
if (dmabuf->flags & WLR_DMABUF_ATTRIBUTES_FLAGS_BOTTOM_FIRST) {
|
||||
flags |= ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_BOTTOM_FIRST;
|
||||
}
|
||||
struct wl_buffer *wl_buffer = zwp_linux_buffer_params_v1_create_immed(
|
||||
params, dmabuf->width, dmabuf->height, dmabuf->format, flags);
|
||||
params, dmabuf->width, dmabuf->height, dmabuf->format, 0);
|
||||
// TODO: handle create() errors
|
||||
return wl_buffer;
|
||||
}
|
||||
|
|
@ -530,12 +520,14 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *wlr_backend) {
|
|||
wlr_output_update_custom_mode(wlr_output, 1280, 720, 0);
|
||||
strncpy(wlr_output->make, "wayland", sizeof(wlr_output->make));
|
||||
strncpy(wlr_output->model, "wayland", sizeof(wlr_output->model));
|
||||
snprintf(wlr_output->name, sizeof(wlr_output->name), "WL-%zd",
|
||||
++backend->last_output_num);
|
||||
|
||||
char name[64];
|
||||
snprintf(name, sizeof(name), "WL-%zu", ++backend->last_output_num);
|
||||
wlr_output_set_name(wlr_output, name);
|
||||
|
||||
char description[128];
|
||||
snprintf(description, sizeof(description),
|
||||
"Wayland output %zd", backend->last_output_num);
|
||||
"Wayland output %zu", backend->last_output_num);
|
||||
wlr_output_set_description(wlr_output, description);
|
||||
|
||||
output->backend = backend;
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@
|
|||
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/interfaces/wlr_touch.h>
|
||||
#include <wlr/interfaces/wlr_tablet_tool.h>
|
||||
#include <wlr/interfaces/wlr_tablet_pad.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||
|
|
@ -22,15 +23,20 @@
|
|||
#include "util/signal.h"
|
||||
#include "util/time.h"
|
||||
|
||||
static const struct wlr_pointer_impl pointer_impl;
|
||||
static const struct wlr_keyboard_impl keyboard_impl;
|
||||
static const struct wlr_touch_impl touch_impl;
|
||||
|
||||
static struct wlr_wl_pointer *output_get_pointer(
|
||||
struct wlr_wl_output *output,
|
||||
const struct wl_pointer *wl_pointer) {
|
||||
struct wlr_input_device *wlr_dev;
|
||||
wl_list_for_each(wlr_dev, &output->backend->devices, link) {
|
||||
if (wlr_dev->type != WLR_INPUT_DEVICE_POINTER) {
|
||||
struct wlr_wl_input_device *dev;
|
||||
wl_list_for_each(dev, &output->backend->devices, link) {
|
||||
if (dev->wlr_input_device.type != WLR_INPUT_DEVICE_POINTER) {
|
||||
continue;
|
||||
}
|
||||
struct wlr_wl_pointer *pointer = pointer_get_wl(wlr_dev->pointer);
|
||||
struct wlr_wl_pointer *pointer =
|
||||
pointer_get_wl(dev->wlr_input_device.pointer);
|
||||
if (pointer->output == output && pointer->wl_pointer == wl_pointer) {
|
||||
return pointer;
|
||||
}
|
||||
|
|
@ -430,26 +436,21 @@ static struct wlr_wl_seat *input_device_get_seat(struct wlr_input_device *wlr_de
|
|||
return dev->seat;
|
||||
}
|
||||
|
||||
static void input_device_destroy(struct wlr_input_device *wlr_dev) {
|
||||
struct wlr_wl_input_device *dev =
|
||||
get_wl_input_device_from_input_device(wlr_dev);
|
||||
if (dev->wlr_input_device.type == WLR_INPUT_DEVICE_KEYBOARD) {
|
||||
struct wlr_wl_seat *seat = input_device_get_seat(wlr_dev);
|
||||
wl_keyboard_release(seat->keyboard);
|
||||
seat->keyboard = NULL;
|
||||
}
|
||||
// We can't destroy pointer here because we might have multiple devices
|
||||
// exposing it to compositor.
|
||||
wl_list_remove(&dev->wlr_input_device.link);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static const struct wlr_input_device_impl input_device_impl = {
|
||||
.destroy = input_device_destroy,
|
||||
};
|
||||
|
||||
bool wlr_input_device_is_wl(struct wlr_input_device *dev) {
|
||||
return dev->impl == &input_device_impl;
|
||||
switch (dev->type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
return dev->keyboard->impl == &keyboard_impl;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
return dev->pointer->impl == &pointer_impl;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
return dev->touch->impl == &touch_impl;
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
return dev->tablet->impl == &tablet_impl;
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
return dev->tablet_pad->impl == &tablet_pad_impl;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
struct wlr_wl_input_device *create_wl_input_device(
|
||||
|
|
@ -465,19 +466,51 @@ struct wlr_wl_input_device *create_wl_input_device(
|
|||
|
||||
struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
|
||||
|
||||
unsigned int vendor = 0, product = 0;
|
||||
const char *type_name = "unknown";
|
||||
|
||||
size_t name_size = 8 + strlen(seat->name) + 1;
|
||||
switch (type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
type_name = "keyboard";
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
type_name = "pointer";
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
type_name = "touch";
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
type_name = "tablet-tool";
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
type_name = "tablet-pad";
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
type_name = "switch";
|
||||
break;
|
||||
}
|
||||
|
||||
size_t name_size = 8 + strlen(type_name) + strlen(seat->name) + 1;
|
||||
char name[name_size];
|
||||
(void) snprintf(name, name_size, "wayland-%s", seat->name);
|
||||
(void) snprintf(name, name_size, "wayland-%s-%s", type_name, seat->name);
|
||||
|
||||
wlr_input_device_init(wlr_dev, type, &input_device_impl, name, vendor,
|
||||
product);
|
||||
wl_list_insert(&seat->backend->devices, &wlr_dev->link);
|
||||
wlr_input_device_init(wlr_dev, type, name);
|
||||
wl_list_insert(&seat->backend->devices, &dev->link);
|
||||
return dev;
|
||||
}
|
||||
|
||||
static const struct wlr_pointer_impl pointer_impl;
|
||||
void destroy_wl_input_device(struct wlr_wl_input_device *dev) {
|
||||
/**
|
||||
* TODO remove the redundant wlr_input_device from wlr_wl_input_device
|
||||
* wlr_wl_input_device::wlr_input_device is not owned by its input device
|
||||
* type, which means we have 2 wlr_input_device to cleanup
|
||||
*/
|
||||
wlr_input_device_finish(&dev->wlr_input_device);
|
||||
if (dev->wlr_input_device._device) {
|
||||
wlr_input_device_destroy(&dev->wlr_input_device);
|
||||
}
|
||||
wl_list_remove(&dev->link);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
struct wlr_wl_pointer *pointer_get_wl(struct wlr_pointer *wlr_pointer) {
|
||||
assert(wlr_pointer->impl == &pointer_impl);
|
||||
|
|
@ -684,7 +717,7 @@ static void pointer_handle_output_destroy(struct wl_listener *listener,
|
|||
void *data) {
|
||||
struct wlr_wl_pointer *pointer =
|
||||
wl_container_of(listener, pointer, output_destroy);
|
||||
wlr_input_device_destroy(&pointer->input_device->wlr_input_device);
|
||||
destroy_wl_input_device(pointer->input_device);
|
||||
}
|
||||
|
||||
void create_wl_pointer(struct wlr_wl_seat *seat, struct wlr_wl_output *output) {
|
||||
|
|
@ -716,13 +749,14 @@ void create_wl_pointer(struct wlr_wl_seat *seat, struct wlr_wl_output *output) {
|
|||
}
|
||||
pointer->input_device = dev;
|
||||
|
||||
wl_signal_add(&output->wlr_output.events.destroy, &pointer->output_destroy);
|
||||
pointer->output_destroy.notify = pointer_handle_output_destroy;
|
||||
|
||||
struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
|
||||
wlr_dev->pointer = &pointer->wlr_pointer;
|
||||
wlr_dev->output_name = strdup(output->wlr_output.name);
|
||||
wlr_pointer_init(wlr_dev->pointer, &pointer_impl);
|
||||
|
||||
wlr_pointer_init(&pointer->wlr_pointer, &pointer_impl, wlr_dev->name);
|
||||
|
||||
wl_signal_add(&output->wlr_output.events.destroy, &pointer->output_destroy);
|
||||
pointer->output_destroy.notify = pointer_handle_output_destroy;
|
||||
|
||||
if (backend->zwp_pointer_gestures_v1) {
|
||||
uint32_t version = zwp_pointer_gestures_v1_get_version(
|
||||
|
|
@ -764,14 +798,14 @@ void create_wl_keyboard(struct wlr_wl_seat *seat) {
|
|||
}
|
||||
|
||||
struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
|
||||
|
||||
wlr_dev->keyboard = calloc(1, sizeof(*wlr_dev->keyboard));
|
||||
if (!wlr_dev->keyboard) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
wlr_input_device_destroy(wlr_dev);
|
||||
destroy_wl_input_device(dev);
|
||||
return;
|
||||
}
|
||||
wlr_keyboard_init(wlr_dev->keyboard, NULL);
|
||||
|
||||
wlr_keyboard_init(wlr_dev->keyboard, &keyboard_impl, wlr_dev->name);
|
||||
|
||||
wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, wlr_dev);
|
||||
wlr_signal_emit_safe(&seat->backend->backend.events.new_input, wlr_dev);
|
||||
|
|
@ -791,16 +825,15 @@ void create_wl_touch(struct wlr_wl_seat *seat) {
|
|||
wlr_dev->touch = calloc(1, sizeof(*wlr_dev->touch));
|
||||
if (!wlr_dev->touch) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
wlr_input_device_destroy(wlr_dev);
|
||||
destroy_wl_input_device(dev);
|
||||
return;
|
||||
}
|
||||
wlr_touch_init(wlr_dev->touch, NULL);
|
||||
wlr_touch_init(wlr_dev->touch, &touch_impl, wlr_dev->name);
|
||||
|
||||
wl_touch_add_listener(wl_touch, &touch_listener, dev);
|
||||
wlr_signal_emit_safe(&seat->backend->backend.events.new_input, wlr_dev);
|
||||
}
|
||||
|
||||
|
||||
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||
enum wl_seat_capability caps) {
|
||||
struct wlr_wl_seat *seat = data;
|
||||
|
|
@ -822,19 +855,20 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
|
||||
struct wl_pointer *wl_pointer = seat->pointer;
|
||||
|
||||
struct wlr_input_device *device, *tmp;
|
||||
struct wlr_wl_input_device *device, *tmp;
|
||||
wl_list_for_each_safe(device, tmp, &backend->devices, link) {
|
||||
if (device->type != WLR_INPUT_DEVICE_POINTER) {
|
||||
if (device->wlr_input_device.type != WLR_INPUT_DEVICE_POINTER) {
|
||||
continue;
|
||||
}
|
||||
struct wlr_wl_pointer *pointer = pointer_get_wl(device->pointer);
|
||||
struct wlr_wl_pointer *pointer =
|
||||
pointer_get_wl(device->wlr_input_device.pointer);
|
||||
if (pointer->wl_pointer != wl_pointer) {
|
||||
continue;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "dropping pointer %s",
|
||||
pointer->input_device->wlr_input_device.name);
|
||||
struct wlr_wl_output *output = pointer->output;
|
||||
wlr_input_device_destroy(device);
|
||||
destroy_wl_input_device(device);
|
||||
assert(seat->active_pointer != pointer);
|
||||
assert(output->cursor.pointer != pointer);
|
||||
}
|
||||
|
|
@ -856,18 +890,16 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->keyboard != NULL) {
|
||||
wlr_log(WLR_DEBUG, "seat %p dropped keyboard", (void *)wl_seat);
|
||||
|
||||
struct wlr_input_device *device, *tmp;
|
||||
struct wlr_wl_input_device *device, *tmp;
|
||||
wl_list_for_each_safe(device, tmp, &backend->devices, link) {
|
||||
if (device->type != WLR_INPUT_DEVICE_KEYBOARD) {
|
||||
if (device->wlr_input_device.type != WLR_INPUT_DEVICE_KEYBOARD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct wlr_wl_input_device *input_device =
|
||||
get_wl_input_device_from_input_device(device);
|
||||
if (input_device->seat != seat) {
|
||||
if (device->seat != seat) {
|
||||
continue;
|
||||
}
|
||||
wlr_input_device_destroy(device);
|
||||
destroy_wl_input_device(device);
|
||||
}
|
||||
assert(seat->keyboard == NULL); // free'ed by input_device_destroy
|
||||
}
|
||||
|
|
@ -883,10 +915,10 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
|||
if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch != NULL) {
|
||||
wlr_log(WLR_DEBUG, "seat %p dropped touch", (void *)wl_seat);
|
||||
|
||||
struct wlr_input_device *device, *tmp;
|
||||
struct wlr_wl_input_device *device, *tmp;
|
||||
wl_list_for_each_safe(device, tmp, &backend->devices, link) {
|
||||
if (device->type == WLR_INPUT_DEVICE_TOUCH) {
|
||||
wlr_input_device_destroy(device);
|
||||
if (device->wlr_input_device.type == WLR_INPUT_DEVICE_TOUCH) {
|
||||
destroy_wl_input_device(device);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <wlr/interfaces/wlr_tablet_pad.h>
|
||||
#include <wlr/interfaces/wlr_tablet_tool.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
|
||||
#include "util/signal.h"
|
||||
#include "util/time.h"
|
||||
|
|
@ -402,7 +401,7 @@ static void handle_tablet_pad_removed(void *data,
|
|||
/* This doesn't free anything, but emits the destroy signal */
|
||||
wlr_input_device_destroy(&dev->wlr_input_device);
|
||||
/* This is a bit ugly, but we need to remove it from our list */
|
||||
wl_list_remove(&dev->wlr_input_device.link);
|
||||
wl_list_remove(&dev->link);
|
||||
|
||||
struct wlr_wl_tablet_pad_group *group, *it;
|
||||
wl_list_for_each_safe(group, it, &tablet_pad->groups, group.link) {
|
||||
|
|
@ -426,6 +425,8 @@ static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = {
|
|||
.removed = handle_tablet_pad_removed,
|
||||
};
|
||||
|
||||
const struct wlr_tablet_pad_impl tablet_pad_impl = {0};
|
||||
|
||||
static void handle_pad_added(void *data,
|
||||
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2,
|
||||
struct zwp_tablet_pad_v2 *id) {
|
||||
|
|
@ -453,7 +454,7 @@ static void handle_pad_added(void *data,
|
|||
zwp_tablet_pad_v2_destroy(id);
|
||||
return;
|
||||
}
|
||||
wlr_tablet_pad_init(wlr_dev->tablet_pad, NULL);
|
||||
wlr_tablet_pad_init(wlr_dev->tablet_pad, &tablet_pad_impl, wlr_dev->name);
|
||||
zwp_tablet_pad_v2_add_listener(id, &tablet_pad_listener, dev);
|
||||
}
|
||||
|
||||
|
|
@ -873,7 +874,7 @@ static void handle_tablet_removed(void *data,
|
|||
/* This doesn't free anything, but emits the destroy signal */
|
||||
wlr_input_device_destroy(&dev->wlr_input_device);
|
||||
/* This is a bit ugly, but we need to remove it from our list */
|
||||
wl_list_remove(&dev->wlr_input_device.link);
|
||||
wl_list_remove(&dev->link);
|
||||
|
||||
zwp_tablet_v2_destroy(dev->resource);
|
||||
free(dev);
|
||||
|
|
@ -887,6 +888,8 @@ static const struct zwp_tablet_v2_listener tablet_listener = {
|
|||
.removed = handle_tablet_removed,
|
||||
};
|
||||
|
||||
const struct wlr_tablet_impl tablet_impl = {0};
|
||||
|
||||
static void handle_tab_added(void *data,
|
||||
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2,
|
||||
struct zwp_tablet_v2 *id) {
|
||||
|
|
@ -909,7 +912,7 @@ static void handle_tab_added(void *data,
|
|||
return;
|
||||
}
|
||||
zwp_tablet_v2_set_user_data(id, wlr_dev->tablet);
|
||||
wlr_tablet_init(wlr_dev->tablet, NULL);
|
||||
wlr_tablet_init(wlr_dev->tablet, &tablet_impl, wlr_dev->name);
|
||||
zwp_tablet_v2_add_listener(id, &tablet_listener, dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include <wlr/backend/interface.h>
|
||||
#include <wlr/backend/x11.h>
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
|
@ -165,7 +164,7 @@ static bool backend_start(struct wlr_backend *backend) {
|
|||
|
||||
wlr_log(WLR_INFO, "Starting X11 backend");
|
||||
|
||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &x11->keyboard_dev);
|
||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &x11->keyboard.base);
|
||||
|
||||
for (size_t i = 0; i < x11->requested_outputs; ++i) {
|
||||
wlr_x11_output_create(&x11->backend);
|
||||
|
|
@ -186,7 +185,7 @@ static void backend_destroy(struct wlr_backend *backend) {
|
|||
wlr_output_destroy(&output->wlr_output);
|
||||
}
|
||||
|
||||
wlr_input_device_destroy(&x11->keyboard_dev);
|
||||
wlr_keyboard_destroy(&x11->keyboard);
|
||||
|
||||
wlr_backend_finish(backend);
|
||||
|
||||
|
|
@ -354,6 +353,7 @@ static bool query_formats(struct wlr_x11_backend *x11) {
|
|||
}
|
||||
|
||||
if (x11->have_dri3) {
|
||||
// X11 always supports implicit modifiers
|
||||
wlr_drm_format_set_add(&x11->dri3_formats, format->drm,
|
||||
DRM_FORMAT_MOD_INVALID);
|
||||
if (!query_dri3_modifiers(x11, format)) {
|
||||
|
|
@ -572,9 +572,9 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
|||
goto error_event;
|
||||
}
|
||||
|
||||
x11->depth = get_depth(x11->screen, 32);
|
||||
x11->depth = get_depth(x11->screen, 24);
|
||||
if (!x11->depth) {
|
||||
wlr_log(WLR_ERROR, "Failed to get 32-bit depth for X11 screen");
|
||||
wlr_log(WLR_ERROR, "Failed to get 24-bit depth for X11 screen");
|
||||
goto error_event;
|
||||
}
|
||||
|
||||
|
|
@ -637,10 +637,7 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
|||
}
|
||||
#endif
|
||||
|
||||
wlr_input_device_init(&x11->keyboard_dev, WLR_INPUT_DEVICE_KEYBOARD,
|
||||
&input_device_impl, "X11 keyboard", 0, 0);
|
||||
wlr_keyboard_init(&x11->keyboard, &keyboard_impl);
|
||||
x11->keyboard_dev.keyboard = &x11->keyboard;
|
||||
wlr_keyboard_init(&x11->keyboard, &x11_keyboard_impl, "x11-keyboard");
|
||||
|
||||
x11->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &x11->display_destroy);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <xcb/xfixes.h>
|
||||
#include <xcb/xinput.h>
|
||||
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/interfaces/wlr_touch.h>
|
||||
|
|
@ -33,7 +32,7 @@ static void send_key_event(struct wlr_x11_backend *x11, uint32_t key,
|
|||
static void send_button_event(struct wlr_x11_output *output, uint32_t key,
|
||||
enum wlr_button_state st, xcb_timestamp_t time) {
|
||||
struct wlr_event_pointer_button ev = {
|
||||
.device = &output->pointer_dev,
|
||||
.device = &output->pointer.base,
|
||||
.time_msec = time,
|
||||
.button = key,
|
||||
.state = st,
|
||||
|
|
@ -45,7 +44,7 @@ static void send_button_event(struct wlr_x11_output *output, uint32_t key,
|
|||
static void send_axis_event(struct wlr_x11_output *output, int32_t delta,
|
||||
xcb_timestamp_t time) {
|
||||
struct wlr_event_pointer_axis ev = {
|
||||
.device = &output->pointer_dev,
|
||||
.device = &output->pointer.base,
|
||||
.time_msec = time,
|
||||
.source = WLR_AXIS_SOURCE_WHEEL,
|
||||
.orientation = WLR_AXIS_ORIENTATION_VERTICAL,
|
||||
|
|
@ -60,7 +59,7 @@ static void send_axis_event(struct wlr_x11_output *output, int32_t delta,
|
|||
static void send_pointer_position_event(struct wlr_x11_output *output,
|
||||
int16_t x, int16_t y, xcb_timestamp_t time) {
|
||||
struct wlr_event_pointer_motion_absolute ev = {
|
||||
.device = &output->pointer_dev,
|
||||
.device = &output->pointer.base,
|
||||
.time_msec = time,
|
||||
.x = (double)x / output->wlr_output.width,
|
||||
.y = (double)y / output->wlr_output.height,
|
||||
|
|
@ -72,7 +71,7 @@ static void send_pointer_position_event(struct wlr_x11_output *output,
|
|||
static void send_touch_down_event(struct wlr_x11_output *output,
|
||||
int16_t x, int16_t y, int32_t touch_id, xcb_timestamp_t time) {
|
||||
struct wlr_event_touch_down ev = {
|
||||
.device = &output->touch_dev,
|
||||
.device = &output->touch.base,
|
||||
.time_msec = time,
|
||||
.x = (double)x / output->wlr_output.width,
|
||||
.y = (double)y / output->wlr_output.height,
|
||||
|
|
@ -85,7 +84,7 @@ static void send_touch_down_event(struct wlr_x11_output *output,
|
|||
static void send_touch_motion_event(struct wlr_x11_output *output,
|
||||
int16_t x, int16_t y, int32_t touch_id, xcb_timestamp_t time) {
|
||||
struct wlr_event_touch_motion ev = {
|
||||
.device = &output->touch_dev,
|
||||
.device = &output->touch.base,
|
||||
.time_msec = time,
|
||||
.x = (double)x / output->wlr_output.width,
|
||||
.y = (double)y / output->wlr_output.height,
|
||||
|
|
@ -98,7 +97,7 @@ static void send_touch_motion_event(struct wlr_x11_output *output,
|
|||
static void send_touch_up_event(struct wlr_x11_output *output,
|
||||
int32_t touch_id, xcb_timestamp_t time) {
|
||||
struct wlr_event_touch_up ev = {
|
||||
.device = &output->touch_dev,
|
||||
.device = &output->touch.base,
|
||||
.time_msec = time,
|
||||
.touch_id = touch_id,
|
||||
};
|
||||
|
|
@ -286,19 +285,11 @@ void handle_x11_xinput_event(struct wlr_x11_backend *x11,
|
|||
}
|
||||
}
|
||||
|
||||
static void input_device_destroy(struct wlr_input_device *wlr_device) {
|
||||
// Don't free the input device, it's on the stack
|
||||
}
|
||||
|
||||
const struct wlr_input_device_impl input_device_impl = {
|
||||
.destroy = input_device_destroy,
|
||||
};
|
||||
|
||||
static void keyboard_destroy(struct wlr_keyboard *wlr_keyboard) {
|
||||
// Don't free the keyboard, it's on the stack
|
||||
}
|
||||
|
||||
const struct wlr_keyboard_impl keyboard_impl = {
|
||||
const struct wlr_keyboard_impl x11_keyboard_impl = {
|
||||
.destroy = keyboard_destroy,
|
||||
};
|
||||
|
||||
|
|
@ -306,7 +297,7 @@ static void pointer_destroy(struct wlr_pointer *wlr_pointer) {
|
|||
// Don't free the pointer, it's on the stack
|
||||
}
|
||||
|
||||
const struct wlr_pointer_impl pointer_impl = {
|
||||
const struct wlr_pointer_impl x11_pointer_impl = {
|
||||
.destroy = pointer_destroy,
|
||||
};
|
||||
|
||||
|
|
@ -314,7 +305,7 @@ static void touch_destroy(struct wlr_touch *wlr_touch) {
|
|||
// Don't free the touch, it's on the stack
|
||||
}
|
||||
|
||||
const struct wlr_touch_impl touch_impl = {
|
||||
const struct wlr_touch_impl x11_touch_impl = {
|
||||
.destroy = touch_destroy,
|
||||
};
|
||||
|
||||
|
|
@ -336,5 +327,14 @@ void update_x11_pointer_position(struct wlr_x11_output *output,
|
|||
}
|
||||
|
||||
bool wlr_input_device_is_x11(struct wlr_input_device *wlr_dev) {
|
||||
return wlr_dev->impl == &input_device_impl;
|
||||
switch (wlr_dev->type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
return wlr_dev->keyboard->impl == &x11_keyboard_impl;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
return wlr_dev->pointer->impl == &x11_pointer_impl;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
return wlr_dev->touch->impl == &x11_touch_impl;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ static void output_destroy(struct wlr_output *wlr_output) {
|
|||
|
||||
pixman_region32_fini(&output->exposed);
|
||||
|
||||
wlr_input_device_destroy(&output->pointer_dev);
|
||||
wlr_input_device_destroy(&output->touch_dev);
|
||||
wlr_pointer_destroy(&output->pointer);
|
||||
wlr_touch_destroy(&output->touch);
|
||||
|
||||
struct wlr_x11_buffer *buffer, *buffer_tmp;
|
||||
wl_list_for_each_safe(buffer, buffer_tmp, &output->buffers, link) {
|
||||
|
|
@ -140,10 +140,6 @@ static xcb_pixmap_t import_dmabuf(struct wlr_x11_output *output,
|
|||
return XCB_PIXMAP_NONE;
|
||||
}
|
||||
|
||||
if (dmabuf->flags != 0) {
|
||||
return XCB_PIXMAP_NONE;
|
||||
}
|
||||
|
||||
// xcb closes the FDs after sending them, so we need to dup them here
|
||||
struct wlr_dmabuf_attributes dup_attrs = {0};
|
||||
if (!wlr_dmabuf_attributes_copy(&dup_attrs, dmabuf)) {
|
||||
|
|
@ -380,7 +376,7 @@ static void update_x11_output_cursor(struct wlr_x11_output *output,
|
|||
static bool output_cursor_to_picture(struct wlr_x11_output *output,
|
||||
struct wlr_buffer *buffer) {
|
||||
struct wlr_x11_backend *x11 = output->x11;
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(&x11->backend);
|
||||
struct wlr_renderer *renderer = output->wlr_output.renderer;
|
||||
|
||||
if (output->cursor.pic != XCB_NONE) {
|
||||
xcb_render_free_picture(x11->xcb, output->cursor.pic);
|
||||
|
|
@ -516,13 +512,15 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
|
|||
|
||||
wlr_output_update_custom_mode(wlr_output, 1024, 768, 0);
|
||||
|
||||
snprintf(wlr_output->name, sizeof(wlr_output->name), "X11-%zd",
|
||||
++x11->last_output_num);
|
||||
char name[64];
|
||||
snprintf(name, sizeof(name), "X11-%zu", ++x11->last_output_num);
|
||||
wlr_output_set_name(wlr_output, name);
|
||||
|
||||
parse_xcb_setup(wlr_output, x11->xcb);
|
||||
|
||||
char description[128];
|
||||
snprintf(description, sizeof(description),
|
||||
"X11 output %zd", x11->last_output_num);
|
||||
"X11 output %zu", x11->last_output_num);
|
||||
wlr_output_set_description(wlr_output, description);
|
||||
|
||||
// The X11 protocol requires us to set a colormap and border pixel if the
|
||||
|
|
@ -575,22 +573,16 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
|
|||
|
||||
wlr_output_update_enabled(wlr_output, true);
|
||||
|
||||
wlr_input_device_init(&output->pointer_dev, WLR_INPUT_DEVICE_POINTER,
|
||||
&input_device_impl, "X11 pointer", 0, 0);
|
||||
wlr_pointer_init(&output->pointer, &pointer_impl);
|
||||
output->pointer_dev.pointer = &output->pointer;
|
||||
output->pointer_dev.output_name = strdup(wlr_output->name);
|
||||
wlr_pointer_init(&output->pointer, &x11_pointer_impl, "x11-pointer");
|
||||
output->pointer.base.output_name = strdup(wlr_output->name);
|
||||
|
||||
wlr_input_device_init(&output->touch_dev, WLR_INPUT_DEVICE_TOUCH,
|
||||
&input_device_impl, "X11 touch", 0, 0);
|
||||
wlr_touch_init(&output->touch, &touch_impl);
|
||||
output->touch_dev.touch = &output->touch;
|
||||
output->touch_dev.output_name = strdup(wlr_output->name);
|
||||
wlr_touch_init(&output->touch, &x11_touch_impl, "x11-touch");
|
||||
output->touch.base.output_name = strdup(wlr_output->name);
|
||||
wl_list_init(&output->touchpoints);
|
||||
|
||||
wlr_signal_emit_safe(&x11->backend.events.new_output, wlr_output);
|
||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &output->pointer_dev);
|
||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &output->touch_dev);
|
||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &output->pointer.base);
|
||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &output->touch.base);
|
||||
|
||||
// Start the rendering loop by requesting the compositor to render a frame
|
||||
wlr_output_schedule_frame(wlr_output);
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@ wlroots reads these environment variables
|
|||
# wlroots specific
|
||||
|
||||
* *WLR_BACKENDS*: comma-separated list of backends to use (available backends:
|
||||
libinput, drm, wayland, x11, headless, noop)
|
||||
libinput, drm, wayland, x11, headless)
|
||||
* *WLR_NO_HARDWARE_CURSORS*: set to 1 to use software cursors instead of
|
||||
hardware cursors
|
||||
* *WLR_DIRECT_TTY*: specifies the tty to be used (instead of using /dev/tty)
|
||||
* *WLR_XWAYLAND*: specifies the path to an Xwayland binary to be used (instead
|
||||
of following shell search semantics for "Xwayland")
|
||||
* *WLR_RENDERER*: forces the creation of a specified renderer (available
|
||||
renderers: gles2, pixman)
|
||||
renderers: gles2, pixman, vulkan)
|
||||
* *WLR_RENDER_DRM_DEVICE*: specifies the DRM node to use for
|
||||
hardware-accelerated renderers.
|
||||
|
||||
## DRM backend
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#define _POSIX_C_SOURCE 199309L
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/display.h>
|
||||
#include <libavutil/hwcontext_drm.h>
|
||||
|
|
@ -619,12 +620,12 @@ static int init_encoding(struct capture_context *ctx) {
|
|||
}
|
||||
|
||||
/* Find encoder */
|
||||
AVCodec *out_codec = avcodec_find_encoder_by_name(ctx->encoder_name);
|
||||
const AVCodec *out_codec = avcodec_find_encoder_by_name(ctx->encoder_name);
|
||||
if (!out_codec) {
|
||||
av_log(ctx, AV_LOG_ERROR, "Codec not found (not compiled in lavc?)!\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
ctx->avf->oformat->video_codec = out_codec->id;
|
||||
ctx->avf->oformat = av_guess_format(ctx->encoder_name, NULL, NULL);
|
||||
ctx->is_software_encoder = !(out_codec->capabilities & AV_CODEC_CAP_HARDWARE);
|
||||
|
||||
ctx->avctx = avcodec_alloc_context3(out_codec);
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@
|
|||
#include <unistd.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_fullscreen_shell_v1.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/util/box.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
|
|
@ -25,6 +25,7 @@ struct fullscreen_server {
|
|||
struct wl_display *wl_display;
|
||||
struct wlr_backend *backend;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
|
||||
struct wlr_fullscreen_shell_v1 *fullscreen_shell;
|
||||
struct wl_listener present_surface;
|
||||
|
|
@ -146,6 +147,8 @@ static void server_handle_new_output(struct wl_listener *listener, void *data) {
|
|||
wl_container_of(listener, server, new_output);
|
||||
struct wlr_output *wlr_output = data;
|
||||
|
||||
wlr_output_init_render(wlr_output, server->allocator, server->renderer);
|
||||
|
||||
struct fullscreen_output *output =
|
||||
calloc(1, sizeof(struct fullscreen_output));
|
||||
output->wlr_output = wlr_output;
|
||||
|
|
@ -203,8 +206,10 @@ int main(int argc, char *argv[]) {
|
|||
struct fullscreen_server server = {0};
|
||||
server.wl_display = wl_display_create();
|
||||
server.backend = wlr_backend_autocreate(server.wl_display);
|
||||
server.renderer = wlr_backend_get_renderer(server.backend);
|
||||
server.renderer = wlr_renderer_autocreate(server.backend);
|
||||
wlr_renderer_init_wl_display(server.renderer, server.wl_display);
|
||||
server.allocator = wlr_allocator_autocreate(server.backend,
|
||||
server.renderer);
|
||||
|
||||
wlr_compositor_create(server.wl_display, server.renderer);
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include <wayland-client.h>
|
||||
#include <wayland-cursor.h>
|
||||
#include <wayland-egl.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "egl_common.h"
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
|
|
@ -177,8 +176,7 @@ static const struct xdg_surface_listener xdg_surface_listener = {
|
|||
|
||||
static void xdg_popup_configure(void *data, struct xdg_popup *xdg_popup,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height) {
|
||||
wlr_log(WLR_DEBUG, "Popup configured %dx%d@%d,%d",
|
||||
width, height, x, y);
|
||||
fprintf(stderr, "Popup configured %dx%d@%d,%d\n", width, height, x, y);
|
||||
popup_width = width;
|
||||
popup_height = height;
|
||||
if (popup_egl_window) {
|
||||
|
|
@ -197,7 +195,7 @@ static void popup_destroy(void) {
|
|||
}
|
||||
|
||||
static void xdg_popup_done(void *data, struct xdg_popup *xdg_popup) {
|
||||
wlr_log(WLR_DEBUG, "Popup done");
|
||||
fprintf(stderr, "Popup done\n");
|
||||
popup_destroy();
|
||||
}
|
||||
|
||||
|
|
@ -377,17 +375,17 @@ static void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||
|
||||
static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
|
||||
wlr_log(WLR_DEBUG, "Keyboard enter");
|
||||
fprintf(stderr, "Keyboard enter\n");
|
||||
}
|
||||
|
||||
static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, struct wl_surface *surface) {
|
||||
wlr_log(WLR_DEBUG, "Keyboard leave");
|
||||
fprintf(stderr, "Keyboard leave\n");
|
||||
}
|
||||
|
||||
static void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard,
|
||||
uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
|
||||
wlr_log(WLR_DEBUG, "Key event: %d %d", key, state);
|
||||
fprintf(stderr, "Key event: %d %d\n", key, state);
|
||||
}
|
||||
|
||||
static void wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,
|
||||
|
|
@ -473,7 +471,6 @@ static const struct wl_registry_listener registry_listener = {
|
|||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
wlr_log_init(WLR_DEBUG, NULL);
|
||||
char *namespace = "wlroots";
|
||||
int exclusive_zone = 0;
|
||||
int32_t margin_right = 0, margin_bottom = 0, margin_left = 0;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
threads = dependency('threads')
|
||||
wayland_egl = dependency('wayland-egl')
|
||||
wayland_cursor = dependency('wayland-cursor')
|
||||
wayland_client = dependency('wayland-client')
|
||||
libpng = dependency('libpng', required: false, disabler: true)
|
||||
egl = dependency('egl', required: false, disabler: true)
|
||||
glesv2 = dependency('glesv2', required: false, disabler: true)
|
||||
|
|
@ -81,7 +82,7 @@ clients = {
|
|||
},
|
||||
'layer-shell': {
|
||||
'src': ['layer-shell.c', 'egl_common.c'],
|
||||
'dep': [wayland_egl, wayland_cursor, wlroots, egl, glesv2],
|
||||
'dep': [wayland_egl, wayland_cursor, egl, glesv2],
|
||||
'proto': [
|
||||
'wlr-layer-shell-unstable-v1',
|
||||
'xdg-shell',
|
||||
|
|
@ -102,7 +103,7 @@ clients = {
|
|||
},
|
||||
'output-power-management': {
|
||||
'src': 'output-power-management.c',
|
||||
'dep': [wayland_client, wlroots],
|
||||
'dep': [wayland_client],
|
||||
'proto': ['wlr-output-power-management-unstable-v1'],
|
||||
},
|
||||
'pointer-constraints': {
|
||||
|
|
@ -128,7 +129,7 @@ clients = {
|
|||
libavcodec,
|
||||
libavformat,
|
||||
libavutil,
|
||||
drm.partial_dependency(compile_args: true), # <drm_fourcc.h>
|
||||
drm,
|
||||
threads,
|
||||
],
|
||||
'proto': ['wlr-export-dmabuf-unstable-v1'],
|
||||
|
|
@ -173,12 +174,10 @@ clients = {
|
|||
},
|
||||
'foreign-toplevel': {
|
||||
'src': 'foreign-toplevel.c',
|
||||
'dep': [wlroots],
|
||||
'proto': ['wlr-foreign-toplevel-management-unstable-v1'],
|
||||
},
|
||||
'virtual-pointer': {
|
||||
'src': 'virtual-pointer.c',
|
||||
'dep': wlroots,
|
||||
'proto': ['wlr-virtual-pointer-unstable-v1'],
|
||||
},
|
||||
'input-method-keyboard-grab': {
|
||||
|
|
@ -215,7 +214,7 @@ foreach name, info : clients
|
|||
executable(
|
||||
name,
|
||||
[info.get('src'), extra_src],
|
||||
dependencies: [wayland_client, info.get('dep')],
|
||||
dependencies: [wayland_client, info.get('dep', [])],
|
||||
build_by_default: get_option('examples'),
|
||||
)
|
||||
endforeach
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
|
|
@ -22,6 +23,8 @@
|
|||
struct sample_state {
|
||||
struct wl_display *display;
|
||||
struct wlr_xcursor *xcursor;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
float default_color[4];
|
||||
float clear_color[4];
|
||||
struct wlr_output_layout *layout;
|
||||
|
|
@ -90,7 +93,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||
struct sample_output *output = wl_container_of(listener, output, frame);
|
||||
struct sample_state *sample = output->sample;
|
||||
struct wlr_output *wlr_output = output->output;
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
|
||||
struct wlr_renderer *renderer = sample->renderer;
|
||||
|
||||
wlr_output_attach_render(wlr_output, NULL);
|
||||
|
||||
|
|
@ -144,6 +147,9 @@ static void output_remove_notify(struct wl_listener *listener, void *data) {
|
|||
static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output *output = data;
|
||||
struct sample_state *sample = wl_container_of(listener, sample, new_output);
|
||||
|
||||
wlr_output_init_render(output, sample->allocator, sample->renderer);
|
||||
|
||||
struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
|
||||
sample_output->output = output;
|
||||
sample_output->sample = sample;
|
||||
|
|
@ -269,6 +275,10 @@ int main(int argc, char *argv[]) {
|
|||
if (!wlr) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
state.renderer = wlr_renderer_autocreate(wlr);
|
||||
state.allocator = wlr_allocator_autocreate(wlr, state.renderer);
|
||||
|
||||
wl_list_init(&state.cursors);
|
||||
wl_list_init(&state.pointers);
|
||||
wl_list_init(&state.outputs);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
|
|
@ -27,6 +28,7 @@ struct sample_state {
|
|||
struct wl_listener new_output;
|
||||
struct wl_listener new_input;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
struct wlr_texture *cat_texture;
|
||||
struct wlr_output_layout *layout;
|
||||
float x_offs, y_offs;
|
||||
|
|
@ -158,6 +160,9 @@ static void output_remove_notify(struct wl_listener *listener, void *data) {
|
|||
static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output *output = data;
|
||||
struct sample_state *sample = wl_container_of(listener, sample, new_output);
|
||||
|
||||
wlr_output_init_render(output, sample->allocator, sample->renderer);
|
||||
|
||||
struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
|
||||
wlr_output_layout_add_auto(sample->layout, output);
|
||||
sample_output->output = output;
|
||||
|
|
@ -273,11 +278,13 @@ int main(int argc, char *argv[]) {
|
|||
wl_signal_add(&wlr->events.new_input, &state.new_input);
|
||||
state.new_input.notify = new_input_notify;
|
||||
|
||||
state.renderer = wlr_backend_get_renderer(wlr);
|
||||
state.renderer = wlr_renderer_autocreate(wlr);
|
||||
state.cat_texture = wlr_texture_from_pixels(state.renderer,
|
||||
DRM_FORMAT_ABGR8888, cat_tex.width * 4, cat_tex.width, cat_tex.height,
|
||||
cat_tex.pixel_data);
|
||||
|
||||
state.allocator = wlr_allocator_autocreate(wlr, state.renderer);
|
||||
|
||||
if (!wlr_backend_start(wlr)) {
|
||||
wlr_log(WLR_ERROR, "Failed to start backend");
|
||||
wlr_backend_destroy(wlr);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
|
|
@ -24,6 +25,8 @@
|
|||
struct sample_state {
|
||||
struct wl_display *display;
|
||||
struct compositor_state *compositor;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
struct wlr_xcursor_manager *xcursor_manager;
|
||||
struct wlr_cursor *cursor;
|
||||
double cur_x, cur_y;
|
||||
|
|
@ -95,7 +98,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||
struct sample_output *sample_output = wl_container_of(listener, sample_output, frame);
|
||||
struct sample_state *state = sample_output->state;
|
||||
struct wlr_output *wlr_output = sample_output->output;
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
|
||||
struct wlr_renderer *renderer = state->renderer;
|
||||
assert(renderer);
|
||||
|
||||
wlr_output_attach_render(wlr_output, NULL);
|
||||
|
|
@ -250,6 +253,9 @@ static void output_remove_notify(struct wl_listener *listener, void *data) {
|
|||
static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output *output = data;
|
||||
struct sample_state *sample = wl_container_of(listener, sample, new_output);
|
||||
|
||||
wlr_output_init_render(output, sample->allocator, sample->renderer);
|
||||
|
||||
struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
|
||||
sample_output->output = output;
|
||||
sample_output->state = sample;
|
||||
|
|
@ -331,6 +337,10 @@ int main(int argc, char *argv[]) {
|
|||
if (!wlr) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
state.renderer = wlr_renderer_autocreate(wlr);
|
||||
state.allocator = wlr_allocator_autocreate(wlr, state.renderer);
|
||||
|
||||
state.cursor = wlr_cursor_create();
|
||||
state.layout = wlr_output_layout_create();
|
||||
wlr_cursor_attach_output_layout(state.cursor, state.layout);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <unistd.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
|
@ -24,6 +25,7 @@ struct sample_state {
|
|||
struct wl_listener new_input;
|
||||
struct timespec last_frame;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
struct wl_list outputs;
|
||||
};
|
||||
|
||||
|
|
@ -103,6 +105,9 @@ static void output_remove_notify(struct wl_listener *listener, void *data) {
|
|||
static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output *output = data;
|
||||
struct sample_state *sample = wl_container_of(listener, sample, new_output);
|
||||
|
||||
wlr_output_init_render(output, sample->allocator, sample->renderer);
|
||||
|
||||
struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
|
||||
|
||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
||||
|
|
@ -195,13 +200,15 @@ int main(int argc, char *argv[]) {
|
|||
state.new_input.notify = new_input_notify;
|
||||
clock_gettime(CLOCK_MONOTONIC, &state.last_frame);
|
||||
|
||||
state.renderer = wlr_backend_get_renderer(wlr);
|
||||
state.renderer = wlr_renderer_autocreate(wlr);
|
||||
if (!state.renderer) {
|
||||
wlr_log(WLR_ERROR, "Could not start compositor, OOM");
|
||||
wlr_backend_destroy(wlr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
state.allocator = wlr_allocator_autocreate(wlr, state.renderer);
|
||||
|
||||
if (!wlr_backend_start(wlr)) {
|
||||
wlr_log(WLR_ERROR, "Failed to start backend");
|
||||
wlr_backend_destroy(wlr);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <unistd.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
|
@ -25,6 +26,7 @@ struct sample_state {
|
|||
struct wl_listener new_input;
|
||||
struct timespec last_frame;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
struct wlr_texture *cat_texture;
|
||||
struct wl_list outputs;
|
||||
enum wl_output_transform transform;
|
||||
|
|
@ -105,6 +107,9 @@ static void output_remove_notify(struct wl_listener *listener, void *data) {
|
|||
static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output *output = data;
|
||||
struct sample_state *sample = wl_container_of(listener, sample, new_output);
|
||||
|
||||
wlr_output_init_render(output, sample->allocator, sample->renderer);
|
||||
|
||||
struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
|
||||
sample_output->x_offs = sample_output->y_offs = 0;
|
||||
sample_output->x_vel = sample_output->y_vel = 128;
|
||||
|
|
@ -245,7 +250,7 @@ int main(int argc, char *argv[]) {
|
|||
state.new_input.notify = new_input_notify;
|
||||
clock_gettime(CLOCK_MONOTONIC, &state.last_frame);
|
||||
|
||||
state.renderer = wlr_backend_get_renderer(wlr);
|
||||
state.renderer = wlr_renderer_autocreate(wlr);
|
||||
if (!state.renderer) {
|
||||
wlr_log(WLR_ERROR, "Could not start compositor, OOM");
|
||||
wlr_backend_destroy(wlr);
|
||||
|
|
@ -259,6 +264,8 @@ int main(int argc, char *argv[]) {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
state.allocator = wlr_allocator_autocreate(wlr, state.renderer);
|
||||
|
||||
if (!wlr_backend_start(wlr)) {
|
||||
wlr_log(WLR_ERROR, "Failed to start backend");
|
||||
wlr_backend_destroy(wlr);
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@
|
|||
#include <unistd.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
|
|
@ -25,10 +25,11 @@ static const int border_width = 3;
|
|||
struct server {
|
||||
struct wl_display *display;
|
||||
struct wlr_backend *backend;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
struct wlr_scene *scene;
|
||||
|
||||
struct wl_list outputs;
|
||||
struct wl_list surfaces;
|
||||
uint32_t surface_offset;
|
||||
|
||||
struct wl_listener new_output;
|
||||
struct wl_listener new_surface;
|
||||
|
|
@ -62,24 +63,21 @@ static void output_handle_frame(struct wl_listener *listener, void *data) {
|
|||
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
struct surface *surface;
|
||||
wl_list_for_each(surface, &output->server->surfaces, link) {
|
||||
wlr_surface_send_frame_done(surface->wlr, &now);
|
||||
}
|
||||
wlr_scene_output_send_frame_done(output->scene_output, &now);
|
||||
}
|
||||
|
||||
static void server_handle_new_output(struct wl_listener *listener, void *data) {
|
||||
struct server *server = wl_container_of(listener, server, new_output);
|
||||
struct wlr_output *wlr_output = data;
|
||||
|
||||
wlr_output_init_render(wlr_output, server->allocator, server->renderer);
|
||||
|
||||
struct output *output =
|
||||
calloc(1, sizeof(struct output));
|
||||
output->wlr = wlr_output;
|
||||
output->server = server;
|
||||
output->frame.notify = output_handle_frame;
|
||||
wl_signal_add(&wlr_output->events.frame, &output->frame);
|
||||
wl_list_insert(&server->outputs, &output->link);
|
||||
|
||||
output->scene_output = wlr_scene_output_create(server->scene, wlr_output);
|
||||
|
||||
|
|
@ -113,7 +111,8 @@ static void server_handle_new_surface(struct wl_listener *listener,
|
|||
struct server *server = wl_container_of(listener, server, new_surface);
|
||||
struct wlr_surface *wlr_surface = data;
|
||||
|
||||
int pos = 50 * wl_list_length(&server->surfaces);
|
||||
int pos = server->surface_offset;
|
||||
server->surface_offset += 50;
|
||||
|
||||
struct surface *surface = calloc(1, sizeof(struct surface));
|
||||
surface->wlr = wlr_surface;
|
||||
|
|
@ -129,7 +128,6 @@ static void server_handle_new_surface(struct wl_listener *listener,
|
|||
|
||||
surface->scene_surface =
|
||||
wlr_scene_surface_create(&server->scene->node, wlr_surface);
|
||||
wl_list_insert(server->surfaces.prev, &surface->link);
|
||||
|
||||
wlr_scene_node_set_position(&surface->scene_surface->node,
|
||||
pos + border_width, pos + border_width);
|
||||
|
|
@ -157,21 +155,22 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
struct server server = {0};
|
||||
server.surface_offset = 0;
|
||||
server.display = wl_display_create();
|
||||
server.backend = wlr_backend_autocreate(server.display);
|
||||
server.scene = wlr_scene_create();
|
||||
|
||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(server.backend);
|
||||
wlr_renderer_init_wl_display(renderer, server.display);
|
||||
server.renderer = wlr_renderer_autocreate(server.backend);
|
||||
wlr_renderer_init_wl_display(server.renderer, server.display);
|
||||
|
||||
server.allocator = wlr_allocator_autocreate(server.backend,
|
||||
server.renderer);
|
||||
|
||||
struct wlr_compositor *compositor =
|
||||
wlr_compositor_create(server.display, renderer);
|
||||
wlr_compositor_create(server.display, server.renderer);
|
||||
|
||||
wlr_xdg_shell_create(server.display);
|
||||
|
||||
wl_list_init(&server.outputs);
|
||||
wl_list_init(&server.surfaces);
|
||||
|
||||
server.new_output.notify = server_handle_new_output;
|
||||
wl_signal_add(&server.backend->events.new_output, &server.new_output);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
|
|
@ -18,6 +19,8 @@ struct sample_state {
|
|||
struct wl_display *display;
|
||||
struct wl_listener new_output;
|
||||
struct wl_listener new_input;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
struct timespec last_frame;
|
||||
float color[4];
|
||||
int dec;
|
||||
|
|
@ -61,8 +64,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||
|
||||
wlr_output_attach_render(wlr_output, NULL);
|
||||
|
||||
struct wlr_renderer *renderer =
|
||||
wlr_backend_get_renderer(wlr_output->backend);
|
||||
struct wlr_renderer *renderer = sample->renderer;
|
||||
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
|
||||
wlr_renderer_clear(renderer, sample->color);
|
||||
wlr_renderer_end(renderer);
|
||||
|
|
@ -84,6 +86,9 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
|||
struct wlr_output *output = data;
|
||||
struct sample_state *sample =
|
||||
wl_container_of(listener, sample, new_output);
|
||||
|
||||
wlr_output_init_render(output, sample->allocator, sample->renderer);
|
||||
|
||||
struct sample_output *sample_output =
|
||||
calloc(1, sizeof(struct sample_output));
|
||||
sample_output->output = output;
|
||||
|
|
@ -171,6 +176,10 @@ int main(void) {
|
|||
if (!backend) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
state.renderer = wlr_renderer_autocreate(backend);
|
||||
state.allocator = wlr_allocator_autocreate(backend, state.renderer);
|
||||
|
||||
wl_signal_add(&backend->events.new_output, &state.new_output);
|
||||
state.new_output.notify = new_output_notify;
|
||||
wl_signal_add(&backend->events.new_input, &state.new_input);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
struct sample_state {
|
||||
struct wl_display *display;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
bool proximity, tap, button;
|
||||
double distance;
|
||||
double pressure;
|
||||
|
|
@ -237,6 +239,9 @@ static void output_remove_notify(struct wl_listener *listener, void *data) {
|
|||
static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output *output = data;
|
||||
struct sample_state *sample = wl_container_of(listener, sample, new_output);
|
||||
|
||||
wlr_output_init_render(output, sample->allocator, sample->renderer);
|
||||
|
||||
struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
|
||||
sample_output->output = output;
|
||||
sample_output->sample = sample;
|
||||
|
|
@ -361,11 +366,14 @@ int main(int argc, char *argv[]) {
|
|||
state.new_input.notify = new_input_notify;
|
||||
clock_gettime(CLOCK_MONOTONIC, &state.last_frame);
|
||||
|
||||
state.renderer = wlr_backend_get_renderer(wlr);
|
||||
state.renderer = wlr_renderer_autocreate(wlr);
|
||||
if (!state.renderer) {
|
||||
wlr_log(WLR_ERROR, "Could not start compositor, OOM");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
state.allocator = wlr_allocator_autocreate(wlr, state.renderer);
|
||||
|
||||
if (!wlr_backend_start(wlr)) {
|
||||
wlr_log(WLR_ERROR, "Failed to start backend");
|
||||
wlr_backend_destroy(wlr);
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/session.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_matrix.h>
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
struct sample_state {
|
||||
struct wl_display *display;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
struct wlr_texture *cat_texture;
|
||||
struct wl_list touch_points;
|
||||
struct timespec last_frame;
|
||||
|
|
@ -148,6 +150,9 @@ static void output_remove_notify(struct wl_listener *listener, void *data) {
|
|||
static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output *output = data;
|
||||
struct sample_state *sample = wl_container_of(listener, sample, new_output);
|
||||
|
||||
wlr_output_init_render(output, sample->allocator, sample->renderer);
|
||||
|
||||
struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
|
||||
sample_output->output = output;
|
||||
sample_output->sample = sample;
|
||||
|
|
@ -254,8 +259,7 @@ int main(int argc, char *argv[]) {
|
|||
state.new_input.notify = new_input_notify;
|
||||
clock_gettime(CLOCK_MONOTONIC, &state.last_frame);
|
||||
|
||||
|
||||
state.renderer = wlr_backend_get_renderer(wlr);
|
||||
state.renderer = wlr_renderer_autocreate(wlr);
|
||||
if (!state.renderer) {
|
||||
wlr_log(WLR_ERROR, "Could not start compositor, OOM");
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
@ -268,6 +272,8 @@ int main(int argc, char *argv[]) {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
state.allocator = wlr_allocator_autocreate(wlr, state.renderer);
|
||||
|
||||
if (!wlr_backend_start(wlr)) {
|
||||
wlr_log(WLR_ERROR, "Failed to start backend");
|
||||
wlr_backend_destroy(wlr);
|
||||
|
|
|
|||
|
|
@ -10,10 +10,4 @@
|
|||
*/
|
||||
uint32_t backend_get_buffer_caps(struct wlr_backend *backend);
|
||||
|
||||
/**
|
||||
* Get the backend's allocator. Automatically creates the allocator if
|
||||
* necessary.
|
||||
*/
|
||||
struct wlr_allocator *backend_get_allocator(struct wlr_backend *backend);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ struct wlr_drm_plane {
|
|||
|
||||
struct wlr_drm_crtc {
|
||||
uint32_t id;
|
||||
uint32_t lessee_id;
|
||||
struct wlr_drm_lease *lease;
|
||||
|
||||
// Atomic modesetting only
|
||||
uint32_t mode_id;
|
||||
|
|
@ -118,7 +118,7 @@ struct wlr_drm_connector {
|
|||
enum wlr_drm_connector_status status;
|
||||
bool desired_enabled;
|
||||
uint32_t id;
|
||||
uint32_t lessee_id;
|
||||
struct wlr_drm_lease *lease;
|
||||
|
||||
struct wlr_drm_crtc *crtc;
|
||||
uint32_t possible_crtcs;
|
||||
|
|
@ -149,6 +149,7 @@ bool init_drm_resources(struct wlr_drm_backend *drm);
|
|||
void finish_drm_resources(struct wlr_drm_backend *drm);
|
||||
void scan_drm_connectors(struct wlr_drm_backend *state,
|
||||
struct wlr_device_hotplug_event *event);
|
||||
void scan_drm_leases(struct wlr_drm_backend *drm);
|
||||
int handle_drm_event(int fd, uint32_t mask, void *data);
|
||||
void destroy_drm_connector(struct wlr_drm_connector *conn);
|
||||
bool drm_connector_commit_state(struct wlr_drm_connector *conn,
|
||||
|
|
@ -157,6 +158,7 @@ bool drm_connector_is_cursor_visible(struct wlr_drm_connector *conn);
|
|||
bool drm_connector_supports_vrr(struct wlr_drm_connector *conn);
|
||||
size_t drm_crtc_get_gamma_lut_size(struct wlr_drm_backend *drm,
|
||||
struct wlr_drm_crtc *crtc);
|
||||
void drm_lease_destroy(struct wlr_drm_lease *lease);
|
||||
|
||||
struct wlr_drm_fb *plane_get_next_fb(struct wlr_drm_plane *plane);
|
||||
|
||||
|
|
|
|||
24
include/backend/drm/monitor.h
Normal file
24
include/backend/drm/monitor.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef BACKEND_DRM_MONITOR_H
|
||||
#define BACKEND_DRM_MONITOR_H
|
||||
|
||||
#include <wlr/backend/drm.h>
|
||||
|
||||
/**
|
||||
* Helper to create new DRM sub-backends on GPU hotplug.
|
||||
*/
|
||||
struct wlr_drm_backend_monitor {
|
||||
struct wlr_backend *multi;
|
||||
struct wlr_backend *primary_drm;
|
||||
struct wlr_session *session;
|
||||
|
||||
struct wl_listener multi_destroy;
|
||||
struct wl_listener primary_drm_destroy;
|
||||
struct wl_listener session_destroy;
|
||||
struct wl_listener session_add_drm_card;
|
||||
};
|
||||
|
||||
struct wlr_drm_backend_monitor *drm_backend_monitor_create(
|
||||
struct wlr_backend *multi, struct wlr_backend *primary_drm,
|
||||
struct wlr_session *session);
|
||||
|
||||
#endif
|
||||
|
|
@ -39,11 +39,4 @@ size_t match_obj(size_t num_objs, const uint32_t objs[static restrict num_objs],
|
|||
size_t num_res, const uint32_t res[static restrict num_res],
|
||||
uint32_t out[static restrict num_res]);
|
||||
|
||||
/**
|
||||
* Close a GEM buffer handle.
|
||||
*
|
||||
* TODO: replace with drmCloseBufferHandle.
|
||||
*/
|
||||
void close_bo_handle(int drm_fd, uint32_t handle);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -8,14 +8,10 @@
|
|||
|
||||
struct wlr_headless_backend {
|
||||
struct wlr_backend backend;
|
||||
int drm_fd;
|
||||
struct wl_display *display;
|
||||
struct wl_list outputs;
|
||||
size_t last_output_num;
|
||||
struct wl_list input_devices;
|
||||
struct wl_listener display_destroy;
|
||||
struct wlr_renderer *parent_renderer;
|
||||
struct wl_listener parent_renderer_destroy;
|
||||
bool started;
|
||||
};
|
||||
|
||||
|
|
@ -29,12 +25,6 @@ struct wlr_headless_output {
|
|||
int frame_delay; // ms
|
||||
};
|
||||
|
||||
struct wlr_headless_input_device {
|
||||
struct wlr_input_device wlr_input_device;
|
||||
|
||||
struct wlr_headless_backend *backend;
|
||||
};
|
||||
|
||||
struct wlr_headless_backend *headless_backend_from_backend(
|
||||
struct wlr_backend *wlr_backend);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,12 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend/interface.h>
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/interfaces/wlr_switch.h>
|
||||
#include <wlr/interfaces/wlr_tablet_pad.h>
|
||||
#include <wlr/interfaces/wlr_tablet_tool.h>
|
||||
#include <wlr/interfaces/wlr_touch.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
|
||||
struct wlr_libinput_backend {
|
||||
|
|
@ -26,7 +31,7 @@ struct wlr_libinput_backend {
|
|||
|
||||
struct wlr_libinput_input_device {
|
||||
struct wlr_input_device wlr_input_device;
|
||||
|
||||
struct wl_list link;
|
||||
struct libinput_device *handle;
|
||||
};
|
||||
|
||||
|
|
@ -39,6 +44,15 @@ struct wlr_input_device *get_appropriate_device(
|
|||
enum wlr_input_device_type desired_type,
|
||||
struct libinput_device *device);
|
||||
|
||||
void destroy_libinput_input_device(struct wlr_libinput_input_device *dev);
|
||||
|
||||
extern const struct wlr_keyboard_impl libinput_keyboard_impl;
|
||||
extern const struct wlr_pointer_impl libinput_pointer_impl;
|
||||
extern const struct wlr_switch_impl libinput_switch_impl;
|
||||
extern const struct wlr_tablet_impl libinput_tablet_impl;
|
||||
extern const struct wlr_tablet_pad_impl libinput_tablet_pad_impl;
|
||||
extern const struct wlr_touch_impl libinput_touch_impl;
|
||||
|
||||
struct wlr_keyboard *create_libinput_keyboard(
|
||||
struct libinput_device *device);
|
||||
void handle_keyboard_key(struct libinput_event *event,
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef BACKEND_NOOP_H
|
||||
#define BACKEND_NOOP_H
|
||||
|
||||
#include <wlr/backend/noop.h>
|
||||
#include <wlr/backend/interface.h>
|
||||
|
||||
struct wlr_noop_backend {
|
||||
struct wlr_backend backend;
|
||||
struct wl_display *display;
|
||||
struct wl_list outputs;
|
||||
size_t last_output_num;
|
||||
bool started;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
};
|
||||
|
||||
struct wlr_noop_output {
|
||||
struct wlr_output wlr_output;
|
||||
|
||||
struct wlr_noop_backend *backend;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct wlr_noop_backend *noop_backend_from_backend(
|
||||
struct wlr_backend *wlr_backend);
|
||||
|
||||
#endif
|
||||
|
|
@ -11,4 +11,7 @@ bool libseat_change_vt(struct wlr_session *base, unsigned vt);
|
|||
|
||||
void session_init(struct wlr_session *session);
|
||||
|
||||
struct wlr_device *session_open_if_kms(struct wlr_session *restrict session,
|
||||
const char *restrict path);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct wlr_wl_backend {
|
|||
struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1;
|
||||
struct wl_list seats; // wlr_wl_seat.link
|
||||
struct zwp_tablet_manager_v2 *tablet_manager;
|
||||
clockid_t presentation_clock;
|
||||
struct wlr_drm_format_set shm_formats;
|
||||
struct wlr_drm_format_set linux_dmabuf_v1_formats;
|
||||
struct wl_drm *legacy_drm;
|
||||
|
|
@ -86,6 +87,7 @@ struct wlr_wl_output {
|
|||
|
||||
struct wlr_wl_input_device {
|
||||
struct wlr_input_device wlr_input_device;
|
||||
struct wl_list link;
|
||||
uint32_t fingers;
|
||||
|
||||
struct wlr_wl_backend *backend;
|
||||
|
|
@ -132,9 +134,12 @@ struct wlr_wl_input_device *create_wl_input_device(
|
|||
struct wlr_wl_seat *seat, enum wlr_input_device_type type);
|
||||
bool create_wl_seat(struct wl_seat *wl_seat, struct wlr_wl_backend *wl);
|
||||
void destroy_wl_seats(struct wlr_wl_backend *wl);
|
||||
void destroy_wl_input_device(struct wlr_wl_input_device *dev);
|
||||
void destroy_wl_buffer(struct wlr_wl_buffer *buffer);
|
||||
|
||||
extern const struct wl_seat_listener seat_listener;
|
||||
extern const struct wlr_tablet_pad_impl tablet_pad_impl;
|
||||
extern const struct wlr_tablet_impl tablet_impl;
|
||||
|
||||
struct wlr_wl_tablet_seat *wl_add_tablet_seat(
|
||||
struct zwp_tablet_manager_v2 *manager,
|
||||
|
|
|
|||
|
|
@ -15,11 +15,10 @@
|
|||
|
||||
#include <pixman.h>
|
||||
#include <wlr/backend/x11.h>
|
||||
#include <wlr/interfaces/wlr_input_device.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/interfaces/wlr_output.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/interfaces/wlr_touch.h>
|
||||
#include <wlr/types/wlr_pointer.h>
|
||||
#include <wlr/render/drm_format_set.h>
|
||||
|
||||
#define XCB_EVENT_RESPONSE_TYPE_MASK 0x7f
|
||||
|
|
@ -35,10 +34,8 @@ struct wlr_x11_output {
|
|||
xcb_present_event_t present_event_id;
|
||||
|
||||
struct wlr_pointer pointer;
|
||||
struct wlr_input_device pointer_dev;
|
||||
|
||||
struct wlr_touch touch;
|
||||
struct wlr_input_device touch_dev;
|
||||
struct wl_list touchpoints; // wlr_x11_touchpoint::link
|
||||
|
||||
struct wl_list buffers; // wlr_x11_buffer::link
|
||||
|
|
@ -81,7 +78,6 @@ struct wlr_x11_backend {
|
|||
struct wl_list outputs; // wlr_x11_output::link
|
||||
|
||||
struct wlr_keyboard keyboard;
|
||||
struct wlr_input_device keyboard_dev;
|
||||
|
||||
int drm_fd;
|
||||
struct wlr_drm_format_set dri3_formats;
|
||||
|
|
@ -130,10 +126,9 @@ struct wlr_x11_backend *get_x11_backend_from_backend(
|
|||
struct wlr_x11_output *get_x11_output_from_window_id(
|
||||
struct wlr_x11_backend *x11, xcb_window_t window);
|
||||
|
||||
extern const struct wlr_keyboard_impl keyboard_impl;
|
||||
extern const struct wlr_pointer_impl pointer_impl;
|
||||
extern const struct wlr_touch_impl touch_impl;
|
||||
extern const struct wlr_input_device_impl input_device_impl;
|
||||
extern const struct wlr_keyboard_impl x11_keyboard_impl;
|
||||
extern const struct wlr_pointer_impl x11_pointer_impl;
|
||||
extern const struct wlr_touch_impl x11_touch_impl;
|
||||
|
||||
void handle_x11_xinput_event(struct wlr_x11_backend *x11,
|
||||
xcb_ge_generic_event_t *event);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <wlr/render/drm_format_set.h>
|
||||
|
||||
struct wlr_drm_format *wlr_drm_format_create(uint32_t format);
|
||||
bool wlr_drm_format_has(const struct wlr_drm_format *fmt, uint64_t modifier);
|
||||
bool wlr_drm_format_add(struct wlr_drm_format **fmt_ptr, uint64_t modifier);
|
||||
struct wlr_drm_format *wlr_drm_format_dup(const struct wlr_drm_format *format);
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ struct wlr_gles2_pixel_format {
|
|||
struct wlr_gles2_tex_shader {
|
||||
GLuint program;
|
||||
GLint proj;
|
||||
GLint invert_y;
|
||||
GLint tex;
|
||||
GLint alpha;
|
||||
GLint pos_attrib;
|
||||
|
|
@ -101,7 +100,6 @@ struct wlr_gles2_texture {
|
|||
|
||||
EGLImageKHR image;
|
||||
|
||||
bool inverted_y;
|
||||
bool has_alpha;
|
||||
|
||||
// Only affects target == GL_TEXTURE_2D
|
||||
|
|
|
|||
|
|
@ -246,7 +246,6 @@ struct wlr_vk_texture {
|
|||
bool dmabuf_imported;
|
||||
bool owned; // if dmabuf_imported: whether we have ownership of the image
|
||||
bool transitioned; // if dma_imported: whether we transitioned it away from preinit
|
||||
bool invert_y; // if dma_imported: whether we must flip y
|
||||
struct wl_list foreign_link;
|
||||
struct wl_list destroy_link;
|
||||
struct wl_list link; // wlr_gles2_renderer.textures
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ void output_pending_resolution(struct wlr_output *output, int *width,
|
|||
int *height);
|
||||
|
||||
struct wlr_drm_format *output_pick_format(struct wlr_output *output,
|
||||
const struct wlr_drm_format_set *display_formats);
|
||||
const struct wlr_drm_format_set *display_formats, uint32_t format);
|
||||
void output_clear_back_buffer(struct wlr_output *output);
|
||||
bool output_ensure_buffer(struct wlr_output *output);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef TYPES_WLR_SURFACE_H
|
||||
#define TYPES_WLR_SURFACE_H
|
||||
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
|
||||
struct wlr_renderer;
|
||||
|
||||
/**
|
||||
* Create a new surface resource with the provided new ID.
|
||||
*/
|
||||
struct wlr_surface *surface_create(struct wl_client *client,
|
||||
uint32_t version, uint32_t id, struct wlr_renderer *renderer);
|
||||
|
||||
/**
|
||||
* Create a new subsurface resource with the provided new ID.
|
||||
*/
|
||||
struct wlr_subsurface *subsurface_create(struct wlr_surface *surface,
|
||||
struct wlr_surface *parent, uint32_t version, uint32_t id);
|
||||
|
||||
#endif
|
||||
|
|
@ -5,41 +5,36 @@
|
|||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include "xdg-shell-protocol.h"
|
||||
|
||||
struct wlr_xdg_positioner_resource {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_xdg_positioner attrs;
|
||||
};
|
||||
|
||||
extern const struct wlr_surface_role xdg_toplevel_surface_role;
|
||||
extern const struct wlr_surface_role xdg_popup_surface_role;
|
||||
|
||||
struct wlr_xdg_surface *create_xdg_surface(
|
||||
struct wlr_xdg_client *client, struct wlr_surface *surface,
|
||||
struct wlr_xdg_client *client, struct wlr_surface *wlr_surface,
|
||||
uint32_t id);
|
||||
void unmap_xdg_surface(struct wlr_xdg_surface *surface);
|
||||
void reset_xdg_surface(struct wlr_xdg_surface *xdg_surface);
|
||||
void reset_xdg_surface(struct wlr_xdg_surface *surface);
|
||||
void destroy_xdg_surface(struct wlr_xdg_surface *surface);
|
||||
void handle_xdg_surface_commit(struct wlr_surface *wlr_surface);
|
||||
void handle_xdg_surface_precommit(struct wlr_surface *wlr_surface);
|
||||
void xdg_surface_role_commit(struct wlr_surface *wlr_surface);
|
||||
void xdg_surface_role_precommit(struct wlr_surface *wlr_surface,
|
||||
const struct wlr_surface_state *state);
|
||||
|
||||
void create_xdg_positioner(struct wlr_xdg_client *client, uint32_t id);
|
||||
struct wlr_xdg_positioner_resource *get_xdg_positioner_from_resource(
|
||||
struct wl_resource *resource);
|
||||
|
||||
void create_xdg_popup(struct wlr_xdg_surface *xdg_surface,
|
||||
void create_xdg_popup(struct wlr_xdg_surface *surface,
|
||||
struct wlr_xdg_surface *parent,
|
||||
struct wlr_xdg_positioner_resource *positioner, int32_t id);
|
||||
void handle_xdg_surface_popup_committed(struct wlr_xdg_surface *surface);
|
||||
struct wlr_xdg_popup_grab *get_xdg_shell_popup_grab_from_seat(
|
||||
struct wlr_xdg_shell *shell, struct wlr_seat *seat);
|
||||
struct wlr_xdg_positioner *positioner, uint32_t id);
|
||||
void unmap_xdg_popup(struct wlr_xdg_popup *popup);
|
||||
void destroy_xdg_popup(struct wlr_xdg_popup *popup);
|
||||
void handle_xdg_popup_committed(struct wlr_xdg_popup *popup);
|
||||
|
||||
void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface,
|
||||
void create_xdg_toplevel(struct wlr_xdg_surface *surface,
|
||||
uint32_t id);
|
||||
void handle_xdg_surface_toplevel_committed(struct wlr_xdg_surface *surface);
|
||||
void send_xdg_toplevel_configure(struct wlr_xdg_surface *surface,
|
||||
struct wlr_xdg_surface_configure *configure);
|
||||
void handle_xdg_toplevel_ack_configure(struct wlr_xdg_surface *surface,
|
||||
struct wlr_xdg_surface_configure *configure);
|
||||
void destroy_xdg_toplevel(struct wlr_xdg_surface *surface);
|
||||
void unmap_xdg_toplevel(struct wlr_xdg_toplevel *toplevel);
|
||||
void destroy_xdg_toplevel(struct wlr_xdg_toplevel *toplevel);
|
||||
void handle_xdg_toplevel_committed(struct wlr_xdg_toplevel *toplevel);
|
||||
struct wlr_xdg_toplevel_configure *send_xdg_toplevel_configure(
|
||||
struct wlr_xdg_toplevel *toplevel);
|
||||
void handle_xdg_toplevel_ack_configure(struct wlr_xdg_toplevel *toplevel,
|
||||
struct wlr_xdg_toplevel_configure *configure);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
* Globals that are created and destroyed on the fly need special handling to
|
||||
* prevent race conditions with wl_registry. Use this function to destroy them.
|
||||
*/
|
||||
void wlr_global_destroy_safe(struct wl_global *global,
|
||||
struct wl_display *display);
|
||||
void wlr_global_destroy_safe(struct wl_global *global);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,12 +25,6 @@ struct wlr_backend {
|
|||
/** Raised when new outputs are added, passed the wlr_output */
|
||||
struct wl_signal new_output;
|
||||
} events;
|
||||
|
||||
// Private state
|
||||
|
||||
bool has_own_renderer;
|
||||
struct wlr_renderer *renderer;
|
||||
struct wlr_allocator *allocator;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -50,10 +44,6 @@ bool wlr_backend_start(struct wlr_backend *backend);
|
|||
* automatically when the wl_display is destroyed.
|
||||
*/
|
||||
void wlr_backend_destroy(struct wlr_backend *backend);
|
||||
/**
|
||||
* Obtains the wlr_renderer reference this backend is using.
|
||||
*/
|
||||
struct wlr_renderer *wlr_backend_get_renderer(struct wlr_backend *backend);
|
||||
/**
|
||||
* Obtains the wlr_session reference from this backend if there is any.
|
||||
* Might return NULL for backends that don't use a session.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,20 @@
|
|||
#include <wlr/backend/session.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
||||
struct wlr_drm_backend;
|
||||
|
||||
struct wlr_drm_lease {
|
||||
int fd;
|
||||
uint32_t lessee_id;
|
||||
struct wlr_drm_backend *backend;
|
||||
|
||||
struct {
|
||||
struct wl_signal destroy;
|
||||
} events;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a DRM backend using the specified GPU file descriptor (typically from
|
||||
* a device node in /dev/dri).
|
||||
|
|
@ -41,18 +55,20 @@ uint32_t wlr_drm_connector_get_id(struct wlr_output *output);
|
|||
int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend);
|
||||
|
||||
/**
|
||||
* Leases a given output to the caller. The output must be from the associated
|
||||
* DRM backend.
|
||||
* Returns a valid opened DRM FD or -1 on error.
|
||||
* Leases the given outputs to the caller. The outputs must be from the
|
||||
* associated DRM backend.
|
||||
*
|
||||
* Returns NULL on error.
|
||||
*/
|
||||
int wlr_drm_create_lease(struct wlr_output **outputs, size_t n_outputs,
|
||||
uint32_t *lessee_id);
|
||||
struct wlr_drm_lease *wlr_drm_create_lease(struct wlr_output **outputs,
|
||||
size_t n_outputs, int *lease_fd);
|
||||
|
||||
/**
|
||||
* Terminates a given lease. The output will be owned again by the backend
|
||||
* Terminates and destroys a given lease.
|
||||
*
|
||||
* The outputs will be owned again by the backend.
|
||||
*/
|
||||
bool wlr_drm_backend_terminate_lease(struct wlr_backend *backend,
|
||||
uint32_t lessee_id);
|
||||
void wlr_drm_lease_terminate(struct wlr_drm_lease *lease);
|
||||
|
||||
/**
|
||||
* Add mode to the list of available modes
|
||||
|
|
|
|||
|
|
@ -18,11 +18,6 @@
|
|||
* default.
|
||||
*/
|
||||
struct wlr_backend *wlr_headless_backend_create(struct wl_display *display);
|
||||
/**
|
||||
* Creates a headless backend with an existing renderer.
|
||||
*/
|
||||
struct wlr_backend *wlr_headless_backend_create_with_renderer(
|
||||
struct wl_display *display, struct wlr_renderer *renderer);
|
||||
/**
|
||||
* Create a new headless output backed by an in-memory EGL framebuffer. You can
|
||||
* read pixels from this framebuffer via wlr_renderer_read_pixels but it is
|
||||
|
|
@ -30,15 +25,8 @@ struct wlr_backend *wlr_headless_backend_create_with_renderer(
|
|||
*/
|
||||
struct wlr_output *wlr_headless_add_output(struct wlr_backend *backend,
|
||||
unsigned int width, unsigned int height);
|
||||
/**
|
||||
* Creates a new input device. The caller is responsible for manually raising
|
||||
* any event signals on the new input device if it wants to simulate input
|
||||
* events.
|
||||
*/
|
||||
struct wlr_input_device *wlr_headless_add_input_device(
|
||||
struct wlr_backend *backend, enum wlr_input_device_type type);
|
||||
|
||||
bool wlr_backend_is_headless(struct wlr_backend *backend);
|
||||
bool wlr_input_device_is_headless(struct wlr_input_device *device);
|
||||
bool wlr_output_is_headless(struct wlr_output *output);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
struct wlr_backend_impl {
|
||||
bool (*start)(struct wlr_backend *backend);
|
||||
void (*destroy)(struct wlr_backend *backend);
|
||||
struct wlr_renderer *(*get_renderer)(struct wlr_backend *backend);
|
||||
struct wlr_session *(*get_session)(struct wlr_backend *backend);
|
||||
clockid_t (*get_presentation_clock)(struct wlr_backend *backend);
|
||||
int (*get_drm_fd)(struct wlr_backend *backend);
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* This an unstable interface of wlroots. No guarantees are made regarding the
|
||||
* future consistency of this API.
|
||||
*/
|
||||
#ifndef WLR_USE_UNSTABLE
|
||||
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
||||
#endif
|
||||
|
||||
#ifndef WLR_BACKEND_NOOP_H
|
||||
#define WLR_BACKEND_NOOP_H
|
||||
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
||||
/**
|
||||
* Creates a noop backend. Noop backends do not have a framebuffer and are not
|
||||
* capable of rendering anything. They are useful for when there's no real
|
||||
* outputs connected; you can stash your views on a noop output until an output
|
||||
* is connected.
|
||||
*/
|
||||
struct wlr_backend *wlr_noop_backend_create(struct wl_display *display);
|
||||
|
||||
/**
|
||||
* Create a new noop output.
|
||||
*/
|
||||
struct wlr_output *wlr_noop_add_output(struct wlr_backend *backend);
|
||||
|
||||
bool wlr_backend_is_noop(struct wlr_backend *backend);
|
||||
bool wlr_output_is_noop(struct wlr_output *output);
|
||||
|
||||
#endif
|
||||
|
|
@ -59,6 +59,7 @@ struct wlr_session_add_event {
|
|||
|
||||
enum wlr_device_change_type {
|
||||
WLR_DEVICE_HOTPLUG = 1,
|
||||
WLR_DEVICE_LEASE,
|
||||
};
|
||||
|
||||
struct wlr_device_hotplug_event {
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* This an unstable interface of wlroots. No guarantees are made regarding the
|
||||
* future consistency of this API.
|
||||
*/
|
||||
#ifndef WLR_USE_UNSTABLE
|
||||
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
||||
#endif
|
||||
|
||||
#ifndef WLR_INTERFACES_WLR_INPUT_DEVICE_H
|
||||
#define WLR_INTERFACES_WLR_INPUT_DEVICE_H
|
||||
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
|
||||
struct wlr_input_device_impl {
|
||||
void (*destroy)(struct wlr_input_device *wlr_device);
|
||||
};
|
||||
|
||||
void wlr_input_device_init(
|
||||
struct wlr_input_device *wlr_device,
|
||||
enum wlr_input_device_type type,
|
||||
const struct wlr_input_device_impl *impl,
|
||||
const char *name, int vendor, int product);
|
||||
void wlr_input_device_destroy(struct wlr_input_device *dev);
|
||||
|
||||
#endif
|
||||
|
|
@ -18,7 +18,7 @@ struct wlr_keyboard_impl {
|
|||
};
|
||||
|
||||
void wlr_keyboard_init(struct wlr_keyboard *keyboard,
|
||||
const struct wlr_keyboard_impl *impl);
|
||||
const struct wlr_keyboard_impl *impl, const char *name);
|
||||
void wlr_keyboard_destroy(struct wlr_keyboard *keyboard);
|
||||
void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard,
|
||||
struct wlr_event_keyboard_key *event);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
(WLR_OUTPUT_STATE_DAMAGE | \
|
||||
WLR_OUTPUT_STATE_SCALE | \
|
||||
WLR_OUTPUT_STATE_TRANSFORM | \
|
||||
WLR_OUTPUT_STATE_RENDER_FORMAT | \
|
||||
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED)
|
||||
|
||||
/**
|
||||
|
|
@ -85,7 +86,7 @@ struct wlr_output_impl {
|
|||
*/
|
||||
void (*get_cursor_size)(struct wlr_output *output, int *width, int *height);
|
||||
/**
|
||||
* Get the list of DMA-BUF formats suitable for the primary buffer,
|
||||
* Get the list of DRM formats suitable for the primary buffer,
|
||||
* assuming a buffer with the specified capabilities.
|
||||
*
|
||||
* If unimplemented, the primary buffer has no format constraint. If NULL
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ struct wlr_pointer_impl {
|
|||
};
|
||||
|
||||
void wlr_pointer_init(struct wlr_pointer *pointer,
|
||||
const struct wlr_pointer_impl *impl);
|
||||
const struct wlr_pointer_impl *impl, const char *name);
|
||||
void wlr_pointer_destroy(struct wlr_pointer *pointer);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ struct wlr_switch_impl {
|
|||
};
|
||||
|
||||
void wlr_switch_init(struct wlr_switch *switch_device,
|
||||
struct wlr_switch_impl *impl);
|
||||
const struct wlr_switch_impl *impl, const char *name);
|
||||
void wlr_switch_destroy(struct wlr_switch *switch_device);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ struct wlr_tablet_pad_impl {
|
|||
};
|
||||
|
||||
void wlr_tablet_pad_init(struct wlr_tablet_pad *pad,
|
||||
struct wlr_tablet_pad_impl *impl);
|
||||
const struct wlr_tablet_pad_impl *impl, const char *name);
|
||||
void wlr_tablet_pad_destroy(struct wlr_tablet_pad *pad);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ struct wlr_tablet_impl {
|
|||
};
|
||||
|
||||
void wlr_tablet_init(struct wlr_tablet *tablet,
|
||||
const struct wlr_tablet_impl *impl);
|
||||
const struct wlr_tablet_impl *impl, const char *name);
|
||||
void wlr_tablet_destroy(struct wlr_tablet *tablet);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ struct wlr_touch_impl {
|
|||
};
|
||||
|
||||
void wlr_touch_init(struct wlr_touch *touch,
|
||||
const struct wlr_touch_impl *impl);
|
||||
const struct wlr_touch_impl *impl, const char *name);
|
||||
void wlr_touch_destroy(struct wlr_touch *touch);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -51,6 +51,18 @@ void wlr_allocator_destroy(struct wlr_allocator *alloc);
|
|||
*
|
||||
* When the caller is done with it, they must unreference it by calling
|
||||
* wlr_buffer_drop.
|
||||
*
|
||||
* The `format` passed in indicates the format to use and the list of
|
||||
* acceptable modifiers. The order in which modifiers are listed is not
|
||||
* significant.
|
||||
*
|
||||
* When running with legacy drivers which don't support explicit modifiers, the
|
||||
* allocator must recognize two modifiers: INVALID (for implicit tiling and/or
|
||||
* compression) and LINEAR.
|
||||
*
|
||||
* The allocator must return a buffer using one of the modifiers listed. In
|
||||
* particular, allocators must not return a buffer with an implicit modifier
|
||||
* unless the user has allowed it by passing INVALID in the modifier list.
|
||||
*/
|
||||
struct wlr_buffer *wlr_allocator_create_buffer(struct wlr_allocator *alloc,
|
||||
int width, int height, const struct wlr_drm_format *format);
|
||||
|
|
|
|||
|
|
@ -14,17 +14,27 @@
|
|||
|
||||
#define WLR_DMABUF_MAX_PLANES 4
|
||||
|
||||
enum wlr_dmabuf_attributes_flags {
|
||||
WLR_DMABUF_ATTRIBUTES_FLAGS_Y_INVERT = 1 << 0,
|
||||
WLR_DMABUF_ATTRIBUTES_FLAGS_INTERLACED = 1 << 1,
|
||||
WLR_DMABUF_ATTRIBUTES_FLAGS_BOTTOM_FIRST = 1 << 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* A Linux DMA-BUF pixel buffer.
|
||||
*
|
||||
* If the buffer was allocated with explicit modifiers enabled, the `modifier`
|
||||
* field must not be INVALID.
|
||||
*
|
||||
* If the buffer was allocated with explicit modifiers disabled (either because
|
||||
* the driver doesn't support it, or because the user didn't specify a valid
|
||||
* modifier list), the `modifier` field can have two values: INVALID means that
|
||||
* an implicit vendor-defined modifier is in use, LINEAR means that the buffer
|
||||
* is linear. The `modifier` field must not have any other value.
|
||||
*
|
||||
* When importing a DMA-BUF, users must not ignore the modifier unless it's
|
||||
* INVALID or LINEAR. In particular, users must not import a DMA-BUF to a
|
||||
* legacy API which doesn't support specifying an explicit modifier unless the
|
||||
* modifier is set to INVALID or LINEAR.
|
||||
*/
|
||||
struct wlr_dmabuf_attributes {
|
||||
int32_t width, height;
|
||||
uint32_t format;
|
||||
uint32_t flags; // enum wlr_dmabuf_attributes_flags
|
||||
uint64_t modifier;
|
||||
uint32_t format; // FourCC code, see DRM_FORMAT_* in <drm_fourcc.h>
|
||||
uint64_t modifier; // see DRM_FORMAT_MOD_* in <drm_fourcc.h>
|
||||
|
||||
int n_planes;
|
||||
uint32_t offset[WLR_DMABUF_MAX_PLANES];
|
||||
|
|
|
|||
|
|
@ -5,19 +5,55 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/** A single DRM format, with a set of modifiers attached. */
|
||||
struct wlr_drm_format {
|
||||
// The actual DRM format, from `drm_fourcc.h`
|
||||
uint32_t format;
|
||||
size_t len, cap;
|
||||
// The number of modifiers
|
||||
size_t len;
|
||||
// The capacity of the array; do not use.
|
||||
size_t capacity;
|
||||
// The actual modifiers
|
||||
uint64_t modifiers[];
|
||||
};
|
||||
|
||||
/**
|
||||
* A set of DRM formats and modifiers.
|
||||
*
|
||||
* This is used to describe the supported format + modifier combinations. For
|
||||
* instance, backends will report the set they can display, and renderers will
|
||||
* report the set they can render to. For a more general overview of formats
|
||||
* and modifiers, see:
|
||||
* https://lore.kernel.org/dri-devel/20210905122742.86029-1-daniels@collabora.com/
|
||||
*
|
||||
* For compatibility with legacy drivers which don't support explicit
|
||||
* modifiers, the special modifier DRM_FORMAT_MOD_INVALID is used to indicate
|
||||
* that implicit modifiers are supported. Legacy drivers can also support the
|
||||
* DRM_FORMAT_MOD_LINEAR modifier, which forces the buffer to have a linear
|
||||
* layout.
|
||||
*
|
||||
* Users must not assume that implicit modifiers are supported unless INVALID
|
||||
* is listed in the modifier list.
|
||||
*/
|
||||
struct wlr_drm_format_set {
|
||||
size_t len, cap;
|
||||
// The number of formats
|
||||
size_t len;
|
||||
// The capacity of the array; private to wlroots
|
||||
size_t capacity;
|
||||
// A pointer to an array of `struct wlr_drm_format *` of length `len`.
|
||||
struct wlr_drm_format **formats;
|
||||
};
|
||||
|
||||
/**
|
||||
* Free all of the DRM formats in the set, making the set empty. Does not
|
||||
* free the set itself.
|
||||
*/
|
||||
void wlr_drm_format_set_finish(struct wlr_drm_format_set *set);
|
||||
|
||||
/**
|
||||
* Return a pointer to a member of this `wlr_drm_format_set` of format
|
||||
* `format`, or NULL if none exists.
|
||||
*/
|
||||
const struct wlr_drm_format *wlr_drm_format_set_get(
|
||||
const struct wlr_drm_format_set *set, uint32_t format);
|
||||
|
||||
|
|
@ -27,4 +63,13 @@ bool wlr_drm_format_set_has(const struct wlr_drm_format_set *set,
|
|||
bool wlr_drm_format_set_add(struct wlr_drm_format_set *set, uint32_t format,
|
||||
uint64_t modifier);
|
||||
|
||||
/**
|
||||
* Intersect two DRM format sets `a` and `b`, storing in the destination set
|
||||
* `dst` the format + modifier pairs which are in both source sets.
|
||||
*
|
||||
* Returns false on failure or when the intersection is empty.
|
||||
*/
|
||||
bool wlr_drm_format_set_intersect(struct wlr_drm_format_set *dst,
|
||||
const struct wlr_drm_format_set *a, const struct wlr_drm_format_set *b);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ struct wlr_egl {
|
|||
bool KHR_image_base;
|
||||
bool EXT_image_dma_buf_import;
|
||||
bool EXT_image_dma_buf_import_modifiers;
|
||||
bool IMG_context_priority;
|
||||
|
||||
// Device extensions
|
||||
bool EXT_device_drm;
|
||||
|
|
@ -64,10 +65,14 @@ struct wlr_egl {
|
|||
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
|
||||
} procs;
|
||||
|
||||
bool has_modifiers;
|
||||
struct wlr_drm_format_set dmabuf_texture_formats;
|
||||
struct wlr_drm_format_set dmabuf_render_formats;
|
||||
};
|
||||
|
||||
struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
||||
EGLContext context);
|
||||
|
||||
/**
|
||||
* Make the EGL context current.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ struct wlr_gles2_texture_attribs {
|
|||
GLenum target; /* either GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES */
|
||||
GLuint tex;
|
||||
|
||||
bool inverted_y;
|
||||
bool has_alpha;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -99,13 +99,19 @@ bool wlr_renderer_read_pixels(struct wlr_renderer *r, uint32_t fmt,
|
|||
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y, void *data);
|
||||
|
||||
/**
|
||||
* Creates necessary shm and invokes the initialization of the implementation.
|
||||
* Initializes wl_shm, linux-dmabuf and other buffer factory protocols.
|
||||
*
|
||||
* Returns false on failure.
|
||||
*/
|
||||
bool wlr_renderer_init_wl_display(struct wlr_renderer *r,
|
||||
struct wl_display *wl_display);
|
||||
|
||||
/**
|
||||
* Initializes wl_shm on the provided wl_display.
|
||||
*/
|
||||
bool wlr_renderer_init_wl_shm(struct wlr_renderer *r,
|
||||
struct wl_display *wl_display);
|
||||
|
||||
/**
|
||||
* Obtains the FD of the DRM device used for rendering, or -1 if unavailable.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -33,16 +33,6 @@ struct wlr_texture *wlr_texture_from_pixels(struct wlr_renderer *renderer,
|
|||
uint32_t fmt, uint32_t stride, uint32_t width, uint32_t height,
|
||||
const void *data);
|
||||
|
||||
/**
|
||||
* Create a new texture from a wl_drm resource. The returned texture is
|
||||
* immutable.
|
||||
*
|
||||
* Should not be called in a rendering block like renderer_begin()/end() or
|
||||
* between attaching a renderer to an output and committing it.
|
||||
*/
|
||||
struct wlr_texture *wlr_texture_from_wl_drm(struct wlr_renderer *renderer,
|
||||
struct wl_resource *data);
|
||||
|
||||
/**
|
||||
* Create a new texture from a DMA-BUF. The returned texture is immutable.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef WLR_TYPES_WLR_BOX_H
|
||||
#define WLR_TYPES_WLR_BOX_H
|
||||
|
||||
#warning "wlr_box has been moved to wlr/util/box.h"
|
||||
#include <wlr/util/box.h>
|
||||
|
||||
#endif
|
||||
|
|
@ -9,21 +9,167 @@
|
|||
#ifndef WLR_TYPES_WLR_COMPOSITOR_H
|
||||
#define WLR_TYPES_WLR_COMPOSITOR_H
|
||||
|
||||
#include <pixman.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/util/addon.h>
|
||||
#include <wlr/util/box.h>
|
||||
|
||||
struct wlr_surface;
|
||||
|
||||
struct wlr_subcompositor {
|
||||
struct wl_global *global;
|
||||
enum wlr_surface_state_field {
|
||||
WLR_SURFACE_STATE_BUFFER = 1 << 0,
|
||||
WLR_SURFACE_STATE_SURFACE_DAMAGE = 1 << 1,
|
||||
WLR_SURFACE_STATE_BUFFER_DAMAGE = 1 << 2,
|
||||
WLR_SURFACE_STATE_OPAQUE_REGION = 1 << 3,
|
||||
WLR_SURFACE_STATE_INPUT_REGION = 1 << 4,
|
||||
WLR_SURFACE_STATE_TRANSFORM = 1 << 5,
|
||||
WLR_SURFACE_STATE_SCALE = 1 << 6,
|
||||
WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7,
|
||||
WLR_SURFACE_STATE_VIEWPORT = 1 << 8,
|
||||
};
|
||||
|
||||
struct wlr_surface_state {
|
||||
uint32_t committed; // enum wlr_surface_state_field
|
||||
// Sequence number of the surface state. Incremented on each commit, may
|
||||
// overflow.
|
||||
uint32_t seq;
|
||||
|
||||
struct wlr_buffer *buffer;
|
||||
int32_t dx, dy; // relative to previous position
|
||||
pixman_region32_t surface_damage, buffer_damage; // clipped to bounds
|
||||
pixman_region32_t opaque, input;
|
||||
enum wl_output_transform transform;
|
||||
int32_t scale;
|
||||
struct wl_list frame_callback_list; // wl_resource
|
||||
|
||||
int width, height; // in surface-local coordinates
|
||||
int buffer_width, buffer_height;
|
||||
|
||||
struct wl_list subsurfaces_below;
|
||||
struct wl_list subsurfaces_above;
|
||||
|
||||
/**
|
||||
* The viewport is applied after the surface transform and scale.
|
||||
*
|
||||
* If has_src is true, the surface content is cropped to the provided
|
||||
* rectangle. If has_dst is true, the surface content is scaled to the
|
||||
* provided rectangle.
|
||||
*/
|
||||
struct {
|
||||
bool has_src, has_dst;
|
||||
// In coordinates after scale/transform are applied, but before the
|
||||
// destination rectangle is applied
|
||||
struct wlr_fbox src;
|
||||
int dst_width, dst_height; // in surface-local coordinates
|
||||
} viewport;
|
||||
|
||||
// Number of locks that prevent this surface state from being committed.
|
||||
size_t cached_state_locks;
|
||||
struct wl_list cached_state_link; // wlr_surface.cached
|
||||
};
|
||||
|
||||
struct wlr_surface_role {
|
||||
const char *name;
|
||||
void (*commit)(struct wlr_surface *surface);
|
||||
void (*precommit)(struct wlr_surface *surface,
|
||||
const struct wlr_surface_state *state);
|
||||
};
|
||||
|
||||
struct wlr_surface_output {
|
||||
struct wlr_surface *surface;
|
||||
struct wlr_output *output;
|
||||
|
||||
struct wl_list link; // wlr_surface::current_outputs
|
||||
struct wl_listener bind;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct wlr_surface {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_renderer *renderer;
|
||||
/**
|
||||
* The surface's buffer, if any. A surface has an attached buffer when it
|
||||
* commits with a non-null buffer in its pending state. A surface will not
|
||||
* have a buffer if it has never committed one, has committed a null buffer,
|
||||
* or something went wrong with uploading the buffer.
|
||||
*/
|
||||
struct wlr_client_buffer *buffer;
|
||||
/**
|
||||
* The buffer position, in surface-local units.
|
||||
*/
|
||||
int sx, sy;
|
||||
/**
|
||||
* The last commit's buffer damage, in buffer-local coordinates. This
|
||||
* contains both the damage accumulated by the client via
|
||||
* `wlr_surface_state.surface_damage` and `wlr_surface_state.buffer_damage`.
|
||||
* If the buffer has been resized, the whole buffer is damaged.
|
||||
*
|
||||
* This region needs to be scaled and transformed into output coordinates,
|
||||
* just like the buffer's texture. In addition, if the buffer has shrunk the
|
||||
* old size needs to be damaged and if the buffer has moved the old and new
|
||||
* positions need to be damaged.
|
||||
*/
|
||||
pixman_region32_t buffer_damage;
|
||||
/**
|
||||
* The last commit's damage caused by surface and its subsurfaces'
|
||||
* movement, in surface-local coordinates.
|
||||
*/
|
||||
pixman_region32_t external_damage;
|
||||
/**
|
||||
* The current opaque region, in surface-local coordinates. It is clipped to
|
||||
* the surface bounds. If the surface's buffer is using a fully opaque
|
||||
* format, this is set to the whole surface.
|
||||
*/
|
||||
pixman_region32_t opaque_region;
|
||||
/**
|
||||
* The current input region, in surface-local coordinates. It is clipped to
|
||||
* the surface bounds.
|
||||
*/
|
||||
pixman_region32_t input_region;
|
||||
/**
|
||||
* `current` contains the current, committed surface state. `pending`
|
||||
* accumulates state changes from the client between commits and shouldn't
|
||||
* be accessed by the compositor directly.
|
||||
*/
|
||||
struct wlr_surface_state current, pending;
|
||||
|
||||
struct wl_list cached; // wlr_surface_state.cached_link
|
||||
|
||||
const struct wlr_surface_role *role; // the lifetime-bound role or NULL
|
||||
void *role_data; // role-specific data
|
||||
|
||||
struct {
|
||||
struct wl_signal client_commit;
|
||||
struct wl_signal commit;
|
||||
struct wl_signal new_subsurface;
|
||||
struct wl_signal destroy;
|
||||
} events;
|
||||
|
||||
struct wl_list current_outputs; // wlr_surface_output::link
|
||||
|
||||
struct wlr_addon_set addons;
|
||||
void *data;
|
||||
|
||||
// private state
|
||||
|
||||
struct wl_listener renderer_destroy;
|
||||
|
||||
struct {
|
||||
int32_t scale;
|
||||
enum wl_output_transform transform;
|
||||
int width, height;
|
||||
int buffer_width, buffer_height;
|
||||
} previous;
|
||||
};
|
||||
|
||||
struct wlr_renderer;
|
||||
|
||||
struct wlr_compositor {
|
||||
struct wl_global *global;
|
||||
struct wlr_renderer *renderer;
|
||||
|
||||
struct wlr_subcompositor subcompositor;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
struct {
|
||||
|
|
@ -32,16 +178,125 @@ struct wlr_compositor {
|
|||
} events;
|
||||
};
|
||||
|
||||
typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface,
|
||||
int sx, int sy, void *data);
|
||||
|
||||
/**
|
||||
* Set the lifetime role for this surface. Returns 0 on success or -1 if the
|
||||
* role cannot be set.
|
||||
*/
|
||||
bool wlr_surface_set_role(struct wlr_surface *surface,
|
||||
const struct wlr_surface_role *role, void *role_data,
|
||||
struct wl_resource *error_resource, uint32_t error_code);
|
||||
|
||||
/**
|
||||
* Whether or not this surface currently has an attached buffer. A surface has
|
||||
* an attached buffer when it commits with a non-null buffer in its pending
|
||||
* state. A surface will not have a buffer if it has never committed one, has
|
||||
* committed a null buffer, or something went wrong with uploading the buffer.
|
||||
*/
|
||||
bool wlr_surface_has_buffer(struct wlr_surface *surface);
|
||||
|
||||
/**
|
||||
* Get the texture of the buffer currently attached to this surface. Returns
|
||||
* NULL if no buffer is currently attached or if something went wrong with
|
||||
* uploading the buffer.
|
||||
*/
|
||||
struct wlr_texture *wlr_surface_get_texture(struct wlr_surface *surface);
|
||||
|
||||
/**
|
||||
* Get the root of the subsurface tree for this surface. Can return NULL if
|
||||
* a surface in the tree has been destroyed.
|
||||
*/
|
||||
struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface);
|
||||
|
||||
/**
|
||||
* Check if the surface accepts input events at the given surface-local
|
||||
* coordinates. Does not check the surface's subsurfaces.
|
||||
*/
|
||||
bool wlr_surface_point_accepts_input(struct wlr_surface *surface,
|
||||
double sx, double sy);
|
||||
|
||||
/**
|
||||
* Find a surface in this surface's tree that accepts input events and has all
|
||||
* parents mapped (except this surface, which can be unmapped) at the given
|
||||
* surface-local coordinates. Returns the surface and coordinates in the leaf
|
||||
* surface coordinate system or NULL if no surface is found at that location.
|
||||
*/
|
||||
struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface,
|
||||
double sx, double sy, double *sub_x, double *sub_y);
|
||||
|
||||
void wlr_surface_send_enter(struct wlr_surface *surface,
|
||||
struct wlr_output *output);
|
||||
|
||||
void wlr_surface_send_leave(struct wlr_surface *surface,
|
||||
struct wlr_output *output);
|
||||
|
||||
void wlr_surface_send_frame_done(struct wlr_surface *surface,
|
||||
const struct timespec *when);
|
||||
|
||||
/**
|
||||
* Get the bounding box that contains the surface and all subsurfaces in
|
||||
* surface coordinates.
|
||||
* X and y may be negative, if there are subsurfaces with negative position.
|
||||
*/
|
||||
void wlr_surface_get_extends(struct wlr_surface *surface, struct wlr_box *box);
|
||||
|
||||
/**
|
||||
* Get the wlr_surface corresponding to a wl_surface resource. This asserts
|
||||
* that the resource is a valid wl_surface resource created by wlroots and
|
||||
* will never return NULL.
|
||||
*/
|
||||
struct wlr_surface *wlr_surface_from_resource(struct wl_resource *resource);
|
||||
|
||||
/**
|
||||
* Call `iterator` on each mapped surface in the surface tree (whether or not
|
||||
* this surface is mapped), with the surface's position relative to the root
|
||||
* surface. The function is called from root to leaves (in rendering order).
|
||||
*/
|
||||
void wlr_surface_for_each_surface(struct wlr_surface *surface,
|
||||
wlr_surface_iterator_func_t iterator, void *user_data);
|
||||
|
||||
/**
|
||||
* Get the effective surface damage in surface-local coordinate space. Besides
|
||||
* buffer damage, this includes damage induced by resizing and moving the
|
||||
* surface and its subsurfaces. The resulting damage is not expected to be
|
||||
* bounded by the surface itself.
|
||||
*/
|
||||
void wlr_surface_get_effective_damage(struct wlr_surface *surface,
|
||||
pixman_region32_t *damage);
|
||||
|
||||
/**
|
||||
* Get the source rectangle describing the region of the buffer that needs to
|
||||
* be sampled to render this surface's current state. The box is in
|
||||
* buffer-local coordinates.
|
||||
*
|
||||
* If the viewport's source rectangle is unset, the position is zero and the
|
||||
* size is the buffer's.
|
||||
*/
|
||||
void wlr_surface_get_buffer_source_box(struct wlr_surface *surface,
|
||||
struct wlr_fbox *box);
|
||||
|
||||
/**
|
||||
* Acquire a lock for the pending surface state.
|
||||
*
|
||||
* The state won't be committed before the caller releases the lock. Instead,
|
||||
* the state becomes cached. The caller needs to use wlr_surface_unlock_cached
|
||||
* to release the lock.
|
||||
*
|
||||
* Returns a surface commit sequence number for the cached state.
|
||||
*/
|
||||
uint32_t wlr_surface_lock_pending(struct wlr_surface *surface);
|
||||
|
||||
/**
|
||||
* Release a lock for a cached state.
|
||||
*
|
||||
* Callers should not assume that the cached state will immediately be
|
||||
* committed. Another caller may still have an active lock.
|
||||
*/
|
||||
void wlr_surface_unlock_cached(struct wlr_surface *surface, uint32_t seq);
|
||||
|
||||
struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
|
||||
struct wlr_renderer *renderer);
|
||||
|
||||
bool wlr_surface_is_subsurface(struct wlr_surface *surface);
|
||||
|
||||
/**
|
||||
* Get a subsurface from a surface. Can return NULL if the subsurface has been
|
||||
* destroyed.
|
||||
*/
|
||||
struct wlr_subsurface *wlr_subsurface_from_wlr_surface(
|
||||
struct wlr_surface *surface);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -192,13 +192,13 @@ void wlr_cursor_map_input_to_output(struct wlr_cursor *cur,
|
|||
/**
|
||||
* Maps this cursor to an arbitrary region on the associated wlr_output_layout.
|
||||
*/
|
||||
void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_box *box);
|
||||
void wlr_cursor_map_to_region(struct wlr_cursor *cur, const struct wlr_box *box);
|
||||
|
||||
/**
|
||||
* Maps inputs from this input device to an arbitrary region on the associated
|
||||
* wlr_output_layout.
|
||||
*/
|
||||
void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
|
||||
struct wlr_input_device *dev, struct wlr_box *box);
|
||||
struct wlr_input_device *dev, const struct wlr_box *box);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -81,16 +81,17 @@ struct wlr_drm_lease_request_v1 {
|
|||
|
||||
struct wlr_drm_lease_v1 {
|
||||
struct wl_resource *resource;
|
||||
struct wlr_drm_lease *drm_lease;
|
||||
|
||||
struct wlr_drm_lease_device_v1 *device;
|
||||
|
||||
struct wlr_drm_lease_connector_v1 **connectors;
|
||||
size_t n_connectors;
|
||||
|
||||
uint32_t lessee_id;
|
||||
|
||||
struct wl_list link; // wlr_drm_lease_device_v1::leases
|
||||
|
||||
struct wl_listener destroy;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,10 +36,13 @@ enum wlr_foreign_toplevel_handle_v1_state {
|
|||
|
||||
struct wlr_foreign_toplevel_handle_v1_output {
|
||||
struct wl_list link; // wlr_foreign_toplevel_handle_v1::outputs
|
||||
struct wl_listener output_destroy;
|
||||
struct wlr_output *output;
|
||||
|
||||
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
||||
|
||||
// private state
|
||||
|
||||
struct wl_listener output_bind;
|
||||
struct wl_listener output_destroy;
|
||||
};
|
||||
|
||||
struct wlr_foreign_toplevel_handle_v1 {
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ enum wlr_input_device_type {
|
|||
struct wlr_input_device_impl;
|
||||
|
||||
struct wlr_input_device {
|
||||
const struct wlr_input_device_impl *impl;
|
||||
|
||||
enum wlr_input_device_type type;
|
||||
unsigned int vendor, product;
|
||||
char *name;
|
||||
|
|
@ -53,8 +51,21 @@ struct wlr_input_device {
|
|||
} events;
|
||||
|
||||
void *data;
|
||||
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
void wlr_input_device_init(struct wlr_input_device *wlr_device,
|
||||
enum wlr_input_device_type type, const char *name);
|
||||
|
||||
/**
|
||||
* Clean up all of the provided wlr_input_device resources
|
||||
*/
|
||||
void wlr_input_device_finish(struct wlr_input_device *wlr_device);
|
||||
|
||||
/**
|
||||
* Calls the specialized input device destroy function.
|
||||
* If the wlr_input_device is not owned by a specialized input device, the
|
||||
* function will finish the wlr_input_device and free it.
|
||||
*/
|
||||
void wlr_input_device_destroy(struct wlr_input_device *dev);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <stdint.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wayland-server-protocol.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#define WLR_LED_COUNT 3
|
||||
|
|
@ -48,6 +49,8 @@ struct wlr_keyboard_modifiers {
|
|||
};
|
||||
|
||||
struct wlr_keyboard {
|
||||
struct wlr_input_device base;
|
||||
|
||||
const struct wlr_keyboard_impl *impl;
|
||||
struct wlr_keyboard_group *group;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,9 @@
|
|||
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
|
||||
struct wlr_keyboard_group {
|
||||
struct wlr_keyboard keyboard;
|
||||
struct wlr_input_device *input_device;
|
||||
struct wl_list devices; // keyboard_group_device::link
|
||||
struct wl_list keys; // keyboard_group_key::link
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include "wlr-layer-shell-unstable-v1-protocol.h"
|
||||
|
||||
/**
|
||||
|
|
@ -58,7 +58,7 @@ struct wlr_layer_surface_v1_state {
|
|||
uint32_t anchor;
|
||||
int32_t exclusive_zone;
|
||||
struct {
|
||||
uint32_t top, right, bottom, left;
|
||||
int32_t top, right, bottom, left;
|
||||
} margin;
|
||||
enum zwlr_layer_surface_v1_keyboard_interactivity keyboard_interactive;
|
||||
uint32_t desired_width, desired_height;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue