The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

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

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

    }

}

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