diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emman.c | 1 | ||||
-rw-r--r-- | src/init.C | 1697 | ||||
-rw-r--r-- | src/rxvt.h | 1481 | ||||
-rw-r--r-- | src/rxvtdaemon.C | 2 | ||||
-rw-r--r-- | src/rxvtutil.h | 3 | ||||
-rw-r--r-- | src/screen.C | 2 |
6 files changed, 3184 insertions, 2 deletions
diff --git a/src/emman.c b/src/emman.c index 0b511f9..65cc9e0 100644 --- a/src/emman.c +++ b/src/emman.c @@ -1,5 +1,6 @@ /* enable mremap on GNU/Linux */ #ifdef __linux__ +# undef _GNU_SOURCE # define _GNU_SOURCE #endif diff --git a/src/init.C b/src/init.C new file mode 100644 index 0000000..7e78358 --- /dev/null +++ b/src/init.C @@ -0,0 +1,1697 @@ +/*----------------------------------------------------------------------* + * File: init.C + *----------------------------------------------------------------------* + * + * 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) 1996 Chuck Blake <cblake@BBN.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> + * - extensive modifications + * Copyright (c) 2003-2008 Marc Lehmann <schmorp@schmorp.de> + * Copyright (c) 2015 Emanuele Giaquinta <e.giaquinta@glauco.it> + * + * 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 3 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. + *---------------------------------------------------------------------*/ +/* + * Initialisation routines. + */ + +#include "../config.h" /* NECESSARY */ +#include "rxvt.h" /* NECESSARY */ +#include "rxvtutil.h" +#include "init.h" +#include "keyboard.h" + +#include <limits> + +#include <signal.h> + +#include <fcntl.h> + +#ifdef HAVE_XMU +# include <X11/Xmu/CurUtil.h> +#endif + +#ifdef HAVE_XSETLOCALE +# define X_LOCALE +# include <X11/Xlocale.h> +#else +# include <locale.h> +#endif + +#ifdef HAVE_NL_LANGINFO +# include <langinfo.h> +#endif + +#ifdef HAVE_STARTUP_NOTIFICATION +# define SN_API_NOT_YET_FROZEN +# include <libsn/sn-launchee.h> +#endif + +#ifdef DISPLAY_IS_IP +/* On Solaris link with -lsocket and -lnsl */ +#include <sys/types.h> +#include <sys/socket.h> + +/* these next two are probably only on Sun (not Solaris) */ +#ifdef HAVE_SYS_SOCKIO_H +#include <sys/sockio.h> +#endif +#ifdef HAVE_SYS_BYTEORDER_H +#include <sys/byteorder.h> +#endif + +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <net/if_arp.h> + +static char * ecb_cold +rxvt_network_display (const char *display) +{ + char buffer[1024], *rval = NULL; + struct ifconf ifc; + struct ifreq *ifr; + int i, skfd; + + if (display[0] != ':' && strncmp (display, "unix:", 5)) + return (char *) display; /* nothing to do */ + + ifc.ifc_len = sizeof (buffer); /* Get names of all ifaces */ + ifc.ifc_buf = buffer; + + if ((skfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + { + perror ("socket"); + return NULL; + } + + if (ioctl (skfd, SIOCGIFCONF, &ifc) < 0) + { + perror ("SIOCGIFCONF"); + close (skfd); + return NULL; + } + + for (i = 0, ifr = ifc.ifc_req; + i < (ifc.ifc_len / sizeof (struct ifreq)); + i++, ifr++) + { + struct ifreq ifr2; + + strcpy (ifr2.ifr_name, ifr->ifr_name); + + if (ioctl (skfd, SIOCGIFADDR, &ifr2) >= 0) + { + unsigned long addr; + struct sockaddr_in *p_addr; + + p_addr = (struct sockaddr_in *) &ifr2.ifr_addr; + addr = htonl ((unsigned long)p_addr->sin_addr.s_addr); + + /* + * not "0.0.0.0" or "127.0.0.1" - so format the address + */ + if (addr && addr != 0x7F000001) + { + char *colon = strchr (display, ':'); + + if (colon == NULL) + colon = ":0.0"; + + rval = rxvt_malloc (strlen (colon) + 16); + sprintf (rval, "%d.%d.%d.%d%s", + (int) ((addr >> 030) & 0xFF), + (int) ((addr >> 020) & 0xFF), + (int) ((addr >> 010) & 0xFF), + (int) (addr & 0xFF), colon); + break; + } + } + } + + close (skfd); + + return rval; +} +#endif + +#define NULL_5 \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, + +#define NULL_10 \ + NULL_5 \ + NULL_5 + +#define NULL_40 \ + NULL_10 \ + NULL_10 \ + NULL_10 \ + NULL_10 + +#define NULL_50 \ + NULL_40 \ + NULL_10 + +#define NULL_100 \ + NULL_50 \ + NULL_50 + +static const char *const def_colorName[] = + { + COLOR_FOREGROUND, + COLOR_BACKGROUND, + /* low-intensity colors */ + "rgb:00/00/00", // 0: black (Black) + "rgb:cd/00/00", // 1: red (Red3) + "rgb:00/cd/00", // 2: green (Green3) + "rgb:cd/cd/00", // 3: yellow (Yellow3) + "rgb:00/00/cd", // 4: blue (Blue3) + "rgb:cd/00/cd", // 5: magenta (Magenta3) + "rgb:00/cd/cd", // 6: cyan (Cyan3) +# ifdef XTERM_COLORS + "rgb:e5/e5/e5", // 7: white (Grey90) +# else + "rgb:fa/eb/d7", // 7: white (AntiqueWhite) +# endif + /* high-intensity colors */ +# ifdef XTERM_COLORS + "rgb:4d/4d/4d", // 8: bright black (Grey30) +# else + "rgb:40/40/40", // 8: bright black (Grey25) +# endif + "rgb:ff/00/00", // 1/9: bright red (Reed) + "rgb:00/ff/00", // 2/10: bright green (Green) + "rgb:ff/ff/00", // 3/11: bright yellow (Yellow) + "rgb:00/00/ff", // 4/12: bright blue (Blue) + "rgb:ff/00/ff", // 5/13: bright magenta (Magenta) + "rgb:00/ff/ff", // 6/14: bright cyan (Cyan) + "rgb:ff/ff/ff", // 7/15: bright white (White) + +#if !USE_256_COLORS + // 88 xterm colours + "rgb:00/00/00", + "rgb:00/00/8b", + "rgb:00/00/cd", + "rgb:00/00/ff", + "rgb:00/8b/00", + "rgb:00/8b/8b", + "rgb:00/8b/cd", + "rgb:00/8b/ff", + "rgb:00/cd/00", + "rgb:00/cd/8b", + "rgb:00/cd/cd", + "rgb:00/cd/ff", + "rgb:00/ff/00", + "rgb:00/ff/8b", + "rgb:00/ff/cd", + "rgb:00/ff/ff", + "rgb:8b/00/00", + "rgb:8b/00/8b", + "rgb:8b/00/cd", + "rgb:8b/00/ff", + "rgb:8b/8b/00", + "rgb:8b/8b/8b", + "rgb:8b/8b/cd", + "rgb:8b/8b/ff", + "rgb:8b/cd/00", + "rgb:8b/cd/8b", + "rgb:8b/cd/cd", + "rgb:8b/cd/ff", + "rgb:8b/ff/00", + "rgb:8b/ff/8b", + "rgb:8b/ff/cd", + "rgb:8b/ff/ff", + "rgb:cd/00/00", + "rgb:cd/00/8b", + "rgb:cd/00/cd", + "rgb:cd/00/ff", + "rgb:cd/8b/00", + "rgb:cd/8b/8b", + "rgb:cd/8b/cd", + "rgb:cd/8b/ff", + "rgb:cd/cd/00", + "rgb:cd/cd/8b", + "rgb:cd/cd/cd", + "rgb:cd/cd/ff", + "rgb:cd/ff/00", + "rgb:cd/ff/8b", + "rgb:cd/ff/cd", + "rgb:cd/ff/ff", + "rgb:ff/00/00", + "rgb:ff/00/8b", + "rgb:ff/00/cd", + "rgb:ff/00/ff", + "rgb:ff/8b/00", + "rgb:ff/8b/8b", + "rgb:ff/8b/cd", + "rgb:ff/8b/ff", + "rgb:ff/cd/00", + "rgb:ff/cd/8b", + "rgb:ff/cd/cd", + "rgb:ff/cd/ff", + "rgb:ff/ff/00", + "rgb:ff/ff/8b", + "rgb:ff/ff/cd", + "rgb:ff/ff/ff", + "rgb:2e/2e/2e", + "rgb:5c/5c/5c", + "rgb:73/73/73", + "rgb:8b/8b/8b", + "rgb:a2/a2/a2", + "rgb:b9/b9/b9", + "rgb:d0/d0/d0", + "rgb:e7/e7/e7", + NULL_100 + NULL_40 + NULL, + NULL, + NULL, + NULL, +#else + // 256 xterm colours + "rgb:00/00/00", + "rgb:00/00/5f", + "rgb:00/00/87", + "rgb:00/00/af", + "rgb:00/00/d7", + "rgb:00/00/ff", + "rgb:00/5f/00", + "rgb:00/5f/5f", + "rgb:00/5f/87", + "rgb:00/5f/af", + "rgb:00/5f/d7", + "rgb:00/5f/ff", + "rgb:00/87/00", + "rgb:00/87/5f", + "rgb:00/87/87", + "rgb:00/87/af", + "rgb:00/87/d7", + "rgb:00/87/ff", + "rgb:00/af/00", + "rgb:00/af/5f", + "rgb:00/af/87", + "rgb:00/af/af", + "rgb:00/af/d7", + "rgb:00/af/ff", + "rgb:00/d7/00", + "rgb:00/d7/5f", + "rgb:00/d7/87", + "rgb:00/d7/af", + "rgb:00/d7/d7", + "rgb:00/d7/ff", + "rgb:00/ff/00", + "rgb:00/ff/5f", + "rgb:00/ff/87", + "rgb:00/ff/af", + "rgb:00/ff/d7", + "rgb:00/ff/ff", + "rgb:5f/00/00", + "rgb:5f/00/5f", + "rgb:5f/00/87", + "rgb:5f/00/af", + "rgb:5f/00/d7", + "rgb:5f/00/ff", + "rgb:5f/5f/00", + "rgb:5f/5f/5f", + "rgb:5f/5f/87", + "rgb:5f/5f/af", + "rgb:5f/5f/d7", + "rgb:5f/5f/ff", + "rgb:5f/87/00", + "rgb:5f/87/5f", + "rgb:5f/87/87", + "rgb:5f/87/af", + "rgb:5f/87/d7", + "rgb:5f/87/ff", + "rgb:5f/af/00", + "rgb:5f/af/5f", + "rgb:5f/af/87", + "rgb:5f/af/af", + "rgb:5f/af/d7", + "rgb:5f/af/ff", + "rgb:5f/d7/00", + "rgb:5f/d7/5f", + "rgb:5f/d7/87", + "rgb:5f/d7/af", + "rgb:5f/d7/d7", + "rgb:5f/d7/ff", + "rgb:5f/ff/00", + "rgb:5f/ff/5f", + "rgb:5f/ff/87", + "rgb:5f/ff/af", + "rgb:5f/ff/d7", + "rgb:5f/ff/ff", + "rgb:87/00/00", + "rgb:87/00/5f", + "rgb:87/00/87", + "rgb:87/00/af", + "rgb:87/00/d7", + "rgb:87/00/ff", + "rgb:87/5f/00", + "rgb:87/5f/5f", + "rgb:87/5f/87", + "rgb:87/5f/af", + "rgb:87/5f/d7", + "rgb:87/5f/ff", + "rgb:87/87/00", + "rgb:87/87/5f", + "rgb:87/87/87", + "rgb:87/87/af", + "rgb:87/87/d7", + "rgb:87/87/ff", + "rgb:87/af/00", + "rgb:87/af/5f", + "rgb:87/af/87", + "rgb:87/af/af", + "rgb:87/af/d7", + "rgb:87/af/ff", + "rgb:87/d7/00", + "rgb:87/d7/5f", + "rgb:87/d7/87", + "rgb:87/d7/af", + "rgb:87/d7/d7", + "rgb:87/d7/ff", + "rgb:87/ff/00", + "rgb:87/ff/5f", + "rgb:87/ff/87", + "rgb:87/ff/af", + "rgb:87/ff/d7", + "rgb:87/ff/ff", + "rgb:af/00/00", + "rgb:af/00/5f", + "rgb:af/00/87", + "rgb:af/00/af", + "rgb:af/00/d7", + "rgb:af/00/ff", + "rgb:af/5f/00", + "rgb:af/5f/5f", + "rgb:af/5f/87", + "rgb:af/5f/af", + "rgb:af/5f/d7", + "rgb:af/5f/ff", + "rgb:af/87/00", + "rgb:af/87/5f", + "rgb:af/87/87", + "rgb:af/87/af", + "rgb:af/87/d7", + "rgb:af/87/ff", + "rgb:af/af/00", + "rgb:af/af/5f", + "rgb:af/af/87", + "rgb:af/af/af", + "rgb:af/af/d7", + "rgb:af/af/ff", + "rgb:af/d7/00", + "rgb:af/d7/5f", + "rgb:af/d7/87", + "rgb:af/d7/af", + "rgb:af/d7/d7", + "rgb:af/d7/ff", + "rgb:af/ff/00", + "rgb:af/ff/5f", + "rgb:af/ff/87", + "rgb:af/ff/af", + "rgb:af/ff/d7", + "rgb:af/ff/ff", + "rgb:d7/00/00", + "rgb:d7/00/5f", + "rgb:d7/00/87", + "rgb:d7/00/af", + "rgb:d7/00/d7", + "rgb:d7/00/ff", + "rgb:d7/5f/00", + "rgb:d7/5f/5f", + "rgb:d7/5f/87", + "rgb:d7/5f/af", + "rgb:d7/5f/d7", + "rgb:d7/5f/ff", + "rgb:d7/87/00", + "rgb:d7/87/5f", + "rgb:d7/87/87", + "rgb:d7/87/af", + "rgb:d7/87/d7", + "rgb:d7/87/ff", + "rgb:d7/af/00", + "rgb:d7/af/5f", + "rgb:d7/af/87", + "rgb:d7/af/af", + "rgb:d7/af/d7", + "rgb:d7/af/ff", + "rgb:d7/d7/00", + "rgb:d7/d7/5f", + "rgb:d7/d7/87", + "rgb:d7/d7/af", + "rgb:d7/d7/d7", + "rgb:d7/d7/ff", + "rgb:d7/ff/00", + "rgb:d7/ff/5f", + "rgb:d7/ff/87", + "rgb:d7/ff/af", + "rgb:d7/ff/d7", + "rgb:d7/ff/ff", + "rgb:ff/00/00", + "rgb:ff/00/5f", + "rgb:ff/00/87", + "rgb:ff/00/af", + "rgb:ff/00/d7", + "rgb:ff/00/ff", + "rgb:ff/5f/00", + "rgb:ff/5f/5f", + "rgb:ff/5f/87", + "rgb:ff/5f/af", + "rgb:ff/5f/d7", + "rgb:ff/5f/ff", + "rgb:ff/87/00", + "rgb:ff/87/5f", + "rgb:ff/87/87", + "rgb:ff/87/af", + "rgb:ff/87/d7", + "rgb:ff/87/ff", + "rgb:ff/af/00", + "rgb:ff/af/5f", + "rgb:ff/af/87", + "rgb:ff/af/af", + "rgb:ff/af/d7", + "rgb:ff/af/ff", + "rgb:ff/d7/00", + "rgb:ff/d7/5f", + "rgb:ff/d7/87", + "rgb:ff/d7/af", + "rgb:ff/d7/d7", + "rgb:ff/d7/ff", + "rgb:ff/ff/00", + "rgb:ff/ff/5f", + "rgb:ff/ff/87", + "rgb:ff/ff/af", + "rgb:ff/ff/d7", + "rgb:ff/ff/ff", + "rgb:08/08/08", + "rgb:12/12/12", + "rgb:1c/1c/1c", + "rgb:26/26/26", + "rgb:30/30/30", + "rgb:3a/3a/3a", + "rgb:44/44/44", + "rgb:4e/4e/4e", + "rgb:58/58/58", + "rgb:62/62/62", + "rgb:6c/6c/6c", + "rgb:76/76/76", + "rgb:80/80/80", + "rgb:8a/8a/8a", + "rgb:94/94/94", + "rgb:9e/9e/9e", + "rgb:a8/a8/a8", + "rgb:b2/b2/b2", + "rgb:bc/bc/bc", + "rgb:c6/c6/c6", + "rgb:d0/d0/d0", + "rgb:da/da/da", + "rgb:e4/e4/e4", + "rgb:ee/ee/ee", + NULL_100 + NULL_100 + NULL_40 + NULL_5 +#endif + +#ifndef NO_CURSORCOLOR + COLOR_CURSOR_BACKGROUND, + COLOR_CURSOR_FOREGROUND, +#endif /* ! NO_CURSORCOLOR */ + NULL, /* Color_pointer_fg */ + NULL, /* Color_pointer_bg */ + NULL, /* Color_border */ +#ifndef NO_BOLD_UNDERLINE_REVERSE + NULL, /* Color_BD */ + NULL, /* Color_IT */ + NULL, /* Color_UL */ + NULL, /* Color_RV */ +#endif /* ! NO_BOLD_UNDERLINE_REVERSE */ +#if ENABLE_FRILLS + NULL, // Color_underline +#endif +#ifdef OPTION_HC + NULL, + NULL, +#endif + COLOR_SCROLLBAR, +#ifdef RXVT_SCROLLBAR + COLOR_SCROLLTROUGH, +#endif +#if OFF_FOCUS_FADING + "rgb:00/00/00", +#endif + }; + +void +rxvt_term::init_vars () +{ + pix_colors = pix_colors_focused; + + MEvent.time = CurrentTime; + MEvent.button = AnyButton; + want_refresh = 1; + priv_modes = SavedModes = PrivMode_Default; + ncol = 80; + nrow = 24; + int_bwidth = INTERNALBORDERWIDTH; + ext_bwidth = EXTERNALBORDERWIDTH; + lineSpace = LINESPACE; + letterSpace = LETTERSPACE; + saveLines = SAVELINES; + + refresh_type = SLOW_REFRESH; + + oldcursor.row = oldcursor.col = -1; + + set_option (Opt_scrollBar); + set_option (Opt_scrollTtyOutput); + set_option (Opt_jumpScroll); + set_option (Opt_skipScroll); + set_option (Opt_secondaryScreen); + set_option (Opt_secondaryScroll); + set_option (Opt_pastableTabs); + set_option (Opt_intensityStyles); + set_option (Opt_iso14755); + set_option (Opt_iso14755_52); + set_option (Opt_buffered); +} + +#if ENABLE_PERL +static void +rxvt_perl_parse_resource (rxvt_term *term, const char *k, const char *v) +{ + rxvt_perl.parse_resource (term, k, false, false, 0, v); +} +#endif + +/*----------------------------------------------------------------------*/ +const char ** +rxvt_term::init_resources (int argc, const char *const *argv) +{ + int i; + const char **cmd_argv; + + rs[Rs_name] = rxvt_basename (argv[0]); + + /* + * Open display, get options/resources and create the window + */ + + if ((rs[Rs_display_name] = getenv ("DISPLAY")) == NULL) + rs[Rs_display_name] = ":0"; + + cmd_argv = get_options (argc, argv); + + if (!(display = displays.get (rs[Rs_display_name]))) + rxvt_fatal ("can't open display %s, aborting.\n", rs[Rs_display_name]); + + // using a local pointer decreases code size a lot + xa = display->xa; + + set (display); + extract_resources (); + +#if ENABLE_FRILLS + if (rs[Rs_visual]) + select_visual (strtol (rs[Rs_visual], 0, 0)); + else if (rs[Rs_depth]) + select_depth (strtol (rs[Rs_depth], 0, 0)); +#endif + + for (int i = NUM_RESOURCES; i--; ) + if (rs [i] == resval_undef) + rs [i] = 0; + +#if ENABLE_PERL + if (!rs[Rs_perl_ext_1]) + rs[Rs_perl_ext_1] = "default"; + + if ((rs[Rs_perl_ext_1] && *rs[Rs_perl_ext_1]) + || (rs[Rs_perl_ext_2] && *rs[Rs_perl_ext_2]) + || (rs[Rs_perl_eval] && *rs[Rs_perl_eval])) + { + rxvt_perl.init (this); + enumerate_resources (rxvt_perl_parse_resource); + HOOK_INVOKE ((this, HOOK_INIT, DT_END)); + } +#endif + + // must be called after initialising the perl interpreter as it + // may invoke the `on_register_command' hook + extract_keysym_resources (); + + /* + * set any defaults not already set + */ + if (cmd_argv && cmd_argv[0]) + { + if (!rs[Rs_title]) + rs[Rs_title] = rxvt_basename (cmd_argv[0]); + + if (!rs[Rs_iconName]) + rs[Rs_iconName] = rs[Rs_title]; + } + else + { + if (!rs[Rs_title]) + rs[Rs_title] = rs[Rs_name]; + + if (!rs[Rs_iconName]) + rs[Rs_iconName] = rs[Rs_name]; + } + + if (rs[Rs_saveLines] && (i = atoi (rs[Rs_saveLines])) >= 0) + saveLines = min (i, MAX_SAVELINES); + +#if ENABLE_FRILLS + if (rs[Rs_int_bwidth] && (i = atoi (rs[Rs_int_bwidth])) >= 0) + int_bwidth = min (i, std::numeric_limits<int16_t>::max ()); + + if (rs[Rs_ext_bwidth] && (i = atoi (rs[Rs_ext_bwidth])) >= 0) + ext_bwidth = min (i, std::numeric_limits<int16_t>::max ()); + + if (rs[Rs_lineSpace] && (i = atoi (rs[Rs_lineSpace])) >= 0) + lineSpace = min (i, std::numeric_limits<int16_t>::max ()); + + if (rs[Rs_letterSpace]) + letterSpace = atoi (rs[Rs_letterSpace]); +#endif + +#ifdef POINTER_BLANK + if (rs[Rs_pointerBlankDelay] && (i = atoi (rs[Rs_pointerBlankDelay])) >= 0) + pointerBlankDelay = i; + else + pointerBlankDelay = 2; +#endif + + if (rs[Rs_multiClickTime] && (i = atoi (rs[Rs_multiClickTime])) >= 0) + multiClickTime = i; + else + multiClickTime = 500; + + cursor_type = option (Opt_cursorUnderline) ? 1 : 0; + + /* no point having a scrollbar without having any scrollback! */ + if (!saveLines) + set_option (Opt_scrollBar, 0); + + if (!rs[Rs_cutchars]) + rs[Rs_cutchars] = CUTCHARS; + +#ifndef NO_BACKSPACE_KEY + if (!rs[Rs_backspace_key]) +# ifdef DEFAULT_BACKSPACE + rs[Rs_backspace_key] = DEFAULT_BACKSPACE; +# else + rs[Rs_backspace_key] = "DEC"; /* can toggle between \010 or \177 */ +# endif +#endif + +#ifndef NO_DELETE_KEY + if (!rs[Rs_delete_key]) +# ifdef DEFAULT_DELETE + rs[Rs_delete_key] = DEFAULT_DELETE; +# else + rs[Rs_delete_key] = "\033[3~"; +# endif +#endif + + scrollBar.setup (this); + +#ifdef XTERM_REVERSE_VIDEO + /* this is how xterm implements reverseVideo */ + if (option (Opt_reverseVideo)) + { + if (!rs[Rs_color + Color_fg]) + rs[Rs_color + Color_fg] = def_colorName[Color_bg]; + + if (!rs[Rs_color + Color_bg]) + rs[Rs_color + Color_bg] = def_colorName[Color_fg]; + } +#endif + + for (i = 0; i < NRS_COLORS; i++) + if (!rs[Rs_color + i]) + rs[Rs_color + i] = def_colorName[i]; + +#ifndef XTERM_REVERSE_VIDEO + /* this is how we implement reverseVideo */ + if (option (Opt_reverseVideo)) + ::swap (rs[Rs_color + Color_fg], rs[Rs_color + Color_bg]); +#endif + + /* convenient aliases for setting fg/bg to colors */ + color_aliases (Color_fg); + color_aliases (Color_bg); +#ifndef NO_CURSORCOLOR + color_aliases (Color_cursor); + color_aliases (Color_cursor2); +#endif /* NO_CURSORCOLOR */ + color_aliases (Color_pointer_fg); + color_aliases (Color_pointer_bg); + color_aliases (Color_border); +#ifndef NO_BOLD_UNDERLINE_REVERSE + color_aliases (Color_BD); + color_aliases (Color_UL); + color_aliases (Color_RV); +#endif /* ! NO_BOLD_UNDERLINE_REVERSE */ + + if (!rs[Rs_color + Color_border]) + rs[Rs_color + Color_border] = rs[Rs_color + Color_bg]; + + return cmd_argv; +} + +/*----------------------------------------------------------------------*/ +void +rxvt_term::init (stringvec *argv, stringvec *envv) +{ + argv->push_back (0); + envv->push_back (0); + + this->argv = argv; + this->envv = envv; + + env = new char *[this->envv->size ()]; + for (int i = 0; i < this->envv->size (); i++) + env[i] = this->envv->at (i); + + init2 (argv->size () - 1, argv->begin ()); +} + +void +rxvt_term::init (int argc, const char *const *argv, const char *const *envv) +{ +#if ENABLE_PERL + // perl might want to access the stringvecs later, so we need to copy them + stringvec *args = new stringvec; + for (int i = 0; i < argc; i++) + args->push_back (strdup (argv [i])); + + stringvec *envs = new stringvec; + for (const char *const *var = envv; *var; var++) + envs->push_back (strdup (*var)); + + init (args, envs); +#else + init2 (argc, argv); +#endif +} + +void +rxvt_term::init2 (int argc, const char *const *argv) +{ + SET_R (this); + set_locale (""); + set_environ (env); // a few things in X do not call setlocale :( + + init_vars (); + + const char **cmd_argv = init_resources (argc, argv); + +#ifdef KEYSYM_RESOURCE + keyboard->register_done (); +#endif + + if (const char *path = rs[Rs_chdir]) + if (*path) // ignored if empty + { + if (*path != '/') + rxvt_fatal ("specified shell working directory must start with a slash, aborting.\n"); + + if (chdir (path)) + rxvt_fatal ("unable to change into specified shell working directory, aborting.\n"); + } + + if (option (Opt_scrollBar)) + scrollBar.state = SB_STATE_IDLE; /* set existence for size calculations */ + + pty = ptytty::create (); + + create_windows (argc, argv); + + init_xlocale (); + + scr_poweron (); // initialize screen + +#if 0 + XSynchronize (dpy, True); +#endif + + if (option (Opt_scrollBar)) + scrollBar.resize (); /* create and map scrollbar */ + +#if ENABLE_PERL + rootwin_ev.start (display, display->root); +#endif + + init_done = 1; + + init_command (cmd_argv); + + if (pty->pty >= 0) + pty_ev.start (pty->pty, ev::READ); + + HOOK_INVOKE ((this, HOOK_START, DT_END)); + +#if ENABLE_XEMBED + if (rs[Rs_embed]) + { + long info[2] = { 0, XEMBED_MAPPED }; + + XChangeProperty (dpy, parent, xa[XA_XEMBED_INFO], xa[XA_XEMBED_INFO], + 32, PropModeReplace, (unsigned char *)&info, 2); + } +#endif + +#if HAVE_STARTUP_NOTIFICATION + SnDisplay *snDisplay; + SnLauncheeContext *snContext; + + snDisplay = sn_display_new (dpy, NULL, NULL); + snContext = sn_launchee_context_new_from_environment (snDisplay, DefaultScreen (dpy)); + + /* Tell the window manager that this window is part of the startup context */ + if (snContext) + sn_launchee_context_setup_window (snContext, parent); +#endif + + XMapWindow (dpy, vt); + XMapWindow (dpy, parent); + +#if HAVE_STARTUP_NOTIFICATION + if (snContext) + { + /* Mark the startup process as complete */ + sn_launchee_context_complete (snContext); + + sn_launchee_context_unref (snContext); + } + + sn_display_unref (snDisplay); +#endif + + refresh_check (); +} + +/*----------------------------------------------------------------------*/ +void +rxvt_term::init_env () +{ + char *val; + char *env_display; + char *env_windowid; + char *env_colorfgbg; + char *env_term; + +#ifdef DISPLAY_IS_IP + /* Fixup display_name for export over pty to any interested terminal + * clients via "ESC[7n" (e.g. shells). Note we use the pure IP number + * (for the first non-loopback interface) that we get from + * rxvt_network_display (). This is more "name-resolution-portable", if you + * will, and probably allows for faster x-client startup if your name + * server is beyond a slow link or overloaded at client startup. Of + * course that only helps the shell's child processes, not us. + * + * Giving out the display_name also affords a potential security hole + */ + val = rxvt_network_display (rs[Rs_display_name]); + rs[Rs_display_name] = (const char *)val; + + if (val == NULL) +#endif /* DISPLAY_IS_IP */ + val = XDisplayString (dpy); + + if (rs[Rs_display_name] == NULL) + rs[Rs_display_name] = val; /* use broken `:0' value */ + + env_display = (char *)rxvt_malloc (strlen (val) + 9); + + sprintf (env_display, "DISPLAY=%s", val); + + env_windowid = (char *)rxvt_malloc (21); + sprintf (env_windowid, "WINDOWID=%lu", (unsigned long)parent); + + /* add entries to the environment: + * @ DISPLAY: in case we started with -display + * @ WINDOWID: X window id number of the window + * @ COLORTERM: terminal sub-name and also indicates its color + * @ TERM: terminal name + * @ TERMINFO: path to terminfo directory + * @ COLORFGBG: fg;bg color codes + */ + putenv (env_display); + putenv (env_windowid); + + env_colorfgbg = get_colorfgbg (); + putenv (env_colorfgbg); + +#ifdef RXVT_TERMINFO + putenv ("TERMINFO=" RXVT_TERMINFO); +#endif + + if (depth <= 2) + putenv ((char *)"COLORTERM=" COLORTERMENV "-mono"); + else + putenv ((char *)"COLORTERM=" COLORTERMENVFULL); + + if (rs[Rs_term_name] != NULL) + { + env_term = (char *)rxvt_malloc (strlen (rs[Rs_term_name]) + 6); + sprintf (env_term, "TERM=%s", rs[Rs_term_name]); + putenv (env_term); + } + else + putenv ((char *)"TERM=" TERMENV); + +#ifdef HAVE_UNSETENV + /* avoid passing old settings and confusing term size */ + unsetenv ("LINES"); + unsetenv ("COLUMNS"); + unsetenv ("TERMCAP"); /* terminfo should be okay */ +#endif /* HAVE_UNSETENV */ +} + +/*----------------------------------------------------------------------*/ +void +rxvt_term::set_locale (const char *locale) +{ + set_environ (env); + + free (this->locale); + this->locale = setlocale (LC_CTYPE, locale); + + if (!this->locale) + { + if (*locale) + { + rxvt_warn ("unable to set locale \"%s\", using C locale instead.\n", locale); + setlocale (LC_CTYPE, "C"); + } + else + rxvt_warn ("default locale unavailable, check LC_* and LANG variables. Continuing.\n"); + + this->locale = (char *)"C"; /* strdup'ed below */ + } + + + this->locale = strdup (this->locale); + SET_LOCALE (this->locale); + mbstate.reset (); + +#if HAVE_NL_LANGINFO + char *codeset = nl_langinfo (CODESET); + // /^UTF.?8/i + enc_utf8 = (codeset[0] == 'U' || codeset[0] == 'u') + && (codeset[1] == 'T' || codeset[1] == 't') + && (codeset[2] == 'F' || codeset[2] == 'f') + && (codeset[3] == '8' || codeset[4] == '8'); +#else + enc_utf8 = 0; +#endif +} + +void +rxvt_term::init_xlocale () +{ + set_environ (env); + +#if USE_XIM + if (!locale) + rxvt_warn ("setting locale failed, continuing without locale support.\n"); + else + { + set_string_property (xa[XA_WM_LOCALE_NAME], locale); + + if (!XSupportsLocale ()) + { + rxvt_warn ("the locale is not supported by Xlib, continuing without locale support.\n"); + return; + } + + im_ev.start (display); + + /* see if we can connect already */ + im_cb (); + } +#endif +} + +/*----------------------------------------------------------------------*/ +void +rxvt_term::init_command (const char *const *argv) +{ + /* + * Initialize the command connection. + * This should be called after the X server connection is established. + */ + +#ifdef META8_OPTION + meta_char = option (Opt_meta8) ? 0x80 : C0_ESC; +#endif + + get_ourmods (); + + if (!option (Opt_scrollTtyOutput)) + priv_modes |= PrivMode_TtyOutputInh; + if (option (Opt_scrollTtyKeypress)) + priv_modes |= PrivMode_Keypress; + if (!option (Opt_jumpScroll)) + priv_modes |= PrivMode_smoothScroll; + +#ifndef NO_BACKSPACE_KEY + if (strcmp (rs[Rs_backspace_key], "DEC") == 0) + priv_modes |= PrivMode_HaveBackSpace; +#endif + + /* add value for scrollBar */ + if (scrollBar.state) + { + priv_modes |= PrivMode_scrollBar; + SavedModes |= PrivMode_scrollBar; + } + + run_command (argv); +} + +/*----------------------------------------------------------------------*/ +void +rxvt_term::get_colors () +{ + int i; + +#ifdef OFF_FOCUS_FADING + pix_colors = pix_colors_focused; +#endif + + for (i = 0; i < NRS_COLORS; i++) + if (const char *name = rs[Rs_color + i]) + set_color (pix_colors [i], name); + + /* + * get scrollBar shadow colors + * + * The calculations of topShadow/bottomShadow values are adapted + * from the fvwm window manager. + */ +#ifdef RXVT_SCROLLBAR + pix_colors [Color_scroll].fade (this, 50, pix_colors [Color_bottomShadow]); + + rgba cscroll; + pix_colors [Color_scroll].get (cscroll); + + /* topShadowColor */ + if (!pix_colors[Color_topShadow].set (this, + rgba ( + min ((int)rgba::MAX_CC, max (cscroll.r / 5, cscroll.r) * 7 / 5), + min ((int)rgba::MAX_CC, max (cscroll.g / 5, cscroll.g) * 7 / 5), + min ((int)rgba::MAX_CC, max (cscroll.b / 5, cscroll.b) * 7 / 5), + cscroll.a) + )) + alias_color (Color_topShadow, Color_White); +#endif + +#ifdef OFF_FOCUS_FADING + for (i = 0; i < NRS_COLORS; i++) + update_fade_color (i, true); +#endif +} + +/*----------------------------------------------------------------------*/ +/* color aliases, fg/bg bright-bold */ +void +rxvt_term::color_aliases (int idx) +{ + if (rs[Rs_color + idx] && isdigit (*rs[Rs_color + idx])) + { + int i = atoi (rs[Rs_color + idx]); + + if (i >= 8 && i <= 15) + /* bright colors */ + rs[Rs_color + idx] = rs[Rs_color + minBrightCOLOR + i - 8]; + else if (i >= 0 && i <= 7) + /* normal colors */ + rs[Rs_color + idx] = rs[Rs_color + minCOLOR + i]; + } +} + +/*----------------------------------------------------------------------*/ +/* + * Probe the modifier keymap to get the Meta (Alt) and Num_Lock settings + * Use resource ``modifier'' to override the Meta modifier + */ +void +rxvt_term::get_ourmods () +{ + int i, j, k; + int requestedmeta, realmeta, realalt; + const char *cm, *rsmod; + XModifierKeymap *map; + KeyCode *kc; + const unsigned int modmasks[] = + { + Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask + }; + + requestedmeta = realmeta = realalt = 0; + rsmod = rs[Rs_modifier]; + + if (rsmod + && strcasecmp (rsmod, "mod1") >= 0 && strcasecmp (rsmod, "mod5") <= 0) + requestedmeta = rsmod[3] - '0'; + + map = XGetModifierMapping (dpy); + kc = map->modifiermap; + + for (i = 1; i < 6; i++) + { + k = (i + 2) * map->max_keypermod; /* skip shift/lock/control */ + + for (j = map->max_keypermod; j--; k++) + { + if (kc[k] == 0) + break; + + switch (rxvt_XKeycodeToKe |