18fa2b2a7SDavid du Colombier #include <u.h>
28fa2b2a7SDavid du Colombier #include <libc.h>
38fa2b2a7SDavid du Colombier #include <bio.h>
48fa2b2a7SDavid du Colombier #include <draw.h>
58fa2b2a7SDavid du Colombier #include <event.h>
68fa2b2a7SDavid du Colombier #include <cursor.h>
78fa2b2a7SDavid du Colombier
88fa2b2a7SDavid du Colombier typedef struct Icon Icon;
98fa2b2a7SDavid du Colombier struct Icon
108fa2b2a7SDavid du Colombier {
118fa2b2a7SDavid du Colombier Icon *next;
128fa2b2a7SDavid du Colombier
138fa2b2a7SDavid du Colombier uchar w; /* icon width */
148fa2b2a7SDavid du Colombier uchar h; /* icon height */
158fa2b2a7SDavid du Colombier ushort ncolor; /* number of colors */
168fa2b2a7SDavid du Colombier ushort nplane; /* number of bit planes */
178fa2b2a7SDavid du Colombier ushort bits; /* bits per pixel */
188fa2b2a7SDavid du Colombier ulong len; /* length of data */
198fa2b2a7SDavid du Colombier ulong offset; /* file offset to data */
208fa2b2a7SDavid du Colombier
218fa2b2a7SDavid du Colombier Image *img;
228fa2b2a7SDavid du Colombier Image *mask;
238fa2b2a7SDavid du Colombier
248fa2b2a7SDavid du Colombier Rectangle r; /* relative */
258fa2b2a7SDavid du Colombier Rectangle sr; /* abs */
268fa2b2a7SDavid du Colombier };
278fa2b2a7SDavid du Colombier
288fa2b2a7SDavid du Colombier typedef struct Header Header;
298fa2b2a7SDavid du Colombier struct Header
308fa2b2a7SDavid du Colombier {
318fa2b2a7SDavid du Colombier uint n;
328fa2b2a7SDavid du Colombier Icon *first;
338fa2b2a7SDavid du Colombier Icon *last;
348fa2b2a7SDavid du Colombier };
358fa2b2a7SDavid du Colombier
368fa2b2a7SDavid du Colombier int debug;
378fa2b2a7SDavid du Colombier Mouse mouse;
388fa2b2a7SDavid du Colombier Header h;
398fa2b2a7SDavid du Colombier Image *background;
408fa2b2a7SDavid du Colombier
418fa2b2a7SDavid du Colombier ushort
gets(uchar * p)428fa2b2a7SDavid du Colombier gets(uchar *p)
438fa2b2a7SDavid du Colombier {
448fa2b2a7SDavid du Colombier return p[0] | (p[1]<<8);
458fa2b2a7SDavid du Colombier }
468fa2b2a7SDavid du Colombier
478fa2b2a7SDavid du Colombier ulong
getl(uchar * p)488fa2b2a7SDavid du Colombier getl(uchar *p)
498fa2b2a7SDavid du Colombier {
508fa2b2a7SDavid du Colombier return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
518fa2b2a7SDavid du Colombier }
528fa2b2a7SDavid du Colombier
538fa2b2a7SDavid du Colombier int
Bgetheader(Biobuf * b,Header * h)548fa2b2a7SDavid du Colombier Bgetheader(Biobuf *b, Header *h)
558fa2b2a7SDavid du Colombier {
568fa2b2a7SDavid du Colombier Icon *icon;
578fa2b2a7SDavid du Colombier int i;
588fa2b2a7SDavid du Colombier uchar buf[40];
598fa2b2a7SDavid du Colombier
608fa2b2a7SDavid du Colombier memset(h, 0, sizeof(*h));
618fa2b2a7SDavid du Colombier if(Bread(b, buf, 6) != 6)
628fa2b2a7SDavid du Colombier goto eof;
638fa2b2a7SDavid du Colombier if(gets(&buf[0]) != 0)
648fa2b2a7SDavid du Colombier goto header;
658fa2b2a7SDavid du Colombier if(gets(&buf[2]) != 1)
668fa2b2a7SDavid du Colombier goto header;
678fa2b2a7SDavid du Colombier h->n = gets(&buf[4]);
688fa2b2a7SDavid du Colombier
698fa2b2a7SDavid du Colombier for(i = 0; i < h->n; i++){
708fa2b2a7SDavid du Colombier icon = mallocz(sizeof(*icon), 1);
718fa2b2a7SDavid du Colombier if(icon == nil)
728fa2b2a7SDavid du Colombier sysfatal("malloc: %r");
738fa2b2a7SDavid du Colombier if(Bread(b, buf, 16) != 16)
748fa2b2a7SDavid du Colombier goto eof;
758fa2b2a7SDavid du Colombier icon->w = buf[0];
768fa2b2a7SDavid du Colombier icon->h = buf[1];
778fa2b2a7SDavid du Colombier icon->ncolor = buf[2] == 0 ? 256 : buf[2];
788fa2b2a7SDavid du Colombier if(buf[3] != 0)
798fa2b2a7SDavid du Colombier goto header;
808fa2b2a7SDavid du Colombier icon->nplane = gets(&buf[4]);
818fa2b2a7SDavid du Colombier icon->bits = gets(&buf[6]);
828fa2b2a7SDavid du Colombier icon->len = getl(&buf[8]);
838fa2b2a7SDavid du Colombier icon->offset = getl(&buf[12]);
848fa2b2a7SDavid du Colombier
858fa2b2a7SDavid du Colombier if(i == 0)
868fa2b2a7SDavid du Colombier h->first = icon;
878fa2b2a7SDavid du Colombier else
888fa2b2a7SDavid du Colombier h->last->next = icon;
898fa2b2a7SDavid du Colombier h->last = icon;
908fa2b2a7SDavid du Colombier }
918fa2b2a7SDavid du Colombier return 0;
928fa2b2a7SDavid du Colombier
938fa2b2a7SDavid du Colombier eof:
948fa2b2a7SDavid du Colombier werrstr("unexpected EOF");
958fa2b2a7SDavid du Colombier return -1;
968fa2b2a7SDavid du Colombier header:
978fa2b2a7SDavid du Colombier werrstr("unknown header format");
988fa2b2a7SDavid du Colombier return -1;
998fa2b2a7SDavid du Colombier }
1008fa2b2a7SDavid du Colombier
1018fa2b2a7SDavid du Colombier uchar*
transcmap(Icon * icon,uchar * map)1028fa2b2a7SDavid du Colombier transcmap(Icon *icon, uchar *map)
1038fa2b2a7SDavid du Colombier {
1048fa2b2a7SDavid du Colombier uchar *m, *p;
1058fa2b2a7SDavid du Colombier int i;
1068fa2b2a7SDavid du Colombier
1078fa2b2a7SDavid du Colombier p = m = malloc(sizeof(int)*(1<<icon->bits));
1088fa2b2a7SDavid du Colombier for(i = 0; i < icon->ncolor; i++){
1098fa2b2a7SDavid du Colombier *p++ = rgb2cmap(map[2], map[1], map[0]);
1108fa2b2a7SDavid du Colombier map += 4;
1118fa2b2a7SDavid du Colombier }
1128fa2b2a7SDavid du Colombier return m;
1138fa2b2a7SDavid du Colombier }
1148fa2b2a7SDavid du Colombier
1158fa2b2a7SDavid du Colombier Image*
xor2img(Icon * icon,uchar * xor,uchar * map)1168fa2b2a7SDavid du Colombier xor2img(Icon *icon, uchar *xor, uchar *map)
1178fa2b2a7SDavid du Colombier {
1188fa2b2a7SDavid du Colombier uchar *data;
1198fa2b2a7SDavid du Colombier Image *img;
1208fa2b2a7SDavid du Colombier int inxlen;
1218fa2b2a7SDavid du Colombier uchar *from, *to;
1228fa2b2a7SDavid du Colombier int s, byte, mask;
1238fa2b2a7SDavid du Colombier int x, y;
1248fa2b2a7SDavid du Colombier
1258fa2b2a7SDavid du Colombier inxlen = 4*((icon->bits*icon->w+31)/32);
1268fa2b2a7SDavid du Colombier to = data = malloc(icon->w*icon->h);
1278fa2b2a7SDavid du Colombier
1288fa2b2a7SDavid du Colombier /* rotate around the y axis, go to 8 bits, and convert color */
1298fa2b2a7SDavid du Colombier mask = (1<<icon->bits)-1;
1308fa2b2a7SDavid du Colombier for(y = 0; y < icon->h; y++){
1318fa2b2a7SDavid du Colombier s = -1;
1328fa2b2a7SDavid du Colombier byte = 0;
1338fa2b2a7SDavid du Colombier from = xor + (icon->h - 1 - y)*inxlen;
1348fa2b2a7SDavid du Colombier for(x = 0; x < icon->w; x++){
1358fa2b2a7SDavid du Colombier if(s < 0){
1368fa2b2a7SDavid du Colombier byte = *from++;
1378fa2b2a7SDavid du Colombier s = 8-icon->bits;
1388fa2b2a7SDavid du Colombier }
1398fa2b2a7SDavid du Colombier *to++ = map[(byte>>s) & mask];
1408fa2b2a7SDavid du Colombier s -= icon->bits;
1418fa2b2a7SDavid du Colombier }
1428fa2b2a7SDavid du Colombier }
1438fa2b2a7SDavid du Colombier
1448fa2b2a7SDavid du Colombier /* stick in an image */
1458fa2b2a7SDavid du Colombier img = allocimage(display, Rect(0,0,icon->w,icon->h), CMAP8, 0, DNofill);
1468fa2b2a7SDavid du Colombier loadimage(img, Rect(0,0,icon->w,icon->h), data, icon->h*icon->w);
1478fa2b2a7SDavid du Colombier
1488fa2b2a7SDavid du Colombier free(data);
1498fa2b2a7SDavid du Colombier return img;
1508fa2b2a7SDavid du Colombier }
1518fa2b2a7SDavid du Colombier
1528fa2b2a7SDavid du Colombier Image*
and2img(Icon * icon,uchar * and)1538fa2b2a7SDavid du Colombier and2img(Icon *icon, uchar *and)
1548fa2b2a7SDavid du Colombier {
1558fa2b2a7SDavid du Colombier uchar *data;
1568fa2b2a7SDavid du Colombier Image *img;
1578fa2b2a7SDavid du Colombier int inxlen;
1588fa2b2a7SDavid du Colombier int outxlen;
1598fa2b2a7SDavid du Colombier uchar *from, *to;
1608fa2b2a7SDavid du Colombier int x, y;
1618fa2b2a7SDavid du Colombier
1628fa2b2a7SDavid du Colombier inxlen = 4*((icon->w+31)/32);
1638fa2b2a7SDavid du Colombier to = data = malloc(inxlen*icon->h);
1648fa2b2a7SDavid du Colombier
1658fa2b2a7SDavid du Colombier /* rotate around the y axis and invert bits */
1668fa2b2a7SDavid du Colombier outxlen = (icon->w+7)/8;
1678fa2b2a7SDavid du Colombier for(y = 0; y < icon->h; y++){
1688fa2b2a7SDavid du Colombier from = and + (icon->h - 1 - y)*inxlen;
1698fa2b2a7SDavid du Colombier for(x = 0; x < outxlen; x++){
1708fa2b2a7SDavid du Colombier *to++ = ~(*from++);
1718fa2b2a7SDavid du Colombier }
1728fa2b2a7SDavid du Colombier }
1738fa2b2a7SDavid du Colombier
1748fa2b2a7SDavid du Colombier /* stick in an image */
1758fa2b2a7SDavid du Colombier img = allocimage(display, Rect(0,0,icon->w,icon->h), GREY1, 0, DNofill);
1768fa2b2a7SDavid du Colombier loadimage(img, Rect(0,0,icon->w,icon->h), data, icon->h*outxlen);
1778fa2b2a7SDavid du Colombier
1788fa2b2a7SDavid du Colombier free(data);
1798fa2b2a7SDavid du Colombier return img;
1808fa2b2a7SDavid du Colombier }
1818fa2b2a7SDavid du Colombier
1828fa2b2a7SDavid du Colombier int
Bgeticon(Biobuf * b,Icon * icon)1838fa2b2a7SDavid du Colombier Bgeticon(Biobuf *b, Icon *icon)
1848fa2b2a7SDavid du Colombier {
1858fa2b2a7SDavid du Colombier ulong l;
1868fa2b2a7SDavid du Colombier ushort s;
1878fa2b2a7SDavid du Colombier uchar *xor;
1888fa2b2a7SDavid du Colombier uchar *and;
1898fa2b2a7SDavid du Colombier uchar *cm;
1908fa2b2a7SDavid du Colombier uchar *buf;
1918fa2b2a7SDavid du Colombier uchar *map2map;
1928fa2b2a7SDavid du Colombier Image *img;
1938fa2b2a7SDavid du Colombier
1948fa2b2a7SDavid du Colombier Bseek(b, icon->offset, 0);
1958fa2b2a7SDavid du Colombier buf = malloc(icon->len);
1968fa2b2a7SDavid du Colombier if(buf == nil)
1978fa2b2a7SDavid du Colombier return -1;
1988fa2b2a7SDavid du Colombier if(Bread(b, buf, icon->len) != icon->len){
1998fa2b2a7SDavid du Colombier werrstr("unexpected EOF");
2008fa2b2a7SDavid du Colombier return -1;
2018fa2b2a7SDavid du Colombier }
2028fa2b2a7SDavid du Colombier
2038fa2b2a7SDavid du Colombier /* this header's info takes precedence over previous one */
2048fa2b2a7SDavid du Colombier if(getl(buf) != 40){
2058fa2b2a7SDavid du Colombier werrstr("bad icon header");
2068fa2b2a7SDavid du Colombier return -1;
2078fa2b2a7SDavid du Colombier }
2088fa2b2a7SDavid du Colombier l = getl(buf+4);
2098fa2b2a7SDavid du Colombier if(l != icon->w)
2108fa2b2a7SDavid du Colombier icon->w = l;
2118fa2b2a7SDavid du Colombier l = getl(buf+8);
2128fa2b2a7SDavid du Colombier if(l>>1 != icon->h)
2138fa2b2a7SDavid du Colombier icon->h = l>>1;
2148fa2b2a7SDavid du Colombier s = gets(buf+12);
2158fa2b2a7SDavid du Colombier if(s != icon->nplane)
2168fa2b2a7SDavid du Colombier icon->nplane = s;
2178fa2b2a7SDavid du Colombier s = gets(buf+14);
2188fa2b2a7SDavid du Colombier if(s != icon->bits)
2198fa2b2a7SDavid du Colombier icon->bits = s;
2208fa2b2a7SDavid du Colombier
2218fa2b2a7SDavid du Colombier /* limit what we handle */
2228fa2b2a7SDavid du Colombier switch(icon->bits){
2238fa2b2a7SDavid du Colombier case 1:
2248fa2b2a7SDavid du Colombier case 2:
2258fa2b2a7SDavid du Colombier case 4:
2268fa2b2a7SDavid du Colombier case 8:
2278fa2b2a7SDavid du Colombier break;
2288fa2b2a7SDavid du Colombier default:
2298fa2b2a7SDavid du Colombier werrstr("don't support %d bit pixels", icon->bits);
2308fa2b2a7SDavid du Colombier return -1;
2318fa2b2a7SDavid du Colombier }
2328fa2b2a7SDavid du Colombier if(icon->nplane != 1){
2338fa2b2a7SDavid du Colombier werrstr("don't support %d planes", icon->nplane);
2348fa2b2a7SDavid du Colombier return -1;
2358fa2b2a7SDavid du Colombier }
2368fa2b2a7SDavid du Colombier
2378fa2b2a7SDavid du Colombier cm = buf + 40;
2388fa2b2a7SDavid du Colombier xor = cm + 4*icon->ncolor;
2398fa2b2a7SDavid du Colombier and = xor + icon->h*4*((icon->bits*icon->w+31)/32);
2408fa2b2a7SDavid du Colombier
2418fa2b2a7SDavid du Colombier /* translate the color map to a plan 9 one */
2428fa2b2a7SDavid du Colombier map2map = transcmap(icon, cm);
2438fa2b2a7SDavid du Colombier
2448fa2b2a7SDavid du Colombier /* convert the images */
2458fa2b2a7SDavid du Colombier icon->img = xor2img(icon, xor, map2map);
2468fa2b2a7SDavid du Colombier icon->mask = and2img(icon, and);
2478fa2b2a7SDavid du Colombier
2488fa2b2a7SDavid du Colombier /* so that we save an image with a white background */
2498fa2b2a7SDavid du Colombier img = allocimage(display, icon->img->r, CMAP8, 0, DWhite);
2508fa2b2a7SDavid du Colombier draw(img, icon->img->r, icon->img, icon->mask, ZP);
2518fa2b2a7SDavid du Colombier icon->img = img;
2528fa2b2a7SDavid du Colombier
2538fa2b2a7SDavid du Colombier free(buf);
2548fa2b2a7SDavid du Colombier free(map2map);
2558fa2b2a7SDavid du Colombier return 0;
2568fa2b2a7SDavid du Colombier }
2578fa2b2a7SDavid du Colombier
2588fa2b2a7SDavid du Colombier void
usage(void)2598fa2b2a7SDavid du Colombier usage(void)
2608fa2b2a7SDavid du Colombier {
2618fa2b2a7SDavid du Colombier fprint(2, "usage: %s [file]\n", argv0);
2628fa2b2a7SDavid du Colombier exits("usage");
2638fa2b2a7SDavid du Colombier }
2648fa2b2a7SDavid du Colombier
2658fa2b2a7SDavid du Colombier enum
2668fa2b2a7SDavid du Colombier {
2678fa2b2a7SDavid du Colombier Mimage,
2688fa2b2a7SDavid du Colombier Mmask,
2698fa2b2a7SDavid du Colombier Mexit,
2708fa2b2a7SDavid du Colombier
2718fa2b2a7SDavid du Colombier Up= 1,
2728fa2b2a7SDavid du Colombier Down= 0,
2738fa2b2a7SDavid du Colombier };
2748fa2b2a7SDavid du Colombier
2758fa2b2a7SDavid du Colombier char *menu3str[] = {
2768fa2b2a7SDavid du Colombier [Mimage] "write image",
2778fa2b2a7SDavid du Colombier [Mmask] "write mask",
2788fa2b2a7SDavid du Colombier [Mexit] "exit",
2798fa2b2a7SDavid du Colombier 0,
2808fa2b2a7SDavid du Colombier };
2818fa2b2a7SDavid du Colombier
2828fa2b2a7SDavid du Colombier Menu menu3 = {
2838fa2b2a7SDavid du Colombier menu3str
2848fa2b2a7SDavid du Colombier };
2858fa2b2a7SDavid du Colombier
2868fa2b2a7SDavid du Colombier Cursor sight = {
2878fa2b2a7SDavid du Colombier {-7, -7},
2888fa2b2a7SDavid du Colombier {0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
2898fa2b2a7SDavid du Colombier 0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
2908fa2b2a7SDavid du Colombier 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
2918fa2b2a7SDavid du Colombier 0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8,},
2928fa2b2a7SDavid du Colombier {0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
2938fa2b2a7SDavid du Colombier 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
2948fa2b2a7SDavid du Colombier 0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
2958fa2b2a7SDavid du Colombier 0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00,}
2968fa2b2a7SDavid du Colombier };
2978fa2b2a7SDavid du Colombier
2988fa2b2a7SDavid du Colombier void
buttons(int ud)2998fa2b2a7SDavid du Colombier buttons(int ud)
3008fa2b2a7SDavid du Colombier {
3018fa2b2a7SDavid du Colombier while((mouse.buttons==0) != ud)
3028fa2b2a7SDavid du Colombier mouse = emouse();
3038fa2b2a7SDavid du Colombier }
3048fa2b2a7SDavid du Colombier
3058fa2b2a7SDavid du Colombier void
mesg(char * fmt,...)3068fa2b2a7SDavid du Colombier mesg(char *fmt, ...)
3078fa2b2a7SDavid du Colombier {
3088fa2b2a7SDavid du Colombier va_list arg;
3098fa2b2a7SDavid du Colombier char buf[1024];
3108fa2b2a7SDavid du Colombier static char obuf[1024];
3118fa2b2a7SDavid du Colombier
3128fa2b2a7SDavid du Colombier va_start(arg, fmt);
3138fa2b2a7SDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg);
3148fa2b2a7SDavid du Colombier va_end(arg);
3158fa2b2a7SDavid du Colombier string(screen, screen->r.min, background, ZP, font, obuf);
3168fa2b2a7SDavid du Colombier string(screen, screen->r.min, display->white, ZP, font, buf);
3178fa2b2a7SDavid du Colombier strcpy(obuf, buf);
3188fa2b2a7SDavid du Colombier }
3198fa2b2a7SDavid du Colombier
3208fa2b2a7SDavid du Colombier void
doimage(Icon * icon)3218fa2b2a7SDavid du Colombier doimage(Icon *icon)
3228fa2b2a7SDavid du Colombier {
3238fa2b2a7SDavid du Colombier int rv;
3248fa2b2a7SDavid du Colombier char file[256];
3258fa2b2a7SDavid du Colombier int fd;
3268fa2b2a7SDavid du Colombier
3278fa2b2a7SDavid du Colombier rv = -1;
3288fa2b2a7SDavid du Colombier snprint(file, sizeof(file), "%dx%d.img", icon->w, icon->h);
3298fa2b2a7SDavid du Colombier fd = create(file, OWRITE, 0664);
3308fa2b2a7SDavid du Colombier if(fd >= 0){
3318fa2b2a7SDavid du Colombier rv = writeimage(fd, icon->img, 0);
3328fa2b2a7SDavid du Colombier close(fd);
3338fa2b2a7SDavid du Colombier }
3348fa2b2a7SDavid du Colombier if(rv < 0)
3358fa2b2a7SDavid du Colombier mesg("error writing %s: %r", file);
3368fa2b2a7SDavid du Colombier else
3378fa2b2a7SDavid du Colombier mesg("created %s", file);
3388fa2b2a7SDavid du Colombier }
3398fa2b2a7SDavid du Colombier
3408fa2b2a7SDavid du Colombier void
domask(Icon * icon)3418fa2b2a7SDavid du Colombier domask(Icon *icon)
3428fa2b2a7SDavid du Colombier {
3438fa2b2a7SDavid du Colombier int rv;
3448fa2b2a7SDavid du Colombier char file[64];
3458fa2b2a7SDavid du Colombier int fd;
3468fa2b2a7SDavid du Colombier
3478fa2b2a7SDavid du Colombier rv = -1;
3488fa2b2a7SDavid du Colombier snprint(file, sizeof(file), "%dx%d.mask", icon->w, icon->h);
3498fa2b2a7SDavid du Colombier fd = create(file, OWRITE, 0664);
3508fa2b2a7SDavid du Colombier if(fd >= 0){
3518fa2b2a7SDavid du Colombier rv = writeimage(fd, icon->mask, 0);
3528fa2b2a7SDavid du Colombier close(fd);
3538fa2b2a7SDavid du Colombier }
3548fa2b2a7SDavid du Colombier if(rv < 0)
3558fa2b2a7SDavid du Colombier mesg("error writing %s: %r", file);
3568fa2b2a7SDavid du Colombier else
3578fa2b2a7SDavid du Colombier mesg("created %s", file);
3588fa2b2a7SDavid du Colombier }
3598fa2b2a7SDavid du Colombier
3608fa2b2a7SDavid du Colombier void
apply(void (* f)(Icon *))3618fa2b2a7SDavid du Colombier apply(void (*f)(Icon*))
3628fa2b2a7SDavid du Colombier {
3638fa2b2a7SDavid du Colombier Icon *icon;
3648fa2b2a7SDavid du Colombier
3658fa2b2a7SDavid du Colombier esetcursor(&sight);
3668fa2b2a7SDavid du Colombier buttons(Down);
3678fa2b2a7SDavid du Colombier if(mouse.buttons == 4)
3688fa2b2a7SDavid du Colombier for(icon = h.first; icon; icon = icon->next)
3698fa2b2a7SDavid du Colombier if(ptinrect(mouse.xy, icon->sr)){
3708fa2b2a7SDavid du Colombier buttons(Up);
3718fa2b2a7SDavid du Colombier f(icon);
3728fa2b2a7SDavid du Colombier break;
3738fa2b2a7SDavid du Colombier }
3748fa2b2a7SDavid du Colombier buttons(Up);
3758fa2b2a7SDavid du Colombier esetcursor(0);
3768fa2b2a7SDavid du Colombier }
3778fa2b2a7SDavid du Colombier
3788fa2b2a7SDavid du Colombier void
menu(void)3798fa2b2a7SDavid du Colombier menu(void)
3808fa2b2a7SDavid du Colombier {
3818fa2b2a7SDavid du Colombier int sel;
3828fa2b2a7SDavid du Colombier
3838fa2b2a7SDavid du Colombier sel = emenuhit(3, &mouse, &menu3);
3848fa2b2a7SDavid du Colombier switch(sel){
3858fa2b2a7SDavid du Colombier case Mimage:
3868fa2b2a7SDavid du Colombier apply(doimage);
3878fa2b2a7SDavid du Colombier break;
3888fa2b2a7SDavid du Colombier case Mmask:
3898fa2b2a7SDavid du Colombier apply(domask);
3908fa2b2a7SDavid du Colombier break;
3918fa2b2a7SDavid du Colombier case Mexit:
3928fa2b2a7SDavid du Colombier exits(0);
3938fa2b2a7SDavid du Colombier break;
3948fa2b2a7SDavid du Colombier }
3958fa2b2a7SDavid du Colombier }
3968fa2b2a7SDavid du Colombier
3978fa2b2a7SDavid du Colombier void
mousemoved(void)3988fa2b2a7SDavid du Colombier mousemoved(void)
3998fa2b2a7SDavid du Colombier {
4008fa2b2a7SDavid du Colombier Icon *icon;
4018fa2b2a7SDavid du Colombier
4028fa2b2a7SDavid du Colombier for(icon = h.first; icon; icon = icon->next)
4038fa2b2a7SDavid du Colombier if(ptinrect(mouse.xy, icon->sr)){
4048fa2b2a7SDavid du Colombier mesg("%dx%d", icon->w, icon->h);
4058fa2b2a7SDavid du Colombier return;
4068fa2b2a7SDavid du Colombier }
4078fa2b2a7SDavid du Colombier mesg("");
4088fa2b2a7SDavid du Colombier }
4098fa2b2a7SDavid du Colombier
4108fa2b2a7SDavid du Colombier enum
4118fa2b2a7SDavid du Colombier {
4128fa2b2a7SDavid du Colombier BORDER= 1,
4138fa2b2a7SDavid du Colombier };
4148fa2b2a7SDavid du Colombier
4158fa2b2a7SDavid du Colombier void
eresized(int new)4168fa2b2a7SDavid du Colombier eresized(int new)
4178fa2b2a7SDavid du Colombier {
4188fa2b2a7SDavid du Colombier Icon *icon;
4198fa2b2a7SDavid du Colombier Rectangle r;
4208fa2b2a7SDavid du Colombier
4218fa2b2a7SDavid du Colombier if(new && getwindow(display, Refnone) < 0)
4228fa2b2a7SDavid du Colombier sysfatal("can't reattach to window");
4238fa2b2a7SDavid du Colombier draw(screen, screen->clipr, background, nil, ZP);
4248fa2b2a7SDavid du Colombier r.max.x = screen->r.min.x;
4258fa2b2a7SDavid du Colombier r.min.y = screen->r.min.y + font->height + 2*BORDER;
4268fa2b2a7SDavid du Colombier for(icon = h.first; icon != nil; icon = icon->next){
4278fa2b2a7SDavid du Colombier r.min.x = r.max.x + BORDER;
4288fa2b2a7SDavid du Colombier r.max.x = r.min.x + Dx(icon->img->r);
4298fa2b2a7SDavid du Colombier r.max.y = r.min.y + Dy(icon->img->r);
4308fa2b2a7SDavid du Colombier draw(screen, r, icon->img, nil, ZP);
4318fa2b2a7SDavid du Colombier border(screen, r, -BORDER, display->black, ZP);
4328fa2b2a7SDavid du Colombier icon->sr = r;
4338fa2b2a7SDavid du Colombier }
4348fa2b2a7SDavid du Colombier flushimage(display, 1);
4358fa2b2a7SDavid du Colombier }
4368fa2b2a7SDavid du Colombier
4378fa2b2a7SDavid du Colombier void
main(int argc,char ** argv)4388fa2b2a7SDavid du Colombier main(int argc, char **argv)
4398fa2b2a7SDavid du Colombier {
4408fa2b2a7SDavid du Colombier Biobuf in;
4418fa2b2a7SDavid du Colombier Icon *icon;
442*e6d20ddfSDavid du Colombier int num, fd;
4438fa2b2a7SDavid du Colombier Rectangle r;
4448fa2b2a7SDavid du Colombier Event e;
4458fa2b2a7SDavid du Colombier
4468fa2b2a7SDavid du Colombier ARGBEGIN{
4478fa2b2a7SDavid du Colombier case 'd':
4488fa2b2a7SDavid du Colombier debug = 1;
4498fa2b2a7SDavid du Colombier break;
4508fa2b2a7SDavid du Colombier }ARGEND;
4518fa2b2a7SDavid du Colombier
4528fa2b2a7SDavid du Colombier fd = -1;
4538fa2b2a7SDavid du Colombier switch(argc){
4548fa2b2a7SDavid du Colombier case 0:
4558fa2b2a7SDavid du Colombier fd = 0;
4568fa2b2a7SDavid du Colombier break;
4578fa2b2a7SDavid du Colombier case 1:
4588fa2b2a7SDavid du Colombier fd = open(argv[0], OREAD);
4598fa2b2a7SDavid du Colombier if(fd < 0)
4608fa2b2a7SDavid du Colombier sysfatal("opening: %r");
4618fa2b2a7SDavid du Colombier break;
4628fa2b2a7SDavid du Colombier default:
4638fa2b2a7SDavid du Colombier usage();
4648fa2b2a7SDavid du Colombier break;
4658fa2b2a7SDavid du Colombier }
4668fa2b2a7SDavid du Colombier
4678fa2b2a7SDavid du Colombier Binit(&in, fd, OREAD);
4688fa2b2a7SDavid du Colombier
4698fa2b2a7SDavid du Colombier if(Bgetheader(&in, &h) < 0)
4708fa2b2a7SDavid du Colombier sysfatal("reading header: %r");
4718fa2b2a7SDavid du Colombier
4728fa2b2a7SDavid du Colombier initdraw(nil, nil, "ico");
4738fa2b2a7SDavid du Colombier background = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, (128<<24)|(128<<16)|(128<<8)|0xFF);
4748fa2b2a7SDavid du Colombier
4758fa2b2a7SDavid du Colombier einit(Emouse|Ekeyboard);
4768fa2b2a7SDavid du Colombier
477*e6d20ddfSDavid du Colombier num = 0;
4788fa2b2a7SDavid du Colombier r.min = Pt(4, 4);
4798fa2b2a7SDavid du Colombier for(icon = h.first; icon != nil; icon = icon->next){
4808fa2b2a7SDavid du Colombier if(Bgeticon(&in, icon) < 0){
481*e6d20ddfSDavid du Colombier fprint(2, "%s: read fail: %r\n", argv0);
4828fa2b2a7SDavid du Colombier continue;
4838fa2b2a7SDavid du Colombier }
4848fa2b2a7SDavid du Colombier if(debug)
4858fa2b2a7SDavid du Colombier fprint(2, "w %ud h %ud ncolor %ud bits %ud len %lud offset %lud\n",
4868fa2b2a7SDavid du Colombier icon->w, icon->h, icon->ncolor, icon->bits, icon->len, icon->offset);
4878fa2b2a7SDavid du Colombier r.max = addpt(r.min, Pt(icon->w, icon->h));
4888fa2b2a7SDavid du Colombier icon->r = r;
4898fa2b2a7SDavid du Colombier r.min.x += r.max.x;
490*e6d20ddfSDavid du Colombier num++;
4918fa2b2a7SDavid du Colombier }
492*e6d20ddfSDavid du Colombier
493*e6d20ddfSDavid du Colombier if(num == 0)
494*e6d20ddfSDavid du Colombier exits("no images");
4958fa2b2a7SDavid du Colombier eresized(0);
4968fa2b2a7SDavid du Colombier
4978fa2b2a7SDavid du Colombier for(;;)
4988fa2b2a7SDavid du Colombier switch(event(&e)){
4998fa2b2a7SDavid du Colombier case Ekeyboard:
5008fa2b2a7SDavid du Colombier break;
5018fa2b2a7SDavid du Colombier case Emouse:
5028fa2b2a7SDavid du Colombier mouse = e.mouse;
5038fa2b2a7SDavid du Colombier if(mouse.buttons & 4)
5048fa2b2a7SDavid du Colombier menu();
5058fa2b2a7SDavid du Colombier else
5068fa2b2a7SDavid du Colombier mousemoved();
5078fa2b2a7SDavid du Colombier break;
5088fa2b2a7SDavid du Colombier }
509b85a8364SDavid du Colombier /* not reached */
5108fa2b2a7SDavid du Colombier }
511