⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wind.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Convert back to physical coordinates */voidwmovemouse(Window *w, Point p){	p.x += w->screenr.min.x-w->i->r.min.x;	p.y += w->screenr.min.y-w->i->r.min.y;	moveto(mousectl, p);}voidwborder(Window *w, int type){	Image *col;	if(w->i == nil)		return;	if(w->holding){		if(type == Selborder)			col = holdcol;		else			col = paleholdcol;	}else{		if(type == Selborder)			col = titlecol;		else			col = lighttitlecol;	}	border(w->i, w->i->r, Selborder, col, ZP);}Window*wpointto(Point pt){	int i;	Window *v, *w;	w = nil;	for(i=0; i<nwindow; i++){		v = window[i];		if(ptinrect(pt, v->screenr))		if(!v->deleted)		if(w==nil || v->topped>w->topped)			w = v;	}	return w;}voidwcurrent(Window *w){	Window *oi;	if(wkeyboard!=nil && w==wkeyboard)		return;	oi = input;	input = w;	if(oi!=w && oi!=nil)		wrepaint(oi);	if(w !=nil){		wrepaint(w);		wsetcursor(w, 0);	}	if(w != oi){		if(oi){			oi->wctlready = 1;			wsendctlmesg(oi, Wakeup, ZR, nil);		}		if(w){			w->wctlready = 1;			wsendctlmesg(w, Wakeup, ZR, nil);		}	}}voidwsetcursor(Window *w, int force){	Cursor *p;	if(w==nil || /*w!=input || */ w->i==nil || Dx(w->screenr)<=0)		p = nil;	else if(wpointto(mouse->xy) == w){		p = w->cursorp;		if(p==nil && w->holding)			p = &whitearrow;	}else		p = nil;	if(!menuing)		riosetcursor(p, force && !menuing);}voidriosetcursor(Cursor *p, int force){	if(!force && p==lastcursor)		return;	setcursor(mousectl, p);	lastcursor = p;}Window*wtop(Point pt){	Window *w;	w = wpointto(pt);	if(w){		if(w->topped == topped)			return nil;		topwindow(w->i);		wcurrent(w);		flushimage(display, 1);		w->topped = ++topped;	}	return w;}voidwtopme(Window *w){	if(w!=nil && w->i!=nil && !w->deleted && w->topped!=topped){		topwindow(w->i);		flushimage(display, 1);		w->topped = ++ topped;	}}voidwbottomme(Window *w){	if(w!=nil && w->i!=nil && !w->deleted){		bottomwindow(w->i);		flushimage(display, 1);		w->topped = - ++topped;	}}Window*wlookid(int id){	int i;	for(i=0; i<nwindow; i++)		if(window[i]->id == id)			return window[i];	return nil;}voidwclosewin(Window *w){	Rectangle r;	int i;	w->deleted = TRUE;	if(w == input){		input = nil;		wsetcursor(w, 0);	}	if(w == wkeyboard)		wkeyboard = nil;	for(i=0; i<nhidden; i++)		if(hidden[i] == w){			--nhidden;			memmove(hidden+i, hidden+i+1, (nhidden-i)*sizeof(hidden[0]));			break;		}	for(i=0; i<nwindow; i++)		if(window[i] == w){			--nwindow;			memmove(window+i, window+i+1, (nwindow-i)*sizeof(Window*));			w->deleted = TRUE;			r = w->i->r;			/* move it off-screen to hide it, in case client is slow in letting it go */			MOVEIT originwindow(w->i, r.min, view->r.max);			freeimage(w->i);			w->i = nil;			return;		}	error("unknown window in closewin");}voidwsetpid(Window *w, int pid, int dolabel){	char buf[128];	int fd;	w->pid = pid;	if(dolabel){		sprint(buf, "rc %d", pid);		free(w->label);		w->label = estrdup(buf);	}	sprint(buf, "/proc/%d/notepg", pid);	fd = open(buf, OWRITE|OCEXEC);	if(w->notefd > 0)		close(w->notefd);	w->notefd = fd;}voidwinshell(void *args){	Window *w;	Channel *pidc;	void **arg;	char *cmd, *dir;	char **argv;	arg = args;	w = arg[0];	pidc = arg[1];	cmd = arg[2];	argv = arg[3];	dir = arg[4];	rfork(RFNAMEG|RFFDG|RFENVG);	if(filsysmount(filsys, w->id) < 0){		fprint(2, "mount failed: %r\n");		sendul(pidc, 0);		threadexits("mount failed");	}	close(0);	if(open("/dev/cons", OREAD) < 0){		fprint(2, "can't open /dev/cons: %r\n");		sendul(pidc, 0);		threadexits("/dev/cons");	}	close(1);	if(open("/dev/cons", OWRITE) < 0){		fprint(2, "can't open /dev/cons: %r\n");		sendul(pidc, 0);		threadexits("open");	/* BUG? was terminate() */	}	if(wclose(w) == 0){	/* remove extra ref hanging from creation */		notify(nil);		dup(1, 2);		if(dir)			chdir(dir);		procexec(pidc, cmd, argv);		_exits("exec failed");	}}static Rune left1[] =  { L'{', L'[', L'(', L'<', L'«', 0 };static Rune right1[] = { L'}', L']', L')', L'>', L'»', 0 };static Rune left2[] =  { L'\n', 0 };static Rune left3[] =  { L'\'', L'"', L'`', 0 };Rune *left[] = {	left1,	left2,	left3,	nil};Rune *right[] = {	right1,	left2,	left3,	nil};voidwdoubleclick(Window *w, uint *q0, uint *q1){	int c, i;	Rune *r, *l, *p;	uint q;	for(i=0; left[i]!=nil; i++){		q = *q0;		l = left[i];		r = right[i];		/* try matching character to left, looking right */		if(q == 0)			c = '\n';		else			c = w->r[q-1];		p = strrune(l, c);		if(p != nil){			if(wclickmatch(w, c, r[p-l], 1, &q))				*q1 = q-(c!='\n');			return;		}		/* try matching character to right, looking left */		if(q == w->nr)			c = '\n';		else			c = w->r[q];		p = strrune(r, c);		if(p != nil){			if(wclickmatch(w, c, l[p-r], -1, &q)){				*q1 = *q0+(*q0<w->nr && c=='\n');				*q0 = q;				if(c!='\n' || q!=0 || w->r[0]=='\n')					(*q0)++;			}			return;		}	}	/* try filling out word to right */	while(*q1<w->nr && isalnum(w->r[*q1]))		(*q1)++;	/* try filling out word to left */	while(*q0>0 && isalnum(w->r[*q0-1]))		(*q0)--;}intwclickmatch(Window *w, int cl, int cr, int dir, uint *q){	Rune c;	int nest;	nest = 1;	for(;;){		if(dir > 0){			if(*q == w->nr)				break;			c = w->r[*q];			(*q)++;		}else{			if(*q == 0)				break;			(*q)--;			c = w->r[*q];		}		if(c == cr){			if(--nest==0)				return 1;		}else if(c == cl)			nest++;	}	return cl=='\n' && nest==1;}uintwbacknl(Window *w, uint p, uint n){	int i, j;	/* look for start of this line if n==0 */	if(n==0 && p>0 && w->r[p-1]!='\n')		n = 1;	i = n;	while(i-->0 && p>0){		--p;	/* it's at a newline now; back over it */		if(p == 0)			break;		/* at 128 chars, call it a line anyway */		for(j=128; --j>0 && p>0; p--)			if(w->r[p-1]=='\n')				break;	}	return p;}voidwshow(Window *w, uint q0){	int qe;	int nl;	uint q;	qe = w->org+w->nchars;	if(w->org<=q0 && (q0<qe || (q0==qe && qe==w->nr)))		wscrdraw(w);	else{		nl = 4*w->maxlines/5;		q = wbacknl(w, q0, nl);		/* avoid going backwards if trying to go forwards - long lines! */		if(!(q0>w->org && q<w->org))			wsetorigin(w, q, TRUE);		while(q0 > w->org+w->nchars)			wsetorigin(w, w->org+1, FALSE);	}}voidwsetorigin(Window *w, uint org, int exact){	int i, a, fixup;	Rune *r;	uint n;	if(org>0 && !exact){		/* org is an estimate of the char posn; find a newline */		/* don't try harder than 256 chars */		for(i=0; i<256 && org<w->nr; i++){			if(w->r[org] == '\n'){				org++;				break;			}			org++;		}	}	a = org-w->org;	fixup = 0;	if(a>=0 && a<w->nchars){		frdelete(w, 0, a);		fixup = 1;	/* frdelete can leave end of last line in wrong selection mode; it doesn't know what follows */	}else if(a<0 && -a<w->nchars){		n = w->org - org;		r = runemalloc(n);		runemove(r, w->r+org, n);		frinsert(w, r, r+n, 0);		free(r);	}else		frdelete(w, 0, w->nchars);	w->org = org;	wfill(w);	wscrdraw(w);	wsetselect(w, w->q0, w->q1);	if(fixup && w->p1 > w->p0)		frdrawsel(w, frptofchar(w, w->p1-1), w->p1-1, w->p1, 1);}voidwsetselect(Window *w, uint q0, uint q1){	int p0, p1;	/* w->p0 and w->p1 are always right; w->q0 and w->q1 may be off */	w->q0 = q0;	w->q1 = q1;	/* compute desired p0,p1 from q0,q1 */	p0 = q0-w->org;	p1 = q1-w->org;	if(p0 < 0)		p0 = 0;	if(p1 < 0)		p1 = 0;	if(p0 > w->nchars)		p0 = w->nchars;	if(p1 > w->nchars)		p1 = w->nchars;	if(p0==w->p0 && p1==w->p1)		return;	/* screen disagrees with desired selection */	if(w->p1<=p0 || p1<=w->p0 || p0==p1 || w->p1==w->p0){		/* no overlap or too easy to bother trying */		frdrawsel(w, frptofchar(w, w->p0), w->p0, w->p1, 0);		frdrawsel(w, frptofchar(w, p0), p0, p1, 1);		goto Return;	}	/* overlap; avoid unnecessary painting */	if(p0 < w->p0){		/* extend selection backwards */		frdrawsel(w, frptofchar(w, p0), p0, w->p0, 1);	}else if(p0 > w->p0){		/* trim first part of selection */		frdrawsel(w, frptofchar(w, w->p0), w->p0, p0, 0);	}	if(p1 > w->p1){		/* extend selection forwards */		frdrawsel(w, frptofchar(w, w->p1), w->p1, p1, 1);	}else if(p1 < w->p1){		/* trim last part of selection */		frdrawsel(w, frptofchar(w, p1), p1, w->p1, 0);	}    Return:	w->p0 = p0;	w->p1 = p1;}uintwinsert(Window *w, Rune *r, int n, uint q0){	uint m;	if(n == 0)		return q0;	if(w->nr+n>HiWater && q0>=w->org && q0>=w->qh){		m = min(HiWater-LoWater, min(w->org, w->qh));		w->org -= m;		w->qh -= m;		if(w->q0 > m)			w->q0 -= m;		else			w->q0 = 0;		if(w->q1 > m)			w->q1 -= m;		else			w->q1 = 0;		w->nr -= m;		runemove(w->r, w->r+m, w->nr);		q0 -= m;	}	if(w->nr+n > w->maxr){		/*		 * Minimize realloc breakage:		 *	Allocate at least MinWater		 * 	Double allocation size each time		 *	But don't go much above HiWater		 */		m = max(min(2*(w->nr+n), HiWater), w->nr+n)+MinWater;		if(m > HiWater)			m = max(HiWater+MinWater, w->nr+n);		if(m > w->maxr){			w->r = runerealloc(w->r, m);			w->maxr = m;		}	}	runemove(w->r+q0+n, w->r+q0, w->nr-q0);	runemove(w->r+q0, r, n);	w->nr += n;	/* if output touches, advance selection, not qh; works best for keyboard and output */	if(q0 <= w->q1)		w->q1 += n;	if(q0 <= w->q0)		w->q0 += n;	if(q0 < w->qh)		w->qh += n;	if(q0 < w->org)		w->org += n;	else if(q0 <= w->org+w->nchars)		frinsert(w, r, r+n, q0-w->org);	return q0;}voidwfill(Window *w){	Rune *rp;	int i, n, m, nl;	if(w->lastlinefull)		return;	rp = malloc(messagesize);	do{		n = w->nr-(w->org+w->nchars);		if(n == 0)			break;		if(n > 2000)	/* educated guess at reasonable amount */			n = 2000;		runemove(rp, w->r+(w->org+w->nchars), n);		/*		 * it's expensive to frinsert more than we need, so		 * count newlines.		 */		nl = w->maxlines-w->nlines;		m = 0;		for(i=0; i<n; ){			if(rp[i++] == '\n'){				m++;				if(m >= nl)					break;			}		}		frinsert(w, rp, rp+i, w->nchars);	}while(w->lastlinefull == FALSE);	free(rp);}char*wcontents(Window *w, int *ip){	return runetobyte(w->r, w->nr, ip);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -