summaryrefslogtreecommitdiff
path: root/src/drivers/video/video.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-07-21 21:10:12 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-07-21 21:10:12 +0200
commit6c1633b80a30c639bc096cc4b98a1da998af38c2 (patch)
tree0f45096ba3d4cfcb92ae84274e2ce2d53d95f3f7 /src/drivers/video/video.c
parent3e9f594c7e06017b5d919d79530c39a58de8a3c7 (diff)
downloadabaos-6c1633b80a30c639bc096cc4b98a1da998af38c2.tar.gz
abaos-6c1633b80a30c639bc096cc4b98a1da998af38c2.tar.bz2
changed video mode management, moved to video driver,
the VGA driver registers his specific mode data with the video driver kernel function now use virtual functions of the video driver
Diffstat (limited to 'src/drivers/video/video.c')
-rw-r--r--src/drivers/video/video.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/drivers/video/video.c b/src/drivers/video/video.c
index eb12272..7e062a5 100644
--- a/src/drivers/video/video.c
+++ b/src/drivers/video/video.c
@@ -20,6 +20,8 @@ void video_init( video_t *video, interrupt_t *interrupt, void *context )
driver_init( (driver_t *)video, DRIVER_TYPE_VIDEO, interrupt, context );
+ video->nof_modes = 0;
+
((driver_t *)video)->vtable = (driver_vtable_t *)&video_vtable;
}
@@ -42,3 +44,76 @@ void video_print_info( void *obj )
{
kernel_panic( "Printing info of generic video driver should not be called directly." );
}
+
+video_mode_t video_make_mode( const video_mode_type_t mode_type, const int x, const int y, const int color_depth )
+{
+ video_mode_t mode;
+
+ mode.mode_type = mode_type;
+ mode.x = x;
+ mode.y = y;
+ mode.color_depth = color_depth;
+
+ return mode;
+}
+
+void video_register_mode( void *obj, const video_mode_t *mode )
+{
+ video_t *video = (video_t *)obj;
+
+ if( video->nof_modes >= MAX_NOF_VIDEO_MODES ) {
+ kernel_panic( "Trying to register too many video modes, see MAX_NOF_VIDEO_MODES: %d", MAX_NOF_VIDEO_MODES );
+ }
+
+ video->modes[video->nof_modes++] = mode;
+}
+
+static int get_matching_mode_idx( video_t *video, const video_mode_t mode )
+{
+ for( int i = 0; video->modes[i]->x != 0; i++ ) {
+ if( mode.mode_type == video->modes[i]->mode_type &&
+ mode.x == video->modes[i]->x &&
+ mode.y == video->modes[i]->y &&
+ mode.color_depth == video->modes[i]->color_depth ) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+bool video_supports_mode( void *obj, const video_mode_t mode )
+{
+ video_t *video = (video_t *)obj;
+
+ for( int i = 0; video->modes[i]->x != 0; i++ ) {
+ if( mode.mode_type == video->modes[i]->mode_type &&
+ mode.x == video->modes[i]->x &&
+ mode.y == video->modes[i]->y &&
+ mode.color_depth == video->modes[i]->color_depth ) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool video_set_mode( void *obj, const video_mode_t mode )
+{
+ video_t *video = (video_t *)obj;
+
+ // do not allow unknown timings!
+ if( !((video_vtable_t *)(video->base.vtable))->supports_mode( obj, mode ) ) {
+ return false;
+ }
+
+ const video_mode_t *matching_mode = video->modes[get_matching_mode_idx( video, mode )];
+
+ return ((video_vtable_t *)(video->base.vtable))->switch_mode( obj, matching_mode );
+}
+
+bool video_switch_mode( void *obj, const video_mode_t *mode )
+{
+ kernel_panic( "Switching mode function of abstract video driver should not be called directly." );
+}
+