📄 init.c
字号:
const char* pbeg; const char* pcur; /* not implemented yet */ *argc = 0; if (NULL == string) return NULL;#define MAX_ARGV (64) /* Up to 64 argv. * * 2006-02-23 gi1242: Use calloc instead of malloc. Thus when freeing pret, * we can safely free all elements till we encounter a NULL pointer. */ pret = (char**) rxvt_calloc (MAX_ARGV, sizeof (char*)); DBG_MSG(1, (stderr, "fetch command argv for the tab\n")); pbeg = pcur = string; /* 2006-02-23 gi1242: Remember to leave space for a NULL terminated pointer * at the end */ for (i = 0; i < MAX_ARGV-2; i ++) { int dq = 0; /* double quote */ int sq = 0; /* single quote */ /* set default argument to NULL */ pret[i] = NULL; /* skip any spaces and non-printable */ while (*pcur && (isspace ((int) *pcur) || !isprint ((int) *pcur))) pcur ++; /* stop if reach end of string */ if (!*pcur) break; /* beginning of the token */ if (isalnum ((int) *pcur) || ispunct ((int) *pcur)) { if ('\"' == *pcur) { /* beginning of double quote */ dq = 1; pbeg = pcur + 1; pcur ++; } else if ('\'' == *pcur) { /* beginning of single quote */ sq = 1; pbeg = pcur + 1; pcur ++; } else /* normal characters */ pbeg = pcur; }#ifdef DEBUG else /* shouldn't happen */ assert (0);#endif /* move forward one character */ pcur ++; /* now fetch the new token */ while (*pcur && /* not end of string */ ((dq && *pcur != '\"') || /* not end of double quote */ (sq && *pcur != '\'') || /* not end of single quote */ (!dq && !sq && !isspace ((int) *pcur)))) *pcur ++; if (!*pcur && /* end of string */ (dq || sq)) /* no match of quote is found */ goto NotMatch; if (!*pcur) /* end of string */ { pret[i] = STRDUP (pbeg); DBG_MSG(1, (stderr, " argv[%d] = %s\n", i, pret[i])); break; /* ready to return */ } if ( (dq && *pcur == '\"') /* end of double quote */ || (sq && *pcur == '\'') /* end of single quote */ || (!dq && !sq && isspace ((int) *pcur)) /* space */ ) { int len = sizeof (char) * (pcur - pbeg) + 1; assert (len > 0); /* possible integer overflow? */ pret[i] = (char*) rxvt_malloc (len * sizeof(char)); MEMCPY (pret[i], pbeg, len-1); pret[i][len-1] = (char) 0; DBG_MSG(1, (stderr, " argv[%d] = %s\n", i, pret[i])); /* forward to next character */ pcur ++; /* fetch next token */ continue; } /* shouldn't get here */ assert (0); }#undef MAX_ARGV /* set the end of argv */ if (pret[i]) { *argc = i+1; pret[i+1] = NULL; } else if (i) /* non-empty argv */ { *argc = i; } else /* empty argv */ {#if 0 /* 2006-02-23 gi1242: Also need to free the char* pointers in pret? */ free (pret); return NULL;#endif goto NotMatch; } /* 2006-02-23 gi1242: Can now reduce the size of pret. */ pret = (char **) rxvt_realloc( pret, (*argc + 1) * sizeof(char*) ); return pret;NotMatch: *argc = 0; { char **s; for( s = pret; *s != NULL; s++) free(*s); } free (pret); return NULL;}/* EXTPROTO */voidrxvt_switch_fgbg_color( rxvt_t *r, int page ){ /* Restore bg/ufbg color */ rxvt_restore_ufbg_color (r);#ifdef OFF_FOCUS_FADING /* Restore off-focus color */ rxvt_restore_pix_color (r);#endif /* * Set fg/bg color of individual terminal */ r->PixColors[Color_fg] = PVTS(r, page)->p_fg; r->PixColors[Color_bg] = PVTS(r, page)->p_bg;#ifdef XFT_SUPPORT r->XftColors[Color_fg] = PVTS(r, page)->p_xftfg; r->XftColors[Color_bg] = PVTS(r, page)->p_xftbg;#endif /* XFT_SUPPORT */ /* * Set foreground/background color for GC. This is necessary. Since all VTs * share the same GC, if we do not set the color here, color from other VTs * will be used to draw the following text till there is a color change. */ XSetForeground( r->Xdisplay, r->TermWin.gc, r->PixColors[Color_fg] ); XSetBackground( r->Xdisplay, r->TermWin.gc, r->PixColors[Color_bg] );}/* INTPROTO */termenv_trxvt_get_termenv( const char *env ){ if (NULL == env) return (TERMENV_XTERM); else if (0 == STRCASECMP (env, "xterm")) return (TERMENV_XTERM); else if (0 == STRCASECMP (env, "rxvt")) return (TERMENV_RXVT); else if (0 == STRCASECMP (env, "vt102")) return (TERMENV_VT102); else if (0 == STRCASECMP (env, "vt100")) return (TERMENV_VT100); else if (0 == STRCASECMP (env, "ansi")) return (TERMENV_ANSI); else if (0 == STRCASECMP (env, "dumb")) return (TERMENV_DUMB); else return (TERMENV_XTERM);}/* INTPROTO */voidrxvt_init_vts( rxvt_t *r, int page, int profile ){#ifdef TTY_GID_SUPPORT struct group* gr = getgrnam( "tty" );#endif struct tms tp; register int i; assert( page < MAX_PAGES ); /* look for an unused term_t structure */ for( i = 0; i < MAX_PAGES; i ++ ) if( -1 == r->vterm[i].vts_idx ) break; assert( i != MAX_PAGES ); DBG_MSG( 1, (stderr, "Find vterm[%d] for pointer vts[%d]\n", i, page) ); /* clear the term_t structure */ r->vts[page] = &(r->vterm[i]); MEMSET( r->vts[page], 0, sizeof( r->vterm[0] ) ); /* set vts_idx for the vterm */ PVTS(r, page)->vts_idx = i; /* Set the profile number */ PVTS(r, page)->profileNum = profile;#ifdef TTY_GID_SUPPORT /* change group ownership of tty to "tty" */ if (gr) { PVTS(r, page)->ttymode = S_IRUSR | S_IWUSR | S_IWGRP; } else#endif /* TTY_GID_SUPPORT */ { PVTS(r, page)->ttymode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; } /* Initialize term_t (vts) structure */ PVTS( r, page )->saveLines = r->profile[profile].saveLines; /* will be set in rxvt_create_termwin */ PVTS(r, page)->vt = None;#ifdef XFT_SUPPORT PVTS(r, page)->xftvt = NULL;#endif PVTS(r, page)->tab_title = NULL;#ifdef BACKGROUND_IMAGE PVTS(r, page)->pixmap = None; PVTS(r, page)->bg.pixmap = None; PVTS(r, page)->bg.x = PVTS(r, page)->bg.y = 50;#endif PVTS(r, page)->cmd_pid = -1; PVTS(r, page)->cmd_fd = PVTS(r, page)->tty_fd = -1;#ifdef UTMP_SUPPORT PVTS(r, page)->next_utmp_action = SAVE;#endif#ifndef NO_SETOWNER_TTYDEV PVTS(r, page)->next_tty_action = SAVE;#endif PVTS(r, page)->hold = 0; /* clear hold flag */ PVTS(r, page)->dead = 0; /* clear dead flag */ PVTS(r, page)->highlight = 0; /* clear highlight flag */ /* Get term_env type */ PVTS(r, page)->termenv = rxvt_get_termenv ( r->h->rs[Rs_term_name] ? r->h->rs[Rs_term_name] : TERMENV); /* Initialize PrivateModes and SavedModes */ PVTS(r, page)->PrivateModes = PVTS(r, page)->SavedModes = PrivMode_Default; if (r->Options & Opt_scrollTtyOutputInhibit) PVTS(r, page)->PrivateModes |= PrivMode_TtyOutputInh; if (r->Options & Opt_scrollTtyKeypress) PVTS(r, page)->PrivateModes |= PrivMode_Keypress; if (!(r->Options & Opt_jumpScroll)) PVTS(r, page)->PrivateModes |= PrivMode_smoothScroll;#ifndef NO_BACKSPACE_KEY if (STRCMP(r->h->key_backspace, "DEC") == 0) PVTS(r, page)->PrivateModes |= PrivMode_HaveBackSpace;#endif#ifdef HAVE_SCROLLBARS if (rxvt_scrollbar_visible(r)) { PVTS(r, page)->PrivateModes |= PrivMode_scrollBar; PVTS(r, page)->SavedModes |= PrivMode_scrollBar; }#endif#ifdef HAVE_MENUBAR if (rxvt_menubar_visible(r)) { PVTS(r, page)->PrivateModes |= PrivMode_menuBar; PVTS(r, page)->SavedModes |= PrivMode_menuBar; }#endif /* Now set VT fg/bg color */ PVTS(r, page)->p_fg = ISSET_VTFG(r, profile) ? VTFG(r, profile) : r->h->global_fg; PVTS(r, page)->p_bg = ISSET_VTBG(r, profile) ? VTBG(r, profile) : r->h->global_bg;#ifdef XFT_SUPPORT PVTS(r, page)->p_xftfg = ISSET_VTFG(r, profile) ? VTXFTFG(r, profile) : r->h->global_xftfg; PVTS(r, page)->p_xftbg = ISSET_VTBG(r, profile) ? VTXFTBG(r, profile) : r->h->global_xftbg;#endif /* Initialize input buffer */ PVTS(r, page)->cmdbuf_ptr = PVTS(r, page)->cmdbuf_endp = PVTS(r, page)->cmdbuf_base; /* Initialize write out buffer */ PVTS(r, page)->v_buffer = PVTS(r, page)->v_bufstr = PVTS(r, page)->v_bufptr = PVTS(r, page)->v_bufend = NULL; /* Initialize checksum */ PVTS(r, page)->checksum = times (&tp); /* Set screen structure initialization flag */ PVTS(r, page)->init_screen = 0;}/*----------------------------------------------------------------------*//* rxvt_destroy_termwin() - destroy a terminal window *//* EXTPROTO */voidrxvt_destroy_termwin( rxvt_t *r, int page ){ assert (page < MAX_PAGES); assert (PVTS(r, page)->tab_title); free (PVTS(r, page)->tab_title); PVTS(r, page)->tab_title = NULL;#ifdef XFT_SUPPORT if (r->Options & Opt_xft) { if (PVTS(r, page)->xftvt) XftDrawDestroy (PVTS(r, page)->xftvt); PVTS(r, page)->xftvt = NULL; }#endif assert (None != PVTS(r, page)->vt); XDestroyWindow (r->Xdisplay, PVTS(r, page)->vt); PVTS(r, page)->vt = None;#ifdef BACKGROUND_IMAGE if (None != PVTS(r, page)->pixmap) { XFreePixmap (r->Xdisplay, PVTS(r, page)->pixmap); PVTS(r, page)->pixmap = None; } if (None != PVTS(r, page)->bg.pixmap) { XFreePixmap (r->Xdisplay, PVTS(r, page)->bg.pixmap); PVTS(r, page)->bg.pixmap = None; }#endif /* Set vterm index to -1, so that we know it's unused */ PVTS(r, page)->vts_idx = -1;}/* rxvt_create_termwin() - create a terminal window *//* EXTPROTO */voidrxvt_create_termwin( rxvt_t *r, int page, int profile, const char TAINTED *title ){#ifdef DEBUG_X char vt_name[32];#endif long vt_emask; assert( page < MAX_PAGES ); rxvt_init_vts( r, page, profile ); /* * Set the tab title */ if( title == NULL ) title = DEFAULT_TAB_TITLE; PVTS(r, page)->tab_title = (char UNTAINTED *) STRNDUP( title, MAX_TAB_TXT );#ifdef HAVE_PUTENV /* Set environment variable of tab title */ sprintf (r->h->env_tabtitle, TABTITLEENV "%s", PVTS(r, page)->tab_title); putenv (r->h->env_tabtitle);#endif PVTS(r, page)->tab_width = rxvt_tab_width (r, PVTS(r, page)->tab_title); /* ** Now switch fg/bg colors before creating VT because this ** will use the fg/bg colors */ rxvt_switch_fgbg_color (r, page); /* create the terminal window */ DBG_MSG (1, (stderr, "Create VT %d (%dx%d+%dx%d)\n", page, r->h->window_vt_x, r->h->window_vt_y, VT_WIDTH(r), VT_HEIGHT(r))); PVTS(r, page)->vt = XCreateSimpleWindow (r->Xdisplay, r->TermWin.parent, r->h->window_vt_x, r->h->window_vt_y, VT_WIDTH(r), VT_HEIGHT(r), 0, r->PixColors[Color_fg], r->PixColors[Color_bg]); assert (None != PVTS(r, page)->vt);#ifdef XFT_SUPPORT if (r->Options & Opt_xft) { PVTS(r, page)->xftvt = XftDrawCreate (r->Xdisplay, PVTS(r, page)->vt, XVISUAL, XCMAP); assert (NULL != PVTS(r, page)->xftvt); }#endif#ifdef DEBUG_X sprintf (vt_name, "vt %d window", page); rxvt_set_win_title (r, PVTS(r, page)->vt, vt_name);#endif /* define cursor for the terminal window */ rxvt_pointer_unblank(r, page); /* define event mask fo the terminal window */ vt_emask = (ExposureMask | ButtonPressMask | ButtonReleaseMask | PropertyChangeMask);#ifdef POINTER_BLANK if ((r->Options & Opt_pointerBlank)) vt_emask |= PointerMotionMask; else#endif vt_emask |= (Button1MotionMask | Button3MotionMask); XSelectInput(r->Xdisplay, PVTS(r, page)->vt, vt_emask);#ifdef TRANSPARENT /* Set transparent background */ if (r->Options & Opt_transparent) { XSetWindowBackgroundPixmap (r->Xdisplay, PVTS(r, page)->vt, ParentRelative); }#endif /* * Load the background image for terminal window when not transparent */#ifdef BACKGROUND_IMAGE# ifdef TRANSPARENT if( !(r->Options & Opt_transparent) )# endif { const char *pf = getProfileOption( r, profile, Rs_backgroundPixmap ); if( pf != NULL ) { /* Load pixmap for each individual tab */ const char *p = pf; if( (p = STRCHR(p, ';')) != NULL ) { p++; rxvt_scale_pixmap(r, page, p); } rxvt_load_bg_pixmap(r, page, pf); /* rxvt_scr_touch(r, page, True); */ } } /* if( !(r->Options & Opt_transparent) ) */#endif XMapWindow (r->Xdisplay, PVTS(r, page)->vt);}/* * Return the value of an option with profile number "profile". This function * should only be called for profile options. * * The string returned is one of r->h->rs[], so should not be freed. *//* EXTPROTO */const char *getProfileOption( rxvt_t *r, int profile, int resource ){ assert( profile >= 0 || profile <= MAX_PROFILES ); /* * Profile 0 is default, so if the profile option is unset, fall back to * profile 0. */ return (r->h->rs[resource + profile] != NULL) ? r->h->rs[resource + profile] : r->h->rs[resource];}/* INTPROTO */voidrxvt_set_borderless( rxvt_t *r ){ Atom prop; CARD32 hints; /* KDE/GNOME hints */ MWMHints mwmhints; /* Motif hints */ hints = (CARD32) 0; mwmhints.flags = MWM_HINTS_DECORATIONS; mwmhints.decorations = 0; /* Motif compatible WM */ prop = XInternAtom (r->Xdisplay, "_MOTIF_WM_HINTS", True); if (None != prop) XChangeProperty (r->Xdisplay, r->TermWin.parent, prop, prop, 32, PropModeReplace, (unsigned char*) &mwmhints, PROP_MWM_HINTS_ELEMENTS); /* GNOME compatible WM */ prop = XInternAtom (r->Xdisplay, "_WIN_HINTS", True); if (None != prop) XChangeProperty (r->Xdisplay, r->TermWin.parent, prop, prop, 32, PropModeReplace, (unsigned char*) &hints, 1); /* KDE compatible WM */ prop = XInternAtom (r->Xdisplay, "KWM_WIN_DECORATION", True); if (None != prop) XChangeProperty (r->Xdisplay, r->TermWin.parent, prop, prop, 32, PropModeReplace, (unsigned char*) &hints, 1);}/* * Send a message to an EWMH compatible window manager. *//* EXTPROTO */Statusewmh_message( Display *dpy, Window root_win, Window client_win, Atom msgAtom, long d0, long d1, long d2, long d3, long d4){ XEvent event; if( msgAtom == No
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -