ecore_evas: change VNC API and use snapshot internally.
authorCedric BAIL <cedric@osg.samsung.com>
Wed, 22 Mar 2017 18:19:27 +0000 (11:19 -0700)
committerCedric BAIL <cedric@osg.samsung.com>
Wed, 12 Apr 2017 22:13:19 +0000 (15:13 -0700)
src/lib/ecore_evas/Ecore_Evas.h
src/lib/ecore_evas/ecore_evas.c
src/lib/ecore_evas/ecore_evas_private.h
src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c
src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c

index df514ab..2dd4687 100644 (file)
@@ -2579,23 +2579,15 @@ typedef void (*Ecore_Evas_Vnc_Client_Disconnected_Cb)(void *data, Ecore_Evas *ee
  * @param accept_cb A callback used to accept a new client. If @c NULL all clients will be accepted.
  * @param disc_cb A callback used to inform that a client has disconnected. It may be @c NULL.
  * @param data Data to @a cb
- * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ * @return an Evas_Object that take everything under it to represent the view of the client.
  * @see ecore_evas_vnc_stop()
  * @see Ecore_Evas_Vnc_Client_Accept_Cb()
  * @since 1.19
  */
-EAPI Eina_Bool      ecore_evas_vnc_start(Ecore_Evas *ee, const char *addr, int port, Ecore_Evas_Vnc_Client_Accept_Cb accept_cb,
-                                         Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb, void *data);
-
-/**
- * @brief Stops a running VNC server
- *
- * @param ee Ecore_Evas to stop the VNC server
- * @return @c EINA_TRUE if the VNC server was stopped, @c EINA_FALSE otherwise.
- * @see ecore_evas_vnc_start()
- * @since 1.19
- */
-EAPI Eina_Bool      ecore_evas_vnc_stop(Ecore_Evas *ee);
+EAPI Evas_Object *ecore_evas_vnc_start(Ecore_Evas *ee, const char *addr, int port,
+                                       Ecore_Evas_Vnc_Client_Accept_Cb accept_cb,
+                                       Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb,
+                                       void *data);
 
 #endif
 
index 8f4fe40..bc847b0 100644 (file)
@@ -2613,31 +2613,31 @@ ecore_evas_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
 
 EAPI void
 ecore_evas_pointer_device_xy_get(const Ecore_Evas *ee,
-                                 const Efl_Input_Device *pointer, Evas_Coord *x,
-                                 Evas_Coord *y)
+                                 const Efl_Input_Device *pointer,
+                                 Evas_Coord *x, Evas_Coord *y)
 {
+   ECORE_EVAS_CHECK(ee);
+
    if ((!pointer) ||
        (pointer == evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_CLASS_MOUSE)))
      ecore_evas_pointer_xy_get(ee, x, y);
    else
      {
-        if (x) *x = 0;
-        if (y) *y = 0;
-        ECORE_EVAS_CHECK(ee);
-        if (ee->vnc_server)
-          {
-             Eina_Module *mod;
-             void (*pointer_xy_get)(const void *, const Efl_Input_Device *, Evas_Coord *, Evas_Coord *y);
+        static Eina_Bool (*pointer_xy_get)(const Evas_Object *, const Efl_Input_Device *, Evas_Coord *, Evas_Coord *y) = NULL;
+        Eina_Module *mod;
 
+        if (!pointer_xy_get && ee->vnc_server)
+          {
              mod = _ecore_evas_vnc_server_module_load();
              EINA_SAFETY_ON_NULL_RETURN(mod);
 
              pointer_xy_get = eina_module_symbol_get(mod, "ecore_evas_vnc_server_pointer_xy_get");
              EINA_SAFETY_ON_NULL_RETURN(pointer_xy_get);
-             pointer_xy_get(ee->vnc_server, pointer, x, y);
           }
-        else if (ee->engine.func->fn_pointer_device_xy_get)
-          ee->engine.func->fn_pointer_device_xy_get(ee, pointer, x, y);
+
+        // FIXME: Handle matching of the efl_input_device with proper evas_object
+
+        ecore_evas_pointer_xy_get(ee, x, y);
      }
 }
 
@@ -3050,17 +3050,12 @@ _ecore_evas_unref(Ecore_Evas *ee)
 static Eina_Bool
 _ecore_evas_vnc_stop(Ecore_Evas *ee)
 {
-   Eina_Module *mod;
-   void (*vnc_del)(void *);
-
-   mod = _ecore_evas_vnc_server_module_load();
-   EINA_SAFETY_ON_NULL_RETURN_VAL(mod, EINA_FALSE);
+   Evas_Object *obj;
+   Eina_List *l;
 
-   vnc_del = eina_module_symbol_get(mod, "ecore_evas_vnc_server_del");
-   EINA_SAFETY_ON_NULL_RETURN_VAL(vnc_del, EINA_FALSE);
+   EINA_LIST_FOREACH(ee->vnc_server, l, obj)
+     evas_object_del(obj);
 
-   vnc_del(ee->vnc_server);
-   ee->vnc_server = NULL;
    return EINA_TRUE;
 }
 
@@ -3849,41 +3844,36 @@ ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
    iface->shape_input_apply(ee);
 }
 
-EAPI Eina_Bool
+EAPI Evas_Object *
 ecore_evas_vnc_start(Ecore_Evas *ee, const char *addr, int port,
                      Ecore_Evas_Vnc_Client_Accept_Cb accept_cb,
                      Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb,
                      void *data)
 {
-   Eina_Module *mod;
-   void *(*vnc_new)(Ecore_Evas *, int, const char *,
-                    Ecore_Evas_Vnc_Client_Accept_Cb,
-                    Ecore_Evas_Vnc_Client_Disconnected_Cb,
-                    void *);
+   static Evas_Object *(*vnc_new)(Ecore_Evas *, int, const char *,
+                                  Ecore_Evas_Vnc_Client_Accept_Cb,
+                                  Ecore_Evas_Vnc_Client_Disconnected_Cb,
+                                  void *) = NULL;
+   Evas_Object *r;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
-
-   if (ee->vnc_server)
-     return EINA_FALSE;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ee, NULL);
 
-   mod = _ecore_evas_vnc_server_module_load();
-   EINA_SAFETY_ON_NULL_RETURN_VAL(mod, EINA_FALSE);
+   if (!vnc_new)
+     {
+        Eina_Module *mod;
 
-   vnc_new = eina_module_symbol_get(mod, "ecore_evas_vnc_server_new");
-   EINA_SAFETY_ON_NULL_RETURN_VAL(vnc_new, EINA_FALSE);
+        mod = _ecore_evas_vnc_server_module_load();
+        EINA_SAFETY_ON_NULL_RETURN_VAL(mod, NULL);
 
-   ee->vnc_server = vnc_new(ee, port, addr, accept_cb, disc_cb, data);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ee->vnc_server, EINA_FALSE);
-   return EINA_TRUE;
-}
+        vnc_new = eina_module_symbol_get(mod, "ecore_evas_vnc_server_new");
+        EINA_SAFETY_ON_NULL_RETURN_VAL(vnc_new, NULL);
+     }
 
-EAPI Eina_Bool
-ecore_evas_vnc_stop(Ecore_Evas *ee)
-{
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE);
-   EINA_SAFETY_ON_FALSE_RETURN_VAL(ee->vnc_server, EINA_FALSE);
+   r = vnc_new(ee, port, addr, accept_cb, disc_cb, data);
+   if (!r) return NULL;
 
-   return _ecore_evas_vnc_stop(ee);
+   ee->vnc_server = eina_list_append(ee->vnc_server, r);
+   return r;
 }
 
 EAPI Ecore_Evas *
index 7400503..25fa6de 100644 (file)
@@ -218,7 +218,7 @@ struct _Ecore_Evas
    Eina_Hash  *data;
    Eina_List  *mice_in;
 
-   void *vnc_server; /* @since 1.19 */
+   Eina_List  *vnc_server; /* @since 1.19 */
 
    struct {
       int      x, y, w, h;
index 88c02d2..6a55da5 100644 (file)
@@ -79,7 +79,9 @@ typedef struct _Ecore_Evas_Vnc_Server {
    Ecore_Evas_Vnc_Client_Accept_Cb accept_cb;
    Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb;
    void *cb_data;
+   Evas_Object *snapshot;
    Ecore_Evas *ee;
+   Eina_Tiler *t;
    Ecore_Evas_Vnc_Key_Info_Get key_info_get_func;
    double double_click_time;
    int last_w;
@@ -321,29 +323,6 @@ _ecore_evas_vnc_server_ecore_event_generic_free(void *user_data,
    free(func_data);
 }
 
-#ifdef BUILD_ENGINE_SOFTWARE_X11
-static Eina_Bool
-_ecore_evas_vnc_server_x11_key_info_get(rfbKeySym key,
-                                        const char **key_name,
-                                        const char **key_str,
-                                        const char **compose,
-                                        int *keycode)
-{
-   *key_str = *key_name = ecore_x_keysym_string_get(key);
-
-   if (!*key_str)
-     {
-        *keycode = 0;
-        return EINA_FALSE;
-     }
-
-   *compose = NULL;
-   *keycode = ecore_x_keysym_keycode_get(*key_str);
-   return EINA_TRUE;
-}
-#endif
-
-#ifdef BUILD_ENGINE_FB
 static Eina_Bool
 _ecore_evas_vnc_server_fb_key_info_get(rfbKeySym key,
                                        const char **key_name,
@@ -355,7 +334,6 @@ _ecore_evas_vnc_server_fb_key_info_get(rfbKeySym key,
                                                        key_name, key_str,
                                                        compose);
 }
-#endif
 
 static void
 _ecore_evas_vnc_server_client_keyboard_event(rfbBool down,
@@ -630,152 +608,161 @@ _ecore_evas_vnc_server_shutdown(void)
    eina_shutdown();
 }
 
+static inline int
+align4(int v)
+{
+   return ((v / 4) + (v % 4 ? 1 : 0)) * 4;
+}
+
 static void
-_ecore_evas_vnc_server_draw(Evas *evas, int x, int y,
-                            int w, int h, const void *pixels)
+_ecore_evas_vnc_server_draw(void *data, Evas *e EINA_UNUSED, void *event_info)
 {
+   Evas_Event_Render_Post *post = event_info;
+   Evas_Object *snapshot = data;
    Ecore_Evas_Vnc_Server *server;
-   Ecore_Evas *ee;
-   size_t size, src_stride;
-   int dy;
+   const void *pixels;
+   Eina_List *l;
+   Eina_Rectangle *r;
+   size_t size;
    Eina_Bool new_buf = EINA_FALSE;
+   Eina_Rectangle snapshot_pos;
+
+   // Nothing was updated, so let's not bother sending nothingness
+   if (!post->updated_area) return ;
 
-   ee = evas_data_attach_get(evas);
-   server = ee->vnc_server;
+   server = evas_object_data_get(snapshot, "_ecore_evas.vnc");
+   EINA_SAFETY_ON_NULL_RETURN(server);
+
+   pixels = evas_object_image_data_get(snapshot, EINA_FALSE);
+   evas_object_geometry_get(snapshot,
+                            &snapshot_pos.x,
+                            &snapshot_pos.y,
+                            &snapshot_pos.w,
+                            &snapshot_pos.h);
+
+   // Align size on 4 pixels for vnc library stability
+   snapshot_pos.w = align4(snapshot_pos.w);
+   snapshot_pos.h = align4(snapshot_pos.h);
 
-   if (!server) return;
+   DBG("Preparing sending of buffer {%i, %i} with %i updates.", snapshot_pos.w, snapshot_pos.h, eina_list_count(post->updated_area));
 
-   if (!server->frame_buffer || server->last_w != ee->w || server->last_h != ee->h)
+   if (!server->frame_buffer ||
+       server->last_w != snapshot_pos.w ||
+       server->last_h != snapshot_pos.h)
      {
+        Eina_Rectangle tmp = { 0, 0, snapshot_pos.w, snapshot_pos.h };
         char *new_fb;
 
-        size = ee->w * ee->h * VNC_BYTES_PER_PIXEL;
+        size = snapshot_pos.w * snapshot_pos.h * VNC_BYTES_PER_PIXEL;
         new_fb = malloc(size);
         EINA_SAFETY_ON_NULL_RETURN(new_fb);
         free(server->frame_buffer);
         server->frame_buffer = new_fb;
-        server->last_w = ee->w;
-        server->last_h = ee->h;
+        server->last_w = snapshot_pos.w;
+        server->last_h = snapshot_pos.h;
         new_buf = EINA_TRUE;
+        eina_tiler_area_size_set(server->t, snapshot_pos.w, snapshot_pos.h);
+        eina_tiler_rect_add(server->t, &tmp);
 
-        rfbNewFramebuffer(server->vnc_screen, server->frame_buffer, ee->w,
-                          ee->h, VNC_BITS_PER_SAMPLE, VNC_SAMPLES_PER_PIXEL,
-                          VNC_BYTES_PER_PIXEL);
+        rfbNewFramebuffer(server->vnc_screen, server->frame_buffer,
+                          snapshot_pos.w, snapshot_pos.h,
+                          VNC_BITS_PER_SAMPLE, VNC_SAMPLES_PER_PIXEL, VNC_BYTES_PER_PIXEL);
         _ecore_evas_vnc_server_format_setup(server->vnc_screen);
      }
 
-   if (y > server->last_h || x > server->last_w)
-     return;
+   EINA_LIST_FOREACH(post->updated_area, l, r)
+     {
+        Eina_Rectangle tmp = *r;
+        size_t src_stride;
+        int dy;
 
-   //Do not paint outside the VNC canvas
-   if (y + h > server->last_h)
-     h = server->last_h - y;
+        if (tmp.x > snapshot_pos.w ||
+            tmp.y > snapshot_pos.h)
+          continue ;
 
-   //Do not paint outside the VNC canvas
-   if (x + w > server->last_w)
-     w = server->last_w - x;
+        if (!eina_rectangle_intersection(&tmp, &snapshot_pos))
+          continue ;
 
-   src_stride = w * VNC_BYTES_PER_PIXEL;
+        src_stride = tmp.w * VNC_BYTES_PER_PIXEL;
 
-   for (dy = 0; dy < h; dy++)
-     {
-        memcpy(server->frame_buffer + (x * VNC_BYTES_PER_PIXEL)
-               + ((dy + y) * (server->last_w * VNC_BYTES_PER_PIXEL)),
-               (char *)pixels + (dy * src_stride), src_stride);
+        for (dy = 0; dy < tmp.h; dy++)
+          {
+             memcpy(server->frame_buffer + (tmp.x * VNC_BYTES_PER_PIXEL)
+                    + ((dy + tmp.y) * (snapshot_pos.w * VNC_BYTES_PER_PIXEL)),
+                    (char *)pixels + (dy * src_stride), src_stride);
+          }
+
+        rfbMarkRectAsModified(server->vnc_screen,
+                              tmp.x, tmp.y, tmp.x + tmp.w, tmp.y + tmp.h);
+
+        if (new_buf) eina_tiler_rect_del(server->t, &tmp);
      }
 
    //We did not receive the whole buffer yet, zero the missing bytes for now.
    if (new_buf)
      {
-        //Missing width
-        if (server->last_w != w || x != 0)
-          {
-             for (dy = 0; dy < h; dy++)
-               {
-                  if (x)
-                    {
-                       memset(server->frame_buffer
-                              + ((dy + y) * (server->last_w * VNC_BYTES_PER_PIXEL)),
-                              0, x * VNC_BYTES_PER_PIXEL);
-                    }
-
-                  memset(server->frame_buffer +
-                         ((dy + y) * (server->last_w * VNC_BYTES_PER_PIXEL))
-                         + ((x + w) * VNC_BYTES_PER_PIXEL),
-                         0, (server->last_w - (w + x)) * VNC_BYTES_PER_PIXEL);
-               }
-          }
+        Eina_Iterator *it;
 
-        //Missing height
-        if (server->last_h != h || y != 0)
+        it = eina_tiler_iterator_new(server->t);
+        EINA_ITERATOR_FOREACH(it, r)
           {
-             src_stride = server->last_w * VNC_BYTES_PER_PIXEL;
-             for (dy = 0; dy < y; dy++)
-               memset(server->frame_buffer + (dy * src_stride), 0, src_stride);
+             Eina_Rectangle tmp = *r;
+             size_t src_stride;
+             int dy;
+
+             src_stride = tmp.w * VNC_BYTES_PER_PIXEL;
 
-             for (dy = y + h; dy < server->last_h; dy++)
-               memset(server->frame_buffer + (dy * src_stride), 0, src_stride);
+             for (dy = 0; dy < tmp.h; dy++)
+               {
+                  memset(server->frame_buffer + (tmp.x * VNC_BYTES_PER_PIXEL)
+                         + ((dy + tmp.y) * (snapshot_pos.w * VNC_BYTES_PER_PIXEL)),
+                         0, src_stride);
+               }
           }
+        eina_iterator_free(it);
+        eina_tiler_clear(server->t);
      }
 
-   rfbMarkRectAsModified(server->vnc_screen, x, y, x+w, y+h);
    _ecore_evas_vnc_server_update_clients(server->vnc_screen);
 }
 
-EAPI Ecore_Evas_Vnc_Server *
+static void
+_ecore_evas_vnc_server_del(void *data, const Efl_Event *ev EINA_UNUSED)
+{
+   Ecore_Evas_Vnc_Server *server = data;
+
+   ecore_main_fd_handler_del(server->vnc_listen6_handler);
+   ecore_main_fd_handler_del(server->vnc_listen_handler);
+   evas_object_del(server->snapshot);
+   rfbShutdownServer(server->vnc_screen, TRUE);
+   free(server->frame_buffer);
+   rfbScreenCleanup(server->vnc_screen);
+   free(server);
+}
+
+EAPI Evas_Object *
 ecore_evas_vnc_server_new(Ecore_Evas *ee, int port, const char *addr,
                           Ecore_Evas_Vnc_Client_Accept_Cb accept_cb,
                           Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb,
                           void *data)
 {
    Ecore_Evas_Vnc_Server *server;
+   Evas_Object *snapshot;
    Eina_Bool can_listen = EINA_FALSE;
-   Evas_Engine_Info *engine;
-   Eina_Bool err, engine_set = EINA_FALSE;
-   Ecore_Evas_Vnc_Key_Info_Get key_info_get_func;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ee, NULL);
 
-   engine = evas_engine_info_get(ee->evas);
-
-#ifdef BUILD_ENGINE_SOFTWARE_X11
-   if (!strcmp(ee->driver, "software_x11"))
-     {
-        Evas_Engine_Info_Software_X11 *x11_engine;
-
-        x11_engine = (Evas_Engine_Info_Software_X11 *)engine;
-        x11_engine->func.region_push_hook = _ecore_evas_vnc_server_draw;
-        x11_engine->push_to = ee->evas;
-        engine_set = EINA_TRUE;
-        key_info_get_func = _ecore_evas_vnc_server_x11_key_info_get;
-     }
-#endif
-
-#ifdef BUILD_ENGINE_FB
-   if (!engine_set && !strcmp(ee->driver, "fb"))
-     {
-        Evas_Engine_Info_FB *fb_engine;
-
-        fb_engine = (Evas_Engine_Info_FB *)engine;
-        fb_engine->func.region_push_hook = _ecore_evas_vnc_server_draw;
-        fb_engine->push_to = ee->evas;
-        engine_set = EINA_TRUE;
-        key_info_get_func = _ecore_evas_vnc_server_fb_key_info_get;
-     }
-#endif
-
-   if (!engine_set)
-     {
-        WRN("The engine '%s' is not supported. Only Software X11"
-            " and FB are supported.", ee->driver);
-        return NULL;
-     }
-
    server = calloc(1, sizeof(Ecore_Evas_Vnc_Server));
    EINA_SAFETY_ON_NULL_RETURN_VAL(server, NULL);
-   server->key_info_get_func = key_info_get_func;
 
-   server->vnc_screen = rfbGetScreen(0, NULL, ee->w, ee->h, VNC_BITS_PER_SAMPLE,
+   snapshot = evas_object_image_filled_add(ee->evas);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(snapshot, NULL);
+   evas_object_image_snapshot_set(snapshot, EINA_TRUE);
+   efl_event_callback_del(snapshot, EFL_EVENT_DEL, _ecore_evas_vnc_server_del, server);
+
+   server->key_info_get_func = _ecore_evas_vnc_server_fb_key_info_get;
+
+   server->vnc_screen = rfbGetScreen(0, NULL, 4, 4, VNC_BITS_PER_SAMPLE,
                                      VNC_SAMPLES_PER_PIXEL, VNC_BYTES_PER_PIXEL);
    EINA_SAFETY_ON_NULL_GOTO(server->vnc_screen, err_screen);
 
@@ -825,18 +812,22 @@ ecore_evas_vnc_server_new(Ecore_Evas *ee, int port, const char *addr,
      }
 
    //rfbInitServer() failed and could not setup the sockets.
-   EINA_SAFETY_ON_FALSE_GOTO(can_listen, err_listen);
-
-   err = evas_engine_info_set(ee->evas, (Evas_Engine_Info *)engine);
-   EINA_SAFETY_ON_FALSE_GOTO(err, err_engine);
+   EINA_SAFETY_ON_FALSE_GOTO(can_listen, err_engine);
 
+   server->ee = ee;
    server->vnc_screen->screenData = server;
    server->cb_data = data;
    server->accept_cb = accept_cb;
    server->disc_cb = disc_cb;
-   server->ee = ee;
+   server->snapshot = snapshot;
+   server->t = eina_tiler_new(1, 1);
+   eina_tiler_tile_size_set(server->t, 1, 1);
+   eina_tiler_strict_set(server->t, EINA_TRUE);
 
-   return server;
+   evas_object_data_set(snapshot, "_ecore_evas.vnc", server);
+   evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST, _ecore_evas_vnc_server_draw, snapshot);
+
+   return snapshot;
 
  err_engine:
    ecore_main_fd_handler_del(server->vnc_listen6_handler);
@@ -851,62 +842,22 @@ ecore_evas_vnc_server_new(Ecore_Evas *ee, int port, const char *addr,
    return NULL;
 }
 
-EAPI void
-ecore_evas_vnc_server_del(Ecore_Evas_Vnc_Server *server)
-{
-   Evas_Engine_Info *engine;
-   Eina_Bool err;
-
-   EINA_SAFETY_ON_NULL_RETURN(server);
-
-   engine = evas_engine_info_get(server->ee->evas);
-
-#ifdef BUILD_ENGINE_SOFTWARE_X11
-   if (!strcmp(server->ee->driver, "software_x11"))
-     {
-        Evas_Engine_Info_Software_X11 *x11_engine;
-
-        x11_engine = (Evas_Engine_Info_Software_X11 *)engine;
-        x11_engine->func.region_push_hook = NULL;
-        x11_engine->push_to = NULL;
-     }
-#endif
-#ifdef BUILD_ENGINE_FB
-   if (!strcmp(server->ee->driver, "fb"))
-     {
-        Evas_Engine_Info_FB *fb_engine;
-
-        fb_engine = (Evas_Engine_Info_FB *)engine;
-        fb_engine->func.region_push_hook = NULL;
-        fb_engine->push_to = NULL;
-     }
-#endif
-
-   err = evas_engine_info_set(server->ee->evas, engine);
-   if (!err)
-     WRN("Could not unset the region push hook callback");
-   ecore_main_fd_handler_del(server->vnc_listen6_handler);
-   ecore_main_fd_handler_del(server->vnc_listen_handler);
-   rfbShutdownServer(server->vnc_screen, TRUE);
-   free(server->frame_buffer);
-   rfbScreenCleanup(server->vnc_screen);
-   free(server);
-}
-
-EAPI void
-ecore_evas_vnc_server_pointer_xy_get(const Ecore_Evas_Vnc_Server *server,
+EAPI Eina_Bool
+ecore_evas_vnc_server_pointer_xy_get(const Evas_Object *snapshot,
                                      const Evas_Device *pointer,
                                      Evas_Coord *x, Evas_Coord *y)
 {
-   Evas_Coord sx, sy;
-   rfbClientIteratorPtr itr;
+   Ecore_Evas_Vnc_Server *server;
    rfbClientRec *client;
    Ecore_Evas_Vnc_Server_Client_Data *cdata;
+   rfbClientIteratorPtr itr;
 
-   EINA_SAFETY_ON_NULL_RETURN(server);
-   EINA_SAFETY_ON_NULL_RETURN(pointer);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(snapshot, EINA_FALSE);
+   server = evas_object_data_get(snapshot, "_ecore_evas.vnc");
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(server, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(pointer, EINA_FALSE);
 
-   sx = sy = 0;
    itr = rfbGetClientIterator(server->vnc_screen);
 
    while ((client = rfbClientIteratorNext(itr)))
@@ -915,15 +866,14 @@ ecore_evas_vnc_server_pointer_xy_get(const Ecore_Evas_Vnc_Server *server,
 
         if (cdata->mouse == pointer)
           {
-             sx = client->lastPtrX;
-             sy = client->lastPtrY;
-             break;
+             if (x) *x = client->lastPtrX;
+             if (y) *y = client->lastPtrY;
+             return EINA_TRUE;
           }
      }
 
    rfbReleaseClientIterator(itr);
-   if (x) *x = sx;
-   if (y) *y = sy;
+   return EINA_FALSE;
 }
 
 EINA_MODULE_INIT(_ecore_evas_vnc_server_init);
index 36497ca..4193f1d 100644 (file)
@@ -360,4 +360,3 @@ ecore_evas_vnc_server_keysym_to_fb_translate(rfbKeySym key,
    *compose = _ecore_fb_li_kbd_syms[(id* 7) + 3 + offset];
    return EINA_TRUE;
 }
-