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

📄 fe-picogui.c

📁 The major functionality added in this release includes: - Rootless mode in X11 - Widget Templt
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 <stdlib.h>#include <string.h>#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <ctype.h>#include "../common/xchat.h"#include "../common/xchatc.h"#include "../common/outbound.h"#include "../common/util.h"#include "../common/fe.h"#include <picogui.h>#include "fe-picogui.h"static GSList *tmr_list;		  /* timer list */static int tmr_list_count;static GSList *se_list;			  /* socket event list */static int se_list_count;static pghandle pgEmptyString, pgPlusHTML;static short int output_type=PG_WIDGET_TERMINAL;static intfieldActivate(struct pgEvent *evt){	char *cmd;	pghandle handle;	handle=pgGetWidget(evt->from, PG_WP_TEXT);	if(handle&&(cmd=strdup(pgGetString(handle))))	{		pgSetWidget(evt->from, PG_WP_TEXT, pgEmptyString, 0);		/* Must do handle_command last because it may be /close */		handle_command (cmd, evt->extra, TRUE, FALSE);		free(cmd);	}	return 0;}static intevtActionsToggle(struct pgEvent *evt){	pgSetWidget(((struct session_gui*)evt->extra)->buttonbox,		    PG_WP_SIZE, pgGetWidget(evt->from,PG_WP_ON) ? -1 : 0,		    0);	return 0;}static intevtCloseMessage(struct pgEvent *evt){	pghandle title=pgGetWidget(evt->from, PG_WP_TEXT);	pgDelete(evt->from);	pgDelete(title);	/* for labels, but not textboxen */	if(evt->extra)		pgDelete((pghandle)evt->extra);	return 1;}static intevtCloseWindow(struct pgEvent *evt){	fe_close_window(evt->extra);	/* 1 prevents us from exiting */	return 1;}static intevtPassFocus(struct pgEvent *evt){	int i;	union pg_client_trigger trig;	pgFocus((pghandle)evt->extra);	/* hope they don't send things with mods.. */	for(i=0;i<evt->e.data.size;i++) {		trig.content.type = PG_TRIGGER_CHAR;		trig.content.u.kbd.key = evt->e.data.pointer[i];		pgInFilterSend(&trig);	}	return 1;}static int done_intro = 0;voidfe_new_window (struct session *sess){	char buf[512];	pghandle scroll, rightbox, boxbar;	sess->gui = malloc(sizeof(struct session_gui));	memset(sess->gui, 0, sizeof(struct session_gui));	/* App */	sess->gui->app = pgRegisterApp(PG_APP_NORMAL, "X-Chat ["VERSION"]", 0);	fe_set_title(sess);	pgBind(0, PG_WE_CLOSE, evtCloseWindow, sess);	sess->gui->input = pgNewWidget(PG_WIDGET_FIELD, 0, 0);	pgSetWidget(0, PG_WP_SIDE, PG_S_BOTTOM, 0);	pgBind(0, PG_WE_ACTIVATE, fieldActivate, sess);	/* Chat area */	if(sess->type!=SESS_DIALOG)	{		rightbox=pgNewWidget(PG_WIDGET_BOX, 0, 0);		pgSetWidget(PGDEFAULT,			    PG_WP_SIDE, PG_S_RIGHT,			    PG_WP_MARGIN, 0,			    0);		/* Add a panelbar to resize the right box with */		boxbar = pgNewWidget(PG_WIDGET_PANELBAR, PG_DERIVE_INSIDE, rightbox);		pgSetWidget(PGDEFAULT,			    PG_WP_SIDE, PG_S_LEFT,			    PG_WP_BIND, rightbox,			    0);		sess->gui->userlistinfo = pgNewWidget(PG_WIDGET_LABEL,PG_DERIVE_INSIDE, 0);		pgSetWidget(PGDEFAULT,			    PG_WP_DIRECTION, PG_DIR_VERTICAL,			    PG_WP_SIDE, PG_S_ALL,			    PG_WP_THOBJ, PGTH_O_PANELBAR,			    PG_WP_TEXT, pgNewString("User List (Drag to resize)"),			    0);		pgNewWidget(PG_WIDGET_BUTTON, PG_DERIVE_BEFORE, 0);		pgSetWidget(PGDEFAULT,			    PG_WP_DIRECTION, PG_DIR_VERTICAL,			    PG_WP_SIDE, PG_S_BOTTOM,			    PG_WP_TEXT, pgNewString("Actions"),			    PG_WP_EXTDEVENTS, PG_EXEV_TOGGLE,			    0);		pgBind(PGDEFAULT, PG_WE_ACTIVATE, evtActionsToggle, sess->gui);		/* scroll bug: the scroll doesn't recalculate correctly		 * when resized. be sure to have the top of the nicklist		 * visible when enlarging */		sess->gui->userscroll=pgNewWidget(PG_WIDGET_SCROLL, PG_DERIVE_AFTER, boxbar);		sess->gui->userlist=pgNewWidget(PG_WIDGET_BOX, 0, 0);		pgSetWidget(0, PG_WP_SIDE, PG_S_ALL, 0);		pgSetWidget (sess->gui->userscroll, PG_WP_BIND,				sess->gui->userlist, 0);		sess->gui->buttonbox = pgNewWidget(PG_WIDGET_BOX, PG_DERIVE_AFTER, boxbar);		pgSetWidget(PGDEFAULT, 			    PG_WP_SIDE, PG_S_BOTTOM,			    PG_WP_SIZE, 0,			    0);		fe_buttons_update(sess);		pgNewWidget(PG_WIDGET_BOX, 0, rightbox);	}	else		pgNewWidget(PG_WIDGET_BOX, 0, 0);	pgSetWidget(0, 		    PG_WP_SIDE, PG_S_ALL,		    PG_WP_MARGIN, 0,		    0);	scroll=pgNewWidget(PG_WIDGET_SCROLL, PG_DERIVE_INSIDE, 0);	pgSetWidget(0, PG_WP_SIDE, PG_S_RIGHT, 0);	/* can be set from command line */	sess->gui->output_type = output_type;	sess->gui->output = pgNewWidget(output_type, 0, 0);	pgSetWidget(scroll, PG_WP_BIND, sess->gui->output, 0);	switch(output_type) {		case PG_WIDGET_TEXTBOX:			/* set the textbox to autoscroll, append HTML */			pgSetWidget(0, PG_WP_AUTOSCROLL, 1,				PG_WP_SIDE, PG_S_ALL, PG_WP_TEXTFORMAT,				pgPlusHTML, 0);			break;		case PG_WIDGET_TERMINAL:			/* make the terminal widget pass focus to the input */			pgBind(0, PG_WE_DATA, evtPassFocus,					(void*)sess->gui->input);			pgSetWidget(0, PG_WP_SIDE, PG_S_ALL,					PG_WP_AUTOSCROLL, 1,					PG_WP_THOBJ, ircterm, 0);			if(prefs.max_lines)				pgSetWidget(0, PG_WP_LINES, prefs.max_lines, 0);			/* hide cursor */			pgWriteData(0, pgFromMemory("\e[?25l", 6));			break;	}	if (!sess->server->front_session)	{		pgFocus(sess->gui->input);		sess->server->front_session = sess;	}	if (!current_tab)		current_tab = sess;	if (done_intro)		return;	done_intro = 1;	snprintf (buf, sizeof (buf),					"\n"				" \017xchat \00310"VERSION"\n"				" \017Running on \00310%s \017glib \00310%d.%d.%d\n"				" \017This binary compiled \00310"__DATE__"\017\n",				get_cpu_str(), 				glib_major_version, glib_minor_version, glib_micro_version);	fe_print_text (sess, buf);	strcpy (buf, "\n\nCompiled in Features\0032:\017 ");#ifdef USE_PERL	strcat (buf, "Perl ");#endif#ifdef USE_PYTHON	strcat (buf, "Python ");#endif#ifdef USE_PLUGIN	strcat (buf, "Plugin ");#endif#ifdef ENABLE_NLS	strcat (buf, "NLS ");#endif#ifdef USE_TRANS	strcat (buf, "Trans ");#endif#ifdef USE_HEBREW	strcat (buf, "Hebrew ");#endif#ifdef USE_OPENSSL	strcat (buf, "OpenSSL ");#endif#ifdef SOCKS	strcat (buf, "Socks5 ");#endif#ifdef HAVE_ICONV	strcat (buf, "JCode ");#endif#ifdef USE_IPV6	strcat (buf, "IPv6 ");#endif	strcat (buf, "\n\n");	fe_print_text (sess, buf);}voidfe_timeout_remove (int tag){	timerevent *te;	GSList *list;	list = tmr_list;	while (list)	{		te = (timerevent *) list->data;		if (te->tag == tag)		{			tmr_list = g_slist_remove (tmr_list, te);			free (te);			return;		}		list = list->next;	}}intfe_timeout_add (int interval, void *callback, void *userdata){	struct timeval now;	timerevent *te = malloc (sizeof (timerevent));	tmr_list_count++;  /* this overflows at 2.2Billion, who cares!! */	te->tag = tmr_list_count;	te->interval = interval;	te->callback = callback;	te->userdata = userdata;	gettimeofday (&now, NULL);	te->next_call = now.tv_sec * 1000 + (now.tv_usec / 1000) + te->interval;	tmr_list = g_slist_prepend (tmr_list, te);	return te->tag;}voidfe_input_remove (int tag){	socketevent *se;	GSList *list;	list = se_list;	while (list)	{		se = (socketevent *) list->data;		if (se->tag == tag)		{			se_list = g_slist_remove (se_list, se);			free (se);			return;		}		list = list->next;	}}intfe_input_add (int sok, int rread, int wwrite, int eexcept, void *func,				  void *data){	socketevent *se = malloc (sizeof (socketevent));	se_list_count++;  /* this overflows at 2.2Billion, who cares!! */	se->tag = se_list_count;	se->sok = sok;	se->rread = rread;	se->wwrite = wwrite;	se->eexcept = eexcept;	se->callback = func;	se->userdata = data;	se_list = g_slist_prepend (se_list, se);	return se->tag;}intfe_args (int argc, char *argv[]){	pgInit(argc, argv);	pgEmptyString=pgNewString("");	pgPlusHTML=pgNewString("+HTML");	if (argc > 1)	{		if (!strcasecmp (argv[1], "--version") || !strcasecmp (argv[1], "-v"))		{			puts (VERSION);			return 0;		}		if (!strcasecmp (argv[1], "--textbox"))			output_type=PG_WIDGET_TEXTBOX;		if (!strcasecmp (argv[1], "--terminal"))			output_type=PG_WIDGET_TERMINAL;	}	return 1;}voidfe_init (void){	se_list = 0;	se_list_count = 0;	tmr_list = 0;	tmr_list_count = 0;	prefs.autosave = 0;	prefs.use_server_tab = 0;	prefs.autodialog = 0;	prefs.lagometer = 0;	prefs.skipserverlist = 1;	palette_load();}static intselectwrapper (int nfds, fd_set *readfds, fd_set *writefds,		fd_set *exceptfds, struct timeval *timeout);static voidafterselect(int result, fd_set *rfds);voidfe_main (void){#ifdef ENABLE_NLS	bindtextdomain (PACKAGE, LOCALEDIR);	textdomain (PACKAGE);#endif	pgCustomizeSelect(selectwrapper, afterselect);	pgEventLoop();}static fd_set *fe_pg_rfds, *fe_pg_wfds, *fe_pg_efds;staticint selectwrapper (int n, fd_set *readfds, fd_set *writefds,		fd_set *exceptfds, struct timeval *timeout){	static fd_set rfds, wfds, efds;	struct timeval now;	socketevent *se;	timerevent *te;	GSList *list;	guint64 shortest, delay;	if(readfds)		fe_pg_rfds=readfds;	else	{		fe_pg_rfds=&rfds;		FD_ZERO (&rfds);	}	if(writefds)		fe_pg_wfds=writefds;	else	{		fe_pg_wfds=&wfds;		FD_ZERO (&wfds);	}	if(exceptfds)		fe_pg_efds=exceptfds;	else	{		fe_pg_efds=&efds;		FD_ZERO (&efds);	}	list = se_list;	while (list)	{		se = (socketevent *) list->data;		if (se->rread)		{			FD_SET (se->sok, fe_pg_rfds);			if(n<=se->sok)				n=se->sok+1;		}		if (se->wwrite)		{			FD_SET (se->sok, fe_pg_wfds);			if(n<=se->sok)				n=se->sok+1;		}		if (se->eexcept)		{			FD_SET (se->sok, fe_pg_efds);			if(n<=se->sok)				n=se->sok+1;		}		list = list->next;	}	/* find the shortest timeout event */	if(tmr_list)	{		gettimeofday (&now, NULL);		shortest = now.tv_sec * 1000 + now.tv_usec / 1000 +			23*60*60*1000;	/* we wait a max of 23 hours */		list = tmr_list;		while (list)		{			te = (timerevent *) list->data;			if (te->next_call < shortest)				shortest = te->next_call;			list = list->next;		}		delay = shortest - ((now.tv_sec * 1000) + (now.tv_usec / 1000));		if(delay<0)			delay=0;		now.tv_sec = delay / 1000;		now.tv_usec = (delay % 1000) * 1000;		if(timeout)		{			if(now.tv_sec<timeout->tv_sec ||					(now.tv_sec==timeout->tv_sec &&					now.tv_usec<timeout->tv_usec))				*timeout=now;		}		else			timeout=&now;	}	return select (n, fe_pg_rfds, fe_pg_wfds, fe_pg_efds, timeout);}static voidafterselect(int result, fd_set *rfds){	GSList *list;	socketevent *se;	timerevent *te;	struct timeval now;	static int last=0;	/* these should already be the same */	fe_pg_rfds=rfds;	/* set all checked flags to false */	list = se_list;	while (list)	{		se = (socketevent *) list->data;		se->checked = 0;		list = list->next;	}	/* check all the socket callbacks */	list = se_list;	while (list)	{		se = (socketevent *) list->data;		se->checked = 1;		if (se->rread && FD_ISSET (se->sok, fe_pg_rfds))		{			se->callback (NULL, 0, se->userdata);		} else if (se->wwrite && FD_ISSET (se->sok, fe_pg_wfds))		{			se->callback (NULL, 0, se->userdata);		} else if (se->eexcept && FD_ISSET (se->sok, fe_pg_efds))		{			se->callback (NULL, 0, se->userdata);		}		list = se_list;		if (list)		{			se = (socketevent *) list->data;			while (se->checked)			{				list = list->next;				if (!list)					break;				se = (socketevent *) list->data;			}		}	}	/* now check our list of timeout events, some might need to be called! */	gettimeofday (&now, NULL);	list = tmr_list;	while (list)	{		te = (timerevent *) list->data;		list = list->next;		if (now.tv_sec < last)			te->next_call -= 24*60*60*1000;		if (now.tv_sec * 1000 + (now.tv_usec / 1000) >= te->next_call)		{			/* if the callback returns 0, it must be removed */			if (te->callback (te->userdata) == 0)			{

⌨️ 快捷键说明

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