+ draw_census();
+
+ wait_vsync();
+ memcpy(fbptr, backbuf, fbsize);
+ }
+}
+
+static int video_init(void)
+{
+ struct vbe_edid edid;
+ struct video_mode vinf, *vmodes;
+ int i, xres, yres, nmodes, mode_idx = -1;
+ const char *vendor;
+
+ if(mode_idx == -1 && (vendor = get_video_vendor()) && strstr(vendor, "SeaBIOS")) {
+ mode_idx = find_video_mode_idx(800, 600, 32);
+ }
+
+ if(mode_idx == -1 && vbe_get_edid(&edid) == 0 && edid_preferred_resolution(&edid, &xres, &yres) == 0) {
+ printf("EDID: preferred resolution: %dx%d\n", xres, yres);
+ mode_idx = find_video_mode_idx(xres, yres, 0);
+ }
+
+ nmodes = video_mode_count();
+ if(!(vmodes = malloc(nmodes * sizeof *vmodes))) {
+ printf("failed to allocate video modes array (%d modes)\n", nmodes);
+ return -1;
+ }
+
+ for(i=0; i<nmodes; i++) {
+ video_mode_info(i, &vinf);
+ vmodes[i] = vinf;
+ }
+
+ if(mode_idx >= 0) {
+ if(!(fbptr = set_video_mode(vmodes[mode_idx].mode))) {
+ printf("failed to set video mode: %x (%dx%d %dbpp)\n", mode_idx,
+ vmodes[mode_idx].width, vmodes[mode_idx].height, vmodes[mode_idx].bpp);
+ mode_idx = -1;
+ } else {
+ vmode = vmodes[mode_idx];
+ printf("video mode: %x (%dx%d %dbpp)\n", vmode.mode, vmode.width,
+ vmode.height, vmode.bpp);
+ }
+ }
+
+ if(mode_idx == -1) {
+ qsort(vmodes, nmodes, sizeof *vmodes, modecmp);
+
+ for(i=0; i<nmodes; i++) {
+ if((fbptr = set_video_mode(vmodes[i].mode))) {
+ vmode = vmodes[i];
+ printf("video mode: %x (%dx%d %dbpp)\n", vmode.mode, vmode.width,
+ vmode.height, vmode.bpp);
+ break;