123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- #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);
- }
|