+ if(vbe_info(&vbe) == -1) {
+ fprintf(stderr, "failed to retrieve VBE information\n");
+ return -1;
+ }
+ vbe_print_info(stdout, &vbe);
+
+ num_vmodes = 0;
+ max_modes = 64;
+ if(!(vmodes = malloc(max_modes * sizeof *vmodes))) {
+ fprintf(stderr, "failed to allocate video modes list\n");
+ return -1;
+ }
+
+ num = vbe_num_modes(&vbe);
+ for(i=0; i<num; i++) {
+ struct vbe_mode_info minf;
+
+ if(vbe_mode_info(vbe.modes[i], &minf) == -1) {
+ continue;
+ }
+
+ if(num_vmodes >= max_modes) {
+ int newmax = max_modes ? (max_modes << 1) : 16;
+ if(!(vmptr = realloc(vmodes, newmax * sizeof *vmodes))) {
+ fprintf(stderr, "failed to grow video mode list (%d)\n", newmax);
+ free(vmodes);
+ return -1;
+ }
+ vmodes = vmptr;
+ max_modes = newmax;
+ }
+
+ vmptr = vmodes + num_vmodes++;
+ memset(vmptr, 0, sizeof *vmptr);
+ vmptr->mode = vbe.modes[i];
+ vmptr->xsz = minf.xres;
+ vmptr->ysz = minf.yres;
+ vmptr->bpp = minf.bpp;
+ vmptr->pitch = minf.scanline_bytes;
+ if(minf.mem_model == VBE_TYPE_DIRECT) {
+ vmptr->rbits = minf.rsize;
+ vmptr->gbits = minf.gsize;
+ vmptr->bbits = minf.bsize;
+ vmptr->rshift = minf.rpos;
+ vmptr->gshift = minf.gpos;
+ vmptr->bshift = minf.bpos;
+ vmptr->rmask = calc_mask(minf.rsize, minf.rpos);
+ vmptr->gmask = calc_mask(minf.gsize, minf.gpos);
+ vmptr->bmask = calc_mask(minf.bsize, minf.bpos);
+ /*vmptr->bpp = vmptr->rbits + vmptr->gbits + vmptr->bbits;*/
+ }
+ if(minf.attr & VBE_ATTR_LFB) {
+ vmptr->fb_addr = minf.fb_addr;
+ }
+ vmptr->max_pages = minf.num_img_pages;
+ vmptr->win_gran = minf.win_gran;
+
+ printf("%04x: ", vbe.modes[i]);
+ vbe_print_mode_info(stdout, &minf);
+ }
+ fflush(stdout);
+
+ vbe_init_ver = VBE_VER_MAJOR(vbe.ver);
+ return 0;
+}
+
+void cleanup_video(void)
+{
+ free(vmodes);
+}
+
+struct video_mode *video_modes(void)
+{
+ return vmodes;
+}
+
+int num_video_modes(void)
+{
+ return num_vmodes;
+}
+
+struct video_mode *get_video_mode(int idx)
+{
+ if(idx == VMODE_CURRENT) {
+ return curmode;
+ }
+ return vmodes + idx;
+}
+
+int match_video_mode(int xsz, int ysz, int bpp)
+{
+ int i, best = -1;
+ struct video_mode *vm;
+
+ for(i=0; i<num_vmodes; i++) {
+ vm = vmodes + i;
+ if(vm->xsz != xsz || vm->ysz != ysz) continue;
+ if(SAME_BPP(vm->bpp, bpp)) {
+ best = i;