diff options
author | Alex Auvolat <alex@adnab.me> | 2015-03-10 17:27:55 +0100 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2015-03-10 17:27:55 +0100 |
commit | 4ab8b6206b1ba36cbf4db4a416e04304bbd7ebc0 (patch) | |
tree | 56f7742a3b6ffb9a07aebe5d6e8b614ad9960a99 /src/kernel | |
parent | ef50c1c0de9e992db9144571e7f08e5badbb9720 (diff) | |
download | kogata-4ab8b6206b1ba36cbf4db4a416e04304bbd7ebc0.tar.gz kogata-4ab8b6206b1ba36cbf4db4a416e04304bbd7ebc0.zip |
Implement VESA ioctl (not tested).
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/dev/vesa.c | 32 |
1 files changed, 31 insertions, 1 deletions
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; } |