aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/window/window.c87
1 files changed, 52 insertions, 35 deletions
diff --git a/src/window/window.c b/src/window/window.c
index 60f6277..481d17a 100644
--- a/src/window/window.c
+++ b/src/window/window.c
@@ -1095,12 +1095,17 @@ bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback,
mgl_clock timeout_timer;
mgl_clock_init(&timeout_timer);
+ bool success = false;
const double timeout_seconds = 5.0;
while(mgl_clock_get_elapsed_time_seconds(&timeout_timer) < timeout_seconds) {
+ /* TODO: Wait for SelectionNotify event instead */
while(XCheckTypedWindowEvent(context->connection, self->window, SelectionNotify, &xev)) {
+ if(mgl_clock_get_elapsed_time_seconds(&timeout_timer) >= timeout_seconds)
+ break;
+
if(!xev.xselection.property)
- return false;
+ continue;
if(!xev.xselection.target || xev.xselection.selection != x11_context->clipboard_atom)
continue;
@@ -1108,87 +1113,99 @@ bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback,
Atom type = None;
int format;
unsigned long items;
- unsigned long remaining_bytes = 32768;
+ unsigned long remaining_bytes = 0;
unsigned char *data = NULL;
if(xev.xselection.target == XA_TARGETS && requested_clipboard_type == None) {
- if(XGetWindowProperty(context->connection, xev.xselection.requestor, xev.xselection.property, 0, 1024, False, AnyPropertyType, &type, &format, &items, &remaining_bytes, &data) == Success && data) {
- bool got_clipboard = false;
+ /* TODO: Wait for PropertyNotify event instead */
+ if(XGetWindowProperty(context->connection, xev.xselection.requestor, xev.xselection.property, 0, 1024, False, PropertyNewValue, &type, &format, &items, &remaining_bytes, &data) == Success && data) {
if(type != x11_context->incr_atom && type == XA_ATOM && format == 32) {
requested_clipboard_type = find_matching_atom(supported_clipboard_types, num_supported_clipboard_types, (Atom*)data, items);
if(requested_clipboard_type == None) {
/* Pasting clipboard data type we dont support */
XFree(data);
- return false;
+ goto done;
} else {
XConvertSelection(context->connection, x11_context->clipboard_atom, requested_clipboard_type, x11_context->clipboard_atom, self->window, CurrentTime);
}
}
+
XFree(data);
}
} else if(xev.xselection.target == requested_clipboard_type) {
- unsigned int total_size = 0;
- unsigned int total_offset = 0;
+ bool got_data = false;
+ long chunk_size = 65536;
+
+ //XDeleteProperty(context->connection, self->window, x11_context->incr_atom);
+ //XFlush(context->connection);
+
while(mgl_clock_get_elapsed_time_seconds(&timeout_timer) < timeout_seconds) {
- bool success = false;
unsigned long offset = 0;
/* offset is specified in XGetWindowProperty as a multiple of 32-bit (4 bytes) */
- while(XGetWindowProperty(context->connection, xev.xselection.requestor, xev.xselection.property, offset/4, 32768, True, AnyPropertyType, &type, &format, &items, &remaining_bytes, &data) == Success) {
+ /* TODO: Wait for PropertyNotify event instead */
+ while(XGetWindowProperty(context->connection, xev.xselection.requestor, xev.xselection.property, offset/4, chunk_size, True, PropertyNewValue, &type, &format, &items, &remaining_bytes, &data) == Success) {
if(mgl_clock_get_elapsed_time_seconds(&timeout_timer) >= timeout_seconds)
break;
if(type == x11_context->incr_atom) {
+ if(data)
+ chunk_size = *(long*)data;
XDeleteProperty(context->connection, self->window, x11_context->incr_atom);
- /* TODO: */
- /*receive_property_notify_event(self);*/
- total_size = *(unsigned long*)data;
- offset = 0;
- type = None;
+ XFlush(context->connection);
XFree(data);
data = NULL;
- continue;
+ break;
+ } else if(type == requested_clipboard_type) {
+ got_data = true;
}
- const size_t num_items_bytes = items * (format/8);
- const mgl_clipboard_type clipboard_type = atom_type_to_supported_clipboard_type(x11_context, type, format);
- if(data && num_items_bytes > 0 && clipboard_type != -1) {
- if(!callback(data, num_items_bytes, clipboard_type, userdata)) {
+ if(!got_data && items == 0) {
+ XDeleteProperty(context->connection, self->window, type);
+ XFlush(context->connection);
+ if(data) {
XFree(data);
- break;
+ data = NULL;
+ }
+ break;
+ }
+
+ const size_t num_items_bytes = items * (format/8); /* format is the bit size of the data */
+ if(got_data) {
+ const mgl_clipboard_type clipboard_type = atom_type_to_supported_clipboard_type(x11_context, type, format);
+ if(data && num_items_bytes > 0 && clipboard_type != -1) {
+ if(!callback(data, num_items_bytes, clipboard_type, userdata)) {
+ XFree(data);
+ goto done;
+ }
}
}
- offset += num_items_bytes; // format is the bit size of the data
- total_offset += num_items_bytes;
+ offset += num_items_bytes;
if(data) {
XFree(data);
data = NULL;
}
- if((total_size == 0 && remaining_bytes == 0) || (total_size > 0 && total_offset >= total_size)) {
+ if(got_data && num_items_bytes == 0/* && format == 8*/) {
success = true;
- break;
+ goto done;
}
if(remaining_bytes == 0)
- break;
- }
-
- if((total_size == 0 && remaining_bytes != 0) || (total_size > 0 && total_offset < total_size)) {
- offset = 0;
- XDeleteProperty(context->connection, self->window, x11_context->incr_atom);
- continue;
+ break;
}
-
- return success;
}
+
+ goto done;
}
}
}
- /* Timed out waiting for clipboard */
- return false;
+ done:
+ if(requested_clipboard_type)
+ XDeleteProperty(context->connection, self->window, requested_clipboard_type);
+ return success;
}
typedef struct {