void graphicsoff(void) { if (vgl_inited == 0) return; VGLBitmapDestroy(sVGLDisplay); VGLEnd(); }
void VGL_VideoQuit(_THIS) { int i, j; VGLKeyboardEnd(); if (VGLCurMode != NULL) { VGLEnd(); SDL_free(VGLCurMode); VGLCurMode = NULL; } if (hw_lock != NULL) { SDL_DestroyMutex(hw_lock); hw_lock = NULL; } for (i = 0; i < NUM_MODELISTS; i++) { if (SDL_modelist[i] != NULL) { for (j = 0; SDL_modelist[i][j] != NULL; ++j) { SDL_free(SDL_modelist[i][j]); } SDL_free(SDL_modelist[i]); SDL_modelist[i] = NULL; } } if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { this->screen->pixels = NULL; } }
/* Note: If we are terminated, this could be called in the middle of another SDL video routine -- notably UpdateRects. */ void VGL_VideoQuit(_THIS) { int i, j; /* Return the keyboard to the normal state */ VGLKeyboardEnd(); /* Reset the console video mode if we actually initialised one */ if (VGLCurMode != NULL) { VGLEnd(); SDL_free(VGLCurMode); VGLCurMode = NULL; } /* Clear the lock mutex */ if (hw_lock != NULL) { SDL_DestroyMutex(hw_lock); hw_lock = NULL; } /* Free video mode lists */ for (i = 0; i < NUM_MODELISTS; i++) { if (SDL_modelist[i] != NULL) { for (j = 0; SDL_modelist[i][j] != NULL; ++j) { SDL_free(SDL_modelist[i][j]); } SDL_free(SDL_modelist[i]); SDL_modelist[i] = NULL; } } if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { /* Direct screen access, not a memory buffer */ this->screen->pixels = NULL; } }
int main(int argc, char *argv[]) { int i,j,k; char c; int res=0; int x,y; char buttons; struct termios t_new,t_old; FILE *fsc; char buf[100]; progname=argv[0]; screen_gamma=1.5; #ifdef DEBUG log=fopen("/png/view.log","w"); #endif while((c=getopt(argc,argv,"r:g:"))!=-1) { switch(c) { case 'r': res=atoi(optarg); if(res>0) max_screen_colors=256; break; case 'g': screen_gamma=atof(optarg); break; case '?': default: usage(); exit(0); } } switch(res) { case 0: VGLInit(SW_CG640x480); break; case 1: VGLInit(SW_VGA_CG320); break; case 2: VGLInit(SW_VGA_MODEX); break; default: fprintf(stderr,"No such resolution!\n"); usage(); exit(-1); } #ifdef DEBUG fprintf(log,"VGL initialised\n"); #endif VGLSavePalette(); if(argc>optind) { res=png_load(argv[optind]); } else { VGLEnd(); usage(); exit(0); } if(res) { /* Hmm... Script? */ fsc=fopen(argv[optind],"r"); #ifdef DEBUG fprintf(log,"Trying script %s\n",argv[optind]); #endif fgets(buf,99,fsc); buf[strlen(buf)-1]='\0'; if(strncmp("VIEW SCRIPT",buf,11)!=NULL) { VGLEnd(); usage(); } if(strlen(buf)>12) { auto_chg=atoi(buf+12); } fgets(buf,99,fsc); buf[strlen(buf)-1]='\0'; nimg=atoi(buf); if(nimg==0) { VGLEnd(); usage(); } pres=(char **)calloc(nimg,sizeof(char *)); for(i=0;i<nimg;i++) { fgets(buf,99,fsc); buf[strlen(buf)-1]='\0'; pres[i]=strdup(buf); } fclose(fsc); cur_img=0; #ifdef DEBUG fprintf(log,"Script with %d entries\n",nimg); #endif png_load(pres[cur_img]); } VGLMouseInit(VGL_MOUSEHIDE); /* Prepare the keyboard */ tcgetattr(0,&t_old); memcpy(&t_new,&t_old,sizeof(struct termios)); cfmakeraw(&t_new); tcsetattr(0,TCSAFLUSH,&t_new); fcntl(0,F_SETFL,O_ASYNC); /* XXX VGLClear doesn't work.. :-(( Prepare a blank background */ bkg.Bitmap=(byte *)calloc(VGLDisplay->Xsize*VGLDisplay->Ysize,1); bkg.Xsize=VGLDisplay->Xsize; bkg.Ysize=VGLDisplay->Ysize; bkg.Type=VGLDisplay->Type; signal(SIGIO,kbd_handler); a.zoom=1; a.Xshift=(VGLDisplay->Xsize-pic.Xsize)/2; a.Yshift=(VGLDisplay->Ysize-pic.Ysize)/2; a.rotate=0; quit=0; changed=0; display(&pic,pal_red,pal_green,pal_blue,&a); while(!quit) { if(act) { #ifdef DEBUG fprintf(log,"kbd_action(%c)\n",act); #endif kbd_action(x,y,act); } if(quit) break; if(changed) { #ifdef DEBUG fprintf(log,"changed, redisplaying\n"); #endif display(&pic,pal_red,pal_green,pal_blue,&a); changed=0; } if(auto_chg) { sleep(auto_chg); kbd_action(x,y,'n'); } else { pause(); } VGLMouseStatus(&x,&y,&buttons); if(buttons & MOUSE_BUTTON3DOWN) { #ifdef DEBUG fprintf(log,"pop_up called\n"); #endif pop_up("View",x,y); } } VGLEnd(); #ifdef DEBUG fclose(log); #endif exit(0); }
int png_load(char *filename) { int i,j,k; FILE *fd; u_char header[NUMBER]; png_structp png_ptr; png_infop info_ptr,end_info; png_uint_32 width,height; int bit_depth,color_type,interlace_type; int compression_type,filter_type; int channels,rowbytes; double gamma; png_colorp palette; int num_palette; png_bytep *row_pointers; char c; int res=0; fd=fopen(filename,"rb"); if(fd==NULL) { VGLEnd(); perror("fopen"); exit(1); } fread(header,1,NUMBER,fd); if(!png_check_sig(header,NUMBER)) { fprintf(stderr,"Not a PNG file.\n"); return(-1); } png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,(void *)NULL, NULL,NULL); info_ptr=png_create_info_struct(png_ptr); end_info=png_create_info_struct(png_ptr); if(!png_ptr || !info_ptr || !end_info) { VGLEnd(); fprintf(stderr,"failed to allocate needed structs!\n"); png_destroy_read_struct(&png_ptr,&info_ptr,&end_info); return(-1); } png_set_sig_bytes(png_ptr,NUMBER); png_init_io(png_ptr,fd); png_read_info(png_ptr,info_ptr); png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth, &color_type,&interlace_type,&compression_type,&filter_type); png_get_PLTE(png_ptr,info_ptr,&palette,&num_palette); channels=png_get_channels(png_ptr,info_ptr); rowbytes=png_get_rowbytes(png_ptr,info_ptr); if(bit_depth==16) png_set_strip_16(png_ptr); if(color_type & PNG_COLOR_MASK_ALPHA) png_set_strip_alpha(png_ptr); if(png_get_gAMA(png_ptr,info_ptr,&gamma)) png_set_gamma(png_ptr,screen_gamma,gamma); else png_set_gamma(png_ptr,screen_gamma,0.45); if(res==0) { /* Dither */ if(color_type & PNG_COLOR_MASK_COLOR) { if(png_get_valid(png_ptr,info_ptr,PNG_INFO_PLTE)) { png_uint_16p histogram; png_get_hIST(png_ptr,info_ptr,&histogram); png_set_dither(png_ptr,palette,num_palette,max_screen_colors,histogram,0); } else { png_color std_color_cube[16]={ {0x00,0x00,0x00}, {0x02,0x02,0x02}, {0x04,0x04,0x04}, {0x06,0x06,0x06}, {0x08,0x08,0x08}, {0x0a,0x0a,0x0a}, {0x0c,0x0c,0x0c}, {0x0e,0x0e,0x0e}, {0x10,0x10,0x10}, {0x12,0x12,0x12}, {0x14,0x14,0x14}, {0x16,0x16,0x16}, {0x18,0x18,0x18}, {0x1a,0x1a,0x1a}, {0x1d,0x1d,0x1d}, {0xff,0xff,0xff}, }; png_set_dither(png_ptr,std_color_cube,max_screen_colors,max_screen_colors,NULL,0); } } } png_set_packing(png_ptr); if(png_get_valid(png_ptr,info_ptr,PNG_INFO_sBIT)) { png_color_8p sig_bit; png_get_sBIT(png_ptr,info_ptr,&sig_bit); png_set_shift(png_ptr,sig_bit); } png_read_update_info(png_ptr,info_ptr); png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth, &color_type,&interlace_type,&compression_type,&filter_type); png_get_PLTE(png_ptr,info_ptr,&palette,&num_palette); channels=png_get_channels(png_ptr,info_ptr); rowbytes=png_get_rowbytes(png_ptr,info_ptr); row_pointers=malloc(height*sizeof(png_bytep)); for(i=0;i<height;i++) { row_pointers[i]=malloc(rowbytes); } png_read_image(png_ptr,row_pointers); png_read_end(png_ptr,end_info); png_destroy_read_struct(&png_ptr,&info_ptr,&end_info); fclose(fd); /* Set palette */ if(res) k=2; else k=2; for(i=0;i<256;i++) { pal_red[i]=255; pal_green[i]=255; pal_blue[i]=255; } for(i=0;i<num_palette;i++) { pal_red[i]=(palette+i)->red>>k; pal_green[i]=(palette+i)->green>>k; pal_blue[i]=(palette+i)->blue>>k; } pal_colors=num_palette; if(pic.Bitmap!=NULL) free(pic.Bitmap); pic.Bitmap=(byte *)calloc(rowbytes*height,sizeof(byte)); pic.Type=MEMBUF; pic.Xsize=rowbytes; pic.Ysize=height; for(i=0;i<rowbytes;i++) { for(j=0;j<height;j++) { VGLSetXY(&pic, i,j,row_pointers[j][i]); } } a.zoom=1; a.Xshift=(VGLDisplay->Xsize-pic.Xsize)/2; a.Yshift=(VGLDisplay->Ysize-pic.Ysize)/2; a.rotate=0; return(0); }
int main(int argc, char **argv) { int y, xsize, ysize, i,j; VGLBitmap *tmp; // set graphics mode, here 320x240 256 colors // supported modes are (from <sys/consio.h>): // SW_VGA_CG320: std VGA 320x200 256 colors // SW_VGA_MODEX: Modex VGA 320x240 256 colors // SW_VGA_VG640: std VGA 640x480 16 colors VGLInit(SW_VGA_MODEX); // initialize mouse and show pointer VGLMouseInit(VGL_MOUSESHOW); // VGLDisplay is a ptr to a struct Bitmap defined and initialized by // libvgl. The Bitmap points directly to screen memory etc. xsize=VGLDisplay->Xsize; ysize=VGLDisplay->Ysize; // alloc a new bitmap tmp = VGLBitmapCreate(MEMBUF, 256, 256, NULL); VGLBitmapAllocateBits(tmp); VGLClear(tmp, 0); // fill the screen with colored lines for (y=0; y<ysize; y++) VGLLine(VGLDisplay, 0, y, xsize-1, y, y/2 % 256); // draw some lines and circles just to show off VGLLine(VGLDisplay, 0, 0, xsize-1, ysize-1, 63); VGLLine(VGLDisplay, 0, ysize-1, xsize-1, 0, 63); VGLLine(VGLDisplay, 0, 0, 0, ysize-1, 63); VGLLine(VGLDisplay, xsize-1, 0, xsize-1, ysize-1, 63); VGLEllipse(VGLDisplay, 256, 0, 256, 256, 63); VGLEllipse(VGLDisplay, 0, 256, 256, 256, 0); // some text is also useful VGLBitmapString(VGLDisplay, 100,100, "This is text", 63, 0, 0, VGL_DIR_RIGHT); sleep(2); VGLBitmapString(VGLDisplay, 100,100, "This is text", 63, 0, 0, VGL_DIR_UP); sleep(2); VGLBitmapString(VGLDisplay, 100,100, "This is text", 63, 0, 0, VGL_DIR_LEFT); sleep(2); VGLBitmapString(VGLDisplay, 100,100, "This is text", 63, 0, 0, VGL_DIR_DOWN); sleep(2); // now show some simple bitblit for (i=0; i<256; i++) for (j=0; j<256; j++) tmp->Bitmap[i+256*j] = i%16; VGLBitmapCopy(tmp, 0, 0, VGLDisplay, 0, 0, 128, 128); for (i=0; i<256; i++) for (j=0; j<256; j++) tmp->Bitmap[i+256*j] = j%16; VGLBitmapCopy(tmp, 0, 0, VGLDisplay, 3, 128, 128, 128); sleep(2); VGLBitmapCopy(VGLDisplay, 237, 311, tmp, 64, 64, 128, 128); VGLBitmapCopy(tmp, 32, 32, VGLDisplay, 400, 128, 128, 128); sleep(2); VGLBitmapCopy(VGLDisplay, 300, 300, VGLDisplay, 500, 128, 128, 128); sleep(5); i=0; // loop around drawing and copying while (++i) { VGLBitmapCopy(VGLDisplay, rand()%xsize, rand()%ysize, VGLDisplay, rand()%xsize, rand()%ysize, rand()%xsize, rand()%ysize); VGLLine(VGLDisplay, rand()%xsize, rand()%ysize, rand()%xsize, rand()%ysize, rand()%256); VGLEllipse(VGLDisplay, rand()%xsize, rand()%ysize, rand()%xsize/2, rand()%ysize/2, rand()%256); rand(); if (i > 1000) break; } // restore screen to its original mode VGLEnd(); return 0; }
SDL_Surface *VGL_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { int mode_found; int i; VGLMode **modes; modes = VGLListModes(bpp, V_INFO_MM_DIRECT | V_INFO_MM_PACKED); mode_found = 0; for (i = 0; modes[i] != NULL; i++) { if ((modes[i]->ModeInfo.Xsize == width) && (modes[i]->ModeInfo.Ysize == height) && ((modes[i]->ModeInfo.Type == VIDBUF8) || (modes[i]->ModeInfo.Type == VIDBUF16) || (modes[i]->ModeInfo.Type == VIDBUF32))) { mode_found = 1; break; } } if (mode_found == 0) { SDL_SetError("No matching video mode found"); return NULL; } if (VGLCurMode != NULL) VGLEnd(); if (VGLInit(modes[i]->ModeId) != 0) { SDL_SetError("Unable to switch to requested mode"); return NULL; } VGLCurMode = SDL_realloc(VGLCurMode, sizeof(VGLMode)); VGLCurMode->ModeInfo = *VGLDisplay; VGLCurMode->Depth = modes[i]->Depth; VGLCurMode->ModeId = modes[i]->ModeId; VGLCurMode->Rmask = modes[i]->Rmask; VGLCurMode->Gmask = modes[i]->Gmask; VGLCurMode->Bmask = modes[i]->Bmask; if (VGLCurMode->ModeInfo.PixelBytes == 0) (VGLCurMode->ModeInfo.PixelBytes = 1); current->w = VGLCurMode->ModeInfo.Xsize; current->h = VGLCurMode->ModeInfo.Ysize; current->pixels = VGLCurMode->ModeInfo.Bitmap; current->pitch = VGLCurMode->ModeInfo.Xsize * VGLCurMode->ModeInfo.PixelBytes; current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE); if (VGLCurMode->ModeInfo.Type == VIDBUF8) current->flags |= SDL_HWPALETTE; if (flags & SDL_DOUBLEBUF) { if (VGLCurMode->ModeInfo.Xsize * 2 <= VGLCurMode->ModeInfo.VYsize) { current->flags |= SDL_DOUBLEBUF; flip_page = 0; flip_address[0] = (byte *)current->pixels; flip_address[1] = (byte *)current->pixels + current->h * current->pitch; VGL_FlipHWSurface(this, current); } } if (! SDL_ReallocFormat(current, modes[i]->Depth, VGLCurMode->Rmask, VGLCurMode->Gmask, VGLCurMode->Bmask, 0)) { return NULL; } VGL_UpdateVideoInfo(this); this->UpdateRects = VGL_DirectUpdate; return current; }
void VGLCheckSwitch(void) { if (VGLAbortPending) { VGLEnd(); exit(0); } while (VGLSwitchPending) { unsigned int offset; unsigned int len; int i; VGLSwitchPending = 0; if (VGLOnDisplay) { ioctl(0, KDENABIO, 0); ioctl(0, KDSETMODE, KD_GRAPHICS); ioctl(0, VGLMode, 0); VGLCurWindow = 0; VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE, MAP_FILE, 0, 0); /* XXX: what if mmap() has failed! */ VGLDisplay->Type = VIDBUF8; /* XXX */ switch (VGLModeInfo.vi_mem_model) { case V_INFO_MM_PLANAR: if (VGLModeInfo.vi_depth == 4 && VGLModeInfo.vi_planes == 4) { if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) VGLDisplay->Type = VIDBUF4S; else VGLDisplay->Type = VIDBUF4; } else { /* shouldn't be happening */ } break; case V_INFO_MM_PACKED: if (VGLModeInfo.vi_depth == 8) { if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) VGLDisplay->Type = VIDBUF8S; else VGLDisplay->Type = VIDBUF8; } else { /* shouldn't be happening */ } break; case V_INFO_MM_VGAX: VGLDisplay->Type = VIDBUF8X; break; default: /* shouldn't be happening */ break; } VGLDisplay->Bitmap = VGLMem; VGLDisplay->Xsize = VGLModeInfo.vi_width; VGLDisplay->Ysize = VGLModeInfo.vi_height; VGLSetVScreenSize(VGLDisplay, VGLDisplay->VXsize, VGLDisplay->VYsize); VGLPanScreen(VGLDisplay, VGLDisplay->Xorigin, VGLDisplay->Yorigin); switch (VGLDisplay->Type) { case VIDBUF4S: outb(0x3c6, 0xff); outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes; offset += len) { VGLSetSegment(offset); len = min(VGLBufSize/VGLModeInfo.vi_planes - offset, VGLAdpInfo.va_window_size); for (i = 0; i < VGLModeInfo.vi_planes; i++) { outb(0x3c4, 0x02); outb(0x3c5, 0x01<<i); bcopy(&VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset], VGLMem, len); } } break; case VIDBUF4: case VIDBUF8X: outb(0x3c6, 0xff); outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ for (i = 0; i < VGLModeInfo.vi_planes; i++) { outb(0x3c4, 0x02); outb(0x3c5, 0x01<<i); bcopy(&VGLBuf[i*VGLAdpInfo.va_window_size], VGLMem, VGLAdpInfo.va_window_size); } break; case VIDBUF8: case VIDBUF8S: for (offset = 0; offset < VGLBufSize; offset += len) { VGLSetSegment(offset); len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size); bcopy(&VGLBuf[offset], VGLMem, len); } break; } VGLRestorePalette(); ioctl(0, VT_RELDISP, VT_ACKACQ); } else { switch (VGLDisplay->Type) { case VIDBUF4S: for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes; offset += len) { VGLSetSegment(offset); len = min(VGLBufSize/VGLModeInfo.vi_planes - offset, VGLAdpInfo.va_window_size); for (i = 0; i < VGLModeInfo.vi_planes; i++) { outb(0x3ce, 0x04); outb(0x3cf, i); bcopy(VGLMem, &VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset], len); } } break; case VIDBUF4: case VIDBUF8X: /* * NOTE: the saved buffer is NOT in the MEMBUF format which * the ordinary memory bitmap object is stored in. XXX */ for (i = 0; i < VGLModeInfo.vi_planes; i++) { outb(0x3ce, 0x04); outb(0x3cf, i); bcopy(VGLMem, &VGLBuf[i*VGLAdpInfo.va_window_size], VGLAdpInfo.va_window_size); } break; case VIDBUF8: case VIDBUF8S: for (offset = 0; offset < VGLBufSize; offset += len) { VGLSetSegment(offset); len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size); bcopy(VGLMem, &VGLBuf[offset], len); } break; } VGLMem = MAP_FAILED; munmap(VGLDisplay->Bitmap, VGLAdpInfo.va_window_size); ioctl(0, VGLOldMode, 0); ioctl(0, KDSETMODE, KD_TEXT); ioctl(0, KDDISABIO, 0); ioctl(0, VT_RELDISP, VT_TRUE); VGLDisplay->Bitmap = VGLBuf; VGLDisplay->Type = MEMBUF; VGLDisplay->Xsize = VGLDisplay->VXsize; VGLDisplay->Ysize = VGLDisplay->VYsize; while (!VGLOnDisplay) pause(); } } }
int VGLInit(int mode) { struct vt_mode smode; int adptype; if (VGLInitDone) return -1; signal(SIGUSR1, VGLSwitch); signal(SIGINT, VGLAbort); signal(SIGTERM, VGLAbort); signal(SIGSEGV, VGLAbort); signal(SIGBUS, VGLAbort); signal(SIGUSR2, SIG_IGN); VGLOnDisplay = 1; VGLSwitchPending = 0; VGLAbortPending = 0; if (ioctl(0, CONS_GET, &VGLOldMode) || ioctl(0, CONS_CURRENT, &adptype)) return -1; VGLModeInfo.vi_mode = mode; if (ioctl(0, CONS_MODEINFO, &VGLModeInfo)) /* FBIO_MODEINFO */ return -1; /* If current mode is VESA_800x600 then save its geometry to restore later */ if ((VGLOldMode >= M_VESA_BASE) && (VGLOldMode == M_VESA_800x600)) if (ioctl(0, TIOCGWINSZ, &VGLOldWSize)) return -1; VGLDisplay = (VGLBitmap *)malloc(sizeof(VGLBitmap)); if (VGLDisplay == NULL) return -2; if (ioctl(0, KDENABIO, 0)) { free(VGLDisplay); return -3; } VGLInitDone = 1; /* * vi_mem_model specifies the memory model of the current video mode * in -CURRENT. */ switch (VGLModeInfo.vi_mem_model) { case V_INFO_MM_PLANAR: /* we can handle EGA/VGA planner modes only */ if (VGLModeInfo.vi_depth != 4 || VGLModeInfo.vi_planes != 4 || (adptype != KD_EGA && adptype != KD_VGA)) { VGLEnd(); return -4; } VGLDisplay->Type = VIDBUF4; break; case V_INFO_MM_PACKED: /* we can do only 256 color packed modes */ if (VGLModeInfo.vi_depth != 8) { VGLEnd(); return -4; } VGLDisplay->Type = VIDBUF8; break; case V_INFO_MM_VGAX: VGLDisplay->Type = VIDBUF8X; break; default: VGLEnd(); return -4; } ioctl(0, VT_WAITACTIVE, 0); ioctl(0, KDSETMODE, KD_GRAPHICS); if (ioctl(0, CONS_SET, &mode)) { VGLEnd(); return -5; } if (ioctl(0, CONS_ADPINFO, &VGLAdpInfo)) { /* FBIO_ADPINFO */ VGLEnd(); return -6; } /* * Calculate the shadow screen buffer size. In -CURRENT, va_buffer_size * always holds the entire frame buffer size, wheather it's in the linear * mode or windowed mode. * VGLBufSize = VGLAdpInfo.va_buffer_size; * In -STABLE, va_buffer_size holds the frame buffer size, only if * the linear frame buffer mode is supported. Otherwise the field is zero. * We shall calculate the minimal size in this case: * VGLAdpInfo.va_line_width*VGLModeInfo.vi_height*VGLModeInfo.vi_planes * or * VGLAdpInfo.va_window_size*VGLModeInfo.vi_planes; * Use whichever is larger. */ if (VGLAdpInfo.va_buffer_size != 0) VGLBufSize = VGLAdpInfo.va_buffer_size; else VGLBufSize = max(VGLAdpInfo.va_line_width*VGLModeInfo.vi_height, VGLAdpInfo.va_window_size)*VGLModeInfo.vi_planes; VGLBuf = malloc(VGLBufSize); if (VGLBuf == NULL) { VGLEnd(); return -7; } #ifdef LIBVGL_DEBUG fprintf(stderr, "VGLBufSize:0x%x\n", VGLBufSize); #endif /* see if we are in the windowed buffer mode or in the linear buffer mode */ if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) { if (VGLDisplay->Type == VIDBUF4) VGLDisplay->Type = VIDBUF4S; else if (VGLDisplay->Type == VIDBUF8) VGLDisplay->Type = VIDBUF8S; } VGLMode = mode; VGLCurWindow = 0; VGLDisplay->Xsize = VGLModeInfo.vi_width; VGLDisplay->Ysize = VGLModeInfo.vi_height; VGLDisplay->VXsize = VGLAdpInfo.va_line_width *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes); VGLDisplay->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width; VGLDisplay->Xorigin = 0; VGLDisplay->Yorigin = 0; VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE, MAP_FILE, 0, 0); if (VGLMem == MAP_FAILED) { VGLEnd(); return -7; } VGLDisplay->Bitmap = VGLMem; VGLSavePalette(); #ifdef LIBVGL_DEBUG fprintf(stderr, "va_line_width:%d\n", VGLAdpInfo.va_line_width); fprintf(stderr, "VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n", VGLDisplay->Xsize, VGLDisplay->Ysize, VGLDisplay->VXsize, VGLDisplay->VYsize); #endif smode.mode = VT_PROCESS; smode.waitv = 0; smode.relsig = SIGUSR1; smode.acqsig = SIGUSR1; smode.frsig = SIGINT; if (ioctl(0, VT_SETMODE, &smode)) { VGLEnd(); return -9; } VGLTextSetFontFile(NULL); VGLClear(VGLDisplay, 0); return 0; }
int GGI_vgl_setmode(ggi_visual *vis, ggi_mode *tm) { struct vgl_priv *priv = VGL_PRIV(vis); ggi_graphtype gt = tm->graphtype; video_info_t modeinfo; unsigned long modenum = 0; char sugname[GGI_MAX_APILEN]; char args[GGI_MAX_APILEN]; int err = 0; int id, i; int pixelBytes; err = GGI_vgl_checkmode(vis, tm); if (err) return err; /* reset the modeinfo structure as expected by query_mode */ memset(&modeinfo, 0, sizeof(modeinfo)); switch(gt) { case GT_1BIT : modeinfo.vi_depth = 1; pixelBytes = 1; break; case GT_4BIT : modeinfo.vi_depth = 4; pixelBytes = 1; break; case GT_8BIT : modeinfo.vi_depth = 8; pixelBytes = 1; break; case GT_16BIT: modeinfo.vi_depth = 16; pixelBytes = 2; break; case GT_32BIT: modeinfo.vi_depth = 32; pixelBytes = 4; break; /* Unsupported mode depths */ case GT_15BIT: case GT_24BIT: default: return GGI_ENOMATCH; } modeinfo.vi_width = tm->visible.x; modeinfo.vi_height = tm->visible.y; /* XXX should be added to libvgl */ if (ioctl(0, FBIO_FINDMODE, &modeinfo)) return -1; DPRINT("Setting VGLlib mode %d (0x%x)\n", modeinfo.vi_mode, modeinfo.vi_mode); /* Terminate any current mode before initialising another */ if (priv->vgl_init_done) { priv->vgl_init_done = 0; VGLEnd(); } /* XXX should be in VGL */ if ((modeinfo.vi_mode >= M_B40x25) && (modeinfo.vi_mode <= M_VGA_M90x60)) modenum = _IO('S', modeinfo.vi_mode); if ((modeinfo.vi_mode >= M_TEXT_80x25) && (modeinfo.vi_mode <= M_TEXT_132x60)) modenum = _IO('S', modeinfo.vi_mode); if ((modeinfo.vi_mode >= M_VESA_CG640x400) && (modeinfo.vi_mode <= M_VESA_FULL_1280)) modenum = _IO('V', modeinfo.vi_mode - M_VESA_BASE); if ((err = VGLInit(modenum)) != 0) { DPRINT("display-vgl: setting mode 0x%x failed with error %d\n", modeinfo.vi_mode, err); return GGI_EFATAL; } priv->vgl_init_done = 1; if (priv->vgl_use_db) { _GGI_vgl_freedbs(vis); /* Set up DirectBuffer(s) */ for (i = 0; i<tm->frames; i++) { if (LIBGGI_FB_SIZE(tm) > (unsigned)(VGLDisplay->Xsize*VGLDisplay->Ysize* pixelBytes)) { fprintf(stderr, "display-vgl: framebuffer too large! (%d > %d*%d*%d)\n", LIBGGI_FB_SIZE(tm), VGLDisplay->Xsize, VGLDisplay->Ysize, pixelBytes); return GGI_ENOMEM; } _ggi_db_add_buffer(LIBGGI_APPLIST(vis), _ggi_db_get_new()); LIBGGI_APPBUFS(vis)[i]->frame = i; LIBGGI_APPBUFS(vis)[i]->type = GGI_DB_NORMAL | GGI_DB_SIMPLE_PLB; LIBGGI_APPBUFS(vis)[i]->read = VGLDisplay->Bitmap; LIBGGI_APPBUFS(vis)[i]->write = VGLDisplay->Bitmap; LIBGGI_APPBUFS(vis)[i]->layout = blPixelLinearBuffer; LIBGGI_APPBUFS(vis)[i]->buffer.plb.stride = GT_ByPPP(tm->virt.x, tm->graphtype); } } /* Save mode info returned by the VESA driver */ bcopy(&modeinfo, &priv->modeinfo, sizeof(priv->modeinfo)); /* Palette */ if (vis->palette) { free(vis->palette); vis->palette = NULL; } if (priv->savepalette) { free(priv->savepalette); priv->savepalette = NULL; } if (GT_SCHEME(tm->graphtype) == GT_PALETTE) { int len = 1 << GT_DEPTH(tm->graphtype); vis->palette = malloc(len * sizeof(ggi_color)); if (vis->palette == NULL) return GGI_EFATAL; priv->savepalette = malloc(sizeof(int) * (len*3)); if (priv->savepalette == NULL) return GGI_EFATAL; /* Set an initial palette */ ggiSetColorfulPalette(vis); } /* Set up pixel format */ memset(LIBGGI_PIXFMT(vis), 0, sizeof(ggi_pixelformat)); LIBGGI_PIXFMT(vis)->size = GT_SIZE(gt); LIBGGI_PIXFMT(vis)->depth = GT_DEPTH(gt); switch (GT_SCHEME(gt)) { case GT_PALETTE: case GT_GREYSCALE: LIBGGI_PIXFMT(vis)->clut_mask = (1 << GT_DEPTH(gt)) - 1; break; case GT_TRUECOLOR: DPRINT_MODE("display-vgl: RGB %d:%d:%d offsets %d:%d:%d\n", priv->modeinfo.vi_pixel_fsizes[VGL_RED_INDEX], priv->modeinfo.vi_pixel_fsizes[VGL_GREEN_INDEX], priv->modeinfo.vi_pixel_fsizes[VGL_BLUE_INDEX], priv->modeinfo.vi_pixel_fields[VGL_RED_INDEX], priv->modeinfo.vi_pixel_fields[VGL_GREEN_INDEX], priv->modeinfo.vi_pixel_fields[VGL_BLUE_INDEX]); LIBGGI_PIXFMT(vis)->red_mask = ((1 << priv->modeinfo.vi_pixel_fsizes[VGL_RED_INDEX]) - 1) << priv->modeinfo.vi_pixel_fields[VGL_RED_INDEX]; LIBGGI_PIXFMT(vis)->green_mask = ((1 << priv->modeinfo.vi_pixel_fsizes[VGL_GREEN_INDEX]) - 1) << priv->modeinfo.vi_pixel_fields[VGL_GREEN_INDEX]; LIBGGI_PIXFMT(vis)->blue_mask = ((1 << priv->modeinfo.vi_pixel_fsizes[VGL_BLUE_INDEX]) - 1) << priv->modeinfo.vi_pixel_fields[VGL_BLUE_INDEX]; break; case GT_TEXT: /* Assumes VGA text */ LIBGGI_PIXFMT(vis)->texture_mask = 0x00ff; LIBGGI_PIXFMT(vis)->fg_mask = 0x0f00; LIBGGI_PIXFMT(vis)->bg_mask = 0xf000; break; } _ggi_build_pixfmt(LIBGGI_PIXFMT(vis)); memcpy(LIBGGI_MODE(vis),tm,sizeof(ggi_mode)); _ggiZapMode(vis, 0); for(id = 1; 0 == GGI_vgl_getapi(vis, id, sugname, args); id++) { if (_ggiOpenDL(vis, _ggiGetConfigHandle(), sugname, args, NULL)) { fprintf(stderr,"display-vgl: Can't open the %s (%s) library.\n", sugname, args); return GGI_EFATAL; } else { DPRINT("Success in loading %s (%s)\n", sugname, args); } } if (!priv->vgl_use_db) { vis->opdraw->putpixel = GGI_vgl_putpixel; vis->opdraw->putpixel_nc = GGI_vgl_putpixel_nc; vis->opdraw->getpixel = GGI_vgl_getpixel; vis->opdraw->drawpixel = GGI_vgl_drawpixel; vis->opdraw->drawpixel_nc = GGI_vgl_drawpixel_nc; vis->opdraw->drawhline = GGI_vgl_drawhline; vis->opdraw->drawhline_nc = GGI_vgl_drawhline_nc; vis->opdraw->drawvline = GGI_vgl_drawvline; vis->opdraw->drawvline_nc = GGI_vgl_drawvline_nc; vis->opdraw->drawbox = GGI_vgl_drawbox; vis->opdraw->drawline = GGI_vgl_drawline; vis->opdraw->puthline = GGI_vgl_puthline; vis->opdraw->putbox = GGI_vgl_putbox; } else { vis->opdraw->setorigin = GGI_vgl_setorigin; } if (GT_SCHEME(tm->graphtype) == GT_PALETTE) { vis->opcolor->setpalvec = GGI_vgl_setpalvec; } if(priv->vgl_use_db) { for(i = 0; i<tm->frames; i++) LIBGGI_APPBUFS(vis)[i]->buffer.plb.pixelformat = LIBGGI_PIXFMT(vis); } ggiIndicateChange(vis, GGI_CHG_APILIST); return 0; }
SDL_Surface *VGL_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { int mode_found; int i; VGLMode **modes; modes = VGLListModes(bpp, V_INFO_MM_DIRECT | V_INFO_MM_PACKED); mode_found = 0; for (i = 0; modes[i] != NULL; i++) { if ((modes[i]->ModeInfo.Xsize == width) && (modes[i]->ModeInfo.Ysize == height) && ((modes[i]->ModeInfo.Type == VIDBUF8) || (modes[i]->ModeInfo.Type == VIDBUF16) || (modes[i]->ModeInfo.Type == VIDBUF32))) { mode_found = 1; break; } } if (mode_found == 0) { SDL_SetError("No matching video mode found"); return NULL; } /* Shutdown previous videomode (if any) */ if (VGLCurMode != NULL) VGLEnd(); /* Try to set the requested linear video mode */ if (VGLInit(modes[i]->ModeId) != 0) { SDL_SetError("Unable to switch to requested mode"); return NULL; } VGLCurMode = SDL_realloc(VGLCurMode, sizeof(VGLMode)); VGLCurMode->ModeInfo = *VGLDisplay; VGLCurMode->Depth = modes[i]->Depth; VGLCurMode->ModeId = modes[i]->ModeId; VGLCurMode->Rmask = modes[i]->Rmask; VGLCurMode->Gmask = modes[i]->Gmask; VGLCurMode->Bmask = modes[i]->Bmask; /* Workaround a bug in libvgl */ if (VGLCurMode->ModeInfo.PixelBytes == 0) (VGLCurMode->ModeInfo.PixelBytes = 1); current->w = VGLCurMode->ModeInfo.Xsize; current->h = VGLCurMode->ModeInfo.Ysize; current->pixels = VGLCurMode->ModeInfo.Bitmap; current->pitch = VGLCurMode->ModeInfo.Xsize * VGLCurMode->ModeInfo.PixelBytes; current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE); /* Check if we are in a pseudo-color mode */ if (VGLCurMode->ModeInfo.Type == VIDBUF8) current->flags |= SDL_HWPALETTE; /* Check if we can do doublebuffering */ if (flags & SDL_DOUBLEBUF) { if (VGLCurMode->ModeInfo.Xsize * 2 <= VGLCurMode->ModeInfo.VYsize) { current->flags |= SDL_DOUBLEBUF; flip_page = 0; flip_address[0] = (byte *)current->pixels; flip_address[1] = (byte *)current->pixels + current->h * current->pitch; VGL_FlipHWSurface(this, current); } } if (! SDL_ReallocFormat(current, modes[i]->Depth, VGLCurMode->Rmask, VGLCurMode->Gmask, VGLCurMode->Bmask, 0)) { return NULL; } /* Update hardware acceleration info */ VGL_UpdateVideoInfo(this); /* Set the blit function */ this->UpdateRects = VGL_DirectUpdate; /* We're done */ return current; }