scope.c (4943B)
1 #include <u.h> 2 #include <libc.h> 3 #include <thread.h> 4 #include <draw.h> 5 #include <mouse.h> 6 #include <cursor.h> 7 #include <keyboard.h> 8 9 #define LMAX 1024 10 #define RBUF 1024 11 #define DFPS 60 12 13 enum { 14 C_BG = 0x3f3f3fff, 15 C_GG = 0x000000ff, 16 C_FG = 0xffff00ff, 17 }; 18 19 Point P[LMAX]; 20 21 typedef struct Readctl Readctl; 22 23 struct Readctl { 24 Channel *c; 25 }; 26 27 Image *Im, *Ibg, *Igg, *Ifg, *Igrid; 28 Rectangle R; 29 int rh; 30 31 void (*dlines)(void); 32 33 34 35 36 void 37 usage(void) 38 { 39 fprint(2, "usage: %s [-lrs2]\n", argv0); 40 threadexitsall("usage"); 41 } 42 43 void 44 dclear(void) 45 { 46 draw(screen, screen->r, Ibg, 0, ZP); 47 //draw(screen, R, Ibg, 0, ZP); 48 } 49 50 void 51 dgrid(void) 52 { 53 const int div = 8; 54 int i; 55 Rectangle r; 56 Point p; 57 /* horizontal */ 58 r =Rect(0,0,rh,1); 59 for (i = 0; i <= div; i++){ 60 p = Pt(0, i * (rh-1)/div); 61 draw(Igrid, rectaddpt(r, p), Igg, 0, ZP); 62 } 63 /* vertical */ 64 r = Rect(0,0,1,rh); 65 for (i = 0; i <= div; i++){ 66 p = Pt(i * (rh-1)/div, 0); 67 draw(Igrid, rectaddpt(r, p), Igg, 0, ZP); 68 } 69 } 70 71 void 72 dfade(void) 73 { 74 draw(screen, R, Ibg, Im, ZP); 75 } 76 77 void 78 dXY(void) 79 { 80 int i; 81 Point p; 82 for (i = 0; i < LMAX; i++){ 83 p = Pt(P[i].x, -P[i].y); 84 p = addpt(p, addpt(R.min, Pt(rh/2, rh/2))); 85 draw(screen, Rpt(p, addpt(p, Pt(1,1))), Ifg, 0, ZP); 86 } 87 } 88 89 void 90 dboth(void) 91 { 92 int i; 93 Point p0, p1; 94 for (i = 0; i < LMAX; i++){ 95 p0.x = R.min.x + i * rh / LMAX; 96 p0.y = R.min.y + rh/4 - P[i].x/2; 97 p1.x = p0.x; 98 p1.y = R.min.y + (3 * rh)/4 - P[i].y/2; 99 draw(screen, Rpt(p0, addpt(p0, Pt(1,1))), Ifg, 0, ZP); 100 draw(screen, Rpt(p1, addpt(p1, Pt(1,1))), Ifg, 0, ZP); 101 } 102 } 103 104 void 105 dmono(int c) 106 { 107 int i; 108 Point p; 109 for (i = 0; i < LMAX; i++){ 110 p.x = R.min.x + i * rh / LMAX; 111 p.y = R.min.y + rh/2; 112 p.y += c ? -P[i].x : -P[i].y; 113 draw(screen, Rpt(p, addpt(p, Pt(1,1))), Ifg, 0, ZP); 114 } 115 } 116 117 void 118 dleft(void) 119 { 120 dmono(0); 121 } 122 123 void 124 dright(void) 125 { 126 dmono(1); 127 } 128 129 void (*dfunc[])(void) = {dleft, dright, dboth, dXY}; 130 131 132 void 133 threadupdate(void *v) 134 { 135 vlong ot, ct; 136 Channel *c; 137 c = v; 138 threadsetname("threadupdate"); 139 ot = 0; 140 for (;;) { 141 ct = nsec(); 142 if ((ct - ot) > (1000000000/DFPS)) { 143 send(c, 0); 144 ot = nsec(); 145 } 146 yield(); 147 }; 148 } 149 150 void 151 procread(void *v) 152 { 153 s16int buf[RBUF]; 154 s16int *bp; 155 long n; 156 Readctl *rctl; 157 rctl = v; 158 threadsetname("procread"); 159 while((n = read(0, buf, sizeof(s16int) * RBUF)) > 0) { 160 for (bp = buf; bp < buf + (n / sizeof(s16int)); bp+=2) { 161 send(rctl->c, bp); 162 } 163 } 164 chanclose(rctl->c); 165 } 166 167 Rectangle 168 getdrawrect(void) 169 { 170 Rectangle R; 171 R.max = Pt(Dx(screen->r), Dy(screen->r)); 172 R.min = Pt(0, 0); 173 R.max.x = (R.max.x < R.max.y) ? R.max.x : R.max.y; 174 rh = R.max.y = R.max.x; 175 R = rectaddpt(R, addpt(screen->r.min, 176 Pt((Dx(screen->r)-rh)/2,(Dy(screen->r)-rh)/2))); 177 return R; 178 } 179 180 void 181 threadmain(int argc, char **argv) 182 { 183 long pp; 184 Mousectl *mctl; 185 Keyboardctl *kctl; 186 Rune kv; 187 Mouse mv; 188 int rv[2]; 189 Channel *supc; 190 int sv; 191 Readctl *rctl; 192 s16int prv[2]; 193 194 dlines = dXY; 195 pp = 0; 196 197 ARGBEGIN { 198 case 'l': 199 dlines = dleft; 200 break; 201 case 'r': 202 dlines = dright; 203 break; 204 case 's': 205 dlines = dboth; 206 break; 207 case '2': 208 dlines = dXY; 209 break; 210 default: 211 usage(); 212 } ARGEND 213 if (argc > 0) usage(); 214 if (initdraw(nil, nil, "scope") < 0) sysfatal("initdraw failed: %r"); 215 if ((mctl = initmouse(0, screen)) == nil) sysfatal("initmouse failed: %r"); 216 if ((kctl = initkeyboard(0)) == nil) sysfatal("initkeyboard failed: %r"); 217 supc = chancreate(sizeof(int), 0); 218 219 Ibg = allocimage(display, Rect(0,0,1,1), RGB24, 1, C_BG); 220 Igg = allocimage(display, Rect(0,0,1,1), RGB24, 1, C_GG); 221 Ifg = allocimage(display, Rect(0,0,1,1), RGB24, 1, C_FG); 222 Im = allocimage(display, Rect(0,0,1,1), RGBA32, 1, 0xffffff1f); 223 rctl = malloc(sizeof(Readctl)); 224 rctl->c = chancreate(sizeof(s16int) * 2, LMAX); 225 226 threadcreate(threadupdate, supc, 8 * 1024); 227 proccreate(procread, rctl, 64*1024); 228 229 char *menustr[5] = { 230 "left", 231 "right", 232 "both", 233 "XY", 234 nil, 235 }; 236 237 Menu menu = {menustr, nil, 0}; 238 239 R = getdrawrect(); 240 Igrid = allocimage(display, Rect(0,0,rh,rh), RGB24, 0, C_BG); 241 dgrid(); 242 dclear(); 243 flushimage(display, 1); 244 Alt alts[6] = { 245 {kctl->c, &kv, CHANRCV}, 246 {mctl->c, &mv, CHANRCV}, 247 {mctl->resizec, rv, CHANRCV}, 248 {supc, &sv, CHANRCV}, 249 {rctl->c, prv, CHANRCV}, 250 {0, 0, CHANEND}, 251 }; 252 for(;;){ 253 switch(alt(alts)){ 254 case 0: /* keyboard */ 255 if (kv == 'q') threadexitsall(0); 256 if (kv == 0x7f) threadexitsall(0); 257 break; 258 case 1: /* mouse */ 259 if (mv.buttons == 1) { 260 int m; 261 m = menuhit(1, mctl, &menu, 0); 262 if (m >=0) dlines = dfunc[m]; 263 } 264 break; 265 case 2: /* resize */ 266 if(getwindow(display, Refnone) < 0) 267 sysfatal("resize failed: %r"); 268 R = getdrawrect(); 269 freeimage(Igrid); 270 Igrid = allocimage(display, Rect(0,0,rh,rh), RGB24, 0, C_BG); 271 dgrid(); 272 dclear(); 273 case 3: /* update screen */ 274 draw(screen, R, Igrid, 0, ZP); 275 dlines(); 276 flushimage(display, 1); 277 break; 278 case 4: /* read input */ 279 P[pp] = (Pt(prv[0] * rh / 0xffff, prv[1] * rh / 0xffff)); 280 pp = (pp+1)%LMAX; 281 break; 282 } 283 } 284 }