diff --git a/Makefile b/Makefile index 69f21d895e..71bd24524d 100644 --- a/Makefile +++ b/Makefile @@ -342,11 +342,13 @@ install: $(TARGET) mkdir -p $(DESTDIR)$(PREFIX)/bin 2>/dev/null || /bin/true mkdir -p $(DESTDIR)/etc 2>/dev/null || /bin/true mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1 2>/dev/null || /bin/true + mkdir -p $(DESTDIR)$(PREFIX)/share/icons 2>/dev/null || /bin/true install -m755 $(TARGET) $(DESTDIR)$(PREFIX)/bin install -m644 retroarch.cfg $(DESTDIR)/etc/retroarch.cfg install -m644 docs/retroarch.1 $(DESTDIR)$(PREFIX)/share/man/man1 install -m644 docs/retroarch-joyconfig.1 $(DESTDIR)$(PREFIX)/share/man/man1 install -m755 retroarch-zip $(DESTDIR)$(PREFIX)/bin + install -m644 media/retroarch.png $(DESTDIR)/usr/share/icons uninstall: rm -f $(DESTDIR)$(PREFIX)/bin/retroarch @@ -355,6 +357,7 @@ uninstall: rm -f $(DESTDIR)/etc/retroarch.cfg rm -f $(DESTDIR)$(PREFIX)/share/man/man1/retroarch.1 rm -f $(DESTDIR)$(PREFIX)/share/man/man1/retroarch-joyconfig.1 + rm -f $(DESTDIR)/usr/share/icons/retroarch.png clean: rm -f *.o diff --git a/gfx/context/glx_ctx.c b/gfx/context/glx_ctx.c index 52ee32e023..cab05e1614 100644 --- a/gfx/context/glx_ctx.c +++ b/gfx/context/glx_ctx.c @@ -293,6 +293,7 @@ static bool gfx_ctx_set_video_mode( XSetWindowBackground(g_dpy, g_win, 0); gfx_ctx_update_window_title(true); + x11_set_window_icon(g_dpy, g_win); if (fullscreen) x11_hide_mouse(g_dpy, g_win); diff --git a/gfx/context/x11_common.c b/gfx/context/x11_common.c index c4ed2c4028..b0f7a02d2f 100644 --- a/gfx/context/x11_common.c +++ b/gfx/context/x11_common.c @@ -17,6 +17,8 @@ #include "x11_common.h" #include #include +#include +#include "../image.h" #include "../../general.h" void x11_hide_mouse(Display *dpy, Window win) @@ -47,6 +49,7 @@ void x11_hide_mouse(Display *dpy, Window win) static Atom XA_NET_WM_STATE; static Atom XA_NET_WM_STATE_FULLSCREEN; static Atom XA_NET_MOVERESIZE_WINDOW; +static Atom XA_NET_WM_ICON; #define XA_INIT(x) XA##x = XInternAtom(dpy, #x, False) #define _NET_WM_STATE_ADD 1 #define MOVERESIZE_GRAVITY_CENTER 5 @@ -57,12 +60,6 @@ void x11_windowed_fullscreen(Display *dpy, Window win) XA_INIT(_NET_WM_STATE); XA_INIT(_NET_WM_STATE_FULLSCREEN); - if (!XA_NET_WM_STATE || !XA_NET_WM_STATE_FULLSCREEN) - { - RARCH_ERR("[X11]: Cannot set windowed fullscreen.\n"); - return; - } - XEvent xev = {0}; xev.xclient.type = ClientMessage; @@ -83,11 +80,6 @@ void x11_move_window(Display *dpy, Window win, int x, int y, unsigned width, unsigned height) { XA_INIT(_NET_MOVERESIZE_WINDOW); - if (!XA_NET_MOVERESIZE_WINDOW) - { - RARCH_ERR("[X11]: Cannot move window.\n"); - return; - } XEvent xev = {0}; @@ -105,6 +97,40 @@ void x11_move_window(Display *dpy, Window win, int x, int y, &xev); } +void x11_set_window_icon(Display *dpy, Window win) +{ + XA_INIT(_NET_WM_ICON); + + const char *path = "/usr/share/icons/retroarch.png"; + + struct texture_image img; + if (texture_image_load(path, &img)) + { + size_t propsize = img.width * img.height + 2; + unsigned long *propdata = (unsigned long*)calloc(sizeof(unsigned long), propsize); // X11 wants a long array for '32-bit' :(. + if (!propdata) + { + free(img.pixels); + return; + } + + propdata[0] = img.width; + propdata[1] = img.height; + + unsigned img_size = img.width * img.height; + for (unsigned i = 0; i < img_size; i++) + propdata[i + 2] = img.pixels[i]; + free(img.pixels); + + RARCH_LOG("[X11]: Setting window icon: %s\n", path); + XChangeProperty(dpy, win, XA_NET_WM_ICON, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)propdata, propsize); + XFlush(dpy); + free(propdata); + } + else + RARCH_ERR("[X11]: Failed to load icon from: %s\n", path); +} + void x11_suspend_screensaver(Window wnd) { char cmd[64]; diff --git a/gfx/context/x11_common.h b/gfx/context/x11_common.h index 5c5b4e543e..222f16357e 100644 --- a/gfx/context/x11_common.h +++ b/gfx/context/x11_common.h @@ -38,6 +38,8 @@ bool x11_enter_fullscreen(Display *dpy, unsigned width, unsigned height, XF86Vid void x11_exit_fullscreen(Display *dpy, XF86VidModeModeInfo *desktop_mode); void x11_move_window(Display *dpy, Window win, int x, int y, unsigned width, unsigned height); +void x11_set_window_icon(Display *dpy, Window win); + #ifdef HAVE_XINERAMA bool x11_get_xinerama_coord(Display *dpy, int screen, int *x, int *y, unsigned *w, unsigned *h); diff --git a/gfx/context/xegl_ctx.c b/gfx/context/xegl_ctx.c index 8c6638320f..587ccfde53 100644 --- a/gfx/context/xegl_ctx.c +++ b/gfx/context/xegl_ctx.c @@ -340,6 +340,7 @@ static bool gfx_ctx_set_video_mode( goto error; gfx_ctx_update_window_title(true); + x11_set_window_icon(g_dpy, g_win); if (fullscreen) x11_hide_mouse(g_dpy, g_win); diff --git a/gfx/xvideo.c b/gfx/xvideo.c index 2194b01757..b7532e1ddd 100644 --- a/gfx/xvideo.c +++ b/gfx/xvideo.c @@ -484,6 +484,8 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo if (gfx_window_title(buf, sizeof(buf))) XStoreName(xv->display, xv->window, buf); + x11_set_window_icon(xv->display, xv->window); + if (video->fullscreen) set_fullscreen(xv); hide_mouse(xv); diff --git a/media/retroarch.png b/media/retroarch.png new file mode 100644 index 0000000000..4ac5100731 Binary files /dev/null and b/media/retroarch.png differ