Moderadores: 51, guest2003, Renie, gpenga
//###################################################################
//-------------------------------------------------------------------
// Example of basic FRAME BUFFER program.
// Code from: busybox-1.15.3(fbsplash.c)
//-------------------------------------------------------------------
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <getopt.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#define USHORT unsigned short
#define UINT unsigned int
struct _fbb {
struct fb_var_screeninfo info;
UINT *addr; // ponteiro para o frame buffer
}fbb;
UINT FBB_base_init() {
UINT fd;
if ( (fd = open("/dev/fb0", O_RDWR)) < 0 ) {
printf("'/dev/fb0' NAO ENCONTRADO, OU SEM PERMICAO DE ACESSO.\n");
return 0; // ERROR
}
ioctl(fd, FBIOGET_VSCREENINFO, &fbb.info);
//1366 * 768
fbb.addr = (UINT *)mmap(NULL,(fbb.info.xres*fbb.info.yres)*4 ,PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
printf("bit por pixel %d\n",fbb.info.bits_per_pixel);
printf("x res %d\n",fbb.info.xres);
printf("y res %d\n",fbb.info.yres);
printf("x virtual %d\n",fbb.info.xres_virtual);
printf("y virtual %d\n",fbb.info.yres_virtual);
printf("x ofset %d\n",fbb.info.xoffset);
printf("y ofset %d\n",fbb.info.yoffset);
}
void put_line(UINT x1,UINT y1 ,UINT x2,UINT y2, UINT pen)
{
register UINT xinc, yinc;
register UINT pixel_start, pixel_end;
register UINT lin;
register UINT offs;
register UINT xv, yv;
register UINT *ponto;
/* Drawing is performed at a much 'higher' resolution that the
actual display. Before writing to the frame buffer, the 'lower'
resolution is restored. */
/* Swap x1 and x2 if x1 is larger than x2 */
if (x1 > x2)
{
lin = x1;
x1 = x2;
x2 = lin;
}
/* Swap y1 and y2 if y1 is larger than y2 */
if (y1 > y2)
{
lin = y1;
y1 = y2;
y2 = lin;
}
/* Determine difference X and Y values */
xinc = x2 - x1;
yinc = y2 - y1;
if (xinc > yinc)
{
/* Use X axis for drawing */
pixel_start = x1;
pixel_end = x2;
/* Determine incremental values for X and Y */
yinc = fbb.info.yres * yinc / xinc;
xinc = fbb.info.xres;
}
else
{
/* Use Y axis for drawing */
pixel_start = y1;
pixel_end = y2;
/* Determine scaling factors */
xinc = fbb.info.xres * xinc / yinc;
yinc = fbb.info.yres;
}
x1 = x1 * fbb.info.xres;
y1 = y1 * fbb.info.yres;
/* Draw line */
for (lin = pixel_start; lin < pixel_end;)
{
/* Convert pixel address into real offset in display
Only plot if in physical display */
xv = x1 / fbb.info.xres;
yv = y1 / fbb.info.yres;
if ((xv >= 0) && (yv >= 0) && (xv <= (fbb.info.xres - 1)) && (yv <= (fbb.info.yres - 1)))
{
offs = xv + (yv * fbb.info.xres);
ponto = (UINT *)(fbb.addr);
ponto += offs;
*ponto = pen;
}
else
{
/* Out of display, force exit*/
lin = pixel_end +1;//+ 1;
}
/* Increment X and Y pixel locations */
x1 = x1 + xinc;
y1 = y1 + yinc;
/* Increment to next pixel */
lin++;
}
}
//-------------------------------------------------------------------
// NAME: FBB_base_makecol.
// USE: color = FBB_base_makecol(255, 130, 30);
//
// DESC:
// Make a color only in 16 bits.
//
// CODE BASEAD IN:
// See file: from busybox-1.15.3: /miscutils/fbsplash.c
// Function: static void fb_drawfullrectangle(...).
// Copyright (C) 2008 Michele Sanges <michele.sanges@gmail.com>
//
// BY: gokernel
//-------------------------------------------------------------------
UINT FBB_base_makecol(unsigned char r, unsigned char g, unsigned char b) {
return r+(g<<8)+(b<<16) ;
}
// Put PIXEL
void FBB_base_putpixel(short x, short y, register unsigned short color) {
register UINT *pointer;
pointer = (UINT*)(fbb.addr + (y * fbb.info.xres + x) );
*pointer = color; // <-- Put HERE;
}
// Horizontal Lines
// posi Y Start X End X
void FBB_base_hline( short y, short x1, short x2, register UINT color) {
register UINT count;
register UINT *pointer;
// horizontal lines
pointer = (UINT *)(fbb.addr + (y * fbb.info.xres + x1));
count = x2 - x1;
do {
*pointer++ = color;
} while (--count >= 0);
}
// Vertical Lines posi x start y end y
void FBB_base_vline(short x, short y1, short y2, register UINT color) {
register UINT count;
register UINT *pointer;
// vertical lines
pointer = (UINT *)(fbb.addr + (y1 * fbb.info.xres + x));
count = y2 - y1;
do {
*pointer = color;
pointer += fbb.info.xres; // Screen HEIGHT;
} while (--count >= 0);
}
UINT main(UINT argc, char *argv[]) {
if ( !FBB_base_init() ){//inicializa o frame buffer, e escreve as informações do monitor
return 1; // ERROR // aqui o FB foi criado com a resolução normal do monitor
}
//aqui foi incrementado os valores de referencia das rotinas em 10
//a rotina put_line utiliza como referencia de matriz os valores passados abaixo
//observe que no FBB_base_init, o buffer foi criado baseado nos valores que o kernel retornou x=1366 y=768
// aqui embaixo estes valores foram incrementados em 10, para o uso das rotinas de baixo nivel
fbb.info.xres+=10;
fbb.info.yres+=20;
// o mais interessante,
put_line(0,0,0,760,0xffff0000);//vermelho no meio da tela horizontal
put_line(0,0,1360,0,0xffff0000);//vermelho no meio da tela vertical
put_line(1360,0,1360,760,0xffff0000);//vermelho no meio da tela horizontal
put_line(0,760,1360,760,0xffff0000);//vermelho no meio da tela vertical
// Se os valores forem maiores que os informados acima, ocorre a falha de seguimentação !!!
return 0;
}
//###################################################################
//###################################################################
//-------------------------------------------------------------------
// Example of basic FRAME BUFFER program.
// Code from: busybox-1.15.3(fbsplash.c)
//-------------------------------------------------------------------
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <getopt.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#define USHORT unsigned short
#define UINT unsigned int
struct _fbb {
struct fb_var_screeninfo info;
UINT *addr; // ponteiro para o frame buffer
} fbb;
UINT FBB_base_init()
{
int fd; // man open: fd deve ser int!!!
if ((fd = open("/dev/fb0", O_RDWR)) < 0) {
printf("'/dev/fb0' NAO ENCONTRADO, OU SEM PERMICAO DE ACESSO.\n");
return 0; // ERROR
}
ioctl(fd, FBIOGET_VSCREENINFO, &fbb.info);
fbb.addr = (UINT *) mmap(NULL, fbb.info.xres * fbb.info.yres * fbb.info.bits_per_pixel / 8,
PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
printf("bit por pixel %d\n", fbb.info.bits_per_pixel);
printf("x res %d\n", fbb.info.xres);
printf("y res %d\n", fbb.info.yres);
printf("x virtual %d\n", fbb.info.xres_virtual);
printf("y virtual %d\n", fbb.info.yres_virtual);
printf("x ofset %d\n", fbb.info.xoffset);
printf("y ofset %d\n", fbb.info.yoffset);
}
void put_line(UINT x1, UINT y1, UINT x2, UINT y2, UINT pen)
{
register UINT xinc, yinc;
register UINT pixel_start, pixel_end;
register UINT lin;
register UINT offs;
register UINT xv, yv;
register UINT *ponto;
/* Drawing is performed at a much 'higher' resolution that the
actual display. Before writing to the frame buffer, the 'lower'
resolution is restored. */
/* Swap x1 and x2 if x1 is larger than x2 */
if (x1 > x2) {
lin = x1;
x1 = x2;
x2 = lin;
}
/* Swap y1 and y2 if y1 is larger than y2 */
if (y1 > y2) {
lin = y1;
y1 = y2;
y2 = lin;
}
/* Determine difference X and Y values */
xinc = x2 - x1;
yinc = y2 - y1;
if (xinc > yinc) {
/* Use X axis for drawing */
pixel_start = x1;
pixel_end = x2;
/* Determine incremental values for X and Y */
yinc = fbb.info.yres * yinc / xinc;
xinc = fbb.info.xres;
} else {
/* Use Y axis for drawing */
pixel_start = y1;
pixel_end = y2;
/* Determine scaling factors */
xinc = fbb.info.xres * xinc / yinc;
yinc = fbb.info.yres;
}
x1 = x1 * fbb.info.xres;
y1 = y1 * fbb.info.yres;
/* Draw line */
for (lin = pixel_start; lin < pixel_end;) {
/* Convert pixel address into real offset in display
Only plot if in physical display */
xv = x1 / fbb.info.xres;
yv = y1 / fbb.info.yres;
if ((xv >= 0) && (yv >= 0) && (xv <= (fbb.info.xres - 1))
&& (yv <= (fbb.info.yres - 1))) {
offs = xv + (yv * fbb.info.xres);
ponto = (UINT *) (fbb.addr);
ponto += offs;
*ponto = pen;
} else {
/* Out of display, force exit */
lin = pixel_end + 1; //+ 1;
}
/* Increment X and Y pixel locations */
x1 = x1 + xinc;
y1 = y1 + yinc;
/* Increment to next pixel */
lin++;
}
}
// Put PIXEL
void FBB_base_putpixel(short x, short y, register unsigned short color)
{
register UINT *pointer;
pointer = (UINT *) (fbb.addr + (y * fbb.info.xres + x));
*pointer = color; // <-- Put HERE;
}
// Horizontal Lines
// posi Y Start X End X
void FBB_base_hline(short y, short x1, short x2, register UINT color)
{
register UINT count;
register UINT *pointer;
// horizontal lines
pointer = (UINT *) (fbb.addr + (y * fbb.info.xres + x1));
count = x2 - x1;
do {
*pointer++ = color;
} while (--count >= 0);
}
// Vertical Lines posi x start y end y
void FBB_base_vline(short x, short y1, short y2, register UINT color)
{
register UINT count;
register UINT *pointer;
// vertical lines
pointer = (UINT *) (fbb.addr + (y1 * fbb.info.xres + x));
count = y2 - y1;
do {
*pointer = color;
pointer += fbb.info.xres; // Screen HEIGHT;
} while (--count >= 0);
}
UINT main(UINT argc, char *argv[])
{
if (!FBB_base_init()) { //inicializa o frame buffer, e escreve as informações do monitor
return 1; // ERROR // aqui o FB foi criado com a resolução normal do monitor
}
put_line(0, 0, 0, fbb.info.yres-1, 0xffff0000); //vermelho no meio da tela horizontal
put_line(0, 0, fbb.info.xres-1, 0, 0xffff0000); //vermelho no meio da tela vertical
put_line(fbb.info.xres-1, 0, fbb.info.xres-1, fbb.info.yres-1, 0xffff0000); //vermelho no meio da tela horizontal
put_line(0, fbb.info.yres-1, fbb.info.xres-1, fbb.info.yres-1, 0xffff0000); //vermelho no meio da tela vertical
getchar();
return 0;
}
//###################################################################
void put_pixel(unsigned x, unsigned y, unsigned color)
{
fbb.addr[y * fbb.info.xres + x] = color;
}
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <getopt.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#define USHORT unsigned short
#define UINT unsigned int
struct _fbb {
struct fb_var_screeninfo info;
UINT *addr; // ponteiro para o frame buffer
} fbb;
int FBB_base_init(void )
{
int fd; // man open: fd deve ser int!!!
if ((fd = open("/dev/fb0", O_RDWR)) < 0) {
printf("'/dev/fb0' NAO ENCONTRADO, OU SEM PERMICAO DE ACESSO.\n");
return 0; // ERROR
}
ioctl(fd, FBIOGET_VSCREENINFO, &fbb.info);
fbb.addr = (UINT *) mmap(NULL, fbb.info.xres * fbb.info.yres * (fbb.info.bits_per_pixel / 8),PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
printf("bit por pixel %d\n", fbb.info.bits_per_pixel);
printf("x res %d\n", fbb.info.xres);
printf("y res %d\n", fbb.info.yres);
printf("x virtual %d\n", fbb.info.xres_virtual);
printf("y virtual %d\n", fbb.info.yres_virtual);
printf("x ofset %d\n", fbb.info.xoffset);
printf("y ofset %d\n", fbb.info.yoffset);
return 1;
}
void put_line(UINT x1, UINT y1, UINT x2, UINT y2, UINT pen)
{
register UINT xinc, yinc;
register UINT pixel_start, pixel_end;
register UINT lin;
register UINT offs;
register UINT xv, yv;
register UINT *ponto;
/* Drawing is performed at a much 'higher' resolution that the
actual display. Before writing to the frame buffer, the 'lower'
resolution is restored. */
/* Swap x1 and x2 if x1 is larger than x2 */
if (x1 > x2) {
lin = x1;
x1 = x2;
x2 = lin;
}
/* Swap y1 and y2 if y1 is larger than y2 */
if (y1 > y2) {
lin = y1;
y1 = y2;
y2 = lin;
}
/* Determine difference X and Y values */
xinc = x2 - x1;
yinc = y2 - y1;
if (xinc > yinc) {
/* Use X axis for drawing */
pixel_start = x1;
pixel_end = x2;
/* Determine incremental values for X and Y */
yinc = fbb.info.yres * yinc / xinc;
xinc = fbb.info.xres;
} else {
/* Use Y axis for drawing */
pixel_start = y1;
pixel_end = y2;
/* Determine scaling factors */
xinc = fbb.info.xres * xinc / yinc;
yinc = fbb.info.yres;
}
x1 = x1 * fbb.info.xres;
y1 = y1 * fbb.info.yres;
/* Draw line */
for (lin = pixel_start; lin < pixel_end;) {
/* Convert pixel address into real offset in display
Only plot if in physical display */
xv = x1 / fbb.info.xres;
yv = y1 / fbb.info.yres;
if ((xv >= 0) && (yv >= 0) && (xv <= (fbb.info.xres - 1))
&& (yv <= (fbb.info.yres - 1))) {
offs = xv + (yv * fbb.info.xres);
ponto = (UINT *) (fbb.addr);
ponto += offs;
*ponto = pen;
} else {
/* Out of display, force exit */
lin = pixel_end + 1; //+ 1;
}
/* Increment X and Y pixel locations */
x1 = x1 + xinc;
y1 = y1 + yinc;
/* Increment to next pixel */
lin++;
}
}
// Put PIXEL
void FBB_base_putpixel(short x, short y, register unsigned short color)
{
register UINT *pointer;
pointer = (UINT *) (fbb.addr + (y * fbb.info.xres + x));
*pointer = color; // <-- Put HERE;
}
// Horizontal Lines
// posi Y Start X End X
void FBB_base_hline(short y, short x1, short x2, register UINT color)
{
register UINT count;
register UINT *pointer;
// horizontal lines
pointer = (UINT *) (fbb.addr + (y * fbb.info.xres + x1));
count = x2 - x1;
do {
*pointer++ = color;
} while (--count >= 0);
}
// Vertical Lines posi x start y end y
void FBB_base_vline(short x, short y1, short y2, register UINT color)
{
register UINT count;
register UINT *pointer;
// vertical lines
pointer = (UINT *) (fbb.addr + (y1 * fbb.info.xres + x));
count = y2 - y1;
do {
*pointer = color;
pointer += fbb.info.xres; // Screen HEIGHT;
} while (--count >= 0);
}
int main(int argc, char *argv[])
{
register int resx,resy;
char string[100];
if (!FBB_base_init()) { //inicializa o frame buffer, e escreve as informações do monitor
return 1; // ERROR // aqui o FB foi criado com a resolução normal do monitor
}
// Eu faço uma copia do comprimento xy que o kernel me informa
// após isto, eu incremento em 10 as variaveis.
// a rotina de escrita de linhas no display, utiliza fbb.info.xres e .yres como parametro
// o que esta ocorrendo é que: O kernel informa 1366 X 768, porem isto não esta correto.
// a linha vertical só fica correta se o valor de x passado como referencia para a rotina for de 1376...
resx = fbb.info.xres;
resy = fbb.info.yres;
//agora adiciona 10 em cada parametro para que a rotina possa funcionar com os valores que foram descobertos por tentativa e erro !!
fbb.info.xres += 10;
fbb.info.yres += 10;
//ai esta o problema agora.
//você irá chamar por exemplo, ./teste 0 0 1366 768, veja o que vai acontecer !!
put_line(atoi(argv[1]), atoi(argv[2]),atoi(argv[3]), atoi(argv[4]), 0xffff0000); //vermelho no meio da tela horizontal
getchar();//aguarda tecla ser precionada
return 0;
}
fbb.addr = (UINT *) mmap(NULL, fbb.info.xres * fbb.info.yres * (fbb.info.bits_per_pixel / 8),PROT_WRITE, MAP_SHARED, fd, 0);
ioctl(fd, FBIOGET_VSCREENINFO, &fbb.info);
fbb.info.xres += 10;
fbb.info.yres += 10;
fbb.addr = (UINT *) mmap(NULL, fbb.info.xres * fbb.info.yres * (fbb.info.bits_per_pixel / 8),PROT_WRITE, MAP_SHARED, fd, 0);
fabim escreveu:Ai que ta SAM !!!
Se eu alocar um valor maior que 1366 * 768 no mmap, simplesmente POOF !! Não works !!!
Ou seja.
Eu aloco 1366*768*4 !!! Ou seja, o que cabe no FB é exatamente este valor capisco ?
Porém, o real é 1376 na horizontal, e 778 na vertical. !!
Eu crio e limito a região de escrita para 1366 por 768, porém oriento as rotinas como se o display fosse de 1376 por 778.
Entendeu ?
só pra não abrir outro: De onde você tirou aquele calculo ??
Voltar para Linux ( x86 ou x64 )
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante