今天看別人的代碼,知道可以使控制臺進入圖形模式,這樣SHELL程序的顯示就不會影響B(tài)MP圖像的顯示了。于是,COPY過來,放入自己先前的那個程序,再整個800x600的BMP圖,試試全屏顯示的效果!爽^0^爽
/*
showbmp.c
allenyao 2006/11/10
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <linux/fb.h>
#include <linux/kd.h>/*新添加的,用于進行圖形模式時ioctl使用*/
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
typedef struct
{
char cfType[2]; /* 文件類型, 必須為 "BM" (0x4D42) */
char cfSize[4]; /* 文件的大小(字節(jié)) */
char cfReserved[4]; /* 保留, 必須為 0 */
char cfoffBits[4]; /* 位圖陣列相對于文件頭的偏移量(字節(jié)) */
} BITMAPFILEHEADER; /* 文件頭結構 */
typedef struct
{
char ciSize[4]; /* size of BITMAPINFOHEADER */
char ciWidth[4]; /* 位圖寬度(像素) */
char ciHeight[4]; /* 位圖高度(像素) */
char ciPlanes[2]; /* 目標設備的位平面數(shù), 必須置為1 */
char ciBitCount[2]; /* 每個像素的位數(shù), 1,4,8或24 */
char ciCompress[4]; /* 位圖陣列的壓縮方法,0=不壓縮 */
char ciSizeImage[4]; /* 圖像大小(字節(jié)) */
char ciXPelsPerMeter[4];/* 目標設備水平每米像素個數(shù) */
char ciYPelsPerMeter[4];/* 目標設備垂直每米像素個數(shù) */
char ciClrUsed[4]; /* 位圖實際使用的顏色表的顏色數(shù) */
char ciClrImportant[4]; /* 重要顏色索引的個數(shù) */
} BITMAPINFOHEADER; /* 位圖信息頭結構 */
typedef struct
{
char rgbBlue;
char rgbGreen;
char rgbRed;
char rgbReserved;
} RGBQUAD;
BITMAPFILEHEADER FileHead;
BITMAPINFOHEADER InfoHead;
RGBQUAD rgbquad;
char *fbp = 0;
int xres = 0;
int yres = 0;
int bits_per_pixel = 0;
int tty;
int tty_mode_was;
int set_tty_graphics( void );
int set_tty_text( void );
int show_bmp ( char *bmpfile );
long chartolong( char * string, int length );
/******************************************************************************
*
******************************************************************************/
int main( int argc, char *argv[] )
{
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd)
{
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo))
{
printf("Error reading fixed information.\n");
exit(2);
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo))
{
printf("Error reading variable information.\n");
exit(3);
}
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
xres = vinfo.xres;
yres = vinfo.yres;
bits_per_pixel = vinfo.bits_per_pixel;
// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);
if ((int)fbp == -1)
{
printf("Error: failed to map framebuffer device to memory.\n");
exit(4);
}
if (set_tty_graphics())
{
show_bmp( argv[1] );
}
sleep( 10 );
set_tty_text();
munmap(fbp, screensize);
close(fbfd);
return 0;
}
/******************************************************************************
*
******************************************************************************/
int show_bmp( char *bmpfile )
{
FILE *fp;
int rc;
int ciBitCount, ciWidth, ciHeight;
int line_x, line_y;
long int location = 0, BytesPerLine = 0;
char tmp[1024*10];
/* 打開位圖文件 */
fp = fopen( bmpfile, "rb" );
if (fp == NULL)
{
return( -1 );
}
/* 讀取位圖文件頭 */
rc = fread( &FileHead, 1, sizeof(BITMAPFILEHEADER), fp );
if ( rc != sizeof( BITMAPFILEHEADER ) )
{
fclose( fp );
return( -2 );
}
/* 判斷位圖的類型 */
if (memcmp(FileHead.cfType, "BM", 2) != 0)
{
fclose( fp );
return( -3 );
}
/* 讀取位圖信息頭 */
rc = fread( (char *)&InfoHead, 1, sizeof(BITMAPINFOHEADER), fp );
if ( rc != sizeof(BITMAPINFOHEADER) )
{
fclose( fp );
return( -4 );
}
ciWidth = (int) chartolong( InfoHead.ciWidth, 4 );
ciHeight = (int) chartolong( InfoHead.ciHeight, 4 );
ciBitCount = (int) chartolong( InfoHead.ciBitCount, 4 );
line_x = line_y = 0;
/*
while( !feof( fp ) )
{
rc = fread( (char *)&rgbquad, 1, sizeof(RGBQUAD), fp );
if ( rc != sizeof(RGBQUAD) )
{
break;
}
location = line_x * bits_per_pixel / 8 + (ciHeight - line_y - 1) * xres * bits_per_pixel / 8;
*(fbp + location) = rgbquad.rgbBlue;
*(fbp + location + 1) = rgbquad.rgbGreen;
*(fbp + location + 2) = rgbquad.rgbRed;
*(fbp + location + 3) = rgbquad.rgbReserved;
line_x++;
if ( line_x == ( ciWidth - 1 ) )
{
line_x = 0;
line_y++;
}
}
*/
BytesPerLine = (ciWidth * ciBitCount + 31) / 32 * 4;
while( !feof( fp ) )
{
rc = fread( tmp, 1, BytesPerLine, fp );
if ( rc != BytesPerLine )
{
break;
}
location = (ciHeight - line_y - 1) * xres * bits_per_pixel / 8;
memcpy( (fbp + location) , tmp, BytesPerLine );
line_y++;
}
fclose( fp );
return( 0 );
}
/******************************************************************************
*
******************************************************************************/
long chartolong( char * string, int length )
{
long number;
if (length <= 4)
{
memset( &number, 0x00, sizeof(long) );
memcpy( &number, string, length );
}
return( number );
}
/******************************************************************************
*
******************************************************************************/
int set_tty_graphics( void )
{
int ret = 1;
if(0 > (tty = open("/dev/tty0", O_RDWR)))
{
printf( "ERROR: /dev/tty0 open failed\n" );
ret = 0;
}
else if(0 > ioctl(tty, KDGETMODE, &tty_mode_was))
{
printf( "ERROR: /dev/tty0 get mode failed\n");
close(tty);
ret = 0;
}
else if((KD_GRAPHICS != tty_mode_was)
&& (0 > ioctl(tty, KDSETMODE, KD_GRAPHICS)))
{
printf( "ERROR: /dev/tty0 set graphics failed\n");
close(tty);
ret = 0;
}
else
{
printf("tty mode was ");
switch(tty_mode_was)
{
case KD_TEXT : printf("KD_TEXT" ); break;
case KD_GRAPHICS : printf("KD_GRAPHICS" ); break;
default : printf("IMPOSSIBLE!" ); break;
}
printf("\n");
printf("tty mode set to KD_GRAPHICS\n");
fflush(stdout);
close(tty);
}
return( ret );
}
/******************************************************************************
*
******************************************************************************/
int set_tty_text( void )
{
int ret = 1;
if(0 > (tty = open("/dev/tty0", O_RDWR)))
{
printf( "ERROR: /dev/tty0 open failed\n" );
ret = 0;
}
else if(0 > ioctl(tty, KDSETMODE, tty_mode_was))
{
printf( "ERROR: /dev/tty0 reset mode failed\n");
close(tty);
ret = 0;
}
else
{
printf("tty mode set to ");
switch(tty_mode_was)
{
case KD_TEXT : printf("KD_TEXT" ); break;
case KD_GRAPHICS : printf("KD_GRAPHICS" ); break;
default : printf("IMPOSSIBLE!" ); break;
}
printf("\n");
fflush(stdout);
close(tty);
}
return( ret );
}