diff options
Diffstat (limited to 'minuitwrp')
-rw-r--r-- | minuitwrp/Android.mk | 149 | ||||
-rw-r--r-- | minuitwrp/events.c | 774 | ||||
-rw-r--r-- | minuitwrp/font_10x18.h | 214 | ||||
-rw-r--r-- | minuitwrp/font_7x16.h | 15 | ||||
-rw-r--r-- | minuitwrp/graphics.c | 929 | ||||
-rw-r--r-- | minuitwrp/graphics_overlay.c | 458 | ||||
-rw-r--r-- | minuitwrp/graphics_utils.c | 107 | ||||
-rw-r--r-- | minuitwrp/include/linux/msm_ion.h | 157 | ||||
-rw-r--r-- | minuitwrp/include/linux/msm_mdp.h | 992 | ||||
-rw-r--r-- | minuitwrp/minui.h | 100 | ||||
-rw-r--r-- | minuitwrp/mkfont.c | 54 | ||||
-rw-r--r-- | minuitwrp/resources.c | 442 | ||||
-rw-r--r-- | minuitwrp/roboto_10x18.h | 197 | ||||
-rw-r--r-- | minuitwrp/roboto_15x24.h | 281 | ||||
-rw-r--r-- | minuitwrp/roboto_23x41.h | 461 | ||||
-rw-r--r-- | minuitwrp/truetype.c | 793 |
16 files changed, 6123 insertions, 0 deletions
diff --git a/minuitwrp/Android.mk b/minuitwrp/Android.mk new file mode 100644 index 000000000..c9749eb16 --- /dev/null +++ b/minuitwrp/Android.mk @@ -0,0 +1,149 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := events.c resources.c graphics_overlay.c graphics_utils.c + +ifneq ($(TW_BOARD_CUSTOM_GRAPHICS),) + LOCAL_SRC_FILES += $(TW_BOARD_CUSTOM_GRAPHICS) +else + LOCAL_SRC_FILES += graphics.c +endif + +ifeq ($(TW_TARGET_USES_QCOM_BSP), true) + LOCAL_CFLAGS += -DMSM_BSP + ifeq ($(TARGET_PREBUILT_KERNEL),) + LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include + else + ifeq ($(TARGET_CUSTOM_KERNEL_HEADERS),) + LOCAL_C_INCLUDES += $(commands_recovery_local_path)/minuitwrp/include + else + LOCAL_C_INCLUDES += $(TARGET_CUSTOM_KERNEL_HEADERS) + endif + endif +else + LOCAL_C_INCLUDES += $(commands_recovery_local_path)/minuitwrp/include +endif + +LOCAL_C_INCLUDES += \ + external/libpng \ + external/zlib \ + system/core/include \ + external/jpeg + +ifeq ($(RECOVERY_TOUCHSCREEN_SWAP_XY), true) +LOCAL_CFLAGS += -DRECOVERY_TOUCHSCREEN_SWAP_XY +endif + +ifeq ($(RECOVERY_TOUCHSCREEN_FLIP_X), true) +LOCAL_CFLAGS += -DRECOVERY_TOUCHSCREEN_FLIP_X +endif + +ifeq ($(RECOVERY_TOUCHSCREEN_FLIP_Y), true) +LOCAL_CFLAGS += -DRECOVERY_TOUCHSCREEN_FLIP_Y +endif + +ifeq ($(RECOVERY_GRAPHICS_USE_LINELENGTH), true) +LOCAL_CFLAGS += -DRECOVERY_GRAPHICS_USE_LINELENGTH +endif + +#Remove the # from the line below to enable event logging +#TWRP_EVENT_LOGGING := true +ifeq ($(TWRP_EVENT_LOGGING), true) +LOCAL_CFLAGS += -D_EVENT_LOGGING +endif + +ifeq ($(subst ",,$(TARGET_RECOVERY_PIXEL_FORMAT)),RGBX_8888) + LOCAL_CFLAGS += -DRECOVERY_RGBX +endif +ifeq ($(subst ",,$(TARGET_RECOVERY_PIXEL_FORMAT)),BGRA_8888) + LOCAL_CFLAGS += -DRECOVERY_BGRA +endif +ifeq ($(subst ",,$(TARGET_RECOVERY_PIXEL_FORMAT)),RGB_565) + LOCAL_CFLAGS += -DRECOVERY_RGB_565 +endif + +ifeq ($(TARGET_RECOVERY_PIXEL_FORMAT),"RGBX_8888") + LOCAL_CFLAGS += -DRECOVERY_RGBX +endif +ifeq ($(TARGET_RECOVERY_PIXEL_FORMAT),"BGRA_8888") + LOCAL_CFLAGS += -DRECOVERY_BGRA +endif +ifeq ($(TARGET_RECOVERY_PIXEL_FORMAT),"RGB_565") + LOCAL_CFLAGS += -DRECOVERY_RGB_565 +endif +ifeq ($(TW_SCREEN_BLANK_ON_BOOT), true) + LOCAL_CFLAGS += -DTW_SCREEN_BLANK_ON_BOOT +endif + +ifeq ($(BOARD_HAS_FLIPPED_SCREEN), true) +LOCAL_CFLAGS += -DBOARD_HAS_FLIPPED_SCREEN +endif + +ifeq ($(TW_IGNORE_MAJOR_AXIS_0), true) +LOCAL_CFLAGS += -DTW_IGNORE_MAJOR_AXIS_0 +endif + +ifeq ($(TW_IGNORE_MT_POSITION_0), true) +LOCAL_CFLAGS += -DTW_IGNORE_MT_POSITION_0 +endif + +ifneq ($(TW_INPUT_BLACKLIST),) + LOCAL_CFLAGS += -DTW_INPUT_BLACKLIST=$(TW_INPUT_BLACKLIST) +endif + +ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),) + LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=$(BOARD_USE_CUSTOM_RECOVERY_FONT) +else + ifeq ($(TW_THEME),) + # This converts the old DEVICE_RESOLUTION flag to the new TW_THEME flag + PORTRAIT_MDPI := 320x480 480x800 480x854 540x960 + PORTRAIT_HDPI := 720x1280 800x1280 1080x1920 1200x1920 1440x2560 1600x2560 + WATCH_MDPI := 240x240 280x280 320x320 + LANDSCAPE_MDPI := 800x480 1024x600 1024x768 + LANDSCAPE_HDPI := 1280x800 1920x1200 2560x1600 + ifneq ($(filter $(DEVICE_RESOLUTION), $(PORTRAIT_MDPI)),) + TW_THEME := portrait_mdpi + else ifneq ($(filter $(DEVICE_RESOLUTION), $(PORTRAIT_HDPI)),) + TW_THEME := portrait_hdpi + else ifneq ($(filter $(DEVICE_RESOLUTION), $(WATCH_MDPI)),) + TW_THEME := watch_mdpi + else ifneq ($(filter $(DEVICE_RESOLUTION), $(LANDSCAPE_MDPI)),) + TW_THEME := landscape_mdpi + else ifneq ($(filter $(DEVICE_RESOLUTION), $(LANDSCAPE_HDPI)),) + TW_THEME := landscape_hdpi + endif + endif + ifeq ($(TW_THEME), portrait_mdpi) + LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=\"roboto_10x18.h\" + else ifeq ($(TW_THEME), portrait_hdpi) + LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=\"roboto_15x24.h\" + else ifeq ($(TW_THEME), watch_mdpi) + LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=\"font_7x16.h\" + else ifeq ($(TW_THEME), landscape_mdpi) + LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=\"roboto_10x18.h\" + else ifeq ($(TW_THEME), landscape_hdpi) + LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=\"roboto_15x24.h\" + endif +endif + +ifneq ($(TW_WHITELIST_INPUT),) + LOCAL_CFLAGS += -DWHITELIST_INPUT=$(TW_WHITELIST_INPUT) +endif + +ifeq ($(TW_DISABLE_TTF), true) + LOCAL_CFLAGS += -DTW_DISABLE_TTF +else + LOCAL_SHARED_LIBRARIES += libft2 + LOCAL_C_INCLUDES += external/freetype/include + LOCAL_SRC_FILES += truetype.c +endif + +LOCAL_CFLAGS += -DTWRES=\"$(TWRES_PATH)\" +LOCAL_SHARED_LIBRARIES += libz libc libcutils libjpeg libpng +LOCAL_STATIC_LIBRARIES += libpixelflinger_static +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE := libminuitwrp + +include $(BUILD_SHARED_LIBRARY) diff --git a/minuitwrp/events.c b/minuitwrp/events.c new file mode 100644 index 000000000..0309a9a21 --- /dev/null +++ b/minuitwrp/events.c @@ -0,0 +1,774 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <dirent.h> +#include <sys/poll.h> +#include <limits.h> +#include <linux/input.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + + +#include "../common.h" + +#include "minui.h" + +//#define _EVENT_LOGGING + +#define MAX_DEVICES 32 + +#define VIBRATOR_TIMEOUT_FILE "/sys/class/timed_output/vibrator/enable" +#define VIBRATOR_TIME_MS 50 + +#ifndef SYN_REPORT +#define SYN_REPORT 0x00 +#endif +#ifndef SYN_CONFIG +#define SYN_CONFIG 0x01 +#endif +#ifndef SYN_MT_REPORT +#define SYN_MT_REPORT 0x02 +#endif + +#define ABS_MT_POSITION 0x2a /* Group a set of X and Y */ +#define ABS_MT_AMPLITUDE 0x2b /* Group a set of Z and W */ +#define ABS_MT_SLOT 0x2f +#define ABS_MT_TOUCH_MAJOR 0x30 +#define ABS_MT_TOUCH_MINOR 0x31 +#define ABS_MT_WIDTH_MAJOR 0x32 +#define ABS_MT_WIDTH_MINOR 0x33 +#define ABS_MT_ORIENTATION 0x34 +#define ABS_MT_POSITION_X 0x35 +#define ABS_MT_POSITION_Y 0x36 +#define ABS_MT_TOOL_TYPE 0x37 +#define ABS_MT_BLOB_ID 0x38 +#define ABS_MT_TRACKING_ID 0x39 +#define ABS_MT_PRESSURE 0x3a +#define ABS_MT_DISTANCE 0x3b + +enum { + DOWN_NOT, + DOWN_SENT, + DOWN_RELEASED, +}; + +struct virtualkey { + int scancode; + int centerx, centery; + int width, height; +}; + +struct position { + int x, y; + int synced; + struct input_absinfo xi, yi; +}; + +struct ev { + struct pollfd *fd; + + struct virtualkey *vks; + int vk_count; + + char deviceName[64]; + + int ignored; + + struct position p, mt_p; + int down; +}; + +static struct pollfd ev_fds[MAX_DEVICES]; +static struct ev evs[MAX_DEVICES]; +static unsigned ev_count = 0; +static struct timeval lastInputStat; +static unsigned long lastInputMTime; +static int has_mouse = 0; + +static inline int ABS(int x) { + return x<0?-x:x; +} + +int vibrate(int timeout_ms) +{ + char str[20]; + int fd; + int ret; + + if (timeout_ms > 10000) timeout_ms = 1000; + + fd = open(VIBRATOR_TIMEOUT_FILE, O_WRONLY); + if (fd < 0) + return -1; + + ret = snprintf(str, sizeof(str), "%d", timeout_ms); + ret = write(fd, str, ret); + close(fd); + + if (ret < 0) + return -1; + + return 0; +} + +/* Returns empty tokens */ +static char *vk_strtok_r(char *str, const char *delim, char **save_str) +{ + if(!str) + { + if(!*save_str) + return NULL; + + str = (*save_str) + 1; + } + *save_str = strpbrk(str, delim); + + if (*save_str) + **save_str = '\0'; + + return str; +} + +static int vk_init(struct ev *e) +{ + char vk_path[PATH_MAX] = "/sys/board_properties/virtualkeys."; + char vks[2048], *ts = NULL; + ssize_t len; + int vk_fd; + int i; + + e->vk_count = 0; + + len = strlen(vk_path); + len = ioctl(e->fd->fd, EVIOCGNAME(sizeof(e->deviceName)), e->deviceName); + if (len <= 0) + { + printf("Unable to query event object.\n"); + return -1; + } +#ifdef _EVENT_LOGGING + printf("Event object: %s\n", e->deviceName); +#endif + +#ifdef WHITELIST_INPUT + if (strcmp(e->deviceName, EXPAND(WHITELIST_INPUT)) != 0) + { + e->ignored = 1; + } +#else +#ifndef TW_INPUT_BLACKLIST + // Blacklist these "input" devices + if (strcmp(e->deviceName, "bma250") == 0 || strcmp(e->deviceName, "bma150") == 0) + { + printf("blacklisting %s input device\n", e->deviceName); + e->ignored = 1; + } +#else + char* bl = strdup(EXPAND(TW_INPUT_BLACKLIST)); + char* blacklist = strtok(bl, "\n"); + + while (blacklist != NULL) { + if (strcmp(e->deviceName, blacklist) == 0) { + printf("blacklisting %s input device\n", blacklist); + e->ignored = 1; + } + blacklist = strtok(NULL, "\n"); + } + free(bl); +#endif +#endif + + strcat(vk_path, e->deviceName); + + // Some devices split the keys from the touchscreen + e->vk_count = 0; + vk_fd = open(vk_path, O_RDONLY); + if (vk_fd >= 0) + { + len = read(vk_fd, vks, sizeof(vks)-1); + close(vk_fd); + if (len <= 0) + return -1; + + vks[len] = '\0'; + + /* Parse a line like: + keytype:keycode:centerx:centery:width:height:keytype2:keycode2:centerx2:... + */ + for (ts = vks, e->vk_count = 1; *ts; ++ts) { + if (*ts == ':') + ++e->vk_count; + } + + if (e->vk_count % 6) { + printf("minui: %s is %d %% 6\n", vk_path, e->vk_count % 6); + } + e->vk_count /= 6; + if (e->vk_count <= 0) + return -1; + + e->down = DOWN_NOT; + } + + ioctl(e->fd->fd, EVIOCGABS(ABS_X), &e->p.xi); + ioctl(e->fd->fd, EVIOCGABS(ABS_Y), &e->p.yi); + e->p.synced = 0; +#ifdef _EVENT_LOGGING + printf("EV: ST minX: %d maxX: %d minY: %d maxY: %d\n", e->p.xi.minimum, e->p.xi.maximum, e->p.yi.minimum, e->p.yi.maximum); +#endif + + ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_X), &e->mt_p.xi); + ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_Y), &e->mt_p.yi); + e->mt_p.synced = 0; +#ifdef _EVENT_LOGGING + printf("EV: MT minX: %d maxX: %d minY: %d maxY: %d\n", e->mt_p.xi.minimum, e->mt_p.xi.maximum, e->mt_p.yi.minimum, e->mt_p.yi.maximum); +#endif + + e->vks = malloc(sizeof(*e->vks) * e->vk_count); + + for (i = 0; i < e->vk_count; ++i) { + char *token[6]; + int j; + + for (j = 0; j < 6; ++j) { + token[j] = vk_strtok_r((i||j)?NULL:vks, ":", &ts); + } + + if (strcmp(token[0], "0x01") != 0) { + /* Java does string compare, so we do too. */ + printf("minui: %s: ignoring unknown virtual key type %s\n", vk_path, token[0]); + continue; + } + + e->vks[i].scancode = strtol(token[1], NULL, 0); + e->vks[i].centerx = strtol(token[2], NULL, 0); + e->vks[i].centery = strtol(token[3], NULL, 0); + e->vks[i].width = strtol(token[4], NULL, 0); + e->vks[i].height = strtol(token[5], NULL, 0); + } + + return 0; +} + +#define BITS_PER_LONG (sizeof(long) * 8) +#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) +#define OFF(x) ((x)%BITS_PER_LONG) +#define LONG(x) ((x)/BITS_PER_LONG) +#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) + +// Check for EV_REL (REL_X and REL_Y) and, because touchscreens can have those too, +// check also for EV_KEY (BTN_LEFT and BTN_RIGHT) +static void check_mouse(int fd) +{ + if(has_mouse) + return; + + unsigned long bit[EV_MAX][NBITS(KEY_MAX)]; + memset(bit, 0, sizeof(bit)); + ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]); + + if(!test_bit(EV_REL, bit[0]) || !test_bit(EV_KEY, bit[0])) + return; + + ioctl(fd, EVIOCGBIT(EV_REL, KEY_MAX), bit[EV_REL]); + if(!test_bit(REL_X, bit[EV_REL]) || !test_bit(REL_Y, bit[EV_REL])) + return; + + ioctl(fd, EVIOCGBIT(EV_KEY, KEY_MAX), bit[EV_KEY]); + if(!test_bit(BTN_LEFT, bit[EV_KEY]) || !test_bit(BTN_RIGHT, bit[EV_KEY])) + return; + + has_mouse = 1; +} + +int ev_has_mouse(void) +{ + return has_mouse; +} + +int ev_init(void) +{ + DIR *dir; + struct dirent *de; + int fd; + + has_mouse = 0; + + dir = opendir("/dev/input"); + if(dir != 0) { + while((de = readdir(dir))) { +// fprintf(stderr,"/dev/input/%s\n", de->d_name); + if(strncmp(de->d_name,"event",5)) continue; + fd = openat(dirfd(dir), de->d_name, O_RDONLY); + if(fd < 0) continue; + + ev_fds[ev_count].fd = fd; + ev_fds[ev_count].events = POLLIN; + evs[ev_count].fd = &ev_fds[ev_count]; + + /* Load virtualkeys if there are any */ + vk_init(&evs[ev_count]); + + check_mouse(fd); + + ev_count++; + if(ev_count == MAX_DEVICES) break; + } + closedir(dir); + } + + struct stat st; + if(stat("/dev/input", &st) >= 0) + lastInputMTime = st.st_mtime; + gettimeofday(&lastInputStat, NULL); + + return 0; +} + +void ev_exit(void) +{ + while (ev_count-- > 0) { + if (evs[ev_count].vk_count) { + free(evs[ev_count].vks); + evs[ev_count].vk_count = 0; + } + close(ev_fds[ev_count].fd); + } + ev_count = 0; +} + +static int vk_inside_display(__s32 value, struct input_absinfo *info, int screen_size) +{ + int screen_pos; + + if (info->minimum == info->maximum) + return 0; + + screen_pos = (value - info->minimum) * (screen_size - 1) / (info->maximum - info->minimum); + return (screen_pos >= 0 && screen_pos < screen_size); +} + +static int vk_tp_to_screen(struct position *p, int *x, int *y) +{ + if (p->xi.minimum == p->xi.maximum || p->yi.minimum == p->yi.maximum) + { + // In this case, we assume the screen dimensions are the same. + *x = p->x; + *y = p->y; + return 0; + } + +#ifdef _EVENT_LOGGING + printf("EV: p->x=%d x-range=%d,%d fb-width=%d\n", p->x, p->xi.minimum, p->xi.maximum, gr_fb_width()); +#endif + +#ifndef RECOVERY_TOUCHSCREEN_SWAP_XY + int fb_width = gr_fb_width(); + int fb_height = gr_fb_height(); +#else + // We need to swap the scaling sizes, too + int fb_width = gr_fb_height(); + int fb_height = gr_fb_width(); +#endif + + *x = (p->x - p->xi.minimum) * (fb_width - 1) / (p->xi.maximum - p->xi.minimum); + *y = (p->y - p->yi.minimum) * (fb_height - 1) / (p->yi.maximum - p->yi.minimum); + + if (*x >= 0 && *x < fb_width && + *y >= 0 && *y < fb_height) + { + return 0; + } + + return 1; +} + +/* Translate a virtual key in to a real key event, if needed */ +/* Returns non-zero when the event should be consumed */ +static int vk_modify(struct ev *e, struct input_event *ev) +{ + static int downX = -1, downY = -1; + static int discard = 0; + static int last_virt_key = 0; + static int lastWasSynReport = 0; + static int touchReleaseOnNextSynReport = 0; + static int use_tracking_id_negative_as_touch_release = 0; // On some devices, type: 3 code: 39 value: -1, aka EV_ABS ABS_MT_TRACKING_ID -1 indicates a true touch release + int i; + int x, y; + + // This is used to ditch useless event handlers, like an accelerometer + if (e->ignored) return 1; + + if (ev->type == EV_REL && ev->code == REL_Z) + { + // This appears to be an accelerometer or another strange input device. It's not the touchscreen. +#ifdef _EVENT_LOGGING + printf("EV: Device disabled due to non-touchscreen messages.\n"); +#endif + e->ignored = 1; + return 1; + } + +#ifdef _EVENT_LOGGING + printf("EV: %s => type: %x code: %x value: %d\n", e->deviceName, ev->type, ev->code, ev->value); +#endif + + // Handle keyboard events, value of 1 indicates key down, 0 indicates key up + if (ev->type == EV_KEY) { + return 0; + } + + if (ev->type == EV_ABS) { + switch (ev->code) { + + case ABS_X: //00 + e->p.synced |= 0x01; + e->p.x = ev->value; +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_X %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_Y: //01 + e->p.synced |= 0x02; + e->p.y = ev->value; +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_Y %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_MT_POSITION: //2a + e->mt_p.synced = 0x03; + if (ev->value == (1 << 31)) + { +#ifndef TW_IGNORE_MT_POSITION_0 + e->mt_p.x = 0; + e->mt_p.y = 0; + lastWasSynReport = 1; +#endif +#ifdef _EVENT_LOGGING +#ifndef TW_IGNORE_MT_POSITION_0 + printf("EV: %s => EV_ABS ABS_MT_POSITION %d, set x and y to 0 and lastWasSynReport to 1\n", e->deviceName, ev->value); +#else + printf("Ignoring ABS_MT_POSITION 0\n", e->deviceName, ev->value); +#endif +#endif + } + else + { + lastWasSynReport = 0; + e->mt_p.x = (ev->value & 0x7FFF0000) >> 16; + e->mt_p.y = (ev->value & 0xFFFF); +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_POSITION %d, set x: %d and y: %d and lastWasSynReport to 0\n", e->deviceName, ev->value, (ev->value & 0x7FFF0000) >> 16, (ev->value & 0xFFFF)); +#endif + } + break; + + case ABS_MT_TOUCH_MAJOR: //30 + if (ev->value == 0) + { +#ifndef TW_IGNORE_MAJOR_AXIS_0 + // We're in a touch release, although some devices will still send positions as well + e->mt_p.x = 0; + e->mt_p.y = 0; + touchReleaseOnNextSynReport = 1; +#endif + } +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_TOUCH_MAJOR %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_MT_PRESSURE: //3a + if (ev->value == 0) + { + // We're in a touch release, although some devices will still send positions as well + e->mt_p.x = 0; + e->mt_p.y = 0; + touchReleaseOnNextSynReport = 1; + } +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_PRESSURE %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_MT_POSITION_X: //35 + e->mt_p.synced |= 0x01; + e->mt_p.x = ev->value; +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_POSITION_X %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_MT_POSITION_Y: //36 + e->mt_p.synced |= 0x02; + e->mt_p.y = ev->value; +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_POSITION_Y %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_MT_TOUCH_MINOR: //31 +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_TOUCH_MINOR %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_MT_WIDTH_MAJOR: //32 +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_WIDTH_MAJOR %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_MT_WIDTH_MINOR: //33 +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_WIDTH_MINOR %d\n", e->deviceName, ev->value); +#endif + break; + + case ABS_MT_TRACKING_ID: //39 + if (ev->value < 0) { + e->mt_p.x = 0; + e->mt_p.y = 0; + touchReleaseOnNextSynReport = 2; + use_tracking_id_negative_as_touch_release = 1; +#ifdef _EVENT_LOGGING + if (use_tracking_id_negative_as_touch_release) + printf("using ABS_MT_TRACKING_ID value -1 to indicate touch releases\n"); +#endif + } +#ifdef _EVENT_LOGGING + printf("EV: %s => EV_ABS ABS_MT_TRACKING_ID %d\n", e->deviceName, ev->value); +#endif + break; + +#ifdef _EVENT_LOGGING + // These are for touch logging purposes only + case ABS_MT_ORIENTATION: //34 + printf("EV: %s => EV_ABS ABS_MT_ORIENTATION %d\n", e->deviceName, ev->value); + return 1; + break; + + case ABS_MT_TOOL_TYPE: //37 + LOGI("EV: %s => EV_ABS ABS_MT_TOOL_TYPE %d\n", e->deviceName, ev->value); + return 1; + break; + + case ABS_MT_BLOB_ID: //38 + printf("EV: %s => EV_ABS ABS_MT_BLOB_ID %d\n", e->deviceName, ev->value); + return 1; + break; + + case ABS_MT_DISTANCE: //3b + printf("EV: %s => EV_ABS ABS_MT_DISTANCE %d\n", e->deviceName, ev->value); + return 1; + break; +#endif + + default: + // This is an unhandled message, just skip it + return 1; + } + + if (ev->code != ABS_MT_POSITION) + { + lastWasSynReport = 0; + return 1; + } + } + + // Check if we should ignore the message + if (ev->code != ABS_MT_POSITION && (ev->type != EV_SYN || (ev->code != SYN_REPORT && ev->code != SYN_MT_REPORT))) + { + lastWasSynReport = 0; + return 0; + } + +#ifdef _EVENT_LOGGING + if (ev->type == EV_SYN && ev->code == SYN_REPORT) printf("EV: %s => EV_SYN SYN_REPORT\n", e->deviceName); + if (ev->type == EV_SYN && ev->code == SYN_MT_REPORT) printf("EV: %s => EV_SYN SYN_MT_REPORT\n", e->deviceName); +#endif + + // Discard the MT versions + if (ev->code == SYN_MT_REPORT) return 0; + + if (((lastWasSynReport == 1 || touchReleaseOnNextSynReport == 1) && !use_tracking_id_negative_as_touch_release) || (use_tracking_id_negative_as_touch_release && touchReleaseOnNextSynReport == 2)) + { + // Reset the value + touchReleaseOnNextSynReport = 0; + + // We are a finger-up state + if (!discard) + { + // Report the key up + ev->type = EV_ABS; + ev->code = 0; + ev->value = (downX << 16) | downY; + } + downX = -1; + downY = -1; + if (discard) + { + discard = 0; + + // Send the keyUp event + ev->type = EV_KEY; + ev->code = last_virt_key; + ev->value = 0; + } + return 0; + } + lastWasSynReport = 1; + + // Retrieve where the x,y position is + if (e->p.synced & 0x03) + { + vk_tp_to_screen(&e->p, &x, &y); + } + else if (e->mt_p.synced & 0x03) + { + vk_tp_to_screen(&e->mt_p, &x, &y); + } + else + { + // We don't have useful information to convey + return 1; + } + +#ifdef RECOVERY_TOUCHSCREEN_SWAP_XY + x ^= y; + y ^= x; + x ^= y; +#endif +#ifdef RECOVERY_TOUCHSCREEN_FLIP_X + x = gr_fb_width() - x; +#endif +#ifdef RECOVERY_TOUCHSCREEN_FLIP_Y + y = gr_fb_height() - y; +#endif + +#ifdef _EVENT_LOGGING + printf("EV: x: %d y: %d\n", x, y); +#endif + + // Clear the current sync states + e->p.synced = e->mt_p.synced = 0; + + // If we have nothing useful to report, skip it + if (x == -1 || y == -1) return 1; + + // On first touch, see if we're at a virtual key + if (downX == -1) + { + // Attempt mapping to virtual key + for (i = 0; i < e->vk_count; ++i) + { + int xd = ABS(e->vks[i].centerx - x); + int yd = ABS(e->vks[i].centery - y); + + if (xd < e->vks[i].width/2 && yd < e->vks[i].height/2) + { + ev->type = EV_KEY; + ev->code = e->vks[i].scancode; + ev->value = 1; + + last_virt_key = e->vks[i].scancode; + + vibrate(VIBRATOR_TIME_MS); + + // Mark that all further movement until lift is discard, + // and make sure we don't come back into this area + discard = 1; + downX = 0; + return 0; + } + } + } + + // If we were originally a button press, discard this event + if (discard) + { + return 1; + } + + // Record where we started the touch for deciding if this is a key or a scroll + downX = x; + downY = y; + + ev->type = EV_ABS; + ev->code = 1; + ev->value = (x << 16) | y; + return 0; +} + +int ev_get(struct input_event *ev, int timeout_ms) +{ + int r; + unsigned n; + struct timeval curr; + + gettimeofday(&curr, NULL); + if(curr.tv_sec - lastInputStat.tv_sec >= 2) + { + struct stat st; + stat("/dev/input", &st); + if (st.st_mtime > lastInputMTime) + { + printf("Reloading input devices\n"); + ev_exit(); + ev_init(); + lastInputMTime = st.st_mtime; + } + lastInputStat = curr; + } + + r = poll(ev_fds, ev_count, timeout_ms); + + if(r > 0) { + for(n = 0; n < ev_count; n++) { + if(ev_fds[n].revents & POLLIN) { + r = read(ev_fds[n].fd, ev, sizeof(*ev)); + if(r == sizeof(*ev)) { + if (!vk_modify(&evs[n], ev)) + return 0; + } + } + } + return -1; + } + + return -2; +} + +int ev_wait(int timeout) +{ + return -1; +} + +void ev_dispatch(void) +{ + return; +} + +int ev_get_input(int fd, short revents, struct input_event *ev) +{ + return -1; +} diff --git a/minuitwrp/font_10x18.h b/minuitwrp/font_10x18.h new file mode 100644 index 000000000..7f96465cc --- /dev/null +++ b/minuitwrp/font_10x18.h @@ -0,0 +1,214 @@ +struct { + unsigned width; + unsigned height; + unsigned cwidth; + unsigned cheight; + unsigned char rundata[]; +} font = { + .width = 960, + .height = 18, + .cwidth = 10, + .cheight = 18, + .rundata = { +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x55,0x82,0x06,0x82,0x02,0x82,0x10,0x82, +0x11,0x83,0x08,0x82,0x0a,0x82,0x04,0x82,0x46,0x82,0x08,0x82,0x07,0x84,0x06, +0x84,0x0a,0x81,0x03,0x88,0x04,0x84,0x04,0x88,0x04,0x84,0x06,0x84,0x1e,0x81, +0x0e,0x81,0x0a,0x84,0x06,0x84,0x07,0x82,0x05,0x85,0x07,0x84,0x04,0x86,0x04, +0x88,0x02,0x88,0x04,0x84,0x04,0x82,0x04,0x82,0x02,0x88,0x05,0x86,0x01,0x82, +0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x84,0x04, +0x86,0x06,0x84,0x04,0x86,0x06,0x84,0x04,0x88,0x02,0x82,0x04,0x82,0x02,0x82, +0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02, +0x88,0x03,0x86,0x0e,0x86,0x06,0x82,0x11,0x82,0x10,0x82,0x18,0x82,0x0f,0x84, +0x0d,0x82,0x1c,0x82,0x09,0x84,0x7f,0x16,0x84,0x05,0x82,0x05,0x84,0x07,0x83, +0x02,0x82,0x19,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x82,0x03,0x86,0x04, +0x83,0x02,0x82,0x03,0x82,0x01,0x82,0x07,0x82,0x09,0x82,0x06,0x82,0x3e,0x82, +0x04,0x84,0x06,0x83,0x06,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x03, +0x82,0x09,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82, +0x1c,0x82,0x0e,0x82,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x05,0x84,0x04, +0x82,0x02,0x82,0x05,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82, +0x09,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x04, +0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x03,0x82,0x02,0x82, +0x03,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02, +0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82, +0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x03,0x82,0x08,0x82,0x0c, +0x82,0x05,0x84,0x11,0x82,0x0f,0x82,0x18,0x82,0x0e,0x82,0x02,0x82,0x0c,0x82, +0x1c,0x82,0x0b,0x82,0x7f,0x15,0x82,0x08,0x82,0x08,0x82,0x05,0x82,0x01,0x82, +0x01,0x82,0x19,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x82,0x02,0x82,0x01, +0x82,0x01,0x82,0x02,0x82,0x01,0x82,0x01,0x82,0x03,0x82,0x01,0x82,0x07,0x82, +0x08,0x82,0x08,0x82,0x3d,0x82,0x03,0x82,0x02,0x82,0x04,0x84,0x05,0x82,0x04, +0x82,0x02,0x82,0x04,0x82,0x06,0x83,0x03,0x82,0x08,0x82,0x04,0x81,0x09,0x82, +0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x1a,0x82,0x10,0x82,0x06,0x82,0x04, +0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82, +0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02, +0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x83, +0x02,0x83,0x02,0x83,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02, +0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82, +0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x04, +0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x08,0x82,0x0c,0x82,0x04,0x82,0x02,0x82, +0x11,0x82,0x0e,0x82,0x18,0x82,0x0e,0x82,0x02,0x82,0x0c,0x82,0x0b,0x82,0x0b, +0x82,0x02,0x82,0x0b,0x82,0x4d,0x82,0x45,0x82,0x08,0x82,0x08,0x82,0x05,0x82, +0x02,0x83,0x1a,0x82,0x07,0x81,0x02,0x81,0x07,0x82,0x01,0x82,0x02,0x82,0x01, +0x82,0x05,0x82,0x01,0x84,0x04,0x82,0x01,0x82,0x07,0x82,0x08,0x82,0x08,0x82, +0x06,0x82,0x02,0x82,0x06,0x82,0x28,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x01, +0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x84,0x03,0x82,0x08,0x82, +0x0d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x19,0x82,0x12,0x82,0x05, +0x82,0x04,0x82,0x02,0x82,0x02,0x84,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82, +0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x04, +0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x83,0x02,0x83, +0x02,0x84,0x02,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04, +0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x0b,0x82,0x05,0x82,0x04,0x82,0x02,0x82, +0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08, +0x82,0x04,0x82,0x09,0x82,0x0b,0x82,0x03,0x82,0x04,0x82,0x20,0x82,0x18,0x82, +0x0e,0x82,0x10,0x82,0x0b,0x82,0x0b,0x82,0x02,0x82,0x0b,0x82,0x4d,0x82,0x45, +0x82,0x08,0x82,0x08,0x82,0x26,0x82,0x10,0x88,0x01,0x82,0x01,0x82,0x06,0x83, +0x01,0x82,0x04,0x84,0x08,0x81,0x08,0x82,0x0a,0x82,0x05,0x82,0x02,0x82,0x06, +0x82,0x28,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x08,0x82,0x04,0x82, +0x01,0x82,0x03,0x82,0x08,0x82,0x0d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04, +0x82,0x18,0x82,0x06,0x88,0x06,0x82,0x04,0x82,0x04,0x82,0x02,0x82,0x01,0x85, +0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x04,0x82,0x02, +0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82, +0x02,0x82,0x04,0x82,0x08,0x88,0x02,0x84,0x02,0x82,0x02,0x82,0x04,0x82,0x02, +0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x0b,0x82, +0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x04,0x84,0x06, +0x84,0x08,0x82,0x05,0x82,0x09,0x82,0x0b,0x82,0x2b,0x82,0x18,0x82,0x0e,0x82, +0x10,0x82,0x1c,0x82,0x0b,0x82,0x4d,0x82,0x45,0x82,0x08,0x82,0x08,0x82,0x26, +0x82,0x11,0x82,0x01,0x82,0x03,0x82,0x01,0x82,0x09,0x82,0x06,0x82,0x12,0x82, +0x0a,0x82,0x06,0x84,0x07,0x82,0x27,0x82,0x04,0x82,0x04,0x82,0x05,0x82,0x0b, +0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x01,0x83,0x04,0x82,0x01,0x83, +0x08,0x82,0x05,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x05,0x83,0x07,0x83,0x05, +0x82,0x16,0x82,0x08,0x82,0x03,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82, +0x02,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08, +0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82, +0x08,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04, +0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82, +0x0a,0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01, +0x82,0x04,0x84,0x06,0x84,0x08,0x82,0x05,0x82,0x0a,0x82,0x0a,0x82,0x23,0x85, +0x03,0x82,0x01,0x83,0x06,0x85,0x05,0x83,0x01,0x82,0x04,0x84,0x04,0x86,0x05, +0x85,0x01,0x81,0x02,0x82,0x01,0x83,0x05,0x84,0x09,0x84,0x02,0x82,0x03,0x82, +0x06,0x82,0x05,0x81,0x01,0x82,0x01,0x82,0x03,0x82,0x01,0x83,0x06,0x84,0x04, +0x82,0x01,0x83,0x06,0x83,0x01,0x82,0x02,0x82,0x01,0x84,0x04,0x86,0x03,0x86, +0x04,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04, +0x82,0x02,0x82,0x04,0x82,0x03,0x87,0x05,0x82,0x08,0x82,0x08,0x82,0x26,0x82, +0x11,0x82,0x01,0x82,0x04,0x86,0x07,0x82,0x05,0x83,0x12,0x82,0x0a,0x82,0x04, +0x88,0x02,0x88,0x0c,0x88,0x10,0x82,0x04,0x82,0x04,0x82,0x05,0x82,0x0a,0x82, +0x06,0x83,0x04,0x82,0x03,0x82,0x03,0x83,0x02,0x82,0x03,0x83,0x02,0x82,0x07, +0x82,0x06,0x84,0x05,0x82,0x02,0x83,0x05,0x83,0x07,0x83,0x04,0x82,0x18,0x82, +0x06,0x82,0x04,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x86,0x04, +0x82,0x08,0x82,0x04,0x82,0x02,0x86,0x04,0x86,0x04,0x82,0x02,0x84,0x02,0x88, +0x05,0x82,0x0a,0x82,0x03,0x85,0x05,0x82,0x08,0x82,0x01,0x82,0x01,0x82,0x02, +0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82, +0x04,0x82,0x02,0x82,0x03,0x82,0x05,0x84,0x07,0x82,0x05,0x82,0x04,0x82,0x03, +0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,0x82,0x05,0x82,0x08,0x82,0x08,0x82, +0x06,0x82,0x0a,0x82,0x0a,0x82,0x22,0x82,0x03,0x82,0x02,0x83,0x02,0x82,0x04, +0x82,0x03,0x82,0x03,0x82,0x02,0x83,0x03,0x82,0x02,0x82,0x05,0x82,0x06,0x82, +0x03,0x83,0x02,0x83,0x02,0x82,0x06,0x82,0x0b,0x82,0x02,0x82,0x02,0x82,0x07, +0x82,0x05,0x88,0x02,0x83,0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x82, +0x04,0x82,0x02,0x83,0x03,0x83,0x02,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06, +0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82, +0x03,0x82,0x04,0x82,0x08,0x82,0x02,0x84,0x09,0x82,0x09,0x84,0x23,0x82,0x11, +0x82,0x01,0x82,0x06,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x01,0x82,0x11,0x82, +0x0a,0x82,0x06,0x84,0x07,0x82,0x26,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x08, +0x83,0x09,0x82,0x03,0x82,0x03,0x82,0x09,0x82,0x02,0x82,0x04,0x82,0x05,0x82, +0x06,0x82,0x02,0x82,0x05,0x83,0x01,0x82,0x17,0x82,0x16,0x82,0x06,0x82,0x05, +0x82,0x01,0x82,0x01,0x82,0x02,0x88,0x02,0x82,0x03,0x82,0x03,0x82,0x08,0x82, +0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05, +0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x01,0x82,0x01,0x82, +0x02,0x82,0x02,0x84,0x02,0x82,0x04,0x82,0x02,0x86,0x04,0x82,0x04,0x82,0x02, +0x86,0x09,0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x82, +0x01,0x82,0x04,0x84,0x07,0x82,0x07,0x82,0x07,0x82,0x0b,0x82,0x09,0x82,0x27, +0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82, +0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02, +0x82,0x01,0x82,0x08,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82, +0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x07, +0x82,0x0a,0x82,0x06,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x04,0x82, +0x04,0x84,0x04,0x82,0x04,0x82,0x07,0x82,0x06,0x82,0x08,0x82,0x08,0x82,0x26, +0x82,0x0f,0x88,0x05,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x02,0x82,0x01,0x82, +0x0d,0x82,0x0a,0x82,0x05,0x82,0x02,0x82,0x06,0x82,0x26,0x82,0x05,0x82,0x04, +0x82,0x05,0x82,0x07,0x82,0x0c,0x82,0x02,0x88,0x08,0x82,0x02,0x82,0x04,0x82, +0x05,0x82,0x05,0x82,0x04,0x82,0x08,0x82,0x18,0x82,0x14,0x82,0x07,0x82,0x05, +0x82,0x01,0x84,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82, +0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05, +0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x01,0x82,0x01,0x82, +0x02,0x82,0x02,0x84,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02, +0x82,0x02,0x82,0x0a,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x82, +0x01,0x82,0x01,0x82,0x04,0x84,0x07,0x82,0x07,0x82,0x07,0x82,0x0b,0x82,0x09, +0x82,0x22,0x87,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x88, +0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02, +0x84,0x09,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82, +0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x08,0x86,0x05, +0x82,0x06,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,0x82, +0x05,0x82,0x05,0x82,0x04,0x82,0x06,0x82,0x07,0x82,0x08,0x82,0x08,0x82,0x26, +0x82,0x10,0x82,0x01,0x82,0x07,0x82,0x01,0x82,0x04,0x82,0x01,0x83,0x02,0x82, +0x03,0x83,0x0f,0x82,0x08,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x25,0x82,0x07, +0x82,0x02,0x82,0x06,0x82,0x06,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x09,0x82, +0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x04,0x82,0x08,0x82,0x19,0x82,0x05, +0x88,0x05,0x82,0x08,0x82,0x05,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x02,0x82, +0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04, +0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x03,0x82,0x03,0x82,0x03,0x82, +0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02, +0x82,0x08,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x03,0x82,0x09,0x82,0x05,0x82, +0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x83,0x02,0x83,0x03,0x82,0x02,0x82,0x06, +0x82,0x06,0x82,0x08,0x82,0x0c,0x82,0x08,0x82,0x21,0x82,0x04,0x82,0x02,0x82, +0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,0x82,0x06,0x82,0x03, +0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x85,0x08,0x82,0x05,0x82, +0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04, +0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0d,0x82,0x04,0x82,0x06,0x82,0x04,0x82, +0x04,0x84,0x04,0x82,0x01,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x05, +0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x38,0x82,0x01,0x82,0x04,0x82,0x01,0x82, +0x01,0x82,0x04,0x84,0x01,0x82,0x01,0x82,0x03,0x82,0x10,0x82,0x08,0x82,0x30, +0x83,0x06,0x82,0x07,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x08,0x82,0x04,0x82, +0x07,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x04, +0x82,0x03,0x81,0x04,0x82,0x1a,0x82,0x10,0x82,0x10,0x82,0x08,0x82,0x04,0x82, +0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08, +0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x03,0x82, +0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02, +0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x02,0x84,0x02,0x82,0x03,0x82,0x03,0x82, +0x04,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x05,0x83,0x02,0x83,0x03, +0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x09,0x82,0x0c,0x82,0x08,0x82,0x21,0x82, +0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a, +0x82,0x07,0x85,0x04,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x82,0x02,0x82, +0x07,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04, +0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0d,0x82,0x04,0x82, +0x06,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x82,0x01,0x82,0x04,0x84,0x04, +0x82,0x04,0x82,0x04,0x82,0x09,0x82,0x08,0x82,0x08,0x82,0x26,0x82,0x10,0x82, +0x01,0x82,0x05,0x86,0x04,0x82,0x01,0x82,0x01,0x82,0x01,0x83,0x01,0x84,0x10, +0x82,0x06,0x82,0x1d,0x83,0x11,0x83,0x05,0x82,0x09,0x84,0x07,0x82,0x05,0x82, +0x09,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04, +0x82,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x06,0x83,0x07,0x83,0x09,0x82, +0x0e,0x82,0x0a,0x82,0x06,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x03, +0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x09,0x82, +0x02,0x83,0x02,0x82,0x04,0x82,0x05,0x82,0x06,0x82,0x01,0x82,0x04,0x82,0x04, +0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82, +0x03,0x82,0x09,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x06, +0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82, +0x05,0x82,0x05,0x82,0x09,0x82,0x0d,0x82,0x07,0x82,0x21,0x82,0x04,0x82,0x02, +0x83,0x02,0x82,0x04,0x82,0x03,0x82,0x03,0x82,0x02,0x83,0x03,0x82,0x03,0x82, +0x04,0x82,0x06,0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x82,0x03, +0x82,0x06,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x03,0x82, +0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x07,0x82,0x04, +0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x02,0x83,0x05,0x82,0x05,0x88,0x03,0x82, +0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x0a,0x82,0x08,0x82,0x08,0x82,0x26, +0x82,0x1c,0x82,0x06,0x82,0x02,0x83,0x03,0x84,0x02,0x82,0x10,0x82,0x04,0x82, +0x1e,0x83,0x11,0x83,0x05,0x82,0x0a,0x82,0x05,0x88,0x02,0x88,0x04,0x84,0x09, +0x82,0x05,0x84,0x06,0x84,0x05,0x82,0x09,0x84,0x06,0x84,0x07,0x83,0x07,0x83, +0x0a,0x81,0x0e,0x81,0x0b,0x82,0x07,0x85,0x03,0x82,0x04,0x82,0x02,0x86,0x06, +0x84,0x04,0x86,0x04,0x88,0x02,0x82,0x0a,0x84,0x01,0x81,0x02,0x82,0x04,0x82, +0x02,0x88,0x04,0x83,0x05,0x82,0x04,0x82,0x02,0x88,0x02,0x82,0x04,0x82,0x02, +0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x0a,0x85,0x03,0x82,0x04,0x82,0x04,0x84, +0x07,0x82,0x07,0x84,0x07,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05, +0x82,0x05,0x88,0x03,0x86,0x09,0x82,0x03,0x86,0x22,0x85,0x01,0x81,0x02,0x82, +0x01,0x83,0x06,0x85,0x05,0x83,0x01,0x82,0x04,0x85,0x05,0x82,0x07,0x86,0x03, +0x82,0x04,0x82,0x02,0x88,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x88,0x02,0x82, +0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x83,0x06, +0x83,0x01,0x82,0x03,0x82,0x08,0x86,0x06,0x84,0x05,0x83,0x01,0x82,0x05,0x82, +0x06,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x04,0x83,0x01,0x82,0x03,0x87,0x06, +0x84,0x05,0x82,0x05,0x84,0x7f,0x15,0x83,0x7f,0x14,0x83,0x7f,0x5e,0x82,0x7f, +0x05,0x89,0x47,0x82,0x04,0x82,0x17,0x82,0x03,0x82,0x34,0x82,0x0e,0x82,0x4e, +0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0a,0x82,0x04,0x82,0x17,0x82,0x03,0x82, +0x34,0x82,0x0e,0x82,0x48,0x82,0x04,0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0a, +0x82,0x04,0x82,0x17,0x82,0x03,0x82,0x34,0x82,0x0e,0x82,0x49,0x82,0x02,0x82, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0c,0x86,0x19,0x85,0x35,0x82,0x0e,0x82,0x4a, +0x84,0x3f, +0x00, + } +}; diff --git a/minuitwrp/font_7x16.h b/minuitwrp/font_7x16.h new file mode 100644 index 000000000..0f72b5386 --- /dev/null +++ b/minuitwrp/font_7x16.h @@ -0,0 +1,15 @@ +struct { + unsigned width; + unsigned height; + unsigned cwidth; + unsigned cheight; + unsigned char rundata[]; +} font = { + .width = 668, + .height = 16, + .cwidth = 7, + .cheight = 16, + .rundata = { +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7e,0x82,0x03,0x82,0x7f,0x7f,0x5f,0x82,0x0b,0x82,0x14,0x81,0x0b,0x81,0x11,0x81,0x0c,0x82,0x09,0x81,0x08,0x81,0x07,0x81,0x03,0x81,0x06,0x83,0x68,0x83,0x04,0x81,0x04,0x83,0x17,0x81,0x05,0x81,0x01,0x81,0x0c,0x81,0x04,0x82,0x07,0x83,0x04,0x81,0x07,0x81,0x05,0x81,0x06,0x81,0x25,0x81,0x02,0x84,0x02,0x83,0x05,0x84,0x03,0x84,0x05,0x82,0x02,0x85,0x04,0x83,0x02,0x86,0x02,0x84,0x03,0x84,0x27,0x83,0x0b,0x82,0x03,0x85,0x04,0x83,0x02,0x84,0x03,0x86,0x01,0x86,0x03,0x83,0x02,0x81,0x04,0x81,0x01,0x85,0x04,0x83,0x02,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x82,0x03,0x81,0x02,0x84,0x02,0x85,0x03,0x84,0x02,0x85,0x03,0x84,0x01,0x87,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x82,0x05,0x81,0x01,0x81,0x04,0x82,0x05,0x81,0x01,0x86,0x03,0x81,0x04,0x81,0x08,0x81,0x05,0x82,0x0e,0x81,0x0a,0x81,0x11,0x81,0x0b,0x81,0x0b,0x81,0x14,0x81,0x08,0x81,0x37,0x81,0x30,0x81,0x06,0x81,0x06,0x81,0x17,0x81,0x05,0x81,0x01,0x81,0x05,0x81,0x01,0x81,0x03,0x83,0x02,0x81,0x02,0x81,0x05,0x81,0x07,0x81,0x07,0x81,0x05,0x81,0x04,0x81,0x01,0x81,0x01,0x81,0x22,0x81,0x03,0x81,0x02,0x81,0x04,0x81,0x04,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x04,0x82,0x02,0x81,0x07,0x81,0x03,0x81,0x05,0x82,0x01,0x81,0x04,0x81,0x01,0x82,0x02,0x81,0x26,0x81,0x03,0x81,0x03,0x83,0x04,0x82,0x03,0x81,0x04,0x81,0x02,0x81,0x03,0x81,0x01,0x81,0x03,0x81,0x02,0x81,0x06,0x81,0x07,0x81,0x03,0x81,0x01,0x81,0x04,0x81,0x03,0x81,0x08,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x06,0x82,0x02,0x82,0x01,0x82,0x03,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x04,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x01,0x81,0x04,0x82,0x02,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x03,0x81,0x06,0x82,0x03,0x81,0x05,0x81,0x07,0x81,0x04,0x81,0x02,0x81,0x18,0x81,0x11,0x81,0x0b,0x81,0x0b,0x81,0x14,0x81,0x08,0x81,0x37,0x81,0x30,0x81,0x06,0x81,0x06,0x81,0x17,0x81,0x05,0x81,0x01,0x81,0x04,0x81,0x02,0x81,0x02,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x02,0x81,0x05,0x81,0x07,0x81,0x06,0x81,0x07,0x81,0x04,0x83,0x05,0x81,0x1d,0x81,0x02,0x81,0x04,0x81,0x03,0x81,0x09,0x81,0x06,0x81,0x03,0x81,0x01,0x81,0x02,0x81,0x06,0x81,0x0a,0x81,0x02,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x14,0x81,0x08,0x81,0x0b,0x81,0x02,0x81,0x02,0x82,0x03,0x82,0x03,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x06,0x81,0x06,0x81,0x04,0x81,0x03,0x81,0x08,0x81,0x02,0x81,0x02,0x81,0x03,0x81,0x06,0x82,0x02,0x82,0x01,0x81,0x01,0x81,0x02,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x08,0x81,0x04,0x81,0x04,0x81,0x02,0x81,0x02,0x81,0x01,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x03,0x81,0x01,0x81,0x07,0x81,0x04,0x81,0x05,0x81,0x07,0x81,0x03,0x81,0x04,0x81,0x11,0x83,0x03,0x84,0x04,0x83,0x04,0x84,0x03,0x83,0x03,0x85,0x03,0x84,0x02,0x81,0x01,0x82,0x03,0x83,0x05,0x83,0x03,0x81,0x03,0x81,0x04,0x81,0x04,0x85,0x02,0x81,0x01,0x82,0x04,0x83,0x03,0x84,0x04,0x84,0x03,0x84,0x03,0x83,0x03,0x85,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x01,0x81,0x05,0x81,0x01,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x85,0x04,0x81,0x06,0x81,0x06,0x81,0x17,0x81,0x0b,0x86,0x01,0x81,0x01,0x81,0x04,0x82,0x02,0x81,0x03,0x82,0x0d,0x81,0x07,0x81,0x04,0x83,0x05,0x81,0x1c,0x81,0x03,0x81,0x04,0x81,0x03,0x81,0x09,0x81,0x06,0x81,0x02,0x82,0x01,0x81,0x02,0x85,0x02,0x81,0x01,0x83,0x06,0x81,0x02,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x03,0x81,0x06,0x81,0x06,0x83,0x0a,0x83,0x06,0x82,0x02,0x81,0x04,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x06,0x81,0x06,0x81,0x04,0x81,0x03,0x81,0x08,0x81,0x02,0x81,0x01,0x81,0x04,0x81,0x06,0x81,0x01,0x82,0x01,0x81,0x01,0x81,0x01,0x81,0x02,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x01,0x82,0x07,0x81,0x04,0x81,0x04,0x81,0x02,0x81,0x02,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x03,0x82,0x04,0x81,0x01,0x81,0x06,0x81,0x05,0x81,0x06,0x81,0x06,0x81,0x19,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x82,0x05,0x81,0x03,0x81,0x02,0x82,0x02,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x02,0x82,0x02,0x81,0x04,0x81,0x07,0x81,0x03,0x81,0x02,0x81,0x05,0x81,0x04,0x81,0x01,0x81,0x01,0x81,0x02,0x82,0x02,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x03,0x82,0x02,0x81,0x01,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x01,0x81,0x05,0x81,0x02,0x81,0x01,0x81,0x03,0x81,0x03,0x81,0x06,0x81,0x04,0x81,0x06,0x81,0x06,0x81,0x17,0x81,0x0c,0x81,0x01,0x81,0x03,0x83,0x06,0x82,0x04,0x82,0x0d,0x81,0x07,0x81,0x03,0x81,0x01,0x81,0x01,0x81,0x04,0x81,0x1c,0x81,0x03,0x81,0x02,0x81,0x01,0x81,0x03,0x81,0x08,0x81,0x04,0x83,0x03,0x81,0x02,0x81,0x06,0x82,0x01,0x82,0x02,0x82,0x04,0x81,0x04,0x84,0x02,0x81,0x03,0x82,0x03,0x81,0x06,0x81,0x04,0x82,0x05,0x86,0x05,0x82,0x03,0x82,0x03,0x81,0x02,0x83,0x02,0x81,0x02,0x81,0x02,0x85,0x02,0x81,0x06,0x81,0x04,0x81,0x01,0x86,0x01,0x86,0x01,0x81,0x03,0x82,0x01,0x86,0x03,0x81,0x08,0x81,0x02,0x83,0x04,0x81,0x06,0x81,0x01,0x82,0x01,0x81,0x01,0x81,0x01,0x82,0x01,0x81,0x01,0x81,0x04,0x81,0x01,0x85,0x02,0x81,0x04,0x81,0x01,0x85,0x03,0x84,0x04,0x81,0x04,0x81,0x04,0x81,0x02,0x81,0x02,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x03,0x82,0x05,0x81,0x06,0x82,0x05,0x81,0x06,0x81,0x06,0x81,0x1d,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x06,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x04,0x81,0x07,0x81,0x03,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x01,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x03,0x81,0x05,0x81,0x08,0x81,0x04,0x81,0x03,0x81,0x03,0x81,0x01,0x81,0x03,0x81,0x01,0x81,0x01,0x81,0x03,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x03,0x82,0x07,0x81,0x07,0x82,0x02,0x83,0x10,0x81,0x0c,0x81,0x01,0x81,0x05,0x83,0x02,0x82,0x01,0x82,0x02,0x81,0x02,0x81,0x01,0x81,0x0a,0x81,0x07,0x81,0x05,0x81,0x03,0x87,0x09,0x83,0x0c,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x07,0x81,0x08,0x81,0x01,0x81,0x03,0x81,0x07,0x81,0x01,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x04,0x81,0x02,0x83,0x01,0x81,0x0f,0x82,0x10,0x82,0x03,0x81,0x04,0x81,0x01,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x02,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x03,0x81,0x08,0x81,0x02,0x81,0x02,0x81,0x03,0x81,0x06,0x81,0x01,0x82,0x01,0x81,0x01,0x81,0x02,0x81,0x01,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x03,0x81,0x07,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x02,0x81,0x02,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x03,0x82,0x05,0x81,0x06,0x81,0x06,0x81,0x07,0x81,0x05,0x81,0x1a,0x84,0x02,0x81,0x03,0x81,0x02,0x81,0x06,0x81,0x03,0x81,0x02,0x85,0x04,0x81,0x04,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x04,0x81,0x07,0x81,0x03,0x82,0x07,0x81,0x04,0x81,0x01,0x81,0x01,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x03,0x81,0x06,0x83,0x05,0x81,0x04,0x81,0x03,0x81,0x03,0x81,0x01,0x81,0x03,0x81,0x01,0x81,0x01,0x81,0x04,0x81,0x05,0x81,0x01,0x81,0x05,0x81,0x06,0x81,0x06,0x81,0x06,0x81,0x07,0x83,0x18,0x86,0x04,0x81,0x01,0x81,0x04,0x81,0x02,0x81,0x01,0x81,0x02,0x83,0x0a,0x81,0x07,0x81,0x0c,0x81,0x1b,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x06,0x81,0x09,0x81,0x01,0x86,0x06,0x81,0x01,0x81,0x04,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x06,0x81,0x11,0x83,0x02,0x86,0x02,0x83,0x0a,0x81,0x01,0x81,0x02,0x81,0x02,0x84,0x02,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x03,0x81,0x08,0x81,0x02,0x81,0x02,0x82,0x02,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x02,0x81,0x01,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x06,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x03,0x82,0x03,0x82,0x01,0x82,0x03,0x81,0x02,0x81,0x04,0x81,0x05,0x81,0x07,0x81,0x07,0x81,0x05,0x81,0x19,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x06,0x81,0x03,0x81,0x02,0x81,0x08,0x81,0x04,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x04,0x81,0x07,0x81,0x03,0x81,0x01,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x01,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x03,0x81,0x09,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x03,0x81,0x01,0x81,0x03,0x82,0x01,0x82,0x03,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x07,0x81,0x06,0x81,0x06,0x81,0x17,0x81,0x0b,0x81,0x02,0x81,0x03,0x81,0x01,0x81,0x01,0x81,0x04,0x81,0x02,0x81,0x01,0x82,0x02,0x81,0x0c,0x81,0x05,0x81,0x0d,0x81,0x06,0x81,0x0d,0x81,0x05,0x81,0x06,0x81,0x02,0x81,0x04,0x81,0x05,0x81,0x05,0x81,0x04,0x81,0x05,0x81,0x02,0x81,0x03,0x82,0x02,0x81,0x02,0x82,0x03,0x81,0x04,0x81,0x04,0x81,0x01,0x81,0x03,0x81,0x04,0x81,0x06,0x81,0x09,0x81,0x08,0x81,0x08,0x81,0x04,0x81,0x02,0x83,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x02,0x81,0x03,0x81,0x01,0x81,0x03,0x81,0x02,0x81,0x06,0x81,0x07,0x81,0x03,0x81,0x01,0x81,0x04,0x81,0x03,0x81,0x04,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x06,0x81,0x04,0x81,0x01,0x81,0x03,0x82,0x02,0x81,0x02,0x81,0x02,0x81,0x07,0x81,0x02,0x82,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x03,0x82,0x03,0x81,0x03,0x81,0x03,0x81,0x02,0x81,0x04,0x81,0x04,0x82,0x07,0x81,0x08,0x81,0x04,0x81,0x19,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x82,0x05,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x04,0x81,0x07,0x81,0x03,0x81,0x02,0x81,0x05,0x81,0x04,0x81,0x01,0x81,0x01,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x03,0x81,0x05,0x81,0x03,0x81,0x04,0x81,0x04,0x81,0x03,0x81,0x04,0x81,0x05,0x81,0x01,0x81,0x04,0x81,0x01,0x81,0x04,0x82,0x04,0x81,0x08,0x81,0x06,0x81,0x06,0x81,0x17,0x81,0x0b,0x81,0x01,0x81,0x05,0x83,0x06,0x82,0x03,0x83,0x01,0x81,0x0b,0x81,0x05,0x81,0x0d,0x81,0x06,0x81,0x0d,0x81,0x05,0x81,0x06,0x84,0x02,0x85,0x02,0x86,0x02,0x84,0x06,0x81,0x03,0x84,0x03,0x84,0x03,0x81,0x06,0x84,0x03,0x83,0x05,0x81,0x06,0x81,0x1b,0x81,0x04,0x82,0x05,0x81,0x04,0x81,0x01,0x85,0x04,0x83,0x02,0x84,0x03,0x86,0x01,0x81,0x08,0x83,0x02,0x81,0x04,0x81,0x01,0x85,0x03,0x83,0x03,0x81,0x04,0x81,0x01,0x86,0x01,0x81,0x04,0x81,0x01,0x81,0x03,0x82,0x02,0x84,0x02,0x81,0x07,0x84,0x02,0x81,0x05,0x81,0x01,0x84,0x04,0x81,0x05,0x84,0x04,0x82,0x03,0x81,0x03,0x81,0x02,0x81,0x04,0x81,0x03,0x81,0x04,0x86,0x03,0x81,0x08,0x81,0x04,0x81,0x1a,0x84,0x02,0x84,0x04,0x83,0x04,0x84,0x03,0x83,0x05,0x81,0x05,0x84,0x02,0x81,0x03,0x81,0x02,0x85,0x05,0x81,0x03,0x81,0x03,0x81,0x05,0x82,0x02,0x81,0x01,0x81,0x01,0x81,0x02,0x81,0x03,0x81,0x03,0x83,0x03,0x84,0x04,0x84,0x03,0x81,0x06,0x83,0x05,0x83,0x03,0x84,0x04,0x81,0x05,0x81,0x01,0x81,0x03,0x81,0x03,0x81,0x04,0x81,0x04,0x85,0x04,0x81,0x06,0x81,0x06,0x81,0x2c,0x81,0x1c,0x82,0x03,0x82,0x13,0x81,0x13,0x81,0x54,0x81,0x22,0x81,0x79,0x81,0x43,0x82,0x08,0x81,0x02,0x82,0x47,0x81,0x13,0x81,0x26,0x81,0x0a,0x81,0x35,0x81,0x0d,0x83,0x04,0x81,0x04,0x83,0x2c,0x81,0x7f,0x44,0x83,0x76,0x81,0x7f,0x17,0x81,0x02,0x81,0x13,0x81,0x26,0x81,0x0a,0x81,0x34,0x81,0x15,0x81,0x7f,0x7f,0x7f,0x50,0x87,0x34,0x82,0x12,0x82,0x27,0x81,0x0a,0x81,0x33,0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x4b,0x00,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x00,0x49,0x44,0x41,0x54,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0x00,0x00,0x00,0x00,0x50,0x4c,0x54,0x45,0x00,0x00,0x00,0x00,0x62,0x4b,0x47,0x44,0x00,0x00,0x00,0x00,0x63,0x48,0x52,0x4d,0x00,0x00,0x00,0x00,0x67,0x41,0x4d,0x41,0x00,0x00,0x00,0x00,0x68,0x49,0x53,0x54,0x00,0x00,0x00,0x00,0x69,0x43,0x43,0x50,0x00,0x00,0x00,0x00,0x69,0x54,0x58,0x74,0x00,0x00,0x00,0x00,0x6f,0x46,0x46,0x73,0x00,0x00,0x00,0x00,0x70,0x43,0x41,0x4c,0x00,0x00,0x00,0x00,0x73,0x43,0x41,0x4c,0x00,0x00,0x00,0x00,0x70,0x48,0x59,0x73,0x00,0x00,0x00,0x00,0x73,0x42,0x49,0x54,0x00,0x00,0x00,0x00,0x73,0x50,0x4c,0x54,0x00,0x00,0x00,0x00,0x73,0x52,0x47,0x42,0x00,0x00,0x00,0x00,0x74,0x45,0x58,0x74,0x00,0x00,0x00,0x00,0x74,0x49,0x4d,0x45,0x00,0x00,0x00,0x00,0x74,0x52,0x4e,0x53,0x00,0x00,0x00,0x00,0x7a,0x54,0x58,0x74,0x00, + } +}; diff --git a/minuitwrp/graphics.c b/minuitwrp/graphics.c new file mode 100644 index 000000000..1465ce99b --- /dev/null +++ b/minuitwrp/graphics.c @@ -0,0 +1,929 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> + +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/types.h> + +#include <linux/fb.h> +#include <linux/kd.h> + +#include <pixelflinger/pixelflinger.h> + +#include "minui.h" + +#ifdef BOARD_USE_CUSTOM_RECOVERY_FONT +#include BOARD_USE_CUSTOM_RECOVERY_FONT +#else +#include "font_10x18.h" +#endif + +#ifdef RECOVERY_BGRA +#define PIXEL_FORMAT GGL_PIXEL_FORMAT_BGRA_8888 +#define PIXEL_SIZE 4 +#endif +#ifdef RECOVERY_RGBX +#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGBX_8888 +#define PIXEL_SIZE 4 +#endif +#ifndef PIXEL_FORMAT +#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGB_565 +#define PIXEL_SIZE 2 +#endif + +#define NUM_BUFFERS 2 +#define MAX_DISPLAY_DIM 2048 + +// #define PRINT_SCREENINFO 1 // Enables printing of screen info to log + +typedef struct { + int type; + GGLSurface texture; + unsigned offset[97]; + unsigned cheight; + unsigned ascent; +} GRFont; + +static GRFont *gr_font = 0; +static GGLContext *gr_context = 0; +static GGLSurface gr_font_texture; +static GGLSurface gr_framebuffer[NUM_BUFFERS]; +GGLSurface gr_mem_surface; +static unsigned gr_active_fb = 0; +static unsigned double_buffering = 0; +static int gr_is_curr_clr_opaque = 0; + +static int gr_fb_fd = -1; +static int gr_vt_fd = -1; + +struct fb_var_screeninfo vi; +static struct fb_fix_screeninfo fi; + +static bool has_overlay = false; +static int leftSplit = 0; +static int rightSplit = 0; + +bool target_has_overlay(char *version); +int free_ion_mem(void); +int alloc_ion_mem(unsigned int size); +int allocate_overlay(int fd, GGLSurface gr_fb[]); +int free_overlay(int fd); +int overlay_display_frame(int fd, GGLubyte* data, size_t size); + +#ifdef PRINT_SCREENINFO +static void print_fb_var_screeninfo() +{ + printf("vi.xres: %d\n", vi.xres); + printf("vi.yres: %d\n", vi.yres); + printf("vi.xres_virtual: %d\n", vi.xres_virtual); + printf("vi.yres_virtual: %d\n", vi.yres_virtual); + printf("vi.xoffset: %d\n", vi.xoffset); + printf("vi.yoffset: %d\n", vi.yoffset); + printf("vi.bits_per_pixel: %d\n", vi.bits_per_pixel); + printf("vi.grayscale: %d\n", vi.grayscale); +} +#endif + +#ifdef MSM_BSP +int getLeftSplit(void) { + //Default even split for all displays with high res + int lSplit = vi.xres / 2; + + //Override if split published by driver + if (leftSplit) + lSplit = leftSplit; + + return lSplit; +} + +int getRightSplit(void) { + return rightSplit; +} + + +void setDisplaySplit(void) { + char split[64] = {0}; + FILE* fp = fopen("/sys/class/graphics/fb0/msm_fb_split", "r"); + if (fp) { + //Format "left right" space as delimiter + if(fread(split, sizeof(char), 64, fp)) { + leftSplit = atoi(split); + printf("Left Split=%d\n",leftSplit); + char *rght = strpbrk(split, " "); + if (rght) + rightSplit = atoi(rght + 1); + printf("Right Split=%d\n", rightSplit); + } + } else { + printf("Failed to open mdss_fb_split node\n"); + } + if (fp) + fclose(fp); +} + +bool isDisplaySplit(void) { + if (vi.xres > MAX_DISPLAY_DIM) + return true; + //check if right split is set by driver + if (getRightSplit()) + return true; + + return false; +} + +int getFbXres(void) { + return vi.xres; +} + +int getFbYres (void) { + return vi.yres; +} +#endif // MSM_BSP + +static int get_framebuffer(GGLSurface *fb) +{ + int fd, index = 0; + void *bits; + + fd = open("/dev/graphics/fb0", O_RDWR); + while (fd < 0 && index < 10) { + usleep(1000); + fd = open("/dev/graphics/fb0", O_RDWR); + index++; + } + if (fd < 0) { + perror("cannot open fb0\n"); + return -1; + } + + if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) { + perror("failed to get fb0 info"); + close(fd); + return -1; + } + + fprintf(stderr, "Pixel format: %dx%d @ %dbpp\n", vi.xres, vi.yres, vi.bits_per_pixel); + + vi.bits_per_pixel = PIXEL_SIZE * 8; + if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_BGRA_8888) { + fprintf(stderr, "Pixel format: BGRA_8888\n"); + if (PIXEL_SIZE != 4) fprintf(stderr, "E: Pixel Size mismatch!\n"); + vi.red.offset = 8; + vi.red.length = 8; + vi.green.offset = 16; + vi.green.length = 8; + vi.blue.offset = 24; + vi.blue.length = 8; + vi.transp.offset = 0; + vi.transp.length = 8; + } else if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_RGBX_8888) { + fprintf(stderr, "Pixel format: RGBX_8888\n"); + if (PIXEL_SIZE != 4) fprintf(stderr, "E: Pixel Size mismatch!\n"); + vi.red.offset = 24; + vi.red.length = 8; + vi.green.offset = 16; + vi.green.length = 8; + vi.blue.offset = 8; + vi.blue.length = 8; + vi.transp.offset = 0; + vi.transp.length = 8; + } else if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_RGB_565) { +#ifdef RECOVERY_RGB_565 + fprintf(stderr, "Pixel format: RGB_565\n"); + vi.blue.offset = 0; + vi.green.offset = 5; + vi.red.offset = 11; +#else + fprintf(stderr, "Pixel format: BGR_565\n"); + vi.blue.offset = 11; + vi.green.offset = 5; + vi.red.offset = 0; +#endif + if (PIXEL_SIZE != 2) fprintf(stderr, "E: Pixel Size mismatch!\n"); + vi.blue.length = 5; + vi.green.length = 6; + vi.red.length = 5; + vi.blue.msb_right = 0; + vi.green.msb_right = 0; + vi.red.msb_right = 0; + vi.transp.offset = 0; + vi.transp.length = 0; + } + else + { + perror("unknown pixel format"); + close(fd); + return -1; + } + + vi.vmode = FB_VMODE_NONINTERLACED; + vi.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; + + if (ioctl(fd, FBIOPUT_VSCREENINFO, &vi) < 0) { + perror("failed to put fb0 info"); + close(fd); + return -1; + } + + if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) { + perror("failed to get fb0 info"); + close(fd); + return -1; + } + +#ifdef MSM_BSP + has_overlay = target_has_overlay(fi.id); + + if (isTargetMdp5()) + setDisplaySplit(); +#else + has_overlay = false; +#endif + + if (!has_overlay) { + printf("Not using qualcomm overlay, '%s'\n", fi.id); + bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (bits == MAP_FAILED) { + perror("failed to mmap framebuffer"); + close(fd); + return -1; + } + } else { + printf("Using qualcomm overlay\n"); + } + +#ifdef RECOVERY_GRAPHICS_USE_LINELENGTH + vi.xres_virtual = fi.line_length / PIXEL_SIZE; +#endif + + fb->version = sizeof(*fb); + fb->width = vi.xres; + fb->height = vi.yres; +#ifdef BOARD_HAS_JANKY_BACKBUFFER + printf("setting JANKY BACKBUFFER\n"); + fb->stride = fi.line_length/2; +#else + fb->stride = vi.xres_virtual; +#endif + fb->format = PIXEL_FORMAT; + if (!has_overlay) { + fb->data = bits; + memset(fb->data, 0, vi.yres * fb->stride * PIXEL_SIZE); + } + + fb++; + + /* check if we can use double buffering */ + if (vi.yres * fi.line_length * 2 > fi.smem_len) + return fd; + + double_buffering = 1; + + fb->version = sizeof(*fb); + fb->width = vi.xres; + fb->height = vi.yres; +#ifdef BOARD_HAS_JANKY_BACKBUFFER + fb->stride = fi.line_length/2; + fb->data = (GGLubyte*) (((unsigned long) bits) + vi.yres * fi.line_length); +#else + fb->stride = vi.xres_virtual; + fb->data = (GGLubyte*) (((unsigned long) bits) + vi.yres * fb->stride * PIXEL_SIZE); +#endif + fb->format = PIXEL_FORMAT; + if (!has_overlay) { + memset(fb->data, 0, vi.yres * fb->stride * PIXEL_SIZE); + } + +#ifdef PRINT_SCREENINFO + print_fb_var_screeninfo(); +#endif + + return fd; +} + +static void get_memory_surface(GGLSurface* ms) { + ms->version = sizeof(*ms); + ms->width = vi.xres; + ms->height = vi.yres; + ms->stride = vi.xres_virtual; + ms->data = malloc(vi.xres_virtual * vi.yres * PIXEL_SIZE); + ms->format = PIXEL_FORMAT; +} + +static void set_active_framebuffer(unsigned n) +{ + if (n > 1 || !double_buffering) return; + vi.yres_virtual = vi.yres * NUM_BUFFERS; + vi.yoffset = n * vi.yres; +// vi.bits_per_pixel = PIXEL_SIZE * 8; + if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) { + perror("active fb swap failed"); + } +} + +void gr_flip(void) +{ + if (-EINVAL == overlay_display_frame(gr_fb_fd, gr_mem_surface.data, + (fi.line_length * vi.yres))) { + GGLContext *gl = gr_context; + + /* swap front and back buffers */ + if (double_buffering) + gr_active_fb = (gr_active_fb + 1) & 1; + +#ifdef BOARD_HAS_FLIPPED_SCREEN + /* flip buffer 180 degrees for devices with physicaly inverted screens */ + unsigned int i; + unsigned int j; + for (i = 0; i < vi.yres; i++) { + for (j = 0; j < vi.xres; j++) { + memcpy(gr_framebuffer[gr_active_fb].data + (i * vi.xres_virtual + j) * PIXEL_SIZE, + gr_mem_surface.data + ((vi.yres - i - 1) * vi.xres_virtual + vi.xres - j - 1) * PIXEL_SIZE, PIXEL_SIZE); + } + } +#else + /* copy data from the in-memory surface to the buffer we're about + * to make active. */ + memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data, + vi.xres_virtual * vi.yres * PIXEL_SIZE); +#endif + + /* inform the display driver */ + set_active_framebuffer(gr_active_fb); + } +} + +void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + GGLContext *gl = gr_context; + GGLint color[4]; + color[0] = ((r << 8) | r) + 1; + color[1] = ((g << 8) | g) + 1; + color[2] = ((b << 8) | b) + 1; + color[3] = ((a << 8) | a) + 1; + gl->color4xv(gl, color); + + gr_is_curr_clr_opaque = (a == 255); +} + +int gr_measureEx(const char *s, void* font) +{ + GRFont* fnt = (GRFont*) font; + int total = 0; + unsigned pos; + unsigned off; + + if (!fnt) fnt = gr_font; + +#ifndef TW_DISABLE_TTF + if(fnt->type == FONT_TYPE_TTF) + return gr_ttf_measureEx(s, font); +#endif + + while ((off = *s++)) + { + off -= 32; + if (off < 96) + total += (fnt->offset[off+1] - fnt->offset[off]); + } + return total; +} + +int gr_maxExW(const char *s, void* font, int max_width) +{ + GRFont* fnt = (GRFont*) font; + int total = 0; + unsigned pos; + unsigned off; + + if (!fnt) fnt = gr_font; + +#ifndef TW_DISABLE_TTF + if(fnt->type == FONT_TYPE_TTF) + return gr_ttf_maxExW(s, font, max_width); +#endif + + while ((off = *s++)) + { + off -= 32; + if (off < 96) { + max_width -= (fnt->offset[off+1] - fnt->offset[off]); + if (max_width > 0) { + total++; + } else { + return total; + } + } + } + return total; +} + +int gr_textEx(int x, int y, const char *s, void* pFont) +{ + GGLContext *gl = gr_context; + GRFont *font = (GRFont*) pFont; + unsigned off; + unsigned cwidth; + + /* Handle default font */ + if (!font) font = gr_font; + +#ifndef TW_DISABLE_TTF + if(font->type == FONT_TYPE_TTF) + return gr_ttf_textExWH(gl, x, y, s, pFont, -1, -1); +#endif + + gl->bindTexture(gl, &font->texture); + gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); + gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->enable(gl, GGL_TEXTURE_2D); + + while((off = *s++)) { + off -= 32; + cwidth = 0; + if (off < 96) { + cwidth = font->offset[off+1] - font->offset[off]; + gl->texCoord2i(gl, (font->offset[off]) - x, 0 - y); + gl->recti(gl, x, y, x + cwidth, y + font->cheight); + x += cwidth; + } + } + + gl->disable(gl, GGL_TEXTURE_2D); + + return x; +} + +int gr_textExW(int x, int y, const char *s, void* pFont, int max_width) +{ + GGLContext *gl = gr_context; + GRFont *font = (GRFont*) pFont; + unsigned off; + unsigned cwidth; + + /* Handle default font */ + if (!font) font = gr_font; + +#ifndef TW_DISABLE_TTF + if(font->type == FONT_TYPE_TTF) + return gr_ttf_textExWH(gl, x, y, s, pFont, max_width, -1); +#endif + + gl->bindTexture(gl, &font->texture); + gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); + gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->enable(gl, GGL_TEXTURE_2D); + + while((off = *s++)) { + off -= 32; + cwidth = 0; + if (off < 96) { + cwidth = font->offset[off+1] - font->offset[off]; + if ((x + (int)cwidth) < max_width) { + gl->texCoord2i(gl, (font->offset[off]) - x, 0 - y); + gl->recti(gl, x, y, x + cwidth, y + font->cheight); + x += cwidth; + } else { + gl->texCoord2i(gl, (font->offset[off]) - x, 0 - y); + gl->recti(gl, x, y, max_width, y + font->cheight); + x = max_width; + return x; + } + } + } + + gl->disable(gl, GGL_TEXTURE_2D); + + return x; +} + +int gr_textExWH(int x, int y, const char *s, void* pFont, int max_width, int max_height) +{ + GGLContext *gl = gr_context; + GRFont *font = (GRFont*) pFont; + unsigned off; + unsigned cwidth; + int rect_x, rect_y; + + /* Handle default font */ + if (!font) font = gr_font; + +#ifndef TW_DISABLE_TTF + if(font->type == FONT_TYPE_TTF) + return gr_ttf_textExWH(gl, x, y, s, pFont, max_width, max_height); +#endif + + gl->bindTexture(gl, &font->texture); + gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); + gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->enable(gl, GGL_TEXTURE_2D); + + while((off = *s++)) { + off -= 32; + cwidth = 0; + if (off < 96) { + cwidth = font->offset[off+1] - font->offset[off]; + if ((x + (int)cwidth) < max_width) + rect_x = x + cwidth; + else + rect_x = max_width; + if (y + font->cheight < (unsigned int)(max_height)) + rect_y = y + font->cheight; + else + rect_y = max_height; + + gl->texCoord2i(gl, (font->offset[off]) - x, 0 - y); + gl->recti(gl, x, y, rect_x, rect_y); + x += cwidth; + if (x > max_width) + return x; + } + } + + gl->disable(gl, GGL_TEXTURE_2D); + + return x; +} + +void gr_clip(int x, int y, int w, int h) +{ + GGLContext *gl = gr_context; + gl->scissor(gl, x, y, w, h); + gl->enable(gl, GGL_SCISSOR_TEST); +} + +void gr_noclip() +{ + GGLContext *gl = gr_context; + gl->scissor(gl, 0, 0, gr_fb_width(), gr_fb_height()); + gl->disable(gl, GGL_SCISSOR_TEST); +} + +void gr_fill(int x, int y, int w, int h) +{ + GGLContext *gl = gr_context; + + if(gr_is_curr_clr_opaque) + gl->disable(gl, GGL_BLEND); + + gl->recti(gl, x, y, x + w, y + h); + + if(gr_is_curr_clr_opaque) + gl->enable(gl, GGL_BLEND); +} + +void gr_line(int x0, int y0, int x1, int y1, int width) +{ + GGLContext *gl = gr_context; + + if(gr_is_curr_clr_opaque) + gl->disable(gl, GGL_BLEND); + + const int coords0[2] = { x0 << 4, y0 << 4 }; + const int coords1[2] = { x1 << 4, y1 << 4 }; + gl->linex(gl, coords0, coords1, width << 4); + + if(gr_is_curr_clr_opaque) + gl->enable(gl, GGL_BLEND); +} + +gr_surface gr_render_circle(int radius, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + int rx, ry; + GGLSurface *surface; + const int diameter = radius*2 + 1; + const int radius_check = radius*radius + radius*0.8; + const uint32_t px = (a << 24) | (b << 16) | (g << 8) | r; + uint32_t *data; + + surface = malloc(sizeof(GGLSurface)); + memset(surface, 0, sizeof(GGLSurface)); + + data = malloc(diameter * diameter * 4); + memset(data, 0, diameter * diameter * 4); + + surface->version = sizeof(surface); + surface->width = diameter; + surface->height = diameter; + surface->stride = diameter; + surface->data = (GGLubyte*)data; + surface->format = GGL_PIXEL_FORMAT_RGBA_8888; + + for(ry = -radius; ry <= radius; ++ry) + for(rx = -radius; rx <= radius; ++rx) + if(rx*rx+ry*ry <= radius_check) + *(data + diameter*(radius + ry) + (radius+rx)) = px; + + return surface; +} + +void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) { + if (gr_context == NULL) { + return; + } + + GGLContext *gl = gr_context; + GGLSurface *surface = (GGLSurface*)source; + + if(surface->format == GGL_PIXEL_FORMAT_RGBX_8888) + gl->disable(gl, GGL_BLEND); + + gl->bindTexture(gl, surface); + gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); + gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->enable(gl, GGL_TEXTURE_2D); + gl->texCoord2i(gl, sx - dx, sy - dy); + gl->recti(gl, dx, dy, dx + w, dy + h); + gl->disable(gl, GGL_TEXTURE_2D); + + if(surface->format == GGL_PIXEL_FORMAT_RGBX_8888) + gl->enable(gl, GGL_BLEND); +} + +unsigned int gr_get_width(gr_surface surface) { + if (surface == NULL) { + return 0; + } + return ((GGLSurface*) surface)->width; +} + +unsigned int gr_get_height(gr_surface surface) { + if (surface == NULL) { + return 0; + } + return ((GGLSurface*) surface)->height; +} + +void* gr_loadFont(const char* fontName) +{ + int fd; + GRFont *font = 0; + GGLSurface *ftex; + unsigned char *bits, *rle; + unsigned char *in, data; + unsigned width, height; + unsigned element; + + fd = open(fontName, O_RDONLY); + if (fd == -1) + { + char tmp[128]; + + sprintf(tmp, TWRES "fonts/%s.dat", fontName); + fd = open(tmp, O_RDONLY); + if (fd == -1) + return NULL; + } + + font = calloc(sizeof(*font), 1); + ftex = &font->texture; + + read(fd, &width, sizeof(unsigned)); + read(fd, &height, sizeof(unsigned)); + read(fd, font->offset, sizeof(unsigned) * 96); + font->offset[96] = width; + + bits = malloc(width * height); + memset(bits, 0, width * height); + + unsigned pos = 0; + while (pos < width * height) + { + int bit; + + read(fd, &data, 1); + for (bit = 0; bit < 8; bit++) + { + if (data & (1 << (7-bit))) bits[pos++] = 255; + else bits[pos++] = 0; + + if (pos == width * height) break; + } + } + close(fd); + + ftex->version = sizeof(*ftex); + ftex->width = width; + ftex->height = height; + ftex->stride = width; + ftex->data = (void*) bits; + ftex->format = GGL_PIXEL_FORMAT_A_8; + font->type = FONT_TYPE_TWRP; + font->cheight = height; + font->ascent = height - 2; + return (void*) font; +} + +void gr_freeFont(void *font) +{ + GRFont *f = font; + free(f->texture.data); + free(f); +} + +int gr_getMaxFontHeight(void *font) +{ + GRFont *fnt = (GRFont*) font; + + if (!fnt) fnt = gr_font; + if (!fnt) return -1; + +#ifndef TW_DISABLE_TTF + if(fnt->type == FONT_TYPE_TTF) + return gr_ttf_getMaxFontHeight(font); +#endif + + return fnt->cheight; +} + +static void gr_init_font(void) +{ + int fontRes; + GGLSurface *ftex; + unsigned char *bits, *rle; + unsigned char *in, data; + unsigned width, height; + unsigned element; + + gr_font = calloc(sizeof(*gr_font), 1); + ftex = &gr_font->texture; + + width = font.width; + height = font.height; + + bits = malloc(width * height); + rle = bits; + + in = font.rundata; + while((data = *in++)) + { + memset(rle, (data & 0x80) ? 255 : 0, data & 0x7f); + rle += (data & 0x7f); + } + for (element = 0; element < 97; element++) + { + gr_font->offset[element] = (element * font.cwidth); + } + + ftex->version = sizeof(*ftex); + ftex->width = width; + ftex->height = height; + ftex->stride = width; + ftex->data = (void*) bits; + ftex->format = GGL_PIXEL_FORMAT_A_8; + gr_font->type = FONT_TYPE_TWRP; + gr_font->cheight = height; + gr_font->ascent = height - 2; + return; +} + +int gr_init(void) +{ + gglInit(&gr_context); + GGLContext *gl = gr_context; + + gr_init_font(); + gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC); + if (gr_vt_fd < 0) { + // This is non-fatal; post-Cupcake kernels don't have tty0. + } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) { + // However, if we do open tty0, we expect the ioctl to work. + perror("failed KDSETMODE to KD_GRAPHICS on tty0"); + gr_exit(); + return -1; + } + + gr_fb_fd = get_framebuffer(gr_framebuffer); + if (gr_fb_fd < 0) { + perror("Unable to get framebuffer.\n"); + gr_exit(); + return -1; + } + + get_memory_surface(&gr_mem_surface); + + fprintf(stderr, "framebuffer: fd %d (%d x %d)\n", + gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height); + + /* start with 0 as front (displayed) and 1 as back (drawing) */ + gr_active_fb = 0; + if (!has_overlay) + set_active_framebuffer(0); + gl->colorBuffer(gl, &gr_mem_surface); + + gl->activeTexture(gl, 0); + gl->enable(gl, GGL_BLEND); + gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA); + +#ifdef TW_SCREEN_BLANK_ON_BOOT + printf("TW_SCREEN_BLANK_ON_BOOT := true\n"); + gr_fb_blank(true); + gr_fb_blank(false); +#endif + + if (!alloc_ion_mem(fi.line_length * vi.yres)) + allocate_overlay(gr_fb_fd, gr_framebuffer); + + return 0; +} + +void gr_exit(void) +{ + free_overlay(gr_fb_fd); + free_ion_mem(); + + close(gr_fb_fd); + gr_fb_fd = -1; + + free(gr_mem_surface.data); + + ioctl(gr_vt_fd, KDSETMODE, (void*) KD_TEXT); + close(gr_vt_fd); + gr_vt_fd = -1; +} + +int gr_fb_width(void) +{ + return gr_framebuffer[0].width; +} + +int gr_fb_height(void) +{ + return gr_framebuffer[0].height; +} + +gr_pixel *gr_fb_data(void) +{ + return (unsigned short *) gr_mem_surface.data; +} + +int gr_fb_blank(int blank) +{ + int ret; + //if (blank) + //free_overlay(gr_fb_fd); + + ret = ioctl(gr_fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK); + if (ret < 0) + perror("ioctl(): blank"); + + //if (!blank) + //allocate_overlay(gr_fb_fd, gr_framebuffer); + return ret; +} + +int gr_get_surface(gr_surface* surface) +{ + GGLSurface* ms = malloc(sizeof(GGLSurface)); + if (!ms) return -1; + + // Allocate the data + get_memory_surface(ms); + + // Now, copy the data + memcpy(ms->data, gr_mem_surface.data, vi.xres * vi.yres * vi.bits_per_pixel / 8); + + *surface = (gr_surface*) ms; + return 0; +} + +int gr_free_surface(gr_surface surface) +{ + if (!surface) + return -1; + + GGLSurface* ms = (GGLSurface*) surface; + free(ms->data); + free(ms); + return 0; +} + +void gr_write_frame_to_file(int fd) +{ + write(fd, gr_mem_surface.data, vi.xres * vi.yres * vi.bits_per_pixel / 8); +} diff --git a/minuitwrp/graphics_overlay.c b/minuitwrp/graphics_overlay.c new file mode 100644 index 000000000..05c5472dc --- /dev/null +++ b/minuitwrp/graphics_overlay.c @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> + +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/types.h> + +#include <linux/fb.h> +#include <linux/kd.h> + +#ifdef MSM_BSP +#include <linux/msm_mdp.h> +#include <linux/msm_ion.h> +#endif + +#include <pixelflinger/pixelflinger.h> + +#include "minui.h" + +#define MDP_V4_0 400 + +#ifdef MSM_BSP +#define ALIGN(x, align) (((x) + ((align)-1)) & ~((align)-1)) + +typedef struct { + unsigned char *mem_buf; + int size; + int ion_fd; + int mem_fd; + struct ion_handle_data handle_data; +} memInfo; + +//Left and right overlay id +static int overlayL_id = MSMFB_NEW_REQUEST; +static int overlayR_id = MSMFB_NEW_REQUEST; + +static memInfo mem_info; + +static int map_mdp_pixel_format() +{ + int format = MDP_RGB_565; +#if defined(RECOVERY_BGRA) + format = MDP_BGRA_8888; +#elif defined(RECOVERY_RGBX) + format = MDP_RGBA_8888; +#endif + return format; +} + +static bool overlay_supported = false; +static bool isMDP5 = false; + +bool target_has_overlay(char *version) +{ + int ret; + int mdp_version; + + if (strlen(version) >= 8) { + if(!strncmp(version, "msmfb", strlen("msmfb"))) { + char str_ver[4]; + memcpy(str_ver, version + strlen("msmfb"), 3); + str_ver[3] = '\0'; + mdp_version = atoi(str_ver); + if (mdp_version >= MDP_V4_0) { + overlay_supported = true; + } + } else if (!strncmp(version, "mdssfb", strlen("mdssfb"))) { + overlay_supported = true; + isMDP5 = true; + } + } + if (overlay_supported) printf("Using qcomm overlay\n"); + return overlay_supported; +} + +bool isTargetMdp5() +{ + if (isMDP5) + return true; + + return false; +} + +int free_ion_mem(void) { + if (!overlay_supported) + return -EINVAL; + + int ret = 0; + + if (mem_info.mem_buf) + munmap(mem_info.mem_buf, mem_info.size); + + if (mem_info.ion_fd >= 0) { + ret = ioctl(mem_info.ion_fd, ION_IOC_FREE, &mem_info.handle_data); + if (ret < 0) + perror("free_mem failed "); + } + + if (mem_info.mem_fd >= 0) + close(mem_info.mem_fd); + if (mem_info.ion_fd >= 0) + close(mem_info.ion_fd); + + memset(&mem_info, 0, sizeof(mem_info)); + mem_info.mem_fd = -1; + mem_info.ion_fd = -1; + return 0; +} + +int alloc_ion_mem(unsigned int size) +{ + if (!overlay_supported) + return -EINVAL; + int result; + struct ion_fd_data fd_data; + struct ion_allocation_data ionAllocData; + + mem_info.ion_fd = open("/dev/ion", O_RDWR|O_DSYNC); + if (mem_info.ion_fd < 0) { + perror("ERROR: Can't open ion "); + return -errno; + } + + ionAllocData.flags = 0; + ionAllocData.len = size; + ionAllocData.align = sysconf(_SC_PAGESIZE); + ionAllocData.heap_mask = + ION_HEAP(ION_IOMMU_HEAP_ID) | + ION_HEAP(ION_SYSTEM_CONTIG_HEAP_ID); + + result = ioctl(mem_info.ion_fd, ION_IOC_ALLOC, &ionAllocData); + if(result){ + perror("ION_IOC_ALLOC Failed "); + close(mem_info.ion_fd); + return result; + } + + fd_data.handle = ionAllocData.handle; + mem_info.handle_data.handle = ionAllocData.handle; + result = ioctl(mem_info.ion_fd, ION_IOC_MAP, &fd_data); + if (result) { + perror("ION_IOC_MAP Failed "); + free_ion_mem(); + return result; + } + mem_info.mem_buf = (unsigned char *)mmap(NULL, size, PROT_READ | + PROT_WRITE, MAP_SHARED, fd_data.fd, 0); + mem_info.mem_fd = fd_data.fd; + + if (!mem_info.mem_buf) { + perror("ERROR: mem_buf MAP_FAILED "); + free_ion_mem(); + return -ENOMEM; + } + + return 0; +} + +int allocate_overlay(int fd, GGLSurface gr_fb[]) +{ + int ret = 0; + + if (!overlay_supported) + return -EINVAL; + + if (!isDisplaySplit()) { + // Check if overlay is already allocated + if (MSMFB_NEW_REQUEST == overlayL_id) { + struct mdp_overlay overlayL; + + memset(&overlayL, 0 , sizeof (struct mdp_overlay)); + + /* Fill Overlay Data */ + overlayL.src.width = ALIGN(gr_fb[0].width, 32); + overlayL.src.height = gr_fb[0].height; + overlayL.src.format = map_mdp_pixel_format(); + overlayL.src_rect.w = gr_fb[0].width; + overlayL.src_rect.h = gr_fb[0].height; + overlayL.dst_rect.w = gr_fb[0].width; + overlayL.dst_rect.h = gr_fb[0].height; + overlayL.alpha = 0xFF; + overlayL.transp_mask = MDP_TRANSP_NOP; + overlayL.id = MSMFB_NEW_REQUEST; + ret = ioctl(fd, MSMFB_OVERLAY_SET, &overlayL); + if (ret < 0) { + perror("Overlay Set Failed"); + return ret; + } + overlayL_id = overlayL.id; + } + } else { + float xres = getFbXres(); + int lSplit = getLeftSplit(); + float lSplitRatio = lSplit / xres; + float lCropWidth = gr_fb[0].width * lSplitRatio; + int lWidth = lSplit; + int rWidth = gr_fb[0].width - lSplit; + int height = gr_fb[0].height; + + if (MSMFB_NEW_REQUEST == overlayL_id) { + + struct mdp_overlay overlayL; + + memset(&overlayL, 0 , sizeof (struct mdp_overlay)); + + /* Fill OverlayL Data */ + overlayL.src.width = ALIGN(gr_fb[0].width, 32); + overlayL.src.height = gr_fb[0].height; + overlayL.src.format = map_mdp_pixel_format(); + overlayL.src_rect.x = 0; + overlayL.src_rect.y = 0; + overlayL.src_rect.w = lCropWidth; + overlayL.src_rect.h = gr_fb[0].height; + overlayL.dst_rect.x = 0; + overlayL.dst_rect.y = 0; + overlayL.dst_rect.w = lWidth; + overlayL.dst_rect.h = height; + overlayL.alpha = 0xFF; + overlayL.transp_mask = MDP_TRANSP_NOP; + overlayL.id = MSMFB_NEW_REQUEST; + ret = ioctl(fd, MSMFB_OVERLAY_SET, &overlayL); + if (ret < 0) { + perror("OverlayL Set Failed"); + return ret; + } + overlayL_id = overlayL.id; + } + if (MSMFB_NEW_REQUEST == overlayR_id) { + struct mdp_overlay overlayR; + + memset(&overlayR, 0 , sizeof (struct mdp_overlay)); + + /* Fill OverlayR Data */ + overlayR.src.width = ALIGN(gr_fb[0].width, 32); + overlayR.src.height = gr_fb[0].height; + overlayR.src.format = map_mdp_pixel_format(); + overlayR.src_rect.x = lCropWidth; + overlayR.src_rect.y = 0; + overlayR.src_rect.w = gr_fb[0].width - lCropWidth; + overlayR.src_rect.h = gr_fb[0].height; + overlayR.dst_rect.x = 0; + overlayR.dst_rect.y = 0; + overlayR.dst_rect.w = rWidth; + overlayR.dst_rect.h = height; + overlayR.alpha = 0xFF; + overlayR.flags = MDSS_MDP_RIGHT_MIXER; + overlayR.transp_mask = MDP_TRANSP_NOP; + overlayR.id = MSMFB_NEW_REQUEST; + ret = ioctl(fd, MSMFB_OVERLAY_SET, &overlayR); + if (ret < 0) { + perror("OverlayR Set Failed"); + return ret; + } + overlayR_id = overlayR.id; + } + + } + return 0; +} + +int free_overlay(int fd) +{ + if (!overlay_supported) + return -EINVAL; + + int ret = 0; + struct mdp_display_commit ext_commit; + + if (!isDisplaySplit()) { + if (overlayL_id != MSMFB_NEW_REQUEST) { + ret = ioctl(fd, MSMFB_OVERLAY_UNSET, &overlayL_id); + if (ret) { + perror("Overlay Unset Failed"); + overlayL_id = MSMFB_NEW_REQUEST; + return ret; + } + } + } else { + + if (overlayL_id != MSMFB_NEW_REQUEST) { + ret = ioctl(fd, MSMFB_OVERLAY_UNSET, &overlayL_id); + if (ret) { + perror("OverlayL Unset Failed"); + overlayL_id = MSMFB_NEW_REQUEST; + return ret; + } + } + + if (overlayR_id != MSMFB_NEW_REQUEST) { + ret = ioctl(fd, MSMFB_OVERLAY_UNSET, &overlayR_id); + if (ret) { + perror("OverlayR Unset Failed"); + overlayR_id = MSMFB_NEW_REQUEST; + return ret; + } + } + } + memset(&ext_commit, 0, sizeof(struct mdp_display_commit)); + ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY; + ext_commit.wait_for_finish = 1; + ret = ioctl(fd, MSMFB_DISPLAY_COMMIT, &ext_commit); + if (ret < 0) { + perror("ERROR: Clear MSMFB_DISPLAY_COMMIT failed!"); + overlayL_id = MSMFB_NEW_REQUEST; + overlayR_id = MSMFB_NEW_REQUEST; + return ret; + } + overlayL_id = MSMFB_NEW_REQUEST; + overlayR_id = MSMFB_NEW_REQUEST; + + return 0; +} + +int overlay_display_frame(int fd, GGLubyte* data, size_t size) +{ + if (!overlay_supported) + return -EINVAL; + + int ret = 0; + struct msmfb_overlay_data ovdataL, ovdataR; + struct mdp_display_commit ext_commit; + + if (!isDisplaySplit()) { + if (overlayL_id == MSMFB_NEW_REQUEST) { + perror("display_frame failed, no overlay\n"); + return -EINVAL; + } + + memcpy(mem_info.mem_buf, data, size); + + memset(&ovdataL, 0, sizeof(struct msmfb_overlay_data)); + + ovdataL.id = overlayL_id; + ovdataL.data.flags = 0; + ovdataL.data.offset = 0; + ovdataL.data.memory_id = mem_info.mem_fd; + ret = ioctl(fd, MSMFB_OVERLAY_PLAY, &ovdataL); + if (ret < 0) { + perror("overlay_display_frame failed, overlay play Failed\n"); + return ret; + } + } else { + + if (overlayL_id == MSMFB_NEW_REQUEST) { + perror("display_frame failed, no overlayL \n"); + return -EINVAL; + } + + memcpy(mem_info.mem_buf, data, size); + + memset(&ovdataL, 0, sizeof(struct msmfb_overlay_data)); + + ovdataL.id = overlayL_id; + ovdataL.data.flags = 0; + ovdataL.data.offset = 0; + ovdataL.data.memory_id = mem_info.mem_fd; + ret = ioctl(fd, MSMFB_OVERLAY_PLAY, &ovdataL); + if (ret < 0) { + perror("overlay_display_frame failed, overlayL play Failed\n"); + return ret; + } + + if (overlayR_id == MSMFB_NEW_REQUEST) { + perror("display_frame failed, no overlayR \n"); + return -EINVAL; + } + memset(&ovdataR, 0, sizeof(struct msmfb_overlay_data)); + + ovdataR.id = overlayR_id; + ovdataR.data.flags = 0; + ovdataR.data.offset = 0; + ovdataR.data.memory_id = mem_info.mem_fd; + ret = ioctl(fd, MSMFB_OVERLAY_PLAY, &ovdataR); + if (ret < 0) { + perror("overlay_display_frame failed, overlayR play Failed\n"); + return ret; + } + } + memset(&ext_commit, 0, sizeof(struct mdp_display_commit)); + ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY; + ext_commit.wait_for_finish = 1; + ret = ioctl(fd, MSMFB_DISPLAY_COMMIT, &ext_commit); + if (ret < 0) { + perror("overlay_display_frame failed, overlay commit Failed\n!"); + } + + return ret; +} + +#else + +bool target_has_overlay(char *version) { + return false; +} + +bool isTargetMdp5() { + return false; +} + +int free_ion_mem(void) { + return -EINVAL; +} + +int alloc_ion_mem(unsigned int size) +{ + return -EINVAL; +} + +int allocate_overlay(int fd, GGLSurface gr_fb[]) +{ + return -EINVAL; +} + +int free_overlay(int fd) +{ + return -EINVAL; +} + +int overlay_display_frame(int fd, GGLubyte* data, size_t size) +{ + return -EINVAL; +} + +#endif //#ifdef MSM_BSP diff --git a/minuitwrp/graphics_utils.c b/minuitwrp/graphics_utils.c new file mode 100644 index 000000000..6083c7599 --- /dev/null +++ b/minuitwrp/graphics_utils.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <png.h> +#include <pixelflinger/pixelflinger.h> +#include <linux/fb.h> + +#include "minui.h" + +struct fb_var_screeninfo vi; +GGLSurface gr_mem_surface; + +int gr_save_screenshot(const char *dest) +{ + uint32_t y, stride_bytes; + int res = -1; + GGLContext *gl = NULL; + GGLSurface surface; + uint8_t * volatile img_data = NULL; + uint8_t *ptr; + FILE *fp = NULL; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + + fp = fopen(dest, "wb"); + if(!fp) + goto exit; + + img_data = malloc(vi.xres * vi.yres * 3); + surface.version = sizeof(surface); + surface.width = gr_mem_surface.width; + surface.height = gr_mem_surface.height; + surface.stride = gr_mem_surface.width; + surface.data = img_data; + surface.format = GGL_PIXEL_FORMAT_RGB_888; + + gglInit(&gl); + gl->colorBuffer(gl, &surface); + gl->activeTexture(gl, 0); + + gl->bindTexture(gl, &gr_mem_surface); + gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); + gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->enable(gl, GGL_TEXTURE_2D); + gl->texCoord2i(gl, 0, 0); + gl->recti(gl, 0, 0, gr_mem_surface.width, gr_mem_surface.height); + + gglUninit(gl); + gl = NULL; + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + goto exit; + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) + goto exit; + + if (setjmp(png_jmpbuf(png_ptr))) + goto exit; + + png_init_io(png_ptr, fp); + png_set_IHDR(png_ptr, info_ptr, surface.width, surface.height, + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_write_info(png_ptr, info_ptr); + + ptr = img_data; + stride_bytes = surface.width*3; + for(y = 0; y < surface.height; ++y) + { + png_write_row(png_ptr, ptr); + ptr += stride_bytes; + } + + png_write_end(png_ptr, NULL); + + res = 0; +exit: + if(info_ptr) + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + if(png_ptr) + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + if(gl) + gglUninit(gl); + if(img_data) + free(img_data); + if(fp) + fclose(fp); + return res; +} diff --git a/minuitwrp/include/linux/msm_ion.h b/minuitwrp/include/linux/msm_ion.h new file mode 100644 index 000000000..121a5a7a7 --- /dev/null +++ b/minuitwrp/include/linux/msm_ion.h @@ -0,0 +1,157 @@ +#ifndef _LINUX_MSM_ION_H +#define _LINUX_MSM_ION_H + +#include <linux/ion.h> + +/*enum msm_ion_heap_types { + ION_HEAP_TYPE_MSM_START = ION_HEAP_TYPE_CUSTOM + 1, + ION_HEAP_TYPE_IOMMU = ION_HEAP_TYPE_MSM_START, + ION_HEAP_TYPE_DMA, + ION_HEAP_TYPE_CP, + ION_HEAP_TYPE_SECURE_DMA, + ION_HEAP_TYPE_REMOVED, +};*/ + +/** + * These are the only ids that should be used for Ion heap ids. + * The ids listed are the order in which allocation will be attempted + * if specified. Don't swap the order of heap ids unless you know what + * you are doing! + * Id's are spaced by purpose to allow new Id's to be inserted in-between (for + * possible fallbacks) + */ + +enum ion_heap_ids { + INVALID_HEAP_ID = -1, + ION_CP_MM_HEAP_ID = 8, + ION_CP_MFC_HEAP_ID = 12, + ION_CP_WB_HEAP_ID = 16, /* 8660 only */ + ION_CAMERA_HEAP_ID = 20, /* 8660 only */ + ION_SYSTEM_CONTIG_HEAP_ID = 21, + ION_ADSP_HEAP_ID = 22, + ION_PIL1_HEAP_ID = 23, /* Currently used for other PIL images */ + ION_SF_HEAP_ID = 24, + ION_IOMMU_HEAP_ID = 25, + ION_PIL2_HEAP_ID = 26, /* Currently used for modem firmware images */ + ION_QSECOM_HEAP_ID = 27, + ION_AUDIO_HEAP_ID = 28, + + ION_MM_FIRMWARE_HEAP_ID = 29, + ION_SYSTEM_HEAP_ID = 30, + + ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_FLAG_SECURE flag */ +}; + +/*enum ion_fixed_position { + NOT_FIXED, + FIXED_LOW, + FIXED_MIDDLE, + FIXED_HIGH, +};*/ + +/*enum cp_mem_usage { + VIDEO_BITSTREAM = 0x1, + VIDEO_PIXEL = 0x2, + VIDEO_NONPIXEL = 0x3, + MAX_USAGE = 0x4, + UNKNOWN = 0x7FFFFFFF, +};*/ + +#define ION_HEAP_CP_MASK (1 << ION_HEAP_TYPE_CP) +#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) + +/** + * Flag to use when allocating to indicate that a heap is secure. + */ +#define ION_FLAG_SECURE (1 << ION_HEAP_ID_RESERVED) + +/** + * Flag for clients to force contiguous memort allocation + * + * Use of this flag is carefully monitored! + */ +#define ION_FLAG_FORCE_CONTIGUOUS (1 << 30) + +/* + * Used in conjunction with heap which pool memory to force an allocation + * to come from the page allocator directly instead of from the pool allocation + */ +#define ION_FLAG_POOL_FORCE_ALLOC (1 << 16) + +/** +* Deprecated! Please use the corresponding ION_FLAG_* +*/ +#define ION_SECURE ION_FLAG_SECURE +#define ION_FORCE_CONTIGUOUS ION_FLAG_FORCE_CONTIGUOUS + +/** + * Macro should be used with ion_heap_ids defined above. + */ +#define ION_HEAP(bit) (1 << (bit)) + +#define ION_ADSP_HEAP_NAME "adsp" +#define ION_VMALLOC_HEAP_NAME "vmalloc" +#define ION_KMALLOC_HEAP_NAME "kmalloc" +#define ION_AUDIO_HEAP_NAME "audio" +#define ION_SF_HEAP_NAME "sf" +#define ION_MM_HEAP_NAME "mm" +#define ION_CAMERA_HEAP_NAME "camera_preview" +#define ION_IOMMU_HEAP_NAME "iommu" +#define ION_MFC_HEAP_NAME "mfc" +#define ION_WB_HEAP_NAME "wb" +#define ION_MM_FIRMWARE_HEAP_NAME "mm_fw" +#define ION_PIL1_HEAP_NAME "pil_1" +#define ION_PIL2_HEAP_NAME "pil_2" +#define ION_QSECOM_HEAP_NAME "qsecom" + +#define ION_SET_CACHED(__cache) (__cache | ION_FLAG_CACHED) +#define ION_SET_UNCACHED(__cache) (__cache & ~ION_FLAG_CACHED) + +#define ION_IS_CACHED(__flags) ((__flags) & ION_FLAG_CACHED) + + +/* struct ion_flush_data - data passed to ion for flushing caches + * + * @handle: handle with data to flush + * @fd: fd to flush + * @vaddr: userspace virtual address mapped with mmap + * @offset: offset into the handle to flush + * @length: length of handle to flush + * + * Performs cache operations on the handle. If p is the start address + * of the handle, p + offset through p + offset + length will have + * the cache operations performed + */ +struct ion_flush_data { + struct ion_handle *handle; + int fd; + void *vaddr; + unsigned int offset; + unsigned int length; +}; + +#define ION_IOC_MSM_MAGIC 'M' + +/** + * DOC: ION_IOC_CLEAN_CACHES - clean the caches + * + * Clean the caches of the handle specified. + */ +#define ION_IOC_CLEAN_CACHES _IOWR(ION_IOC_MSM_MAGIC, 0, \ + struct ion_flush_data) +/** + * DOC: ION_IOC_INV_CACHES - invalidate the caches + * + * Invalidate the caches of the handle specified. + */ +#define ION_IOC_INV_CACHES _IOWR(ION_IOC_MSM_MAGIC, 1, \ + struct ion_flush_data) +/** + * DOC: ION_IOC_CLEAN_INV_CACHES - clean and invalidate the caches + * + * Clean and invalidate the caches of the handle specified. + */ +#define ION_IOC_CLEAN_INV_CACHES _IOWR(ION_IOC_MSM_MAGIC, 2, \ + struct ion_flush_data) + +#endif diff --git a/minuitwrp/include/linux/msm_mdp.h b/minuitwrp/include/linux/msm_mdp.h new file mode 100644 index 000000000..abdcd29e9 --- /dev/null +++ b/minuitwrp/include/linux/msm_mdp.h @@ -0,0 +1,992 @@ +/* include/linux/msm_mdp.h + * + * Copyright (C) 2007 Google Incorporated + * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef _MSM_MDP_H_ +#define _MSM_MDP_H_ + +#include <linux/types.h> +#include <linux/fb.h> + +#define MSMFB_IOCTL_MAGIC 'm' +#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int) +#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int) +#define MSMFB_SUSPEND_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 128, unsigned int) +#define MSMFB_RESUME_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 129, unsigned int) +#define MSMFB_CURSOR _IOW(MSMFB_IOCTL_MAGIC, 130, struct fb_cursor) +#define MSMFB_SET_LUT _IOW(MSMFB_IOCTL_MAGIC, 131, struct fb_cmap) +#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram_data) +/* new ioctls's for set/get ccs matrix */ +#define MSMFB_GET_CCS_MATRIX _IOWR(MSMFB_IOCTL_MAGIC, 133, struct mdp_ccs) +#define MSMFB_SET_CCS_MATRIX _IOW(MSMFB_IOCTL_MAGIC, 134, struct mdp_ccs) +#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \ + struct mdp_overlay) +#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int) + +#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \ + struct msmfb_overlay_data) +#define MSMFB_OVERLAY_QUEUE MSMFB_OVERLAY_PLAY + +#define MSMFB_GET_PAGE_PROTECTION _IOR(MSMFB_IOCTL_MAGIC, 138, \ + struct mdp_page_protection) +#define MSMFB_SET_PAGE_PROTECTION _IOW(MSMFB_IOCTL_MAGIC, 139, \ + struct mdp_page_protection) +#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \ + struct mdp_overlay) +#define MSMFB_OVERLAY_PLAY_ENABLE _IOW(MSMFB_IOCTL_MAGIC, 141, unsigned int) +#define MSMFB_OVERLAY_BLT _IOWR(MSMFB_IOCTL_MAGIC, 142, \ + struct msmfb_overlay_blt) +#define MSMFB_OVERLAY_BLT_OFFSET _IOW(MSMFB_IOCTL_MAGIC, 143, unsigned int) +#define MSMFB_HISTOGRAM_START _IOR(MSMFB_IOCTL_MAGIC, 144, \ + struct mdp_histogram_start_req) +#define MSMFB_HISTOGRAM_STOP _IOR(MSMFB_IOCTL_MAGIC, 145, unsigned int) +#define MSMFB_NOTIFY_UPDATE _IOWR(MSMFB_IOCTL_MAGIC, 146, unsigned int) + +#define MSMFB_OVERLAY_3D _IOWR(MSMFB_IOCTL_MAGIC, 147, \ + struct msmfb_overlay_3d) + +#define MSMFB_MIXER_INFO _IOWR(MSMFB_IOCTL_MAGIC, 148, \ + struct msmfb_mixer_info_req) +#define MSMFB_OVERLAY_PLAY_WAIT _IOWR(MSMFB_IOCTL_MAGIC, 149, \ + struct msmfb_overlay_data) +#define MSMFB_WRITEBACK_INIT _IO(MSMFB_IOCTL_MAGIC, 150) +#define MSMFB_WRITEBACK_START _IO(MSMFB_IOCTL_MAGIC, 151) +#define MSMFB_WRITEBACK_STOP _IO(MSMFB_IOCTL_MAGIC, 152) +#define MSMFB_WRITEBACK_QUEUE_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 153, \ + struct msmfb_data) +#define MSMFB_WRITEBACK_DEQUEUE_BUFFER _IOW(MSMFB_IOCTL_MAGIC, 154, \ + struct msmfb_data) +#define MSMFB_WRITEBACK_TERMINATE _IO(MSMFB_IOCTL_MAGIC, 155) +#define MSMFB_MDP_PP _IOWR(MSMFB_IOCTL_MAGIC, 156, struct msmfb_mdp_pp) +#define MSMFB_OVERLAY_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 160, unsigned int) +#define MSMFB_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 161, unsigned int) +#define MSMFB_BUFFER_SYNC _IOW(MSMFB_IOCTL_MAGIC, 162, struct mdp_buf_sync) +#define MSMFB_OVERLAY_COMMIT _IO(MSMFB_IOCTL_MAGIC, 163) +#define MSMFB_DISPLAY_COMMIT _IOW(MSMFB_IOCTL_MAGIC, 164, \ + struct mdp_display_commit) +#define MSMFB_METADATA_SET _IOW(MSMFB_IOCTL_MAGIC, 165, struct msmfb_metadata) +#define MSMFB_METADATA_GET _IOW(MSMFB_IOCTL_MAGIC, 166, struct msmfb_metadata) +#define MSMFB_WRITEBACK_SET_MIRRORING_HINT _IOW(MSMFB_IOCTL_MAGIC, 167, \ + unsigned int) +#define MSMFB_ASYNC_BLIT _IOW(MSMFB_IOCTL_MAGIC, 168, unsigned int) + +#define FB_TYPE_3D_PANEL 0x10101010 +#define MDP_IMGTYPE2_START 0x10000 +#define MSMFB_DRIVER_VERSION 0xF9E8D701 + +enum { + NOTIFY_UPDATE_START, + NOTIFY_UPDATE_STOP, + NOTIFY_UPDATE_POWER_OFF, +}; + +enum { + NOTIFY_TYPE_NO_UPDATE, + NOTIFY_TYPE_SUSPEND, + NOTIFY_TYPE_UPDATE, +}; + +enum { + MDP_RGB_565, /* RGB 565 planer */ + MDP_XRGB_8888, /* RGB 888 padded */ + MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planer w/ Cb is in MSB */ + MDP_Y_CBCR_H2V2_ADRENO, + MDP_ARGB_8888, /* ARGB 888 */ + MDP_RGB_888, /* RGB 888 planer */ + MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planer w/ Cr is in MSB */ + MDP_YCRYCB_H2V1, /* YCrYCb interleave */ + MDP_CBYCRY_H2V1, /* CbYCrY interleave */ + MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_Y_CRCB_H1V2, + MDP_Y_CBCR_H1V2, + MDP_RGBA_8888, /* ARGB 888 */ + MDP_BGRA_8888, /* ABGR 888 */ + MDP_RGBX_8888, /* RGBX 888 */ + MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */ + MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */ + MDP_Y_CR_CB_H2V2, /* Y, Cr and Cb, planar */ + MDP_Y_CR_CB_GH2V2, /* Y, Cr and Cb, planar aligned to Android YV12 */ + MDP_Y_CB_CR_H2V2, /* Y, Cb and Cr, planar */ + MDP_Y_CRCB_H1V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ + MDP_Y_CBCR_H1V1, /* Y and CbCr, pseduo planer w/ Cb is in MSB */ + MDP_YCRCB_H1V1, /* YCrCb interleave */ + MDP_YCBCR_H1V1, /* YCbCr interleave */ + MDP_BGR_565, /* BGR 565 planer */ + MDP_BGR_888, /* BGR 888 */ + MDP_Y_CBCR_H2V2_VENUS, + MDP_BGRX_8888, /* BGRX 8888 */ + MDP_RGBA_8888_TILE, /* RGBA 8888 in tile format */ + MDP_ARGB_8888_TILE, /* ARGB 8888 in tile format */ + MDP_ABGR_8888_TILE, /* ABGR 8888 in tile format */ + MDP_BGRA_8888_TILE, /* BGRA 8888 in tile format */ + MDP_RGBX_8888_TILE, /* RGBX 8888 in tile format */ + MDP_XRGB_8888_TILE, /* XRGB 8888 in tile format */ + MDP_XBGR_8888_TILE, /* XBGR 8888 in tile format */ + MDP_BGRX_8888_TILE, /* BGRX 8888 in tile format */ + MDP_YCBYCR_H2V1, /* YCbYCr interleave */ + MDP_IMGTYPE_LIMIT, + MDP_RGB_BORDERFILL, /* border fill pipe */ + MDP_FB_FORMAT = MDP_IMGTYPE2_START, /* framebuffer format */ + MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */ +}; + +enum { + PMEM_IMG, + FB_IMG, +}; + +enum { + HSIC_HUE = 0, + HSIC_SAT, + HSIC_INT, + HSIC_CON, + NUM_HSIC_PARAM, +}; + +#define MDSS_MDP_ROT_ONLY 0x80 +#define MDSS_MDP_RIGHT_MIXER 0x100 +#define MDSS_MDP_DUAL_PIPE 0x200 + +/* mdp_blit_req flag values */ +#define MDP_ROT_NOP 0 +#define MDP_FLIP_LR 0x1 +#define MDP_FLIP_UD 0x2 +#define MDP_ROT_90 0x4 +#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) +#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) +#define MDP_DITHER 0x8 +#define MDP_BLUR 0x10 +#define MDP_BLEND_FG_PREMULT 0x20000 +#define MDP_IS_FG 0x40000 +#define MDP_SOLID_FILL 0x0000100 +#define MDP_DEINTERLACE 0x80000000 +#define MDP_SHARPENING 0x40000000 +#define MDP_NO_DMA_BARRIER_START 0x20000000 +#define MDP_NO_DMA_BARRIER_END 0x10000000 +#define MDP_NO_BLIT 0x08000000 +#define MDP_BLIT_WITH_DMA_BARRIERS 0x000 +#define MDP_BLIT_WITH_NO_DMA_BARRIERS \ + (MDP_NO_DMA_BARRIER_START | MDP_NO_DMA_BARRIER_END) +#define MDP_BLIT_SRC_GEM 0x04000000 +#define MDP_BLIT_DST_GEM 0x02000000 +#define MDP_BLIT_NON_CACHED 0x01000000 +#define MDP_OV_PIPE_SHARE 0x00800000 +#define MDP_DEINTERLACE_ODD 0x00400000 +#define MDP_OV_PLAY_NOWAIT 0x00200000 +#define MDP_SOURCE_ROTATED_90 0x00100000 +#define MDP_OVERLAY_PP_CFG_EN 0x00080000 +#define MDP_BACKEND_COMPOSITION 0x00040000 +#define MDP_BORDERFILL_SUPPORTED 0x00010000 +#define MDP_SECURE_OVERLAY_SESSION 0x00008000 +#define MDP_SECURE_DISPLAY_OVERLAY_SESSION 0x00002000 +#define MDP_OV_PIPE_FORCE_DMA 0x00004000 +#define MDP_MEMORY_ID_TYPE_FB 0x00001000 +#define MDP_BWC_EN 0x00000400 +#define MDP_DECIMATION_EN 0x00000800 +#define MDP_TRANSP_NOP 0xffffffff +#define MDP_ALPHA_NOP 0xff + +#define MDP_FB_PAGE_PROTECTION_NONCACHED (0) +#define MDP_FB_PAGE_PROTECTION_WRITECOMBINE (1) +#define MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE (2) +#define MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE (3) +#define MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE (4) +/* Sentinel: Don't use! */ +#define MDP_FB_PAGE_PROTECTION_INVALID (5) +/* Count of the number of MDP_FB_PAGE_PROTECTION_... values. */ +#define MDP_NUM_FB_PAGE_PROTECTION_VALUES (5) + +struct mdp_rect { + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; +}; + +struct mdp_img { + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t offset; + int memory_id; /* the file descriptor */ + uint32_t priv; +}; + +/* + * {3x3} + {3} ccs matrix + */ + +#define MDP_CCS_RGB2YUV 0 +#define MDP_CCS_YUV2RGB 1 + +#define MDP_CCS_SIZE 9 +#define MDP_BV_SIZE 3 + +struct mdp_ccs { + int direction; /* MDP_CCS_RGB2YUV or YUV2RGB */ + uint16_t ccs[MDP_CCS_SIZE]; /* 3x3 color coefficients */ + uint16_t bv[MDP_BV_SIZE]; /* 1x3 bias vector */ +}; + +struct mdp_csc { + int id; + uint32_t csc_mv[9]; + uint32_t csc_pre_bv[3]; + uint32_t csc_post_bv[3]; + uint32_t csc_pre_lv[6]; + uint32_t csc_post_lv[6]; +}; + +/* The version of the mdp_blit_req structure so that + * user applications can selectively decide which functionality + * to include + */ + +#define MDP_BLIT_REQ_VERSION 2 + +struct color { + uint32_t r; + uint32_t g; + uint32_t b; + uint32_t alpha; +}; + +struct mdp_blit_req { + struct mdp_img src; + struct mdp_img dst; + struct mdp_rect src_rect; + struct mdp_rect dst_rect; + struct color const_color; + uint32_t alpha; + uint32_t transp_mask; + uint32_t flags; + int sharpening_strength; /* -127 <--> 127, default 64 */ +}; + +struct mdp_blit_req_list { + uint32_t count; + struct mdp_blit_req req[]; +}; + +#define MSMFB_DATA_VERSION 2 + +struct msmfb_data { + uint32_t offset; + int memory_id; + int id; + uint32_t flags; + uint32_t priv; + uint32_t iova; +}; + +#define MSMFB_NEW_REQUEST -1 + +struct msmfb_overlay_data { + uint32_t id; + struct msmfb_data data; + uint32_t version_key; + struct msmfb_data plane1_data; + struct msmfb_data plane2_data; + struct msmfb_data dst_data; +}; + +struct msmfb_img { + uint32_t width; + uint32_t height; + uint32_t format; +}; + +#define MSMFB_WRITEBACK_DEQUEUE_BLOCKING 0x1 +struct msmfb_writeback_data { + struct msmfb_data buf_info; + struct msmfb_img img; +}; + +#define MDP_PP_OPS_ENABLE 0x1 +#define MDP_PP_OPS_READ 0x2 +#define MDP_PP_OPS_WRITE 0x4 +#define MDP_PP_OPS_DISABLE 0x8 +#define MDP_PP_IGC_FLAG_ROM0 0x10 +#define MDP_PP_IGC_FLAG_ROM1 0x20 + +#define MDSS_PP_DSPP_CFG 0x000 +#define MDSS_PP_SSPP_CFG 0x100 +#define MDSS_PP_LM_CFG 0x200 +#define MDSS_PP_WB_CFG 0x300 + +#define MDSS_PP_ARG_MASK 0x3C00 +#define MDSS_PP_ARG_NUM 4 +#define MDSS_PP_ARG_SHIFT 10 +#define MDSS_PP_LOCATION_MASK 0x0300 +#define MDSS_PP_LOGICAL_MASK 0x00FF + +#define MDSS_PP_ADD_ARG(var, arg) ((var) | (0x1 << (MDSS_PP_ARG_SHIFT + (arg)))) +#define PP_ARG(x, var) ((var) & (0x1 << (MDSS_PP_ARG_SHIFT + (x)))) +#define PP_LOCAT(var) ((var) & MDSS_PP_LOCATION_MASK) +#define PP_BLOCK(var) ((var) & MDSS_PP_LOGICAL_MASK) + + +struct mdp_qseed_cfg { + uint32_t table_num; + uint32_t ops; + uint32_t len; + uint32_t *data; +}; + +struct mdp_sharp_cfg { + uint32_t flags; + uint32_t strength; + uint32_t edge_thr; + uint32_t smooth_thr; + uint32_t noise_thr; +}; + +struct mdp_qseed_cfg_data { + uint32_t block; + struct mdp_qseed_cfg qseed_data; +}; + +#define MDP_OVERLAY_PP_CSC_CFG 0x1 +#define MDP_OVERLAY_PP_QSEED_CFG 0x2 +#define MDP_OVERLAY_PP_PA_CFG 0x4 +#define MDP_OVERLAY_PP_IGC_CFG 0x8 +#define MDP_OVERLAY_PP_SHARP_CFG 0x10 +#define MDP_OVERLAY_PP_HIST_CFG 0x20 +#define MDP_OVERLAY_PP_HIST_LUT_CFG 0x40 + +#define MDP_CSC_FLAG_ENABLE 0x1 +#define MDP_CSC_FLAG_YUV_IN 0x2 +#define MDP_CSC_FLAG_YUV_OUT 0x4 + +struct mdp_csc_cfg { + /* flags for enable CSC, toggling RGB,YUV input/output */ + uint32_t flags; + uint32_t csc_mv[9]; + uint32_t csc_pre_bv[3]; + uint32_t csc_post_bv[3]; + uint32_t csc_pre_lv[6]; + uint32_t csc_post_lv[6]; +}; + +struct mdp_csc_cfg_data { + uint32_t block; + struct mdp_csc_cfg csc_data; +}; + +struct mdp_pa_cfg { + uint32_t flags; + uint32_t hue_adj; + uint32_t sat_adj; + uint32_t val_adj; + uint32_t cont_adj; +}; + +struct mdp_igc_lut_data { + uint32_t block; + uint32_t len, ops; + uint32_t *c0_c1_data; + uint32_t *c2_data; +}; + +struct mdp_histogram_cfg { + uint32_t ops; + uint32_t block; + uint8_t frame_cnt; + uint8_t bit_mask; + uint16_t num_bins; +}; + +struct mdp_hist_lut_data { + uint32_t block; + uint32_t ops; + uint32_t len; + uint32_t *data; +}; + +struct mdp_overlay_pp_params { + uint32_t config_ops; + struct mdp_csc_cfg csc_cfg; + struct mdp_qseed_cfg qseed_cfg[2]; + struct mdp_pa_cfg pa_cfg; + struct mdp_igc_lut_data igc_cfg; + struct mdp_sharp_cfg sharp_cfg; + struct mdp_histogram_cfg hist_cfg; + struct mdp_hist_lut_data hist_lut_cfg; +}; + +/** + * enum mdss_mdp_blend_op - Different blend operations set by userspace + * + * @BLEND_OP_NOT_DEFINED: No blend operation defined for the layer. + * @BLEND_OP_OPAQUE: Apply a constant blend operation. The layer + * would appear opaque in case fg plane alpha is + * 0xff. + * @BLEND_OP_PREMULTIPLIED: Apply source over blend rule. Layer already has + * alpha pre-multiplication done. If fg plane alpha + * is less than 0xff, apply modulation as well. This + * operation is intended on layers having alpha + * channel. + * @BLEND_OP_COVERAGE: Apply source over blend rule. Layer is not alpha + * pre-multiplied. Apply pre-multiplication. If fg + * plane alpha is less than 0xff, apply modulation as + * well. + * @BLEND_OP_MAX: Used to track maximum blend operation possible by + * mdp. + */ +enum mdss_mdp_blend_op { + BLEND_OP_NOT_DEFINED = 0, + BLEND_OP_OPAQUE, + BLEND_OP_PREMULTIPLIED, + BLEND_OP_COVERAGE, + BLEND_OP_MAX, +}; + +#define MAX_PLANES 4 +struct mdp_scale_data { + uint8_t enable_pxl_ext; + + int init_phase_x[MAX_PLANES]; + int phase_step_x[MAX_PLANES]; + int init_phase_y[MAX_PLANES]; + int phase_step_y[MAX_PLANES]; + + int num_ext_pxls_left[MAX_PLANES]; + int num_ext_pxls_right[MAX_PLANES]; + int num_ext_pxls_top[MAX_PLANES]; + int num_ext_pxls_btm[MAX_PLANES]; + + int left_ftch[MAX_PLANES]; + int left_rpt[MAX_PLANES]; + int right_ftch[MAX_PLANES]; + int right_rpt[MAX_PLANES]; + + int top_rpt[MAX_PLANES]; + int btm_rpt[MAX_PLANES]; + int top_ftch[MAX_PLANES]; + int btm_ftch[MAX_PLANES]; + + uint32_t roi_w[MAX_PLANES]; +}; + +/** + * struct mdp_overlay - overlay surface structure + * @src: Source image information (width, height, format). + * @src_rect: Source crop rectangle, portion of image that will be fetched. + * This should always be within boundaries of source image. + * @dst_rect: Destination rectangle, the position and size of image on screen. + * This should always be within panel boundaries. + * @z_order: Blending stage to occupy in display, if multiple layers are + * present, highest z_order usually means the top most visible + * layer. The range acceptable is from 0-3 to support blending + * up to 4 layers. + * @is_fg: This flag is used to disable blending of any layers with z_order + * less than this overlay. It means that any layers with z_order + * less than this layer will not be blended and will be replaced + * by the background border color. + * @alpha: Used to set plane opacity. The range can be from 0-255, where + * 0 means completely transparent and 255 means fully opaque. + * @transp_mask: Color used as color key for transparency. Any pixel in fetched + * image matching this color will be transparent when blending. + * The color should be in same format as the source image format. + * @flags: This is used to customize operation of overlay. See MDP flags + * for more information. + * @user_data: DEPRECATED* Used to store user application specific information. + * @bg_color: Solid color used to fill the overlay surface when no source + * buffer is provided. + * @horz_deci: Horizontal decimation value, this indicates the amount of pixels + * dropped for each pixel that is fetched from a line. The value + * given should be power of two of decimation amount. + * 0: no decimation + * 1: decimate by 2 (drop 1 pixel for each pixel fetched) + * 2: decimate by 4 (drop 3 pixels for each pixel fetched) + * 3: decimate by 8 (drop 7 pixels for each pixel fetched) + * 4: decimate by 16 (drop 15 pixels for each pixel fetched) + * @vert_deci: Vertical decimation value, this indicates the amount of lines + * dropped for each line that is fetched from overlay. The value + * given should be power of two of decimation amount. + * 0: no decimation + * 1: decimation by 2 (drop 1 line for each line fetched) + * 2: decimation by 4 (drop 3 lines for each line fetched) + * 3: decimation by 8 (drop 7 lines for each line fetched) + * 4: decimation by 16 (drop 15 lines for each line fetched) + * @overlay_pp_cfg: Overlay post processing configuration, for more information + * see struct mdp_overlay_pp_params. + */ +struct mdp_overlay { + struct msmfb_img src; + struct mdp_rect src_rect; + struct mdp_rect dst_rect; + uint32_t z_order; /* stage number */ + uint32_t is_fg; /* control alpha & transp */ + uint32_t alpha; + uint32_t blend_op; + uint32_t transp_mask; + uint32_t flags; + uint32_t id; + uint32_t user_data[6]; + uint32_t bg_color; + uint8_t horz_deci; + uint8_t vert_deci; + struct mdp_overlay_pp_params overlay_pp_cfg; + struct mdp_scale_data scale; +}; + +struct msmfb_overlay_3d { + uint32_t is_3d; + uint32_t width; + uint32_t height; +}; + + +struct msmfb_overlay_blt { + uint32_t enable; + uint32_t offset; + uint32_t width; + uint32_t height; + uint32_t bpp; +}; + +struct mdp_histogram { + uint32_t frame_cnt; + uint32_t bin_cnt; + uint32_t *r; + uint32_t *g; + uint32_t *b; +}; + +enum { + DISPLAY_MISR_EDP, + DISPLAY_MISR_DSI0, + DISPLAY_MISR_DSI1, + DISPLAY_MISR_HDMI, + DISPLAY_MISR_LCDC, + DISPLAY_MISR_ATV, + DISPLAY_MISR_DSI_CMD, + DISPLAY_MISR_MAX +}; + +enum { + MISR_OP_NONE, + MISR_OP_SFM, + MISR_OP_MFM, + MISR_OP_BM, + MISR_OP_MAX +}; + +struct mdp_misr { + uint32_t block_id; + uint32_t frame_count; + uint32_t crc_op_mode; + uint32_t crc_value[32]; +}; + +/* + + mdp_block_type defines the identifiers for pipes in MDP 4.3 and up + + MDP_BLOCK_RESERVED is provided for backward compatibility and is + deprecated. It corresponds to DMA_P. So MDP_BLOCK_DMA_P should be used + instead. + + MDP_LOGICAL_BLOCK_DISP_0 identifies the display pipe which fb0 uses, + same for others. + +*/ + +enum { + MDP_BLOCK_RESERVED = 0, + MDP_BLOCK_OVERLAY_0, + MDP_BLOCK_OVERLAY_1, + MDP_BLOCK_VG_1, + MDP_BLOCK_VG_2, + MDP_BLOCK_RGB_1, + MDP_BLOCK_RGB_2, + MDP_BLOCK_DMA_P, + MDP_BLOCK_DMA_S, + MDP_BLOCK_DMA_E, + MDP_BLOCK_OVERLAY_2, + MDP_LOGICAL_BLOCK_DISP_0 = 0x10, + MDP_LOGICAL_BLOCK_DISP_1, + MDP_LOGICAL_BLOCK_DISP_2, + MDP_BLOCK_MAX, +}; + +/* + * mdp_histogram_start_req is used to provide the parameters for + * histogram start request + */ + +struct mdp_histogram_start_req { + uint32_t block; + uint8_t frame_cnt; + uint8_t bit_mask; + uint16_t num_bins; +}; + +/* + * mdp_histogram_data is used to return the histogram data, once + * the histogram is done/stopped/cance + */ + +struct mdp_histogram_data { + uint32_t block; + uint32_t bin_cnt; + uint32_t *c0; + uint32_t *c1; + uint32_t *c2; + uint32_t *extra_info; +}; + +struct mdp_pcc_coeff { + uint32_t c, r, g, b, rr, gg, bb, rg, gb, rb, rgb_0, rgb_1; +}; + +struct mdp_pcc_cfg_data { + uint32_t block; + uint32_t ops; + struct mdp_pcc_coeff r, g, b; +}; + +#define MDP_GAMUT_TABLE_NUM 8 + +enum { + mdp_lut_igc, + mdp_lut_pgc, + mdp_lut_hist, + mdp_lut_max, +}; + +struct mdp_ar_gc_lut_data { + uint32_t x_start; + uint32_t slope; + uint32_t offset; +}; + +struct mdp_pgc_lut_data { + uint32_t block; + uint32_t flags; + uint8_t num_r_stages; + uint8_t num_g_stages; + uint8_t num_b_stages; + struct mdp_ar_gc_lut_data *r_data; + struct mdp_ar_gc_lut_data *g_data; + struct mdp_ar_gc_lut_data *b_data; +}; + + +struct mdp_lut_cfg_data { + uint32_t lut_type; + union { + struct mdp_igc_lut_data igc_lut_data; + struct mdp_pgc_lut_data pgc_lut_data; + struct mdp_hist_lut_data hist_lut_data; + } data; +}; + +struct mdp_bl_scale_data { + uint32_t min_lvl; + uint32_t scale; +}; + +struct mdp_pa_cfg_data { + uint32_t block; + struct mdp_pa_cfg pa_data; +}; + +struct mdp_dither_cfg_data { + uint32_t block; + uint32_t flags; + uint32_t g_y_depth; + uint32_t r_cr_depth; + uint32_t b_cb_depth; +}; + +struct mdp_gamut_cfg_data { + uint32_t block; + uint32_t flags; + uint32_t gamut_first; + uint32_t tbl_size[MDP_GAMUT_TABLE_NUM]; + uint16_t *r_tbl[MDP_GAMUT_TABLE_NUM]; + uint16_t *g_tbl[MDP_GAMUT_TABLE_NUM]; + uint16_t *b_tbl[MDP_GAMUT_TABLE_NUM]; +}; + +struct mdp_calib_config_data { + uint32_t ops; + uint32_t addr; + uint32_t data; +}; + +struct mdp_calib_config_buffer { + uint32_t ops; + uint32_t size; + uint32_t *buffer; +}; + +struct mdp_calib_dcm_state { + uint32_t ops; + uint32_t dcm_state; +}; + +enum { + DCM_UNINIT, + DCM_UNBLANK, + DCM_ENTER, + DCM_EXIT, + DCM_BLANK, +}; + +#define MDSS_MAX_BL_BRIGHTNESS 255 +#define AD_BL_LIN_LEN (MDSS_MAX_BL_BRIGHTNESS + 1) + +#define MDSS_AD_MODE_AUTO_BL 0x0 +#define MDSS_AD_MODE_AUTO_STR 0x1 +#define MDSS_AD_MODE_TARG_STR 0x3 +#define MDSS_AD_MODE_MAN_STR 0x7 +#define MDSS_AD_MODE_CALIB 0xF + +#define MDP_PP_AD_INIT 0x10 +#define MDP_PP_AD_CFG 0x20 + +struct mdss_ad_init { + uint32_t asym_lut[33]; + uint32_t color_corr_lut[33]; + uint8_t i_control[2]; + uint16_t black_lvl; + uint16_t white_lvl; + uint8_t var; + uint8_t limit_ampl; + uint8_t i_dither; + uint8_t slope_max; + uint8_t slope_min; + uint8_t dither_ctl; + uint8_t format; + uint8_t auto_size; + uint16_t frame_w; + uint16_t frame_h; + uint8_t logo_v; + uint8_t logo_h; + uint32_t bl_lin_len; + uint32_t *bl_lin; + uint32_t *bl_lin_inv; +}; + +#define MDSS_AD_BL_CTRL_MODE_EN 1 +#define MDSS_AD_BL_CTRL_MODE_DIS 0 +struct mdss_ad_cfg { + uint32_t mode; + uint32_t al_calib_lut[33]; + uint16_t backlight_min; + uint16_t backlight_max; + uint16_t backlight_scale; + uint16_t amb_light_min; + uint16_t filter[2]; + uint16_t calib[4]; + uint8_t strength_limit; + uint8_t t_filter_recursion; + uint16_t stab_itr; + uint32_t bl_ctrl_mode; +}; + +/* ops uses standard MDP_PP_* flags */ +struct mdss_ad_init_cfg { + uint32_t ops; + union { + struct mdss_ad_init init; + struct mdss_ad_cfg cfg; + } params; +}; + +/* mode uses MDSS_AD_MODE_* flags */ +struct mdss_ad_input { + uint32_t mode; + union { + uint32_t amb_light; + uint32_t strength; + uint32_t calib_bl; + } in; + uint32_t output; +}; + +#define MDSS_CALIB_MODE_BL 0x1 +struct mdss_calib_cfg { + uint32_t ops; + uint32_t calib_mask; +}; + +enum { + mdp_op_pcc_cfg, + mdp_op_csc_cfg, + mdp_op_lut_cfg, + mdp_op_qseed_cfg, + mdp_bl_scale_cfg, + mdp_op_pa_cfg, + mdp_op_dither_cfg, + mdp_op_gamut_cfg, + mdp_op_calib_cfg, + mdp_op_ad_cfg, + mdp_op_ad_input, + mdp_op_calib_mode, + mdp_op_calib_buffer, + mdp_op_calib_dcm_state, + mdp_op_max, +}; + +enum { + WB_FORMAT_NV12, + WB_FORMAT_RGB_565, + WB_FORMAT_RGB_888, + WB_FORMAT_xRGB_8888, + WB_FORMAT_ARGB_8888, + WB_FORMAT_BGRA_8888, + WB_FORMAT_BGRX_8888, + WB_FORMAT_ARGB_8888_INPUT_ALPHA /* Need to support */ +}; + +struct msmfb_mdp_pp { + uint32_t op; + union { + struct mdp_pcc_cfg_data pcc_cfg_data; + struct mdp_csc_cfg_data csc_cfg_data; + struct mdp_lut_cfg_data lut_cfg_data; + struct mdp_qseed_cfg_data qseed_cfg_data; + struct mdp_bl_scale_data bl_scale_data; + struct mdp_pa_cfg_data pa_cfg_data; + struct mdp_dither_cfg_data dither_cfg_data; + struct mdp_gamut_cfg_data gamut_cfg_data; + struct mdp_calib_config_data calib_cfg; + struct mdss_ad_init_cfg ad_init_cfg; + struct mdss_calib_cfg mdss_calib_cfg; + struct mdss_ad_input ad_input; + struct mdp_calib_config_buffer calib_buffer; + struct mdp_calib_dcm_state calib_dcm; + } data; +}; + +#define FB_METADATA_VIDEO_INFO_CODE_SUPPORT 1 +enum { + metadata_op_none, + metadata_op_base_blend, + metadata_op_frame_rate, + metadata_op_vic, + metadata_op_wb_format, + metadata_op_get_caps, + metadata_op_crc, + metadata_op_max +}; + +struct mdp_blend_cfg { + uint32_t is_premultiplied; +}; + +struct mdp_mixer_cfg { + uint32_t writeback_format; + uint32_t alpha; +}; + +struct mdss_hw_caps { + uint32_t mdp_rev; + uint8_t rgb_pipes; + uint8_t vig_pipes; + uint8_t dma_pipes; + uint32_t features; +}; + +struct msmfb_metadata { + uint32_t op; + uint32_t flags; + union { + struct mdp_misr misr_request; + struct mdp_blend_cfg blend_cfg; + struct mdp_mixer_cfg mixer_cfg; + uint32_t panel_frame_rate; + uint32_t video_info_code; + struct mdss_hw_caps caps; + } data; +}; + +#define MDP_MAX_FENCE_FD 32 +#define MDP_BUF_SYNC_FLAG_WAIT 1 + +struct mdp_buf_sync { + uint32_t flags; + uint32_t acq_fen_fd_cnt; + uint32_t session_id; + int *acq_fen_fd; + int *rel_fen_fd; +}; + +struct mdp_async_blit_req_list { + struct mdp_buf_sync sync; + uint32_t count; + struct mdp_blit_req req[]; +}; + +#define MDP_DISPLAY_COMMIT_OVERLAY 1 +struct mdp_buf_fence { + uint32_t flags; + uint32_t acq_fen_fd_cnt; + int acq_fen_fd[MDP_MAX_FENCE_FD]; + int rel_fen_fd[MDP_MAX_FENCE_FD]; +}; + + +struct mdp_display_commit { + uint32_t flags; + uint32_t wait_for_finish; + struct fb_var_screeninfo var; + struct mdp_buf_fence buf_fence; + struct mdp_rect roi; +}; + +struct mdp_page_protection { + uint32_t page_protection; +}; + + +struct mdp_mixer_info { + int pndx; + int pnum; + int ptype; + int mixer_num; + int z_order; +}; + +#define MAX_PIPE_PER_MIXER 4 + +struct msmfb_mixer_info_req { + int mixer_num; + int cnt; + struct mdp_mixer_info info[MAX_PIPE_PER_MIXER]; +}; + +enum { + DISPLAY_SUBSYSTEM_ID, + ROTATOR_SUBSYSTEM_ID, +}; + +enum { + MDP_IOMMU_DOMAIN_CP, + MDP_IOMMU_DOMAIN_NS, +}; + +enum { + MDP_WRITEBACK_MIRROR_OFF, + MDP_WRITEBACK_MIRROR_ON, + MDP_WRITEBACK_MIRROR_PAUSE, + MDP_WRITEBACK_MIRROR_RESUME, +}; + + +#endif /*_MSM_MDP_H_*/ diff --git a/minuitwrp/minui.h b/minuitwrp/minui.h new file mode 100644 index 000000000..6033da728 --- /dev/null +++ b/minuitwrp/minui.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MINUI_H_ +#define _MINUI_H_ + +typedef void* gr_surface; +typedef unsigned short gr_pixel; + +#define FONT_TYPE_TWRP 0 + +#ifndef TW_DISABLE_TTF +#define FONT_TYPE_TTF 1 +#endif + +int gr_init(void); +void gr_exit(void); + +int gr_fb_width(void); +int gr_fb_height(void); +gr_pixel *gr_fb_data(void); +void gr_flip(void); +int gr_fb_blank(int blank); + +void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a); +void gr_clip(int x, int y, int w, int h); +void gr_noclip(); +void gr_fill(int x, int y, int w, int h); +void gr_line(int x0, int y0, int x1, int y1, int width); +gr_surface gr_render_circle(int radius, unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +int gr_textEx(int x, int y, const char *s, void* font); +int gr_textExW(int x, int y, const char *s, void* font, int max_width); +int gr_textExWH(int x, int y, const char *s, void* pFont, int max_width, int max_height); +static inline int gr_text(int x, int y, const char *s) { return gr_textEx(x, y, s, NULL); } +int gr_measureEx(const char *s, void* font); +static inline int gr_measure(const char *s) { return gr_measureEx(s, NULL); } +int gr_maxExW(const char *s, void* font, int max_width); + +int gr_getMaxFontHeight(void *font); + +void* gr_loadFont(const char* fontName); +void gr_freeFont(void *font); + +#ifndef TW_DISABLE_TTF +void *gr_ttf_loadFont(const char *filename, int size, int dpi); +void gr_ttf_freeFont(void *font); +int gr_ttf_textExWH(void *context, int x, int y, const char *s, void *pFont, int max_width, int max_height); +int gr_ttf_measureEx(const char *s, void *font); +int gr_ttf_maxExW(const char *s, void *font, int max_width); +int gr_ttf_getMaxFontHeight(void *font); +void gr_ttf_dump_stats(void); +#endif + +void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy); +unsigned int gr_get_width(gr_surface surface); +unsigned int gr_get_height(gr_surface surface); +int gr_get_surface(gr_surface* surface); +int gr_free_surface(gr_surface surface); + +// Functions in graphics_utils.c +int gr_save_screenshot(const char *dest); + +// input event structure, include <linux/input.h> for the definition. +// see http://www.mjmwired.net/kernel/Documentation/input/ for info. +struct input_event; + +int ev_init(void); +void ev_exit(void); +int ev_get(struct input_event *ev, int timeout_ms); +int ev_has_mouse(void); + +// Resources + +// Returns 0 if no error, else negative. +int res_create_surface(const char* name, gr_surface* pSurface); +void res_free_surface(gr_surface surface); +int res_scale_surface(gr_surface source, gr_surface* destination, float scale_w, float scale_h); + +// Needed for AOSP: +int ev_wait(int timeout); +void ev_dispatch(void); +int ev_get_input(int fd, short revents, struct input_event *ev); + +int vibrate(int timeout_ms); + +#endif diff --git a/minuitwrp/mkfont.c b/minuitwrp/mkfont.c new file mode 100644 index 000000000..409316cb1 --- /dev/null +++ b/minuitwrp/mkfont.c @@ -0,0 +1,54 @@ +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char *argv) +{ + unsigned n; + unsigned char *x; + unsigned m; + unsigned run_val; + unsigned run_count; + + n = gimp_image.width * gimp_image.height; + m = 0; + x = gimp_image.pixel_data; + + printf("struct {\n"); + printf(" unsigned width;\n"); + printf(" unsigned height;\n"); + printf(" unsigned cwidth;\n"); + printf(" unsigned cheight;\n"); + printf(" unsigned char rundata[];\n"); + printf("} font = {\n"); + printf(" .width = %d,\n .height = %d,\n .cwidth = %d,\n .cheight = %d,\n", gimp_image.width, gimp_image.height, + gimp_image.width / 96, gimp_image.height); + printf(" .rundata = {\n"); + + run_val = (*x ? 0 : 255); + run_count = 1; + n--; + x+=3; + + while(n-- > 0) { + unsigned val = (*x ? 0 : 255); + x+=3; + if((val == run_val) && (run_count < 127)) { + run_count++; + } else { +eject: + printf("0x%02x,",run_count | (run_val ? 0x80 : 0x00)); + run_val = val; + run_count = 1; + m += 5; + if(m >= 75) { + printf("\n"); + m = 0; + } + } + } + printf("0x%02x,",run_count | (run_val ? 0x80 : 0x00)); + printf("\n0x00,"); + printf("\n"); + printf(" }\n};\n"); + return 0; +} diff --git a/minuitwrp/resources.c b/minuitwrp/resources.c new file mode 100644 index 000000000..3e3375d11 --- /dev/null +++ b/minuitwrp/resources.c @@ -0,0 +1,442 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <unistd.h> + +#include <fcntl.h> +#include <stdio.h> + +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/types.h> + +#include <linux/fb.h> +#include <linux/kd.h> + +#include <pixelflinger/pixelflinger.h> + +#include <png.h> +#include "jpeglib.h" + +#include "minui.h" + +// libpng gives "undefined reference to 'pow'" errors, and I have no +// idea how to convince the build system to link with -lm. We don't +// need this functionality (it's used for gamma adjustment) so provide +// a dummy implementation to satisfy the linker. +double pow(double x, double y) { + return x; +} + +#define SURFACE_DATA_ALIGNMENT 8 + +static GGLSurface* malloc_surface(size_t data_size) { + unsigned char* temp = malloc(sizeof(GGLSurface) + data_size + SURFACE_DATA_ALIGNMENT); + if (temp == NULL) return NULL; + GGLSurface* surface = (GGLSurface*) temp; + surface->data = temp + sizeof(GGLSurface) + + (SURFACE_DATA_ALIGNMENT - (sizeof(GGLSurface) % SURFACE_DATA_ALIGNMENT)); + return surface; +} + +static int open_png(const char* name, png_structp* png_ptr, png_infop* info_ptr, + png_uint_32* width, png_uint_32* height, png_byte* channels, FILE** fpp) { + char resPath[256]; + unsigned char header[8]; + int result = 0; + + snprintf(resPath, sizeof(resPath)-1, TWRES "images/%s.png", name); + printf("open_png %s\n", resPath); + resPath[sizeof(resPath)-1] = '\0'; + FILE* fp = fopen(resPath, "rb"); + if (fp == NULL) { + fp = fopen(name, "rb"); + if (fp == NULL) { + result = -1; + goto exit; + } + } + + size_t bytesRead = fread(header, 1, sizeof(header), fp); + if (bytesRead != sizeof(header)) { + result = -2; + goto exit; + } + + if (png_sig_cmp(header, 0, sizeof(header))) { + result = -3; + goto exit; + } + + *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!*png_ptr) { + result = -4; + goto exit; + } + + *info_ptr = png_create_info_struct(*png_ptr); + if (!*info_ptr) { + result = -5; + goto exit; + } + + if (setjmp(png_jmpbuf(*png_ptr))) { + result = -6; + goto exit; + } + + png_init_io(*png_ptr, fp); + png_set_sig_bytes(*png_ptr, sizeof(header)); + png_read_info(*png_ptr, *info_ptr); + + int color_type, bit_depth; + png_get_IHDR(*png_ptr, *info_ptr, width, height, &bit_depth, + &color_type, NULL, NULL, NULL); + + *channels = png_get_channels(*png_ptr, *info_ptr); + + /*if (bit_depth == 8 && *channels == 3 && color_type == PNG_COLOR_TYPE_RGB) { + // 8-bit RGB images: great, nothing to do. + } else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_GRAY) { + // 1-, 2-, 4-, or 8-bit gray images: expand to 8-bit gray. + png_set_expand_gray_1_2_4_to_8(*png_ptr); + } else if (bit_depth <= 8 && *channels == 1 && color_type == PNG_COLOR_TYPE_PALETTE) { + // paletted images: expand to 8-bit RGB. Note that we DON'T + // currently expand the tRNS chunk (if any) to an alpha + // channel, because minui doesn't support alpha channels in + // general. + png_set_palette_to_rgb(*png_ptr); + *channels = 3; + } else { + fprintf(stderr, "minui doesn't support PNG depth %d channels %d color_type %d\n", + bit_depth, *channels, color_type); + result = -7; + goto exit; + }*/ + if (color_type == PNG_COLOR_TYPE_PALETTE) { + png_set_palette_to_rgb(png_ptr); + } + + *fpp = fp; + return result; + + exit: + if (result < 0) { + png_destroy_read_struct(png_ptr, info_ptr, NULL); + } + if (fp != NULL) { + fclose(fp); + } + + return result; +} + +// "display" surfaces are transformed into the framebuffer's required +// pixel format (currently only RGBX is supported) at load time, so +// gr_blit() can be nothing more than a memcpy() for each row. The +// next two functions are the only ones that know anything about the +// framebuffer pixel format; they need to be modified if the +// framebuffer format changes (but nothing else should). + +// Allocate and return a gr_surface sufficient for storing an image of +// the indicated size in the framebuffer pixel format. +static GGLSurface* init_display_surface(png_uint_32 width, png_uint_32 height) { + GGLSurface* surface; + + surface = (GGLSurface*) malloc_surface(width * height * 4); + if (surface == NULL) return NULL; + + surface->version = sizeof(GGLSurface); + surface->width = width; + surface->height = height; + surface->stride = width; + + return surface; +} + +// Copy 'input_row' to 'output_row', transforming it to the +// framebuffer pixel format. The input format depends on the value of +// 'channels': +// +// 1 - input is 8-bit grayscale +// 3 - input is 24-bit RGB +// 4 - input is 32-bit RGBA/RGBX +// +// 'width' is the number of pixels in the row. +static void transform_rgb_to_draw(unsigned char* input_row, + unsigned char* output_row, + int channels, int width) { + int x; + unsigned char* ip = input_row; + unsigned char* op = output_row; + + switch (channels) { + case 1: + // expand gray level to RGBX + for (x = 0; x < width; ++x) { + *op++ = *ip; + *op++ = *ip; + *op++ = *ip; + *op++ = 0xff; + ip++; + } + break; + + case 3: + // expand RGBA to RGBX + for (x = 0; x < width; ++x) { + *op++ = *ip++; + *op++ = *ip++; + *op++ = *ip++; + *op++ = 0xff; + } + break; + + case 4: + // copy RGBA to RGBX + memcpy(output_row, input_row, width*4); + break; + } +} + +int res_create_surface_png(const char* name, gr_surface* pSurface) { + GGLSurface* surface = NULL; + int result = 0; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + png_uint_32 width, height; + png_byte channels; + FILE* fp; + + *pSurface = NULL; + + result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels, &fp); + if (result < 0) return result; + + surface = init_display_surface(width, height); + if (surface == NULL) { + result = -8; + goto exit; + } + + unsigned char* p_row = malloc(width * 4); + unsigned int y; + for (y = 0; y < height; ++y) { + png_read_row(png_ptr, p_row, NULL); + transform_rgb_to_draw(p_row, surface->data + y * width * 4, channels, width); + } + free(p_row); + + if (channels == 3) + surface->format = GGL_PIXEL_FORMAT_RGBX_8888; + else + surface->format = GGL_PIXEL_FORMAT_RGBA_8888; + + *pSurface = (gr_surface) surface; + + exit: + fclose(fp); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + if (result < 0 && surface != NULL) free(surface); + return result; +} + +int res_create_surface_jpg(const char* name, gr_surface* pSurface) { + GGLSurface* surface = NULL; + int result = 0; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + + FILE* fp = fopen(name, "rb"); + if (fp == NULL) { + char resPath[256]; + + snprintf(resPath, sizeof(resPath)-1, TWRES "images/%s", name); + resPath[sizeof(resPath)-1] = '\0'; + fp = fopen(resPath, "rb"); + if (fp == NULL) { + result = -1; + goto exit; + } + } + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + + /* Specify data source for decompression */ + jpeg_stdio_src(&cinfo, fp); + + /* Read file header, set default decompression parameters */ + if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) + goto exit; + + /* Start decompressor */ + (void) jpeg_start_decompress(&cinfo); + + size_t width = cinfo.image_width; + size_t height = cinfo.image_height; + size_t stride = 4 * width; + size_t pixelSize = stride * height; + + surface = malloc(sizeof(GGLSurface) + pixelSize); + if (surface == NULL) { + result = -8; + goto exit; + } + + unsigned char* pData = (unsigned char*) (surface + 1); + surface->version = sizeof(GGLSurface); + surface->width = width; + surface->height = height; + surface->stride = width; /* Yes, pixels, not bytes */ + surface->data = pData; + surface->format = GGL_PIXEL_FORMAT_RGBX_8888; + + int y; + for (y = 0; y < (int) height; ++y) { + unsigned char* pRow = pData + y * stride; + jpeg_read_scanlines(&cinfo, &pRow, 1); + + int x; + for(x = width - 1; x >= 0; x--) { + int sx = x * 3; + int dx = x * 4; + unsigned char r = pRow[sx]; + unsigned char g = pRow[sx + 1]; + unsigned char b = pRow[sx + 2]; + unsigned char a = 0xff; + pRow[dx ] = r; // r + pRow[dx + 1] = g; // g + pRow[dx + 2] = b; // b + pRow[dx + 3] = a; + } + } + *pSurface = (gr_surface) surface; + +exit: + if (fp != NULL) + { + if (surface) + { + (void) jpeg_finish_decompress(&cinfo); + if (result < 0) + { + free(surface); + } + } + jpeg_destroy_decompress(&cinfo); + fclose(fp); + } + return result; +} + +int res_create_surface(const char* name, gr_surface* pSurface) { + int ret; + + if (!name) return -1; + + if (strlen(name) > 4 && strcmp(name + strlen(name) - 4, ".jpg") == 0) + return res_create_surface_jpg(name,pSurface); + + ret = res_create_surface_png(name,pSurface); + if (ret < 0) + ret = res_create_surface_jpg(name,pSurface); + + return ret; +} + +void res_free_surface(gr_surface surface) { + GGLSurface* pSurface = (GGLSurface*) surface; + if (pSurface) { + free(pSurface); + } +} + +// Scale image function +int res_scale_surface(gr_surface source, gr_surface* destination, float scale_w, float scale_h) { + GGLContext *gl = NULL; + GGLSurface* sc_mem_surface = NULL; + *destination = NULL; + GGLSurface *surface = (GGLSurface*)source; + int w = gr_get_width(source), h = gr_get_height(source); + int sx = 0, sy = 0, dx = 0, dy = 0; + float dw = (float)w * scale_w; + float dh = (float)h * scale_h; + + // Create a new surface that is the appropriate size + sc_mem_surface = init_display_surface((int)dw, (int)dh); + if (!sc_mem_surface) { + printf("gr_scale_surface failed to init_display_surface\n"); + return -1; + } + sc_mem_surface->format = surface->format; + + // Initialize the context + gglInit(&gl); + gl->colorBuffer(gl, sc_mem_surface); + gl->activeTexture(gl, 0); + + // Enable or disable blending based on source surface format + if (surface->format == GGL_PIXEL_FORMAT_RGBX_8888) { + gl->disable(gl, GGL_BLEND); + } else { + gl->enable(gl, GGL_BLEND); + gl->blendFunc(gl, GGL_ONE, GGL_ZERO); + } + + // Bind our source surface to the context + gl->bindTexture(gl, surface); + + // Deal with the scaling + gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_MIN_FILTER, GGL_LINEAR); + gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_MAG_FILTER, GGL_LINEAR); + gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP); + gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP); + gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); + gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC); + gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC); + gl->enable(gl, GGL_TEXTURE_2D); + + int32_t grad[8]; + memset(grad, 0, sizeof(grad)); + // s, dsdx, dsdy, scale, t, dtdx, dtdy, tscale <- this is wrong! + // This api uses block floating-point for S and T texture coordinates. + // All values are given in 16.16, scaled by 'scale'. In other words, + // set scale to 0, for 16.16 values. + + // s, dsdx, dsdy, t, dtdx, dtdy, sscale, tscale + float dsdx = (float)w / dw; + float dtdy = (float)h / dh; + grad[0] = ((float)sx - (dsdx * dx)) * 65536; + grad[1] = dsdx * 65536; + grad[3] = ((float)sy - (dtdy * dy)) * 65536; + grad[5] = dtdy * 65536; +// printf("blit: w=%d h=%d dx=%d dy=%d dw=%f dh=%f dsdx=%f dtdy=%f s0=%x dsdx=%x t0=%x dtdy=%x\n", +// w, h, dx, dy, dw, dh, dsdx, dtdy, grad[0], grad[1], grad[3], grad[5]); + gl->texCoordGradScale8xv(gl, 0 /*tmu*/, grad); + + // draw / scale the source surface to our target context + gl->recti(gl, dx, dy, dx + dw, dy + dh); + gglUninit(gl); + gl = NULL; + // put the scaled surface in our destination + *destination = (gr_surface*) sc_mem_surface; + // free memory used in the source + res_free_surface(source); + source = NULL; + return 0; +} diff --git a/minuitwrp/roboto_10x18.h b/minuitwrp/roboto_10x18.h new file mode 100644 index 000000000..3119c81c2 --- /dev/null +++ b/minuitwrp/roboto_10x18.h @@ -0,0 +1,197 @@ +struct { + unsigned width; + unsigned height; + unsigned cwidth; + unsigned cheight; + unsigned char rundata[]; +} font = { + .width = 960, + .height = 18, + .cwidth = 10, + .cheight = 18, + .rundata = { +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x3b,0x81,0x29,0x81,0x06,0x81,0x3f,0x81,0x7f,0x7f,0x7f,0x37,0x83,0x05,0x81, +0x0a,0x83,0x7f,0x7f,0x2f,0x81,0x0e,0x81,0x29,0x82,0x07,0x81,0x01,0x82,0x07, +0x81,0x02,0x81,0x05,0x83,0x05,0x82,0x0a,0x82,0x09,0x82,0x09,0x81,0x08,0x81, +0x3e,0x81,0x05,0x84,0x06,0x84,0x06,0x83,0x06,0x84,0x09,0x82,0x05,0x85,0x06, +0x84,0x04,0x87,0x04,0x84,0x07,0x84,0x39,0x83,0x06,0x84,0x07,0x81,0x06,0x86, +0x06,0x84,0x04,0x86,0x04,0x87,0x04,0x87,0x04,0x84,0x04,0x82,0x04,0x82,0x03, +0x86,0x08,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x07,0x82,0x05,0x82,0x02,0x82, +0x05,0x81,0x04,0x84,0x04,0x86,0x06,0x84,0x04,0x86,0x06,0x84,0x04,0x88,0x02, +0x82,0x05,0x81,0x01,0x82,0x06,0x81,0x01,0x81,0x07,0x81,0x02,0x81,0x05,0x82, +0x02,0x82,0x04,0x82,0x02,0x87,0x06,0x81,0x07,0x82,0x0b,0x81,0x08,0x81,0x12, +0x82,0x10,0x82,0x18,0x82,0x10,0x83,0x0d,0x82,0x0b,0x82,0x08,0x82,0x06,0x82, +0x09,0x83,0x4c,0x82,0x48,0x81,0x07,0x82,0x07,0x81,0x28,0x82,0x07,0x81,0x01, +0x82,0x07,0x81,0x02,0x81,0x04,0x82,0x01,0x82,0x03,0x81,0x02,0x81,0x08,0x81, +0x02,0x81,0x08,0x82,0x08,0x82,0x08,0x82,0x3c,0x82,0x04,0x82,0x02,0x82,0x04, +0x85,0x05,0x82,0x01,0x82,0x04,0x82,0x02,0x82,0x07,0x83,0x05,0x85,0x05,0x82, +0x02,0x81,0x09,0x82,0x03,0x82,0x02,0x82,0x05,0x82,0x02,0x82,0x37,0x82,0x01, +0x82,0x04,0x81,0x03,0x82,0x06,0x82,0x05,0x82,0x03,0x82,0x04,0x83,0x01,0x82, +0x03,0x82,0x03,0x82,0x03,0x82,0x09,0x82,0x08,0x82,0x02,0x82,0x03,0x82,0x04, +0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x07,0x82,0x05,0x82, +0x02,0x82,0x05,0x81,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02, +0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x05,0x81, +0x02,0x81,0x05,0x82,0x01,0x81,0x07,0x81,0x02,0x82,0x04,0x81,0x03,0x82,0x04, +0x82,0x07,0x82,0x06,0x81,0x08,0x81,0x0b,0x81,0x07,0x82,0x13,0x81,0x10,0x82, +0x18,0x82,0x0f,0x84,0x0d,0x82,0x1d,0x82,0x0a,0x82,0x4c,0x82,0x47,0x82,0x07, +0x82,0x07,0x82,0x27,0x82,0x07,0x81,0x01,0x82,0x06,0x81,0x02,0x81,0x04,0x82, +0x03,0x82,0x02,0x81,0x02,0x81,0x02,0x81,0x04,0x82,0x02,0x82,0x08,0x81,0x08, +0x81,0x0a,0x81,0x12,0x82,0x28,0x81,0x05,0x81,0x04,0x81,0x07,0x82,0x04,0x82, +0x03,0x82,0x03,0x81,0x04,0x81,0x07,0x83,0x05,0x81,0x08,0x82,0x0c,0x82,0x04, +0x81,0x04,0x82,0x04,0x81,0x04,0x81,0x36,0x82,0x03,0x81,0x03,0x81,0x05,0x82, +0x04,0x83,0x05,0x82,0x04,0x81,0x03,0x83,0x03,0x82,0x02,0x82,0x04,0x82,0x02, +0x82,0x09,0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x0a,0x82, +0x03,0x82,0x02,0x82,0x04,0x82,0x07,0x83,0x03,0x83,0x02,0x83,0x04,0x81,0x02, +0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x81, +0x03,0x82,0x04,0x81,0x06,0x82,0x05,0x82,0x05,0x81,0x02,0x81,0x05,0x82,0x01, +0x82,0x02,0x81,0x02,0x82,0x03,0x82,0x02,0x82,0x04,0x81,0x03,0x82,0x08,0x81, +0x07,0x81,0x08,0x81,0x0b,0x81,0x07,0x83,0x13,0x81,0x0f,0x82,0x18,0x82,0x0e, +0x82,0x10,0x82,0x1d,0x82,0x0a,0x82,0x4c,0x82,0x47,0x81,0x08,0x82,0x08,0x81, +0x27,0x82,0x07,0x81,0x01,0x81,0x05,0x88,0x02,0x82,0x07,0x81,0x02,0x81,0x01, +0x82,0x05,0x81,0x02,0x81,0x08,0x81,0x08,0x82,0x0a,0x82,0x07,0x81,0x09,0x82, +0x27,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x0a,0x81,0x08,0x81,0x06,0x81,0x01, +0x82,0x05,0x81,0x08,0x82,0x0c,0x81,0x05,0x81,0x04,0x82,0x04,0x81,0x04,0x81, +0x05,0x82,0x08,0x82,0x2a,0x81,0x03,0x81,0x02,0x81,0x03,0x81,0x04,0x81,0x01, +0x82,0x04,0x82,0x04,0x81,0x03,0x82,0x04,0x82,0x02,0x82,0x05,0x81,0x02,0x82, +0x09,0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03, +0x82,0x02,0x81,0x05,0x82,0x07,0x83,0x03,0x83,0x02,0x84,0x03,0x81,0x02,0x82, +0x05,0x81,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02, +0x82,0x0b,0x82,0x05,0x82,0x05,0x81,0x02,0x82,0x04,0x81,0x03,0x81,0x02,0x82, +0x01,0x82,0x04,0x81,0x01,0x82,0x05,0x82,0x01,0x82,0x08,0x82,0x07,0x81,0x08, +0x82,0x0a,0x81,0x06,0x82,0x01,0x81,0x1a,0x85,0x04,0x82,0x01,0x83,0x06,0x84, +0x06,0x83,0x01,0x82,0x04,0x84,0x06,0x82,0x07,0x85,0x04,0x82,0x01,0x83,0x06, +0x83,0x08,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x05,0x81,0x01,0x82,0x01,0x82, +0x03,0x82,0x01,0x84,0x05,0x84,0x04,0x82,0x01,0x83,0x06,0x83,0x01,0x82,0x03, +0x82,0x01,0x84,0x04,0x84,0x04,0x86,0x04,0x82,0x04,0x82,0x02,0x82,0x04,0x81, +0x02,0x82,0x06,0x81,0x02,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x03,0x86,0x07, +0x81,0x08,0x82,0x08,0x81,0x27,0x82,0x11,0x81,0x02,0x81,0x05,0x82,0x06,0x84, +0x01,0x81,0x06,0x83,0x12,0x82,0x0a,0x82,0x05,0x81,0x01,0x81,0x01,0x81,0x07, +0x82,0x27,0x81,0x05,0x82,0x04,0x82,0x06,0x82,0x09,0x82,0x07,0x82,0x05,0x82, +0x01,0x82,0x04,0x85,0x05,0x81,0x01,0x83,0x08,0x82,0x06,0x81,0x02,0x82,0x05, +0x81,0x04,0x81,0x05,0x82,0x08,0x82,0x0a,0x83,0x04,0x86,0x04,0x82,0x0c,0x82, +0x02,0x81,0x02,0x81,0x01,0x81,0x02,0x81,0x04,0x81,0x01,0x82,0x04,0x82,0x03, +0x82,0x03,0x82,0x08,0x82,0x05,0x81,0x02,0x82,0x09,0x82,0x07,0x81,0x09,0x82, +0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x01,0x82,0x05,0x82,0x07,0x84,0x02, +0x83,0x02,0x82,0x01,0x81,0x03,0x81,0x02,0x82,0x05,0x81,0x02,0x82,0x04,0x82, +0x02,0x81,0x06,0x81,0x02,0x82,0x03,0x82,0x04,0x82,0x0a,0x82,0x05,0x82,0x05, +0x81,0x03,0x81,0x03,0x82,0x03,0x81,0x01,0x81,0x01,0x81,0x01,0x81,0x05,0x83, +0x07,0x84,0x07,0x82,0x08,0x81,0x09,0x81,0x0a,0x81,0x06,0x81,0x02,0x81,0x19, +0x82,0x02,0x83,0x03,0x83,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x83, +0x03,0x82,0x02,0x82,0x04,0x85,0x04,0x83,0x01,0x83,0x03,0x83,0x02,0x82,0x06, +0x82,0x08,0x82,0x06,0x82,0x02,0x81,0x07,0x82,0x05,0x82,0x01,0x82,0x01,0x82, +0x02,0x83,0x03,0x82,0x03,0x82,0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02, +0x83,0x03,0x83,0x03,0x81,0x03,0x82,0x02,0x82,0x04,0x82,0x07,0x82,0x04,0x82, +0x03,0x81,0x03,0x82,0x02,0x82,0x02,0x82,0x02,0x81,0x03,0x82,0x02,0x81,0x05, +0x81,0x04,0x82,0x07,0x81,0x08,0x81,0x08,0x82,0x08,0x81,0x27,0x82,0x11,0x81, +0x02,0x81,0x06,0x83,0x08,0x81,0x07,0x82,0x13,0x82,0x0a,0x82,0x05,0x85,0x04, +0x88,0x23,0x82,0x05,0x82,0x04,0x82,0x06,0x82,0x08,0x82,0x06,0x83,0x06,0x81, +0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x07,0x81,0x08,0x83,0x06, +0x82,0x02,0x82,0x19,0x83,0x11,0x83,0x09,0x82,0x03,0x81,0x01,0x81,0x02,0x81, +0x02,0x81,0x03,0x82,0x02,0x81,0x04,0x86,0x04,0x82,0x08,0x82,0x05,0x81,0x02, +0x86,0x05,0x86,0x03,0x81,0x09,0x88,0x05,0x82,0x0a,0x82,0x03,0x84,0x06,0x82, +0x07,0x82,0x01,0x81,0x01,0x81,0x01,0x82,0x02,0x82,0x01,0x82,0x02,0x81,0x02, +0x82,0x05,0x81,0x02,0x82,0x03,0x82,0x03,0x81,0x06,0x81,0x02,0x86,0x06,0x83, +0x08,0x82,0x05,0x82,0x05,0x81,0x03,0x82,0x02,0x81,0x04,0x81,0x01,0x81,0x01, +0x81,0x01,0x81,0x06,0x82,0x08,0x82,0x08,0x81,0x09,0x81,0x09,0x82,0x09,0x81, +0x06,0x81,0x02,0x82,0x1d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x81,0x03, +0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82, +0x04,0x82,0x05,0x82,0x08,0x82,0x06,0x82,0x01,0x81,0x08,0x82,0x05,0x82,0x01, +0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82, +0x02,0x82,0x04,0x82,0x03,0x82,0x08,0x81,0x09,0x82,0x07,0x82,0x04,0x82,0x03, +0x82,0x02,0x81,0x04,0x81,0x02,0x82,0x02,0x81,0x04,0x81,0x01,0x82,0x05,0x82, +0x02,0x82,0x07,0x82,0x08,0x81,0x08,0x82,0x08,0x81,0x07,0x83,0x03,0x81,0x19, +0x82,0x11,0x81,0x02,0x81,0x08,0x82,0x07,0x81,0x01,0x82,0x03,0x82,0x01,0x81, +0x02,0x82,0x0e,0x81,0x0c,0x81,0x06,0x82,0x06,0x88,0x0d,0x86,0x10,0x81,0x06, +0x82,0x04,0x82,0x06,0x82,0x07,0x82,0x09,0x82,0x04,0x82,0x02,0x82,0x09,0x82, +0x03,0x81,0x04,0x82,0x05,0x82,0x06,0x82,0x03,0x81,0x06,0x85,0x18,0x82,0x15, +0x83,0x06,0x82,0x04,0x81,0x01,0x81,0x02,0x81,0x02,0x81,0x03,0x81,0x03,0x82, +0x03,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x05,0x81,0x02,0x82,0x09,0x82,0x07, +0x81,0x03,0x84,0x02,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x01,0x82, +0x05,0x82,0x07,0x82,0x01,0x81,0x01,0x81,0x01,0x82,0x02,0x82,0x02,0x82,0x01, +0x81,0x02,0x82,0x05,0x81,0x02,0x86,0x04,0x81,0x06,0x81,0x02,0x82,0x03,0x82, +0x07,0x82,0x07,0x82,0x05,0x82,0x05,0x81,0x03,0x82,0x02,0x81,0x04,0x83,0x01, +0x83,0x05,0x83,0x08,0x82,0x07,0x82,0x09,0x81,0x0a,0x81,0x09,0x81,0x25,0x85, +0x03,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x88,0x04,0x82,0x06, +0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x08,0x82,0x06,0x84,0x08,0x82, +0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02, +0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x08,0x83,0x07,0x82,0x07,0x82, +0x04,0x82,0x04,0x81,0x02,0x81,0x04,0x81,0x02,0x82,0x02,0x81,0x05,0x82,0x06, +0x82,0x02,0x82,0x06,0x82,0x07,0x82,0x09,0x82,0x09,0x82,0x04,0x82,0x01,0x82, +0x01,0x82,0x2a,0x87,0x08,0x82,0x05,0x81,0x01,0x81,0x02,0x81,0x02,0x81,0x02, +0x82,0x01,0x82,0x0e,0x81,0x0c,0x81,0x05,0x82,0x01,0x82,0x07,0x82,0x26,0x81, +0x06,0x82,0x04,0x82,0x06,0x82,0x06,0x82,0x0b,0x82,0x03,0x87,0x08,0x82,0x03, +0x81,0x04,0x82,0x05,0x82,0x06,0x81,0x04,0x82,0x09,0x81,0x18,0x82,0x08,0x86, +0x08,0x82,0x06,0x82,0x04,0x81,0x01,0x81,0x02,0x81,0x02,0x81,0x03,0x86,0x03, +0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x05,0x81,0x02,0x82,0x09,0x82,0x07,0x82, +0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04, +0x82,0x07,0x82,0x01,0x83,0x01,0x82,0x02,0x82,0x03,0x81,0x01,0x81,0x02,0x82, +0x05,0x81,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x81,0x08,0x82,0x06, +0x82,0x05,0x82,0x05,0x81,0x04,0x81,0x01,0x82,0x05,0x82,0x02,0x82,0x05,0x81, +0x01,0x82,0x07,0x82,0x06,0x82,0x0a,0x81,0x0a,0x81,0x09,0x81,0x24,0x82,0x02, +0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,0x82, +0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x08,0x82,0x06,0x84,0x08, +0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82, +0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0b,0x83,0x04,0x82,0x07, +0x82,0x04,0x82,0x04,0x81,0x01,0x82,0x04,0x81,0x01,0x81,0x01,0x81,0x01,0x82, +0x05,0x82,0x07,0x81,0x02,0x82,0x06,0x81,0x0a,0x81,0x08,0x82,0x08,0x81,0x06, +0x81,0x03,0x83,0x2c,0x81,0x02,0x81,0x05,0x81,0x04,0x82,0x04,0x81,0x02,0x81, +0x02,0x81,0x01,0x82,0x03,0x83,0x0f,0x82,0x0a,0x82,0x11,0x82,0x25,0x82,0x07, +0x81,0x04,0x81,0x07,0x82,0x05,0x82,0x07,0x81,0x04,0x82,0x03,0x87,0x03,0x81, +0x04,0x82,0x03,0x81,0x04,0x82,0x05,0x81,0x07,0x81,0x04,0x82,0x08,0x82,0x19, +0x84,0x10,0x83,0x0e,0x81,0x01,0x81,0x02,0x81,0x01,0x82,0x02,0x82,0x04,0x81, +0x03,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x09, +0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x81,0x04,0x82, +0x03,0x82,0x03,0x81,0x04,0x82,0x07,0x82,0x02,0x81,0x02,0x82,0x02,0x82,0x03, +0x83,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82, +0x02,0x81,0x05,0x81,0x06,0x82,0x05,0x83,0x03,0x82,0x04,0x83,0x06,0x82,0x02, +0x82,0x04,0x82,0x02,0x81,0x07,0x82,0x06,0x81,0x0b,0x81,0x0a,0x82,0x08,0x81, +0x23,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x81,0x03,0x82,0x04, +0x82,0x02,0x82,0x0a,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82, +0x08,0x82,0x06,0x82,0x01,0x82,0x07,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02, +0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82, +0x03,0x82,0x0d,0x81,0x04,0x82,0x07,0x82,0x03,0x83,0x04,0x83,0x06,0x82,0x02, +0x82,0x05,0x81,0x01,0x82,0x06,0x84,0x06,0x81,0x0b,0x81,0x08,0x82,0x08,0x81, +0x27,0x82,0x10,0x81,0x02,0x81,0x05,0x82,0x02,0x83,0x04,0x81,0x02,0x81,0x02, +0x81,0x02,0x81,0x04,0x82,0x0f,0x82,0x0a,0x82,0x11,0x82,0x07,0x82,0x12,0x82, +0x08,0x81,0x08,0x82,0x02,0x82,0x07,0x82,0x05,0x81,0x08,0x82,0x03,0x81,0x08, +0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x06,0x81,0x07,0x82,0x02,0x82, +0x08,0x82,0x06,0x82,0x08,0x82,0x0b,0x82,0x0e,0x82,0x0a,0x82,0x04,0x81,0x01, +0x83,0x01,0x82,0x03,0x81,0x05,0x82,0x02,0x82,0x04,0x82,0x03,0x83,0x01,0x82, +0x03,0x82,0x03,0x82,0x03,0x82,0x09,0x82,0x08,0x82,0x03,0x82,0x02,0x82,0x04, +0x82,0x05,0x82,0x05,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x03,0x82,0x07,0x82, +0x05,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x09,0x82,0x02, +0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x06,0x82,0x06,0x82,0x03,0x82, +0x05,0x82,0x06,0x82,0x02,0x81,0x04,0x82,0x03,0x82,0x06,0x82,0x05,0x82,0x0b, +0x81,0x0b,0x81,0x08,0x81,0x23,0x82,0x02,0x83,0x03,0x83,0x02,0x82,0x04,0x82, +0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x03,0x82,0x04,0x82,0x06,0x83,0x01, +0x83,0x03,0x82,0x04,0x82,0x05,0x82,0x08,0x82,0x06,0x82,0x02,0x82,0x06,0x82, +0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03, +0x83,0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x08,0x82,0x02,0x82,0x04,0x82, +0x03,0x81,0x03,0x83,0x01,0x84,0x05,0x82,0x06,0x82,0x02,0x82,0x04,0x82,0x02, +0x81,0x07,0x83,0x05,0x82,0x0b,0x81,0x08,0x82,0x08,0x81,0x27,0x82,0x10,0x81, +0x02,0x81,0x06,0x85,0x09,0x82,0x04,0x84,0x01,0x82,0x0f,0x81,0x0a,0x81,0x1b, +0x82,0x12,0x82,0x08,0x81,0x09,0x84,0x08,0x82,0x04,0x87,0x04,0x84,0x09,0x82, +0x05,0x84,0x06,0x84,0x07,0x81,0x08,0x84,0x06,0x84,0x07,0x82,0x08,0x82,0x27, +0x82,0x04,0x82,0x09,0x81,0x06,0x81,0x02,0x87,0x05,0x84,0x04,0x86,0x04,0x87, +0x04,0x82,0x09,0x85,0x03,0x82,0x04,0x82,0x03,0x86,0x04,0x84,0x05,0x82,0x04, +0x82,0x02,0x87,0x02,0x82,0x05,0x82,0x02,0x82,0x05,0x81,0x04,0x84,0x04,0x82, +0x0a,0x86,0x02,0x82,0x04,0x82,0x03,0x85,0x07,0x82,0x07,0x85,0x06,0x82,0x06, +0x82,0x02,0x81,0x04,0x82,0x04,0x82,0x05,0x82,0x05,0x87,0x06,0x81,0x0b,0x82, +0x07,0x81,0x23,0x84,0x01,0x82,0x03,0x82,0x01,0x83,0x06,0x84,0x06,0x83,0x01, +0x82,0x04,0x85,0x05,0x82,0x07,0x83,0x01,0x82,0x03,0x82,0x04,0x82,0x03,0x86, +0x06,0x82,0x06,0x82,0x03,0x81,0x04,0x86,0x03,0x82,0x01,0x82,0x01,0x82,0x02, +0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x83,0x06,0x83,0x01,0x82,0x03,0x82, +0x09,0x84,0x06,0x84,0x05,0x84,0x01,0x82,0x05,0x82,0x06,0x81,0x03,0x82,0x03, +0x82,0x03,0x82,0x07,0x82,0x05,0x86,0x07,0x81,0x08,0x82,0x08,0x81,0x45,0x81, +0x27,0x81,0x0a,0x81,0x1c,0x81,0x1b,0x82,0x78,0x81,0x2e,0x82,0x7f,0x30,0x82, +0x5e,0x81,0x0c,0x81,0x07,0x81,0x0f,0x88,0x4d,0x82,0x1a,0x82,0x37,0x82,0x0e, +0x82,0x4b,0x82,0x13,0x82,0x07,0x82,0x07,0x82,0x45,0x81,0x28,0x81,0x08,0x81, +0x1c,0x81,0x1c,0x81,0x78,0x81,0x30,0x84,0x7f,0x7f,0x0e,0x83,0x0a,0x81,0x05, +0x83,0x64,0x82,0x1a,0x82,0x37,0x82,0x0e,0x82,0x4b,0x82,0x14,0x81,0x07,0x82, +0x07,0x81,0x70,0x81,0x06,0x81,0x7f,0x7f,0x7f,0x7f,0x6e,0x85,0x1a,0x82,0x38, +0x82,0x0e,0x82,0x4a,0x82,0x16,0x81,0x0e,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x62, +0x00, + } +}; diff --git a/minuitwrp/roboto_15x24.h b/minuitwrp/roboto_15x24.h new file mode 100644 index 000000000..7271d74bb --- /dev/null +++ b/minuitwrp/roboto_15x24.h @@ -0,0 +1,281 @@ +struct { + unsigned width; + unsigned height; + unsigned cwidth; + unsigned cheight; + unsigned char rundata[]; +} font = { + .width = 1440, + .height = 24, + .cwidth = 15, + .cheight = 24, + .rundata = { +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x6e,0x81,0x3e,0x81, +0x07,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x76,0x84,0x17,0x84,0x7f,0x7f,0x7f,0x7f, +0x4c,0x81,0x3d,0x82,0x07,0x82,0x5f,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x15,0x84, +0x07,0x82,0x0e,0x84,0x45,0x82,0x24,0x82,0x1a,0x83,0x16,0x82,0x10,0x82,0x0e, +0x82,0x0a,0x82,0x0d,0x84,0x7f,0x62,0x82,0x0b,0x82,0x0b,0x82,0x3b,0x82,0x0c, +0x82,0x02,0x82,0x0a,0x82,0x03,0x81,0x0a,0x84,0x08,0x83,0x0e,0x84,0x0b,0x82, +0x10,0x82,0x09,0x82,0x5e,0x81,0x09,0x84,0x0b,0x84,0x0b,0x84,0x0b,0x84,0x0e, +0x83,0x08,0x88,0x09,0x84,0x07,0x8a,0x08,0x84,0x0b,0x84,0x56,0x84,0x1c,0x82, +0x08,0x87,0x0b,0x85,0x07,0x87,0x09,0x89,0x06,0x8a,0x07,0x85,0x06,0x82,0x08, +0x82,0x06,0x86,0x0f,0x82,0x06,0x82,0x07,0x82,0x04,0x82,0x0a,0x83,0x09,0x82, +0x03,0x82,0x08,0x82,0x06,0x85,0x07,0x87,0x0b,0x85,0x07,0x87,0x0c,0x84,0x06, +0x8d,0x03,0x82,0x07,0x82,0x02,0x83,0x08,0x83,0x01,0x82,0x0a,0x82,0x02,0x82, +0x08,0x82,0x03,0x82,0x08,0x82,0x04,0x8b,0x09,0x82,0x09,0x82,0x10,0x82,0x0d, +0x81,0x1d,0x82,0x18,0x82,0x24,0x82,0x19,0x84,0x16,0x82,0x10,0x82,0x0e,0x82, +0x0a,0x82,0x0d,0x84,0x7f,0x61,0x82,0x0c,0x82,0x0c,0x82,0x3a,0x82,0x0c,0x82, +0x02,0x82,0x0a,0x82,0x03,0x81,0x08,0x87,0x06,0x82,0x01,0x82,0x0c,0x86,0x0a, +0x82,0x0f,0x82,0x0b,0x82,0x5c,0x82,0x08,0x87,0x07,0x86,0x0a,0x87,0x08,0x87, +0x0c,0x83,0x08,0x88,0x07,0x87,0x06,0x8a,0x07,0x87,0x07,0x87,0x54,0x87,0x08, +0x86,0x0c,0x82,0x08,0x89,0x07,0x88,0x06,0x89,0x07,0x89,0x06,0x8a,0x05,0x88, +0x05,0x82,0x08,0x82,0x06,0x86,0x0f,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x0a, +0x83,0x08,0x83,0x03,0x83,0x07,0x82,0x04,0x88,0x06,0x89,0x07,0x88,0x06,0x89, +0x08,0x88,0x04,0x8d,0x03,0x82,0x07,0x82,0x03,0x82,0x08,0x82,0x02,0x82,0x04, +0x81,0x05,0x82,0x03,0x82,0x06,0x82,0x04,0x82,0x07,0x83,0x04,0x8b,0x09,0x82, +0x0a,0x82,0x0f,0x82,0x0c,0x83,0x1d,0x82,0x17,0x82,0x24,0x82,0x18,0x83,0x18, +0x82,0x2c,0x82,0x0f,0x82,0x7f,0x60,0x83,0x0c,0x82,0x0d,0x82,0x39,0x82,0x0c, +0x82,0x02,0x82,0x0a,0x82,0x02,0x82,0x07,0x83,0x03,0x83,0x04,0x82,0x03,0x81, +0x04,0x81,0x06,0x83,0x03,0x82,0x09,0x82,0x0f,0x82,0x0b,0x82,0x5c,0x82,0x07, +0x82,0x04,0x82,0x0a,0x83,0x09,0x82,0x04,0x83,0x06,0x82,0x04,0x83,0x0a,0x84, +0x08,0x82,0x0d,0x82,0x13,0x82,0x06,0x82,0x04,0x83,0x06,0x82,0x04,0x82,0x52, +0x82,0x04,0x82,0x07,0x82,0x05,0x82,0x09,0x84,0x07,0x82,0x05,0x83,0x06,0x82, +0x05,0x82,0x05,0x82,0x05,0x83,0x06,0x82,0x0d,0x82,0x0d,0x82,0x05,0x82,0x04, +0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06,0x82,0x05,0x82,0x06,0x82,0x0a,0x83, +0x08,0x83,0x03,0x83,0x07,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x06, +0x82,0x05,0x82,0x05,0x82,0x05,0x83,0x06,0x83,0x04,0x83,0x08,0x83,0x08,0x82, +0x07,0x82,0x03,0x82,0x08,0x82,0x02,0x82,0x03,0x83,0x04,0x82,0x03,0x83,0x04, +0x83,0x05,0x82,0x06,0x82,0x0d,0x82,0x0a,0x82,0x0a,0x82,0x0f,0x82,0x0c,0x83, +0x1e,0x81,0x17,0x82,0x24,0x82,0x18,0x82,0x19,0x82,0x2c,0x82,0x0f,0x82,0x74, +0x82,0x69,0x82,0x0d,0x82,0x0d,0x82,0x39,0x82,0x0c,0x82,0x02,0x82,0x0a,0x82, +0x02,0x82,0x07,0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x06,0x82,0x04, +0x82,0x09,0x82,0x0e,0x82,0x0d,0x82,0x1c,0x82,0x3c,0x82,0x08,0x82,0x05,0x82, +0x09,0x83,0x09,0x82,0x05,0x82,0x05,0x83,0x05,0x82,0x09,0x85,0x07,0x82,0x0d, +0x82,0x13,0x82,0x07,0x82,0x05,0x82,0x05,0x82,0x05,0x83,0x51,0x82,0x04,0x82, +0x06,0x82,0x07,0x82,0x08,0x84,0x07,0x82,0x06,0x82,0x05,0x82,0x07,0x82,0x04, +0x82,0x06,0x83,0x05,0x82,0x0d,0x82,0x0c,0x82,0x07,0x82,0x03,0x82,0x08,0x82, +0x08,0x82,0x11,0x82,0x06,0x82,0x04,0x83,0x06,0x82,0x0a,0x84,0x06,0x84,0x03, +0x84,0x06,0x82,0x03,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x07,0x82, +0x04,0x82,0x06,0x82,0x06,0x82,0x06,0x82,0x08,0x83,0x08,0x82,0x07,0x82,0x03, +0x83,0x06,0x83,0x02,0x82,0x03,0x83,0x03,0x82,0x05,0x82,0x04,0x82,0x06,0x82, +0x05,0x83,0x0c,0x83,0x0a,0x82,0x0b,0x82,0x0e,0x82,0x0c,0x81,0x01,0x82,0x35, +0x82,0x24,0x82,0x18,0x82,0x19,0x82,0x2c,0x82,0x0f,0x82,0x74,0x82,0x69,0x82, +0x0d,0x82,0x0d,0x83,0x38,0x82,0x0c,0x82,0x02,0x81,0x0b,0x81,0x03,0x82,0x07, +0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x81,0x07,0x82,0x04,0x82,0x09,0x82, +0x0e,0x82,0x0d,0x82,0x0d,0x82,0x0d,0x82,0x3c,0x82,0x07,0x82,0x06,0x82,0x09, +0x83,0x08,0x83,0x05,0x82,0x0d,0x82,0x09,0x85,0x07,0x82,0x0d,0x82,0x12,0x83, +0x07,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x57,0x83,0x04,0x82,0x09,0x81,0x08, +0x84,0x07,0x82,0x06,0x82,0x05,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x05,0x82, +0x0d,0x82,0x0c,0x82,0x07,0x82,0x03,0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06, +0x82,0x03,0x83,0x07,0x82,0x0a,0x84,0x06,0x84,0x03,0x85,0x05,0x82,0x03,0x82, +0x07,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x06,0x83,0x05, +0x82,0x06,0x82,0x08,0x83,0x08,0x82,0x07,0x82,0x04,0x82,0x06,0x82,0x03,0x82, +0x03,0x83,0x03,0x82,0x05,0x83,0x02,0x83,0x07,0x82,0x04,0x82,0x0d,0x82,0x0b, +0x82,0x0b,0x82,0x0e,0x82,0x0b,0x82,0x01,0x82,0x29,0x84,0x08,0x82,0x01,0x84, +0x0a,0x86,0x0a,0x83,0x02,0x82,0x08,0x84,0x0a,0x86,0x0a,0x83,0x02,0x82,0x06, +0x82,0x01,0x84,0x09,0x84,0x0e,0x82,0x0a,0x82,0x04,0x83,0x08,0x82,0x07,0x81, +0x02,0x83,0x03,0x83,0x05,0x81,0x02,0x84,0x0b,0x84,0x09,0x81,0x02,0x84,0x0a, +0x83,0x02,0x82,0x08,0x81,0x02,0x84,0x08,0x84,0x08,0x88,0x07,0x82,0x06,0x82, +0x05,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x04, +0x83,0x05,0x83,0x06,0x89,0x09,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x0c,0x82, +0x02,0x81,0x08,0x8b,0x05,0x82,0x0b,0x82,0x03,0x81,0x02,0x82,0x07,0x83,0x02, +0x82,0x0a,0x81,0x0f,0x82,0x0d,0x82,0x0d,0x82,0x0d,0x82,0x3c,0x82,0x07,0x82, +0x06,0x82,0x09,0x83,0x10,0x82,0x0d,0x82,0x08,0x82,0x01,0x83,0x07,0x82,0x0d, +0x82,0x12,0x82,0x08,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x08,0x82,0x0d,0x82, +0x13,0x81,0x06,0x89,0x06,0x81,0x14,0x82,0x05,0x81,0x04,0x84,0x02,0x82,0x06, +0x82,0x02,0x82,0x06,0x82,0x06,0x82,0x04,0x82,0x0e,0x82,0x07,0x82,0x05,0x82, +0x0d,0x82,0x0b,0x82,0x0d,0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06,0x82,0x03, +0x82,0x08,0x82,0x0a,0x82,0x01,0x82,0x05,0x84,0x03,0x82,0x01,0x82,0x05,0x82, +0x02,0x82,0x09,0x82,0x03,0x82,0x07,0x82,0x03,0x82,0x09,0x82,0x03,0x82,0x06, +0x83,0x05,0x82,0x10,0x83,0x08,0x82,0x07,0x82,0x04,0x82,0x06,0x82,0x03,0x82, +0x03,0x81,0x01,0x82,0x02,0x82,0x06,0x82,0x02,0x82,0x08,0x82,0x03,0x83,0x0c, +0x82,0x0c,0x82,0x0b,0x82,0x0e,0x82,0x0b,0x82,0x02,0x81,0x28,0x87,0x06,0x88, +0x08,0x88,0x08,0x88,0x07,0x86,0x09,0x86,0x09,0x88,0x06,0x88,0x08,0x84,0x0e, +0x82,0x0a,0x82,0x03,0x83,0x09,0x82,0x07,0x87,0x01,0x85,0x04,0x88,0x09,0x87, +0x07,0x81,0x01,0x86,0x08,0x88,0x08,0x87,0x06,0x87,0x07,0x88,0x07,0x82,0x06, +0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x04,0x83,0x03,0x83, +0x05,0x82,0x05,0x82,0x07,0x89,0x09,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x1b, +0x82,0x03,0x81,0x08,0x83,0x0b,0x85,0x01,0x82,0x09,0x85,0x1a,0x83,0x0d,0x83, +0x09,0x81,0x02,0x82,0x01,0x81,0x0b,0x82,0x3b,0x82,0x08,0x82,0x06,0x82,0x09, +0x83,0x0f,0x82,0x0d,0x82,0x09,0x82,0x01,0x83,0x07,0x87,0x07,0x83,0x01,0x84, +0x0c,0x82,0x09,0x83,0x03,0x82,0x06,0x82,0x06,0x82,0x08,0x82,0x0d,0x82,0x11, +0x83,0x06,0x89,0x06,0x83,0x12,0x82,0x05,0x81,0x03,0x82,0x02,0x82,0x02,0x81, +0x06,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x05,0x82,0x0e,0x82,0x07,0x83,0x04, +0x82,0x0d,0x82,0x0b,0x82,0x0d,0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06,0x82, +0x02,0x82,0x09,0x82,0x0a,0x82,0x01,0x82,0x04,0x82,0x01,0x82,0x03,0x82,0x02, +0x82,0x04,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x07,0x82,0x03,0x82,0x09,0x82, +0x03,0x82,0x06,0x82,0x06,0x83,0x0f,0x83,0x08,0x82,0x07,0x82,0x05,0x82,0x04, +0x82,0x05,0x81,0x02,0x82,0x01,0x82,0x02,0x82,0x07,0x84,0x0a,0x82,0x02,0x82, +0x0c,0x83,0x0c,0x82,0x0c,0x82,0x0d,0x82,0x0a,0x82,0x03,0x82,0x26,0x82,0x04, +0x82,0x06,0x83,0x03,0x83,0x07,0x82,0x05,0x82,0x06,0x82,0x04,0x83,0x06,0x82, +0x04,0x82,0x0a,0x82,0x0a,0x83,0x03,0x83,0x06,0x82,0x04,0x83,0x09,0x82,0x0e, +0x82,0x0a,0x82,0x03,0x82,0x0a,0x82,0x07,0x82,0x03,0x84,0x02,0x82,0x04,0x82, +0x04,0x83,0x07,0x82,0x04,0x83,0x06,0x82,0x04,0x83,0x06,0x82,0x04,0x83,0x08, +0x83,0x0a,0x82,0x04,0x82,0x08,0x82,0x0b,0x82,0x06,0x82,0x05,0x82,0x05,0x82, +0x04,0x82,0x03,0x83,0x03,0x82,0x06,0x82,0x03,0x82,0x06,0x82,0x05,0x82,0x0d, +0x82,0x0a,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x1b,0x82,0x02,0x82,0x09,0x85, +0x0e,0x81,0x0b,0x83,0x1b,0x82,0x0f,0x82,0x09,0x87,0x0b,0x82,0x3b,0x82,0x08, +0x82,0x06,0x82,0x09,0x83,0x0e,0x83,0x09,0x85,0x09,0x82,0x02,0x83,0x07,0x88, +0x06,0x89,0x0b,0x82,0x0a,0x86,0x07,0x82,0x06,0x82,0x27,0x85,0x17,0x84,0x0f, +0x82,0x05,0x82,0x03,0x81,0x03,0x82,0x02,0x81,0x06,0x82,0x02,0x82,0x06,0x88, +0x06,0x82,0x0e,0x82,0x07,0x83,0x04,0x88,0x07,0x88,0x05,0x82,0x0d,0x8c,0x08, +0x82,0x11,0x82,0x06,0x85,0x0a,0x82,0x0a,0x82,0x01,0x82,0x04,0x82,0x01,0x82, +0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x06,0x82,0x04, +0x82,0x09,0x82,0x03,0x82,0x04,0x83,0x08,0x85,0x0c,0x83,0x08,0x82,0x07,0x82, +0x05,0x82,0x04,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x81,0x08,0x84,0x0a, +0x86,0x0c,0x82,0x0d,0x82,0x0c,0x82,0x0d,0x82,0x0a,0x82,0x03,0x82,0x26,0x82, +0x04,0x83,0x05,0x82,0x05,0x82,0x06,0x83,0x05,0x82,0x05,0x83,0x05,0x82,0x05, +0x83,0x04,0x82,0x0a,0x82,0x0a,0x82,0x05,0x82,0x06,0x82,0x05,0x82,0x09,0x82, +0x0e,0x82,0x0a,0x82,0x02,0x82,0x0b,0x82,0x07,0x82,0x03,0x83,0x03,0x83,0x03, +0x82,0x05,0x82,0x06,0x83,0x05,0x82,0x06,0x82,0x05,0x82,0x05,0x83,0x05,0x82, +0x08,0x82,0x0b,0x82,0x04,0x82,0x08,0x82,0x0b,0x82,0x06,0x82,0x06,0x82,0x04, +0x82,0x04,0x82,0x02,0x84,0x03,0x82,0x07,0x82,0x01,0x82,0x07,0x83,0x03,0x83, +0x0c,0x83,0x0a,0x82,0x0d,0x82,0x0e,0x82,0x0a,0x82,0x2c,0x82,0x1b,0x82,0x02, +0x82,0x0b,0x85,0x0b,0x82,0x09,0x85,0x1b,0x82,0x0f,0x82,0x0b,0x83,0x09,0x8b, +0x36,0x81,0x09,0x82,0x06,0x82,0x09,0x83,0x0e,0x82,0x0a,0x86,0x07,0x82,0x03, +0x83,0x07,0x82,0x04,0x83,0x05,0x84,0x03,0x83,0x09,0x82,0x0b,0x87,0x07,0x82, +0x04,0x83,0x25,0x85,0x1b,0x85,0x0b,0x82,0x06,0x82,0x02,0x82,0x03,0x82,0x02, +0x81,0x05,0x82,0x04,0x82,0x05,0x8a,0x04,0x82,0x0e,0x82,0x07,0x83,0x04,0x88, +0x07,0x88,0x05,0x82,0x04,0x86,0x03,0x8c,0x08,0x82,0x11,0x82,0x06,0x86,0x09, +0x82,0x0a,0x82,0x02,0x82,0x02,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82, +0x02,0x82,0x09,0x82,0x03,0x8a,0x04,0x82,0x09,0x82,0x03,0x89,0x0a,0x85,0x0a, +0x83,0x08,0x82,0x07,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x01,0x82,0x02,0x81, +0x01,0x82,0x09,0x82,0x0c,0x84,0x0c,0x82,0x0e,0x82,0x0d,0x82,0x0c,0x82,0x3d, +0x83,0x05,0x82,0x05,0x82,0x06,0x82,0x0d,0x82,0x06,0x82,0x05,0x82,0x06,0x82, +0x09,0x82,0x09,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,0x0a, +0x82,0x01,0x83,0x0b,0x82,0x07,0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82, +0x06,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x08,0x82,0x0b, +0x82,0x0e,0x82,0x0b,0x82,0x06,0x82,0x06,0x82,0x03,0x82,0x06,0x82,0x01,0x82, +0x01,0x81,0x03,0x82,0x07,0x82,0x01,0x82,0x08,0x82,0x03,0x82,0x0c,0x83,0x09, +0x83,0x0e,0x82,0x0e,0x83,0x07,0x86,0x04,0x82,0x24,0x82,0x1b,0x81,0x03,0x82, +0x0d,0x84,0x0a,0x81,0x02,0x84,0x03,0x83,0x01,0x83,0x03,0x82,0x15,0x82,0x0f, +0x82,0x0b,0x84,0x08,0x8b,0x15,0x86,0x1a,0x82,0x09,0x82,0x06,0x82,0x09,0x83, +0x0d,0x82,0x0f,0x83,0x06,0x82,0x03,0x83,0x0e,0x82,0x05,0x83,0x05,0x82,0x09, +0x82,0x0a,0x82,0x04,0x83,0x06,0x89,0x24,0x83,0x21,0x84,0x08,0x82,0x07,0x81, +0x03,0x82,0x03,0x81,0x03,0x81,0x05,0x82,0x04,0x82,0x05,0x82,0x06,0x83,0x03, +0x82,0x0e,0x82,0x07,0x83,0x04,0x82,0x0d,0x82,0x0b,0x82,0x04,0x86,0x03,0x82, +0x08,0x82,0x08,0x82,0x11,0x82,0x06,0x82,0x02,0x82,0x09,0x82,0x0a,0x82,0x02, +0x82,0x02,0x82,0x02,0x82,0x03,0x82,0x03,0x83,0x02,0x82,0x02,0x82,0x09,0x82, +0x03,0x88,0x06,0x82,0x09,0x82,0x03,0x82,0x05,0x83,0x0c,0x84,0x08,0x83,0x08, +0x82,0x07,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x81,0x03,0x84,0x08,0x84, +0x0b,0x83,0x0c,0x83,0x0e,0x82,0x0d,0x82,0x0c,0x82,0x39,0x87,0x05,0x82,0x05, +0x82,0x06,0x82,0x0d,0x82,0x06,0x82,0x05,0x8a,0x09,0x82,0x09,0x82,0x06,0x82, +0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,0x0a,0x85,0x0c,0x82,0x07,0x82,0x04, +0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x06,0x82,0x06,0x82,0x06,0x82,0x05,0x82, +0x05,0x82,0x06,0x82,0x08,0x82,0x0b,0x85,0x0b,0x82,0x0b,0x82,0x06,0x82,0x06, +0x82,0x03,0x82,0x06,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x08,0x83,0x09,0x82, +0x03,0x82,0x0c,0x82,0x0a,0x82,0x0f,0x82,0x0f,0x83,0x06,0x82,0x02,0x83,0x02, +0x82,0x25,0x82,0x18,0x8b,0x0d,0x82,0x09,0x82,0x01,0x82,0x02,0x82,0x02,0x82, +0x03,0x83,0x02,0x82,0x15,0x82,0x0f,0x82,0x0a,0x82,0x01,0x82,0x0c,0x82,0x3a, +0x82,0x09,0x82,0x06,0x82,0x09,0x83,0x0c,0x82,0x11,0x82,0x05,0x82,0x04,0x83, +0x0e,0x82,0x05,0x83,0x05,0x82,0x09,0x82,0x09,0x82,0x06,0x82,0x08,0x83,0x02, +0x82,0x24,0x83,0x0c,0x89,0x0d,0x83,0x08,0x82,0x07,0x81,0x03,0x82,0x03,0x81, +0x03,0x81,0x04,0x89,0x05,0x82,0x07,0x82,0x03,0x82,0x0e,0x82,0x07,0x82,0x05, +0x82,0x0d,0x82,0x0b,0x82,0x08,0x82,0x03,0x82,0x08,0x82,0x08,0x82,0x11,0x82, +0x06,0x82,0x03,0x82,0x08,0x82,0x0a,0x82,0x03,0x81,0x02,0x81,0x03,0x82,0x03, +0x82,0x04,0x82,0x02,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x0c,0x82,0x09,0x82, +0x03,0x82,0x06,0x82,0x0e,0x82,0x08,0x83,0x08,0x82,0x07,0x82,0x06,0x82,0x02, +0x82,0x06,0x84,0x03,0x84,0x07,0x86,0x0b,0x82,0x0c,0x82,0x0f,0x82,0x0d,0x82, +0x0c,0x82,0x37,0x89,0x05,0x82,0x05,0x82,0x06,0x82,0x0d,0x82,0x06,0x82,0x05, +0x8a,0x09,0x82,0x09,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82, +0x0a,0x85,0x0c,0x82,0x07,0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x06, +0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x05,0x82,0x06,0x82,0x08,0x82,0x0d,0x85, +0x09,0x82,0x0b,0x82,0x06,0x82,0x07,0x82,0x02,0x81,0x07,0x82,0x01,0x81,0x02, +0x82,0x01,0x82,0x09,0x83,0x0a,0x82,0x01,0x83,0x0b,0x82,0x0c,0x82,0x0e,0x82, +0x0e,0x82,0x07,0x82,0x04,0x86,0x3f,0x8b,0x05,0x82,0x06,0x82,0x08,0x82,0x02, +0x81,0x04,0x81,0x02,0x82,0x04,0x85,0x16,0x82,0x0f,0x82,0x0e,0x81,0x0c,0x82, +0x39,0x82,0x0a,0x82,0x06,0x82,0x09,0x83,0x0b,0x83,0x11,0x82,0x05,0x8b,0x0c, +0x82,0x06,0x82,0x05,0x82,0x08,0x83,0x09,0x82,0x06,0x82,0x0d,0x82,0x25,0x85, +0x09,0x89,0x0a,0x85,0x09,0x82,0x07,0x81,0x03,0x82,0x03,0x81,0x02,0x82,0x04, +0x8a,0x04,0x82,0x07,0x82,0x03,0x83,0x07,0x82,0x04,0x82,0x07,0x82,0x05,0x82, +0x0d,0x82,0x0b,0x83,0x07,0x82,0x03,0x82,0x08,0x82,0x08,0x82,0x11,0x82,0x06, +0x82,0x03,0x83,0x07,0x82,0x0a,0x82,0x03,0x84,0x03,0x82,0x03,0x82,0x05,0x82, +0x01,0x82,0x02,0x83,0x07,0x83,0x03,0x82,0x0c,0x83,0x07,0x83,0x03,0x82,0x06, +0x83,0x04,0x82,0x07,0x82,0x08,0x83,0x08,0x82,0x07,0x82,0x06,0x82,0x01,0x83, +0x07,0x83,0x03,0x84,0x07,0x82,0x02,0x82,0x0b,0x82,0x0b,0x82,0x10,0x82,0x0e, +0x82,0x0b,0x82,0x36,0x83,0x04,0x83,0x05,0x82,0x05,0x82,0x06,0x82,0x0d,0x82, +0x06,0x82,0x05,0x82,0x11,0x82,0x09,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x09, +0x82,0x0e,0x82,0x0a,0x82,0x02,0x82,0x0b,0x82,0x07,0x82,0x04,0x82,0x04,0x82, +0x03,0x82,0x05,0x82,0x06,0x82,0x06,0x82,0x06,0x82,0x05,0x82,0x05,0x82,0x06, +0x82,0x08,0x82,0x10,0x83,0x08,0x82,0x0b,0x82,0x06,0x82,0x07,0x82,0x01,0x82, +0x08,0x83,0x03,0x81,0x01,0x82,0x08,0x85,0x09,0x82,0x01,0x82,0x0b,0x83,0x0d, +0x82,0x0d,0x82,0x0e,0x82,0x0f,0x82,0x43,0x82,0x02,0x82,0x08,0x83,0x05,0x82, +0x08,0x81,0x03,0x81,0x04,0x81,0x02,0x82,0x05,0x84,0x16,0x82,0x0f,0x82,0x1b, +0x82,0x39,0x82,0x0a,0x83,0x05,0x82,0x09,0x83,0x0a,0x83,0x0a,0x82,0x06,0x82, +0x0b,0x83,0x07,0x82,0x05,0x82,0x06,0x82,0x05,0x82,0x08,0x82,0x0a,0x82,0x06, +0x82,0x0c,0x83,0x27,0x85,0x18,0x84,0x15,0x82,0x02,0x82,0x02,0x82,0x02,0x81, +0x05,0x82,0x06,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x04,0x82,0x06, +0x83,0x05,0x82,0x0d,0x82,0x0c,0x82,0x07,0x82,0x03,0x82,0x08,0x82,0x08,0x82, +0x0a,0x82,0x05,0x82,0x06,0x82,0x04,0x83,0x06,0x82,0x0a,0x82,0x03,0x84,0x03, +0x82,0x03,0x82,0x05,0x85,0x03,0x82,0x07,0x82,0x04,0x82,0x0d,0x82,0x05,0x81, +0x01,0x82,0x04,0x82,0x06,0x83,0x04,0x83,0x06,0x82,0x08,0x83,0x08,0x82,0x07, +0x82,0x07,0x84,0x08,0x83,0x04,0x82,0x07,0x82,0x04,0x82,0x0a,0x82,0x0a,0x83, +0x10,0x82,0x0e,0x82,0x0b,0x82,0x36,0x82,0x05,0x83,0x05,0x82,0x05,0x82,0x06, +0x83,0x05,0x82,0x05,0x82,0x06,0x82,0x05,0x83,0x10,0x82,0x09,0x83,0x05,0x82, +0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,0x0a,0x82,0x02,0x83,0x0a,0x82,0x07, +0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x06,0x83,0x05,0x82,0x06,0x82, +0x05,0x82,0x05,0x82,0x06,0x82,0x08,0x82,0x0a,0x82,0x05,0x82,0x08,0x82,0x0b, +0x82,0x06,0x82,0x08,0x81,0x01,0x82,0x08,0x83,0x03,0x84,0x08,0x82,0x01,0x82, +0x09,0x82,0x01,0x82,0x0b,0x82,0x0e,0x82,0x0d,0x82,0x0d,0x83,0x54,0x82,0x02, +0x82,0x09,0x82,0x04,0x83,0x07,0x82,0x03,0x81,0x04,0x81,0x02,0x82,0x06,0x82, +0x18,0x82,0x0d,0x82,0x1c,0x82,0x39,0x81,0x0c,0x82,0x04,0x83,0x09,0x83,0x09, +0x83,0x0c,0x82,0x05,0x82,0x0b,0x83,0x07,0x82,0x04,0x83,0x06,0x83,0x04,0x82, +0x08,0x82,0x0a,0x83,0x05,0x82,0x0c,0x82,0x2b,0x83,0x15,0x84,0x18,0x81,0x03, +0x83,0x01,0x83,0x05,0x82,0x07,0x83,0x03,0x82,0x06,0x83,0x04,0x83,0x05,0x82, +0x05,0x82,0x06,0x82,0x06,0x82,0x0d,0x82,0x0c,0x83,0x06,0x82,0x03,0x82,0x08, +0x82,0x08,0x82,0x0a,0x82,0x05,0x82,0x06,0x82,0x05,0x83,0x05,0x82,0x0a,0x82, +0x04,0x82,0x04,0x82,0x03,0x82,0x06,0x84,0x03,0x83,0x05,0x83,0x04,0x82,0x0d, +0x83,0x05,0x83,0x04,0x82,0x06,0x83,0x05,0x82,0x06,0x82,0x08,0x83,0x08,0x83, +0x05,0x83,0x07,0x84,0x08,0x82,0x05,0x82,0x06,0x83,0x04,0x83,0x09,0x82,0x0a, +0x82,0x11,0x82,0x0e,0x82,0x0b,0x82,0x36,0x82,0x05,0x83,0x05,0x83,0x04,0x82, +0x07,0x82,0x05,0x82,0x06,0x82,0x04,0x83,0x06,0x82,0x10,0x82,0x0a,0x82,0x04, +0x83,0x06,0x82,0x05,0x82,0x09,0x82,0x0e,0x82,0x0a,0x82,0x03,0x82,0x0a,0x82, +0x07,0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x07,0x82,0x04,0x83,0x06, +0x82,0x05,0x82,0x06,0x82,0x04,0x83,0x08,0x82,0x0a,0x83,0x04,0x82,0x08,0x82, +0x03,0x82,0x06,0x83,0x04,0x83,0x08,0x83,0x09,0x82,0x04,0x83,0x08,0x82,0x03, +0x82,0x09,0x83,0x0b,0x82,0x0f,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x1a,0x81, +0x03,0x82,0x09,0x88,0x08,0x81,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x85,0x17, +0x82,0x0d,0x82,0x29,0x82,0x1d,0x82,0x0c,0x82,0x0c,0x83,0x02,0x83,0x0a,0x83, +0x09,0x89,0x06,0x84,0x01,0x83,0x0c,0x83,0x07,0x84,0x01,0x83,0x08,0x83,0x01, +0x83,0x09,0x82,0x0b,0x84,0x01,0x83,0x07,0x82,0x02,0x84,0x09,0x82,0x0d,0x82, +0x13,0x81,0x15,0x82,0x10,0x82,0x08,0x81,0x0f,0x82,0x08,0x82,0x03,0x8a,0x06, +0x83,0x02,0x84,0x05,0x89,0x07,0x89,0x06,0x82,0x0d,0x84,0x02,0x84,0x03,0x82, +0x08,0x82,0x06,0x86,0x09,0x83,0x01,0x83,0x07,0x82,0x06,0x83,0x04,0x8a,0x02, +0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x07,0x83,0x04,0x89,0x05,0x82,0x0e,0x8a, +0x04,0x82,0x07,0x82,0x05,0x84,0x02,0x83,0x09,0x83,0x09,0x84,0x01,0x84,0x08, +0x83,0x09,0x82,0x05,0x82,0x06,0x82,0x06,0x82,0x09,0x82,0x09,0x8b,0x09,0x82, +0x0f,0x82,0x0a,0x82,0x37,0x89,0x05,0x88,0x08,0x88,0x07,0x89,0x06,0x84,0x02, +0x82,0x0a,0x82,0x0a,0x89,0x06,0x82,0x05,0x82,0x06,0x88,0x0b,0x82,0x0a,0x82, +0x04,0x82,0x06,0x88,0x04,0x82,0x04,0x82,0x04,0x82,0x03,0x82,0x05,0x82,0x07, +0x84,0x01,0x83,0x07,0x84,0x01,0x83,0x07,0x83,0x02,0x84,0x08,0x82,0x0b,0x83, +0x02,0x83,0x08,0x87,0x06,0x8a,0x08,0x83,0x09,0x82,0x05,0x82,0x07,0x83,0x03, +0x83,0x08,0x83,0x0a,0x89,0x09,0x82,0x0d,0x82,0x0d,0x83,0x38,0x82,0x1a,0x81, +0x03,0x82,0x0a,0x86,0x0f,0x84,0x05,0x86,0x01,0x83,0x16,0x82,0x0d,0x82,0x29, +0x82,0x1d,0x82,0x0c,0x82,0x0d,0x86,0x0b,0x83,0x09,0x89,0x07,0x86,0x0d,0x83, +0x08,0x86,0x0a,0x85,0x0a,0x82,0x0c,0x86,0x08,0x86,0x0b,0x82,0x0d,0x82,0x3b, +0x82,0x09,0x81,0x0e,0x82,0x08,0x82,0x03,0x89,0x08,0x86,0x07,0x88,0x08,0x89, +0x06,0x82,0x0e,0x87,0x05,0x82,0x08,0x82,0x06,0x86,0x0a,0x85,0x08,0x82,0x07, +0x82,0x04,0x8a,0x02,0x82,0x0a,0x82,0x03,0x82,0x07,0x83,0x05,0x86,0x07,0x82, +0x0f,0x86,0x01,0x83,0x03,0x82,0x07,0x82,0x07,0x86,0x0a,0x83,0x0a,0x87,0x0a, +0x82,0x09,0x82,0x06,0x81,0x05,0x83,0x06,0x83,0x08,0x82,0x09,0x8b,0x09,0x82, +0x0f,0x82,0x0a,0x82,0x37,0x85,0x02,0x82,0x05,0x81,0x01,0x85,0x0b,0x85,0x09, +0x85,0x01,0x82,0x08,0x86,0x0a,0x82,0x0b,0x85,0x01,0x82,0x06,0x82,0x05,0x82, +0x06,0x88,0x0b,0x82,0x0a,0x82,0x04,0x83,0x05,0x88,0x04,0x82,0x04,0x82,0x04, +0x82,0x03,0x82,0x05,0x82,0x09,0x85,0x08,0x87,0x09,0x85,0x01,0x82,0x08,0x82, +0x0c,0x86,0x0a,0x84,0x09,0x86,0x01,0x82,0x09,0x82,0x0a,0x81,0x05,0x82,0x07, +0x82,0x05,0x82,0x08,0x83,0x0a,0x89,0x09,0x82,0x0d,0x82,0x0d,0x82,0x68,0x81, +0x3b,0x82,0x0b,0x82,0x2a,0x82,0x2a,0x82,0x7f,0x35,0x82,0x46,0x83,0x7f,0x7f, +0x08,0x82,0x7f,0x10,0x82,0x10,0x82,0x09,0x82,0x18,0x8a,0x76,0x82,0x28,0x82, +0x54,0x82,0x14,0x82,0x71,0x82,0x1d,0x82,0x0d,0x82,0x0d,0x82,0x68,0x81,0x3b, +0x82,0x0b,0x82,0x2a,0x82,0x2a,0x82,0x7f,0x35,0x82,0x48,0x86,0x7f,0x7f,0x7f, +0x15,0x84,0x0e,0x82,0x07,0x84,0x18,0x8a,0x76,0x82,0x28,0x82,0x54,0x82,0x14, +0x82,0x71,0x82,0x1d,0x83,0x0c,0x82,0x0d,0x82,0x7f,0x26,0x82,0x09,0x82,0x2b, +0x81,0x7f,0x62,0x81,0x7f,0x7f,0x7f,0x64,0x84,0x17,0x84,0x7f,0x12,0x82,0x04, +0x82,0x28,0x83,0x54,0x82,0x14,0x82,0x70,0x83,0x1e,0x83,0x0b,0x82,0x0c,0x82, +0x7f,0x28,0x82,0x07,0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x27,0x88,0x26, +0x84,0x55,0x82,0x14,0x82,0x6e,0x84,0x21,0x81,0x0b,0x82,0x0c,0x81,0x7f,0x2a, +0x81,0x07,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x2a,0x84,0x28,0x83,0x7f, +0x5d,0x83,0x64, +0x00, + } +}; diff --git a/minuitwrp/roboto_23x41.h b/minuitwrp/roboto_23x41.h new file mode 100644 index 000000000..6e7566efe --- /dev/null +++ b/minuitwrp/roboto_23x41.h @@ -0,0 +1,461 @@ +struct { + unsigned width; + unsigned height; + unsigned cwidth; + unsigned cheight; + unsigned char rundata[]; +} font = { + .width = 2208, + .height = 41, + .cwidth = 23, + .cheight = 41, + .rundata = { +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x17,0x83,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x2e,0x83,0x60,0x82,0x0a,0x81,0x7f,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0b,0x87,0x23,0x86,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x05,0x83,0x5f,0x83,0x09,0x83,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x0a,0x87,0x23,0x86,0x7f,0x7f,0x7f,0x7f,0x7f,0x39,0x82,0x26, +0x82,0x7f,0x21,0x83,0x5e,0x83,0x0b,0x83,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x09,0x87,0x23,0x86,0x40,0x84,0x27,0x83,0x37,0x83,0x27,0x86,0x20, +0x83,0x1a,0x83,0x17,0x83,0x0c,0x83,0x16,0x86,0x7f,0x7f,0x5a,0x85,0x10,0x83, +0x11,0x85,0x7f,0x1d,0x87,0x5c,0x83,0x0b,0x83,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x09,0x83,0x2a,0x83,0x41,0x83,0x27,0x83,0x37,0x83,0x26,0x86, +0x21,0x83,0x1a,0x83,0x17,0x83,0x0c,0x83,0x16,0x86,0x7f,0x7f,0x59,0x84,0x12, +0x83,0x13,0x84,0x58,0x83,0x11,0x83,0x03,0x83,0x10,0x83,0x04,0x83,0x0a,0x8a, +0x0c,0x84,0x16,0x85,0x14,0x83,0x18,0x83,0x0d,0x83,0x7f,0x11,0x83,0x0d,0x86, +0x13,0x84,0x11,0x86,0x11,0x86,0x16,0x83,0x0d,0x8c,0x0e,0x86,0x0b,0x91,0x0c, +0x87,0x0f,0x86,0x7f,0x05,0x86,0x2a,0x83,0x0d,0x8c,0x10,0x87,0x0a,0x8c,0x0c, +0x90,0x07,0x90,0x0d,0x86,0x0a,0x83,0x0d,0x83,0x09,0x89,0x16,0x83,0x08,0x83, +0x0b,0x84,0x06,0x83,0x10,0x84,0x0e,0x84,0x03,0x83,0x0d,0x83,0x0a,0x86,0x0c, +0x8d,0x0f,0x86,0x0c,0x8c,0x10,0x87,0x09,0x94,0x04,0x83,0x0d,0x83,0x03,0x83, +0x0e,0x84,0x01,0x83,0x10,0x83,0x03,0x84,0x0b,0x84,0x03,0x84,0x0d,0x84,0x04, +0x92,0x0c,0x83,0x0e,0x83,0x19,0x83,0x14,0x83,0x2b,0x83,0x26,0x83,0x37,0x83, +0x25,0x87,0x21,0x83,0x1a,0x83,0x17,0x83,0x0c,0x83,0x19,0x83,0x7f,0x7f,0x59, +0x83,0x13,0x83,0x14,0x83,0x58,0x83,0x11,0x83,0x03,0x83,0x10,0x83,0x04,0x83, +0x09,0x8c,0x09,0x88,0x12,0x89,0x12,0x83,0x17,0x83,0x0f,0x83,0x7f,0x0f,0x83, +0x0c,0x8a,0x0e,0x87,0x0f,0x8a,0x0d,0x8a,0x13,0x84,0x0d,0x8c,0x0c,0x8a,0x09, +0x91,0x0a,0x8b,0x0b,0x8a,0x7f,0x01,0x8a,0x28,0x83,0x0d,0x8e,0x0c,0x8b,0x08, +0x8e,0x0a,0x90,0x07,0x90,0x0a,0x8c,0x07,0x83,0x0d,0x83,0x09,0x89,0x16,0x83, +0x08,0x83,0x0a,0x84,0x07,0x83,0x10,0x85,0x0d,0x84,0x03,0x84,0x0c,0x83,0x08, +0x8a,0x0a,0x8f,0x0b,0x8a,0x0a,0x8e,0x0c,0x8b,0x07,0x94,0x04,0x83,0x0d,0x83, +0x03,0x84,0x0d,0x84,0x01,0x83,0x08,0x81,0x07,0x83,0x03,0x84,0x0b,0x84,0x04, +0x84,0x0b,0x84,0x05,0x92,0x0c,0x83,0x0e,0x84,0x18,0x83,0x14,0x83,0x2b,0x84, +0x25,0x83,0x37,0x83,0x24,0x84,0x25,0x83,0x43,0x83,0x19,0x83,0x7f,0x33,0x83, +0x7f,0x22,0x84,0x13,0x83,0x14,0x83,0x58,0x83,0x11,0x83,0x03,0x83,0x10,0x83, +0x04,0x83,0x09,0x84,0x05,0x84,0x08,0x83,0x02,0x83,0x11,0x8b,0x11,0x83,0x17, +0x83,0x0f,0x83,0x7f,0x0f,0x83,0x0b,0x8c,0x0b,0x89,0x0e,0x8c,0x0b,0x8c,0x11, +0x85,0x0c,0x8d,0x0b,0x8b,0x09,0x91,0x09,0x8d,0x09,0x8c,0x7e,0x8c,0x0e,0x87, +0x11,0x85,0x0c,0x8f,0x0a,0x8e,0x06,0x8f,0x09,0x90,0x07,0x90,0x09,0x8e,0x06, +0x83,0x0d,0x83,0x0c,0x83,0x19,0x83,0x08,0x83,0x09,0x84,0x08,0x83,0x10,0x85, +0x0c,0x85,0x03,0x85,0x0b,0x83,0x06,0x8e,0x08,0x90,0x08,0x8e,0x08,0x8f,0x0a, +0x8d,0x06,0x94,0x04,0x83,0x0d,0x83,0x03,0x84,0x0d,0x83,0x02,0x83,0x08,0x81, +0x07,0x83,0x04,0x84,0x09,0x84,0x05,0x84,0x0b,0x84,0x05,0x92,0x0c,0x83,0x0f, +0x83,0x18,0x83,0x13,0x85,0x2b,0x83,0x25,0x83,0x37,0x83,0x24,0x83,0x26,0x83, +0x43,0x83,0x19,0x83,0x7f,0x33,0x83,0x7f,0x22,0x83,0x14,0x83,0x15,0x83,0x57, +0x83,0x11,0x83,0x03,0x83,0x10,0x82,0x05,0x83,0x08,0x84,0x07,0x83,0x07,0x83, +0x04,0x83,0x05,0x82,0x08,0x85,0x04,0x84,0x10,0x83,0x16,0x83,0x11,0x83,0x7f, +0x0e,0x83,0x0a,0x85,0x04,0x85,0x09,0x86,0x01,0x83,0x0d,0x84,0x05,0x84,0x0a, +0x84,0x05,0x84,0x11,0x85,0x0c,0x84,0x13,0x84,0x06,0x82,0x16,0x84,0x09,0x84, +0x05,0x84,0x08,0x85,0x04,0x85,0x7d,0x84,0x04,0x84,0x0c,0x8b,0x0f,0x85,0x0c, +0x83,0x08,0x85,0x08,0x85,0x06,0x84,0x06,0x83,0x08,0x85,0x08,0x83,0x14,0x83, +0x15,0x85,0x06,0x85,0x05,0x83,0x0d,0x83,0x0c,0x83,0x19,0x83,0x08,0x83,0x08, +0x84,0x09,0x83,0x10,0x86,0x0b,0x85,0x03,0x85,0x0b,0x83,0x05,0x85,0x06,0x85, +0x07,0x83,0x09,0x85,0x06,0x85,0x06,0x85,0x07,0x83,0x08,0x85,0x08,0x85,0x05, +0x85,0x0e,0x83,0x0c,0x83,0x0d,0x83,0x04,0x83,0x0c,0x84,0x02,0x83,0x07,0x82, +0x07,0x83,0x05,0x84,0x07,0x84,0x07,0x84,0x09,0x84,0x14,0x83,0x0d,0x83,0x0f, +0x83,0x18,0x83,0x13,0x85,0x53,0x83,0x37,0x83,0x24,0x83,0x26,0x83,0x43,0x83, +0x19,0x83,0x7f,0x33,0x83,0x7f,0x22,0x83,0x14,0x83,0x15,0x83,0x57,0x83,0x11, +0x83,0x03,0x83,0x10,0x82,0x05,0x82,0x09,0x83,0x08,0x84,0x06,0x83,0x04,0x83, +0x05,0x82,0x08,0x83,0x07,0x83,0x10,0x83,0x16,0x83,0x11,0x83,0x2c,0x83,0x5d, +0x83,0x0b,0x83,0x08,0x83,0x09,0x83,0x04,0x83,0x0d,0x83,0x07,0x84,0x08,0x84, +0x07,0x84,0x0f,0x86,0x0c,0x83,0x13,0x84,0x1e,0x84,0x09,0x84,0x07,0x84,0x07, +0x83,0x08,0x83,0x7c,0x84,0x06,0x84,0x0a,0x83,0x06,0x84,0x0e,0x86,0x0b,0x83, +0x0a,0x84,0x07,0x84,0x08,0x84,0x05,0x83,0x0a,0x84,0x07,0x83,0x14,0x83,0x15, +0x84,0x09,0x83,0x05,0x83,0x0d,0x83,0x0c,0x83,0x19,0x83,0x08,0x83,0x08,0x83, +0x0a,0x83,0x10,0x86,0x0b,0x85,0x03,0x86,0x0a,0x83,0x05,0x84,0x08,0x84,0x07, +0x83,0x0b,0x83,0x06,0x84,0x08,0x84,0x07,0x83,0x0a,0x84,0x06,0x84,0x09,0x83, +0x0e,0x83,0x0c,0x83,0x0d,0x83,0x04,0x84,0x0b,0x84,0x03,0x82,0x07,0x83,0x06, +0x82,0x06,0x84,0x07,0x84,0x08,0x83,0x09,0x84,0x13,0x84,0x0d,0x83,0x0f,0x84, +0x17,0x83,0x13,0x82,0x01,0x83,0x52,0x83,0x37,0x83,0x24,0x83,0x26,0x83,0x43, +0x83,0x19,0x83,0x7f,0x33,0x83,0x7f,0x22,0x83,0x14,0x83,0x15,0x83,0x57,0x83, +0x11,0x83,0x03,0x83,0x0f,0x83,0x04,0x83,0x09,0x83,0x09,0x83,0x06,0x83,0x04, +0x83,0x04,0x82,0x09,0x83,0x07,0x83,0x10,0x83,0x15,0x83,0x13,0x83,0x2b,0x83, +0x5d,0x83,0x0b,0x83,0x08,0x83,0x10,0x83,0x0c,0x83,0x09,0x83,0x08,0x83,0x09, +0x83,0x0f,0x86,0x0c,0x83,0x13,0x83,0x1e,0x84,0x0a,0x83,0x09,0x83,0x06,0x84, +0x08,0x83,0x7c,0x83,0x08,0x83,0x09,0x83,0x09,0x83,0x0c,0x87,0x0b,0x83,0x0b, +0x83,0x06,0x84,0x0a,0x84,0x04,0x83,0x0b,0x84,0x06,0x83,0x14,0x83,0x14,0x84, +0x0a,0x84,0x04,0x83,0x0d,0x83,0x0c,0x83,0x19,0x83,0x08,0x83,0x07,0x84,0x0a, +0x83,0x10,0x86,0x0a,0x86,0x03,0x87,0x09,0x83,0x04,0x84,0x0a,0x84,0x06,0x83, +0x0b,0x84,0x04,0x84,0x0a,0x84,0x06,0x83,0x0b,0x83,0x06,0x83,0x0a,0x84,0x0d, +0x83,0x0c,0x83,0x0d,0x83,0x04,0x84,0x0b,0x83,0x04,0x83,0x06,0x83,0x06,0x82, +0x07,0x84,0x05,0x84,0x09,0x84,0x07,0x84,0x13,0x84,0x0e,0x83,0x10,0x83,0x17, +0x83,0x12,0x83,0x01,0x83,0x52,0x83,0x37,0x83,0x24,0x83,0x26,0x83,0x43,0x83, +0x19,0x83,0x7f,0x33,0x83,0x7f,0x22,0x83,0x14,0x83,0x15,0x83,0x57,0x83,0x11, +0x82,0x04,0x82,0x10,0x83,0x04,0x83,0x09,0x83,0x09,0x83,0x06,0x83,0x04,0x83, +0x04,0x82,0x09,0x83,0x07,0x83,0x10,0x82,0x16,0x83,0x13,0x83,0x14,0x83,0x14, +0x83,0x5d,0x82,0x0b,0x83,0x0a,0x83,0x0f,0x83,0x0c,0x83,0x09,0x83,0x08,0x83, +0x09,0x83,0x0e,0x83,0x01,0x83,0x0c,0x83,0x13,0x83,0x1e,0x83,0x0b,0x83,0x09, +0x83,0x06,0x83,0x0a,0x83,0x0d,0x83,0x14,0x83,0x5f,0x83,0x08,0x83,0x0b,0x82, +0x0c,0x83,0x01,0x83,0x0b,0x83,0x0b,0x83,0x06,0x83,0x0c,0x83,0x04,0x83,0x0c, +0x83,0x06,0x83,0x14,0x83,0x14,0x83,0x0c,0x83,0x04,0x83,0x0d,0x83,0x0c,0x83, +0x19,0x83,0x08,0x83,0x06,0x84,0x0b,0x83,0x10,0x87,0x09,0x86,0x03,0x87,0x09, +0x83,0x04,0x83,0x0c,0x83,0x06,0x83,0x0c,0x83,0x04,0x83,0x0c,0x83,0x06,0x83, +0x0b,0x83,0x06,0x83,0x0b,0x83,0x0d,0x83,0x0c,0x83,0x0d,0x83,0x05,0x83,0x0a, +0x84,0x04,0x83,0x06,0x83,0x05,0x83,0x07,0x84,0x05,0x84,0x0a,0x83,0x07,0x84, +0x13,0x83,0x0f,0x83,0x10,0x83,0x17,0x83,0x12,0x83,0x01,0x83,0x40,0x86,0x0c, +0x83,0x03,0x85,0x11,0x86,0x10,0x85,0x03,0x83,0x0d,0x85,0x0f,0x8a,0x0f,0x85, +0x04,0x82,0x08,0x83,0x03,0x85,0x0f,0x86,0x17,0x83,0x0c,0x83,0x07,0x84,0x0e, +0x83,0x0a,0x83,0x02,0x83,0x07,0x83,0x09,0x83,0x03,0x85,0x10,0x86,0x0d,0x82, +0x04,0x85,0x10,0x85,0x04,0x82,0x09,0x83,0x02,0x85,0x11,0x86,0x0c,0x8d,0x0a, +0x83,0x09,0x83,0x08,0x84,0x09,0x83,0x03,0x84,0x0f,0x83,0x05,0x84,0x08,0x84, +0x07,0x83,0x0a,0x83,0x07,0x8f,0x0e,0x83,0x14,0x83,0x15,0x83,0x57,0x83,0x11, +0x82,0x04,0x82,0x0b,0x92,0x06,0x83,0x12,0x83,0x04,0x83,0x03,0x82,0x0a,0x83, +0x06,0x84,0x10,0x82,0x16,0x83,0x13,0x83,0x14,0x83,0x14,0x83,0x5c,0x83,0x0b, +0x83,0x0a,0x83,0x0f,0x83,0x0c,0x83,0x09,0x83,0x14,0x83,0x0d,0x84,0x01,0x83, +0x0c,0x83,0x12,0x83,0x1e,0x83,0x0c,0x83,0x09,0x83,0x06,0x83,0x0a,0x83,0x0d, +0x83,0x14,0x83,0x5f,0x83,0x07,0x83,0x0d,0x82,0x0b,0x83,0x01,0x84,0x0a,0x83, +0x0b,0x83,0x05,0x84,0x0c,0x83,0x04,0x83,0x0c,0x83,0x06,0x83,0x14,0x83,0x13, +0x83,0x0d,0x83,0x04,0x83,0x0d,0x83,0x0c,0x83,0x19,0x83,0x08,0x83,0x05,0x84, +0x0c,0x83,0x10,0x83,0x01,0x83,0x08,0x83,0x01,0x83,0x03,0x83,0x01,0x84,0x08, +0x83,0x03,0x84,0x0c,0x84,0x05,0x83,0x0c,0x83,0x03,0x84,0x0c,0x84,0x05,0x83, +0x0b,0x83,0x06,0x83,0x0b,0x83,0x0d,0x83,0x0c,0x83,0x0d,0x83,0x05,0x84,0x09, +0x84,0x04,0x83,0x06,0x83,0x05,0x83,0x08,0x84,0x03,0x84,0x0b,0x84,0x05,0x84, +0x13,0x84,0x0f,0x83,0x10,0x84,0x16,0x83,0x11,0x83,0x03,0x83,0x3d,0x8a,0x0a, +0x83,0x01,0x89,0x0d,0x89,0x0d,0x89,0x01,0x83,0x0b,0x89,0x0d,0x8a,0x0d,0x89, +0x01,0x83,0x08,0x83,0x01,0x89,0x0d,0x86,0x17,0x83,0x0c,0x83,0x06,0x84,0x0f, +0x83,0x0a,0x83,0x01,0x86,0x03,0x87,0x07,0x83,0x01,0x89,0x0d,0x89,0x0b,0x83, +0x01,0x89,0x0c,0x89,0x01,0x83,0x09,0x83,0x01,0x88,0x0d,0x8a,0x0a,0x8d,0x0a, +0x83,0x09,0x83,0x08,0x84,0x09,0x83,0x03,0x84,0x06,0x82,0x06,0x84,0x06,0x84, +0x06,0x84,0x08,0x84,0x08,0x84,0x07,0x8f,0x0e,0x83,0x14,0x83,0x15,0x83,0x57, +0x83,0x11,0x82,0x04,0x82,0x0b,0x92,0x06,0x84,0x12,0x83,0x02,0x83,0x03,0x83, +0x0a,0x84,0x04,0x84,0x11,0x82,0x16,0x83,0x13,0x83,0x14,0x83,0x14,0x83,0x5c, +0x83,0x0b,0x83,0x0a,0x83,0x0f,0x83,0x18,0x83,0x13,0x84,0x0d,0x83,0x02,0x83, +0x0c,0x83,0x12,0x83,0x1d,0x84,0x0c,0x84,0x07,0x84,0x06,0x83,0x0a,0x83,0x0d, +0x83,0x14,0x83,0x1a,0x82,0x0a,0x8f,0x08,0x81,0x21,0x83,0x07,0x82,0x06,0x84, +0x04,0x83,0x09,0x83,0x03,0x83,0x0a,0x83,0x0b,0x83,0x05,0x83,0x0d,0x83,0x04, +0x83,0x0d,0x83,0x05,0x83,0x14,0x83,0x13,0x83,0x14,0x83,0x0d,0x83,0x0c,0x83, +0x19,0x83,0x08,0x83,0x04,0x84,0x0d,0x83,0x10,0x83,0x01,0x84,0x07,0x83,0x01, +0x83,0x03,0x83,0x01,0x85,0x07,0x83,0x03,0x83,0x0e,0x83,0x05,0x83,0x0c,0x83, +0x03,0x83,0x0e,0x83,0x05,0x83,0x0b,0x83,0x06,0x83,0x1b,0x83,0x0c,0x83,0x0d, +0x83,0x05,0x84,0x09,0x83,0x06,0x82,0x06,0x83,0x05,0x82,0x0a,0x83,0x02,0x84, +0x0d,0x83,0x05,0x83,0x13,0x84,0x10,0x83,0x11,0x83,0x16,0x83,0x11,0x83,0x03, +0x83,0x3c,0x8c,0x09,0x8e,0x0b,0x8b,0x0b,0x8e,0x0a,0x8b,0x0c,0x8a,0x0c,0x8e, +0x08,0x8e,0x0f,0x83,0x17,0x83,0x0c,0x83,0x06,0x84,0x0f,0x83,0x0a,0x8b,0x01, +0x89,0x06,0x8e,0x0a,0x8c,0x0a,0x8e,0x0a,0x8e,0x09,0x8d,0x0b,0x8c,0x09,0x8d, +0x0a,0x83,0x09,0x83,0x08,0x84,0x08,0x84,0x03,0x84,0x05,0x83,0x06,0x84,0x06, +0x84,0x06,0x83,0x09,0x84,0x08,0x84,0x07,0x8f,0x0e,0x83,0x14,0x83,0x15,0x83, +0x57,0x83,0x24,0x92,0x07,0x83,0x12,0x88,0x03,0x82,0x0c,0x83,0x03,0x84,0x29, +0x83,0x15,0x83,0x0f,0x81,0x03,0x83,0x03,0x81,0x10,0x83,0x5b,0x83,0x0c,0x83, +0x0a,0x83,0x0f,0x83,0x17,0x83,0x13,0x84,0x0d,0x83,0x03,0x83,0x0c,0x83,0x01, +0x85,0x0c,0x83,0x03,0x85,0x15,0x83,0x0e,0x84,0x05,0x84,0x07,0x83,0x0a,0x83, +0x3f,0x84,0x0a,0x8f,0x08,0x83,0x1e,0x83,0x07,0x82,0x06,0x86,0x04,0x82,0x09, +0x83,0x03,0x83,0x0a,0x83,0x0a,0x83,0x06,0x83,0x14,0x83,0x0d,0x83,0x05,0x83, +0x14,0x83,0x13,0x83,0x14,0x83,0x0d,0x83,0x0c,0x83,0x19,0x83,0x08,0x83,0x03, +0x84,0x0e,0x83,0x10,0x83,0x02,0x83,0x06,0x84,0x01,0x83,0x03,0x83,0x02,0x84, +0x07,0x83,0x03,0x83,0x0e,0x83,0x05,0x83,0x0c,0x83,0x03,0x83,0x0e,0x83,0x05, +0x83,0x0b,0x83,0x07,0x83,0x1a,0x83,0x0c,0x83,0x0d,0x83,0x06,0x83,0x08,0x84, +0x06,0x83,0x04,0x85,0x04,0x82,0x0a,0x84,0x01,0x84,0x0d,0x84,0x03,0x84,0x12, +0x84,0x11,0x83,0x11,0x84,0x15,0x83,0x11,0x83,0x03,0x84,0x3b,0x84,0x04,0x84, +0x09,0x85,0x05,0x84,0x0b,0x84,0x04,0x84,0x0a,0x84,0x05,0x85,0x09,0x84,0x05, +0x84,0x0e,0x83,0x10,0x84,0x05,0x85,0x08,0x85,0x05,0x84,0x0f,0x83,0x17,0x83, +0x0c,0x83,0x05,0x84,0x10,0x83,0x0a,0x85,0x02,0x84,0x01,0x83,0x02,0x84,0x06, +0x85,0x05,0x84,0x0a,0x84,0x05,0x84,0x09,0x85,0x05,0x84,0x0a,0x84,0x05,0x85, +0x09,0x85,0x05,0x84,0x09,0x84,0x05,0x84,0x0c,0x83,0x11,0x83,0x09,0x83,0x09, +0x83,0x08,0x83,0x05,0x83,0x05,0x83,0x06,0x83,0x08,0x84,0x04,0x84,0x0a,0x83, +0x08,0x83,0x12,0x84,0x0f,0x83,0x14,0x83,0x15,0x83,0x57,0x83,0x28,0x83,0x05, +0x82,0x0b,0x85,0x12,0x84,0x04,0x82,0x0d,0x89,0x2a,0x83,0x15,0x83,0x0e,0x88, +0x01,0x83,0x10,0x83,0x5b,0x83,0x0c,0x83,0x0a,0x83,0x0f,0x83,0x17,0x83,0x0e, +0x88,0x0e,0x83,0x03,0x83,0x0c,0x8b,0x0a,0x83,0x01,0x89,0x12,0x83,0x10,0x8b, +0x08,0x83,0x0a,0x83,0x3c,0x87,0x0a,0x8f,0x08,0x86,0x1a,0x84,0x07,0x82,0x05, +0x83,0x02,0x82,0x04,0x82,0x08,0x84,0x03,0x84,0x09,0x83,0x09,0x84,0x06,0x83, +0x14,0x83,0x0d,0x83,0x05,0x83,0x14,0x83,0x13,0x83,0x14,0x83,0x0d,0x83,0x0c, +0x83,0x19,0x83,0x08,0x83,0x02,0x84,0x0f,0x83,0x10,0x83,0x02,0x83,0x06,0x83, +0x02,0x83,0x03,0x83,0x03,0x84,0x06,0x83,0x03,0x83,0x0e,0x83,0x05,0x83,0x0b, +0x84,0x03,0x83,0x0e,0x83,0x05,0x83,0x0a,0x83,0x08,0x84,0x19,0x83,0x0c,0x83, +0x0d,0x83,0x06,0x84,0x07,0x84,0x06,0x83,0x04,0x85,0x03,0x83,0x0b,0x87,0x0f, +0x83,0x03,0x83,0x13,0x84,0x11,0x83,0x12,0x83,0x15,0x83,0x10,0x83,0x05,0x83, +0x3a,0x83,0x07,0x84,0x08,0x84,0x07,0x84,0x09,0x84,0x06,0x84,0x08,0x84,0x07, +0x84,0x08,0x84,0x07,0x83,0x0e,0x83,0x0f,0x84,0x07,0x84,0x08,0x84,0x07,0x84, +0x0e,0x83,0x17,0x83,0x0c,0x83,0x04,0x84,0x11,0x83,0x0a,0x84,0x04,0x85,0x05, +0x84,0x05,0x84,0x07,0x84,0x08,0x84,0x07,0x84,0x08,0x84,0x07,0x84,0x08,0x84, +0x07,0x84,0x09,0x84,0x08,0x82,0x09,0x83,0x07,0x84,0x0b,0x83,0x11,0x83,0x09, +0x83,0x09,0x84,0x07,0x83,0x05,0x83,0x05,0x83,0x06,0x83,0x09,0x83,0x04,0x83, +0x0b,0x84,0x06,0x84,0x12,0x84,0x0f,0x83,0x14,0x83,0x15,0x83,0x57,0x83,0x28, +0x83,0x04,0x83,0x0c,0x86,0x17,0x83,0x0e,0x86,0x2c,0x83,0x15,0x83,0x0e,0x8d, +0x0f,0x83,0x5b,0x82,0x0d,0x83,0x0a,0x83,0x0f,0x83,0x16,0x83,0x0f,0x87,0x0e, +0x83,0x04,0x83,0x0c,0x8c,0x09,0x8e,0x11,0x83,0x12,0x87,0x0a,0x84,0x09,0x83, +0x3a,0x88,0x22,0x88,0x18,0x83,0x08,0x82,0x04,0x83,0x03,0x82,0x04,0x83,0x07, +0x83,0x05,0x83,0x09,0x8f,0x07,0x83,0x14,0x83,0x0d,0x83,0x05,0x8e,0x09,0x8f, +0x07,0x83,0x14,0x93,0x0c,0x83,0x19,0x83,0x08,0x88,0x10,0x83,0x10,0x83,0x02, +0x84,0x05,0x83,0x02,0x83,0x03,0x83,0x03,0x85,0x05,0x83,0x03,0x83,0x0e,0x83, +0x05,0x83,0x0b,0x83,0x04,0x83,0x0e,0x83,0x05,0x83,0x09,0x84,0x09,0x86,0x16, +0x83,0x0c,0x83,0x0d,0x83,0x07,0x83,0x07,0x83,0x07,0x83,0x04,0x82,0x01,0x82, +0x03,0x83,0x0c,0x85,0x10,0x84,0x01,0x84,0x12,0x84,0x12,0x83,0x12,0x83,0x15, +0x83,0x10,0x83,0x05,0x83,0x3a,0x83,0x08,0x83,0x08,0x83,0x09,0x83,0x09,0x83, +0x08,0x83,0x08,0x83,0x09,0x83,0x08,0x83,0x09,0x83,0x0d,0x83,0x0f,0x83,0x09, +0x83,0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c,0x83,0x04,0x84,0x11,0x83, +0x0a,0x83,0x06,0x84,0x06,0x83,0x05,0x83,0x09,0x83,0x08,0x83,0x09,0x83,0x08, +0x83,0x09,0x83,0x08,0x83,0x09,0x83,0x09,0x83,0x14,0x83,0x08,0x83,0x0b,0x83, +0x11,0x83,0x09,0x83,0x0a,0x83,0x06,0x84,0x05,0x84,0x04,0x84,0x05,0x83,0x09, +0x84,0x02,0x84,0x0b,0x84,0x06,0x84,0x11,0x84,0x0f,0x83,0x15,0x83,0x16,0x83, +0x56,0x83,0x28,0x83,0x04,0x83,0x0d,0x88,0x14,0x82,0x0f,0x85,0x2d,0x83,0x15, +0x83,0x11,0x88,0x0a,0x92,0x52,0x83,0x0d,0x83,0x0a,0x83,0x0f,0x83,0x15,0x84, +0x0f,0x89,0x0b,0x83,0x05,0x83,0x0b,0x85,0x04,0x85,0x08,0x85,0x05,0x85,0x0f, +0x83,0x11,0x8b,0x09,0x83,0x08,0x84,0x38,0x88,0x26,0x88,0x15,0x83,0x08,0x82, +0x05,0x83,0x03,0x82,0x05,0x82,0x07,0x83,0x05,0x83,0x09,0x8f,0x07,0x83,0x14, +0x83,0x0d,0x83,0x05,0x8e,0x09,0x8f,0x07,0x83,0x07,0x89,0x04,0x93,0x0c,0x83, +0x19,0x83,0x08,0x88,0x10,0x83,0x10,0x83,0x03,0x83,0x04,0x83,0x03,0x83,0x03, +0x83,0x04,0x84,0x05,0x83,0x03,0x83,0x0e,0x83,0x05,0x83,0x09,0x85,0x04,0x83, +0x0e,0x83,0x05,0x8f,0x0c,0x87,0x13,0x83,0x0c,0x83,0x0d,0x83,0x07,0x83,0x06, +0x84,0x08,0x82,0x04,0x82,0x01,0x83,0x02,0x82,0x0d,0x85,0x11,0x83,0x01,0x83, +0x12,0x84,0x13,0x83,0x12,0x84,0x14,0x83,0x0f,0x84,0x06,0x83,0x44,0x83,0x08, +0x83,0x09,0x84,0x07,0x83,0x09,0x83,0x07,0x84,0x09,0x83,0x07,0x83,0x0a,0x83, +0x0d,0x83,0x0e,0x84,0x09,0x83,0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c, +0x83,0x03,0x84,0x12,0x83,0x0a,0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83, +0x07,0x84,0x09,0x84,0x07,0x83,0x09,0x84,0x06,0x84,0x09,0x83,0x09,0x83,0x14, +0x83,0x16,0x83,0x11,0x83,0x09,0x83,0x0a,0x83,0x06,0x83,0x06,0x84,0x03,0x85, +0x04,0x83,0x0b,0x88,0x0d,0x83,0x06,0x83,0x11,0x84,0x0f,0x84,0x15,0x83,0x16, +0x84,0x0c,0x85,0x44,0x83,0x28,0x82,0x05,0x83,0x0e,0x88,0x12,0x82,0x0f,0x87, +0x2c,0x83,0x15,0x83,0x12,0x85,0x0c,0x92,0x1f,0x8d,0x26,0x83,0x0d,0x83,0x0a, +0x83,0x0f,0x83,0x15,0x83,0x16,0x84,0x0a,0x83,0x05,0x83,0x0b,0x84,0x07,0x83, +0x08,0x84,0x08,0x83,0x0f,0x83,0x10,0x84,0x04,0x85,0x08,0x85,0x04,0x86,0x36, +0x87,0x2c,0x87,0x12,0x83,0x09,0x82,0x04,0x83,0x04,0x82,0x05,0x82,0x06,0x83, +0x06,0x84,0x08,0x90,0x06,0x83,0x14,0x83,0x0d,0x83,0x05,0x8e,0x09,0x8f,0x07, +0x83,0x07,0x89,0x04,0x93,0x0c,0x83,0x19,0x83,0x08,0x89,0x0f,0x83,0x10,0x83, +0x03,0x84,0x03,0x83,0x03,0x83,0x03,0x83,0x05,0x84,0x04,0x83,0x03,0x83,0x0e, +0x83,0x05,0x90,0x05,0x83,0x0e,0x83,0x05,0x8e,0x0f,0x87,0x11,0x83,0x0c,0x83, +0x0d,0x83,0x07,0x84,0x05,0x83,0x09,0x83,0x02,0x83,0x02,0x82,0x02,0x82,0x0d, +0x85,0x11,0x87,0x12,0x84,0x13,0x83,0x13,0x83,0x14,0x83,0x60,0x83,0x08,0x83, +0x0a,0x83,0x07,0x83,0x13,0x83,0x0a,0x83,0x07,0x83,0x0a,0x83,0x0d,0x83,0x0e, +0x83,0x0a,0x83,0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c,0x83,0x02,0x84, +0x13,0x83,0x0a,0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83,0x07,0x83,0x0b, +0x83,0x07,0x83,0x0a,0x83,0x06,0x83,0x0a,0x83,0x09,0x83,0x14,0x84,0x15,0x83, +0x11,0x83,0x09,0x83,0x0a,0x84,0x05,0x83,0x07,0x83,0x03,0x85,0x04,0x83,0x0c, +0x86,0x0e,0x84,0x05,0x83,0x10,0x84,0x0f,0x84,0x16,0x83,0x17,0x85,0x09,0x88, +0x07,0x83,0x38,0x83,0x28,0x82,0x05,0x82,0x12,0x86,0x11,0x82,0x03,0x84,0x07, +0x84,0x01,0x84,0x06,0x83,0x22,0x83,0x15,0x83,0x11,0x87,0x0b,0x92,0x1f,0x8d, +0x26,0x82,0x0e,0x83,0x0a,0x83,0x0f,0x83,0x14,0x83,0x18,0x83,0x09,0x83,0x06, +0x83,0x16,0x84,0x07,0x83,0x09,0x84,0x0d,0x83,0x10,0x83,0x08,0x83,0x09,0x8e, +0x34,0x87,0x30,0x87,0x0f,0x83,0x0a,0x82,0x04,0x83,0x04,0x82,0x05,0x82,0x06, +0x83,0x07,0x83,0x08,0x83,0x09,0x85,0x05,0x83,0x14,0x83,0x0d,0x83,0x05,0x83, +0x14,0x83,0x13,0x83,0x07,0x89,0x04,0x83,0x0d,0x83,0x0c,0x83,0x19,0x83,0x08, +0x83,0x03,0x84,0x0e,0x83,0x10,0x83,0x04,0x83,0x02,0x84,0x03,0x83,0x03,0x83, +0x05,0x85,0x03,0x83,0x03,0x83,0x0e,0x83,0x05,0x8f,0x06,0x83,0x0e,0x83,0x05, +0x8f,0x11,0x86,0x0f,0x83,0x0c,0x83,0x0d,0x83,0x08,0x83,0x05,0x83,0x09,0x83, +0x02,0x82,0x03,0x82,0x01,0x83,0x0d,0x86,0x11,0x85,0x12,0x84,0x14,0x83,0x13, +0x83,0x14,0x83,0x59,0x8a,0x08,0x83,0x0a,0x83,0x07,0x83,0x13,0x83,0x0a,0x83, +0x07,0x90,0x0d,0x83,0x0e,0x83,0x0a,0x83,0x08,0x83,0x09,0x83,0x0e,0x83,0x17, +0x83,0x0c,0x88,0x14,0x83,0x0a,0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83, +0x07,0x83,0x0b,0x83,0x07,0x83,0x0a,0x83,0x06,0x83,0x0a,0x83,0x09,0x83,0x15, +0x85,0x13,0x83,0x11,0x83,0x09,0x83,0x0b,0x83,0x04,0x84,0x07,0x83,0x03,0x86, +0x03,0x83,0x0c,0x86,0x0f,0x83,0x04,0x84,0x10,0x84,0x0f,0x83,0x17,0x83,0x18, +0x84,0x08,0x8a,0x06,0x83,0x38,0x83,0x27,0x83,0x05,0x82,0x14,0x85,0x0f,0x82, +0x03,0x86,0x05,0x84,0x03,0x84,0x05,0x83,0x22,0x83,0x15,0x83,0x10,0x84,0x01, +0x83,0x12,0x83,0x27,0x8d,0x25,0x83,0x0e,0x83,0x0a,0x83,0x0f,0x83,0x13,0x83, +0x1a,0x83,0x07,0x84,0x06,0x83,0x17,0x83,0x07,0x83,0x0a,0x83,0x0d,0x83,0x0f, +0x84,0x08,0x84,0x09,0x89,0x01,0x83,0x34,0x85,0x35,0x85,0x0d,0x84,0x0a,0x82, +0x04,0x83,0x04,0x82,0x05,0x82,0x06,0x83,0x07,0x83,0x08,0x83,0x0b,0x83,0x05, +0x83,0x14,0x83,0x0d,0x83,0x05,0x83,0x14,0x83,0x13,0x83,0x0d,0x83,0x04,0x83, +0x0d,0x83,0x0c,0x83,0x19,0x83,0x08,0x83,0x03,0x85,0x0d,0x83,0x10,0x83,0x04, +0x84,0x01,0x83,0x04,0x83,0x03,0x83,0x06,0x84,0x03,0x83,0x03,0x83,0x0e,0x83, +0x05,0x8d,0x08,0x83,0x0e,0x83,0x05,0x83,0x09,0x84,0x13,0x84,0x0e,0x83,0x0c, +0x83,0x0d,0x83,0x08,0x83,0x04,0x84,0x09,0x83,0x02,0x82,0x03,0x82,0x01,0x83, +0x0c,0x87,0x11,0x85,0x11,0x84,0x15,0x83,0x13,0x84,0x13,0x83,0x56,0x8d,0x08, +0x83,0x0a,0x83,0x07,0x83,0x13,0x83,0x0a,0x83,0x07,0x90,0x0d,0x83,0x0e,0x83, +0x0a,0x83,0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c,0x88,0x14,0x83,0x0a, +0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83,0x07,0x83,0x0b,0x83,0x07,0x83, +0x0a,0x83,0x06,0x83,0x0a,0x83,0x09,0x83,0x16,0x88,0x0f,0x83,0x11,0x83,0x09, +0x83,0x0b,0x83,0x04,0x83,0x08,0x84,0x01,0x83,0x01,0x83,0x03,0x83,0x0d,0x84, +0x10,0x83,0x04,0x83,0x10,0x84,0x10,0x84,0x16,0x83,0x17,0x85,0x07,0x84,0x04, +0x84,0x04,0x84,0x38,0x83,0x23,0x92,0x12,0x84,0x0d,0x83,0x02,0x83,0x02,0x83, +0x03,0x84,0x05,0x84,0x04,0x83,0x22,0x83,0x15,0x83,0x10,0x83,0x03,0x83,0x11, +0x83,0x59,0x82,0x0f,0x83,0x0a,0x83,0x0f,0x83,0x12,0x84,0x1a,0x83,0x07,0x83, +0x07,0x83,0x17,0x83,0x07,0x83,0x0a,0x83,0x0d,0x83,0x0f,0x83,0x0a,0x83,0x0b, +0x85,0x03,0x83,0x34,0x85,0x14,0x8f,0x13,0x84,0x0d,0x83,0x0b,0x82,0x04,0x83, +0x04,0x82,0x05,0x82,0x05,0x8f,0x07,0x83,0x0c,0x83,0x04,0x83,0x14,0x83,0x0d, +0x83,0x05,0x83,0x14,0x83,0x13,0x83,0x0d,0x83,0x04,0x83,0x0d,0x83,0x0c,0x83, +0x19,0x83,0x08,0x83,0x04,0x85,0x0c,0x83,0x10,0x83,0x04,0x84,0x01,0x83,0x04, +0x83,0x03,0x83,0x07,0x84,0x02,0x83,0x03,0x83,0x0e,0x83,0x05,0x83,0x12,0x83, +0x0e,0x83,0x05,0x83,0x0a,0x84,0x13,0x83,0x0e,0x83,0x0c,0x83,0x0d,0x83,0x08, +0x84,0x03,0x83,0x0a,0x83,0x01,0x83,0x03,0x82,0x01,0x83,0x0b,0x84,0x01,0x84, +0x11,0x83,0x12,0x83,0x16,0x83,0x14,0x83,0x13,0x83,0x55,0x8e,0x08,0x83,0x0a, +0x83,0x07,0x83,0x13,0x83,0x0a,0x83,0x07,0x90,0x0d,0x83,0x0e,0x83,0x0a,0x83, +0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c,0x88,0x14,0x83,0x0a,0x83,0x06, +0x83,0x07,0x83,0x05,0x83,0x09,0x83,0x07,0x83,0x0b,0x83,0x07,0x83,0x0a,0x83, +0x06,0x83,0x0a,0x83,0x09,0x83,0x19,0x87,0x0d,0x83,0x11,0x83,0x09,0x83,0x0b, +0x84,0x03,0x83,0x09,0x83,0x01,0x83,0x01,0x83,0x02,0x83,0x0e,0x84,0x10,0x84, +0x03,0x83,0x0f,0x84,0x12,0x84,0x15,0x83,0x16,0x84,0x09,0x83,0x06,0x8a,0x39, +0x83,0x23,0x92,0x12,0x84,0x0d,0x82,0x02,0x83,0x04,0x83,0x02,0x83,0x07,0x84, +0x02,0x84,0x22,0x83,0x15,0x83,0x11,0x81,0x04,0x82,0x12,0x83,0x58,0x83,0x0f, +0x83,0x0a,0x83,0x0f,0x83,0x11,0x84,0x1b,0x83,0x06,0x92,0x13,0x83,0x07,0x83, +0x0a,0x83,0x0d,0x83,0x0f,0x83,0x0a,0x83,0x13,0x83,0x35,0x87,0x11,0x8f,0x10, +0x87,0x0d,0x83,0x0b,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x05,0x8f,0x07,0x83, +0x0c,0x83,0x04,0x83,0x0d,0x83,0x04,0x83,0x0d,0x83,0x05,0x83,0x14,0x83,0x13, +0x83,0x0d,0x83,0x04,0x83,0x0d,0x83,0x0c,0x83,0x19,0x83,0x08,0x83,0x05,0x84, +0x0c,0x83,0x10,0x83,0x05,0x86,0x05,0x83,0x03,0x83,0x07,0x85,0x01,0x83,0x03, +0x83,0x0e,0x83,0x05,0x83,0x12,0x83,0x0e,0x83,0x05,0x83,0x0b,0x83,0x14,0x83, +0x0d,0x83,0x0c,0x83,0x0d,0x83,0x09,0x83,0x03,0x83,0x0b,0x82,0x01,0x82,0x04, +0x86,0x0b,0x83,0x02,0x84,0x11,0x83,0x11,0x84,0x16,0x83,0x14,0x84,0x12,0x83, +0x55,0x84,0x07,0x83,0x08,0x83,0x0a,0x83,0x07,0x83,0x13,0x83,0x0a,0x83,0x07, +0x83,0x1a,0x83,0x0e,0x83,0x0a,0x83,0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83, +0x0c,0x83,0x02,0x84,0x13,0x83,0x0a,0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09, +0x83,0x07,0x83,0x0b,0x83,0x07,0x83,0x0a,0x83,0x06,0x83,0x0a,0x83,0x09,0x83, +0x1c,0x85,0x0c,0x83,0x11,0x83,0x09,0x83,0x0c,0x83,0x02,0x84,0x09,0x83,0x01, +0x83,0x01,0x83,0x02,0x83,0x0d,0x86,0x10,0x83,0x02,0x84,0x0e,0x84,0x14,0x83, +0x15,0x83,0x16,0x83,0x0a,0x83,0x07,0x88,0x60,0x92,0x13,0x83,0x0c,0x82,0x03, +0x83,0x04,0x83,0x02,0x83,0x07,0x85,0x01,0x83,0x23,0x83,0x15,0x83,0x2a,0x83, +0x58,0x83,0x0f,0x83,0x0a,0x83,0x0f,0x83,0x10,0x84,0x0f,0x83,0x0a,0x83,0x06, +0x92,0x13,0x83,0x07,0x83,0x0a,0x83,0x0c,0x83,0x10,0x83,0x0a,0x83,0x13,0x83, +0x37,0x87,0x0f,0x8f,0x0e,0x87,0x0f,0x83,0x0b,0x82,0x04,0x82,0x05,0x82,0x05, +0x82,0x05,0x8f,0x07,0x83,0x0c,0x83,0x04,0x84,0x0c,0x83,0x04,0x83,0x0c,0x84, +0x05,0x83,0x14,0x83,0x13,0x84,0x0c,0x83,0x04,0x83,0x0d,0x83,0x0c,0x83,0x0d, +0x83,0x09,0x83,0x08,0x83,0x06,0x84,0x0b,0x83,0x10,0x83,0x05,0x86,0x05,0x83, +0x03,0x83,0x08,0x84,0x01,0x83,0x03,0x84,0x0c,0x84,0x05,0x83,0x12,0x84,0x0c, +0x84,0x05,0x83,0x0b,0x83,0x05,0x83,0x0c,0x83,0x0d,0x83,0x0c,0x83,0x0d,0x83, +0x09,0x84,0x01,0x84,0x0b,0x82,0x01,0x82,0x05,0x84,0x0b,0x84,0x03,0x84,0x10, +0x83,0x10,0x84,0x17,0x83,0x15,0x83,0x12,0x83,0x54,0x84,0x08,0x83,0x08,0x83, +0x0a,0x83,0x07,0x83,0x13,0x83,0x0a,0x83,0x07,0x83,0x1a,0x83,0x0e,0x83,0x0a, +0x83,0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c,0x83,0x03,0x84,0x12,0x83, +0x0a,0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83,0x07,0x83,0x0b,0x83,0x07, +0x83,0x0a,0x83,0x06,0x83,0x0a,0x83,0x09,0x83,0x1e,0x84,0x0b,0x83,0x11,0x83, +0x09,0x83,0x0c,0x83,0x02,0x83,0x0a,0x83,0x01,0x82,0x03,0x83,0x01,0x83,0x0d, +0x87,0x0f,0x83,0x02,0x83,0x0f,0x83,0x16,0x83,0x14,0x83,0x15,0x83,0x17,0x85, +0x65,0x82,0x05,0x83,0x0a,0x83,0x0a,0x83,0x0c,0x82,0x03,0x83,0x04,0x83,0x02, +0x83,0x08,0x88,0x23,0x83,0x15,0x83,0x2a,0x83,0x58,0x82,0x10,0x83,0x0a,0x83, +0x0f,0x83,0x0f,0x84,0x10,0x83,0x0a,0x83,0x06,0x92,0x07,0x83,0x09,0x83,0x07, +0x84,0x09,0x83,0x0c,0x83,0x10,0x83,0x0a,0x83,0x12,0x84,0x39,0x87,0x27,0x88, +0x1f,0x82,0x04,0x82,0x05,0x82,0x04,0x82,0x05,0x83,0x0a,0x84,0x06,0x83,0x0c, +0x83,0x05,0x83,0x0c,0x83,0x04,0x83,0x0c,0x83,0x06,0x83,0x14,0x83,0x14,0x83, +0x0c,0x83,0x04,0x83,0x0d,0x83,0x0c,0x83,0x0d,0x83,0x09,0x83,0x08,0x83,0x07, +0x84,0x0a,0x83,0x10,0x83,0x06,0x85,0x05,0x83,0x03,0x83,0x09,0x87,0x04,0x83, +0x0c,0x83,0x06,0x83,0x13,0x83,0x0c,0x83,0x06,0x83,0x0b,0x83,0x05,0x83,0x0c, +0x83,0x0d,0x83,0x0c,0x83,0x0c,0x84,0x0a,0x83,0x01,0x83,0x0c,0x85,0x05,0x84, +0x0a,0x84,0x05,0x84,0x0f,0x83,0x10,0x83,0x18,0x83,0x15,0x83,0x12,0x83,0x54, +0x83,0x09,0x83,0x08,0x83,0x0a,0x83,0x07,0x83,0x09,0x83,0x07,0x83,0x0a,0x83, +0x07,0x83,0x1a,0x83,0x0e,0x83,0x0a,0x83,0x08,0x83,0x09,0x83,0x0e,0x83,0x17, +0x83,0x0c,0x83,0x04,0x84,0x11,0x83,0x0a,0x83,0x06,0x83,0x07,0x83,0x05,0x83, +0x09,0x83,0x07,0x84,0x09,0x84,0x07,0x83,0x0a,0x83,0x06,0x83,0x0a,0x83,0x09, +0x83,0x1f,0x83,0x0b,0x83,0x11,0x83,0x09,0x83,0x0d,0x83,0x01,0x83,0x0a,0x86, +0x03,0x83,0x01,0x82,0x0d,0x83,0x02,0x83,0x0f,0x84,0x01,0x83,0x0e,0x84,0x16, +0x83,0x14,0x83,0x15,0x83,0x7f,0x02,0x82,0x05,0x82,0x0b,0x83,0x0a,0x83,0x0b, +0x82,0x04,0x83,0x04,0x83,0x02,0x83,0x09,0x86,0x24,0x83,0x15,0x83,0x2a,0x83, +0x57,0x83,0x11,0x83,0x08,0x83,0x10,0x83,0x0f,0x83,0x11,0x84,0x08,0x84,0x11, +0x83,0x0b,0x83,0x08,0x84,0x08,0x83,0x08,0x84,0x0c,0x83,0x10,0x84,0x08,0x84, +0x12,0x83,0x3c,0x88,0x22,0x88,0x21,0x82,0x04,0x83,0x03,0x83,0x04,0x82,0x05, +0x83,0x0b,0x83,0x06,0x83,0x0c,0x83,0x05,0x84,0x0a,0x83,0x05,0x83,0x0b,0x84, +0x06,0x83,0x14,0x83,0x14,0x84,0x0b,0x83,0x04,0x83,0x0d,0x83,0x0c,0x83,0x0d, +0x83,0x08,0x84,0x08,0x83,0x07,0x85,0x09,0x83,0x10,0x83,0x07,0x83,0x06,0x83, +0x03,0x83,0x09,0x87,0x04,0x84,0x0a,0x84,0x06,0x83,0x13,0x84,0x0a,0x84,0x06, +0x83,0x0b,0x83,0x05,0x84,0x0b,0x83,0x0d,0x83,0x0d,0x83,0x0b,0x83,0x0b,0x83, +0x01,0x83,0x0c,0x85,0x05,0x84,0x0a,0x84,0x05,0x84,0x0f,0x83,0x0f,0x84,0x18, +0x83,0x15,0x84,0x11,0x83,0x54,0x83,0x09,0x83,0x08,0x83,0x09,0x83,0x09,0x83, +0x08,0x83,0x07,0x84,0x09,0x83,0x08,0x83,0x19,0x83,0x0e,0x84,0x09,0x83,0x08, +0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c,0x83,0x04,0x84,0x11,0x83,0x0a,0x83, +0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83,0x08,0x83,0x09,0x83,0x08,0x83,0x09, +0x83,0x07,0x84,0x09,0x83,0x09,0x83,0x13,0x83,0x09,0x83,0x0b,0x83,0x11,0x83, +0x09,0x83,0x0d,0x86,0x0c,0x85,0x03,0x83,0x01,0x82,0x0c,0x84,0x02,0x84,0x0f, +0x87,0x0d,0x84,0x17,0x83,0x14,0x83,0x15,0x83,0x7f,0x01,0x83,0x05,0x82,0x0b, +0x83,0x0a,0x83,0x0a,0x83,0x04,0x83,0x04,0x83,0x02,0x84,0x09,0x84,0x26,0x83, +0x13,0x83,0x2b,0x83,0x57,0x83,0x11,0x83,0x08,0x83,0x10,0x83,0x0e,0x83,0x13, +0x83,0x08,0x83,0x12,0x83,0x0b,0x84,0x07,0x83,0x09,0x84,0x07,0x83,0x0d,0x83, +0x11,0x83,0x08,0x83,0x12,0x84,0x25,0x83,0x16,0x86,0x21,0x86,0x25,0x82,0x03, +0x83,0x02,0x85,0x02,0x82,0x05,0x84,0x0b,0x83,0x06,0x83,0x0b,0x84,0x06,0x83, +0x09,0x84,0x05,0x83,0x0a,0x84,0x07,0x83,0x14,0x83,0x15,0x84,0x09,0x84,0x04, +0x83,0x0d,0x83,0x0c,0x83,0x0d,0x84,0x07,0x83,0x09,0x83,0x08,0x85,0x08,0x83, +0x10,0x83,0x07,0x83,0x06,0x83,0x03,0x83,0x0a,0x86,0x05,0x83,0x09,0x84,0x07, +0x83,0x14,0x83,0x09,0x84,0x07,0x83,0x0b,0x83,0x06,0x84,0x09,0x84,0x0d,0x83, +0x0d,0x84,0x09,0x84,0x0b,0x87,0x0c,0x84,0x07,0x83,0x09,0x84,0x07,0x84,0x0e, +0x83,0x0e,0x84,0x19,0x83,0x16,0x83,0x11,0x83,0x54,0x83,0x08,0x84,0x08,0x84, +0x08,0x83,0x09,0x83,0x07,0x84,0x08,0x83,0x08,0x84,0x08,0x83,0x0a,0x81,0x0e, +0x83,0x0f,0x83,0x08,0x84,0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c,0x83, +0x05,0x84,0x10,0x83,0x0a,0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83,0x08, +0x84,0x07,0x84,0x08,0x84,0x07,0x84,0x08,0x84,0x07,0x84,0x09,0x83,0x13,0x84, +0x08,0x83,0x0b,0x83,0x11,0x84,0x07,0x84,0x0d,0x86,0x0c,0x84,0x05,0x85,0x0c, +0x83,0x04,0x83,0x0f,0x86,0x0d,0x84,0x18,0x83,0x14,0x83,0x15,0x83,0x7f,0x01, +0x83,0x04,0x83,0x0c,0x83,0x08,0x84,0x0a,0x82,0x05,0x83,0x04,0x83,0x03,0x84, +0x06,0x87,0x25,0x83,0x13,0x83,0x2b,0x83,0x57,0x82,0x12,0x85,0x04,0x85,0x10, +0x83,0x0d,0x83,0x14,0x85,0x04,0x85,0x12,0x83,0x0c,0x84,0x05,0x84,0x0a,0x84, +0x04,0x85,0x0d,0x83,0x11,0x85,0x04,0x85,0x09,0x81,0x07,0x84,0x26,0x83,0x18, +0x84,0x21,0x84,0x18,0x83,0x0c,0x82,0x04,0x85,0x01,0x86,0x06,0x83,0x0c,0x84, +0x05,0x83,0x0a,0x84,0x07,0x85,0x06,0x84,0x06,0x83,0x08,0x85,0x08,0x83,0x14, +0x83,0x15,0x85,0x07,0x85,0x04,0x83,0x0d,0x83,0x0c,0x83,0x0e,0x84,0x05,0x84, +0x09,0x83,0x09,0x84,0x08,0x83,0x10,0x83,0x10,0x83,0x03,0x83,0x0b,0x85,0x05, +0x85,0x06,0x85,0x07,0x83,0x14,0x85,0x06,0x85,0x07,0x83,0x0b,0x83,0x06,0x85, +0x06,0x85,0x0e,0x83,0x0e,0x85,0x05,0x85,0x0d,0x85,0x0d,0x84,0x07,0x83,0x08, +0x84,0x09,0x84,0x0d,0x83,0x0d,0x84,0x1a,0x83,0x16,0x83,0x11,0x83,0x54,0x84, +0x05,0x86,0x08,0x85,0x05,0x85,0x0a,0x84,0x04,0x84,0x09,0x85,0x05,0x85,0x09, +0x84,0x06,0x83,0x0e,0x83,0x0f,0x85,0x05,0x85,0x08,0x83,0x09,0x83,0x0e,0x83, +0x17,0x83,0x0c,0x83,0x06,0x84,0x0f,0x83,0x0a,0x83,0x06,0x83,0x07,0x83,0x05, +0x83,0x09,0x83,0x09,0x84,0x05,0x84,0x09,0x85,0x05,0x85,0x08,0x85,0x05,0x85, +0x09,0x83,0x14,0x84,0x05,0x85,0x0b,0x84,0x05,0x83,0x09,0x84,0x05,0x85,0x0e, +0x85,0x0c,0x84,0x05,0x85,0x0b,0x84,0x04,0x84,0x0e,0x86,0x0d,0x83,0x19,0x83, +0x14,0x83,0x15,0x83,0x57,0x83,0x26,0x83,0x04,0x83,0x0c,0x85,0x05,0x84,0x13, +0x83,0x02,0x83,0x05,0x91,0x24,0x83,0x13,0x83,0x40,0x83,0x2c,0x83,0x12,0x83, +0x13,0x8c,0x11,0x83,0x0c,0x90,0x09,0x8c,0x13,0x83,0x0c,0x8c,0x0b,0x8c,0x0e, +0x83,0x12,0x8c,0x0a,0x8c,0x0f,0x83,0x14,0x83,0x1a,0x82,0x21,0x82,0x1a,0x83, +0x0c,0x83,0x04,0x83,0x03,0x84,0x07,0x83,0x0d,0x83,0x05,0x90,0x09,0x8e,0x06, +0x8f,0x09,0x90,0x07,0x83,0x16,0x8f,0x05,0x83,0x0d,0x83,0x0c,0x83,0x0e,0x8c, +0x0a,0x83,0x0a,0x84,0x07,0x90,0x03,0x83,0x10,0x83,0x03,0x83,0x0b,0x85,0x06, +0x8e,0x08,0x83,0x15,0x90,0x06,0x83,0x0b,0x83,0x07,0x8e,0x0f,0x83,0x0e,0x8e, +0x0e,0x85,0x0e,0x83,0x07,0x83,0x08,0x84,0x09,0x84,0x0d,0x83,0x0d,0x92,0x0c, +0x83,0x16,0x84,0x10,0x83,0x55,0x8a,0x01,0x83,0x08,0x8e,0x0b,0x8b,0x0b,0x8e, +0x09,0x8e,0x0d,0x83,0x10,0x8e,0x08,0x83,0x09,0x83,0x0e,0x83,0x17,0x83,0x0c, +0x83,0x06,0x84,0x0f,0x83,0x0a,0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83, +0x09,0x8d,0x09,0x8e,0x0a,0x8e,0x09,0x83,0x14,0x8d,0x0c,0x8c,0x09,0x8e,0x0e, +0x84,0x0e,0x83,0x05,0x84,0x0b,0x84,0x06,0x84,0x0e,0x85,0x0c,0x8f,0x0e,0x83, +0x14,0x83,0x15,0x83,0x57,0x83,0x26,0x82,0x05,0x83,0x0d,0x8c,0x15,0x86,0x07, +0x8b,0x02,0x84,0x23,0x83,0x13,0x83,0x40,0x83,0x2c,0x83,0x12,0x82,0x15,0x8a, +0x12,0x83,0x0c,0x90,0x0a,0x8a,0x14,0x83,0x0d,0x8a,0x0e,0x89,0x0f,0x83,0x13, +0x8a,0x0b,0x8a,0x11,0x83,0x14,0x83,0x59,0x83,0x0d,0x82,0x14,0x84,0x0d,0x83, +0x05,0x8f,0x0b,0x8b,0x08,0x8e,0x0a,0x90,0x07,0x83,0x18,0x8b,0x07,0x83,0x0d, +0x83,0x09,0x89,0x0c,0x8a,0x0b,0x83,0x0b,0x84,0x06,0x90,0x03,0x83,0x10,0x83, +0x03,0x83,0x0c,0x84,0x07,0x8b,0x0a,0x83,0x17,0x8a,0x01,0x84,0x05,0x83,0x0b, +0x83,0x09,0x8b,0x10,0x83,0x10,0x8b,0x0f,0x84,0x0f,0x82,0x09,0x82,0x07,0x84, +0x0b,0x84,0x0c,0x83,0x0d,0x92,0x0c,0x83,0x17,0x83,0x10,0x83,0x56,0x88,0x02, +0x83,0x08,0x83,0x01,0x89,0x0d,0x89,0x0d,0x89,0x01,0x83,0x0b,0x8a,0x0f,0x83, +0x11,0x89,0x01,0x83,0x08,0x83,0x09,0x83,0x0a,0x8b,0x13,0x83,0x0c,0x83,0x07, +0x84,0x0a,0x8b,0x06,0x83,0x06,0x83,0x07,0x83,0x05,0x83,0x09,0x83,0x0b,0x89, +0x0b,0x83,0x01,0x89,0x0c,0x89,0x01,0x83,0x09,0x83,0x16,0x8a,0x0e,0x8a,0x0b, +0x89,0x01,0x83,0x0e,0x84,0x0e,0x83,0x06,0x83,0x0b,0x84,0x06,0x84,0x0e,0x84, +0x0d,0x8f,0x0e,0x83,0x14,0x83,0x15,0x83,0x57,0x83,0x25,0x83,0x05,0x82,0x0f, +0x8a,0x17,0x84,0x0a,0x87,0x04,0x84,0x24,0x83,0x11,0x83,0x41,0x83,0x2c,0x83, +0x11,0x83,0x17,0x86,0x14,0x83,0x0c,0x90,0x0c,0x86,0x16,0x83,0x0f,0x86,0x11, +0x86,0x11,0x83,0x15,0x86,0x0e,0x87,0x13,0x83,0x14,0x82,0x5a,0x83,0x0d,0x83, +0x13,0x83,0x0e,0x84,0x04,0x8d,0x0f,0x87,0x0a,0x8c,0x0c,0x90,0x07,0x83,0x1a, +0x87,0x09,0x83,0x0d,0x83,0x09,0x89,0x0e,0x86,0x0d,0x83,0x0b,0x85,0x05,0x90, +0x03,0x83,0x10,0x83,0x03,0x83,0x0d,0x83,0x0a,0x86,0x0c,0x83,0x19,0x86,0x04, +0x84,0x04,0x83,0x0c,0x83,0x0a,0x87,0x12,0x83,0x12,0x87,0x12,0x83,0x10,0x81, +0x09,0x81,0x07,0x85,0x0b,0x85,0x0b,0x83,0x0d,0x92,0x0c,0x83,0x17,0x84,0x0f, +0x83,0x57,0x86,0x03,0x83,0x08,0x82,0x04,0x85,0x11,0x86,0x10,0x85,0x04,0x82, +0x0d,0x86,0x11,0x83,0x13,0x85,0x03,0x83,0x08,0x83,0x09,0x83,0x0a,0x8b,0x13, +0x83,0x0c,0x83,0x08,0x84,0x09,0x8b,0x06,0x83,0x06,0x83,0x07,0x83,0x05,0x83, +0x09,0x83,0x0c,0x87,0x0c,0x83,0x03,0x85,0x10,0x85,0x03,0x83,0x09,0x83,0x17, +0x87,0x11,0x87,0x0f,0x85,0x03,0x83,0x0f,0x83,0x0e,0x82,0x07,0x83,0x0a,0x84, +0x08,0x84,0x0d,0x84,0x0d,0x8f,0x0e,0x83,0x14,0x83,0x15,0x83,0x7f,0x1c,0x85, +0x5a,0x83,0x11,0x83,0x41,0x83,0x40,0x83,0x7f,0x7f,0x16,0x83,0x6b,0x83,0x7f, +0x7f,0x7f,0x17,0x83,0x7f,0x5b,0x83,0x18,0x83,0x0f,0x83,0x25,0x90,0x7f,0x36, +0x83,0x3f,0x83,0x7e,0x83,0x20,0x83,0x7f,0x30,0x83,0x2b,0x83,0x14,0x83,0x15, +0x83,0x7f,0x1d,0x83,0x5c,0x83,0x0f,0x83,0x42,0x82,0x41,0x82,0x7f,0x7f,0x17, +0x82,0x6d,0x84,0x06,0x81,0x7f,0x7f,0x7f,0x0f,0x81,0x7f,0x5c,0x83,0x18,0x83, +0x0f,0x83,0x25,0x90,0x7f,0x36,0x83,0x3f,0x83,0x7e,0x83,0x20,0x83,0x7f,0x30, +0x83,0x2b,0x84,0x13,0x83,0x14,0x83,0x7f,0x1e,0x83,0x5c,0x83,0x0f,0x83,0x41, +0x83,0x7f,0x7f,0x5a,0x82,0x6e,0x8b,0x7f,0x7f,0x7f,0x7f,0x6b,0x83,0x2a,0x83, +0x25,0x90,0x7f,0x36,0x83,0x3f,0x83,0x7e,0x83,0x20,0x83,0x7f,0x2f,0x84,0x2c, +0x83,0x13,0x83,0x14,0x83,0x7f,0x1e,0x83,0x5d,0x83,0x0d,0x83,0x42,0x82,0x7f, +0x7f,0x7f,0x4e,0x86,0x7f,0x7f,0x7f,0x7f,0x6e,0x87,0x23,0x86,0x7f,0x6a,0x83, +0x3f,0x84,0x7e,0x83,0x20,0x83,0x7f,0x2f,0x83,0x2d,0x84,0x12,0x83,0x13,0x84, +0x7f,0x7f,0x82,0x0d,0x82,0x43,0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x43,0x87,0x23,0x86,0x7f,0x60,0x82,0x07,0x84,0x3e,0x84,0x7f,0x83,0x20,0x83, +0x7f,0x2e,0x84,0x2e,0x84,0x11,0x83,0x11,0x85,0x7f,0x7f,0x01,0x83,0x0b,0x83, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x09,0x87,0x23,0x86,0x7f,0x60, +0x8c,0x3b,0x88,0x7f,0x83,0x20,0x83,0x7f,0x2b,0x86,0x31,0x82,0x11,0x83,0x12, +0x82,0x7f,0x7f,0x04,0x83,0x09,0x83,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x7f,0x1b,0x8b,0x3c,0x87,0x7f,0x01,0x83,0x20,0x83,0x7f,0x2b,0x86, +0x7f,0x7f,0x60,0x81,0x0b,0x81,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x1e,0x87,0x3e,0x85,0x7f,0x03,0x83,0x20,0x83,0x7f,0x2b,0x84,0x7f, +0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, +0x7f,0x7f,0x4a, +0x00, + } +}; diff --git a/minuitwrp/truetype.c b/minuitwrp/truetype.c new file mode 100644 index 000000000..db70236a4 --- /dev/null +++ b/minuitwrp/truetype.c @@ -0,0 +1,793 @@ +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> + +#include <errno.h> +#include <stdio.h> + +#include "minui.h" + +#include <cutils/hashmap.h> +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_GLYPH_H + +#include <pixelflinger/pixelflinger.h> +#include <pthread.h> + +#define STRING_CACHE_MAX_ENTRIES 400 +#define STRING_CACHE_TRUNCATE_ENTRIES 150 + +typedef struct +{ + int size; + int dpi; + char *path; +} TrueTypeFontKey; + +typedef struct +{ + int type; + int refcount; + int size; + int dpi; + int max_height; + int base; + FT_Face face; + Hashmap *glyph_cache; + Hashmap *string_cache; + struct StringCacheEntry *string_cache_head; + struct StringCacheEntry *string_cache_tail; + pthread_mutex_t mutex; + TrueTypeFontKey *key; +} TrueTypeFont; + +typedef struct +{ + FT_BBox bbox; + FT_BitmapGlyph glyph; +} TrueTypeCacheEntry; + +typedef struct +{ + char *text; + int max_width; +} StringCacheKey; + +struct StringCacheEntry +{ + GGLSurface surface; + int rendered_bytes; // number of bytes from C string rendered, not number of UTF8 characters! + StringCacheKey *key; + struct StringCacheEntry *prev; + struct StringCacheEntry *next; +}; + +typedef struct StringCacheEntry StringCacheEntry; + +typedef struct +{ + FT_Library ft_library; + Hashmap *fonts; + pthread_mutex_t mutex; +} FontData; + +static FontData font_data = { + .ft_library = NULL, + .fonts = NULL, + .mutex = PTHREAD_MUTEX_INITIALIZER, +}; + +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) +#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) + +// 32bit FNV-1a hash algorithm +// http://isthe.com/chongo/tech/comp/fnv/#FNV-1a +static const uint32_t FNV_prime = 16777619U; +static const uint32_t offset_basis = 2166136261U; + +static uint32_t fnv_hash(void *data, uint32_t len) +{ + uint8_t *d8 = data; + uint32_t *d32 = data; + uint32_t i, max; + uint32_t hash = offset_basis; + + max = len/4; + + // 32 bit data + for(i = 0; i < max; ++i) + { + hash ^= *d32++; + hash *= FNV_prime; + } + + // last bits + for(i *= 4; i < len; ++i) + { + hash ^= (uint32_t) d8[i]; + hash *= FNV_prime; + } + return hash; +} + +static inline uint32_t fnv_hash_add(uint32_t cur_hash, uint32_t word) +{ + cur_hash ^= word; + cur_hash *= FNV_prime; + return cur_hash; +} + +int utf8_to_unicode(unsigned char* pIn, unsigned int *pOut) +{ + if(pIn == NULL || pOut == NULL) + return 0; + + int utf_bytes = 1; + unsigned int unicode = 0; + unsigned char tmp; + tmp = *pIn++; + if (tmp < 0x80) + { + *pOut = tmp; + } + else + { + unsigned int high_bit_mask = 0x3F; + unsigned int high_bit_shift = 0; + int total_bits = 0; + while((tmp & 0xC0) == 0xC0) + { + utf_bytes ++; + if(utf_bytes > 6) return 0; + tmp = 0xFF & (tmp << 1); + total_bits += 6; + high_bit_mask >>= 1; + high_bit_shift++; + unicode <<= 6; + unicode |= (*pIn++) & 0x3F; + } + unicode |= ((tmp >> high_bit_shift) & high_bit_mask) << total_bits; + *pOut = unicode; + } + + return utf_bytes; +} + +static bool gr_ttf_string_cache_equals(void *keyA, void *keyB) +{ + StringCacheKey *a = keyA; + StringCacheKey *b = keyB; + return a->max_width == b->max_width && strcmp(a->text, b->text) == 0; +} + +static int gr_ttf_string_cache_hash(void *key) +{ + StringCacheKey *k = key; + return fnv_hash(k->text, strlen(k->text)); +} + +static bool gr_ttf_font_cache_equals(void *keyA, void *keyB) +{ + TrueTypeFontKey *a = keyA; + TrueTypeFontKey *b = keyB; + return (a->size == b->size) && (a->dpi == b->dpi) && !strcmp(a->path, b->path); +} + +static int gr_ttf_font_cache_hash(void *key) +{ + TrueTypeFontKey *k = key; + + uint32_t hash = fnv_hash(k->path, strlen(k->path)); + hash = fnv_hash_add(hash, k->size); + hash = fnv_hash_add(hash, k->dpi); + return hash; +} + +void *gr_ttf_loadFont(const char *filename, int size, int dpi) +{ + int error; + TrueTypeFont *res = NULL; + + pthread_mutex_lock(&font_data.mutex); + + if(font_data.fonts) + { + TrueTypeFontKey k = { + .size = size, + .dpi = dpi, + .path = (char*)filename + }; + + res = hashmapGet(font_data.fonts, &k); + if(res) + { + ++res->refcount; + goto exit; + } + } + + if(!font_data.ft_library) + { + error = FT_Init_FreeType(&font_data.ft_library); + if(error) + { + fprintf(stderr, "Failed to init libfreetype! %d\n", error); + goto exit; + } + } + + FT_Face face; + error = FT_New_Face(font_data.ft_library, filename, 0, &face); + if(error) + { + fprintf(stderr, "Failed to load truetype face %s: %d\n", filename, error); + goto exit; + } + + error = FT_Set_Char_Size(face, 0, size*16, dpi, dpi); + if(error) + { + fprintf(stderr, "Failed to set truetype face size to %d, dpi %d: %d\n", size, dpi, error); + FT_Done_Face(face); + goto exit; + } + + res = malloc(sizeof(TrueTypeFont)); + memset(res, 0, sizeof(TrueTypeFont)); + res->type = FONT_TYPE_TTF; + res->size = size; + res->dpi = dpi; + res->face = face; + res->max_height = -1; + res->base = -1; + res->refcount = 1; + res->glyph_cache = hashmapCreate(32, hashmapIntHash, hashmapIntEquals); + res->string_cache = hashmapCreate(128, gr_ttf_string_cache_hash, gr_ttf_string_cache_equals); + pthread_mutex_init(&res->mutex, 0); + + if(!font_data.fonts) + font_data.fonts = hashmapCreate(4, gr_ttf_font_cache_hash, gr_ttf_font_cache_equals); + + TrueTypeFontKey *key = malloc(sizeof(TrueTypeFontKey)); + memset(key, 0, sizeof(TrueTypeFontKey)); + key->path = strdup(filename); + key->size = size; + key->dpi = dpi; + + res->key = key; + + hashmapPut(font_data.fonts, key, res); + +exit: + pthread_mutex_unlock(&font_data.mutex); + return res; +} + +static bool gr_ttf_freeFontCache(void *key, void *value, void *context) +{ + TrueTypeCacheEntry *e = value; + FT_Done_Glyph((FT_Glyph)e->glyph); + free(e); + free(key); + return true; +} + +static bool gr_ttf_freeStringCache(void *key, void *value, void *context) +{ + StringCacheKey *k = key; + free(k->text); + free(k); + + StringCacheEntry *e = value; + free(e->surface.data); + free(e); + return true; +} + +void gr_ttf_freeFont(void *font) +{ + pthread_mutex_lock(&font_data.mutex); + + TrueTypeFont *d = font; + + if(--d->refcount == 0) + { + hashmapRemove(font_data.fonts, d->key); + + if(hashmapSize(font_data.fonts) == 0) + { + hashmapFree(font_data.fonts); + font_data.fonts = NULL; + } + + free(d->key->path); + free(d->key); + + FT_Done_Face(d->face); + hashmapForEach(d->string_cache, gr_ttf_freeStringCache, NULL); + hashmapFree(d->string_cache); + hashmapForEach(d->glyph_cache, gr_ttf_freeFontCache, NULL); + hashmapFree(d->glyph_cache); + pthread_mutex_destroy(&d->mutex); + free(d); + } + + pthread_mutex_unlock(&font_data.mutex); +} + +static TrueTypeCacheEntry *gr_ttf_glyph_cache_peek(TrueTypeFont *font, int char_index) +{ + return hashmapGet(font->glyph_cache, &char_index); +} + +static TrueTypeCacheEntry *gr_ttf_glyph_cache_get(TrueTypeFont *font, int char_index) +{ + TrueTypeCacheEntry *res = hashmapGet(font->glyph_cache, &char_index); + if(!res) + { + int error = FT_Load_Glyph(font->face, char_index, FT_LOAD_RENDER); + if(error) + { + fprintf(stderr, "Failed to load glyph idx %d: %d\n", char_index, error); + return NULL; + } + + FT_BitmapGlyph glyph; + error = FT_Get_Glyph(font->face->glyph, (FT_Glyph*)&glyph); + if(error) + { + fprintf(stderr, "Failed to copy glyph %d: %d\n", char_index, error); + return NULL; + } + + res = malloc(sizeof(TrueTypeCacheEntry)); + memset(res, 0, sizeof(TrueTypeCacheEntry)); + res->glyph = glyph; + FT_Glyph_Get_CBox((FT_Glyph)glyph, FT_GLYPH_BBOX_PIXELS, &res->bbox); + + int *key = malloc(sizeof(int)); + *key = char_index; + + hashmapPut(font->glyph_cache, key, res); + } + + return res; +} + +static int gr_ttf_copy_glyph_to_surface(GGLSurface *dest, FT_BitmapGlyph glyph, int offX, int offY, int base) +{ + int y; + uint8_t *src_itr = glyph->bitmap.buffer; + uint8_t *dest_itr = dest->data; + + if(glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY) + { + fprintf(stderr, "Unsupported pixel mode in FT_BitmapGlyph %d\n", glyph->bitmap.pixel_mode); + return -1; + } + + dest_itr += (offY + base - glyph->top)*dest->stride + (offX + glyph->left); + + for(y = 0; y < glyph->bitmap.rows; ++y) + { + memcpy(dest_itr, src_itr, glyph->bitmap.width); + src_itr += glyph->bitmap.pitch; + dest_itr += dest->stride; + } + return 0; +} + +// returns number of bytes from const char *text rendered to fit max_width, not number of UTF8 characters! +static int gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const char *text, int max_width) +{ + TrueTypeFont *f = font; + TrueTypeCacheEntry *ent; + int bytes_rendered = 0, total_w = 0; + int utf_bytes = 0; + unsigned int unicode = 0; + int i, x, diff, char_idx, prev_idx = 0; + int height, base; + FT_Vector delta; + uint8_t *data = NULL; + const char *text_itr = text; + int *char_idxs; + int char_idxs_len = 0; + + char_idxs = malloc(strlen(text) * sizeof(int)); + + while(*text_itr) + { + utf_bytes = utf8_to_unicode(text_itr, &unicode); + text_itr += utf_bytes; + bytes_rendered += utf_bytes; + + char_idx = FT_Get_Char_Index(f->face, unicode); + char_idxs[char_idxs_len] = char_idx; + + ent = gr_ttf_glyph_cache_get(f, char_idx); + if(ent) + { + diff = ent->glyph->root.advance.x >> 16; + + if(FT_HAS_KERNING(f->face) && prev_idx && char_idx) + { + FT_Get_Kerning(f->face, prev_idx, char_idx, FT_KERNING_DEFAULT, &delta); + diff += delta.x >> 6; + } + + if(max_width != -1 && total_w + diff > max_width) + break; + + total_w += diff; + } + prev_idx = char_idx; + ++char_idxs_len; + } + + if(font->max_height == -1) + gr_ttf_getMaxFontHeight(font); + + if(font->max_height == -1) + { + free(char_idxs); + return -1; + } + + height = font->max_height; + + data = malloc(total_w*height); + memset(data, 0, total_w*height); + x = 0; + prev_idx = 0; + + surface->version = sizeof(*surface); + surface->width = total_w; + surface->height = height; + surface->stride = total_w; + surface->data = (void*)data; + surface->format = GGL_PIXEL_FORMAT_A_8; + + for(i = 0; i < char_idxs_len; ++i) + { + char_idx = char_idxs[i]; + if(FT_HAS_KERNING(f->face) && prev_idx && char_idx) + { + FT_Get_Kerning(f->face, prev_idx, char_idx, FT_KERNING_DEFAULT, &delta); + x += delta.x >> 6; + } + + ent = gr_ttf_glyph_cache_get(f, char_idx); + if(ent) + { + gr_ttf_copy_glyph_to_surface(surface, ent->glyph, x, 0, font->base); + x += ent->glyph->root.advance.x >> 16; + } + + prev_idx = char_idx; + } + + free(char_idxs); + return bytes_rendered; +} + +static StringCacheEntry *gr_ttf_string_cache_peek(TrueTypeFont *font, const char *text, int max_width) +{ + StringCacheEntry *res; + StringCacheKey k = { + .text = (char*)text, + .max_width = max_width + }; + + return hashmapGet(font->string_cache, &k); +} + +static StringCacheEntry *gr_ttf_string_cache_get(TrueTypeFont *font, const char *text, int max_width) +{ + StringCacheEntry *res; + StringCacheKey k = { + .text = (char*)text, + .max_width = max_width + }; + + res = hashmapGet(font->string_cache, &k); + if(!res) + { + res = malloc(sizeof(StringCacheEntry)); + memset(res, 0, sizeof(StringCacheEntry)); + res->rendered_bytes = gr_ttf_render_text(font, &res->surface, text, max_width); + if(res->rendered_bytes < 0) + { + free(res); + return NULL; + } + + StringCacheKey *new_key = malloc(sizeof(StringCacheKey)); + memset(new_key, 0, sizeof(StringCacheKey)); + new_key->max_width = max_width; + new_key->text = strdup(text); + + res->key = new_key; + + if(font->string_cache_tail) + { + res->prev = font->string_cache_tail; + res->prev->next = res; + } + else + font->string_cache_head = res; + font->string_cache_tail = res; + + hashmapPut(font->string_cache, new_key, res); + } + else if(res->next) + { + // move this entry to the tail of the linked list + // if it isn't already there + if(res->prev) + res->prev->next = res->next; + + res->next->prev = res->prev; + + if(!res->prev) + font->string_cache_head = res->next; + + res->next = NULL; + res->prev = font->string_cache_tail; + res->prev->next = res; + font->string_cache_tail = res; + + // truncate old entries + if(hashmapSize(font->string_cache) >= STRING_CACHE_MAX_ENTRIES) + { + printf("Truncating string cache entries.\n"); + int i; + StringCacheEntry *ent; + for(i = 0; i < STRING_CACHE_TRUNCATE_ENTRIES; ++i) + { + ent = font->string_cache_head; + font->string_cache_head = ent->next; + font->string_cache_head->prev = NULL; + + hashmapRemove(font->string_cache, ent->key); + + gr_ttf_freeStringCache(ent->key, ent, NULL); + } + } + } + return res; +} + +int gr_ttf_measureEx(const char *s, void *font) +{ + TrueTypeFont *f = font; + int res = -1; + + pthread_mutex_lock(&f->mutex); + StringCacheEntry *e = gr_ttf_string_cache_get(font, s, -1); + if(e) + res = e->surface.width; + pthread_mutex_unlock(&f->mutex); + + return res; +} + +int gr_ttf_maxExW(const char *s, void *font, int max_width) +{ + TrueTypeFont *f = font; + TrueTypeCacheEntry *ent; + int max_bytes = 0, total_w = 0; + int utf_bytes, prev_utf_bytes = 0; + unsigned int unicode = 0; + int char_idx, prev_idx = 0; + FT_Vector delta; + StringCacheEntry *e; + + pthread_mutex_lock(&f->mutex); + + e = gr_ttf_string_cache_peek(font, s, max_width); + if(e) + { + max_bytes = e->rendered_bytes; + pthread_mutex_unlock(&f->mutex); + return max_bytes; + } + + while(*s) + { + utf_bytes = utf8_to_unicode(s, &unicode); + s += utf_bytes; + + char_idx = FT_Get_Char_Index(f->face, unicode); + if(FT_HAS_KERNING(f->face) && prev_idx && char_idx) + { + FT_Get_Kerning(f->face, prev_idx, char_idx, FT_KERNING_DEFAULT, &delta); + total_w += delta.x >> 6; + } + prev_idx = char_idx; + + if(total_w > max_width) + { + max_bytes -= prev_utf_bytes; + break; + } + prev_utf_bytes = utf_bytes; + + ent = gr_ttf_glyph_cache_get(f, char_idx); + if(!ent) + continue; + + total_w += ent->glyph->root.advance.x >> 16; + max_bytes += utf_bytes; + } + pthread_mutex_unlock(&f->mutex); + return max_bytes; +} + +int gr_ttf_textExWH(void *context, int x, int y, const char *s, void *pFont, int max_width, int max_height) +{ + GGLContext *gl = context; + TrueTypeFont *font = pFont; + + // not actualy max width, but max_width + x + if(max_width != -1) + { + max_width -= x; + if(max_width <= 0) + return 0; + } + + pthread_mutex_lock(&font->mutex); + + StringCacheEntry *e = gr_ttf_string_cache_get(font, s, max_width); + if(!e) + { + pthread_mutex_unlock(&font->mutex); + return -1; + } + + int y_bottom = y + e->surface.height; + int res = e->rendered_bytes; + + if(max_height != -1 && max_height < y_bottom) + { + y_bottom = max_height; + if(y_bottom <= y) + { + pthread_mutex_unlock(&font->mutex); + return 0; + } + } + + gl->bindTexture(gl, &e->surface); + gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); + gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); + + gl->enable(gl, GGL_TEXTURE_2D); + gl->texCoord2i(gl, -x, -y); + gl->recti(gl, x, y, x + e->surface.width, y_bottom); + gl->disable(gl, GGL_TEXTURE_2D); + + pthread_mutex_unlock(&font->mutex); + return res; +} + +int gr_ttf_getMaxFontHeight(void *font) +{ + int res; + TrueTypeFont *f = font; + + pthread_mutex_lock(&f->mutex); + + if(f->max_height == -1) + { + char c; + int char_idx; + int error; + FT_Glyph glyph; + FT_BBox bbox; + FT_BBox bbox_glyph; + TrueTypeCacheEntry *ent; + + bbox.yMin = bbox_glyph.yMin = LONG_MAX; + bbox.yMax = bbox_glyph.yMax = LONG_MIN; + + for(c = '!'; c <= '~'; ++c) + { + char_idx = FT_Get_Char_Index(f->face, c); + ent = gr_ttf_glyph_cache_peek(f, char_idx); + if(ent) + { + bbox.yMin = MIN(bbox.yMin, ent->bbox.yMin); + bbox.yMax = MAX(bbox.yMax, ent->bbox.yMax); + } + else + { + error = FT_Load_Glyph(f->face, char_idx, 0); + if(error) + continue; + + error = FT_Get_Glyph(f->face->glyph, &glyph); + if(error) + continue; + + FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &bbox_glyph); + bbox.yMin = MIN(bbox.yMin, bbox_glyph.yMin); + bbox.yMax = MAX(bbox.yMax, bbox_glyph.yMax); + + FT_Done_Glyph(glyph); + } + } + + if(bbox.yMin > bbox.yMax) + bbox.yMin = bbox.yMax = 0; + + f->max_height = bbox.yMax - bbox.yMin; + f->base = bbox.yMax; + + // FIXME: twrp fonts have some padding on top, I'll add it here + // Should be fixed in the themes + f->max_height += f->size / 4; + f->base += f->size / 4; + } + + res = f->max_height; + + pthread_mutex_unlock(&f->mutex); + return res; +} + +static bool gr_ttf_dump_stats_count_string_cache(void *key, void *value, void *context) +{ + int *string_cache_size = context; + StringCacheEntry *e = value; + *string_cache_size += e->surface.height*e->surface.width + sizeof(StringCacheEntry); + return true; +} + +static bool gr_ttf_dump_stats_font(void *key, void *value, void *context) +{ + TrueTypeFontKey *k = key; + TrueTypeFont *f = value; + int *total_string_cache_size = context; + int string_cache_size = 0; + + pthread_mutex_lock(&f->mutex); + + hashmapForEach(f->string_cache, gr_ttf_dump_stats_count_string_cache, &string_cache_size); + + printf(" Font %s (size %d, dpi %d):\n" + " refcount: %d\n" + " max_height: %d\n" + " base: %d\n" + " glyph_cache: %d entries\n" + " string_cache: %d entries (%.2f kB)\n", + k->path, k->size, k->dpi, + f->refcount, f->max_height, f->base, + hashmapSize(f->glyph_cache), + hashmapSize(f->string_cache), ((double)string_cache_size)/1024); + + pthread_mutex_unlock(&f->mutex); + + *total_string_cache_size += string_cache_size; + return true; +} + +void gr_ttf_dump_stats(void) +{ + pthread_mutex_lock(&font_data.mutex); + + printf("TrueType fonts system stats: "); + if(!font_data.fonts) + printf("no truetype fonts loaded.\n"); + else + { + int total_string_cache_size = 0; + printf("%d fonts loaded.\n", hashmapSize(font_data.fonts)); + hashmapForEach(font_data.fonts, gr_ttf_dump_stats_font, &total_string_cache_size); + printf(" Total string cache size: %.2f kB\n", ((double)total_string_cache_size)/1024); + } + + pthread_mutex_unlock(&font_data.mutex); +} |