From ee7e6b2d8bc82029aac405d13f719f4532851224 Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 14 Jun 2013 01:03:59 +0300 Subject: [PATCH] support app icon by reusing x11 sdl code --- configure.in | 1 + src/video/omapdss/SDL_x11reuse.c | 62 ++++++++++++++++++++++++++ src/video/omapdss/SDL_x11reuse.h | 8 ++++ src/video/omapdss/linux/xenv.c | 14 ++++++ src/video/omapdss/linux/xenv.h | 1 + src/video/omapdss/osdl.h | 7 +++ src/video/omapdss/osdl_video.c | 5 +++ src/video/omapdss/sdlif.c | 74 ++++++++++++++++++++++++++++++-- 8 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 src/video/omapdss/SDL_x11reuse.c create mode 100644 src/video/omapdss/SDL_x11reuse.h diff --git a/configure.in b/configure.in index 1a339a8..209f6bc 100644 --- a/configure.in +++ b/configure.in @@ -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 index 0000000..d95bd65 --- /dev/null +++ b/src/video/omapdss/SDL_x11reuse.c @@ -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 index 0000000..0ab8a37 --- /dev/null +++ b/src/video/omapdss/SDL_x11reuse.h @@ -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); diff --git a/src/video/omapdss/linux/xenv.c b/src/video/omapdss/linux/xenv.c index 6b93118..5a81cc7 100644 --- a/src/video/omapdss/linux/xenv.c +++ b/src/video/omapdss/linux/xenv.c @@ -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? diff --git a/src/video/omapdss/linux/xenv.h b/src/video/omapdss/linux/xenv.h index 05dd457..ec41cf7 100644 --- a/src/video/omapdss/linux/xenv.h +++ b/src/video/omapdss/linux/xenv.h @@ -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); diff --git a/src/video/omapdss/osdl.h b/src/video/omapdss/osdl.h index 6b78977..6a1789c 100644 --- a/src/video/omapdss/osdl.h +++ b/src/video/omapdss/osdl.h @@ -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); diff --git a/src/video/omapdss/osdl_video.c b/src/video/omapdss/osdl_video.c index 5a291a7..bf42a00 100644 --- a/src/video/omapdss/osdl_video.c +++ b/src/video/omapdss/osdl_video.c @@ -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; diff --git a/src/video/omapdss/sdlif.c b/src/video/omapdss/sdlif.c index 9e374ef..b5cadbe 100644 --- a/src/video/omapdss/sdlif.c +++ b/src/video/omapdss/sdlif.c @@ -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; -- 2.39.5