Added lirc.
[irreco.git] / lirc-0.8.4a / daemons / hw_silitek.c
blobeb69828ba0df257df68df50f9d1dc57ce80baa17
1 /****************************************************************************
2 ** hw_silitek.c ***********************************************************
3 ****************************************************************************
5 * routines for Silitek receiver
7 * Copyright (C) 1999 Christoph Bartelmus <lirc@bartelmus.de>
8 * modified for logitech receiver by Isaac Lauer <inl101@alumni.psu.edu>
9 * modified for silitek receiver by Krister Wicksell
10 * <krister.wicksell@spray.se>
11 * */
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <limits.h>
22 #include <signal.h>
23 #include <termios.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <sys/ioctl.h>
28 #include "hardware.h"
29 #include "serial.h"
30 #include "ir_remote.h"
31 #include "lircd.h"
32 #include "hw_silitek.h"
34 #define NUMBYTES 3
35 #define TIMEOUT 20000
37 extern struct ir_remote *repeat_remote, *last_remote;
39 unsigned char b[NUMBYTES];
40 ir_code code;
41 struct timeval current, last;
42 int do_repeat;
44 struct hardware hw_silitek=
46 LIRC_DRIVER_DEVICE, /* default device */
47 -1, /* fd */
48 LIRC_CAN_REC_LIRCCODE, /* features */
49 0, /* send_mode */
50 LIRC_MODE_LIRCCODE, /* rec_mode */
51 24, /* code_length */
52 silitek_init, /* init_func */
53 NULL, /* config_func */
54 silitek_deinit, /* deinit_func */
55 NULL, /* send_func */
56 silitek_rec, /* rec_func */
57 silitek_decode, /* decode_func */
58 NULL, /* ioctl_func */
59 NULL, /* readdata */
60 "silitek"
63 int silitek_read(int fd, unsigned char *data, long timeout) {
64 if(!waitfordata(timeout)) {
65 return(0);
68 if(!read(fd, data, 1)) {
69 return(0);
72 return(1);
75 int silitek_decode(struct ir_remote *remote,
76 ir_code *prep,ir_code *codep,ir_code *postp,
77 int *repeat_flagp,
78 lirc_t *min_remaining_gapp,
79 lirc_t *max_remaining_gapp)
81 if(!map_code(remote, prep, codep, postp, 0, 0, 24, code, 0, 0)) {
82 return(0);
85 map_gap(remote, &current, &last, 0, repeat_flagp,
86 min_remaining_gapp, max_remaining_gapp);
88 if(!do_repeat) *repeat_flagp = 0;
90 LOGPRINTF(1, "repeat_flagp: %d", *repeat_flagp);
92 return(1);
95 int silitek_init(void) {
96 if(!tty_create_lock(hw.device)) {
97 logprintf(LOG_ERR, "could not create lock files");
98 return(0);
101 if((hw.fd = open(hw.device, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
102 logprintf(LOG_ERR, "could not open %s", hw.device);
103 logperror(LOG_ERR, "silitek_init()");
104 tty_delete_lock();
105 return(0);
108 if(!tty_reset(hw.fd)) {
109 logprintf(LOG_ERR,"could not reset %s", hw.device);
110 silitek_deinit();
111 return(0);
114 if(!tty_setbaud(hw.fd, 1200)) {
115 logprintf(LOG_ERR,"could not set baud rate on %s", hw.device);
116 silitek_deinit();
117 return(0);
120 return(1);
123 int silitek_deinit(void) {
124 close(hw.fd);
125 tty_delete_lock();
126 return(1);
129 char *silitek_rec(struct ir_remote *remotes) {
130 char *m;
131 int mouse_x;
132 int mouse_y;
133 char sign = 0x00; /* store sign of mouse direction. */
134 char pos = 0x00; /* store mouse direction. */
136 do_repeat = 1;
138 if(!silitek_read(hw.fd, &b[0], TIMEOUT)) {
139 logprintf(LOG_ERR,"reading of byte 0 failed");
140 logperror(LOG_ERR,NULL);
141 return(NULL);
144 if((b[0] != 0x3f) && /* button down */
145 (b[0] != 0x31) && /* button still down */
146 (b[0] != 0x2a) && /* button up */
147 (b[0] != 0x7c) && /* mouse event */
148 (b[0] != 0x7f) && /* mouse event, l+r-mouse button down */
149 (b[0] != 0xfd) && /* mouse event, r-mouse button down */
150 (b[0] != 0xfe)) { /* mouse event, l-mouse button down */
151 return(NULL);
154 last = current;
156 if(!silitek_read(hw.fd, &b[1], TIMEOUT)) {
157 logprintf(LOG_ERR,"reading of byte 1 failed");
158 logperror(LOG_ERR,NULL);
159 return(NULL);
162 if(!silitek_read(hw.fd, &b[2], TIMEOUT)) {
163 logprintf(LOG_ERR,"reading of byte 2 failed");
164 logperror(LOG_ERR,NULL);
165 return(NULL);
168 /* mouse event ? */
169 if((b[0] == 0x7c) || (b[0] == 0x7f) || (b[0] == 0xfd) || (b[0] == 0xfe)) {
170 /* if mouse was not moved check mouse-button state. */
171 if((b[1] == 0x80) && (b[2] == 0x80)) {
172 switch(b[0]) {
173 case 0xfd:
174 b[1] = 0xa0; /* r-mouse button */
175 b[2] = 0xbb;
176 break;
177 case 0xfe:
178 b[1] = 0x0a; /* l-mouse button */
179 b[2] = 0xbb;
180 break;
181 case 0x7f:
182 b[1] = 0xaa; /* l+r-mouse button */
183 b[2] = 0xbb;
184 break;
187 else {
188 /* calc mouse x movement */
189 mouse_x = b[1] & 0x1f;
190 /* calc mouse y movement */
191 mouse_y = b[2] & 0x1f;
193 /* if the joystick is pulled to the left */
194 if((b[1] & 0x20) == 0x20) {
195 mouse_x = 32 - mouse_x;
196 sign |= 0x10;
199 /* if the joystick is pulled up */
200 if((b[2] & 0x20) == 0x20) {
201 mouse_y = 32 - mouse_y;
202 sign |= 0x01;
205 /* calc mouse direction */
206 if((mouse_x > 0) && (mouse_y == 0)) pos = 0x01;
207 if((mouse_x > mouse_y) && (mouse_y > 0)) pos = 0x02;
208 if((mouse_x == mouse_y) && (mouse_x > 0)) pos = 0x03;
209 if((mouse_y > mouse_x) && (mouse_x > 0)) pos = 0x04;
210 if((mouse_y > 0) && (mouse_x == 0)) pos = 0x05;
212 b[1] = sign;
213 b[2] = pos;
215 /* if only a small mouse movement don't set
216 repeat flag gets better control in lircmd
217 this way */
218 if((mouse_x < 4) && (mouse_y < 4)) {
219 do_repeat = 0;
222 b[0] = 0xaa; /* set to indicate mouse event */
224 else {
225 if(b[0] != 0x2a) {
226 b[0] = 0xbb; /* set to indicate button down event */
228 else {
229 b[0] = 0xcc; /* set to indicate button up event */
233 code = ((ir_code)b[0] << 16) + ((ir_code)b[1] << 8) + (ir_code)b[2];
234 gettimeofday(&current, NULL);
236 m = decode_all(remotes);
237 return(m);