linux下的framebuffer应用编程

framebuffer机制是linux显示技术的一个抽象,它对用户屏蔽了不同的硬件(显示)实现,将不同的硬件实现抽象为一个通用的文件节点/dev/fb0,并提供针对该节点的一组通用的ioctrl操作方式。因此对一个应用程序而言,想要在屏幕上进行绘制时只需要打开这个节点并通过ioctrl操作之,而不必关心设备具体用了哪个厂家的显示设备


android上有现成的实现代码和公共操作接口供调用(bootable/recovery/minui/),可参考

http://osxr.org/android/source/bootable/recovery/minui/?v=android-4.4.4_r1


本文仅仅是一个示例程序,基于上述minui库实现。

以下为代码:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "minui.h"

//====================  debug  ====================
#define ENTER \
do{ printf("[FB_DBG] func: %s  line: %04d\n", __func__, __LINE__); }while(0)

#define PRINT_DBG(format,x...)  \
do{ printf("[FB_DBG] " format, ## x); }while(0)

#define PRINT_INFO(format,x...)  \
do{ printf("[FB_INFO] " format, ## x); }while(0)

#define PRINT_WARN(format,x...)  \
do{ printf("[FB_WARN] " format, ## x); }while(0)

#define PRINT_ERR(format,x...)  \
do{ printf("[FB_ERR] func: %s  line: %04d  info: " format, __func__, __LINE__, ## x); }while(0)
//====================  debug  ====================

gr_surface fb_surface;

//不知什么原因,这个gr_text的y参数更像是每一行文字的下边沿坐标,因此我用gr_text_wrap对其做了包裹:强制对其y坐标加20个像素。
//这样,当你调用gr_text_wrap时便可以将传入的x、y坐标当作每一行文字的左上角坐标了。不知道文字的高度和宽度怎么调整,所以只有左上角坐标就可以了。
int gr_text_wrap(int x, int y, const char *s)
{
        return gr_text(x, y+20, s);
}

void fb_draw_image()
{
        PRINT_INFO("fb_draw_image\n");

        struct timeval time_start,time_end;
        int width = gr_get_width(fb_surface);
        int height = gr_get_height(fb_surface);

        int dx = (gr_fb_width() - width)/2;
        int dy = (gr_fb_height() - height)/2;
        gettimeofday(&time_start,NULL);
        PRINT_INFO("show picture for 1 seconds\n");
        while(1) {
                //refresh this image continuely for 1 seconds
                gr_blit(fb_surface, 0, 0, width, height, dx, dy);
                gr_flip();
                gettimeofday(&time_end,NULL);
                if((time_end.tv_sec - time_start.tv_sec) >= 1) {
                        PRINT_INFO("show picture end\n");
                        break;
                }
        }
        res_free_surface(fb_surface);
}

void fb_load_image(char *image)
{
        PRINT_INFO("fb_load_image\n");

        int result = res_create_surface(image, &fb_surface);
        if (result < 0) {
                if (result == -2) {
                        PRINT_INFO("Bitmap %s missing header\n",image );
                } else {
                        PRINT_ERR("Missing bitmap %s\n(Code %d)\n", image, result);
                }
                fb_surface = NULL;
        }
        else
                fb_draw_image();
}

void fb_fill_line_green(void)
{
        gr_color(0, 255, 0, 255);
        gr_fill(0, 0, gr_fb_width(), 40);//绘制矩形区域:前两个参数是左上角的坐标(x,y),后两个参数是右下角的坐标(x,y)  
        gr_flip();
        PRINT_INFO("fill line with green\n");
}

void fb_fill_line_red(void)
{
        gr_color(255, 0, 0, 255);
        gr_fill(0, 0, gr_fb_width(), 40);
        gr_flip();
        PRINT_INFO("fill line with red\n");
}

void fb_fill_full_white(void)
{
        gr_color(255, 255, 255, 255);
        gr_fill(0, 0, gr_fb_width(), gr_fb_height());
        gr_flip();
        PRINT_INFO("fill full with white\n");
}

void fb_fill_full_black(void)
{
        gr_color(0, 0, 0, 255);
        gr_fill(0, 0, gr_fb_width(), gr_fb_height());
        gr_flip();
        PRINT_INFO("fill full with black\n");
}

void fb_show_success(int x, int y)
{
        PRINT_INFO("show success logo\n");

        int curr_y=y;
        int offset_y=10;
        int offset_x=0;
        int i=0;

        gr_color(0, 255, 0, 255);//GREEN

        while(i<10) {
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"                ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"               ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"              ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"             ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"            ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"           ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"##        ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y," ##      ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"  ##    ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"   ##  ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"    ####");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"     ##");
                offset_x+=1;
                curr_y=y;
                i++;
        }

        gr_flip();
}

void fb_show_failed(int x, int y)
{
        PRINT_INFO("show failed logo\n");

        int curr_y=y;
        int offset_y=10;
        int offset_x=0;
        int i=0;

        gr_color(255, 0, 0, 255);//RED

        while(i<10) {
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"##         ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y," ##       ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"  ##     ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"   ##   ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"    ## ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"     ###");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"      #");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"     ###");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"    ## ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"   ##   ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"  ##     ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y," ##       ##");
                gr_text_wrap(x+offset_x,curr_y+=offset_y,"##         ##");
                offset_x+=1;
                curr_y=y;
                i++;
        }

        gr_flip();
}

void fb_print_info(char* msg)
{
        fb_fill_full_white();
        fb_fill_line_green();

        gr_color(0, 0, 0, 255);//BLACK
        PRINT_INFO("show the text\n");
        gr_text_wrap(0,0,msg);
        gr_flip();

        fb_show_success(200, 300);
}

void fb_print_error(char* msg)
{
        fb_fill_full_white();
        fb_fill_line_red();

        gr_color(255, 255, 0, 255);//YELLOW
        PRINT_INFO("show the text\n");
        gr_text_wrap(0,0,msg);
        gr_flip();

        fb_show_failed(200, 300);
}

void fb_test(void)
{
        PRINT_INFO("start framebuffer test\n");
        PRINT_INFO("clean and refresh the screen\n");
        gr_clean();

        fb_fill_full_white();
        sleep(1);
        fb_fill_full_black();
        sleep(1);
        fb_fill_full_white();
        sleep(1);
        fb_fill_line_green();
        sleep(1);
        fb_fill_line_red();
        sleep(1);
        fb_print_info("success !!!!!");
        sleep(1);
        fb_print_error("failed !!!!!");
        sleep(1);

        fb_load_image("tangwei");

        PRINT_INFO("fb_test Exit\n");
}

int main(int argc, char **argv)
{
        gr_init();
        gr_clean();
        PRINT_INFO("frambuffer init\n");

        fb_test();

        PRINT_INFO("Exit\n");
        return 0;
}















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YasinLeeX

再来一杯西湖龙井。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值