icons_builtin.c revision 0bbfda8a
10bbfda8aSnia/*
20bbfda8aSnia * Built-in icon building
30bbfda8aSnia *
40bbfda8aSnia * This conceptually overlaps pretty strongly with
50bbfda8aSnia * image_bitmap_builtin.c, since both are about drawing some built-in
60bbfda8aSnia * images used for internal stuff.  They're kept separate because i_b_b
70bbfda8aSnia * is backend bits for GetImage() calls for ":xpm:", "%xpm:", and ":"
80bbfda8aSnia * images, while these are called directly from the code.  Perhaps they
90bbfda8aSnia * should be subsumed under that, but they haven't been so far, so we're
100bbfda8aSnia * keeping them separate for now.
110bbfda8aSnia */
120bbfda8aSnia
130bbfda8aSnia#include "ctwm.h"
140bbfda8aSnia
150bbfda8aSnia#include <stdlib.h>
160bbfda8aSnia
170bbfda8aSnia#include "drawing.h"
180bbfda8aSnia#include "screen.h"
190bbfda8aSnia#include "iconmgr.h"
200bbfda8aSnia
210bbfda8aSnia#include "icons_builtin.h"
220bbfda8aSnia
230bbfda8aSnia
240bbfda8aSniastruct Colori {
250bbfda8aSnia	Pixel color;
260bbfda8aSnia	Pixmap pix;
270bbfda8aSnia	struct Colori *next;
280bbfda8aSnia};
290bbfda8aSnia
300bbfda8aSnia
310bbfda8aSnia/*
320bbfda8aSnia * The icons on menu items for submenus, in UseThreeDMenus and non
330bbfda8aSnia * variants.
340bbfda8aSnia */
350bbfda8aSniaPixmap
360bbfda8aSniaCreate3DMenuIcon(unsigned int height,
370bbfda8aSnia                 unsigned int *widthp, unsigned int *heightp,
380bbfda8aSnia                 ColorPair cp)
390bbfda8aSnia{
400bbfda8aSnia	unsigned int h, w;
410bbfda8aSnia	int         i;
420bbfda8aSnia	struct Colori *col;
430bbfda8aSnia	static struct Colori *colori = NULL;
440bbfda8aSnia
450bbfda8aSnia	h = height;
460bbfda8aSnia	w = h * 7 / 8;
470bbfda8aSnia	if(h < 1) {
480bbfda8aSnia		h = 1;
490bbfda8aSnia	}
500bbfda8aSnia	if(w < 1) {
510bbfda8aSnia		w = 1;
520bbfda8aSnia	}
530bbfda8aSnia	*widthp  = w;
540bbfda8aSnia	*heightp = h;
550bbfda8aSnia
560bbfda8aSnia	for(col = colori; col; col = col->next) {
570bbfda8aSnia		if(col->color == cp.back) {
580bbfda8aSnia			break;
590bbfda8aSnia		}
600bbfda8aSnia	}
610bbfda8aSnia	if(col != NULL) {
620bbfda8aSnia		return (col->pix);
630bbfda8aSnia	}
640bbfda8aSnia	col = malloc(sizeof(struct Colori));
650bbfda8aSnia	col->color = cp.back;
660bbfda8aSnia	col->pix   = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth);
670bbfda8aSnia	col->next = colori;
680bbfda8aSnia	colori = col;
690bbfda8aSnia
700bbfda8aSnia	Draw3DBorder(col->pix, 0, 0, w, h, 1, cp, off, true, false);
710bbfda8aSnia	for(i = 3; i + 5 < h; i += 5) {
720bbfda8aSnia		Draw3DBorder(col->pix, 4, i, w - 8, 3, 1, Scr->MenuC, off, true, false);
730bbfda8aSnia	}
740bbfda8aSnia	return (colori->pix);
750bbfda8aSnia}
760bbfda8aSnia
770bbfda8aSniaPixmap
780bbfda8aSniaCreateMenuIcon(int height, unsigned int *widthp, unsigned int *heightp)
790bbfda8aSnia{
800bbfda8aSnia	int h, w;
810bbfda8aSnia	int ih, iw;
820bbfda8aSnia	int ix, iy;
830bbfda8aSnia	int mh, mw;
840bbfda8aSnia	int tw, th;
850bbfda8aSnia	int lw, lh;
860bbfda8aSnia	int lx, ly;
870bbfda8aSnia	int lines, dly;
880bbfda8aSnia	int offset;
890bbfda8aSnia	int bw;
900bbfda8aSnia
910bbfda8aSnia	h = height;
920bbfda8aSnia	w = h * 7 / 8;
930bbfda8aSnia	if(h < 1) {
940bbfda8aSnia		h = 1;
950bbfda8aSnia	}
960bbfda8aSnia	if(w < 1) {
970bbfda8aSnia		w = 1;
980bbfda8aSnia	}
990bbfda8aSnia	*widthp = w;
1000bbfda8aSnia	*heightp = h;
1010bbfda8aSnia	if(Scr->tbpm.menu == None) {
1020bbfda8aSnia		Pixmap  pix;
1030bbfda8aSnia		GC      gc;
1040bbfda8aSnia
1050bbfda8aSnia		pix = Scr->tbpm.menu = XCreatePixmap(dpy, Scr->Root, w, h, 1);
1060bbfda8aSnia		gc = XCreateGC(dpy, pix, 0L, NULL);
1070bbfda8aSnia		XSetForeground(dpy, gc, 0L);
1080bbfda8aSnia		XFillRectangle(dpy, pix, gc, 0, 0, w, h);
1090bbfda8aSnia		XSetForeground(dpy, gc, 1L);
1100bbfda8aSnia		ix = 1;
1110bbfda8aSnia		iy = 1;
1120bbfda8aSnia		ih = h - iy * 2;
1130bbfda8aSnia		iw = w - ix * 2;
1140bbfda8aSnia		offset = ih / 8;
1150bbfda8aSnia		mh = ih - offset;
1160bbfda8aSnia		mw = iw - offset;
1170bbfda8aSnia		bw = mh / 16;
1180bbfda8aSnia		if(bw == 0 && mw > 2) {
1190bbfda8aSnia			bw = 1;
1200bbfda8aSnia		}
1210bbfda8aSnia		tw = mw - bw * 2;
1220bbfda8aSnia		th = mh - bw * 2;
1230bbfda8aSnia		XFillRectangle(dpy, pix, gc, ix, iy, mw, mh);
1240bbfda8aSnia		XFillRectangle(dpy, pix, gc, ix + iw - mw, iy + ih - mh, mw, mh);
1250bbfda8aSnia		XSetForeground(dpy, gc, 0L);
1260bbfda8aSnia		XFillRectangle(dpy, pix, gc, ix + bw, iy + bw, tw, th);
1270bbfda8aSnia		XSetForeground(dpy, gc, 1L);
1280bbfda8aSnia		lw = tw / 2;
1290bbfda8aSnia		if((tw & 1) ^ (lw & 1)) {
1300bbfda8aSnia			lw++;
1310bbfda8aSnia		}
1320bbfda8aSnia		lx = ix + bw + (tw - lw) / 2;
1330bbfda8aSnia
1340bbfda8aSnia		lh = th / 2 - bw;
1350bbfda8aSnia		if((lh & 1) ^ ((th - bw) & 1)) {
1360bbfda8aSnia			lh++;
1370bbfda8aSnia		}
1380bbfda8aSnia		ly = iy + bw + (th - bw - lh) / 2;
1390bbfda8aSnia
1400bbfda8aSnia		lines = 3;
1410bbfda8aSnia		if((lh & 1) && lh < 6) {
1420bbfda8aSnia			lines--;
1430bbfda8aSnia		}
1440bbfda8aSnia		dly = lh / (lines - 1);
1450bbfda8aSnia		while(lines--) {
1460bbfda8aSnia			XFillRectangle(dpy, pix, gc, lx, ly, lw, bw);
1470bbfda8aSnia			ly += dly;
1480bbfda8aSnia		}
1490bbfda8aSnia		XFreeGC(dpy, gc);
1500bbfda8aSnia	}
1510bbfda8aSnia	return Scr->tbpm.menu;
1520bbfda8aSnia}
1530bbfda8aSnia
1540bbfda8aSnia
1550bbfda8aSnia
1560bbfda8aSnia/*
1570bbfda8aSnia * Icon used in the icon manager for iconified windows.
1580bbfda8aSnia *
1590bbfda8aSnia * For the 2d case, there's just one icon stored screen-wide, which is
1600bbfda8aSnia * XCopyPlane()'d into the icon manager.  This works because it's just a
1610bbfda8aSnia * 2-color thing represented as a bitmap, and we color it to match the
1620bbfda8aSnia * FG/BG of the row at the time.
1630bbfda8aSnia *
1640bbfda8aSnia * The 3d variant is more complicated, and doesn't just use the row's
1650bbfda8aSnia * FG/BG colors; it draws various shades from them.  So since each row in
1660bbfda8aSnia * an icon manager may be a different FG/BG color, we have to make a new
1670bbfda8aSnia * one for each row.
1680bbfda8aSnia */
1690bbfda8aSnia
1700bbfda8aSniaconst unsigned int im_iconified_icon_width = 11;
1710bbfda8aSniaconst unsigned int im_iconified_icon_height = 11;
1720bbfda8aSniastatic unsigned char im_iconified_icon_bits[] = {
1730bbfda8aSnia	0xff, 0x07, 0x01, 0x04, 0x0d, 0x05, 0x9d, 0x05, 0xb9, 0x04, 0x51, 0x04,
1740bbfda8aSnia	0xe9, 0x04, 0xcd, 0x05, 0x85, 0x05, 0x01, 0x04, 0xff, 0x07
1750bbfda8aSnia};
1760bbfda8aSnia
1770bbfda8aSniaPixmap
1780bbfda8aSniaCreate3DIconManagerIcon(ColorPair cp)
1790bbfda8aSnia{
1800bbfda8aSnia	struct Colori *col;
1810bbfda8aSnia	static struct Colori *colori = NULL;
1820bbfda8aSnia	const unsigned int w = im_iconified_icon_width;
1830bbfda8aSnia	const unsigned int h = im_iconified_icon_height;
1840bbfda8aSnia
1850bbfda8aSnia	/*
1860bbfda8aSnia	 * Keep a list of ones we've made, and if we've already made one this
1870bbfda8aSnia	 * color, just hand it back.
1880bbfda8aSnia	 */
1890bbfda8aSnia	for(col = colori; col; col = col->next) {
1900bbfda8aSnia		if(col->color == cp.back) {
1910bbfda8aSnia			return col->pix;
1920bbfda8aSnia		}
1930bbfda8aSnia	}
1940bbfda8aSnia
1950bbfda8aSnia	/* Don't have one this color yet, make it */
1960bbfda8aSnia	col = malloc(sizeof(struct Colori));
1970bbfda8aSnia	col->color = cp.back;
1980bbfda8aSnia	col->pix   = XCreatePixmap(dpy, Scr->Root, w, h, Scr->d_depth);
1990bbfda8aSnia	Draw3DBorder(col->pix, 0, 0, w, h, 4, cp, off, true, false);
2000bbfda8aSnia
2010bbfda8aSnia	/* Add to the cache list so we hit the above next time */
2020bbfda8aSnia	col->next = colori;
2030bbfda8aSnia	colori = col;
2040bbfda8aSnia
2050bbfda8aSnia	return colori->pix;
2060bbfda8aSnia}
2070bbfda8aSnia
2080bbfda8aSniaPixmap
2090bbfda8aSniaCreate2DIconManagerIcon(void)
2100bbfda8aSnia{
2110bbfda8aSnia	char *bits = (char *)im_iconified_icon_bits;
2120bbfda8aSnia	const unsigned int w = im_iconified_icon_width;
2130bbfda8aSnia	const unsigned int h = im_iconified_icon_height;
2140bbfda8aSnia
2150bbfda8aSnia	return XCreatePixmapFromBitmapData(dpy, Scr->Root, bits, w, h, 1, 0, 1);
2160bbfda8aSnia}
217