#include <u.h>
#include <libc.h>
#include <bio.h>
#include <thread.h>
#include <draw.h>
#include <mouse.h>
#include <keyboard.h>
#include <frame.h>
#include <cursor.h>
#include "dat.h"
#include "fns.h"
Mousectl *mc;
Keyboardctl *kc;
int quitok;
enum {
ZEROX,
RESIZE,
CLOSE,
WRITE,
QUIT,
WIN
};
int
quit(void)
{
File *f;
if(!quitok)
for(f = flist.next; f != &flist; f = f->next)
if(f->change > 0){
cmdprint("?\n");
quitok = 1;
return 0;
}
return -1;
}
static char *
menugen(int n)
{
File *f;
static int mw;
static char buf[512];
int rc;
char *p;
switch(n){
case ZEROX: return "zerox";
case CLOSE: return "close";
case RESIZE: return "resize";
case WRITE: return "write";
case QUIT: return "quit";
}
if(n < WIN)
sysfatal("menugen: no string for n=%d", n);
n -= WIN;
if(n == 0){
mw = 0;
for(f = flist.next; f != &flist; f = f->next){
rc = filtitlelen(f);
if(rc > mw)
mw = rc;
}
return "~~spred~~";
}
for(f = flist.next; f != &flist; f = f->next)
if(--n == 0){
p = filtitle(f, buf, buf + sizeof(buf));
rc = mw - utflen(buf);
if(p + rc >= buf + sizeof(buf))
rc = buf + sizeof(buf) - p - 1;
memset(p, ' ', rc);
p[rc] = 0;
return buf;
}
return nil;
}
static int
rmb(void)
{
static Menu menu = {nil, menugen};
int n;
Win *w;
File *f;
if(actw != nil && actw->tab->rmb != nil && actw->tab->rmb(actw, mc) >= 0)
return 0;
n = menuhit(3, mc, &menu, nil);
if(n < 0)
return 0;
switch(n){
case ZEROX:
w = winsel(mc, 3);
if(w != nil)
winzerox(w, mc);
return 0;
case CLOSE:
w = winsel(mc, 3);
if(w != nil)
winclose(w);
return 0;
case RESIZE:
winresize(winsel(mc, 3), mc);
return 0;
case WRITE:
w = winsel(mc, 3);
if(w != nil)
winwrite(w, nil);
return 0;
case QUIT:
return quit();
}
if(n < WIN)
sysfatal("rmb: no action for n=%d", n);
if(n == 0){
setfocus(cmdw);
return 0;
}
n -= WIN;
for(f = flist.next; f != &flist; f = f->next)
if(--n == 0){
if(f->wins.wnext == &f->wins){
newwinsel(f->type, mc, f);
return 0;
}
for(w = f->wins.wnext; w != &f->wins && w != actw; w = w->wnext)
;
if(w->wnext == &f->wins)
w = w->wnext;
setfocus(w->wnext);
return 0;
}
return 0;
}
static void
loop(void)
{
Rune r;
int n;
Alt a[] = {
{mc->c, &mc->Mouse, CHANRCV},
{kc->c, &r, CHANRCV},
{mc->resizec, &n, CHANRCV},
{nil, nil, CHANEND}
};
for(;;){
flushimage(display, 1);
switch(alt(a)){
case 0:
if((mc->buttons & 1) != 0)
winclick(mc);
if((mc->buttons & 2) != 0)
if(actw != nil && actw->tab->menu != nil)
actw->tab->menu(actw, mc);
if((mc->buttons & 4) != 0)
if(rmb() < 0)
return;
break;
case 1:
if(actw != nil && actw->tab->key != nil)
actw->tab->key(actw, r);
break;
case 2:
resize();
break;
}
}
}
void
threadmain(int argc, char **argv)
{
ARGBEGIN {
default:
;
} ARGEND;
quotefmtinstall();
if(initdraw(nil, nil, nil) < 0)
sysfatal("initdraw: %r");
initwin();
mc = initmouse(nil, screen);
if(mc == nil)
sysfatal("initmouse: %r");
kc = initkeyboard(nil);
if(kc == nil)
sysfatal("initkeyboard: %r");
loop();
threadexitsall(nil);
}
Cursor crosscursor = {
{-7, -7},
{0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0,
0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, },
{0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x7F, 0xFE,
0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, }
};