aboutsummaryrefslogtreecommitdiff
path: root/src/libframe
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-09-30 17:47:43 +0000
committerrsc <devnull@localhost>2003-09-30 17:47:43 +0000
commitb822e0d8035e1c80b86d974e63bd10936a96ed2d (patch)
treee213ab32233fa820bc9ce8a043b8b44173377f4b /src/libframe
parentb5990708483a1fa452b3d4b6ed2bfa998deeeb39 (diff)
downloadplan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.tar.gz
plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.tar.bz2
plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.zip
Initial revision
Diffstat (limited to 'src/libframe')
-rw-r--r--src/libframe/Makefile92
-rw-r--r--src/libframe/Makefile.MID21
-rw-r--r--src/libframe/frbox.c156
-rw-r--r--src/libframe/frdraw.c176
-rw-r--r--src/libframe/mkfile1
5 files changed, 446 insertions, 0 deletions
diff --git a/src/libframe/Makefile b/src/libframe/Makefile
new file mode 100644
index 00000000..81b73e98
--- /dev/null
+++ b/src/libframe/Makefile
@@ -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
diff --git a/src/libframe/Makefile.MID b/src/libframe/Makefile.MID
new file mode 100644
index 00000000..f7d29ece
--- /dev/null
+++ b/src/libframe/Makefile.MID
@@ -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
diff --git a/src/libframe/frbox.c b/src/libframe/frbox.c
new file mode 100644
index 00000000..d2593011
--- /dev/null
+++ b/src/libframe/frbox.c
@@ -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;
+}
diff --git a/src/libframe/frdraw.c b/src/libframe/frdraw.c
new file mode 100644
index 00000000..29c3daff
--- /dev/null
+++ b/src/libframe/frdraw.c
@@ -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;
+}
diff --git a/src/libframe/mkfile b/src/libframe/mkfile
new file mode 100644
index 00000000..bb99a25a
--- /dev/null
+++ b/src/libframe/mkfile
@@ -0,0 +1 @@
+<../libutf/mkfile