mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-25 06:47:03 -04:00
Merge gitlab.freedesktop.org:wlroots/wlroots
This commit is contained in:
commit
26f6fab4eb
275 changed files with 7472 additions and 5463 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -1,9 +1 @@
|
||||||
.clang_complete
|
/subprojects/
|
||||||
*.o
|
|
||||||
*.a
|
|
||||||
bin/
|
|
||||||
test/
|
|
||||||
build/
|
|
||||||
build-*/
|
|
||||||
wayland-*-protocol.*
|
|
||||||
wlr-example.ini
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ If you already have your own merge request habits, feel free to use them. If you
|
||||||
don't, however, allow me to make a suggestion: feature branches pulled from
|
don't, however, allow me to make a suggestion: feature branches pulled from
|
||||||
upstream. Try this:
|
upstream. Try this:
|
||||||
|
|
||||||
1. Fork wlroots
|
1. Fork wlroots (make the fork public to allow the CI to run)
|
||||||
2. `git clone git@gitlab.freedesktop.org:<username>/wlroots.git && cd wlroots`
|
2. `git clone git@gitlab.freedesktop.org:<username>/wlroots.git && cd wlroots`
|
||||||
3. `git remote add upstream https://gitlab.freedesktop.org/wlroots/wlroots.git`
|
3. `git remote add upstream https://gitlab.freedesktop.org/wlroots/wlroots.git`
|
||||||
|
|
||||||
|
|
@ -167,7 +167,6 @@ if (condition1 && condition2 && ...
|
||||||
|
|
||||||
Try to break the line in the place which you think is the most appropriate.
|
Try to break the line in the place which you think is the most appropriate.
|
||||||
|
|
||||||
|
|
||||||
### Line Length
|
### Line Length
|
||||||
|
|
||||||
Try to keep your lines under 80 columns, but you can go up to 100 if it
|
Try to keep your lines under 80 columns, but you can go up to 100 if it
|
||||||
|
|
@ -190,16 +189,18 @@ Functions that are responsible for constructing objects should take one of the
|
||||||
two following forms:
|
two following forms:
|
||||||
|
|
||||||
* `init`: for functions which accept a pointer to a pre-allocated object (e.g.
|
* `init`: for functions which accept a pointer to a pre-allocated object (e.g.
|
||||||
a member of a struct) and initialize it.
|
a member of a struct) and initialize it. Such functions must call `memset()`
|
||||||
|
to zero out the memory before initializing it to avoid leaving unset fields.
|
||||||
* `create`: for functions which allocate the memory for an object, initialize
|
* `create`: for functions which allocate the memory for an object, initialize
|
||||||
it, and return a pointer.
|
it, and return a pointer. Such functions should allocate the memory with
|
||||||
|
`calloc()` to avoid leaving unset fields.
|
||||||
|
|
||||||
Likewise, functions that are responsible for destructing objects should take
|
Likewise, functions that are responsible for destructing objects should take
|
||||||
one of the two following forms:
|
one of the two following forms:
|
||||||
|
|
||||||
* `finish`: for functions which accept a pointer to an object and deinitialize
|
* `finish`: for functions which accept a pointer to an object and deinitialize
|
||||||
it. Such functions should always be able to accept an already deinitialized
|
it. If a finished object isn't destroyed but kept for future use, it must be
|
||||||
object.
|
reinitialized to be used again.
|
||||||
* `destroy`: for functions which accept a pointer to an object, deinitialize
|
* `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
|
it, and free the memory. Such functions should always be able to accept a NULL
|
||||||
pointer.
|
pointer.
|
||||||
|
|
@ -215,6 +216,19 @@ Try to keep the use of macros to a minimum, especially if a function can do the
|
||||||
job. If you do need to use them, try to keep them close to where they're being
|
job. If you do need to use them, try to keep them close to where they're being
|
||||||
used and `#undef` them after.
|
used and `#undef` them after.
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
* Documentation comments for declarations start with `/**` and end with `*/`.
|
||||||
|
* Cross-reference other declarations by ending function names with `()`, and
|
||||||
|
writing `struct`, `union`, `enum` or `typedef` before types.
|
||||||
|
* Document fields which can be NULL with a `// may be NULL` comment, optionally
|
||||||
|
with more details describing when this can happen.
|
||||||
|
* Document the bits of a bitfield with a `// enum bar` comment.
|
||||||
|
* Document the `data` argument of a `struct wl_signal` with a `// struct foo`
|
||||||
|
comment.
|
||||||
|
* Document the contents and container of a `struct wl_list` with a
|
||||||
|
`// content.link` and `// container.list` comment.
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ Install dependencies:
|
||||||
* EGL and GLESv2 (optional, for the GLES2 renderer)
|
* EGL and GLESv2 (optional, for the GLES2 renderer)
|
||||||
* Vulkan loader, headers and glslang (optional, for the Vulkan renderer)
|
* Vulkan loader, headers and glslang (optional, for the Vulkan renderer)
|
||||||
* libdrm
|
* libdrm
|
||||||
* GBM
|
* GBM (optional, for the GBM allocator)
|
||||||
* libinput (optional, for the libinput backend)
|
* libinput (optional, for the libinput backend)
|
||||||
* xkbcommon
|
* xkbcommon
|
||||||
* udev
|
* udev
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
#include "backend/backend.h"
|
#include "backend/backend.h"
|
||||||
#include "backend/multi.h"
|
#include "backend/multi.h"
|
||||||
#include "render/allocator/allocator.h"
|
#include "render/allocator/allocator.h"
|
||||||
#include "util/signal.h"
|
#include "util/env.h"
|
||||||
|
|
||||||
#if WLR_HAS_DRM_BACKEND
|
#if WLR_HAS_DRM_BACKEND
|
||||||
#include <wlr/backend/drm.h>
|
#include <wlr/backend/drm.h>
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
void wlr_backend_init(struct wlr_backend *backend,
|
void wlr_backend_init(struct wlr_backend *backend,
|
||||||
const struct wlr_backend_impl *impl) {
|
const struct wlr_backend_impl *impl) {
|
||||||
assert(backend);
|
memset(backend, 0, sizeof(*backend));
|
||||||
backend->impl = impl;
|
backend->impl = impl;
|
||||||
wl_signal_init(&backend->events.destroy);
|
wl_signal_init(&backend->events.destroy);
|
||||||
wl_signal_init(&backend->events.new_input);
|
wl_signal_init(&backend->events.new_input);
|
||||||
|
|
@ -44,7 +44,7 @@ void wlr_backend_init(struct wlr_backend *backend,
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_backend_finish(struct wlr_backend *backend) {
|
void wlr_backend_finish(struct wlr_backend *backend) {
|
||||||
wlr_signal_emit_safe(&backend->events.destroy, backend);
|
wl_signal_emit_mutable(&backend->events.destroy, backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_backend_start(struct wlr_backend *backend) {
|
bool wlr_backend_start(struct wlr_backend *backend) {
|
||||||
|
|
@ -365,8 +365,7 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display) {
|
||||||
}
|
}
|
||||||
wlr_multi_backend_add(backend, libinput);
|
wlr_multi_backend_add(backend, libinput);
|
||||||
#else
|
#else
|
||||||
const char *no_devs = getenv("WLR_LIBINPUT_NO_DEVICES");
|
if (env_parse_bool("WLR_LIBINPUT_NO_DEVICES")) {
|
||||||
if (no_devs && strcmp(no_devs, "1") == 0) {
|
|
||||||
wlr_log(WLR_INFO, "WLR_LIBINPUT_NO_DEVICES is set, "
|
wlr_log(WLR_INFO, "WLR_LIBINPUT_NO_DEVICES is set, "
|
||||||
"starting without libinput backend");
|
"starting without libinput backend");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
|
@ -6,6 +8,41 @@
|
||||||
#include "backend/drm/iface.h"
|
#include "backend/drm/iface.h"
|
||||||
#include "backend/drm/util.h"
|
#include "backend/drm/util.h"
|
||||||
|
|
||||||
|
static char *atomic_commit_flags_str(uint32_t flags) {
|
||||||
|
const char *const l[] = {
|
||||||
|
(flags & DRM_MODE_PAGE_FLIP_EVENT) ? "PAGE_FLIP_EVENT" : NULL,
|
||||||
|
(flags & DRM_MODE_PAGE_FLIP_ASYNC) ? "PAGE_FLIP_ASYNC" : NULL,
|
||||||
|
(flags & DRM_MODE_ATOMIC_TEST_ONLY) ? "ATOMIC_TEST_ONLY" : NULL,
|
||||||
|
(flags & DRM_MODE_ATOMIC_NONBLOCK) ? "ATOMIC_NONBLOCK" : NULL,
|
||||||
|
(flags & DRM_MODE_ATOMIC_ALLOW_MODESET) ? "ATOMIC_ALLOW_MODESET" : NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
char *buf = NULL;
|
||||||
|
size_t size = 0;
|
||||||
|
FILE *f = open_memstream(&buf, &size);
|
||||||
|
if (f == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(l) / sizeof(l[0]); i++) {
|
||||||
|
if (l[i] == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ftell(f) > 0) {
|
||||||
|
fprintf(f, " | ");
|
||||||
|
}
|
||||||
|
fprintf(f, "%s", l[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftell(f) == 0) {
|
||||||
|
fprintf(f, "none");
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
struct atomic {
|
struct atomic {
|
||||||
drmModeAtomicReq *req;
|
drmModeAtomicReq *req;
|
||||||
bool failed;
|
bool failed;
|
||||||
|
|
@ -33,9 +70,11 @@ static bool atomic_commit(struct atomic *atom,
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
wlr_drm_conn_log_errno(conn,
|
wlr_drm_conn_log_errno(conn,
|
||||||
(flags & DRM_MODE_ATOMIC_TEST_ONLY) ? WLR_DEBUG : WLR_ERROR,
|
(flags & DRM_MODE_ATOMIC_TEST_ONLY) ? WLR_DEBUG : WLR_ERROR,
|
||||||
"Atomic %s failed (%s)",
|
"Atomic commit failed");
|
||||||
(flags & DRM_MODE_ATOMIC_TEST_ONLY) ? "test" : "commit",
|
char *flags_str = atomic_commit_flags_str(flags);
|
||||||
(flags & DRM_MODE_ATOMIC_ALLOW_MODESET) ? "modeset" : "pageflip");
|
wlr_log(WLR_DEBUG, "(Atomic commit flags: %s)",
|
||||||
|
flags_str ? flags_str : "<error>");
|
||||||
|
free(flags_str);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -217,8 +256,10 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
||||||
bool prev_vrr_enabled =
|
bool prev_vrr_enabled =
|
||||||
output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED;
|
output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED;
|
||||||
bool vrr_enabled = prev_vrr_enabled;
|
bool vrr_enabled = prev_vrr_enabled;
|
||||||
if ((state->base->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) &&
|
if ((state->base->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED)) {
|
||||||
drm_connector_supports_vrr(conn)) {
|
if (!drm_connector_supports_vrr(conn)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
vrr_enabled = state->base->adaptive_sync_enabled;
|
vrr_enabled = state->base->adaptive_sync_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,7 +268,12 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
||||||
}
|
}
|
||||||
if (modeset) {
|
if (modeset) {
|
||||||
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||||
} else if (!test_only) {
|
} else if (!test_only && (state->base->committed & WLR_OUTPUT_STATE_BUFFER)) {
|
||||||
|
// The wlr_output API requires non-modeset commits with a new buffer to
|
||||||
|
// wait for the frame event. However compositors often perform
|
||||||
|
// non-modesets commits without a new buffer without waiting for the
|
||||||
|
// frame event. In that case we need to make the KMS commit blocking,
|
||||||
|
// otherwise the kernel will error out with EBUSY.
|
||||||
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,6 +284,13 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
||||||
atomic_add(&atom, conn->id, conn->props.link_status,
|
atomic_add(&atom, conn->id, conn->props.link_status,
|
||||||
DRM_MODE_LINK_STATUS_GOOD);
|
DRM_MODE_LINK_STATUS_GOOD);
|
||||||
}
|
}
|
||||||
|
if (active && conn->props.content_type != 0) {
|
||||||
|
atomic_add(&atom, conn->id, conn->props.content_type,
|
||||||
|
DRM_MODE_CONTENT_TYPE_GRAPHICS);
|
||||||
|
}
|
||||||
|
if (active && conn->props.max_bpc != 0 && conn->max_bpc > 0) {
|
||||||
|
atomic_add(&atom, conn->id, conn->props.max_bpc, conn->max_bpc);
|
||||||
|
}
|
||||||
atomic_add(&atom, crtc->id, crtc->props.mode_id, mode_id);
|
atomic_add(&atom, crtc->id, crtc->props.mode_id, mode_id);
|
||||||
atomic_add(&atom, crtc->id, crtc->props.active, active);
|
atomic_add(&atom, crtc->id, crtc->props.active, active);
|
||||||
if (active) {
|
if (active) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
#include <libudev.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -12,7 +13,6 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include "backend/drm/drm.h"
|
#include "backend/drm/drm.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
struct wlr_drm_backend *get_drm_backend_from_backend(
|
struct wlr_drm_backend *get_drm_backend_from_backend(
|
||||||
struct wlr_backend *wlr_backend) {
|
struct wlr_backend *wlr_backend) {
|
||||||
|
|
@ -58,6 +58,7 @@ static void backend_destroy(struct wlr_backend *backend) {
|
||||||
|
|
||||||
finish_drm_resources(drm);
|
finish_drm_resources(drm);
|
||||||
|
|
||||||
|
udev_hwdb_unref(drm->hwdb);
|
||||||
free(drm->name);
|
free(drm->name);
|
||||||
wlr_session_close_file(drm->session, drm->dev);
|
wlr_session_close_file(drm->session, drm->dev);
|
||||||
wl_event_source_remove(drm->drm_event);
|
wl_event_source_remove(drm->drm_event);
|
||||||
|
|
@ -172,6 +173,23 @@ static void handle_parent_destroy(struct wl_listener *listener, void *data) {
|
||||||
backend_destroy(&drm->backend);
|
backend_destroy(&drm->backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct udev_hwdb *create_udev_hwdb(void) {
|
||||||
|
struct udev *udev = udev_new();
|
||||||
|
if (!udev) {
|
||||||
|
wlr_log(WLR_ERROR, "udev_new failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udev_hwdb *hwdb = udev_hwdb_new(udev);
|
||||||
|
udev_unref(udev);
|
||||||
|
if (!hwdb) {
|
||||||
|
wlr_log(WLR_ERROR, "udev_hwdb_new failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hwdb;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
||||||
struct wlr_session *session, struct wlr_device *dev,
|
struct wlr_session *session, struct wlr_device *dev,
|
||||||
struct wlr_backend *parent) {
|
struct wlr_backend *parent) {
|
||||||
|
|
@ -226,6 +244,12 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
||||||
drm->session_active.notify = handle_session_active;
|
drm->session_active.notify = handle_session_active;
|
||||||
wl_signal_add(&session->events.active, &drm->session_active);
|
wl_signal_add(&session->events.active, &drm->session_active);
|
||||||
|
|
||||||
|
drm->hwdb = create_udev_hwdb();
|
||||||
|
if (!drm->hwdb) {
|
||||||
|
wlr_log(WLR_INFO, "Failed to load udev_hwdb, "
|
||||||
|
"falling back to PnP IDs instead of manufacturer names");
|
||||||
|
}
|
||||||
|
|
||||||
if (!check_drm_features(drm)) {
|
if (!check_drm_features(drm)) {
|
||||||
goto error_event;
|
goto error_event;
|
||||||
}
|
}
|
||||||
|
|
@ -250,15 +274,17 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
||||||
goto error_mgpu_renderer;
|
goto error_mgpu_renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force a linear layout. In case explicit modifiers aren't supported,
|
// Forbid implicit modifiers, because their meaning changes from one
|
||||||
// the meaning of implicit modifiers changes from one GPU to the other.
|
// GPU to another.
|
||||||
// In case explicit modifiers are supported, we still have no guarantee
|
|
||||||
// that the buffer producer will support these, so they might fallback
|
|
||||||
// to implicit modifiers.
|
|
||||||
for (size_t i = 0; i < texture_formats->len; i++) {
|
for (size_t i = 0; i < texture_formats->len; i++) {
|
||||||
const struct wlr_drm_format *fmt = texture_formats->formats[i];
|
const struct wlr_drm_format *fmt = texture_formats->formats[i];
|
||||||
wlr_drm_format_set_add(&drm->mgpu_formats, fmt->format,
|
for (size_t j = 0; j < fmt->len; j++) {
|
||||||
DRM_FORMAT_MOD_LINEAR);
|
uint64_t mod = fmt->modifiers[j];
|
||||||
|
if (mod == DRM_FORMAT_MOD_INVALID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wlr_drm_format_set_add(&drm->mgpu_formats, fmt->format, mod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -275,6 +301,7 @@ error_mgpu_renderer:
|
||||||
error_resources:
|
error_resources:
|
||||||
finish_drm_resources(drm);
|
finish_drm_resources(drm);
|
||||||
error_event:
|
error_event:
|
||||||
|
udev_hwdb_unref(drm->hwdb);
|
||||||
wl_list_remove(&drm->session_active.link);
|
wl_list_remove(&drm->session_active.link);
|
||||||
wl_event_source_remove(drm->drm_event);
|
wl_event_source_remove(drm->drm_event);
|
||||||
error_fd:
|
error_fd:
|
||||||
|
|
|
||||||
|
|
@ -29,14 +29,18 @@
|
||||||
#include "render/drm_format_set.h"
|
#include "render/drm_format_set.h"
|
||||||
#include "render/swapchain.h"
|
#include "render/swapchain.h"
|
||||||
#include "render/wlr_renderer.h"
|
#include "render/wlr_renderer.h"
|
||||||
#include "util/signal.h"
|
#include "util/env.h"
|
||||||
|
|
||||||
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
// Output state which needs a KMS commit to be applied
|
||||||
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
|
static const uint32_t COMMIT_OUTPUT_STATE =
|
||||||
WLR_OUTPUT_STATE_BUFFER |
|
WLR_OUTPUT_STATE_BUFFER |
|
||||||
WLR_OUTPUT_STATE_MODE |
|
WLR_OUTPUT_STATE_MODE |
|
||||||
WLR_OUTPUT_STATE_ENABLED |
|
WLR_OUTPUT_STATE_ENABLED |
|
||||||
WLR_OUTPUT_STATE_GAMMA_LUT;
|
WLR_OUTPUT_STATE_GAMMA_LUT |
|
||||||
|
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED;
|
||||||
|
|
||||||
|
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
||||||
|
WLR_OUTPUT_STATE_BACKEND_OPTIONAL | COMMIT_OUTPUT_STATE;
|
||||||
|
|
||||||
bool check_drm_features(struct wlr_drm_backend *drm) {
|
bool check_drm_features(struct wlr_drm_backend *drm) {
|
||||||
if (drmGetCap(drm->fd, DRM_CAP_CURSOR_WIDTH, &drm->cursor_width)) {
|
if (drmGetCap(drm->fd, DRM_CAP_CURSOR_WIDTH, &drm->cursor_width)) {
|
||||||
|
|
@ -72,8 +76,7 @@ bool check_drm_features(struct wlr_drm_backend *drm) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *no_atomic = getenv("WLR_DRM_NO_ATOMIC");
|
if (env_parse_bool("WLR_DRM_NO_ATOMIC")) {
|
||||||
if (no_atomic && strcmp(no_atomic, "1") == 0) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
wlr_log(WLR_DEBUG,
|
||||||
"WLR_DRM_NO_ATOMIC set, forcing legacy DRM interface");
|
"WLR_DRM_NO_ATOMIC set, forcing legacy DRM interface");
|
||||||
drm->iface = &legacy_iface;
|
drm->iface = &legacy_iface;
|
||||||
|
|
@ -89,8 +92,7 @@ bool check_drm_features(struct wlr_drm_backend *drm) {
|
||||||
int ret = drmGetCap(drm->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
|
int ret = drmGetCap(drm->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
|
||||||
drm->clock = (ret == 0 && cap == 1) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
|
drm->clock = (ret == 0 && cap == 1) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
|
||||||
|
|
||||||
const char *no_modifiers = getenv("WLR_DRM_NO_MODIFIERS");
|
if (env_parse_bool("WLR_DRM_NO_MODIFIERS")) {
|
||||||
if (no_modifiers != NULL && strcmp(no_modifiers, "1") == 0) {
|
|
||||||
wlr_log(WLR_DEBUG, "WLR_DRM_NO_MODIFIERS set, disabling modifiers");
|
wlr_log(WLR_DEBUG, "WLR_DRM_NO_MODIFIERS set, disabling modifiers");
|
||||||
} else {
|
} else {
|
||||||
ret = drmGetCap(drm->fd, DRM_CAP_ADDFB2_MODIFIERS, &cap);
|
ret = drmGetCap(drm->fd, DRM_CAP_ADDFB2_MODIFIERS, &cap);
|
||||||
|
|
@ -380,6 +382,7 @@ static bool drm_crtc_page_flip(struct wlr_drm_connector *conn,
|
||||||
static void drm_connector_state_init(struct wlr_drm_connector_state *state,
|
static void drm_connector_state_init(struct wlr_drm_connector_state *state,
|
||||||
struct wlr_drm_connector *conn,
|
struct wlr_drm_connector *conn,
|
||||||
const struct wlr_output_state *base) {
|
const struct wlr_output_state *base) {
|
||||||
|
memset(state, 0, sizeof(*state));
|
||||||
state->base = base;
|
state->base = base;
|
||||||
state->modeset = base->committed &
|
state->modeset = base->committed &
|
||||||
(WLR_OUTPUT_STATE_ENABLED | WLR_OUTPUT_STATE_MODE);
|
(WLR_OUTPUT_STATE_ENABLED | WLR_OUTPUT_STATE_MODE);
|
||||||
|
|
@ -458,37 +461,48 @@ static bool drm_connector_set_pending_fb(struct wlr_drm_connector *conn,
|
||||||
|
|
||||||
static bool drm_connector_alloc_crtc(struct wlr_drm_connector *conn);
|
static bool drm_connector_alloc_crtc(struct wlr_drm_connector *conn);
|
||||||
|
|
||||||
static bool drm_connector_test(struct wlr_output *output) {
|
static bool drm_connector_test(struct wlr_output *output,
|
||||||
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
|
struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
|
||||||
|
|
||||||
if (!conn->backend->session->active) {
|
if (!conn->backend->session->active) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t unsupported = output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
|
uint32_t unsupported = state->committed & ~SUPPORTED_OUTPUT_STATE;
|
||||||
if (unsupported != 0) {
|
if (unsupported != 0) {
|
||||||
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
||||||
unsupported);
|
unsupported);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((output->pending.committed & WLR_OUTPUT_STATE_ENABLED) &&
|
if ((state->committed & COMMIT_OUTPUT_STATE) == 0) {
|
||||||
output->pending.enabled) {
|
// This commit doesn't change the KMS state
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((state->committed & WLR_OUTPUT_STATE_ENABLED) && state->enabled) {
|
||||||
if (output->current_mode == NULL &&
|
if (output->current_mode == NULL &&
|
||||||
!(output->pending.committed & WLR_OUTPUT_STATE_MODE)) {
|
!(state->committed & WLR_OUTPUT_STATE_MODE)) {
|
||||||
wlr_drm_conn_log(conn, WLR_DEBUG,
|
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||||
"Can't enable an output without a mode");
|
"Can't enable an output without a mode");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((state->committed & WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED) &&
|
||||||
|
state->adaptive_sync_enabled &&
|
||||||
|
!drm_connector_supports_vrr(conn)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_drm_connector_state pending = {0};
|
struct wlr_drm_connector_state pending = {0};
|
||||||
drm_connector_state_init(&pending, conn, &output->pending);
|
drm_connector_state_init(&pending, conn, state);
|
||||||
|
|
||||||
if (pending.active) {
|
if (pending.active) {
|
||||||
if ((output->pending.committed &
|
if ((state->committed &
|
||||||
(WLR_OUTPUT_STATE_ENABLED | WLR_OUTPUT_STATE_MODE)) &&
|
(WLR_OUTPUT_STATE_ENABLED | WLR_OUTPUT_STATE_MODE)) &&
|
||||||
!(output->pending.committed & WLR_OUTPUT_STATE_BUFFER)) {
|
!(state->committed & WLR_OUTPUT_STATE_BUFFER)) {
|
||||||
wlr_drm_conn_log(conn, WLR_DEBUG,
|
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||||
"Can't enable an output without a buffer");
|
"Can't enable an output without a buffer");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -513,7 +527,7 @@ static bool drm_connector_test(struct wlr_output *output) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||||
if (!drm_connector_set_pending_fb(conn, pending.base)) {
|
if (!drm_connector_set_pending_fb(conn, pending.base)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -559,6 +573,11 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((base->committed & COMMIT_OUTPUT_STATE) == 0) {
|
||||||
|
// This commit doesn't change the KMS state
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_drm_connector_state pending = {0};
|
struct wlr_drm_connector_state pending = {0};
|
||||||
drm_connector_state_init(&pending, conn, base);
|
drm_connector_state_init(&pending, conn, base);
|
||||||
|
|
||||||
|
|
@ -596,14 +615,15 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool drm_connector_commit(struct wlr_output *output) {
|
static bool drm_connector_commit(struct wlr_output *output,
|
||||||
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
|
struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
|
||||||
|
|
||||||
if (!drm_connector_test(output)) {
|
if (!drm_connector_test(output, state)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return drm_connector_commit_state(conn, &output->pending);
|
return drm_connector_commit_state(conn, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t drm_crtc_get_gamma_lut_size(struct wlr_drm_backend *drm,
|
size_t drm_crtc_get_gamma_lut_size(struct wlr_drm_backend *drm,
|
||||||
|
|
@ -692,8 +712,7 @@ static bool drm_connector_set_mode(struct wlr_drm_connector *conn,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->status != WLR_DRM_CONN_CONNECTED
|
if (conn->status != DRM_MODE_CONNECTED) {
|
||||||
&& conn->status != WLR_DRM_CONN_NEEDS_MODESET) {
|
|
||||||
wlr_drm_conn_log(conn, WLR_ERROR,
|
wlr_drm_conn_log(conn, WLR_ERROR,
|
||||||
"Cannot modeset a disconnected output");
|
"Cannot modeset a disconnected output");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -720,7 +739,6 @@ static bool drm_connector_set_mode(struct wlr_drm_connector *conn,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->status = WLR_DRM_CONN_CONNECTED;
|
|
||||||
wlr_output_update_mode(&conn->output, wlr_mode);
|
wlr_output_update_mode(&conn->output, wlr_mode);
|
||||||
wlr_output_update_enabled(&conn->output, true);
|
wlr_output_update_enabled(&conn->output, true);
|
||||||
conn->desired_enabled = true;
|
conn->desired_enabled = true;
|
||||||
|
|
@ -892,7 +910,7 @@ static void drm_connector_destroy_output(struct wlr_output *output) {
|
||||||
|
|
||||||
dealloc_crtc(conn);
|
dealloc_crtc(conn);
|
||||||
|
|
||||||
conn->status = WLR_DRM_CONN_DISCONNECTED;
|
conn->status = DRM_MODE_DISCONNECTED;
|
||||||
conn->desired_enabled = false;
|
conn->desired_enabled = false;
|
||||||
conn->possible_crtcs = 0;
|
conn->possible_crtcs = 0;
|
||||||
conn->pending_page_flip_crtc = 0;
|
conn->pending_page_flip_crtc = 0;
|
||||||
|
|
@ -1071,9 +1089,7 @@ static void realloc_crtcs(struct wlr_drm_backend *drm) {
|
||||||
|
|
||||||
// Only search CRTCs for user-enabled outputs (that are already
|
// Only search CRTCs for user-enabled outputs (that are already
|
||||||
// connected or in need of a modeset)
|
// connected or in need of a modeset)
|
||||||
if ((conn->status == WLR_DRM_CONN_CONNECTED ||
|
if (conn->status == DRM_MODE_CONNECTED && conn->desired_enabled) {
|
||||||
conn->status == WLR_DRM_CONN_NEEDS_MODESET) &&
|
|
||||||
conn->desired_enabled) {
|
|
||||||
connector_constraints[i] = conn->possible_crtcs;
|
connector_constraints[i] = conn->possible_crtcs;
|
||||||
} else {
|
} else {
|
||||||
// Will always fail to match anything
|
// Will always fail to match anything
|
||||||
|
|
@ -1104,8 +1120,7 @@ static void realloc_crtcs(struct wlr_drm_backend *drm) {
|
||||||
*/
|
*/
|
||||||
for (size_t i = 0; i < num_outputs; ++i) {
|
for (size_t i = 0; i < num_outputs; ++i) {
|
||||||
struct wlr_drm_connector *conn = connectors[i];
|
struct wlr_drm_connector *conn = connectors[i];
|
||||||
if (conn->status == WLR_DRM_CONN_CONNECTED &&
|
if (conn->status == DRM_MODE_CONNECTED && conn->output.enabled &&
|
||||||
conn->desired_enabled &&
|
|
||||||
connector_match[i] == -1) {
|
connector_match[i] == -1) {
|
||||||
wlr_log(WLR_DEBUG, "Could not match a CRTC for previously connected output; "
|
wlr_log(WLR_DEBUG, "Could not match a CRTC for previously connected output; "
|
||||||
"keeping old configuration");
|
"keeping old configuration");
|
||||||
|
|
@ -1132,7 +1147,6 @@ static void realloc_crtcs(struct wlr_drm_backend *drm) {
|
||||||
if (connector_match[i] == -1) {
|
if (connector_match[i] == -1) {
|
||||||
if (prev_enabled) {
|
if (prev_enabled) {
|
||||||
wlr_drm_conn_log(conn, WLR_DEBUG, "Output has lost its CRTC");
|
wlr_drm_conn_log(conn, WLR_DEBUG, "Output has lost its CRTC");
|
||||||
conn->status = WLR_DRM_CONN_NEEDS_MODESET;
|
|
||||||
wlr_output_update_enabled(&conn->output, false);
|
wlr_output_update_enabled(&conn->output, false);
|
||||||
wlr_output_update_mode(&conn->output, NULL);
|
wlr_output_update_mode(&conn->output, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -1142,42 +1156,17 @@ static void realloc_crtcs(struct wlr_drm_backend *drm) {
|
||||||
conn->crtc = &drm->crtcs[connector_match[i]];
|
conn->crtc = &drm->crtcs[connector_match[i]];
|
||||||
|
|
||||||
// Only realloc buffers if we have actually been modeset
|
// Only realloc buffers if we have actually been modeset
|
||||||
if (conn->status != WLR_DRM_CONN_CONNECTED) {
|
if (conn->status != DRM_MODE_CONNECTED || !conn->output.enabled) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
wlr_output_damage_whole(&conn->output);
|
wlr_output_damage_whole(&conn->output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t get_possible_crtcs(int fd, const drmModeConnector *conn) {
|
|
||||||
uint32_t possible_crtcs = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < conn->count_encoders; ++i) {
|
|
||||||
drmModeEncoder *enc = drmModeGetEncoder(fd, conn->encoders[i]);
|
|
||||||
if (!enc) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
possible_crtcs |= enc->possible_crtcs;
|
|
||||||
|
|
||||||
drmModeFreeEncoder(enc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return possible_crtcs;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disconnect_drm_connector(struct wlr_drm_connector *conn);
|
static void disconnect_drm_connector(struct wlr_drm_connector *conn);
|
||||||
|
|
||||||
void scan_drm_connectors(struct wlr_drm_backend *drm,
|
void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
struct wlr_device_hotplug_event *event) {
|
struct wlr_device_hotplug_event *event) {
|
||||||
/*
|
|
||||||
* This GPU is not really a modesetting device.
|
|
||||||
* It's just being used as a renderer.
|
|
||||||
*/
|
|
||||||
if (drm->num_crtcs == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event != NULL && event->connector_id != 0) {
|
if (event != NULL && event->connector_id != 0) {
|
||||||
wlr_log(WLR_INFO, "Scanning DRM connector %"PRIu32" on %s",
|
wlr_log(WLR_INFO, "Scanning DRM connector %"PRIu32" on %s",
|
||||||
event->connector_id, drm->name);
|
event->connector_id, drm->name);
|
||||||
|
|
@ -1240,12 +1229,17 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_conn->backend = drm;
|
wlr_conn->backend = drm;
|
||||||
wlr_conn->status = WLR_DRM_CONN_DISCONNECTED;
|
wlr_conn->status = DRM_MODE_DISCONNECTED;
|
||||||
wlr_conn->id = drm_conn->connector_id;
|
wlr_conn->id = drm_conn->connector_id;
|
||||||
|
|
||||||
|
const char *conn_name =
|
||||||
|
drmModeGetConnectorTypeName(drm_conn->connector_type);
|
||||||
|
if (conn_name == NULL) {
|
||||||
|
conn_name = "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(wlr_conn->name, sizeof(wlr_conn->name),
|
snprintf(wlr_conn->name, sizeof(wlr_conn->name),
|
||||||
"%s-%"PRIu32, conn_get_name(drm_conn->connector_type),
|
"%s-%"PRIu32, conn_name, drm_conn->connector_type_id);
|
||||||
drm_conn->connector_type_id);
|
|
||||||
|
|
||||||
wl_list_insert(drm->outputs.prev, &wlr_conn->link);
|
wl_list_insert(drm->outputs.prev, &wlr_conn->link);
|
||||||
wlr_log(WLR_INFO, "Found connector '%s'", wlr_conn->name);
|
wlr_log(WLR_INFO, "Found connector '%s'", wlr_conn->name);
|
||||||
|
|
@ -1282,7 +1276,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_conn->status == WLR_DRM_CONN_DISCONNECTED &&
|
if (wlr_conn->status == DRM_MODE_DISCONNECTED &&
|
||||||
drm_conn->connection == DRM_MODE_CONNECTED) {
|
drm_conn->connection == DRM_MODE_CONNECTED) {
|
||||||
wlr_log(WLR_INFO, "'%s' connected", wlr_conn->name);
|
wlr_log(WLR_INFO, "'%s' connected", wlr_conn->name);
|
||||||
wlr_log(WLR_DEBUG, "Current CRTC: %d",
|
wlr_log(WLR_DEBUG, "Current CRTC: %d",
|
||||||
|
|
@ -1310,16 +1304,24 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
wlr_conn->output.non_desktop = non_desktop;
|
wlr_conn->output.non_desktop = non_desktop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlr_conn->max_bpc = 0;
|
||||||
|
if (wlr_conn->props.max_bpc != 0) {
|
||||||
|
if (!introspect_drm_prop_range(drm->fd, wlr_conn->props.max_bpc,
|
||||||
|
NULL, &wlr_conn->max_bpc)) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to introspect 'max bpc' property");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t edid_len = 0;
|
size_t edid_len = 0;
|
||||||
uint8_t *edid = get_drm_prop_blob(drm->fd,
|
uint8_t *edid = get_drm_prop_blob(drm->fd,
|
||||||
wlr_conn->id, wlr_conn->props.edid, &edid_len);
|
wlr_conn->id, wlr_conn->props.edid, &edid_len);
|
||||||
parse_edid(&wlr_conn->output, edid_len, edid);
|
parse_edid(wlr_conn, edid_len, edid);
|
||||||
free(edid);
|
free(edid);
|
||||||
|
|
||||||
size_t tile_len = 0;
|
size_t tile_len = 0;
|
||||||
uint8_t *tile = get_drm_prop_blob(drm->fd,
|
uint8_t *tile = get_drm_prop_blob(drm->fd,
|
||||||
wlr_conn->id, wlr_conn->props.tile, &tile_len);
|
wlr_conn->id, wlr_conn->props.tile, &tile_len);
|
||||||
parse_tile(&wlr_conn->output, tile_len, tile);
|
parse_tile(wlr_conn, tile_len, tile);
|
||||||
free(tile);
|
free(tile);
|
||||||
|
|
||||||
char *subconnector = NULL;
|
char *subconnector = NULL;
|
||||||
|
|
@ -1334,9 +1336,13 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
|
|
||||||
struct wlr_output *output = &wlr_conn->output;
|
struct wlr_output *output = &wlr_conn->output;
|
||||||
char description[128];
|
char description[128];
|
||||||
snprintf(description, sizeof(description), "%s %s %s (%s%s%s)",
|
snprintf(description, sizeof(description), "%s %s%s%s (%s%s%s)",
|
||||||
output->make, output->model, output->serial, output->name,
|
output->make, output->model,
|
||||||
subconnector ? " via " : "", subconnector ? subconnector : "");
|
output->serial ? " " : "",
|
||||||
|
output->serial ? output->serial : "",
|
||||||
|
output->name,
|
||||||
|
subconnector ? " via " : "",
|
||||||
|
subconnector ? subconnector : "");
|
||||||
wlr_output_set_description(output, description);
|
wlr_output_set_description(output, description);
|
||||||
|
|
||||||
free(subconnector);
|
free(subconnector);
|
||||||
|
|
@ -1371,7 +1377,8 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
wl_list_insert(wlr_conn->output.modes.prev, &mode->wlr_mode.link);
|
wl_list_insert(wlr_conn->output.modes.prev, &mode->wlr_mode.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_conn->possible_crtcs = get_possible_crtcs(drm->fd, drm_conn);
|
wlr_conn->possible_crtcs =
|
||||||
|
drmModeConnectorGetPossibleCrtcs(drm->fd, drm_conn);
|
||||||
if (wlr_conn->possible_crtcs == 0) {
|
if (wlr_conn->possible_crtcs == 0) {
|
||||||
wlr_drm_conn_log(wlr_conn, WLR_ERROR, "No CRTC possible");
|
wlr_drm_conn_log(wlr_conn, WLR_ERROR, "No CRTC possible");
|
||||||
}
|
}
|
||||||
|
|
@ -1381,10 +1388,9 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
wlr_output_update_enabled(&wlr_conn->output, wlr_conn->crtc != NULL);
|
wlr_output_update_enabled(&wlr_conn->output, wlr_conn->crtc != NULL);
|
||||||
wlr_conn->desired_enabled = true;
|
wlr_conn->desired_enabled = true;
|
||||||
|
|
||||||
wlr_conn->status = WLR_DRM_CONN_NEEDS_MODESET;
|
wlr_conn->status = DRM_MODE_CONNECTED;
|
||||||
new_outputs[new_outputs_len++] = wlr_conn;
|
new_outputs[new_outputs_len++] = wlr_conn;
|
||||||
} else if ((wlr_conn->status == WLR_DRM_CONN_CONNECTED ||
|
} else if (wlr_conn->status == DRM_MODE_CONNECTED &&
|
||||||
wlr_conn->status == WLR_DRM_CONN_NEEDS_MODESET) &&
|
|
||||||
drm_conn->connection != DRM_MODE_CONNECTED) {
|
drm_conn->connection != DRM_MODE_CONNECTED) {
|
||||||
wlr_log(WLR_INFO, "'%s' disconnected", wlr_conn->name);
|
wlr_log(WLR_INFO, "'%s' disconnected", wlr_conn->name);
|
||||||
disconnect_drm_connector(wlr_conn);
|
disconnect_drm_connector(wlr_conn);
|
||||||
|
|
@ -1416,7 +1422,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_connector *conn = new_outputs[i];
|
struct wlr_drm_connector *conn = new_outputs[i];
|
||||||
|
|
||||||
wlr_drm_conn_log(conn, WLR_INFO, "Requesting modeset");
|
wlr_drm_conn_log(conn, WLR_INFO, "Requesting modeset");
|
||||||
wlr_signal_emit_safe(&drm->backend.events.new_output,
|
wl_signal_emit_mutable(&drm->backend.events.new_output,
|
||||||
&conn->output);
|
&conn->output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1474,7 +1480,7 @@ static void handle_page_flip(int fd, unsigned seq,
|
||||||
|
|
||||||
conn->pending_page_flip_crtc = 0;
|
conn->pending_page_flip_crtc = 0;
|
||||||
|
|
||||||
if (conn->status != WLR_DRM_CONN_CONNECTED || conn->crtc == NULL) {
|
if (conn->status != DRM_MODE_CONNECTED || conn->crtc == NULL) {
|
||||||
wlr_drm_conn_log(conn, WLR_DEBUG,
|
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||||
"Ignoring page-flip event for disabled connector");
|
"Ignoring page-flip event for disabled connector");
|
||||||
return;
|
return;
|
||||||
|
|
@ -1537,7 +1543,7 @@ int handle_drm_event(int fd, uint32_t mask, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disconnect_drm_connector(struct wlr_drm_connector *conn) {
|
static void disconnect_drm_connector(struct wlr_drm_connector *conn) {
|
||||||
if (conn->status == WLR_DRM_CONN_DISCONNECTED) {
|
if (conn->status == DRM_MODE_DISCONNECTED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1545,7 +1551,7 @@ static void disconnect_drm_connector(struct wlr_drm_connector *conn) {
|
||||||
// our wlr_drm_connector.
|
// our wlr_drm_connector.
|
||||||
wlr_output_destroy(&conn->output);
|
wlr_output_destroy(&conn->output);
|
||||||
|
|
||||||
assert(conn->status == WLR_DRM_CONN_DISCONNECTED);
|
assert(conn->status == DRM_MODE_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_drm_connector(struct wlr_drm_connector *conn) {
|
void destroy_drm_connector(struct wlr_drm_connector *conn) {
|
||||||
|
|
@ -1635,7 +1641,7 @@ struct wlr_drm_lease *wlr_drm_create_lease(struct wlr_output **outputs,
|
||||||
wl_signal_init(&lease->events.destroy);
|
wl_signal_init(&lease->events.destroy);
|
||||||
|
|
||||||
wlr_log(WLR_DEBUG, "Issuing DRM lease with %d objects", n_objects);
|
wlr_log(WLR_DEBUG, "Issuing DRM lease with %d objects", n_objects);
|
||||||
int lease_fd = drmModeCreateLease(drm->fd, objects, n_objects, 0,
|
int lease_fd = drmModeCreateLease(drm->fd, objects, n_objects, O_CLOEXEC,
|
||||||
&lease->lessee_id);
|
&lease->lessee_id);
|
||||||
if (lease_fd < 0) {
|
if (lease_fd < 0) {
|
||||||
free(lease);
|
free(lease);
|
||||||
|
|
@ -1669,7 +1675,7 @@ void wlr_drm_lease_terminate(struct wlr_drm_lease *lease) {
|
||||||
void drm_lease_destroy(struct wlr_drm_lease *lease) {
|
void drm_lease_destroy(struct wlr_drm_lease *lease) {
|
||||||
struct wlr_drm_backend *drm = lease->backend;
|
struct wlr_drm_backend *drm = lease->backend;
|
||||||
|
|
||||||
wlr_signal_emit_safe(&lease->events.destroy, NULL);
|
wl_signal_emit_mutable(&lease->events.destroy, NULL);
|
||||||
|
|
||||||
struct wlr_drm_connector *conn;
|
struct wlr_drm_connector *conn;
|
||||||
wl_list_for_each(conn, &drm->outputs, link) {
|
wl_list_for_each(conn, &drm->outputs, link) {
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,10 @@ static bool legacy_crtc_commit(struct wlr_drm_connector *conn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((state->base->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) &&
|
if (state->base->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) {
|
||||||
drm_connector_supports_vrr(conn)) {
|
if (!drm_connector_supports_vrr(conn)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (drmModeObjectSetProperty(drm->fd, crtc->id, DRM_MODE_OBJECT_CRTC,
|
if (drmModeObjectSetProperty(drm->fd, crtc->id, DRM_MODE_OBJECT_CRTC,
|
||||||
crtc->props.vrr_enabled,
|
crtc->props.vrr_enabled,
|
||||||
state->base->adaptive_sync_enabled) != 0) {
|
state->base->adaptive_sync_enabled) != 0) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
@ -25,7 +26,9 @@ static const struct prop_info connector_info[] = {
|
||||||
{ "EDID", INDEX(edid) },
|
{ "EDID", INDEX(edid) },
|
||||||
{ "PATH", INDEX(path) },
|
{ "PATH", INDEX(path) },
|
||||||
{ "TILE", INDEX(tile) },
|
{ "TILE", INDEX(tile) },
|
||||||
|
{ "content type", INDEX(content_type) },
|
||||||
{ "link-status", INDEX(link_status) },
|
{ "link-status", INDEX(link_status) },
|
||||||
|
{ "max bpc", INDEX(max_bpc) },
|
||||||
{ "non-desktop", INDEX(non_desktop) },
|
{ "non-desktop", INDEX(non_desktop) },
|
||||||
{ "panel orientation", INDEX(panel_orientation) },
|
{ "panel orientation", INDEX(panel_orientation) },
|
||||||
{ "subconnector", INDEX(subconnector) },
|
{ "subconnector", INDEX(subconnector) },
|
||||||
|
|
@ -181,3 +184,28 @@ char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop_id) {
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool introspect_drm_prop_range(int fd, uint32_t prop_id,
|
||||||
|
uint64_t *min, uint64_t *max) {
|
||||||
|
drmModePropertyRes *prop = drmModeGetProperty(fd, prop_id);
|
||||||
|
if (!prop) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drmModeGetPropertyType(prop) != DRM_MODE_PROP_RANGE) {
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(prop->count_values == 2);
|
||||||
|
|
||||||
|
if (min != NULL) {
|
||||||
|
*min = prop->values[0];
|
||||||
|
}
|
||||||
|
if (max != NULL) {
|
||||||
|
*max = prop->values[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,31 +48,6 @@ void finish_drm_renderer(struct wlr_drm_renderer *renderer) {
|
||||||
wlr_renderer_destroy(renderer->wlr_rend);
|
wlr_renderer_destroy(renderer->wlr_rend);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init_drm_surface(struct wlr_drm_surface *surf,
|
|
||||||
struct wlr_drm_renderer *renderer, uint32_t width, uint32_t height,
|
|
||||||
const struct wlr_drm_format *drm_format) {
|
|
||||||
if (surf->width == width && surf->height == height) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
surf->renderer = renderer;
|
|
||||||
surf->width = width;
|
|
||||||
surf->height = height;
|
|
||||||
|
|
||||||
wlr_swapchain_destroy(surf->swapchain);
|
|
||||||
surf->swapchain = NULL;
|
|
||||||
|
|
||||||
surf->swapchain = wlr_swapchain_create(renderer->allocator, width, height,
|
|
||||||
drm_format);
|
|
||||||
if (surf->swapchain == NULL) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to create swapchain");
|
|
||||||
memset(surf, 0, sizeof(*surf));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void finish_drm_surface(struct wlr_drm_surface *surf) {
|
static void finish_drm_surface(struct wlr_drm_surface *surf) {
|
||||||
if (!surf || !surf->renderer) {
|
if (!surf || !surf->renderer) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -83,12 +58,34 @@ static void finish_drm_surface(struct wlr_drm_surface *surf) {
|
||||||
memset(surf, 0, sizeof(*surf));
|
memset(surf, 0, sizeof(*surf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool init_drm_surface(struct wlr_drm_surface *surf,
|
||||||
|
struct wlr_drm_renderer *renderer, int width, int height,
|
||||||
|
const struct wlr_drm_format *drm_format) {
|
||||||
|
if (surf->swapchain != NULL && surf->swapchain->width == width &&
|
||||||
|
surf->swapchain->height == height) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_drm_surface(surf);
|
||||||
|
|
||||||
|
surf->swapchain = wlr_swapchain_create(renderer->allocator, width, height,
|
||||||
|
drm_format);
|
||||||
|
if (surf->swapchain == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create swapchain");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
surf->renderer = renderer;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf,
|
struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf,
|
||||||
struct wlr_buffer *buffer) {
|
struct wlr_buffer *buffer) {
|
||||||
struct wlr_renderer *renderer = surf->renderer->wlr_rend;
|
struct wlr_renderer *renderer = surf->renderer->wlr_rend;
|
||||||
|
|
||||||
if (surf->width != (uint32_t)buffer->width ||
|
if (surf->swapchain->width != buffer->width ||
|
||||||
surf->height != (uint32_t)buffer->height) {
|
surf->swapchain->height != buffer->height) {
|
||||||
wlr_log(WLR_ERROR, "Surface size doesn't match buffer size");
|
wlr_log(WLR_ERROR, "Surface size doesn't match buffer size");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +103,7 @@ struct wlr_buffer *drm_surface_blit(struct wlr_drm_surface *surf,
|
||||||
|
|
||||||
float mat[9];
|
float mat[9];
|
||||||
wlr_matrix_identity(mat);
|
wlr_matrix_identity(mat);
|
||||||
wlr_matrix_scale(mat, surf->width, surf->height);
|
wlr_matrix_scale(mat, surf->swapchain->width, surf->swapchain->height);
|
||||||
|
|
||||||
if (!wlr_renderer_begin_with_buffer(renderer, dst)) {
|
if (!wlr_renderer_begin_with_buffer(renderer, dst)) {
|
||||||
wlr_buffer_unlock(dst);
|
wlr_buffer_unlock(dst);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
#include <drm_mode.h>
|
#include <drm_mode.h>
|
||||||
#include <drm.h>
|
#include <drm.h>
|
||||||
|
#include <libudev.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
#include "backend/drm/drm.h"
|
||||||
#include "backend/drm/util.h"
|
#include "backend/drm/util.h"
|
||||||
|
|
||||||
int32_t calculate_refresh_rate(const drmModeModeInfo *mode) {
|
int32_t calculate_refresh_rate(const drmModeModeInfo *mode) {
|
||||||
|
|
@ -26,125 +30,93 @@ int32_t calculate_refresh_rate(const drmModeModeInfo *mode) {
|
||||||
return refresh;
|
return refresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructed from http://edid.tv/manufacturer
|
static const char *get_manufacturer(struct udev_hwdb *hwdb, uint16_t code) {
|
||||||
static const char *get_manufacturer(uint16_t id) {
|
static char pnp_id[4];
|
||||||
#define ID(a, b, c) ((a & 0x1f) << 10) | ((b & 0x1f) << 5) | (c & 0x1f)
|
|
||||||
switch (id) {
|
// The ASCII 3-letter manufacturer PnP ID is encoded in 5-bit codes
|
||||||
case ID('A', 'A', 'A'): return "Avolites Ltd";
|
pnp_id[0] = ((code >> 10) & 0x1F) + '@';
|
||||||
case ID('A', 'C', 'I'): return "Ancor Communications Inc";
|
pnp_id[1] = ((code >> 5) & 0x1F) + '@';
|
||||||
case ID('A', 'C', 'R'): return "Acer Technologies";
|
pnp_id[2] = ((code >> 0) & 0x1F) + '@';
|
||||||
case ID('A', 'D', 'A'): return "Addi-Data GmbH";
|
pnp_id[3] = '\0';
|
||||||
case ID('A', 'P', 'P'): return "Apple Computer Inc";
|
|
||||||
case ID('A', 'S', 'K'): return "Ask A/S";
|
if (hwdb == NULL) {
|
||||||
case ID('A', 'V', 'T'): return "Avtek (Electronics) Pty Ltd";
|
return pnp_id;
|
||||||
case ID('B', 'N', 'O'): return "Bang & Olufsen";
|
|
||||||
case ID('B', 'N', 'Q'): return "BenQ Corporation";
|
|
||||||
case ID('C', 'M', 'N'): return "Chimei Innolux Corporation";
|
|
||||||
case ID('C', 'M', 'O'): return "Chi Mei Optoelectronics corp.";
|
|
||||||
case ID('C', 'R', 'O'): return "Extraordinary Technologies PTY Limited";
|
|
||||||
case ID('D', 'E', 'L'): return "Dell Inc.";
|
|
||||||
case ID('D', 'G', 'C'): return "Data General Corporation";
|
|
||||||
case ID('D', 'O', 'N'): return "DENON, Ltd.";
|
|
||||||
case ID('E', 'N', 'C'): return "Eizo Nanao Corporation";
|
|
||||||
case ID('E', 'P', 'H'): return "Epiphan Systems Inc.";
|
|
||||||
case ID('E', 'X', 'P'): return "Data Export Corporation";
|
|
||||||
case ID('F', 'N', 'I'): return "Funai Electric Co., Ltd.";
|
|
||||||
case ID('F', 'U', 'S'): return "Fujitsu Siemens Computers GmbH";
|
|
||||||
case ID('G', 'S', 'M'): return "Goldstar Company Ltd";
|
|
||||||
case ID('H', 'I', 'Q'): return "Kaohsiung Opto Electronics Americas, Inc.";
|
|
||||||
case ID('H', 'S', 'D'): return "HannStar Display Corp";
|
|
||||||
case ID('H', 'T', 'C'): return "Hitachi Ltd";
|
|
||||||
case ID('H', 'W', 'P'): return "Hewlett Packard";
|
|
||||||
case ID('I', 'N', 'T'): return "Interphase Corporation";
|
|
||||||
case ID('I', 'N', 'X'): return "Communications Supply Corporation (A division of WESCO)";
|
|
||||||
case ID('I', 'T', 'E'): return "Integrated Tech Express Inc";
|
|
||||||
case ID('I', 'V', 'M'): return "Iiyama North America";
|
|
||||||
case ID('L', 'E', 'N'): return "Lenovo Group Limited";
|
|
||||||
case ID('M', 'A', 'X'): return "Rogen Tech Distribution Inc";
|
|
||||||
case ID('M', 'E', 'G'): return "Abeam Tech Ltd";
|
|
||||||
case ID('M', 'E', 'I'): return "Panasonic Industry Company";
|
|
||||||
case ID('M', 'T', 'C'): return "Mars-Tech Corporation";
|
|
||||||
case ID('M', 'T', 'X'): return "Matrox";
|
|
||||||
case ID('N', 'E', 'C'): return "NEC Corporation";
|
|
||||||
case ID('N', 'E', 'X'): return "Nexgen Mediatech Inc.";
|
|
||||||
case ID('O', 'N', 'K'): return "ONKYO Corporation";
|
|
||||||
case ID('O', 'R', 'N'): return "ORION ELECTRIC CO., LTD.";
|
|
||||||
case ID('O', 'T', 'M'): return "Optoma Corporation";
|
|
||||||
case ID('O', 'V', 'R'): return "Oculus VR, Inc.";
|
|
||||||
case ID('P', 'H', 'L'): return "Philips Consumer Electronics Company";
|
|
||||||
case ID('P', 'I', 'O'): return "Pioneer Electronic Corporation";
|
|
||||||
case ID('P', 'N', 'R'): return "Planar Systems, Inc.";
|
|
||||||
case ID('Q', 'D', 'S'): return "Quanta Display Inc.";
|
|
||||||
case ID('R', 'A', 'T'): return "Rent-A-Tech";
|
|
||||||
case ID('R', 'E', 'N'): return "Renesas Technology Corp.";
|
|
||||||
case ID('S', 'A', 'M'): return "Samsung Electric Company";
|
|
||||||
case ID('S', 'A', 'N'): return "Sanyo Electric Co., Ltd.";
|
|
||||||
case ID('S', 'E', 'C'): return "Seiko Epson Corporation";
|
|
||||||
case ID('S', 'H', 'P'): return "Sharp Corporation";
|
|
||||||
case ID('S', 'I', 'I'): return "Silicon Image, Inc.";
|
|
||||||
case ID('S', 'N', 'Y'): return "Sony";
|
|
||||||
case ID('S', 'T', 'D'): return "STD Computer Inc";
|
|
||||||
case ID('S', 'V', 'S'): return "SVSI";
|
|
||||||
case ID('S', 'Y', 'N'): return "Synaptics Inc";
|
|
||||||
case ID('T', 'C', 'L'): return "Technical Concepts Ltd";
|
|
||||||
case ID('T', 'O', 'P'): return "Orion Communications Co., Ltd.";
|
|
||||||
case ID('T', 'S', 'B'): return "Toshiba America Info Systems Inc";
|
|
||||||
case ID('T', 'S', 'T'): return "Transtream Inc";
|
|
||||||
case ID('U', 'N', 'K'): return "Unknown";
|
|
||||||
case ID('V', 'E', 'S'): return "Vestel Elektronik Sanayi ve Ticaret A. S.";
|
|
||||||
case ID('V', 'I', 'T'): return "Visitech AS";
|
|
||||||
case ID('V', 'I', 'Z'): return "VIZIO, Inc";
|
|
||||||
case ID('V', 'L', 'V'): return "Valve";
|
|
||||||
case ID('V', 'S', 'C'): return "ViewSonic Corporation";
|
|
||||||
case ID('Y', 'M', 'H'): return "Yamaha Corporation";
|
|
||||||
default: return "Unknown";
|
|
||||||
}
|
}
|
||||||
#undef ID
|
|
||||||
|
char query[32];
|
||||||
|
snprintf(query, sizeof(query), "acpi:%s:", pnp_id);
|
||||||
|
struct udev_list_entry *acpi_entry =
|
||||||
|
udev_hwdb_get_properties_list_entry(hwdb, query, 0);
|
||||||
|
if (acpi_entry == NULL) {
|
||||||
|
return pnp_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udev_list_entry *vendor_entry =
|
||||||
|
udev_list_entry_get_by_name(acpi_entry, "ID_VENDOR_FROM_DATABASE");
|
||||||
|
if (vendor_entry == NULL) {
|
||||||
|
return pnp_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return udev_list_entry_get_value(vendor_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See https://en.wikipedia.org/wiki/Extended_Display_Identification_Data for layout of EDID data.
|
/* See https://en.wikipedia.org/wiki/Extended_Display_Identification_Data for layout of EDID data.
|
||||||
* We don't parse the EDID properly. We just expect to receive valid data.
|
* We don't parse the EDID properly. We just expect to receive valid data.
|
||||||
*/
|
*/
|
||||||
void parse_edid(struct wlr_output *restrict output, size_t len, const uint8_t *data) {
|
void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) {
|
||||||
|
struct wlr_output *output = &conn->output;
|
||||||
|
|
||||||
|
free(output->make);
|
||||||
|
free(output->model);
|
||||||
|
free(output->serial);
|
||||||
|
output->make = NULL;
|
||||||
|
output->model = NULL;
|
||||||
|
output->serial = NULL;
|
||||||
|
|
||||||
if (!data || len < 128) {
|
if (!data || len < 128) {
|
||||||
snprintf(output->make, sizeof(output->make), "<Unknown>");
|
|
||||||
snprintf(output->model, sizeof(output->model), "<Unknown>");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t id = (data[8] << 8) | data[9];
|
uint16_t id = (data[8] << 8) | data[9];
|
||||||
snprintf(output->make, sizeof(output->make), "%s", get_manufacturer(id));
|
output->make = strdup(get_manufacturer(conn->backend->hwdb, id));
|
||||||
|
|
||||||
uint16_t model = data[10] | (data[11] << 8);
|
uint16_t model = data[10] | (data[11] << 8);
|
||||||
snprintf(output->model, sizeof(output->model), "0x%04X", model);
|
char model_str[32];
|
||||||
|
snprintf(model_str, sizeof(model_str), "0x%04" PRIX16, model);
|
||||||
|
|
||||||
uint32_t serial = data[12] | (data[13] << 8) | (data[14] << 8) | (data[15] << 8);
|
uint32_t serial = data[12] | (data[13] << 8) | (data[14] << 8) | (data[15] << 8);
|
||||||
snprintf(output->serial, sizeof(output->serial), "0x%08X", serial);
|
char serial_str[32];
|
||||||
|
if (serial != 0) {
|
||||||
|
snprintf(serial_str, sizeof(serial_str), "0x%08" PRIX32, serial);
|
||||||
|
} else {
|
||||||
|
serial_str[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 72; i <= 108; i += 18) {
|
for (size_t i = 72; i <= 108; i += 18) {
|
||||||
uint16_t flag = (data[i] << 8) | data[i + 1];
|
uint16_t flag = (data[i] << 8) | data[i + 1];
|
||||||
if (flag == 0 && data[i + 3] == 0xFC) {
|
if (flag == 0 && data[i + 3] == 0xFC) {
|
||||||
sprintf(output->model, "%.13s", &data[i + 5]);
|
snprintf(model_str, sizeof(model_str), "%.13s", &data[i + 5]);
|
||||||
|
|
||||||
// Monitor names are terminated by newline if they're too short
|
// Monitor names are terminated by newline if they're too short
|
||||||
char *nl = strchr(output->model, '\n');
|
char *nl = strchr(model_str, '\n');
|
||||||
if (nl) {
|
if (nl) {
|
||||||
*nl = '\0';
|
*nl = '\0';
|
||||||
}
|
}
|
||||||
} else if (flag == 0 && data[i + 3] == 0xFF) {
|
} else if (flag == 0 && data[i + 3] == 0xFF) {
|
||||||
sprintf(output->serial, "%.13s", &data[i + 5]);
|
snprintf(serial_str, sizeof(serial_str), "%.13s", &data[i + 5]);
|
||||||
|
|
||||||
// Monitor serial numbers are terminated by newline if they're too
|
// Monitor serial numbers are terminated by newline if they're too
|
||||||
// short
|
// short
|
||||||
char *nl = strchr(output->serial, '\n');
|
char* nl = strchr(serial_str, '\n');
|
||||||
|
|
||||||
if (nl) {
|
if (nl) {
|
||||||
*nl = '\0';
|
*nl = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void parse_tile(struct wlr_output *restrict output, size_t len, const uint8_t *data) {
|
void parse_tile(struct wlr_drm_connector *conn, size_t len, const uint8_t *data) {
|
||||||
|
struct wlr_output *output = &conn->output;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
int ret;
|
int ret;
|
||||||
ret = sscanf((char*)data, "%d:%d:%d:%d:%d:%d:%d:%d",
|
ret = sscanf((char*)data, "%d:%d:%d:%d:%d:%d:%d:%d",
|
||||||
|
|
@ -207,6 +179,9 @@ const char *conn_get_name(uint32_t type_id) {
|
||||||
case DRM_MODE_CONNECTOR_USB: return "USB";
|
case DRM_MODE_CONNECTOR_USB: return "USB";
|
||||||
#endif
|
#endif
|
||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
|
output->model = strdup(model_str);
|
||||||
|
if (serial_str[0] != '\0') {
|
||||||
|
output->serial = strdup(serial_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include <wlr/interfaces/wlr_output.h>
|
#include <wlr/interfaces/wlr_output.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/headless.h"
|
#include "backend/headless.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
struct wlr_headless_backend *headless_backend_from_backend(
|
struct wlr_headless_backend *headless_backend_from_backend(
|
||||||
struct wlr_backend *wlr_backend) {
|
struct wlr_backend *wlr_backend) {
|
||||||
|
|
@ -20,7 +19,7 @@ static bool backend_start(struct wlr_backend *wlr_backend) {
|
||||||
wl_list_for_each(output, &backend->outputs, link) {
|
wl_list_for_each(output, &backend->outputs, link) {
|
||||||
wl_event_source_timer_update(output->frame_timer, output->frame_delay);
|
wl_event_source_timer_update(output->frame_timer, output->frame_delay);
|
||||||
wlr_output_update_enabled(&output->wlr_output, true);
|
wlr_output_update_enabled(&output->wlr_output, true);
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_output,
|
wl_signal_emit_mutable(&backend->backend.events.new_output,
|
||||||
&output->wlr_output);
|
&output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
#include <wlr/interfaces/wlr_output.h>
|
#include <wlr/interfaces/wlr_output.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/headless.h"
|
#include "backend/headless.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
||||||
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
|
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
|
||||||
|
|
@ -29,40 +28,41 @@ static bool output_set_custom_mode(struct wlr_headless_output *output,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_test(struct wlr_output *wlr_output) {
|
static bool output_test(struct wlr_output *wlr_output,
|
||||||
uint32_t unsupported =
|
const struct wlr_output_state *state) {
|
||||||
wlr_output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
|
uint32_t unsupported = state->committed & ~SUPPORTED_OUTPUT_STATE;
|
||||||
if (unsupported != 0) {
|
if (unsupported != 0) {
|
||||||
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
||||||
unsupported);
|
unsupported);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
|
if (state->committed & WLR_OUTPUT_STATE_MODE) {
|
||||||
assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
|
assert(state->mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_commit(struct wlr_output *wlr_output) {
|
static bool output_commit(struct wlr_output *wlr_output,
|
||||||
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_headless_output *output =
|
struct wlr_headless_output *output =
|
||||||
headless_output_from_output(wlr_output);
|
headless_output_from_output(wlr_output);
|
||||||
|
|
||||||
if (!output_test(wlr_output)) {
|
if (!output_test(wlr_output, state)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
|
if (state->committed & WLR_OUTPUT_STATE_MODE) {
|
||||||
if (!output_set_custom_mode(output,
|
if (!output_set_custom_mode(output,
|
||||||
wlr_output->pending.custom_mode.width,
|
state->custom_mode.width,
|
||||||
wlr_output->pending.custom_mode.height,
|
state->custom_mode.height,
|
||||||
wlr_output->pending.custom_mode.refresh)) {
|
state->custom_mode.refresh)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||||
struct wlr_output_event_present present_event = {
|
struct wlr_output_event_present present_event = {
|
||||||
.commit_seq = wlr_output->commit_seq + 1,
|
.commit_seq = wlr_output->commit_seq + 1,
|
||||||
.presented = true,
|
.presented = true,
|
||||||
|
|
@ -70,6 +70,8 @@ static bool output_commit(struct wlr_output *wlr_output) {
|
||||||
wlr_output_send_present(wlr_output, &present_event);
|
wlr_output_send_present(wlr_output, &present_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_event_source_timer_update(output->frame_timer, output->frame_delay);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,7 +95,6 @@ bool wlr_output_is_headless(struct wlr_output *wlr_output) {
|
||||||
static int signal_frame(void *data) {
|
static int signal_frame(void *data) {
|
||||||
struct wlr_headless_output *output = data;
|
struct wlr_headless_output *output = data;
|
||||||
wlr_output_send_frame(&output->wlr_output);
|
wlr_output_send_frame(&output->wlr_output);
|
||||||
wl_event_source_timer_update(output->frame_timer, output->frame_delay);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,8 +115,6 @@ struct wlr_output *wlr_headless_add_output(struct wlr_backend *wlr_backend,
|
||||||
struct wlr_output *wlr_output = &output->wlr_output;
|
struct wlr_output *wlr_output = &output->wlr_output;
|
||||||
|
|
||||||
output_set_custom_mode(output, width, height, 0);
|
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));
|
|
||||||
|
|
||||||
char name[64];
|
char name[64];
|
||||||
snprintf(name, sizeof(name), "HEADLESS-%zu", ++backend->last_output_num);
|
snprintf(name, sizeof(name), "HEADLESS-%zu", ++backend->last_output_num);
|
||||||
|
|
@ -134,7 +133,7 @@ struct wlr_output *wlr_headless_add_output(struct wlr_backend *wlr_backend,
|
||||||
if (backend->started) {
|
if (backend->started) {
|
||||||
wl_event_source_timer_update(output->frame_timer, output->frame_delay);
|
wl_event_source_timer_update(output->frame_timer, output->frame_delay);
|
||||||
wlr_output_update_enabled(wlr_output, true);
|
wlr_output_update_enabled(wlr_output, true);
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_output, wlr_output);
|
wl_signal_emit_mutable(&backend->backend.events.new_output, wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wlr_output;
|
return wlr_output;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include <wlr/backend/session.h>
|
#include <wlr/backend/session.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/libinput.h"
|
#include "backend/libinput.h"
|
||||||
#include "util/signal.h"
|
#include "util/env.h"
|
||||||
|
|
||||||
static struct wlr_libinput_backend *get_libinput_backend_from_backend(
|
static struct wlr_libinput_backend *get_libinput_backend_from_backend(
|
||||||
struct wlr_backend *wlr_backend) {
|
struct wlr_backend *wlr_backend) {
|
||||||
|
|
@ -104,15 +104,10 @@ static bool backend_start(struct wlr_backend *wlr_backend) {
|
||||||
libinput_log_set_priority(backend->libinput_context, LIBINPUT_LOG_PRIORITY_ERROR);
|
libinput_log_set_priority(backend->libinput_context, LIBINPUT_LOG_PRIORITY_ERROR);
|
||||||
|
|
||||||
int libinput_fd = libinput_get_fd(backend->libinput_context);
|
int libinput_fd = libinput_get_fd(backend->libinput_context);
|
||||||
char *no_devs = getenv("WLR_LIBINPUT_NO_DEVICES");
|
|
||||||
if (no_devs) {
|
if (!env_parse_bool("WLR_LIBINPUT_NO_DEVICES") && wl_list_empty(&backend->devices)) {
|
||||||
if (strcmp(no_devs, "1") != 0) {
|
|
||||||
no_devs = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!no_devs && backend->wlr_device_lists.size == 0) {
|
|
||||||
handle_libinput_readable(libinput_fd, WL_EVENT_READABLE, backend);
|
handle_libinput_readable(libinput_fd, WL_EVENT_READABLE, backend);
|
||||||
if (backend->wlr_device_lists.size == 0) {
|
if (wl_list_empty(&backend->devices)) {
|
||||||
wlr_log(WLR_ERROR, "libinput initialization failed, no input devices");
|
wlr_log(WLR_ERROR, "libinput initialization failed, no input devices");
|
||||||
wlr_log(WLR_ERROR, "Set WLR_LIBINPUT_NO_DEVICES=1 to suppress this check");
|
wlr_log(WLR_ERROR, "Set WLR_LIBINPUT_NO_DEVICES=1 to suppress this check");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -141,13 +136,9 @@ static void backend_destroy(struct wlr_backend *wlr_backend) {
|
||||||
struct wlr_libinput_backend *backend =
|
struct wlr_libinput_backend *backend =
|
||||||
get_libinput_backend_from_backend(wlr_backend);
|
get_libinput_backend_from_backend(wlr_backend);
|
||||||
|
|
||||||
struct wl_list **wlr_devices_ptr;
|
struct wlr_libinput_input_device *dev, *tmp;
|
||||||
wl_array_for_each(wlr_devices_ptr, &backend->wlr_device_lists) {
|
wl_list_for_each_safe(dev, tmp, &backend->devices, link) {
|
||||||
struct wlr_libinput_input_device *dev, *tmp;
|
destroy_libinput_input_device(dev);
|
||||||
wl_list_for_each_safe(dev, tmp, *wlr_devices_ptr, link) {
|
|
||||||
destroy_libinput_input_device(dev);
|
|
||||||
}
|
|
||||||
free(*wlr_devices_ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_backend_finish(wlr_backend);
|
wlr_backend_finish(wlr_backend);
|
||||||
|
|
@ -156,7 +147,6 @@ static void backend_destroy(struct wlr_backend *wlr_backend) {
|
||||||
wl_list_remove(&backend->session_destroy.link);
|
wl_list_remove(&backend->session_destroy.link);
|
||||||
wl_list_remove(&backend->session_signal.link);
|
wl_list_remove(&backend->session_signal.link);
|
||||||
|
|
||||||
wl_array_release(&backend->wlr_device_lists);
|
|
||||||
if (backend->input_event) {
|
if (backend->input_event) {
|
||||||
wl_event_source_remove(backend->input_event);
|
wl_event_source_remove(backend->input_event);
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +201,7 @@ struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display,
|
||||||
}
|
}
|
||||||
wlr_backend_init(&backend->backend, &backend_impl);
|
wlr_backend_init(&backend->backend, &backend_impl);
|
||||||
|
|
||||||
wl_array_init(&backend->wlr_device_lists);
|
wl_list_init(&backend->devices);
|
||||||
|
|
||||||
backend->session = session;
|
backend->session = session;
|
||||||
backend->display = display;
|
backend->display = display;
|
||||||
|
|
@ -230,8 +220,27 @@ struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display,
|
||||||
|
|
||||||
struct libinput_device *wlr_libinput_get_device_handle(
|
struct libinput_device *wlr_libinput_get_device_handle(
|
||||||
struct wlr_input_device *wlr_dev) {
|
struct wlr_input_device *wlr_dev) {
|
||||||
struct wlr_libinput_input_device *dev =
|
struct wlr_libinput_input_device *dev = NULL;
|
||||||
(struct wlr_libinput_input_device *)wlr_dev;
|
switch (wlr_dev->type) {
|
||||||
|
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||||
|
dev = device_from_keyboard(wlr_keyboard_from_input_device(wlr_dev));
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_POINTER:
|
||||||
|
dev = device_from_pointer(wlr_pointer_from_input_device(wlr_dev));
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_SWITCH:
|
||||||
|
dev = device_from_switch(wlr_switch_from_input_device(wlr_dev));
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_TOUCH:
|
||||||
|
dev = device_from_touch(wlr_touch_from_input_device(wlr_dev));
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||||
|
dev = device_from_tablet(wlr_tablet_from_input_device(wlr_dev));
|
||||||
|
break;
|
||||||
|
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||||
|
dev = device_from_tablet_pad(wlr_tablet_pad_from_input_device(wlr_dev));
|
||||||
|
break;
|
||||||
|
}
|
||||||
return dev->handle;
|
return dev->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,87 +1,62 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <assert.h>
|
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wayland-util.h>
|
|
||||||
#include <wlr/backend/session.h>
|
#include <wlr/backend/session.h>
|
||||||
|
#include <wlr/interfaces/wlr_keyboard.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/interfaces/wlr_switch.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/libinput.h"
|
#include "backend/libinput.h"
|
||||||
#include "util/array.h"
|
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
struct wlr_input_device *get_appropriate_device(
|
void destroy_libinput_input_device(struct wlr_libinput_input_device *dev) {
|
||||||
enum wlr_input_device_type desired_type,
|
if (dev->keyboard.impl) {
|
||||||
struct libinput_device *libinput_dev) {
|
wlr_keyboard_finish(&dev->keyboard);
|
||||||
struct wl_list *wlr_devices = libinput_device_get_user_data(libinput_dev);
|
|
||||||
if (!wlr_devices) {
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
struct wlr_libinput_input_device *dev;
|
if (dev->pointer.impl) {
|
||||||
wl_list_for_each(dev, wlr_devices, link) {
|
wlr_pointer_finish(&dev->pointer);
|
||||||
if (dev->wlr_input_device.type == desired_type) {
|
|
||||||
return &dev->wlr_input_device;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NULL;
|
if (dev->switch_device.impl) {
|
||||||
}
|
wlr_switch_finish(&dev->switch_device);
|
||||||
|
}
|
||||||
void destroy_libinput_input_device(struct wlr_libinput_input_device *dev)
|
if (dev->touch.impl) {
|
||||||
{
|
wlr_touch_finish(&dev->touch);
|
||||||
/**
|
}
|
||||||
* TODO remove the redundant wlr_input_device from wlr_libinput_input_device
|
if (dev->tablet.impl) {
|
||||||
* wlr_libinput_input_device::wlr_input_device is not owned by its input
|
finish_device_tablet(dev);
|
||||||
* device type, which means we have 2 wlr_input_device to cleanup
|
}
|
||||||
*/
|
if (dev->tablet_pad.impl) {
|
||||||
if (dev->wlr_input_device._device) {
|
finish_device_tablet_pad(dev);
|
||||||
wlr_input_device_destroy(&dev->wlr_input_device);
|
|
||||||
}
|
}
|
||||||
wlr_input_device_finish(&dev->wlr_input_device);
|
|
||||||
|
|
||||||
libinput_device_unref(dev->handle);
|
libinput_device_unref(dev->handle);
|
||||||
wl_list_remove(&dev->link);
|
wl_list_remove(&dev->link);
|
||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
|
||||||
const char *name = libinput_device_get_name(libinput_dev);
|
|
||||||
struct wlr_libinput_input_device *dev =
|
|
||||||
calloc(1, sizeof(struct wlr_libinput_input_device));
|
|
||||||
if (dev == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
|
|
||||||
libinput_device_get_size(libinput_dev,
|
|
||||||
&wlr_dev->width_mm, &wlr_dev->height_mm);
|
|
||||||
const char *output_name = libinput_device_get_output_name(libinput_dev);
|
|
||||||
if (output_name != NULL) {
|
|
||||||
wlr_dev->output_name = strdup(output_name);
|
|
||||||
}
|
|
||||||
wl_list_insert(wlr_devices, &dev->link);
|
|
||||||
dev->handle = libinput_dev;
|
|
||||||
libinput_device_ref(libinput_dev);
|
|
||||||
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) {
|
bool wlr_input_device_is_libinput(struct wlr_input_device *wlr_dev) {
|
||||||
switch (wlr_dev->type) {
|
switch (wlr_dev->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||||
return wlr_dev->keyboard->impl == &libinput_keyboard_impl;
|
return wlr_keyboard_from_input_device(wlr_dev)->impl ==
|
||||||
|
&libinput_keyboard_impl;
|
||||||
case WLR_INPUT_DEVICE_POINTER:
|
case WLR_INPUT_DEVICE_POINTER:
|
||||||
return wlr_dev->pointer->impl == &libinput_pointer_impl;
|
return wlr_pointer_from_input_device(wlr_dev)->impl ==
|
||||||
|
&libinput_pointer_impl;
|
||||||
case WLR_INPUT_DEVICE_TOUCH:
|
case WLR_INPUT_DEVICE_TOUCH:
|
||||||
return wlr_dev->touch->impl == &libinput_touch_impl;
|
return wlr_touch_from_input_device(wlr_dev)->impl ==
|
||||||
|
&libinput_touch_impl;
|
||||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||||
return wlr_dev->tablet->impl == &libinput_tablet_impl;
|
return wlr_tablet_from_input_device(wlr_dev)-> impl ==
|
||||||
|
&libinput_tablet_impl;
|
||||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||||
return wlr_dev->tablet_pad->impl == &libinput_tablet_pad_impl;
|
return wlr_tablet_pad_from_input_device(wlr_dev)->impl ==
|
||||||
|
&libinput_tablet_pad_impl;
|
||||||
case WLR_INPUT_DEVICE_SWITCH:
|
case WLR_INPUT_DEVICE_SWITCH:
|
||||||
return wlr_dev->switch_device->impl == &libinput_switch_impl;
|
return wlr_switch_from_input_device(wlr_dev)->impl ==
|
||||||
|
&libinput_switch_impl;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -89,165 +64,96 @@ bool wlr_input_device_is_libinput(struct wlr_input_device *wlr_dev) {
|
||||||
|
|
||||||
static void handle_device_added(struct wlr_libinput_backend *backend,
|
static void handle_device_added(struct wlr_libinput_backend *backend,
|
||||||
struct libinput_device *libinput_dev) {
|
struct libinput_device *libinput_dev) {
|
||||||
/*
|
|
||||||
* Note: the wlr API exposes only devices with a single capability, because
|
|
||||||
* that meshes better with how Wayland does things and is a bit simpler.
|
|
||||||
* However, libinput devices often have multiple capabilities - in such
|
|
||||||
* cases we have to create several devices.
|
|
||||||
*/
|
|
||||||
int vendor = libinput_device_get_id_vendor(libinput_dev);
|
int vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||||
int product = libinput_device_get_id_product(libinput_dev);
|
int product = libinput_device_get_id_product(libinput_dev);
|
||||||
const char *name = libinput_device_get_name(libinput_dev);
|
const char *name = libinput_device_get_name(libinput_dev);
|
||||||
struct wl_list *wlr_devices = calloc(1, sizeof(struct wl_list));
|
wlr_log(WLR_DEBUG, "Adding %s [%d:%d]", name, vendor, product);
|
||||||
if (!wlr_devices) {
|
|
||||||
wlr_log(WLR_ERROR, "Allocation failed");
|
struct wlr_libinput_input_device *dev =
|
||||||
|
calloc(1, sizeof(struct wlr_libinput_input_device));
|
||||||
|
if (dev == NULL) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "failed to allocate wlr_libinput_input_device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wl_list_init(wlr_devices);
|
|
||||||
wlr_log(WLR_DEBUG, "Added %s [%d:%d]", name, vendor, product);
|
dev->handle = libinput_dev;
|
||||||
|
libinput_device_ref(libinput_dev);
|
||||||
|
libinput_device_set_user_data(libinput_dev, dev);
|
||||||
|
|
||||||
|
wl_list_insert(&backend->devices, &dev->link);
|
||||||
|
|
||||||
if (libinput_device_has_capability(
|
if (libinput_device_has_capability(
|
||||||
libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
|
libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) {
|
||||||
struct wlr_input_device *wlr_dev = allocate_device(backend,
|
init_device_keyboard(dev);
|
||||||
libinput_dev, wlr_devices, WLR_INPUT_DEVICE_KEYBOARD);
|
|
||||||
if (!wlr_dev) {
|
wl_signal_emit_mutable(&backend->backend.events.new_input,
|
||||||
goto fail;
|
&dev->keyboard.base);
|
||||||
}
|
|
||||||
wlr_dev->keyboard = create_libinput_keyboard(libinput_dev);
|
|
||||||
if (!wlr_dev->keyboard) {
|
|
||||||
free(wlr_dev);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libinput_device_has_capability(
|
if (libinput_device_has_capability(
|
||||||
libinput_dev, LIBINPUT_DEVICE_CAP_POINTER)) {
|
libinput_dev, LIBINPUT_DEVICE_CAP_POINTER)) {
|
||||||
struct wlr_input_device *wlr_dev = allocate_device(backend,
|
init_device_pointer(dev);
|
||||||
libinput_dev, wlr_devices, WLR_INPUT_DEVICE_POINTER);
|
|
||||||
if (!wlr_dev) {
|
wl_signal_emit_mutable(&backend->backend.events.new_input,
|
||||||
goto fail;
|
&dev->pointer.base);
|
||||||
}
|
|
||||||
wlr_dev->pointer = create_libinput_pointer(libinput_dev);
|
|
||||||
if (!wlr_dev->pointer) {
|
|
||||||
free(wlr_dev);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
|
|
||||||
}
|
|
||||||
if (libinput_device_has_capability(
|
|
||||||
libinput_dev, LIBINPUT_DEVICE_CAP_TOUCH)) {
|
|
||||||
struct wlr_input_device *wlr_dev = allocate_device(backend,
|
|
||||||
libinput_dev, wlr_devices, WLR_INPUT_DEVICE_TOUCH);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_dev->touch = create_libinput_touch(libinput_dev);
|
|
||||||
if (!wlr_dev->touch) {
|
|
||||||
free(wlr_dev);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
|
|
||||||
}
|
|
||||||
if (libinput_device_has_capability(libinput_dev,
|
|
||||||
LIBINPUT_DEVICE_CAP_TABLET_TOOL)) {
|
|
||||||
struct wlr_input_device *wlr_dev = allocate_device(backend,
|
|
||||||
libinput_dev, wlr_devices, WLR_INPUT_DEVICE_TABLET_TOOL);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_dev->tablet = create_libinput_tablet(libinput_dev);
|
|
||||||
if (!wlr_dev->tablet) {
|
|
||||||
free(wlr_dev);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
|
|
||||||
}
|
|
||||||
if (libinput_device_has_capability(
|
|
||||||
libinput_dev, LIBINPUT_DEVICE_CAP_TABLET_PAD)) {
|
|
||||||
struct wlr_input_device *wlr_dev = allocate_device(backend,
|
|
||||||
libinput_dev, wlr_devices, WLR_INPUT_DEVICE_TABLET_PAD);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_dev->tablet_pad = create_libinput_tablet_pad(libinput_dev);
|
|
||||||
if (!wlr_dev->tablet_pad) {
|
|
||||||
free(wlr_dev);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
|
|
||||||
}
|
|
||||||
if (libinput_device_has_capability(
|
|
||||||
libinput_dev, LIBINPUT_DEVICE_CAP_GESTURE)) {
|
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libinput_device_has_capability(
|
if (libinput_device_has_capability(
|
||||||
libinput_dev, LIBINPUT_DEVICE_CAP_SWITCH)) {
|
libinput_dev, LIBINPUT_DEVICE_CAP_SWITCH)) {
|
||||||
struct wlr_input_device *wlr_dev = allocate_device(backend,
|
init_device_switch(dev);
|
||||||
libinput_dev, wlr_devices, WLR_INPUT_DEVICE_SWITCH);
|
wl_signal_emit_mutable(&backend->backend.events.new_input,
|
||||||
if (!wlr_dev) {
|
&dev->switch_device.base);
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_dev->switch_device = create_libinput_switch(libinput_dev);
|
|
||||||
if (!wlr_dev->switch_device) {
|
|
||||||
free(wlr_dev);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wl_list_empty(wlr_devices)) {
|
if (libinput_device_has_capability(
|
||||||
struct wl_list **dst = wl_array_add(&backend->wlr_device_lists, sizeof(wlr_devices));
|
libinput_dev, LIBINPUT_DEVICE_CAP_TOUCH)) {
|
||||||
if (!dst) {
|
init_device_touch(dev);
|
||||||
goto fail;
|
wl_signal_emit_mutable(&backend->backend.events.new_input,
|
||||||
}
|
&dev->touch.base);
|
||||||
*dst = wlr_devices;
|
|
||||||
|
|
||||||
libinput_device_set_user_data(libinput_dev, wlr_devices);
|
|
||||||
} else {
|
|
||||||
free(wlr_devices);
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
fail:
|
if (libinput_device_has_capability(libinput_dev,
|
||||||
wlr_log(WLR_ERROR, "Could not allocate new device");
|
LIBINPUT_DEVICE_CAP_TABLET_TOOL)) {
|
||||||
struct wlr_libinput_input_device *dev, *tmp_dev;
|
init_device_tablet(dev);
|
||||||
wl_list_for_each_safe(dev, tmp_dev, wlr_devices, link) {
|
wl_signal_emit_mutable(&backend->backend.events.new_input,
|
||||||
free(dev);
|
&dev->tablet.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (libinput_device_has_capability(
|
||||||
|
libinput_dev, LIBINPUT_DEVICE_CAP_TABLET_PAD)) {
|
||||||
|
init_device_tablet_pad(dev);
|
||||||
|
wl_signal_emit_mutable(&backend->backend.events.new_input,
|
||||||
|
&dev->tablet_pad.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (libinput_device_has_capability(
|
||||||
|
libinput_dev, LIBINPUT_DEVICE_CAP_GESTURE)) {
|
||||||
|
wlr_log(WLR_DEBUG, "libinput gesture not handled");
|
||||||
}
|
}
|
||||||
free(wlr_devices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_device_removed(struct wlr_libinput_backend *backend,
|
static void handle_device_removed(struct wlr_libinput_backend *backend,
|
||||||
struct libinput_device *libinput_dev) {
|
struct libinput_device *libinput_dev) {
|
||||||
struct wl_list *wlr_devices = libinput_device_get_user_data(libinput_dev);
|
|
||||||
int vendor = libinput_device_get_id_vendor(libinput_dev);
|
int vendor = libinput_device_get_id_vendor(libinput_dev);
|
||||||
int product = libinput_device_get_id_product(libinput_dev);
|
int product = libinput_device_get_id_product(libinput_dev);
|
||||||
const char *name = libinput_device_get_name(libinput_dev);
|
const char *name = libinput_device_get_name(libinput_dev);
|
||||||
wlr_log(WLR_DEBUG, "Removing %s [%d:%d]", name, vendor, product);
|
wlr_log(WLR_DEBUG, "Removing %s [%d:%d]", name, vendor, product);
|
||||||
if (!wlr_devices) {
|
|
||||||
|
struct wlr_libinput_input_device *dev =
|
||||||
|
libinput_device_get_user_data(libinput_dev);
|
||||||
|
if (dev == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "libinput_device has no wlr_libinput_input_device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct wlr_libinput_input_device *dev, *tmp_dev;
|
|
||||||
wl_list_for_each_safe(dev, tmp_dev, wlr_devices, link) {
|
destroy_libinput_input_device(dev);
|
||||||
destroy_libinput_input_device(dev);
|
|
||||||
}
|
|
||||||
size_t i = 0;
|
|
||||||
struct wl_list **ptr;
|
|
||||||
wl_array_for_each(ptr, &backend->wlr_device_lists) {
|
|
||||||
struct wl_list *iter = *ptr;
|
|
||||||
if (iter == wlr_devices) {
|
|
||||||
array_remove_at(&backend->wlr_device_lists,
|
|
||||||
i * sizeof(struct wl_list *), sizeof(struct wl_list *));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
free(wlr_devices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_libinput_event(struct wlr_libinput_backend *backend,
|
void handle_libinput_event(struct wlr_libinput_backend *backend,
|
||||||
struct libinput_event *event) {
|
struct libinput_event *event) {
|
||||||
struct libinput_device *libinput_dev = libinput_event_get_device(event);
|
struct libinput_device *libinput_dev = libinput_event_get_device(event);
|
||||||
|
struct wlr_libinput_input_device *dev =
|
||||||
|
libinput_device_get_user_data(libinput_dev);
|
||||||
enum libinput_event_type event_type = libinput_event_get_type(event);
|
enum libinput_event_type event_type = libinput_event_get_type(event);
|
||||||
switch (event_type) {
|
switch (event_type) {
|
||||||
case LIBINPUT_EVENT_DEVICE_ADDED:
|
case LIBINPUT_EVENT_DEVICE_ADDED:
|
||||||
|
|
@ -257,83 +163,100 @@ void handle_libinput_event(struct wlr_libinput_backend *backend,
|
||||||
handle_device_removed(backend, libinput_dev);
|
handle_device_removed(backend, libinput_dev);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_KEYBOARD_KEY:
|
case LIBINPUT_EVENT_KEYBOARD_KEY:
|
||||||
handle_keyboard_key(event, libinput_dev);
|
handle_keyboard_key(event, &dev->keyboard);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_POINTER_MOTION:
|
case LIBINPUT_EVENT_POINTER_MOTION:
|
||||||
handle_pointer_motion(event, libinput_dev);
|
handle_pointer_motion(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
|
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
|
||||||
handle_pointer_motion_abs(event, libinput_dev);
|
handle_pointer_motion_abs(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_POINTER_BUTTON:
|
case LIBINPUT_EVENT_POINTER_BUTTON:
|
||||||
handle_pointer_button(event, libinput_dev);
|
handle_pointer_button(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_POINTER_AXIS:
|
case LIBINPUT_EVENT_POINTER_AXIS:
|
||||||
handle_pointer_axis(event, libinput_dev);
|
#if !LIBINPUT_HAS_SCROLL_VALUE120
|
||||||
|
/* This event must be ignored in favour of the SCROLL_* events */
|
||||||
|
handle_pointer_axis(event, &dev->pointer);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
#if LIBINPUT_HAS_SCROLL_VALUE120
|
||||||
|
case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
|
||||||
|
handle_pointer_axis_value120(event, &dev->pointer,
|
||||||
|
WLR_AXIS_SOURCE_WHEEL);
|
||||||
|
break;
|
||||||
|
case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
|
||||||
|
handle_pointer_axis_value120(event, &dev->pointer,
|
||||||
|
WLR_AXIS_SOURCE_FINGER);
|
||||||
|
break;
|
||||||
|
case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
|
||||||
|
handle_pointer_axis_value120(event, &dev->pointer,
|
||||||
|
WLR_AXIS_SOURCE_CONTINUOUS);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case LIBINPUT_EVENT_TOUCH_DOWN:
|
case LIBINPUT_EVENT_TOUCH_DOWN:
|
||||||
handle_touch_down(event, libinput_dev);
|
handle_touch_down(event, &dev->touch);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TOUCH_UP:
|
case LIBINPUT_EVENT_TOUCH_UP:
|
||||||
handle_touch_up(event, libinput_dev);
|
handle_touch_up(event, &dev->touch);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TOUCH_MOTION:
|
case LIBINPUT_EVENT_TOUCH_MOTION:
|
||||||
handle_touch_motion(event, libinput_dev);
|
handle_touch_motion(event, &dev->touch);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
||||||
handle_touch_cancel(event, libinput_dev);
|
handle_touch_cancel(event, &dev->touch);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TOUCH_FRAME:
|
case LIBINPUT_EVENT_TOUCH_FRAME:
|
||||||
handle_touch_frame(event, libinput_dev);
|
handle_touch_frame(event, &dev->touch);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
|
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
|
||||||
handle_tablet_tool_axis(event, libinput_dev);
|
handle_tablet_tool_axis(event, &dev->tablet);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
|
case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
|
||||||
handle_tablet_tool_proximity(event, libinput_dev);
|
handle_tablet_tool_proximity(event, &dev->tablet);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TABLET_TOOL_TIP:
|
case LIBINPUT_EVENT_TABLET_TOOL_TIP:
|
||||||
handle_tablet_tool_tip(event, libinput_dev);
|
handle_tablet_tool_tip(event, &dev->tablet);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
|
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
|
||||||
handle_tablet_tool_button(event, libinput_dev);
|
handle_tablet_tool_button(event, &dev->tablet);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
|
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
|
||||||
handle_tablet_pad_button(event, libinput_dev);
|
handle_tablet_pad_button(event, &dev->tablet_pad);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TABLET_PAD_RING:
|
case LIBINPUT_EVENT_TABLET_PAD_RING:
|
||||||
handle_tablet_pad_ring(event, libinput_dev);
|
handle_tablet_pad_ring(event, &dev->tablet_pad);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
|
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
|
||||||
handle_tablet_pad_strip(event, libinput_dev);
|
handle_tablet_pad_strip(event, &dev->tablet_pad);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_SWITCH_TOGGLE:
|
case LIBINPUT_EVENT_SWITCH_TOGGLE:
|
||||||
handle_switch_toggle(event, libinput_dev);
|
handle_switch_toggle(event, &dev->switch_device);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
|
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
|
||||||
handle_pointer_swipe_begin(event, libinput_dev);
|
handle_pointer_swipe_begin(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
|
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
|
||||||
handle_pointer_swipe_update(event, libinput_dev);
|
handle_pointer_swipe_update(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
|
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
|
||||||
handle_pointer_swipe_end(event, libinput_dev);
|
handle_pointer_swipe_end(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
|
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
|
||||||
handle_pointer_pinch_begin(event, libinput_dev);
|
handle_pointer_pinch_begin(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
|
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
|
||||||
handle_pointer_pinch_update(event, libinput_dev);
|
handle_pointer_pinch_update(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_GESTURE_PINCH_END:
|
case LIBINPUT_EVENT_GESTURE_PINCH_END:
|
||||||
handle_pointer_pinch_end(event, libinput_dev);
|
handle_pointer_pinch_end(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
#if LIBINPUT_HAS_HOLD_GESTURES
|
#if LIBINPUT_HAS_HOLD_GESTURES
|
||||||
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
|
case LIBINPUT_EVENT_GESTURE_HOLD_BEGIN:
|
||||||
handle_pointer_hold_begin(event, libinput_dev);
|
handle_pointer_hold_begin(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
case LIBINPUT_EVENT_GESTURE_HOLD_END:
|
case LIBINPUT_EVENT_GESTURE_HOLD_END:
|
||||||
handle_pointer_hold_end(event, libinput_dev);
|
handle_pointer_hold_end(event, &dev->pointer);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,42 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <stdlib.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"
|
#include "backend/libinput.h"
|
||||||
|
|
||||||
struct wlr_libinput_keyboard {
|
struct wlr_libinput_input_device *device_from_keyboard(
|
||||||
struct wlr_keyboard wlr_keyboard;
|
struct wlr_keyboard *kb) {
|
||||||
struct libinput_device *libinput_dev;
|
assert(kb->impl == &libinput_keyboard_impl);
|
||||||
};
|
|
||||||
|
|
||||||
static struct wlr_libinput_keyboard *get_libinput_keyboard_from_keyboard(
|
struct wlr_libinput_input_device *dev = wl_container_of(kb, dev, keyboard);
|
||||||
struct wlr_keyboard *wlr_kb) {
|
return dev;
|
||||||
assert(wlr_kb->impl == &libinput_keyboard_impl);
|
|
||||||
return (struct wlr_libinput_keyboard *)wlr_kb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_set_leds(struct wlr_keyboard *wlr_kb, uint32_t leds) {
|
static void keyboard_set_leds(struct wlr_keyboard *wlr_kb, uint32_t leds) {
|
||||||
struct wlr_libinput_keyboard *kb =
|
struct wlr_libinput_input_device *dev = device_from_keyboard(wlr_kb);
|
||||||
get_libinput_keyboard_from_keyboard(wlr_kb);
|
libinput_device_led_update(dev->handle, leds);
|
||||||
libinput_device_led_update(kb->libinput_dev, leds);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void keyboard_destroy(struct wlr_keyboard *wlr_kb) {
|
|
||||||
struct wlr_libinput_keyboard *kb =
|
|
||||||
get_libinput_keyboard_from_keyboard(wlr_kb);
|
|
||||||
libinput_device_unref(kb->libinput_dev);
|
|
||||||
free(kb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct wlr_keyboard_impl libinput_keyboard_impl = {
|
const struct wlr_keyboard_impl libinput_keyboard_impl = {
|
||||||
.destroy = keyboard_destroy,
|
.name = "libinput-keyboard",
|
||||||
.led_update = keyboard_set_leds
|
.led_update = keyboard_set_leds
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_keyboard *create_libinput_keyboard(
|
void init_device_keyboard(struct wlr_libinput_input_device *dev) {
|
||||||
struct libinput_device *libinput_dev) {
|
const char *name = libinput_device_get_name(dev->handle);
|
||||||
struct wlr_libinput_keyboard *kb =
|
struct wlr_keyboard *wlr_kb = &dev->keyboard;
|
||||||
calloc(1, sizeof(struct wlr_libinput_keyboard));
|
|
||||||
if (kb == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
kb->libinput_dev = libinput_dev;
|
|
||||||
libinput_device_ref(libinput_dev);
|
|
||||||
libinput_device_led_update(libinput_dev, 0);
|
|
||||||
struct wlr_keyboard *wlr_kb = &kb->wlr_keyboard;
|
|
||||||
const char *name = libinput_device_get_name(libinput_dev);
|
|
||||||
wlr_keyboard_init(wlr_kb, &libinput_keyboard_impl, name);
|
wlr_keyboard_init(wlr_kb, &libinput_keyboard_impl, name);
|
||||||
wlr_kb->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
wlr_kb->base.vendor = libinput_device_get_id_vendor(dev->handle);
|
||||||
wlr_kb->base.product = libinput_device_get_id_product(libinput_dev);
|
wlr_kb->base.product = libinput_device_get_id_product(dev->handle);
|
||||||
return wlr_kb;
|
|
||||||
|
libinput_device_led_update(dev->handle, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_keyboard_key(struct libinput_event *event,
|
void handle_keyboard_key(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_keyboard *kb) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_KEYBOARD, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"Got a keyboard event for a device with no keyboards?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_keyboard *kbevent =
|
struct libinput_event_keyboard *kbevent =
|
||||||
libinput_event_get_keyboard_event(event);
|
libinput_event_get_keyboard_event(event);
|
||||||
struct wlr_event_keyboard_key wlr_event = { 0 };
|
struct wlr_keyboard_key_event wlr_event = { 0 };
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent));
|
usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent));
|
||||||
wlr_event.keycode = libinput_event_keyboard_get_key(kbevent);
|
wlr_event.keycode = libinput_event_keyboard_get_key(kbevent);
|
||||||
|
|
@ -79,5 +51,5 @@ void handle_keyboard_key(struct libinput_event *event,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wlr_event.update_state = true;
|
wlr_event.update_state = true;
|
||||||
wlr_keyboard_notify_key(wlr_dev->keyboard, &wlr_event);
|
wlr_keyboard_notify_key(kb, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ wlr_files += files(
|
||||||
features += { 'libinput-backend': true }
|
features += { 'libinput-backend': true }
|
||||||
wlr_deps += libinput
|
wlr_deps += libinput
|
||||||
|
|
||||||
# libinput hold gestures are available since 1.19.0
|
# libinput hold gestures and high resolution scroll are available since 1.19.0
|
||||||
add_project_arguments(
|
add_project_arguments([
|
||||||
'-DLIBINPUT_HAS_HOLD_GESTURES=@0@'.format(libinput.version().version_compare('>=1.19.0').to_int()),
|
'-DLIBINPUT_HAS_HOLD_GESTURES=@0@'.format(libinput.version().version_compare('>=1.19.0').to_int()),
|
||||||
language: 'c',
|
'-DLIBINPUT_HAS_SCROLL_VALUE120=@0@'.format(libinput.version().version_compare('>=1.19.0').to_int()),
|
||||||
)
|
], language: 'c')
|
||||||
|
|
|
||||||
|
|
@ -1,83 +1,65 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <stdlib.h>
|
#include <wlr/interfaces/wlr_pointer.h>
|
||||||
#include <wlr/backend/session.h>
|
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include "backend/libinput.h"
|
#include "backend/libinput.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
const struct wlr_pointer_impl libinput_pointer_impl = {0};
|
const struct wlr_pointer_impl libinput_pointer_impl = {
|
||||||
|
.name = "libinput-pointer",
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_pointer *create_libinput_pointer(
|
void init_device_pointer(struct wlr_libinput_input_device *dev) {
|
||||||
struct libinput_device *libinput_dev) {
|
const char *name = libinput_device_get_name(dev->handle);
|
||||||
assert(libinput_dev);
|
struct wlr_pointer *wlr_pointer = &dev->pointer;
|
||||||
struct wlr_pointer *wlr_pointer = calloc(1, sizeof(struct wlr_pointer));
|
|
||||||
if (!wlr_pointer) {
|
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_pointer");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
const char *name = libinput_device_get_name(libinput_dev);
|
|
||||||
wlr_pointer_init(wlr_pointer, &libinput_pointer_impl, name);
|
wlr_pointer_init(wlr_pointer, &libinput_pointer_impl, name);
|
||||||
wlr_pointer->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
wlr_pointer->base.vendor = libinput_device_get_id_vendor(dev->handle);
|
||||||
wlr_pointer->base.product = libinput_device_get_id_product(libinput_dev);
|
wlr_pointer->base.product = libinput_device_get_id_product(dev->handle);
|
||||||
return wlr_pointer;
|
}
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *device_from_pointer(
|
||||||
|
struct wlr_pointer *wlr_pointer) {
|
||||||
|
assert(wlr_pointer->impl == &libinput_pointer_impl);
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *dev =
|
||||||
|
wl_container_of(wlr_pointer, dev, pointer);
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_motion(struct libinput_event *event,
|
void handle_pointer_motion(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_pointer *pevent =
|
struct libinput_event_pointer *pevent =
|
||||||
libinput_event_get_pointer_event(event);
|
libinput_event_get_pointer_event(event);
|
||||||
struct wlr_event_pointer_motion wlr_event = { 0 };
|
struct wlr_pointer_motion_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
wlr_event.pointer = pointer;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||||
wlr_event.delta_x = libinput_event_pointer_get_dx(pevent);
|
wlr_event.delta_x = libinput_event_pointer_get_dx(pevent);
|
||||||
wlr_event.delta_y = libinput_event_pointer_get_dy(pevent);
|
wlr_event.delta_y = libinput_event_pointer_get_dy(pevent);
|
||||||
wlr_event.unaccel_dx = libinput_event_pointer_get_dx_unaccelerated(pevent);
|
wlr_event.unaccel_dx = libinput_event_pointer_get_dx_unaccelerated(pevent);
|
||||||
wlr_event.unaccel_dy = libinput_event_pointer_get_dy_unaccelerated(pevent);
|
wlr_event.unaccel_dy = libinput_event_pointer_get_dy_unaccelerated(pevent);
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.motion, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.motion, &wlr_event);
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.frame, wlr_dev->pointer);
|
wl_signal_emit_mutable(&pointer->events.frame, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_motion_abs(struct libinput_event *event,
|
void handle_pointer_motion_abs(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_pointer *pevent =
|
struct libinput_event_pointer *pevent =
|
||||||
libinput_event_get_pointer_event(event);
|
libinput_event_get_pointer_event(event);
|
||||||
struct wlr_event_pointer_motion_absolute wlr_event = { 0 };
|
struct wlr_pointer_motion_absolute_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
wlr_event.pointer = pointer;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||||
wlr_event.x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1);
|
wlr_event.x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1);
|
||||||
wlr_event.y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1);
|
wlr_event.y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1);
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.motion_absolute, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.motion_absolute, &wlr_event);
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.frame, wlr_dev->pointer);
|
wl_signal_emit_mutable(&pointer->events.frame, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_button(struct libinput_event *event,
|
void handle_pointer_button(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_pointer *pevent =
|
struct libinput_event_pointer *pevent =
|
||||||
libinput_event_get_pointer_event(event);
|
libinput_event_get_pointer_event(event);
|
||||||
struct wlr_event_pointer_button wlr_event = { 0 };
|
struct wlr_pointer_button_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
wlr_event.pointer = pointer;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||||
wlr_event.button = libinput_event_pointer_get_button(pevent);
|
wlr_event.button = libinput_event_pointer_get_button(pevent);
|
||||||
|
|
@ -89,22 +71,16 @@ void handle_pointer_button(struct libinput_event *event,
|
||||||
wlr_event.state = WLR_BUTTON_RELEASED;
|
wlr_event.state = WLR_BUTTON_RELEASED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.button, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.button, &wlr_event);
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.frame, wlr_dev->pointer);
|
wl_signal_emit_mutable(&pointer->events.frame, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_axis(struct libinput_event *event,
|
void handle_pointer_axis(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_pointer *pevent =
|
struct libinput_event_pointer *pevent =
|
||||||
libinput_event_get_pointer_event(event);
|
libinput_event_get_pointer_event(event);
|
||||||
struct wlr_event_pointer_axis wlr_event = { 0 };
|
struct wlr_pointer_axis_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
wlr_event.pointer = pointer;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||||
switch (libinput_event_pointer_get_axis_source(pevent)) {
|
switch (libinput_event_pointer_get_axis_source(pevent)) {
|
||||||
|
|
@ -126,115 +102,127 @@ void handle_pointer_axis(struct libinput_event *event,
|
||||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
||||||
};
|
};
|
||||||
for (size_t i = 0; i < sizeof(axes) / sizeof(axes[0]); ++i) {
|
for (size_t i = 0; i < sizeof(axes) / sizeof(axes[0]); ++i) {
|
||||||
if (libinput_event_pointer_has_axis(pevent, axes[i])) {
|
if (!libinput_event_pointer_has_axis(pevent, axes[i])) {
|
||||||
switch (axes[i]) {
|
continue;
|
||||||
case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
|
|
||||||
wlr_event.orientation = WLR_AXIS_ORIENTATION_VERTICAL;
|
|
||||||
break;
|
|
||||||
case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
|
|
||||||
wlr_event.orientation = WLR_AXIS_ORIENTATION_HORIZONTAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
wlr_event.delta =
|
|
||||||
libinput_event_pointer_get_axis_value(pevent, axes[i]);
|
|
||||||
wlr_event.delta_discrete =
|
|
||||||
libinput_event_pointer_get_axis_value_discrete(pevent, axes[i]);
|
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.axis, &wlr_event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (axes[i]) {
|
||||||
|
case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
|
||||||
|
wlr_event.orientation = WLR_AXIS_ORIENTATION_VERTICAL;
|
||||||
|
break;
|
||||||
|
case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
|
||||||
|
wlr_event.orientation = WLR_AXIS_ORIENTATION_HORIZONTAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wlr_event.delta =
|
||||||
|
libinput_event_pointer_get_axis_value(pevent, axes[i]);
|
||||||
|
wlr_event.delta_discrete =
|
||||||
|
libinput_event_pointer_get_axis_value_discrete(pevent, axes[i]);
|
||||||
|
wlr_event.delta_discrete *= WLR_POINTER_AXIS_DISCRETE_STEP;
|
||||||
|
wl_signal_emit_mutable(&pointer->events.axis, &wlr_event);
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.frame, wlr_dev->pointer);
|
wl_signal_emit_mutable(&pointer->events.frame, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_swipe_begin(struct libinput_event *event,
|
#if LIBINPUT_HAS_SCROLL_VALUE120
|
||||||
struct libinput_device *libinput_dev) {
|
void handle_pointer_axis_value120(struct libinput_event *event,
|
||||||
struct wlr_input_device *wlr_dev =
|
struct wlr_pointer *pointer, enum wlr_axis_source source) {
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
struct libinput_event_pointer *pevent =
|
||||||
if (!wlr_dev) {
|
libinput_event_get_pointer_event(event);
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?");
|
struct wlr_pointer_axis_event wlr_event = { 0 };
|
||||||
return;
|
wlr_event.pointer = pointer;
|
||||||
|
wlr_event.time_msec =
|
||||||
|
usec_to_msec(libinput_event_pointer_get_time_usec(pevent));
|
||||||
|
wlr_event.source = source;
|
||||||
|
|
||||||
|
const enum libinput_pointer_axis axes[] = {
|
||||||
|
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
||||||
|
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
||||||
|
};
|
||||||
|
for (size_t i = 0; i < sizeof(axes) / sizeof(axes[0]); ++i) {
|
||||||
|
if (!libinput_event_pointer_has_axis(pevent, axes[i])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (axes[i]) {
|
||||||
|
case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
|
||||||
|
wlr_event.orientation = WLR_AXIS_ORIENTATION_VERTICAL;
|
||||||
|
break;
|
||||||
|
case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
|
||||||
|
wlr_event.orientation = WLR_AXIS_ORIENTATION_HORIZONTAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wlr_event.delta =
|
||||||
|
libinput_event_pointer_get_scroll_value(pevent, axes[i]);
|
||||||
|
if (source == WLR_AXIS_SOURCE_WHEEL) {
|
||||||
|
wlr_event.delta_discrete =
|
||||||
|
libinput_event_pointer_get_scroll_value_v120(pevent, axes[i]);
|
||||||
|
}
|
||||||
|
wl_signal_emit_mutable(&pointer->events.axis, &wlr_event);
|
||||||
}
|
}
|
||||||
|
wl_signal_emit_mutable(&pointer->events.frame, pointer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void handle_pointer_swipe_begin(struct libinput_event *event,
|
||||||
|
struct wlr_pointer *pointer) {
|
||||||
struct libinput_event_gesture *gevent =
|
struct libinput_event_gesture *gevent =
|
||||||
libinput_event_get_gesture_event(event);
|
libinput_event_get_gesture_event(event);
|
||||||
struct wlr_event_pointer_swipe_begin wlr_event = {
|
struct wlr_pointer_swipe_begin_event wlr_event = {
|
||||||
.device = wlr_dev,
|
.pointer = pointer,
|
||||||
.time_msec =
|
.time_msec =
|
||||||
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
||||||
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_begin, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.swipe_begin, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_swipe_update(struct libinput_event *event,
|
void handle_pointer_swipe_update(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_gesture *gevent =
|
struct libinput_event_gesture *gevent =
|
||||||
libinput_event_get_gesture_event(event);
|
libinput_event_get_gesture_event(event);
|
||||||
struct wlr_event_pointer_swipe_update wlr_event = {
|
struct wlr_pointer_swipe_update_event wlr_event = {
|
||||||
.device = wlr_dev,
|
.pointer = pointer,
|
||||||
.time_msec =
|
.time_msec =
|
||||||
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
||||||
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
||||||
.dx = libinput_event_gesture_get_dx(gevent),
|
.dx = libinput_event_gesture_get_dx(gevent),
|
||||||
.dy = libinput_event_gesture_get_dy(gevent),
|
.dy = libinput_event_gesture_get_dy(gevent),
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_update, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.swipe_update, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_swipe_end(struct libinput_event *event,
|
void handle_pointer_swipe_end(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_gesture *gevent =
|
struct libinput_event_gesture *gevent =
|
||||||
libinput_event_get_gesture_event(event);
|
libinput_event_get_gesture_event(event);
|
||||||
struct wlr_event_pointer_swipe_end wlr_event = {
|
struct wlr_pointer_swipe_end_event wlr_event = {
|
||||||
.device = wlr_dev,
|
.pointer = pointer,
|
||||||
.time_msec =
|
.time_msec =
|
||||||
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
||||||
.cancelled = libinput_event_gesture_get_cancelled(gevent),
|
.cancelled = libinput_event_gesture_get_cancelled(gevent),
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.swipe_end, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.swipe_end, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_pinch_begin(struct libinput_event *event,
|
void handle_pointer_pinch_begin(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_gesture *gevent =
|
struct libinput_event_gesture *gevent =
|
||||||
libinput_event_get_gesture_event(event);
|
libinput_event_get_gesture_event(event);
|
||||||
struct wlr_event_pointer_pinch_begin wlr_event = {
|
struct wlr_pointer_pinch_begin_event wlr_event = {
|
||||||
.device = wlr_dev,
|
.pointer = pointer,
|
||||||
.time_msec =
|
.time_msec =
|
||||||
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
||||||
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_begin, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.pinch_begin, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_pinch_update(struct libinput_event *event,
|
void handle_pointer_pinch_update(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_gesture *gevent =
|
struct libinput_event_gesture *gevent =
|
||||||
libinput_event_get_gesture_event(event);
|
libinput_event_get_gesture_event(event);
|
||||||
struct wlr_event_pointer_pinch_update wlr_event = {
|
struct wlr_pointer_pinch_update_event wlr_event = {
|
||||||
.device = wlr_dev,
|
.pointer = pointer,
|
||||||
.time_msec =
|
.time_msec =
|
||||||
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
||||||
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
||||||
|
|
@ -243,62 +231,44 @@ void handle_pointer_pinch_update(struct libinput_event *event,
|
||||||
.scale = libinput_event_gesture_get_scale(gevent),
|
.scale = libinput_event_gesture_get_scale(gevent),
|
||||||
.rotation = libinput_event_gesture_get_angle_delta(gevent),
|
.rotation = libinput_event_gesture_get_angle_delta(gevent),
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_update, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.pinch_update, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_pinch_end(struct libinput_event *event,
|
void handle_pointer_pinch_end(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_gesture *gevent =
|
struct libinput_event_gesture *gevent =
|
||||||
libinput_event_get_gesture_event(event);
|
libinput_event_get_gesture_event(event);
|
||||||
struct wlr_event_pointer_pinch_end wlr_event = {
|
struct wlr_pointer_pinch_end_event wlr_event = {
|
||||||
.device = wlr_dev,
|
.pointer = pointer,
|
||||||
.time_msec =
|
.time_msec =
|
||||||
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
||||||
.cancelled = libinput_event_gesture_get_cancelled(gevent),
|
.cancelled = libinput_event_gesture_get_cancelled(gevent),
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.pinch_end, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.pinch_end, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_hold_begin(struct libinput_event *event,
|
void handle_pointer_hold_begin(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_gesture *gevent =
|
struct libinput_event_gesture *gevent =
|
||||||
libinput_event_get_gesture_event(event);
|
libinput_event_get_gesture_event(event);
|
||||||
struct wlr_event_pointer_hold_begin wlr_event = {
|
struct wlr_pointer_hold_begin_event wlr_event = {
|
||||||
.device = wlr_dev,
|
.pointer = pointer,
|
||||||
.time_msec =
|
.time_msec =
|
||||||
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
||||||
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
.fingers = libinput_event_gesture_get_finger_count(gevent),
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.hold_begin, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.hold_begin, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_pointer_hold_end(struct libinput_event *event,
|
void handle_pointer_hold_end(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_pointer *pointer) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_POINTER, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a pointer gesture event for a device with no pointers?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_gesture *gevent =
|
struct libinput_event_gesture *gevent =
|
||||||
libinput_event_get_gesture_event(event);
|
libinput_event_get_gesture_event(event);
|
||||||
struct wlr_event_pointer_hold_end wlr_event = {
|
struct wlr_pointer_hold_end_event wlr_event = {
|
||||||
.device = wlr_dev,
|
.pointer = pointer,
|
||||||
.time_msec =
|
.time_msec =
|
||||||
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
usec_to_msec(libinput_event_gesture_get_time_usec(gevent)),
|
||||||
.cancelled = libinput_event_gesture_get_cancelled(gevent),
|
.cancelled = libinput_event_gesture_get_cancelled(gevent),
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&wlr_dev->pointer->events.hold_end, &wlr_event);
|
wl_signal_emit_mutable(&pointer->events.hold_end, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,34 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <wlr/backend/session.h>
|
|
||||||
#include <wlr/interfaces/wlr_switch.h>
|
#include <wlr/interfaces/wlr_switch.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include "backend/libinput.h"
|
#include "backend/libinput.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
const struct wlr_switch_impl libinput_switch_impl;
|
const struct wlr_switch_impl libinput_switch_impl = {
|
||||||
|
.name = "libinput-switch",
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_switch *create_libinput_switch(
|
void init_device_switch(struct wlr_libinput_input_device *dev) {
|
||||||
struct libinput_device *libinput_dev) {
|
const char *name = libinput_device_get_name(dev->handle);
|
||||||
assert(libinput_dev);
|
struct wlr_switch *wlr_switch = &dev->switch_device;
|
||||||
struct wlr_switch *wlr_switch = calloc(1, sizeof(struct wlr_switch));
|
|
||||||
if (!wlr_switch) {
|
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_switch");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
const char *name = libinput_device_get_name(libinput_dev);
|
|
||||||
wlr_switch_init(wlr_switch, &libinput_switch_impl, name);
|
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(dev->handle);
|
||||||
wlr_switch->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
wlr_switch->base.product = libinput_device_get_id_product(dev->handle);
|
||||||
wlr_switch->base.product = libinput_device_get_id_product(libinput_dev);
|
}
|
||||||
return wlr_switch;
|
|
||||||
|
struct wlr_libinput_input_device *device_from_switch(
|
||||||
|
struct wlr_switch *wlr_switch) {
|
||||||
|
assert(wlr_switch->impl == &libinput_switch_impl);
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *dev =
|
||||||
|
wl_container_of(wlr_switch, dev, switch_device);
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_switch_toggle(struct libinput_event *event,
|
void handle_switch_toggle(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_switch *wlr_switch) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_SWITCH, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a switch event for a device with no switch?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_switch *sevent =
|
struct libinput_event_switch *sevent =
|
||||||
libinput_event_get_switch_event (event);
|
libinput_event_get_switch_event (event);
|
||||||
struct wlr_event_switch_toggle wlr_event = { 0 };
|
struct wlr_switch_toggle_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
|
||||||
switch (libinput_event_switch_get_switch(sevent)) {
|
switch (libinput_event_switch_get_switch(sevent)) {
|
||||||
case LIBINPUT_SWITCH_LID:
|
case LIBINPUT_SWITCH_LID:
|
||||||
wlr_event.switch_type = WLR_SWITCH_TYPE_LID;
|
wlr_event.switch_type = WLR_SWITCH_TYPE_LID;
|
||||||
|
|
@ -56,5 +47,5 @@ void handle_switch_toggle(struct libinput_event *event,
|
||||||
}
|
}
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_switch_get_time_usec(sevent));
|
usec_to_msec(libinput_event_switch_get_time_usec(sevent));
|
||||||
wlr_signal_emit_safe(&wlr_dev->switch_device->events.toggle, &wlr_event);
|
wl_signal_emit_mutable(&wlr_switch->events.toggle, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,23 @@
|
||||||
#ifndef _POSIX_C_SOURCE
|
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#endif
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wlr/backend/session.h>
|
|
||||||
#include <wlr/interfaces/wlr_tablet_pad.h>
|
#include <wlr/interfaces/wlr_tablet_pad.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/libinput.h"
|
#include "backend/libinput.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
// FIXME: Decide on how to alloc/count here
|
const struct wlr_tablet_pad_impl libinput_tablet_pad_impl = {
|
||||||
|
.name = "libinput-tablet-pad",
|
||||||
|
};
|
||||||
|
|
||||||
|
static void group_destroy(struct wlr_tablet_pad_group *group) {
|
||||||
|
free(group->buttons);
|
||||||
|
free(group->strips);
|
||||||
|
free(group->rings);
|
||||||
|
free(group);
|
||||||
|
}
|
||||||
|
|
||||||
static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad,
|
static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad,
|
||||||
struct libinput_device *device, unsigned int index) {
|
struct libinput_device *device, unsigned int index) {
|
||||||
struct libinput_tablet_pad_mode_group *li_group =
|
struct libinput_tablet_pad_mode_group *li_group =
|
||||||
|
|
@ -20,6 +25,7 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad,
|
||||||
struct wlr_tablet_pad_group *group =
|
struct wlr_tablet_pad_group *group =
|
||||||
calloc(1, sizeof(struct wlr_tablet_pad_group));
|
calloc(1, sizeof(struct wlr_tablet_pad_group));
|
||||||
if (!group) {
|
if (!group) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "failed to allocate wlr_tablet_pad_group");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,6 +35,10 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group->rings = calloc(sizeof(unsigned int), group->ring_count);
|
group->rings = calloc(sizeof(unsigned int), group->ring_count);
|
||||||
|
if (group->rings == NULL) {
|
||||||
|
goto group_fail;
|
||||||
|
}
|
||||||
|
|
||||||
size_t ring = 0;
|
size_t ring = 0;
|
||||||
for (size_t i = 0; i < pad->ring_count; ++i) {
|
for (size_t i = 0; i < pad->ring_count; ++i) {
|
||||||
if (libinput_tablet_pad_mode_group_has_ring(li_group, i)) {
|
if (libinput_tablet_pad_mode_group_has_ring(li_group, i)) {
|
||||||
|
|
@ -42,6 +52,9 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group->strips = calloc(sizeof(unsigned int), group->strip_count);
|
group->strips = calloc(sizeof(unsigned int), group->strip_count);
|
||||||
|
if (group->strips == NULL) {
|
||||||
|
goto group_fail;
|
||||||
|
}
|
||||||
size_t strip = 0;
|
size_t strip = 0;
|
||||||
for (size_t i = 0; i < pad->strip_count; ++i) {
|
for (size_t i = 0; i < pad->strip_count; ++i) {
|
||||||
if (libinput_tablet_pad_mode_group_has_strip(li_group, i)) {
|
if (libinput_tablet_pad_mode_group_has_strip(li_group, i)) {
|
||||||
|
|
@ -55,6 +68,9 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group->buttons = calloc(sizeof(unsigned int), group->button_count);
|
group->buttons = calloc(sizeof(unsigned int), group->button_count);
|
||||||
|
if (group->buttons == NULL) {
|
||||||
|
goto group_fail;
|
||||||
|
}
|
||||||
size_t button = 0;
|
size_t button = 0;
|
||||||
for (size_t i = 0; i < pad->button_count; ++i) {
|
for (size_t i = 0; i < pad->button_count; ++i) {
|
||||||
if (libinput_tablet_pad_mode_group_has_button(li_group, i)) {
|
if (libinput_tablet_pad_mode_group_has_button(li_group, i)) {
|
||||||
|
|
@ -63,56 +79,72 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad,
|
||||||
}
|
}
|
||||||
|
|
||||||
group->mode_count = libinput_tablet_pad_mode_group_get_num_modes(li_group);
|
group->mode_count = libinput_tablet_pad_mode_group_get_num_modes(li_group);
|
||||||
|
|
||||||
|
libinput_tablet_pad_mode_group_ref(li_group);
|
||||||
|
|
||||||
wl_list_insert(&pad->groups, &group->link);
|
wl_list_insert(&pad->groups, &group->link);
|
||||||
|
return;
|
||||||
|
|
||||||
|
group_fail:
|
||||||
|
wlr_log(WLR_ERROR, "failed to configure wlr_tablet_pad_group");
|
||||||
|
group_destroy(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct wlr_tablet_pad_impl libinput_tablet_pad_impl;
|
void init_device_tablet_pad(struct wlr_libinput_input_device *dev) {
|
||||||
|
struct libinput_device *handle = dev->handle;
|
||||||
struct wlr_tablet_pad *create_libinput_tablet_pad(
|
const char *name = libinput_device_get_name(handle);
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_tablet_pad *wlr_tablet_pad = &dev->tablet_pad;
|
||||||
assert(libinput_dev);
|
|
||||||
struct wlr_tablet_pad *wlr_tablet_pad =
|
|
||||||
calloc(1, sizeof(struct wlr_tablet_pad));
|
|
||||||
if (!wlr_tablet_pad) {
|
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_tablet_pad");
|
|
||||||
return 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_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.vendor = libinput_device_get_id_vendor(handle);
|
||||||
wlr_tablet_pad->base.product = libinput_device_get_id_product(libinput_dev);
|
wlr_tablet_pad->base.product = libinput_device_get_id_product(handle);
|
||||||
|
|
||||||
wlr_tablet_pad->button_count =
|
wlr_tablet_pad->button_count =
|
||||||
libinput_device_tablet_pad_get_num_buttons(libinput_dev);
|
libinput_device_tablet_pad_get_num_buttons(handle);
|
||||||
wlr_tablet_pad->ring_count =
|
wlr_tablet_pad->ring_count =
|
||||||
libinput_device_tablet_pad_get_num_rings(libinput_dev);
|
libinput_device_tablet_pad_get_num_rings(handle);
|
||||||
wlr_tablet_pad->strip_count =
|
wlr_tablet_pad->strip_count =
|
||||||
libinput_device_tablet_pad_get_num_strips(libinput_dev);
|
libinput_device_tablet_pad_get_num_strips(handle);
|
||||||
|
|
||||||
struct udev_device *udev = libinput_device_get_udev_device(libinput_dev);
|
struct udev_device *udev = libinput_device_get_udev_device(handle);
|
||||||
char **dst = wl_array_add(&wlr_tablet_pad->paths, sizeof(char *));
|
char **dst = wl_array_add(&wlr_tablet_pad->paths, sizeof(char *));
|
||||||
*dst = strdup(udev_device_get_syspath(udev));
|
*dst = strdup(udev_device_get_syspath(udev));
|
||||||
|
|
||||||
int groups = libinput_device_tablet_pad_get_num_mode_groups(libinput_dev);
|
int groups = libinput_device_tablet_pad_get_num_mode_groups(handle);
|
||||||
for (int i = 0; i < groups; ++i) {
|
for (int i = 0; i < groups; ++i) {
|
||||||
add_pad_group_from_libinput(wlr_tablet_pad, libinput_dev, i);
|
add_pad_group_from_libinput(wlr_tablet_pad, handle, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish_device_tablet_pad(struct wlr_libinput_input_device *dev) {
|
||||||
|
struct wlr_tablet_pad_group *group, *tmp;
|
||||||
|
wl_list_for_each_safe(group, tmp, &dev->tablet_pad.groups, link) {
|
||||||
|
group_destroy(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wlr_tablet_pad;
|
wlr_tablet_pad_finish(&dev->tablet_pad);
|
||||||
|
|
||||||
|
int groups = libinput_device_tablet_pad_get_num_mode_groups(dev->handle);
|
||||||
|
for (int i = 0; i < groups; ++i) {
|
||||||
|
struct libinput_tablet_pad_mode_group *li_group =
|
||||||
|
libinput_device_tablet_pad_get_mode_group(dev->handle, i);
|
||||||
|
libinput_tablet_pad_mode_group_unref(li_group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *device_from_tablet_pad(
|
||||||
|
struct wlr_tablet_pad *wlr_tablet_pad) {
|
||||||
|
assert(wlr_tablet_pad->impl == &libinput_tablet_pad_impl);
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *dev =
|
||||||
|
wl_container_of(wlr_tablet_pad, dev, tablet_pad);
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_tablet_pad_button(struct libinput_event *event,
|
void handle_tablet_pad_button(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_tablet_pad *tablet_pad) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"Got a tablet pad event for a device with no tablet pad?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_tablet_pad *pevent =
|
struct libinput_event_tablet_pad *pevent =
|
||||||
libinput_event_get_tablet_pad_event(event);
|
libinput_event_get_tablet_pad_event(event);
|
||||||
struct wlr_event_tablet_pad_button wlr_event = { 0 };
|
struct wlr_tablet_pad_button_event wlr_event = { 0 };
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent));
|
usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent));
|
||||||
wlr_event.button = libinput_event_tablet_pad_get_button_number(pevent);
|
wlr_event.button = libinput_event_tablet_pad_get_button_number(pevent);
|
||||||
|
|
@ -127,21 +159,14 @@ void handle_tablet_pad_button(struct libinput_event *event,
|
||||||
wlr_event.state = WLR_BUTTON_RELEASED;
|
wlr_event.state = WLR_BUTTON_RELEASED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.button, &wlr_event);
|
wl_signal_emit_mutable(&tablet_pad->events.button, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_tablet_pad_ring(struct libinput_event *event,
|
void handle_tablet_pad_ring(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_tablet_pad *tablet_pad) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"Got a tablet pad event for a device with no tablet pad?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_tablet_pad *pevent =
|
struct libinput_event_tablet_pad *pevent =
|
||||||
libinput_event_get_tablet_pad_event(event);
|
libinput_event_get_tablet_pad_event(event);
|
||||||
struct wlr_event_tablet_pad_ring wlr_event = { 0 };
|
struct wlr_tablet_pad_ring_event wlr_event = { 0 };
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent));
|
usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent));
|
||||||
wlr_event.ring = libinput_event_tablet_pad_get_ring_number(pevent);
|
wlr_event.ring = libinput_event_tablet_pad_get_ring_number(pevent);
|
||||||
|
|
@ -155,21 +180,14 @@ void handle_tablet_pad_ring(struct libinput_event *event,
|
||||||
wlr_event.source = WLR_TABLET_PAD_RING_SOURCE_FINGER;
|
wlr_event.source = WLR_TABLET_PAD_RING_SOURCE_FINGER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.ring, &wlr_event);
|
wl_signal_emit_mutable(&tablet_pad->events.ring, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_tablet_pad_strip(struct libinput_event *event,
|
void handle_tablet_pad_strip(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_tablet_pad *tablet_pad) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TABLET_PAD, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"Got a tablet pad event for a device with no tablet pad?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_tablet_pad *pevent =
|
struct libinput_event_tablet_pad *pevent =
|
||||||
libinput_event_get_tablet_pad_event(event);
|
libinput_event_get_tablet_pad_event(event);
|
||||||
struct wlr_event_tablet_pad_strip wlr_event = { 0 };
|
struct wlr_tablet_pad_strip_event wlr_event = { 0 };
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent));
|
usec_to_msec(libinput_event_tablet_pad_get_time_usec(pevent));
|
||||||
wlr_event.strip = libinput_event_tablet_pad_get_strip_number(pevent);
|
wlr_event.strip = libinput_event_tablet_pad_get_strip_number(pevent);
|
||||||
|
|
@ -183,5 +201,5 @@ void handle_tablet_pad_strip(struct libinput_event *event,
|
||||||
wlr_event.source = WLR_TABLET_PAD_STRIP_SOURCE_FINGER;
|
wlr_event.source = WLR_TABLET_PAD_STRIP_SOURCE_FINGER;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->tablet_pad->events.strip, &wlr_event);
|
wl_signal_emit_mutable(&tablet_pad->events.strip, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,92 +1,63 @@
|
||||||
#ifndef _POSIX_C_SOURCE
|
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#endif
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wayland-util.h>
|
|
||||||
#include <wlr/backend/session.h>
|
|
||||||
#include <wlr/interfaces/wlr_tablet_tool.h>
|
#include <wlr/interfaces/wlr_tablet_tool.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/libinput.h"
|
#include "backend/libinput.h"
|
||||||
#include "util/array.h"
|
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
static bool tablet_is_libinput(struct wlr_tablet *tablet) {
|
struct tablet_tool {
|
||||||
return tablet->impl == &libinput_tablet_impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_libinput_tablet_tool {
|
|
||||||
struct wlr_tablet_tool wlr_tool;
|
struct wlr_tablet_tool wlr_tool;
|
||||||
|
struct libinput_tablet_tool *handle;
|
||||||
struct libinput_tablet_tool *libinput_tool;
|
struct wl_list link; // wlr_libinput_input_device::tablet_tools
|
||||||
|
|
||||||
bool unique;
|
|
||||||
// Refcount for destroy + release
|
|
||||||
size_t pad_refs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_libinput_tablet {
|
|
||||||
struct wlr_tablet wlr_tablet;
|
|
||||||
struct wl_array tools; // struct wlr_libinput_tablet_tool *
|
|
||||||
};
|
|
||||||
|
|
||||||
static void destroy_tool(struct wlr_libinput_tablet_tool *tool) {
|
|
||||||
wlr_signal_emit_safe(&tool->wlr_tool.events.destroy, &tool->wlr_tool);
|
|
||||||
libinput_tablet_tool_ref(tool->libinput_tool);
|
|
||||||
libinput_tablet_tool_set_user_data(tool->libinput_tool, NULL);
|
|
||||||
free(tool);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroy_tablet(struct wlr_tablet *wlr_tablet) {
|
|
||||||
assert(tablet_is_libinput(wlr_tablet));
|
|
||||||
struct wlr_libinput_tablet *tablet =
|
|
||||||
wl_container_of(wlr_tablet, tablet, wlr_tablet);
|
|
||||||
|
|
||||||
struct wlr_libinput_tablet_tool **tool_ptr;
|
|
||||||
wl_array_for_each(tool_ptr, &tablet->tools) {
|
|
||||||
struct wlr_libinput_tablet_tool *tool = *tool_ptr;
|
|
||||||
if (--tool->pad_refs == 0) {
|
|
||||||
destroy_tool(tool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wl_array_release(&tablet->tools);
|
|
||||||
|
|
||||||
free(tablet);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct wlr_tablet_impl libinput_tablet_impl = {
|
const struct wlr_tablet_impl libinput_tablet_impl = {
|
||||||
.destroy = destroy_tablet,
|
.name = "libinput-tablet-tool",
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_tablet *create_libinput_tablet(
|
void init_device_tablet(struct wlr_libinput_input_device *dev) {
|
||||||
struct libinput_device *libinput_dev) {
|
const char *name = libinput_device_get_name(dev->handle);
|
||||||
assert(libinput_dev);
|
struct wlr_tablet *wlr_tablet = &dev->tablet;
|
||||||
struct wlr_libinput_tablet *libinput_tablet =
|
|
||||||
calloc(1, sizeof(struct wlr_libinput_tablet));
|
|
||||||
if (!libinput_tablet) {
|
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_tablet_tool");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_tablet *wlr_tablet = &libinput_tablet->wlr_tablet;
|
|
||||||
const char *name = libinput_device_get_name(libinput_dev);
|
|
||||||
|
|
||||||
wlr_tablet_init(wlr_tablet, &libinput_tablet_impl, name);
|
wlr_tablet_init(wlr_tablet, &libinput_tablet_impl, name);
|
||||||
wlr_tablet->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
wlr_tablet->base.vendor = libinput_device_get_id_vendor(dev->handle);
|
||||||
wlr_tablet->base.product = libinput_device_get_id_product(libinput_dev);
|
wlr_tablet->base.product = libinput_device_get_id_product(dev->handle);
|
||||||
|
|
||||||
struct udev_device *udev = libinput_device_get_udev_device(libinput_dev);
|
libinput_device_get_size(dev->handle, &wlr_tablet->width_mm,
|
||||||
|
&wlr_tablet->height_mm);
|
||||||
|
|
||||||
|
struct udev_device *udev = libinput_device_get_udev_device(dev->handle);
|
||||||
char **dst = wl_array_add(&wlr_tablet->paths, sizeof(char *));
|
char **dst = wl_array_add(&wlr_tablet->paths, sizeof(char *));
|
||||||
*dst = strdup(udev_device_get_syspath(udev));
|
*dst = strdup(udev_device_get_syspath(udev));
|
||||||
|
|
||||||
wlr_tablet->name = strdup(libinput_device_get_name(libinput_dev));
|
wl_list_init(&dev->tablet_tools);
|
||||||
|
}
|
||||||
|
|
||||||
wl_array_init(&libinput_tablet->tools);
|
static void tool_destroy(struct tablet_tool *tool) {
|
||||||
|
wl_signal_emit_mutable(&tool->wlr_tool.events.destroy, &tool->wlr_tool);
|
||||||
|
libinput_tablet_tool_unref(tool->handle);
|
||||||
|
libinput_tablet_tool_set_user_data(tool->handle, NULL);
|
||||||
|
wl_list_remove(&tool->link);
|
||||||
|
free(tool);
|
||||||
|
}
|
||||||
|
|
||||||
return wlr_tablet;
|
void finish_device_tablet(struct wlr_libinput_input_device *dev) {
|
||||||
|
struct tablet_tool *tool, *tmp;
|
||||||
|
wl_list_for_each_safe(tool, tmp, &dev->tablet_tools, link) {
|
||||||
|
tool_destroy(tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_tablet_finish(&dev->tablet);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *device_from_tablet(
|
||||||
|
struct wlr_tablet *wlr_tablet) {
|
||||||
|
assert(wlr_tablet->impl == &libinput_tablet_impl);
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *dev =
|
||||||
|
wl_container_of(wlr_tablet, dev, tablet);
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum wlr_tablet_tool_type wlr_type_from_libinput_type(
|
static enum wlr_tablet_tool_type wlr_type_from_libinput_type(
|
||||||
|
|
@ -112,87 +83,54 @@ static enum wlr_tablet_tool_type wlr_type_from_libinput_type(
|
||||||
abort(); // unreachable
|
abort(); // unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_libinput_tablet_tool *get_wlr_tablet_tool(
|
static struct tablet_tool *get_tablet_tool(
|
||||||
struct libinput_tablet_tool *tool) {
|
struct wlr_libinput_input_device *dev,
|
||||||
struct wlr_libinput_tablet_tool *ret =
|
struct libinput_tablet_tool *libinput_tool) {
|
||||||
libinput_tablet_tool_get_user_data(tool);
|
struct tablet_tool *tool =
|
||||||
|
libinput_tablet_tool_get_user_data(libinput_tool);
|
||||||
if (ret) {
|
if (tool) {
|
||||||
return ret;
|
return tool;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = calloc(1, sizeof(struct wlr_libinput_tablet_tool));
|
tool = calloc(1, sizeof(struct tablet_tool));
|
||||||
if (!ret) {
|
if (tool == NULL) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "failed to allocate wlr_libinput_tablet_tool");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->libinput_tool = libinput_tablet_tool_ref(tool);
|
tool->wlr_tool.type = wlr_type_from_libinput_type(
|
||||||
ret->wlr_tool.pressure = libinput_tablet_tool_has_pressure(tool);
|
libinput_tablet_tool_get_type(libinput_tool));
|
||||||
ret->wlr_tool.distance = libinput_tablet_tool_has_distance(tool);
|
tool->wlr_tool.hardware_serial =
|
||||||
ret->wlr_tool.tilt = libinput_tablet_tool_has_tilt(tool);
|
libinput_tablet_tool_get_serial(libinput_tool);
|
||||||
ret->wlr_tool.rotation = libinput_tablet_tool_has_rotation(tool);
|
tool->wlr_tool.hardware_wacom =
|
||||||
ret->wlr_tool.slider = libinput_tablet_tool_has_slider(tool);
|
libinput_tablet_tool_get_tool_id(libinput_tool);
|
||||||
ret->wlr_tool.wheel = libinput_tablet_tool_has_wheel(tool);
|
|
||||||
|
|
||||||
ret->wlr_tool.hardware_serial = libinput_tablet_tool_get_serial(tool);
|
tool->wlr_tool.pressure = libinput_tablet_tool_has_pressure(libinput_tool);
|
||||||
ret->wlr_tool.hardware_wacom = libinput_tablet_tool_get_tool_id(tool);
|
tool->wlr_tool.distance = libinput_tablet_tool_has_distance(libinput_tool);
|
||||||
ret->wlr_tool.type = wlr_type_from_libinput_type(
|
tool->wlr_tool.tilt = libinput_tablet_tool_has_tilt(libinput_tool);
|
||||||
libinput_tablet_tool_get_type(tool));
|
tool->wlr_tool.rotation = libinput_tablet_tool_has_rotation(libinput_tool);
|
||||||
|
tool->wlr_tool.slider = libinput_tablet_tool_has_slider(libinput_tool);
|
||||||
|
tool->wlr_tool.wheel = libinput_tablet_tool_has_wheel(libinput_tool);
|
||||||
|
|
||||||
ret->unique = libinput_tablet_tool_is_unique(tool);
|
wl_signal_init(&tool->wlr_tool.events.destroy);
|
||||||
|
|
||||||
wl_signal_init(&ret->wlr_tool.events.destroy);
|
tool->handle = libinput_tablet_tool_ref(libinput_tool);
|
||||||
|
libinput_tablet_tool_set_user_data(libinput_tool, tool);
|
||||||
|
|
||||||
libinput_tablet_tool_set_user_data(tool, ret);
|
wl_list_insert(&dev->tablet_tools, &tool->link);
|
||||||
return ret;
|
return tool;
|
||||||
}
|
|
||||||
|
|
||||||
static void ensure_tool_reference(struct wlr_libinput_tablet_tool *tool,
|
|
||||||
struct wlr_tablet *wlr_dev) {
|
|
||||||
assert(tablet_is_libinput(wlr_dev));
|
|
||||||
struct wlr_libinput_tablet *tablet =
|
|
||||||
wl_container_of(wlr_dev, tablet, wlr_tablet);
|
|
||||||
|
|
||||||
struct wlr_libinput_tablet_tool **tool_ptr;
|
|
||||||
wl_array_for_each(tool_ptr, &tablet->tools) {
|
|
||||||
if (*tool_ptr == tool) { // We already have a ref
|
|
||||||
// XXX: We *could* optimize the tool to the front of
|
|
||||||
// the list here, since we will probably get the next
|
|
||||||
// couple of events from the same tool.
|
|
||||||
// BUT the list should always be rather short (probably
|
|
||||||
// single digit amount of tools) so it might be more
|
|
||||||
// work than it saves
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_libinput_tablet_tool **dst =
|
|
||||||
wl_array_add(&tablet->tools, sizeof(tool));
|
|
||||||
if (!dst) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to allocate memory for tracking tablet tool");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*dst = tool;
|
|
||||||
++tool->pad_refs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_tablet_tool_axis(struct libinput_event *event,
|
void handle_tablet_tool_axis(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_tablet *wlr_tablet) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TABLET_TOOL, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"Got a tablet tool event for a device with no tablet tools?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_tablet_tool *tevent =
|
struct libinput_event_tablet_tool *tevent =
|
||||||
libinput_event_get_tablet_tool_event(event);
|
libinput_event_get_tablet_tool_event(event);
|
||||||
struct wlr_event_tablet_tool_axis wlr_event = { 0 };
|
struct wlr_libinput_input_device *dev = device_from_tablet(wlr_tablet);
|
||||||
struct wlr_libinput_tablet_tool *tool = get_wlr_tablet_tool(
|
struct tablet_tool *tool =
|
||||||
libinput_event_tablet_tool_get_tool(tevent));
|
get_tablet_tool(dev, libinput_event_tablet_tool_get_tool(tevent));
|
||||||
ensure_tool_reference(tool, wlr_dev->tablet);
|
|
||||||
|
|
||||||
wlr_event.device = wlr_dev;
|
struct wlr_tablet_tool_axis_event wlr_event = { 0 };
|
||||||
|
wlr_event.tablet = wlr_tablet;
|
||||||
wlr_event.tool = &tool->wlr_tool;
|
wlr_event.tool = &tool->wlr_tool;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent));
|
usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent));
|
||||||
|
|
@ -234,27 +172,20 @@ void handle_tablet_tool_axis(struct libinput_event *event,
|
||||||
wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_WHEEL;
|
wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_WHEEL;
|
||||||
wlr_event.wheel_delta = libinput_event_tablet_tool_get_wheel_delta(tevent);
|
wlr_event.wheel_delta = libinput_event_tablet_tool_get_wheel_delta(tevent);
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->tablet->events.axis, &wlr_event);
|
wl_signal_emit_mutable(&wlr_tablet->events.axis, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_tablet_tool_proximity(struct libinput_event *event,
|
void handle_tablet_tool_proximity(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_tablet *wlr_tablet) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TABLET_TOOL, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"Got a tablet tool event for a device with no tablet tools?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_tablet_tool *tevent =
|
struct libinput_event_tablet_tool *tevent =
|
||||||
libinput_event_get_tablet_tool_event(event);
|
libinput_event_get_tablet_tool_event(event);
|
||||||
struct wlr_event_tablet_tool_proximity wlr_event = { 0 };
|
struct wlr_libinput_input_device *dev = device_from_tablet(wlr_tablet);
|
||||||
struct wlr_libinput_tablet_tool *tool = get_wlr_tablet_tool(
|
struct tablet_tool *tool =
|
||||||
libinput_event_tablet_tool_get_tool(tevent));
|
get_tablet_tool(dev, libinput_event_tablet_tool_get_tool(tevent));
|
||||||
ensure_tool_reference(tool, wlr_dev->tablet);
|
|
||||||
|
|
||||||
|
struct wlr_tablet_tool_proximity_event wlr_event = { 0 };
|
||||||
|
wlr_event.tablet = wlr_tablet;
|
||||||
wlr_event.tool = &tool->wlr_tool;
|
wlr_event.tool = &tool->wlr_tool;
|
||||||
wlr_event.device = wlr_dev;
|
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent));
|
usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent));
|
||||||
wlr_event.x = libinput_event_tablet_tool_get_x_transformed(tevent, 1);
|
wlr_event.x = libinput_event_tablet_tool_get_x_transformed(tevent, 1);
|
||||||
|
|
@ -268,56 +199,34 @@ void handle_tablet_tool_proximity(struct libinput_event *event,
|
||||||
wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_IN;
|
wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_IN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->tablet->events.proximity, &wlr_event);
|
wl_signal_emit_mutable(&wlr_tablet->events.proximity, &wlr_event);
|
||||||
|
|
||||||
if (libinput_event_tablet_tool_get_proximity_state(tevent) ==
|
if (libinput_event_tablet_tool_get_proximity_state(tevent) ==
|
||||||
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN) {
|
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN) {
|
||||||
handle_tablet_tool_axis(event, libinput_dev);
|
handle_tablet_tool_axis(event, wlr_tablet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the tool is not unique, libinput will not find it again after the
|
// If the tool is not unique, libinput will not find it again after the
|
||||||
// proximity out, so we should destroy it
|
// proximity out, so we should destroy it
|
||||||
if (!tool->unique &&
|
if (!libinput_tablet_tool_is_unique(tool->handle)
|
||||||
libinput_event_tablet_tool_get_proximity_state(tevent) ==
|
&& libinput_event_tablet_tool_get_proximity_state(tevent) ==
|
||||||
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) {
|
LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) {
|
||||||
// The tool isn't unique, it can't be on multiple tablets
|
// The tool isn't unique, it can't be on multiple tablets
|
||||||
assert(tool->pad_refs == 1);
|
tool_destroy(tool);
|
||||||
assert(tablet_is_libinput(wlr_dev->tablet));
|
|
||||||
struct wlr_libinput_tablet *tablet =
|
|
||||||
wl_container_of(wlr_dev->tablet, tablet, wlr_tablet);
|
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
struct wlr_libinput_tablet_tool **tool_ptr;
|
|
||||||
wl_array_for_each(tool_ptr, &tablet->tools) {
|
|
||||||
if (*tool_ptr == tool) {
|
|
||||||
array_remove_at(&tablet->tools, i * sizeof(tool), sizeof(tool));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy_tool(tool);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_tablet_tool_tip(struct libinput_event *event,
|
void handle_tablet_tool_tip(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_tablet *wlr_tablet) {
|
||||||
struct wlr_input_device *wlr_dev =
|
handle_tablet_tool_axis(event, wlr_tablet);
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TABLET_TOOL, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"Got a tablet tool event for a device with no tablet tools?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handle_tablet_tool_axis(event, libinput_dev);
|
|
||||||
struct libinput_event_tablet_tool *tevent =
|
struct libinput_event_tablet_tool *tevent =
|
||||||
libinput_event_get_tablet_tool_event(event);
|
libinput_event_get_tablet_tool_event(event);
|
||||||
struct wlr_event_tablet_tool_tip wlr_event = { 0 };
|
struct wlr_libinput_input_device *dev = device_from_tablet(wlr_tablet);
|
||||||
struct wlr_libinput_tablet_tool *tool = get_wlr_tablet_tool(
|
struct tablet_tool *tool =
|
||||||
libinput_event_tablet_tool_get_tool(tevent));
|
get_tablet_tool(dev, libinput_event_tablet_tool_get_tool(tevent));
|
||||||
ensure_tool_reference(tool, wlr_dev->tablet);
|
|
||||||
|
|
||||||
wlr_event.device = wlr_dev;
|
struct wlr_tablet_tool_tip_event wlr_event = { 0 };
|
||||||
|
wlr_event.tablet = wlr_tablet;
|
||||||
wlr_event.tool = &tool->wlr_tool;
|
wlr_event.tool = &tool->wlr_tool;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent));
|
usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent));
|
||||||
|
|
@ -332,27 +241,20 @@ void handle_tablet_tool_tip(struct libinput_event *event,
|
||||||
wlr_event.state = WLR_TABLET_TOOL_TIP_DOWN;
|
wlr_event.state = WLR_TABLET_TOOL_TIP_DOWN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->tablet->events.tip, &wlr_event);
|
wl_signal_emit_mutable(&wlr_tablet->events.tip, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_tablet_tool_button(struct libinput_event *event,
|
void handle_tablet_tool_button(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_tablet *wlr_tablet) {
|
||||||
struct wlr_input_device *wlr_dev =
|
handle_tablet_tool_axis(event, wlr_tablet);
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TABLET_TOOL, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG,
|
|
||||||
"Got a tablet tool event for a device with no tablet tools?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handle_tablet_tool_axis(event, libinput_dev);
|
|
||||||
struct libinput_event_tablet_tool *tevent =
|
struct libinput_event_tablet_tool *tevent =
|
||||||
libinput_event_get_tablet_tool_event(event);
|
libinput_event_get_tablet_tool_event(event);
|
||||||
struct wlr_event_tablet_tool_button wlr_event = { 0 };
|
struct wlr_libinput_input_device *dev = device_from_tablet(wlr_tablet);
|
||||||
struct wlr_libinput_tablet_tool *tool = get_wlr_tablet_tool(
|
struct tablet_tool *tool =
|
||||||
libinput_event_tablet_tool_get_tool(tevent));
|
get_tablet_tool(dev, libinput_event_tablet_tool_get_tool(tevent));
|
||||||
ensure_tool_reference(tool, wlr_dev->tablet);
|
|
||||||
|
|
||||||
wlr_event.device = wlr_dev;
|
struct wlr_tablet_tool_button_event wlr_event = { 0 };
|
||||||
|
wlr_event.tablet = wlr_tablet;
|
||||||
wlr_event.tool = &tool->wlr_tool;
|
wlr_event.tool = &tool->wlr_tool;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent));
|
usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent));
|
||||||
|
|
@ -365,5 +267,5 @@ void handle_tablet_tool_button(struct libinput_event *event,
|
||||||
wlr_event.state = WLR_BUTTON_PRESSED;
|
wlr_event.state = WLR_BUTTON_PRESSED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wlr_signal_emit_safe(&wlr_dev->tablet->events.button, &wlr_event);
|
wl_signal_emit_mutable(&wlr_tablet->events.button, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,113 +1,85 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <wlr/backend/session.h>
|
|
||||||
#include <wlr/interfaces/wlr_touch.h>
|
#include <wlr/interfaces/wlr_touch.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include "backend/libinput.h"
|
#include "backend/libinput.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
const struct wlr_touch_impl libinput_touch_impl;
|
const struct wlr_touch_impl libinput_touch_impl = {
|
||||||
|
.name = "libinput-touch",
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_touch *create_libinput_touch(
|
void init_device_touch(struct wlr_libinput_input_device *dev) {
|
||||||
struct libinput_device *libinput_dev) {
|
const char *name = libinput_device_get_name(dev->handle);
|
||||||
assert(libinput_dev);
|
struct wlr_touch *wlr_touch = &dev->touch;
|
||||||
struct wlr_touch *wlr_touch = calloc(1, sizeof(struct wlr_touch));
|
|
||||||
if (!wlr_touch) {
|
|
||||||
wlr_log(WLR_ERROR, "Unable to allocate wlr_touch");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
const char *name = libinput_device_get_name(libinput_dev);
|
|
||||||
wlr_touch_init(wlr_touch, &libinput_touch_impl, name);
|
wlr_touch_init(wlr_touch, &libinput_touch_impl, name);
|
||||||
wlr_touch->base.vendor = libinput_device_get_id_vendor(libinput_dev);
|
wlr_touch->base.vendor = libinput_device_get_id_vendor(dev->handle);
|
||||||
wlr_touch->base.product = libinput_device_get_id_product(libinput_dev);
|
wlr_touch->base.product = libinput_device_get_id_product(dev->handle);
|
||||||
return wlr_touch;
|
|
||||||
|
libinput_device_get_size(dev->handle, &wlr_touch->width_mm,
|
||||||
|
&wlr_touch->height_mm);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *device_from_touch(
|
||||||
|
struct wlr_touch *wlr_touch) {
|
||||||
|
assert(wlr_touch->impl == &libinput_touch_impl);
|
||||||
|
|
||||||
|
struct wlr_libinput_input_device *dev =
|
||||||
|
wl_container_of(wlr_touch, dev, touch);
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_touch_down(struct libinput_event *event,
|
void handle_touch_down(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_touch *touch) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TOUCH, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a touch event for a device with no touch?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_touch *tevent =
|
struct libinput_event_touch *tevent =
|
||||||
libinput_event_get_touch_event(event);
|
libinput_event_get_touch_event(event);
|
||||||
struct wlr_event_touch_down wlr_event = { 0 };
|
struct wlr_touch_down_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
wlr_event.touch = touch;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
||||||
wlr_event.touch_id = libinput_event_touch_get_seat_slot(tevent);
|
wlr_event.touch_id = libinput_event_touch_get_seat_slot(tevent);
|
||||||
wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1);
|
wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1);
|
||||||
wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1);
|
wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1);
|
||||||
wlr_signal_emit_safe(&wlr_dev->touch->events.down, &wlr_event);
|
wl_signal_emit_mutable(&touch->events.down, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_touch_up(struct libinput_event *event,
|
void handle_touch_up(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_touch *touch) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TOUCH, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a touch event for a device with no touch?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_touch *tevent =
|
struct libinput_event_touch *tevent =
|
||||||
libinput_event_get_touch_event(event);
|
libinput_event_get_touch_event(event);
|
||||||
struct wlr_event_touch_up wlr_event = { 0 };
|
struct wlr_touch_up_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
wlr_event.touch = touch;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
||||||
wlr_event.touch_id = libinput_event_touch_get_seat_slot(tevent);
|
wlr_event.touch_id = libinput_event_touch_get_seat_slot(tevent);
|
||||||
wlr_signal_emit_safe(&wlr_dev->touch->events.up, &wlr_event);
|
wl_signal_emit_mutable(&touch->events.up, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_touch_motion(struct libinput_event *event,
|
void handle_touch_motion(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_touch *touch) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TOUCH, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a touch event for a device with no touch?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_touch *tevent =
|
struct libinput_event_touch *tevent =
|
||||||
libinput_event_get_touch_event(event);
|
libinput_event_get_touch_event(event);
|
||||||
struct wlr_event_touch_motion wlr_event = { 0 };
|
struct wlr_touch_motion_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
wlr_event.touch = touch;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
||||||
wlr_event.touch_id = libinput_event_touch_get_seat_slot(tevent);
|
wlr_event.touch_id = libinput_event_touch_get_seat_slot(tevent);
|
||||||
wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1);
|
wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1);
|
||||||
wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1);
|
wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1);
|
||||||
wlr_signal_emit_safe(&wlr_dev->touch->events.motion, &wlr_event);
|
wl_signal_emit_mutable(&touch->events.motion, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_touch_cancel(struct libinput_event *event,
|
void handle_touch_cancel(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_touch *touch) {
|
||||||
struct wlr_input_device *wlr_dev =
|
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TOUCH, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a touch event for a device with no touch?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct libinput_event_touch *tevent =
|
struct libinput_event_touch *tevent =
|
||||||
libinput_event_get_touch_event(event);
|
libinput_event_get_touch_event(event);
|
||||||
struct wlr_event_touch_cancel wlr_event = { 0 };
|
struct wlr_touch_cancel_event wlr_event = { 0 };
|
||||||
wlr_event.device = wlr_dev;
|
wlr_event.touch = touch;
|
||||||
wlr_event.time_msec =
|
wlr_event.time_msec =
|
||||||
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
usec_to_msec(libinput_event_touch_get_time_usec(tevent));
|
||||||
wlr_event.touch_id = libinput_event_touch_get_seat_slot(tevent);
|
wlr_event.touch_id = libinput_event_touch_get_seat_slot(tevent);
|
||||||
wlr_signal_emit_safe(&wlr_dev->touch->events.cancel, &wlr_event);
|
wl_signal_emit_mutable(&touch->events.cancel, &wlr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_touch_frame(struct libinput_event *event,
|
void handle_touch_frame(struct libinput_event *event,
|
||||||
struct libinput_device *libinput_dev) {
|
struct wlr_touch *touch) {
|
||||||
struct wlr_input_device *wlr_dev =
|
wl_signal_emit_mutable(&touch->events.frame, NULL);
|
||||||
get_appropriate_device(WLR_INPUT_DEVICE_TOUCH, libinput_dev);
|
|
||||||
if (!wlr_dev) {
|
|
||||||
wlr_log(WLR_DEBUG, "Got a touch event for a device with no touch?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wlr_signal_emit_safe(&wlr_dev->touch->events.frame, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/backend.h"
|
#include "backend/backend.h"
|
||||||
#include "backend/multi.h"
|
#include "backend/multi.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
struct subbackend_state {
|
struct subbackend_state {
|
||||||
struct wlr_backend *backend;
|
struct wlr_backend *backend;
|
||||||
|
|
@ -161,13 +160,13 @@ bool wlr_backend_is_multi(struct wlr_backend *b) {
|
||||||
static void new_input_reemit(struct wl_listener *listener, void *data) {
|
static void new_input_reemit(struct wl_listener *listener, void *data) {
|
||||||
struct subbackend_state *state = wl_container_of(listener,
|
struct subbackend_state *state = wl_container_of(listener,
|
||||||
state, new_input);
|
state, new_input);
|
||||||
wlr_signal_emit_safe(&state->container->events.new_input, data);
|
wl_signal_emit_mutable(&state->container->events.new_input, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void new_output_reemit(struct wl_listener *listener, void *data) {
|
static void new_output_reemit(struct wl_listener *listener, void *data) {
|
||||||
struct subbackend_state *state = wl_container_of(listener,
|
struct subbackend_state *state = wl_container_of(listener,
|
||||||
state, new_output);
|
state, new_output);
|
||||||
wlr_signal_emit_safe(&state->container->events.new_output, data);
|
wl_signal_emit_mutable(&state->container->events.new_output, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_subbackend_destroy(struct wl_listener *listener,
|
static void handle_subbackend_destroy(struct wl_listener *listener,
|
||||||
|
|
@ -218,7 +217,7 @@ bool wlr_multi_backend_add(struct wlr_backend *_multi,
|
||||||
wl_signal_add(&backend->events.new_output, &sub->new_output);
|
wl_signal_add(&backend->events.new_output, &sub->new_output);
|
||||||
sub->new_output.notify = new_output_reemit;
|
sub->new_output.notify = new_output_reemit;
|
||||||
|
|
||||||
wlr_signal_emit_safe(&multi->events.backend_add, backend);
|
wl_signal_emit_mutable(&multi->events.backend_add, backend);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,7 +229,7 @@ void wlr_multi_backend_remove(struct wlr_backend *_multi,
|
||||||
multi_backend_get_subbackend(multi, backend);
|
multi_backend_get_subbackend(multi, backend);
|
||||||
|
|
||||||
if (sub) {
|
if (sub) {
|
||||||
wlr_signal_emit_safe(&multi->events.backend_remove, backend);
|
wl_signal_emit_mutable(&multi->events.backend_remove, backend);
|
||||||
subbackend_state_destroy(sub);
|
subbackend_state_destroy(sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
#include "backend/session/session.h"
|
#include "backend/session/session.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
#include <libseat.h>
|
#include <libseat.h>
|
||||||
|
|
||||||
|
|
@ -26,13 +25,13 @@
|
||||||
static void handle_enable_seat(struct libseat *seat, void *data) {
|
static void handle_enable_seat(struct libseat *seat, void *data) {
|
||||||
struct wlr_session *session = data;
|
struct wlr_session *session = data;
|
||||||
session->active = true;
|
session->active = true;
|
||||||
wlr_signal_emit_safe(&session->events.active, NULL);
|
wl_signal_emit_mutable(&session->events.active, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_disable_seat(struct libseat *seat, void *data) {
|
static void handle_disable_seat(struct libseat *seat, void *data) {
|
||||||
struct wlr_session *session = data;
|
struct wlr_session *session = data;
|
||||||
session->active = false;
|
session->active = false;
|
||||||
wlr_signal_emit_safe(&session->events.active, NULL);
|
wl_signal_emit_mutable(&session->events.active, NULL);
|
||||||
libseat_disable_seat(session->seat_handle);
|
libseat_disable_seat(session->seat_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,7 +197,7 @@ static int handle_udev_event(int fd, uint32_t mask, void *data) {
|
||||||
struct wlr_session_add_event event = {
|
struct wlr_session_add_event event = {
|
||||||
.path = devnode,
|
.path = devnode,
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&session->events.add_drm_card, &event);
|
wl_signal_emit_mutable(&session->events.add_drm_card, &event);
|
||||||
} else if (strcmp(action, "change") == 0 || strcmp(action, "remove") == 0) {
|
} else if (strcmp(action, "change") == 0 || strcmp(action, "remove") == 0) {
|
||||||
dev_t devnum = udev_device_get_devnum(udev_dev);
|
dev_t devnum = udev_device_get_devnum(udev_dev);
|
||||||
struct wlr_device *dev;
|
struct wlr_device *dev;
|
||||||
|
|
@ -211,10 +210,10 @@ static int handle_udev_event(int fd, uint32_t mask, void *data) {
|
||||||
wlr_log(WLR_DEBUG, "DRM device %s changed", sysname);
|
wlr_log(WLR_DEBUG, "DRM device %s changed", sysname);
|
||||||
struct wlr_device_change_event event = {0};
|
struct wlr_device_change_event event = {0};
|
||||||
read_udev_change_event(&event, udev_dev);
|
read_udev_change_event(&event, udev_dev);
|
||||||
wlr_signal_emit_safe(&dev->events.change, &event);
|
wl_signal_emit_mutable(&dev->events.change, &event);
|
||||||
} else if (strcmp(action, "remove") == 0) {
|
} else if (strcmp(action, "remove") == 0) {
|
||||||
wlr_log(WLR_DEBUG, "DRM device %s removed", sysname);
|
wlr_log(WLR_DEBUG, "DRM device %s removed", sysname);
|
||||||
wlr_signal_emit_safe(&dev->events.remove, NULL);
|
wl_signal_emit_mutable(&dev->events.remove, NULL);
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +297,7 @@ void wlr_session_destroy(struct wlr_session *session) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_signal_emit_safe(&session->events.destroy, session);
|
wl_signal_emit_mutable(&session->events.destroy, session);
|
||||||
wl_list_remove(&session->display_destroy.link);
|
wl_list_remove(&session->display_destroy.link);
|
||||||
|
|
||||||
wl_event_source_remove(session->udev_event);
|
wl_event_source_remove(session->udev_event);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
#include "backend/wayland.h"
|
#include "backend/wayland.h"
|
||||||
#include "render/drm_format_set.h"
|
#include "render/drm_format_set.h"
|
||||||
#include "render/pixel_format.h"
|
#include "render/pixel_format.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
#include "drm-client-protocol.h"
|
#include "drm-client-protocol.h"
|
||||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||||
|
|
@ -346,8 +345,15 @@ static void registry_global(void *data, struct wl_registry *registry,
|
||||||
wl->compositor = wl_registry_bind(registry, name,
|
wl->compositor = wl_registry_bind(registry, name,
|
||||||
&wl_compositor_interface, 4);
|
&wl_compositor_interface, 4);
|
||||||
} else if (strcmp(iface, wl_seat_interface.name) == 0) {
|
} else if (strcmp(iface, wl_seat_interface.name) == 0) {
|
||||||
|
uint32_t target_version = version;
|
||||||
|
if (version < 5) {
|
||||||
|
target_version = 5;
|
||||||
|
}
|
||||||
|
if (version > 8) {
|
||||||
|
target_version = 8;
|
||||||
|
}
|
||||||
struct wl_seat *wl_seat = wl_registry_bind(registry, name,
|
struct wl_seat *wl_seat = wl_registry_bind(registry, name,
|
||||||
&wl_seat_interface, 5);
|
&wl_seat_interface, target_version);
|
||||||
if (!create_wl_seat(wl_seat, wl)) {
|
if (!create_wl_seat(wl_seat, wl)) {
|
||||||
wl_seat_destroy(wl_seat);
|
wl_seat_destroy(wl_seat);
|
||||||
}
|
}
|
||||||
|
|
@ -413,12 +419,16 @@ static bool backend_start(struct wlr_backend *backend) {
|
||||||
|
|
||||||
struct wlr_wl_seat *seat;
|
struct wlr_wl_seat *seat;
|
||||||
wl_list_for_each(seat, &wl->seats, link) {
|
wl_list_for_each(seat, &wl->seats, link) {
|
||||||
if (seat->keyboard) {
|
if (seat->wl_keyboard) {
|
||||||
create_wl_keyboard(seat);
|
init_seat_keyboard(seat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat->wl_touch) {
|
||||||
|
init_seat_touch(seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wl->tablet_manager) {
|
if (wl->tablet_manager) {
|
||||||
wl_add_tablet_seat(wl->tablet_manager, seat);
|
init_seat_tablet(seat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -441,11 +451,6 @@ static void backend_destroy(struct wlr_backend *backend) {
|
||||||
wlr_output_destroy(&output->wlr_output);
|
wlr_output_destroy(&output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_wl_input_device *input_device, *tmp_input_device;
|
|
||||||
wl_list_for_each_safe(input_device, tmp_input_device, &wl->devices, link) {
|
|
||||||
destroy_wl_input_device(input_device);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_wl_buffer *buffer, *tmp_buffer;
|
struct wlr_wl_buffer *buffer, *tmp_buffer;
|
||||||
wl_list_for_each_safe(buffer, tmp_buffer, &wl->buffers, link) {
|
wl_list_for_each_safe(buffer, tmp_buffer, &wl->buffers, link) {
|
||||||
destroy_wl_buffer(buffer);
|
destroy_wl_buffer(buffer);
|
||||||
|
|
@ -538,7 +543,6 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display,
|
||||||
wlr_backend_init(&wl->backend, &backend_impl);
|
wlr_backend_init(&wl->backend, &backend_impl);
|
||||||
|
|
||||||
wl->local_display = display;
|
wl->local_display = display;
|
||||||
wl_list_init(&wl->devices);
|
|
||||||
wl_list_init(&wl->outputs);
|
wl_list_init(&wl->outputs);
|
||||||
wl_list_init(&wl->seats);
|
wl_list_init(&wl->seats);
|
||||||
wl_list_init(&wl->buffers);
|
wl_list_init(&wl->buffers);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ wlr_files += files(
|
||||||
'backend.c',
|
'backend.c',
|
||||||
'output.c',
|
'output.c',
|
||||||
'seat.c',
|
'seat.c',
|
||||||
|
'pointer.c',
|
||||||
'tablet_v2.c',
|
'tablet_v2.c',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
#include "render/pixel_format.h"
|
#include "render/pixel_format.h"
|
||||||
#include "render/swapchain.h"
|
#include "render/swapchain.h"
|
||||||
#include "render/wlr_renderer.h"
|
#include "render/wlr_renderer.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||||
#include "presentation-time-client-protocol.h"
|
#include "presentation-time-client-protocol.h"
|
||||||
|
|
@ -30,7 +29,8 @@
|
||||||
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
||||||
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
|
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
|
||||||
WLR_OUTPUT_STATE_BUFFER |
|
WLR_OUTPUT_STATE_BUFFER |
|
||||||
WLR_OUTPUT_STATE_MODE;
|
WLR_OUTPUT_STATE_MODE |
|
||||||
|
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED;
|
||||||
|
|
||||||
static struct wlr_wl_output *get_wl_output_from_output(
|
static struct wlr_wl_output *get_wl_output_from_output(
|
||||||
struct wlr_output *wlr_output) {
|
struct wlr_output *wlr_output) {
|
||||||
|
|
@ -240,48 +240,59 @@ static struct wlr_wl_buffer *get_or_create_wl_buffer(struct wlr_wl_backend *wl,
|
||||||
return create_wl_buffer(wl, wlr_buffer);
|
return create_wl_buffer(wl, wlr_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_test(struct wlr_output *wlr_output) {
|
static bool output_test(struct wlr_output *wlr_output,
|
||||||
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_wl_output *output =
|
struct wlr_wl_output *output =
|
||||||
get_wl_output_from_output(wlr_output);
|
get_wl_output_from_output(wlr_output);
|
||||||
|
|
||||||
uint32_t unsupported =
|
uint32_t unsupported = state->committed & ~SUPPORTED_OUTPUT_STATE;
|
||||||
wlr_output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
|
|
||||||
if (unsupported != 0) {
|
if (unsupported != 0) {
|
||||||
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
||||||
unsupported);
|
unsupported);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
|
// Adaptive sync is effectively always enabled when using the Wayland
|
||||||
assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
|
// backend. This is not something we have control over, so we set the state
|
||||||
|
// to enabled on creating the output and never allow changing it.
|
||||||
|
assert(wlr_output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED);
|
||||||
|
if (state->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) {
|
||||||
|
if (!state->adaptive_sync_enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((wlr_output->pending.committed & WLR_OUTPUT_STATE_BUFFER) &&
|
if (state->committed & WLR_OUTPUT_STATE_MODE) {
|
||||||
!test_buffer(output->backend, wlr_output->pending.buffer)) {
|
assert(state->mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((state->committed & WLR_OUTPUT_STATE_BUFFER) &&
|
||||||
|
!test_buffer(output->backend, state->buffer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_commit(struct wlr_output *wlr_output) {
|
static bool output_commit(struct wlr_output *wlr_output,
|
||||||
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_wl_output *output =
|
struct wlr_wl_output *output =
|
||||||
get_wl_output_from_output(wlr_output);
|
get_wl_output_from_output(wlr_output);
|
||||||
|
|
||||||
if (!output_test(wlr_output)) {
|
if (!output_test(wlr_output, state)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
|
if (state->committed & WLR_OUTPUT_STATE_MODE) {
|
||||||
if (!output_set_custom_mode(wlr_output,
|
if (!output_set_custom_mode(wlr_output,
|
||||||
wlr_output->pending.custom_mode.width,
|
state->custom_mode.width,
|
||||||
wlr_output->pending.custom_mode.height,
|
state->custom_mode.height,
|
||||||
wlr_output->pending.custom_mode.refresh)) {
|
state->custom_mode.refresh)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||||
struct wp_presentation_feedback *wp_feedback = NULL;
|
struct wp_presentation_feedback *wp_feedback = NULL;
|
||||||
if (output->backend->presentation != NULL) {
|
if (output->backend->presentation != NULL) {
|
||||||
wp_feedback = wp_presentation_feedback(output->backend->presentation,
|
wp_feedback = wp_presentation_feedback(output->backend->presentation,
|
||||||
|
|
@ -289,8 +300,8 @@ static bool output_commit(struct wlr_output *wlr_output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pixman_region32_t *damage = NULL;
|
pixman_region32_t *damage = NULL;
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_DAMAGE) {
|
if (state->committed & WLR_OUTPUT_STATE_DAMAGE) {
|
||||||
damage = &wlr_output->pending.damage;
|
damage = (pixman_region32_t *) &state->damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output->frame_callback != NULL) {
|
if (output->frame_callback != NULL) {
|
||||||
|
|
@ -301,7 +312,7 @@ static bool output_commit(struct wlr_output *wlr_output) {
|
||||||
output->frame_callback = wl_surface_frame(output->surface);
|
output->frame_callback = wl_surface_frame(output->surface);
|
||||||
wl_callback_add_listener(output->frame_callback, &frame_listener, output);
|
wl_callback_add_listener(output->frame_callback, &frame_listener, output);
|
||||||
|
|
||||||
struct wlr_buffer *wlr_buffer = wlr_output->pending.buffer;
|
struct wlr_buffer *wlr_buffer = state->buffer;
|
||||||
struct wlr_wl_buffer *buffer =
|
struct wlr_wl_buffer *buffer =
|
||||||
get_or_create_wl_buffer(output->backend, wlr_buffer);
|
get_or_create_wl_buffer(output->backend, wlr_buffer);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
|
|
@ -436,7 +447,9 @@ void update_wl_output_cursor(struct wlr_wl_output *output) {
|
||||||
if (pointer) {
|
if (pointer) {
|
||||||
assert(pointer->output == output);
|
assert(pointer->output == output);
|
||||||
assert(output->enter_serial);
|
assert(output->enter_serial);
|
||||||
wl_pointer_set_cursor(pointer->wl_pointer, output->enter_serial,
|
|
||||||
|
struct wlr_wl_seat *seat = pointer->seat;
|
||||||
|
wl_pointer_set_cursor(seat->wl_pointer, output->enter_serial,
|
||||||
output->cursor.surface, output->cursor.hotspot_x,
|
output->cursor.surface, output->cursor.hotspot_x,
|
||||||
output->cursor.hotspot_y);
|
output->cursor.hotspot_y);
|
||||||
}
|
}
|
||||||
|
|
@ -518,8 +531,8 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *wlr_backend) {
|
||||||
struct wlr_output *wlr_output = &output->wlr_output;
|
struct wlr_output *wlr_output = &output->wlr_output;
|
||||||
|
|
||||||
wlr_output_update_custom_mode(wlr_output, 1280, 720, 0);
|
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));
|
wlr_output->adaptive_sync_status = WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED;
|
||||||
|
|
||||||
char name[64];
|
char name[64];
|
||||||
snprintf(name, sizeof(name), "WL-%zu", ++backend->last_output_num);
|
snprintf(name, sizeof(name), "WL-%zu", ++backend->last_output_num);
|
||||||
|
|
@ -578,12 +591,12 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *wlr_backend) {
|
||||||
wl_list_insert(&backend->outputs, &output->link);
|
wl_list_insert(&backend->outputs, &output->link);
|
||||||
wlr_output_update_enabled(wlr_output, true);
|
wlr_output_update_enabled(wlr_output, true);
|
||||||
|
|
||||||
wlr_signal_emit_safe(&backend->backend.events.new_output, wlr_output);
|
wl_signal_emit_mutable(&backend->backend.events.new_output, wlr_output);
|
||||||
|
|
||||||
struct wlr_wl_seat *seat;
|
struct wlr_wl_seat *seat;
|
||||||
wl_list_for_each(seat, &backend->seats, link) {
|
wl_list_for_each(seat, &backend->seats, link) {
|
||||||
if (seat->pointer) {
|
if (seat->wl_pointer) {
|
||||||
create_wl_pointer(seat, output);
|
create_pointer(seat, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
541
backend/wayland/pointer.c
Normal file
541
backend/wayland/pointer.c
Normal file
|
|
@ -0,0 +1,541 @@
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include <wlr/interfaces/wlr_pointer.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
#include "backend/wayland.h"
|
||||||
|
|
||||||
|
#include "pointer-gestures-unstable-v1-client-protocol.h"
|
||||||
|
#include "relative-pointer-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
|
static struct wlr_wl_pointer *output_get_pointer(struct wlr_wl_output *output,
|
||||||
|
const struct wl_pointer *wl_pointer) {
|
||||||
|
struct wlr_wl_seat *seat;
|
||||||
|
wl_list_for_each(seat, &output->backend->seats, link) {
|
||||||
|
if (seat->wl_pointer != wl_pointer) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_wl_pointer *pointer;
|
||||||
|
wl_list_for_each(pointer, &seat->pointers, link) {
|
||||||
|
if (pointer->output == output) {
|
||||||
|
return pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t serial, struct wl_surface *surface, wl_fixed_t sx,
|
||||||
|
wl_fixed_t sy) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
if (surface == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_wl_output *output = wl_surface_get_user_data(surface);
|
||||||
|
assert(output);
|
||||||
|
|
||||||
|
struct wlr_wl_pointer *pointer = output_get_pointer(output, wl_pointer);
|
||||||
|
seat->active_pointer = pointer;
|
||||||
|
|
||||||
|
// Manage cursor icon/rendering on output
|
||||||
|
struct wlr_wl_pointer *current = output->cursor.pointer;
|
||||||
|
if (current && current != pointer) {
|
||||||
|
wlr_log(WLR_INFO, "Ignoring seat '%s' pointer in favor of seat '%s'",
|
||||||
|
seat->name, current->seat->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->enter_serial = serial;
|
||||||
|
output->cursor.pointer = pointer;
|
||||||
|
update_wl_output_cursor(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t serial, struct wl_surface *surface) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
if (surface == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_wl_output *output = wl_surface_get_user_data(surface);
|
||||||
|
assert(output);
|
||||||
|
|
||||||
|
if (seat->active_pointer != NULL &&
|
||||||
|
seat->active_pointer->output == output) {
|
||||||
|
seat->active_pointer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output->cursor.pointer == seat->active_pointer) {
|
||||||
|
output->enter_serial = 0;
|
||||||
|
output->cursor.pointer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t time, wl_fixed_t sx, wl_fixed_t sy) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_output *wlr_output = &pointer->output->wlr_output;
|
||||||
|
struct wlr_pointer_motion_absolute_event event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.x = wl_fixed_to_double(sx) / wlr_output->width,
|
||||||
|
.y = wl_fixed_to_double(sy) / wlr_output->height,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.motion_absolute, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_pointer_button_event event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.button = button,
|
||||||
|
.state = state,
|
||||||
|
.time_msec = time,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.button, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t time, uint32_t axis, wl_fixed_t value) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_pointer_axis_event event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.delta = wl_fixed_to_double(value),
|
||||||
|
.delta_discrete = pointer->axis_discrete,
|
||||||
|
.orientation = axis,
|
||||||
|
.time_msec = time,
|
||||||
|
.source = pointer->axis_source,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.axis, &event);
|
||||||
|
|
||||||
|
pointer->axis_discrete = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.frame,
|
||||||
|
&pointer->wlr_pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_axis_source(void *data,
|
||||||
|
struct wl_pointer *wl_pointer, uint32_t axis_source) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer->axis_source = axis_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t time, uint32_t axis) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_pointer_axis_event event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.delta = 0,
|
||||||
|
.delta_discrete = 0,
|
||||||
|
.orientation = axis,
|
||||||
|
.time_msec = time,
|
||||||
|
.source = pointer->axis_source,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.axis, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_axis_discrete(void *data,
|
||||||
|
struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer->axis_discrete = discrete * WLR_POINTER_AXIS_DISCRETE_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_axis_value120(void *data,
|
||||||
|
struct wl_pointer *wl_pointer, uint32_t axis, int32_t value120) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer->axis_discrete = value120;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_pointer_listener pointer_listener = {
|
||||||
|
.enter = pointer_handle_enter,
|
||||||
|
.leave = pointer_handle_leave,
|
||||||
|
.motion = pointer_handle_motion,
|
||||||
|
.button = pointer_handle_button,
|
||||||
|
.axis = pointer_handle_axis,
|
||||||
|
.frame = pointer_handle_frame,
|
||||||
|
.axis_source = pointer_handle_axis_source,
|
||||||
|
.axis_stop = pointer_handle_axis_stop,
|
||||||
|
.axis_discrete = pointer_handle_axis_discrete,
|
||||||
|
.axis_value120 = pointer_handle_axis_value120,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gesture_swipe_begin(void *data,
|
||||||
|
struct zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1,
|
||||||
|
uint32_t serial, uint32_t time, struct wl_surface *surface,
|
||||||
|
uint32_t fingers) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer->fingers = fingers;
|
||||||
|
|
||||||
|
struct wlr_pointer_swipe_begin_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.fingers = fingers,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.swipe_begin, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gesture_swipe_update(void *data,
|
||||||
|
struct zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1,
|
||||||
|
uint32_t time, wl_fixed_t dx, wl_fixed_t dy) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_pointer_swipe_update_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.fingers = pointer->fingers,
|
||||||
|
.dx = wl_fixed_to_double(dx),
|
||||||
|
.dy = wl_fixed_to_double(dy),
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.swipe_update, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gesture_swipe_end(void *data,
|
||||||
|
struct zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1,
|
||||||
|
uint32_t serial, uint32_t time, int32_t cancelled) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_pointer_swipe_end_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.cancelled = cancelled,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.swipe_end, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_pointer_gesture_swipe_v1_listener gesture_swipe_impl = {
|
||||||
|
.begin = gesture_swipe_begin,
|
||||||
|
.update = gesture_swipe_update,
|
||||||
|
.end = gesture_swipe_end,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gesture_pinch_begin(void *data,
|
||||||
|
struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1,
|
||||||
|
uint32_t serial, uint32_t time, struct wl_surface *surface,
|
||||||
|
uint32_t fingers) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer->fingers = fingers;
|
||||||
|
|
||||||
|
struct wlr_pointer_pinch_begin_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.fingers = pointer->fingers,
|
||||||
|
};
|
||||||
|
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.pinch_begin, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gesture_pinch_update(void *data,
|
||||||
|
struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1,
|
||||||
|
uint32_t time, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t scale,
|
||||||
|
wl_fixed_t rotation) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_pointer_pinch_update_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.fingers = pointer->fingers,
|
||||||
|
.dx = wl_fixed_to_double(dx),
|
||||||
|
.dy = wl_fixed_to_double(dy),
|
||||||
|
.scale = wl_fixed_to_double(scale),
|
||||||
|
.rotation = wl_fixed_to_double(rotation),
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.pinch_update, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gesture_pinch_end(void *data,
|
||||||
|
struct zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1,
|
||||||
|
uint32_t serial, uint32_t time, int32_t cancelled) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_pointer_pinch_end_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.cancelled = cancelled,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.pinch_end, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_pointer_gesture_pinch_v1_listener gesture_pinch_impl = {
|
||||||
|
.begin = gesture_pinch_begin,
|
||||||
|
.update = gesture_pinch_update,
|
||||||
|
.end = gesture_pinch_end,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gesture_hold_begin(void *data,
|
||||||
|
struct zwp_pointer_gesture_hold_v1 *zwp_pointer_gesture_hold_v1,
|
||||||
|
uint32_t serial, uint32_t time, struct wl_surface *surface,
|
||||||
|
uint32_t fingers) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer->fingers = fingers;
|
||||||
|
|
||||||
|
struct wlr_pointer_hold_begin_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.fingers = fingers,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.hold_begin, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gesture_hold_end(void *data,
|
||||||
|
struct zwp_pointer_gesture_hold_v1 *zwp_pointer_gesture_hold_v1,
|
||||||
|
uint32_t serial, uint32_t time, int32_t cancelled) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_pointer_hold_end_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = time,
|
||||||
|
.cancelled = cancelled,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.hold_end, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_pointer_gesture_hold_v1_listener gesture_hold_impl = {
|
||||||
|
.begin = gesture_hold_begin,
|
||||||
|
.end = gesture_hold_end,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void relative_pointer_handle_relative_motion(void *data,
|
||||||
|
struct zwp_relative_pointer_v1 *relative_pointer, uint32_t utime_hi,
|
||||||
|
uint32_t utime_lo, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel,
|
||||||
|
wl_fixed_t dy_unaccel) {
|
||||||
|
struct wlr_wl_seat *seat = data;
|
||||||
|
struct wlr_wl_pointer *pointer = seat->active_pointer;
|
||||||
|
if (pointer == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t time_usec = (uint64_t)utime_hi << 32 | utime_lo;
|
||||||
|
|
||||||
|
struct wlr_pointer_motion_event wlr_event = {
|
||||||
|
.pointer = &pointer->wlr_pointer,
|
||||||
|
.time_msec = (uint32_t)(time_usec / 1000),
|
||||||
|
.delta_x = wl_fixed_to_double(dx),
|
||||||
|
.delta_y = wl_fixed_to_double(dy),
|
||||||
|
.unaccel_dx = wl_fixed_to_double(dx_unaccel),
|
||||||
|
.unaccel_dy = wl_fixed_to_double(dy_unaccel),
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&pointer->wlr_pointer.events.motion, &wlr_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
|
||||||
|
.relative_motion = relative_pointer_handle_relative_motion,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct wlr_pointer_impl wl_pointer_impl = {
|
||||||
|
.name = "wl-pointer",
|
||||||
|
};
|
||||||
|
|
||||||
|
static void destroy_pointer(struct wlr_wl_pointer *pointer) {
|
||||||
|
if (pointer->output->cursor.pointer == pointer) {
|
||||||
|
pointer->output->cursor.pointer = NULL;
|
||||||
|
}
|
||||||
|
if (pointer->seat->active_pointer == pointer) {
|
||||||
|
pointer->seat->active_pointer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_pointer_finish(&pointer->wlr_pointer);
|
||||||
|
wl_list_remove(&pointer->output_destroy.link);
|
||||||
|
wl_list_remove(&pointer->link);
|
||||||
|
free(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_output_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_wl_pointer *pointer =
|
||||||
|
wl_container_of(listener, pointer, output_destroy);
|
||||||
|
destroy_pointer(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_pointer(struct wlr_wl_seat *seat, struct wlr_wl_output *output) {
|
||||||
|
assert(seat->wl_pointer);
|
||||||
|
|
||||||
|
if (output_get_pointer(output, seat->wl_pointer)) {
|
||||||
|
wlr_log(WLR_DEBUG,
|
||||||
|
"pointer for output '%s' from seat '%s' already exists",
|
||||||
|
output->wlr_output.name, seat->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(WLR_DEBUG, "creating pointer for output '%s' from seat '%s'",
|
||||||
|
output->wlr_output.name, seat->name);
|
||||||
|
|
||||||
|
struct wlr_wl_pointer *pointer = calloc(1, sizeof(struct wlr_wl_pointer));
|
||||||
|
if (pointer == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "failed to allocate wlr_wl_pointer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char name[64] = {0};
|
||||||
|
snprintf(name, sizeof(name), "wayland-pointer-%s", seat->name);
|
||||||
|
wlr_pointer_init(&pointer->wlr_pointer, &wl_pointer_impl, name);
|
||||||
|
|
||||||
|
pointer->wlr_pointer.output_name = strdup(output->wlr_output.name);
|
||||||
|
|
||||||
|
pointer->seat = seat;
|
||||||
|
pointer->output = output;
|
||||||
|
|
||||||
|
wl_signal_add(&output->wlr_output.events.destroy, &pointer->output_destroy);
|
||||||
|
pointer->output_destroy.notify = pointer_output_destroy;
|
||||||
|
|
||||||
|
wl_signal_emit_mutable(&seat->backend->backend.events.new_input,
|
||||||
|
&pointer->wlr_pointer.base);
|
||||||
|
|
||||||
|
wl_list_insert(&seat->pointers, &pointer->link);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_seat_pointer(struct wlr_wl_seat *seat) {
|
||||||
|
assert(seat->wl_pointer);
|
||||||
|
|
||||||
|
struct wlr_wl_backend *backend = seat->backend;
|
||||||
|
|
||||||
|
wl_list_init(&seat->pointers);
|
||||||
|
|
||||||
|
struct wlr_wl_output *output;
|
||||||
|
wl_list_for_each(output, &backend->outputs, link) {
|
||||||
|
create_pointer(seat, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backend->zwp_pointer_gestures_v1) {
|
||||||
|
uint32_t version = zwp_pointer_gestures_v1_get_version(
|
||||||
|
backend->zwp_pointer_gestures_v1);
|
||||||
|
|
||||||
|
seat->gesture_swipe = zwp_pointer_gestures_v1_get_swipe_gesture(
|
||||||
|
backend->zwp_pointer_gestures_v1, seat->wl_pointer);
|
||||||
|
zwp_pointer_gesture_swipe_v1_add_listener(seat->gesture_swipe,
|
||||||
|
&gesture_swipe_impl, seat);
|
||||||
|
|
||||||
|
seat->gesture_pinch = zwp_pointer_gestures_v1_get_pinch_gesture(
|
||||||
|
backend->zwp_pointer_gestures_v1, seat->wl_pointer);
|
||||||
|
zwp_pointer_gesture_pinch_v1_add_listener(seat->gesture_pinch,
|
||||||
|
&gesture_pinch_impl, seat);
|
||||||
|
|
||||||
|
if (version >= ZWP_POINTER_GESTURES_V1_GET_HOLD_GESTURE) {
|
||||||
|
seat->gesture_hold = zwp_pointer_gestures_v1_get_hold_gesture(
|
||||||
|
backend->zwp_pointer_gestures_v1, seat->wl_pointer);
|
||||||
|
zwp_pointer_gesture_hold_v1_add_listener(seat->gesture_hold,
|
||||||
|
&gesture_hold_impl, seat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backend->zwp_relative_pointer_manager_v1) {
|
||||||
|
seat->relative_pointer =
|
||||||
|
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||||
|
backend->zwp_relative_pointer_manager_v1, seat->wl_pointer);
|
||||||
|
zwp_relative_pointer_v1_add_listener(seat->relative_pointer,
|
||||||
|
&relative_pointer_listener, seat);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_pointer_add_listener(seat->wl_pointer, &pointer_listener, seat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish_seat_pointer(struct wlr_wl_seat *seat) {
|
||||||
|
assert(seat->wl_pointer);
|
||||||
|
|
||||||
|
wl_pointer_release(seat->wl_pointer);
|
||||||
|
|
||||||
|
struct wlr_wl_pointer *pointer, *tmp;
|
||||||
|
wl_list_for_each_safe(pointer, tmp, &seat->pointers, link) {
|
||||||
|
destroy_pointer(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat->gesture_swipe != NULL) {
|
||||||
|
zwp_pointer_gesture_swipe_v1_destroy(seat->gesture_swipe);
|
||||||
|
}
|
||||||
|
if (seat->gesture_pinch != NULL) {
|
||||||
|
zwp_pointer_gesture_pinch_v1_destroy(seat->gesture_pinch);
|
||||||
|
}
|
||||||
|
if (seat->gesture_hold != NULL) {
|
||||||
|
zwp_pointer_gesture_hold_v1_destroy(seat->gesture_hold);
|
||||||
|
}
|
||||||
|
if (seat->relative_pointer != NULL) {
|
||||||
|
zwp_relative_pointer_v1_destroy(seat->relative_pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
seat->wl_pointer = NULL;
|
||||||
|
seat->active_pointer = NULL;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,35 +1,24 @@
|
||||||
#ifndef _POSIX_C_SOURCE
|
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <wayland-util.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wlr/interfaces/wlr_tablet_pad.h>
|
#include <wlr/interfaces/wlr_tablet_pad.h>
|
||||||
#include <wlr/interfaces/wlr_tablet_tool.h>
|
#include <wlr/interfaces/wlr_tablet_tool.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
#include "util/signal.h"
|
|
||||||
#include "util/time.h"
|
|
||||||
#include "wlr/util/log.h"
|
|
||||||
#include "tablet-unstable-v2-client-protocol.h"
|
|
||||||
|
|
||||||
#include "backend/wayland.h"
|
#include "backend/wayland.h"
|
||||||
|
#include "util/time.h"
|
||||||
|
|
||||||
struct wlr_wl_tablet_seat {
|
#include "tablet-unstable-v2-client-protocol.h"
|
||||||
struct zwp_tablet_seat_v2 *tablet_seat;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wlr_wl_tablet_tool {
|
struct tablet_tool {
|
||||||
/* static */
|
/* static */
|
||||||
struct zwp_tablet_tool_v2 *tool;
|
struct wlr_wl_seat *seat;
|
||||||
struct wlr_tablet_tool wlr_tool;
|
|
||||||
|
|
||||||
/* semi-static */
|
/* semi-static */
|
||||||
struct wlr_wl_output *output;
|
struct wlr_wl_output *output;
|
||||||
struct wlr_wl_input_device *tablet;
|
|
||||||
double pre_x, pre_y;
|
double pre_x, pre_y;
|
||||||
|
|
||||||
/* per frame */
|
/* per frame */
|
||||||
|
|
@ -49,11 +38,11 @@ struct wlr_wl_tablet_tool {
|
||||||
bool is_down;
|
bool is_down;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_wl_tablet_pad_ring {
|
struct tablet_pad_ring {
|
||||||
struct wl_list link; // wlr_wl_tablet_pad_group::rings
|
struct wl_list link; // tablet_pad_group::rings
|
||||||
/* static */
|
/* static */
|
||||||
struct zwp_tablet_pad_ring_v2 *ring;
|
struct zwp_tablet_pad_ring_v2 *ring;
|
||||||
struct wlr_wl_tablet_pad_group *group;
|
struct tablet_pad_group *group;
|
||||||
size_t index;
|
size_t index;
|
||||||
|
|
||||||
/* per frame */
|
/* per frame */
|
||||||
|
|
@ -62,10 +51,10 @@ struct wlr_wl_tablet_pad_ring {
|
||||||
bool stopped;
|
bool stopped;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_wl_tablet_pad_strip {
|
struct tablet_pad_strip {
|
||||||
struct wl_list link; // wlr_wl_tablet_pad_group::strips
|
struct wl_list link; // tablet_pad_group::strips
|
||||||
struct zwp_tablet_pad_strip_v2 *strip;
|
struct zwp_tablet_pad_strip_v2 *strip;
|
||||||
struct wlr_wl_tablet_pad_group *group;
|
struct tablet_pad_group *group;
|
||||||
size_t index;
|
size_t index;
|
||||||
|
|
||||||
enum wlr_tablet_pad_strip_source source;
|
enum wlr_tablet_pad_strip_source source;
|
||||||
|
|
@ -73,43 +62,43 @@ struct wlr_wl_tablet_pad_strip {
|
||||||
bool stopped;
|
bool stopped;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_wl_tablet_pad_group {
|
struct tablet_pad_group {
|
||||||
struct zwp_tablet_pad_group_v2 *pad_group;
|
struct zwp_tablet_pad_group_v2 *pad_group;
|
||||||
struct wlr_tablet_pad *pad;
|
struct wlr_tablet_pad *pad;
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
|
|
||||||
struct wlr_tablet_pad_group group;
|
struct wlr_tablet_pad_group group;
|
||||||
|
|
||||||
struct wl_list rings; // wlr_wl_tablet_pad_ring::link
|
struct wl_list rings; // tablet_pad_ring::link
|
||||||
struct wl_list strips; // wlr_wl_tablet_pad_strips::link
|
struct wl_list strips; // tablet_pad_strips::link
|
||||||
};
|
};
|
||||||
|
|
||||||
static void handle_tablet_pad_ring_source(void *data,
|
static void handle_tablet_pad_ring_source(void *data,
|
||||||
struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
|
struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
|
||||||
uint32_t source) {
|
uint32_t source) {
|
||||||
struct wlr_wl_tablet_pad_ring *ring = data;
|
struct tablet_pad_ring *ring = data;
|
||||||
ring->source = source;
|
ring->source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_ring_angle(void *data,
|
static void handle_tablet_pad_ring_angle(void *data,
|
||||||
struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
|
struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
|
||||||
wl_fixed_t degrees) {
|
wl_fixed_t degrees) {
|
||||||
struct wlr_wl_tablet_pad_ring *ring = data;
|
struct tablet_pad_ring *ring = data;
|
||||||
ring->angle = wl_fixed_to_double(degrees);
|
ring->angle = wl_fixed_to_double(degrees);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_ring_stop(void *data,
|
static void handle_tablet_pad_ring_stop(void *data,
|
||||||
struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2) {
|
struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2) {
|
||||||
struct wlr_wl_tablet_pad_ring *ring = data;
|
struct tablet_pad_ring *ring = data;
|
||||||
ring->stopped = true;
|
ring->stopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_ring_frame(void *data,
|
static void handle_tablet_pad_ring_frame(void *data,
|
||||||
struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
|
struct zwp_tablet_pad_ring_v2 *zwp_tablet_pad_ring_v2,
|
||||||
uint32_t time) {
|
uint32_t time) {
|
||||||
struct wlr_wl_tablet_pad_ring *ring = data;
|
struct tablet_pad_ring *ring = data;
|
||||||
|
|
||||||
struct wlr_event_tablet_pad_ring evt = {
|
struct wlr_tablet_pad_ring_event evt = {
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.source = ring->source,
|
.source = ring->source,
|
||||||
.ring = ring->index,
|
.ring = ring->index,
|
||||||
|
|
@ -118,11 +107,11 @@ static void handle_tablet_pad_ring_frame(void *data,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ring->angle >= 0) {
|
if (ring->angle >= 0) {
|
||||||
wlr_signal_emit_safe(&ring->group->pad->events.ring, &evt);
|
wl_signal_emit_mutable(&ring->group->pad->events.ring, &evt);
|
||||||
}
|
}
|
||||||
if (ring->stopped) {
|
if (ring->stopped) {
|
||||||
evt.position = -1;
|
evt.position = -1;
|
||||||
wlr_signal_emit_safe(&ring->group->pad->events.ring, &evt);
|
wl_signal_emit_mutable(&ring->group->pad->events.ring, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
ring->angle = -1;
|
ring->angle = -1;
|
||||||
|
|
@ -140,29 +129,29 @@ static const struct zwp_tablet_pad_ring_v2_listener tablet_pad_ring_listener = {
|
||||||
static void handle_tablet_pad_strip_source(void *data,
|
static void handle_tablet_pad_strip_source(void *data,
|
||||||
struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
|
struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
|
||||||
uint32_t source) {
|
uint32_t source) {
|
||||||
struct wlr_wl_tablet_pad_strip *strip = data;
|
struct tablet_pad_strip *strip = data;
|
||||||
strip->source = source;
|
strip->source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_strip_position(void *data,
|
static void handle_tablet_pad_strip_position(void *data,
|
||||||
struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
|
struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
|
||||||
uint32_t position) {
|
uint32_t position) {
|
||||||
struct wlr_wl_tablet_pad_strip *strip = data;
|
struct tablet_pad_strip *strip = data;
|
||||||
strip->position = (double) position / 65536.0;
|
strip->position = (double) position / 65536.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_strip_stop(void *data,
|
static void handle_tablet_pad_strip_stop(void *data,
|
||||||
struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2) {
|
struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2) {
|
||||||
struct wlr_wl_tablet_pad_strip *strip = data;
|
struct tablet_pad_strip *strip = data;
|
||||||
strip->stopped = true;
|
strip->stopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_strip_frame(void *data,
|
static void handle_tablet_pad_strip_frame(void *data,
|
||||||
struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
|
struct zwp_tablet_pad_strip_v2 *zwp_tablet_pad_strip_v2,
|
||||||
uint32_t time) {
|
uint32_t time) {
|
||||||
struct wlr_wl_tablet_pad_strip *strip = data;
|
struct tablet_pad_strip *strip = data;
|
||||||
|
|
||||||
struct wlr_event_tablet_pad_strip evt = {
|
struct wlr_tablet_pad_strip_event evt = {
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.source = strip->source,
|
.source = strip->source,
|
||||||
.strip = strip->index,
|
.strip = strip->index,
|
||||||
|
|
@ -171,11 +160,11 @@ static void handle_tablet_pad_strip_frame(void *data,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (strip->position >= 0) {
|
if (strip->position >= 0) {
|
||||||
wlr_signal_emit_safe(&strip->group->pad->events.strip, &evt);
|
wl_signal_emit_mutable(&strip->group->pad->events.strip, &evt);
|
||||||
}
|
}
|
||||||
if (strip->stopped) {
|
if (strip->stopped) {
|
||||||
evt.position = -1;
|
evt.position = -1;
|
||||||
wlr_signal_emit_safe(&strip->group->pad->events.strip, &evt);
|
wl_signal_emit_mutable(&strip->group->pad->events.strip, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
strip->position = -1;
|
strip->position = -1;
|
||||||
|
|
@ -193,7 +182,7 @@ static const struct zwp_tablet_pad_strip_v2_listener tablet_pad_strip_listener =
|
||||||
static void handle_tablet_pad_group_buttons(void *data,
|
static void handle_tablet_pad_group_buttons(void *data,
|
||||||
struct zwp_tablet_pad_group_v2 *pad_group,
|
struct zwp_tablet_pad_group_v2 *pad_group,
|
||||||
struct wl_array *buttons) {
|
struct wl_array *buttons) {
|
||||||
struct wlr_wl_tablet_pad_group *group = data;
|
struct tablet_pad_group *group = data;
|
||||||
|
|
||||||
free(group->group.buttons);
|
free(group->group.buttons);
|
||||||
group->group.buttons = calloc(1, buttons->size);
|
group->group.buttons = calloc(1, buttons->size);
|
||||||
|
|
@ -208,7 +197,7 @@ static void handle_tablet_pad_group_buttons(void *data,
|
||||||
|
|
||||||
static void handle_tablet_pad_group_modes(void *data,
|
static void handle_tablet_pad_group_modes(void *data,
|
||||||
struct zwp_tablet_pad_group_v2 *pad_group, uint32_t modes) {
|
struct zwp_tablet_pad_group_v2 *pad_group, uint32_t modes) {
|
||||||
struct wlr_wl_tablet_pad_group *group = data;
|
struct tablet_pad_group *group = data;
|
||||||
|
|
||||||
group->group.mode_count = modes;
|
group->group.mode_count = modes;
|
||||||
}
|
}
|
||||||
|
|
@ -216,9 +205,9 @@ static void handle_tablet_pad_group_modes(void *data,
|
||||||
static void handle_tablet_pad_group_ring(void *data,
|
static void handle_tablet_pad_group_ring(void *data,
|
||||||
struct zwp_tablet_pad_group_v2 *pad_group,
|
struct zwp_tablet_pad_group_v2 *pad_group,
|
||||||
struct zwp_tablet_pad_ring_v2 *ring) {
|
struct zwp_tablet_pad_ring_v2 *ring) {
|
||||||
struct wlr_wl_tablet_pad_group *group = data;
|
struct tablet_pad_group *group = data;
|
||||||
struct wlr_wl_tablet_pad_ring *tablet_ring =
|
struct tablet_pad_ring *tablet_ring =
|
||||||
calloc(1, sizeof(struct wlr_wl_tablet_pad_ring));
|
calloc(1, sizeof(struct tablet_pad_ring));
|
||||||
if (!tablet_ring) {
|
if (!tablet_ring) {
|
||||||
zwp_tablet_pad_ring_v2_destroy(ring);
|
zwp_tablet_pad_ring_v2_destroy(ring);
|
||||||
return;
|
return;
|
||||||
|
|
@ -237,9 +226,9 @@ static void handle_tablet_pad_group_ring(void *data,
|
||||||
static void handle_tablet_pad_group_strip(void *data,
|
static void handle_tablet_pad_group_strip(void *data,
|
||||||
struct zwp_tablet_pad_group_v2 *pad_group,
|
struct zwp_tablet_pad_group_v2 *pad_group,
|
||||||
struct zwp_tablet_pad_strip_v2 *strip) {
|
struct zwp_tablet_pad_strip_v2 *strip) {
|
||||||
struct wlr_wl_tablet_pad_group *group = data;
|
struct tablet_pad_group *group = data;
|
||||||
struct wlr_wl_tablet_pad_strip *tablet_strip =
|
struct tablet_pad_strip *tablet_strip =
|
||||||
calloc(1, sizeof(struct wlr_wl_tablet_pad_strip));
|
calloc(1, sizeof(struct tablet_pad_strip));
|
||||||
if (!tablet_strip) {
|
if (!tablet_strip) {
|
||||||
zwp_tablet_pad_strip_v2_destroy(strip);
|
zwp_tablet_pad_strip_v2_destroy(strip);
|
||||||
return;
|
return;
|
||||||
|
|
@ -263,25 +252,20 @@ static void handle_tablet_pad_group_done(void *data,
|
||||||
static void handle_tablet_pad_group_mode_switch(void *data,
|
static void handle_tablet_pad_group_mode_switch(void *data,
|
||||||
struct zwp_tablet_pad_group_v2 *pad_group,
|
struct zwp_tablet_pad_group_v2 *pad_group,
|
||||||
uint32_t time, uint32_t serial, uint32_t mode) {
|
uint32_t time, uint32_t serial, uint32_t mode) {
|
||||||
struct wlr_wl_tablet_pad_group *group = data;
|
struct tablet_pad_group *group = data;
|
||||||
group->mode = mode;
|
group->mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This isn't in the listener, but keep the naming scheme around since the
|
static void destroy_tablet_pad_group(struct tablet_pad_group *group) {
|
||||||
* other removed functions work like this, and pad sub-resources are just a bit
|
|
||||||
* special */
|
|
||||||
static void handle_tablet_pad_group_removed(
|
|
||||||
struct wlr_wl_tablet_pad_group *group) {
|
|
||||||
|
|
||||||
/* No need to remove the ::link on strips rings as long as we do *not*
|
/* No need to remove the ::link on strips rings as long as we do *not*
|
||||||
* wl_list_remove on the wl_groups ring/strip attributes here */
|
* wl_list_remove on the wl_groups ring/strip attributes here */
|
||||||
struct wlr_wl_tablet_pad_ring *ring, *tmp_ring;
|
struct tablet_pad_ring *ring, *tmp_ring;
|
||||||
wl_list_for_each_safe(ring, tmp_ring, &group->rings, link) {
|
wl_list_for_each_safe(ring, tmp_ring, &group->rings, link) {
|
||||||
zwp_tablet_pad_ring_v2_destroy(ring->ring);
|
zwp_tablet_pad_ring_v2_destroy(ring->ring);
|
||||||
free(ring);
|
free(ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_wl_tablet_pad_strip *strip, *tmp_strip;
|
struct tablet_pad_strip *strip, *tmp_strip;
|
||||||
wl_list_for_each_safe(strip, tmp_strip, &group->strips, link) {
|
wl_list_for_each_safe(strip, tmp_strip, &group->strips, link) {
|
||||||
zwp_tablet_pad_strip_v2_destroy(strip->strip);
|
zwp_tablet_pad_strip_v2_destroy(strip->strip);
|
||||||
free(strip);
|
free(strip);
|
||||||
|
|
@ -289,10 +273,11 @@ static void handle_tablet_pad_group_removed(
|
||||||
|
|
||||||
zwp_tablet_pad_group_v2_destroy(group->pad_group);
|
zwp_tablet_pad_group_v2_destroy(group->pad_group);
|
||||||
|
|
||||||
/* While I'm pretty sure we have control over this as well, it's
|
free(group->group.buttons);
|
||||||
* outside the scope of a single function, so better be safe than
|
free(group->group.strips);
|
||||||
* sorry */
|
free(group->group.rings);
|
||||||
wl_list_remove(&group->group.link);
|
wl_list_remove(&group->group.link);
|
||||||
|
|
||||||
free(group);
|
free(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,12 +293,13 @@ static const struct zwp_tablet_pad_group_v2_listener tablet_pad_group_listener =
|
||||||
static void handle_tablet_pad_group(void *data,
|
static void handle_tablet_pad_group(void *data,
|
||||||
struct zwp_tablet_pad_v2 *zwp_tablet_pad,
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad,
|
||||||
struct zwp_tablet_pad_group_v2 *pad_group) {
|
struct zwp_tablet_pad_group_v2 *pad_group) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_tablet_pad *pad = dev->wlr_input_device.tablet_pad;
|
struct wlr_tablet_pad *pad = &seat->wlr_tablet_pad;
|
||||||
|
|
||||||
struct wlr_wl_tablet_pad_group *group =
|
struct tablet_pad_group *group =
|
||||||
calloc(1, sizeof(struct wlr_wl_tablet_pad_group));
|
calloc(1, sizeof(struct tablet_pad_group));
|
||||||
if (!group) {
|
if (!group) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "failed to allocate tablet_pad_group");
|
||||||
zwp_tablet_pad_group_v2_destroy(pad_group);
|
zwp_tablet_pad_group_v2_destroy(pad_group);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -330,20 +316,18 @@ static void handle_tablet_pad_group(void *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_path(void *data,
|
static void handle_tablet_pad_path(void *data,
|
||||||
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, const char *path) {
|
||||||
const char *path) {
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_tablet_pad *tablet_pad = &seat->wlr_tablet_pad;
|
||||||
struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad;
|
|
||||||
|
|
||||||
char **dst = wl_array_add(&tablet_pad->paths, sizeof(char *));
|
char **dst = wl_array_add(&tablet_pad->paths, sizeof(char *));
|
||||||
*dst = strdup(path);
|
*dst = strdup(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_buttons(void *data,
|
static void handle_tablet_pad_buttons(void *data,
|
||||||
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2, uint32_t buttons) {
|
||||||
uint32_t buttons) {
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_tablet_pad *tablet_pad = &seat->wlr_tablet_pad;
|
||||||
struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad;
|
|
||||||
|
|
||||||
tablet_pad->button_count = buttons;
|
tablet_pad->button_count = buttons;
|
||||||
}
|
}
|
||||||
|
|
@ -351,10 +335,8 @@ static void handle_tablet_pad_buttons(void *data,
|
||||||
static void handle_tablet_pad_button(void *data,
|
static void handle_tablet_pad_button(void *data,
|
||||||
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
|
||||||
uint32_t time, uint32_t button, uint32_t state) {
|
uint32_t time, uint32_t button, uint32_t state) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad;
|
struct wlr_tablet_pad_button_event evt = {
|
||||||
|
|
||||||
struct wlr_event_tablet_pad_button evt = {
|
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.button = button,
|
.button = button,
|
||||||
.state = state,
|
.state = state,
|
||||||
|
|
@ -362,28 +344,25 @@ static void handle_tablet_pad_button(void *data,
|
||||||
.group = 0,
|
.group = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr_signal_emit_safe(&tablet_pad->events.button, &evt);
|
wl_signal_emit_mutable(&seat->wlr_tablet_pad.events.button, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_done(void *data,
|
static void handle_tablet_pad_done(void *data,
|
||||||
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) {
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
|
wl_signal_emit_mutable(&seat->backend->backend.events.new_input,
|
||||||
wlr_signal_emit_safe(&dev->backend->backend.events.new_input,
|
&seat->wlr_tablet_pad.base);
|
||||||
&dev->wlr_input_device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_enter(void *data,
|
static void handle_tablet_pad_enter(void *data,
|
||||||
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2,
|
||||||
uint32_t serial, struct zwp_tablet_v2 *tablet_p,
|
uint32_t serial, struct zwp_tablet_v2 *tablet_p,
|
||||||
struct wl_surface *surface) {
|
struct wl_surface *surface) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad;
|
assert(seat->zwp_tablet_v2 == tablet_p);
|
||||||
struct wlr_wl_input_device *tab_dev = zwp_tablet_v2_get_user_data(tablet_p);
|
|
||||||
struct wlr_input_device *tablet = &tab_dev->wlr_input_device;
|
|
||||||
wlr_log(WLR_DEBUG, "Tablet: %p\n", tablet);
|
|
||||||
|
|
||||||
wlr_signal_emit_safe(&tablet_pad->events.attach_tablet, tablet);
|
wl_signal_emit_mutable(&seat->wlr_tablet_pad.events.attach_tablet,
|
||||||
|
&seat->wlr_tablet_tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_pad_leave(void *data,
|
static void handle_tablet_pad_leave(void *data,
|
||||||
|
|
@ -395,23 +374,17 @@ static void handle_tablet_pad_leave(void *data,
|
||||||
|
|
||||||
static void handle_tablet_pad_removed(void *data,
|
static void handle_tablet_pad_removed(void *data,
|
||||||
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) {
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_tablet_pad *tablet_pad = dev->wlr_input_device.tablet_pad;
|
|
||||||
|
|
||||||
/* This doesn't free anything, but emits the destroy signal */
|
struct wlr_tablet_pad *tablet_pad = &seat->wlr_tablet_pad;
|
||||||
wlr_input_device_destroy(&dev->wlr_input_device);
|
struct tablet_pad_group *group, *it;
|
||||||
/* This is a bit ugly, but we need to remove it from our list */
|
|
||||||
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) {
|
wl_list_for_each_safe(group, it, &tablet_pad->groups, group.link) {
|
||||||
handle_tablet_pad_group_removed(group);
|
destroy_tablet_pad_group(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This frees */
|
wlr_tablet_pad_finish(tablet_pad);
|
||||||
wlr_tablet_pad_destroy(tablet_pad);
|
zwp_tablet_pad_v2_destroy(seat->zwp_tablet_pad_v2);
|
||||||
zwp_tablet_pad_v2_destroy(dev->resource);
|
seat->zwp_tablet_pad_v2 = NULL;
|
||||||
free(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = {
|
static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = {
|
||||||
|
|
@ -425,37 +398,25 @@ static const struct zwp_tablet_pad_v2_listener tablet_pad_listener = {
|
||||||
.removed = handle_tablet_pad_removed,
|
.removed = handle_tablet_pad_removed,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct wlr_tablet_pad_impl tablet_pad_impl = {0};
|
const struct wlr_tablet_pad_impl wl_tablet_pad_impl = {
|
||||||
|
.name = "wl-tablet-pad",
|
||||||
|
};
|
||||||
|
|
||||||
static void handle_pad_added(void *data,
|
static void handle_pad_added(void *data,
|
||||||
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2,
|
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2,
|
||||||
struct zwp_tablet_pad_v2 *id) {
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2) {
|
||||||
wlr_log(WLR_DEBUG, "New tablet pad");
|
|
||||||
struct wlr_wl_seat *seat = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_wl_input_device *dev = create_wl_input_device(
|
if (seat->zwp_tablet_pad_v2 != NULL) {
|
||||||
seat, WLR_INPUT_DEVICE_TABLET_PAD);
|
wlr_log(WLR_ERROR, "zwp_tablet_pad_v2 is already present");
|
||||||
if (!dev) {
|
|
||||||
/* This leaks a couple of server-sent resource ids. iirc this
|
|
||||||
* shouldn't ever be a problem, but it isn't exactly nice
|
|
||||||
* either. */
|
|
||||||
zwp_tablet_pad_v2_destroy(id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->resource = id;
|
seat->zwp_tablet_pad_v2 = zwp_tablet_pad_v2;
|
||||||
struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
|
zwp_tablet_pad_v2_add_listener(zwp_tablet_pad_v2, &tablet_pad_listener,
|
||||||
wlr_dev->tablet_pad = calloc(1, sizeof(*wlr_dev->tablet_pad));
|
seat);
|
||||||
|
|
||||||
if (!wlr_dev->tablet_pad) {
|
wlr_tablet_pad_init(&seat->wlr_tablet_pad, &wl_tablet_pad_impl,
|
||||||
/* This leaks a couple of server-sent resource ids. iirc this
|
"wlr_tablet_v2");
|
||||||
* shouldn't ever be a problem, but it isn't exactly nice
|
|
||||||
* either. */
|
|
||||||
free(dev);
|
|
||||||
zwp_tablet_pad_v2_destroy(id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_done(void *data,
|
static void handle_tablet_tool_done(void *data,
|
||||||
|
|
@ -463,7 +424,8 @@ static void handle_tablet_tool_done(void *data,
|
||||||
/* empty */
|
/* empty */
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum wlr_tablet_tool_type tablet_type_to_wlr_type(enum zwp_tablet_tool_v2_type type) {
|
static enum wlr_tablet_tool_type tablet_type_to_wlr_type(
|
||||||
|
enum zwp_tablet_tool_v2_type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ZWP_TABLET_TOOL_V2_TYPE_PEN:
|
case ZWP_TABLET_TOOL_V2_TYPE_PEN:
|
||||||
return WLR_TABLET_TOOL_TYPE_PEN;
|
return WLR_TABLET_TOOL_TYPE_PEN;
|
||||||
|
|
@ -488,94 +450,85 @@ static enum wlr_tablet_tool_type tablet_type_to_wlr_type(enum zwp_tablet_tool_v2
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_type(void *data,
|
static void handle_tablet_tool_type(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id, uint32_t tool_type) {
|
||||||
uint32_t tool_type) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct wlr_tablet_tool *wlr_tool = &tool->seat->wlr_tablet_tool;
|
||||||
|
wlr_tool->type = tablet_type_to_wlr_type(tool_type);
|
||||||
tool->wlr_tool.type = tablet_type_to_wlr_type(tool_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_serial(void *data,
|
static void handle_tablet_tool_serial(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id, uint32_t high, uint32_t low) {
|
||||||
uint32_t high, uint32_t low) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct wlr_tablet_tool *wlr_tool = &tool->seat->wlr_tablet_tool;
|
||||||
|
wlr_tool->hardware_serial = ((uint64_t) high) << 32 | (uint64_t) low;
|
||||||
tool->wlr_tool.hardware_serial =
|
|
||||||
((uint64_t) high) << 32 | (uint64_t) low;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_id_wacom(void *data,
|
static void handle_tablet_tool_id_wacom(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id, uint32_t high, uint32_t low) {
|
||||||
uint32_t high, uint32_t low) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct wlr_tablet_tool *wlr_tool = &tool->seat->wlr_tablet_tool;
|
||||||
|
wlr_tool->hardware_wacom = ((uint64_t) high) << 32 | (uint64_t) low;
|
||||||
tool->wlr_tool.hardware_wacom =
|
|
||||||
((uint64_t) high) << 32 | (uint64_t) low;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_capability(void *data,
|
static void handle_tablet_tool_capability(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id, uint32_t capability) {
|
||||||
uint32_t capability) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct wlr_tablet_tool *wlr_tool = &tool->seat->wlr_tablet_tool;
|
||||||
|
|
||||||
enum zwp_tablet_tool_v2_capability cap = capability;
|
/* One event is sent for each capability */
|
||||||
|
switch (capability) {
|
||||||
switch (cap) {
|
|
||||||
case ZWP_TABLET_TOOL_V2_CAPABILITY_TILT:
|
case ZWP_TABLET_TOOL_V2_CAPABILITY_TILT:
|
||||||
tool->wlr_tool.tilt = true;
|
wlr_tool->tilt = true;
|
||||||
break;
|
break;
|
||||||
case ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE:
|
case ZWP_TABLET_TOOL_V2_CAPABILITY_PRESSURE:
|
||||||
tool->wlr_tool.pressure = true;
|
wlr_tool->pressure = true;
|
||||||
break;
|
break;
|
||||||
case ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE:
|
case ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE:
|
||||||
tool->wlr_tool.distance = true;
|
wlr_tool->distance = true;
|
||||||
break;
|
break;
|
||||||
case ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION:
|
case ZWP_TABLET_TOOL_V2_CAPABILITY_ROTATION:
|
||||||
tool->wlr_tool.rotation = true;
|
wlr_tool->rotation = true;
|
||||||
break;
|
break;
|
||||||
case ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER:
|
case ZWP_TABLET_TOOL_V2_CAPABILITY_SLIDER:
|
||||||
tool->wlr_tool.slider = true;
|
wlr_tool->slider = true;
|
||||||
break;
|
break;
|
||||||
case ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL:
|
case ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL:
|
||||||
tool->wlr_tool.wheel = true;
|
wlr_tool->wheel = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_proximity_in(void *data,
|
static void handle_tablet_tool_proximity_in(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id, uint32_t serial,
|
struct zwp_tablet_tool_v2 *id, uint32_t serial,
|
||||||
struct zwp_tablet_v2 *tablet_id,
|
struct zwp_tablet_v2 *tablet_id, struct wl_surface *surface) {
|
||||||
struct wl_surface *surface) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
assert(tablet_id == tool->seat->zwp_tablet_v2);
|
||||||
|
|
||||||
tool->is_in = true;
|
tool->is_in = true;
|
||||||
tool->tablet = zwp_tablet_v2_get_user_data(tablet_id);
|
|
||||||
tool->output = wl_surface_get_user_data(surface);
|
tool->output = wl_surface_get_user_data(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_proximity_out(void *data,
|
static void handle_tablet_tool_proximity_out(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id) {
|
struct zwp_tablet_tool_v2 *id) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
tool->is_out = true;
|
tool->is_out = true;
|
||||||
tool->output = NULL;
|
tool->output = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_down(void *data,
|
static void handle_tablet_tool_down(void *data, struct zwp_tablet_tool_v2 *id,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
|
||||||
unsigned int serial) {
|
unsigned int serial) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
tool->is_down = true;
|
tool->is_down = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_up(void *data,
|
static void handle_tablet_tool_up(void *data, struct zwp_tablet_tool_v2 *id) {
|
||||||
struct zwp_tablet_tool_v2 *id) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
|
||||||
tool->is_up = true;
|
tool->is_up = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_motion(void *data,
|
static void handle_tablet_tool_motion(void *data, struct zwp_tablet_tool_v2 *id,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
|
||||||
wl_fixed_t x, wl_fixed_t y) {
|
wl_fixed_t x, wl_fixed_t y) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_output *output = tool->output;
|
struct wlr_wl_output *output = tool->output;
|
||||||
assert(output);
|
assert(output);
|
||||||
|
|
||||||
|
|
@ -584,68 +537,63 @@ static void handle_tablet_tool_motion(void *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_pressure(void *data,
|
static void handle_tablet_tool_pressure(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id, uint32_t pressure) {
|
||||||
uint32_t pressure) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
|
||||||
tool->pressure = (double) pressure / 65535.0;
|
tool->pressure = (double) pressure / 65535.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_distance(void *data,
|
static void handle_tablet_tool_distance(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id, uint32_t distance) {
|
||||||
uint32_t distance) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
|
||||||
tool->distance = (double) distance / 65535.0;
|
tool->distance = (double) distance / 65535.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_tilt(void *data,
|
static void handle_tablet_tool_tilt(void *data, struct zwp_tablet_tool_v2 *id,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
|
||||||
wl_fixed_t x, wl_fixed_t y) {
|
wl_fixed_t x, wl_fixed_t y) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
tool->tilt_x = wl_fixed_to_double(x);
|
tool->tilt_x = wl_fixed_to_double(x);
|
||||||
tool->tilt_y = wl_fixed_to_double(y);
|
tool->tilt_y = wl_fixed_to_double(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_rotation(void *data,
|
static void handle_tablet_tool_rotation(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id, wl_fixed_t rotation) {
|
||||||
wl_fixed_t rotation) {
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
|
||||||
tool->rotation = wl_fixed_to_double(rotation);
|
tool->rotation = wl_fixed_to_double(rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_slider(void *data,
|
static void handle_tablet_tool_slider(void *data, struct zwp_tablet_tool_v2 *id,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
|
||||||
int slider) {
|
int slider) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
tool->slider = (double) slider / 65535.0;;
|
tool->slider = (double) slider / 65535.0;;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This looks wrong :/
|
// TODO: This looks wrong :/
|
||||||
static void handle_tablet_tool_wheel(void *data,
|
static void handle_tablet_tool_wheel(void *data, struct zwp_tablet_tool_v2 *id,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
|
||||||
wl_fixed_t degree, int clicks) {
|
wl_fixed_t degree, int clicks) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
tool->wheel_delta = wl_fixed_to_double(degree);
|
tool->wheel_delta = wl_fixed_to_double(degree);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_tool_button(void *data,
|
static void handle_tablet_tool_button(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id,
|
||||||
uint32_t serial, uint32_t button, uint32_t state) {
|
uint32_t serial, uint32_t button, uint32_t state) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
struct wlr_tablet *tablet = tool->tablet->wlr_input_device.tablet;
|
struct wlr_wl_seat *seat = tool->seat;
|
||||||
|
struct wlr_tablet *tablet = &seat->wlr_tablet;
|
||||||
|
|
||||||
struct wlr_event_tablet_tool_button evt = {
|
struct wlr_tablet_tool_button_event evt = {
|
||||||
.device = &tool->tablet->wlr_input_device,
|
.tablet = tablet,
|
||||||
.tool = &tool->wlr_tool,
|
.tool = &seat->wlr_tablet_tool,
|
||||||
.time_msec = get_current_time_msec(),
|
.time_msec = get_current_time_msec(),
|
||||||
.button = button,
|
.button = button,
|
||||||
.state = state == ZWP_TABLET_TOOL_V2_BUTTON_STATE_RELEASED ?
|
.state = state == ZWP_TABLET_TOOL_V2_BUTTON_STATE_RELEASED ?
|
||||||
WLR_BUTTON_RELEASED : WLR_BUTTON_PRESSED,
|
WLR_BUTTON_RELEASED : WLR_BUTTON_PRESSED,
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr_signal_emit_safe(&tablet->events.button, &evt);
|
wl_signal_emit_mutable(&tablet->events.button, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_tablet_tool_values(struct wlr_wl_tablet_tool *tool) {
|
static void clear_tablet_tool_values(struct tablet_tool *tool) {
|
||||||
tool->is_out = tool->is_in = false;
|
tool->is_out = tool->is_in = false;
|
||||||
tool->is_up = tool->is_down = false;
|
tool->is_up = tool->is_down = false;
|
||||||
tool->x = tool->y = NAN;
|
tool->x = tool->y = NAN;
|
||||||
|
|
@ -660,31 +608,33 @@ static void clear_tablet_tool_values(struct wlr_wl_tablet_tool *tool) {
|
||||||
static void handle_tablet_tool_frame(void *data,
|
static void handle_tablet_tool_frame(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id,
|
struct zwp_tablet_tool_v2 *id,
|
||||||
uint32_t time) {
|
uint32_t time) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
|
struct wlr_wl_seat *seat = tool->seat;
|
||||||
|
|
||||||
if (tool->is_out && tool->is_in) {
|
if (tool->is_out && tool->is_in) {
|
||||||
/* we got a tablet tool coming in and out of proximity before
|
/* we got a tablet tool coming in and out of proximity before
|
||||||
* we could process it. Just ignore anything it did */
|
* we could process it. Just ignore anything it did */
|
||||||
goto clear_values;
|
goto clear_values;
|
||||||
}
|
}
|
||||||
struct wlr_tablet *tablet = tool->tablet->wlr_input_device.tablet;
|
struct wlr_tablet *tablet = &seat->wlr_tablet;
|
||||||
|
|
||||||
if (tool->is_in) {
|
if (tool->is_in) {
|
||||||
struct wlr_event_tablet_tool_proximity evt = {
|
struct wlr_tablet_tool_proximity_event evt = {
|
||||||
.device = &tool->tablet->wlr_input_device,
|
.tablet = tablet,
|
||||||
.tool = &tool->wlr_tool,
|
.tool = &seat->wlr_tablet_tool,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.x = tool->x,
|
.x = tool->x,
|
||||||
.y = tool->y,
|
.y = tool->y,
|
||||||
.state = WLR_TABLET_TOOL_PROXIMITY_IN,
|
.state = WLR_TABLET_TOOL_PROXIMITY_IN,
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr_signal_emit_safe(&tablet->events.proximity, &evt);
|
wl_signal_emit_mutable(&tablet->events.proximity, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
struct wlr_event_tablet_tool_axis evt = {
|
struct wlr_tablet_tool_axis_event evt = {
|
||||||
.device = &tool->tablet->wlr_input_device,
|
.tablet = tablet,
|
||||||
.tool = &tool->wlr_tool,
|
.tool = &seat->wlr_tablet_tool,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.updated_axes = 0,
|
.updated_axes = 0,
|
||||||
};
|
};
|
||||||
|
|
@ -735,7 +685,7 @@ static void handle_tablet_tool_frame(void *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt.updated_axes) {
|
if (evt.updated_axes) {
|
||||||
wlr_signal_emit_safe(&tablet->events.axis, &evt);
|
wl_signal_emit_mutable(&tablet->events.axis, &evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -745,42 +695,42 @@ static void handle_tablet_tool_frame(void *data,
|
||||||
* Downside: Here we have the frame time, if we sent right away, we
|
* Downside: Here we have the frame time, if we sent right away, we
|
||||||
* need to generate the time */
|
* need to generate the time */
|
||||||
if (tool->is_down) {
|
if (tool->is_down) {
|
||||||
struct wlr_event_tablet_tool_tip evt = {
|
struct wlr_tablet_tool_tip_event evt = {
|
||||||
.device = &tool->tablet->wlr_input_device,
|
.tablet = tablet,
|
||||||
.tool = &tool->wlr_tool,
|
.tool = &seat->wlr_tablet_tool,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.x = tool->x,
|
.x = tool->x,
|
||||||
.y = tool->y,
|
.y = tool->y,
|
||||||
.state = WLR_TABLET_TOOL_TIP_DOWN,
|
.state = WLR_TABLET_TOOL_TIP_DOWN,
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr_signal_emit_safe(&tablet->events.tip, &evt);
|
wl_signal_emit_mutable(&tablet->events.tip, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tool->is_up) {
|
if (tool->is_up) {
|
||||||
struct wlr_event_tablet_tool_tip evt = {
|
struct wlr_tablet_tool_tip_event evt = {
|
||||||
.device = &tool->tablet->wlr_input_device,
|
.tablet = tablet,
|
||||||
.tool = &tool->wlr_tool,
|
.tool = &seat->wlr_tablet_tool,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.x = tool->x,
|
.x = tool->x,
|
||||||
.y = tool->y,
|
.y = tool->y,
|
||||||
.state = WLR_TABLET_TOOL_TIP_UP,
|
.state = WLR_TABLET_TOOL_TIP_UP,
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr_signal_emit_safe(&tablet->events.tip, &evt);
|
wl_signal_emit_mutable(&tablet->events.tip, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tool->is_out) {
|
if (tool->is_out) {
|
||||||
struct wlr_event_tablet_tool_proximity evt = {
|
struct wlr_tablet_tool_proximity_event evt = {
|
||||||
.device = &tool->tablet->wlr_input_device,
|
.tablet = tablet,
|
||||||
.tool = &tool->wlr_tool,
|
.tool = &seat->wlr_tablet_tool,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.x = tool->x,
|
.x = tool->x,
|
||||||
.y = tool->y,
|
.y = tool->y,
|
||||||
.state = WLR_TABLET_TOOL_PROXIMITY_OUT,
|
.state = WLR_TABLET_TOOL_PROXIMITY_OUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
wlr_signal_emit_safe(&tablet->events.proximity, &evt);
|
wl_signal_emit_mutable(&tablet->events.proximity, &evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_values:
|
clear_values:
|
||||||
|
|
@ -789,10 +739,12 @@ clear_values:
|
||||||
|
|
||||||
static void handle_tablet_tool_removed(void *data,
|
static void handle_tablet_tool_removed(void *data,
|
||||||
struct zwp_tablet_tool_v2 *id) {
|
struct zwp_tablet_tool_v2 *id) {
|
||||||
struct wlr_wl_tablet_tool *tool = data;
|
struct tablet_tool *tool = data;
|
||||||
|
struct wlr_wl_seat *seat = tool->seat;
|
||||||
|
|
||||||
|
zwp_tablet_tool_v2_destroy(seat->zwp_tablet_tool_v2);
|
||||||
|
seat->zwp_tablet_tool_v2 = NULL;
|
||||||
|
|
||||||
zwp_tablet_tool_v2_destroy(tool->tool);
|
|
||||||
wlr_signal_emit_safe(&tool->wlr_tool.events.destroy, &tool->wlr_tool);
|
|
||||||
free(tool);
|
free(tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -822,62 +774,71 @@ static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
|
||||||
|
|
||||||
static void handle_tool_added(void *data,
|
static void handle_tool_added(void *data,
|
||||||
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2,
|
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2,
|
||||||
struct zwp_tablet_tool_v2 *id) {
|
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2) {
|
||||||
wlr_log(WLR_DEBUG, "New tablet tool");
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_wl_tablet_tool *tool = calloc(1, sizeof(*tool));
|
if (seat->zwp_tablet_tool_v2 != NULL) {
|
||||||
if (!tool) {
|
wlr_log(WLR_ERROR, "zwp_tablet_tool_v2 already present");
|
||||||
zwp_tablet_tool_v2_destroy(id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tool->tool = id;
|
|
||||||
|
wl_signal_init(&seat->wlr_tablet_tool.events.destroy);
|
||||||
|
|
||||||
|
struct tablet_tool *tool = calloc(1, sizeof(struct tablet_tool));
|
||||||
|
if (tool == NULL) {
|
||||||
|
wlr_log_errno(WLR_ERROR, "failed to allocate tablet_tool");
|
||||||
|
zwp_tablet_tool_v2_destroy(zwp_tablet_tool_v2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tool->seat = seat;
|
||||||
clear_tablet_tool_values(tool);
|
clear_tablet_tool_values(tool);
|
||||||
wl_signal_init(&tool->wlr_tool.events.destroy);
|
|
||||||
zwp_tablet_tool_v2_add_listener(id, &tablet_tool_listener, tool);
|
seat->zwp_tablet_tool_v2 = zwp_tablet_tool_v2;
|
||||||
|
zwp_tablet_tool_v2_add_listener(seat->zwp_tablet_tool_v2, &tablet_tool_listener,
|
||||||
|
tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_name(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
|
static void handle_tablet_name(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
|
||||||
const char *name) {
|
const char *name) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_tablet *tablet = dev->wlr_input_device.tablet;
|
struct wlr_tablet *tablet = &seat->wlr_tablet;
|
||||||
|
|
||||||
free(tablet->name);
|
free(tablet->base.name);
|
||||||
tablet->name = strdup(name);
|
tablet->base.name = strdup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_id(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
|
static void handle_tablet_id(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
|
||||||
uint32_t vid, uint32_t pid) {
|
uint32_t vid, uint32_t pid) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
dev->wlr_input_device.vendor = vid;
|
struct wlr_tablet *tablet = &seat->wlr_tablet;
|
||||||
dev->wlr_input_device.product = pid;
|
|
||||||
|
tablet->base.vendor = vid;
|
||||||
|
tablet->base.product = pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_path(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
|
static void handle_tablet_path(void *data, struct zwp_tablet_v2 *zwp_tablet_v2,
|
||||||
const char *path) {
|
const char *path) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_tablet *tablet = dev->wlr_input_device.tablet;
|
struct wlr_tablet *tablet = &seat->wlr_tablet;
|
||||||
|
|
||||||
char **dst = wl_array_add(&tablet->paths, sizeof(char *));
|
char **dst = wl_array_add(&tablet->paths, sizeof(char *));
|
||||||
*dst = strdup(path);
|
*dst = strdup(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_done(void *data, struct zwp_tablet_v2 *zwp_tablet_v2) {
|
static void handle_tablet_done(void *data, struct zwp_tablet_v2 *zwp_tablet_v2) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
|
|
||||||
wlr_signal_emit_safe(&dev->backend->backend.events.new_input,
|
wl_signal_emit_mutable(&seat->backend->backend.events.new_input,
|
||||||
&dev->wlr_input_device);
|
&seat->wlr_tablet.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_tablet_removed(void *data,
|
static void handle_tablet_removed(void *data,
|
||||||
struct zwp_tablet_v2 *zwp_tablet_v2) {
|
struct zwp_tablet_v2 *zwp_tablet_v2) {
|
||||||
struct wlr_wl_input_device *dev = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
|
|
||||||
/* This doesn't free anything, but emits the destroy signal */
|
wlr_tablet_finish(&seat->wlr_tablet);
|
||||||
wlr_input_device_destroy(&dev->wlr_input_device);
|
zwp_tablet_v2_destroy(seat->zwp_tablet_v2);
|
||||||
/* This is a bit ugly, but we need to remove it from our list */
|
seat->zwp_tablet_v2 = NULL;
|
||||||
wl_list_remove(&dev->link);
|
|
||||||
|
|
||||||
zwp_tablet_v2_destroy(dev->resource);
|
|
||||||
free(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct zwp_tablet_v2_listener tablet_listener = {
|
static const struct zwp_tablet_v2_listener tablet_listener = {
|
||||||
|
|
@ -888,32 +849,23 @@ static const struct zwp_tablet_v2_listener tablet_listener = {
|
||||||
.removed = handle_tablet_removed,
|
.removed = handle_tablet_removed,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct wlr_tablet_impl tablet_impl = {0};
|
const struct wlr_tablet_impl wl_tablet_impl = {
|
||||||
|
.name = "wl-tablet-tool",
|
||||||
|
};
|
||||||
|
|
||||||
static void handle_tab_added(void *data,
|
static void handle_tab_added(void *data,
|
||||||
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2,
|
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2,
|
||||||
struct zwp_tablet_v2 *id) {
|
struct zwp_tablet_v2 *zwp_tablet_v2) {
|
||||||
wlr_log(WLR_DEBUG, "New tablet");
|
|
||||||
struct wlr_wl_seat *seat = data;
|
struct wlr_wl_seat *seat = data;
|
||||||
struct wlr_wl_input_device *dev = create_wl_input_device(
|
if (seat->zwp_tablet_v2 != NULL) {
|
||||||
seat, WLR_INPUT_DEVICE_TABLET_TOOL);
|
wlr_log(WLR_ERROR, "zwp_tablet_v2 already present");
|
||||||
|
|
||||||
if (!dev) {
|
|
||||||
zwp_tablet_v2_destroy(id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dev->resource = id;
|
|
||||||
|
|
||||||
struct wlr_input_device *wlr_dev = &dev->wlr_input_device;
|
seat->zwp_tablet_v2 = zwp_tablet_v2;
|
||||||
wlr_dev->tablet = calloc(1, sizeof(*wlr_dev->tablet));
|
zwp_tablet_v2_add_listener(zwp_tablet_v2, &tablet_listener, seat);
|
||||||
|
|
||||||
if (!wlr_dev->tablet) {
|
wlr_tablet_init(&seat->wlr_tablet, &wl_tablet_impl, "wlr_tablet_v2");
|
||||||
zwp_tablet_v2_destroy(id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
zwp_tablet_v2_set_user_data(id, wlr_dev->tablet);
|
|
||||||
wlr_tablet_init(wlr_dev->tablet, &tablet_impl, wlr_dev->name);
|
|
||||||
zwp_tablet_v2_add_listener(id, &tablet_listener, dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
|
static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
|
||||||
|
|
@ -922,20 +874,55 @@ static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
|
||||||
.pad_added = handle_pad_added,
|
.pad_added = handle_pad_added,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_wl_tablet_seat *wl_add_tablet_seat(
|
void init_seat_tablet(struct wlr_wl_seat *seat) {
|
||||||
struct zwp_tablet_manager_v2 *manager,
|
struct zwp_tablet_manager_v2 *manager = seat->backend->tablet_manager;
|
||||||
struct wlr_wl_seat *seat) {
|
assert(manager);
|
||||||
struct wlr_wl_tablet_seat *ret =
|
|
||||||
calloc(1, sizeof(struct wlr_wl_tablet_seat));
|
|
||||||
|
|
||||||
if (!(ret->tablet_seat =
|
/**
|
||||||
zwp_tablet_manager_v2_get_tablet_seat(manager, seat->wl_seat))) {
|
* TODO: multi tablet support
|
||||||
free(ret);
|
* The wlr_wl_seat should support multiple tablet_v2 devices, but for
|
||||||
return NULL;
|
* the sake of simplicity, it supports only one device of each.
|
||||||
|
* If this is a feature you want/need, please open an issue on the wlroots
|
||||||
|
* tracker here https://gitlab.freedesktop.org/wlroots/wlroots/-/issues
|
||||||
|
*/
|
||||||
|
|
||||||
|
seat->zwp_tablet_seat_v2 =
|
||||||
|
zwp_tablet_manager_v2_get_tablet_seat(manager, seat->wl_seat);
|
||||||
|
if (seat->zwp_tablet_seat_v2 == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "failed to get zwp_tablet_manager_v2 from seat '%s'",
|
||||||
|
seat->name);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
zwp_tablet_seat_v2_add_listener(ret->tablet_seat,
|
zwp_tablet_seat_v2_add_listener(seat->zwp_tablet_seat_v2,
|
||||||
&tablet_seat_listener, seat);
|
&tablet_seat_listener, seat);
|
||||||
|
}
|
||||||
return ret;
|
|
||||||
|
void finish_seat_tablet(struct wlr_wl_seat *seat) {
|
||||||
|
if (seat->zwp_tablet_v2 != NULL) {
|
||||||
|
wlr_tablet_finish(&seat->wlr_tablet);
|
||||||
|
zwp_tablet_v2_destroy(seat->zwp_tablet_v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat->zwp_tablet_tool_v2 != NULL) {
|
||||||
|
struct tablet_tool *tool =
|
||||||
|
zwp_tablet_tool_v2_get_user_data(seat->zwp_tablet_tool_v2);
|
||||||
|
free(tool);
|
||||||
|
|
||||||
|
zwp_tablet_tool_v2_destroy(seat->zwp_tablet_tool_v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat->zwp_tablet_pad_v2 != NULL) {
|
||||||
|
struct wlr_tablet_pad *tablet_pad = &seat->wlr_tablet_pad;
|
||||||
|
struct tablet_pad_group *group, *it;
|
||||||
|
wl_list_for_each_safe(group, it, &tablet_pad->groups, group.link) {
|
||||||
|
destroy_tablet_pad_group(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_tablet_pad_finish(tablet_pad);
|
||||||
|
zwp_tablet_pad_v2_destroy(seat->zwp_tablet_pad_v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
zwp_tablet_seat_v2_destroy(seat->zwp_tablet_seat_v2);
|
||||||
|
seat->zwp_tablet_seat_v2 = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include "backend/x11.h"
|
#include "backend/x11.h"
|
||||||
#include "render/drm_format_set.h"
|
#include "render/drm_format_set.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
// See dri2_format_for_depth in mesa
|
// See dri2_format_for_depth in mesa
|
||||||
const struct wlr_x11_format formats[] = {
|
const struct wlr_x11_format formats[] = {
|
||||||
|
|
@ -164,7 +163,7 @@ static bool backend_start(struct wlr_backend *backend) {
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "Starting X11 backend");
|
wlr_log(WLR_INFO, "Starting X11 backend");
|
||||||
|
|
||||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &x11->keyboard.base);
|
wl_signal_emit_mutable(&x11->backend.events.new_input, &x11->keyboard.base);
|
||||||
|
|
||||||
for (size_t i = 0; i < x11->requested_outputs; ++i) {
|
for (size_t i = 0; i < x11->requested_outputs; ++i) {
|
||||||
wlr_x11_output_create(&x11->backend);
|
wlr_x11_output_create(&x11->backend);
|
||||||
|
|
@ -185,7 +184,7 @@ static void backend_destroy(struct wlr_backend *backend) {
|
||||||
wlr_output_destroy(&output->wlr_output);
|
wlr_output_destroy(&output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_keyboard_destroy(&x11->keyboard);
|
wlr_keyboard_finish(&x11->keyboard);
|
||||||
|
|
||||||
wlr_backend_finish(backend);
|
wlr_backend_finish(backend);
|
||||||
|
|
||||||
|
|
@ -637,7 +636,8 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wlr_keyboard_init(&x11->keyboard, &x11_keyboard_impl, "x11-keyboard");
|
wlr_keyboard_init(&x11->keyboard, &x11_keyboard_impl,
|
||||||
|
x11_keyboard_impl.name);
|
||||||
|
|
||||||
x11->display_destroy.notify = handle_display_destroy;
|
x11->display_destroy.notify = handle_display_destroy;
|
||||||
wl_display_add_destroy_listener(display, &x11->display_destroy);
|
wl_display_add_destroy_listener(display, &x11->display_destroy);
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,10 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
#include "backend/x11.h"
|
#include "backend/x11.h"
|
||||||
#include "util/signal.h"
|
|
||||||
|
|
||||||
static void send_key_event(struct wlr_x11_backend *x11, uint32_t key,
|
static void send_key_event(struct wlr_x11_backend *x11, uint32_t key,
|
||||||
enum wl_keyboard_key_state st, xcb_timestamp_t time) {
|
enum wl_keyboard_key_state st, xcb_timestamp_t time) {
|
||||||
struct wlr_event_keyboard_key ev = {
|
struct wlr_keyboard_key_event ev = {
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.keycode = key,
|
.keycode = key,
|
||||||
.state = st,
|
.state = st,
|
||||||
|
|
@ -31,20 +30,20 @@ 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,
|
static void send_button_event(struct wlr_x11_output *output, uint32_t key,
|
||||||
enum wlr_button_state st, xcb_timestamp_t time) {
|
enum wlr_button_state st, xcb_timestamp_t time) {
|
||||||
struct wlr_event_pointer_button ev = {
|
struct wlr_pointer_button_event ev = {
|
||||||
.device = &output->pointer.base,
|
.pointer = &output->pointer,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.button = key,
|
.button = key,
|
||||||
.state = st,
|
.state = st,
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&output->pointer.events.button, &ev);
|
wl_signal_emit_mutable(&output->pointer.events.button, &ev);
|
||||||
wlr_signal_emit_safe(&output->pointer.events.frame, &output->pointer);
|
wl_signal_emit_mutable(&output->pointer.events.frame, &output->pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_axis_event(struct wlr_x11_output *output, int32_t delta,
|
static void send_axis_event(struct wlr_x11_output *output, int32_t delta,
|
||||||
xcb_timestamp_t time) {
|
xcb_timestamp_t time) {
|
||||||
struct wlr_event_pointer_axis ev = {
|
struct wlr_pointer_axis_event ev = {
|
||||||
.device = &output->pointer.base,
|
.pointer = &output->pointer,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.source = WLR_AXIS_SOURCE_WHEEL,
|
.source = WLR_AXIS_SOURCE_WHEEL,
|
||||||
.orientation = WLR_AXIS_ORIENTATION_VERTICAL,
|
.orientation = WLR_AXIS_ORIENTATION_VERTICAL,
|
||||||
|
|
@ -52,57 +51,57 @@ static void send_axis_event(struct wlr_x11_output *output, int32_t delta,
|
||||||
.delta = delta * 15,
|
.delta = delta * 15,
|
||||||
.delta_discrete = delta,
|
.delta_discrete = delta,
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&output->pointer.events.axis, &ev);
|
wl_signal_emit_mutable(&output->pointer.events.axis, &ev);
|
||||||
wlr_signal_emit_safe(&output->pointer.events.frame, &output->pointer);
|
wl_signal_emit_mutable(&output->pointer.events.frame, &output->pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_pointer_position_event(struct wlr_x11_output *output,
|
static void send_pointer_position_event(struct wlr_x11_output *output,
|
||||||
int16_t x, int16_t y, xcb_timestamp_t time) {
|
int16_t x, int16_t y, xcb_timestamp_t time) {
|
||||||
struct wlr_event_pointer_motion_absolute ev = {
|
struct wlr_pointer_motion_absolute_event ev = {
|
||||||
.device = &output->pointer.base,
|
.pointer = &output->pointer,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.x = (double)x / output->wlr_output.width,
|
.x = (double)x / output->wlr_output.width,
|
||||||
.y = (double)y / output->wlr_output.height,
|
.y = (double)y / output->wlr_output.height,
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&output->pointer.events.motion_absolute, &ev);
|
wl_signal_emit_mutable(&output->pointer.events.motion_absolute, &ev);
|
||||||
wlr_signal_emit_safe(&output->pointer.events.frame, &output->pointer);
|
wl_signal_emit_mutable(&output->pointer.events.frame, &output->pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_touch_down_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) {
|
int16_t x, int16_t y, int32_t touch_id, xcb_timestamp_t time) {
|
||||||
struct wlr_event_touch_down ev = {
|
struct wlr_touch_down_event ev = {
|
||||||
.device = &output->touch.base,
|
.touch = &output->touch,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.x = (double)x / output->wlr_output.width,
|
.x = (double)x / output->wlr_output.width,
|
||||||
.y = (double)y / output->wlr_output.height,
|
.y = (double)y / output->wlr_output.height,
|
||||||
.touch_id = touch_id,
|
.touch_id = touch_id,
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&output->touch.events.down, &ev);
|
wl_signal_emit_mutable(&output->touch.events.down, &ev);
|
||||||
wlr_signal_emit_safe(&output->touch.events.frame, NULL);
|
wl_signal_emit_mutable(&output->touch.events.frame, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_touch_motion_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) {
|
int16_t x, int16_t y, int32_t touch_id, xcb_timestamp_t time) {
|
||||||
struct wlr_event_touch_motion ev = {
|
struct wlr_touch_motion_event ev = {
|
||||||
.device = &output->touch.base,
|
.touch = &output->touch,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.x = (double)x / output->wlr_output.width,
|
.x = (double)x / output->wlr_output.width,
|
||||||
.y = (double)y / output->wlr_output.height,
|
.y = (double)y / output->wlr_output.height,
|
||||||
.touch_id = touch_id,
|
.touch_id = touch_id,
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&output->touch.events.motion, &ev);
|
wl_signal_emit_mutable(&output->touch.events.motion, &ev);
|
||||||
wlr_signal_emit_safe(&output->touch.events.frame, NULL);
|
wl_signal_emit_mutable(&output->touch.events.frame, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_touch_up_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) {
|
int32_t touch_id, xcb_timestamp_t time) {
|
||||||
struct wlr_event_touch_up ev = {
|
struct wlr_touch_up_event ev = {
|
||||||
.device = &output->touch.base,
|
.touch = &output->touch,
|
||||||
.time_msec = time,
|
.time_msec = time,
|
||||||
.touch_id = touch_id,
|
.touch_id = touch_id,
|
||||||
};
|
};
|
||||||
wlr_signal_emit_safe(&output->touch.events.up, &ev);
|
wl_signal_emit_mutable(&output->touch.events.up, &ev);
|
||||||
wlr_signal_emit_safe(&output->touch.events.frame, NULL);
|
wl_signal_emit_mutable(&output->touch.events.frame, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_x11_touchpoint *get_touchpoint_from_x11_touch_id(
|
static struct wlr_x11_touchpoint *get_touchpoint_from_x11_touch_id(
|
||||||
|
|
@ -285,28 +284,16 @@ void handle_x11_xinput_event(struct wlr_x11_backend *x11,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_destroy(struct wlr_keyboard *wlr_keyboard) {
|
|
||||||
// Don't free the keyboard, it's on the stack
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct wlr_keyboard_impl x11_keyboard_impl = {
|
const struct wlr_keyboard_impl x11_keyboard_impl = {
|
||||||
.destroy = keyboard_destroy,
|
.name = "x11-keyboard",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pointer_destroy(struct wlr_pointer *wlr_pointer) {
|
|
||||||
// Don't free the pointer, it's on the stack
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct wlr_pointer_impl x11_pointer_impl = {
|
const struct wlr_pointer_impl x11_pointer_impl = {
|
||||||
.destroy = pointer_destroy,
|
.name = "x11-pointer",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void touch_destroy(struct wlr_touch *wlr_touch) {
|
|
||||||
// Don't free the touch, it's on the stack
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct wlr_touch_impl x11_touch_impl = {
|
const struct wlr_touch_impl x11_touch_impl = {
|
||||||
.destroy = touch_destroy,
|
.name = "x11-touch",
|
||||||
};
|
};
|
||||||
|
|
||||||
void update_x11_pointer_position(struct wlr_x11_output *output,
|
void update_x11_pointer_position(struct wlr_x11_output *output,
|
||||||
|
|
@ -329,11 +316,11 @@ void update_x11_pointer_position(struct wlr_x11_output *output,
|
||||||
bool wlr_input_device_is_x11(struct wlr_input_device *wlr_dev) {
|
bool wlr_input_device_is_x11(struct wlr_input_device *wlr_dev) {
|
||||||
switch (wlr_dev->type) {
|
switch (wlr_dev->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||||
return wlr_dev->keyboard->impl == &x11_keyboard_impl;
|
return wlr_keyboard_from_input_device(wlr_dev)->impl == &x11_keyboard_impl;
|
||||||
case WLR_INPUT_DEVICE_POINTER:
|
case WLR_INPUT_DEVICE_POINTER:
|
||||||
return wlr_dev->pointer->impl == &x11_pointer_impl;
|
return wlr_pointer_from_input_device(wlr_dev)->impl == &x11_pointer_impl;
|
||||||
case WLR_INPUT_DEVICE_TOUCH:
|
case WLR_INPUT_DEVICE_TOUCH:
|
||||||
return wlr_dev->touch->impl == &x11_touch_impl;
|
return wlr_touch_from_input_device(wlr_dev)->impl == &x11_touch_impl;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,24 +21,31 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
#include "backend/x11.h"
|
#include "backend/x11.h"
|
||||||
#include "util/signal.h"
|
|
||||||
#include "util/time.h"
|
#include "util/time.h"
|
||||||
|
|
||||||
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
static const uint32_t SUPPORTED_OUTPUT_STATE =
|
||||||
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
|
WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
|
||||||
WLR_OUTPUT_STATE_BUFFER |
|
WLR_OUTPUT_STATE_BUFFER |
|
||||||
WLR_OUTPUT_STATE_MODE;
|
WLR_OUTPUT_STATE_MODE |
|
||||||
|
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED;
|
||||||
|
|
||||||
static void parse_xcb_setup(struct wlr_output *output,
|
static void parse_xcb_setup(struct wlr_output *output,
|
||||||
xcb_connection_t *xcb) {
|
xcb_connection_t *xcb) {
|
||||||
const xcb_setup_t *xcb_setup = xcb_get_setup(xcb);
|
const xcb_setup_t *xcb_setup = xcb_get_setup(xcb);
|
||||||
|
|
||||||
snprintf(output->make, sizeof(output->make), "%.*s",
|
output->make = calloc(1, xcb_setup_vendor_length(xcb_setup) + 1);
|
||||||
xcb_setup_vendor_length(xcb_setup),
|
if (output->make == NULL) {
|
||||||
xcb_setup_vendor(xcb_setup));
|
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||||
snprintf(output->model, sizeof(output->model), "%"PRIu16".%"PRIu16,
|
return;
|
||||||
xcb_setup->protocol_major_version,
|
}
|
||||||
xcb_setup->protocol_minor_version);
|
memcpy(output->make, xcb_setup_vendor(xcb_setup),
|
||||||
|
xcb_setup_vendor_length(xcb_setup));
|
||||||
|
|
||||||
|
char model[64];
|
||||||
|
snprintf(model, sizeof(model), "%"PRIu16".%"PRIu16,
|
||||||
|
xcb_setup->protocol_major_version,
|
||||||
|
xcb_setup->protocol_minor_version);
|
||||||
|
output->model = strdup(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_x11_output *get_x11_output_from_output(
|
static struct wlr_x11_output *get_x11_output_from_output(
|
||||||
|
|
@ -76,8 +83,8 @@ static void output_destroy(struct wlr_output *wlr_output) {
|
||||||
|
|
||||||
pixman_region32_fini(&output->exposed);
|
pixman_region32_fini(&output->exposed);
|
||||||
|
|
||||||
wlr_pointer_destroy(&output->pointer);
|
wlr_pointer_finish(&output->pointer);
|
||||||
wlr_touch_destroy(&output->touch);
|
wlr_touch_finish(&output->touch);
|
||||||
|
|
||||||
struct wlr_x11_buffer *buffer, *buffer_tmp;
|
struct wlr_x11_buffer *buffer, *buffer_tmp;
|
||||||
wl_list_for_each_safe(buffer, buffer_tmp, &output->buffers, link) {
|
wl_list_for_each_safe(buffer, buffer_tmp, &output->buffers, link) {
|
||||||
|
|
@ -97,17 +104,28 @@ static void output_destroy(struct wlr_output *wlr_output) {
|
||||||
free(output);
|
free(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_test(struct wlr_output *wlr_output) {
|
static bool output_test(struct wlr_output *wlr_output,
|
||||||
uint32_t unsupported =
|
const struct wlr_output_state *state) {
|
||||||
wlr_output->pending.committed & ~SUPPORTED_OUTPUT_STATE;
|
uint32_t unsupported = state->committed & ~SUPPORTED_OUTPUT_STATE;
|
||||||
if (unsupported != 0) {
|
if (unsupported != 0) {
|
||||||
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
wlr_log(WLR_DEBUG, "Unsupported output state fields: 0x%"PRIx32,
|
||||||
unsupported);
|
unsupported);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
|
// All we can do to influence adaptive sync on the X11 backend is set the
|
||||||
assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
|
// _VARIABLE_REFRESH window property like mesa automatically does. We don't
|
||||||
|
// have any control beyond that, so we set the state to enabled on creating
|
||||||
|
// the output and never allow changing it (just like the Wayland backend).
|
||||||
|
assert(wlr_output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED);
|
||||||
|
if (state->committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) {
|
||||||
|
if (!state->adaptive_sync_enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->committed & WLR_OUTPUT_STATE_MODE) {
|
||||||
|
assert(state->mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -250,10 +268,11 @@ static struct wlr_x11_buffer *get_or_create_x11_buffer(
|
||||||
return create_x11_buffer(output, wlr_buffer);
|
return create_x11_buffer(output, wlr_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_commit_buffer(struct wlr_x11_output *output) {
|
static bool output_commit_buffer(struct wlr_x11_output *output,
|
||||||
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_x11_backend *x11 = output->x11;
|
struct wlr_x11_backend *x11 = output->x11;
|
||||||
|
|
||||||
struct wlr_buffer *buffer = output->wlr_output.pending.buffer;
|
struct wlr_buffer *buffer = state->buffer;
|
||||||
struct wlr_x11_buffer *x11_buffer =
|
struct wlr_x11_buffer *x11_buffer =
|
||||||
get_or_create_x11_buffer(output, buffer);
|
get_or_create_x11_buffer(output, buffer);
|
||||||
if (!x11_buffer) {
|
if (!x11_buffer) {
|
||||||
|
|
@ -261,8 +280,9 @@ static bool output_commit_buffer(struct wlr_x11_output *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_xfixes_region_t region = XCB_NONE;
|
xcb_xfixes_region_t region = XCB_NONE;
|
||||||
if (output->wlr_output.pending.committed & WLR_OUTPUT_STATE_DAMAGE) {
|
if (state->committed & WLR_OUTPUT_STATE_DAMAGE) {
|
||||||
pixman_region32_union(&output->exposed, &output->exposed, &output->wlr_output.pending.damage);
|
pixman_region32_union(&output->exposed, &output->exposed,
|
||||||
|
(pixman_region32_t *) &state->damage);
|
||||||
|
|
||||||
int rects_len = 0;
|
int rects_len = 0;
|
||||||
pixman_box32_t *rects = pixman_region32_rectangles(&output->exposed, &rects_len);
|
pixman_box32_t *rects = pixman_region32_rectangles(&output->exposed, &rects_len);
|
||||||
|
|
@ -308,40 +328,26 @@ error:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_commit(struct wlr_output *wlr_output) {
|
static bool output_commit(struct wlr_output *wlr_output,
|
||||||
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_x11_output *output = get_x11_output_from_output(wlr_output);
|
struct wlr_x11_output *output = get_x11_output_from_output(wlr_output);
|
||||||
struct wlr_x11_backend *x11 = output->x11;
|
struct wlr_x11_backend *x11 = output->x11;
|
||||||
|
|
||||||
if (!output_test(wlr_output)) {
|
if (!output_test(wlr_output, state)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
|
if (state->committed & WLR_OUTPUT_STATE_MODE) {
|
||||||
if (!output_set_custom_mode(wlr_output,
|
if (!output_set_custom_mode(wlr_output,
|
||||||
wlr_output->pending.custom_mode.width,
|
state->custom_mode.width,
|
||||||
wlr_output->pending.custom_mode.height,
|
state->custom_mode.height,
|
||||||
wlr_output->pending.custom_mode.refresh)) {
|
state->custom_mode.refresh)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED &&
|
if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||||
x11->atoms.variable_refresh != XCB_ATOM_NONE) {
|
if (!output_commit_buffer(output, state)) {
|
||||||
if (wlr_output->pending.adaptive_sync_enabled) {
|
|
||||||
uint32_t enabled = 1;
|
|
||||||
xcb_change_property(x11->xcb, XCB_PROP_MODE_REPLACE, output->win,
|
|
||||||
x11->atoms.variable_refresh, XCB_ATOM_CARDINAL, 32, 1,
|
|
||||||
&enabled);
|
|
||||||
wlr_output->adaptive_sync_status = WLR_OUTPUT_ADAPTIVE_SYNC_UNKNOWN;
|
|
||||||
} else {
|
|
||||||
xcb_delete_property(x11->xcb, output->win,
|
|
||||||
x11->atoms.variable_refresh);
|
|
||||||
wlr_output->adaptive_sync_status = WLR_OUTPUT_ADAPTIVE_SYNC_DISABLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
|
||||||
if (!output_commit_buffer(output)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -564,6 +570,12 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
|
||||||
x11->atoms.wm_protocols, XCB_ATOM_ATOM, 32, 1,
|
x11->atoms.wm_protocols, XCB_ATOM_ATOM, 32, 1,
|
||||||
&x11->atoms.wm_delete_window);
|
&x11->atoms.wm_delete_window);
|
||||||
|
|
||||||
|
uint32_t enabled = 1;
|
||||||
|
xcb_change_property(x11->xcb, XCB_PROP_MODE_REPLACE, output->win,
|
||||||
|
x11->atoms.variable_refresh, XCB_ATOM_CARDINAL, 32, 1,
|
||||||
|
&enabled);
|
||||||
|
wlr_output->adaptive_sync_status = WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED;
|
||||||
|
|
||||||
wlr_x11_output_set_title(wlr_output, NULL);
|
wlr_x11_output_set_title(wlr_output, NULL);
|
||||||
|
|
||||||
xcb_map_window(x11->xcb, output->win);
|
xcb_map_window(x11->xcb, output->win);
|
||||||
|
|
@ -574,15 +586,15 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) {
|
||||||
wlr_output_update_enabled(wlr_output, true);
|
wlr_output_update_enabled(wlr_output, true);
|
||||||
|
|
||||||
wlr_pointer_init(&output->pointer, &x11_pointer_impl, "x11-pointer");
|
wlr_pointer_init(&output->pointer, &x11_pointer_impl, "x11-pointer");
|
||||||
output->pointer.base.output_name = strdup(wlr_output->name);
|
output->pointer.output_name = strdup(wlr_output->name);
|
||||||
|
|
||||||
wlr_touch_init(&output->touch, &x11_touch_impl, "x11-touch");
|
wlr_touch_init(&output->touch, &x11_touch_impl, "x11-touch");
|
||||||
output->touch.base.output_name = strdup(wlr_output->name);
|
output->touch.output_name = strdup(wlr_output->name);
|
||||||
wl_list_init(&output->touchpoints);
|
wl_list_init(&output->touchpoints);
|
||||||
|
|
||||||
wlr_signal_emit_safe(&x11->backend.events.new_output, wlr_output);
|
wl_signal_emit_mutable(&x11->backend.events.new_output, wlr_output);
|
||||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &output->pointer.base);
|
wl_signal_emit_mutable(&x11->backend.events.new_input, &output->pointer.base);
|
||||||
wlr_signal_emit_safe(&x11->backend.events.new_input, &output->touch.base);
|
wl_signal_emit_mutable(&x11->backend.events.new_input, &output->touch.base);
|
||||||
|
|
||||||
// Start the rendering loop by requesting the compositor to render a frame
|
// Start the rendering loop by requesting the compositor to render a frame
|
||||||
wlr_output_schedule_frame(wlr_output);
|
wlr_output_schedule_frame(wlr_output);
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,16 @@ wlroots reads these environment variables
|
||||||
* *WLR_RENDERER_ALLOW_SOFTWARE*: allows the gles2 renderer to use software
|
* *WLR_RENDERER_ALLOW_SOFTWARE*: allows the gles2 renderer to use software
|
||||||
rendering
|
rendering
|
||||||
|
|
||||||
|
## scenes
|
||||||
|
|
||||||
|
* *WLR_SCENE_DEBUG_DAMAGE*: specifies debug options for screen damage related
|
||||||
|
tasks for compositors that use scenes (available options: none, rerender,
|
||||||
|
highlight)
|
||||||
|
* *WLR_SCENE_DISABLE_DIRECT_SCANOUT*: disables direct scan-out for debugging.
|
||||||
|
* *WLR_SCENE_DISABLE_VISIBILITY*: If set to 1, the visibility of all scene nodes
|
||||||
|
will be considered to be the full node. Intelligent visibility canculations will
|
||||||
|
be disabled.
|
||||||
|
|
||||||
# Generic
|
# Generic
|
||||||
|
|
||||||
* *DISPLAY*: if set probe X11 backend in `wlr_backend_autocreate`
|
* *DISPLAY*: if set probe X11 backend in `wlr_backend_autocreate`
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT;
|
||||||
|
|
||||||
const EGLint config_attribs[] = {
|
const EGLint config_attribs[] = {
|
||||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
EGL_RED_SIZE, 1,
|
EGL_RED_SIZE, 8,
|
||||||
EGL_GREEN_SIZE, 1,
|
EGL_GREEN_SIZE, 8,
|
||||||
EGL_BLUE_SIZE, 1,
|
EGL_BLUE_SIZE, 8,
|
||||||
EGL_ALPHA_SIZE, 1,
|
EGL_ALPHA_SIZE, 8,
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||||
EGL_NONE,
|
EGL_NONE,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ static void do_updates(void) {
|
||||||
update_stage++;
|
update_stage++;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (strcmp(current.surrounding.text, "_Commit_") != 0) {
|
if (current.surrounding.text && strcmp(current.surrounding.text, "_Commit_") != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
zwp_input_method_v2_commit_string(input_method, "_CommitNoPreed_");
|
zwp_input_method_v2_commit_string(input_method, "_CommitNoPreed_");
|
||||||
|
|
@ -203,7 +203,7 @@ static void do_updates(void) {
|
||||||
update_stage++;
|
update_stage++;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (strcmp(current.surrounding.text, "_Commit__CommitNoPreed_") != 0) {
|
if (current.surrounding.text && strcmp(current.surrounding.text, "_Commit__CommitNoPreed_") != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
zwp_input_method_v2_commit_string(input_method, "_WaitNo_");
|
zwp_input_method_v2_commit_string(input_method, "_WaitNo_");
|
||||||
|
|
@ -212,7 +212,7 @@ static void do_updates(void) {
|
||||||
update_stage++;
|
update_stage++;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (strcmp(current.surrounding.text, "_Commit__WaitNo_") != 0) {
|
if (current.surrounding.text && strcmp(current.surrounding.text, "_Commit__WaitNo_") != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
zwp_input_method_v2_set_preedit_string(input_method, "PreedWithDel", strlen("Preed"), strlen("Preed"));
|
zwp_input_method_v2_set_preedit_string(input_method, "PreedWithDel", strlen("Preed"), strlen("Preed"));
|
||||||
|
|
@ -221,7 +221,7 @@ static void do_updates(void) {
|
||||||
update_stage++;
|
update_stage++;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (strcmp(current.surrounding.text, "_Commit_") != 0) {
|
if (current.surrounding.text && strcmp(current.surrounding.text, "_Commit_") != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
zwp_input_method_v2_delete_surrounding_text(input_method, strlen("mit_"), 0);
|
zwp_input_method_v2_delete_surrounding_text(input_method, strlen("mit_"), 0);
|
||||||
|
|
@ -229,7 +229,7 @@ static void do_updates(void) {
|
||||||
update_stage++;
|
update_stage++;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
if (strcmp(current.surrounding.text, "_Com") != 0) {
|
if (current.surrounding.text && strcmp(current.surrounding.text, "_Com") != 0) {
|
||||||
printf("Failed\n");
|
printf("Failed\n");
|
||||||
}
|
}
|
||||||
update_stage++;
|
update_stage++;
|
||||||
|
|
|
||||||
|
|
@ -124,9 +124,10 @@ static void draw(void) {
|
||||||
|
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
if (buttons) {
|
if (buttons) {
|
||||||
glClearColor(1, 1, 1, alpha);
|
glClearColor(alpha, alpha, alpha, alpha);
|
||||||
} else {
|
} else {
|
||||||
glClearColor(demo.color[0], demo.color[1], demo.color[2], alpha);
|
glClearColor(demo.color[0] * alpha, demo.color[1] * alpha,
|
||||||
|
demo.color[2] * alpha, alpha);
|
||||||
}
|
}
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
@ -151,7 +152,8 @@ static void draw_popup(void) {
|
||||||
|
|
||||||
eglMakeCurrent(egl_display, popup_egl_surface, popup_egl_surface, egl_context);
|
eglMakeCurrent(egl_display, popup_egl_surface, popup_egl_surface, egl_context);
|
||||||
glViewport(0, 0, popup_width, popup_height);
|
glViewport(0, 0, popup_width, popup_height);
|
||||||
glClearColor(popup_red, 0.5f, 0.5f, popup_alpha);
|
glClearColor(popup_red * popup_alpha, 0.5f * popup_alpha,
|
||||||
|
0.5f * popup_alpha, popup_alpha);
|
||||||
popup_alpha += alpha_mod;
|
popup_alpha += alpha_mod;
|
||||||
if (popup_alpha < 0.01 || popup_alpha >= 1.0f) {
|
if (popup_alpha < 0.01 || popup_alpha >= 1.0f) {
|
||||||
alpha_mod *= -1.0;
|
alpha_mod *= -1.0;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ wayland_client = dependency('wayland-client')
|
||||||
libpng = dependency('libpng', required: false, disabler: true)
|
libpng = dependency('libpng', required: false, disabler: true)
|
||||||
egl = dependency('egl', required: false, disabler: true)
|
egl = dependency('egl', required: false, disabler: true)
|
||||||
glesv2 = dependency('glesv2', required: false, disabler: true)
|
glesv2 = dependency('glesv2', required: false, disabler: true)
|
||||||
|
gbm = dependency('gbm', required: false, disabler: true)
|
||||||
# These versions correspond to ffmpeg 4.0
|
# These versions correspond to ffmpeg 4.0
|
||||||
libavutil = dependency('libavutil', version: '>=56.14.100', required: false, disabler: true)
|
libavutil = dependency('libavutil', version: '>=56.14.100', required: false, disabler: true)
|
||||||
libavcodec = dependency('libavcodec', version: '>=58.18.100', required: false, disabler: true)
|
libavcodec = dependency('libavcodec', version: '>=58.18.100', required: false, disabler: true)
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ struct sample_output {
|
||||||
|
|
||||||
struct sample_keyboard {
|
struct sample_keyboard {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
@ -109,8 +109,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
||||||
struct sample_cursor *cursor =
|
struct sample_cursor *cursor =
|
||||||
wl_container_of(listener, cursor, cursor_motion);
|
wl_container_of(listener, cursor, cursor_motion);
|
||||||
struct wlr_event_pointer_motion *event = data;
|
struct wlr_pointer_motion_event *event = data;
|
||||||
wlr_cursor_move(cursor->cursor, event->device, event->delta_x,
|
wlr_cursor_move(cursor->cursor, &event->pointer->base, event->delta_x,
|
||||||
event->delta_y);
|
event->delta_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,8 +118,9 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct sample_cursor *cursor =
|
struct sample_cursor *cursor =
|
||||||
wl_container_of(listener, cursor, cursor_motion_absolute);
|
wl_container_of(listener, cursor, cursor_motion_absolute);
|
||||||
struct wlr_event_pointer_motion_absolute *event = data;
|
struct wlr_pointer_motion_absolute_event *event = data;
|
||||||
wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y);
|
wlr_cursor_warp_absolute(cursor->cursor, &event->pointer->base, event->x,
|
||||||
|
event->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cursor_destroy(struct sample_cursor *cursor) {
|
static void cursor_destroy(struct sample_cursor *cursor) {
|
||||||
|
|
@ -184,10 +185,10 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||||
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
struct sample_state *sample = keyboard->sample;
|
struct sample_state *sample = keyboard->sample;
|
||||||
struct wlr_event_keyboard_key *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
|
||||||
keycode, &syms);
|
keycode, &syms);
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < nsyms; i++) {
|
||||||
xkb_keysym_t sym = syms[i];
|
xkb_keysym_t sym = syms[i];
|
||||||
|
|
@ -210,11 +211,11 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:;
|
case WLR_INPUT_DEVICE_KEYBOARD:;
|
||||||
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
||||||
keyboard->device = device;
|
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
|
||||||
keyboard->sample = sample;
|
keyboard->sample = sample;
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
||||||
keyboard->destroy.notify = keyboard_destroy_notify;
|
keyboard->destroy.notify = keyboard_destroy_notify;
|
||||||
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
|
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
|
||||||
keyboard->key.notify = keyboard_key_notify;
|
keyboard->key.notify = keyboard_key_notify;
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
@ -227,7 +228,7 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
wlr_keyboard_set_keymap(device->keyboard, keymap);
|
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ struct sample_output {
|
||||||
|
|
||||||
struct sample_keyboard {
|
struct sample_keyboard {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
@ -183,10 +183,10 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||||
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
struct sample_state *sample = keyboard->sample;
|
struct sample_state *sample = keyboard->sample;
|
||||||
struct wlr_event_keyboard_key *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
|
||||||
keycode, &syms);
|
keycode, &syms);
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < nsyms; i++) {
|
||||||
xkb_keysym_t sym = syms[i];
|
xkb_keysym_t sym = syms[i];
|
||||||
|
|
@ -229,11 +229,11 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:;
|
case WLR_INPUT_DEVICE_KEYBOARD:;
|
||||||
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
||||||
keyboard->device = device;
|
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
|
||||||
keyboard->sample = sample;
|
keyboard->sample = sample;
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
||||||
keyboard->destroy.notify = keyboard_destroy_notify;
|
keyboard->destroy.notify = keyboard_destroy_notify;
|
||||||
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
|
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
|
||||||
keyboard->key.notify = keyboard_key_notify;
|
keyboard->key.notify = keyboard_key_notify;
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
@ -246,7 +246,7 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
wlr_keyboard_set_keymap(device->keyboard, keymap);
|
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ struct sample_output {
|
||||||
|
|
||||||
struct sample_keyboard {
|
struct sample_keyboard {
|
||||||
struct sample_state *state;
|
struct sample_state *state;
|
||||||
struct wlr_input_device *device;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
@ -112,8 +112,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
||||||
struct sample_state *sample =
|
struct sample_state *sample =
|
||||||
wl_container_of(listener, sample, cursor_motion);
|
wl_container_of(listener, sample, cursor_motion);
|
||||||
struct wlr_event_pointer_motion *event = data;
|
struct wlr_pointer_motion_event *event = data;
|
||||||
wlr_cursor_move(sample->cursor, event->device, event->delta_x,
|
wlr_cursor_move(sample->cursor, &event->pointer->base, event->delta_x,
|
||||||
event->delta_y);
|
event->delta_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,19 +121,19 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct sample_state *sample =
|
struct sample_state *sample =
|
||||||
wl_container_of(listener, sample, cursor_motion_absolute);
|
wl_container_of(listener, sample, cursor_motion_absolute);
|
||||||
struct wlr_event_pointer_motion_absolute *event = data;
|
struct wlr_pointer_motion_absolute_event *event = data;
|
||||||
|
|
||||||
sample->cur_x = event->x;
|
sample->cur_x = event->x;
|
||||||
sample->cur_y = event->y;
|
sample->cur_y = event->y;
|
||||||
|
|
||||||
wlr_cursor_warp_absolute(sample->cursor, event->device, sample->cur_x,
|
wlr_cursor_warp_absolute(sample->cursor, &event->pointer->base,
|
||||||
sample->cur_y);
|
sample->cur_x, sample->cur_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_cursor_button(struct wl_listener *listener, void *data) {
|
static void handle_cursor_button(struct wl_listener *listener, void *data) {
|
||||||
struct sample_state *sample =
|
struct sample_state *sample =
|
||||||
wl_container_of(listener, sample, cursor_button);
|
wl_container_of(listener, sample, cursor_button);
|
||||||
struct wlr_event_pointer_button *event = data;
|
struct wlr_pointer_button_event *event = data;
|
||||||
|
|
||||||
float (*color)[4];
|
float (*color)[4];
|
||||||
if (event->state == WLR_BUTTON_RELEASED) {
|
if (event->state == WLR_BUTTON_RELEASED) {
|
||||||
|
|
@ -150,7 +150,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
|
||||||
static void handle_cursor_axis(struct wl_listener *listener, void *data) {
|
static void handle_cursor_axis(struct wl_listener *listener, void *data) {
|
||||||
struct sample_state *sample =
|
struct sample_state *sample =
|
||||||
wl_container_of(listener, sample, cursor_axis);
|
wl_container_of(listener, sample, cursor_axis);
|
||||||
struct wlr_event_pointer_axis *event = data;
|
struct wlr_pointer_axis_event *event = data;
|
||||||
|
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
sample->default_color[i] += event->delta > 0 ? -0.05f : 0.05f;
|
sample->default_color[i] += event->delta > 0 ? -0.05f : 0.05f;
|
||||||
|
|
@ -168,7 +168,7 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
static void handle_touch_up(struct wl_listener *listener, void *data) {
|
static void handle_touch_up(struct wl_listener *listener, void *data) {
|
||||||
struct sample_state *sample = wl_container_of(listener, sample, touch_up);
|
struct sample_state *sample = wl_container_of(listener, sample, touch_up);
|
||||||
struct wlr_event_touch_up *event = data;
|
struct wlr_touch_up_event *event = data;
|
||||||
|
|
||||||
struct touch_point *point, *tmp;
|
struct touch_point *point, *tmp;
|
||||||
wl_list_for_each_safe(point, tmp, &sample->touch_points, link) {
|
wl_list_for_each_safe(point, tmp, &sample->touch_points, link) {
|
||||||
|
|
@ -178,25 +178,25 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
warp_to_touch(sample, event->device);
|
warp_to_touch(sample, &event->touch->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_touch_down(struct wl_listener *listener, void *data) {
|
static void handle_touch_down(struct wl_listener *listener, void *data) {
|
||||||
struct sample_state *sample = wl_container_of(listener, sample, touch_down);
|
struct sample_state *sample = wl_container_of(listener, sample, touch_down);
|
||||||
struct wlr_event_touch_down *event = data;
|
struct wlr_touch_down_event *event = data;
|
||||||
struct touch_point *point = calloc(1, sizeof(struct touch_point));
|
struct touch_point *point = calloc(1, sizeof(struct touch_point));
|
||||||
point->touch_id = event->touch_id;
|
point->touch_id = event->touch_id;
|
||||||
point->x = event->x;
|
point->x = event->x;
|
||||||
point->y = event->y;
|
point->y = event->y;
|
||||||
wl_list_insert(&sample->touch_points, &point->link);
|
wl_list_insert(&sample->touch_points, &point->link);
|
||||||
|
|
||||||
warp_to_touch(sample, event->device);
|
warp_to_touch(sample, &event->touch->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
||||||
struct sample_state *sample =
|
struct sample_state *sample =
|
||||||
wl_container_of(listener, sample, touch_motion);
|
wl_container_of(listener, sample, touch_motion);
|
||||||
struct wlr_event_touch_motion *event = data;
|
struct wlr_touch_motion_event *event = data;
|
||||||
|
|
||||||
struct touch_point *point;
|
struct touch_point *point;
|
||||||
wl_list_for_each(point, &sample->touch_points, link) {
|
wl_list_for_each(point, &sample->touch_points, link) {
|
||||||
|
|
@ -207,7 +207,7 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
warp_to_touch(sample, event->device);
|
warp_to_touch(sample, &event->touch->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_touch_cancel(struct wl_listener *listener, void *data) {
|
static void handle_touch_cancel(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -217,21 +217,21 @@ static void handle_touch_cancel(struct wl_listener *listener, void *data) {
|
||||||
static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) {
|
static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) {
|
||||||
struct sample_state *sample =
|
struct sample_state *sample =
|
||||||
wl_container_of(listener, sample, tablet_tool_axis);
|
wl_container_of(listener, sample, tablet_tool_axis);
|
||||||
struct wlr_event_tablet_tool_axis *event = data;
|
struct wlr_tablet_tool_axis_event *event = data;
|
||||||
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) &&
|
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) &&
|
||||||
(event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) {
|
(event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) {
|
||||||
wlr_cursor_warp_absolute(sample->cursor,
|
wlr_cursor_warp_absolute(sample->cursor, &event->tablet->base,
|
||||||
event->device, event->x, event->y);
|
event->x, event->y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
struct sample_state *sample = keyboard->state;
|
struct sample_state *sample = keyboard->state;
|
||||||
struct wlr_event_keyboard_key *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
|
||||||
keycode, &syms);
|
keycode, &syms);
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < nsyms; i++) {
|
||||||
xkb_keysym_t sym = syms[i];
|
xkb_keysym_t sym = syms[i];
|
||||||
|
|
@ -297,11 +297,11 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:;
|
case WLR_INPUT_DEVICE_KEYBOARD:;
|
||||||
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
||||||
keyboard->device = device;
|
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
|
||||||
keyboard->state = state;
|
keyboard->state = state;
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
||||||
keyboard->destroy.notify = keyboard_destroy_notify;
|
keyboard->destroy.notify = keyboard_destroy_notify;
|
||||||
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
|
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
|
||||||
keyboard->key.notify = keyboard_key_notify;
|
keyboard->key.notify = keyboard_key_notify;
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
@ -314,7 +314,7 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
wlr_keyboard_set_keymap(device->keyboard, keymap);
|
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ struct sample_output {
|
||||||
|
|
||||||
struct sample_keyboard {
|
struct sample_keyboard {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
@ -129,10 +129,10 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||||
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
struct sample_state *sample = keyboard->sample;
|
struct sample_state *sample = keyboard->sample;
|
||||||
struct wlr_event_keyboard_key *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
|
||||||
keycode, &syms);
|
keycode, &syms);
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < nsyms; i++) {
|
||||||
xkb_keysym_t sym = syms[i];
|
xkb_keysym_t sym = syms[i];
|
||||||
|
|
@ -155,11 +155,11 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:;
|
case WLR_INPUT_DEVICE_KEYBOARD:;
|
||||||
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
||||||
keyboard->device = device;
|
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
|
||||||
keyboard->sample = sample;
|
keyboard->sample = sample;
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
||||||
keyboard->destroy.notify = keyboard_destroy_notify;
|
keyboard->destroy.notify = keyboard_destroy_notify;
|
||||||
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
|
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
|
||||||
keyboard->key.notify = keyboard_key_notify;
|
keyboard->key.notify = keyboard_key_notify;
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
@ -172,7 +172,7 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
wlr_keyboard_set_keymap(device->keyboard, keymap);
|
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ struct sample_output {
|
||||||
|
|
||||||
struct sample_keyboard {
|
struct sample_keyboard {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
@ -134,10 +134,10 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||||
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
struct sample_state *sample = keyboard->sample;
|
struct sample_state *sample = keyboard->sample;
|
||||||
struct wlr_event_keyboard_key *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
|
||||||
keycode, &syms);
|
keycode, &syms);
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < nsyms; i++) {
|
||||||
xkb_keysym_t sym = syms[i];
|
xkb_keysym_t sym = syms[i];
|
||||||
|
|
@ -176,11 +176,11 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:;
|
case WLR_INPUT_DEVICE_KEYBOARD:;
|
||||||
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
||||||
keyboard->device = device;
|
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
|
||||||
keyboard->sample = sample;
|
keyboard->sample = sample;
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
||||||
keyboard->destroy.notify = keyboard_destroy_notify;
|
keyboard->destroy.notify = keyboard_destroy_notify;
|
||||||
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
|
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
|
||||||
keyboard->key.notify = keyboard_key_notify;
|
keyboard->key.notify = keyboard_key_notify;
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
@ -193,7 +193,7 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
wlr_keyboard_set_keymap(device->keyboard, keymap);
|
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ static void surface_handle_commit(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
static void surface_handle_destroy(struct wl_listener *listener, void *data) {
|
static void surface_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
struct surface *surface = wl_container_of(listener, surface, destroy);
|
struct surface *surface = wl_container_of(listener, surface, destroy);
|
||||||
wlr_scene_node_destroy(&surface->scene_surface->node);
|
wlr_scene_node_destroy(&surface->scene_surface->buffer->node);
|
||||||
wlr_scene_node_destroy(&surface->border->node);
|
wlr_scene_node_destroy(&surface->border->node);
|
||||||
wl_list_remove(&surface->destroy.link);
|
wl_list_remove(&surface->destroy.link);
|
||||||
wl_list_remove(&surface->link);
|
wl_list_remove(&surface->link);
|
||||||
|
|
@ -122,14 +122,14 @@ static void server_handle_new_surface(struct wl_listener *listener,
|
||||||
wl_signal_add(&wlr_surface->events.destroy, &surface->destroy);
|
wl_signal_add(&wlr_surface->events.destroy, &surface->destroy);
|
||||||
|
|
||||||
/* Border dimensions will be set in surface.commit handler */
|
/* Border dimensions will be set in surface.commit handler */
|
||||||
surface->border = wlr_scene_rect_create(&server->scene->node,
|
surface->border = wlr_scene_rect_create(&server->scene->tree,
|
||||||
0, 0, (float[4]){ 0.5f, 0.5f, 0.5f, 1 });
|
0, 0, (float[4]){ 0.5f, 0.5f, 0.5f, 1 });
|
||||||
wlr_scene_node_set_position(&surface->border->node, pos, pos);
|
wlr_scene_node_set_position(&surface->border->node, pos, pos);
|
||||||
|
|
||||||
surface->scene_surface =
|
surface->scene_surface =
|
||||||
wlr_scene_surface_create(&server->scene->node, wlr_surface);
|
wlr_scene_surface_create(&server->scene->tree, wlr_surface);
|
||||||
|
|
||||||
wlr_scene_node_set_position(&surface->scene_surface->node,
|
wlr_scene_node_set_position(&surface->scene_surface->buffer->node,
|
||||||
pos + border_width, pos + border_width);
|
pos + border_width, pos + border_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,7 +169,7 @@ int main(int argc, char *argv[]) {
|
||||||
struct wlr_compositor *compositor =
|
struct wlr_compositor *compositor =
|
||||||
wlr_compositor_create(server.display, server.renderer);
|
wlr_compositor_create(server.display, server.renderer);
|
||||||
|
|
||||||
wlr_xdg_shell_create(server.display);
|
wlr_xdg_shell_create(server.display, 2);
|
||||||
|
|
||||||
server.new_output.notify = server_handle_new_output;
|
server.new_output.notify = server_handle_new_output;
|
||||||
wl_signal_add(&server.backend->events.new_output, &server.new_output);
|
wl_signal_add(&server.backend->events.new_output, &server.new_output);
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ static const struct format formats[] = {
|
||||||
{DRM_FORMAT_ABGR8888, false},
|
{DRM_FORMAT_ABGR8888, false},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool find_render_node(char *node, size_t maxlen) {
|
static bool find_render_node(char *node, size_t node_size) {
|
||||||
bool r = false;
|
bool r = false;
|
||||||
drmDevice *devices[64];
|
drmDevice *devices[64];
|
||||||
|
|
||||||
|
|
@ -87,8 +87,7 @@ static bool find_render_node(char *node, size_t maxlen) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(node, dev->nodes[DRM_NODE_RENDER], maxlen - 1);
|
snprintf(node, node_size, "%s", dev->nodes[DRM_NODE_RENDER]);
|
||||||
node[maxlen - 1] = '\0';
|
|
||||||
r = true;
|
r = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ struct sample_output {
|
||||||
|
|
||||||
struct sample_keyboard {
|
struct sample_keyboard {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
@ -109,10 +109,10 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||||
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
struct sample_state *sample = keyboard->sample;
|
struct sample_state *sample = keyboard->sample;
|
||||||
struct wlr_event_keyboard_key *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
|
||||||
keycode, &syms);
|
keycode, &syms);
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < nsyms; i++) {
|
||||||
xkb_keysym_t sym = syms[i];
|
xkb_keysym_t sym = syms[i];
|
||||||
|
|
@ -137,11 +137,11 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:;
|
case WLR_INPUT_DEVICE_KEYBOARD:;
|
||||||
struct sample_keyboard *keyboard =
|
struct sample_keyboard *keyboard =
|
||||||
calloc(1, sizeof(struct sample_keyboard));
|
calloc(1, sizeof(struct sample_keyboard));
|
||||||
keyboard->device = device;
|
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
|
||||||
keyboard->sample = sample;
|
keyboard->sample = sample;
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
||||||
keyboard->destroy.notify = keyboard_destroy_notify;
|
keyboard->destroy.notify = keyboard_destroy_notify;
|
||||||
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
|
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
|
||||||
keyboard->key.notify = keyboard_key_notify;
|
keyboard->key.notify = keyboard_key_notify;
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
@ -154,7 +154,7 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
wlr_keyboard_set_keymap(device->keyboard, keymap);
|
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ struct sample_state {
|
||||||
|
|
||||||
struct tablet_tool_state {
|
struct tablet_tool_state {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_tablet *wlr_tablet;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener axis;
|
struct wl_listener axis;
|
||||||
struct wl_listener proximity;
|
struct wl_listener proximity;
|
||||||
|
|
@ -55,7 +55,7 @@ struct tablet_tool_state {
|
||||||
|
|
||||||
struct tablet_pad_state {
|
struct tablet_pad_state {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_tablet_pad *wlr_tablet_pad;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener button;
|
struct wl_listener button;
|
||||||
struct wl_listener ring;
|
struct wl_listener ring;
|
||||||
|
|
@ -72,7 +72,7 @@ struct sample_output {
|
||||||
|
|
||||||
struct sample_keyboard {
|
struct sample_keyboard {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
@ -136,7 +136,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
static void tablet_tool_axis_notify(struct wl_listener *listener, void *data) {
|
static void tablet_tool_axis_notify(struct wl_listener *listener, void *data) {
|
||||||
struct tablet_tool_state *tstate = wl_container_of(listener, tstate, axis);
|
struct tablet_tool_state *tstate = wl_container_of(listener, tstate, axis);
|
||||||
struct wlr_event_tablet_tool_axis *event = data;
|
struct wlr_tablet_tool_axis_event *event = data;
|
||||||
struct sample_state *sample = tstate->sample;
|
struct sample_state *sample = tstate->sample;
|
||||||
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) {
|
if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) {
|
||||||
sample->x = event->x;
|
sample->x = event->x;
|
||||||
|
|
@ -160,14 +160,14 @@ static void tablet_tool_axis_notify(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
static void tablet_tool_proximity_notify(struct wl_listener *listener, void *data) {
|
static void tablet_tool_proximity_notify(struct wl_listener *listener, void *data) {
|
||||||
struct tablet_tool_state *tstate = wl_container_of(listener, tstate, proximity);
|
struct tablet_tool_state *tstate = wl_container_of(listener, tstate, proximity);
|
||||||
struct wlr_event_tablet_tool_proximity *event = data;
|
struct wlr_tablet_tool_proximity_event *event = data;
|
||||||
struct sample_state *sample = tstate->sample;
|
struct sample_state *sample = tstate->sample;
|
||||||
sample->proximity = event->state == WLR_TABLET_TOOL_PROXIMITY_IN;
|
sample->proximity = event->state == WLR_TABLET_TOOL_PROXIMITY_IN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tablet_tool_button_notify(struct wl_listener *listener, void *data) {
|
static void tablet_tool_button_notify(struct wl_listener *listener, void *data) {
|
||||||
struct tablet_tool_state *tstate = wl_container_of(listener, tstate, button);
|
struct tablet_tool_state *tstate = wl_container_of(listener, tstate, button);
|
||||||
struct wlr_event_tablet_tool_button *event = data;
|
struct wlr_tablet_tool_button_event *event = data;
|
||||||
struct sample_state *sample = tstate->sample;
|
struct sample_state *sample = tstate->sample;
|
||||||
if (event->state == WLR_BUTTON_RELEASED) {
|
if (event->state == WLR_BUTTON_RELEASED) {
|
||||||
sample->button = false;
|
sample->button = false;
|
||||||
|
|
@ -185,7 +185,7 @@ static void tablet_tool_button_notify(struct wl_listener *listener, void *data)
|
||||||
|
|
||||||
static void tablet_pad_button_notify(struct wl_listener *listener, void *data) {
|
static void tablet_pad_button_notify(struct wl_listener *listener, void *data) {
|
||||||
struct tablet_pad_state *pstate = wl_container_of(listener, pstate, button);
|
struct tablet_pad_state *pstate = wl_container_of(listener, pstate, button);
|
||||||
struct wlr_event_tablet_pad_button *event = data;
|
struct wlr_tablet_pad_button_event *event = data;
|
||||||
struct sample_state *sample = pstate->sample;
|
struct sample_state *sample = pstate->sample;
|
||||||
float default_color[4] = { 0.5, 0.5, 0.5, 1.0 };
|
float default_color[4] = { 0.5, 0.5, 0.5, 1.0 };
|
||||||
if (event->state == WLR_BUTTON_RELEASED) {
|
if (event->state == WLR_BUTTON_RELEASED) {
|
||||||
|
|
@ -203,7 +203,7 @@ static void tablet_pad_button_notify(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
static void tablet_pad_ring_notify(struct wl_listener *listener, void *data) {
|
static void tablet_pad_ring_notify(struct wl_listener *listener, void *data) {
|
||||||
struct tablet_pad_state *pstate = wl_container_of(listener, pstate, ring);
|
struct tablet_pad_state *pstate = wl_container_of(listener, pstate, ring);
|
||||||
struct wlr_event_tablet_pad_ring *event = data;
|
struct wlr_tablet_pad_ring_event *event = data;
|
||||||
struct sample_state *sample = pstate->sample;
|
struct sample_state *sample = pstate->sample;
|
||||||
if (event->position != -1) {
|
if (event->position != -1) {
|
||||||
sample->ring = -(event->position * (M_PI / 180.0));
|
sample->ring = -(event->position * (M_PI / 180.0));
|
||||||
|
|
@ -261,10 +261,10 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||||
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
struct sample_state *sample = keyboard->sample;
|
struct sample_state *sample = keyboard->sample;
|
||||||
struct wlr_event_keyboard_key *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
|
||||||
keycode, &syms);
|
keycode, &syms);
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < nsyms; i++) {
|
||||||
xkb_keysym_t sym = syms[i];
|
xkb_keysym_t sym = syms[i];
|
||||||
|
|
@ -287,11 +287,11 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:;
|
case WLR_INPUT_DEVICE_KEYBOARD:;
|
||||||
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
||||||
keyboard->device = device;
|
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
|
||||||
keyboard->sample = sample;
|
keyboard->sample = sample;
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
||||||
keyboard->destroy.notify = keyboard_destroy_notify;
|
keyboard->destroy.notify = keyboard_destroy_notify;
|
||||||
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
|
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
|
||||||
keyboard->key.notify = keyboard_key_notify;
|
keyboard->key.notify = keyboard_key_notify;
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
@ -304,39 +304,40 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
wlr_keyboard_set_keymap(device->keyboard, keymap);
|
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
break;
|
break;
|
||||||
case WLR_INPUT_DEVICE_TABLET_PAD:;
|
case WLR_INPUT_DEVICE_TABLET_PAD:;
|
||||||
struct tablet_pad_state *pstate = calloc(sizeof(struct tablet_pad_state), 1);
|
struct tablet_pad_state *pstate = calloc(sizeof(struct tablet_pad_state), 1);
|
||||||
pstate->device = device;
|
pstate->wlr_tablet_pad = wlr_tablet_pad_from_input_device(device);
|
||||||
pstate->sample = sample;
|
pstate->sample = sample;
|
||||||
pstate->destroy.notify = tablet_pad_destroy_notify;
|
pstate->destroy.notify = tablet_pad_destroy_notify;
|
||||||
wl_signal_add(&device->events.destroy, &pstate->destroy);
|
wl_signal_add(&device->events.destroy, &pstate->destroy);
|
||||||
pstate->button.notify = tablet_pad_button_notify;
|
pstate->button.notify = tablet_pad_button_notify;
|
||||||
wl_signal_add(&device->tablet_pad->events.button, &pstate->button);
|
wl_signal_add(&pstate->wlr_tablet_pad->events.button, &pstate->button);
|
||||||
pstate->ring.notify = tablet_pad_ring_notify;
|
pstate->ring.notify = tablet_pad_ring_notify;
|
||||||
wl_signal_add(&device->tablet_pad->events.ring, &pstate->ring);
|
wl_signal_add(&pstate->wlr_tablet_pad->events.ring, &pstate->ring);
|
||||||
wl_list_insert(&sample->tablet_pads, &pstate->link);
|
wl_list_insert(&sample->tablet_pads, &pstate->link);
|
||||||
break;
|
break;
|
||||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
case WLR_INPUT_DEVICE_TABLET_TOOL:;
|
||||||
sample->width_mm = device->width_mm == 0 ?
|
struct wlr_tablet *tablet = wlr_tablet_from_input_device(device);
|
||||||
20 : device->width_mm;
|
sample->width_mm = tablet->width_mm == 0 ?
|
||||||
sample->height_mm = device->height_mm == 0 ?
|
20 : tablet->width_mm;
|
||||||
10 : device->height_mm;
|
sample->height_mm = tablet->height_mm == 0 ?
|
||||||
|
10 : tablet->height_mm;
|
||||||
|
|
||||||
struct tablet_tool_state *tstate = calloc(sizeof(struct tablet_tool_state), 1);
|
struct tablet_tool_state *tstate = calloc(sizeof(struct tablet_tool_state), 1);
|
||||||
tstate->device = device;
|
tstate->wlr_tablet = tablet;
|
||||||
tstate->sample = sample;
|
tstate->sample = sample;
|
||||||
tstate->destroy.notify = tablet_tool_destroy_notify;
|
tstate->destroy.notify = tablet_tool_destroy_notify;
|
||||||
wl_signal_add(&device->events.destroy, &tstate->destroy);
|
wl_signal_add(&device->events.destroy, &tstate->destroy);
|
||||||
tstate->axis.notify = tablet_tool_axis_notify;
|
tstate->axis.notify = tablet_tool_axis_notify;
|
||||||
wl_signal_add(&device->tablet->events.axis, &tstate->axis);
|
wl_signal_add(&tablet->events.axis, &tstate->axis);
|
||||||
tstate->proximity.notify = tablet_tool_proximity_notify;
|
tstate->proximity.notify = tablet_tool_proximity_notify;
|
||||||
wl_signal_add(&device->tablet->events.proximity, &tstate->proximity);
|
wl_signal_add(&tablet->events.proximity, &tstate->proximity);
|
||||||
tstate->button.notify = tablet_tool_button_notify;
|
tstate->button.notify = tablet_tool_button_notify;
|
||||||
wl_signal_add(&device->tablet->events.button, &tstate->button);
|
wl_signal_add(&tablet->events.button, &tstate->button);
|
||||||
wl_list_insert(&sample->tablet_tools, &tstate->link);
|
wl_list_insert(&sample->tablet_tools, &tstate->link);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -344,7 +345,6 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
wlr_log_init(WLR_DEBUG, NULL);
|
wlr_log_init(WLR_DEBUG, NULL);
|
||||||
struct wl_display *display = wl_display_create();
|
struct wl_display *display = wl_display_create();
|
||||||
|
|
|
||||||
|
|
@ -244,15 +244,15 @@ static void text_input_handle_done(void *data,
|
||||||
buffer[strlen(buffer) - delete_before] = '\0';
|
buffer[strlen(buffer) - delete_before] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
char *commit_string = current.commit;
|
const char *commit_string = current.commit;
|
||||||
if (!commit_string) {
|
if (!commit_string) {
|
||||||
commit_string = "";
|
commit_string = "";
|
||||||
}
|
}
|
||||||
char *old_buffer = buffer;
|
size_t new_size = strlen(buffer) + strlen(commit_string) + 1;
|
||||||
buffer = calloc(strlen(buffer) + strlen(commit_string) + 1, sizeof(char)); // realloc may fail anyway
|
char *new_buffer = calloc(new_size, sizeof(char)); // realloc may fail anyway
|
||||||
strcpy(buffer, old_buffer);
|
snprintf(new_buffer, new_size, "%s%s", buffer, commit_string);
|
||||||
free(old_buffer);
|
free(buffer);
|
||||||
strcat(buffer, commit_string);
|
buffer = new_buffer;
|
||||||
|
|
||||||
send_status_update(zwp_text_input_v3);
|
send_status_update(zwp_text_input_v3);
|
||||||
show_status();
|
show_status();
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ struct touch_point {
|
||||||
|
|
||||||
struct touch_state {
|
struct touch_state {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_touch *wlr_touch;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener down;
|
struct wl_listener down;
|
||||||
struct wl_listener up;
|
struct wl_listener up;
|
||||||
|
|
@ -59,7 +59,7 @@ struct sample_output {
|
||||||
|
|
||||||
struct sample_keyboard {
|
struct sample_keyboard {
|
||||||
struct sample_state *sample;
|
struct sample_state *sample;
|
||||||
struct wlr_input_device *device;
|
struct wlr_keyboard *wlr_keyboard;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
@ -93,7 +93,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void touch_down_notify(struct wl_listener *listener, void *data) {
|
static void touch_down_notify(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_event_touch_motion *event = data;
|
struct wlr_touch_motion_event *event = data;
|
||||||
struct touch_state *tstate = wl_container_of(listener, tstate, down);
|
struct touch_state *tstate = wl_container_of(listener, tstate, down);
|
||||||
struct sample_state *sample = tstate->sample;
|
struct sample_state *sample = tstate->sample;
|
||||||
struct touch_point *point = calloc(1, sizeof(struct touch_point));
|
struct touch_point *point = calloc(1, sizeof(struct touch_point));
|
||||||
|
|
@ -104,7 +104,7 @@ static void touch_down_notify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void touch_up_notify(struct wl_listener *listener, void *data ) {
|
static void touch_up_notify(struct wl_listener *listener, void *data ) {
|
||||||
struct wlr_event_touch_up *event = data;
|
struct wlr_touch_up_event *event = data;
|
||||||
struct touch_state *tstate = wl_container_of(listener, tstate, up);
|
struct touch_state *tstate = wl_container_of(listener, tstate, up);
|
||||||
struct sample_state *sample = tstate->sample;
|
struct sample_state *sample = tstate->sample;
|
||||||
struct touch_point *point, *tmp;
|
struct touch_point *point, *tmp;
|
||||||
|
|
@ -117,7 +117,7 @@ static void touch_up_notify(struct wl_listener *listener, void *data ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void touch_motion_notify(struct wl_listener *listener, void *data) {
|
static void touch_motion_notify(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_event_touch_motion *event = data;
|
struct wlr_touch_motion_event *event = data;
|
||||||
struct touch_state *tstate = wl_container_of(listener, tstate, motion);
|
struct touch_state *tstate = wl_container_of(listener, tstate, motion);
|
||||||
struct sample_state *sample = tstate->sample;
|
struct sample_state *sample = tstate->sample;
|
||||||
struct touch_point *point;
|
struct touch_point *point;
|
||||||
|
|
@ -172,10 +172,10 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
||||||
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
static void keyboard_key_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct sample_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
struct sample_state *sample = keyboard->sample;
|
struct sample_state *sample = keyboard->sample;
|
||||||
struct wlr_event_keyboard_key *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state,
|
||||||
keycode, &syms);
|
keycode, &syms);
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < nsyms; i++) {
|
||||||
xkb_keysym_t sym = syms[i];
|
xkb_keysym_t sym = syms[i];
|
||||||
|
|
@ -198,11 +198,11 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:;
|
case WLR_INPUT_DEVICE_KEYBOARD:;
|
||||||
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
struct sample_keyboard *keyboard = calloc(1, sizeof(struct sample_keyboard));
|
||||||
keyboard->device = device;
|
keyboard->wlr_keyboard = wlr_keyboard_from_input_device(device);
|
||||||
keyboard->sample = sample;
|
keyboard->sample = sample;
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
||||||
keyboard->destroy.notify = keyboard_destroy_notify;
|
keyboard->destroy.notify = keyboard_destroy_notify;
|
||||||
wl_signal_add(&device->keyboard->events.key, &keyboard->key);
|
wl_signal_add(&keyboard->wlr_keyboard->events.key, &keyboard->key);
|
||||||
keyboard->key.notify = keyboard_key_notify;
|
keyboard->key.notify = keyboard_key_notify;
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|
@ -215,22 +215,22 @@ static void new_input_notify(struct wl_listener *listener, void *data) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
wlr_log(WLR_ERROR, "Failed to create XKB keymap");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
wlr_keyboard_set_keymap(device->keyboard, keymap);
|
wlr_keyboard_set_keymap(keyboard->wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
break;
|
break;
|
||||||
case WLR_INPUT_DEVICE_TOUCH:;
|
case WLR_INPUT_DEVICE_TOUCH:;
|
||||||
struct touch_state *tstate = calloc(sizeof(struct touch_state), 1);
|
struct touch_state *tstate = calloc(sizeof(struct touch_state), 1);
|
||||||
tstate->device = device;
|
tstate->wlr_touch = wlr_touch_from_input_device(device);
|
||||||
tstate->sample = sample;
|
tstate->sample = sample;
|
||||||
tstate->destroy.notify = touch_destroy_notify;
|
tstate->destroy.notify = touch_destroy_notify;
|
||||||
wl_signal_add(&device->events.destroy, &tstate->destroy);
|
wl_signal_add(&device->events.destroy, &tstate->destroy);
|
||||||
tstate->down.notify = touch_down_notify;
|
tstate->down.notify = touch_down_notify;
|
||||||
wl_signal_add(&device->touch->events.down, &tstate->down);
|
wl_signal_add(&tstate->wlr_touch->events.down, &tstate->down);
|
||||||
tstate->motion.notify = touch_motion_notify;
|
tstate->motion.notify = touch_motion_notify;
|
||||||
wl_signal_add(&device->touch->events.motion, &tstate->motion);
|
wl_signal_add(&tstate->wlr_touch->events.motion, &tstate->motion);
|
||||||
tstate->up.notify = touch_up_notify;
|
tstate->up.notify = touch_up_notify;
|
||||||
wl_signal_add(&device->touch->events.up, &tstate->up);
|
wl_signal_add(&tstate->wlr_touch->events.up, &tstate->up);
|
||||||
wl_list_insert(&sample->touch, &tstate->link);
|
wl_list_insert(&sample->touch, &tstate->link);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ struct wlr_drm_backend {
|
||||||
const struct wlr_drm_interface *iface;
|
const struct wlr_drm_interface *iface;
|
||||||
clockid_t clock;
|
clockid_t clock;
|
||||||
bool addfb2_modifiers;
|
bool addfb2_modifiers;
|
||||||
|
struct udev_hwdb *hwdb;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
@ -89,15 +90,6 @@ struct wlr_drm_backend {
|
||||||
struct wlr_drm_format_set mgpu_formats;
|
struct wlr_drm_format_set mgpu_formats;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum wlr_drm_connector_status {
|
|
||||||
// Connector is available but no output is plugged in
|
|
||||||
WLR_DRM_CONN_DISCONNECTED,
|
|
||||||
// An output just has been plugged in and is waiting for a modeset
|
|
||||||
WLR_DRM_CONN_NEEDS_MODESET,
|
|
||||||
WLR_DRM_CONN_CLEANUP,
|
|
||||||
WLR_DRM_CONN_CONNECTED,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wlr_drm_mode {
|
struct wlr_drm_mode {
|
||||||
struct wlr_output_mode wlr_mode;
|
struct wlr_output_mode wlr_mode;
|
||||||
drmModeModeInfo drm_mode;
|
drmModeModeInfo drm_mode;
|
||||||
|
|
@ -115,9 +107,10 @@ struct wlr_drm_connector {
|
||||||
|
|
||||||
struct wlr_drm_backend *backend;
|
struct wlr_drm_backend *backend;
|
||||||
char name[24];
|
char name[24];
|
||||||
enum wlr_drm_connector_status status;
|
drmModeConnection status;
|
||||||
bool desired_enabled;
|
bool desired_enabled;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
uint64_t max_bpc;
|
||||||
struct wlr_drm_lease *lease;
|
struct wlr_drm_lease *lease;
|
||||||
|
|
||||||
struct wlr_drm_crtc *crtc;
|
struct wlr_drm_crtc *crtc;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ union wlr_drm_connector_props {
|
||||||
uint32_t non_desktop;
|
uint32_t non_desktop;
|
||||||
uint32_t panel_orientation; // not guaranteed to exist
|
uint32_t panel_orientation; // not guaranteed to exist
|
||||||
uint32_t tile;
|
uint32_t tile;
|
||||||
|
uint32_t content_type; // not guaranteed to exist
|
||||||
|
uint32_t max_bpc; // not guaranteed to exist
|
||||||
|
|
||||||
// atomic-modesetting only
|
// atomic-modesetting only
|
||||||
|
|
||||||
|
|
@ -76,4 +78,7 @@ bool get_drm_prop(int fd, uint32_t obj, uint32_t prop, uint64_t *ret);
|
||||||
void *get_drm_prop_blob(int fd, uint32_t obj, uint32_t prop, size_t *ret_len);
|
void *get_drm_prop_blob(int fd, uint32_t obj, uint32_t prop, size_t *ret_len);
|
||||||
char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop);
|
char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop);
|
||||||
|
|
||||||
|
bool introspect_drm_prop_range(int fd, uint32_t prop_id,
|
||||||
|
uint64_t *min, uint64_t *max);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,6 @@ struct wlr_drm_renderer {
|
||||||
|
|
||||||
struct wlr_drm_surface {
|
struct wlr_drm_surface {
|
||||||
struct wlr_drm_renderer *renderer;
|
struct wlr_drm_renderer *renderer;
|
||||||
|
|
||||||
uint32_t width;
|
|
||||||
uint32_t height;
|
|
||||||
|
|
||||||
struct wlr_swapchain *swapchain;
|
struct wlr_swapchain *swapchain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -40,7 +36,7 @@ bool init_drm_renderer(struct wlr_drm_backend *drm,
|
||||||
void finish_drm_renderer(struct wlr_drm_renderer *renderer);
|
void finish_drm_renderer(struct wlr_drm_renderer *renderer);
|
||||||
|
|
||||||
bool init_drm_surface(struct wlr_drm_surface *surf,
|
bool init_drm_surface(struct wlr_drm_surface *surf,
|
||||||
struct wlr_drm_renderer *renderer, uint32_t width, uint32_t height,
|
struct wlr_drm_renderer *renderer, int width, int height,
|
||||||
const struct wlr_drm_format *drm_format);
|
const struct wlr_drm_format *drm_format);
|
||||||
|
|
||||||
bool drm_fb_import(struct wlr_drm_fb **fb, struct wlr_drm_backend *drm,
|
bool drm_fb_import(struct wlr_drm_fb **fb, struct wlr_drm_backend *drm,
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,17 @@
|
||||||
#define BACKEND_DRM_UTIL_H
|
#define BACKEND_DRM_UTIL_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
|
||||||
|
struct wlr_drm_connector;
|
||||||
|
|
||||||
// Calculates a more accurate refresh rate (mHz) than what mode itself provides
|
// Calculates a more accurate refresh rate (mHz) than what mode itself provides
|
||||||
int32_t calculate_refresh_rate(const drmModeModeInfo *mode);
|
int32_t calculate_refresh_rate(const drmModeModeInfo *mode);
|
||||||
// Populates the make/model/phys_{width,height} of output from the edid data
|
// Populates the make/model/phys_{width,height} of output from the edid data
|
||||||
void parse_edid(struct wlr_output *restrict output, size_t len,
|
void parse_edid(struct wlr_drm_connector *conn, size_t len, const uint8_t *data);
|
||||||
const uint8_t *data);
|
|
||||||
// Parses the TILE property
|
// Parses the TILE property
|
||||||
void parse_tile(struct wlr_output *restrict output, size_t len,
|
void parse_tile(struct wlr_drm_connector *conn, size_t len, const uint8_t *data);
|
||||||
const uint8_t *data);
|
|
||||||
// Returns the string representation of a DRM output type
|
|
||||||
const char *conn_get_name(uint32_t type_id);
|
|
||||||
|
|
||||||
// Part of match_obj
|
// Part of match_obj
|
||||||
enum {
|
enum {
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,12 @@
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/backend/interface.h>
|
#include <wlr/backend/interface.h>
|
||||||
#include <wlr/backend/libinput.h>
|
#include <wlr/backend/libinput.h>
|
||||||
#include <wlr/interfaces/wlr_keyboard.h>
|
#include <wlr/types/wlr_keyboard.h>
|
||||||
#include <wlr/interfaces/wlr_pointer.h>
|
#include <wlr/types/wlr_pointer.h>
|
||||||
#include <wlr/interfaces/wlr_switch.h>
|
#include <wlr/types/wlr_switch.h>
|
||||||
#include <wlr/interfaces/wlr_tablet_pad.h>
|
#include <wlr/types/wlr_tablet_pad.h>
|
||||||
#include <wlr/interfaces/wlr_tablet_tool.h>
|
#include <wlr/types/wlr_tablet_tool.h>
|
||||||
#include <wlr/interfaces/wlr_touch.h>
|
#include <wlr/types/wlr_touch.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
|
|
||||||
struct wlr_libinput_backend {
|
struct wlr_libinput_backend {
|
||||||
struct wlr_backend backend;
|
struct wlr_backend backend;
|
||||||
|
|
@ -26,13 +25,21 @@ struct wlr_libinput_backend {
|
||||||
struct wl_listener session_destroy;
|
struct wl_listener session_destroy;
|
||||||
struct wl_listener session_signal;
|
struct wl_listener session_signal;
|
||||||
|
|
||||||
struct wl_array wlr_device_lists; // struct wl_list *
|
struct wl_list devices; // wlr_libinput_device::link
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_libinput_input_device {
|
struct wlr_libinput_input_device {
|
||||||
struct wlr_input_device wlr_input_device;
|
|
||||||
struct wl_list link;
|
|
||||||
struct libinput_device *handle;
|
struct libinput_device *handle;
|
||||||
|
|
||||||
|
struct wlr_keyboard keyboard;
|
||||||
|
struct wlr_pointer pointer;
|
||||||
|
struct wlr_switch switch_device;
|
||||||
|
struct wlr_touch touch;
|
||||||
|
struct wlr_tablet tablet;
|
||||||
|
struct wl_list tablet_tools; // see backend/libinput/tablet_tool.c
|
||||||
|
struct wlr_tablet_pad tablet_pad;
|
||||||
|
|
||||||
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t usec_to_msec(uint64_t usec);
|
uint32_t usec_to_msec(uint64_t usec);
|
||||||
|
|
@ -40,10 +47,6 @@ uint32_t usec_to_msec(uint64_t usec);
|
||||||
void handle_libinput_event(struct wlr_libinput_backend *state,
|
void handle_libinput_event(struct wlr_libinput_backend *state,
|
||||||
struct libinput_event *event);
|
struct libinput_event *event);
|
||||||
|
|
||||||
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);
|
void destroy_libinput_input_device(struct wlr_libinput_input_device *dev);
|
||||||
|
|
||||||
extern const struct wlr_keyboard_impl libinput_keyboard_impl;
|
extern const struct wlr_keyboard_impl libinput_keyboard_impl;
|
||||||
|
|
@ -53,74 +56,83 @@ extern const struct wlr_tablet_impl libinput_tablet_impl;
|
||||||
extern const struct wlr_tablet_pad_impl libinput_tablet_pad_impl;
|
extern const struct wlr_tablet_pad_impl libinput_tablet_pad_impl;
|
||||||
extern const struct wlr_touch_impl libinput_touch_impl;
|
extern const struct wlr_touch_impl libinput_touch_impl;
|
||||||
|
|
||||||
struct wlr_keyboard *create_libinput_keyboard(
|
void init_device_keyboard(struct wlr_libinput_input_device *dev);
|
||||||
struct libinput_device *device);
|
struct wlr_libinput_input_device *device_from_keyboard(struct wlr_keyboard *kb);
|
||||||
void handle_keyboard_key(struct libinput_event *event,
|
void handle_keyboard_key(struct libinput_event *event, struct wlr_keyboard *kb);
|
||||||
struct libinput_device *device);
|
|
||||||
|
|
||||||
struct wlr_pointer *create_libinput_pointer(
|
void init_device_pointer(struct wlr_libinput_input_device *dev);
|
||||||
struct libinput_device *device);
|
struct wlr_libinput_input_device *device_from_pointer(struct wlr_pointer *kb);
|
||||||
void handle_pointer_motion(struct libinput_event *event,
|
void handle_pointer_motion(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_motion_abs(struct libinput_event *event,
|
void handle_pointer_motion_abs(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_button(struct libinput_event *event,
|
void handle_pointer_button(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_axis(struct libinput_event *event,
|
void handle_pointer_axis(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
|
#if LIBINPUT_HAS_SCROLL_VALUE120
|
||||||
|
void handle_pointer_axis_value120(struct libinput_event *event,
|
||||||
|
struct wlr_pointer *pointer, enum wlr_axis_source source);
|
||||||
|
#endif
|
||||||
void handle_pointer_swipe_begin(struct libinput_event *event,
|
void handle_pointer_swipe_begin(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_swipe_update(struct libinput_event *event,
|
void handle_pointer_swipe_update(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_swipe_end(struct libinput_event *event,
|
void handle_pointer_swipe_end(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_pinch_begin(struct libinput_event *event,
|
void handle_pointer_pinch_begin(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_pinch_update(struct libinput_event *event,
|
void handle_pointer_pinch_update(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_pinch_end(struct libinput_event *event,
|
void handle_pointer_pinch_end(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_hold_begin(struct libinput_event *event,
|
void handle_pointer_hold_begin(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
void handle_pointer_hold_end(struct libinput_event *event,
|
void handle_pointer_hold_end(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_pointer *pointer);
|
||||||
|
|
||||||
struct wlr_switch *create_libinput_switch(
|
void init_device_switch(struct wlr_libinput_input_device *dev);
|
||||||
struct libinput_device *device);
|
struct wlr_libinput_input_device *device_from_switch(
|
||||||
|
struct wlr_switch *switch_device);
|
||||||
void handle_switch_toggle(struct libinput_event *event,
|
void handle_switch_toggle(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_switch *switch_device);
|
||||||
|
|
||||||
struct wlr_touch *create_libinput_touch(
|
void init_device_touch(struct wlr_libinput_input_device *dev);
|
||||||
struct libinput_device *device);
|
struct wlr_libinput_input_device *device_from_touch(
|
||||||
|
struct wlr_touch *touch);
|
||||||
void handle_touch_down(struct libinput_event *event,
|
void handle_touch_down(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_touch *touch);
|
||||||
void handle_touch_up(struct libinput_event *event,
|
void handle_touch_up(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_touch *touch);
|
||||||
void handle_touch_motion(struct libinput_event *event,
|
void handle_touch_motion(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_touch *touch);
|
||||||
void handle_touch_cancel(struct libinput_event *event,
|
void handle_touch_cancel(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_touch *touch);
|
||||||
void handle_touch_frame(struct libinput_event *event,
|
void handle_touch_frame(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_touch *touch);
|
||||||
|
|
||||||
struct wlr_tablet *create_libinput_tablet(
|
void init_device_tablet(struct wlr_libinput_input_device *dev);
|
||||||
struct libinput_device *device);
|
void finish_device_tablet(struct wlr_libinput_input_device *dev);
|
||||||
|
struct wlr_libinput_input_device *device_from_tablet(
|
||||||
|
struct wlr_tablet *tablet);
|
||||||
void handle_tablet_tool_axis(struct libinput_event *event,
|
void handle_tablet_tool_axis(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_tablet *tablet);
|
||||||
void handle_tablet_tool_proximity(struct libinput_event *event,
|
void handle_tablet_tool_proximity(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_tablet *tablet);
|
||||||
void handle_tablet_tool_tip(struct libinput_event *event,
|
void handle_tablet_tool_tip(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_tablet *tablet);
|
||||||
void handle_tablet_tool_button(struct libinput_event *event,
|
void handle_tablet_tool_button(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_tablet *tablet);
|
||||||
|
|
||||||
struct wlr_tablet_pad *create_libinput_tablet_pad(
|
void init_device_tablet_pad(struct wlr_libinput_input_device *dev);
|
||||||
struct libinput_device *device);
|
void finish_device_tablet_pad(struct wlr_libinput_input_device *dev);
|
||||||
|
struct wlr_libinput_input_device *device_from_tablet_pad(
|
||||||
|
struct wlr_tablet_pad *tablet_pad);
|
||||||
void handle_tablet_pad_button(struct libinput_event *event,
|
void handle_tablet_pad_button(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_tablet_pad *tablet_pad);
|
||||||
void handle_tablet_pad_ring(struct libinput_event *event,
|
void handle_tablet_pad_ring(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_tablet_pad *tablet_pad);
|
||||||
void handle_tablet_pad_strip(struct libinput_event *event,
|
void handle_tablet_pad_strip(struct libinput_event *event,
|
||||||
struct libinput_device *device);
|
struct wlr_tablet_pad *tablet_pad);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,11 @@
|
||||||
|
|
||||||
#include <wlr/backend/wayland.h>
|
#include <wlr/backend/wayland.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
|
#include <wlr/types/wlr_keyboard.h>
|
||||||
#include <wlr/types/wlr_pointer.h>
|
#include <wlr/types/wlr_pointer.h>
|
||||||
|
#include <wlr/types/wlr_tablet_pad.h>
|
||||||
|
#include <wlr/types/wlr_tablet_tool.h>
|
||||||
|
#include <wlr/types/wlr_touch.h>
|
||||||
#include <wlr/render/drm_format_set.h>
|
#include <wlr/render/drm_format_set.h>
|
||||||
|
|
||||||
struct wlr_wl_backend {
|
struct wlr_wl_backend {
|
||||||
|
|
@ -17,7 +21,6 @@ struct wlr_wl_backend {
|
||||||
/* local state */
|
/* local state */
|
||||||
bool started;
|
bool started;
|
||||||
struct wl_display *local_display;
|
struct wl_display *local_display;
|
||||||
struct wl_list devices;
|
|
||||||
struct wl_list outputs;
|
struct wl_list outputs;
|
||||||
int drm_fd;
|
int drm_fd;
|
||||||
struct wl_list buffers; // wlr_wl_buffer.link
|
struct wl_list buffers; // wlr_wl_buffer.link
|
||||||
|
|
@ -85,64 +88,73 @@ struct wlr_wl_output {
|
||||||
} cursor;
|
} cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_wl_input_device {
|
|
||||||
struct wlr_input_device wlr_input_device;
|
|
||||||
struct wl_list link;
|
|
||||||
uint32_t fingers;
|
|
||||||
|
|
||||||
struct wlr_wl_backend *backend;
|
|
||||||
struct wlr_wl_seat *seat;
|
|
||||||
void *resource;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wlr_wl_pointer {
|
struct wlr_wl_pointer {
|
||||||
struct wlr_pointer wlr_pointer;
|
struct wlr_pointer wlr_pointer;
|
||||||
|
|
||||||
struct wlr_wl_input_device *input_device;
|
struct wlr_wl_seat *seat;
|
||||||
|
struct wlr_wl_output *output;
|
||||||
|
|
||||||
|
enum wlr_axis_source axis_source;
|
||||||
|
int32_t axis_discrete;
|
||||||
|
uint32_t fingers; // trackpad gesture
|
||||||
|
|
||||||
|
struct wl_listener output_destroy;
|
||||||
|
|
||||||
|
struct wl_list link;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_wl_seat {
|
||||||
|
char *name;
|
||||||
|
struct wl_seat *wl_seat;
|
||||||
|
|
||||||
|
struct wlr_wl_backend *backend;
|
||||||
|
|
||||||
|
struct wl_keyboard *wl_keyboard;
|
||||||
|
struct wlr_keyboard wlr_keyboard;
|
||||||
|
|
||||||
struct wl_pointer *wl_pointer;
|
struct wl_pointer *wl_pointer;
|
||||||
|
struct wlr_wl_pointer *active_pointer;
|
||||||
|
struct wl_list pointers; // wlr_wl_pointer::link
|
||||||
|
|
||||||
struct zwp_pointer_gesture_swipe_v1 *gesture_swipe;
|
struct zwp_pointer_gesture_swipe_v1 *gesture_swipe;
|
||||||
struct zwp_pointer_gesture_pinch_v1 *gesture_pinch;
|
struct zwp_pointer_gesture_pinch_v1 *gesture_pinch;
|
||||||
struct zwp_pointer_gesture_hold_v1 *gesture_hold;
|
struct zwp_pointer_gesture_hold_v1 *gesture_hold;
|
||||||
struct zwp_relative_pointer_v1 *relative_pointer;
|
struct zwp_relative_pointer_v1 *relative_pointer;
|
||||||
enum wlr_axis_source axis_source;
|
|
||||||
int32_t axis_discrete;
|
|
||||||
struct wlr_wl_output *output;
|
|
||||||
|
|
||||||
struct wl_listener output_destroy;
|
struct wl_touch *wl_touch;
|
||||||
};
|
struct wlr_touch wlr_touch;
|
||||||
|
|
||||||
struct wlr_wl_seat {
|
struct zwp_tablet_seat_v2 *zwp_tablet_seat_v2;
|
||||||
struct wl_seat *wl_seat;
|
struct zwp_tablet_v2 *zwp_tablet_v2;
|
||||||
|
struct wlr_tablet wlr_tablet;
|
||||||
|
struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2;
|
||||||
|
struct wlr_tablet_tool wlr_tablet_tool;
|
||||||
|
struct zwp_tablet_pad_v2 *zwp_tablet_pad_v2;
|
||||||
|
struct wlr_tablet_pad wlr_tablet_pad;
|
||||||
|
|
||||||
struct wl_list link; // wlr_wl_backend.seats
|
struct wl_list link; // wlr_wl_backend.seats
|
||||||
char *name;
|
|
||||||
struct wl_touch *touch;
|
|
||||||
struct wl_pointer *pointer;
|
|
||||||
struct wl_keyboard *keyboard;
|
|
||||||
|
|
||||||
struct wlr_wl_backend *backend;
|
|
||||||
struct wlr_wl_pointer *active_pointer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_wl_backend *get_wl_backend_from_backend(struct wlr_backend *backend);
|
struct wlr_wl_backend *get_wl_backend_from_backend(struct wlr_backend *backend);
|
||||||
void update_wl_output_cursor(struct wlr_wl_output *output);
|
void update_wl_output_cursor(struct wlr_wl_output *output);
|
||||||
struct wlr_wl_pointer *pointer_get_wl(struct wlr_pointer *wlr_pointer);
|
|
||||||
void create_wl_pointer(struct wlr_wl_seat *seat, struct wlr_wl_output *output);
|
void init_seat_keyboard(struct wlr_wl_seat *seat);
|
||||||
void create_wl_keyboard(struct wlr_wl_seat *seat);
|
|
||||||
void create_wl_touch(struct wlr_wl_seat *seat);
|
void init_seat_pointer(struct wlr_wl_seat *seat);
|
||||||
struct wlr_wl_input_device *create_wl_input_device(
|
void finish_seat_pointer(struct wlr_wl_seat *seat);
|
||||||
struct wlr_wl_seat *seat, enum wlr_input_device_type type);
|
void create_pointer(struct wlr_wl_seat *seat, struct wlr_wl_output *output);
|
||||||
|
|
||||||
|
void init_seat_touch(struct wlr_wl_seat *seat);
|
||||||
|
|
||||||
|
void init_seat_tablet(struct wlr_wl_seat *seat);
|
||||||
|
void finish_seat_tablet(struct wlr_wl_seat *seat);
|
||||||
|
|
||||||
bool create_wl_seat(struct wl_seat *wl_seat, struct wlr_wl_backend *wl);
|
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_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);
|
void destroy_wl_buffer(struct wlr_wl_buffer *buffer);
|
||||||
|
|
||||||
extern const struct wl_seat_listener seat_listener;
|
extern const struct wlr_pointer_impl wl_pointer_impl;
|
||||||
extern const struct wlr_tablet_pad_impl tablet_pad_impl;
|
extern const struct wlr_tablet_pad_impl wl_tablet_pad_impl;
|
||||||
extern const struct wlr_tablet_impl tablet_impl;
|
extern const struct wlr_tablet_impl wl_tablet_impl;
|
||||||
|
|
||||||
struct wlr_wl_tablet_seat *wl_add_tablet_seat(
|
|
||||||
struct zwp_tablet_manager_v2 *manager,
|
|
||||||
struct wlr_wl_seat *seat);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
20
include/interfaces/wlr_input_device.h
Normal file
20
include/interfaces/wlr_input_device.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef INTERFACES_INPUT_DEVICE_H
|
||||||
|
#define INTERFACES_INPUT_DEVICE_H
|
||||||
|
|
||||||
|
#include <wlr/types/wlr_input_device.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a given wlr_input_device. Allocates memory for the name and sets
|
||||||
|
* its vendor and product id to 0.
|
||||||
|
* wlr_device must be non-NULL.
|
||||||
|
*/
|
||||||
|
void wlr_input_device_init(struct wlr_input_device *wlr_device,
|
||||||
|
enum wlr_input_device_type type, const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up all the memory owned by a given wlr_input_device and signals
|
||||||
|
* the destroy event.
|
||||||
|
*/
|
||||||
|
void wlr_input_device_finish(struct wlr_input_device *wlr_device);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -3,6 +3,47 @@
|
||||||
|
|
||||||
#include <wlr/render/egl.h>
|
#include <wlr/render/egl.h>
|
||||||
|
|
||||||
|
struct wlr_egl {
|
||||||
|
EGLDisplay display;
|
||||||
|
EGLContext context;
|
||||||
|
EGLDeviceEXT device; // may be EGL_NO_DEVICE_EXT
|
||||||
|
struct gbm_device *gbm_device;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
// Display extensions
|
||||||
|
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;
|
||||||
|
bool EXT_device_drm_render_node;
|
||||||
|
|
||||||
|
// Client extensions
|
||||||
|
bool EXT_device_query;
|
||||||
|
bool KHR_platform_gbm;
|
||||||
|
bool EXT_platform_device;
|
||||||
|
} exts;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
|
||||||
|
PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
|
||||||
|
PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
|
||||||
|
PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL;
|
||||||
|
PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT;
|
||||||
|
PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT;
|
||||||
|
PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR;
|
||||||
|
PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT;
|
||||||
|
PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT;
|
||||||
|
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_context {
|
struct wlr_egl_context {
|
||||||
EGLDisplay display;
|
EGLDisplay display;
|
||||||
EGLContext context;
|
EGLContext context;
|
||||||
|
|
@ -60,4 +101,16 @@ void wlr_egl_save_context(struct wlr_egl_context *context);
|
||||||
*/
|
*/
|
||||||
bool wlr_egl_restore_context(struct wlr_egl_context *context);
|
bool wlr_egl_restore_context(struct wlr_egl_context *context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the EGL context current.
|
||||||
|
*
|
||||||
|
* Callers are expected to clear the current context when they are done by
|
||||||
|
* calling wlr_egl_unset_current().
|
||||||
|
*/
|
||||||
|
bool wlr_egl_make_current(struct wlr_egl *egl);
|
||||||
|
|
||||||
|
bool wlr_egl_unset_current(struct wlr_egl *egl);
|
||||||
|
|
||||||
|
bool wlr_egl_is_current(struct wlr_egl *egl);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
struct wlr_gles2_pixel_format {
|
struct wlr_gles2_pixel_format {
|
||||||
uint32_t drm_format;
|
uint32_t drm_format;
|
||||||
|
// optional field, if empty then internalformat = format
|
||||||
|
GLint gl_internalformat;
|
||||||
GLint gl_format, gl_type;
|
GLint gl_format, gl_type;
|
||||||
bool has_alpha;
|
bool has_alpha;
|
||||||
};
|
};
|
||||||
|
|
@ -45,6 +47,7 @@ struct wlr_gles2_renderer {
|
||||||
bool OES_egl_image;
|
bool OES_egl_image;
|
||||||
bool EXT_texture_type_2_10_10_10_REV;
|
bool EXT_texture_type_2_10_10_10_REV;
|
||||||
bool OES_texture_half_float_linear;
|
bool OES_texture_half_float_linear;
|
||||||
|
bool EXT_texture_norm16;
|
||||||
} exts;
|
} exts;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
|
|
@ -69,4 +69,13 @@ struct wlr_dmabuf_buffer *dmabuf_buffer_create(
|
||||||
*/
|
*/
|
||||||
bool dmabuf_buffer_drop(struct wlr_dmabuf_buffer *buffer);
|
bool dmabuf_buffer_drop(struct wlr_dmabuf_buffer *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a buffer is fully opaque.
|
||||||
|
*
|
||||||
|
* When true is returned, the buffer is guaranteed to be fully opaque, but the
|
||||||
|
* reverse is not true: false may be returned in cases where the buffer is fully
|
||||||
|
* opaque.
|
||||||
|
*/
|
||||||
|
bool buffer_is_opaque(struct wlr_buffer *buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <wlr/types/wlr_keyboard.h>
|
#include <wlr/types/wlr_keyboard.h>
|
||||||
|
|
||||||
void keyboard_key_update(struct wlr_keyboard *keyboard,
|
void keyboard_key_update(struct wlr_keyboard *keyboard,
|
||||||
struct wlr_event_keyboard_key *event);
|
struct wlr_keyboard_key_event *event);
|
||||||
|
|
||||||
bool keyboard_modifier_update(struct wlr_keyboard *keyboard);
|
bool keyboard_modifier_update(struct wlr_keyboard *keyboard);
|
||||||
|
|
||||||
|
|
|
||||||
15
include/types/wlr_matrix.h
Normal file
15
include/types/wlr_matrix.h
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef TYPES_WLR_MATRIX_H
|
||||||
|
#define TYPES_WLR_MATRIX_H
|
||||||
|
|
||||||
|
#include <wlr/types/wlr_matrix.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a 2D orthographic projection matrix to mat of (width, height) with a
|
||||||
|
* specified wl_output_transform.
|
||||||
|
*
|
||||||
|
* Equivalent to glOrtho(0, width, 0, height, 1, -1) with the transform applied.
|
||||||
|
*/
|
||||||
|
void matrix_projection(float mat[static 9], int width, int height,
|
||||||
|
enum wl_output_transform transform);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -4,12 +4,15 @@
|
||||||
#include <wlr/render/drm_format_set.h>
|
#include <wlr/render/drm_format_set.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
|
||||||
void output_pending_resolution(struct wlr_output *output, int *width,
|
void output_pending_resolution(struct wlr_output *output,
|
||||||
int *height);
|
const struct wlr_output_state *state, int *width, int *height);
|
||||||
|
void output_state_attach_buffer(struct wlr_output_state *state,
|
||||||
|
struct wlr_buffer *buffer);
|
||||||
|
|
||||||
struct wlr_drm_format *output_pick_format(struct wlr_output *output,
|
struct wlr_drm_format *output_pick_format(struct wlr_output *output,
|
||||||
const struct wlr_drm_format_set *display_formats, uint32_t format);
|
const struct wlr_drm_format_set *display_formats, uint32_t format);
|
||||||
void output_clear_back_buffer(struct wlr_output *output);
|
void output_clear_back_buffer(struct wlr_output *output);
|
||||||
bool output_ensure_buffer(struct wlr_output *output);
|
bool output_ensure_buffer(struct wlr_output *output,
|
||||||
|
const struct wlr_output_state *state, bool *new_back_buffer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
8
include/types/wlr_scene.h
Normal file
8
include/types/wlr_scene.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef TYPES_WLR_SCENE_H
|
||||||
|
#define TYPES_WLR_SCENE_H
|
||||||
|
|
||||||
|
#include <wlr/types/wlr_scene.h>
|
||||||
|
|
||||||
|
struct wlr_scene *scene_node_get_root(struct wlr_scene_node *node);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -26,6 +26,10 @@ void create_xdg_popup(struct wlr_xdg_surface *surface,
|
||||||
void unmap_xdg_popup(struct wlr_xdg_popup *popup);
|
void unmap_xdg_popup(struct wlr_xdg_popup *popup);
|
||||||
void destroy_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 handle_xdg_popup_committed(struct wlr_xdg_popup *popup);
|
||||||
|
struct wlr_xdg_popup_configure *send_xdg_popup_configure(
|
||||||
|
struct wlr_xdg_popup *popup);
|
||||||
|
void handle_xdg_popup_ack_configure(struct wlr_xdg_popup *popup,
|
||||||
|
struct wlr_xdg_popup_configure *configure);
|
||||||
|
|
||||||
void create_xdg_toplevel(struct wlr_xdg_surface *surface,
|
void create_xdg_toplevel(struct wlr_xdg_surface *surface,
|
||||||
uint32_t id);
|
uint32_t id);
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,18 @@
|
||||||
#ifndef UTIL_ARRAY_H
|
#ifndef UTIL_ARRAY_H
|
||||||
#define UTIL_ARRAY_H
|
#define UTIL_ARRAY_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wayland-util.h>
|
#include <wayland-util.h>
|
||||||
|
|
||||||
size_t push_zeroes_to_end(uint32_t arr[], size_t n);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add `target` to `values` if it doesn't exist
|
|
||||||
* "set"s should only be modified with set_* functions
|
|
||||||
* Values MUST be greater than 0
|
|
||||||
*/
|
|
||||||
bool set_add(uint32_t values[], size_t *len, size_t cap, uint32_t target);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove `target` from `values` if it exists
|
|
||||||
* "set"s should only be modified with set_* functions
|
|
||||||
* Values MUST be greater than 0
|
|
||||||
*/
|
|
||||||
bool set_remove(uint32_t values[], size_t *len, size_t cap, uint32_t target);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a chunk of memory of the specified size at the specified offset.
|
* Remove a chunk of memory of the specified size at the specified offset.
|
||||||
*/
|
*/
|
||||||
void array_remove_at(struct wl_array *arr, size_t offset, size_t size);
|
void array_remove_at(struct wl_array *arr, size_t offset, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grow or shrink the array to fit the specifized size.
|
||||||
|
*/
|
||||||
|
bool array_realloc(struct wl_array *arr, size_t size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
11
include/util/env.h
Normal file
11
include/util/env.h
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef UTIL_ENV_H
|
||||||
|
#define UTIL_ENV_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
bool env_parse_bool(const char *option);
|
||||||
|
|
||||||
|
ssize_t env_parse_switch(const char *option, const char **switches);
|
||||||
|
|
||||||
|
#endif
|
||||||
29
include/util/set.h
Normal file
29
include/util/set.h
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef UTIL_SET_H
|
||||||
|
#define UTIL_SET_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add target to values.
|
||||||
|
*
|
||||||
|
* Target is added to the end of the set.
|
||||||
|
*
|
||||||
|
* Returns the index of target, or -1 if the set is full or target already
|
||||||
|
* exists.
|
||||||
|
*/
|
||||||
|
ssize_t set_add(uint32_t values[], size_t *len, size_t cap, uint32_t target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove target from values.
|
||||||
|
*
|
||||||
|
* When target is removed, the last element of the set is moved to where
|
||||||
|
* target was.
|
||||||
|
*
|
||||||
|
* Returns the previous index of target, or -1 if target wasn't in values.
|
||||||
|
*/
|
||||||
|
ssize_t set_remove(uint32_t values[], size_t *len, size_t cap, uint32_t target);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef UTIL_SIGNAL_H
|
|
||||||
#define UTIL_SIGNAL_H
|
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
|
||||||
|
|
||||||
void wlr_signal_emit_safe(struct wl_signal *signal, void *data);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -14,22 +14,25 @@
|
||||||
|
|
||||||
struct wlr_backend_impl;
|
struct wlr_backend_impl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A backend provides a set of input and output devices.
|
||||||
|
*/
|
||||||
struct wlr_backend {
|
struct wlr_backend {
|
||||||
const struct wlr_backend_impl *impl;
|
const struct wlr_backend_impl *impl;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/** Raised when destroyed, passed the wlr_backend reference */
|
/** Raised when destroyed */
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
/** Raised when new inputs are added, passed the wlr_input_device */
|
/** Raised when new inputs are added, passed the struct wlr_input_device */
|
||||||
struct wl_signal new_input;
|
struct wl_signal new_input;
|
||||||
/** Raised when new outputs are added, passed the wlr_output */
|
/** Raised when new outputs are added, passed the struct wlr_output */
|
||||||
struct wl_signal new_output;
|
struct wl_signal new_output;
|
||||||
} events;
|
} events;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically initializes the most suitable backend given the environment.
|
* Automatically initializes the most suitable backend given the environment.
|
||||||
* Will always return a multibackend. The backend is created but not started.
|
* Will always return a multi-backend. The backend is created but not started.
|
||||||
* Returns NULL on failure.
|
* Returns NULL on failure.
|
||||||
*/
|
*/
|
||||||
struct wlr_backend *wlr_backend_autocreate(struct wl_display *display);
|
struct wlr_backend *wlr_backend_autocreate(struct wl_display *display);
|
||||||
|
|
@ -41,11 +44,11 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_display *display);
|
||||||
bool wlr_backend_start(struct wlr_backend *backend);
|
bool wlr_backend_start(struct wlr_backend *backend);
|
||||||
/**
|
/**
|
||||||
* Destroy the backend and clean up all of its resources. Normally called
|
* Destroy the backend and clean up all of its resources. Normally called
|
||||||
* automatically when the wl_display is destroyed.
|
* automatically when the struct wl_display is destroyed.
|
||||||
*/
|
*/
|
||||||
void wlr_backend_destroy(struct wlr_backend *backend);
|
void wlr_backend_destroy(struct wlr_backend *backend);
|
||||||
/**
|
/**
|
||||||
* Obtains the wlr_session reference from this backend if there is any.
|
* Obtains the struct wlr_session reference from this backend if there is any.
|
||||||
* Might return NULL for backends that don't use a session.
|
* Might return NULL for backends that don't use a session.
|
||||||
*/
|
*/
|
||||||
struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend);
|
struct wlr_session *wlr_backend_get_session(struct wlr_backend *backend);
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,9 @@ bool wlr_output_is_drm(struct wlr_output *output);
|
||||||
uint32_t wlr_drm_connector_get_id(struct wlr_output *output);
|
uint32_t wlr_drm_connector_get_id(struct wlr_output *output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to open non-master DRM FD. The compositor must not call `drmSetMaster`
|
* Tries to open non-master DRM FD. The compositor must not call drmSetMaster()
|
||||||
* on the returned FD.
|
* on the returned FD.
|
||||||
|
*
|
||||||
* Returns a valid opened DRM FD, or -1 on error.
|
* Returns a valid opened DRM FD, or -1 on error.
|
||||||
*/
|
*/
|
||||||
int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend);
|
int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend);
|
||||||
|
|
@ -71,7 +72,7 @@ struct wlr_drm_lease *wlr_drm_create_lease(struct wlr_output **outputs,
|
||||||
void wlr_drm_lease_terminate(struct wlr_drm_lease *lease);
|
void wlr_drm_lease_terminate(struct wlr_drm_lease *lease);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add mode to the list of available modes
|
* Add mode to the list of available modes.
|
||||||
*/
|
*/
|
||||||
typedef struct _drmModeModeInfo drmModeModeInfo;
|
typedef struct _drmModeModeInfo drmModeModeInfo;
|
||||||
struct wlr_output_mode *wlr_drm_connector_add_mode(struct wlr_output *output,
|
struct wlr_output_mode *wlr_drm_connector_add_mode(struct wlr_output *output,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
#define WLR_BACKEND_HEADLESS_H
|
#define WLR_BACKEND_HEADLESS_H
|
||||||
|
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -19,9 +18,9 @@
|
||||||
*/
|
*/
|
||||||
struct wlr_backend *wlr_headless_backend_create(struct wl_display *display);
|
struct wlr_backend *wlr_headless_backend_create(struct wl_display *display);
|
||||||
/**
|
/**
|
||||||
* Create a new headless output backed by an in-memory EGL framebuffer. You can
|
* Create a new headless output.
|
||||||
* read pixels from this framebuffer via wlr_renderer_read_pixels but it is
|
*
|
||||||
* otherwise not displayed.
|
* The buffers presented on the output won't be displayed to the user.
|
||||||
*/
|
*/
|
||||||
struct wlr_output *wlr_headless_add_output(struct wlr_backend *backend,
|
struct wlr_output *wlr_headless_add_output(struct wlr_backend *backend,
|
||||||
unsigned int width, unsigned int height);
|
unsigned int width, unsigned int height);
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ struct wlr_backend_impl {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes common state on a wlr_backend and sets the implementation to the
|
* Initializes common state on a struct wlr_backend and sets the implementation
|
||||||
* provided wlr_backend_impl reference.
|
* to the provided struct wlr_backend_impl reference.
|
||||||
*/
|
*/
|
||||||
void wlr_backend_init(struct wlr_backend *backend,
|
void wlr_backend_init(struct wlr_backend *backend,
|
||||||
const struct wlr_backend_impl *impl);
|
const struct wlr_backend_impl *impl);
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,14 @@
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/backend/session.h>
|
#include <wlr/backend/session.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
|
struct wlr_input_device;
|
||||||
|
|
||||||
struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display,
|
struct wlr_backend *wlr_libinput_backend_create(struct wl_display *display,
|
||||||
struct wlr_session *session);
|
struct wlr_session *session);
|
||||||
/** Gets the underlying libinput_device handle for the given wlr_input_device */
|
/**
|
||||||
|
* Gets the underlying struct libinput_device handle for the given input device.
|
||||||
|
*/
|
||||||
struct libinput_device *wlr_libinput_get_device_handle(
|
struct libinput_device *wlr_libinput_get_device_handle(
|
||||||
struct wlr_input_device *dev);
|
struct wlr_input_device *dev);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,36 +79,33 @@ struct wlr_device_change_event {
|
||||||
* This should not be called if another program is already in control
|
* This should not be called if another program is already in control
|
||||||
* of the terminal (Xorg, another Wayland compositor, etc.).
|
* of the terminal (Xorg, another Wayland compositor, etc.).
|
||||||
*
|
*
|
||||||
* If libseat support is not enabled, or if a standalone backend is to be used,
|
|
||||||
* then you must have CAP_SYS_ADMIN or be root. It is safe to drop privileges
|
|
||||||
* after this is called.
|
|
||||||
*
|
|
||||||
* Returns NULL on error.
|
* Returns NULL on error.
|
||||||
*/
|
*/
|
||||||
struct wlr_session *wlr_session_create(struct wl_display *disp);
|
struct wlr_session *wlr_session_create(struct wl_display *disp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Closes a previously opened session and restores the virtual terminal.
|
* Closes a previously opened session and restores the virtual terminal.
|
||||||
* You should call wlr_session_close_file on each files you opened
|
* You should call wlr_session_close_file() on each files you opened
|
||||||
* with wlr_session_open_file before you call this.
|
* with wlr_session_open_file() before you call this.
|
||||||
*/
|
*/
|
||||||
void wlr_session_destroy(struct wlr_session *session);
|
void wlr_session_destroy(struct wlr_session *session);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Opens the file at path.
|
* Opens the file at path.
|
||||||
* This can only be used to open DRM or evdev (input) devices.
|
*
|
||||||
|
* This can only be used to open DRM or evdev (input) devices. Files opened via
|
||||||
|
* this function must be closed by calling wlr_session_close_file().
|
||||||
*
|
*
|
||||||
* When the session becomes inactive:
|
* When the session becomes inactive:
|
||||||
|
*
|
||||||
* - DRM files lose their DRM master status
|
* - DRM files lose their DRM master status
|
||||||
* - evdev files become invalid and should be closed
|
* - evdev files become invalid and should be closed
|
||||||
*
|
|
||||||
* Returns -errno on error.
|
|
||||||
*/
|
*/
|
||||||
struct wlr_device *wlr_session_open_file(struct wlr_session *session,
|
struct wlr_device *wlr_session_open_file(struct wlr_session *session,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Closes a file previously opened with wlr_session_open_file.
|
* Closes a file previously opened with wlr_session_open_file().
|
||||||
*/
|
*/
|
||||||
void wlr_session_close_file(struct wlr_session *session,
|
void wlr_session_close_file(struct wlr_session *session,
|
||||||
struct wlr_device *device);
|
struct wlr_device *device);
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,23 @@
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
|
||||||
|
struct wlr_input_device;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new wlr_wl_backend. This backend will be created with no outputs;
|
* Creates a new Wayland backend. This backend will be created with no outputs;
|
||||||
* you must use wlr_wl_output_create to add them.
|
* you must use wlr_wl_output_create() to add them.
|
||||||
*
|
*
|
||||||
* The `remote` argument is the name of the host compositor wayland socket. Set
|
* The `remote` argument is the name of the host compositor wayland socket. Set
|
||||||
* to NULL for the default behaviour (WAYLAND_DISPLAY env variable or wayland-0
|
* to NULL for the default behaviour (WAYLAND_DISPLAY env variable or wayland-0
|
||||||
* default)
|
* default).
|
||||||
*/
|
*/
|
||||||
struct wlr_backend *wlr_wl_backend_create(struct wl_display *display,
|
struct wlr_backend *wlr_wl_backend_create(struct wl_display *display,
|
||||||
const char *remote);
|
const char *remote);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the remote wl_display used by the Wayland backend.
|
* Returns the remote struct wl_display used by the Wayland backend.
|
||||||
*/
|
*/
|
||||||
struct wl_display *wlr_wl_backend_get_remote_display(struct wlr_backend *backend);
|
struct wl_display *wlr_wl_backend_get_remote_display(struct wlr_backend *backend);
|
||||||
|
|
||||||
|
|
@ -27,37 +28,37 @@ struct wl_display *wlr_wl_backend_get_remote_display(struct wlr_backend *backend
|
||||||
* Adds a new output to this backend. You may remove outputs by destroying them.
|
* Adds a new output to this backend. You may remove outputs by destroying them.
|
||||||
* Note that if called before initializing the backend, this will return NULL
|
* Note that if called before initializing the backend, this will return NULL
|
||||||
* and your outputs will be created during initialization (and given to you via
|
* and your outputs will be created during initialization (and given to you via
|
||||||
* the output_add signal).
|
* the new_output signal).
|
||||||
*/
|
*/
|
||||||
struct wlr_output *wlr_wl_output_create(struct wlr_backend *backend);
|
struct wlr_output *wlr_wl_output_create(struct wlr_backend *backend);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the given backend is a wlr_wl_backend.
|
* Check whether the provided backend is a Wayland backend.
|
||||||
*/
|
*/
|
||||||
bool wlr_backend_is_wl(struct wlr_backend *backend);
|
bool wlr_backend_is_wl(struct wlr_backend *backend);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the given input device is a wlr_wl_input_device.
|
* Check whether the provided input device is a Wayland input device.
|
||||||
*/
|
*/
|
||||||
bool wlr_input_device_is_wl(struct wlr_input_device *device);
|
bool wlr_input_device_is_wl(struct wlr_input_device *device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the given output is a wlr_wl_output.
|
* Check whether the provided output device is a Wayland output device.
|
||||||
*/
|
*/
|
||||||
bool wlr_output_is_wl(struct wlr_output *output);
|
bool wlr_output_is_wl(struct wlr_output *output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the title of a wlr_output which is a Wayland window.
|
* Sets the title of a struct wlr_output which is a Wayland toplevel.
|
||||||
*/
|
*/
|
||||||
void wlr_wl_output_set_title(struct wlr_output *output, const char *title);
|
void wlr_wl_output_set_title(struct wlr_output *output, const char *title);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the remote wl_surface used by the Wayland output.
|
* Returns the remote struct wl_surface used by the Wayland output.
|
||||||
*/
|
*/
|
||||||
struct wl_surface *wlr_wl_output_get_surface(struct wlr_output *output);
|
struct wl_surface *wlr_wl_output_get_surface(struct wlr_output *output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the remote wl_seat for a Wayland input device.
|
* Returns the remote struct wl_seat for a Wayland input device.
|
||||||
*/
|
*/
|
||||||
struct wl_seat *wlr_wl_input_device_get_seat(struct wlr_input_device *dev);
|
struct wl_seat *wlr_wl_input_device_get_seat(struct wlr_input_device *dev);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,16 @@
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
|
||||||
|
struct wlr_input_device;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new wlr_x11_backend. This backend will be created with no outputs;
|
* Creates a new X11 backend. This backend will be created with no outputs;
|
||||||
* you must use wlr_x11_output_create to add them.
|
* you must use wlr_x11_output_create() to add them.
|
||||||
*
|
*
|
||||||
* The `x11_display` argument is the name of the X Display socket. Set
|
* The `x11_display` argument is the name of the X Display socket. Set
|
||||||
* to NULL for the default behaviour of XOpenDisplay.
|
* to NULL for the default behaviour of XOpenDisplay().
|
||||||
*/
|
*/
|
||||||
struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
||||||
const char *x11_display);
|
const char *x11_display);
|
||||||
|
|
@ -23,27 +24,27 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
|
||||||
* Adds a new output to this backend. You may remove outputs by destroying them.
|
* Adds a new output to this backend. You may remove outputs by destroying them.
|
||||||
* Note that if called before initializing the backend, this will return NULL
|
* Note that if called before initializing the backend, this will return NULL
|
||||||
* and your outputs will be created during initialization (and given to you via
|
* and your outputs will be created during initialization (and given to you via
|
||||||
* the output_add signal).
|
* the new_output signal).
|
||||||
*/
|
*/
|
||||||
struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend);
|
struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the given backend is a wlr_x11_backend.
|
* Check whether this backend is an X11 backend.
|
||||||
*/
|
*/
|
||||||
bool wlr_backend_is_x11(struct wlr_backend *backend);
|
bool wlr_backend_is_x11(struct wlr_backend *backend);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the given input device is a wlr_x11_input_device.
|
* Check whether this input device is an X11 input device.
|
||||||
*/
|
*/
|
||||||
bool wlr_input_device_is_x11(struct wlr_input_device *device);
|
bool wlr_input_device_is_x11(struct wlr_input_device *device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the given output is a wlr_x11_output.
|
* Check whether this output device is an X11 output device.
|
||||||
*/
|
*/
|
||||||
bool wlr_output_is_x11(struct wlr_output *output);
|
bool wlr_output_is_x11(struct wlr_output *output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the title of a wlr_output which is an X11 window.
|
* Sets the title of a struct wlr_output which is an X11 window.
|
||||||
*/
|
*/
|
||||||
void wlr_x11_output_set_title(struct wlr_output *output, const char *title);
|
void wlr_x11_output_set_title(struct wlr_output *output, const char *title);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,10 @@
|
||||||
#mesondefine WLR_HAS_X11_BACKEND
|
#mesondefine WLR_HAS_X11_BACKEND
|
||||||
|
|
||||||
#mesondefine WLR_HAS_GLES2_RENDERER
|
#mesondefine WLR_HAS_GLES2_RENDERER
|
||||||
|
|
||||||
#mesondefine WLR_HAS_VULKAN_RENDERER
|
#mesondefine WLR_HAS_VULKAN_RENDERER
|
||||||
|
|
||||||
|
#mesondefine WLR_HAS_GBM_ALLOCATOR
|
||||||
|
|
||||||
#mesondefine WLR_HAS_XWAYLAND
|
#mesondefine WLR_HAS_XWAYLAND
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
48
include/wlr/interfaces/wlr_buffer.h
Normal file
48
include/wlr/interfaces/wlr_buffer.h
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* 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_BUFFER_H
|
||||||
|
#define WLR_INTERFACES_WLR_BUFFER_H
|
||||||
|
|
||||||
|
#include <wlr/types/wlr_buffer.h>
|
||||||
|
|
||||||
|
struct wlr_buffer_impl {
|
||||||
|
void (*destroy)(struct wlr_buffer *buffer);
|
||||||
|
bool (*get_dmabuf)(struct wlr_buffer *buffer,
|
||||||
|
struct wlr_dmabuf_attributes *attribs);
|
||||||
|
bool (*get_shm)(struct wlr_buffer *buffer,
|
||||||
|
struct wlr_shm_attributes *attribs);
|
||||||
|
bool (*begin_data_ptr_access)(struct wlr_buffer *buffer, uint32_t flags,
|
||||||
|
void **data, uint32_t *format, size_t *stride);
|
||||||
|
void (*end_data_ptr_access)(struct wlr_buffer *buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_buffer_resource_interface {
|
||||||
|
const char *name;
|
||||||
|
bool (*is_instance)(struct wl_resource *resource);
|
||||||
|
struct wlr_buffer *(*from_resource)(struct wl_resource *resource);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a buffer. This function should be called by producers. The
|
||||||
|
* initialized buffer is referenced: once the producer is done with the buffer
|
||||||
|
* they should call wlr_buffer_drop().
|
||||||
|
*/
|
||||||
|
void wlr_buffer_init(struct wlr_buffer *buffer,
|
||||||
|
const struct wlr_buffer_impl *impl, int width, int height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the registration of a struct wl_resource implementation.
|
||||||
|
*
|
||||||
|
* The matching function will be called for the struct wl_resource when creating
|
||||||
|
* a struct wlr_buffer from a struct wl_resource.
|
||||||
|
*/
|
||||||
|
void wlr_buffer_register_resource_interface(
|
||||||
|
const struct wlr_buffer_resource_interface *iface);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -13,15 +13,20 @@
|
||||||
#include <wlr/types/wlr_keyboard.h>
|
#include <wlr/types/wlr_keyboard.h>
|
||||||
|
|
||||||
struct wlr_keyboard_impl {
|
struct wlr_keyboard_impl {
|
||||||
void (*destroy)(struct wlr_keyboard *keyboard);
|
const char *name;
|
||||||
void (*led_update)(struct wlr_keyboard *keyboard, uint32_t leds);
|
void (*led_update)(struct wlr_keyboard *keyboard, uint32_t leds);
|
||||||
};
|
};
|
||||||
|
|
||||||
void wlr_keyboard_init(struct wlr_keyboard *keyboard,
|
void wlr_keyboard_init(struct wlr_keyboard *keyboard,
|
||||||
const struct wlr_keyboard_impl *impl, const char *name);
|
const struct wlr_keyboard_impl *impl, const char *name);
|
||||||
void wlr_keyboard_destroy(struct wlr_keyboard *keyboard);
|
|
||||||
|
/**
|
||||||
|
* Cleans up all of the resources owned by the struct wlr_keyboard.
|
||||||
|
*/
|
||||||
|
void wlr_keyboard_finish(struct wlr_keyboard *keyboard);
|
||||||
|
|
||||||
void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard,
|
void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard,
|
||||||
struct wlr_event_keyboard_key *event);
|
struct wlr_keyboard_key_event *event);
|
||||||
void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard,
|
void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard,
|
||||||
uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,
|
uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,
|
||||||
uint32_t group);
|
uint32_t group);
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,10 @@
|
||||||
WLR_OUTPUT_STATE_SCALE | \
|
WLR_OUTPUT_STATE_SCALE | \
|
||||||
WLR_OUTPUT_STATE_TRANSFORM | \
|
WLR_OUTPUT_STATE_TRANSFORM | \
|
||||||
WLR_OUTPUT_STATE_RENDER_FORMAT | \
|
WLR_OUTPUT_STATE_RENDER_FORMAT | \
|
||||||
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED)
|
WLR_OUTPUT_STATE_SUBPIXEL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A backend implementation of wlr_output.
|
* A backend implementation of struct wlr_output.
|
||||||
*
|
*
|
||||||
* The commit function is mandatory. Other functions are optional.
|
* The commit function is mandatory. Other functions are optional.
|
||||||
*/
|
*/
|
||||||
|
|
@ -38,7 +38,7 @@ struct wlr_output_impl {
|
||||||
* The hotspot indicates the offset that needs to be applied to the
|
* The hotspot indicates the offset that needs to be applied to the
|
||||||
* top-left corner of the image to match the cursor position. In other
|
* top-left corner of the image to match the cursor position. In other
|
||||||
* words, the image should be displayed at (x - hotspot_x, y - hotspot_y).
|
* words, the image should be displayed at (x - hotspot_x, y - hotspot_y).
|
||||||
* The hotspot is given in the texture's coordinate space.
|
* The hotspot is given in the buffer's coordinate space.
|
||||||
*/
|
*/
|
||||||
bool (*set_cursor)(struct wlr_output *output, struct wlr_buffer *buffer,
|
bool (*set_cursor)(struct wlr_output *output, struct wlr_buffer *buffer,
|
||||||
int hotspot_x, int hotspot_y);
|
int hotspot_x, int hotspot_y);
|
||||||
|
|
@ -53,18 +53,18 @@ struct wlr_output_impl {
|
||||||
*/
|
*/
|
||||||
void (*destroy)(struct wlr_output *output);
|
void (*destroy)(struct wlr_output *output);
|
||||||
/**
|
/**
|
||||||
* Check that the pending output state is a valid configuration.
|
* Check that the supplied output state is a valid configuration.
|
||||||
*
|
*
|
||||||
* If this function returns true, commit can only fail due to a runtime
|
* If this function returns true, commit can only fail due to a runtime
|
||||||
* error.
|
* error.
|
||||||
*/
|
*/
|
||||||
bool (*test)(struct wlr_output *output);
|
bool (*test)(struct wlr_output *output, const struct wlr_output_state *state);
|
||||||
/**
|
/**
|
||||||
* Commit the pending output state.
|
* Commit the supplied output state.
|
||||||
*
|
*
|
||||||
* If a buffer has been attached, a frame event is scheduled.
|
* If a buffer has been attached, a frame event is scheduled.
|
||||||
*/
|
*/
|
||||||
bool (*commit)(struct wlr_output *output);
|
bool (*commit)(struct wlr_output *output, const struct wlr_output_state *state);
|
||||||
/**
|
/**
|
||||||
* Get the maximum number of gamma LUT elements for each channel.
|
* Get the maximum number of gamma LUT elements for each channel.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@
|
||||||
#include <wlr/types/wlr_pointer.h>
|
#include <wlr/types/wlr_pointer.h>
|
||||||
|
|
||||||
struct wlr_pointer_impl {
|
struct wlr_pointer_impl {
|
||||||
void (*destroy)(struct wlr_pointer *pointer);
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
void wlr_pointer_init(struct wlr_pointer *pointer,
|
void wlr_pointer_init(struct wlr_pointer *pointer,
|
||||||
const struct wlr_pointer_impl *impl, const char *name);
|
const struct wlr_pointer_impl *impl, const char *name);
|
||||||
void wlr_pointer_destroy(struct wlr_pointer *pointer);
|
void wlr_pointer_finish(struct wlr_pointer *pointer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@
|
||||||
#include <wlr/types/wlr_switch.h>
|
#include <wlr/types/wlr_switch.h>
|
||||||
|
|
||||||
struct wlr_switch_impl {
|
struct wlr_switch_impl {
|
||||||
void (*destroy)(struct wlr_switch *switch_device);
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
void wlr_switch_init(struct wlr_switch *switch_device,
|
void wlr_switch_init(struct wlr_switch *switch_device,
|
||||||
const struct wlr_switch_impl *impl, const char *name);
|
const struct wlr_switch_impl *impl, const char *name);
|
||||||
void wlr_switch_destroy(struct wlr_switch *switch_device);
|
void wlr_switch_finish(struct wlr_switch *switch_device);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,19 @@
|
||||||
#include <wlr/types/wlr_tablet_pad.h>
|
#include <wlr/types/wlr_tablet_pad.h>
|
||||||
|
|
||||||
struct wlr_tablet_pad_impl {
|
struct wlr_tablet_pad_impl {
|
||||||
void (*destroy)(struct wlr_tablet_pad *pad);
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
void wlr_tablet_pad_init(struct wlr_tablet_pad *pad,
|
void wlr_tablet_pad_init(struct wlr_tablet_pad *pad,
|
||||||
const struct wlr_tablet_pad_impl *impl, const char *name);
|
const struct wlr_tablet_pad_impl *impl, const char *name);
|
||||||
void wlr_tablet_pad_destroy(struct wlr_tablet_pad *pad);
|
|
||||||
|
/**
|
||||||
|
* Cleans up the resources owned by a struct wlr_tablet_pad.
|
||||||
|
*
|
||||||
|
* This function will not clean the memory allocated by
|
||||||
|
* struct wlr_tablet_pad_group, it's the responsibility of the caller to clean
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
void wlr_tablet_pad_finish(struct wlr_tablet_pad *pad);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@
|
||||||
#include <wlr/types/wlr_tablet_tool.h>
|
#include <wlr/types/wlr_tablet_tool.h>
|
||||||
|
|
||||||
struct wlr_tablet_impl {
|
struct wlr_tablet_impl {
|
||||||
void (*destroy)(struct wlr_tablet *tablet);
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
void wlr_tablet_init(struct wlr_tablet *tablet,
|
void wlr_tablet_init(struct wlr_tablet *tablet,
|
||||||
const struct wlr_tablet_impl *impl, const char *name);
|
const struct wlr_tablet_impl *impl, const char *name);
|
||||||
void wlr_tablet_destroy(struct wlr_tablet *tablet);
|
void wlr_tablet_finish(struct wlr_tablet *tablet);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@
|
||||||
#include <wlr/types/wlr_touch.h>
|
#include <wlr/types/wlr_touch.h>
|
||||||
|
|
||||||
struct wlr_touch_impl {
|
struct wlr_touch_impl {
|
||||||
void (*destroy)(struct wlr_touch *touch);
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
void wlr_touch_init(struct wlr_touch *touch,
|
void wlr_touch_init(struct wlr_touch *touch,
|
||||||
const struct wlr_touch_impl *impl, const char *name);
|
const struct wlr_touch_impl *impl, const char *name);
|
||||||
void wlr_touch_destroy(struct wlr_touch *touch);
|
void wlr_touch_finish(struct wlr_touch *touch);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
version_array = meson.project_version().split('.')
|
version_base = meson.project_version().split('-')[0]
|
||||||
|
version_array = version_base.split('.')
|
||||||
version_data = configuration_data()
|
version_data = configuration_data()
|
||||||
version_data.set_quoted('WLR_VERSION_STR', meson.project_version())
|
version_data.set_quoted('WLR_VERSION_STR', meson.project_version())
|
||||||
version_data.set('WLR_VERSION_MAJOR', version_array[0])
|
version_data.set('WLR_VERSION_MAJOR', version_array[0])
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ struct wlr_allocator {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the adequate wlr_allocator given a backend and a renderer
|
* Creates the adequate struct wlr_allocator given a backend and a renderer.
|
||||||
*/
|
*/
|
||||||
struct wlr_allocator *wlr_allocator_autocreate(struct wlr_backend *backend,
|
struct wlr_allocator *wlr_allocator_autocreate(struct wlr_backend *backend,
|
||||||
struct wlr_renderer *renderer);
|
struct wlr_renderer *renderer);
|
||||||
|
|
@ -50,7 +50,7 @@ void wlr_allocator_destroy(struct wlr_allocator *alloc);
|
||||||
* Allocate a new buffer.
|
* Allocate a new buffer.
|
||||||
*
|
*
|
||||||
* When the caller is done with it, they must unreference it by calling
|
* When the caller is done with it, they must unreference it by calling
|
||||||
* wlr_buffer_drop.
|
* wlr_buffer_drop().
|
||||||
*
|
*
|
||||||
* The `format` passed in indicates the format to use and the list of
|
* The `format` passed in indicates the format to use and the list of
|
||||||
* acceptable modifiers. The order in which modifiers are listed is not
|
* acceptable modifiers. The order in which modifiers are listed is not
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ struct wlr_drm_format_set {
|
||||||
void wlr_drm_format_set_finish(struct wlr_drm_format_set *set);
|
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
|
* Return a pointer to a member of this struct wlr_drm_format_set of format
|
||||||
* `format`, or NULL if none exists.
|
* `format`, or NULL if none exists.
|
||||||
*/
|
*/
|
||||||
const struct wlr_drm_format *wlr_drm_format_set_get(
|
const struct wlr_drm_format *wlr_drm_format_set_get(
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@
|
||||||
#ifndef WLR_RENDER_EGL_H
|
#ifndef WLR_RENDER_EGL_H
|
||||||
#define WLR_RENDER_EGL_H
|
#define WLR_RENDER_EGL_H
|
||||||
|
|
||||||
#ifndef MESA_EGL_NO_X11_HEADERS
|
|
||||||
#define MESA_EGL_NO_X11_HEADERS
|
|
||||||
#endif
|
|
||||||
#ifndef EGL_NO_X11
|
#ifndef EGL_NO_X11
|
||||||
#define EGL_NO_X11
|
#define EGL_NO_X11
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -29,60 +26,31 @@
|
||||||
#include <wlr/render/dmabuf.h>
|
#include <wlr/render/dmabuf.h>
|
||||||
#include <wlr/render/drm_format_set.h>
|
#include <wlr/render/drm_format_set.h>
|
||||||
|
|
||||||
struct wlr_egl {
|
struct wlr_egl;
|
||||||
EGLDisplay display;
|
|
||||||
EGLContext context;
|
|
||||||
EGLDeviceEXT device; // may be EGL_NO_DEVICE_EXT
|
|
||||||
struct gbm_device *gbm_device;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
// Display extensions
|
|
||||||
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;
|
|
||||||
bool EXT_device_drm_render_node;
|
|
||||||
|
|
||||||
// Client extensions
|
|
||||||
bool EXT_device_query;
|
|
||||||
bool KHR_platform_gbm;
|
|
||||||
bool EXT_platform_device;
|
|
||||||
} exts;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
|
|
||||||
PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
|
|
||||||
PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
|
|
||||||
PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL;
|
|
||||||
PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT;
|
|
||||||
PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT;
|
|
||||||
PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR;
|
|
||||||
PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT;
|
|
||||||
PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT;
|
|
||||||
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
|
|
||||||
} procs;
|
|
||||||
|
|
||||||
bool has_modifiers;
|
|
||||||
struct wlr_drm_format_set dmabuf_texture_formats;
|
|
||||||
struct wlr_drm_format_set dmabuf_render_formats;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a struct wlr_egl with an existing EGL display and context.
|
||||||
|
*
|
||||||
|
* This is typically used by compositors which want to customize EGL
|
||||||
|
* initialization.
|
||||||
|
*/
|
||||||
struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
||||||
EGLContext context);
|
EGLContext context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the EGL context current.
|
* Get the EGL display used by the struct wlr_egl.
|
||||||
*
|
*
|
||||||
* Callers are expected to clear the current context when they are done by
|
* This is typically used by compositors which need to perform custom OpenGL
|
||||||
* calling wlr_egl_unset_current.
|
* operations.
|
||||||
*/
|
*/
|
||||||
bool wlr_egl_make_current(struct wlr_egl *egl);
|
EGLDisplay wlr_egl_get_display(struct wlr_egl *egl);
|
||||||
|
|
||||||
bool wlr_egl_unset_current(struct wlr_egl *egl);
|
/**
|
||||||
|
* Get the EGL context used by the struct wlr_egl.
|
||||||
bool wlr_egl_is_current(struct wlr_egl *egl);
|
*
|
||||||
|
* This is typically used by compositors which need to perform custom OpenGL
|
||||||
|
* operations.
|
||||||
|
*/
|
||||||
|
EGLContext wlr_egl_get_context(struct wlr_egl *egl);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,8 @@ void wlr_renderer_init(struct wlr_renderer *renderer,
|
||||||
const struct wlr_renderer_impl *impl);
|
const struct wlr_renderer_impl *impl);
|
||||||
|
|
||||||
struct wlr_texture_impl {
|
struct wlr_texture_impl {
|
||||||
bool (*is_opaque)(struct wlr_texture *texture);
|
bool (*update_from_buffer)(struct wlr_texture *texture,
|
||||||
bool (*write_pixels)(struct wlr_texture *texture,
|
struct wlr_buffer *buffer, pixman_region32_t *damage);
|
||||||
uint32_t stride, uint32_t width, uint32_t height,
|
|
||||||
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
|
|
||||||
const void *data);
|
|
||||||
void (*destroy)(struct wlr_texture *texture);
|
void (*destroy)(struct wlr_texture *texture);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,13 +77,13 @@ void wlr_render_quad_with_matrix(struct wlr_renderer *r,
|
||||||
const float color[static 4], const float matrix[static 9]);
|
const float color[static 4], const float matrix[static 9]);
|
||||||
/**
|
/**
|
||||||
* Get the shared-memory formats supporting import usage. Buffers allocated
|
* Get the shared-memory formats supporting import usage. Buffers allocated
|
||||||
* with a format from this list may be imported via wlr_texture_from_pixels.
|
* with a format from this list may be imported via wlr_texture_from_pixels().
|
||||||
*/
|
*/
|
||||||
const uint32_t *wlr_renderer_get_shm_texture_formats(
|
const uint32_t *wlr_renderer_get_shm_texture_formats(
|
||||||
struct wlr_renderer *r, size_t *len);
|
struct wlr_renderer *r, size_t *len);
|
||||||
/**
|
/**
|
||||||
* Get the DMA-BUF formats supporting sampling usage. Buffers allocated with
|
* Get the DMA-BUF formats supporting sampling usage. Buffers allocated with
|
||||||
* a format from this list may be imported via wlr_texture_from_dmabuf.
|
* a format from this list may be imported via wlr_texture_from_dmabuf().
|
||||||
*/
|
*/
|
||||||
const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_texture_formats(
|
const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_texture_formats(
|
||||||
struct wlr_renderer *renderer);
|
struct wlr_renderer *renderer);
|
||||||
|
|
@ -92,7 +92,7 @@ const struct wlr_drm_format_set *wlr_renderer_get_dmabuf_texture_formats(
|
||||||
* bytes.
|
* bytes.
|
||||||
*
|
*
|
||||||
* If `flags` is not NULl, the caller indicates that it accepts frame flags
|
* If `flags` is not NULl, the caller indicates that it accepts frame flags
|
||||||
* defined in `enum wlr_renderer_read_pixels_flags`.
|
* defined in enum wlr_renderer_read_pixels_flags.
|
||||||
*/
|
*/
|
||||||
bool wlr_renderer_read_pixels(struct wlr_renderer *r, uint32_t fmt,
|
bool wlr_renderer_read_pixels(struct wlr_renderer *r, uint32_t fmt,
|
||||||
uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
|
uint32_t *flags, uint32_t stride, uint32_t width, uint32_t height,
|
||||||
|
|
@ -107,7 +107,7 @@ bool wlr_renderer_init_wl_display(struct wlr_renderer *r,
|
||||||
struct wl_display *wl_display);
|
struct wl_display *wl_display);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes wl_shm on the provided wl_display.
|
* Initializes wl_shm on the provided struct wl_display.
|
||||||
*/
|
*/
|
||||||
bool wlr_renderer_init_wl_shm(struct wlr_renderer *r,
|
bool wlr_renderer_init_wl_shm(struct wlr_renderer *r,
|
||||||
struct wl_display *wl_display);
|
struct wl_display *wl_display);
|
||||||
|
|
@ -120,7 +120,9 @@ bool wlr_renderer_init_wl_shm(struct wlr_renderer *r,
|
||||||
int wlr_renderer_get_drm_fd(struct wlr_renderer *r);
|
int wlr_renderer_get_drm_fd(struct wlr_renderer *r);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys this wlr_renderer. Textures must be destroyed separately.
|
* Destroys the renderer.
|
||||||
|
*
|
||||||
|
* Textures must be destroyed separately.
|
||||||
*/
|
*/
|
||||||
void wlr_renderer_destroy(struct wlr_renderer *renderer);
|
void wlr_renderer_destroy(struct wlr_renderer *renderer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#ifndef WLR_RENDER_WLR_TEXTURE_H
|
#ifndef WLR_RENDER_WLR_TEXTURE_H
|
||||||
#define WLR_RENDER_WLR_TEXTURE_H
|
#define WLR_RENDER_WLR_TEXTURE_H
|
||||||
|
|
||||||
|
#include <pixman.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/render/dmabuf.h>
|
#include <wlr/render/dmabuf.h>
|
||||||
|
|
@ -25,9 +26,6 @@ struct wlr_texture {
|
||||||
/**
|
/**
|
||||||
* Create a new texture from raw pixel data. `stride` is in bytes. The returned
|
* Create a new texture from raw pixel data. `stride` is in bytes. The returned
|
||||||
* texture is mutable.
|
* texture is mutable.
|
||||||
*
|
|
||||||
* 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_pixels(struct wlr_renderer *renderer,
|
struct wlr_texture *wlr_texture_from_pixels(struct wlr_renderer *renderer,
|
||||||
uint32_t fmt, uint32_t stride, uint32_t width, uint32_t height,
|
uint32_t fmt, uint32_t stride, uint32_t width, uint32_t height,
|
||||||
|
|
@ -35,40 +33,30 @@ struct wlr_texture *wlr_texture_from_pixels(struct wlr_renderer *renderer,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new texture from a DMA-BUF. The returned texture is immutable.
|
* Create a new texture from a DMA-BUF. 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_dmabuf(struct wlr_renderer *renderer,
|
struct wlr_texture *wlr_texture_from_dmabuf(struct wlr_renderer *renderer,
|
||||||
struct wlr_dmabuf_attributes *attribs);
|
struct wlr_dmabuf_attributes *attribs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this texture is using a fully opaque format.
|
* Update a texture with a struct wlr_buffer's contents.
|
||||||
*/
|
|
||||||
bool wlr_texture_is_opaque(struct wlr_texture *texture);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a texture with raw pixels. The texture must be mutable, and the input
|
|
||||||
* data must have the same pixel format that the texture was created with.
|
|
||||||
*
|
*
|
||||||
* Should not be called in a rendering block like renderer_begin()/end() or
|
* The update might be rejected (in case the texture is immutable, the buffer
|
||||||
* between attaching a renderer to an output and committing it.
|
* has an unsupported type/format, etc), so callers must be prepared to fall
|
||||||
|
* back to re-creating the texture from scratch via wlr_texture_from_buffer().
|
||||||
|
*
|
||||||
|
* The damage can be used by the renderer as an optimization: only the supplied
|
||||||
|
* region needs to be updated.
|
||||||
*/
|
*/
|
||||||
bool wlr_texture_write_pixels(struct wlr_texture *texture,
|
bool wlr_texture_update_from_buffer(struct wlr_texture *texture,
|
||||||
uint32_t stride, uint32_t width, uint32_t height,
|
struct wlr_buffer *buffer, pixman_region32_t *damage);
|
||||||
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
|
|
||||||
const void *data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys this wlr_texture.
|
* Destroys the texture.
|
||||||
*/
|
*/
|
||||||
void wlr_texture_destroy(struct wlr_texture *texture);
|
void wlr_texture_destroy(struct wlr_texture *texture);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new texture from a buffer.
|
* Create a new texture from a buffer.
|
||||||
*
|
|
||||||
* 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_buffer(struct wlr_renderer *renderer,
|
struct wlr_texture *wlr_texture_from_buffer(struct wlr_renderer *renderer,
|
||||||
struct wlr_buffer *buffer);
|
struct wlr_buffer *buffer);
|
||||||
|
|
|
||||||
|
|
@ -24,22 +24,11 @@ struct wlr_shm_attributes {
|
||||||
off_t offset;
|
off_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_buffer_impl {
|
|
||||||
void (*destroy)(struct wlr_buffer *buffer);
|
|
||||||
bool (*get_dmabuf)(struct wlr_buffer *buffer,
|
|
||||||
struct wlr_dmabuf_attributes *attribs);
|
|
||||||
bool (*get_shm)(struct wlr_buffer *buffer,
|
|
||||||
struct wlr_shm_attributes *attribs);
|
|
||||||
bool (*begin_data_ptr_access)(struct wlr_buffer *buffer, uint32_t flags,
|
|
||||||
void **data, uint32_t *format, size_t *stride);
|
|
||||||
void (*end_data_ptr_access)(struct wlr_buffer *buffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Buffer capabilities.
|
* Buffer capabilities.
|
||||||
*
|
*
|
||||||
* These bits indicate the features supported by a wlr_buffer. There is one bit
|
* These bits indicate the features supported by a struct wlr_buffer. There is
|
||||||
* per function in wlr_buffer_impl.
|
* one bit per function in struct wlr_buffer_impl.
|
||||||
*/
|
*/
|
||||||
enum wlr_buffer_cap {
|
enum wlr_buffer_cap {
|
||||||
WLR_BUFFER_CAP_DATA_PTR = 1 << 0,
|
WLR_BUFFER_CAP_DATA_PTR = 1 << 0,
|
||||||
|
|
@ -72,19 +61,6 @@ struct wlr_buffer {
|
||||||
struct wlr_addon_set addons;
|
struct wlr_addon_set addons;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_buffer_resource_interface {
|
|
||||||
const char *name;
|
|
||||||
bool (*is_instance)(struct wl_resource *resource);
|
|
||||||
struct wlr_buffer *(*from_resource)(struct wl_resource *resource);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a buffer. This function should be called by producers. The
|
|
||||||
* initialized buffer is referenced: once the producer is done with the buffer
|
|
||||||
* they should call wlr_buffer_drop.
|
|
||||||
*/
|
|
||||||
void wlr_buffer_init(struct wlr_buffer *buffer,
|
|
||||||
const struct wlr_buffer_impl *impl, int width, int height);
|
|
||||||
/**
|
/**
|
||||||
* Unreference the buffer. This function should be called by producers when
|
* Unreference the buffer. This function should be called by producers when
|
||||||
* they are done with the buffer.
|
* they are done with the buffer.
|
||||||
|
|
@ -93,7 +69,7 @@ void wlr_buffer_drop(struct wlr_buffer *buffer);
|
||||||
/**
|
/**
|
||||||
* Lock the buffer. This function should be called by consumers to make
|
* Lock the buffer. This function should be called by consumers to make
|
||||||
* sure the buffer can be safely read from. Once the consumer is done with the
|
* sure the buffer can be safely read from. Once the consumer is done with the
|
||||||
* buffer, they should call wlr_buffer_unlock.
|
* buffer, they should call wlr_buffer_unlock().
|
||||||
*/
|
*/
|
||||||
struct wlr_buffer *wlr_buffer_lock(struct wlr_buffer *buffer);
|
struct wlr_buffer *wlr_buffer_lock(struct wlr_buffer *buffer);
|
||||||
/**
|
/**
|
||||||
|
|
@ -106,7 +82,7 @@ void wlr_buffer_unlock(struct wlr_buffer *buffer);
|
||||||
* returns false.
|
* returns false.
|
||||||
*
|
*
|
||||||
* The returned DMA-BUF attributes are valid for the lifetime of the
|
* The returned DMA-BUF attributes are valid for the lifetime of the
|
||||||
* wlr_buffer. The caller isn't responsible for cleaning up the DMA-BUF
|
* struct wlr_buffer. The caller isn't responsible for cleaning up the DMA-BUF
|
||||||
* attributes.
|
* attributes.
|
||||||
*/
|
*/
|
||||||
bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer,
|
bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer,
|
||||||
|
|
@ -116,24 +92,16 @@ bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer,
|
||||||
* memory, returns false.
|
* memory, returns false.
|
||||||
*
|
*
|
||||||
* The returned shared memory attributes are valid for the lifetime of the
|
* The returned shared memory attributes are valid for the lifetime of the
|
||||||
* wlr_buffer. The caller isn't responsible for cleaning up the shared memory
|
* struct wlr_buffer. The caller isn't responsible for cleaning up the shared
|
||||||
* attributes.
|
* memory attributes.
|
||||||
*/
|
*/
|
||||||
bool wlr_buffer_get_shm(struct wlr_buffer *buffer,
|
bool wlr_buffer_get_shm(struct wlr_buffer *buffer,
|
||||||
struct wlr_shm_attributes *attribs);
|
struct wlr_shm_attributes *attribs);
|
||||||
/**
|
/**
|
||||||
* Allows the registration of a wl_resource implementation.
|
* Transforms a struct wl_resource into a struct wlr_buffer and locks it. Once
|
||||||
|
* the caller is done with the buffer, they must call wlr_buffer_unlock().
|
||||||
*
|
*
|
||||||
* The matching function will be called for the wl_resource when creating a
|
* The provided struct wl_resource must be a wl_buffer.
|
||||||
* wlr_buffer from a wl_resource.
|
|
||||||
*/
|
|
||||||
void wlr_buffer_register_resource_interface(
|
|
||||||
const struct wlr_buffer_resource_interface *iface);
|
|
||||||
/**
|
|
||||||
* Transforms a wl_resource into a wlr_buffer and locks it. Once the caller is
|
|
||||||
* done with the buffer, they must call wlr_buffer_unlock.
|
|
||||||
*
|
|
||||||
* The provided wl_resource must be a wl_buffer.
|
|
||||||
*/
|
*/
|
||||||
struct wlr_buffer *wlr_buffer_from_resource(struct wl_resource *resource);
|
struct wlr_buffer *wlr_buffer_from_resource(struct wl_resource *resource);
|
||||||
|
|
||||||
|
|
@ -158,7 +126,7 @@ enum wlr_buffer_data_ptr_access_flag {
|
||||||
*
|
*
|
||||||
* The returned pointer should be pointing to a valid memory region for the
|
* The returned pointer should be pointing to a valid memory region for the
|
||||||
* operations specified in the flags. The returned pointer is only valid up to
|
* operations specified in the flags. The returned pointer is only valid up to
|
||||||
* the next buffer_end_data_ptr_access call.
|
* the next wlr_buffer_end_data_ptr_access() call.
|
||||||
*/
|
*/
|
||||||
bool wlr_buffer_begin_data_ptr_access(struct wlr_buffer *buffer, uint32_t flags,
|
bool wlr_buffer_begin_data_ptr_access(struct wlr_buffer *buffer, uint32_t flags,
|
||||||
void **data, uint32_t *format, size_t *stride);
|
void **data, uint32_t *format, size_t *stride);
|
||||||
|
|
@ -183,14 +151,11 @@ struct wlr_client_buffer {
|
||||||
// private state
|
// private state
|
||||||
|
|
||||||
struct wl_listener source_destroy;
|
struct wl_listener source_destroy;
|
||||||
|
|
||||||
// If the client buffer has been created from a wl_shm buffer
|
|
||||||
uint32_t shm_source_format;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a wlr_client_buffer from a given wlr_buffer by creating a texture
|
* Creates a struct wlr_client_buffer from a given struct wlr_buffer by creating
|
||||||
* from it, and copying its wl_resource.
|
* a texture from it, and copying its struct wl_resource.
|
||||||
*/
|
*/
|
||||||
struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer,
|
struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer,
|
||||||
struct wlr_renderer *renderer);
|
struct wlr_renderer *renderer);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ enum wlr_surface_state_field {
|
||||||
WLR_SURFACE_STATE_SCALE = 1 << 6,
|
WLR_SURFACE_STATE_SCALE = 1 << 6,
|
||||||
WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7,
|
WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7,
|
||||||
WLR_SURFACE_STATE_VIEWPORT = 1 << 8,
|
WLR_SURFACE_STATE_VIEWPORT = 1 << 8,
|
||||||
|
WLR_SURFACE_STATE_OFFSET = 1 << 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_surface_state {
|
struct wlr_surface_state {
|
||||||
|
|
@ -147,7 +148,7 @@ struct wlr_surface {
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
} events;
|
} events;
|
||||||
|
|
||||||
struct wl_list current_outputs; // wlr_surface_output::link
|
struct wl_list current_outputs; // wlr_surface_output.link
|
||||||
|
|
||||||
struct wlr_addon_set addons;
|
struct wlr_addon_set addons;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
@ -162,6 +163,8 @@ struct wlr_surface {
|
||||||
int width, height;
|
int width, height;
|
||||||
int buffer_width, buffer_height;
|
int buffer_width, buffer_height;
|
||||||
} previous;
|
} previous;
|
||||||
|
|
||||||
|
bool opaque;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_renderer;
|
struct wlr_renderer;
|
||||||
|
|
@ -243,9 +246,10 @@ void wlr_surface_send_frame_done(struct wlr_surface *surface,
|
||||||
void wlr_surface_get_extends(struct wlr_surface *surface, struct wlr_box *box);
|
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
|
* Get the struct wlr_surface corresponding to a wl_surface resource.
|
||||||
* that the resource is a valid wl_surface resource created by wlroots and
|
*
|
||||||
* will never return NULL.
|
* 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);
|
struct wlr_surface *wlr_surface_from_resource(struct wl_resource *resource);
|
||||||
|
|
||||||
|
|
@ -281,7 +285,7 @@ void wlr_surface_get_buffer_source_box(struct wlr_surface *surface,
|
||||||
* Acquire a lock for the pending surface state.
|
* Acquire a lock for the pending surface state.
|
||||||
*
|
*
|
||||||
* The state won't be committed before the caller releases the lock. Instead,
|
* 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
|
* the state becomes cached. The caller needs to use wlr_surface_unlock_cached()
|
||||||
* to release the lock.
|
* to release the lock.
|
||||||
*
|
*
|
||||||
* Returns a surface commit sequence number for the cached state.
|
* Returns a surface commit sequence number for the cached state.
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,20 @@
|
||||||
#define WLR_TYPES_WLR_CURSOR_H
|
#define WLR_TYPES_WLR_CURSOR_H
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
|
||||||
|
struct wlr_input_device;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlr_cursor implements the behavior of the "cursor", that is, the image on the
|
* wlr_cursor implements the behavior of the "cursor", that is, the image on the
|
||||||
* screen typically moved about with a mouse or so. It provides tracking for
|
* screen typically moved about with a mouse or so. It provides tracking for
|
||||||
* this in global coordinates, and integrates with wlr_output,
|
* this in global coordinates, and integrates with struct wlr_output,
|
||||||
* wlr_output_layout, and wlr_input_device. You can use it to abstract multiple
|
* struct wlr_output_layout, and struct wlr_input_device. You can use it to
|
||||||
* input devices over a single cursor, constrain cursor movement to the usable
|
* abstract multiple input devices over a single cursor, constrain cursor
|
||||||
* area of a wlr_output_layout and communicate position updates to the hardware
|
* movement to the usable area of a struct wlr_output_layout and communicate
|
||||||
* cursor, constrain specific input devices to specific outputs or regions of
|
* position updates to the hardware cursor, constrain specific input devices to
|
||||||
* the screen, and so on.
|
* specific outputs or regions of the screen, and so on.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct wlr_box;
|
struct wlr_box;
|
||||||
|
|
@ -36,15 +37,15 @@ struct wlr_cursor {
|
||||||
* The interpretation of these signals is the responsibility of the
|
* The interpretation of these signals is the responsibility of the
|
||||||
* compositor, but some helpers are provided for your benefit. If you
|
* compositor, but some helpers are provided for your benefit. If you
|
||||||
* receive a relative motion event, for example, you may want to call
|
* receive a relative motion event, for example, you may want to call
|
||||||
* wlr_cursor_move. If you receive an absolute event, call
|
* wlr_cursor_move(). If you receive an absolute event, call
|
||||||
* wlr_cursor_warp_absolute. If you pass an input device into these
|
* wlr_cursor_warp_absolute(). If you pass an input device into these
|
||||||
* functions, it will apply the region/output constraints associated with
|
* functions, it will apply the region/output constraints associated with
|
||||||
* that device to the resulting cursor motion. If an output layout is
|
* that device to the resulting cursor motion. If an output layout is
|
||||||
* attached, these functions will constrain the resulting cursor motion to
|
* attached, these functions will constrain the resulting cursor motion to
|
||||||
* within the usable space of the output layout.
|
* within the usable space of the output layout.
|
||||||
*
|
*
|
||||||
* Re-broadcasting these signals to, for example, a wlr_seat, is also your
|
* Re-broadcasting these signals to, for example, a struct wlr_seat, is also
|
||||||
* responsibility.
|
* your responsibility.
|
||||||
*/
|
*/
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal motion;
|
struct wl_signal motion;
|
||||||
|
|
@ -190,13 +191,14 @@ void wlr_cursor_map_input_to_output(struct wlr_cursor *cur,
|
||||||
struct wlr_input_device *dev, struct wlr_output *output);
|
struct wlr_input_device *dev, struct wlr_output *output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps this cursor to an arbitrary region on the associated wlr_output_layout.
|
* Maps this cursor to an arbitrary region on the associated
|
||||||
|
* struct wlr_output_layout.
|
||||||
*/
|
*/
|
||||||
void wlr_cursor_map_to_region(struct wlr_cursor *cur, const 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
|
* Maps inputs from this input device to an arbitrary region on the associated
|
||||||
* wlr_output_layout.
|
* struct wlr_output_layout.
|
||||||
*/
|
*/
|
||||||
void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
|
void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
|
||||||
struct wlr_input_device *dev, const struct wlr_box *box);
|
struct wlr_input_device *dev, const struct wlr_box *box);
|
||||||
|
|
|
||||||
81
include/wlr/types/wlr_damage_ring.h
Normal file
81
include/wlr/types/wlr_damage_ring.h
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* 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_TYPES_WLR_DAMAGE_RING_H
|
||||||
|
#define WLR_TYPES_WLR_DAMAGE_RING_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/* For triple buffering, a history of two frames is required. */
|
||||||
|
#define WLR_DAMAGE_RING_PREVIOUS_LEN 2
|
||||||
|
|
||||||
|
struct wlr_box;
|
||||||
|
|
||||||
|
struct wlr_damage_ring {
|
||||||
|
int32_t width, height;
|
||||||
|
|
||||||
|
// Difference between the current buffer and the previous one
|
||||||
|
pixman_region32_t current;
|
||||||
|
|
||||||
|
// private state
|
||||||
|
|
||||||
|
pixman_region32_t previous[WLR_DAMAGE_RING_PREVIOUS_LEN];
|
||||||
|
size_t previous_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
void wlr_damage_ring_init(struct wlr_damage_ring *ring);
|
||||||
|
|
||||||
|
void wlr_damage_ring_finish(struct wlr_damage_ring *ring);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set ring bounds and damage the ring fully.
|
||||||
|
*
|
||||||
|
* Next time damage will be added, it will be cropped to the ring bounds.
|
||||||
|
* If at least one of the dimensions is 0, bounds are removed.
|
||||||
|
*
|
||||||
|
* By default, a damage ring doesn't have bounds.
|
||||||
|
*/
|
||||||
|
void wlr_damage_ring_set_bounds(struct wlr_damage_ring *ring,
|
||||||
|
int32_t width, int32_t height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a region to the current damage.
|
||||||
|
*
|
||||||
|
* Returns true if the region intersects the ring bounds, false otherwise.
|
||||||
|
*/
|
||||||
|
bool wlr_damage_ring_add(struct wlr_damage_ring *ring,
|
||||||
|
pixman_region32_t *damage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a box to the current damage.
|
||||||
|
*
|
||||||
|
* Returns true if the box intersects the ring bounds, false otherwise.
|
||||||
|
*/
|
||||||
|
bool wlr_damage_ring_add_box(struct wlr_damage_ring *ring,
|
||||||
|
const struct wlr_box *box);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Damage the ring fully.
|
||||||
|
*/
|
||||||
|
void wlr_damage_ring_add_whole(struct wlr_damage_ring *ring);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotate the damage ring. This needs to be called after using the accumulated
|
||||||
|
* damage, e.g. after rendering to an output's back buffer.
|
||||||
|
*/
|
||||||
|
void wlr_damage_ring_rotate(struct wlr_damage_ring *ring);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get accumulated damage, which is the difference between the current buffer
|
||||||
|
* and the buffer with age of buffer_age; in context of rendering, this is
|
||||||
|
* the region that needs to be redrawn.
|
||||||
|
*/
|
||||||
|
void wlr_damage_ring_get_buffer_damage(struct wlr_damage_ring *ring,
|
||||||
|
int buffer_age, pixman_region32_t *damage);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
struct wlr_data_control_manager_v1 {
|
struct wlr_data_control_manager_v1 {
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
struct wl_list devices; // wlr_data_control_device_v1::link
|
struct wl_list devices; // wlr_data_control_device_v1.link
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
|
|
@ -27,7 +27,7 @@ struct wlr_data_control_manager_v1 {
|
||||||
struct wlr_data_control_device_v1 {
|
struct wlr_data_control_device_v1 {
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wlr_data_control_manager_v1 *manager;
|
struct wlr_data_control_manager_v1 *manager;
|
||||||
struct wl_list link; // wlr_data_control_manager_v1::devices
|
struct wl_list link; // wlr_data_control_manager_v1.devices
|
||||||
|
|
||||||
struct wlr_seat *seat;
|
struct wlr_seat *seat;
|
||||||
struct wl_resource *selection_offer_resource; // current selection offer
|
struct wl_resource *selection_offer_resource; // current selection offer
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ struct wlr_data_offer {
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wlr_data_source *source;
|
struct wlr_data_source *source;
|
||||||
enum wlr_data_offer_type type;
|
enum wlr_data_offer_type type;
|
||||||
struct wl_list link; // wlr_seat::{selection_offers,drag_offers}
|
struct wl_list link; // wlr_seat.{selection_offers,drag_offers}
|
||||||
|
|
||||||
uint32_t actions;
|
uint32_t actions;
|
||||||
enum wl_data_device_manager_dnd_action preferred_action;
|
enum wl_data_device_manager_dnd_action preferred_action;
|
||||||
|
|
@ -54,7 +54,7 @@ struct wlr_data_offer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A data source implementation. Only the `send` function is mandatory. Refer to
|
* A data source implementation. Only the `send` function is mandatory. Refer to
|
||||||
* the matching wl_data_source_* functions documentation to know what they do.
|
* the matching `wlr_data_source_*` functions documentation to know what they do.
|
||||||
*/
|
*/
|
||||||
struct wlr_data_source_impl {
|
struct wlr_data_source_impl {
|
||||||
void (*send)(struct wlr_data_source *source, const char *mime_type,
|
void (*send)(struct wlr_data_source *source, const char *mime_type,
|
||||||
|
|
@ -131,8 +131,8 @@ struct wlr_drag {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal focus;
|
struct wl_signal focus;
|
||||||
struct wl_signal motion; // wlr_drag_motion_event
|
struct wl_signal motion; // struct wlr_drag_motion_event
|
||||||
struct wl_signal drop; // wlr_drag_drop_event
|
struct wl_signal drop; // struct wlr_drag_drop_event
|
||||||
struct wl_signal destroy;
|
struct wl_signal destroy;
|
||||||
} events;
|
} events;
|
||||||
|
|
||||||
|
|
@ -155,7 +155,7 @@ struct wlr_drag_drop_event {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a wl data device manager global for this display.
|
* Create a wl_data_device_manager global for this display.
|
||||||
*/
|
*/
|
||||||
struct wlr_data_device_manager *wlr_data_device_manager_create(
|
struct wlr_data_device_manager *wlr_data_device_manager_create(
|
||||||
struct wl_display *display);
|
struct wl_display *display);
|
||||||
|
|
@ -181,7 +181,7 @@ void wlr_seat_set_selection(struct wlr_seat *seat,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new drag. To request to start the drag, call
|
* Creates a new drag. To request to start the drag, call
|
||||||
* `wlr_seat_request_start_drag`.
|
* wlr_seat_request_start_drag().
|
||||||
*/
|
*/
|
||||||
struct wlr_drag *wlr_drag_create(struct wlr_seat_client *seat_client,
|
struct wlr_drag *wlr_drag_create(struct wlr_seat_client *seat_client,
|
||||||
struct wlr_data_source *source, struct wlr_surface *icon_surface);
|
struct wlr_data_source *source, struct wlr_surface *icon_surface);
|
||||||
|
|
@ -258,7 +258,7 @@ void wlr_data_source_dnd_finish(struct wlr_data_source *source);
|
||||||
* Notifies the data source that a target accepts the drag with the specified
|
* Notifies the data source that a target accepts the drag with the specified
|
||||||
* action.
|
* action.
|
||||||
*
|
*
|
||||||
* This shouldn't be called after `wlr_data_source_dnd_drop` unless the
|
* This shouldn't be called after wlr_data_source_dnd_drop() unless the
|
||||||
* drag-and-drop operation ended in an "ask" action.
|
* drag-and-drop operation ended in an "ask" action.
|
||||||
*/
|
*/
|
||||||
void wlr_data_source_dnd_action(struct wlr_data_source *source,
|
void wlr_data_source_dnd_action(struct wlr_data_source *source,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ struct wlr_backend;
|
||||||
struct wlr_output;
|
struct wlr_output;
|
||||||
|
|
||||||
struct wlr_drm_lease_v1_manager {
|
struct wlr_drm_lease_v1_manager {
|
||||||
struct wl_list devices; // wlr_drm_lease_device_v1::link;
|
struct wl_list devices; // wlr_drm_lease_device_v1.link
|
||||||
|
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
struct wl_listener display_destroy;
|
struct wl_listener display_destroy;
|
||||||
|
|
@ -23,9 +23,9 @@ struct wlr_drm_lease_v1_manager {
|
||||||
struct {
|
struct {
|
||||||
/**
|
/**
|
||||||
* Upon receiving this signal, call
|
* Upon receiving this signal, call
|
||||||
* wlr_drm_lease_device_v1_grant_lease_request to grant a lease of the
|
* wlr_drm_lease_device_v1_grant_lease_request() to grant a lease of the
|
||||||
* requested DRM resources, or
|
* requested DRM resources, or
|
||||||
* wlr_drm_lease_device_v1_reject_lease_request to reject the request.
|
* wlr_drm_lease_device_v1_reject_lease_request() to reject the request.
|
||||||
*/
|
*/
|
||||||
struct wl_signal request;
|
struct wl_signal request;
|
||||||
} events;
|
} events;
|
||||||
|
|
@ -38,10 +38,10 @@ struct wlr_drm_lease_device_v1 {
|
||||||
struct wlr_drm_lease_v1_manager *manager;
|
struct wlr_drm_lease_v1_manager *manager;
|
||||||
struct wlr_backend *backend;
|
struct wlr_backend *backend;
|
||||||
|
|
||||||
struct wl_list connectors; // wlr_drm_lease_connector_v1::link
|
struct wl_list connectors; // wlr_drm_lease_connector_v1.link
|
||||||
struct wl_list leases; // wlr_drm_lease_v1::link
|
struct wl_list leases; // wlr_drm_lease_v1.link
|
||||||
struct wl_list requests; // wlr_drm_lease_request_v1::link
|
struct wl_list requests; // wlr_drm_lease_request_v1.link
|
||||||
struct wl_list link; // wlr_drm_lease_v1_manager::devices
|
struct wl_list link; // wlr_drm_lease_v1_manager.devices
|
||||||
|
|
||||||
struct wl_listener backend_destroy;
|
struct wl_listener backend_destroy;
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ struct wlr_drm_lease_device_v1 {
|
||||||
struct wlr_drm_lease_v1;
|
struct wlr_drm_lease_v1;
|
||||||
|
|
||||||
struct wlr_drm_lease_connector_v1 {
|
struct wlr_drm_lease_connector_v1 {
|
||||||
struct wl_list resources; // wl_resource_get_link
|
struct wl_list resources; // wl_resource_get_link()
|
||||||
|
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
struct wlr_drm_lease_device_v1 *device;
|
struct wlr_drm_lease_device_v1 *device;
|
||||||
|
|
@ -60,7 +60,7 @@ struct wlr_drm_lease_connector_v1 {
|
||||||
|
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
|
|
||||||
struct wl_list link; // wlr_drm_lease_device_v1::connectors
|
struct wl_list link; // wlr_drm_lease_device_v1.connectors
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_drm_lease_request_v1 {
|
struct wlr_drm_lease_request_v1 {
|
||||||
|
|
@ -76,7 +76,7 @@ struct wlr_drm_lease_request_v1 {
|
||||||
|
|
||||||
bool invalid;
|
bool invalid;
|
||||||
|
|
||||||
struct wl_list link; // wlr_drm_lease_device_v1::requests
|
struct wl_list link; // wlr_drm_lease_device_v1.requests
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_drm_lease_v1 {
|
struct wlr_drm_lease_v1 {
|
||||||
|
|
@ -97,7 +97,8 @@ struct wlr_drm_lease_v1 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a DRM lease manager. A DRM lease device will be created for each
|
* Creates a DRM lease manager. A DRM lease device will be created for each
|
||||||
* DRM backend supplied in case of a wlr_multi_backend.
|
* DRM backend supplied in case of a struct wlr_multi_backend.
|
||||||
|
*
|
||||||
* Returns NULL if no DRM backend is supplied.
|
* Returns NULL if no DRM backend is supplied.
|
||||||
*/
|
*/
|
||||||
struct wlr_drm_lease_v1_manager *wlr_drm_lease_v1_manager_create(
|
struct wlr_drm_lease_v1_manager *wlr_drm_lease_v1_manager_create(
|
||||||
|
|
@ -105,6 +106,7 @@ struct wlr_drm_lease_v1_manager *wlr_drm_lease_v1_manager_create(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Offers a wlr_output for lease.
|
* Offers a wlr_output for lease.
|
||||||
|
*
|
||||||
* Returns false if the output can't be offered to lease.
|
* Returns false if the output can't be offered to lease.
|
||||||
*/
|
*/
|
||||||
bool wlr_drm_lease_v1_manager_offer_output(
|
bool wlr_drm_lease_v1_manager_offer_output(
|
||||||
|
|
@ -120,7 +122,7 @@ void wlr_drm_lease_v1_manager_withdraw_output(
|
||||||
/**
|
/**
|
||||||
* Grants a client's lease request. The lease device will then provision the
|
* Grants a client's lease request. The lease device will then provision the
|
||||||
* DRM lease and transfer the file descriptor to the client. After calling this,
|
* DRM lease and transfer the file descriptor to the client. After calling this,
|
||||||
* each wlr_output leased is destroyed, and will be re-issued through
|
* each struct wlr_output leased is destroyed, and will be re-issued through
|
||||||
* wlr_backend.events.new_outputs when the lease is revoked.
|
* wlr_backend.events.new_outputs when the lease is revoked.
|
||||||
*
|
*
|
||||||
* This will return NULL without leasing any resources if the lease is invalid;
|
* This will return NULL without leasing any resources if the lease is invalid;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
struct wlr_export_dmabuf_manager_v1 {
|
struct wlr_export_dmabuf_manager_v1 {
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
struct wl_list frames; // wlr_export_dmabuf_frame_v1::link
|
struct wl_list frames; // wlr_export_dmabuf_frame_v1.link
|
||||||
|
|
||||||
struct wl_listener display_destroy;
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ struct wlr_export_dmabuf_manager_v1 {
|
||||||
struct wlr_export_dmabuf_frame_v1 {
|
struct wlr_export_dmabuf_frame_v1 {
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
struct wlr_export_dmabuf_manager_v1 *manager;
|
struct wlr_export_dmabuf_manager_v1 *manager;
|
||||||
struct wl_list link; // wlr_export_dmabuf_manager_v1::frames
|
struct wl_list link; // wlr_export_dmabuf_manager_v1.frames
|
||||||
|
|
||||||
struct wlr_output *output;
|
struct wlr_output *output;
|
||||||
|
|
||||||
|
|
|
||||||
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