You are not logged in.

#1 2012-07-28 20:41:48

rlblaster
Member
Registered: 2007-12-28
Posts: 12

My xterm modifications

I had a little free time so I thought I try xterm as my new terminal. But it turns out it was missing some features I like. I've hacked some of these into xterm and thought I share my patches. Please note I'm not familiar with xterm sources so these hacks might be ugly as hell. And as I won't have much free time from now on I won't be sending these patches upstream. If someone has the time to make proper patches from these and get it integrated into xterm, I'd appreciate. :)

The patches can be applied in the order as presented, I haven't tried any other order.

1) Resize problem

If I have several long lines and resize xterm so they don't fit into the window and then when I resize them back I lose those characters! That's pretty annoying so I've made this patch which fixes this at the cost of some extra memory:

--- xterm-281/linedata.c	2011-09-11 16:59:39.000000000 +0200
+++ xterm-281-patched/linedata.c	2012-07-24 03:12:48.342496137 +0200
@@ -62,11 +62,11 @@ getLineData(TScreen * screen, int row)
     }
     if (row >= 0 && row <= max_row) {
 	result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row);
 	if (result != 0) {
 #if 1				/* FIXME - these should be done in setupLineData, etc. */
-	    result->lineSize = (Dimension) MaxCols(screen);
+	    //result->lineSize = (Dimension) MaxCols(screen);
 #if OPT_WIDE_CHARS
 	    if (screen->wide_chars) {
 		result->combSize = (Char) screen->max_combining;
 	    } else {
 		result->combSize = 0;
--- xterm-281/screen.c	2012-05-08 10:36:43.000000000 +0200
+++ xterm-281-patched/screen.c	2012-07-24 03:12:38.542549023 +0200
@@ -428,10 +428,11 @@ Reallocate(XtermWidget xw,
 	   Char ** sbufaddr,
 	   unsigned nrow,
 	   unsigned ncol,
 	   unsigned oldrow)
 {
+    static unsigned biggest_ncol = 0;
     TScreen *screen = TScreenOf(xw);
     ScrnBuf oldBufHead;
     ScrnBuf newBufHead;
     Char *newBufData;
     unsigned minrows;
@@ -440,10 +441,15 @@ Reallocate(XtermWidget xw,
 
     if (sbuf == NULL || *sbuf == NULL) {
 	return 0;
     }
 
+    if (ncol > biggest_ncol)
+        biggest_ncol = ncol;
+    else
+        ncol = biggest_ncol;
+
     oldBufData = *sbufaddr;
 
     TRACE(("Reallocate %dx%d -> %dx%d\n", oldrow, MaxCols(screen), nrow, ncol));
 
     /*

2) urxvt.scrollWithBuffer

This patch tries to show the same lines when you are scrolled back (same as scrollWithBuffer in urxvt). Currently xterm just keeps scrolling downwards when an application is outputting new lines. I think you can already do this via scroll lock but as my laptop doesn't have one, so I couldn't use that.

--- xterm-281/util.c	2012-06-03 20:45:04.000000000 +0200
+++ xterm-281-patched/util.c	2012-07-24 04:05:42.368634038 +0200
@@ -565,11 +565,12 @@ xtermScroll(XtermWidget xw, int amount)
     i = screen->bot_marg - screen->top_marg + 1;
     if (amount > i)
 	amount = i;
 
 #if OPT_SCROLL_LOCK
-    if (screen->allowScrollLock && screen->scroll_lock) {
+    //if (screen->allowScrollLock && screen->scroll_lock) {
+    if (screen->topline != 0) {
 	refreshheight = 0;
 	screen->scroll_amt = 0;
 	screen->refresh_amt = 0;
 	if (--(screen->topline) < -screen->savelines) {
 	    screen->topline = -screen->savelines;

3) Clear shouldn't erase lines

Type "seq 1000 && clear". Now if you scroll back you can see that xterm erased some lines. I don't like this and I've seen that VTE based terminals don't do this and got used to this feature. This patch might break some applications, so don't just blindly apply it! I've already done a similar patch to urxvt which I shared here: https://bbs.archlinux.org/viewtopic.php?id=129302

--- xterm-281/charproc.c	2012-06-11 10:57:49.000000000 +0200
+++ xterm-281-patched/charproc.c	2012-07-24 04:03:53.815888271 +0200
@@ -1948,10 +1948,22 @@ doparsing(XtermWidget xw, unsigned c, st
 	    ResetState(sp);
 	    break;
 
 	case CASE_CUP:
 	    TRACE(("CASE_CUP - cursor position\n"));
+	    if (VTbuffer->next - 3 >= VTbuffer->buffer && VTbuffer->next+3 < VTbuffer->last) {
+	    	    if (memcmp(VTbuffer->next-3, "\e[H\e[2J", 7) == 0) {
+			    // Add some extra lines to avoid deleting the lines
+			    // already on screen. If we are already at the top,
+			    // add an extra screen height of lines.
+			    int extra_lines = MaxRows(screen) - 1;
+			    if (screen->cur_row == 0)
+					extra_lines += MaxRows(screen);
+			    xtermIndex(xw, extra_lines);
+			    CarriageReturn(xw);
+		    }
+	    }
 	    if_OPT_XMC_GLITCH(screen, {
 		Jump_XMC(xw);
 	    });
 	    if ((row = param[0]) < 1)
 		row = 1;

4) Flicker-free xterm

I think I'm the only one suffering this problem, because I couldn't find other annoyed people on the internet: xterm flickers when I'm quickly scrolling back or having long outputs. I think I have this problem because I have a slow CPU and the drivers are not at its best settings. Firstly, I added double buffering to xterm to avoid tearing.

Also some applications (like vim) are behaving interestingly. When I press page-up/page-down this needs a full redraw but vim does this in a rather ugly way. Here's the strace output when I press 'gg' (jump to the beginning):

23466 16:55:50.918822 read(0, "g", 4096) = 1
23466 16:55:50.918974 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:50.919149 write(1, "\33[?25l\33[66;212Hg\33[32;5H\33[?12l\33[?"..., 35) = 35
23466 16:55:50.919247 ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0
23466 16:55:50.919318 select(5, [0 4], NULL, [0], {4, 0}) = 1 (in [0], left {3, 795529})
23466 16:55:51.123955 select(5, [0 4], NULL, [0], NULL) = 1 (in [0])
23466 16:55:51.124088 read(0, "g", 4096) = 1
23466 16:55:51.124230 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.124357 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.124457 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.124549 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.124639 write(1, "\33[?25l\33[66;212H \33[32;5H", 23) = 23
23466 16:55:51.124724 ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0
23466 16:55:51.124791 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.124913 write(1, "\33[66;212Hgg\33[32;5H", 18) = 18
23466 16:55:51.125061 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.126027 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.126101 write(1, "\33[66;212H  \33[1;5H", 17) = 17
23466 16:55:51.126173 ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0
23466 16:55:51.126234 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.127906 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.129483 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.130171 write(1, "\33[27m\33[m\33[H\33[2J\33[1;1H\33[93m  1 \33["..., 2042) = 2042
23466 16:55:51.131177 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.132774 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.133807 write(1, "\33[93m 29 \33[m[    25.564] (==) Au"..., 2047) = 2047
23466 16:55:51.134378 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.135405 select(5, [0 4], NULL, [0], {0, 0}) = 0 (Timeout)
23466 16:55:51.135473 write(1, "d. This was enabled by default a"..., 842) = 842

As you can see when I press the second g it begins to draw to the console at 16:55:51.130171 (this draws the half the screen) and finishes at 16:55:51.135473. This means that for 5 ms xterm draws a blank screen for the half of the screen. I perceive this as "flickering". So the second change in this patch to avoid this problem is to make xterm wait an extra 25 msec for extra input whenever it detects some input. I barely notice this input lag (and some game consoles have even bigger input lag!).

Also this patch limits xterm refresh rate to 40 FPS. This helps me because for some reason font rendering is slow on my machine and X uses way too much CPU for it. This reduces the load on the CPU when xterm is rendering lots of output.

My xterm also flickers at resizing but I don't use that feature often, so I didn't tried to fix that.

This is a quite long patch because of the double buffering modifications:

--- xterm-281/charproc.c	2012-07-28 21:28:50.465443124 +0200
+++ xterm-281-patched/charproc.c	2012-07-28 20:09:53.684437767 +0200
@@ -100,10 +100,12 @@
 #include <X11/XawPlus/XawImP.h>
 #endif
 
 #endif
 
+#include <X11/extensions/Xdbe.h>
+
 #if OPT_WIDE_CHARS
 #include <wcwidth.h>
 #include <precompose.h>
 #ifdef HAVE_LANGINFO_CODESET
 #include <langinfo.h>
@@ -3884,10 +3886,11 @@ in_put(XtermWidget xw)
 
     TScreen *screen = TScreenOf(xw);
     int i, time_select;
     int size;
     int update = VTbuffer->update;
+    int should_wait = 1;
 
     static struct timeval select_timeout;
 
 #if OPT_BLINK_CURS
     /*
@@ -3915,33 +3918,23 @@ in_put(XtermWidget xw)
 		   BUF_SIZE));
 	    if ((VTbuffer->last - VTbuffer->buffer) > BUF_SIZE) {
 		FD_CLR(screen->respond, &select_mask);
 		break;
 	    }
-#if defined(HAVE_SCHED_YIELD)
-	    /*
-	     * If we've read a full (small/fragment) buffer, let the operating
-	     * system have a turn, and we'll resume reading until we've either
-	     * read only a fragment of the buffer, or we've filled the large
-	     * buffer (see above).  Doing this helps keep up with large bursts
-	     * of output.
-	     */
-	    if (size == FRG_SIZE) {
-		select_timeout.tv_sec = 0;
-		i = Select(max_plus1, &select_mask, &write_mask, 0,
-			   &select_timeout);
-		if (i > 0) {
-		    sched_yield();
-		} else
+	    if (should_wait) {
+	    	    // wait 25 msec for potential extra data (avoids some bogus flickering)
+	    	    // that's only 40 FPS but hey, it's still lower than the input lag on some consoles! :)
+	    	    usleep(25000);
+	    	    should_wait = 0;
+	    }
+	    select_timeout.tv_sec = 0;
+	    i = Select(max_plus1, &select_mask, &write_mask, 0,
+			    &select_timeout);
+	    if (i > 0)
+		    continue;
+	    else
 		    break;
-	    } else {
-		break;
-	    }
-#else
-	    (void) size;	/* unused in this branch */
-	    break;
-#endif
 	}
 	/* update the screen */
 	if (screen->scroll_amt)
 	    FlushScroll(xw);
 	if (screen->cursor_set && CursorMoved(screen)) {
@@ -4002,10 +3995,18 @@ in_put(XtermWidget xw)
 		FD_SET(ice_fd, &select_mask);
 #endif
 	}
 	if (need_cleanup)
 	    Cleanup(0);
+	if (screen->needSwap) {
+		XdbeSwapInfo swap;
+		swap.swap_window = VWindow(screen);
+		swap.swap_action = XdbeCopied;
+		XdbeSwapBuffers(XtDisplay(term), &swap, 1);
+		XFlush(XtDisplay(xw));
+		screen->needSwap = 0;
+	}
 	i = Select(max_plus1, &select_mask, &write_mask, 0,
 		   (time_select ? &select_timeout : 0));
 	if (i < 0) {
 	    if (errno != EINTR)
 		SysError(ERROR_SELECT);
@@ -6051,17 +6052,16 @@ SwitchBufs(XtermWidget xw, int toBuf)
 
     if ((top = INX2ROW(screen, 0)) < rows) {
 	if (screen->scroll_amt) {
 	    FlushScroll(xw);
 	}
-	XClearArea(screen->display,
-		   VWindow(screen),
-		   (int) OriginX(screen),
-		   (int) top * FontHeight(screen) + screen->border,
-		   (unsigned) Width(screen),
-		   (unsigned) ((rows - top) * FontHeight(screen)),
-		   False);
+	XFillRectangle(screen->display, VDrawable(screen),
+			ReverseGC(xw, screen),
+			(int) OriginX(screen),
+			(int) top * FontHeight(screen) + screen->border,
+			(unsigned) Width(screen),
+			(unsigned) ((rows - top) * FontHeight(screen)));
     }
     ScrnUpdate(xw, 0, 0, rows, MaxCols(screen), False);
 }
 
 Bool
@@ -7957,10 +7957,28 @@ VTRealize(Widget w,
 		      xw->core.x, xw->core.y,
 		      xw->core.width, xw->core.height, BorderWidth(xw),
 		      (int) xw->core.depth,
 		      InputOutput, CopyFromParent,
 		      *valuemask | CWBitGravity, values);
+    screen->fullVwin.drawable = screen->fullVwin.window;
+
+	{
+		Window win = screen->fullVwin.window;
+		Drawable d;
+		int major, minor;
+		if (!XdbeQueryExtension(XtDisplay(xw), &major, &minor)) {
+			fprintf(stderr, "XdbeQueryExtension returned zero!\n");
+			exit(3);
+		}
+		d = XdbeAllocateBackBufferName(XtDisplay(xw), win, XdbeCopied);
+		if (d == None) {
+			fprintf(stderr, "Couldn't allocate a back buffer!\n");
+			exit(3);
+		}
+		screen->fullVwin.drawable = d;
+		screen->needSwap = 1;
+	}
     screen->event_mask = values->event_mask;
 
 #ifndef NO_ACTIVE_ICON
     /*
      * Normally, the font-number for icon fonts does not correspond with any of
@@ -8021,10 +8039,11 @@ VTRealize(Widget w,
 			  xw->misc.icon_border_width,
 			  (int) xw->core.depth,
 			  InputOutput, CopyFromParent,
 			  *valuemask | CWBitGravity | CWBorderPixel,
 			  values);
+	screen->iconVwin.drawable = screen->iconVwin.window;
 	XtVaSetValues(shell,
 		      XtNiconWindow, screen->iconVwin.window,
 		      (XtPointer) 0);
 	XtRegisterDrawable(XtDisplay(xw), screen->iconVwin.window, w);
 
@@ -8819,11 +8838,11 @@ ShowCursor(void)
 	    /*
 	     * Finally, draw the underline.
 	     */
 	    screen->box->x = (short) x;
 	    screen->box->y = (short) (y + FontHeight(screen) - 2);
-	    XDrawLines(screen->display, VWindow(screen), outlineGC,
+	    XDrawLines(screen->display, VDrawable(screen), outlineGC,
 		       screen->box, NBOX, CoordModePrevious);
 	} else {
 
 	    drawXtermText(xw, flags & DRAWX_MASK,
 			  currentGC, x, y,
@@ -8845,11 +8864,11 @@ ShowCursor(void)
 #endif
 
 	    if (!filled) {
 		screen->box->x = (short) x;
 		screen->box->y = (short) y;
-		XDrawLines(screen->display, VWindow(screen), outlineGC,
+		XDrawLines(screen->display, VDrawable(screen), outlineGC,
 			   screen->box, NBOX, CoordModePrevious);
 	    }
 	}
     }
     screen->cursor_state = ON;
--- xterm-281/fontutils.c	2011-12-27 11:20:50.000000000 +0100
+++ xterm-281-patched/fontutils.c	2012-07-26 17:14:38.418959004 +0200
@@ -2480,11 +2480,11 @@ xtermDrawBoxChar(XtermWidget xw,
 	setCgsBack(xw, cgsWin, cgsId, getCgsBack(xw, cgsWin, gc));
     }
     gc2 = getCgsGC(xw, cgsWin, cgsId);
 
     if (!(flags & NOBACKGROUND)) {
-	XFillRectangle(screen->display, VWindow(screen), gc2, x, y,
+	XFillRectangle(screen->display, VDrawable(screen), gc2, x, y,
 		       font_width,
 		       font_height);
     }
 
     setCgsFont(xw, cgsWin, cgsId, getCgsFont(xw, cgsWin, gc));
@@ -2529,11 +2529,11 @@ xtermDrawBoxChar(XtermWidget xw,
 	    points[n].x = (short) (points[n].x + x);
 	    points[n].y = (short) (points[n].y + y);
 	}
 
 	XFillPolygon(screen->display,
-		     VWindow(screen), gc2,
+		     VDrawable(screen), gc2,
 		     points, npoints,
 		     Convex, CoordModeOrigin);
     } else if (ch == 7) {	/* degrees */
 	unsigned width = (BOX_WIDE / 3);
 	int x_coord = MID_WIDE - (int) (width / 2);
@@ -2542,11 +2542,11 @@ xtermDrawBoxChar(XtermWidget xw,
 	SCALE_X(x_coord);
 	SCALE_Y(y_coord);
 	width = (unsigned) SCALED_X(width);
 
 	XDrawArc(screen->display,
-		 VWindow(screen), gc2,
+		 VDrawable(screen), gc2,
 		 x + x_coord, y + y_coord, width, width,
 		 0,
 		 360 * 64);
     } else if (ch == 0x1f) {	/* bullet */
 	unsigned width = 7 * BOX_WIDE / 10;
@@ -2556,11 +2556,11 @@ xtermDrawBoxChar(XtermWidget xw,
 	SCALE_X(x_coord);
 	SCALE_Y(y_coord);
 	width = (unsigned) SCALED_X(width);
 
 	XDrawArc(screen->display,
-		 VWindow(screen), gc2,
+		 VDrawable(screen), gc2,
 		 x + x_coord, y + y_coord, width, width,
 		 0,
 		 360 * 64);
     } else if (ch < (sizeof(lines) / sizeof(lines[0]))
 	       && (p = lines[ch]) != 0) {
@@ -2572,19 +2572,19 @@ xtermDrawBoxChar(XtermWidget xw,
 		SCALE_X(coord[0]);
 		SCALE_Y(coord[1]);
 		SCALE_X(coord[2]);
 		SCALE_Y(coord[3]);
 		XDrawLine(screen->display,
-			  VWindow(screen), gc2,
+			  VDrawable(screen), gc2,
 			  x + coord[0], y + coord[1],
 			  x + coord[2], y + coord[3]);
 		n = 0;
 	    }
 	}
     } else if (screen->force_all_chars) {
 	/* bounding rectangle, for debugging */
-	XDrawRectangle(screen->display, VWindow(screen), gc2, x, y,
+	XDrawRectangle(screen->display, VDrawable(screen), gc2, x, y,
 		       font_width - 1,
 		       font_height - 1);
     }
 }
 
--- xterm-281/screen.c	2012-07-28 21:28:47.512125752 +0200
+++ xterm-281-patched/screen.c	2012-07-28 21:21:32.311150104 +0200
@@ -1347,11 +1347,11 @@ ShowWrapMarks(XtermWidget xw, int row, L
     int y = row * FontHeight(screen) + screen->border;
     int x = LineCursorX(screen, ld, screen->max_col + 1);
 
     TRACE2(("ShowWrapMarks %d:%s\n", row, BtoS(set)));
 
-    XFillRectangle(screen->display, VWindow(screen),
+    XFillRectangle(screen->display, VDrawable(screen),
 		   getCgsGC(xw, currentWin, cgsId),
 		   x, y,
 		   (unsigned) screen->border,
 		   (unsigned) FontHeight(screen));
 }
@@ -1809,11 +1809,11 @@ ScreenResize(XtermWidget xw,
     int border = 2 * screen->border;
     int move_down_by = 0;
 #ifdef TTYSIZE_STRUCT
     TTYSIZE_STRUCT ts;
 #endif
-    Window tw = VWindow(screen);
+    Window tw = VDrawable(screen);
 
     TRACE(("ScreenResize %dx%d border %d font %dx%d\n",
 	   height, width, border,
 	   FontHeight(screen), FontWidth(screen)));
 
@@ -1822,20 +1822,20 @@ ScreenResize(XtermWidget xw,
 
     if (screen->is_running) {
 	/* clear the right and bottom internal border because of NorthWest
 	   gravity might have left junk on the right and bottom edges */
 	if (width >= (int) FullWidth(screen)) {
-	    XClearArea(screen->display, tw,
-		       FullWidth(screen), 0,	/* right edge */
-		       0, (unsigned) height,	/* from top to bottom */
-		       False);
+	    XFillRectangle(screen->display, VDrawable(screen),
+			    ReverseGC(xw, screen),
+			    FullWidth(screen), 0,
+			    width - FullWidth(screen), height);
 	}
 	if (height >= (int) FullHeight(screen)) {
-	    XClearArea(screen->display, tw,
-		       0, FullHeight(screen),	/* bottom */
-		       (unsigned) width, 0,	/* all across the bottom */
-		       False);
+	    XFillRectangle(screen->display, VDrawable(screen),
+			    ReverseGC(xw, screen),
+			    0, FullHeight(screen),
+			    width, height - FullHeight(screen));
 	}
     }
 
     TRACE(("...computing rows/cols: %.2f %.2f\n",
 	   (double) (height - border) / FontHeight(screen),
--- xterm-281/scrollbar.c	2011-09-03 14:13:42.000000000 +0200
+++ xterm-281-patched/scrollbar.c	2012-07-28 16:19:36.319292838 +0200
@@ -398,18 +398,16 @@ WindowScroll(XtermWidget xw, int top, Bo
 	    scrolling_copy_area(xw, scrolltop, scrollheight, -i);
 	    screen->topline = top;
 
 	    ScrollSelection(screen, i, True);
 
-	    XClearArea(
-			  screen->display,
-			  VWindow(screen),
-			  OriginX(screen),
-			  OriginY(screen) + refreshtop * FontHeight(screen),
-			  (unsigned) Width(screen),
-			  (unsigned) (lines * FontHeight(screen)),
-			  False);
+	    XFillRectangle(screen->display, VDrawable(screen),
+			    ReverseGC(xw, screen),
+			    OriginX(screen),
+			    OriginY(screen) + refreshtop * FontHeight(screen),
+			    (unsigned) Width(screen),
+			    (unsigned) (lines * FontHeight(screen)));
 	    ScrnRefresh(xw, refreshtop, 0, lines, MaxCols(screen), False);
 
 #if OPT_BLINK_CURS || OPT_BLINK_TEXT
 	    RestartBlinking(screen);
 #endif
--- xterm-281/util.c	2012-07-28 21:28:46.215466329 +0200
+++ xterm-281-patched/util.c	2012-07-28 16:19:33.545974545 +0200
@@ -1861,10 +1861,11 @@ do_erase_display(XtermWidget xw, int par
 }
 
 static void
 CopyWait(XtermWidget xw)
 {
+#if 0
     TScreen *screen = TScreenOf(xw);
     XEvent reply;
     XEvent *rep = &reply;
 
     for (;;) {
@@ -1895,10 +1896,11 @@ CopyWait(XtermWidget xw)
 		screen->incopy = -1;
 	    }
 	    break;
 	}
     }
+#endif
 }
 
 /*
  * used by vertical_copy_area and and horizontal_copy_area
  */
@@ -1927,11 +1929,11 @@ copy_area(XtermWidget xw,
 	screen->copy_height = height;
 	screen->copy_dest_x = dest_x;
 	screen->copy_dest_y = dest_y;
 
 	XCopyArea(screen->display,
-		  VWindow(screen), VWindow(screen),
+		  VDrawable(screen), VDrawable(screen),
 		  NormalGC(xw, screen),
 		  src_x, src_y, width, height, dest_x, dest_y);
     }
 }
 
@@ -2108,15 +2110,16 @@ handle_translated_exposure(XtermWidget x
     if ((x0 < 0 ||
 	 y0 < 0 ||
 	 x1 > Width(screen) ||
 	 y1 > Height(screen))) {
 	set_background(xw, -1);
-	XClearArea(screen->display, VWindow(screen),
-		   rect_x,
-		   rect_y,
-		   (unsigned) rect_width,
-		   (unsigned) rect_height, False);
+	XFillRectangle(screen->display, VDrawable(screen),
+			ReverseGC(xw, screen),
+			rect_x,
+			rect_y,
+			(unsigned) rect_width,
+			(unsigned) rect_height);
     }
     toprow = y0 / FontHeight(screen);
     if (toprow < 0)
 	toprow = 0;
 
@@ -2293,11 +2296,14 @@ void
 xtermClear(XtermWidget xw)
 {
     TScreen *screen = TScreenOf(xw);
 
     TRACE(("xtermClear\n"));
-    XClearWindow(screen->display, VWindow(screen));
+    XFillRectangle(screen->display, VDrawable(screen),
+		    ReverseGC(xw, screen),
+		    0, 0,
+		    FullWidth(screen), FullHeight(screen));
 }
 
 void
 xtermRepaint(XtermWidget xw)
 {
@@ -2885,11 +2891,11 @@ xtermFillCells(XtermWidget xw,
 
 	if (dstId != gcMAX) {
 	    setCgsFore(xw, currentWin, dstId, bg);
 	    setCgsBack(xw, currentWin, dstId, fg);
 
-	    XFillRectangle(screen->display, VWindow(screen),
+	    XFillRectangle(screen->display, VDrawable(screen),
 			   getCgsGC(xw, currentWin, dstId),
 			   x, y,
 			   len * (Cardinal) FontWidth(screen),
 			   (unsigned) FontHeight(screen));
 	}
@@ -2906,11 +2912,11 @@ xtermSetClipRectangles(Display * dpy,
 		       Cardinal nr,
 		       int order)
 {
 #if 0
     TScreen *screen = TScreenOf(term);
-    Drawable draw = VWindow(screen);
+    Drawable draw = VDrawable(screen);
 
     XSetClipMask(dpy, gc, None);
     XDrawRectangle(screen->display, draw, gc,
 		   x + rp->x - 1,
 		   y + rp->y - 1,
@@ -3165,11 +3171,11 @@ drawXtermText(XtermWidget xw,
 	int fontnum = screen->menu_font_number;
 	int ncells;
 
 	if (!screen->renderDraw) {
 	    int scr;
-	    Drawable draw = VWindow(screen);
+	    Drawable draw = VDrawable(screen);
 	    Visual *visual;
 
 	    scr = DefaultScreen(dpy);
 	    visual = DefaultVisual(dpy, scr);
 	    screen->renderDraw = XftDrawCreate(dpy, draw, visual,
@@ -3340,11 +3346,11 @@ drawXtermText(XtermWidget xw,
 #endif /* OPT_BOX_CHARS */
 
 	if ((flags & UNDERLINE) && screen->underline && !did_ul) {
 	    if (FontDescent(screen) > 1)
 		y++;
-	    XDrawLine(screen->display, VWindow(screen), gc,
+	    XDrawLine(screen->display, VDrawable(screen), gc,
 		      x, y,
 		      x + (int) underline_len * FontWidth(screen) - 1,
 		      y);
 	}
 	return x + (int) len *FontWidth(screen);
@@ -3642,23 +3648,23 @@ drawXtermText(XtermWidget xw,
 	    }
 	}
 
 	if (flags & NOBACKGROUND) {
 	    XDrawString16(screen->display,
-			  VWindow(screen), gc,
+			  VDrawable(screen), gc,
 			  x, y + ascent_adjust,
 			  buffer, dst);
 	} else {
 	    XDrawImageString16(screen->display,
-			       VWindow(screen), gc,
+			       VDrawable(screen), gc,
 			       x, y + ascent_adjust,
 			       buffer, dst);
 	}
 
 	if ((flags & BOLDATTR(screen)) && screen->enbolden) {
 	    beginClipping(screen, gc, (Cardinal) font_width, len);
-	    XDrawString16(screen->display, VWindow(screen), gc,
+	    XDrawString16(screen->display, VDrawable(screen), gc,
 			  x + 1,
 			  y + ascent_adjust,
 			  buffer, dst);
 	    endClipping(screen, gc);
 	}
@@ -3679,29 +3685,29 @@ drawXtermText(XtermWidget xw,
 #else
 	char *buffer = (char *) text;
 #endif
 
 	if (flags & NOBACKGROUND) {
-	    XDrawString(screen->display, VWindow(screen), gc,
+	    XDrawString(screen->display, VDrawable(screen), gc,
 			x, y, buffer, length);
 	} else {
-	    XDrawImageString(screen->display, VWindow(screen), gc,
+	    XDrawImageString(screen->display, VDrawable(screen), gc,
 			     x, y, buffer, length);
 	}
 	underline_len = (Cardinal) length;
 	if ((flags & BOLDATTR(screen)) && screen->enbolden) {
 	    beginClipping(screen, gc, font_width, length);
-	    XDrawString(screen->display, VWindow(screen), gc,
+	    XDrawString(screen->display, VDrawable(screen), gc,
 			x + 1, y, buffer, length);
 	    endClipping(screen, gc);
 	}
     }
 
     if ((flags & UNDERLINE) && screen->underline && !did_ul) {
 	if (FontDescent(screen) > 1)
 	    y++;
-	XDrawLine(screen->display, VWindow(screen), gc,
+	XDrawLine(screen->display, VDrawable(screen), gc,
 		  x, y, (x + (int) underline_len * font_width - 1), y);
     }
 
     return x + (int) real_length *FontWidth(screen);
 }
@@ -3977,16 +3983,16 @@ ClearCurBackground(XtermWidget xw,
     assert((int) height <= screen->max_row + 1);
 
     if (VWindow(screen)) {
 	set_background(xw, xw->cur_background);
 
-	XClearArea(screen->display, VWindow(screen),
-		   CursorX2(screen, left, fw),
-		   CursorY(screen, top),
-		   (width * fw),
-		   (height * (unsigned) FontHeight(screen)),
-		   False);
+	XFillRectangle(screen->display, VDrawable(screen),
+		    ReverseGC(xw, screen),
+		    CursorX2(screen, left, fw),
+		    CursorY(screen, top),
+		    (width * fw),
+		    (height * (unsigned) FontHeight(screen)));
 
 	set_background(xw, -1);
     }
 }
 #endif /* OPT_ISO_COLORS */
--- xterm-281/ptyx.h	2012-06-24 20:45:38.000000000 +0200
+++ xterm-281-patched/ptyx.h	2012-07-28 11:37:00.319903505 +0200
@@ -1549,10 +1549,11 @@ typedef struct {
 #define VT100_TB_INFO(name) screen.fullVwin.tb_info.name
 #endif
 
 typedef struct {
 	Window		window;		/* X window id			*/
+	Drawable	drawable;	/* X drawable id		*/
 	int		width;		/* width of columns		*/
 	int		height;		/* height of rows		*/
 	Dimension	fullwidth;	/* full width of window		*/
 	Dimension	fullheight;	/* full height of window	*/
 	int		f_width;	/* width of fonts in pixels	*/
@@ -1760,10 +1761,11 @@ typedef struct {
 	int		inhibit;	/* flags for inhibiting changes	*/
 
 /* VT window parameters */
 	Boolean		Vshow;		/* VT window showing		*/
 	VTwin		fullVwin;
+	int             needSwap;
 #ifndef NO_ACTIVE_ICON
 	VTwin		iconVwin;
 	VTwin		*whichVwin;
 #endif /* NO_ACTIVE_ICON */
 
@@ -2599,10 +2601,11 @@ typedef struct _TekWidgetRec {
 
 /*
  * These definitions do not depend on whether xterm supports active-icon.
  */
 #define VWindow(screen)		WhichVWin(screen)->window
+#define VDrawable(screen)	(((screen)->needSwap=1), WhichVWin(screen)->drawable)
 #define VShellWindow(xw)	XtWindow(SHELL_OF(xw))
 #define TWindow(screen)		WhichTWin(screen)->window
 #define TShellWindow		XtWindow(SHELL_OF(tekWidget))
 
 #define Width(screen)		WhichVWin(screen)->width
--- xterm-281/xterm.h	2012-06-24 20:33:27.000000000 +0200
+++ xterm-281-patched/xterm.h	2012-07-26 13:40:53.955101757 +0200
@@ -1369,11 +1369,11 @@ extern Pixel xtermGetColorRes(XtermWidge
 
 #define MapToColorMode(fg, screen, flags) fg
 
 #define ClearCurBackground(xw, top, left, height, width, fw) \
 	XClearArea (TScreenOf(xw)->display, \
-		    VWindow(TScreenOf(xw)), \
+		    VDrawable(TScreenOf(xw)), \
 		    CursorX2(TScreenOf(xw), left, fw), \
 		    CursorY(TScreenOf(xw), top), \
 		    width * fw, \
 		    height * FontHeight(TScreenOf(xw)), \
 		    False)
--- xterm-281/configure	2012-06-26 11:58:09.000000000 +0200
+++ xterm-281-patched/configure	2012-07-28 21:34:05.080405087 +0200
@@ -18384,11 +18384,11 @@ s,@target_alias@,$target_alias,;t t
 s,@ECHO_C@,$ECHO_C,;t t
 s,@ECHO_N@,$ECHO_N,;t t
 s,@ECHO_T@,$ECHO_T,;t t
 s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
 s,@DEFS@,$DEFS,;t t
-s,@LIBS@,$LIBS,;t t
+s,@LIBS@,-lXext $LIBS,;t t
 s,@build@,$build,;t t
 s,@build_cpu@,$build_cpu,;t t
 s,@build_vendor@,$build_vendor,;t t
 s,@build_os@,$build_os,;t t
 s,@host@,$host,;t t

That's all from me. I hope somebody else also finds some these changes useful. :)

Offline

#2 2012-07-28 21:14:40

dickey
Member
Registered: 2009-06-01
Posts: 35

Re: My xterm modifications

I'll take a look at the changes (thanks)

Offline

Board footer

Powered by FluxBB