summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2025-01-16 06:05:57 +0100
committerMitya Selivanov <automainint@guattari.tech>2025-01-16 06:05:57 +0100
commitbf17379743b283937a12340717bffccf619cc864 (patch)
tree634dd51c2435fa42be0b94941e5a3e4a538e711d
parent41abfb196c524cf16107675b8e5b356827a04cd0 (diff)
downloadreduced_system_layer-bf17379743b283937a12340717bffccf619cc864.zip
Drag and drop fixes
-rw-r--r--examples/ui.c9
-rw-r--r--reduced_system_layer.c122
2 files changed, 80 insertions, 51 deletions
diff --git a/examples/ui.c b/examples/ui.c
index 0e8e29e..6738d7e 100644
--- a/examples/ui.c
+++ b/examples/ui.c
@@ -213,6 +213,15 @@ void update_and_render_frame(void) {
}
}
+ if (g_platform.files_dropped && g_platform.num_drop_files > 0) {
+ text_len = g_platform.drop_files[0].data_size;
+ if (text_len > (i64) (sizeof text / sizeof *text))
+ text_len = sizeof text / sizeof *text;
+
+ for (i64 i = 0; i < text_len; ++i)
+ text[i] = g_platform.drop_files[0].data[i];
+ }
+
draw_text_area(RGB(0.f, 0.f, 0.f), x0 + 8, y0 - 8, w, h, 10., 10., text_len, text);
draw_text_area((Brush) { .color = with_alpha(color, 1.f) }, x0, y0, w, h, 10., 10., text_len, text);
draw_selection_cursor((Brush) { .xor_color = 1, .color = { 1.f, 1.f, 1.f, 1.f } }, x0, y0, w, h, 10., 10., cursor, selection, text_len, text);
diff --git a/reduced_system_layer.c b/reduced_system_layer.c
index 8853166..b128f1b 100644
--- a/reduced_system_layer.c
+++ b/reduced_system_layer.c
@@ -28,7 +28,7 @@
// To-Do list
//
// - Work in progress
-// - X11, Web - Drop files
+// - Drop files - Web
// - Graphics - Anti-aliasing
// - Plain buffer allocator
// - Logging
@@ -81,16 +81,9 @@
// - Particles
// - Graph
// - Sine Wave
-// - Window
-// - X11
-// - WebAssembly
-// - Sound
-// - ALSA
-// - Web audio
-// - Networking
-// - Unix UDP sockets
-// - UTF-8
-// - Testing
+// - Utility
+// - UTF-8
+// - Testing
// - Graphics
// - Font
// - Adaptive resolution
@@ -98,6 +91,12 @@
// - Relative coordinates
// - Blending
// - Self-contained impl
+// - System
+// - Window - X11, Web
+// - Sound - ALSA, Web
+// - Networking
+// - Unix UDP sockets
+// - Drop files - X11
//
// ----------------------------------------------------------------
//
@@ -488,7 +487,7 @@ typedef struct {
} Input_Key;
typedef struct {
- i64 name_size;
+ i64 name_len;
c8 *name;
i64 data_size;
u8 *data;
@@ -765,7 +764,7 @@ static i64 drop_files_data_size_(i64 num) {
for (i64 i = 0; i < num; ++i)
data_size +=
- align_size_(g_platform.drop_files[i].name_size) +
+ align_size_(g_platform.drop_files[i].name_len) +
align_size_(g_platform.drop_files[i].data_size);
return data_size;
@@ -803,9 +802,9 @@ static void drop_files_empty_after_(i64 index) {
}
for (i64 i = index + 1; i < g_platform.num_drop_files; ++i) {
- if (g_platform.drop_files[i].name_size != 0) {
+ if (g_platform.drop_files[i].name_len != 0) {
LOG_ERROR("Sanity");
- g_platform.drop_files[i].name_size = 0;
+ g_platform.drop_files[i].name_len = 0;
}
if (g_platform.drop_files[i].data_size != 0) {
@@ -829,7 +828,7 @@ static void drop_files_empty_data_after_(i64 index) {
}
}
-static void drop_files_set_name_(i64 index, i64 name_size, c8 *name) {
+static void drop_files_set_name_(i64 index, i64 name_len, c8 *name) {
if (g_platform.drop_files == NULL) {
LOG_ERROR("Sanity");
return;
@@ -840,17 +839,17 @@ static void drop_files_set_name_(i64 index, i64 name_size, c8 *name) {
i64 offset = drop_files_data_size_(index);
i64 available = DROP_FILES_BUFFER_SIZE - offset - g_platform.num_drop_files * sizeof(Drop_File);
- if (available < name_size + 1) {
+ if (available < name_len + 1) {
LOG_ERROR("Out of memory");
return;
}
- g_platform.drop_files[index].name_size = name_size + 1;
- g_platform.drop_files[index].name = (c8 *) _drop_files_buffer + offset;
+ g_platform.drop_files[index].name_len = name_len + 1;
+ g_platform.drop_files[index].name = (c8 *) _drop_files_buffer + offset;
- for (i64 i = 0; i < name_size; ++i)
+ for (i64 i = 0; i < name_len; ++i)
g_platform.drop_files[index].name[i] = name[i];
- g_platform.drop_files[index].name[name_size] = '\0';
+ g_platform.drop_files[index].name[name_len] = '\0';
}
static void drop_files_set_data_(i64 index, i64 data_size) {
@@ -1345,6 +1344,9 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) {
#include <X11/Xutil.h>
#include <X11/Xatom.h>
+#define FILE_PATH_PREFIX_ "file://"
+#define FILE_PATH_PREFIX_LEN_ ((sizeof FILE_PATH_PREFIX_) - 1)
+
static i64 _frame_time = 0;
static XImage _image = {0};
static Display *_display = NULL;
@@ -1384,6 +1386,13 @@ static u32 _pixels_scaled [MAX_NUM_PIXELS] = {0};
static u32 _pixels_internal [MAX_NUM_PIXELS] = {0};
static c8 _clipboard_buffer [MAX_CLIPBOARD_SIZE] = {0};
+static b8 sub_str_eq_(c8 *a, c8 *b, i64 len) {
+ for (i64 i = 0; i < len; ++i)
+ if (a[i] != b[i])
+ return 0;
+ return 1;
+}
+
void p_init(void) {
_display = XOpenDisplay(NULL);
@@ -1852,7 +1861,18 @@ i32 p_handle_events(void) {
for (i64 i = 0; i < len; ++i)
if (data[i] == '\n' || i + 1 == len) {
- drop_files_set_name_(index, i - offset, (c8 *) data + offset);
+ c8 *name = (c8 *) data + offset;
+
+ if (sub_str_eq_(name, FILE_PATH_PREFIX_, FILE_PATH_PREFIX_LEN_))
+ name = name + FILE_PATH_PREFIX_LEN_;
+
+ i64 name_len = 0;
+ while (name_len < (c8 *) data + len - name
+ && name[name_len] != '\n'
+ && name[name_len] != '\r')
+ ++name_len;
+
+ drop_files_set_name_(index, name_len, name);
++index;
offset = i + 1;
@@ -1861,6 +1881,35 @@ i32 p_handle_events(void) {
XFree(data);
}
+ g_platform.files_dropped = 1;
+
+ if (g_platform.drop_files == NULL)
+ LOG_ERROR("No drop files.");
+ else
+ for (i64 i = 0; i < g_platform.num_drop_files; ++i) {
+ FILE *f = fopen(g_platform.drop_files[i].name, "rb");
+
+ if (f != NULL) {
+ i64 size = 0;
+ struct stat info;
+ if (fstat(fileno(f), &info) == 0 && S_ISREG(info.st_mode))
+ size = (i64) info.st_size;
+ else
+ LOG_ERROR("Unable to get the file info: %s", g_platform.drop_files[i].name);
+
+ drop_files_set_data_(i, size);
+
+ i64 num = (i64) fread(g_platform.drop_files[i].data, 1, g_platform.drop_files[i].data_size + 1, f);
+ fclose(f);
+
+ if (num != g_platform.drop_files[i].data_size) {
+ LOG_ERROR("Unable to read: %s", g_platform.drop_files[i].name);
+ drop_files_set_data_(i, 0);
+ }
+ } else
+ LOG_ERROR("Unable to open: %s", g_platform.drop_files[i].name);
+ }
+
if (_dnd_version >= 2) {
XSendEvent(
_display,
@@ -2052,35 +2101,6 @@ i32 p_handle_events(void) {
XSendEvent(_display, _dnd_source, False, NoEventMask, &reply);
XFlush(_display);
} else if (ev.xclient.message_type == _dnd_drop) {
- g_platform.files_dropped = 1;
-
- if (g_platform.drop_files == NULL)
- LOG_ERROR("No drop files.");
- else
- for (i64 i = 0; i < g_platform.num_drop_files; ++i) {
- FILE *f = fopen(g_platform.drop_files[i].name, "rb");
-
- if (f != NULL) {
- i64 size = 0;
- struct stat info;
- if (fstat(fileno(f), &info) == 0 && S_ISREG(info.st_mode))
- size = (i64) info.st_size;
- else
- LOG_ERROR("Unable to get the file info: %s", g_platform.drop_files[i].name);
-
- drop_files_set_data_(i, size);
-
- i64 num = (i64) fread(g_platform.drop_files[i].data, 1, g_platform.drop_files[i].data_size + 1, f);
- fclose(f);
-
- if (num != g_platform.drop_files[i].data_size) {
- LOG_ERROR("Unable to read the file: %s", g_platform.drop_files[i].name);
- drop_files_set_data_(i, 0);
- }
- } else
- LOG_ERROR("Unable to open the file: %s", g_platform.drop_files[i].name);
- }
-
if (_dnd_format)
XConvertSelection(
_display,