@ -1,18 +1,31 @@
# include "e.h"
# include "e_mod_main.h"
# define HISTORY_MAX 8
typedef struct
{
E_Zone * zone ;
Ecore_X_Window win ;
Ecore_Timer * timer ;
int x , y , dx , dy ;
Ecore_Timer * double_down_timer ;
int x , y , dx , dy , mx , my ;
int mouse_history [ HISTORY_MAX ] ;
unsigned int dt ;
Eina_Inlist * history ;
Eina_Bool down : 1 ;
Eina_Bool two_finger_down : 1 ;
Eina_Bool mouse_double_down : 1 ;
} Cover ;
typedef struct
{
EINA_INLIST ;
int device ;
} Multi ;
static Eina_List * covers = NULL ;
static Eina_List * handlers = NULL ;
static int multi_device [ 3 ] ;
static Ecore_X_Window
_mouse_win_in_get ( Cover * cov , int x , int y )
@ -21,7 +34,7 @@ _mouse_win_in_get(Cover *cov, int x, int y)
Ecore_X_Window * skip , inwin ;
Cover * cov2 ;
int i ;
skip = alloca ( sizeof ( Ecore_X_Window ) * eina_list_count ( covers ) ) ;
i = 0 ;
EINA_LIST_FOREACH ( covers , l , cov2 )
@ -31,6 +44,7 @@ _mouse_win_in_get(Cover *cov, int x, int y)
}
inwin = ecore_x_window_shadow_tree_at_xy_with_skip_get
( cov - > zone - > container - > manager - > root , x , y , skip , i ) ;
return inwin ;
}
@ -39,8 +53,9 @@ _mouse_win_fake_tap(Cover *cov, Ecore_Event_Mouse_Button *ev)
{
Ecore_X_Window inwin ;
int x , y ;
inwin = _mouse_win_in_get ( cov , ev - > root . x , ev - > root . y ) ;
ecore_x_pointer_xy_get ( inwin , & x , & y ) ;
ecore_x_mouse_in_send ( inwin , x , y ) ;
ecore_x_mouse_move_send ( inwin , x , y ) ;
@ -49,20 +64,59 @@ _mouse_win_fake_tap(Cover *cov, Ecore_Event_Mouse_Button *ev)
ecore_x_mouse_out_send ( inwin , x , y ) ;
}
static void
_record_mouse_history ( Cover * cov , void * event )
{
Ecore_Event_Mouse_Move * ev = event ;
int i = 0 ;
for ( i = 0 ; i < HISTORY_MAX ; i + + )
{
if ( cov - > mouse_history [ i ] = = - 1 )
{
cov - > mouse_history [ i ] = ev - > multi . device ;
break ;
}
}
// if there is not enough space to save device number, shift!
if ( i = = HISTORY_MAX )
{
for ( i = 0 ; i < ( HISTORY_MAX - 1 ) ; i + + )
cov - > mouse_history [ i ] = cov - > mouse_history [ i + 1 ] ;
cov - > mouse_history [ HISTORY_MAX - 1 ] = ev - > multi . device ;
}
}
static Eina_Bool
_check_mouse_history ( Cover * cov )
{
int i = 0 ;
for ( i = 0 ; i < HISTORY_MAX ; i + + )
{
if ( ( cov - > mouse_history [ i ] ! = multi_device [ 0 ] ) & &
( cov - > mouse_history [ i ] ! = - 1 ) )
return EINA_FALSE ;
}
return EINA_TRUE ;
}
static Eina_Bool
_mouse_longpress ( void * data )
{
Cover * cov = data ;
int distance = 40 ;
int dx , dy ;
cov - > timer = NULL ;
dx = cov - > x - cov - > dx ;
dy = cov - > y - cov - > dy ;
if ( ( ( dx * dx ) + ( dy * dy ) ) < ( distance * distance ) )
{
E_Border * bd = e_border_focused_get ( ) ;
cov - > down = EINA_FALSE ;
printf ( " longpress \n " ) ;
if ( bd )
@ -71,18 +125,76 @@ _mouse_longpress(void *data)
return EINA_FALSE ;
}
static Eina_Bool
_mouse_double_down ( void * data )
{
Cover * cov = data ;
ecore_timer_del ( cov - > double_down_timer ) ;
cov - > double_down_timer = NULL ;
return EINA_FALSE ;
}
static void
_mouse_double_down_timeout ( Cover * cov )
{
double short_time = 0.3 ;
int distance = 40 ;
int dx , dy ;
dx = cov - > x - cov - > dx ;
dy = cov - > y - cov - > dy ;
if ( ( cov - > double_down_timer ) & &
( ( ( dx * dx ) + ( dy * dy ) ) < ( distance * distance ) ) )
{
// start double tap and move from here
cov - > mouse_double_down = EINA_TRUE ;
if ( cov - > timer )
{
ecore_timer_del ( cov - > timer ) ;
cov - > timer = NULL ;
}
}
if ( cov - > double_down_timer )
{
ecore_timer_del ( cov - > double_down_timer ) ;
cov - > double_down_timer = NULL ;
return ;
}
cov - > double_down_timer = ecore_timer_add ( short_time , _mouse_double_down ,
cov ) ;
}
static void
_mouse_down ( Cover * cov , Ecore_Event_Mouse_Button * ev )
{
int x , y ;
E_Border * bd ;
double longtime = 0.5 ;
cov - > dx = ev - > x ;
cov - > dy = ev - > y ;
cov - > mx = ev - > x ;
cov - > my = ev - > y ;
cov - > x = ev - > x ;
cov - > y = ev - > y ;
cov - > dt = ev - > timestamp ;
cov - > down = EINA_TRUE ;
cov - > timer = ecore_timer_add ( longtime , _mouse_longpress , cov ) ;
// 2nd finger comes...
_mouse_double_down_timeout ( cov ) ;
// mouse in should be here
bd = e_border_focused_get ( ) ;
if ( ! bd ) return ;
ecore_x_pointer_xy_get ( bd - > client . win , & x , & y ) ;
ecore_x_mouse_in_send ( bd - > client . win , x , y ) ;
}
static void
@ -91,8 +203,22 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
double timeout = 0.15 ;
int distance = 40 ;
int dx , dy ;
int x , y ;
E_Border * bd = e_border_focused_get ( ) ;
// for two finger panning
if ( cov - > two_finger_down )
{
ecore_x_pointer_xy_get ( bd - > client . win , & x , & y ) ;
ecore_x_mouse_up_send ( bd - > client . win , x , y , 1 ) ;
cov - > two_finger_down = EINA_FALSE ;
ecore_x_mouse_out_send ( bd - > client . win , x , y ) ;
}
// reset double down and moving
cov - > mouse_double_down = EINA_FALSE ;
if ( cov - > timer )
{
ecore_timer_del ( cov - > timer ) ;
@ -115,19 +241,26 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
ecore_x_e_illume_access_action_activate_send ( bd - > client . win ) ;
}
}
else
else if ( ( ( dx * dx ) + ( dy * dy ) ) > ( 4 * distance * distance )
& & ( ( ev - > timestamp - cov - > dt ) < ( timeout * 1000 ) ) )
{
if ( abs ( dx ) > abs ( dy ) ) // left or right
{
if ( dx > 0 ) // right
{
printf ( " right \n " ) ;
if ( _check_mouse_history ( cov ) )
printf ( " single flick right \n " ) ;
else
printf ( " double flick right \n " ) ;
if ( bd )
ecore_x_e_illume_access_action_read_next_send ( bd - > client . win ) ;
}
else // left
{
printf ( " left \n " ) ;
if ( _check_mouse_history ( cov ) )
printf ( " single flick left \n " ) ;
else
printf ( " double flick left \n " ) ;
if ( bd )
ecore_x_e_illume_access_action_read_prev_send ( bd - > client . win ) ;
}
@ -136,13 +269,20 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
{
if ( dy > 0 ) // down
{
printf ( " down \n " ) ;
if ( _check_mouse_history ( cov ) )
printf ( " single flick down \n " ) ;
else
printf ( " double flick down \n " ) ;
if ( bd )
ecore_x_e_illume_access_action_next_send ( bd - > client . win ) ;
}
else // up
{
printf ( " up \n " ) ;
if ( _check_mouse_history ( cov ) )
printf ( " single flick up \n " ) ;
else
printf ( " double flick up \n " ) ;
if ( bd )
ecore_x_e_illume_access_action_prev_send ( bd - > client . win ) ;
}
@ -154,9 +294,50 @@ _mouse_up(Cover *cov, Ecore_Event_Mouse_Button *ev)
static void
_mouse_move ( Cover * cov , Ecore_Event_Mouse_Move * ev )
{
if ( ! cov - > down ) return ;
int distance = 5 ;
int x , y ;
int dx , dy ;
E_Border * bd ;
//FIXME: why here.. after long press you cannot go below..
//if (!cov->down) return;
cov - > x = ev - > x ;
cov - > y = ev - > y ;
bd = e_border_focused_get ( ) ;
if ( ! bd ) return ;
_record_mouse_history ( cov , ev ) ;
ecore_x_pointer_xy_get ( bd - > client . win , & x , & y ) ;
ecore_x_mouse_move_send ( bd - > client . win , x , y ) ;
// for panning, without check two_finger_down, there will be several down_send()
if ( ( ev - > multi . device = = multi_device [ 0 ] ) & & ( cov - > mouse_double_down ) )
{
dx = ev - > x - cov - > mx ;
dy = ev - > y - cov - > my ;
if ( ( ( dx * dx ) + ( dy * dy ) ) > ( distance * distance ) )
{
if ( abs ( dx ) > abs ( dy ) ) // left or right
{
if ( dx > 0 ) // right
printf ( " mouse double down and moving - right \n " ) ;
else // left
printf ( " mouse double down and moving - left \n " ) ;
}
else // up or down
{
if ( dy > 0 ) // down
printf ( " mouse double down and moving - down \n " ) ;
else // up
printf ( " mouse double down and moving - up \n " ) ;
}
cov - > mx = ev - > x ;
cov - > my = ev - > y ;
}
}
}
static void
@ -173,13 +354,38 @@ _cb_mouse_down(void *data __UNUSED__,
Ecore_Event_Mouse_Button * ev = event ;
Eina_List * l ;
Cover * cov ;
int i = 0 ;
E_Border * bd ;
int x , y ;
for ( i = 0 ; i < 3 ; i + + )
{
if ( multi_device [ i ] = = - 1 )
{
multi_device [ i ] = ev - > multi . device ;
break ;
}
else if ( multi_device [ i ] = = ev - > multi . device ) break ;
}
EINA_LIST_FOREACH ( covers , l , cov )
{
if ( ev - > window = = cov - > win )
{
if ( ( ev - > buttons = = 1 ) & & ( ev - > multi . device = = 0 ) )
// XXX change specific number
if ( ev - > multi . device = = multi_device [ 0 ] )
_mouse_down ( cov , ev ) ;
if ( ( ev - > multi . device = = multi_device [ 1 ] ) & &
( ! cov - > two_finger_down ) )
{
bd = e_border_focused_get ( ) ;
if ( ! bd ) return ECORE_CALLBACK_PASS_ON ;
ecore_x_pointer_xy_get ( bd - > client . win , & x , & y ) ;
ecore_x_mouse_move_send ( bd - > client . win , x , y ) ;
ecore_x_mouse_down_send ( bd - > client . win , x , y , 1 ) ;
cov - > two_finger_down = EINA_TRUE ;
}
return ECORE_CALLBACK_PASS_ON ;
}
}
@ -194,12 +400,12 @@ _cb_mouse_up(void *data __UNUSED__,
Ecore_Event_Mouse_Button * ev = event ;
Eina_List * l ;
Cover * cov ;
EINA_LIST_FOREACH ( covers , l , cov )
{
if ( ev - > window = = cov - > win )
{
if ( ( ev - > buttons = = 1 ) & & ( ev - > multi . device = = 0 ) )
if ( ev - > buttons = = 1 )
_mouse_up ( cov , ev ) ;
return ECORE_CALLBACK_PASS_ON ;
}
@ -215,12 +421,12 @@ _cb_mouse_move(void *data __UNUSED__,
Ecore_Event_Mouse_Move * ev = event ;
Eina_List * l ;
Cover * cov ;
EINA_LIST_FOREACH ( covers , l , cov )
{
if ( ev - > window = = cov - > win )
{
if ( ev - > multi . device = = 0 )
if ( ( ev - > multi . device = = multi_device [ 0 ] ) | |
( ev - > multi . device = = multi_device [ 1 ] ) )
_mouse_move ( cov , ev ) ;
return ECORE_CALLBACK_PASS_ON ;
}
@ -236,7 +442,7 @@ _cb_mouse_wheel(void *data __UNUSED__,
Ecore_Event_Mouse_Wheel * ev = event ;
Eina_List * l ;
Cover * cov ;
EINA_LIST_FOREACH ( covers , l , cov )
{
if ( ev - > window = = cov - > win )
@ -252,7 +458,7 @@ static Cover *
_cover_new ( E_Zone * zone )
{
Cover * cov ;
cov = E_NEW ( Cover , 1 ) ;
if ( ! cov ) return NULL ;
cov - > zone = zone ;
@ -260,6 +466,9 @@ _cover_new(E_Zone *zone)
zone - > container - > x + zone - > x ,
zone - > container - > y + zone - > y ,
zone - > w , zone - > h ) ;
ecore_x_input_multi_select ( cov - > win ) ;
ecore_x_window_ignore_set ( cov - > win , 1 ) ;
ecore_x_window_configure ( cov - > win ,
ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
@ -268,6 +477,8 @@ _cover_new(E_Zone *zone)
zone - > container - > layers [ 8 ] . win ,
ECORE_X_WINDOW_STACK_ABOVE ) ;
ecore_x_window_show ( cov - > win ) ;
ecore_x_window_raise ( cov - > win ) ;
return cov ;
}
@ -276,19 +487,23 @@ _covers_init(void)
{
Eina_List * l , * l2 , * l3 ;
E_Manager * man ;
int i = 0 ;
EINA_LIST_FOREACH ( e_manager_list ( ) , l , man )
{
E_Container * con ;
EINA_LIST_FOREACH ( man - > containers , l2 , con )
{
E_Zone * zone ;
EINA_LIST_FOREACH ( con - > zones , l3 , zone )
{
Cover * cov = _cover_new ( zone ) ;
if ( cov ) covers = eina_list_append ( covers , cov ) ;
if ( cov )
{
covers = eina_list_append ( covers , cov ) ;
for ( i = 0 ; i < HISTORY_MAX ; i + + )
cov - > mouse_history [ i ] = - 1 ;
}
}
}
}
@ -298,7 +513,7 @@ static void
_covers_shutdown ( void )
{
Cover * cov ;
EINA_LIST_FREE ( covers , cov )
{
ecore_x_window_ignore_set ( cov - > win , 0 ) ;
@ -345,6 +560,8 @@ _cb_zone_move_resize(void *data __UNUSED__,
static void
_events_init ( void )
{
int i = 0 ;
handlers = eina_list_append
( handlers , ecore_event_handler_add ( ECORE_EVENT_MOUSE_BUTTON_DOWN ,
_cb_mouse_down , NULL ) ) ;
@ -366,6 +583,8 @@ _events_init(void)
handlers = eina_list_append
( handlers , ecore_event_handler_add ( E_EVENT_ZONE_MOVE_RESIZE ,
_cb_zone_move_resize , NULL ) ) ;
for ( i = 0 ; i < 3 ; i + + ) multi_device [ i ] = - 1 ;
}
static void