|
|
1.1 ! root 1: #include <suntool/sunview.h> ! 2: #include <suntool/canvas.h> ! 3: #include <fcntl.h> ! 4: ! 5: ! 6: /* from jerq.h... */ ! 7: ! 8: typedef struct Point { ! 9: short x; ! 10: short y; ! 11: } Point; ! 12: ! 13: int muldiv(x,y,d) { return (x * y) / d; } ! 14: ! 15: Point pt(x, y) { Point p; p.x = x; p.y = y; return p; } ! 16: Point Pt(x, y) { Point p; p.x = x; p.y = y; return p; } ! 17: Point add(p1, p2) Point p1, p2; { p1.x += p2.x; p1.y += p2.y; return p1; } ! 18: Point sub(p1, p2) Point p1, p2; { p1.x -= p2.x; p1.y -= p2.y; return p1; } ! 19: ! 20: typedef struct Rectangle { ! 21: Point origin; ! 22: Point corner; ! 23: } Rectangle; ! 24: ! 25: Rectangle raddp(r, p) Rectangle r; Point p; ! 26: { ! 27: r.origin = add(r.origin, p); ! 28: r.corner = add(r.corner, p); ! 29: return r; ! 30: } ! 31: ! 32: Rectangle Rpt(p1,p2) Point p1, p2; ! 33: { ! 34: Rectangle r; ! 35: r.origin.x = p1.x; r.origin.y = p1.y; ! 36: r.corner.x = p2.x; r.corner.y = p2.y; ! 37: return r; ! 38: } ! 39: ! 40: Rectangle Rect4(x1,y1,x2,y2) ! 41: { ! 42: Rectangle r; ! 43: r.origin.x = x1; r.origin.y = y1; ! 44: r.corner.x = x2; r.corner.y = y2; ! 45: return r; ! 46: } ! 47: ! 48: Rectangle inset(r, n) Rectangle r; ! 49: { ! 50: r.origin.x += n; r.origin.y += n; ! 51: r.corner.x -= n; r.corner.y -= n; ! 52: return r; ! 53: } ! 54: ! 55: int eqpt(p1, p2) Point p1, p2; { return p1.x == p2.x && p1.y == p2.y; } ! 56: ! 57: Rectangle Drect; ! 58: #define Do Drect.origin ! 59: #define Dc Drect.corner ! 60: ! 61: Rectangle getrect23(); ! 62: Rectangle display; /* not used */ ! 63: int defont; ! 64: ! 65: /* bitblt function codes */ ! 66: #define F_STORE (PIX_SRC) /* target = source */ ! 67: #define F_OR (PIX_SRC|PIX_DST) /* target |= source */ ! 68: #define F_CLR (PIX_NOT(PIX_SRC)&(PIX_DST)) /* target &= ~source */ ! 69: #define F_XOR (PIX_SRC^PIX_DST) /* target ^= source */ ! 70: ! 71: Cursor *cursor,normalcursor,bullseye,coffeecup,sweep,deadmouse,lockarrow; ! 72: ! 73: #include "anim.h" ! 74: ! 75: typedef unsigned char uchar; ! 76: ! 77: #define PUT { char buf[100]; sprintf(buf, ! 78: #define END ); putstring(buf); } ! 79: #define readpoint(p) { p.x = readint(); p.y = readint(); } ! 80: #define readpair(p1,p2) { readpoint(p1); readpoint(p2); } ! 81: ! 82: /* holds data for all input objects */ ! 83: ! 84: unsigned memsize; /* bytes */ ! 85: uchar *inbuf; /* input collected here */ ! 86: uchar *input; /* leave a null at front */ ! 87: uchar *inp; /* next free slot in input */ ! 88: int nobj = 0; /* number of objects in input */ ! 89: int overflow = 0; /* 1 => too much input */ ! 90: ! 91: long slot[2000]; /* slots */ ! 92: int slotnum; ! 93: ! 94: extern uchar *savechar(), *draw_obj(), *click_obj(), *step_obj(); ! 95: extern uchar *prev_obj(), *next_obj(); ! 96: ! 97: extern Point readpt(), fetchpt(), scalept(); ! 98: int xmax, ymax; ! 99: ! 100: #define MAXVIEW 10 ! 101: char *viewname[MAXVIEW]; ! 102: typedef struct { ! 103: Rectangle vr; ! 104: int xmax; ! 105: int ymax; ! 106: } View; ! 107: View viewpt[MAXVIEW]; ! 108: int curview = 0; ! 109: int nview = 0; ! 110: #define INSET 4 /* picture inset from frame */ ! 111: ! 112: #define AW 8 /* arrowhead width and height */ ! 113: #define AH 10 ! 114: ! 115: #define MARGINPCT 6 ! 116: int margin = MARGINPCT; /* percent margin around edges */ ! 117: ! 118: #define MAXCLICK 20 ! 119: char *clickname[MAXCLICK]; /* click names */ ! 120: int clickval[MAXCLICK]; /* 1 => click on this */ ! 121: int clicking = 0; /* number of active clicks */ ! 122: int nclick = 0; ! 123: ! 124: char buf[200]; ! 125: char *pbuf; ! 126: ! 127: #define Again 0 /* Menu items -- must be 0.. */ ! 128: #define Faster (Again+1) ! 129: #define Slower (Faster+1) ! 130: #define Step (Slower+1) ! 131: #define Forward (Step+1) ! 132: #define Fatter (Forward+1) ! 133: #define Thinner (Fatter+1) ! 134: #define Xor (Thinner+1) ! 135: #define File (Xor+1) ! 136: #define Quit (File+1) /* ... down this far */ ! 137: #define Backward (Quit+1) /* subsequent names are arbitrary */ ! 138: #define Proceed (Backward+1) ! 139: #define Hit (Proceed+1) ! 140: #define FreeRun (Hit+1) ! 141: ! 142: int delay = 1; /* how long to delay between things */ ! 143: int singstep = 0; /* single step if 1 */ ! 144: #define Fwd 1 ! 145: #define Back 0 ! 146: int dir = Fwd; /* 1 = fwd, 0 = backward */ ! 147: int fatness = 0; /* n => draw with 2n+1 lines */ ! 148: int xormode = F_XOR; /* otherwise OR/CLR */ ! 149: ! 150: char *m3[] = { "again", "faster", "slower", "1 step", "backward", ! 151: "fatter", "thinner", "or mode", "new file", "Quit?", 0 }; ! 152: char *stepmenu[] = { "1 step", "run" }; ! 153: char *dirmenu[] = { "forward", "backward" }; ! 154: char *modemenu[] = { "or mode", "xor mode" }; ! 155: ! 156: char *m3gen(n) ! 157: { ! 158: static char buf[20][20]; ! 159: extern int delay; ! 160: ! 161: if (n < 0 || n > Quit) ! 162: return 0; ! 163: else if (n == Faster) { ! 164: sprintf(buf[n], "faster %d", delay); ! 165: return buf[n]; ! 166: } else if (n == Slower) { ! 167: sprintf(buf[n], "slower %d", delay); ! 168: return buf[n]; ! 169: } else if (n == Step) { ! 170: return stepmenu[singstep]; ! 171: } else if (n == Forward) { ! 172: return dirmenu[dir]; ! 173: } else if (n == Fatter) { ! 174: sprintf(buf[n], "fatter %d", fatness+1); ! 175: return buf[n]; ! 176: } else if (n == Thinner) { ! 177: sprintf(buf[n], "thinner %d", fatness+1); ! 178: return buf[n]; ! 179: } else if (n == Xor) { ! 180: return xormode == F_XOR ? modemenu[0] : modemenu[1]; ! 181: } else ! 182: return m3[n]; ! 183: } ! 184: ! 185: char *m2gen(n) ! 186: { ! 187: static char buf[20][50]; ! 188: ! 189: if (n < 0 || n >= nview+nclick) ! 190: return 0; ! 191: else if (n < nview) { ! 192: sprintf(buf[n], "view %s", viewname[n]); ! 193: return buf[n]; ! 194: } else { ! 195: sprintf(buf[n], "click %s%s", ! 196: clickname[n-nview], clickval[n-nview] ? "*" : ""); ! 197: return buf[n]; ! 198: } ! 199: } ! 200: ! 201: Menu mbut3; ! 202: Menu mbut2; ! 203: int last_hit; ! 204: int last_but; ! 205: ! 206: void inevent(); ! 207: ! 208: Canvas canvas; ! 209: Pixwin *pw; ! 210: int canvasfd; ! 211: int height, width; /* screen window */ ! 212: ! 213: init_params() ! 214: { ! 215: int i; ! 216: ! 217: for (i = 0; i < MAXCLICK; i++) ! 218: if (clickname[i]) { ! 219: free(clickname[i]); ! 220: clickname[i] = 0; ! 221: clickval[i] = 0; ! 222: } ! 223: for (i = 0; i < MAXVIEW; i++) ! 224: if (viewname[i]) { ! 225: free(viewname[i]); ! 226: viewname[i] = 0; ! 227: } ! 228: nclick = nview = curview = nobj = clicking = overflow = slotnum = 0; ! 229: } ! 230: ! 231: main() ! 232: { ! 233: int i, n; ! 234: Frame baseframe; ! 235: ! 236: baseframe = window_create(NULL, FRAME, FRAME_LABEL, "Anim", ! 237: WIN_ERROR_MSG, "Can't create Anim base window", 0); ! 238: canvas = window_create(baseframe, CANVAS, 0); ! 239: pw = canvas_pixwin(canvas); ! 240: canvasfd = (int)window_get(canvas, WIN_FD); ! 241: fcntl(canvasfd, F_SETFL, FNDELAY); /* allow nonblocking reads */ ! 242: width = (int)window_get(canvas, CANVAS_WIDTH); ! 243: height = (int)window_get(canvas, CANVAS_HEIGHT); ! 244: Drect.origin = pt(0,0); ! 245: Drect.corner = add(Drect.origin, pt(width,height)); ! 246: ! 247: do_rcv(); ! 248: ! 249: initmenus(); ! 250: initcursors(); ! 251: /* get these events by default: LOC_WINENTER, LOC_WINEXIT, LOC_MOVE, ! 252: MS_LEFT, MS_MIDDLE, MS_RIGHT */ ! 253: window_set(canvas, ! 254: WIN_CONSUME_KBD_EVENT, WIN_ASCII_EVENTS, ! 255: WIN_EVENT_PROC, inevent, 0); ! 256: window_main_loop(baseframe); ! 257: send1char(P_QUIT); /* tell host part we're done */ ! 258: flushproto(); ! 259: } ! 260: ! 261: initmenus() ! 262: { ! 263: int i; ! 264: char *s; ! 265: ! 266: mbut2 = menu_create(MENU_DEFAULT, 1, 0); ! 267: for (i = 0; s = m2gen(i); i++) ! 268: menu_set(mbut2, MENU_STRING_ITEM, s, i+1, 0); ! 269: mbut3 = menu_create(MENU_DEFAULT, 1, 0); ! 270: for (i = 0; m3[i]; i++) ! 271: menu_set(mbut3, MENU_STRING_ITEM, m3[i], i+1, 0); ! 272: } ! 273: ! 274: char kbdline[100]; /* collect keyboard input here */ ! 275: int kbdi = 0; /* kbdline index */ ! 276: ! 277: void inevent(c, e) ! 278: Canvas c; ! 279: Event *e; ! 280: { ! 281: int n, i, eid, ch; ! 282: char *s; ! 283: ! 284: eid = event_id(e); ! 285: switch (eid) { ! 286: default: ! 287: if (!event_is_ascii(e)) ! 288: return; ! 289: if (eid != '\n' && eid != '\r') { /* which do we get? */ ! 290: if (eid == '\b' && kbdi > 0) ! 291: kbdi--; ! 292: else ! 293: kbdline[kbdi++] = eid; ! 294: kbdline[kbdi] = '\0'; ! 295: putstring(kbdline); ! 296: return; ! 297: } ! 298: kbdline[kbdi] = '\0'; ! 299: kbdi = 0; ! 300: /* now we have a filename */ ! 301: send1char(P_FILE); ! 302: sendstring(kbdline); ! 303: if ((ch = readchar()) == P_FILE) { ! 304: do_rcv(); ! 305: } else { ! 306: PUT "can't open file %s", kbdline END; ! 307: } ! 308: return; ! 309: case WIN_RESIZE: ! 310: /* doesn't do much right now */ ! 311: width=(int)window_get(canvas, CANVAS_WIDTH); ! 312: height=(int)window_get(canvas, CANVAS_HEIGHT); ! 313: Drect.origin = pt(0,0); ! 314: Drect.corner = add(Drect.origin, pt(width,height)); ! 315: view_setup(nview); ! 316: return; ! 317: case MS_LEFT: /* button 1 */ ! 318: if (event_is_up(e)) ! 319: return; ! 320: last_but = 1; ! 321: last_hit = 0; ! 322: n = domouse(); ! 323: break; ! 324: case MS_MIDDLE: ! 325: if (event_is_up(e)) ! 326: return; ! 327: last_but = 2; ! 328: last_hit = (int) menu_show(mbut2, canvas, e, 0) - 1; ! 329: n = domouse(); ! 330: for (i = 0; s = m2gen(i); i++) ! 331: menu_set(menu_get(mbut2, MENU_NTH_ITEM, i+1), ! 332: MENU_STRING, s, 0); ! 333: if (last_hit >= 0) /* start with this selected next time */ ! 334: menu_set(mbut2, MENU_DEFAULT, last_hit+1, 0); ! 335: break; ! 336: case MS_RIGHT: ! 337: if (event_is_up(e)) ! 338: return; ! 339: last_but = 3; ! 340: last_hit = (int) menu_show(mbut3, canvas, e, 0) - 1; ! 341: n = domouse(); ! 342: for (i = 0; s = m3gen(i); i++) ! 343: menu_set(menu_get(mbut3, MENU_NTH_ITEM, i+1), ! 344: MENU_STRING, s, 0); ! 345: if (last_hit >= 0) /* start with this selected next time */ ! 346: menu_set(mbut3, MENU_DEFAULT, last_hit+1, 0); ! 347: break; ! 348: } ! 349: run_one(n); ! 350: } ! 351: ! 352: run_one(n) ! 353: { ! 354: static uchar *ip; ! 355: int i; ! 356: char *s; ! 357: Event ev; ! 358: Event *e= &ev; ! 359: ! 360: again: ! 361: if (ip == 0) { ! 362: ip = dir == Fwd ? input : inp; ! 363: clear(); ! 364: } ! 365: if (n == Quit) { ! 366: window_done(canvas); ! 367: return; ! 368: } ! 369: if (n == Hit) /* wait for another mouse hit */ ! 370: return; ! 371: if (n == Forward) { /* change from fwd to back -- fiddle ip */ ! 372: ip = next_obj(ip); ! 373: return; ! 374: } ! 375: if (n == Backward) { ! 376: ip = prev_obj(ip); ! 377: return; ! 378: } ! 379: if (n == File) { ! 380: putstring("filename? "); ! 381: return; ! 382: } ! 383: if (n == Again) { ! 384: clear(); ! 385: dir = Fwd; ! 386: ip = input; ! 387: } ! 388: if (singstep) { ! 389: if (clicking > 0) ! 390: ip = click_obj(ip, xormode, dir); ! 391: else ! 392: ip = step_obj(ip, xormode, dir); ! 393: } else { /* free running */ ! 394: while (ip) { ! 395: if (clicking > 0) ! 396: ip = click_obj(ip, xormode, dir); ! 397: else ! 398: ip = step_obj(ip, xormode, dir); ! 399: if (ip && window_read_event(canvas,e)==0) { ! 400: /* this just about duplicates inevent */ ! 401: switch (event_id(e)) { ! 402: case WIN_RESIZE: ! 403: width=(int)window_get(canvas, ! 404: CANVAS_WIDTH); ! 405: height=(int)window_get(canvas, ! 406: CANVAS_HEIGHT); ! 407: Drect.origin = pt(0,0); ! 408: Drect.corner = add(Drect.origin, ! 409: pt(width,height)); ! 410: view_setup(nview); ! 411: break; ! 412: case WIN_REPAINT: ! 413: pw_repairretained(pw); ! 414: break; ! 415: case MS_LEFT: /* button 1 */ ! 416: if (event_is_up(e)) ! 417: break; ! 418: last_but = 1; ! 419: last_hit = 0; ! 420: return; /* interrupt run */ ! 421: case MS_MIDDLE: ! 422: if (event_is_up(e)) ! 423: break; ! 424: last_but = 2; ! 425: last_hit = (int) menu_show(mbut2, ! 426: canvas, e, 0) - 1; ! 427: n = domouse(); ! 428: for (i = 0; s = m2gen(i); i++) ! 429: menu_set(menu_get(mbut2, ! 430: MENU_NTH_ITEM, i+1), ! 431: MENU_STRING, s, 0); ! 432: if (last_hit >= 0) ! 433: menu_set(mbut2, MENU_DEFAULT ! 434: , last_hit+1, 0); ! 435: goto again; ! 436: case MS_RIGHT: ! 437: if (event_is_up(e)) ! 438: break; ! 439: last_but = 3; ! 440: last_hit = (int) menu_show(mbut3, ! 441: canvas, e, 0) - 1; ! 442: n = domouse(); ! 443: for (i = 0; s = m3gen(i); i++) ! 444: menu_set(menu_get(mbut3, ! 445: MENU_NTH_ITEM, i+1), ! 446: MENU_STRING, s, 0); ! 447: if (last_hit >= 0) ! 448: menu_set(mbut3, MENU_DEFAULT ! 449: , last_hit+1, 0); ! 450: goto again; ! 451: } ! 452: } ! 453: sleephz(delay-1); ! 454: } ! 455: } ! 456: } ! 457: ! 458: domouse() ! 459: { ! 460: int n; ! 461: ! 462: if (last_but == 1) ! 463: return Proceed; ! 464: if (last_but == 3) { ! 465: switch (last_hit) { ! 466: case Again: ! 467: return Again; ! 468: case Faster: ! 469: if (delay > 1) ! 470: delay /= 2; ! 471: return Hit; ! 472: case Slower: ! 473: delay *= 2; ! 474: return Hit; ! 475: case Step: ! 476: singstep = 1 - singstep; ! 477: n = Step; ! 478: return Hit; ! 479: case Forward: ! 480: dir = 1 - dir; ! 481: if (xormode == F_OR) ! 482: xormode = F_CLR; ! 483: else if (xormode == F_CLR) ! 484: xormode = F_OR; ! 485: return dir == Fwd ? Forward : Backward; ! 486: case Fatter: ! 487: fatness++; ! 488: return Hit; ! 489: case Thinner: ! 490: if (fatness > 0) ! 491: fatness--; ! 492: return Hit; ! 493: case Xor: ! 494: if (xormode == F_OR || xormode == F_CLR) ! 495: xormode = F_XOR; ! 496: else if (dir == Fwd) ! 497: xormode = F_OR; ! 498: else ! 499: xormode = F_CLR; ! 500: return Hit; ! 501: case File: ! 502: return File; ! 503: case Quit: ! 504: return Quit; ! 505: default: ! 506: return Hit; ! 507: } ! 508: } else if (last_but == 2) { ! 509: Rectangle r, shrink(); ! 510: if (last_hit == -1) ! 511: return Hit; ! 512: else if (last_hit < nview) { ! 513: r = getrect23(); ! 514: if (r.origin.x == 0 && r.corner.x == 0) /* bailed out */ ! 515: return Hit; ! 516: if (eqpt(r.origin, r.corner)) ! 517: r = Drect; ! 518: drawrect(inset(viewpt[last_hit].vr, -(INSET+fatness)), F_CLR); ! 519: drawrect(r, F_OR); ! 520: viewpt[last_hit].vr = r = inset(r, INSET+fatness); ! 521: viewpt[last_hit].xmax = r.corner.x - r.origin.x; ! 522: viewpt[last_hit].ymax = r.corner.y - r.origin.y; ! 523: return Hit; ! 524: ! 525: } else { /* a click */ ! 526: if (clickval[last_hit-nview]) { /* was on, so turn off */ ! 527: clickval[last_hit-nview] = 0; ! 528: clicking--; ! 529: } else { ! 530: clickval[last_hit-nview] = 1; ! 531: clicking++; ! 532: } ! 533: return Hit; ! 534: } ! 535: } ! 536: } ! 537: ! 538: Rectangle shrink(r, pct) /* shrink rectangle by 2*pct */ ! 539: Rectangle r; ! 540: { ! 541: int dx = muldiv(r.corner.x-r.origin.x, pct, 100); ! 542: int dy = muldiv(r.corner.y-r.origin.y, pct, 100); ! 543: r.origin = add(r.origin, Pt(dx,dy)); ! 544: r.corner = sub(r.corner, Pt(dx,dy)); ! 545: return r; ! 546: } ! 547: ! 548: view_setup(n) ! 549: int n; ! 550: { ! 551: int i, dx, dy; ! 552: ! 553: dx = (Dc.x - Do.x) / 2; ! 554: dy = (Dc.y - Do.y) / 2; ! 555: viewpt[0].vr = Drect; ! 556: switch (n) { ! 557: case 2: ! 558: viewpt[1].vr = Drect; ! 559: viewpt[0].vr.corner.y -= dy; ! 560: viewpt[1].vr.origin.y += dy; ! 561: break; ! 562: case 3: case 4: ! 563: viewpt[0].vr.corner = add(Drect.origin, Pt(dx,dy)); ! 564: viewpt[1].vr = raddp(viewpt[0].vr, Pt(0,dy)); ! 565: viewpt[2].vr = raddp(viewpt[0].vr, Pt(dx,0)); ! 566: viewpt[3].vr = raddp(viewpt[0].vr, Pt(dx,dy)); ! 567: break; ! 568: } ! 569: for (i = 0; i < n; i++) { ! 570: viewpt[i].vr = shrink(viewpt[i].vr, MARGINPCT); ! 571: viewpt[i].xmax = viewpt[i].vr.corner.x - viewpt[i].vr.origin.x; ! 572: viewpt[i].ymax = viewpt[i].vr.corner.y - viewpt[i].vr.origin.y; ! 573: } ! 574: } ! 575: ! 576: drawrect(r, mode) ! 577: Rectangle r; ! 578: { ! 579: segment(&display, r.origin, Pt(r.origin.x,r.corner.y), mode); ! 580: segment(&display, r.origin, Pt(r.corner.x,r.origin.y), mode); ! 581: segment(&display, r.corner, Pt(r.origin.x,r.corner.y), mode); ! 582: segment(&display, r.corner, Pt(r.corner.x,r.origin.y), mode); ! 583: } ! 584: ! 585: segment(dp, p1, p2, mode) ! 586: Rectangle *dp; /* fake */ ! 587: Point p1, p2; ! 588: int mode; ! 589: { ! 590: pw_vector(pw, p1.x, p1.y, p2.x, p2.y, mode, 1); ! 591: } ! 592: ! 593: point(dp, p, mode) ! 594: Rectangle *dp; ! 595: Point p; ! 596: int mode; ! 597: { ! 598: register int val; ! 599: val = (mode==F_XOR)? pw_get(pw, p.x, p.y)^1 : ! 600: ((mode==F_OR)? 1 : 0); ! 601: pw_put(pw, p.x, p.y, val); ! 602: } ! 603: ! 604: /* return the raster op that f needs to be when SRC is inverted */ ! 605: invsrc(f) ! 606: register int f; ! 607: { ! 608: if(f==F_XOR) f=PIX_NOT(PIX_SRC)^PIX_DST; ! 609: else if(f==F_OR) f=PIX_NOT(PIX_SRC)|PIX_DST; ! 610: else if(f==F_STORE) f=PIX_NOT(PIX_SRC); ! 611: else if(f==F_CLR) f=PIX_SRC&PIX_DST; ! 612: return f; ! 613: } ! 614: ! 615: rectf(dp, r, mode) ! 616: Rectangle *dp; ! 617: Rectangle r; ! 618: int mode; ! 619: { ! 620: pw_writebackground(pw,r.origin.x, r.origin.y, ! 621: r.corner.x-r.origin.x, r.corner.y-r.origin.y, invsrc(mode)); ! 622: } ! 623: circle(dp, p, r, mode) ! 624: Rectangle *dp; ! 625: Point p; ! 626: int r, mode; ! 627: { ! 628: int x1=p.x; ! 629: register y1=p.y; ! 630: register eps = 0; /* x^2 + y^2 - r^2 */ ! 631: register dxsq = 1; /* (x+dx)^2-x^2*/ ! 632: register dysq = 1 - 2*r; ! 633: register exy; ! 634: int x0 = x1; ! 635: register y0 = y1 - r; ! 636: y1 += r; ! 637: pw_batch_on(pw); ! 638: if (mode == F_XOR) { /* endpoints coincide */ ! 639: point(dp,Pt(x0,y0),mode); ! 640: point(dp,Pt(x0,y1),mode); ! 641: } ! 642: while(y1 > y0) { ! 643: point(dp,Pt(x0,y0),mode); ! 644: point(dp,Pt(x0,y1),mode); ! 645: point(dp,Pt(x1,y0),mode); ! 646: point(dp,Pt(x1,y1),mode); ! 647: exy = eps + dxsq + dysq; ! 648: if(-exy <= eps+dxsq) { ! 649: y1--; ! 650: y0++; ! 651: eps += dysq; ! 652: dysq += 2; ! 653: } ! 654: if(exy <= -eps) { ! 655: x1++; ! 656: x0--; ! 657: eps += dxsq; ! 658: dxsq += 2; ! 659: } ! 660: } ! 661: point(dp,Pt(x0,y0),mode); ! 662: point(dp,Pt(x1,y0),mode); ! 663: pw_batch_off(pw); ! 664: } ! 665: ! 666: disc(dp, p, r, mode) ! 667: Rectangle *dp; ! 668: Point p; ! 669: int r, mode; ! 670: { ! 671: register x1=p.x, y1=p.y; ! 672: register eps = 0; /* x^2 + y^2 - r^2 */ ! 673: int dxsq = 1; /* (x+dx)^2-x^2*/ ! 674: int dysq = 1 - 2*r; ! 675: int exy; ! 676: register x0 = x1; ! 677: register y0 = y1 - r; ! 678: x1++; /* to offset jerq's half-open lines*/ ! 679: y1 += r; ! 680: pw_batch_on(pw); ! 681: while(y1 > y0) { ! 682: exy = eps + dxsq + dysq; ! 683: if(-exy <= eps+dxsq) { ! 684: rectf(dp, Rect4(x0, y0, x1, y0+1), mode); ! 685: rectf(dp, Rect4(x0, y1, x1, y1+1), mode); ! 686: y1--; ! 687: y0++; ! 688: eps += dysq; ! 689: dysq += 2; ! 690: } ! 691: if(exy <= -eps) { ! 692: x1++; ! 693: x0--; ! 694: eps += dxsq; ! 695: dxsq += 2; ! 696: } ! 697: } ! 698: rectf(dp, Rect4(x0, y0, x1, y0+1), mode); ! 699: pw_batch_off(pw); ! 700: } ! 701: ! 702: string(fp, s, dp, p, mode) ! 703: int *fp; /* actually a font pointer */ ! 704: uchar *s; ! 705: Rectangle *dp; ! 706: Point p; ! 707: int mode; ! 708: { ! 709: pw_text(pw, p.x, p.y+16, mode, 0, s); ! 710: } ! 711: ! 712: do_rcv() ! 713: { ! 714: int c, n, b, m, i; ! 715: uchar *ip; ! 716: ! 717: init_params(); ! 718: clear(); ! 719: memsize = readint(); ! 720: if ((inbuf = (uchar *) malloc(memsize)) == (uchar *) NULL) { ! 721: PUT "can't allocate %d bytes", memsize END ! 722: sleephz(60); ! 723: termabort(); ! 724: } ! 725: input = inbuf+1; /* leave a null at front */ ! 726: inp = inbuf+1; /* next free slot in input */ ! 727: dir = Fwd; ! 728: PUT "%d bytes, limit %d", inp - input, memsize END ! 729: ! 730: top: ! 731: switch (c = readchar()) { ! 732: case P_INIT: /* initialize */ ! 733: break; ! 734: case P_ENDFILE: ! 735: *inp = 0; ! 736: return; ! 737: case P_CLEAR: ! 738: clear(); ! 739: break; ! 740: case P_DEFINE: ! 741: /* view, click, ... */ ! 742: c = readchar(); ! 743: assert(c == 'c' || c == 'v', "illegal define"); ! 744: i = readint(); ! 745: readstring(buf); ! 746: if (c == 'c') { ! 747: clickname[i] = (char *) malloc(strlen(buf)+1); ! 748: strcpy(clickname[i], buf); ! 749: nclick++; ! 750: } else { /* c == 'v' */ ! 751: viewname[i] = (char *) malloc(strlen(buf)+1); ! 752: strcpy(viewname[i], buf); ! 753: nview++; ! 754: } ! 755: break; ! 756: case P_OBJECT: /* read an object */ ! 757: ip = inp; ! 758: if (nobj++ == 0) ! 759: view_setup(nview); ! 760: if (nobj % 100 == 0) ! 761: PUT "%d", nobj END ! 762: read_obj(); ! 763: draw_obj(ip, F_XOR, Fwd); ! 764: break; ! 765: case P_PRINT: /* print a string */ ! 766: readstring(buf); ! 767: putstring(buf); ! 768: break; ! 769: case P_ERROR: /* host is going to exit */ ! 770: termabort(); ! 771: default: ! 772: if (overflow) ! 773: break; ! 774: putstring("do_rcv error; unrecognized command: "); ! 775: for (pbuf = buf; c != '\n'; c = readchar()) ! 776: *pbuf++ = c; ! 777: *pbuf = 0; ! 778: putstring(buf); ! 779: break; ! 780: } ! 781: goto top; ! 782: } ! 783: ! 784: clear() ! 785: { ! 786: rectf(&display, Drect, F_CLR); /* clear screen */ ! 787: } ! 788: ! 789: read_obj() /* read an object, stick it in input[] */ ! 790: { ! 791: int c, n, m; ! 792: uchar *p; ! 793: ! 794: if (inp > input+memsize-50) { /* eat up at least one */ ! 795: PUT "overflow at %d bytes, limit %d", inp - input, memsize END ! 796: overflow++; ! 797: return; ! 798: } ! 799: c = readchar(); ! 800: switch (c) { ! 801: case ' ': ! 802: case '\n': ! 803: break; ! 804: case 'b': ! 805: case 'l': ! 806: slotnum = readint(); ! 807: slot[slotnum] = inp-input; ! 808: p = savechar(c); ! 809: savechar(curview = readint()); ! 810: savechar(readint()); /* options */ ! 811: savept(readpt()); ! 812: savept(readpt()); ! 813: savect(inp-p); ! 814: break; ! 815: case 'o': ! 816: slotnum = readint(); ! 817: slot[slotnum] = inp-input; ! 818: p = savechar(c); ! 819: savechar(curview = readint()); ! 820: savechar(readint()); /* options */ ! 821: savept(readpt()); ! 822: saveint(readint()); /* radius */ ! 823: savect(inp-p); ! 824: break; ! 825: case 't': ! 826: slotnum = readint(); ! 827: slot[slotnum] = inp-input; ! 828: p = savechar(c); ! 829: savechar(curview = readint()); ! 830: savechar(readint()); /* options */ ! 831: savept(readpt()); ! 832: n = readstring(inp+1); /* +1 leaves a hole */ ! 833: *inp = n; /* insert count before string */ ! 834: inp += n + 2; /* +2 = count before and \0 on end */ ! 835: savect(inp-p); ! 836: break; ! 837: case 'e': ! 838: p = savechar(c); ! 839: savelong(slot[readint()]); ! 840: savect(inp-p); ! 841: break; ! 842: case 'c': ! 843: p = savechar(c); ! 844: savechar(readint()); ! 845: savect(inp-p); ! 846: break; ! 847: } ! 848: } ! 849: ! 850: Point readpt() /* read a Point */ ! 851: { ! 852: Point p; ! 853: ! 854: p.x = readint(); ! 855: p.y = readint(); ! 856: return p; ! 857: } ! 858: ! 859: uchar *savechar(c) ! 860: { ! 861: *inp++ = c; ! 862: return inp-1; ! 863: } ! 864: ! 865: savect(n) ! 866: { ! 867: if (n > 255) ! 868: putstring("text string too long"); ! 869: *inp++ = n; ! 870: } ! 871: ! 872: saveint(n) ! 873: { ! 874: *inp++ = n >> 8; ! 875: *inp++ = n & 0377; ! 876: } ! 877: ! 878: savelong(n) ! 879: long n; ! 880: { ! 881: *inp++ = n >> 24; ! 882: *inp++ = n >> 16; ! 883: *inp++ = n >> 8; ! 884: *inp++ = n; ! 885: } ! 886: ! 887: savept(p) ! 888: Point p; ! 889: { ! 890: *inp++ = p.x >> 8; ! 891: *inp++ = p.x & 0377; ! 892: *inp++ = p.y >> 8; ! 893: *inp++ = p.y & 0377; ! 894: } ! 895: ! 896: getpoint(ip) ! 897: uchar *ip; ! 898: { ! 899: return *ip << 8 | *(ip+1); ! 900: } ! 901: ! 902: long getlong(ip) ! 903: uchar *ip; ! 904: { ! 905: return *ip << 24 | *(ip+1) << 16 | *(ip+2) << 8 | *(ip+3); ! 906: } ! 907: ! 908: Point scalept(v, p) ! 909: Point p; ! 910: { ! 911: p.x = p.x * viewpt[v].xmax / 10000; ! 912: p.y = viewpt[v].ymax - p.y * viewpt[v].ymax / 10000; ! 913: return p; ! 914: } ! 915: ! 916: scalex(v, n) ! 917: { ! 918: return n * viewpt[v].xmax / 10000; ! 919: } ! 920: ! 921: Point fetchpt(v, ip) ! 922: int v; ! 923: uchar *ip; ! 924: { ! 925: Point pt; ! 926: ! 927: pt.x = *ip << 8 | *(ip+1); ! 928: pt.y = *(ip+2) << 8 | *(ip+3); ! 929: pt = scalept(v, pt); ! 930: return add(pt, viewpt[v].vr.origin); ! 931: } ! 932: ! 933: /* ! 934: Encoding: type, view#, opts, coords, chars, etc., # = length of group ! 935: bvoxxyyxxyy# ! 936: lvoxxyyxxyy# ! 937: ovoxxyyrr# ! 938: tvoxxyynccc0# ! 939: ennnn# ! 940: cn# ! 941: ! 942: */ ! 943: ! 944: uchar *prev_obj(ip) ! 945: uchar *ip; ! 946: { ! 947: if (ip <= input) ! 948: return 0; ! 949: return ip - ip[-1] - 1; ! 950: } ! 951: ! 952: uchar *next_obj(ip) ! 953: uchar *ip; ! 954: { ! 955: if (ip < input || ip >= inp) ! 956: return 0; ! 957: switch (*ip) { ! 958: case 0: ! 959: return 0; ! 960: case 'b': ! 961: case 'l': ! 962: return ip + 12; ! 963: case 'o': ! 964: return ip + 10; ! 965: case 't': ! 966: return ip + ip[7] + 10; ! 967: case 'c': ! 968: return ip + 3; ! 969: case 'e': ! 970: return ip + 6; ! 971: default: ! 972: return 0; ! 973: } ! 974: } ! 975: ! 976: uchar *step_obj(ip, mode, dir) /* draw objs until one that changes something */ ! 977: uchar *ip; ! 978: { ! 979: int c; ! 980: ! 981: while (ip) { ! 982: c = *ip; ! 983: ip = draw_obj(ip, mode, dir); ! 984: if (c == 'b' || c == 'l' || c == 't' || c == 'e' || c == 'o') ! 985: return ip; ! 986: } ! 987: return ip; ! 988: } ! 989: ! 990: uchar *click_obj(ip, mode, dir) /* draw objs until matching click */ ! 991: uchar *ip; ! 992: { ! 993: int c; ! 994: uchar *oip; ! 995: ! 996: for (;;) { ! 997: oip = ip; ! 998: ip = draw_obj(ip, mode, dir); ! 999: if (ip == 0 || (oip && *oip == 'c' && clickval[oip[1]])) ! 1000: return ip; ! 1001: } ! 1002: } ! 1003: ! 1004: uchar *draw_obj(ip, mode, dir) /* draw obj from coords at ip */ ! 1005: uchar *ip; ! 1006: int mode, dir; ! 1007: { ! 1008: int c, r, thick, n, shift, head; ! 1009: Point p0, p1, p2; ! 1010: ! 1011: if (ip < input || ip >= inp) ! 1012: return 0; ! 1013: switch (c = *ip++) { ! 1014: case 'b': ! 1015: p0 = fetchpt(*ip, ip+2); ! 1016: p1 = fetchpt(*ip, ip+6); ! 1017: if (ip[1] == Bfill) { ! 1018: if (p0.y < p1.y) ! 1019: rectf(&display, Rpt(p0, p1), mode); ! 1020: else ! 1021: rectf(&display, Rect4(p0.x,p1.y,p1.x,p0.y), mode); ! 1022: } else { ! 1023: segment(&display, p0, Pt(p0.x,p1.y), mode); ! 1024: segment(&display, Pt(p0.x,p1.y), p1, mode); ! 1025: segment(&display, p1, Pt(p1.x,p0.y), mode); ! 1026: segment(&display, Pt(p1.x,p0.y), p0, mode); ! 1027: } ! 1028: if (dir == Fwd) ! 1029: ip += 1+9+1; ! 1030: else ! 1031: ip -= (*(ip-2) + 2); ! 1032: break; ! 1033: case 'l': ! 1034: p0 = fetchpt(*ip, ip+2); ! 1035: p1 = fetchpt(*ip, ip+6); ! 1036: thick = ip[1]/10; /* ought to be a macro! */ ! 1037: if (thick == Ldotted/10 || thick == Ldashed/10) ! 1038: thick = 1; ! 1039: thick = 2 * thick - 1; /* 1,3,5 */ ! 1040: fatline(p0, p1, mode, thick); ! 1041: head = ip[1]%10; /* ditto */ ! 1042: if (head == Larrow1 || head == Larrow3) ! 1043: arrow(p0, p1, AW, AH, mode); ! 1044: if (head == Larrow2 || head == Larrow3) ! 1045: arrow(p1, p0, AW, AH, mode); ! 1046: if (dir == Fwd) ! 1047: ip += 1+9+1; ! 1048: else ! 1049: ip -= (*(ip-2) + 2); ! 1050: break; ! 1051: case 'o': ! 1052: p0 = fetchpt(*ip, ip+2); ! 1053: r = scalex(*ip, getpoint(ip+6)); ! 1054: if (ip[1] == Cnofill) ! 1055: circle(&display, p0, r, mode); ! 1056: else ! 1057: disc(&display, p0, r, mode); ! 1058: if (dir == Fwd) ! 1059: ip += 1+7+1; ! 1060: else ! 1061: ip -= (*(ip-2) + 2); ! 1062: break; ! 1063: case 't': ! 1064: p0 = fetchpt(*ip, ip+2); ! 1065: n = ip[6]; ! 1066: shift = (ip[1]/10) * 10; /* ought to be a macro! */ ! 1067: if (shift == Tljust) ! 1068: shift = 0; ! 1069: else if (shift == Tcenter) ! 1070: shift = (9 * n) / 2; /* 9 = char width */ ! 1071: else ! 1072: shift = 9 * n; ! 1073: string(&defont, ip+7, &display, sub(p0, Pt(shift,8)), mode); ! 1074: if (dir == Fwd) ! 1075: ip += 1+5 + *(ip+6)+2 + 1; ! 1076: else ! 1077: ip -= (*(ip-2) + 2); ! 1078: break; ! 1079: case 'e': ! 1080: erase(ip-1); ! 1081: if (dir == Fwd) ! 1082: ip += 5; ! 1083: else ! 1084: ip -= (*(ip-2) + 2); ! 1085: break; ! 1086: case 'c': ! 1087: if (dir == Fwd) ! 1088: ip += 2; ! 1089: else ! 1090: ip -= (*(ip-2) + 2); ! 1091: break; ! 1092: default: ! 1093: ip = 0; ! 1094: break; ! 1095: } ! 1096: return ip; ! 1097: } ! 1098: ! 1099: erase(ip) ! 1100: uchar *ip; ! 1101: { ! 1102: long target = getlong(ip+1); /* target label index */ ! 1103: int mode = F_XOR; ! 1104: ! 1105: if (xormode == F_OR || xormode == F_CLR) ! 1106: mode = dir == Fwd ? F_CLR : F_OR; ! 1107: draw_obj(input+target, mode, Fwd); ! 1108: } ! 1109: ! 1110: #define abs(x) ((x) >= 0 ? (x) : -(x)) ! 1111: ! 1112: fatline(p0, p1, mode, thick) ! 1113: Point p0, p1; ! 1114: { ! 1115: int i, fat, beg, nl; ! 1116: ! 1117: fat = thick * (2 * fatness + 1); ! 1118: beg = fat / 2; ! 1119: if (abs(p1.x-p0.x) >= abs(p1.y-p0.y)) { /* horizontal */ ! 1120: for (nl = 0, i = -beg; nl < fat; nl++, i++) ! 1121: segment(&display, add(p0, Pt(0,i)), add(p1, Pt(0,i)), mode); ! 1122: } else { ! 1123: for (nl = 0, i = -beg; nl < fat; nl++, i++) ! 1124: segment(&display, add(p0, Pt(i,0)), add(p1, Pt(i,0)), mode); ! 1125: } ! 1126: } ! 1127: ! 1128: arrow(p1, p2, w, h, c) ! 1129: Point p1, p2; ! 1130: int w, h, c; ! 1131: /* ! 1132: ** draw arrow of height,width (h,w) at p2 of segment p1,p2. ! 1133: */ ! 1134: { ! 1135: Point d; ! 1136: int norm, qx, qy, lx, ly; ! 1137: ! 1138: d = sub(p2, p1); ! 1139: /* norm = sqrt((long)d.x*d.x + (long)d.y*d.y); */ ! 1140: norm = ((long)d.x*d.x + (long)d.y*d.y) / 2; ! 1141: if (norm == 0) /* shouldn't happen, but ... */ ! 1142: return; ! 1143: qx = p2.x - h*d.x/norm; ! 1144: qy = p2.y - h*d.y/norm; ! 1145: lx = w/2 * -d.y/norm; ! 1146: ly = w/2 * d.x/norm; ! 1147: /* segment(&display, p1, p2, c); */ ! 1148: segment(&display, Pt(qx+lx, qy+ly), p2, c); ! 1149: segment(&display, Pt(qx-lx, qy-ly), p2, c); ! 1150: } ! 1151: ! 1152: ! 1153: putstring(a1, a2, a3, a4, a5) ! 1154: char *a1, *a2, *a3, *a4, *a5; ! 1155: { ! 1156: char buf[100]; ! 1157: ! 1158: sprintf(buf, "%50s", " "); /* cheap clear */ ! 1159: pw_text(pw, 20, 20, F_STORE, 0, buf); ! 1160: sprintf(buf, a1, a2, a3, a4, a5); ! 1161: pw_text(pw, 20, 20, F_STORE, 0, buf); ! 1162: } ! 1163: ! 1164: assert(c, s) /* poor man's assertion */ ! 1165: char *s; ! 1166: { ! 1167: if (!c) { ! 1168: putstring("assertion %s failed\n", s); ! 1169: sleephz(60); ! 1170: termabort(); ! 1171: } ! 1172: } ! 1173: ! 1174: termabort() ! 1175: { ! 1176: send1char(P_QUIT); ! 1177: flushproto(); ! 1178: window_done(canvas); ! 1179: exit(1); ! 1180: } ! 1181: ! 1182: readbyte() ! 1183: { ! 1184: char c; ! 1185: ! 1186: read(0, &c, 1); ! 1187: return c; ! 1188: } ! 1189: ! 1190: sendbuf(buf, p) ! 1191: char *buf, *p; ! 1192: { ! 1193: write(1, buf, p-buf); ! 1194: } ! 1195: ! 1196: ! 1197: short bullseye_bits[]={ ! 1198: 0x07E0, 0x1FF8, 0x399C, 0x63C6, 0x6FF6, 0xCDB3, 0xD99B, 0xFFFF, ! 1199: 0xFFFF, 0xD99B, 0xCDB3, 0x6FF6, 0x63C6, 0x399C, 0x1FF8, 0x07E0, ! 1200: }; ! 1201: short coffeecup_bits[]={ ! 1202: 0x0100, 0x00E0, 0x0010, 0x03E0, 0x0400, 0x0FE0, 0x123C, 0x1FE2, ! 1203: 0x101A, 0x101A, 0x1002, 0x103C, 0x1810, 0x6FEC, 0x4004, 0x3FF8, ! 1204: }; ! 1205: short sweep_bits[]={ ! 1206: 0x43FF, 0xE001, 0x7001, 0x3801, 0x1D01, 0x0F01, 0x8701, 0x8F01, ! 1207: 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0xFFFF, ! 1208: }; ! 1209: short deadmouse_bits[]={ ! 1210: 0x0000, 0x0114, 0xA208, 0x4100, 0x0000, 0x0008, 0x0004, 0x0082, ! 1211: 0x0441, 0xFFE1, 0x5FF1, 0x3FFE, 0x17F0, 0x03E0, 0x0000, 0x0000, ! 1212: }; ! 1213: short darkgrey_bits[]={ ! 1214: 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, ! 1215: 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, 0xDDDD, 0x7777, ! 1216: }; ! 1217: short lockarrow_bits[]={ ! 1218: 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0FC0, 0x0FC0, ! 1219: 0x03C0, 0x07C0, 0x0EC0, 0x1CC0, 0x3800, 0x7000, 0xE0DB, 0xC0DB, ! 1220: }; ! 1221: mpr_static(bullseye_pr, 16, 16, 1, bullseye_bits); ! 1222: mpr_static(coffeecup_pr, 16, 16, 1, coffeecup_bits); ! 1223: mpr_static(sweep_pr, 16, 16, 1, sweep_bits); ! 1224: mpr_static(deadmouse_pr, 16, 16, 1, deadmouse_bits); ! 1225: mpr_static(lockarrow_pr, 16, 16, 1, lockarrow_bits); ! 1226: mpr_static(darkgrey, 16, 16, 1, darkgrey_bits); ! 1227: ! 1228: initcursors() ! 1229: { ! 1230: normalcursor=cursor_copy(window_get(canvas,WIN_CURSOR)); ! 1231: cursor_set(normalcursor,CURSOR_OP,F_XOR,0); ! 1232: bullseye=cursor_create(CURSOR_IMAGE,&bullseye_pr, ! 1233: CURSOR_XHOT,7,CURSOR_YHOT,7,CURSOR_OP,F_XOR,0); ! 1234: coffeecup=cursor_create(CURSOR_IMAGE,&coffeecup_pr, ! 1235: CURSOR_XHOT,7,CURSOR_YHOT,7,CURSOR_OP,F_XOR,0); ! 1236: sweep=cursor_create(CURSOR_IMAGE,&sweep_pr, ! 1237: CURSOR_XHOT,7,CURSOR_YHOT,7,CURSOR_OP,F_XOR,0); ! 1238: deadmouse=cursor_create(CURSOR_IMAGE,&deadmouse_pr, ! 1239: CURSOR_XHOT,7,CURSOR_YHOT,7,CURSOR_OP,F_XOR,0); ! 1240: lockarrow=cursor_create(CURSOR_IMAGE,&lockarrow_pr, ! 1241: CURSOR_XHOT,0,CURSOR_YHOT,0,CURSOR_OP,F_XOR,0); ! 1242: cursor= &normalcursor; ! 1243: } ! 1244: ! 1245: ! 1246: Rectangle getrect23() ! 1247: { ! 1248: static Rectangle r; ! 1249: static Event ev; ! 1250: register Event *e= &ev; ! 1251: register int sweepstate=0; ! 1252: r.origin.x=r.origin.y=r.corner.x=r.corner.y=0; ! 1253: cursswitch(&sweep); ! 1254: window_set(canvas, WIN_CONSUME_PICK_EVENT, LOC_DRAG, 0, 0); ! 1255: window_release_event_lock(canvas); ! 1256: while(sweepstate<=1){ ! 1257: if(window_read_event(canvas,e)!=0) ! 1258: ; /* non-blocking read */ ! 1259: switch (event_id(e)) { ! 1260: case MS_LEFT: ! 1261: if(sweepstate) showr(&r); /*erase box*/ ! 1262: sweepstate=2; ! 1263: break; ! 1264: case MS_MIDDLE: ! 1265: case MS_RIGHT: ! 1266: if(!sweepstate && event_is_down(e)){ ! 1267: r.origin.x=r.corner.x=event_x(e); ! 1268: r.origin.y=r.corner.y=event_y(e); ! 1269: sweepstate=1; ! 1270: showr(&r); ! 1271: } ! 1272: else if(sweepstate && event_is_up(e)){ ! 1273: r.corner.x=event_x(e); ! 1274: r.corner.y=event_y(e); ! 1275: showr(&r); ! 1276: sweepstate=2; ! 1277: } ! 1278: break; ! 1279: case LOC_DRAG: ! 1280: showr(&r); /* erase old one */ ! 1281: r.corner.x=event_x(e); ! 1282: r.corner.y=event_y(e); ! 1283: showr(&r); ! 1284: break; ! 1285: case LOC_WINEXIT: ! 1286: if(sweepstate){ ! 1287: showr(&r); ! 1288: r.corner.x=event_x(e); ! 1289: r.corner.y=event_y(e); ! 1290: showr(&r); ! 1291: sweepstate=2; ! 1292: } ! 1293: break; ! 1294: } ! 1295: } ! 1296: window_set(canvas, WIN_IGNORE_PICK_EVENT, LOC_DRAG, 0); ! 1297: cursswitch(&normalcursor); ! 1298: return r; ! 1299: } ! 1300: showr(rp) ! 1301: register Rectangle *rp; ! 1302: { ! 1303: register int x0=rp->origin.x; ! 1304: register int y0=rp->origin.y; ! 1305: register int x1=rp->corner.x; ! 1306: register int y1=rp->corner.y; ! 1307: pw_batch_on(pw); ! 1308: pw_vector(pw, x0, y0, x1, y0, PIX_SRC^PIX_DST, 1); ! 1309: if(y1>y0) y0++; /*avoid redoing corner*/ ! 1310: else y0--; ! 1311: pw_vector(pw, x1, y0, x1, y1, PIX_SRC^PIX_DST, 1); ! 1312: if(x1>x0) x1--; ! 1313: else x1++; ! 1314: pw_vector(pw, x1, y1, x0, y1, PIX_SRC^PIX_DST, 1); ! 1315: pw_vector(pw, x0, y1, x0, y0, PIX_SRC^PIX_DST, 1); ! 1316: pw_batch_off(pw); ! 1317: } ! 1318: ! 1319: cursswitch(cp) ! 1320: Cursor *cp; ! 1321: { ! 1322: window_set(canvas, WIN_CURSOR, cp? *cp : normalcursor, 0); ! 1323: } ! 1324: ! 1325: ! 1326: /* sleep, but in 1/60's of second */ ! 1327: /* #include <sys/time.h> */ ! 1328: #include <signal.h> ! 1329: ! 1330: #define mask(s) (1<<((s)-1)) ! 1331: #define setvec(vec, a) \ ! 1332: vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 ! 1333: ! 1334: static int ringring; ! 1335: ! 1336: sleephz(n) ! 1337: unsigned n; ! 1338: { ! 1339: int sleepx(), omask; ! 1340: struct itimerval itv, oitv; ! 1341: register struct itimerval *itp = &itv; ! 1342: struct sigvec vec, ovec; ! 1343: ! 1344: if (n == 0) ! 1345: return; ! 1346: timerclear(&itp->it_interval); ! 1347: timerclear(&itp->it_value); ! 1348: if (setitimer(ITIMER_REAL, itp, &oitv) < 0) ! 1349: return; ! 1350: setvec(ovec, SIG_DFL); ! 1351: omask = sigblock(0); ! 1352: n *= 16666; ! 1353: itp->it_value.tv_sec = n / 1000000; ! 1354: itp->it_value.tv_usec = n % 1000000; ! 1355: if (timerisset(&oitv.it_value)) { ! 1356: if (timercmp(&oitv.it_value, &itp->it_value, >)) ! 1357: oitv.it_value.tv_sec -= itp->it_value.tv_sec; ! 1358: else { ! 1359: itp->it_value = oitv.it_value; ! 1360: /* ! 1361: * This is a hack, but we must have time to ! 1362: * return from the setitimer after the alarm ! 1363: * or else it'll be restarted. And, anyway, ! 1364: * sleep never did anything more than this before. ! 1365: */ ! 1366: oitv.it_value.tv_sec = 1; ! 1367: oitv.it_value.tv_usec = 0; ! 1368: } ! 1369: } ! 1370: setvec(vec, sleepx); ! 1371: (void) sigvec(SIGALRM, &vec, &ovec); ! 1372: ringring = 0; ! 1373: (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0); ! 1374: while (!ringring) ! 1375: sigpause(omask &~ mask(SIGALRM)); ! 1376: (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); ! 1377: (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); ! 1378: } ! 1379: ! 1380: static ! 1381: sleepx() ! 1382: { ! 1383: ! 1384: ringring = 1; ! 1385: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.