From: Junkyeong Kim Date: Wed, 5 Jun 2024 06:01:22 +0000 (+0900) Subject: Support multi mime types X-Git-Tag: accepted/tizen/unified/20240612.095957~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F09%2F312209%2F1;p=platform%2Fcore%2Fuifw%2Fcbhm.git Support multi mime types AS-IS : support only first mime type for selection. TO-BE : support all selection offered mime types. Change-Id: I678e3e3edd866bc8e9287510ba73490770fe4b62 Signed-off-by: Junkyeong Kim --- diff --git a/src/cbhm.c b/src/cbhm.c index a1e8568..4e46a60 100644 --- a/src/cbhm.c +++ b/src/cbhm.c @@ -42,12 +42,17 @@ typedef struct { typedef struct { struct wl_data_offer *data_offer; + int type_count; struct list_head offer_mimetype_list; } Cbhm_Data_Offer; typedef struct { + char *mimetype; void *data; uint32_t len; + + /* link of data */ + struct list_head item_link; } Cbhm_Received_Data; typedef struct { @@ -70,9 +75,11 @@ typedef struct { struct wl_array types; uint32_t serial; - Cbhm_Received_Data *received_data; + struct list_head received_data_list; Cbhm_Data_Offer *cbhm_data_offer; + char *temp_mime_type; bool data_receive; + int data_received_count; } Cbhm_Glib_Info; static void @@ -112,6 +119,7 @@ _cbhm_add_mime_type(Cbhm_Data_Offer *cbhm_data_offer, const char *type) if (LIST_IS_EMPTY(&cbhm_data_offer->offer_mimetype_list)) { DBG("[CBHM]_cbhm_add_mime_type: %s\n", type); LIST_ADDTAIL(&mime->item_link, &cbhm_data_offer->offer_mimetype_list); + cbhm_data_offer->type_count++; } else { LIST_FOR_EACH_ENTRY(temp, &cbhm_data_offer->offer_mimetype_list, item_link) { if (!strcmp(temp->mimetype, type)) { @@ -125,6 +133,7 @@ _cbhm_add_mime_type(Cbhm_Data_Offer *cbhm_data_offer, const char *type) if (type_match == false) { DBG("[CBHM]_cbhm_add_mime_type: %s\n", type); LIST_ADDTAIL(&mime->item_link, &cbhm_data_offer->offer_mimetype_list); + cbhm_data_offer->type_count++; } } } @@ -168,13 +177,21 @@ _cbhm_free_mime_type_list(Cbhm_Data_Offer *cbhm_data_offer) } static void -_cbhm_free_received_data(Cbhm_Received_Data *received_data) +_cbhm_free_received_data(Cbhm_Glib_Info *info) { - if (!received_data) return; + Cbhm_Received_Data *data; + Cbhm_Received_Data *temp; + + if (LIST_IS_EMPTY(&info->received_data_list)) return; - if (received_data->data) - free(received_data->data); - free(received_data); + LIST_FOR_EACH_ENTRY_SAFE(data, temp, &info->received_data_list, item_link) { + free(data->data); + free(data->mimetype); + LIST_DEL(&data->item_link); + free(data); + } + LIST_DELINIT(&info->received_data_list); + info->data_received_count = 0; } static void @@ -189,20 +206,23 @@ _data_source_send(void *data, struct wl_data_source *source, const char *mime_ty Cbhm_Data_Offer *cbhm_data_offer; char *buf = NULL, *cur_buf; int ret, len_remained, size_ret, len_written = 0; - Cbhm_Mime_Type *mime; + Cbhm_Received_Data *received_data; if (!info) return; if (!info->cbhm_data_offer) return; cbhm_data_offer = info->cbhm_data_offer; - if (!info->received_data) { + if (info->data_source != source) { + WRN("[CBHM]_data_source_send: source changed\n"); + buf = strdup("CLIPBOARD_EMPTY"); + } else if (LIST_IS_EMPTY(&info->received_data_list)) { WRN("[CBHM]_data_source_send: no saved data\n"); buf = strdup("CLIPBOARD_EMPTY"); } else { - LIST_FOR_EACH_ENTRY(mime, &cbhm_data_offer->offer_mimetype_list, item_link) { - if (!strcmp(mime->mimetype, mime_type)) { - buf = calloc(info->received_data->len, sizeof(char)); - strncpy(buf, info->received_data->data, info->received_data->len); + LIST_FOR_EACH_ENTRY(received_data, &info->received_data_list, item_link) { + if (!strcmp(received_data->mimetype, mime_type)) { + buf = calloc(received_data->len, sizeof(char)); + strncpy(buf, received_data->data, received_data->len); break; } } @@ -329,6 +349,52 @@ _cbhm_set_selection(Cbhm_Glib_Info *info) wl_data_device_set_selection(info->data_device, info->data_source, info->serial++); } +static void +_cbhm_offer_receive(Cbhm_Glib_Info *info) +{ + Cbhm_Data_Offer *cbhm_data_offer; + Cbhm_Mime_Type *mime = NULL; + int pipe[2]; + int count = 0; + + cbhm_data_offer = info->cbhm_data_offer; + + if (info->data_received_count == cbhm_data_offer->type_count) { + DBG("[CBHM]_cbhm_offer_receive: already received all type data : %d", cbhm_data_offer->type_count); + return; + } + + LIST_FOR_EACH_ENTRY(mime, &cbhm_data_offer->offer_mimetype_list, item_link) { + if (count != info->data_received_count) { + count++; + continue; + } + info->temp_mime_type = strdup(mime->mimetype); + break; + } + DBG("[CBHM]_cbhm_offer_receive: selected mime type : %s", info->temp_mime_type); + + if (pipe2(pipe, O_CLOEXEC) == -1) { + ERR("[CBHM]_cbhm_offer_receive: pipe2 fail\n"); + free(info->temp_mime_type); + info->temp_mime_type = NULL; + return; + } + + wl_data_offer_receive(cbhm_data_offer->data_offer, (const char *)info->temp_mime_type, pipe[1]); + close(pipe[1]); + + wl_display_flush(info->wl_disp); + + info->datafd.fd = pipe[0]; + + info->datafd.events = G_IO_IN | G_IO_ERR; + info->datafd.revents = 0; + + g_source_add_poll(&info->gsource, &info->datafd); + DBG("[CBHM]_cbhm_offer_receive: set datafd(%d, %d)\n", pipe[0], pipe[1]); +} + static void _cbhm_receive_data(Cbhm_Glib_Info *info) { @@ -343,9 +409,10 @@ _cbhm_receive_data(Cbhm_Glib_Info *info) received_data = calloc(1, sizeof(Cbhm_Received_Data)); if (!received_data) { ERR("[CBHM]_cbhm_receive_data: alloc fail \n"); + free(info->temp_mime_type); + info->temp_mime_type = NULL; return; } - info->received_data = received_data; while (1) { len = read(info->datafd.fd, buffer, sizeof(buffer)); @@ -354,8 +421,7 @@ _cbhm_receive_data(Cbhm_Glib_Info *info) continue; } else { ERR("[CBHM]_cbhm_receive_data: read fail.(%d) %m\n", errno); - _cbhm_free_received_data(received_data); - info->received_data = NULL; + free(received_data); goto receive_data_done; } } else if (len == 0) { @@ -380,6 +446,7 @@ _cbhm_receive_data(Cbhm_Glib_Info *info) if (received_data->data != NULL) { free(received_data->data); received_data->data = NULL; + free(received_data); } goto receive_data_done; } @@ -401,15 +468,29 @@ _cbhm_receive_data(Cbhm_Glib_Info *info) ERR("[CBHM]_cbhm_receive_data: realloc fail\n"); free(received_data->data); received_data->data = NULL; + free(received_data); goto receive_data_done; } } - INF("[CBHM]_cbhm_receive_data: (%d) %s\n", received_data->len, (char *)received_data->data); + received_data->mimetype = strdup(info->temp_mime_type); + LIST_ADDTAIL(&received_data->item_link, &info->received_data_list); + info->data_received_count++; + INF("[CBHM]_cbhm_receive_data:(%d:%d) len:%d, %s\n", + info->data_received_count, info->cbhm_data_offer->type_count, received_data->len, (char *)received_data->data); receive_data_done: g_source_remove_poll(&info->gsource, &info->datafd); close(info->datafd.fd); info->datafd.fd = -1; + + free(info->temp_mime_type); + info->temp_mime_type = NULL; + + if (info->data_received_count != info->cbhm_data_offer->type_count) { + _cbhm_offer_receive(info); + return; + } + info->data_receive = false; _cbhm_set_selection(info); @@ -485,6 +566,9 @@ _data_device_cb_offer(void *data, struct wl_data_device *data_device, struct wl_ } DBG("[CBHM]_data_device_cb_offer : %p\n", offer); + _cbhm_free_received_data(info); + LIST_INITHEAD(&info->received_data_list); + LIST_INITHEAD(&cbhm_data_offer->offer_mimetype_list); cbhm_data_offer->data_offer = offer; info->cbhm_data_offer = cbhm_data_offer; @@ -517,9 +601,6 @@ _data_device_cb_selection(void *data, struct wl_data_device *data_device, struct { Cbhm_Glib_Info *info; Cbhm_Data_Offer *cbhm_data_offer; - Cbhm_Mime_Type *mime = NULL; - char *mime_type; - int pipe[2]; info = data; if (!info) return; @@ -551,36 +632,9 @@ _data_device_cb_selection(void *data, struct wl_data_device *data_device, struct return; } - LIST_FOR_EACH_ENTRY(mime, &cbhm_data_offer->offer_mimetype_list, item_link) { - mime_type = strdup(mime->mimetype); - break; - } - DBG("[CBHM]_data_device_cb_selection: selected mime type : %s", mime_type); - - if (pipe2(pipe, O_CLOEXEC) == -1) { - ERR("[CBHM]_data_device_cb_selection: pipe2 fail\n"); - free(mime_type); - return; - } - info->data_receive = true; - _cbhm_free_received_data(info->received_data); - info->received_data = NULL; - - wl_data_offer_receive(offer, (const char *)mime_type, pipe[1]); - close(pipe[1]); - wl_display_flush(info->wl_disp); - - free(mime_type); - - info->datafd.fd = pipe[0]; - - info->datafd.events = G_IO_IN | G_IO_ERR; - info->datafd.revents = 0; - - g_source_add_poll(&info->gsource, &info->datafd); - DBG("[CBHM]_data_device_cb_selection: set datafd(%d, %d)\n", pipe[0], pipe[1]); + _cbhm_offer_receive(info); } static const struct wl_data_device_listener _data_device_listener = @@ -864,9 +918,7 @@ cbhm_gsource_finalize(GSource *source) Cbhm_Glib_Info *info = (Cbhm_Glib_Info *)source; INF("[CBHM]cbhm_gsource_finalize: revent:0x%x\n", info->gfd.revents); - if (info->received_data) - _cbhm_free_received_data(info->received_data); - info->received_data = NULL; + _cbhm_free_received_data(info); if (info->cbhm_data_offer) { wl_data_offer_destroy(info->cbhm_data_offer->data_offer); _cbhm_free_mime_type_list(info->cbhm_data_offer); @@ -877,6 +929,8 @@ cbhm_gsource_finalize(GSource *source) close(info->datafd.fd); info->datafd.fd = -1; } + if (info->temp_mime_type) + free(info->temp_mime_type); cbhm_wayland_shutdown(info); g_source_destroy(source); @@ -903,6 +957,7 @@ cbhm_init(void) } info->datafd.fd = -1; + LIST_INITHEAD(&info->received_data_list); ret = cbhm_wayland_init(info); if (ret) { @@ -943,9 +998,7 @@ cbhm_shutdown(GSource *gsource) info = (Cbhm_Glib_Info *)gsource; - if (info->received_data) - _cbhm_free_received_data(info->received_data); - info->received_data = NULL; + _cbhm_free_received_data(info); if (info->cbhm_data_offer) { wl_data_offer_destroy(info->cbhm_data_offer->data_offer); _cbhm_free_mime_type_list(info->cbhm_data_offer);