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