ref: df830dd2a611299eda94cadaf6e2d08a81ec2a59
parent: a959605dff6d7ffffbca9441db4e57b98b261b71
author: spew <spew@palas>
date: Sat Feb 8 00:14:09 EST 2025
start moving the ui stuff into the irc client
--- a/guitest.c
+++ b/guitest.c
@@ -62,18 +62,6 @@
return p;
}
-uint
-lines(Rune *text)
-{
- Rune *e;
- uint l;
-
- e = text;
- for(l = 0; e != nil; l++)
- e = runestrchr(e+1, L'\n');
- return l;
-}
-
#define max(a, b) ((a)>(b)?(a):(b))
#define min(a, b) ((a)<(b)?(a):(b))
@@ -89,13 +77,13 @@
scrpos = t->scrollr;
if(t->nlines > 0){
- scrpos.min.y = scrpos.min.y+max(0, Dy(scrpos))*t->origin/t->nlines;
+ scrpos.min.y = scrpos.min.y+max(0, Dy(scrpos))*t->topline/t->nlines;
scrpos.max.y = scrpos.min.y+Dy(t->scrollr)*t->Frame.maxlines/t->nlines;
}
scrpos = insetrect(scrpos, 1);
draw(screen, scrpos, t->cols[BACK], nil, ZP);
- frinsert(t, t->text+t->lines[t->origin], t->text+t->textlen, 0);
+ frinsert(t, t->text+t->lines[t->topline], t->text+t->textlen, 0);
flushimage(display, 1);
}
@@ -122,7 +110,7 @@
t->linescap = 1024;
t->lines = emallocz(t->linescap*sizeof(*t->lines), 1);
t->nlines = 0;
- t->origin = 0;
+ t->topline = 0;
}
frclear(t, 0);
@@ -156,7 +144,7 @@
}
void
-textsetline(Text *t, uint sol)
+textaddline(Text *t, uint sol)
{
if(t->nlines == t->linescap){
t->linescap *= 2;
@@ -166,10 +154,9 @@
}
void
-textaddlines(Text *t, Rune *s)
+textaddrunes(Text *t, Rune *s)
{
Rune *rp;
- uint sol;
int len;
len = runestrlen(s);
@@ -178,11 +165,8 @@
t->text = erealloc(t->text, t->textcap*sizeof(*t->text));
}
runestrecpy(t->text+t->textlen, t->text+t->textcap, s);
- sol = t->textlen;
- for(rp = s; rp = runestrchr(rp, L'\n'); rp++){
- textsetline(t, sol);
- sol = rp + 1 - s + t->textlen;
- }
+ for(rp = t->text+t->textlen; *rp != L'\0'; rp++)
+ if(*rp == L'\n') textaddline(t, rp+1-t->text);
t->textlen += len;
}
@@ -201,24 +185,28 @@
void
textscroll(Text *t, Mousectl *mc)
{
- uint pos, i, diff;
+ uint pos, i;
while(mc->buttons == 2){
- t->origin = min(max(0, mc->xy.y-t->scrollr.min.y)*t->nlines/Dy(t->scrollr), t->nlines-1);
+ t->topline = min(max(0, mc->xy.y-t->scrollr.min.y)*t->nlines/Dy(t->scrollr), t->nlines-1);
textdraw(t);
readmouse(mc);
}
while(mc->buttons == 1){
pos = frcharofpt(t, (Point){t->bodyr.min.x+1, mc->xy.y});
- for(i = t->origin; t->lines[t->origin]+pos > t->lines[i]; i++);
- t->origin -= i-t->origin;
+ for(i = t->topline; t->lines[t->topline]+pos > t->lines[i]; i++){
+ if(i == t->nlines) break;
+ }
+ i -= t->topline;
+ if(t->topline < i) t->topline = 0;
+ else t->topline -= i;
textdraw(t);
readmouse(mc);
}
while(mc->buttons == 4){
pos = frcharofpt(t, (Point){t->bodyr.min.x+1, mc->xy.y});
- for(i = t->origin; t->lines[t->origin]+pos > t->lines[i]; i++);
- t->origin = min(i, t->nlines-1);
+ for(i = t->topline; t->lines[t->topline]+pos > t->lines[i]; i++);
+ t->topline = min(i, t->nlines-1);
textdraw(t);
readmouse(mc);
}
@@ -299,7 +287,7 @@
chan->body._screen = &_screen;
chan->body.wsys = "/dev";
textinit(&chan->body);
- textaddlines(&chan->body, lorem);
+ textaddrunes(&chan->body, lorem);
lorem[0] = L'\0';
if(nicksf != nil){
@@ -324,7 +312,7 @@
chan->nicks._screen = &_nicksscreen;
chan->nicks.wsys = nickswsys;
textinit(&chan->nicks);
- textaddlines(&chan->nicks, lorem);
+ textaddrunes(&chan->nicks, lorem);
cmd = emallocz(sizeof(*cmd), 1);
dim = (Rectangle){
--- a/mez.c
+++ b/mez.c
@@ -9,10 +9,27 @@
#include <frame.h>
#include "mez.h"
+Image *nicksscreen, *cmdscreen, *nickscols[NCOL], *cols[NCOL], *cmdcols[NCOL];
+char *nickswsys = "/mnt/nickswsys", *cmdwsys = "/mnt/cmdwsys";
+Screen *_nicksscreen, *_cmdscreen;
+
+enum {
+ MOUSE,
+ KEYBD,
+ RESIZE,
+ NICKSMOUSE,
+ NICKSKEYBD,
+ NICKSRESIZE,
+ CMDMOUSE,
+ CMDKEYBD,
+ CMDRESIZE,
+ NCHAN,
+};
+
void
usage(void)
{
- fprint(2, "usage: %s [-u user] host\n", argv0);
+ fprint(2, "usage: %s [-u user] host netid\n", argv0);
threadexits("usage");
}
@@ -34,86 +51,96 @@
return p;
}
+void*
+erealloc(void *ptr, ulong size)
+{
+ void *p;
+
+ if((p = realloc(ptr, size)) == nil)
+ error("Out of memory there");
+ setmalloctag(p, getcallerpc(&ptr));
+ return p;
+}
+
void
-vwmsg(int fd, char *fmt, va_list v)
+vwmsg(Net *n, char *fmt, va_list v)
{
- static char buf[8192];
char *e;
- e = vseprint(buf, buf+sizeof(buf), fmt, v);
+ e = vseprint(n->buf, n->buf+sizeof(n->buf), fmt, v);
va_end(v);
*e++ = '\r';
*e++ = '\n';
- write(fd, buf, e-buf);
+ write(n->fd, n->buf, e-n->buf);
}
void
-wmsg(int fd, char *fmt, ...)
+wmsg(Net *n, char *fmt, ...)
{
va_list v;
va_start(v, fmt);
- vwmsg(fd, fmt, v);
+ vwmsg(n, fmt, v);
}
char*
-rmsg(int fd)
+rmsg(Net *n)
{
int bytes;
- static char buf[8192];
- bytes = read(fd, buf, sizeof(buf));
- buf[bytes] = '\0';
- return buf;
+ bytes = read(n->fd, n->buf, sizeof(n->buf));
+ n->buf[bytes-2] = '\n';
+ n->buf[bytes-1] = '\0';
+ return n->buf;
}
char*
-wrmsg(int fd, char *fmt, ...)
+wrmsg(Net *n, char *fmt, ...)
{
va_list v;
va_start(v, fmt);
- vwmsg(fd, fmt, v);
- return rmsg(fd);
+ vwmsg(n, fmt, v);
+ return rmsg(n);
}
-int
+Net*
connect(App *a, int netid)
{
- int fd, bytes;
+ Net *n;
+ int bytes;
char b64[512];
uchar buf[512];
TLSconn *conn;
- fd = dial(netmkaddr(a->host, "tcp", "6697"), nil, nil, nil);
- if(fd == -1)
+ n = emallocz(sizeof(*n), 1);
+ n->id = netid;
+ n->fd = dial(netmkaddr(a->host, "tcp", "6697"), nil, nil, nil);
+ if(n->fd == -1)
error("Could not connect");
conn = emallocz(sizeof(*conn), 1);
- fd = tlsClient(fd, conn);
+ n->fd = tlsClient(n->fd, conn);
free(conn);
- if(fd == -1)
+ if(n->fd == -1)
error("Could not negotiate tls connection");
- wmsg(fd, "CAP LS 302");
- wmsg(fd, "NICK %s", a->user);
- print(wrmsg(fd, "USER %s 0 * %s", a->user, a->user));
-
- print(wrmsg(fd, "CAP REQ :sasl"));
-
- print(wrmsg(fd, "AUTHENTICATE PLAIN\r\n"));
-
+ wmsg(n, "CAP LS 302");
+ wmsg(n, "NICK %s", a->user);
+ print(wrmsg(n, "USER %s 0 * %s", a->user, a->user));
+ print(wrmsg(n, "CAP REQ :sasl"));
+ print(wrmsg(n, "AUTHENTICATE PLAIN\r\n"));
bytes = snprint((char*)buf, sizeof(buf), "%c%s%c%s", '\0', a->user, '\0', a->passwd);
enc64(b64, sizeof(b64), buf, bytes);
- print(wrmsg(fd, "AUTHENTICATE %s\r\n", b64));
+ print(wrmsg(n, "AUTHENTICATE %s\r\n", b64));
- if(netid < 0){
- wmsg(fd, "CAP END");
- wmsg(fd, "BOUNCER LISTNETWORKS");
- return fd;
+ if(n->id < 0){
+ wmsg(n, "CAP END");
+ wmsg(n, "BOUNCER LISTNETWORKS");
+ return n;
}
- wmsg(fd, "BOUNCER BIND %d", netid);
- wmsg(fd, "CAP END");
- return fd;
+ wmsg(n, "BOUNCER BIND %d", netid);
+ wmsg(n, "CAP END");
+ return n;
}
void
@@ -124,9 +151,9 @@
net = a;
for(;;){
- in = rmsg(net->fd);
+ in = rmsg(net);
if(strcmp(in, "PING") == 0){
- wmsg(net->fd, "PONG%s", in+4);
+ wmsg(net, "PONG%s", in+4);
continue;
}
}
@@ -133,11 +160,38 @@
}
void
+createwindow(char *wsys, Image **screen, Screen **_screen, Rectangle r)
+{
+ static char s[512];
+ char *wsysv;
+ int fd;
+
+ if((wsysv = getenv("wsys")) == nil)
+ sysfatal("cannot find $wsys: %r");
+ if((fd = open(wsysv, ORDWR)) < 0)
+ sysfatal("cannot open $wsys: %r");
+ free(wsysv);
+ snprint(s, sizeof(s), "new -r %d %d %d %d", r.min.x, r.min.y, r.max.x, r.max.y);
+ if(mount(fd, -1, wsys, MREPL, s) < 0)
+ sysfatal("cannot create new window: %r");
+ close(fd);
+ snprint(s, sizeof(s), "%s/label", wsys);
+ if((fd = open(s, OWRITE)) < 0)
+ sysfatal("cannot open label: %r");
+ write(fd, "guitest", sizeof("guitest"));
+ close(fd);
+ snprint(s, sizeof(s), "%s/winname", wsys);
+ if(gengetwindow(display, s, screen, _screen, Refnone) < 0)
+ sysfatal("cannot get window: %r");
+}
+
+void
threadmain(int argc, char **argv)
{
App app;
UserPasswd *up;
- int fd;
+ Net *n;
+ int netid;
app.user = getenv("user");
ARGBEGIN{
@@ -147,18 +201,20 @@
app.user = EARGF(usage());
break;
}ARGEND
- if (argc != 1)
+ if (argc != 2)
usage();
app.host = argv[0];
+ netid = strtol(argv[1], nil, 0);
up = auth_getuserpasswd(auth_getkey, "proto=pass server=%s service=irc user=%s", app.host, app.user);
if(up == nil)
error("could not get a password");
app.passwd = up->passwd;
- fd = connect(&app, 3);
+ n = connect(&app, netid);
for(int i = 0; i < 10000; i++){
- print(rmsg(fd));
+ print(rmsg(n));
}
free(up);
- close(fd);
+ close(n->fd);
+ free(n);
threadexits(0);
}
--- a/mez.h
+++ b/mez.h
@@ -12,7 +12,7 @@
struct Text {
Frame;
Rune *text;
- uint textlen, origin, nlines, linescap, textcap, *lines;
+ uint textlen, topline, nlines, linescap, textcap, *lines;
Rectangle scrollr, bodyr;
Image **screen, *cols[NCOL];
Screen **_screen;
@@ -29,5 +29,9 @@
char *name, *host, *state, *nick, *user, *real;
Chan *channels;
int fd, id;
- char buf[1024];
+ char buf[8192];
};
+
+void error(char*);
+void *emallocz(ulong sz, int clr);
+void *erealloc(void *ptr, ulong size);
\ No newline at end of file
--- a/mkfile
+++ b/mkfile
@@ -1,9 +1,8 @@
</$objtype/mkfile
-TARG=mez guitest
+TARG=mez
BIN=/$objtype/bin
+OFILES=mez.$O text.$O
+HFILES=mez.h
-HFILES=\
- mez.h
-
-</sys/src/cmd/mkmany
+</sys/src/cmd/mkone
--- /dev/null
+++ b/text.c
@@ -1,0 +1,146 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <thread.h>
+#include <mouse.h>
+#include <frame.h>
+#include "mez.h"
+
+enum {
+ Scrollwid = 12, /* width of scroll bar */
+ Scrollgap = 4, /* gap right of scroll bar */
+ Margin = 4, /* margin around text */
+};
+
+#define max(a, b) ((a)>(b)?(a):(b))
+#define min(a, b) ((a)<(b)?(a):(b))
+
+void
+textdraw(Text *t)
+{
+ Rectangle scrpos;
+ Image *screen;
+
+ screen = *t->screen;
+ draw(screen, screen->r, t->cols[BACK], nil, ZP);
+ draw(screen, t->scrollr, t->cols[BORD], nil, ZP);
+
+ scrpos = t->scrollr;
+ if(t->nlines > 0){
+ scrpos.min.y = scrpos.min.y+max(0, Dy(scrpos))*t->topline/t->nlines;
+ scrpos.max.y = scrpos.min.y+Dy(t->scrollr)*t->Frame.maxlines/t->nlines;
+ }
+ scrpos = insetrect(scrpos, 1);
+ draw(screen, scrpos, t->cols[BACK], nil, ZP);
+
+ frinsert(t, t->text+t->lines[t->topline], t->text+t->textlen, 0);
+ flushimage(display, 1);
+}
+
+void
+textinit(Text *t)
+{
+ Image *screen;
+
+ screen = *t->screen;
+ t->scrollr = screen->r;
+ t->scrollr.max.x = screen->r.min.x + Scrollwid + 1;
+
+ t->bodyr.min.x = screen->r.min.x + Scrollwid + Scrollgap + Margin;
+ t->bodyr.min.y = screen->r.min.y;
+ t->bodyr.max = screen->r.max;
+
+ if(t->text == nil){
+ t->textcap = 8192;
+ t->text = emallocz(t->textcap*sizeof(*t->text), 1);
+ t->textlen = 0;
+ }
+
+ if(t->lines == nil){
+ t->linescap = 1024;
+ t->lines = emallocz(t->linescap*sizeof(*t->lines), 1);
+ t->nlines = 0;
+ t->topline = 0;
+ }
+
+ frclear(t, 0);
+ frinit(t, t->bodyr, display->defaultfont, screen, t->cols);
+}
+
+void
+textaddline(Text *t, uint sol)
+{
+ if(t->nlines == t->linescap){
+ t->linescap *= 2;
+ t->lines = erealloc(t->lines, t->linescap*sizeof(*t->lines));
+ }
+ t->lines[t->nlines++] = sol;
+}
+
+void
+textaddrunes(Text *t, Rune *s)
+{
+ Rune *rp;
+ int len;
+
+ len = runestrlen(s);
+ while(len > t->textcap-t->textlen+1){
+ t->textcap *= 2;
+ t->text = erealloc(t->text, t->textcap*sizeof(*t->text));
+ }
+ runestrecpy(t->text+t->textlen, t->text+t->textcap, s);
+ for(rp = t->text+t->textlen; *rp != L'\0'; rp++)
+ if(*rp == L'\n') textaddline(t, rp+1-t->text);
+ t->textlen += len;
+}
+
+void
+textresize(Text *t)
+{
+ static char s[512];
+
+ snprint(s, sizeof(s), "%s/winname", t->wsys);
+ if(gengetwindow(display, s, t->screen, t->_screen, Refnone) < 0)
+ sysfatal("%s: %r", argv0);
+ textinit(t);
+ textdraw(t);
+}
+
+void
+textscroll(Text *t, Mousectl *mc)
+{
+ uint pos, i;
+
+ while(mc->buttons == 2){
+ t->topline = min(max(0, mc->xy.y-t->scrollr.min.y)*t->nlines/Dy(t->scrollr), t->nlines-1);
+ textdraw(t);
+ readmouse(mc);
+ }
+ while(mc->buttons == 1){
+ pos = frcharofpt(t, (Point){t->bodyr.min.x+1, mc->xy.y});
+ for(i = t->topline; t->lines[t->topline]+pos > t->lines[i]; i++){
+ if(i == t->nlines) break;
+ }
+ i -= t->topline;
+ if(t->topline < i) t->topline = 0;
+ else t->topline -= i;
+ textdraw(t);
+ readmouse(mc);
+ }
+ while(mc->buttons == 4){
+ pos = frcharofpt(t, (Point){t->bodyr.min.x+1, mc->xy.y});
+ for(i = t->topline; t->lines[t->topline]+pos > t->lines[i]; i++);
+ t->topline = min(i, t->nlines-1);
+ textdraw(t);
+ readmouse(mc);
+ }
+}
+
+void
+textmouse(Text *t, Mousectl *mc)
+{
+ if(ptinrect(mc->xy, t->scrollr)){
+ textscroll(t, mc);
+ return;
+ }
+}