Annotation of researchv10no/cmd/movie/libj.c, revision 1.1

1.1     ! root        1: #include "xjerq.h"
        !             2: #include <errno.h>
        !             3: #ifdef BSD
        !             4: #include <sys/ioctl.h>
        !             5: #else
        !             6: #include <sys/filio.h>
        !             7: #endif
        !             8: 
        !             9: Rectangle Drect;
        !            10: Bitmap display;
        !            11: struct Mouse mouse;
        !            12: static struct JProc sP;
        !            13: struct JProc *P;
        !            14: GC gcs[4];
        !            15: Display *dpy;
        !            16: unsigned long fgpix;
        !            17: unsigned long bgpix;
        !            18: Colormap colormap;
        !            19: XColor fgcolor, bgcolor;
        !            20: Font defont;
        !            21: 
        !            22: static short arrow_bits[]={
        !            23:        0x0004, 0x000E, 0x001F, 0x003E,
        !            24:        0x007C, 0x00F8, 0x01F0, 0x83E0,
        !            25:        0x87C0, 0xCF80, 0xDF00, 0xFE00,
        !            26:        0xFC00, 0xF800, 0xFE00, 0xFF80,
        !            27: };
        !            28: Cursor normalcursor;
        !            29: 
        !            30: /*
        !            31:  * Buffer for keyboard input
        !            32:  */
        !            33: #define KBDBUFSIZE     128
        !            34: static unsigned char kbdbuffer[KBDBUFSIZE];
        !            35: 
        !            36: static struct {
        !            37:        unsigned char *buf;
        !            38:        unsigned char *in;
        !            39:        unsigned char *out;
        !            40:        int cnt;
        !            41:        int size;
        !            42: } kbdbuf = {kbdbuffer, kbdbuffer, kbdbuffer, 0, KBDBUFSIZE};
        !            43: 
        !            44: initdisplay(argc, argv)
        !            45: int argc;
        !            46: char *argv[];
        !            47: {
        !            48:        int i;
        !            49:        Window win;
        !            50:        XSetWindowAttributes xswa;
        !            51:        XSizeHints sizehints;
        !            52:        Font *df;
        !            53:        char *font;
        !            54:        char *geom = 0;
        !            55:        int flags;
        !            56:        int width, height, x, y;
        !            57:        char **ap;
        !            58: 
        !            59:        if (!(dpy= XOpenDisplay(NULL))) {
        !            60:                perror("Cannot open display\n");
        !            61:                exit(-1);
        !            62:        }
        !            63: 
        !            64:        if ((font = XGetDefault(dpy, argv[0], "JerqFont")) == NULL)
        !            65:                font = "fixed";
        !            66:        bzero(&sizehints, sizeof(sizehints));
        !            67:        ap = argv; i = argc;
        !            68:        while (i-- > 0) {
        !            69:                if (!strcmp("-fn", ap[0])) {
        !            70:                        font = ap[1];
        !            71:                        i--; ap++;
        !            72:                }
        !            73:                else if (ap[0][0] == '=') {
        !            74:                        geom = ap[0];   
        !            75:                        flags = XParseGeometry(ap[0], &x, &y, &width, &height);
        !            76:                        if(WidthValue & flags) {
        !            77:                                sizehints.flags |= USSize;
        !            78:                                sizehints.width = width;
        !            79:                        }
        !            80:                        if(HeightValue & flags) {
        !            81:                                sizehints.flags |= USSize;
        !            82:                                sizehints.height = height;
        !            83:                        }
        !            84:                        if(XValue & flags) {
        !            85:                                if(XNegative & flags)
        !            86:                                  x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
        !            87:                                        - sizehints.width;
        !            88:                                sizehints.flags |= USPosition;
        !            89:                                sizehints.x = x;
        !            90:                        }
        !            91:                        if(YValue & flags) {
        !            92:                                if(YNegative & flags)
        !            93:                                  y = DisplayHeight(dpy, DefaultScreen(dpy)) + y
        !            94:                                        -sizehints.height;
        !            95:                                sizehints.flags |= USPosition;
        !            96:                                sizehints.y = y;
        !            97:                        }
        !            98:                }
        !            99:                ap++;
        !           100:        }
        !           101: 
        !           102:        df = XLoadQueryFont(dpy, font);
        !           103:        defont = *df;
        !           104:        P = &sP;
        !           105: 
        !           106:        sizehints.width_inc = sizehints.height_inc = 1;
        !           107:        sizehints.min_width = sizehints.min_height = 20;
        !           108:        sizehints.flags |= PResizeInc|PMinSize;
        !           109:        if (!geom) {
        !           110:                sizehints.width = defont.max_bounds.width * 80;
        !           111:                sizehints.height = (defont.max_bounds.ascent +
        !           112:                                 defont.max_bounds.descent) * 24;
        !           113:                sizehints.flags |= PSize;
        !           114:        }
        !           115: 
        !           116:        xswa.event_mask = 0;
        !           117:        bgpix = xswa.background_pixel = WhitePixel(dpy, 0);
        !           118:        fgpix = xswa.border_pixel = BlackPixel(dpy, 0);
        !           119:        win = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)),
        !           120:                sizehints.x, sizehints.y, sizehints.width, sizehints.height,
        !           121:                2, 0,
        !           122:                InputOutput, DefaultVisual(dpy, DefaultScreen(dpy)),
        !           123:                CWEventMask | CWBackPixel | CWBorderPixel, &xswa);
        !           124: 
        !           125:        XSetStandardProperties(dpy, win, argv[0], argv[0],
        !           126:                                None, argv, argc, &sizehints);
        !           127: 
        !           128:        XSelectInput(dpy, win,
        !           129:                ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|
        !           130:                StructureNotifyMask|ExposureMask|KeyPressMask);
        !           131:        XMapWindow(dpy, win);
        !           132: 
        !           133:        colormap = XDefaultColormap(dpy, 0);
        !           134:        fgcolor.pixel = fgpix;
        !           135:        bgcolor.pixel = bgpix;
        !           136:        XQueryColor(dpy, colormap, &fgcolor);
        !           137:        XQueryColor(dpy, colormap, &bgcolor);
        !           138: 
        !           139:        gcs[F_STORE] = XCreateGC(dpy, win, 0, NULL);
        !           140:        XSetForeground(dpy, gcs[F_STORE], fgpix);
        !           141:        XSetBackground(dpy, gcs[F_STORE], bgpix);
        !           142:        XSetFont(dpy, gcs[F_STORE], defont.fid);
        !           143:        gcs[F_OR] = XCreateGC(dpy, win, 0, NULL);
        !           144:        XCopyGC(dpy, gcs[F_STORE], GCForeground|GCBackground|GCFont, gcs[F_OR]);
        !           145:        gcs[F_CLR] = XCreateGC(dpy, win, 0, NULL);
        !           146:        XCopyGC(dpy, gcs[F_STORE], GCBackground|GCFont, gcs[F_CLR]);
        !           147:        XSetForeground(dpy, gcs[F_CLR], bgpix);
        !           148:        gcs[F_XOR] = XCreateGC(dpy, win, 0, NULL);
        !           149:        XCopyGC(dpy, gcs[F_STORE], GCBackground|GCFont, gcs[F_XOR]);
        !           150:        XSetForeground(dpy, gcs[F_XOR], AllPlanes);
        !           151:        XSetFunction(dpy, gcs[F_XOR], GXxor);
        !           152: 
        !           153:        display.dr = win;
        !           154:        Drect.origin.x = 0;
        !           155:        Drect.origin.y = 0;
        !           156:        Drect.corner.x = sizehints.width;
        !           157:        Drect.corner.y = sizehints.height;
        !           158:        display.rect = Drect;
        !           159:        while (! P->state & RESHAPED)
        !           160:                handleinput();  /* wait for exposure */
        !           161:        P->state &= ~RESHAPED;
        !           162:        normalcursor = ToCursor(arrow_bits, arrow_bits, 0, 15);
        !           163:        cursswitch(&normalcursor);
        !           164: 
        !           165: 
        !           166: }
        !           167: 
        !           168: Bitmap *
        !           169: balloc(r)
        !           170:        Rectangle r;
        !           171: {
        !           172:        Bitmap *b;
        !           173:        Pixmap pm;
        !           174:        b=(Bitmap *)malloc(sizeof (struct Bitmap));
        !           175:        pm = XCreatePixmap(dpy, display.dr, r.corner.x-r.origin.x,
        !           176:                r.corner.y-r.origin.y, DefaultDepth(dpy, 0));
        !           177:        b->dr=pm;
        !           178:        b->rect=r;
        !           179:        b->flag = BI_PIXMAP;
        !           180:        return b;
        !           181: }
        !           182: 
        !           183: void
        !           184: bfree(b)
        !           185:        Bitmap *b;
        !           186: {
        !           187:        if(b){
        !           188:                XFreePixmap(dpy, b->dr);
        !           189:                free((char *)b);
        !           190:        }
        !           191: }
        !           192: 
        !           193: #define brx(b) (b->rect.origin.x)
        !           194: #define bry(b) (b->rect.origin.y)
        !           195: 
        !           196: void
        !           197: rectf(b,r,f)
        !           198:        Bitmap *b;
        !           199:        Rectangle r;
        !           200:        Code f;
        !           201: {
        !           202:        register wd=r.corner.x-r.origin.x;
        !           203:        register ht=r.corner.y-r.origin.y;
        !           204: 
        !           205:        if (b->flag & BI_PIXMAP)
        !           206:                r.origin = sub(r.origin, b->rect.origin);
        !           207:        XFillRectangle(dpy, b->dr, gcs[f], r.origin.x, r.origin.y, wd, ht);
        !           208: }
        !           209: 
        !           210: void
        !           211: bitblt(sb,r,db,p,f)
        !           212:        Bitmap *sb, *db;
        !           213:        Rectangle r; /* in source bitmap */
        !           214:        Point p; /* in dest bitmap */
        !           215:        Code f;
        !           216: {
        !           217:        int wd=r.corner.x-r.origin.x;
        !           218:        int ht=r.corner.y-r.origin.y;
        !           219: 
        !           220:        if (sb->flag & BI_PIXMAP)
        !           221:                r.origin = sub(r.origin, sb->rect.origin);
        !           222:        if (db->flag & BI_PIXMAP)
        !           223:                p = sub(p, db->rect.origin);
        !           224:        XCopyArea(dpy, sb->dr, db->dr, gcs[f], r.origin.x, r.origin.y,
        !           225:                wd, ht, p.x, p.y);
        !           226: }
        !           227: 
        !           228: Point
        !           229: string(ft, s, b, p, f)
        !           230:        XFontStruct *ft;
        !           231:        char *s;
        !           232:        Bitmap *b;
        !           233:        Point p;
        !           234:        Code f;
        !           235: {
        !           236:        Point p1;
        !           237:        int i;
        !           238: 
        !           239:        i = strlen(s);
        !           240:        p1 = p;
        !           241:        p.y += ft->max_bounds.ascent;
        !           242:        if (b->flag & BI_PIXMAP)
        !           243:                p = sub(p, b->rect.origin);
        !           244:        XDrawString(dpy, b->dr, gcs[f], p.x, p.y, s, i);
        !           245:        p1.x += XTextWidth(ft, s, i);
        !           246:        return p1;
        !           247: }
        !           248: 
        !           249: strwidth(ft,s)
        !           250:        XFontStruct *ft;
        !           251:        char *s;
        !           252: {
        !           253:        return XTextWidth(ft, s, strlen(s));
        !           254: }
        !           255: 
        !           256: #ifdef safe
        !           257: Point
        !           258: Pt(x, y)
        !           259:        short x, y;
        !           260: {
        !           261:        Point p;
        !           262:        p.x = x;
        !           263:        p.y = y;
        !           264:        return p;
        !           265: }
        !           266: Rectangle
        !           267: SRect(x1, y1, x2, y2)
        !           268:        short x1, y1, x2, y2;
        !           269: {
        !           270:        Rectangle r;
        !           271:        r.origin.x = x1;
        !           272:        r.origin.y = y1;
        !           273:        r.corner.x = x2;
        !           274:        r.corner.y = y2;
        !           275:        return r;
        !           276: }
        !           277: Rectangle
        !           278: Rpt(p1, p2)
        !           279:        Point p1, p2;
        !           280: {
        !           281:        Rectangle r;
        !           282:        r.origin = p1;
        !           283:        r.corner = p2;
        !           284:        return r;
        !           285: }
        !           286: #endif safe
        !           287: 
        !           288: Point
        !           289: add(a, b)
        !           290:        Point a, b;
        !           291: {
        !           292:        register short *ap= &a.x, *bp= &b.x;
        !           293:        *ap++ += *bp++;
        !           294:        *ap += *bp;
        !           295:        return a;
        !           296: }
        !           297: Point
        !           298: sub(a, b)
        !           299:        Point a, b;
        !           300: {
        !           301:        register short *ap= &a.x, *bp= &b.x;
        !           302:        *ap++ -= *bp++;
        !           303:        *ap -= *bp;
        !           304:        return a;
        !           305: }
        !           306: Rectangle
        !           307: inset(r,n)
        !           308:        Rectangle r;
        !           309:        register n;
        !           310: {
        !           311:        register short *rp= &r.origin.x;
        !           312:        *rp++ += n;
        !           313:        *rp++ += n;
        !           314:        *rp++ -= n;
        !           315:        *rp   -= n;
        !           316:        return r;
        !           317: }
        !           318: Rectangle
        !           319: raddp(r, p)
        !           320:        Rectangle r;
        !           321:        Point p;
        !           322: {
        !           323:        register short *rp= &r.origin.x, *pp= &p.x;
        !           324:        *rp++ += *pp++;
        !           325:        *rp++ += *pp--;
        !           326:        *rp++ += *pp++;
        !           327:        *rp   += *pp;
        !           328:        return r;
        !           329: }
        !           330: eqpt(p, q)
        !           331:        Point p, q;
        !           332: {
        !           333:        register long *pp=(long *)&p, *qq=(long *)&q;
        !           334:        return *pp==*qq;
        !           335: }
        !           336: ptinrect(p, r)
        !           337:        Point p;
        !           338:        Rectangle r;
        !           339: {
        !           340:        return(p.x>=r.origin.x && p.x<r.corner.x
        !           341:            && p.y>=r.origin.y && p.y<r.corner.y);
        !           342: }
        !           343: 
        !           344: /*
        !           345:  * Convert a blit style texture to a pixmap which can be used in tiling
        !           346:  * or cursor operations.
        !           347:  */
        !           348: Pixmap ToPixmap(bits)
        !           349: short bits[];
        !           350: {
        !           351:        static XImage *im;
        !           352:        Pixmap pm;
        !           353: 
        !           354:        if (!im)
        !           355:                im = XCreateImage(dpy, XDefaultVisual(dpy, 0), 1,
        !           356:                                  XYBitmap, 0, (char *)bits, 16, 16, 8, 2);
        !           357:        else
        !           358:                im->data = (char *)bits;
        !           359:        pm = XCreatePixmap(dpy, display.dr, 16, 16, 1);
        !           360:        XPutImage(dpy, pm, gcs[F_STORE], im, 0, 0, 0, 0, 16, 16);
        !           361:        return pm;
        !           362: }
        !           363: 
        !           364: Cursor ToCursor(source, mask, hotx, hoty)
        !           365: short source[], mask[];
        !           366: {
        !           367:        Pixmap sp, mp;
        !           368:        Cursor c;
        !           369: 
        !           370:        sp = ToPixmap(source);
        !           371:        mp = ToPixmap(mask);
        !           372:        c = XCreatePixmapCursor(dpy, sp, mp, &fgcolor, &bgcolor, hotx, hoty);
        !           373:        XFreePixmap(dpy, sp);
        !           374:        XFreePixmap(dpy, mp);
        !           375:        return(c);
        !           376: }
        !           377: 
        !           378: cursset(p)
        !           379:        Point p;
        !           380: {
        !           381:        XWarpPointer(dpy, display.dr, display.dr, mouse.xy.x, mouse.xy.y,
        !           382:                display.rect.corner.x, display.rect.corner.y, p.x, p.y);
        !           383:        mouse.xy.x = p.x;
        !           384:        mouse.xy.y = p.y;
        !           385: }
        !           386: 
        !           387: jnap(i)
        !           388: {
        !           389:        handleinput();
        !           390: }
        !           391: 
        !           392: kbdchar()
        !           393: {
        !           394:        int i;
        !           395: 
        !           396:        if (!kbdbuf.cnt)
        !           397:                return -1;
        !           398:        i = *kbdbuf.out++;
        !           399:        if (kbdbuf.out == &kbdbuf.buf[kbdbuf.size])
        !           400:                kbdbuf.out = kbdbuf.buf;
        !           401:        if (--kbdbuf.cnt == 0)
        !           402:                P->state &= ~KBD;
        !           403:        return(i);
        !           404: }
        !           405: 
        !           406: #undef button
        !           407: handleinput()
        !           408: {
        !           409:        XEvent ev;
        !           410:        unsigned char s[16], *cp;
        !           411:        int n;
        !           412: 
        !           413:        XNextEvent(dpy, &ev);
        !           414:        switch (ev.type) {
        !           415:                case ButtonPress:
        !           416:                        mouse.buttons |= (8 >> ev.xbutton.button);
        !           417:                        mouse.xy.x = ev.xbutton.x;
        !           418:                        mouse.xy.y = ev.xbutton.y;
        !           419:                        mouse.time = ev.xbutton.time;
        !           420:                        break;
        !           421:                case ButtonRelease:
        !           422:                        mouse.buttons &= ~(8 >> ev.xbutton.button);
        !           423:                        mouse.xy.x = ev.xbutton.x;
        !           424:                        mouse.xy.y = ev.xbutton.y;
        !           425:                        mouse.time = ev.xbutton.time;
        !           426:                        break;
        !           427:                case MotionNotify:
        !           428:                        mouse.xy.x = ev.xmotion.x;
        !           429:                        mouse.xy.y = ev.xmotion.y;
        !           430:                        break;
        !           431:                case MapNotify:
        !           432:                case NoExpose:
        !           433:                        break;
        !           434:                case ConfigureNotify:
        !           435:                        if (display.rect.corner.x != ev.xconfigure.width ||
        !           436:                            display.rect.corner.y != ev.xconfigure.height) {
        !           437:                                display.rect.corner.x = ev.xconfigure.width;
        !           438:                                display.rect.corner.y = ev.xconfigure.height;
        !           439:                                Drect = display.rect;
        !           440:                        }
        !           441:                        break;
        !           442:                case Expose:
        !           443:                        if (ev.xexpose.count == 0) {
        !           444:                                rectf(&display, Drect, F_CLR);
        !           445:                                P->state |= RESHAPED;
        !           446:                        }
        !           447:                        break;
        !           448:                case KeyPress:
        !           449:                        mouse.xy.x = ev.xkey.x;
        !           450:                        mouse.xy.y = ev.xkey.y;
        !           451:                        mouse.time = ev.xkey.time;
        !           452:                        n = XLookupString(&ev, s, sizeof(s), NULL, NULL);
        !           453:                        if (n > 0) {
        !           454:                                cp = s;
        !           455:                                P->state |= KBD;
        !           456:                                do {
        !           457:                                        if (kbdbuf.cnt == kbdbuf.size)
        !           458:                                                break;
        !           459:                                        *kbdbuf.in++ = *cp++;
        !           460:                                        kbdbuf.cnt++;
        !           461:                                        if (kbdbuf.in == &kbdbuf.buf[kbdbuf.size])
        !           462:                                                kbdbuf.in = kbdbuf.buf;
        !           463:                                } while (--n);
        !           464:                        }
        !           465:                        break;
        !           466:                default:
        !           467:                        break;
        !           468:        }
        !           469: }
        !           470: #define button(i)              (mouse.buttons&(8>>i))
        !           471: 
        !           472: char *
        !           473: gcalloc(nbytes, where)
        !           474:        unsigned long nbytes;
        !           475:        char **where;
        !           476: {
        !           477:        *where=(char *)alloc(nbytes);
        !           478:        return *where;
        !           479: }
        !           480: void
        !           481: gcfree(s)
        !           482:        char *s;
        !           483: {
        !           484:        free(s);
        !           485: }
        !           486: 
        !           487: min(a,b)
        !           488: {
        !           489:        return (a<b? a: b);
        !           490: }
        !           491: max(a,b)
        !           492: {
        !           493:        return (a>b? a: b);
        !           494: }
        !           495: 
        !           496: /*     Form a circle of radius r centered at x1,y1
        !           497:  */
        !           498: circle(b,p,r,f)
        !           499:        Bitmap *b;
        !           500:        Point p;
        !           501: {
        !           502:        unsigned int diam = 2*r;
        !           503:        if (b->flag & BI_PIXMAP)
        !           504:                p = sub(p, b->rect.origin);
        !           505:        p = sub(p, Pt(r,r));
        !           506:        XDrawArc(dpy, b->dr, gcs[f], p.x, p.y, diam, diam, 0, 23040/* 360 deg */);
        !           507: }
        !           508: 
        !           509: Cursor *
        !           510: cursswitch(cp)
        !           511: Cursor *cp;
        !           512: {
        !           513:        static Cursor *prev = &normalcursor;
        !           514:        Cursor *ret = prev;
        !           515:        if (!cp)
        !           516:                cp = &normalcursor;
        !           517:        XDefineCursor(dpy, display.dr, *cp);
        !           518:        prev = cp;
        !           519:        return ret;
        !           520: }
        !           521: /*     Fill a disc of radius r centered at x1,y1
        !           522:  */
        !           523: disc(b, p, r, f)
        !           524:        Bitmap *b;
        !           525:        Point p;
        !           526:        int r;
        !           527:        Code f;
        !           528: {
        !           529:        unsigned int diam = 2*r;
        !           530:        if (b->flag & BI_PIXMAP)
        !           531:                p = sub(p, b->rect.origin);
        !           532:        p = sub(p, Pt(r,r));
        !           533:        XFillArc(dpy, b->dr, gcs[f], p.x, p.y, diam, diam, 0, 23040/* 360 deg */);
        !           534: }
        !           535: 
        !           536: typedef struct String{
        !           537:        char *s;        /* pointer to string */
        !           538:        short n;        /* number used, no terminal null */
        !           539:        short size;     /* size of allocated area */
        !           540: } String;
        !           541: 
        !           542: getmuxbuf(pmb)
        !           543:        String *pmb;
        !           544: {
        !           545:        char *ans;
        !           546:        int n;
        !           547:        ans=XFetchBytes(dpy, &n);
        !           548:        pmb->size=pmb->n=n;
        !           549:        gcalloc(pmb->size, &(pmb->s));
        !           550:        strncpy(pmb->s, ans, n);
        !           551:        free(ans);
        !           552: }
        !           553: 
        !           554: #define        UP      0
        !           555: #define        DOWN    1
        !           556: 
        !           557: static short boxcurs_bits[] = {
        !           558:        0x43FF, 0xE001, 0x7001, 0x3801, 0x1D01, 0x0F01, 0x8701, 0x8F01,
        !           559:        0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0xFFFF,
        !           560: };
        !           561: static Cursor boxcurs;
        !           562: 
        !           563: buttons(updown)
        !           564: {
        !           565:        while((button123()!=0) != updown)
        !           566:                jnap(2);
        !           567: }
        !           568: 
        !           569: Rectangle
        !           570: canon(p1, p2)
        !           571:        Point p1, p2;
        !           572: {
        !           573:        Rectangle r;
        !           574:        r.origin.x = min(p1.x, p2.x);
        !           575:        r.origin.y = min(p1.y, p2.y);
        !           576:        r.corner.x = max(p1.x, p2.x);
        !           577:        r.corner.y = max(p1.y, p2.y);
        !           578:        return(r);
        !           579: }
        !           580: 
        !           581: static outline(r)
        !           582:        Rectangle  r;
        !           583: {
        !           584:        XPoint p[5], *pp;
        !           585:        
        !           586:        pp = p;
        !           587:        pp->x = r.corner.x; pp->y = r.origin.y; pp++;
        !           588:        pp->x = r.corner.x; pp->y = r.corner.y; pp++;
        !           589:        pp->x = r.origin.x; pp->y = r.corner.y; pp++;
        !           590:        pp->x = r.origin.x; pp->y = r.origin.y; pp++;
        !           591:        pp->x = r.corner.x; pp->y = r.origin.y; pp++;
        !           592:        XDrawLines(dpy, display.dr, gcs[F_XOR], p, 5, CoordModeOrigin);
        !           593: }
        !           594: 
        !           595: Rectangle
        !           596: getrectb(n)
        !           597:        int n;
        !           598: {
        !           599:        Rectangle r;
        !           600:        Point p1, p2;
        !           601:        
        !           602:        if (!boxcurs)
        !           603:                boxcurs = ToCursor(boxcurs_bits, boxcurs_bits, 8, 8);
        !           604:        cursswitch(&boxcurs);
        !           605:        buttons(UP);
        !           606:        buttons(DOWN);
        !           607:        if(!(mouse.buttons&n)){
        !           608:                r.origin.x=r.origin.y=r.corner.x=r.corner.y=0;
        !           609:                buttons(UP);
        !           610:                goto Return;
        !           611:        }
        !           612:        p1=mouse.xy;
        !           613:        p2=p1;
        !           614:        r=canon(p1, p2);
        !           615:        outline(r);
        !           616:        for(; mouse.buttons&n; jnap(2)){
        !           617:                outline(r);
        !           618:                p2=mouse.xy;
        !           619:                r=canon(p1, p2);
        !           620:                outline(r);
        !           621:        }
        !           622:        outline(r);     /* undraw for the last time */
        !           623:     Return:
        !           624:        cursswitch(0);
        !           625:        return r;
        !           626: }
        !           627: 
        !           628: Rectangle
        !           629: getrect(n)
        !           630: {
        !           631:        return getrectb(8>>n);
        !           632: }
        !           633: 
        !           634: #define scale(x, inmin, inmax, outmin, outmax)\
        !           635:        (outmin + muldiv(x-inmin,outmax-outmin,inmax-inmin))
        !           636: 
        !           637: #define bound(x, low, high) min(high, max( low, x ))
        !           638: 
        !           639: #define DISPLAY                16
        !           640: #define DELTA          6
        !           641: #define BARWIDTH       18
        !           642: 
        !           643: static char **table;
        !           644: static char *
        !           645: tablegen(i)
        !           646: {
        !           647:        return table[i];
        !           648: }
        !           649: 
        !           650: menuhit(m, but)
        !           651: register Menu *m;
        !           652: {
        !           653:        register int width, i, j, top, newtop, hit, newhit, items, lines, length;
        !           654:        Point p, q, savep, baro, barc;
        !           655:        Rectangle sr, tr, mr;   /* scroll, text, menu */
        !           656:        register Bitmap *b;
        !           657:        register char *s, *(*generator)(), *from, *to;
        !           658:        char fill[64];
        !           659:        Font *font = &defont;
        !           660:        int spacing = font->max_bounds.ascent + font->max_bounds.descent;
        !           661: 
        !           662: #define sro sr.origin
        !           663: #define src sr.corner
        !           664: #define tro tr.origin
        !           665: #define trc tr.corner
        !           666: #define mro mr.origin
        !           667: #define mrc mr.corner
        !           668: 
        !           669:        generator = (table=m->item) ? tablegen : m->generator;
        !           670:        p = mouse.xy;
        !           671:        length = width = items = 0;
        !           672:        for( ; s=(*generator)(items); ++items) {
        !           673:                length = max(length, strlen(s));
        !           674:                width = max(width, strwidth(font,s));
        !           675:        }
        !           676:        if(items == 0){
        !           677:                while(button(but));
        !           678:                return -1;
        !           679:        }
        !           680:        width += 10;
        !           681:        sro.x = sro.y = src.x = tro.x = mro.x = mro.y = 0;
        !           682:        if(items <= DISPLAY)
        !           683:                lines = items;
        !           684:        else{
        !           685:                lines = DISPLAY;
        !           686:                tro.x = src.x = BARWIDTH;
        !           687:                sro.x = sro.y = 1;
        !           688:        }
        !           689:        tro.y = 1;
        !           690:        mrc = trc = add(Pt(tro.x, mro.y), Pt(width, min(items, lines)*spacing+2));
        !           691:        trc.y = src.y = mrc.y-1;
        !           692:        newtop = bound(m->prevtop, 0, items-lines);
        !           693:        p.y -= bound(m->prevhit, 0, lines-1)*spacing+spacing/2;
        !           694:        p.x = bound(p.x-(src.x+width/2), 0, display.rect.corner.x-mrc.x);
        !           695:        p.y = bound(p.y, 0, display.rect.corner.y-mrc.y);
        !           696:        sr = raddp(sr, p);
        !           697:        tr = raddp(tr, p);
        !           698:        mr = raddp(mr, p);
        !           699:        b = balloc(mr);
        !           700:        if(b)
        !           701:                bitblt(&display, mr, b, mro, F_STORE);
        !           702:        rectf(&display, mr, F_OR);
        !           703: PaintMenu:
        !           704:        rectf(&display, inset(mr, 1), F_CLR);
        !           705:        top = newtop;
        !           706:        if(items > DISPLAY){
        !           707:                baro.y = scale(top, 0, items, sro.y, src.y);
        !           708:                baro.x = sr.origin.x;
        !           709:                barc.y = scale(top+DISPLAY, 0, items, sro.y, src.y);
        !           710:                barc.x = sr.corner.x;
        !           711:                rectf(&display, Rpt(baro,barc), F_XOR);
        !           712:        }
        !           713:        for(p=tro, i=top; i < min(top+lines, items); ++i){
        !           714:                q = p;
        !           715:                from = generator(i);
        !           716:                for(to = &fill[0]; *from; ++from)
        !           717:                        if(*from & 0x80)
        !           718:                                for(j=length-(strlen(from+1)+(to-&fill[0])); j-->0;)
        !           719:                                        *to++ = *from & 0x7F;
        !           720:                        else
        !           721:                                *to++ = *from;
        !           722:                *to = '\0';
        !           723:                q.x += (width-strwidth(font,fill))/2;
        !           724:                string(font, fill, &display, q, F_XOR);
        !           725:                p.y += spacing;
        !           726:        }
        !           727:        savep = mouse.xy;
        !           728:        for(newhit = hit = -1; button(but); jnap(2)){
        !           729:                if(ptinrect(p = mouse.xy, sr)){
        !           730:                        if(ptinrect(savep,tr)){
        !           731:                                p.y = (baro.y+barc.y)/2;
        !           732:                                cursset(p);
        !           733:                        }
        !           734:                        newtop = scale(p.y, sro.y, src.y, 0, items);
        !           735:                        newtop = bound(newtop-DISPLAY/2, 0, items-DISPLAY);
        !           736:                        if(newtop != top)
        !           737:                                goto PaintMenu;
        !           738:                }else if(ptinrect(savep,sr)){
        !           739:                        register dx, dy;
        !           740:                        if(abs(dx = p.x-savep.x) < DELTA)
        !           741:                                dx = 0;
        !           742:                        if(abs(dy = p.y-savep.y) < DELTA)
        !           743:                                dy = 0;
        !           744:                        if(abs(dy) >= abs(dx))
        !           745:                                dx = 0;
        !           746:                        else
        !           747:                                dy = 0;
        !           748:                        cursset(p = add(savep, Pt(dx,dy)));
        !           749:                }
        !           750:                savep = p;
        !           751:                newhit = -1;
        !           752:                if(ptinrect(p, tr)){
        !           753:                        newhit = bound((p.y-tro.y)/spacing, 0, lines-1);
        !           754:                        if(newhit!=hit && hit>=0
        !           755:                         && abs(tro.y+spacing*newhit+spacing/2-p.y) > spacing/3)
        !           756:                                newhit = hit;
        !           757:                }
        !           758:                if(newhit != hit){
        !           759:                        flip(tr, hit, spacing);
        !           760:                        flip(tr, hit = newhit, spacing);
        !           761:                }
        !           762:                if(newhit==0 && top>0){
        !           763:                        newtop = top-1;
        !           764:                        p.y += spacing;
        !           765:                        cursset(p);
        !           766:                        goto PaintMenu;
        !           767:                }
        !           768:                if(newhit==DISPLAY-1 && top<items-lines){
        !           769:                        newtop = top+1;
        !           770:                        p.y -= spacing;
        !           771:                        cursset(p);
        !           772:                        goto PaintMenu;
        !           773:                }
        !           774:        }
        !           775:        if(b){
        !           776:                bitblt(b, b->rect, &display, b->rect.origin, F_STORE);
        !           777:                bfree(b);
        !           778:        }
        !           779:        if(hit>=0){
        !           780:                m->prevhit = hit;
        !           781:                m->prevtop = top;
        !           782:                return hit+top;
        !           783:        }else
        !           784:                return -1;
        !           785: }
        !           786: 
        !           787: static
        !           788: flip(r,n,spacing)
        !           789:        Rectangle r;
        !           790: {
        !           791:        if(n<0)
        !           792:                return;
        !           793:        ++r.origin.x;
        !           794:        r.corner.y = (r.origin.y += spacing*n) + spacing;
        !           795:        --r.corner.x;
        !           796:        rectf(&display, r, F_XOR);
        !           797: }
        !           798: 
        !           799: void
        !           800: point(b,p,f)
        !           801:        Bitmap *b;
        !           802:        Point p;
        !           803:        Code f;
        !           804: {
        !           805:        if (b->flag & BI_PIXMAP)
        !           806:                p = sub(p, b->rect.origin);
        !           807:        XDrawPoint(dpy, b->dr, gcs[f], p.x, p.y);
        !           808: }
        !           809: 
        !           810: #define PBSIZE 100
        !           811: 
        !           812: static XPoint xp[PBSIZE];
        !           813: static xpcnt;
        !           814: static Code fc;
        !           815: static ispixmap;
        !           816: static Bitmap *bitm;
        !           817: 
        !           818: #define flushpt()      if (xpcnt) flushpoints();
        !           819: 
        !           820: points(p)
        !           821:        Point p;
        !           822: {
        !           823:        register XPoint *x;
        !           824: 
        !           825:        if (ispixmap)
        !           826:                p = sub(p, bitm->rect.origin);
        !           827:        x = &xp[xpcnt];
        !           828:        x->x = p.x;
        !           829:        x->y = p.y;
        !           830:        if (++xpcnt == PBSIZE)
        !           831:                flushpoints();
        !           832: }
        !           833: 
        !           834: initpoints(b, f)
        !           835:        Bitmap *b;
        !           836:        Code f;
        !           837: {
        !           838:        if (b->flag & BI_PIXMAP)
        !           839:                ispixmap = 1;
        !           840:        else
        !           841:                ispixmap = 0;
        !           842:        bitm = b;
        !           843:        fc = f;
        !           844: }
        !           845: 
        !           846: endpoints()
        !           847: {
        !           848:        flushpt();
        !           849:        XSync(dpy, 0);
        !           850: }
        !           851: 
        !           852: flushpoints()
        !           853: {
        !           854:        if (xpcnt) {
        !           855:                XDrawPoints(dpy, bitm->dr, gcs[fc], xp, xpcnt, CoordModeOrigin);
        !           856:                xpcnt = 0;
        !           857:        }
        !           858: }
        !           859: 
        !           860: /*
        !           861:  * Buffer for keyboard input
        !           862:  */
        !           863: #define RCVBUFSIZE     1024
        !           864: 
        !           865: static unsigned char rcvbuffer[RCVBUFSIZE];
        !           866: 
        !           867: static struct {
        !           868:        unsigned char *buf;
        !           869:        unsigned char *in;
        !           870:        unsigned char *out;
        !           871:        int cnt;
        !           872:        int size;
        !           873: }rcvbuf = { rcvbuffer, rcvbuffer, rcvbuffer, 0, RCVBUFSIZE };
        !           874: 
        !           875: 
        !           876: rcvchar()
        !           877: {
        !           878:        int i;
        !           879: 
        !           880:        if (!rcvbuf.cnt)
        !           881:                return -1;
        !           882:        i = *rcvbuf.out++;
        !           883:        if (rcvbuf.out == &rcvbuf.buf[rcvbuf.size])
        !           884:                rcvbuf.out = rcvbuf.buf;
        !           885:        if (--rcvbuf.cnt == 0)
        !           886:                P->state &= ~RCV;
        !           887:        return(i);
        !           888: }
        !           889: 
        !           890: rcvfill()
        !           891: {
        !           892:        register i;
        !           893: 
        !           894:        if (rcvbuf.cnt == rcvbuf.size)
        !           895:                return;
        !           896:        if (rcvbuf.in < rcvbuf.out)
        !           897:                i = rcvbuf.out - rcvbuf.in;
        !           898:        else
        !           899:                i = &rcvbuf.buf[rcvbuf.size] - rcvbuf.in;
        !           900:        i = read(0, rcvbuf.in, i);
        !           901:        if (i <= 0)
        !           902:                return;
        !           903:        P->state |= RCV;
        !           904:        rcvbuf.cnt += i;
        !           905:        rcvbuf.in += i;
        !           906:        if (rcvbuf.in == &rcvbuf.buf[rcvbuf.size])
        !           907:                rcvbuf.in = rcvbuf.buf;
        !           908: }
        !           909: 
        !           910: void
        !           911: request(r)
        !           912:        int r;
        !           913: {
        !           914:        int i=1;
        !           915:        if (r & RCV) {
        !           916:                /* need non-blocking I/O on stdout */
        !           917: #ifdef BSD
        !           918:                ioctl(1, FIONBIO, &i);
        !           919: #else
        !           920:                ioctl(1, FIOWNBLK, 0);
        !           921: #endif
        !           922:        }
        !           923:        /* for now, assume MOUSE|KBD requested */
        !           924: }
        !           925: 
        !           926: void
        !           927: segment(b,p,q,f)
        !           928:        Bitmap *b;
        !           929:        Point p, q;
        !           930:        Code f;
        !           931: {
        !           932:        if (b->flag & BI_PIXMAP) {
        !           933:                p = sub(p, b->rect.origin);
        !           934:                q = sub(q, b->rect.origin);
        !           935:        }
        !           936:        XDrawLine(dpy, b->dr, gcs[f], p.x, p.y, q.x, q.y);
        !           937: }
        !           938: 
        !           939: #ifndef BSD
        !           940: #define EWOULDBLOCK EBUSY
        !           941: #endif
        !           942: 
        !           943: sendnchars(n,p)
        !           944:        char *p;
        !           945:        int n;
        !           946: {
        !           947:        int i;
        !           948:        int maxfd, rmask, wmask;
        !           949: 
        !           950:        while (n) {
        !           951:                i = write(1, p, n);
        !           952:                if (i > 0) {
        !           953:                        n -= i;
        !           954:                        p += i;
        !           955:                        continue;
        !           956:                }
        !           957:                if (i < 0 && errno == EWOULDBLOCK) {
        !           958:                        maxfd = dpy->fd + 1;
        !           959:                        do {
        !           960:                                while (XPending(dpy))
        !           961:                                        handleinput();
        !           962:                                rmask = (1 << dpy->fd) | 1;
        !           963:                                wmask = 2;
        !           964: #ifdef BSD
        !           965:                                select(maxfd, &rmask, &wmask, 0, 0);
        !           966: #else
        !           967:                                select(maxfd, &rmask, &wmask, 0x6fffffff);
        !           968: #endif
        !           969:                                if (rmask & 1)
        !           970:                                        rcvfill();
        !           971:                                if (rmask & (1 << dpy->fd))
        !           972:                                        handleinput();
        !           973:                        } while (!wmask);
        !           974:                }
        !           975:                else
        !           976:                        exit(1);
        !           977:        }
        !           978: }
        !           979: #define MAXROOT 0xb504
        !           980: sqrt(x)
        !           981:        register long x;
        !           982: {
        !           983:        register long high=MAXROOT;
        !           984:        register long low=0;
        !           985:        register long current=MAXROOT/2;
        !           986:        if(x<=0)
        !           987:                return 0;
        !           988:        if(x>=MAXROOT*MAXROOT)
        !           989:                return(MAXROOT);
        !           990:        while(high>low+1){
        !           991:                if(current*current==x)
        !           992:                        return (current);
        !           993:                if(current*current>x)
        !           994:                        high=current;
        !           995:                else
        !           996:                        low=current;
        !           997:                current=(high+low)>>1;
        !           998:        }
        !           999:        return(current);
        !          1000: }
        !          1001: 
        !          1002: wait(resource)
        !          1003: {
        !          1004:        int maxfd, smask, i;
        !          1005: 
        !          1006:        maxfd = dpy->fd + 1;
        !          1007:        for(;;) {
        !          1008:                if (P->state & resource)
        !          1009:                        break;
        !          1010:                if (XPending(dpy))
        !          1011:                        goto xin;
        !          1012:                if (resource & CPU)
        !          1013:                        break;
        !          1014:                smask = (1 << dpy->fd) | 1;
        !          1015: #ifdef BSD
        !          1016:                select(maxfd, &smask, 0, 0, 0);
        !          1017: #else
        !          1018:                select(maxfd, &smask, 0, 0x6fffffff);
        !          1019: #endif
        !          1020:                if (smask & 1)
        !          1021:                        rcvfill();
        !          1022:                if (smask & (1 << dpy->fd)) {
        !          1023: xin:
        !          1024:                        handleinput();
        !          1025:                        /* We always have the mouse and cpu */
        !          1026:                        if (resource & (MOUSE|CPU))
        !          1027:                                break;
        !          1028:                }
        !          1029:        }
        !          1030:        return P->state;
        !          1031: }
        !          1032: 
        !          1033: int
        !          1034: own()
        !          1035: {
        !          1036:        return P->state|MOUSE;
        !          1037: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.