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

📄 fe-gtk.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
字号:
/* 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 */#include <stdio.h>#include <string.h>#include "../../config.h"#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <stdlib.h>#include <unistd.h>#include "fe-gtk.h"#include "../common/xchat.h"#include "../common/fe.h"#include "../common/util.h"#include "../common/text.h"#include "../common/cfgfiles.h"#include "../common/xchatc.h"#include "gtkutil.h"#include "maingui.h"#include "pixmaps.h"#include "xtext.h"#include "palette.h"#include "menu.h"#include "notifygui.h"#include "textgui.h"#include "fkeys.h"#include "urlgrab.h"#ifdef USE_PANEL#include "panel.h"#include <applet-widget.h>#endif#ifdef USE_XLIB#include <gdk/gdkx.h>#include <gtk/gtkinvisible.h>#endif#ifdef USE_GDK_PIXBUF#include <gdk-pixbuf/gdk-pixbuf.h>#endifGdkFont *font_normal;GdkFont *dialog_font_normal;GdkPixmap *channelwin_pix;GdkPixmap *dialogwin_pix;extern void open_server_list (GtkWidget *wid, gpointer sess, int dontshow);extern void serverlist_autoconnect (struct session *sess, int);#ifdef USE_XLIBstatic GtkWidget *proxy_invisible;static voidredraw_trans_xtexts (void){	GSList *list = sess_list;	struct session *sess;	while (list)	{		sess = (struct session *) list->data;#ifdef USE_ZVT		if (sess->type == SESS_SHELL)		{			menu_newshell_set_palette (sess);			gtk_widget_queue_draw (sess->gui->textgad);		} else#endif			if (GTK_XTEXT (sess->gui->textgad)->transparent)				gtk_xtext_refresh (GTK_XTEXT (sess->gui->textgad), 1);		list = list->next;	}}static gbooleanhandle_property_notify (GtkWidget *widget, GdkEventProperty *event,								gpointer user_data){	static Atom prop = None;	if (prop == None)		prop = XInternAtom (GDK_DISPLAY (), "_XROOTPMAP_ID", True);	if (event->atom == prop)		redraw_trans_xtexts ();	return FALSE;}#endifintfe_args (int argc, char *argv[]){#ifdef USE_GNOME	struct poptOption options[] = {		{"cfgdir", 'd', POPT_ARG_STRING, 0, 0, _("Config dir"), 0},		{"noauto", 'a', POPT_ARG_NONE, 0, 0, _("Don't Auto connect"), 0},#ifdef USE_PANEL		{"no-panel", 'n', POPT_ARG_NONE, 0, 0, _("Don't use GNOME Panel"), 0},#endif		POPT_AUTOHELP {0, '\0', 0, 0}	};#endif	if (argc > 1)	{		if (!strcasecmp (argv[1], "-a") || !strcasecmp (argv[1], "--noauto"))		{			auto_connect = 0;		}#ifdef USE_PANEL		if (!strcasecmp (argv[1], "-n") || !strcasecmp (argv[1], "--no-panel"))		{			nopanel = TRUE;		}#endif		if (!strcasecmp (argv[1], "-v") || !strcasecmp (argv[1], "--version"))		{			printf (PACKAGE" "VERSION"\n");			return 0;		}#ifndef USE_GNOME#ifdef ENABLE_NLS		bindtextdomain (PACKAGE, PREFIX"/share/locale");		textdomain (PACKAGE);#endif		if (!strcasecmp (argv[1], "-h") || !strcasecmp (argv[1], "--help"))		{			printf(_("%s %s Options:\n\n"					"   --cfgdir <dir> -d\t : use a different config dir\n"					"   --noauto       -a\t : don't auto connect\n"					"   --version      -v\t : show version information\n"                ), PACKAGE, VERSION);			return 0;		}#endif	}#ifdef ENABLE_NLS#ifdef USE_GNOME	bindtextdomain (PACKAGE, PREFIX"/share/locale");	textdomain (PACKAGE);#endif#endif	if (argc > 2)	{		if (!strcasecmp (argv[1], "-d") || !strcasecmp (argv[1], "--cfgdir"))		{			xdir = strdup (argv[2]);			if (xdir[strlen (xdir) - 1] == '/')				xdir[strlen (xdir) - 1] = 0;		}	}#ifndef USE_GNOME	gtk_set_locale ();#endif#ifdef USE_PANEL	if (nopanel)		gnome_init_with_popt_table (argv[0], VERSION, argc, argv, options, 0, 0);	else {		CORBA_Environment ev;		CORBA_exception_init (&ev);		gnome_CORBA_init_with_popt_table (argv[0], VERSION,						  &argc, argv, options, 0, 0,						  GNORBA_INIT_SERVER_FUNC, &ev);		CORBA_exception_free (&ev);	}#else#ifdef USE_GNOME	gnome_init_with_popt_table (argv[0], VERSION, argc, argv, options, 0, 0);#else	gtk_init (&argc, &argv);#endif#endif#ifndef USE_GNOME#ifdef USE_GDK_PIXBUF	gdk_rgb_init();#endif#endif#ifdef USE_XLIB	proxy_invisible = gtk_invisible_new ();	gtk_widget_show (proxy_invisible);	/* Make the root window send events to the invisible proxy widget */	gdk_window_set_user_data (GDK_ROOT_PARENT (), proxy_invisible);		/* Select for PropertyNotify events from the root window */	XSelectInput (GDK_DISPLAY (), GDK_ROOT_WINDOW (), PropertyChangeMask);	gtk_signal_connect (GTK_OBJECT (proxy_invisible), "property-notify-event",							 GTK_SIGNAL_FUNC (handle_property_notify), NULL);#endif	return 1;}GdkFont *my_font_load (char *fontname){	GdkFont *font;	char temp[256];	if (!*fontname)		fontname = "fixed";	if (prefs.use_fontset)		font = gdk_fontset_load (fontname);	else		font = gdk_font_load (fontname);	if (!font)	{		snprintf (temp, sizeof (temp), _("Cannot open font:\n\n%s"), fontname);		gtkutil_simpledialog (temp);		font = gdk_font_load ("fixed");		if (!font)		{			g_error (_("gdk_font_load failed"));			gtk_exit (0);		}	}	return font;}GtkStyle *create_inputgad_style (void){	GtkStyle *style;	style = gtk_style_new ();	gdk_font_unref (style->font);	gdk_font_ref (font_normal);	style->font = font_normal;	style->base[GTK_STATE_NORMAL] = colors[19];	style->bg[GTK_STATE_NORMAL] = colors[19];	style->fg[GTK_STATE_NORMAL] = colors[18];	return style;}voidfe_init (void){	font_normal = my_font_load (prefs.font_normal);	dialog_font_normal = my_font_load (prefs.dialog_font_normal);	palette_load ();	key_init ();	pixmaps_init ();	channelwin_pix = pixmap_load_from_file (prefs.background);	dialogwin_pix = pixmap_load_from_file (prefs.background_dialog);	inputgad_style = create_inputgad_style ();}voidfe_main (void){#ifdef USE_PANEL	if (nopanel)		gtk_main ();	else		applet_widget_gtk_main ();#else	gtk_main ();#endif	/* sleep for 3 seconds so any QUIT messages are not lost. The  */	/* GUI is closed at this point, so the user doesn't even know! */	sleep (3);}voidfe_cleanup (void){	palette_save ();	if (prefs.autosave_url)		url_autosave ();#ifdef USE_PANEL	panel_cleanup ();#endif}voidfe_exit (void){	gtk_main_quit ();}intfe_timeout_add (int interval, void *callback, void *userdata){	return g_timeout_add (interval, (GSourceFunc) callback, userdata);}voidfe_timeout_remove (int tag){	g_source_remove (tag);}voidfe_new_window (struct session *sess){	sess->gui = malloc (sizeof (struct session_gui));	memset (sess->gui, 0, sizeof (struct session_gui));	create_window (sess);}voidfe_new_server (struct server *serv){	serv->gui = malloc (sizeof (struct server_gui));	memset (serv->gui, 0, sizeof (struct server_gui));}static voidnull_this_var (GtkWidget * unused, GtkWidget ** dialog){	*dialog = 0;}voidfe_message (char *msg, int wait){	GtkWidget *dialog;	dialog = gtkutil_simpledialog (msg);	if (wait)	{		gtk_signal_connect (GTK_OBJECT (dialog), "destroy",								  null_this_var, &dialog);		while (dialog)			gtk_main_iteration ();	}}voidfe_input_remove (int tag){	g_source_remove (tag);}intfe_input_add (int sok, int read, int write, int ex, void *func, void *data){	int tag, type = 0;	GIOChannel *channel;#ifdef WIN32	if (read == 3)		channel = g_io_channel_win32_new_fd (sok);	else		channel = g_io_channel_win32_new_socket (sok);#else	channel = g_io_channel_unix_new (sok);#endif	if (read)		type |= G_IO_IN | G_IO_HUP | G_IO_ERR;	if (write)		type |= G_IO_OUT | G_IO_ERR;	if (ex)		type |= G_IO_PRI;	tag = g_io_add_watch (channel, type, (GIOFunc) func, data);	g_io_channel_unref (channel);	return tag;}voidfe_set_topic (struct session *sess, char *topic){	char buf[512];	gtk_entry_set_text (GTK_ENTRY (sess->gui->topicgad), topic);	if (sess->type == SESS_CHANNEL)	{		snprintf (buf, sizeof (buf), _("Topic for %s is: %s"), sess->channel,					 topic);		add_tip (sess->gui->topicgad, buf);	}}voidfe_set_hilight (struct session *sess){#ifdef USE_PANEL	if (sess->gui->panel_button)		gtk_widget_set_style (GTK_BIN (sess->gui->panel_button)->child,									 bluetab_style);#endif	gtk_widget_set_style (sess->gui->changad, bluetab_style);	if (prefs.treeview)		tree_blue_style (sess);}voidfe_update_channel_key (struct session *sess){	if (sess->gui->flag_wid[0])	/* channel mode buttons enabled? */		gtk_entry_set_text ((GtkEntry*)sess->gui->key_entry, sess->channelkey);	fe_set_title (sess);}voidfe_update_channel_limit (struct session *sess){	char tmp[16];	if (sess->gui->flag_wid[0])	/* channel mode buttons enabled? */	{		sprintf (tmp, "%d", sess->limit);		gtk_entry_set_text ((GtkEntry*)sess->gui->limit_entry, tmp);	}}intfe_is_chanwindow (struct server *serv){	if (!serv->gui->chanlist_window)		return 0;	return 1;}intfe_is_banwindow (struct session *sess){   if (!sess->gui->banlist_window)     return 0;   return 1;}voidfe_chan_list_end (struct server *serv){	gtk_widget_set_sensitive (serv->gui->chanlist_refresh, TRUE);}voidfe_notify_update (char *name){	if (name)		update_all_of (name);	else		notify_gui_update ();}voidfe_text_clear (struct session *sess){	gtk_xtext_clear (GTK_XTEXT (sess->gui->textgad));}voidfe_close_window (struct session *sess){	gtk_widget_destroy (sess->gui->window);}static intupdatedate_bar (struct session *sess){	static int type = 0;	static float pos = 0;	if (!is_session (sess))		return 0;	pos += 0.05;	if (pos >= 0.99)	{		if (type == 0)		{			type = 1;			gtk_progress_bar_set_orientation ((GtkProgressBar *) sess->gui->bar,														 GTK_PROGRESS_RIGHT_TO_LEFT);		} else		{			type = 0;			gtk_progress_bar_set_orientation ((GtkProgressBar *) sess->gui->bar,														 GTK_PROGRESS_LEFT_TO_RIGHT);		}		pos = 0.05;	}	gtk_progress_bar_update ((GtkProgressBar *) sess->gui->bar, pos);	return 1;}voidfe_progressbar_start (struct session *sess){	if (sess->gui->op_box)	{		sess->gui->bar = gtk_progress_bar_new ();		gtk_box_pack_start (GTK_BOX (sess->gui->op_box), sess->gui->bar, 0, 0,								  0);		gtk_widget_show (sess->gui->bar);		sess->server->bartag = fe_timeout_add (50, updatedate_bar, sess);	}}voidfe_progressbar_end (struct session *sess){	struct server *serv;	GSList *list = sess_list;	if (sess)	{		serv = sess->server;		while (list)				  /* check all windows that use this server and  *										   * remove the connecting graph, if it has one. */		{			sess = (struct session *) list->data;			if (sess->server == serv && sess->gui->bar)			{				if (GTK_IS_WIDGET (sess->gui->bar))					gtk_widget_destroy (sess->gui->bar);				sess->gui->bar = 0;				fe_timeout_remove (sess->server->bartag);			}			list = list->next;		}	}}voidfe_print_text (struct session *sess, char *text){	int indent;	if (sess->type == SESS_DIALOG)		indent = prefs.dialog_indent_nicks;	else		indent = prefs.indent_nicks;	PrintTextRaw (sess->gui->textgad, text, indent);	if (prefs.limitedtabhighlight && !sess->highlight_tab)		return;	sess->highlight_tab = FALSE;	if (!sess->new_data && !sess->nick_said && sess != current_tab)	{#ifdef USE_PANEL		if (sess->gui->panel_button)			gtk_widget_set_style (GTK_BIN (sess->gui->panel_button)->child,										 redtab_style);#endif		if (prefs.treeview)			tree_red_style (sess);	}	if (!sess->new_data && sess != current_tab &&		 sess->is_tab && !sess->nick_said)	{		sess->new_data = TRUE;		gtk_widget_set_style (sess->gui->changad, redtab_style);	}}voidfe_beep (void){	gdk_beep ();}intfe_is_beep (struct session *sess){	if (GTK_TOGGLE_BUTTON (sess->gui->beepbutton)->active)		return 1;	return 0;}intfe_is_confmode (struct session *sess){	if (GTK_TOGGLE_BUTTON (sess->gui->confbutton)->active)		return 1;	return 0;}voidfe_lastlog (session *sess, session *lastlog_sess, char *sstr){	textentry *ent;	ent = GTK_XTEXT(sess->gui->textgad)->text_first;	if (!ent)	{		PrintText (lastlog_sess, "Search buffer is empty.\n");	} else	{		do		{			if (nocasestrstr (ent->str, sstr))				PrintText (lastlog_sess, ent->str);			ent = ent->next;		}		while (ent);	}}voidfe_set_lag (server *serv, int lag){	GSList *list = sess_list;	session *sess;	gdouble per;	char tip[64];	unsigned long nowtim;	if (lag == -1)	{		if (!serv->lag_sent)			return;		nowtim = make_ping_time ();		lag = (nowtim - serv->lag_sent) / 100000;	}	per = (double)((double)lag / (double)40);	if (per > 1.0)		per = 1.0;	while (list)	{		sess = list->data;		if (sess->server == serv)		{			if (sess->gui->lagometer)			{				gtk_progress_bar_update ((GtkProgressBar *) sess->gui->lagometer, per);			}			if (sess->gui->laginfo)			{				snprintf (tip, sizeof(tip) - 1, "%s%d.%ds",					serv->lag_sent ? "+" : "", lag / 10, lag % 10);				gtk_label_set_text ((GtkLabel *) sess->gui->laginfo, tip);			}		}		list = list->next;	}}voidfe_set_throttle (server *serv){	GSList *list = sess_list;	struct session *sess;	float per;	char tbuf[64];	per = (float) serv->sendq_len / 1024.0;	if (per > 1.0)		per = 1.0;	while (list)	{		sess = list->data;		if (sess->server == serv)		{			if (sess->gui->throttlemeter)			{				gtk_progress_bar_update ((GtkProgressBar *) sess->gui->throttlemeter, per);			}			if (sess->gui->throttleinfo)			{				snprintf (tbuf, sizeof(tbuf) - 1, "%d bytes", serv->sendq_len);				gtk_label_set_text ((GtkLabel *) sess->gui->throttleinfo, tbuf);			}		}		list = list->next;	}}

⌨️ 快捷键说明

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