1*7dd7cddfSDavid du Colombier #include <u.h> 2*7dd7cddfSDavid 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> 6*7dd7cddfSDavid du Colombier #include <keyboard.h> 7*7dd7cddfSDavid du Colombier #include <frame.h> 8*7dd7cddfSDavid du Colombier #include <auth.h> 9*7dd7cddfSDavid du Colombier #include <fcall.h> 10*7dd7cddfSDavid du Colombier #include <plumb.h> 11*7dd7cddfSDavid du Colombier #include "dat.h" 12*7dd7cddfSDavid du Colombier #include "fns.h" 13*7dd7cddfSDavid du Colombier 14*7dd7cddfSDavid du Colombier static Image *scrtmp; 15*7dd7cddfSDavid du Colombier 16*7dd7cddfSDavid du Colombier static 17*7dd7cddfSDavid du Colombier Rectangle 18*7dd7cddfSDavid du Colombier scrpos(Rectangle r, uint p0, uint p1, uint tot) 19*7dd7cddfSDavid du Colombier { 20*7dd7cddfSDavid du Colombier Rectangle q; 21*7dd7cddfSDavid du Colombier int h; 22*7dd7cddfSDavid du Colombier 23*7dd7cddfSDavid du Colombier q = r; 24*7dd7cddfSDavid du Colombier h = q.max.y-q.min.y; 25*7dd7cddfSDavid du Colombier if(tot == 0) 26*7dd7cddfSDavid du Colombier return q; 27*7dd7cddfSDavid du Colombier if(tot > 1024*1024){ 28*7dd7cddfSDavid du Colombier tot>>=10; 29*7dd7cddfSDavid du Colombier p0>>=10; 30*7dd7cddfSDavid du Colombier p1>>=10; 31*7dd7cddfSDavid du Colombier } 32*7dd7cddfSDavid du Colombier if(p0 > 0) 33*7dd7cddfSDavid du Colombier q.min.y += h*p0/tot; 34*7dd7cddfSDavid du Colombier if(p1 < tot) 35*7dd7cddfSDavid du Colombier q.max.y -= h*(tot-p1)/tot; 36*7dd7cddfSDavid du Colombier if(q.max.y < q.min.y+2){ 37*7dd7cddfSDavid du Colombier if(q.min.y+2 <= r.max.y) 38*7dd7cddfSDavid du Colombier q.max.y = q.min.y+2; 39*7dd7cddfSDavid du Colombier else 40*7dd7cddfSDavid du Colombier q.min.y = q.max.y-2; 41*7dd7cddfSDavid du Colombier } 42*7dd7cddfSDavid du Colombier return q; 43*7dd7cddfSDavid du Colombier } 44*7dd7cddfSDavid du Colombier 45*7dd7cddfSDavid du Colombier void 46*7dd7cddfSDavid du Colombier scrlresize(void) 47*7dd7cddfSDavid du Colombier { 48*7dd7cddfSDavid du Colombier freeimage(scrtmp); 49*7dd7cddfSDavid du Colombier scrtmp = allocimage(display, Rect(0, 0, 32, screen->r.max.y), display->chan, 0, DNofill); 50*7dd7cddfSDavid du Colombier if(scrtmp == nil) 51*7dd7cddfSDavid du Colombier error("scroll alloc"); 52*7dd7cddfSDavid du Colombier } 53*7dd7cddfSDavid du Colombier 54*7dd7cddfSDavid du Colombier void 55*7dd7cddfSDavid du Colombier textscrdraw(Text *t) 56*7dd7cddfSDavid du Colombier { 57*7dd7cddfSDavid du Colombier Rectangle r, r1, r2; 58*7dd7cddfSDavid du Colombier Image *b; 59*7dd7cddfSDavid du Colombier 60*7dd7cddfSDavid du Colombier if(t->w==nil || t!=&t->w->body) 61*7dd7cddfSDavid du Colombier return; 62*7dd7cddfSDavid du Colombier if(scrtmp == nil) 63*7dd7cddfSDavid du Colombier scrlresize(); 64*7dd7cddfSDavid du Colombier r = t->scrollr; 65*7dd7cddfSDavid du Colombier b = scrtmp; 66*7dd7cddfSDavid du Colombier r1 = r; 67*7dd7cddfSDavid du Colombier r1.min.x = 0; 68*7dd7cddfSDavid du Colombier r1.max.x = Dx(r); 69*7dd7cddfSDavid du Colombier r2 = scrpos(r1, t->org, t->org+t->nchars, t->file->nc); 70*7dd7cddfSDavid du Colombier if(!eqrect(r2, t->lastsr)){ 71*7dd7cddfSDavid du Colombier t->lastsr = r2; 72*7dd7cddfSDavid du Colombier draw(b, r1, t->cols[BORD], nil, ZP); 73*7dd7cddfSDavid du Colombier draw(b, r2, t->cols[BACK], nil, ZP); 74*7dd7cddfSDavid du Colombier r2.min.x = r2.max.x-1; 75*7dd7cddfSDavid du Colombier draw(b, r2, t->cols[BORD], nil, ZP); 76*7dd7cddfSDavid du Colombier draw(t->b, r, b, nil, Pt(0, r1.min.y)); 77*7dd7cddfSDavid du Colombier /*flushimage(display, 1);/*BUG?*/ 78*7dd7cddfSDavid du Colombier } 79*7dd7cddfSDavid du Colombier } 80*7dd7cddfSDavid du Colombier 81*7dd7cddfSDavid du Colombier void 82*7dd7cddfSDavid du Colombier scrsleep(uint dt) 83*7dd7cddfSDavid du Colombier { 84*7dd7cddfSDavid du Colombier Timer *timer; 85*7dd7cddfSDavid du Colombier static Alt alts[3]; 86*7dd7cddfSDavid du Colombier 87*7dd7cddfSDavid du Colombier timer = timerstart(dt); 88*7dd7cddfSDavid du Colombier alts[0].c = timer->c; 89*7dd7cddfSDavid du Colombier alts[0].v = nil; 90*7dd7cddfSDavid du Colombier alts[0].op = CHANRCV; 91*7dd7cddfSDavid du Colombier alts[1].c = mousectl->c; 92*7dd7cddfSDavid du Colombier alts[1].v = &mousectl->Mouse; 93*7dd7cddfSDavid du Colombier alts[1].op = CHANRCV; 94*7dd7cddfSDavid du Colombier alts[2].op = CHANEND; 95*7dd7cddfSDavid du Colombier for(;;) 96*7dd7cddfSDavid du Colombier switch(alt(alts)){ 97*7dd7cddfSDavid du Colombier case 0: 98*7dd7cddfSDavid du Colombier timerstop(timer); 99*7dd7cddfSDavid du Colombier return; 100*7dd7cddfSDavid du Colombier case 1: 101*7dd7cddfSDavid du Colombier timercancel(timer); 102*7dd7cddfSDavid du Colombier return; 103*7dd7cddfSDavid du Colombier } 104*7dd7cddfSDavid du Colombier } 105*7dd7cddfSDavid du Colombier 106*7dd7cddfSDavid du Colombier void 107*7dd7cddfSDavid du Colombier textscroll(Text *t, int but) 108*7dd7cddfSDavid du Colombier { 109*7dd7cddfSDavid du Colombier uint p0, oldp0; 110*7dd7cddfSDavid du Colombier Rectangle s; 111*7dd7cddfSDavid du Colombier int x, y, my, h, first; 112*7dd7cddfSDavid du Colombier 113*7dd7cddfSDavid du Colombier s = insetrect(t->scrollr, 1); 114*7dd7cddfSDavid du Colombier h = s.max.y-s.min.y; 115*7dd7cddfSDavid du Colombier x = (s.min.x+s.max.x)/2; 116*7dd7cddfSDavid du Colombier oldp0 = ~0; 117*7dd7cddfSDavid du Colombier first = TRUE; 118*7dd7cddfSDavid du Colombier do{ 119*7dd7cddfSDavid du Colombier flushimage(display, 1); 120*7dd7cddfSDavid du Colombier if(mouse->xy.x<s.min.x || s.max.x<=mouse->xy.x){ 121*7dd7cddfSDavid du Colombier readmouse(mousectl); 122*7dd7cddfSDavid du Colombier }else{ 123*7dd7cddfSDavid du Colombier my = mouse->xy.y; 124*7dd7cddfSDavid du Colombier if(my < s.min.y) 125*7dd7cddfSDavid du Colombier my = s.min.y; 126*7dd7cddfSDavid du Colombier if(my >= s.max.y) 127*7dd7cddfSDavid du Colombier my = s.max.y; 128*7dd7cddfSDavid du Colombier if(!eqpt(mouse->xy, Pt(x, my))){ 129*7dd7cddfSDavid du Colombier moveto(mousectl, Pt(x, my)); 130*7dd7cddfSDavid du Colombier readmouse(mousectl); /* absorb event generated by moveto() */ 131*7dd7cddfSDavid du Colombier } 132*7dd7cddfSDavid du Colombier if(but == 2){ 133*7dd7cddfSDavid du Colombier y = my; 134*7dd7cddfSDavid du Colombier if(y > s.max.y-2) 135*7dd7cddfSDavid du Colombier y = s.max.y-2; 136*7dd7cddfSDavid du Colombier if(t->file->nc > 1024*1024) 137*7dd7cddfSDavid du Colombier p0 = ((t->file->nc>>10)*(y-s.min.y)/h)<<10; 138*7dd7cddfSDavid du Colombier else 139*7dd7cddfSDavid du Colombier p0 = t->file->nc*(y-s.min.y)/h; 140*7dd7cddfSDavid du Colombier if(oldp0 != p0) 141*7dd7cddfSDavid du Colombier textsetorigin(t, p0, FALSE); 142*7dd7cddfSDavid du Colombier oldp0 = p0; 143*7dd7cddfSDavid du Colombier readmouse(mousectl); 144*7dd7cddfSDavid du Colombier continue; 145*7dd7cddfSDavid du Colombier } 146*7dd7cddfSDavid du Colombier if(but == 1) 147*7dd7cddfSDavid du Colombier p0 = textbacknl(t, t->org, (my-s.min.y)/t->font->height); 148*7dd7cddfSDavid du Colombier else 149*7dd7cddfSDavid du Colombier p0 = t->org+frcharofpt(t, Pt(s.max.x, my)); 150*7dd7cddfSDavid du Colombier if(oldp0 != p0) 151*7dd7cddfSDavid du Colombier textsetorigin(t, p0, TRUE); 152*7dd7cddfSDavid du Colombier oldp0 = p0; 153*7dd7cddfSDavid du Colombier /* debounce */ 154*7dd7cddfSDavid du Colombier if(first){ 155*7dd7cddfSDavid du Colombier flushimage(display, 1); 156*7dd7cddfSDavid du Colombier sleep(200); 157*7dd7cddfSDavid du Colombier nbrecv(mousectl->c, &mousectl->Mouse); 158*7dd7cddfSDavid du Colombier first = FALSE; 159*7dd7cddfSDavid du Colombier } 160*7dd7cddfSDavid du Colombier scrsleep(80); 161*7dd7cddfSDavid du Colombier } 162*7dd7cddfSDavid du Colombier }while(mouse->buttons & (1<<(but-1))); 163*7dd7cddfSDavid du Colombier while(mouse->buttons) 164*7dd7cddfSDavid du Colombier readmouse(mousectl); 165*7dd7cddfSDavid du Colombier } 166