Esempio n. 1
0
static void change_private_mode(int mode, int set)
{
	switch (mode)
	{
	case 1: /* DECCKM */
		console->cursor_key_mode = set;
		break;

	case 3:
		if (set) /* 132 column mode */
			console_set_size(132, 24);
		else /* 80 column mode */
			console_set_size(80, 24);
		/* Clear window content and reset scrolling regions */
		erase_screen(2);
		set_pos(0, 0);
		break;
		
	case 6:
		console->origin_mode = set;
		break;

	case 7:
		console->wraparound_mode = set;
		break;

	default:
		log_error("change_private_mode(): private mode %d not supported.\n", mode);
	}
}
Esempio n. 2
0
void restart_screen (void)
{

    /* Use default settings */

    os_set_colour (h_default_foreground, h_default_background);

    if (os_font_data (TEXT_FONT, &font_height, &font_width))
        os_set_font (TEXT_FONT);

    os_set_text_style (0);

    cursor = TRUE;

    /* Initialise window properties */

    mwin = 1;

    for (cwp = wp; cwp < wp + 8; cwp++) {
        cwp->y_pos = 1;
        cwp->x_pos = 1;
        cwp->y_size = 0;
        cwp->x_size = 0;
        cwp->y_cursor = 1;
        cwp->x_cursor = 1;
        cwp->left = 0;
        cwp->right = 0;
        cwp->nl_routine = 0;
        cwp->nl_countdown = 0;
        cwp->style = 0;
        cwp->colour = (h_default_background << 8) | h_default_foreground;
        cwp->font = TEXT_FONT;
        cwp->font_size = (font_height << 8) | font_width;
        cwp->attribute = 8;
        cwp->true_fore = hx_fore_colour;
        cwp->true_back = hx_back_colour;
    }

    /* Prepare lower/upper windows and status line */

    wp[0].attribute = 15;

    wp[0].left = option_left_margin;
    wp[0].right = option_right_margin;

    wp[0].x_size = h_screen_width;
    wp[1].x_size = h_screen_width;

    if (h_version <= V3)
        wp[7].x_size = h_screen_width;

    os_restart_game (RESTART_WPROP_SET);

    /* Clear the screen, unsplit it and select window 0 */

    erase_screen ((zword) (-1));

}/* restart_screen */
Esempio n. 3
0
File: screen.c Progetto: BAM-X/frotz
/*
 * z_erase_window, erase a window or the screen to background colour.
 *
 *	zargs[0] = window (-3 current, -2 screen, -1 screen & unsplit)
 *
 */
void z_erase_window (void)
{
    flush_buffer ();

    if ((short) zargs[0] == -1 || (short) zargs[0] == -2)
	erase_screen (zargs[0]);
    else
	erase_window (winarg0 ());

}/* z_erase_window */
Esempio n. 4
0
int show_buffer(struct session *ses) {
  char temp[STRING_SIZE];
  int scroll_size, scroll_cnt, scroll_tmp, scroll_add, scroll_cut;

  if (ses != gtd->ses) {
    return TRUE;
  }

  scroll_size = get_scroll_size(ses);
  scroll_add = 0 - ses->scroll_base;
  scroll_tmp = 0;
  scroll_cnt = ses->scroll_line;
  scroll_cut = 0;
  /*
     Find the upper limit of the buffer shown
   */

  while (TRUE) {
    if (ses->buffer[scroll_cnt] == NULL) {
      break;
    }

    scroll_tmp = str_hash_lines(ses->buffer[scroll_cnt]);

    if (scroll_add + scroll_tmp > scroll_size) {
      if (scroll_add == scroll_size) {
        scroll_cut = 0;
      } else {
        scroll_cut = scroll_tmp - (scroll_size - scroll_add);
      }
      break;
    }

    scroll_add += scroll_tmp;

    if (scroll_cnt == ses->scroll_max - 1) {
      scroll_cnt = 0;
    } else {
      scroll_cnt++;
    }
  }

  if (ses->buffer[scroll_cnt] == NULL) {
    erase_screen(ses);
  }

  if (IS_SPLIT(ses)) {
    save_pos(ses);
    goto_rowcol(ses, ses->bot_row, 1);
    SET_BIT(ses->flags, SES_FLAG_READMUD);
  }

  /*
     If the top line exists of multiple lines split it in the middle.
   */

  if (ses->buffer[scroll_cnt] && scroll_cut) {
    if (scroll_add >= 0) {
      word_wrap_split(ses, ses->buffer[scroll_cnt], temp, scroll_tmp - scroll_cut, scroll_cut);

      printf("%s\n", temp);
    } else {
      word_wrap_split(ses, ses->buffer[scroll_cnt], temp, ses->scroll_base, scroll_size);

      goto eof;
    }
  }

  /*
     Print away
   */

  while (TRUE) {
    if (scroll_cnt == 0) {
      scroll_cnt = ses->scroll_max - 1;
    } else {
      scroll_cnt--;
    }

    if (ses->buffer[scroll_cnt] == NULL) {
      break;
    }

    scroll_tmp = word_wrap(ses, ses->buffer[scroll_cnt], temp, FALSE);

    if (scroll_add - scroll_tmp < 0) {
      scroll_cut = scroll_add;
      break;
    }

    scroll_add -= scroll_tmp;

    printf("%s\n", temp);
  }

  /*
     If the bottom line exists of multiple lines split it in the middle
   */

  if (scroll_tmp && ses->buffer[scroll_cnt]) {
    word_wrap_split(ses, ses->buffer[scroll_cnt], temp, 0, scroll_cut);
  }

 eof:

  if (IS_SPLIT(ses)) {
    restore_pos(ses);
    DEL_BIT(ses->flags, SES_FLAG_READMUD);
  }
  return TRUE;
}
Esempio n. 5
0
File: ansi.c Progetto: AVLeo/libav
static int decode_frame(AVCodecContext *avctx,
                            void *data, int *got_frame,
                            AVPacket *avpkt)
{
    AnsiContext *s = avctx->priv_data;
    uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    const uint8_t *buf_end   = buf+buf_size;
    int ret, i, count;

    ret = ff_reget_buffer(avctx, s->frame);
    if (ret < 0){
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }
    if (!avctx->frame_number) {
        memset(s->frame->data[0], 0, avctx->height * FFABS(s->frame->linesize[0]));
        memset(s->frame->data[1], 0, AVPALETTE_SIZE);
    }

    s->frame->pict_type           = AV_PICTURE_TYPE_I;
    s->frame->palette_has_changed = 1;
    memcpy(s->frame->data[1], ff_cga_palette, 16 * 4);

    while(buf < buf_end) {
        switch(s->state) {
        case STATE_NORMAL:
            switch (buf[0]) {
            case 0x00: //NUL
            case 0x07: //BEL
            case 0x1A: //SUB
                /* ignore */
                break;
            case 0x08: //BS
                s->x = FFMAX(s->x - 1, 0);
                break;
            case 0x09: //HT
                i = s->x / FONT_WIDTH;
                count = ((i + 8) & ~7) - i;
                for (i = 0; i < count; i++)
                    draw_char(avctx, ' ');
                break;
            case 0x0A: //LF
                hscroll(avctx);
            case 0x0D: //CR
                s->x = 0;
                break;
            case 0x0C: //FF
                erase_screen(avctx);
                break;
            case 0x1B: //ESC
                s->state = STATE_ESCAPE;
                break;
            default:
                draw_char(avctx, buf[0]);
            }
            break;
        case STATE_ESCAPE:
            if (buf[0] == '[') {
                s->state   = STATE_CODE;
                s->nb_args = 0;
                s->args[0] = 0;
            } else {
                s->state = STATE_NORMAL;
                draw_char(avctx, 0x1B);
                continue;
            }
            break;
        case STATE_CODE:
            switch(buf[0]) {
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
                if (s->nb_args < MAX_NB_ARGS)
                    s->args[s->nb_args] = s->args[s->nb_args] * 10 + buf[0] - '0';
                break;
            case ';':
                s->nb_args++;
                if (s->nb_args < MAX_NB_ARGS)
                    s->args[s->nb_args] = 0;
                break;
            case 'M':
                s->state = STATE_MUSIC_PREAMBLE;
                break;
            case '=': case '?':
                /* ignore */
                break;
            default:
                if (s->nb_args > MAX_NB_ARGS)
                    av_log(avctx, AV_LOG_WARNING, "args overflow (%i)\n", s->nb_args);
                if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args])
                    s->nb_args++;
                if ((ret = execute_code(avctx, buf[0])) < 0)
                    return ret;
                s->state = STATE_NORMAL;
            }
            break;
        case STATE_MUSIC_PREAMBLE:
            if (buf[0] == 0x0E || buf[0] == 0x1B)
                s->state = STATE_NORMAL;
            /* ignore music data */
            break;
        }
        buf++;
    }

    *got_frame = 1;
    if ((ret = av_frame_ref(data, s->frame)) < 0)
        return ret;
    return buf_size;
}
Esempio n. 6
0
File: ansi.c Progetto: AVLeo/libav
/**
 * Execute ANSI escape code
 * @return 0 on success, negative on error
 */
static int execute_code(AVCodecContext * avctx, int c)
{
    AnsiContext *s = avctx->priv_data;
    int ret, i;
    int width = 0;
    int height = 0;

    switch(c) {
    case 'A': //Cursor Up
        s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0);
        break;
    case 'B': //Cursor Down
        s->y = FFMIN(s->y + (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), avctx->height - s->font_height);
        break;
    case 'C': //Cursor Right
        s->x = FFMIN(s->x + (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), avctx->width  - FONT_WIDTH);
        break;
    case 'D': //Cursor Left
        s->x = FFMAX(s->x - (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), 0);
        break;
    case 'H': //Cursor Position
    case 'f': //Horizontal and Vertical Position
        s->y = s->nb_args > 0 ? av_clip((s->args[0] - 1)*s->font_height, 0, avctx->height - s->font_height) : 0;
        s->x = s->nb_args > 1 ? av_clip((s->args[1] - 1)*FONT_WIDTH,     0, avctx->width  - FONT_WIDTH) : 0;
        break;
    case 'h': //set creen mode
    case 'l': //reset screen mode
        if (s->nb_args < 2)
            s->args[0] = DEFAULT_SCREEN_MODE;
        switch(s->args[0]) {
        case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows)
            s->font = ff_cga_font;
            s->font_height = 8;
            width  = 40<<3;
            height = 25<<3;
            break;
        case 2: case 3: //640x400 (25 rows)
            s->font = ff_vga16_font;
            s->font_height = 16;
            width  = 80<<3;
            height = 25<<4;
            break;
        case 6: case 14: //640x200 (25 rows)
            s->font = ff_cga_font;
            s->font_height = 8;
            width  = 80<<3;
            height = 25<<3;
            break;
        case 7: //set line wrapping
            break;
        case 15: case 16: //640x350 (43 rows)
            s->font = ff_cga_font;
            s->font_height = 8;
            width  = 80<<3;
            height = 43<<3;
            break;
        case 17: case 18: //640x480 (60 rows)
            s->font = ff_cga_font;
            s->font_height = 8;
            width  = 80<<3;
            height = 60<<4;
            break;
        default:
            avpriv_request_sample(avctx, "Unsupported screen mode");
        }
        if (width != 0 && height != 0 &&
            (width != avctx->width || height != avctx->height)) {
            av_frame_unref(s->frame);
            ret = ff_set_dimensions(avctx, width, height);
            if (ret < 0)
                return ret;
            ret = ff_get_buffer(avctx, s->frame, AV_GET_BUFFER_FLAG_REF);
            if (ret < 0) {
                av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                return ret;
            }
            s->frame->pict_type           = AV_PICTURE_TYPE_I;
            s->frame->palette_has_changed = 1;
            memcpy(s->frame->data[1], ff_cga_palette, 16 * 4);
            erase_screen(avctx);
        } else if (c == 'l') {
            erase_screen(avctx);
        }
        break;
    case 'J': //Erase in Page
        switch (s->args[0]) {
        case 0:
            erase_line(avctx, s->x, avctx->width - s->x);
            if (s->y < avctx->height - s->font_height)
                memset(s->frame->data[0] + (s->y + s->font_height)*s->frame->linesize[0],
                    DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame->linesize[0]);
            break;
        case 1:
            erase_line(avctx, 0, s->x);
            if (s->y > 0)
                memset(s->frame->data[0], DEFAULT_BG_COLOR, s->y * s->frame->linesize[0]);
            break;
        case 2:
            erase_screen(avctx);
        }
        break;
    case 'K': //Erase in Line
        switch(s->args[0]) {
        case 0:
            erase_line(avctx, s->x, avctx->width - s->x);
            break;
        case 1:
            erase_line(avctx, 0, s->x);
            break;
        case 2:
            erase_line(avctx, 0, avctx->width);
        }
        break;
    case 'm': //Select Graphics Rendition
        if (s->nb_args == 0) {
            s->nb_args = 1;
            s->args[0] = 0;
        }
        for (i = 0; i < FFMIN(s->nb_args, MAX_NB_ARGS); i++) {
            int m = s->args[i];
            if (m == 0) {
                s->attributes = 0;
                s->fg = DEFAULT_FG_COLOR;
                s->bg = DEFAULT_BG_COLOR;
            } else if (m == 1 || m == 2 || m == 4 || m == 5 || m == 7 || m == 8) {
                s->attributes |= 1 << (m - 1);
            } else if (m >= 30 && m <= 38) {
                s->fg = ansi_to_cga[m - 30];
            } else if (m == 39) {
                s->fg = ansi_to_cga[DEFAULT_FG_COLOR];
            } else if (m >= 40 && m <= 47) {
                s->bg = ansi_to_cga[m - 40];
            } else if (m == 49) {
                s->fg = ansi_to_cga[DEFAULT_BG_COLOR];
            } else {
                avpriv_request_sample(avctx, "Unsupported rendition parameter");
            }
        }
        break;
    case 'n': //Device Status Report
    case 'R': //report current line and column
        /* ignore */
        break;
    case 's': //Save Cursor Position
        s->sx = s->x;
        s->sy = s->y;
        break;
    case 'u': //Restore Cursor Position
        s->x = av_clip(s->sx, 0, avctx->width  - FONT_WIDTH);
        s->y = av_clip(s->sy, 0, avctx->height - s->font_height);
        break;
    default:
        avpriv_request_sample(avctx, "Unknown escape code");
        break;
    }
    return 0;
}
Esempio n. 7
0
void in_term(struct terminal *term)
{
    struct event *ev;
    int r;
    unsigned char *iq;
    if ((unsigned)term->qlen + ALLOC_GR > MAXINT) overalloc();
    iq = mem_realloc(term->input_queue, term->qlen + ALLOC_GR);
    term->input_queue = iq;
    if ((r = read(term->fdin, iq + term->qlen, ALLOC_GR)) <= 0) {
        if (r == -1 && errno != ECONNRESET) error("ERROR: error %d on terminal: could not read event", errno);
        destroy_terminal(term);
        return;
    }
    term->qlen += r;
test_queue:
    if ((size_t)term->qlen < sizeof(struct event)) return;
    ev = (struct event *)iq;
    r = sizeof(struct event);
    if (ev->ev != EV_INIT && ev->ev != EV_RESIZE && ev->ev != EV_REDRAW && ev->ev != EV_KBD && ev->ev != EV_MOUSE && ev->ev != EV_ABORT) {
        error("ERROR: error on terminal: bad event %d", ev->ev);
        goto mm;
    }
    if (ev->ev == EV_INIT) {
        int init_len;
        if ((size_t)term->qlen < sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int)) return;
        init_len = *(int *)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + sizeof(int));
        if ((size_t)term->qlen < sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int) + init_len) return;
        memcpy(term->term, iq + sizeof(struct event), MAX_TERM_LEN);
        term->term[MAX_TERM_LEN - 1] = 0;
        memcpy(term->cwd, iq + sizeof(struct event) + MAX_TERM_LEN, MAX_CWD_LEN);
        term->cwd[MAX_CWD_LEN - 1] = 0;
        term->environment = *(int *)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN);
        ev->b = (long)(iq + sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + sizeof(int));
        r = sizeof(struct event) + MAX_TERM_LEN + MAX_CWD_LEN + 2 * sizeof(int) + init_len;
        sync_term_specs();
    }
    if (ev->ev == EV_REDRAW || ev->ev == EV_RESIZE || ev->ev == EV_INIT) {
        struct window *win;
send_redraw:
        if (ev->x < 0 || ev->y < 0) {
            error("ERROR: bad terminal size: %d, %d", (int)ev->x, (int)ev->y);
            goto mm;
        }
        alloc_term_screen(term, ev->x, ev->y);
        clear_terminal(term);
        erase_screen(term);
        term->redrawing = 1;
        foreachback(win, term->windows) win->handler(win, ev, 0);
        term->redrawing = 0;
    }
    if (ev->ev == EV_KBD || ev->ev == EV_MOUSE) {
        if (ev->ev == EV_KBD && upcase(ev->x) == 'L' && ev->y == KBD_CTRL) {
            ev->ev = EV_REDRAW;
            ev->x = term->x;
            ev->y = term->y;
            goto send_redraw;
        }
        else if (ev->ev == EV_KBD && ev->x == KBD_CTRL_C) ((struct window *)term->windows.prev)->handler(term->windows.prev, ev, 0);
        else ((struct window *)term->windows.next)->handler(term->windows.next, ev, 0);
    }
    if (ev->ev == EV_ABORT) {
        destroy_terminal(term);
        return;
    }
    /*redraw_screen(term);*/
mm:
    if (term->qlen == r) term->qlen = 0;
    else memmove(iq, iq + r, term->qlen -= r);
    goto test_queue;
}
Esempio n. 8
0
void redraw_terminal_cls(struct terminal *term)
{
    erase_screen(term);
    alloc_term_screen(term, term->x, term->y);
    redraw_terminal_all(term);
}
Esempio n. 9
0
/* Handler for control sequencie introducer, "ESC [" */
static void control_escape_csi(char ch)
{
	switch (ch)
	{
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		console->params[console->param_count] = 10 * console->params[console->param_count] + (ch - '0');
		break;

	case ';':
		if (console->param_count + 1 == CONSOLE_MAX_PARAMS)
			log_error("Too many console parameters.\n");
		else
			console->param_count++;
		break;

	case 'A': /* CUU */
		move_up(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case 'B': /* CUD */
	case 'e': /* VPR */
		move_down(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case 'C': /* CUF */
	case 'a': /* HPR */
		move_right(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case 'D': /* CUB */
		move_left(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case 'd': /* VPA */
	{
		int y = console->params[0]? console->params[0]: 1;
		if (y > console->height)
			y = console->height;
		set_pos(console->x, y - 1);
		console->processor = NULL;
		break;
	}

	case 'G': /* CHA */
	case '`': /* HPA */
	{
		int x = console->params[0] ? console->params[0] : 1;
		if (x > console->width)
			x = console->width;
		set_pos(x - 1, console->y);
		console->processor = NULL;
		break;
	}

	case 'H':
	case 'f':
		/* Zero or one both represents the first row/column */
		if (console->params[0] > 0)
			console->params[0]--;
		if (console->params[1] > 0)
			console->params[1]--;
		if (console->origin_mode)
			set_pos(console->params[1], console->scroll_top + console->params[0]);
		else
			set_pos(console->params[1], console->params[0]);
		console->processor = NULL;
		break;

	case 'h':
		if (console->private_mode)
			change_private_mode(console->params[0], 1);
		else
			change_mode(console->params[0], 1);
		console->processor = NULL;
		break;

	case 'J':
		erase_screen(console->params[0]);
		console->processor = NULL;
		break;

	case 'K':
		erase_line(console->params[0]);
		console->processor = NULL;
		break;

	case 'l':
		if (console->private_mode)
			change_private_mode(console->params[0], 0);
		else
			change_mode(console->params[0], 0);
		console->processor = NULL;
		break;

	case 'L': /* IL */
		insert_line(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case 'M': /* DL */
		delete_line(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case '@': /* ICH */
		insert_character(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case 'P': /* DCH */
		delete_character(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case 'm':
		for (int i = 0; i <= console->param_count; i++)
		{
			switch (console->params[i])
			{
			case 0: /* Reset */
				console->bright = 0;
				console->reverse = 0;
				console->foreground = 7;
				console->background = 0;
				break;

			case 1:
				console->bright = 1;
				break;

			case 2:
				console->bright = 0;
				break;

			case 7:
				console->reverse = 1;
				break;

			case 27:
				console->reverse = 0;
				break;

			case 30:
			case 31:
			case 32:
			case 33:
			case 34:
			case 35:
			case 36:
			case 37:
				console->foreground = console->params[i] - 30;
				break;

			case 40:
			case 41:
			case 42:
			case 43:
			case 44:
			case 45:
			case 46:
			case 47:
				console->background = console->params[i] - 40;
				break;

			default:
				log_error("Unknown console attribute: %d\n", console->params[i]);
			}
		}
		/* Set updated text attribute */
		SetConsoleTextAttribute(console->out, get_text_attribute(console));
		console->processor = NULL;
		break;

	case 'r':
		if (console->params[0] == 0)
			console->params[0] = 1;
		if (console->params[1] == 0)
			console->params[1] = console->height;
		console->scroll_full_screen = (console->params[0] == 1 && console->params[1] == console->height);
		console->scroll_top = console->params[0] - 1;
		console->scroll_bottom = console->params[1] - 1;
		set_pos(0, 0);
		console->processor = NULL;
		break;

	case 'S': /* SU */
		scroll_up(console->params[0]? console->params[0]: 1);
		console->processor = NULL;
		break;

	case '?':
		console->private_mode = 1;
		break;

	default:
		log_error("control_escape_csi(): Unhandled character %c\n", ch);
		console->processor = NULL;
	}
}
Esempio n. 10
0
/**
 * Push one byte through the VT52 emulator.
 *
 * @param from_modem one byte from the remote side.
 * @param to_screen if the return is Q_EMUL_FSM_ONE_CHAR or
 * Q_EMUL_FSM_MANY_CHARS, then to_screen will have a character to display on
 * the screen.
 * @return one of the Q_EMULATION_STATUS constants.  See emulation.h.
 */
Q_EMULATION_STATUS vt52(const unsigned char from_modem, wchar_t * to_screen) {
    static unsigned char *count;
    static attr_t attributes;
    int new_row;
    int new_col;
    unsigned char from_modem2;

    /*
     * The VT52 spec only supports 7-bit ASCII. Strip the high bit off every
     * character.
     */
    from_modem2 = from_modem & 0x7F;

    DLOG(("STATE: %d CHAR: 0x%02x '%c'\n", scan_state, from_modem2,
          from_modem2));

vt52_start:

    switch (scan_state) {

    case SCAN_NONE:
        /*
         * ESC
         */
        if (from_modem2 == C_ESC) {
            save_char(from_modem2, to_screen);
            scan_state = SCAN_ESC;
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        /*
         * Only a few control chars to handle here.  CR and LF are in
         * emulation.c .
         */
        if (from_modem2 == 0x05) {

            DLOG(("Enquire\n"));

            /*
             * ENQ - transmit the answerback message.
             */
            qodem_write(q_child_tty_fd, get_option(Q_OPTION_ENQ_ANSWERBACK),
                        strlen(get_option(Q_OPTION_ENQ_ANSWERBACK)), Q_TRUE);
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 0x08) {

            DLOG(("Backspace\n"));

            /*
             * Backspace.
             */
            cursor_left(1, Q_FALSE);
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 0x09) {

            DLOG(("Tab\n"));

            /*
             * Tab.
             */
            while (q_status.cursor_x < 80) {
                cursor_right(1, Q_FALSE);
                if (q_status.cursor_x % 8 == 0) {
                    break;
                }
            }

            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 0x7F) {

            DLOG(("Del\n"));

            /*
             * Del - consume but do nothing.
             */
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        /*
         * Any other control characters.
         */
        if (iscntrl(from_modem2)) {
            /*
             * Consume but do nothing.
             */
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        /*
         * This is a printable character.
         */
        *to_screen = map_character(from_modem2);
        return Q_EMUL_FSM_ONE_CHAR;

    case SCAN_Y_1:
        save_char(from_modem2, to_screen);
        scan_state = SCAN_Y_2;
        return Q_EMUL_FSM_NO_CHAR_YET;

    case SCAN_Y_2:
        /*
         * q_emul_buffer[0] = ESC
         * q_emul_buffer[1] = 'Y'
         */
        new_row = q_emul_buffer[2] - 32;
        new_col = from_modem2 - 32;
        if (new_row < 0) {
            new_row = 0;
        }
        if (new_col < 0) {
            new_col = 0;
        }

        DLOG(("Cursor position: %d %d\n", new_row, new_col));

        cursor_position(new_row, new_col);
        clear_state(to_screen);
        return Q_EMUL_FSM_NO_CHAR_YET;

    case SCAN_ESC:

        if (from_modem2 == 'A') {

            DLOG(("Cursor up\n"));

            cursor_up(1, Q_FALSE);
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'B') {

            DLOG(("Cursor down\n"));

            cursor_down(1, Q_FALSE);
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'C') {

            DLOG(("Cursor right\n"));

            cursor_right(1, Q_FALSE);
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'D') {

            DLOG(("Cursor left\n"));

            cursor_left(1, Q_FALSE);
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'E') {

            DLOG(("Erase entire screen\n"));

            /*
             * Cursor position to (0,0) and erase entire screen.
             */
            cursor_formfeed();
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'F') {

            DLOG(("Graphics mode ON\n"));

            graphics_mode = Q_TRUE;
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'G') {

            DLOG(("Graphics mode OFF\n"));

            graphics_mode = Q_FALSE;
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'H') {

            DLOG(("Cursor home\n"));

            cursor_position(0, 0);
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'I') {

            DLOG(("Reverse linefeed\n"));

            /*
             * Move up one column, inserting a line if already at the top.
             */
            if (q_status.cursor_y == 0) {
                scroll_down(1);
            } else {
                cursor_up(1, Q_FALSE);
            }

            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'J') {

            DLOG(("Erase to end of screen\n"));

            /*
             * Erase from here to end of screen.
             */
            erase_screen(q_status.cursor_y, q_status.cursor_x,
                         HEIGHT - STATUS_HEIGHT - 1, WIDTH - 1, Q_FALSE);

            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'K') {

            DLOG(("Erase to end of line\n"));

            /*
             * Erase from here to end of line.
             */
            erase_line(q_status.cursor_x, q_scrollback_current->length,
                       Q_FALSE);

            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'Y') {
            /*
             * Cursor position.
             */
            save_char(from_modem2, to_screen);
            scan_state = SCAN_Y_1;
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'Z') {

            DLOG(("DECID\n"));

            /*
             * Identify
             */

            /*
             * Note the VT100 and above will send <ESC>/Z, but the DECScope
             * manual claims the VT52 will send <ESC>/K if it does not have
             * an "integral electrolytic copier" (an internal printer that
             * used wet paper).
             */
            qodem_write(q_child_tty_fd, "\033/K", 3, Q_TRUE);

            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == '=') {

            DLOG(("Alternate keypad ON\n"));

            q_vt52_alternate_keypad_mode = Q_TRUE;
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == '>') {

            DLOG(("Alternate keypad OFF\n"));

            q_vt52_alternate_keypad_mode = Q_FALSE;
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == '[') {
            if (q_status.vt52_color == Q_TRUE) {
                /*
                 * Fall into SCAN_CSI only if VT52_COLOR is enabled.
                 */
                save_char(from_modem2, to_screen);
                scan_state = SCAN_CSI;
                return Q_EMUL_FSM_NO_CHAR_YET;
            }

            DLOG(("Hold screen mode ON\n"));

            q_status.hold_screen_mode = Q_TRUE;
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == '\\') {

            DLOG(("Hold screen mode OFF\n"));

            q_status.hold_screen_mode = Q_FALSE;
            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        break;

    case SCAN_CSI:
        /*
         * We are only going to support CSI Pn [ ; Pn ... ] m a.k.a. ANSI
         * Select Graphics Rendition.  We can see only a digit or 'm'.
         */
        if (q_isdigit(from_modem2)) {
            /*
             * Save the position for the counter.
             */
            count = q_emul_buffer + q_emul_buffer_n;
            save_char(from_modem2, to_screen);
            scan_state = SCAN_CSI_PARAM;
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'm') {
            /*
             * ESC [ m mean ESC [ 0 m, all attributes off.
             */

            DLOG(("ANSI SGR: reset\n"));

            q_current_color =
                Q_A_NORMAL | scrollback_full_attr(Q_COLOR_CONSOLE_TEXT);

            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        /*
         * This means we entered HOLD SCREEN mode.
         */

        DLOG(("Hold screen mode ON\n"));

        q_status.hold_screen_mode = Q_TRUE;

        /*
         * Reprocess the character from the top.
         */
        clear_state(to_screen);
        goto vt52_start;

    case SCAN_CSI_PARAM:
        /*
         * Following through on the SGR code, we are now looking only for a
         * digit, semicolon, or 'm'
         *
         */
        if ((q_isdigit(from_modem2)) || (from_modem2 == ';')) {
            save_char(from_modem2, to_screen);
            scan_state = SCAN_CSI_PARAM;
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        if (from_modem2 == 'm') {

            DLOG(("ANSI SGR: change text attributes\n"));

            /*
             * Text attributes.
             */
            if (ansi_color(&attributes, &count) == Q_TRUE) {
                q_current_color = attributes;
            } else {
                break;
            }

            clear_state(to_screen);
            return Q_EMUL_FSM_NO_CHAR_YET;
        }

        break;
    }

    /*
     * This point means we got most, but not all, of a sequence.
     */
    q_emul_buffer[q_emul_buffer_n] = from_modem2;
    q_emul_buffer_n++;
    *to_screen = q_emul_buffer[q_emul_buffer_i];
    q_emul_buffer_i++;
    scan_state = SCAN_NONE;

    /*
     * Special case: one character returns Q_EMUL_FSM_ONE_CHAR.
     */
    if (q_emul_buffer_n == 1) {
        q_emul_buffer_i = 0;
        q_emul_buffer_n = 0;
        return Q_EMUL_FSM_ONE_CHAR;
    }

    return Q_EMUL_FSM_MANY_CHARS;
}
Esempio n. 11
0
static void
create_subimages(Gif_Stream *gfs, int optimize_flags, int save_uncompressed)
{
  unsigned screen_size;
  Gif_Image *last_gfi;
  int next_data_valid;
  uint16_t *previous_data = 0;
  int local_color_tables = 0;

  screen_size = (unsigned) screen_width * (unsigned) screen_height;

  next_data = Gif_NewArray(uint16_t, screen_size);
  next_data_valid = 0;

  /* do first image. Remember to uncompress it if necessary */
  erase_screen(last_data);
  erase_screen(this_data);
  last_gfi = 0;

  /* PRECONDITION:
     previous_data -- garbage
     last_data -- optimized image after disposal of previous optimized frame
     this_data -- input image after disposal of previous input frame
     next_data -- input image after application of current input frame,
                  if next_image_valid */
  for (image_index = 0; image_index < gfs->nimages; image_index++) {
    Gif_Image *gfi = gfs->images[image_index];
    Gif_OptData *subimage = new_opt_data();
    if (gfi->local)
        local_color_tables = 1;

    /* save previous data if necessary */
    if (gfi->disposal == GIF_DISPOSAL_PREVIOUS
        || (local_color_tables && image_index > 0
            && last_gfi->disposal > GIF_DISPOSAL_ASIS)) {
      if (!previous_data)
	previous_data = Gif_NewArray(uint16_t, screen_size);
      memcpy(previous_data, this_data, sizeof(uint16_t) * screen_size);
    }

    /* set this_data equal to the current image */
    if (next_data_valid) {
      uint16_t *temp = this_data;
      this_data = next_data;
      next_data = temp;
      next_data_valid = 0;
    } else
      apply_frame(this_data, gfi, 0, save_uncompressed);

 retry_frame:
    /* find minimum area of difference between this image and last image */
    subimage->disposal = GIF_DISPOSAL_ASIS;
    if (image_index > 0)
      find_difference_bounds(subimage, gfi, last_gfi);
    else {
      Gif_OptBounds ob = safe_bounds(gfi);
      subimage->left = ob.left;
      subimage->top = ob.top;
      subimage->width = ob.width;
      subimage->height = ob.height;
    }

    /* might need to expand difference border if transparent background &
       background disposal */
    if ((gfi->disposal == GIF_DISPOSAL_BACKGROUND
	 || gfi->disposal == GIF_DISPOSAL_PREVIOUS)
	&& background == TRANSP
	&& image_index < gfs->nimages - 1) {
      /* set up next_data */
      Gif_Image *next_gfi = gfs->images[image_index + 1];
      apply_frame_disposal(next_data, this_data, previous_data, gfi);
      apply_frame(next_data, next_gfi, 0, save_uncompressed);
      next_data_valid = 1;
      /* expand border as necessary */
      if (expand_difference_bounds(subimage, gfi))
	subimage->disposal = GIF_DISPOSAL_BACKGROUND;
    }

    fix_difference_bounds(subimage);

    /* set map of used colors */
    {
      int use_transparency = (optimize_flags & GT_OPT_MASK) > 1
          && image_index > 0;
      if (image_index == 0 && background == TRANSP)
	use_transparency = 2;
      get_used_colors(subimage, use_transparency);
      /* Gifsicle's optimization strategy normally creates frames with ASIS
         or BACKGROUND disposal (not PREVIOUS disposal). However, there are
         cases when PREVIOUS disposal is strictly required, or a frame would
         require more than 256 colors. Detect this case and try to recover. */
      if (subimage->required_color_count > 256) {
          if (image_index > 0 && local_color_tables) {
              Gif_OptData *subimage = (Gif_OptData*) last_gfi->user_data;
              if ((last_gfi->disposal == GIF_DISPOSAL_PREVIOUS
                   || last_gfi->disposal == GIF_DISPOSAL_BACKGROUND)
                  && subimage->disposal != last_gfi->disposal) {
                  subimage->disposal = last_gfi->disposal;
                  memcpy(last_data, previous_data, sizeof(uint16_t) * screen_size);
                  goto retry_frame;
              }
          }
          fatal_error("%d colors required in a frame (256 is max)",
                      subimage->required_color_count);
      }
    }

    gfi->user_data = subimage;
    last_gfi = gfi;

    /* Apply optimized disposal to last_data and unoptimized disposal to
       this_data. Before 9.Dec.1998 I applied unoptimized disposal uniformly
       to both. This led to subtle bugs. After all, to determine bounds, we
       want to compare the current image (only obtainable through unoptimized
       disposal) with what WILL be left after the previous OPTIMIZED image's
       disposal. This fix is repeated in create_new_image_data */
    if (subimage->disposal == GIF_DISPOSAL_BACKGROUND)
      fill_data_area_subimage(last_data, background, subimage);
    else
      copy_data_area_subimage(last_data, this_data, subimage);

    if (last_gfi->disposal == GIF_DISPOSAL_BACKGROUND)
      fill_data_area(this_data, background, last_gfi);
    else if (last_gfi->disposal == GIF_DISPOSAL_PREVIOUS) {
      uint16_t *temp = previous_data;
      previous_data = this_data;
      this_data = temp;
    }
  }

  Gif_DeleteArray(next_data);
  if (previous_data)
    Gif_DeleteArray(previous_data);
}
Esempio n. 12
0
static void
create_new_image_data(Gif_Stream *gfs, int optimize_flags)
{
  Gif_Image cur_unopt_gfi;	/* placehoder; maintains pre-optimization
				   image size so we can apply background
				   disposal */
  unsigned screen_size = (unsigned) screen_width * (unsigned) screen_height;
  uint16_t *previous_data = 0;
  Gif_CompressInfo gcinfo = gif_write_info;
  if ((optimize_flags & GT_OPT_MASK) >= 3)
      gcinfo.flags |= GIF_WRITE_OPTIMIZE;

  gfs->global = out_global_map;

  /* do first image. Remember to uncompress it if necessary */
  erase_screen(last_data);
  erase_screen(this_data);

  for (image_index = 0; image_index < gfs->nimages; image_index++) {
    Gif_Image *cur_gfi = gfs->images[image_index];
    Gif_OptData *opt = (Gif_OptData *)cur_gfi->user_data;
    int was_compressed = (cur_gfi->img == 0);

    /* save previous data if necessary */
    if (cur_gfi->disposal == GIF_DISPOSAL_PREVIOUS) {
      if (!previous_data)
          previous_data = Gif_NewArray(uint16_t, screen_size);
      copy_data_area(previous_data, this_data, cur_gfi);
    }

    /* set up this_data to be equal to the current image */
    apply_frame(this_data, cur_gfi, 0, 0);

    /* save actual bounds and disposal from unoptimized version so we can
       apply the disposal correctly next time through */
    cur_unopt_gfi = *cur_gfi;

    /* set bounds and disposal from optdata */
    Gif_ReleaseUncompressedImage(cur_gfi);
    cur_gfi->left = opt->left;
    cur_gfi->top = opt->top;
    cur_gfi->width = opt->width;
    cur_gfi->height = opt->height;
    cur_gfi->disposal = opt->disposal;
    if (image_index > 0)
	cur_gfi->interlace = 0;

    /* find the new image's colormap and then make new data */
    {
      uint8_t *map = prepare_colormap(cur_gfi, opt->needed_colors);
      uint8_t *data = Gif_NewArray(uint8_t, (size_t) cur_gfi->width * (size_t) cur_gfi->height);
      Gif_SetUncompressedImage(cur_gfi, data, Gif_DeleteArrayFunc, 0);

      /* don't use transparency on first frame */
      if ((optimize_flags & GT_OPT_MASK) > 1 && image_index > 0
	  && cur_gfi->transparent >= 0)
	transp_frame_data(gfs, cur_gfi, map, optimize_flags, &gcinfo);
      else
	simple_frame_data(cur_gfi, map);

      if (cur_gfi->img) {
	if (was_compressed || (optimize_flags & GT_OPT_MASK) > 1) {
	  Gif_FullCompressImage(gfs, cur_gfi, &gcinfo);
	  Gif_ReleaseUncompressedImage(cur_gfi);
	} else			/* bug fix 22.May.2001 */
	  Gif_ReleaseCompressedImage(cur_gfi);
      }

      Gif_DeleteArray(map);
    }

    delete_opt_data(opt);
    cur_gfi->user_data = 0;

    /* Set up last_data and this_data. last_data must contain this_data + new
       disposal. this_data must contain this_data + old disposal. */
    if (cur_gfi->disposal == GIF_DISPOSAL_NONE
	|| cur_gfi->disposal == GIF_DISPOSAL_ASIS)
      copy_data_area(last_data, this_data, cur_gfi);
    else if (cur_gfi->disposal == GIF_DISPOSAL_BACKGROUND)
      fill_data_area(last_data, background, cur_gfi);
    else if (cur_gfi->disposal != GIF_DISPOSAL_PREVIOUS)
      assert(0 && "optimized frame has strange disposal");

    if (cur_unopt_gfi.disposal == GIF_DISPOSAL_BACKGROUND)
      fill_data_area(this_data, background, &cur_unopt_gfi);
    else if (cur_unopt_gfi.disposal == GIF_DISPOSAL_PREVIOUS)
      copy_data_area(this_data, previous_data, &cur_unopt_gfi);
  }

  if (previous_data)
      Gif_DeleteArray(previous_data);
}
Esempio n. 13
0
static void
create_subimages(Gif_Stream *gfs, int optimize_flags, int save_uncompressed)
{
  int screen_size;
  Gif_Image *last_gfi;
  int next_data_valid;
  uint16_t *previous_data = 0;

  screen_size = screen_width * screen_height;

  next_data = Gif_NewArray(uint16_t, screen_size);
  next_data_valid = 0;

  /* do first image. Remember to uncompress it if necessary */
  erase_screen(last_data);
  erase_screen(this_data);
  last_gfi = 0;

  /* PRECONDITION: last_data, previous_data -- garbage
     this_data -- equal to image data after disposal of previous image
     next_data -- equal to image data for next image if next_image_valid */
  for (image_index = 0; image_index < gfs->nimages; image_index++) {
    Gif_Image *gfi = gfs->images[image_index];
    Gif_OptData *subimage = new_opt_data();

    /* save previous data if necessary */
    if (gfi->disposal == GIF_DISPOSAL_PREVIOUS) {
      if (!previous_data)
	previous_data = Gif_NewArray(uint16_t, screen_size);
      memcpy(previous_data, this_data, sizeof(uint16_t) * screen_size);
    }

    /* set this_data equal to the current image */
    if (next_data_valid) {
      uint16_t *temp = this_data;
      this_data = next_data;
      next_data = temp;
      next_data_valid = 0;
    } else
      apply_frame(this_data, gfi, 0, save_uncompressed);

    /* find minimum area of difference between this image and last image */
    subimage->disposal = GIF_DISPOSAL_ASIS;
    if (image_index > 0)
      find_difference_bounds(subimage, gfi, last_gfi);
    else {
      Gif_OptBounds ob = safe_bounds(gfi);
      subimage->left = ob.left;
      subimage->top = ob.top;
      subimage->width = ob.width;
      subimage->height = ob.height;
    }

    /* might need to expand difference border if transparent background &
       background disposal */
    if ((gfi->disposal == GIF_DISPOSAL_BACKGROUND
	 || gfi->disposal == GIF_DISPOSAL_PREVIOUS)
	&& background == TRANSP
	&& image_index < gfs->nimages - 1) {
      /* set up next_data */
      Gif_Image *next_gfi = gfs->images[image_index + 1];
      apply_frame_disposal(next_data, this_data, previous_data, gfi);
      apply_frame(next_data, next_gfi, 0, save_uncompressed);
      next_data_valid = 1;
      /* expand border as necessary */
      if (expand_difference_bounds(subimage, gfi))
	subimage->disposal = GIF_DISPOSAL_BACKGROUND;
    }

    fix_difference_bounds(subimage);

    /* set map of used colors */
    {
      int use_transparency = (optimize_flags & GT_OPT_MASK) > 1 && image_index > 0;
      if (image_index == 0 && background == TRANSP)
	use_transparency = 2;
      get_used_colors(subimage, use_transparency);
    }

    gfi->user_data = subimage;
    last_gfi = gfi;

    /* Apply optimized disposal to last_data and unoptimized disposal to
       this_data. Before 9.Dec.1998 I applied unoptimized disposal uniformly
       to both. This led to subtle bugs. After all, to determine bounds, we
       want to compare the current image (only obtainable through unoptimized
       disposal) with what WILL be left after the previous OPTIMIZED image's
       disposal. This fix is repeated in create_new_image_data */
    if (subimage->disposal == GIF_DISPOSAL_BACKGROUND)
      fill_data_area_subimage(last_data, background, subimage);
    else
      copy_data_area_subimage(last_data, this_data, subimage);

    if (last_gfi->disposal == GIF_DISPOSAL_BACKGROUND)
      fill_data_area(this_data, background, last_gfi);
    else if (last_gfi->disposal == GIF_DISPOSAL_PREVIOUS) {
      uint16_t *temp = previous_data;
      previous_data = this_data;
      this_data = temp;
    }
  }

  Gif_DeleteArray(next_data);
  if (previous_data)
    Gif_DeleteArray(previous_data);
}
Esempio n. 14
0
static void change_private_mode(int mode, int set)
{
	switch (mode)
	{
	case 1: /* DECCKM */
		console->cursor_key_mode = set;
		break;

	case 3:
		if (set) /* 132 column mode */
			console_set_size(132, 24);
		else /* 80 column mode */
			console_set_size(80, 24);
		/* Clear window content and reset scrolling regions */
		erase_screen(2);
		set_pos(0, 0);
		break;
		
	case 6:
		console->origin_mode = set;
		break;

	case 7:
		console->wraparound_mode = set;
		break;

	case 47:
		if (set)
			switch_to_alternate_buffer();
		else
			switch_to_normal_buffer();
		break;

	case 1047:
		if (set)
		{
			if (console->out == console->normal_buffer)
			{
				switch_to_alternate_buffer();
				erase_screen(ERASE_SCREEN_BEGIN_TO_END);
			}
		}
		else
		{
			if (console->out == console->alternate_buffer)
			{
				switch_to_normal_buffer();
				erase_screen(ERASE_SCREEN_BEGIN_TO_END);
			}
		}
		break;

	case 1048:
		if (set)
			save_cursor();
		else
			restore_cursor();
		break;

	case 1049:
		if (set)
		{
			save_cursor();
			if (console->out == console->normal_buffer)
			{
				switch_to_alternate_buffer();
				erase_screen(ERASE_SCREEN_BEGIN_TO_END);
			}
		}
		else
		{
			if (console->out == console->alternate_buffer)
			{
				switch_to_normal_buffer();
				erase_screen(ERASE_SCREEN_BEGIN_TO_END);
			}
			restore_cursor();
		}
		break;

	default:
		log_error("change_private_mode(): private mode %d not supported.\n", mode);
	}
}
Esempio n. 15
0
static bool
process_vt100_command(const char c, bool seenBracket, int32 *args,
	int32 argCount)
{
	bool ret = true;

//	kprintf("process_vt100_command: c '%c', argCount %ld, arg[0] %ld, arg[1] %ld, seenBracket %d\n",
//		c, argCount, args[0], args[1], seenBracket);

	if (seenBracket) {
		switch (c) {
			case 'H':	// set cursor position
			case 'f':
			{
				int32 row = argCount > 0 ? args[0] : 1;
				int32 col = argCount > 1 ? args[1] : 1;
				if (row > 0)
					row--;
				if (col > 0)
					col--;
				move_cursor(col, row);
				break;
			}
			case 'A':	// move up
			{
				int32 deltaY = argCount > 0 ? -args[0] : -1;
				if (deltaY == 0)
					deltaY = -1;
				move_cursor(sScreen.x, sScreen.y + deltaY);
				break;
			}
			case 'e':
			case 'B':	// move down
			{
				int32 deltaY = argCount > 0 ? args[0] : 1;
				if (deltaY == 0)
					deltaY = 1;
				move_cursor(sScreen.x, sScreen.y + deltaY);
				break;
			}
			case 'D':	// move left
			{
				int32 deltaX = argCount > 0 ? -args[0] : -1;
				if (deltaX == 0)
					deltaX = -1;
				move_cursor(sScreen.x + deltaX, sScreen.y);
				break;
			}
			case 'a':
			case 'C':	// move right
			{
				int32 deltaX = argCount > 0 ? args[0] : 1;
				if (deltaX == 0)
					deltaX = 1;
				move_cursor(sScreen.x + deltaX, sScreen.y);
				break;
			}
			case '`':
			case 'G':	// set X position
			{
				int32 newX = argCount > 0 ? args[0] : 1;
				if (newX > 0)
					newX--;
				move_cursor(newX, sScreen.y);
				break;
			}
			case 'd':	// set y position
			{
				int32 newY = argCount > 0 ? args[0] : 1;
				if (newY > 0)
					newY--;
				move_cursor(sScreen.x, newY);
				break;
			}
#if 0
			case 's':	// save current cursor
				save_cur(console, false);
				break;
			case 'u':	// restore cursor
				restore_cur(console, false);
				break;
			case 'r':	// set scroll region
			{
				int32 low = argCount > 0 ? args[0] : 1;
				int32 high = argCount > 1 ? args[1] : sScreen.lines;
				if (low <= high)
					set_scroll_region(console, low - 1, high - 1);
				break;
			}
			case 'L':	// scroll virtual down at cursor
			{
				int32 lines = argCount > 0 ? args[0] : 1;
				while (lines > 0) {
					scrdown(console);
					lines--;
				}
				break;
			}
			case 'M':	// scroll virtual up at cursor
			{
				int32 lines = argCount > 0 ? args[0] : 1;
				while (lines > 0) {
					scrup(console);
					lines--;
				}
				break;
			}
#endif
			case 'K':
				if (argCount == 0 || args[0] == 0) {
					// erase to end of line
					erase_line(LINE_ERASE_RIGHT);
				} else if (argCount > 0) {
					if (args[0] == 1)
						erase_line(LINE_ERASE_LEFT);
					else if (args[0] == 2)
						erase_line(LINE_ERASE_WHOLE);
				}
				break;
#if 0
			case 'J':
				if (argCount == 0 || args[0] == 0) {
					// erase to end of screen
					erase_screen(console, SCREEN_ERASE_DOWN);
				} else {
					if (args[0] == 1)
						erase_screen(console, SCREEN_ERASE_UP);
					else if (args[0] == 2)
						erase_screen(console, SCREEN_ERASE_WHOLE);
				}
				break;
#endif
			case 'm':
				if (argCount >= 0)
					set_vt100_attributes(args, argCount);
				break;
			default:
				ret = false;
		}
	} else {
		switch (c) {
#if 0
			case 'c':
				reset_console(console);
				break;
			case 'D':
				rlf(console);
				break;
			case 'M':
				lf(console);
				break;
			case '7':
				save_cur(console, true);
				break;
			case '8':
				restore_cur(console, true);
				break;
#endif
			default:
				ret = false;
		}
	}

	return ret;
}