diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2017-07-21 21:10:12 +0200 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2017-07-21 21:10:12 +0200 |
commit | 6c1633b80a30c639bc096cc4b98a1da998af38c2 (patch) | |
tree | 0f45096ba3d4cfcb92ae84274e2ce2d53d95f3f7 /src/drivers/video/video.c | |
parent | 3e9f594c7e06017b5d919d79530c39a58de8a3c7 (diff) | |
download | abaos-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.c | 75 |
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." ); +} + |