From b4ef9730e22e3232415c89ca288b6d3f1a7f5e4b Mon Sep 17 00:00:00 2001 From: Aki Date: Wed, 25 Aug 2021 19:34:54 +0200 Subject: Added naive support for remaining usual selections --- clipfs.c | 68 ++++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/clipfs.c b/clipfs.c index 427a8bc..303defd 100644 --- a/clipfs.c +++ b/clipfs.c @@ -11,11 +11,14 @@ struct selection { + const char * name; uint32_t len; char * data; + xcb_atom_t atom; }; -void update_selection(void); +int get_selection_index(const char *); +void update_selection(int); xcb_atom_t get_atom(xcb_connection_t *, const char *); int clip_getattr(const char *, struct stat *, struct fuse_file_info *); int clip_readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags); @@ -34,7 +37,11 @@ const struct fuse_operations clip_ops = { static xcb_connection_t * c; static xcb_screen_t * s; static xcb_window_t w; -static struct selection x = {.len = 0, .data = NULL}; +static struct selection x[] = { + {.name = "primary", .len = 0, .data = NULL}, + {.name = "secondary", .len = 0, .data = NULL}, + {.name = "clipboard", .len = 0, .data = NULL}, +}; int main(int argc, char ** argv) @@ -45,17 +52,29 @@ int main(int argc, char ** argv) xcb_create_window( c, XCB_COPY_FROM_PARENT, w, s->root, 0, 0, 1, 1, 0, XCB_COPY_FROM_PARENT, s->root_visual, mask, values); xcb_flush(c); + x[0].atom = get_atom(c, "PRIMARY"); + x[1].atom = get_atom(c, "PRIMARY"); // TODO: This is intentional until update can recognize missing selection. + x[2].atom = get_atom(c, "CLIPBOARD"); fuse_main(argc, argv, &clip_ops, NULL); xcb_disconnect(c); } -void update_selection(void) +int get_selection_index(const char * path) +{ + for (int i = 0; i < 3; ++i) + if (0 == strcmp(path + 1, x[i].name)) + return i; + return -ENOENT; +} + + +void update_selection(const int i) { xcb_atom_t TARGET_PROPERTY = get_atom(c, "_TARGET_SELECTION"); xcb_atom_t UTF8_STRING = get_atom(c, "UTF8_STRING"); // TODO: Actually, focus on "rawest" format at first. // TODO-maybe: Look for the selection owner first? - xcb_convert_selection(c, w, XCB_ATOM_PRIMARY, UTF8_STRING, TARGET_PROPERTY, XCB_CURRENT_TIME); + xcb_convert_selection(c, w, x[i].atom, UTF8_STRING, TARGET_PROPERTY, XCB_CURRENT_TIME); xcb_flush(c); xcb_generic_event_t * e; int done = 0; // TODO: Look into continuous notifications and keeping the data somewhere? @@ -69,17 +88,17 @@ void update_selection(void) continue; } xcb_selection_notify_event_t * n = (xcb_selection_notify_event_t *) e; - if (XCB_ATOM_PRIMARY == n->selection && XCB_NONE != n->property) + if (x[i].atom == n->selection && XCB_NONE != n->property) { xcb_icccm_get_text_property_reply_t prop; xcb_get_property_cookie_t cookie = xcb_icccm_get_text_property(c, n->requestor, n->property); if (xcb_icccm_get_text_property_reply(c, cookie, &prop, NULL)) { - x.data = realloc(x.data, prop.name_len); - if (NULL == x.data) - x.len = 0; - x.len = prop.name_len; - memcpy(x.data, prop.name, prop.name_len); + x[i].data = realloc(x[i].data, prop.name_len); + if (NULL == x[i].data) + x[i].len = 0; + x[i].len = prop.name_len; + memcpy(x[i].data, prop.name, prop.name_len); xcb_icccm_get_text_property_reply_wipe(&prop); xcb_delete_property(c, n->requestor, n->property); done = 1; @@ -103,21 +122,22 @@ xcb_atom_t get_atom(xcb_connection_t * c, const char * name) int clip_getattr(const char * path, struct stat * st, struct fuse_file_info * fi) { (void) fi; - update_selection(); // TODO: The content is updated way too often. memset(st, 0, sizeof(struct stat)); if (0 == strcmp(path, "/")) { st->st_mode = S_IFDIR | 0755; st->st_nlink = 2; } - else if (0 == strcmp(path + 1, "primary")) + else { + const int i = get_selection_index(path); + if (-ENOENT == i) + return -ENOENT; + update_selection(i); // TODO: The content is updated way too often. st->st_mode = S_IFREG | 0444; st->st_nlink = 1; - st->st_size = x.len; + st->st_size = x[i].len; } - else - return -ENOENT; return 0; } @@ -133,14 +153,15 @@ int clip_readdir( return -ENOENT; filler(buf, ".", NULL, 0, 0); filler(buf, "..", NULL, 0, 0); - filler(buf, "primary", NULL, 0, 0); + for (int i = 0; i < 3; ++i) + filler(buf, x[i].name, NULL, 0, 0); return 0; } int clip_open(const char * path, struct fuse_file_info * fi) { - if (0 != strcmp(path + 1, "primary")) + if (-ENOENT == get_selection_index(path)) return -ENOENT; if (O_RDONLY != (fi->flags & O_ACCMODE)) return -EACCES; @@ -151,14 +172,15 @@ int clip_open(const char * path, struct fuse_file_info * fi) int clip_read(const char * path, char * buf, size_t size, off_t offset, struct fuse_file_info * fi) { (void) fi; - if (0 != strcmp(path + 1, "primary")) + const int i = get_selection_index(path); + if (-ENOENT == i) return -ENOENT; - update_selection(); // TODO: The content is updated way too often. - if (offset < x.len) + update_selection(i); // TODO: The content is updated way too often. + if (offset < x[i].len) { - if (offset + size > x.len) - size = x.len - offset; - memcpy(buf, x.data + offset, size); + if (offset + size > x[i].len) + size = x[i].len - offset; + memcpy(buf, x[i].data + offset, size); } else size = 0; -- cgit v1.1