mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-06-13 14:32:57 -04:00
Merge branch 'wscons' into 'master'
Draft: Add OpenBSD/wscons support See merge request wlroots/wlroots!5378
This commit is contained in:
commit
90cf273319
24 changed files with 1531 additions and 179 deletions
|
|
@ -32,6 +32,10 @@
|
||||||
#include <wlr/backend/x11.h>
|
#include <wlr/backend/x11.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WLR_HAS_WSCONS_BACKEND
|
||||||
|
#include <wlr/backend/wscons.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define WAIT_SESSION_TIMEOUT 10000 // ms
|
#define WAIT_SESSION_TIMEOUT 10000 // ms
|
||||||
|
|
||||||
void wlr_backend_init(struct wlr_backend *backend,
|
void wlr_backend_init(struct wlr_backend *backend,
|
||||||
|
|
@ -287,6 +291,15 @@ static struct wlr_backend *attempt_libinput_backend(struct wlr_session *session)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct wlr_backend *attempt_wscons_backend(struct wlr_session *session) {
|
||||||
|
#if WLR_HAS_WSCONS_BACKEND
|
||||||
|
return wlr_wscons_backend_create(session);
|
||||||
|
#else
|
||||||
|
wlr_log(WLR_ERROR, "Cannot create wscons backend: disabled at compile-time");
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static bool attempt_backend_by_name(struct wl_event_loop *loop,
|
static bool attempt_backend_by_name(struct wl_event_loop *loop,
|
||||||
struct wlr_backend *multi, char *name,
|
struct wlr_backend *multi, char *name,
|
||||||
struct wlr_session **session_ptr) {
|
struct wlr_session **session_ptr) {
|
||||||
|
|
@ -297,8 +310,9 @@ static bool attempt_backend_by_name(struct wl_event_loop *loop,
|
||||||
backend = attempt_x11_backend(loop, NULL);
|
backend = attempt_x11_backend(loop, NULL);
|
||||||
} else if (strcmp(name, "headless") == 0) {
|
} else if (strcmp(name, "headless") == 0) {
|
||||||
backend = attempt_headless_backend(loop);
|
backend = attempt_headless_backend(loop);
|
||||||
} else if (strcmp(name, "drm") == 0 || strcmp(name, "libinput") == 0) {
|
} else if (strcmp(name, "drm") == 0 || strcmp(name, "libinput") == 0
|
||||||
// DRM and libinput need a session
|
|| strcmp(name, "wscons") == 0) {
|
||||||
|
// DRM and libinput/wscons need a session
|
||||||
if (*session_ptr == NULL) {
|
if (*session_ptr == NULL) {
|
||||||
*session_ptr = session_create_and_wait(loop);
|
*session_ptr = session_create_and_wait(loop);
|
||||||
if (*session_ptr == NULL) {
|
if (*session_ptr == NULL) {
|
||||||
|
|
@ -309,6 +323,8 @@ static bool attempt_backend_by_name(struct wl_event_loop *loop,
|
||||||
|
|
||||||
if (strcmp(name, "libinput") == 0) {
|
if (strcmp(name, "libinput") == 0) {
|
||||||
backend = attempt_libinput_backend(*session_ptr);
|
backend = attempt_libinput_backend(*session_ptr);
|
||||||
|
} else if (strcmp(name, "wscons") == 0) {
|
||||||
|
backend = attempt_wscons_backend(*session_ptr);
|
||||||
} else {
|
} else {
|
||||||
// attempt_drm_backend() adds the multi drm backends itself
|
// attempt_drm_backend() adds the multi drm backends itself
|
||||||
return attempt_drm_backend(multi, *session_ptr) != NULL;
|
return attempt_drm_backend(multi, *session_ptr) != NULL;
|
||||||
|
|
@ -393,13 +409,24 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_event_loop *loop,
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt DRM+libinput
|
// Attempt DRM+libinput/wscons
|
||||||
session = session_create_and_wait(loop);
|
session = session_create_and_wait(loop);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
wlr_log(WLR_ERROR, "Failed to start a DRM session");
|
wlr_log(WLR_ERROR, "Failed to start a DRM session");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WLR_HAS_WSCONS_BACKEND
|
||||||
|
struct wlr_backend *wscons = attempt_wscons_backend(session);
|
||||||
|
if (!wscons) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to start wscons backend");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
wlr_multi_backend_add(multi, wscons);
|
||||||
|
if (!auto_backend_monitor_create(multi, wscons)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#else
|
||||||
struct wlr_backend *libinput = attempt_libinput_backend(session);
|
struct wlr_backend *libinput = attempt_libinput_backend(session);
|
||||||
if (libinput) {
|
if (libinput) {
|
||||||
wlr_multi_backend_add(multi, libinput);
|
wlr_multi_backend_add(multi, libinput);
|
||||||
|
|
@ -414,6 +441,7 @@ struct wlr_backend *wlr_backend_autocreate(struct wl_event_loop *loop,
|
||||||
wlr_log(WLR_ERROR, "Set WLR_LIBINPUT_NO_DEVICES=1 to skip libinput");
|
wlr_log(WLR_ERROR, "Set WLR_LIBINPUT_NO_DEVICES=1 to skip libinput");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct wlr_backend *primary_drm = attempt_drm_backend(multi, session);
|
struct wlr_backend *primary_drm = attempt_drm_backend(multi, session);
|
||||||
if (primary_drm == NULL) {
|
if (primary_drm == NULL) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/libinput.h"
|
#include "backend/libinput.h"
|
||||||
#include "util/env.h"
|
#include "util/env.h"
|
||||||
|
#include <libudev.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) {
|
||||||
|
|
@ -192,7 +193,7 @@ struct wlr_backend *wlr_libinput_backend_create(struct wlr_session *session) {
|
||||||
backend->session = session;
|
backend->session = session;
|
||||||
|
|
||||||
backend->libinput_context = libinput_udev_create_context(&libinput_impl,
|
backend->libinput_context = libinput_udev_create_context(&libinput_impl,
|
||||||
backend, backend->session->udev);
|
backend, udev_new());
|
||||||
if (!backend->libinput_context) {
|
if (!backend->libinput_context) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create libinput context");
|
wlr_log(WLR_ERROR, "Failed to create libinput context");
|
||||||
wlr_backend_finish(&backend->backend);
|
wlr_backend_finish(&backend->backend);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ if not (libinput.found() and features['session'])
|
||||||
subdir_done()
|
subdir_done()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# libinput has a hardcoded udev dependency in its API
|
||||||
|
wlr_deps += dependency('libudev')
|
||||||
|
|
||||||
wlr_files += files(
|
wlr_files += files(
|
||||||
'backend.c',
|
'backend.c',
|
||||||
'events.c',
|
'events.c',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
wlr_files += files('backend.c')
|
wlr_files += files('backend.c')
|
||||||
|
|
||||||
all_backends = ['drm', 'libinput', 'x11']
|
all_backends = ['drm', 'libinput', 'x11', 'wscons']
|
||||||
backends = get_option('backends')
|
backends = get_option('backends')
|
||||||
if 'auto' in backends and get_option('auto_features').enabled()
|
if 'auto' in backends and get_option('auto_features').enabled()
|
||||||
backends = all_backends
|
backends = all_backends
|
||||||
|
|
@ -8,10 +8,10 @@ elif 'auto' in backends and get_option('auto_features').disabled()
|
||||||
backends = []
|
backends = []
|
||||||
endif
|
endif
|
||||||
|
|
||||||
session_required = 'drm' in backends or 'libinput' in backends or get_option('session').enabled()
|
session_required = 'drm' in backends or 'libinput' in backends or 'wscons' in backends or get_option('session').enabled()
|
||||||
if get_option('session').disabled()
|
if get_option('session').disabled()
|
||||||
if session_required
|
if session_required
|
||||||
error('Session support is required for the DRM or libinput backends')
|
error('Session support is required for the DRM or libinput/wscons backends')
|
||||||
endif
|
endif
|
||||||
session_required = disabler()
|
session_required = disabler()
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,27 @@
|
||||||
msg = 'Required for session support.'
|
|
||||||
udev = dependency('libudev', required: session_required, not_found_message: msg)
|
|
||||||
libseat = dependency(
|
libseat = dependency(
|
||||||
'libseat',
|
'libseat',
|
||||||
version: '>=0.2.0',
|
version: '>=0.2.0',
|
||||||
fallback: 'seatd',
|
fallback: 'seatd',
|
||||||
default_options: ['server=disabled', 'man-pages=disabled', 'examples=disabled'],
|
default_options: ['server=disabled', 'man-pages=disabled', 'examples=disabled'],
|
||||||
required: session_required,
|
required: session_required,
|
||||||
not_found_message: msg,
|
|
||||||
)
|
)
|
||||||
if not (udev.found() and libseat.found())
|
|
||||||
subdir_done()
|
platform = target_machine.system()
|
||||||
|
if platform == 'linux' or platform == 'freebsd'
|
||||||
|
libudev = dependency('libudev', required: session_required)
|
||||||
|
if not (libudev.found() and libseat.found())
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
|
||||||
|
wlr_files += files('session_libudev.c')
|
||||||
|
wlr_deps += libudev
|
||||||
|
elif platform == 'openbsd'
|
||||||
|
wlr_files += files('session_openbsd.c')
|
||||||
|
else
|
||||||
|
error('Unsupported platform')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
wlr_files += files('session.c')
|
wlr_files += files('session.c')
|
||||||
wlr_deps += [udev, libseat]
|
wlr_deps += libseat
|
||||||
features += { 'session': true }
|
features += { 'session': true }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libudev.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -14,6 +13,7 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
#include <glob.h>
|
||||||
#include "backend/session/session.h"
|
#include "backend/session/session.h"
|
||||||
#include "util/time.h"
|
#include "util/time.h"
|
||||||
|
|
||||||
|
|
@ -146,99 +146,70 @@ static bool is_drm_card(const char *sysname) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_udev_change_event(struct wlr_device_change_event *event,
|
static int handle_device_event(int fd, uint32_t mask, void *data) {
|
||||||
struct udev_device *udev_dev) {
|
|
||||||
const char *hotplug = udev_device_get_property_value(udev_dev, "HOTPLUG");
|
|
||||||
if (hotplug != NULL && strcmp(hotplug, "1") == 0) {
|
|
||||||
event->type = WLR_DEVICE_HOTPLUG;
|
|
||||||
struct wlr_device_hotplug_event *hotplug = &event->hotplug;
|
|
||||||
|
|
||||||
const char *connector =
|
|
||||||
udev_device_get_property_value(udev_dev, "CONNECTOR");
|
|
||||||
if (connector != NULL) {
|
|
||||||
hotplug->connector_id = strtoul(connector, NULL, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *prop =
|
|
||||||
udev_device_get_property_value(udev_dev, "PROPERTY");
|
|
||||||
if (prop != NULL) {
|
|
||||||
hotplug->prop_id = strtoul(prop, NULL, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *lease = udev_device_get_property_value(udev_dev, "LEASE");
|
|
||||||
if (lease != NULL && strcmp(lease, "1") == 0) {
|
|
||||||
event->type = WLR_DEVICE_LEASE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int handle_udev_event(int fd, uint32_t mask, void *data) {
|
|
||||||
struct wlr_session *session = data;
|
struct wlr_session *session = data;
|
||||||
|
|
||||||
struct udev_device *udev_dev = udev_monitor_receive_device(session->mon);
|
struct drm_event_content ev;
|
||||||
if (!udev_dev) {
|
if (receive_drm_device(session->drm_handle, &ev) < 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
wlr_log(WLR_DEBUG, "drm event for %s", ev.devnode);
|
||||||
|
|
||||||
|
if (!is_drm_card(ev.devnode)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *sysname = udev_device_get_sysname(udev_dev);
|
const char *seat = get_device_seat(session->drm_handle, ev.devnode);
|
||||||
const char *devnode = udev_device_get_devnode(udev_dev);
|
|
||||||
const char *action = udev_device_get_action(udev_dev);
|
|
||||||
wlr_log(WLR_DEBUG, "udev event for %s (%s)", sysname, action);
|
|
||||||
|
|
||||||
if (!is_drm_card(sysname) || !action || !devnode) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *seat = udev_device_get_property_value(udev_dev, "ID_SEAT");
|
|
||||||
if (!seat) {
|
if (!seat) {
|
||||||
seat = "seat0";
|
seat = "seat0";
|
||||||
}
|
}
|
||||||
if (session->seat[0] != '\0' && strcmp(session->seat, seat) != 0) {
|
if (session->seat[0] != '\0' && strcmp(session->seat, seat) != 0) {
|
||||||
goto out;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_t devnum = udev_device_get_devnum(udev_dev);
|
struct wlr_device *dev;
|
||||||
if (strcmp(action, "add") == 0) {
|
switch (ev.type) {
|
||||||
struct wlr_device *dev;
|
case DRM_EVENT_ACTION_ADD:
|
||||||
wl_list_for_each(dev, &session->devices, link) {
|
wl_list_for_each(dev, &session->devices, link) {
|
||||||
if (dev->dev == devnum) {
|
if (dev->dev == ev.devnum) {
|
||||||
wlr_log(WLR_DEBUG, "Skipping duplicate device %s", sysname);
|
wlr_log(WLR_DEBUG, "Skipping duplicate device %s", ev.devnode);
|
||||||
goto out;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_log(WLR_DEBUG, "DRM device %s added", sysname);
|
wlr_log(WLR_DEBUG, "DRM device %s added", ev.devnode);
|
||||||
struct wlr_session_add_event event = {
|
struct wlr_session_add_event event = {
|
||||||
.path = devnode,
|
.path = ev.devnode,
|
||||||
};
|
};
|
||||||
wl_signal_emit_mutable(&session->events.add_drm_card, &event);
|
wl_signal_emit_mutable(&session->events.add_drm_card, &event);
|
||||||
} else if (strcmp(action, "change") == 0) {
|
break;
|
||||||
struct wlr_device *dev;
|
case DRM_EVENT_ACTION_CHANGE:
|
||||||
wl_list_for_each(dev, &session->devices, link) {
|
wl_list_for_each(dev, &session->devices, link) {
|
||||||
if (dev->dev == devnum) {
|
if (dev->dev == ev.devnum) {
|
||||||
wlr_log(WLR_DEBUG, "DRM device %s changed", sysname);
|
wlr_log(WLR_DEBUG, "DRM device %s changed", ev.devnode);
|
||||||
struct wlr_device_change_event event = {0};
|
struct wlr_device_change_event event = {0};
|
||||||
read_udev_change_event(&event, udev_dev);
|
event.hotplug.connector_id = ev.conn_id;
|
||||||
|
event.hotplug.prop_id = ev.prop_id;
|
||||||
|
event.type = ev.has_lease ?
|
||||||
|
WLR_DEVICE_LEASE : WLR_DEVICE_HOTPLUG;
|
||||||
wl_signal_emit_mutable(&dev->events.change, &event);
|
wl_signal_emit_mutable(&dev->events.change, &event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (strcmp(action, "remove") == 0) {
|
break;
|
||||||
struct wlr_device *dev;
|
case DRM_EVENT_ACTION_REMOVE:
|
||||||
wl_list_for_each(dev, &session->devices, link) {
|
wl_list_for_each(dev, &session->devices, link) {
|
||||||
if (dev->dev == devnum) {
|
if (dev->dev == ev.devnum) {
|
||||||
wlr_log(WLR_DEBUG, "DRM device %s removed", sysname);
|
wlr_log(WLR_DEBUG, "DRM device %s removed", ev.devnode);
|
||||||
wl_signal_emit_mutable(&dev->events.remove, NULL);
|
wl_signal_emit_mutable(&dev->events.remove, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case DRM_EVENT_ACTION_NONE:
|
||||||
|
wlr_log(WLR_DEBUG, "Unknown device event");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
udev_device_unref(udev_dev);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,27 +237,17 @@ struct wlr_session *wlr_session_create(struct wl_event_loop *event_loop) {
|
||||||
goto error_open;
|
goto error_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->udev = udev_new();
|
int fd = -1;
|
||||||
if (!session->udev) {
|
session->drm_handle = monitor_drm_events(&fd);
|
||||||
wlr_log_errno(WLR_ERROR, "Failed to create udev context");
|
if (!session->drm_handle) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create device monitor context");
|
||||||
goto error_session;
|
goto error_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->mon = udev_monitor_new_from_netlink(session->udev, "udev");
|
session->drm_event = wl_event_loop_add_fd(event_loop, fd,
|
||||||
if (!session->mon) {
|
WL_EVENT_READABLE, handle_device_event, session);
|
||||||
wlr_log_errno(WLR_ERROR, "Failed to create udev monitor");
|
if (!session->drm_event) {
|
||||||
goto error_udev;
|
wlr_log_errno(WLR_ERROR, "Failed to create device event source");
|
||||||
}
|
|
||||||
|
|
||||||
udev_monitor_filter_add_match_subsystem_devtype(session->mon, "drm", NULL);
|
|
||||||
udev_monitor_enable_receiving(session->mon);
|
|
||||||
|
|
||||||
int fd = udev_monitor_get_fd(session->mon);
|
|
||||||
|
|
||||||
session->udev_event = wl_event_loop_add_fd(event_loop, fd,
|
|
||||||
WL_EVENT_READABLE, handle_udev_event, session);
|
|
||||||
if (!session->udev_event) {
|
|
||||||
wlr_log_errno(WLR_ERROR, "Failed to create udev event source");
|
|
||||||
goto error_mon;
|
goto error_mon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,9 +257,7 @@ struct wlr_session *wlr_session_create(struct wl_event_loop *event_loop) {
|
||||||
return session;
|
return session;
|
||||||
|
|
||||||
error_mon:
|
error_mon:
|
||||||
udev_monitor_unref(session->mon);
|
drm_event_monitor_free(session->drm_handle);
|
||||||
error_udev:
|
|
||||||
udev_unref(session->udev);
|
|
||||||
error_session:
|
error_session:
|
||||||
libseat_session_finish(session);
|
libseat_session_finish(session);
|
||||||
error_open:
|
error_open:
|
||||||
|
|
@ -319,9 +278,8 @@ void wlr_session_destroy(struct wlr_session *session) {
|
||||||
|
|
||||||
wl_list_remove(&session->event_loop_destroy.link);
|
wl_list_remove(&session->event_loop_destroy.link);
|
||||||
|
|
||||||
wl_event_source_remove(session->udev_event);
|
wl_event_source_remove(session->drm_event);
|
||||||
udev_monitor_unref(session->mon);
|
drm_event_monitor_free(session->drm_handle);
|
||||||
udev_unref(session->udev);
|
|
||||||
|
|
||||||
struct wlr_device *dev, *tmp_dev;
|
struct wlr_device *dev, *tmp_dev;
|
||||||
wl_list_for_each_safe(dev, tmp_dev, &session->devices, link) {
|
wl_list_for_each_safe(dev, tmp_dev, &session->devices, link) {
|
||||||
|
|
@ -443,25 +401,6 @@ static ssize_t explicit_find_gpus(struct wlr_session *session,
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct udev_enumerate *enumerate_drm_cards(struct udev *udev) {
|
|
||||||
struct udev_enumerate *en = udev_enumerate_new(udev);
|
|
||||||
if (!en) {
|
|
||||||
wlr_log(WLR_ERROR, "udev_enumerate_new failed");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
udev_enumerate_add_match_subsystem(en, "drm");
|
|
||||||
udev_enumerate_add_match_sysname(en, DRM_PRIMARY_MINOR_NAME "[0-9]*");
|
|
||||||
|
|
||||||
if (udev_enumerate_scan_devices(en) != 0) {
|
|
||||||
wlr_log(WLR_ERROR, "udev_enumerate_scan_devices failed");
|
|
||||||
udev_enumerate_unref(en);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return en;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct find_gpus_add_handler {
|
struct find_gpus_add_handler {
|
||||||
bool added;
|
bool added;
|
||||||
struct wl_listener listener;
|
struct wl_listener listener;
|
||||||
|
|
@ -481,14 +420,13 @@ ssize_t wlr_session_find_gpus(struct wlr_session *session,
|
||||||
return explicit_find_gpus(session, ret_len, ret, explicit);
|
return explicit_find_gpus(session, ret_len, ret, explicit);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct udev_enumerate *en = enumerate_drm_cards(session->udev);
|
static const char *node_glob = DRM_DIR_NAME "/" DRM_PRIMARY_MINOR_NAME "[0-9]*";
|
||||||
if (!en) {
|
glob_t gl;
|
||||||
|
if (glob(node_glob, 0, NULL, &gl) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (gl.gl_pathc == 0) {
|
||||||
if (udev_enumerate_get_list_entry(en) == NULL) {
|
globfree(&gl);
|
||||||
udev_enumerate_unref(en);
|
|
||||||
en = NULL;
|
|
||||||
wlr_log(WLR_INFO, "Waiting for a KMS device");
|
wlr_log(WLR_INFO, "Waiting for a KMS device");
|
||||||
|
|
||||||
struct find_gpus_add_handler handler = {0};
|
struct find_gpus_add_handler handler = {0};
|
||||||
|
|
@ -513,71 +451,39 @@ ssize_t wlr_session_find_gpus(struct wlr_session *session,
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_remove(&handler.listener.link);
|
wl_list_remove(&handler.listener.link);
|
||||||
|
if (glob(node_glob, 0, NULL, &gl) != 0) {
|
||||||
en = enumerate_drm_cards(session->udev);
|
|
||||||
if (!en) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct udev_list_entry *entry;
|
size_t ret_num = 0;
|
||||||
size_t i = 0;
|
for (size_t i = 0; i < gl.gl_pathc && ret_num < ret_len; i++) {
|
||||||
|
const char *devnode = gl.gl_pathv[i];
|
||||||
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(en)) {
|
const char *seat = get_device_seat(session->drm_handle, devnode);
|
||||||
if (i == ret_len) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *path = udev_list_entry_get_name(entry);
|
|
||||||
struct udev_device *dev = udev_device_new_from_syspath(session->udev, path);
|
|
||||||
if (!dev) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *seat = udev_device_get_property_value(dev, "ID_SEAT");
|
|
||||||
if (!seat) {
|
if (!seat) {
|
||||||
seat = "seat0";
|
seat = "seat0";
|
||||||
}
|
}
|
||||||
if (session->seat[0] && strcmp(session->seat, seat) != 0) {
|
if (session->seat[0] && strcmp(session->seat, seat) != 0) {
|
||||||
udev_device_unref(dev);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_primary = false;
|
bool is_primary = is_drm_device_primary(session->drm_handle, devnode);
|
||||||
const char *boot_display = udev_device_get_sysattr_value(dev, "boot_display");
|
|
||||||
if (boot_display && strcmp(boot_display, "1") == 0) {
|
|
||||||
is_primary = true;
|
|
||||||
} else {
|
|
||||||
// This is owned by 'dev', so we don't need to free it
|
|
||||||
struct udev_device *pci =
|
|
||||||
udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
|
|
||||||
|
|
||||||
if (pci) {
|
|
||||||
const char *id = udev_device_get_sysattr_value(pci, "boot_vga");
|
|
||||||
if (id && strcmp(id, "1") == 0) {
|
|
||||||
is_primary = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_device *wlr_dev =
|
struct wlr_device *wlr_dev =
|
||||||
session_open_if_kms(session, udev_device_get_devnode(dev));
|
session_open_if_kms(session, devnode);
|
||||||
udev_device_unref(dev);
|
|
||||||
if (!wlr_dev) {
|
if (!wlr_dev) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret[i] = wlr_dev;
|
ret[ret_num] = wlr_dev;
|
||||||
if (is_primary) {
|
if (is_primary) {
|
||||||
struct wlr_device *tmp = ret[0];
|
struct wlr_device *tmp = ret[0];
|
||||||
ret[0] = ret[i];
|
ret[0] = ret[ret_num];
|
||||||
ret[i] = tmp;
|
ret[ret_num] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
++ret_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_enumerate_unref(en);
|
globfree(&gl);
|
||||||
|
return ret_num;
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
147
backend/session/session_libudev.c
Normal file
147
backend/session/session_libudev.c
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <libudev.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <wlr/backend/session.h>
|
||||||
|
#include "backend/session/session.h"
|
||||||
|
|
||||||
|
struct drm_event_monitor {
|
||||||
|
struct udev *udev;
|
||||||
|
struct udev_monitor *mon;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_event_monitor *monitor_drm_events(int *fd) {
|
||||||
|
struct drm_event_monitor *ctx = calloc(1, sizeof(*ctx));
|
||||||
|
if (!ctx) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ctx->udev = udev_new();
|
||||||
|
if (!ctx->udev) {
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ctx->mon = udev_monitor_new_from_netlink(ctx->udev, "udev");
|
||||||
|
if (!ctx->mon) {
|
||||||
|
udev_unref(ctx->udev);
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
udev_monitor_filter_add_match_subsystem_devtype(ctx->mon, "drm", NULL);
|
||||||
|
udev_monitor_enable_receiving(ctx->mon);
|
||||||
|
*fd = udev_monitor_get_fd(ctx->mon);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drm_event_monitor_free(struct drm_event_monitor *ctx) {
|
||||||
|
udev_monitor_unref(ctx->mon);
|
||||||
|
udev_unref(ctx->udev);
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void populate_drm_event(struct drm_event_content *ev,
|
||||||
|
struct udev_device *dev) {
|
||||||
|
memset(ev, 0, sizeof(*ev));
|
||||||
|
|
||||||
|
const char *devnode = udev_device_get_devnode(dev);
|
||||||
|
if (devnode) {
|
||||||
|
int len = snprintf(ev->devnode, sizeof(ev->devnode), "%s", devnode);
|
||||||
|
assert((size_t)len < sizeof(ev->devnode));
|
||||||
|
}
|
||||||
|
ev->devnum = udev_device_get_devnum(dev);
|
||||||
|
|
||||||
|
const char *action = udev_device_get_action(dev);
|
||||||
|
if (strcmp(action, "add") == 0) {
|
||||||
|
ev->type = DRM_EVENT_ACTION_ADD;
|
||||||
|
} else if (strcmp(action, "change") == 0) {
|
||||||
|
ev->type = DRM_EVENT_ACTION_CHANGE;
|
||||||
|
} else if (strcmp(action, "remove") == 0) {
|
||||||
|
ev->type = DRM_EVENT_ACTION_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *hotplug = udev_device_get_property_value(dev, "HOTPLUG");
|
||||||
|
if (hotplug != NULL && strcmp(hotplug, "1") == 0) {
|
||||||
|
ev->has_lease = false;
|
||||||
|
|
||||||
|
const char *connector =
|
||||||
|
udev_device_get_property_value(dev, "CONNECTOR");
|
||||||
|
if (connector != NULL) {
|
||||||
|
ev->conn_id = strtoul(connector, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *prop =
|
||||||
|
udev_device_get_property_value(dev, "PROPERTY");
|
||||||
|
if (prop != NULL) {
|
||||||
|
ev->prop_id = strtoul(prop, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *lease = udev_device_get_property_value(dev, "LEASE");
|
||||||
|
if (lease != NULL && strcmp(lease, "1") == 0) {
|
||||||
|
ev->has_lease = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int receive_drm_device(struct drm_event_monitor *ctx,
|
||||||
|
struct drm_event_content *ev) {
|
||||||
|
struct udev_device *dev = udev_monitor_receive_device(ctx->mon);
|
||||||
|
if (!dev) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
populate_drm_event(ev, dev);
|
||||||
|
udev_device_unref(dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct udev_device *get_udev_device_from_devnode(struct udev *udev,
|
||||||
|
const char *devnode) {
|
||||||
|
const char *sysname = strrchr(devnode, '/');
|
||||||
|
if (!sysname) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sysname += 1;
|
||||||
|
struct udev_device *dev =
|
||||||
|
udev_device_new_from_subsystem_sysname(udev, "drm", sysname);
|
||||||
|
if (!dev) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: move it to libseat?
|
||||||
|
const char *get_device_seat(struct drm_event_monitor *ctx, const char *devnode) {
|
||||||
|
struct udev_device *dev = get_udev_device_from_devnode(ctx->udev, devnode);
|
||||||
|
if (!dev) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
const char *seat = udev_device_get_property_value(dev, "ID_SEAT");
|
||||||
|
udev_device_unref(dev);
|
||||||
|
return seat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: use sysfs directly?
|
||||||
|
bool is_drm_device_primary(struct drm_event_monitor *ctx, const char *devnode) {
|
||||||
|
struct udev_device *dev = get_udev_device_from_devnode(ctx->udev, devnode);
|
||||||
|
if (!dev) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const char *boot_display = udev_device_get_sysattr_value(dev, "boot_display");
|
||||||
|
if (boot_display && strcmp(boot_display, "1") == 0) {
|
||||||
|
udev_device_unref(dev);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// This is owned by 'dev', so we don't need to free it
|
||||||
|
struct udev_device *pci =
|
||||||
|
udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
|
||||||
|
if (!pci) {
|
||||||
|
udev_device_unref(dev);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const char *id = udev_device_get_sysattr_value(pci, "boot_vga");
|
||||||
|
bool primary = id && strcmp(id, "1") == 0;
|
||||||
|
udev_device_unref(dev);
|
||||||
|
return primary;
|
||||||
|
}
|
||||||
41
backend/session/session_openbsd.c
Normal file
41
backend/session/session_openbsd.c
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "backend/session/session.h"
|
||||||
|
|
||||||
|
struct drm_event_monitor {
|
||||||
|
int fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: use kqueue NOTE_CHANGE mechanism
|
||||||
|
struct drm_event_monitor *monitor_drm_events(int *fd) {
|
||||||
|
struct drm_event_monitor *ctx = calloc(1, sizeof(struct drm_event_monitor));
|
||||||
|
if (!ctx) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ctx->fd = open("/dev/null", O_RDONLY);
|
||||||
|
if (ctx->fd == -1) {
|
||||||
|
free(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*fd = ctx->fd;
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
void drm_event_monitor_free(struct drm_event_monitor *ctx) {
|
||||||
|
close(ctx->fd);
|
||||||
|
free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int receive_drm_device(struct drm_event_monitor *ctx,
|
||||||
|
struct drm_event_content *ev) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *get_device_seat(struct drm_event_monitor *ctx, const char *devnode) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_drm_device_primary(struct drm_event_monitor *ctx, const char *devnode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
281
backend/wscons/atKeynames.h
Normal file
281
backend/wscons/atKeynames.h
Normal file
|
|
@ -0,0 +1,281 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
* documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
* the above copyright notice appear in all copies and that both that
|
||||||
|
* copyright notice and this permission notice appear in supporting
|
||||||
|
* documentation, and that the name of Thomas Roell not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the software without
|
||||||
|
* specific, written prior permission. Thomas Roell makes no representations
|
||||||
|
* about the suitability of this software for any purpose. It is provided
|
||||||
|
* "as is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||||
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1994-2003 by The XFree86 Project, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* Except as contained in this notice, the name of the copyright holder(s)
|
||||||
|
* and author(s) shall not be used in advertising or otherwise to promote
|
||||||
|
* the sale, use or other dealings in this Software without prior written
|
||||||
|
* authorization from the copyright holder(s) and author(s).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ATKEYNAMES_H
|
||||||
|
#define _ATKEYNAMES_H
|
||||||
|
|
||||||
|
#define XK_TECHNICAL
|
||||||
|
#define XK_KATAKANA
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three)
|
||||||
|
* sets of scancodes. Set3 can only be generated by a MF keyboard.
|
||||||
|
* Set2 sends a makecode for keypress, and the same code prefixed by a
|
||||||
|
* F0 for keyrelease. This is a little bit ugly to handle. Thus we use
|
||||||
|
* here for X386 the PC/XT compatible Set1. This set uses 8bit scancodes.
|
||||||
|
* Bit 7 ist set if the key is released. The code E0 switches to a
|
||||||
|
* different meaning to add the new MF cursorkeys, while not breaking old
|
||||||
|
* applications. E1 is another special prefix. Since I assume that there
|
||||||
|
* will be further versions of PC/XT scancode compatible keyboards, we
|
||||||
|
* may be in trouble one day.
|
||||||
|
*
|
||||||
|
* IDEA: 1) Use Set2 on AT84 keyboards and translate it to MF Set3.
|
||||||
|
* 2) Use the keyboards native set and translate it to common keysyms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* definition of the AT84/MF101/MF102 Keyboard:
|
||||||
|
* ============================================================
|
||||||
|
* Defined Key Cap Glyphs Pressed value
|
||||||
|
* Key Name Main Also (hex) (dec)
|
||||||
|
* ---------------- ---------- ------- ------ ------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KEY_Escape /* Escape 0x01 */ 1
|
||||||
|
#define KEY_1 /* 1 ! 0x02 */ 2
|
||||||
|
#define KEY_2 /* 2 @ 0x03 */ 3
|
||||||
|
#define KEY_3 /* 3 # 0x04 */ 4
|
||||||
|
#define KEY_4 /* 4 $ 0x05 */ 5
|
||||||
|
#define KEY_5 /* 5 % 0x06 */ 6
|
||||||
|
#define KEY_6 /* 6 ^ 0x07 */ 7
|
||||||
|
#define KEY_7 /* 7 & 0x08 */ 8
|
||||||
|
#define KEY_8 /* 8 * 0x09 */ 9
|
||||||
|
#define KEY_9 /* 9 ( 0x0a */ 10
|
||||||
|
#define KEY_0 /* 0 ) 0x0b */ 11
|
||||||
|
#define KEY_Minus /* - (Minus) _ (Under) 0x0c */ 12
|
||||||
|
#define KEY_Equal /* = (Equal) + 0x0d */ 13
|
||||||
|
#define KEY_BackSpace /* Back Space 0x0e */ 14
|
||||||
|
#define KEY_Tab /* Tab 0x0f */ 15
|
||||||
|
#define KEY_Q /* Q 0x10 */ 16
|
||||||
|
#define KEY_W /* W 0x11 */ 17
|
||||||
|
#define KEY_E /* E 0x12 */ 18
|
||||||
|
#define KEY_R /* R 0x13 */ 19
|
||||||
|
#define KEY_T /* T 0x14 */ 20
|
||||||
|
#define KEY_Y /* Y 0x15 */ 21
|
||||||
|
#define KEY_U /* U 0x16 */ 22
|
||||||
|
#define KEY_I /* I 0x17 */ 23
|
||||||
|
#define KEY_O /* O 0x18 */ 24
|
||||||
|
#define KEY_P /* P 0x19 */ 25
|
||||||
|
#define KEY_LBrace /* [ { 0x1a */ 26
|
||||||
|
#define KEY_RBrace /* ] } 0x1b */ 27
|
||||||
|
#define KEY_Enter /* Enter 0x1c */ 28
|
||||||
|
#define KEY_LCtrl /* Ctrl(left) 0x1d */ 29
|
||||||
|
#define KEY_A /* A 0x1e */ 30
|
||||||
|
#define KEY_S /* S 0x1f */ 31
|
||||||
|
#define KEY_D /* D 0x20 */ 32
|
||||||
|
#define KEY_F /* F 0x21 */ 33
|
||||||
|
#define KEY_G /* G 0x22 */ 34
|
||||||
|
#define KEY_H /* H 0x23 */ 35
|
||||||
|
#define KEY_J /* J 0x24 */ 36
|
||||||
|
#define KEY_K /* K 0x25 */ 37
|
||||||
|
#define KEY_L /* L 0x26 */ 38
|
||||||
|
#define KEY_SemiColon /* ;(SemiColon) :(Colon) 0x27 */ 39
|
||||||
|
#define KEY_Quote /* ' (Apostr) " (Quote) 0x28 */ 40
|
||||||
|
#define KEY_Tilde /* ` (Accent) ~ (Tilde) 0x29 */ 41
|
||||||
|
#define KEY_ShiftL /* Shift(left) 0x2a */ 42
|
||||||
|
#define KEY_BSlash /* \(BckSlash) |(VertBar)0x2b */ 43
|
||||||
|
#define KEY_Z /* Z 0x2c */ 44
|
||||||
|
#define KEY_X /* X 0x2d */ 45
|
||||||
|
#define KEY_C /* C 0x2e */ 46
|
||||||
|
#define KEY_V /* V 0x2f */ 47
|
||||||
|
#define KEY_B /* B 0x30 */ 48
|
||||||
|
#define KEY_N /* N 0x31 */ 49
|
||||||
|
#define KEY_M /* M 0x32 */ 50
|
||||||
|
#define KEY_Comma /* , (Comma) < (Less) 0x33 */ 51
|
||||||
|
#define KEY_Period /* . (Period) >(Greater)0x34 */ 52
|
||||||
|
#define KEY_Slash /* / (Slash) ? 0x35 */ 53
|
||||||
|
#define KEY_ShiftR /* Shift(right) 0x36 */ 54
|
||||||
|
#define KEY_KP_Multiply /* * 0x37 */ 55
|
||||||
|
#define KEY_Alt /* Alt(left) 0x38 */ 56
|
||||||
|
#define KEY_Space /* (SpaceBar) 0x39 */ 57
|
||||||
|
#define KEY_CapsLock /* CapsLock 0x3a */ 58
|
||||||
|
#define KEY_F1 /* F1 0x3b */ 59
|
||||||
|
#define KEY_F2 /* F2 0x3c */ 60
|
||||||
|
#define KEY_F3 /* F3 0x3d */ 61
|
||||||
|
#define KEY_F4 /* F4 0x3e */ 62
|
||||||
|
#define KEY_F5 /* F5 0x3f */ 63
|
||||||
|
#define KEY_F6 /* F6 0x40 */ 64
|
||||||
|
#define KEY_F7 /* F7 0x41 */ 65
|
||||||
|
#define KEY_F8 /* F8 0x42 */ 66
|
||||||
|
#define KEY_F9 /* F9 0x43 */ 67
|
||||||
|
#define KEY_F10 /* F10 0x44 */ 68
|
||||||
|
#define KEY_NumLock /* NumLock 0x45 */ 69
|
||||||
|
#define KEY_ScrollLock /* ScrollLock 0x46 */ 70
|
||||||
|
#define KEY_KP_7 /* 7 Home 0x47 */ 71
|
||||||
|
#define KEY_KP_8 /* 8 Up 0x48 */ 72
|
||||||
|
#define KEY_KP_9 /* 9 PgUp 0x49 */ 73
|
||||||
|
#define KEY_KP_Minus /* - (Minus) 0x4a */ 74
|
||||||
|
#define KEY_KP_4 /* 4 Left 0x4b */ 75
|
||||||
|
#define KEY_KP_5 /* 5 0x4c */ 76
|
||||||
|
#define KEY_KP_6 /* 6 Right 0x4d */ 77
|
||||||
|
#define KEY_KP_Plus /* + (Plus) 0x4e */ 78
|
||||||
|
#define KEY_KP_1 /* 1 End 0x4f */ 79
|
||||||
|
#define KEY_KP_2 /* 2 Down 0x50 */ 80
|
||||||
|
#define KEY_KP_3 /* 3 PgDown 0x51 */ 81
|
||||||
|
#define KEY_KP_0 /* 0 Insert 0x52 */ 82
|
||||||
|
#define KEY_KP_Decimal /* . (Decimal) Delete 0x53 */ 83
|
||||||
|
#define KEY_SysReqest /* SysReqest 0x54 */ 84
|
||||||
|
/* NOTUSED 0x55 */
|
||||||
|
#define KEY_Less /* < (Less) >(Greater) 0x56 */ 86
|
||||||
|
#define KEY_F11 /* F11 0x57 */ 87
|
||||||
|
#define KEY_F12 /* F12 0x58 */ 88
|
||||||
|
|
||||||
|
#define KEY_Prefix0 /* special 0x60 */ 96
|
||||||
|
#define KEY_Prefix1 /* specail 0x61 */ 97
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 'scancodes' below are generated by the server, because the MF101/102
|
||||||
|
* keyboard sends them as sequence of other scancodes
|
||||||
|
*/
|
||||||
|
#define KEY_Home /* Home 0x59 */ 89
|
||||||
|
#define KEY_Up /* Up 0x5a */ 90
|
||||||
|
#define KEY_PgUp /* PgUp 0x5b */ 91
|
||||||
|
#define KEY_Left /* Left 0x5c */ 92
|
||||||
|
#define KEY_Begin /* Begin 0x5d */ 93
|
||||||
|
#define KEY_Right /* Right 0x5e */ 94
|
||||||
|
#define KEY_End /* End 0x5f */ 95
|
||||||
|
#define KEY_Down /* Down 0x60 */ 96
|
||||||
|
#define KEY_PgDown /* PgDown 0x61 */ 97
|
||||||
|
#define KEY_Insert /* Insert 0x62 */ 98
|
||||||
|
#define KEY_Delete /* Delete 0x63 */ 99
|
||||||
|
#define KEY_KP_Enter /* Enter 0x64 */ 100
|
||||||
|
#define KEY_RCtrl /* Ctrl(right) 0x65 */ 101
|
||||||
|
#define KEY_Pause /* Pause 0x66 */ 102
|
||||||
|
#define KEY_Print /* Print 0x67 */ 103
|
||||||
|
#define KEY_KP_Divide /* Divide 0x68 */ 104
|
||||||
|
#define KEY_AltLang /* AtlLang(right) 0x69 */ 105
|
||||||
|
#define KEY_Break /* Break 0x6a */ 106
|
||||||
|
#define KEY_LMeta /* Left Meta 0x6b */ 107
|
||||||
|
#define KEY_RMeta /* Right Meta 0x6c */ 108
|
||||||
|
#define KEY_Menu /* Menu 0x6d */ 109
|
||||||
|
#define KEY_F13 /* F13 0x6e */ 110
|
||||||
|
#define KEY_F14 /* F14 0x6f */ 111
|
||||||
|
#define KEY_F15 /* F15 0x70 */ 112
|
||||||
|
#define KEY_HKTG /* Hirugana/Katakana tog 0x70 */ 112
|
||||||
|
#define KEY_F16 /* F16 0x71 */ 113
|
||||||
|
#define KEY_F17 /* F17 0x72 */ 114
|
||||||
|
#define KEY_KP_DEC /* KP_DEC 0x73 */ 115
|
||||||
|
#define KEY_BSlash2 /* \ _ 0x73 */ 115
|
||||||
|
#define KEY_KP_Equal /* Equal (Keypad) 0x76 */ 118
|
||||||
|
#define KEY_XFER /* Kanji Transfer 0x79 */ 121
|
||||||
|
#define KEY_NFER /* No Kanji Transfer 0x7b */ 123
|
||||||
|
#define KEY_Yen /* Yen 0x7d */ 125
|
||||||
|
|
||||||
|
#define KEY_Power /* Power Key 0x84 */ 132
|
||||||
|
#define KEY_Mute /* Audio Mute 0x85 */ 133
|
||||||
|
#define KEY_AudioLower /* Audio Lower 0x86 */ 134
|
||||||
|
#define KEY_AudioRaise /* Audio Raise 0x87 */ 135
|
||||||
|
#define KEY_Help /* Help 0x88 */ 136
|
||||||
|
#define KEY_L1 /* Stop 0x89 */ 137
|
||||||
|
#define KEY_L2 /* Again 0x8a */ 138
|
||||||
|
#define KEY_L3 /* Props 0x8b */ 139
|
||||||
|
#define KEY_L4 /* Undo 0x8c */ 140
|
||||||
|
#define KEY_L5 /* Front 0x8d */ 141
|
||||||
|
#define KEY_L6 /* Copy 0x8e */ 142
|
||||||
|
#define KEY_L7 /* Open 0x8f */ 143
|
||||||
|
#define KEY_L8 /* Paste 0x90 */ 144
|
||||||
|
#define KEY_L9 /* Find 0x91 */ 145
|
||||||
|
#define KEY_L10 /* Cut 0x92 */ 146
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fake 'scancodes' in the following ranges are generated for 2-byte
|
||||||
|
* codes not handled elsewhere. These correspond to most extended keys
|
||||||
|
* on so-called "Internet" keyboards:
|
||||||
|
*
|
||||||
|
* 0x79-0x93
|
||||||
|
* 0x96-0xa1
|
||||||
|
* 0xa3-0xac
|
||||||
|
* 0xb1-0xb4
|
||||||
|
* 0xba-0xbd
|
||||||
|
* 0xc2
|
||||||
|
* 0xcc-0xd2
|
||||||
|
* 0xd6-0xf7
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remapped 'scancodes' are generated for single-byte codes in the range
|
||||||
|
* 0x59-0x5f,0x62-0x76. These are used for some extra keys on some keyboards.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KEY_0x59 0x95
|
||||||
|
#define KEY_0x5A 0xA2
|
||||||
|
#define KEY_0x5B 0xAD
|
||||||
|
#define KEY_0x5C KEY_KP_EQUAL
|
||||||
|
#define KEY_0x5D 0xAE
|
||||||
|
#define KEY_0x5E 0xAF
|
||||||
|
#define KEY_0x5F 0xB0
|
||||||
|
#define KEY_0x62 0xB5
|
||||||
|
#define KEY_0x63 0xB6
|
||||||
|
#define KEY_0x64 0xB7
|
||||||
|
#define KEY_0x65 0xB8
|
||||||
|
#define KEY_0x66 0xB9
|
||||||
|
#define KEY_0x67 0xBE
|
||||||
|
#define KEY_0x68 0xBF
|
||||||
|
#define KEY_0x69 0xC0
|
||||||
|
#define KEY_0x6A 0xC1
|
||||||
|
#define KEY_0x6B 0xC3
|
||||||
|
#define KEY_0x6C 0xC4
|
||||||
|
#define KEY_0x6D 0xC5
|
||||||
|
#define KEY_0x6E 0xC6
|
||||||
|
#define KEY_0x6F 0xC7
|
||||||
|
#define KEY_0x70 0xC8
|
||||||
|
#define KEY_0x71 0xC9
|
||||||
|
#define KEY_0x72 0xCA
|
||||||
|
#define KEY_0x73 0xCB
|
||||||
|
#define KEY_0x74 0xD3
|
||||||
|
#define KEY_0x75 0xD4
|
||||||
|
#define KEY_0x76 0xD5
|
||||||
|
#define KEY_R_0xF4 0xF4
|
||||||
|
#define KEY_R_0xF5 0xF5
|
||||||
|
|
||||||
|
/* These are for "notused" and "unknown" entries in translation maps. */
|
||||||
|
#define KEY_NOTUSED 0
|
||||||
|
#define KEY_UNKNOWN 255
|
||||||
|
|
||||||
|
#endif /* _ATKEYNAMES_H */
|
||||||
332
backend/wscons/backend.c
Normal file
332
backend/wscons/backend.c
Normal file
|
|
@ -0,0 +1,332 @@
|
||||||
|
#define _BSD_SOURCE
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/event.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
#include <wlr/backend/interface.h>
|
||||||
|
#include <wlr/backend/session.h>
|
||||||
|
#include <dev/wscons/wsconsio.h>
|
||||||
|
#include <dev/wscons/wsksymdef.h>
|
||||||
|
#include <wlr/interfaces/wlr_keyboard.h>
|
||||||
|
#include <wlr/interfaces/wlr_pointer.h>
|
||||||
|
|
||||||
|
#include "backend/wscons.h"
|
||||||
|
#include "util/time.h"
|
||||||
|
|
||||||
|
#include "atKeynames.h"
|
||||||
|
#include "bsd_KbdMap.h"
|
||||||
|
|
||||||
|
static struct wlr_wscons_backend *get_wscons_backend_from_backend(
|
||||||
|
struct wlr_backend *wlr_backend) {
|
||||||
|
assert(wlr_backend_is_wscons(wlr_backend));
|
||||||
|
struct wlr_wscons_backend *backend = wl_container_of(wlr_backend, backend, backend);
|
||||||
|
return backend;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ws_to_xkb(unsigned type, int key) {
|
||||||
|
switch (type) {
|
||||||
|
case WSKBD_TYPE_PC_XT:
|
||||||
|
case WSKBD_TYPE_PC_AT:
|
||||||
|
return wsXtMap[key];
|
||||||
|
case WSKBD_TYPE_USB:
|
||||||
|
return wsUsbMap[key];
|
||||||
|
default:
|
||||||
|
wlr_log(WLR_INFO, "Unknown wskbd type %d", type);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wsmouse_to_evdev(int button) {
|
||||||
|
// The right and middle mouse buttons must be swapped
|
||||||
|
switch (button) {
|
||||||
|
case 1: // Middle
|
||||||
|
return 0x112;
|
||||||
|
case 2: // Right
|
||||||
|
return 0x111;
|
||||||
|
default:
|
||||||
|
return button + 0x110;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notify_key(struct wlr_keyboard *wlr_kbd, uint32_t msec,
|
||||||
|
uint32_t state, uint32_t keycode) {
|
||||||
|
struct wlr_keyboard_key_event ev;
|
||||||
|
ev.update_state = true;
|
||||||
|
ev.time_msec = msec;
|
||||||
|
ev.state = state;
|
||||||
|
ev.keycode = keycode;
|
||||||
|
|
||||||
|
wlr_keyboard_notify_key(wlr_kbd, &ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notify_button(struct wlr_pointer *wlr_ptr, uint32_t msec,
|
||||||
|
uint32_t state, uint32_t button) {
|
||||||
|
struct wlr_pointer_button_event ev;
|
||||||
|
ev.pointer = wlr_ptr;
|
||||||
|
ev.time_msec = msec;
|
||||||
|
ev.button = button;
|
||||||
|
ev.state = state;
|
||||||
|
|
||||||
|
wlr_pointer_notify_button(wlr_ptr, &ev);
|
||||||
|
wl_signal_emit_mutable(&wlr_ptr->events.frame, wlr_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notify_motion(struct wlr_pointer *wlr_ptr, uint32_t msec,
|
||||||
|
double x, double y) {
|
||||||
|
struct wlr_pointer_motion_event ev;
|
||||||
|
ev.pointer = wlr_ptr;
|
||||||
|
ev.time_msec = msec;
|
||||||
|
ev.delta_x = x;
|
||||||
|
ev.delta_y = y;
|
||||||
|
ev.unaccel_dx = x;
|
||||||
|
ev.unaccel_dy = y;
|
||||||
|
|
||||||
|
wl_signal_emit_mutable(&wlr_ptr->events.motion, &ev);
|
||||||
|
wl_signal_emit_mutable(&wlr_ptr->events.frame, wlr_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notify_axis(struct wlr_pointer *wlr_ptr, uint32_t msec,
|
||||||
|
uint32_t axis, double delta) {
|
||||||
|
struct wlr_pointer_axis_event ev;
|
||||||
|
ev.pointer = wlr_ptr;
|
||||||
|
ev.time_msec = msec;
|
||||||
|
ev.source = WL_POINTER_AXIS_SOURCE_WHEEL;
|
||||||
|
ev.relative_direction = WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL;
|
||||||
|
ev.delta_discrete = 0; // XXX
|
||||||
|
ev.orientation = axis;
|
||||||
|
ev.delta = delta;
|
||||||
|
|
||||||
|
wl_signal_emit_mutable(&wlr_ptr->events.axis, &ev);
|
||||||
|
wl_signal_emit_mutable(&wlr_ptr->events.frame, wlr_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void notify_motion_abs(struct wlr_pointer *wlr_ptr, uint32_t msec,
|
||||||
|
double x, double y) {
|
||||||
|
struct wlr_pointer_motion_absolute_event ev;
|
||||||
|
ev.pointer = wlr_ptr;
|
||||||
|
ev.time_msec = msec;
|
||||||
|
ev.x = x;
|
||||||
|
ev.y = y;
|
||||||
|
|
||||||
|
wl_signal_emit_mutable(&wlr_ptr->events.motion_absolute, &ev);
|
||||||
|
wl_signal_emit_mutable(&wlr_ptr->events.frame, wlr_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_event(struct wlr_wscons_backend *backend, struct wscons_event *ws_ev) {
|
||||||
|
struct wlr_keyboard *wlr_kbd = &backend->kbd;
|
||||||
|
struct wlr_pointer *wlr_ptr = &backend->mouse;
|
||||||
|
|
||||||
|
uint32_t msec = timespec_to_msec(&ws_ev->time);
|
||||||
|
// TODO: make sure all types are handled
|
||||||
|
switch (ws_ev->type) {
|
||||||
|
case WSCONS_EVENT_KEY_UP:
|
||||||
|
notify_key(wlr_kbd, msec, WL_KEYBOARD_KEY_STATE_RELEASED,
|
||||||
|
ws_to_xkb(backend->kbd_type, ws_ev->value));
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_KEY_DOWN:
|
||||||
|
notify_key(wlr_kbd, msec, WL_KEYBOARD_KEY_STATE_PRESSED,
|
||||||
|
ws_to_xkb(backend->kbd_type, ws_ev->value));
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_MOUSE_UP:
|
||||||
|
notify_button(wlr_ptr, msec, WL_POINTER_BUTTON_STATE_RELEASED,
|
||||||
|
wsmouse_to_evdev(ws_ev->value));
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_MOUSE_DOWN:
|
||||||
|
notify_button(wlr_ptr, msec, WL_POINTER_BUTTON_STATE_PRESSED,
|
||||||
|
wsmouse_to_evdev(ws_ev->value));
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_MOUSE_DELTA_X:
|
||||||
|
notify_motion(wlr_ptr, msec, ws_ev->value, 0);
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_MOUSE_DELTA_Y:
|
||||||
|
notify_motion(wlr_ptr, msec, 0, -ws_ev->value);
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_MOUSE_DELTA_Z:
|
||||||
|
notify_axis(wlr_ptr, msec, WL_POINTER_AXIS_VERTICAL_SCROLL,
|
||||||
|
ws_ev->value * 10);
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_MOUSE_DELTA_W:
|
||||||
|
notify_axis(wlr_ptr, msec, WL_POINTER_AXIS_HORIZONTAL_SCROLL,
|
||||||
|
ws_ev->value * 10);
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
|
||||||
|
notify_motion_abs(wlr_ptr, msec, ws_ev->value, 0);
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
|
||||||
|
notify_motion_abs(wlr_ptr, msec, 0, -ws_ev->value);
|
||||||
|
break;
|
||||||
|
case WSCONS_EVENT_ALL_KEYS_UP:
|
||||||
|
case WSCONS_EVENT_WSMOUSED_ON:
|
||||||
|
case WSCONS_EVENT_WSMOUSED_OFF:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wlr_log(WLR_DEBUG, "Unknown wscons event type: %x", ws_ev->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_wscons_readable(int fd, uint32_t mask, void *_backend) {
|
||||||
|
struct wlr_wscons_backend *backend = _backend;
|
||||||
|
|
||||||
|
while (backend->session->active) {
|
||||||
|
struct kevent kq_ev;
|
||||||
|
static const struct timespec dontblock = {0};
|
||||||
|
if (kevent(fd, NULL, 0, &kq_ev, 1, &dontblock) <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
assert(kq_ev.filter == EVFILT_READ);
|
||||||
|
int in_fd = kq_ev.ident;
|
||||||
|
|
||||||
|
struct wscons_event ws_ev;
|
||||||
|
if (read(in_fd, &ws_ev, sizeof(ws_ev)) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
handle_event(backend, &ws_ev);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void keyboard_set_leds(struct wlr_keyboard *wlr_kb, uint32_t leds) {
|
||||||
|
// TODO: use WSKBDIO_SETLEDS
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct wlr_keyboard_impl wscons_keyboard_impl = {
|
||||||
|
.name = "wscons-keyboard",
|
||||||
|
.led_update = keyboard_set_leds
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct wlr_pointer_impl wscons_pointer_impl = {
|
||||||
|
.name = "wscons-pointer",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int init_wscons(struct wlr_wscons_backend *backend) {
|
||||||
|
struct wlr_device *mouse_dev = wlr_session_open_file(backend->session, "/dev/wsmouse");
|
||||||
|
struct wlr_device *kbd_dev = wlr_session_open_file(backend->session, "/dev/wskbd");
|
||||||
|
if (!mouse_dev || !kbd_dev) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to open input devices");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl(kbd_dev->fd, WSKBDIO_GTYPE, &backend->kbd_type) == -1) {
|
||||||
|
// TODO: free
|
||||||
|
wlr_log(WLR_ERROR, "Failed to get keyboard type");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kfd = kqueue1(O_CLOEXEC);
|
||||||
|
if (kfd == -1) {
|
||||||
|
// TODO: free
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create kqueue fd");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
struct kevent evs[2];
|
||||||
|
EV_SET(&evs[0], mouse_dev->fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
|
||||||
|
EV_SET(&evs[1], kbd_dev->fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
|
||||||
|
if (kevent(kfd, evs, sizeof(evs) / sizeof(evs[0]), NULL, 0, NULL) == -1) {
|
||||||
|
// TODO: free
|
||||||
|
wlr_log(WLR_ERROR, "Failed to setup kqueue");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
backend->mouse_dev = mouse_dev;
|
||||||
|
backend->kbd_dev = kbd_dev;
|
||||||
|
|
||||||
|
struct wlr_keyboard *wlr_kbd = &backend->kbd;
|
||||||
|
wlr_keyboard_init(wlr_kbd, &wscons_keyboard_impl, "wscons-keyboard");
|
||||||
|
wl_signal_emit_mutable(&backend->backend.events.new_input, &wlr_kbd->base);
|
||||||
|
|
||||||
|
struct wlr_pointer *wlr_ptr = &backend->mouse;
|
||||||
|
wlr_pointer_init(wlr_ptr, &wscons_pointer_impl, "wscons-pointer");
|
||||||
|
wl_signal_emit_mutable(&backend->backend.events.new_input, &wlr_ptr->base);
|
||||||
|
|
||||||
|
return kfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool backend_start(struct wlr_backend *wlr_backend) {
|
||||||
|
struct wlr_wscons_backend *backend =
|
||||||
|
get_wscons_backend_from_backend(wlr_backend);
|
||||||
|
wlr_log(WLR_DEBUG, "Starting wscons backend");
|
||||||
|
|
||||||
|
int fd = init_wscons(backend);
|
||||||
|
if (fd < 0) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to initialize wscons backend");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
backend->kqueue_fd = fd;
|
||||||
|
|
||||||
|
if (backend->input_event) {
|
||||||
|
wl_event_source_remove(backend->input_event);
|
||||||
|
}
|
||||||
|
backend->input_event = wl_event_loop_add_fd(backend->session->event_loop, fd,
|
||||||
|
WL_EVENT_READABLE, handle_wscons_readable, backend);
|
||||||
|
if (!backend->input_event) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create input event on event loop");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
wlr_log(WLR_DEBUG, "wscons successfully initialized");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void backend_destroy(struct wlr_backend *wlr_backend) {
|
||||||
|
if (!wlr_backend) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct wlr_wscons_backend *backend =
|
||||||
|
get_wscons_backend_from_backend(wlr_backend);
|
||||||
|
|
||||||
|
wlr_backend_finish(wlr_backend);
|
||||||
|
|
||||||
|
wl_list_remove(&backend->session_destroy.link);
|
||||||
|
|
||||||
|
if (backend->input_event) {
|
||||||
|
wl_event_source_remove(backend->input_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(backend->kqueue_fd);
|
||||||
|
|
||||||
|
if (backend->mouse_dev) {
|
||||||
|
wlr_session_close_file(backend->session, backend->mouse_dev);
|
||||||
|
}
|
||||||
|
if (backend->kbd_dev) {
|
||||||
|
wlr_session_close_file(backend->session, backend->kbd_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(backend);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wlr_backend_impl backend_impl = {
|
||||||
|
.start = backend_start,
|
||||||
|
.destroy = backend_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool wlr_backend_is_wscons(const struct wlr_backend *b) {
|
||||||
|
return b->impl == &backend_impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_session_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_wscons_backend *backend =
|
||||||
|
wl_container_of(listener, backend, session_destroy);
|
||||||
|
backend_destroy(&backend->backend);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_backend *wlr_wscons_backend_create(struct wlr_session *session) {
|
||||||
|
struct wlr_wscons_backend *backend = calloc(1, sizeof(*backend));
|
||||||
|
if (!backend) {
|
||||||
|
wlr_log(WLR_ERROR, "Allocation failed: %s", strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wlr_backend_init(&backend->backend, &backend_impl);
|
||||||
|
|
||||||
|
backend->session = session;
|
||||||
|
backend->kqueue_fd = -1;
|
||||||
|
|
||||||
|
backend->session_destroy.notify = handle_session_destroy;
|
||||||
|
wl_signal_add(&session->events.destroy, &backend->session_destroy);
|
||||||
|
|
||||||
|
return &backend->backend;
|
||||||
|
}
|
||||||
485
backend/wscons/bsd_KbdMap.h
Normal file
485
backend/wscons/bsd_KbdMap.h
Normal file
|
|
@ -0,0 +1,485 @@
|
||||||
|
/*
|
||||||
|
* Slightly modified xf86KbdBSD.c which is
|
||||||
|
*
|
||||||
|
* Derived from xf86Kbd.c by S_ren Schmidt (sos@login.dkuug.dk)
|
||||||
|
* which is Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
|
||||||
|
* and from xf86KbdCODrv.c by Holger Veit
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static uint8_t wsUsbMap[] = {
|
||||||
|
/* 0 */ KEY_NOTUSED,
|
||||||
|
/* 1 */ KEY_NOTUSED,
|
||||||
|
/* 2 */ KEY_NOTUSED,
|
||||||
|
/* 3 */ KEY_NOTUSED,
|
||||||
|
/* 4 */ KEY_A,
|
||||||
|
/* 5 */ KEY_B,
|
||||||
|
/* 6 */ KEY_C,
|
||||||
|
/* 7 */ KEY_D,
|
||||||
|
/* 8 */ KEY_E,
|
||||||
|
/* 9 */ KEY_F,
|
||||||
|
/* 10 */ KEY_G,
|
||||||
|
/* 11 */ KEY_H,
|
||||||
|
/* 12 */ KEY_I,
|
||||||
|
/* 13 */ KEY_J,
|
||||||
|
/* 14 */ KEY_K,
|
||||||
|
/* 15 */ KEY_L,
|
||||||
|
/* 16 */ KEY_M,
|
||||||
|
/* 17 */ KEY_N,
|
||||||
|
/* 18 */ KEY_O,
|
||||||
|
/* 19 */ KEY_P,
|
||||||
|
/* 20 */ KEY_Q,
|
||||||
|
/* 21 */ KEY_R,
|
||||||
|
/* 22 */ KEY_S,
|
||||||
|
/* 23 */ KEY_T,
|
||||||
|
/* 24 */ KEY_U,
|
||||||
|
/* 25 */ KEY_V,
|
||||||
|
/* 26 */ KEY_W,
|
||||||
|
/* 27 */ KEY_X,
|
||||||
|
/* 28 */ KEY_Y,
|
||||||
|
/* 29 */ KEY_Z,
|
||||||
|
/* 30 */ KEY_1, /* 1 !*/
|
||||||
|
/* 31 */ KEY_2, /* 2 @ */
|
||||||
|
/* 32 */ KEY_3, /* 3 # */
|
||||||
|
/* 33 */ KEY_4, /* 4 $ */
|
||||||
|
/* 34 */ KEY_5, /* 5 % */
|
||||||
|
/* 35 */ KEY_6, /* 6 ^ */
|
||||||
|
/* 36 */ KEY_7, /* 7 & */
|
||||||
|
/* 37 */ KEY_8, /* 8 * */
|
||||||
|
/* 38 */ KEY_9, /* 9 ( */
|
||||||
|
/* 39 */ KEY_0, /* 0 ) */
|
||||||
|
/* 40 */ KEY_Enter, /* Return */
|
||||||
|
/* 41 */ KEY_Escape, /* Escape */
|
||||||
|
/* 42 */ KEY_BackSpace, /* Backspace Delete */
|
||||||
|
/* 43 */ KEY_Tab, /* Tab */
|
||||||
|
/* 44 */ KEY_Space, /* Space */
|
||||||
|
/* 45 */ KEY_Minus, /* - _ */
|
||||||
|
/* 46 */ KEY_Equal, /* = + */
|
||||||
|
/* 47 */ KEY_LBrace, /* [ { */
|
||||||
|
/* 48 */ KEY_RBrace, /* ] } */
|
||||||
|
/* 49 */ KEY_BSlash, /* \ | */
|
||||||
|
/* 50 */ KEY_BSlash, /* \ _ # ~ on some keyboards */
|
||||||
|
/* 51 */ KEY_SemiColon, /* ; : */
|
||||||
|
/* 52 */ KEY_Quote, /* ' " */
|
||||||
|
/* 53 */ KEY_Tilde, /* ` ~ */
|
||||||
|
/* 54 */ KEY_Comma, /* , < */
|
||||||
|
/* 55 */ KEY_Period, /* . > */
|
||||||
|
/* 56 */ KEY_Slash, /* / ? */
|
||||||
|
/* 57 */ KEY_CapsLock, /* Caps Lock */
|
||||||
|
/* 58 */ KEY_F1, /* F1 */
|
||||||
|
/* 59 */ KEY_F2, /* F2 */
|
||||||
|
/* 60 */ KEY_F3, /* F3 */
|
||||||
|
/* 61 */ KEY_F4, /* F4 */
|
||||||
|
/* 62 */ KEY_F5, /* F5 */
|
||||||
|
/* 63 */ KEY_F6, /* F6 */
|
||||||
|
/* 64 */ KEY_F7, /* F7 */
|
||||||
|
/* 65 */ KEY_F8, /* F8 */
|
||||||
|
/* 66 */ KEY_F9, /* F9 */
|
||||||
|
/* 67 */ KEY_F10, /* F10 */
|
||||||
|
/* 68 */ KEY_F11, /* F11 */
|
||||||
|
/* 69 */ KEY_F12, /* F12 */
|
||||||
|
/* 70 */ KEY_Print, /* PrintScrn SysReq */
|
||||||
|
/* 71 */ KEY_ScrollLock, /* Scroll Lock */
|
||||||
|
/* 72 */ KEY_Pause, /* Pause Break */
|
||||||
|
/* 73 */ KEY_Insert, /* Insert XXX Help on some Mac Keyboards */
|
||||||
|
/* 74 */ KEY_Home, /* Home */
|
||||||
|
/* 75 */ KEY_PgUp, /* Page Up */
|
||||||
|
/* 76 */ KEY_Delete, /* Delete */
|
||||||
|
/* 77 */ KEY_End, /* End */
|
||||||
|
/* 78 */ KEY_PgDown, /* Page Down */
|
||||||
|
/* 79 */ KEY_Right, /* Right Arrow */
|
||||||
|
/* 80 */ KEY_Left, /* Left Arrow */
|
||||||
|
/* 81 */ KEY_Down, /* Down Arrow */
|
||||||
|
/* 82 */ KEY_Up, /* Up Arrow */
|
||||||
|
/* 83 */ KEY_NumLock, /* Num Lock */
|
||||||
|
/* 84 */ KEY_KP_Divide, /* Keypad / */
|
||||||
|
/* 85 */ KEY_KP_Multiply, /* Keypad * */
|
||||||
|
/* 86 */ KEY_KP_Minus, /* Keypad - */
|
||||||
|
/* 87 */ KEY_KP_Plus, /* Keypad + */
|
||||||
|
/* 88 */ KEY_KP_Enter, /* Keypad Enter */
|
||||||
|
/* 89 */ KEY_KP_1, /* Keypad 1 End */
|
||||||
|
/* 90 */ KEY_KP_2, /* Keypad 2 Down */
|
||||||
|
/* 91 */ KEY_KP_3, /* Keypad 3 Pg Down */
|
||||||
|
/* 92 */ KEY_KP_4, /* Keypad 4 Left */
|
||||||
|
/* 93 */ KEY_KP_5, /* Keypad 5 */
|
||||||
|
/* 94 */ KEY_KP_6, /* Keypad 6 */
|
||||||
|
/* 95 */ KEY_KP_7, /* Keypad 7 Home */
|
||||||
|
/* 96 */ KEY_KP_8, /* Keypad 8 Up */
|
||||||
|
/* 97 */ KEY_KP_9, /* KEypad 9 Pg Up */
|
||||||
|
/* 98 */ KEY_KP_0, /* Keypad 0 Ins */
|
||||||
|
/* 99 */ KEY_KP_Decimal, /* Keypad . Del */
|
||||||
|
/* 100 */ KEY_Less, /* < > on some keyboards */
|
||||||
|
/* 101 */ KEY_Menu, /* Menu */
|
||||||
|
/* 102 */ KEY_Power, /* sleep key on Sun USB */
|
||||||
|
/* 103 */ KEY_KP_Equal, /* Keypad = on Mac keyboards */
|
||||||
|
/* 104 */ KEY_F13,
|
||||||
|
/* 105 */ KEY_F14,
|
||||||
|
/* 106 */ KEY_F15,
|
||||||
|
/* 107 */ KEY_F16,
|
||||||
|
/* 108 */ KEY_NOTUSED,
|
||||||
|
/* 109 */ KEY_Power,
|
||||||
|
/* 110 */ KEY_NOTUSED,
|
||||||
|
/* 111 */ KEY_NOTUSED,
|
||||||
|
/* 112 */ KEY_NOTUSED,
|
||||||
|
/* 113 */ KEY_NOTUSED,
|
||||||
|
/* 114 */ KEY_NOTUSED,
|
||||||
|
/* 115 */ KEY_NOTUSED,
|
||||||
|
/* 116 */ KEY_L7,
|
||||||
|
/* 117 */ KEY_Help,
|
||||||
|
/* 118 */ KEY_L3,
|
||||||
|
/* 119 */ KEY_L5,
|
||||||
|
/* 120 */ KEY_L1,
|
||||||
|
/* 121 */ KEY_L2,
|
||||||
|
/* 122 */ KEY_L4,
|
||||||
|
/* 123 */ KEY_L10,
|
||||||
|
/* 124 */ KEY_L6,
|
||||||
|
/* 125 */ KEY_L8,
|
||||||
|
/* 126 */ KEY_L9,
|
||||||
|
/* 127 */ KEY_Mute,
|
||||||
|
/* 128 */ KEY_AudioRaise,
|
||||||
|
/* 129 */ KEY_AudioLower,
|
||||||
|
/* 130 */ KEY_NOTUSED,
|
||||||
|
/* 131 */ KEY_NOTUSED,
|
||||||
|
/* 132 */ KEY_NOTUSED,
|
||||||
|
/* 133 */ KEY_NOTUSED,
|
||||||
|
/* 134 */ KEY_NOTUSED,
|
||||||
|
/*
|
||||||
|
* Special keycodes for Japanese keyboards
|
||||||
|
* Override atKeyname HKTG and BSlash2 code to unique values for JP106 keyboards
|
||||||
|
*/
|
||||||
|
#undef KEY_HKTG
|
||||||
|
#define KEY_HKTG 200 /* Japanese Hiragana Katakana Toggle */
|
||||||
|
#undef KEY_BSlash2
|
||||||
|
#define KEY_BSlash2 203 /* Japanese '\_' key */
|
||||||
|
|
||||||
|
/* 135 */ KEY_BSlash2, /* Japanese 106 kbd: '\_' */
|
||||||
|
/* 136 */ KEY_HKTG, /* Japanese 106 kbd: Hiragana Katakana toggle */
|
||||||
|
/* 137 */ KEY_Yen, /* Japanese 106 kbd: '\|' */
|
||||||
|
/* 138 */ KEY_XFER, /* Japanese 106 kbd: Henkan */
|
||||||
|
/* 139 */ KEY_NFER, /* Japanese 106 kbd: Muhenkan */
|
||||||
|
/* 140 */ KEY_NOTUSED,
|
||||||
|
/* 141 */ KEY_NOTUSED,
|
||||||
|
/* 142 */ KEY_NOTUSED,
|
||||||
|
/* 143 */ KEY_NOTUSED,
|
||||||
|
/*
|
||||||
|
* Special keycodes for Korean keyboards
|
||||||
|
* Define Hangul and Hangul_Hanja unique key codes
|
||||||
|
* These keys also use KANA and EISU on some Macintosh Japanese USB keyboards
|
||||||
|
*/
|
||||||
|
#define KEY_Hangul 201 /* Also KANA Key on Mac JP USB kbd */
|
||||||
|
#define KEY_Hangul_Hanja 202 /* Also EISU Key on Mac JP USB kbd */
|
||||||
|
/* 144 */ KEY_Hangul, /* Korean 106 kbd: Hangul */
|
||||||
|
/* 145 */ KEY_Hangul_Hanja, /* Korean 106 kbd: Hangul Hanja */
|
||||||
|
/* 146 */ KEY_NOTUSED,
|
||||||
|
/* 147 */ KEY_NOTUSED,
|
||||||
|
/* 148 */ KEY_NOTUSED,
|
||||||
|
/* 149 */ KEY_NOTUSED,
|
||||||
|
/* 150 */ KEY_NOTUSED,
|
||||||
|
/* 151 */ KEY_NOTUSED,
|
||||||
|
/* 152 */ KEY_NOTUSED,
|
||||||
|
/* 153 */ KEY_NOTUSED,
|
||||||
|
/* 154 */ KEY_NOTUSED,
|
||||||
|
/* 155 */ KEY_NOTUSED,
|
||||||
|
/* 156 */ KEY_NOTUSED,
|
||||||
|
/* 157 */ KEY_NOTUSED,
|
||||||
|
/* 158 */ KEY_NOTUSED,
|
||||||
|
/* 159 */ KEY_NOTUSED,
|
||||||
|
/* 160 */ KEY_NOTUSED,
|
||||||
|
/* 161 */ KEY_NOTUSED,
|
||||||
|
/* 162 */ KEY_NOTUSED,
|
||||||
|
/* 163 */ KEY_NOTUSED,
|
||||||
|
/* 164 */ KEY_NOTUSED,
|
||||||
|
/* 165 */ KEY_NOTUSED,
|
||||||
|
/* 166 */ KEY_NOTUSED,
|
||||||
|
/* 167 */ KEY_NOTUSED,
|
||||||
|
/* 168 */ KEY_NOTUSED,
|
||||||
|
/* 169 */ KEY_NOTUSED,
|
||||||
|
/* 170 */ KEY_NOTUSED,
|
||||||
|
/* 171 */ KEY_NOTUSED,
|
||||||
|
/* 172 */ KEY_NOTUSED,
|
||||||
|
/* 173 */ KEY_NOTUSED,
|
||||||
|
/* 174 */ KEY_NOTUSED,
|
||||||
|
/* 175 */ KEY_NOTUSED,
|
||||||
|
/* 176 */ KEY_NOTUSED,
|
||||||
|
/* 177 */ KEY_NOTUSED,
|
||||||
|
/* 178 */ KEY_NOTUSED,
|
||||||
|
/* 179 */ KEY_NOTUSED,
|
||||||
|
/* 180 */ KEY_NOTUSED,
|
||||||
|
/* 181 */ KEY_NOTUSED,
|
||||||
|
/* 182 */ KEY_NOTUSED,
|
||||||
|
/* 183 */ KEY_NOTUSED,
|
||||||
|
/* 184 */ KEY_NOTUSED,
|
||||||
|
/* 185 */ KEY_NOTUSED,
|
||||||
|
/* 186 */ KEY_NOTUSED,
|
||||||
|
/* 187 */ KEY_NOTUSED,
|
||||||
|
/* 188 */ KEY_NOTUSED,
|
||||||
|
/* 189 */ KEY_NOTUSED,
|
||||||
|
/* 190 */ KEY_NOTUSED,
|
||||||
|
/* 191 */ KEY_NOTUSED,
|
||||||
|
/* 192 */ KEY_NOTUSED,
|
||||||
|
/* 193 */ KEY_NOTUSED,
|
||||||
|
/* 194 */ KEY_NOTUSED,
|
||||||
|
/* 195 */ KEY_NOTUSED,
|
||||||
|
/* 196 */ KEY_NOTUSED,
|
||||||
|
/* 197 */ KEY_NOTUSED,
|
||||||
|
/* 198 */ KEY_NOTUSED,
|
||||||
|
/* 199 */ KEY_NOTUSED,
|
||||||
|
/* 200 */ KEY_NOTUSED,
|
||||||
|
/* 201 */ KEY_NOTUSED,
|
||||||
|
/* 202 */ KEY_NOTUSED,
|
||||||
|
/* 203 */ KEY_NOTUSED,
|
||||||
|
/* 204 */ KEY_NOTUSED,
|
||||||
|
/* 205 */ KEY_NOTUSED,
|
||||||
|
/* 206 */ KEY_NOTUSED,
|
||||||
|
/* 207 */ KEY_NOTUSED,
|
||||||
|
/* 208 */ KEY_NOTUSED,
|
||||||
|
/* 209 */ KEY_NOTUSED,
|
||||||
|
/* 210 */ KEY_NOTUSED,
|
||||||
|
/* 211 */ KEY_NOTUSED,
|
||||||
|
/* 212 */ KEY_NOTUSED,
|
||||||
|
/* 213 */ KEY_NOTUSED,
|
||||||
|
/* 214 */ KEY_NOTUSED,
|
||||||
|
/* 215 */ KEY_NOTUSED,
|
||||||
|
/* 216 */ KEY_NOTUSED,
|
||||||
|
/* 217 */ KEY_NOTUSED,
|
||||||
|
/* 218 */ KEY_NOTUSED,
|
||||||
|
/* 219 */ KEY_NOTUSED,
|
||||||
|
/* 220 */ KEY_NOTUSED,
|
||||||
|
/* 221 */ KEY_NOTUSED,
|
||||||
|
/* 222 */ KEY_NOTUSED,
|
||||||
|
/* 223 */ KEY_NOTUSED,
|
||||||
|
/* 224 */ KEY_LCtrl, /* Left Control */
|
||||||
|
/* 225 */ KEY_ShiftL, /* Left Shift */
|
||||||
|
/* 226 */ KEY_Alt, /* Left Alt */
|
||||||
|
/* 227 */ KEY_LMeta, /* Left Meta */
|
||||||
|
/* 228 */ KEY_RCtrl, /* Right Control */
|
||||||
|
/* 229 */ KEY_ShiftR, /* Right Shift */
|
||||||
|
/* 230 */ KEY_AltLang, /* Right Alt, AKA AltGr */
|
||||||
|
/* 231 */ KEY_LMeta, /* Right Meta XXX */
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t wsXtMap[] = {
|
||||||
|
/* 0 */ KEY_NOTUSED,
|
||||||
|
/* 1 */ KEY_Escape,
|
||||||
|
/* 2 */ KEY_1,
|
||||||
|
/* 3 */ KEY_2,
|
||||||
|
/* 4 */ KEY_3,
|
||||||
|
/* 5 */ KEY_4,
|
||||||
|
/* 6 */ KEY_5,
|
||||||
|
/* 7 */ KEY_6,
|
||||||
|
/* 8 */ KEY_7,
|
||||||
|
/* 9 */ KEY_8,
|
||||||
|
/* 10 */ KEY_9,
|
||||||
|
/* 11 */ KEY_0,
|
||||||
|
/* 12 */ KEY_Minus,
|
||||||
|
/* 13 */ KEY_Equal,
|
||||||
|
/* 14 */ KEY_BackSpace,
|
||||||
|
/* 15 */ KEY_Tab,
|
||||||
|
/* 16 */ KEY_Q,
|
||||||
|
/* 17 */ KEY_W,
|
||||||
|
/* 18 */ KEY_E,
|
||||||
|
/* 19 */ KEY_R,
|
||||||
|
/* 20 */ KEY_T,
|
||||||
|
/* 21 */ KEY_Y,
|
||||||
|
/* 22 */ KEY_U,
|
||||||
|
/* 23 */ KEY_I,
|
||||||
|
/* 24 */ KEY_O,
|
||||||
|
/* 25 */ KEY_P,
|
||||||
|
/* 26 */ KEY_LBrace,
|
||||||
|
/* 27 */ KEY_RBrace,
|
||||||
|
/* 28 */ KEY_Enter,
|
||||||
|
/* 29 */ KEY_LCtrl,
|
||||||
|
/* 30 */ KEY_A,
|
||||||
|
/* 31 */ KEY_S,
|
||||||
|
/* 32 */ KEY_D,
|
||||||
|
/* 33 */ KEY_F,
|
||||||
|
/* 34 */ KEY_G,
|
||||||
|
/* 35 */ KEY_H,
|
||||||
|
/* 36 */ KEY_J,
|
||||||
|
/* 37 */ KEY_K,
|
||||||
|
/* 38 */ KEY_L,
|
||||||
|
/* 39 */ KEY_SemiColon,
|
||||||
|
/* 40 */ KEY_Quote,
|
||||||
|
/* 41 */ KEY_Tilde,
|
||||||
|
/* 42 */ KEY_ShiftL,
|
||||||
|
/* 43 */ KEY_BSlash,
|
||||||
|
/* 44 */ KEY_Z,
|
||||||
|
/* 45 */ KEY_X,
|
||||||
|
/* 46 */ KEY_C,
|
||||||
|
/* 47 */ KEY_V,
|
||||||
|
/* 48 */ KEY_B,
|
||||||
|
/* 49 */ KEY_N,
|
||||||
|
/* 50 */ KEY_M,
|
||||||
|
/* 51 */ KEY_Comma,
|
||||||
|
/* 52 */ KEY_Period,
|
||||||
|
/* 53 */ KEY_Slash,
|
||||||
|
/* 54 */ KEY_ShiftR,
|
||||||
|
/* 55 */ KEY_KP_Multiply,
|
||||||
|
/* 56 */ KEY_Alt,
|
||||||
|
/* 57 */ KEY_Space,
|
||||||
|
/* 58 */ KEY_CapsLock,
|
||||||
|
/* 59 */ KEY_F1,
|
||||||
|
/* 60 */ KEY_F2,
|
||||||
|
/* 61 */ KEY_F3,
|
||||||
|
/* 62 */ KEY_F4,
|
||||||
|
/* 63 */ KEY_F5,
|
||||||
|
/* 64 */ KEY_F6,
|
||||||
|
/* 65 */ KEY_F7,
|
||||||
|
/* 66 */ KEY_F8,
|
||||||
|
/* 67 */ KEY_F9,
|
||||||
|
/* 68 */ KEY_F10,
|
||||||
|
/* 69 */ KEY_NumLock,
|
||||||
|
/* 70 */ KEY_ScrollLock,
|
||||||
|
/* 71 */ KEY_KP_7,
|
||||||
|
/* 72 */ KEY_KP_8,
|
||||||
|
/* 73 */ KEY_KP_9,
|
||||||
|
/* 74 */ KEY_KP_Minus,
|
||||||
|
/* 75 */ KEY_KP_4,
|
||||||
|
/* 76 */ KEY_KP_5,
|
||||||
|
/* 77 */ KEY_KP_6,
|
||||||
|
/* 78 */ KEY_KP_Plus,
|
||||||
|
/* 79 */ KEY_KP_1,
|
||||||
|
/* 80 */ KEY_KP_2,
|
||||||
|
/* 81 */ KEY_KP_3,
|
||||||
|
/* 82 */ KEY_KP_0,
|
||||||
|
/* 83 */ KEY_KP_Decimal,
|
||||||
|
/* 84 */ KEY_NOTUSED,
|
||||||
|
/* 85 */ KEY_NOTUSED,
|
||||||
|
/* 86 */ KEY_Less, /* backslash on uk, < on german */
|
||||||
|
/* 87 */ KEY_F11,
|
||||||
|
/* 88 */ KEY_F12,
|
||||||
|
/* 89 */ KEY_NOTUSED,
|
||||||
|
/* 90 */ KEY_NOTUSED,
|
||||||
|
/* 91 */ KEY_NOTUSED,
|
||||||
|
/* 92 */ KEY_NOTUSED,
|
||||||
|
/* 93 */ KEY_NOTUSED,
|
||||||
|
/* 94 */ KEY_NOTUSED,
|
||||||
|
/* 95 */ KEY_NOTUSED,
|
||||||
|
/* 96 */ KEY_NOTUSED,
|
||||||
|
/* 97 */ KEY_NOTUSED,
|
||||||
|
/* 98 */ KEY_NOTUSED,
|
||||||
|
/* 99 */ KEY_NOTUSED,
|
||||||
|
/* 100 */ KEY_NOTUSED,
|
||||||
|
/* 101 */ KEY_NOTUSED,
|
||||||
|
/* 102 */ KEY_NOTUSED,
|
||||||
|
/* 103 */ KEY_NOTUSED,
|
||||||
|
/* 104 */ KEY_NOTUSED,
|
||||||
|
/* 105 */ KEY_NOTUSED,
|
||||||
|
/* 106 */ KEY_NOTUSED,
|
||||||
|
/* 107 */ KEY_NOTUSED,
|
||||||
|
/* 108 */ KEY_NOTUSED,
|
||||||
|
/* 109 */ KEY_NOTUSED,
|
||||||
|
/* 110 */ KEY_NOTUSED,
|
||||||
|
/* 111 */ KEY_NOTUSED,
|
||||||
|
/* 112 */ KEY_NOTUSED,
|
||||||
|
/* 113 */ KEY_NOTUSED,
|
||||||
|
/* 114 */ KEY_NOTUSED,
|
||||||
|
/* 115 */ KEY_NOTUSED,
|
||||||
|
/* 116 */ KEY_NOTUSED,
|
||||||
|
/* 117 */ KEY_NOTUSED,
|
||||||
|
/* 118 */ KEY_NOTUSED,
|
||||||
|
/* 119 */ KEY_NOTUSED,
|
||||||
|
/* 120 */ KEY_NOTUSED,
|
||||||
|
/* 121 */ KEY_NOTUSED,
|
||||||
|
/* 122 */ KEY_NOTUSED,
|
||||||
|
/* 123 */ KEY_NOTUSED,
|
||||||
|
/* 124 */ KEY_NOTUSED,
|
||||||
|
/* 125 */ KEY_NOTUSED,
|
||||||
|
/* 126 */ KEY_NOTUSED,
|
||||||
|
/* 127 */ KEY_Pause,
|
||||||
|
/* 128 */ KEY_NOTUSED,
|
||||||
|
/* 129 */ KEY_NOTUSED,
|
||||||
|
/* 130 */ KEY_NOTUSED,
|
||||||
|
/* 131 */ KEY_NOTUSED,
|
||||||
|
/* 132 */ KEY_NOTUSED,
|
||||||
|
/* 133 */ KEY_NOTUSED,
|
||||||
|
/* 134 */ KEY_NOTUSED,
|
||||||
|
/* 135 */ KEY_NOTUSED,
|
||||||
|
/* 136 */ KEY_NOTUSED,
|
||||||
|
/* 137 */ KEY_NOTUSED,
|
||||||
|
/* 138 */ KEY_NOTUSED,
|
||||||
|
/* 139 */ KEY_NOTUSED,
|
||||||
|
/* 140 */ KEY_NOTUSED,
|
||||||
|
/* 141 */ KEY_NOTUSED,
|
||||||
|
/* 142 */ KEY_NOTUSED,
|
||||||
|
/* 143 */ KEY_NOTUSED,
|
||||||
|
/* 144 */ KEY_NOTUSED,
|
||||||
|
/* 145 */ KEY_NOTUSED,
|
||||||
|
/* 146 */ KEY_NOTUSED,
|
||||||
|
/* 147 */ KEY_NOTUSED,
|
||||||
|
/* 148 */ KEY_NOTUSED,
|
||||||
|
/* 149 */ KEY_NOTUSED,
|
||||||
|
/* 150 */ KEY_NOTUSED,
|
||||||
|
/* 151 */ KEY_NOTUSED,
|
||||||
|
/* 152 */ KEY_NOTUSED,
|
||||||
|
/* 153 */ KEY_NOTUSED,
|
||||||
|
/* 154 */ KEY_NOTUSED,
|
||||||
|
/* 155 */ KEY_NOTUSED,
|
||||||
|
/* 156 */ KEY_KP_Enter,
|
||||||
|
/* 157 */ KEY_RCtrl,
|
||||||
|
/* 158 */ KEY_NOTUSED,
|
||||||
|
/* 159 */ KEY_NOTUSED,
|
||||||
|
/* 160 */ KEY_Mute,
|
||||||
|
/* 161 */ KEY_NOTUSED,
|
||||||
|
/* 162 */ KEY_NOTUSED,
|
||||||
|
/* 163 */ KEY_NOTUSED,
|
||||||
|
/* 164 */ KEY_NOTUSED,
|
||||||
|
/* 165 */ KEY_NOTUSED,
|
||||||
|
/* 166 */ KEY_NOTUSED,
|
||||||
|
/* 167 */ KEY_NOTUSED,
|
||||||
|
/* 168 */ KEY_NOTUSED,
|
||||||
|
/* 169 */ KEY_NOTUSED,
|
||||||
|
/* 170 */ KEY_Print,
|
||||||
|
/* 171 */ KEY_NOTUSED,
|
||||||
|
/* 172 */ KEY_NOTUSED,
|
||||||
|
/* 173 */ KEY_NOTUSED,
|
||||||
|
/* 174 */ KEY_AudioLower,
|
||||||
|
/* 175 */ KEY_AudioRaise,
|
||||||
|
/* 176 */ KEY_NOTUSED,
|
||||||
|
/* 177 */ KEY_NOTUSED,
|
||||||
|
/* 178 */ KEY_NOTUSED,
|
||||||
|
/* 179 */ KEY_NOTUSED,
|
||||||
|
/* 180 */ KEY_NOTUSED,
|
||||||
|
/* 181 */ KEY_KP_Divide,
|
||||||
|
/* 182 */ KEY_NOTUSED,
|
||||||
|
/* 183 */ KEY_Print,
|
||||||
|
/* 184 */ KEY_AltLang,
|
||||||
|
/* 185 */ KEY_NOTUSED,
|
||||||
|
/* 186 */ KEY_NOTUSED,
|
||||||
|
/* 187 */ KEY_NOTUSED,
|
||||||
|
/* 188 */ KEY_NOTUSED,
|
||||||
|
/* 189 */ KEY_NOTUSED,
|
||||||
|
/* 190 */ KEY_NOTUSED,
|
||||||
|
/* 191 */ KEY_NOTUSED,
|
||||||
|
/* 192 */ KEY_NOTUSED,
|
||||||
|
/* 193 */ KEY_NOTUSED,
|
||||||
|
/* 194 */ KEY_NOTUSED,
|
||||||
|
/* 195 */ KEY_NOTUSED,
|
||||||
|
/* 196 */ KEY_NOTUSED,
|
||||||
|
/* 197 */ KEY_NOTUSED,
|
||||||
|
/* 198 */ KEY_NOTUSED,
|
||||||
|
/* 199 */ KEY_Home,
|
||||||
|
/* 200 */ KEY_Up,
|
||||||
|
/* 201 */ KEY_PgUp,
|
||||||
|
/* 202 */ KEY_NOTUSED,
|
||||||
|
/* 203 */ KEY_Left,
|
||||||
|
/* 204 */ KEY_NOTUSED,
|
||||||
|
/* 205 */ KEY_Right,
|
||||||
|
/* 206 */ KEY_NOTUSED,
|
||||||
|
/* 207 */ KEY_End,
|
||||||
|
/* 208 */ KEY_Down,
|
||||||
|
/* 209 */ KEY_PgDown,
|
||||||
|
/* 210 */ KEY_Insert,
|
||||||
|
/* 211 */ KEY_Delete,
|
||||||
|
/* 212 */ KEY_NOTUSED,
|
||||||
|
/* 213 */ KEY_NOTUSED,
|
||||||
|
/* 214 */ KEY_NOTUSED,
|
||||||
|
/* 215 */ KEY_NOTUSED,
|
||||||
|
/* 216 */ KEY_NOTUSED,
|
||||||
|
/* 217 */ KEY_NOTUSED,
|
||||||
|
/* 218 */ KEY_NOTUSED,
|
||||||
|
/* 219 */ KEY_LMeta,
|
||||||
|
/* 220 */ KEY_RMeta,
|
||||||
|
/* 221 */ KEY_Menu,
|
||||||
|
};
|
||||||
9
backend/wscons/meson.build
Normal file
9
backend/wscons/meson.build
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
platform = target_machine.system()
|
||||||
|
if platform != 'openbsd'
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
|
||||||
|
wlr_files += files('atKeynames.h')
|
||||||
|
wlr_files += files('bsd_KbdMap.h')
|
||||||
|
wlr_files += files('backend.c')
|
||||||
|
features += { 'wscons-backend': true }
|
||||||
|
|
@ -2,6 +2,31 @@
|
||||||
#define BACKEND_SESSION_SESSION_H
|
#define BACKEND_SESSION_SESSION_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
|
||||||
|
// for some reason libdrm does not define MAX3, but has defs that depend on it
|
||||||
|
#define MAX3(a, b, c) ((a) > (b) && (a) > (c) ? (a) : \
|
||||||
|
(b) > (c) ? (b) : (c))
|
||||||
|
|
||||||
|
struct drm_event_monitor;
|
||||||
|
|
||||||
|
enum drm_event_action {
|
||||||
|
DRM_EVENT_ACTION_NONE,
|
||||||
|
DRM_EVENT_ACTION_ADD,
|
||||||
|
DRM_EVENT_ACTION_CHANGE,
|
||||||
|
DRM_EVENT_ACTION_REMOVE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_event_content {
|
||||||
|
char devnode[DRM_NODE_NAME_MAX];
|
||||||
|
dev_t devnum;
|
||||||
|
enum drm_event_action type;
|
||||||
|
int16_t conn_id;
|
||||||
|
int16_t prop_id;
|
||||||
|
bool has_lease;
|
||||||
|
};
|
||||||
|
|
||||||
struct wl_display;
|
struct wl_display;
|
||||||
struct wlr_session;
|
struct wlr_session;
|
||||||
|
|
@ -17,4 +42,13 @@ void session_init(struct wlr_session *session);
|
||||||
struct wlr_device *session_open_if_kms(struct wlr_session *session,
|
struct wlr_device *session_open_if_kms(struct wlr_session *session,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|
||||||
|
struct drm_event_monitor *monitor_drm_events(int *fd);
|
||||||
|
void drm_event_monitor_free(struct drm_event_monitor *ctx);
|
||||||
|
|
||||||
|
int receive_drm_device(struct drm_event_monitor *ctx,
|
||||||
|
struct drm_event_content *ev);
|
||||||
|
|
||||||
|
const char *get_device_seat(struct drm_event_monitor *ctx, const char *devnode);
|
||||||
|
bool is_drm_device_primary(struct drm_event_monitor *ctx, const char *devnode);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
32
include/backend/wscons.h
Normal file
32
include/backend/wscons.h
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef BACKEND_WSCONS_H
|
||||||
|
#define BACKEND_WSCONS_H
|
||||||
|
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
#include <wlr/backend/interface.h>
|
||||||
|
#include <wlr/backend/wscons.h>
|
||||||
|
#include <wlr/types/wlr_keyboard.h>
|
||||||
|
#include <wlr/types/wlr_pointer.h>
|
||||||
|
#include <wlr/backend/session.h>
|
||||||
|
|
||||||
|
struct wlr_wscons_backend {
|
||||||
|
struct wlr_backend backend;
|
||||||
|
|
||||||
|
struct wlr_device *mouse_dev;
|
||||||
|
struct wlr_device *kbd_dev;
|
||||||
|
|
||||||
|
struct wlr_keyboard kbd;
|
||||||
|
struct wlr_pointer mouse;
|
||||||
|
|
||||||
|
unsigned kbd_type;
|
||||||
|
int kqueue_fd;
|
||||||
|
|
||||||
|
struct wlr_session *session;
|
||||||
|
|
||||||
|
struct wl_event_source *input_event;
|
||||||
|
struct wl_listener session_destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct wlr_keyboard_impl wscons_keyboard_impl;
|
||||||
|
extern const struct wlr_pointer_impl wscons_pointer_impl;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -23,6 +23,9 @@ endif
|
||||||
if not features.get('session')
|
if not features.get('session')
|
||||||
exclude_files += 'backend/session.h'
|
exclude_files += 'backend/session.h'
|
||||||
endif
|
endif
|
||||||
|
if not features.get('wscons-backend')
|
||||||
|
exclude_files += 'backend/wscons.h'
|
||||||
|
endif
|
||||||
|
|
||||||
install_subdir('wlr',
|
install_subdir('wlr',
|
||||||
install_dir: get_option('includedir') / versioned_name,
|
install_dir: get_option('includedir') / versioned_name,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
struct libseat;
|
struct libseat;
|
||||||
|
struct drm_event_monitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An opened physical device.
|
* An opened physical device.
|
||||||
|
|
@ -45,9 +46,8 @@ struct wlr_session {
|
||||||
|
|
||||||
char seat[256];
|
char seat[256];
|
||||||
|
|
||||||
struct udev *udev;
|
struct drm_event_monitor *drm_handle;
|
||||||
struct udev_monitor *mon;
|
struct wl_event_source *drm_event;
|
||||||
struct wl_event_source *udev_event;
|
|
||||||
|
|
||||||
struct libseat *seat_handle;
|
struct libseat *seat_handle;
|
||||||
struct wl_event_source *libseat_event;
|
struct wl_event_source *libseat_event;
|
||||||
|
|
|
||||||
23
include/wlr/backend/wscons.h
Normal file
23
include/wlr/backend/wscons.h
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* This an unstable interface of wlroots. No guarantees are made regarding the
|
||||||
|
* future consistency of this API.
|
||||||
|
*/
|
||||||
|
#ifndef WLR_USE_UNSTABLE
|
||||||
|
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WLR_BACKEND_WSCONS_H
|
||||||
|
#define WLR_BACKEND_WSCONS_H
|
||||||
|
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
#include <wlr/backend.h>
|
||||||
|
#include <wlr/backend/session.h>
|
||||||
|
|
||||||
|
struct wlr_input_device;
|
||||||
|
|
||||||
|
struct wlr_backend *wlr_wscons_backend_create(struct wlr_session *session);
|
||||||
|
|
||||||
|
bool wlr_backend_is_wscons(const struct wlr_backend *backend);
|
||||||
|
bool wlr_input_device_is_wscons(struct wlr_input_device *device);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -15,6 +15,13 @@
|
||||||
* Required for <wlr/backend/libinput.h>.
|
* Required for <wlr/backend/libinput.h>.
|
||||||
*/
|
*/
|
||||||
#mesondefine WLR_HAS_LIBINPUT_BACKEND
|
#mesondefine WLR_HAS_LIBINPUT_BACKEND
|
||||||
|
/**
|
||||||
|
* Whether the wscons backend is compile-time enabled. Equivalent to the
|
||||||
|
* pkg-config "have_wscons_backend" vartiable.
|
||||||
|
*
|
||||||
|
* Required for <wlr/backend/wscons.h>.
|
||||||
|
*/
|
||||||
|
#mesondefine WLR_HAS_WSCONS_BACKEND
|
||||||
/**
|
/**
|
||||||
* Whether the X11 backend is compile-time enabled. Equivalent to the
|
* Whether the X11 backend is compile-time enabled. Equivalent to the
|
||||||
* pkg-config "have_x11_backend" variable.
|
* pkg-config "have_x11_backend" variable.
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ features = {
|
||||||
'drm-backend': false,
|
'drm-backend': false,
|
||||||
'x11-backend': false,
|
'x11-backend': false,
|
||||||
'libinput-backend': false,
|
'libinput-backend': false,
|
||||||
|
'wscons-backend': false,
|
||||||
'xwayland': false,
|
'xwayland': false,
|
||||||
'gles2-renderer': false,
|
'gles2-renderer': false,
|
||||||
'vulkan-renderer': false,
|
'vulkan-renderer': false,
|
||||||
|
|
@ -121,7 +122,12 @@ pixman = dependency('pixman-1',
|
||||||
default_options: ['werror=false'],
|
default_options: ['werror=false'],
|
||||||
)
|
)
|
||||||
math = cc.find_library('m')
|
math = cc.find_library('m')
|
||||||
rt = cc.find_library('rt')
|
platform = target_machine.system()
|
||||||
|
if platform == 'openbsd'
|
||||||
|
rt = dependency('', required: false)
|
||||||
|
else
|
||||||
|
rt = cc.find_library('rt')
|
||||||
|
endif
|
||||||
|
|
||||||
wlr_files = []
|
wlr_files = []
|
||||||
wlr_deps = [
|
wlr_deps = [
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ option('xwayland', type: 'feature', value: 'auto', yield: true, description: 'En
|
||||||
option('examples', type: 'boolean', value: true, description: 'Build example applications')
|
option('examples', type: 'boolean', value: true, description: 'Build example applications')
|
||||||
option('icon_directory', description: 'Location used to look for cursors (default: ${datadir}/icons)', type: 'string', value: '')
|
option('icon_directory', description: 'Location used to look for cursors (default: ${datadir}/icons)', type: 'string', value: '')
|
||||||
option('renderers', type: 'array', choices: ['auto', 'gles2', 'vulkan'], value: ['auto'], description: 'Select built-in renderers')
|
option('renderers', type: 'array', choices: ['auto', 'gles2', 'vulkan'], value: ['auto'], description: 'Select built-in renderers')
|
||||||
option('backends', type: 'array', choices: ['auto', 'drm', 'libinput', 'x11'], value: ['auto'], description: 'Select built-in backends')
|
option('backends', type: 'array', choices: ['auto', 'drm', 'libinput', 'x11', 'wscons'], value: ['auto'], description: 'Select built-in backends')
|
||||||
option('allocators', type: 'array', choices: ['auto', 'gbm', 'udmabuf'], value: ['auto'],
|
option('allocators', type: 'array', choices: ['auto', 'gbm', 'udmabuf'], value: ['auto'],
|
||||||
description: 'Select built-in allocators')
|
description: 'Select built-in allocators')
|
||||||
option('session', type: 'feature', value: 'auto', description: 'Enable session support')
|
option('session', type: 'feature', value: 'auto', description: 'Enable session support')
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ static int reopen_drm_node(int drm_fd, bool allow_render_node) {
|
||||||
int lease_fd = drmModeCreateLease(drm_fd, NULL, 0, O_CLOEXEC, &lessee_id);
|
int lease_fd = drmModeCreateLease(drm_fd, NULL, 0, O_CLOEXEC, &lessee_id);
|
||||||
if (lease_fd >= 0) {
|
if (lease_fd >= 0) {
|
||||||
return lease_fd;
|
return lease_fd;
|
||||||
} else if (lease_fd != -EINVAL && lease_fd != -EOPNOTSUPP) {
|
} else if (lease_fd != -EINVAL && lease_fd != -EOPNOTSUPP && lease_fd != -ENODEV) {
|
||||||
wlr_log_errno(WLR_ERROR, "drmModeCreateLease failed");
|
wlr_log_errno(WLR_ERROR, "drmModeCreateLease failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ out:
|
||||||
bool wlr_drm_syncobj_timeline_check(struct wlr_drm_syncobj_timeline *timeline,
|
bool wlr_drm_syncobj_timeline_check(struct wlr_drm_syncobj_timeline *timeline,
|
||||||
uint64_t point, uint32_t flags, bool *result) {
|
uint64_t point, uint32_t flags, bool *result) {
|
||||||
int etime;
|
int etime;
|
||||||
#if defined(__FreeBSD__)
|
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
etime = ETIMEDOUT;
|
etime = ETIMEDOUT;
|
||||||
#else
|
#else
|
||||||
etime = ETIME;
|
etime = ETIME;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <linux/input-event-codes.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
@ -323,6 +322,10 @@ bool wlr_keyboard_keymaps_match(struct xkb_keymap *km1,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BTN_LEFT 0x110
|
||||||
|
#define BTN_RIGHT 0x111
|
||||||
|
#define BTN_MIDDLE 0x112
|
||||||
|
|
||||||
uint32_t wlr_keyboard_keysym_to_pointer_button(xkb_keysym_t keysym) {
|
uint32_t wlr_keyboard_keysym_to_pointer_button(xkb_keysym_t keysym) {
|
||||||
switch (keysym) {
|
switch (keysym) {
|
||||||
case XKB_KEY_Pointer_Button1:
|
case XKB_KEY_Pointer_Button1:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#define _XOPEN_SOURCE 700
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue