diff options
Diffstat (limited to 'firmware/target/hosted/android/dx50/button-dx50.c')
-rw-r--r-- | firmware/target/hosted/android/dx50/button-dx50.c | 316 |
1 files changed, 0 insertions, 316 deletions
diff --git a/firmware/target/hosted/android/dx50/button-dx50.c b/firmware/target/hosted/android/dx50/button-dx50.c deleted file mode 100644 index 250b448491..0000000000 --- a/firmware/target/hosted/android/dx50/button-dx50.c +++ /dev/null | |||
@@ -1,316 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (c) 2010 Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | |||
23 | #include <stdbool.h> | ||
24 | #include "button.h" | ||
25 | #include "buttonmap.h" | ||
26 | #include "config.h" | ||
27 | #include "kernel.h" | ||
28 | #include "system.h" | ||
29 | #include "touchscreen.h" | ||
30 | #include "powermgmt.h" | ||
31 | #include "backlight.h" | ||
32 | |||
33 | #include <linux/input.h> | ||
34 | #include <stdio.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <string.h> | ||
37 | #include <stdint.h> | ||
38 | #include <dirent.h> | ||
39 | #include <fcntl.h> | ||
40 | #include <sys/ioctl.h> | ||
41 | #include <sys/inotify.h> | ||
42 | #include <sys/limits.h> | ||
43 | #include <sys/poll.h> | ||
44 | #include <errno.h> | ||
45 | |||
46 | |||
47 | static struct pollfd *ufds; | ||
48 | static char **device_names; | ||
49 | static int nfds; | ||
50 | |||
51 | enum { | ||
52 | PRINT_DEVICE_ERRORS = 1U << 0, | ||
53 | PRINT_DEVICE = 1U << 1, | ||
54 | PRINT_DEVICE_NAME = 1U << 2, | ||
55 | PRINT_DEVICE_INFO = 1U << 3, | ||
56 | PRINT_VERSION = 1U << 4, | ||
57 | PRINT_POSSIBLE_EVENTS = 1U << 5, | ||
58 | PRINT_INPUT_PROPS = 1U << 6, | ||
59 | PRINT_HID_DESCRIPTOR = 1U << 7, | ||
60 | |||
61 | PRINT_ALL_INFO = (1U << 8) - 1, | ||
62 | |||
63 | PRINT_LABELS = 1U << 16, | ||
64 | }; | ||
65 | |||
66 | static int last_y, last_x; | ||
67 | static int last_btns; | ||
68 | |||
69 | static enum { | ||
70 | STATE_UNKNOWN, | ||
71 | STATE_UP, | ||
72 | STATE_DOWN | ||
73 | } last_touch_state = STATE_UNKNOWN; | ||
74 | |||
75 | |||
76 | static int open_device(const char *device, int print_flags) | ||
77 | { | ||
78 | int fd; | ||
79 | struct pollfd *new_ufds; | ||
80 | char **new_device_names; | ||
81 | |||
82 | fd = open(device, O_RDWR); | ||
83 | if(fd < 0) { | ||
84 | if(print_flags & PRINT_DEVICE_ERRORS) | ||
85 | fprintf(stderr, "could not open %s, %s\n", device, strerror(errno)); | ||
86 | return -1; | ||
87 | } | ||
88 | |||
89 | new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1)); | ||
90 | if(new_ufds == NULL) { | ||
91 | fprintf(stderr, "out of memory\n"); | ||
92 | close(fd); | ||
93 | return -1; | ||
94 | } | ||
95 | ufds = new_ufds; | ||
96 | new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1)); | ||
97 | if(new_device_names == NULL) { | ||
98 | fprintf(stderr, "out of memory\n"); | ||
99 | close(fd); | ||
100 | return -1; | ||
101 | } | ||
102 | device_names = new_device_names; | ||
103 | |||
104 | ufds[nfds].fd = fd; | ||
105 | ufds[nfds].events = POLLIN; | ||
106 | device_names[nfds] = strdup(device); | ||
107 | nfds++; | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | |||
113 | |||
114 | static int scan_dir(const char *dirname, int print_flags) | ||
115 | { | ||
116 | char devname[PATH_MAX]; | ||
117 | char *filename; | ||
118 | DIR *dir; | ||
119 | struct dirent *de; | ||
120 | dir = opendir(dirname); | ||
121 | if(dir == NULL) | ||
122 | return -1; | ||
123 | strcpy(devname, dirname); | ||
124 | filename = devname + strlen(devname); | ||
125 | *filename++ = '/'; | ||
126 | while((de = readdir(dir))) { | ||
127 | if(de->d_name[0] == '.' && | ||
128 | (de->d_name[1] == '\0' || | ||
129 | (de->d_name[1] == '.' && de->d_name[2] == '\0'))) | ||
130 | continue; | ||
131 | strcpy(filename, de->d_name); | ||
132 | open_device(devname, print_flags); | ||
133 | } | ||
134 | closedir(dir); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | bool _hold; | ||
139 | |||
140 | bool button_hold() | ||
141 | { | ||
142 | FILE *f = fopen("/sys/class/axppower/holdkey", "r"); | ||
143 | char x; | ||
144 | fscanf(f, "%c", &x); | ||
145 | fclose(f); | ||
146 | _hold = !(x&STATE_UNLOCKED); | ||
147 | return _hold; | ||
148 | } | ||
149 | |||
150 | |||
151 | void button_init_device(void) | ||
152 | { | ||
153 | int res; | ||
154 | int print_flags = 0; | ||
155 | const char *device = NULL; | ||
156 | const char *device_path = "/dev/input"; | ||
157 | |||
158 | nfds = 1; | ||
159 | ufds = calloc(1, sizeof(ufds[0])); | ||
160 | ufds[0].fd = inotify_init(); | ||
161 | ufds[0].events = POLLIN; | ||
162 | if(device) { | ||
163 | res = open_device(device, print_flags); | ||
164 | if(res < 0) { | ||
165 | // return 1; | ||
166 | } | ||
167 | } else { | ||
168 | res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); | ||
169 | if(res < 0) { | ||
170 | fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno)); | ||
171 | // return 1; | ||
172 | } | ||
173 | res = scan_dir(device_path, print_flags); | ||
174 | if(res < 0) { | ||
175 | fprintf(stderr, "scan dir failed for %s\n", device_path); | ||
176 | // return 1; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | button_hold(); //store state | ||
181 | |||
182 | set_rockbox_ready(); | ||
183 | } | ||
184 | |||
185 | void touchscreen_enable_device(bool en) | ||
186 | { | ||
187 | (void)en; /* FIXME: do something smart */ | ||
188 | } | ||
189 | |||
190 | |||
191 | int keycode_to_button(int keyboard_key) | ||
192 | { | ||
193 | switch(keyboard_key){ | ||
194 | case KEYCODE_PWR: | ||
195 | return BUTTON_POWER; | ||
196 | |||
197 | case KEYCODE_PWR_LONG: | ||
198 | return BUTTON_POWER_LONG; | ||
199 | |||
200 | case KEYCODE_VOLPLUS: | ||
201 | return BUTTON_VOL_UP; | ||
202 | |||
203 | case KEYCODE_VOLMINUS: | ||
204 | return BUTTON_VOL_DOWN; | ||
205 | |||
206 | case KEYCODE_PREV: | ||
207 | return BUTTON_LEFT; | ||
208 | |||
209 | case KEYCODE_NEXT: | ||
210 | return BUTTON_RIGHT; | ||
211 | |||
212 | case KEYCODE_PLAY: | ||
213 | return BUTTON_PLAY; | ||
214 | |||
215 | case KEYCODE_HOLD: | ||
216 | button_hold(); /* store state */ | ||
217 | backlight_hold_changed(_hold); | ||
218 | return BUTTON_NONE; | ||
219 | |||
220 | default: | ||
221 | return BUTTON_NONE; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | |||
226 | int button_read_device(int *data) | ||
227 | { | ||
228 | int i; | ||
229 | int res; | ||
230 | struct input_event event; | ||
231 | int read_more; | ||
232 | unsigned button = 0; | ||
233 | |||
234 | if(last_btns & BUTTON_POWER_LONG) | ||
235 | { | ||
236 | return last_btns; /* simulate repeat */ | ||
237 | } | ||
238 | |||
239 | do { | ||
240 | read_more = 0; | ||
241 | poll(ufds, nfds, 10); | ||
242 | for(i = 1; i < nfds; i++) { | ||
243 | if(ufds[i].revents & POLLIN) { | ||
244 | res = read(ufds[i].fd, &event, sizeof(event)); | ||
245 | if(res < (int)sizeof(event)) { | ||
246 | fprintf(stderr, "could not get event\n"); | ||
247 | } | ||
248 | |||
249 | switch(event.type) | ||
250 | { | ||
251 | case 1: /* HW-Button */ | ||
252 | button = keycode_to_button(event.code); | ||
253 | if (_hold) /* we have to wait for keycode_to_button() first to maybe clear hold state */ | ||
254 | break; | ||
255 | if (button == BUTTON_NONE) | ||
256 | { | ||
257 | last_btns = button; | ||
258 | break; | ||
259 | } | ||
260 | /* workaround for a wrong feedback, only present with DX90 */ | ||
261 | #if defined(DX90) | ||
262 | if (button == BUTTON_RIGHT && (last_btns & BUTTON_LEFT == BUTTON_LEFT) && !event.value) | ||
263 | { | ||
264 | button = BUTTON_LEFT; | ||
265 | } | ||
266 | #endif | ||
267 | if (event.value) | ||
268 | last_btns |= button; | ||
269 | else | ||
270 | last_btns &= (~button); | ||
271 | |||
272 | break; | ||
273 | |||
274 | case 3: /* Touchscreen */ | ||
275 | if(_hold) | ||
276 | break; | ||
277 | |||
278 | switch(event.code) | ||
279 | { | ||
280 | case 53: /* x -> next will be y */ | ||
281 | last_x = event.value; | ||
282 | read_more = 1; | ||
283 | break; | ||
284 | case 54: /* y */ | ||
285 | last_y = event.value; | ||
286 | break; | ||
287 | case 57: /* press -> next will be x */ | ||
288 | if(event.value==1) | ||
289 | { | ||
290 | last_touch_state = STATE_DOWN; | ||
291 | read_more = 1; | ||
292 | } | ||
293 | else | ||
294 | last_touch_state = STATE_UP; | ||
295 | break; | ||
296 | } | ||
297 | break; | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | } while(read_more); | ||
302 | |||
303 | |||
304 | /* Get grid button/coordinates based on the current touchscreen mode | ||
305 | * | ||
306 | * Caveat: the caller seemingly depends on *data always being filled with | ||
307 | * the last known touchscreen position, so always call | ||
308 | * touchscreen_to_pixels() */ | ||
309 | int touch = touchscreen_to_pixels(last_x, last_y, data); | ||
310 | |||
311 | if (last_touch_state == STATE_DOWN) | ||
312 | return last_btns | touch; | ||
313 | |||
314 | return last_btns; | ||
315 | } | ||
316 | |||