aboutsummaryrefslogtreecommitdiffstats
path: root/drmtools.c
diff options
context:
space:
mode:
Diffstat (limited to 'drmtools.c')
-rw-r--r--drmtools.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/drmtools.c b/drmtools.c
index acccc29..1d2656a 100644
--- a/drmtools.c
+++ b/drmtools.c
@@ -18,11 +18,15 @@
/* ------------------------------------------------------------------ */
/* device */
+
int drm_fd;
drmModeEncoder *drm_enc = NULL;
drmModeModeInfo *drm_mode = NULL;
drmModeConnector *drm_conn = NULL;
+
static drmModeCrtc *scrtc = NULL;
+static gfxfmt *drm_fmt = NULL;
+static char drm_dev[64];
struct drmfb {
uint32_t id;
@@ -200,7 +204,7 @@ static int drm_init_fb(struct drmfb *fb, struct gfxfmt *fmt, bool logerrors)
fprintf(stderr, "drm: DRM_IOCTL_MODE_MAP_DUMB: %s\n", strerror(errno));
return -1;
}
- fb->mem = mmap(0, fb->creq.size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ fb->mem = mmap(fb->mem, fb->creq.size, PROT_READ | PROT_WRITE, MAP_SHARED,
drm_fd, mreq.offset);
if (fb->mem == MAP_FAILED) {
if (logerrors)
@@ -210,6 +214,12 @@ static int drm_init_fb(struct drmfb *fb, struct gfxfmt *fmt, bool logerrors)
return 0;
}
+static int drm_fini_fb(struct drmfb *fb)
+{
+ munmap(fb->mem, fb->creq.size);
+ return 0;
+}
+
static int drm_show_fb(struct drmfb *fb)
{
int rc;
@@ -226,8 +236,21 @@ static int drm_show_fb(struct drmfb *fb)
/* ------------------------------------------------------------------ */
-static void drm_restore_display(void)
+static void drm_suspend_display(void)
{
+ if (fb2.mem)
+ drm_fini_fb(&fb2);
+ drm_fini_fb(&fb1);
+ close(drm_fd);
+ drm_fd = -1;
+}
+
+static void drm_resume_display(void)
+{
+ drm_fd = open(drm_dev, O_RDWR | O_CLOEXEC);
+ drm_init_fb(&fb1, drm_fmt, false);
+ if (fb2.mem)
+ drm_init_fb(&fb2, drm_fmt, false);
drm_show_fb(fbc);
}
@@ -243,26 +266,24 @@ gfxstate *drm_init(const char *device, const char *output,
{
struct stat st;
gfxstate *gfx;
- gfxfmt *fmt = NULL;
- char dev[64];
int i;
if (device) {
- snprintf(dev, sizeof(dev), "%s", device);
+ snprintf(drm_dev, sizeof(drm_dev), "%s", device);
} else {
- snprintf(dev, sizeof(dev), DRM_DEV_NAME, DRM_DIR_NAME, 0);
+ snprintf(drm_dev, sizeof(drm_dev), DRM_DEV_NAME, DRM_DIR_NAME, 0);
}
- fprintf(stderr, "trying drm: %s ...\n", dev);
+ fprintf(stderr, "trying drm: %s ...\n", drm_dev);
- if (drm_init_dev(dev, output, mode) < 0)
+ if (drm_init_dev(drm_dev, output, mode) < 0)
return NULL;
for (i = 0; i < fmt_count; i++) {
if (drm_init_fb(&fb1, fmt_list + i, true) < 0)
continue;
- fmt = fmt_list + i;
+ drm_fmt = fmt_list + i;
break;
}
- if (fmt == NULL)
+ if (drm_fmt == NULL)
return NULL;
if (drm_show_fb(&fb1) < 0)
return NULL;
@@ -275,18 +296,19 @@ gfxstate *drm_init(const char *device, const char *output,
gfx->vdisplay = drm_mode->vdisplay;
gfx->stride = fb1.creq.pitch;
gfx->mem = fb1.mem;
- gfx->fmt = fmt;
+ gfx->fmt = drm_fmt;
- gfx->restore_display = drm_restore_display;
+ gfx->suspend_display = drm_suspend_display;
+ gfx->resume_display = drm_resume_display;
gfx->cleanup_display = drm_cleanup_display;
gfx->flush_display = drm_flush_display;
fstat(drm_fd, &st);
gfx->devnum = st.st_rdev;
- snprintf(gfx->devpath, sizeof(gfx->devpath), "%s", dev);
+ snprintf(gfx->devpath, sizeof(gfx->devpath), "%s", drm_dev);
if (pageflip) {
- if (drm_init_fb(&fb2, fmt, false) == 0) {
+ if (drm_init_fb(&fb2, drm_fmt, false) == 0) {
gfx->mem2 = fb2.mem;
} else {
fprintf(stderr, "drm: can't alloc two fbs, pageflip disabled.\n");