support app icon by reusing x11 sdl code
authornotaz <notasas@gmail.com>
Thu, 13 Jun 2013 22:03:59 +0000 (01:03 +0300)
committernotaz <notasas@gmail.com>
Thu, 13 Jun 2013 22:17:58 +0000 (01:17 +0300)
configure.in
src/video/omapdss/SDL_x11reuse.c [new file with mode: 0644]
src/video/omapdss/SDL_x11reuse.h [new file with mode: 0644]
src/video/omapdss/linux/xenv.c
src/video/omapdss/linux/xenv.h
src/video/omapdss/osdl.h
src/video/omapdss/osdl_video.c
src/video/omapdss/sdlif.c

index 1a339a8..209f6bc 100644 (file)
@@ -1638,6 +1638,7 @@ AC_HELP_STRING([--enable-video-omapdss], [use OMAP DSS2 video driver [[default=y
         SOURCES="$SOURCES $srcdir/src/video/omapdss/osdl_input.c"
         SOURCES="$SOURCES $srcdir/src/video/omapdss/osdl_video.c"
         SOURCES="$SOURCES $srcdir/src/video/omapdss/config.c"
+        SOURCES="$SOURCES $srcdir/src/video/omapdss/SDL_x11reuse.c"
         SOURCES="$SOURCES $srcdir/src/video/omapdss/linux/fbdev.c"
         SOURCES="$SOURCES $srcdir/src/video/omapdss/linux/xenv.c"
         have_video=yes
diff --git a/src/video/omapdss/SDL_x11reuse.c b/src/video/omapdss/SDL_x11reuse.c
new file mode 100644 (file)
index 0000000..d95bd65
--- /dev/null
@@ -0,0 +1,62 @@
+/* this file is all aobut reusing stock SDL's x11 functions */
+
+#include "SDL_x11reuse.h"
+#define SDL_PrivateVideoData SDL_x11_PrivateVideoData
+#include "../x11/SDL_x11video.h"
+
+/* mess from SDL_x11video.h */
+#undef SDL_Display
+#undef GFX_Display
+#undef SDL_Screen
+#undef WMwindow
+#undef SDL_iconcolors
+
+struct x11reuse_context {
+       SDL_VideoDevice fake_device;
+       struct SDL_x11_PrivateVideoData fake_x11private;
+};
+
+struct x11reuse_context *x11reuse_init(void)
+{
+       struct x11reuse_context *retval;
+       int ret;
+
+       ret = SDL_X11_LoadSymbols();
+       if (ret == 0) {
+               fprintf(stderr, "omapsdl: SDL_X11_LoadSymbols failed\n");
+               return NULL;
+       }
+
+       retval = calloc(1, sizeof(*retval));
+       if (retval == NULL)
+               return NULL;
+
+       retval->fake_device.hidden = &retval->fake_x11private;
+       return retval;
+}
+
+void x11reuse_SetCaption(struct x11reuse_context *context,
+       void *display, int screen, void *window,
+       const char *title, const char *icon)
+{
+       if (context == NULL)
+               return;
+
+       context->fake_x11private.X11_Display =
+       context->fake_x11private.GFX_Display = display;
+       context->fake_x11private.WMwindow = (Window)window;
+       X11_SetCaptionNoLock(&context->fake_device, title, icon);
+}
+
+void x11reuse_SetIcon(struct x11reuse_context *context,
+       void *display, int screen, void *window,
+       void *icon, void *mask)
+{
+       if (context == NULL)
+               return;
+
+       context->fake_x11private.X11_Display =
+       context->fake_x11private.GFX_Display = display;
+       context->fake_x11private.WMwindow = (Window)window;
+       X11_SetIcon(&context->fake_device, icon, mask);
+}
diff --git a/src/video/omapdss/SDL_x11reuse.h b/src/video/omapdss/SDL_x11reuse.h
new file mode 100644 (file)
index 0000000..0ab8a37
--- /dev/null
@@ -0,0 +1,8 @@
+
+struct x11reuse_context *x11reuse_init(void);
+void x11reuse_SetCaption(struct x11reuse_context *context,
+       void *display, int screen, void *window,
+       const char *title, const char *icon);
+void x11reuse_SetIcon(struct x11reuse_context *context,
+       void *display, int screen, void *window,
+       void *icon, void *mask);
index 6b93118..5a81cc7 100644 (file)
@@ -448,6 +448,20 @@ int xenv_keycode_to_keysym(int kc, int shift)
        return -1;
 }
 
+int xenv_get_window(void **display, int *screen, void **window)
+{
+       *display = *window = NULL;
+       *screen = 0;
+       if (g_xstuff.display && g_xstuff.window) {
+               *display = g_xstuff.display;
+               *screen = DefaultScreen(g_xstuff.display);
+               *window = (void *)g_xstuff.window;
+               return 0;
+       }
+
+       return -1;
+}
+
 void xenv_finish(void)
 {
        // TODO: cleanup X?
index 05dd457..ec41cf7 100644 (file)
@@ -15,5 +15,6 @@ int  xenv_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
 
 int  xenv_minimize(void);
 int  xenv_keycode_to_keysym(int kc, int shift);
+int  xenv_get_window(void **display, int *screen, void **window);
 void xenv_finish(void);
 
index 6b78977..6a1789c 100644 (file)
@@ -25,6 +25,8 @@
 #define dbg(...)
 #endif
 
+struct x11reuse_context;
+
 struct SDL_PrivateVideoData {
        struct vout_fbdev *fbdev;
        void *front_buffer;
@@ -38,6 +40,7 @@ struct SDL_PrivateVideoData {
        /* phys -> layer coord multipliers (16.16) */
        int ts_xmul, ts_ymul;
        /* misc/config */
+       struct x11reuse_context *x11reuse_context;
        unsigned int xenv_up:1;
        unsigned int xenv_mouse:1;
        unsigned int app_uses_flip:1;
@@ -46,6 +49,9 @@ struct SDL_PrivateVideoData {
        unsigned int cfg_force_directbuf:1;
        unsigned int cfg_no_ts_translate:1;
        unsigned int cfg_ts_force_tslib:1;
+       /* delayed icon surface */
+       struct SDL_Surface *delayed_icon;
+       void *delayed_icon_mask;
 };
 
 void *osdl_video_set_mode(struct SDL_PrivateVideoData *pdata,
@@ -56,6 +62,7 @@ void *osdl_video_flip(struct SDL_PrivateVideoData *pdata);
 void *osdl_video_get_active_buffer(struct SDL_PrivateVideoData *pdata);
 int   osdl_video_detect_screen(struct SDL_PrivateVideoData *pdata);
 int   osdl_video_pause(struct SDL_PrivateVideoData *pdata, int is_pause);
+int   osdl_video_get_window(void **display, int *screen, void **window);
 void  osdl_video_finish(struct SDL_PrivateVideoData *pdata);
 
 void omapsdl_input_init(void);
index 5a291a7..bf42a00 100644 (file)
@@ -525,6 +525,11 @@ int osdl_video_pause(struct SDL_PrivateVideoData *pdata, int is_pause)
        return 0;
 }
 
+int osdl_video_get_window(void **display, int *screen, void **window)
+{
+       return xenv_get_window(display, screen, window);
+}
+
 void osdl_video_finish(struct SDL_PrivateVideoData *pdata)
 {
        static const char *fbname;
index 9e374ef..b5cadbe 100644 (file)
@@ -13,6 +13,7 @@
 #include "../SDL_pixels_c.h"
 #include "../../events/SDL_events_c.h"
 
+#include "SDL_x11reuse.h"
 #include "linux/xenv.h"
 #include "osdl.h"
 
@@ -31,6 +32,7 @@ static void omap_free(SDL_VideoDevice *device)
 
 static int omap_VideoInit(SDL_VideoDevice *this, SDL_PixelFormat *vformat)
 {
+       struct SDL_PrivateVideoData *pdata = this->hidden;
        const char *tmp;
        int w, h, ret;
 
@@ -40,21 +42,23 @@ static int omap_VideoInit(SDL_VideoDevice *this, SDL_PixelFormat *vformat)
        vformat->BitsPerPixel = 16;
 
        omapsdl_input_init();
-       omapsdl_config(this->hidden);
+       omapsdl_config(pdata);
 
        tmp = getenv("SDL_OMAP_DEFAULT_MODE");
        if (tmp != NULL && sscanf(tmp, "%dx%d", &w, &h) == 2) {
                this->info.current_w = w;
                this->info.current_h = h;
        }
-       else if (osdl_video_detect_screen(this->hidden) == 0) {
-               this->info.current_w = this->hidden->phys_w;
-               this->info.current_h = this->hidden->phys_h;
+       else if (osdl_video_detect_screen(pdata) == 0) {
+               this->info.current_w = pdata->phys_w;
+               this->info.current_h = pdata->phys_h;
        }
 
        this->handles_any_size = 1;
        this->info.hw_available = 1;
 
+       pdata->x11reuse_context = x11reuse_init();
+
        return 0;
 }
 
@@ -185,6 +189,17 @@ static SDL_Surface *omap_SetVideoMode(SDL_VideoDevice *this, SDL_Surface *curren
                pdata->ts_ymul = (v_height << 16) / pdata->layer_h;
        }
 
+       if (pdata->delayed_icon != NULL) {
+               this->SetIcon(this, pdata->delayed_icon,
+                       pdata->delayed_icon_mask);
+               SDL_FreeSurface(pdata->delayed_icon);
+               pdata->delayed_icon = NULL;
+               if (pdata->delayed_icon_mask) {
+                       free(pdata->delayed_icon_mask);
+                       pdata->delayed_icon_mask = NULL;
+               }
+       }
+
        return current;
 }
 
@@ -441,6 +456,55 @@ static void omap_PumpEvents(SDL_VideoDevice *this)
                read_tslib ? ts_event_cb : NULL, this);
 }
 
+static void omap_SetCaption(SDL_VideoDevice *this, const char *title, const char *icon)
+{
+       void *display = NULL, *window = NULL;
+       int screen = 0;
+       int ret;
+
+       ret = osdl_video_get_window(&display, &screen, &window);
+       if (ret == 0) {
+               x11reuse_SetCaption(this->hidden->x11reuse_context,
+                       display, screen, window, title, icon);
+       }
+}
+
+static void omap_SetIcon(SDL_VideoDevice *this, SDL_Surface *icon, Uint8 *mask)
+{
+       struct SDL_PrivateVideoData *pdata = this->hidden;
+       void *display = NULL, *window = NULL;
+       int screen = 0;
+       int ret;
+
+       ret = osdl_video_get_window(&display, &screen, &window);
+       if (ret == 0) {
+               x11reuse_SetIcon(pdata->x11reuse_context,
+                       display, screen, window, icon, mask);
+       }
+       else {
+               SDL_Surface *old_icon = pdata->delayed_icon;
+               void *old_icon_mask = pdata->delayed_icon_mask;
+               int mask_size = ((icon->w + 7) / 8) * icon->h;
+
+               pdata->delayed_icon = SDL_ConvertSurface(icon,
+                                       icon->format, icon->flags);
+               if (pdata->delayed_icon != NULL) {
+                       memcpy(pdata->delayed_icon->pixels, icon->pixels,
+                               icon->pitch * icon->h);
+               }
+               if (mask != NULL) {
+                       pdata->delayed_icon_mask = malloc(mask_size);
+                       if (pdata->delayed_icon_mask)
+                               memcpy(pdata->delayed_icon_mask, mask, mask_size);
+               }
+
+               if (old_icon != NULL)
+                       SDL_FreeSurface(old_icon);
+               if (old_icon_mask)
+                       free(old_icon_mask);
+       }
+}
+
 static SDL_VideoDevice *omap_create(int devindex)
 {
        SDL_VideoDevice *this;
@@ -464,6 +528,8 @@ static SDL_VideoDevice *omap_create(int devindex)
        this->VideoQuit = omap_VideoQuit;
        this->InitOSKeymap = omap_InitOSKeymap;
        this->PumpEvents = omap_PumpEvents;
+       this->SetCaption = omap_SetCaption;
+       this->SetIcon = omap_SetIcon;
        this->free = omap_free;
 
        return this;