tInitial revision - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit b822e0d8035e1c80b86d974e63bd10936a96ed2d
 (DIR) parent b5990708483a1fa452b3d4b6ed2bfa998deeeb39
 (HTM) Author: rsc <devnull@localhost>
       Date:   Tue, 30 Sep 2003 17:47:43 +0000
       
       Initial revision
       
       Diffstat:
         A src/libdraw/test                    |       0 
         A src/libdraw/test.core               |       0 
         A src/libframe/Makefile               |      92 +++++++++++++++++++++++++++++++
         A src/libframe/Makefile.MID           |      21 +++++++++++++++++++++
         A src/libframe/frbox.c                |     156 +++++++++++++++++++++++++++++++
         A src/libframe/frdraw.c               |     176 +++++++++++++++++++++++++++++++
         A src/libframe/mkfile                 |       1 +
       
       7 files changed, 446 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/src/libdraw/test b/src/libdraw/test
       Binary files differ.
 (DIR) diff --git a/src/libdraw/test.core b/src/libdraw/test.core
       Binary files differ.
 (DIR) diff --git a/src/libframe/Makefile b/src/libframe/Makefile
       t@@ -0,0 +1,92 @@
       +
       +# this works in gnu make
       +SYSNAME:=${shell uname}
       +OBJTYPE:=${shell uname -m | sed 's;i.86;386;; s;/.*;;; s; ;;g'}
       +
       +# this works in bsd make
       +SYSNAME!=uname
       +OBJTYPE!=uname -m | sed 's;i.86;386;; s;/.*;;; s; ;;g'
       +
       +# the gnu rules will mess up bsd but not vice versa,
       +# hence the gnu rules come first.
       +
       +include Make.$(SYSNAME)-$(OBJTYPE)
       +
       +PREFIX=/usr/local
       +
       +NUKEFILES=
       +
       +TGZFILES=
       +
       +LIB=libframe.a
       +VERSION=2.0
       +PORTPLACE=devel/libframe
       +NAME=libdraw
       +
       +OFILES=\
       +        frbox.$O\
       +        frdelete.$O\
       +        frdraw.$O\
       +        frinit.$O\
       +        frinsert.$O\
       +        frptofchar.$O\
       +        frselect.$O\
       +        frstr.$O\
       +        frutil.$O\
       +
       +all: $(LIB)
       +
       +install: $(LIB)
       +        install -c -m 0644 $(LIB) $(PREFIX)/lib/$(LIB)
       +        install -c -m 0644 frame.h $(PREFIX)/include/frame.h
       +$(LIB): $(OFILES)
       +        $(AR) $(ARFLAGS) $(LIB) $(OFILES)
       +
       +NUKEFILES+=$(LIB)
       +.c.$O:
       +        $(CC) $(CFLAGS) -I/usr/X11R6/include -I$(PREFIX)/include $*.c
       +
       +%.$O: %.c
       +        $(CC) $(CFLAGS) -I/usr/X11R6/include -I$(PREFIX)/include $*.c
       +
       +
       +$(OFILES): $(HFILES)
       +
       +tgz:
       +        rm -rf $(NAME)-$(VERSION)
       +        mkdir $(NAME)-$(VERSION)
       +        cp Makefile Make.* README LICENSE NOTICE *.[ch137] rpm.spec bundle.ports $(TGZFILES) $(NAME)-$(VERSION)
       +        tar cf - $(NAME)-$(VERSION) | gzip >$(NAME)-$(VERSION).tgz
       +        rm -rf $(NAME)-$(VERSION)
       +
       +clean:
       +        rm -f $(OFILES) $(LIB)
       +
       +nuke:
       +        rm -f $(OFILES) *.tgz *.rpm $(NUKEFILES)
       +
       +rpm:
       +        make tgz
       +        cp $(NAME)-$(VERSION).tgz /usr/src/RPM/SOURCES
       +        rpm -ba rpm.spec
       +        cp /usr/src/RPM/SRPMS/$(NAME)-$(VERSION)-1.src.rpm .
       +        cp /usr/src/RPM/RPMS/i586/$(NAME)-$(VERSION)-1.i586.rpm .
       +        scp *.rpm rsc@amsterdam.lcs.mit.edu:public_html/software
       +
       +PORTDIR=/usr/ports/$(PORTPLACE)
       +
       +ports:
       +        make tgz
       +        rm -rf $(PORTDIR)
       +        mkdir $(PORTDIR)
       +        cp $(NAME)-$(VERSION).tgz /usr/ports/distfiles
       +        cat bundle.ports | (cd $(PORTDIR) && awk '$$1=="---" && $$3=="---" { ofile=$$2; next} {if(ofile) print >ofile}')
       +        (cd $(PORTDIR); make makesum)
       +        (cd $(PORTDIR); make)
       +        (cd $(PORTDIR); /usr/local/bin/portlint)
       +        rm -rf $(PORTDIR)/work
       +        shar `find $(PORTDIR)` > ports.shar
       +        (cd $(PORTDIR); tar cf - *) | gzip >$(NAME)-$(VERSION)-ports.tgz
       +        scp *.tgz rsc@amsterdam.lcs.mit.edu:public_html/software
       +
       +.phony: all clean nuke install tgz rpm ports
 (DIR) diff --git a/src/libframe/Makefile.MID b/src/libframe/Makefile.MID
       t@@ -0,0 +1,21 @@
       +LIB=libframe.a
       +VERSION=2.0
       +PORTPLACE=devel/libframe
       +NAME=libdraw
       +
       +OFILES=\
       +        frbox.$O\
       +        frdelete.$O\
       +        frdraw.$O\
       +        frinit.$O\
       +        frinsert.$O\
       +        frptofchar.$O\
       +        frselect.$O\
       +        frstr.$O\
       +        frutil.$O\
       +
       +all: $(LIB)
       +
       +install: $(LIB)
       +        install -c -m 0644 $(LIB) $(PREFIX)/lib/$(LIB)
       +        install -c -m 0644 frame.h $(PREFIX)/include/frame.h
 (DIR) diff --git a/src/libframe/frbox.c b/src/libframe/frbox.c
       t@@ -0,0 +1,156 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <draw.h>
       +#include <mouse.h>
       +#include <frame.h>
       +
       +#define        SLOP        25
       +
       +void
       +_fraddbox(Frame *f, int bn, int n)        /* add n boxes after bn, shift the rest up,
       +                                 * box[bn+n]==box[bn] */
       +{
       +        int i;
       +
       +        if(bn > f->nbox)
       +                drawerror(f->display, "_fraddbox");
       +        if(f->nbox+n > f->nalloc)
       +                _frgrowbox(f, n+SLOP);
       +        for(i=f->nbox; --i>=bn; )
       +                f->box[i+n] = f->box[i];
       +        f->nbox+=n;
       +}
       +
       +void
       +_frclosebox(Frame *f, int n0, int n1)        /* inclusive */
       +{
       +        int i;
       +
       +        if(n0>=f->nbox || n1>=f->nbox || n1<n0)
       +                drawerror(f->display, "_frclosebox");
       +        n1++;
       +        for(i=n1; i<f->nbox; i++)
       +                f->box[i-(n1-n0)] = f->box[i];
       +        f->nbox -= n1-n0;
       +}
       +
       +void
       +_frdelbox(Frame *f, int n0, int n1)        /* inclusive */
       +{
       +        if(n0>=f->nbox || n1>=f->nbox || n1<n0)
       +                drawerror(f->display, "_frdelbox");
       +        _frfreebox(f, n0, n1);
       +        _frclosebox(f, n0, n1);
       +}
       +
       +void
       +_frfreebox(Frame *f, int n0, int n1)        /* inclusive */
       +{
       +        int i;
       +
       +        if(n1<n0)
       +                return;
       +        if(n0>=f->nbox || n1>=f->nbox)
       +                drawerror(f->display, "_frfreebox");
       +        n1++;
       +        for(i=n0; i<n1; i++)
       +                if(f->box[i].nrune >= 0)
       +                        free(f->box[i].ptr);
       +}
       +
       +void
       +_frgrowbox(Frame *f, int delta)
       +{
       +        f->nalloc += delta;
       +        f->box = realloc(f->box, f->nalloc*sizeof(Frbox));
       +        if(f->box == 0)
       +                drawerror(f->display, "_frgrowbox");
       +}
       +
       +static
       +void
       +dupbox(Frame *f, int bn)
       +{
       +        uchar *p;
       +
       +        if(f->box[bn].nrune < 0)
       +                drawerror(f->display, "dupbox");
       +        _fraddbox(f, bn, 1);
       +        if(f->box[bn].nrune >= 0){
       +                p = _frallocstr(f, NBYTE(&f->box[bn])+1);
       +                strcpy((char*)p, (char*)f->box[bn].ptr);
       +                f->box[bn+1].ptr = p;
       +        }
       +}
       +
       +static
       +uchar*
       +runeindex(uchar *p, int n)
       +{
       +        int i, w;
       +        Rune rune;
       +
       +        for(i=0; i<n; i++,p+=w)
       +                if(*p < Runeself)
       +                        w = 1;
       +                else{
       +                        w = chartorune(&rune, (char*)p);
       +                        USED(rune);
       +                }
       +        return p;
       +}
       +
       +static
       +void
       +truncatebox(Frame *f, Frbox *b, int n)        /* drop last n chars; no allocation done */
       +{
       +        if(b->nrune<0 || b->nrune<n)
       +                drawerror(f->display, "truncatebox");
       +        b->nrune -= n;
       +        runeindex(b->ptr, b->nrune)[0] = 0;
       +        b->wid = stringwidth(f->font, (char *)b->ptr);
       +}
       +
       +static
       +void
       +chopbox(Frame *f, Frbox *b, int n)        /* drop first n chars; no allocation done */
       +{
       +        if(b->nrune<0 || b->nrune<n)
       +                drawerror(f->display, "chopbox");
       +        strcpy((char*)b->ptr, (char*)runeindex(b->ptr, n));
       +        b->nrune -= n;
       +        b->wid = stringwidth(f->font, (char *)b->ptr);
       +}
       +
       +void
       +_frsplitbox(Frame *f, int bn, int n)
       +{
       +        dupbox(f, bn);
       +        truncatebox(f, &f->box[bn], f->box[bn].nrune-n);
       +        chopbox(f, &f->box[bn+1], n);
       +}
       +
       +void
       +_frmergebox(Frame *f, int bn)                /* merge bn and bn+1 */
       +{
       +        Frbox *b;
       +
       +        b = &f->box[bn];
       +        _frinsure(f, bn, NBYTE(&b[0])+NBYTE(&b[1])+1);
       +        strcpy((char*)runeindex(b[0].ptr, b[0].nrune), (char*)b[1].ptr);
       +        b[0].wid += b[1].wid;
       +        b[0].nrune += b[1].nrune;
       +        _frdelbox(f, bn+1, bn+1);
       +}
       +
       +int
       +_frfindbox(Frame *f, int bn, ulong p, ulong q)        /* find box containing q and put q on a box boundary */
       +{
       +        Frbox *b;
       +
       +        for(b = &f->box[bn]; bn<f->nbox && p+NRUNE(b)<=q; bn++, b++)
       +                p += NRUNE(b);
       +        if(p != q)
       +                _frsplitbox(f, bn++, (int)(q-p));
       +        return bn;
       +}
 (DIR) diff --git a/src/libframe/frdraw.c b/src/libframe/frdraw.c
       t@@ -0,0 +1,176 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <draw.h>
       +#include <mouse.h>
       +#include <frame.h>
       +
       +void
       +_frredraw(Frame *f, Point pt)
       +{
       +        Frbox *b;
       +        int nb;
       +        /* static int x; */
       +
       +        for(nb=0,b=f->box; nb<f->nbox; nb++, b++){
       +                _frcklinewrap(f, &pt, b);
       +                if(b->nrune >= 0){
       +                        string(f->b, pt, f->cols[TEXT], ZP, f->font, (char *)b->ptr);
       +                }
       +                pt.x += b->wid;
       +        }
       +}
       +
       +static int
       +nbytes(char *s0, int nr)
       +{
       +        char *s;
       +        Rune r;
       +
       +        s = s0;
       +        while(--nr >= 0)
       +                s += chartorune(&r, s);
       +        return s-s0;
       +}
       +
       +void
       +frdrawsel(Frame *f, Point pt, ulong p0, ulong p1, int issel)
       +{
       +        Image *back, *text;
       +
       +        if(f->ticked)
       +                frtick(f, frptofchar(f, f->p0), 0);
       +
       +        if(p0 == p1){
       +                frtick(f, pt, issel);
       +                return;
       +        }
       +
       +        if(issel){
       +                back = f->cols[HIGH];
       +                text = f->cols[HTEXT];
       +        }else{
       +                back = f->cols[BACK];
       +                text = f->cols[TEXT];
       +        }
       +
       +        frdrawsel0(f, pt, p0, p1, back, text);
       +}
       +
       +void
       +frdrawsel0(Frame *f, Point pt, ulong p0, ulong p1, Image *back, Image *text)
       +{
       +        Frbox *b;
       +        int nb, nr, w, x, trim;
       +        Point qt;
       +        uint p;
       +        char *ptr;
       +
       +        p = 0;
       +        b = f->box;
       +        trim = 0;
       +        for(nb=0; nb<f->nbox && p<p1; nb++){
       +                nr = b->nrune;
       +                if(nr < 0)
       +                        nr = 1;
       +                if(p+nr <= p0)
       +                        goto Continue;
       +                if(p >= p0){
       +                        qt = pt;
       +                        _frcklinewrap(f, &pt, b);
       +                        if(pt.y > qt.y)
       +                                draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt);
       +                }
       +                ptr = (char*)b->ptr;
       +                if(p < p0){        /* beginning of region: advance into box */
       +                        ptr += nbytes(ptr, p0-p);
       +                        nr -= (p0-p);
       +                        p = p0;
       +                }
       +                trim = 0;
       +                if(p+nr > p1){        /* end of region: trim box */
       +                        nr -= (p+nr)-p1;
       +                        trim = 1;
       +                }
       +                if(b->nrune<0 || nr==b->nrune)
       +                        w = b->wid;
       +                else
       +                        w = stringnwidth(f->font, ptr, nr);
       +                x = pt.x+w;
       +                if(x > f->r.max.x)
       +                        x = f->r.max.x;
       +                draw(f->b, Rect(pt.x, pt.y, x, pt.y+f->font->height), back, nil, pt);
       +                if(b->nrune >= 0)
       +                        stringn(f->b, pt, text, ZP, f->font, ptr, nr);
       +                pt.x += w;
       +            Continue:
       +                b++;
       +                p += nr;
       +        }
       +        /* if this is end of last plain text box on wrapped line, fill to end of line */
       +        if(p1>p0 &&  b>f->box && b<f->box+f->nbox && b[-1].nrune>0 && !trim){
       +                qt = pt;
       +                _frcklinewrap(f, &pt, b);
       +                if(pt.y > qt.y)
       +                        draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt);
       +        }
       +}
       +
       +void
       +frtick(Frame *f, Point pt, int ticked)
       +{
       +        Rectangle r;
       +
       +        if(f->ticked==ticked || f->tick==0 || !ptinrect(pt, f->r))
       +                return;
       +        pt.x--;        /* looks best just left of where requested */
       +        r = Rect(pt.x, pt.y, pt.x+FRTICKW, pt.y+f->font->height);
       +        if(ticked){
       +                draw(f->tickback, f->tickback->r, f->b, nil, pt);
       +                draw(f->b, r, f->tick, nil, ZP);
       +        }else
       +                draw(f->b, r, f->tickback, nil, ZP);
       +        f->ticked = ticked;
       +}
       +
       +Point
       +_frdraw(Frame *f, Point pt)
       +{
       +        Frbox *b;
       +        int nb, n;
       +
       +        for(b=f->box,nb=0; nb<f->nbox; nb++, b++){
       +                _frcklinewrap0(f, &pt, b);
       +                if(pt.y == f->r.max.y){
       +                        f->nchars -= _frstrlen(f, nb);
       +                        _frdelbox(f, nb, f->nbox-1);
       +                        break;
       +                }
       +                if(b->nrune > 0){
       +                        n = _frcanfit(f, pt, b);
       +                        if(n == 0)
       +                                drawerror(f->display, "draw: _frcanfit==0");
       +                        if(n != b->nrune){
       +                                _frsplitbox(f, nb, n);
       +                                b = &f->box[nb];
       +                        }
       +                        pt.x += b->wid;
       +                }else{
       +                        if(b->bc == '\n'){
       +                                pt.x = f->r.min.x;
       +                                pt.y+=f->font->height;
       +                        }else
       +                                pt.x += _frnewwid(f, pt, b);
       +                }
       +        }
       +        return pt;
       +}
       +
       +int
       +_frstrlen(Frame *f, int nb)
       +{
       +        int n;
       +
       +        for(n=0; nb<f->nbox; nb++)
       +                n += NRUNE(&f->box[nb]);
       +        return n;
       +}
 (DIR) diff --git a/src/libframe/mkfile b/src/libframe/mkfile
       t@@ -0,0 +1 @@
       +<../libutf/mkfile