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

📄 ev_once.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lint#ifdef sccsstatic  char sccsid[] = "@(#)ev_once.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. *//* * Initialization and finalization of entity views. */#include <suntool/primal.h>#include <sys/time.h>#include <pixrect/pixrect.h>#include <pixrect/pr_util.h>#include <pixrect/memvar.h>#include <pixrect/pixfont.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/pixwin.h>#include <suntool/tool.h>#include <suntool/ev_impl.h>extern Es_index	ev_index_for_line();static short caret_image[7]={	0x1000, 0x3800, 0x3800, 0x7C00, 0x7C00, 0xFE00, 0xFE00};mpr_static(ev_caret_mpr, 7, 7, 1, caret_image);static short ghost_caret[7]={	0x1000, 0x2800, 0x5400, 0xAA00, 0x5400, 0x2800, 0x1000};#ifdef notdefstatic short ghost_caret[7]={	0x1000, 0x2800, 0x2800, 0x5400, 0x5400, 0xAA00, 0xAA00};#endif notdefmpr_static(ev_ghost_mpr, 7, 7, 1, ghost_caret);Ev_chainev_create_chain(esh, eih)	Es_handle	esh;	Ei_handle	eih;{	Ev_chain		chain = NEW(struct ev_chain_object);	Ev_chain_pd_handle	private =				NEW(struct ev_chain_private_data_object);	chain->esh = esh;	chain->eih = eih;	chain->fingers = FT_CLIENT_CREATE(10, struct ev_finger_datum);	chain->client_data = (caddr_t) 0;	FT_CLEAR_ALL(chain->fingers);	private->insert_pos = ES_CANNOT_SET;	(void) ev_init_mark(&private->selection[0]);	(void) ev_init_mark(&private->selection[1]);	private->op_bdry = FT_CLIENT_CREATE(10, struct op_bdry_datum);	FT_CLEAR_ALL(private->op_bdry);	private->lower_context = EV_NO_CONTEXT;	private->upper_context = EV_NO_CONTEXT;	private->notify_level = 0;	private->notify_proc = (int (*)()) 0;	private->edit_number = 1;	private->caret_is_ghost = TRUE;	private->caret_pr = &ev_caret_mpr;	private->caret_hotpoint.x = (ev_caret_mpr.pr_size.x+1) >> 1;	private->caret_hotpoint.y = 2;	private->ghost_pr = &ev_ghost_mpr;	private->ghost_hotpoint.x = (ev_ghost_mpr.pr_size.x+1) >> 1;	private->ghost_hotpoint.y = 2;	private->cache_pos_for_file_line.index_of_first = ES_CANNOT_SET;	private->cache_pos_for_file_line.edit_number = 0;	private->cache_pos_for_file_line.first_line_number = 0;	private->cache_pos_for_file_line.line_count = 0;	chain->private_data = (caddr_t) private;	return(chain);}Ev_handleev_create_view(chain, pw, rect)	Ev_chain	chain;	struct pixwin	*pw;	struct rect	*rect;{	extern Ev_line_table	ev_ft_for_rect();	Ev_handle		view = NEW(struct ev_object);	Ev_pd_handle		private = NEW(struct ev_private_data_object);	view->pw = pw;	view->rect = *rect;	view->line_table = ev_ft_for_rect(chain->eih, rect);	view->tmp_line_table = ev_ft_for_rect(chain->eih, rect);	view->view_chain = chain;	view->next = chain->first_view;	chain->first_view = view;	private->caret_pr_pos.x = EV_NULL_DIM;	private->caret_pr_pos.y = EV_NULL_DIM;	private->left_margin = private->right_margin = 0;	private->right_break = EV_CLIP;	/*   Note: calloc correctly initializes private->cached_insert_info	 * and private->cached_line_info.	 */	view->client_data = (caddr_t) 0;	view->private_data = (caddr_t) private;	return(view);}ev_destroy(view)	Ev_handle		view;{	register Ev_handle	first_view = view->view_chain->first_view;	if (first_view == view) {		view->view_chain->first_view = first_view->next;	} else {		register Ev_handle prior = first_view;		while (prior->next != view) {			prior = prior->next;		}		prior->next = view->next;	}	ft_destroy(&view->line_table);	ft_destroy(&view->tmp_line_table);	free((char *)(view->private_data));	free((char *)view);}Ev_chainev_destroy_chain_and_views(chain)	Ev_chain	chain;{	Ev_handle	next_view = chain->first_view;	while (next_view) {		next_view = next_view->next;		ev_destroy(chain->first_view);	}	ft_destroy(&chain->fingers);	free(chain->private_data);	free((char *)chain);	return(0);}Ev_handleev_view_above(this_view)	Ev_handle	this_view;{	register int		max_top = -1, this_top = this_view->rect.r_top;	register Ev_handle	view, result = 0;	FORALLVIEWS(this_view->view_chain, view) {	    if (view->rect.r_top > max_top && view->rect.r_top < this_top) {		max_top = view->rect.r_top;		result = view;	    }	}	return(result);}Ev_handleev_view_below(this_view)	Ev_handle	this_view;{	register int		min_top = 20000,				this_top = this_view->rect.r_top;	register Ev_handle	view, result = 0;	FORALLVIEWS(this_view->view_chain, view) {	    if (view->rect.r_top < min_top && view->rect.r_top > this_top) {		min_top = view->rect.r_top;		result = view;	    }	}	return(result);}Ev_handleev_highest_view(chain)	Ev_chain	chain;{	register Ev_handle	view, result = chain->first_view;	FORNEXTVIEWS(result, view) {	    if (view->rect.r_top < result->rect.r_top)		result = view;	}	return(result);}Ev_handleev_lowest_view(chain)	Ev_chain	chain;{	register Ev_handle	view, result = chain->first_view;	FORNEXTVIEWS(result, view) {	    if (view->rect.r_top > result->rect.r_top)		result = view;	}	return(result);}extern voidev_line_info(view, top, bottom)	register Ev_handle	 view;	int			*top, *bottom;/* Return the 1-origin line numbers of the physical lines present on the * first and last screen lines of the view. */{	Es_index		 last_plus_one, old_first, delta_first;	Ev_pd_handle		 private = EV_PRIVATE(view);	register Ev_chain	 chain = view->view_chain;	Ev_chain_pd_handle	 chain_private = EV_CHAIN_PRIVATE(chain);	int			 edit_number_ok, first_ok;	register Ev_physical_line_info				*cache = &(private->cached_line_info);	edit_number_ok = (cache->edit_number == chain_private->edit_number);	first_ok = (cache->index_of_first == EV_VIEW_FIRST(view));	if (!(first_ok && edit_number_ok)) {	    /*	     * Cache is invalid - incremental fix is:	     * a) possible iff edit_number_ok;	     * b) worthwhile unless view moved closer to start of file and	     *    view is now closer to start than to old position.	     */	    old_first = cache->index_of_first;	    ev_view_range(view, &cache->index_of_first, &last_plus_one);	    delta_first = old_first - cache->index_of_first;	    if ((edit_number_ok) && (		(delta_first < 0) || (delta_first < cache->index_of_first) )) {		if (delta_first < 0) {		    cache->first_line_number +=			ev_newlines_in_esh(chain->esh,					   old_first, cache->index_of_first);		} else {		    cache->first_line_number -=			ev_newlines_in_esh(chain->esh,					   cache->index_of_first, old_first);		}	    } else {		cache->first_line_number =		    ev_newlines_in_esh(chain->esh, 0L,				       cache->index_of_first);	    }	    cache->line_count =		ev_newlines_in_esh(chain->esh,				   cache->index_of_first,				   last_plus_one);	    cache->edit_number = chain_private->edit_number;	}	if (top)	    *top = cache->first_line_number + 1;	if (bottom)	    *bottom = cache->first_line_number +		      cache->line_count;}extern intev_newlines_in_esh(esh, first, last_plus_one)	Es_handle	esh;	Es_index	first, last_plus_one;{#define BUFSIZE 2096	char			buf[BUFSIZE+4];	register char		*in_buf, *buf_last_plus_one;	register int		count = 0;	int			 read;	register Es_index	new_pos = first, pos;	es_set_position(esh, new_pos);	while (new_pos < last_plus_one) {	    pos = new_pos;	    new_pos = es_read(esh, BUFSIZE, buf, &read);	    if (READ_AT_EOF(pos, new_pos, read))		goto Return;	    if (read > 0) {		if (pos+read > last_plus_one) {		    read = last_plus_one - pos;		}		buf_last_plus_one = buf + read;		for (in_buf = buf; in_buf < buf_last_plus_one; in_buf++) {		    if (*in_buf == '\n')			count++;		}	    }	}Return:	return(count);#undef BUFSIZE}extern intev_rect_for_ith_physical_line(view, phys_line, first, rect, skip_white_space)	register Ev_handle	 view;	int			 phys_line;	register Es_index	*first;	Rect			*rect;	int			 skip_white_space;{	extern Rect		 ev_rect_for_line();	int			 lt_index;	Es_index		 last_plus_one;	char			*newline_str = "\n";	ev_view_range(view, first, &last_plus_one);	if (phys_line == 0) {	    lt_index = 0;	} else {	    ev_find_in_esh(view->view_chain->esh, newline_str, 1,			   *first, (unsigned)phys_line, 0,			   first, &last_plus_one);	    if (*first == ES_CANNOT_SET)		return(-1);	    lt_index = ft_bounding_index(&view->line_table, last_plus_one);	}	*first = ev_index_for_line(view, lt_index);	*rect = ev_rect_for_line(view, lt_index);	if (skip_white_space) {	    Es_index	span_first;	    ev_span(view->view_chain, *first, &span_first, &last_plus_one,		EI_SPAN_SP_AND_TAB|EI_SPAN_RIGHT_ONLY|EI_SPAN_IN_CLASS_ONLY);	    if (span_first != ES_CANNOT_SET) {		*first = last_plus_one;		(void) ev_xy_in_view(view, *first, &lt_index, rect);	    }	}	return(lt_index);}/* *   Semantics added to catch filemerge problems: a line MUST contain at * least one character.  Prior to this additional restriction, this routine * would return the stream length when asked to map line n, for streams * containing exactly n newlines, and no characters after the last newline. */extern Es_indexev_position_for_physical_line(chain, line, skip_white_space)	Ev_chain	 chain;	register int	 line;	int		 skip_white_space;{	register Ev_chain_pd_handle			 chain_private = EV_CHAIN_PRIVATE(chain);	register Ev_physical_line_info			*cache = &chain_private->cache_pos_for_file_line;	Es_index	 first, last_plus_one;	Es_index	 start_search;	register int	 count;	char		 buf[2];	if (line > 0) {	    count = line;	    if (cache->edit_number == chain_private->edit_number &&		line >= cache->first_line_number) {		start_search = cache->index_of_first;		count -= cache->first_line_number;	    } else {		start_search = 0L;	    }	    if (count) {		buf[0] = '\n';		ev_find_in_esh(chain->esh, buf, 1, start_search, count, 0,			       &first, &last_plus_one);	    } else {		/* Consecutive identical queries: make sure that following		 * tests and assignments on first and last_plus_one will 		 * generate the correct result.		 */		first = last_plus_one = start_search;	    }	    if (first != ES_CANNOT_SET) {		/* Check for match at end-of-stream. */		if (last_plus_one < es_get_length(chain->esh)) {		    first = last_plus_one;		    cache->edit_number = chain_private->edit_number;		    cache->first_line_number = line;		    cache->index_of_first = first;		} else {		    first = ES_CANNOT_SET;		}	    }	} else if (line < 0) {	    first = ES_CANNOT_SET;	} else {	    first = 0;	}	if ((first != ES_CANNOT_SET) && skip_white_space) {	    Es_index	span_first;	    ev_span(chain, first, &span_first, &last_plus_one,		  EI_SPAN_SP_AND_TAB|EI_SPAN_RIGHT_ONLY|EI_SPAN_IN_CLASS_ONLY);	    if (span_first != ES_CANNOT_SET)		first = last_plus_one;	}	return(first);}ev_find_in_esh(esh, pattern, pattern_length, position, count, flags,		first, last_plus_one)	Es_handle	 esh;		  /* stream handle          */	char		*pattern;	  /* pattern to search for  */	unsigned	 pattern_length;  /* no. of chars in pat.   */	Es_index	 position;	  /* start search from here */	unsigned	 count;		  /* no. occurrances of pat */	unsigned	 flags;		  /* fwd or back            */	Es_index	*first;		  /* start of found pattern */	Es_index	*last_plus_one;	  /* end of found pattern   */{/* * Currently only simple patterns are supported. */#define BUFSIZE 2096	char			 buf[BUFSIZE+4];	register char		*in_buf, *buf_last_plus_one,				*matched_to, *done_match;	register Es_index	 new_pos, pos, start_pattern = position;	Es_index		 length;	int			 read;	int			 useful_bufsize = BUFSIZE;	*first = ES_CANNOT_SET;	if (flags & EV_FIND_RE)	    goto Return;	matched_to = pattern;	done_match = pattern + pattern_length;	if (flags & EV_FIND_BACKWARD) {	    struct es_buf_object	esbuf;	    esbuf.esh = esh;	    esbuf.buf = buf;	    esbuf.sizeof_buf = BUFSIZE;	    esbuf.first = ES_INFINITY;	    start_pattern--;Init_Backward:	    FOREVER {		if (start_pattern < 0)		    goto Return;		switch (es_make_buf_include_index(&esbuf,			start_pattern+(long)(pattern_length-1), BUFSIZE-1)) {		  case 0:		    pos = esbuf.first;		    read = esbuf.last_plus_one - pos;		    in_buf = buf + (start_pattern-pos);		    FOREVER {			ASSERT(in_buf <= buf + read);			if (*matched_to++ != *in_buf++) {			    start_pattern--;			} else if (matched_to == done_match) {			    if (--count == 0) {				*first = start_pattern;				*last_plus_one = pos + (in_buf-buf);				goto Return;			    }			    start_pattern -= pattern_length;				/* Overlap matches are not found. */			} else			    continue;			matched_to = pattern;			if (start_pattern >= pos) {			    in_buf = buf + (start_pattern-pos);			} else {			    /*			     * We need to back up as start_pattern is not			     *   in the current buffer.			     */			    goto Init_Backward;			}		    }		    break;		  case 1:		    length = es_get_length(esh);		    if ((start_pattern+pattern_length-1) < length)			goto Return;		    goto Skip_Backward;		  case 2:		    /* Gap in entity indices (hopefully due to wrap-around		     *   of bounded stream).  Move start_pattern over gap.		     * NOTE: this implies that we never match a pattern		     *   against a span of indices containing a gap.		     */		    length = esbuf.last_plus_one;Skip_Backward:		    /*		     * Following test is paranoia to detect infinite loop		     *   in "impossible" case.		     */		    if (esbuf.first == ES_CANNOT_SET)			goto Return;		    esbuf.first = ES_CANNOT_SET;		    start_pattern = length-pattern_length;		    break;		}	    }	} else {	    if (pattern_length == 1 && count == 1)		useful_bufsize = 256;Init_Forward:	    new_pos = start_pattern;	    es_set_position(esh, new_pos);	    FOREVER {		pos = new_pos;		new_pos = es_read(esh, useful_bufsize, buf, &read);		if (read == 0) {		    if (pos == new_pos)			goto Return;		    /* Gap in entity indices (hopefully due to wrap-around		     *   of bounded stream).  Move start_pattern over gap.		     * NOTE: this implies that we never match a pattern		     *   against a span of indices containing a gap.		     */		    start_pattern = new_pos;		    goto Init_Forward;		} else {		    in_buf = buf;		    buf_last_plus_one = buf + read;		    FOREVER {			if (*matched_to++ == *in_buf++) {			    if (matched_to == done_match) {				if (--count == 0) {				    *first = start_pattern;				    *last_plus_one = pos + (in_buf-buf);				    goto Return;				} else {				    matched_to = pattern;				    start_pattern = pos + (in_buf-buf);					/* Overlap matches are not found. */				}			    }			} else {			    matched_to = pattern;			    start_pattern++;			    if (start_pattern >= pos) {				in_buf = buf + (start_pattern-pos);			    } else {				/*				 * We need to back up as start_pattern is not				 *   in the current buffer.				 */				goto Init_Forward;			    }			}			if (in_buf == buf_last_plus_one)			    break;		/* Next buffer */		    }		}	    }	}Return:	return;#undef BUFSIZE}

⌨️ 快捷键说明

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