Ecore_Evas VNC: Add frame buffer support.

This commit is contained in:
Guilherme Iscaro 2016-09-26 15:43:49 -03:00 committed by Bruno Dilly
parent 0fa8dc48cd
commit 70b83ad455
5 changed files with 500 additions and 26 deletions

View File

@ -4476,17 +4476,22 @@ if test "x${have_ecore_evas_opengl_x11}" = "xyes" || test "x${have_ecore_evas_op
fi
build_ecore_evas_x11="no"
build_ecore_evas_vnc="no"
if test "x$have_ecore_evas_software_x11" = "xyes" || \
test "x$have_ecore_evas_opengl_x11" = "xyes"; then
AC_DEFINE([BUILD_ECORE_EVAS_X11], [1], [Support for X Window Engines in Ecore_Evas])
build_ecore_evas_x11="yes"
if test "$want_vnc_server" = "yes"; then
build_ecore_evas_vnc="yes"
fi
fi
AM_CONDITIONAL([BUILD_ECORE_EVAS_X11], [test "${build_ecore_evas_x11}" = "yes"])
build_ecore_evas_vnc="no"
if test "${want_vnc_server}" = "yes" && \
(test "${build_ecore_evas_x11}" = "yes" || \
test "${want_fb}" = "yes"); then
AC_DEFINE([BUILD_ECORE_EVAS_VNC_SERVER], [1], [Build Ecore_Evas VNC module])
build_ecore_evas_vnc="yes"
fi
AM_CONDITIONAL([BUILD_ECORE_EVAS_VNC_SERVER], [test "${build_ecore_evas_vnc}" = "yes"])
AC_DEFINE_IF([BUILD_ECORE_EVAS_VNC_SERVER], [test "${build_ecore_evas_vnc}" = "yes"], [1], [Build Ecore_Evas VNC module])
EFL_ADD_FEATURE([ECORE_EVAS], [vnc_server], [${build_ecore_evas_vnc}])

View File

@ -297,17 +297,25 @@ $(install_ecoreevasenginevncserverpkgLTLIBRARIES): install-libLTLIBRARIES
modules_ecore_evas_vnc_server_module_la_SOURCES = $(VNCSERVERSOURCES)
modules_ecore_evas_vnc_server_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
@ECORE_EVAS_CFLAGS@ \
@LIBVNCSERVER_CFLAGS@ \
@ECORE_X_CFLAGS@ \
-I$(top_srcdir)/src/modules/evas/engines/software_x11
@LIBVNCSERVER_CFLAGS@
modules_ecore_evas_vnc_server_module_la_LIBADD = \
@USE_ECORE_EVAS_LIBS@ \
@LIBVNCSERVER_LIBS@ \
@USE_ECORE_X_LIBS@
@LIBVNCSERVER_LIBS@
modules_ecore_evas_vnc_server_module_la_DEPENDENCIES = \
@USE_ECORE_EVAS_INTERNAL_LIBS@
modules_ecore_evas_vnc_server_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
modules_ecore_evas_vnc_server_module_la_LIBTOOLFLAGS = --tag=disable-static
if BUILD_ECORE_EVAS_FB
modules_ecore_evas_vnc_server_module_la_CPPFLAGS += @ECORE_FB_CFLAGS@ -I$(top_srcdir)/src/modules/evas/engines/fb
modules_ecore_evas_vnc_server_module_la_LIBADD += @USE_ECORE_FB_LIBS@
VNCSERVERSOURCES += \
modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c \
modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.h
endif
if BUILD_ECORE_EVAS_X11
modules_ecore_evas_vnc_server_module_la_LIBADD += @USE_ECORE_X_LIBS@
modules_ecore_evas_vnc_server_module_la_CPPFLAGS += @ECORE_X_CFLAGS@ -I$(top_srcdir)/src/modules/evas/engines/software_x11
endif
endif
### Binary

View File

@ -11,8 +11,16 @@
#include <Ecore_Input.h>
#include <Evas.h>
#include <Ecore_Evas.h>
#include <Evas_Engine_Software_X11.h>
#include <Ecore_X.h>
#ifdef BUILD_ENGINE_SOFTWARE_X11
# include <Evas_Engine_Software_X11.h>
# include <Ecore_X.h>
#endif
#ifdef BUILD_ENGINE_FB
# include <Evas_Engine_FB.h>
# include "ecore_evas_vnc_server_fb_keymap.h"
#endif
#include <time.h>
#include <stdio.h>
@ -57,6 +65,12 @@ static unsigned int _available_seat = 1;
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_ecore_evas_vnc_server_log_dom, __VA_ARGS__)
typedef Eina_Bool (*Ecore_Evas_Vnc_Key_Info_Get)(rfbKeySym key,
const char **key_name,
const char **key_str,
const char **compose,
int *keycode);
typedef struct _Ecore_Evas_Vnc_Server {
char *frame_buffer;
rfbScreenInfoPtr vnc_screen;
@ -65,6 +79,7 @@ typedef struct _Ecore_Evas_Vnc_Server {
Ecore_Evas_Vnc_Client_Accept_Cb accept_cb;
void *accept_cb_data;
Ecore_Evas *ee;
Ecore_Evas_Vnc_Key_Info_Get key_info_get_func;
double double_click_time;
int last_w;
int last_h;
@ -263,6 +278,42 @@ _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,
const char **key_str,
const char **compose,
int *keycode EINA_UNUSED)
{
return ecore_evas_vnc_server_keysym_to_fb_translate(key,
key_name, key_str,
compose);
}
#endif
static void
_ecore_evas_vnc_server_client_keyboard_event(rfbBool down,
rfbKeySym key,
@ -272,7 +323,9 @@ _ecore_evas_vnc_server_client_keyboard_event(rfbBool down,
Ecore_Evas_Vnc_Server_Client_Data *cdata = client->clientData;
rfbScreenInfoPtr screen = client->screen;
Ecore_Evas_Vnc_Server *server = screen->screenData;
const char *key_string;
const char *key_str, *compose, *key_name;
int keycode = 0;
Eina_Bool r;
char buf[10];
if (key >= XK_Shift_L && key <= XK_Hyper_R)
@ -288,12 +341,13 @@ _ecore_evas_vnc_server_client_keyboard_event(rfbBool down,
if (server->ee->ignore_events)
return;
key_string = ecore_x_keysym_string_get(key);
EINA_SAFETY_ON_NULL_RETURN(key_string);
r = server->key_info_get_func(key, &key_str, &key_name,
&compose, &keycode);
EINA_SAFETY_ON_FALSE_RETURN(r);
snprintf(buf, sizeof(buf), "%lc", key);
e = calloc(1, sizeof(Ecore_Event_Key) + strlen(buf) + 1);
e = calloc(1, sizeof(Ecore_Event_Key) + (compose ? 0 : strlen(buf) + 1));
EINA_SAFETY_ON_NULL_RETURN(e);
e->timestamp = (unsigned int)time(NULL);
@ -303,10 +357,14 @@ _ecore_evas_vnc_server_client_keyboard_event(rfbBool down,
server->ee->prop.window;
e->dev = cdata->keyboard;
efl_ref(cdata->keyboard);
e->keycode = ecore_x_keysym_keycode_get(key_string);
e->keyname = e->key = key_string;
e->keyname = key_name;
e->key = key_str;
e->keycode = keycode;
e->compose = (char *)(e + 1);
strcpy((char *)e->compose, buf);
if (compose)
e->compose = compose;
else
strcpy((char *)e->compose, buf);
e->string = e->compose;
ecore_event_add(down ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP,
@ -618,18 +676,48 @@ ecore_evas_vnc_server_new(Ecore_Evas *ee, int port, const char *addr,
{
Ecore_Evas_Vnc_Server *server;
Eina_Bool can_listen = EINA_FALSE;
Evas_Engine_Info_Software_X11 *einfo;
Eina_Bool err;
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);
EINA_SAFETY_ON_TRUE_RETURN_VAL(strcmp(ee->driver, "software_x11"), NULL);
engine = evas_engine_info_get(ee->evas);
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
EINA_SAFETY_ON_NULL_RETURN_VAL(einfo, NULL);
#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;
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;
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,
VNC_SAMPLES_PER_PIXEL, VNC_BYTES_PER_PIXEL);
@ -683,8 +771,7 @@ 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_addr);
einfo->func.region_push_hook = _ecore_evas_vnc_server_draw;
err = evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
err = evas_engine_info_set(ee->evas, (Evas_Engine_Info *)engine);
EINA_SAFETY_ON_FALSE_GOTO(err, err_engine);
server->vnc_screen->screenData = server;
@ -695,7 +782,6 @@ ecore_evas_vnc_server_new(Ecore_Evas *ee, int port, const char *addr,
return server;
err_engine:
einfo->func.region_push_hook = NULL;
ecore_main_fd_handler_del(server->vnc_listen6_handler);
err_listen:
ecore_main_fd_handler_del(server->vnc_listen_handler);

View File

@ -0,0 +1,363 @@
#include <linux/input-event-codes.h>
#include <rfb/keysym.h>
#include <stdlib.h>
#include <limits.h>
#include <Ecore_Input.h>
static const char *_ecore_fb_li_kbd_syms[128 * 7] =
{
#include <ecore_fb_keytable.h>
};
#include "ecore_evas_vnc_server_fb_keymap.h"
static unsigned int
_x11_to_fb(rfbKeySym key, unsigned int *offset)
{
switch (key)
{
case XK_Num_Lock:
return KEY_NUMLOCK;
case XK_KP_Delete:
return KEY_DELETE;
case XK_KP_Equal:
return KEY_KPEQUAL;
case XK_KP_Multiply:
return KEY_KPASTERISK;
case XK_KP_Add:
return KEY_KPPLUS;
case XK_KP_Subtract:
return KEY_KPMINUS;
case XK_KP_Decimal:
return KEY_KPDOT;
case XK_KP_Divide:
return KEY_KPSLASH;
case XK_plus:
*offset = 1;
case XK_equal:
return KEY_EQUAL;
case XK_underscore:
*offset = 1;
case XK_minus:
return KEY_MINUS;
case XK_quotedbl:
*offset = 1;
case XK_apostrophe:
return KEY_APOSTROPHE;
case XK_Shift_L:
return KEY_LEFTSHIFT;
case XK_Shift_R:
return KEY_RIGHTSHIFT;
case XK_Control_L:
return KEY_LEFTCTRL;
case XK_Control_R:
return KEY_RIGHTCTRL;
case XK_Caps_Lock:
return KEY_CAPSLOCK;
case XK_Meta_L:
return KEY_LEFTMETA;
case XK_Meta_R:
return KEY_RIGHTMETA;
case XK_Alt_L:
return KEY_LEFTALT;
case XK_Alt_R:
return KEY_RIGHTALT;
case XK_space:
return KEY_SPACE;
case XK_period:
*offset = 1;
case XK_greater:
return KEY_DOT;
case XK_bar:
*offset = 1;
case XK_backslash:
return KEY_BACKSLASH;
case XK_question:
*offset = 1;
case XK_slash:
return KEY_SLASH;
case XK_braceleft:
case XK_bracketleft:
return KEY_LEFTBRACE;
case XK_braceright:
case XK_bracketright:
return KEY_RIGHTBRACE;
case XK_colon:
*offset = 1;
case XK_semicolon:
return KEY_SEMICOLON;
case XK_asciitilde:
*offset = 1;
case XK_grave:
return KEY_GRAVE;
case XK_less:
*offset = 1;
case XK_comma:
return KEY_COMMA;
case XK_F1:
return KEY_F1;
case XK_F2:
return KEY_F2;
case XK_F3:
return KEY_F3;
case XK_F4:
return KEY_F4;
case XK_F5:
return KEY_F5;
case XK_F6:
return KEY_F6;
case XK_F7:
return KEY_F7;
case XK_F8:
return KEY_F8;
case XK_F9:
return KEY_F9;
case XK_F10:
return KEY_F10;
case XK_F11:
return KEY_F11;
case XK_F12:
return KEY_F12;
case XK_BackSpace:
return KEY_BACKSPACE;
case XK_Tab:
return KEY_TAB;
case XK_Return:
return KEY_ENTER;
case XK_Pause:
return KEY_PAUSE;
case XK_Escape:
return KEY_ESC;
case XK_Delete:
return KEY_DELETE;
case XK_Linefeed:
return KEY_LINEFEED;
case XK_Scroll_Lock:
return KEY_SCROLLLOCK;
case XK_Sys_Req:
return KEY_SYSRQ;
case XK_Home:
return KEY_HOME;
case XK_Left:
return KEY_LEFT;
case XK_Up:
return KEY_UP;
case XK_Right:
return KEY_RIGHT;
case XK_Down:
return KEY_DOWN;
case XK_Page_Up:
return KEY_PAGEUP;
case XK_Page_Down:
return KEY_PAGEDOWN;
case XK_End:
return KEY_END;
case XK_KP_0:
*offset = 1;
case XK_KP_Insert:
return KEY_KP0;
case XK_KP_1:
*offset = 1;
case XK_KP_End:
return KEY_KP1;
case XK_KP_2:
*offset = 1;
case XK_KP_Down:
return KEY_KP2;
case XK_KP_3:
*offset = 1;
case XK_KP_Next:
return KEY_KP3;
case XK_KP_4:
*offset = 1;
case XK_KP_Left:
return KEY_KP4;
case XK_KP_5:
*offset = 1;
case XK_KP_Begin:
return KEY_KP5;
case XK_KP_6:
*offset = 1;
case XK_KP_Right:
return KEY_KP6;
case XK_KP_7:
*offset = 1;
case XK_KP_Home:
return KEY_KP7;
case XK_KP_8:
*offset = 1;
case XK_KP_Up:
return KEY_KP8;
case XK_KP_9:
*offset = 1;
case XK_KP_Prior:
return KEY_KP9;
case XK_KP_Enter:
return KEY_KPENTER;
case XK_parenright:
*offset = 1;
case XK_0:
return KEY_0;
case XK_exclam:
*offset = 1;
case XK_1:
return KEY_1;
case XK_at:
*offset = 1;
case XK_2:
return KEY_2;
case XK_numbersign:
*offset = 1;
case XK_3:
return KEY_3;
case XK_dollar:
*offset = 1;
case XK_4:
return KEY_4;
case XK_percent:
*offset = 1;
case XK_5:
return KEY_5;
case XK_asciicircum:
*offset = 1;
case XK_6:
return KEY_6;
case XK_ampersand:
*offset = 1;
case XK_7:
return KEY_7;
case XK_asterisk:
*offset = 1;
case XK_8:
return KEY_8;
case XK_parenleft:
*offset = 1;
case XK_9:
return KEY_9;
case XK_A:
*offset = 1;
case XK_a:
return KEY_A;
case XK_B:
*offset = 1;
case XK_b:
return KEY_B;
case XK_C:
*offset = 1;
case XK_c:
return KEY_C;
case XK_D:
*offset = 1;
case XK_d:
return KEY_D;
case XK_E:
*offset = 1;
case XK_e:
return KEY_E;
case XK_F:
*offset = 1;
case XK_f:
return KEY_F;
case XK_G:
*offset = 1;
case XK_g:
return KEY_G;
case XK_H:
*offset = 1;
case XK_h:
return KEY_H;
case XK_I:
*offset = 1;
case XK_i:
return KEY_I;
case XK_J:
*offset = 1;
case XK_j:
return KEY_J;
case XK_K:
*offset = 1;
case XK_k:
return KEY_K;
case XK_L:
*offset = 1;
case XK_l:
return KEY_L;
case XK_M:
*offset = 1;
case XK_m:
return KEY_M;
case XK_N:
*offset = 1;
case XK_n:
return KEY_N;
case XK_O:
*offset = 1;
case XK_o:
return KEY_O;
case XK_P:
*offset = 1;
case XK_p:
return KEY_P;
case XK_Q:
*offset = 1;
case XK_q:
return KEY_Q;
case XK_R:
*offset = 1;
case XK_r:
return KEY_R;
case XK_S:
*offset = 1;
case XK_s:
return KEY_S;
case XK_T:
*offset = 1;
case XK_t:
return KEY_T;
case XK_U:
*offset = 1;
case XK_u:
return KEY_U;
case XK_V:
*offset = 1;
case XK_v:
return KEY_V;
case XK_W:
*offset = 1;
case XK_w:
return KEY_W;
case XK_X:
*offset = 1;
case XK_x:
return KEY_X;
case XK_Y:
*offset = 1;
case XK_y:
return KEY_Y;
case XK_Z:
*offset = 1;
case XK_z:
return KEY_Z;
default:
return UINT_MAX;
}
}
Eina_Bool
ecore_evas_vnc_server_keysym_to_fb_translate(rfbKeySym key,
const char **key_name,
const char **key_str,
const char **compose)
{
unsigned int offset = 0;
unsigned int id = _x11_to_fb(key, &offset);
if (id == UINT_MAX)
return EINA_FALSE;
*key_name = _ecore_fb_li_kbd_syms[id * 7];
*key_str = _ecore_fb_li_kbd_syms[(id * 7) + offset];
*compose = _ecore_fb_li_kbd_syms[(id* 7) + 3 + offset];
return EINA_TRUE;
}

View File

@ -0,0 +1,12 @@
#include <rfb/rfb.h>
#include <Eina.h>
#ifndef ECORE_EVAS_VNC_SERVER_FB_KEY_MAP_H
#define ECORE_EVAS_VNC_SERVER_FB_KEY_MAP_H
Eina_Bool ecore_evas_vnc_server_keysym_to_fb_translate(rfbKeySym key,
const char **key_name,
const char **key_str,
const char **compose);
#endif