forked from Bananymous/banan-os
				
			Kernel: Don't wrap cursor immediatly at cols()
This prevents unwanted scrolling when writing to bottom right cell
This commit is contained in:
		
							parent
							
								
									cc7c1ad30d
								
							
						
					
					
						commit
						dabc3c6cc4
					
				|  | @ -38,6 +38,7 @@ namespace Kernel | ||||||
| 		void putcodepoint(uint32_t codepoint); | 		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 scroll_if_needed(); | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		enum class State | 		enum class State | ||||||
|  |  | ||||||
|  | @ -104,6 +104,11 @@ namespace Kernel | ||||||
| 
 | 
 | ||||||
| 	void FramebufferTerminalDriver::show_cursor(bool use_data) | 	void FramebufferTerminalDriver::show_cursor(bool use_data) | ||||||
| 	{ | 	{ | ||||||
|  | 		// NOTE: cursor is allowed to be on width as scrolling only
 | ||||||
|  | 		//       happens after character gets printed to next line
 | ||||||
|  | 		if (m_cursor_x == width()) | ||||||
|  | 			return; | ||||||
|  | 
 | ||||||
| 		if (!use_data) | 		if (!use_data) | ||||||
| 			read_cursor(); | 			read_cursor(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -140,6 +140,10 @@ namespace Kernel | ||||||
| 
 | 
 | ||||||
| 	void TextModeTerminalDriver::set_cursor_position(uint32_t x, uint32_t y) | 	void TextModeTerminalDriver::set_cursor_position(uint32_t x, uint32_t y) | ||||||
| 	{ | 	{ | ||||||
|  | 		// NOTE: cursor is allowed to be on width as scrolling only
 | ||||||
|  | 		//       happens after character gets printed to next line
 | ||||||
|  | 		if (x == m_width) | ||||||
|  | 			return; | ||||||
| 		const uint16_t pos = y * m_width + x; | 		const uint16_t pos = y * m_width + x; | ||||||
| 		IO::outb(0x3D4, 0x0F); | 		IO::outb(0x3D4, 0x0F); | ||||||
| 		IO::outb(0x3D5, pos & 0xFF); | 		IO::outb(0x3D5, pos & 0xFF); | ||||||
|  |  | ||||||
|  | @ -385,6 +385,29 @@ namespace Kernel | ||||||
| 		m_terminal_driver->putchar_at(codepoint, x, y, cell.foreground, cell.background); | 		m_terminal_driver->putchar_at(codepoint, x, y, cell.foreground, cell.background); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	void VirtualTTY::scroll_if_needed() | ||||||
|  | 	{ | ||||||
|  | 		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::putcodepoint(uint32_t codepoint) | 	void VirtualTTY::putcodepoint(uint32_t codepoint) | ||||||
| 	{ | 	{ | ||||||
| 		ASSERT(m_write_lock.current_processor_has_lock()); | 		ASSERT(m_write_lock.current_processor_has_lock()); | ||||||
|  | @ -416,37 +439,19 @@ namespace Kernel | ||||||
| 				m_state = State::WaitingAnsiEscape; | 				m_state = State::WaitingAnsiEscape; | ||||||
| 				break; | 				break; | ||||||
| 			default: | 			default: | ||||||
|  | 				if (m_column >= m_width) | ||||||
|  | 				{ | ||||||
|  | 					m_column = 0; | ||||||
|  | 					m_row++; | ||||||
|  | 				} | ||||||
|  | 				scroll_if_needed(); | ||||||
| 				putchar_at(codepoint, m_column, m_row); | 				putchar_at(codepoint, m_column, m_row); | ||||||
| 				m_last_graphic_char = codepoint; | 				m_last_graphic_char = codepoint; | ||||||
| 				m_column++; | 				m_column++; | ||||||
| 				break; | 				break; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (m_column >= m_width) | 		scroll_if_needed(); | ||||||
| 		{ |  | ||||||
| 			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) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue