[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xterm: Changes to 'upstream-unstable'



 Makefile.in    |   10 
 button.c       |   35 ++-
 charclass.c    |    7 
 charproc.c     |  603 ++++++++++++++++++++++++++++++++++++++++++---------------
 ctlseqs.ms     |   26 +-
 ctlseqs.txt    |   29 +-
 fontutils.c    |    9 
 main.h         |    6 
 menu.c         |    4 
 misc.c         |   45 ++--
 ptyx.h         |   53 ++++-
 screen.c       |   14 -
 termcap        |   18 -
 util.c         |   90 +++++---
 version.h      |    4 
 xterm.h        |    4 
 xterm.log.html |   19 +
 xterm.man      |   81 +++++++
 xutf8.c        |   16 -
 19 files changed, 797 insertions(+), 276 deletions(-)

New commits:
commit 348bcb54a657552033bf9840d0aac61f4af6f23d
Author: Julien Cristau <jcristau@debian.org>
Date:   Wed Nov 11 16:29:28 2009 +0100

    Import xterm 251

diff --git a/Makefile.in b/Makefile.in
index 671c6e3..9bf2014 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-## $XTermId: Makefile.in,v 1.158 2009/04/27 19:29:31 tom Exp $
+## $XTermId: Makefile.in,v 1.161 2009/11/05 23:06:36 tom Exp $
 ##
 ## Copyright 2002-2008,2009 by Thomas E. Dickey
 ##
@@ -117,7 +117,7 @@ all :	$(PROGRAMS)
 	grep '^CASE_' $< | $(AWK) '{printf "#define %s %d\n", $$1, n++}' >$@
 
 .man.$(manext) :
-	$(SHELL) $(srcdir)/minstall.sh "$(INSTALL_DATA)" $(srcdir)/xterm.man $@ $(appsdir)
+	$(SHELL) $(srcdir)/minstall.sh "$(INSTALL_DATA)" $< $@ $(appsdir)
 
 .$(manext).html :
 	GROFF_NO_SGR=stupid $(SHELL) -c "tbl $*.$(manext) | groff -Thtml -man" >$@
@@ -316,6 +316,7 @@ distclean : clean
 	-$(RM) Makefile config.status config.cache config.log xtermcfg.h
 	-$(RM) *.ps *.pdf *.png
 	-$(RM) xterm.html xterm.$(manext) xterm.txt
+	-$(RM) resize.html resize.$(manext) resize.txt
 	-$(RM) ctlseqs.html ctlseqs.$(manext)
 
 realclean : distclean
@@ -332,6 +333,11 @@ ctlseqs.pdf : ctlseqs.ps
 ctlseqs.ps : ctlseqs.ms
 ctlseqs.txt : ctlseqs.ms
 ################################################################################
+resize.html : resize.$(manext)
+resize.pdf : resize.ps
+resize.ps : resize.$(manext)
+resize.txt : resize.$(manext)
+################################################################################
 xterm.html : xterm.$(manext)
 xterm.pdf : xterm.ps
 xterm.ps : xterm.$(manext)
diff --git a/button.c b/button.c
index 6ccd5d5..4c0b1a1 100644
--- a/button.c
+++ b/button.c
@@ -1,4 +1,4 @@
-/* $XTermId: button.c,v 1.356 2009/10/10 23:37:27 tom Exp $ */
+/* $XTermId: button.c,v 1.359 2009/10/28 23:50:23 tom Exp $ */
 
 /*
  * Copyright 1999-2008,2009 by Thomas E. Dickey
@@ -62,6 +62,7 @@ button.c	Handles button events in the terminal emulator.
 #include <xterm.h>
 
 #include <stdio.h>
+#include <assert.h>
 
 #include <X11/Xatom.h>
 #include <X11/Xmu/Atoms.h>
@@ -2601,6 +2602,7 @@ class_of(LineData * ld, CELL * cell)
     }
 #endif
 
+    assert(temp.col < ld->lineSize);
     return CharacterClass((int) (ld->charData[temp.col]));
 }
 
@@ -2629,9 +2631,11 @@ okPosition(TScreen * screen,
     if (cell->row > screen->max_row) {
 	result = False;
     } else if (cell->col > (LastTextCol(screen, *ld, cell->row) + 1)) {
-	cell->col = 0;
-	*ld = GET_LINEDATA(screen, ++cell->row);
-	result = False;
+	if (cell->row < screen->max_row) {
+	    cell->col = 0;
+	    *ld = GET_LINEDATA(screen, ++cell->row);
+	    result = False;
+	}
     }
     return result;
 }
@@ -2733,6 +2737,7 @@ make_indexed_text(TScreen * screen, int row, unsigned length, int *indexed)
 		Char *next = last;
 		unsigned data = ld->charData[col];
 
+		assert(col < ld->lineSize);
 		/* some internal points may not be drawn */
 		if (data == 0)
 		    data = ' ';
@@ -2941,6 +2946,9 @@ do_select_regex(TScreen * screen, CELL * startc, CELL * endc)
 #define PrevRow(name) \
 	ld.name = GET_LINEDATA(screen, --screen->name.row)
 
+#define MoreRows(name) \
+	screen->name.row < screen->max_row
+
 #define isPrevWrapped(name) \
 	(screen->name.row > 0 \
 	   && (ltmp = GET_LINEDATA(screen, screen->name.row - 1)) != 0 \
@@ -2979,7 +2987,7 @@ ComputeSelect(XtermWidget xw,
     if (first.col > 1
 	&& isWideCell(first.row, first.col - 1)
 	&& XTERM_CELL(first.row, first.col - 0) == HIDDEN_CHAR) {
-	fprintf(stderr, "Adjusting start. Changing downwards from %i.\n", first.col);
+	TRACE(("Adjusting start. Changing downwards from %i.\n", first.col));
 	first.col -= 1;
 	if (last.col == (first.col + 1))
 	    last.col--;
@@ -3038,6 +3046,8 @@ ComputeSelect(XtermWidget xw,
 		++screen->endSel.col;
 		if (screen->endSel.col > length
 		    && LineTstWrapped(ld.endSel)) {
+		    if (!MoreRows(endSel))
+			break;
 		    screen->endSel.col = 0;
 		    NextRow(endSel);
 		    length = LastTextCol(screen, ld.endSel, screen->endSel.row);
@@ -3048,7 +3058,8 @@ ComputeSelect(XtermWidget xw,
 	     * especially note that it includes the last character in a word.
 	     * So we do no --endSel.col and do special eol handling.
 	     */
-	    if (screen->endSel.col > length + 1) {
+	    if (screen->endSel.col > length + 1
+		&& MoreRows(endSel)) {
 		screen->endSel.col = 0;
 		NextRow(endSel);
 	    }
@@ -3065,7 +3076,8 @@ ComputeSelect(XtermWidget xw,
 
     case Select_LINE:
 	TRACE(("Select_LINE\n"));
-	while (LineTstWrapped(ld.endSel)) {
+	while (LineTstWrapped(ld.endSel)
+	       && MoreRows(endSel)) {
 	    NextRow(endSel);
 	}
 	if (screen->cutToBeginningOfLine
@@ -3101,7 +3113,7 @@ ComputeSelect(XtermWidget xw,
 	    }
 	    screen->startSel.col = 0;
 	    /* scan forward for end of group */
-	    while (screen->endSel.row < screen->max_row &&
+	    while (MoreRows(endSel) &&
 		   (LastTextCol(screen, ld.endSel, screen->endSel.row + 1) >
 		    0 ||
 		    LineTstWrapped(ld.endSel))) {
@@ -3115,7 +3127,7 @@ ComputeSelect(XtermWidget xw,
 	TRACE(("Select_PAGE\n"));
 	screen->startSel.row = 0;
 	screen->startSel.col = 0;
-	screen->endSel.row = screen->max_row + 1;
+	screen->endSel.row = MaxRows(screen);
 	screen->endSel.col = 0;
 	break;
 
@@ -3123,7 +3135,7 @@ ComputeSelect(XtermWidget xw,
 	TRACE(("Select_ALL\n"));
 	screen->startSel.row = -screen->savedlines;
 	screen->startSel.col = 0;
-	screen->endSel.row = screen->max_row + 1;
+	screen->endSel.row = MaxRows(screen);
 	screen->endSel.col = 0;
 	break;
 
@@ -3711,6 +3723,8 @@ _OwnSelection(XtermWidget xw,
 	    unsigned long limit =
 	    (unsigned long) (4 * XMaxRequestSize(XtDisplay((Widget) xw)) - 32);
 	    if (screen->selection_length > limit) {
+		TRACE(("selection too big (%lu bytes), not storing in CUT_BUFFER%d\n",
+		       screen->selection_length, cutbuffer));
 		fprintf(stderr,
 			"%s: selection too big (%lu bytes), not storing in CUT_BUFFER%d\n",
 			xterm_name, screen->selection_length, cutbuffer);
@@ -3849,6 +3863,7 @@ SaveText(TScreen * screen,
 #endif
     *eol = !LineTstWrapped(ld);
     for (i = scol; i < ecol; i++) {
+	assert(i < ld->lineSize);
 	c = E2A(ld->charData[i]);
 #if OPT_WIDE_CHARS
 	/* We want to strip out every occurrence of HIDDEN_CHAR AFTER a
diff --git a/charclass.c b/charclass.c
index 8452842..675ef17 100644
--- a/charclass.c
+++ b/charclass.c
@@ -1,4 +1,4 @@
-/* $XTermId: charclass.c,v 1.21 2008/12/30 17:35:09 tom Exp $ */
+/* $XTermId: charclass.c,v 1.22 2009/11/05 23:46:15 tom Exp $ */
 
 /*
  * Compact and efficient reimplementation of the
@@ -51,7 +51,8 @@ SetCharacterClassRange(int low, int high, int value)
     /* make sure we have at least one free entry left at table end */
     if (classtab[0].last > classtab[0].cclass - 2) {
 	classtab[0].cclass += 5 + classtab[0].cclass / 4;
-	classtab = TypeRealloc(struct classentry, (unsigned) classtab[0].cclass, classtab);
+	classtab = TypeRealloc(struct classentry,
+			         (unsigned) classtab[0].cclass, classtab);
 	if (!classtab)
 	    abort();
     }
@@ -77,7 +78,7 @@ init_classtab(void)
 {
     const int size = 50;
 
-    classtab = TypeMallocN(struct classentry, size);
+    classtab = TypeMallocN(struct classentry, (unsigned) size);
     if (!classtab)
 	abort();
     classtab[0].cclass = size;
diff --git a/charproc.c b/charproc.c
index c65f55c..43751b6 100644
--- a/charproc.c
+++ b/charproc.c
@@ -1,4 +1,4 @@
-/* $XTermId: charproc.c,v 1.980 2009/10/11 23:48:30 tom Exp $ */
+/* $XTermId: charproc.c,v 1.990 2009/11/11 00:34:11 tom Exp $ */
 
 /*
 
@@ -132,8 +132,13 @@ in this Software without prior written authorization from The Open Group.
 #include <charclass.h>
 #include <xstrings.h>
 
+typedef struct {
+    const char *name;
+    int code;
+} FlagList;
+
 static IChar doinput(void);
-static int set_character_class(char *s);
+static int set_character_class(char * /*s */ );
 static void FromAlternate(XtermWidget /* xw */ );
 static void RequestResize(XtermWidget termw, int rows, int cols, Bool text);
 static void SwitchBufs(XtermWidget xw);
@@ -483,6 +488,8 @@ static XtResource xterm_resources[] =
     Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL),
     Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID),
     Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"),
+    Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps,
+	 screen.disallowedWinOps, DEF_DISALLOWED_WINDOW),
     Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes,
 	 screen.eightbit_select_types, NULL),
     Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT),
@@ -1285,6 +1292,24 @@ select_charset(struct ParseState *sp, int type, int size)
     }
 }
 
+static int
+zero_if_default(int which)
+{
+    int result = (nparam > which) ? param[which] : 0;
+    if (result <= 0)
+	result = 0;
+    return result;
+}
+
+static int
+one_if_default(int which)
+{
+    int result = (nparam > which) ? param[which] : 0;
+    if (result <= 0)
+	result = 1;
+    return result;
+}
+
 static Boolean
 doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 {
@@ -1752,13 +1777,15 @@ doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 
 	case CASE_ESC_DIGIT:
 	    /* digit in csi or dec mode */
-	    if ((row = param[nparam - 1]) == DEFAULT)
-		row = 0;
-	    param[nparam - 1] = (10 * row) + ((int) c - '0');
-	    if (param[nparam - 1] > 65535)
-		param[nparam - 1] = 65535;
-	    if (sp->parsestate == csi_table)
-		sp->parsestate = csi2_table;
+	    if (nparam > 0) {
+		if ((row = param[nparam - 1]) == DEFAULT)
+		    row = 0;
+		param[nparam - 1] = (10 * row) + ((int) c - '0');
+		if (param[nparam - 1] > 65535)
+		    param[nparam - 1] = 65535;
+		if (sp->parsestate == csi_table)
+		    sp->parsestate = csi2_table;
+	    }
 	    break;
 
 	case CASE_ESC_SEMI:
@@ -1919,7 +1946,7 @@ doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 		/* Track mouse as long as in window and between
 		 * specified rows
 		 */
-		start.row = param[2] - 1;
+		start.row = one_if_default(2) - 1;
 		start.col = param[1] - 1;
 		TrackMouse(xw,
 			   param[0],
@@ -2505,10 +2532,15 @@ doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 		VTReset(xw, False, False);
 		screen->vtXX_level = param[0] - 60;
 		if (param[0] > 61) {
-		    if (param[1] == 1)
+		    switch (zero_if_default(1)) {
+		    case 1:
 			show_8bit_control(False);
-		    else if (param[1] == 0 || param[1] == 2)
+			break;
+		    case 0:
+		    case 2:
 			show_8bit_control(True);
+			break;
+		    }
 		}
 	    }
 	    sp->parsestate = sp->groundtable;
@@ -2930,8 +2962,7 @@ doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 
 	case CASE_XTERM_WINOPS:
 	    TRACE(("CASE_XTERM_WINOPS\n"));
-	    if (AllowWindowOps(xw))
-		window_ops(xw);
+	    window_ops(xw);
 	    sp->parsestate = sp->groundtable;
 	    break;
 #if OPT_WIDE_CHARS
@@ -3041,6 +3072,7 @@ v_write(int f, Char * data, unsigned len)
     int riten;
     unsigned c = len;
 
+    TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len)));
     if (v_bufstr == NULL && len > 0) {
 	v_buffer = (Char *) XtMalloc((Cardinal) len);
 	v_bufstr = v_buffer;
@@ -4472,35 +4504,86 @@ restoremodes(XtermWidget xw)
 }
 
 /*
+ * Convert an XTextProperty to a string.
+ *
+ * This frees the data owned by the XTextProperty, and returns in its place the
+ * string, which must be freed by the caller.
+ */
+static char *
+property_to_string(XTextProperty * text)
+{
+    char *result = 0;
+    char **list;
+    int length = 0;
+
+    if (XTextPropertyToStringList(text, &list, &length)) {
+	int n, c, pass;
+	size_t need = 0;
+
+	for (pass = 0; pass < 2; ++pass) {
+	    for (n = 0, need = 0; n < length; n++) {
+		char *s = list[n];
+		while ((c = *s++) != '\0') {
+		    if (pass)
+			result[need] = (char) c;
+		    ++need;
+		}
+	    }
+	    if (pass)
+		result[need] = '\0';
+	    else
+		result = malloc(need + 1);
+	    if (result == 0)
+		break;
+	}
+	XFreeStringList(list);
+    }
+    if (text->value != 0)
+	XFree(text->value);
+
+    return result;
+}
+
+static char *
+get_icon_label(XtermWidget xw)
+{
+    XTextProperty text;
+    char *result = 0;
+
+    if (XGetWMIconName(TScreenOf(xw)->display, VShellWindow, &text)) {
+	result = property_to_string(&text);
+    }
+    return result;
+}
+
+static char *
+get_window_label(XtermWidget xw)
+{
+    XTextProperty text;
+    char *result = 0;
+
+    if (XGetWMName(TScreenOf(xw)->display, VShellWindow, &text)) {
+	result = property_to_string(&text);
+    }
+    return result;
+}
+
+/*
  * Report window label (icon or title) in dtterm protocol
  * ESC ] code label ESC backslash
  */
 static void
 report_win_label(XtermWidget xw,
 		 int code,
-		 XTextProperty * text,
-		 Status ok)
+		 char *text)
 {
-    char **list;
-    int length = 0;
-
     reply.a_type = ANSI_ESC;
     unparseputc(xw, ANSI_ESC);
     unparseputc(xw, ']');
     unparseputc(xw, code);
 
-    if (ok) {
-	if (XTextPropertyToStringList(text, &list, &length)) {
-	    int n, c;
-	    for (n = 0; n < length; n++) {
-		char *s = list[n];
-		while ((c = *s++) != '\0')
-		    unparseputc(xw, c);
-	    }
-	    XFreeStringList(list);
-	}
-	if (text->value != 0)
-	    XFree(text->value);
+    if (text != 0) {
+	unparseputs(xw, text);
     }
 
     unparseputc(xw, ANSI_ESC);
@@ -4518,7 +4601,6 @@ window_ops(XtermWidget xw)
     TScreen *screen = &xw->screen;
     XWindowChanges values;
     XWindowAttributes win_attrs;
-    XTextProperty text;
     unsigned value_mask;
 #if OPT_MAXIMIZE
     unsigned root_width;
@@ -4527,156 +4609,252 @@ window_ops(XtermWidget xw)
 
     TRACE(("window_ops %d\n", param[0]));
     switch (param[0]) {
-    case 1:			/* Restore (de-iconify) window */
-	TRACE(("...de-iconify window\n"));
-	XMapWindow(screen->display,
-		   VShellWindow);
+    case ewRestoreWin:		/* Restore (de-iconify) window */
+	if (AllowWindowOps(xw, ewRestoreWin)) {
+	    TRACE(("...de-iconify window\n"));
+	    XMapWindow(screen->display,
+		       VShellWindow);
+	}
 	break;
 
-    case 2:			/* Minimize (iconify) window */
-	TRACE(("...iconify window\n"));
-	XIconifyWindow(screen->display,
-		       VShellWindow,
-		       DefaultScreen(screen->display));
+    case ewMinimizeWin:	/* Minimize (iconify) window */
+	if (AllowWindowOps(xw, ewMinimizeWin)) {
+	    TRACE(("...iconify window\n"));
+	    XIconifyWindow(screen->display,
+			   VShellWindow,
+			   DefaultScreen(screen->display));
+	}
 	break;
 
-    case 3:			/* Move the window to the given position */
-	TRACE(("...move window to %d,%d\n", param[1], param[2]));
-	values.x = param[1];
-	values.y = param[2];
-	value_mask = (CWX | CWY);
-	XReconfigureWMWindow(screen->display,
-			     VShellWindow,
-			     DefaultScreen(screen->display),
-			     value_mask,
-			     &values);
+    case ewSetWinPosition:	/* Move the window to the given position */
+	if (AllowWindowOps(xw, ewSetWinPosition)) {
+	    values.x = zero_if_default(1);
+	    values.y = zero_if_default(2);
+	    TRACE(("...move window to %d,%d\n", values.x, values.y));
+	    value_mask = (CWX | CWY);
+	    XReconfigureWMWindow(screen->display,
+				 VShellWindow,
+				 DefaultScreen(screen->display),
+				 value_mask,
+				 &values);
+	}
 	break;
 
-    case 4:			/* Resize the window to given size in pixels */
-	RequestResize(xw, param[1], param[2], False);
+    case ewSetWinSizePixels:	/* Resize the window to given size in pixels */
+	if (AllowWindowOps(xw, ewSetWinSizePixels)) {
+	    RequestResize(xw, zero_if_default(1), zero_if_default(2), False);
+	}
 	break;
 
-    case 5:			/* Raise the window to the front of the stack */
-	TRACE(("...raise window\n"));
-	XRaiseWindow(screen->display, VShellWindow);
+    case ewRaiseWin:		/* Raise the window to the front of the stack */
+	if (AllowWindowOps(xw, ewRaiseWin)) {
+	    TRACE(("...raise window\n"));
+	    XRaiseWindow(screen->display, VShellWindow);
+	}
 	break;
 
-    case 6:			/* Lower the window to the bottom of the stack */
-	TRACE(("...lower window\n"));
-	XLowerWindow(screen->display, VShellWindow);
+    case ewLowerWin:		/* Lower the window to the bottom of the stack */
+	if (AllowWindowOps(xw, ewLowerWin)) {
+	    TRACE(("...lower window\n"));
+	    XLowerWindow(screen->display, VShellWindow);
+	}
 	break;
 
-    case 7:			/* Refresh the window */
-	TRACE(("...redraw window\n"));
-	Redraw();
+    case ewRefreshWin:		/* Refresh the window */
+	if (AllowWindowOps(xw, ewRefreshWin)) {
+	    TRACE(("...redraw window\n"));
+	    Redraw();
+	}
 	break;
 
-    case 8:			/* Resize the text-area, in characters */
-	RequestResize(xw, param[1], param[2], True);
+    case ewSetWinSizeChars:	/* Resize the text-area, in characters */
+	if (AllowWindowOps(xw, ewSetWinSizeChars)) {
+	    RequestResize(xw, zero_if_default(1), zero_if_default(2), True);
+	}
 	break;
 
 #if OPT_MAXIMIZE
-    case 9:			/* Maximize or restore */
-	RequestMaximize(xw, param[1]);
+    case ewMaximizeWin:	/* Maximize or restore */
+	if (AllowWindowOps(xw, ewMaximizeWin)) {
+	    RequestMaximize(xw, zero_if_default(1));
+	}
 	break;
 #endif
 
-    case 11:			/* Report the window's state */
-	TRACE(("...get window attributes\n"));
-	XGetWindowAttributes(screen->display,
-			     VWindow(screen),
-			     &win_attrs);
-	reply.a_type = ANSI_CSI;
-	reply.a_pintro = 0;
-	reply.a_nparam = 1;
-	reply.a_param[0] = (ParmType) ((win_attrs.map_state == IsViewable)
-				       ? 1
-				       : 2);
-	reply.a_inters = 0;
-	reply.a_final = 't';
-	unparseseq(xw, &reply);
+    case ewGetWinState:	/* Report the window's state */
+	if (AllowWindowOps(xw, ewGetWinState)) {
+	    TRACE(("...get window attributes\n"));
+	    XGetWindowAttributes(screen->display,
+				 VWindow(screen),
+				 &win_attrs);
+	    reply.a_type = ANSI_CSI;
+	    reply.a_pintro = 0;
+	    reply.a_nparam = 1;
+	    reply.a_param[0] = (ParmType) ((win_attrs.map_state == IsViewable)
+					   ? 1
+					   : 2);
+	    reply.a_inters = 0;
+	    reply.a_final = 't';
+	    unparseseq(xw, &reply);
+	}
 	break;
 
-    case 13:			/* Report the window's position */
-	TRACE(("...get window position\n"));
-	XGetWindowAttributes(screen->display,
-			     WMFrameWindow(xw),
-			     &win_attrs);
-	reply.a_type = ANSI_CSI;
-	reply.a_pintro = 0;
-	reply.a_nparam = 3;
-	reply.a_param[0] = 3;
-	reply.a_param[1] = (ParmType) win_attrs.x;
-	reply.a_param[2] = (ParmType) win_attrs.y;
-	reply.a_inters = 0;
-	reply.a_final = 't';
-	unparseseq(xw, &reply);
+    case ewGetWinPosition:	/* Report the window's position */
+	if (AllowWindowOps(xw, ewGetWinPosition)) {
+	    TRACE(("...get window position\n"));
+	    XGetWindowAttributes(screen->display,
+				 WMFrameWindow(xw),
+				 &win_attrs);
+	    reply.a_type = ANSI_CSI;
+	    reply.a_pintro = 0;
+	    reply.a_nparam = 3;
+	    reply.a_param[0] = 3;
+	    reply.a_param[1] = (ParmType) win_attrs.x;
+	    reply.a_param[2] = (ParmType) win_attrs.y;
+	    reply.a_inters = 0;
+	    reply.a_final = 't';
+	    unparseseq(xw, &reply);
+	}
 	break;
 
-    case 14:			/* Report the window's size in pixels */
-	TRACE(("...get window size in pixels\n"));
-	XGetWindowAttributes(screen->display,
-			     VWindow(screen),
-			     &win_attrs);
-	reply.a_type = ANSI_CSI;
-	reply.a_pintro = 0;
-	reply.a_nparam = 3;
-	reply.a_param[0] = 4;
-	/*FIXME: find if dtterm uses
-	 *    win_attrs.height or Height
-	 *      win_attrs.width  or Width
-	 */
-	reply.a_param[1] = (ParmType) Height(screen);
-	reply.a_param[2] = (ParmType) Width(screen);
-	reply.a_inters = 0;
-	reply.a_final = 't';
-	unparseseq(xw, &reply);
+    case ewGetWinSizePixels:	/* Report the window's size in pixels */
+	if (AllowWindowOps(xw, ewGetWinSizePixels)) {
+	    TRACE(("...get window size in pixels\n"));
+	    XGetWindowAttributes(screen->display,
+				 VWindow(screen),
+				 &win_attrs);
+	    reply.a_type = ANSI_CSI;
+	    reply.a_pintro = 0;
+	    reply.a_nparam = 3;
+	    reply.a_param[0] = 4;
+	    /*FIXME: find if dtterm uses
+	     *    win_attrs.height or Height
+	     *      win_attrs.width  or Width
+	     */
+	    reply.a_param[1] = (ParmType) Height(screen);
+	    reply.a_param[2] = (ParmType) Width(screen);
+	    reply.a_inters = 0;
+	    reply.a_final = 't';
+	    unparseseq(xw, &reply);
+	}
 	break;
 
-    case 18:			/* Report the text's size in characters */
-	TRACE(("...get window size in characters\n"));
-	reply.a_type = ANSI_CSI;
-	reply.a_pintro = 0;
-	reply.a_nparam = 3;
-	reply.a_param[0] = 8;
-	reply.a_param[1] = (ParmType) MaxRows(screen);
-	reply.a_param[2] = (ParmType) MaxCols(screen);
-	reply.a_inters = 0;
-	reply.a_final = 't';
-	unparseseq(xw, &reply);
+    case ewGetWinSizeChars:	/* Report the text's size in characters */
+	if (AllowWindowOps(xw, ewGetWinSizeChars)) {
+	    TRACE(("...get window size in characters\n"));
+	    reply.a_type = ANSI_CSI;
+	    reply.a_pintro = 0;
+	    reply.a_nparam = 3;
+	    reply.a_param[0] = 8;
+	    reply.a_param[1] = (ParmType) MaxRows(screen);
+	    reply.a_param[2] = (ParmType) MaxCols(screen);
+	    reply.a_inters = 0;
+	    reply.a_final = 't';
+	    unparseseq(xw, &reply);
+	}
 	break;
 
 #if OPT_MAXIMIZE
-    case 19:			/* Report the screen's size, in characters */
-	if (!QueryMaximize(xw, &root_height, &root_width)) {
-	    root_height = 0;
-	    root_width = 0;
+    case ewGetScreenSizeChars:	/* Report the screen's size, in characters */
+	if (AllowWindowOps(xw, ewGetScreenSizeChars)) {
+	    TRACE(("...get screen size in characters\n"));
+	    if (!QueryMaximize(xw, &root_height, &root_width)) {
+		root_height = 0;
+		root_width = 0;
+	    }
+	    reply.a_type = ANSI_CSI;
+	    reply.a_pintro = 0;
+	    reply.a_nparam = 3;
+	    reply.a_param[0] = 9;
+	    reply.a_param[1] = (ParmType) (root_height / FontHeight(screen));
+	    reply.a_param[2] = (ParmType) (root_width / FontWidth(screen));
+	    reply.a_inters = 0;
+	    reply.a_final = 't';
+	    unparseseq(xw, &reply);
 	}
-	reply.a_type = ANSI_CSI;
-	reply.a_pintro = 0;
-	reply.a_nparam = 3;
-	reply.a_param[0] = 9;
-	reply.a_param[1] = (ParmType) (root_height / FontHeight(screen));
-	reply.a_param[2] = (ParmType) (root_width / FontWidth(screen));
-	reply.a_inters = 0;
-	reply.a_final = 't';
-	unparseseq(xw, &reply);
 	break;
 #endif
 
-    case 20:			/* Report the icon's label */
-	report_win_label(xw, 'L', &text,
-			 XGetWMIconName(screen->display, VShellWindow, &text));
+    case ewGetIconTitle:	/* Report the icon's label */
+	if (AllowWindowOps(xw, ewGetIconTitle)) {
+	    TRACE(("...get icon's label\n"));
+	    report_win_label(xw, 'L', get_icon_label(xw));
+	}
 	break;
 
-    case 21:			/* Report the window's title */
-	report_win_label(xw, 'l', &text,
-			 XGetWMName(screen->display, VShellWindow, &text));
+    case ewGetWinTitle:	/* Report the window's title */
+	if (AllowWindowOps(xw, ewGetWinTitle)) {
+	    TRACE(("...get window's label\n"));
+	    report_win_label(xw, 'l', get_window_label(xw));
+	}
+	break;
+
+    case ewPushTitle:		/* save the window's title(s) on stack */
+	if (AllowWindowOps(xw, ewPushTitle)) {
+	    SaveTitle *last = screen->save_title;
+	    SaveTitle *item = TypeCalloc(SaveTitle);
+
+	    TRACE(("...push title onto stack\n"));
+	    if (item != 0) {
+		switch (zero_if_default(1)) {
+		case 0:
+		    item->iconName = get_icon_label(xw);
+		    item->windowName = get_window_label(xw);
+		    break;
+		case 1:
+		    item->iconName = get_icon_label(xw);
+		    break;
+		case 2:
+		    item->windowName = get_window_label(xw);
+		    break;
+		}
+		item->next = last;
+		if (item->iconName == 0) {
+		    item->iconName = ((last == 0)
+				      ? get_icon_label(xw)
+				      : x_strdup(last->iconName));
+		}
+		if (item->windowName == 0) {
+		    item->windowName = ((last == 0)
+					? get_window_label(xw)
+					: x_strdup(last->windowName));
+		}
+		screen->save_title = item;
+	    }
+	}
+	break;
+
+    case ewPopTitle:		/* restore the window's title(s) from stack */
+	if (AllowWindowOps(xw, ewPopTitle)) {
+	    SaveTitle *item = screen->save_title;
+
+	    TRACE(("...pop title off stack\n"));
+	    if (item != 0) {
+		switch (zero_if_default(1)) {
+		case 0:
+		    ChangeIconName(xw, item->iconName);
+		    ChangeTitle(xw, item->windowName);
+		    break;
+		case 1:
+		    ChangeIconName(xw, item->iconName);
+		    break;
+		case 2:
+		    ChangeTitle(xw, item->windowName);
+		    break;
+		}
+		screen->save_title = item->next;
+		free(item->iconName);
+		free(item->windowName);
+		free(item);
+	    }
+	}
 	break;
 
     default:			/* DECSLPP (24, 25, 36, 48, 72, 144) */
-	if (param[0] >= 24)
-	    RequestResize(xw, param[0], -1, True);
+	if (AllowWindowOps(xw, ewSetWinLines)) {
+	    if (param[0] >= 24)
+		RequestResize(xw, param[0], -1, True);
+	}
 	break;
     }
 }
@@ -5041,8 +5219,8 @@ RequestResize(XtermWidget xw, int rows, int cols, Bool text)
 
     TRACE(("RequestResize(rows=%d, cols=%d, text=%d)\n", rows, cols, text));
 
-    if ((askedWidth = (Dimension) cols) < cols
-	|| (askedHeight = (Dimension) rows) < rows)
+    if ((int) (askedWidth = (Dimension) cols) < cols
+	|| (int) (askedHeight = (Dimension) rows) < rows)
 	return;
 
     if (askedHeight == 0
@@ -5087,11 +5265,11 @@ RequestResize(XtermWidget xw, int rows, int cols, Bool text)
     if (xw->misc.limit_resize > 0) {
 	Dimension high = (Dimension) (xw->misc.limit_resize * attrs.height);
 	Dimension wide = (Dimension) (xw->misc.limit_resize * attrs.width);
-	if (high < attrs.height)
+	if ((int) high < attrs.height)
 	    high = (Dimension) attrs.height;
 	if (askedHeight > high)
 	    askedHeight = high;
-	if (wide < attrs.width)
+	if ((int) wide < attrs.width)
 	    wide = (Dimension) attrs.width;
 	if (askedWidth > wide)
 	    askedWidth = wide;
@@ -5410,6 +5588,87 @@ ParseOnClicks(XtermWidget wnew, XtermWidget wreq, Cardinal item)
     }
 }
 
+/*
+ * Parse a comma-separated list, returning a string which the caller must
+ * free, and updating the source pointer.
+ */
+static char *
+ParseList(const char **source)
+{
+    const char *base = *source;
+    const char *next;
+    unsigned size;
+    char *value = 0;
+
+    /* ignore empty values */
+    while (*base == ',')
+	++base;
+    if (*base != '\0') {
+	next = base;
+	while (*next != '\0' && *next != ',')
+	    ++next;
+	size = (unsigned) (1 + next - base);
+	value = malloc(size);
+	if (value != 0) {
+	    memcpy(value, base, size);
+	    value[size - 1] = '\0';
+	}
+	*source = next;
+    } else {
+	*source = base;
+    }
+    return x_strtrim(value);
+}
+
+static void
+set_flags_from_list(char *target,
+		    const char *source,
+		    FlagList * list,
+		    Cardinal limit)
+{
+    Cardinal n;
+    int value;
+
+    while (*source != '\0') {
+	char *next = ParseList(&source);
+	Boolean found = False;
+
+	if (next == 0)
+	    break;
+	if (isdigit(CharOf(*next))) {
+	    char *temp;
+
+	    value = (int) strtol(next, &temp, 0);
+	    if (temp != 0 && *temp != '\0') {
+		fprintf(stderr, "Expected a number: %s\n", next);
+	    } else {
+		for (n = 0; n < limit; ++n) {
+		    if (list[n].code == value) {
+			target[value] = 1;
+			found = True;
+			break;
+		    }
+		}
+	    }
+	} else {
+	    for (n = 0; n < limit; ++n) {
+		if (!x_strcasecmp(next, list[n].name)) {
+		    value = list[n].code;
+		    target[value] = 1;
+		    found = True;
+		    break;
+		}
+	    }
+	}
+	if (!found) {
+	    fprintf(stderr, "Unrecognized keyword: %s\n", next);
+	} else {
+	    TRACE(("...found %s (%d)\n", next, value));
+	}
+	free(next);
+    }
+}
+
 /* ARGSUSED */
 static void
 VTInitialize(Widget wrequest,
@@ -5423,6 +5682,38 @@ VTInitialize(Widget wrequest,
 #define DftFg(name) isDefaultForeground(Kolor(name))
 #define DftBg(name) isDefaultBackground(Kolor(name))
 
+#define DATA(name) { #name, ew##name }
+    static FlagList tblWindowOps[] =
+    {
+	DATA(RestoreWin)
+	,DATA(MinimizeWin)
+	,DATA(SetWinPosition)
+	,DATA(SetWinSizePixels)
+	,DATA(RaiseWin)
+	,DATA(LowerWin)
+	,DATA(RefreshWin)
+	,DATA(SetWinSizeChars)
+#if OPT_MAXIMIZE
+	,DATA(MaximizeWin)
+#endif
+	,DATA(GetWinState)
+	,DATA(GetWinPosition)
+	,DATA(GetWinSizePixels)
+	,DATA(GetWinSizeChars)
+#if OPT_MAXIMIZE
+	,DATA(GetScreenSizeChars)
+#endif
+	,DATA(GetIconTitle)
+	,DATA(GetWinTitle)
+	,DATA(PushTitle)
+	,DATA(PopTitle)
+	,DATA(SetWinLines)
+	,DATA(SetXprop)
+	,DATA(GetSelection)
+	,DATA(SetSelection)
+    };
+#undef DATA
+
     XtermWidget request = (XtermWidget) wrequest;
     XtermWidget wnew = (XtermWidget) new_arg;
     Widget my_parent = SHELL_OF(wnew);
@@ -5635,6 +5926,13 @@ VTInitialize(Widget wrequest,
     init_Bres(screen.allowTitleOp0);
     init_Bres(screen.allowWindowOp0);
 
+    init_Sres(screen.disallowedWinOps);
+
+    set_flags_from_list(wnew->screen.disallow_win_ops,


Reply to: