+static unsigned long
+grayscale(unsigned long color)
+{
+ int red;
+ int green;
+ int blue;
+ int total;
+ int gray_r;
+ int gray_g;
+ int gray_b;
+
+ if (!grayscale_p)
+ return color;
+ if (!transparent)
+ return color;
+ if ((rmask == 0) || (gmask == 0) || (bmask == 0))
+ return color;
+
+ red = ((color >> rshift) & rmask);
+ green = ((color >> gshift) & gmask);
+ blue = ((color >> bshift) & bmask);
+ total = red * gmask * bmask + green * rmask * bmask + blue * rmask * gmask;
+
+ gray_r = total / (3 * gmask * bmask);
+ if (gray_r < 0)
+ gray_r = 0;
+ if (gray_r > rmask)
+ gray_r = rmask;
+
+ gray_g = total / (3 * rmask * bmask);
+ if (gray_g < 0)
+ gray_g = 0;
+ if (gray_g > gmask)
+ gray_g = gmask;
+
+ gray_b = total / (3 * rmask * gmask);
+ if (gray_b < 0)
+ gray_b = 0;
+ if (gray_b > bmask)
+ gray_b = bmask;
+
+ return ((unsigned long)
+ ((gray_r << rshift) | (gray_g << gshift) | (gray_b << bshift)));
+}
+
+