diff --git a/minui/graphics_drm.cpp b/minui/graphics_drm.cpp
index ddda187..ef377b7 100644
--- a/minui/graphics_drm.cpp
+++ b/minui/graphics_drm.cpp
@@ -14,466 +14,384 @@
  * limitations under the License.
  */
 
-#include <drm_fourcc.h>
+#include "graphics_drm.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 <drm_fourcc.h>
 #include <xf86drm.h>
 #include <xf86drmMode.h>
 
-#include "minui.h"
-#include "graphics.h"
+#include "minui/minui.h"
 
 #define ARRAY_SIZE(A) (sizeof(A)/sizeof(*(A)))
 
-struct drm_surface {
-    GRSurface base;
-    uint32_t fb_id;
-    uint32_t handle;
-};
+MinuiBackendDrm::MinuiBackendDrm()
+    : GRSurfaceDrms(), main_monitor_crtc(nullptr), main_monitor_connector(nullptr), drm_fd(-1) {}
 
-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
-    }
+void MinuiBackendDrm::DrmDisableCrtc(int drm_fd, drmModeCrtc* crtc) {
+  if (crtc) {
+    drmModeSetCrtc(drm_fd, crtc->crtc_id,
+                   0,         // fb_id
+                   0, 0,      // x,y
+                   nullptr,   // connectors
+                   0,         // connector_count
+                   nullptr);  // mode
+  }
 }
 
-static void drm_enable_crtc(int drm_fd, drmModeCrtc *crtc,
-                            struct drm_surface *surface) {
-    int32_t ret;
+void MinuiBackendDrm::DrmEnableCrtc(int drm_fd, drmModeCrtc* crtc, GRSurfaceDrm* surface) {
+  int32_t 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);
 
-    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);
+  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]);
+void MinuiBackendDrm::Blank(bool blank) {
+  if (blank) {
+    DrmDisableCrtc(drm_fd, main_monitor_crtc);
+  } else {
+    DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[current_buffer]);
+  }
 }
 
-static void drm_destroy_surface(struct drm_surface *surface) {
-    struct drm_gem_close gem_close;
-    int ret;
+void MinuiBackendDrm::DrmDestroySurface(GRSurfaceDrm* surface) {
+  if (!surface) return;
 
-    if(!surface)
-        return;
+  if (surface->data) {
+    munmap(surface->data, surface->row_bytes * surface->height);
+  }
 
-    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->fb_id) {
+    int 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;
+  if (surface->handle) {
+    drm_gem_close 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);
+    int ret = drmIoctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+    if (ret) {
+      printf("DRM_IOCTL_GEM_CLOSE failed ret=%d\n", ret);
     }
+  }
 
-    free(surface);
+  delete 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_ARGB8888:
-        case DRM_FORMAT_XRGB8888:
-            return 32;
-        case DRM_FORMAT_RGB565:
-            return 16;
-        default:
-            printf("Unknown format %d\n", format);
-            return 32;
-    }
+  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;
+GRSurfaceDrm* MinuiBackendDrm::DrmCreateSurface(int width, int height) {
+  GRSurfaceDrm* surface = new GRSurfaceDrm;
+  *surface = {};
 
-    surface = (struct drm_surface*)calloc(1, sizeof(*surface));
-    if (!surface) {
-        printf("Can't allocate memory\n");
-        return NULL;
-    }
-
+  uint32_t format;
 #if defined(RECOVERY_ABGR)
-    format = DRM_FORMAT_RGBA8888;
+  format = DRM_FORMAT_RGBA8888;
 #elif defined(RECOVERY_BGRA)
-    format = DRM_FORMAT_ARGB8888;
+  format = DRM_FORMAT_ARGB8888;
 #elif defined(RECOVERY_RGBA)
-    format = DRM_FORMAT_ABGR8888;
+  format = DRM_FORMAT_ARGB8888;
 #elif defined(RECOVERY_RGBX)
-    format = DRM_FORMAT_XBGR8888;
+  format = DRM_FORMAT_XBGR8888;
 #else
-    format = DRM_FORMAT_RGB565;
+  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;
+  drm_mode_create_dumb 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;
+  int ret = drmIoctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
+  if (ret) {
+    printf("DRM_IOCTL_MODE_CREATE_DUMB failed ret=%d\n", ret);
+    DrmDestroySurface(surface);
+    return nullptr;
+  }
+  surface->handle = create_dumb.handle;
 
-    uint32_t handles[4], pitches[4], offsets[4];
+  uint32_t handles[4], pitches[4], offsets[4];
 
-    handles[0] = surface->handle;
-    pitches[0] = create_dumb.pitch;
-    offsets[0] = 0;
+  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;
-    }
+  ret =
+      drmModeAddFB2(drm_fd, width, height, format, handles, pitches, offsets, &(surface->fb_id), 0);
+  if (ret) {
+    printf("drmModeAddFB2 failed ret=%d\n", ret);
+    DrmDestroySurface(surface);
+    return nullptr;
+  }
 
-    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;;
-    }
+  drm_mode_map_dumb 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);
+    DrmDestroySurface(surface);
+    return nullptr;
+  }
 
-    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;
-    }
+  surface->height = height;
+  surface->width = width;
+  surface->row_bytes = create_dumb.pitch;
+  surface->pixel_bytes = create_dumb.bpp / 8;
+  surface->data = static_cast<unsigned char*>(mmap(nullptr, surface->height * surface->row_bytes,
+                                                   PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd,
+                                                   map_dumb.offset));
+  if (surface->data == MAP_FAILED) {
+    perror("mmap() failed");
+    DrmDestroySurface(surface);
+    return nullptr;
+  }
 
-    return surface;
+  return surface;
 }
 
-static drmModeCrtc *find_crtc_for_connector(int fd,
-                            drmModeRes *resources,
-                            drmModeConnector *connector) {
-    int i, j;
-    drmModeEncoder *encoder;
-    int32_t crtc;
+static drmModeCrtc* find_crtc_for_connector(int fd, drmModeRes* resources,
+                                            drmModeConnector* connector) {
+  // Find the encoder. If we already have one, just use it.
+  drmModeEncoder* encoder;
+  if (connector->encoder_id) {
+    encoder = drmModeGetEncoder(fd, connector->encoder_id);
+  } else {
+    encoder = nullptr;
+  }
 
-    /*
-     * Find the encoder. If we already have one, just use it.
-     */
-    if (connector->encoder_id)
-        encoder = drmModeGetEncoder(fd, connector->encoder_id);
-    else
-        encoder = NULL;
+  int32_t crtc;
+  if (encoder && encoder->crtc_id) {
+    crtc = encoder->crtc_id;
+    drmModeFreeEncoder(encoder);
+    return drmModeGetCrtc(fd, crtc);
+  }
 
-    if (encoder && encoder->crtc_id) {
-        crtc = encoder->crtc_id;
+  // Didn't find anything, try to find a crtc and encoder combo.
+  crtc = -1;
+  for (int i = 0; i < connector->count_encoders; i++) {
+    encoder = drmModeGetEncoder(fd, connector->encoders[i]);
+
+    if (encoder) {
+      for (int 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);
+      }
     }
+  }
 
-    /*
-     * 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;
+  return nullptr;
 }
 
-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);
-        }
+static drmModeConnector* find_used_connector_by_type(int fd, drmModeRes* resources, unsigned type) {
+  for (int i = 0; i < resources->count_connectors; i++) {
+    drmModeConnector* 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;
+  }
+  return nullptr;
 }
 
-static drmModeConnector *find_first_connected_connector(int fd,
-                             drmModeRes *resources) {
-    int i;
-    for (i = 0; i < resources->count_connectors; i++) {
-        drmModeConnector *connector;
+static drmModeConnector* find_first_connected_connector(int fd, drmModeRes* resources) {
+  for (int 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;
+    connector = drmModeGetConnector(fd, resources->connectors[i]);
+    if (connector) {
+      if ((connector->count_modes > 0) && (connector->connection == DRM_MODE_CONNECTED))
+        return connector;
 
-            drmModeFreeConnector(connector);
-        }
+      drmModeFreeConnector(connector);
     }
-    return NULL;
+  }
+  return nullptr;
 }
 
-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* MinuiBackendDrm::FindMainMonitor(int fd, drmModeRes* resources,
+                                                   uint32_t* mode_index) {
+  /* Look for LVDS/eDP/DSI connectors. Those are the main screens. */
+  static constexpr 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));
+  drmModeConnector* main_monitor_connector = nullptr;
+  unsigned i = 0;
+  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 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;
+  /* If we still didn't find a connector, give up and return. */
+  if (!main_monitor_connector) return nullptr;
 
-    *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;
-        }
+  *mode_index = 0;
+  for (int 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;
+  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);
+void MinuiBackendDrm::DisableNonMainCrtcs(int fd, drmModeRes* resources, drmModeCrtc* main_crtc) {
+  for (int i = 0; i < resources->count_connectors; i++) {
+    drmModeConnector* connector = drmModeGetConnector(fd, resources->connectors[i]);
+    drmModeCrtc* crtc = find_crtc_for_connector(fd, resources, connector);
+    if (crtc->crtc_id != main_crtc->crtc_id) {
+      DrmDisableCrtc(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;
+GRSurface* MinuiBackendDrm::Init() {
+  drmModeRes* res = nullptr;
 
-    /* Consider DRM devices in order. */
-    for (i = 0; i < DRM_MAX_MINOR; i++) {
-        uint64_t cap = 0;
+  /* Consider DRM devices in order. */
+  for (int i = 0; i < DRM_MAX_MINOR; i++) {
+    char* dev_name;
+    int ret = asprintf(&dev_name, DRM_DEV_NAME, DRM_DIR_NAME, i);
+    if (ret < 0) continue;
 
-        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;
 
-        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;
+    uint64_t cap = 0;
+    /* We need dumb buffers. */
+    ret = drmGetCap(drm_fd, DRM_CAP_DUMB_BUFFER, &cap);
+    if (ret || cap == 0) {
+      close(drm_fd);
+      continue;
     }
 
-    if (drm_fd < 0 || res == NULL) {
-        perror("cannot find/open a drm device");
-        return NULL;
+    res = drmModeGetResources(drm_fd);
+    if (!res) {
+      close(drm_fd);
+      continue;
     }
 
-    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;
+    /* 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;
     }
 
-    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;
+    res = nullptr;
+  }
+
+  if (drm_fd < 0 || res == nullptr) {
+    perror("cannot find/open a drm device");
+    return nullptr;
+  }
+
+  uint32_t selected_mode;
+  main_monitor_connector = FindMainMonitor(drm_fd, res, &selected_mode);
+
+  if (!main_monitor_connector) {
+    printf("main_monitor_connector not found\n");
+    drmModeFreeResources(res);
+    close(drm_fd);
+    return nullptr;
+  }
+
+  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 nullptr;
+  }
+
+  DisableNonMainCrtcs(drm_fd, res, main_monitor_crtc);
+
+  main_monitor_crtc->mode = main_monitor_connector->modes[selected_mode];
+
+  int width = main_monitor_crtc->mode.hdisplay;
+  int height = main_monitor_crtc->mode.vdisplay;
+
+  drmModeFreeResources(res);
+
+  GRSurfaceDrms[0] = DrmCreateSurface(width, height);
+  GRSurfaceDrms[1] = DrmCreateSurface(width, height);
+  if (!GRSurfaceDrms[0] || !GRSurfaceDrms[1]) {
+    // GRSurfaceDrms and drm_fd should be freed in d'tor.
+    return nullptr;
+  }
+
+  current_buffer = 0;
+
+  DrmEnableCrtc(drm_fd, main_monitor_crtc, GRSurfaceDrms[1]);
+
+  return GRSurfaceDrms[0];
 }
 
-static minui_backend drm_backend = {
-    .init = drm_init,
-    .flip = drm_flip,
-    .blank = drm_blank,
-    .exit = drm_exit,
-};
+GRSurface* MinuiBackendDrm::Flip() {
+  int ret = drmModePageFlip(drm_fd, main_monitor_crtc->crtc_id,
+                            GRSurfaceDrms[current_buffer]->fb_id, 0, nullptr);
+  if (ret < 0) {
+    printf("drmModePageFlip failed ret=%d\n", ret);
+    return nullptr;
+  }
+  current_buffer = 1 - current_buffer;
+  return GRSurfaceDrms[current_buffer];
+}
 
-minui_backend* open_drm() {
-    return &drm_backend;
+MinuiBackendDrm::~MinuiBackendDrm() {
+  DrmDisableCrtc(drm_fd, main_monitor_crtc);
+  DrmDestroySurface(GRSurfaceDrms[0]);
+  DrmDestroySurface(GRSurfaceDrms[1]);
+  drmModeFreeCrtc(main_monitor_crtc);
+  drmModeFreeConnector(main_monitor_connector);
+  close(drm_fd);
+  drm_fd = -1;
 }
