ref: 1527811f3015c04a1d84528d6eb7fb50575a57e2
parent: c8dfc9e70b9e9df578e0c1213b04ae31d5c28c08
author: jmq <jmq@jmq.sh>
date: Sat Jan 18 22:21:26 EST 2025
I donnu man I haven't work on this in months
--- a/fns.h
+++ b/fns.h
@@ -17,9 +17,6 @@
void clearview(void);
void setbrushcolor(ulong col);
int resizeimage(Image *, Rectangle, float, Image *, Point);
-int newtask(ulong, void (*)(void));
-int removetask(int);
-void runtasks(void);
int newlayerimage(Layer *);
void centercanvas(void);
Layer * newlayer(void);
@@ -49,3 +46,6 @@
// utils
void quitloop(void);
+int newtask(ulong, void (*)(void));
+int removetask(int);
+void runtasks(void);
--- a/fs.c
+++ b/fs.c
@@ -1,246 +1,159 @@
#include <u.h>
#include <libc.h>
-#include <auth.h>
#include <fcall.h>
#include <thread.h>
-#include <9p.h>
#include <draw.h>
-#include <mouse.h>
+#include <9p.h>
#include "dat.h"
#include "fns.h"
-#define WALK1NAMEQID(q_, n_) \
-if (strcmp(n_, name) == 0) { \- *qid = (Qid){q_, 0, QTDIR}; \- return nil; \
-}
+static void fsstart(Srv *);
+static void fsend(Srv *);
+static void fswrite(Req *);
+static void fsread(Req *);
-int fillstat(ulong qid, Dir *d);
+static char * canvasread(Req *);
+static char * canvaswrite(Req *);
+static int FsPID = -1;
-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);
+typedef struct FileEntry {+ char * name;
+ char * (*read) (Req *);
+ char * (*write) (Req *);
+ int mode;
+} FileEntry;
-static char mntpath[128] = {0};-static void fssrvforker(void (*fn)(void*), void *arg, int flags);
-
-static Srv fs = {- .open = fsopen,
- .read = fsread,
- .write = fswrite,
- .wstat = fswstat,
- .walk1 = fswalk1,
- .create = fscreate,
- .destroyfid = fsdestroyfid,
- .attach = fsattach,
- .start = fsstart,
- .forker = fssrvforker,
+FileEntry entries[] = {+ {"canvas", canvasread, canvaswrite, 0666 }};
+static Image * CanvasReadImage = nil;
+static long CanvasReadReady = 0;
+static char * FsName = nil;
-enum {- Qdir,
- Qctl,
- Qcanvas,
- Qerrors,
- Qevent,
- Qcursor,
- Qwindow,
- Qlog,
- Qlabel,
- Qbrush,
+Srv s = {+ .start = fsstart,
+ .end = fsend,
+ .read = fsread,
+ .write = fswrite,
};
-int
-fillstat(ulong qid, Dir *d)
+static void
+fsstart(Srv *)
{- static char buf[32];
+ File * r, * t;
+ char * u;
+ int i;
- 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;
+ u = getuser();
+ if ((s.tree = alloctree(u, u, 0555, nil)) == nil)
+ sysfatal("alloctree: %r");- 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;
+ r = s.tree->root;
+ if ((t = createfile(r, FsName, u, DMDIR | 0555, nil)) == nil)
+ sysfatal("createfile: %r");+
+ for (i = 0; i < ARRLEN(entries); i++)
+ if (createfile(t, entries[i].name, u, entries[i].mode, &entries[i]) == nil)
+ sysfatal("createfile: %r");+ FsPID = getpid();
}
static void
-fsopen(Req * req) {- respond(req, nil);
+fsend(Srv *)
+{+ exits(nil);
}
static void
-fsread(Req * req) {- respond(req,nil);
+fsread(Req * r)
+{+ FileEntry * e;
+ r->ofcall.count = 0;
+ e = r->fid->file->aux;
+ respond(r, e->read(r));
}
static void
-fswrite(Req * req) {- respond(req,nil);
+fswrite(Req * r)
+{+ FileEntry * e;
+ e = r->fid->file->aux;
+ respond(r, e->write(r));
}
static void
-fswstat(Req * req) {- respond(req,nil);
+canvasreadtask(void)
+{+ if (CanvasReadImage != nil)
+ freeimage(CanvasReadImage);
+
+ if ((CanvasReadImage = allocimage(display, ViewImage->r, ViewImage->chan, ViewImage->repl, DTransparent)) == nil) {+ semrelease(&CanvasReadReady, 1);
+ return;
+ }
+
+ draw(CanvasReadImage, CanvasReadImage->r, ViewImage, nil, ZP);
+ semrelease(&CanvasReadReady, 1);
}
-static void
-fscreate(Req * req) {- respond(req,nil);
-}
+static char *
+canvasread(Req * r)
+{+ uchar * b;
+ int n;
+ char hdr[11+5*12+1], cbuf[20];;
-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";
+ if (newtask(0, canvasreadtask) < 0)
+ return "failed to allocated canvas read task";
+ if (tsemacquire(&CanvasReadReady, 1000) < 0)
+ return "canvas read timed out";
+
+ if (CanvasReadImage == nil) {+ return "no view image";
}
-}
-static void
-fsdestroyfid(Fid * req) {- USED(req);
-}
-
-static void
-fsattach(Req * req) {- char *spec;
-
- spec = r->ifcall.aname;
- if(spec && spec[0]){- respond(r, "invalid attach specifier");
- return;
+ sprint(hdr, "%11s %11d %11d %11d %11d ",
+ chantostr(cbuf, CanvasReadImage->chan),
+ CanvasReadImage->r.min.x,
+ CanvasReadImage->r.min.y,
+ CanvasReadImage->r.max.x,
+ CanvasReadImage->r.max.y
+ );
+
+ n = bytesperline(CanvasReadImage->r, CanvasReadImage->depth) * Dy(CanvasReadImage->r);
+ b = emalloc9p(n + sizeof(hdr));
+ memcpy(b, hdr, sizeof(hdr));
+ b += sizeof(hdr);
+ if (b != nil) {+ unloadimage(CanvasReadImage, CanvasReadImage->r, b, n);
+ b -= sizeof(hdr);
+ readbuf(r, b, n + sizeof(hdr));
+ free(b);
}
- r->ofcall.qid = (Qid){Qdir, 0, QTDIR};- r->fid->qid = r->ofcall.qid;
- respond(r, nil);
+ return nil;
}
-static void
-fsstart(Srv * srv) {- USED(srv);
+static char *
+canvaswrite(Req *)
+{+ return nil;
}
-static void
-fsdestroyfile(File * f) {- USED(f);
+int
+fsinit(char * name)
+{+ FsName = name;
+ postmountsrv(&s, name, "/n", MBEFORE);
+ return 1;
}
void
fsclose(void)
{- Waitmsg * m;
- while ((m = wait()) != nil)
- free(m);
-}
+ if (FsPID < 0)
+ return;
-static void
-fssrvforker(void (*fn)(void*), void *arg, int flags)
-{- srvforker(fn, arg, RFPROC|RFNAMEG|RFNOTEG|RFMEM|flags);
+ postnote(PNGROUP, FsPID, "shutdown");
}
-
-int
-fsinit(char * srvname)
-{- if (fs.tree == nil) {- return -1;
- }
- snprint(mntpath, sizeof(mntpath), "/mnt/%s", srvname);
- postmountsrv(&fs, srvname, mntpath, MCREATE|MREPL);
-
- return 1;
-}
-
--- a/main.c
+++ b/main.c
@@ -17,7 +17,6 @@
#define RECTOPPT(r, op) ((Rectangle){op(r.min),op(r.max)})#define DEFAULTCANVASSIZE RECTANGLE(1920, 1080)
#define STROKEEND Endsquare
-#define TASKLISTSIZE 2
#define NOTIFICATIONFONTCOLOR DBlack
#define NOTIFICATIONBACKGROUNDCOLOR 0x72DEC2FF
#define ZOOMAPPLYDELAY (1000/6)
@@ -49,7 +48,6 @@
Point MousePosition = {0}; Point PastMousePosition = {0};int RunLoop = 1;
-Task TaskList[TASKLISTSIZE] = {0};int ZoomTaskId = -1;
uint LayerIDCounter = 0;
@@ -177,10 +175,14 @@
i = rectclip(&vr,Rect(0, 0, Dx(screen->r), Dy(screen->r)));
if (i && ((CanvasMoved && Ar(vr) != Ar(ZoomedSize)) || sr)) {p = CanvasAt;
- if (p.x < 0)
+ if (p.x < 0) {+ vr.max.x += -p.x;
p.x = 0;
- if (p.y < 0)
+ }
+ if (p.y < 0) {+ vr.max.y += -p.y;
p.y = 0;
+ }
vr = rectsubpt(vr, p);
if (resizeimage(ZoomedImage, vr, Zoom, ViewImage, ZP) < 0)
sysfatal("resizeimage: %r");@@ -201,43 +203,6 @@
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)
{ @@ -280,7 +245,6 @@
DrawAllLayers = 1;
ZoomTaskId = -1;
- ntfprint("zoom set to %f", Zoom);}
void
@@ -304,6 +268,7 @@
werrstr("newtask: no tasks available");return;
}
+ ntfprint("zoom set to %f", TargetZoom);}
void
@@ -334,10 +299,10 @@
line(l->image, addpt(f, l->offset), addpt(t, l->offset), STROKEEND, STROKEEND, 1, BrushImage, ZP);
// Draw on the zoomed image
- f = mulpt(f, Zoom);
- t = mulpt(t, Zoom);
+ f = mulptf(f, Zoom);
+ t = mulptf(t, Zoom);
if (ZoomedImage != nil)
- line(ZoomedImage, addpt(f, l->offset), addpt(t, l->offset), STROKEEND, STROKEEND, 1*Zoom, BrushImage, ZP);
+ line(ZoomedImage, addpt(f, l->offset), addpt(t, l->offset), STROKEEND, STROKEEND, Zoom, BrushImage, ZP);
// Draw on the screen
f = screentoglobalatcanvaspt(f);
@@ -473,6 +438,12 @@
CanvasAt = subpt(CanvasAt, Pt((Dx(ZoomedSize)/2), (Dy(ZoomedSize)/2)));
}
+static void
+cleannup(void)
+{+ fsclose();
+}
+
void
main(int argc, char * argv[])
{@@ -485,11 +456,11 @@
if (initdraw(nil, nil, "pain") < 0)
sysfatal("initdraw: %r\n");-// if (fsinit(nil) < 1)
-// sysfatal("fsinit: %r");+ if (fsinit("pain") < 1)+ sysfatal("fsinit: %r");-// if (!atexit(fsclose))
-// sysfatal("atexit: %r");+ if (!atexit(cleannup))
+ sysfatal("atexit: %r");if ((BorderImage = allocimage(display, RECTANGLE(1, 1), RGBA32, 1, DBlack)) == nil)
sysfatal("allocimage: %r");--- a/mkfile
+++ b/mkfile
@@ -5,7 +5,8 @@
main.$O \
resize.$O \
bindings.$O \
- utils.$O
+ utils.$O \
+ fs.$O
HFILES=fns.h dat.h
BIN=$home/bin/$objtype
--- a/resize.c
+++ b/resize.c
@@ -57,12 +57,8 @@
// the temporary image
r.min = tr.min;
r.max.y = tr.max.y;
- r.max.x = r.min.x + MAX(1.0, scale); // It wouldn't make much sense to have
- // a horizontal width of less than 1
- i = r.max.x - r.min.x;
- d = p.x;
- f = r.min.x;
+ i = 0;
// Scan the source image with a vertical cursor image and apply it to the
// temporary image. We want to do this until we try to scan outside the
// source image, or we try to write outside of the target image.
@@ -72,17 +68,16 @@
// image, for every line on the target image will we will skip over multiple
// lines on the source image.
- // Move the ci one 1/scale space to the right
+ // Move the ci one 1/scale space to the righ
draw(ci, ci->r, si, nil, p);
- d += MAX(1/scale, 1);
- p.x = d;
+ p.x += 1;
// Move the draw rectangle for the temporary image scale
// rectangles to the right
+ r.min.x = (int)(((float)(i))*scale) + tr.min.x;
+ r.max.x = (int)(((float)(i+1))*scale) + tr.min.x;
draw(t, r, ci, nil, ZP);
- f += MAX(scale, 1);
- r.min.x = f;
- r.max.x = r.min.x + i;
+ i+=1;
}
freeimage(ci);
@@ -101,7 +96,7 @@
return -1;
}
- // Location of the cursor relative to the source image's sp
+ // Location of the cursor relative to the source image's s
p.x = (int)(((float)dr.min.x)/scale);
p.y = (int)(((float)dr.min.y)/scale);
p = addpt(p, sp);
@@ -112,7 +107,7 @@
r.max.x = tr.max.x;
r.max.y = r.min.y + MAX(1.0, scale);
- i = r.max.y - r.min.y;
+ i = 0;
d = p.y;
f = r.min.y;
while (r.min.y < dr.max.y) {@@ -123,15 +118,14 @@
// Move the ci one 1/scale space to the right
draw(ci, ci->r, t, nil, p);
- d += MAX(1/scale, 1);
- p.y = d;
+ p.y += 1;
// Move the draw rectangle for the temporary image scale
// rectangles to the right
+ r.min.y = (int)(((float)(i))*scale) + dr.min.x;
+ r.max.y = (int)(((float)(i+1))*scale) + dr.min.x;
draw(di, r, ci, nil, ZP);
- f += MAX(scale, 1);
- r.min.y = f;
- r.max.y = r.min.y + i;
+ i+=1;
}
freeimage(t);
--- a/utils.c
+++ b/utils.c
@@ -5,6 +5,58 @@
#include "dat.h"
#include "fns.h"
+#define TASKLISTSIZE 10
+
+QLock TaskLock;
+Task TaskList[TASKLISTSIZE] = {0};+
+int newtask(ulong s, void (*f)(void))
+{+ uint i;
+
+ qlock(&TaskLock);
+ for (i = 0; i < ARRLEN(TaskList); i++) {+ if (TaskList[i].func != nil)
+ continue;
+
+ TaskList[i] = (Task) { s, f };+ break;
+ }
+ qunlock(&TaskLock);
+
+ return i >= ARRLEN(TaskList) ? -1 : i;
+}
+
+int removetask(int id)
+{+ if (id < 0 || id >= ARRLEN(TaskList))
+ return -1;
+ qlock(&TaskLock);
+ TaskList[id] = (Task) {0, nil};+ qunlock(&TaskLock);
+ return 0;
+}
+
+void runtasks(void)
+{+ Task * t;
+ Task tl[ARRLEN(TaskList)];
+ ulong i;
+
+ qlock(&TaskLock);
+ memcpy(tl, TaskList, sizeof(TaskList));
+ qunlock(&TaskLock);
+
+ for (i = 0; i < ARRLEN(tl); i++) {+ t = &tl[i];
+ if (t->func == nil || t->start > msec())
+ continue;
+
+ t->func();
+ removetask(i);
+ }
+}
+
void
quitloop(void)
{@@ -18,3 +70,4 @@
p.y = (int)(((float)p.y) * f);
return p;
}
+
--
⑨