ftp.nice.ch/pub/next/tools/emulators/vice.0.15.0.NeXT.sd.tgz#/vice-0.15.0/src/arch/msdos/tui.c

This is tui.c in view mode; [Download] [Up]

/*
 * tui.c - A (very) simple text-based user interface.
 *
 * Written by
 *  Ettore Perazzoli (ettore@comm2000.it)
 *
 * This file is part of VICE, the Versatile Commodore Emulator.
 * See README for copyright notice.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307  USA.
 *
 */

#include "vice.h"

#include <sys/farptr.h>
#include <go32.h>
#include <strings.h>
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <pc.h>
#include <keys.h>
#include <stdarg.h>

#include <allegro.h>

#include "tui.h"
#include "utils.h"

/* ------------------------------------------------------------------------- */

static int _tui_input_string(int x, int y, char *buf, int max_length,
			     int displayed_length, int foreground_color,
			     int background_color)
{
    int cursor_pos = 0;
    int scroll_offset = 0;
    int string_length = strlen(buf);
    int need_redisplay = 1;

    tui_set_attr(foreground_color, background_color, 0);
    _setcursortype(_SOLIDCURSOR);
    while (1) {
	int key;

	if (need_redisplay) {
	    tui_display(x, y, displayed_length, "%s", buf + scroll_offset);
	    need_redisplay = 0;
	}
	tui_gotoxy(x + cursor_pos - scroll_offset, y);
	key = getkey();
	switch (key) {
	  case K_Left:
	    if (cursor_pos > 0) {
		cursor_pos--;
		if (cursor_pos < scroll_offset) {
		    scroll_offset = cursor_pos;
		    need_redisplay = 1;
		}
	    }
	    break;
	  case K_Right:
	    if (cursor_pos < string_length) {
		cursor_pos++;
		if (cursor_pos >= (scroll_offset + displayed_length)) {
		    scroll_offset = cursor_pos - displayed_length + 1;
		    need_redisplay = 1;
		}
	    }
	    break;
	  case K_Home:
	    cursor_pos = 0;
	    scroll_offset = 0;
	    need_redisplay = 1;
	    break;
	  case K_End:
	    cursor_pos = string_length;
	    scroll_offset = cursor_pos - displayed_length + 1;
	    if (scroll_offset < 0)
		scroll_offset = 0;
	    need_redisplay = 1;
	    break;
	  case K_BackSpace:
	    if (cursor_pos > 0 && cursor_pos <= string_length) {
		memmove(buf + cursor_pos - 1, buf + cursor_pos,
			string_length - cursor_pos + 1);
		string_length--;
		cursor_pos--;
		if (cursor_pos < scroll_offset)
		    scroll_offset = cursor_pos;
		need_redisplay = 1;
	    }
	    break;
	  case K_Delete:
	    if (cursor_pos < string_length) {
		memmove(buf + cursor_pos, buf + cursor_pos + 1,
			string_length - cursor_pos);
		string_length--;
		need_redisplay = 1;
	    }
	    break;
	  case K_Return:
	    _setcursortype(_NOCURSOR);
	    return 0;
	  case K_Escape:
	    _setcursortype(_NOCURSOR);
	    return -1;
	  default:
	    if (key <= 0xff
		&& isprint((char) key)
		&& string_length < max_length) {
		memmove(buf + cursor_pos + 1, buf + cursor_pos,
			string_length - cursor_pos + 1);
		buf[cursor_pos] = (char) key;
		cursor_pos++;
		string_length++;
		if (cursor_pos - scroll_offset >= displayed_length)
		    scroll_offset = cursor_pos - displayed_length + 1;
		need_redisplay = 1;
	    }
	    break;
	}
    }
}

int tui_input_string(const char *title, const char *prompt, char *buf,
		     int buflen)
{
    int field_width, x, y, width, height, retval;
    tui_area_t backing_store = NULL;

    if (buflen + 1 < tui_num_cols() - 12)
	field_width = buflen + 1;
    else
	field_width = tui_num_cols() - 12;

    width = field_width + 4;
    height = 4;
    x = CENTER_X(width);
    y = CENTER_Y(height);

    tui_display_window(x, y, width, height, REQUESTER_BORDER, REQUESTER_BACK,
		       title, &backing_store);
    tui_set_attr(REQUESTER_FORE, REQUESTER_BACK, 0);
    tui_display(x + 2, y + 1, field_width, prompt);

    retval = _tui_input_string(x + 2, y + 2, buf, buflen, field_width,
			       FIELD_FORE, FIELD_BACK);

    tui_area_put(backing_store, x, y);
    tui_area_free(backing_store);

    return retval;
}

/* ------------------------------------------------------------------------- */

void tui_error(const char *format,...)
{
    int x, y, width, height;
    char str[1024];
    int str_length;
    va_list ap;
    tui_area_t backing_store = NULL;

    va_start(ap, format);
    vsprintf(str, format, ap);
    str_length = strlen(str);
    if (str_length > tui_num_cols() - 10) {
	str_length = tui_num_cols() - 10;
	str[str_length] = 0;
    }
    x = CENTER_X(str_length + 6);
    y = CENTER_Y(5);
    width = str_length + 6;
    height = 5;

    tui_display_window(x, y, width, height, ERROR_BORDER, ERROR_BACK, "Error!",
		       &backing_store);
    tui_set_attr(ERROR_FORE, ERROR_BACK, 0);
    tui_display(CENTER_X(str_length), y + 2, 0, str);
    getkey();

    tui_area_put(backing_store, x, y);
    tui_area_free(backing_store);
}

void tui_message(const char *format,...)
{
    int x, y, width, height;
    char str[1024];
    int str_length;
    va_list ap;
    tui_area_t backing_store = NULL;

    va_start(ap, format);
    vsprintf(str, format, ap);
    str_length = strlen(str);
    if (str_length > tui_num_cols() - 10) {
	str_length = tui_num_cols() - 10;
	str[str_length] = 0;
    }
    x = CENTER_X(str_length + 6);
    y = CENTER_Y(5);
    width = str_length + 6;
    height = 5;

    tui_display_window(x, y, width, height, MESSAGE_BORDER, MESSAGE_BACK,
		       NULL, &backing_store);
    tui_set_attr(MESSAGE_FORE, MESSAGE_BACK, 0);
    tui_display(CENTER_X(str_length), y + 2, 0, str);
    getkey();

    tui_area_put(backing_store, x, y);
    tui_area_free(backing_store);
}

int tui_ask_confirmation(const char *format, ...)
{
    int x, y, width, height;
    char str[1024];
    int str_length;
    va_list ap;
    tui_area_t backing_store = NULL;
    int c;

    va_start(ap, format);
    vsprintf(str, format, ap);
    str_length = strlen(str);
    if (str_length > tui_num_cols() - 10) {
	str_length = tui_num_cols() - 10;
	str[str_length] = 0;
    }
    x = CENTER_X(str_length + 6);
    y = CENTER_Y(5);
    width = str_length + 6;
    height = 5;

    tui_display_window(x, y, width, height, MESSAGE_BORDER, MESSAGE_BACK,
		       NULL, &backing_store);
    tui_set_attr(MESSAGE_FORE, MESSAGE_BACK, 0);
    tui_display(CENTER_X(str_length), y + 2, 0, str);

    do {
        c = getkey();
    } while (toupper(c) != 'Y' && toupper(c) != 'N');

    tui_area_put(backing_store, x, y);
    tui_area_free(backing_store);

    return toupper(c) == 'Y';
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.