Skip to content

Commit af560e0

Browse files
author
differrari
committed
[MOUSE, FAIL] draw cursor
1 parent fbefb6a commit af560e0

11 files changed

Lines changed: 148 additions & 21 deletions

File tree

kernel/graph/drivers/gpu_driver.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class GPUDriver {
2121
virtual void draw_string(string s, uint32_t x, uint32_t y, uint32_t scale, uint32_t color) = 0;
2222
virtual uint32_t get_char_size(uint32_t scale) = 0;
2323

24+
virtual void setup_cursor() = 0;
25+
virtual void update_cursor(uint32_t x, uint32_t y, bool full) = 0;
26+
2427
virtual draw_ctx get_ctx() = 0;
2528

2629
virtual ~GPUDriver() = default;

kernel/graph/drivers/ramfb_driver/ramfb.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,14 @@ uint32_t RamFBGPUDriver::get_char_size(uint32_t scale){
135135

136136
draw_ctx RamFBGPUDriver::get_ctx(){
137137
return (uint32_t*)back_framebuffer;
138+
}
139+
140+
void RamFBGPUDriver::setup_cursor()
141+
{
142+
143+
}
144+
145+
void RamFBGPUDriver::update_cursor(uint32_t x, uint32_t y, bool full)
146+
{
147+
138148
}

kernel/graph/drivers/ramfb_driver/ramfb.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class RamFBGPUDriver : public GPUDriver {
2121

2222
draw_ctx get_ctx() override;
2323

24+
void setup_cursor() override;
25+
void update_cursor(uint32_t x, uint32_t y, bool full) override;
26+
2427
~RamFBGPUDriver() = default;
2528

2629
private:

kernel/graph/drivers/videocore/videocore.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,14 @@ uint32_t VideoCoreGPUDriver::get_char_size(uint32_t scale){
134134

135135
draw_ctx VideoCoreGPUDriver::get_ctx(){
136136
return (uint32_t*)back_framebuffer;
137+
}
138+
139+
void VideoCoreGPUDriver::setup_cursor()
140+
{
141+
142+
}
143+
144+
void VideoCoreGPUDriver::update_cursor(uint32_t x, uint32_t y, bool full)
145+
{
146+
137147
}

kernel/graph/drivers/videocore/videocore.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class VideoCoreGPUDriver : public GPUDriver {
2020
uint32_t get_char_size(uint32_t scale) override;
2121

2222
draw_ctx get_ctx() override;
23+
24+
void setup_cursor() override;
25+
void update_cursor(uint32_t x, uint32_t y, bool full) override;
2326

2427
~VideoCoreGPUDriver() = default;
2528

kernel/graph/drivers/virtio_gpu_pci/virtio_gpu_pci.cpp

Lines changed: 92 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#define VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D 0x0105
1313
#define VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING 0x0106
1414
#define VIRTIO_GPU_CMD_GET_CAPSET_INFO 0x0108
15+
#define VIRTIO_GPU_CMD_UPDATE_CURSOR 0x0300
16+
#define VIRTIO_GPU_CMD_MOVE_CURSOR 0x0301
1517

1618
#define VIRTIO_GPU_RESP_OK_NODATA 0x1100
1719
#define VIRTIO_GPU_RESP_OK_DISPLAY_INFO 0x1101
@@ -21,10 +23,11 @@
2123
#define VIRTIO_GPU_RESP_OK_RESOURCE_UUID 0x1105
2224
#define VIRTIO_GPU_RESP_OK_MAP_INFO 0x1106
2325

24-
#define GPU_RESOURCE_ID 1
25-
2626
#define BPP 4
2727

28+
#define CONTROL_QUEUE 0
29+
#define CURSOR_QUEUE 1
30+
2831
//TODO: format logs
2932
VirtioGPUDriver* VirtioGPUDriver::try_init(gpu_size preferred_screen_size){
3033
VirtioGPUDriver* driver = new VirtioGPUDriver();
@@ -64,6 +67,8 @@ bool VirtioGPUDriver::init(gpu_size preferred_screen_size){
6467

6568
fb_set_stride(screen_size.width * BPP);
6669

70+
resource_id_counter = 0;
71+
6772
kprintf("Stride %i",screen_size.width * BPP);
6873

6974
framebuffer_size = screen_size.width * screen_size.height * BPP;
@@ -72,10 +77,14 @@ bool VirtioGPUDriver::init(gpu_size preferred_screen_size){
7277
fb_set_bounds(screen_size.width,screen_size.height);
7378

7479
get_capset();
80+
81+
fb_resource_id = new_resource_id();
82+
83+
kprintf("Resource %i", fb_resource_id);
7584

76-
if (!create_2d_resource(screen_size)) return false;
85+
if (!create_2d_resource(fb_resource_id, screen_size)) return false;
7786

78-
if (!attach_backing()) return false;
87+
if (!attach_backing(fb_resource_id, (sizedptr){framebuffer,framebuffer_size})) return false;
7988

8089
if (scanout_found)
8190
set_scanout();
@@ -87,6 +96,10 @@ bool VirtioGPUDriver::init(gpu_size preferred_screen_size){
8796
return true;
8897
}
8998

99+
uint32_t VirtioGPUDriver::new_resource_id(){
100+
return ++resource_id_counter;
101+
}
102+
90103
#define VIRTIO_GPU_MAX_SCANOUTS 16
91104

92105
typedef struct virtio_gpu_ctrl_hdr {
@@ -165,7 +178,7 @@ gpu_size VirtioGPUDriver::get_display_info(){
165178
return (gpu_size){0, 0};
166179
}
167180

168-
bool VirtioGPUDriver::create_2d_resource(gpu_size size) {
181+
bool VirtioGPUDriver::create_2d_resource(uint32_t resource_id, gpu_size size) {
169182
virtio_2d_resource* cmd = (virtio_2d_resource*)kalloc(gpu_dev.memory_page, sizeof(virtio_2d_resource), ALIGN_4KB, true, true);
170183

171184
cmd->hdr.type = VIRTIO_GPU_CMD_RESOURCE_CREATE_2D;
@@ -176,7 +189,7 @@ bool VirtioGPUDriver::create_2d_resource(gpu_size size) {
176189
cmd->hdr.padding[0] = 0;
177190
cmd->hdr.padding[1] = 0;
178191
cmd->hdr.padding[2] = 0;
179-
cmd->resource_id = GPU_RESOURCE_ID;
192+
cmd->resource_id = resource_id;
180193
cmd->format = 1; // VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM
181194
cmd->width = size.width;
182195
cmd->height = size.height;
@@ -213,7 +226,7 @@ typedef struct virtio_backing_cmd {
213226
}__attribute__((packed)) entries[1];
214227
}__attribute__((packed)) virtio_backing_cmd;
215228

216-
bool VirtioGPUDriver::attach_backing() {
229+
bool VirtioGPUDriver::attach_backing(uint32_t resource_id, sizedptr ptr) {
217230
virtio_backing_cmd* cmd = (virtio_backing_cmd*)kalloc(gpu_dev.memory_page, sizeof(virtio_backing_cmd), ALIGN_4KB, true, true);
218231

219232
cmd->hdr.type = VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING;
@@ -224,11 +237,11 @@ bool VirtioGPUDriver::attach_backing() {
224237
cmd->hdr.padding[0] = 0;
225238
cmd->hdr.padding[1] = 0;
226239
cmd->hdr.padding[2] = 0;
227-
cmd->resource_id = GPU_RESOURCE_ID;
240+
cmd->resource_id = resource_id;
228241
cmd->nr_entries = 1;
229242

230-
cmd->entries[0].addr = framebuffer;
231-
cmd->entries[0].length = framebuffer_size;
243+
cmd->entries[0].addr = ptr.ptr;
244+
cmd->entries[0].length = ptr.size;
232245
cmd->entries[0].padding = 0;
233246

234247
virtio_gpu_ctrl_hdr* resp = (virtio_gpu_ctrl_hdr*)kalloc(gpu_dev.memory_page, sizeof(virtio_gpu_ctrl_hdr), ALIGN_4KB, true, true);
@@ -267,7 +280,7 @@ bool VirtioGPUDriver::set_scanout() {
267280
cmd->r.height = screen_size.height;
268281

269282
cmd->scanout_id = scanout_id;
270-
cmd->resource_id = GPU_RESOURCE_ID;
283+
cmd->resource_id = fb_resource_id;
271284

272285
cmd->hdr.type = VIRTIO_GPU_CMD_SET_SCANOUT;
273286
cmd->hdr.flags = 0;
@@ -306,7 +319,7 @@ typedef struct virtio_transfer_cmd {
306319
uint32_t padding;
307320
}__attribute__((packed)) virtio_transfer_cmd;
308321

309-
bool VirtioGPUDriver::transfer_to_host(gpu_rect rect) {
322+
bool VirtioGPUDriver::transfer_to_host(uint32_t resource_id, gpu_rect rect) {
310323
virtio_transfer_cmd* cmd = (virtio_transfer_cmd*)kalloc(gpu_dev.memory_page, sizeof(virtio_transfer_cmd), ALIGN_4KB, true, true);
311324

312325
cmd->hdr.type = VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D;
@@ -315,7 +328,7 @@ bool VirtioGPUDriver::transfer_to_host(gpu_rect rect) {
315328
cmd->hdr.padding[0] = 0;
316329
cmd->hdr.padding[1] = 0;
317330
cmd->hdr.padding[2] = 0;
318-
cmd->resource_id = GPU_RESOURCE_ID;
331+
cmd->resource_id = resource_id;
319332
cmd->offset = 0;
320333
cmd->padding = 0;
321334
cmd->rect.x = rect.point.x;
@@ -353,11 +366,11 @@ typedef struct virtio_flush_cmd {
353366
void VirtioGPUDriver::flush() {
354367

355368
if (full_redraw) {
356-
transfer_to_host((gpu_rect){{0,0},{screen_size.width,screen_size.height}});
369+
transfer_to_host(fb_resource_id, (gpu_rect){{0,0},{screen_size.width,screen_size.height}});
357370
} else {
358371
for (uint32_t i = 0; i < dirty_count; i++) {
359372
gpu_rect r = dirty_rects[i];
360-
transfer_to_host(r);
373+
transfer_to_host(fb_resource_id, r);
361374
}
362375
}
363376

@@ -369,7 +382,7 @@ void VirtioGPUDriver::flush() {
369382
cmd->hdr.padding[0] = 0;
370383
cmd->hdr.padding[1] = 0;
371384
cmd->hdr.padding[2] = 0;
372-
cmd->resource_id = GPU_RESOURCE_ID;
385+
cmd->resource_id = fb_resource_id;
373386
cmd->padding = 0;
374387
cmd->rect.x = 0;
375388
cmd->rect.y = 0;
@@ -478,4 +491,66 @@ gpu_size VirtioGPUDriver::get_screen_size(){
478491

479492
draw_ctx VirtioGPUDriver::get_ctx(){
480493
return (uint32_t*)framebuffer;
481-
}
494+
}
495+
496+
void VirtioGPUDriver::setup_cursor()
497+
{
498+
cursor_resource_id = new_resource_id();
499+
size_t cursor_size = 64*64*BPP;
500+
create_2d_resource(cursor_resource_id, {64,64});
501+
uint32_t *cursor = (uint32_t*)kalloc(gpu_dev.memory_page, cursor_size, ALIGN_4KB, true, true);
502+
for (uint32_t i = 0; i < 64*64; i++) cursor[i] = 0xB4DD13;
503+
attach_backing(cursor_resource_id, (sizedptr){(uintptr_t)cursor, cursor_size});
504+
transfer_to_host(cursor_resource_id, {{0,0},{64,64}});
505+
}
506+
507+
struct virtio_gpu_cursor_pos {
508+
uint32_t scanout_id;
509+
uint32_t x;
510+
uint32_t y;
511+
uint32_t padding;
512+
};
513+
514+
struct virtio_gpu_update_cursor {
515+
virtio_gpu_ctrl_hdr hdr;
516+
virtio_gpu_cursor_pos pos;
517+
uint32_t resource_id;
518+
uint32_t hot_x;
519+
uint32_t hot_y;
520+
uint32_t padding;
521+
};
522+
static_assert(sizeof(virtio_gpu_update_cursor) == 56, "Update cursor command must be 56 bytes");
523+
524+
void VirtioGPUDriver::update_cursor(uint32_t x, uint32_t y, bool full)
525+
{
526+
select_queue(&gpu_dev, CURSOR_QUEUE);
527+
528+
virtio_gpu_update_cursor* cmd = (virtio_gpu_update_cursor*)kalloc(gpu_dev.memory_page, sizeof(virtio_gpu_update_cursor), ALIGN_4KB, true, true);
529+
530+
cmd->hdr.type = full ? VIRTIO_GPU_CMD_UPDATE_CURSOR : VIRTIO_GPU_CMD_MOVE_CURSOR;
531+
cmd->pos.scanout_id = scanout_id;
532+
cmd->pos.x = x;
533+
cmd->pos.y = y;
534+
cmd->resource_id = cursor_resource_id;
535+
536+
virtio_gpu_ctrl_hdr* resp = (virtio_gpu_ctrl_hdr*)kalloc(gpu_dev.memory_page, sizeof(virtio_gpu_ctrl_hdr), ALIGN_4KB, true, true);
537+
538+
if (!virtio_send(&gpu_dev, gpu_dev.common_cfg->queue_desc, gpu_dev.common_cfg->queue_driver, gpu_dev.common_cfg->queue_device,
539+
(uintptr_t)cmd, sizeof(virtio_gpu_update_cursor), (uintptr_t)resp, sizeof(virtio_gpu_ctrl_hdr), VIRTQ_DESC_F_WRITE)){
540+
select_queue(&gpu_dev, CONTROL_QUEUE);
541+
kfree((void*)cmd, sizeof(virtio_gpu_update_cursor));
542+
kfree((void*)resp, sizeof(virtio_gpu_ctrl_hdr));
543+
return;
544+
}
545+
546+
select_queue(&gpu_dev, CONTROL_QUEUE);
547+
548+
if (resp->type != VIRTIO_GPU_RESP_OK_NODATA) {
549+
kfree((void*)cmd, sizeof(virtio_gpu_update_cursor));
550+
kfree((void*)resp, sizeof(virtio_gpu_ctrl_hdr));
551+
return;
552+
}
553+
554+
kfree((void*)cmd, sizeof(virtio_gpu_update_cursor));
555+
kfree((void*)resp, sizeof(virtio_gpu_ctrl_hdr));
556+
}

kernel/graph/drivers/virtio_gpu_pci/virtio_gpu_pci.hpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class VirtioGPUDriver : public GPUDriver {
2323
uint32_t get_char_size(uint32_t scale) override;
2424

2525
draw_ctx get_ctx() override;
26+
27+
void setup_cursor() override;
28+
void update_cursor(uint32_t x, uint32_t y, bool full) override;
2629

2730
~VirtioGPUDriver() = default;
2831

@@ -33,11 +36,17 @@ class VirtioGPUDriver : public GPUDriver {
3336
uint64_t framebuffer_size;
3437

3538
gpu_size get_display_info();
36-
bool create_2d_resource(gpu_size size);
37-
bool attach_backing();
39+
bool create_2d_resource(uint32_t resource_id, gpu_size size);
40+
bool attach_backing(uint32_t resource_id, sizedptr ptr);
3841
bool set_scanout();
39-
bool transfer_to_host(gpu_rect rect);
42+
bool transfer_to_host(uint32_t resource_id, gpu_rect rect);
4043
void get_capset();
44+
uint32_t new_resource_id();
45+
46+
uint32_t resource_id_counter;
47+
48+
uint32_t fb_resource_id;
49+
uint32_t cursor_resource_id;
4150

4251
bool scanout_found;
4352
uint64_t scanout_id;

kernel/graph/graphics.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,15 @@ draw_ctx gpu_get_ctx(){
9292
return gpu_driver->get_ctx();
9393
}
9494

95+
void gpu_setup_cursor(gpu_point initial_loc){
96+
gpu_driver->setup_cursor();
97+
gpu_driver->update_cursor(initial_loc.x, initial_loc.y, true);
98+
}
99+
100+
void gpu_update_cursor(gpu_point new_loc){
101+
gpu_driver->update_cursor(new_loc.x, new_loc.y, true);
102+
}
103+
95104
driver_module graphics_module = {
96105
.name = "graphics",
97106
.mount = "/dev/graph",

kernel/graph/graphics.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ void gpu_draw_string(string s, gpu_point p, uint32_t scale, uint32_t color);
2424
uint32_t gpu_get_char_size(uint32_t scale);
2525
draw_ctx gpu_get_ctx();
2626

27+
void gpu_setup_cursor(gpu_point initial_loc);
28+
void gpu_update_cursor(gpu_point new_loc);
29+
2730
extern driver_module graphics_module;
2831

2932
#ifdef __cplusplus

kernel/input/input_dispatch.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "std/std.hpp"
88
#include "kernel_processes/kprocess_loader.h"
99
#include "math/math.h"
10+
#include "graph/graphics.h"
1011

1112
process_t* focused_proc;
1213

@@ -52,6 +53,7 @@ void register_keypress(keypress kp) {
5253
}
5354

5455
void mouse_config(gpu_point point, gpu_size size){
56+
gpu_setup_cursor(point);
5557
mouse_loc = point;
5658
screen_bounds = size;
5759
}
@@ -63,6 +65,7 @@ void register_mouse_input(mouse_input *rat){
6365
mouse_loc.y += dy;
6466
mouse_loc.x = min(max(0, mouse_loc.x), screen_bounds.width);
6567
mouse_loc.y = min(max(0, mouse_loc.y), screen_bounds.height);
68+
gpu_update_cursor({mouse_loc});
6669
}
6770

6871
gpu_point get_mouse_pos(){

0 commit comments

Comments
 (0)