History

Merging echoline's android and fbdev forks

Lorenzo Bivens committed 5 years ago

Commit 96209041 parent a130d4427 files · +2398 −0Browse files

Showing the changes to gui-android/cpp/devandroid.c (1 of 27 files). Show all

Unified · Split

gui-android/cpp/devandroid.c+248−0
@@ -0,0 +1,248 @@
1#include "u.h"
2#include "lib.h"
3#include "dat.h"
4#include "fns.h"
5#include "error.h"
6
7#include <android/log.h>
8#include <android/sensor.h>
9
10void show_notification(char *buf);
11void take_picture(int id);
12int num_cameras();
13
14int Ncameras = 0;
15
16uchar *cambuf = nil;
17int camlen;
18
19ASensorManager *sensorManager = NULL;
20
21enum
22{
23 Qdir = 0,
24 Qcam = 1,
25 Qaccel = 2,
26 Qcompass = 4,
27 Qnotification = 6,
28};
29#define QID(p, c, y) (((p)<<16) | ((c)<<4) | (y))
30
31static void androidinit(void);
32
33static void
34androidinit(void)
35{
36 sensorManager = ASensorManager_getInstance();
37
38 Ncameras = num_cameras();
39}
40
41static Chan*
42androidattach(char *param)
43{
44 Chan *c;
45
46 c = devattach('N', param);
47 c->qid.path = QID(0, 0, Qdir);
48 c->qid.type = QTDIR;
49 c->qid.vers = 0;
50
51 return c;
52}
53
54static int
55androidgen(Chan *c, char *n, Dirtab *d, int nd, int s, Dir *dp)
56{
57 Qid q;
58
59 if (s == DEVDOTDOT) {
60 mkqid(&q, Qdir, 0, QTDIR);
61 devdir(c, q, "#N", 0, eve, 0555, dp);
62 return 1;
63 }
64 if (s < Ncameras) {
65 sprintf(up->genbuf, "cam%d.jpg", s);
66 mkqid(&q, (s << 16) | Qcam, 0, QTFILE);
67 devdir(c, q, up->genbuf, 0, eve, 0444, dp);
68 return 1;
69 }
70 if (s == Ncameras) {
71 sprintf(up->genbuf, "accel");
72 mkqid(&q, Qaccel, 0, QTFILE);
73 devdir(c, q, up->genbuf, 0, eve, 0444, dp);
74 return 1;
75 }
76 if (s == (Ncameras+1)) {
77 sprintf(up->genbuf, "compass");
78 mkqid(&q, Qcompass, 0, QTFILE);
79 devdir(c, q, up->genbuf, 0, eve, 0444, dp);
80 return 1;
81 }
82 if (s == (Ncameras+2)) {
83 sprintf(up->genbuf, "notification");
84 mkqid(&q, Qnotification, 0, QTFILE);
85 devdir(c, q, up->genbuf, 0, eve, 0222, dp);
86 return 1;
87 }
88 return -1;
89}
90
91static Walkqid*
92androidwalk(Chan *c, Chan *nc, char **name, int nname)
93{
94 return devwalk(c, nc, name, nname, 0, 0, androidgen);
95}
96
97static int
98androidstat(Chan *c, uchar *db, int n)
99{
100 return devstat(c, db, n, 0, 0, androidgen);
101}
102
103static Chan*
104androidopen(Chan *c, int omode)
105{
106 p9_uvlong s;
107
108 c = devopen(c, omode, 0, 0, androidgen);
109
110 if (c->qid.path & Qcam) {
111 s = c->qid.path >> 16;
112 take_picture(s);
113 }
114 c->mode = openmode(omode);
115 c->flag |= COPEN;
116 c->offset = 0;
117 c->iounit = 8192;
118
119 return c;
120}
121
122static void
123androidclose(Chan *c)
124{
125 if (c->qid.path & Qcam && cambuf != nil) {
126 free(cambuf);
127 cambuf = nil;
128 }
129}
130
131static long
132androidread(Chan *c, void *v, long n, vlong off)
133{
134 char *a = v;
135 long l;
136 const ASensor *sensor;
137 ASensorEventQueue *queue = NULL;
138 ASensorEvent data;
139
140 switch((ulong)c->qid.path & 0xF) {
141 default:
142 error(Eperm);
143 return -1;
144
145 case Qcam:
146 while(cambuf == nil)
147 usleep(10 * 1000);
148
149 l = camlen - off;
150 if (l > n)
151 l = n;
152
153 if (l > 0)
154 memcpy(a, cambuf + off, l);
155
156 return l;
157 case Qaccel:
158 queue = ASensorManager_createEventQueue(sensorManager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), 1, NULL, NULL);
159 if (queue == NULL)
160 return 0;
161 sensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
162 if (sensor == NULL) {
163 ASensorManager_destroyEventQueue(sensorManager, queue);
164 return 0;
165 }
166 if (ASensorEventQueue_enableSensor(queue, sensor)) {
167 ASensorEventQueue_disableSensor(queue, sensor);
168 ASensorManager_destroyEventQueue(sensorManager, queue);
169 return 0;
170 }
171 l = 0;
172 if (ALooper_pollAll(1000, NULL, NULL, NULL) == 1) {
173 if (ASensorEventQueue_getEvents(queue, &data, 1)) {
174 l = snprint(a, n, "%11f %11f %11f\n", data.vector.x, data.vector.y, data.vector.z);
175 }
176 }
177 ASensorEventQueue_disableSensor(queue, sensor);
178 ASensorManager_destroyEventQueue(sensorManager, queue);
179 return l;
180 case Qcompass:
181 queue = ASensorManager_createEventQueue(sensorManager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), 1, NULL, NULL);
182 if (queue == NULL)
183 return 0;
184 sensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_MAGNETIC_FIELD);
185 if (sensor == NULL) {
186 ASensorManager_destroyEventQueue(sensorManager, queue);
187 return 0;
188 }
189 if (ASensorEventQueue_enableSensor(queue, sensor)) {
190 ASensorEventQueue_disableSensor(queue, sensor);
191 ASensorManager_destroyEventQueue(sensorManager, queue);
192 return 0;
193 }
194 l = 0;
195 if (ALooper_pollAll(1000, NULL, NULL, NULL) == 1) {
196 if (ASensorEventQueue_getEvents(queue, &data, 1)) {
197 l = snprint(a, n, "%11f %11f %11f\n", data.vector.x, data.vector.y, data.vector.z);
198 }
199 }
200 ASensorEventQueue_disableSensor(queue, sensor);
201 ASensorManager_destroyEventQueue(sensorManager, queue);
202 return l;
203 case Qdir:
204 return devdirread(c, a, n, 0, 0, androidgen);
205 }
206}
207
208static long
209androidwrite(Chan *c, void *vp, long n, vlong off)
210{
211 char *a = vp;
212 char *str;
213
214 switch((ulong)c->qid.path) {
215 case Qnotification:
216 str = malloc(n+1);
217 memcpy(str, a, n);
218 str[n] = '\0';
219 show_notification(str);
220 free(str);
221 return n;
222 default:
223 error(Eperm);
224 break;
225 }
226 return -1;
227}
228
229Dev androiddevtab = {
230 'N',
231 "android",
232
233 devreset,
234 androidinit,
235 devshutdown,
236 androidattach,
237 androidwalk,
238 androidstat,
239 androidopen,
240 devcreate,
241 androidclose,
242 androidread,
243 devbread,
244 androidwrite,
245 devbwrite,
246 devremove,
247 devwstat,
248};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t