aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2017-11-05 11:33:31 +0100
committerBjörn Linse <bjorn.linse@gmail.com>2018-12-31 12:44:21 +0100
commitc9b559a0308714ef8ad396eb340a4af580e44d74 (patch)
tree922c689e4ebe9d4556c283a7eb5d82dc8966cdcd /src
parentccbcd390d42d33a15f15c29fab5d6076a6d3ac08 (diff)
downloadrneovim-c9b559a0308714ef8ad396eb340a4af580e44d74.tar.gz
rneovim-c9b559a0308714ef8ad396eb340a4af580e44d74.tar.bz2
rneovim-c9b559a0308714ef8ad396eb340a4af580e44d74.zip
multigrid: introduce grid abstraction
Diffstat (limited to 'src')
-rw-r--r--src/nvim/globals.h8
-rw-r--r--src/nvim/mbyte.h7
-rw-r--r--src/nvim/memory.c4
-rw-r--r--src/nvim/move.c5
-rw-r--r--src/nvim/screen.c123
-rw-r--r--src/nvim/types.h18
6 files changed, 94 insertions, 71 deletions
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 04ff1320ce..097c71928c 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -128,12 +128,6 @@ typedef off_t off_T;
# endif
#endif
-/*
- * The characters and attributes cached for the screen.
- */
-typedef char_u schar_T[(MAX_MCO+1) * 4 + 1];
-typedef int16_t sattr_T;
-
/// ScreenLines[] contains a copy of the whole screen, as it currently is
/// displayed. It is a single block of screen cells, the size of the screen
/// plus one line. The extra line used as a buffer while redrawing a window
@@ -167,6 +161,8 @@ EXTERN char_u *LineWraps INIT(= NULL); /* line wraps to next line */
EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
+EXTERN ScreenGrid default_grid INIT(= { 0 });
+
/*
* When vgetc() is called, it sets mod_mask to the set of modifiers that are
* held down based on the MOD_MASK_* symbols that are read first.
diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h
index 70073a8540..ed48705c6d 100644
--- a/src/nvim/mbyte.h
+++ b/src/nvim/mbyte.h
@@ -19,13 +19,6 @@
#define MB_BYTE2LEN(b) utf8len_tab[b]
#define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : utf8len_tab[b])
-/// Maximum value for 'maxcombine'
-///
-/// At most that number of composing characters may be attached to the leading
-/// character by various `utfc_*` functions. Note that some functions do not
-/// have this limit.
-enum { MAX_MCO = 6 };
-
// max length of an unicode char
#define MB_MAXCHAR 6
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 6b96a3b070..ce914b43f9 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -698,8 +698,8 @@ void free_all_mem(void)
buf = bufref_valid(&bufref) ? nextbuf : firstbuf;
}
- /* screenlines (can't display anything now!) */
- free_screenlines();
+ // free screenlines (can't display anything now!)
+ free_screengrid(&default_grid);
clear_hl_tables(false);
list_free_log();
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 3a29851ee6..bb44b458e8 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -149,9 +149,12 @@ void update_topline(void)
bool check_botline = false;
long save_so = p_so;
+ // need to have w_grid.Rows/Columns updated
+ win_grid_alloc(curwin, false);
+
// If there is no valid screen and when the window height is zero just use
// the cursor line.
- if (!screen_valid(true) || curwin->w_height == 0) {
+ if (!screen_valid(true) || curwin->w_grid.Rows == 0) {
curwin->w_topline = curwin->w_cursor.lnum;
curwin->w_botline = curwin->w_topline;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index d095bdb7c8..fcb225084d 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -130,6 +130,10 @@ static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */
static schar_T *current_ScreenLine;
StlClickDefinition *tab_page_click_defs = NULL;
+
+int grid_Rows = 0;
+int grid_Columns = 0;
+
long tab_page_click_defs_size = 0;
// for line_putchar. Contains the state that needs to be remembered from
@@ -5883,8 +5887,6 @@ int screen_valid(int doclear)
*/
void screenalloc(bool doclear)
{
- int new_row, old_row;
- int len;
static bool entered = false; // avoid recursiveness
int retry_count = 0;
@@ -5892,7 +5894,7 @@ retry:
// Allocation of the screen buffers is done only when the size changes and
// when Rows and Columns have been set and we have started doing full
// screen stuff.
- if ((ScreenLines != NULL
+ if ((default_grid.ScreenLines != NULL
&& Rows == screen_Rows
&& Columns == screen_Columns
)
@@ -5938,13 +5940,7 @@ retry:
if (aucmd_win != NULL)
win_free_lsize(aucmd_win);
- // Allocate space for an extra row as scratch space, so that a redrawn
- // line can be compared with the previous screen line state.
- size_t ncells = (size_t)((Rows+1) * Columns);
- schar_T *new_ScreenLines = xmalloc(ncells * sizeof(*new_ScreenLines));
- sattr_T *new_ScreenAttrs = xmalloc(ncells * sizeof(*new_ScreenAttrs));
- unsigned *new_LineOffset = xmalloc((size_t)(Rows * sizeof(*new_LineOffset)));
- char_u *new_LineWraps = xmalloc((size_t)(Rows * sizeof(*new_LineWraps)));
+ alloc_grid(&default_grid, Rows, Columns, !doclear);
StlClickDefinition *new_tab_page_click_defs = xcalloc(
(size_t)Columns, sizeof(*new_tab_page_click_defs));
@@ -5955,46 +5951,11 @@ retry:
win_alloc_lines(aucmd_win);
}
- for (new_row = 0; new_row < Rows; new_row++) {
- new_LineOffset[new_row] = new_row * Columns;
- new_LineWraps[new_row] = false;
-
- // If the screen is not going to be cleared, copy as much as
- // possible from the old screen to the new one and clear the rest
- // (used when resizing the window at the "--more--" prompt or when
- // executing an external command, for the GUI).
- if (!doclear) {
- for (int col = 0; col < Columns; col++) {
- schar_from_ascii(new_ScreenLines[new_row * Columns + col], ' ');
- }
- memset(new_ScreenAttrs + new_row * Columns,
- 0, (size_t)Columns * sizeof(*new_ScreenAttrs));
- old_row = new_row + (screen_Rows - Rows);
- if (old_row >= 0 && ScreenLines != NULL) {
- if (screen_Columns < Columns) {
- len = screen_Columns;
- } else {
- len = Columns;
- }
-
- memmove(new_ScreenLines + new_LineOffset[new_row],
- ScreenLines + LineOffset[old_row],
- (size_t)len * sizeof(schar_T));
- memmove(new_ScreenAttrs + new_LineOffset[new_row],
- ScreenAttrs + LineOffset[old_row],
- (size_t)len * sizeof(new_ScreenAttrs[0]));
- }
- }
- }
- // Use the last line of the screen for the current line.
- current_ScreenLine = new_ScreenLines + Rows * Columns;
+ clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
+ xfree(tab_page_click_defs);
- free_screenlines();
+ set_screengrid(&default_grid);
- ScreenLines = new_ScreenLines;
- ScreenAttrs = new_ScreenAttrs;
- LineOffset = new_LineOffset;
- LineWraps = new_LineWraps;
tab_page_click_defs = new_tab_page_click_defs;
tab_page_click_defs_size = Columns;
@@ -6023,14 +5984,66 @@ retry:
}
}
-void free_screenlines(void)
+void alloc_grid(ScreenGrid *grid, int Rows, int Columns, bool copy)
{
- xfree(ScreenLines);
- xfree(ScreenAttrs);
- xfree(LineOffset);
- xfree(LineWraps);
- clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
- xfree(tab_page_click_defs);
+ int new_row, old_row;
+ ScreenGrid new = { 0 };
+
+ size_t ncells = (size_t)((Rows+1) * Columns);
+ new.ScreenLines = xmalloc(ncells * sizeof(schar_T));
+ new.ScreenAttrs = xmalloc(ncells * sizeof(sattr_T));
+ new.LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned)));
+ new.LineWraps = xmalloc((size_t)(Rows * sizeof(char_u)));
+
+ new.Rows = Rows;
+ new.Columns = Columns;
+
+ for (new_row = 0; new_row < Rows; new_row++) {
+ new.LineOffset[new_row] = new_row * Columns;
+ new.LineWraps[new_row] = false;
+ if (copy) {
+ // If the screen is not going to be cleared, copy as much as
+ // possible from the old screen to the new one and clear the rest
+ // (used when resizing the window at the "--more--" prompt or when
+ // executing an external command, for the GUI).
+ memset(new.ScreenLines + new_row * Columns,
+ ' ', (size_t)Columns * sizeof(schar_T));
+ memset(new.ScreenAttrs + new_row * Columns,
+ 0, (size_t)Columns * sizeof(sattr_T));
+ old_row = new_row + (grid->Rows - Rows);
+ if (old_row >= 0 && grid->ScreenLines != NULL) {
+ int len = MIN(grid->Columns, Columns);
+ memmove(new.ScreenLines + new.LineOffset[new_row],
+ grid->ScreenLines + grid->LineOffset[old_row],
+ (size_t)len * sizeof(schar_T));
+ memmove(new.ScreenAttrs + new.LineOffset[new_row],
+ grid->ScreenAttrs + grid->LineOffset[old_row],
+ (size_t)len * sizeof(sattr_T));
+ }
+ }
+ }
+ free_screengrid(grid);
+ *grid = new;
+}
+
+
+void free_screengrid(ScreenGrid *grid)
+{
+ xfree(grid->ScreenLines);
+ xfree(grid->ScreenAttrs);
+ xfree(grid->LineOffset);
+ xfree(grid->LineWraps);
+}
+
+void set_screengrid(ScreenGrid *grid)
+{
+ ScreenLines = grid->ScreenLines;
+ ScreenAttrs = grid->ScreenAttrs;
+ LineOffset = grid->LineOffset;
+ LineWraps = grid->LineWraps;
+ grid_Rows = grid->Rows;
+ grid_Columns = grid->Columns;
+ current_ScreenLine = ScreenLines + grid_Rows * grid_Columns;
}
/// Clear tab_page_click_defs table
diff --git a/src/nvim/types.h b/src/nvim/types.h
index 317bead3bb..84634b1cb7 100644
--- a/src/nvim/types.h
+++ b/src/nvim/types.h
@@ -15,4 +15,22 @@ typedef uint32_t u8char_T;
typedef struct expand expand_T;
+#define MAX_MCO 6 // maximum value for 'maxcombine'
+
+
+// The characters and attributes cached for the screen.
+typedef char_u schar_T[(MAX_MCO+1) * 4 + 1];
+typedef int16_t sattr_T;
+
+// TODO(bfredl): find me a good home
+typedef struct {
+ schar_T *ScreenLines;
+ sattr_T *ScreenAttrs;
+ unsigned *LineOffset;
+ char_u *LineWraps;
+
+ int Rows;
+ int Columns;
+} ScreenGrid;
+
#endif // NVIM_TYPES_H