diff --git a/configure.ac b/configure.ac index fe8626430e..0758c7d451 100644 --- a/configure.ac +++ b/configure.ac @@ -2843,6 +2843,8 @@ EFL_INTERNAL_DEPEND_PKG([ECORE_COCOA], [ecore-input]) EFL_INTERNAL_DEPEND_PKG([ECORE_COCOA], [ecore]) EFL_INTERNAL_DEPEND_PKG([ECORE_COCOA], [eo]) EFL_INTERNAL_DEPEND_PKG([ECORE_COCOA], [eina]) +EFL_INTERNAL_DEPEND_PKG([ECORE_COCOA], [evas]) +EFL_INTERNAL_DEPEND_PKG([ECORE_COCOA], [emile]) ### Checks for header files diff --git a/src/Makefile_Ecore_Cocoa.am b/src/Makefile_Ecore_Cocoa.am index a158767380..9b5ab544b1 100644 --- a/src/Makefile_Ecore_Cocoa.am +++ b/src/Makefile_Ecore_Cocoa.am @@ -14,6 +14,7 @@ lib_ecore_cocoa_libecore_cocoa_la_SOURCES = \ lib/ecore_cocoa/ecore_cocoa.m \ lib/ecore_cocoa/ecore_cocoa_window.h \ lib/ecore_cocoa/ecore_cocoa_window.m \ +lib/ecore_cocoa/ecore_cocoa_cnp.m \ lib/ecore_cocoa/ecore_cocoa_app.m \ lib/ecore_cocoa/ecore_cocoa_app.h \ lib/ecore_cocoa/ecore_cocoa_private.h diff --git a/src/lib/ecore_cocoa/Ecore_Cocoa.h b/src/lib/ecore_cocoa/Ecore_Cocoa.h index 84a69a87d2..caae2d0741 100644 --- a/src/lib/ecore_cocoa/Ecore_Cocoa.h +++ b/src/lib/ecore_cocoa/Ecore_Cocoa.h @@ -40,6 +40,8 @@ EAPI extern int ECORE_COCOA_EVENT_LOST_FOCUS; EAPI extern int ECORE_COCOA_EVENT_RESIZE; EAPI extern int ECORE_COCOA_EVENT_EXPOSE; EAPI extern int ECORE_COCOA_EVENT_WINDOW_DESTROY; +EAPI extern int ECORE_COCOA_EVENT_DATA_SOURCE_SEND; +EAPI extern int ECORE_COCOA_EVENT_SELECTION_DATA_READY; typedef void * Ecore_Cocoa_Window_Id; typedef struct _Ecore_Cocoa_Event_Video_Resize Ecore_Cocoa_Event_Video_Resize; @@ -61,6 +63,15 @@ struct _Ecore_Cocoa_Screen int dummy; }; +typedef enum +{ + ECORE_COCOA_CNP_TYPE_UNKNOWN = 0, + ECORE_COCOA_CNP_TYPE_STRING = (1 << 0), + ECORE_COCOA_CNP_TYPE_MARKUP = (1 << 1), + ECORE_COCOA_CNP_TYPE_IMAGE = (1 << 2), + ECORE_COCOA_CNP_TYPE_HTML = (1 << 3) +} Ecore_Cocoa_Cnp_Type; + /* Core */ EAPI int ecore_cocoa_init(void); @@ -167,6 +178,27 @@ EAPI int ecore_cocoa_titlebar_height_get(void); EAPI Ecore_Cocoa_Window_Id ecore_cocoa_window_get_window_id(const Ecore_Cocoa_Window *window); + +/** + * @return false on error, true otherwise + * + * @ingroup Ecore_Cocoa_Cpn_Group + */ +EAPI Eina_Bool ecore_cocoa_selection_clipboard_set(const void *data, int size, Ecore_Cocoa_Cnp_Type type); + +/** + * @return false if type not found or on error, true otherwise + * + * @ingroup Ecore_Cocoa_Cnp_Group + */ +EAPI void *ecore_cocoa_selection_clipboard_get(int *size, Ecore_Cocoa_Cnp_Type type, + Ecore_Cocoa_Cnp_Type *retrieved_types); + +/** + * @ingroup Ecore_Cocoa_Cnp_Group + */ +EAPI void ecore_cocoa_selection_clipboard_clear(void); + EAPI void ecore_cocoa_window_cursor_set(Ecore_Cocoa_Window *win, Ecore_Cocoa_Cursor c); EAPI void ecore_cocoa_window_cursor_show(Ecore_Cocoa_Window *win, Eina_Bool show); diff --git a/src/lib/ecore_cocoa/ecore_cocoa.m b/src/lib/ecore_cocoa/ecore_cocoa.m index 84ee03bf2c..d2acc20c86 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa.m +++ b/src/lib/ecore_cocoa/ecore_cocoa.m @@ -20,6 +20,8 @@ EAPI int ECORE_COCOA_EVENT_LOST_FOCUS = 0; EAPI int ECORE_COCOA_EVENT_RESIZE = 0; EAPI int ECORE_COCOA_EVENT_EXPOSE = 0; EAPI int ECORE_COCOA_EVENT_WINDOW_DESTROY = 0; +EAPI int ECORE_COCOA_EVENT_DATA_SOURCE_SEND = 0; +EAPI int ECORE_COCOA_EVENT_SELECTION_DATA_READY = 0; static int _ecore_cocoa_init_count = 0; @@ -47,12 +49,15 @@ ecore_cocoa_init(void) } DBG(""); - + ECORE_COCOA_EVENT_GOT_FOCUS = ecore_event_type_new(); ECORE_COCOA_EVENT_LOST_FOCUS = ecore_event_type_new(); ECORE_COCOA_EVENT_RESIZE = ecore_event_type_new(); ECORE_COCOA_EVENT_EXPOSE = ecore_event_type_new(); ECORE_COCOA_EVENT_WINDOW_DESTROY = ecore_event_type_new(); + ECORE_COCOA_EVENT_DATA_SOURCE_SEND = ecore_event_type_new(); + ECORE_COCOA_EVENT_SELECTION_DATA_READY = ecore_event_type_new(); + /* Init the Application handler */ [Ecore_Cocoa_Application sharedApplication]; diff --git a/src/lib/ecore_cocoa/ecore_cocoa_cnp.m b/src/lib/ecore_cocoa/ecore_cocoa_cnp.m new file mode 100644 index 0000000000..f94dfe98cd --- /dev/null +++ b/src/lib/ecore_cocoa/ecore_cocoa_cnp.m @@ -0,0 +1,176 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#import +#import "ecore_cocoa_window.h" +#include "ecore_cocoa_private.h" +#import "ecore_cocoa_app.h" + +EAPI Eina_Bool +ecore_cocoa_selection_clipboard_set(const void *data, + int size, + Ecore_Cocoa_Cnp_Type type) +{ + static NSMutableArray *objects = nil; + NSPasteboard *pb; + NSString *str = nil; + BOOL ok = YES; + + if (!objects) + objects = [[NSMutableArray alloc] init]; + + pb = [NSPasteboard generalPasteboard]; + [pb clearContents]; + + if (type & ECORE_COCOA_CNP_TYPE_STRING) + { + str = [[NSString alloc] initWithBytes: data + length: size + encoding: NSUTF8StringEncoding]; + [objects addObject: str]; + } + if (type & ECORE_COCOA_CNP_TYPE_MARKUP) + { + char *utf8; + + utf8 = evas_textblock_text_markup_to_utf8(NULL, (const char *)data); + str = [[NSString alloc] initWithBytes: utf8 + length: strlen(utf8) // XXX strlen() ? + encoding: NSUTF8StringEncoding]; + free(utf8); + [objects addObject: str]; + } + if (type & ECORE_COCOA_CNP_TYPE_IMAGE) + { + WRN("Image CNP: NOT IMPLEMENTED"); + } + if (type & ECORE_COCOA_CNP_TYPE_HTML) + { + WRN("HTML CNP: NOT IMPLEMENTED"); + } + + /* Write to pasteboard */ + if ([objects count] > 0) + { + ok = [pb writeObjects: objects]; + [objects removeAllObjects]; + } + + return (ok) ? EINA_TRUE : EINA_FALSE; +} + + +EAPI void * +ecore_cocoa_selection_clipboard_get(int *size, + Ecore_Cocoa_Cnp_Type type, + Ecore_Cocoa_Cnp_Type *retrieved_types) +{ + static NSMutableArray *classes = nil; + void *data; + NSDictionary *options; + NSPasteboard *pb; + NSArray *items; + unsigned int len; + BOOL string_class = NO; + Ecore_Cocoa_Cnp_Type types = 0; + + if (!classes) + classes = [[NSMutableArray alloc] init]; + + if ((type & ECORE_COCOA_CNP_TYPE_STRING) || + (type & ECORE_COCOA_CNP_TYPE_MARKUP)) + { + string_class = YES; + [classes addObject: [NSString class]]; + } + if (type & ECORE_COCOA_CNP_TYPE_IMAGE) + { + WRN("Image CNP: NOT IMPLEMENTED"); + } + if (type & ECORE_COCOA_CNP_TYPE_HTML) + { + WRN("HTML CNP: NOT IMPLEMENTED"); + } + + if ([classes count] <= 0) + { + ERR("No registered classes... got nothing from pasteboard"); + goto fail; + } + + pb = [NSPasteboard generalPasteboard]; + options = [NSDictionary dictionary]; + items = [pb readObjectsForClasses: classes + options: options]; + if (!items) + { + ERR("No items in the clipboard"); + goto remove_fail; + } + if ([items count] != 1) + { + ERR("%lu items in pasteboard. Only one at the time can be handled", + [items count]); + goto fail; + } + + if (string_class) + { + NSString *str = [items objectAtIndex: 0]; + data = (void *)[str UTF8String]; + len = [str lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; + data = strndup((const char *)data, len); + + if (EINA_UNLIKELY(!data)) + { + CRI("Failed to strndup() string \"%s\" (len: %u)", + (const char *)data, len); + goto remove_fail; + } + types |= ECORE_COCOA_CNP_TYPE_STRING; + +#if 0 + if (type & ECORE_COCOA_CNP_TYPE_MARKUP) + { + char *markup; + markup = evas_textblock_text_utf8_to_markup(NULL, data); + free(data); + data = markup; + if (EINA_UNLIKELY(!data)) + { + CRI("Failed to retrieve markup from UTF8"); + goto remove_fail; + } + len = strlen(markup); + } +#endif + } + + if (!types) + { + ERR("No types retrieved!"); + goto remove_fail; + } + + [classes removeAllObjects]; + + if (size) *size = len; + if (retrieved_types) *retrieved_types = types; + return data; + +remove_fail: + [classes removeAllObjects]; +fail: + if (size) *size = 0; + if (retrieved_types) *retrieved_types = 0; + return NULL; +} + +EAPI void +ecore_cocoa_selection_clipboard_clear(void) +{ + [[NSPasteboard generalPasteboard] clearContents]; +}