frontend: merge updates from SDL project
authornotaz <notasas@gmail.com>
Mon, 9 Apr 2012 21:33:43 +0000 (00:33 +0300)
committernotaz <notasas@gmail.com>
Tue, 10 Apr 2012 00:07:13 +0000 (03:07 +0300)
frontend/linux/fbdev.c
frontend/linux/fbdev.h
frontend/linux/xenv.c
frontend/linux/xenv.h
frontend/plat_omap.c

index afd5531..ec3d5c7 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "fbdev.h"
 
+#define PFX "fbdev: "
+
 struct vout_fbdev {
        int     fd;
        void    *mem;
@@ -32,6 +34,8 @@ struct vout_fbdev {
        int     fb_size;
        int     buffer_count;
        int     top_border, bottom_border;
+       void    *mem_saved;
+       size_t  mem_saved_size;
 };
 
 void *vout_fbdev_flip(struct vout_fbdev *fbdev)
@@ -83,7 +87,7 @@ void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp,
        {
                if (fbdev->fbvar_new.bits_per_pixel != bpp ||
                                w != fbdev->fbvar_new.xres || h != fbdev->fbvar_new.yres)
-                       printf(switching to %dx%d@%d\n", w, h, bpp);
+                       printf(PFX "switching to %dx%d@%d\n", w, h, bpp);
 
                fbdev->fbvar_new.xres = w;
                fbdev->fbvar_new.yres = h;
@@ -105,12 +109,12 @@ void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp,
                        fbdev->fbvar_new.yres_virtual = h_total;
                        ret = ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_new);
                        if (ret == -1) {
-                               perror("FBIOPUT_VSCREENINFO ioctl");
+                               perror(PFX "FBIOPUT_VSCREENINFO ioctl");
                                return NULL;
                        }
                        fbdev->buffer_count = 1;
                        fbdev->buffer_write = 0;
-                       fprintf(stderr, "Warning: failed to increase virtual resolution, "
+                       fprintf(stderr, PFX "Warning: failed to increase virtual resolution, "
                                        "multibuffering disabled\n");
                }
 
@@ -129,7 +133,7 @@ void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp,
 
        fbdev->mem = mmap(0, mem_size, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev->fd, 0);
        if (fbdev->mem == MAP_FAILED && fbdev->buffer_count > 1) {
-               fprintf(stderr, "Warning: can't map %zd bytes, doublebuffering disabled\n", mem_size);
+               fprintf(stderr, PFX "Warning: can't map %zd bytes, doublebuffering disabled\n", mem_size);
                fbdev->buffer_count = 1;
                fbdev->buffer_write = 0;
                mem_size = fbdev->fb_size;
@@ -138,7 +142,7 @@ void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp,
        if (fbdev->mem == MAP_FAILED) {
                fbdev->mem = NULL;
                fbdev->mem_size = 0;
-               perror("mmap framebuffer");
+               perror(PFX "mmap framebuffer");
                return NULL;
        }
 
@@ -184,14 +188,14 @@ struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int b
 
        fbdev->fd = open(fbdev_name, O_RDWR);
        if (fbdev->fd == -1) {
-               fprintf(stderr, "%s: ", fbdev_name);
+               fprintf(stderr, PFX "%s: ", fbdev_name);
                perror("open");
                goto fail_open;
        }
 
        ret = ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->fbvar_old);
        if (ret == -1) {
-               perror("FBIOGET_VSCREENINFO ioctl");
+               perror(PFX "FBIOGET_VSCREENINFO ioctl");
                goto fail;
        }
 
@@ -208,8 +212,8 @@ struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int b
        if (pret == NULL)
                goto fail;
 
-       printf("%s: %ix%i@%d\n", fbdev_name, fbdev->fbvar_new.xres, fbdev->fbvar_new.yres,
-               fbdev->fbvar_new.bits_per_pixel);
+       printf(PFX "%s: %ix%i@%d\n", fbdev_name, fbdev->fbvar_new.xres,
+               fbdev->fbvar_new.yres, fbdev->fbvar_new.bits_per_pixel);
        *w = fbdev->fbvar_new.xres;
        *h = fbdev->fbvar_new.yres;
 
@@ -219,7 +223,7 @@ struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int b
        ret = 0;
        ret = ioctl(fbdev->fd, FBIO_WAITFORVSYNC, &ret);
        if (ret != 0)
-               fprintf(stderr, "Warning: vsync doesn't seem to be supported\n");
+               fprintf(stderr, PFX "Warning: vsync doesn't seem to be supported\n");
 
        if (fbdev->buffer_count > 1) {
                fbdev->buffer_write = 0;
@@ -227,7 +231,7 @@ struct vout_fbdev *vout_fbdev_init(const char *fbdev_name, int *w, int *h, int b
                ret = ioctl(fbdev->fd, FBIOPAN_DISPLAY, &fbdev->fbvar_new);
                if (ret != 0) {
                        fbdev->buffer_count = 1;
-                       fprintf(stderr, "Warning: can't pan display, doublebuffering disabled\n");
+                       fprintf(stderr, PFX "Warning: can't pan display, doublebuffering disabled\n");
                }
        }
 
@@ -241,14 +245,66 @@ fail_open:
        return NULL;
 }
 
-void vout_fbdev_finish(struct vout_fbdev *fbdev)
+static void vout_fbdev_release(struct vout_fbdev *fbdev)
 {
        ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_old);
        if (fbdev->mem != MAP_FAILED)
                munmap(fbdev->mem, fbdev->mem_size);
+       fbdev->mem = NULL;
+}
+
+int vout_fbdev_save(struct vout_fbdev *fbdev)
+{
+       void *tmp;
+
+       if (fbdev == NULL || fbdev->mem == NULL || fbdev->mem == MAP_FAILED) {
+               fprintf(stderr, PFX "bad args for save\n");
+               return -1;
+       }
+
+       if (fbdev->mem_saved_size < fbdev->mem_size) {
+               tmp = realloc(fbdev->mem_saved, fbdev->mem_size);
+               if (tmp == NULL)
+                       return -1;
+               fbdev->mem_saved = tmp;
+       }
+       memcpy(fbdev->mem_saved, fbdev->mem, fbdev->mem_size);
+       fbdev->mem_saved_size = fbdev->mem_size;
+
+       vout_fbdev_release(fbdev);
+       return 0;
+}
+
+int vout_fbdev_restore(struct vout_fbdev *fbdev)
+{
+       int ret;
+
+       if (fbdev == NULL || fbdev->mem != NULL) {
+               fprintf(stderr, PFX "bad args/state for restore\n");
+               return -1;
+       }
+
+       fbdev->mem = mmap(0, fbdev->mem_size, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev->fd, 0);
+       if (fbdev->mem == MAP_FAILED) {
+               perror(PFX "restore: memory restore failed");
+               return -1;
+       }
+       memcpy(fbdev->mem, fbdev->mem_saved, fbdev->mem_size);
+
+       ret = ioctl(fbdev->fd, FBIOPUT_VSCREENINFO, &fbdev->fbvar_new);
+       if (ret == -1) {
+               perror(PFX "restore: FBIOPUT_VSCREENINFO");
+               return -1;
+       }
+
+       return 0;
+}
+
+void vout_fbdev_finish(struct vout_fbdev *fbdev)
+{
+       vout_fbdev_release(fbdev);
        if (fbdev->fd >= 0)
                close(fbdev->fd);
-       fbdev->mem = NULL;
        fbdev->fd = -1;
        free(fbdev);
 }
index 2db9163..88cd519 100644 (file)
@@ -9,4 +9,6 @@ void *vout_fbdev_resize(struct vout_fbdev *fbdev, int w, int h, int bpp,
 void  vout_fbdev_clear(struct vout_fbdev *fbdev);
 void  vout_fbdev_clear_lines(struct vout_fbdev *fbdev, int y, int count);
 int   vout_fbdev_get_fd(struct vout_fbdev *fbdev);
+int   vout_fbdev_save(struct vout_fbdev *fbdev);
+int   vout_fbdev_restore(struct vout_fbdev *fbdev);
 void  vout_fbdev_finish(struct vout_fbdev *fbdev);
index f54e57d..40bf92c 100644 (file)
@@ -25,6 +25,8 @@
 #include <termios.h>
 #include <linux/kd.h>
 
+#include "xenv.h"
+
 #define PFX "xenv: "
 
 #define FPTR(f) typeof(f) * p##f
@@ -81,13 +83,14 @@ static Cursor transparent_cursor(struct xstuff *xf, Display *display, Window win
        return cursor;
 }
 
-static int x11h_init(const char *window_title)
+static int x11h_init(int *xenv_flags, const char *window_title)
 {
        unsigned int display_width, display_height;
        Display *display;
        XSetWindowAttributes attributes;
        Window win;
        Visual *visual;
+       long evt_mask;
        void *x11lib;
        int screen;
 
@@ -153,9 +156,14 @@ static int x11h_init(const char *window_title)
        attributes.cursor = transparent_cursor(&g_xstuff, display, win);
        g_xstuff.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes);
 
-       g_xstuff.pXStoreName(display, win, window_title);
-       g_xstuff.pXSelectInput(display, win,
-               ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PropertyChangeMask);
+       if (window_title != NULL)
+               g_xstuff.pXStoreName(display, win, window_title);
+       evt_mask = ExposureMask | FocusChangeMask | PropertyChangeMask;
+       if (xenv_flags && (*xenv_flags & XENV_CAP_KEYS))
+               evt_mask |= KeyPressMask | KeyReleaseMask;
+       if (xenv_flags && (*xenv_flags & XENV_CAP_MOUSE))
+               evt_mask |= ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
+       g_xstuff.pXSelectInput(display, win, evt_mask);
        g_xstuff.pXMapWindow(display, win);
        g_xstuff.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
        g_xstuff.pXkbSetDetectableAutoRepeat(display, 1, NULL);
@@ -173,34 +181,54 @@ fail:
        return -1;
 }
 
-static int x11h_update(int *is_down)
+static void x11h_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
+                       int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
+                       int (*mousem_cb)(void *cb_arg, int x, int y),
+                       void *cb_arg)
 {
        XEvent evt;
+       int keysym;
 
        while (g_xstuff.pXPending(g_xstuff.display))
        {
                g_xstuff.pXNextEvent(g_xstuff.display, &evt);
                switch (evt.type)
                {
-                       case Expose:
-                               while (g_xstuff.pXCheckTypedEvent(g_xstuff.display, Expose, &evt))
-                                       ;
-                       default:
-                               // printf("event %d\n", evt.type);
-                               break;
-
-                       case KeyPress:
-                               *is_down = 1;
-                               return g_xstuff.pXLookupKeysym(&evt.xkey, 0);
-
-                       case KeyRelease:
-                               *is_down = 0;
-                               return g_xstuff.pXLookupKeysym(&evt.xkey, 0);
-                               // printf("press %d\n", evt.xkey.keycode);
+               case Expose:
+                       while (g_xstuff.pXCheckTypedEvent(g_xstuff.display, Expose, &evt))
+                               ;
+                       break;
+
+               case KeyPress:
+                       keysym = g_xstuff.pXLookupKeysym(&evt.xkey, 0);
+                       if (key_cb != NULL)
+                               key_cb(cb_arg, keysym, 1);
+                       break;
+
+               case KeyRelease:
+                       keysym = g_xstuff.pXLookupKeysym(&evt.xkey, 0);
+                       if (key_cb != NULL)
+                               key_cb(cb_arg, keysym, 0);
+                       break;
+
+               case ButtonPress:
+                       if (mouseb_cb != NULL)
+                               mouseb_cb(cb_arg, evt.xbutton.x, evt.xbutton.y,
+                                         evt.xbutton.button, 1);
+                       break;
+
+               case ButtonRelease:
+                       if (mouseb_cb != NULL)
+                               mouseb_cb(cb_arg, evt.xbutton.x, evt.xbutton.y,
+                                         evt.xbutton.button, 0);
+                       break;
+
+               case MotionNotify:
+                       if (mousem_cb != NULL)
+                               mousem_cb(cb_arg, evt.xmotion.x, evt.xmotion.y);
+                       break;
                }
        }
-
-       return NoSymbol;
 }
 
 static void x11h_wait_vmstate(void)
@@ -221,7 +249,7 @@ static void x11h_wait_vmstate(void)
                usleep(200000);
        }
 
-       printf("timeout waiting for wm_state change\n");
+       fprintf(stderr, PFX "timeout waiting for wm_state change\n");
 }
 
 static int x11h_minimize(void)
@@ -347,40 +375,49 @@ static void tty_end(void)
        g_kbdfd = -1;
 }
 
-int xenv_init(const char *window_title)
+int xenv_init(int *xenv_flags, const char *window_title)
 {
        int ret;
 
-       ret = x11h_init(window_title);
+       ret = x11h_init(xenv_flags, window_title);
        if (ret == 0)
-               return 0;
+               goto out;
 
+       if (xenv_flags != NULL)
+               *xenv_flags &= ~(XENV_CAP_KEYS | XENV_CAP_MOUSE); /* TODO? */
        ret = tty_init();
        if (ret == 0)
-               return 0;
+               goto out;
 
        fprintf(stderr, PFX "error: both x11h_init and tty_init failed\n");
-       return -1;
+       ret = -1;
+out:
+       return ret;
 }
 
-int xenv_update(int *is_down)
+int xenv_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
+               int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
+               int (*mousem_cb)(void *cb_arg, int x, int y),
+               void *cb_arg)
 {
-       if (g_xstuff.display)
-               return x11h_update(is_down);
+       if (g_xstuff.display) {
+               x11h_update(key_cb, mouseb_cb, mousem_cb, cb_arg);
+               return 0;
+       }
 
        // TODO: read tty?
        return -1;
 }
 
-/* blocking minimize until user maximazes again */
+/* blocking minimize until user maximizes again */
 int xenv_minimize(void)
 {
-       int ret, dummy;
+       int ret;
 
        if (g_xstuff.display) {
-               xenv_update(&dummy);
+               xenv_update(NULL, NULL, NULL, NULL);
                ret = x11h_minimize();
-               xenv_update(&dummy);
+               xenv_update(NULL, NULL, NULL, NULL);
                return ret;
        }
 
index 1afad9d..6abda19 100644 (file)
@@ -1,6 +1,18 @@
 
-int  xenv_init(const char *window_title);
-int  xenv_update(int *is_down);
+#define XENV_CAP_KEYS  (1<<0)
+#define XENV_CAP_MOUSE (1<<1)
+
+/* xenv_flags specify if we need keys and mouse,
+ * on return, flag is removed if input is not available */
+int  xenv_init(int *xenv_flags, const char *window_title);
+
+/* read events from X, calling key_cb for key, mouseb_cb for mouse button
+ * and mousem_cb for mouse motion events */
+int  xenv_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
+                int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
+                int (*mousem_cb)(void *cb_arg, int x, int y),
+                void *cb_arg);
+
 int  xenv_minimize(void);
 void xenv_finish(void);
 
index 3a6a948..4ab7cf0 100644 (file)
@@ -90,15 +90,12 @@ int omap_enable_layer(int enabled)
 
 void plat_video_menu_enter(int is_rom_loaded)
 {
-       int dummy;
-
        g_menuscreen_ptr = vout_fbdev_resize(main_fb,
                g_menuscreen_w, g_menuscreen_h, 16, 0, 0, 0, 0, 3);
        if (g_menuscreen_ptr == NULL)
                fprintf(stderr, "warning: vout_fbdev_resize failed\n");
 
-       // hmh
-       xenv_update(&dummy);
+       xenv_update(NULL, NULL, NULL, NULL);
 }
 
 void plat_video_menu_begin(void)
@@ -165,7 +162,7 @@ void plat_init(void)
                exit(1);
        }
 
-       xenv_init("PCSX-ReARMed");
+       xenv_init(NULL, "PCSX-ReARMed");
 
        w = h = 0;
        main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);