X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcontrol%2Fmotion.c;h=0935d28f3d0d2343db496a9b15d9a66137b0db7a;hb=0820fb75f362afb97b6b11ece174c1e2f19abdd5;hp=25856e6b1cbda6f93531573511fd631a1a5b3c39;hpb=a06213d7f406c886dba790418ef8cca43d7ad140;p=vlc diff --git a/modules/control/motion.c b/modules/control/motion.c index 25856e6b1c..0935d28f3d 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,26 +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; - int i_last_x, i_calibrate; - int i_threshold; + bool b_use_rotate; }; /***************************************************************************** @@ -55,17 +69,25 @@ static void Close ( vlc_object_t * ); static void RunIntf( intf_thread_t *p_intf ); static int GetOrientation( intf_thread_t *p_intf ); +#define USE_ROTATE_TEXT N_("Use the rotate video filter instead of transform") + /***************************************************************************** * Module descriptor *****************************************************************************/ -vlc_module_begin(); - set_shortname( _("motion")); - set_category( CAT_INTERFACE ); - set_description( _("motion control interface") ); +vlc_module_begin () + set_shortname( N_("motion")) + set_category( CAT_INTERFACE ) + set_subcategory( SUBCAT_INTERFACE_CONTROL ) + 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", false, NULL, + USE_ROTATE_TEXT, USE_ROTATE_TEXT, false ) - set_capability( "interface", 0 ); - set_callbacks( Open, Close ); -vlc_module_end(); + set_capability( "interface", 0 ) + set_callbacks( Open, Close ) +vlc_module_end () /***************************************************************************** * OpenIntf: initialise interface @@ -104,6 +126,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 */ @@ -112,6 +156,9 @@ int Open ( vlc_object_t *p_this ) p_intf->pf_run = RunIntf; + p_intf->p_sys->b_use_rotate = + var_InheritInteger( p_intf, "motion-use-rotate" ); + return VLC_SUCCESS; } @@ -128,70 +175,97 @@ 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 ) ) + for( ;; ) { -#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 ); + int canc = vlc_savecancel(); 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 ) + { + /* 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 ); + } + } + goto loop; + } 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"; } - if( !b_change ) - { - continue; - } - - p_vout = (vout_thread_t *) - vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); - if( !p_vout ) + if( b_change ) { - continue; + p_vout = (vout_thread_t *) + vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); + if( p_vout ) + { + config_PutPsz( p_vout, "transform-type", psz_type ); + var_SetString( p_vout, "vout-filter", psz_filter ); + vlc_object_release( p_vout ); + + i_oldx = i_x; + } } - - config_PutPsz( p_vout, "transform-type", psz_type ); - var_SetString( p_vout, "vout-filter", psz_filter ); - vlc_object_release( p_vout ); - - i_oldx = i_x; +loop: + vlc_restorecancel( canc ); } } +#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 ) { @@ -206,7 +280,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" ); @@ -218,8 +292,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; }