henesyinit from p9f0ed2a895 years agoHistory
311 lines · 5.6 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <mouse.h>#include <keyboard.h>#include <control.h>#include <scribble.h> typedef struct Scrib Scrib; struct Scrib{	Control;	int		border;	CImage	*image;	CImage	*color;	CImage	*bordercolor;	CFont	*font;	int		align;	int		lastbut;	char		lastchar[8];	Scribble	*scrib;}; enum{	EAlign,	EBorder,	EBordercolor,	EFocus,	EFont,	EImage,	ELinecolor,	ERect,	EShow,}; static char *cmds[] = {	[EAlign] =		"align",	[EBorder] =	"border",	[EBordercolor] ="bordercolor",	[EFocus] = 	"focus",	[EFont] =		"font",	[EImage] =	"image",	[ELinecolor] =	"linecolor",	[ERect] =		"rect",	[EShow] =		"show",	nil}; static void	scribctl(Control*, char*);static void	scribshow(Scrib*);static void	scribfree(Scrib*);static void scribchar(Scrib*, Rune); static void	resetstroke(Scrib *w);static void	displaystroke(Scrib *w);static void	displaylast(Scrib *w);static void	addpoint(Scrib *w, Point p); static voidscribthread(void *v){	char buf[32];	Scrib *b;	Rune r; 	b = v; 	snprint(buf, sizeof buf, "scrib-%s-0x%p", b->name, b);	threadsetname(buf); 	b->image = _getctlimage("white");	b->color = _getctlimage("black");	b->bordercolor = _getctlimage("black");	b->align = Aupperleft;	b->format = ctlstrdup("%q: value 0x%x");	b->font = _getctlfont("font");	b->scrib = scribblealloc();	b->lastbut = 0;	b->bordercolor = _getctlimage("black");	b->border = 0; 	for(;;){		switch(alt(b->alts)){		default:			ctlerror("%q: unknown message", b->name);		case AKey:			/* ignore keystrokes */			break;		case AMouse:			if (b->m.buttons & 0x1) {				if ((b->lastbut & 0x1) == 0) {					/* mouse went down */					resetstroke(b);				}				/* mouse is down */				addpoint(b, b->m.xy);			} else if (b->lastbut & 0x1) {				/* mouse went up */				r = recognize(b->scrib);				scribchar(b, r);				scribshow(b);				if (r) printctl(b->event, b->format, b->name, r);			}			b->lastbut = b->m.buttons;			break;		case ACtl:			_ctlcontrol(b, b->str, scribctl);			free(b->str);			break;		case AWire:			_ctlrewire(b);			break;		case AExit:			scribfree(b);			sendul(b->exit, 0);			return;		}	}} Control*createscribble(Controlset *cs, char *name){	return _createctl(cs, "scrib", sizeof(Scrib), name, scribthread, 64*1024);} static voidscribfree(Scrib *b){	_putctlimage(b->image);	_putctlimage(b->color);	_putctlimage(b->bordercolor);	_putctlfont(b->font);//	scribblefree(b->scrib);} static voidscribchar(Scrib *b, Rune r){	if(r == 0)		b->lastchar[0] = '\0';	else if(r == ' ')		strcpy(b->lastchar, "' '");	else if(r < ' ')		sprint(b->lastchar, "ctl-%c", r+'@');	else		sprint(b->lastchar, "%C", r);}  static voidscribshow(Scrib *b){	Image *i;	Rectangle r;	char *mode;	Scribble *s = b->scrib;	char buf[32]; 	if(b->border > 0){		r = insetrect(b->rect, b->border);		border(b->screen, b->rect, b->border, b->bordercolor->image, ZP);	}else		r = b->rect; 	i = b->image->image;	draw(b->screen, r, i, nil, i->r.min); 	if (s->ctrlShift)		mode = " ^C";	else if (s->puncShift)		mode = " #&^";	else if (s->curCharSet == CS_DIGITS)		mode = " 123";	else if (s->capsLock)		mode = " ABC";	else if (s->tmpShift)		mode = " Abc";	else		mode = " abc"; 	snprint(buf, sizeof buf, "%s %s", mode, b->lastchar); 	string(b->screen, r.min, b->color->image, ZP, b->font->font, buf);	flushimage(display, 1);} static voidscribctl(Control *c, char *str){	int cmd;	CParse cp;	Rectangle r;	Scrib *b; 	b = (Scrib*)c;	cmd = _ctlparse(&cp, str, cmds);	switch(cmd){	default:		ctlerror("%q: unrecognized message '%s'", b->name, cp.str);		break;	case EAlign:		_ctlargcount(b, &cp, 2);		b->align = _ctlalignment(cp.args[1]);		break;	case EBorder:		_ctlargcount(b, &cp, 2);		if(cp.iargs[1] < 0)			ctlerror("%q: bad border: %c", b->name, cp.str);		b->border = cp.iargs[1];		break;	case EBordercolor:		_ctlargcount(b, &cp, 2);		_setctlimage(b, &b->bordercolor, cp.args[1]);		break;	case EFocus:		break;	case EImage:		_ctlargcount(b, &cp, 2);		_setctlimage(b, &b->image, cp.args[1]);		break;	case ELinecolor:		_ctlargcount(b, &cp, 2);		_setctlimage(b, &b->bordercolor, cp.args[1]);		break;	case ERect:		_ctlargcount(b, &cp, 5);		r.min.x = cp.iargs[1];		r.min.y = cp.iargs[2];		r.max.x = cp.iargs[3];		r.max.y = cp.iargs[4];		if(Dx(r)<0 || Dy(r)<0)			ctlerror("%q: bad rectangle: %s", b->name, cp.str);		b->rect = r;		break;	case EShow:		_ctlargcount(b, &cp, 1);		scribshow(b);		break;	case EFont:		_ctlargcount(b, &cp, 2);		_setctlfont(b, &b->font, cp.args[1]);		break;	}} static voidresetstroke(Scrib *w){	Scribble *s = w->scrib; 	s->ps.npts = 0;	scribshow(w);} static voiddisplaystroke(Scrib *b){	Scribble *s = b->scrib; 	poly(b->screen, s->pt, s->ps.npts, Endsquare, Endsquare, 0, b->color->image, ZP);	flushimage(display, 1);} static voiddisplaylast(Scrib *w){	int	    npt;	Scribble *s = w->scrib; 	npt = s->ps.npts;	if (npt > 2)		npt = 2;	poly(w->screen, s->pt + (s->ps.npts - npt), npt, Endsquare, Endsquare,		0, w->color->image, ZP);	flushimage(display, 1);} static voidaddpoint(Scrib *w, Point p){	pen_point	*ppa;	Point	*pt;	int		ppasize;	Scribble	*s = w->scrib; 	if (s->ps.npts == s->ppasize) {		ppasize = s->ppasize + 100;		ppa = malloc ((sizeof (pen_point) + sizeof (Point)) * ppasize);		if (!ppa)			return;		pt = (Point *) (ppa + ppasize);		memmove(ppa, s->ps.pts, s->ppasize * sizeof (pen_point));		memmove(pt, s->pt, s->ppasize * sizeof (Point));		free (s->ps.pts);		s->ps.pts = ppa;		s->pt = pt;		s->ppasize = ppasize;	}	ppa = &s->ps.pts[s->ps.npts];	ppa->Point = p; 	pt = &s->pt[s->ps.npts];	*pt = p; 	s->ps.npts++;		displaylast(w);}