summaryrefslogtreecommitdiff
path: root/src/drivers/video/video.c
diff options
context:
space:
mode:
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." );
+}
+