On Mon, Dec 19, 2011 at 7:54 AM, Enlightenment SVN
<no-re...@enlightenment.org> 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
> enlightenment-...@lists.sourceforge.net
> 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
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to