Распечатка 9.1 Пример работы с кадровым буфером

Предыдущая  Содержание  Следующая V*D*V

Распечатка 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");

    }

}

Предыдущая  Содержание  Следующая