예제 #1
0
파일: tuifs.c 프로젝트: AreaScout/vice
static void file_selector_display_item(struct file_list *fl, int num, int first_item_num, int x, int y, int width, int height, int num_cols)
{
    y += (num - first_item_num) % height;
    x += ((num - first_item_num) / height) * width;

    if (num >= fl->num_used_items) {
        tui_hline(x, y, ' ', width);
    } else {
        int len = strlen(fl->items[num].name);

        /* XXX: Assumes `width' is > 5!  */
        if (len > width - 2) {
            char *name = alloca(width - 2 + 1);

            if (fl->items[num].type == FT_DIR) {
                memcpy(name, fl->items[num].name, width - 3);
                name[width - 4] = name[width - 5] = '.';
                name[width - 3] = '/';
            } else {
                memcpy(name, fl->items[num].name, width - 2);
                name[width - 3] = name[width - 4] = '.';
            }
            name[width - 2] = '\0';
            tui_display(x, y, width, " %s ", name);
        } else {
            if (fl->items[num].type == FT_DIR) {
                tui_display(x, y, width, " %s/ ", fl->items[num].name);
            } else {
              tui_display(x, y, width, " %s ", fl->items[num].name);
            }
        }
    }
}
예제 #2
0
파일: tui.c 프로젝트: martinpiper/VICE
void tui_message(const char *format,...)
{
    int x, y, width, height;
    char *str;
    int str_length;
    va_list ap;
    tui_area_t backing_store = NULL;

    va_start(ap, format);
    str = lib_mvsprintf(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);
    lib_free(str);
}
예제 #3
0
파일: tui.c 프로젝트: martinpiper/VICE
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;
}
예제 #4
0
void tui_display_window(int x, int y, int width, int height,
                        int foreground_color, int background_color,
                        const char *title, tui_area_t *backing_store)
{
    int i;

    if (backing_store != NULL) {
        /* 2 more chars on right, 1 more on bottom because of the "shadow".  */
        tui_area_get(backing_store, x, y, width + 2, height + 1);
    }

    tui_make_shadow(x + 2, y + 1, width, height);

    tui_set_attr(foreground_color, background_color, 0);
    tui_put_char(x, y, 0xc9);
    tui_hline(x + 1, y, 0xcd, width - 2);
    tui_put_char(x + width - 1, y, 0xbb);
    tui_put_char(x, y + height - 1, 0xc8);
    tui_hline(x + 1, y + height - 1, 0xcd, width - 2);
    tui_put_char(x + width - 1, y + height - 1, 0xbc);
    for (i = 0; i < height - 2; i++) {
        tui_put_char(x, y + i + 1, 0xba);
        tui_hline(x + 1, y + i + 1, ' ', width - 2);
        tui_put_char(x + width - 1, y + i + 1, 0xba);
    }

    if (!util_check_null_string(title)) {
        int title_x, title_length;

        title_length = strlen(title);
        title_x = x + (width - title_length - 4) / 2;
        tui_display(title_x, y, 0, "\x10 %s \x11", title);
    }
}
예제 #5
0
void tui_clear_screen(void)
{
    int i;

    _setcursortype(_NOCURSOR);

    tui_set_attr(FIRST_LINE_FORE, FIRST_LINE_BACK, 0);

#ifndef UNSTABLE
    tui_display(0, 0, tui_num_cols(), "VICE version %s", VERSION);
#else
    tui_display(0, 0, tui_num_cols(), "VICE version %s (unstable)", VERSION);
#endif

    tui_set_attr(BACKPATTERN_FORE, BACKPATTERN_BACK, 0);
    for (i = 1; i < tui_num_lines() - 1; i++)
        tui_hline(0, i, BACKCHAR, tui_num_cols());
}
예제 #6
0
static TUI_MENU_CALLBACK(keyset_callback)
{
    int direction, number;
    int value;
    char *rname;

    number = (int)param >> 8;
    direction = (int)param & 0xff;
    rname = lib_msprintf("KeySet%d%s", number, joystick_direction_to_string(direction));

    if (been_activated) {
        kbd_code_t key;
        int width = 60, height = 5;
        int x = CENTER_X(width), y = CENTER_Y(height);
        tui_area_t backing_store = NULL;
        char *msg;

        msg = lib_msprintf("Press key for %s%s (Esc for none)...", direction == KEYSET_FIRE ? "" : "direction ", joystick_direction_to_string(direction));
        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(strlen(msg)), y + 2, 0, msg);
        lib_free(msg);

        /* Do not allow Alt as we need it for hotkeys.  */
        do {
            key = grab_key();
        } while (key == K_LEFTALT || key == K_RIGHTALT);

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

        if (key == K_ESC) {
            key = K_NONE;
        }
        resources_set_int(rname, (int)key);
    }

    resources_get_int(rname, &value);
    lib_free(rname);
    return kbd_code_to_string((kbd_code_t)value);
}
예제 #7
0
파일: tui.c 프로젝트: martinpiper/VICE
int tui_ask_confirmation(const char *format, ...)
{
    int x, y, width, height;
    char *str;
    int str_length;
    va_list ap;
    tui_area_t backing_store = NULL;
    int c;

    va_start(ap, format);
    str = lib_mvsprintf(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);

    lib_free(str);

    return toupper(c) == 'Y';
}
예제 #8
0
파일: tui.c 프로젝트: martinpiper/VICE
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;
        }
    }
}
예제 #9
0
파일: tuifs.c 프로젝트: AreaScout/vice
/* FIXME: documentation.  */
char *tui_file_selector(const char *title, const char *directory,
                        const char *pattern, const char *default_item,
                        read_contents_func_type contents_func,
                        char **browse_file_return,
                        unsigned int *browse_file_number_return)
{
    static char *return_path = NULL;
    struct file_list *fl;
    int curr_item, first_item, need_update;
    int x, y, width, height, num_cols, num_lines, field_width;
    int num_files;
    char str[0x100];
    int str_len = 0;
    tui_area_t backing_store = NULL;

    if (contents_func != NULL) {
        *browse_file_return = NULL;
    }

    if (browse_file_number_return != NULL) {
        *browse_file_number_return = 0;
    }

    if (directory != NULL) {
        return_path = lib_stralloc(directory);
    } else {
        return_path = ioutil_current_dir();
    }

    slashize_path(&return_path);

    fl = file_list_read(return_path, pattern);
    if (fl == NULL) {
        return NULL;
    }

    first_item = curr_item = 0;
    num_cols = 4;
    field_width = 18;
    num_lines = 17;
    height = num_lines + 2;
    width = field_width * num_cols + 4;
    num_files = num_cols * num_lines;

    if (default_item != NULL && *default_item) {
        int i;

        for (i = 0; i < fl->num_items; i++) {
            if (!strcasecmp(default_item, fl->items[i].name)) {
                curr_item = i;
                while (curr_item - first_item >= num_files) {
                    first_item += num_lines;
                }
                break;
            }
        }
    }

    x = CENTER_X(width);
    y = CENTER_Y(height);

    need_update = 1;

    tui_area_get(&backing_store, x, y, width + 2, height + 1);

    tui_display_window(x, y, width, height, MENU_BORDER, MENU_BACK, title, NULL);

    while (1) {
        int key;

        tui_set_attr(MENU_FORE, MENU_BACK, 0);
        if (need_update) {
            file_selector_display_path(return_path, x + 1, y + height - 1, width - 2);
            file_selector_update(fl, first_item, x + 2, y + 1, field_width, num_lines, num_cols);
            tui_set_attr(FIRST_LINE_FORE, FIRST_LINE_BACK, 0);
            tui_display(0, tui_num_lines() - 1, tui_num_cols(), "\030\031\033\032: Move  <Enter>: Select  %s<Alt>-<letter>: Change drive", contents_func != NULL ? "<Space>: Preview  " : "");
            need_update = 0;
        }
        tui_set_attr(MENU_FORE, MENU_HIGHLIGHT, 0);
        file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1, field_width, num_lines, num_cols);
        key = getkey();
        tui_set_attr(MENU_FORE, MENU_BACK, 0);
        file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1, field_width, num_lines, num_cols);

        switch (key) {
            case K_Escape:
                tui_area_put(backing_store, x, y);
                tui_area_free(backing_store);
                return NULL;
            case K_Left:
                str_len = 0;
                if (curr_item - num_lines >= 0) {
                    curr_item -= num_lines;
                    if (curr_item < first_item) {
                        if (first_item >= num_lines) {
                            first_item -= num_lines;
                            need_update = 1;
                        } else {
                            curr_item += num_lines;
                        }
                    }
                }
                break;
            case K_Up:
                str_len = 0;
                if (curr_item > 0) {
                    curr_item--;
                    if (curr_item < first_item) {
                        first_item = curr_item;
                        need_update = 1;
                    }
                }
                break;
            case K_Right:
                str_len = 0;
                if (curr_item + num_lines < fl->num_used_items) {
                    curr_item += num_lines;
                    if (curr_item - first_item >= num_files) {
                        first_item += num_lines;
                        need_update = 1;
                    }
                }
                break;
            case K_Down:
                str_len = 0;
                if (curr_item < fl->num_used_items - 1) {
                    curr_item++;
                    if (curr_item == first_item + num_files) {
                        first_item++;
                        need_update = 1;
                    }
                }
                break;
            case K_PageDown:
                str_len = 0;
                if (curr_item + num_files < fl->num_used_items) {
                    curr_item += num_files;
                    first_item += num_files;
                }
                need_update = 1;
                break;
            case K_PageUp:
                str_len = 0;
                if (curr_item - num_files >= 0) {
                    curr_item -= num_files;
                    first_item -= num_files;
                    if (first_item < 0) {
                        first_item = 0;
                    }
                    need_update = 1;
                }
                break;
            case K_Home:
                str_len = 0;
                curr_item = 0;
                if (first_item != 0) {
                    first_item = 0;
                    need_update = 1;
                }
                break;
            case K_End:
                str_len = 0;
                curr_item = fl->num_used_items - 1;
                first_item = curr_item - num_files + 1;
                if (first_item < 0) {
                    first_item = 0;
                }
                need_update = 1;
                break;
            case K_Return:
                str_len = 0;
                if (fl->items[curr_item].type == FT_DIR) {
                    struct file_list *new_fl;
                    char *new_path;

                    new_path = change_path(fl, return_path, curr_item);

                    new_fl = file_list_read(new_path, pattern);

                    if (new_fl != NULL) {
                        file_list_free(fl);
                        fl = new_fl;
                        first_item = curr_item = 0;
                        lib_free(return_path);
                        return_path = new_path;
                        need_update = 1;
                        ioutil_chdir(return_path);
                    } else {
                        lib_free(new_path);
                    }
                } else {
                    char *p = util_concat(return_path, fl->items[curr_item].name, NULL);

                    lib_free(return_path);
                    return_path = p;
                    tui_area_put(backing_store, x, y);
                    tui_area_free(backing_store);
                    return return_path;
                }
                break;
            case K_BackSpace:
                if (str_len > 1) {
                    int n;
                    str_len--;
                    n = file_list_find(fl, str, str_len);
                    if (n >= 0) {
                        curr_item = n;
                        if (curr_item < first_item) {
                            first_item = curr_item;
                            need_update = 1;
                        } else if (first_item + num_files <= curr_item) {
                            first_item = curr_item - num_files + 1;
                            need_update = 1;
                        }
                    }
                } else {
                    str_len = 0;
                    curr_item = 0;
                    if (first_item != 0) {
                        first_item = 0;
                        need_update = 1;
                    }
                }
                break;
            case ' ':
                if (contents_func != NULL && fl->items[curr_item].type != FT_DIR && browse_file_return != NULL) {
                    tui_display(0, tui_num_lines() - 1, tui_num_cols(), "");
                    *browse_file_return = tui_image_browser(fl->items[curr_item].name, contents_func, browse_file_number_return);
                    if (*browse_file_return != NULL) {
                        char *p = util_concat(return_path, fl->items[curr_item].name, NULL);

                        lib_free(return_path);
                        return_path = p;
                        tui_area_put(backing_store, x, y);
                        tui_area_free(backing_store);
                        return return_path;
                    }
                    need_update = 1;
                    break;
                } else {
                    tui_beep();
                }
            default:
                {
                    int drive_num;

                    drive_num = alt_key_to_drive_num(key);

                    if (drive_num > 0) {
                        /* `A-a' ... `A-z' change the current drive.  */
                        int num_available_drives;
                        int current_drive;

                        _dos_getdrive(&current_drive);
                        _dos_setdrive(current_drive, &num_available_drives);
                        if (drive_num <= num_available_drives) {
                            char *new_path;

                            /* FIXME: This is a hack...  Maybe there is a cleaner
                               way to do it, but for now I just don't know.  */
                            _dos_setdrive(drive_num, &num_available_drives);
                            new_path = ioutil_current_dir();
                            if (new_path != NULL) {
                                slashize_path(&new_path);
                                _dos_setdrive(current_drive, &num_available_drives);
                                if (new_path != NULL) {
                                    struct file_list *new_fl;

                                    new_fl = file_list_read(new_path, pattern);
                                    if (new_fl != NULL) {
                                        file_list_free(fl);
                                        fl = new_fl;
                                        first_item = curr_item = 0;
                                        lib_free(return_path);
                                        return_path = new_path;
                                        need_update = 1;
                                        ioutil_chdir(return_path);
                                    } else {
                                        lib_free(new_path);
                                    }
                                }
                            } else {
                                _dos_setdrive(current_drive, &num_available_drives);
                                tui_beep();
                            }
                        } else {
                            tui_beep();
                        }
                    } else if (isprint(key) && str_len < 0x100) {
                        int n;

                        str[str_len] = key;
                        n = file_list_find(fl, str, str_len + 1);
                        if (n < 0) {
                            tui_beep();
                        } else {
                            str_len++;
                            curr_item = n;
                            if (curr_item < first_item) {
                                first_item = curr_item;
                                need_update = 1;
                            } else if (first_item + num_files <= curr_item) {
                                first_item = curr_item - num_files + 1;
                                need_update = 1;
                            }
                        }
                    }
                }
                break;
        }
    }
}