diff --git a/configure.ac b/configure.ac index c709f7f0f3..f4b7aa57dc 100644 --- a/configure.ac +++ b/configure.ac @@ -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}]) diff --git a/src/Makefile_Ecore_Evas.am b/src/Makefile_Ecore_Evas.am index ea854c402c..7907a67269 100644 --- a/src/Makefile_Ecore_Evas.am +++ b/src/Makefile_Ecore_Evas.am @@ -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 diff --git a/src/examples/ecore/ecore_evas_vnc_example.c b/src/examples/ecore/ecore_evas_vnc_example.c index 3d16733665..b451af3e64 100644 --- a/src/examples/ecore/ecore_evas_vnc_example.c +++ b/src/examples/ecore/ecore_evas_vnc_example.c @@ -8,6 +8,9 @@ #include #include #include +#include + +static int width = 800; static Eina_Bool _anim(void *data) @@ -30,10 +33,10 @@ _anim(void *data) else { x += speed; - if (x >= 800) + if (x >= width) { direction = LEFT; - x = 800; + x = width; } } @@ -164,7 +167,7 @@ _dev_added_or_removed(void *data EINA_UNUSED, const Efl_Event *event) } int -main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED) +main(int argc, char *argv[]) { Ecore_Evas *ee; Evas *evas; @@ -173,10 +176,52 @@ main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED) Eina_Bool r; Ecore_Event_Handler *keydown_handler, *keyup_handler, *mouse_move, *mouse_down, *mouse_up, *mouse_wheel; + char *engine = "software_x11"; + int args, height = 600; + Eina_Bool quit_option = EINA_FALSE; + static const Ecore_Getopt options = { + "ecore_evas_vnc_example", + NULL, + "0.1", + "(C) 2016 Enlightenment Project", + "BSD 2-Clause", + "Ecore_Evas VNC example.\n", + EINA_TRUE, + { + ECORE_GETOPT_STORE_DEF_STR('e', "engine", "The engine backend", "software_x11"), + ECORE_GETOPT_STORE_DEF_INT('w', "width", "The window width", 800), + ECORE_GETOPT_STORE_DEF_INT('h', "height", "The window height", 600), + ECORE_GETOPT_VERSION('v', "version"), + ECORE_GETOPT_COPYRIGHT('c', "copyright"), + ECORE_GETOPT_LICENSE('k', "license"), + ECORE_GETOPT_HELP('H', "help"), + ECORE_GETOPT_SENTINEL + } + }; + Ecore_Getopt_Value values[] = { + ECORE_GETOPT_VALUE_STR(engine), + ECORE_GETOPT_VALUE_INT(width), + ECORE_GETOPT_VALUE_INT(height), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_BOOL(quit_option), + ECORE_GETOPT_VALUE_NONE + }; ecore_evas_init(); - ee = ecore_evas_new(NULL, 0, 0, 800, 600, NULL); + args = ecore_getopt_parse(&options, values, argc, argv); + if (args < 0) + { + fprintf(stderr, "Could not parse command line options.\n"); + return -1; + } + + if (quit_option) return 0; + + printf("Using engine '%s'. Width: %d - Height: %d\n", engine, width, height); + ee = ecore_evas_new(engine, 0, 0, width, height, NULL); if (!ee) { @@ -189,13 +234,13 @@ main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED) bg = evas_object_rectangle_add(evas); evas_object_color_set(bg, 255, 255, 255, 255); evas_object_move(bg, 0, 0); - evas_object_resize(bg, 800, 600); + evas_object_resize(bg, width, height); evas_object_show(bg); rect = evas_object_rectangle_add(evas); evas_object_color_set(rect, 0, 255, 0, 255); evas_object_resize(rect, 50, 50); - evas_object_move(rect, (800 - 50) /2, (600 - 50)/2); + evas_object_move(rect, (width - 50) /2, (height - 50)/2); evas_object_show(rect); animator = ecore_animator_add(_anim, rect); 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 63df8d08b8..140a31089a 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 @@ -11,8 +11,16 @@ #include #include #include -#include -#include + +#ifdef BUILD_ENGINE_SOFTWARE_X11 +# include +# include +#endif + +#ifdef BUILD_ENGINE_FB +# include +# include "ecore_evas_vnc_server_fb_keymap.h" +#endif #include #include @@ -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); diff --git a/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c new file mode 100644 index 0000000000..33f9d2109d --- /dev/null +++ b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c @@ -0,0 +1,363 @@ +#include +#include +#include +#include +#include + +static const char *_ecore_fb_li_kbd_syms[128 * 7] = +{ +#include +}; + +#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; +} + diff --git a/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.h b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.h new file mode 100644 index 0000000000..ebcfee1d33 --- /dev/null +++ b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.h @@ -0,0 +1,12 @@ +#include +#include + +#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 diff --git a/src/modules/evas/engines/fb/Evas_Engine_FB.h b/src/modules/evas/engines/fb/Evas_Engine_FB.h index b548237857..12c50670f6 100644 --- a/src/modules/evas/engines/fb/Evas_Engine_FB.h +++ b/src/modules/evas/engines/fb/Evas_Engine_FB.h @@ -19,6 +19,10 @@ struct _Evas_Engine_Info_FB /* non-blocking or blocking mode */ Evas_Engine_Render_Mode render_mode; + + struct { + void (*region_push_hook)(Evas *e, int x, int y, int w, int h, const void *pixels); + } func; }; #endif diff --git a/src/modules/evas/engines/fb/evas_engine.c b/src/modules/evas/engines/fb/evas_engine.c index 9457485dd9..3156b95a78 100644 --- a/src/modules/evas/engines/fb/evas_engine.c +++ b/src/modules/evas/engines/fb/evas_engine.c @@ -3,8 +3,13 @@ #include "evas_engine.h" #include "Evas_Engine_FB.h" +#include +#include + int _evas_engine_fb_log_dom = -1; +static Eina_List *_outbufs = NULL; + /* function tables - filled in later (func and parent func) */ static Evas_Func func, pfunc; @@ -16,17 +21,76 @@ struct _Render_Engine Render_Engine_Software_Generic generic; }; +typedef struct _Region_Push_Hook_Ctx { + void *pixels; + Outbuf *buf; + int x; + int y; + int w; + int h; +} Region_Push_Hook_Ctx; + /* prototypes we will use here */ -static void *_output_setup(int w, int h, int rot, int vt, int dev, int refresh); +static void *_output_setup(Evas *eo_e, int w, int h, int rot, int vt, int dev, int refresh, + void (*region_push_hook)(Evas *e, int x, int y, int w, int h, + const void *pixels)); static void *eng_info(Evas *eo_e); static void eng_info_free(Evas *eo_e, void *info); static int eng_setup(Evas *eo_e, void *info); static void eng_output_free(void *data); +static void +_evas_fb_region_push_hook_call(void *data) +{ + Region_Push_Hook_Ctx *ctx = data; + + + if (eina_list_data_find(_outbufs, ctx->buf)) + { + ctx->buf->region_push_hook.cb(ctx->buf->region_push_hook.evas, + ctx->x, ctx->y, ctx->w, ctx->h, + ctx->pixels); + } + + free(ctx->pixels); + free(ctx); +} + +void +evas_fb_region_push_hook_call(Outbuf *buf, int x, int y, int w, int h, + const void *pixels) +{ + Region_Push_Hook_Ctx *ctx; + size_t s; + + if (!buf->region_push_hook.cb) + return; + + s = w * h * buf->priv.fb.fb->bpp; + ctx = malloc(sizeof(Region_Push_Hook_Ctx)); + EINA_SAFETY_ON_NULL_RETURN(ctx); + ctx->pixels = malloc(s); + EINA_SAFETY_ON_NULL_GOTO(ctx->pixels, err_pixels); + ctx->x = x; + ctx->y = y; + ctx->w = w; + ctx->h = h; + ctx->buf = buf; + memcpy(ctx->pixels, pixels, s); + + ecore_main_loop_thread_safe_call_async(_evas_fb_region_push_hook_call, ctx); + return; + + err_pixels: + free(ctx); +} + /* internal engine routines */ static void * -_output_setup(int w, int h, int rot, int vt, int dev, int refresh) +_output_setup(Evas *eo_e, int w, int h, int rot, int vt, int dev, int refresh, + void (*region_push_hook)(Evas *e, int x, int y, int w, int h, + const void *pixels)) { Render_Engine *re; Outbuf *ob; @@ -43,6 +107,8 @@ _output_setup(int w, int h, int rot, int vt, int dev, int refresh) ob = evas_fb_outbuf_fb_setup_fb(w, h, rot, OUTBUF_DEPTH_INHERIT, vt, dev, refresh); if (!ob) goto on_error; + ob->region_push_hook.cb = region_push_hook; + ob->region_push_hook.evas = eo_e; if (!evas_render_engine_software_generic_init(&re->generic, ob, NULL, evas_fb_outbuf_fb_get_rot, evas_fb_outbuf_fb_reconfigure, @@ -61,6 +127,7 @@ _output_setup(int w, int h, int rot, int vt, int dev, int refresh) /* no backbuf! */ evas_fb_outbuf_fb_set_have_backbuf(ob, 0); + _outbufs = eina_list_append(_outbufs, ob); return re; on_error: @@ -98,12 +165,12 @@ eng_setup(Evas *eo_e, void *in) Evas_Engine_Info_FB *info; info = (Evas_Engine_Info_FB *)in; - re = _output_setup(e->output.w, + re = _output_setup(eo_e, e->output.w, e->output.h, info->info.rotation, info->info.virtual_terminal, info->info.device_number, - info->info.refresh); + info->info.refresh, info->func.region_push_hook); e->engine.data.output = re; if (!e->engine.data.output) return 0; e->engine.data.context = e->engine.func->context_new(e->engine.data.output); @@ -119,6 +186,7 @@ eng_output_free(void *data) re = (Render_Engine *)data; if (re) { + _outbufs = eina_list_remove(_outbufs, re->generic.ob); evas_render_engine_software_generic_clean(&re->generic); free(re); } diff --git a/src/modules/evas/engines/fb/evas_engine.h b/src/modules/evas/engines/fb/evas_engine.h index 424d47cbbe..44e4991034 100644 --- a/src/modules/evas/engines/fb/evas_engine.h +++ b/src/modules/evas/engines/fb/evas_engine.h @@ -46,6 +46,11 @@ struct _Outbuf } mask; RGBA_Image *back_buf; } priv; + + struct { + void (*cb)(Evas *e, int x, int y, int w, int h, const void *pixels); + Evas *evas; + } region_push_hook; }; /****/ @@ -68,4 +73,6 @@ int evas_fb_outbuf_fb_get_rot (Outbuf *buf); int evas_fb_outbuf_fb_get_have_backbuf (Outbuf *buf); void evas_fb_outbuf_fb_set_have_backbuf (Outbuf *buf, int have_backbuf); +void evas_fb_region_push_hook_call(Outbuf *buf, int x, int y, int w, int h, const void *pixels); + #endif diff --git a/src/modules/evas/engines/fb/evas_outbuf.c b/src/modules/evas/engines/fb/evas_outbuf.c index 77274289db..46b0441fea 100644 --- a/src/modules/evas/engines/fb/evas_outbuf.c +++ b/src/modules/evas/engines/fb/evas_outbuf.c @@ -357,6 +357,7 @@ evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, in h, w, x, y, NULL); } + evas_fb_region_push_hook_call(buf, x, y, w, h, src_data); } } }