|
|
@ -139,8 +139,8 @@ static int xwm_data_source_read(int fd, uint32_t mask, void *data) {
|
|
|
|
goto error_out;
|
|
|
|
goto error_out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
wlr_log(L_DEBUG, "read %ld (available %zu, mask 0x%x) bytes: \"%.*s\"",
|
|
|
|
wlr_log(L_DEBUG, "read %ld bytes (available %zu, mask 0x%x)", len,
|
|
|
|
len, available, mask, (int)len, (char *)p);
|
|
|
|
available, mask);
|
|
|
|
|
|
|
|
|
|
|
|
transfer->source_data.size = current + len;
|
|
|
|
transfer->source_data.size = current + len;
|
|
|
|
if (transfer->source_data.size >= incr_chunk_size) {
|
|
|
|
if (transfer->source_data.size >= incr_chunk_size) {
|
|
|
@ -629,43 +629,6 @@ static void xwm_handle_selection_request(struct wlr_xwm *xwm,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int xwm_handle_selection_property_notify(struct wlr_xwm *xwm,
|
|
|
|
|
|
|
|
xcb_property_notify_event_t *event) {
|
|
|
|
|
|
|
|
struct wlr_xwm_selection *selections[] = {
|
|
|
|
|
|
|
|
&xwm->clipboard_selection,
|
|
|
|
|
|
|
|
&xwm->primary_selection,
|
|
|
|
|
|
|
|
&xwm->dnd_selection,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < sizeof(selections)/sizeof(selections[0]); ++i) {
|
|
|
|
|
|
|
|
struct wlr_xwm_selection *selection = selections[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (event->window == xwm->selection_window) {
|
|
|
|
|
|
|
|
if (event->state == XCB_PROPERTY_NEW_VALUE &&
|
|
|
|
|
|
|
|
event->atom == xwm->atoms[WL_SELECTION] &&
|
|
|
|
|
|
|
|
selection->incoming.incr) {
|
|
|
|
|
|
|
|
wlr_log(L_DEBUG, "get incr chunk");
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_xwm_selection_transfer *outgoing;
|
|
|
|
|
|
|
|
wl_list_for_each(outgoing, &selection->outgoing, outgoing_link) {
|
|
|
|
|
|
|
|
if (event->window == outgoing->request.requestor) {
|
|
|
|
|
|
|
|
if (event->state == XCB_PROPERTY_DELETE &&
|
|
|
|
|
|
|
|
event->atom == outgoing->request.property &&
|
|
|
|
|
|
|
|
outgoing->incr) {
|
|
|
|
|
|
|
|
xwm_send_incr_chunk(outgoing);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void xwm_selection_transfer_destroy_property_reply(
|
|
|
|
static void xwm_selection_transfer_destroy_property_reply(
|
|
|
|
struct wlr_xwm_selection_transfer *transfer) {
|
|
|
|
struct wlr_xwm_selection_transfer *transfer) {
|
|
|
|
free(transfer->property_reply);
|
|
|
|
free(transfer->property_reply);
|
|
|
@ -702,8 +665,10 @@ static int xwm_data_source_write(int fd, uint32_t mask, void *data) {
|
|
|
|
xwm_selection_transfer_remove_source(transfer);
|
|
|
|
xwm_selection_transfer_remove_source(transfer);
|
|
|
|
|
|
|
|
|
|
|
|
if (transfer->incr) {
|
|
|
|
if (transfer->incr) {
|
|
|
|
|
|
|
|
wlr_log(L_DEBUG, "deleting property");
|
|
|
|
xcb_delete_property(xwm->xcb_conn, transfer->selection->window,
|
|
|
|
xcb_delete_property(xwm->xcb_conn, transfer->selection->window,
|
|
|
|
xwm->atoms[WL_SELECTION]);
|
|
|
|
xwm->atoms[WL_SELECTION]);
|
|
|
|
|
|
|
|
xcb_flush(xwm->xcb_conn);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
wlr_log(L_DEBUG, "transfer complete");
|
|
|
|
wlr_log(L_DEBUG, "transfer complete");
|
|
|
|
xwm_selection_transfer_close_source_fd(transfer);
|
|
|
|
xwm_selection_transfer_close_source_fd(transfer);
|
|
|
@ -731,6 +696,38 @@ static void xwm_write_property(struct wlr_xwm_selection_transfer *transfer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void xwm_get_incr_chunk(struct wlr_xwm_selection_transfer *transfer) {
|
|
|
|
|
|
|
|
struct wlr_xwm *xwm = transfer->selection->xwm;
|
|
|
|
|
|
|
|
wlr_log(L_DEBUG, "xwm_get_incr_chunk");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xcb_get_property_cookie_t cookie = xcb_get_property(xwm->xcb_conn,
|
|
|
|
|
|
|
|
0, // delete
|
|
|
|
|
|
|
|
transfer->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) {
|
|
|
|
|
|
|
|
wlr_log(L_ERROR, "cannot get selection property");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//dump_property(xwm, xwm->atoms[WL_SELECTION], reply);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (xcb_get_property_value_length(reply) > 0) {
|
|
|
|
|
|
|
|
/* Reply's ownership is transferred to xwm, which is responsible
|
|
|
|
|
|
|
|
* for freeing it */
|
|
|
|
|
|
|
|
xwm_write_property(transfer, reply);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
wlr_log(L_DEBUG, "transfer complete");
|
|
|
|
|
|
|
|
xwm_selection_transfer_close_source_fd(transfer);
|
|
|
|
|
|
|
|
free(reply);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void xwm_selection_get_data(struct wlr_xwm_selection *selection) {
|
|
|
|
static void xwm_selection_get_data(struct wlr_xwm_selection *selection) {
|
|
|
|
struct wlr_xwm *xwm = selection->xwm;
|
|
|
|
struct wlr_xwm *xwm = selection->xwm;
|
|
|
|
|
|
|
|
|
|
|
@ -1074,6 +1071,42 @@ static int xwm_handle_xfixes_selection_notify(struct wlr_xwm *xwm,
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int xwm_handle_selection_property_notify(struct wlr_xwm *xwm,
|
|
|
|
|
|
|
|
xcb_property_notify_event_t *event) {
|
|
|
|
|
|
|
|
struct wlr_xwm_selection *selections[] = {
|
|
|
|
|
|
|
|
&xwm->clipboard_selection,
|
|
|
|
|
|
|
|
&xwm->primary_selection,
|
|
|
|
|
|
|
|
&xwm->dnd_selection,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < sizeof(selections)/sizeof(selections[0]); ++i) {
|
|
|
|
|
|
|
|
struct wlr_xwm_selection *selection = selections[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (event->window == selection->window) {
|
|
|
|
|
|
|
|
if (event->state == XCB_PROPERTY_NEW_VALUE &&
|
|
|
|
|
|
|
|
event->atom == xwm->atoms[WL_SELECTION] &&
|
|
|
|
|
|
|
|
selection->incoming.incr) {
|
|
|
|
|
|
|
|
xwm_get_incr_chunk(&selection->incoming);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_xwm_selection_transfer *outgoing;
|
|
|
|
|
|
|
|
wl_list_for_each(outgoing, &selection->outgoing, outgoing_link) {
|
|
|
|
|
|
|
|
if (event->window == outgoing->request.requestor) {
|
|
|
|
|
|
|
|
if (event->state == XCB_PROPERTY_DELETE &&
|
|
|
|
|
|
|
|
event->atom == outgoing->request.property &&
|
|
|
|
|
|
|
|
outgoing->incr) {
|
|
|
|
|
|
|
|
xwm_send_incr_chunk(outgoing);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int xwm_handle_selection_event(struct wlr_xwm *xwm,
|
|
|
|
int xwm_handle_selection_event(struct wlr_xwm *xwm,
|
|
|
|
xcb_generic_event_t *event) {
|
|
|
|
xcb_generic_event_t *event) {
|
|
|
|
if (xwm->seat == NULL) {
|
|
|
|
if (xwm->seat == NULL) {
|
|
|
|