aboutsummaryrefslogtreecommitdiffstats
path: root/src/wreadln.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-10-06 14:55:01 +0200
committerMax Kellermann <max@duempel.org>2008-10-06 14:55:01 +0200
commit458cad80dfe71f4650aebb0b9710a3a683fd6379 (patch)
tree775a3c2f5eaab1c9f6b40d5e4c0063fdcd516167 /src/wreadln.c
parent04ede1809e29ec58fba71725d65978fd4e586beb (diff)
downloadmpd-458cad80dfe71f4650aebb0b9710a3a683fd6379.tar.gz
mpd-458cad80dfe71f4650aebb0b9710a3a683fd6379.tar.xz
mpd-458cad80dfe71f4650aebb0b9710a3a683fd6379.zip
wreadln: added struct wreadln
Don't pass a dozen of parameters to all internal functions; pass a pointer to the wreadln struct instead.
Diffstat (limited to 'src/wreadln.c')
-rw-r--r--src/wreadln.c205
1 files changed, 111 insertions, 94 deletions
diff --git a/src/wreadln.c b/src/wreadln.c
index eb78a57f1..42703a016 100644
--- a/src/wreadln.c
+++ b/src/wreadln.c
@@ -40,6 +40,30 @@
#define KEY_BCKSPC 8
#define TAB 9
+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;
+};
+
/** max size allocated for a line */
static const size_t wrln_max_line_size = 1024;
@@ -51,61 +75,48 @@ wrln_gcmp_pre_cb_t wrln_pre_completion_callback = NULL;
wrln_gcmp_post_cb_t wrln_post_completion_callback = NULL;
/* move the cursor one step to the right */
-static inline void cursor_move_right(gint *cursor,
- gint *start,
- gint width,
- gchar *line)
+static inline void cursor_move_right(struct wreadln *wr)
{
- if (*cursor < (int)strlen(line) &&
- *cursor < (int)wrln_max_line_size - 1) {
- (*cursor)++;
- if (*cursor >= width && *start < *cursor - width + 1)
- (*start)++;
+ if (wr->cursor < (int)strlen(wr->line) &&
+ wr->cursor < (int)wrln_max_line_size - 1) {
+ ++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,
- gchar *line)
+static inline void cursor_move_to_eol(struct wreadln *wr)
{
- *cursor = strlen(line);
- if (*cursor >= width)
- *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);
+ wmove(wr->w, wr->y, wr->x);
/* clear input area */
- whline(w, ' ', width);
+ whline(wr->w, ' ', wr->width);
/* print visible part of the line buffer */
- if(masked == TRUE)
- whline(w, '*', utf8_width(line) - start);
+ if (wr->masked)
+ whline(wr->w, '*', utf8_width(wr->line) - wr->start);
else
- waddnstr(w, line+start, width);
+ waddnstr(wr->w, wr->line + wr->start, wr->width);
/* move the cursor to the correct position */
- wmove(w, y, x0 + cursor-start);
+ wmove(wr->w, wr->y, wr->x + wr->cursor - wr->start);
/* tell ncurses to redraw the screen */
doupdate();
}
@@ -121,14 +132,17 @@ _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);
+ wr.line = g_malloc0(wrln_max_line_size);
/* turn off echo */
noecho();
/* make shure the cursor is visible */
@@ -137,13 +151,13 @@ _wreadln(WINDOW *w,
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) {
/* append the a new line to our history list */
@@ -158,19 +172,19 @@ _wreadln(WINDOW *w,
if (history && hlist->prev) {
if (hlist == hcurrent)
/* save the current line */
- g_strlcpy(hlist->data, line, wrln_max_line_size);
+ g_strlcpy(hlist->data, wr.line, wrln_max_line_size);
/* get previous line */
hlist = hlist->prev;
- g_strlcpy(line, hlist->data, wrln_max_line_size);
+ g_strlcpy(wr.line, hlist->data, wrln_max_line_size);
}
- cursor_move_to_eol(&cursor, &start, width, line);
- drawline(cursor, start, width, x0, y, masked, line, w);
+ 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, line);
- drawline(cursor, start, width, x0, y, masked, line, w);
+ g_strlcpy(wr.line, initial_value, wrln_max_line_size);
+ cursor_move_to_eol(&wr);
+ drawline(&wr);
}
while (key != 13 && key != '\n') {
@@ -196,25 +210,25 @@ _wreadln(WINDOW *w,
GList *list;
if (wrln_pre_completion_callback)
- wrln_pre_completion_callback(gcmp, line,
+ wrln_pre_completion_callback(gcmp, wr.line,
wrln_completion_callback_data);
- list = g_completion_complete(gcmp, line, &prefix);
+ list = g_completion_complete(gcmp, wr.line, &prefix);
if (prefix) {
- g_strlcpy(line, prefix, wrln_max_line_size);
- cursor_move_to_eol(&cursor, &start, width, line);
+ g_strlcpy(wr.line, prefix, wrln_max_line_size);
+ cursor_move_to_eol(&wr);
g_free(prefix);
} else
screen_bell();
if (wrln_post_completion_callback)
- wrln_post_completion_callback(gcmp, line, list,
+ wrln_post_completion_callback(gcmp, wr.line, list,
wrln_completion_callback_data);
}
break;
case KEY_CTRL_G:
screen_bell();
- g_free(line);
+ g_free(wr.line);
if (history) {
g_free(hcurrent->data);
hcurrent->data = NULL;
@@ -224,44 +238,44 @@ _wreadln(WINDOW *w,
case KEY_LEFT:
case KEY_CTRL_B:
- cursor_move_left(&cursor, &start);
+ cursor_move_left(&wr);
break;
case KEY_RIGHT:
case KEY_CTRL_F:
- cursor_move_right(&cursor, &start, width, line);
+ 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, 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 = utf8_width(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 <= (gint)utf8_width(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:
@@ -270,13 +284,15 @@ _wreadln(WINDOW *w,
if (history && hlist->prev) {
if (hlist == hcurrent)
/* save the current line */
- g_strlcpy(hlist->data, line, wrln_max_line_size);
+ g_strlcpy(hlist->data, wr.line,
+ wrln_max_line_size);
/* get previous line */
hlist = hlist->prev;
- g_strlcpy(line, hlist->data, wrln_max_line_size);
+ g_strlcpy(wr.line, hlist->data,
+ wrln_max_line_size);
}
- cursor_move_to_eol(&cursor, &start, width, line);
+ cursor_move_to_eol(&wr);
break;
case KEY_DOWN:
case KEY_CTRL_N:
@@ -284,9 +300,10 @@ _wreadln(WINDOW *w,
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,
+ wrln_max_line_size);
}
- cursor_move_to_eol(&cursor, &start, width, line);
+ cursor_move_to_eol(&wr);
break;
case '\n':
@@ -299,36 +316,36 @@ _wreadln(WINDOW *w,
break;
default:
if (key >= 32) {
- if (strlen (line + cursor)) { /* if the cursor is */
+ if (strlen(wr.line + wr.cursor)) { /* if the cursor is */
/* not at the last pos */
gchar *tmp = NULL;
- gsize size = strlen(line + cursor) + 1;
+ gsize size = strlen(wr.line + wr.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_strlcpy (tmp, wr.line + wr.cursor, size);
+ wr.line[wr.cursor] = key;
+ wr.line[wr.cursor + 1] = 0;
+ g_strlcat(&wr.line[wr.cursor + 1], tmp, size);
g_free(tmp);
- cursor_move_right(&cursor, &start, width, line);
+ cursor_move_right(&wr);
} else {
- line[cursor + 1] = 0;
- line[cursor] = key;
- cursor_move_right(&cursor, &start, width, line);
+ wr.line[wr.cursor + 1] = 0;
+ wr.line[wr.cursor] = key;
+ cursor_move_right(&wr);
}
}
}
- drawline(cursor, start, width, x0, y, masked, line, w);
+ drawline(&wr);
}
/* update history */
if (history) {
- if (strlen(line)) {
+ 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);
@@ -346,7 +363,7 @@ _wreadln(WINDOW *w,
}
}
- return g_realloc(line, strlen(line)+1);
+ return g_realloc(wr.line, strlen(wr.line) + 1);
}
gchar *