diff options
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." ); +} + |