Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit 6dd58ca43c773133b28dee0112cd46de8d5c176a 0 parents
Patrick Jacques authored December 22, 2011
31  Android.mk
... ...
@@ -0,0 +1,31 @@
  1
+LOCAL_PATH := $(call my-dir)
  2
+include $(CLEAR_VARS)
  3
+
  4
+commands_recovery_local_path := $(LOCAL_PATH)
  5
+
  6
+ifeq ($(TARGET_ARCH),arm)
  7
+
  8
+LOCAL_SRC_FILES := \
  9
+	luksunlock.c \
  10
+
  11
+LOCAL_MODULE := luksunlock
  12
+
  13
+LOCAL_FORCE_STATIC_EXECUTABLE := true
  14
+
  15
+RECOVERY_API_VERSION := 2
  16
+LOCAL_CFLAGS += -DRECOVERY_API_VERSION=$(RECOVERY_API_VERSION) -Wall
  17
+
  18
+LOCAL_MODULE_TAGS := optional
  19
+
  20
+LOCAL_STATIC_LIBRARIES := libunz 
  21
+LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils
  22
+LOCAL_STATIC_LIBRARIES += libstdc++ libc libz 
  23
+
  24
+include $(BUILD_EXECUTABLE)
  25
+
  26
+include $(CLEAR_VARS)
  27
+
  28
+include $(commands_recovery_local_path)/minui/Android.mk
  29
+commands_recovery_local_path :=
  30
+
  31
+endif   # TARGET_ARCH == arm
BIN  luksunlock
Binary file not shown
311  luksunlock.c
... ...
@@ -0,0 +1,311 @@
  1
+#include <stdio.h>
  2
+#include <stdlib.h>
  3
+#include <pthread.h>
  4
+#include <string.h>
  5
+#include <unistd.h>
  6
+#include <fcntl.h>
  7
+#include <linux/input.h>
  8
+
  9
+#include "minui/minui.h"
  10
+
  11
+#define CRYPTSETUP		"/system/bin/cryptsetup"
  12
+
  13
+#define SDCARD_DEVICE		"/dev/block/mmcblk0p2"
  14
+#define DATA_DEVICE		"/dev/block/loop0"
  15
+
  16
+#define SDCARD_MAPPER_NAME	"encrypted-sdcard"
  17
+#define DATA_MAPPER_NAME	"encrypted-data"
  18
+
  19
+#define CHAR_WIDTH		10
  20
+#define CHAR_HEIGHT		18
  21
+
  22
+#define CHAR_START		0x20
  23
+#define CHAR_END		0x7E
  24
+
  25
+struct keymap {
  26
+	unsigned char key;
  27
+	int xpos;
  28
+	int ypos;
  29
+	int selected;
  30
+};
  31
+
  32
+struct keymap keys[CHAR_END - CHAR_START];
  33
+struct input_event keyqueue[2048];
  34
+
  35
+char passphrase[1024];
  36
+
  37
+pthread_mutex_t keymutex;
  38
+unsigned int sp = 0;
  39
+
  40
+gr_surface background;
  41
+int res, current = 0;
  42
+
  43
+char *escape_input(char *str) {
  44
+	size_t i, j = 0;
  45
+	char *new = malloc(sizeof(char) * (strlen(str) * 2 + 1));
  46
+
  47
+	for(i = 0; i < strlen(str); i++) {
  48
+		if(!(((str[i] >= 'A') && (str[i] <= 'Z')) ||
  49
+		((str[i] >= 'a') && (str[i] <= 'z')) ||
  50
+		((str[i] >= '0') && (str[i] <= '9')) )) {
  51
+			new[j] = '\\';
  52
+			j++;
  53
+		}
  54
+		new[j] = str[i];
  55
+		j++;
  56
+	}
  57
+	new[j] = '\0';
  58
+
  59
+	return new;
  60
+}
  61
+
  62
+void draw_keymap() {
  63
+	size_t i;
  64
+	char keybuf[2];
  65
+
  66
+	for(i = 0; i < (CHAR_END - CHAR_START); i++) {
  67
+		sprintf(keybuf, "%c", keys[i].key);
  68
+
  69
+		if(keys[i].selected == 1) {
  70
+			gr_color(255, 0, 0, 255);
  71
+			gr_fill(keys[i].xpos, keys[i].ypos - CHAR_HEIGHT, keys[i].xpos + CHAR_WIDTH, keys[i].ypos);
  72
+			gr_color(255, 255, 255, 255);
  73
+		}
  74
+		else
  75
+			gr_color(0, 0, 0, 255);
  76
+
  77
+		gr_text(keys[i].xpos, keys[i].ypos, keybuf);
  78
+	}
  79
+}
  80
+
  81
+static void *input_thread() {
  82
+	int rel_sum = 0;
  83
+
  84
+	for(;;) {
  85
+		struct  input_event ev;
  86
+
  87
+		do {
  88
+			ev_get(&ev, 0);
  89
+
  90
+			switch(ev.type) {
  91
+				case EV_SYN:
  92
+					continue;
  93
+				case EV_REL:
  94
+					rel_sum += ev.value;
  95
+					break;
  96
+
  97
+				default:
  98
+					rel_sum = 0;
  99
+			}
  100
+
  101
+			if(rel_sum > 4 || rel_sum < -4)
  102
+				break;
  103
+
  104
+		} while(ev.type != EV_KEY || ev.code > KEY_MAX);
  105
+
  106
+		rel_sum = 0;
  107
+
  108
+		// Add the key to the fifo
  109
+		pthread_mutex_lock(&keymutex);
  110
+		if(sp < (sizeof(keyqueue) / sizeof(struct input_event)))
  111
+			sp++;
  112
+
  113
+		keyqueue[sp] = ev;
  114
+		pthread_mutex_unlock(&keymutex);
  115
+	}
  116
+
  117
+	return 0;
  118
+}
  119
+
  120
+void ui_init(void) {
  121
+	gr_init();
  122
+	ev_init();
  123
+
  124
+	// Generate bitmap from /system/res/padlock.png ( you can change the path in minui/resources.c)
  125
+	res_create_surface("padlock", &background);
  126
+}
  127
+
  128
+void draw_screen() {
  129
+	// This probably only looks good in HTC Wildfire resolution
  130
+	int bgwidth, bgheight, bgxpos, bgypos, i, cols;
  131
+
  132
+	gr_color(0, 0, 0, 255);
  133
+	gr_fill(0, 0, gr_fb_width(), gr_fb_height());
  134
+
  135
+	bgwidth = gr_get_width(background);
  136
+	bgheight = gr_get_height(background);
  137
+	bgxpos = (gr_fb_width() - gr_get_width(background)) / 2;
  138
+	bgypos = (gr_fb_height() - gr_get_height(background)) / 2;
  139
+
  140
+	gr_blit(background, 0, 0, bgwidth, bgheight, bgxpos, bgypos);
  141
+
  142
+	gr_text(0, CHAR_HEIGHT, "Enter unlock phrase: ");
  143
+
  144
+	cols = gr_fb_width() / CHAR_WIDTH;
  145
+
  146
+	for(i = 0; i < (int) strlen(passphrase); i++) 
  147
+		gr_text(i * CHAR_WIDTH, CHAR_HEIGHT * 2, "*");
  148
+
  149
+	for(; i < cols - 1; i++)
  150
+		gr_text(i * CHAR_WIDTH, CHAR_HEIGHT * 2, "_");
  151
+
  152
+	gr_text(0, gr_fb_height() - CHAR_HEIGHT, "Press Volup to unlock");
  153
+	gr_text(0, gr_fb_height(), "Press Voldown to erase");
  154
+
  155
+	draw_keymap();
  156
+	gr_flip();
  157
+}
  158
+
  159
+void generate_keymap() {
  160
+	int xpos, ypos;
  161
+	char key;
  162
+	int i;
  163
+
  164
+	xpos = 0;
  165
+	ypos = CHAR_HEIGHT * 4;
  166
+
  167
+	for(i = 0, key = CHAR_START; key < CHAR_END; key++, i++, xpos += (CHAR_WIDTH * 3)) {
  168
+		if(xpos >= gr_fb_width() - CHAR_WIDTH) {
  169
+			ypos += CHAR_HEIGHT;
  170
+
  171
+			xpos = 0;
  172
+		}
  173
+
  174
+		keys[i].key = key;
  175
+		keys[i].xpos = xpos;
  176
+		keys[i].ypos = ypos;
  177
+		keys[i].selected = 0;
  178
+	}
  179
+
  180
+	keys[current].selected = 1;
  181
+}
  182
+
  183
+void unlock() {
  184
+	char buffer[2048];
  185
+	int fd, failed = 0;
  186
+
  187
+	gr_color(0, 0, 0, 255);
  188
+	gr_fill(0, 0, gr_fb_width(), gr_fb_height());
  189
+	gr_color(255, 255, 255, 255);
  190
+
  191
+	gr_text((gr_fb_width() / 2) - ((strlen("Unlocking...") / 2) * CHAR_WIDTH), gr_fb_height() / 2, "Unlocking...");
  192
+	gr_flip();
  193
+
  194
+	snprintf(buffer, sizeof(buffer) - 1, "echo %s | %s luksOpen %s %s", escape_input(passphrase), CRYPTSETUP, SDCARD_DEVICE, SDCARD_MAPPER_NAME);
  195
+	system(buffer);
  196
+
  197
+	snprintf(buffer, sizeof(buffer) - 1, "echo %s | %s luksOpen %s %s", escape_input(passphrase), CRYPTSETUP, DATA_DEVICE, DATA_MAPPER_NAME);
  198
+	system(buffer);
  199
+
  200
+	snprintf(buffer, sizeof(buffer) - 1, "/dev/mapper/%s", SDCARD_MAPPER_NAME);
  201
+	fd = open(buffer, 0);
  202
+	if(fd < 0)
  203
+		failed = 1;
  204
+
  205
+	snprintf(buffer, sizeof(buffer) - 1, "/dev/mapper/%s", DATA_MAPPER_NAME);
  206
+	fd = open(buffer, 0);
  207
+	if(fd < 0)
  208
+		failed = 1;
  209
+
  210
+	if(!failed) {
  211
+		gr_text((gr_fb_width() / 2) - ((strlen("Success!") / 2) * CHAR_WIDTH), gr_fb_height() / 2 + CHAR_HEIGHT, "Success!");
  212
+		gr_flip();
  213
+		exit(0);
  214
+	}
  215
+
  216
+	gr_text((gr_fb_width() / 2) - ((strlen("Failed!") / 2) * CHAR_WIDTH), gr_fb_height() / 2 + CHAR_HEIGHT, "Failed!");
  217
+	gr_flip();
  218
+
  219
+	sleep(2);
  220
+	passphrase[0] = '\0';
  221
+}
  222
+
  223
+void handle_key(struct input_event event) {
  224
+	int cols;
  225
+
  226
+	cols = gr_fb_width() / (CHAR_WIDTH * 3);
  227
+	keys[current].selected = 0;
  228
+
  229
+	// Joystick down or up
  230
+	if(event.type == EV_REL && event.code == 1) {
  231
+		if(event.value > 0) {
  232
+			if(current + cols < (CHAR_END - CHAR_START))
  233
+				current += cols;
  234
+		} else if(event.value < 0) {
  235
+			if(current - cols > 0)
  236
+				current -= cols;
  237
+		}
  238
+	}
  239
+
  240
+	// Joystick left or right
  241
+	if(event.type == EV_REL && event.code == 0) {
  242
+		if(event.value > 0 && current < (CHAR_END - CHAR_START) - 1)
  243
+				current++;
  244
+		else if(event.value < 0 && current > 0)
  245
+				current--;
  246
+	}
  247
+
  248
+	keys[current].selected = 1;
  249
+
  250
+	// Pressed joystick
  251
+	if(event.type == EV_KEY && event.value == 0 && event.code == BTN_MOUSE) {
  252
+		snprintf(passphrase, sizeof(passphrase) - 1, "%s%c", passphrase, keys[current].key);
  253
+	}
  254
+
  255
+	// Pressed vol down
  256
+	if(event.type == EV_KEY && event.code == KEY_VOLUMEDOWN)
  257
+		passphrase[strlen(passphrase) - 1] = '\0';
  258
+
  259
+	// Pressed vol up
  260
+	if(event.type == 1 && event.code == KEY_VOLUMEUP) {
  261
+		unlock();
  262
+	}
  263
+
  264
+	draw_screen();
  265
+}
  266
+
  267
+int main(int argc, char **argv, char **envp) {
  268
+	struct input_event event;
  269
+	pthread_t t;
  270
+	unsigned int i, key_up = 0;
  271
+
  272
+	ui_init();
  273
+	generate_keymap();
  274
+	draw_screen();
  275
+
  276
+	pthread_create(&t, NULL, input_thread, NULL);
  277
+	pthread_mutex_init(&keymutex, NULL);
  278
+
  279
+	for(;;) {
  280
+		pthread_mutex_lock(&keymutex);
  281
+
  282
+		if(sp > 0) {
  283
+			for(i = 0; i < sp; i++)
  284
+				keyqueue[i] = keyqueue[i + 1];
  285
+
  286
+			event = keyqueue[0];
  287
+			sp--;
  288
+
  289
+			pthread_mutex_unlock(&keymutex);
  290
+		} else {
  291
+			pthread_mutex_unlock(&keymutex);
  292
+			continue;
  293
+		}
  294
+
  295
+		switch(event.type) {
  296
+			case(EV_KEY):
  297
+				if(key_up == 1) {
  298
+					key_up = 0;
  299
+					break;
  300
+				}
  301
+				key_up = 1;
  302
+			case(EV_REL):
  303
+				handle_key(event);
  304
+				break;
  305
+			case(EV_SYN):
  306
+				break;
  307
+		}
  308
+	}
  309
+
  310
+	return 0;
  311
+}
12  minui/Android.mk
... ...
@@ -0,0 +1,12 @@
  1
+LOCAL_PATH := $(call my-dir)
  2
+include $(CLEAR_VARS)
  3
+
  4
+LOCAL_SRC_FILES := graphics.c events.c resources.c
  5
+
  6
+LOCAL_C_INCLUDES +=\
  7
+    external/libpng\
  8
+    external/zlib
  9
+
  10
+LOCAL_MODULE := libminui
  11
+
  12
+include $(BUILD_STATIC_LIBRARY)
82  minui/events.c
... ...
@@ -0,0 +1,82 @@
  1
+/*
  2
+ * Copyright (C) 2007 The Android Open Source Project
  3
+ *
  4
+ * Licensed under the Apache License, Version 2.0 (the "License");
  5
+ * you may not use this file except in compliance with the License.
  6
+ * You may obtain a copy of the License at
  7
+ *
  8
+ *      http://www.apache.org/licenses/LICENSE-2.0
  9
+ *
  10
+ * Unless required by applicable law or agreed to in writing, software
  11
+ * distributed under the License is distributed on an "AS IS" BASIS,
  12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13
+ * See the License for the specific language governing permissions and
  14
+ * limitations under the License.
  15
+ */
  16
+
  17
+#include <stdio.h>
  18
+#include <stdlib.h>
  19
+#include <fcntl.h>
  20
+#include <dirent.h>
  21
+#include <sys/poll.h>
  22
+
  23
+#include <linux/input.h>
  24
+
  25
+#include "minui.h"
  26
+
  27
+#define MAX_DEVICES 16
  28
+
  29
+static struct pollfd ev_fds[MAX_DEVICES];
  30
+static unsigned ev_count = 0;
  31
+
  32
+int ev_init(void)
  33
+{
  34
+    DIR *dir;
  35
+    struct dirent *de;
  36
+    int fd;
  37
+
  38
+    dir = opendir("/dev/input");
  39
+    if(dir != 0) {
  40
+        while((de = readdir(dir))) {
  41
+//            fprintf(stderr,"/dev/input/%s\n", de->d_name);
  42
+            if(strncmp(de->d_name,"event",5)) continue;
  43
+            fd = openat(dirfd(dir), de->d_name, O_RDONLY);
  44
+            if(fd < 0) continue;
  45
+
  46
+            ev_fds[ev_count].fd = fd;
  47
+            ev_fds[ev_count].events = POLLIN;
  48
+            ev_count++;
  49
+            if(ev_count == MAX_DEVICES) break;
  50
+        }
  51
+    }
  52
+
  53
+    return 0;
  54
+}
  55
+
  56
+void ev_exit(void)
  57
+{
  58
+    while (ev_count > 0) {
  59
+        close(ev_fds[--ev_count].fd);
  60
+    }
  61
+}
  62
+
  63
+int ev_get(struct input_event *ev, unsigned dont_wait)
  64
+{
  65
+    int r;
  66
+    unsigned n;
  67
+
  68
+    do {
  69
+        r = poll(ev_fds, ev_count, dont_wait ? 0 : -1);
  70
+
  71
+        if(r > 0) {
  72
+            for(n = 0; n < ev_count; n++) {
  73
+                if(ev_fds[n].revents & POLLIN) {
  74
+                    r = read(ev_fds[n].fd, ev, sizeof(*ev));
  75
+                    if(r == sizeof(*ev)) return 0;
  76
+                }
  77
+            }
  78
+        }
  79
+    } while(dont_wait == 0);
  80
+
  81
+    return -1;
  82
+}
214  minui/font_10x18.h
... ...
@@ -0,0 +1,214 @@
  1
+struct {
  2
+  unsigned width;
  3
+  unsigned height;
  4
+  unsigned cwidth;
  5
+  unsigned cheight;
  6
+  unsigned char rundata[];
  7
+} font = {
  8
+  .width = 960,
  9
+  .height = 18,
  10
+  .cwidth = 10,
  11
+  .cheight = 18,
  12
+  .rundata = {
  13
+0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x55,0x82,0x06,0x82,0x02,0x82,0x10,0x82,
  14
+0x11,0x83,0x08,0x82,0x0a,0x82,0x04,0x82,0x46,0x82,0x08,0x82,0x07,0x84,0x06,
  15
+0x84,0x0a,0x81,0x03,0x88,0x04,0x84,0x04,0x88,0x04,0x84,0x06,0x84,0x1e,0x81,
  16
+0x0e,0x81,0x0a,0x84,0x06,0x84,0x07,0x82,0x05,0x85,0x07,0x84,0x04,0x86,0x04,
  17
+0x88,0x02,0x88,0x04,0x84,0x04,0x82,0x04,0x82,0x02,0x88,0x05,0x86,0x01,0x82,
  18
+0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x84,0x04,
  19
+0x86,0x06,0x84,0x04,0x86,0x06,0x84,0x04,0x88,0x02,0x82,0x04,0x82,0x02,0x82,
  20
+0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,
  21
+0x88,0x03,0x86,0x0e,0x86,0x06,0x82,0x11,0x82,0x10,0x82,0x18,0x82,0x0f,0x84,
  22
+0x0d,0x82,0x1c,0x82,0x09,0x84,0x7f,0x16,0x84,0x05,0x82,0x05,0x84,0x07,0x83,
  23
+0x02,0x82,0x19,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x82,0x03,0x86,0x04,
  24
+0x83,0x02,0x82,0x03,0x82,0x01,0x82,0x07,0x82,0x09,0x82,0x06,0x82,0x3e,0x82,
  25
+0x04,0x84,0x06,0x83,0x06,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x03,
  26
+0x82,0x09,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,
  27
+0x1c,0x82,0x0e,0x82,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x05,0x84,0x04,
  28
+0x82,0x02,0x82,0x05,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,
  29
+0x09,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x04,
  30
+0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x03,0x82,0x02,0x82,
  31
+0x03,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02,
  32
+0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
  33
+0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x03,0x82,0x08,0x82,0x0c,
  34
+0x82,0x05,0x84,0x11,0x82,0x0f,0x82,0x18,0x82,0x0e,0x82,0x02,0x82,0x0c,0x82,
  35
+0x1c,0x82,0x0b,0x82,0x7f,0x15,0x82,0x08,0x82,0x08,0x82,0x05,0x82,0x01,0x82,
  36
+0x01,0x82,0x19,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x82,0x02,0x82,0x01,
  37
+0x82,0x01,0x82,0x02,0x82,0x01,0x82,0x01,0x82,0x03,0x82,0x01,0x82,0x07,0x82,
  38
+0x08,0x82,0x08,0x82,0x3d,0x82,0x03,0x82,0x02,0x82,0x04,0x84,0x05,0x82,0x04,
  39
+0x82,0x02,0x82,0x04,0x82,0x06,0x83,0x03,0x82,0x08,0x82,0x04,0x81,0x09,0x82,
  40
+0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x1a,0x82,0x10,0x82,0x06,0x82,0x04,
  41
+0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,
  42
+0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,
  43
+0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x83,
  44
+0x02,0x83,0x02,0x83,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,
  45
+0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,
  46
+0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x04,
  47
+0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x08,0x82,0x0c,0x82,0x04,0x82,0x02,0x82,
  48
+0x11,0x82,0x0e,0x82,0x18,0x82,0x0e,0x82,0x02,0x82,0x0c,0x82,0x0b,0x82,0x0b,
  49
+0x82,0x02,0x82,0x0b,0x82,0x4d,0x82,0x45,0x82,0x08,0x82,0x08,0x82,0x05,0x82,
  50
+0x02,0x83,0x1a,0x82,0x07,0x81,0x02,0x81,0x07,0x82,0x01,0x82,0x02,0x82,0x01,
  51
+0x82,0x05,0x82,0x01,0x84,0x04,0x82,0x01,0x82,0x07,0x82,0x08,0x82,0x08,0x82,
  52
+0x06,0x82,0x02,0x82,0x06,0x82,0x28,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x01,
  53
+0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x84,0x03,0x82,0x08,0x82,
  54
+0x0d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x19,0x82,0x12,0x82,0x05,
  55
+0x82,0x04,0x82,0x02,0x82,0x02,0x84,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,
  56
+0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x04,
  57
+0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x83,0x02,0x83,
  58
+0x02,0x84,0x02,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
  59
+0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x0b,0x82,0x05,0x82,0x04,0x82,0x02,0x82,
  60
+0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,
  61
+0x82,0x04,0x82,0x09,0x82,0x0b,0x82,0x03,0x82,0x04,0x82,0x20,0x82,0x18,0x82,
  62
+0x0e,0x82,0x10,0x82,0x0b,0x82,0x0b,0x82,0x02,0x82,0x0b,0x82,0x4d,0x82,0x45,
  63
+0x82,0x08,0x82,0x08,0x82,0x26,0x82,0x10,0x88,0x01,0x82,0x01,0x82,0x06,0x83,
  64
+0x01,0x82,0x04,0x84,0x08,0x81,0x08,0x82,0x0a,0x82,0x05,0x82,0x02,0x82,0x06,
  65
+0x82,0x28,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x08,0x82,0x04,0x82,
  66
+0x01,0x82,0x03,0x82,0x08,0x82,0x0d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,
  67
+0x82,0x18,0x82,0x06,0x88,0x06,0x82,0x04,0x82,0x04,0x82,0x02,0x82,0x01,0x85,
  68
+0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x04,0x82,0x02,
  69
+0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,
  70
+0x02,0x82,0x04,0x82,0x08,0x88,0x02,0x84,0x02,0x82,0x02,0x82,0x04,0x82,0x02,
  71
+0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x0b,0x82,
  72
+0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x04,0x84,0x06,
  73
+0x84,0x08,0x82,0x05,0x82,0x09,0x82,0x0b,0x82,0x2b,0x82,0x18,0x82,0x0e,0x82,
  74
+0x10,0x82,0x1c,0x82,0x0b,0x82,0x4d,0x82,0x45,0x82,0x08,0x82,0x08,0x82,0x26,
  75
+0x82,0x11,0x82,0x01,0x82,0x03,0x82,0x01,0x82,0x09,0x82,0x06,0x82,0x12,0x82,
  76
+0x0a,0x82,0x06,0x84,0x07,0x82,0x27,0x82,0x04,0x82,0x04,0x82,0x05,0x82,0x0b,
  77
+0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x01,0x83,0x04,0x82,0x01,0x83,
  78
+0x08,0x82,0x05,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x05,0x83,0x07,0x83,0x05,
  79
+0x82,0x16,0x82,0x08,0x82,0x03,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,
  80
+0x02,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,
  81
+0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,
  82
+0x08,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,
  83
+0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,
  84
+0x0a,0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,
  85
+0x82,0x04,0x84,0x06,0x84,0x08,0x82,0x05,0x82,0x0a,0x82,0x0a,0x82,0x23,0x85,
  86
+0x03,0x82,0x01,0x83,0x06,0x85,0x05,0x83,0x01,0x82,0x04,0x84,0x04,0x86,0x05,
  87
+0x85,0x01,0x81,0x02,0x82,0x01,0x83,0x05,0x84,0x09,0x84,0x02,0x82,0x03,0x82,
  88
+0x06,0x82,0x05,0x81,0x01,0x82,0x01,0x82,0x03,0x82,0x01,0x83,0x06,0x84,0x04,
  89
+0x82,0x01,0x83,0x06,0x83,0x01,0x82,0x02,0x82,0x01,0x84,0x04,0x86,0x03,0x86,
  90
+0x04,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
  91
+0x82,0x02,0x82,0x04,0x82,0x03,0x87,0x05,0x82,0x08,0x82,0x08,0x82,0x26,0x82,
  92
+0x11,0x82,0x01,0x82,0x04,0x86,0x07,0x82,0x05,0x83,0x12,0x82,0x0a,0x82,0x04,
  93
+0x88,0x02,0x88,0x0c,0x88,0x10,0x82,0x04,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,
  94
+0x06,0x83,0x04,0x82,0x03,0x82,0x03,0x83,0x02,0x82,0x03,0x83,0x02,0x82,0x07,
  95
+0x82,0x06,0x84,0x05,0x82,0x02,0x83,0x05,0x83,0x07,0x83,0x04,0x82,0x18,0x82,
  96
+0x06,0x82,0x04,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x86,0x04,
  97
+0x82,0x08,0x82,0x04,0x82,0x02,0x86,0x04,0x86,0x04,0x82,0x02,0x84,0x02,0x88,
  98
+0x05,0x82,0x0a,0x82,0x03,0x85,0x05,0x82,0x08,0x82,0x01,0x82,0x01,0x82,0x02,
  99
+0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,
  100
+0x04,0x82,0x02,0x82,0x03,0x82,0x05,0x84,0x07,0x82,0x05,0x82,0x04,0x82,0x03,
  101
+0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,0x82,0x05,0x82,0x08,0x82,0x08,0x82,
  102
+0x06,0x82,0x0a,0x82,0x0a,0x82,0x22,0x82,0x03,0x82,0x02,0x83,0x02,0x82,0x04,
  103
+0x82,0x03,0x82,0x03,0x82,0x02,0x83,0x03,0x82,0x02,0x82,0x05,0x82,0x06,0x82,
  104
+0x03,0x83,0x02,0x83,0x02,0x82,0x06,0x82,0x0b,0x82,0x02,0x82,0x02,0x82,0x07,
  105
+0x82,0x05,0x88,0x02,0x83,0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x82,
  106
+0x04,0x82,0x02,0x83,0x03,0x83,0x02,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,
  107
+0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,
  108
+0x03,0x82,0x04,0x82,0x08,0x82,0x02,0x84,0x09,0x82,0x09,0x84,0x23,0x82,0x11,
  109
+0x82,0x01,0x82,0x06,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x01,0x82,0x11,0x82,
  110
+0x0a,0x82,0x06,0x84,0x07,0x82,0x26,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x08,
  111
+0x83,0x09,0x82,0x03,0x82,0x03,0x82,0x09,0x82,0x02,0x82,0x04,0x82,0x05,0x82,
  112
+0x06,0x82,0x02,0x82,0x05,0x83,0x01,0x82,0x17,0x82,0x16,0x82,0x06,0x82,0x05,
  113
+0x82,0x01,0x82,0x01,0x82,0x02,0x88,0x02,0x82,0x03,0x82,0x03,0x82,0x08,0x82,
  114
+0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
  115
+0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x01,0x82,0x01,0x82,
  116
+0x02,0x82,0x02,0x84,0x02,0x82,0x04,0x82,0x02,0x86,0x04,0x82,0x04,0x82,0x02,
  117
+0x86,0x09,0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x82,
  118
+0x01,0x82,0x04,0x84,0x07,0x82,0x07,0x82,0x07,0x82,0x0b,0x82,0x09,0x82,0x27,
  119
+0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
  120
+0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,
  121
+0x82,0x01,0x82,0x08,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,
  122
+0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x07,
  123
+0x82,0x0a,0x82,0x06,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x04,0x82,
  124
+0x04,0x84,0x04,0x82,0x04,0x82,0x07,0x82,0x06,0x82,0x08,0x82,0x08,0x82,0x26,
  125
+0x82,0x0f,0x88,0x05,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x02,0x82,0x01,0x82,
  126
+0x0d,0x82,0x0a,0x82,0x05,0x82,0x02,0x82,0x06,0x82,0x26,0x82,0x05,0x82,0x04,
  127
+0x82,0x05,0x82,0x07,0x82,0x0c,0x82,0x02,0x88,0x08,0x82,0x02,0x82,0x04,0x82,
  128
+0x05,0x82,0x05,0x82,0x04,0x82,0x08,0x82,0x18,0x82,0x14,0x82,0x07,0x82,0x05,
  129
+0x82,0x01,0x84,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,
  130
+0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
  131
+0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x01,0x82,0x01,0x82,
  132
+0x02,0x82,0x02,0x84,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,
  133
+0x82,0x02,0x82,0x0a,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x82,
  134
+0x01,0x82,0x01,0x82,0x04,0x84,0x07,0x82,0x07,0x82,0x07,0x82,0x0b,0x82,0x09,
  135
+0x82,0x22,0x87,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x88,
  136
+0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,
  137
+0x84,0x09,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,
  138
+0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x08,0x86,0x05,
  139
+0x82,0x06,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,0x82,
  140
+0x05,0x82,0x05,0x82,0x04,0x82,0x06,0x82,0x07,0x82,0x08,0x82,0x08,0x82,0x26,
  141
+0x82,0x10,0x82,0x01,0x82,0x07,0x82,0x01,0x82,0x04,0x82,0x01,0x83,0x02,0x82,
  142
+0x03,0x83,0x0f,0x82,0x08,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x25,0x82,0x07,
  143
+0x82,0x02,0x82,0x06,0x82,0x06,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x09,0x82,
  144
+0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x04,0x82,0x08,0x82,0x19,0x82,0x05,
  145
+0x88,0x05,0x82,0x08,0x82,0x05,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x02,0x82,
  146
+0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,
  147
+0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x03,0x82,0x03,0x82,0x03,0x82,
  148
+0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02,
  149
+0x82,0x08,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x03,0x82,0x09,0x82,0x05,0x82,
  150
+0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x83,0x02,0x83,0x03,0x82,0x02,0x82,0x06,
  151
+0x82,0x06,0x82,0x08,0x82,0x0c,0x82,0x08,0x82,0x21,0x82,0x04,0x82,0x02,0x82,
  152
+0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,0x82,0x06,0x82,0x03,
  153
+0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x85,0x08,0x82,0x05,0x82,
  154
+0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
  155
+0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0d,0x82,0x04,0x82,0x06,0x82,0x04,0x82,
  156
+0x04,0x84,0x04,0x82,0x01,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x05,
  157
+0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x38,0x82,0x01,0x82,0x04,0x82,0x01,0x82,
  158
+0x01,0x82,0x04,0x84,0x01,0x82,0x01,0x82,0x03,0x82,0x10,0x82,0x08,0x82,0x30,
  159
+0x83,0x06,0x82,0x07,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x08,0x82,0x04,0x82,
  160
+0x07,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x04,
  161
+0x82,0x03,0x81,0x04,0x82,0x1a,0x82,0x10,0x82,0x10,0x82,0x08,0x82,0x04,0x82,
  162
+0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,
  163
+0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x03,0x82,
  164
+0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,
  165
+0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x02,0x84,0x02,0x82,0x03,0x82,0x03,0x82,
  166
+0x04,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x05,0x83,0x02,0x83,0x03,
  167
+0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x09,0x82,0x0c,0x82,0x08,0x82,0x21,0x82,
  168
+0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,
  169
+0x82,0x07,0x85,0x04,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x82,0x02,0x82,
  170
+0x07,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
  171
+0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0d,0x82,0x04,0x82,
  172
+0x06,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x82,0x01,0x82,0x04,0x84,0x04,
  173
+0x82,0x04,0x82,0x04,0x82,0x09,0x82,0x08,0x82,0x08,0x82,0x26,0x82,0x10,0x82,
  174
+0x01,0x82,0x05,0x86,0x04,0x82,0x01,0x82,0x01,0x82,0x01,0x83,0x01,0x84,0x10,
  175
+0x82,0x06,0x82,0x1d,0x83,0x11,0x83,0x05,0x82,0x09,0x84,0x07,0x82,0x05,0x82,
  176
+0x09,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
  177
+0x82,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x06,0x83,0x07,0x83,0x09,0x82,
  178
+0x0e,0x82,0x0a,0x82,0x06,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x03,
  179
+0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x09,0x82,
  180
+0x02,0x83,0x02,0x82,0x04,0x82,0x05,0x82,0x06,0x82,0x01,0x82,0x04,0x82,0x04,
  181
+0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,
  182
+0x03,0x82,0x09,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x06,
  183
+0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
  184
+0x05,0x82,0x05,0x82,0x09,0x82,0x0d,0x82,0x07,0x82,0x21,0x82,0x04,0x82,0x02,
  185
+0x83,0x02,0x82,0x04,0x82,0x03,0x82,0x03,0x82,0x02,0x83,0x03,0x82,0x03,0x82,
  186
+0x04,0x82,0x06,0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x82,0x03,
  187
+0x82,0x06,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x03,0x82,
  188
+0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x07,0x82,0x04,
  189
+0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x02,0x83,0x05,0x82,0x05,0x88,0x03,0x82,
  190
+0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x0a,0x82,0x08,0x82,0x08,0x82,0x26,
  191
+0x82,0x1c,0x82,0x06,0x82,0x02,0x83,0x03,0x84,0x02,0x82,0x10,0x82,0x04,0x82,
  192
+0x1e,0x83,0x11,0x83,0x05,0x82,0x0a,0x82,0x05,0x88,0x02,0x88,0x04,0x84,0x09,
  193
+0x82,0x05,0x84,0x06,0x84,0x05,0x82,0x09,0x84,0x06,0x84,0x07,0x83,0x07,0x83,
  194
+0x0a,0x81,0x0e,0x81,0x0b,0x82,0x07,0x85,0x03,0x82,0x04,0x82,0x02,0x86,0x06,
  195
+0x84,0x04,0x86,0x04,0x88,0x02,0x82,0x0a,0x84,0x01,0x81,0x02,0x82,0x04,0x82,
  196
+0x02,0x88,0x04,0x83,0x05,0x82,0x04,0x82,0x02,0x88,0x02,0x82,0x04,0x82,0x02,
  197
+0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x0a,0x85,0x03,0x82,0x04,0x82,0x04,0x84,
  198
+0x07,0x82,0x07,0x84,0x07,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
  199
+0x82,0x05,0x88,0x03,0x86,0x09,0x82,0x03,0x86,0x22,0x85,0x01,0x81,0x02,0x82,
  200
+0x01,0x83,0x06,0x85,0x05,0x83,0x01,0x82,0x04,0x85,0x05,0x82,0x07,0x86,0x03,
  201
+0x82,0x04,0x82,0x02,0x88,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x88,0x02,0x82,
  202
+0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x83,0x06,
  203
+0x83,0x01,0x82,0x03,0x82,0x08,0x86,0x06,0x84,0x05,0x83,0x01,0x82,0x05,0x82,
  204
+0x06,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x04,0x83,0x01,0x82,0x03,0x87,0x06,
  205
+0x84,0x05,0x82,0x05,0x84,0x7f,0x15,0x83,0x7f,0x14,0x83,0x7f,0x5e,0x82,0x7f,
  206
+0x05,0x89,0x47,0x82,0x04,0x82,0x17,0x82,0x03,0x82,0x34,0x82,0x0e,0x82,0x4e,
  207
+0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0a,0x82,0x04,0x82,0x17,0x82,0x03,0x82,
  208
+0x34,0x82,0x0e,0x82,0x48,0x82,0x04,0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0a,
  209
+0x82,0x04,0x82,0x17,0x82,0x03,0x82,0x34,0x82,0x0e,0x82,0x49,0x82,0x02,0x82,
  210
+0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0c,0x86,0x19,0x85,0x35,0x82,0x0e,0x82,0x4a,
  211
+0x84,0x3f,
  212
+0x00,
  213
+  }
  214
+};
313  minui/graphics.c
... ...
@@ -0,0 +1,313 @@
  1
+/*
  2
+ * Copyright (C) 2007 The Android Open Source Project
  3
+ *
  4
+ * Licensed under the Apache License, Version 2.0 (the "License");
  5
+ * you may not use this file except in compliance with the License.
  6
+ * You may obtain a copy of the License at
  7
+ *
  8
+ *      http://www.apache.org/licenses/LICENSE-2.0
  9
+ *
  10
+ * Unless required by applicable law or agreed to in writing, software
  11
+ * distributed under the License is distributed on an "AS IS" BASIS,
  12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13
+ * See the License for the specific language governing permissions and
  14
+ * limitations under the License.
  15
+ */
  16
+
  17
+#include <stdlib.h>
  18
+#include <unistd.h>
  19
+
  20
+#include <fcntl.h>
  21
+#include <stdio.h>
  22
+
  23
+#include <sys/ioctl.h>
  24
+#include <sys/mman.h>
  25
+#include <sys/types.h>
  26
+
  27
+#include <linux/fb.h>
  28
+#include <linux/kd.h>
  29
+
  30
+#include <pixelflinger/pixelflinger.h>
  31
+
  32
+#include "font_10x18.h"
  33
+#include "minui.h"
  34
+
  35
+typedef struct {
  36
+    GGLSurface texture;
  37
+    unsigned cwidth;
  38
+    unsigned cheight;
  39
+    unsigned ascent;
  40
+} GRFont;
  41
+
  42
+static GRFont *gr_font = 0;
  43
+static GGLContext *gr_context = 0;
  44
+static GGLSurface gr_font_texture;
  45
+static GGLSurface gr_framebuffer[2];
  46
+static GGLSurface gr_mem_surface;
  47
+static unsigned gr_active_fb = 0;
  48
+
  49
+static int gr_fb_fd = -1;
  50
+static int gr_vt_fd = -1;
  51
+
  52
+static struct fb_var_screeninfo vi;
  53
+
  54
+static int get_framebuffer(GGLSurface *fb)
  55
+{
  56
+    int fd;
  57
+    struct fb_fix_screeninfo fi;
  58
+    void *bits;
  59
+
  60
+    fd = open("/dev/graphics/fb0", O_RDWR);
  61
+    if (fd < 0) {
  62
+        perror("cannot open fb0");
  63
+        return -1;
  64
+    }
  65
+
  66
+    if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
  67
+        perror("failed to get fb0 info");
  68
+        close(fd);
  69
+        return -1;
  70
+    }
  71
+
  72
+    if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
  73
+        perror("failed to get fb0 info");
  74
+        close(fd);
  75
+        return -1;
  76
+    }
  77
+
  78
+    bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  79
+    if (bits == MAP_FAILED) {
  80
+        perror("failed to mmap framebuffer");
  81
+        close(fd);
  82
+        return -1;
  83
+    }
  84
+
  85
+    fb->version = sizeof(*fb);
  86
+    fb->width = vi.xres;
  87
+    fb->height = vi.yres;
  88
+    fb->stride = vi.xres;
  89
+    fb->data = bits;
  90
+    fb->format = GGL_PIXEL_FORMAT_RGB_565;
  91
+
  92
+    fb++;
  93
+
  94
+    fb->version = sizeof(*fb);
  95
+    fb->width = vi.xres;
  96
+    fb->height = vi.yres;
  97
+    fb->stride = vi.xres;
  98
+    fb->data = (void*) (((unsigned) bits) + vi.yres * vi.xres * 2);
  99
+    fb->format = GGL_PIXEL_FORMAT_RGB_565;
  100
+
  101
+    return fd;
  102
+}
  103
+
  104
+static void get_memory_surface(GGLSurface* ms) {
  105
+  ms->version = sizeof(*ms);
  106
+  ms->width = vi.xres;
  107
+  ms->height = vi.yres;
  108
+  ms->stride = vi.xres;
  109
+  ms->data = malloc(vi.xres * vi.yres * 2);
  110
+  ms->format = GGL_PIXEL_FORMAT_RGB_565;
  111
+}
  112
+
  113
+static void set_active_framebuffer(unsigned n)
  114
+{
  115
+    if (n > 1) return;
  116
+    vi.yres_virtual = vi.yres * 2;
  117
+    vi.yoffset = n * vi.yres;
  118
+    vi.bits_per_pixel = 16;
  119
+    if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
  120
+        perror("active fb swap failed");
  121
+    }
  122
+}
  123
+
  124
+void gr_flip(void)
  125
+{
  126
+    GGLContext *gl = gr_context;
  127
+
  128
+    /* swap front and back buffers */
  129
+    gr_active_fb = (gr_active_fb + 1) & 1;
  130
+
  131
+    /* copy data from the in-memory surface to the buffer we're about
  132
+     * to make active. */
  133
+    memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data,
  134
+           vi.xres * vi.yres * 2);
  135
+
  136
+    /* inform the display driver */
  137
+    set_active_framebuffer(gr_active_fb);
  138
+}
  139
+
  140
+void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
  141
+{
  142
+    GGLContext *gl = gr_context;
  143
+    GGLint color[4];
  144
+    color[0] = ((r << 8) | r) + 1;
  145
+    color[1] = ((g << 8) | g) + 1;
  146
+    color[2] = ((b << 8) | b) + 1;
  147
+    color[3] = ((a << 8) | a) + 1;
  148
+    gl->color4xv(gl, color);
  149
+}
  150
+
  151
+int gr_measure(const char *s)
  152
+{
  153
+    return gr_font->cwidth * strlen(s);
  154
+}
  155
+
  156
+int gr_text(int x, int y, const char *s)
  157
+{
  158
+    GGLContext *gl = gr_context;
  159
+    GRFont *font = gr_font;
  160
+    unsigned off;
  161
+
  162
+    y -= font->ascent;
  163
+
  164
+    gl->bindTexture(gl, &font->texture);
  165
+    gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
  166
+    gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
  167
+    gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
  168
+    gl->enable(gl, GGL_TEXTURE_2D);
  169
+
  170
+    while((off = *s++)) {
  171
+        off -= 32;
  172
+        if (off < 96) {
  173
+            gl->texCoord2i(gl, (off * font->cwidth) - x, 0 - y);
  174
+            gl->recti(gl, x, y, x + font->cwidth, y + font->cheight);
  175
+        }
  176
+        x += font->cwidth;
  177
+    }
  178
+
  179
+    return x;
  180
+}
  181
+
  182
+void gr_fill(int x, int y, int w, int h)
  183
+{
  184
+    GGLContext *gl = gr_context;
  185
+    gl->disable(gl, GGL_TEXTURE_2D);
  186
+    gl->recti(gl, x, y, w, h);
  187
+}
  188
+
  189
+void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) {
  190
+    if (gr_context == NULL) {
  191
+        return;
  192
+    }
  193
+    GGLContext *gl = gr_context;
  194
+
  195
+    gl->bindTexture(gl, (GGLSurface*) source);
  196
+    gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
  197
+    gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
  198
+    gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
  199
+    gl->enable(gl, GGL_TEXTURE_2D);
  200
+    gl->texCoord2i(gl, sx - dx, sy - dy);
  201
+    gl->recti(gl, dx, dy, dx + w, dy + h);
  202
+}
  203
+
  204
+unsigned int gr_get_width(gr_surface surface) {
  205
+    if (surface == NULL) {
  206
+        return 0;
  207
+    }
  208
+    return ((GGLSurface*) surface)->width;
  209
+}
  210
+
  211
+unsigned int gr_get_height(gr_surface surface) {
  212
+    if (surface == NULL) {
  213
+        return 0;
  214
+    }
  215
+    return ((GGLSurface*) surface)->height;
  216
+}
  217
+
  218
+static void gr_init_font(void)
  219
+{
  220
+    GGLSurface *ftex;
  221
+    unsigned char *bits, *rle;
  222
+    unsigned char *in, data;
  223
+
  224
+    gr_font = calloc(sizeof(*gr_font), 1);
  225
+    ftex = &gr_font->texture;
  226
+
  227
+    bits = malloc(font.width * font.height);
  228
+
  229
+    ftex->version = sizeof(*ftex);
  230
+    ftex->width = font.width;
  231
+    ftex->height = font.height;
  232
+    ftex->stride = font.width;
  233
+    ftex->data = (void*) bits;
  234
+    ftex->format = GGL_PIXEL_FORMAT_A_8;
  235
+
  236
+    in = font.rundata;
  237
+    while((data = *in++)) {
  238
+        memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
  239
+        bits += (data & 0x7f);
  240
+    }
  241
+
  242
+    gr_font->cwidth = font.cwidth;
  243
+    gr_font->cheight = font.cheight;
  244
+    gr_font->ascent = font.cheight - 2;
  245
+}
  246
+
  247
+int gr_init(void)
  248
+{
  249
+    gglInit(&gr_context);
  250
+    GGLContext *gl = gr_context;
  251
+
  252
+    gr_init_font();
  253
+    gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC);
  254
+    if (gr_vt_fd < 0) {
  255
+        // This is non-fatal; post-Cupcake kernels don't have tty0.
  256
+        perror("can't open /dev/tty0");
  257
+    } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) {
  258
+        // However, if we do open tty0, we expect the ioctl to work.
  259
+        perror("failed KDSETMODE to KD_GRAPHICS on tty0");
  260
+        gr_exit();
  261
+        return -1;
  262
+    }
  263
+
  264
+    gr_fb_fd = get_framebuffer(gr_framebuffer);
  265
+    if (gr_fb_fd < 0) {
  266
+        gr_exit();
  267
+        return -1;
  268
+    }
  269
+
  270
+    get_memory_surface(&gr_mem_surface);
  271
+
  272
+    fprintf(stderr, "framebuffer: fd %d (%d x %d)\n",
  273
+            gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height);
  274
+
  275
+        /* start with 0 as front (displayed) and 1 as back (drawing) */
  276
+    gr_active_fb = 0;
  277
+    set_active_framebuffer(0);
  278
+    gl->colorBuffer(gl, &gr_mem_surface);
  279
+
  280
+
  281
+    gl->activeTexture(gl, 0);
  282
+    gl->enable(gl, GGL_BLEND);
  283
+    gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA);
  284
+
  285
+    return 0;
  286
+}
  287
+
  288
+void gr_exit(void)
  289
+{
  290
+    close(gr_fb_fd);
  291
+    gr_fb_fd = -1;
  292
+
  293
+    free(gr_mem_surface.data);
  294
+
  295
+    ioctl(gr_vt_fd, KDSETMODE, (void*) KD_TEXT);
  296
+    close(gr_vt_fd);
  297
+    gr_vt_fd = -1;
  298
+}
  299
+
  300
+int gr_fb_width(void)
  301
+{
  302
+    return gr_framebuffer[0].width;
  303
+}
  304
+
  305
+int gr_fb_height(void)
  306
+{
  307
+    return gr_framebuffer[0].height;
  308
+}
  309
+
  310
+gr_pixel *gr_fb_data(void)
  311
+{
  312
+    return (unsigned short *) gr_mem_surface.data;
  313
+}
71  minui/minui.h
... ...
@@ -0,0 +1,71 @@
  1
+/*
  2
+ * Copyright (C) 2007 The Android Open Source Project
  3
+ *
  4
+ * Licensed under the Apache License, Version 2.0 (the "License");
  5
+ * you may not use this file except in compliance with the License.
  6
+ * You may obtain a copy of the License at
  7
+ *
  8
+ *      http://www.apache.org/licenses/LICENSE-2.0
  9
+ *
  10
+ * Unless required by applicable law or agreed to in writing, software
  11
+ * distributed under the License is distributed on an "AS IS" BASIS,
  12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13
+ * See the License for the specific language governing permissions and
  14
+ * limitations under the License.
  15
+ */
  16
+
  17
+#ifndef _MINUI_H_
  18
+#define _MINUI_H_
  19
+
  20
+typedef void* gr_surface;
  21
+typedef unsigned short gr_pixel;
  22
+
  23
+int gr_init(void);
  24
+void gr_exit(void);
  25
+
  26
+int gr_fb_width(void);
  27
+int gr_fb_height(void);
  28
+gr_pixel *gr_fb_data(void);
  29
+void gr_flip(void);
  30
+
  31
+void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
  32
+void gr_fill(int x, int y, int w, int h);
  33
+int gr_text(int x, int y, const char *s);
  34
+int gr_measure(const char *s);
  35
+
  36
+void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy);
  37
+unsigned int gr_get_width(gr_surface surface);
  38
+unsigned int gr_get_height(gr_surface surface);
  39
+
  40
+// input event structure, include <linux/input.h> for the definition.
  41
+// see http://www.mjmwired.net/kernel/Documentation/input/ for info.
  42
+struct input_event;
  43
+
  44
+// Dream-specific key codes
  45
+#define KEY_DREAM_HOME        102  // = KEY_HOME
  46
+#define KEY_DREAM_RED         107  // = KEY_END
  47
+#define KEY_DREAM_VOLUMEDOWN  114  // = KEY_VOLUMEDOWN
  48
+#define KEY_DREAM_VOLUMEUP    115  // = KEY_VOLUMEUP
  49
+#define KEY_DREAM_SYM         127  // = KEY_COMPOSE
  50
+#define KEY_DREAM_MENU        139  // = KEY_MENU
  51
+#define KEY_DREAM_BACK        158  // = KEY_BACK
  52
+#define KEY_DREAM_FOCUS       211  // = KEY_HP (light touch on camera)
  53
+#define KEY_DREAM_CAMERA      212  // = KEY_CAMERA
  54
+#define KEY_DREAM_AT          215  // = KEY_EMAIL
  55
+#define KEY_DREAM_GREEN       231
  56
+#define KEY_DREAM_FATTOUCH    258  // = BTN_2 ???
  57
+#define KEY_DREAM_BALL        272  // = BTN_MOUSE
  58
+#define BTN_HERO_BALL         191  // = BTN_HERO_BALL
  59
+#define KEY_DREAM_TOUCH       330  // = BTN_TOUCH
  60
+
  61
+int ev_init(void);
  62
+void ev_exit(void);
  63
+int ev_get(struct input_event *ev, unsigned dont_wait);
  64
+
  65
+// Resources
  66
+
  67
+// Returns 0 if no error, else negative.
  68
+int res_create_surface(const char* name, gr_surface* pSurface);
  69
+void res_free_surface(gr_surface surface);
  70
+
  71
+#endif
54  minui/mkfont.c
... ...
@@ -0,0 +1,54 @@
  1
+#include <stdio.h>
  2
+#include <stdlib.h>
  3
+
  4
+int main(int argc, char *argv)
  5
+{
  6
+    unsigned n;
  7
+    unsigned char *x;
  8
+    unsigned m;
  9
+    unsigned run_val;
  10
+    unsigned run_count;
  11
+ 
  12
+    n = gimp_image.width * gimp_image.height;
  13
+    m = 0;
  14
+    x = gimp_image.pixel_data;
  15
+
  16
+    printf("struct {\n");
  17
+    printf("  unsigned width;\n");
  18
+    printf("  unsigned height;\n");
  19
+    printf("  unsigned cwidth;\n");
  20
+    printf("  unsigned cheight;\n");
  21
+    printf("  unsigned char rundata[];\n");
  22
+    printf("} font = {\n");
  23
+    printf("  .width = %d,\n  .height = %d,\n  .cwidth = %d,\n  .cheight = %d,\n", gimp_image.width, gimp_image.height,
  24
+           gimp_image.width / 96, gimp_image.height);
  25
+    printf("  .rundata = {\n");
  26
+   
  27
+    run_val = (*x ? 0 : 255);
  28
+    run_count = 1;
  29
+    n--;
  30
+    x+=3;
  31
+
  32
+    while(n-- > 0) {
  33
+        unsigned val = (*x ? 0 : 255);
  34
+        x+=3;
  35
+        if((val == run_val) && (run_count < 127)) {
  36
+            run_count++;
  37
+        } else {
  38
+eject:
  39
+            printf("0x%02x,",run_count | (run_val ? 0x80 : 0x00));
  40
+            run_val = val;
  41
+            run_count = 1;
  42
+            m += 5;
  43
+            if(m >= 75) {
  44
+                printf("\n");
  45
+                m = 0;
  46
+            }
  47
+        }
  48
+    }
  49
+    printf("0x%02x,",run_count | (run_val ? 0x80 : 0x00));
  50
+    printf("\n0x00,");
  51
+    printf("\n");
  52
+    printf("  }\n};\n");
  53
+    return 0;
  54
+}
169  minui/resources.c
... ...
@@ -0,0 +1,169 @@
  1
+/*
  2
+ * Copyright (C) 2007 The Android Open Source Project
  3
+ *
  4
+ * Licensed under the Apache License, Version 2.0 (the "License");
  5
+ * you may not use this file except in compliance with the License.
  6
+ * You may obtain a copy of the License at
  7
+ *
  8
+ *      http://www.apache.org/licenses/LICENSE-2.0
  9
+ *
  10
+ * Unless required by applicable law or agreed to in writing, software
  11
+ * distributed under the License is distributed on an "AS IS" BASIS,
  12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13
+ * See the License for the specific language governing permissions and
  14
+ * limitations under the License.
  15
+ */
  16
+
  17
+#include <stdlib.h>
  18
+#include <unistd.h>
  19
+
  20
+#include <fcntl.h>
  21
+#include <stdio.h>
  22
+
  23
+#include <sys/ioctl.h>
  24
+#include <sys/mman.h>
  25
+#include <sys/types.h>
  26
+
  27
+#include <linux/fb.h>
  28
+#include <linux/kd.h>
  29
+
  30
+#include <pixelflinger/pixelflinger.h>
  31
+
  32
+#include <png.h>
  33
+
  34
+#include "minui.h"
  35
+
  36
+// libpng gives "undefined reference to 'pow'" errors, and I have no
  37
+// idea how to convince the build system to link with -lm.  We don't
  38
+// need this functionality (it's used for gamma adjustment) so provide
  39
+// a dummy implementation to satisfy the linker.
  40
+double pow(double x, double y) {
  41
+    return x;
  42
+}
  43
+
  44
+int res_create_surface(const char* name, gr_surface* pSurface) {
  45
+    char resPath[256];
  46
+    GGLSurface* surface = NULL;
  47
+    int result = 0;
  48
+    unsigned char header[8];
  49
+    png_structp png_ptr = NULL;
  50
+    png_infop info_ptr = NULL;
  51
+
  52
+    snprintf(resPath, sizeof(resPath)-1, "/system/res/%s.png", name);
  53
+    resPath[sizeof(resPath)-1] = '\0';
  54
+    FILE* fp = fopen(resPath, "rb");
  55
+    if (fp == NULL) {
  56
+        result = -1;
  57
+        goto exit;
  58
+    }
  59
+
  60
+    size_t bytesRead = fread(header, 1, sizeof(header), fp);
  61
+    if (bytesRead != sizeof(header)) {
  62
+        result = -2;
  63
+        goto exit;
  64
+    }
  65
+
  66
+    if (png_sig_cmp(header, 0, sizeof(header))) {
  67
+        result = -3;
  68
+        goto exit;
  69
+    }
  70
+
  71
+    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  72
+    if (!png_ptr) {
  73
+        result = -4;
  74
+        goto exit;
  75
+    }
  76
+
  77
+    info_ptr = png_create_info_struct(png_ptr);
  78
+    if (!info_ptr) {
  79
+        result = -5;
  80
+        goto exit;
  81
+    }