summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2020-02-14 14:10:44 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-02-19 20:00:36 +0100
commit2ac728a0217f01cf09da59ad97fa01891a4b323b (patch)
treed6b9fe5f21f8e8fc0d5b093039a14db38ea05a51
parent61e3836b3b0e29e905fee8c7d283f198231dee1e (diff)
ecore_evas: Introduce cnp support for cocoadevs/bu5hm4n/work_cnp
with this commit you can do limited cnp for cocoa. You still cannot copy and paste pictures or markup arround, only text is supported so far. However, text on its own works quite stable and good. Differential Revision: https://phab.enlightenment.org/D11351
-rw-r--r--src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c137
1 files changed, 136 insertions, 1 deletions
diff --git a/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c b/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c
index e1c5a66..3352efb 100644
--- a/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c
+++ b/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c
@@ -34,6 +34,11 @@ static Ecore_Event_Handler *ecore_evas_event_handlers[4];
34static const char *_iface_name = "opengl_cocoa"; 34static const char *_iface_name = "opengl_cocoa";
35static const int _iface_version = 1; 35static const int _iface_version = 1;
36 36
37typedef struct {
38 Ecore_Evas_Selection_Callbacks clipboard;
39 Eina_Future *delivery;
40} Ecore_Evas_Cocoa_Engine_Data;
41
37static inline Ecore_Evas * 42static inline Ecore_Evas *
38_ecore_evas_cocoa_match(Ecore_Cocoa_Object *cocoa_win) 43_ecore_evas_cocoa_match(Ecore_Cocoa_Object *cocoa_win)
39{ 44{
@@ -422,6 +427,125 @@ _ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func
422 ee->func.fn_delete_request = func; 427 ee->func.fn_delete_request = func;
423} 428}
424 429
430static Eina_Value
431_delivery(void *data, const Eina_Value value EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
432{
433 Ecore_Evas *ee = data;
434 Ecore_Evas_Cocoa_Engine_Data *edata = ee->engine.data;
435 Eina_Rw_Slice slice;
436 const char *mime_type = NULL;
437
438 EINA_SAFETY_ON_NULL_GOTO(edata->delivery, end);
439
440 for (unsigned int i = 0; i < eina_array_count(edata->clipboard.available_types); ++i)
441 {
442 mime_type = eina_array_data_get(edata->clipboard.available_types, i);
443 if (!strncmp("text/", mime_type, strlen("text/")))
444 break;
445 }
446 if (mime_type)
447 {
448 edata->clipboard.delivery(ee, 1, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER, mime_type, &slice);
449 EINA_SAFETY_ON_FALSE_GOTO(ecore_cocoa_clipboard_set(slice.mem, slice.len, mime_type), end);
450 }
451 else
452 {
453 ERR("No compatible mime type found");
454 }
455
456end:
457 return EINA_VALUE_EMPTY;
458}
459
460static Eina_Bool
461_ecore_evas_cocoa_selection_claim(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Internal_Delivery delivery, Ecore_Evas_Internal_Cancel cancel)
462{
463 if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
464 return EINA_FALSE;
465
466 if (!delivery && !cancel)
467 {
468 ecore_cocoa_clipboard_clear();
469 return EINA_TRUE;
470 }
471 else
472 {
473 Ecore_Evas_Cocoa_Engine_Data *edata = ee->engine.data;
474
475 if (edata->clipboard.cancel)
476 {
477 edata->clipboard.cancel(ee, seat, selection);
478 eina_array_free(edata->clipboard.available_types);
479 }
480
481 edata->delivery = efl_loop_job(efl_main_loop_get());
482 eina_future_then(edata->delivery, _delivery, ee);
483 edata->clipboard.delivery = delivery;
484 edata->clipboard.cancel = cancel;
485 edata->clipboard.available_types = available_types;
486 return EINA_TRUE;
487 }
488}
489
490Eina_Future*
491_ecore_evas_cocoa_selection_request(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_type)
492{
493 Eina_Future *future;
494 Eina_Promise *promise;
495 const char *mime_type;
496
497 if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
498 return eina_future_rejected(efl_loop_future_scheduler_get(efl_main_loop_get()), ecore_evas_no_selection);
499
500 promise = efl_loop_promise_new(efl_main_loop_get());
501 future = eina_future_new(promise);
502
503 for (unsigned int i = 0; i < eina_array_count(acceptable_type); ++i)
504 {
505 mime_type = eina_array_data_get(acceptable_type, i);
506 if (!strncmp("text/", mime_type, strlen("text/")))
507 break;
508 }
509 if (!mime_type)
510 {
511 eina_promise_reject(promise, ecore_evas_no_matching_type);
512 }
513 else
514 {
515 int size;
516 void *data;
517 Eina_Content *content;
518 Eina_Rw_Slice slice;
519
520 data = ecore_cocoa_clipboard_get(&size, mime_type);
521 if (!strncmp(mime_type, "text", strlen("text")))
522 {
523 //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
524 slice.len = size + 1;
525 slice.mem = eina_memdup(data, size, EINA_TRUE);
526 }
527 else
528 {
529 slice.len = size;
530 slice.mem = data;
531 }
532 content = eina_content_new(eina_rw_slice_slice_get(slice), mime_type);
533 if (!content) // construction can fail because of some validation reasons
534 eina_promise_reject(promise, ecore_evas_no_matching_type);
535 else
536 eina_promise_resolve(promise, eina_value_content_init(content));
537 }
538 return future;
539}
540
541static Eina_Bool
542_ecore_evas_cocoa_selection_has_owner(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection EINA_UNUSED)
543{
544 if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
545 return ecore_cocoa_clipboard_exists();
546 return EINA_FALSE;
547}
548
425static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func = 549static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func =
426 { 550 {
427 _ecore_evas_cocoa_free, 551 _ecore_evas_cocoa_free,
@@ -508,6 +632,11 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func =
508 NULL, //fn_pointer_device_xy_get 632 NULL, //fn_pointer_device_xy_get
509 NULL, //fn_prepare 633 NULL, //fn_prepare
510 NULL, //fn_last_tick_get 634 NULL, //fn_last_tick_get
635 _ecore_evas_cocoa_selection_claim, //fn_selection_claim
636 _ecore_evas_cocoa_selection_has_owner, //fn_selection_has_owner
637 _ecore_evas_cocoa_selection_request, //fn_selection_request
638 NULL, //fn_dnd_start
639 NULL, //fn_dnd_stop
511 }; 640 };
512 641
513static Ecore_Cocoa_Window * 642static Ecore_Cocoa_Window *
@@ -517,11 +646,11 @@ _ecore_evas_cocoa_window_get(const Ecore_Evas *ee)
517 return (Ecore_Cocoa_Window *)(ee->prop.window); 646 return (Ecore_Cocoa_Window *)(ee->prop.window);
518} 647}
519 648
520
521EAPI Ecore_Evas * 649EAPI Ecore_Evas *
522ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int y, int w, int h) 650ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int y, int w, int h)
523{ 651{
524 Ecore_Evas *ee; 652 Ecore_Evas *ee;
653 Ecore_Evas_Cocoa_Engine_Data *edata;
525 Ecore_Evas_Interface_Cocoa *iface; 654 Ecore_Evas_Interface_Cocoa *iface;
526 655
527 if (!ecore_cocoa_init()) 656 if (!ecore_cocoa_init())
@@ -532,6 +661,10 @@ ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int
532 ee = calloc(1, sizeof(Ecore_Evas)); 661 ee = calloc(1, sizeof(Ecore_Evas));
533 if (!ee) 662 if (!ee)
534 goto shutdown_ecore_cocoa; 663 goto shutdown_ecore_cocoa;
664 edata = calloc(1, sizeof(Ecore_Evas_Cocoa_Engine_Data));
665 if (!edata)
666 goto shutdown_ecore_cocoa_engine_data;
667 ee->engine.data = edata;
535 668
536 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); 669 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
537 670
@@ -606,6 +739,8 @@ ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int
606 free(ee->name); 739 free(ee->name);
607 //free_ee: 740 //free_ee:
608 _ecore_evas_cocoa_shutdown(); 741 _ecore_evas_cocoa_shutdown();
742 free(edata);
743 shutdown_ecore_cocoa_engine_data:
609 free(ee); 744 free(ee);
610 shutdown_ecore_cocoa: 745 shutdown_ecore_cocoa:
611 ecore_cocoa_shutdown(); 746 ecore_cocoa_shutdown();