bdilly pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=bc6e8d2692084a808c0cf7012e7db4a9849601e7

commit bc6e8d2692084a808c0cf7012e7db4a9849601e7
Author: Guilherme Iscaro <isc...@profusion.mobi>
Date:   Wed Sep 21 13:52:57 2016 -0300

    Ecore_Evas_X: Add VNC draw support.
    
    This patch adds the support to draw the X11 screen contents to
    all remove VNC clients.
---
 configure.ac                                    |  24 +-
 src/lib/ecore_evas/Ecore_Evas.h                 |  36 +++
 src/lib/ecore_evas/ecore_evas.c                 |  31 +++
 src/lib/ecore_evas/ecore_evas_x11.h             |   4 +
 src/modules/ecore_evas/engines/x/ecore_evas_x.c | 353 ++++++++++++++++++++++++
 5 files changed, 446 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 61d3c9d..9c18780 100644
--- a/configure.ac
+++ b/configure.ac
@@ -433,6 +433,24 @@ AC_DEFINE_IF([ENABLE_LIBLZ4], [test "${want_liblz4}" = 
"yes"], [1], [Use liblz4
 AC_SUBST([want_liblz4])
 AC_SUBST([ENABLE_LIBLZ4])
 
+
+want_vnc_server="no"
+AC_ARG_ENABLE([vnc-server],
+   [AS_HELP_STRING([--enable-vnc-server],[Enable VNC server support for 
Ecore_Evas_X. @<:@default=disabled@:>@])],
+   [
+    if test "x${enableval}" = "xyes" ; then
+       want_vnc_server="yes"
+    else
+       want_vnc_server="no"
+    fi
+   ],
+   [want_vnc_server="no"])
+
+AM_CONDITIONAL([ENABLE_VNC_SERVER], [test "${want_vnc_server}" = "yes"])
+AC_DEFINE_IF([ENABLE_VNC_SERVER], [test "${want_vnc_server}" = "yes"], [1], 
[Use VNC server support for Ecore_Evas_X])
+AC_SUBST([want_vnc_server])
+AC_SUBST([ENABLE_VNC_SERVER])
+
 #### Checks for header files
 
 # Common Checks (keep names sorted for ease of use):
@@ -4622,7 +4640,8 @@ AM_CONDITIONAL([BUILD_ECORE_EVAS_WIN32],
 
 # XXX TODO: ecore_evas_x11
 
-ECORE_EVAS_MODULE([software-x11], [${want_x11_any}])
+ECORE_EVAS_MODULE([software-x11], [${want_x11_any}],
+  [EFL_OPTIONAL_DEPEND_PKG([ECORE_EVAS], [${want_vnc_server}], [VNC_SERVER], 
[libvncserver])])
 
 have_ecore_evas_software_xlib="no"
 have_ecore_evas_software_xcb="no"
@@ -4645,7 +4664,8 @@ fi
 
 # XXX TODO: ecore_evas_opengl_x11
 
-ECORE_EVAS_MODULE([opengl-x11], [${want_x11_any_opengl}])
+ECORE_EVAS_MODULE([opengl-x11], [${want_x11_any_opengl}],
+  [EFL_OPTIONAL_DEPEND_PKG([ECORE_EVAS], [${want_vnc_server}], [VNC_SERVER], 
[libvncserver])])
 
 have_ecore_evas_opengl_xlib="no"
 have_ecore_evas_opengl_xcb="no"
diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h
index 30e45b1..d9827ac 100644
--- a/src/lib/ecore_evas/Ecore_Evas.h
+++ b/src/lib/ecore_evas/Ecore_Evas.h
@@ -2398,6 +2398,42 @@ EAPI void           
ecore_evas_x11_shape_input_reset(Ecore_Evas *ee);
 EAPI void           ecore_evas_x11_shape_input_apply(Ecore_Evas *ee);
 
 /**
+ * @brief A callback used to accept a new client.
+ * @param data The callback data
+ * @param ee The Ecore_Evas
+ * @param client_host The address of the new client.
+ * @return @c EINA_TRUE to accep the client, @c EINA_FALSE otherwise.
+ * @see ecore_evas_vnc_start()
+ * @since 1.19
+ */
+typedef Eina_Bool (*Ecore_Evas_Vnc_Client_Accept_Cb)(void *data, Ecore_Evas 
*ee, const char *client_host);
+
+/**
+ * @brief Starts a VNC server.
+ *
+ * @param ee The Ecore_Evas to start the VNC server
+ * @param addr The address that will be used to bind the VNC server. Use @c 
NULL to bind to any interface.
+ * @param port The port number to start the VNC server. Use @c -1 to set the 
default VNC port (5900)
+ * @param cb A callback used to accept a new client. If @c NULL all clients 
will be accepted.
+ * @param data Data to @a cb
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
+ * @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 cb, void *data);
+
+/**
+ * @brief Stop 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);
+
+/**
  * @defgroup Ecore_Evas_Ews Ecore_Evas Single Process Windowing System.
  * @ingroup Ecore_Evas_Group
  *
diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c
index 72e4699..979a6ae 100644
--- a/src/lib/ecore_evas/ecore_evas.c
+++ b/src/lib/ecore_evas/ecore_evas.c
@@ -3955,6 +3955,37 @@ ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
    iface->shape_input_apply(ee);
 }
 
+EAPI Eina_Bool
+ecore_evas_vnc_start(Ecore_Evas *ee, const char *addr, int port,
+                         Ecore_Evas_Vnc_Client_Accept_Cb cb, void *data)
+{
+   Ecore_Evas_Interface_X11 *iface;
+
+   if (strcmp(ee->driver, "software_x11"))
+     return EINA_FALSE;
+
+   iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iface->vnc_start, EINA_FALSE);
+
+   return iface->vnc_start(ee, addr, port, cb, data);
+}
+
+EAPI Eina_Bool
+ecore_evas_vnc_stop(Ecore_Evas *ee)
+{
+   Ecore_Evas_Interface_X11 *iface;
+
+   if (strcmp(ee->driver, "software_x11"))
+     return EINA_FALSE;
+
+   iface = (Ecore_Evas_Interface_X11 *)_ecore_evas_interface_get(ee, "x11");
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iface, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(iface->vnc_stop, EINA_FALSE);
+
+   return iface->vnc_stop(ee);
+}
+
 EAPI Ecore_Evas *
 ecore_evas_extn_socket_new(int w, int h)
 {
diff --git a/src/lib/ecore_evas/ecore_evas_x11.h 
b/src/lib/ecore_evas/ecore_evas_x11.h
index b349b7f..7d5e809 100644
--- a/src/lib/ecore_evas/ecore_evas_x11.h
+++ b/src/lib/ecore_evas/ecore_evas_x11.h
@@ -17,6 +17,10 @@ struct _Ecore_Evas_Interface_X11 {
    void           (*shape_input_empty)(Ecore_Evas *ee);
    void           (*shape_input_reset)(Ecore_Evas *ee);
    void           (*shape_input_apply)(Ecore_Evas *ee);
+   Eina_Bool      (*vnc_start)(Ecore_Evas *ee, const char *addr, int port,
+                               Ecore_Evas_Vnc_Client_Accept_Cb cb,
+                               void *data);
+   Eina_Bool      (*vnc_stop)(Ecore_Evas *ee);
 };
 
 struct _Ecore_Evas_Interface_Software_X11 {
diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c 
b/src/modules/ecore_evas/engines/x/ecore_evas_x.c
index e3bfaa8..88086e2 100644
--- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c
+++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c
@@ -26,6 +26,11 @@
 #include "ecore_evas_private.h"
 #include "ecore_evas_x11.h"
 
+#ifdef ENABLE_VNC_SERVER
+# include <rfb/rfb.h>
+# include <rfb/rfbregion.h>
+#endif
+
 #ifdef EAPI
 # undef EAPI
 #endif
@@ -131,6 +136,17 @@ struct _Ecore_Evas_Engine_Data_X11 {
         unsigned long colormap; // store colormap used to create pixmap
      } pixmap;
    Eina_Bool destroyed : 1; // X window has been deleted and cannot be used
+
+#ifdef ENABLE_VNC_SERVER
+   char *frame_buffer;
+   rfbScreenInfoPtr vnc_screen;
+   Ecore_Fd_Handler *vnc_listen_handler;
+   Ecore_Fd_Handler *vnc_listen6_handler;
+   Ecore_Evas_Vnc_Client_Accept_Cb accept_cb;
+   void *accept_cb_data;
+   int last_w;
+   int last_h;
+#endif
 };
 
 static Ecore_Evas_Interface_X11 * _ecore_evas_x_interface_x11_new(void);
@@ -152,6 +168,123 @@ static void _transparent_do(Ecore_Evas *, int);
 static void _avoid_damage_do(Ecore_Evas *, int);
 static void _rotation_do(Ecore_Evas *, int, int);
 
+#ifdef ENABLE_VNC_SERVER
+
+typedef struct _Ecore_Evas_X11_Vnc_Client_Data {
+   Ecore_Fd_Handler *handler;
+} Ecore_Evas_X11_Vnc_Client_Data;
+
+static unsigned int _available_seat = 1;
+
+#define VNC_BITS_PER_SAMPLE (8)
+#define VNC_SAMPLES_PER_PIXEL (3)
+#define VNC_BYTES_PER_PIXEL (4)
+
+static void
+_ecore_evas_x11_update_vnc_clients(rfbScreenInfoPtr vnc_screen)
+{
+   rfbClientIteratorPtr itr;
+   rfbClientRec *client;
+
+   itr = rfbGetClientIterator(vnc_screen);
+
+   //No clients.
+   if (!itr) return;
+
+   while ((client = rfbClientIteratorNext(itr))) {
+      rfbBool r;
+
+      r = rfbUpdateClient(client);
+
+      if (!r)
+        {
+           Ecore_Evas_X11_Vnc_Client_Data *cdata = client->clientData;
+
+           WRN("Could not update the VNC client on seat '%p'\n", cdata);
+        }
+
+      //Client disconnected
+      if (client->sock == -1) rfbClientConnectionGone(client);
+   }
+
+   rfbReleaseClientIterator(itr);
+}
+
+static void
+_ecore_evas_x11_vnc_server_format_setup(Ecore_Evas_Engine_Data_X11 *edata)
+{
+   int aux;
+
+   //FIXME: Using BGR - Is there a better way to do this?
+   aux = edata->vnc_screen->serverFormat.redShift;
+   edata->vnc_screen->serverFormat.redShift = 
edata->vnc_screen->serverFormat.blueShift;
+   edata->vnc_screen->serverFormat.blueShift = aux;
+}
+
+static void
+_ecore_evas_x11_region_push_hook(Evas *e, int x, int y, int w, int h,
+                                 const void *pixels)
+{
+   Ecore_Evas *ee;
+   Ecore_Evas_Engine_Data_X11 *edata;
+   size_t size;
+
+   ee = evas_data_attach_get(e);
+   edata = ee->engine.data;
+
+   if (!edata->frame_buffer || edata->last_w != ee->w || edata->last_h != 
ee->h)
+     {
+        char *new_fb;
+
+        size = ee->w * ee->h * VNC_BYTES_PER_PIXEL;
+        new_fb = malloc(size);
+        EINA_SAFETY_ON_NULL_RETURN(new_fb);
+        free(edata->frame_buffer);
+        memcpy(new_fb, pixels, size);
+        edata->frame_buffer = new_fb;
+        edata->last_w = ee->w;
+        edata->last_h = ee->h;
+        if (edata->vnc_screen)
+          {
+             rfbNewFramebuffer(edata->vnc_screen, edata->frame_buffer, ee->w,
+                               ee->h, VNC_BITS_PER_SAMPLE, 
VNC_SAMPLES_PER_PIXEL,
+                               VNC_BYTES_PER_PIXEL);
+             _ecore_evas_x11_vnc_server_format_setup(edata);
+          }
+     }
+   else
+     {
+        //Partial update
+        int dy;
+        const int src_stride = w * VNC_BYTES_PER_PIXEL;
+
+        for (dy = 0; dy < h; dy++)
+          {
+             memcpy(edata->frame_buffer + (x * VNC_BYTES_PER_PIXEL)
+                    + ((dy + y) * (edata->last_w * VNC_BYTES_PER_PIXEL)),
+                    (char *)pixels + (dy * src_stride), src_stride);
+          }
+     }
+
+   if (edata->vnc_screen)
+     {
+        rfbMarkRectAsModified(edata->vnc_screen, x, y, x+w, y+h);
+        _ecore_evas_x11_update_vnc_clients(edata->vnc_screen);
+     }
+}
+
+#else
+
+static void
+_ecore_evas_x11_region_push_hook(Evas *e EINA_UNUSED, int x EINA_UNUSED,
+                                 int y EINA_UNUSED, int w EINA_UNUSED,
+                                 int h EINA_UNUSED,
+                                 const void *pixels EINA_UNUSED)
+{
+}
+
+#endif //ENABLE_VNC_SERVER
+
 static void
 _ecore_evas_x_hints_update(Ecore_Evas *ee)
 {
@@ -2059,6 +2192,16 @@ _ecore_evas_x_free(Ecore_Evas *ee)
         ecore_timer_del(edata->outdelay);
         edata->outdelay = NULL;
      }
+#ifdef ENABLE_VNC_SERVER
+   if (edata->vnc_screen)
+     {
+        ecore_main_fd_handler_del(edata->vnc_listen6_handler);
+        ecore_main_fd_handler_del(edata->vnc_listen_handler);
+        free(edata->frame_buffer);
+        rfbScreenCleanup(edata->vnc_screen);
+        edata->vnc_screen = NULL;
+     }
+#endif
    free(edata);
    _ecore_evas_x_shutdown();
    ecore_x_shutdown();
@@ -4110,6 +4253,7 @@ ecore_evas_software_x11_new_internal(const char 
*disp_name, Ecore_X_Window paren
         einfo->info.screen = NULL;
 # endif
         einfo->info.drawable = ee->prop.window;
+        einfo->func.region_push_hook = _ecore_evas_x11_region_push_hook;
 
         if (argb)
           {
@@ -4298,6 +4442,7 @@ ecore_evas_software_x11_pixmap_new_internal(const char 
*disp_name, Ecore_X_Windo
                }
           }
 
+        einfo->func.region_push_hook = _ecore_evas_x11_region_push_hook;
         einfo->info.destination_alpha = argb;
 
         if (redraw_debug < 0)
@@ -5131,6 +5276,211 @@ _ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
    ecore_x_window_shape_input_window_set(ee->prop.window, 
edata->win_shaped_input);
 }
 
+#ifdef ENABLE_VNC_SERVER
+static Eina_Bool
+_ecore_evas_x11_vnc_socket_listen_activity(void *data,
+                                           Ecore_Fd_Handler *fd_handler 
EINA_UNUSED)
+{
+   rfbProcessNewConnection(data);
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_ecore_evas_x11_client_gone(rfbClientRec *client)
+{
+   Ecore_Evas_X11_Vnc_Client_Data *cdata = client->clientData;
+
+   EDBG("VNC client on seat '%p' gone", cdata);
+
+   ecore_main_fd_handler_del(cdata->handler);
+   free(cdata);
+   _available_seat--;
+}
+
+static Eina_Bool
+_ecore_evas_x11_client_activity(void *data,
+                                Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+   Eina_Bool r = ECORE_CALLBACK_RENEW;
+   rfbClientRec *client = data;
+
+   rfbProcessClientMessage(client);
+
+   //macro from rfb.h
+   if (FB_UPDATE_PENDING(client))
+     rfbSendFramebufferUpdate(client, client->modifiedRegion);
+
+   //Client disconnected.
+   if (client->sock == -1)
+     {
+        rfbClientConnectionGone(client);
+        r = ECORE_CALLBACK_DONE;
+     }
+
+   return r;
+}
+
+static enum rfbNewClientAction
+_ecore_evas_x11_vnc_client_connection_new(rfbClientRec *client)
+{
+   Ecore_Evas *ee;
+   Ecore_Evas_Engine_Data_X11 *edata;
+   Ecore_Evas_X11_Vnc_Client_Data *cdata;
+
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(_available_seat == UINT_MAX,
+                                  RFB_CLIENT_REFUSE);
+
+   ee = client->screen->screenData;
+   edata = ee->engine.data;
+
+   if (!edata->accept_cb(edata->accept_cb_data, ee, client->host))
+     return RFB_CLIENT_REFUSE;
+
+   cdata = calloc(1, sizeof(Ecore_Evas_X11_Vnc_Client_Data));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cdata, RFB_CLIENT_REFUSE);
+
+   cdata->handler = ecore_main_fd_handler_add(client->sock, ECORE_FD_READ,
+                                              _ecore_evas_x11_client_activity,
+                                              client, NULL, NULL);
+   EINA_SAFETY_ON_NULL_GOTO(cdata->handler, err_handler);
+
+   client->clientGoneHook = _ecore_evas_x11_client_gone;
+   client->clientData = cdata;
+
+   EDBG("New VNC client on seat '%u'", _available_seat);
+
+   _available_seat++;
+   return RFB_CLIENT_ACCEPT;
+
+ err_handler:
+   free(cdata);
+   return RFB_CLIENT_REFUSE;
+}
+
+static void
+_ecore_evas_x11_vnc_client_keyboard_event(rfbBool down EINA_UNUSED,
+                                          rfbKeySym keySym EINA_UNUSED,
+                                          rfbClientRec *client EINA_UNUSED)
+{
+   EDBG("Keyboard event\n");
+}
+
+static void
+_ecore_evas_x11_vnc_client_pointer_event(int buttonMask EINA_UNUSED,
+                                         int x EINA_UNUSED, int y EINA_UNUSED,
+                                         rfbClientPtr client EINA_UNUSED)
+{
+   EDBG("Pointer event\n");
+}
+#endif
+
+static Eina_Bool
+_ecore_evas_x11_vnc_start(Ecore_Evas *ee, const char *addr, int port,
+                          Ecore_Evas_Vnc_Client_Accept_Cb cb, void *data)
+{
+#ifdef ENABLE_VNC_SERVER
+   Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
+   Eina_Bool can_listen = EINA_FALSE;
+
+   if (edata->vnc_screen)
+     return EINA_FALSE;
+
+   edata->vnc_screen = rfbGetScreen(0, NULL, ee->w, ee->h, VNC_BITS_PER_SAMPLE,
+                                    VNC_SAMPLES_PER_PIXEL, 
VNC_BYTES_PER_PIXEL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(edata->vnc_screen, EINA_FALSE);
+
+   edata->vnc_screen->newClientHook = 
_ecore_evas_x11_vnc_client_connection_new;
+   edata->vnc_screen->kbdAddEvent = _ecore_evas_x11_vnc_client_keyboard_event;
+   edata->vnc_screen->ptrAddEvent = _ecore_evas_x11_vnc_client_pointer_event;
+
+   //This enables multiple client connections at the same time.
+   edata->vnc_screen->alwaysShared = TRUE;
+   edata->vnc_screen->frameBuffer = edata->frame_buffer;
+
+   _ecore_evas_x11_vnc_server_format_setup(edata);
+
+   if (port > 0)
+     edata->vnc_screen->port = edata->vnc_screen->ipv6port= port;
+
+   if (addr)
+     {
+        int err;
+
+        //rfbStringToAddr() does not change the addr contents.
+        err = rfbStringToAddr((char *)addr, 
&edata->vnc_screen->listenInterface);
+        EINA_SAFETY_ON_TRUE_GOTO(err == 0, err_screen);
+     }
+
+   rfbInitServer(edata->vnc_screen);
+   if (edata->vnc_screen->listenSock >= 0)
+     {
+        edata->vnc_listen_handler = 
ecore_main_fd_handler_add(edata->vnc_screen->listenSock,
+                                                              ECORE_FD_READ,
+                                                              
_ecore_evas_x11_vnc_socket_listen_activity,
+                                                              
edata->vnc_screen, NULL,
+                                                              NULL);
+        EINA_SAFETY_ON_NULL_GOTO(edata->vnc_listen_handler, err_listen);
+        can_listen = EINA_TRUE;
+     }
+
+   if (edata->vnc_screen->listen6Sock >= 0)
+     {
+        edata->vnc_listen6_handler = 
ecore_main_fd_handler_add(edata->vnc_screen->listen6Sock,
+                                                               ECORE_FD_READ,
+                                                               
_ecore_evas_x11_vnc_socket_listen_activity,
+                                                               
edata->vnc_screen,
+                                                               NULL, NULL);
+        EINA_SAFETY_ON_NULL_GOTO(edata->vnc_listen6_handler, err_listen6);
+        can_listen = EINA_TRUE;
+     }
+
+   //rfbInitServer() failed and could not setup the sockets.
+   EINA_SAFETY_ON_FALSE_GOTO(can_listen, err_listen);
+
+   edata->vnc_screen->screenData = ee;
+   edata->accept_cb_data = data;
+   edata->accept_cb = cb;
+
+   return EINA_TRUE;
+
+ err_listen6:
+   ecore_main_fd_handler_del(edata->vnc_listen_handler);
+   edata->vnc_listen_handler = NULL;
+ err_listen:
+   rfbScreenCleanup(edata->vnc_screen);
+   edata->vnc_screen = NULL;
+ err_screen:
+   return EINA_FALSE;
+#else
+   (void)ee;
+   (void)addr;
+   (void)port;
+   (void)cb;
+   (void)data;
+   return EINA_FALSE;
+#endif
+}
+
+static Eina_Bool
+_ecore_evas_x11_vnc_stop(Ecore_Evas *ee)
+{
+#ifdef ENABLE_VNC_SERVER
+   Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
+
+   if (!edata->vnc_screen)
+     return EINA_FALSE;
+
+   ecore_main_fd_handler_del(edata->vnc_listen6_handler);
+   ecore_main_fd_handler_del(edata->vnc_listen_handler);
+   rfbScreenCleanup(edata->vnc_screen);
+   edata->vnc_screen = NULL;
+   return EINA_TRUE;
+#else
+   (void)ee;
+   return EINA_FALSE;
+#endif
+}
+
 static Ecore_Evas_Interface_X11 *
 _ecore_evas_x_interface_x11_new(void)
 {
@@ -5151,6 +5501,8 @@ _ecore_evas_x_interface_x11_new(void)
    iface->shape_input_empty = _ecore_evas_x11_shape_input_empty;
    iface->shape_input_reset = _ecore_evas_x11_shape_input_reset;
    iface->shape_input_apply = _ecore_evas_x11_shape_input_apply;
+   iface->vnc_start = _ecore_evas_x11_vnc_start;
+   iface->vnc_stop = _ecore_evas_x11_vnc_stop;
 
    return iface;
 }
@@ -5205,3 +5557,4 @@ _ecore_evas_x_interface_gl_x11_new(void)
    return iface;
 }
 #endif
+

-- 


Reply via email to