diff options
-rw-r--r-- | drmtools.c | 50 | ||||
-rw-r--r-- | fbcon.c | 11 | ||||
-rw-r--r-- | fbi.c | 2 | ||||
-rw-r--r-- | fbpdf.c | 2 | ||||
-rw-r--r-- | fbtools.c | 9 | ||||
-rw-r--r-- | gfx.h | 3 | ||||
-rw-r--r-- | logind.c | 3 |
7 files changed, 59 insertions, 21 deletions
@@ -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"); @@ -47,6 +47,7 @@ static int font_size = 16; static bool verbose; static gfxstate *gfx; +static bool active; static cairo_font_extents_t extents; static struct cairo_state { cairo_surface_t *surface; @@ -178,15 +179,18 @@ static void cleanup_and_exit(int code) static void console_switch_suspend(void) { + gfx->suspend_display(); libinput_suspend(kbd); logind_release_control(); + active = false; } static void console_switch_resume(void) { - gfx->restore_display(); + active = true; logind_take_control(); libinput_resume(kbd); + gfx->resume_display(); state1.clear++; state2.clear++; dirty++; @@ -643,10 +647,13 @@ int main(int argc, char *argv[]) exit(1); exit_signals_init(); signal(SIGTSTP,SIG_IGN); +#if 0 if (console_switch_init(console_switch_suspend, console_switch_resume) < 0) { fprintf(stderr, "NOTICE: No vt switching available on terminal.\n"); } +#endif + active = true; /* init cairo */ state1.surface = cairo_image_surface_create_for_data(gfx->mem, @@ -710,7 +717,7 @@ int main(int argc, char *argv[]) fd_set set; int rc, max; - if (dirty) { + if (active && dirty) { fbcon_tsm_render(); dirty = 0; } @@ -1212,7 +1212,7 @@ static void console_switch_suspend(void) static void console_switch_resume(void) { - gfx->restore_display(); + gfx->resume_display(); shadow_render(gfx); kbd_resume(); } @@ -205,7 +205,7 @@ static void console_switch_suspend(void) static void console_switch_resume(void) { - gfx->restore_display(); + gfx->resume_display(); kbd_resume(); } @@ -180,7 +180,11 @@ fb_setmode(char *name) return -1; } -static void fb_restore_display(void) +static void fb_suspend_display(void) +{ +} + +static void fb_resume_display(void) { ioctl(fb,FBIOPAN_DISPLAY,&fb_var); fb_set_palette(); @@ -310,7 +314,8 @@ gfxstate* fb_init(const char *device, char *mode) gfx->mem = fb_mem; gfx->fmt = fmt; - gfx->restore_display = fb_restore_display; + gfx->suspend_display = fb_suspend_display; + gfx->resume_display = fb_resume_display; gfx->cleanup_display = fb_cleanup_display; fstat(fb, &st); @@ -43,7 +43,8 @@ struct gfxstate { dev_t devnum; /* calls */ - void (*restore_display)(void); + void (*suspend_display)(void); + void (*resume_display)(void); void (*cleanup_display)(void); void (*flush_display)(bool second); }; @@ -182,6 +182,9 @@ int logind_init(bool take_control, logind_session_cb, NULL); + session_suspend = suspend; + session_resume = resume; + fprintf(stderr, "Opening input devices via logind.\n"); return 0; } |