diff --git a/apps/compositor.c b/apps/compositor.c index 4127aabf..bd72c11b 100644 --- a/apps/compositor.c +++ b/apps/compositor.c @@ -2445,6 +2445,13 @@ int main(int argc, char * argv[]) { pex_send(yg->server, w->owner, response->size, (char *)response); } break; + case YUTANI_SPECIAL_REQUEST_CLIPBOARD: + { + yutani_msg_buildx_clipboard_alloc(response, yg->clipboard_size); + yutani_msg_buildx_clipboard(response, yg->clipboard); + pex_send(server, p->source, response->size, (char *)response); + } + break; default: TRACE("Unknown special request type: 0x%x", sr->request); break; @@ -2452,6 +2459,15 @@ int main(int argc, char * argv[]) { } break; + case YUTANI_MSG_CLIPBOARD: + { + struct yutani_msg_clipboard * cb = (void *)m->data; + yg->clipboard_size = min(cb->size, 511); + memcpy(yg->clipboard, cb->content, yg->clipboard_size); + yg->clipboard[yg->clipboard_size] = '\0'; + TRACE("Copied text to clipbard (size=%d)", yg->clipboard_size); + } + break; default: { TRACE("Unknown type: 0x%8x", m->type); diff --git a/apps/terminal.c b/apps/terminal.c index 4d6e7d67..f64edfb0 100644 --- a/apps/terminal.c +++ b/apps/terminal.c @@ -317,6 +317,8 @@ char * copy_selection(void) { selection_text[_selection_count-1] = '\0'; } + yutani_set_clipboard(yctx, selection_text); + return selection_text; } @@ -1222,9 +1224,12 @@ void key_event(int ret, key_event_t * event) { (event->modifiers & KEY_MOD_LEFT_CTRL || event->modifiers & KEY_MOD_RIGHT_CTRL) && (event->keycode == 'v')) { /* Paste selection */ + yutani_special_request(yctx, NULL, YUTANI_SPECIAL_REQUEST_CLIPBOARD); +#if 0 if (selection_text) { handle_input_s(selection_text); } +#endif return; } if (event->modifiers & KEY_MOD_LEFT_ALT || event->modifiers & KEY_MOD_RIGHT_ALT) { @@ -1602,6 +1607,18 @@ void * handle_incoming(void) { resize_finish(wr->width, wr->height); } break; + case YUTANI_MSG_CLIPBOARD: + { + struct yutani_msg_clipboard * cb = (void *)m->data; + if (selection_text) { + free(selection_text); + } + selection_text = malloc(cb->size+1); + memcpy(selection_text, cb->content, cb->size); + selection_text[cb->size] = '\0'; + handle_input_s(selection_text); + } + break; case YUTANI_MSG_WINDOW_MOUSE_EVENT: { struct yutani_msg_window_mouse_event * me = (void*)m->data; diff --git a/apps/yutani_int.h b/apps/yutani_int.h index 29dc36bb..b30f4c2a 100644 --- a/apps/yutani_int.h +++ b/apps/yutani_int.h @@ -173,6 +173,9 @@ typedef struct { int32_t mouse_click_x_orig; int32_t mouse_click_y_orig; + + char clipboard[512]; + int clipboard_size; } yutani_globals_t; struct key_bind { diff --git a/base/usr/include/toaru/yutani.h b/base/usr/include/toaru/yutani.h index 1895d025..bc4c8956 100644 --- a/base/usr/include/toaru/yutani.h +++ b/base/usr/include/toaru/yutani.h @@ -206,6 +206,11 @@ typedef struct yutani_window { yutani_t * ctx; } yutani_window_t; +struct yutani_msg_clipboard { + uint32_t size; + char content[]; +}; + /* Magic value */ #define YUTANI_MSG__MAGIC 0xABAD1DEA @@ -249,6 +254,8 @@ typedef struct yutani_window { #define YUTANI_MSG_WINDOW_UPDATE_SHAPE 0x00000050 +#define YUTANI_MSG_CLIPBOARD 0x00000060 + #define YUTANI_MSG_GOODBYE 0x000000F0 /* Special request (eg. one-off single-shot requests like "please maximize me" */ @@ -406,6 +413,8 @@ typedef struct yutani_window { #define YUTANI_SPECIAL_REQUEST_MAXIMIZE 1 #define YUTANI_SPECIAL_REQUEST_PLEASE_CLOSE 2 +#define YUTANI_SPECIAL_REQUEST_CLIPBOARD 10 + typedef struct { int x; int y; @@ -447,6 +456,7 @@ extern size_t yutani_query(yutani_t * y); #define yutani_msg_buildx_window_show_mouse_alloc(out) char _yutani_tmp_ ## LINE [sizeof(struct yutani_message) + sizeof(struct yutani_msg_window_show_mouse)]; yutani_msg_t * out = (void *)&_yutani_tmp_ ## LINE; #define yutani_msg_buildx_window_resize_start_alloc(out) char _yutani_tmp_ ## LINE [sizeof(struct yutani_message) + sizeof(struct yutani_msg_window_resize_start)]; yutani_msg_t * out = (void *)&_yutani_tmp_ ## LINE; #define yutani_msg_buildx_special_request_alloc(out) char _yutani_tmp_ ## LINE [sizeof(struct yutani_message) + sizeof(struct yutani_msg_special_request)]; yutani_msg_t * out = (void *)&_yutani_tmp_ ## LINE; +#define yutani_msg_buildx_clipboard_alloc(out, length) char _yutani_tmp_ ## LINE [sizeof(struct yutani_message) + sizeof(struct yutani_msg_clipboard)+length]; yutani_msg_t * out = (void *)&_yutani_tmp_ ## LINE; extern void yutani_msg_buildx_hello(yutani_msg_t * msg); extern void yutani_msg_buildx_flip(yutani_msg_t * msg, yutani_wid_t wid); @@ -477,6 +487,7 @@ extern void yutani_msg_buildx_window_warp_mouse(yutani_msg_t * msg, yutani_wid_t extern void yutani_msg_buildx_window_show_mouse(yutani_msg_t * msg, yutani_wid_t wid, int32_t show_mouse); extern void yutani_msg_buildx_window_resize_start(yutani_msg_t * msg, yutani_wid_t wid, yutani_scale_direction_t direction); extern void yutani_msg_buildx_special_request(yutani_msg_t * msg, yutani_wid_t wid, uint32_t request); +extern void yutani_msg_buildx_clipboard(yutani_msg_t * msg, char * content); extern int yutani_msg_send(yutani_t * y, yutani_msg_t * msg); extern yutani_t * yutani_context_create(FILE * socket); @@ -508,7 +519,7 @@ extern void yutani_window_show_mouse(yutani_t * yctx, yutani_window_t * window, extern void yutani_window_resize_start(yutani_t * yctx, yutani_window_t * window, yutani_scale_direction_t direction); extern void yutani_special_request(yutani_t * yctx, yutani_window_t * window, uint32_t request); extern void yutani_special_request_wid(yutani_t * yctx, yutani_wid_t wid, uint32_t request); - +extern void yutani_set_clipboard(yutani_t * yctx, char * content); extern gfx_context_t * init_graphics_yutani(yutani_window_t * window); extern gfx_context_t * init_graphics_yutani_double_buffer(yutani_window_t * window); diff --git a/lib/yutani.c b/lib/yutani.c index 4ef4b97b..3391e2ee 100644 --- a/lib/yutani.c +++ b/lib/yutani.c @@ -433,6 +433,17 @@ void yutani_msg_buildx_special_request(yutani_msg_t * msg, yutani_wid_t wid, uin sr->request = request; } +void yutani_msg_buildx_clipboard(yutani_msg_t * msg, char * content) { + msg->magic = YUTANI_MSG__MAGIC; + msg->type = YUTANI_MSG_CLIPBOARD; + msg->size = sizeof(struct yutani_message) + sizeof(struct yutani_msg_clipboard) + strlen(content); + + struct yutani_msg_clipboard * cl = (void *)msg->data; + + cl->size = strlen(content); + memcpy(cl->content, content, strlen(content)); +} + int yutani_msg_send(yutani_t * y, yutani_msg_t * msg) { return pex_reply(y->sock, msg->size, (char *)msg); } @@ -748,6 +759,13 @@ void yutani_special_request_wid(yutani_t * yctx, yutani_wid_t wid, uint32_t requ yutani_msg_send(yctx, m); } +void yutani_set_clipboard(yutani_t * yctx, char * content) { + /* Set clipboard contents */ + yutani_msg_buildx_clipboard_alloc(m, strlen(content)); + yutani_msg_buildx_clipboard(m, content); + yutani_msg_send(yctx, m); +} + gfx_context_t * init_graphics_yutani(yutani_window_t * window) { gfx_context_t * out = malloc(sizeof(gfx_context_t)); out->width = window->width;