1 /*****************************************************************************
2 * hotkeys.c: Hotkey handling for vlc
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: hotkeys.c,v 1.1 2003/10/26 12:46:55 sigmunau Exp $
7 * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
27 #include <stdlib.h> /* malloc(), free() */
36 #define BUFFER_SIZE 10
37 /*****************************************************************************
38 * intf_sys_t: description and status of FB interface
39 *****************************************************************************/
42 vlc_mutex_t change_lock; /* mutex to keep the callback
43 * and the main loop from
44 * stepping on each others
46 int p_keys[ BUFFER_SIZE ]; /* buffer that contains
48 int i_size; /* number of events in buffer */
49 input_thread_t * p_input; /* pointer to input */
50 vout_thread_t * p_vout; /* pointer to vout object */
53 /*****************************************************************************
55 *****************************************************************************/
56 static int Open ( vlc_object_t * );
57 static void Close ( vlc_object_t * );
58 static void Run ( intf_thread_t * );
59 static void Feedback( intf_thread_t *, char * );
60 static int GetKey ( intf_thread_t *);
61 static int KeyEvent( vlc_object_t *, char const *,
62 vlc_value_t, vlc_value_t, void * );
64 /*****************************************************************************
66 *****************************************************************************/
68 set_description( _("hotkey interface") );
69 set_capability( "interface", 0 );
70 set_callbacks( Open, Close );
73 /*****************************************************************************
74 * Open: initialize interface
75 *****************************************************************************/
76 static int Open( vlc_object_t *p_this )
78 intf_thread_t *p_intf = (intf_thread_t *)p_this;
80 /* Allocate instance and initialize some members */
81 p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
82 if( p_intf->p_sys == NULL )
84 msg_Err( p_intf, "out of memory" );
87 vlc_mutex_init( p_intf, &p_intf->p_sys->change_lock );
88 p_intf->p_sys->i_size = 0;
91 p_intf->p_sys->p_input = NULL;
92 p_intf->p_sys->p_vout = NULL;
93 var_AddCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
97 /*****************************************************************************
98 * Close: destroy interface
99 *****************************************************************************/
100 static void Close( vlc_object_t *p_this )
102 intf_thread_t *p_intf = (intf_thread_t *)p_this;
104 if( p_intf->p_sys->p_input )
106 vlc_object_release( p_intf->p_sys->p_input );
108 if( p_intf->p_sys->p_vout )
110 vlc_object_release( p_intf->p_sys->p_vout );
112 /* Destroy structure */
113 free( p_intf->p_sys );
116 /*****************************************************************************
118 *****************************************************************************/
119 static void Run( intf_thread_t *p_intf )
121 playlist_t *p_playlist;
122 input_thread_t *p_input;
123 vout_thread_t *p_vout = NULL;
124 int i_fullscreen = config_GetInt( p_intf, "fullscreen-key" );
125 int i_quit = config_GetInt( p_intf, "quit-key" );
126 int i_vol_up = config_GetInt( p_intf, "vol-up-key" );
127 int i_vol_down = config_GetInt( p_intf, "vol-down-key" );
128 int i_play_pause = config_GetInt( p_intf, "play-pause-key" );
129 int i_play = config_GetInt( p_intf, "play-key" );
130 int i_pause = config_GetInt( p_intf, "pause-key" );
131 int i_stop = config_GetInt( p_intf, "stop-key" );
132 int i_next = config_GetInt( p_intf, "next-key" );
133 int i_prev = config_GetInt( p_intf, "prev-key" );
134 int i_faster = config_GetInt( p_intf, "faster-key" );
135 int i_slower = config_GetInt( p_intf, "slower-key" );
138 while( !p_intf->b_die )
141 msleep( INTF_IDLE_SLEEP );
143 /* Update the input */
144 if( p_intf->p_sys->p_input == NULL )
146 p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
149 else if( p_intf->p_sys->p_input->b_dead )
151 vlc_object_release( p_intf->p_sys->p_input );
152 p_intf->p_sys->p_input = NULL;
154 p_input = p_intf->p_sys->p_input;
156 /* Update the vout */
159 p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
161 p_intf->p_sys->p_vout = p_vout;
163 else if( p_vout->b_die )
165 vlc_object_release( p_vout );
167 p_intf->p_sys->p_vout = NULL;
170 i_key = GetKey( p_intf );
173 /* No key pressed, sleep a bit more */
174 msleep( INTF_IDLE_SLEEP );
177 if( i_key == i_quit )
179 p_intf->p_vlc->b_die = VLC_TRUE;
180 Feedback( p_intf, _("Quit" ) );
183 if( i_key == i_vol_up )
185 audio_volume_t i_newvol;
187 aout_VolumeUp( p_intf, 1, &i_newvol );
188 sprintf( string, "Vol %%%d", i_newvol*100/AOUT_VOLUME_MAX );
189 Feedback( p_intf, string );
191 if( i_key == i_vol_down )
193 audio_volume_t i_newvol;
195 aout_VolumeDown( p_intf, 1, &i_newvol );
196 sprintf( string, "Vol %%%d", i_newvol*100/AOUT_VOLUME_MAX );
197 Feedback( p_intf, string );
201 if( i_key == i_fullscreen )
203 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
208 if( i_key == i_play )
210 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
214 vlc_mutex_lock( &p_playlist->object_lock );
215 if( p_playlist->i_size )
217 vlc_mutex_unlock( &p_playlist->object_lock );
218 playlist_Play( p_playlist );
219 vlc_object_release( p_playlist );
225 if( i_key == i_play_pause )
228 p_input->stream.control.i_status != PAUSE_S )
230 Feedback( p_intf, _( "Pause" ) );
231 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
235 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
239 vlc_mutex_lock( &p_playlist->object_lock );
240 if( p_playlist->i_size )
242 vlc_mutex_unlock( &p_playlist->object_lock );
243 Feedback( p_intf, _( "Play" ) );
244 playlist_Play( p_playlist );
245 vlc_object_release( p_playlist );
254 if( i_key == i_pause )
256 Feedback( p_intf, _( "Pause" ) );
257 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
259 else if( i_key == i_next )
261 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
265 playlist_Next( p_playlist );
266 vlc_object_release( p_playlist );
269 else if( i_key == i_prev )
271 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
275 playlist_Prev( p_playlist );
276 vlc_object_release( p_playlist );
279 else if( i_key == i_stop )
281 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
285 playlist_Stop( p_playlist );
286 vlc_object_release( p_playlist );
289 else if( i_key == i_faster )
291 input_SetStatus( p_input, INPUT_STATUS_FASTER );
293 else if( i_key == i_slower )
295 input_SetStatus( p_input, INPUT_STATUS_SLOWER );
302 static void Feedback( intf_thread_t *p_intf, char *psz_string )
304 if ( p_intf->p_sys->p_vout )
306 vout_ShowTextRelative( p_intf->p_sys->p_vout, psz_string, NULL,
307 OSD_ALIGN_TOP|OSD_ALIGN_RIGHT, 30,20,400000 );
311 static int GetKey ( intf_thread_t *p_intf)
313 vlc_mutex_lock( &p_intf->p_sys->change_lock );
314 if ( p_intf->p_sys->i_size == 0 )
316 vlc_mutex_unlock( &p_intf->p_sys->change_lock );
321 int i_return = p_intf->p_sys->p_keys[ 0 ];
323 p_intf->p_sys->i_size--;
324 for ( i = 0; i < BUFFER_SIZE - 1; i++)
326 p_intf->p_sys->p_keys[ i ] = p_intf->p_sys->p_keys[ i + 1 ];
328 vlc_mutex_unlock( &p_intf->p_sys->change_lock );
333 /*****************************************************************************
334 * KeyEvent: callback for keyboard events
335 *****************************************************************************/
336 static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
337 vlc_value_t oldval, vlc_value_t newval, void *p_data )
339 intf_thread_t *p_intf = (intf_thread_t *)p_data;
340 vlc_mutex_lock( &p_intf->p_sys->change_lock );
341 if ( p_intf->p_sys->i_size == BUFFER_SIZE )
343 msg_Warn( p_intf, "Event buffer full, dropping keypress" );
344 vlc_mutex_unlock( &p_intf->p_sys->change_lock );
349 p_intf->p_sys->p_keys[ p_intf->p_sys->i_size ] = newval.i_int;
350 p_intf->p_sys->i_size++;
352 vlc_mutex_unlock( &p_intf->p_sys->change_lock );