summaryrefslogtreecommitdiffstats
path: root/minui
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--minui.old/Android.mk140
-rw-r--r--minui.old/events.c (renamed from minui/events.c)0
-rw-r--r--minui.old/font_10x18.h214
-rw-r--r--minui.old/font_7x16.h (renamed from minui/font_7x16.h)0
-rw-r--r--minui.old/graphics.c (renamed from minui/graphics.c)0
-rw-r--r--minui.old/graphics_overlay.c (renamed from minui/graphics_overlay.c)0
-rw-r--r--minui.old/include/linux/msm_ion.h (renamed from minui/include/linux/msm_ion.h)0
-rw-r--r--minui.old/include/linux/msm_mdp.h (renamed from minui/include/linux/msm_mdp.h)0
-rw-r--r--minui.old/minui.h105
-rw-r--r--minui.old/mkfont.c54
-rw-r--r--minui.old/resources.c (renamed from minui/resources.c)0
-rw-r--r--minui.old/roboto_10x18.h (renamed from minui/roboto_10x18.h)0
-rw-r--r--minui.old/roboto_15x24.h (renamed from minui/roboto_15x24.h)0
-rw-r--r--minui.old/roboto_23x41.h (renamed from minui/roboto_23x41.h)0
-rw-r--r--minui/Android.mk101
-rw-r--r--minui/events.cpp232
-rw-r--r--minui/font_10x18.h2
-rw-r--r--minui/graphics.cpp411
-rw-r--r--minui/graphics.h43
-rw-r--r--minui/graphics_adf.cpp249
-rw-r--r--minui/graphics_drm.cpp476
-rw-r--r--minui/graphics_fbdev.cpp227
-rw-r--r--minui/minui.h113
-rw-r--r--minui/resources.cpp459
-rw-r--r--minuitwrp/Android.mk2
-rw-r--r--minuitwrp/events.c2
-rw-r--r--minuitwrp/graphics.c1
-rw-r--r--minuitwrp/resources.c1
28 files changed, 2748 insertions, 84 deletions
diff --git a/minui.old/Android.mk b/minui.old/Android.mk
new file mode 100644
index 000000000..7d8e3a7f3
--- /dev/null
+++ b/minui.old/Android.mk
@@ -0,0 +1,140 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := graphics_overlay.c events.c resources.c
+ifneq ($(BOARD_CUSTOM_GRAPHICS),)
+ LOCAL_SRC_FILES += $(BOARD_CUSTOM_GRAPHICS)
+else
+ LOCAL_SRC_FILES += graphics.c
+endif
+
+LOCAL_C_INCLUDES +=\
+ external/libpng \
+ external/zlib \
+ system/core/include/pixelflinger
+
+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)/minui/include
+ else
+ LOCAL_C_INCLUDES += $(TARGET_CUSTOM_KERNEL_HEADERS)
+ endif
+ endif
+else
+ LOCAL_C_INCLUDES += $(commands_recovery_local_path)/minui/include
+endif
+
+ifeq ($(TW_NEW_ION_HEAP), true)
+ LOCAL_CFLAGS += -DNEW_ION_HEAP
+endif
+
+LOCAL_STATIC_LIBRARY := libpng
+LOCAL_WHOLE_STATIC_LIBRARIES := libpixelflinger_static
+LOCAL_MODULE := libminui
+
+# This used to compare against values in double-quotes (which are just
+# ordinary characters in this context). Strip double-quotes from the
+# value so that either will work.
+
+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
+
+ifneq ($(TARGET_RECOVERY_OVERSCAN_PERCENT),)
+ LOCAL_CFLAGS += -DOVERSCAN_PERCENT=$(TARGET_RECOVERY_OVERSCAN_PERCENT)
+else
+ LOCAL_CFLAGS += -DOVERSCAN_PERCENT=0
+endif
+
+ifneq ($(TW_BRIGHTNESS_PATH),)
+ LOCAL_CFLAGS += -DTW_BRIGHTNESS_PATH=\"$(TW_BRIGHTNESS_PATH)\"
+endif
+ifneq ($(TW_MAX_BRIGHTNESS),)
+ LOCAL_CFLAGS += -DTW_MAX_BRIGHTNESS=$(TW_MAX_BRIGHTNESS)
+else
+ LOCAL_CFLAGS += -DTW_MAX_BRIGHTNESS=255
+endif
+ifneq ($(TW_NO_SCREEN_BLANK),)
+ LOCAL_CFLAGS += -DTW_NO_SCREEN_BLANK
+endif
+ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),)
+ LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=$(BOARD_USE_CUSTOM_RECOVERY_FONT)
+endif
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := graphics_overlay.c events.c resources.c
+ifneq ($(BOARD_CUSTOM_GRAPHICS),)
+ LOCAL_SRC_FILES += $(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)/minui/include
+ else
+ LOCAL_C_INCLUDES += $(TARGET_CUSTOM_KERNEL_HEADERS)
+ endif
+ endif
+else
+ LOCAL_C_INCLUDES += $(commands_recovery_local_path)/minui/include
+endif
+
+LOCAL_C_INCLUDES +=\
+ external/libpng\
+ external/zlib
+
+LOCAL_MODULE := libminui
+
+LOCAL_ARM_MODE:= arm
+LOCAL_SHARED_LIBRARIES := libpng libpixelflinger
+# This used to compare against values in double-quotes (which are just
+# ordinary characters in this context). Strip double-quotes from the
+# value so that either will work.
+
+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
+
+ifneq ($(TARGET_RECOVERY_OVERSCAN_PERCENT),)
+ LOCAL_CFLAGS += -DOVERSCAN_PERCENT=$(TARGET_RECOVERY_OVERSCAN_PERCENT)
+else
+ LOCAL_CFLAGS += -DOVERSCAN_PERCENT=0
+endif
+
+ifneq ($(TW_BRIGHTNESS_PATH),)
+ LOCAL_CFLAGS += -DTW_BRIGHTNESS_PATH=\"$(TW_BRIGHTNESS_PATH)\"
+endif
+ifneq ($(TW_MAX_BRIGHTNESS),)
+ LOCAL_CFLAGS += -DTW_MAX_BRIGHTNESS=$(TW_MAX_BRIGHTNESS)
+else
+ LOCAL_CFLAGS += -DTW_MAX_BRIGHTNESS=255
+endif
+ifneq ($(TW_NO_SCREEN_BLANK),)
+ LOCAL_CFLAGS += -DTW_NO_SCREEN_BLANK
+endif
+ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),)
+ LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=$(BOARD_USE_CUSTOM_RECOVERY_FONT)
+endif
+
+LOCAL_CFLAGS += -DFASTMMI_FEATURE
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/minui/events.c b/minui.old/events.c
index b8cf15ab4..b8cf15ab4 100644
--- a/minui/events.c
+++ b/minui.old/events.c
diff --git a/minui.old/font_10x18.h b/minui.old/font_10x18.h
new file mode 100644
index 000000000..7f96465cc
--- /dev/null
+++ b/minui.old/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/minui/font_7x16.h b/minui.old/font_7x16.h
index 0f72b5386..0f72b5386 100644
--- a/minui/font_7x16.h
+++ b/minui.old/font_7x16.h
diff --git a/minui/graphics.c b/minui.old/graphics.c
index cce02a963..cce02a963 100644
--- a/minui/graphics.c
+++ b/minui.old/graphics.c
diff --git a/minui/graphics_overlay.c b/minui.old/graphics_overlay.c
index d793b57e6..d793b57e6 100644
--- a/minui/graphics_overlay.c
+++ b/minui.old/graphics_overlay.c
diff --git a/minui/include/linux/msm_ion.h b/minui.old/include/linux/msm_ion.h
index 121a5a7a7..121a5a7a7 100644
--- a/minui/include/linux/msm_ion.h
+++ b/minui.old/include/linux/msm_ion.h
diff --git a/minui/include/linux/msm_mdp.h b/minui.old/include/linux/msm_mdp.h
index abdcd29e9..abdcd29e9 100644
--- a/minui/include/linux/msm_mdp.h
+++ b/minui.old/include/linux/msm_mdp.h
diff --git a/minui.old/minui.h b/minui.old/minui.h
new file mode 100644
index 000000000..4c629c1b5
--- /dev/null
+++ b/minui.old/minui.h
@@ -0,0 +1,105 @@
+/*
+ * 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_
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* gr_surface;
+typedef unsigned short gr_pixel;
+
+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);
+void gr_fb_blank(bool blank);
+
+void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+void gr_fill(int x1, int y1, int x2, int y2);
+
+// system/core/charger uses different gr_print signatures in diferent
+// Android versions, either with or without int bold.
+int gr_text(int x, int y, const char *s, ...);
+int gr_text_impl(int x, int y, const char *s, int bold);
+
+ void gr_texticon(int x, int y, gr_surface icon);
+int gr_measure(const char *s);
+void gr_font_size(int *x, int *y);
+void gr_get_memory_surface(gr_surface);
+
+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);
+
+// input event structure, include <linux/input.h> for the definition.
+// see http://www.mjmwired.net/kernel/Documentation/input/ for info.
+struct input_event;
+
+typedef int (*ev_callback)(int fd, uint32_t epevents, void *data);
+typedef int (*ev_set_key_callback)(int code, int value, void *data);
+
+int ev_init(ev_callback input_cb, void *data);
+void ev_exit(void);
+int ev_add_fd(int fd, ev_callback cb, void *data);
+int ev_sync_key_state(ev_set_key_callback set_key_cb, void *data);
+
+/* timeout has the same semantics as for poll
+ * 0 : don't block
+ * < 0 : block forever
+ * > 0 : block for 'timeout' milliseconds
+ */
+int ev_wait(int timeout);
+
+int ev_get_input(int fd, uint32_t epevents, struct input_event *ev);
+void ev_dispatch(void);
+int ev_get_epollfd(void);
+
+// Resources
+
+// Returns 0 if no error, else negative.
+int res_create_surface(const char* name, gr_surface* pSurface);
+
+// Load an array of display surfaces from a single PNG image. The PNG
+// should have a 'Frames' text chunk whose value is the number of
+// frames this image represents. The pixel data itself is interlaced
+// by row.
+int res_create_multi_display_surface(const char* name,
+ int* frames, gr_surface** pSurface);
+
+int res_create_localized_surface(const char* name, gr_surface* pSurface);
+void res_free_surface(gr_surface surface);
+static inline int res_create_display_surface(const char* name, gr_surface* pSurface) {
+ return res_create_surface(name, pSurface);
+}
+
+// These are new graphics functions from 5.0 that were not available in
+// 4.4 that are required by charger and healthd
+void gr_clear();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/minui.old/mkfont.c b/minui.old/mkfont.c
new file mode 100644
index 000000000..61a5edeb2
--- /dev/null
+++ b/minui.old/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/minui/resources.c b/minui.old/resources.c
index ed25e45a2..ed25e45a2 100644
--- a/minui/resources.c
+++ b/minui.old/resources.c
diff --git a/minui/roboto_10x18.h b/minui.old/roboto_10x18.h
index 3119c81c2..3119c81c2 100644
--- a/minui/roboto_10x18.h
+++ b/minui.old/roboto_10x18.h
diff --git a/minui/roboto_15x24.h b/minui.old/roboto_15x24.h
index 7271d74bb..7271d74bb 100644
--- a/minui/roboto_15x24.h
+++ b/minui.old/roboto_15x24.h
diff --git a/minui/roboto_23x41.h b/minui.old/roboto_23x41.h
index 6e7566efe..6e7566efe 100644
--- a/minui/roboto_23x41.h
+++ b/minui.old/roboto_23x41.h
diff --git a/minui/Android.mk b/minui/Android.mk
index 7d8e3a7f3..d50bf1048 100644
--- a/minui/Android.mk
+++ b/minui/Android.mk
@@ -1,17 +1,13 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := graphics_overlay.c events.c resources.c
-ifneq ($(BOARD_CUSTOM_GRAPHICS),)
- LOCAL_SRC_FILES += $(BOARD_CUSTOM_GRAPHICS)
-else
- LOCAL_SRC_FILES += graphics.c
-endif
-
-LOCAL_C_INCLUDES +=\
- external/libpng \
- external/zlib \
- system/core/include/pixelflinger
+LOCAL_SRC_FILES := \
+ events.cpp \
+ graphics.cpp \
+ graphics_adf.cpp \
+ graphics_drm.cpp \
+ graphics_fbdev.cpp \
+ resources.cpp \
ifeq ($(TW_TARGET_USES_QCOM_BSP), true)
LOCAL_CFLAGS += -DMSM_BSP
@@ -33,14 +29,21 @@ ifeq ($(TW_NEW_ION_HEAP), true)
LOCAL_CFLAGS += -DNEW_ION_HEAP
endif
-LOCAL_STATIC_LIBRARY := libpng
-LOCAL_WHOLE_STATIC_LIBRARIES := libpixelflinger_static
+LOCAL_WHOLE_STATIC_LIBRARIES += libadf
+LOCAL_WHOLE_STATIC_LIBRARIES += libdrm
+LOCAL_STATIC_LIBRARIES += libpng
+
LOCAL_MODULE := libminui
+LOCAL_CLANG := true
+
# This used to compare against values in double-quotes (which are just
# ordinary characters in this context). Strip double-quotes from the
# value so that either will work.
+ifeq ($(subst ",,$(TARGET_RECOVERY_PIXEL_FORMAT)),ABGR_8888)
+ LOCAL_CFLAGS += -DRECOVERY_ABGR
+endif
ifeq ($(subst ",,$(TARGET_RECOVERY_PIXEL_FORMAT)),RGBX_8888)
LOCAL_CFLAGS += -DRECOVERY_RGBX
endif
@@ -65,76 +68,12 @@ endif
ifneq ($(TW_NO_SCREEN_BLANK),)
LOCAL_CFLAGS += -DTW_NO_SCREEN_BLANK
endif
-ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),)
- LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=$(BOARD_USE_CUSTOM_RECOVERY_FONT)
-endif
+
include $(BUILD_STATIC_LIBRARY)
+# Used by OEMs for factory test images.
include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := graphics_overlay.c events.c resources.c
-ifneq ($(BOARD_CUSTOM_GRAPHICS),)
- LOCAL_SRC_FILES += $(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)/minui/include
- else
- LOCAL_C_INCLUDES += $(TARGET_CUSTOM_KERNEL_HEADERS)
- endif
- endif
-else
- LOCAL_C_INCLUDES += $(commands_recovery_local_path)/minui/include
-endif
-
-LOCAL_C_INCLUDES +=\
- external/libpng\
- external/zlib
-
LOCAL_MODULE := libminui
-
-LOCAL_ARM_MODE:= arm
-LOCAL_SHARED_LIBRARIES := libpng libpixelflinger
-# This used to compare against values in double-quotes (which are just
-# ordinary characters in this context). Strip double-quotes from the
-# value so that either will work.
-
-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
-
-ifneq ($(TARGET_RECOVERY_OVERSCAN_PERCENT),)
- LOCAL_CFLAGS += -DOVERSCAN_PERCENT=$(TARGET_RECOVERY_OVERSCAN_PERCENT)
-else
- LOCAL_CFLAGS += -DOVERSCAN_PERCENT=0
-endif
-
-ifneq ($(TW_BRIGHTNESS_PATH),)
- LOCAL_CFLAGS += -DTW_BRIGHTNESS_PATH=\"$(TW_BRIGHTNESS_PATH)\"
-endif
-ifneq ($(TW_MAX_BRIGHTNESS),)
- LOCAL_CFLAGS += -DTW_MAX_BRIGHTNESS=$(TW_MAX_BRIGHTNESS)
-else
- LOCAL_CFLAGS += -DTW_MAX_BRIGHTNESS=255
-endif
-ifneq ($(TW_NO_SCREEN_BLANK),)
- LOCAL_CFLAGS += -DTW_NO_SCREEN_BLANK
-endif
-ifneq ($(BOARD_USE_CUSTOM_RECOVERY_FONT),)
- LOCAL_CFLAGS += -DBOARD_USE_CUSTOM_RECOVERY_FONT=$(BOARD_USE_CUSTOM_RECOVERY_FONT)
-endif
-
-LOCAL_CFLAGS += -DFASTMMI_FEATURE
-
+LOCAL_WHOLE_STATIC_LIBRARIES += libminui
+LOCAL_SHARED_LIBRARIES := libpng
include $(BUILD_SHARED_LIBRARY)
diff --git a/minui/events.cpp b/minui/events.cpp
new file mode 100644
index 000000000..3b2262a4b
--- /dev/null
+++ b/minui/events.cpp
@@ -0,0 +1,232 @@
+/*
+ * 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 <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <unistd.h>
+
+#include <linux/input.h>
+
+#include "minui.h"
+
+#define MAX_DEVICES 16
+#define MAX_MISC_FDS 16
+
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+#define BITS_TO_LONGS(x) (((x) + BITS_PER_LONG - 1) / BITS_PER_LONG)
+
+struct fd_info {
+ int fd;
+ ev_callback cb;
+ void* data;
+};
+
+static int g_epoll_fd;
+static epoll_event polledevents[MAX_DEVICES + MAX_MISC_FDS];
+static int npolledevents;
+
+static fd_info ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS];
+
+static unsigned ev_count = 0;
+static unsigned ev_dev_count = 0;
+static unsigned ev_misc_count = 0;
+
+static bool test_bit(size_t bit, unsigned long* array) {
+ return (array[bit/BITS_PER_LONG] & (1UL << (bit % BITS_PER_LONG))) != 0;
+}
+
+int ev_init(ev_callback input_cb, void* data) {
+ bool epollctlfail = false;
+
+ g_epoll_fd = epoll_create(MAX_DEVICES + MAX_MISC_FDS);
+ if (g_epoll_fd == -1) {
+ return -1;
+ }
+
+ DIR* dir = opendir("/dev/input");
+ if (dir != NULL) {
+ dirent* de;
+ while ((de = readdir(dir))) {
+ unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
+
+// fprintf(stderr,"/dev/input/%s\n", de->d_name);
+ if (strncmp(de->d_name, "event", 5)) continue;
+ int fd = openat(dirfd(dir), de->d_name, O_RDONLY);
+ if (fd == -1) continue;
+
+ // Read the evbits of the input device.
+ if (ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
+ close(fd);
+ continue;
+ }
+
+ // We assume that only EV_KEY, EV_REL, and EV_SW event types are ever needed.
+ if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) {
+ close(fd);
+ continue;
+ }
+
+ epoll_event ev;
+ ev.events = EPOLLIN | EPOLLWAKEUP;
+ ev.data.ptr = &ev_fdinfo[ev_count];
+ if (epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
+ close(fd);
+ epollctlfail = true;
+ continue;
+ }
+
+ ev_fdinfo[ev_count].fd = fd;
+ ev_fdinfo[ev_count].cb = input_cb;
+ ev_fdinfo[ev_count].data = data;
+ ev_count++;
+ ev_dev_count++;
+ if (ev_dev_count == MAX_DEVICES) break;
+ }
+
+ closedir(dir);
+ }
+
+ if (epollctlfail && !ev_count) {
+ close(g_epoll_fd);
+ g_epoll_fd = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+int ev_get_epollfd(void) {
+ return g_epoll_fd;
+}
+
+int ev_add_fd(int fd, ev_callback cb, void* data) {
+ if (ev_misc_count == MAX_MISC_FDS || cb == NULL) {
+ return -1;
+ }
+
+ epoll_event ev;
+ ev.events = EPOLLIN | EPOLLWAKEUP;
+ ev.data.ptr = (void *)&ev_fdinfo[ev_count];
+ int ret = epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, fd, &ev);
+ if (!ret) {
+ ev_fdinfo[ev_count].fd = fd;
+ ev_fdinfo[ev_count].cb = cb;
+ ev_fdinfo[ev_count].data = data;
+ ev_count++;
+ ev_misc_count++;
+ }
+
+ return ret;
+}
+
+void ev_exit(void) {
+ while (ev_count > 0) {
+ close(ev_fdinfo[--ev_count].fd);
+ }
+ ev_misc_count = 0;
+ ev_dev_count = 0;
+ close(g_epoll_fd);
+}
+
+int ev_wait(int timeout) {
+ npolledevents = epoll_wait(g_epoll_fd, polledevents, ev_count, timeout);
+ if (npolledevents <= 0) {
+ return -1;
+ }
+ return 0;
+}
+
+void ev_dispatch(void) {
+ for (int n = 0; n < npolledevents; n++) {
+ fd_info* fdi = reinterpret_cast<fd_info*>(polledevents[n].data.ptr);
+ ev_callback cb = fdi->cb;
+ if (cb) {
+ cb(fdi->fd, polledevents[n].events, fdi->data);
+ }
+ }
+}
+
+int ev_get_input(int fd, uint32_t epevents, input_event* ev) {
+ if (epevents & EPOLLIN) {
+ ssize_t r = TEMP_FAILURE_RETRY(read(fd, ev, sizeof(*ev)));
+ if (r == sizeof(*ev)) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data) {
+ unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
+ unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];
+
+ for (size_t i = 0; i < ev_dev_count; ++i) {
+ memset(ev_bits, 0, sizeof(ev_bits));
+ memset(key_bits, 0, sizeof(key_bits));
+
+ if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
+ continue;
+ }
+ if (!test_bit(EV_KEY, ev_bits)) {
+ continue;
+ }
+ if (ioctl(ev_fdinfo[i].fd, EVIOCGKEY(sizeof(key_bits)), key_bits) == -1) {
+ continue;
+ }
+
+ for (int code = 0; code <= KEY_MAX; code++) {
+ if (test_bit(code, key_bits)) {
+ set_key_cb(code, 1, data);
+ }
+ }
+ }
+
+ return 0;
+}
+
+void ev_iterate_available_keys(std::function<void(int)> f) {
+ unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
+ unsigned long key_bits[BITS_TO_LONGS(KEY_MAX)];
+
+ for (size_t i = 0; i < ev_dev_count; ++i) {
+ memset(ev_bits, 0, sizeof(ev_bits));
+ memset(key_bits, 0, sizeof(key_bits));
+
+ // Does this device even have keys?
+ if (ioctl(ev_fdinfo[i].fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) {
+ continue;
+ }
+ if (!test_bit(EV_KEY, ev_bits)) {
+ continue;
+ }
+
+ int rc = ioctl(ev_fdinfo[i].fd, EVIOCGBIT(EV_KEY, KEY_MAX), key_bits);
+ if (rc == -1) {
+ continue;
+ }
+
+ for (int key_code = 0; key_code <= KEY_MAX; ++key_code) {
+ if (test_bit(key_code, key_bits)) {
+ f(key_code);
+ }
+ }
+ }
+}
diff --git a/minui/font_10x18.h b/minui/font_10x18.h
index 7f96465cc..29d705344 100644
--- a/minui/font_10x18.h
+++ b/minui/font_10x18.h
@@ -3,7 +3,7 @@ struct {
unsigned height;
unsigned cwidth;
unsigned cheight;
- unsigned char rundata[];
+ unsigned char rundata[2973];
} font = {
.width = 960,
.height = 18,
diff --git a/minui/graphics.cpp b/minui/graphics.cpp
new file mode 100644
index 000000000..c0eea9e38
--- /dev/null
+++ b/minui/graphics.cpp
@@ -0,0 +1,411 @@
+/*
+ * 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 <string.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 <time.h>
+
+#include "font_10x18.h"
+#include "minui.h"
+#include "graphics.h"
+
+struct GRFont {
+ GRSurface* texture;
+ int cwidth;
+ int cheight;
+};
+
+static GRFont* gr_font = NULL;
+static minui_backend* gr_backend = NULL;
+
+static int overscan_percent = OVERSCAN_PERCENT;
+static int overscan_offset_x = 0;
+static int overscan_offset_y = 0;
+
+static unsigned char gr_current_r = 255;
+static unsigned char gr_current_g = 255;
+static unsigned char gr_current_b = 255;
+static unsigned char gr_current_a = 255;
+
+static GRSurface* gr_draw = NULL;
+
+static bool outside(int x, int y)
+{
+ return x < 0 || x >= gr_draw->width || y < 0 || y >= gr_draw->height;
+}
+
+int gr_measure(const char *s)
+{
+ return gr_font->cwidth * strlen(s);
+}
+
+void gr_font_size(int *x, int *y)
+{
+ *x = gr_font->cwidth;
+ *y = gr_font->cheight;
+}
+
+static void text_blend(unsigned char* src_p, int src_row_bytes,
+ unsigned char* dst_p, int dst_row_bytes,
+ int width, int height)
+{
+ for (int j = 0; j < height; ++j) {
+ unsigned char* sx = src_p;
+ unsigned char* px = dst_p;
+ for (int i = 0; i < width; ++i) {
+ unsigned char a = *sx++;
+ if (gr_current_a < 255) a = ((int)a * gr_current_a) / 255;
+ if (a == 255) {
+ *px++ = gr_current_r;
+ *px++ = gr_current_g;
+ *px++ = gr_current_b;
+ px++;
+ } else if (a > 0) {
+ *px = (*px * (255-a) + gr_current_r * a) / 255;
+ ++px;
+ *px = (*px * (255-a) + gr_current_g * a) / 255;
+ ++px;
+ *px = (*px * (255-a) + gr_current_b * a) / 255;
+ ++px;
+ ++px;
+ } else {
+ px += 4;
+ }
+ }
+ src_p += src_row_bytes;
+ dst_p += dst_row_bytes;
+ }
+}
+
+void gr_text(int x, int y, const char *s, bool bold)
+{
+ GRFont* font = gr_font;
+
+ if (!font->texture || gr_current_a == 0) return;
+
+ bold = bold && (font->texture->height != font->cheight);
+
+ x += overscan_offset_x;
+ y += overscan_offset_y;
+
+ unsigned char ch;
+ while ((ch = *s++)) {
+ if (outside(x, y) || outside(x+font->cwidth-1, y+font->cheight-1)) break;
+
+ if (ch < ' ' || ch > '~') {
+ ch = '?';
+ }
+
+ unsigned char* src_p = font->texture->data + ((ch - ' ') * font->cwidth) +
+ (bold ? font->cheight * font->texture->row_bytes : 0);
+ unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
+
+ text_blend(src_p, font->texture->row_bytes,
+ dst_p, gr_draw->row_bytes,
+ font->cwidth, font->cheight);
+
+ x += font->cwidth;
+ }
+}
+
+void gr_texticon(int x, int y, GRSurface* icon) {
+ if (icon == NULL) return;
+
+ if (icon->pixel_bytes != 1) {
+ printf("gr_texticon: source has wrong format\n");
+ return;
+ }
+
+ x += overscan_offset_x;
+ y += overscan_offset_y;
+
+ if (outside(x, y) || outside(x+icon->width-1, y+icon->height-1)) return;
+
+ unsigned char* src_p = icon->data;
+ unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
+
+ text_blend(src_p, icon->row_bytes,
+ dst_p, gr_draw->row_bytes,
+ icon->width, icon->height);
+}
+
+void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+{
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+ gr_current_r = b;
+ gr_current_g = g;
+ gr_current_b = r;
+ gr_current_a = a;
+#else
+ gr_current_r = r;
+ gr_current_g = g;
+ gr_current_b = b;
+ gr_current_a = a;
+#endif
+}
+
+void gr_clear()
+{
+ if (gr_current_r == gr_current_g && gr_current_r == gr_current_b) {
+ memset(gr_draw->data, gr_current_r, gr_draw->height * gr_draw->row_bytes);
+ } else {
+ unsigned char* px = gr_draw->data;
+ for (int y = 0; y < gr_draw->height; ++y) {
+ for (int x = 0; x < gr_draw->width; ++x) {
+ *px++ = gr_current_r;
+ *px++ = gr_current_g;
+ *px++ = gr_current_b;
+ px++;
+ }
+ px += gr_draw->row_bytes - (gr_draw->width * gr_draw->pixel_bytes);
+ }
+ }
+}
+
+void gr_fill(int x1, int y1, int x2, int y2)
+{
+ x1 += overscan_offset_x;
+ y1 += overscan_offset_y;
+
+ x2 += overscan_offset_x;
+ y2 += overscan_offset_y;
+
+ if (outside(x1, y1) || outside(x2-1, y2-1)) return;
+
+ unsigned char* p = gr_draw->data + y1 * gr_draw->row_bytes + x1 * gr_draw->pixel_bytes;
+ if (gr_current_a == 255) {
+ int x, y;
+ for (y = y1; y < y2; ++y) {
+ unsigned char* px = p;
+ for (x = x1; x < x2; ++x) {
+ *px++ = gr_current_r;
+ *px++ = gr_current_g;
+ *px++ = gr_current_b;
+ px++;
+ }
+ p += gr_draw->row_bytes;
+ }
+ } else if (gr_current_a > 0) {
+ int x, y;
+ for (y = y1; y < y2; ++y) {
+ unsigned char* px = p;
+ for (x = x1; x < x2; ++x) {
+ *px = (*px * (255-gr_current_a) + gr_current_r * gr_current_a) / 255;
+ ++px;
+ *px = (*px * (255-gr_current_a) + gr_current_g * gr_current_a) / 255;
+ ++px;
+ *px = (*px * (255-gr_current_a) + gr_current_b * gr_current_a) / 255;
+ ++px;
+ ++px;
+ }
+ p += gr_draw->row_bytes;
+ }
+ }
+}
+
+void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) {
+ if (source == NULL) return;
+
+ if (gr_draw->pixel_bytes != source->pixel_bytes) {
+ printf("gr_blit: source has wrong format\n");
+ return;
+ }
+
+ dx += overscan_offset_x;
+ dy += overscan_offset_y;
+
+ if (outside(dx, dy) || outside(dx+w-1, dy+h-1)) return;
+
+ unsigned char* src_p = source->data + sy*source->row_bytes + sx*source->pixel_bytes;
+ unsigned char* dst_p = gr_draw->data + dy*gr_draw->row_bytes + dx*gr_draw->pixel_bytes;
+
+ int i;
+ for (i = 0; i < h; ++i) {
+ memcpy(dst_p, src_p, w * source->pixel_bytes);
+ src_p += source->row_bytes;
+ dst_p += gr_draw->row_bytes;
+ }
+}
+
+unsigned int gr_get_width(GRSurface* surface) {
+ if (surface == NULL) {
+ return 0;
+ }
+ return surface->width;
+}
+
+unsigned int gr_get_height(GRSurface* surface) {
+ if (surface == NULL) {
+ return 0;
+ }
+ return surface->height;
+}
+
+static void gr_init_font(void)
+{
+ gr_font = reinterpret_cast<GRFont*>(calloc(sizeof(*gr_font), 1));
+
+ int res = res_create_alpha_surface("font", &(gr_font->texture));
+ if (res == 0) {
+ // The font image should be a 96x2 array of character images. The
+ // columns are the printable ASCII characters 0x20 - 0x7f. The
+ // top row is regular text; the bottom row is bold.
+ gr_font->cwidth = gr_font->texture->width / 96;
+ gr_font->cheight = gr_font->texture->height / 2;
+ } else {
+ printf("failed to read font: res=%d\n", res);
+
+ // fall back to the compiled-in font.
+ gr_font->texture = reinterpret_cast<GRSurface*>(malloc(sizeof(*gr_font->texture)));
+ gr_font->texture->width = font.width;
+ gr_font->texture->height = font.height;
+ gr_font->texture->row_bytes = font.width;
+ gr_font->texture->pixel_bytes = 1;
+
+ unsigned char* bits = reinterpret_cast<unsigned char*>(malloc(font.width * font.height));
+ gr_font->texture->data = reinterpret_cast<unsigned char*>(bits);
+
+ unsigned char data;
+ unsigned char* in = font.rundata;
+ while((data = *in++)) {
+ memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
+ bits += (data & 0x7f);
+ }
+
+ gr_font->cwidth = font.cwidth;
+ gr_font->cheight = font.cheight;
+ }
+}
+
+#if 0
+// Exercises many of the gr_*() functions; useful for testing.
+static void gr_test() {
+ GRSurface** images;
+ int frames;
+ int result = res_create_multi_surface("icon_installing", &frames, &images);
+ if (result < 0) {
+ printf("create surface %d\n", result);
+ gr_exit();
+ return;
+ }
+
+ time_t start = time(NULL);
+ int x;
+ for (x = 0; x <= 1200; ++x) {
+ if (x < 400) {
+ gr_color(0, 0, 0, 255);
+ } else {
+ gr_color(0, (x-400)%128, 0, 255);
+ }
+ gr_clear();
+
+ gr_color(255, 0, 0, 255);
+ GRSurface* frame = images[x%frames];
+ gr_blit(frame, 0, 0, frame->width, frame->height, x, 0);
+
+ gr_color(255, 0, 0, 128);
+ gr_fill(400, 150, 600, 350);
+
+ gr_color(255, 255, 255, 255);
+ gr_text(500, 225, "hello, world!", 0);
+ gr_color(255, 255, 0, 128);
+ gr_text(300+x, 275, "pack my box with five dozen liquor jugs", 1);
+
+ gr_color(0, 0, 255, 128);
+ gr_fill(gr_draw->width - 200 - x, 300, gr_draw->width - x, 500);
+
+ gr_draw = gr_backend->flip(gr_backend);
+ }
+ printf("getting end time\n");
+ time_t end = time(NULL);
+ printf("got end time\n");
+ printf("start %ld end %ld\n", (long)start, (long)end);
+ if (end > start) {
+ printf("%.2f fps\n", ((double)x) / (end-start));
+ }
+}
+#endif
+
+void gr_flip() {
+ gr_draw = gr_backend->flip(gr_backend);
+}
+
+int gr_init(void)
+{
+ gr_init_font();
+
+ gr_backend = open_adf();
+ if (gr_backend) {
+ gr_draw = gr_backend->init(gr_backend);
+ if (!gr_draw) {
+ gr_backend->exit(gr_backend);
+ }
+ }
+
+ if (!gr_draw) {
+ gr_backend = open_drm();
+ gr_draw = gr_backend->init(gr_backend);
+ }
+
+ if (!gr_draw) {
+ gr_backend = open_fbdev();
+ gr_draw = gr_backend->init(gr_backend);
+ if (gr_draw == NULL) {
+ return -1;
+ }
+ }
+
+ overscan_offset_x = gr_draw->width * overscan_percent / 100;
+ overscan_offset_y = gr_draw->height * overscan_percent / 100;
+
+ gr_flip();
+ gr_flip();
+
+ return 0;
+}
+
+void gr_exit(void)
+{
+ gr_backend->exit(gr_backend);
+}
+
+int gr_fb_width(void)
+{
+ return gr_draw->width - 2*overscan_offset_x;
+}
+
+int gr_fb_height(void)
+{
+ return gr_draw->height - 2*overscan_offset_y;
+}
+
+void gr_fb_blank(bool blank)
+{
+ gr_backend->blank(gr_backend, blank);
+}
diff --git a/minui/graphics.h b/minui/graphics.h
new file mode 100644
index 000000000..52968eb10
--- /dev/null
+++ b/minui/graphics.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 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 _GRAPHICS_H_
+#define _GRAPHICS_H_
+
+#include "minui.h"
+
+// TODO: lose the function pointers.
+struct minui_backend {
+ // Initializes the backend and returns a GRSurface* to draw into.
+ GRSurface* (*init)(minui_backend*);
+
+ // Causes the current drawing surface (returned by the most recent
+ // call to flip() or init()) to be displayed, and returns a new
+ // drawing surface.
+ GRSurface* (*flip)(minui_backend*);
+
+ // Blank (or unblank) the screen.
+ void (*blank)(minui_backend*, bool);
+
+ // Device cleanup when drawing is done.
+ void (*exit)(minui_backend*);
+};
+
+minui_backend* open_fbdev();
+minui_backend* open_adf();
+minui_backend* open_drm();
+
+#endif
diff --git a/minui/graphics_adf.cpp b/minui/graphics_adf.cpp
new file mode 100644
index 000000000..5d0867f58
--- /dev/null
+++ b/minui/graphics_adf.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2014 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 <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/cdefs.h>
+#include <sys/mman.h>
+
+#include <adf/adf.h>
+
+#include "graphics.h"
+
+struct adf_surface_pdata {
+ GRSurface base;
+ int fd;
+ __u32 offset;
+ __u32 pitch;
+};
+
+struct adf_pdata {
+ minui_backend base;
+ int intf_fd;
+ adf_id_t eng_id;
+ __u32 format;
+
+ unsigned int current_surface;
+ unsigned int n_surfaces;
+ adf_surface_pdata surfaces[2];
+};
+
+static GRSurface* adf_flip(minui_backend *backend);
+static void adf_blank(minui_backend *backend, bool blank);
+
+static int adf_surface_init(adf_pdata *pdata, drm_mode_modeinfo *mode, adf_surface_pdata *surf) {
+ memset(surf, 0, sizeof(*surf));
+
+ surf->fd = adf_interface_simple_buffer_alloc(pdata->intf_fd, mode->hdisplay,
+ mode->vdisplay, pdata->format, &surf->offset, &surf->pitch);
+ if (surf->fd < 0)
+ return surf->fd;
+
+ surf->base.width = mode->hdisplay;
+ surf->base.height = mode->vdisplay;
+ surf->base.row_bytes = surf->pitch;
+ surf->base.pixel_bytes = (pdata->format == DRM_FORMAT_RGB565) ? 2 : 4;
+
+ surf->base.data = reinterpret_cast<uint8_t*>(mmap(NULL,
+ surf->pitch * surf->base.height, PROT_WRITE,
+ MAP_SHARED, surf->fd, surf->offset));
+ if (surf->base.data == MAP_FAILED) {
+ close(surf->fd);
+ return -errno;
+ }
+
+ return 0;
+}
+
+static int adf_interface_init(adf_pdata *pdata)
+{
+ adf_interface_data intf_data;
+ int ret = 0;
+ int err;
+
+ err = adf_get_interface_data(pdata->intf_fd, &intf_data);
+ if (err < 0)
+ return err;
+
+ err = adf_surface_init(pdata, &intf_data.current_mode, &pdata->surfaces[0]);
+ if (err < 0) {
+ fprintf(stderr, "allocating surface 0 failed: %s\n", strerror(-err));
+ ret = err;
+ goto done;
+ }
+
+ err = adf_surface_init(pdata, &intf_data.current_mode,
+ &pdata->surfaces[1]);
+ if (err < 0) {
+ fprintf(stderr, "allocating surface 1 failed: %s\n", strerror(-err));
+ memset(&pdata->surfaces[1], 0, sizeof(pdata->surfaces[1]));
+ pdata->n_surfaces = 1;
+ } else {
+ pdata->n_surfaces = 2;
+ }
+
+done:
+ adf_free_interface_data(&intf_data);
+ return ret;
+}
+
+static int adf_device_init(adf_pdata *pdata, adf_device *dev)
+{
+ adf_id_t intf_id;
+ int intf_fd;
+ int err;
+
+ err = adf_find_simple_post_configuration(dev, &pdata->format, 1, &intf_id,
+ &pdata->eng_id);
+ if (err < 0)
+ return err;
+
+ err = adf_device_attach(dev, pdata->eng_id, intf_id);
+ if (err < 0 && err != -EALREADY)
+ return err;
+
+ pdata->intf_fd = adf_interface_open(dev, intf_id, O_RDWR);
+ if (pdata->intf_fd < 0)
+ return pdata->intf_fd;
+
+ err = adf_interface_init(pdata);
+ if (err < 0) {
+ close(pdata->intf_fd);
+ pdata->intf_fd = -1;
+ }
+
+ return err;
+}
+
+static GRSurface* adf_init(minui_backend *backend)
+{
+ adf_pdata *pdata = (adf_pdata *)backend;
+ adf_id_t *dev_ids = NULL;
+ ssize_t n_dev_ids, i;
+ GRSurface* ret;
+
+#if defined(RECOVERY_ABGR)
+ pdata->format = DRM_FORMAT_ABGR8888;
+#elif defined(RECOVERY_BGRA)
+ pdata->format = DRM_FORMAT_BGRA8888;
+#elif defined(RECOVERY_RGBX)
+ pdata->format = DRM_FORMAT_RGBX8888;
+#else
+ pdata->format = DRM_FORMAT_RGB565;
+#endif
+
+ n_dev_ids = adf_devices(&dev_ids);
+ if (n_dev_ids == 0) {
+ return NULL;
+ } else if (n_dev_ids < 0) {
+ fprintf(stderr, "enumerating adf devices failed: %s\n",
+ strerror(-n_dev_ids));
+ return NULL;
+ }
+
+ pdata->intf_fd = -1;
+
+ for (i = 0; i < n_dev_ids && pdata->intf_fd < 0; i++) {
+ adf_device dev;
+
+ int err = adf_device_open(dev_ids[i], O_RDWR, &dev);
+ if (err < 0) {
+ fprintf(stderr, "opening adf device %u failed: %s\n", dev_ids[i],
+ strerror(-err));
+ continue;
+ }
+
+ err = adf_device_init(pdata, &dev);
+ if (err < 0)
+ fprintf(stderr, "initializing adf device %u failed: %s\n",
+ dev_ids[i], strerror(-err));
+
+ adf_device_close(&dev);
+ }
+
+ free(dev_ids);
+
+ if (pdata->intf_fd < 0)
+ return NULL;
+
+ ret = adf_flip(backend);
+
+ adf_blank(backend, true);
+ adf_blank(backend, false);
+
+ return ret;
+}
+
+static GRSurface* adf_flip(minui_backend *backend)
+{
+ adf_pdata *pdata = (adf_pdata *)backend;
+ adf_surface_pdata *surf = &pdata->surfaces[pdata->current_surface];
+
+ int fence_fd = adf_interface_simple_post(pdata->intf_fd, pdata->eng_id,
+ surf->base.width, surf->base.height, pdata->format, surf->fd,
+ surf->offset, surf->pitch, -1);
+ if (fence_fd >= 0)
+ close(fence_fd);
+
+ pdata->current_surface = (pdata->current_surface + 1) % pdata->n_surfaces;
+ return &pdata->surfaces[pdata->current_surface].base;
+}
+
+static void adf_blank(minui_backend *backend, bool blank)
+{
+ adf_pdata *pdata = (adf_pdata *)backend;
+ adf_interface_blank(pdata->intf_fd,
+ blank ? DRM_MODE_DPMS_OFF : DRM_MODE_DPMS_ON);
+}
+
+static void adf_surface_destroy(adf_surface_pdata *surf)
+{
+ munmap(surf->base.data, surf->pitch * surf->base.height);
+ close(surf->fd);
+}
+
+static void adf_exit(minui_backend *backend)
+{
+ adf_pdata *pdata = (adf_pdata *)backend;
+ unsigned int i;
+
+ for (i = 0; i < pdata->n_surfaces; i++)
+ adf_surface_destroy(&pdata->surfaces[i]);
+ if (pdata->intf_fd >= 0)
+ close(pdata->intf_fd);
+ free(pdata);
+}
+
+minui_backend *open_adf()
+{
+ adf_pdata* pdata = reinterpret_cast<adf_pdata*>(calloc(1, sizeof(*pdata)));
+ if (!pdata) {
+ perror("allocating adf backend failed");
+ return NULL;
+ }
+
+ pdata->base.init = adf_init;
+ pdata->base.flip = adf_flip;
+ pdata->base.blank = adf_blank;
+ pdata->base.exit = adf_exit;
+ return &pdata->base;
+}
diff --git a/minui/graphics_drm.cpp b/minui/graphics_drm.cpp
new file mode 100644
index 000000000..03e33b775
--- /dev/null
+++ b/minui/graphics_drm.cpp
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2015 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 <drm_fourcc.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include "minui.h"
+#include "graphics.h"
+
+#define ARRAY_SIZE(A) (sizeof(A)/sizeof(*(A)))
+
+struct drm_surface {
+ GRSurface base;
+ uint32_t fb_id;
+ uint32_t handle;
+};
+
+static drm_surface *drm_surfaces[2];
+static int current_buffer;
+
+static drmModeCrtc *main_monitor_crtc;
+static drmModeConnector *main_monitor_connector;
+
+static int drm_fd = -1;
+
+static void drm_disable_crtc(int drm_fd, drmModeCrtc *crtc) {
+ if (crtc) {
+ drmModeSetCrtc(drm_fd, crtc->crtc_id,
+ 0, // fb_id
+ 0, 0, // x,y
+ NULL, // connectors
+ 0, // connector_count
+ NULL); // mode
+ }
+}
+
+static void drm_enable_crtc(int drm_fd, drmModeCrtc *crtc,
+ struct drm_surface *surface) {
+ int32_t ret;
+
+ ret = drmModeSetCrtc(drm_fd, crtc->crtc_id,
+ surface->fb_id,
+ 0, 0, // x,y
+ &main_monitor_connector->connector_id,
+ 1, // connector_count
+ &main_monitor_crtc->mode);
+
+ if (ret)
+ printf("drmModeSetCrtc failed ret=%d\n", ret);
+}
+
+static void drm_blank(minui_backend* backend __unused, bool blank) {
+ if (blank)
+ drm_disable_crtc(drm_fd, main_monitor_crtc);
+ else
+ drm_enable_crtc(drm_fd, main_monitor_crtc,
+ drm_surfaces[current_buffer]);
+}
+
+static void drm_destroy_surface(struct drm_surface *surface) {
+ struct drm_gem_close gem_close;
+ int ret;
+
+ if(!surface)
+ return;
+
+ if (surface->base.data)
+ munmap(surface->base.data,
+ surface->base.row_bytes * surface->base.height);
+
+ if (surface->fb_id) {
+ ret = drmModeRmFB(drm_fd, surface->fb_id);
+ if (ret)
+ printf("drmModeRmFB failed ret=%d\n", ret);
+ }
+
+ if (surface->handle) {
+ memset(&gem_close, 0, sizeof(gem_close));
+ gem_close.handle = surface->handle;
+
+ ret = drmIoctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+ if (ret)
+ printf("DRM_IOCTL_GEM_CLOSE failed ret=%d\n", ret);
+ }
+
+ free(surface);
+}
+
+static int drm_format_to_bpp(uint32_t format) {
+ switch(format) {
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_BGRA8888:
+ case DRM_FORMAT_RGBX8888:
+ case DRM_FORMAT_BGRX8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_XRGB8888:
+ return 32;
+ case DRM_FORMAT_RGB565:
+ return 16;
+ default:
+ printf("Unknown format %d\n", format);
+ return 32;
+ }
+}
+
+static drm_surface *drm_create_surface(int width, int height) {
+ struct drm_surface *surface;
+ struct drm_mode_create_dumb create_dumb;
+ uint32_t format;
+ int ret;
+
+ surface = (struct drm_surface*)calloc(1, sizeof(*surface));
+ if (!surface) {
+ printf("Can't allocate memory\n");
+ return NULL;
+ }
+
+#if defined(RECOVERY_ABGR)
+ format = DRM_FORMAT_RGBA8888;
+#elif defined(RECOVERY_BGRA)
+ format = DRM_FORMAT_ARGB8888;
+#elif defined(RECOVERY_RGBX)
+ format = DRM_FORMAT_XBGR8888;
+#else
+ format = DRM_FORMAT_RGB565;
+#endif
+
+ memset(&create_dumb, 0, sizeof(create_dumb));
+ create_dumb.height = height;
+ create_dumb.width = width;
+ create_dumb.bpp = drm_format_to_bpp(format);
+ create_dumb.flags = 0;
+
+ ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
+ if (ret) {
+ printf("DRM_IOCTL_MODE_CREATE_DUMB failed ret=%d\n",ret);
+ drm_destroy_surface(surface);
+ return NULL;
+ }
+ surface->handle = create_dumb.handle;
+
+ uint32_t handles[4], pitches[4], offsets[4];
+
+ handles[0] = surface->handle;
+ pitches[0] = create_dumb.pitch;
+ offsets[0] = 0;
+
+ ret = drmModeAddFB2(drm_fd, width, height,
+ format, handles, pitches, offsets,
+ &(surface->fb_id), 0);
+ if (ret) {
+ printf("drmModeAddFB2 failed ret=%d\n", ret);
+ drm_destroy_surface(surface);
+ return NULL;
+ }
+
+ struct drm_mode_map_dumb map_dumb;
+ memset(&map_dumb, 0, sizeof(map_dumb));
+ map_dumb.handle = create_dumb.handle;
+ ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
+ if (ret) {
+ printf("DRM_IOCTL_MODE_MAP_DUMB failed ret=%d\n",ret);
+ drm_destroy_surface(surface);
+ return NULL;;
+ }
+
+ surface->base.height = height;
+ surface->base.width = width;
+ surface->base.row_bytes = create_dumb.pitch;
+ surface->base.pixel_bytes = create_dumb.bpp / 8;
+ surface->base.data = (unsigned char*)
+ mmap(NULL,
+ surface->base.height * surface->base.row_bytes,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ drm_fd, map_dumb.offset);
+ if (surface->base.data == MAP_FAILED) {
+ perror("mmap() failed");
+ drm_destroy_surface(surface);
+ return NULL;
+ }
+
+ return surface;
+}
+
+static drmModeCrtc *find_crtc_for_connector(int fd,
+ drmModeRes *resources,
+ drmModeConnector *connector) {
+ int i, j;
+ drmModeEncoder *encoder;
+ int32_t crtc;
+
+ /*
+ * Find the encoder. If we already have one, just use it.
+ */
+ if (connector->encoder_id)
+ encoder = drmModeGetEncoder(fd, connector->encoder_id);
+ else
+ encoder = NULL;
+
+ if (encoder && encoder->crtc_id) {
+ crtc = encoder->crtc_id;
+ drmModeFreeEncoder(encoder);
+ return drmModeGetCrtc(fd, crtc);
+ }
+
+ /*
+ * Didn't find anything, try to find a crtc and encoder combo.
+ */
+ crtc = -1;
+ for (i = 0; i < connector->count_encoders; i++) {
+ encoder = drmModeGetEncoder(fd, connector->encoders[i]);
+
+ if (encoder) {
+ for (j = 0; j < resources->count_crtcs; j++) {
+ if (!(encoder->possible_crtcs & (1 << j)))
+ continue;
+ crtc = resources->crtcs[j];
+ break;
+ }
+ if (crtc >= 0) {
+ drmModeFreeEncoder(encoder);
+ return drmModeGetCrtc(fd, crtc);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static drmModeConnector *find_used_connector_by_type(int fd,
+ drmModeRes *resources,
+ unsigned type) {
+ int i;
+ for (i = 0; i < resources->count_connectors; i++) {
+ drmModeConnector *connector;
+
+ connector = drmModeGetConnector(fd, resources->connectors[i]);
+ if (connector) {
+ if ((connector->connector_type == type) &&
+ (connector->connection == DRM_MODE_CONNECTED) &&
+ (connector->count_modes > 0))
+ return connector;
+
+ drmModeFreeConnector(connector);
+ }
+ }
+ return NULL;
+}
+
+static drmModeConnector *find_first_connected_connector(int fd,
+ drmModeRes *resources) {
+ int i;
+ for (i = 0; i < resources->count_connectors; i++) {
+ drmModeConnector *connector;
+
+ connector = drmModeGetConnector(fd, resources->connectors[i]);
+ if (connector) {
+ if ((connector->count_modes > 0) &&
+ (connector->connection == DRM_MODE_CONNECTED))
+ return connector;
+
+ drmModeFreeConnector(connector);
+ }
+ }
+ return NULL;
+}
+
+static drmModeConnector *find_main_monitor(int fd, drmModeRes *resources,
+ uint32_t *mode_index) {
+ unsigned i = 0;
+ int modes;
+ /* Look for LVDS/eDP/DSI connectors. Those are the main screens. */
+ unsigned kConnectorPriority[] = {
+ DRM_MODE_CONNECTOR_LVDS,
+ DRM_MODE_CONNECTOR_eDP,
+ DRM_MODE_CONNECTOR_DSI,
+ };
+
+ drmModeConnector *main_monitor_connector = NULL;
+ do {
+ main_monitor_connector = find_used_connector_by_type(fd,
+ resources,
+ kConnectorPriority[i]);
+ i++;
+ } while (!main_monitor_connector && i < ARRAY_SIZE(kConnectorPriority));
+
+ /* If we didn't find a connector, grab the first one that is connected. */
+ if (!main_monitor_connector)
+ main_monitor_connector =
+ find_first_connected_connector(fd, resources);
+
+ /* If we still didn't find a connector, give up and return. */
+ if (!main_monitor_connector)
+ return NULL;
+
+ *mode_index = 0;
+ for (modes = 0; modes < main_monitor_connector->count_modes; modes++) {
+ if (main_monitor_connector->modes[modes].type &
+ DRM_MODE_TYPE_PREFERRED) {
+ *mode_index = modes;
+ break;
+ }
+ }
+
+ return main_monitor_connector;
+}
+
+static void disable_non_main_crtcs(int fd,
+ drmModeRes *resources,
+ drmModeCrtc* main_crtc) {
+ int i;
+ drmModeCrtc* crtc;
+
+ for (i = 0; i < resources->count_connectors; i++) {
+ drmModeConnector *connector;
+
+ connector = drmModeGetConnector(fd, resources->connectors[i]);
+ crtc = find_crtc_for_connector(fd, resources, connector);
+ if (crtc->crtc_id != main_crtc->crtc_id)
+ drm_disable_crtc(fd, crtc);
+ drmModeFreeCrtc(crtc);
+ }
+}
+
+static GRSurface* drm_init(minui_backend* backend __unused) {
+ drmModeRes *res = NULL;
+ uint32_t selected_mode;
+ char *dev_name;
+ int width, height;
+ int ret, i;
+
+ /* Consider DRM devices in order. */
+ for (i = 0; i < DRM_MAX_MINOR; i++) {
+ uint64_t cap = 0;
+
+ ret = asprintf(&dev_name, DRM_DEV_NAME, DRM_DIR_NAME, i);
+ if (ret < 0)
+ continue;
+
+ drm_fd = open(dev_name, O_RDWR, 0);
+ free(dev_name);
+ if (drm_fd < 0)
+ continue;
+
+ /* We need dumb buffers. */
+ ret = drmGetCap(drm_fd, DRM_CAP_DUMB_BUFFER, &cap);
+ if (ret || cap == 0) {
+ close(drm_fd);
+ continue;
+ }
+
+ res = drmModeGetResources(drm_fd);
+ if (!res) {
+ close(drm_fd);
+ continue;
+ }
+
+ /* Use this device if it has at least one connected monitor. */
+ if (res->count_crtcs > 0 && res->count_connectors > 0)
+ if (find_first_connected_connector(drm_fd, res))
+ break;
+
+ drmModeFreeResources(res);
+ close(drm_fd);
+ res = NULL;
+ }
+
+ if (drm_fd < 0 || res == NULL) {
+ perror("cannot find/open a drm device");
+ return NULL;
+ }
+
+ main_monitor_connector = find_main_monitor(drm_fd,
+ res, &selected_mode);
+
+ if (!main_monitor_connector) {
+ printf("main_monitor_connector not found\n");
+ drmModeFreeResources(res);
+ close(drm_fd);
+ return NULL;
+ }
+
+ main_monitor_crtc = find_crtc_for_connector(drm_fd, res,
+ main_monitor_connector);
+
+ if (!main_monitor_crtc) {
+ printf("main_monitor_crtc not found\n");
+ drmModeFreeResources(res);
+ close(drm_fd);
+ return NULL;
+ }
+
+ disable_non_main_crtcs(drm_fd,
+ res, main_monitor_crtc);
+
+ main_monitor_crtc->mode = main_monitor_connector->modes[selected_mode];
+
+ width = main_monitor_crtc->mode.hdisplay;
+ height = main_monitor_crtc->mode.vdisplay;
+
+ drmModeFreeResources(res);
+
+ drm_surfaces[0] = drm_create_surface(width, height);
+ drm_surfaces[1] = drm_create_surface(width, height);
+ if (!drm_surfaces[0] || !drm_surfaces[1]) {
+ drm_destroy_surface(drm_surfaces[0]);
+ drm_destroy_surface(drm_surfaces[1]);
+ drmModeFreeResources(res);
+ close(drm_fd);
+ return NULL;
+ }
+
+ current_buffer = 0;
+
+ drm_enable_crtc(drm_fd, main_monitor_crtc, drm_surfaces[1]);
+
+ return &(drm_surfaces[0]->base);
+}
+
+static GRSurface* drm_flip(minui_backend* backend __unused) {
+ int ret;
+
+ ret = drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id,
+ drm_surfaces[current_buffer]->fb_id, 0, NULL);
+ if (ret < 0) {
+ printf("drmModePageFlip failed ret=%d\n", ret);
+ return NULL;
+ }
+ current_buffer = 1 - current_buffer;
+ return &(drm_surfaces[current_buffer]->base);
+}
+
+static void drm_exit(minui_backend* backend __unused) {
+ drm_disable_crtc(drm_fd, main_monitor_crtc);
+ drm_destroy_surface(drm_surfaces[0]);
+ drm_destroy_surface(drm_surfaces[1]);
+ drmModeFreeCrtc(main_monitor_crtc);
+ drmModeFreeConnector(main_monitor_connector);
+ close(drm_fd);
+ drm_fd = -1;
+}
+
+static minui_backend drm_backend = {
+ .init = drm_init,
+ .flip = drm_flip,
+ .blank = drm_blank,
+ .exit = drm_exit,
+};
+
+minui_backend* open_drm() {
+ return &drm_backend;
+}
diff --git a/minui/graphics_fbdev.cpp b/minui/graphics_fbdev.cpp
new file mode 100644
index 000000000..512a7d0e7
--- /dev/null
+++ b/minui/graphics_fbdev.cpp
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2014 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 <string.h>
+#include <unistd.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include <linux/fb.h>
+#include <linux/kd.h>
+
+#include "minui.h"
+#include "graphics.h"
+
+static GRSurface* fbdev_init(minui_backend*);
+static GRSurface* fbdev_flip(minui_backend*);
+static void fbdev_blank(minui_backend*, bool);
+static void fbdev_exit(minui_backend*);
+
+static GRSurface gr_framebuffer[2];
+static bool double_buffered;
+static GRSurface* gr_draw = NULL;
+static int displayed_buffer;
+
+static fb_var_screeninfo vi;
+static int fb_fd = -1;
+
+static minui_backend my_backend = {
+ .init = fbdev_init,
+ .flip = fbdev_flip,
+ .blank = fbdev_blank,
+ .exit = fbdev_exit,
+};
+
+minui_backend* open_fbdev() {
+ return &my_backend;
+}
+
+static void fbdev_blank(minui_backend* backend __unused, bool blank)
+{
+#if defined(TW_NO_SCREEN_BLANK) && defined(TW_BRIGHTNESS_PATH) && defined(TW_MAX_BRIGHTNESS)
+ int fd;
+ char brightness[4];
+ snprintf(brightness, 4, "%03d", TW_MAX_BRIGHTNESS/2);
+
+ fd = open(TW_BRIGHTNESS_PATH, O_RDWR);
+ if (fd < 0) {
+ perror("cannot open LCD backlight");
+ return;
+ }
+ write(fd, blank ? "000" : brightness, 3);
+ close(fd);
+#else
+ int ret;
+
+ ret = ioctl(fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
+ if (ret < 0)
+ perror("ioctl(): blank");
+#endif
+}
+
+static void set_displayed_framebuffer(unsigned n)
+{
+ if (n > 1 || !double_buffered) return;
+
+ vi.yres_virtual = gr_framebuffer[0].height * 2;
+ vi.yoffset = n * gr_framebuffer[0].height;
+ vi.bits_per_pixel = gr_framebuffer[0].pixel_bytes * 8;
+ if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
+ perror("active fb swap failed");
+ }
+ displayed_buffer = n;
+}
+
+static GRSurface* fbdev_init(minui_backend* backend) {
+ int fd = open("/dev/graphics/fb0", O_RDWR);
+ if (fd == -1) {
+ perror("cannot open fb0");
+ return NULL;
+ }
+
+ fb_fix_screeninfo fi;
+ if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
+ perror("failed to get fb0 info");
+ close(fd);
+ return NULL;
+ }
+
+ if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
+ perror("failed to get fb0 info");
+ close(fd);
+ return NULL;
+ }
+
+ // We print this out for informational purposes only, but
+ // throughout we assume that the framebuffer device uses an RGBX
+ // pixel format. This is the case for every development device I
+ // have access to. For some of those devices (eg, hammerhead aka
+ // Nexus 5), FBIOGET_VSCREENINFO *reports* that it wants a
+ // different format (XBGR) but actually produces the correct
+ // results on the display when you write RGBX.
+ //
+ // If you have a device that actually *needs* another pixel format
+ // (ie, BGRX, or 565), patches welcome...
+
+ printf("fb0 reports (possibly inaccurate):\n"
+ " vi.bits_per_pixel = %d\n"
+ " vi.red.offset = %3d .length = %3d\n"
+ " vi.green.offset = %3d .length = %3d\n"
+ " vi.blue.offset = %3d .length = %3d\n",
+ vi.bits_per_pixel,
+ vi.red.offset, vi.red.length,
+ vi.green.offset, vi.green.length,
+ vi.blue.offset, vi.blue.length);
+
+ void* 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 NULL;
+ }
+
+ memset(bits, 0, fi.smem_len);
+
+ gr_framebuffer[0].width = vi.xres;
+ gr_framebuffer[0].height = vi.yres;
+ gr_framebuffer[0].row_bytes = fi.line_length;
+ gr_framebuffer[0].pixel_bytes = vi.bits_per_pixel / 8;
+ gr_framebuffer[0].data = reinterpret_cast<uint8_t*>(bits);
+ memset(gr_framebuffer[0].data, 0, gr_framebuffer[0].height * gr_framebuffer[0].row_bytes);
+
+ /* check if we can use double buffering */
+ if (vi.yres * fi.line_length * 2 <= fi.smem_len) {
+ double_buffered = true;
+
+ memcpy(gr_framebuffer+1, gr_framebuffer, sizeof(GRSurface));
+ gr_framebuffer[1].data = gr_framebuffer[0].data +
+ gr_framebuffer[0].height * gr_framebuffer[0].row_bytes;
+
+ gr_draw = gr_framebuffer+1;
+
+ } else {
+ double_buffered = false;
+
+ // Without double-buffering, we allocate RAM for a buffer to
+ // draw in, and then "flipping" the buffer consists of a
+ // memcpy from the buffer we allocated to the framebuffer.
+
+ gr_draw = (GRSurface*) malloc(sizeof(GRSurface));
+ memcpy(gr_draw, gr_framebuffer, sizeof(GRSurface));
+ gr_draw->data = (unsigned char*) malloc(gr_draw->height * gr_draw->row_bytes);
+ if (!gr_draw->data) {
+ perror("failed to allocate in-memory surface");
+ return NULL;
+ }
+ }
+
+ memset(gr_draw->data, 0, gr_draw->height * gr_draw->row_bytes);
+ fb_fd = fd;
+ set_displayed_framebuffer(0);
+
+ printf("framebuffer: %d (%d x %d)\n", fb_fd, gr_draw->width, gr_draw->height);
+
+ fbdev_blank(backend, true);
+ fbdev_blank(backend, false);
+
+ return gr_draw;
+}
+
+static GRSurface* fbdev_flip(minui_backend* backend __unused) {
+ if (double_buffered) {
+#if defined(RECOVERY_BGRA)
+ // In case of BGRA, do some byte swapping
+ unsigned int idx;
+ unsigned char tmp;
+ unsigned char* ucfb_vaddr = (unsigned char*)gr_draw->data;
+ for (idx = 0 ; idx < (gr_draw->height * gr_draw->row_bytes);
+ idx += 4) {
+ tmp = ucfb_vaddr[idx];
+ ucfb_vaddr[idx ] = ucfb_vaddr[idx + 2];
+ ucfb_vaddr[idx + 2] = tmp;
+ }
+#endif
+ // Change gr_draw to point to the buffer currently displayed,
+ // then flip the driver so we're displaying the other buffer
+ // instead.
+ gr_draw = gr_framebuffer + displayed_buffer;
+ set_displayed_framebuffer(1-displayed_buffer);
+ } else {
+ // Copy from the in-memory surface to the framebuffer.
+ memcpy(gr_framebuffer[0].data, gr_draw->data,
+ gr_draw->height * gr_draw->row_bytes);
+ }
+ return gr_draw;
+}
+
+static void fbdev_exit(minui_backend* backend __unused) {
+ close(fb_fd);
+ fb_fd = -1;
+
+ if (!double_buffered && gr_draw) {
+ free(gr_draw->data);
+ free(gr_draw);
+ }
+ gr_draw = NULL;
+}
diff --git a/minui/minui.h b/minui/minui.h
index 4c629c1b5..18173b198 100644
--- a/minui/minui.h
+++ b/minui/minui.h
@@ -17,6 +17,116 @@
#ifndef _MINUI_H_
#define _MINUI_H_
+#ifndef TW_USE_OLD_MINUI_H
+
+#include <sys/types.h>
+
+#include <functional>
+
+//
+// Graphics.
+//
+
+struct GRSurface {
+ int width;
+ int height;
+ int row_bytes;
+ int pixel_bytes;
+ unsigned char* data;
+};
+
+int gr_init();
+void gr_exit();
+
+int gr_fb_width();
+int gr_fb_height();
+
+void gr_flip();
+void gr_fb_blank(bool blank);
+
+void gr_clear(); // clear entire surface to current color
+void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+void gr_fill(int x1, int y1, int x2, int y2);
+void gr_text(int x, int y, const char *s, bool bold);
+void gr_texticon(int x, int y, GRSurface* icon);
+int gr_measure(const char *s);
+void gr_font_size(int *x, int *y);
+
+void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy);
+unsigned int gr_get_width(GRSurface* surface);
+unsigned int gr_get_height(GRSurface* surface);
+
+//
+// Input events.
+//
+
+struct input_event;
+
+// TODO: move these over to std::function.
+typedef int (*ev_callback)(int fd, uint32_t epevents, void* data);
+typedef int (*ev_set_key_callback)(int code, int value, void* data);
+
+int ev_init(ev_callback input_cb, void* data);
+void ev_exit();
+int ev_add_fd(int fd, ev_callback cb, void* data);
+void ev_iterate_available_keys(std::function<void(int)> f);
+int ev_sync_key_state(ev_set_key_callback set_key_cb, void* data);
+
+// 'timeout' has the same semantics as poll(2).
+// 0 : don't block
+// < 0 : block forever
+// > 0 : block for 'timeout' milliseconds
+int ev_wait(int timeout);
+
+int ev_get_input(int fd, uint32_t epevents, input_event* ev);
+void ev_dispatch();
+int ev_get_epollfd();
+
+//
+// Resources
+//
+
+// res_create_*_surface() functions return 0 if no error, else
+// negative.
+//
+// A "display" surface is one that is intended to be drawn to the
+// screen with gr_blit(). An "alpha" surface is a grayscale image
+// interpreted as an alpha mask used to render text in the current
+// color (with gr_text() or gr_texticon()).
+//
+// All these functions load PNG images from "/res/images/${name}.png".
+
+// Load a single display surface from a PNG image.
+int res_create_display_surface(const char* name, GRSurface** pSurface);
+
+// Load an array of display surfaces from a single PNG image. The PNG
+// should have a 'Frames' text chunk whose value is the number of
+// frames this image represents. The pixel data itself is interlaced
+// by row.
+int res_create_multi_display_surface(const char* name,
+ int* frames, GRSurface*** pSurface);
+
+// Load a single alpha surface from a grayscale PNG image.
+int res_create_alpha_surface(const char* name, GRSurface** pSurface);
+
+// Load part of a grayscale PNG image that is the first match for the
+// given locale. The image is expected to be a composite of multiple
+// translations of the same text, with special added rows that encode
+// the subimages' size and intended locale in the pixel data. See
+// development/tools/recovery_l10n for an app that will generate these
+// specialized images from Android resources.
+int res_create_localized_alpha_surface(const char* name, const char* locale,
+ GRSurface** pSurface);
+
+// Free a surface allocated by any of the res_create_*_surface()
+// functions.
+void res_free_surface(GRSurface* surface);
+
+#else //ifndef TW_USE_OLD_MINUI_H
+
+// This the old minui.old/minui.h for compatibility with building TWRP
+// in pre 6.0 trees.
+
#include <stdbool.h>
#ifdef __cplusplus
@@ -102,4 +212,5 @@ void gr_clear();
}
#endif
-#endif
+#endif // ifndef TW_USE_OLD_MINUI_H
+#endif // ifndef _MINUI_H_
diff --git a/minui/resources.cpp b/minui/resources.cpp
new file mode 100644
index 000000000..5e4789277
--- /dev/null
+++ b/minui/resources.cpp
@@ -0,0 +1,459 @@
+/*
+ * 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 <string.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 <png.h>
+
+#include "minui.h"
+
+extern char* locale;
+
+#define SURFACE_DATA_ALIGNMENT 8
+
+static GRSurface* malloc_surface(size_t data_size) {
+ size_t size = sizeof(GRSurface) + data_size + SURFACE_DATA_ALIGNMENT;
+ unsigned char* temp = reinterpret_cast<unsigned char*>(malloc(size));
+ if (temp == NULL) return NULL;
+ GRSurface* surface = reinterpret_cast<GRSurface*>(temp);
+ surface->data = temp + sizeof(GRSurface) +
+ (SURFACE_DATA_ALIGNMENT - (sizeof(GRSurface) % 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) {
+ char resPath[256];
+ unsigned char header[8];
+ int result = 0;
+ int color_type, bit_depth;
+ size_t bytesRead;
+
+ snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.png", name);
+ resPath[sizeof(resPath)-1] = '\0';
+ FILE* fp = fopen(resPath, "rb");
+ if (fp == NULL) {
+ result = -1;
+ goto exit;
+ }
+
+ 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);
+
+ 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;
+ }
+
+ 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 GRSurface* sufficient for storing an image of
+// the indicated size in the framebuffer pixel format.
+static GRSurface* init_display_surface(png_uint_32 width, png_uint_32 height) {
+ GRSurface* surface = malloc_surface(width * height * 4);
+ if (surface == NULL) return NULL;
+
+ surface->width = width;
+ surface->height = height;
+ surface->row_bytes = width * 4;
+ surface->pixel_bytes = 4;
+
+ 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_display_surface(const char* name, GRSurface** pSurface) {
+ GRSurface* surface = NULL;
+ int result = 0;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_uint_32 width, height;
+ png_byte channels;
+ unsigned char* p_row;
+ unsigned int y;
+
+ *pSurface = NULL;
+
+ result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
+ if (result < 0) return result;
+
+ surface = init_display_surface(width, height);
+ if (surface == NULL) {
+ result = -8;
+ goto exit;
+ }
+
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+ png_set_bgr(png_ptr);
+#endif
+
+ p_row = reinterpret_cast<unsigned char*>(malloc(width * 4));
+ for (y = 0; y < height; ++y) {
+ png_read_row(png_ptr, p_row, NULL);
+ transform_rgb_to_draw(p_row, surface->data + y * surface->row_bytes, channels, width);
+ }
+ free(p_row);
+
+ *pSurface = surface;
+
+ exit:
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ if (result < 0 && surface != NULL) free(surface);
+ return result;
+}
+
+int res_create_multi_display_surface(const char* name, int* frames, GRSurface*** pSurface) {
+ GRSurface** surface = NULL;
+ int result = 0;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_uint_32 width, height;
+ png_byte channels;
+ int i;
+ png_textp text;
+ int num_text;
+ unsigned char* p_row;
+ unsigned int y;
+
+ *pSurface = NULL;
+ *frames = -1;
+
+ result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
+ if (result < 0) return result;
+
+ *frames = 1;
+ if (png_get_text(png_ptr, info_ptr, &text, &num_text)) {
+ for (i = 0; i < num_text; ++i) {
+ if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) {
+ *frames = atoi(text[i].text);
+ break;
+ }
+ }
+ printf(" found frames = %d\n", *frames);
+ }
+
+ if (height % *frames != 0) {
+ printf("bad height (%d) for frame count (%d)\n", height, *frames);
+ result = -9;
+ goto exit;
+ }
+
+ surface = reinterpret_cast<GRSurface**>(malloc(*frames * sizeof(GRSurface*)));
+ if (surface == NULL) {
+ result = -8;
+ goto exit;
+ }
+ for (i = 0; i < *frames; ++i) {
+ surface[i] = init_display_surface(width, height / *frames);
+ if (surface[i] == NULL) {
+ result = -8;
+ goto exit;
+ }
+ }
+
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+ png_set_bgr(png_ptr);
+#endif
+
+ p_row = reinterpret_cast<unsigned char*>(malloc(width * 4));
+ for (y = 0; y < height; ++y) {
+ png_read_row(png_ptr, p_row, NULL);
+ int frame = y % *frames;
+ unsigned char* out_row = surface[frame]->data +
+ (y / *frames) * surface[frame]->row_bytes;
+ transform_rgb_to_draw(p_row, out_row, channels, width);
+ }
+ free(p_row);
+
+ *pSurface = reinterpret_cast<GRSurface**>(surface);
+
+exit:
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+
+ if (result < 0) {
+ if (surface) {
+ for (i = 0; i < *frames; ++i) {
+ if (surface[i]) free(surface[i]);
+ }
+ free(surface);
+ }
+ }
+ return result;
+}
+
+int res_create_alpha_surface(const char* name, GRSurface** pSurface) {
+ GRSurface* surface = NULL;
+ int result = 0;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_uint_32 width, height;
+ png_byte channels;
+
+ *pSurface = NULL;
+
+ result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
+ if (result < 0) return result;
+
+ if (channels != 1) {
+ result = -7;
+ goto exit;
+ }
+
+ surface = malloc_surface(width * height);
+ if (surface == NULL) {
+ result = -8;
+ goto exit;
+ }
+ surface->width = width;
+ surface->height = height;
+ surface->row_bytes = width;
+ surface->pixel_bytes = 1;
+
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+ png_set_bgr(png_ptr);
+#endif
+
+ unsigned char* p_row;
+ unsigned int y;
+ for (y = 0; y < height; ++y) {
+ p_row = surface->data + y * surface->row_bytes;
+ png_read_row(png_ptr, p_row, NULL);
+ }
+
+ *pSurface = surface;
+
+ exit:
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ if (result < 0 && surface != NULL) free(surface);
+ return result;
+}
+
+static int matches_locale(const char* loc, const char* locale) {
+ if (locale == NULL) return 0;
+
+ if (strcmp(loc, locale) == 0) return 1;
+
+ // if loc does *not* have an underscore, and it matches the start
+ // of locale, and the next character in locale *is* an underscore,
+ // that's a match. For instance, loc == "en" matches locale ==
+ // "en_US".
+
+ int i;
+ for (i = 0; loc[i] != 0 && loc[i] != '_'; ++i);
+ if (loc[i] == '_') return 0;
+
+ return (strncmp(locale, loc, i) == 0 && locale[i] == '_');
+}
+
+int res_create_localized_alpha_surface(const char* name,
+ const char* locale,
+ GRSurface** pSurface) {
+ GRSurface* surface = NULL;
+ int result = 0;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_uint_32 width, height;
+ png_byte channels;
+ unsigned char* row;
+ png_uint_32 y;
+
+ *pSurface = NULL;
+
+ if (locale == NULL) {
+ surface = malloc_surface(0);
+ surface->width = 0;
+ surface->height = 0;
+ surface->row_bytes = 0;
+ surface->pixel_bytes = 1;
+ goto exit;
+ }
+
+ result = open_png(name, &png_ptr, &info_ptr, &width, &height, &channels);
+ if (result < 0) return result;
+
+ if (channels != 1) {
+ result = -7;
+ goto exit;
+ }
+
+ row = reinterpret_cast<unsigned char*>(malloc(width));
+ for (y = 0; y < height; ++y) {
+ png_read_row(png_ptr, row, NULL);
+ int w = (row[1] << 8) | row[0];
+ int h = (row[3] << 8) | row[2];
+ int len = row[4];
+ char* loc = (char*)row+5;
+
+ if (y+1+h >= height || matches_locale(loc, locale)) {
+ printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y);
+
+ surface = malloc_surface(w*h);
+ if (surface == NULL) {
+ result = -8;
+ goto exit;
+ }
+ surface->width = w;
+ surface->height = h;
+ surface->row_bytes = w;
+ surface->pixel_bytes = 1;
+
+ int i;
+ for (i = 0; i < h; ++i, ++y) {
+ png_read_row(png_ptr, row, NULL);
+ memcpy(surface->data + i*w, row, w);
+ }
+
+ *pSurface = reinterpret_cast<GRSurface*>(surface);
+ break;
+ } else {
+ int i;
+ for (i = 0; i < h; ++i, ++y) {
+ png_read_row(png_ptr, row, NULL);
+ }
+ }
+ }
+
+exit:
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ if (result < 0 && surface != NULL) free(surface);
+ return result;
+}
+
+void res_free_surface(GRSurface* surface) {
+ free(surface);
+}
diff --git a/minuitwrp/Android.mk b/minuitwrp/Android.mk
index 76b4024cc..2f30343d0 100644
--- a/minuitwrp/Android.mk
+++ b/minuitwrp/Android.mk
@@ -154,7 +154,7 @@ endif
LOCAL_CFLAGS += -DTWRES=\"$(TWRES_PATH)\"
LOCAL_SHARED_LIBRARIES += libz libc libcutils libjpeg libpng
-LOCAL_STATIC_LIBRARIES += libpixelflinger_static
+LOCAL_STATIC_LIBRARIES += libpixelflinger_twrp
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := libminuitwrp
diff --git a/minuitwrp/events.c b/minuitwrp/events.c
index 1d2af6b7c..4e10e72fd 100644
--- a/minuitwrp/events.c
+++ b/minuitwrp/events.c
@@ -24,6 +24,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
#include "../common.h"
diff --git a/minuitwrp/graphics.c b/minuitwrp/graphics.c
index 04c41fb54..6dfbc23b5 100644
--- a/minuitwrp/graphics.c
+++ b/minuitwrp/graphics.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
+#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
diff --git a/minuitwrp/resources.c b/minuitwrp/resources.c
index 3e3375d11..0e124608e 100644
--- a/minuitwrp/resources.c
+++ b/minuitwrp/resources.c
@@ -23,6 +23,7 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
+#include <string.h>
#include <linux/fb.h>
#include <linux/kd.h>