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

📄 xtext.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
📖 第 1 页 / 共 5 页
字号:
	return ret;}static int inlineget_char_width (GtkXText *xtext, unsigned char *str, int *mbl_ret, int is_mb){	int mbl, width;	switch (xtext->fonttype)	{	case FONT_1BYTE:		width = xtext->fontwidth[(int)*str];		mbl = 1;		break;	case FONT_2BYTE:		width = gdk_text_width (xtext->font, str, 2);		mbl = 2;		break;	default: /* FONT_SET: */		if (!is_mb)		{			width = xtext->fontwidth[(int)*str];			mbl = 1;		} else		{			mbl = charlen (str);			if (mbl == 1)				width = xtext->fontwidth[(int)*str];			else if (mbl > 0)				width = gdk_text_width (xtext->font, str, mbl);			else				width = 0;		}		break;	}	*mbl_ret = mbl;	return width;}static intfind_x (GtkXText *xtext, textentry *ent, unsigned char *text, int x, int indent){	int xx = indent;	int i = 0;	int col = FALSE;	int nc = 0;	unsigned char *orig = text;	int mbl;	while (*text)	{		mbl = 1;		if ((col && isdigit (*text) && nc < 2) ||			 (col && *text == ',' && isdigit (*(text+1)) && nc < 3))		{			nc++;			if (*text == ',')				nc = 0;			text++;		} else		{			col = FALSE;			switch (*text)			{			case ATTR_COLOR:				col = TRUE;				nc = 0;			case ATTR_BEEP:			case ATTR_RESET:			case ATTR_REVERSE:			case ATTR_BOLD:			case ATTR_UNDERLINE:				text++;				break;			default:				xx += get_char_width (xtext, text, &mbl, ent->mb);				text += mbl;				if (xx >= x)					return i + (orig - ent->str);			}		}		i += mbl;		if (text - orig >= ent->str_len)			return ent->str_len;	}	return ent->str_len;}static intgtk_xtext_find_x (GtkXText * xtext, int x, textentry * ent, int subline,						int line, int *out_of_bounds){	int indent;	unsigned char *str;	if (subline < 1)		indent = ent->indent;	else		indent = xtext->indent;	if (line > xtext->adj->page_size || line < 0)		return 0;	if (xtext->grid_offset[line] > ent->str_len)		return 0;	if (xtext->grid_offset[line] < 0)		return 0;	str = ent->str + xtext->grid_offset[line];	if (x < indent)	{		*out_of_bounds = 1;		return (str - ent->str);	}	*out_of_bounds = 0;	return find_x (xtext, ent, str, x, indent);}static textentry *gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off,							int *out_of_bounds){	textentry *ent;	int line;	int subline;	int win_width;	gdk_window_get_size (GTK_WIDGET (xtext)->window, &win_width, 0);	win_width -= MARGIN;	line = (y - xtext->font->descent + xtext->pixel_offset) / xtext->fontsize;	subline = xtext->pagetop_subline;	ent = gtk_xtext_nth (xtext, xtext->pagetop_ent, line, &subline);	if (!ent)		return 0;	if (off)		*off = gtk_xtext_find_x (xtext, x, ent, subline, line, out_of_bounds);	return ent;}static gintgtk_xtext_expose (GtkWidget * widget, GdkEventExpose * event){	GtkXText *xtext = GTK_XTEXT (widget);	textentry *ent_start, *ent_end;	if (xtext->skip_exposure)	{		xtext->skip_exposure = FALSE;		return FALSE;	}	if (event->area.x == 0 && event->area.y == 0 &&		 event->area.height == widget->allocation.height &&		 event->area.width == widget->allocation.width)	{		gtk_xtext_render_page (xtext);		return FALSE;	}	gdk_draw_rectangle (xtext->draw_buf, xtext->bgc, 1,							  event->area.x, event->area.y,							  event->area.width, event->area.height);	ent_start = gtk_xtext_find_char (xtext, event->area.x, event->area.y,												NULL, NULL);	ent_end = gtk_xtext_find_char (xtext, event->area.x + event->area.width,						event->area.y + event->area.height + xtext->font->descent,						NULL, NULL);	xtext->skip_fills = TRUE;	xtext->skip_border_fills = TRUE;	gtk_xtext_render_ents (xtext, ent_start, ent_end, TRUE);	xtext->skip_fills = FALSE;	xtext->skip_border_fills = FALSE;	gtk_xtext_draw_sep (xtext, -1);	return FALSE;}static voidgtk_xtext_selection_render (GtkXText *xtext, textentry *start_ent,									 int start_offset, textentry *end_ent,									 int end_offset){	textentry *ent, *ent2;	xtext->skip_border_fills = TRUE;	xtext->skip_stamp = TRUE;	/* marking downward? */	if (xtext->last_ent_start == start_ent &&			xtext->last_offset_start == start_offset)	{		ent = start_ent;		while (ent)		{			if (ent == xtext->last_ent_end)			{				gtk_xtext_render_ents (xtext, ent, end_ent, TRUE);				break;			}			if (ent == end_ent)			{				gtk_xtext_render_ents (xtext, ent, xtext->last_ent_end, TRUE);				break;			}			ent = ent->next;		}	}	/* marking upward? */	else if (xtext->last_ent_end == end_ent &&				xtext->last_offset_end == end_offset)	{		ent = start_ent;		ent2 = xtext->last_ent_start;		do		{			if (ent == xtext->last_ent_start)			{				gtk_xtext_render_ents (xtext, start_ent, ent, TRUE);				break;			}			if (ent2 == start_ent)			{				gtk_xtext_render_ents (xtext, xtext->last_ent_start, start_ent, TRUE);				break;			}			if (ent)				ent = ent->next;			if (ent2)				ent2 = ent2->next;		}		while (ent || ent2);	}	else	/* cross-over mark */	{		gtk_xtext_render_ents (xtext, xtext->last_ent_start, xtext->last_ent_end, TRUE);		gtk_xtext_render_ents (xtext, start_ent, end_ent, TRUE);	}	xtext->last_ent_start = start_ent;	xtext->last_ent_end = end_ent;	xtext->last_offset_start = start_offset;	xtext->last_offset_end = end_offset;	xtext->skip_border_fills = FALSE;	xtext->skip_stamp = FALSE;}static voidgtk_xtext_selection_draw (GtkXText * xtext, GdkEventMotion * event){	textentry *ent;	textentry *ent_end;	textentry *ent_start;	int offset_start;	int offset_end;	int low_x;	int low_y;	int high_x;	int high_y;	int tmp;	if (xtext->select_start_y > xtext->select_end_y)	{		low_x = xtext->select_end_x;		low_y = xtext->select_end_y;		high_x = xtext->select_start_x;		high_y = xtext->select_start_y;	} else	{		low_x = xtext->select_start_x;		low_y = xtext->select_start_y;		high_x = xtext->select_end_x;		high_y = xtext->select_end_y;	}	ent_start = gtk_xtext_find_char (xtext, low_x, low_y, &offset_start, &tmp);	ent_end = gtk_xtext_find_char (xtext, high_x, high_y, &offset_end, &tmp);	if (ent_start && !ent_end)	{		ent_end = xtext->text_last;		offset_end = ent_end->str_len;	}	if (!ent_start || !ent_end)	{		if (xtext->adj->value != xtext->old_value)			gtk_xtext_render_page (xtext);		return;	}	gtk_xtext_selection_clear (xtext);	/* marking less than a complete line? */	if (ent_start == ent_end)	{		ent_start->mark_start = MIN (offset_start, offset_end);		ent_start->mark_end = MAX (offset_end, offset_start);		if (offset_start == offset_end)		{			if (xtext->fonttype == FONT_SET)			{				int mbl;				mbl = charlen (ent_start->str + offset_start);				if (0 < mbl)					ent_start->mark_end += mbl;			} else			{				ent_start->mark_end++;			}		}	} else	{		ent_start->mark_start = offset_start;		ent_start->mark_end = ent_start->str_len;		if (offset_end != 0)		{			ent_end->mark_start = 0;			ent_end->mark_end = offset_end;		}	}	if (ent_start != ent_end)	{		ent = ent_start->next;		while (ent && ent != ent_end)		{			ent->mark_start = 0;			ent->mark_end = ent->str_len;			ent = ent->next;		}	}	/* has the selection changed? Dont render unless necessary */	if (xtext->last_ent_start == ent_start &&		 xtext->last_ent_end == ent_end &&		 xtext->last_offset_start == offset_start &&		 xtext->last_offset_end == offset_end)		return;	gtk_xtext_selection_render (xtext, ent_start, offset_start, ent_end, offset_end);}static gintgtk_xtext_scrolldown_timeout (GtkXText * xtext){	int p_y, win_height;	gdk_window_get_pointer (GTK_WIDGET (xtext)->window, 0, &p_y, 0);	gdk_window_get_size (GTK_WIDGET (xtext)->window, 0, &win_height);	if (p_y > win_height &&		 xtext->adj->value < (xtext->adj->upper - xtext->adj->page_size))	{		xtext->adj->value++;		gtk_adjustment_changed (xtext->adj);		gtk_xtext_render_page (xtext);		return 1;	}	xtext->scroll_tag = 0;	return 0;}static gintgtk_xtext_scrollup_timeout (GtkXText * xtext){	int p_y;	gdk_window_get_pointer (GTK_WIDGET (xtext)->window, 0, &p_y, 0);	if (p_y < 0 && xtext->adj->value > 0.0)	{		xtext->adj->value--;		gtk_adjustment_changed (xtext->adj);		gtk_xtext_render_page (xtext);		return 1;	}	xtext->scroll_tag = 0;	return 0;}static voidgtk_xtext_selection_update (GtkXText * xtext, GdkEventMotion * event, int p_y){	int win_height;	int moved;	gdk_window_get_size (GTK_WIDGET (xtext)->window, 0, &win_height);	/* selecting past top of window, scroll up! */	if (p_y < 0 && xtext->adj->value >= 0)	{		if (!xtext->scroll_tag)			xtext->scroll_tag = g_timeout_add (100,															(GSourceFunc)														 	gtk_xtext_scrollup_timeout,															xtext);		return;	}	/* selecting past bottom of window, scroll down! */	if (p_y > win_height &&		 xtext->adj->value < (xtext->adj->upper - xtext->adj->page_size))	{		if (!xtext->scroll_tag)			xtext->scroll_tag = g_timeout_add (100,															(GSourceFunc)															gtk_xtext_scrolldown_timeout,															xtext);		return;	}	moved = xtext->adj->value - xtext->select_start_adj;	xtext->select_start_y -= (moved * xtext->fontsize);	xtext->select_start_adj = xtext->adj->value;	gtk_xtext_selection_draw (xtext, event);}static char *gtk_xtext_get_word (GtkXText * xtext, int x, int y, textentry ** ret_ent,						  int *ret_off, int *ret_len){	textentry *ent;	int offset;	unsigned char *str;	unsigned char *word;	int len;	int out_of_bounds;	ent = gtk_xtext_find_char (xtext, x, y, &offset, &out_of_bounds);	if (!ent)		return 0;	if (out_of_bounds)		return 0;	if (offset == ent->str_len)		return 0;	if (offset < 1)		return 0;	offset--;	str = ent->str + offset;	while (!is_del (*str) && str != ent->str)		str--;	word = str + 1;	len = 0;	str = word;	while (!is_del (*str) && len != ent->str_len)	{		str++;		len++;	}	if (ret_ent)		*ret_ent = ent;	if (ret_off)		*ret_off = word - ent->str;	if (ret_len)		*ret_len = str - word;	return gtk_xtext_strip_color (word, len, xtext->scratch_buffer, NULL, xtext->fonttype, NULL);}#ifdef MOTION_MONITORstatic gintgtk_xtext_leave_notify (GtkWidget * widget, GdkEventCrossing * event){	GtkXText *xtext = GTK_XTEXT (widget);	if (xtext->cursor_hand)	{		xtext->hilight_start = -1;		xtext->hilight_end = -1;		xtext->cursor_hand = FALSE;		gdk_window_set_cursor (widget->window, 0);		xtext->skip_border_fills = TRUE;		xtext->do_underline_fills_only = TRUE;		gtk_xtext_render_ents (xtext, xtext->hilight_ent, NULL, FALSE);		xtext->skip_border_fills = FALSE;		xtext->do_underline_fills_only = FALSE;		xtext->hilight_ent = NULL;	}	return FALSE;}#endifstatic gintgtk_xtext_motion_notify (GtkWidget * widget, GdkEventMotion * event){	GtkXText *xtext = GTK_XTEXT (widget);	int tmp, x, y, offset, len;	unsigned char *word;	textentry *word_ent, *old_ent;	gdk_window_get_pointer (widget->window, &x, &y, 0);	if (xtext->moving_separator)	{		if (x < (3 * widget->allocation.width) / 5 && x > 15)		{			tmp = xtext->indent;			xtext->indent = x;			gtk_xtext_fix_indent (xtext);			if (tmp != xtext->indent)			{				gtk_xtext_recalc_widths (xtext, FALSE);				if (xtext->scrollbar_down)					gtk_adjustment_set_value (xtext->adj, xtext->adj->upper -													  xtext->adj->page_size);				if (!xtext->io_tag)					xtext->io_tag = g_timeout_add (REFRESH_TIMEOUT,																(GSourceFunc)																gtk_xtext_adjustment_timeout,																xtext);			}		}		return FALSE;	}	if (xtext->button_down)	{		gtk_grab_add (widget);		/*gdk_pointer_grab (widget->window, TRUE,									GDK_BUTTON_RELEASE_MASK |									GDK_BUTTON_MOTION_MASK, NULL, NULL, 0);*/		xtext->select_end_x = x;		xtext->select_end_y = y;		gtk_xtext_selection_update (xtext, event, y);		return FALSE;	}#ifdef MOTION_MONITOR	if (xtext->urlcheck_function == NULL)		return FALSE;	word = gtk_xtext_get_word (xtext, x, y, &word_ent, &offset, &len);	if (word)	{		if (xtext->urlcheck_function (GTK_WIDGET (xtext), word) > 0)		{			if (!xtext->cursor_hand ||				 xtext->hilight_ent != word_ent ||				 xtext->hilight_start != offset ||				 xtext->hilight_end != offset + len)			{				if (!xtext->cursor_hand)				{					gdk_window_set_cursor (GTK_WIDGET (xtext)->window,											  		xtext->hand_cursor);					xtext->cursor_hand = TRUE;				}				old_ent = xtext->hilight_ent;				xtext->hilight_ent = word_ent;				xtext->hilight_start = offset;				xtext->hilight_end = offset + len;				xtext->skip_border_fills = TRUE;				xtext->do_underline_fills_only = TRUE;

⌨️ 快捷键说明

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