forked from enlightenment/efl
Merge branch 'devs/iscaro/ecore_evas_vnc_multiseat'
This series adds the Ecore_Evas multi-seat VNC support using the software X11 backend. This implementation tries to mimic the Wayland's multi-seat support. This series also introduces two new kinds of EFL events, which are: * EFL_CANVAS_EVENT_DEVICE_ADDED - Which is emitted every time an Evas_Device is created. * EFL_CANVAS_EVENT_DEVICE_REMOVED - Which is emmited every time an Evas_Device is removed/deleted. The new events are useful when one wants to monitor how many and what kind of devices are connected to the system. Patches by iscaro. Differential Revision: https://phab.enlightenment.org/D4295 @feature
This commit is contained in:
commit
0566abeee8
24
configure.ac
24
configure.ac
|
@ -433,6 +433,24 @@ AC_DEFINE_IF([ENABLE_LIBLZ4], [test "${want_liblz4}" = "yes"], [1], [Use liblz4
|
||||||
AC_SUBST([want_liblz4])
|
AC_SUBST([want_liblz4])
|
||||||
AC_SUBST([ENABLE_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
|
#### Checks for header files
|
||||||
|
|
||||||
# Common Checks (keep names sorted for ease of use):
|
# Common Checks (keep names sorted for ease of use):
|
||||||
|
@ -4622,7 +4640,8 @@ AM_CONDITIONAL([BUILD_ECORE_EVAS_WIN32],
|
||||||
|
|
||||||
# XXX TODO: ecore_evas_x11
|
# 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_xlib="no"
|
||||||
have_ecore_evas_software_xcb="no"
|
have_ecore_evas_software_xcb="no"
|
||||||
|
@ -4645,7 +4664,8 @@ fi
|
||||||
|
|
||||||
# XXX TODO: ecore_evas_opengl_x11
|
# 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_xlib="no"
|
||||||
have_ecore_evas_opengl_xcb="no"
|
have_ecore_evas_opengl_xcb="no"
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
/ecore_evas_extn_socket_example
|
/ecore_evas_extn_socket_example
|
||||||
/ecore_evas_object_example
|
/ecore_evas_object_example
|
||||||
/ecore_evas_window_sizes_example
|
/ecore_evas_window_sizes_example
|
||||||
|
/ecore_evas_vnc
|
||||||
/ecore_event_example_01
|
/ecore_event_example_01
|
||||||
/ecore_event_example_02
|
/ecore_event_example_02
|
||||||
/ecore_exe_example
|
/ecore_exe_example
|
||||||
|
|
|
@ -60,6 +60,7 @@ ecore_evas_callbacks \
|
||||||
ecore_evas_ews_example \
|
ecore_evas_ews_example \
|
||||||
ecore_evas_object_example \
|
ecore_evas_object_example \
|
||||||
ecore_evas_window_sizes_example \
|
ecore_evas_window_sizes_example \
|
||||||
|
ecore_evas_vnc \
|
||||||
ecore_event_example_01 \
|
ecore_event_example_01 \
|
||||||
ecore_event_example_02 \
|
ecore_event_example_02 \
|
||||||
ecore_exe_example \
|
ecore_exe_example \
|
||||||
|
@ -203,6 +204,9 @@ ecore_evas_object_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
||||||
ecore_evas_window_sizes_example_SOURCES = ecore_evas_window_sizes_example.c
|
ecore_evas_window_sizes_example_SOURCES = ecore_evas_window_sizes_example.c
|
||||||
ecore_evas_window_sizes_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
ecore_evas_window_sizes_example_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
||||||
|
|
||||||
|
ecore_evas_vnc_SOURCES = ecore_evas_vnc.c
|
||||||
|
ecore_evas_vnc_LDADD = $(ECORE_EVAS_COMMON_LDADD)
|
||||||
|
|
||||||
ecore_event_example_01_SOURCES = ecore_event_example_01.c
|
ecore_event_example_01_SOURCES = ecore_event_example_01.c
|
||||||
ecore_event_example_01_LDADD = $(ECORE_COMMON_LDADD)
|
ecore_event_example_01_LDADD = $(ECORE_COMMON_LDADD)
|
||||||
|
|
||||||
|
@ -330,6 +334,7 @@ ecore_evas_callbacks.c \
|
||||||
ecore_evas_ews_example.c \
|
ecore_evas_ews_example.c \
|
||||||
ecore_evas_object_example.c \
|
ecore_evas_object_example.c \
|
||||||
ecore_evas_window_sizes_example.c \
|
ecore_evas_window_sizes_example.c \
|
||||||
|
ecore_evas_vnc.c \
|
||||||
ecore_event_example_01.c \
|
ecore_event_example_01.c \
|
||||||
ecore_event_example_02.c \
|
ecore_event_example_02.c \
|
||||||
ecore_exe_example.c \
|
ecore_exe_example.c \
|
||||||
|
|
|
@ -0,0 +1,244 @@
|
||||||
|
#define EFL_EO_API_SUPPORT
|
||||||
|
#define EFL_BETA_API_SUPPORT
|
||||||
|
|
||||||
|
#include <Efl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <Ecore.h>
|
||||||
|
#include <Evas.h>
|
||||||
|
#include <Eina.h>
|
||||||
|
#include <Ecore_Evas.h>
|
||||||
|
#include <Ecore_Input.h>
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_anim(void *data)
|
||||||
|
{
|
||||||
|
static enum { RIGHT, LEFT } direction = LEFT;
|
||||||
|
static const int speed = 20;
|
||||||
|
int x, y;
|
||||||
|
Evas_Object *rect = data;
|
||||||
|
|
||||||
|
evas_object_geometry_get(rect, &x, &y, NULL, NULL);
|
||||||
|
if (direction == LEFT)
|
||||||
|
{
|
||||||
|
x -= speed;
|
||||||
|
if (x <= 0)
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
direction = RIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x += speed;
|
||||||
|
if (x >= 800)
|
||||||
|
{
|
||||||
|
direction = LEFT;
|
||||||
|
x = 800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evas_object_move(rect, x, y);
|
||||||
|
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_accept_cb(void *data EINA_UNUSED, Ecore_Evas *ee EINA_UNUSED, const char *client_host)
|
||||||
|
{
|
||||||
|
printf("Client %s trying to connect\n", client_host);
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Efl_Input_Device *
|
||||||
|
_get_seat(Efl_Input_Device *dev)
|
||||||
|
{
|
||||||
|
if (!dev)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while ((dev = efl_input_device_parent_get(dev)))
|
||||||
|
{
|
||||||
|
if (efl_input_device_type_get(dev) == EFL_INPUT_DEVICE_CLASS_SEAT)
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_keyboard_event(void *data EINA_UNUSED, int type, void *event)
|
||||||
|
{
|
||||||
|
Ecore_Event_Key *e = event;
|
||||||
|
Efl_Input_Device *seat = NULL;
|
||||||
|
|
||||||
|
if (e->dev)
|
||||||
|
seat = _get_seat(e->dev);
|
||||||
|
|
||||||
|
printf("The keyboard on seat '%s' %s the key '%s'\n", seat ?
|
||||||
|
efl_input_device_name_get(seat) : "default",
|
||||||
|
type == ECORE_EVENT_KEY_DOWN ? "pressed" : "released",
|
||||||
|
e->keyname);
|
||||||
|
|
||||||
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_mouse_move(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||||
|
{
|
||||||
|
Ecore_Event_Mouse_Move *e = event;
|
||||||
|
Efl_Input_Device *seat = NULL;
|
||||||
|
|
||||||
|
if (e->dev)
|
||||||
|
seat = _get_seat(e->dev);
|
||||||
|
|
||||||
|
printf("The mouse on seat '%s' is at X: %d Y:%d\n",
|
||||||
|
seat ? efl_input_device_name_get(seat) : "default", e->x, e->y);
|
||||||
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_mouse_button(void *data EINA_UNUSED, int type, void *event)
|
||||||
|
{
|
||||||
|
Ecore_Event_Mouse_Button *e = event;
|
||||||
|
Efl_Input_Device *seat = NULL;
|
||||||
|
|
||||||
|
if (e->dev)
|
||||||
|
seat = _get_seat(e->dev);
|
||||||
|
|
||||||
|
printf("The mouse on seat '%s' %s the following button '%d'\n",
|
||||||
|
seat ? efl_input_device_name_get(seat) : "default",
|
||||||
|
type == ECORE_EVENT_MOUSE_BUTTON_DOWN ? "pressed" : "released",
|
||||||
|
e->buttons);
|
||||||
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_mouse_wheel(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
|
||||||
|
{
|
||||||
|
Ecore_Event_Mouse_Wheel *e = event;
|
||||||
|
Efl_Input_Device *seat = NULL;
|
||||||
|
|
||||||
|
if (e->dev)
|
||||||
|
seat = _get_seat(e->dev);
|
||||||
|
|
||||||
|
printf("The mouse on seat '%s' moved the wheel '%s'\n",
|
||||||
|
seat ? efl_input_device_name_get(seat) : "default",
|
||||||
|
e->z < 0 ? "up" : "down");
|
||||||
|
return ECORE_CALLBACK_PASS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_device_type_to_string(Efl_Input_Device_Class klass)
|
||||||
|
{
|
||||||
|
switch (klass)
|
||||||
|
{
|
||||||
|
case EFL_INPUT_DEVICE_CLASS_NONE:
|
||||||
|
return "None";
|
||||||
|
case EFL_INPUT_DEVICE_CLASS_SEAT:
|
||||||
|
return "Seat";
|
||||||
|
case EFL_INPUT_DEVICE_CLASS_KEYBOARD:
|
||||||
|
return "Keyboard";
|
||||||
|
case EFL_INPUT_DEVICE_CLASS_MOUSE:
|
||||||
|
return "Mouse";
|
||||||
|
case EFL_INPUT_DEVICE_CLASS_TOUCH:
|
||||||
|
return "Touch";
|
||||||
|
case EFL_INPUT_DEVICE_CLASS_PEN:
|
||||||
|
return "Pen";
|
||||||
|
case EFL_INPUT_DEVICE_CLASS_WAND:
|
||||||
|
return "Wand";
|
||||||
|
case EFL_INPUT_DEVICE_CLASS_GAMEPAD:
|
||||||
|
return "Gamepad";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_dev_added_or_removed(void *data EINA_UNUSED, const Efl_Event *event)
|
||||||
|
{
|
||||||
|
Efl_Input_Device *dev = event->info;
|
||||||
|
|
||||||
|
printf("The device '%s' - class: '%s' - description: '%s' was '%s'\n",
|
||||||
|
efl_input_device_name_get(dev),
|
||||||
|
_device_type_to_string(efl_input_device_type_get(dev)),
|
||||||
|
efl_input_device_description_get(dev),
|
||||||
|
event->desc == EFL_CANVAS_EVENT_DEVICE_ADDED ? "added" : "removed");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Ecore_Evas *ee;
|
||||||
|
Evas *evas;
|
||||||
|
Evas_Object *bg, *rect;
|
||||||
|
Ecore_Animator *animator;
|
||||||
|
Eina_Bool r;
|
||||||
|
Ecore_Event_Handler *keydown_handler, *keyup_handler, *mouse_move,
|
||||||
|
*mouse_down, *mouse_up, *mouse_wheel;
|
||||||
|
|
||||||
|
ecore_evas_init();
|
||||||
|
|
||||||
|
ee = ecore_evas_new(NULL, 0, 0, 800, 600, NULL);
|
||||||
|
|
||||||
|
if (!ee)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not create the ecore evas\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
evas = ecore_evas_get(ee);
|
||||||
|
|
||||||
|
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_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_show(rect);
|
||||||
|
|
||||||
|
animator = ecore_animator_add(_anim, rect);
|
||||||
|
|
||||||
|
ecore_evas_show(ee);
|
||||||
|
|
||||||
|
r = ecore_evas_vnc_start(ee, "localhost", -1, _accept_cb, NULL);
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not enable the VNC support!\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
keydown_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
|
||||||
|
_keyboard_event, NULL);
|
||||||
|
keyup_handler = ecore_event_handler_add(ECORE_EVENT_KEY_UP,
|
||||||
|
_keyboard_event, NULL);
|
||||||
|
mouse_move = ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _mouse_move,
|
||||||
|
NULL);
|
||||||
|
mouse_up = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
|
||||||
|
_mouse_button, NULL);
|
||||||
|
mouse_down = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN,
|
||||||
|
_mouse_button, NULL);
|
||||||
|
mouse_wheel = ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL,
|
||||||
|
_mouse_wheel, NULL);
|
||||||
|
|
||||||
|
efl_event_callback_add(evas, EFL_CANVAS_EVENT_DEVICE_ADDED,
|
||||||
|
_dev_added_or_removed, NULL);
|
||||||
|
efl_event_callback_add(evas, EFL_CANVAS_EVENT_DEVICE_REMOVED,
|
||||||
|
_dev_added_or_removed, NULL);
|
||||||
|
ecore_main_loop_begin();
|
||||||
|
|
||||||
|
ecore_event_handler_del(mouse_wheel);
|
||||||
|
ecore_event_handler_del(keydown_handler);
|
||||||
|
ecore_event_handler_del(keyup_handler);
|
||||||
|
ecore_event_handler_del(mouse_move);
|
||||||
|
ecore_event_handler_del(mouse_up);
|
||||||
|
ecore_event_handler_del(mouse_down);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ecore_evas_free(ee);
|
||||||
|
ecore_animator_del(animator);
|
||||||
|
ecore_evas_shutdown();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -2397,6 +2397,42 @@ EAPI void ecore_evas_x11_shape_input_empty(Ecore_Evas *ee);
|
||||||
EAPI void ecore_evas_x11_shape_input_reset(Ecore_Evas *ee);
|
EAPI void ecore_evas_x11_shape_input_reset(Ecore_Evas *ee);
|
||||||
EAPI void ecore_evas_x11_shape_input_apply(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.
|
* @defgroup Ecore_Evas_Ews Ecore_Evas Single Process Windowing System.
|
||||||
* @ingroup Ecore_Evas_Group
|
* @ingroup Ecore_Evas_Group
|
||||||
|
|
|
@ -3955,6 +3955,37 @@ ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
|
||||||
iface->shape_input_apply(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 *
|
EAPI Ecore_Evas *
|
||||||
ecore_evas_extn_socket_new(int w, int h)
|
ecore_evas_extn_socket_new(int w, int h)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,10 @@ struct _Ecore_Evas_Interface_X11 {
|
||||||
void (*shape_input_empty)(Ecore_Evas *ee);
|
void (*shape_input_empty)(Ecore_Evas *ee);
|
||||||
void (*shape_input_reset)(Ecore_Evas *ee);
|
void (*shape_input_reset)(Ecore_Evas *ee);
|
||||||
void (*shape_input_apply)(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 {
|
struct _Ecore_Evas_Interface_Software_X11 {
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
#include <Eina.h>
|
#include <Eina.h>
|
||||||
|
|
||||||
|
#include <Eo.h>
|
||||||
|
|
||||||
#ifdef EAPI
|
#ifdef EAPI
|
||||||
# undef EAPI
|
# undef EAPI
|
||||||
#endif
|
#endif
|
||||||
|
@ -209,6 +211,8 @@ extern "C" {
|
||||||
unsigned int keycode; /**< Key scan code numeric value @since 1.10 */
|
unsigned int keycode; /**< Key scan code numeric value @since 1.10 */
|
||||||
|
|
||||||
void *data; /**< User data associated with an Ecore_Event_Key @since 1.10 */
|
void *data; /**< User data associated with an Ecore_Event_Key @since 1.10 */
|
||||||
|
|
||||||
|
Eo *dev; /**< The Efl_Input_Device that originated the event @since 1.19 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,6 +249,8 @@ extern "C" {
|
||||||
double x, y;
|
double x, y;
|
||||||
} root; /**< same as root.x, root.y, but with sub-pixel precision, if available */
|
} root; /**< same as root.x, root.y, but with sub-pixel precision, if available */
|
||||||
} multi;
|
} multi;
|
||||||
|
|
||||||
|
Eo *dev; /**< The Efl_Input_Device that originated the event @since 1.19 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -270,6 +276,8 @@ extern "C" {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
} root; /**< Coordinates relative to root window */
|
} root; /**< Coordinates relative to root window */
|
||||||
|
|
||||||
|
Eo *dev; /**< The Efl_Input_Device that originated the event @since 1.19 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -304,6 +312,8 @@ extern "C" {
|
||||||
double x, y;
|
double x, y;
|
||||||
} root;
|
} root;
|
||||||
} multi;
|
} multi;
|
||||||
|
|
||||||
|
Eo *dev; /**< The Efl_Input_Device that originated the event @since 1.19 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum _Ecore_Axis_Label
|
typedef enum _Ecore_Axis_Label
|
||||||
|
@ -344,6 +354,8 @@ extern "C" {
|
||||||
|
|
||||||
int naxis;
|
int naxis;
|
||||||
Ecore_Axis *axis;
|
Ecore_Axis *axis;
|
||||||
|
|
||||||
|
Eo *dev; /**< The Efl_Input_Device that originated the event @since 1.19 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -360,6 +372,8 @@ extern "C" {
|
||||||
|
|
||||||
int x; /**< x coordinate relative to window where event happened */
|
int x; /**< x coordinate relative to window where event happened */
|
||||||
int y; /**< y coordinate relative to window where event happened */
|
int y; /**< y coordinate relative to window where event happened */
|
||||||
|
|
||||||
|
Eo *dev; /**< The Efl_Input_Device that originated the event @since 1.19 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -396,6 +410,8 @@ extern "C" {
|
||||||
double value; /* [0.0 .. 1.0] 0.0 == fully unpressed, 1.0 == fully pressed */
|
double value; /* [0.0 .. 1.0] 0.0 == fully unpressed, 1.0 == fully pressed */
|
||||||
} button;
|
} button;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Eo *dev; /**< The Efl_Input_Device that originated the event @since 1.19 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -155,5 +155,7 @@ interface Efl.Canvas ()
|
||||||
render,pre;
|
render,pre;
|
||||||
render,post;
|
render,post;
|
||||||
device,changed: Efl.Input.Device;
|
device,changed: Efl.Input.Device;
|
||||||
|
device,added: Efl.Input.Device;
|
||||||
|
device,removed: Efl.Input.Device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,4 +103,23 @@ _efl_input_device_parent_get(Eo *obj EINA_UNUSED, Efl_Input_Device_Data *pd)
|
||||||
return pd->parent;
|
return pd->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_input_device_parent_set(Eo *obj, Efl_Input_Device_Data *pd, Efl_Input_Device *parent)
|
||||||
|
{
|
||||||
|
if (pd->parent == parent) return;
|
||||||
|
if (pd->parent)
|
||||||
|
{
|
||||||
|
Efl_Input_Device_Data *p = efl_data_scope_get(pd->parent, EFL_INPUT_DEVICE_CLASS);
|
||||||
|
p->children = eina_list_remove(p->children, obj);
|
||||||
|
efl_unref(obj);
|
||||||
|
}
|
||||||
|
pd->parent = parent;
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
Efl_Input_Device_Data *p = efl_data_scope_get(parent, EFL_INPUT_DEVICE_CLASS);
|
||||||
|
p->children = eina_list_append(p->children, obj);
|
||||||
|
efl_ref(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#include "interfaces/efl_input_device.eo.c"
|
#include "interfaces/efl_input_device.eo.c"
|
||||||
|
|
|
@ -39,7 +39,7 @@ enum Efl.Input.Device.Sub_Class
|
||||||
|
|
||||||
|
|
||||||
/* This represents Evas_Device */
|
/* This represents Evas_Device */
|
||||||
/* FIXME: no parent, no children and no Evas */
|
/* FIXME: no children and no Evas */
|
||||||
|
|
||||||
class Efl.Input.Device (Efl.Object)
|
class Efl.Input.Device (Efl.Object)
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,7 @@ class Efl.Input.Device (Efl.Object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@property parent {
|
@property parent {
|
||||||
/* set {} */
|
set {}
|
||||||
get {}
|
get {}
|
||||||
values {
|
values {
|
||||||
parent: Efl.Input.Device;
|
parent: Efl.Input.Device;
|
||||||
|
|
|
@ -338,17 +338,17 @@ typedef Efl_Input_Device_Class Evas_Device_Class;
|
||||||
|
|
||||||
typedef Efl_Input_Device_Sub_Class Evas_Device_Subclass;
|
typedef Efl_Input_Device_Sub_Class Evas_Device_Subclass;
|
||||||
|
|
||||||
#define EVAS_DEVICE_SUBCLASS_NONE EFL_INPUT_DEVICE_SUBCLASS_NONE /**< Not a device @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_NONE EFL_INPUT_DEVICE_SUB_CLASS_NONE /**< Not a device @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_FINGER EFL_INPUT_DEVICE_SUBCLASS_FINGER /**< The normal flat of your finger @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_FINGER EFL_INPUT_DEVICE_SUB_CLASS_FINGER /**< The normal flat of your finger @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_FINGERNAIL EFL_INPUT_DEVICE_SUBCLASS_FINGERNAIL /**< A fingernail @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_FINGERNAIL EFL_INPUT_DEVICE_SUB_CLASS_FINGERNAIL /**< A fingernail @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_KNUCKLE EFL_INPUT_DEVICE_SUBCLASS_KNUCKLE /**< A Knuckle @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_KNUCKLE EFL_INPUT_DEVICE_SUB_CLASS_KNUCKLE /**< A Knuckle @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_PALM EFL_INPUT_DEVICE_SUBCLASS_PALM /**< The palm of a users hand @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_PALM EFL_INPUT_DEVICE_SUB_CLASS_PALM /**< The palm of a users hand @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_HAND_SIZE EFL_INPUT_DEVICE_SUBCLASS_HAND_SIZE /**< The side of your hand @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_HAND_SIZE EFL_INPUT_DEVICE_SUB_CLASS_HAND_SIZE /**< The side of your hand @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_HAND_FLAT EFL_INPUT_DEVICE_SUBCLASS_HAND_FLAT /**< The flat of your hand @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_HAND_FLAT EFL_INPUT_DEVICE_SUB_CLASS_HAND_FLAT /**< The flat of your hand @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_PEN_TIP EFL_INPUT_DEVICE_SUBCLASS_PEN_TIP /**< The tip of a pen @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_PEN_TIP EFL_INPUT_DEVICE_SUB_CLASS_PEN_TIP /**< The tip of a pen @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_TRACKPAD EFL_INPUT_DEVICE_SUBCLASS_TRACKPAD /**< A trackpad style mouse @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_TRACKPAD EFL_INPUT_DEVICE_SUB_CLASS_TRACKPAD /**< A trackpad style mouse @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_TRACKPOINT EFL_INPUT_DEVICE_SUBCLASS_TRACKPOINT /**< A trackpoint style mouse @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_TRACKPOINT EFL_INPUT_DEVICE_SUB_CLASS_TRACKPOINT /**< A trackpoint style mouse @since 1.8 */
|
||||||
#define EVAS_DEVICE_SUBCLASS_TRACKBALL EFL_INPUT_DEVICE_SUBCLASS_TRACKBALL /**< A trackball style mouse @since 1.8 */
|
#define EVAS_DEVICE_SUBCLASS_TRACKBALL EFL_INPUT_DEVICE_SUB_CLASS_TRACKBALL /**< A trackball style mouse @since 1.8 */
|
||||||
|
|
||||||
typedef Efl_Pointer_Flags Evas_Button_Flags;
|
typedef Efl_Pointer_Flags Evas_Button_Flags;
|
||||||
|
|
||||||
|
@ -1126,10 +1126,38 @@ EAPI void evas_render_updates_free(Eina_List *updates);
|
||||||
* @return the device node created or NULL if an error occurred.
|
* @return the device node created or NULL if an error occurred.
|
||||||
*
|
*
|
||||||
* @see evas_device_del
|
* @see evas_device_del
|
||||||
|
* @see evas_device_full_add
|
||||||
* @since 1.8
|
* @since 1.8
|
||||||
*/
|
*/
|
||||||
EAPI Evas_Device *evas_device_add(Evas *e);
|
EAPI Evas_Device *evas_device_add(Evas *e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new device type
|
||||||
|
*
|
||||||
|
* @param e The canvas to create the device node for.
|
||||||
|
* @param name The name of the device.
|
||||||
|
* @param desc The description of the device.
|
||||||
|
* @param parent_dev The parent device.
|
||||||
|
* @param emulation_dev The source device.
|
||||||
|
* @param clas The device class.
|
||||||
|
* @param sub_class The device subclass.
|
||||||
|
*
|
||||||
|
* Adds a new device node to the given canvas @p e. All devices created as
|
||||||
|
* part of the canvas @p e will automatically be deleted when the canvas
|
||||||
|
* is freed.
|
||||||
|
*
|
||||||
|
* @return the device node created or NULL if an error occurred.
|
||||||
|
*
|
||||||
|
* @see evas_device_del
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
EAPI Evas_Device *evas_device_full_add(Evas *eo_e, const char *name,
|
||||||
|
const char *desc,
|
||||||
|
Evas_Device *parent_dev,
|
||||||
|
Evas_Device *emulation_dev,
|
||||||
|
Evas_Device_Class clas,
|
||||||
|
Evas_Device_Subclass sub_clas);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a new device type
|
* Delete a new device type
|
||||||
*
|
*
|
||||||
|
|
|
@ -31,10 +31,22 @@ _del_cb(void *data, const Efl_Event *ev)
|
||||||
|
|
||||||
// can not be done in std destructor
|
// can not be done in std destructor
|
||||||
e->devices = eina_list_remove(e->devices, ev->object);
|
e->devices = eina_list_remove(e->devices, ev->object);
|
||||||
|
efl_event_callback_call(e->evas, EFL_CANVAS_EVENT_DEVICE_REMOVED,
|
||||||
|
ev->object);
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI Evas_Device *
|
EAPI Evas_Device *
|
||||||
evas_device_add(Evas *eo_e)
|
evas_device_add(Evas *eo_e)
|
||||||
|
{
|
||||||
|
return evas_device_full_add(eo_e, NULL, NULL, NULL, NULL,
|
||||||
|
EVAS_DEVICE_CLASS_NONE,
|
||||||
|
EVAS_DEVICE_SUBCLASS_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Evas_Device *
|
||||||
|
evas_device_full_add(Evas *eo_e, const char *name, const char *desc,
|
||||||
|
Evas_Device *parent_dev, Evas_Device *emulation_dev,
|
||||||
|
Evas_Device_Class clas, Evas_Device_Subclass sub_clas)
|
||||||
{
|
{
|
||||||
Efl_Input_Device_Data *d;
|
Efl_Input_Device_Data *d;
|
||||||
Evas_Public_Data *e;
|
Evas_Public_Data *e;
|
||||||
|
@ -42,15 +54,24 @@ evas_device_add(Evas *eo_e)
|
||||||
|
|
||||||
SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS, NULL);
|
SAFETY_CHECK(eo_e, EVAS_CANVAS_CLASS, NULL);
|
||||||
|
|
||||||
dev = efl_add(EFL_INPUT_DEVICE_CLASS, eo_e);
|
dev = efl_add(EFL_INPUT_DEVICE_CLASS, eo_e,
|
||||||
|
efl_input_device_name_set(efl_added, name),
|
||||||
|
efl_input_device_description_set(efl_added, desc),
|
||||||
|
efl_input_device_type_set(efl_added, clas),
|
||||||
|
efl_input_device_subtype_set(efl_added, sub_clas),
|
||||||
|
efl_input_device_source_set(efl_added, emulation_dev),
|
||||||
|
efl_input_device_parent_set(efl_added, parent_dev));
|
||||||
|
|
||||||
d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
d = efl_data_scope_get(dev, EFL_INPUT_DEVICE_CLASS);
|
||||||
d->evas = eo_e;
|
d->evas = eo_e;
|
||||||
|
|
||||||
e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
||||||
e->devices = eina_list_append(e->devices, dev);
|
if (!parent_dev)
|
||||||
|
e->devices = eina_list_append(e->devices, dev);
|
||||||
efl_event_callback_add(dev, EFL_EVENT_DEL, _del_cb, e);
|
efl_event_callback_add(dev, EFL_EVENT_DEL, _del_cb, e);
|
||||||
|
|
||||||
|
efl_event_callback_call(eo_e, EFL_CANVAS_EVENT_DEVICE_ADDED, dev);
|
||||||
|
// Keeping this event to do not break things...
|
||||||
evas_event_callback_call(eo_e, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
evas_event_callback_call(eo_e, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
|
@ -61,7 +82,7 @@ evas_device_del(Evas_Device *dev)
|
||||||
{
|
{
|
||||||
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
SAFETY_CHECK(dev, EFL_INPUT_DEVICE_CLASS);
|
||||||
|
|
||||||
efl_unref(dev);
|
efl_del(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
|
@ -155,24 +176,11 @@ evas_device_parent_set(Evas_Device *dev, Evas_Device *parent)
|
||||||
SAFETY_CHECK(parent, EFL_INPUT_DEVICE_CLASS);
|
SAFETY_CHECK(parent, EFL_INPUT_DEVICE_CLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: move this to Efl.Input.Device */
|
efl_input_device_parent_set(dev, parent);
|
||||||
if (d->parent == parent) return;
|
|
||||||
if (d->parent)
|
|
||||||
{
|
|
||||||
Efl_Input_Device_Data *p = efl_data_scope_get(d->parent, EFL_INPUT_DEVICE_CLASS);
|
|
||||||
p->children = eina_list_remove(p->children, dev);
|
|
||||||
}
|
|
||||||
else if (parent)
|
|
||||||
e->devices = eina_list_remove(e->devices, dev);
|
|
||||||
d->parent = parent;
|
|
||||||
if (parent)
|
if (parent)
|
||||||
{
|
e->devices = eina_list_remove(e->devices, dev);
|
||||||
Efl_Input_Device_Data *p = efl_data_scope_get(parent, EFL_INPUT_DEVICE_CLASS);
|
|
||||||
p->children = eina_list_append(p->children, dev);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
e->devices = eina_list_append(e->devices, dev);
|
e->devices = eina_list_append(e->devices, dev);
|
||||||
|
|
||||||
evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
evas_event_callback_call(d->evas, EVAS_CALLBACK_DEVICE_CHANGED, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,12 @@
|
||||||
#include "ecore_evas_private.h"
|
#include "ecore_evas_private.h"
|
||||||
#include "ecore_evas_x11.h"
|
#include "ecore_evas_x11.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_VNC_SERVER
|
||||||
|
# include <rfb/rfb.h>
|
||||||
|
# include <rfb/rfbregion.h>
|
||||||
|
# include <rfb/keysym.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef EAPI
|
#ifdef EAPI
|
||||||
# undef EAPI
|
# undef EAPI
|
||||||
#endif
|
#endif
|
||||||
|
@ -131,6 +137,17 @@ struct _Ecore_Evas_Engine_Data_X11 {
|
||||||
unsigned long colormap; // store colormap used to create pixmap
|
unsigned long colormap; // store colormap used to create pixmap
|
||||||
} pixmap;
|
} pixmap;
|
||||||
Eina_Bool destroyed : 1; // X window has been deleted and cannot be used
|
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);
|
static Ecore_Evas_Interface_X11 * _ecore_evas_x_interface_x11_new(void);
|
||||||
|
@ -152,6 +169,131 @@ static void _transparent_do(Ecore_Evas *, int);
|
||||||
static void _avoid_damage_do(Ecore_Evas *, int);
|
static void _avoid_damage_do(Ecore_Evas *, int);
|
||||||
static void _rotation_do(Ecore_Evas *, int, 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;
|
||||||
|
unsigned int key_modifiers;
|
||||||
|
time_t last_mouse_button_down;
|
||||||
|
Eina_Bool double_click;
|
||||||
|
Eina_Bool triple_click;
|
||||||
|
Evas_Device *keyboard;
|
||||||
|
Evas_Device *mouse;
|
||||||
|
Evas_Device *seat;
|
||||||
|
} 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 '%s'\n",
|
||||||
|
evas_device_name_get(cdata->seat));
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
static void
|
||||||
_ecore_evas_x_hints_update(Ecore_Evas *ee)
|
_ecore_evas_x_hints_update(Ecore_Evas *ee)
|
||||||
{
|
{
|
||||||
|
@ -2059,6 +2201,16 @@ _ecore_evas_x_free(Ecore_Evas *ee)
|
||||||
ecore_timer_del(edata->outdelay);
|
ecore_timer_del(edata->outdelay);
|
||||||
edata->outdelay = NULL;
|
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);
|
free(edata);
|
||||||
_ecore_evas_x_shutdown();
|
_ecore_evas_x_shutdown();
|
||||||
ecore_x_shutdown();
|
ecore_x_shutdown();
|
||||||
|
@ -4110,6 +4262,7 @@ ecore_evas_software_x11_new_internal(const char *disp_name, Ecore_X_Window paren
|
||||||
einfo->info.screen = NULL;
|
einfo->info.screen = NULL;
|
||||||
# endif
|
# endif
|
||||||
einfo->info.drawable = ee->prop.window;
|
einfo->info.drawable = ee->prop.window;
|
||||||
|
einfo->func.region_push_hook = _ecore_evas_x11_region_push_hook;
|
||||||
|
|
||||||
if (argb)
|
if (argb)
|
||||||
{
|
{
|
||||||
|
@ -4298,6 +4451,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;
|
einfo->info.destination_alpha = argb;
|
||||||
|
|
||||||
if (redraw_debug < 0)
|
if (redraw_debug < 0)
|
||||||
|
@ -5131,6 +5285,448 @@ _ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
|
||||||
ecore_x_window_shape_input_window_set(ee->prop.window, edata->win_shaped_input);
|
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 '%s' gone", evas_device_name_get(cdata->seat));
|
||||||
|
|
||||||
|
ecore_main_fd_handler_del(cdata->handler);
|
||||||
|
evas_device_del(cdata->keyboard);
|
||||||
|
evas_device_del(cdata->mouse);
|
||||||
|
evas_device_del(cdata->seat);
|
||||||
|
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;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "seat-%u", _available_seat);
|
||||||
|
|
||||||
|
cdata->seat = evas_device_full_add(ee->evas, buf,
|
||||||
|
"A remote VNC seat",
|
||||||
|
NULL, NULL, EVAS_DEVICE_CLASS_SEAT,
|
||||||
|
EVAS_DEVICE_SUBCLASS_NONE);
|
||||||
|
EINA_SAFETY_ON_NULL_GOTO(cdata->seat, err_handler);
|
||||||
|
cdata->keyboard = evas_device_full_add(ee->evas, "Keyboard",
|
||||||
|
"A remote VNC keyboard",
|
||||||
|
cdata->seat, NULL,
|
||||||
|
EVAS_DEVICE_CLASS_KEYBOARD,
|
||||||
|
EVAS_DEVICE_SUBCLASS_NONE);
|
||||||
|
EINA_SAFETY_ON_NULL_GOTO(cdata->keyboard, err_dev);
|
||||||
|
cdata->mouse = evas_device_full_add(ee->evas, "Mouse",
|
||||||
|
"A remote VNC mouse",
|
||||||
|
cdata->seat, NULL,
|
||||||
|
EVAS_DEVICE_CLASS_MOUSE,
|
||||||
|
EVAS_DEVICE_SUBCLASS_NONE);
|
||||||
|
EINA_SAFETY_ON_NULL_GOTO(cdata->mouse, err_mouse);
|
||||||
|
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_mouse:
|
||||||
|
evas_device_del(cdata->keyboard);
|
||||||
|
err_dev:
|
||||||
|
evas_device_del(cdata->seat);
|
||||||
|
err_handler:
|
||||||
|
free(cdata);
|
||||||
|
return RFB_CLIENT_REFUSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
_ecore_evas_x11_vnc_vnc_modifier_to_ecore_x_modifier(int mod)
|
||||||
|
{
|
||||||
|
if (mod == XK_Shift_L || mod == XK_Shift_R)
|
||||||
|
return ECORE_EVENT_MODIFIER_SHIFT;
|
||||||
|
if (mod == XK_Control_L || mod == XK_Control_R)
|
||||||
|
return ECORE_EVENT_MODIFIER_CTRL;
|
||||||
|
if (mod == XK_Alt_L || mod == XK_Alt_R)
|
||||||
|
return ECORE_EVENT_MODIFIER_ALT;
|
||||||
|
if (mod == XK_Super_L || mod == XK_Super_R)
|
||||||
|
return ECORE_EVENT_MODIFIER_WIN;
|
||||||
|
if (mod == XK_Scroll_Lock)
|
||||||
|
return ECORE_EVENT_LOCK_SCROLL;
|
||||||
|
if (mod == XK_Num_Lock)
|
||||||
|
return ECORE_EVENT_LOCK_NUM;
|
||||||
|
if (mod == XK_Caps_Lock)
|
||||||
|
return ECORE_EVENT_LOCK_CAPS;
|
||||||
|
if (mod == XK_Shift_Lock)
|
||||||
|
return ECORE_EVENT_LOCK_SHIFT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ecore_evas_x11_ecore_event_generic_free(void *user_data,
|
||||||
|
void *func_data)
|
||||||
|
{
|
||||||
|
efl_unref(user_data);
|
||||||
|
free(func_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ecore_evas_x11_vnc_client_keyboard_event(rfbBool down,
|
||||||
|
rfbKeySym key,
|
||||||
|
rfbClientRec *client)
|
||||||
|
{
|
||||||
|
Ecore_Event_Key *e;
|
||||||
|
Ecore_Evas_X11_Vnc_Client_Data *cdata = client->clientData;
|
||||||
|
rfbScreenInfoPtr screen = client->screen;
|
||||||
|
Ecore_Evas *ee = screen->screenData;
|
||||||
|
const char *key_string;
|
||||||
|
char buf[10];
|
||||||
|
|
||||||
|
if (key >= XK_Shift_L && key <= XK_Hyper_R)
|
||||||
|
{
|
||||||
|
int mod = _ecore_evas_x11_vnc_vnc_modifier_to_ecore_x_modifier(key);
|
||||||
|
|
||||||
|
if (down)
|
||||||
|
cdata->key_modifiers |= mod;
|
||||||
|
else
|
||||||
|
cdata->key_modifiers &= ~mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ee->ignore_events)
|
||||||
|
return;
|
||||||
|
|
||||||
|
key_string = ecore_x_keysym_string_get(key);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(key_string);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%lc", key);
|
||||||
|
|
||||||
|
e = calloc(1, sizeof(Ecore_Event_Key) + strlen(buf) + 1);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(e);
|
||||||
|
|
||||||
|
e->timestamp = (unsigned int)time(NULL);
|
||||||
|
e->modifiers = cdata->key_modifiers;
|
||||||
|
e->same_screen = 1;
|
||||||
|
e->window = e->root_window = e->event_window = 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->compose = (char *)(e + 1);
|
||||||
|
strcpy((char *)e->compose, buf);
|
||||||
|
e->string = e->compose;
|
||||||
|
|
||||||
|
ecore_event_add(down ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP,
|
||||||
|
e, _ecore_evas_x11_ecore_event_generic_free,
|
||||||
|
cdata->keyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_ecore_evas_x11_vnc_pointer_button_get(int mask)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
if (mask >> i & 1)
|
||||||
|
return i + 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ecore_evas_x11_vnc_client_pointer_event(int button_mask,
|
||||||
|
int x, int y,
|
||||||
|
rfbClientPtr client)
|
||||||
|
{
|
||||||
|
Ecore_Evas_X11_Vnc_Client_Data *cdata = client->clientData;
|
||||||
|
rfbScreenInfoPtr screen = client->screen;
|
||||||
|
Ecore_Evas *ee = screen->screenData;
|
||||||
|
Ecore_Event_Mouse_Move *move_event;
|
||||||
|
Ecore_Event_Mouse_Button *button_event;
|
||||||
|
Ecore_Event_Mouse_Wheel *wheel_event;
|
||||||
|
int button_changed, button, event, z = 0, direction = 0;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
if (ee->ignore_events)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (client->lastPtrX != x || client->lastPtrY != y)
|
||||||
|
{
|
||||||
|
move_event = calloc(1, sizeof(Ecore_Event_Mouse_Move));
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(move_event);
|
||||||
|
|
||||||
|
move_event->x = move_event->multi.x = x;
|
||||||
|
move_event->y = move_event->multi.y = y;
|
||||||
|
move_event->same_screen = 1;
|
||||||
|
move_event->timestamp = (unsigned int)now;
|
||||||
|
move_event->window = move_event->event_window =
|
||||||
|
move_event->root_window = ee->prop.window;
|
||||||
|
move_event->multi.pressure = 1.0;
|
||||||
|
move_event->modifiers = cdata->key_modifiers;
|
||||||
|
move_event->dev = cdata->mouse;
|
||||||
|
efl_ref(cdata->mouse);
|
||||||
|
ecore_event_add(ECORE_EVENT_MOUSE_MOVE, move_event,
|
||||||
|
_ecore_evas_x11_ecore_event_generic_free, cdata->mouse);
|
||||||
|
client->lastPtrX = x;
|
||||||
|
client->lastPtrY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
button_changed = button_mask - client->lastPtrButtons;
|
||||||
|
|
||||||
|
if (button_changed > 0)
|
||||||
|
{
|
||||||
|
button = _ecore_evas_x11_vnc_pointer_button_get(button_changed);
|
||||||
|
|
||||||
|
switch (button)
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
event = ECORE_EVENT_MOUSE_WHEEL;
|
||||||
|
direction = 0; //Vertical
|
||||||
|
z = -1; //Up
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
event = ECORE_EVENT_MOUSE_WHEEL;
|
||||||
|
direction = 0;
|
||||||
|
z = 1; //Down
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
event = ECORE_EVENT_MOUSE_WHEEL;
|
||||||
|
direction = 1; //Horizontal
|
||||||
|
z = -1;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
event = ECORE_EVENT_MOUSE_WHEEL;
|
||||||
|
direction = 1;
|
||||||
|
z = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
event = ECORE_EVENT_MOUSE_BUTTON_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (now - cdata->last_mouse_button_down <= 1000 * ecore_x_double_click_time_get())
|
||||||
|
cdata->double_click = EINA_TRUE;
|
||||||
|
else
|
||||||
|
cdata->double_click = cdata->triple_click = EINA_FALSE;
|
||||||
|
|
||||||
|
if (now - cdata->last_mouse_button_down <= 2000 * ecore_x_double_click_time_get())
|
||||||
|
cdata->triple_click = EINA_TRUE;
|
||||||
|
else
|
||||||
|
cdata->triple_click = EINA_FALSE;
|
||||||
|
|
||||||
|
cdata->last_mouse_button_down = now;
|
||||||
|
}
|
||||||
|
else if (button_changed < 0)
|
||||||
|
{
|
||||||
|
button = _ecore_evas_x11_vnc_pointer_button_get(-button_changed);
|
||||||
|
//Ignore, it was already report.
|
||||||
|
if (button > 3 && button < 8)
|
||||||
|
return;
|
||||||
|
event = ECORE_EVENT_MOUSE_BUTTON_UP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN ||
|
||||||
|
event == ECORE_EVENT_MOUSE_BUTTON_UP)
|
||||||
|
{
|
||||||
|
button_event = calloc(1, sizeof(Ecore_Event_Mouse_Button));
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(button_event);
|
||||||
|
|
||||||
|
button_event->timestamp = (unsigned int)now;
|
||||||
|
button_event->window = button_event->event_window =
|
||||||
|
button_event->root_window = ee->prop.window;
|
||||||
|
button_event->x = button_event->multi.x = x;
|
||||||
|
button_event->y = button_event->multi.y = y;
|
||||||
|
button_event->multi.pressure = 1.0;
|
||||||
|
button_event->same_screen = 1;
|
||||||
|
button_event->buttons = button;
|
||||||
|
button_event->modifiers = cdata->key_modifiers;
|
||||||
|
button_event->double_click = cdata->double_click ? 1 : 0;
|
||||||
|
button_event->triple_click = cdata->triple_click ? 1 : 0;
|
||||||
|
button_event->dev = cdata->mouse;
|
||||||
|
efl_ref(cdata->mouse);
|
||||||
|
|
||||||
|
ecore_event_add(event, button_event,
|
||||||
|
_ecore_evas_x11_ecore_event_generic_free, cdata->mouse);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Mouse wheel
|
||||||
|
wheel_event = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(wheel_event);
|
||||||
|
wheel_event->dev = cdata->mouse;
|
||||||
|
efl_ref(cdata->mouse);
|
||||||
|
wheel_event->window = wheel_event->event_window =
|
||||||
|
wheel_event->root_window = ee->prop.window;
|
||||||
|
wheel_event->same_screen = 1;
|
||||||
|
wheel_event->modifiers = cdata->key_modifiers;
|
||||||
|
wheel_event->x = x;
|
||||||
|
wheel_event->y = y;
|
||||||
|
wheel_event->direction = direction;
|
||||||
|
wheel_event->z = z;
|
||||||
|
|
||||||
|
ecore_event_add(event, wheel_event,
|
||||||
|
_ecore_evas_x11_ecore_event_generic_free, cdata->mouse);
|
||||||
|
}
|
||||||
|
#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 *
|
static Ecore_Evas_Interface_X11 *
|
||||||
_ecore_evas_x_interface_x11_new(void)
|
_ecore_evas_x_interface_x11_new(void)
|
||||||
{
|
{
|
||||||
|
@ -5151,6 +5747,8 @@ _ecore_evas_x_interface_x11_new(void)
|
||||||
iface->shape_input_empty = _ecore_evas_x11_shape_input_empty;
|
iface->shape_input_empty = _ecore_evas_x11_shape_input_empty;
|
||||||
iface->shape_input_reset = _ecore_evas_x11_shape_input_reset;
|
iface->shape_input_reset = _ecore_evas_x11_shape_input_reset;
|
||||||
iface->shape_input_apply = _ecore_evas_x11_shape_input_apply;
|
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;
|
return iface;
|
||||||
}
|
}
|
||||||
|
@ -5205,3 +5803,4 @@ _ecore_evas_x_interface_gl_x11_new(void)
|
||||||
return iface;
|
return iface;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct _Evas_Engine_Info_Software_X11
|
||||||
void *(*best_visual_get) (int backend, void *connection, int screen);
|
void *(*best_visual_get) (int backend, void *connection, int screen);
|
||||||
unsigned int (*best_colormap_get) (int backend, void *connection, int screen);
|
unsigned int (*best_colormap_get) (int backend, void *connection, int screen);
|
||||||
int (*best_depth_get) (int backend, void *connection, int screen);
|
int (*best_depth_get) (int backend, void *connection, int screen);
|
||||||
|
void (*region_push_hook)(Evas *e, int x, int y, int w, int h, const void *pixels);
|
||||||
} func;
|
} func;
|
||||||
|
|
||||||
unsigned char mask_changed : 1;
|
unsigned char mask_changed : 1;
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <Ecore.h>
|
||||||
|
|
||||||
Evas_Native_Tbm_Surface_Image_Set_Call glsym__evas_native_tbm_surface_image_set = NULL;
|
Evas_Native_Tbm_Surface_Image_Set_Call glsym__evas_native_tbm_surface_image_set = NULL;
|
||||||
Evas_Native_Tbm_Surface_Stride_Get_Call glsym__evas_native_tbm_surface_stride_get = NULL;
|
Evas_Native_Tbm_Surface_Stride_Get_Call glsym__evas_native_tbm_surface_stride_get = NULL;
|
||||||
int _evas_engine_soft_x11_log_dom = -1;
|
int _evas_engine_soft_x11_log_dom = -1;
|
||||||
|
@ -133,6 +135,22 @@ _output_egl_setup(int w, int h, int rot, Display *disp, Drawable draw,
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
evas_software_x11_region_push_hook_call(Outbuf *buf, int x, int y, int w, int h,
|
||||||
|
const void *pixels)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!buf->region_push_hook.cb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
err = ecore_thread_main_loop_begin();
|
||||||
|
EINA_SAFETY_ON_TRUE_RETURN(err == -1);
|
||||||
|
buf->region_push_hook.cb(buf->region_push_hook.evas, x, y, w, h, pixels);
|
||||||
|
ecore_thread_main_loop_end();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_output_egl_shutdown(Render_Engine *re)
|
_output_egl_shutdown(Render_Engine *re)
|
||||||
{
|
{
|
||||||
|
@ -526,6 +544,8 @@ eng_setup(Evas *eo_e, void *in)
|
||||||
info->info.destination_alpha);
|
info->info.destination_alpha);
|
||||||
re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get;
|
re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get;
|
||||||
}
|
}
|
||||||
|
re->generic.ob->region_push_hook.cb = info->func.region_push_hook;
|
||||||
|
re->generic.ob->region_push_hook.evas = eo_e;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -621,6 +641,8 @@ eng_setup(Evas *eo_e, void *in)
|
||||||
if (ob)
|
if (ob)
|
||||||
{
|
{
|
||||||
evas_render_engine_software_generic_update(&re->generic, ob, e->output.w, e->output.h);
|
evas_render_engine_software_generic_update(&re->generic, ob, e->output.w, e->output.h);
|
||||||
|
ob->region_push_hook.cb = info->func.region_push_hook;
|
||||||
|
ob->region_push_hook.evas = eo_e;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if ((re) && (re->ob)) re->ob->onebuf = ponebuf; */
|
/* if ((re) && (re->ob)) re->ob->onebuf = ponebuf; */
|
||||||
|
|
|
@ -113,9 +113,16 @@ struct _Outbuf
|
||||||
unsigned char debug : 1;
|
unsigned char debug : 1;
|
||||||
unsigned char synced : 1;
|
unsigned char synced : 1;
|
||||||
} priv;
|
} priv;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
void (*cb)(Evas *e, int x, int y, int w, int h, const void *pixels);
|
||||||
|
Evas *evas;
|
||||||
|
} region_push_hook;
|
||||||
};
|
};
|
||||||
|
|
||||||
void evas_software_xlib_x_init(void);
|
void evas_software_xlib_x_init(void);
|
||||||
void evas_software_xcb_init(void);
|
void evas_software_xcb_init(void);
|
||||||
|
|
||||||
|
void evas_software_x11_region_push_hook_call(Outbuf *buf, int x, int y, int w, int h, const void *pixels);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -680,9 +680,14 @@ evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Eva
|
||||||
pixman_region_n_rects(&tmpr),
|
pixman_region_n_rects(&tmpr),
|
||||||
(const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL));
|
(const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL));
|
||||||
if (obr->xcbob)
|
if (obr->xcbob)
|
||||||
evas_software_xcb_output_buffer_paste(obr->xcbob,
|
{
|
||||||
buf->priv.x11.xcb.win,
|
evas_software_x11_region_push_hook_call(buf, 0, 0, obr->xcbob->xim->width,
|
||||||
buf->priv.x11.xcb.gc, 0, 0, 0);
|
obr->xcbob->xim->height,
|
||||||
|
evas_software_xcb_output_buffer_data(obr->xcbob, NULL));
|
||||||
|
evas_software_xcb_output_buffer_paste(obr->xcbob,
|
||||||
|
buf->priv.x11.xcb.win,
|
||||||
|
buf->priv.x11.xcb.gc, 0, 0, 0);
|
||||||
|
}
|
||||||
if (obr->mask)
|
if (obr->mask)
|
||||||
{
|
{
|
||||||
xcb_set_clip_rectangles(buf->priv.x11.xcb.conn,
|
xcb_set_clip_rectangles(buf->priv.x11.xcb.conn,
|
||||||
|
@ -709,10 +714,16 @@ evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Eva
|
||||||
evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win,
|
evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win,
|
||||||
obr->x, obr->y, obr->w, obr->h);
|
obr->x, obr->y, obr->w, obr->h);
|
||||||
if (obr->xcbob)
|
if (obr->xcbob)
|
||||||
evas_software_xcb_output_buffer_paste(obr->xcbob,
|
{
|
||||||
buf->priv.x11.xcb.win,
|
evas_software_x11_region_push_hook_call(buf, obr->x, obr->y,
|
||||||
buf->priv.x11.xcb.gc,
|
obr->xcbob->xim->width,
|
||||||
obr->x, obr->y, 0);
|
obr->xcbob->xim->height,
|
||||||
|
evas_software_xcb_output_buffer_data(obr->xcbob, NULL));
|
||||||
|
evas_software_xcb_output_buffer_paste(obr->xcbob,
|
||||||
|
buf->priv.x11.xcb.win,
|
||||||
|
buf->priv.x11.xcb.gc,
|
||||||
|
obr->x, obr->y, 0);
|
||||||
|
}
|
||||||
if (obr->mask)
|
if (obr->mask)
|
||||||
evas_software_xcb_output_buffer_paste(obr->mask,
|
evas_software_xcb_output_buffer_paste(obr->mask,
|
||||||
buf->priv.x11.xcb.mask,
|
buf->priv.x11.xcb.mask,
|
||||||
|
@ -959,10 +970,16 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, in
|
||||||
evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win,
|
evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win,
|
||||||
obr->x, obr->y, obr->w, obr->h);
|
obr->x, obr->y, obr->w, obr->h);
|
||||||
if (obr->xcbob)
|
if (obr->xcbob)
|
||||||
evas_software_xcb_output_buffer_paste(obr->xcbob,
|
{
|
||||||
buf->priv.x11.xcb.win,
|
evas_software_x11_region_push_hook_call(buf, obr->x, obr->y,
|
||||||
buf->priv.x11.xcb.gc,
|
obr->xcbob->xim->width,
|
||||||
obr->x, obr->y, 0);
|
obr->xcbob->xim->height,
|
||||||
|
evas_software_xcb_output_buffer_data(obr->xcbob, NULL));
|
||||||
|
evas_software_xcb_output_buffer_paste(obr->xcbob,
|
||||||
|
buf->priv.x11.xcb.win,
|
||||||
|
buf->priv.x11.xcb.gc,
|
||||||
|
obr->x, obr->y, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (obr->mask)
|
if (obr->mask)
|
||||||
|
|
|
@ -818,9 +818,14 @@ evas_software_xlib_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Ev
|
||||||
eina_array_clean(&buf->priv.onebuf_regions);
|
eina_array_clean(&buf->priv.onebuf_regions);
|
||||||
XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc, tmpr);
|
XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc, tmpr);
|
||||||
if (obr->xob)
|
if (obr->xob)
|
||||||
evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
|
{
|
||||||
buf->priv.x11.xlib.gc,
|
evas_software_x11_region_push_hook_call(buf, 0, 0, obr->xob->xim->width,
|
||||||
0, 0, 0);
|
obr->xob->xim->height,
|
||||||
|
evas_software_xlib_x_output_buffer_data(obr->xob, NULL));
|
||||||
|
evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
|
||||||
|
buf->priv.x11.xlib.gc,
|
||||||
|
0, 0, 0);
|
||||||
|
}
|
||||||
if (obr->mxob)
|
if (obr->mxob)
|
||||||
{
|
{
|
||||||
XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gcm, tmpr);
|
XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gcm, tmpr);
|
||||||
|
@ -843,9 +848,15 @@ evas_software_xlib_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Ev
|
||||||
evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
|
evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
|
||||||
obr->x, obr->y, obr->w, obr->h);
|
obr->x, obr->y, obr->w, obr->h);
|
||||||
if (obr->xob)
|
if (obr->xob)
|
||||||
evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
|
{
|
||||||
buf->priv.x11.xlib.gc,
|
evas_software_x11_region_push_hook_call(buf, obr->x, obr->y,
|
||||||
obr->x, obr->y, 0);
|
obr->xob->xim->width,
|
||||||
|
obr->xob->xim->height,
|
||||||
|
evas_software_xlib_x_output_buffer_data(obr->xob, NULL));
|
||||||
|
evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
|
||||||
|
buf->priv.x11.xlib.gc,
|
||||||
|
obr->x, obr->y, 0);
|
||||||
|
}
|
||||||
if (obr->mxob)
|
if (obr->mxob)
|
||||||
evas_software_xlib_x_output_buffer_paste(obr->mxob,
|
evas_software_xlib_x_output_buffer_paste(obr->mxob,
|
||||||
buf->priv.x11.xlib.mask,
|
buf->priv.x11.xlib.mask,
|
||||||
|
@ -1124,9 +1135,15 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
|
||||||
evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
|
evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
|
||||||
obr->x, obr->y, obr->w, obr->h);
|
obr->x, obr->y, obr->w, obr->h);
|
||||||
if (obr->xob)
|
if (obr->xob)
|
||||||
evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
|
{
|
||||||
buf->priv.x11.xlib.gc,
|
evas_software_x11_region_push_hook_call(buf, obr->x, obr->y,
|
||||||
obr->x, obr->y, 0);
|
obr->xob->xim->width,
|
||||||
|
obr->xob->xim->height,
|
||||||
|
evas_software_xlib_x_output_buffer_data(obr->xob, NULL));
|
||||||
|
evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
|
||||||
|
buf->priv.x11.xlib.gc,
|
||||||
|
obr->x, obr->y, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (obr->mxob)
|
if (obr->mxob)
|
||||||
|
|
Loading…
Reference in New Issue