aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/include/proto/fb.h4
-rw-r--r--src/kernel/dev/vesa.c32
2 files changed, 33 insertions, 3 deletions
diff --git a/src/common/include/proto/fb.h b/src/common/include/proto/fb.h
index 0519554..6bc6a6c 100644
--- a/src/common/include/proto/fb.h
+++ b/src/common/include/proto/fb.h
@@ -25,9 +25,9 @@ typedef struct {
framebuffer_info_t geom;
} fbdev_mode_info_t;
+#define IOCTL_FB_GET_INFO 1
+
#define IOCTL_FBDEV_GET_MODE_INFO 10
#define IOCTL_FBDEV_SET_MODE 11
-#define IOCTL_FB_GET_INFO 12
-
/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/kernel/dev/vesa.c b/src/kernel/dev/vesa.c
index f1a87d8..e60cc98 100644
--- a/src/kernel/dev/vesa.c
+++ b/src/kernel/dev/vesa.c
@@ -4,6 +4,7 @@
#include <vfs.h>
#include <nullfs.h>
+#include <process.h>
#include <dev/vesa.h>
#include <dev/v86.h>
@@ -366,7 +367,36 @@ void vesa_close(fs_handle_t *f) {
}
int vesa_ioctl(fs_handle_t *h, int command, void* data) {
- // TODO
+ vesa_driver_t *d = (vesa_driver_t*)h->node->data;
+
+ if (command == IOCTL_FBDEV_GET_MODE_INFO) {
+ fbdev_mode_info_t *m = (fbdev_mode_info_t*)data;
+
+ if ((void*)m < (void*)K_HIGHHALF_ADDR) probe_for_write(m, sizeof(fbdev_mode_info_t));
+
+ if (m->mode_number >= 0 && m->mode_number < d->nmodes) {
+ memcpy(&m->geom, &d->modes[m->mode_number].info, sizeof(framebuffer_info_t));
+ return 1;
+ }
+ } else if (command == IOCTL_FBDEV_SET_MODE) {
+ fbdev_mode_info_t *m = (fbdev_mode_info_t*)data;
+
+ if ((void*)m < (void*)K_HIGHHALF_ADDR) probe_for_read(m, sizeof(fbdev_mode_info_t));
+
+ if (m->mode_number >= 0 && m->mode_number < d->nmodes) {
+ if (vesa_set_mode(d, m->mode_number)) return 1;
+ }
+ } else if (command == IOCTL_FB_GET_INFO) {
+ if (d->current_mode != -1) {
+ framebuffer_info_t *i = (framebuffer_info_t*)data;
+
+ if ((void*)i < (void*)K_HIGHHALF_ADDR) probe_for_write(i, sizeof(framebuffer_info_t));
+ memcpy(i, &d->modes[d->current_mode].info, sizeof(framebuffer_info_t));
+
+ return 1;
+ }
+ }
+
return 0;
}