From 3c4deef40ccb57e46e3da30c76dee1e5011d7fd7 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 5 Nov 2022 11:18:03 +0100 Subject: Only allow text in mgl_window_get_clipboard_string --- include/mgl/window/window.h | 14 +++++++++----- src/window/window.c | 41 ++++++++++++++++++++++++++++------------- tests/main.c | 2 +- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/include/mgl/window/window.h b/include/mgl/window/window.h index 34f8cbb..ed50dcb 100644 --- a/include/mgl/window/window.h +++ b/include/mgl/window/window.h @@ -56,12 +56,15 @@ typedef struct { } mgl_window_create_params; typedef enum { - MGL_CLIPBOARD_TYPE_STRING, - MGL_CLIPBOARD_TYPE_IMAGE_PNG, - MGL_CLIPBOARD_TYPE_IMAGE_JPG, - MGL_CLIPBOARD_TYPE_IMAGE_GIF, + MGL_CLIPBOARD_TYPE_STRING = 1 << 0, + MGL_CLIPBOARD_TYPE_IMAGE_PNG = 1 << 1, + MGL_CLIPBOARD_TYPE_IMAGE_JPG = 1 << 2, + MGL_CLIPBOARD_TYPE_IMAGE_GIF = 1 << 3, } mgl_clipboard_type; +#define MGL_CLIPBOARD_TYPE_ALL 0xFFFFFFFF +#define MGL_CLIPBOARD_TYPE_IMAGE (MGL_CLIPBOARD_TYPE_IMAGE_PNG | MGL_CLIPBOARD_TYPE_IMAGE_JPG | MGL_CLIPBOARD_TYPE_IMAGE_GIF) + /* Return true to continue. |mgl_window_get_clipboard| returns false if this returns false. Note: |size| is the size of the current data, not the total data (if the callback only contains a part of the data). @@ -115,7 +118,8 @@ void mgl_window_set_size(mgl_window *self, mgl_vec2i size); void mgl_window_set_size_limits(mgl_window *self, mgl_vec2i minimum, mgl_vec2i maximum); void mgl_window_set_clipboard(mgl_window *self, const char *str, size_t size); -bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, void *userdata); +/* clipboard_types should be a bit-or of mgl_clipboard_type */ +bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, void *userdata, uint32_t clipboard_types); /* A new string is allocated and the pointer is copied to |str| with the size returned in |size|. |str| should be deallocated with |free| by the user. diff --git a/src/window/window.c b/src/window/window.c index 1817a2f..8d63650 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -1028,7 +1028,7 @@ static mgl_clipboard_type atom_type_to_supported_clipboard_type(x11_context *x11 } } -bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, void *userdata) { +bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, void *userdata, uint32_t clipboard_types) { assert(callback); mgl_context *context = mgl_get_context(); @@ -1052,16 +1052,28 @@ bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, /* Sorted by preference */ /* TODO: Support more types (BITMAP?, PIXMAP?) */ - const Atom supported_clipboard_types[] = { - x11_context->utf8_string_atom, - XA_STRING, - x11_context->text_atom, - x11_context->image_png, - x11_context->image_jpg, - x11_context->image_jpeg, - x11_context->image_gif, - }; - const unsigned long num_supported_clipboard_types = sizeof(supported_clipboard_types) / sizeof(supported_clipboard_types[0]); + Atom supported_clipboard_types[7]; + + int supported_clipboard_type_index = 0; + if(clipboard_types & MGL_CLIPBOARD_TYPE_STRING) { + supported_clipboard_types[supported_clipboard_type_index++] = x11_context->utf8_string_atom; + supported_clipboard_types[supported_clipboard_type_index++] = XA_STRING; + supported_clipboard_types[supported_clipboard_type_index++] = x11_context->text_atom; + } + + if(clipboard_types & MGL_CLIPBOARD_TYPE_IMAGE_PNG) { + supported_clipboard_types[supported_clipboard_type_index++] = x11_context->image_png; + } + + if(clipboard_types & MGL_CLIPBOARD_TYPE_IMAGE_JPG) { + supported_clipboard_types[supported_clipboard_type_index++] = x11_context->image_jpeg; + } + + if(clipboard_types & MGL_CLIPBOARD_TYPE_IMAGE_GIF) { + supported_clipboard_types[supported_clipboard_type_index++] = x11_context->image_gif; + } + + const unsigned long num_supported_clipboard_types = supported_clipboard_type_index; Atom requested_clipboard_type = None; const Atom XA_TARGETS = XInternAtom(context->connection, "TARGETS", False); @@ -1073,7 +1085,10 @@ bool mgl_window_get_clipboard(mgl_window *self, mgl_clipboard_callback callback, const double timeout_seconds = 5.0; while(mgl_clock_get_elapsed_time_seconds(&timeout_timer) < timeout_seconds) { while(XCheckTypedWindowEvent(context->connection, self->window, SelectionNotify, &xev)) { - if(!xev.xselection.property || !xev.xselection.target || xev.xselection.selection != x11_context->clipboard_atom) + if(!xev.xselection.property) + return false; + + if(!xev.xselection.target || xev.xselection.selection != x11_context->clipboard_atom) continue; Atom type = None; @@ -1201,7 +1216,7 @@ bool mgl_window_get_clipboard_string(mgl_window *self, char **str, size_t *size) ClipboardStringCallbackData callback_data; callback_data.str = str; callback_data.size = size; - const bool success = mgl_window_get_clipboard(self, clipboard_copy_string_callback, &callback_data); + const bool success = mgl_window_get_clipboard(self, clipboard_copy_string_callback, &callback_data, MGL_CLIPBOARD_TYPE_STRING); if(!success) { free(*str); *size = 0; diff --git a/tests/main.c b/tests/main.c index f1fad72..ee632a7 100644 --- a/tests/main.c +++ b/tests/main.c @@ -292,7 +292,7 @@ int main(int argc, char **argv) { mgl_window_set_clipboard(&window, str, strlen(str)); fprintf(stderr, "Copied '%s' to the clipboard\n", str); } else if(event.key.code == MGL_KEY_V) { - if(mgl_window_get_clipboard(&window, clipboard_callback, NULL)) { + if(mgl_window_get_clipboard(&window, clipboard_callback, NULL, MGL_CLIPBOARD_TYPE_ALL)) { fprintf(stderr, "Successfully copied clipboard!\n"); } else { fprintf(stderr, "Failed to copy clipboard!\n"); -- cgit v1.2.3