mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-29 16:05:59 +01:00
xwm: get selection data
This commit is contained in:
parent
39e2ea8420
commit
ea6f77b484
3 changed files with 94 additions and 1 deletions
|
@ -1,5 +1,6 @@
|
||||||
#define _XOPEN_SOURCE 700
|
#define _XOPEN_SOURCE 700
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -35,8 +36,95 @@ static void xwm_handle_selection_request(struct wlr_xwm *xwm,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int writable_callback(int fd, uint32_t mask, void *data) {
|
||||||
|
struct wlr_xwm *xwm = data;
|
||||||
|
|
||||||
|
unsigned char *property = xcb_get_property_value(xwm->property_reply);
|
||||||
|
int remainder = xcb_get_property_value_length(xwm->property_reply) -
|
||||||
|
xwm->property_start;
|
||||||
|
|
||||||
|
int len = write(fd, property + xwm->property_start, remainder);
|
||||||
|
if (len == -1) {
|
||||||
|
free(xwm->property_reply);
|
||||||
|
xwm->property_reply = NULL;
|
||||||
|
if (xwm->property_source) {
|
||||||
|
wl_event_source_remove(xwm->property_source);
|
||||||
|
}
|
||||||
|
xwm->property_source = NULL;
|
||||||
|
close(fd);
|
||||||
|
wlr_log(L_ERROR, "write error to target fd: %m\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(L_DEBUG, "wrote %d (chunk size %d) of %d bytes\n",
|
||||||
|
xwm->property_start + len,
|
||||||
|
len, xcb_get_property_value_length(xwm->property_reply));
|
||||||
|
|
||||||
|
xwm->property_start += len;
|
||||||
|
if (len == remainder) {
|
||||||
|
free(xwm->property_reply);
|
||||||
|
xwm->property_reply = NULL;
|
||||||
|
if (xwm->property_source) {
|
||||||
|
wl_event_source_remove(xwm->property_source);
|
||||||
|
}
|
||||||
|
xwm->property_source = NULL;
|
||||||
|
|
||||||
|
if (xwm->incr) {
|
||||||
|
xcb_delete_property(xwm->xcb_conn,
|
||||||
|
xwm->selection_window,
|
||||||
|
xwm->atoms[WL_SELECTION]);
|
||||||
|
} else {
|
||||||
|
wlr_log(L_DEBUG, "transfer complete\n");
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xwm_write_property(struct wlr_xwm *xwm,
|
||||||
|
xcb_get_property_reply_t *reply) {
|
||||||
|
xwm->property_start = 0;
|
||||||
|
xwm->property_reply = reply;
|
||||||
|
writable_callback(xwm->data_source_fd, WL_EVENT_WRITABLE, xwm);
|
||||||
|
|
||||||
|
if (xwm->property_reply) {
|
||||||
|
struct wl_event_loop *loop =
|
||||||
|
wl_display_get_event_loop(xwm->xwayland->wl_display);
|
||||||
|
xwm->property_source =
|
||||||
|
wl_event_loop_add_fd(loop,
|
||||||
|
xwm->data_source_fd,
|
||||||
|
WL_EVENT_WRITABLE,
|
||||||
|
writable_callback, xwm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void xwm_get_selection_data(struct wlr_xwm *xwm) {
|
static void xwm_get_selection_data(struct wlr_xwm *xwm) {
|
||||||
wlr_log(L_DEBUG, "TODO: GET SELECTION DATA");
|
xcb_get_property_cookie_t cookie =
|
||||||
|
xcb_get_property(xwm->xcb_conn,
|
||||||
|
1, // delete
|
||||||
|
xwm->selection_window,
|
||||||
|
xwm->atoms[WL_SELECTION],
|
||||||
|
XCB_GET_PROPERTY_TYPE_ANY,
|
||||||
|
0, // offset
|
||||||
|
0x1fffffff // length
|
||||||
|
);
|
||||||
|
|
||||||
|
xcb_get_property_reply_t *reply =
|
||||||
|
xcb_get_property_reply(xwm->xcb_conn, cookie, NULL);
|
||||||
|
|
||||||
|
if (reply == NULL) {
|
||||||
|
return;
|
||||||
|
} else if (reply->type == xwm->atoms[INCR]) {
|
||||||
|
xwm->incr = 1;
|
||||||
|
free(reply);
|
||||||
|
} else {
|
||||||
|
xwm->incr = 0;
|
||||||
|
// reply's ownership is transferred to wm, which is responsible
|
||||||
|
// for freeing it
|
||||||
|
xwm_write_property(xwm, reply);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct x11_data_source {
|
struct x11_data_source {
|
||||||
|
|
|
@ -47,6 +47,7 @@ const char *atom_map[ATOM_LAST] = {
|
||||||
"_WL_SELECTION",
|
"_WL_SELECTION",
|
||||||
"TARGETS",
|
"TARGETS",
|
||||||
"CLIPBOARD_MANAGER",
|
"CLIPBOARD_MANAGER",
|
||||||
|
"INCR",
|
||||||
};
|
};
|
||||||
|
|
||||||
/* General helpers */
|
/* General helpers */
|
||||||
|
|
|
@ -35,6 +35,7 @@ enum atom_name {
|
||||||
WL_SELECTION,
|
WL_SELECTION,
|
||||||
TARGETS,
|
TARGETS,
|
||||||
CLIPBOARD_MANAGER,
|
CLIPBOARD_MANAGER,
|
||||||
|
INCR,
|
||||||
ATOM_LAST,
|
ATOM_LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,6 +67,9 @@ struct wlr_xwm {
|
||||||
xcb_timestamp_t selection_timestamp;
|
xcb_timestamp_t selection_timestamp;
|
||||||
int incr;
|
int incr;
|
||||||
int data_source_fd;
|
int data_source_fd;
|
||||||
|
int property_start;
|
||||||
|
xcb_get_property_reply_t *property_reply;
|
||||||
|
struct wl_event_source *property_source;
|
||||||
|
|
||||||
struct wlr_xwayland_surface *focus_surface;
|
struct wlr_xwayland_surface *focus_surface;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue