Kernel: Fix ANSI CSI @ and b for VirtualTTY
This commit is contained in:
		
							parent
							
								
									4409d0f03f
								
							
						
					
					
						commit
						439fb57d88
					
				| 
						 | 
					@ -31,6 +31,7 @@ namespace Kernel
 | 
				
			||||||
		void reset_ansi();
 | 
							void reset_ansi();
 | 
				
			||||||
		void handle_ansi_csi(uint8_t ch);
 | 
							void handle_ansi_csi(uint8_t ch);
 | 
				
			||||||
		void handle_ansi_csi_color(uint8_t ch);
 | 
							void handle_ansi_csi_color(uint8_t ch);
 | 
				
			||||||
 | 
							void putcodepoint(uint32_t codepoint);
 | 
				
			||||||
		void putchar_at(uint32_t codepoint, uint32_t x, uint32_t y);
 | 
							void putchar_at(uint32_t codepoint, uint32_t x, uint32_t y);
 | 
				
			||||||
		void render_from_buffer(uint32_t x, uint32_t y);
 | 
							void render_from_buffer(uint32_t x, uint32_t y);
 | 
				
			||||||
		void set_cursor_position(uint32_t x, uint32_t y);
 | 
							void set_cursor_position(uint32_t x, uint32_t y);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -329,23 +329,24 @@ namespace Kernel
 | 
				
			||||||
			case '@':
 | 
								case '@':
 | 
				
			||||||
				if (m_ansi_state.nums[0] == -1)
 | 
									if (m_ansi_state.nums[0] == -1)
 | 
				
			||||||
					m_ansi_state.nums[0] = 1;
 | 
										m_ansi_state.nums[0] = 1;
 | 
				
			||||||
				reset_ansi();
 | 
									m_ansi_state.nums[0] = BAN::Math::min<uint32_t>(m_ansi_state.nums[0], m_width - m_column);
 | 
				
			||||||
 | 
									memmove(
 | 
				
			||||||
 | 
										&m_buffer[m_row * m_width + m_column],
 | 
				
			||||||
 | 
										&m_buffer[m_row * m_width + m_column + m_ansi_state.nums[0]],
 | 
				
			||||||
 | 
										m_width - m_column - m_ansi_state.nums[0]
 | 
				
			||||||
 | 
									);
 | 
				
			||||||
				for (int i = 0; i < m_ansi_state.nums[0]; i++)
 | 
									for (int i = 0; i < m_ansi_state.nums[0]; i++)
 | 
				
			||||||
					putchar_impl(' ');
 | 
										putchar_at(' ', m_column + i, m_row);
 | 
				
			||||||
				return;
 | 
									for (uint32_t x = m_column + m_ansi_state.nums[0]; x < m_width; x++)
 | 
				
			||||||
 | 
										render_from_buffer(x, m_row);
 | 
				
			||||||
 | 
									return reset_ansi();
 | 
				
			||||||
			case 'b':
 | 
								case 'b':
 | 
				
			||||||
				if (m_ansi_state.nums[0] == -1)
 | 
									if (m_ansi_state.nums[0] == -1)
 | 
				
			||||||
					m_ansi_state.nums[0] = 1;
 | 
										m_ansi_state.nums[0] = 1;
 | 
				
			||||||
				reset_ansi();
 | 
					 | 
				
			||||||
				if (m_last_graphic_char)
 | 
									if (m_last_graphic_char)
 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					char buffer[5] {};
 | 
					 | 
				
			||||||
					BAN::UTF8::from_codepoints(&m_last_graphic_char, 1, buffer);
 | 
					 | 
				
			||||||
					for (int i = 0; i < m_ansi_state.nums[0]; i++)
 | 
										for (int i = 0; i < m_ansi_state.nums[0]; i++)
 | 
				
			||||||
						for (int j = 0; buffer[j]; j++)
 | 
											putcodepoint(m_last_graphic_char);
 | 
				
			||||||
							putchar_impl(buffer[j]);
 | 
									return reset_ansi();
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return;
 | 
					 | 
				
			||||||
			case 'd':
 | 
								case 'd':
 | 
				
			||||||
				if (m_ansi_state.nums[0] == -1)
 | 
									if (m_ansi_state.nums[0] == -1)
 | 
				
			||||||
					m_ansi_state.nums[0] = 1;
 | 
										m_ansi_state.nums[0] = 1;
 | 
				
			||||||
| 
						 | 
					@ -396,6 +397,70 @@ namespace Kernel
 | 
				
			||||||
		m_terminal_driver->putchar_at(codepoint, x, y, m_foreground, m_background);
 | 
							m_terminal_driver->putchar_at(codepoint, x, y, m_foreground, m_background);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void VirtualTTY::putcodepoint(uint32_t codepoint)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ASSERT(m_write_lock.current_processor_has_lock());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (codepoint)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								case BEL: // TODO
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case BS:
 | 
				
			||||||
 | 
									if (m_column > 0)
 | 
				
			||||||
 | 
										putchar_at(' ', --m_column, m_row);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case HT:
 | 
				
			||||||
 | 
									m_column++;
 | 
				
			||||||
 | 
									while (m_column % 8)
 | 
				
			||||||
 | 
										m_column++;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case LF:
 | 
				
			||||||
 | 
									m_column = 0;
 | 
				
			||||||
 | 
									m_row++;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case FF:
 | 
				
			||||||
 | 
									m_row++;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case CR:
 | 
				
			||||||
 | 
									m_column = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case ESC:
 | 
				
			||||||
 | 
									m_state = State::WaitingAnsiEscape;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									putchar_at(codepoint, m_column, m_row);
 | 
				
			||||||
 | 
									m_last_graphic_char = codepoint;
 | 
				
			||||||
 | 
									m_column++;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (m_column >= m_width)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								m_column = 0;
 | 
				
			||||||
 | 
								m_row++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							while (m_row >= m_height)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								memmove(m_buffer, m_buffer + m_width, m_width * (m_height - 1) * sizeof(Cell));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Clear last line in buffer
 | 
				
			||||||
 | 
								for (uint32_t x = 0; x < m_width; x++)
 | 
				
			||||||
 | 
									m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!m_terminal_driver->scroll(m_background))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									// No fast scrolling, render the whole buffer to the screen
 | 
				
			||||||
 | 
									for (uint32_t y = 0; y < m_height; y++)
 | 
				
			||||||
 | 
										for (uint32_t x = 0; x < m_width; x++)
 | 
				
			||||||
 | 
											render_from_buffer(x, y);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								m_column = 0;
 | 
				
			||||||
 | 
								m_row--;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void VirtualTTY::putchar_impl(uint8_t ch)
 | 
						void VirtualTTY::putchar_impl(uint8_t ch)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ASSERT(m_write_lock.current_processor_has_lock());
 | 
							ASSERT(m_write_lock.current_processor_has_lock());
 | 
				
			||||||
| 
						 | 
					@ -465,64 +530,7 @@ namespace Kernel
 | 
				
			||||||
		m_show_cursor = false;
 | 
							m_show_cursor = false;
 | 
				
			||||||
		set_cursor_position(m_column, m_row);
 | 
							set_cursor_position(m_column, m_row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch (codepoint)
 | 
							putcodepoint(codepoint);
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			case BEL: // TODO
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			case BS:
 | 
					 | 
				
			||||||
				if (m_column > 0)
 | 
					 | 
				
			||||||
					putchar_at(' ', --m_column, m_row);
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			case HT:
 | 
					 | 
				
			||||||
				m_column++;
 | 
					 | 
				
			||||||
				while (m_column % 8)
 | 
					 | 
				
			||||||
					m_column++;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			case LF:
 | 
					 | 
				
			||||||
				m_column = 0;
 | 
					 | 
				
			||||||
				m_row++;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			case FF:
 | 
					 | 
				
			||||||
				m_row++;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			case CR:
 | 
					 | 
				
			||||||
				m_column = 0;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			case ESC:
 | 
					 | 
				
			||||||
				m_state = State::WaitingAnsiEscape;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				putchar_at(codepoint, m_column, m_row);
 | 
					 | 
				
			||||||
				m_last_graphic_char = codepoint;
 | 
					 | 
				
			||||||
				m_column++;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (m_column >= m_width)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			m_column = 0;
 | 
					 | 
				
			||||||
			m_row++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		while (m_row >= m_height)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			memmove(m_buffer, m_buffer + m_width, m_width * (m_height - 1) * sizeof(Cell));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// Clear last line in buffer
 | 
					 | 
				
			||||||
			for (uint32_t x = 0; x < m_width; x++)
 | 
					 | 
				
			||||||
				m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!m_terminal_driver->scroll(m_background))
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				// No fast scrolling, render the whole buffer to the screen
 | 
					 | 
				
			||||||
				for (uint32_t y = 0; y < m_height; y++)
 | 
					 | 
				
			||||||
					for (uint32_t x = 0; x < m_width; x++)
 | 
					 | 
				
			||||||
						render_from_buffer(x, y);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			m_column = 0;
 | 
					 | 
				
			||||||
			m_row--;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m_show_cursor = old_show_cursor;
 | 
							m_show_cursor = old_show_cursor;
 | 
				
			||||||
		set_cursor_position(m_column, m_row);
 | 
							set_cursor_position(m_column, m_row);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue