13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3*7dd7cddfSDavid du Colombier #include <draw.h>
4*7dd7cddfSDavid du Colombier #include <thread.h>
5*7dd7cddfSDavid du Colombier #include <mouse.h>
63e12c5d1SDavid du Colombier #include <frame.h>
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier Point
_frptofcharptb(Frame * f,ulong p,Point pt,int bn)93e12c5d1SDavid du Colombier _frptofcharptb(Frame *f, ulong p, Point pt, int bn)
103e12c5d1SDavid du Colombier {
113e12c5d1SDavid du Colombier uchar *s;
123e12c5d1SDavid du Colombier Frbox *b;
133e12c5d1SDavid du Colombier int w, l;
143e12c5d1SDavid du Colombier Rune r;
153e12c5d1SDavid du Colombier
163e12c5d1SDavid du Colombier for(b = &f->box[bn]; bn<f->nbox; bn++,b++){
173e12c5d1SDavid du Colombier _frcklinewrap(f, &pt, b);
183e12c5d1SDavid du Colombier if(p < (l=NRUNE(b))){
193e12c5d1SDavid du Colombier if(b->nrune > 0)
203e12c5d1SDavid du Colombier for(s=b->ptr; p>0; s+=w, p--){
213e12c5d1SDavid du Colombier if((r = *s) < Runeself)
223e12c5d1SDavid du Colombier w = 1;
233e12c5d1SDavid du Colombier else
243e12c5d1SDavid du Colombier w = chartorune(&r, (char*)s);
25*7dd7cddfSDavid du Colombier pt.x += stringnwidth(f->font, (char*)s, 1);
263e12c5d1SDavid du Colombier if(r==0 || pt.x>f->r.max.x)
27*7dd7cddfSDavid du Colombier drawerror(f->display, "frptofchar");
283e12c5d1SDavid du Colombier }
293e12c5d1SDavid du Colombier break;
303e12c5d1SDavid du Colombier }
313e12c5d1SDavid du Colombier p -= l;
323e12c5d1SDavid du Colombier _fradvance(f, &pt, b);
333e12c5d1SDavid du Colombier }
343e12c5d1SDavid du Colombier return pt;
353e12c5d1SDavid du Colombier }
363e12c5d1SDavid du Colombier
373e12c5d1SDavid du Colombier Point
frptofchar(Frame * f,ulong p)383e12c5d1SDavid du Colombier frptofchar(Frame *f, ulong p)
393e12c5d1SDavid du Colombier {
40*7dd7cddfSDavid du Colombier return _frptofcharptb(f, p, f->r.min, 0);
413e12c5d1SDavid du Colombier }
423e12c5d1SDavid du Colombier
433e12c5d1SDavid du Colombier Point
_frptofcharnb(Frame * f,ulong p,int nb)443e12c5d1SDavid du Colombier _frptofcharnb(Frame *f, ulong p, int nb) /* doesn't do final _fradvance to next line */
453e12c5d1SDavid du Colombier {
463e12c5d1SDavid du Colombier Point pt;
473e12c5d1SDavid du Colombier int nbox;
483e12c5d1SDavid du Colombier
493e12c5d1SDavid du Colombier nbox = f->nbox;
503e12c5d1SDavid du Colombier f->nbox = nb;
51*7dd7cddfSDavid du Colombier pt = _frptofcharptb(f, p, f->r.min, 0);
523e12c5d1SDavid du Colombier f->nbox = nbox;
533e12c5d1SDavid du Colombier return pt;
543e12c5d1SDavid du Colombier }
553e12c5d1SDavid du Colombier
563e12c5d1SDavid du Colombier static
573e12c5d1SDavid du Colombier Point
_frgrid(Frame * f,Point p)583e12c5d1SDavid du Colombier _frgrid(Frame *f, Point p)
593e12c5d1SDavid du Colombier {
603e12c5d1SDavid du Colombier p.y -= f->r.min.y;
613e12c5d1SDavid du Colombier p.y -= p.y%f->font->height;
623e12c5d1SDavid du Colombier p.y += f->r.min.y;
633e12c5d1SDavid du Colombier if(p.x > f->r.max.x)
643e12c5d1SDavid du Colombier p.x = f->r.max.x;
653e12c5d1SDavid du Colombier return p;
663e12c5d1SDavid du Colombier }
673e12c5d1SDavid du Colombier
683e12c5d1SDavid du Colombier ulong
frcharofpt(Frame * f,Point pt)693e12c5d1SDavid du Colombier frcharofpt(Frame *f, Point pt)
703e12c5d1SDavid du Colombier {
713e12c5d1SDavid du Colombier Point qt;
723e12c5d1SDavid du Colombier int w, bn;
733e12c5d1SDavid du Colombier uchar *s;
743e12c5d1SDavid du Colombier Frbox *b;
753e12c5d1SDavid du Colombier ulong p;
763e12c5d1SDavid du Colombier Rune r;
773e12c5d1SDavid du Colombier
783e12c5d1SDavid du Colombier pt = _frgrid(f, pt);
79*7dd7cddfSDavid du Colombier qt = f->r.min;
803e12c5d1SDavid du Colombier for(b=f->box,bn=0,p=0; bn<f->nbox && qt.y<pt.y; bn++,b++){
813e12c5d1SDavid du Colombier _frcklinewrap(f, &qt, b);
823e12c5d1SDavid du Colombier if(qt.y >= pt.y)
833e12c5d1SDavid du Colombier break;
843e12c5d1SDavid du Colombier _fradvance(f, &qt, b);
853e12c5d1SDavid du Colombier p += NRUNE(b);
863e12c5d1SDavid du Colombier }
873e12c5d1SDavid du Colombier for(; bn<f->nbox && qt.x<=pt.x; bn++,b++){
883e12c5d1SDavid du Colombier _frcklinewrap(f, &qt, b);
893e12c5d1SDavid du Colombier if(qt.y > pt.y)
903e12c5d1SDavid du Colombier break;
913e12c5d1SDavid du Colombier if(qt.x+b->wid > pt.x){
923e12c5d1SDavid du Colombier if(b->nrune < 0)
933e12c5d1SDavid du Colombier _fradvance(f, &qt, b);
943e12c5d1SDavid du Colombier else{
953e12c5d1SDavid du Colombier s = b->ptr;
963e12c5d1SDavid du Colombier for(;;){
973e12c5d1SDavid du Colombier if((r = *s) < Runeself)
983e12c5d1SDavid du Colombier w = 1;
993e12c5d1SDavid du Colombier else
1003e12c5d1SDavid du Colombier w = chartorune(&r, (char*)s);
1013e12c5d1SDavid du Colombier if(r == 0)
102*7dd7cddfSDavid du Colombier drawerror(f->display, "end of string in frcharofpt");
103*7dd7cddfSDavid du Colombier qt.x += stringnwidth(f->font, (char*)s, 1);
1043e12c5d1SDavid du Colombier s += w;
1053e12c5d1SDavid du Colombier if(qt.x > pt.x)
1063e12c5d1SDavid du Colombier break;
1073e12c5d1SDavid du Colombier p++;
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier }
1103e12c5d1SDavid du Colombier }else{
1113e12c5d1SDavid du Colombier p += NRUNE(b);
1123e12c5d1SDavid du Colombier _fradvance(f, &qt, b);
1133e12c5d1SDavid du Colombier }
1143e12c5d1SDavid du Colombier }
1153e12c5d1SDavid du Colombier return p;
1163e12c5d1SDavid du Colombier }
117