From 1f0fe5f783019ea6d4744e52370eb8c190eab12a Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 4 Aug 2013 18:07:29 +0300 Subject: [PATCH] op_runfbapp: more complete layer state save/restore --- op_runfbapp.c | 179 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 146 insertions(+), 33 deletions(-) diff --git a/op_runfbapp.c b/op_runfbapp.c index 4a5abb3..1c73d59 100644 --- a/op_runfbapp.c +++ b/op_runfbapp.c @@ -42,6 +42,7 @@ #include #include #include +#include #define __user #include "omapfb.h" @@ -95,61 +96,159 @@ static void x11h_wait_vmstate(Display *display) fprintf(stderr, "timeout waiting for wm_state change\n"); } -static struct omapfb_plane_info omap_pi; +static struct omapfb_plane_info desktop_pi, app_pi[2]; +static struct fb_var_screeninfo desktop_si, app_si[2]; +static int desktop_saved; -static int hide_omap_layer(void) +static int save_fb_state(int index, struct omapfb_plane_info *pi, + struct fb_var_screeninfo *si) { int retval = -1; + char buf[16]; + int fd = -1; int ret; - int fd; - fd = open("/dev/fb1", O_RDWR); + snprintf(buf, sizeof(buf), "/dev/fb%d", index); + fd = open(buf, O_RDWR); if (fd == -1) { - perror("open(/dev/fb1)"); - return -1; + fprintf(stderr, PFX); + perror(buf); + goto out; + } + + ret = ioctl(fd, OMAPFB_QUERY_PLANE, pi); + if (ret != 0) { + perror(PFX "QUERY_PLANE"); + goto out; + } + + ret = ioctl(fd, FBIOGET_VSCREENINFO, si); + if (ret == -1) { + perror(PFX "FBIOGET_VSCREENINFO"); + goto out; + } + + retval = 0; +out: + if (fd != -1) + close(fd); + return retval; +} + +static int load_fb_state(int index, struct omapfb_plane_info *pi, + struct fb_var_screeninfo *si) +{ + struct omapfb_plane_info tmp_pi; + int retval = -1; + char buf[16]; + int fd = -1; + int ret; + + snprintf(buf, sizeof(buf), "/dev/fb%d", index); + fd = open(buf, O_RDWR); + if (fd == -1) { + fprintf(stderr, PFX); + perror(buf); + goto out; + } + + // resolution can sometimes only be restored if position is right, + // so it's a bit more tricky.. + ret = ioctl(fd, OMAPFB_QUERY_PLANE, &tmp_pi); + if (ret != 0) { + perror(PFX "QUERY_PLANE"); + goto out; + } + + tmp_pi.enabled = 0; + tmp_pi.pos_x = 0; + tmp_pi.pos_y = 0; + ret = ioctl(fd, OMAPFB_SETUP_PLANE, &tmp_pi); + if (ret != 0) { + perror(PFX "SETUP_PLANE"); + goto out; + } + + ret = ioctl(fd, FBIOPUT_VSCREENINFO, si); + if (ret == -1) { + perror(PFX "FBIOPUT_VSCREENINFO"); + goto out; } - ret = ioctl(fd, OMAPFB_QUERY_PLANE, &omap_pi); + ret = ioctl(fd, OMAPFB_SETUP_PLANE, pi); if (ret != 0) { - perror("QUERY_PLANE"); + perror(PFX "SETUP_PLANE(2)"); goto out; } - if (omap_pi.enabled) { - omap_pi.enabled = 0; - ret = ioctl(fd, OMAPFB_SETUP_PLANE, &omap_pi); + retval = 0; +out: + if (fd != -1) + close(fd); + return retval; +} + +// prepare OMAP layers for desktop +static int minimize_omap_layers(void) +{ + struct omapfb_plane_info pi_set; + int retval = -1; + int fd = -1; + int i, ret; + + if (!desktop_saved) { + fprintf(stderr, PFX "desktop not saved\n"); + goto out; + } + + for (i = 0; i < 2; i++) { + ret = save_fb_state(i, &app_pi[i], &app_si[i]); if (ret != 0) { - perror("SETUP_PLANE"); + fprintf(stderr, PFX "layer %d state save failed\n", i); goto out; } + } + + retval = 0; // no restoring needed + + if (memcmp(&app_pi[0], &desktop_pi, sizeof(desktop_pi)) != 0) { + ret = load_fb_state(0, &desktop_pi, &desktop_si); + if (ret != 0) { + fprintf(stderr, PFX "desktop restore failed\n"); + // but continue, I guess? + } retval = 1; } - else { - retval = 0; + + if (app_pi[1].enabled) { + pi_set = app_pi[1]; + pi_set.enabled = 0; + + fd = open("/dev/fb1", O_RDWR); + ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi_set); + if (ret != 0) { + perror(PFX "SETUP_PLANE"); + } + retval = 1; } out: - close(fd); + if (fd != -1) + close(fd); return retval; } -static void show_omap_layer(void) +static void restore_omap_layers(void) { - int ret; - int fd; + int i, ret; - fd = open("/dev/fb1", O_RDWR); - if (fd == -1) { - perror("open(/dev/fb1)"); - return; + for (i = 0; i < 2; i++) { + ret = load_fb_state(i, &app_pi[i], &app_si[i]); + if (ret != 0) { + fprintf(stderr, PFX "layer %d state load failed\n", i); + // .. but try to continue .. + } } - - omap_pi.enabled = 1; - ret = ioctl(fd, OMAPFB_SETUP_PLANE, &omap_pi); - if (ret != 0) - perror("SETUP_PLANE"); - - close(fd); } static int x11h_minimize(Display *display, Window window) @@ -269,10 +368,17 @@ static void *x11_handler(void *arg) && g_child_pid != 0) { kill(g_child_pid, SIGSTOP); - ret = hide_omap_layer(); - x11h_minimize(display, win); - if (ret > 0) - show_omap_layer(); + ret = minimize_omap_layers(); + if (ret >= 0) { + fflush(stdout); + fflush(stderr); + x11h_minimize(display, win); + } + if (ret > 0) { + restore_omap_layers(); + fflush(stdout); + fflush(stderr); + } kill(g_child_pid, SIGCONT); } @@ -394,6 +500,13 @@ int main(int argc, char *argv[]) } pthread_detach(tid); + // assume desktop is in good state.. + ret = save_fb_state(0, &desktop_pi, &desktop_si); + if (ret == 0) + desktop_saved = 1; + else + fprintf(stderr, PFX "initial desktop state save failed\n"); + pthread_cond_wait(&g_start_cond, &g_start_mutex); pthread_mutex_unlock(&g_start_mutex); -- 2.39.5