745 lines · 12.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <mouse.h>#include <cursor.h>#include <keyboard.h>#include <frame.h>#include "flayer.h"#include "samterm.h" Text	cmd;Rune	*scratch;long	nscralloc;Cursor	*cursor;Flayer	*which = 0;Flayer	*work = 0;long	snarflen;long	typestart = -1;long	typeend = -1;long	typeesc = -1;long	modified = 0;		/* strange lookahead for menus */char	hostlock = 1;char	hasunlocked = 0;int	maxtab = 8;int	chord;int	autoindent; #define chording 0	/* code here for reference but it causes deadlocks */ voidnotifyf(void *a, char *msg){	if(strcmp(msg, "interrupt") == 0)		noted(NCONT);	noted(NDFLT);} voidthreadmain(int argc, char *argv[]){	int i, got, scr, w;	Text *t;	Rectangle r;	Flayer *nwhich; 	/*	 * sam is talking to us on fd 0 and 1.	 * move these elsewhere so that if we accidentally	 * use 0 and 1 in other code, nothing bad happens.	 */	dup(0, 3);	dup(1, 4);	hostfd[0] = 3;	hostfd[1] = 4;	close(0);	close(1);	open("/dev/null", OREAD);	if(open("/dev/tty", OWRITE) < 0)		open("/dev/null", OWRITE); 	notify(notifyf); 	if(protodebug) print("getscreen\n");	getscreen(argc, argv);	if(protodebug) print("iconinit\n");	iconinit();	if(protodebug) print("initio\n");	initio();	if(protodebug) print("scratch\n");	scratch = alloc(100*RUNESIZE);	nscralloc = 100;	r = screen->r;	r.max.y = r.min.y+Dy(r)/5;	if(protodebug) print("flstart\n");	flstart(screen->clipr);	rinit(&cmd.rasp);	flnew(&cmd.l[0], gettext, 1, &cmd);	flinit(&cmd.l[0], r, font, cmdcols);	cmd.nwin = 1;	which = &cmd.l[0];	cmd.tag = Untagged;	outTs(Tversion, VERSION);	startnewfile(Tstartcmdfile, &cmd); 	got = 0;	if(protodebug) print("loop\n");	for(;;got = waitforio()){		if(hasunlocked && RESIZED())			resize();		if(got&(1<<RHost))			rcv();		if(got&(1<<RPlumb)){			for(i=0; cmd.l[i].textfn==0; i++)				;			current(&cmd.l[i]);			flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);			type(which, RPlumb);		}		if(got&(1<<RKeyboard))			if(which)				type(which, RKeyboard);			else				kbdblock();		if(got&(1<<RMouse)){			if(hostlock==2 || !ptinrect(mousep->xy, screen->r)){				mouseunblock();				continue;			}			nwhich = flwhich(mousep->xy);			scr = which && ptinrect(mousep->xy, which->scroll);			if(mousep->buttons)				flushtyping(1);			if(chording && chord==1 && !mousep->buttons)				chord = 0;			if(chording && chord)				chord |= mousep->buttons;			else if(mousep->buttons&1){				if(nwhich){					if(nwhich!=which)						current(nwhich);					else if(scr)						scroll(which, 1);					else{						t=(Text *)which->user1;						if(flselect(which)){							outTsl(Tdclick, t->tag, which->p0);							t->lock++;						}else if(t!=&cmd)							outcmd();						if(mousep->buttons&1)							chord = mousep->buttons;					}				}			}else if((mousep->buttons&2) && which){				if(scr)					scroll(which, 2);				else					menu2hit();			}else if((mousep->buttons&4)){				if(scr)					scroll(which, 3);				else					menu3hit();			}			mouseunblock();		}		if(chording && chord){			t = (Text*)which->user1;			if(!t->lock && !hostlock){				w = which-t->l;				if(chord&2){					cut(t, w, 1, 1);					chord &= ~2;				}else if(chord&4){					paste(t, w);					chord &= ~4;				}			}		}	}} voidresize(void){	int i; 	flresize(screen->clipr);	for(i = 0; i<nname; i++)		if(text[i])			hcheck(text[i]->tag);} voidcurrent(Flayer *nw){	Text *t; 	if(which)		flborder(which, 0);	if(nw){		flushtyping(1);		flupfront(nw);		flborder(nw, 1);		buttons(Up);		t = (Text *)nw->user1;		t->front = nw-&t->l[0];		if(t != &cmd)			work = nw;	}	which = nw;} voidcloseup(Flayer *l){	Text *t=(Text *)l->user1;	int m; 	m = whichmenu(t->tag);	if(m < 0)		return;	flclose(l);	if(l == which){		which = 0;		current(flwhich(Pt(0, 0)));	}	if(l == work)		work = 0;	if(--t->nwin == 0){		rclear(&t->rasp);		free((uchar *)t);		text[m] = 0;	}else if(l == &t->l[t->front]){		for(m=0; m<NL; m++)	/* find one; any one will do */			if(t->l[m].textfn){				t->front = m;				return;			}		panic("close");	}} Flayer *findl(Text *t){	int i;	for(i = 0; i<NL; i++)		if(t->l[i].textfn==0)			return &t->l[i];	return 0;} voidduplicate(Flayer *l, Rectangle r, Font *f, int close){	Text *t=(Text *)l->user1;	Flayer *nl = findl(t);	Rune *rp;	ulong n; 	if(nl){		flnew(nl, gettext, l->user0, (char *)t);		flinit(nl, r, f, l->f.cols);		nl->origin = l->origin;		rp = (*l->textfn)(l, l->f.nchars, &n);		flinsert(nl, rp, rp+n, l->origin);		flsetselect(nl, l->p0, l->p1);		if(close){			flclose(l);			if(l==which)				which = 0;		}else			t->nwin++;		current(nl);		hcheck(t->tag);	}	setcursor(mousectl, cursor);} voidbuttons(int updown){	while(((mousep->buttons&7)!=0) != updown)		getmouse();} intgetr(Rectangle *rp){	Point p;	Rectangle r; 	*rp = getrect(3, mousectl);	if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){		p = rp->min;		r = cmd.l[cmd.front].entire;		*rp = screen->r;		if(cmd.nwin==1){			if (p.y <= r.min.y)				rp->max.y = r.min.y;			else if (p.y >= r.max.y)				rp->min.y = r.max.y;			if (p.x <= r.min.x)				rp->max.x = r.min.x;			else if (p.x >= r.max.x)				rp->min.x = r.max.x;		}	}	return rectclip(rp, screen->r) &&	   rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40;} voidsnarf(Text *t, int w){	Flayer *l = &t->l[w]; 	if(l->p1>l->p0){		snarflen = l->p1-l->p0;		outTsll(Tsnarf, t->tag, l->p0, l->p1);	}} voidcut(Text *t, int w, int save, int check){	long p0, p1;	Flayer *l; 	l = &t->l[w];	p0 = l->p0;	p1 = l->p1;	if(p0 == p1)		return;	if(p0 < 0)		panic("cut");	if(save)		snarf(t, w);	outTsll(Tcut, t->tag, p0, p1);	flsetselect(l, p0, p0);	t->lock++;	hcut(t->tag, p0, p1-p0);	if(check)		hcheck(t->tag);} voidpaste(Text *t, int w){	if(snarflen){		cut(t, w, 0, 0);		t->lock++;		outTsl(Tpaste, t->tag, t->l[w].p0);	}} voidscrorigin(Flayer *l, int but, long p0){	Text *t=(Text *)l->user1; 	switch(but){	case 1:		outTsll(Torigin, t->tag, l->origin, p0);		break;	case 2:		outTsll(Torigin, t->tag, p0, 1L);		break;	case 3:		horigin(t->tag,p0);	}} intalnum(int c){	/*	 * Hard to get absolutely right.  Use what we know about ASCII	 * and assume anything above the Latin control characters is	 * potentially an alphanumeric.	 */	if(c<=' ')		return 0;	if(0x7F<=c && c<=0xA0)		return 0;	if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))		return 0;	return 1;} intraspc(Rasp *r, long p){	ulong n;	rload(r, p, p+1, &n);	if(n)		return scratch[0];	return 0;} longctlw(Rasp *r, long o, long p){	int c; 	if(--p < o)		return o;	if(raspc(r, p)=='\n')		return p;	for(; p>=o && !alnum(c=raspc(r, p)); --p)		if(c=='\n')			return p+1;	for(; p>o && alnum(raspc(r, p-1)); --p)		;	return p>=o? p : o;} longctlu(Rasp *r, long o, long p){	if(--p < o)		return o;	if(raspc(r, p)=='\n')		return p;	for(; p-1>=o && raspc(r, p-1)!='\n'; --p)		;	return p>=o? p : o;} intcenter(Flayer *l, long a){	Text *t; 	t = l->user1;	if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){		if(a > t->rasp.nrunes)			a = t->rasp.nrunes;		outTsll(Torigin, t->tag, a, 2L);		return 1;	}	return 0;} intthirds(Flayer *l, long a, int n){	Text *t;	Rectangle s;	long lines; 	t = l->user1;	if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){		if(a > t->rasp.nrunes)			a = t->rasp.nrunes;		s = insetrect(l->scroll, 1);		lines = (n*(s.max.y-s.min.y)/l->f.font->height+1)/3;		if (lines < 2)			lines = 2;		outTsll(Torigin, t->tag, a, lines);		return 1;	}	return 0;} intonethird(Flayer *l, long a){	return thirds(l, a, 1);} inttwothirds(Flayer *l, long a){	return thirds(l, a, 2);} voidflushtyping(int clearesc){	Text *t;	ulong n; 	if(clearesc)		typeesc = -1;		if(typestart == typeend) {		modified = 0;		return;	}	t = which->user1;	if(t != &cmd)		modified = 1;	rload(&t->rasp, typestart, typeend, &n);	scratch[n] = 0;	if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1]=='\n'){		setlock();		outcmd();	}	outTslS(Ttype, t->tag, typestart, scratch);	typestart = -1;	typeend = -1;} #define	BACKSCROLLKEY	Kup#define	ENDKEY	Kend#define	ESC		0x1B#define	HOMEKEY	Khome#define	LEFTARROW	Kleft#define	LINEEND	0x05#define	LINESTART	0x01#define	PAGEDOWN	Kpgdown#define	PAGEUP	Kpgup#define	RIGHTARROW	Kright#define	SCROLLKEY	Kdown#define	CUT	(Kcmd+'x')#define	COPY	(Kcmd+'c')#define	PASTE	(Kcmd+'v') 

Lines 1–500 of 745.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t