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