X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fwreadln.c;h=5d019d9003d3438b1287141082fa380349dbf167;hb=3a92aa17478c901b1704fb935723783b11f193e7;hp=f6b848cdd86788df9ade64319e474e8c8f052fad;hpb=76a8fab4adc293982f355609b89dde88d5f355e0;p=ncmpc.git diff --git a/src/wreadln.c b/src/wreadln.c index f6b848c..5d019d9 100644 --- a/src/wreadln.c +++ b/src/wreadln.c @@ -1,6 +1,4 @@ -/* - * $Id$ - * +/* * (c) 2004 by Kalle Wallin * * This program is free software; you can redistribute it and/or modify @@ -18,108 +16,119 @@ * */ +#include "wreadln.h" +#include "charset.h" +#include "screen_utils.h" #include "config.h" #include #include #include -#ifdef USE_NCURSESW -#include -#else -#include -#endif - -#include "wreadln.h" - #define KEY_CTRL_A 1 +#define KEY_CTRL_B 2 #define KEY_CTRL_C 3 -#define KEY_CTRL_D 4 +#define KEY_CTRL_D 4 #define KEY_CTRL_E 5 +#define KEY_CTRL_F 6 #define KEY_CTRL_G 7 #define KEY_CTRL_K 11 +#define KEY_CTRL_N 14 +#define KEY_CTRL_P 16 #define KEY_CTRL_U 21 #define KEY_CTRL_Z 26 #define KEY_BCKSPC 8 #define TAB 9 -#define WRLN_MAX_LINE_SIZE 1024 -#define WRLN_MAX_HISTORY_LENGTH 32 - -guint wrln_max_line_size = WRLN_MAX_LINE_SIZE; -guint wrln_max_history_length = WRLN_MAX_HISTORY_LENGTH; -wrln_wgetch_fn_t wrln_wgetch = NULL; +struct wreadln { + /** the ncurses window where this field is displayed */ + WINDOW *const w; + + /** the origin coordinates in the window */ + gint x, y; + + /** the screen width of the input field */ + gint width; + + /** is the input masked, i.e. characters displayed as '*'? */ + const gboolean masked; + + /** the byte position of the cursor */ + gint cursor; + + /** the byte position displayed at the origin (for horizontal + scrolling) */ + gint start; + + /** the current value */ + gchar line[1024]; +}; + +/** max items stored in the history list */ +static const guint wrln_max_history_length = 32; + void *wrln_completion_callback_data = NULL; wrln_gcmp_pre_cb_t wrln_pre_completion_callback = NULL; wrln_gcmp_post_cb_t wrln_post_completion_callback = NULL; -extern void sigstop(void); -extern void screen_bell(void); -extern size_t my_strlen(char *str); - -#ifndef USE_NCURSESW /* move the cursor one step to the right */ -static inline void cursor_move_right(gint *cursor, - gint *start, - gint width, - gint x0, - gint x1, - gchar *line) +static inline void cursor_move_right(struct wreadln *wr) { - if (*cursor < strlen(line) && *cursor < wrln_max_line_size - 1) { - (*cursor)++; - if (*cursor + x0 >= x1 && *start < *cursor - width + 1) - (*start)++; + if (wr->cursor < (int)strlen(wr->line)) { + ++wr->cursor; + if (wr->cursor >= wr->width && + wr->start < wr->cursor - wr->width + 1) + ++wr->start; } } /* move the cursor one step to the left */ -static inline void cursor_move_left(gint *cursor, - gint *start) +static inline void cursor_move_left(struct wreadln *wr) { - if( *cursor > 0 ) - { - if( *cursor==*start && *start > 0 ) - (*start)--; - (*cursor)--; - } + if (wr->cursor > 0) { + if (wr->cursor == wr->start && wr->start > 0) + --wr->start; + --wr->cursor; + } } /* move the cursor to the end of the line */ -static inline void cursor_move_to_eol(gint *cursor, - gint *start, - gint width, - gint x0, - gint x1, - gchar *line) +static inline void cursor_move_to_eol(struct wreadln *wr) { - *cursor = strlen(line); - if( *cursor+x0 >= x1 ) - *start = *cursor-width+1; + wr->cursor = strlen(wr->line); + if (wr->cursor >= wr->width) + wr->start = wr->cursor - wr->width + 1; } /* draw line buffer and update cursor position */ -static inline void drawline(gint cursor, - gint start, - gint width, - gint x0, - gint y, - gboolean masked, - gchar *line, - WINDOW *w) +static inline void drawline(const struct wreadln *wr) { - wmove(w, y, x0); - /* clear input area */ - whline(w, ' ', width); - /* print visible part of the line buffer */ - if(masked == TRUE) whline(w, '*', my_strlen(line)-start); - else waddnstr(w, line+start, width); - /* move the cursor to the correct position */ - wmove(w, y, x0 + cursor-start); - /* tell ncurses to redraw the screen */ - doupdate(); + wmove(wr->w, wr->y, wr->x); + /* clear input area */ + whline(wr->w, ' ', wr->width); + /* print visible part of the line buffer */ + if (wr->masked) + whline(wr->w, '*', utf8_width(wr->line) - wr->start); + else + waddnstr(wr->w, wr->line + wr->start, wr->width); + /* move the cursor to the correct position */ + wmove(wr->w, wr->y, wr->x + wr->cursor - wr->start); + /* tell ncurses to redraw the screen */ + doupdate(); } +static void +wreadln_insert_byte(struct wreadln *wr, gint key) +{ + size_t rest = strlen(wr->line + wr->cursor) + 1; + const size_t length = 1; + + memmove(wr->line + wr->cursor + length, + wr->line + wr->cursor, rest); + wr->line[wr->cursor] = key; + + cursor_move_right(wr); +} /* libcurses version */ @@ -132,71 +141,67 @@ _wreadln(WINDOW *w, GCompletion *gcmp, gboolean masked) { + struct wreadln wr = { + .w = w, + .masked = masked, + .cursor = 0, + .start = 0, + }; GList *hlist = NULL, *hcurrent = NULL; - gchar *line; - gint x0, y, width; - gint cursor = 0, start = 0; gint key = 0, i; - /* allocate a line buffer */ - line = g_malloc0(wrln_max_line_size); /* turn off echo */ noecho(); /* make shure the cursor is visible */ curs_set(1); /* print prompt string */ - if( prompt ) + if (prompt) waddstr(w, prompt); /* retrive y and x0 position */ - getyx(w, y, x0); + getyx(w, wr.y, wr.x); /* check the x1 value */ - if( x1<=x0 || x1>COLS ) + if (x1 <= wr.x || x1 > COLS) x1 = COLS; - width = x1-x0; + wr.width = x1 - wr.x; /* clear input area */ - mvwhline(w, y, x0, ' ', width); + mvwhline(w, wr.y, wr.x, ' ', wr.width); - if( history ) { + if (history) { /* append the a new line to our history list */ - *history = g_list_append(*history, g_malloc0(wrln_max_line_size)); + *history = g_list_append(*history, g_malloc0(sizeof(wr.line))); /* hlist points to the current item in the history list */ - hlist = g_list_last(*history); + hlist = g_list_last(*history); hcurrent = hlist; } - if( initial_value == (char *) -1 ) { + if (initial_value == (char *)-1) { /* get previous history entry */ - if( history && hlist->prev ) - { - if( hlist==hcurrent ) - { - /* save the current line */ - g_strlcpy(hlist->data, line, wrln_max_line_size); - } - /* get previous line */ - hlist = hlist->prev; - g_strlcpy(line, hlist->data, wrln_max_line_size); - } - cursor_move_to_eol(&cursor, &start, width, x0, x1, line); - drawline(cursor, start, width, x0, y, masked, line, w); - } else if( initial_value ) { + if (history && hlist->prev) { + if (hlist == hcurrent) + /* save the current line */ + g_strlcpy(hlist->data, wr.line, sizeof(wr.line)); + + /* get previous line */ + hlist = hlist->prev; + g_strlcpy(wr.line, hlist->data, sizeof(wr.line)); + } + cursor_move_to_eol(&wr); + drawline(&wr); + } else if (initial_value) { /* copy the initial value to the line buffer */ - g_strlcpy(line, initial_value, wrln_max_line_size); - cursor_move_to_eol(&cursor, &start, width, x0, x1, line); - drawline(cursor, start, width, x0, y, masked, line, w); + g_strlcpy(wr.line, initial_value, sizeof(wr.line)); + cursor_move_to_eol(&wr); + drawline(&wr); } - while( key!=13 && key!='\n' ) { - if( wrln_wgetch ) - key = wrln_wgetch(w); - else - key = wgetch(w); + while (key != 13 && key != '\n') { + key = wgetch(w); /* check if key is a function key */ - for(i=0; i<63; i++) - if( key==KEY_F(i) ) { - key=KEY_F(1); - i=64; + for (i = 0; i < 63; i++) + if (key == KEY_F(i)) { + key = KEY_F(1); + i = 64; } switch (key) { @@ -206,43 +211,31 @@ _wreadln(WINDOW *w, case ERR: /* ingnore errors */ break; - case KEY_RESIZE: - /* a resize event */ - if( x1>COLS ) { - x1=COLS; - width = x1-x0; - cursor_move_to_eol(&cursor, &start, width, x0, x1, line); - } - /* make shure the cursor is visible */ - curs_set(1); - break; - case TAB: - if( gcmp ) { + if (gcmp) { char *prefix = NULL; GList *list; - if(wrln_pre_completion_callback) - wrln_pre_completion_callback(gcmp, line, + if (wrln_pre_completion_callback) + wrln_pre_completion_callback(gcmp, wr.line, wrln_completion_callback_data); - list = g_completion_complete(gcmp, line, &prefix); - if( prefix ) { - g_strlcpy(line, prefix, wrln_max_line_size); - cursor_move_to_eol(&cursor, &start, width, x0, x1, line); + list = g_completion_complete(gcmp, wr.line, &prefix); + if (prefix) { + g_strlcpy(wr.line, prefix, sizeof(wr.line)); + cursor_move_to_eol(&wr); g_free(prefix); - } - else + } else screen_bell(); - if( wrln_post_completion_callback ) - wrln_post_completion_callback(gcmp, line, list, + + if (wrln_post_completion_callback) + wrln_post_completion_callback(gcmp, wr.line, list, wrln_completion_callback_data); } break; case KEY_CTRL_G: screen_bell(); - g_free(line); - if( history ) { + if (history) { g_free(hcurrent->data); hcurrent->data = NULL; *history = g_list_delete_link(*history, hcurrent); @@ -250,67 +243,73 @@ _wreadln(WINDOW *w, return NULL; case KEY_LEFT: - cursor_move_left(&cursor, &start); + case KEY_CTRL_B: + cursor_move_left(&wr); break; case KEY_RIGHT: - cursor_move_right(&cursor, &start, width, x0, x1, line); + case KEY_CTRL_F: + cursor_move_right(&wr); break; case KEY_HOME: case KEY_CTRL_A: - cursor = 0; - start = 0; + wr.cursor = 0; + wr.start = 0; break; case KEY_END: case KEY_CTRL_E: - cursor_move_to_eol(&cursor, &start, width, x0, x1, line); + cursor_move_to_eol(&wr); break; case KEY_CTRL_K: - line[cursor] = 0; + wr.line[wr.cursor] = 0; break; case KEY_CTRL_U: - cursor = my_strlen(line); - for (i = 0;i < cursor; i++) - line[i] = '\0'; - cursor = 0; + wr.cursor = utf8_width(wr.line); + for (i = 0; i < wr.cursor; i++) + wr.line[i] = '\0'; + wr.cursor = 0; break; case 127: case KEY_BCKSPC: /* handle backspace: copy all */ case KEY_BACKSPACE: /* chars starting from curpos */ - if( cursor > 0 ) {/* - 1 from buf[n+1] to buf */ - for (i = cursor - 1; line[i] != 0; i++) - line[i] = line[i + 1]; - cursor_move_left(&cursor, &start); + if (wr.cursor > 0) {/* - 1 from buf[n+1] to buf */ + for (i = wr.cursor - 1; wr.line[i] != 0; i++) + wr.line[i] = wr.line[i + 1]; + cursor_move_left(&wr); } break; case KEY_DC: /* handle delete key. As above */ case KEY_CTRL_D: - if (cursor <= my_strlen(line) - 1) { - for (i = cursor; line[i] != 0; i++) - line[i] = line[i + 1]; + if (wr.cursor <= (gint)utf8_width(wr.line) - 1) { + for (i = wr.cursor; wr.line[i] != 0; i++) + wr.line[i] = wr.line[i + 1]; } break; case KEY_UP: + case KEY_CTRL_P: /* get previous history entry */ - if( history && hlist->prev ) { - if( hlist==hcurrent ) - { - /* save the current line */ - g_strlcpy(hlist->data, line, wrln_max_line_size); - } + if (history && hlist->prev) { + if (hlist == hcurrent) + /* save the current line */ + g_strlcpy(hlist->data, wr.line, + sizeof(wr.line)); + /* get previous line */ hlist = hlist->prev; - g_strlcpy(line, hlist->data, wrln_max_line_size); + g_strlcpy(wr.line, hlist->data, + sizeof(wr.line)); } - cursor_move_to_eol(&cursor, &start, width, x0, x1, line); + cursor_move_to_eol(&wr); break; case KEY_DOWN: + case KEY_CTRL_N: /* get next history entry */ - if( history && hlist->next ) { + if (history && hlist->next) { /* get next line */ hlist = hlist->next; - g_strlcpy(line, hlist->data, wrln_max_line_size); + g_strlcpy(wr.line, hlist->data, + sizeof(wr.line)); } - cursor_move_to_eol(&cursor, &start, width, x0, x1, line); + cursor_move_to_eol(&wr); break; case '\n': @@ -322,37 +321,20 @@ _wreadln(WINDOW *w, /* ignore char */ break; default: - if (key >= 32) { - if (strlen (line + cursor)) { /* if the cursor is */ - /* not at the last pos */ - gchar *tmp = 0; - gsize size = strlen(line + cursor) + 1; - - tmp = g_malloc0(size); - g_strlcpy (tmp, line + cursor, size); - line[cursor] = key; - line[cursor + 1] = 0; - g_strlcat (&line[cursor + 1], tmp, size); - g_free(tmp); - cursor_move_right(&cursor, &start, width, x0, x1, line); - } else { - line[cursor + 1] = 0; - line[cursor] = key; - cursor_move_right(&cursor, &start, width, x0, x1, line); - } - } + if (key >= 32) + wreadln_insert_byte(&wr, key); } - drawline(cursor, start, width, x0, y, masked, line, w); + drawline(&wr); } /* update history */ - if( history ) { - if( strlen(line) ) { + if (history) { + if (strlen(wr.line)) { /* update the current history entry */ - size_t size = strlen(line)+1; + size_t size = strlen(wr.line) + 1; hcurrent->data = g_realloc(hcurrent->data, size); - g_strlcpy(hcurrent->data, line, size); + g_strlcpy(hcurrent->data, wr.line, size); } else { /* the line was empty - remove the current history entry */ g_free(hcurrent->data); @@ -360,7 +342,7 @@ _wreadln(WINDOW *w, *history = g_list_delete_link(*history, hcurrent); } - while( g_list_length(*history) > wrln_max_history_length ) { + while (g_list_length(*history) > wrln_max_history_length) { GList *first = g_list_first(*history); /* remove the oldest history entry */ @@ -370,397 +352,9 @@ _wreadln(WINDOW *w, } } - return g_realloc(line, strlen(line)+1); -} - -#else - -/* move the cursor one step to the right */ -static inline void cursor_move_right(gint *cursor, - gint *start, - gint width, - gint x0, - gint x1, - wchar_t *wline) -{ - if( *cursor < wcslen(wline) && *cursor= x1 && *start<*cursor-width+1) - (*start)++; - } + return g_strdup(wr.line); } -/* move the cursor one step to the left */ -static inline void cursor_move_left(gint *cursor, - gint *start, - gint width, - gint x0, - gint x1, - wchar_t *line) -{ - if( *cursor > 0 ) - { - if( *cursor==*start && *start > 0 ) - (*start)--; - (*cursor)--; - } -} - - -static inline void backspace(gint *cursor, - gint *start, - gint width, - gint x0, - gint x1, - wchar_t *wline) -{ - int i; - if( *cursor > 0 ) - { - for (i = *cursor - 1; wline[i] != 0; i++) - wline[i] = wline[i + 1]; - cursor_move_left(cursor, start, width, x0, x1, wline); - } -} - -/* handle delete */ -static inline void delete(gint *cursor, - wchar_t *wline) -{ - int i; - if( *cursor <= wcslen(wline) - 1 ) - { - for (i = *cursor; wline[i] != 0; i++) - wline[i] = wline[i + 1]; - } -} - -/* move the cursor to the end of the line */ -static inline void cursor_move_to_eol(gint *cursor, - gint *start, - gint width, - gint x0, - gint x1, - wchar_t *line) -{ - *cursor = wcslen(line); - if( *cursor+x0 >= x1 ) - *start = *cursor-width+1; -} - -/* draw line buffer and update cursor position */ -static inline void drawline(gint cursor, - gint start, - gint width, - gint x0, - gint y, - gboolean masked, - wchar_t *line, - WINDOW *w) -{ - wmove(w, y, x0); - /* clear input area */ - whline(w, ' ', width); - /* print visible part of the line buffer */ - if(masked == TRUE) whline(w, '*', wcslen(line)-start); - else waddnwstr(w, line+start, width); - FILE *dbg = fopen ("dbg", "a+"); - fprintf (dbg, "%i,%s---%i---", width, line, wcslen (line)); - /* move the cursor to the correct position */ - wmove(w, y, x0 + cursor-start); - /* tell ncurses to redraw the screen */ - doupdate(); -} - -/* libcursesw version */ - -static gchar * -_wreadln(WINDOW *w, - const gchar *prompt, - const gchar *initial_value, - gint x1, - GList **history, - GCompletion *gcmp, - gboolean masked) -{ - GList *hlist = NULL, *hcurrent = NULL; - wchar_t *wline; - gchar *mbline; - gint x0, x, y, width, start; - gint cursor; - wint_t wch; - gint key; - gint i; - - /* initialize variables */ - start = 0; - x = 0; - cursor = 0; - mbline = NULL; - - /* allocate a line buffer */ - wline = g_malloc0(wrln_max_line_size*sizeof(wchar_t)); - /* turn off echo */ - noecho(); - /* make shure the cursor is visible */ - curs_set(1); - /* print prompt string */ - if( prompt ) - waddstr(w, prompt); - /* retrive y and x0 position */ - getyx(w, y, x0); - /* check the x1 value */ - if( x1<=x0 || x1>COLS ) - x1 = COLS; - width = x1-x0; - /* clear input area */ - mvwhline(w, y, x0, ' ', width); - - - if( history ) - { - /* append the a new line to our history list */ - *history = g_list_append(*history, g_malloc0(wrln_max_line_size)); - /* hlist points to the current item in the history list */ - hlist = g_list_last(*history); - hcurrent = hlist; - } - if( initial_value == (char *) -1 ) - { - /* get previous history entry */ - if( history && hlist->prev ) - { - if( hlist==hcurrent ) - { - /* save the current line */ - //g_strlcpy(hlist->data, line, wrln_max_line_size); - } - /* get previous line */ - hlist = hlist->prev; - mbstowcs(wline, hlist->data, wrln_max_line_size); - } - cursor_move_to_eol(&cursor, &start, width, x0, x1, wline); - drawline(cursor, start, width, x0, y, masked, wline, w); - } - else if( initial_value ) - { - /* copy the initial value to the line buffer */ - mbstowcs(wline, initial_value, wrln_max_line_size); - cursor_move_to_eol(&cursor, &start, width, x0, x1, wline); - drawline(cursor, start, width, x0, y, masked, wline, w); - } - - wch=0; - key=0; - while( wch!=13 && wch!='\n' ) - { - key = wget_wch(w, &wch); - - if( key==KEY_CODE_YES ) - { - /* function key */ - switch(wch) - { - case KEY_HOME: - x=0; - cursor=0; - start=0; - break; - case KEY_END: - cursor_move_to_eol(&cursor, &start, width, x0, x1, wline); - break; - case KEY_LEFT: - cursor_move_left(&cursor, &start, width, x0, x1, wline); - break; - case KEY_RIGHT: - cursor_move_right(&cursor, &start, width, x0, x1, wline); - break; - case KEY_DC: - delete(&cursor, wline); - break; - case KEY_BCKSPC: - case KEY_BACKSPACE: - backspace(&cursor, &start, width, x0, x1, wline); - break; - case KEY_UP: - /* get previous history entry */ - if( history && hlist->prev ) - { - if( hlist==hcurrent ) - { - /* save the current line */ - wcstombs(hlist->data, wline, wrln_max_line_size); - } - /* get previous line */ - hlist = hlist->prev; - mbstowcs(wline, hlist->data, wrln_max_line_size); - } - cursor_move_to_eol(&cursor, &start, width, x0, x1, wline); - break; - case KEY_DOWN: - /* get next history entry */ - if( history && hlist->next ) - { - /* get next line */ - hlist = hlist->next; - mbstowcs(wline, hlist->data, wrln_max_line_size); - } - cursor_move_to_eol(&cursor, &start, width, x0, x1, wline); - break; - case KEY_RESIZE: - /* resize event */ - if( x1>COLS ) - { - x1=COLS; - width = x1-x0; - cursor_move_to_eol(&cursor, &start, width, x0, x1, wline); - } - /* make shure the cursor is visible */ - curs_set(1); - break; - } - - } - else if( key!=ERR ) - { - switch(wch) - { - case KEY_CTRL_A: - x=0; - cursor=0; - start=0; - break; - case KEY_CTRL_C: - exit(EXIT_SUCCESS); - break; - case KEY_CTRL_D: - delete(&cursor, wline); - break; - case KEY_CTRL_E: - cursor_move_to_eol(&cursor, &start, width, x0, x1, wline); - break; - case TAB: - if( gcmp ) - { - char *prefix = NULL; - GList *list; - - i = wcstombs(NULL,wline,0)+1; - mbline = g_malloc0(i); - wcstombs(mbline, wline, i); - - if(wrln_pre_completion_callback) - wrln_pre_completion_callback(gcmp, mbline, - wrln_completion_callback_data); - list = g_completion_complete(gcmp, mbline, &prefix); - if( prefix ) - { - mbstowcs(wline, prefix, wrln_max_line_size); - cursor_move_to_eol(&cursor, &start, width, x0, x1, wline); - g_free(prefix); - } - else - screen_bell(); - if( wrln_post_completion_callback ) - wrln_post_completion_callback(gcmp, mbline, list, - wrln_completion_callback_data); - - g_free(mbline); - } - break; - case KEY_CTRL_G: - screen_bell(); - g_free(wline); - if( history ) - { - g_free(hcurrent->data); - hcurrent->data = NULL; - *history = g_list_delete_link(*history, hcurrent); - } - return NULL; - case KEY_CTRL_K: - wline[cursor] = 0; - break; - case KEY_CTRL_U: - cursor = wcslen(wline); - for (i = 0;i < cursor; i++) - wline[i] = '\0'; - cursor = 0; - break; - case KEY_CTRL_Z: - sigstop(); - break; - case 127: - backspace(&cursor, &start, width, x0, x1, wline); - break; - case '\n': - case 13: - /* ignore char */ - break; - default: - if( (wcslen(wline+cursor)) ) - { - /* the cursor is not at the last pos */ - wchar_t *tmp = NULL; - gsize len = (wcslen(wline+cursor)+1); - tmp = g_malloc0(len*sizeof(wchar_t)); - wmemcpy(tmp, wline+cursor, len); - wline[cursor] = wch; - wline[cursor+1] = 0; - wcscat(&wline[cursor+1], tmp); - g_free(tmp); - cursor_move_right(&cursor, &start, width, x0, x1, wline); - } - else - { - FILE *ff = fopen ("curspr", "a+"); - fprintf (ff, "%i", cursor); - wline[cursor] = wch; - wline[cursor+1] = 0; - cursor_move_right(&cursor, &start, width, x0, x1, wline); - } - } - } - drawline(cursor, start, width, x0, y, masked, wline, w); - } - i = wcstombs(NULL,wline,0)+1; - mbline = g_malloc0(i); - wcstombs(mbline, wline, i); - - /* update history */ - if( history ) - { - if( strlen(mbline) ) - { - /* update the current history entry */ - size_t size = strlen(mbline)+1; - hcurrent->data = g_realloc(hcurrent->data, size); - g_strlcpy(hcurrent->data, mbline, size); - } - else - { - /* the line was empty - remove the current history entry */ - g_free(hcurrent->data); - hcurrent->data = NULL; - *history = g_list_delete_link(*history, hcurrent); - } - - while( g_list_length(*history) > wrln_max_history_length ) - { - GList *first = g_list_first(*history); - - /* remove the oldest history entry */ - g_free(first->data); - first->data = NULL; - *history = g_list_delete_link(*history, first); - } - } - return mbline; -} - -#endif - gchar * wreadln(WINDOW *w, const gchar *prompt,