From: divverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Fri, 27 Aug 2010 05:43:07 +0000 (+0000)
Subject: GLX: use _NET_WM_ICON additionally to the xpm icon for most current window managers
X-Git-Tag: xonotic-v0.1.0preview~230^2~62
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=ff0866cefb73303f135a4e27eec21e8a24662912;p=xonotic%2Fdarkplaces.git

GLX: use _NET_WM_ICON additionally to the xpm icon for most current window managers
_NET_WM_ICON is generated from darkplaces-icon.tga, darkplaces-icon2.tga, darkplaces-icon3.tga in this order
NOTE: at least GNOME displays the first icon only, so this one should have a nice resolution like 64x64

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10421 d7cf8633-e32d-0410-b094-e92efae38249
---

diff --git a/quakedef.h b/quakedef.h
index dd06836f..9e62f0d2 100644
--- a/quakedef.h
+++ b/quakedef.h
@@ -88,6 +88,8 @@ extern char engineversion[128];
 #define	MAX_LEVELNETWORKEYES	0 // no portal support
 #define	MAX_OCCLUSION_QUERIES	256
 
+#define MAX_NETWM_ICON 1026 // one 32x32
+
 #define	MAX_WATERPLANES			2
 #define	MAX_CUBEMAPS			64
 #define	MAX_EXPLOSIONS			8
@@ -152,6 +154,8 @@ extern char engineversion[128];
 #define	MAX_LEVELNETWORKEYES	512 ///< max number of locations that can be added to pvs when culling network entities (must be at least 2 for prediction)
 #define	MAX_OCCLUSION_QUERIES	4096 ///< max number of GL_ARB_occlusion_query objects that can be used in one frame
 
+#define MAX_NETWM_ICON 352822 // 16x16, 22x22, 24x24, 32x32, 48x48, 64x64, 128x128, 256x256, 512x512
+
 #define	MAX_WATERPLANES			16 ///< max number of water planes visible (each one causes additional view renders)
 #define	MAX_CUBEMAPS			256 ///< max number of cubemap textures loaded for light filters
 #define	MAX_EXPLOSIONS			64 ///< max number of explosion shell effects active at once (not particle related)
diff --git a/vid_glx.c b/vid_glx.c
index e1b4bc72..342e52db 100644
--- a/vid_glx.c
+++ b/vid_glx.c
@@ -41,6 +41,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 // get the Uchar type
 #include "utf8lib.h"
+#include "image.h"
 
 #include "nexuiz.xpm"
 #include "darkplaces.xpm"
@@ -86,6 +87,8 @@ Atom wm_delete_window_atom;
 Atom net_wm_state_atom;
 Atom net_wm_state_hidden_atom;
 Atom net_wm_state_fullscreen_atom;
+Atom net_wm_icon;
+Atom cardinal;
 
 #define KEY_MASK (KeyPressMask | KeyReleaseMask)
 #define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
@@ -805,7 +808,7 @@ void VID_BuildGLXAttrib(int *attrib, qboolean stencil, qboolean stereobuffer, in
 
 qboolean VID_InitMode(viddef_mode_t *mode)
 {
-	int i;
+	int i, j;
 	int attrib[32];
 	XSetWindowAttributes attr;
 	XClassHint *clshints;
@@ -817,6 +820,7 @@ qboolean VID_InitMode(viddef_mode_t *mode)
 	const char *drivername;
 	char *xpm;
 	char **idata;
+	unsigned char *data;
 
 	vid_isfullscreen = false;
 	vid_isnetwmfullscreen = false;
@@ -852,6 +856,8 @@ qboolean VID_InitMode(viddef_mode_t *mode)
 	net_wm_state_atom = XInternAtom(vidx11_display, "_NET_WM_STATE", false);
 	net_wm_state_fullscreen_atom = XInternAtom(vidx11_display, "_NET_WM_STATE_FULLSCREEN", false);
 	net_wm_state_hidden_atom = XInternAtom(vidx11_display, "_NET_WM_STATE_HIDDEN", false);
+	net_wm_icon = XInternAtom(vidx11_display, "_NET_WM_ICON", false);
+	cardinal = XInternAtom(vidx11_display, "CARDINAL", false);
 
 	// make autorepeat send keypress/keypress/.../keyrelease instead of intervening keyrelease
 	XkbSetDetectableAutoRepeat(vidx11_display, true, NULL);
@@ -999,6 +1005,36 @@ qboolean VID_InitMode(viddef_mode_t *mode)
 
 	win = XCreateWindow(vidx11_display, root, 0, 0, mode->width, mode->height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr);
 
+	data = loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
+	if(data)
+	{
+		// use _NET_WM_ICON too
+		static long netwm_icon[MAX_NETWM_ICON];
+		int pos = 0;
+		int i = 1;
+
+		while(data)
+		{
+			if(pos + 2 * image_width * image_height < MAX_NETWM_ICON)
+			{
+				netwm_icon[pos++] = image_width;
+				netwm_icon[pos++] = image_height;
+				for(i = 0; i < image_height; ++i)
+					for(j = 0; j < image_width; ++j)
+						netwm_icon[pos++] = BuffLittleLong(&data[(i*image_width+j)*4]);
+			}
+			else
+			{
+				Con_Printf("Skipping NETWM icon #%d because there is no space left\n", i);
+			}
+			++i;
+			Mem_Free(data);
+			data = loadimagepixelsbgra(va("darkplaces-icon%d", i), false, false, false, NULL);
+		}
+		XChangeProperty(vidx11_display, win, net_wm_icon, cardinal, 32, PropModeReplace, (const unsigned char *) netwm_icon, pos);
+	}
+
+	// fallthrough for old window managers
 	xpm = (char *) FS_LoadFile("darkplaces-icon.xpm", tempmempool, false, NULL);
 	idata = NULL;
 	if(xpm)