From cf6e8218bab44447c6916dfd924e41de30beb8cb Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 27 Mar 2019 14:33:25 +0100 Subject: more logind console switching --- drmtools.c | 50 ++++++++++++++++++++++++++++++++++++-------------- fbcon.c | 11 +++++++++-- fbi.c | 2 +- fbpdf.c | 2 +- fbtools.c | 9 +++++++-- gfx.h | 3 ++- logind.c | 3 +++ 7 files changed, 59 insertions(+), 21 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"); diff --git a/fbcon.c b/fbcon.c index 489191a..2f0f2bc 100644 --- a/fbcon.c +++ b/fbcon.c @@ -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; } diff --git a/fbi.c b/fbi.c index 6d5d49f..397593d 100644 --- a/fbi.c +++ b/fbi.c @@ -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(); } diff --git a/fbpdf.c b/fbpdf.c index ed73d3a..a48d7d6 100644 --- a/fbpdf.c +++ b/fbpdf.c @@ -205,7 +205,7 @@ static void console_switch_suspend(void) static void console_switch_resume(void) { - gfx->restore_display(); + gfx->resume_display(); kbd_resume(); } diff --git a/fbtools.c b/fbtools.c index 30021fb..3158d2e 100644 --- a/fbtools.c +++ b/fbtools.c @@ -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); diff --git a/gfx.h b/gfx.h index f060d38..212f4ef 100644 --- a/gfx.h +++ b/gfx.h @@ -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); }; diff --git a/logind.c b/logind.c index a179684..6b1b77c 100644 --- a/logind.c +++ b/logind.c @@ -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; } -- cgit