some input framework attempt
[libpicofe.git] / common / input.c
CommitLineData
2258f158 1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "input.h"
6#include "../linux/event.h"
7
8typedef struct
9{
10 int drv_id;
11 void *drv_data;
12 int *binds;
13 char *name;
14 int probed:1;
15 int ignore:1;
16} in_dev_t;
17
18#define IN_MAX_DEVS 10
19
20static in_dev_t in_devices[IN_MAX_DEVS];
21static int in_dev_count = 0;
22
23static int in_bind_count(int drv_id)
24{
25 int count = 0;
26#ifdef IN_EVDEV
27 if (drv_id == IN_DRVID_EVDEV)
28 count = in_evdev_bind_count();
29#endif
30 if (count <= 0)
31 printf("input: failed to get bind count for drv %d\n", drv_id);
32
33 return count;
34}
35
36static int *in_alloc_binds(int drv_id)
37{
38 int count, *ret;
39
40 count = in_bind_count(drv_id);
41 if (count <= 0) {
42 printf("input: failed to get bind count for drv %d\n", drv_id);
43 return NULL;
44 }
45
46 ret = malloc(count * sizeof(*ret));
47 return ret;
48}
49
50static void in_free(in_dev_t *dev)
51{
52 if (dev->probed) {
53#ifdef IN_EVDEV
54 if (dev->drv_id == IN_DRVID_EVDEV)
55 in_evdev_free(dev->drv_data);
56#endif
57 }
58 dev->probed = 0;
59 dev->drv_data = NULL;
60 free(dev->name);
61 dev->name = NULL;
62 free(dev->binds);
63 dev->binds = NULL;
64}
65
66/* to be called by drivers */
67void in_register(const char *nname, int drv_id, void *drv_data)
68{
69 int i, dupe_count = 0, *binds;
70 char name[256], *name_end, *tmp;
71
72 strncpy(name, nname, sizeof(name));
73 name[sizeof(name)-12] = 0;
74 name_end = name + strlen(name);
75
76 for (i = 0; i < in_dev_count; i++)
77 {
78 if (in_devices[i].name == NULL)
79 continue;
80 if (strcmp(in_devices[i].name, name) == 0)
81 {
82 if (in_devices[i].probed) {
83 dupe_count++;
84 sprintf(name_end, " [%d]", dupe_count);
85 continue;
86 }
87 goto update;
88 }
89 }
90
91 if (i >= IN_MAX_DEVS)
92 {
93 /* try to find unused device */
94 for (i = 0; i < IN_MAX_DEVS; i++)
95 if (!in_devices[i].probed) break;
96 if (i >= IN_MAX_DEVS) {
97 printf("input: too many devices, can't add %s\n", name);
98 return;
99 }
100 in_free(&in_devices[i]);
101 }
102
103 tmp = strdup(name);
104 if (tmp == NULL)
105 return;
106
107 binds = in_alloc_binds(drv_id);
108 if (binds == NULL) {
109 free(tmp);
110 return;
111 }
112
113 in_devices[i].name = tmp;
114 in_devices[i].binds = binds;
115 if (i + 1 > in_dev_count)
116 in_dev_count = i + 1;
117
118 printf("input: new device #%d \"%s\"\n", i, name);
119update:
120 in_devices[i].probed = 1;
121 in_devices[i].drv_id = drv_id;
122 in_devices[i].drv_data = drv_data;
123}
124
125void in_probe(void)
126{
127 int i;
128 for (i = 0; i < in_dev_count; i++)
129 in_devices[i].probed = 0;
130
131#ifdef IN_EVDEV
132 in_evdev_probe();
133#endif
134
135 /* get rid of devs without binds and probes */
136 for (i = 0; i < in_dev_count; i++) {
137 if (!in_devices[i].probed && in_devices[i].binds == NULL) {
138 in_dev_count--;
139 if (i < in_dev_count) {
140 free(in_devices[i].name);
141 memmove(&in_devices[i], &in_devices[i+1],
142 (in_dev_count - i) * sizeof(in_devices[0]));
143 }
144 }
145 }
146}
147
148void in_clear_binds(const char *devname)
149{
150/* int count;
151
152 count = in_bind_count(drv_id);
153 if (count <= 0) {
154 printf("input: failed to get bind count for drv %d\n", dev->drv_id);
155 return NULL;
156 }
157*/
158}
159
160int in_update(void)
161{
162 int i, result = 0;
163
164 for (i = 0; i < in_dev_count; i++) {
165 if (in_devices[i].probed && in_devices[i].binds != NULL) {
166#ifdef IN_EVDEV
167 result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds);
168#endif
169 }
170 }
171
172 return result;
173}
174
175void in_init(void)
176{
177 memset(in_devices, 0, sizeof(in_devices));
178 in_dev_count = 0;
179}
180
181int main(void)
182{
183 in_init();
184 in_probe();
185
186 while (1) {
187 in_update();
188 sleep(1);
189 }
190
191 return 0;
192}
193