talloc.c: Update to match current upstream ("likely" macro definitions)
[mplayer.git] / input / lirc.c
blobfec56f482822961776873cab299ad5ee8efe7f88
1 /*
2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "config.h"
21 #include <lirc/lirc_client.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/time.h>
28 #include <stdlib.h>
30 #include "mp_msg.h"
31 #include "help_mp.h"
32 #include "input.h"
34 static struct lirc_config *lirc_config;
35 char *lirc_configfile;
37 static char* cmd_buf = NULL;
39 int
40 mp_input_lirc_init(void) {
41 int lirc_sock;
43 mp_msg(MSGT_LIRC,MSGL_V,MSGTR_SettingUpLIRC);
44 if((lirc_sock=lirc_init("mplayer",1))==-1){
45 mp_msg(MSGT_LIRC,MSGL_ERR,MSGTR_LIRCopenfailed);
46 return -1;
49 if(lirc_readconfig( lirc_configfile,&lirc_config,NULL )!=0 ){
50 mp_msg(MSGT_LIRC,MSGL_ERR,MSGTR_LIRCcfgerr,
51 lirc_configfile == NULL ? "~/.lircrc" : lirc_configfile);
52 lirc_deinit();
53 return -1;
56 return lirc_sock;
59 int mp_input_lirc_read(int fd,char* dest, int s) {
60 fd_set fds;
61 struct timeval tv;
62 int r,cl = 0;
63 char *code = NULL,*c = NULL;
65 // We have something in the buffer return it
66 if(cmd_buf != NULL) {
67 int l = strlen(cmd_buf), w = l > s ? s : l;
68 memcpy(dest,cmd_buf,w);
69 l -= w;
70 if(l > 0)
71 memmove(cmd_buf,&cmd_buf[w],l+1);
72 else {
73 free(cmd_buf);
74 cmd_buf = NULL;
76 return w;
79 // Nothing in the buffer, pool the lirc fd
80 FD_ZERO(&fds);
81 FD_SET(fd,&fds);
82 memset(&tv,0,sizeof(tv));
83 while((r = select(fd+1,&fds,NULL,NULL,&tv)) <= 0) {
84 if(r < 0) {
85 if(errno == EINTR)
86 continue;
87 mp_msg(MSGT_INPUT,MSGL_ERR,"Select error : %s\n",strerror(errno));
88 return MP_INPUT_ERROR;
89 } else
90 return MP_INPUT_NOTHING;
93 // There's something to read
94 if(lirc_nextcode(&code) != 0) {
95 mp_msg(MSGT_INPUT,MSGL_ERR,"Lirc error :(\n");
96 return MP_INPUT_DEAD;
99 if(!code) return MP_INPUT_NOTHING;
101 // We put all cmds in a single buffer separated by \n
102 while((r = lirc_code2char(lirc_config,code,&c))==0 && c!=NULL) {
103 int l = strlen(c);
104 if(l <= 0)
105 continue;
106 cmd_buf = realloc(cmd_buf,cl+l+2);
107 memcpy(&cmd_buf[cl],c,l);
108 cl += l+1;
109 cmd_buf[cl-1] = '\n';
110 cmd_buf[cl] = '\0';
113 free(code);
115 if(r < 0)
116 return MP_INPUT_DEAD;
117 else if(cmd_buf) // return the first command in the buffer
118 return mp_input_lirc_read(fd,dest,s);
119 else
120 return MP_INPUT_RETRY;
124 void
125 mp_input_lirc_close(int fd) {
126 if(cmd_buf) {
127 free(cmd_buf);
128 cmd_buf = NULL;
130 lirc_freeconfig(lirc_config);
131 lirc_deinit();