/* term.c -- Eterm terminal emulation module * * This file is original work by Michael Jennings and * Tuomo Venalainen . This file, and any other file * bearing this same message or a similar one, is distributed under * the GNU Public License (GPL) as outlined in the COPYING file. * * Copyright (C) 1997-1999, Michael Jennings and Tuomo Venalainen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ static const char cvs_ident[] = "$Id$"; #include "config.h" #include "feature.h" #include #include #include #include #include "../libmej/debug.h" #include "../libmej/mem.h" #include "../libmej/strings.h" #include "debug.h" #include "actions.h" #include "command.h" #include "e.h" #include "events.h" #include "font.h" #include "startup.h" #include "options.h" #include "pixmap.h" #include "screen.h" #include "scrollbar.h" #include "term.h" #include "windows.h" #ifdef META8_OPTION unsigned char meta_char = 033; /* Alt-key prefix */ #endif unsigned long PrivateModes = PrivMode_Default; unsigned long SavedModes = PrivMode_Default; char *def_colorName[] = { "rgb:ff/ff/ff", "rgb:0/0/0", /* fg/bg */ "rgb:0/0/0", /* 0: black (#000000) */ #ifndef NO_BRIGHTCOLOR /* low-intensity colors */ "rgb:cc/00/00", /* 1: red */ "rgb:00/cc/00", /* 2: green */ "rgb:cc/cc/00", /* 3: yellow */ "rgb:00/00/cc", /* 4: blue */ "rgb:cc/00/cc", /* 5: magenta */ "rgb:00/cc/cc", /* 6: cyan */ "rgb:fa/eb/d7", /* 7: white */ /* high-intensity colors */ "rgb:33/33/33", /* 8: bright black */ #endif /* NO_BRIGHTCOLOR */ "rgb:ff/00/00", /* 1/9: bright red */ "rgb:00/ff/00", /* 2/10: bright green */ "rgb:ff/ff/00", /* 3/11: bright yellow */ "rgb:00/00/ff", /* 4/12: bright blue */ "rgb:ff/00/ff", /* 5/13: bright magenta */ "rgb:00/ff/ff", /* 6/14: bright cyan */ "rgb:ff/ff/ff", /* 7/15: bright white */ #ifndef NO_CURSORCOLOR NULL, NULL, /* cursorColor, cursorColor2 */ #endif /* NO_CURSORCOLOR */ NULL, NULL /* pointerColor, borderColor */ #ifndef NO_BOLDUNDERLINE ,NULL, NULL /* colorBD, colorUL */ #endif /* NO_BOLDUNDERLINE */ ,"rgb:ff/ff/ff" /* menuTextColor */ ,"rgb:b2/b2/b2" /* scrollColor: match Netscape color */ ,NULL /* menuColor: match scrollbar color */ ,NULL /* unfocusedscrollColor: somebody chose black? */ ,NULL /* unfocusedMenuColor */ }; char *rs_color[NRS_COLORS]; Pixel PixColors[NRS_COLORS + NSHADOWCOLORS]; /* To handle buffer overflows properly, we must malloc a buffer. Free it when done. */ #ifdef USE_XIM # define LK_RET() do {if (kbuf_alloced) FREE(kbuf); return;} while (0) #else # define LK_RET() return #endif /* Convert the keypress event into a string */ void lookup_key(XEvent * ev) { static int numlock_state = 0; int ctrl, meta, shft, len; KeySym keysym; #ifdef USE_XIM int valid_keysym; static unsigned char short_buf[256]; unsigned char *kbuf = short_buf; int kbuf_alloced = 0; #else static unsigned char kbuf[KBUFSZ]; #endif #if DEBUG >= DEBUG_CMD static int debug_key = 1; /* accessible by a debugger only */ #endif #ifdef GREEK_SUPPORT static short greek_mode = 0; #endif /* * use Num_Lock to toggle Keypad on/off. If Num_Lock is off, allow an * escape sequence to toggle the Keypad. * * Always permit `shift' to override the current setting */ shft = (ev->xkey.state & ShiftMask); ctrl = (ev->xkey.state & ControlMask); meta = (ev->xkey.state & Mod1Mask); if (numlock_state || (ev->xkey.state & Mod5Mask)) { numlock_state = (ev->xkey.state & Mod5Mask); /* numlock toggle */ PrivMode((!numlock_state), PrivMode_aplKP); } #ifdef USE_XIM if (Input_Context != NULL) { Status status_return; kbuf[0] = '\0'; len = XmbLookupString(Input_Context, &ev->xkey, (char *) kbuf, sizeof(short_buf), &keysym, &status_return); if (status_return == XBufferOverflow) { kbuf = (unsigned char *) MALLOC(len + 1); kbuf_alloced = 1; len = XmbLookupString(Input_Context, &ev->xkey, (char *) kbuf, len, &keysym, &status_return); } valid_keysym = (status_return == XLookupKeySym) || (status_return == XLookupBoth); } else { len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(short_buf), &keysym, NULL); } #else /* USE_XIM */ len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL); /* * have unmapped Latin[2-4] entries -> Latin1 * good for installations with correct fonts, but without XLOCALE */ if (!len && (keysym >= 0x0100) && (keysym < 0x0400)) { len = 1; kbuf[0] = (keysym & 0xff); } #endif /* USE_XIM */ #ifdef USE_XIM if (valid_keysym) { #endif if (action_dispatch(ev, keysym)) { LK_RET(); } if (len) { if (keypress_exit) { exit(0); } else if (Options & Opt_homeOnInput) { TermWin.view_start = 0; } } if ((Options & Opt_report_as_keysyms) && (keysym >= 0xff00)) { len = sprintf((char *) kbuf, "\033[k%X;%X~", (unsigned int) (ev->xkey.state & 0xff), (unsigned int) (keysym & 0xff)); tt_write(kbuf, len); LK_RET(); } #ifdef HOTKEY /* for some backwards compatibility */ if (HOTKEY) { if (keysym == ks_bigfont) { change_font(0, FONT_UP); LK_RET(); } else if (keysym == ks_smallfont) { change_font(0, FONT_DN); LK_RET(); } } #endif if (shft) { /* Shift + F1 - F10 generates F11 - F20 */ if (keysym >= XK_F1 && keysym <= XK_F10) { keysym += (XK_F11 - XK_F1); shft = 0; /* turn off Shift */ } else if (!ctrl && !meta && (PrivateModes & PrivMode_ShiftKeys)) { int lnsppg; /* Lines per page to scroll */ #ifdef PAGING_CONTEXT_LINES lnsppg = TermWin.nrow - PAGING_CONTEXT_LINES; #else lnsppg = TermWin.nrow * 4 / 5; #endif switch (keysym) { /* normal XTerm key bindings */ case XK_Prior: /* Shift+Prior = scroll back */ if (TermWin.saveLines) { scr_page(UP, lnsppg); LK_RET(); } break; case XK_Next: /* Shift+Next = scroll forward */ if (TermWin.saveLines) { scr_page(DN, lnsppg); LK_RET(); } break; case XK_Insert: /* Shift+Insert = paste mouse selection */ selection_request(ev->xkey.time, ev->xkey.x, ev->xkey.y); LK_RET(); break; /* Eterm extras */ case XK_KP_Add: /* Shift+KP_Add = bigger font */ change_font(0, FONT_UP); LK_RET(); break; case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ change_font(0, FONT_DN); LK_RET(); break; } } } #ifdef UNSHIFTED_SCROLLKEYS else if (!ctrl && !meta) { switch (keysym) { case XK_Prior: if (TermWin.saveLines) { scr_page(UP, TermWin.nrow * 4 / 5); LK_RET(); } break; case XK_Next: if (TermWin.saveLines) { scr_page(DN, TermWin.nrow * 4 / 5); LK_RET(); } break; } } #endif switch (keysym) { case XK_Print: #if DEBUG >= DEBUG_SELECTION if (debug_level >= DEBUG_SELECTION) { debug_selection(); } #endif #ifdef PRINTPIPE scr_printscreen(ctrl | shft); LK_RET(); #endif break; case XK_Mode_switch: #ifdef GREEK_SUPPORT greek_mode = !greek_mode; if (greek_mode) { xterm_seq(XTerm_title, (greek_getmode() == GREEK_ELOT928 ? "[Greek: iso]" : "[Greek: ibm]")); greek_reset(); } else xterm_seq(XTerm_title, APL_NAME "-" VERSION); LK_RET(); #endif break; } if (keysym >= 0xFF00 && keysym <= 0xFFFF) { #ifdef KEYSYM_ATTRIBUTE if (!(shft | ctrl) && KeySym_map[keysym - 0xFF00] != NULL) { const unsigned char *tmpbuf; unsigned int len; tmpbuf = (KeySym_map[keysym - 0xFF00]); len = *tmpbuf++; /* escape prefix */ if (meta # ifdef META8_OPTION && (meta_char == 033) # endif ) { const unsigned char ch = '\033'; tt_write(&ch, 1); } tt_write(tmpbuf, len); LK_RET(); } else #endif switch (keysym) { case XK_BackSpace: len = 1; #ifdef FORCE_BACKSPACE kbuf[0] = (!(shft | ctrl) ? '\b' : '\177'); #elif defined(FORCE_DELETE) kbuf[0] = ((shft | ctrl) ? '\b' : '\177'); #else kbuf[0] = (((PrivateModes & PrivMode_BackSpace) ? !(shft | ctrl) : (shft | ctrl)) ? '\b' : '\177'); #endif break; case XK_Tab: if (shft) { len = 3; strcpy(kbuf, "\033[Z"); } break; #ifdef XK_KP_Home case XK_KP_Home: /* allow shift to override */ if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { len = 3; strcpy(kbuf, "\033Ow"); break; } /* -> else FALL THROUGH */ #endif case XK_Home: len = strlen(strcpy(kbuf, KS_HOME)); break; #ifdef XK_KP_Left case XK_KP_Left: /* \033Ot or standard */ case XK_KP_Up: /* \033Ox or standard */ case XK_KP_Right: /* \033Ov or standard */ case XK_KP_Down: /* \033Ow or standard */ if ((PrivateModes && PrivMode_aplKP) ? !shft : shft) { len = 3; strcpy(kbuf, "\033OZ"); kbuf[2] = ("txvw"[keysym - XK_KP_Left]); break; } else { /* translate to std. cursor key */ keysym = XK_Left + (keysym - XK_KP_Left); } /* FALL THROUGH */ #endif case XK_Left: /* "\033[D" */ case XK_Up: /* "\033[A" */ case XK_Right: /* "\033[C" */ case XK_Down: /* "\033[B" */ len = 3; strcpy(kbuf, "\033[@"); kbuf[2] = ("DACB"[keysym - XK_Left]); if (PrivateModes & PrivMode_aplCUR) { kbuf[1] = 'O'; } else if (shft) { /* do Shift first */ kbuf[2] = ("dacb"[keysym - XK_Left]); } else if (ctrl) { kbuf[1] = 'O'; kbuf[2] = ("dacb"[keysym - XK_Left]); } break; #ifndef UNSHIFTED_SCROLLKEYS # ifdef XK_KP_Prior case XK_KP_Prior: /* allow shift to override */ if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { len = 3; strcpy(kbuf, "\033Oy"); break; } /* -> else FALL THROUGH */ # endif /* XK_KP_Prior */ case XK_Prior: len = 4; strcpy(kbuf, "\033[5~"); break; # ifdef XK_KP_Next case XK_KP_Next: /* allow shift to override */ if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { len = 3; strcpy(kbuf, "\033Os"); break; } /* -> else FALL THROUGH */ # endif /* XK_KP_Next */ case XK_Next: len = 4; strcpy(kbuf, "\033[6~"); break; #endif /* UNSHIFTED_SCROLLKEYS */ #ifdef XK_KP_End case XK_KP_End: /* allow shift to override */ if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { len = 3; strcpy(kbuf, "\033Oq"); break; } /* -> else FALL THROUGH */ #endif /* XK_KP_End */ case XK_End: len = strlen(strcpy(kbuf, KS_END)); break; case XK_Select: len = 4; strcpy(kbuf, "\033[4~"); break; #ifdef DXK_Remove /* support for DEC remove like key */ case DXK_Remove: /* drop */ #endif case XK_Execute: len = 4; strcpy(kbuf, "\033[3~"); break; case XK_Insert: len = 4; strcpy(kbuf, "\033[2~"); break; case XK_Menu: len = 5; strcpy(kbuf, "\033[29~"); break; case XK_Find: len = 4; strcpy(kbuf, "\033[1~"); break; case XK_Help: len = 5; strcpy(kbuf, "\033[28~"); break; case XK_KP_Enter: /* allow shift to override */ if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { len = 3; strcpy(kbuf, "\033OM"); } else { len = 1; kbuf[0] = '\r'; } break; #ifdef XK_KP_Begin case XK_KP_Begin: len = 3; strcpy(kbuf, "\033Ou"); break; case XK_KP_Insert: len = 3; strcpy(kbuf, "\033Op"); break; case XK_KP_Delete: len = 3; strcpy(kbuf, "\033On"); break; #endif /* XK_KP_Begin */ case XK_KP_F1: /* "\033OP" */ case XK_KP_F2: /* "\033OQ" */ case XK_KP_F3: /* "\033OR" */ case XK_KP_F4: /* "\033OS" */ len = 3; strcpy(kbuf, "\033OP"); kbuf[2] += (keysym - XK_KP_F1); break; case XK_KP_Multiply: /* "\033Oj" : "*" */ case XK_KP_Add: /* "\033Ok" : "+" */ case XK_KP_Separator: /* "\033Ol" : "," */ case XK_KP_Subtract: /* "\033Om" : "-" */ case XK_KP_Decimal: /* "\033On" : "." */ case XK_KP_Divide: /* "\033Oo" : "/" */ case XK_KP_0: /* "\033Op" : "0" */ case XK_KP_1: /* "\033Oq" : "1" */ case XK_KP_2: /* "\033Or" : "2" */ case XK_KP_3: /* "\033Os" : "3" */ case XK_KP_4: /* "\033Ot" : "4" */ case XK_KP_5: /* "\033Ou" : "5" */ case XK_KP_6: /* "\033Ov" : "6" */ case XK_KP_7: /* "\033Ow" : "7" */ case XK_KP_8: /* "\033Ox" : "8" */ case XK_KP_9: /* "\033Oy" : "9" */ /* allow shift to override */ if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) { len = 3; strcpy(kbuf, "\033Oj"); kbuf[2] += (keysym - XK_KP_Multiply); } else { len = 1; kbuf[0] = ('*' + (keysym - XK_KP_Multiply)); } break; #define FKEY(n,fkey) do { \ len = 5; \ sprintf((char *) kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \ } while (0); case XK_F1: /* "\033[11~" */ case XK_F2: /* "\033[12~" */ case XK_F3: /* "\033[13~" */ case XK_F4: /* "\033[14~" */ case XK_F5: /* "\033[15~" */ FKEY(11, XK_F1); break; case XK_F6: /* "\033[17~" */ case XK_F7: /* "\033[18~" */ case XK_F8: /* "\033[19~" */ case XK_F9: /* "\033[20~" */ case XK_F10: /* "\033[21~" */ FKEY(17, XK_F6); break; case XK_F11: /* "\033[23~" */ case XK_F12: /* "\033[24~" */ case XK_F13: /* "\033[25~" */ case XK_F14: /* "\033[26~" */ FKEY(23, XK_F11); break; case XK_F15: /* "\033[28~" */ case XK_F16: /* "\033[29~" */ FKEY(28, XK_F15); break; case XK_F17: /* "\033[31~" */ case XK_F18: /* "\033[32~" */ case XK_F19: /* "\033[33~" */ case XK_F20: /* "\033[34~" */ case XK_F21: /* "\033[35~" */ case XK_F22: /* "\033[36~" */ case XK_F23: /* "\033[37~" */ case XK_F24: /* "\033[38~" */ case XK_F25: /* "\033[39~" */ case XK_F26: /* "\033[40~" */ case XK_F27: /* "\033[41~" */ case XK_F28: /* "\033[42~" */ case XK_F29: /* "\033[43~" */ case XK_F30: /* "\033[44~" */ case XK_F31: /* "\033[45~" */ case XK_F32: /* "\033[46~" */ case XK_F33: /* "\033[47~" */ case XK_F34: /* "\033[48~" */ case XK_F35: /* "\033[49~" */ FKEY(31, XK_F17); break; #undef FKEY #ifdef KS_DELETE case XK_Delete: len = strlen(strcpy(kbuf, KS_DELETE)); break; #endif } #ifdef META8_OPTION if (meta && (meta_char == 0x80) && len > 0) { kbuf[len - 1] |= 0x80; } #endif } else if (ctrl && keysym == XK_minus) { len = 1; kbuf[0] = '\037'; /* Ctrl-Minus generates ^_ (31) */ } else { #ifdef META8_OPTION /* set 8-bit on */ if (meta && (meta_char == 0x80)) { unsigned char *ch; for (ch = kbuf; ch < kbuf + len; ch++) *ch |= 0x80; meta = 0; } #endif #ifdef GREEK_SUPPORT if (greek_mode) len = greek_xlat(kbuf, len); #endif } #ifdef USE_XIM } #endif if (len <= 0) LK_RET(); /* not mapped */ /* * these modifications only affect the static keybuffer * pass Shift/Control indicators for function keys ending with `~' * * eg, * Prior = "ESC[5~" * Shift+Prior = "ESC[5~" * Ctrl+Prior = "ESC[5^" * Ctrl+Shift+Prior = "ESC[5@" */ if (kbuf[0] == '\033' && kbuf[1] == '[' && kbuf[len - 1] == '~') kbuf[len - 1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~')); /* escape prefix */ if (meta #ifdef META8_OPTION && (meta_char == 033) #endif ) { const unsigned char ch = '\033'; tt_write(&ch, 1); } #if DEBUG >= DEBUG_CMD if (debug_level >= DEBUG_CMD && debug_key) { /* Display keyboard buffer contents */ char *p; int i; fprintf(stderr, "key 0x%04X[%d]: `", (unsigned int) keysym, len); for (i = 0, p = (char *) kbuf; i < len; i++, p++) fprintf(stderr, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p); fprintf(stderr, "'\n"); } #endif /* DEBUG_CMD */ tt_write(kbuf, len); LK_RET(); } /* print pipe */ #ifdef PRINTPIPE FILE * popen_printer(void) { FILE *stream = (FILE *) popen(rs_print_pipe, "w"); if (stream == NULL) print_error("can't open printer pipe \"%s\" -- %s", rs_print_pipe, strerror(errno)); return stream; } int pclose_printer(FILE * stream) { fflush(stream); return pclose(stream); } /* simulate attached vt100 printer */ void process_print_pipe(void) { const char *const escape_seq = "\033[4i"; const char *const rev_escape_seq = "i4[\033"; int index; FILE *fd; if ((fd = popen_printer()) != NULL) { for (index = 0; index < 4; /* nil */ ) { unsigned char ch = cmd_getc(); if (ch == escape_seq[index]) index++; else if (index) for ( /*nil */ ; index > 0; index--) fputc(rev_escape_seq[index - 1], fd); if (index == 0) fputc(ch, fd); } pclose_printer(fd); } } #endif /* PRINTPIPE */ /* process escape sequences */ void process_escape_seq(void) { unsigned char ch = cmd_getc(); switch (ch) { /* case 1: do_tek_mode (); break; */ case '#': if (cmd_getc() == '8') scr_E(); break; case '(': scr_charset_set(0, cmd_getc()); break; case ')': scr_charset_set(1, cmd_getc()); break; case '*': scr_charset_set(2, cmd_getc()); break; case '+': scr_charset_set(3, cmd_getc()); break; #ifdef MULTI_CHARSET case '$': scr_charset_set(-2, cmd_getc()); break; #endif case '7': scr_cursor(SAVE); break; case '8': scr_cursor(RESTORE); break; case '=': case '>': PrivMode((ch == '='), PrivMode_aplKP); break; case '@': (void) cmd_getc(); break; case 'D': scr_index(UP); break; case 'E': scr_add_lines((unsigned char *) "\n\r", 1, 2); break; case 'G': if ((ch = cmd_getc()) == 'Q') { /* query graphics */ tt_printf((unsigned char *) "\033G0\n"); /* no graphics */ } else { do { ch = cmd_getc(); } while (ch != ':'); } break; case 'H': scr_set_tab(1); break; case 'M': scr_index(DN); break; /*case 'N': scr_single_shift (2); break; */ /*case 'O': scr_single_shift (3); break; */ case 'Z': tt_printf((unsigned char *) ESCZ_ANSWER); break; /* steal obsolete ESC [ c */ case '[': process_csi_seq(); break; case ']': process_xterm_seq(); break; case 'c': scr_poweron(); break; case 'n': scr_charset_choose(2); break; case 'o': scr_charset_choose(3); break; } } /* process CSI (code sequence introducer) sequences `ESC[' */ void process_csi_seq(void) { unsigned char ch, priv; unsigned int nargs; int arg[ESC_ARGS]; nargs = 0; arg[0] = 0; arg[1] = 0; priv = 0; ch = cmd_getc(); if (ch >= '<' && ch <= '?') { priv = ch; ch = cmd_getc(); } /* read any numerical arguments */ do { int n; for (n = 0; isdigit(ch); ch = cmd_getc()) n = n * 10 + (ch - '0'); if (nargs < ESC_ARGS) arg[nargs++] = n; if (ch == '\b') { scr_backspace(); } else if (ch == 033) { process_escape_seq(); return; } else if (ch < ' ') { scr_add_lines(&ch, 0, 1); return; } if (ch < '@') ch = cmd_getc(); } while (ch >= ' ' && ch < '@'); if (ch == 033) { process_escape_seq(); return; } else if (ch < ' ') return; switch (ch) { #ifdef PRINTPIPE case 'i': /* printing */ switch (arg[0]) { case 0: scr_printscreen(0); break; case 5: process_print_pipe(); break; } break; #endif case 'A': case 'e': /* up */ scr_gotorc((arg[0] ? -arg[0] : -1), 0, RELATIVE); break; case 'B': /* down */ scr_gotorc((arg[0] ? +arg[0] : +1), 0, RELATIVE); break; case 'C': case 'a': /* right */ scr_gotorc(0, (arg[0] ? +arg[0] : +1), RELATIVE); break; case 'D': /* left */ scr_gotorc(0, (arg[0] ? -arg[0] : -1), RELATIVE); break; case 'E': /* down & to first column */ scr_gotorc((arg[0] ? +arg[0] : +1), 0, R_RELATIVE); break; case 'F': /* up & to first column */ scr_gotorc((arg[0] ? -arg[0] : -1), 0, R_RELATIVE); break; case 'G': case '`': /* move to col */ scr_gotorc(0, (arg[0] ? arg[0] - 1 : +1), R_RELATIVE); break; case 'd': /* move to row */ scr_gotorc((arg[0] ? arg[0] - 1 : +1), 0, C_RELATIVE); break; case 'H': case 'f': /* position cursor */ switch (nargs) { case 0: scr_gotorc(0, 0, 0); break; case 1: scr_gotorc((arg[0] ? arg[0] - 1 : 0), 0, 0); break; default: scr_gotorc(arg[0] - 1, arg[1] - 1, 0); break; } break; case 'I': scr_tab(arg[0] ? +arg[0] : +1); break; case 'Z': scr_tab(arg[0] ? -arg[0] : -1); break; case 'J': scr_erase_screen(arg[0]); break; case 'K': scr_erase_line(arg[0]); break; case '@': scr_insdel_chars((arg[0] ? arg[0] : 1), INSERT); break; case 'L': scr_insdel_lines((arg[0] ? arg[0] : 1), INSERT); break; case 'M': scr_insdel_lines((arg[0] ? arg[0] : 1), DELETE); break; case 'X': scr_insdel_chars((arg[0] ? arg[0] : 1), ERASE); break; case 'P': scr_insdel_chars((arg[0] ? arg[0] : 1), DELETE); break; case 'c': #ifndef NO_VT100_ANS tt_printf(VT100_ANS); #endif break; case 'm': process_sgr_mode(nargs, arg); break; case 'n': /* request for information */ switch (arg[0]) { case 5: tt_printf((unsigned char *) "\033[0n"); break; /* ready */ case 6: scr_report_position(); break; #if defined (ENABLE_DISPLAY_ANSWER) case 7: tt_printf((unsigned char *) "%s\n", display_name); break; #endif case 8: xterm_seq(XTerm_title, APL_NAME "-" VERSION); break; case 9: #ifdef PIXMAP_OFFSET if (image_mode_is(image_bg, MODE_TRANS)) { char tbuff[70]; char shading = 0; unsigned long tint = 0xffffff; if (images[image_bg].current->iml->mod) { shading = images[image_bg].current->iml->mod->brightness / 0xff * 100; } if (images[image_bg].current->iml->rmod) { tint = (tint & 0x00ffff) | ((images[image_bg].current->iml->rmod->brightness & 0xff) << 16); } if (images[image_bg].current->iml->gmod) { tint = (tint & 0xff00ff) | ((images[image_bg].current->iml->gmod->brightness & 0xff) << 8); } if (images[image_bg].current->iml->bmod) { tint = (tint & 0xffff00) | (images[image_bg].current->iml->bmod->brightness & 0xff); } snprintf(tbuff, sizeof(tbuff), APL_NAME "-" VERSION ": Transparent - %d%% shading - 0x%06lx tint mask", shading, tint); xterm_seq(XTerm_title, tbuff); } else #endif #ifdef PIXMAP_SUPPORT { char *tbuff; unsigned short len; if (background_is_pixmap()) { char *fname = images[image_bg].current->iml->im->filename; len = strlen(fname) + sizeof(APL_NAME) + sizeof(VERSION) + 5; tbuff = MALLOC(len); snprintf(tbuff, len, APL_NAME "-" VERSION ": %s", fname); xterm_seq(XTerm_title, tbuff); FREE(tbuff); } else { xterm_seq(XTerm_title, APL_NAME "-" VERSION ": No Pixmap"); } } #endif /* PIXMAP_SUPPORT */ break; } break; case 'r': /* set top and bottom margins */ if (priv != '?') { if (nargs < 2 || arg[0] >= arg[1]) scr_scroll_region(0, 10000); else scr_scroll_region(arg[0] - 1, arg[1] - 1); break; } /* drop */ case 't': if (priv != '?') { process_window_mode(nargs, arg); break; } /* drop */ case 's': if (ch == 's' && !nargs) { scr_cursor(SAVE); break; } /* drop */ case 'h': case 'l': process_terminal_mode(ch, priv, nargs, arg); break; case 'u': if (!nargs) { scr_cursor(RESTORE); } break; case 'g': switch (arg[0]) { case 0: scr_set_tab(0); break; /* delete tab */ case 3: scr_set_tab(-1); break; /* clear all tabs */ } break; case 'W': switch (arg[0]) { case 0: scr_set_tab(1); break; /* = ESC H */ case 2: scr_set_tab(0); break; /* = ESC [ 0 g */ case 5: scr_set_tab(-1); break; /* = ESC [ 3 g */ } break; } } /* process xterm text parameters sequences `ESC ] Ps ; Pt BEL' */ void process_xterm_seq(void) { unsigned char ch, string[STRING_MAX]; int arg; ch = cmd_getc(); if (isdigit(ch)) { for (arg = 0; isdigit(ch); ch = cmd_getc()) { arg = arg * 10 + (ch - '0'); } } else if (ch == ';') { arg = 0; } else { arg = ch; ch = cmd_getc(); } if (ch == ';') { unsigned long n = 0; while ((ch = cmd_getc()) != 007) { if (ch) { if (ch == '\t') ch = ' '; /* translate '\t' to space */ else if ((ch < ' ') && !(isspace(ch) && arg == XTerm_EtermIPC)) return; /* control character - exit */ if (n < sizeof(string) - 1) string[n++] = ch; } } string[n] = '\0'; xterm_seq(arg, (char *) string); } else { unsigned long n = 0; for (; ch != '\033'; ch = cmd_getc()) { if (ch) { if (ch == '\t') ch = ' '; /* translate '\t' to space */ else if (ch < ' ') return; /* control character - exit */ if (n < sizeof(string) - 1) string[n++] = ch; } } string[n] = '\0'; if ((ch = cmd_getc()) != '\\') { return; } switch (arg) { case 'l': xterm_seq(XTerm_title, (char *) string); break; case 'L': xterm_seq(XTerm_iconName, (char *) string); break; case 'I': set_icon_pixmap((char *) string, NULL); break; default: break; } } } /* Process window manipulations */ void process_window_mode(unsigned int nargs, int args[]) { register unsigned int i; int x, y; Screen *scr; Window dummy_child; char buff[128], *name; if (!nargs) return; scr = ScreenOfDisplay(Xdisplay, Xscreen); if (!scr) return; for (i = 0; i < nargs; i++) { if (args[i] == 14) { int dummy_x, dummy_y; unsigned int dummy_border, dummy_depth; /* Store current width and height in x and y */ XGetGeometry(Xdisplay, TermWin.parent, &dummy_child, &dummy_x, &dummy_y, (unsigned int *) (&x), (unsigned int *) (&y), &dummy_border, &dummy_depth); } switch (args[i]) { case 1: XRaiseWindow(Xdisplay, TermWin.parent); break; case 2: XIconifyWindow(Xdisplay, TermWin.parent, Xscreen); break; case 3: if (i + 2 >= nargs) return; /* Make sure there are 2 args left */ x = args[++i]; y = args[++i]; if (((unsigned int) x > (unsigned int) scr->width) || ((unsigned int) y > (unsigned int) scr->height)) return; /* Don't move off-screen */ XMoveWindow(Xdisplay, TermWin.parent, x, y); break; case 4: if (i + 2 >= nargs) return; /* Make sure there are 2 args left */ y = args[++i]; x = args[++i]; XResizeWindow(Xdisplay, TermWin.parent, x, y); #ifdef USE_XIM xim_set_status_position(); #endif break; case 5: XRaiseWindow(Xdisplay, TermWin.parent); break; case 6: XLowerWindow(Xdisplay, TermWin.parent); break; case 7: XClearWindow(Xdisplay, TermWin.vt); XSync(Xdisplay, False); scr_touch(); scr_refresh(DEFAULT_REFRESH); break; case 8: if (i + 2 >= nargs) return; /* Make sure there are 2 args left */ y = args[++i]; x = args[++i]; XResizeWindow(Xdisplay, TermWin.parent, Width2Pixel(x) + 2 * TermWin.internalBorder + (scrollbar_visible()? scrollbar_trough_width() : 0), Height2Pixel(y) + 2 * TermWin.internalBorder); break; case 11: break; case 13: XTranslateCoordinates(Xdisplay, TermWin.parent, Xroot, 0, 0, &x, &y, &dummy_child); snprintf(buff, sizeof(buff), "\033[3;%d;%dt", x, y); tt_write((unsigned char *) buff, strlen(buff)); break; case 14: snprintf(buff, sizeof(buff), "\033[4;%d;%dt", y, x); tt_write((unsigned char *) buff, strlen(buff)); break; case 18: snprintf(buff, sizeof(buff), "\033[8;%d;%dt", TermWin.nrow, TermWin.ncol); tt_write((unsigned char *) buff, strlen(buff)); break; case 20: XGetIconName(Xdisplay, TermWin.parent, &name); snprintf(buff, sizeof(buff), "\033]L%s\033\\", name); tt_write((unsigned char *) buff, strlen(buff)); XFree(name); break; case 21: XFetchName(Xdisplay, TermWin.parent, &name); snprintf(buff, sizeof(buff), "\033]l%s\033\\", name); tt_write((unsigned char *) buff, strlen(buff)); XFree(name); break; default: break; } } } /* process DEC private mode sequences `ESC [ ? Ps mode' */ /* * mode can only have the following values: * 'l' = low * 'h' = high * 's' = save * 'r' = restore * 't' = toggle */ void process_terminal_mode(int mode, int priv, unsigned int nargs, int arg[]) { unsigned int i; int state; if (nargs == 0) return; /* make lo/hi boolean */ switch (mode) { case 'l': mode = 0; break; case 'h': mode = 1; break; } switch (priv) { case 0: if (mode && mode != 1) return; /* only do high/low */ for (i = 0; i < nargs; i++) switch (arg[i]) { case 4: scr_insert_mode(mode); break; /* case 38: TEK mode */ } break; case '?': for (i = 0; i < nargs; i++) switch (arg[i]) { case 1: /* application cursor keys */ PrivCases(PrivMode_aplCUR); break; /* case 2: - reset charsets to USASCII */ case 3: /* 80/132 */ PrivCases(PrivMode_132); if (PrivateModes & PrivMode_132OK) set_width(state ? 132 : 80); break; /* case 4: - smooth scrolling */ case 5: /* reverse video */ PrivCases(PrivMode_rVideo); scr_rvideo_mode(state); break; case 6: /* relative/absolute origins */ PrivCases(PrivMode_relOrigin); scr_relative_origin(state); break; case 7: /* autowrap */ PrivCases(PrivMode_Autowrap); scr_autowrap(state); break; /* case 8: - auto repeat, can't do on a per window basis */ case 9: /* X10 mouse reporting */ PrivCases(PrivMode_MouseX10); /* orthogonal */ if (PrivateModes & PrivMode_MouseX10) PrivateModes &= ~(PrivMode_MouseX11); break; #ifdef scrollBar_esc case scrollBar_esc: PrivCases(PrivMode_scrollBar); map_scrollbar(state); break; #endif case 25: /* visible/invisible cursor */ PrivCases(PrivMode_VisibleCursor); scr_cursor_visible(state); break; case 35: PrivCases(PrivMode_ShiftKeys); break; case 40: /* 80 <--> 132 mode */ PrivCases(PrivMode_132OK); break; case 47: /* secondary screen */ PrivCases(PrivMode_Screen); scr_change_screen(state); break; case 66: /* application key pad */ PrivCases(PrivMode_aplKP); break; case 67: PrivCases(PrivMode_BackSpace); break; case 1000: /* X11 mouse reporting */ PrivCases(PrivMode_MouseX11); /* orthogonal */ if (PrivateModes & PrivMode_MouseX11) PrivateModes &= ~(PrivMode_MouseX10); break; #if 0 case 1001: break; /* X11 mouse highlighting */ #endif case 1010: /* Scroll to bottom on TTY output */ if (Options & Opt_homeOnEcho) Options &= ~Opt_homeOnEcho; else Options |= Opt_homeOnEcho; break; case 1011: /* scroll to bottom on refresh */ if (Options & Opt_homeOnRefresh) Options &= ~Opt_homeOnRefresh; else Options |= Opt_homeOnRefresh; break; case 1012: /* Scroll to bottom on TTY input */ if (Options & Opt_homeOnInput) Options &= ~Opt_homeOnInput; else Options |= Opt_homeOnInput; break; } break; } } /* process sgr sequences */ void process_sgr_mode(unsigned int nargs, int arg[]) { unsigned int i; if (nargs == 0) { scr_rendition(0, ~RS_None); return; } for (i = 0; i < nargs; i++) switch (arg[i]) { case 0: scr_rendition(0, ~RS_None); break; case 1: scr_rendition(1, RS_Bold); break; case 4: scr_rendition(1, RS_Uline); break; case 5: scr_rendition(1, RS_Blink); break; case 7: scr_rendition(1, RS_RVid); break; case 22: scr_rendition(0, RS_Bold); break; case 24: scr_rendition(0, RS_Uline); break; case 25: scr_rendition(0, RS_Blink); break; case 27: scr_rendition(0, RS_RVid); break; case 30: case 31: /* set fg color */ case 32: case 33: case 34: case 35: case 36: case 37: scr_color(minColor + (arg[i] - 30), RS_Bold); break; case 39: /* default fg */ scr_color(restoreFG, RS_Bold); break; case 40: case 41: /* set bg color */ case 42: case 43: case 44: case 45: case 46: case 47: scr_color(minColor + (arg[i] - 40), RS_Blink); break; case 49: /* default bg */ scr_color(restoreBG, RS_Blink); break; } } /* color aliases, fg/bg bright-bold */ void color_aliases(int idx) { if (rs_color[idx] && isdigit(*rs_color[idx])) { int i = atoi(rs_color[idx]); if (i >= 8 && i <= 15) { /* bright colors */ i -= 8; #ifndef NO_BRIGHTCOLOR rs_color[idx] = rs_color[minBright + i]; return; #endif } if (i >= 0 && i <= 7) /* normal colors */ rs_color[idx] = rs_color[minColor + i]; } } /* find if fg/bg matches any of the normal (low-intensity) colors */ #ifndef NO_BRIGHTCOLOR void set_colorfgbg(void) { unsigned int i; static char *colorfgbg_env = NULL; char *p; int fg = -1, bg = -1; if (!colorfgbg_env) { colorfgbg_env = (char *) malloc(30); strcpy(colorfgbg_env, "COLORFGBG=default;default;bg"); } for (i = BlackColor; i <= WhiteColor; i++) { if (PixColors[fgColor] == PixColors[i]) { fg = (i - BlackColor); break; } } for (i = BlackColor; i <= WhiteColor; i++) { if (PixColors[bgColor] == PixColors[i]) { bg = (i - BlackColor); break; } } p = strchr(colorfgbg_env, '='); p++; if (fg >= 0) sprintf(p, "%d;", fg); else strcpy(p, "default;"); p = strchr(p, '\0'); if (bg >= 0) sprintf(p, # ifdef PIXMAP_SUPPORT "default;" # endif "%d", bg); else strcpy(p, "default"); putenv(colorfgbg_env); colorfgbg = DEFAULT_RSTYLE; for (i = minColor; i <= maxColor; i++) { if (PixColors[fgColor] == PixColors[i] # ifndef NO_BOLDUNDERLINE && PixColors[fgColor] == PixColors[colorBD] # endif /* NO_BOLDUNDERLINE */ /* if we wanted boldFont to have precedence */ # if 0 /* ifndef NO_BOLDFONT */ && TermWin.boldFont == NULL # endif /* NO_BOLDFONT */ ) colorfgbg = SET_FGCOLOR(colorfgbg, i); if (PixColors[bgColor] == PixColors[i]) colorfgbg = SET_BGCOLOR(colorfgbg, i); } } #endif /* NO_BRIGHTCOLOR */ /* xterm sequences - title, iconName, color (exptl) */ #ifdef SMART_WINDOW_TITLE static void set_title(const char *str) { char *name; if (XFetchName(Xdisplay, TermWin.parent, &name) == 0) { name = NULL; } if (name == NULL || strcmp(name, str)) { XStoreName(Xdisplay, TermWin.parent, str); } if (name) { XFree(name); } } static void set_icon_name(const char *str) { char *name; if (XGetIconName(Xdisplay, TermWin.parent, &name) == 0) { name = NULL; } if (name == NULL || strcmp(name, str)) { XSetIconName(Xdisplay, TermWin.parent, str); } if (name) { XFree(name); } } #else # define set_title(str) XStoreName(Xdisplay, TermWin.parent, str) # define set_icon_name(str) XSetIconName(Xdisplay, TermWin.parent, str) #endif /* * XTerm escape sequences: ESC ] Ps;Pt BEL * 0 = change iconName/title * 1 = change iconName * 2 = change title * 46 = change logfile (not implemented) * 50 = change font * * rxvt/Eterm extensions: * 5 = Hostile takeover (grab focus and raise) * 6 = Transparency mode stuff * 10 = menu * 20 = bg pixmap * 39 = change default fg color * 49 = change default bg color */ void xterm_seq(int op, const char *str) { XColor xcol; char *nstr, *tnstr, *orig_tnstr, *valptr; unsigned char eterm_seq_op, which = 0; #ifdef PIXMAP_SUPPORT unsigned char changed = 0, scaled = 0; char *color, *mod; #endif if (!str) return; #ifdef PIXMAP_SUPPORT orig_tnstr = tnstr = StrDup(str); #endif switch (op) { case XTerm_title: set_title(str); break; case XTerm_prop: if ((nstr = (char *) strsep(&tnstr, ";")) == NULL) { break; } if ((valptr = strchr(nstr, '=')) != NULL) { *(valptr++) = 0; } set_text_property(TermWin.parent, nstr, valptr); break; case XTerm_name: set_title(str); /* drop */ case XTerm_iconName: set_icon_name(str); break; case XTerm_Takeover: XSetInputFocus(Xdisplay, TermWin.parent, RevertToParent, CurrentTime); XRaiseWindow(Xdisplay, TermWin.parent); break; case XTerm_EtermSeq: /* Eterm proprietary escape sequences Syntax: ESC ] 6 ; ; BEL where is: 0 Set/toggle transparency 1 Set color modifiers 3 Force update of pseudo-transparent background 10 Set scrollbar type/width 11 Set/toggle right-side scrollbar 12 Set/toggle floating scrollbar 13 Set/toggle popup scrollbar 20 Set/toggle visual bell 21 Set/toggle map alert 22 Set/toggle xterm selection behavior 23 Set/toggle triple-click line selection 24 Set/toggle viewport mode 25 Set/toggle selection of trailing spaces 30 Do not use 40 Do not use 50 Move window to another desktop 70 Exit Eterm 71 Save current configuration to a file and is an optional argument, depending on the particular sequence being used. It (along with its preceeding semicolon) may or may not be needed. */ D_CMD(("Got XTerm_EtermSeq sequence\n")); nstr = (char *) strsep(&tnstr, ";"); eterm_seq_op = (unsigned char) strtol(nstr, (char **) NULL, 10); D_CMD((" XTerm_EtermSeq operation is %d\n", eterm_seq_op)); /* Yes, there is order to the numbers for this stuff. And here it is: 0-9 Transparency Configuration 10-14 Scrollbar Configuration 15-19 Menu Configuration 20-29 Miscellaneous Toggles 30-39 Foreground/Text Color Configuration 40-49 Background Color Configuration 50-69 Window/Window Manager Configuration/Interaction 70-79 Internal Eterm Operations */ switch (eterm_seq_op) { #ifdef PIXMAP_OFFSET case 0: nstr = (char *) strsep(&tnstr, ";"); if (nstr) { if (BOOL_OPT_ISTRUE(nstr)) { D_CMD((" Request to enable transparency.\n")); FOREACH_IMAGE(if (!image_mode_is(idx, MODE_TRANS) && image_mode_is(idx, ALLOW_TRANS)) { \ image_set_mode(idx, MODE_TRANS); \ if (images[idx].current->pmap->pixmap != None) { \ Imlib_free_pixmap(imlib_id, images[idx].current->pmap->pixmap); \ } \ images[idx].current->pmap->pixmap = None; \ }); } else if (BOOL_OPT_ISFALSE(nstr)) { D_CMD((" Request to disable transparency.\n")); FOREACH_IMAGE(if (image_mode_is(idx, MODE_TRANS)) {if (image_mode_is(idx, ALLOW_IMAGE)) {image_set_mode(idx, MODE_IMAGE);} else {image_set_mode(idx, MODE_SOLID);}}); } else { D_CMD((" Bad boolean value in transparency request.\n")); break; } } else { D_CMD((" Request to toggle transparency.\n")); FOREACH_IMAGE(if (!image_mode_is(idx, MODE_TRANS) && image_mode_is(idx, ALLOW_TRANS)) { \ image_set_mode(idx, MODE_TRANS); \ if (images[idx].current->pmap->pixmap != None) { \ Imlib_free_pixmap(imlib_id, images[idx].current->pmap->pixmap); \ } \ images[idx].current->pmap->pixmap = None; \ } else if (image_mode_is(idx, MODE_TRANS)) {if (image_mode_is(idx, ALLOW_IMAGE)) {image_set_mode(idx, MODE_IMAGE);} else {image_set_mode(idx, MODE_SOLID);}}); } redraw_all_images(); break; case 1: if ((color = (char *) strsep(&tnstr, ";")) == NULL) { break; } if ((strlen(color) == 2) || (!strcasecmp(color, "down"))) { /* They specified an image index */ if (!strcasecmp(color, "bg")) { which = image_bg; } else if (!strcasecmp(color, "sb")) { which = image_sb; } else if (!strcasecmp(color, "sa")) { which = image_sa; } else if (!strcasecmp(color, "up")) { which = image_up; } else if (!strcasecmp(color, "down")) { which = image_down; } else { break; } if ((color = (char *) strsep(&tnstr, ";")) == NULL) { break; } } else { which = image_bg; } if ((mod = (char *) strsep(&tnstr, ";")) == NULL) { break; } if ((valptr = (char *) strsep(&tnstr, ";")) == NULL) { break; } D_CMD(("Modifying the %s attribute of the %s color modifier of the %s image to be %s\n", mod, color, get_image_type(which), valptr)); if (image_mode_is(which, MODE_TRANS) && (desktop_pixmap != None)) { free_desktop_pixmap(); } if (image_mode_is(which, MODE_VIEWPORT) && (viewport_pixmap != None)) { XFreePixmap(Xdisplay, viewport_pixmap); viewport_pixmap = None; /* Force the re-read */ } if (!strcasecmp(color, "image")) { imlib_t *iml = images[which].current->iml; if (iml->mod == NULL) { iml->mod = (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier)); iml->mod->brightness = iml->mod->contrast = iml->mod->gamma = 0xff; } if (!BEG_STRCASECMP("brightness", mod)) { iml->mod->brightness = (int) strtol(valptr, (char **) NULL, 0); } else if (!BEG_STRCASECMP("contrast", mod)) { iml->mod->contrast = (int) strtol(valptr, (char **) NULL, 0); } else if (!BEG_STRCASECMP("gamma", mod)) { iml->mod->gamma = (int) strtol(valptr, (char **) NULL, 0); } } else if (!strcasecmp(color, "red")) { imlib_t *iml = images[which].current->iml; if (iml->rmod == NULL) { iml->rmod = (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier)); iml->rmod->brightness = iml->rmod->contrast = iml->rmod->gamma = 0xff; } if (!BEG_STRCASECMP("brightness", mod)) { iml->rmod->brightness = (int) strtol(valptr, (char **) NULL, 0); } else if (!BEG_STRCASECMP("contrast", mod)) { iml->rmod->contrast = (int) strtol(valptr, (char **) NULL, 0); } else if (!BEG_STRCASECMP("gamma", mod)) { iml->rmod->gamma = (int) strtol(valptr, (char **) NULL, 0); } } else if (!strcasecmp(color, "green")) { imlib_t *iml = images[which].current->iml; if (iml->gmod == NULL) { iml->gmod = (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier)); iml->gmod->brightness = iml->gmod->contrast = iml->gmod->gamma = 0xff; } if (!BEG_STRCASECMP("brightness", mod)) { iml->gmod->brightness = (int) strtol(valptr, (char **) NULL, 0); } else if (!BEG_STRCASECMP("contrast", mod)) { iml->gmod->contrast = (int) strtol(valptr, (char **) NULL, 0); } else if (!BEG_STRCASECMP("gamma", mod)) { iml->gmod->gamma = (int) strtol(valptr, (char **) NULL, 0); } } else if (!strcasecmp(color, "blue")) { imlib_t *iml = images[which].current->iml; if (iml->bmod == NULL) { iml->bmod = (ImlibColorModifier *) MALLOC(sizeof(ImlibColorModifier)); iml->bmod->brightness = iml->bmod->contrast = iml->bmod->gamma = 0xff; } if (!BEG_STRCASECMP("brightness", mod)) { iml->bmod->brightness = (int) strtol(valptr, (char **) NULL, 0); } else if (!BEG_STRCASECMP("contrast", mod)) { iml->bmod->contrast = (int) strtol(valptr, (char **) NULL, 0); } else if (!BEG_STRCASECMP("gamma", mod)) { iml->bmod->gamma = (int) strtol(valptr, (char **) NULL, 0); } } redraw_all_images(); break; case 3: get_desktop_window(); if (desktop_window == None) { FOREACH_IMAGE(if (image_mode_is(idx, MODE_TRANS)) {image_set_mode(idx, MODE_IMAGE); image_allow_mode(idx, ALLOW_IMAGE);}); break; } get_desktop_pixmap(); redraw_all_images(); break; #endif case 10: nstr = (char *) strsep(&tnstr, ";"); if (nstr && *nstr) { if (!strcasecmp(nstr, "xterm")) { #ifdef XTERM_SCROLLBAR scrollBar.type = SCROLLBAR_XTERM; #else print_error("Support for xterm scrollbars was not compiled in. Sorry."); #endif } else if (!strcasecmp(nstr, "next")) { #ifdef NEXT_SCROLLBAR scrollBar.type = SCROLLBAR_NEXT; #else print_error("Support for NeXT scrollbars was not compiled in. Sorry."); #endif } else if (!strcasecmp(nstr, "motif")) { #ifdef MOTIF_SCROLLBAR scrollBar.type = SCROLLBAR_MOTIF; #else print_error("Support for motif scrollbars was not compiled in. Sorry."); #endif } else { print_error("Unrecognized scrollbar type \"%s\".", nstr); } scrollbar_reset(); map_scrollbar(0); map_scrollbar(1); scrollbar_show(0); } nstr = (char *) strsep(&tnstr, ";"); if (nstr && *nstr) { scrollBar.width = strtoul(nstr, (char **) NULL, 0); if (scrollBar.width == 0) { print_error("Invalid scrollbar length \"%s\".", nstr); scrollBar.width = SB_WIDTH; } scrollbar_reset(); map_scrollbar(0); map_scrollbar(1); scrollbar_show(0); } break; case 11: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollBar_right); scrollbar_reset(); map_scrollbar(0); map_scrollbar(1); scrollbar_show(0); break; case 12: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollBar_floating); scrollbar_reset(); map_scrollbar(0); map_scrollbar(1); scrollbar_show(0); break; case 13: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_scrollbar_popup); break; case 20: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_visualBell); break; #ifdef MAPALERT_OPTION case 21: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_mapAlert); break; #endif case 22: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_xterm_select); break; case 23: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_select_whole_line); break; case 24: nstr = (char *) strsep(&tnstr, ";"); FOREACH_IMAGE(if (!image_mode_is(idx, MODE_VIEWPORT) && image_mode_is(idx, ALLOW_VIEWPORT)) {image_set_mode(idx, MODE_VIEWPORT);}); redraw_all_images(); break; case 25: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_select_trailing_spaces); break; case 26: nstr = (char *) strsep(&tnstr, ";"); OPT_SET_OR_TOGGLE(nstr, Options, Opt_report_as_keysyms); break; case 30: nstr = (char *) strsep(&tnstr, ";"); if (nstr) { if (XParseColor(Xdisplay, cmap, nstr, &xcol) && XAllocColor(Xdisplay, cmap, &xcol)) { PixColors[fgColor] = xcol.pixel; scr_refresh(DEFAULT_REFRESH); } } break; case 40: nstr = (char *) strsep(&tnstr, ";"); if (nstr) { if (XParseColor(Xdisplay, cmap, nstr, &xcol) && XAllocColor(Xdisplay, cmap, &xcol)) { PixColors[bgColor] = xcol.pixel; scr_refresh(DEFAULT_REFRESH); } } break; case 50: /* Change desktops */ nstr = (char *) strsep(&tnstr, ";"); if (nstr && *nstr) { XClientMessageEvent xev; rs_desktop = (int) strtol(nstr, (char **) NULL, 0); xev.type = ClientMessage; xev.window = TermWin.parent; xev.message_type = XInternAtom(Xdisplay, "_WIN_WORKSPACE", False); xev.format = 32; xev.data.l[0] = rs_desktop; XChangeProperty(Xdisplay, TermWin.parent, xev.message_type, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &rs_desktop, 1); XSendEvent(Xdisplay, Xroot, False, SubstructureNotifyMask, (XEvent *) & xev); } break; case 70: /* Exit Eterm */ exit(0); break; case 71: /* Save current config */ nstr = (char *) strsep(&tnstr, ";"); if (nstr && *nstr) { save_config(nstr); } else { save_config(NULL); } break; case 80: /* Set debugging level */ nstr = (char *) strsep(&tnstr, ";"); if (nstr && *nstr) { debug_level = (unsigned int) strtoul(nstr, (char **) NULL, 0); } break; default: break; } break; case XTerm_Pixmap: #ifdef PIXMAP_SUPPORT FOREACH_IMAGE(if (!image_mode_is(idx, MODE_IMAGE) && image_mode_is(idx, ALLOW_IMAGE)) {image_set_mode(idx, MODE_IMAGE);}); if (!strcmp(str, ";")) { load_image("", image_bg); bg_needs_update = 1; } else { nstr = (char *) strsep(&tnstr, ";"); if (nstr) { if (*nstr) { set_pixmap_scale("", images[image_bg].current->pmap); bg_needs_update = 1; load_image(nstr, image_bg); } while ((nstr = (char *) strsep(&tnstr, ";")) && *nstr) { changed += set_pixmap_scale(nstr, images[image_bg].current->pmap); scaled = 1; } } else { load_image("", image_bg); bg_needs_update = 1; } } if ((changed) || (bg_needs_update)) { redraw_image(image_bg); } #endif /* PIXMAP_SUPPORT */ break; case XTerm_EtermIPC: for (; (nstr = (char *) strsep(&tnstr, ";"));) { eterm_ipc_parse(nstr); } break; case XTerm_restoreFG: #ifdef XTERM_COLOR_CHANGE set_window_color(fgColor, str); #endif break; case XTerm_restoreBG: #ifdef XTERM_COLOR_CHANGE set_window_color(bgColor, str); #endif break; case XTerm_logfile: break; case XTerm_font: change_font(0, str); break; #ifdef ETERM_COMMAND_MODE case ETerm_command_mode: fprintf(stderr, "ETerm_command_mode\n"); break; #endif default: D_CMD(("Unsupported xterm escape sequence operator: 0x%02x\n", op)); break; } #ifdef PIXMAP_SUPPORT FREE(orig_tnstr); #endif }