]> git.sesse.net Git - vlc/blob - modules/control/lirc.c
contrib: growl: fix build
[vlc] / modules / control / lirc.c
1 /*****************************************************************************
2  * lirc.c : lirc module for vlc
3  *****************************************************************************
4  * Copyright (C) 2003-2005 the VideoLAN team
5  * $Id$
6  *
7  * Author: Sigmund Augdal Helberg <dnumgis@videolan.org>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27
28 #include <errno.h>
29 #include <fcntl.h>
30
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_interface.h>
38 #include <vlc_osd.h>
39 #include <vlc_keys.h>
40
41 #ifdef HAVE_POLL
42 # include <poll.h>
43 #endif
44
45 #include <lirc/lirc_client.h>
46
47 #define LIRC_TEXT N_("Change the lirc configuration file")
48 #define LIRC_LONGTEXT N_( \
49     "Tell lirc to read this configuration file. By default it " \
50     "searches in the users home directory." )
51
52 /*****************************************************************************
53  * Module descriptor
54  *****************************************************************************/
55 static int  Open    ( vlc_object_t * );
56 static void Close   ( vlc_object_t * );
57
58 vlc_module_begin ()
59     set_shortname( N_("Infrared") )
60     set_category( CAT_INTERFACE )
61     set_subcategory( SUBCAT_INTERFACE_CONTROL )
62     set_description( N_("Infrared remote control interface") )
63     set_capability( "interface", 0 )
64     set_callbacks( Open, Close )
65
66     add_string( "lirc-file", NULL,
67                 LIRC_TEXT, LIRC_LONGTEXT, true )
68 vlc_module_end ()
69
70 /*****************************************************************************
71  * intf_sys_t: description and status of FB interface
72  *****************************************************************************/
73 struct intf_sys_t
74 {
75     struct lirc_config *config;
76
77     int i_fd;
78 };
79
80 /*****************************************************************************
81  * Local prototypes
82  *****************************************************************************/
83 static void Run( intf_thread_t * );
84
85 static void Process( intf_thread_t * );
86
87 /*****************************************************************************
88  * Open: initialize interface
89  *****************************************************************************/
90 static int Open( vlc_object_t *p_this )
91 {
92     intf_thread_t *p_intf = (intf_thread_t *)p_this;
93     intf_sys_t *p_sys;
94     char *psz_file;
95
96     /* Allocate instance and initialize some members */
97     p_intf->p_sys = p_sys = malloc( sizeof( intf_sys_t ) );
98     if( p_sys == NULL )
99         return VLC_ENOMEM;
100
101     p_intf->pf_run = Run;
102
103     p_sys->i_fd = lirc_init( "vlc", 1 );
104     if( p_sys->i_fd == -1 )
105     {
106         msg_Err( p_intf, "lirc initialisation failed" );
107         goto exit;
108     }
109
110     /* We want polling */
111     fcntl( p_sys->i_fd, F_SETFL, fcntl( p_sys->i_fd, F_GETFL ) | O_NONBLOCK );
112
113     /* Read the configuration file */
114     psz_file = var_CreateGetNonEmptyString( p_intf, "lirc-file" );
115     if( lirc_readconfig( psz_file, &p_sys->config, NULL ) != 0 )
116     {
117         msg_Err( p_intf, "failure while reading lirc config" );
118         free( psz_file );
119         goto exit;
120     }
121     free( psz_file );
122
123     return VLC_SUCCESS;
124
125 exit:
126     if( p_sys->i_fd != -1 )
127         lirc_deinit();
128     free( p_sys );
129     return VLC_EGENERIC;
130 }
131
132 /*****************************************************************************
133  * Close: destroy interface
134  *****************************************************************************/
135 static void Close( vlc_object_t *p_this )
136 {
137     intf_thread_t *p_intf = (intf_thread_t *)p_this;
138     intf_sys_t *p_sys = p_intf->p_sys;
139
140     /* Destroy structure */
141     lirc_freeconfig( p_sys->config );
142     lirc_deinit();
143     free( p_sys );
144 }
145
146 /*****************************************************************************
147  * Run: main loop
148  *****************************************************************************/
149 static void Run( intf_thread_t *p_intf )
150 {
151     intf_sys_t *p_sys = p_intf->p_sys;
152
153     for( ;; )
154     {
155         /* Wait for data */
156         struct pollfd ufd = { .fd = p_sys->i_fd, .events = POLLIN, .revents = 0 };
157         if( poll( &ufd, 1, -1 ) == -1 )
158         {
159             if( errno == EINTR )
160                 continue;
161             else
162                 break;
163         }
164
165         /* Process */
166         int canc = vlc_savecancel();
167         Process( p_intf );
168         vlc_restorecancel(canc);
169     }
170 }
171
172 static void Process( intf_thread_t *p_intf )
173 {
174     for( ;; )
175     {
176         char *code, *c;
177         if( lirc_nextcode( &code ) )
178             return;
179
180         if( code == NULL )
181             return;
182
183         while( vlc_object_alive( p_intf )
184                 && (lirc_code2char( p_intf->p_sys->config, code, &c ) == 0)
185                 && (c != NULL) )
186         {
187             if( !strncmp( "key-", c, 4 ) )
188             {
189                 vlc_action_t i_key = vlc_GetActionId( c );
190                 if( i_key )
191                     var_SetInteger( p_intf->p_libvlc, "key-action", i_key );
192                 else
193                     msg_Err( p_intf, "Unknown hotkey '%s'", c );
194             }
195             else if( !strncmp( "menu ", c, 5)  )
196             {
197                 if( !strncmp( c, "menu on", 7 ) ||
198                     !strncmp( c, "menu show", 9 ))
199                     osd_MenuShow( VLC_OBJECT(p_intf) );
200                 else if( !strncmp( c, "menu off", 8 ) ||
201                          !strncmp( c, "menu hide", 9 ) )
202                     osd_MenuHide( VLC_OBJECT(p_intf) );
203                 else if( !strncmp( c, "menu up", 7 ) )
204                     osd_MenuUp( VLC_OBJECT(p_intf) );
205                 else if( !strncmp( c, "menu down", 9 ) )
206                     osd_MenuDown( VLC_OBJECT(p_intf) );
207                 else if( !strncmp( c, "menu left", 9 ) )
208                     osd_MenuPrev( VLC_OBJECT(p_intf) );
209                 else if( !strncmp( c, "menu right", 10 ) )
210                     osd_MenuNext( VLC_OBJECT(p_intf) );
211                 else if( !strncmp( c, "menu select", 11 ) )
212                     osd_MenuActivate( VLC_OBJECT(p_intf) );
213                 else
214                 {
215                     msg_Err( p_intf, "Please provide one of the following parameters:" );
216                     msg_Err( p_intf, "[on|off|up|down|left|right|select]" );
217                     break;
218                 }
219             }
220             else
221             {
222                 msg_Err( p_intf, "this doesn't appear to be a valid keycombo "
223                                  "lirc sent us. Please look at the "
224                                  "doc/lirc/example.lirc file in VLC" );
225                 break;
226             }
227         }
228         free( code );
229     }
230 }