17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <event.h>
57dd7cddfSDavid du Colombier
67dd7cddfSDavid du Colombier enum {
77dd7cddfSDavid du Colombier Edge = 5,
87dd7cddfSDavid du Colombier Maxmag = 16
97dd7cddfSDavid du Colombier };
107dd7cddfSDavid du Colombier
11*5e91980fSDavid du Colombier enum {
12*5e91980fSDavid du Colombier Mzoom,
13*5e91980fSDavid du Colombier Munzoom,
14*5e91980fSDavid du Colombier Mgrid,
15*5e91980fSDavid du Colombier Mredraw,
16*5e91980fSDavid du Colombier Mexit
17*5e91980fSDavid du Colombier };
18*5e91980fSDavid du Colombier
19*5e91980fSDavid du Colombier char *menustr[] = {
20*5e91980fSDavid du Colombier "zoom",
21*5e91980fSDavid du Colombier "unzoom",
22*5e91980fSDavid du Colombier "grid",
23*5e91980fSDavid du Colombier "redraw",
24*5e91980fSDavid du Colombier "exit",
25*5e91980fSDavid du Colombier nil
26*5e91980fSDavid du Colombier };
27*5e91980fSDavid du Colombier
28*5e91980fSDavid du Colombier Menu menu = {
29*5e91980fSDavid du Colombier menustr,
30*5e91980fSDavid du Colombier nil,
31*5e91980fSDavid du Colombier -1
32*5e91980fSDavid du Colombier };
33*5e91980fSDavid du Colombier
347dd7cddfSDavid du Colombier Point lastp;
357dd7cddfSDavid du Colombier Image *red;
367dd7cddfSDavid du Colombier Image *tmp;
373ff48bf5SDavid du Colombier Image *grid;
383ff48bf5SDavid du Colombier Image *chequer;
397dd7cddfSDavid du Colombier int screenfd;
407dd7cddfSDavid du Colombier int mag = 4;
413ff48bf5SDavid du Colombier int showgrid = 0;
427dd7cddfSDavid du Colombier Rectangle screenr;
437dd7cddfSDavid du Colombier uchar *screenbuf;
447dd7cddfSDavid du Colombier
457dd7cddfSDavid du Colombier void magnify(void);
463ff48bf5SDavid du Colombier void makegrid(void);
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier void
drawit(void)497dd7cddfSDavid du Colombier drawit(void)
507dd7cddfSDavid du Colombier {
513ff48bf5SDavid du Colombier Rectangle r;
527dd7cddfSDavid du Colombier border(screen, screen->r, Edge, red, ZP);
537dd7cddfSDavid du Colombier magnify();
543ff48bf5SDavid du Colombier r = insetrect(screen->r, Edge);
553ff48bf5SDavid du Colombier draw(screen, r, tmp, nil, tmp->r.min);
567dd7cddfSDavid du Colombier flushimage(display, 1);
577dd7cddfSDavid du Colombier }
587dd7cddfSDavid du Colombier
597dd7cddfSDavid du Colombier int bypp;
607dd7cddfSDavid du Colombier
617dd7cddfSDavid du Colombier void
main(int argc,char * argv[])627dd7cddfSDavid du Colombier main(int argc, char *argv[])
637dd7cddfSDavid du Colombier {
647dd7cddfSDavid du Colombier Event e;
657dd7cddfSDavid du Colombier char buf[5*12];
667dd7cddfSDavid du Colombier ulong chan;
677dd7cddfSDavid du Colombier int d;
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier USED(argc, argv);
707dd7cddfSDavid du Colombier if(initdraw(nil, nil, "lens") < 0){
717dd7cddfSDavid du Colombier fprint(2, "lens: initdraw failed: %r\n");
727dd7cddfSDavid du Colombier exits("initdraw");
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier einit(Emouse|Ekeyboard);
757dd7cddfSDavid du Colombier red = allocimage(display, Rect(0, 0, 1, 1), CMAP8, 1, DRed);
763ff48bf5SDavid du Colombier chequer = allocimage(display, Rect(0, 0, 2, 2), GREY1, 1, DBlack);
773ff48bf5SDavid du Colombier draw(chequer, Rect(0, 0, 1, 1), display->white, nil, ZP);
783ff48bf5SDavid du Colombier draw(chequer, Rect(1, 1, 2, 2), display->white, nil, ZP);
797dd7cddfSDavid du Colombier lastp = divpt(addpt(screen->r.min, screen->r.max), 2);
807dd7cddfSDavid du Colombier screenfd = open("/dev/screen", OREAD);
817dd7cddfSDavid du Colombier if(screenfd < 0){
827dd7cddfSDavid du Colombier fprint(2, "lens: can't open /dev/screen: %r\n");
837dd7cddfSDavid du Colombier exits("screen");
847dd7cddfSDavid du Colombier }
857dd7cddfSDavid du Colombier if(read(screenfd, buf, sizeof buf) != sizeof buf){
867dd7cddfSDavid du Colombier fprint(2, "lens: can't read /dev/screen: %r\n");
877dd7cddfSDavid du Colombier exits("screen");
887dd7cddfSDavid du Colombier }
897dd7cddfSDavid du Colombier chan = strtochan(buf);
907dd7cddfSDavid du Colombier d = chantodepth(chan);
917dd7cddfSDavid du Colombier if(d < 8){
927dd7cddfSDavid du Colombier fprint(2, "lens: can't handle screen format %11.11s\n", buf);
937dd7cddfSDavid du Colombier exits("screen");
947dd7cddfSDavid du Colombier }
957dd7cddfSDavid du Colombier bypp = d/8;
967dd7cddfSDavid du Colombier screenr.min.x = atoi(buf+1*12);
977dd7cddfSDavid du Colombier screenr.min.y = atoi(buf+2*12);
987dd7cddfSDavid du Colombier screenr.max.x = atoi(buf+3*12);
997dd7cddfSDavid du Colombier screenr.max.y = atoi(buf+4*12);
1007dd7cddfSDavid du Colombier screenbuf = malloc(bypp*Dx(screenr)*Dy(screenr));
1017dd7cddfSDavid du Colombier if(screenbuf == nil){
1027dd7cddfSDavid du Colombier fprint(2, "lens: buffer malloc failed: %r\n");
1037dd7cddfSDavid du Colombier exits("malloc");
1047dd7cddfSDavid du Colombier }
1057dd7cddfSDavid du Colombier eresized(0);
1067dd7cddfSDavid du Colombier
1077dd7cddfSDavid du Colombier for(;;)
1087dd7cddfSDavid du Colombier switch(event(&e)){
1097dd7cddfSDavid du Colombier case Ekeyboard:
1107dd7cddfSDavid du Colombier switch(e.kbdc){
1117dd7cddfSDavid du Colombier case 'q':
112*5e91980fSDavid du Colombier case 0x7f:
1137dd7cddfSDavid du Colombier case '\04':
114*5e91980fSDavid du Colombier caseexit:
1157dd7cddfSDavid du Colombier exits(nil);
1167dd7cddfSDavid du Colombier case '=':
1177dd7cddfSDavid du Colombier case '+':
118*5e91980fSDavid du Colombier casezoom:
1197dd7cddfSDavid du Colombier if(mag < Maxmag){
1207dd7cddfSDavid du Colombier mag++;
1213ff48bf5SDavid du Colombier makegrid();
1227dd7cddfSDavid du Colombier drawit();
1237dd7cddfSDavid du Colombier }
1247dd7cddfSDavid du Colombier break;
1253ff48bf5SDavid du Colombier case 'g':
126*5e91980fSDavid du Colombier casegrid:
1273ff48bf5SDavid du Colombier showgrid = !showgrid;
1283ff48bf5SDavid du Colombier makegrid();
1293ff48bf5SDavid du Colombier drawit();
1303ff48bf5SDavid du Colombier break;
1317dd7cddfSDavid du Colombier case '-':
1327dd7cddfSDavid du Colombier case '_':
133*5e91980fSDavid du Colombier caseunzoom:
1347dd7cddfSDavid du Colombier if(mag > 1){
1357dd7cddfSDavid du Colombier mag--;
1363ff48bf5SDavid du Colombier makegrid();
1377dd7cddfSDavid du Colombier drawit();
1387dd7cddfSDavid du Colombier }
1397dd7cddfSDavid du Colombier break;
1407dd7cddfSDavid du Colombier case '.':
1417dd7cddfSDavid du Colombier case ' ':
142*5e91980fSDavid du Colombier caseredraw:
1437dd7cddfSDavid du Colombier drawit();
1447dd7cddfSDavid du Colombier break;
1457dd7cddfSDavid du Colombier case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case'0':
1467dd7cddfSDavid du Colombier mag = e.kbdc-'0';
1477dd7cddfSDavid du Colombier if(mag == 0)
1487dd7cddfSDavid du Colombier mag = 10;
1493ff48bf5SDavid du Colombier makegrid();
1507dd7cddfSDavid du Colombier drawit();
1517dd7cddfSDavid du Colombier break;
1527dd7cddfSDavid du Colombier }
1537dd7cddfSDavid du Colombier break;
1547dd7cddfSDavid du Colombier case Emouse:
155*5e91980fSDavid du Colombier if(e.mouse.buttons & 1){
1567dd7cddfSDavid du Colombier lastp = e.mouse.xy;
1577dd7cddfSDavid du Colombier drawit();
1587dd7cddfSDavid du Colombier }
159*5e91980fSDavid du Colombier if(e.mouse.buttons & 4)
160*5e91980fSDavid du Colombier switch(emenuhit(3, &e.mouse, &menu)){
161*5e91980fSDavid du Colombier case Mzoom:
162*5e91980fSDavid du Colombier goto casezoom;
163*5e91980fSDavid du Colombier case Munzoom:
164*5e91980fSDavid du Colombier goto caseunzoom;
165*5e91980fSDavid du Colombier case Mgrid:
166*5e91980fSDavid du Colombier goto casegrid;
167*5e91980fSDavid du Colombier case Mredraw:
168*5e91980fSDavid du Colombier goto caseredraw;
169*5e91980fSDavid du Colombier case Mexit:
170*5e91980fSDavid du Colombier goto caseexit;
171*5e91980fSDavid du Colombier }
1727dd7cddfSDavid du Colombier break;
1737dd7cddfSDavid du Colombier }
1747dd7cddfSDavid du Colombier }
1757dd7cddfSDavid du Colombier
1767dd7cddfSDavid du Colombier void
makegrid(void)1773ff48bf5SDavid du Colombier makegrid(void)
1783ff48bf5SDavid du Colombier {
1796b6b9ac8SDavid du Colombier int m;
1803ff48bf5SDavid du Colombier if (grid != nil) {
1813ff48bf5SDavid du Colombier freeimage(grid);
1823ff48bf5SDavid du Colombier grid = nil;
1833ff48bf5SDavid du Colombier }
1843ff48bf5SDavid du Colombier if (showgrid) {
1856b6b9ac8SDavid du Colombier m = mag;
1866b6b9ac8SDavid du Colombier if (m < 5)
1876b6b9ac8SDavid du Colombier m *= 10;
1886b6b9ac8SDavid du Colombier grid = allocimage(display, Rect(0, 0, m, m),
1893ff48bf5SDavid du Colombier CHAN2(CGrey, 8, CAlpha, 8), 1, DTransparent);
1906b6b9ac8SDavid du Colombier if (grid != nil){
1916b6b9ac8SDavid du Colombier draw(grid, Rect(0, 0, m, 1), chequer, nil, ZP);
1926b6b9ac8SDavid du Colombier draw(grid, Rect(0, 1, 1, m), chequer, nil, ZP);
1933ff48bf5SDavid du Colombier }
1943ff48bf5SDavid du Colombier }
1953ff48bf5SDavid du Colombier }
1963ff48bf5SDavid du Colombier
1973ff48bf5SDavid du Colombier void
eresized(int new)1987dd7cddfSDavid du Colombier eresized(int new)
1997dd7cddfSDavid du Colombier {
2007dd7cddfSDavid du Colombier if(new && getwindow(display, Refnone) < 0){
2017dd7cddfSDavid du Colombier fprint(2, "lens: can't reattach to window: %r\n");
2027dd7cddfSDavid du Colombier exits("attach");
2037dd7cddfSDavid du Colombier }
2047dd7cddfSDavid du Colombier freeimage(tmp);
2057dd7cddfSDavid du Colombier tmp = allocimage(display, Rect(0, 0, Dx(screen->r)-Edge, Dy(screen->r)-Edge+Maxmag), screen->chan, 0, DNofill);
2067dd7cddfSDavid du Colombier if(tmp == nil){
2077dd7cddfSDavid du Colombier fprint(2, "lens: allocimage failed: %r\n");
2087dd7cddfSDavid du Colombier exits("allocimage");
2097dd7cddfSDavid du Colombier }
2107dd7cddfSDavid du Colombier drawit();
2117dd7cddfSDavid du Colombier }
2127dd7cddfSDavid du Colombier
2137dd7cddfSDavid du Colombier void
magnify(void)2147dd7cddfSDavid du Colombier magnify(void)
2157dd7cddfSDavid du Colombier {
2167dd7cddfSDavid du Colombier int x, y, xx, yy, dd, i;
2177dd7cddfSDavid du Colombier int dx, dy;
2187dd7cddfSDavid du Colombier int xoff, yoff;
2197dd7cddfSDavid du Colombier uchar out[8192];
2207dd7cddfSDavid du Colombier uchar sp[4];
2217dd7cddfSDavid du Colombier
2227dd7cddfSDavid du Colombier dx = (Dx(tmp->r)+mag-1)/mag;
2237dd7cddfSDavid du Colombier dy = (Dy(tmp->r)+mag-1)/mag;
2247dd7cddfSDavid du Colombier xoff = lastp.x-Dx(tmp->r)/(mag*2);
2257dd7cddfSDavid du Colombier yoff = lastp.y-Dy(tmp->r)/(mag*2);
2267dd7cddfSDavid du Colombier
2277dd7cddfSDavid du Colombier yy = yoff;
2287dd7cddfSDavid du Colombier dd = dy;
2297dd7cddfSDavid du Colombier if(yy < 0){
2307dd7cddfSDavid du Colombier dd += dy;
2317dd7cddfSDavid du Colombier yy = 0;
2327dd7cddfSDavid du Colombier }
2337dd7cddfSDavid du Colombier if(yy+dd > Dy(screenr))
2347dd7cddfSDavid du Colombier dd = Dy(screenr)-yy;
2357dd7cddfSDavid du Colombier seek(screenfd, 5*12+bypp*yy*Dx(screenr), 0);
2367dd7cddfSDavid du Colombier if(readn(screenfd, screenbuf+bypp*yy*Dx(screenr), bypp*Dx(screenr)*dd) != bypp*Dx(screenr)*dd){
2377dd7cddfSDavid du Colombier fprint(2, "lens: can't read screen: %r\n");
2387dd7cddfSDavid du Colombier return;
2397dd7cddfSDavid du Colombier }
2407dd7cddfSDavid du Colombier
2417dd7cddfSDavid du Colombier for(y=0; y<dy; y++){
2427dd7cddfSDavid du Colombier yy = yoff+y;
2437dd7cddfSDavid du Colombier if(yy>=0 && yy<Dy(screenr))
2447dd7cddfSDavid du Colombier for(x=0; x<dx; x++){
2457dd7cddfSDavid du Colombier xx = xoff+x;
2467dd7cddfSDavid du Colombier if(xx>=0 && xx<Dx(screenr)) /* snarf pixel at xx, yy */
2477dd7cddfSDavid du Colombier for(i=0; i<bypp; i++)
2487dd7cddfSDavid du Colombier sp[i] = screenbuf[bypp*(yy*Dx(screenr)+xx)+i];
2497dd7cddfSDavid du Colombier else
2507dd7cddfSDavid du Colombier sp[0] = sp[1] = sp[2] = sp[3] = 0;
2517dd7cddfSDavid du Colombier
2527dd7cddfSDavid du Colombier for(xx=0; xx<mag; xx++)
2537dd7cddfSDavid du Colombier if(x*mag+xx < tmp->r.max.x)
2547dd7cddfSDavid du Colombier for(i=0; i<bypp; i++)
2557dd7cddfSDavid du Colombier out[(x*mag+xx)*bypp+i] = sp[i];
2567dd7cddfSDavid du Colombier }
2577dd7cddfSDavid du Colombier else
2587dd7cddfSDavid du Colombier memset(out, 0, bypp*Dx(tmp->r));
2597dd7cddfSDavid du Colombier for(yy=0; yy<mag && y*mag+yy<Dy(tmp->r); yy++){
2607dd7cddfSDavid du Colombier werrstr("no error");
2617dd7cddfSDavid du Colombier if(loadimage(tmp, Rect(0, y*mag+yy, Dx(tmp->r), y*mag+yy+1), out, bypp*Dx(tmp->r)) != bypp*Dx(tmp->r)){
2627dd7cddfSDavid du Colombier exits("load");
2637dd7cddfSDavid du Colombier }
2647dd7cddfSDavid du Colombier }
2657dd7cddfSDavid du Colombier }
2666b6b9ac8SDavid du Colombier if (showgrid && mag && grid)
2676b6b9ac8SDavid du Colombier draw(tmp, tmp->r, grid, nil, mulpt(Pt(xoff, yoff), mag));
2687dd7cddfSDavid du Colombier }
269