Mercurial > mplayer.hg
comparison libvo/vo_fbdev.c @ 305:6c3a6322f81c
directcolor support?
author | szabii |
---|---|
date | Sat, 07 Apr 2001 22:03:18 +0000 |
parents | 604b37178b3d |
children | 344d115a285d |
comparison
equal
deleted
inserted
replaced
304:662f876d77e9 | 305:6c3a6322f81c |
---|---|
1 /* | |
2 * Video driver for Framebuffer device | |
3 * by Szabolcs Berecz <szabi@inf.elte.hu> | |
4 * | |
5 * Some idea and code borrowed from Chris Lawrence's ppmtofb-0.27 | |
6 */ | |
7 | |
1 #include <stdio.h> | 8 #include <stdio.h> |
2 #include <stdlib.h> | 9 #include <stdlib.h> |
3 #include <string.h> | 10 #include <string.h> |
4 #include <fcntl.h> | 11 #include <fcntl.h> |
5 #include <unistd.h> | 12 #include <unistd.h> |
48 static uint8_t *next_frame; | 55 static uint8_t *next_frame; |
49 static int screen_width; | 56 static int screen_width; |
50 static uint32_t pixel_format; | 57 static uint32_t pixel_format; |
51 | 58 |
52 static int fb_init_done = 0; | 59 static int fb_init_done = 0; |
60 static int fb_works = 0; | |
61 | |
62 /* | |
63 * Note: this function is completely cut'n'pasted from | |
64 * Chris Lawrence's code. | |
65 * (modified to fit in my code :) ) | |
66 */ | |
67 struct fb_cmap *make_directcolor_cmap(struct fb_var_screeninfo *var) | |
68 { | |
69 /* Hopefully any DIRECTCOLOR device will have a big enough palette | |
70 * to handle mapping the full color depth. | |
71 * e.g. 8 bpp -> 256 entry palette | |
72 * | |
73 * We could handle some sort of gamma here | |
74 */ | |
75 int i, cols, rcols, gcols, bcols; | |
76 uint16_t *red, *green, *blue; | |
77 struct fb_cmap *cmap; | |
78 | |
79 rcols = 1 << var->red.length; | |
80 gcols = 1 << var->green.length; | |
81 bcols = 1 << var->blue.length; | |
82 | |
83 /* Make our palette the length of the deepest color */ | |
84 cols = (rcols > gcols ? rcols : gcols); | |
85 cols = (cols > bcols ? cols : bcols); | |
86 | |
87 red = malloc(cols * sizeof(red[0])); | |
88 if(!red) { | |
89 printf("Can't allocate red palette with %d entries.\n", cols); | |
90 return NULL; | |
91 } | |
92 for(i=0; i< rcols; i++) | |
93 red[i] = (65535/(rcols-1)) * i; | |
94 | |
95 green = malloc(cols * sizeof(green[0])); | |
96 if(!green) { | |
97 printf("Can't allocate green palette with %d entries.\n", cols); | |
98 free(red); | |
99 return NULL; | |
100 } | |
101 for(i=0; i< gcols; i++) | |
102 green[i] = (65535/(gcols-1)) * i; | |
103 | |
104 blue = malloc(cols * sizeof(blue[0])); | |
105 if(!blue) { | |
106 printf("Can't allocate blue palette with %d entries.\n", cols); | |
107 free(red); | |
108 free(green); | |
109 return NULL; | |
110 } | |
111 for(i=0; i< bcols; i++) | |
112 blue[i] = (65535/(bcols-1)) * i; | |
113 | |
114 cmap = malloc(sizeof(struct fb_cmap)); | |
115 if(!cmap) { | |
116 printf("Can't allocate color map\n"); | |
117 free(red); | |
118 free(green); | |
119 free(blue); | |
120 return NULL; | |
121 } | |
122 cmap->start = 0; | |
123 cmap->transp = 0; | |
124 cmap->len = cols; | |
125 cmap->red = red; | |
126 cmap->blue = blue; | |
127 cmap->green = green; | |
128 cmap->transp = NULL; | |
129 | |
130 return cmap; | |
131 } | |
53 | 132 |
54 static int fb_init(void) | 133 static int fb_init(void) |
55 { | 134 { |
56 int fd; | 135 int fd; |
136 struct fb_cmap *cmap; | |
57 #if 0 | 137 #if 0 |
58 int vt; | 138 int vt; |
59 char vt_name[11]; | 139 char vt_name[11]; |
60 struct vt_stat vt_state; | 140 struct vt_stat vt_state; |
61 struct vt_mode vt_mode; | 141 struct vt_mode vt_mode; |
110 fb_dev_name = "/dev/fb0"; | 190 fb_dev_name = "/dev/fb0"; |
111 printf("fb_init: using %s\n", fb_dev_name); | 191 printf("fb_init: using %s\n", fb_dev_name); |
112 | 192 |
113 if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) { | 193 if ((fb_dev_fd = open(fb_dev_name, O_RDWR)) == -1) { |
114 printf("fb_init: Can't open %s: %s\n", fb_dev_name, strerror(errno)); | 194 printf("fb_init: Can't open %s: %s\n", fb_dev_name, strerror(errno)); |
115 return 1; | 195 goto err_out; |
116 } | 196 } |
117 | 197 |
118 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_var_info)) { | 198 if (ioctl(fb_dev_fd, FBIOGET_VSCREENINFO, &fb_var_info)) { |
119 printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno)); | 199 printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno)); |
120 return 1; | 200 goto err_out_fd; |
121 } | 201 } |
122 | 202 |
123 /* disable scrolling */ | 203 /* disable scrolling */ |
124 fb_xres_virtual = fb_var_info.xres_virtual; | 204 fb_xres_virtual = fb_var_info.xres_virtual; |
125 fb_yres_virtual = fb_var_info.yres_virtual; | 205 fb_yres_virtual = fb_var_info.yres_virtual; |
126 fb_var_info.xres_virtual = fb_var_info.xres; | 206 fb_var_info.xres_virtual = fb_var_info.xres; |
127 fb_var_info.yres_virtual = fb_var_info.yres; | 207 fb_var_info.yres_virtual = fb_var_info.yres; |
128 | 208 |
129 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) { | 209 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) { |
130 printf("fb_init: Can't put VSCREENINFO: %s\n", strerror(errno)); | 210 printf("fb_init: Can't put VSCREENINFO: %s\n", strerror(errno)); |
131 return 1; | 211 goto err_out_fd; |
132 } | 212 } |
133 | 213 |
134 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_fix_info)) { | 214 if (ioctl(fb_dev_fd, FBIOGET_FSCREENINFO, &fb_fix_info)) { |
135 printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno)); | 215 printf("fb_init: Can't get VSCREENINFO: %s\n", strerror(errno)); |
216 goto err_out_fd; | |
136 return 1; | 217 return 1; |
137 } | 218 } |
138 switch (fb_fix_info.type) { | 219 switch (fb_fix_info.type) { |
139 case FB_TYPE_VGA_PLANES: | 220 case FB_TYPE_VGA_PLANES: |
140 printf("fb_init: FB_TYPE_VGA_PLANES not supported.\n"); | 221 printf("fb_init: FB_TYPE_VGA_PLANES not supported.\n"); |
141 return 1; | 222 goto err_out_fd; |
142 break; | 223 break; |
143 case FB_TYPE_PLANES: | 224 case FB_TYPE_PLANES: |
144 printf("fb_init: FB_TYPE_PLANES not supported.\n"); | 225 printf("fb_init: FB_TYPE_PLANES not supported.\n"); |
145 return 1; | 226 goto err_out_fd; |
146 break; | 227 break; |
147 case FB_TYPE_INTERLEAVED_PLANES: | 228 case FB_TYPE_INTERLEAVED_PLANES: |
148 printf("fb_init: FB_TYPE_INTERLEAVED_PLANES not supported.\n"); | 229 printf("fb_init: FB_TYPE_INTERLEAVED_PLANES not supported.\n"); |
149 return 1; | 230 goto err_out_fd; |
150 break; | 231 break; |
151 #ifdef FB_TYPE_TEXT | 232 #ifdef FB_TYPE_TEXT |
152 case FB_TYPE_TEXT: | 233 case FB_TYPE_TEXT: |
153 printf("fb_init: FB_TYPE_TEXT not supported.\n"); | 234 printf("fb_init: FB_TYPE_TEXT not supported.\n"); |
154 return 1; | 235 goto err_out_fd; |
155 break; | 236 break; |
156 #endif | 237 #endif |
157 case FB_TYPE_PACKED_PIXELS: | 238 case FB_TYPE_PACKED_PIXELS: |
158 /* OK */ | 239 /* OK */ |
159 printf("fb_init: FB_TYPE_PACKED_PIXELS: OK\n"); | 240 printf("fb_init: FB_TYPE_PACKED_PIXELS: OK\n"); |
160 break; | 241 break; |
161 default: | 242 default: |
162 printf("fb_init: unknown FB_TYPE: %d\n", fb_fix_info.type); | 243 printf("fb_init: unknown FB_TYPE: %d\n", fb_fix_info.type); |
163 return 1; | 244 goto err_out_fd; |
245 } | |
246 if (fb_fix_info.visual == FB_VISUAL_DIRECTCOLOR) { | |
247 printf("fb_init: creating cmap for directcolor\n"); | |
248 if (!(cmap = make_directcolor_cmap(&fb_var_info))) | |
249 goto err_out_fd; | |
250 if (ioctl(fb_dev_fd, FBIOPUTCMAP, cmap)) { | |
251 printf("fb_init: can't put cmap: %s\n", | |
252 strerror(errno)); | |
253 goto err_out_fd; | |
254 } | |
255 free(cmap->red); | |
256 free(cmap->green); | |
257 free(cmap->blue); | |
258 free(cmap); | |
164 } | 259 } |
165 | 260 |
166 fb_pixel_size = fb_var_info.bits_per_pixel / 8; | 261 fb_pixel_size = fb_var_info.bits_per_pixel / 8; |
167 fb_bpp = fb_var_info.red.length + fb_var_info.green.length + | 262 fb_bpp = fb_var_info.red.length + fb_var_info.green.length + |
168 fb_var_info.blue.length; | 263 fb_var_info.blue.length; |
169 screen_width = fb_fix_info.line_length; | 264 screen_width = fb_fix_info.line_length; |
170 fb_size = fb_fix_info.smem_len; | 265 fb_size = fb_fix_info.smem_len; |
171 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, | 266 if ((frame_buffer = (uint8_t *) mmap(0, fb_size, PROT_READ | PROT_WRITE, |
172 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) { | 267 MAP_SHARED, fb_dev_fd, 0)) == (uint8_t *) -1) { |
173 printf("fb_init: Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); | 268 printf("fb_init: Can't mmap %s: %s\n", fb_dev_name, strerror(errno)); |
174 return 1; | 269 goto err_out_fd; |
175 } | 270 } |
176 | 271 |
177 printf("fb_init: framebuffer @ %p\n", frame_buffer); | 272 printf("fb_init: framebuffer @ %p\n", frame_buffer); |
178 printf("fb_init: framebuffer size: %d bytes\n", fb_size); | 273 printf("fb_init: framebuffer size: %d bytes\n", fb_size); |
179 printf("fb_init: bpp: %d\n", fb_bpp); | 274 printf("fb_init: bpp: %d\n", fb_bpp); |
186 fb_var_info.green.length, fb_var_info.green.msb_right); | 281 fb_var_info.green.length, fb_var_info.green.msb_right); |
187 printf("fb_init: blue: %d %d %d\n", fb_var_info.blue.offset, | 282 printf("fb_init: blue: %d %d %d\n", fb_var_info.blue.offset, |
188 fb_var_info.blue.length, fb_var_info.blue.msb_right); | 283 fb_var_info.blue.length, fb_var_info.blue.msb_right); |
189 | 284 |
190 fb_init_done = 1; | 285 fb_init_done = 1; |
286 fb_works = 1; | |
191 return 0; | 287 return 0; |
288 err_out_fd: | |
289 close(fb_dev_fd); | |
290 fb_dev_fd = -1; | |
291 err_out: | |
292 fb_init_done = 1; | |
293 return 1; | |
192 } | 294 } |
193 | 295 |
194 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, | 296 static uint32_t init(uint32_t width, uint32_t height, uint32_t d_width, |
195 uint32_t d_height, uint32_t fullscreen, char *title, | 297 uint32_t d_height, uint32_t fullscreen, char *title, |
196 uint32_t format) | 298 uint32_t format) |
197 { | 299 { |
198 if (!fb_init_done) | 300 if (!fb_init_done) |
199 if (fb_init()) | 301 if (fb_init()) |
200 return 1; | 302 return 1; |
303 if (!fb_works) | |
304 return 1; | |
201 | 305 |
202 in_width = width; | 306 in_width = width; |
203 in_height = height; | 307 in_height = height; |
204 out_width = width; | 308 out_width = width; |
205 out_height = height; | 309 out_height = height; |
218 static uint32_t query_format(uint32_t format) | 322 static uint32_t query_format(uint32_t format) |
219 { | 323 { |
220 if (!fb_init_done) | 324 if (!fb_init_done) |
221 if (fb_init()) | 325 if (fb_init()) |
222 return 0; | 326 return 0; |
327 if (!fb_works) | |
328 return 0; | |
329 | |
223 printf("vo_fbdev: query_format(%#x(%.4s)): ", format, &format); | 330 printf("vo_fbdev: query_format(%#x(%.4s)): ", format, &format); |
224 // if (format & IMGFMT_BGR_MASK == IMGFMT_BGR) | 331 // if (format & IMGFMT_BGR_MASK == IMGFMT_BGR) |
225 // goto not_supported; | 332 // goto not_supported; |
226 switch (format) { | 333 switch (format) { |
227 case IMGFMT_YV12: | 334 case IMGFMT_YV12: |
347 static void uninit(void) | 454 static void uninit(void) |
348 { | 455 { |
349 printf("vo_fbdev: uninit\n"); | 456 printf("vo_fbdev: uninit\n"); |
350 fb_var_info.xres_virtual = fb_xres_virtual; | 457 fb_var_info.xres_virtual = fb_xres_virtual; |
351 fb_var_info.yres_virtual = fb_yres_virtual; | 458 fb_var_info.yres_virtual = fb_yres_virtual; |
352 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) | 459 if (fb_dev_fd != -1) { |
353 printf("vo_fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno)); | 460 if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_var_info)) |
354 close(fb_dev_fd); | 461 printf("vo_fbdev: Can't set virtual screensize to original value: %s\n", strerror(errno)); |
462 close(fb_dev_fd); | |
463 } | |
355 memset(next_frame, '\0', in_height * in_width * fb_pixel_size); | 464 memset(next_frame, '\0', in_height * in_width * fb_pixel_size); |
356 put_frame(); | 465 put_frame(); |
357 if (vt_active >= 0) | 466 if (vt_active >= 0) |
358 ioctl(vt_fd, VT_ACTIVATE, vt_active); | 467 ioctl(vt_fd, VT_ACTIVATE, vt_active); |
359 free(next_frame); | 468 free(next_frame); |