efl/src/lib/ecore_fb/ecore_fb_ps2.c

225 lines
6.9 KiB
C

typedef struct _Ecore_Fb_Ps2_Event Ecore_Fb_Ps2_Event;
struct _Ecore_Fb_Ps2_Event
{
unsigned char button;
unsigned char x;
unsigned char y;
unsigned char z;
};
static int _ecore_fb_ps2_event_byte_count = 0;
static Ecore_Fb_Ps2_Event _ecore_fb_ps2_event;
static int _ecore_fb_ps2_fd = 0;
static Eina_Bool _ecore_fb_ps2_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
int
ecore_fb_ps2_init(void)
{
_ecore_fb_ps2_fd = open("/dev/psaux", O_RDWR);
if (_ecore_fb_ps2_fd >= 0)
{
prev_flags = fcntl(_ecore_fb_ps2_fd, F_GETFL);
fcntl(_ecore_fb_ps2_fd, F_SETFL, prev_flags | O_NONBLOCK);
_ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ps2_fd,
ECORE_FD_READ,
_ecore_fb_ps2_fd_handler, NULL, NULL, NULL);
if (!_ecore_fb_ts_fd_handler_handle)
{
close(_ecore_fb_ps2_fd);
return 0;
}
return 1;
}
return 0;
}
void
ecore_fb_ps2_shutdown(void)
{
if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd);
_ecore_fb_ps2_fd = 0;
}
static Eina_Bool
_ecore_fb_ps2_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
{
static int prev_x = 0, prev_y = 0, prev_button = 0;
static double last_time = 0;
static double last_last_time = 0;
int v = 0;
do
{
int x, y, button, i;
int num;
char *ptr;
double t;
static int did_double = 0;
static int did_triple = 0;
ptr = (char *)&(_ecore_fb_ps2_event);
ptr += _ecore_fb_ps2_event_byte_count;
num = sizeof(Ecore_Fb_Ps2_Event) - _ecore_fb_ps2_event_byte_count;
v = read(_ecore_fb_ps2_fd, ptr, num);
if (v < 0) return EINA_TRUE;
_ecore_fb_ps2_event_byte_count += v;
if (v < num) return EINA_TRUE;
t = ecore_loop_time_get();
_ecore_fb_ps2_event_byte_count = 0;
if (_ecore_fb_ps2_event.button & 0x10)
x = prev_x + (0xffffff00 | _ecore_fb_ps2_event.x);
else
x = prev_x + _ecore_fb_ps2_event.x;
if (_ecore_fb_ps2_event.button & 0x20)
y = prev_y - (0xffffff00 | _ecore_fb_ps2_event.y);
else
y = prev_y - _ecore_fb_ps2_event.y;
button = _ecore_fb_ps2_event.button & 0x7;
if (x < 0) x = 0;
if (y < 0) y = 0;
if (x >= _ecore_fb_console_w) x = _ecore_fb_console_w - 1;
if (y >= _ecore_fb_console_h) y = _ecore_fb_console_h - 1;
/* add event to queue */
/* always add a move event */
if (1)
{
/* MOVE: mouse is down and was */
Ecore_Event_Mouse_Move *e;
e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move));
if (!e) goto retry;
e->x = x;
e->y = y;
e->root.x = e->x;
e->root.y = e->y;
e->window = 1;
e->event_window = e->window;
e->root_window = e->window;
e->same_screen = 1;
e->timestamp = ecore_loop_time_get() * 1000.0;
ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
}
for (i = 1; i <= 3; i++)
{
int mask;
mask = 1 << (i - 1);
if (((button & mask)) && (!(prev_button & mask)))
{
/* DOWN: mouse is down, but was not now */
Ecore_Event_Mouse_Button *e;
e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
if (!e) goto retry;
e->x = x;
e->y = y;
e->root.x = e->x;
e->root.y = e->y;
e->button = i;
e->window = 1;
e->event_window = e->window;
e->root_window = e->window;
e->same_screen = 1;
if ((t - last_time) <= _ecore_fb_double_click_time)
{
e->double_click = 1;
did_double = 1;
}
else
{
did_double = 0;
did_triple = 0;
}
if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
{
did_triple = 1;
e->triple_click = 1;
}
else
{
did_triple = 0;
}
e->timestamp = ecore_loop_time_get() * 1000.0;
ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
}
else if ((!(button & mask)) && ((prev_button & mask)))
{
/* UP: mouse was down, but is not now */
Ecore_Event_Mouse_Button *e;
e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
if (!e) goto retry;
e->x = x;
e->y = y;
e->root.x = e->x;
e->root.y = e->y;
e->button = i;
e->window = 1;
e->event_window = e->window;
e->root_window = e->window;
e->same_screen = 1;
if (did_double)
e->double_click = 1;
if (did_triple)
e->triple_click = 1;
e->timestamp = ecore_loop_time_get() * 1000.0;
ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
}
}
if (did_triple)
{
last_time = 0;
last_last_time = 0;
}
else
{
last_last_time = last_time;
last_time = t;
}
retry:
prev_x = x;
prev_y = y;
prev_button = button;
}
while (v > 0);
return EINA_TRUE;
}
/**
* @defgroup Ecore_FB_Click_Group Framebuffer Double Click Functions
* @ingroup Ecore_FB_Group
*
* Functions that deal with the double click time of the framebuffer.
*/
/**
* Sets the timeout for a double and triple clicks to be flagged.
*
* This sets the time between clicks before the double_click flag is
* set in a button down event. If 3 clicks occur within double this
* time, the triple_click flag is also set.
*
* @param t The time in seconds
* @ingroup Ecore_FB_Click_Group
*/
EAPI void
ecore_fb_double_click_time_set(double t)
{
if (t < 0.0) t = 0.0;
_ecore_fb_double_click_time = t;
}
/**
* Retrieves the double and triple click flag timeout.
*
* See @ref ecore_x_double_click_time_set for more information.
*
* @return The timeout for double clicks in seconds.
* @ingroup Ecore_FB_Click_Group
*/
EAPI double
ecore_fb_double_click_time_get(void)
{
return _ecore_fb_double_click_time;
}