From f1fe86dcb2aa2f4b780face9302c8b8a3d884899 Mon Sep 17 00:00:00 2001 From: Jean Guyomarc'h Date: Thu, 8 Oct 2015 11:58:46 +0200 Subject: [PATCH] ecore_cocoa: add support for system cursors - Ecore_Cocoa_Cursor enum which references system cursors; - API to show/hide cursor: ecore_cocoa_window_cursor_show(); - API to set system cursor: ecore_cocoa_window_cursor_set(); - Ecore_Evas interface to get Ecore_Cocoa_Window from Ecore_Evas. @feature Change-Id: Iadef3d4bbffd5c92fa2c8d040393f7a9160c8ac4 Signed-off-by: Cedric BAIL --- src/Makefile_Ecore_Cocoa.am | 1 + src/Makefile_Ecore_Evas.am | 1 + src/lib/ecore_cocoa/Ecore_Cocoa.h | 5 ++ src/lib/ecore_cocoa/Ecore_Cocoa_Cursor.h | 32 +++++++++++++ src/lib/ecore_cocoa/ecore_cocoa.m | 3 ++ src/lib/ecore_cocoa/ecore_cocoa_private.h | 4 ++ src/lib/ecore_cocoa/ecore_cocoa_window.m | 53 ++++++++++++++++++++ src/lib/ecore_evas/Ecore_Evas.h | 2 + src/lib/ecore_evas/ecore_evas.c | 10 ++++ src/lib/ecore_evas/ecore_evas_cocoa.h | 14 ++++++ .../ecore_evas/engines/cocoa/ecore_evas_cocoa.c | 56 ++++++++++++++++++---- 11 files changed, 172 insertions(+), 9 deletions(-) create mode 100644 src/lib/ecore_cocoa/Ecore_Cocoa_Cursor.h create mode 100644 src/lib/ecore_evas/ecore_evas_cocoa.h diff --git a/src/Makefile_Ecore_Cocoa.am b/src/Makefile_Ecore_Cocoa.am index 3321b25..a158767 100644 --- a/src/Makefile_Ecore_Cocoa.am +++ b/src/Makefile_Ecore_Cocoa.am @@ -7,6 +7,7 @@ lib_LTLIBRARIES += lib/ecore_cocoa/libecore_cocoa.la installed_ecorecocoamainheadersdir = $(includedir)/ecore-cocoa-@VMAJ@ dist_installed_ecorecocoamainheaders_DATA = \ lib/ecore_cocoa/Ecore_Cocoa.h \ +lib/ecore_cocoa/Ecore_Cocoa_Cursor.h \ lib/ecore_cocoa/Ecore_Cocoa_Keys.h lib_ecore_cocoa_libecore_cocoa_la_SOURCES = \ diff --git a/src/Makefile_Ecore_Evas.am b/src/Makefile_Ecore_Evas.am index a1c50a8..f43b667 100755 --- a/src/Makefile_Ecore_Evas.am +++ b/src/Makefile_Ecore_Evas.am @@ -20,6 +20,7 @@ lib/ecore_evas/ecore_evas_private.h \ lib/ecore_evas/ecore_evas_extn.h \ lib/ecore_evas/ecore_evas_extn.c \ lib/ecore_evas/ecore_evas_wayland.h \ +lib/ecore_evas/ecore_evas_cocoa.h \ lib/ecore_evas/ecore_evas_win32.h \ lib/ecore_evas/ecore_evas_x11.h \ lib/ecore_evas/ecore_evas_util.c diff --git a/src/lib/ecore_cocoa/Ecore_Cocoa.h b/src/lib/ecore_cocoa/Ecore_Cocoa.h index 78d15ce..4341389 100644 --- a/src/lib/ecore_cocoa/Ecore_Cocoa.h +++ b/src/lib/ecore_cocoa/Ecore_Cocoa.h @@ -26,6 +26,7 @@ #endif #include +#include "Ecore_Cocoa_Cursor.h" #ifdef __cplusplus extern "C" { @@ -165,6 +166,10 @@ EAPI int ecore_cocoa_titlebar_height_get(void); EAPI Ecore_Cocoa_Window_Id ecore_cocoa_window_get_window_id(Ecore_Cocoa_Window *window); + +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); + #ifdef __cplusplus } #endif diff --git a/src/lib/ecore_cocoa/Ecore_Cocoa_Cursor.h b/src/lib/ecore_cocoa/Ecore_Cocoa_Cursor.h new file mode 100644 index 0000000..6bca47f --- /dev/null +++ b/src/lib/ecore_cocoa/Ecore_Cocoa_Cursor.h @@ -0,0 +1,32 @@ +#ifndef __ECORE_COCOA_CURSOR_H__ +#define __ECORE_COCOA_CURSOR_H__ + +typedef enum +{ + ECORE_COCOA_CURSOR_ARROW = 0, + ECORE_COCOA_CURSOR_CONTEXTUAL_MENU, + ECORE_COCOA_CURSOR_CLOSED_HAND, + ECORE_COCOA_CURSOR_CROSSHAIR, + ECORE_COCOA_CURSOR_DISAPPEARING_ITEM, + ECORE_COCOA_CURSOR_DRAG_COPY, + ECORE_COCOA_CURSOR_DRAG_LINK, + ECORE_COCOA_CURSOR_IBEAM, + ECORE_COCOA_CURSOR_OPEN_HAND, + ECORE_COCOA_CURSOR_OPERATION_NOT_ALLOWED, + ECORE_COCOA_CURSOR_POINTING_HAND, + ECORE_COCOA_CURSOR_RESIZE_DOWN, + ECORE_COCOA_CURSOR_RESIZE_LEFT, + ECORE_COCOA_CURSOR_RESIZE_LEFT_RIGHT, + ECORE_COCOA_CURSOR_RESIZE_RIGHT, + ECORE_COCOA_CURSOR_RESIZE_UP, + ECORE_COCOA_CURSOR_RESIZE_UP_DOWN, + ECORE_COCOA_CURSOR_IBEAM_VERTICAL, + + __ECORE_COCOA_CURSOR_LAST, /* Sentinel */ + + ECORE_COCOA_CURSOR_DEFAULT = ECORE_COCOA_CURSOR_ARROW + +} Ecore_Cocoa_Cursor; + +#endif /* ! __ECORE_COCOA_CURSOR_H__ */ + diff --git a/src/lib/ecore_cocoa/ecore_cocoa.m b/src/lib/ecore_cocoa/ecore_cocoa.m index 979d557..aae3c02 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa.m +++ b/src/lib/ecore_cocoa/ecore_cocoa.m @@ -61,6 +61,9 @@ ecore_cocoa_init(void) /* Start events monitoring */ [NSApp run]; + if (!_ecore_cocoa_window_init()) + return --_ecore_cocoa_init_count; + return _ecore_cocoa_init_count; } diff --git a/src/lib/ecore_cocoa/ecore_cocoa_private.h b/src/lib/ecore_cocoa/ecore_cocoa_private.h index ffe48ab..9952278 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_private.h +++ b/src/lib/ecore_cocoa/ecore_cocoa_private.h @@ -62,4 +62,8 @@ struct _Ecore_Cocoa_Window }; +/* Internal init */ +Eina_Bool _ecore_cocoa_window_init(void); + + #endif diff --git a/src/lib/ecore_cocoa/ecore_cocoa_window.m b/src/lib/ecore_cocoa/ecore_cocoa_window.m index 53137a0..de905c5 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_window.m +++ b/src/lib/ecore_cocoa/ecore_cocoa_window.m @@ -6,9 +6,13 @@ #include #include +#include #import "ecore_cocoa_window.h" #include "ecore_cocoa_private.h" +static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; + + @implementation EcoreCocoaWindow @synthesize ecore_window_data; @@ -501,3 +505,52 @@ Ecore_Cocoa_Window_Id ecore_cocoa_window_get_window_id(Ecore_Cocoa_Window *windo return window->window; } + +EAPI void +ecore_cocoa_window_cursor_set(Ecore_Cocoa_Window *win, + Ecore_Cocoa_Cursor c) +{ + EINA_SAFETY_ON_NULL_RETURN(win); + EINA_SAFETY_ON_FALSE_RETURN((c >= 0) && (c <= __ECORE_COCOA_CURSOR_LAST)); + + NSCursor *cursor = _cursors[c]; + + DBG("Setting cursor %i (%s)", c, [[cursor description] UTF8String]); + [cursor set]; +} + +EAPI void +ecore_cocoa_window_cursor_show(Ecore_Cocoa_Window *win, + Eina_Bool show) +{ + EINA_SAFETY_ON_NULL_RETURN(win); + + if (show) [NSCursor unhide]; + else [NSCursor hide]; +} + +Eina_Bool +_ecore_cocoa_window_init(void) +{ + _cursors[ECORE_COCOA_CURSOR_ARROW] = [NSCursor arrowCursor]; + _cursors[ECORE_COCOA_CURSOR_CONTEXTUAL_MENU] = [NSCursor contextualMenuCursor]; + _cursors[ECORE_COCOA_CURSOR_CLOSED_HAND] = [NSCursor closedHandCursor]; + _cursors[ECORE_COCOA_CURSOR_CROSSHAIR] = [NSCursor crosshairCursor]; + _cursors[ECORE_COCOA_CURSOR_DISAPPEARING_ITEM] = [NSCursor disappearingItemCursor]; + _cursors[ECORE_COCOA_CURSOR_DRAG_COPY] = [NSCursor dragCopyCursor]; + _cursors[ECORE_COCOA_CURSOR_DRAG_LINK] = [NSCursor dragLinkCursor]; + _cursors[ECORE_COCOA_CURSOR_IBEAM] = [NSCursor IBeamCursor]; + _cursors[ECORE_COCOA_CURSOR_OPEN_HAND] = [NSCursor openHandCursor]; + _cursors[ECORE_COCOA_CURSOR_OPERATION_NOT_ALLOWED] = [NSCursor operationNotAllowedCursor]; + _cursors[ECORE_COCOA_CURSOR_POINTING_HAND] = [NSCursor pointingHandCursor]; + _cursors[ECORE_COCOA_CURSOR_RESIZE_DOWN] = [NSCursor resizeDownCursor]; + _cursors[ECORE_COCOA_CURSOR_RESIZE_LEFT] = [NSCursor resizeLeftCursor]; + _cursors[ECORE_COCOA_CURSOR_RESIZE_LEFT_RIGHT] = [NSCursor resizeLeftRightCursor]; + _cursors[ECORE_COCOA_CURSOR_RESIZE_RIGHT] = [NSCursor resizeRightCursor]; + _cursors[ECORE_COCOA_CURSOR_RESIZE_UP] = [NSCursor resizeUpCursor]; + _cursors[ECORE_COCOA_CURSOR_RESIZE_UP_DOWN] = [NSCursor resizeUpDownCursor]; + _cursors[ECORE_COCOA_CURSOR_IBEAM_VERTICAL] = [NSCursor IBeamCursorForVerticalLayout]; + + return EINA_TRUE; +} + diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h index f960147..92ea827 100755 --- a/src/lib/ecore_evas/Ecore_Evas.h +++ b/src/lib/ecore_evas/Ecore_Evas.h @@ -1378,6 +1378,8 @@ EAPI void ecore_evas_wayland_pointer_set(Ecore_Evas *ee, int hot_x, i EAPI void ecore_evas_wayland_type_set(Ecore_Evas *ee, int type); EAPI Ecore_Wl_Window *ecore_evas_wayland_window_get(const Ecore_Evas *ee); +EAPI Ecore_Cocoa_Window *ecore_evas_cocoa_window_get(const Ecore_Evas *ee); + EAPI Ecore_Evas *ecore_evas_drm_new(const char *device, unsigned int parent, int x, int y, int w, int h); EAPI Ecore_Evas *ecore_evas_gl_drm_new(const char *device, unsigned int parent, int x, int y, int w, int h); /** @since 1.12 */ diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index c5721b8..237bc57 100755 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -30,6 +30,7 @@ #include "ecore_evas_private.h" #include "ecore_evas_x11.h" #include "ecore_evas_wayland.h" +#include "ecore_evas_cocoa.h" #include "ecore_evas_extn.h" #include "ecore_evas_win32.h" @@ -4277,6 +4278,15 @@ ecore_evas_wayland_window_get(const Ecore_Evas *ee) return iface->window_get(ee); } +EAPI Ecore_Cocoa_Window * +ecore_evas_cocoa_window_get(const Ecore_Evas *ee) +{ + Ecore_Evas_Interface_Cocoa *iface; + iface = (Ecore_Evas_Interface_Cocoa *)_ecore_evas_interface_get(ee, "opengl_cocoa"); + EINA_SAFETY_ON_NULL_RETURN_VAL(iface, NULL); + return iface->window_get(ee); +} + EAPI Ecore_Evas * ecore_evas_drm_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h) diff --git a/src/lib/ecore_evas/ecore_evas_cocoa.h b/src/lib/ecore_evas/ecore_evas_cocoa.h new file mode 100644 index 0000000..edc8e05 --- /dev/null +++ b/src/lib/ecore_evas/ecore_evas_cocoa.h @@ -0,0 +1,14 @@ +#ifndef __ECORE_EVAS_COCOA_H__ +#define __ECORE_EVAS_COCOA_H__ + +typedef struct _Ecore_Evas_Interface_Cocoa Ecore_Evas_Interface_Cocoa; + +struct _Ecore_Evas_Interface_Cocoa +{ + Ecore_Evas_Interface base; + + Ecore_Cocoa_Window *(*window_get)(const Ecore_Evas *ee); +}; + +#endif /* ! __ECORE_EVAS_COCOA_H__ */ + 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 22c8fb6..da296fd 100644 --- a/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c +++ b/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c @@ -12,6 +12,7 @@ #include "Ecore_Evas.h" #include "ecore_evas_private.h" +#include "ecore_evas_cocoa.h" #ifdef EAPI # undef EAPI @@ -44,6 +45,9 @@ static Eina_List *ecore_evases = NULL; static Ecore_Event_Handler *ecore_evas_event_handlers[5] = { 0 }; static Ecore_Idle_Enterer *ecore_evas_idle_enterer = NULL; +static const char *_iface_name = "opengl_cocoa"; +static const int _iface_version = 1; + static int _render_updates_process(Ecore_Evas *ee, Eina_List *updates) { @@ -528,16 +532,19 @@ static void _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y) { int x, y; + Evas_Object *old; + Ecore_Cocoa_Window *win = (Ecore_Cocoa_Window *)(ee->prop.window); DBG(""); - if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object); + old = ee->prop.cursor.object; if (obj == NULL) { ee->prop.cursor.object = NULL; ee->prop.cursor.layer = 0; ee->prop.cursor.hot.x = 0; ee->prop.cursor.hot.y = 0; - return; + ecore_cocoa_window_cursor_show(win, EINA_TRUE); + goto end; } ee->prop.cursor.object = obj; @@ -546,17 +553,27 @@ _ecore_evas_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int h ee->prop.cursor.hot.y = hot_y; evas_pointer_output_xy_get(ee->evas, &x, &y); - evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer); + if (obj != old) + { + ecore_cocoa_window_cursor_show(win, EINA_FALSE); + evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer); + evas_object_pass_events_set(ee->prop.cursor.object, 1); + if (evas_pointer_inside_get(ee->evas)) + evas_object_show(ee->prop.cursor.object); + evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, + _ecore_evas_object_cursor_del, ee); + } evas_object_move(ee->prop.cursor.object, x - ee->prop.cursor.hot.x, y - ee->prop.cursor.hot.y); - evas_object_pass_events_set(ee->prop.cursor.object, 1); - - if (evas_pointer_inside_get(ee->evas)) - evas_object_show(ee->prop.cursor.object); - - evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee); +end: + if ((old) && (obj != old)) + { + evas_object_event_callback_del_full(old, EVAS_CALLBACK_DEL, + _ecore_evas_object_cursor_del, ee); + evas_object_del(old); + } } static void @@ -688,10 +705,19 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func = NULL // msg_send }; +static Ecore_Cocoa_Window * +_ecore_evas_cocoa_window_get(const Ecore_Evas *ee) +{ + /* See affectation of ee->prop.window in ecore_evas_cocoa_new_internal */ + return (Ecore_Cocoa_Window *)(ee->prop.window); +} + + EAPI Ecore_Evas * ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int y, int w, int h) { Ecore_Evas *ee; + Ecore_Evas_Interface_Cocoa *iface; if (!ecore_cocoa_init()) return NULL; @@ -755,6 +781,18 @@ ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int return NULL; } + /* Interface setup */ + iface = calloc(1, sizeof(*iface)); + if (EINA_UNLIKELY(!iface)) + { + _ecore_evas_cocoa_shutdown(); + free(ee); + return NULL; + } + iface->base.name = _iface_name; + iface->base.version = _iface_version; + iface->window_get = _ecore_evas_cocoa_window_get; + ee->engine.ifaces = eina_list_append(ee->engine.ifaces, iface); ee->engine.func->fn_render = _ecore_evas_cocoa_render; _ecore_evas_register(ee); -- 2.7.4