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

📄 main.c

📁 multi-tabed terminal based on rxvt
💻 C
📖 第 1 页 / 共 5 页
字号:
/*--------------------------------*-C-*---------------------------------* * File:    main.c *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 1992        John Bovey <jdb@ukc.ac.uk> * Copyright (c) 1994        Robert Nation <nation@rocket.sanders.lockheed.com> * Copyright (c) 1995        Garrett D'Amore <garrett@netcom.com> * Copyright (c) 1997        mj olesen <olesen@me.QueensU.CA> * Copyright (c) 1997,1998   Oezguer Kesim <kesim@math.fu-berlin.de> * Copyright (c) 1998-2001   Geoff Wing <gcw@pobox.com> * Copyright (c) 2000        Xianping Ge <xge@ics.uci.edu> * Copyright (c) 2003-2004   Marc Lehmann <pcg@goof.com> * Copyright (c) 2005        Burgers A.R. <burgers@ecn.nl> * Copyright (c) 2004-2006   Jingmin Zhou <jimmyzhou@users.sourceforge.net> * Copyright (c) 2005-2006   Gautam Iyer <gi1242@users.sourceforge.net> * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------------*/#include "../config.h"#include "rxvt.h"#ifdef XFT_SUPPORT# include "xftacs.h"#endif/*--------------------------------------------------------------------* *         BEGIN `INTERNAL' ROUTINE PROTOTYPES                        * *--------------------------------------------------------------------*/void rxvt_alarm_signal	       ( __attribute__((unused)) int sig );void rxvt_pre_show_init	       (rxvt_t* r);void rxvt_clean_commands       (rxvt_t* r, int command_number);void rxvt_free_hidden          (rxvt_t*);void rxvt_font_up_down         (rxvt_t*, int, int);int  rxvt_get_font_widest      (XFontStruct*);void rxvt_set_colorfgbg        (rxvt_t*);void rxvt_resize_sub_windows   (rxvt_t*);#ifdef USE_XIMvoid rxvt_IM_set_size          (rxvt_t*, XRectangle*);void rxvt_IM_set_position      (rxvt_t*, XPoint*);void rxvt_IM_set_color         (rxvt_t*, unsigned long*, unsigned long*);Bool rxvt_IM_is_running        (rxvt_t*);void rxvt_IM_change_fontset    (rxvt_t*, int);void rxvt_IM_set_preedit_area  (rxvt_t*, XRectangle*, XRectangle*, XRectangle*);void rxvt_IM_destroy_callback  (XIM, XPointer, XPointer);Bool rxvt_IM_get_IC            (rxvt_t*);void rxvt_IM_send_size         (rxvt_t*);void rxvt_IM_set_status_pos    (rxvt_t*);#endifvoid rxvt_set_r                (rxvt_t*);#ifdef XFT_SUPPORTvoid xftFreeUnusedFont	       (rxvt_t*, XftFont*);void setXftWeight	       (XftPattern *, const char *, int);void rxvt_init_font_fixed      (rxvt_t*);# ifndef NO_BOLDFONTvoid rxvt_init_bfont_xft       (rxvt_t*, XftPattern*);# endif# ifdef MULTICHAR_SETint  rxvt_init_mfont_xft       (rxvt_t*, XftPattern*, const char*);int  isDoubleWidthFont         (Display *dpy, XftFont *font);# endif#endif	/* XFT_SUPPORT *//*--------------------------------------------------------------------* *         END   `INTERNAL' ROUTINE PROTOTYPES                        * *--------------------------------------------------------------------*//*----------------------------------------------------------------------*/const char**	cmd_argv;/*----------------------------------------------------------------------*//* * Initialization done after reading command line options, and before calling * rxvt_create_show_windows(). *//* INTPROTO */voidrxvt_pre_show_init( rxvt_t *r ){    /*     * 2006-08-18 gi1242 TODO: If we're using Xft, then we don't need to     * initialize this array.     */    r->pixColorsFocus = rxvt_malloc( sizeof(unsigned long) * (TOTAL_COLORS));    r->pixColors = r->pixColorsFocus;#ifdef XFT_SUPPORT    if( ISSET_OPTION( r, Opt_xft ) )    {	r->xftColorsFocus = rxvt_malloc( sizeof(XftColor) * (TOTAL_COLORS) );	r->xftColors = r->xftColorsFocus;    }    else    {	SET_NULL( r->xftColors );	SET_NULL( r->xftColorsFocus );    }#endif    if( r->TermWin.fade )    {	rxvt_dbgmsg ((DBG_DEBUG, DBG_MAIN, "Allocating space for fade colors\n"));	r->pixColorsUnfocus =	    rxvt_malloc( sizeof(unsigned long) * (TOTAL_COLORS) );# ifdef XFT_SUPPORT	if( ISSET_OPTION( r, Opt_xft ) )	    r->xftColorsUnfocus =		rxvt_malloc( sizeof(XftColor) * TOTAL_COLORS );	else	    SET_NULL( r->xftColorsUnfocus );# endif /* XFT_SUPPORT */    }    else    {	SET_NULL( r->pixColorsUnfocus );# ifdef XFT_SUPPORT	SET_NULL( r->xftColorsUnfocus );# endif    }}/* rxvt_init() *//* LIBPROTO */rxvt_t		*rxvt_init(int argc, const char *const *argv){    register int    i;    register int    itnum; /* initial terminal number */    rxvt_t*	    r;    /* Allocate memory for "r" and initialize contents to 0 */    r = (rxvt_t *) rxvt_calloc(1, sizeof(rxvt_t));    /* Save "r" in _rxvt_vars. This is the only assignment to _rxvt_vars */    rxvt_set_r(r);    /* Initialize vars in "r" */    if (rxvt_init_vars(r) < 0)    {	rxvt_msg (DBG_ERROR, DBG_MAIN,  "Could not initialize." );	rxvt_free(r);	return NULL;    }    /* save global argc and argv */    r->global_argc = argc;    r->global_argv = (char**) argv;    rxvt_init_secondary(r);    cmd_argv = rxvt_init_resources(r, argc, argv);    rxvt_pre_show_init( r );    rxvt_create_show_windows(r, argc, argv);#ifdef TRANSPARENT    if (ISSET_OPTION(r, Opt_transparent))    {	XSelectInput(r->Xdisplay, XROOT, PropertyChangeMask);	/*	 * Our "parents" will automatically be checked on the first expose and	 * ConfigureNotify event respectively. Forcefully calling it is just a	 * waste of time.	 */# if 0	rxvt_check_our_parents(r);# endif    }#endif    rxvt_init_env(r);    rxvt_init_command(r);    rxvt_init_screen (r);    /*     * Initialize the pages     */    if( r->h->rs[Rs_initProfiles] )    {	/* Split into a comma separated string */	char *s = (char *) r->h->rs[Rs_initProfiles];	do	  {	    int profile = atoi( s );	    rxvt_append_page( r, profile, NULL, NULL );	    s = STRCHR( s, ',' );	  }	while (NULL != s++);    }    /* Backward compatibility: Open profiles 0 .. n-1 if tnum=n. */    else if( r->h->rs[Rs_init_term_num] )    {	rxvt_msg (DBG_ERROR, DBG_MAIN,  "Option tnum is obsolete."		" Use --initProfileList instead" );	itnum = atoi( r->h->rs[Rs_init_term_num] );	itnum = max( 1, itnum );	itnum = min( itnum, MAX_PAGES );	for (i = 0; i < itnum; i ++)	    rxvt_append_page( r, (i < MAX_PROFILES) ? i : 0 , NULL, NULL );    }    /* Just open the default tab */    else	rxvt_append_page( r, 0, NULL, NULL );    /* Activate the tab */    rxvt_activate_page (r, 0);    /* Initialize xlocale after VT is created */    rxvt_init_xlocale(r);    return r;}/* ------------------------------------------------------------------------- * *			    SIGNAL HANDLING & EXIT HANDLER			* * ------------------------------------------------------------------------- *//* * Catch a SIGCHLD signal and exit if the direct child has died *//* ARGSUSED *//* EXTPROTO */RETSIGTYPErxvt_Child_signal(int sig __attribute__((unused))){    /*     * Sometimes the child process could exit before we have a chance to     * initialize the term structure. So we just count the number of calls to     * this function here. We will wait for our dead children later.     */    rxvt_t  *r;    rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, "\e[31mrxvt_Child_signal()\e[0m\n"));    r = rxvt_get_r();    r->ndead_childs++;    rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, "done rxvt_Child_signal()\n"));}/* * Catch a fatal signal and tidy up before quitting *//* EXTPROTO */RETSIGTYPErxvt_Exit_signal(int sig){#ifdef UTMP_SUPPORT    register int    i;#endif    rxvt_t*	    r;    rxvt_msg (DBG_INFO, DBG_MAIN, "Received signal %d\n", (int) sig);    r = rxvt_get_r();#ifdef UTMP_SUPPORT    for (i = 0; i <= LTAB(r); i ++)    {	rxvt_privileges( RESTORE );	rxvt_cleanutent( r, i );	rxvt_privileges( IGNORE );    }#endif    /* resend signal to default handler */    /* kill (getpid (), sig); */    rxvt_close_all_tabs( r );}voidrxvt_alarm_signal( __attribute__((unused)) int sig ){    int i;    rxvt_t *r = rxvt_get_r();    if( LTAB(r) >= 0 )    {	rxvt_msg (DBG_WARN, DBG_MAIN, APL_NAME ": WARNING Processes ");	for( i=0; i <= LTAB(r); i ++ )	    rxvt_msg (DBG_WARN, DBG_MAIN, "%d%c", PVTS(r, i)->cmd_pid,		    i == LTAB(r) ? ' ' : ',' );	rxvt_msg (DBG_WARN, DBG_MAIN,	    " have not responded to SIGHUP, and are still "	    "running. Either 'kill -9' these processes or close the "	    APL_NAME " window again within 3 seconds.\n");    }}/* INTPROTO */voidrxvt_free_hidden( rxvt_t* r ){#ifdef DEBUG    if (IS_CURSOR(r->h->bar_pointer))    {	XFreeCursor( r->Xdisplay, r->h->bar_pointer );	UNSET_CURSOR(r->h->bar_pointer);    }# ifdef POINTER_BLANK    if (IS_CURSOR(r->h->blank_pointer))    {	XFreeCursor( r->Xdisplay, r->h->blank_pointer );	UNSET_CURSOR(r->h->blank_pointer);    }# endif#endif	/* DEBUG */#ifdef USE_XIM    if( r->h->Input_Context )       {	XDestroyIC( r->h->Input_Context );	SET_NULL(r->h->Input_Context);     }#endif}/* * If we're protecting the secondary screen, or have multiple tabs with a hidden * tabbar, then avoid exiting. *//* EXTPROTO */voidrxvt_exit_request( rxvt_t *r ){    /* Avoid exiting if there are multiple tabs with hidden tabbar */    if( LTAB(r) > 0 &&  !rxvt_tabbar_visible( r ) )    {	XBell( r->Xdisplay, 0 );	if( rxvt_tabbar_show(r) ) rxvt_resize_on_subwin (r, SHOW_TABBAR);	return;    }    /* Avoid exiting if some tab is in the secondary screen */    if(ISSET_OPTION(r, Opt2_protectSecondary))    {	int i, dontExit = 0;	for( i=0; i <= LTAB(r); i++)	{	    if( PVTS(r, i)->current_screen == SECONDARY )	    {		dontExit = 1;		if( i != ATAB(r) )		    rxvt_tabbar_highlight_tab( r, i, False);	    }	}	if( dontExit )	{	    XBell( r->Xdisplay, 0);	    return;	}    }    rxvt_close_all_tabs(r);}/* * Remove all held tabs, and send SIGHUP to processes in all live tabs * * 2006-09-22 gi1242: In mrxvt-0.5.1 and before, we would exit mrxvt by calling * rxvt_clean_exit(). This would send SIGHUP to all child processes, and then * call exit(). This however is flawed! If some processes do not exit on SIGHUP, * then they will remain in the background and the user will not know. * * To fix this issue, we call rxvt_close_all_tabs() instead of rxvt_clean_exit() * when we want to exit mrxvt. rxvt_close_all_tabs() will send SIGHUP's to all * child processes, and remove all held tabs. If mrxvt does not exit within two * seconds, then it will sound an alarm warning the user of the offending * processes which ignored SIGHUP. The user can either kill -9 those processes * manually, or request another exit of mrxvt within the next 3 seconds to have * mrxvt forcefully exit (but leaving the child processes running). *//* EXTPROTO */voidrxvt_close_all_tabs( rxvt_t *r){    static struct timeval   lastRequest = {0, 0};    struct timeval	    now;    int			    i;    for( i=LTAB(r); i >=0; i-- )    {	if( PVTS(r, i)->dead )	    rxvt_remove_page( r, i );	else	{	    PVTS(r, i)->holdOption = 0;	    kill( PVTS(r, i)->cmd_pid, SIGHUP );	}    }    gettimeofday( &now, NULL );    if( lastRequest.tv_sec != 0 && now.tv_sec - lastRequest.tv_sec < 5 )	/* Second request within 5 seconds. Kill mrxvt */	rxvt_clean_exit(r);    else    {	lastRequest = now;	/* Just in case the processes don't exit on SIGHUP, warn the user */	signal( SIGALRM, rxvt_alarm_signal );	alarm( 2 );    }}/* EXTPROTO */voidrxvt_clean_exit (rxvt_t* r){#ifdef HAVE_X11_SM_SMLIB_H    if (ISSET_OPTION(r, Opt2_enableSessionMgt))	rxvt_session_exit (r);#endif#if 0    /*     * Now kill all child processes, zsh puts them into background if we do not     * do so.     *     * 2006-09-22 gi1242: No! See comments before rxvt_close_all_tabs().     */    for (i = 0; i <= LTAB(r); i ++)	kill (PVTS(r, i)->cmd_pid, SIGHUP);#endif    /*     * 2006-01-27 gi1242: Free all used resources. This used to be done only in     * debug mode, but I think it's good practice to do it always. It can't hurt     * anything.     *//* #ifdef DEBUG	*/    rxvt_free_hidden (r);    /* Destroy windows before other X resources */    if (IS_WIN(r->TermWin.parent))    {	XDestroySubwindows (r->Xdisplay, r->TermWin.parent);	XDestroyWindow (r->Xdisplay, r->TermWin.parent);	UNSET_WIN(r->TermWin.parent);    }# ifdef HAVE_SCROLLBARS    rxvt_scrollbar_clean_exit (r);# endif# ifdef HAVE_MENUBAR    rxvt_menubar_clean_exit (r);# endif    rxvt_tabbar_clean_exit (r);    if (NOT_NULL(r->TermWin.font))	XFreeFont (r->Xdisplay, r->TermWin.font);# ifndef NO_BOLDFONT    if (NOT_NULL(r->TermWin.bfont) && r->TermWin.font != r->TermWin.bfont)    {	XFreeFont (r->Xdisplay, r->TermWin.bfont);	SET_NULL(r->TermWin.bfont);    }# endif

⌨️ 快捷键说明

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