Merge branch 'devs/iscaro/vnc-fb'

This series adds support to Framebuffer on Ecore Evas VNC.

So both X11 and FB will be supported by Ecore Evas VNC and
may be used to map remote clients as multiple seats.

Patches by Guilherme Iscaro <iscaro@profusion.mobi>
Differential Revision: https://phab.enlightenment.org/D4373
This commit is contained in:
Bruno Dilly 2016-11-04 18:52:18 -02:00
commit f869cd580e
10 changed files with 635 additions and 36 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

@ -8,6 +8,9 @@
#include <Eina.h>
#include <Ecore_Evas.h>
#include <Ecore_Input.h>
#include <Ecore_Getopt.h>
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);

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

View File

@ -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

View File

@ -3,8 +3,13 @@
#include "evas_engine.h"
#include "Evas_Engine_FB.h"
#include <Ecore.h>
#include <Eina.h>
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);
}

View File

@ -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

View File

@ -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);
}
}
}