#include <termios.h>
#include <signal.h>
#include <linux/kd.h>
+#include <linux/fb.h>
#define __user
#include "omapfb.h"
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)
&& 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);
}
}
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);