forked from enlightenment/efl
Compare commits
1 Commits
master
...
devs/bu5hm
Author | SHA1 | Date |
---|---|---|
Marcel Hollerbach | 202bae05ec |
|
@ -47,6 +47,8 @@ typedef struct _Elput_Pointer Elput_Pointer;
|
||||||
/* opaque structure to represent a touch device */
|
/* opaque structure to represent a touch device */
|
||||||
typedef struct _Elput_Touch Elput_Touch;
|
typedef struct _Elput_Touch Elput_Touch;
|
||||||
|
|
||||||
|
typedef struct _Elput_Swipe_Gesture Elput_Swipe_Gesture;
|
||||||
|
|
||||||
/* structure to represent event for seat capability changes */
|
/* structure to represent event for seat capability changes */
|
||||||
typedef struct _Elput_Event_Seat_Caps
|
typedef struct _Elput_Event_Seat_Caps
|
||||||
{
|
{
|
||||||
|
@ -201,6 +203,19 @@ EAPI int elput_shutdown(void);
|
||||||
*/
|
*/
|
||||||
EAPI Elput_Manager *elput_manager_connect(const char *seat, unsigned int tty);
|
EAPI Elput_Manager *elput_manager_connect(const char *seat, unsigned int tty);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an input manager on the specified seat. Only gesture events are emitted. Nothing else.
|
||||||
|
*
|
||||||
|
* @param seat
|
||||||
|
* @param tty
|
||||||
|
*
|
||||||
|
* @return A Elput_Manager on success, NULL on failure
|
||||||
|
*
|
||||||
|
* @ingroup Elput_Manager_Group
|
||||||
|
*/
|
||||||
|
EAPI Elput_Manager *elput_manager_connect_gestures(const char *seat, unsigned int tty);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect an input manager
|
* Disconnect an input manager
|
||||||
*
|
*
|
||||||
|
@ -726,6 +741,17 @@ EAPI Eina_Stringshare *elput_seat_name_get(const Elput_Seat *seat);
|
||||||
* @since 1.20
|
* @since 1.20
|
||||||
*/
|
*/
|
||||||
EAPI Elput_Manager *elput_seat_manager_get(const Elput_Seat *seat);
|
EAPI Elput_Manager *elput_seat_manager_get(const Elput_Seat *seat);
|
||||||
|
|
||||||
|
typedef void (*Elput_Swipe_Gesture_Callback)(void *data, Elput_Device *dev, Elput_Swipe_Gesture *gesture);
|
||||||
|
|
||||||
|
EAPI double elput_swipe_dx_get(Elput_Swipe_Gesture *gesture);
|
||||||
|
EAPI double elput_swipe_dy_get(Elput_Swipe_Gesture *gesture);
|
||||||
|
EAPI int elput_swipe_finger_count_get(Elput_Swipe_Gesture *gesture);
|
||||||
|
EAPI void elput_manager_swipe_gesture_listen(Elput_Manager *em,
|
||||||
|
Elput_Swipe_Gesture_Callback begin, void *begin_data,
|
||||||
|
Elput_Swipe_Gesture_Callback update, void *update_data,
|
||||||
|
Elput_Swipe_Gesture_Callback end, void *end_data);
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# undef EAPI
|
# undef EAPI
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include <elput_private.h>
|
||||||
|
|
||||||
|
|
||||||
|
EAPI double
|
||||||
|
elput_swipe_dx_get(Elput_Swipe_Gesture *gesture)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(gesture, 0.0f);
|
||||||
|
return gesture->dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI double
|
||||||
|
elput_swipe_dy_get(Elput_Swipe_Gesture *gesture)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(gesture, 0.0f);
|
||||||
|
return gesture->dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI int
|
||||||
|
elput_swipe_finger_count_get(Elput_Swipe_Gesture *gesture)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(gesture, 0);
|
||||||
|
return gesture->finger_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI void
|
||||||
|
elput_manager_swipe_gesture_listen(Elput_Manager *em,
|
||||||
|
Elput_Swipe_Gesture_Callback begin, void *begin_data,
|
||||||
|
Elput_Swipe_Gesture_Callback update, void *update_data,
|
||||||
|
Elput_Swipe_Gesture_Callback end, void *end_data)
|
||||||
|
{
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN(em);
|
||||||
|
em->swipe_callback.begin.cb = begin;
|
||||||
|
em->swipe_callback.begin.data = begin_data;
|
||||||
|
em->swipe_callback.end.cb = end;
|
||||||
|
em->swipe_callback.end.data = end_data;
|
||||||
|
em->swipe_callback.update.cb = update;
|
||||||
|
em->swipe_callback.update.data = update_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Elput_Manager*
|
||||||
|
elput_manager_connect_gestures(const char *seat, unsigned int tty)
|
||||||
|
{
|
||||||
|
Elput_Manager *em = elput_manager_connect(seat, tty);
|
||||||
|
|
||||||
|
if (em)
|
||||||
|
{
|
||||||
|
em->only_gesture_events = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return em;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_eval_callback(Elput_Gesture_Swipe_Callback *callback, struct libinput_device *device, struct libinput_event_gesture *gesture)
|
||||||
|
{
|
||||||
|
Elput_Device *dev;
|
||||||
|
Elput_Swipe_Gesture elput_gesture = {
|
||||||
|
libinput_event_gesture_get_dx(gesture),
|
||||||
|
libinput_event_gesture_get_dy(gesture),
|
||||||
|
libinput_event_gesture_get_finger_count(gesture),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!callback->cb) return;
|
||||||
|
|
||||||
|
dev = libinput_device_get_user_data(device);
|
||||||
|
|
||||||
|
callback->cb(callback->data, dev, &elput_gesture);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_gesture_event_process(struct libinput_event *event)
|
||||||
|
{
|
||||||
|
Elput_Manager *em;
|
||||||
|
struct libinput *lib;
|
||||||
|
struct libinput_device *dev;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
lib = libinput_event_get_context(event);
|
||||||
|
dev = libinput_event_get_device(event);
|
||||||
|
em = libinput_get_user_data(lib);
|
||||||
|
|
||||||
|
switch (libinput_event_get_type(event))
|
||||||
|
{
|
||||||
|
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
|
||||||
|
_eval_callback(&em->swipe_callback.begin, dev, libinput_event_get_gesture_event(event));
|
||||||
|
break;
|
||||||
|
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
|
||||||
|
_eval_callback(&em->swipe_callback.update, dev, libinput_event_get_gesture_event(event));
|
||||||
|
break;
|
||||||
|
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
|
||||||
|
_eval_callback(&em->swipe_callback.end, dev, libinput_event_get_gesture_event(event));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -301,20 +301,25 @@ _udev_process_event(struct libinput_event *event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_process_event(struct libinput_event *event)
|
_process_event(Elput_Manager *em, struct libinput_event *event)
|
||||||
{
|
{
|
||||||
if (_udev_process_event(event)) return;
|
if (_udev_process_event(event)) return;
|
||||||
if (_evdev_event_process(event)) return;
|
if (!em->only_gesture_events)
|
||||||
|
{
|
||||||
|
if (_evdev_event_process(event)) return;
|
||||||
|
}
|
||||||
|
if (_gesture_event_process(event)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_process_events(Elput_Input *ei)
|
_process_events(Elput_Manager *em)
|
||||||
{
|
{
|
||||||
struct libinput_event *event;
|
struct libinput_event *event;
|
||||||
|
Elput_Input *ei = &em->input;
|
||||||
|
|
||||||
while ((ei->lib) && (event = libinput_get_event(ei->lib)))
|
while ((ei->lib) && (event = libinput_get_event(ei->lib)))
|
||||||
{
|
{
|
||||||
_process_event(event);
|
_process_event(em, event);
|
||||||
libinput_event_destroy(event);
|
libinput_event_destroy(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,14 +327,14 @@ _process_events(Elput_Input *ei)
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
_cb_input_dispatch(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Elput_Input *ei;
|
Elput_Manager *em;
|
||||||
|
|
||||||
ei = data;
|
em = data;
|
||||||
|
|
||||||
if ((ei->lib) && (libinput_dispatch(ei->lib) != 0))
|
if ((em->input.lib) && (libinput_dispatch(em->input.lib) != 0))
|
||||||
WRN("libinput failed to dispatch events");
|
WRN("libinput failed to dispatch events");
|
||||||
|
|
||||||
_process_events(ei);
|
_process_events(em);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -361,10 +366,10 @@ _elput_input_init_end(void *data, Ecore_Thread *eth EINA_UNUSED)
|
||||||
manager->input.hdlr =
|
manager->input.hdlr =
|
||||||
ecore_main_fd_handler_add(libinput_get_fd(manager->input.lib),
|
ecore_main_fd_handler_add(libinput_get_fd(manager->input.lib),
|
||||||
ECORE_FD_READ, _cb_input_dispatch,
|
ECORE_FD_READ, _cb_input_dispatch,
|
||||||
&manager->input, NULL, NULL);
|
manager, NULL, NULL);
|
||||||
|
|
||||||
if (manager->input.hdlr)
|
if (manager->input.hdlr)
|
||||||
_process_events(&manager->input);
|
_process_events(manager);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("Could not create input fd handler");
|
ERR("Could not create input fd handler");
|
||||||
|
@ -431,7 +436,7 @@ _elput_input_enable(Elput_Manager *manager)
|
||||||
{
|
{
|
||||||
if (libinput_resume(manager->input.lib) != 0) return;
|
if (libinput_resume(manager->input.lib) != 0) return;
|
||||||
manager->input.suspended = EINA_FALSE;
|
manager->input.suspended = EINA_FALSE;
|
||||||
_process_events(&manager->input);
|
_process_events(manager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +449,7 @@ _elput_input_disable(Elput_Manager *manager)
|
||||||
EINA_LIST_FOREACH(manager->input.seats, l, seat)
|
EINA_LIST_FOREACH(manager->input.seats, l, seat)
|
||||||
seat->pending_motion = 1;
|
seat->pending_motion = 1;
|
||||||
if (manager->input.lib) libinput_suspend(manager->input.lib);
|
if (manager->input.lib) libinput_suspend(manager->input.lib);
|
||||||
_process_events(&manager->input);
|
_process_events(manager);
|
||||||
manager->input.suspended = EINA_TRUE;
|
manager->input.suspended = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ static Elput_Interface *_ifaces[] =
|
||||||
#ifdef HAVE_SYSTEMD
|
#ifdef HAVE_SYSTEMD
|
||||||
&_logind_interface,
|
&_logind_interface,
|
||||||
#endif
|
#endif
|
||||||
|
&_root_interface,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,16 @@ struct _Elput_Device
|
||||||
Eina_Bool invert_y : 1;
|
Eina_Bool invert_y : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elput_Swipe_Gesture_Callback cb;
|
||||||
|
void *data;
|
||||||
|
} Elput_Gesture_Swipe_Callback;
|
||||||
|
|
||||||
|
struct _Elput_Swipe_Gesture {
|
||||||
|
double dx, dy;
|
||||||
|
int finger_count;
|
||||||
|
};
|
||||||
|
|
||||||
struct _Elput_Manager
|
struct _Elput_Manager
|
||||||
{
|
{
|
||||||
Elput_Interface *interface;
|
Elput_Interface *interface;
|
||||||
|
@ -257,6 +267,9 @@ struct _Elput_Manager
|
||||||
int vt_fd;
|
int vt_fd;
|
||||||
Ecore_Event_Handler *vt_hdlr;
|
Ecore_Event_Handler *vt_hdlr;
|
||||||
uint32_t window;
|
uint32_t window;
|
||||||
|
struct {
|
||||||
|
Elput_Gesture_Swipe_Callback begin, update, end;
|
||||||
|
} swipe_callback;
|
||||||
|
|
||||||
int pending_ptr_x;
|
int pending_ptr_x;
|
||||||
int pending_ptr_y;
|
int pending_ptr_y;
|
||||||
|
@ -282,6 +295,7 @@ struct _Elput_Manager
|
||||||
|
|
||||||
Elput_Input input;
|
Elput_Input input;
|
||||||
Eina_Bool del : 1;
|
Eina_Bool del : 1;
|
||||||
|
Eina_Bool only_gesture_events : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _Elput_Async_Open
|
typedef struct _Elput_Async_Open
|
||||||
|
@ -295,6 +309,7 @@ void _elput_input_enable(Elput_Manager *manager);
|
||||||
void _elput_input_disable(Elput_Manager *manager);
|
void _elput_input_disable(Elput_Manager *manager);
|
||||||
|
|
||||||
int _evdev_event_process(struct libinput_event *event);
|
int _evdev_event_process(struct libinput_event *event);
|
||||||
|
int _gesture_event_process(struct libinput_event *event);
|
||||||
Elput_Device *_evdev_device_create(Elput_Seat *seat, struct libinput_device *device);
|
Elput_Device *_evdev_device_create(Elput_Seat *seat, struct libinput_device *device);
|
||||||
void _evdev_device_destroy(Elput_Device *edev);
|
void _evdev_device_destroy(Elput_Device *edev);
|
||||||
void _evdev_keyboard_destroy(Elput_Keyboard *kbd);
|
void _evdev_keyboard_destroy(Elput_Keyboard *kbd);
|
||||||
|
@ -308,6 +323,7 @@ Elput_Keyboard *_evdev_keyboard_get(Elput_Seat *seat);
|
||||||
Elput_Touch *_evdev_touch_get(Elput_Seat *seat);
|
Elput_Touch *_evdev_touch_get(Elput_Seat *seat);
|
||||||
|
|
||||||
extern Elput_Interface _logind_interface;
|
extern Elput_Interface _logind_interface;
|
||||||
|
extern Elput_Interface _root_interface;
|
||||||
|
|
||||||
void _keyboard_keymap_update(Elput_Seat *seat);
|
void _keyboard_keymap_update(Elput_Seat *seat);
|
||||||
void _keyboard_group_update(Elput_Seat *seat);
|
void _keyboard_group_update(Elput_Seat *seat);
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
#include "elput_private.h"
|
||||||
|
#include <grp.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
# ifdef major
|
||||||
|
# define MAJOR(x) major(x)
|
||||||
|
# else
|
||||||
|
# define MAJOR(x) ((((x) >> 8) & 0xfff) | (((x) >> 32) & ~0xfff))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_user_part_of_input(void)
|
||||||
|
{
|
||||||
|
uid_t user = getuid();
|
||||||
|
struct passwd *user_pw = getpwuid(user);
|
||||||
|
gid_t *gids = NULL;
|
||||||
|
int number_of_groups = 0;
|
||||||
|
struct group *input_group = getgrnam("input");
|
||||||
|
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(user_pw, EINA_FALSE);
|
||||||
|
EINA_SAFETY_ON_NULL_RETURN_VAL(input_group, EINA_FALSE);
|
||||||
|
|
||||||
|
if (getgrouplist(user_pw->pw_name, getgid(), NULL, &number_of_groups) != -1)
|
||||||
|
{
|
||||||
|
ERR("Failed to enumerate groups of user");
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
number_of_groups ++;
|
||||||
|
gids = alloca((number_of_groups) * sizeof(gid_t));
|
||||||
|
if (getgrouplist(user_pw->pw_name, getgid(), gids, &number_of_groups) == -1)
|
||||||
|
{
|
||||||
|
ERR("Failed to get groups of user");
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < number_of_groups; ++i)
|
||||||
|
{
|
||||||
|
if (gids[i] == input_group->gr_gid)
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_root_connect(Elput_Manager **manager EINA_UNUSED, const char *seat EINA_UNUSED, unsigned int tty EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Elput_Manager *em;
|
||||||
|
|
||||||
|
em = calloc(1, sizeof(Elput_Manager));
|
||||||
|
if (!em) return EINA_FALSE;
|
||||||
|
|
||||||
|
em->interface = &_root_interface;
|
||||||
|
em->seat = eina_stringshare_add(seat);
|
||||||
|
|
||||||
|
if (!_user_part_of_input())
|
||||||
|
{
|
||||||
|
free(em);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
*manager = em;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_root_disconnect(Elput_Manager *em EINA_UNUSED)
|
||||||
|
{
|
||||||
|
//Nothing to do here, there is no data to free
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_root_open(Elput_Manager *em EINA_UNUSED, const char *path, int flags)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
int ret, fd = -1;
|
||||||
|
int fl;
|
||||||
|
|
||||||
|
ret = stat(path, &st);
|
||||||
|
if (ret < 0) return -1;
|
||||||
|
|
||||||
|
if (!S_ISCHR(st.st_mode)) return -1;
|
||||||
|
|
||||||
|
fd = open(path, flags);
|
||||||
|
if (fd < 0) return fd;
|
||||||
|
|
||||||
|
if (MAJOR(st.st_rdev) == 226) //DRM_MAJOR
|
||||||
|
em->drm_opens++;
|
||||||
|
|
||||||
|
fl = fcntl(fd, F_GETFL);
|
||||||
|
if (fl < 0) goto err;
|
||||||
|
|
||||||
|
if (flags & O_NONBLOCK)
|
||||||
|
fl |= O_NONBLOCK;
|
||||||
|
|
||||||
|
ret = fcntl(fd, F_SETFL, fl);
|
||||||
|
if (ret < 0) goto err;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
err:
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_root_open_async(Elput_Manager *em, const char *path, int flags)
|
||||||
|
{
|
||||||
|
int fd = _root_open(em, path, flags);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ret = write(em->input.pipe, &fd, sizeof(int));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
if ((errno == EAGAIN) || (errno == EINTR))
|
||||||
|
continue;
|
||||||
|
WRN("Failed to write to input pipe");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(em->input.pipe);
|
||||||
|
em->input.pipe = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_root_close(Elput_Manager *em EINA_UNUSED, int fd)
|
||||||
|
{
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_root_vt_set(Elput_Manager *em EINA_UNUSED, int vt EINA_UNUSED)
|
||||||
|
{
|
||||||
|
//Nothing to do here
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Elput_Interface _root_interface =
|
||||||
|
{
|
||||||
|
_root_connect,
|
||||||
|
_root_disconnect,
|
||||||
|
_root_open,
|
||||||
|
_root_open_async,
|
||||||
|
_root_close,
|
||||||
|
_root_vt_set,
|
||||||
|
};
|
|
@ -11,7 +11,9 @@ elput_src = files([
|
||||||
'elput_evdev.c',
|
'elput_evdev.c',
|
||||||
'elput_input.c',
|
'elput_input.c',
|
||||||
'elput_logind.c',
|
'elput_logind.c',
|
||||||
|
'elput_root.c',
|
||||||
'elput_manager.c',
|
'elput_manager.c',
|
||||||
|
'elput_gestures.c',
|
||||||
'elput.c',
|
'elput.c',
|
||||||
'elput_private.h'
|
'elput_private.h'
|
||||||
])
|
])
|
||||||
|
|
Loading…
Reference in New Issue