Распечатка 9.1 Пример работы с кадровым буфером |
Предыдущая Содержание Следующая |
Распечатка 9.1
/* File: fbs.c */
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <asm/page.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <asm/page.h> #include <linux/fb.h>
/* имя устройства, подобное /dev/fb */ char *fbname; /* дескриптор устройства с к/б */ int FrameBufferFD; /* неизменяемая информация об экране */ struct fb_fix_screeninfo fix_info; /* изменяемая информация экрана */ struct fb_var_screeninfo var_info; /* указатель на память кадрового буфера */ void *framebuffer; /* функция для отрисовки пикселя в позиции (x,y) */ void draw_pixel(int x,int y, u_int32_t pixel);
int main(int argc, char *argv[]) { int size; u_int8_t red, green, blue; int x, y; u_int32_t pixel;
fbname = "/dev/fb0";
/* Открываем устройство с кадровым буфером в режиме чтения и записи */ FrameBufferFD = open(fbname, O_RDWR); if (FrameBufferFD < 0) { printf("Unable to open %s.\n", fbname); return 1; }
/* Выполняем Ioctl. Запрашиваем неизменяемую информацию об экране. */ if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &fix_info) < 0) { printf("get fixed screen info failed: %s\n", strerror(errno)); close(FrameBufferFD); return 1; }
/* Выполняем Ioctl. Получаем изменяемую информацию экрана. */ if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &var_info) < 0) { printf("Unable to retrieve variable screen info: %s\n", strerror(errno)); close(FrameBufferFD); return 1; }
/* Печатаем доступную в настоящее время некоторую информацию об экране */ printf("Screen resolution: (%dx%d)\n", var_info.xres,var_info.yres); printf("Line width in bytes %d\n", fix_info.line_length); printf("bits per pixel : %d\n", var_info.bits_per_pixel); printf("Red: length %d bits, offset %d\n", var_info.red.length,var_info.red.offset); printf("Green: length %d bits, offset %d\n", var_info.red.length, var_info.green.offset); printf("Blue: length %d bits, offset %d\n", var_info.red.length,var_info.blue.offset);
/* Рассчитываем размер для mmap */ size=fix_info.line_length * var_info.yres;
/* Теперь для кадрового буфера выполняем mmap. */ framebuffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, FrameBufferFD,0); if (framebuffer == NULL) { printf("mmap failed:\n"); close(FrameBufferFD); return 1; }
printf("framebuffer mmap address=%p\n", framebuffer); printf("framebuffer size=%d bytes\n", size);
/* Программа будет работать только в TRUECOLOR */ if (fix_info.visual == FB_VISUAL_TRUECOLOR) { /* Белый пиксель ? максимальные значения красного, зелёного и синего */ /* Максимальное 8-ми битовое значение = 0xFF */ red = 0xFF; green = 0xFF; blue = 0xFF;
/* * Теперь пакуем пиксель на основе смещения битов rgb. * Вычисляем значение каждого цвета на основе числа битов * и сдвигаем его в пикселе на соответствующее значение. * * Например: При работе с RGB565, формула будет * выглядеть так: * Красный len=5, off=11 : Зелёный len=6, off=6 : Синий len=5, off=0 * pixel_value = ((0xFF >> (8 - 5) << 11)| * ((0xFF >> (8 - 6) << 6) | * ((0xFF >> (8 - 5) << 0) = 0xFFFF // Белый */ pixel = ((red >> (8-var_info.red.length)) << var_info.red.offset) | ((green >> (8-var_info.green.length)) << var_info.green.offset) | ((blue >>(8-var_info.blue.length)) << var_info.blue.offset); }else { printf("Unsupported Mode.\n"); return 1; }
/* Вычисляем центр экрана */ x = var_info.xres / 2 + var_info.xoffset; y = var_info.yres / 2 + var_info.yoffset;
/* Рисуем пиксель по координатам x,y */ draw_pixel(x,y, pixel);
/* Освобождаем mmap. */ munmap(framebuffer,0); close(FrameBufferFD); return 0; }
void draw_pixel(int x, int y, u_int32_t pixel) { /* * Базируясь на числе бит на пиксель, присваиваем значение pixel_value * адресу, на который указывает framebuffer. Вспомните метод матричной * индексации, описанный для линейного кадрового буфера. * pixel(x,y)=(line_width * y) + x. */ switch (var_info.bits_per_pixel) { case 8: *((u_int8_t *)framebuffer + fix_info.line_length * y +x) = (u_int8_t)pixel; break;
case 16: *((u_int16_t *)framebuffer + fix_info.line_length / 2 * y + x) = (u_int16_t)pixel; break;
case 32: *((u_int32_t *)framebuffer + fix_info.line_length / 4 * y + x) = (u_int32_t)pixel; break;
default: printf("Unknown depth.\n"); } } |
Предыдущая Содержание Следующая |