📄 main.c
字号:
# ifdef MULTICHAR_SET if (NOT_NULL(r->TermWin.mfont) && r->TermWin.font != r->TermWin.mfont) { XFreeFont (r->Xdisplay, r->TermWin.mfont); SET_NULL(r->TermWin.mfont); }# endif SET_NULL(r->TermWin.font); /* clear font */# ifdef XFT_SUPPORT if (NOT_NULL(r->TermWin.xftfont)) { XftFont *fn; XftFontClose (r->Xdisplay, r->TermWin.xftfont); xftCloseACS (r->Xdisplay); if( (fn = r->TermWin.xftpfont) ) { SET_NULL(r->TermWin.xftpfont); xftFreeUnusedFont( r, fn); } if( (fn = r->TermWin.xftPfont) ) { SET_NULL(r->TermWin.xftPfont); xftFreeUnusedFont( r, fn); }# ifndef NO_BOLDFONT fn = r->TermWin.xftbfont; SET_NULL(r->TermWin.xftbfont); xftFreeUnusedFont( r, fn);# endif# ifdef MULTICHAR_SET fn = r->TermWin.xftmfont; SET_NULL(r->TermWin.xftmfont); xftFreeUnusedFont( r, fn);# endif } SET_NULL(r->TermWin.xftfont); /* clear font */ /* * XXX gi1242 2006-01-27: Xft bug. Patterns passed to XftFontOpenPattern * can't always be safely freed. */# if 0 if( r->TermWin.xftpattern ) XftPatternDestroy( r->TermWin.xftpattern);# ifdef MULTICHAR_SET if( r->TermWin.xftmpattern ) XftPatternDestroy( r->TermWin.xftmpattern );# endif# endif# endif if (IS_CURSOR(r->term_pointer)) { XFreeCursor (r->Xdisplay, r->term_pointer); UNSET_CURSOR(r->term_pointer); } if (IS_GC(r->TermWin.gc)) { XFreeGC (r->Xdisplay, r->TermWin.gc); UNSET_GC(r->TermWin.gc); } XCloseDisplay (r->Xdisplay); SET_NULL(r->Xdisplay);#ifdef USE_FIFO if( r->fifo_fd != -1 ) { close( r->fifo_fd ); r->fifo_fd = -1; unlink( r->fifo_name ); rxvt_free( r->fifo_name ); SET_NULL( r->fifo_name ); }#endif/*USE_FIFO*/ rxvt_free (r->tabstop); SET_NULL(r->tabstop); rxvt_free (r->pixColorsFocus); SET_NULL(r->pixColorsFocus); if( NOT_NULL( r->pixColorsUnfocus ) ) { rxvt_free (r->pixColorsUnfocus); SET_NULL(r->pixColorsUnfocus); }# ifdef XFT_SUPPORT if( NOT_NULL( r->xftColorsUnfocus ) ) { rxvt_free( r->xftColorsUnfocus ); SET_NULL( r->xftColorsUnfocus ); }# endif /* XFT_SUPPORT */# ifdef XFT_SUPPORT if( NOT_NULL( r->xftColors ) ) { rxvt_free (r->xftColors); SET_NULL(r->xftColors); }# endif rxvt_free (r->h); SET_NULL(r->h); rxvt_free (r); SET_NULL(r);/* #endif */ /* DEBUG */ exit(EXIT_SUCCESS);}/* ------------------------------------------------------------------------- * * PRIVILEGED OPERATIONS * * ------------------------------------------------------------------------- */#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(OS_CYGWIN)static uid_t g_euid;static gid_t g_egid;#endif/* take care of suid/sgid super-user (root) privileges *//* EXTPROTO */voidrxvt_privileges(int mode){#if !defined(OS_CYGWIN)# 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: g_euid = geteuid(); g_egid = getegid(); break; case RESTORE: seteuid(g_euid); setegid(g_egid); break; }# else switch (mode) { case IGNORE: if (setuid(getuid()) < 0) exit (EXIT_FAILURE); if (setgid(getgid()) < 0) exit (EXIT_FAILURE); /* FALLTHROUGH */ case SAVE: /* FALLTHROUGH */ case RESTORE: break; }# endif#endif}#ifdef UTMP_SUPPORT/* EXTPROTO */voidrxvt_privileged_utmp(rxvt_t* r, int page, char action){ rxvt_msg (DBG_INFO, DBG_MAIN, "rxvt_privileged_utmp %d (%c); waiting for: %c (pid: %d)\n", page, action, PVTS(r, page)->next_utmp_action, (int) getpid()); if (PVTS(r, page)->next_utmp_action != action || (action != SAVE && action != RESTORE) || ISSET_OPTION(r, Opt_utmpInhibit) || IS_NULL(PVTS(r, page)->ttydev) || (char) 0 == *(PVTS(r, page)->ttydev)) return; rxvt_privileges(RESTORE); if (action == SAVE) { PVTS(r, page)->next_utmp_action = RESTORE; rxvt_makeutent(r, page, PVTS(r, page)->ttydev, r->h->rs[Rs_display_name]); } else /* action == RESTORE */ { PVTS(r, page)->next_utmp_action = IGNORE; rxvt_cleanutent(r, page); } rxvt_privileges(IGNORE);}#endif#ifndef NO_SETOWNER_TTYDEV/* EXTPROTO */voidrxvt_privileged_ttydev(rxvt_t* r, int page, char action){ rxvt_msg (DBG_INFO, DBG_MAIN, "rxvt_privileged_ttydev %d (r, %c); waiting for: %c (pid: %d)\n", page, action, PVTS(r, page)->next_tty_action, getpid()); if (PVTS(r, page)->next_tty_action != action || (action != SAVE && action != RESTORE) || IS_NULL(PVTS(r, page)->ttydev) || (char) 0 == *(PVTS(r, page)->ttydev)) return; rxvt_privileges(RESTORE); if (action == SAVE) { PVTS(r, page)->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(PVTS(r, page)->ttydev, &h->ttyfd_stat) < 0) /* you lose out */ PVTS(r, page)->next_tty_action = IGNORE; else# endif { /* fail silently */ chown(PVTS(r, page)->ttydev, getuid(), r->h->ttygid); chmod(PVTS(r, page)->ttydev, PVTS(r, page)->ttymode);# ifdef HAVE_REVOKE revoke(PVTS(r, page)->ttydev);# endif } } else /* action == RESTORE */ { PVTS(r, page)->next_tty_action = IGNORE;# ifndef RESET_TTY_TO_COMMON_DEFAULTS chmod(PVTS(r, page)->ttydev, PVTS(r, page)->ttyfd_stat.st_mode); chown(PVTS(r, page)->ttydev, PVTS(r, page)->ttyfd_stat.st_uid, PVTS(r, page)->ttyfd_stat.st_gid);# else chmod(PVTS(r, page)->ttydev, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)); chown(PVTS(r, page)->ttydev, 0, 0);# endif } rxvt_privileges(IGNORE);# ifndef RESET_TTY_TO_COMMON_DEFAULTS rxvt_msg (DBG_INFO, DBG_MAIN, "%s \"%s\": mode %03o, uid %d, gid %d\n", action == RESTORE ? "Restoring" : (action == SAVE ? "Saving" : "UNKNOWN ERROR for"), PVTS(r, page)->ttydev, PVTS(r, page)->ttyfd_stat.st_mode, PVTS(r, page)->ttyfd_stat.st_uid, PVTS(r, page)->ttyfd_stat.st_gid);# endif}#endif/*----------------------------------------------------------------------*//* * 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, pid_t pid){ struct winsize ws;#ifdef DEBUG if( pid && fd > STDERR_FILENO ) { rxvt_dbgmsg ((DBG_DEBUG, DBG_MAIN, "%s( fd=%d, col=%hu, row=%hu, pid=%d )\n", __func__, fd, col, row, pid)); }#endif if (fd < 0) return; ws.ws_col = col; ws.ws_row = row; ws.ws_xpixel = ws.ws_ypixel = 0; if (ioctl(fd, TIOCSWINSZ, &ws) < 0) {#ifdef DEBUG if( pid && fd > STDERR_FILENO ) { rxvt_msg (DBG_WARN, DBG_MAIN, "Failed to send TIOCSWINSZ to fd %d\n", fd); }#endif }#ifdef SIGWINCH else if( pid ) /* force through to the command */ kill(pid, SIGWINCH);#endif}#define IDX2FNUM(i) ((FONT0_IDX + i) % MAX_NFONTS)#define FNUM2IDX(f) ((FONT0_IDX + f) % MAX_NFONTS)#ifdef XFT_SUPPORT# ifndef NO_BOLDFONT/* INTPROTO */voidrxvt_init_bfont_xft (rxvt_t* r, XftPattern* xpold){ XftResult fr; XftPattern* xp, *xftbpattern;# ifdef DEBUG FT_Face face;# endif rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, "rxvt_init_bfont_xft()")); xp = XftPatternDuplicate (xpold); if (IS_NULL(xp)) return ; /* set font weight */ XftPatternDel (xp, XFT_WEIGHT); setXftWeight( xp, r->h->rs[Rs_xftBwt], XFT_WEIGHT_BOLD ); xftbpattern = XftFontMatch (r->Xdisplay, XSCREEN, xp, &fr); if (NOT_NULL(xftbpattern)) { r->TermWin.xftbfont = XftFontOpenPattern (r->Xdisplay, xftbpattern); if (IS_NULL(r->TermWin.xftbfont)) { /* fall back to normal font */ XftPatternDestroy (xftbpattern); SET_NULL(xftbpattern); } else { rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, "Opened bold font: h=%d(%d), w=%d(%d)", r->TermWin.xftbfont->height, r->TermWin.xftfont->height, r->TermWin.xftbfont->max_advance_width, r->TermWin.xftfont->max_advance_width));#ifdef DEBUG FcPatternPrint( xftbpattern );#endif /* * If the bold font is of different dimensions from the regular * font, we should draw it like a proportionally spaced font. */ if (r->TermWin.xftbfont->max_advance_width < r->TermWin.fwidth) r->TermWin.propfont |= PROPFONT_BOLD; else { if (r->TermWin.xftbfont->max_advance_width > r->TermWin.fwidth) { rxvt_msg (DBG_ERROR, DBG_MAIN, "Bold font too wide. Using overstrike" ); XftFontClose( r->Xdisplay, r->TermWin.xftbfont ); SET_NULL( r->TermWin.xftbfont ); } /* * Now we're either overstriking, or using a correctly sized * bold font, so clear PROPFONT_BOLD. */ r->TermWin.propfont &= ~PROPFONT_BOLD; } }# ifdef DEBUG { if (!IS_NULL(r->TermWin.xftbfont)) { face = XftLockFace (r->TermWin.xftbfont); XftUnlockFace (r->TermWin.xftbfont); } }# endif } XftPatternDestroy (xp);}# endif /* NO_BOLDFONT */# ifdef MULTICHAR_SET/* INTPROTO */intrxvt_init_mfont_xft (rxvt_t* r, XftPattern* xp, const char* ofname){ XftResult fr; int len, olen; /* font name length */ char* mfname; /* mfont name to open */ FcChar8* omfname = NULL; /* actually opened mfont name */ int width, height;# ifdef DEBUG FT_Face face;# endif /* temporary XftPattern */ assert (NOT_NULL(xp)); /* actually opened normal font name */ assert (NOT_NULL(ofname)); /* ** Now try to open freetype mfont */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_MAIN, "load freetype mfont\n")); /* font family */ mfname = (char*) r->h->rs[Rs_xftmfont]; if (IS_NULL(mfname)) mfname = rxvt_fallback_mfont_xft (r); /* * If we should not use mfont, then we always use normal font */ if (ISSET_OPTION(r, Opt2_xftNomFont)) { r->TermWin.xftmpattern = r->TermWin.xftpattern; r->TermWin.xftmfont = r->TermWin.xftfont; return 1; } /* * shortcut: * mfont is the same as font, just alias mfont to font */ if (0 == STRCASECMP (ofname, mfname)) { r->TermWin.xftmpattern = r->TermWin.xftpattern; r->TermWin.xftmfont = r->TermWin.xftfont; return 1; } /* font family */ XftPatternDel (xp, XFT_FAMILY); XftPatternAddString (xp, XFT_FAMILY, mfname); XftPatternDel (xp, XFT_SIZE); /* * 2006-02-11 gi1242: This is however HORRIBLE for regular fonts. It's * probably better to fall back to xftsz. Thus the random user who knows * nothing about mrxvt (or encodings) will get a reasonable looking terminal * by default. */#if 0 /* this seems to be optimal for simsun font */ XftPatternAddDouble (xp, XFT_SIZE, r->h->rs[Rs_xftmsz] ? (double) r->TermWin.xftmsize : (double) (r->TermWin.xftfont->height - 1));#endif XftPatternAddDouble( xp, XFT_SIZE, (r->h->rs[Rs_xftmsz] ? (double) r->TermWin.xftmsize : (double) r->TermWin.xftsize)); /* * XXX 2006-01-26 gi1242: I don't know anything about mfont. Not sure if it * should be monospaced or not. Original mrxvt code did not have mono space * for any font, so I remove it here for the mfont. */#if 0 XftPatternDel (xp, XFT_SPACING);#endif /* font pattern */ r->TermWin.xftmpattern = XftFontMatch (r->Xdisplay, XSCREEN, xp, &fr); if (IS_NULL(r->TermWin.xftmpattern)) return 0; /* globaladvance */ if (ISSET_OPTION(r, Opt2_xftGlobalAdvance)) { XftPatternDel (r->TermWin.xftmpattern, FC_GLOBAL_ADVANCE); XftPatternAddBool (r->TermWin.xftmpattern, FC_GLOBAL_ADVANCE, FcTrue); }# ifdef DEBUG FcPatternPrint (r->TermWin.xftmpattern);# endif /* * Print a warning if our matched mfont is different from the user supplied * font.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -