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_XKeycodeToKeysym (dpy, kc[k], 0)) + { + case XK_Num_Lock: + ModNumLockMask = modmasks[i - 1]; + continue; + + case XK_ISO_Level3_Shift: + ModLevel3Mask = modmasks[i - 1]; + continue; + + case XK_Meta_L: + case XK_Meta_R: + cm = "meta"; + realmeta = i; + break; + + case XK_Alt_L: + case XK_Alt_R: + cm = "alt"; + realalt = i; + break; + + case XK_Super_L: + case XK_Super_R: + cm = "super"; + break; + + case XK_Hyper_L: + case XK_Hyper_R: + cm = "hyper"; + break; + + default: + continue; + } + + if (rsmod && strncasecmp (rsmod, cm, strlen (cm)) == 0) + requestedmeta = i; + } + } + + XFreeModifiermap (map); + + i = requestedmeta ? requestedmeta + : realmeta ? realmeta + : realalt ? realalt + : 0; + + if (i) + ModMetaMask = modmasks[i - 1]; +} + +void +rxvt_term::set_icon (const char *file) +{ +#if HAVE_PIXBUF && ENABLE_EWMH + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (file, NULL); + if (!pixbuf) + { + rxvt_warn ("Loading image icon failed, continuing without.\n"); + return; + } + + unsigned int w = gdk_pixbuf_get_width (pixbuf); + unsigned int h = gdk_pixbuf_get_height (pixbuf); + + if (!IN_RANGE_INC (w, 1, 16383) || !IN_RANGE_INC (h, 1, 16383)) + { + rxvt_warn ("Icon image too big, continuing without.\n"); + g_object_unref (pixbuf); + return; + } + + if (long *buffer = (long *)malloc ((2 + w * h) * sizeof (long))) + { + int rowstride = gdk_pixbuf_get_rowstride (pixbuf); + unsigned char *row = gdk_pixbuf_get_pixels (pixbuf); + int channels = gdk_pixbuf_get_n_channels (pixbuf); + + buffer [0] = w; + buffer [1] = h; + for (int i = 0; i < h; i++) + { + for (int j = 0; j < w; j++) + { + unsigned char *pixel = row + j * channels; + long value; + + if (channels == 4) + value = pixel[3]; + else + value = (unsigned char)0x00ff; + + value = (value << 8) + pixel[0]; + value = (value << 8) + pixel[1]; + value = (value << 8) + pixel[2]; + buffer[(i * w + j) + 2] = value; + } + + row += rowstride; + } + + XChangeProperty (dpy, parent, xa[XA_NET_WM_ICON], XA_CARDINAL, 32, + PropModeReplace, (const unsigned char *) buffer, 2 + w * h); + free (buffer); + } + else + rxvt_warn ("Memory allocation for icon hint failed, continuing without.\n"); + + g_object_unref (pixbuf); +#endif +} + +/*----------------------------------------------------------------------*/ +/* Open and map the window */ +void +rxvt_term::create_windows (int argc, const char *const *argv) +{ + XClassHint classHint; + XWMHints wmHint; +#if ENABLE_FRILLS + MWMHints mwmhints = { }; +#endif + XGCValues gcvalue; + XSetWindowAttributes attributes; + Window top, parent; + + dLocal (Display *, dpy); + + /* grab colors before netscape does */ + get_colors (); + + if (!set_fonts ()) + rxvt_fatal ("unable to load base fontset, please specify a valid one using -fn, aborting.\n"); + + parent = display->root; + + attributes.override_redirect = !!option (Opt_override_redirect); + +#if ENABLE_FRILLS + if (option (Opt_borderLess)) + { + if (XInternAtom (dpy, "_MOTIF_WM_INFO", True) == None) + { + // rxvt_warn("Window Manager does not support MWM hints. Bypassing window manager control for borderless window.\n"); + attributes.override_redirect = true; + } + else + { + mwmhints.flags = MWM_HINTS_DECORATIONS; + } + } +#endif + +#if ENABLE_XEMBED + if (rs[Rs_embed]) + { + XWindowAttributes wattr; + + parent = strtol (rs[Rs_embed], 0, 0); + + if (!XGetWindowAttributes (dpy, parent, &wattr)) + rxvt_fatal ("invalid window-id specified with -embed, aborting.\n"); + + window_calc (wattr.width, wattr.height); + } +#endif + + window_calc (0, 0); + + /* sub-window placement & size in rxvt_term::resize_all_windows () */ + attributes.background_pixel = pix_colors_focused [Color_border]; + attributes.border_pixel = pix_colors_focused [Color_border]; + attributes.colormap = cmap; + + top = XCreateWindow (dpy, parent, + szHint.x, szHint.y, + szHint.width, szHint.height, + ext_bwidth, + depth, InputOutput, visual, + CWColormap | CWBackPixel | CWBorderPixel | CWOverrideRedirect, + &attributes); + + this->parent = top; + + set_title (rs [Rs_title]); + set_icon_name (rs [Rs_iconName]); + + classHint.res_name = (char *)rs[Rs_name]; + classHint.res_class = (char *)RESCLASS; + + wmHint.flags = InputHint | StateHint | WindowGroupHint; + wmHint.input = True; + wmHint.initial_state = option (Opt_iconic) ? IconicState + : option (Opt_dockapp) ? WithdrawnState + : NormalState; + wmHint.window_group = top; + + XmbSetWMProperties (dpy, top, NULL, NULL, (char **)argv, argc, + &szHint, &wmHint, &classHint); +#if ENABLE_EWMH + /* + * set up icon hint + * rs [Rs_iconfile] is path to icon + */ + + if (rs [Rs_iconfile]) + set_icon (rs [Rs_iconfile]); +#endif + +#if ENABLE_FRILLS + if (mwmhints.flags) + XChangeProperty (dpy, top, xa[XA_MOTIF_WM_HINTS], xa[XA_MOTIF_WM_HINTS], 32, + PropModeReplace, (unsigned char *)&mwmhints, PROP_MWM_HINTS_ELEMENTS); +#endif + + Atom protocols[] = { + xa[XA_WM_DELETE_WINDOW], +#if ENABLE_EWMH + xa[XA_NET_WM_PING], +#endif + }; + + XSetWMProtocols (dpy, top, protocols, ecb_array_length (protocols)); + +#if ENABLE_FRILLS + if (rs[Rs_transient_for]) + XSetTransientForHint (dpy, top, (Window)strtol (rs[Rs_transient_for], 0, 0)); +#endif + +#if ENABLE_EWMH + long pid = getpid (); + + XChangeProperty (dpy, top, + xa[XA_NET_WM_PID], XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&pid, 1); + + // _NET_WM_WINDOW_TYPE is NORMAL, which is the default +#endif + + XSelectInput (dpy, top, + KeyPressMask +#if (MOUSE_WHEEL && MOUSE_SLIP_WHEELING) || ENABLE_FRILLS || ISO_14755 + | KeyReleaseMask +#endif + | FocusChangeMask | VisibilityChangeMask + | ExposureMask | StructureNotifyMask); + + termwin_ev.start (display, top); + + /* vt cursor: Black-on-White is standard, but this is more popular */ + unsigned int shape = XC_xterm; + +#ifdef HAVE_XMU + if (rs[Rs_pointerShape]) + { + int stmp = XmuCursorNameToIndex (rs[Rs_pointerShape]); + if (stmp >= 0) + shape = stmp; + } +#endif + + TermWin_cursor = XCreateFontCursor (dpy, shape); + + /* the vt window */ + vt = XCreateSimpleWindow (dpy, top, + window_vt_x, window_vt_y, + vt_width, vt_height, + 0, + pix_colors_focused[Color_fg], + pix_colors_focused[Color_bg]); + + attributes.bit_gravity = NorthWestGravity; + XChangeWindowAttributes (dpy, vt, CWBitGravity, &attributes); + + vt_emask = ExposureMask | ButtonPressMask | ButtonReleaseMask | PropertyChangeMask; + + if (option (Opt_pointerBlank)) + vt_emask |= PointerMotionMask; + else + vt_emask |= Button1MotionMask | Button3MotionMask; + + vt_select_input (); + + vt_ev.start (display, vt); + + /* graphics context for the vt window */ + gcvalue.foreground = pix_colors[Color_fg]; + gcvalue.background = pix_colors[Color_bg]; + gcvalue.graphics_exposures = 0; + + gc = XCreateGC (dpy, vt, + GCForeground | GCBackground | GCGraphicsExposures, + &gcvalue); + + drawable = new rxvt_drawable (this, vt); + +#ifdef OFF_FOCUS_FADING + // initially we are in unfocused state + if (rs[Rs_fade]) + pix_colors = pix_colors_unfocused; +#endif + + pointer_unblank (); + scr_recolor (); +} + +/*----------------------------------------------------------------------*/ +/* + * Run the command in a subprocess and return a file descriptor for the + * master end of the pseudo-teletype pair with the command talking to + * the slave. + */ +void +rxvt_term::run_command (const char *const *argv) +{ +#if ENABLE_FRILLS + if (rs[Rs_pty_fd]) + { + pty->pty = atoi (rs[Rs_pty_fd]); + + if (pty->pty >= 0) + { + if (getfd_hook) + pty->pty = (*getfd_hook) (pty->pty); + + if (pty->pty < 0) + rxvt_fatal ("unusable pty-fd filehandle, aborting.\n"); + } + } + else +#endif + if (!pty->get ()) + rxvt_fatal ("can't initialize pseudo-tty, aborting.\n"); + + fcntl (pty->pty, F_SETFL, O_NONBLOCK); + + struct termios tio = def_tio; + +#ifndef NO_BACKSPACE_KEY + if (rs[Rs_backspace_key][0] && !rs[Rs_backspace_key][1]) + tio.c_cc[VERASE] = rs[Rs_backspace_key][0]; + else if (strcmp (rs[Rs_backspace_key], "DEC") == 0) + tio.c_cc[VERASE] = '\177'; /* the initial state anyway */ +#endif + + /* init terminal attributes */ + cfsetospeed (&tio, BAUDRATE); + cfsetispeed (&tio, BAUDRATE); + tcsetattr (pty->tty, TCSANOW, &tio); + pty->set_utf8_mode (enc_utf8); + + /* set initial window size */ + tt_winch (); + +#if ENABLE_FRILLS + if (rs[Rs_pty_fd]) + return; +#endif + + /* spin off the command interpreter */ + switch (cmd_pid = fork ()) + { + case -1: + { + cmd_pid = 0; + rxvt_fatal ("can't fork, aborting.\n"); + } + case 0: + init_env (); + + if (!pty->make_controlling_tty ()) + fprintf (stderr, "%s: could not obtain control of tty.", RESNAME); + else + { + /* Reopen stdin, stdout and stderr over the tty file descriptor */ + dup2 (pty->tty, STDIN_FILENO); + dup2 (pty->tty, STDOUT_FILENO); + dup2 (pty->tty, STDERR_FILENO); + + // close all our file handles that we do no longer need + for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++) + { + if ((*t)->pty->pty > 2) close ((*t)->pty->pty); + if ((*t)->pty->tty > 2) close ((*t)->pty->tty); + } + + run_child (argv); + fprintf (stderr, "%s: unable to exec child.", RESNAME); + } + + _exit (EXIT_FAILURE); + + default: + if (!option (Opt_utmpInhibit)) + { +#ifdef LOG_ONLY_ON_LOGIN + bool login_shell = option (Opt_loginShell); +#else + bool login_shell = true; +#endif + pty->login (cmd_pid, login_shell, rs[Rs_display_name]); + } + + pty->close_tty (); + + child_ev.start (cmd_pid); + + HOOK_INVOKE ((this, HOOK_CHILD_START, DT_INT, cmd_pid, DT_END)); + break; + } +} + +/* ------------------------------------------------------------------------- * + * CHILD PROCESS OPERATIONS * + * ------------------------------------------------------------------------- */ +/* + * The only open file descriptor is the slave tty - so no error messages. + * returns are fatal + */ +int +rxvt_term::run_child (const char *const *argv) +{ + char *login; + + if (option (Opt_console)) + { + /* be virtual console, fail silently */ +#ifdef TIOCCONS + unsigned int on = 1; + + ioctl (STDIN_FILENO, TIOCCONS, &on); +#elif defined (SRIOCSREDIR) + int fd; + + fd = open (CONSOLE, O_WRONLY, 0); + if (fd >= 0) + { + ioctl (fd, SRIOCSREDIR, STDIN_FILENO); + close (fd); + } +#endif /* SRIOCSREDIR */ + } + + /* reset signals and spin off the command interpreter */ + signal (SIGINT, SIG_DFL); + signal (SIGQUIT, SIG_DFL); + signal (SIGCHLD, SIG_DFL); + signal (SIGHUP, SIG_DFL); + signal (SIGPIPE, SIG_DFL); + /* + * mimic login's behavior by disabling the job control signals + * a shell that wants them can turn them back on + */ +#ifdef SIGTSTP + signal (SIGTSTP, SIG_IGN); + signal (SIGTTIN, SIG_IGN); + signal (SIGTTOU, SIG_IGN); +#endif /* SIGTSTP */ + + /* command interpreter path */ + if (argv) + { +# ifdef DEBUG_CMD + int i; + + for (i = 0; argv[i]; i++) + fprintf (stderr, "argv [%d] = \"%s\"\n", i, argv[i]); +# endif + + execvp (argv[0], (char *const *)argv); + /* no error message: STDERR is closed! */ + } + else + { + const char *argv0, *shell; + + if ((shell = getenv ("SHELL")) == NULL || *shell == '\0') + shell = "/bin/sh"; + + argv0 = rxvt_basename (shell); + + if (option (Opt_loginShell)) + { + login = (char *)rxvt_malloc (strlen (argv0) + 2); + + login[0] = '-'; + strcpy (&login[1], argv0); + argv0 = login; + } + + execlp (shell, argv0, (char *)0); + /* no error message: STDERR is closed! */ + } + + return -1; +} + +/*----------------------- end-of-file (C source) -----------------------*/ diff --git a/src/rxvt.h b/src/rxvt.h new file mode 100644 index 0000000..85029e6 --- /dev/null +++ b/src/rxvt.h @@ -0,0 +1,1481 @@ +#ifndef RXVT_H_ /* include once only */ +#define RXVT_H_ + +#include <stdio.h> +#include <ctype.h> +#include <errno.h> +#include <stdarg.h> +#include <stdlib.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <assert.h> +#ifdef HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif +#ifdef HAVE_SYS_STRREDIR_H +#include <sys/strredir.h> +#endif + +#if HAVE_WCHAR_H +# include <wchar.h> +#else +// stdlib.h might provide it +#endif + +// we assume that Xlib.h defines XPointer, and it does since at least 1994... + +extern "C" { +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xresource.h> +} + +#if UNICODE_3 +typedef uint32_t text_t; +#else +typedef uint16_t text_t; // saves lots of memory +#endif +typedef uint32_t rend_t; +typedef int32_t tlen_t; // was int16_t, but this results in smaller code and memory use +typedef int32_t tlen_t_; // specifically for use in the line_t structure + +#include "feature.h" + +#if defined (ISO_14755) || defined (ENABLE_PERL) +# define ENABLE_OVERLAY 1 +#endif + +#if ENABLE_PERL +# define ENABLE_FRILLS 1 +# define ENABLE_COMBINING 1 +#endif + +#if ENABLE_FRILLS +# define ENABLE_XEMBED 1 +# define ENABLE_EWMH 1 +# define ENABLE_XIM_ONTHESPOT 1 +# define CURSOR_BLINK 1 +# define OPTION_HC 1 +# define BUILTIN_GLYPHS 1 +#else +# define ENABLE_MINIMAL 1 +#endif + +#include <limits.h> + +#include <X11/cursorfont.h> +#include <X11/keysym.h> +#include <X11/keysymdef.h> +#include <X11/Xatom.h> + +#if HAVE_PIXBUF +# include <gdk-pixbuf/gdk-pixbuf.h> +#endif + +#if XRENDER && (HAVE_PIXBUF || ENABLE_TRANSPARENCY) +# define HAVE_IMG 1 +#endif + +#define ECB_NO_THREADS 1 +#include "ecb.h" + +#include "encoding.h" +#include "rxvtutil.h" +#include "rxvtfont.h" +#include "rxvttoolkit.h" +#include "rxvtimg.h" +#include "scrollbar.h" +#include "ev_cpp.h" +#include "libptytty.h" + +#include "rxvtperl.h" + +// try to avoid some macros to decrease code size, on some systems +#if ENABLE_MINIMAL +# define strcmp(a,b) (strcmp)(a,b) +# define strlen(a) (strlen)(a) +# define strcpy(a,b) (strcpy)(a,b) +# define memset(a,c,l) (memset)(a,c,l) +# define memcpy(a,b,l) (memcpy)(a,b,l) +#endif + +/* + ***************************************************************************** + * SYSTEM HACKS + ***************************************************************************** + */ + +#include <termios.h> + +#ifndef STDIN_FILENO +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 +#endif + +#ifndef EXIT_SUCCESS /* missing from <stdlib.h> */ +# define EXIT_SUCCESS 0 /* exit function success */ +# define EXIT_FAILURE 1 /* exit function failure */ +#endif + +/****************************************************************************/ + +// exception thrown on fatal (per-instance) errors +class rxvt_failure_exception { }; + +// exception thrown when the command parser runs out of input data +class out_of_input { }; + +/* + ***************************************************************************** + * PROTOTYPES + ***************************************************************************** + */ +// main.C +#define SET_LOCALE(locale) rxvt_set_locale (locale) +extern bool rxvt_set_locale (const char *locale) NOTHROW; +extern void rxvt_push_locale (const char *locale) NOTHROW; +extern void rxvt_pop_locale () NOTHROW; +void rxvt_init (); + +// misc.C +char * rxvt_wcstombs (const wchar_t *str, int len = -1); +wchar_t * rxvt_mbstowcs (const char *str, int len = -1); +char * rxvt_wcstoutf8 (const wchar_t *str, int len = -1); +wchar_t * rxvt_utf8towcs (const char *str, int len = -1); + +const char * rxvt_basename (const char *str) NOTHROW; +void rxvt_vlog (const char *fmt, va_list arg_ptr) NOTHROW; +void rxvt_log (const char *fmt,...) NOTHROW; +void rxvt_warn (const char *fmt,...) NOTHROW; +ecb_noreturn ecb_cold +void rxvt_fatal (const char *fmt, ...) THROW ((class rxvt_failure_exception)); +ecb_noreturn ecb_cold +void rxvt_exit_failure () THROW ((class rxvt_failure_exception)); + +void * rxvt_malloc (size_t size); +void * rxvt_calloc (size_t number, size_t size); +void * rxvt_realloc (void *ptr, size_t size); + +char * rxvt_strtrim (char *str) NOTHROW; +char ** rxvt_strsplit (char delim, const char *str) NOTHROW; + +static inline void +rxvt_free_strsplit (char **ptr) NOTHROW +{ + free (ptr[0]); + free (ptr); +} + +KeySym rxvt_XKeycodeToKeysym (Display *dpy, KeyCode keycode, int index); + +///////////////////////////////////////////////////////////////////////////// + +// temporarily replace the process environment +extern char **environ; +extern char **rxvt_environ; // the original environ pointer + +static inline void +set_environ (char **envv) +{ +#if ENABLE_PERL + assert (envv); +#else + if (envv) +#endif + environ = envv; +} + +struct localise_env +{ + char **orig_env; + + localise_env (char **new_env) + { + orig_env = environ; + environ = new_env; + } + + ~localise_env () + { + environ = orig_env; + } +}; + +/* + ***************************************************************************** + * STRUCTURES AND TYPEDEFS + ***************************************************************************** + */ + +/* + * the 'essential' information for reporting Mouse Events + * pared down from XButtonEvent + */ +struct mouse_event +{ + int clicks; + Time time; /* milliseconds */ + unsigned int state; /* key or button mask */ + unsigned int button; /* detail */ +}; + +#if ENABLE_XEMBED +// XEMBED messages +# define XEMBED_EMBEDDED_NOTIFY 0 +# define XEMBED_WINDOW_ACTIVATE 1 +# define XEMBED_WINDOW_DEACTIVATE 2 +# define XEMBED_REQUEST_FOCUS 3 +# define XEMBED_FOCUS_IN 4 +# define XEMBED_FOCUS_OUT 5 +# define XEMBED_FOCUS_NEXT 6 +# define XEMBED_FOCUS_PREV 7 + +# define XEMBED_MODALITY_ON 10 +# define XEMBED_MODALITY_OFF 11 +# define XEMBED_REGISTER_ACCELERATOR 12 +# define XEMBED_UNREGISTER_ACCELERATOR 13 +# define XEMBED_ACTIVATE_ACCELERATOR 14 + +// XEMBED detail code +# define XEMBED_FOCUS_CURRENT 0 +# define XEMBED_FOCUS_FIRST 1 +# define XEMBED_FOCUS_LAST 2 + +# define XEMBED_MAPPED (1 << 0) +#endif + +/* + ***************************************************************************** + * NORMAL DEFINES + ***************************************************************************** + */ + +/* COLORTERM, TERM environment variables */ +#define COLORTERMENV "rxvt" +#if HAVE_IMG +# define COLORTERMENVFULL COLORTERMENV "-xpm" +#else +# define COLORTERMENVFULL COLORTERMENV +#endif +#ifndef TERMENV +# if USE_256_COLORS +# define TERMENV "rxvt-unicode-256color" +# else +# define TERMENV "rxvt-unicode" +# endif +#endif + +// Hidden color cube for indexed 24-bit colors. There are fewer blue levels +// because normal human eye is less sensitive to the blue component than to +// the red or green. (https://en.m.wikipedia.org/wiki/Color_depth#8-bit_color) +#if USE_256_COLORS +// 7x7x5=245 < 254 unused color indices +# define Red_levels 7 +# define Green_levels 7 +# define Blue_levels 5 +#else +// 6x6x4=144 < 166 unused color indices +# define Red_levels 6 +# define Green_levels 6 +# define Blue_levels 4 +#endif + +#define RGB24_CUBE_SIZE (Red_levels * Green_levels * Blue_levels) + +#if defined (NO_MOUSE_REPORT) && !defined (NO_MOUSE_REPORT_SCROLLBAR) +# define NO_MOUSE_REPORT_SCROLLBAR 1 +#endif + +#define scrollBar_esc 30 + +#if !defined (RXVT_SCROLLBAR) && !defined (NEXT_SCROLLBAR) +# define NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING 1 +#endif + +enum { + NO_REFRESH = 0, /* Window not visible at all! */ + FAST_REFRESH = 1, /* Fully exposed window */ + SLOW_REFRESH = 2, /* Partially exposed window */ +}; + +#ifdef NO_SECONDARY_SCREEN +# define NSCREENS 0 +#else +# define NSCREENS 1 +#endif + +/* flags for rxvt_term::scr_gotorc () */ +enum { + C_RELATIVE = 1, /* col movement is relative */ + R_RELATIVE = 2, /* row movement is relative */ + RELATIVE = C_RELATIVE | R_RELATIVE, +}; + +/* modes for rxvt_term::scr_insdel_chars (), rxvt_term::scr_insdel_lines () */ +enum { + INSERT = -1, /* don't change these values */ + DELETE = +1, + ERASE = +2, +}; + +/* modes for rxvt_term::scr_page () - scroll page. used by scrollbar window */ +enum page_dirn { + DN = -1, + NO_DIR = 0, + UP = 1, +}; + +/* arguments for rxvt_term::scr_change_screen () */ +enum { + PRIMARY = 0, + SECONDARY, +}; + +// define various rendition bits and masks. the rendition word +// is 32 bits in size, and we should use it as efficiently as possible + +#define RS_None 0 + +// GET_BGATTR depends on RS_fgShift > RS_bgShift +#define RS_colorMask ((1UL << Color_Bits) - 1UL) +#define RS_bgShift 0 +#define RS_fgShift (RS_bgShift + Color_Bits) +#define RS_bgMask (RS_colorMask << RS_bgShift) +#define RS_fgMask (RS_colorMask << RS_fgShift) + +// must have space for rxvt_fontset::fontCount * 2 + 2 values +#define RS_fontShift (RS_fgShift + Color_Bits) +#define RS_Careful (1UL << RS_fontShift) /* be careful when drawing these */ +#define RS_fontCount rxvt_fontset::fontCount +#define RS_fontMask ((RS_fontCount << (RS_fontShift + 1)) | RS_Careful) // includes RS_Careful + +// toggle this to force redraw, must be != RS_Careful and otherwise "pretty neutral" +#define RS_redraw (2UL << RS_fontShift) + +#define RS_Sel (1UL << 22) + +// 4 custom bits for extensions +#define RS_customCount 16UL +#define RS_customShift 23 +#define RS_customMask ((RS_customCount - 1UL) << RS_customShift) + +// font styles +#define RS_Bold (1UL << RS_styleShift) +#define RS_Italic (2UL << RS_styleShift) + +#define RS_styleCount 4 +#define RS_styleShift 27 +#define RS_styleMask (RS_Bold | RS_Italic) + +// fake styles +#define RS_Blink (1UL << 29) +#define RS_RVid (1UL << 30) // reverse video +#define RS_Uline (1UL << 31) // underline + +#define RS_baseattrMask (RS_Italic | RS_Bold | RS_Blink | RS_RVid | RS_Uline) +#define RS_attrMask (RS_baseattrMask | RS_fontMask) + +#define DEFAULT_RSTYLE (RS_None | (Color_fg << RS_fgShift) | (Color_bg << RS_bgShift)) +#define OVERLAY_RSTYLE (RS_None | (Color_Black << RS_fgShift) | (Color_Yellow << RS_bgShift)) + +enum { + C0_NUL = 0x00, + C0_SOH, C0_STX, C0_ETX, C0_EOT, C0_ENQ, C0_ACK, C0_BEL, + C0_BS , C0_HT , C0_LF , C0_VT , C0_FF , C0_CR , C0_SO , C0_SI , + C0_DLE, C0_DC1, C0_DC2, D0_DC3, C0_DC4, C0_NAK, C0_SYN, C0_ETB, + C0_CAN, C0_EM , C0_SUB, C0_ESC, C0_IS4, C0_IS3, C0_IS2, C0_IS1, +}; +#define CHAR_ST 0x9c /* 0234 */ + +/* + * XTerm Operating System Commands: ESC ] Ps;Pt (ST|BEL) + * colour extensions by Christian W. Zuckschwerdt <zany@triq.net> + */ +enum { + XTerm_name = 0, + XTerm_iconName = 1, + XTerm_title = 2, + XTerm_property = 3, // change X property + XTerm_Color = 4, // change colors + XTerm_Color00 = 10, // change fg color + XTerm_Color01 = 11, // change bg color + XTerm_Color_cursor = 12, // change actual 'Cursor' color + XTerm_Color_pointer_fg = 13, // change actual 'Pointer' fg color + XTerm_Color_pointer_bg = 14, // change actual 'Pointer' bg color + XTerm_Color05 = 15, // not implemented (tektronix fg) + XTerm_Color06 = 16, // not implemented (tektronix bg) + XTerm_Color_HC = 17, // change actual 'Highlight' bg color + XTerm_Color_HTC = 19, // change actual 'Highlight' fg color + XTerm_logfile = 46, // not implemented + XTerm_font = 50, + + XTerm_konsole30 = 30, // reserved for konsole + XTerm_konsole31 = 31, // reserved for konsole + XTerm_emacs51 = 51, // reserved for emacs shell + /* + * rxvt extensions of XTerm OSCs: ESC ] Ps;Pt (ST|BEL) + */ + + // deprecated + Rxvt_restoreFG = 39, + Rxvt_restoreBG = 49, + + Rxvt_dumpscreen = 55, // dump scrollback and all of screen + + URxvt_locale = 701, // change locale + URxvt_version = 702, // request version + + URxvt_Color_IT = 704, // change actual 'Italic' colour + URxvt_Color_BD = 706, // change actual 'Bold' color + URxvt_Color_UL = 707, // change actual 'Underline' color + URxvt_Color_border = 708, + + URxvt_font = 710, + URxvt_boldFont = 711, + URxvt_italicFont = 712, + URxvt_boldItalicFont = 713, + + URxvt_view_up = 720, + URxvt_view_down = 721, + + URxvt_perl = 777, // for use by perl extensions, starts with "extension-name;" +}; + +/* Words starting with `Color_' are colours. Others are counts */ +/* + * The PixColor and rendition colour usage should probably be decoupled + * on the unnecessary items, e.g. Color_pointer, but won't bother + * until we need to. Also, be aware of usage in pixcolor_set + */ + +enum colour_list { + Color_none = -2, + Color_transparent = -1, + Color_fg = 0, + Color_bg, + minCOLOR, /* 2 */ + Color_Black = minCOLOR, + Color_Red3, + Color_Green3, + Color_Yellow3, + Color_Blue3, + Color_Magenta3, + Color_Cyan3, + maxCOLOR, /* minCOLOR + 7 */ +#ifndef NO_BRIGHTCOLOR + Color_AntiqueWhite = maxCOLOR, + minBrightCOLOR, /* maxCOLOR + 1 */ + Color_Grey25 = minBrightCOLOR, + Color_Red, + Color_Green, + Color_Yellow, + Color_Blue, + Color_Magenta, + Color_Cyan, + maxBrightCOLOR, /* minBrightCOLOR + 7 */ + Color_White = maxBrightCOLOR, +#else + Color_White = maxCOLOR, +#endif + minTermCOLOR = Color_White + 1, +#if USE_256_COLORS + maxTermCOLOR = Color_White + 240, +#else + maxTermCOLOR = Color_White + 72, +#endif + minTermCOLOR24, + maxTermCOLOR24 = minTermCOLOR24 + + RGB24_CUBE_SIZE - 1, +#ifndef NO_CURSORCOLOR + Color_cursor, + Color_cursor2, +#endif + Color_pointer_fg, + Color_pointer_bg, + Color_border, +#ifndef NO_BOLD_UNDERLINE_REVERSE + Color_BD, + Color_IT, + Color_UL, + Color_RV, +#endif +#if ENABLE_FRILLS + Color_underline, +#endif +#ifdef OPTION_HC + Color_HC, + Color_HTC, +#endif + Color_scroll, +#ifdef RXVT_SCROLLBAR + Color_trough, +#endif +#if OFF_FOCUS_FADING + Color_fade, +#endif + NRS_COLORS, /* */ +#ifdef RXVT_SCROLLBAR + Color_topShadow = NRS_COLORS, + Color_bottomShadow, + TOTAL_COLORS +#else + TOTAL_COLORS = NRS_COLORS +#endif +}; + +#if USE_256_COLORS +# define Color_Bits 9 // 0 .. maxTermCOLOR24 +#else +# define Color_Bits 8 // 0 .. maxTermCOLOR24 +#endif + +#if maxTermCOLOR24 >= (1 << Color_Bits) +# error color index overflow +#endif + +/* + * Resource list + */ +enum { +# define def(name) Rs_ ## name, +# define reserve(name,count) Rs_ ## name ## _ = Rs_ ## name + (count) - 1, +# include "rsinc.h" +# undef def +# undef reserve + NUM_RESOURCES +}; + +/* DEC private modes */ +#define PrivMode_132 (1UL<<0) +#define PrivMode_132OK (1UL<<1) +#define PrivMode_rVideo (1UL<<2) +#define PrivMode_relOrigin (1UL<<3) +#define PrivMode_Screen (1UL<<4) +#define PrivMode_Autowrap (1UL<<5) +#define PrivMode_aplCUR (1UL<<6) +#define PrivMode_aplKP (1UL<<7) +#define PrivMode_HaveBackSpace (1UL<<8) +#define PrivMode_BackSpace (1UL<<9) +#define PrivMode_ShiftKeys (1UL<<10) +#define PrivMode_VisibleCursor (1UL<<11) +#define PrivMode_MouseX10 (1UL<<12) +#define PrivMode_MouseX11 (1UL<<13) +#define PrivMode_scrollBar (1UL<<14) +#define PrivMode_TtyOutputInh (1UL<<15) +#define PrivMode_Keypress (1UL<<16) +#define PrivMode_smoothScroll (1UL<<17) +#define PrivMode_vt52 (1UL<<18) +#define PrivMode_LFNL (1UL<<19) +#define PrivMode_MouseBtnEvent (1UL<<20) +#define PrivMode_MouseAnyEvent (1UL<<21) +#define PrivMode_BracketPaste (1UL<<22) +#define PrivMode_ExtModeMouse (1UL<<23) // xterm pseudo-utf-8 hack +#define PrivMode_ExtMouseRight (1UL<<24) // xterm pseudo-utf-8, but works in non-utf-8-locales +#define PrivMode_BlinkingCursor (1UL<<25) +#define PrivMode_FocusEvent (1UL<<26) + +#define PrivMode_mouse_report (PrivMode_MouseX10|PrivMode_MouseX11|PrivMode_MouseBtnEvent|PrivMode_MouseAnyEvent) + +#ifdef ALLOW_132_MODE +# define PrivMode_Default (PrivMode_Autowrap|PrivMode_ShiftKeys|PrivMode_VisibleCursor|PrivMode_132OK) +#else +# define PrivMode_Default (PrivMode_Autowrap|PrivMode_ShiftKeys|PrivMode_VisibleCursor) +#endif + +// do not change these constants lightly, there are many interdependencies +#define IMBUFSIZ 128 // input modifier buffer sizes +#define KBUFSZ 512 // size of keyboard mapping buffer +#define CBUFSIZ 32768 // size of command buffer (longest command sequence possible) +#define CBUFCNT 8 // never call pty_fill/cmd_parse more than this often in a row +#define UBUFSIZ 2048 // character buffer + +#if ENABLE_FRILLS +# include <X11/Xmd.h> +typedef struct _mwmhints +{ + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 input_mode; + CARD32 status; +} MWMHints; +#endif + +/* Motif window hints */ +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) +/* bit definitions for MwmHints.functions */ +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) +/* bit definitions for MwmHints.decorations */ +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) +/* bit definitions for MwmHints.inputMode */ +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define PROP_MWM_HINTS_ELEMENTS 5 + +/* + ***************************************************************************** + * MACRO DEFINES + ***************************************************************************** + */ + +// speed hack, copy some member variable into a local variable of the same name +#define dLocal(type,name) type const name = this->name + +// for speed reasons, we assume that all codepoints 32 to 126 are +// single-width. +#define WCWIDTH(c) (IN_RANGE_INC (c, 0x20, 0x7e) ? 1 : wcwidth (c)) + +/* convert pixel dimensions to row/column values. Everything as int32_t */ +#define Pixel2Col(x) Pixel2Width((int32_t)(x)) +#define Pixel2Row(y) Pixel2Height((int32_t)(y)) +#define Pixel2Width(x) ((int32_t)(x) / (int32_t)fwidth) +#define Pixel2Height(y) ((int32_t)(y) / (int32_t)fheight) +#define Col2Pixel(col) ((int32_t)Width2Pixel(col)) +#define Row2Pixel(row) ((int32_t)Height2Pixel(row)) +#define Width2Pixel(n) ((int32_t)(n) * (int32_t)fwidth) +#define Height2Pixel(n) ((int32_t)(n) * (int32_t)fheight) + +#define LINENO_of(t,n) MOD ((t)->term_start + int(n), (t)->total_rows) +#define ROW_of(t,n) (t)->row_buf [LINENO_of ((t), n)] + +#define LINENO(n) LINENO_of (this, n) +#define ROW(n) ROW_of (this, n) + +/* how to build & extract colors and attributes */ +#define GET_BASEFG(x) (((x) & RS_fgMask) >> RS_fgShift) +#define GET_BASEBG(x) (((x) & RS_bgMask) >> RS_bgShift) + +#define GET_FONT(x) (((x) & RS_fontMask) >> RS_fontShift) +#define SET_FONT(x,fid) (((x) & ~RS_fontMask) | ((fid) << RS_fontShift)) + +#define GET_STYLE(x) (((x) & RS_styleMask) >> RS_styleShift) +#define SET_STYLE(x,style) (((x) & ~RS_styleMask) | ((style) << RS_styleShift)) + +#define GET_ATTR(x) (((x) & RS_attrMask)) +#define SET_FGCOLOR(x,fg) (((x) & ~RS_fgMask) | ((fg) << RS_fgShift)) +#define SET_BGCOLOR(x,bg) (((x) & ~RS_bgMask) | ((bg) << RS_bgShift)) +#define SET_ATTR(x,a) (((x) & ~RS_attrMask) | (a)) + +#define RS_SAME(a,b) (!(((a) ^ (b)) & ~RS_Careful)) + +#define PIXCOLOR_NAME(idx) rs[Rs_color + (idx)] +#define ISSET_PIXCOLOR(idx) (!!rs[Rs_color + (idx)]) + +#if ENABLE_STYLES +# define FONTSET_of(t,style) (t)->fontset[GET_STYLE (style)] +#else +# define FONTSET_of(t,style) (t)->fontset[0] +#endif + +#define FONTSET(style) FONTSET_of (this, style) + +typedef callback<void (const char *)> log_callback; +typedef callback<int (int)> getfd_callback; + +/****************************************************************************/ + +#define LINE_LONGER 0x0001 // line is continued on the next row +#define LINE_FILTERED 0x0002 // line has been filtered +#define LINE_COMPRESSED 0x0004 // line has been compressed (NYI) +#define LINE_FILTER 0x0008 // line needs to be filtered before display (NYI) +#define LINE_BIDI 0x0010 // line needs bidi (NYI) + +struct line_t +{ + text_t *t; // terminal the text + rend_t *r; // rendition, uses RS_ flags + tlen_t_ l; // length of each text line + uint32_t f; // flags + + bool valid () + { + return l >= 0; + } + + void alloc () + { + l = 0; + } + + bool is_longer () + { + return f & LINE_LONGER; + } + + void is_longer (int set) + { + if (set) + f |= LINE_LONGER; + else + f &= ~LINE_LONGER; + } + + void clear () + { + t = 0; + r = 0; + l = 0; + f = 0; + } + + void touch () // call whenever a line is changed/touched/updated + { +#if ENABLE_PERL + f &= ~LINE_FILTERED; +#endif + } + + void touch (int col) + { + max_it (l, col); + touch (); + } +}; + +/****************************************************************************/ + +// primitive wrapper around mbstate_t to ensure initialisation +struct mbstate +{ + mbstate_t mbs; + + operator mbstate_t *() { return &mbs; } + void reset () { memset (&mbs, 0, sizeof (mbs)); } + mbstate () { reset (); } +}; + +/****************************************************************************/ + +#define UNICODE_MASK 0x1fffffUL + +#if UNICODE_3 +# define COMPOSE_LO 0x40000000UL +# define COMPOSE_HI 0x400fffffUL +# define IS_COMPOSE(n) ((int32_t)(n) >= COMPOSE_LO) +#else +# if ENABLE_PERL +# define COMPOSE_LO 0xe000UL // our _own_ functions don't like (illegal) surrogates +# define COMPOSE_HI 0xf8ffUL // in utf-8, so use private use area only +# else +# define COMPOSE_LO 0xd800UL +# define COMPOSE_HI 0xf8ffUL +# endif +# define IS_COMPOSE(n) IN_RANGE_INC ((n), COMPOSE_LO, COMPOSE_HI) +#endif + +#if ENABLE_COMBINING +// compose chars are used to represent composite characters +// that are not representable in unicode, as well as characters +// not fitting in the BMP. +struct compose_char +{ + unicode_t c1, c2; // any chars != NOCHAR are valid + + compose_char (unicode_t c1, unicode_t c2) + : c1(c1), c2(c2) + { } +}; + +class rxvt_composite_vec +{ + vector<compose_char> v; +public: + text_t compose (unicode_t c1, unicode_t c2 = NOCHAR); + int expand (unicode_t c, wchar_t *r); + compose_char *operator [](text_t c) + { + return c >= COMPOSE_LO && c < COMPOSE_LO + v.size () + ? &v[c - COMPOSE_LO] + : 0; + } +}; + +extern class rxvt_composite_vec rxvt_composite; +#endif + +/****************************************************************************/ + +#ifdef KEYSYM_RESOURCE +class keyboard_manager; +#endif + +typedef struct rxvt_term *rxvt_t; + +extern rxvt_t rxvt_current_term; + +#define SET_R(r) rxvt_current_term = const_cast<rxvt_term *>(r) +#define GET_R rxvt_current_term + +/* ------------------------------------------------------------------------- */ +struct overlay_base +{ + int x, y, w, h; // overlay dimensions + text_t **text; + rend_t **rend; + + // while tempting to add swap() etc. here, it effectively only increases code size +}; + +/* ------------------------------------------------------------------------- */ + +typedef struct +{ + int row; + int col; +} row_col_t; + +/* + * terminal limits: + * + * width : 1 <= width + * height : 1 <= height + * ncol : 1 <= ncol <= MAX(tlen_t) + * nrow : 1 <= nrow <= MAX(int) + * saveLines : 0 <= saveLines <= MAX(int) + * term_start : 0 <= term_start < saveLines + * total_rows : nrow + saveLines + * + * top_row : -saveLines <= top_row <= 0 + * view_start : top_row <= view_start <= 0 + * + * | most coordinates are stored relative to term_start, + * ROW_BUF | which is the first line of the terminal screen + * |························= row_buf[0] + * |························= row_buf[1] + * |························= row_buf[2] etc. + * | + * +------------+···········= term_start + top_row + * | scrollback | + * | scrollback +---------+·= term_start + view_start + * | scrollback | display | + * | scrollback | display | + * +------------+·display·+·= term_start + * | terminal | display | + * | terminal +---------+ + * | terminal | + * | terminal | + * +------------+···········= term_start + nrow - 1 + * | + * | + * END······················= total_rows + */ + +struct TermWin_t +{ + int vt_width; /* actual window width [pixels] */ + int vt_height; /* actual window height [pixels] */ + int width; /* window width [pixels] */ + int height; /* window height [pixels] */ + int fwidth; /* font width [pixels] */ + int fheight; /* font height [pixels] */ + int fbase; /* font ascent (baseline) [pixels] */ + int ncol; /* window columns [characters] */ + int nrow; /* window rows [characters] */ + int focus; /* window has focus */ + int mapped; /* window state mapped? */ + int int_bwidth; /* internal border width */ + int ext_bwidth; /* external border width */ + int lineSpace; /* number of extra pixels between rows */ + int letterSpace; /* number of extra pixels between columns */ + int saveLines; /* number of lines that fit in scrollback */ + int total_rows; /* total number of rows in this terminal */ + int term_start; /* term lines start here */ + int view_start; /* scrollback view starts here */ + int top_row; /* topmost row index of scrollback */ + Window parent; /* parent identifier */ + Window vt; /* vt100 window */ + GC gc; /* GC for drawing */ + rxvt_drawable *drawable; + rxvt_fontset *fontset[4]; +}; + +/* + * screen accounting: + * screen_t elements + * row: Cursor row position : 0 <= row < nrow + * col: Cursor column position : 0 <= col < ncol + * tscroll: Scrolling region top row inclusive : 0 <= row < nrow + * bscroll: Scrolling region bottom row inclusive : 0 <= row < nrow + * + * selection_t elements + * clicks: 1, 2 or 3 clicks - 4 indicates a special condition of 1 where + * nothing is selected + * beg: row/column of beginning of selection : never past mark + * mark: row/column of initial click : never past end + * end: row/column of one character past end of selection + * * Note: top_row <= beg.row <= mark.row <= end.row < nrow + * * Note: col == -1 ==> we're left of screen + * + */ +struct screen_t +{ + row_col_t cur; /* cursor position on the screen */ + int tscroll; /* top of settable scroll region */ + int bscroll; /* bottom of settable scroll region */ + unsigned int charset; /* character set number [0..3] */ + unsigned int flags; /* see below */ + row_col_t s_cur; /* saved cursor position */ + unsigned int s_charset; /* saved character set number [0..3] */ + char s_charset_char; + rend_t s_rstyle; /* saved rendition style */ +}; + +enum selection_op_t +{ + SELECTION_CLEAR = 0, /* nothing selected */ + SELECTION_INIT, /* marked a point */ + SELECTION_BEGIN, /* started a selection */ + SELECTION_CONT, /* continued selection */ + SELECTION_DONE /* selection put in CUT_BUFFER0 */ +}; + +struct selection_t +{ + wchar_t *text; /* selected text */ + unsigned int len; /* length of selected text */ + unsigned int screen; /* screen being used */ + unsigned int clicks; /* number of clicks */ + selection_op_t op; /* current operation */ + bool rect; /* rectangular selection? */ + row_col_t beg; /* beginning of selection <= mark */ + row_col_t mark; /* point of initial click <= end */ + row_col_t end; /* one character past end point */ + wchar_t *clip_text; /* text copied to the clipboard */ + unsigned int clip_len; /* length of clipboard text */ +}; + +/* ------------------------------------------------------------------------- */ + +/* screen_t flags */ +#define Screen_Relative (1<<0) /* relative origin mode flag */ +#define Screen_VisibleCursor (1<<1) /* cursor visible? */ +#define Screen_Autowrap (1<<2) /* auto-wrap flag */ +#define Screen_Insert (1<<3) /* insert mode (vs. overstrike) */ +#define Screen_WrapNext (1<<4) /* need to wrap for next char? */ +#define Screen_DefaultFlags (Screen_VisibleCursor | Screen_Autowrap) + +/* rxvt_vars.options */ +enum { +# define def(name) Opt_ ## name, +# define nodef(name) Opt_prev_ ## name, Opt_ ## name = 0, Opt_next_ ## name = Opt_prev_ ## name - 1, + Opt_0, +# include "optinc.h" +# undef nodef +# undef def + Opt_count +}; + +/* ------------------------------------------------------------------------- */ + +struct rxvt_vars : TermWin_t +{ + scrollBar_t scrollBar; + uint8_t options[(Opt_count + 7) >> 3]; + XSizeHints szHint; + rxvt_color *pix_colors; + Cursor TermWin_cursor; /* cursor for vt window */ + + line_t *row_buf; // all lines, scrollback + terminal, circular + line_t *drawn_buf; // text on screen + line_t *swap_buf; // lines for swap buffer + char *tabs; /* per location: 1 == tab-stop */ + screen_t screen; + screen_t swap; + selection_t selection; + rxvt_color pix_colors_focused[TOTAL_COLORS]; +#ifdef OFF_FOCUS_FADING + rxvt_color pix_colors_unfocused[TOTAL_COLORS]; +#endif +}; + +struct rxvt_term : zero_initialized, rxvt_vars, rxvt_screen +{ + + // special markers with magic addresses + static const char resval_undef []; // options specifically unset + static const char resval_on []; // boolean options switched on + static const char resval_off []; // or off + + log_callback *log_hook; // log error messages through this hook, if != 0 + getfd_callback *getfd_hook; // convert remote to local fd, if != 0 +#if ENABLE_PERL + rxvt_perl_term perl; +#endif + struct mbstate mbstate; // current input multibyte state + + unsigned char want_refresh:1, + current_screen:1, /* primary or secondary */ + num_scr_allow:1, + bypass_keystate:1, +#if ENABLE_FRILLS + urgency_hint:1, +#endif +#if CURSOR_BLINK + hidden_cursor:1, +#endif +#if TEXT_BLINK + hidden_text:1, +#endif +#if POINTER_BLANK + hidden_pointer:1, +#endif + enc_utf8:1, /* whether locale uses utf-8 */ + seen_input:1, /* whether we have seen some program output yet */ + seen_resize:1, /* whether we had a resize event */ + init_done:1, + parsed_geometry:1; + + unsigned char refresh_type, +#ifdef META8_OPTION + meta_char; /* Alt-key prefix */ +#endif +/* ---------- */ + bool rvideo_state, rvideo_mode; +#ifndef NO_BELL + bool rvideo_bell; +#endif + int num_scr; /* screen: number of lines scrolled */ + int prev_ncol, /* screen: previous number of columns */ + prev_nrow; /* screen: previous number of rows */ +/* ---------- */ + rend_t rstyle; +/* ---------- */ +#ifdef SELECTION_SCROLLING + int scroll_selection_lines; + int selection_save_x, + selection_save_y, + selection_save_state; +#endif +/* ---------- */ + int csrO, /* Hops - csr offset in thumb/slider to */ + /* give proper Scroll behaviour */ +#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING) + mouse_slip_wheel_speed, +#endif + refresh_count, + window_vt_x, + window_vt_y, + mouse_row, + mouse_col, +# ifdef POINTER_BLANK + pointerBlankDelay, +# endif + multiClickTime, + cursor_type, + allowedxerror; +/* ---------- */ + unsigned int ModLevel3Mask, + ModMetaMask, + ModNumLockMask; + unsigned long priv_modes, + SavedModes; +/* ---------- */ + Atom *xa; +/* ---------- */ + Time selection_time, + clipboard_time; + rxvt_selection *selection_req; + pid_t cmd_pid; /* process id of child */ +/* ---------- */ + struct mouse_event MEvent; + XComposeStatus compose; + static struct termios def_tio; + row_col_t oldcursor; + +#ifdef HAVE_IMG + enum { + BG_IS_TRANSPARENT = 1 << 1, + BG_NEEDS_REFRESH = 1 << 2, + }; + + uint8_t bg_flags; + + rxvt_img *bg_img; +#endif + +#if ENABLE_OVERLAY + overlay_base ov; + + void scr_swap_overlay () NOTHROW; + void scr_overlay_new (int x, int y, int w, int h) NOTHROW; + void scr_overlay_off () NOTHROW; + void scr_overlay_set (int x, int y, + text_t text, + rend_t rend = OVERLAY_RSTYLE) NOTHROW; + void scr_overlay_set (int x, int y, const char *s) NOTHROW; + void scr_overlay_set (int x, int y, const wchar_t *s) NOTHROW; +#endif + + vector<void *> allocated; // free these memory blocks with free() + + int parent_x, parent_y; // parent window position relative to root, only updated on demand + + char *locale; + char charsets[4]; + char *v_buffer; /* pointer to physical buffer */ + unsigned int v_buflen; /* size of area to write */ + stringvec *argv, *envv; /* if != 0, will be freed at destroy time */ + char **env; + +#ifdef KEYSYM_RESOURCE + keyboard_manager *keyboard; +#endif +#ifndef NO_RESOURCES + XrmDatabase option_db; +#endif + + const char *rs[NUM_RESOURCES]; + /* command input buffering */ + char *cmdbuf_ptr, *cmdbuf_endp; + char cmdbuf_base[CBUFSIZ]; + + ptytty *pty; + + // chunk contains all line_t's as well as rend_t and text_t buffers + // for drawn_buf, swap_buf and row_buf, in this order + void *chunk; + size_t chunk_size; + + uint32_t rgb24_color[RGB24_CUBE_SIZE]; // the 24-bit color value + uint16_t rgb24_seqno[RGB24_CUBE_SIZE]; // which one is older? + uint16_t rgb24_sequence; + + static vector<rxvt_term *> termlist; // a vector of all running rxvt_term's + +#if ENABLE_FRILLS || ISO_14755 + // ISO 14755 entry support + unicode_t iso14755buf; + void commit_iso14755 (); +# if ISO_14755 + void iso14755_51 (unicode_t ch, rend_t r = DEFAULT_RSTYLE, int x = 0, int y = -1, int y2 = -1); + void iso14755_54 (int x, int y); +# endif +#endif + + long vt_emask, vt_emask_perl, vt_emask_xim, vt_emask_mouse; + + void vt_select_input () const NOTHROW + { + XSelectInput (dpy, vt, vt_emask | vt_emask_perl | vt_emask_xim | vt_emask_mouse); + } + +#if ENABLE_PERL + void rootwin_cb (XEvent &xev); + xevent_watcher rootwin_ev; +#endif + + void x_cb (XEvent &xev); + xevent_watcher termwin_ev; + xevent_watcher vt_ev; + xevent_watcher scrollbar_ev; + + void child_cb (ev::child &w, int revents); ev::child child_ev; + void destroy_cb (ev::idle &w, int revents); ev::idle destroy_ev; + void refresh_check (); + void flush (); + void flush_cb (ev::timer &w, int revents); ev::timer flush_ev; + void cmdbuf_reify (); + void cmdbuf_append (const char *str, size_t count); + bool pty_fill (); + void pty_cb (ev::io &w, int revents); ev::io pty_ev; + +#ifdef CURSOR_BLINK + void cursor_blink_reset (); + void cursor_blink_cb (ev::timer &w, int revents); ev::timer cursor_blink_ev; +#endif +#ifdef TEXT_BLINK + void text_blink_cb (ev::timer &w, int revents); ev::timer text_blink_ev; +#endif +#ifndef NO_BELL + void bell_cb (ev::timer &w, int revents); ev::timer bell_ev; +#endif + +#ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING + void cont_scroll_cb (ev::timer &w, int revents); ev::timer cont_scroll_ev; +#endif +#ifdef SELECTION_SCROLLING + void sel_scroll_cb (ev::timer &w, int revents); ev::timer sel_scroll_ev; +#endif +#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING) + void slip_wheel_cb (ev::timer &w, int revents); ev::timer slip_wheel_ev; +#endif + +#ifdef POINTER_BLANK + void pointer_cb (ev::timer &w, int revents); ev::timer pointer_ev; + void pointer_blank (); +#endif + void pointer_unblank (); + + void tt_printf (const char *fmt,...); + void tt_write_ (const char *data, unsigned int len); + void tt_write (const char *data, unsigned int len); + void tt_write_user_input (const char *data, unsigned int len); + void pty_write (); + + void make_current () const // make this the "currently active" urxvt instance + { + SET_R (this); + set_environ (env); + rxvt_set_locale (locale); + } + +#if USE_XIM + rxvt_xim *input_method; + XIC Input_Context; + XIMStyle input_style; + XPoint spot; // most recently sent spot position + + void im_destroy (); + void im_cb (); im_watcher im_ev; + void im_set_size (XRectangle &size); + void im_set_position (XPoint &pos) NOTHROW; + void im_set_color (unsigned long &fg, unsigned long &bg); + void im_set_preedit_area (XRectangle &preedit_rect, XRectangle &status_rect, const XRectangle &needed_rect); + + bool im_is_running (); + void im_send_spot (); + bool im_get_ic (const char *modifiers); + void im_set_position (); +#endif + + // command.C + void key_press (XKeyEvent &ev); + void key_release (XKeyEvent &ev); + + wchar_t next_char () NOTHROW; + wchar_t cmd_getc () THROW ((class out_of_input)); + uint32_t next_octet () NOTHROW; + uint32_t cmd_get8 () THROW ((class out_of_input)); + + void cmd_parse (); + void mouse_report (XButtonEvent &ev); + void button_press (XButtonEvent &ev); + void button_release (XButtonEvent &ev); + void focus_in (); + void focus_out (); +#if ENABLE_FRILLS + void set_urgency (bool enable); +#else + void set_urgency (bool enable) { } +#endif + void update_fade_color (unsigned int idx, bool first_time = false); +#ifdef PRINTPIPE + FILE *popen_printer (); + int pclose_printer (FILE *stream); +#endif + void process_print_pipe (); + void process_nonprinting (unicode_t ch); + void process_escape_vt52 (unicode_t ch); + void process_escape_seq (); + void process_csi_seq (); + void process_window_ops (const int *args, unsigned int nargs); + char *get_to_st (unicode_t &ends_how); + void process_dcs_seq (); + void process_osc_seq (); + void process_color_seq (int report, int color, const char *str, char resp); + void process_xterm_seq (int op, char *str, char resp); + unsigned int map_rgb24_color (unsigned int r, unsigned int g, unsigned int b, unsigned int a); + int privcases (int mode, unsigned long bit); + void process_terminal_mode (int mode, int priv, unsigned int nargs, const int *arg); + void process_sgr_mode (unsigned int nargs, const int *arg); + void set_cursor_style (int style); + // init.C + void init (stringvec *argv, stringvec *envv); + void init (int argc, const char *const *argv, const char *const *envv); + void init2 (int argc, const char *const *argv); + void init_vars (); + const char **init_resources (int argc, const char *const *argv); + void init_env (); + void set_locale (const char *locale); + void init_xlocale (); + void init_command (const char *const *argv); + void run_command (const char *const *argv); + int run_child (const char *const *argv); + void color_aliases (int idx); + void create_windows (int argc, const char *const *argv); + void get_colors (); + void get_ourmods (); + void set_icon (const char *file); + // main.C + void tt_winch (); + rxvt_term (); + ~rxvt_term (); + void destroy (); + void emergency_cleanup (); + void recolor_cursor (); + void resize_all_windows (unsigned int newwidth, unsigned int newheight, int ignoreparent); + void window_calc (unsigned int newwidth, unsigned int newheight); + bool set_fonts (); + void set_string_property (Atom prop, const char *str, int len = -1); + void set_mbstring_property (Atom prop, const char *str, int len = -1); + void set_utf8_property (Atom prop, const char *str, int len = -1); + void set_title (const char *str); + void set_icon_name (const char *str); + void set_window_color (int idx, const char *color); + char *get_colorfgbg (); + bool set_color (rxvt_color &color, const char *name); + void alias_color (int dst, int src); + void set_widthheight (unsigned int newwidth, unsigned int newheight); + void get_window_origin (int &x, int &y); + + // screen.C + + bool option (uint8_t opt) const NOTHROW + { + return options[opt >> 3] & (1 << (opt & 7)); + } + + void set_option (uint8_t opt, bool set = true) NOTHROW; + + int fgcolor_of (rend_t r) const NOTHROW + { + int base = GET_BASEFG (r); +#ifndef NO_BRIGHTCOLOR + if (r & RS_Bold +# if ENABLE_STYLES + && option (Opt_intensityStyles) +# endif + && IN_RANGE_EXC (base, minCOLOR, minBrightCOLOR)) + base += minBrightCOLOR - minCOLOR; +#endif + return base; + } + + int bgcolor_of (rend_t r) const NOTHROW + { + int base = GET_BASEBG (r); +#ifndef NO_BRIGHTCOLOR + if (r & RS_Blink +# if ENABLE_STYLES + && option (Opt_intensityStyles) +# endif + && IN_RANGE_EXC (base, minCOLOR, minBrightCOLOR)) + base += minBrightCOLOR - minCOLOR; +#endif + return base; + } + + // modifies first argument(!) + void tt_paste (char *data, unsigned int len) NOTHROW; + void paste (char *data, unsigned int len) NOTHROW; + void scr_alloc () NOTHROW; + void scr_blank_line (line_t &l, unsigned int col, unsigned int width, rend_t efs) const NOTHROW; + void scr_blank_screen_mem (line_t &l, rend_t efs) const NOTHROW; + void scr_kill_char (line_t &l, int col) const NOTHROW; + void scr_set_char_rend (line_t &l, int col, rend_t rend); + int scr_scroll_text (int row1, int row2, int count) NOTHROW; + void copy_line (line_t &dst, line_t &src); + void scr_reset (); + void scr_release () NOTHROW; + void scr_clear (bool really = false) NOTHROW; + void scr_refresh () NOTHROW; + bool scr_refresh_rend (rend_t mask, rend_t value) NOTHROW; + void scr_erase_screen (int mode) NOTHROW; +#if ENABLE_FRILLS + void scr_erase_savelines () NOTHROW; + void scr_backindex () NOTHROW; + void scr_forwardindex () NOTHROW; +#endif + void scr_touch (bool refresh) NOTHROW; + void scr_expose (int x, int y, int width, int height, bool refresh) NOTHROW; + void scr_recolor (bool refresh = true) NOTHROW; + void scr_remap_chars () NOTHROW; + void scr_remap_chars (line_t &l) NOTHROW; + + enum cursor_mode { SAVE, RESTORE }; + + void scr_poweron (); + void scr_soft_reset () NOTHROW; + void scr_cursor (cursor_mode mode) NOTHROW; + void scr_do_wrap () NOTHROW; + void scr_swap_screen () NOTHROW; + void scr_change_screen (int scrn); + void scr_color (unsigned int color, int fgbg) NOTHROW; + void scr_rendition (int set, int style) NOTHROW; + void scr_add_lines (const wchar_t *str, int len, int minlines = 0) NOTHROW; + void scr_backspace () NOTHROW; + void scr_tab (int count, bool ht = false) NOTHROW; + void scr_gotorc (int row, int col, int relative) NOTHROW; + void scr_index (enum page_dirn direction) NOTHROW; + void scr_erase_line (int mode) NOTHROW; + void scr_E () NOTHROW; + void scr_insdel_lines (int count, int insdel) NOTHROW; + void scr_insdel_chars (int count, int insdel) NOTHROW; + void scr_scroll_region (int top, int bot) NOTHROW; + void scr_cursor_visible (int mode) NOTHROW; + void scr_autowrap (int mode) NOTHROW; + void scr_relative_origin (int mode) NOTHROW; + void scr_insert_mode (int mode) NOTHROW; + void scr_set_tab (int mode) NOTHROW; + void scr_rvideo_mode (bool on) NOTHROW; + void scr_report_position () NOTHROW; + void set_font_style () NOTHROW; + void scr_charset_choose (int set) NOTHROW; + void scr_charset_set (int set, unsigned int ch) NOTHROW; + void scr_move_to (int y, int len) NOTHROW; + bool scr_page (int nlines) NOTHROW; + bool scr_page (enum page_dirn direction, int nlines) NOTHROW + { + return scr_page (direction * nlines); + } + bool scr_changeview (int new_view_start) NOTHROW; + void scr_bell () NOTHROW; + void scr_printscreen (int fullhist) NOTHROW; + void scr_xor_rect (int beg_row, int beg_col, int end_row, int end_col, rend_t rstyle1, rend_t rstyle2) NOTHROW; + void scr_xor_span (int beg_row, int beg_col, int end_row, int end_col, rend_t rstyle) NOTHROW; + void scr_reverse_selection () NOTHROW; + void scr_dump (int fd) NOTHROW; + + void selection_check (int check_more) NOTHROW; + void selection_changed () NOTHROW; /* sets want_refresh, corrects coordinates */ + void selection_request (Time tm, int selnum = Sel_Primary) NOTHROW; + void selection_clear (bool clipboard = false) NOTHROW; + void selection_make (Time tm); + bool selection_grab (Time tm, bool clipboard = false) NOTHROW; + void selection_start_colrow (int col, int row) NOTHROW; + void selection_delimit_word (enum page_dirn dirn, const row_col_t *mark, row_col_t *ret) NOTHROW; + void selection_extend_colrow (int32_t col, int32_t row, int button3, int buttonpress, int clickchange) NOTHROW; + void selection_remove_trailing_spaces () NOTHROW; + void selection_send (const XSelectionRequestEvent &rq) NOTHROW; + void selection_click (int clicks, int x, int y) NOTHROW; + void selection_extend (int x, int y, int flag) NOTHROW; + void selection_rotate (int x, int y) NOTHROW; + + // xdefaults.C + void rxvt_usage (int type); + const char **get_options (int argc, const char *const *argv); + int parse_keysym (const char *str, unsigned int &state); + int bind_action (const char *str, const char *arg); + const char *x_resource (const char *name); + void extract_resources (); + void enumerate_resources (void (*cb)(rxvt_term *, const char *, const char *), const char *name_p = 0, const char *class_p = 0); + void enumerate_keysym_resources (void (*cb)(rxvt_term *, const char *, const char *)) + { + enumerate_resources (cb, "keysym", "Keysym"); + } + void extract_keysym_resources (); +}; + +#endif /* _RXVT_H_ */ + diff --git a/src/rxvtdaemon.C b/src/rxvtdaemon.C index 7986c5f..2ce9e6c 100644 --- a/src/rxvtdaemon.C +++ b/src/rxvtdaemon.C @@ -36,7 +36,7 @@ char *rxvt_connection::unix_sockname () { char name[PATH_MAX]; - char *path = getenv ("RXVT_SOCKET"); + const char *path = getenv ("RXVT_SOCKET"); if (!path) { diff --git a/src/rxvtutil.h b/src/rxvtutil.h index 9d252d9..19a63aa 100644 --- a/src/rxvtutil.h +++ b/src/rxvtutil.h @@ -3,7 +3,10 @@ #include <stdlib.h> #include <string.h> + +#define ECB_NO_THREADS 1 #include "ecb.h" + #include "estl.h" #include "emman.h" diff --git a/src/screen.C b/src/screen.C index f3c6d57..b813107 100644 --- a/src/screen.C +++ b/src/screen.C @@ -3502,7 +3502,7 @@ rxvt_term::selection_send (const XSelectionRequestEvent &rq) NOTHROW } else { - cl = L""; + cl = (wchar_t *)L""; selectlen = 0; } |
