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