joystick.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:21k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * joystick.c: control vlc with a joystick
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 VideoLAN
  5.  * $Id: joystick.c 8338 2004-07-31 17:29:44Z sam $
  6.  *
  7.  * Authors: Cl閙ent Stenac <zorglub@via.ecp.fr>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>                                      /* malloc(), free() */
  27. #include <string.h>
  28. #include <unistd.h>
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <sys/select.h>
  32. #include <errno.h>
  33. #include <fcntl.h>
  34. #include <vlc/vlc.h>
  35. #include <vlc/intf.h>
  36. #include <vlc/vout.h>
  37. #include <linux/joystick.h>
  38. #include "audio_output.h"
  39. /* Default values for parameters */
  40. #define DEFAULT_MAX_SEEK        10 /* seconds */
  41. #define DEFAULT_REPEAT          100
  42. #define DEFAULT_WAIT            500
  43. #define DEFAULT_DEVICE          "/dev/input/js0"
  44. #define DEFAULT_THRESHOLD       12000  /* 0 -> 32767 */
  45. #define DEFAULT_MAPPING 
  46.     "{axis-0-up=forward,axis-0-down=back," 
  47.     "axis-1-up=next,axis-1-down=prev," 
  48.     "butt-1-down=play,butt-2-down=fullscreen}"
  49. /* Default Actions (used if there are missing actions in the default
  50.  * Available actions are: Next,Prev, Forward,Back,Play,Fullscreen,dummy */
  51. #define AXIS_0_UP_ACTION        Forward
  52. #define AXIS_0_DOWN_ACTION      Back
  53. #define AXIS_1_UP_ACTION        Next
  54. #define AXIS_1_DOWN_ACTION      Prev
  55. #define BUTTON_1_PRESS_ACTION   Play
  56. #define BUTTON_1_RELEASE_ACTION dummy
  57. #define BUTTON_2_PRESS_ACTION   Fullscreen
  58. #define BUTTON_2_RELEASE_ACTION dummy
  59. /*****************************************************************************
  60.  * intf_sys_t: description and status of interface
  61.  *****************************************************************************/
  62. typedef int (*action)(intf_thread_t *p_intf);
  63. struct joy_axis_t
  64. {
  65.     int         b_trigered;     /* Are we in the trigger zone ? */
  66.     int         i_value;        /* Value of movement */
  67.     int         b_dowork;       /* Do we have to do the action ? */
  68.     action      pf_actup;       /* Action when axis is up */
  69.     action      pf_actdown;     /* Action when axis is down */
  70.     mtime_t     l_time;         /* When did the axis enter the trigger
  71.                                  * zone ? */
  72. };
  73. struct joy_button_t
  74. {
  75.     action      pf_actup;  /* What to do when button is released */
  76.     action      pf_actdown;/* What to do when button is pressed */
  77. };
  78. struct intf_sys_t
  79. {
  80.     int                 i_fd;           /* File descriptor for joystick */
  81.     struct timeval      timeout;        /* Select timeout */
  82.     int                 i_threshold;    /* motion threshold */
  83.     int                 i_wait;         /* How much to wait before repeat */
  84.     int                 i_repeat;       /* Repeat time */
  85.     int                 i_maxseek;      /* Maximum seek time */
  86.     struct joy_axis_t   axes[3];        /* Axes descriptor */
  87.     struct joy_button_t buttons[2];     /* Buttons descriptor */
  88.     input_thread_t      *p_input;       /* Input thread (for seeking) */
  89.     float               f_seconds;      /* How much to seek */
  90. };
  91. /*****************************************************************************
  92.  * Local prototypes.
  93.  *****************************************************************************/
  94. static int  Open   ( vlc_object_t * );
  95. static void Close  ( vlc_object_t * );
  96. static int  Init   ( intf_thread_t *p_intf );
  97. static int handle_event   ( intf_thread_t *p_intf, struct js_event event );
  98. /* Actions */
  99. static int Next        (intf_thread_t *p_intf);
  100. static int Prev        (intf_thread_t *p_intf);
  101. static int Back        (intf_thread_t *p_intf);
  102. static int Forward     (intf_thread_t *p_intf);
  103. static int Play        (intf_thread_t *p_intf);
  104. static int Fullscreen  (intf_thread_t *p_intf);
  105. static int dummy       (intf_thread_t *p_intf);
  106. /* Exported functions */
  107. static void Run       ( intf_thread_t *p_intf );
  108. /*****************************************************************************
  109.  * Module descriptor
  110.  *****************************************************************************/
  111. #define THRESHOLD_TEXT N_( "Motion threshold" )
  112. #define THRESHOLD_LONGTEXT N_( 
  113.     "Amount of joystick movement required for a movement to be " 
  114.     "recorded (0->32767)." )
  115. #define DEVICE_TEXT N_( "Joystick device" )
  116. #define DEVICE_LONGTEXT N_( 
  117.     "The joystick device (usually /dev/js0 or /dev/input/js0).")
  118. #define REPEAT_TEXT N_( "Repeat time (ms)" )
  119. #define REPEAT_LONGTEXT N_( 
  120.     "Delay waited before the action is repeated if it is still " 
  121.     "triggered, in milliseconds." )
  122. #define WAIT_TEXT N_( "Wait time (ms)")
  123. #define WAIT_LONGTEXT N_(
  124.    "The time waited before the repeat starts, in milliseconds.")
  125. #define SEEK_TEXT N_( "Max seek interval (seconds)")
  126. #define SEEK_LONGTEXT N_(
  127.    "The maximum number of seconds that will be sought at a time." )
  128. #define MAP_TEXT N_( "Action mapping")
  129. #define MAP_LONGTEXT N_( "Allows you to remap the actions." )
  130. vlc_module_begin();
  131.     add_integer( "motion-threshold", DEFAULT_THRESHOLD, NULL,
  132.                      THRESHOLD_TEXT, THRESHOLD_LONGTEXT, VLC_TRUE );
  133.     add_string( "joystick-device", DEFAULT_DEVICE, NULL,
  134.                      DEVICE_TEXT, DEVICE_LONGTEXT, VLC_TRUE );
  135.     add_integer ("joystick-repeat", DEFAULT_REPEAT,NULL,
  136.                      REPEAT_TEXT, REPEAT_LONGTEXT, VLC_TRUE );
  137.     add_integer ("joystick-wait", DEFAULT_WAIT,NULL,
  138.                      WAIT_TEXT, WAIT_LONGTEXT, VLC_TRUE );
  139.     add_integer ("joystick-max-seek",DEFAULT_MAX_SEEK,NULL,
  140.                      SEEK_TEXT, SEEK_LONGTEXT, VLC_TRUE );
  141.     add_string("joystick-mapping",DEFAULT_MAPPING,NULL,
  142.                     MAP_TEXT,MAP_LONGTEXT, VLC_TRUE );
  143.     set_description( _("Joystick control interface") );
  144.     set_capability( "interface", 0 );
  145.     set_callbacks( Open, Close );
  146. vlc_module_end();
  147. /*****************************************************************************
  148.  * Open: initialize interface
  149.  *****************************************************************************/
  150. static int Open ( vlc_object_t *p_this )
  151. {
  152.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  153.     /* Allocate instance and initialize some members */
  154.     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
  155.     if( p_intf->p_sys == NULL )
  156.     {
  157.         return VLC_ENOMEM;
  158.     }
  159.     if( Init( p_intf ) < 0 )
  160.     {
  161.         msg_Err( p_intf, "cannot initialize interface" );
  162.         free( p_intf->p_sys );
  163.         return VLC_EGENERIC;
  164.     }
  165.     msg_Dbg( p_intf, "interface initialized" );
  166.     p_intf->pf_run = Run;
  167.     return VLC_SUCCESS;
  168. }
  169. /*****************************************************************************
  170.  * Close: destroy the interface
  171.  *****************************************************************************/
  172. static void Close ( vlc_object_t *p_this )
  173. {
  174.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  175.     /* Destroy structure */
  176.     if( p_intf->p_sys )
  177.     {
  178.         free( p_intf->p_sys );
  179.     }
  180. }
  181. /*****************************************************************************
  182.  * Run: main loop
  183.  *****************************************************************************/
  184. static void Run( intf_thread_t *p_intf )
  185. {
  186.     int i_sel_res = 0;
  187.     int i_read    = 0;
  188.     int i_axis     = 0;
  189.     struct js_event event;
  190.     /* Main loop */
  191.     while( !p_intf->b_die )
  192.     {
  193.         fd_set fds;
  194.  
  195.         vlc_mutex_lock( &p_intf->change_lock );
  196.         FD_ZERO( &fds );
  197.         FD_SET( p_intf->p_sys->i_fd, &fds );
  198.         p_intf->p_sys->timeout.tv_sec  = 0;
  199.         p_intf->p_sys->timeout.tv_usec = p_intf->p_sys->i_repeat;
  200.         i_sel_res = select( p_intf->p_sys->i_fd + 1, &fds,
  201.                             NULL, NULL, &p_intf->p_sys->timeout );
  202.         p_intf->p_sys->p_input = (input_thread_t *)
  203.            vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
  204.         if( i_sel_res == -1 && errno != EINTR )
  205.         {
  206.             msg_Err( p_intf, "select error: %s",strerror(errno) );
  207.         }
  208.         else if(i_sel_res > 0 && FD_ISSET( p_intf->p_sys->i_fd, &fds))
  209.         {
  210.             /* We got an event */
  211.             memset(&event,0,sizeof(struct js_event));
  212.             i_read = read( p_intf->p_sys->i_fd, &event,
  213.                                     sizeof(struct js_event));
  214.             handle_event( p_intf, event ) ;
  215.         }
  216.         else if(i_sel_res == 0)
  217.         {
  218.             /*We have no event, but check if we have an action to repeat */
  219.             for(i_axis = 0; i_axis <= 1; i_axis++)
  220.             {
  221.                 if( p_intf->p_sys->axes[i_axis].b_trigered &&
  222.                     mdate()-p_intf->p_sys->axes[i_axis].l_time >
  223.                         p_intf->p_sys->i_wait &&
  224.                     p_intf->p_sys->axes[i_axis].i_value > 0 )
  225.                 {
  226.                     p_intf->p_sys->axes[i_axis].pf_actup(p_intf);
  227.                 }
  228.                 if( p_intf->p_sys->axes[i_axis].b_trigered &&
  229.                     mdate()-p_intf->p_sys->axes[i_axis].l_time >
  230.                           p_intf->p_sys->i_wait &&
  231.                     p_intf->p_sys->axes[i_axis].i_value < 0 )
  232.                 {
  233.                     p_intf->p_sys->axes[i_axis].pf_actdown(p_intf);
  234.                 }
  235.             }
  236.         }
  237.         if(p_intf->p_sys->p_input)
  238.                 vlc_object_release (p_intf->p_sys->p_input);
  239.         vlc_mutex_unlock ( &p_intf->change_lock );
  240.     }
  241. }
  242. /*****************************************************************************
  243.  * InitThread: Initialize the interface
  244.  *****************************************************************************/
  245. static int Init( intf_thread_t * p_intf )
  246. {
  247.     char *psz_device;
  248.     char *psz_parse;
  249.     char *psz_eof;  /* end of field */
  250.     psz_device = config_GetPsz( p_intf, "joystick-device");
  251.     if( !psz_device ) /* strange... */
  252.     {
  253.         psz_device = strdup( DEFAULT_DEVICE );
  254.     }
  255.     p_intf->p_sys->i_fd = open( psz_device, O_RDONLY|O_NONBLOCK );
  256.     if( p_intf->p_sys->i_fd == -1 )
  257.     {
  258.         msg_Warn( p_intf, "unable to open %s for reading: %s",
  259.                           psz_device, strerror(errno) );
  260.         return VLC_EGENERIC;
  261.     }
  262.     p_intf->p_sys->i_repeat = 1000 * config_GetInt( p_intf, "joystick-repeat");
  263.     p_intf->p_sys->i_wait = 1000 * config_GetInt( p_intf, "joystick-wait");
  264.     p_intf->p_sys->i_threshold = config_GetInt( p_intf, "motion-threshold" );
  265.     if(p_intf->p_sys->i_threshold > 32767 || p_intf->p_sys->i_threshold < 0 )
  266.         p_intf->p_sys->i_threshold = DEFAULT_THRESHOLD;
  267.     p_intf->p_sys->i_maxseek = config_GetInt( p_intf, "joystick-max-seek" );
  268.     psz_parse = config_GetPsz( p_intf, "joystick-mapping" ) ;
  269.     if( ! psz_parse)
  270.     {
  271.         msg_Warn (p_intf,"invalid mapping. aborting" );
  272.         return VLC_EGENERIC;
  273.     }
  274.     if( !strlen( psz_parse ) )
  275.     {
  276.         msg_Warn( p_intf, "invalid mapping, aborting" );
  277.         return VLC_EGENERIC;
  278.     }
  279.     p_intf->p_sys->axes[0].pf_actup  = AXIS_0_UP_ACTION;
  280.     p_intf->p_sys->axes[0].pf_actdown  = AXIS_0_DOWN_ACTION;
  281.     p_intf->p_sys->axes[1].pf_actup  = AXIS_1_UP_ACTION;
  282.     p_intf->p_sys->axes[1].pf_actdown  = AXIS_1_DOWN_ACTION;
  283.     p_intf->p_sys->buttons[0].pf_actdown = BUTTON_1_PRESS_ACTION;
  284.     p_intf->p_sys->buttons[0].pf_actup   = BUTTON_1_RELEASE_ACTION;
  285.     p_intf->p_sys->buttons[1].pf_actdown = BUTTON_2_PRESS_ACTION;
  286.     p_intf->p_sys->buttons[1].pf_actup   = BUTTON_2_RELEASE_ACTION;
  287. /* Macro to parse the command line */
  288. #define PARSE(name,function)                                                  
  289.     if(!strncmp( psz_parse, name, strlen( name ) ) )                          
  290.     {                                                                         
  291.         psz_parse += strlen( name );                                          
  292.         psz_eof = strchr( psz_parse, ',' );                                   
  293.         if( !psz_eof)                                                         
  294.             psz_eof = strchr( psz_parse, '}' );                               
  295.         if( !psz_eof)                                                         
  296.             psz_eof = psz_parse + strlen(psz_parse);                          
  297.         if( psz_eof )                                                         
  298.         {                                                                     
  299.             *psz_eof = '' ;                                                 
  300.         }                                                                     
  301.         msg_Dbg(p_intf,"%s -> %s", name,psz_parse) ;                          
  302.         if(!strcasecmp( psz_parse, "play" ) ) function = Play;                
  303.         if(!strcasecmp( psz_parse, "next" ) ) function = Next;                
  304.         if(!strcasecmp( psz_parse, "prev" ) ) function = Prev;                
  305.         if(!strcasecmp( psz_parse, "fullscreen" ) ) function = Fullscreen;    
  306.         if(!strcasecmp( psz_parse, "forward" ) ) function = Forward;          
  307.         if(!strcasecmp( psz_parse, "back" ) ) function = Back;                
  308.         psz_parse = psz_eof;                                                  
  309.         psz_parse ++;                                                         
  310.         continue;                                                             
  311.     }                                                                         
  312.     for( ; *psz_parse ; psz_parse++ )
  313.     {
  314.         PARSE("axis-0-up=",   p_intf->p_sys->axes[0].pf_actup );
  315.         PARSE("axis-0-down=", p_intf->p_sys->axes[0].pf_actdown );
  316.         PARSE("axis-1-up=",   p_intf->p_sys->axes[1].pf_actup );
  317.         PARSE("axis-1-down=", p_intf->p_sys->axes[1].pf_actdown );
  318.         PARSE("butt-1-up=",   p_intf->p_sys->buttons[0].pf_actup );
  319.         PARSE("butt-1-down=", p_intf->p_sys->buttons[0].pf_actdown );
  320.         PARSE("butt-2-up=",   p_intf->p_sys->buttons[1].pf_actup );
  321.         PARSE("butt-2-down=", p_intf->p_sys->buttons[1].pf_actdown );
  322.     }
  323.     p_intf->p_sys->axes[0].b_trigered = VLC_FALSE;
  324.     p_intf->p_sys->axes[0].l_time = 0;
  325.     p_intf->p_sys->axes[1].b_trigered = VLC_FALSE;
  326.     p_intf->p_sys->axes[1].l_time = 0;
  327.     return VLC_SUCCESS;
  328. }
  329. /*****************************************************************************
  330.  * handle_event : parse a joystick event and takes the appropriate action    *
  331.  *****************************************************************************/
  332. static int handle_event ( intf_thread_t *p_intf, struct js_event event)
  333. {
  334.     unsigned int i_axis;
  335.     if( event.type == JS_EVENT_AXIS )
  336.     {
  337.         /* Third axis is supposed to behave in a different way: it is a
  338.          * throttle, and will set a value, without triggering anything */
  339.         if( event.number == 2 &&
  340.             /* Try to avoid Parkinson joysticks */
  341.             abs(event.value - p_intf->p_sys->axes[2].i_value) > 200 )
  342.         {
  343.             p_intf->p_sys->axes[2].i_value = event.value;
  344.             msg_Dbg( p_intf, "updating volume" );
  345.             /* This way, the volume is between 0 and 1024 */
  346.             aout_VolumeSet( p_intf, (32767-event.value)/64 );
  347.             return 0;
  348.         }
  349.         p_intf->p_sys->axes[event.number].b_dowork = VLC_FALSE;
  350.         p_intf->p_sys->axes[event.number].i_value  = event.value;
  351.         if( abs(event.value) > p_intf->p_sys->i_threshold &&
  352.              p_intf->p_sys->axes[event.number].b_trigered == VLC_FALSE )
  353.         {
  354.             /* The axis entered the trigger zone. Start the event */
  355.             p_intf->p_sys->axes[event.number].b_trigered = VLC_TRUE;
  356.             p_intf->p_sys->axes[event.number].b_dowork   = VLC_TRUE;
  357.             p_intf->p_sys->axes[event.number].l_time     = mdate();
  358.         }
  359.         else if( abs(event.value) > p_intf->p_sys->i_threshold &&
  360.                  p_intf->p_sys->axes[event.number].b_trigered == VLC_TRUE )
  361.         {
  362.             /* The axis moved but remained in the trigger zone
  363.              * Do nothing at this time */
  364.         }
  365.         else if( abs(event.value) < p_intf->p_sys->i_threshold )
  366.         {
  367.             /* The axis is not in the trigger zone */
  368.             p_intf->p_sys->axes[event.number].b_trigered = VLC_FALSE;
  369.         }
  370.         /* Special for seeking */
  371.         p_intf->p_sys->f_seconds = 1 +
  372.             (abs(event.value) - p_intf->p_sys->i_threshold) *
  373.             (p_intf->p_sys->i_maxseek - 1 ) /
  374.             (32767 - p_intf->p_sys->i_threshold);
  375.         /* Handle the first two axes. */
  376.         for(i_axis = 0; i_axis <= 1; i_axis ++)
  377.         {
  378.             if(p_intf->p_sys->axes[i_axis].b_dowork == VLC_TRUE)
  379.             {
  380.                 if( p_intf->p_sys->axes[i_axis].i_value
  381.                               > p_intf->p_sys->i_threshold )
  382.                 {
  383.                     msg_Dbg(p_intf,"up for axis %in",i_axis);
  384.                     p_intf->p_sys->axes[i_axis].pf_actup(p_intf);
  385.                 }
  386.                 else if( p_intf->p_sys->axes[i_axis].i_value
  387.                                 < -p_intf->p_sys->i_threshold )
  388.                 {
  389.                     msg_Dbg(p_intf,"down for axis %in",i_axis);
  390.                     p_intf->p_sys->axes[i_axis].pf_actdown(p_intf);
  391.                 }
  392.             }
  393.         }
  394.     }
  395.     else if( event.type == JS_EVENT_BUTTON )
  396.     {
  397.         msg_Dbg( p_intf, "button %i %s", event.number,
  398.                          event.value ? "pressed" : "released" );
  399.         if( event.number > 1 )
  400.             return 0; /* Only trigger 2 buttons */
  401.         if( event.value == 1 ) /* Button pressed */
  402.         {
  403.             if( p_intf->p_sys->buttons[event.number].pf_actdown )
  404.                 p_intf->p_sys->buttons[event.number].pf_actdown( p_intf );
  405.         }
  406.         else /* Button released */
  407.         {
  408.             if( p_intf->p_sys->buttons[event.number].pf_actup )
  409.                 p_intf->p_sys->buttons[event.number].pf_actup( p_intf );
  410.         }
  411.     }
  412.     return 0;
  413. }
  414. /****************************************************************************
  415.  * The actions
  416.  ****************************************************************************/
  417. /* Go to next item in the playlist */
  418. static int Next( intf_thread_t *p_intf )
  419. {
  420.     playlist_t *p_playlist;
  421.     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  422.     if( p_playlist == NULL )
  423.     {
  424.         return VLC_ENOOBJ;
  425.     }
  426.     playlist_Next( p_playlist );
  427.     vlc_object_release( p_playlist );
  428.     return VLC_SUCCESS;
  429. }
  430. /* Go to previous item in the playlist */
  431. static int Prev( intf_thread_t *p_intf )
  432. {
  433.     playlist_t *p_playlist;
  434.     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  435.     if( p_playlist == NULL )
  436.     {
  437.         return VLC_ENOOBJ;
  438.     }
  439.     playlist_Prev( p_playlist );
  440.     vlc_object_release( p_playlist );
  441.     return VLC_SUCCESS;
  442. }
  443. /* Seek forward */
  444. static int Forward( intf_thread_t *p_intf )
  445. {
  446.     if( p_intf->p_sys->p_input )
  447.     {
  448.         msg_Dbg( p_intf,"seeking %f seconds",p_intf->p_sys->f_seconds );
  449.         var_SetTime( p_intf->p_sys->p_input, "time-offset",
  450.                      (int64_t)p_intf->p_sys->f_seconds * I64C(1000000) );
  451.         return VLC_SUCCESS;
  452.     }
  453.     return VLC_ENOOBJ;
  454. }
  455. /* Seek backwards */
  456. static int Back( intf_thread_t *p_intf )
  457. {
  458.     if( p_intf->p_sys->p_input )
  459.     {
  460.         msg_Dbg( p_intf,"seeking -%f seconds", p_intf->p_sys->f_seconds );
  461.         var_SetTime( p_intf->p_sys->p_input, "time-offset",
  462.                      -(int64_t)p_intf->p_sys->f_seconds * I64C(1000000) );
  463.         return VLC_SUCCESS;
  464.     }
  465.     return VLC_ENOOBJ;
  466. }
  467. /* Toggle Play/Pause */
  468. static int Play( intf_thread_t *p_intf )
  469. {
  470.     if( p_intf->p_sys->p_input )
  471.     {
  472.         var_SetInteger( p_intf->p_sys->p_input, "state", PAUSE_S );
  473.         return VLC_SUCCESS;
  474.     }
  475.     return VLC_ENOOBJ;
  476. }
  477. /* Toggle fullscreen mode */
  478. static int Fullscreen( intf_thread_t *p_intf )
  479. {
  480.     vout_thread_t * p_vout;
  481.     p_vout = vlc_object_find(p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
  482.     if( p_vout )
  483.     {
  484.         p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
  485.         vlc_object_release(p_vout);
  486.     }
  487.     return VLC_SUCCESS;
  488. }
  489. /* dummy event. Use it if you don't wan't anything to happen */
  490. static int dummy( intf_thread_t *p_intf )
  491. {
  492.     return VLC_SUCCESS;
  493. }