PatchworkOS  10941b4
A non-POSIX operating system.
Loading...
Searching...
No Matches
screen.c
Go to the documentation of this file.
1#include <kernel/log/screen.h>
2
5#include <kernel/log/glyphs.h>
6#include <kernel/log/panic.h>
7#include <kernel/sync/lock.h>
8
9#include <string.h>
10#include <sys/math.h>
11
12static bool hidden = false;
13
14static boot_gop_t gop = {0};
15static screen_pos_t cursor = {0, 0};
16
23
25
27{
28 size_t index = (y + offset) % height;
29 return &lines[index];
30}
31
33{
34 if (invalidStart.x == 0 && invalidStart.y == 0 && invalidEnd.x == 0 && invalidEnd.y == 0)
35 {
37 invalidEnd = (screen_pos_t){pos->x + 1, pos->y + 1};
38 }
39 else
40 {
43 invalidEnd.x = MAX(invalidEnd.x, pos->x + 1);
44 invalidEnd.y = MAX(invalidEnd.y, pos->y + 1);
45 }
46
49}
50
51static void screen_put(char chr)
52{
53 if (chr == '\n' || chr < ' ')
54 {
55 chr = ' ';
56 }
57
59 const glyph_t* glyph = &cache->glyphs[(uint8_t)chr];
60
62
64 for (uint64_t y = 0; y < GLYPH_HEIGHT; y++)
65 {
66 memcpy(&line->pixels[pixelX + y * SCREEN_LINE_STRIDE], &glyph->pixels[y * GLYPH_WIDTH],
67 sizeof(uint32_t) * GLYPH_WIDTH);
68 }
69
70 line->length = MAX(line->length, cursor.x + 1);
72}
73
74static void screen_flush(void)
75{
76 if (hidden)
77 {
78 goto flush;
79 }
80
81 for (uint64_t y = invalidStart.y; y < invalidEnd.y; y++)
82 {
84
86 {
89 (MIN(invalidEnd.x, line->length) - invalidStart.x) * GLYPH_WIDTH * sizeof(uint32_t));
90 }
91 }
92
93flush:
94 invalidStart = (screen_pos_t){0, 0};
95 invalidEnd = (screen_pos_t){0, 0};
96}
97
98void screen_init(void)
99{
101 if (bootInfo == NULL)
102 {
103 panic(NULL, "screen_init: boot info is NULL");
104 }
105
106 gop = bootInfo->gop;
107
110
111 memset(gop.virtAddr, 0, gop.height * gop.stride * sizeof(uint32_t));
112}
113
114static void screen_scroll(void)
115{
116 uint64_t newCursorY = cursor.y != 0 ? cursor.y - 1 : 0;
117
118 if (hidden)
119 {
120 goto flush;
121 }
122
123 for (uint64_t y = 0; y < newCursorY; y++)
124 {
127
128 for (uint64_t offsetY = 0; offsetY < GLYPH_HEIGHT; offsetY++)
129 {
130 memcpy(&gop.virtAddr[(offsetY + y * GLYPH_HEIGHT) * gop.stride],
131 &newLine->pixels[offsetY * SCREEN_LINE_STRIDE], newLine->length * GLYPH_WIDTH * sizeof(uint32_t));
132 }
133
134 if (line->length > newLine->length)
135 {
136 for (uint64_t offsetY = 0; offsetY < GLYPH_HEIGHT; offsetY++)
137 {
138 memset32(&gop.virtAddr[(offsetY + y * GLYPH_HEIGHT) * gop.stride + newLine->length * GLYPH_WIDTH],
139 0xFF000000, (line->length - newLine->length) * GLYPH_WIDTH);
140 }
141 }
142 }
143
145 for (uint64_t offsetY = 0; offsetY < GLYPH_HEIGHT; offsetY++)
146 {
147 memset32(&gop.virtAddr[(offsetY + newCursorY * GLYPH_HEIGHT) * gop.stride], 0xFF000000,
148 last->length * GLYPH_WIDTH);
149 }
150
151flush:
153 invalidStart = (screen_pos_t){0, 0};
154 invalidEnd = (screen_pos_t){0, 0};
155 offset = (offset + 1) % height;
156
158 currentLine->length = 0;
159}
160
161static void screen_advance_cursor(char chr)
162{
163 if (chr == '\n')
164 {
165 cursor.y++;
166 cursor.x = 0;
167
168 if (cursor.y >= height)
169 {
171 }
172 }
173 else if (cursor.x >= width)
174 {
175 cursor.y++;
176 cursor.x = 0;
177
178 if (cursor.y >= height)
179 {
181 }
182
183 for (uint64_t i = 0; i < SCREEN_WRAP_INDENT; i++)
184 {
185 screen_put(' ');
186 cursor.x++;
187 }
188 }
189 else
190 {
191 cursor.x++;
192 }
193}
194
195void screen_hide(void)
196{
198 hidden = true;
199}
200
201void screen_show(void)
202{
204 hidden = false;
205
206 memset(gop.virtAddr, 0, gop.height * gop.stride * sizeof(uint32_t));
207
208 invalidStart = (screen_pos_t){0, 0};
210 screen_flush();
211}
212
214{
215 return width;
216}
217
219{
220 return height;
221}
222
223void screen_write(const char* string, uint64_t length)
224{
226
227 for (uint64_t i = 0; i < length; i++)
228 {
229 char chr = string[i];
230 screen_put(chr);
232 }
233
234 screen_flush();
235}
boot_info_t * bootInfo
Definition boot_info.c:14
int64_t y
Definition main.c:153
static uint64_t height
Definition screen.c:14
static uint64_t width
Definition screen.c:13
static const glyph_cache_t cache
Definition glyphs.c:5
#define GLYPH_HEIGHT
Definition glyphs.h:7
const glyph_cache_t * glyph_cache_get(void)
Definition glyphs.c:3848
#define GLYPH_WIDTH
Definition glyphs.h:8
boot_info_t * boot_info_get(void)
Gets the boot info structure.
Definition boot_info.c:16
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:267
#define SCREEN_WRAP_INDENT
Number of spaces to indent when a line wraps.
Definition screen.h:23
#define SCREEN_LINE_MAX_LENGTH
Maximum number of characters in a single line.
Definition screen.h:28
uint64_t screen_get_width(void)
Get screen width in characters.
Definition screen.c:213
uint64_t screen_get_height(void)
Get screen height in characters.
Definition screen.c:218
void screen_init(void)
Initialize and enable the screen logging.
Definition screen.c:80
void screen_write(const char *string, uint64_t length)
Write a string to the screen.
Definition screen.c:223
#define SCREEN_LINE_STRIDE
The stride of a screen line in pixels.
Definition screen.h:33
void screen_hide(void)
Hide the screen logging.
Definition screen.c:195
void screen_show(void)
Show the screen logging.
Definition screen.c:201
#define LOCK_CREATE()
Create a lock initializer.
Definition lock.h:69
#define LOCK_SCOPE(lock)
Acquires a lock for the reminder of the current scope.
Definition lock.h:58
#define CONFIG_SCREEN_MAX_LINES
Maximum screen lines configuration.
Definition config.h:130
#define MIN(x, y)
Definition math.h:16
#define MAX(x, y)
Definition math.h:15
#define NULL
Pointer error value.
Definition NULL.h:23
static uint64_t pos
Definition interactive.c:21
static screen_line_t * screen_get_line(size_t y)
Definition screen.c:26
static void screen_flush(void)
Definition screen.c:74
static screen_pos_t cursor
Definition screen.c:15
static void screen_scroll(void)
Definition screen.c:114
static boot_gop_t gop
Definition screen.c:14
static bool hidden
Definition screen.c:12
static uint64_t offset
Definition screen.c:19
static lock_t lock
Definition screen.c:24
static void screen_invalidate(const screen_pos_t *pos)
Definition screen.c:32
static screen_line_t lines[CONFIG_SCREEN_MAX_LINES]
Definition screen.c:22
static screen_pos_t invalidStart
Definition screen.c:20
static void screen_put(char chr)
Definition screen.c:51
static screen_pos_t invalidEnd
Definition screen.c:21
static void screen_advance_cursor(char chr)
Definition screen.c:161
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
_PUBLIC void * memset32(void *s, __UINT32_TYPE__ c, size_t n)
Definition memset32.c:4
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:61
_PUBLIC void * memset(void *s, int c, size_t n)
Definition memset.c:4
size_t stride
Definition boot_info.h:49
uint32_t * virtAddr
Definition boot_info.h:45
size_t width
Definition boot_info.h:47
size_t height
Definition boot_info.h:48
boot_gop_t gop
Definition boot_info.h:101
glyph_t glyphs[GLYPH_AMOUNT]
Definition glyphs.h:18
A simple ticket lock implementation.
Definition lock.h:44
A single line in the screen buffer.
Definition screen.h:48
uint8_t length
The distance from the start of the line to the end of the furthest away char, in chars.
Definition screen.h:49
Represents a position on the screen in character coordinates.
Definition screen.h:39
uint8_t x
Definition screen.h:40
uint8_t y
Definition screen.h:41