From 458cad80dfe71f4650aebb0b9710a3a683fd6379 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 6 Oct 2008 14:55:01 +0200 Subject: [PATCH] wreadln: added struct wreadln Don't pass a dozen of parameters to all internal functions; pass a pointer to the wreadln struct instead. --- src/wreadln.c | 205 +++++++++++++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 94 deletions(-) diff --git a/src/wreadln.c b/src/wreadln.c index eb78a57..42703a0 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 * -- 2.30.2