mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-03 07:17:06 -04:00
Compare commits
44 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88a8698557 | ||
|
|
2bc71d19d4 | ||
|
|
8c4a74717f | ||
|
|
6fee18f373 | ||
|
|
a34411c2fe | ||
|
|
f7e7d8f183 | ||
|
|
004806fae2 | ||
|
|
4080e2f627 | ||
|
|
d834de6167 | ||
|
|
0f9a1f1443 | ||
|
|
0280a03136 | ||
|
|
29bba098bd | ||
|
|
31dc115b9f | ||
|
|
11f5ba8bf2 | ||
|
|
b858230394 | ||
|
|
b08af09626 | ||
|
|
4279ee5091 | ||
|
|
aabe351207 | ||
|
|
878aebfb74 | ||
|
|
8c9e6b7c9f | ||
|
|
e432b7bd1c | ||
|
|
ea1ade5e5d | ||
|
|
f56a69aa76 | ||
|
|
8fc64ae8d5 | ||
|
|
761927bbbd | ||
|
|
0d20e46498 | ||
|
|
eba71d59d4 | ||
|
|
9b42c1901d | ||
|
|
7a52788929 | ||
|
|
d4009183a1 | ||
|
|
d092e40dec | ||
|
|
bb5180ce9e | ||
|
|
73aa61686f | ||
|
|
9079380498 | ||
|
|
3118ca5c3e | ||
|
|
c1938f79c3 | ||
|
|
aa904ccf06 | ||
|
|
52e1ad01e3 | ||
|
|
30c0602457 | ||
|
|
b7205866c0 | ||
|
|
f935404e68 | ||
|
|
5aa8c192a5 | ||
|
|
68dea55970 | ||
|
|
f3fe6b9a43 |
40 changed files with 463 additions and 262 deletions
|
|
@ -41,9 +41,10 @@ tasks:
|
|||
cd wlroots/build-gcc/tinywl
|
||||
sudo modprobe vkms
|
||||
udevadm settle
|
||||
card="/dev/dri/$(ls /sys/devices/faux/vkms/drm/ | grep ^card)"
|
||||
export WLR_BACKENDS=drm
|
||||
export WLR_RENDERER=pixman
|
||||
export WLR_DRM_DEVICES=/dev/dri/by-path/platform-vkms-card
|
||||
export WLR_DRM_DEVICES="$card"
|
||||
export UBSAN_OPTIONS=halt_on_error=1
|
||||
sudo chmod ugo+rw /dev/dri/by-path/platform-vkms-card
|
||||
sudo chmod ugo+rw "$card"
|
||||
sudo -E seatd-launch -- ./tinywl -s 'kill $PPID' || [ $? = 143 ]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
include: https://git.sr.ht/~emersion/dalligi/blob/master/templates/multi.yml
|
||||
include: https://gitlab.freedesktop.org/emersion/dalligi/-/raw/master/templates/multi.yml
|
||||
alpine:
|
||||
extends: .dalligi
|
||||
pages: true
|
||||
|
|
|
|||
|
|
@ -485,5 +485,10 @@ bool wlr_backend_commit(struct wlr_backend *backend,
|
|||
output_apply_commit(state->output, &state->base);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < states_len; i++) {
|
||||
const struct wlr_backend_output_state *state = &states[i];
|
||||
output_send_commit_event(state->output, &state->base);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2085,6 +2085,7 @@ int wlr_drm_backend_get_non_master_fd(struct wlr_backend *backend) {
|
|||
|
||||
if (drmIsMaster(fd) && drmDropMaster(fd) < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to drop master");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -249,3 +249,15 @@ void handle_libinput_event(struct wlr_libinput_backend *backend,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool button_state_from_libinput(enum libinput_button_state state, enum wlr_button_state *out) {
|
||||
switch (state) {
|
||||
case LIBINPUT_BUTTON_STATE_RELEASED:
|
||||
*out = WLR_BUTTON_RELEASED;
|
||||
return true;
|
||||
case LIBINPUT_BUTTON_STATE_PRESSED:
|
||||
*out = WLR_BUTTON_PRESSED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <libinput.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/interfaces/wlr_keyboard.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/libinput.h"
|
||||
|
||||
struct wlr_libinput_input_device *device_from_keyboard(
|
||||
|
|
@ -30,6 +31,18 @@ void init_device_keyboard(struct wlr_libinput_input_device *dev) {
|
|||
libinput_device_led_update(dev->handle, 0);
|
||||
}
|
||||
|
||||
static bool key_state_from_libinput(enum libinput_key_state state, enum wl_keyboard_key_state *out) {
|
||||
switch (state) {
|
||||
case LIBINPUT_KEY_STATE_RELEASED:
|
||||
*out = WL_KEYBOARD_KEY_STATE_RELEASED;
|
||||
return true;
|
||||
case LIBINPUT_KEY_STATE_PRESSED:
|
||||
*out = WL_KEYBOARD_KEY_STATE_PRESSED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handle_keyboard_key(struct libinput_event *event,
|
||||
struct wlr_keyboard *kb) {
|
||||
struct libinput_event_keyboard *kbevent =
|
||||
|
|
@ -39,13 +52,9 @@ void handle_keyboard_key(struct libinput_event *event,
|
|||
.keycode = libinput_event_keyboard_get_key(kbevent),
|
||||
.update_state = true,
|
||||
};
|
||||
switch (libinput_event_keyboard_get_key_state(kbevent)) {
|
||||
case LIBINPUT_KEY_STATE_RELEASED:
|
||||
wlr_event.state = WL_KEYBOARD_KEY_STATE_RELEASED;
|
||||
break;
|
||||
case LIBINPUT_KEY_STATE_PRESSED:
|
||||
wlr_event.state = WL_KEYBOARD_KEY_STATE_PRESSED;
|
||||
break;
|
||||
if (!key_state_from_libinput(libinput_event_keyboard_get_key_state(kbevent), &wlr_event.state)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput key state");
|
||||
return;
|
||||
}
|
||||
wlr_keyboard_notify_key(kb, &wlr_event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,3 +29,7 @@ features += { 'libinput-backend': true }
|
|||
wlr_deps += libinput
|
||||
|
||||
internal_config.set10('HAVE_LIBINPUT_BUSTYPE', libinput.version().version_compare('>=1.26.0'))
|
||||
internal_config.set10(
|
||||
'HAVE_LIBINPUT_SWITCH_KEYPAD_SLIDE',
|
||||
libinput.version().version_compare('>=1.30.901')
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <assert.h>
|
||||
#include <libinput.h>
|
||||
#include <wlr/interfaces/wlr_pointer.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/libinput.h"
|
||||
|
||||
const struct wlr_pointer_impl libinput_pointer_impl = {
|
||||
|
|
@ -52,6 +53,38 @@ void handle_pointer_motion_abs(struct libinput_event *event,
|
|||
wl_signal_emit_mutable(&pointer->events.frame, pointer);
|
||||
}
|
||||
|
||||
static bool pointer_button_state_from_libinput(enum libinput_button_state state,
|
||||
enum wl_pointer_button_state *out) {
|
||||
switch (state) {
|
||||
case LIBINPUT_BUTTON_STATE_PRESSED:
|
||||
*out = WL_POINTER_BUTTON_STATE_PRESSED;
|
||||
return true;
|
||||
case LIBINPUT_BUTTON_STATE_RELEASED:
|
||||
*out = WL_POINTER_BUTTON_STATE_RELEASED;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool axis_source_from_libinput(enum libinput_pointer_axis_source source,
|
||||
enum wl_pointer_axis_source *out) {
|
||||
switch (source) {
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
|
||||
*out = WL_POINTER_AXIS_SOURCE_WHEEL;
|
||||
return true;
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
|
||||
*out = WL_POINTER_AXIS_SOURCE_FINGER;
|
||||
return true;
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
|
||||
*out = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
|
||||
return true;
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT:
|
||||
*out = WL_POINTER_AXIS_SOURCE_WHEEL_TILT;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handle_pointer_button(struct libinput_event *event,
|
||||
struct wlr_pointer *pointer) {
|
||||
struct libinput_event_pointer *pevent =
|
||||
|
|
@ -61,13 +94,10 @@ void handle_pointer_button(struct libinput_event *event,
|
|||
.time_msec = usec_to_msec(libinput_event_pointer_get_time_usec(pevent)),
|
||||
.button = libinput_event_pointer_get_button(pevent),
|
||||
};
|
||||
switch (libinput_event_pointer_get_button_state(pevent)) {
|
||||
case LIBINPUT_BUTTON_STATE_PRESSED:
|
||||
wlr_event.state = WL_POINTER_BUTTON_STATE_PRESSED;
|
||||
break;
|
||||
case LIBINPUT_BUTTON_STATE_RELEASED:
|
||||
wlr_event.state = WL_POINTER_BUTTON_STATE_RELEASED;
|
||||
break;
|
||||
if (!pointer_button_state_from_libinput(libinput_event_pointer_get_button_state(pevent),
|
||||
&wlr_event.state)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput button state");
|
||||
return;
|
||||
}
|
||||
wlr_pointer_notify_button(pointer, &wlr_event);
|
||||
wl_signal_emit_mutable(&pointer->events.frame, pointer);
|
||||
|
|
@ -81,19 +111,9 @@ void handle_pointer_axis(struct libinput_event *event,
|
|||
.pointer = pointer,
|
||||
.time_msec = usec_to_msec(libinput_event_pointer_get_time_usec(pevent)),
|
||||
};
|
||||
switch (libinput_event_pointer_get_axis_source(pevent)) {
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
|
||||
wlr_event.source = WL_POINTER_AXIS_SOURCE_WHEEL;
|
||||
break;
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
|
||||
wlr_event.source = WL_POINTER_AXIS_SOURCE_FINGER;
|
||||
break;
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
|
||||
wlr_event.source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
|
||||
break;
|
||||
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT:
|
||||
wlr_event.source = WL_POINTER_AXIS_SOURCE_WHEEL_TILT;
|
||||
break;
|
||||
if (!axis_source_from_libinput(libinput_event_pointer_get_axis_source(pevent), &wlr_event.source)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput pointer axis source");
|
||||
return;
|
||||
}
|
||||
const enum libinput_pointer_axis axes[] = {
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include <assert.h>
|
||||
#include <libinput.h>
|
||||
#include <wlr/interfaces/wlr_switch.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "backend/libinput.h"
|
||||
#include "config.h"
|
||||
|
||||
const struct wlr_switch_impl libinput_switch_impl = {
|
||||
.name = "libinput-switch",
|
||||
|
|
@ -22,6 +24,35 @@ struct wlr_libinput_input_device *device_from_switch(
|
|||
return dev;
|
||||
}
|
||||
|
||||
static bool switch_type_from_libinput(enum libinput_switch type, enum wlr_switch_type *out) {
|
||||
switch (type) {
|
||||
case LIBINPUT_SWITCH_LID:
|
||||
*out = WLR_SWITCH_TYPE_LID;
|
||||
return true;
|
||||
case LIBINPUT_SWITCH_TABLET_MODE:
|
||||
*out = WLR_SWITCH_TYPE_TABLET_MODE;
|
||||
return true;
|
||||
#if HAVE_LIBINPUT_SWITCH_KEYPAD_SLIDE
|
||||
case LIBINPUT_SWITCH_KEYPAD_SLIDE:
|
||||
*out = WLR_SWITCH_TYPE_KEYPAD_SLIDE;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool switch_state_from_libinput(enum libinput_switch_state state, enum wlr_switch_state *out) {
|
||||
switch (state) {
|
||||
case LIBINPUT_SWITCH_STATE_OFF:
|
||||
*out = WLR_SWITCH_STATE_OFF;
|
||||
return true;
|
||||
case LIBINPUT_SWITCH_STATE_ON:
|
||||
*out = WLR_SWITCH_STATE_ON;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handle_switch_toggle(struct libinput_event *event,
|
||||
struct wlr_switch *wlr_switch) {
|
||||
struct libinput_event_switch *sevent =
|
||||
|
|
@ -29,21 +60,13 @@ void handle_switch_toggle(struct libinput_event *event,
|
|||
struct wlr_switch_toggle_event wlr_event = {
|
||||
.time_msec = usec_to_msec(libinput_event_switch_get_time_usec(sevent)),
|
||||
};
|
||||
switch (libinput_event_switch_get_switch(sevent)) {
|
||||
case LIBINPUT_SWITCH_LID:
|
||||
wlr_event.switch_type = WLR_SWITCH_TYPE_LID;
|
||||
break;
|
||||
case LIBINPUT_SWITCH_TABLET_MODE:
|
||||
wlr_event.switch_type = WLR_SWITCH_TYPE_TABLET_MODE;
|
||||
break;
|
||||
if (!switch_type_from_libinput(libinput_event_switch_get_switch(sevent), &wlr_event.switch_type)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput switch type");
|
||||
return;
|
||||
}
|
||||
switch (libinput_event_switch_get_switch_state(sevent)) {
|
||||
case LIBINPUT_SWITCH_STATE_OFF:
|
||||
wlr_event.switch_state = WLR_SWITCH_STATE_OFF;
|
||||
break;
|
||||
case LIBINPUT_SWITCH_STATE_ON:
|
||||
wlr_event.switch_state = WLR_SWITCH_STATE_ON;
|
||||
break;
|
||||
if (!switch_state_from_libinput(libinput_event_switch_get_switch_state(sevent), &wlr_event.switch_state)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput switch state");
|
||||
return;
|
||||
}
|
||||
wl_signal_emit_mutable(&wlr_switch->events.toggle, &wlr_event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ void init_device_tablet_pad(struct wlr_libinput_input_device *dev) {
|
|||
struct udev_device *udev = libinput_device_get_udev_device(handle);
|
||||
char **dst = wl_array_add(&wlr_tablet_pad->paths, sizeof(char *));
|
||||
*dst = strdup(udev_device_get_syspath(udev));
|
||||
udev_device_unref(udev);
|
||||
|
||||
int groups = libinput_device_tablet_pad_get_num_mode_groups(handle);
|
||||
for (int i = 0; i < groups; ++i) {
|
||||
|
|
@ -147,13 +148,9 @@ void handle_tablet_pad_button(struct libinput_event *event,
|
|||
.group = libinput_tablet_pad_mode_group_get_index(
|
||||
libinput_event_tablet_pad_get_mode_group(pevent)),
|
||||
};
|
||||
switch (libinput_event_tablet_pad_get_button_state(pevent)) {
|
||||
case LIBINPUT_BUTTON_STATE_PRESSED:
|
||||
wlr_event.state = WLR_BUTTON_PRESSED;
|
||||
break;
|
||||
case LIBINPUT_BUTTON_STATE_RELEASED:
|
||||
wlr_event.state = WLR_BUTTON_RELEASED;
|
||||
break;
|
||||
if (!button_state_from_libinput(libinput_event_tablet_pad_get_button_state(pevent), &wlr_event.state)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput button state");
|
||||
return;
|
||||
}
|
||||
wl_signal_emit_mutable(&tablet_pad->events.button, &wlr_event);
|
||||
}
|
||||
|
|
@ -167,6 +164,7 @@ void handle_tablet_pad_ring(struct libinput_event *event,
|
|||
.ring = libinput_event_tablet_pad_get_ring_number(pevent),
|
||||
.position = libinput_event_tablet_pad_get_ring_position(pevent),
|
||||
.mode = libinput_event_tablet_pad_get_mode(pevent),
|
||||
.source = WLR_TABLET_PAD_RING_SOURCE_UNKNOWN,
|
||||
};
|
||||
switch (libinput_event_tablet_pad_get_ring_source(pevent)) {
|
||||
case LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN:
|
||||
|
|
@ -188,6 +186,7 @@ void handle_tablet_pad_strip(struct libinput_event *event,
|
|||
.strip = libinput_event_tablet_pad_get_strip_number(pevent),
|
||||
.position = libinput_event_tablet_pad_get_strip_position(pevent),
|
||||
.mode = libinput_event_tablet_pad_get_mode(pevent),
|
||||
.source = WLR_TABLET_PAD_STRIP_SOURCE_UNKNOWN,
|
||||
};
|
||||
switch (libinput_event_tablet_pad_get_strip_source(pevent)) {
|
||||
case LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN:
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ void init_device_tablet(struct wlr_libinput_input_device *dev) {
|
|||
struct udev_device *udev = libinput_device_get_udev_device(dev->handle);
|
||||
char **dst = wl_array_add(&wlr_tablet->paths, sizeof(char *));
|
||||
*dst = strdup(udev_device_get_syspath(udev));
|
||||
udev_device_unref(udev);
|
||||
|
||||
wl_list_init(&dev->tablet_tools);
|
||||
}
|
||||
|
|
@ -67,27 +68,61 @@ struct wlr_libinput_input_device *device_from_tablet(
|
|||
return dev;
|
||||
}
|
||||
|
||||
static enum wlr_tablet_tool_type wlr_type_from_libinput_type(
|
||||
enum libinput_tablet_tool_type value) {
|
||||
switch (value) {
|
||||
static bool type_from_libinput(enum libinput_tablet_tool_type type,
|
||||
enum wlr_tablet_tool_type *out) {
|
||||
switch (type) {
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_PEN:
|
||||
return WLR_TABLET_TOOL_TYPE_PEN;
|
||||
*out = WLR_TABLET_TOOL_TYPE_PEN;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_ERASER:
|
||||
return WLR_TABLET_TOOL_TYPE_ERASER;
|
||||
*out = WLR_TABLET_TOOL_TYPE_ERASER;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_BRUSH:
|
||||
return WLR_TABLET_TOOL_TYPE_BRUSH;
|
||||
*out = WLR_TABLET_TOOL_TYPE_BRUSH;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_PENCIL:
|
||||
return WLR_TABLET_TOOL_TYPE_PENCIL;
|
||||
*out = WLR_TABLET_TOOL_TYPE_PENCIL;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH:
|
||||
return WLR_TABLET_TOOL_TYPE_AIRBRUSH;
|
||||
*out = WLR_TABLET_TOOL_TYPE_AIRBRUSH;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_MOUSE:
|
||||
return WLR_TABLET_TOOL_TYPE_MOUSE;
|
||||
*out = WLR_TABLET_TOOL_TYPE_MOUSE;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_LENS:
|
||||
return WLR_TABLET_TOOL_TYPE_LENS;
|
||||
*out = WLR_TABLET_TOOL_TYPE_LENS;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_TOTEM:
|
||||
return WLR_TABLET_TOOL_TYPE_TOTEM;
|
||||
*out = WLR_TABLET_TOOL_TYPE_TOTEM;
|
||||
return true;
|
||||
}
|
||||
abort(); // unreachable
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool proximity_state_from_libinput(enum libinput_tablet_tool_proximity_state state,
|
||||
enum wlr_tablet_tool_proximity_state *out) {
|
||||
switch (state) {
|
||||
case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT:
|
||||
*out = WLR_TABLET_TOOL_PROXIMITY_OUT;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN:
|
||||
*out = WLR_TABLET_TOOL_PROXIMITY_IN;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool tip_state_from_libinput(enum libinput_tablet_tool_tip_state state,
|
||||
enum wlr_tablet_tool_tip_state *out) {
|
||||
switch (state) {
|
||||
case LIBINPUT_TABLET_TOOL_TIP_UP:
|
||||
*out = WLR_TABLET_TOOL_TIP_UP;
|
||||
return true;
|
||||
case LIBINPUT_TABLET_TOOL_TIP_DOWN:
|
||||
*out = WLR_TABLET_TOOL_TIP_DOWN;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct tablet_tool *get_tablet_tool(
|
||||
|
|
@ -99,14 +134,19 @@ static struct tablet_tool *get_tablet_tool(
|
|||
return tool;
|
||||
}
|
||||
|
||||
enum wlr_tablet_tool_type type;
|
||||
if (!type_from_libinput(libinput_tablet_tool_get_type(libinput_tool), &type)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tool = calloc(1, sizeof(*tool));
|
||||
if (tool == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "failed to allocate wlr_libinput_tablet_tool");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tool->wlr_tool.type = wlr_type_from_libinput_type(
|
||||
libinput_tablet_tool_get_type(libinput_tool));
|
||||
tool->wlr_tool.type = type;
|
||||
tool->wlr_tool.hardware_serial =
|
||||
libinput_tablet_tool_get_serial(libinput_tool);
|
||||
tool->wlr_tool.hardware_wacom =
|
||||
|
|
@ -198,14 +238,12 @@ void handle_tablet_tool_proximity(struct libinput_event *event,
|
|||
.y = libinput_event_tablet_tool_get_y_transformed(tevent, 1),
|
||||
};
|
||||
|
||||
switch (libinput_event_tablet_tool_get_proximity_state(tevent)) {
|
||||
case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT:
|
||||
wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_OUT;
|
||||
break;
|
||||
case LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN:
|
||||
wlr_event.state = WLR_TABLET_TOOL_PROXIMITY_IN;
|
||||
break;
|
||||
if (!proximity_state_from_libinput(libinput_event_tablet_tool_get_proximity_state(tevent),
|
||||
&wlr_event.state)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool proximity state");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_signal_emit_mutable(&wlr_tablet->events.proximity, &wlr_event);
|
||||
|
||||
if (libinput_event_tablet_tool_get_proximity_state(tevent) ==
|
||||
|
|
@ -240,14 +278,11 @@ void handle_tablet_tool_tip(struct libinput_event *event,
|
|||
.y = libinput_event_tablet_tool_get_y_transformed(tevent, 1),
|
||||
};
|
||||
|
||||
switch (libinput_event_tablet_tool_get_tip_state(tevent)) {
|
||||
case LIBINPUT_TABLET_TOOL_TIP_UP:
|
||||
wlr_event.state = WLR_TABLET_TOOL_TIP_UP;
|
||||
break;
|
||||
case LIBINPUT_TABLET_TOOL_TIP_DOWN:
|
||||
wlr_event.state = WLR_TABLET_TOOL_TIP_DOWN;
|
||||
break;
|
||||
if (!tip_state_from_libinput(libinput_event_tablet_tool_get_tip_state(tevent), &wlr_event.state)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput tablet tool tip state");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_signal_emit_mutable(&wlr_tablet->events.tip, &wlr_event);
|
||||
}
|
||||
|
||||
|
|
@ -266,13 +301,11 @@ void handle_tablet_tool_button(struct libinput_event *event,
|
|||
.time_msec = usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent)),
|
||||
.button = libinput_event_tablet_tool_get_button(tevent),
|
||||
};
|
||||
switch (libinput_event_tablet_tool_get_button_state(tevent)) {
|
||||
case LIBINPUT_BUTTON_STATE_RELEASED:
|
||||
wlr_event.state = WLR_BUTTON_RELEASED;
|
||||
break;
|
||||
case LIBINPUT_BUTTON_STATE_PRESSED:
|
||||
wlr_event.state = WLR_BUTTON_PRESSED;
|
||||
break;
|
||||
|
||||
if (!button_state_from_libinput(libinput_event_tablet_tool_get_button_state(tevent), &wlr_event.state)) {
|
||||
wlr_log(WLR_DEBUG, "Unhandled libinput button state");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_signal_emit_mutable(&wlr_tablet->events.button, &wlr_event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,15 @@ static void handle_disable_seat(struct libseat *seat, void *data) {
|
|||
|
||||
static int libseat_event(int fd, uint32_t mask, void *data) {
|
||||
struct wlr_session *session = data;
|
||||
if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) {
|
||||
if (mask & WL_EVENT_ERROR) {
|
||||
wlr_log(WLR_ERROR, "Failed to wait for libseat event");
|
||||
} else {
|
||||
wlr_log(WLR_INFO, "Failed to wait for libseat event");
|
||||
}
|
||||
wlr_session_destroy(session);
|
||||
return 0;
|
||||
}
|
||||
if (libseat_dispatch(session->seat_handle, 0) == -1) {
|
||||
wlr_log_errno(WLR_ERROR, "Failed to dispatch libseat");
|
||||
wlr_session_destroy(session);
|
||||
|
|
@ -367,7 +376,10 @@ void wlr_session_close_file(struct wlr_session *session,
|
|||
}
|
||||
|
||||
assert(wl_list_empty(&dev->events.change.listener_list));
|
||||
assert(wl_list_empty(&dev->events.remove.listener_list));
|
||||
// TODO: assert that the "remove" listener list is empty as well. Listeners
|
||||
// will typically call wlr_session_close_file() in response, and
|
||||
// wl_signal_emit_mutable() installs two phantom listeners, so we'd count
|
||||
// these two.
|
||||
|
||||
close(dev->fd);
|
||||
wl_list_remove(&dev->link);
|
||||
|
|
|
|||
|
|
@ -132,4 +132,6 @@ void handle_tablet_pad_ring(struct libinput_event *event,
|
|||
void handle_tablet_pad_strip(struct libinput_event *event,
|
||||
struct wlr_tablet_pad *tablet_pad);
|
||||
|
||||
bool button_state_from_libinput(enum libinput_button_state state, enum wlr_button_state *out);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -433,10 +433,11 @@ void vulkan_reset_command_buffer(struct wlr_vk_command_buffer *cb);
|
|||
bool vulkan_wait_command_buffer(struct wlr_vk_command_buffer *cb,
|
||||
struct wlr_vk_renderer *renderer);
|
||||
|
||||
bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer,
|
||||
struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb,
|
||||
struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point);
|
||||
bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture,
|
||||
bool vulkan_sync_render_pass_release(struct wlr_vk_renderer *renderer,
|
||||
struct wlr_vk_render_pass *pass);
|
||||
bool vulkan_sync_foreign_texture_acquire(struct wlr_vk_texture *texture,
|
||||
int sync_file_fds[static WLR_DMABUF_MAX_PLANES]);
|
||||
bool vulkan_sync_render_buffer_acquire(struct wlr_vk_render_buffer *render_buffer,
|
||||
int sync_file_fds[static WLR_DMABUF_MAX_PLANES]);
|
||||
|
||||
bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ void output_defer_present(struct wlr_output *output, struct wlr_output_event_pre
|
|||
|
||||
bool output_prepare_commit(struct wlr_output *output, const struct wlr_output_state *state);
|
||||
void output_apply_commit(struct wlr_output *output, const struct wlr_output_state *state);
|
||||
void output_send_commit_event(struct wlr_output *output, const struct wlr_output_state *state);
|
||||
|
||||
void output_state_get_buffer_src_box(const struct wlr_output_state *state,
|
||||
struct wlr_fbox *out);
|
||||
|
|
|
|||
|
|
@ -62,8 +62,6 @@ struct wlr_drm_lease_connector_v1 {
|
|||
|
||||
struct wlr_output *output;
|
||||
struct wlr_drm_lease_device_v1 *device;
|
||||
/** NULL if no client is currently leasing this connector */
|
||||
struct wlr_drm_lease_v1 *active_lease;
|
||||
|
||||
struct wl_list link; // wlr_drm_lease_device_v1.connectors
|
||||
|
||||
|
|
@ -93,9 +91,6 @@ struct wlr_drm_lease_v1 {
|
|||
|
||||
struct wlr_drm_lease_device_v1 *device;
|
||||
|
||||
struct wlr_drm_lease_connector_v1 **connectors;
|
||||
size_t n_connectors;
|
||||
|
||||
struct wl_list link; // wlr_drm_lease_device_v1.leases
|
||||
|
||||
void *data;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ struct wlr_switch {
|
|||
enum wlr_switch_type {
|
||||
WLR_SWITCH_TYPE_LID,
|
||||
WLR_SWITCH_TYPE_TABLET_MODE,
|
||||
WLR_SWITCH_TYPE_KEYPAD_SLIDE,
|
||||
};
|
||||
|
||||
enum wlr_switch_state {
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ struct wlr_xwm {
|
|||
struct wl_listener drop_focus_destroy;
|
||||
};
|
||||
|
||||
// xwm_create takes ownership of wm_fd and will close it under all circumstances.
|
||||
struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland, int wm_fd);
|
||||
|
||||
void xwm_destroy(struct wlr_xwm *xwm);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
project(
|
||||
'wlroots',
|
||||
'c',
|
||||
version: '0.19.0',
|
||||
version: '0.19.3',
|
||||
license: 'MIT',
|
||||
meson_version: '>=1.3',
|
||||
default_options: [
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ static struct wlr_shm_buffer *shm_buffer_from_buffer(
|
|||
|
||||
static void buffer_destroy(struct wlr_buffer *wlr_buffer) {
|
||||
struct wlr_shm_buffer *buffer = shm_buffer_from_buffer(wlr_buffer);
|
||||
wlr_buffer_finish(wlr_buffer);
|
||||
munmap(buffer->data, buffer->size);
|
||||
close(buffer->shm.fd);
|
||||
free(buffer);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ static bool buffer_get_dmabuf(struct wlr_buffer *wlr_buffer, struct wlr_dmabuf_a
|
|||
|
||||
static void buffer_destroy(struct wlr_buffer *wlr_buffer) {
|
||||
struct wlr_udmabuf_buffer *buffer = wl_container_of(wlr_buffer, buffer, base);
|
||||
wlr_buffer_finish(wlr_buffer);
|
||||
wlr_dmabuf_attributes_finish(&buffer->dmabuf);
|
||||
close(buffer->shm.fd);
|
||||
free(buffer);
|
||||
|
|
|
|||
20
render/egl.c
20
render/egl.c
|
|
@ -260,7 +260,8 @@ static struct wlr_egl *egl_create(void) {
|
|||
return egl;
|
||||
}
|
||||
|
||||
static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display) {
|
||||
static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display,
|
||||
bool allow_software) {
|
||||
egl->display = display;
|
||||
|
||||
EGLint major, minor;
|
||||
|
|
@ -326,9 +327,8 @@ static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display) {
|
|||
|
||||
// The only way a non-DRM device is selected is when the user
|
||||
// explicitly picks software rendering
|
||||
if (check_egl_ext(device_exts_str, "EGL_MESA_device_software") &&
|
||||
egl->exts.EXT_device_drm) {
|
||||
if (env_parse_bool("WLR_RENDERER_ALLOW_SOFTWARE")) {
|
||||
if (check_egl_ext(device_exts_str, "EGL_MESA_device_software")) {
|
||||
if (allow_software || env_parse_bool("WLR_RENDERER_ALLOW_SOFTWARE")) {
|
||||
wlr_log(WLR_INFO, "Using software rendering");
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Software rendering detected, please use "
|
||||
|
|
@ -382,7 +382,7 @@ static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display) {
|
|||
}
|
||||
|
||||
static bool egl_init(struct wlr_egl *egl, EGLenum platform,
|
||||
void *remote_display) {
|
||||
void *remote_display, bool allow_software) {
|
||||
EGLint display_attribs[3] = {0};
|
||||
size_t display_attribs_len = 0;
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!egl_init_display(egl, display)) {
|
||||
if (!egl_init_display(egl, display, allow_software)) {
|
||||
if (egl->exts.KHR_display_reference) {
|
||||
eglTerminate(display);
|
||||
}
|
||||
|
|
@ -556,6 +556,8 @@ static int open_render_node(int drm_fd) {
|
|||
}
|
||||
|
||||
struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
|
||||
bool allow_software = drm_fd < 0;
|
||||
|
||||
struct wlr_egl *egl = egl_create();
|
||||
if (egl == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to create EGL context");
|
||||
|
|
@ -569,7 +571,7 @@ struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
|
|||
*/
|
||||
EGLDeviceEXT egl_device = get_egl_device_from_drm_fd(egl, drm_fd);
|
||||
if (egl_device != EGL_NO_DEVICE_EXT) {
|
||||
if (egl_init(egl, EGL_PLATFORM_DEVICE_EXT, egl_device)) {
|
||||
if (egl_init(egl, EGL_PLATFORM_DEVICE_EXT, egl_device, allow_software)) {
|
||||
wlr_log(WLR_DEBUG, "Using EGL_PLATFORM_DEVICE_EXT");
|
||||
return egl;
|
||||
}
|
||||
|
|
@ -594,7 +596,7 @@ struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (egl_init(egl, EGL_PLATFORM_GBM_KHR, egl->gbm_device)) {
|
||||
if (egl_init(egl, EGL_PLATFORM_GBM_KHR, egl->gbm_device, allow_software)) {
|
||||
wlr_log(WLR_DEBUG, "Using EGL_PLATFORM_GBM_KHR");
|
||||
return egl;
|
||||
}
|
||||
|
|
@ -633,7 +635,7 @@ struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!egl_init_display(egl, display)) {
|
||||
if (!egl_init_display(egl, display, true)) {
|
||||
free(egl);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ void wlr_render_pass_add_texture(struct wlr_render_pass *render_pass,
|
|||
if (!wlr_fbox_empty(&options->src_box)) {
|
||||
const struct wlr_fbox *box = &options->src_box;
|
||||
assert(box->x >= 0 && box->y >= 0 &&
|
||||
box->x + box->width <= options->texture->width &&
|
||||
box->y + box->height <= options->texture->height);
|
||||
(uint32_t)(box->x + box->width) <= options->texture->width &&
|
||||
(uint32_t)(box->y + box->height) <= options->texture->height);
|
||||
}
|
||||
|
||||
render_pass->impl->add_texture(render_pass, options);
|
||||
|
|
|
|||
|
|
@ -141,6 +141,40 @@ static VkSemaphore render_pass_wait_sync_file(struct wlr_vk_render_pass *pass,
|
|||
return *sem_ptr;
|
||||
}
|
||||
|
||||
static bool render_pass_wait_render_buffer(struct wlr_vk_render_pass *pass,
|
||||
VkSemaphoreSubmitInfoKHR *render_wait, uint32_t *render_wait_len_ptr) {
|
||||
int sync_file_fds[WLR_DMABUF_MAX_PLANES];
|
||||
for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) {
|
||||
sync_file_fds[i] = -1;
|
||||
}
|
||||
|
||||
if (!vulkan_sync_render_buffer_acquire(pass->render_buffer, sync_file_fds)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < WLR_DMABUF_MAX_PLANES; i++) {
|
||||
if (sync_file_fds[i] < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VkSemaphore sem = render_pass_wait_sync_file(pass, *render_wait_len_ptr, sync_file_fds[i]);
|
||||
if (sem == VK_NULL_HANDLE) {
|
||||
close(sync_file_fds[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
render_wait[*render_wait_len_ptr] = (VkSemaphoreSubmitInfoKHR){
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,
|
||||
.semaphore = sem,
|
||||
.stageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR,
|
||||
};
|
||||
|
||||
(*render_wait_len_ptr)++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
||||
struct wlr_vk_render_pass *pass = get_render_pass(wlr_pass);
|
||||
struct wlr_vk_renderer *renderer = pass->renderer;
|
||||
|
|
@ -236,7 +270,7 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
|||
vkCmdEndRenderPass(render_cb->vk);
|
||||
|
||||
size_t pass_textures_len = pass->textures.size / sizeof(struct wlr_vk_render_pass_texture);
|
||||
size_t render_wait_cap = pass_textures_len * WLR_DMABUF_MAX_PLANES;
|
||||
size_t render_wait_cap = (1 + pass_textures_len) * WLR_DMABUF_MAX_PLANES;
|
||||
render_wait = calloc(render_wait_cap, sizeof(*render_wait));
|
||||
if (render_wait == NULL) {
|
||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||
|
|
@ -314,7 +348,7 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
|||
sync_file_fds[0] = sync_file_fd;
|
||||
} else {
|
||||
struct wlr_vk_texture *texture = pass_texture->texture;
|
||||
if (!vulkan_sync_foreign_texture(texture, sync_file_fds)) {
|
||||
if (!vulkan_sync_foreign_texture_acquire(texture, sync_file_fds)) {
|
||||
wlr_log(WLR_ERROR, "Failed to wait for foreign texture DMA-BUF fence");
|
||||
continue;
|
||||
}
|
||||
|
|
@ -341,6 +375,10 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!render_pass_wait_render_buffer(pass, render_wait, &render_wait_len)) {
|
||||
wlr_log(WLR_ERROR, "Failed to wait for render buffer DMA-BUF fence");
|
||||
}
|
||||
|
||||
// also add acquire/release barriers for the current render buffer
|
||||
VkImageLayout src_layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
if (pass->srgb_pathway) {
|
||||
|
|
@ -538,8 +576,7 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
|||
wl_list_insert(&stage_cb->stage_buffers, &stage_buf->link);
|
||||
}
|
||||
|
||||
if (!vulkan_sync_render_buffer(renderer, render_buffer, render_cb,
|
||||
pass->signal_timeline, pass->signal_point)) {
|
||||
if (!vulkan_sync_render_pass_release(renderer, pass)) {
|
||||
wlr_log(WLR_ERROR, "Failed to sync render buffer");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,16 +66,35 @@ static struct wlr_vk_descriptor_pool *alloc_ds(
|
|||
struct wl_list *pool_list, size_t *last_pool_size) {
|
||||
VkResult res;
|
||||
|
||||
bool found = false;
|
||||
VkDescriptorSetAllocateInfo ds_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = layout,
|
||||
};
|
||||
|
||||
struct wlr_vk_descriptor_pool *pool;
|
||||
wl_list_for_each(pool, pool_list, link) {
|
||||
if (pool->free > 0) {
|
||||
found = true;
|
||||
break;
|
||||
ds_info.descriptorPool = pool->pool;
|
||||
res = vkAllocateDescriptorSets(renderer->dev->dev, &ds_info, ds);
|
||||
switch (res) {
|
||||
case VK_ERROR_FRAGMENTED_POOL:
|
||||
case VK_ERROR_OUT_OF_POOL_MEMORY:
|
||||
// Descriptor sets with more than one descriptor can cause us
|
||||
// to run out of pool memory early or lead to fragmentation
|
||||
// that makes the pool unable to service our allocation
|
||||
// request. Try the next pool or allocate a new one.
|
||||
continue;
|
||||
case VK_SUCCESS:
|
||||
--pool->free;
|
||||
return pool;
|
||||
default:
|
||||
wlr_vk_error("vkAllocateDescriptorSets", res);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) { // create new pool
|
||||
pool = calloc(1, sizeof(*pool));
|
||||
if (!pool) {
|
||||
wlr_log_errno(WLR_ERROR, "allocation failed");
|
||||
|
|
@ -111,14 +130,8 @@ static struct wlr_vk_descriptor_pool *alloc_ds(
|
|||
|
||||
*last_pool_size = count;
|
||||
wl_list_insert(pool_list, &pool->link);
|
||||
}
|
||||
|
||||
VkDescriptorSetAllocateInfo ds_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = layout,
|
||||
.descriptorPool = pool->pool,
|
||||
};
|
||||
ds_info.descriptorPool = pool->pool;
|
||||
res = vkAllocateDescriptorSets(renderer->dev->dev, &ds_info, ds);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkAllocateDescriptorSets", res);
|
||||
|
|
@ -934,13 +947,11 @@ static struct wlr_vk_render_buffer *get_render_buffer(
|
|||
return buffer;
|
||||
}
|
||||
|
||||
bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture,
|
||||
int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) {
|
||||
struct wlr_vk_renderer *renderer = texture->renderer;
|
||||
|
||||
static bool buffer_export_sync_file(struct wlr_vk_renderer *renderer, struct wlr_buffer *buffer,
|
||||
uint32_t flags, int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) {
|
||||
struct wlr_dmabuf_attributes dmabuf = {0};
|
||||
if (!wlr_buffer_get_dmabuf(texture->buffer, &dmabuf)) {
|
||||
wlr_log(WLR_ERROR, "Failed to get texture DMA-BUF");
|
||||
if (!wlr_buffer_get_dmabuf(buffer, &dmabuf)) {
|
||||
wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -950,7 +961,7 @@ bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture,
|
|||
for (int i = 0; i < dmabuf.n_planes; i++) {
|
||||
struct pollfd pollfd = {
|
||||
.fd = dmabuf.fd[i],
|
||||
.events = POLLIN,
|
||||
.events = (flags & DMA_BUF_SYNC_WRITE) ? POLLOUT : POLLIN,
|
||||
};
|
||||
int timeout_ms = 1000;
|
||||
int ret = poll(&pollfd, 1, timeout_ms);
|
||||
|
|
@ -967,7 +978,7 @@ bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture,
|
|||
}
|
||||
|
||||
for (int i = 0; i < dmabuf.n_planes; i++) {
|
||||
int sync_file_fd = dmabuf_export_sync_file(dmabuf.fd[i], DMA_BUF_SYNC_READ);
|
||||
int sync_file_fd = dmabuf_export_sync_file(dmabuf.fd[i], flags);
|
||||
if (sync_file_fd < 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to extract DMA-BUF fence");
|
||||
return false;
|
||||
|
|
@ -979,12 +990,40 @@ bool vulkan_sync_foreign_texture(struct wlr_vk_texture *texture,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer,
|
||||
struct wlr_vk_render_buffer *render_buffer, struct wlr_vk_command_buffer *cb,
|
||||
struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point) {
|
||||
VkResult res;
|
||||
bool vulkan_sync_foreign_texture_acquire(struct wlr_vk_texture *texture,
|
||||
int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) {
|
||||
return buffer_export_sync_file(texture->renderer, texture->buffer, DMA_BUF_SYNC_READ, sync_file_fds);
|
||||
}
|
||||
|
||||
if (!renderer->dev->implicit_sync_interop && signal_timeline == NULL) {
|
||||
bool vulkan_sync_render_buffer_acquire(struct wlr_vk_render_buffer *render_buffer,
|
||||
int sync_file_fds[static WLR_DMABUF_MAX_PLANES]) {
|
||||
return buffer_export_sync_file(render_buffer->renderer, render_buffer->wlr_buffer,
|
||||
DMA_BUF_SYNC_WRITE, sync_file_fds);
|
||||
}
|
||||
|
||||
static bool buffer_import_sync_file(struct wlr_buffer *buffer, uint32_t flags, int sync_file_fd) {
|
||||
struct wlr_dmabuf_attributes dmabuf = {0};
|
||||
if (!wlr_buffer_get_dmabuf(buffer, &dmabuf)) {
|
||||
wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dmabuf.n_planes; i++) {
|
||||
if (!dmabuf_import_sync_file(dmabuf.fd[i], flags,
|
||||
sync_file_fd)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vulkan_sync_render_pass_release(struct wlr_vk_renderer *renderer,
|
||||
struct wlr_vk_render_pass *pass) {
|
||||
VkResult res;
|
||||
struct wlr_vk_command_buffer *cb = pass->command_buffer;
|
||||
|
||||
if (!renderer->dev->implicit_sync_interop && pass->signal_timeline == NULL) {
|
||||
// We have no choice but to block here sadly
|
||||
return vulkan_wait_command_buffer(cb, renderer);
|
||||
}
|
||||
|
|
@ -1006,21 +1045,19 @@ bool vulkan_sync_render_buffer(struct wlr_vk_renderer *renderer,
|
|||
}
|
||||
|
||||
bool ok = false;
|
||||
if (signal_timeline != NULL) {
|
||||
if (!wlr_drm_syncobj_timeline_import_sync_file(signal_timeline,
|
||||
signal_point, sync_file_fd)) {
|
||||
if (pass->signal_timeline != NULL) {
|
||||
if (!wlr_drm_syncobj_timeline_import_sync_file(pass->signal_timeline,
|
||||
pass->signal_point, sync_file_fd)) {
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
struct wlr_dmabuf_attributes dmabuf = {0};
|
||||
if (!wlr_buffer_get_dmabuf(render_buffer->wlr_buffer, &dmabuf)) {
|
||||
wlr_log(WLR_ERROR, "wlr_buffer_get_dmabuf failed");
|
||||
if (!buffer_import_sync_file(pass->render_buffer->wlr_buffer, DMA_BUF_SYNC_WRITE, sync_file_fd)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dmabuf.n_planes; i++) {
|
||||
if (!dmabuf_import_sync_file(dmabuf.fd[i], DMA_BUF_SYNC_WRITE,
|
||||
sync_file_fd)) {
|
||||
struct wlr_vk_render_pass_texture *pass_texture;
|
||||
wl_array_for_each(pass_texture, &pass->textures) {
|
||||
if (!buffer_import_sync_file(pass_texture->texture->buffer, DMA_BUF_SYNC_READ, sync_file_fd)) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ xdg-shell-protocol.h:
|
|||
tinywl.o: tinywl.c xdg-shell-protocol.h
|
||||
$(CC) -c $< -g -Werror $(CFLAGS) -I. -DWLR_USE_UNSTABLE -o $@
|
||||
tinywl: tinywl.o
|
||||
$(CC) $^ $> -g -Werror $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@
|
||||
$(CC) $^ -g -Werror $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@
|
||||
|
||||
clean:
|
||||
rm -f tinywl tinywl.o xdg-shell-protocol.h
|
||||
|
|
|
|||
|
|
@ -107,6 +107,10 @@ static const struct wlr_ext_image_capture_source_v1_interface output_source_impl
|
|||
static void source_update_buffer_constraints(struct wlr_ext_output_image_capture_source_v1 *source) {
|
||||
struct wlr_output *output = source->output;
|
||||
|
||||
if (!output->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wlr_output_configure_primary_swapchain(output, NULL, &output->swapchain)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -120,7 +124,8 @@ static void source_handle_output_commit(struct wl_listener *listener,
|
|||
struct wlr_ext_output_image_capture_source_v1 *source = wl_container_of(listener, source, output_commit);
|
||||
struct wlr_output_event_commit *event = data;
|
||||
|
||||
if (event->state->committed & (WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_RENDER_FORMAT)) {
|
||||
if (event->state->committed & (WLR_OUTPUT_STATE_MODE |
|
||||
WLR_OUTPUT_STATE_RENDER_FORMAT | WLR_OUTPUT_STATE_ENABLED)) {
|
||||
source_update_buffer_constraints(source);
|
||||
}
|
||||
|
||||
|
|
@ -283,7 +288,8 @@ static void output_cursor_source_copy_frame(struct wlr_ext_image_capture_source_
|
|||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
wlr_ext_image_copy_capture_frame_v1_ready(frame, WL_OUTPUT_TRANSFORM_NORMAL, &now);
|
||||
wlr_ext_image_copy_capture_frame_v1_ready(frame,
|
||||
cursor_source->output->transform, &now);
|
||||
}
|
||||
|
||||
static const struct wlr_ext_image_capture_source_v1_interface output_cursor_source_impl = {
|
||||
|
|
|
|||
|
|
@ -288,18 +288,10 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
|
|||
static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
||||
struct wlr_output *output = cursor->output;
|
||||
|
||||
if (!output->impl->set_cursor ||
|
||||
output->software_cursor_locks > 0) {
|
||||
if (!output->impl->set_cursor || output->software_cursor_locks > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wlr_output_cursor *hwcur = output->hardware_cursor;
|
||||
if (hwcur != NULL && hwcur != cursor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
output->hardware_cursor = NULL;
|
||||
|
||||
struct wlr_texture *texture = cursor->texture;
|
||||
|
||||
// If the cursor was hidden or was a software cursor, the hardware
|
||||
|
|
@ -424,12 +416,15 @@ bool output_cursor_set_texture(struct wlr_output_cursor *cursor,
|
|||
wl_list_init(&cursor->renderer_destroy.link);
|
||||
}
|
||||
|
||||
if (output->hardware_cursor == NULL || output->hardware_cursor == cursor) {
|
||||
if (output_cursor_attempt_hardware(cursor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Falling back to software cursor on output '%s'", output->name);
|
||||
output_disable_hardware_cursor(output);
|
||||
}
|
||||
|
||||
output_cursor_damage_whole(cursor);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -745,7 +745,9 @@ void output_apply_commit(struct wlr_output *output, const struct wlr_output_stat
|
|||
}
|
||||
|
||||
output_apply_state(output, state);
|
||||
}
|
||||
|
||||
void output_send_commit_event(struct wlr_output *output, const struct wlr_output_state *state) {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
struct wlr_output_event_commit event = {
|
||||
|
|
@ -787,6 +789,7 @@ bool wlr_output_commit_state(struct wlr_output *output,
|
|||
}
|
||||
|
||||
output_apply_commit(output, &pending);
|
||||
output_send_commit_event(output, &pending);
|
||||
|
||||
if (new_back_buffer) {
|
||||
wlr_buffer_unlock(pending.buffer);
|
||||
|
|
|
|||
|
|
@ -96,9 +96,12 @@ static void scene_buffer_unmark_client_buffer(struct wlr_scene_buffer *scene_buf
|
|||
return;
|
||||
}
|
||||
|
||||
assert(buffer->n_ignore_locks > 0);
|
||||
// If the buffer was a single-pixel buffer where we cached its color
|
||||
// then it won't have been marked as damage-allowed.
|
||||
if (buffer->n_ignore_locks > 0) {
|
||||
buffer->n_ignore_locks--;
|
||||
}
|
||||
}
|
||||
|
||||
static int min(int a, int b) {
|
||||
return a < b ? a : b;
|
||||
|
|
@ -165,7 +168,21 @@ static void surface_reconfigure(struct wlr_scene_surface *scene_surface) {
|
|||
scene_buffer_unmark_client_buffer(scene_buffer);
|
||||
|
||||
if (surface->buffer) {
|
||||
// If we've cached the buffer's single-pixel buffer color
|
||||
// then any in-place updates to the texture wouldn't be
|
||||
// reflected in rendering. So only allow in-place texture
|
||||
// updates if it's not a single pixel buffer. Note that we
|
||||
// can't use the cached scene_buffer->is_single_pixel_buffer
|
||||
// because that's only set later on.
|
||||
bool is_single_pixel_buffer = false;
|
||||
if (surface->buffer->source != NULL) {
|
||||
struct wlr_single_pixel_buffer_v1 *spb =
|
||||
wlr_single_pixel_buffer_v1_try_from_buffer(surface->buffer->source);
|
||||
is_single_pixel_buffer = spb != NULL;
|
||||
}
|
||||
if (!is_single_pixel_buffer) {
|
||||
client_buffer_mark_next_can_damage(surface->buffer);
|
||||
}
|
||||
|
||||
struct wlr_linux_drm_syncobj_surface_v1_state *syncobj_surface_state =
|
||||
wlr_linux_drm_syncobj_v1_get_surface_state(surface);
|
||||
|
|
@ -186,7 +203,8 @@ static void surface_reconfigure(struct wlr_scene_surface *scene_surface) {
|
|||
&surface->buffer->base, &options);
|
||||
|
||||
if (syncobj_surface_state != NULL &&
|
||||
(surface->current.committed & WLR_SURFACE_STATE_BUFFER)) {
|
||||
(surface->current.committed & WLR_SURFACE_STATE_BUFFER) &&
|
||||
surface->buffer->source != NULL) {
|
||||
wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(syncobj_surface_state,
|
||||
surface->buffer->source);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -530,10 +530,6 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_
|
|||
struct wlr_cursor *cur = output_cursor->cursor;
|
||||
struct wlr_output *output = output_cursor->output_cursor->output;
|
||||
|
||||
if (!output->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor_output_cursor_reset_image(output_cursor);
|
||||
|
||||
if (cur->state->buffer != NULL) {
|
||||
|
|
@ -589,10 +585,11 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_
|
|||
&src_box, dst_width, dst_height, surface->current.transform,
|
||||
hotspot_x, hotspot_y, wait_timeline, wait_point);
|
||||
|
||||
if (syncobj_surface_state != NULL && surface->buffer != NULL &&
|
||||
if (syncobj_surface_state != NULL &&
|
||||
surface->buffer != NULL && surface->buffer->source != NULL &&
|
||||
(surface->current.committed & WLR_SURFACE_STATE_BUFFER)) {
|
||||
wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(syncobj_surface_state,
|
||||
&surface->buffer->base);
|
||||
surface->buffer->source);
|
||||
}
|
||||
|
||||
if (output_cursor->output_cursor->visible) {
|
||||
|
|
|
|||
|
|
@ -68,10 +68,6 @@ static void drm_lease_connector_v1_destroy(
|
|||
|
||||
wlr_log(WLR_DEBUG, "Destroying connector %s", connector->output->name);
|
||||
|
||||
if (connector->active_lease) {
|
||||
wlr_drm_lease_terminate(connector->active_lease->drm_lease);
|
||||
}
|
||||
|
||||
struct wl_resource *resource, *tmp;
|
||||
wl_resource_for_each_safe(resource, tmp, &connector->resources) {
|
||||
wp_drm_lease_connector_v1_send_withdrawn(resource);
|
||||
|
|
@ -140,14 +136,9 @@ static void lease_handle_destroy(struct wl_listener *listener, void *data) {
|
|||
|
||||
wl_list_remove(&lease->destroy.link);
|
||||
|
||||
for (size_t i = 0; i < lease->n_connectors; ++i) {
|
||||
lease->connectors[i]->active_lease = NULL;
|
||||
}
|
||||
|
||||
wl_list_remove(&lease->link);
|
||||
wl_resource_set_user_data(lease->resource, NULL);
|
||||
|
||||
free(lease->connectors);
|
||||
free(lease);
|
||||
}
|
||||
|
||||
|
|
@ -180,20 +171,6 @@ struct wlr_drm_lease_v1 *wlr_drm_lease_request_v1_grant(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lease->connectors = calloc(request->n_connectors, sizeof(*lease->connectors));
|
||||
if (!lease->connectors) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate lease connectors list");
|
||||
close(fd);
|
||||
wp_drm_lease_v1_send_finished(lease->resource);
|
||||
free(lease);
|
||||
return NULL;
|
||||
}
|
||||
lease->n_connectors = request->n_connectors;
|
||||
for (size_t i = 0; i < request->n_connectors; ++i) {
|
||||
lease->connectors[i] = request->connectors[i];
|
||||
lease->connectors[i]->active_lease = lease;
|
||||
}
|
||||
|
||||
lease->destroy.notify = lease_handle_destroy;
|
||||
wl_signal_add(&lease->drm_lease->events.destroy, &lease->destroy);
|
||||
|
||||
|
|
@ -338,16 +315,6 @@ static void drm_lease_request_v1_handle_submit(
|
|||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < request->n_connectors; ++i) {
|
||||
struct wlr_drm_lease_connector_v1 *conn = request->connectors[i];
|
||||
if (conn->active_lease) {
|
||||
wlr_log(WLR_ERROR, "Failed to create lease, connector %s has "
|
||||
"already been leased", conn->output->name);
|
||||
wp_drm_lease_v1_send_finished(lease_resource);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
request->lease_resource = lease_resource;
|
||||
|
||||
wl_signal_emit_mutable(&request->device->manager->events.request,
|
||||
|
|
@ -440,10 +407,6 @@ static struct wp_drm_lease_connector_v1_interface lease_connector_impl = {
|
|||
static void drm_lease_connector_v1_send_to_client(
|
||||
struct wlr_drm_lease_connector_v1 *connector,
|
||||
struct wl_resource *resource) {
|
||||
if (connector->active_lease) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wl_client *client = wl_resource_get_client(resource);
|
||||
|
||||
uint32_t version = wl_resource_get_version(resource);
|
||||
|
|
@ -490,10 +453,12 @@ static void lease_device_bind(struct wl_client *wl_client, void *data,
|
|||
if (!device) {
|
||||
wlr_log(WLR_DEBUG, "Failed to bind lease device, "
|
||||
"the wlr_drm_lease_device_v1 has been destroyed");
|
||||
wl_list_init(wl_resource_get_link(device_resource));
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_user_data(device_resource, device);
|
||||
wl_list_insert(&device->resources, wl_resource_get_link(device_resource));
|
||||
|
||||
int fd = wlr_drm_backend_get_non_master_fd(device->backend);
|
||||
if (fd < 0) {
|
||||
|
|
@ -505,8 +470,6 @@ static void lease_device_bind(struct wl_client *wl_client, void *data,
|
|||
wp_drm_lease_device_v1_send_drm_fd(device_resource, fd);
|
||||
close(fd);
|
||||
|
||||
wl_list_insert(&device->resources, wl_resource_get_link(device_resource));
|
||||
|
||||
struct wlr_drm_lease_connector_v1 *connector;
|
||||
wl_list_for_each(connector, &device->connectors, link) {
|
||||
drm_lease_connector_v1_send_to_client(connector, device_resource);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ struct wlr_linux_drm_syncobj_surface_v1 {
|
|||
};
|
||||
|
||||
struct wlr_linux_drm_syncobj_surface_v1_commit {
|
||||
struct wlr_linux_drm_syncobj_surface_v1 *surface;
|
||||
struct wlr_surface *surface;
|
||||
struct wlr_drm_syncobj_timeline_waiter waiter;
|
||||
uint32_t cached_seq;
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ static struct wlr_linux_drm_syncobj_surface_v1 *surface_from_wlr_surface(
|
|||
}
|
||||
|
||||
static void surface_commit_destroy(struct wlr_linux_drm_syncobj_surface_v1_commit *commit) {
|
||||
wlr_surface_unlock_cached(commit->surface->surface, commit->cached_seq);
|
||||
wlr_surface_unlock_cached(commit->surface, commit->cached_seq);
|
||||
wl_list_remove(&commit->surface_destroy.link);
|
||||
wlr_drm_syncobj_timeline_waiter_finish(&commit->waiter);
|
||||
free(commit);
|
||||
|
|
@ -237,7 +237,7 @@ static bool lock_surface_commit(struct wlr_linux_drm_syncobj_surface_v1 *surface
|
|||
return false;
|
||||
}
|
||||
|
||||
commit->surface = surface;
|
||||
commit->surface = surface->surface;
|
||||
commit->cached_seq = wlr_surface_lock_pending(surface->surface);
|
||||
|
||||
commit->surface_destroy.notify = surface_commit_handle_surface_destroy;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ static void manager_create_transient_seat(struct wl_client *client,
|
|||
wl_resource_set_implementation(seat->resource, &transient_seat_impl,
|
||||
seat, transient_seat_handle_resource_destroy);
|
||||
|
||||
wl_list_init(&seat->seat_destroy.link);
|
||||
wl_signal_emit_mutable(&manager->events.create_seat, seat);
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -134,8 +134,11 @@ static void virtual_pointer_axis_source(struct wl_client *client,
|
|||
if (pointer == NULL) {
|
||||
return;
|
||||
}
|
||||
pointer->axis_event[pointer->axis].pointer = &pointer->pointer;
|
||||
pointer->axis_event[pointer->axis].source = source;
|
||||
int n_axis = sizeof(pointer->axis_event) / sizeof(pointer->axis_event[0]);
|
||||
for (int i = 0; i < n_axis; i++) {
|
||||
pointer->axis_event[i].pointer = &pointer->pointer;
|
||||
pointer->axis_event[i].source = source;
|
||||
}
|
||||
}
|
||||
|
||||
static void virtual_pointer_axis_stop(struct wl_client *client,
|
||||
|
|
|
|||
20
util/box.c
20
util/box.c
|
|
@ -19,16 +19,15 @@ void wlr_box_closest_point(const struct wlr_box *box, double x, double y,
|
|||
//
|
||||
// In order to be consistent with e.g. wlr_box_contains_point(),
|
||||
// this function returns a point inside the bottom and right edges
|
||||
// of the box by at least 1/65536 of a unit (pixel). 1/65536 is
|
||||
// of the box by at least 1/256 of a unit (pixel). 1/256 is
|
||||
// small enough to avoid a "dead zone" with high-resolution mice
|
||||
// but large enough to avoid rounding to zero (due to loss of
|
||||
// significant digits) in simple floating-point calculations.
|
||||
// but large enough to avoid rounding to zero in wl_fixed_from_double().
|
||||
|
||||
// find the closest x point
|
||||
if (x < box->x) {
|
||||
*dest_x = box->x;
|
||||
} else if (x > box->x + box->width - 1/65536.0) {
|
||||
*dest_x = box->x + box->width - 1/65536.0;
|
||||
} else if (x > box->x + box->width - 1/256.0) {
|
||||
*dest_x = box->x + box->width - 1/256.0;
|
||||
} else {
|
||||
*dest_x = x;
|
||||
}
|
||||
|
|
@ -36,8 +35,8 @@ void wlr_box_closest_point(const struct wlr_box *box, double x, double y,
|
|||
// find closest y point
|
||||
if (y < box->y) {
|
||||
*dest_y = box->y;
|
||||
} else if (y > box->y + box->height - 1/65536.0) {
|
||||
*dest_y = box->y + box->height - 1/65536.0;
|
||||
} else if (y > box->y + box->height - 1/256.0) {
|
||||
*dest_y = box->y + box->height - 1/256.0;
|
||||
} else {
|
||||
*dest_y = y;
|
||||
}
|
||||
|
|
@ -67,7 +66,12 @@ bool wlr_box_intersection(struct wlr_box *dest, const struct wlr_box *box_a,
|
|||
dest->width = x2 - x1;
|
||||
dest->height = y2 - y1;
|
||||
|
||||
return !wlr_box_empty(dest);
|
||||
if (wlr_box_empty(dest)) {
|
||||
*dest = (struct wlr_box){0};
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wlr_box_contains_point(const struct wlr_box *box, double x, double y) {
|
||||
|
|
|
|||
|
|
@ -602,7 +602,7 @@ xcursor_build_fullname(const char *dir, const char *subdir, const char *file)
|
|||
static const char *
|
||||
xcursor_next_path(const char *path)
|
||||
{
|
||||
char *colon = strchr(path, ':');
|
||||
const char *colon = strchr(path, ':');
|
||||
|
||||
if (!colon)
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -283,6 +283,8 @@ static bool xwm_selection_send_data(struct wlr_xwm_selection *selection,
|
|||
int p[2];
|
||||
if (pipe(p) == -1) {
|
||||
wlr_log_errno(WLR_ERROR, "pipe() failed");
|
||||
wl_array_release(&transfer->source_data);
|
||||
free(transfer);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ static void handle_server_start(struct wl_listener *listener, void *data) {
|
|||
static void xwayland_mark_ready(struct wlr_xwayland *xwayland) {
|
||||
assert(xwayland->server->wm_fd[0] >= 0);
|
||||
xwayland->xwm = xwm_create(xwayland, xwayland->server->wm_fd[0]);
|
||||
// xwm_create takes ownership of wm_fd[0] under all circumstances
|
||||
xwayland->server->wm_fd[0] = -1;
|
||||
|
||||
if (!xwayland->xwm) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -69,6 +72,11 @@ static void handle_shell_destroy(struct wl_listener *listener, void *data) {
|
|||
struct wlr_xwayland *xwayland =
|
||||
wl_container_of(listener, xwayland, shell_destroy);
|
||||
xwayland->shell_v1 = NULL;
|
||||
wl_list_remove(&xwayland->shell_destroy.link);
|
||||
// Will remove this list in handle_shell_destroy().
|
||||
// This ensures the link is always initialized and
|
||||
// avoids the need to keep check conditions in sync.
|
||||
wl_list_init(&xwayland->shell_destroy.link);
|
||||
}
|
||||
|
||||
void wlr_xwayland_destroy(struct wlr_xwayland *xwayland) {
|
||||
|
|
|
|||
|
|
@ -2470,6 +2470,7 @@ void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride,
|
|||
struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
|
||||
struct wlr_xwm *xwm = calloc(1, sizeof(*xwm));
|
||||
if (xwm == NULL) {
|
||||
close(wm_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2484,11 +2485,13 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
|
|||
|
||||
xwm->ping_timeout = 10000;
|
||||
|
||||
// xcb_connect_to_fd takes ownership of the FD regardless of success/failure
|
||||
xwm->xcb_conn = xcb_connect_to_fd(wm_fd, NULL);
|
||||
|
||||
int rc = xcb_connection_has_error(xwm->xcb_conn);
|
||||
if (rc) {
|
||||
wlr_log(WLR_ERROR, "xcb connect failed: %d", rc);
|
||||
xcb_disconnect(xwm->xcb_conn);
|
||||
free(xwm);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue