summaryrefslogtreecommitdiff
path: root/sys/src/cmd/bitsy/prompter.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/bitsy/prompter.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/bitsy/prompter.c')
-rwxr-xr-xsys/src/cmd/bitsy/prompter.c303
1 files changed, 303 insertions, 0 deletions
diff --git a/sys/src/cmd/bitsy/prompter.c b/sys/src/cmd/bitsy/prompter.c
new file mode 100755
index 000000000..9a76a0d0e
--- /dev/null
+++ b/sys/src/cmd/bitsy/prompter.c
@@ -0,0 +1,303 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <draw.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include <control.h>
+
+int Nline;
+
+enum{
+ Back,
+ Shade,
+ Light,
+ Mask,
+ Ncol
+};
+
+enum {
+ Keyback = 0xeeee9eff,
+ Keyshade = 0xaaaa55ff,
+ Keylight = DWhite,
+ Keymask = 0x0C0C0C0C,
+};
+
+Image *cols[Ncol];
+
+int nline;
+
+char *lines[24]; /* plus one so last line gets terminated by getfields */
+Control *entry[24];
+Control *kbd;
+Control *scrib;
+Controlset *keyboard;
+Controlset *text;
+int kbdy;
+
+int resizeready;
+
+int ctldeletequits = 1;
+
+Channel *eventchan;
+
+void
+resizecontrolset(Controlset *cs)
+{
+ int i;
+ Rectangle r, r1;
+
+ if(cs != keyboard)
+ return;
+ if (!resizeready)
+ return;
+ if(getwindow(display, Refnone) < 0)
+ ctlerror("resize failed: %r");
+ draw(screen, screen->r, cols[Back], nil, ZP);
+ r = insetrect(screen->r, 4);
+ for(i=0; i<Nline; i++){
+ r.max.y = r.min.y + font->height;
+ ctlprint(entry[i], "rect %R", r);
+ ctlprint(entry[i], "show");
+ r.min.y = r.max.y;
+ }
+ kbdy = r.min.y;
+
+ r = screen->r;
+ r.min.y = kbdy;
+ r.max.y = screen->r.max.y;
+ r.min.y = r.max.y - 2*2 - 5*13;
+ if(r.min.y >= r.max.y)
+ r.min.y = r.max.y;
+ r1 = r;
+ if(scrib)
+ r.max.x = (3*r.max.x + r.min.x)/4;
+ ctlprint(kbd, "rect %R", r);
+ ctlprint(kbd, "show");
+ if(scrib){
+ r1.min.x = (3*r1.max.x + r1.min.x)/4;
+ ctlprint(scrib, "rect %R", r1);
+ ctlprint(scrib, "show");
+ }
+}
+
+void
+readall(char *s)
+{
+ char *buf;
+ int fd;
+ Dir *d;
+
+ fd = open(s, OREAD);
+ if(fd < 0){
+ fprint(2, "prompter: can't open %s: %r\n", s);
+ exits("open");
+ }
+ d = dirfstat(fd);
+ if(d == nil){
+ fprint(2, "prompter: can't stat %s: %r\n", s);
+ exits("stat");
+ }
+ buf = ctlmalloc(d->length+1); /* +1 for NUL on end */
+ if(read(fd, buf, d->length) != d->length){
+ fprint(2, "prompter: can't read %s: %r\n", s);
+ exits("stat");
+ }
+ nline = getfields(buf, lines, nelem(lines), 0, "\n");
+ free(d);
+ close(fd);
+}
+
+void
+mousemux(void *v)
+{
+ Mouse m;
+ Channel *c;
+
+ c = v;
+
+ for(;;){
+ if(recv(c, &m) < 0)
+ break;
+ if(m.buttons & 0x20) {
+ sendp(eventchan, "mouse: exit");
+ break;
+ }
+ if(m.xy.y >= kbdy)
+ send(keyboard->mousec, &m);
+ else
+ send(text->mousec, &m);
+ }
+}
+
+void
+resizemux(void *v)
+{
+ Channel *c;
+
+ c = v;
+
+ for(;;){
+ if(recv(c, nil) < 0)
+ break;
+ send(keyboard->resizec, nil);
+ send(text->resizec, nil);
+ }
+}
+
+void
+writeall(char *s)
+{
+ int fd;
+ int i, n;
+
+ fd = create(s, OWRITE, 0666);
+ if(fd < 0){
+ fprint(2, "prompter: can't create %s: %r\n", s);
+ exits("open");
+ }
+
+ for(n=Nline; --n>=0; )
+ if(lines[n][0] != '\0')
+ break;
+
+ for(i=0; i<=n; i++)
+ fprint(fd, "%s\n", lines[i]);
+ close(fd);
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: prompter file\n");
+ threadexitsall("usage");
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+ char *s;
+ Font *f;
+ int i, n;
+ char buf[32], *args[3];
+ Keyboardctl *kbdctl;
+ Mousectl *mousectl;
+ Rune r;
+ Channel *mtok, *mtot, *ktok, *rtok, *rtot;
+ int noscrib;
+
+ noscrib = 0;
+ ARGBEGIN{
+ case 'n':
+ noscrib++;
+ break;
+ default:
+ usage();
+ }ARGEND
+
+ if(argc != 1)
+ usage();
+
+ readall(argv[0]);
+
+ initdraw(0, 0, "prompter");
+ mousectl = initmouse(nil, screen);
+ kbdctl = initkeyboard(nil);
+
+ mtok = chancreate(sizeof(Mouse), 0);
+ mtot = chancreate(sizeof(Mouse), 0);
+ ktok = chancreate(sizeof(Rune), 20);
+ rtok = chancreate(sizeof(int), 2);
+ rtot = chancreate(sizeof(int), 2);
+
+ initcontrols();
+
+ keyboard = newcontrolset(screen, ktok, mtok, rtok);
+ text = newcontrolset(screen, kbdctl->c, mtot, rtot);
+ text->clicktotype = 1;
+
+ threadcreate(mousemux, mousectl->c, 4096);
+ threadcreate(resizemux, mousectl->resizec, 4096);
+
+ eventchan = chancreate(sizeof(char*), 0);
+
+ cols[Back] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, Keyback);
+ namectlimage(cols[Back], "keyback");
+ cols[Light] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, Keylight);
+ namectlimage(cols[Light], "keylight");
+ cols[Shade] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, Keyshade);
+ namectlimage(cols[Shade], "keyshade");
+ cols[Mask] = allocimage(display, Rect(0,0,1,1), RGBA32, 1, Keymask);
+ namectlimage(cols[Shade], "keymask");
+ f = openfont(display, "/lib/font/bit/lucidasans/boldlatin1.6.font");
+ namectlfont(f, "bold");
+ f = openfont(display, "/lib/font/bit/lucidasans/unicode.6.font");
+ namectlfont(f, "roman");
+ font = f;
+
+ Nline = (screen->r.max.y - 2*2 - 5*13 - 8)/font->height;
+ if (Nline > nelem(entry)) Nline = nelem(entry);
+
+ for(i=0; i<Nline; i++){
+ snprint(buf, sizeof buf, "line.%.2d", i);
+ entry[i] = createentry(text, buf);
+ ctlprint(entry[i], "font roman");
+ ctlprint(entry[i], "image keyback");
+ if(i < nline)
+ ctlprint(entry[i], "value %q", lines[i]);
+ controlwire(entry[i], "event", eventchan);
+ activate(entry[i]);
+ }
+
+ kbd = createkeyboard(keyboard, "keyboard");
+ ctlprint(kbd, "font bold roman");
+ ctlprint(kbd, "image keyback");
+ ctlprint(kbd, "light keylight");
+ ctlprint(kbd, "mask keymask");
+ ctlprint(kbd, "border 1");
+ controlwire(kbd, "event", eventchan);
+
+ scrib = nil;
+ if(!noscrib){
+ scrib = createscribble(keyboard, "scribble");
+ ctlprint(scrib, "font bold");
+ ctlprint(scrib, "image keyback");
+ ctlprint(scrib, "border 1");
+ controlwire(scrib, "event", eventchan);
+ activate(scrib);
+ }
+
+ activate(kbd);
+ resizeready = 1;
+ resizecontrolset(keyboard);
+
+ for(;;){
+ s = recvp(eventchan);
+ n = tokenize(s, args, nelem(args));
+ if(n == 2 && strcmp(args[0], "mouse:")==0 && strcmp(args[1], "exit")==0)
+ break;
+ if(n == 3)
+ if(strcmp(args[0], "keyboard:")==0 || strcmp(args[0], "scribble:")==0)
+ if(strcmp(args[1], "value") == 0){
+ n = atoi(args[2]);
+ if(n == '\033') /* Escape exits */
+ break;
+ if(n <= 0xFFFF){
+ r = n;
+ send(kbdctl->c, &r);
+ }
+ }
+ }
+
+ for(i=0; i<Nline; i++){
+ ctlprint(entry[i], "data");
+ lines[i] = ctlstrdup(recvp(entry[i]->data));
+ }
+
+ writeall(argv[0]);
+
+ draw(screen, screen->r, display->white, nil, ZP);
+ flushimage(display, 1);
+
+ threadexitsall(nil);
+}