1 /****************************************************************************
2 ** hw_devinput.c ***********************************************************
3 ****************************************************************************
5 * receive keycodes input via /dev/input/...
7 * Copyright (C) 2002 Oliver Endriss <o.endriss@gmx.de>
9 * Distribute under GPL version 2 or later.
16 - use more than 32 bits (?)
30 #include <sys/fcntl.h>
31 #include <sys/types.h>
35 #include <linux/input.h>
43 #include "ir_remote.h"
48 static int devinput_init();
49 static int devinput_deinit(void);
50 static int devinput_decode(struct ir_remote
*remote
,
51 ir_code
*prep
, ir_code
*codep
, ir_code
*postp
,
53 lirc_t
*min_remaining_gapp
,
54 lirc_t
*max_remaining_gapp
);
55 static char *devinput_rec(struct ir_remote
*remotes
);
62 struct hardware hw_devinput
=
64 "/dev/input/event0", /* "device" */
66 LIRC_CAN_REC_LIRCCODE
, /* features */
68 LIRC_MODE_LIRCCODE
, /* rec_mode */
70 devinput_init
, /* init_func */
71 NULL
, /* config_func */
72 devinput_deinit
, /* deinit_func */
74 devinput_rec
, /* rec_func */
75 devinput_decode
, /* decode_func */
76 NULL
, /* ioctl_func */
82 static int repeat_flag
=0;
86 static int do_match (const char *text
, const char *wild
)
92 const char *next
= text
;
96 if(do_match (next
, wild
))
104 else if (*wild
== '?')
107 if (!*text
++) return 0;
109 else if (*wild
== '\\')
115 if (wild
[1] != *text
++)
121 else if (*wild
++ != *text
++)
130 static int locate_dev (const char *pattern
, enum locate_type type
)
132 static char devname
[FILENAME_MAX
];
138 dir
= opendir ("/dev/input");
148 request
= EVIOCGNAME (sizeof (ioname
));
152 request
= EVIOCGPHYS (sizeof (ioname
));
160 while ((obj
= readdir (dir
)))
163 if (obj
->d_name
[0] == '.' &&
164 (obj
->d_name
[1] == 0 ||
165 (obj
->d_name
[1] == '.' && obj
->d_name
[2] == 0)))
167 continue; /* skip "." and ".." */
169 sprintf (devname
, "/dev/input/%s", obj
->d_name
);
170 fd
= open (devname
, O_RDONLY
);
175 if (ioctl (fd
, request
, ioname
) >= 0)
180 ioname
[sizeof(ioname
)-1] = 0;
181 //ret = !do_match (ioname, pattern);
182 ret
= fnmatch(pattern
, ioname
, 0);
199 logprintf(LOG_INFO
, "initializing '%s'", hw
.device
);
201 if (!strncmp (hw
.device
, "name=", 5)) {
202 if (locate_dev (hw
.device
+ 5, locate_by_name
)) {
203 logprintf(LOG_ERR
, "unable to find '%s'", hw
.device
);
207 else if (!strncmp (hw
.device
, "phys=", 5)) {
208 if (locate_dev (hw
.device
+ 5, locate_by_phys
)) {
209 logprintf(LOG_ERR
, "unable to find '%s'", hw
.device
);
214 if ((hw
.fd
= open(hw
.device
, O_RDONLY
)) < 0) {
215 logprintf(LOG_ERR
, "unable to open '%s'", hw
.device
);
220 if (ioctl(hw
.fd
, EVIOCGRAB
, 1) == -1)
222 logprintf(LOG_WARNING
, "can't get exclusive access to events "
223 "comming from `%s' interface",
232 int devinput_deinit(void)
234 logprintf(LOG_INFO
, "closing '%s'", hw
.device
);
241 int devinput_decode(struct ir_remote
*remote
,
242 ir_code
*prep
, ir_code
*codep
, ir_code
*postp
,
244 lirc_t
*min_remaining_gapp
,
245 lirc_t
*max_remaining_gapp
)
247 LOGPRINTF(1, "devinput_decode");
249 if(!map_code(remote
,prep
,codep
,postp
,
250 0,0,hw_devinput
.code_length
,code
,0,0))
255 *repeat_flagp
= repeat_flag
;
256 *min_remaining_gapp
= 0;
257 *max_remaining_gapp
= 0;
263 char *devinput_rec(struct ir_remote
*remotes
)
265 struct input_event event
;
269 LOGPRINTF(1, "devinput_rec");
271 rd
= read(hw
.fd
, &event
, sizeof event
);
272 if (rd
!= sizeof event
) {
273 logprintf(LOG_ERR
, "error reading '%s'", hw
.device
);
274 if(rd
<= 0 && errno
!= EINTR
) raise(SIGTERM
);
278 LOGPRINTF(1, "time %ld.%06ld type %d code %d value %d",
279 event
.time
.tv_sec
, event
.time
.tv_usec
,
280 event
.type
, event
.code
, event
.value
);
282 code
= (event
.type
== EV_KEY
&& event
.value
!= 0) ? 0x80000000 : 0;
283 code
|= ((event
.type
& 0x7fff) << 16);
286 repeat_flag
= (event
.type
== EV_KEY
&& event
.value
== 2) ? 1:0;
288 LOGPRINTF(1, "code %.8llx", code
);
291 if(event
.type
== EV_SYN
) return NULL
;
293 return decode_all(remotes
);