summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..244097c
--- /dev/null
+++ b/main.c
@@ -0,0 +1,202 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <draw.h>
+#include <memdraw.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include "dat.h"
+#include "fns.h"
+
+Mousectl *mctl;
+ulong kdown;
+double Δt;
+Image *screenb;
+Memimage *fb;
+Memimage *bg, *fg;
+
+Rune keys[Ke] = {
+ [K↑] Kup,
+ [K↓] Kdown,
+ [K←] Kleft,
+ [K→] Kright
+};
+
+Memimage*
+eallocmemimage(Rectangle r, ulong chan)
+{
+ Memimage *i;
+
+ i = allocmemimage(r, chan);
+ if(i == nil)
+ sysfatal("allocmemimage: %r");
+ memfillcolor(i, DTransparent);
+ return i;
+}
+
+Memimage*
+rgb(ulong c)
+{
+ Memimage *i;
+
+ i = eallocmemimage(Rect(0,0,1,1), screen->chan);
+ i->flags |= Frepl;
+ i->clipr = Rect(-1e6, -1e6, 1e6, 1e6);
+ memfillcolor(i, c);
+ return i;
+}
+
+void
+kbdproc(void*)
+{
+ Rune r, *a;
+ char buf[128], *s;
+ int fd, n;
+
+ threadsetname("kbdproc");
+ if((fd = open("/dev/kbd", OREAD)) < 0)
+ sysfatal("kbdproc: %r");
+ memset(buf, 0, sizeof buf);
+ for(;;){
+ if(buf[0] != 0){
+ n = strlen(buf)+1;
+ memmove(buf, buf+n, sizeof(buf)-n);
+ }
+ if(buf[0] == 0){
+ if((n = read(fd, buf, sizeof(buf)-1)) <= 0)
+ break;
+ buf[n-1] = 0;
+ buf[n] = 0;
+ }
+ if(buf[0] == 'c'){
+ if(utfrune(buf, Kdel)){
+ close(fd);
+ threadexitsall(nil);
+ }
+ }
+ if(buf[0] != 'k' && buf[0] != 'K')
+ continue;
+ s = buf+1;
+ kdown = 0;
+ while(*s){
+ s += chartorune(&r, s);
+ for(a = keys; a < keys+Ke; a++)
+ if(r == *a){
+ kdown |= 1 << a-keys;
+ break;
+ }
+ }
+ }
+}
+
+void
+drawproc(void *arg)
+{
+ Channel *c;
+
+ c = arg;
+ for(;;){
+ send(c, nil);
+ sleep(FPS2MS(60));
+ }
+}
+
+void
+resetfb(void)
+{
+ freeimage(screenb);
+ screenb = allocimage(display, Rect(0,0,Dx(screen->r),Dy(screen->r)), screen->chan, 0, DNofill);
+ freememimage(fb);
+ fb = eallocmemimage(Rect(0,0,Dx(screen->r),Dy(screen->r)), screen->chan);
+}
+
+void
+redraw(void)
+{
+ Rectangle r;
+ Point p;
+ static Point incp = {1,1};
+
+ memimagedraw(fb, fb->r, bg, ZP, nil, ZP, SoverD);
+ for(p.y = 0; p.y < Dy(fb->r); p.y++)
+ for(p.x = 0; p.x < Dx(fb->r); p.x++)
+ if(p.x%15 == 0 || p.y%15 == 0)
+ memimagedraw(fb, Rpt(p, addpt(p, incp)), fg, ZP, nil, ZP, SoverD);
+ /*for(p = ZP; ptinrect(p, fb->r); p.x++, p.y++)
+ memimagedraw(fb, Rpt(p, addpt(p, Pt(1,1))), fg, ZP, nil, ZP, SoverD);*/
+ for(r = fb->r; r.min.y < fb->r.max.y; r.min.y++){
+ r.max.y = r.min.y+1;
+ loadimage(screenb, r, byteaddr(fb, r.min), bytesperline(r, fb->depth));
+ }
+ lockdisplay(display);
+ draw(screen, screen->r, screenb, nil, ZP);
+ flushimage(display, 1);
+ unlockdisplay(display);
+}
+
+
+void
+mouse(void)
+{
+}
+
+void
+resize(void)
+{
+ if(getwindow(display, Refnone) < 0)
+ fprint(2, "can't reattach to window\n");
+ resetfb();
+ redraw();
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s\n", argv0);
+ exits("usage");
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+ vlong t0, t;
+ Channel *drawc;
+
+ ARGBEGIN{
+ default: usage();
+ }ARGEND;
+ if(argc)
+ usage();
+ if(initdraw(nil, nil, nil) < 0)
+ sysfatal("initdraw: %r");
+ if(memimageinit() < 0)
+ sysfatal("memimageinit: %r");
+ if((mctl = initmouse(nil, screen)) == nil)
+ sysfatal("initmouse: %r");
+ resetfb();
+ bg = rgb(DWhite);
+ fg = rgb(DBlack);
+ drawc = chancreate(1, 0);
+ display->locking = 1;
+ unlockdisplay(display);
+ proccreate(kbdproc, nil, mainstacksize);
+ proccreate(drawproc, drawc, mainstacksize);
+ t0 = nsec();
+ for(;;){
+ enum {MOUSE, RESIZE, DRAW};
+ Alt a[] = {
+ {mctl->c, &mctl->Mouse, CHANRCV},
+ {mctl->resizec, nil, CHANRCV},
+ {drawc, nil, CHANRCV},
+ {nil, nil, CHANEND}
+ };
+ switch(alt(a)){
+ case MOUSE: mouse(); break;
+ case RESIZE: resize(); break;
+ case DRAW: redraw(); break;
+ }
+ t = nsec();
+ Δt = (t-t0)/1e9;
+ t0 = t;
+ }
+}