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 (3 of 27 files). Show all

Unified · Split

3 files
  1. gui-android/cpp/android.c +230 −0
  2. gui-android/cpp/devandroid.c +248 −0
  3. gui-android/cpp/native-lib.c +173 −0
gui-android/cpp/android.c+230−0
@@ -0,0 +1,230 @@
1#include <jni.h>
2#include <android/native_window.h>
3#include <android/log.h>
4
5#include "u.h"
6#include "lib.h"
7#include "dat.h"
8#include "fns.h"
9
10#include <draw.h>
11#include <memdraw.h>
12#include <keyboard.h>
13#include <cursor.h>
14#include "screen.h"
15
16Memimage *gscreen = nil;
17extern int screenWidth;
18extern int screenHeight;
19extern ANativeWindow *window;
20extern jobject mainActivityObj;
21extern JavaVM *jvm;
22
23char*
24clipread(void)
25{
26 char *ret;
27 const char *s;
28 JNIEnv *env;
29 jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
30 if (rs != JNI_OK) {
31 __android_log_print(ANDROID_LOG_WARN, "drawterm", "AttachCurrentThread returned error: %d", rs);
32 return strdup("");
33 }
34 jclass clazz = (*env)->GetObjectClass(env, mainActivityObj);
35 jmethodID methodID = (*env)->GetMethodID(env, clazz, "getClipBoard", "()Ljava/lang/String;");
36 jstring str = (jstring)(*env)->CallObjectMethod(env, mainActivityObj, methodID);
37 s = (*env)->GetStringUTFChars(env, str, NULL);
38 ret = strdup(s);
39 (*env)->ReleaseStringUTFChars(env, str, s);
40 (*jvm)->DetachCurrentThread(jvm);
41 return ret;
42}
43
44int
45clipwrite(char *buf)
46{
47 JNIEnv *env;
48 jint rs = (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6);
49 if(rs != JNI_OK) {
50 __android_log_print(ANDROID_LOG_WARN, "drawterm", "GetEnv returned error: %d", rs);
51 return 0;
52 }
53 jclass clazz = (*env)->GetObjectClass(env, mainActivityObj);
54 jmethodID methodID = (*env)->GetMethodID(env, clazz, "setClipBoard", "(Ljava/lang/String;)V");
55 jstring str = (*env)->NewStringUTF(env, buf);
56 (*env)->CallVoidMethod(env, mainActivityObj, methodID, str);
57 return 0;
58}
59
60void
61show_notification(char *buf)
62{
63 JNIEnv *env;
64 jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
65 if(rs != JNI_OK) {
66 __android_log_print(ANDROID_LOG_WARN, "drawterm", "AttachCurrentThread returned error: %d", rs);
67 return;
68 }
69 jclass clazz = (*env)->GetObjectClass(env, mainActivityObj);
70 jmethodID methodID = (*env)->GetMethodID(env, clazz, "showNotification", "(Ljava/lang/String;)V");
71 jstring str = (*env)->NewStringUTF(env, buf);
72 (*env)->CallVoidMethod(env, mainActivityObj, methodID, str);
73 (*jvm)->DetachCurrentThread(jvm);
74 return;
75}
76
77int
78num_cameras()
79{
80 JNIEnv *env;
81 int n;
82 jint rs = (*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6);
83 if(rs != JNI_OK) {
84 __android_log_print(ANDROID_LOG_WARN, "drawterm", "GetEnv returned error: %d", rs);
85 return 0;
86 }
87 jclass clazz = (*env)->GetObjectClass(env, mainActivityObj);
88 jmethodID methodID = (*env)->GetMethodID(env, clazz, "numCameras", "()I");
89 n = (*env)->CallIntMethod(env, mainActivityObj, methodID);
90 return n;
91}
92
93void
94take_picture(int id)
95{
96 JNIEnv *env;
97 jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
98 if(rs != JNI_OK) {
99 __android_log_print(ANDROID_LOG_WARN, "drawterm", "AttachCurrentThread returned error: %d", rs);
100 return;
101 }
102 jclass clazz = (*env)->GetObjectClass(env, mainActivityObj);
103 jmethodID methodID = (*env)->GetMethodID(env, clazz, "takePicture", "(I)V");
104 (*env)->CallVoidMethod(env, mainActivityObj, methodID, id);
105 (*jvm)->DetachCurrentThread(jvm);
106 return;
107}
108
109void
110setcolor(ulong i, ulong r, ulong g, ulong b)
111{
112 return;
113}
114
115void
116getcolor(ulong v, ulong *r, ulong *g, ulong *b)
117{
118 *r = (v>>16)&0xFF;
119 *g = (v>>8)&0xFF;
120 *b = v&0xFF;
121}
122
123void
124flushmemscreen(Rectangle r)
125{
126 ANativeWindow_Buffer buffer;
127 uint8_t *pixels;
128 int x, y, o, b;
129 ARect bounds;
130
131 if (window == NULL)
132 return;
133
134 memset(&buffer, 0, sizeof(buffer));
135
136 bounds.left = r.min.x;
137 bounds.top = r.min.y;
138 bounds.right = r.max.x;
139 bounds.bottom = r.max.y;
140
141 if (ANativeWindow_lock(window, &buffer, &bounds) != 0) {
142 __android_log_print(ANDROID_LOG_WARN, "drawterm", "Unable to lock window buffer");
143 return;
144 }
145
146 r.min.x = bounds.left;
147 r.min.y = bounds.top;
148 r.max.x = bounds.right;
149 r.max.y = bounds.bottom;
150
151 pixels = (uint8_t*)buffer.bits;
152 for (y = r.min.y; y < r.max.y; y++)
153 for (x = r.min.x; x < r.max.x; x++) {
154 o = (y * screenWidth + x) * 4;
155 b = (y * buffer.stride + x) * 4;
156 pixels[b+3] = 0xFF;
157 pixels[b+2] = gscreen->data->bdata[o+0];
158 pixels[b+1] = gscreen->data->bdata[o+1];
159 pixels[b+0] = gscreen->data->bdata[o+2];
160 }
161
162 if (ANativeWindow_unlockAndPost(window) != 0) {
163 __android_log_print(ANDROID_LOG_WARN, "drawterm", "Unable to unlock and post window buffer");
164 }
165 return;
166}
167
168void
169screeninit(void)
170{
171 Rectangle r = Rect(0,0,screenWidth,screenHeight);
172 memimageinit();
173 screensize(r, XRGB32);
174 if (gscreen == nil)
175 panic("screensize failed");
176 gscreen->clipr = r;
177 terminit();
178 qlock(&drawlock);
179 flushmemscreen(r);
180 qunlock(&drawlock);
181 return;
182}
183
184void
185screensize(Rectangle r, ulong chan)
186{
187 Memimage *mi;
188
189 mi = allocmemimage(r, chan);
190 if (mi == nil)
191 return;
192
193 if (gscreen != nil)
194 freememimage(gscreen);
195
196 gscreen = mi;
197 gscreen->clipr = ZR;
198}
199
200Memdata*
201attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen)
202{
203 *r = gscreen->clipr;
204 *depth = gscreen->depth;
205 *chan = gscreen->chan;
206 *width = gscreen->width;
207 *softscreen = 1;
208
209 gscreen->data->ref++;
210 return gscreen->data;
211}
212
213void
214setcursor(void)
215{
216 return;
217}
218
219void
220mouseset(Point xy)
221{
222 return;
223}
224
225void
226guimain(void)
227{
228 cpubody();
229}
230
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};
gui-android/cpp/native-lib.c+173−0
@@ -0,0 +1,173 @@
1#include <jni.h>
2#include <android/native_window.h>
3#include <android/native_window_jni.h>
4#include <android/log.h>
5#include "u.h"
6#include "lib.h"
7#include "dat.h"
8#include "fns.h"
9#include "error.h"
10#include <draw.h>
11#include <string.h>
12#include <keyboard.h>
13
14void absmousetrack(int, int, int, ulong);
15ulong ticks(void);
16int dt_main(int, char**);
17int screenWidth;
18int screenHeight;
19Point mousept = {0, 0};
20int buttons = 0;
21float ws = 1;
22float hs = 1;
23extern char *snarfbuf;
24int mPaused = 0;
25ANativeWindow *window = NULL;
26jobject mainActivityObj;
27JavaVM *jvm;
28void flushmemscreen(Rectangle r);
29extern uchar *cambuf;
30extern int camlen;
31
32JNIEXPORT void JNICALL
33Java_org_echoline_drawterm_MainActivity_setObject(
34 JNIEnv *env,
35 jobject obj) {
36 mainActivityObj = (*env)->NewGlobalRef(env, obj);
37 jint rs = (*env)->GetJavaVM(env, &jvm);
38 assert(rs == JNI_OK);
39}
40
41JNIEXPORT void JNICALL
42Java_org_echoline_drawterm_MainActivity_keyDown(
43 JNIEnv *env,
44 jobject obj,
45 jint c) {
46 kbdkey(c, 1);
47}
48
49JNIEXPORT void JNICALL
50Java_org_echoline_drawterm_MainActivity_keyUp(
51 JNIEnv *env,
52 jobject obj,
53 jint c) {
54 kbdkey(c, 0);
55}
56
57JNIEXPORT void JNICALL
58Java_org_echoline_drawterm_MainActivity_setPass(
59 JNIEnv *env,
60 jobject obj,
61 jstring str) {
62 setenv("PASS", (char*)(*env)->GetStringUTFChars(env, str, 0), 1);
63}
64
65JNIEXPORT void JNICALL
66Java_org_echoline_drawterm_MainActivity_setWidth(
67 JNIEnv *env,
68 jobject obj,
69 jint width) {
70 screenWidth = width;
71}
72
73JNIEXPORT void JNICALL
74Java_org_echoline_drawterm_MainActivity_setHeight(
75 JNIEnv *env,
76 jobject obj,
77 jint height) {
78 screenHeight = height;
79}
80
81JNIEXPORT void JNICALL
82Java_org_echoline_drawterm_MainActivity_setWidthScale(
83 JNIEnv *env,
84 jobject obj,
85 jfloat s) {
86 ws = s;
87}
88
89JNIEXPORT void JNICALL
90Java_org_echoline_drawterm_MainActivity_setHeightScale(
91 JNIEnv *env,
92 jobject obj,
93 jfloat s) {
94 hs = s;
95}
96
97JNIEXPORT jint JNICALL
98Java_org_echoline_drawterm_MainActivity_dtmain(
99 JNIEnv *env,
100 jobject obj,
101 jobjectArray argv) {
102 int i, ret;
103 char **args = (char **) malloc(((*env)->GetArrayLength(env, argv)+1) * sizeof(char *));
104
105 for (i = 0; i < (*env)->GetArrayLength(env, argv); i++) {
106 jobject str = (jobject) (*env)->GetObjectArrayElement(env, argv, i);
107 args[i] = strdup((char*)(*env)->GetStringUTFChars(env, (jstring)str, 0));
108 }
109 args[(*env)->GetArrayLength(env, argv)] = NULL;
110
111 ret = dt_main(i, args);
112
113 for (i = 0; args[i] != NULL; i++) {
114 free(args[i]);
115 }
116 free(args);
117
118 return ret;
119}
120
121JNIEXPORT void JNICALL
122Java_org_echoline_drawterm_MainActivity_setMouse(
123 JNIEnv *env,
124 jobject obj,
125 jintArray args) {
126 jboolean isCopy;
127 jint *data;
128 if ((*env)->GetArrayLength(env, args) < 3)
129 return;
130 data = (*env)->GetIntArrayElements(env, args, &isCopy);
131 mousept.x = (int)(data[0] / ws);
132 mousept.y = (int)(data[1] / hs);
133 buttons = data[2];
134 (*env)->ReleaseIntArrayElements(env, args, data, 0);
135 absmousetrack(mousept.x, mousept.y, buttons, ticks());
136}
137
138JNIEXPORT void JNICALL
139Java_org_echoline_drawterm_MainActivity_setDTSurface(
140 JNIEnv* jenv,
141 jobject obj,
142 jobject surface) {
143 if (surface != NULL) {
144 window = ANativeWindow_fromSurface(jenv, surface);
145 ANativeWindow_setBuffersGeometry(window, screenWidth, screenHeight,
146 AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM);
147 flushmemscreen(Rect(0, 0, screenWidth, screenHeight));
148 } else if (window != NULL) {
149 ANativeWindow_release(window);
150 window = NULL;
151 }
152}
153
154JNIEXPORT void JNICALL
155Java_org_echoline_drawterm_MainActivity_exitDT(
156 JNIEnv* jenv,
157 jobject obj) {
158 exit(0);
159}
160
161JNIEXPORT void JNICALL
162Java_org_echoline_drawterm_MainActivity_sendPicture(
163 JNIEnv* env,
164 jobject obj,
165 jbyteArray array) {
166 jint len = (*env)->GetArrayLength(env, array);
167 jbyte *bytes = (*env)->GetByteArrayElements(env, array, NULL);
168 camlen = len;
169 cambuf = malloc(camlen);
170 memcpy(cambuf, bytes, camlen);
171 (*env)->ReleaseByteArrayElements(env, array, bytes, 0);
172}
173

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