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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
#include "video.h"
#include "string.h"
#include "kernel.h"
#undef DEBUG
static video_vtable_t const video_vtable = {
{
driver_activate,
driver_deactivate,
driver_deinit,
driver_print_name,
driver_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;
}
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( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
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
*/
void video_set_pixel( void *obj, const int x, const int y, const video_rgb_color_t color )
{
kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
}
void video_draw_rectangle( void *obj, const int x, const int y, const int w, const int h, const video_rgb_color_t color )
{
kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
}
void video_clear_screen( void *obj, const video_rgb_color_t color )
{
kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
}
void video_draw_char( void *obj, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground )
{
kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
}
void video_wait_for_retrace( void *obj )
{
kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
}
void video_use_z_buffer( void *obj, bool use )
{
kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
}
void video_refresh( void *obj )
{
kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ );
}
|