10bbfda8aSnia/*
20bbfda8aSnia * Builtin bitmap image generation/lookup.
30bbfda8aSnia */
40bbfda8aSnia
50bbfda8aSnia#include "ctwm.h"
60bbfda8aSnia
70bbfda8aSnia#include <stdio.h>
80bbfda8aSnia#include <stdlib.h>
90bbfda8aSnia
100bbfda8aSnia#include <X11/Xmu/Drawing.h>
110bbfda8aSnia
120bbfda8aSnia#include "screen.h"
130bbfda8aSnia#include "drawing.h"
140bbfda8aSnia#include "icons_builtin.h"
150bbfda8aSnia
160bbfda8aSnia#include "image.h"
170bbfda8aSnia#include "image_bitmap_builtin.h"
180bbfda8aSnia
190bbfda8aSnia
200bbfda8aSnia/*
210bbfda8aSnia * Firstly, the plain built-in titlebar symbols.  These are the ones
220bbfda8aSnia * specified with names like ":resize".  For various reasons, these
230bbfda8aSnia * currently return Pixmap's, unlike most of our other builtins that
240bbfda8aSnia * generate Image's.  Possible cleanup candidate.
250bbfda8aSnia */
260bbfda8aSnia#define DEF_BI_PPM(nm) Pixmap nm(unsigned int *widthp, unsigned int *heightp)
270bbfda8aSniastatic DEF_BI_PPM(CreateXLogoPixmap);
280bbfda8aSniastatic DEF_BI_PPM(CreateResizePixmap);
290bbfda8aSniastatic DEF_BI_PPM(CreateQuestionPixmap);
300bbfda8aSniastatic DEF_BI_PPM(CreateMenuPixmap);
310bbfda8aSniastatic DEF_BI_PPM(CreateDotPixmap);
320bbfda8aSnia
330bbfda8aSnia
340bbfda8aSnia
350bbfda8aSnia/*
360bbfda8aSnia * Look up and return a ":something" (not a ":xpm:something").
370bbfda8aSnia *
380bbfda8aSnia * Names of the form :name refer to hardcoded images that are scaled to
390bbfda8aSnia * look nice in title buttons.  Eventually, it would be nice to put in a
400bbfda8aSnia * menu symbol as well....
410bbfda8aSnia */
420bbfda8aSniaPixmap
430bbfda8aSniaget_builtin_plain_pixmap(const char *name, unsigned int *widthp,
440bbfda8aSnia                         unsigned int *heightp)
450bbfda8aSnia{
460bbfda8aSnia	int i;
470bbfda8aSnia	static struct {
480bbfda8aSnia		char *name;
490bbfda8aSnia		DEF_BI_PPM((*proc));
500bbfda8aSnia	} pmtab[] = {
510bbfda8aSnia		/* Lookup table for our various default pixmaps */
520bbfda8aSnia		{ TBPM_DOT,         CreateDotPixmap },
530bbfda8aSnia		{ TBPM_ICONIFY,     CreateDotPixmap },
540bbfda8aSnia		{ TBPM_RESIZE,      CreateResizePixmap },
550bbfda8aSnia		{ TBPM_XLOGO,       CreateXLogoPixmap },
560bbfda8aSnia		{ TBPM_DELETE,      CreateXLogoPixmap },
570bbfda8aSnia		{ TBPM_MENU,        CreateMenuPixmap },
580bbfda8aSnia		{ TBPM_QUESTION,    CreateQuestionPixmap },
590bbfda8aSnia	};
600bbfda8aSnia
610bbfda8aSnia	/* Seatbelts */
620bbfda8aSnia	if(!name || name[0] != ':') {
630bbfda8aSnia		return None;
640bbfda8aSnia	}
650bbfda8aSnia	if(!widthp || !heightp) {
660bbfda8aSnia		return None;
670bbfda8aSnia	}
680bbfda8aSnia
690bbfda8aSnia
700bbfda8aSnia	/* Find it */
710bbfda8aSnia	for(i = 0; i < (sizeof pmtab) / (sizeof pmtab[0]); i++) {
720bbfda8aSnia		if(strcasecmp(pmtab[i].name, name) == 0) {
730bbfda8aSnia			Pixmap pm = (*pmtab[i].proc)(widthp, heightp);
740bbfda8aSnia			if(pm == None) {
750bbfda8aSnia				fprintf(stderr, "%s:  unable to build bitmap \"%s\"\n",
760bbfda8aSnia				        ProgramName, name);
770bbfda8aSnia				return None;
780bbfda8aSnia			}
790bbfda8aSnia			return pm;
800bbfda8aSnia		}
810bbfda8aSnia	}
820bbfda8aSnia
830bbfda8aSnia	/* Didn't find it */
840bbfda8aSnia	fprintf(stderr, "%s:  no such built-in bitmap \"%s\"\n",
850bbfda8aSnia	        ProgramName, name);
860bbfda8aSnia	return None;
870bbfda8aSnia}
880bbfda8aSnia
890bbfda8aSnia
900bbfda8aSnia/*
910bbfda8aSnia * Individual generators for those plain pixmaps
920bbfda8aSnia */
930bbfda8aSniaDEF_BI_PPM(CreateXLogoPixmap)
940bbfda8aSnia{
950bbfda8aSnia	int h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
960bbfda8aSnia	if(h < 0) {
970bbfda8aSnia		h = 0;
980bbfda8aSnia	}
990bbfda8aSnia
1000bbfda8aSnia	*widthp = *heightp = (unsigned int) h;
1010bbfda8aSnia	if(Scr->tbpm.xlogo == None) {
1020bbfda8aSnia		GC gc, gcBack;
1030bbfda8aSnia
1040bbfda8aSnia		Scr->tbpm.xlogo = XCreatePixmap(dpy, Scr->Root, h, h, 1);
1050bbfda8aSnia		gc = XCreateGC(dpy, Scr->tbpm.xlogo, 0L, NULL);
1060bbfda8aSnia		XSetForeground(dpy, gc, 0);
1070bbfda8aSnia		XFillRectangle(dpy, Scr->tbpm.xlogo, gc, 0, 0, h, h);
1080bbfda8aSnia		XSetForeground(dpy, gc, 1);
1090bbfda8aSnia		gcBack = XCreateGC(dpy, Scr->tbpm.xlogo, 0L, NULL);
1100bbfda8aSnia		XSetForeground(dpy, gcBack, 0);
1110bbfda8aSnia
1120bbfda8aSnia		/*
1130bbfda8aSnia		 * draw the logo large so that it gets as dense as possible; then white
1140bbfda8aSnia		 * out the edges so that they look crisp
1150bbfda8aSnia		 */
1160bbfda8aSnia		XmuDrawLogo(dpy, Scr->tbpm.xlogo, gc, gcBack, -1, -1, h + 2, h + 2);
1170bbfda8aSnia		XDrawRectangle(dpy, Scr->tbpm.xlogo, gcBack, 0, 0, h - 1, h - 1);
1180bbfda8aSnia
1190bbfda8aSnia		/*
1200bbfda8aSnia		 * done drawing
1210bbfda8aSnia		 */
1220bbfda8aSnia		XFreeGC(dpy, gc);
1230bbfda8aSnia		XFreeGC(dpy, gcBack);
1240bbfda8aSnia	}
1250bbfda8aSnia	return Scr->tbpm.xlogo;
1260bbfda8aSnia}
1270bbfda8aSnia
1280bbfda8aSnia
1290bbfda8aSniaDEF_BI_PPM(CreateResizePixmap)
1300bbfda8aSnia{
1310bbfda8aSnia	int h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
1320bbfda8aSnia	if(h < 1) {
1330bbfda8aSnia		h = 1;
1340bbfda8aSnia	}
1350bbfda8aSnia
1360bbfda8aSnia	*widthp = *heightp = (unsigned int) h;
1370bbfda8aSnia	if(Scr->tbpm.resize == None) {
1380bbfda8aSnia		XPoint  points[3];
1390bbfda8aSnia		GC gc;
1400bbfda8aSnia		int w;
1410bbfda8aSnia		int lw;
1420bbfda8aSnia
1430bbfda8aSnia		/*
1440bbfda8aSnia		 * create the pixmap
1450bbfda8aSnia		 */
1460bbfda8aSnia		Scr->tbpm.resize = XCreatePixmap(dpy, Scr->Root, h, h, 1);
1470bbfda8aSnia		gc = XCreateGC(dpy, Scr->tbpm.resize, 0L, NULL);
1480bbfda8aSnia		XSetForeground(dpy, gc, 0);
1490bbfda8aSnia		XFillRectangle(dpy, Scr->tbpm.resize, gc, 0, 0, h, h);
1500bbfda8aSnia		XSetForeground(dpy, gc, 1);
1510bbfda8aSnia		lw = h / 16;
1520bbfda8aSnia		if(lw == 1) {
1530bbfda8aSnia			lw = 0;
1540bbfda8aSnia		}
1550bbfda8aSnia		XSetLineAttributes(dpy, gc, lw, LineSolid, CapButt, JoinMiter);
1560bbfda8aSnia
1570bbfda8aSnia		/*
1580bbfda8aSnia		 * draw the resize button,
1590bbfda8aSnia		 */
1600bbfda8aSnia		w = (h * 2) / 3;
1610bbfda8aSnia		points[0].x = w;
1620bbfda8aSnia		points[0].y = 0;
1630bbfda8aSnia		points[1].x = w;
1640bbfda8aSnia		points[1].y = w;
1650bbfda8aSnia		points[2].x = 0;
1660bbfda8aSnia		points[2].y = w;
1670bbfda8aSnia		XDrawLines(dpy, Scr->tbpm.resize, gc, points, 3, CoordModeOrigin);
1680bbfda8aSnia		w = w / 2;
1690bbfda8aSnia		points[0].x = w;
1700bbfda8aSnia		points[0].y = 0;
1710bbfda8aSnia		points[1].x = w;
1720bbfda8aSnia		points[1].y = w;
1730bbfda8aSnia		points[2].x = 0;
1740bbfda8aSnia		points[2].y = w;
1750bbfda8aSnia		XDrawLines(dpy, Scr->tbpm.resize, gc, points, 3, CoordModeOrigin);
1760bbfda8aSnia
1770bbfda8aSnia		/*
1780bbfda8aSnia		 * done drawing
1790bbfda8aSnia		 */
1800bbfda8aSnia		XFreeGC(dpy, gc);
1810bbfda8aSnia	}
1820bbfda8aSnia	return Scr->tbpm.resize;
1830bbfda8aSnia}
1840bbfda8aSnia
1850bbfda8aSnia
1860bbfda8aSnia#define questionmark_width 8
1870bbfda8aSnia#define questionmark_height 8
1880bbfda8aSniastatic char questionmark_bits[] = {
1890bbfda8aSnia	0x38, 0x7c, 0x64, 0x30, 0x18, 0x00, 0x18, 0x18
1900bbfda8aSnia};
1910bbfda8aSnia
1920bbfda8aSniaDEF_BI_PPM(CreateQuestionPixmap)
1930bbfda8aSnia{
1940bbfda8aSnia	*widthp = questionmark_width;
1950bbfda8aSnia	*heightp = questionmark_height;
1960bbfda8aSnia	if(Scr->tbpm.question == None) {
1970bbfda8aSnia		Scr->tbpm.question = XCreateBitmapFromData(dpy, Scr->Root,
1980bbfda8aSnia		                     questionmark_bits,
1990bbfda8aSnia		                     questionmark_width,
2000bbfda8aSnia		                     questionmark_height);
2010bbfda8aSnia	}
2020bbfda8aSnia	/*
2030bbfda8aSnia	 * this must succeed or else we are in deep trouble elsewhere
2040bbfda8aSnia	 */
2050bbfda8aSnia	return Scr->tbpm.question;
2060bbfda8aSnia}
2070bbfda8aSnia#undef questionmark_height
2080bbfda8aSnia#undef questionmark_width
2090bbfda8aSnia
2100bbfda8aSnia
2110bbfda8aSniaDEF_BI_PPM(CreateMenuPixmap)
2120bbfda8aSnia{
2130bbfda8aSnia	return (CreateMenuIcon(Scr->TBInfo.width - Scr->TBInfo.border * 2, widthp,
2140bbfda8aSnia	                       heightp));
2150bbfda8aSnia}
2160bbfda8aSnia
2170bbfda8aSniaDEF_BI_PPM(CreateDotPixmap)
2180bbfda8aSnia{
2190bbfda8aSnia	int h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
2200bbfda8aSnia
2210bbfda8aSnia	h = h * 3 / 4;
2220bbfda8aSnia	if(h < 1) {
2230bbfda8aSnia		h = 1;
2240bbfda8aSnia	}
2250bbfda8aSnia	if(!(h & 1)) {
2260bbfda8aSnia		h--;
2270bbfda8aSnia	}
2280bbfda8aSnia	*widthp = *heightp = (unsigned int) h;
2290bbfda8aSnia	if(Scr->tbpm.delete == None) {
2300bbfda8aSnia		GC  gc;
2310bbfda8aSnia		Pixmap pix;
2320bbfda8aSnia
2330bbfda8aSnia		pix = Scr->tbpm.delete = XCreatePixmap(dpy, Scr->Root, h, h, 1);
2340bbfda8aSnia		gc = XCreateGC(dpy, pix, 0L, NULL);
2350bbfda8aSnia		XSetLineAttributes(dpy, gc, h, LineSolid, CapRound, JoinRound);
2360bbfda8aSnia		XSetForeground(dpy, gc, 0L);
2370bbfda8aSnia		XFillRectangle(dpy, pix, gc, 0, 0, h, h);
2380bbfda8aSnia		XSetForeground(dpy, gc, 1L);
2390bbfda8aSnia		XDrawLine(dpy, pix, gc, h / 2, h / 2, h / 2, h / 2);
2400bbfda8aSnia		XFreeGC(dpy, gc);
2410bbfda8aSnia	}
2420bbfda8aSnia	return Scr->tbpm.delete;
2430bbfda8aSnia}
2440bbfda8aSnia
2450bbfda8aSnia#undef DEF_BI_PPM
2460bbfda8aSnia
2470bbfda8aSnia
2480bbfda8aSnia
2490bbfda8aSnia/*
2500bbfda8aSnia * Next, the "3D/scalable" builtins.  These are the ones specified with
2510bbfda8aSnia * names like ":xpm:resize".  I'm not entirely clear on how these differ
2520bbfda8aSnia * from ":resize"; they both vary by UseThreeDTitles and look the same.
2530bbfda8aSnia * But, whatever.
2540bbfda8aSnia *
2550bbfda8aSnia * These yield [ctwm struct] Image's rather than [X11 type] Pixmap's.
2560bbfda8aSnia */
2570bbfda8aSnia#define DEF_BI_SPM(nm) Image *nm(ColorPair cp)
2580bbfda8aSniastatic DEF_BI_SPM(Create3DMenuImage);
2590bbfda8aSniastatic DEF_BI_SPM(Create3DDotImage);
2600bbfda8aSniastatic DEF_BI_SPM(Create3DResizeImage);
2610bbfda8aSniastatic DEF_BI_SPM(Create3DZoomImage);
2620bbfda8aSniastatic DEF_BI_SPM(Create3DBarImage);
2630bbfda8aSniastatic DEF_BI_SPM(Create3DVertBarImage);
2640bbfda8aSniastatic DEF_BI_SPM(Create3DCrossImage);
2650bbfda8aSniastatic DEF_BI_SPM(Create3DIconifyImage);
2660bbfda8aSniastatic DEF_BI_SPM(Create3DSunkenResizeImage);
2670bbfda8aSniastatic DEF_BI_SPM(Create3DBoxImage);
2680bbfda8aSnia
2690bbfda8aSnia
2700bbfda8aSnia/*
2710bbfda8aSnia * Main lookup
2720bbfda8aSnia *
2730bbfda8aSnia * This is where we find ":xpm:something".  Note that these are _not_
2740bbfda8aSnia * XPM's, and have no relation to the configurable XPM support, which we
2750bbfda8aSnia * get with images specified as "xpm:something" (no leading colon).
2760bbfda8aSnia * That's not confusing at all.
2770bbfda8aSnia */
2780bbfda8aSniaImage *
2790bbfda8aSniaget_builtin_scalable_pixmap(const char *name, ColorPair cp)
2800bbfda8aSnia{
2810bbfda8aSnia	int    i;
2820bbfda8aSnia	static struct {
2830bbfda8aSnia		char *name;
2840bbfda8aSnia		DEF_BI_SPM((*proc));
2850bbfda8aSnia	} pmtab[] = {
2860bbfda8aSnia		/* Lookup for ":xpm:" pixmaps */
2870bbfda8aSnia		{ TBPM_3DDOT,       Create3DDotImage },
2880bbfda8aSnia		{ TBPM_3DRESIZE,    Create3DResizeImage },
2890bbfda8aSnia		{ TBPM_3DMENU,      Create3DMenuImage },
2900bbfda8aSnia		{ TBPM_3DZOOM,      Create3DZoomImage },
2910bbfda8aSnia		{ TBPM_3DBAR,       Create3DBarImage },
2920bbfda8aSnia		{ TBPM_3DVBAR,      Create3DVertBarImage },
2930bbfda8aSnia		{ TBPM_3DCROSS,     Create3DCrossImage },
2940bbfda8aSnia		{ TBPM_3DICONIFY,   Create3DIconifyImage },
2950bbfda8aSnia		{ TBPM_3DBOX,       Create3DBoxImage },
2960bbfda8aSnia		{ TBPM_3DSUNKEN_RESIZE, Create3DSunkenResizeImage },
2970bbfda8aSnia	};
2980bbfda8aSnia
2990bbfda8aSnia	/* Seatbelts */
3000bbfda8aSnia	if(!name || (strncmp(name, ":xpm:", 5) != 0)) {
3010bbfda8aSnia		return NULL;
3020bbfda8aSnia	}
3030bbfda8aSnia
3040bbfda8aSnia	for(i = 0; i < (sizeof pmtab) / (sizeof pmtab[0]); i++) {
3050bbfda8aSnia		if(strcasecmp(pmtab[i].name, name) == 0) {
3060bbfda8aSnia			Image *image = (*pmtab[i].proc)(cp);
3070bbfda8aSnia			if(image == NULL) {
3080bbfda8aSnia				fprintf(stderr, "%s:  unable to build pixmap \"%s\"\n",
3090bbfda8aSnia				        ProgramName, name);
3100bbfda8aSnia				return NULL;
3110bbfda8aSnia			}
3120bbfda8aSnia			return image;
3130bbfda8aSnia		}
3140bbfda8aSnia	}
3150bbfda8aSnia
3160bbfda8aSnia	fprintf(stderr, "%s:  no such built-in pixmap \"%s\"\n", ProgramName, name);
3170bbfda8aSnia	return NULL;
3180bbfda8aSnia}
3190bbfda8aSnia
3200bbfda8aSnia
3210bbfda8aSnia
3220bbfda8aSnia#define LEVITTE_TEST
3230bbfda8aSniastatic DEF_BI_SPM(Create3DCrossImage)
3240bbfda8aSnia{
3250bbfda8aSnia	Image *image;
3260bbfda8aSnia	int        h;
3270bbfda8aSnia	int    point;
3280bbfda8aSnia	int midpoint;
3290bbfda8aSnia
3300bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
3310bbfda8aSnia	if(!(h & 1)) {
3320bbfda8aSnia		h--;
3330bbfda8aSnia	}
3340bbfda8aSnia	point = 4;
3350bbfda8aSnia	midpoint = h / 2;
3360bbfda8aSnia
3370bbfda8aSnia	image = AllocImage();
3380bbfda8aSnia	if(! image) {
3390bbfda8aSnia		return (None);
3400bbfda8aSnia	}
3410bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
3420bbfda8aSnia	if(image->pixmap == None) {
3430bbfda8aSnia		free(image);
3440bbfda8aSnia		return (None);
3450bbfda8aSnia	}
3460bbfda8aSnia
3470bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
3480bbfda8aSnia	             off, true, false);
3490bbfda8aSnia
3500bbfda8aSnia#ifdef LEVITTE_TEST
3510bbfda8aSnia	FB(cp.shadc, cp.shadd);
3520bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point + 1, point - 1, point - 1,
3530bbfda8aSnia	          point + 1);
3540bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point + 1, point, point,
3550bbfda8aSnia	          point + 1);
3560bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point - 1, point + 1, midpoint - 2,
3570bbfda8aSnia	          midpoint);
3580bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, midpoint, midpoint + 2,
3590bbfda8aSnia	          h - point - 3, h - point - 1);
3600bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, point + 1, h - point - 3,
3610bbfda8aSnia	          h - point - 2);
3620bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point - 1, h - point - 2,
3630bbfda8aSnia	          midpoint - 2, midpoint);
3640bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, midpoint, midpoint - 2,
3650bbfda8aSnia	          h - point - 2, point - 1);
3660bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, h - point - 2,
3670bbfda8aSnia	          h - point - 2, point);
3680bbfda8aSnia#endif
3690bbfda8aSnia
3700bbfda8aSnia	FB(cp.shadd, cp.shadc);
3710bbfda8aSnia#ifdef LEVITTE_TEST
3720bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point + 2, point + 1,
3730bbfda8aSnia	          h - point - 1, h - point - 2);
3740bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point + 2, point, midpoint,
3750bbfda8aSnia	          midpoint - 2);
3760bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, midpoint + 2, midpoint, h - point,
3770bbfda8aSnia	          h - point - 2);
3780bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, h - point, h - point - 2,
3790bbfda8aSnia	          h - point - 2, h - point);
3800bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, h - point - 1, h - point - 2,
3810bbfda8aSnia	          h - point - 2, h - point - 1);
3820bbfda8aSnia#else
3830bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, point, h - point - 1,
3840bbfda8aSnia	          h - point - 1);
3850bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point - 1, point, h - point - 1,
3860bbfda8aSnia	          h - point);
3870bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, point - 1, h - point,
3880bbfda8aSnia	          h - point - 1);
3890bbfda8aSnia#endif
3900bbfda8aSnia
3910bbfda8aSnia#ifdef LEVITTE_TEST
3920bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, h - point - 1, point,
3930bbfda8aSnia	          h - point - 1);
3940bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, h - point - 1, point,
3950bbfda8aSnia	          h - point - 1, point);
3960bbfda8aSnia#else
3970bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, h - point - 1,
3980bbfda8aSnia	          h - point - 1, point);
3990bbfda8aSnia#endif
4000bbfda8aSnia#ifdef LEVITTE_TEST
4010bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point + 1, h - point - 1,
4020bbfda8aSnia	          h - point - 1, point + 1);
4030bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point + 1, h - point, midpoint,
4040bbfda8aSnia	          midpoint + 2);
4050bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, midpoint + 2, midpoint, h - point,
4060bbfda8aSnia	          point + 1);
4070bbfda8aSnia#else
4080bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point - 1, h - point - 1,
4090bbfda8aSnia	          h - point - 1, point - 1);
4100bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, h - point, h - point,
4110bbfda8aSnia	          point);
4120bbfda8aSnia#endif
4130bbfda8aSnia
4140bbfda8aSnia	image->width  = h;
4150bbfda8aSnia	image->height = h;
4160bbfda8aSnia
4170bbfda8aSnia	return (image);
4180bbfda8aSnia}
4190bbfda8aSnia#undef LEVITTE_TEST
4200bbfda8aSnia
4210bbfda8aSniastatic DEF_BI_SPM(Create3DIconifyImage)
4220bbfda8aSnia{
4230bbfda8aSnia	Image *image;
4240bbfda8aSnia	int     h;
4250bbfda8aSnia	int point;
4260bbfda8aSnia
4270bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
4280bbfda8aSnia	if(!(h & 1)) {
4290bbfda8aSnia		h--;
4300bbfda8aSnia	}
4310bbfda8aSnia	point = ((h / 2 - 2) * 2 + 1) / 3;
4320bbfda8aSnia
4330bbfda8aSnia	image = AllocImage();
4340bbfda8aSnia	if(! image) {
4350bbfda8aSnia		return (None);
4360bbfda8aSnia	}
4370bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
4380bbfda8aSnia	if(image->pixmap == None) {
4390bbfda8aSnia		free(image);
4400bbfda8aSnia		return (None);
4410bbfda8aSnia	}
4420bbfda8aSnia
4430bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
4440bbfda8aSnia	             off, true, false);
4450bbfda8aSnia	FB(cp.shadd, cp.shadc);
4460bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, point, h / 2, h - point);
4470bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, point, point, h - point, point);
4480bbfda8aSnia
4490bbfda8aSnia	FB(cp.shadc, cp.shadd);
4500bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, h - point, point, h / 2 + 1,
4510bbfda8aSnia	          h - point);
4520bbfda8aSnia	XDrawLine(dpy, image->pixmap, Scr->NormalGC, h - point - 1, point + 1,
4530bbfda8aSnia	          h / 2 + 1, h - point - 1);
4540bbfda8aSnia
4550bbfda8aSnia	image->width  = h;
4560bbfda8aSnia	image->height = h;
4570bbfda8aSnia
4580bbfda8aSnia	return (image);
4590bbfda8aSnia}
4600bbfda8aSnia
4610bbfda8aSniastatic DEF_BI_SPM(Create3DSunkenResizeImage)
4620bbfda8aSnia{
4630bbfda8aSnia	int     h;
4640bbfda8aSnia	Image *image;
4650bbfda8aSnia
4660bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
4670bbfda8aSnia	if(!(h & 1)) {
4680bbfda8aSnia		h--;
4690bbfda8aSnia	}
4700bbfda8aSnia
4710bbfda8aSnia	image = AllocImage();
4720bbfda8aSnia	if(! image) {
4730bbfda8aSnia		return (None);
4740bbfda8aSnia	}
4750bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
4760bbfda8aSnia	if(image->pixmap == None) {
4770bbfda8aSnia		free(image);
4780bbfda8aSnia		return (None);
4790bbfda8aSnia	}
4800bbfda8aSnia
4810bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
4820bbfda8aSnia	             off, true, false);
4830bbfda8aSnia	Draw3DBorder(image->pixmap, 3, 3, h - 6, h - 6, 1, cp, on, true, false);
4840bbfda8aSnia	Draw3DBorder(image->pixmap, 3, ((h - 6) / 3) + 3, ((h - 6) * 2 / 3) + 1,
4850bbfda8aSnia	             ((h - 6) * 2 / 3) + 1, 1, cp, on, true, false);
4860bbfda8aSnia	Draw3DBorder(image->pixmap, 3, ((h - 6) * 2 / 3) + 3, ((h - 6) / 3) + 1,
4870bbfda8aSnia	             ((h - 6) / 3) + 1, 1, cp, on, true, false);
4880bbfda8aSnia
4890bbfda8aSnia	image->width  = h;
4900bbfda8aSnia	image->height = h;
4910bbfda8aSnia
4920bbfda8aSnia	return (image);
4930bbfda8aSnia}
4940bbfda8aSnia
4950bbfda8aSniastatic DEF_BI_SPM(Create3DBoxImage)
4960bbfda8aSnia{
4970bbfda8aSnia	int     h;
4980bbfda8aSnia	Image   *image;
4990bbfda8aSnia
5000bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
5010bbfda8aSnia	if(!(h & 1)) {
5020bbfda8aSnia		h--;
5030bbfda8aSnia	}
5040bbfda8aSnia
5050bbfda8aSnia	image = AllocImage();
5060bbfda8aSnia	if(! image) {
5070bbfda8aSnia		return (None);
5080bbfda8aSnia	}
5090bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
5100bbfda8aSnia	if(image->pixmap == None) {
5110bbfda8aSnia		free(image);
5120bbfda8aSnia		return (None);
5130bbfda8aSnia	}
5140bbfda8aSnia
5150bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
5160bbfda8aSnia	             off, true, false);
5170bbfda8aSnia	Draw3DBorder(image->pixmap, (h / 2) - 4, (h / 2) - 4, 9, 9, 1, cp,
5180bbfda8aSnia	             off, true, false);
5190bbfda8aSnia
5200bbfda8aSnia	image->width  = h;
5210bbfda8aSnia	image->height = h;
5220bbfda8aSnia
5230bbfda8aSnia	return (image);
5240bbfda8aSnia}
5250bbfda8aSnia
5260bbfda8aSniastatic DEF_BI_SPM(Create3DDotImage)
5270bbfda8aSnia{
5280bbfda8aSnia	Image *image;
5290bbfda8aSnia	int   h;
5300bbfda8aSnia	static int idepth = 2;
5310bbfda8aSnia
5320bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
5330bbfda8aSnia	if(!(h & 1)) {
5340bbfda8aSnia		h--;
5350bbfda8aSnia	}
5360bbfda8aSnia
5370bbfda8aSnia	image = AllocImage();
5380bbfda8aSnia	if(! image) {
5390bbfda8aSnia		return (None);
5400bbfda8aSnia	}
5410bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
5420bbfda8aSnia	if(image->pixmap == None) {
5430bbfda8aSnia		free(image);
5440bbfda8aSnia		return (None);
5450bbfda8aSnia	}
5460bbfda8aSnia
5470bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
5480bbfda8aSnia	             off, true, false);
5490bbfda8aSnia	Draw3DBorder(image->pixmap, (h / 2) - idepth,
5500bbfda8aSnia	             (h / 2) - idepth,
5510bbfda8aSnia	             2 * idepth + 1,
5520bbfda8aSnia	             2 * idepth + 1,
5530bbfda8aSnia	             idepth, cp, off, true, false);
5540bbfda8aSnia	image->width  = h;
5550bbfda8aSnia	image->height = h;
5560bbfda8aSnia	return (image);
5570bbfda8aSnia}
5580bbfda8aSnia
5590bbfda8aSniastatic DEF_BI_SPM(Create3DBarImage)
5600bbfda8aSnia{
5610bbfda8aSnia	Image *image;
5620bbfda8aSnia	int   h;
5630bbfda8aSnia	static int idepth = 2;
5640bbfda8aSnia
5650bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
5660bbfda8aSnia	if(!(h & 1)) {
5670bbfda8aSnia		h--;
5680bbfda8aSnia	}
5690bbfda8aSnia
5700bbfda8aSnia	image = AllocImage();
5710bbfda8aSnia	if(! image) {
5720bbfda8aSnia		return (None);
5730bbfda8aSnia	}
5740bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
5750bbfda8aSnia	if(image->pixmap == None) {
5760bbfda8aSnia		free(image);
5770bbfda8aSnia		return (None);
5780bbfda8aSnia	}
5790bbfda8aSnia
5800bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
5810bbfda8aSnia	             off, true, false);
5820bbfda8aSnia	Draw3DBorder(image->pixmap,
5830bbfda8aSnia	             Scr->TitleButtonShadowDepth + 2,
5840bbfda8aSnia	             (h / 2) - idepth,
5850bbfda8aSnia	             h - 2 * (Scr->TitleButtonShadowDepth + 2),
5860bbfda8aSnia	             2 * idepth + 1,
5870bbfda8aSnia	             idepth, cp, off, true, false);
5880bbfda8aSnia	image->width  = h;
5890bbfda8aSnia	image->height = h;
5900bbfda8aSnia	return (image);
5910bbfda8aSnia}
5920bbfda8aSnia
5930bbfda8aSniastatic DEF_BI_SPM(Create3DVertBarImage)
5940bbfda8aSnia{
5950bbfda8aSnia	Image *image;
5960bbfda8aSnia	int   h;
5970bbfda8aSnia	static int idepth = 2;
5980bbfda8aSnia
5990bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
6000bbfda8aSnia	if(!(h & 1)) {
6010bbfda8aSnia		h--;
6020bbfda8aSnia	}
6030bbfda8aSnia
6040bbfda8aSnia	image = AllocImage();
6050bbfda8aSnia	if(! image) {
6060bbfda8aSnia		return (None);
6070bbfda8aSnia	}
6080bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
6090bbfda8aSnia	if(image->pixmap == None) {
6100bbfda8aSnia		free(image);
6110bbfda8aSnia		return (None);
6120bbfda8aSnia	}
6130bbfda8aSnia
6140bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
6150bbfda8aSnia	             off, true, false);
6160bbfda8aSnia	Draw3DBorder(image->pixmap,
6170bbfda8aSnia	             (h / 2) - idepth,
6180bbfda8aSnia	             Scr->TitleButtonShadowDepth + 2,
6190bbfda8aSnia	             2 * idepth + 1,
6200bbfda8aSnia	             h - 2 * (Scr->TitleButtonShadowDepth + 2),
6210bbfda8aSnia	             idepth, cp, off, true, false);
6220bbfda8aSnia	image->width  = h;
6230bbfda8aSnia	image->height = h;
6240bbfda8aSnia	return (image);
6250bbfda8aSnia}
6260bbfda8aSnia
6270bbfda8aSniastatic DEF_BI_SPM(Create3DMenuImage)
6280bbfda8aSnia{
6290bbfda8aSnia	Image *image;
6300bbfda8aSnia	int   h, i;
6310bbfda8aSnia
6320bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
6330bbfda8aSnia	if(!(h & 1)) {
6340bbfda8aSnia		h--;
6350bbfda8aSnia	}
6360bbfda8aSnia
6370bbfda8aSnia	image = AllocImage();
6380bbfda8aSnia	if(! image) {
6390bbfda8aSnia		return (None);
6400bbfda8aSnia	}
6410bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
6420bbfda8aSnia	if(image->pixmap == None) {
6430bbfda8aSnia		free(image);
6440bbfda8aSnia		return (None);
6450bbfda8aSnia	}
6460bbfda8aSnia
6470bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
6480bbfda8aSnia	             off, true, false);
6490bbfda8aSnia	for(i = 4; i < h - 7; i += 5) {
6500bbfda8aSnia		Draw3DBorder(image->pixmap, 4, i, h - 8, 4, 2, cp, off, true, false);
6510bbfda8aSnia	}
6520bbfda8aSnia	image->width  = h;
6530bbfda8aSnia	image->height = h;
6540bbfda8aSnia	return (image);
6550bbfda8aSnia}
6560bbfda8aSnia
6570bbfda8aSniastatic DEF_BI_SPM(Create3DResizeImage)
6580bbfda8aSnia{
6590bbfda8aSnia	Image *image;
6600bbfda8aSnia	int   h;
6610bbfda8aSnia
6620bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
6630bbfda8aSnia	if(!(h & 1)) {
6640bbfda8aSnia		h--;
6650bbfda8aSnia	}
6660bbfda8aSnia
6670bbfda8aSnia	image = AllocImage();
6680bbfda8aSnia	if(! image) {
6690bbfda8aSnia		return (None);
6700bbfda8aSnia	}
6710bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
6720bbfda8aSnia	if(image->pixmap == None) {
6730bbfda8aSnia		free(image);
6740bbfda8aSnia		return (None);
6750bbfda8aSnia	}
6760bbfda8aSnia
6770bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
6780bbfda8aSnia	             off, true, false);
6790bbfda8aSnia	Draw3DBorder(image->pixmap, 0, h / 4, ((3 * h) / 4) + 1, ((3 * h) / 4) + 1,
6800bbfda8aSnia	             2, cp, off, true, false);
6810bbfda8aSnia	Draw3DBorder(image->pixmap, 0, h / 2, (h / 2) + 1, (h / 2) + 1, 2, cp, off,
6820bbfda8aSnia	             true, false);
6830bbfda8aSnia	image->width  = h;
6840bbfda8aSnia	image->height = h;
6850bbfda8aSnia	return (image);
6860bbfda8aSnia}
6870bbfda8aSnia
6880bbfda8aSniastatic DEF_BI_SPM(Create3DZoomImage)
6890bbfda8aSnia{
6900bbfda8aSnia	Image *image;
6910bbfda8aSnia	int         h;
6920bbfda8aSnia	static int idepth = 2;
6930bbfda8aSnia
6940bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
6950bbfda8aSnia	if(!(h & 1)) {
6960bbfda8aSnia		h--;
6970bbfda8aSnia	}
6980bbfda8aSnia
6990bbfda8aSnia	image = AllocImage();
7000bbfda8aSnia	if(! image) {
7010bbfda8aSnia		return (None);
7020bbfda8aSnia	}
7030bbfda8aSnia	image->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
7040bbfda8aSnia	if(image->pixmap == None) {
7050bbfda8aSnia		free(image);
7060bbfda8aSnia		return (None);
7070bbfda8aSnia	}
7080bbfda8aSnia
7090bbfda8aSnia	Draw3DBorder(image->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
7100bbfda8aSnia	             off, true, false);
7110bbfda8aSnia	Draw3DBorder(image->pixmap, Scr->TitleButtonShadowDepth + 2,
7120bbfda8aSnia	             Scr->TitleButtonShadowDepth + 2,
7130bbfda8aSnia	             h - 2 * (Scr->TitleButtonShadowDepth + 2),
7140bbfda8aSnia	             h - 2 * (Scr->TitleButtonShadowDepth + 2),
7150bbfda8aSnia	             idepth, cp, off, true, false);
7160bbfda8aSnia
7170bbfda8aSnia	image->width  = h;
7180bbfda8aSnia	image->height = h;
7190bbfda8aSnia	return (image);
7200bbfda8aSnia}
7210bbfda8aSnia
7220bbfda8aSnia#undef DEF_BI_SPM
7230bbfda8aSnia
7240bbfda8aSnia
7250bbfda8aSnia
7260bbfda8aSnia/*
7270bbfda8aSnia * And the animated builtins.  These are the ones specified with names
7280bbfda8aSnia * like "%xpm:resize".
7290bbfda8aSnia *
7300bbfda8aSnia * These yield [ctwm struct] Image's.
7310bbfda8aSnia */
7320bbfda8aSnia#define DEF_BI_ASPM(nm) Image *nm(ColorPair cp)
7330bbfda8aSnia
7340bbfda8aSnia/* Backend generators */
7350bbfda8aSniastatic Image *Create3DResizeAnimation(bool in, bool left, bool top,
7360bbfda8aSnia                                      ColorPair cp);
7370bbfda8aSniastatic Image *Create3DMenuAnimation(bool up, ColorPair cp);
7380bbfda8aSniastatic Image *Create3DZoomAnimation(bool in, bool out, int n, ColorPair cp);
7390bbfda8aSnia
7400bbfda8aSnia/* Frontends */
7410bbfda8aSnia/* Using: ResizeAnimation */
7420bbfda8aSniastatic DEF_BI_ASPM(Create3DResizeInTopAnimation);
7430bbfda8aSniastatic DEF_BI_ASPM(Create3DResizeOutTopAnimation);
7440bbfda8aSniastatic DEF_BI_ASPM(Create3DResizeInBotAnimation);
7450bbfda8aSniastatic DEF_BI_ASPM(Create3DResizeOutBotAnimation);
7460bbfda8aSnia/* Using: MenuAnimation */
7470bbfda8aSniastatic DEF_BI_ASPM(Create3DMenuUpAnimation);
7480bbfda8aSniastatic DEF_BI_ASPM(Create3DMenuDownAnimation);
7490bbfda8aSnia/* Using: ZoomAnimation */
7500bbfda8aSniastatic DEF_BI_ASPM(Create3DMazeOutAnimation);
7510bbfda8aSniastatic DEF_BI_ASPM(Create3DMazeInAnimation);
7520bbfda8aSniastatic DEF_BI_ASPM(Create3DZoomInAnimation);
7530bbfda8aSniastatic DEF_BI_ASPM(Create3DZoomOutAnimation);
7540bbfda8aSniastatic DEF_BI_ASPM(Create3DZoomInOutAnimation);
7550bbfda8aSnia
7560bbfda8aSnia
7570bbfda8aSnia/*
7580bbfda8aSnia * Entry for animated pixmaps
7590bbfda8aSnia *
7600bbfda8aSnia * This is where we find "%xpm:something".  Note that as above, these are
7610bbfda8aSnia * _not_ XPM's, and have no relation to the configurable XPM support,
7620bbfda8aSnia * which we get with images specified as "xpm:something" (no leading
7630bbfda8aSnia * colon).  Still not confusing at _all_.
7640bbfda8aSnia */
7650bbfda8aSniaImage *
7660bbfda8aSniaget_builtin_animated_pixmap(const char *name, ColorPair cp)
7670bbfda8aSnia{
7680bbfda8aSnia	int    i;
7690bbfda8aSnia	static struct {
7700bbfda8aSnia		char *name;
7710bbfda8aSnia		DEF_BI_ASPM((*proc));
7720bbfda8aSnia	} pmtab[] = {
7730bbfda8aSnia		/* Lookup for "%xpm:" pixmaps */
7740bbfda8aSnia		{ "%xpm:resize-out-top", Create3DResizeInTopAnimation },
7750bbfda8aSnia		{ "%xpm:resize-in-top",  Create3DResizeOutTopAnimation },
7760bbfda8aSnia		{ "%xpm:resize-out-bot", Create3DResizeInBotAnimation },
7770bbfda8aSnia		{ "%xpm:resize-in-bot",  Create3DResizeOutBotAnimation },
7780bbfda8aSnia		{ "%xpm:menu-up",        Create3DMenuUpAnimation },
7790bbfda8aSnia		{ "%xpm:menu-down",      Create3DMenuDownAnimation },
7800bbfda8aSnia		{ "%xpm:maze-out",       Create3DMazeOutAnimation },
7810bbfda8aSnia		{ "%xpm:maze-in",        Create3DMazeInAnimation },
7820bbfda8aSnia		{ "%xpm:resize",         Create3DZoomOutAnimation }, // compat
7830bbfda8aSnia		{ "%xpm:zoom-out",       Create3DZoomOutAnimation },
7840bbfda8aSnia		{ "%xpm:zoom-in",        Create3DZoomInAnimation },
7850bbfda8aSnia		{ "%xpm:zoom-inout",     Create3DZoomInOutAnimation },
7860bbfda8aSnia	};
7870bbfda8aSnia
7880bbfda8aSnia	/* Seatbelts */
7890bbfda8aSnia	if(!name || (strncmp(name, "%xpm:", 5) != 0)) {
7900bbfda8aSnia		return NULL;
7910bbfda8aSnia	}
7920bbfda8aSnia
7930bbfda8aSnia	for(i = 0; i < (sizeof pmtab) / (sizeof pmtab[0]); i++) {
7940bbfda8aSnia		if(strcasecmp(pmtab[i].name, name) == 0) {
7950bbfda8aSnia			Image *image = (*pmtab[i].proc)(cp);
7960bbfda8aSnia			if(image == NULL) {
7970bbfda8aSnia				fprintf(stderr, "%s:  unable to build pixmap \"%s\"\n",
7980bbfda8aSnia				        ProgramName, name);
7990bbfda8aSnia				return NULL;
8000bbfda8aSnia			}
8010bbfda8aSnia			return image;
8020bbfda8aSnia		}
8030bbfda8aSnia	}
8040bbfda8aSnia
8050bbfda8aSnia	fprintf(stderr, "%s:  no such built-in pixmap \"%s\"\n", ProgramName, name);
8060bbfda8aSnia	return (None);
8070bbfda8aSnia}
8080bbfda8aSnia
8090bbfda8aSnia
8100bbfda8aSnia/*
8110bbfda8aSnia * First a couple generator functions the actual functions use
8120bbfda8aSnia */
8130bbfda8aSniastatic Image *
8140bbfda8aSniaCreate3DResizeAnimation(bool in, bool left, bool top,
8150bbfda8aSnia                        ColorPair cp)
8160bbfda8aSnia{
8170bbfda8aSnia	int         h, i, j;
8180bbfda8aSnia	Image       *image, *im, *im1;
8190bbfda8aSnia
8200bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
8210bbfda8aSnia	if(!(h & 1)) {
8220bbfda8aSnia		h--;
8230bbfda8aSnia	}
8240bbfda8aSnia
8250bbfda8aSnia	image = im1 = NULL;
8260bbfda8aSnia	for(i = (in ? 0 : (h / 4) - 1); (i < h / 4) && (i >= 0); i += (in ? 1 : -1)) {
8270bbfda8aSnia		im = AllocImage();
8280bbfda8aSnia		if(! im) {
8290bbfda8aSnia			return NULL;
8300bbfda8aSnia		}
8310bbfda8aSnia		im->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
8320bbfda8aSnia		if(im->pixmap == None) {
8330bbfda8aSnia			free(im);
8340bbfda8aSnia			return NULL;
8350bbfda8aSnia		}
8360bbfda8aSnia		Draw3DBorder(im->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
8370bbfda8aSnia		             off, true, false);
8380bbfda8aSnia		for(j = i; j <= h; j += (h / 4)) {
8390bbfda8aSnia			Draw3DBorder(im->pixmap, (left ? 0 : j), (top ? 0 : j),
8400bbfda8aSnia			             h - j, h - j, 2, cp, off, true, false);
8410bbfda8aSnia		}
8420bbfda8aSnia		im->mask   = None;
8430bbfda8aSnia		im->width  = h;
8440bbfda8aSnia		im->height = h;
8450bbfda8aSnia		im->next   = NULL;
8460bbfda8aSnia		if(image == NULL) {
8470bbfda8aSnia			image = im1 = im;
8480bbfda8aSnia		}
8490bbfda8aSnia		else {
8500bbfda8aSnia			im1->next = im;
8510bbfda8aSnia			im1 = im;
8520bbfda8aSnia		}
8530bbfda8aSnia	}
8540bbfda8aSnia	if(im1 != None) {
8550bbfda8aSnia		im1->next = image;
8560bbfda8aSnia	}
8570bbfda8aSnia	return image;
8580bbfda8aSnia}
8590bbfda8aSnia
8600bbfda8aSniastatic Image *
8610bbfda8aSniaCreate3DMenuAnimation(bool up, ColorPair cp)
8620bbfda8aSnia{
8630bbfda8aSnia	int   h, i, j;
8640bbfda8aSnia	Image *image, *im, *im1;
8650bbfda8aSnia
8660bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
8670bbfda8aSnia	if(!(h & 1)) {
8680bbfda8aSnia		h--;
8690bbfda8aSnia	}
8700bbfda8aSnia
8710bbfda8aSnia	image = im1 = NULL;
8720bbfda8aSnia	for(j = (up ? 4 : 0); j != (up ? -1 : 5); j += (up ? -1 : 1)) {
8730bbfda8aSnia		im = AllocImage();
8740bbfda8aSnia		if(! im) {
8750bbfda8aSnia			return NULL;
8760bbfda8aSnia		}
8770bbfda8aSnia		im->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
8780bbfda8aSnia		if(im->pixmap == None) {
8790bbfda8aSnia			free(im);
8800bbfda8aSnia			return NULL;
8810bbfda8aSnia		}
8820bbfda8aSnia		Draw3DBorder(im->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth, cp,
8830bbfda8aSnia		             off, true, false);
8840bbfda8aSnia		for(i = j; i < h - 3; i += 5) {
8850bbfda8aSnia			Draw3DBorder(im->pixmap, 4, i, h - 8, 4, 2, cp, off, true, false);
8860bbfda8aSnia		}
8870bbfda8aSnia		im->mask   = None;
8880bbfda8aSnia		im->width  = h;
8890bbfda8aSnia		im->height = h;
8900bbfda8aSnia		im->next   = NULL;
8910bbfda8aSnia		if(image == NULL) {
8920bbfda8aSnia			image = im1 = im;
8930bbfda8aSnia		}
8940bbfda8aSnia		else {
8950bbfda8aSnia			im1->next = im;
8960bbfda8aSnia			im1 = im;
8970bbfda8aSnia		}
8980bbfda8aSnia	}
8990bbfda8aSnia	if(im1 != None) {
9000bbfda8aSnia		im1->next = image;
9010bbfda8aSnia	}
9020bbfda8aSnia	return image;
9030bbfda8aSnia}
9040bbfda8aSnia
9050bbfda8aSniastatic Image *
9060bbfda8aSniaCreate3DZoomAnimation(bool in, bool out, int n, ColorPair cp)
9070bbfda8aSnia{
9080bbfda8aSnia	int         h, i, j, k;
9090bbfda8aSnia	Image       *image, *im, *im1;
9100bbfda8aSnia
9110bbfda8aSnia	h = Scr->TBInfo.width - Scr->TBInfo.border * 2;
9120bbfda8aSnia	if(!(h & 1)) {
9130bbfda8aSnia		h--;
9140bbfda8aSnia	}
9150bbfda8aSnia
9160bbfda8aSnia	if(n == 0) {
9170bbfda8aSnia		n = (h / 2) - 2;
9180bbfda8aSnia	}
9190bbfda8aSnia
9200bbfda8aSnia	image = im1 = NULL;
9210bbfda8aSnia	for(j = (out ? -1 : 1) ; j < (in ? 2 : 0); j += 2) {
9220bbfda8aSnia		for(k = (j > 0 ? 0 : n - 1) ; (k >= 0) && (k < n); k += j) {
9230bbfda8aSnia			im = AllocImage();
9240bbfda8aSnia			im->pixmap = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
9250bbfda8aSnia			Draw3DBorder(im->pixmap, 0, 0, h, h, Scr->TitleButtonShadowDepth,
9260bbfda8aSnia			             cp, off, true, false);
9270bbfda8aSnia			for(i = 2 + k; i < (h / 2); i += n) {
9280bbfda8aSnia				Draw3DBorder(im->pixmap, i, i, h - (2 * i), h - (2 * i), 2, cp,
9290bbfda8aSnia				             off, true, false);
9300bbfda8aSnia			}
9310bbfda8aSnia			im->mask   = None;
9320bbfda8aSnia			im->width  = h;
9330bbfda8aSnia			im->height = h;
9340bbfda8aSnia			im->next   = NULL;
9350bbfda8aSnia			if(image == NULL) {
9360bbfda8aSnia				image = im1 = im;
9370bbfda8aSnia			}
9380bbfda8aSnia			else {
9390bbfda8aSnia				im1->next = im;
9400bbfda8aSnia				im1 = im;
9410bbfda8aSnia			}
9420bbfda8aSnia		}
9430bbfda8aSnia	}
9440bbfda8aSnia	if(im1 != None) {
9450bbfda8aSnia		im1->next = image;
9460bbfda8aSnia	}
9470bbfda8aSnia	return image;
9480bbfda8aSnia}
9490bbfda8aSnia
9500bbfda8aSnia
9510bbfda8aSnia/*
9520bbfda8aSnia * And the wrapper funcs for making the images
9530bbfda8aSnia */
9540bbfda8aSniastatic DEF_BI_ASPM(Create3DResizeInTopAnimation)
9550bbfda8aSnia{
9560bbfda8aSnia	return Create3DResizeAnimation(true, false, true, cp);
9570bbfda8aSnia}
9580bbfda8aSnia
9590bbfda8aSniastatic DEF_BI_ASPM(Create3DResizeOutTopAnimation)
9600bbfda8aSnia{
9610bbfda8aSnia	return Create3DResizeAnimation(false, false, true, cp);
9620bbfda8aSnia}
9630bbfda8aSnia
9640bbfda8aSniastatic DEF_BI_ASPM(Create3DResizeInBotAnimation)
9650bbfda8aSnia{
9660bbfda8aSnia	return Create3DResizeAnimation(true, true, false, cp);
9670bbfda8aSnia}
9680bbfda8aSnia
9690bbfda8aSniastatic DEF_BI_ASPM(Create3DResizeOutBotAnimation)
9700bbfda8aSnia{
9710bbfda8aSnia	return Create3DResizeAnimation(false, true, false, cp);
9720bbfda8aSnia}
9730bbfda8aSnia
9740bbfda8aSnia
9750bbfda8aSniastatic DEF_BI_ASPM(Create3DMenuUpAnimation)
9760bbfda8aSnia{
9770bbfda8aSnia	return Create3DMenuAnimation(true, cp);
9780bbfda8aSnia}
9790bbfda8aSnia
9800bbfda8aSniastatic DEF_BI_ASPM(Create3DMenuDownAnimation)
9810bbfda8aSnia{
9820bbfda8aSnia	return Create3DMenuAnimation(false, cp);
9830bbfda8aSnia}
9840bbfda8aSnia
9850bbfda8aSnia
9860bbfda8aSniastatic DEF_BI_ASPM(Create3DMazeInAnimation)
9870bbfda8aSnia{
9880bbfda8aSnia	return Create3DZoomAnimation(true, false, 6, cp);
9890bbfda8aSnia}
9900bbfda8aSnia
9910bbfda8aSniastatic DEF_BI_ASPM(Create3DMazeOutAnimation)
9920bbfda8aSnia{
9930bbfda8aSnia	return Create3DZoomAnimation(false, true, 6, cp);
9940bbfda8aSnia}
9950bbfda8aSnia
9960bbfda8aSniastatic DEF_BI_ASPM(Create3DZoomInAnimation)
9970bbfda8aSnia{
9980bbfda8aSnia	return Create3DZoomAnimation(true, false, 0, cp);
9990bbfda8aSnia}
10000bbfda8aSnia
10010bbfda8aSniastatic DEF_BI_ASPM(Create3DZoomOutAnimation)
10020bbfda8aSnia{
10030bbfda8aSnia	return Create3DZoomAnimation(false, true, 0, cp);
10040bbfda8aSnia}
10050bbfda8aSnia
10060bbfda8aSniastatic DEF_BI_ASPM(Create3DZoomInOutAnimation)
10070bbfda8aSnia{
10080bbfda8aSnia	return Create3DZoomAnimation(true, true, 0, cp);
10090bbfda8aSnia}
10100bbfda8aSnia
10110bbfda8aSnia#undef DEF_BI_ASPM
10120bbfda8aSnia
10130bbfda8aSnia
10140bbfda8aSnia/*
10150bbfda8aSnia * Lastly, some gray/black pixmaps that are used in window border and
10160bbfda8aSnia * hilite bars.
10170bbfda8aSnia */
10180bbfda8aSnia#define BG_WIDTH  2
10190bbfda8aSnia#define BG_HEIGHT 2
10200bbfda8aSnia
10210bbfda8aSniaPixmap
10220bbfda8aSniamk_blackgray_pixmap(const char *which, Drawable dw,
10230bbfda8aSnia                    unsigned long fg, unsigned long bg)
10240bbfda8aSnia{
10250bbfda8aSnia	unsigned char gray_bits[]  = { 0x02, 0x01 };
10260bbfda8aSnia	unsigned char black_bits[] = { 0xFF, 0xFF };
10270bbfda8aSnia	char *bits;
10280bbfda8aSnia
10290bbfda8aSnia	/* Which are we asking for? */
10300bbfda8aSnia	if(strcmp(which, "black") == 0) {
10310bbfda8aSnia		bits = (char *)black_bits;
10320bbfda8aSnia	}
10330bbfda8aSnia	else if(strcmp(which, "gray") == 0) {
10340bbfda8aSnia		bits = (char *)gray_bits;
10350bbfda8aSnia	}
10360bbfda8aSnia	else {
10370bbfda8aSnia		fprintf(stderr, "%s(): Invalid which arg '%s'\n", __func__, which);
10380bbfda8aSnia		return None;
10390bbfda8aSnia	}
10400bbfda8aSnia
10410bbfda8aSnia	/* Make it */
10420bbfda8aSnia	return XCreatePixmapFromBitmapData(dpy, dw,
10430bbfda8aSnia	                                   bits, BG_WIDTH, BG_HEIGHT,
10440bbfda8aSnia	                                   fg, bg, Scr->d_depth);
10450bbfda8aSnia}
10460bbfda8aSnia
10470bbfda8aSniavoid
10480bbfda8aSniaget_blackgray_size(int *width, int *height)
10490bbfda8aSnia{
10500bbfda8aSnia	if(width) {
10510bbfda8aSnia		*width  = BG_WIDTH;
10520bbfda8aSnia	}
10530bbfda8aSnia	if(height) {
10540bbfda8aSnia		*height = BG_HEIGHT;
10550bbfda8aSnia	}
10560bbfda8aSnia}
10570bbfda8aSnia
10580bbfda8aSnia#undef BG_HEIGHT
10590bbfda8aSnia#undef BG_WIDTH
1060