ref: fc299fdf45602f63cf16c939706abbfc276e69db
dir: /linesel.c/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <draw.h>
#include <thread.h>
#include <keyboard.h>
#include <mouse.h>
int bflag;
Image *fgcolor, *bgcolor;
Font *font;
char **lines, **matches, *buffer, *selected;
usize nlines, nmatches;
Rune kbdin[512];
Keyboardctl *keyboard;
Mousectl *mouse;
enum
{
Ckeyboard,
Cmouse,
Cresize,
Cnum
};
static void
redraw(void)
{
draw(screen, screen->r, bgcolor, nil, ZP);
string(screen,
Pt(10, 10), fgcolor, ZP, font, "test");
flushimage(display, 1);
}
static void
resetmatches(void)
{
memmove(matches, lines, nlines * sizeof *lines);
nmatches = nlines;
}
static void
initgraphics(Alt *a)
{
if(initdraw(nil, nil, "linesel") == -1)
sysfatal("initdraw: %r");
if(bflag){
fgcolor = display->white;
bgcolor = display->black;
}else{
fgcolor = display->black;
bgcolor = display->white;
}
font = display->defaultfont;
if((keyboard = initkeyboard(nil)) == nil)
sysfatal("initkeyboard: %r");
if((mouse = initmouse(nil, screen)) == nil)
sysfatal("initmouse: %r");
a[Ckeyboard].c = keyboard->c;
a[Cmouse].c = mouse->c;
}
static void
readbuffer(void)
{
Biobuf *bp;
char *line, *s;
if((bp = Bfdopen(0, OREAD)) == nil)
sysfatal("setting buffering on fd0: %r");
if ((buffer = Brdstr(bp, '\0', 1)) == nil)
sysfatal("reading input lines: %r");
for(line = s = buffer; s = strchr(s, '\n'); line = ++s){
*s = '\0';
if((lines = realloc(lines, ++nlines * sizeof *lines)) == nil)
sysfatal("malloc: %r");
lines[nlines-1] = line;
}
if((matches = malloc(nlines * sizeof *lines)) == nil)
sysfatal("malloc: %r");
}
static void
linesel(void)
{
Rune r;
Mouse m;
Alt a[] = {
[Ckeyboard] = {nil, &r, CHANRCV},
[Cmouse] = {nil, &m, CHANRCV},
[Cnum] = {nil, nil, CHANEND},
};
initgraphics(a);
redraw();
for(;;){
switch(alt(a)){
case -1:
sysfatal("watching channels: %r\n");
case Ckeyboard:
switch(r){
case '\n':
return;
}
break;
case Cmouse:
break;
}
}
}
static void
usage(void)
{
print("usage: %s [-b] <choices\n", argv0);
threadexitsall("usage");
}
void
threadmain(int argc, char **argv)
{
ARGBEGIN{
case 'b':
bflag = 1;
break;
default:
usage();
}ARGEND;
readbuffer();
resetmatches();
selected = matches[0];
linesel();
print("%s\n", selected);
threadexitsall(nil);
}