summaryrefslogtreecommitdiff
path: root/src/drivers/video/video.c
blob: ca57269bd085c1f3e58aab0a7ed029c98d4a0d22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "video.h"

#include "string.h"
#include "kernel.h"

#undef DEBUG

static video_vtable_t const video_vtable = {
	{
	video_activate,
	video_deactivate,
	video_deinit,
	video_print_info
	}
};

void video_init( video_t *video, interrupt_t *interrupt, void *context )
{
	memset( video, 0, sizeof( video_t ) );

	driver_init( (driver_t *)video, DRIVER_TYPE_VIDEO, interrupt, context );

	video->nof_modes = 0;

	((driver_t *)video)->vtable = (driver_vtable_t *)&video_vtable;
}

void video_activate( void *obj )
{
	kernel_panic( "Activating generic video driver should not be called directly." );
}

void video_deactivate( void *obj )
{
	kernel_panic( "Deactivating generic video driver should not be called directly." );
}

void video_deinit( void *obj )
{
	// nothing to be done
}

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." );

	return false;
}

video_rgb_color_t video_make_rgb_color( const int R, const int G, const int B )
{
	video_rgb_color_t c;

	c.R = R;
	c.G = G;
	c.B = B;

	return c;
}

const video_rgb_color_t VIDEO_RGB_COLOR_BLACK 		= { 0x00, 0x00, 0x00 };
const video_rgb_color_t VIDEO_RGB_COLOR_BLUE 		= { 0x00, 0x00, 0xAA };
const video_rgb_color_t VIDEO_RGB_COLOR_GREEN 		= { 0x00, 0xAA, 0x00 };
const video_rgb_color_t VIDEO_RGB_COLOR_CYAN 		= { 0x00, 0xAA, 0xAA };
const video_rgb_color_t VIDEO_RGB_COLOR_RED 		= { 0xAA, 0x00, 0x00 };
const video_rgb_color_t VIDEO_RGB_COLOR_MAGENTA 	= { 0xAA, 0x00, 0xAA };
const video_rgb_color_t VIDEO_RGB_COLOR_BROWN 		= { 0xAA, 0x55, 0x00 };
const video_rgb_color_t VIDEO_RGB_COLOR_GRAY	 	= { 0xAA, 0xAA, 0xAA };
const video_rgb_color_t VIDEO_RGB_COLOR_WHITE 		= { 0xFF, 0xFF, 0xFF };

/*
0x8 	0x38 	21,21,21 	85,85,85 	#555555 	dark gray
0x9 	0x39 	21,21,63 	85,85,255 	#5555ff 	bright blue
0xA 	0x3A 	21,63,21 	85,255,85 	#55ff55 	bright green
0xB 	0x3B 	21,63,63 	85,255,255 	#55ffff 	bright cyan
0xC 	0x3C 	63,21,21 	255,85,85 	#ff5555 	bright red
0xD 	0X3D 	63,21,63 	255,85,255 	#ff55ff 	bright magenta
0xE 	0x3E 	63,63,21 	255,255,85 	#ffff55 	yellow
*/