aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/linux/xenv.c161
-rw-r--r--frontend/linux/xenv.h3
-rw-r--r--frontend/main.c3
-rw-r--r--frontend/main.h1
-rw-r--r--frontend/menu.c3
-rw-r--r--frontend/plat.h1
-rw-r--r--frontend/plat_dummy.c4
-rw-r--r--frontend/plat_omap.c9
-rw-r--r--frontend/plat_pandora.c1
-rw-r--r--frontend/plat_pollux.c4
-rw-r--r--maemo/hildon.c4
11 files changed, 180 insertions, 14 deletions
diff --git a/frontend/linux/xenv.c b/frontend/linux/xenv.c
index 3de7628..f54e57d 100644
--- a/frontend/linux/xenv.c
+++ b/frontend/linux/xenv.c
@@ -1,5 +1,5 @@
/*
- * (C) Gražvydas "notaz" Ignotas, 2009-2011
+ * (C) Gražvydas "notaz" Ignotas, 2009-2012
*
* This work is licensed under the terms of any of these licenses
* (at your option):
@@ -38,6 +38,7 @@
struct xstuff {
Display *display;
+ Window window;
FPTR(XCreateBitmapFromData);
FPTR(XCreatePixmapCursor);
FPTR(XFreePixmap);
@@ -50,11 +51,17 @@ struct xstuff {
FPTR(XMapWindow);
FPTR(XNextEvent);
FPTR(XCheckTypedEvent);
- FPTR(XUnmapWindow);
+ FPTR(XWithdrawWindow);
FPTR(XGrabKeyboard);
FPTR(XPending);
FPTR(XLookupKeysym);
FPTR(XkbSetDetectableAutoRepeat);
+ FPTR(XStoreName);
+ FPTR(XIconifyWindow);
+ FPTR(XMoveResizeWindow);
+ FPTR(XInternAtom);
+ FPTR(XSetWMHints);
+ FPTR(XSync);
};
static struct xstuff g_xstuff;
@@ -74,7 +81,7 @@ static Cursor transparent_cursor(struct xstuff *xf, Display *display, Window win
return cursor;
}
-static int x11h_init(void)
+static int x11h_init(const char *window_title)
{
unsigned int display_width, display_height;
Display *display;
@@ -102,11 +109,17 @@ static int x11h_init(void)
FPTR_LINK(g_xstuff, x11lib, XMapWindow);
FPTR_LINK(g_xstuff, x11lib, XNextEvent);
FPTR_LINK(g_xstuff, x11lib, XCheckTypedEvent);
- FPTR_LINK(g_xstuff, x11lib, XUnmapWindow);
+ FPTR_LINK(g_xstuff, x11lib, XWithdrawWindow);
FPTR_LINK(g_xstuff, x11lib, XGrabKeyboard);
FPTR_LINK(g_xstuff, x11lib, XPending);
FPTR_LINK(g_xstuff, x11lib, XLookupKeysym);
FPTR_LINK(g_xstuff, x11lib, XkbSetDetectableAutoRepeat);
+ FPTR_LINK(g_xstuff, x11lib, XStoreName);
+ FPTR_LINK(g_xstuff, x11lib, XIconifyWindow);
+ FPTR_LINK(g_xstuff, x11lib, XMoveResizeWindow);
+ FPTR_LINK(g_xstuff, x11lib, XInternAtom);
+ FPTR_LINK(g_xstuff, x11lib, XSetWMHints);
+ FPTR_LINK(g_xstuff, x11lib, XSync);
//XInitThreads();
@@ -132,22 +145,25 @@ static int x11h_init(void)
display_height = DisplayHeight(display, screen);
printf(PFX "display is %dx%d\n", display_width, display_height);
- win = g_xstuff.pXCreateSimpleWindow(display,
- RootWindow(display, screen),
- 0, 0, display_width, display_height, 0,
- BlackPixel(display, screen),
- BlackPixel(display, screen));
+ g_xstuff.window = win = g_xstuff.pXCreateSimpleWindow(display,
+ RootWindow(display, screen), 0, 0, display_width, display_height,
+ 0, BlackPixel(display, screen), BlackPixel(display, screen));
attributes.override_redirect = True;
attributes.cursor = transparent_cursor(&g_xstuff, display, win);
g_xstuff.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes);
- g_xstuff.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask);
+ g_xstuff.pXStoreName(display, win, window_title);
+ g_xstuff.pXSelectInput(display, win,
+ ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask);
g_xstuff.pXMapWindow(display, win);
g_xstuff.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
g_xstuff.pXkbSetDetectableAutoRepeat(display, 1, NULL);
// XSetIOErrorHandler
+ // we don't know when event dispatch will be called, so sync now
+ g_xstuff.pXSync(display, False);
+
return 0;
fail2:
dlclose(x11lib);
@@ -169,6 +185,8 @@ static int x11h_update(int *is_down)
case Expose:
while (g_xstuff.pXCheckTypedEvent(g_xstuff.display, Expose, &evt))
;
+ default:
+ // printf("event %d\n", evt.type);
break;
case KeyPress:
@@ -185,6 +203,86 @@ static int x11h_update(int *is_down)
return NoSymbol;
}
+static void x11h_wait_vmstate(void)
+{
+ Atom wm_state = g_xstuff.pXInternAtom(g_xstuff.display, "WM_STATE", False);
+ XEvent evt;
+ int i;
+
+ usleep(20000);
+
+ for (i = 0; i < 20; i++) {
+ while (g_xstuff.pXPending(g_xstuff.display)) {
+ g_xstuff.pXNextEvent(g_xstuff.display, &evt);
+ // printf("w event %d\n", evt.type);
+ if (evt.type == PropertyNotify && evt.xproperty.atom == wm_state)
+ return;
+ }
+ usleep(200000);
+ }
+
+ printf("timeout waiting for wm_state change\n");
+}
+
+static int x11h_minimize(void)
+{
+ XSetWindowAttributes attributes;
+ Display *display = g_xstuff.display;
+ Window window = g_xstuff.window;
+ int screen = DefaultScreen(g_xstuff.display);
+ int display_width, display_height;
+ XWMHints wm_hints;
+ XEvent evt;
+
+ g_xstuff.pXWithdrawWindow(display, window, screen);
+
+ attributes.override_redirect = False;
+ g_xstuff.pXChangeWindowAttributes(display, window,
+ CWOverrideRedirect, &attributes);
+
+ wm_hints.flags = StateHint;
+ wm_hints.initial_state = IconicState;
+ g_xstuff.pXSetWMHints(display, window, &wm_hints);
+
+ g_xstuff.pXMapWindow(display, window);
+
+ while (g_xstuff.pXNextEvent(display, &evt) == 0)
+ {
+ // printf("m event %d\n", evt.type);
+ switch (evt.type)
+ {
+ case FocusIn:
+ goto out;
+ default:
+ break;
+ }
+ }
+
+out:
+ g_xstuff.pXWithdrawWindow(display, window, screen);
+
+ // must wait for some magic vmstate property change before setting override_redirect
+ x11h_wait_vmstate();
+
+ attributes.override_redirect = True;
+ g_xstuff.pXChangeWindowAttributes(display, window,
+ CWOverrideRedirect, &attributes);
+
+ // fixup window after resize on override_redirect loss
+ display_width = DisplayWidth(display, screen);
+ display_height = DisplayHeight(display, screen);
+ g_xstuff.pXMoveResizeWindow(display, window, 0, 0, display_width, display_height);
+
+ g_xstuff.pXMapWindow(display, window);
+ g_xstuff.pXGrabKeyboard(display, window, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ g_xstuff.pXkbSetDetectableAutoRepeat(display, 1, NULL);
+
+ // we don't know when event dispatch will be called, so sync now
+ g_xstuff.pXSync(display, False);
+
+ return 0;
+}
+
static struct termios g_kbd_termios_saved;
static int g_kbdfd = -1;
@@ -249,11 +347,11 @@ static void tty_end(void)
g_kbdfd = -1;
}
-int xenv_init(void)
+int xenv_init(const char *window_title)
{
int ret;
- ret = x11h_init();
+ ret = x11h_init(window_title);
if (ret == 0)
return 0;
@@ -274,8 +372,47 @@ int xenv_update(int *is_down)
return -1;
}
+/* blocking minimize until user maximazes again */
+int xenv_minimize(void)
+{
+ int ret, dummy;
+
+ if (g_xstuff.display) {
+ xenv_update(&dummy);
+ ret = x11h_minimize();
+ xenv_update(&dummy);
+ return ret;
+ }
+
+ return -1;
+}
+
void xenv_finish(void)
{
// TODO: cleanup X?
tty_end();
}
+
+#if 0
+int main()
+{
+ int i, r, d;
+
+ xenv_init("just a test");
+
+ for (i = 0; i < 5; i++) {
+ while ((r = xenv_update(&d)) > 0)
+ printf("%d %x %d\n", d, r, r);
+ sleep(1);
+
+ if (i == 1)
+ xenv_minimize();
+ printf("ll %d\n", i);
+ }
+
+ printf("xenv_finish..\n");
+ xenv_finish();
+
+ return 0;
+}
+#endif
diff --git a/frontend/linux/xenv.h b/frontend/linux/xenv.h
index 948381e..1afad9d 100644
--- a/frontend/linux/xenv.h
+++ b/frontend/linux/xenv.h
@@ -1,5 +1,6 @@
-int xenv_init(void);
+int xenv_init(const char *window_title);
int xenv_update(int *is_down);
+int xenv_minimize(void);
void xenv_finish(void);
diff --git a/frontend/main.c b/frontend/main.c
index 7b3aac5..d7f23ed 100644
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -250,6 +250,9 @@ void do_emu_action(void)
case SACTION_VOLUME_DOWN:
plat_step_volume(emu_action == SACTION_VOLUME_UP);
return;
+ case SACTION_MINIMIZE:
+ plat_minimize();
+ return;
default:
return;
}
diff --git a/frontend/main.h b/frontend/main.h
index bc6c267..22a42f6 100644
--- a/frontend/main.h
+++ b/frontend/main.h
@@ -60,6 +60,7 @@ enum sched_action {
SACTION_SCREENSHOT,
SACTION_VOLUME_UP,
SACTION_VOLUME_DOWN,
+ SACTION_MINIMIZE,
SACTION_GUN_TRIGGER = 16,
SACTION_GUN_A,
SACTION_GUN_B,
diff --git a/frontend/menu.c b/frontend/menu.c
index c6a52de..1e64718 100644
--- a/frontend/menu.c
+++ b/frontend/menu.c
@@ -756,6 +756,9 @@ me_bind_action emuctrl_actions[] =
{ "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP },
{ "Take Screenshot ", 1 << SACTION_SCREENSHOT },
{ "Enter Menu ", 1 << SACTION_ENTER_MENU },
+#ifdef __ARM_ARCH_7A__ /* XXX */
+ { "Minimize ", 1 << SACTION_MINIMIZE },
+#endif
{ "Gun Trigger ", 1 << SACTION_GUN_TRIGGER },
{ "Gun A button ", 1 << SACTION_GUN_A },
{ "Gun B button ", 1 << SACTION_GUN_B },
diff --git a/frontend/plat.h b/frontend/plat.h
index 185ee98..6a22035 100644
--- a/frontend/plat.h
+++ b/frontend/plat.h
@@ -1,3 +1,4 @@
+void plat_minimize(void);
void *plat_prepare_screenshot(int *w, int *h, int *bpp);
void plat_step_volume(int is_up);
int plat_cpu_clock_get(void);
diff --git a/frontend/plat_dummy.c b/frontend/plat_dummy.c
index e768946..7929015 100644
--- a/frontend/plat_dummy.c
+++ b/frontend/plat_dummy.c
@@ -71,3 +71,7 @@ void plat_step_volume(int is_up)
void plat_trigger_vibrate(void)
{
}
+
+void plat_minimize(void)
+{
+}
diff --git a/frontend/plat_omap.c b/frontend/plat_omap.c
index b529cfa..62f198b 100644
--- a/frontend/plat_omap.c
+++ b/frontend/plat_omap.c
@@ -121,6 +121,13 @@ void plat_video_menu_leave(void)
fprintf(stderr, "warning: vout_fbdev_resize failed\n");
}
+void plat_minimize(void)
+{
+ omap_enable_layer(0);
+ xenv_minimize();
+ omap_enable_layer(1);
+}
+
void plat_step_volume(int is_up)
{
}
@@ -158,7 +165,7 @@ void plat_init(void)
exit(1);
}
- xenv_init();
+ xenv_init("PCSX-ReARMed");
w = h = 0;
main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);
diff --git a/frontend/plat_pandora.c b/frontend/plat_pandora.c
index d869d24..1c07924 100644
--- a/frontend/plat_pandora.c
+++ b/frontend/plat_pandora.c
@@ -53,6 +53,7 @@ struct in_default_bind in_evdev_defbinds[] = {
{ KEY_RIGHTCTRL, IN_BINDTYPE_PLAYER12, DKEY_R1 },
{ KEY_Q, IN_BINDTYPE_PLAYER12, DKEY_L2 },
{ KEY_P, IN_BINDTYPE_PLAYER12, DKEY_R2 },
+ { KEY_TAB, IN_BINDTYPE_EMU, SACTION_MINIMIZE },
{ KEY_SPACE, IN_BINDTYPE_EMU, SACTION_ENTER_MENU },
{ KEY_1, IN_BINDTYPE_EMU, SACTION_SAVE_STATE },
{ KEY_2, IN_BINDTYPE_EMU, SACTION_LOAD_STATE },
diff --git a/frontend/plat_pollux.c b/frontend/plat_pollux.c
index af91066..af5b81a 100644
--- a/frontend/plat_pollux.c
+++ b/frontend/plat_pollux.c
@@ -262,6 +262,10 @@ void *plat_prepare_screenshot(int *w, int *h, int *bpp)
return pl_vout_buf;
}
+void plat_minimize(void)
+{
+}
+
static void pl_vout_set_raw_vram(void *vram)
{
int i;
diff --git a/maemo/hildon.c b/maemo/hildon.c
index a5f151e..0399909 100644
--- a/maemo/hildon.c
+++ b/maemo/hildon.c
@@ -265,3 +265,7 @@ void plat_step_volume(int is_up)
void plat_trigger_vibrate(void)
{
}
+
+void plat_minimize(void)
+{
+}