X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcontrol%2Fmotion.c;h=59d6ba2c516f5ffcdcee03407d25e0ae1f2613f8;hb=4e9597b800d1140dfab1cf33c3df8c608d58878f;hp=81511cbb2389472ace04977f2411d9c46f9d0893;hpb=7a5a63a7c0e59e4ab8471dfd4ad1da21a92ee34e;p=vlc diff --git a/modules/control/motion.c b/modules/control/motion.c index 81511cbb23..59d6ba2c51 100644 --- a/modules/control/motion.c +++ b/modules/control/motion.c @@ -1,10 +1,11 @@ /***************************************************************************** * motion.c: control VLC with laptop built-in motion sensors ***************************************************************************** - * Copyright (C) 2006 the VideoLAN team + * Copyright (C) 2006 - 2007 the VideoLAN team * $Id$ * * Author: Sam Hocevar + * Jérôme Decoodt (unimotion integration) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,27 +25,39 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* malloc(), free() */ -#include -#include -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include +#include +#include +#include #ifdef HAVE_UNISTD_H # include #endif +#ifdef __APPLE__ +#include "unimotion.h" +#endif + /***************************************************************************** * intf_sys_t: description and status of interface *****************************************************************************/ struct intf_sys_t { - enum { NO_SENSOR, HDAPS_SENSOR, AMS_SENSOR } sensor; - + enum { NO_SENSOR, HDAPS_SENSOR, AMS_SENSOR, APPLESMC_SENSOR, + UNIMOTION_SENSOR } sensor; +#ifdef __APPLE__ + enum sms_hardware unimotion_hw; +#endif int i_calibrate; - vlc_bool_t b_use_rotate; + bool b_use_rotate; }; /***************************************************************************** @@ -62,12 +75,14 @@ static int GetOrientation( intf_thread_t *p_intf ); * Module descriptor *****************************************************************************/ vlc_module_begin(); - set_shortname( _("motion")); + set_shortname( N_("motion")); set_category( CAT_INTERFACE ); - set_description( _("motion control interface") ); + set_description( N_("motion control interface") ); + set_help( N_("Use HDAPS, AMS, APPLESMC or UNIMOTION motion sensors " \ + "to rotate the video") ) add_bool( "motion-use-rotate", 0, NULL, - USE_ROTATE_TEXT, USE_ROTATE_TEXT, VLC_FALSE ); + USE_ROTATE_TEXT, USE_ROTATE_TEXT, false ); set_capability( "interface", 0 ); set_callbacks( Open, Close ); @@ -110,6 +125,28 @@ int Open ( vlc_object_t *p_this ) /* Apple Motion Sensor support */ p_intf->p_sys->sensor = AMS_SENSOR; } + else if( access( "/sys/devices/applesmc.768/position", R_OK ) == 0 ) + { + /* Apple SMC (newer macbooks) */ + /* Should be factorised with HDAPS */ + f = fopen( "/sys/devices/applesmc.768/calibrate", "r" ); + if( f ) + { + i_x = i_y = 0; + fscanf( f, "(%d,%d)", &i_x, &i_y ); + fclose( f ); + p_intf->p_sys->i_calibrate = i_x; + p_intf->p_sys->sensor = APPLESMC_SENSOR; + } + else + { + p_intf->p_sys->sensor = NO_SENSOR; + } + } +#ifdef __APPLE__ + else if( p_intf->p_sys->unimotion_hw = detect_sms() ) + p_intf->p_sys->sensor = UNIMOTION_SENSOR; +#endif else { /* No motion sensor support */ @@ -120,11 +157,6 @@ int Open ( vlc_object_t *p_this ) p_intf->p_sys->b_use_rotate = config_GetInt( p_intf, "motion-use-rotate" ); - if( p_intf->p_sys->b_use_rotate ) - { - var_Create( p_intf->p_libvlc, "rotate_angle", VLC_VAR_INTEGER ); - } - return VLC_SUCCESS; } @@ -141,50 +173,64 @@ void Close ( vlc_object_t *p_this ) /***************************************************************************** * RunIntf: main loop *****************************************************************************/ +#define FILTER_LENGTH 16 +#define LOW_THRESHOLD 800 +#define HIGH_THRESHOLD 1000 static void RunIntf( intf_thread_t *p_intf ) { - int i_x, i_oldx = 0; + int i_x, i_oldx = 0, i_sum = 0, i = 0; + int p_oldx[FILTER_LENGTH]; + memset( p_oldx, 0, FILTER_LENGTH * sizeof( int ) ); while( !intf_ShouldDie( p_intf ) ) { -#define LOW_THRESHOLD 80 -#define HIGH_THRESHOLD 100 vout_thread_t *p_vout; - char *psz_filter, *psz_type; - vlc_bool_t b_change = VLC_FALSE; + const char *psz_filter, *psz_type; + bool b_change = false; /* Wait a bit, get orientation, change filter if necessary */ msleep( INTF_IDLE_SLEEP ); i_x = GetOrientation( p_intf ); + i_sum += i_x - p_oldx[i]; + p_oldx[i++] = i_x; + if( i == FILTER_LENGTH ) i = 0; + i_x = i_sum / FILTER_LENGTH; if( p_intf->p_sys->b_use_rotate ) { if( i_oldx != i_x ) { - var_SetInteger( p_intf->p_libvlc, "rotate_angle", - ((360+i_x/2)%360) ); - i_oldx = i_x; + /* TODO: cache object pointer */ + vlc_object_t *p_obj = + vlc_object_find_name( p_intf->p_libvlc, "rotate", FIND_CHILD ); + if( p_obj ) + { + var_SetInteger( p_obj, "rotate-deciangle", + ((3600+i_x/2)%3600) ); + i_oldx = i_x; + vlc_object_release( p_obj ); + } } continue; } if( i_x < -HIGH_THRESHOLD && i_oldx > -LOW_THRESHOLD ) { - b_change = VLC_TRUE; + b_change = true; psz_filter = "transform"; psz_type = "270"; } else if( ( i_x > -LOW_THRESHOLD && i_oldx < -HIGH_THRESHOLD ) || ( i_x < LOW_THRESHOLD && i_oldx > HIGH_THRESHOLD ) ) { - b_change = VLC_TRUE; + b_change = true; psz_filter = ""; psz_type = ""; } else if( i_x > HIGH_THRESHOLD && i_oldx < LOW_THRESHOLD ) { - b_change = VLC_TRUE; + b_change = true; psz_filter = "transform"; psz_type = "90"; } @@ -208,14 +254,17 @@ static void RunIntf( intf_thread_t *p_intf ) i_oldx = i_x; } } +#undef FILTER_LENGTH +#undef LOW_THRESHOLD +#undef HIGH_THRESHOLD /***************************************************************************** - * GetOrientation: get laptop orientation, range -180 / +180 + * GetOrientation: get laptop orientation, range -1800 / +1800 *****************************************************************************/ static int GetOrientation( intf_thread_t *p_intf ) { FILE *f; - int i_x, i_y; + int i_x, i_y, i_z = 0; switch( p_intf->p_sys->sensor ) { @@ -230,7 +279,7 @@ static int GetOrientation( intf_thread_t *p_intf ) fscanf( f, "(%d,%d)", &i_x, &i_y ); fclose( f ); - return i_x - p_intf->p_sys->i_calibrate; + return ( i_x - p_intf->p_sys->i_calibrate ) * 10; case AMS_SENSOR: f = fopen( "/sys/devices/ams/x", "r" ); @@ -242,8 +291,37 @@ static int GetOrientation( intf_thread_t *p_intf ) fscanf( f, "%d", &i_x); fclose( f ); - return - i_x * 3; /* FIXME: arbitrary */ + return - i_x * 30; /* FIXME: arbitrary */ + case APPLESMC_SENSOR: + f = fopen( "/sys/devices/applesmc.768/position", "r" ); + if( !f ) + { + return 0; + } + + i_x = i_y = i_z = 0; + fscanf( f, "(%d,%d,%d)", &i_x, &i_y, &i_z ); + fclose( f ); + + return ( i_x - p_intf->p_sys->i_calibrate ) * 10; + +#ifdef __APPLE__ + case UNIMOTION_SENSOR: + if( read_sms_raw( p_intf->p_sys->unimotion_hw, &i_x, &i_y, &i_z ) ) + { + double d_norm = sqrt( i_x*i_x+i_z*i_z ); + if( d_norm < 100 ) + return 0; + double d_x = i_x / d_norm; + if( i_z > 0 ) + return -asin(d_x)*3600/3.141; + else + return 3600 + asin(d_x)*3600/3.141; + } + else + return 0; +#endif default: return 0; }