ref: 434c6ce50a65ecfdfc4e537edbb2ed4f50da6312
parent: d4bb352f8314035b5b5a2130bd7d93e74d9fec4e
author: jmq <jmq@jmq.sh>
date: Wed Dec 4 01:34:26 EST 2024
lots of shit dude i don't remember
--- a/bindings.c
+++ b/bindings.c
@@ -7,6 +7,7 @@
#include "fns.h"
Binding * BindingRoot = nil;
+static Point MoveMark = {0};typedef struct DefaultBinding
{@@ -44,14 +45,21 @@
}
static void
+movecanvas(void)
+{+ CanvasAt = addpt(CanvasAt, subpt(MousePosition, MoveMark));
+ CanvasMoved = DrawAllLayers = 1;
+}
+
+static void
BindingMoveCanvas(int e)
{- print("e = %d\n", e);+ static int movetask = -1;
if (e != BEenter)
return;
-
- CanvasAt = addpt(CanvasAt, subpt(MousePosition, PastMousePosition));
- CanvasMoved = DrawAllLayers = 1;
+ MoveMark = MousePosition;
+ removetask(movetask);
+ movetask = newtask(msec() + 250, movecanvas);
}
DefaultBinding DefaultBindings[] =
--- a/dat.h
+++ b/dat.h
@@ -27,6 +27,12 @@
void (*func)(int);
} Binding;
+typedef struct Task
+{+ ulong start;
+ void (*func)(void);
+} Task;
+
// extern Rectangle CanvasSize = {0}; // extern Point CanvasAt = {0};extern Layer * LayerRoot;
@@ -38,6 +44,7 @@
extern Point CanvasAt;
extern int CanvasMoved;
extern int DrawAllLayers;
+extern ulong LastUpdate;
// extern Layer * CurrentLayer = nil;
// extern Image * Background = nil;
// extern Image * Canvas = nil;
--- a/fns.h
+++ b/fns.h
@@ -2,6 +2,8 @@
#define RECTANGLE(w, h) ((Rectangle){(Point){(0),(0)}, (Point){(w),(h)}})#define NOOP() ((void)(nil))
#define ARRLEN(a) ((sizeof(a))/(sizeof(a[0])))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
ulong msec(void);
void setbackground(ulong col);
@@ -13,6 +15,9 @@
void clearlayer(Layer *);
void setbrushcolor(ulong col);
int resizeimage(Image *, Rectangle, int, Image *, Point);
+int newtask(ulong, void (*)(void));
+int removetask(int);
+void runtasks(void);
Point globaltoscreenpt(Point p);
Point globaltoscreenatcanvaspt(Point p);
--- a/fs.c
+++ b/fs.c
@@ -10,16 +10,27 @@
#include "dat.h"
#include "fns.h"
+#define WALK1NAMEQID(q_, n_) \
+if (strcmp(n_, name) == 0) { \+ *qid = (Qid){q_, 0, QTDIR}; \+ return nil; \
+}
+
+int fillstat(ulong qid, Dir *d);
+
static void fsopen(Req * req);
static void fsread(Req * req);
static void fswrite(Req * req);
static void fswstat(Req * req);
static void fscreate(Req * req);
+static void fsattach(Req * req);
static void fsdestroyfid(Fid * req);
+static void fswalk1(Fid *fid, char *name, Qid *qid);
static void fsstart(Srv * srv);
static void fsdetroyfile(File * f);
-static char srvpath[128] = {0};+static char mntpath[128] = {0};+static void fssrvforker(void (*fn)(void*), void *arg, int flags);
static Srv fs = {.open = fsopen,
@@ -26,33 +37,184 @@
.read = fsread,
.write = fswrite,
.wstat = fswstat,
+ .walk1 = fswalk1,
.create = fscreate,
.destroyfid = fsdestroyfid,
+ .attach = fsattach,
.start = fsstart,
+ .forker = fssrvforker,
};
-static void fsopen(Req * req) {+enum {+ Qdir,
+ Qctl,
+ Qcanvas,
+ Qerrors,
+ Qevent,
+ Qcursor,
+ Qwindow,
+ Qlog,
+ Qlabel,
+ Qbrush,
+};
+
+int
+fillstat(ulong qid, Dir *d)
+{+ static char buf[32];
+
+ nulldir(d);
+ d->type = L'M';
+ d->dev = 1;
+ d->length = 0;
+ d->uid = d->gid = buf;
+ d->muid = "";
+ d->qid = (Qid){qid, drive->nchange, 0};+ d->atime = time(0);
+ d->mtime = drive->changetime;
+
+ switch(qid){+ case Qdir:
+ d->name = "/";
+ d->qid.type = QTDIR;
+ d->mode = DMDIR|0777;
+ break;
+
+ case Qctl:
+ d->name = "ctl";
+ d->mode = 0666;
+ break;
+
+ case Qwa:
+ if(drive->writeok == No ||
+ drive->mmctype != Mmcnone &&
+ drive->mmctype != Mmccd)
+ return 0;
+ d->name = "wa";
+ d->qid.type = QTDIR;
+ d->mode = DMDIR|0777;
+ break;
+
+ case Qwd:
+ if(drive->writeok == No)
+ return 0;
+ d->name = "wd";
+ d->qid.type = QTDIR;
+ d->mode = DMDIR|0777;
+ break;
+
+ default:
+ if(qid-Qtrack >= drive->ntrack)
+ return 0;
+ t = &drive->track[qid-Qtrack];
+ if(strcmp(t->name, "") == 0)
+ return 0;
+ d->name = t->name;
+ d->mode = t->mode;
+ d->length = t->size;
+ break;
+ }
+ return 1;
+}
+
+static void
+fsopen(Req * req) {respond(req, nil);
}
-static void fsread(Req * req) {+
+static void
+fsread(Req * req) {respond(req,nil);
}
-static void fswrite(Req * req) {+
+static void
+fswrite(Req * req) {respond(req,nil);
}
-static void fswstat(Req * req) {+
+static void
+fswstat(Req * req) {respond(req,nil);
}
-static void fscreate(Req * req) {+
+static void
+fscreate(Req * req) {respond(req,nil);
}
-static void fsdestroyfid(Fid * req) {+
+static void
+fswalk1(Fid *fid, char *name, Qid *qid) {+ switch(fid->qid.path) {+ case Qdir:
+ if (strcmp("..", name) == 0) {+ *qid = (Qid){Qdir, 0, QTDIR};+ return nil;
+ }
+ if (strcmp("ctl", name) == 0) {+ *qid = (Qid){Qdir, 0, QTDIR};+ return nil;
+ }
+ if (strcmp("canvas", name) == 0) {+ *qid = (Qid){Qcanvas, 0, QTDIR};+ return nil;
+ }
+ if (strcmp("errors", name) == 0) {+ *qid = (Qid){Qerrors, 0, QTDIR};+ return nil;
+ }
+ if (strcmp("event", name) == 0) {+ *qid = (Qid){Qevent, 0, QTDIR};+ return nil;
+ }
+ if (strcmp("cursor", name) == 0) {+ *qid = (Qid){Qcursor, 0, QTDIR};+ return nil;
+ }
+ if (strcmp("window", name) == 0) {+ *qid = (Qid){Qwindow, 0, QTDIR};+ return nil;
+ }
+ if (strcmp("log", name) == 0) {+ *qid = (Qid){Qlog, 0, QTDIR};+ return nil;
+ }
+ if (strcmp("brush", name) == 0) {+ *qid = (Qid){Qbrush, 0, QTDIR};+ return nil;
+ }
+ return "file not found";
+ default:
+ return "walk in non-directory";
+ }
+}
+
+static void
+fsdestroyfid(Fid * req) {USED(req);
}
-static void fsstart(Srv * srv) {+
+static void
+fsattach(Req * req) {+ char *spec;
+
+ spec = r->ifcall.aname;
+ if(spec && spec[0]){+ respond(r, "invalid attach specifier");
+ return;
+ }
+
+ r->ofcall.qid = (Qid){Qdir, 0, QTDIR};+ r->fid->qid = r->ofcall.qid;
+ respond(r, nil);
+}
+
+static void
+fsstart(Srv * srv) {USED(srv);
}
-static void fsdestroyfile(File * f) {+
+static void
+fsdestroyfile(File * f) {USED(f);
}
@@ -59,28 +221,26 @@
void
fsclose(void)
{- if (srvpath[0] == 0)
- remove(srvpath);
- srvpath[0] = 0;
+ Waitmsg * m;
+ while ((m = wait()) != nil)
+ free(m);
}
+static void
+fssrvforker(void (*fn)(void*), void *arg, int flags)
+{+ srvforker(fn, arg, RFPROC|RFNAMEG|RFNOTEG|RFMEM|flags);
+}
+
int
fsinit(char * srvname)
{- int rc;
-
- fs.tree = alloctree(nil, nil, DMDIR|0755, fsdestroyfile);
if (fs.tree == nil) {return -1;
}
+ snprint(mntpath, sizeof(mntpath), "/mnt/%s", srvname);
+ postmountsrv(&fs, srvname, mntpath, MCREATE|MREPL);
- snprint(srvpath, sizeof(srvpath), "/srv/%s", srvname);
- remove(srvpath);
-
- rc = postsrv(&fs, srvname);
- if (rc == 0) {- exits(nil);
- } else
- return rc;
+ return 1;
}
--- a/main.c
+++ b/main.c
@@ -16,6 +16,8 @@
#define RECTOPPT(r, op) ((Rectangle){op(r.min),op(r.max)})#define DEFAULTCANVASSIZE RECTANGLE(640, 640)
#define STROKEEND Endsquare
+#define TASKLISTSIZE 2
+#define ZOOMAPPLYDELAY 250
int CanvasMoved = 1;
Rectangle CanvasSize;
@@ -24,14 +26,17 @@
Layer * RootLayer = nil;
Layer * CurrentLayer = nil;
Image * Background = nil;
+Image * BorderImage = nil;
Image * ClearImage = nil;
int CurrentKeyboard = 0;
Image * BrushImage = nil;
Image * ViewImage = nil;
Image * ZoomedImage = nil;
+Image * OverlayImage = nil;
ulong LastUpdate = 0;
int DrawAllLayers = 0;
int Zoom = 1;
+int TargetZoom = 1;
int ZoomSensitivity = 1;
Mouse CurrentMouse = {0}; Mouse PastMouse = {0};@@ -38,6 +43,9 @@
Point MousePosition = {0}; Point PastMousePosition = {0};int RunLoop = 1;
+Task TaskList[TASKLISTSIZE] = {0};+int ZoomTaskId = -1;
+int DrawOverlay = 0;
Layer *
newlayer(ulong col)
@@ -102,20 +110,63 @@
if (resizeimage(ZoomedImage, vr, Zoom, ViewImage, ZP) < 0)
sysfatal("resizeimage: %r");}
+
if (CanvasMoved || sr) {draw(screen, screen->r, Background, nil, ZP);
draw(screen, RECTOPPT(ZoomedSize, screentoglobalatcanvaspt), ZoomedImage, nil, ZP);
}
+
+ if (OverlayImage != nil)
+ draw(screen, OverlayImage->r, OverlayImage, nil, ZP);
+
CanvasMoved = 0;
DrawAllLayers = 0;
+ DrawOverlay = 0;
}
ulong
msec(void)
{- return (ulong)(nsec()/1000);
+ return (ulong)(nsec()/1000000);
}
+int newtask(ulong s, void (*f)(void))
+{+ uint i;
+ for (i = 0; i < ARRLEN(TaskList); i++) {+ if (TaskList[i].func != nil)
+ continue;
+
+ TaskList[i] = (Task) { s, f };+ return i;
+ }
+
+ return -1;
+}
+
+int removetask(int id)
+{+ if (id < 0 || id >= ARRLEN(TaskList))
+ return -1;
+ TaskList[id] = (Task) {0, nil};+ return 0;
+}
+
+void runtasks(void)
+{+ Task * t;
+ ulong i;
+
+ for (i = 0; i < ARRLEN(TaskList); i++) {+ t = &TaskList[i];
+ if (t->func == nil || t->start > msec())
+ continue;
+
+ t->func();
+ removetask(i);
+ }
+}
+
void
setbackground(ulong col)
{ @@ -127,38 +178,65 @@
sysfatal("setbackground: %r");}
-void
-zoom(int z)
+static void
+zoomrect(Rectangle * zs, Point * ca, int z)
{int osx, osy;
Point c;
-
- if ((Zoom + z) <= 1)
- Zoom = 1;
- else
- Zoom += z;
c = subpt(CanvasAt, MousePosition);
osx = Dx(ZoomedSize);
osy = Dy(ZoomedSize);
- ZoomedSize.min = mulpt(CanvasSize.min, Zoom);
- ZoomedSize.max = mulpt(CanvasSize.max, Zoom);
-
- if (ZoomedImage != nil) {- freeimage(ZoomedImage);
- ZoomedImage = nil;
- }
+ zs->min = mulpt(CanvasSize.min, z);
+ zs->max = mulpt(CanvasSize.max, z);
- CanvasAt = addpt(
+ *ca = addpt(
Pt(Dx(ZoomedSize)*c.x/osx, Dy(ZoomedSize)*c.y/osy),
MousePosition
);
+}
+static void
+applyzoom(void)
+{+ Zoom = TargetZoom;
+ zoomrect(&ZoomedSize, &CanvasAt, Zoom);
+ if (ZoomedImage != nil) {+ freeimage(ZoomedImage);
+ ZoomedImage = nil;
+ }
+
DrawAllLayers = 1;
+ ZoomTaskId = -1;
}
void
+zoom(int z)
+{+ Rectangle zs;
+ Point ca;
+
+ if ((TargetZoom + z) <= 1)
+ TargetZoom = 1;
+ else
+ TargetZoom += z;
+
+ zoomrect(&zs, &ca, TargetZoom);
+ if (OverlayImage != nil) {+// zs = rectaddpt(zs, ca);
+// border(OverlayImage, zs, 2, BorderImage, ZP);
+ DrawOverlay = 1;
+ }
+
+ removetask(ZoomTaskId);
+ if ((ZoomTaskId = newtask(msec() + ZOOMAPPLYDELAY, applyzoom)) < 0) {+ werrstr("newtask: no tasks available");+ return;
+ }
+}
+
+void
movecanvas()
{}
@@ -283,6 +361,15 @@
}
}
+void
+setoverlaysize(Rectangle r)
+{+ if (OverlayImage != nil)
+ freeimage(OverlayImage);
+ OverlayImage = allocimage(display, r, RGBA32, 1, DTransparent);
+ DrawOverlay = 1;
+}
+
static void
handlekeyboard(int kbdc)
{@@ -311,7 +398,7 @@
void
main(int argc, char * argv[])
{- int d;
+ ulong d;
Event e;
USED(argc);
@@ -320,25 +407,34 @@
if (initdraw(nil, nil, "pain") < 0)
sysfatal("initdraw: %r\n");- if (fsinit("pain") < 1)- sysfatal("fsinit: %r");+// if (fsinit(nil) < 1)
+// sysfatal("fsinit: %r");- if (!atexit(fsclose))
- sysfatal("atexit: %r");-
+// if (!atexit(fsclose))
+// sysfatal("atexit: %r");+
+ if ((BorderImage = allocimage(display, RECTANGLE(1, 1), RGBA32, 1, DBlack)) == nil)
+ sysfatal("allocimage: %r");+
+ setoverlaysize(screen->r);
CanvasSize = ZoomedSize = DEFAULTCANVASSIZE;
setcanvassize(DEFAULTCANVASSIZE);
newlayer(DEFAULTLAYERCOLOR);
- zoom(0);
+ applyzoom();
setdefaultbindings();
einit(Emouse | Ekeyboard);
drawcanvas();
for(;RunLoop;) {- d = msec()-LastUpdate;
- if (d <= UPDATEPERIOD)
- sleep(d - UPDATEPERIOD);
-
+ d = msec();
+ if (d < LastUpdate)
+ LastUpdate = 0;
+
+ d -= LastUpdate;
+ if (d < UPDATEPERIOD)
+ sleep(UPDATEPERIOD - d);
+
+ runtasks();
switch (event(&e))
{case Ekeyboard:
--- a/mkfile
+++ b/mkfile
@@ -3,7 +3,6 @@
TARG=pain
OFILES= \
main.$O \
- fs.$O \
resize.$O \
bindings.$O \
utils.$O
--
⑨