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

📄 xtext.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
📖 第 1 页 / 共 5 页
字号:
/* X-Chat * Copyright (C) 1998 Peter Zelezny. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * ========================================================================= * * xtext, the text widget used by X-Chat. * * By Peter Zelezny <zed@linux.com>. * Some functions used from Zvt and Eterm (transparency stuff). * */#define XCHAT							/* using xchat */#define REFRESH_TIMEOUT 20#define WORDWRAP_LIMIT 24#define TINT_VALUE 195				/* 195/255 of the brightness. */#define MOTION_MONITOR 1			/* URL hilights. */#define MARGIN 2						/* dont touch. */#define SMOOTH_SCROLL#ifdef XCHAT#include "../../config.h"			/* can define USE_XLIB here */#else#define USE_XLIB#endif#include <string.h>#include <ctype.h>#include <stdlib.h>#include <time.h>#include <gtk/gtkmain.h>#include <gtk/gtksignal.h>#include <gtk/gtkselection.h>#ifdef USE_XLIB#include <gdk/gdkx.h>#include <X11/Xlib.h>#include <X11/Xatom.h>#endif#include "xtext.h"#ifdef USE_GDK_PIXBUF#include <gdk-pixbuf/gdk-pixbuf.h>#endif#undef GTK_WIDGET#define GTK_WIDGET(n) ((GtkWidget*)n)#undef GTK_OBJECT#define GTK_OBJECT(n) ((GtkObject*)n)#undef GTK_OBJECT_CLASS#define GTK_OBJECT_CLASS(n) ((GtkObjectClass*)n)#ifdef WIN32#define charlen(str) g_utf8_skip[*(guchar *)(str)]#else#define charlen(str) mblen(str, MB_CUR_MAX)#endif/* is delimiter */#define is_del(c) \	(c == ' ' || c == '\n' || c == ')' || c == '(' || \	 c == '>' || c == '<' || c == ATTR_RESET || c == ATTR_BOLD || c == 0)static GtkWidgetClass *parent_class = NULL;enum{	WORD_CLICK,	LAST_SIGNAL};/* values for selection info */enum{	TARGET_STRING,	TARGET_TEXT,	TARGET_COMPOUND_TEXT};static guint xtext_signals[LAST_SIGNAL] = { 0 };#ifdef XCHATchar *nocasestrstr (char *text, char *tofind);	/* util.c */int get_stamp_str (time_t, char *, int);#endifstatic void gtk_xtext_render_page (GtkXText * xtext);static void gtk_xtext_calc_lines (GtkXText * xtext, int);#ifdef USE_XLIBstatic void gtk_xtext_load_trans (GtkXText * xtext);static void gtk_xtext_free_trans (GtkXText * xtext);#endifstatic textentry *gtk_xtext_nth (GtkXText * xtext, textentry * start_ent,											int line, int *subline);static gint gtk_xtext_selection_kill (GtkWidget * widget,												  GdkEventSelection * event);static void gtk_xtext_selection_get (GtkWidget * widget,												 GtkSelectionData * selection_data_ptr,												 guint info, guint time);static int gtk_xtext_text_width (GtkXText * xtext, unsigned char *text,											int len, int *mb_ret);static void gtk_xtext_adjustment_changed (GtkAdjustment * adj,														GtkXText * xtext);static void gtk_xtext_draw_sep (GtkXText * xtext, int height);static void gtk_xtext_render_ents (GtkXText * xtext, textentry *, textentry *,											  int);static void gtk_xtext_recalc_widths (GtkXText * xtext, int);static void gtk_xtext_fix_indent (GtkXText * xtext);static char *gtk_xtext_conv_color (unsigned char *text, int len, char *outbuf, int *newlen, int fonttype);static guint gtk_xtext_get_type (void);/* some utility functions first */#ifndef XCHAT	/* xchat has this in util.c */static char *nocasestrstr (char *s, char *wanted){   register const size_t len = strlen (wanted);   if (len == 0)     return (char *)s;   while (toupper(*s) != toupper(*wanted) || strncasecmp (s, wanted, len))     if (*s++ == '\0')       return (char *)NULL;   return (char *)s;   }#endifstatic voidxtext_set_fg (GdkGC *gc, gulong pixel){	GdkColor col;	col.pixel = pixel;	gdk_gc_set_foreground (gc, &col);}static voidxtext_set_bg (GdkGC *gc, gulong pixel){	GdkColor col;	col.pixel = pixel;	gdk_gc_set_background (gc, &col);}static voidgtk_xtext_init (GtkXText * xtext){	xtext->old_value = -1;	xtext->pixmap = NULL;	xtext->text_first = NULL;	xtext->text_last = NULL;	xtext->last_ent_start = NULL;	xtext->last_ent_end = NULL;	xtext->io_tag = 0;	xtext->add_io_tag = 0;	xtext->scroll_tag = 0;/*   xtext->frozen = 0;*/	xtext->num_lines = 0;	xtext->max_lines = 0;	xtext->col_back = 19;	xtext->col_fore = 18;	xtext->nc = 0;	xtext->pixel_offset = 0;	xtext->scrollbar_down = TRUE;	xtext->bold = FALSE;	xtext->underline = FALSE;	xtext->reverse = FALSE;	xtext->time_stamp = FALSE;	xtext->font = NULL;	xtext->error_function = NULL;	xtext->urlcheck_function = NULL;	xtext->color_paste = FALSE;	xtext->skip_fills = FALSE;	xtext->skip_border_fills = FALSE;	xtext->skip_stamp = FALSE;	xtext->do_underline_fills_only = FALSE;	xtext->jump_out_early = FALSE;	xtext->recycle = FALSE;	xtext->tint_red = xtext->tint_green = xtext->tint_blue = TINT_VALUE;	xtext->adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 0, 1, 0, 0);	gtk_object_ref ((GtkObject *) xtext->adj);	gtk_object_sink ((GtkObject *) xtext->adj);	gtk_signal_connect (GTK_OBJECT (xtext->adj), "value_changed",							  GTK_SIGNAL_FUNC (gtk_xtext_adjustment_changed), xtext);	gtk_signal_connect (GTK_OBJECT (xtext), "selection_clear_event",							  GTK_SIGNAL_FUNC (gtk_xtext_selection_kill), xtext);	{		static const GtkTargetEntry targets[] = {			{ "STRING", 0, TARGET_STRING },			{ "TEXT",   0, TARGET_TEXT }, 			{ "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT }		};		static const gint n_targets = sizeof (targets) / sizeof (targets[0]);		gtk_selection_add_targets (GTK_WIDGET (xtext), GDK_SELECTION_PRIMARY,											targets, n_targets);		gtk_selection_add_targets (GTK_WIDGET (xtext),											gdk_atom_intern ("CLIPBOARD", FALSE),											targets, n_targets);	}	gtk_signal_connect (GTK_OBJECT (xtext), "selection_get",							  GTK_SIGNAL_FUNC (gtk_xtext_selection_get), xtext);}static voidgtk_xtext_adjustment_set (GtkXText * xtext, int fire_signal){	GtkAdjustment *adj = xtext->adj;	adj->lower = 0;	adj->upper = xtext->num_lines;	adj->page_size =		(GTK_WIDGET (xtext)->allocation.height -		 xtext->font->descent) / xtext->fontsize;	adj->page_increment = adj->page_size;	if (adj->value > adj->upper - adj->page_size)		adj->value = adj->upper - adj->page_size;	if (fire_signal)		gtk_adjustment_changed (adj);}static gintgtk_xtext_adjustment_timeout (GtkXText * xtext){	gtk_xtext_render_page (xtext);	xtext->io_tag = 0;	return 0;}static voidgtk_xtext_adjustment_changed (GtkAdjustment * adj, GtkXText * xtext){/*   if (xtext->frozen)      return;*/#ifdef SMOOTH_SCROLL	if (xtext->old_value != xtext->adj->value)#else	if ((int) xtext->old_value != (int) xtext->adj->value)#endif	{		if (xtext->adj->value >= xtext->adj->upper - xtext->adj->page_size)			xtext->scrollbar_down = TRUE;		else			xtext->scrollbar_down = FALSE;		if (xtext->adj->value + 1 == xtext->old_value ||			 xtext->adj->value - 1 == xtext->old_value)	/* clicked an arrow? */		{			if (xtext->io_tag)			{				g_source_remove (xtext->io_tag);				xtext->io_tag = 0;			}			gtk_xtext_render_page (xtext);		} else		{			if (!xtext->io_tag)				xtext->io_tag = g_timeout_add (REFRESH_TIMEOUT,															(GSourceFunc)															gtk_xtext_adjustment_timeout,															xtext);		}	}	xtext->old_value = adj->value;}GtkWidget *gtk_xtext_new (int indent, int separator){	GtkXText *xtext;	xtext = gtk_type_new (gtk_xtext_get_type ());	xtext->indent = indent;	xtext->separator = separator;	xtext->wordwrap = FALSE;	return GTK_WIDGET (xtext);}static voidgtk_xtext_destroy (GtkObject * object){	GtkXText *xtext = GTK_XTEXT (object);	textentry *ent, *next;	if (xtext->add_io_tag)	{		g_source_remove (xtext->add_io_tag);		xtext->add_io_tag = 0;	}	if (xtext->scroll_tag)	{		g_source_remove (xtext->scroll_tag);		xtext->scroll_tag = 0;	}	if (xtext->io_tag)	{		g_source_remove (xtext->io_tag);		xtext->io_tag = 0;	}	if (xtext->pixmap)	{#ifdef USE_XLIB		if (xtext->transparent)			gtk_xtext_free_trans (xtext);		else#endif			gdk_pixmap_unref (xtext->pixmap);		xtext->pixmap = NULL;	}	if (xtext->font)	{		gdk_font_unref (xtext->font);		xtext->font = NULL;	}	if (xtext->adj)	{		gtk_signal_disconnect_by_data (GTK_OBJECT (xtext->adj), xtext);		gtk_object_unref (GTK_OBJECT (xtext->adj));		xtext->adj = NULL;	}	if (xtext->bgc)	{		gdk_gc_destroy (xtext->bgc);		xtext->bgc = NULL;	}	if (xtext->fgc)	{		gdk_gc_destroy (xtext->fgc);		xtext->fgc = NULL;	}	if (xtext->light_gc)	{		gdk_gc_destroy (xtext->light_gc);		xtext->light_gc = NULL;	}	if (xtext->dark_gc)	{		gdk_gc_destroy (xtext->dark_gc);		xtext->dark_gc = NULL;	}	if (xtext->hand_cursor)	{		gdk_cursor_destroy (xtext->hand_cursor);		xtext->hand_cursor = NULL;	}	ent = xtext->text_first;	while (ent)	{		next = ent->next;		free (ent);		ent = next;	}	xtext->text_first = NULL;	if (GTK_OBJECT_CLASS (parent_class)->destroy)		(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);}static voidgtk_xtext_realize (GtkWidget * widget){	GtkXText *xtext;	GdkWindowAttr attributes;	GdkGCValues val;	GdkColor col;	GdkColormap *cmap;	GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);	xtext = GTK_XTEXT (widget);	attributes.x = widget->allocation.x;	attributes.y = widget->allocation.y;	attributes.width = widget->allocation.width;	attributes.height = widget->allocation.height;	attributes.wclass = GDK_INPUT_OUTPUT;	attributes.window_type = GDK_WINDOW_CHILD;	attributes.event_mask = gtk_widget_get_events (widget) |		GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK#ifdef MOTION_MONITOR		| GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK;#else		| GDK_POINTER_MOTION_MASK;#endif	cmap = gtk_widget_get_colormap (widget);	attributes.colormap = cmap;	attributes.visual = gtk_widget_get_visual (widget);	widget->window = gdk_window_new (widget->parent->window, &attributes,												GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL |												GDK_WA_COLORMAP);	gdk_window_set_user_data (widget->window, widget);	xtext->depth = gdk_window_get_visual (widget->window)->depth;	val.subwindow_mode = GDK_INCLUDE_INFERIORS;	val.graphics_exposures = 0;	xtext->bgc = gdk_gc_new_with_values (widget->window, &val,													 GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);	xtext->fgc = gdk_gc_new_with_values (widget->window, &val,													 GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);	xtext->light_gc = gdk_gc_new_with_values (widget->window, &val,											GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);	xtext->dark_gc = gdk_gc_new_with_values (widget->window, &val,											GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW);	/* for the separator bar (light) */	col.red = 0xffff; col.green = 0xffff; col.blue = 0xffff;	gdk_color_alloc (cmap, &col);	gdk_gc_set_foreground (xtext->light_gc, &col);	/* for the separator bar (dark) */	col.red = 0x8e38; col.green = 0x8e38; col.blue = 0x9f38;	gdk_color_alloc (cmap, &col);	gdk_gc_set_foreground (xtext->dark_gc, &col);	if (xtext->fonttype != FONT_SET && xtext->font != NULL)		gdk_gc_set_font (xtext->fgc, xtext->font);	xtext_set_fg (xtext->fgc, xtext->palette[18]);	xtext_set_bg (xtext->fgc, xtext->palette[19]);	xtext_set_fg (xtext->bgc, xtext->palette[19]);#ifdef USE_XLIB	if (xtext->transparent)	{		gtk_xtext_load_trans (xtext);	} else if (xtext->pixmap)	{		gdk_gc_set_tile (xtext->bgc, xtext->pixmap);		gdk_gc_set_ts_origin (xtext->bgc, 0, 0);		gdk_gc_set_fill (xtext->bgc, GDK_TILED);	}#else	if (xtext->pixmap)	{		gdk_gc_set_tile (xtext->bgc, xtext->pixmap);		gdk_gc_set_ts_origin (xtext->bgc, 0, 0);		gdk_gc_set_fill (xtext->bgc, GDK_TILED);	}#endif	xtext->hand_cursor = gdk_cursor_new (GDK_HAND1);	gdk_window_set_back_pixmap (widget->window, NULL, FALSE);	/* draw directly to window */	xtext->draw_buf = widget->window;	if (xtext->auto_indent)		xtext->indent = 1;}static voidgtk_xtext_size_request (GtkWidget * widget, GtkRequisition * requisition){	requisition->width = GTK_XTEXT (widget)->fontwidth['Z'] * 20;	requisition->height = (GTK_XTEXT (widget)->fontsize * 10) + 3;}static voidgtk_xtext_size_allocate (GtkWidget * widget, GtkAllocation * allocation){	GtkXText *xtext = GTK_XTEXT (widget);	if (allocation->width == widget->allocation.width &&		 allocation->height == widget->allocation.height)		return;	widget->allocation = *allocation;	if (GTK_WIDGET_REALIZED (widget))	{		gdk_window_move_resize (widget->window, allocation->x, allocation->y,										allocation->width, allocation->height);		gtk_xtext_calc_lines (xtext, FALSE);#ifdef USE_XLIB		if (xtext->transparent && xtext->shaded)		{			gtk_xtext_free_trans (xtext);			gtk_xtext_load_trans (xtext);		}#endif	}}static gintgtk_xtext_idle (GtkXText *xtext){	xtext->skip_exposure = FALSE;	return FALSE;}static voidgtk_xtext_draw (GtkWidget * widget, GdkRectangle * area){	GtkXText *xtext = GTK_XTEXT (widget);#ifdef USE_XLIB	int x, y;	if (xtext->transparent)	{		gdk_window_get_origin (widget->window, &x, &y);		/* update transparency only if it moved */		if (xtext->last_win_x != x || xtext->last_win_y != y)		{			xtext->last_win_x = x;			xtext->last_win_y = y;			if (xtext->shaded)			{				xtext->recycle = TRUE;				gtk_xtext_load_trans (xtext);				xtext->recycle = FALSE;			} else			{				gtk_xtext_free_trans (xtext);				gtk_xtext_load_trans (xtext);			}		}	}#endif	gtk_xtext_render_page (xtext);	if (xtext->scrollbar_down)		gtk_adjustment_set_value (xtext->adj,											xtext->adj->upper - xtext->adj->page_size);	xtext->skip_exposure = TRUE;	gtk_idle_add ((GtkFunction)gtk_xtext_idle, xtext);}static intgtk_xtext_selection_clear (GtkXText * xtext){	textentry *ent;	int ret = 0;	ent = xtext->last_ent_start;	while (ent)	{		if (ent->mark_start != -1)			ret = 1;		ent->mark_start = -1;		ent->mark_end = -1;		if (ent == xtext->last_ent_end)			break;		ent = ent->next;	}

⌨️ 快捷键说明

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