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

📄 main.c

📁 rxvt经典的linux下的终端.小巧实用
💻 C
📖 第 1 页 / 共 3 页
字号:
/*--------------------------------*-C-*---------------------------------* * File:	main.c *----------------------------------------------------------------------* * $Id: main.c,v 1.172 2002/10/24 01:50:58 gcw Exp $ * * All portions of code are copyright by their respective author/s. * Copyright (c) 1992      John Bovey, University of Kent at Canterbury <jdb@ukc.ac.uk> *				- original version * Copyright (c) 1994      Robert Nation <nation@rocket.sanders.lockheed.com> *				- extensive modifications * Copyright (c) 1995      Garrett D'Amore <garrett@netcom.com> * Copyright (c) 1997      mj olesen <olesen@me.QueensU.CA> *				- extensive modifications * Copyright (c) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de> * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com> *				- extensive modifications * * 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"		/* NECESSARY */#include "rxvt.h"		/* NECESSARY */#include "main.intpro"		/* PROTOS for internal routines */#include <signal.h>#ifdef TTY_GID_SUPPORT# include <grp.h>#endif#ifdef HAVE_TERMIOS_H# include <termios.h>#endif/*----------------------------------------------------------------------*//* rxvt_init() *//* LIBPROTO */rxvt_t         *rxvt_init(int argc, const char *const *argv){    const char    **cmd_argv;    rxvt_t         *r;    r = (rxvt_t *)rxvt_calloc(1, sizeof(rxvt_t));    rxvt_set_r(r);		/* only assignment to _rxvt_vars */    if (rxvt_init_vars(r) < 0) {	free(r);	return NULL;    }/* * Save and then give up any super-user privileges * If we need privileges in any area then we must specifically request it. * We should only need to be root in these cases: *  1.  write utmp entries on some systems *  2.  chown tty on some systems */    rxvt_privileges(r, SAVE);    rxvt_privileges(r, IGNORE);    rxvt_init_secondary(r);    cmd_argv = rxvt_init_resources(r, argc, argv);#if (MENUBAR_MAX)    rxvt_menubar_read(r, r->h->rs[Rs_menu]);#endif#ifdef HAVE_SCROLLBARS    if (r->Options & Opt_scrollBar)      scrollbar_setIdle();	/* set existence for size calculations */#endif    rxvt_Create_Windows(r, argc, argv);    rxvt_init_xlocale(r);    rxvt_scr_reset(r);		/* initialize screen */    rxvt_Gr_reset(r);		/* reset graphics */#ifdef DEBUG_X    XSynchronize(r->Xdisplay, True);    XSetErrorHandler((XErrorHandler) abort);#else    XSetErrorHandler((XErrorHandler) rxvt_xerror_handler);#endif#ifdef HAVE_SCROLLBARS    if (r->Options & Opt_scrollBar)	rxvt_Resize_scrollBar(r);	/* create and map scrollbar */#endif#if (MENUBAR_MAX)    if (menubar_visible(r))	XMapWindow(r->Xdisplay, r->menuBar.win);#endif#ifdef TRANSPARENT    if (r->Options & Opt_transparent) {	XSelectInput(r->Xdisplay, Xroot, PropertyChangeMask);	rxvt_check_our_parents(r);    }#endif    XMapWindow(r->Xdisplay, r->TermWin.vt);    XMapWindow(r->Xdisplay, r->TermWin.parent[0]);    rxvt_init_env(r);    rxvt_init_command(r, cmd_argv);    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))){    int             pid, save_errno = errno;    rxvt_t         *r;    do {	errno = 0;    } while ((pid = waitpid(-1, NULL, WNOHANG)) == -1 && errno == EINTR);    r = rxvt_get_r();    if (pid == r->h->cmd_pid)	exit(EXIT_SUCCESS);    errno = save_errno;    signal(SIGCHLD, rxvt_Child_signal);}/* * Catch a fatal signal and tidy up before quitting *//* EXTPROTO */RETSIGTYPErxvt_Exit_signal(int sig){    signal(sig, SIG_DFL);#ifdef DEBUG_CMD    rxvt_print_error("signal %d", sig);#endif    rxvt_clean_exit();    kill(getpid(), sig);}/* ARGSUSED *//* INTPROTO */intrxvt_xerror_handler(const Display *display __attribute__((unused)), const XErrorEvent *event){    rxvt_t         *r = rxvt_get_r();    if (r->h->allowedxerror == -1) {	r->h->allowedxerror = event->error_code;	return 0;		/* ignored anyway */    }    rxvt_print_error("XError: Request: %d . %d, Error: %d",		     event->request_code, event->minor_code,		     event->error_code);    /* XXX: probably should call rxvt_clean_exit() bypassing X routines */    exit(EXIT_FAILURE);    /* NOTREACHED */}/*----------------------------------------------------------------------*//* * Exit gracefully, clearing the utmp entry and restoring tty attributes * TODO: if debugging, this should free up any known resources if we can *//* EXTPROTO */voidrxvt_clean_exit(void){    rxvt_t         *r = rxvt_get_r();#ifdef DEBUG_SCREEN    rxvt_scr_release(r);#endif    rxvt_privileged_ttydev(r, RESTORE);    rxvt_privileged_utmp(r, RESTORE);#ifdef USE_XIM    if (r->h->Input_Context != NULL) {	XDestroyIC(r->h->Input_Context);	r->h->Input_Context = NULL;    }#endif}/* ------------------------------------------------------------------------- * *                         MEMORY ALLOCATION WRAPPERS                        * * ------------------------------------------------------------------------- *//* EXTPROTO */void           *rxvt_malloc(size_t size){     void           *p;     p = malloc(size);     if (p)	return p;     fprintf(stderr, APL_NAME ": memory allocation failure.  Aborting");     rxvt_clean_exit();     exit(EXIT_FAILURE);     /* NOTREACHED */}/* EXTPROTO */void           *rxvt_calloc(size_t number, size_t size){     void           *p;     p = calloc(number, size);     if (p)	return p;     fprintf(stderr, APL_NAME ": memory allocation failure.  Aborting");     rxvt_clean_exit();     exit(EXIT_FAILURE);     /* NOTREACHED */}/* EXTPROTO */void           *rxvt_realloc(void *ptr, size_t size){     void           *p;     if (ptr)	p = realloc(ptr, size);     else	p = malloc(size);     if (p)	return p;     fprintf(stderr, APL_NAME ": memory allocation failure.  Aborting");     rxvt_clean_exit();     exit(EXIT_FAILURE);     /* NOTREACHED */}/* ------------------------------------------------------------------------- * *                            PRIVILEGED OPERATIONS                          * * ------------------------------------------------------------------------- *//* take care of suid/sgid super-user (root) privileges *//* INTPROTO */voidrxvt_privileges(rxvt_t *r, int mode){#if ! defined(__CYGWIN32__)# if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)/* setreuid() is the poor man's setuid(), seteuid() */#  define seteuid(a)	setreuid(-1, (a))#  define setegid(a)	setregid(-1, (a))#  define HAVE_SETEUID# endif# ifdef HAVE_SETEUID    switch (mode) {    case IGNORE:	/*	 * change effective uid/gid - not real uid/gid - so we can switch	 * back to root later, as required	 */	seteuid(getuid());	setegid(getgid());	break;    case SAVE:	r->h->euid = geteuid();	r->h->egid = getegid();	break;    case RESTORE:	seteuid(r->h->euid);	setegid(r->h->egid);	break;    }# else    switch (mode) {    case IGNORE:	setuid(getuid());	setgid(getgid());    /* FALLTHROUGH */    case SAVE:    /* FALLTHROUGH */    case RESTORE:	break;    }# endif#endif}#ifdef UTMP_SUPPORT/* EXTPROTO */voidrxvt_privileged_utmp(rxvt_t *r, char action){    struct rxvt_hidden *h = r->h;    D_MAIN((stderr, "rxvt_privileged_utmp(%c); waiting for: %c (pid: %d)", action, h->next_utmp_action, getpid()));    if (h->next_utmp_action != action	|| (action != SAVE && action != RESTORE)	|| (r->Options & Opt_utmpInhibit)	|| h->ttydev == NULL	|| *h->ttydev == '\0')	return;    rxvt_privileges(r, RESTORE);    if (action == SAVE) {	h->next_utmp_action = RESTORE;	rxvt_makeutent(r, h->ttydev, h->rs[Rs_display_name]);    } else {		/* action == RESTORE */	h->next_utmp_action = IGNORE;	rxvt_cleanutent(r);    }    rxvt_privileges(r, IGNORE);}#endif#ifndef NO_SETOWNER_TTYDEV/* EXTPROTO */voidrxvt_privileged_ttydev(rxvt_t *r, char action){    struct rxvt_hidden *h = r->h;    D_MAIN((stderr, "rxvt_privileged_ttydev(r, %c); waiting for: %c (pid: %d)", action, h->next_tty_action, getpid()));    if (h->next_tty_action != action	|| (action != SAVE && action != RESTORE)	|| h->ttydev == NULL	|| *h->ttydev == '\0')	return;    rxvt_privileges(r, RESTORE);    if (action == SAVE) {	h->next_tty_action = RESTORE;# ifndef RESET_TTY_TO_COMMON_DEFAULTS/* store original tty status for restoration rxvt_clean_exit() -- rgg 04/12/95 */	if (lstat(h->ttydev, &h->ttyfd_stat) < 0)	/* you lose out */	    h->next_tty_action = IGNORE;	else# endif	{	    chown(h->ttydev, getuid(), h->ttygid); /* fail silently */	    chmod(h->ttydev, h->ttymode);# ifdef HAVE_REVOKE	    revoke(h->ttydev);# endif	}    } else {			/* action == RESTORE */	h->next_tty_action = IGNORE;# ifndef RESET_TTY_TO_COMMON_DEFAULTS	chmod(h->ttydev, h->ttyfd_stat.st_mode);	chown(h->ttydev, h->ttyfd_stat.st_uid, h->ttyfd_stat.st_gid);# else	chmod(h->ttydev,	      (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH));	chown(h->ttydev, 0, 0);# endif    }    rxvt_privileges(r, IGNORE);# ifndef RESET_TTY_TO_COMMON_DEFAULTS    D_MAIN((stderr, "%s \"%s\": mode %03o, uid %d, gid %d", action == RESTORE ? "Restoring" : (action == SAVE ? "Saving" : "UNKNOWN ERROR for"), h->ttydev, h->ttyfd_stat.st_mode, h->ttyfd_stat.st_uid, h->ttyfd_stat.st_gid));# endif}#endif/*----------------------------------------------------------------------*//* * window size/position calculcations for XSizeHint and other storage. * if width/height are non-zero then override calculated width/height *//* EXTPROTO */voidrxvt_window_calc(rxvt_t *r, unsigned int width, unsigned int height){    short           recalc_x, recalc_y;    int             x, y, sb_w, mb_h, flags;    unsigned int    w, h;    unsigned int    max_width, max_height;    r->szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity;    r->szHint.win_gravity = NorthWestGravity;    /* r->szHint.min_aspect.x = r->szHint.min_aspect.y = 1; */    recalc_x = recalc_y = 0;    flags = 0;    if (!r->h->parsed_geometry) {	r->h->parsed_geometry = 1;	if (r->h->rs[Rs_geometry])	    flags = XParseGeometry(r->h->rs[Rs_geometry], &x, &y, &w, &h);	if (flags & WidthValue) {	    r->TermWin.ncol = BOUND_POSITIVE_INT16(w);	    r->szHint.flags |= USSize;	}	if (flags & HeightValue) {	    r->TermWin.nrow = BOUND_POSITIVE_INT16(h);	    r->szHint.flags |= USSize;	}	if (flags & XValue) {	    r->szHint.x = x;	    r->szHint.flags |= USPosition;	    if (flags & XNegative) {		recalc_x = 1;		r->szHint.win_gravity = NorthEastGravity;	    }	}	if (flags & YValue) {	    r->szHint.y = y;	    r->szHint.flags |= USPosition;	    if (flags & YNegative) {		recalc_y = 1;		if (r->szHint.win_gravity == NorthEastGravity)		    r->szHint.win_gravity = SouthEastGravity;		else		    r->szHint.win_gravity = SouthWestGravity;	    }	}    }/* TODO: BOUNDS */    r->TermWin.width = r->TermWin.ncol * r->TermWin.fwidth;    r->TermWin.height = r->TermWin.nrow * r->TermWin.fheight;    max_width = MAX_COLS * r->TermWin.fwidth;    max_height = MAX_ROWS * r->TermWin.fheight;    r->szHint.base_width = r->szHint.base_height = 2 * r->TermWin.int_bwidth;    sb_w = mb_h = 0;    r->h->window_vt_x = r->h->window_vt_y = 0;    if (scrollbar_visible(r)) {	sb_w = scrollbar_TotalWidth();	r->szHint.base_width += sb_w;	if (!(r->Options & Opt_scrollBar_right))	    r->h->window_vt_x = sb_w;    }    if (menubar_visible(r)) {	mb_h = menuBar_TotalHeight();	r->szHint.base_height += mb_h;	r->h->window_vt_y = mb_h;    }    r->szHint.width_inc = r->TermWin.fwidth;    r->szHint.height_inc = r->TermWin.fheight;    r->szHint.min_width = r->szHint.base_width + r->szHint.width_inc;    r->szHint.min_height = r->szHint.base_height + r->szHint.height_inc;    if (width && width - r->szHint.base_width < max_width) {	r->szHint.width = width;	r->TermWin.width = width - r->szHint.base_width;    } else {	MIN_IT(r->TermWin.width, max_width);	r->szHint.width = r->szHint.base_width + r->TermWin.width;    }    if (height && height - r->szHint.base_height < max_height) {	r->szHint.height = height;	r->TermWin.height = height - r->szHint.base_height;    } else {	MIN_IT(r->TermWin.height, max_height);	r->szHint.height = r->szHint.base_height + r->TermWin.height;    }    if (scrollbar_visible(r) && (r->Options & Opt_scrollBar_right))	r->h->window_sb_x = r->szHint.width - sb_w;    if (recalc_x)	r->szHint.x += (DisplayWidth(r->Xdisplay, Xscreen)			- r->szHint.width - 2 * r->TermWin.ext_bwidth);    if (recalc_y)	r->szHint.y += (DisplayHeight(r->Xdisplay, Xscreen)			- r->szHint.height - 2 * r->TermWin.ext_bwidth);    r->TermWin.ncol = r->TermWin.width / r->TermWin.fwidth;    r->TermWin.nrow = r->TermWin.height / r->TermWin.fheight;    return;}/*----------------------------------------------------------------------*//* * Tell the teletype handler what size the window is. * Called after a window size change. *//* EXTPROTO */voidrxvt_tt_winsize(int fd, unsigned short col, unsigned short row){    struct winsize  ws;    if (fd < 0)	return;    ws.ws_col = col;    ws.ws_row = row;    ws.ws_xpixel = ws.ws_ypixel = 0;    ioctl(fd, TIOCSWINSZ, &ws);}/*----------------------------------------------------------------------*//* rxvt_change_font() - Switch to a new font *//* * init = 1   - initialize * * fontname == FONT_UP  - switch to bigger font * fontname == FONT_DN  - switch to smaller font

⌨️ 快捷键说明

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