diff --git a/minuitwrp/graphics.cpp b/minuitwrp/graphics.cpp
new file mode 100644
index 0000000..47325d0
--- /dev/null
+++ b/minuitwrp/graphics.cpp
@@ -0,0 +1,416 @@
+/*
+ * 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 <pixelflinger/pixelflinger.h>
+#include "../gui/placement.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 unsigned char rgb_555[2];
+static unsigned char gr_current_r5 = 31;
+static unsigned char gr_current_g5 = 63;
+static unsigned char gr_current_b5 = 31;
+
+GRSurface* gr_draw = NULL;
+
+static GGLContext *gr_context = 0;
+GGLSurface gr_mem_surface;
+static int gr_is_curr_clr_opaque = 0;
+
+static bool outside(int x, int y)
+{
+    return x < 0 || x >= gr_draw->width || y < 0 || y >= gr_draw->height;
+}
+
+int gr_textEx_scaleW(int x, int y, const char *s, void* pFont, int max_width, int placement, int scale)
+{
+    GGLContext *gl = gr_context;
+    void* vfont = pFont;
+    GRFont *font = (GRFont*) pFont;
+    unsigned off;
+    unsigned cwidth;
+    int y_scale = 0, measured_width, measured_height, ret, new_height;
+
+    if (!s || strlen(s) == 0 || !font)
+        return 0;
+
+    measured_height = gr_ttf_getMaxFontHeight(font);
+
+    if (scale) {
+        measured_width = gr_ttf_measureEx(s, vfont);
+        if (measured_width > max_width) {
+            // Adjust font size down until the text fits
+            void *new_font = gr_ttf_scaleFont(vfont, max_width, measured_width);
+            if (!new_font) {
+                printf("gr_textEx_scaleW new_font is NULL\n");
+                return 0;
+            }
+            measured_width = gr_ttf_measureEx(s, new_font);
+            // These next 2 lines adjust the y point based on the new font's height
+            new_height = gr_ttf_getMaxFontHeight(new_font);
+            y_scale = (measured_height - new_height) / 2;
+            vfont = new_font;
+        }
+    } else
+        measured_width = gr_ttf_measureEx(s, vfont);
+
+    int x_adj = measured_width;
+    if (measured_width > max_width)
+        x_adj = max_width;
+
+    if (placement != TOP_LEFT && placement != BOTTOM_LEFT && placement != TEXT_ONLY_RIGHT) {
+        if (placement == CENTER || placement == CENTER_X_ONLY)
+            x -= (x_adj / 2);
+        else
+            x -= x_adj;
+    }
+
+    if (placement != TOP_LEFT && placement != TOP_RIGHT) {
+        if (placement == CENTER || placement == TEXT_ONLY_RIGHT)
+            y -= (measured_height / 2);
+        else if (placement == BOTTOM_LEFT || placement == BOTTOM_RIGHT)
+            y -= measured_height;
+    }
+    return gr_ttf_textExWH(gl, x, y + y_scale, s, vfont, measured_width + x, -1);
+}
+
+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_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 = (GGLSurface *)malloc(sizeof(GGLSurface));
+    memset(surface, 0, sizeof(GGLSurface));
+
+    data = (uint32_t *)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 (gr_surface)surface;
+}
+
+void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+{
+    GGLContext *gl = gr_context;
+    GGLint color[4];
+#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
+    color[0] = ((b << 8) | r) + 1;
+    color[1] = ((g << 8) | g) + 1;
+    color[2] = ((r << 8) | b) + 1;
+    color[3] = ((a << 8) | a) + 1;
+#else
+    color[0] = ((r << 8) | r) + 1;
+    color[1] = ((g << 8) | g) + 1;
+    color[2] = ((b << 8) | b) + 1;
+    color[3] = ((a << 8) | a) + 1;
+#endif
+    gl->color4xv(gl, color);
+
+    gr_is_curr_clr_opaque = (a == 255);
+}
+
+void gr_clear()
+{
+    if (gr_draw->pixel_bytes == 2) {
+        gr_fill(0, 0, gr_fb_width(), gr_fb_height());
+        return;
+    }
+
+    // This code only works on 32bpp devices
+    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 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_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_flip() {
+    gr_draw = gr_backend->flip(gr_backend);
+    // On double buffered back ends, when we flip, we need to tell
+    // pixel flinger to draw to the other buffer
+    gr_mem_surface.data = (GGLubyte*)gr_draw->data;
+    gr_context->colorBuffer(gr_context, &gr_mem_surface);
+}
+
+static void get_memory_surface(GGLSurface* ms) {
+    ms->version = sizeof(*ms);
+    ms->width = gr_draw->width;
+    ms->height = gr_draw->height;
+    ms->stride = gr_draw->row_bytes / gr_draw->pixel_bytes;
+    ms->data = (GGLubyte*)gr_draw->data;
+    ms->format = gr_draw->format;
+}
+
+int gr_init(void)
+{
+    gr_draw = NULL;
+
+    gr_backend = open_overlay();
+    if (gr_backend) {
+        gr_draw = gr_backend->init(gr_backend);
+        if (!gr_draw) {
+            gr_backend->exit(gr_backend);
+        } else
+            printf("Using overlay graphics.\n");
+    }
+
+#ifdef HAS_ADF
+    if (!gr_draw) {
+        gr_backend = open_adf();
+        if (gr_backend) {
+            gr_draw = gr_backend->init(gr_backend);
+            if (!gr_draw) {
+                gr_backend->exit(gr_backend);
+            } else
+                printf("Using adf graphics.\n");
+        }
+    }
+#else
+#ifdef MSM_BSP
+	printf("Skipping adf graphics because TW_TARGET_USES_QCOM_BSP := true\n");
+#else
+    printf("Skipping adf graphics -- not present in build tree\n");
+#endif
+#endif
+
+#ifdef HAS_DRM
+    if (!gr_draw) {
+        gr_backend = open_drm();
+        gr_draw = gr_backend->init(gr_backend);
+        if (gr_draw)
+            printf("Using drm graphics.\n");
+    }
+#else
+    printf("Skipping drm graphics -- not present in build tree\n");
+#endif
+
+    if (!gr_draw) {
+        gr_backend = open_fbdev();
+        gr_draw = gr_backend->init(gr_backend);
+        if (gr_draw == NULL) {
+            return -1;
+        } else
+            printf("Using fbdev graphics.\n");
+    }
+
+    overscan_offset_x = gr_draw->width * overscan_percent / 100;
+    overscan_offset_y = gr_draw->height * overscan_percent / 100;
+
+    // Set up pixelflinger
+    get_memory_surface(&gr_mem_surface);
+    gglInit(&gr_context);
+    GGLContext *gl = gr_context;
+    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);
+
+    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);
+}
+
+int gr_get_surface(gr_surface* surface)
+{
+    GGLSurface* ms = (GGLSurface*)malloc(sizeof(GGLSurface));
+    if (!ms)    return -1;
+
+    // Allocate the data
+    get_memory_surface(ms);
+    ms->data = (GGLubyte*)malloc(ms->stride * ms->height * gr_draw->pixel_bytes);
+
+    // Now, copy the data
+    memcpy(ms->data, gr_mem_surface.data, gr_draw->width * gr_draw->height * gr_draw->pixel_bytes / 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, gr_draw->width * gr_draw->height * gr_draw->pixel_bytes / 8);
+}
