Beispiel #1
0
/*
 * Reverse scrolls the screen by amount lines, erases top, doesn't alter
 * cursor position (i.e. cursor moves up amount relative to text).
 * All done within the scrolling region, of course.
 * Requires: amount > 0
 */
void
RevScroll(register TScreen *screen, register int amount)
{
	register int i = screen->bot_marg - screen->top_marg + 1;
	register int shift;
	register int bot;
	register int refreshtop;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if(screen->cursor_state)
		HideCursor();
	if (amount > i)
		amount = i;
    if(screen->jumpscroll) {
	if(screen->scroll_amt < 0) {
		if(-screen->refresh_amt + amount > i)
			FlushScroll(screen);
		screen->scroll_amt -= amount;
		screen->refresh_amt -= amount;
	} else {
		if(screen->scroll_amt > 0)
			FlushScroll(screen);
		screen->scroll_amt = -amount;
		screen->refresh_amt = -amount;
	}
    } else {
	shift = -screen->topline;
	bot = screen->max_row - shift;
	refreshheight = amount;
	scrollheight = screen->bot_marg - screen->top_marg -
	 refreshheight + 1;
	refreshtop = screen->top_marg + shift;
	scrolltop = refreshtop + refreshheight;
	if((i = screen->bot_marg - bot) > 0)
		scrollheight -= i;
	if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
		refreshheight -= i;

	if (screen->multiscroll && amount == 1 &&
	    screen->topline == 0 && screen->top_marg == 0 &&
	    screen->bot_marg == screen->max_row) {
	    if (screen->incopy < 0 && screen->scrolls == 0)
		CopyWait(screen);
	    screen->scrolls++;
	}
	scrolling_copy_area(screen, scrolltop-amount, scrollheight, -amount);
	if(refreshheight > 0) {
		ClearCurBackground(screen,
		    (int) refreshtop * FontHeight(screen) + screen->border,
		    (int) OriginX(screen),
		    (unsigned) refreshheight * FontHeight(screen),
		    (unsigned) Width(screen));
	}
    }
    ScrnInsertLine(screen, screen->visbuf, screen->bot_marg, screen->top_marg,
		   amount, screen->max_col + 1);
}
Beispiel #2
0
/*
 * If cursor not in scrolling region, returns.  Else,
 * inserts n blank lines at the cursor's position.  Lines above the
 * bottom margin are lost.
 */
void
InsertLine (register TScreen *screen, register int n)
{
	register int i;
	register int shift;
	register int bot;
	register int refreshtop;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if (screen->cur_row < screen->top_marg ||
	 screen->cur_row > screen->bot_marg)
		return;
	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if (n > (i = screen->bot_marg - screen->cur_row + 1))
		n = i;
    if(screen->jumpscroll) {
	if(screen->scroll_amt <= 0 &&
	 screen->cur_row <= -screen->refresh_amt) {
		if(-screen->refresh_amt + n > screen->max_row + 1)
			FlushScroll(screen);
		screen->scroll_amt -= n;
		screen->refresh_amt -= n;
	} else if(screen->scroll_amt)
		FlushScroll(screen);
    }
    if(!screen->scroll_amt) {
	shift = -screen->topline;
	bot = screen->max_row - shift;
	refreshheight = n;
	scrollheight = screen->bot_marg - screen->cur_row - refreshheight + 1;
	refreshtop = screen->cur_row + shift;
	scrolltop = refreshtop + refreshheight;
	if((i = screen->bot_marg - bot) > 0)
		scrollheight -= i;
	if((i = screen->cur_row + refreshheight - 1 - bot) > 0)
		refreshheight -= i;
	vertical_copy_area(screen, scrolltop-n, scrollheight, -n);
	if(refreshheight > 0) {
		ClearCurBackground(screen,
		    (int) refreshtop * FontHeight(screen) + screen->border,
		    (int) OriginX(screen),
		    (unsigned) refreshheight * FontHeight(screen),
		    (unsigned) Width(screen));
	}
    }
    ScrnInsertLine(screen, screen->visbuf, screen->bot_marg, screen->cur_row, n,
		   screen->max_col + 1);
}
Beispiel #3
0
/*
 * Clear from cursor position to end of display, inclusive.
 */
static void
ClearBelow (register TScreen *screen)
{
	ClearRight(screen, -1);

	if (screen->protected_mode != OFF_PROTECT) {
		register int row;
		for (row = screen->cur_row + 1; row <= screen->max_row; row++)
			ClearInLine(screen, row, 0, screen->max_col + 1);
	} else {
		register int top;

		if((top = screen->cur_row - screen->topline) <= screen->max_row) {
			if(screen->scroll_amt)
				FlushScroll(screen);
			if(++top <= screen->max_row) {
				ClearCurBackground(screen,
				    top * FontHeight(screen) + screen->border,
				    OriginX(screen),
				    (screen->max_row - top + 1) * FontHeight(screen),
				    Width(screen));
			}
		}
		ClearBufRows(screen, screen->cur_row + 1, screen->max_row);
	}
}
Beispiel #4
0
/*
 * Clear from cursor position to beginning of display, inclusive.
 */
static void
ClearAbove (register TScreen *screen)
{
	if (screen->protected_mode != OFF_PROTECT) {
		register int row;
		for (row = 0; row <= screen->max_row; row++)
			ClearInLine(screen, row, 0, screen->max_col + 1);
	} else {
		register int top, height;

		if(screen->cursor_state)
			HideCursor();
		if((top = -screen->topline) <= screen->max_row) {
			if(screen->scroll_amt)
				FlushScroll(screen);
			if((height = screen->cur_row + top) > screen->max_row)
				height = screen->max_row;
			if((height -= top) > 0) {
				ClearCurBackground(screen,
				    top * FontHeight(screen) + screen->border,
				    OriginX(screen),
				    height * FontHeight(screen),
				    Width(screen));
			}
		}
		ClearBufRows(screen, 0, screen->cur_row - 1);
	}

	if(screen->cur_row - screen->topline <= screen->max_row)
		ClearLeft(screen);
}
Beispiel #5
0
void
xevents(void)
{
	XEvent event;
	XtInputMask input_mask;
	register TScreen *screen = &term->screen;

	if(screen->scroll_amt)
		FlushScroll(screen);
	/*
	 * process timeouts, relying on the fact that XtAppProcessEvent
	 * will process the timeout and return without blockng on the
	 * XEvent queue.  Other sources i.e. the pty are handled elsewhere
	 * with select().
	 */
	while ((input_mask = XtAppPending(app_con)) & XtIMTimer)
		XtAppProcessEvent(app_con, XtIMTimer);
	/*
	 * If there's no XEvents, don't wait around...
	 */
	if ((input_mask & XtIMXEvent) != XtIMXEvent)
	    return;
	do {
		if (waitingForTrackInfo)
			return;
		XtAppNextEvent (app_con, &event);
		/*
		 * Hack to get around problems with the toolkit throwing away
		 * eventing during the exclusive grab of the menu popup.  By
		 * looking at the event ourselves we make sure that we can
		 * do the right thing.
		 */
		if(OUR_EVENT(event, EnterNotify))
		  DoSpecialEnterNotify (&event.xcrossing);
		else
		if(OUR_EVENT(event, LeaveNotify))
		  DoSpecialLeaveNotify (&event.xcrossing);
		else if ((screen->send_mouse_pos == ANY_EVENT_MOUSE
#if OPT_DEC_LOCATOR
			|| screen->send_mouse_pos == DEC_LOCATOR
#endif	/* OPT_DEC_LOCATOR */
								)
		 && event.xany.type == MotionNotify
		 && event.xcrossing.window == XtWindow(term)) {
		    SendMousePosition((Widget)term, &event);
		    continue;
		}

		if (!event.xany.send_event ||
		    screen->allowSendEvents ||
		    ((event.xany.type != KeyPress) &&
		     (event.xany.type != KeyRelease) &&
		     (event.xany.type != ButtonPress) &&
		     (event.xany.type != ButtonRelease)))
		    XtDispatchEvent(&event);
	} while ((input_mask = XtAppPending(app_con)) & XtIMXEvent);
}
Beispiel #6
0
/*
 * Insert n blanks at the cursor's position, no wraparound
 */
void
InsertChar (register TScreen *screen, register int n)
{
	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if(screen->cur_row - screen->topline <= screen->max_row) {
	    if(!AddToRefresh(screen)) {
		int col = screen->max_col + 1 - n;
		if(screen->scroll_amt)
			FlushScroll(screen);

#if OPT_DEC_CHRSET
		if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, screen->cur_row)[0])) {
			col = (screen->max_col + 1) / 2 - n;
		}
#endif
		/*
		 * prevent InsertChar from shifting the end of a line over
		 * if it is being appended to
		 */
		if (non_blank_line (screen->visbuf, screen->cur_row,
				    screen->cur_col, screen->max_col + 1))
		    horizontal_copy_area(screen, screen->cur_col,
					 col - screen->cur_col,
					 n);

		ClearCurBackground(
			screen,
			CursorY (screen, screen->cur_row),
			CurCursorX (screen, screen->cur_row, screen->cur_col),
			FontHeight(screen),
			n * CurFontWidth(screen,screen->cur_row));
	    }
	}
	/* adjust screen->buf */
	ScrnInsertChar(screen, n, screen->max_col + 1);
}
Beispiel #7
0
/*
 * Deletes n chars at the cursor's position, no wraparound.
 */
void
DeleteChar (register TScreen *screen, register int n)
{
	register int width;

	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if (n > (width = screen->max_col + 1 - screen->cur_col))
	  	n = width;

	if(screen->cur_row - screen->topline <= screen->max_row) {
	    if(!AddToRefresh(screen)) {
		int col = screen->max_col + 1 - n;
		if(screen->scroll_amt)
			FlushScroll(screen);

#if OPT_DEC_CHRSET
		if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, screen->cur_row)[0])) {
			col = (screen->max_col + 1) / 2 - n;
		}
#endif
		horizontal_copy_area(screen, screen->cur_col+n,
				     col - screen->cur_col,
				     -n);

		ClearCurBackground (
			screen,
			CursorY (screen, screen->cur_row),
			CurCursorX(screen, screen->cur_row, col),
			FontHeight(screen),
			n * CurFontWidth(screen,screen->cur_row));
	    }
	}
	/* adjust screen->buf */
	ScrnDeleteChar (screen, n, screen->max_col + 1);
}
/*
 * Interpret sixel graphics sequences.
 *
 * Resources:
 *  http://en.wikipedia.org/wiki/Sixel
 *  http://vt100.net/docs/vt3xx-gp/chapter14.html
 *  ftp://ftp.cs.utk.edu/pub/shuford/terminal/sixel_graphics_news.txt
 *  ftp://ftp.cs.utk.edu/pub/shuford/terminal/all_about_sixels.txt
 */
void
parse_sixel(XtermWidget xw, ANSI *params, char const *string)
{
    TScreen *screen = TScreenOf(xw);
    Graphic *graphic;
    SixelContext context;
    Char ch;

    switch (screen->terminal_id) {
    case 240:
    case 241:
    case 330:
    case 340:
	context.aspect_vertical = 2;
	context.aspect_horizontal = 1;
	break;
    case 382:
	context.aspect_vertical = 1;
	context.aspect_horizontal = 1;
	break;
    default:
	context.aspect_vertical = 2;
	context.aspect_horizontal = 1;
	break;
    }

    context.declared_width = 0;
    context.declared_height = 0;

    context.row = 0;
    context.col = 0;

    /* default isn't white on the VT240, but not sure what it is */
    context.current_register = 3;	/* FIXME: using green, but not sure what it should be */

    if (xw->keyboard.flags & MODE_DECSDM) {
	TRACE(("sixel scrolling enabled: inline positioning for graphic at %d,%d\n",
	       screen->cur_row, screen->cur_col));
	graphic = get_new_graphic(xw, screen->cur_row, screen->cur_col, 0U);
    } else {
	TRACE(("sixel scrolling disabled: inline positioning for graphic at %d,%d\n",
	       0, 0));
	graphic = get_new_graphic(xw, 0, 0, 0U);
    }

    {
	int Pmacro = params->a_param[0];
	int Pbgmode = params->a_param[1];
	int Phgrid = params->a_param[2];
	int Pan = params->a_param[3];
	int Pad = params->a_param[4];
	int Ph = params->a_param[5];
	int Pv = params->a_param[6];

	(void) Phgrid;

	TRACE(("sixel bitmap graphics sequence: params=%d (Pmacro=%d Pbgmode=%d Phgrid=%d) scroll_amt=%d\n",
	       params->a_nparam,
	       Pmacro,
	       Pbgmode,
	       Phgrid,
	       screen->scroll_amt));

	switch (params->a_nparam) {
	case 7:
	    if (Pan == 0 || Pad == 0) {
		TRACE(("DATA_ERROR: invalid raster ratio %d/%d\n", Pan, Pad));
		return;
	    }
	    context.aspect_vertical = Pan;
	    context.aspect_horizontal = Pad;

	    if (Ph == 0 || Pv == 0) {
		TRACE(("DATA_ERROR: raster image dimensions are invalid %dx%d\n",
		       Ph, Pv));
		return;
	    }
	    if (Ph > graphic->max_width || Pv > graphic->max_height) {
		TRACE(("DATA_ERROR: raster image dimensions are too large %dx%d\n",
		       Ph, Pv));
		return;
	    }
	    context.declared_width = Ph;
	    context.declared_height = Pv;
	    if (context.declared_width > graphic->actual_width) {
		graphic->actual_width = context.declared_width;
	    }
	    if (context.declared_height > graphic->actual_height) {
		graphic->actual_height = context.declared_height;
	    }
	    break;
	case 3:
	case 2:
	case 1:
	    switch (Pmacro) {
	    case 0:
		/* keep default aspect settings */
		break;
	    case 1:
	    case 5:
	    case 6:
		context.aspect_vertical = 2;
		context.aspect_horizontal = 1;
		break;
	    case 2:
		context.aspect_vertical = 5;
		context.aspect_horizontal = 1;
		break;
	    case 3:
	    case 4:
		context.aspect_vertical = 3;
		context.aspect_horizontal = 1;
		break;
	    case 7:
	    case 8:
	    case 9:
		context.aspect_vertical = 1;
		context.aspect_horizontal = 1;
		break;
	    default:
		TRACE(("DATA_ERROR: unknown sixel macro mode parameter\n"));
		return;
	    }
	    break;
	case 0:
	    break;
	default:
	    TRACE(("DATA_ERROR: unexpected parameter count (found %d)\n", params->a_nparam));
	    return;
	}

	if (Pbgmode == 1) {
	    context.background = COLOR_HOLE;
	} else {
	    /* FIXME: is the default background register always zero?  what about in light background mode? */
	    context.background = 0;
	}

	/* Ignore the grid parameter because it seems only printers paid attention to it.
	 * The VT3xx was always 0.0195 cm.
	 */
    }

    update_sixel_aspect(&context, graphic);

    for (;;) {
	ch = CharOf(*string);
	if (ch == '\0')
	    break;

	if (ch >= 0x3f && ch <= 0x7e) {
	    int sixel = ch - 0x3f;
	    TRACE(("sixel=%x (%c)\n", sixel, (char) ch));
	    if (!graphic->valid) {
		init_sixel_background(graphic, &context);
		graphic->valid = 1;
	    }
	    set_sixel(graphic, &context, sixel);
	    context.col++;
	} else if (ch == '$') {	/* DECGCR */
	    /* ignore DECCRNLM in sixel mode */
	    TRACE(("sixel CR\n"));
	    context.col = 0;
	} else if (ch == '-') {	/* DECGNL */
	    int scroll_lines;
	    TRACE(("sixel NL\n"));
	    scroll_lines = 0;
	    while (graphic->charrow - scroll_lines +
		   (((context.row + 6) * graphic->pixh
		     + FontHeight(screen) - 1)
		    / FontHeight(screen)) > screen->bot_marg) {
		scroll_lines++;
	    }
	    context.col = 0;
	    context.row += 6;
	    /* If we hit the bottom margin on the graphics page (well, we just use the
	     * text margin for now), the behavior is to either scroll or to discard
	     * the remainder of the graphic depending on this setting.
	     */
	    if (scroll_lines > 0) {
		if (xw->keyboard.flags & MODE_DECSDM) {
		    Display *display = screen->display;
		    xtermScroll(xw, scroll_lines);
		    XSync(display, False);
		    TRACE(("graphic scrolled the screen %d lines. screen->scroll_amt=%d screen->topline=%d, now starting row is %d\n",
			   scroll_lines,
			   screen->scroll_amt,
			   screen->topline,
			   graphic->charrow));
		} else {
		    break;
		}
	    }
	} else if (ch == '!') {	/* DECGRI */
	    int Pcount;
	    const char *start;
	    int sixel;
	    int i;

	    start = ++string;
	    for (;;) {
		ch = CharOf(*string);
		if (ch != '0' &&
		    ch != '1' &&
		    ch != '2' &&
		    ch != '3' &&
		    ch != '4' &&
		    ch != '5' &&
		    ch != '6' &&
		    ch != '7' &&
		    ch != '8' &&
		    ch != '9' &&
		    ch != ' ' &&
		    ch != '\r' &&
		    ch != '\n')
		    break;
		string++;
	    }
	    if (ch == '\0') {
		TRACE(("DATA_ERROR: sixel data string terminated in the middle of a repeat operator\n"));
		return;
	    }
	    if (string == start) {
		TRACE(("DATA_ERROR: sixel data string contains a repeat operator with empty count\n"));
		return;
	    }
	    Pcount = atoi(start);
	    sixel = ch - 0x3f;
	    TRACE(("sixel repeat operator: sixel=%d (%c), count=%d\n",
		   sixel, (char) ch, Pcount));
	    if (!graphic->valid) {
		init_sixel_background(graphic, &context);
		graphic->valid = 1;
	    }
	    for (i = 0; i < Pcount; i++) {
		set_sixel(graphic, &context, sixel);
		context.col++;
	    }
	} else if (ch == '#') {	/* DECGCI */
	    ANSI color_params;
	    int Pregister;

	    parse_prefixedtype_params(&color_params, &string);
	    Pregister = color_params.a_param[0];
	    if (Pregister >= (int) graphic->valid_registers) {
		TRACE(("DATA_WARNING: sixel color operator uses out-of-range register %d\n", Pregister));
		/* FIXME: supposedly the DEC terminals wrapped register indicies -- verify */
		while (Pregister >= (int) graphic->valid_registers)
		    Pregister -= (int) graphic->valid_registers;
		TRACE(("DATA_WARNING: converted to %d\n", Pregister));
	    }

	    if (color_params.a_nparam > 2 && color_params.a_nparam <= 5) {
		int Pspace = color_params.a_param[1];
		int Pc1 = color_params.a_param[2];
		int Pc2 = color_params.a_param[3];
		int Pc3 = color_params.a_param[4];
		short r, g, b;

		TRACE(("sixel set color register=%d space=%d color=[%d,%d,%d] (nparams=%d)\n",
		       Pregister, Pspace, Pc1, Pc2, Pc3, color_params.a_nparam));

		switch (Pspace) {
		case 1:	/* HLS */
		    if (Pc1 > 360 || Pc2 > 100 || Pc3 > 100) {
			TRACE(("DATA_ERROR: sixel set color operator uses out-of-range HLS color coordinates %d,%d,%d\n",
			       Pc1, Pc2, Pc3));
			return;
		    }
		    hls2rgb(Pc1, Pc2, Pc3, &r, &g, &b);
		    break;
		case 2:	/* RGB */
		    if (Pc1 > 100 || Pc2 > 100 || Pc3 > 100) {
			TRACE(("DATA_ERROR: sixel set color operator uses out-of-range RGB color coordinates %d,%d,%d\n",
			       Pc1, Pc2, Pc3));
			return;
		    }
		    r = (short) Pc1;
		    g = (short) Pc2;
		    b = (short) Pc3;
		    break;
		default:	/* unknown */
		    TRACE(("DATA_ERROR: sixel set color operator uses unknown color space %d\n", Pspace));
		    return;
		}
		update_color_register(graphic,
				      (RegisterNum) Pregister,
				      r, g, b);
	    } else if (color_params.a_nparam == 1) {
		TRACE(("sixel switch to color register=%d (nparams=%d)\n",
		       Pregister, color_params.a_nparam));
		context.current_register = (RegisterNum) Pregister;
	    } else {
		TRACE(("DATA_ERROR: sixel switch color operator with unexpected parameter count (nparams=%d)\n", color_params.a_nparam));
		return;
	    }
	    continue;
	} else if (ch == '"') /* DECGRA */  {
	    ANSI raster_params;

	    parse_prefixedtype_params(&raster_params, &string);
	    if (raster_params.a_nparam < 2) {
		TRACE(("DATA_ERROR: sixel raster attribute operator with incomplete parameters (found %d, expected 2 or 4)\n", raster_params.a_nparam));
		return;
	    } {
		int Pan = raster_params.a_param[0];
		int Pad = raster_params.a_param[1];
		TRACE(("sixel raster attribute with h:w=%d:%d\n", Pan, Pad));
		if (Pan == 0 || Pad == 0) {
		    TRACE(("DATA_ERROR: invalid raster ratio %d/%d\n", Pan, Pad));
		    return;
		}
		context.aspect_vertical = Pan;
		context.aspect_horizontal = Pad;
		update_sixel_aspect(&context, graphic);
	    }

	    if (raster_params.a_nparam >= 4) {
		int Ph = raster_params.a_param[2];
		int Pv = raster_params.a_param[3];

		TRACE(("sixel raster attribute with h=%d v=%d\n", Ph, Pv));
		if (Ph == 0 || Pv == 0) {
		    TRACE(("DATA_ERROR: raster image dimensions are invalid %dx%d\n",
			   Ph, Pv));
		    return;
		}
		if (Ph > graphic->max_width || Pv > graphic->max_height) {
		    TRACE(("DATA_ERROR: raster image dimensions are too large %dx%d\n",
			   Ph, Pv));
		    return;
		}
		context.declared_width = Ph;
		context.declared_height = Pv;
		if (context.declared_width > graphic->actual_width) {
		    graphic->actual_width = context.declared_width;
		}
		if (context.declared_height > graphic->actual_height) {
		    graphic->actual_height = context.declared_height;
		}
	    }

	    continue;
	} else if (ch == ' ' || ch == '\r' || ch == '\n') {
	    /* EMPTY */ ;
	} else {
	    TRACE(("DATA_ERROR: unknown sixel command %04x (%c)\n",
		   (int) ch, ch));
	}

	string++;
    }

    /* update the screen */
    if (screen->scroll_amt)
	FlushScroll(xw);

    if (xw->keyboard.flags & MODE_DECSDM) {
	int new_row, new_col;

	if (screen->sixel_scrolls_right) {
	    new_row = (graphic->charrow
		       + (((graphic->actual_height * graphic->pixh)
			   + FontHeight(screen) - 1)
			  / FontHeight(screen))
		       - 1);
	    new_col = (graphic->charcol
		       + (((graphic->actual_width * graphic->pixw)
			   + FontWidth(screen) - 1)
			  / FontWidth(screen)));
	} else {
	    /* FIXME: At least of the VT382 the vertical position appears to be
	     * truncated (rounded toward zero after converting to character row.
	     * This code rounds up, which seems more useful, but it would be
	     * better to be compatible.  Verify this is true on a VT3[34]0 as
	     * well.
	     */
	    new_row = (graphic->charrow
		       + (((graphic->actual_height * graphic->pixh)
			   + FontHeight(screen) - 1)
			  / FontHeight(screen)));
	    new_col = 0;
	}

	TRACE(("setting text position after %dx%d graphic starting on row=%d col=%d: cursor new_row=%d new_col=%d\n",
	       graphic->actual_width * graphic->pixw,
	       graphic->actual_height * graphic->pixh,
	       graphic->charrow,
	       graphic->charcol,
	       new_row, new_col));

	if (new_col > screen->rgt_marg) {
	    new_col = screen->lft_marg;
	    new_row++;
	    TRACE(("column past left margin, overriding to row=%d col=%d\n",
		   new_row, new_col));
	}

	while (new_row > screen->bot_marg) {
	    xtermScroll(xw, 1);
	    new_row--;
	    TRACE(("bottom row was past screen.  new start row=%d, cursor row=%d\n",
		   graphic->charrow, new_row));
	}

	if (new_row < 0) {
	    TRACE(("new row is going to be negative (%d)!", new_row));	/* FIXME: this was triggering, now it isn't */
	    goto finis;
	}
	set_cur_row(screen, new_row);
	set_cur_col(screen, new_col <= screen->rgt_marg ? new_col : screen->rgt_marg);
    }

  finis:
    refresh_modified_displayed_graphics(screen);

    TRACE(("DONE successfully parsed sixel data\n"));
    dump_graphic(graphic);
}
Beispiel #9
0
/*
 * Clear the given row, for the given range of columns, returning 1 if no
 * protected characters were found, 0 otherwise.
 */
static int
ClearInLine(register TScreen *screen, int row, int col, int len)
{
	int rc = 1;
	int flags = TERM_COLOR_FLAGS;

	/*
	 * If we're clearing to the end of the line, we won't count this as
	 * "drawn" characters.  We'll only do cut/paste on "drawn" characters,
	 * so this has the effect of suppressing trailing blanks from a
	 * selection.
	 */
	if (col + len + 1 < screen->max_col)
		flags |= CHARDRAWN;

	/* If we've marked protected text on the screen, we'll have to
	 * check each time we do an erase.
	 */
	if (screen->protected_mode != OFF_PROTECT) {
		register int n;
		Char *attrs = SCRN_BUF_ATTRS(screen, row) + col;
		int saved_mode = screen->protected_mode;
		Bool done;

		/* disable this branch during recursion */
		screen->protected_mode = OFF_PROTECT;

		do {
			done = True;
			for (n = 0; n < len; n++) {
				if (attrs[n] & PROTECTED) {
					rc = 0; /* found a protected segment */
					if (n != 0)
						ClearInLine(screen, row, col, n);
					while ((n < len)
					   &&  (attrs[n] & PROTECTED))
						n++;
					done = False;
					break;
				}
			}
			/* setup for another segment, past the protected text */
			if (!done) {
				attrs += n;
				col += n;
				len -= n;
			}
		} while (!done);

		screen->protected_mode = saved_mode;
		if (len <= 0)
			return 0;
	}
	/* fall through to the final non-protected segment */

	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;

	if (row - screen->topline <= screen->max_row) {
		if(!AddToRefresh(screen)) {
			if(screen->scroll_amt)
				FlushScroll(screen);
			ClearCurBackground (
				screen,
				CursorY (screen, row),
				CurCursorX (screen, row, col),
				FontHeight(screen),
				len * CurFontWidth(screen,row));
		}
	}

	memset(SCRN_BUF_CHARS(screen, row) + col, ' ',   len);
	memset(SCRN_BUF_ATTRS(screen, row) + col, flags, len);

	if_OPT_ISO_COLORS(screen,{
		memset(SCRN_BUF_COLOR(screen, row) + col, xtermColorPair(), len);
	})
Beispiel #10
0
/*
 * If cursor not in scrolling region, returns.  Else, deletes n lines
 * at the cursor's position, lines added at bottom margin are blank.
 */
void
DeleteLine(register TScreen *screen, register int n)
{
	register int i;
	register int shift;
	register int bot;
	register int refreshtop;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if (screen->cur_row < screen->top_marg ||
	 screen->cur_row > screen->bot_marg)
		return;
	if(screen->cursor_state)
		HideCursor();
	screen->do_wrap = 0;
	if (n > (i = screen->bot_marg - screen->cur_row + 1))
		n = i;
    if(screen->jumpscroll) {
	if(screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
		if(screen->refresh_amt + n > screen->max_row + 1)
			FlushScroll(screen);
		screen->scroll_amt += n;
		screen->refresh_amt += n;
	} else if(screen->scroll_amt)
		FlushScroll(screen);
    }
    if(!screen->scroll_amt) {

	shift = -screen->topline;
	bot = screen->max_row - shift;
	scrollheight = i - n;
	refreshheight = n;
	if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
	 (i = screen->max_row - refreshheight + 1))
		refreshtop = i;
	if(screen->scrollWidget && !screen->alternate && screen->cur_row == 0) {
		scrolltop = 0;
		if((scrollheight += shift) > i)
			scrollheight = i;
		if((i = screen->savedlines) < screen->savelines) {
			if((i += n) > screen->savelines)
				i = screen->savelines;
			screen->savedlines = i;
			ScrollBarDrawThumb(screen->scrollWidget);
		}
	} else {
		scrolltop = screen->cur_row + shift;
		if((i = screen->bot_marg - bot) > 0) {
			scrollheight -= i;
			if((i = screen->cur_row + n - 1 - bot) >= 0) {
				refreshheight -= i;
			}
		}
	}
	vertical_copy_area(screen, scrolltop+n, scrollheight, n);
	if(refreshheight > 0) {
		ClearCurBackground(screen,
		    (int) refreshtop * FontHeight(screen) + screen->border,
		    (int) OriginX(screen),
		    (unsigned) refreshheight * FontHeight(screen),
		    (unsigned) Width(screen));
	}
    }
	/* adjust screen->buf */
	if(screen->scrollWidget && !screen->alternate && screen->cur_row == 0)
		ScrnDeleteLine(screen, screen->allbuf,
			screen->bot_marg + screen->savelines, 0,
			n, screen->max_col + 1);
	else
		ScrnDeleteLine(screen, screen->visbuf,
			screen->bot_marg, screen->cur_row,
			n, screen->max_col + 1);
}
Beispiel #11
0
/*
 * scrolls the screen by amount lines, erases bottom, doesn't alter
 * cursor position (i.e. cursor moves down amount relative to text).
 * All done within the scrolling region, of course.
 * requires: amount > 0
 */
void
Scroll(register TScreen *screen, register int amount)
{
	register int i = screen->bot_marg - screen->top_marg + 1;
	register int shift;
	register int bot;
	register int refreshtop = 0;
	register int refreshheight;
	register int scrolltop;
	register int scrollheight;

	if(screen->cursor_state)
		HideCursor();
	if (amount > i)
		amount = i;
    if(screen->jumpscroll) {
	if(screen->scroll_amt > 0) {
		if(screen->refresh_amt + amount > i)
			FlushScroll(screen);
		screen->scroll_amt += amount;
		screen->refresh_amt += amount;
	} else {
		if(screen->scroll_amt < 0)
			FlushScroll(screen);
		screen->scroll_amt = amount;
		screen->refresh_amt = amount;
	}
	refreshheight = 0;
    } else {
	ScrollSelection(screen, -(amount));
	if (amount == i) {
		ClearScreen(screen);
		return;
	}
	shift = -screen->topline;
	bot = screen->max_row - shift;
	scrollheight = i - amount;
	refreshheight = amount;
	if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
	 (i = screen->max_row - refreshheight + 1))
		refreshtop = i;
	if(screen->scrollWidget && !screen->alternate
	 && screen->top_marg == 0) {
		scrolltop = 0;
		if((scrollheight += shift) > i)
			scrollheight = i;
		if((i = screen->savedlines) < screen->savelines) {
			if((i += amount) > screen->savelines)
				i = screen->savelines;
			screen->savedlines = i;
			ScrollBarDrawThumb(screen->scrollWidget);
		}
	} else {
		scrolltop = screen->top_marg + shift;
		if((i = screen->bot_marg - bot) > 0) {
			scrollheight -= i;
			if((i = screen->top_marg + amount - 1 - bot) >= 0) {
				refreshtop += i;
				refreshheight -= i;
			}
		}
	}

	if (screen->multiscroll && amount == 1 &&
	    screen->topline == 0 && screen->top_marg == 0 &&
	    screen->bot_marg == screen->max_row) {
	    if (screen->incopy < 0 && screen->scrolls == 0)
		CopyWait(screen);
	    screen->scrolls++;
	}
	scrolling_copy_area(screen, scrolltop+amount, scrollheight, amount);
	if(refreshheight > 0) {
		ClearCurBackground(screen,
		    (int) refreshtop * FontHeight(screen) + screen->border,
		    (int) OriginX(screen),
		    (unsigned) refreshheight * FontHeight(screen),
		    (unsigned) Width(screen));
		if(refreshheight > shift)
			refreshheight = shift;
	}
    }
	if(screen->scrollWidget && !screen->alternate && screen->top_marg == 0)
		ScrnDeleteLine(screen, screen->allbuf,
			screen->bot_marg + screen->savelines, 0,
			amount, screen->max_col + 1);
	else
		ScrnDeleteLine(screen, screen->visbuf,
			screen->bot_marg, screen->top_marg,
			amount, screen->max_col + 1);
	if(refreshheight > 0)
		ScrnRefresh(screen, refreshtop, 0, refreshheight,
		 screen->max_col + 1, False);
}