plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

scrl.c (2917B)


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