On Mon, Dec 19, 2011 at 7:54 AM, Enlightenment SVN
<[email protected]> wrote:
> Log:
> address fixme's in extn :)
>
>
>
> Author: raster
> Date: 2011-12-18 22:54:08 -0800 (Sun, 18 Dec 2011)
> New Revision: 66320
> Trac: http://trac.enlightenment.org/e/changeset/66320
>
> Modified:
> trunk/ecore/src/lib/ecore_evas/Ecore_Evas.h
> trunk/ecore/src/lib/ecore_evas/ecore_evas.c
> trunk/ecore/src/lib/ecore_evas/ecore_evas_extn.c
> trunk/ecore/src/lib/ecore_evas/ecore_evas_private.h
>
> Modified: trunk/ecore/src/lib/ecore_evas/Ecore_Evas.h
> ===================================================================
> --- trunk/ecore/src/lib/ecore_evas/Ecore_Evas.h 2011-12-19 05:57:31 UTC (rev
> 66319)
> +++ trunk/ecore/src/lib/ecore_evas/Ecore_Evas.h 2011-12-19 06:54:08 UTC (rev
> 66320)
> @@ -1649,14 +1649,146 @@
> */
>
> /**
> + * @defgroup Ecore_Evas_Extn External plug/socket infrastructure to remote
> canvases
> + *
> + * These functions allow 1 process to create a "socket" into which another
> + * process can create a "plug" remotely to plug into and provide content
> + * for that socket. This is best for small sized objects (about the size
> range
> + * of a small icon up to a few large icons). Sine the socket is actually an
> + * image object, you cvan fetch the pixel data
> + *
> + * @since 1.2
> + * @{
> + */
> +
> +EAPI extern int ECORE_EVAS_EXTN_CLIENT_ADD; /**< this event is received when
> a plug has connected to an extn socket */
> +EAPI extern int ECORE_EVAS_EXTN_CLIENT_DEL; /**< this event is received when
> a plug has disconnected from an extn socket */
@since 1.2 too just above
Vincent
> +
> +/**
> * Create a new external ecore evas socket
> *
> + * @param ee_target The Ecore_Evas containing the canvas in which the new
> image object will live.
> + * @param svcname The name of the service to be advertised. ensure that it
> is unique (when combined with @p svcnum) otherwise creation may fail.
> + * @param svcnum A number (any value, 0 beig the common default) to
> differentiate multiple instances of services with the same name.
> + * @param svcsys A boolean that if true, specifies to create a system-wide
> service all users can connect to, otherwise the service is private to the
> user ide that created the service.
> + * @return An evas image object that will contain the image output of a plug
> when it plugs in
> + *
> + * This creates an image object that will contain the output of another
> + * processes plug canvas when it connects. All input will be sent back to
> + * this process as well, effectively swallowing or placing the plug process
> + * in the canvas of the socket process in place of the image object. The
> image
> + * object by default is created to be filled (equivalent of
> + * evas_object_image_filled_add() on creation) so image content will scale
> + * toi fill the image unless otherwise reconfigured. The Ecore_Evas size
> + * of the socket is the master size and determines size in pixels of the
> + * plug canvas. You can change the size with something like:
> + *
> + * @code
> + * ecore_evas_resize(ecore_evas_object_ecore_evas_get(obj), 240, 400);
> + * @endcode
> + *
> + * The image object begins as a blank object until a plug client connects.
> + * When a client connects, you will get the ECORE_EVAS_EXTN_CLIENT_ADD event
> + * in the ecore event queue, with event_info being the image object pointer
> + * passed as a void pointer. When a cllient disconnects you will get the
> + * ECORE_EVAS_EXTN_CLIENT_DEL event, and the image object will become blank.
> + *
> + * You can set up event handles for these events as follows:
> + *
> + * @code
> + * static void client_add_cb(void *data, int event, void *event_info)
> + * {
> + * Evas_Object *obj = event_info;
> + * printf("client added to image object %p\n", obj);
> + * evas_object_show(obj);
> + * }
> + *
> + * static void client_del_cb(void *data, int event, void *event_info)
> + * {
> + * Evas_Object *obj = event_info;
> + * printf("client deleted from image object %p\n", obj);
> + * evas_object_hide(obj);
> + * }
> + *
> + * void setup(void)
> + * {
> + * ecore_event_handler_add(ECORE_EVAS_EXTN_CLIENT_ADD,
> + * client_add_cb, NULL);
> + * ecore_event_handler_add(ECORE_EVAS_EXTN_CLIENT_DEL,
> + * client_del_cb, NULL);
> + * }
> + * @endcode
> + *
> + * Note that events come in later after the event happened. You may want to
> be
> + * careful as data structures you had associated with the image object
> + * may have been freed after deleting, but the object may still be around
> + * awating cleanup and thus still be valid.
> + *
> + * @see ecore_evas_extn_socket_object_data_lock()
> + * @see ecore_evas_extn_socket_object_data_unlock()
> + * @see ecore_evas_extn_plug_new()
> + *
> * @since 1.2
> */
> EAPI Evas_Object *ecore_evas_extn_socket_new(Ecore_Evas *ee_target, const
> char *svcname, int svcnum, Eina_Bool svcsys);
> +
> /**
> + * Lock the pixel data so the plug cannot change it
> + *
> + * @param obj The image object returned by ecore_evas_extn_socket_new() to
> lock
> + *
> + * You may need to get the image pixel data with evas_object_image_data_get()
> + * from the image object, but need to ensure that it does not change while
> + * you are using the data. This function lets you set an advisory lock on the
> + * image data so the external plug process will not render to it or alter it.
> + *
> + * You should only hold the lock for just as long as you need to read out the
> + * image data or otherwise deal with it, and then unlokc it with
> + * ecore_evas_extn_socket_object_data_unlock(). Keeping a lock over more than
> + * 1 iteration of the main ecore loop will be problematic, so avoid it. Also
> + * forgetting to unlock may cause the plug process to freeze and thus create
> + * odd behavior.
> + *
> + * @see ecore_evas_extn_socket_new()
> + * @see ecore_evas_extn_socket_object_data_unlock()
> + *
> + * @since 1.2
> + */
> +EAPI void ecore_evas_extn_socket_object_data_lock(Evas_Object *obj);
> +
> +/**
> + * Unlock the pixel data so the plug can change it again.
> + *
> + * @param obj The image object returned by ecore_evas_extn_socket_new() to
> unlock
> + *
> + * This unlocks after an advisor lock has been taken by
> + * ecore_evas_extn_socket_object_data_lock().
> + *
> + * @see ecore_evas_extn_socket_new()
> + * @see ecore_evas_extn_socket_object_data_lock()
> + *
> + * @since 1.2
> + */
> +EAPI void ecore_evas_extn_socket_object_data_unlock(Evas_Object *obj);
> +
> +/**
> * Create a new external ecore evas plug
> *
> + * @param svcname The service name to connect to set up by the socket.
> + * @param svcnum The service number to connect to (set up by socket).
> + * @param svcsys Booleain to set if the service is a system one or not (set
> up by socket).
> + *
> + * This creates an Ecore_evas canvas wrapper and connects it to the given
> + * socket specified by @p svcname, @p svcnum and @p svcsys. If connection
> + * is successful, an Ecore_Evas handle is returned or NULL if connection
> + * fails. If the socket is deleted or disconnects you for whatever reason
> + * youre Ecore_Evas will get a delete request event (the delete request
> + * callback will be called, if set). Also focus, show, hide etc. callbacks
> + * will also be called if the socket object is shown, or already visible on
> + * connect, or if it is hidden later, focused or unfocused.
> + *
> + * @see ecore_evas_extn_socket_new()
> + *
> * @since 1.2
> */
> EAPI Ecore_Evas *ecore_evas_extn_plug_new(const char *svcname, int svcnum,
> Eina_Bool svcsys);
> @@ -1665,6 +1797,10 @@
> * @}
> */
>
> +/**
> + * @}
> + */
> +
> #ifdef __cplusplus
> }
> #endif
>
> Modified: trunk/ecore/src/lib/ecore_evas/ecore_evas.c
> ===================================================================
> --- trunk/ecore/src/lib/ecore_evas/ecore_evas.c 2011-12-19 05:57:31 UTC (rev
> 66319)
> +++ trunk/ecore/src/lib/ecore_evas/ecore_evas.c 2011-12-19 06:54:08 UTC (rev
> 66320)
> @@ -244,6 +244,8 @@
> _ecore_evas_ews_events_init();
> #endif
>
> + _ecore_evas_extn_init();
> +
> if (getenv("ECORE_EVAS_COMP_NOSYNC"))
> _ecore_evas_app_comp_sync = 0;
> return _ecore_evas_init_count;
> @@ -264,6 +266,8 @@
>
> while (ecore_evases) _ecore_evas_free(ecore_evases);
>
> + _ecore_evas_extn_shutdown();
> +
> if (_ecore_evas_fps_debug) _ecore_evas_fps_debug_shutdown();
> ecore_idle_enterer_del(ecore_evas_idle_enterer);
> ecore_evas_idle_enterer = NULL;
>
> Modified: trunk/ecore/src/lib/ecore_evas/ecore_evas_extn.c
> ===================================================================
> --- trunk/ecore/src/lib/ecore_evas/ecore_evas_extn.c 2011-12-19 05:57:31
> UTC (rev 66319)
> +++ trunk/ecore/src/lib/ecore_evas/ecore_evas_extn.c 2011-12-19 06:54:08
> UTC (rev 66320)
> @@ -2,10 +2,6 @@
> # include <config.h>
> #endif
>
> -// FIXME: 1. no way to get events to know when processes connect/disconnect
> -// FIXME: 2. no way to lock/unlock buffer between 2 procs (lock file but
> -// no mechanism to lock/unluck around evas_render())
> -
> #include <stdlib.h>
> #include <unistd.h>
>
> @@ -35,6 +31,7 @@
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <string.h>
> +#include <sys/file.h>
>
> typedef struct _Shmfile Shmfile;
>
> @@ -151,26 +148,6 @@
> free(sf);
> }
>
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> // procotol version - change this as needed
> #define MAJOR 0x1011
>
> @@ -361,12 +338,95 @@
> int w, h;
> Shmfile *shmfile;
> Eina_List *updates;
> + Eina_Bool have_lock : 1;
> } file;
> };
>
> static Eina_List *extn_ee_list = NULL;
>
> +EAPI int ECORE_EVAS_EXTN_CLIENT_ADD = 0;
> +EAPI int ECORE_EVAS_EXTN_CLIENT_DEL = 0;
> +
> +void
> +_ecore_evas_extn_init(void)
> +{
> + if (ECORE_EVAS_EXTN_CLIENT_ADD) return;
> + ECORE_EVAS_EXTN_CLIENT_ADD = ecore_event_type_new();
> + ECORE_EVAS_EXTN_CLIENT_DEL = ecore_event_type_new();
> +}
> +
> +void
> +_ecore_evas_extn_shutdown(void)
> +{
> +}
> +
> static void
> +_ecore_evas_extn_event_free(void *data, void *ev)
> +{
> + Ecore_Evas *ee = data;
> + if (ee->engine.buffer.image)
> + evas_object_unref(ee->engine.buffer.image);
> + _ecore_evas_unref(ee);
> +}
> +
> +static void
> +_ecore_evas_extn_event(Ecore_Evas *ee, int event)
> +{
> + _ecore_evas_ref(ee);
> + if (ee->engine.buffer.image)
> + evas_object_ref(ee->engine.buffer.image);
> + ecore_event_add(event, ee->engine.buffer.image,
> + _ecore_evas_extn_event_free, ee);
> +}
> +
> +static void
> +_ecore_evas_socket_lock(Ecore_Evas *ee)
> +{
> + Extn *extn;
> +
> + extn = ee->engine.buffer.data;
> + if (!extn) return;
> + if (extn->file.lockfd < 0) return;
> + if (extn->file.have_lock) return;
> + flock(extn->file.lockfd, LOCK_EX);
> + extn->file.have_lock = EINA_TRUE;
> +}
> +
> +static void
> +_ecore_evas_socket_unlock(Ecore_Evas *ee)
> +{
> + Extn *extn;
> +
> + extn = ee->engine.buffer.data;
> + if (!extn) return;
> + if (extn->file.lockfd < 0) return;
> + if (!extn->file.have_lock) return;
> + flock(extn->file.lockfd, LOCK_UN);
> + extn->file.have_lock = EINA_FALSE;
> +}
> +
> +static void
> +_ecore_evas_extn_socket_targer_render_pre(void *data, Evas *e __UNUSED__,
> void *event_info __UNUSED__)
> +{
> + Ecore_Evas *ee = data;
> + if (ee) _ecore_evas_socket_lock(ee);
> +}
> +
> +static void
> +_ecore_evas_extn_socket_targer_render_post(void *data, Evas *e __UNUSED__,
> void *event_info __UNUSED__)
> +{
> + Ecore_Evas *ee = data;
> + if (ee) _ecore_evas_socket_unlock(ee);
> +}
> +
> +static void
> +_ecore_evas_extn_socket_image_obj_del(void *data, Evas *e __UNUSED__,
> Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
> +{
> + Ecore_Evas *ee = data;
> + if (ee) ecore_evas_free(ee);
> +}
> +
> +static void
> _ecore_evas_extn_coord_translate(Ecore_Evas *ee, Evas_Coord *x, Evas_Coord
> *y)
> {
> Evas_Coord xx, yy, ww, hh, fx, fy, fw, fh;
> @@ -414,6 +474,8 @@
> {
> Ecore_Event_Handler *hdl;
>
> + if (extn->file.have_lock)
> + _ecore_evas_socket_unlock(ee);
> if (extn->file.lockfd)
> {
> close(extn->file.lockfd);
> @@ -444,25 +506,28 @@
> {
> Ecore_Evas *ee2;
>
> + evas_object_event_callback_del_full(ee->engine.buffer.image,
> + EVAS_CALLBACK_DEL,
> +
> _ecore_evas_extn_socket_image_obj_del,
> + ee);
> +
> evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image),
> + EVAS_CALLBACK_RENDER_PRE,
> +
> _ecore_evas_extn_socket_targer_render_pre,
> + ee);
> +
> evas_event_callback_del_full(evas_object_evas_get(ee->engine.buffer.image),
> + EVAS_CALLBACK_RENDER_POST,
> +
> _ecore_evas_extn_socket_targer_render_post,
> + ee);
> + evas_object_del(ee->engine.buffer.image);
> ee2 = evas_object_data_get(ee->engine.buffer.image,
> "Ecore_Evas_Parent");
> - evas_object_del(ee->engine.buffer.image);
> - ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee);
> + if (ee2)
> + {
> + ee2->sub_ecore_evas = eina_list_remove(ee2->sub_ecore_evas, ee);
> + }
> }
> extn_ee_list = eina_list_remove(extn_ee_list, ee);
> }
>
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> static void
> _ecore_evas_resize(Ecore_Evas *ee, int w, int h)
> {
> @@ -1039,18 +1104,21 @@
> Ecore_Evas *ee = data;
> Extn *extn;
>
> - printf("client add\n");
> if (ee !=
> ecore_ipc_server_data_get(ecore_ipc_client_server_get(e->client)))
> return ECORE_CALLBACK_PASS_ON;
> if (!eina_list_data_find(extn_ee_list, ee))
> return ECORE_CALLBACK_PASS_ON;
> extn = ee->engine.buffer.data;
> if (!extn) return ECORE_CALLBACK_PASS_ON;
> - if (extn->ipc.client) return ECORE_CALLBACK_PASS_ON;
> - printf(" new cl = %p, old = %p\n", e->client, extn->ipc.client);
> + if (extn->ipc.client)
> + {
> + ecore_ipc_client_del(e->client);
> + return ECORE_CALLBACK_PASS_ON;
> + }
> extn->ipc.client = e->client;
>
> - ecore_ipc_client_send(extn->ipc.client, MAJOR, OP_LOCK_FILE, 0, 0, 0,
> extn->file.lock, strlen(extn->file.lock + 1));
> + ecore_ipc_client_send(extn->ipc.client, MAJOR, OP_LOCK_FILE, 0, 0, 0,
> + extn->file.lock, strlen(extn->file.lock) + 1);
> {
> Ipc_Data_Resize ipc;
>
> @@ -1062,8 +1130,8 @@
> ecore_ipc_client_send(extn->ipc.client, MAJOR, OP_SHOW, 0, 0, 0, NULL,
> 0);
> if (ee->prop.focused)
> ecore_ipc_client_send(extn->ipc.client, MAJOR, OP_FOCUS, 0, 0, 0, NULL,
> 0);
> + _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_ADD);
> return ECORE_CALLBACK_PASS_ON;
> - // FIXME: find a way to let app know client came along
> }
>
> static Eina_Bool
> @@ -1073,12 +1141,10 @@
> Ecore_Evas *ee = data;
> Extn *extn;
>
> - printf("client del\n");
> extn = ee->engine.buffer.data;
> if (!extn) return ECORE_CALLBACK_PASS_ON;
> if (extn->ipc.client == e->client)
> {
> - printf(" my client gone\n");
> evas_object_image_data_set(ee->engine.buffer.image, NULL);
> ee->engine.buffer.pixels = NULL;
> if (extn->file.shmfile)
> @@ -1093,7 +1159,7 @@
> }
> extn->ipc.client = NULL;
> }
> - // FIXME: find a way to let app know client left
> + _ecore_evas_extn_event(ee, ECORE_EVAS_EXTN_CLIENT_DEL);
> return ECORE_CALLBACK_PASS_ON;
> }
>
> @@ -1305,6 +1371,10 @@
> evas_object_event_callback_add(ee->engine.buffer.image,
> EVAS_CALLBACK_HIDE,
> _ecore_evas_extn_cb_hide, ee);
> +
> + evas_object_event_callback_add(ee->engine.buffer.image,
> + EVAS_CALLBACK_DEL,
> + _ecore_evas_extn_socket_image_obj_del, ee);
>
> extn = calloc(1, sizeof(Extn));
> if (!extn)
> @@ -1372,49 +1442,44 @@
> ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
> _ipc_client_data, ee));
> }
> - // FIXME: need callbacks for pre and post render on a canvas
> - // eg like EVAS_CALLBACK_RENDER_FLUSH_PRE/POST but covering all of it
> +
> extn_ee_list = eina_list_append(extn_ee_list, ee);
> ee_target->sub_ecore_evas = eina_list_append(ee_target->sub_ecore_evas,
> ee);
> -
> +
> + evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_PRE,
> + _ecore_evas_extn_socket_targer_render_pre, ee);
> + evas_event_callback_add(ee_target->evas, EVAS_CALLBACK_RENDER_POST,
> + _ecore_evas_extn_socket_targer_render_post, ee);
> return o;
> #else
> return NULL;
> #endif
> }
>
> +EAPI void
> +ecore_evas_extn_socket_object_data_lock(Evas_Object *obj)
> +{
> +#ifdef EXTN_ENABLED
> + Ecore_Evas *ee;
> +
> + ee = ecore_evas_object_ecore_evas_get(obj);
> + if (!ee) return;
> + _ecore_evas_socket_lock(ee);
> +#endif
> +}
>
> +EAPI void
> +ecore_evas_extn_socket_object_data_unlock(Evas_Object *obj)
> +{
> +#ifdef EXTN_ENABLED
> + Ecore_Evas *ee;
> +
> + ee = ecore_evas_object_ecore_evas_get(obj);
> + if (!ee) return;
> + _ecore_evas_socket_unlock(ee);
> +#endif
> +}
>
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> -
> #ifdef EXTN_ENABLED
> static void
> _ecore_evas_plug_resize(Ecore_Evas *ee, int w, int h)
> @@ -1506,7 +1571,9 @@
> }
> if (ee->engine.buffer.pixels)
> {
> + _ecore_evas_socket_lock(ee);
> updates = evas_render_updates(ee->evas);
> + _ecore_evas_socket_unlock(ee);
> }
> EINA_LIST_FOREACH(updates, l, r)
> {
>
> Modified: trunk/ecore/src/lib/ecore_evas/ecore_evas_private.h
> ===================================================================
> --- trunk/ecore/src/lib/ecore_evas/ecore_evas_private.h 2011-12-19 05:57:31
> UTC (rev 66319)
> +++ trunk/ecore/src/lib/ecore_evas/ecore_evas_private.h 2011-12-19 06:54:08
> UTC (rev 66320)
> @@ -418,4 +418,7 @@
>
> extern Eina_Bool _ecore_evas_app_comp_sync;
>
> +void _ecore_evas_extn_init(void);
> +void _ecore_evas_extn_shutdown(void);
> +
> #endif
>
>
> ------------------------------------------------------------------------------
> Learn Windows Azure Live! Tuesday, Dec 13, 2011
> Microsoft is holding a special Learn Windows Azure training event for
> developers. It will provide a great way to learn Windows Azure and what it
> provides. You can attend the event by watching it streamed LIVE online.
> Learn more at http://p.sf.net/sfu/ms-windowsazure
> _______________________________________________
> enlightenment-svn mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
------------------------------------------------------------------------------
Learn Windows Azure Live! Tuesday, Dec 13, 2011
Microsoft is holding a special Learn Windows Azure training event for
developers. It will provide a great way to learn Windows Azure and what it
provides. You can attend the event by watching it streamed LIVE online.
Learn more at http://p.sf.net/sfu/ms-windowsazure
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel