304 lines
6.3 KiB
C
304 lines
6.3 KiB
C
|
#include <u.h>
|
||
|
#include <libc.h>
|
||
|
#include <draw.h>
|
||
|
#include <cursor.h>
|
||
|
#include <event.h>
|
||
|
#include <bio.h>
|
||
|
#include "proof.h"
|
||
|
|
||
|
static int checkmouse(void);
|
||
|
static int buttondown(void);
|
||
|
static char *getmousestr(void);
|
||
|
static char *getkbdstr(int);
|
||
|
|
||
|
extern Cursor blot;
|
||
|
extern char *track;
|
||
|
|
||
|
Mouse mouse;
|
||
|
|
||
|
void
|
||
|
mapscreen(void)
|
||
|
{
|
||
|
if(initdraw(0, 0, "proof") < 0){
|
||
|
fprint(2, "proof: initdraw failed: %r\n");
|
||
|
exits("initdraw");
|
||
|
}
|
||
|
einit(Ekeyboard|Emouse);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
clearscreen(void)
|
||
|
{
|
||
|
draw(screen, screen->r, display->black, nil, ZP);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
screenprint(char *fmt, ...)
|
||
|
{
|
||
|
char buf[100];
|
||
|
Point p;
|
||
|
va_list args;
|
||
|
|
||
|
va_start(args, fmt);
|
||
|
vseprint(buf, &buf[sizeof buf], fmt, args);
|
||
|
va_end(args);
|
||
|
p = Pt(screen->clipr.min.x+40, screen->clipr.max.y-40);
|
||
|
string(screen, p, display->black, ZP, font, buf);
|
||
|
}
|
||
|
|
||
|
#define Viewkey 0xb2
|
||
|
|
||
|
char *
|
||
|
getcmdstr(void)
|
||
|
{
|
||
|
Event ev;
|
||
|
int e;
|
||
|
static ulong timekey = 0;
|
||
|
ulong tracktm = 0;
|
||
|
Dir *dir;
|
||
|
|
||
|
if(track){
|
||
|
if(timekey == 0)
|
||
|
timekey = etimer(0, 5000);
|
||
|
dir = dirstat(track);
|
||
|
if(dir != nil){
|
||
|
tracktm = dir->mtime;
|
||
|
free(dir);
|
||
|
}
|
||
|
}
|
||
|
for (;;) {
|
||
|
e = event(&ev);
|
||
|
if(resized){
|
||
|
resized = 0;
|
||
|
return "p";
|
||
|
}
|
||
|
if ((e & Emouse) && ev.mouse.buttons) {
|
||
|
mouse = ev.mouse;
|
||
|
return getmousestr();
|
||
|
} else if (e & Ekeyboard)
|
||
|
return getkbdstr(ev.kbdc); /* sadly, no way to unget */
|
||
|
else if (e & timekey) {
|
||
|
if((dir = dirstat(track)) != nil){
|
||
|
if(tracktm < dir->mtime){
|
||
|
free(dir);
|
||
|
return "q";
|
||
|
}
|
||
|
free(dir);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static char *
|
||
|
getkbdstr(int c0)
|
||
|
{
|
||
|
static char buf[100];
|
||
|
char *p;
|
||
|
int c;
|
||
|
|
||
|
if (c0 == '\n')
|
||
|
return "";
|
||
|
buf[0] = c0;
|
||
|
buf[1] = 0;
|
||
|
screenprint("%s", buf);
|
||
|
for (p = buf+1; (c = ekbd()) != '\n' && c != '\r' && c != -1 && c != Viewkey; ) {
|
||
|
if (c == '\b' && p > buf) {
|
||
|
*--p = ' ';
|
||
|
} else {
|
||
|
*p++ = c;
|
||
|
*p = 0;
|
||
|
}
|
||
|
screenprint("%s", buf);
|
||
|
}
|
||
|
*p = 0;
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define button3(b) ((b) & 4)
|
||
|
#define button2(b) ((b) & 2)
|
||
|
#define button1(b) ((b) & 1)
|
||
|
#define button23(b) ((b) & 6)
|
||
|
#define button123(b) ((b) & 7)
|
||
|
|
||
|
#define butcvt(b) (1 << ((b) - 1))
|
||
|
|
||
|
int waitdown(void) /* wait until some button is down */
|
||
|
{
|
||
|
while (!(mouse.buttons & 7))
|
||
|
mouse = emouse();
|
||
|
return mouse.buttons & 7;
|
||
|
}
|
||
|
|
||
|
int waitup(void)
|
||
|
{
|
||
|
while (mouse.buttons & 7)
|
||
|
mouse = emouse();
|
||
|
return mouse.buttons & 7;
|
||
|
}
|
||
|
|
||
|
char *m3[] = { "next", "prev", "page n", "again", "bigger", "smaller", "pan", "quit?", 0 };
|
||
|
char *m2[] = { 0 };
|
||
|
|
||
|
enum { Next = 0, Prev, Page, Again, Bigger, Smaller, Pan, Quit };
|
||
|
|
||
|
Menu mbut3 = { m3, 0, 0 };
|
||
|
Menu mbut2 = { m2, 0, 0 };
|
||
|
|
||
|
int last_hit;
|
||
|
int last_but;
|
||
|
|
||
|
char *pan(void)
|
||
|
{
|
||
|
Point dd, xy, lastxy, min, max;
|
||
|
|
||
|
esetcursor(&blot);
|
||
|
waitdown();
|
||
|
xy = mouse.xy;
|
||
|
do{
|
||
|
lastxy = mouse.xy;
|
||
|
mouse = emouse();
|
||
|
dd = subpt(mouse.xy, lastxy);
|
||
|
min = addpt(screen->clipr.min, dd);
|
||
|
max = addpt(screen->clipr.max, dd);
|
||
|
draw(screen, rectaddpt(screen->r, subpt(mouse.xy, lastxy)),
|
||
|
screen, nil, screen->r.min);
|
||
|
if(mouse.xy.x < lastxy.x) /* moved left, clear right */
|
||
|
draw(screen, Rect(max.x, screen->r.min.y, screen->r.max.x, screen->r.max.y),
|
||
|
display->white, nil, ZP);
|
||
|
else /* moved right, clear left*/
|
||
|
draw(screen, Rect(screen->r.min.x, screen->r.min.y, min.x, screen->r.max.y),
|
||
|
display->white, nil, ZP);
|
||
|
if(mouse.xy.y < lastxy.y) /* moved up, clear down */
|
||
|
draw(screen, Rect(screen->r.min.x, max.y, screen->r.max.x, screen->r.max.y),
|
||
|
display->white, nil, ZP);
|
||
|
else /* moved down, clear up */
|
||
|
draw(screen, Rect(screen->r.min.x, screen->r.min.y, screen->r.max.x, min.y),
|
||
|
display->white, nil, ZP);
|
||
|
flushimage(display, 1);
|
||
|
}while(mouse.buttons);
|
||
|
|
||
|
xyoffset = addpt(xyoffset, subpt(mouse.xy, xy));
|
||
|
|
||
|
esetcursor(0);
|
||
|
return "p";
|
||
|
}
|
||
|
|
||
|
static char *
|
||
|
getmousestr(void)
|
||
|
{
|
||
|
static char buf[64];
|
||
|
|
||
|
checkmouse();
|
||
|
if (last_but == 1)
|
||
|
return "p"; /* repaint after panning */
|
||
|
if (last_but == 2) {
|
||
|
return "c";
|
||
|
} else if (last_but == 3) {
|
||
|
switch (last_hit) {
|
||
|
case Next:
|
||
|
return "";
|
||
|
case Prev:
|
||
|
return "-1";
|
||
|
case Page:
|
||
|
screenprint("page? ");
|
||
|
return "c";
|
||
|
case Again:
|
||
|
return "p";
|
||
|
case Bigger:
|
||
|
snprint(buf, sizeof buf, "m%g", mag * 1.1);
|
||
|
return buf;
|
||
|
case Smaller:
|
||
|
snprint(buf, sizeof buf, "m%g", mag / 1.1);
|
||
|
return buf;
|
||
|
case Pan:
|
||
|
return pan();
|
||
|
case Quit:
|
||
|
return "q";
|
||
|
default:
|
||
|
return "c";
|
||
|
}
|
||
|
} else { /* button 1 or bail out */
|
||
|
return "c";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
checkmouse(void) /* return button touched if any */
|
||
|
{
|
||
|
int c, b;
|
||
|
char *p;
|
||
|
extern int confirm(int);
|
||
|
|
||
|
b = waitdown();
|
||
|
last_but = 0;
|
||
|
last_hit = -1;
|
||
|
c = 0;
|
||
|
if (button3(b)) {
|
||
|
last_hit = emenuhit(3, &mouse, &mbut3);
|
||
|
last_but = 3;
|
||
|
} else if (button2(b)) {
|
||
|
last_hit = emenuhit(2, &mouse, &mbut2);
|
||
|
last_but = 2;
|
||
|
} else { /* button1() */
|
||
|
pan();
|
||
|
last_but = 1;
|
||
|
}
|
||
|
waitup();
|
||
|
if (last_but == 3 && last_hit >= 0) {
|
||
|
p = m3[last_hit];
|
||
|
c = p[strlen(p) - 1];
|
||
|
}
|
||
|
if (c == '?' && !confirm(last_but))
|
||
|
last_hit = -1;
|
||
|
return last_but;
|
||
|
}
|
||
|
|
||
|
Cursor deadmouse = {
|
||
|
{ 0, 0}, /* offset */
|
||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
|
||
|
0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
|
||
|
0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x0C, 0x00, 0x82, 0x04, 0x41,
|
||
|
0xFF, 0xE1, 0x5F, 0xF1, 0x3F, 0xFE, 0x17, 0xF0,
|
||
|
0x03, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
|
||
|
};
|
||
|
|
||
|
Cursor blot ={
|
||
|
{ 0, 0 },
|
||
|
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
|
||
|
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }
|
||
|
};
|
||
|
|
||
|
Cursor skull ={
|
||
|
{ 0, 0 },
|
||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
|
||
|
0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
|
||
|
0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
|
||
|
0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
|
||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
|
||
|
0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
|
||
|
0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
|
||
|
0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }
|
||
|
};
|
||
|
|
||
|
confirm(int but) /* ask for confirmation if menu item ends with '?' */
|
||
|
{
|
||
|
int c;
|
||
|
static int but_cvt[8] = { 0, 1, 2, 0, 3, 0, 0, 0 };
|
||
|
|
||
|
esetcursor(&skull);
|
||
|
c = waitdown();
|
||
|
waitup();
|
||
|
esetcursor(0);
|
||
|
return but == but_cvt[c];
|
||
|
}
|