1/* 2 * Built-in icon building 3 * 4 * This conceptually overlaps pretty strongly with 5 * image_bitmap_builtin.c, since both are about drawing some built-in 6 * images used for internal stuff. They're kept separate because i_b_b 7 * is backend bits for GetImage() calls for ":xpm:", "%xpm:", and ":" 8 * images, while these are called directly from the code. Perhaps they 9 * should be subsumed under that, but they haven't been so far, so we're 10 * keeping them separate for now. 11 */ 12 13#include "ctwm.h" 14 15#include <stdlib.h> 16 17#include "drawing.h" 18#include "screen.h" 19#include "iconmgr.h" 20 21#include "icons_builtin.h" 22 23 24struct Colori { 25 Pixel color; 26 Pixmap pix; 27 struct Colori *next; 28}; 29 30 31/* 32 * The icons on menu items for submenus, in UseThreeDMenus and non 33 * variants. 34 */ 35Pixmap 36Create3DMenuIcon(unsigned int height, 37 unsigned int *widthp, unsigned int *heightp, 38 ColorPair cp) 39{ 40 unsigned int h, w; 41 int i; 42 struct Colori *col; 43 static struct Colori *colori = NULL; 44 45 h = height; 46 w = h * 7 / 8; 47 if(h < 1) { 48 h = 1; 49 } 50 if(w < 1) { 51 w = 1; 52 } 53 *widthp = w; 54 *heightp = h; 55 56 for(col = colori; col; col = col->next) { 57 if(col->color == cp.back) { 58 break; 59 } 60 } 61 if(col != NULL) { 62 return (col->pix); 63 } 64 col = malloc(sizeof(struct Colori)); 65 col->color = cp.back; 66 col->pix = XCreatePixmap(dpy, Scr->Root, h, h, Scr->d_depth); 67 col->next = colori; 68 colori = col; 69 70 Draw3DBorder(col->pix, 0, 0, w, h, 1, cp, off, true, false); 71 for(i = 3; i + 5 < h; i += 5) { 72 Draw3DBorder(col->pix, 4, i, w - 8, 3, 1, Scr->MenuC, off, true, false); 73 } 74 return (colori->pix); 75} 76 77Pixmap 78CreateMenuIcon(int height, unsigned int *widthp, unsigned int *heightp) 79{ 80 int h, w; 81 int ih, iw; 82 int ix, iy; 83 int mh, mw; 84 int tw, th; 85 int lw, lh; 86 int lx, ly; 87 int lines, dly; 88 int offset; 89 int bw; 90 91 h = height; 92 w = h * 7 / 8; 93 if(h < 1) { 94 h = 1; 95 } 96 if(w < 1) { 97 w = 1; 98 } 99 *widthp = w; 100 *heightp = h; 101 if(Scr->tbpm.menu == None) { 102 Pixmap pix; 103 GC gc; 104 105 pix = Scr->tbpm.menu = XCreatePixmap(dpy, Scr->Root, w, h, 1); 106 gc = XCreateGC(dpy, pix, 0L, NULL); 107 XSetForeground(dpy, gc, 0L); 108 XFillRectangle(dpy, pix, gc, 0, 0, w, h); 109 XSetForeground(dpy, gc, 1L); 110 ix = 1; 111 iy = 1; 112 ih = h - iy * 2; 113 iw = w - ix * 2; 114 offset = ih / 8; 115 mh = ih - offset; 116 mw = iw - offset; 117 bw = mh / 16; 118 if(bw == 0 && mw > 2) { 119 bw = 1; 120 } 121 tw = mw - bw * 2; 122 th = mh - bw * 2; 123 XFillRectangle(dpy, pix, gc, ix, iy, mw, mh); 124 XFillRectangle(dpy, pix, gc, ix + iw - mw, iy + ih - mh, mw, mh); 125 XSetForeground(dpy, gc, 0L); 126 XFillRectangle(dpy, pix, gc, ix + bw, iy + bw, tw, th); 127 XSetForeground(dpy, gc, 1L); 128 lw = tw / 2; 129 if((tw & 1) ^ (lw & 1)) { 130 lw++; 131 } 132 lx = ix + bw + (tw - lw) / 2; 133 134 lh = th / 2 - bw; 135 if((lh & 1) ^ ((th - bw) & 1)) { 136 lh++; 137 } 138 ly = iy + bw + (th - bw - lh) / 2; 139 140 lines = 3; 141 if((lh & 1) && lh < 6) { 142 lines--; 143 } 144 dly = lh / (lines - 1); 145 while(lines--) { 146 XFillRectangle(dpy, pix, gc, lx, ly, lw, bw); 147 ly += dly; 148 } 149 XFreeGC(dpy, gc); 150 } 151 return Scr->tbpm.menu; 152} 153 154 155 156/* 157 * Icon used in the icon manager for iconified windows. 158 * 159 * For the 2d case, there's just one icon stored screen-wide, which is 160 * XCopyPlane()'d into the icon manager. This works because it's just a 161 * 2-color thing represented as a bitmap, and we color it to match the 162 * FG/BG of the row at the time. 163 * 164 * The 3d variant is more complicated, and doesn't just use the row's 165 * FG/BG colors; it draws various shades from them. So since each row in 166 * an icon manager may be a different FG/BG color, we have to make a new 167 * one for each row. 168 */ 169 170const unsigned int im_iconified_icon_width = 11; 171const unsigned int im_iconified_icon_height = 11; 172static unsigned char im_iconified_icon_bits[] = { 173 0xff, 0x07, 0x01, 0x04, 0x0d, 0x05, 0x9d, 0x05, 0xb9, 0x04, 0x51, 0x04, 174 0xe9, 0x04, 0xcd, 0x05, 0x85, 0x05, 0x01, 0x04, 0xff, 0x07 175}; 176 177Pixmap 178Create3DIconManagerIcon(ColorPair cp) 179{ 180 struct Colori *col; 181 static struct Colori *colori = NULL; 182 const unsigned int w = im_iconified_icon_width; 183 const unsigned int h = im_iconified_icon_height; 184 185 /* 186 * Keep a list of ones we've made, and if we've already made one this 187 * color, just hand it back. 188 */ 189 for(col = colori; col; col = col->next) { 190 if(col->color == cp.back) { 191 return col->pix; 192 } 193 } 194 195 /* Don't have one this color yet, make it */ 196 col = malloc(sizeof(struct Colori)); 197 col->color = cp.back; 198 col->pix = XCreatePixmap(dpy, Scr->Root, w, h, Scr->d_depth); 199 Draw3DBorder(col->pix, 0, 0, w, h, 4, cp, off, true, false); 200 201 /* Add to the cache list so we hit the above next time */ 202 col->next = colori; 203 colori = col; 204 205 return colori->pix; 206} 207 208Pixmap 209Create2DIconManagerIcon(void) 210{ 211 char *bits = (char *)im_iconified_icon_bits; 212 const unsigned int w = im_iconified_icon_width; 213 const unsigned int h = im_iconified_icon_height; 214 215 return XCreatePixmapFromBitmapData(dpy, Scr->Root, bits, w, h, 1, 0, 1); 216} 217