1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:17:35 +00:00

Terminal: Use Vectors and OwnPtrs for Terminal lines. Adjust scroll

region behavior
This commit is contained in:
Christopher Dumas 2019-05-29 10:53:21 -07:00 committed by Andreas Kling
parent ce15a4021d
commit e92fe52031
5 changed files with 208 additions and 127 deletions

View file

@ -1,19 +1,19 @@
#include "Terminal.h" #include "Terminal.h"
#include "XtermColors.h" #include "XtermColors.h"
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <AK/AKString.h> #include <AK/AKString.h>
#include <AK/StringBuilder.h>
#include <SharedGraphics/Font.h>
#include <LibGUI/GPainter.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <LibGUI/GApplication.h> #include <AK/StringBuilder.h>
#include <LibGUI/GWindow.h>
#include <Kernel/KeyCode.h> #include <Kernel/KeyCode.h>
#include <LibGUI/GApplication.h>
#include <LibGUI/GPainter.h>
#include <LibGUI/GWindow.h>
#include <SharedGraphics/Font.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h>
//#define TERMINAL_DEBUG //#define TERMINAL_DEBUG
byte Terminal::Attribute::default_foreground_color = 7; byte Terminal::Attribute::default_foreground_color = 7;
@ -30,8 +30,8 @@ Terminal::Terminal(int ptm_fd, RetainPtr<CConfigFile> config)
dbgprintf("Terminal: Load config file from %s\n", m_config->file_name().characters()); dbgprintf("Terminal: Load config file from %s\n", m_config->file_name().characters());
m_cursor_blink_timer.set_interval(m_config->read_num_entry("Text", m_cursor_blink_timer.set_interval(m_config->read_num_entry("Text",
"CursorBlinkInterval", "CursorBlinkInterval",
500)); 500));
m_cursor_blink_timer.on_timeout = [this] { m_cursor_blink_timer.on_timeout = [this] {
m_cursor_blink_state = !m_cursor_blink_state; m_cursor_blink_state = !m_cursor_blink_state;
update_cursor(); update_cursor();
@ -43,7 +43,7 @@ Terminal::Terminal(int ptm_fd, RetainPtr<CConfigFile> config)
else else
set_font(Font::load_from_file(font_entry)); set_font(Font::load_from_file(font_entry));
m_notifier.on_ready_to_read = [this]{ m_notifier.on_ready_to_read = [this] {
byte buffer[BUFSIZ]; byte buffer[BUFSIZ];
ssize_t nread = read(m_ptm_fd, buffer, sizeof(buffer)); ssize_t nread = read(m_ptm_fd, buffer, sizeof(buffer));
if (nread < 0) { if (nread < 0) {
@ -65,7 +65,7 @@ Terminal::Terminal(int ptm_fd, RetainPtr<CConfigFile> config)
m_line_height = font().glyph_height() + m_line_spacing; m_line_height = font().glyph_height() + m_line_spacing;
set_size(m_config->read_num_entry("Window", "Width", 80), set_size(m_config->read_num_entry("Window", "Width", 80),
m_config->read_num_entry("Window", "Height", 25)); m_config->read_num_entry("Window", "Height", 25));
} }
Terminal::Line::Line(word columns) Terminal::Line::Line(word columns)
@ -78,24 +78,24 @@ Terminal::Line::Line(word columns)
Terminal::Line::~Line() Terminal::Line::~Line()
{ {
delete [] characters; delete[] characters;
delete [] attributes; delete[] attributes;
} }
void Terminal::Line::clear(Attribute attribute) void Terminal::Line::clear(Attribute attribute)
{ {
if (dirty) { if (dirty) {
memset(characters, ' ', length); memset(characters, ' ', length);
for (word i = 0 ; i < length; ++i) for (word i = 0; i < length; ++i)
attributes[i] = attribute; attributes[i] = attribute;
return; return;
} }
for (unsigned i = 0 ; i < length; ++i) { for (unsigned i = 0; i < length; ++i) {
if (characters[i] != ' ') if (characters[i] != ' ')
dirty = true; dirty = true;
characters[i] = ' '; characters[i] = ' ';
} }
for (unsigned i = 0 ; i < length; ++i) { for (unsigned i = 0; i < length; ++i) {
if (attributes[i] != attribute) if (attributes[i] != attribute)
dirty = true; dirty = true;
attributes[i] = attribute; attributes[i] = attribute;
@ -104,9 +104,6 @@ void Terminal::Line::clear(Attribute attribute)
Terminal::~Terminal() Terminal::~Terminal()
{ {
for (int i = 0; i < m_rows; ++i)
delete m_lines[i];
delete [] m_lines;
free(m_horizontal_tabs); free(m_horizontal_tabs);
} }
@ -137,6 +134,35 @@ static inline Color lookup_color(unsigned color)
return Color::from_rgb(xterm_colors[color]); return Color::from_rgb(xterm_colors[color]);
} }
void Terminal::escape$h_l(bool should_set, bool question_param, const ParamVector& params)
{
int mode = 2;
if (params.size() > 0) {
mode = params[0];
}
if (!question_param) {
switch (mode) {
// FIXME: implement *something* for this
default:
unimplemented_escape();
break;
}
} else {
switch (mode) {
case 25:
// Hide cursor command, but doesn't need to be run (for now, because
// we don't do inverse control codes anyways)
if (should_set)
dbgprintf("Terminal: Hide Cursor escapecode recieved. Not needed: ignored.\n");
else
dbgprintf("Terminal: Show Cursor escapecode recieved. Not needed: ignored.\n");
break;
default:
break;
}
}
}
void Terminal::escape$m(const ParamVector& params) void Terminal::escape$m(const ParamVector& params)
{ {
if (params.is_empty()) { if (params.is_empty()) {
@ -243,7 +269,7 @@ void Terminal::escape$t(const ParamVector& params)
{ {
if (params.size() < 1) if (params.size() < 1)
return; return;
dbgprintf("FIXME: escape$t: Ps: %u\n", params[0]); dbgprintf("FIXME: escape$t: Ps: %u (param count: %d)\n", params[0], params.size());
} }
void Terminal::escape$r(const ParamVector& params) void Terminal::escape$r(const ParamVector& params)
@ -254,12 +280,12 @@ void Terminal::escape$r(const ParamVector& params)
top = params[0]; top = params[0];
if (params.size() >= 2) if (params.size() >= 2)
bottom = params[1]; bottom = params[1];
if ((bottom - top) < 2 || bottom > m_rows) { if ((bottom - top) < 2 || bottom > m_rows || top < 0) {
dbgprintf("Error: escape: scrolling region invalid: %u-%u\n", top, bottom); dbgprintf("Error: escape$r: scrolling region invalid: %u-%u\n", top, bottom);
return; return;
} }
m_scroll_region_top = top; m_scroll_region_top = top - 1;
m_scroll_region_bottom = bottom; m_scroll_region_bottom = bottom - 1;
set_cursor(0, 0); set_cursor(0, 0);
} }
@ -379,7 +405,10 @@ void Terminal::escape$K(const ParamVector& params)
} }
break; break;
case 2: case 2:
unimplemented_escape(); // Clear the complete line
for (int i = 0; i < m_columns; ++i) {
put_character_at(m_cursor_row, i, ' ');
}
break; break;
default: default:
unimplemented_escape(); unimplemented_escape();
@ -395,9 +424,8 @@ void Terminal::escape$J(const ParamVector& params)
switch (mode) { switch (mode) {
case 0: case 0:
// Clear from cursor to end of screen. // Clear from cursor to end of screen.
for (int i = m_cursor_column; i < m_columns; ++i) { for (int i = m_cursor_column; i < m_columns; ++i)
put_character_at(m_cursor_row, i, ' '); put_character_at(m_cursor_row, i, ' ');
}
for (int row = m_cursor_row + 1; row < m_rows; ++row) { for (int row = m_cursor_row + 1; row < m_rows; ++row) {
for (int column = 0; column < m_columns; ++column) { for (int column = 0; column < m_columns; ++column) {
put_character_at(row, column, ' '); put_character_at(row, column, ' ');
@ -405,8 +433,14 @@ void Terminal::escape$J(const ParamVector& params)
} }
break; break;
case 1: case 1:
// FIXME: Clear from cursor to beginning of screen. /// Clear from cursor to beginning of screen
unimplemented_escape(); for (int i = m_cursor_column - 1; i >= 0; --i)
put_character_at(m_cursor_row, i, ' ');
for (int row = m_cursor_row - 1; row >= 0; --row) {
for (int column = 0; column < m_columns; ++column) {
put_character_at(row, column, ' ');
}
}
break; break;
case 2: case 2:
clear(); clear();
@ -426,7 +460,6 @@ void Terminal::escape$S(const ParamVector& params)
int count = 1; int count = 1;
if (params.size() >= 1) if (params.size() >= 1)
count = params[0]; count = params[0];
dbgprintf("Terminal: Scrolling up %d lines\n", count);
for (word i = 0; i < count; i++) for (word i = 0; i < count; i++)
scroll_up(); scroll_up();
@ -437,7 +470,6 @@ void Terminal::escape$T(const ParamVector& params)
int count = 1; int count = 1;
if (params.size() >= 1) if (params.size() >= 1)
count = params[0]; count = params[0];
dbgprintf("Terminal: Scrolling down %d lines\n", count);
for (word i = 0; i < count; i++) for (word i = 0; i < count; i++)
scroll_down(); scroll_down();
@ -448,12 +480,14 @@ void Terminal::escape$L(const ParamVector& params)
int count = 1; int count = 1;
if (params.size() >= 1) if (params.size() >= 1)
count = params[0]; count = params[0];
dbgprintf("Terminal: Adding %d lines below cursor (at line %d)\n", count, m_cursor_row);
invalidate_cursor(); invalidate_cursor();
for (word row = m_rows; row > m_cursor_row; --row) for (; count > 0; --count) {
m_lines[row] = m_lines[row - 1]; m_lines.insert(m_cursor_row + m_scroll_region_top, make<Line>(m_columns));
m_lines[m_cursor_row] = new Line(m_columns); if (m_scroll_region_bottom + 1 < m_lines.size())
++m_rows_to_scroll_backing_store; m_lines.remove(m_scroll_region_bottom + 1);
else
m_lines.remove(m_lines.size() - 1);
}
m_need_full_flush = true; m_need_full_flush = true;
} }
@ -468,15 +502,16 @@ void Terminal::escape$M(const ParamVector& params)
return; return;
} }
int max_count = m_rows - m_cursor_row; int max_count = m_rows - (m_scroll_region_top + m_cursor_row);
count = min(count, max_count); count = min(count, max_count);
dbgprintf("Delete %d line(s) starting from %d\n", count, m_cursor_row); for (int c = count; c > 0; --c) {
for (word i = 0; i < count; ++i) m_lines.remove(m_cursor_row + m_scroll_region_top);
delete m_lines[m_cursor_row + i]; if (m_scroll_region_bottom < m_lines.size())
for (word row = m_cursor_row + count + 1; row < rows(); ++row) m_lines.insert(m_scroll_region_bottom, make<Line>(m_columns));
m_lines[row - 1] = m_lines[row]; else
m_lines[m_rows - 1]->clear(m_current_attribute); m_lines.append(make<Line>(m_columns));
}
} }
void Terminal::execute_xterm_command() void Terminal::execute_xterm_command()
@ -502,45 +537,116 @@ void Terminal::execute_xterm_command()
void Terminal::execute_escape_sequence(byte final) void Terminal::execute_escape_sequence(byte final)
{ {
bool question_param = false;
m_final = final; m_final = final;
auto paramparts = String::copy(m_parameters).split(';');
ParamVector params; ParamVector params;
if (m_parameters.size() > 0 && m_parameters[0] == '?') {
question_param = true;
m_parameters.remove(0);
}
auto paramparts = String::copy(m_parameters).split(';');
for (auto& parampart : paramparts) { for (auto& parampart : paramparts) {
bool ok; bool ok;
unsigned value = parampart.to_uint(ok); unsigned value = parampart.to_uint(ok);
if (!ok) { if (!ok) {
// FIXME: Should we do something else?
m_parameters.clear_with_capacity(); m_parameters.clear_with_capacity();
m_intermediates.clear_with_capacity(); m_intermediates.clear_with_capacity();
// FIXME: Should we do something else?
return; return;
} }
params.append(value); params.append(value);
} }
#if defined(TERMINAL_DEBUG)
dbgprintf("Terminal::execute_escape_sequence: Handled final '%c'\n", final);
dbgprintf("Params: ");
for (auto& p : params) {
dbgprintf("%d ", p);
}
dbgprintf("\b\n");
#endif
switch (final) { switch (final) {
case 'A': escape$A(params); break; case 'A':
case 'B': escape$B(params); break; escape$A(params);
case 'C': escape$C(params); break; break;
case 'D': escape$D(params); break; case 'B':
case 'H': escape$H(params); break; escape$B(params);
case 'J': escape$J(params); break; break;
case 'K': escape$K(params); break; case 'C':
case 'M': escape$M(params); break; escape$C(params);
case 'S': escape$S(params); break; break;
case 'T': escape$T(params); break; case 'D':
case 'L': escape$L(params); break; escape$D(params);
case 'G': escape$G(params); break; break;
case 'X': escape$X(params); break; case 'H':
case 'd': escape$d(params); break; escape$H(params);
case 'm': escape$m(params); break; break;
case 's': escape$s(params); break; case 'J':
case 'u': escape$u(params); break; escape$J(params);
case 't': escape$t(params); break; break;
case 'r': escape$r(params); break; case 'K':
escape$K(params);
break;
case 'M':
escape$M(params);
break;
case 'S':
escape$S(params);
break;
case 'T':
escape$T(params);
break;
case 'L':
escape$L(params);
break;
case 'G':
escape$G(params);
break;
case 'X':
escape$X(params);
break;
case 'd':
escape$d(params);
break;
case 'm':
escape$m(params);
break;
case 's':
escape$s(params);
break;
case 'u':
escape$u(params);
break;
case 't':
escape$t(params);
break;
case 'r':
escape$r(params);
break;
case 'l':
escape$h_l(true, question_param, params);
break;
case 'h':
escape$h_l(false, question_param, params);
break;
default: default:
dbgprintf("Terminal::execute_escape_sequence: Unhandled final '%c'\n", final); dbgprintf("Terminal::execute_escape_sequence: Unhandled final '%c'\n", final);
break; break;
} }
#if defined(TERMINAL_DEBUG)
dbgprintf("\n");
for (auto& line : m_lines) {
dbgprintf("Terminal: Line: ");
for (int i = 0; i < line->length; i++) {
dbgprintf("%c", line->characters[i]);
}
dbgprintf("\n");
}
#endif
m_parameters.clear_with_capacity(); m_parameters.clear_with_capacity();
m_intermediates.clear_with_capacity(); m_intermediates.clear_with_capacity();
} }
@ -548,7 +654,7 @@ void Terminal::execute_escape_sequence(byte final)
void Terminal::newline() void Terminal::newline()
{ {
word new_row = m_cursor_row; word new_row = m_cursor_row;
if (m_cursor_row == (rows() - 1)) { if (m_cursor_row == m_scroll_region_bottom) {
scroll_up(); scroll_up();
} else { } else {
++new_row; ++new_row;
@ -560,11 +666,8 @@ void Terminal::scroll_up()
{ {
// NOTE: We have to invalidate the cursor first. // NOTE: We have to invalidate the cursor first.
invalidate_cursor(); invalidate_cursor();
delete m_lines[m_scroll_region_top]; m_lines.remove(m_scroll_region_top);
for (word row = m_scroll_region_top + 1; row < m_scroll_region_bottom; ++row) m_lines.insert(m_scroll_region_bottom, make<Line>(m_columns));
m_lines[row - 1] = m_lines[row];
m_lines[m_scroll_region_bottom - 1] = new Line(m_columns);
++m_rows_to_scroll_backing_store;
m_need_full_flush = true; m_need_full_flush = true;
} }
@ -572,10 +675,8 @@ void Terminal::scroll_down()
{ {
// NOTE: We have to invalidate the cursor first. // NOTE: We have to invalidate the cursor first.
invalidate_cursor(); invalidate_cursor();
for (word row = m_scroll_region_bottom; row > m_scroll_region_top; --row) m_lines.remove(m_scroll_region_bottom);
m_lines[row] = m_lines[row - 1]; m_lines.insert(m_scroll_region_top, make<Line>(m_columns));
m_lines[m_scroll_region_top] = new Line(m_columns);
--m_rows_to_scroll_backing_store;
m_need_full_flush = true; m_need_full_flush = true;
} }
@ -590,7 +691,7 @@ void Terminal::set_cursor(unsigned a_row, unsigned a_column)
invalidate_cursor(); invalidate_cursor();
m_cursor_row = row; m_cursor_row = row;
m_cursor_column = column; m_cursor_column = column;
if (column != columns() - 1) if (column != columns() - 1u)
m_stomp = false; m_stomp = false;
invalidate_cursor(); invalidate_cursor();
} }
@ -600,8 +701,6 @@ void Terminal::put_character_at(unsigned row, unsigned column, byte ch)
ASSERT(row < rows()); ASSERT(row < rows());
ASSERT(column < columns()); ASSERT(column < columns());
auto& line = this->line(row); auto& line = this->line(row);
if ((line.characters[column] == ch) && (line.attributes[column] == m_current_attribute))
return;
line.characters[column] = ch; line.characters[column] = ch;
line.attributes[column] = m_current_attribute; line.attributes[column] = m_current_attribute;
line.dirty = true; line.dirty = true;
@ -693,8 +792,8 @@ void Terminal::on_char(byte ch)
m_visual_beep_timer.restart(200); m_visual_beep_timer.restart(200);
m_visual_beep_timer.set_single_shot(true); m_visual_beep_timer.set_single_shot(true);
m_visual_beep_timer.on_timeout = [this] { m_visual_beep_timer.on_timeout = [this] {
force_repaint(); force_repaint();
}; };
force_repaint(); force_repaint();
} }
return; return;
@ -768,17 +867,22 @@ void Terminal::set_size(word columns, word rows)
if (columns == m_columns && rows == m_rows) if (columns == m_columns && rows == m_rows)
return; return;
if (m_lines) { #if defined(TERMINAL_DEBUG)
for (size_t i = 0; i < m_rows; ++i) dbgprintf("Terminal: RESIZE to: %d rows\n", rows);
delete m_lines[i]; #endif
delete m_lines;
if (rows > m_rows) {
while (m_lines.size() < rows)
m_lines.append(make<Line>(columns));
} else {
m_lines.resize(rows);
} }
m_columns = columns; m_columns = columns;
m_rows = rows; m_rows = rows;
m_scroll_region_top = 0; m_scroll_region_top = 0;
m_scroll_region_bottom = rows; m_scroll_region_bottom = rows - 1;
m_cursor_row = 0; m_cursor_row = 0;
m_cursor_column = 0; m_cursor_column = 0;
@ -793,17 +897,12 @@ void Terminal::set_size(word columns, word rows)
// Rightmost column is always last tab on line. // Rightmost column is always last tab on line.
m_horizontal_tabs[columns - 1] = 1; m_horizontal_tabs[columns - 1] = 1;
m_lines = new Line*[rows];
for (size_t i = 0; i < rows; ++i)
m_lines[i] = new Line(columns);
m_pixel_width = (frame_thickness() * 2) + (m_inset * 2) + (m_columns * font().glyph_width('x')); m_pixel_width = (frame_thickness() * 2) + (m_inset * 2) + (m_columns * font().glyph_width('x'));
m_pixel_height = (frame_thickness() * 2) + (m_inset * 2) + (m_rows * (font().glyph_height() + m_line_spacing)) - m_line_spacing; m_pixel_height = (frame_thickness() * 2) + (m_inset * 2) + (m_rows * (font().glyph_height() + m_line_spacing)) - m_line_spacing;
set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed); set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
set_preferred_size({ m_pixel_width, m_pixel_height }); set_preferred_size({ m_pixel_width, m_pixel_height });
m_rows_to_scroll_backing_store = 0;
m_needs_background_fill = true; m_needs_background_fill = true;
force_repaint(); force_repaint();
@ -888,7 +987,9 @@ void Terminal::keydown_event(GKeyEvent& event)
write(m_ptm_fd, "\033[F", 3); write(m_ptm_fd, "\033[F", 3);
break; break;
case KeyCode::Key_RightShift: case KeyCode::Key_RightShift:
dbgprintf("Terminal: A wild Right Shift key is pressed. Not handled.\n"); // Prevent RightShift from being sent to whatever's running in the
// terminal. Prevents `~@` (null) character from being sent after every
// character entered with right shift.
break; break;
default: default:
write(m_ptm_fd, &ch, 1); write(m_ptm_fd, &ch, 1);
@ -902,44 +1003,23 @@ void Terminal::paint_event(GPaintEvent& event)
GPainter painter(*this); GPainter painter(*this);
if (m_needs_background_fill) { if (m_visual_beep_timer.is_active())
m_needs_background_fill = false; painter.fill_rect(frame_inner_rect(), Color::Red);
if (m_visual_beep_timer.is_active()) else
painter.fill_rect(frame_inner_rect(), Color::Red); painter.fill_rect(frame_inner_rect(), Color(Color::Black).with_alpha(255 * m_opacity));
else
painter.fill_rect(frame_inner_rect(), Color(Color::Black).with_alpha(255 * m_opacity));
}
if (m_rows_to_scroll_backing_store && m_rows_to_scroll_backing_store < m_rows) {
int first_scanline = m_inset;
int second_scanline = m_inset + (m_rows_to_scroll_backing_store * m_line_height);
int num_rows_to_memcpy = m_rows - m_rows_to_scroll_backing_store;
int scanlines_to_copy = (num_rows_to_memcpy * m_line_height) - m_line_spacing;
memcpy(
painter.target()->scanline(first_scanline),
painter.target()->scanline(second_scanline),
scanlines_to_copy * painter.target()->pitch()
);
line(max(0, m_cursor_row - m_rows_to_scroll_backing_store)).dirty = true;
}
m_rows_to_scroll_backing_store = 0;
invalidate_cursor(); invalidate_cursor();
for (word row = 0; row < m_rows; ++row) { for (word row = 0; row < m_rows; ++row) {
auto& line = this->line(row); auto& line = this->line(row);
if (!line.dirty)
continue;
line.dirty = false;
bool has_only_one_background_color = line.has_only_one_background_color(); bool has_only_one_background_color = line.has_only_one_background_color();
if (m_visual_beep_timer.is_active()) if (m_visual_beep_timer.is_active())
painter.fill_rect(row_rect(row), Color::Red); painter.fill_rect(row_rect(row), Color::Red);
else if (has_only_one_background_color) else if (has_only_one_background_color)
painter.fill_rect(row_rect(row), lookup_color(line.attributes[0].background_color).with_alpha(255 * m_opacity)); painter.fill_rect(row_rect(row), lookup_color(line.attributes[0].background_color).with_alpha(255 * m_opacity));
for (word column = 0; column < m_columns; ++column) { for (word column = 0; column < m_columns; ++column) {
char ch = line.characters[column];
bool should_reverse_fill_for_cursor = m_cursor_blink_state && m_in_active_window && row == m_cursor_row && column == m_cursor_column; bool should_reverse_fill_for_cursor = m_cursor_blink_state && m_in_active_window && row == m_cursor_row && column == m_cursor_column;
auto& attribute = line.attributes[column]; auto& attribute = line.attributes[column];
char ch = line.characters[column];
auto character_rect = glyph_rect(row, column); auto character_rect = glyph_rect(row, column);
if (!has_only_one_background_color || should_reverse_fill_for_cursor) { if (!has_only_one_background_color || should_reverse_fill_for_cursor) {
auto cell_rect = character_rect.inflated(0, m_line_spacing); auto cell_rect = character_rect.inflated(0, m_line_spacing);

View file

@ -72,6 +72,7 @@ private:
void escape$S(const ParamVector&); void escape$S(const ParamVector&);
void escape$T(const ParamVector&); void escape$T(const ParamVector&);
void escape$L(const ParamVector&); void escape$L(const ParamVector&);
void escape$h_l(bool, bool, const ParamVector&);
void clear(); void clear();
@ -97,7 +98,8 @@ private:
byte foreground_color; byte foreground_color;
byte background_color; byte background_color;
enum Flags { enum Flags
{
NoAttributes = 0x00, NoAttributes = 0x00,
Bold = 0x01, Bold = 0x01,
Italic = 0x02, Italic = 0x02,
@ -136,7 +138,10 @@ private:
return *m_lines[index]; return *m_lines[index];
} }
Line** m_lines { nullptr }; Vector<OwnPtr<Line>> m_lines;
int m_scroll_region_top { 0 };
int m_scroll_region_bottom { 0 };
word m_columns { 0 }; word m_columns { 0 };
word m_rows { 0 }; word m_rows { 0 };
@ -148,8 +153,6 @@ private:
bool m_stomp { false }; bool m_stomp { false };
bool m_should_beep { false }; bool m_should_beep { false };
byte m_scroll_region_top { 0 };
byte m_scroll_region_bottom { 0 };
Attribute m_current_attribute; Attribute m_current_attribute;
@ -179,7 +182,6 @@ private:
int m_pixel_width { 0 }; int m_pixel_width { 0 };
int m_pixel_height { 0 }; int m_pixel_height { 0 };
int m_rows_to_scroll_backing_store { 0 };
int m_inset { 2 }; int m_inset { 2 };
int m_line_spacing { 4 }; int m_line_spacing { 4 };

View file

@ -20,6 +20,7 @@
#include <LibGUI/GAction.h> #include <LibGUI/GAction.h>
#include <LibGUI/GFontDatabase.h> #include <LibGUI/GFontDatabase.h>
#include <LibGUI/GSlider.h> #include <LibGUI/GSlider.h>
#include <LibGUI/GRadioButton.h>
#include <LibCore/CUserInfo.h> #include <LibCore/CUserInfo.h>
static void make_shell(int ptm_fd) static void make_shell(int ptm_fd)

1
Kernel/.gitignore vendored
View file

@ -8,3 +8,4 @@ sync-local.sh
*.pcap *.pcap
eth_null* eth_null*
_disk_image _disk_image
compile_commmands.json

View file

@ -109,7 +109,4 @@ enum
*/ */
#define _POSIX_PRIORITY_SCHEDULING #define _POSIX_PRIORITY_SCHEDULING
// Stifle an less error iirc
#define _PC_VDISABLE 8
__END_DECLS __END_DECLS