From 8687a23820f6287ba1e69024cb98cd526003eef7 Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Mon, 7 Nov 2016 14:44:38 -0800 Subject: [PATCH] Ecore Evas VNC: add client disconnected callback. Summary: Ecore Evas VNC: Properly unregister the region push hook callback. This callback must be unregistered when the VNC server is deleted. Reviewers: bdilly, barbieri, cedric Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4384 Signed-off-by: Cedric BAIL --- src/examples/ecore/ecore_evas_vnc_example.c | 8 +++- src/lib/ecore_evas/Ecore_Evas.h | 16 ++++++- src/lib/ecore_evas/ecore_evas.c | 10 ++-- .../vnc_server/ecore_evas_vnc_server.c | 46 +++++++++++++++++-- 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/examples/ecore/ecore_evas_vnc_example.c b/src/examples/ecore/ecore_evas_vnc_example.c index b451af3e64..228c173398 100644 --- a/src/examples/ecore/ecore_evas_vnc_example.c +++ b/src/examples/ecore/ecore_evas_vnc_example.c @@ -52,6 +52,12 @@ _accept_cb(void *data EINA_UNUSED, Ecore_Evas *ee EINA_UNUSED, const char *clien return EINA_TRUE; } +static void +_disc_cb(void *data EINA_UNUSED, Ecore_Evas *ee EINA_UNUSED, const char *client_host) +{ + printf("Client %s disconnected\n", client_host); +} + static Efl_Input_Device * _get_seat(Efl_Input_Device *dev) { @@ -247,7 +253,7 @@ main(int argc, char *argv[]) ecore_evas_show(ee); - r = ecore_evas_vnc_start(ee, "localhost", -1, _accept_cb, NULL); + r = ecore_evas_vnc_start(ee, "localhost", -1, _accept_cb, _disc_cb, NULL); if (!r) { diff --git a/src/lib/ecore_evas/Ecore_Evas.h b/src/lib/ecore_evas/Ecore_Evas.h index e669422144..3ffdab69d0 100644 --- a/src/lib/ecore_evas/Ecore_Evas.h +++ b/src/lib/ecore_evas/Ecore_Evas.h @@ -2408,20 +2408,32 @@ EAPI void ecore_evas_x11_shape_input_apply(Ecore_Evas *ee); */ typedef Eina_Bool (*Ecore_Evas_Vnc_Client_Accept_Cb)(void *data, Ecore_Evas *ee, const char *client_host); +/** + * @brief A callback used to inform that a client has disconnected. + * @param data The callback data + * @param ee The Ecore_Evas + * @param client_host The adrress of the client + * @see ecore_evas_vnc_start() + * @since 1.19 + */ +typedef void (*Ecore_Evas_Vnc_Client_Disconnected_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 accept_cb A callback used to accept a new client. If @c NULL all clients will be accepted. + * @param disc_cb A callback user 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. * @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); +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 Stop a running VNC server diff --git a/src/lib/ecore_evas/ecore_evas.c b/src/lib/ecore_evas/ecore_evas.c index 5a722a6a6f..51f89fb45a 100644 --- a/src/lib/ecore_evas/ecore_evas.c +++ b/src/lib/ecore_evas/ecore_evas.c @@ -3316,11 +3316,15 @@ ecore_evas_x11_shape_input_apply(Ecore_Evas *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_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, void *); + Ecore_Evas_Vnc_Client_Accept_Cb, + Ecore_Evas_Vnc_Client_Disconnected_Cb, + void *); EINA_SAFETY_ON_NULL_RETURN_VAL(ee, EINA_FALSE); @@ -3333,7 +3337,7 @@ ecore_evas_vnc_start(Ecore_Evas *ee, const char *addr, int port, vnc_new = eina_module_symbol_get(mod, "ecore_evas_vnc_server_new"); EINA_SAFETY_ON_NULL_RETURN_VAL(vnc_new, EINA_FALSE); - ee->vnc_server = vnc_new(ee, port, addr, cb, data); + 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; } diff --git a/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c index 140a31089a..def9593c9e 100644 --- a/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c +++ b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server.c @@ -77,7 +77,8 @@ typedef struct _Ecore_Evas_Vnc_Server { Ecore_Fd_Handler *vnc_listen_handler; Ecore_Fd_Handler *vnc_listen6_handler; Ecore_Evas_Vnc_Client_Accept_Cb accept_cb; - void *accept_cb_data; + Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb; + void *cb_data; Ecore_Evas *ee; Ecore_Evas_Vnc_Key_Info_Get key_info_get_func; double double_click_time; @@ -154,9 +155,12 @@ static void _ecore_evas_vnc_server_client_gone(rfbClientRec *client) { Ecore_Evas_Vnc_Server_Client_Data *cdata = client->clientData; + Ecore_Evas_Vnc_Server *server = client->screen->screenData; DBG("VNC client on seat '%s' gone", evas_device_name_get(cdata->seat)); + if (server->disc_cb) + server->disc_cb(server->cb_data, server->ee, client->host); ecore_main_fd_handler_del(cdata->handler); evas_device_del(cdata->keyboard); evas_device_del(cdata->mouse); @@ -200,7 +204,7 @@ _ecore_evas_vnc_server_client_connection_new(rfbClientRec *client) server = client->screen->screenData; - if (server->accept_cb && !server->accept_cb(server->accept_cb_data, + if (server->accept_cb && !server->accept_cb(server->cb_data, server->ee, client->host)) return RFB_CLIENT_REFUSE; @@ -593,6 +597,8 @@ _ecore_evas_vnc_server_draw(Evas *evas, int x, int y, ee = evas_data_attach_get(evas); server = ee->vnc_server; + if (!server) return; + if (!server->frame_buffer || server->last_w != ee->w || server->last_h != ee->h) { char *new_fb; @@ -672,7 +678,9 @@ _ecore_evas_vnc_server_draw(Evas *evas, int x, int y, EAPI Ecore_Evas_Vnc_Server * ecore_evas_vnc_server_new(Ecore_Evas *ee, int port, const char *addr, - Ecore_Evas_Vnc_Client_Accept_Cb cb, void *data) + Ecore_Evas_Vnc_Client_Accept_Cb accept_cb, + Ecore_Evas_Vnc_Client_Disconnected_Cb disc_cb, + void *data) { Ecore_Evas_Vnc_Server *server; Eina_Bool can_listen = EINA_FALSE; @@ -775,8 +783,9 @@ ecore_evas_vnc_server_new(Ecore_Evas *ee, int port, const char *addr, EINA_SAFETY_ON_FALSE_GOTO(err, err_engine); server->vnc_screen->screenData = server; - server->accept_cb_data = data; - server->accept_cb = cb; + server->cb_data = data; + server->accept_cb = accept_cb; + server->disc_cb = disc_cb; server->ee = ee; return server; @@ -795,8 +804,35 @@ ecore_evas_vnc_server_new(Ecore_Evas *ee, int port, const char *addr, 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; + } +#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; + } +#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); free(server->frame_buffer);